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

Import 2.1.95pre1

parent ad1b31ae
VERSION = 2
PATCHLEVEL = 1
SUBLEVEL = 94
SUBLEVEL = 95
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
......
......@@ -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>
......
......@@ -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:
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 @@ static void read_intr (ide_drive_t *drive)
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);
......
......@@ -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.
......
......@@ -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);
}
/*
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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 */
......@@ -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;
}
}
......@@ -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
......
......@@ -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 *))
......
......@@ -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");
}
......
......@@ -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);
}
}
}
......
......@@ -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) \
......
......@@ -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;
......
......@@ -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.
......
......@@ -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)
......
......@@ -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) {
......
......@@ -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
}
/*
......
......@@ -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_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);
......
......@@ -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);
......
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