]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.95pre1 2.1.95pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:09 +0000 (15:15 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:09 +0000 (15:15 -0500)
25 files changed:
Makefile
arch/alpha/kernel/apecs.c
arch/alpha/kernel/bios32.c
arch/i386/kernel/bios32.c
arch/i386/kernel/irq.c
drivers/block/ide-disk.c
drivers/block/ide.c
drivers/block/ll_rw_blk.c
drivers/char/tga.c
drivers/misc/parport_pc.c
drivers/net/ne.c
drivers/pci/oldproc.c
drivers/pci/pci.c
drivers/scsi/BusLogic.c
drivers/scsi/aha1740.c
drivers/scsi/ncr53c8xx.c
drivers/scsi/scsi.c
drivers/scsi/scsi.h
drivers/scsi/sd.c
drivers/scsi/sg.c
drivers/scsi/sr.c
fs/dcache.c
fs/proc/root.c
include/linux/pci.h
include/linux/proc_fs.h

index 9234795620d5084c3a2186a720754b7a906babbe..9bfef8b6f2c7a10ffe0a4cf18f45c696b743adfd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 94
+SUBLEVEL = 95
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
 
index f2e8d9ac5f6ed3b68b48eef595c9bdfbb9df74fe..2bbdf0062c1adf80c4f59ba244b1d87f18564c26 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/bios32.h>
 #include <linux/pci.h>
 
 #include <asm/system.h>
index 76f87bffd4f67b55e332533fbe3ab7270f72b257..81c8f70e05ec384eb3cebf0718710c26799fce9f 100644 (file)
@@ -250,7 +250,7 @@ static void layout_dev(struct pci_dev *dev)
 {
        struct pci_bus *bus;
        unsigned short cmd;
-       unsigned int base, mask, size, off;
+       unsigned int base, mask, size, off, idx;
        unsigned int alignto;
        unsigned long handle;
 
@@ -278,7 +278,8 @@ static void layout_dev(struct pci_dev *dev)
        bus = dev->bus;
        pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
 
-       for (off = PCI_BASE_ADDRESS_0; off <= PCI_BASE_ADDRESS_5; off += 4) {
+       for (idx = 0; idx <= 5; idx++) {
+               off = PCI_BASE_ADDRESS_0 + 4*idx;
                /*
                 * Figure out how much space and of what type this
                 * device wants.
@@ -288,7 +289,7 @@ static void layout_dev(struct pci_dev *dev)
                pcibios_read_config_dword(bus->number, dev->devfn, off, &base);
                if (!base) {
                        /* this base-address register is unused */
-                       dev->base_address[PCI_BASE_INDEX(off)] = 0;
+                       dev->base_address[idx] = 0;
                        continue;
                }
 
@@ -324,7 +325,7 @@ static void layout_dev(struct pci_dev *dev)
                                                   off, base | 0x1);
 
                        handle = HANDLE(bus->number) | base | 1;
-                       dev->base_address[PCI_BASE_INDEX(off)] = handle;
+                       dev->base_address[idx] = handle;
 
                        DBG_DEVS(("layout_dev: dev 0x%x IO @ 0x%lx (0x%x)\n",
                                  dev->device, handle, size));
@@ -348,7 +349,7 @@ static void layout_dev(struct pci_dev *dev)
                                       "slot %d, function %d: \n",
                                       PCI_SLOT(dev->devfn),
                                       PCI_FUNC(dev->devfn));
-                               off += 4;       /* skip extra 4 bytes */
+                               idx++;  /* skip extra 4 bytes */
                                continue;
 
                        case PCI_BASE_ADDRESS_MEM_TYPE_1M:
index 9ad83ddb17bdb451d980eb1b0431bb4c3a00a77e..91bbe854d50148511f4d5ac8fbd072e9ca5cb413 100644 (file)
@@ -834,44 +834,52 @@ __initfunc(static struct pci_access *pci_find_bios(void))
 __initfunc(void pcibios_fixup(void))
 {
        struct pci_dev *dev;
-       int i, has_io;
+       int i, has_io, has_mem;
+       unsigned short cmd;
+       unsigned char pin;
 
        for(dev = pci_devices; dev; dev=dev->next) {
                /*
-                * There are probably some buggy BIOSes that forget to assign I/O port
-                * addresses to several devices. We probably should assign new addresses
-                * to such devices, but we need to gather some information first. [mj]
+                * There are buggy BIOSes that forget to enable I/O and memory
+                * access to PCI devices. We try to fix this, but we need to
+                * be sure that the BIOS didn't forget to assign an address
+                * to the device. [mj]
                 */
-               has_io = 0;
+               has_io = has_mem = 0;
                for(i=0; i<6; i++) {
                        unsigned long a = dev->base_address[i];
                        if (a & PCI_BASE_ADDRESS_SPACE_IO) {
-                               has_io = 1;
+                               has_io |= 1;
                                a &= PCI_BASE_ADDRESS_IO_MASK;
-                               if (!a || a == PCI_BASE_ADDRESS_IO_MASK)
+                               if (!a || a == PCI_BASE_ADDRESS_IO_MASK) {
                                        printk(KERN_WARNING "PCI: BIOS forgot to assign address #%d to device %02x:%02x,"
                                                " please report to <mj@ucw.cz>\n", i, dev->bus->number, dev->devfn);
-                       }
+                                       has_io |= 2;
+                               }
+                       } else if (a & PCI_BASE_ADDRESS_MEM_MASK)
+                               has_mem = 1;
                }
-               /*
-                * Check if the I/O space access is allowed. If not, moan loudly. [mj]
-                */
-               if (has_io) {
-                       unsigned short cmd;
-                       pci_read_config_word(dev, PCI_COMMAND, &cmd);
-                       if (!(cmd & PCI_COMMAND_IO))
-                               printk(KERN_WARNING "PCI: BIOS forgot to enable I/O for device %02x:%02x,"
-                                       " please report to <mj@ucw.cz>\n", dev->bus->number, dev->devfn);
+               pci_read_config_word(dev, PCI_COMMAND, &cmd);
+               if (has_io == 1 && !(cmd & PCI_COMMAND_IO)) {
+                       printk("PCI: Enabling I/O for device %02x:%02x\n",
+                               dev->bus->number, dev->devfn);
+                       cmd |= PCI_COMMAND_IO;
+                       pci_write_config_word(dev, PCI_COMMAND, cmd);
                }
+               if (has_mem && !(cmd & PCI_COMMAND_MEMORY)) {
+                       printk("PCI: Enabling memory for device %02x:%02x\n",
+                               dev->bus->number, dev->devfn);
+                       cmd |= PCI_COMMAND_MEMORY;
+                       pci_write_config_word(dev, PCI_COMMAND, cmd);
+               }
+               pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 #ifdef __SMP__
                /*
                 * Recalculate IRQ numbers if we use the I/O APIC
                 */
                {
-               unsigned char pin;
                int irq;
 
-               pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
                if (pin) {
                        pin--;          /* interrupt pins are numbered starting from 1 */
                        irq = IO_APIC_get_PCI_irq_vector (dev->bus->number, PCI_SLOT(dev->devfn), pin);
@@ -884,10 +892,13 @@ __initfunc(void pcibios_fixup(void))
                }
 #endif
                /*
-                * Fix out-of-range IRQ numbers.
+                * Fix out-of-range IRQ numbers and report bogus IRQ.
                 */
                if (dev->irq >= NR_IRQS)
                        dev->irq = 0;
+               if (pin && !dev->irq)
+                       printk(KERN_WARNING "PCI: Bogus IRQ for device %02x:%02x [pin=%x], please report to <mj@ucw.cz>\n",
+                               dev->bus->number, dev->devfn, pin);
        }
 }
 
@@ -919,25 +930,25 @@ __initfunc(char *pcibios_setup(char *str))
 {
        if (!strncmp(str, "off", 3)) {
                pci_probe = 0;
-               return str+3;
+               return NULL;
        }
 #ifdef CONFIG_PCI_BIOS
        else if (!strncmp(str, "bios", 4)) {
                pci_probe = PCI_PROBE_BIOS;
-               return str+4;
+               return NULL;
        } else if (!strncmp(str, "nobios", 6)) {
                pci_probe &= ~PCI_PROBE_BIOS;
-               return str+6;
+               return NULL;
        }
 #endif
 #ifdef CONFIG_PCI_DIRECT
        else if (!strncmp(str, "conf1", 5)) {
                pci_probe = PCI_PROBE_CONF1;
-               return str+5;
+               return NULL;
        }
        else if (!strncmp(str, "conf2", 5)) {
                pci_probe = PCI_PROBE_CONF2;
-               return str+5;
+               return NULL;
        }
 #endif
        return str;
index 0408fea355ab0ffac863b2ae3ce07393f47559be..bab7e96601786cb341292034ee5766628b7e8a83 100644 (file)
@@ -537,20 +537,31 @@ static inline void get_irqlock(int cpu)
        global_irq_holder = cpu;
 }
 
+#define EFLAGS_IF_SHIFT 9
+
 /*
  * A global "cli()" while in an interrupt context
  * turns into just a local cli(). Interrupts
  * should use spinlocks for the (very unlikely)
  * case that they ever want to protect against
  * each other.
+ *
+ * If we already have local interrupts disabled,
+ * this will not turn a local disable into a
+ * global one (problems with spinlocks: this makes
+ * save_flags+cli+sti usable inside a spinlock).
  */
 void __global_cli(void)
 {
-       int cpu = smp_processor_id();
+       unsigned int flags;
 
-       __cli();
-       if (!local_irq_count[cpu])
-               get_irqlock(cpu);
+       __save_flags(flags);
+       if (flags & (1 << EFLAGS_IF_SHIFT)) {
+               int cpu = smp_processor_id();
+               __cli();
+               if (!local_irq_count[cpu])
+                       get_irqlock(cpu);
+       }
 }
 
 void __global_sti(void)
@@ -562,33 +573,53 @@ void __global_sti(void)
        __sti();
 }
 
+/*
+ * SMP flags value to restore to:
+ * 0 - global cli
+ * 1 - global sti
+ * 2 - local cli
+ * 3 - local sti
+ */
 unsigned long __global_save_flags(void)
 {
-       if (!local_irq_count[smp_processor_id()])
-               return global_irq_holder == (unsigned char) smp_processor_id();
-       else {
-               unsigned long x;
-               __save_flags(x);
-               return x;
+       int retval;
+       int local_enabled;
+       unsigned long flags;
+
+       __save_flags(flags);
+       local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
+       /* default to local */
+       retval = 2 + local_enabled;
+
+       /* check for global flags if we're not in an interrupt */
+       if (!local_irq_count[smp_processor_id()]) {
+               if (local_enabled)
+                       retval = 1;
+               if (global_irq_holder == (unsigned char) smp_processor_id())
+                       retval = 0;
        }
+       return retval;
 }
 
 void __global_restore_flags(unsigned long flags)
 {
-       if (!local_irq_count[smp_processor_id()]) {
-               switch (flags) {
-               case 0:
-                       __global_sti();
-                       break;
-               case 1:
-                       __global_cli();
-                       break;
-               default:
-                       printk("global_restore_flags: %08lx (%08lx)\n",
-                               flags, (&flags)[-1]);
-               }
-       } else
-               __restore_flags(flags);
+       switch (flags) {
+       case 0:
+               __global_cli();
+               break;
+       case 1:
+               __global_sti();
+               break;
+       case 2:
+               __cli();
+               break;
+       case 3:
+               __sti();
+               break;
+       default:
+               printk("global_restore_flags: %08lx (%08lx)\n",
+                       flags, (&flags)[-1]);
+       }
 }
 
 #endif
@@ -1073,7 +1104,6 @@ __initfunc(void init_IRQ(void))
        outb_p(LATCH & 0xff , 0x40);    /* LSB */
        outb(LATCH >> 8 , 0x40);        /* MSB */
 
-       printk("INIT IRQ\n");
        for (i=0; i<NR_IRQS; i++) {
                irq_events[i] = 0;
                disabled_irq[i] = 0;
index 066896bf71e18d663c058cf92b80d6b66f943f47..662acf9fdf616a1e7259c3239595820c8fb57be2 100644 (file)
@@ -120,7 +120,6 @@ static void read_intr (ide_drive_t *drive)
        }
        msect = drive->mult_count;
        
-       spin_lock_irqsave(&io_request_lock,flags);
 read_next:
        rq = HWGROUP(drive)->rq;
        if (msect) {
@@ -152,7 +151,6 @@ read_next:
                        goto read_next;
                ide_set_handler (drive, &read_intr, WAIT_CMD);
        }
-       spin_unlock_irqrestore(&io_request_lock,flags);
 }
 
 /*
@@ -167,7 +165,6 @@ static void write_intr (ide_drive_t *drive)
        unsigned long flags;
        int error = 0;
 
-       spin_lock_irqsave(&io_request_lock,flags);
        if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) {
 #ifdef DEBUG
                printk("%s: write: sector %ld, buffer=0x%08lx, remaining=%ld\n",
@@ -192,7 +189,6 @@ static void write_intr (ide_drive_t *drive)
                error = 1;
 
 out:
-       spin_unlock_irqrestore(&io_request_lock,flags);
 
        if (error)
                ide_error(drive, "write_intr", stat);
@@ -246,7 +242,6 @@ static void multwrite_intr (ide_drive_t *drive)
        unsigned long flags;
        int error = 0;
 
-       spin_lock_irqsave(&io_request_lock,flags);
        if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) {
                if (stat & DRQ_STAT) {
                        if (rq->nr_sectors) {
@@ -268,7 +263,6 @@ static void multwrite_intr (ide_drive_t *drive)
                error = 1;
 
 out:
-       spin_unlock_irqrestore(&io_request_lock,flags);
 
        if (error)
                ide_error(drive, "multwrite_intr", stat);
index 7750e944654284ef140806d89e4ed6ea472587a1..3f3a9cd6c6280006f4d466c4c150efb797c15480 100644 (file)
@@ -1265,10 +1265,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
 #define IDE_IRQ_EQUAL(irq1, irq2)      ((irq1) == (irq2))
 #endif
 
-/*
- * entry point for all interrupts, caller does __cli() for us
- */
-void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
+static void do_ide_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
        unsigned long flags;
        ide_hwgroup_t *hwgroup = dev_id;
@@ -1303,13 +1300,11 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
                        ide_sti(); HACK */
                handler(drive);
                /* this is necessary, as next rq may be different irq */
-               spin_lock_irqsave(&io_request_lock,flags);
                if (hwgroup->handler == NULL) {
                        set_recovery_timer(HWIF(drive));
                        drive->service_time = jiffies - drive->service_start;
                        ide_do_request(hwgroup);
                }
-               spin_unlock_irqrestore(&io_request_lock,flags);
        } else {
                unexpected_intr(irq, hwgroup);
        }
