diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
commit | dcec8a13bf565e47942a1751a9cec21bec5648fe (patch) | |
tree | 548b69625b18cc2e88c3e68d0923be546c9ebb03 /drivers/scsi/scsi.c | |
parent | 2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff) |
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash.
o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r-- | drivers/scsi/scsi.c | 68 |
1 files changed, 16 insertions, 52 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 90bb6e2d4..0dc7f398f 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -141,7 +141,7 @@ static unsigned char ** dma_malloc_pages = NULL; */ unsigned int scsi_logging_level = 0; -static volatile struct Scsi_Host * host_active = NULL; +volatile struct Scsi_Host * host_active = NULL; #if CONFIG_PROC_FS /* @@ -248,6 +248,7 @@ static struct dev_info device_list[] = {"SONY","CD-ROM CDU-55S","1.0i", BLIST_NOLUN}, {"SONY","CD-ROM CDU-561","1.7x", BLIST_NOLUN}, {"TANDBERG","TDC 3600","U07", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ +{"TEAC","CD-R55S","1.0H", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ {"TEAC","CD-ROM","1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1 * for seagate controller, which causes * SCSI code to reset bus.*/ @@ -332,7 +333,6 @@ void scsi_make_blocked_list(void) { int block_count = 0, index; - unsigned long flags; struct Scsi_Host * sh[128], * shpnt; /* @@ -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) @@ -657,9 +655,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; } @@ -698,9 +698,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; } @@ -840,9 +842,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; } @@ -1078,7 +1082,6 @@ Scsi_Cmnd * scsi_allocate_device (struct request ** reqp, Scsi_Device * device, kdev_t dev; struct request * req = NULL; int tablesize; - unsigned long flags; struct buffer_head * bh, *bhp; struct Scsi_Host * host; Scsi_Cmnd * SCpnt = NULL; @@ -1137,21 +1140,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," @@ -1201,7 +1201,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))); @@ -1282,7 +1281,6 @@ inline int internal_cmnd (Scsi_Cmnd * SCpnt) #ifdef DEBUG_DELAY unsigned long clock; #endif - unsigned long flags; struct Scsi_Host * host; int rtn = 0; unsigned long timeout; @@ -1298,7 +1296,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; @@ -1308,7 +1305,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; @@ -1321,11 +1317,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 ) { @@ -1352,18 +1348,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 @@ -1381,9 +1365,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 { @@ -1394,7 +1375,9 @@ inline int internal_cmnd (Scsi_Cmnd * SCpnt) SCpnt->result = temp; #ifdef DEBUG_DELAY clock = jiffies + 4 * HZ; + spin_unlock_irq(&io_request_lock); while (jiffies < clock) barrier(); + spin_lock_irq(&io_request_lock); printk("done(host = %d, result = %04x) : routine at %p\n", host->host_no, temp, host->hostt->command); #endif @@ -1422,7 +1405,6 @@ void scsi_do_cmd (Scsi_Cmnd * SCpnt, const void *cmnd , void *buffer, unsigned bufflen, void (*done)(Scsi_Cmnd *), int timeout, int retries) { - unsigned long flags; struct Scsi_Host * host = SCpnt->host; Scsi_Device * device = SCpnt->device; @@ -1456,20 +1438,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 @@ -1818,12 +1798,10 @@ static void scsi_unregister_host(Scsi_Host_Template *); void *scsi_malloc(unsigned int len) { unsigned int nbits, mask; - unsigned long flags; int i, j; if(len % SECTOR_SIZE != 0 || len > PAGE_SIZE) return NULL; - spin_lock_irqsave(&io_request_lock, flags); nbits = len >> 9; mask = (1 << nbits) - 1; @@ -1831,7 +1809,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))); @@ -1840,14 +1817,12 @@ 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 */ } int scsi_free(void *obj, unsigned int len) { unsigned int page, sector, nbits, mask; - unsigned long flags; #ifdef DEBUG unsigned long ret = 0; @@ -1874,20 +1849,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; } } @@ -2430,7 +2401,6 @@ static void resize_dma_pool(void) struct Scsi_Host * shpnt; struct Scsi_Host * host = NULL; Scsi_Device * SDpnt; - unsigned long flags; FreeSectorBitmap * new_dma_malloc_freelist = NULL; unsigned int new_dma_sectors = 0; unsigned int new_need_isa_buffer = 0; @@ -2551,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); @@ -2571,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); @@ -2741,7 +2709,6 @@ static int scsi_register_host(Scsi_Host_Template * tpnt) */ static void scsi_unregister_host(Scsi_Host_Template * tpnt) { - unsigned long flags; int online_status; int pcount; Scsi_Cmnd * SCpnt; @@ -2810,10 +2777,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; @@ -2834,7 +2799,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); } } } |