Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 12 Jul 2007 20:41:29 +0000 (13:41 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 12 Jul 2007 20:41:29 +0000 (13:41 -0700)
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6:
  [IA64] Support multiple CPUs going through OS_MCA
  [IA64] silence GCC ia64 unused variable warnings
  [IA64] prevent MCA when performing MMIO mmap to PCI config space
  [IA64] add sn_register_pmi_handler oemcall
  [IA64] Stop bit for brl instruction
  [IA64] SN: Correct ROM resource length for BIOS copy
  [IA64] Don't set psr.ic and psr.i simultaneously

17 files changed:
Documentation/ia64/aliasing-test.c
Documentation/ia64/aliasing.txt
arch/ia64/kernel/gate.S
arch/ia64/kernel/mca.c
arch/ia64/kernel/mca_asm.S
arch/ia64/kernel/mca_drv_asm.S
arch/ia64/kernel/process.c
arch/ia64/mm/tlb.c
arch/ia64/pci/pci.c
arch/ia64/sn/kernel/io_acpi_init.c
arch/ia64/sn/kernel/io_init.c
arch/ia64/sn/kernel/tiocx.c
arch/ia64/sn/pci/pcibr/pcibr_provider.c
drivers/pci/rom.c
include/asm-ia64/mca.h
include/asm-ia64/sn/sn_sal.h
include/linux/pci.h

index d485256ee1cead1c71b20610c0db3e458cbd10db..773a814d409361767da369070d2d7e5267536c16 100644 (file)
@@ -19,6 +19,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <linux/pci.h>
 
 int sum;
 
@@ -34,13 +35,19 @@ int map_mem(char *path, off_t offset, size_t length, int touch)
                return -1;
        }
 
+       if (fnmatch("/proc/bus/pci/*", path, 0) == 0) {
+               rc = ioctl(fd, PCIIOC_MMAP_IS_MEM);
+               if (rc == -1)
+                       perror("PCIIOC_MMAP_IS_MEM ioctl");
+       }
+
        addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
        if (addr == MAP_FAILED)
                return 1;
 
        if (touch) {
                c = (int *) addr;
-               while (c < (int *) (offset + length))
+               while (c < (int *) (addr + length))
                        sum += *c++;
        }
 
@@ -54,7 +61,7 @@ int map_mem(char *path, off_t offset, size_t length, int touch)
        return 0;
 }
 
-int scan_sysfs(char *path, char *file, off_t offset, size_t length, int touch)
+int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
 {
        struct dirent **namelist;
        char *name, *path2;
@@ -93,7 +100,7 @@ int scan_sysfs(char *path, char *file, off_t offset, size_t length, int touch)
                } else {
                        r = lstat(path2, &buf);
                        if (r == 0 && S_ISDIR(buf.st_mode)) {
-                               rc = scan_sysfs(path2, file, offset, length, touch);
+                               rc = scan_tree(path2, file, offset, length, touch);
                                if (rc < 0)
                                        return rc;
                        }
@@ -238,10 +245,15 @@ int main()
        else
                fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
 
-       scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
-       scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
-       scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
-       scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
+       scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
 
        scan_rom("/sys/devices", "rom");
+
+       scan_tree("/proc/bus/pci", "??.?", 0, 0xA0000, 1);
+       scan_tree("/proc/bus/pci", "??.?", 0xA0000, 0x20000, 0);
+       scan_tree("/proc/bus/pci", "??.?", 0xC0000, 0x40000, 1);
+       scan_tree("/proc/bus/pci", "??.?", 0, 1024*1024, 0);
 }
index 9a431a7d0f5d6c61d45687d580137f04878ca4a7..aa3e953f0f7b3f2d29e1b84f95c29ef4d088dded 100644 (file)
@@ -112,6 +112,18 @@ POTENTIAL ATTRIBUTE ALIASING CASES
 
        The /dev/mem mmap constraints apply.
 
+    mmap of /proc/bus/pci/.../??.?
+
+       This is an MMIO mmap of PCI functions, which additionally may or
+       may not be requested as using the WC attribute.
+
+       If WC is requested, and the region in kern_memmap is either WC
+       or UC, and the EFI memory map designates the region as WC, then
+       the WC mapping is allowed.
+
+       Otherwise, the user mapping must use the same attribute as the
+       kernel mapping.
+
     read/write of /dev/mem
 
        This uses copy_from_user(), which implicitly uses a kernel
index 3274850cf2722f07726582c3d133f5c14229d475..74b1ccce4e848187f59df741e944d3edf054f444 100644 (file)
@@ -30,6 +30,7 @@
        .previous
 #define BRL_COND_FSYS_BUBBLE_DOWN(pr)                  \
 [1:](pr)brl.cond.sptk 0;                               \