@@ -1321,6 +1316,18 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
        } while ((hwif = hwif->next) != hwgroup->hwif);
 }
 
+/*
+ * entry point for all interrupts, caller does __cli() for us
+ */
+void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&io_request_lock, flags);
+       do_ide_intr(irq, dev_id, regs);
+       spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
 /*
  * get_info_ptr() returns the (ide_drive_t *) for a given device number.
  * It returns NULL if the given device number does not match any present drives.
index fded11f2cda91e686e7f7089bccf447ccefe8410..76cbe3150df4c99cd49eafccb0285fab0fbfb9b4 100644 (file)
@@ -148,8 +148,6 @@ void unplug_device(void * data)
                        queue_new_request = 1;
                }
        }
-       spin_unlock_irqrestore(&io_request_lock,flags);
-
        if (queue_new_request)
                /*
                 * request functions are smart enough to notice a change
@@ -157,6 +155,8 @@ void unplug_device(void * data)
                 * is OK, i think. <-- FIXME: [is this true? --mingo]
                 */
                (dev->request_fn)();
+
+       spin_unlock_irqrestore(&io_request_lock,flags);
 }
 
 /*
@@ -348,14 +348,13 @@ void add_request(struct blk_dev_struct * dev, struct request * req)
        if (scsi_blk_major(MAJOR(req->rq_dev)))
                queue_new_request = 1;
 out:
-       spin_unlock_irqrestore(&io_request_lock,flags);
-
        /*
         * request_fn() is usually a quite complex and slow function,
         * we want to call it with no spinlocks held
         */
        if (queue_new_request)
                (dev->request_fn)();
