diff -u --recursive --new-file v2.1.94/linux/Makefile linux/Makefile --- v2.1.94/linux/Makefile Wed Apr 8 19:36:24 1998 +++ linux/Makefile Wed Apr 8 19:36:06 1998 @@ -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/) diff -u --recursive --new-file v2.1.94/linux/arch/alpha/kernel/apecs.c linux/arch/alpha/kernel/apecs.c --- v2.1.94/linux/arch/alpha/kernel/apecs.c Wed Apr 1 20:11:47 1998 +++ linux/arch/alpha/kernel/apecs.c Thu Apr 9 13:16:18 1998 @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff -u --recursive --new-file v2.1.94/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c --- v2.1.94/linux/arch/alpha/kernel/bios32.c Wed Apr 8 19:36:24 1998 +++ linux/arch/alpha/kernel/bios32.c Thu Apr 9 13:16:18 1998 @@ -250,7 +250,7 @@ { 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 @@ 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 @@ 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 @@ 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 @@ "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: diff -u --recursive --new-file v2.1.94/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c --- v2.1.94/linux/arch/i386/kernel/bios32.c Wed Apr 8 19:36:24 1998 +++ linux/arch/i386/kernel/bios32.c Thu Apr 9 13:16:18 1998 @@ -834,44 +834,52 @@ __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 \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 \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 @@ } #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 \n", + dev->bus->number, dev->devfn, pin); } } @@ -919,25 +930,25 @@ { 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; diff -u --recursive --new-file v2.1.94/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.1.94/linux/arch/i386/kernel/irq.c Wed Apr 8 19:36:25 1998 +++ linux/arch/i386/kernel/irq.c Thu Apr 9 22:10:59 1998 @@ -537,20 +537,31 @@ 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 @@ __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 @@ outb_p(LATCH & 0xff , 0x40); /* LSB */ outb(LATCH >> 8 , 0x40); /* MSB */ - printk("INIT IRQ\n"); for (i=0; imult_count; - spin_lock_irqsave(&io_request_lock,flags); read_next: rq = HWGROUP(drive)->rq; if (msect) { @@ -152,7 +151,6 @@ goto read_next; ide_set_handler (drive, &read_intr, WAIT_CMD); } - spin_unlock_irqrestore(&io_request_lock,flags); } /* @@ -167,7 +165,6 @@ 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 @@ error = 1; out: - spin_unlock_irqrestore(&io_request_lock,flags); if (error) ide_error(drive, "write_intr", stat); @@ -246,7 +242,6 @@ 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 @@ error = 1; out: - spin_unlock_irqrestore(&io_request_lock,flags); if (error) ide_error(drive, "multwrite_intr", stat); diff -u --recursive --new-file v2.1.94/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.1.94/linux/drivers/block/ide.c Mon Apr 6 17:40:59 1998 +++ linux/drivers/block/ide.c Thu Apr 9 15:42:07 1998 @@ -1265,10 +1265,7 @@ #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 @@ 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); } @@ -1319,6 +1314,18 @@ if (!IDE_IRQ_EQUAL(hwif->irq, irq)) enable_irq(hwif->irq); } 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); } /* diff -u --recursive --new-file v2.1.94/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.1.94/linux/drivers/block/ll_rw_blk.c Mon Apr 6 17:40:59 1998 +++ linux/drivers/block/ll_rw_blk.c Thu Apr 9 13:44:53 1998 @@ -148,8 +148,6 @@ 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 @@ * is OK, i think. <-- FIXME: [is this true? --mingo] */ (dev->request_fn)(); + + spin_unlock_irqrestore(&io_request_lock,flags); } /* @@ -348,14 +348,13 @@ 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); } /* diff -u --recursive --new-file v2.1.94/linux/drivers/char/tga.c linux/drivers/char/tga.c --- v2.1.94/linux/drivers/char/tga.c Mon Apr 6 17:40:59 1998 +++ linux/drivers/char/tga.c Thu Apr 9 13:10:15 1998 @@ -472,12 +472,11 @@ 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; diff -u --recursive --new-file v2.1.94/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c --- v2.1.94/linux/drivers/misc/parport_pc.c Mon Apr 6 17:41:00 1998 +++ linux/drivers/misc/parport_pc.c Thu Apr 9 11:38:13 1998 @@ -677,7 +677,7 @@ 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 @@ 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 */ diff -u --recursive --new-file v2.1.94/linux/drivers/net/ne.c linux/drivers/net/ne.c --- v2.1.94/linux/drivers/net/ne.c Mon Apr 6 17:41:00 1998 +++ linux/drivers/net/ne.c Thu Apr 9 16:20:29 1998 @@ -215,7 +215,7 @@ 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; diff -u --recursive --new-file v2.1.94/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c --- v2.1.94/linux/drivers/pci/oldproc.c Mon Apr 6 17:41:00 1998 +++ linux/drivers/pci/oldproc.c Thu Apr 9 13:16:18 1998 @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #ifdef CONFIG_PROC_FS @@ -910,6 +912,17 @@ len += nprinted; } 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 */ diff -u --recursive --new-file v2.1.94/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.1.94/linux/drivers/pci/pci.c Mon Apr 6 17:41:00 1998 +++ linux/drivers/pci/pci.c Thu Apr 9 13:16:18 1998 @@ -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 @@ * 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 @@ -204,6 +210,17 @@ 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. */ if (class >> 8 == PCI_CLASS_BRIDGE_PCI) { @@ -299,6 +316,7 @@ if (!pci_present()) { printk("PCI: No PCI bus detected\n"); + return; } printk("PCI: Probing PCI hardware.\n"); @@ -312,12 +330,30 @@ #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; + } } diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c --- v2.1.94/linux/drivers/scsi/BusLogic.c Wed Apr 1 20:11:52 1998 +++ linux/drivers/scsi/BusLogic.c Thu Apr 9 13:53:13 1998 @@ -42,6 +42,9 @@ #include #include #include + +#include + #include #include #include @@ -3267,8 +3270,7 @@ 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 @@ } } +/* + * 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 diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c --- v2.1.94/linux/drivers/scsi/aha1740.c Thu Mar 27 14:40:05 1997 +++ linux/drivers/scsi/aha1740.c Thu Apr 9 13:47:16 1998 @@ -228,6 +228,9 @@ 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 @@ } number_serviced++; } + + spin_unlock_irqrestore(&io_request_lock, flags); } int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.1.94/linux/drivers/scsi/ncr53c8xx.c Mon Apr 6 17:41:00 1998 +++ linux/drivers/scsi/ncr53c8xx.c Thu Apr 9 22:11:00 1998 @@ -9787,12 +9787,16 @@ #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"); } diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.1.94/linux/drivers/scsi/scsi.c Mon Apr 6 17:41:00 1998 +++ linux/drivers/scsi/scsi.c Thu Apr 9 22:11:00 1998 @@ -354,7 +354,6 @@ */ - spin_lock_irqsave(&io_request_lock, flags); host_active = NULL; for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next) { @@ -386,7 +385,6 @@ sh[index]->host_no); } - spin_unlock_irqrestore(&io_request_lock, flags); } static void scan_scsis_done (Scsi_Cmnd * SCpnt) @@ -653,9 +651,11 @@ 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ 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 @@ * 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 @@ * 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 @@ { 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 @@ { host->hostt->queuecommand (SCpnt, scsi_old_done); } - - if(!in_interrupt() && SCpnt->host->irq) - enable_irq(SCpnt->host->irq); } else { @@ -1452,20 +1435,18 @@ * 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 @@ 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 @@ 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 @@ 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 @@ 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<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 @@ */ SCpnt->state = SCSI_STATE_DISCONNECTING; SCpnt->request.rq_status = RQ_SCSI_DISCONNECTING; /* Mark as busy */ - spin_unlock_irqrestore(&io_request_lock, flags); } } } diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h --- v2.1.94/linux/drivers/scsi/scsi.h Thu Mar 26 15:57:03 1998 +++ linux/drivers/scsi/scsi.h Thu Apr 9 22:29:29 1998 @@ -686,7 +686,6 @@ #define INIT_SCSI_REQUEST \ if (!CURRENT) { \ CLEAR_INTR; \ - spin_unlock_irqrestore(&io_request_lock,flags); \ return; \ } \ if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \ diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c --- v2.1.94/linux/drivers/scsi/sd.c Tue Mar 17 22:18:14 1998 +++ linux/drivers/scsi/sd.c Thu Apr 9 22:19:46 1998 @@ -36,6 +36,9 @@ #include #include +#include +#include + #include #include @@ -513,14 +516,10 @@ 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 @@ */ if( SDev->host->in_recovery ) { - spin_unlock_irqrestore(&io_request_lock, flags); return; } @@ -555,10 +553,11 @@ */ 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 @@ * 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 @@ 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 @@ 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 @@ 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 @@ (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 @@ (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 @@ } 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 @@ (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 @@ (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 @@ 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 @@ 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 @@ 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; diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c --- v2.1.94/linux/drivers/scsi/sg.c Wed Apr 1 20:11:53 1998 +++ linux/drivers/scsi/sg.c Thu Apr 9 22:11:00 1998 @@ -250,23 +250,22 @@ /* * 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. diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- v2.1.94/linux/drivers/scsi/sr.c Tue Mar 10 10:03:33 1998 +++ linux/drivers/scsi/sr.c Thu Apr 9 13:43:52 1998 @@ -431,10 +431,7 @@ 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 @@ */ if( SDev->host->in_recovery ) { - spin_unlock_irqrestore(&io_request_lock, flags); return; } @@ -469,8 +465,9 @@ */ 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 @@ 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 @@ 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 @@ else req1->next = req->next; } - spin_unlock_irqrestore(&io_request_lock, flags); } if (!SCpnt) diff -u --recursive --new-file v2.1.94/linux/fs/dcache.c linux/fs/dcache.c --- v2.1.94/linux/fs/dcache.c Mon Apr 6 17:41:00 1998 +++ linux/fs/dcache.c Thu Apr 9 13:15:40 1998 @@ -784,7 +784,7 @@ 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) { diff -u --recursive --new-file v2.1.94/linux/fs/proc/root.c linux/fs/proc/root.c --- v2.1.94/linux/fs/proc/root.c Tue Mar 17 22:18:15 1998 +++ linux/fs/proc/root.c Thu Apr 9 13:16:18 1998 @@ -499,13 +499,6 @@ 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 @@ 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 @@ #endif proc_bus = create_proc_entry("bus", S_IFDIR, 0); -#ifdef CONFIG_PCI - proc_bus_pci_init(); -#endif } /* diff -u --recursive --new-file v2.1.94/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.1.94/linux/include/linux/pci.h Wed Apr 8 19:36:29 1998 +++ linux/include/linux/pci.h Thu Apr 9 13:16:18 1998 @@ -977,9 +977,6 @@ #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_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); diff -u --recursive --new-file v2.1.94/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h --- v2.1.94/linux/include/linux/proc_fs.h Mon Apr 6 17:41:01 1998 +++ linux/include/linux/proc_fs.h Thu Apr 9 22:28:47 1998 @@ -275,7 +275,6 @@ 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);