+       ;;                                              \
        .xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
 
 GLOBAL_ENTRY(__kernel_syscall_via_break)
index 1ead5ea6c5ce71afaf259eb6629abc8f65a0c11e..4b5daa3cc0feab6723764d67a7c221e74e5b3eb3 100644 (file)
@@ -57,6 +57,9 @@
  *
  * 2006-09-15 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
  *           Add printing support for MCA/INIT.
+ *
+ * 2007-04-27 Russ Anderson <rja@sgi.com>
+ *           Support multiple cpus going through OS_MCA in the same event.
  */
 #include <linux/types.h>
 #include <linux/init.h>
@@ -96,7 +99,6 @@
 #endif
 
 /* Used by mca_asm.S */
-u32                            ia64_mca_serialize;
 DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */
 DEFINE_PER_CPU(u64, ia64_mca_per_cpu_pte); /* PTE to map per-CPU area */
 DEFINE_PER_CPU(u64, ia64_mca_pal_pte);     /* PTE to map PAL code */
@@ -963,11 +965,12 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
                goto no_mod;
        }
 
+       if (r13 != sos->prev_IA64_KR_CURRENT) {
+               msg = "inconsistent previous current and r13";
+               goto no_mod;
+       }
+
        if (!mca_recover_range(ms->pmsa_iip)) {
-               if (r13 != sos->prev_IA64_KR_CURRENT) {
-                       msg = "inconsistent previous current and r13";
-                       goto no_mod;
-               }
                if ((r12 - r13) >= KERNEL_STACK_SIZE) {
                        msg = "inconsistent r12 and r13";
                        goto no_mod;
@@ -1187,6 +1190,13 @@ all_in:
  *     further MCA logging is enabled by clearing logs.
  *     Monarch also has the duty of sending wakeup-IPIs to pull the
  *     slave processors out of rendezvous spinloop.
+ *
+ *     If multiple processors call into OS_MCA, the first will become
+ *     the monarch.  Subsequent cpus will be recorded in the mca_cpu
+ *     bitmask.  After the first monarch has processed its MCA, it
+ *     will wake up the next cpu in the mca_cpu bitmask and then go
+ *     into the rendezvous loop.  When all processors have serviced
+ *     their MCA, the last monarch frees up the rest of the processors.
  */
 void
 ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
@@ -1196,16 +1206,32 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
        struct task_struct *previous_current;
        struct ia64_mca_notify_die nd =
                { .sos = sos, .monarch_cpu = &monarch_cpu };
+       static atomic_t mca_count;
+       static cpumask_t mca_cpu;
 
+       if (atomic_add_return(1, &mca_count) == 1) {
+               monarch_cpu = cpu;
+               sos->monarch = 1;
+       } else {
+               cpu_set(cpu, mca_cpu);
+               sos->monarch = 0;
+       }
        mprintk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d "
                "monarch=%ld\n", sos->proc_state_param, cpu, sos->monarch);
 
        previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
-       monarch_cpu = cpu;
+
        if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0)
                        == NOTIFY_STOP)
                ia64_mca_spin(__FUNCTION__);
-       ia64_wait_for_slaves(cpu, "MCA");
+       if (sos->monarch) {
+               ia64_wait_for_slaves(cpu, "MCA");
+       } else {
+               ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA;
+               while (cpu_isset(cpu, mca_cpu))
+                       cpu_relax();    /* spin until monarch wakes us */
+               ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
+        }
 
        /* Wakeup all the processors which are spinning in the rendezvous loop.
         * They will leave SAL, then spin in the OS with interrupts disabled
@@ -1244,6 +1270,26 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
                        == NOTIFY_STOP)
                ia64_mca_spin(__FUNCTION__);
 
+
+       if (atomic_dec_return(&mca_count) > 0) {
+               int i;
+
+               /* wake up the next monarch cpu,
+                * and put this cpu in the rendez loop.
+                */
+               ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA;
+               for_each_online_cpu(i) {
+                       if (cpu_isset(i, mca_cpu)) {
+                               monarch_cpu = i;
+                               cpu_clear(i, mca_cpu);  /* wake next cpu */
+                               while (monarch_cpu != -1)
+                                       cpu_relax();    /* spin until last cpu leaves */
+                               ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
+                               set_curr_task(cpu, previous_current);
+                               return;
+                       }
+               }
+       }
        set_curr_task(cpu, previous_current);
        monarch_cpu = -1;
 }