+       spin_unlock_irqrestore(&io_request_lock,flags);
 }
 
 /*
index 6e041a550c77947500ca5f7fa7843b5855a0d6ea..7bab0702365a347ad88f68104f786da04047710c 100644 (file)
@@ -472,12 +472,11 @@ __initfunc(void
 tga_console_init(void))
 {
        struct pci_dev *dev;
-       int status;
        
        /*
         * first, find the TGA among the PCI devices...
         */
-       if (! (dev = pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA, NULL)))
+       if (! (dev = pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA, NULL))) {
                /* PANIC!!! */
                printk("tga_console_init: TGA not found!!! :-(\n");
                return;
index b1fe56af6eddd048e4efa7fd1e14d8f78872e879..89f38ff72716053e4ed1536df3aa8875c7fcfe29 100644 (file)
@@ -677,7 +677,7 @@ static long open_intr_election(void)
 static int close_intr_election(long tmp)
 {
        int irq = PARPORT_IRQ_NONE;
-       int i;
+       int i, valid = 1;
 
        /* We ignore the timer - irq 0 */
        for (i = 1; i < 16; i++)
@@ -685,12 +685,15 @@ static int close_intr_election(long tmp)
                        if (intr_vote[i]) {
                                if (irq != PARPORT_IRQ_NONE)
                                        /* More than one interrupt */
-                                       return PARPORT_IRQ_NONE;
+                                       valid = 0;
                                irq = i;
                        }
                        free_irq(i, intr_vote);
                }
-       return irq;
+       if(valid)
+               return irq;
+       else
+               return PARPORT_IRQ_NONE;
 }
 
 /* Only if supports ECP mode */
index b36cee01b881614cd5a712968684ac548168ac42..10cf519410e1f196534e23a1042d299ac83b54f6 100644 (file)
@@ -215,7 +215,7 @@ __initfunc(static int ne_probe_pci(struct device *dev))
                        if (check_region(pci_ioaddr, NE_IO_EXTENT))
                                continue;
                        pci_irq_line = pdev->irq;
