Commit 2dcb1dcf authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.95pre1

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