index 8c9c26aa6ae092e130f93a4076025d17a297ab92..0f5965fcdf85133fbf0c455f714dcbea091eea2d 100644 (file)
@@ -133,14 +133,6 @@ ia64_do_tlb_purge:
 //StartMain////////////////////////////////////////////////////////////////////
 
 ia64_os_mca_dispatch:
-       // Serialize all MCA processing
-       mov     r3=1;;
-       LOAD_PHYSICAL(p0,r2,ia64_mca_serialize);;
-ia64_os_mca_spin:
-       xchg4   r4=[r2],r3;;
-       cmp.ne  p6,p0=r4,r0
-(p6)   br ia64_os_mca_spin
-
        mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET    // use the MCA stack
        LOAD_PHYSICAL(p0,r2,1f)                 // return address
        mov r19=1                               // All MCA events are treated as monarch (for now)
@@ -291,10 +283,6 @@ END(ia64_os_mca_virtual_begin)
 
        mov             b0=r12                  // SAL_CHECK return address
 
-       // release lock
-       LOAD_PHYSICAL(p0,r3,ia64_mca_serialize);;
-       st4.rel         [r3]=r0
-
        br              b0
 
 //EndMain//////////////////////////////////////////////////////////////////////
index f2d4900751ba9375dc8a7afa5cec7c1f2573f5d4..3bccb06c8d216cc1439c0f0081e6bacce2668035 100644 (file)
@@ -40,7 +40,11 @@ GLOBAL_ENTRY(mca_handler_bhhook)
        mov     b6=loc1
        ;;
        mov     loc1=rp
-       ssm     psr.i | psr.ic
+       ssm     psr.ic
+       ;;
+       srlz.i
+       ;;
+       ssm     psr.i
        br.call.sptk.many rp=b6         // does not return ...
        ;;
        mov     ar.pfs=loc0
index af73b8dfde282c0c91f84b3f8da062327d18a069..fa40cba433500df6e7288903eeab205ce283f54d 100644 (file)
@@ -513,7 +513,8 @@ copy_thread (int nr, unsigned long clone_flags,
 static void
 do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg)
 {
-       unsigned long mask, sp, nat_bits = 0, ip, ar_rnat, urbs_end, cfm;
+       unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm;
+       unsigned long uninitialized_var(ip);    /* GCC be quiet */
        elf_greg_t *dst = arg;
        struct pt_regs *pt;
        char nat;
index fa4e6d4810f3cc2c1c8e6c74fd431e79fe53a350..1682fc639038e79f64e5a1e1cb96ad846e843035 100644 (file)
@@ -175,7 +175,7 @@ EXPORT_SYMBOL(flush_tlb_range);
 void __devinit
 ia64_tlb_init (void)
 {
-       ia64_ptce_info_t ptce_info;
+       ia64_ptce_info_t uninitialized_var(ptce_info); /* GCC be quiet */
        unsigned long tr_pgbits;
        long status;
 
index 73696b4a2eed42caafc4d7414f8ae38c6c3a6922..07d0e92742c8ee604585a526668fd0f0baac8d60 100644 (file)
@@ -591,6 +591,9 @@ int
 pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
                     enum pci_mmap_state mmap_state, int write_combine)
 {
+       unsigned long size = vma->vm_end - vma->vm_start;
+       pgprot_t prot;
+
        /*
         * I/O space cannot be accessed via normal processor loads and
         * stores on this platform.
@@ -604,15 +607,24 @@ pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
                 */
                return -EINVAL;
 
+       if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
+               return -EINVAL;
+
+       prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size,
+                                   vma->vm_page_prot);
+
        /*
-        * Leave vm_pgoff as-is, the PCI space address is the physical
-        * address on this platform.
+        * If the user requested WC, the kernel uses UC or WC for this region,
+        * and the chipset supports WC, we can use WC. Otherwise, we have to
+        * use the same attribute the kernel uses.
         */
-       if (write_combine && efi_range_is_wc(vma->vm_start,
-                                            vma->vm_end - vma->vm_start))
+       if (write_combine &&
+           ((pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_UC ||
+            (pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_WC) &&
+           efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
                vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
        else
-               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+               vma->vm_page_prot = prot;
 
        if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
                             vma->vm_end - vma->vm_start, vma->vm_page_prot))
index c6216f454ffb5ee81d2246bb05361a073ff51268..3c7178f5dce82bad1492cbc006579db7f18ad98e 100644 (file)
@@ -418,7 +418,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
        void __iomem *addr;
        struct pcidev_info *pcidev_info = NULL;
        struct sn_irq_info *sn_irq_info = NULL;
-       size_t size;
+       size_t image_size, size;
 
        if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) {
                panic("%s:  Failure obtaining pcidev_info for %s\n",
@@ -428,17 +428,16 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
        if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) {
                /*
                 * A valid ROM image exists and has been shadowed by the
-                * PROM. Setup the pci_dev ROM resource to point to
-                * the shadowed copy.
+                * PROM. Setup the pci_dev ROM resource with the address
+                * of the shadowed copy, and the actual length of the ROM image.
                 */
-               size = dev->resource[PCI_ROM_RESOURCE].end -
-                               dev->resource[PCI_ROM_RESOURCE].start;
-               addr =
-                    ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
-                            size);
+               size = pci_resource_len(dev, PCI_ROM_RESOURCE);
+               addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
+                              size);
+               image_size = pci_get_rom_size(addr, size);
                dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr;
                dev->resource[PCI_ROM_RESOURCE].end =
-                                               (unsigned long) addr + size;
+                                       (unsigned long) addr + image_size - 1;
                dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY;
        }
        sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