-                       if (pci_irq_line == 0) continue;        /* Try next PCI ID */
+                       if (pci_irq_line) break;        /* Found it */
                }
                if (!pdev)
                        continue;
index a505547221634131a0d08d4f60f9b7b4eb953393..0af8170ca73e0f373629bf1b1ef32f3b1db36b76 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
 #include <asm/page.h>
 
 #ifdef CONFIG_PROC_FS
@@ -912,4 +914,15 @@ int get_pci_list(char *buf)
        return len;
 }
 
+static struct proc_dir_entry proc_old_pci = {
+       PROC_PCI, 3, "pci",
+       S_IFREG | S_IRUGO, 1, 0, 0,
+       0, &proc_array_inode_operations
+};
+
+__initfunc(void proc_old_pci_init(void))
+{
+       proc_register(&proc_root, &proc_old_pci);
+}
+
 #endif /* CONFIG_PROC_FS */
index c8675207c9b0c506d2c63db9902a3d6df7046c54..4ce9459836ce5ed11ae006d85459433b18a16758 100644 (file)
@@ -20,6 +20,7 @@
 struct pci_bus pci_root;
 struct pci_dev *pci_devices = NULL;
 static struct pci_dev **pci_last_dev_p = &pci_devices;
+static int pci_reverse __initdata = 0;
 
 #undef DEBUG
 
@@ -193,8 +194,13 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
                 * Put it into the global PCI device chain. It's used to
                 * find devices once everything is set up.
                 */
-               *pci_last_dev_p = dev;
-               pci_last_dev_p = &dev->next;
+               if (!pci_reverse) {
+                       *pci_last_dev_p = dev;
+                       pci_last_dev_p = &dev->next;
+               } else {
+                       dev->next = pci_devices;
+                       pci_devices = dev;
+               }
 
                /*
                 * Now insert it into the list of devices held
@@ -203,6 +209,17 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
                dev->sibling = bus->devices;
                bus->devices = dev;
 
+               /*
+                * In case the latency timer value is less than 32,
+                * which makes everything very sllooowww, set it to
+                * 32. Pciutils should be used to fine-tune it later.
+                * Note that we don't check if the device is a bus-master:
+                * if it isn't, write to the latency timer should be ignored.
+                */
+               pcibios_read_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER, &tmp);
+               if (tmp < 32)
+                       pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER, 32);
+
                /*
                 * If it's a bridge, scan the bus behind it.
                 */
@@ -299,6 +316,7 @@ __initfunc(void pci_init(void))
 
        if (!pci_present()) {
                printk("PCI: No PCI bus detected\n");
+               return;
        }
 
        printk("PCI: Probing PCI hardware.\n");
@@ -312,12 +330,30 @@ __initfunc(void pci_init(void))
 #ifdef CONFIG_PCI_OPTIMIZE
        pci_quirks_init();
 #endif
+
+#ifdef CONFIG_PROC_FS
+       proc_bus_pci_init();
+#ifdef CONFIG_PCI_OLD_PROC
+       proc_old_pci_init();
+#endif
+#endif
 }
 
 
 __initfunc(void pci_setup (char *str, int *ints))
 {
        str = pcibios_setup(str);
-       if (*str)
-               printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
+       while (str) {
+               char *k = strchr(str, ',');
+               if (k)
+                       *k++ = 0;
+               if (*str) {
+                       if (!(str = pcibios_setup(str)) || !*str)
+                               continue;
+                       if (!strcmp(str, "reverse"))
+                               pci_reverse = 1;
+                       else printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
+               }
+               str = k;
+       }
 }
index a658b1174f7d8aa5185d9294ed65f532fed6cba4..ed2d7369d1d9a56ff83a844cce19a2d9b5bca334 100644 (file)
@@ -42,6 +42,9 @@
 #include <linux/stat.h>
 #include <linux/pci.h>
 #include <linux/bios32.h>
+
+#include <linux/blk.h>
+
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -3267,8 +3270,7 @@ static void BusLogic_ProcessCompletedCCBs(void)
   BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
   Adapters.
 */
-
-static void BusLogic_InterruptHandler(int IRQ_Channel,
+static void do_BusLogic_InterruptHandler(int IRQ_Channel,
                                      void *DeviceIdentifier,
                                      Registers_T *InterruptRegisters)
 {
@@ -3375,6 +3377,22 @@ static void BusLogic_InterruptHandler(int IRQ_Channel,
        }
 }
 
+/*
+ * This is the low-level interrupt handler:
+ * we get the io request lock here to guarantee
+ * that all of this is atomic wrt the setup
+ * functions.
+ */
+static void BusLogic_InterruptHandler(int IRQ_Channel,
+                                     void *DeviceIdentifier,
+                                     Registers_T *InterruptRegisters)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&io_request_lock, flags);
+       do_BusLogic_InterruptHandler(IRQ_Channel, DeviceIdentifier, InterruptRegisters);
+       spin_unlock_irqrestore(&io_request_lock, flags);
+}
 
 /*
   BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
index 802dd3fba2701b504338c0f69358dd5c9b0c833d..a9ec8f76a733029b272629b9aca2819da0cbd638 100644 (file)
@@ -228,6 +228,9 @@ void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
     struct ecb *ecbptr;
     Scsi_Cmnd *SCtmp;
     unsigned int base;
+    unsigned long flags;
+
+    spin_lock_irqsave(&io_request_lock, flags);
 
     if (!aha_host[irq - 9])
        panic("aha1740.c: Irq from unknown host!\n");
@@ -304,6 +307,8 @@ void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
        }
        number_serviced++;
     }
+
+    spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
index 3fc9f9873a084298ddd584a3d8daf19229138f70..f794d321e31ff7aadb18ff979ef563f3e053a873 100644 (file)
@@ -9787,12 +9787,16 @@ printk("ncr53c8xx : command successfully queued\n");
 #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
 static void ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
 {
+     unsigned long flags;
+
 #ifdef DEBUG_NCR53C8XX
      printk("ncr53c8xx : interrupt received\n");
 #endif
 
      if (DEBUG_FLAGS & DEBUG_TINY) printf ("[");
+     spin_lock_irqsave(&io_request_lock, flags);
      ncr_exception((ncb_p) dev_id);
+     spin_unlock_irqrestore(&io_request_lock, flags);
      if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n");
 }
 
index 32eca4960788685165b6544b0419f297e771d3d3..e6036eea4edd3c53f8be427e56577aa0f07ad687 100644 (file)
@@ -354,7 +354,6 @@ scsi_make_blocked_list(void)
      */
 
    
