ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-ia64 / sn / sn_sal.h
1 #ifndef _ASM_IA64_SN_SN_SAL_H
2 #define _ASM_IA64_SN_SN_SAL_H
3
4 /*
5  * System Abstraction Layer definitions for IA64
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License.  See the file "COPYING" in the main directory of this archive
9  * for more details.
10  *
11  * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
12  */
13
14
15 #include <linux/config.h>
16 #include <asm/sal.h>
17 #include <asm/sn/sn_cpuid.h>
18 #include <asm/sn/arch.h>
19 #include <asm/sn/nodepda.h>
20 #include <asm/sn/klconfig.h>
21         
22
23 // SGI Specific Calls
24 #define  SN_SAL_POD_MODE                           0x02000001
25 #define  SN_SAL_SYSTEM_RESET                       0x02000002
26 #define  SN_SAL_PROBE                              0x02000003
27 #define  SN_SAL_GET_MASTER_NASID                   0x02000004
28 #define  SN_SAL_GET_KLCONFIG_ADDR                  0x02000005
29 #define  SN_SAL_LOG_CE                             0x02000006
30 #define  SN_SAL_REGISTER_CE                        0x02000007
31 #define  SN_SAL_GET_PARTITION_ADDR                 0x02000009
32 #define  SN_SAL_XP_ADDR_REGION                     0x0200000f
33 #define  SN_SAL_NO_FAULT_ZONE_VIRTUAL              0x02000010
34 #define  SN_SAL_NO_FAULT_ZONE_PHYSICAL             0x02000011
35 #define  SN_SAL_PRINT_ERROR                        0x02000012
36 #define  SN_SAL_CONSOLE_PUTC                       0x02000021
37 #define  SN_SAL_CONSOLE_GETC                       0x02000022
38 #define  SN_SAL_CONSOLE_PUTS                       0x02000023
39 #define  SN_SAL_CONSOLE_GETS                       0x02000024
40 #define  SN_SAL_CONSOLE_GETS_TIMEOUT               0x02000025
41 #define  SN_SAL_CONSOLE_POLL                       0x02000026
42 #define  SN_SAL_CONSOLE_INTR                       0x02000027
43 #define  SN_SAL_CONSOLE_PUTB                       0x02000028
44 #define  SN_SAL_CONSOLE_XMIT_CHARS                 0x0200002a
45 #define  SN_SAL_CONSOLE_READC                      0x0200002b
46 #define  SN_SAL_SYSCTL_MODID_GET                   0x02000031
47 #define  SN_SAL_SYSCTL_GET                         0x02000032
48 #define  SN_SAL_SYSCTL_IOBRICK_MODULE_GET          0x02000033
49 #define  SN_SAL_SYSCTL_IO_PORTSPEED_GET            0x02000035
50 #define  SN_SAL_SYSCTL_SLAB_GET                    0x02000036
51 #define  SN_SAL_BUS_CONFIG                         0x02000037
52 #define  SN_SAL_SYS_SERIAL_GET                     0x02000038
53 #define  SN_SAL_PARTITION_SERIAL_GET               0x02000039
54 #define  SN_SAL_SYSCTL_PARTITION_GET               0x0200003a
55 #define  SN_SAL_SYSTEM_POWER_DOWN                  0x0200003b
56 #define  SN_SAL_GET_MASTER_BASEIO_NASID            0x0200003c
57 #define  SN_SAL_COHERENCE                          0x0200003d
58 #define  SN_SAL_MEMPROTECT                         0x0200003e
59 #define  SN_SAL_SYSCTL_FRU_CAPTURE                 0x0200003f
60
61 #define  SN_SAL_SYSCTL_IOBRICK_PCI_OP              0x02000042   // reentrant
62
63 /*
64  * Service-specific constants
65  */
66
67 /* Console interrupt manipulation */
68         /* action codes */
69 #define SAL_CONSOLE_INTR_OFF    0       /* turn the interrupt off */
70 #define SAL_CONSOLE_INTR_ON     1       /* turn the interrupt on */
71 #define SAL_CONSOLE_INTR_STATUS 2       /* retrieve the interrupt status */
72         /* interrupt specification & status return codes */
73 #define SAL_CONSOLE_INTR_XMIT   1       /* output interrupt */
74 #define SAL_CONSOLE_INTR_RECV   2       /* input interrupt */
75
76 #ifdef CONFIG_HOTPLUG_PCI_SGI
77 /* power up / power down / reset a PCI slot or bus */
78 #define SAL_SYSCTL_PCI_POWER_UP         0
79 #define SAL_SYSCTL_PCI_POWER_DOWN       1
80 #define SAL_SYSCTL_PCI_RESET            2
81
82 /* what type of I/O brick? */
83 #define SAL_SYSCTL_IO_XTALK     0       /* connected via a compute node */
84
85 #endif  /* CONFIG_HOTPLUG_PCI_SGI */
86
87 /*
88  * SN_SAL_GET_PARTITION_ADDR return constants
89  */
90 #define SALRET_MORE_PASSES      1
91 #define SALRET_OK               0
92 #define SALRET_INVALID_ARG      -2
93 #define SALRET_ERROR            -3
94
95
96 /**
97  * sn_sal_rev_major - get the major SGI SAL revision number
98  *
99  * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
100  * This routine simply extracts the major value from the
101  * @ia64_sal_systab structure constructed by ia64_sal_init().
102  */
103 static inline int
104 sn_sal_rev_major(void)
105 {
106         struct ia64_sal_systab *systab = efi.sal_systab;
107
108         return (int)systab->sal_b_rev_major;
109 }
110
111 /**
112  * sn_sal_rev_minor - get the minor SGI SAL revision number
113  *
114  * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
115  * This routine simply extracts the minor value from the
116  * @ia64_sal_systab structure constructed by ia64_sal_init().
117  */
118 static inline int
119 sn_sal_rev_minor(void)
120 {
121         struct ia64_sal_systab *systab = efi.sal_systab;
122         
123         return (int)systab->sal_b_rev_minor;
124 }
125
126 /*
127  * Specify the minimum PROM revsion required for this kernel.
128  * Note that they're stored in hex format...
129  */
130 #define SN_SAL_MIN_MAJOR        0x1  /* SN2 kernels need at least PROM 1.0 */
131 #define SN_SAL_MIN_MINOR        0x0
132
133 u64 ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr);
134
135 /*
136  * Returns the master console nasid, if the call fails, return an illegal
137  * value.
138  */
139 static inline u64
140 ia64_sn_get_console_nasid(void)
141 {
142         struct ia64_sal_retval ret_stuff;
143
144         ret_stuff.status = 0;
145         ret_stuff.v0 = 0;
146         ret_stuff.v1 = 0;
147         ret_stuff.v2 = 0;
148         SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_NASID, 0, 0, 0, 0, 0, 0, 0);
149
150         if (ret_stuff.status < 0)
151                 return ret_stuff.status;
152
153         /* Master console nasid is in 'v0' */
154         return ret_stuff.v0;
155 }
156
157 /*
158  * Returns the master baseio nasid, if the call fails, return an illegal
159  * value.
160  */
161 static inline u64
162 ia64_sn_get_master_baseio_nasid(void)
163 {
164         struct ia64_sal_retval ret_stuff;
165
166         ret_stuff.status = 0;
167         ret_stuff.v0 = 0;
168         ret_stuff.v1 = 0;
169         ret_stuff.v2 = 0;
170         SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_BASEIO_NASID, 0, 0, 0, 0, 0, 0, 0);
171
172         if (ret_stuff.status < 0)
173                 return ret_stuff.status;
174
175         /* Master baseio nasid is in 'v0' */
176         return ret_stuff.v0;
177 }
178
179 static inline u64
180 ia64_sn_get_klconfig_addr(nasid_t nasid)
181 {
182         struct ia64_sal_retval ret_stuff;
183         int cnodeid;
184
185         cnodeid = nasid_to_cnodeid(nasid);
186         ret_stuff.status = 0;
187         ret_stuff.v0 = 0;
188         ret_stuff.v1 = 0;
189         ret_stuff.v2 = 0;
190         SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
191
192         /*
193          * We should panic if a valid cnode nasid does not produce
194          * a klconfig address.
195          */
196         if (ret_stuff.status != 0) {
197                 panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status);
198         }
199         return(ret_stuff.v0);
200 }
201
202 /*
203  * Returns the next console character.
204  */
205 static inline u64
206 ia64_sn_console_getc(int *ch)
207 {
208         struct ia64_sal_retval ret_stuff;
209
210         ret_stuff.status = 0;
211         ret_stuff.v0 = 0;
212         ret_stuff.v1 = 0;
213         ret_stuff.v2 = 0;
214         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_GETC, 0, 0, 0, 0, 0, 0, 0);
215
216         /* character is in 'v0' */
217         *ch = (int)ret_stuff.v0;
218
219         return ret_stuff.status;
220 }
221
222 /*
223  * Read a character from the SAL console device, after a previous interrupt
224  * or poll operation has given us to know that a character is available
225  * to be read.
226  */
227 static inline u64
228 ia64_sn_console_readc(void)
229 {
230         struct ia64_sal_retval ret_stuff;
231
232         ret_stuff.status = 0;
233         ret_stuff.v0 = 0;
234         ret_stuff.v1 = 0;
235         ret_stuff.v2 = 0;
236         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_READC, 0, 0, 0, 0, 0, 0, 0);
237
238         /* character is in 'v0' */
239         return ret_stuff.v0;
240 }
241
242 /*
243  * Sends the given character to the console.
244  */
245 static inline u64
246 ia64_sn_console_putc(char ch)
247 {
248         struct ia64_sal_retval ret_stuff;
249
250         ret_stuff.status = 0;
251         ret_stuff.v0 = 0;
252         ret_stuff.v1 = 0;
253         ret_stuff.v2 = 0;
254         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTC, (uint64_t)ch, 0, 0, 0, 0, 0, 0);
255
256         return ret_stuff.status;
257 }
258
259 /*
260  * Sends the given buffer to the console.
261  */
262 static inline u64
263 ia64_sn_console_putb(const char *buf, int len)
264 {
265         struct ia64_sal_retval ret_stuff;
266
267         ret_stuff.status = 0;
268         ret_stuff.v0 = 0; 
269         ret_stuff.v1 = 0;
270         ret_stuff.v2 = 0;
271         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTB, (uint64_t)buf, (uint64_t)len, 0, 0, 0, 0, 0);
272
273         if ( ret_stuff.status == 0 ) {
274                 return ret_stuff.v0;
275         }
276         return (u64)0;
277 }
278
279 /*
280  * Print a platform error record
281  */
282 static inline u64
283 ia64_sn_plat_specific_err_print(int (*hook)(const char*, ...), char *rec)
284 {
285         struct ia64_sal_retval ret_stuff;
286
287         ret_stuff.status = 0;
288         ret_stuff.v0 = 0;
289         ret_stuff.v1 = 0;
290         ret_stuff.v2 = 0;
291         SAL_CALL_REENTRANT(ret_stuff, SN_SAL_PRINT_ERROR, (uint64_t)hook, (uint64_t)rec, 0, 0, 0, 0, 0);
292
293         return ret_stuff.status;
294 }
295
296 /*
297  * Check for Platform errors
298  */
299 static inline u64
300 ia64_sn_plat_cpei_handler(void)
301 {
302         struct ia64_sal_retval ret_stuff;
303
304         ret_stuff.status = 0;
305         ret_stuff.v0 = 0;
306         ret_stuff.v1 = 0;
307         ret_stuff.v2 = 0;
308         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_LOG_CE, 0, 0, 0, 0, 0, 0, 0);
309
310         return ret_stuff.status;
311 }
312
313 /*
314  * Checks for console input.
315  */
316 static inline u64
317 ia64_sn_console_check(int *result)
318 {
319         struct ia64_sal_retval ret_stuff;
320
321         ret_stuff.status = 0;
322         ret_stuff.v0 = 0;
323         ret_stuff.v1 = 0;
324         ret_stuff.v2 = 0;
325         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_POLL, 0, 0, 0, 0, 0, 0, 0);
326
327         /* result is in 'v0' */
328         *result = (int)ret_stuff.v0;
329
330         return ret_stuff.status;
331 }
332
333 /*
334  * Checks console interrupt status
335  */
336 static inline u64
337 ia64_sn_console_intr_status(void)
338 {
339         struct ia64_sal_retval ret_stuff;
340
341         ret_stuff.status = 0;
342         ret_stuff.v0 = 0;
343         ret_stuff.v1 = 0;
344         ret_stuff.v2 = 0;
345         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
346                  0, SAL_CONSOLE_INTR_STATUS,
347                  0, 0, 0, 0, 0);
348
349         if (ret_stuff.status == 0) {
350             return ret_stuff.v0;
351         }
352         
353         return 0;
354 }
355
356 /*
357  * Enable an interrupt on the SAL console device.
358  */
359 static inline void
360 ia64_sn_console_intr_enable(uint64_t intr)
361 {
362         struct ia64_sal_retval ret_stuff;
363
364         ret_stuff.status = 0;
365         ret_stuff.v0 = 0;
366         ret_stuff.v1 = 0;
367         ret_stuff.v2 = 0;
368         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
369                  intr, SAL_CONSOLE_INTR_ON,
370                  0, 0, 0, 0, 0);
371 }
372
373 /*
374  * Disable an interrupt on the SAL console device.
375  */
376 static inline void
377 ia64_sn_console_intr_disable(uint64_t intr)
378 {
379         struct ia64_sal_retval ret_stuff;
380
381         ret_stuff.status = 0;
382         ret_stuff.v0 = 0;
383         ret_stuff.v1 = 0;
384         ret_stuff.v2 = 0;
385         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
386                  intr, SAL_CONSOLE_INTR_OFF,
387                  0, 0, 0, 0, 0);
388 }
389
390 /*
391  * Sends a character buffer to the console asynchronously.
392  */
393 static inline u64
394 ia64_sn_console_xmit_chars(char *buf, int len)
395 {
396         struct ia64_sal_retval ret_stuff;
397
398         ret_stuff.status = 0;
399         ret_stuff.v0 = 0;
400         ret_stuff.v1 = 0;
401         ret_stuff.v2 = 0;
402         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_XMIT_CHARS,
403                  (uint64_t)buf, (uint64_t)len,
404                  0, 0, 0, 0, 0);
405
406         if (ret_stuff.status == 0) {
407             return ret_stuff.v0;
408         }
409
410         return 0;
411 }
412
413 /*
414  * Returns the iobrick module Id
415  */
416 static inline u64
417 ia64_sn_sysctl_iobrick_module_get(nasid_t nasid, int *result)
418 {
419         struct ia64_sal_retval ret_stuff;
420
421         ret_stuff.status = 0;
422         ret_stuff.v0 = 0;
423         ret_stuff.v1 = 0;
424         ret_stuff.v2 = 0;
425         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYSCTL_IOBRICK_MODULE_GET, nasid, 0, 0, 0, 0, 0, 0);
426
427         /* result is in 'v0' */
428         *result = (int)ret_stuff.v0;
429
430         return ret_stuff.status;
431 }
432
433 /**
434  * ia64_sn_pod_mode - call the SN_SAL_POD_MODE function
435  *
436  * SN_SAL_POD_MODE actually takes an argument, but it's always
437  * 0 when we call it from the kernel, so we don't have to expose
438  * it to the caller.
439  */
440 static inline u64
441 ia64_sn_pod_mode(void)
442 {
443         struct ia64_sal_retval isrv;
444         SAL_CALL(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0);
445         if (isrv.status)
446                 return 0;
447         return isrv.v0;
448 }
449
450 /*
451  * Retrieve the system serial number as an ASCII string.
452  */
453 static inline u64
454 ia64_sn_sys_serial_get(char *buf)
455 {
456         struct ia64_sal_retval ret_stuff;
457         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
458         return ret_stuff.status;
459 }
460
461 extern char sn_system_serial_number_string[];
462 extern u64 sn_partition_serial_number;
463
464 static inline char *
465 sn_system_serial_number(void) {
466         if (sn_system_serial_number_string[0]) {
467                 return(sn_system_serial_number_string);
468         } else {
469                 ia64_sn_sys_serial_get(sn_system_serial_number_string);
470                 return(sn_system_serial_number_string);
471         }
472 }
473         
474
475 /*
476  * Returns a unique id number for this system and partition (suitable for
477  * use with license managers), based in part on the system serial number.
478  */
479 static inline u64
480 ia64_sn_partition_serial_get(void)
481 {
482         struct ia64_sal_retval ret_stuff;
483         SAL_CALL(ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0, 0, 0, 0, 0, 0, 0);
484         if (ret_stuff.status != 0)
485             return 0;
486         return ret_stuff.v0;
487 }
488
489 static inline u64
490 sn_partition_serial_number_val(void) {
491         if (sn_partition_serial_number) {
492                 return(sn_partition_serial_number);
493         } else {
494                 return(sn_partition_serial_number = ia64_sn_partition_serial_get());
495         }
496 }
497
498 /*
499  * Returns the partition id of the nasid passed in as an argument,
500  * or INVALID_PARTID if the partition id cannot be retrieved.
501  */
502 static inline partid_t
503 ia64_sn_sysctl_partition_get(nasid_t nasid)
504 {
505         struct ia64_sal_retval ret_stuff;
506         SAL_CALL(ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
507                  0, 0, 0, 0, 0, 0);
508         if (ret_stuff.status != 0)
509             return INVALID_PARTID;
510         return ((partid_t)ret_stuff.v0);
511 }
512
513 /*
514  * Returns the partition id of the current processor.
515  */
516
517 extern partid_t sn_partid;
518
519 static inline partid_t
520 sn_local_partid(void) {
521         if (sn_partid < 0) {
522                 return (sn_partid = ia64_sn_sysctl_partition_get(cpuid_to_nasid(smp_processor_id())));
523         } else {
524                 return sn_partid;
525         }
526 }
527
528 /*
529  * Register or unregister a physical address range being referenced across
530  * a partition boundary for which certain SAL errors should be scanned for,
531  * cleaned up and ignored.  This is of value for kernel partitioning code only.
532  * Values for the operation argument:
533  *      1 = register this address range with SAL
534  *      0 = unregister this address range with SAL
535  * 
536  * SAL maintains a reference count on an address range in case it is registered
537  * multiple times.
538  * 
539  * On success, returns the reference count of the address range after the SAL
540  * call has performed the current registration/unregistration.  Returns a
541  * negative value if an error occurred.
542  */
543 static inline int
544 sn_register_xp_addr_region(u64 paddr, u64 len, int operation)
545 {
546         struct ia64_sal_retval ret_stuff;
547         SAL_CALL(ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len, (u64)operation,
548                  0, 0, 0, 0);
549         return ret_stuff.status;
550 }
551
552 /*
553  * Register or unregister an instruction range for which SAL errors should
554  * be ignored.  If an error occurs while in the registered range, SAL jumps
555  * to return_addr after ignoring the error.  Values for the operation argument:
556  *      1 = register this instruction range with SAL
557  *      0 = unregister this instruction range with SAL
558  *
559  * Returns 0 on success, or a negative value if an error occurred.
560  */
561 static inline int
562 sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
563                          int virtual, int operation)
564 {
565         struct ia64_sal_retval ret_stuff;
566         u64 call;
567         if (virtual) {
568                 call = SN_SAL_NO_FAULT_ZONE_VIRTUAL;
569         } else {
570                 call = SN_SAL_NO_FAULT_ZONE_PHYSICAL;
571         }
572         SAL_CALL(ret_stuff, call, start_addr, end_addr, return_addr, (u64)1,
573                  0, 0, 0);
574         return ret_stuff.status;
575 }
576
577 /*
578  * Change or query the coherence domain for this partition. Each cpu-based
579  * nasid is represented by a bit in an array of 64-bit words:
580  *      0 = not in this partition's coherency domain
581  *      1 = in this partition's coherency domain
582  *
583  * It is not possible for the local system's nasids to be removed from
584  * the coherency domain.  Purpose of the domain arguments:
585  *      new_domain = set the coherence domain to the given nasids
586  *      old_domain = return the current coherence domain
587  *
588  * Returns 0 on success, or a negative value if an error occurred.
589  */
590 static inline int
591 sn_change_coherence(u64 *new_domain, u64 *old_domain)
592 {
593         struct ia64_sal_retval ret_stuff;
594         SAL_CALL(ret_stuff, SN_SAL_COHERENCE, new_domain, old_domain, 0, 0,
595                  0, 0, 0);
596         return ret_stuff.status;
597 }
598
599 /*
600  * Change memory access protections for a physical address range.
601  * nasid_array is not used on Altix, but may be in future architectures.
602  * Available memory protection access classes are defined after the function.
603  */
604 static inline int
605 sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
606 {
607         struct ia64_sal_retval ret_stuff;
608         int cnodeid;
609         unsigned long irq_flags;
610
611         cnodeid = nasid_to_cnodeid(get_node_number(paddr));
612         spin_lock(&NODEPDA(cnodeid)->bist_lock);
613         local_irq_save(irq_flags);
614         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_MEMPROTECT, paddr, len, nasid_array,
615                  perms, 0, 0, 0);
616         local_irq_restore(irq_flags);
617         spin_unlock(&NODEPDA(cnodeid)->bist_lock);
618         return ret_stuff.status;
619 }
620 #define SN_MEMPROT_ACCESS_CLASS_0               0x14a080
621 #define SN_MEMPROT_ACCESS_CLASS_1               0x2520c2
622 #define SN_MEMPROT_ACCESS_CLASS_2               0x14a1ca
623 #define SN_MEMPROT_ACCESS_CLASS_3               0x14a290
624 #define SN_MEMPROT_ACCESS_CLASS_6               0x084080
625 #define SN_MEMPROT_ACCESS_CLASS_7               0x021080
626
627 /*
628  * Turns off system power.
629  */
630 static inline void
631 ia64_sn_power_down(void)
632 {
633         struct ia64_sal_retval ret_stuff;
634         SAL_CALL(ret_stuff, SN_SAL_SYSTEM_POWER_DOWN, 0, 0, 0, 0, 0, 0, 0);
635         while(1);
636         /* never returns */
637 }
638
639 /**
640  * ia64_sn_fru_capture - tell the system controller to capture hw state
641  *
642  * This routine will call the SAL which will tell the system controller(s)
643  * to capture hw mmr information from each SHub in the system.
644  */
645 static inline u64
646 ia64_sn_fru_capture(void)
647 {
648         struct ia64_sal_retval isrv;
649         SAL_CALL(isrv, SN_SAL_SYSCTL_FRU_CAPTURE, 0, 0, 0, 0, 0, 0, 0);
650         if (isrv.status)
651                 return 0;
652         return isrv.v0;
653 }
654
655 /*
656  * Performs an operation on a PCI bus or slot -- power up, power down
657  * or reset.
658  */
659 static inline u64
660 ia64_sn_sysctl_iobrick_pci_op(nasid_t n, u64 connection_type, 
661                               u64 bus, slotid_t slot, 
662                               u64 action)
663 {
664         struct ia64_sal_retval rv = {0, 0, 0, 0};
665
666         SAL_CALL_NOLOCK(rv, SN_SAL_SYSCTL_IOBRICK_PCI_OP, connection_type, n, action,
667                  bus, (u64) slot, 0, 0);
668         if (rv.status)
669                 return rv.v0;
670         return 0;
671 }
672
673 #endif /* _ASM_IA64_SN_SN_SAL_H */