index 6b10e5d284883380a284a1d2616e1aa2ec834fd2..906b93674b7604e236099c42f68cd8228a1876ed 100644 (file)
@@ -259,9 +259,23 @@ sn_io_slot_fixup(struct pci_dev *dev)
                        insert_resource(&ioport_resource, &dev->resource[idx]);
                else
                        insert_resource(&iomem_resource, &dev->resource[idx]);
-               /* If ROM, mark as shadowed in PROM */
-               if (idx == PCI_ROM_RESOURCE)
-                       dev->resource[idx].flags |= IORESOURCE_ROM_BIOS_COPY;
+               /*
+                * If ROM, set the actual ROM image size, and mark as
+                * shadowed in PROM.
+                */
+               if (idx == PCI_ROM_RESOURCE) {
+                       size_t image_size;
+                       void __iomem *rom;
+
+                       rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE),
+                                     size + 1);
+                       image_size = pci_get_rom_size(rom, size + 1);
+                       dev->resource[PCI_ROM_RESOURCE].end =
+                               dev->resource[PCI_ROM_RESOURCE].start +
+                               image_size - 1;
+                       dev->resource[PCI_ROM_RESOURCE].flags |=
+                                                IORESOURCE_ROM_BIOS_COPY;
+               }
        }
        /* Create a pci_window in the pci_controller struct for
         * each device resource.
index 493380b2c05fd1b6756ad9edb711c4992125f5e7..5a289e4de8383eb7f286ed99fe7d0d1c80c36df5 100644 (file)
@@ -369,7 +369,7 @@ static void tio_corelet_reset(nasid_t nasid, int corelet)
 
 static int is_fpga_tio(int nasid, int *bt)
 {
-       u16 ioboard_type;
+       u16 uninitialized_var(ioboard_type);    /* GCC be quiet */
        s64 rc;
 
        rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard_type);
index b42bfcae6f911108f364473ae7e3d7a7fcf80b26..42485ad50ceb3aeea3de6312ae22785cf0a994f7 100644 (file)
@@ -80,7 +80,7 @@ static int sal_pcibr_error_interrupt(struct pcibus_info *soft)
 u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus)
 {
        s64 rc;
-       u16 ioboard;
+       u16 uninitialized_var(ioboard);         /* GCC be quiet */
        nasid_t nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
 
        rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard);
index d087e0817715a71a9405415d24f47220552c3533..dbbcc04abd1af1fe06eafc7be1a647d847233e25 100644 (file)
@@ -53,6 +53,49 @@ static void pci_disable_rom(struct pci_dev *pdev)
        pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
 }
 
+/**
+ * pci_get_rom_size - obtain the actual size of the ROM image
+ * @rom: kernel virtual pointer to image of ROM
+ * @size: size of PCI window
+ *  return: size of actual ROM image
+ *
+ * Determine the actual length of the ROM image.
+ * The PCI window size could be much larger than the
+ * actual image size.
+ */
+size_t pci_get_rom_size(void __iomem *rom, size_t size)
+{
+       void __iomem *image;
+       int last_image;
+
+       image = rom;
+       do {
+               void __iomem *pds;
+               /* Standard PCI ROMs start out with these bytes 55 AA */
+               if (readb(image) != 0x55)
+                       break;
+               if (readb(image + 1) != 0xAA)
+                       break;
+               /* get the PCI data structure and check its signature */
+               pds = image + readw(image + 24);
+               if (readb(pds) != 'P')
+                       break;
+               if (readb(pds + 1) != 'C')
+                       break;
+               if (readb(pds + 2) != 'I')
+                       break;
+               if (readb(pds + 3) != 'R')
+                       break;
+               last_image = readb(pds + 21) & 0x80;
+               /* this length is reliable */
+               image += readw(pds + 16) * 512;
+       } while (!last_image);
+
+       /* never return a size larger than the PCI resource window */
+       /* there are known ROMs that get the size wrong */
+       return min((size_t)(image - rom), size);
+}
+
 /**
  * pci_map_rom - map a PCI ROM to kernel space
  * @pdev: pointer to pci device struct
@@ -68,8 +111,6 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
        struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
        loff_t start;
        void __iomem *rom;
-       void __iomem *image;
-       int last_image;
 
        /*
         * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
@@ -117,33 +158,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
         * size is much larger than the actual size of the ROM.
         * True size is important if the ROM is going to be copied.
         */