-    spin_lock_irqsave(&io_request_lock, flags);
     host_active = NULL;
 
     for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next) {
@@ -386,7 +385,6 @@ scsi_make_blocked_list(void)
               sh[index]->host_no);
     }
 
-    spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 static void scan_scsis_done (Scsi_Cmnd * SCpnt)
@@ -653,9 +651,11 @@ int scan_scsis_single (int channel, int dev, int lun, int *max_dev_lun,
     struct semaphore sem = MUTEX_LOCKED;
     SCpnt->request.sem = &sem;
     SCpnt->request.rq_status = RQ_SCSI_BUSY;
+    spin_lock_irq(&io_request_lock);
     scsi_do_cmd (SCpnt, (void *) scsi_cmd,
                  (void *) scsi_result,
                  256, scan_scsis_done, SCSI_TIMEOUT + 4 * HZ, 5);
+    spin_unlock_irq(&io_request_lock);
     down (&sem);
     SCpnt->request.sem = NULL;
   }
@@ -694,9 +694,11 @@ int scan_scsis_single (int channel, int dev, int lun, int *max_dev_lun,
     struct semaphore sem = MUTEX_LOCKED;
     SCpnt->request.sem = &sem;
     SCpnt->request.rq_status = RQ_SCSI_BUSY;
+    spin_lock_irq(&io_request_lock);
     scsi_do_cmd (SCpnt, (void *) scsi_cmd,
                  (void *) scsi_result,
                  256, scan_scsis_done, SCSI_TIMEOUT, 3);
+    spin_unlock_irq(&io_request_lock);
     down (&sem);
     SCpnt->request.sem = NULL;
   }
@@ -836,9 +838,11 @@ int scan_scsis_single (int channel, int dev, int lun, int *max_dev_lun,
       struct semaphore sem = MUTEX_LOCKED;
       SCpnt->request.rq_status = RQ_SCSI_BUSY;
       SCpnt->request.sem = &sem;
+      spin_lock_irq(&io_request_lock);
       scsi_do_cmd (SCpnt, (void *) scsi_cmd,
                    (void *) scsi_result, 0x2a,
                    scan_scsis_done, SCSI_TIMEOUT, 3);
+      spin_unlock_irq(&io_request_lock);
       down (&sem);
       SCpnt->request.sem = NULL;
     }
@@ -1133,21 +1137,18 @@ Scsi_Cmnd * scsi_allocate_device (struct request ** reqp, Scsi_Device * device,
            SCpnt = found;
        }
 
-        __save_flags(flags);
-       __cli();
        /* See if this request has already been queued by an interrupt routine
         */
        if (req && (req->rq_status == RQ_INACTIVE || req->rq_dev != dev)) {
-          __restore_flags(flags);
            return NULL;
        }
        if (!SCpnt || SCpnt->request.rq_status != RQ_INACTIVE)  /* Might have changed */
        {
                if (wait && SCwait && SCwait->request.rq_status != RQ_INACTIVE){
+                       spin_unlock(&io_request_lock);          /* FIXME!!!! */
                        sleep_on(&device->device_wait);
-                       __restore_flags(flags);
+                       spin_lock_irq(&io_request_lock);        /* FIXME!!!! */
                } else {
-                       __restore_flags(flags);
                        if (!wait) return NULL;
                        if (!SCwait) {
                                printk("Attempt to allocate device channel %d,"
@@ -1197,7 +1198,6 @@ Scsi_Cmnd * scsi_allocate_device (struct request ** reqp, Scsi_Device * device,
                                              * to complete */
            }
             atomic_inc(&SCpnt->host->host_active); 
-           __restore_flags(flags);
             SCSI_LOG_MLQUEUE(5, printk("Activating command for device %d (%d)\n", 
                                        SCpnt->target,
                                        atomic_read(&SCpnt->host->host_active)));
@@ -1294,7 +1294,6 @@ inline int internal_cmnd (Scsi_Cmnd * SCpnt)
 
     host = SCpnt->host;
 
-    spin_lock_irqsave(&io_request_lock, flags);
     /* Assign a unique nonzero serial_number. */
     if (++serial_number == 0) serial_number = 1;
     SCpnt->serial_number = serial_number;
@@ -1304,7 +1303,6 @@ inline int internal_cmnd (Scsi_Cmnd * SCpnt)
      * we can avoid the drive not being ready.
      */
     timeout = host->last_reset + MIN_RESET_DELAY;
-    spin_unlock(&io_request_lock);
 
     if (jiffies < timeout) {
        int ticks_remaining = timeout - jiffies;
@@ -1317,11 +1315,11 @@ inline int internal_cmnd (Scsi_Cmnd * SCpnt)
         * interrupt handler (assuming there is one irq-level per
         * host).
         */
-       __sti();
+       spin_unlock_irq(&io_request_lock);
        while (--ticks_remaining >= 0) udelay(1000000/HZ);
        host->last_reset = jiffies - MIN_RESET_DELAY;
+       spin_lock_irq(&io_request_lock);
     }
-    __restore_flags(flags); /* this possibly puts us back into __cli() */
 
     if( host->hostt->use_new_eh_code )
       {
@@ -1348,18 +1346,6 @@ inline int internal_cmnd (Scsi_Cmnd * SCpnt)
     {
        SCSI_LOG_MLQUEUE(3,printk("queuecommand : routine at %p\n",
                                   host->hostt->queuecommand));
-       /* This locking tries to prevent all sorts of races between
-        * queuecommand and the interrupt code.  In effect,
-        * we are only allowed to be in queuecommand once at
-        * any given time, and we can only be in the interrupt
-        * handler and the queuecommand function at the same time
-        * when queuecommand is called while servicing the
-        * interrupt.
-        */
-
-       if(!in_interrupt() && SCpnt->host->irq)
-           disable_irq(SCpnt->host->irq);
-
         /*
          * Use the old error handling code if we haven't converted the driver
          * to use the new one yet.  Note - only the new queuecommand variant
@@ -1377,9 +1363,6 @@ inline int internal_cmnd (Scsi_Cmnd * SCpnt)
           {
             host->hostt->queuecommand (SCpnt, scsi_old_done);
           }
-
-       if(!in_interrupt() && SCpnt->host->irq)
-           enable_irq(SCpnt->host->irq);
     }
     else
     {
@@ -1452,20 +1435,18 @@ SCSI_LOG_MLQUEUE(4,
      * ourselves.
      */
 
-    spin_lock_irqsave(&io_request_lock, flags);
     SCpnt->pid = scsi_pid++;
 
     while (SCSI_BLOCK((Scsi_Device *) NULL, host)) {
-       spin_unlock_irqrestore(&io_request_lock, flags);
+       spin_unlock(&io_request_lock);  /* FIXME!!! */
        SCSI_SLEEP(&host->host_wait, SCSI_BLOCK((Scsi_Device *) NULL, host));
-       spin_lock_irqsave(&io_request_lock, flags);
+       spin_lock_irq(&io_request_lock);        /* FIXME!!! */
     }
 
     if (host->block) host_active = host;
 
     host->host_busy++;
     device->device_busy++;
-    spin_unlock_irqrestore(&io_request_lock, flags);
 
     /*
      * Our own function scsi_done (which marks the host as not busy, disables
@@ -1819,7 +1800,6 @@ void *scsi_malloc(unsigned int len)
     if(len % SECTOR_SIZE != 0 || len > PAGE_SIZE)
        return NULL;
 
-    spin_lock_irqsave(&io_request_lock, flags);
     nbits = len >> 9;
     mask = (1 << nbits) - 1;
 
@@ -1827,7 +1807,6 @@ void *scsi_malloc(unsigned int len)
        for(j=0; j<=SECTORS_PER_PAGE - nbits; j++){
            if ((dma_malloc_freelist[i] & (mask << j)) == 0){
                dma_malloc_freelist[i] |= (mask << j);
-               spin_unlock_irqrestore(&io_request_lock, flags);
                scsi_dma_free_sectors -= nbits;
 #ifdef DEBUG
                 SCSI_LOG_MLQUEUE(3,printk("SMalloc: %d %p [From:%p]\n",len, dma_malloc_pages[i] + (j << 9)));
@@ -1836,7 +1815,6 @@ void *scsi_malloc(unsigned int len)
                return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
            }
        }
-    spin_unlock_irqrestore(&io_request_lock, flags);
     return NULL;  /* Nope.  No more */
 }
 
@@ -1870,20 +1848,16 @@ int scsi_free(void *obj, unsigned int len)
             if ((mask << sector) >= (1 << SECTORS_PER_PAGE))
                 panic ("scsi_free:Bad memory alignment");
 
-           spin_lock_irqsave(&io_request_lock, flags);
             if((dma_malloc_freelist[page] &
                 (mask << sector)) != (mask<<sector)){
-               spin_unlock_irqrestore(&io_request_lock, flags);
 #ifdef DEBUG
                printk("scsi_free(obj=%p, len=%d) called from %08lx\n",
                        obj, len, ret);
 #endif
                 panic("scsi_free:Trying to free unused memory");
-               spin_lock_irqsave(&io_request_lock, flags);
             }
             scsi_dma_free_sectors += nbits;
             dma_malloc_freelist[page] &= ~(mask << sector);
-           spin_unlock_irqrestore(&io_request_lock, flags);
             return 0;
        }
     }
@@ -2547,7 +2521,6 @@ static void resize_dma_pool(void)
     /* When we dick with the actual DMA list, we need to
      * protect things
      */
-    spin_lock_irqsave(&io_request_lock, flags);
     if (dma_malloc_freelist)
     {
         size = (dma_sectors / SECTORS_PER_PAGE)*sizeof(FreeSectorBitmap);
@@ -2567,7 +2540,6 @@ static void resize_dma_pool(void)
     dma_malloc_pages = new_dma_malloc_pages;
     dma_sectors = new_dma_sectors;
     scsi_need_isa_buffer = new_need_isa_buffer;
-    spin_unlock_irqrestore(&io_request_lock, flags);
 
 #ifdef DEBUG_INIT
     printk("resize_dma_pool: dma free sectors   = %d\n", scsi_dma_free_sectors);
@@ -2806,10 +2778,8 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt)
            {
                 online_status = SDpnt->online;
                 SDpnt->online = FALSE;
-               spin_lock_irqsave(&io_request_lock, flags);
                if(SCpnt->request.rq_status != RQ_INACTIVE) 
                 {
-                   spin_unlock_irqrestore(&io_request_lock, flags);
                     printk("SCSI device not inactive - state=%d, id=%d\n",
                            SCpnt->request.rq_status, SCpnt->target);
                     for(SDpnt1 = shpnt->host_queue; SDpnt1; 
@@ -2830,7 +2800,6 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt)
                  */
                 SCpnt->state = SCSI_STATE_DISCONNECTING;
                SCpnt->request.rq_status = RQ_SCSI_DISCONNECTING;  /* Mark as busy */
-               spin_unlock_irqrestore(&io_request_lock, flags);
            }
         }
     }
index 9826fb9900410ad73c3e555a5c61e7e75637c009..035d90b7ab1076c4d812af0c072102cc8b4f1062 100644 (file)
@@ -686,7 +686,6 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors
 #define INIT_SCSI_REQUEST       \
     if (!CURRENT) {             \
        CLEAR_INTR;             \
-       spin_unlock_irqrestore(&io_request_lock,flags); \
        return;                 \
     }                           \
     if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)           \
index 5f0668eb6d197a6ee1ddefb6d6347d242cec10ce..e7da5c95414a456c80b98f7b08dfa017f19169b7 100644 (file)
@@ -36,6 +36,9 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 
+#include <linux/smp.h>
+#include <asm/smp_lock.h>
+
 #include <asm/system.h>
 #include <asm/io.h>
 
@@ -513,14 +516,10 @@ static void do_sd_request (void)
     Scsi_Cmnd * SCpnt = NULL;
     Scsi_Device * SDev;
     struct request * req = NULL;
-    unsigned long flags;
     int flag = 0;
 
     while (1==1){
-       spin_lock_irqsave(&io_request_lock, flags);
-
        if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) {
-            spin_unlock_irqrestore(&io_request_lock, flags);
            return;
        }
 
@@ -535,7 +534,6 @@ static void do_sd_request (void)
          */
         if( SDev->host->in_recovery )
           {
-            spin_unlock_irqrestore(&io_request_lock, flags);
             return;
           }
 
@@ -555,10 +553,11 @@ static void do_sd_request (void)
             */
            if( SDev->removable && !in_interrupt() )
            {
-                spin_unlock_irqrestore(&io_request_lock, flags);
+                spin_unlock_irq(&io_request_lock);     /* FIXME!!!! */
                 scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
                /* scsi_ioctl may allow CURRENT to change, so start over. */
                SDev->was_reset = 0;
+                spin_lock_irq(&io_request_lock);       /* FIXME!!!! */
                continue;
            }
            SDev->was_reset = 0;
@@ -587,7 +586,6 @@ static void do_sd_request (void)
         * Using a "sti()" gets rid of the latency problems but causes
         * race conditions and crashes.
         */
-        spin_unlock_irqrestore(&io_request_lock, flags);
 
        /* This is a performance enhancement. We dig down into the request
         * list and try to find a queueable request (i.e. device not busy,
@@ -605,7 +603,6 @@ static void do_sd_request (void)
        if (!SCpnt && sd_template.nr_dev > 1){
            struct request *req1;
            req1 = NULL;
-           spin_lock_irqsave(&io_request_lock, flags);
            req = CURRENT;
            while(req){
                SCpnt = scsi_request_queueable(req,
@@ -620,7 +617,6 @@ static void do_sd_request (void)
                else
                    req1->next = req->next;
            }
-            spin_unlock_irqrestore(&io_request_lock, flags);
        }
 
        if (!SCpnt) return; /* Could not find anything to do */
@@ -1125,6 +1121,8 @@ static int sd_init_onedisk(int i)
         return i;
     }
 