-       image = rom;
-       do {
-               void __iomem *pds;
-               /* Standard PCI ROMs start out with these bytes 55 AA */
-               if (readb(image) != 0x55)
-                       break;
-               if (readb(image + 1) != 0xAA)
-                       break;
-               /* get the PCI data structure and check its signature */
-               pds = image + readw(image + 24);
-               if (readb(pds) != 'P')
-                       break;
-               if (readb(pds + 1) != 'C')
-                       break;
-               if (readb(pds + 2) != 'I')
-                       break;
-               if (readb(pds + 3) != 'R')
-                       break;
-               last_image = readb(pds + 21) & 0x80;
-               /* this length is reliable */
-               image += readw(pds + 16) * 512;
-       } while (!last_image);
-
-       /* never return a size larger than the PCI resource window */
-       /* there are known ROMs that get the size wrong */
-       *size = min((size_t)(image - rom), *size);
-
+       *size = pci_get_rom_size(rom, *size);
        return rom;
 }
 
index 41098f459684c41f82cc26c6812f3b21deacb400..edd5d01028df93d8d88ad68dbdd1322261bee790 100644 (file)
@@ -48,6 +48,7 @@ enum {
        IA64_MCA_RENDEZ_CHECKIN_NOTDONE =       0x0,
        IA64_MCA_RENDEZ_CHECKIN_DONE    =       0x1,
        IA64_MCA_RENDEZ_CHECKIN_INIT    =       0x2,
+       IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA  =       0x3,
 };
 
 /* Information maintained by the MC infrastructure */
index d3566a298fa40b773a96d3518e1fd1f71782eec0..676b31a08c61dc8fd366d1147b8572080fca4e65 100644 (file)
@@ -32,6 +32,7 @@
 #define  SN_SAL_NO_FAULT_ZONE_VIRTUAL             0x02000010
 #define  SN_SAL_NO_FAULT_ZONE_PHYSICAL            0x02000011
 #define  SN_SAL_PRINT_ERROR                       0x02000012
+#define  SN_SAL_REGISTER_PMI_HANDLER              0x02000014
 #define  SN_SAL_SET_ERROR_HANDLING_FEATURES       0x0200001a   // reentrant
 #define  SN_SAL_GET_FIT_COMPT                     0x0200001b   // reentrant
 #define  SN_SAL_GET_SAPIC_INFO                     0x0200001d
@@ -679,6 +680,25 @@ sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
        return ret_stuff.status;
 }
 
+/*
+ * Register or unregister a function to handle a PMI received by a CPU.
+ * Before calling the registered handler, SAL sets r1 to the value that
+ * was passed in as the global_pointer.
+ *
+ * If the handler pointer is NULL, then the currently registered handler
+ * will be unregistered.
+ *
+ * Returns 0 on success, or a negative value if an error occurred.
+ */
+static inline int
+sn_register_pmi_handler(u64 handler, u64 global_pointer)
+{
+       struct ia64_sal_retval ret_stuff;
+       ia64_sal_oemcall(&ret_stuff, SN_SAL_REGISTER_PMI_HANDLER, handler,
+                        global_pointer, 0, 0, 0, 0, 0);
+       return ret_stuff.status;
+}
+
 /*
  * Change or query the coherence domain for this partition. Each cpu-based
  * nasid is represented by a bit in an array of 64-bit words:
index a5602e26f4dd5219a5e63058ea47c5faa0bf6a7f..37a71580ad8a4f8b9e099e1e6e51b155ef50526b 100644 (file)
@@ -566,6 +566,7 @@ void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
 void __iomem __must_check *pci_map_rom_copy(struct pci_dev *pdev, size_t *size);
 void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
 void pci_remove_rom(struct pci_dev *pdev);
+size_t pci_get_rom_size(void __iomem *rom, size_t size);
 
 /* Power management related routines */
 int pci_save_state(struct pci_dev *dev);