+    spin_lock_irq(&io_request_lock);
+
     /* We need to retry the READ_CAPACITY because a UNIT_ATTENTION is
      * considered a fatal error, and many devices report such an error
      * just after a scsi bus reset.
@@ -1157,7 +1155,9 @@ static int sd_init_onedisk(int i)
                                 (void *) cmd, (void *) buffer,
                                 512, sd_init_done,  SD_TIMEOUT,
                                 MAX_RETRIES);
+                   spin_unlock_irq(&io_request_lock);
                    down(&sem);
+                   spin_lock_irq(&io_request_lock);
                     SCpnt->request.sem = NULL;
                }
 
@@ -1193,7 +1193,9 @@ static int sd_init_onedisk(int i)
                                     (void *) cmd, (void *) buffer,
                                     512, sd_init_done,  SD_TIMEOUT,
                                     MAX_RETRIES);
+                       spin_unlock_irq(&io_request_lock);
                        down(&sem);
+                       spin_lock_irq(&io_request_lock);
                         SCpnt->request.sem = NULL;
                    }
 
@@ -1201,8 +1203,10 @@ static int sd_init_onedisk(int i)
                }
 
                time1 = jiffies + HZ;
+               spin_unlock_irq(&io_request_lock);
                while(jiffies < time1); /* Wait 1 second for next try */
                printk( "." );
+               spin_lock_irq(&io_request_lock);
            }
        } while(the_result && spintime && spintime+100*HZ > jiffies);
        if (spintime) {
@@ -1231,7 +1235,9 @@ static int sd_init_onedisk(int i)
                         (void *) cmd, (void *) buffer,
                         8, sd_init_done,  SD_TIMEOUT,
                         MAX_RETRIES);
+           spin_unlock_irq(&io_request_lock);
            down(&sem); /* sleep until it is ready */
+           spin_lock_irq(&io_request_lock);
             SCpnt->request.sem = NULL;
        }
 
@@ -1406,7 +1412,9 @@ static int sd_init_onedisk(int i)
                         (void *) cmd, (void *) buffer,
                         512, sd_init_done,  SD_TIMEOUT,
                         MAX_RETRIES);
+           spin_unlock_irq(&io_request_lock);
            down(&sem);
+           spin_lock_irq(&io_request_lock);
             SCpnt->request.sem = NULL;
        }
 
@@ -1431,6 +1439,7 @@ static int sd_init_onedisk(int i)
     rscsi_disks[i].ten = 1;
     rscsi_disks[i].remap = 1;
     scsi_free(buffer, 512);
+    spin_unlock_irq(&io_request_lock);
     return i;
 }
 
@@ -1590,7 +1599,6 @@ static int sd_attach(Scsi_Device * SDp){
 int revalidate_scsidisk(kdev_t dev, int maxusage){
     int target;
     struct gendisk * gdev;
-    unsigned long flags;
     int max_p;
     int start;
     int i;
@@ -1598,14 +1606,11 @@ int revalidate_scsidisk(kdev_t dev, int maxusage){
     target =  DEVICE_NR(dev);
     gdev = &GENDISK_STRUCT;
 
-    spin_lock_irqsave(&io_request_lock, flags);
     if (DEVICE_BUSY || USAGE > maxusage) {
-       spin_unlock_irqrestore(&io_request_lock, flags);
        printk("Device busy for revalidation (usage=%d)\n", USAGE);
        return -EBUSY;
     }
     DEVICE_BUSY = 1;
-    spin_unlock_irqrestore(&io_request_lock, flags);
 
     max_p = gdev->max_p;
     start = target << gdev->minor_shift;
index b5d76f7e52f4e84e65cdcaef4cf9d952ffb2a7df..a6afe2a2ceefea01bfab3b05b785803f09c7e7bb 100644 (file)
@@ -250,23 +250,22 @@ static ssize_t sg_read(struct file *filp, char *buf,
     /*
      * Wait until the command is actually done.
      */
-    save_flags(flags);
-    cli();
+    spin_lock_irqsave(&io_request_lock, flags);
     while(!device->pending || !device->complete)
     {
        if (filp->f_flags & O_NONBLOCK)
        {
-           restore_flags(flags);
+           spin_unlock_irqrestore(&io_request_lock, flags);
            return -EAGAIN;
        }
        interruptible_sleep_on(&device->read_wait);
        if (signal_pending(current))
        {
-           restore_flags(flags);
+           spin_unlock_irqrestore(&io_request_lock, flags);
            return -ERESTARTSYS;
        }
     }
-    restore_flags(flags);
+    spin_unlock_irqrestore(&io_request_lock, flags);
 
     /*
      * Now copy the result back to the user buffer.
index e5d3e830a27dea84c23f541730fa6f899bd9a635..c273b49de816f8720511e9be4bd00829a1d65ac5 100644 (file)
@@ -431,10 +431,7 @@ static void do_sr_request (void)
     int flag = 0;
 
     while (1==1){
-       spin_lock_irqsave(&io_request_lock, flags);
-
        if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) {
-           spin_unlock_irqrestore(&io_request_lock, flags);
            return;
        };
 
@@ -450,7 +447,6 @@ static void do_sr_request (void)
          */
         if( SDev->host->in_recovery )
           {
-           spin_unlock_irqrestore(&io_request_lock, flags);
             return;
           }
 
@@ -469,8 +465,9 @@ static void do_sr_request (void)
             */
            if( SDev->removable && !in_interrupt() )
            {
-               spin_unlock_irqrestore(&io_request_lock, flags);
+               spin_unlock_irq(&io_request_lock);              /* FIXME!!!! */
                scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
+               spin_lock_irq(&io_request_lock);                /* FIXME!!!! */
                /* scsi_ioctl may allow CURRENT to change, so start over. */
                SDev->was_reset = 0;
                continue;
@@ -493,7 +490,6 @@ static void do_sr_request (void)
            SCpnt = scsi_allocate_device(&CURRENT,
                                    scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].device, 0);
        else SCpnt = NULL;
-       spin_unlock_irqrestore(&io_request_lock, flags);
 
        /* This is a performance enhancement.  We dig down into the request list and
         * try to find a queueable request (i.e. device not busy, and host able to
@@ -505,7 +501,6 @@ static void do_sr_request (void)
        if (!SCpnt && sr_template.nr_dev > 1){
            struct request *req1;
            req1 = NULL;
-           spin_lock_irqsave(&io_request_lock, flags);
            req = CURRENT;
            while(req){
                SCpnt = scsi_request_queueable(req,
@@ -520,7 +515,6 @@ static void do_sr_request (void)
                else
                    req1->next = req->next;
            }
-           spin_unlock_irqrestore(&io_request_lock, flags);
        }
 
        if (!SCpnt)
index 597ee660d4c9bcccb87c94c6b90329b848ef6b12..728c8ed1c602a4d1512d6ac84ebfd693ca47f153 100644 (file)
@@ -784,7 +784,7 @@ asmlinkage int sys_getcwd(char *buf, unsigned long size)
 
        error = -ENOENT;
        /* Has the current directory has been unlinked? */
-       if (pwd->d_parent != pwd && list_empty(&pwd->d_hash)) {
+       if (pwd->d_parent == pwd || !list_empty(&pwd->d_hash)) {
                char *page = (char *) __get_free_page(GFP_USER);
                error = -ENOMEM;
                if (page) {
index ad3a541cb3a6cb9896f4e9e015f8bb1c5ea252d3..75f81f9b982c74ddb21964bc4bf91b38d75945a7 100644 (file)
@@ -499,13 +499,6 @@ static struct proc_dir_entry proc_root_version = {
        S_IFREG | S_IRUGO, 1, 0, 0,
        0, &proc_array_inode_operations
 };
-#ifdef CONFIG_PCI_OLD_PROC
-static struct proc_dir_entry proc_root_pci = {
-       PROC_PCI, 3, "pci",
-       S_IFREG | S_IRUGO, 1, 0, 0,
-       0, &proc_array_inode_operations
-};
-#endif
 #ifdef CONFIG_ZORRO
 static struct proc_dir_entry proc_root_zorro = {
        PROC_ZORRO, 5, "zorro",
@@ -640,9 +633,6 @@ void proc_root_init(void)
        proc_register(&proc_root, &proc_root_meminfo);
        proc_register(&proc_root, &proc_root_kmsg);
        proc_register(&proc_root, &proc_root_version);
-#ifdef CONFIG_PCI_OLD_PROC
-       proc_register(&proc_root, &proc_root_pci);
-#endif
 #ifdef CONFIG_ZORRO
        proc_register(&proc_root, &proc_root_zorro);
 #endif
@@ -707,9 +697,6 @@ void proc_root_init(void)
 #endif
 
        proc_bus = create_proc_entry("bus", S_IFDIR, 0);
-#ifdef CONFIG_PCI
-       proc_bus_pci_init();
-#endif
 }
 
 /*
index 3cab9e664d3adedde7f56331806cbf28cabc92f3..1819cb353b1ade52cf028a5397cdb48ece411f45 100644 (file)
 
 #ifdef __KERNEL__
 
-/* Create an index into the pci_dev base_address[] array from an offset.  */
-#define PCI_BASE_INDEX(o) (((o)-PCI_BASE_ADDRESS_0)>>2)
-
 /*
  * Error values that may be returned by the PCI bios.  Use
  * pcibios_strerror() to convert to a printable string.
@@ -1078,6 +1075,8 @@ void pci_init(void);
 void pci_setup(char *str, int *ints);
 void pci_quirks_init(void);
 unsigned int pci_scan_bus(struct pci_bus *bus);
+void proc_bus_pci_init(void);
+void proc_old_pci_init(void);
 
 struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
 struct pci_dev *pci_find_class (unsigned int class, struct pci_dev *from);
index 1c81c23dedda54e2d149e1887b0305e5bce85623..076fbd6613d80d2d70923a25e661a076d9025fef 100644 (file)
@@ -275,7 +275,6 @@ extern struct inode_operations proc_scsi_inode_operations;
 
 extern void proc_root_init(void);
 extern void proc_base_init(void);
-extern void proc_bus_pci_init(void);
 
 extern int proc_register(struct proc_dir_entry *, struct proc_dir_entry *);
 extern int proc_unregister(struct proc_dir_entry *, int);