Commit 20081964 authored by David Jeffery's avatar David Jeffery Committed by James Simmons

[PATCH] ips driver 4/6

This is by far the biggest patch.  It is a rewrite of the
driver's horrid locking.  In addition to the host_lock,
the driver used to have 4 other locks per adapter!
It had a redundant ha_lock and a lock for each of 3
queues.  In a few places it also played with atomic bit
setting. And almost all of it was useless as the
host_lock was already held.

This patch cleans up this locking nightmare.  The driver
now uses the host_lock exclusively.  Only a few places
needed to add calls to lock the host_lock.  Most of
this patch is deletion of useless extra locking.
parent d3c20327
...@@ -240,18 +240,16 @@ struct proc_dir_entry proc_scsi_ips = { ...@@ -240,18 +240,16 @@ struct proc_dir_entry proc_scsi_ips = {
#if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0) #if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0)
#define IPS_SG_ADDRESS(sg) ((sg)->address) #define IPS_SG_ADDRESS(sg) ((sg)->address)
#define IPS_LOCK_IRQ(lock) spin_lock_irq(&io_request_lock)
#define IPS_UNLOCK_IRQ(lock) spin_unlock_irq(&io_request_lock)
#define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
#define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags) #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags)
#ifndef __devexit_p
#define __devexit_p(x) x
#endif
#else #else
#define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \ #define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \
page_address((sg)->page)+(sg)->offset : 0) page_address((sg)->page)+(sg)->offset : 0)
#define IPS_LOCK_IRQ(lock) spin_lock_irq(lock) #define IPS_LOCK_SAVE(lock,flags) spin_lock(lock)
#define IPS_UNLOCK_IRQ(lock) spin_unlock_irq(lock) #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock(lock)
#define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(lock,flags)
#define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(lock,flags)
#endif #endif
#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \ #define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
...@@ -961,14 +959,6 @@ ips_detect(Scsi_Host_Template *SHT) { ...@@ -961,14 +959,6 @@ ips_detect(Scsi_Host_Template *SHT) {
ha = IPS_HA(sh); ha = IPS_HA(sh);
memset(ha, 0, sizeof(ips_ha_t)); memset(ha, 0, sizeof(ips_ha_t));
/* Initialize spin lock */
spin_lock_init(&ha->scb_lock);
spin_lock_init(&ha->copp_lock);
spin_lock_init(&ha->ips_lock);
spin_lock_init(&ha->copp_waitlist.lock);
spin_lock_init(&ha->scb_waitlist.lock);
spin_lock_init(&ha->scb_activelist.lock);
ips_sh[ips_next_controller] = sh; ips_sh[ips_next_controller] = sh;
ips_ha[ips_next_controller] = ha; ips_ha[ips_next_controller] = ha;
ips_num_controllers++; ips_num_controllers++;
...@@ -1415,12 +1405,13 @@ ips_halt(struct notifier_block *nb, ulong event, void *buf) { ...@@ -1415,12 +1405,13 @@ ips_halt(struct notifier_block *nb, ulong event, void *buf) {
/* Routine Description: */ /* Routine Description: */
/* */ /* */
/* Abort a command (using the new error code stuff) */ /* Abort a command (using the new error code stuff) */
/* */ /* Note: this routine is called under the io_request_lock */
/****************************************************************************/ /****************************************************************************/
int int
ips_eh_abort(Scsi_Cmnd *SC) { ips_eh_abort(Scsi_Cmnd *SC) {
ips_ha_t *ha; ips_ha_t *ha;
ips_copp_wait_item_t *item; ips_copp_wait_item_t *item;
int ret;
METHOD_TRACE("ips_eh_abort", 1); METHOD_TRACE("ips_eh_abort", 1);
...@@ -1442,36 +1433,25 @@ ips_eh_abort(Scsi_Cmnd *SC) { ...@@ -1442,36 +1433,25 @@ ips_eh_abort(Scsi_Cmnd *SC) {
return (FAILED); return (FAILED);
} }
if (test_and_set_bit(IPS_IN_ABORT, &ha->flags))
return (FAILED);
/* See if the command is on the copp queue */ /* See if the command is on the copp queue */
IPS_QUEUE_LOCK(&ha->copp_waitlist);
item = ha->copp_waitlist.head; item = ha->copp_waitlist.head;
while ((item) && (item->scsi_cmd != SC)) while ((item) && (item->scsi_cmd != SC))
item = item->next; item = item->next;
IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
if (item) { if (item) {
/* Found it */ /* Found it */
ips_removeq_copp(&ha->copp_waitlist, item); ips_removeq_copp(&ha->copp_waitlist, item);
clear_bit(IPS_IN_ABORT, &ha->flags); ret = (SUCCESS);
return (SUCCESS);
}
/* See if the command is on the wait queue */ /* See if the command is on the wait queue */
if (ips_removeq_wait(&ha->scb_waitlist, SC)) { } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
/* command not sent yet */ /* command not sent yet */
clear_bit(IPS_IN_ABORT, &ha->flags); ret = (SUCCESS);
return (SUCCESS);
} else { } else {
/* command must have already been sent */ /* command must have already been sent */
clear_bit(IPS_IN_ABORT, &ha->flags); ret = (FAILED);
return (FAILED);
} }
return ret;
} }
/****************************************************************************/ /****************************************************************************/
...@@ -1492,7 +1472,6 @@ ips_eh_reset(Scsi_Cmnd *SC) { ...@@ -1492,7 +1472,6 @@ ips_eh_reset(Scsi_Cmnd *SC) {
ips_ha_t *ha; ips_ha_t *ha;
ips_scb_t *scb; ips_scb_t *scb;
ips_copp_wait_item_t *item; ips_copp_wait_item_t *item;
unsigned long cpu_flags;
METHOD_TRACE("ips_eh_reset", 1); METHOD_TRACE("ips_eh_reset", 1);
...@@ -1517,36 +1496,27 @@ ips_eh_reset(Scsi_Cmnd *SC) { ...@@ -1517,36 +1496,27 @@ ips_eh_reset(Scsi_Cmnd *SC) {
if (!ha->active) if (!ha->active)
return (FAILED); return (FAILED);
if (test_and_set_bit(IPS_IN_RESET, &ha->flags))
return (FAILED);
/* See if the command is on the copp queue */ /* See if the command is on the copp queue */
IPS_QUEUE_LOCK(&ha->copp_waitlist);
item = ha->copp_waitlist.head; item = ha->copp_waitlist.head;
while ((item) && (item->scsi_cmd != SC)) while ((item) && (item->scsi_cmd != SC))
item = item->next; item = item->next;
IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
if (item) { if (item) {
/* Found it */ /* Found it */
ips_removeq_copp(&ha->copp_waitlist, item); ips_removeq_copp(&ha->copp_waitlist, item);
clear_bit(IPS_IN_RESET, &ha->flags);
return (SUCCESS); return (SUCCESS);
} }
/* See if the command is on the wait queue */ /* See if the command is on the wait queue */
if (ips_removeq_wait(&ha->scb_waitlist, SC)) { if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
/* command not sent yet */ /* command not sent yet */
clear_bit(IPS_IN_RESET, &ha->flags);
return (SUCCESS); return (SUCCESS);
} }
/* An explanation for the casual observer: */ /* An explanation for the casual observer: */
/* Part of the function of a RAID controller is automatic error */ /* Part of the function of a RAID controller is automatic error */
/* detection and recovery. As such, the only problem that physically */ /* detection and recovery. As such, the only problem that physically */
/* resetting a ServeRAID adapter will ever fix is when, for some reason,*/ /* resetting an adapter will ever fix is when, for some reason, */
/* the driver is not successfully communicating with the adapter. */ /* the driver is not successfully communicating with the adapter. */
/* Therefore, we will attempt to flush this adapter. If that succeeds, */ /* Therefore, we will attempt to flush this adapter. If that succeeds, */
/* then there's no real purpose in a physical reset. This will complete */ /* then there's no real purpose in a physical reset. This will complete */
...@@ -1573,13 +1543,12 @@ ips_eh_reset(Scsi_Cmnd *SC) { ...@@ -1573,13 +1543,12 @@ ips_eh_reset(Scsi_Cmnd *SC) {
ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL); ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
if (ret == IPS_SUCCESS) { if (ret == IPS_SUCCESS) {
printk(KERN_NOTICE "(%s%d) Reset Request - Flushed Cache\n", ips_name, ha->host_num); printk(KERN_NOTICE "(%s%d) Reset Request - Flushed Cache\n", ips_name, ha->host_num);
clear_bit(IPS_IN_RESET, &ha->flags);
return (SUCCESS); return (SUCCESS);
} }
} }
/* Either we can't communicate with the adapter or it's an IOCTL request */ /* Either we can't communicate with the adapter or it's an IOCTL request */
/* from a ServeRAID utility. A physical reset is needed at this point. */ /* from a utility. A physical reset is needed at this point. */
ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */ ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */
...@@ -1618,8 +1587,6 @@ ips_eh_reset(Scsi_Cmnd *SC) { ...@@ -1618,8 +1587,6 @@ ips_eh_reset(Scsi_Cmnd *SC) {
} }
ha->active = FALSE; ha->active = FALSE;
clear_bit(IPS_IN_RESET, &ha->flags);
return (FAILED); return (FAILED);
} }
...@@ -1650,8 +1617,6 @@ ips_eh_reset(Scsi_Cmnd *SC) { ...@@ -1650,8 +1617,6 @@ ips_eh_reset(Scsi_Cmnd *SC) {
} }
ha->active = FALSE; ha->active = FALSE;
clear_bit(IPS_IN_RESET, &ha->flags);
return (FAILED); return (FAILED);
} }
...@@ -1660,10 +1625,8 @@ ips_eh_reset(Scsi_Cmnd *SC) { ...@@ -1660,10 +1625,8 @@ ips_eh_reset(Scsi_Cmnd *SC) {
struct timeval tv; struct timeval tv;
do_gettimeofday(&tv); do_gettimeofday(&tv);
IPS_HA_LOCK(cpu_flags);
ha->last_ffdc = tv.tv_sec; ha->last_ffdc = tv.tv_sec;
ha->reset_count++; ha->reset_count++;
IPS_HA_UNLOCK(cpu_flags);
ips_ffdc_reset(ha, IPS_INTR_IORL); ips_ffdc_reset(ha, IPS_INTR_IORL);
} }
...@@ -1682,25 +1645,11 @@ ips_eh_reset(Scsi_Cmnd *SC) { ...@@ -1682,25 +1645,11 @@ ips_eh_reset(Scsi_Cmnd *SC) {
ha->dcdb_active[i-1] = 0; ha->dcdb_active[i-1] = 0;
/* Reset the number of active IOCTLs */ /* Reset the number of active IOCTLs */
IPS_HA_LOCK(cpu_flags);
ha->num_ioctl = 0; ha->num_ioctl = 0;
IPS_HA_UNLOCK(cpu_flags);
clear_bit(IPS_IN_RESET, &ha->flags);
if (!test_bit(IPS_IN_INTR, &ha->flags)) {
/*
* Only execute the next command when
* we are not being called from the
* interrupt handler. The interrupt
* handler wants to do this and since
* interrupts are turned off here....
*/
ips_next(ha, IPS_INTR_IORL); ips_next(ha, IPS_INTR_IORL);
}
return (SUCCESS); return (SUCCESS);
#endif /* NO_IPS_RESET */ #endif /* NO_IPS_RESET */
} }
...@@ -1720,7 +1669,6 @@ ips_eh_reset(Scsi_Cmnd *SC) { ...@@ -1720,7 +1669,6 @@ ips_eh_reset(Scsi_Cmnd *SC) {
int int
ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
ips_ha_t *ha; ips_ha_t *ha;
unsigned long cpu_flags;
ips_passthru_t *pt; ips_passthru_t *pt;
METHOD_TRACE("ips_queue", 1); METHOD_TRACE("ips_queue", 1);
...@@ -1734,28 +1682,17 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { ...@@ -1734,28 +1682,17 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
return (DID_ERROR); return (DID_ERROR);
if (ips_is_passthru(SC)) { if (ips_is_passthru(SC)) {
IPS_QUEUE_LOCK(&ha->copp_waitlist);
if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) { if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
SC->result = DID_BUS_BUSY << 16; SC->result = DID_BUS_BUSY << 16;
done(SC); done(SC);
return (0); return (0);
} else {
IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
} }
} else { } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
IPS_QUEUE_LOCK(&ha->scb_waitlist);
if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
SC->result = DID_BUS_BUSY << 16; SC->result = DID_BUS_BUSY << 16;
done(SC); done(SC);
return (0); return (0);
} else {
IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
}
} }
SC->scsi_done = done; SC->scsi_done = done;
...@@ -1809,27 +1746,15 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) { ...@@ -1809,27 +1746,15 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
} }
scratch->scsi_cmd = SC; scratch->scsi_cmd = SC;
sema_init(&ha->ioctl_sem, 0);
scratch->sem = &ha->ioctl_sem;
scratch->next = NULL; scratch->next = NULL;
ips_putq_copp_tail(&ha->copp_waitlist, scratch); ips_putq_copp_tail(&ha->copp_waitlist, scratch);
} }
else else {
ips_putq_wait_tail(&ha->scb_waitlist, SC); ips_putq_wait_tail(&ha->scb_waitlist, SC);
}
if(ha->scb_waitlist.count + ha->scb_activelist.count > 32)
mod_timer(&SC->eh_timeout, jiffies + 120 * HZ);
IPS_HA_LOCK(cpu_flags);
if ((!test_bit(IPS_IN_INTR, &ha->flags)) &&
(!test_bit(IPS_IN_ABORT, &ha->flags)) &&
(!test_bit(IPS_IN_RESET, &ha->flags))) {
IPS_HA_UNLOCK(cpu_flags);
ips_next(ha, IPS_INTR_IORL); ips_next(ha, IPS_INTR_IORL);
} else {
IPS_HA_UNLOCK(cpu_flags);
}
/* If We were using the CD Boot Flash Buffer, Restore the Old Values */ /* If We were using the CD Boot Flash Buffer, Restore the Old Values */
if ( ips_FlashData == ha->ioctl_data ) { if ( ips_FlashData == ha->ioctl_data ) {
...@@ -1959,20 +1884,13 @@ do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) { ...@@ -1959,20 +1884,13 @@ do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) {
host = ips_sh[ha->host_num]; host = ips_sh[ha->host_num];
IPS_LOCK_SAVE(host->host_lock, cpu_flags); IPS_LOCK_SAVE(host->host_lock, cpu_flags);
if (test_and_set_bit(IPS_IN_INTR, &ha->flags)) {
IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
return ;
}
if (!ha->active) { if (!ha->active) {
clear_bit(IPS_IN_INTR, &ha->flags);
IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
return; return;
} }
(*ha->func.intr)(ha); (*ha->func.intr)(ha);
clear_bit(IPS_IN_INTR, &ha->flags);
IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
/* start the next command */ /* start the next command */
...@@ -1996,7 +1914,6 @@ ips_intr_copperhead(ips_ha_t *ha) { ...@@ -1996,7 +1914,6 @@ ips_intr_copperhead(ips_ha_t *ha) {
ips_scb_t *scb; ips_scb_t *scb;
IPS_STATUS cstatus; IPS_STATUS cstatus;
int intrstatus; int intrstatus;
unsigned long cpu_flags;
METHOD_TRACE("ips_intr", 2); METHOD_TRACE("ips_intr", 2);
...@@ -2006,15 +1923,12 @@ ips_intr_copperhead(ips_ha_t *ha) { ...@@ -2006,15 +1923,12 @@ ips_intr_copperhead(ips_ha_t *ha) {
if (!ha->active) if (!ha->active)
return; return;
IPS_HA_LOCK(cpu_flags);
intrstatus = (*ha->func.isintr)(ha); intrstatus = (*ha->func.isintr)(ha);
if (!intrstatus) { if (!intrstatus) {
/* /*
* Unexpected/Shared interrupt * Unexpected/Shared interrupt
*/ */
IPS_HA_UNLOCK(cpu_flags);
return; return;
} }
...@@ -2041,12 +1955,8 @@ ips_intr_copperhead(ips_ha_t *ha) { ...@@ -2041,12 +1955,8 @@ ips_intr_copperhead(ips_ha_t *ha) {
* use the callback function to finish things up * use the callback function to finish things up
* NOTE: interrupts are OFF for this * NOTE: interrupts are OFF for this
*/ */
IPS_HA_UNLOCK(cpu_flags);
(*scb->callback) (ha, scb); (*scb->callback) (ha, scb);
IPS_HA_LOCK(cpu_flags);
} /* end while */ } /* end while */
IPS_HA_UNLOCK(cpu_flags);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -2066,7 +1976,6 @@ ips_intr_morpheus(ips_ha_t *ha) { ...@@ -2066,7 +1976,6 @@ ips_intr_morpheus(ips_ha_t *ha) {
ips_scb_t *scb; ips_scb_t *scb;
IPS_STATUS cstatus; IPS_STATUS cstatus;
int intrstatus; int intrstatus;
unsigned long cpu_flags;
METHOD_TRACE("ips_intr_morpheus", 2); METHOD_TRACE("ips_intr_morpheus", 2);
...@@ -2076,15 +1985,12 @@ ips_intr_morpheus(ips_ha_t *ha) { ...@@ -2076,15 +1985,12 @@ ips_intr_morpheus(ips_ha_t *ha) {
if (!ha->active) if (!ha->active)
return; return;
IPS_HA_LOCK(cpu_flags);
intrstatus = (*ha->func.isintr)(ha); intrstatus = (*ha->func.isintr)(ha);
if (!intrstatus) { if (!intrstatus) {
/* /*
* Unexpected/Shared interrupt * Unexpected/Shared interrupt
*/ */
IPS_HA_UNLOCK(cpu_flags);
return; return;
} }
...@@ -2117,12 +2023,8 @@ ips_intr_morpheus(ips_ha_t *ha) { ...@@ -2117,12 +2023,8 @@ ips_intr_morpheus(ips_ha_t *ha) {
* use the callback function to finish things up * use the callback function to finish things up
* NOTE: interrupts are OFF for this * NOTE: interrupts are OFF for this
*/ */
IPS_HA_UNLOCK(cpu_flags);
(*scb->callback) (ha, scb); (*scb->callback) (ha, scb);
IPS_HA_LOCK(cpu_flags);
} /* end while */ } /* end while */
IPS_HA_UNLOCK(cpu_flags);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -3234,8 +3136,7 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3234,8 +3136,7 @@ ips_next(ips_ha_t *ha, int intr) {
Scsi_Cmnd *q; Scsi_Cmnd *q;
ips_copp_wait_item_t *item; ips_copp_wait_item_t *item;
int ret; int ret;
unsigned long cpu_flags; unsigned long cpu_flags = 0;
unsigned long cpu_flags2 = 0;
struct Scsi_Host *host; struct Scsi_Host *host;
METHOD_TRACE("ips_next", 1); METHOD_TRACE("ips_next", 1);
...@@ -3246,27 +3147,20 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3246,27 +3147,20 @@ ips_next(ips_ha_t *ha, int intr) {
* Block access to the queue function so * Block access to the queue function so
* this command won't time out * this command won't time out
*/ */
if (intr == IPS_INTR_ON) if(intr == IPS_INTR_ON)
IPS_LOCK_SAVE(host->host_lock, cpu_flags2); IPS_LOCK_SAVE(host->host_lock, cpu_flags);
if ((ha->subsys->param[3] & 0x300000) && ( ha->scb_activelist.count == 0 )) { if ((ha->subsys->param[3] & 0x300000) && ( ha->scb_activelist.count == 0 )) {
struct timeval tv; struct timeval tv;
do_gettimeofday(&tv); do_gettimeofday(&tv);
IPS_HA_LOCK(cpu_flags);
if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) { if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
ha->last_ffdc = tv.tv_sec; ha->last_ffdc = tv.tv_sec;
IPS_HA_UNLOCK(cpu_flags);
ips_ffdc_time(ha); ips_ffdc_time(ha);
} else {
IPS_HA_UNLOCK(cpu_flags);
} }
} }
if (intr == IPS_INTR_ON)
IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags2);
/* /*
* Send passthru commands * Send passthru commands
* These have priority over normal I/O * These have priority over normal I/O
...@@ -3274,22 +3168,21 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3274,22 +3168,21 @@ ips_next(ips_ha_t *ha, int intr) {
* since we limit the number that can be active * since we limit the number that can be active
* on the card at any one time * on the card at any one time
*/ */
IPS_HA_LOCK(cpu_flags);
IPS_QUEUE_LOCK(&ha->copp_waitlist);
while ((ha->num_ioctl < IPS_MAX_IOCTL) && while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
(ha->copp_waitlist.head) && (ha->copp_waitlist.head) &&
(scb = ips_getscb(ha))) { (scb = ips_getscb(ha))) {
IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
item = ips_removeq_copp_head(&ha->copp_waitlist); item = ips_removeq_copp_head(&ha->copp_waitlist);
ha->num_ioctl++; ha->num_ioctl++;
IPS_HA_UNLOCK(cpu_flags); if(intr == IPS_INTR_ON)
IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
scb->scsi_cmd = item->scsi_cmd; scb->scsi_cmd = item->scsi_cmd;
scb->sem = item->sem;
kfree(item); kfree(item);
ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr); ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
if(intr == IPS_INTR_ON)
IPS_LOCK_SAVE(host->host_lock, cpu_flags);
switch (ret) { switch (ret) {
case IPS_FAILURE: case IPS_FAILURE:
if (scb->scsi_cmd) { if (scb->scsi_cmd) {
...@@ -3312,8 +3205,6 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3312,8 +3205,6 @@ ips_next(ips_ha_t *ha, int intr) {
} /* end case */ } /* end case */
if (ret != IPS_SUCCESS) { if (ret != IPS_SUCCESS) {
IPS_HA_LOCK(cpu_flags);
IPS_QUEUE_LOCK(&ha->copp_waitlist);
ha->num_ioctl--; ha->num_ioctl--;
continue; continue;
} }
...@@ -3340,20 +3231,14 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3340,20 +3231,14 @@ ips_next(ips_ha_t *ha, int intr) {
break; break;
} /* end case */ } /* end case */
IPS_HA_LOCK(cpu_flags);
IPS_QUEUE_LOCK(&ha->copp_waitlist);
} }
IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
IPS_HA_UNLOCK(cpu_flags);
/* /*
* Send "Normal" I/O commands * Send "Normal" I/O commands
*/ */
IPS_HA_LOCK(cpu_flags);
IPS_QUEUE_LOCK(&ha->scb_waitlist);
p = ha->scb_waitlist.head; p = ha->scb_waitlist.head;
IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
while ((p) && (scb = ips_getscb(ha))) { while ((p) && (scb = ips_getscb(ha))) {
if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) { if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) {
ips_freescb(ha, scb); ips_freescb(ha, scb);
...@@ -3363,10 +3248,9 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3363,10 +3248,9 @@ ips_next(ips_ha_t *ha, int intr) {
q = p; q = p;
SC = ips_removeq_wait(&ha->scb_waitlist, q); SC = ips_removeq_wait(&ha->scb_waitlist, q);
if (SC == NULL) /* Should never happen, but good to check anyway */
continue;
IPS_HA_UNLOCK(cpu_flags); /* Unlock HA after command is taken off queue */ if(intr == IPS_INTR_ON)
IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */
SC->result = DID_OK; SC->result = DID_OK;
SC->host_scribble = NULL; SC->host_scribble = NULL;
...@@ -3474,13 +3358,15 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3474,13 +3358,15 @@ ips_next(ips_ha_t *ha, int intr) {
scb->dcdb.cmd_attribute |= IPS_TRANSFER64K; scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
scb->dcdb.transfer_length = 0; scb->dcdb.transfer_length = 0;
} }
if(intr == IPS_INTR_ON)
IPS_LOCK_SAVE(host->host_lock, cpu_flags);
ret = ips_send_cmd(ha, scb); ret = ips_send_cmd(ha, scb);
if (ret == IPS_SUCCESS)
ips_putq_scb_head(&ha->scb_activelist, scb);
switch(ret) { switch(ret) {
case IPS_SUCCESS:
ips_putq_scb_head(&ha->scb_activelist, scb);
break;
case IPS_FAILURE: case IPS_FAILURE:
if (scb->scsi_cmd) { if (scb->scsi_cmd) {
scb->scsi_cmd->result = DID_ERROR << 16; scb->scsi_cmd->result = DID_ERROR << 16;
...@@ -3507,10 +3393,10 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3507,10 +3393,10 @@ ips_next(ips_ha_t *ha, int intr) {
p = (Scsi_Cmnd *) p->host_scribble; p = (Scsi_Cmnd *) p->host_scribble;
IPS_HA_LOCK(cpu_flags);
} /* end while */ } /* end while */
IPS_HA_UNLOCK(cpu_flags); if(intr == IPS_INTR_ON)
IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -3521,7 +3407,7 @@ ips_next(ips_ha_t *ha, int intr) { ...@@ -3521,7 +3407,7 @@ ips_next(ips_ha_t *ha, int intr) {
/* */ /* */
/* Add an item to the head of the queue */ /* Add an item to the head of the queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline void static inline void
...@@ -3531,8 +3417,6 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) { ...@@ -3531,8 +3417,6 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
if (!item) if (!item)
return ; return ;
IPS_QUEUE_LOCK(queue);
item->q_next = queue->head; item->q_next = queue->head;
queue->head = item; queue->head = item;
...@@ -3540,8 +3424,6 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) { ...@@ -3540,8 +3424,6 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
queue->tail = item; queue->tail = item;
queue->count++; queue->count++;
IPS_QUEUE_UNLOCK(queue);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -3552,7 +3434,7 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) { ...@@ -3552,7 +3434,7 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
/* */ /* */
/* Add an item to the tail of the queue */ /* Add an item to the tail of the queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline void static inline void
...@@ -3562,8 +3444,6 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) { ...@@ -3562,8 +3444,6 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
if (!item) if (!item)
return ; return ;
IPS_QUEUE_LOCK(queue);
item->q_next = NULL; item->q_next = NULL;
if (queue->tail) if (queue->tail)
...@@ -3575,8 +3455,6 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) { ...@@ -3575,8 +3455,6 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
queue->head = item; queue->head = item;
queue->count++; queue->count++;
IPS_QUEUE_UNLOCK(queue);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -3587,7 +3465,7 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) { ...@@ -3587,7 +3465,7 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
/* */ /* */
/* Remove the head of the queue */ /* Remove the head of the queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline ips_scb_t * static inline ips_scb_t *
...@@ -3596,13 +3474,9 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) { ...@@ -3596,13 +3474,9 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) {
METHOD_TRACE("ips_removeq_scb_head", 1); METHOD_TRACE("ips_removeq_scb_head", 1);
IPS_QUEUE_LOCK(queue);
item = queue->head; item = queue->head;
if (!item) { if (!item) {
IPS_QUEUE_UNLOCK(queue);
return (NULL); return (NULL);
} }
...@@ -3614,8 +3488,6 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) { ...@@ -3614,8 +3488,6 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) {
queue->count--; queue->count--;
IPS_QUEUE_UNLOCK(queue);
return (item); return (item);
} }
...@@ -3627,7 +3499,7 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) { ...@@ -3627,7 +3499,7 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) {
/* */ /* */
/* Remove an item from a queue */ /* Remove an item from a queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline ips_scb_t * static inline ips_scb_t *
...@@ -3639,11 +3511,7 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) { ...@@ -3639,11 +3511,7 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
if (!item) if (!item)
return (NULL); return (NULL);
IPS_QUEUE_LOCK(queue);
if (item == queue->head) { if (item == queue->head) {
IPS_QUEUE_UNLOCK(queue);
return (ips_removeq_scb_head(queue)); return (ips_removeq_scb_head(queue));
} }
...@@ -3662,13 +3530,9 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) { ...@@ -3662,13 +3530,9 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
item->q_next = NULL; item->q_next = NULL;
queue->count--; queue->count--;
IPS_QUEUE_UNLOCK(queue);
return (item); return (item);
} }
IPS_QUEUE_UNLOCK(queue);
return (NULL); return (NULL);
} }
...@@ -3680,7 +3544,7 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) { ...@@ -3680,7 +3544,7 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
/* */ /* */
/* Add an item to the head of the queue */ /* Add an item to the head of the queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline void static inline void
...@@ -3690,8 +3554,6 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) { ...@@ -3690,8 +3554,6 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
if (!item) if (!item)
return ; return ;
IPS_QUEUE_LOCK(queue);
item->host_scribble = (char *) queue->head; item->host_scribble = (char *) queue->head;
queue->head = item; queue->head = item;
...@@ -3699,8 +3561,6 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) { ...@@ -3699,8 +3561,6 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
queue->tail = item; queue->tail = item;
queue->count++; queue->count++;
IPS_QUEUE_UNLOCK(queue);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -3711,7 +3571,7 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) { ...@@ -3711,7 +3571,7 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
/* */ /* */
/* Add an item to the tail of the queue */ /* Add an item to the tail of the queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline void static inline void
...@@ -3721,8 +3581,6 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) { ...@@ -3721,8 +3581,6 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
if (!item) if (!item)
return ; return ;
IPS_QUEUE_LOCK(queue);
item->host_scribble = NULL; item->host_scribble = NULL;
if (queue->tail) if (queue->tail)
...@@ -3734,8 +3592,6 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) { ...@@ -3734,8 +3592,6 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
queue->head = item; queue->head = item;
queue->count++; queue->count++;
IPS_QUEUE_UNLOCK(queue);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -3746,7 +3602,7 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) { ...@@ -3746,7 +3602,7 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
/* */ /* */
/* Remove the head of the queue */ /* Remove the head of the queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline Scsi_Cmnd * static inline Scsi_Cmnd *
...@@ -3755,13 +3611,9 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) { ...@@ -3755,13 +3611,9 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) {
METHOD_TRACE("ips_removeq_wait_head", 1); METHOD_TRACE("ips_removeq_wait_head", 1);
IPS_QUEUE_LOCK(queue);
item = queue->head; item = queue->head;
if (!item) { if (!item) {
IPS_QUEUE_UNLOCK(queue);
return (NULL); return (NULL);
} }
...@@ -3773,8 +3625,6 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) { ...@@ -3773,8 +3625,6 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) {
queue->count--; queue->count--;
IPS_QUEUE_UNLOCK(queue);
return (item); return (item);
} }
...@@ -3786,7 +3636,7 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) { ...@@ -3786,7 +3636,7 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) {
/* */ /* */
/* Remove an item from a queue */ /* Remove an item from a queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline Scsi_Cmnd * static inline Scsi_Cmnd *
...@@ -3798,11 +3648,7 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) { ...@@ -3798,11 +3648,7 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
if (!item) if (!item)
return (NULL); return (NULL);
IPS_QUEUE_LOCK(queue);
if (item == queue->head) { if (item == queue->head) {
IPS_QUEUE_UNLOCK(queue);
return (ips_removeq_wait_head(queue)); return (ips_removeq_wait_head(queue));
} }
...@@ -3821,13 +3667,9 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) { ...@@ -3821,13 +3667,9 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
item->host_scribble = NULL; item->host_scribble = NULL;
queue->count--; queue->count--;
IPS_QUEUE_UNLOCK(queue);
return (item); return (item);
} }
IPS_QUEUE_UNLOCK(queue);
return (NULL); return (NULL);
} }
...@@ -3839,7 +3681,7 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) { ...@@ -3839,7 +3681,7 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
/* */ /* */
/* Add an item to the head of the queue */ /* Add an item to the head of the queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline void static inline void
...@@ -3849,8 +3691,6 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { ...@@ -3849,8 +3691,6 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
if (!item) if (!item)
return ; return ;
IPS_QUEUE_LOCK(queue);
item->next = queue->head; item->next = queue->head;
queue->head = item; queue->head = item;
...@@ -3858,8 +3698,6 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { ...@@ -3858,8 +3698,6 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
queue->tail = item; queue->tail = item;
queue->count++; queue->count++;
IPS_QUEUE_UNLOCK(queue);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -3870,7 +3708,7 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { ...@@ -3870,7 +3708,7 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
/* */ /* */
/* Add an item to the tail of the queue */ /* Add an item to the tail of the queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline void static inline void
...@@ -3880,8 +3718,6 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { ...@@ -3880,8 +3718,6 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
if (!item) if (!item)
return ; return ;
IPS_QUEUE_LOCK(queue);
item->next = NULL; item->next = NULL;
if (queue->tail) if (queue->tail)
...@@ -3893,8 +3729,6 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { ...@@ -3893,8 +3729,6 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
queue->head = item; queue->head = item;
queue->count++; queue->count++;
IPS_QUEUE_UNLOCK(queue);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -3905,7 +3739,7 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { ...@@ -3905,7 +3739,7 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
/* */ /* */
/* Remove the head of the queue */ /* Remove the head of the queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline ips_copp_wait_item_t * static inline ips_copp_wait_item_t *
...@@ -3914,13 +3748,9 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) { ...@@ -3914,13 +3748,9 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) {
METHOD_TRACE("ips_removeq_copp_head", 1); METHOD_TRACE("ips_removeq_copp_head", 1);
IPS_QUEUE_LOCK(queue);
item = queue->head; item = queue->head;
if (!item) { if (!item) {
IPS_QUEUE_UNLOCK(queue);
return (NULL); return (NULL);
} }
...@@ -3932,8 +3762,6 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) { ...@@ -3932,8 +3762,6 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) {
queue->count--; queue->count--;
IPS_QUEUE_UNLOCK(queue);
return (item); return (item);
} }
...@@ -3945,7 +3773,7 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) { ...@@ -3945,7 +3773,7 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) {
/* */ /* */
/* Remove an item from a queue */ /* Remove an item from a queue */
/* */ /* */
/* ASSUMED to be called from within a lock */ /* ASSUMED to be called from within the HA lock */
/* */ /* */
/****************************************************************************/ /****************************************************************************/
static inline ips_copp_wait_item_t * static inline ips_copp_wait_item_t *
...@@ -3957,11 +3785,7 @@ ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { ...@@ -3957,11 +3785,7 @@ ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
if (!item) if (!item)
return (NULL); return (NULL);
IPS_QUEUE_LOCK(queue);
if (item == queue->head) { if (item == queue->head) {
IPS_QUEUE_UNLOCK(queue);
return (ips_removeq_copp_head(queue)); return (ips_removeq_copp_head(queue));
} }
...@@ -3980,13 +3804,9 @@ ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) { ...@@ -3980,13 +3804,9 @@ ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
item->next = NULL; item->next = NULL;
queue->count--; queue->count--;
IPS_QUEUE_UNLOCK(queue);
return (item); return (item);
} }
IPS_QUEUE_UNLOCK(queue);
return (NULL); return (NULL);
} }
...@@ -4050,12 +3870,11 @@ ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -4050,12 +3870,11 @@ ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) {
/* Routine Description: */ /* Routine Description: */
/* */ /* */
/* Do housekeeping on completed commands */ /* Do housekeeping on completed commands */
/* */ /* ASSUMED to be called form within the request lock */
/****************************************************************************/ /****************************************************************************/
static void static void
ips_done(ips_ha_t *ha, ips_scb_t *scb) { ips_done(ips_ha_t *ha, ips_scb_t *scb) {
int ret; int ret;
unsigned long cpu_flags;
METHOD_TRACE("ips_done", 1); METHOD_TRACE("ips_done", 1);
...@@ -4064,9 +3883,7 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -4064,9 +3883,7 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) {
if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) { if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
ips_cleanup_passthru(ha, scb); ips_cleanup_passthru(ha, scb);
IPS_HA_LOCK(cpu_flags);
ha->num_ioctl--; ha->num_ioctl--;
IPS_HA_UNLOCK(cpu_flags);
} else { } else {
/* /*
* Check to see if this command had too much * Check to see if this command had too much
...@@ -4225,9 +4042,7 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -4225,9 +4042,7 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) {
} /* end if passthru */ } /* end if passthru */
if (scb->bus) { if (scb->bus) {
IPS_HA_LOCK(cpu_flags);
ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
IPS_HA_UNLOCK(cpu_flags);
} }
scb->scsi_cmd->scsi_done(scb->scsi_cmd); scb->scsi_cmd->scsi_done(scb->scsi_cmd);
...@@ -4710,7 +4525,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -4710,7 +4525,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
/* Routine Description: */ /* Routine Description: */
/* */ /* */
/* Check the status of commands to logical drives */ /* Check the status of commands to logical drives */
/* */ /* Assumed to be called with the HA lock */
/****************************************************************************/ /****************************************************************************/
static void static void
ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) { ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
...@@ -5239,13 +5054,10 @@ ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -5239,13 +5054,10 @@ ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
static ips_scb_t * static ips_scb_t *
ips_getscb(ips_ha_t *ha) { ips_getscb(ips_ha_t *ha) {
ips_scb_t *scb; ips_scb_t *scb;
unsigned long cpu_flags;
METHOD_TRACE("ips_getscb", 1); METHOD_TRACE("ips_getscb", 1);
IPS_SCB_LOCK(cpu_flags);
if ((scb = ha->scb_freelist) == NULL) { if ((scb = ha->scb_freelist) == NULL) {
IPS_SCB_UNLOCK(cpu_flags);
return (NULL); return (NULL);
} }
...@@ -5253,8 +5065,6 @@ ips_getscb(ips_ha_t *ha) { ...@@ -5253,8 +5065,6 @@ ips_getscb(ips_ha_t *ha) {
ha->scb_freelist = scb->q_next; ha->scb_freelist = scb->q_next;
scb->q_next = NULL; scb->q_next = NULL;
IPS_SCB_UNLOCK(cpu_flags);
ips_init_scb(ha, scb); ips_init_scb(ha, scb);
return (scb); return (scb);
...@@ -5273,7 +5083,6 @@ ips_getscb(ips_ha_t *ha) { ...@@ -5273,7 +5083,6 @@ ips_getscb(ips_ha_t *ha) {
/****************************************************************************/ /****************************************************************************/
static void static void
ips_freescb(ips_ha_t *ha, ips_scb_t *scb) { ips_freescb(ips_ha_t *ha, ips_scb_t *scb) {
unsigned long cpu_flags;
METHOD_TRACE("ips_freescb", 1); METHOD_TRACE("ips_freescb", 1);
if(scb->flags & IPS_SCB_MAP_SG) if(scb->flags & IPS_SCB_MAP_SG)
...@@ -5286,10 +5095,8 @@ ips_freescb(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -5286,10 +5095,8 @@ ips_freescb(ips_ha_t *ha, ips_scb_t *scb) {
/* check to make sure this is not our "special" scb */ /* check to make sure this is not our "special" scb */
if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) { if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
IPS_SCB_LOCK(cpu_flags);
scb->q_next = ha->scb_freelist; scb->q_next = ha->scb_freelist;
ha->scb_freelist = scb; ha->scb_freelist = scb;
IPS_SCB_UNLOCK(cpu_flags);
} }
} }
...@@ -5701,15 +5508,12 @@ ips_init_morpheus(ips_ha_t *ha) { ...@@ -5701,15 +5508,12 @@ ips_init_morpheus(ips_ha_t *ha) {
static int static int
ips_reset_copperhead(ips_ha_t *ha) { ips_reset_copperhead(ips_ha_t *ha) {
int reset_counter; int reset_counter;
unsigned long cpu_flags;
METHOD_TRACE("ips_reset_copperhead", 1); METHOD_TRACE("ips_reset_copperhead", 1);
DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d", DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
ips_name, ha->host_num, ha->io_addr, ha->irq); ips_name, ha->host_num, ha->io_addr, ha->irq);
IPS_HA_LOCK(cpu_flags);
reset_counter = 0; reset_counter = 0;
while (reset_counter < 2) { while (reset_counter < 2) {
...@@ -5728,14 +5532,11 @@ ips_reset_copperhead(ips_ha_t *ha) { ...@@ -5728,14 +5532,11 @@ ips_reset_copperhead(ips_ha_t *ha) {
if ((*ha->func.init)(ha)) if ((*ha->func.init)(ha))
break; break;
else if (reset_counter >= 2) { else if (reset_counter >= 2) {
IPS_HA_UNLOCK(cpu_flags);
return (0); return (0);
} }
} }
IPS_HA_UNLOCK(cpu_flags);
return (1); return (1);
} }
...@@ -5751,15 +5552,12 @@ ips_reset_copperhead(ips_ha_t *ha) { ...@@ -5751,15 +5552,12 @@ ips_reset_copperhead(ips_ha_t *ha) {
static int static int
ips_reset_copperhead_memio(ips_ha_t *ha) { ips_reset_copperhead_memio(ips_ha_t *ha) {
int reset_counter; int reset_counter;
unsigned long cpu_flags;
METHOD_TRACE("ips_reset_copperhead_memio", 1); METHOD_TRACE("ips_reset_copperhead_memio", 1);
DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d", DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
ips_name, ha->host_num, ha->mem_addr, ha->irq); ips_name, ha->host_num, ha->mem_addr, ha->irq);
IPS_HA_LOCK(cpu_flags);
reset_counter = 0; reset_counter = 0;
while (reset_counter < 2) { while (reset_counter < 2) {
...@@ -5778,14 +5576,11 @@ ips_reset_copperhead_memio(ips_ha_t *ha) { ...@@ -5778,14 +5576,11 @@ ips_reset_copperhead_memio(ips_ha_t *ha) {
if ((*ha->func.init)(ha)) if ((*ha->func.init)(ha))
break; break;
else if (reset_counter >= 2) { else if (reset_counter >= 2) {
IPS_HA_UNLOCK(cpu_flags);
return (0); return (0);
} }
} }
IPS_HA_UNLOCK(cpu_flags);
return (1); return (1);
} }
...@@ -5802,15 +5597,12 @@ static int ...@@ -5802,15 +5597,12 @@ static int
ips_reset_morpheus(ips_ha_t *ha) { ips_reset_morpheus(ips_ha_t *ha) {
int reset_counter; int reset_counter;
uint8_t junk; uint8_t junk;
unsigned long cpu_flags;
METHOD_TRACE("ips_reset_morpheus", 1); METHOD_TRACE("ips_reset_morpheus", 1);
DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d", DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
ips_name, ha->host_num, ha->mem_addr, ha->irq); ips_name, ha->host_num, ha->mem_addr, ha->irq);
IPS_HA_LOCK(cpu_flags);
reset_counter = 0; reset_counter = 0;
while (reset_counter < 2) { while (reset_counter < 2) {
...@@ -5827,14 +5619,11 @@ ips_reset_morpheus(ips_ha_t *ha) { ...@@ -5827,14 +5619,11 @@ ips_reset_morpheus(ips_ha_t *ha) {
if ((*ha->func.init)(ha)) if ((*ha->func.init)(ha))
break; break;
else if (reset_counter >= 2) { else if (reset_counter >= 2) {
IPS_HA_UNLOCK(cpu_flags);
return (0); return (0);
} }
} }
IPS_HA_UNLOCK(cpu_flags);
return (1); return (1);
} }
...@@ -5979,7 +5768,6 @@ static int ...@@ -5979,7 +5768,6 @@ static int
ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
uint32_t TimeOut; uint32_t TimeOut;
uint32_t val; uint32_t val;
unsigned long cpu_flags;
METHOD_TRACE("ips_issue_copperhead", 1); METHOD_TRACE("ips_issue_copperhead", 1);
...@@ -5999,8 +5787,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -5999,8 +5787,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
scb->cmd.basic_io.command_id); scb->cmd.basic_io.command_id);
} }
IPS_HA_LOCK(cpu_flags);
TimeOut = 0; TimeOut = 0;
while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) { while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
...@@ -6015,8 +5801,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -6015,8 +5801,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n", printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n",
ips_name, ha->host_num); ips_name, ha->host_num);
IPS_HA_UNLOCK(cpu_flags);
return (IPS_FAILURE); return (IPS_FAILURE);
} /* end if */ } /* end if */
} /* end while */ } /* end while */
...@@ -6024,8 +5808,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -6024,8 +5808,6 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR);
outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR);
IPS_HA_UNLOCK(cpu_flags);
return (IPS_SUCCESS); return (IPS_SUCCESS);
} }
...@@ -6042,7 +5824,6 @@ static int ...@@ -6042,7 +5824,6 @@ static int
ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
uint32_t TimeOut; uint32_t TimeOut;
uint32_t val; uint32_t val;
unsigned long cpu_flags;
METHOD_TRACE("ips_issue_copperhead_memio", 1); METHOD_TRACE("ips_issue_copperhead_memio", 1);
...@@ -6062,8 +5843,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -6062,8 +5843,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
scb->cmd.basic_io.command_id); scb->cmd.basic_io.command_id);
} }
IPS_HA_LOCK(cpu_flags);
TimeOut = 0; TimeOut = 0;
while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) { while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
...@@ -6078,8 +5857,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -6078,8 +5857,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n", printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n",
ips_name, ha->host_num); ips_name, ha->host_num);
IPS_HA_UNLOCK(cpu_flags);
return (IPS_FAILURE); return (IPS_FAILURE);
} /* end if */ } /* end if */
} /* end while */ } /* end while */
...@@ -6087,8 +5864,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -6087,8 +5864,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR); writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR); writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
IPS_HA_UNLOCK(cpu_flags);
return (IPS_SUCCESS); return (IPS_SUCCESS);
} }
...@@ -6103,7 +5878,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -6103,7 +5878,6 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
/****************************************************************************/ /****************************************************************************/
static int static int
ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) {
unsigned long cpu_flags;
METHOD_TRACE("ips_issue_i2o", 1); METHOD_TRACE("ips_issue_i2o", 1);
...@@ -6123,12 +5897,8 @@ ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -6123,12 +5897,8 @@ ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) {
scb->cmd.basic_io.command_id); scb->cmd.basic_io.command_id);
} }
IPS_HA_LOCK(cpu_flags);
outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ);
IPS_HA_UNLOCK(cpu_flags);
return (IPS_SUCCESS); return (IPS_SUCCESS);
} }
...@@ -6143,7 +5913,6 @@ ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -6143,7 +5913,6 @@ ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) {
/****************************************************************************/ /****************************************************************************/
static int static int
ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) { ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) {
unsigned long cpu_flags;
METHOD_TRACE("ips_issue_i2o_memio", 1); METHOD_TRACE("ips_issue_i2o_memio", 1);
...@@ -6163,12 +5932,8 @@ ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -6163,12 +5932,8 @@ ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) {
scb->cmd.basic_io.command_id); scb->cmd.basic_io.command_id);
} }
IPS_HA_LOCK(cpu_flags);
writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ); writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
IPS_HA_UNLOCK(cpu_flags);
return (IPS_SUCCESS); return (IPS_SUCCESS);
} }
...@@ -6305,12 +6070,7 @@ ips_wait(ips_ha_t *ha, int time, int intr) { ...@@ -6305,12 +6070,7 @@ ips_wait(ips_ha_t *ha, int time, int intr) {
* until after we finish. * until after we finish.
*/ */
while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
udelay(1000);
(*ha->func.intr)(ha); (*ha->func.intr)(ha);
clear_bit(IPS_IN_INTR, &ha->flags);
} }
/* This looks like a very evil loop, but it only does this during start-up */ /* This looks like a very evil loop, but it only does this during start-up */
...@@ -7575,14 +7335,6 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) ...@@ -7575,14 +7335,6 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
ha = IPS_HA(sh); ha = IPS_HA(sh);
memset(ha, 0, sizeof(ips_ha_t)); memset(ha, 0, sizeof(ips_ha_t));
/* Initialize spin lock */
spin_lock_init(&ha->scb_lock);
spin_lock_init(&ha->copp_lock);
spin_lock_init(&ha->ips_lock);
spin_lock_init(&ha->copp_waitlist.lock);
spin_lock_init(&ha->scb_waitlist.lock);
spin_lock_init(&ha->scb_activelist.lock);
ips_sh[index] = sh; ips_sh[index] = sh;
ips_ha[index] = ha; ips_ha[index] = ha;
ha->active = 1; ha->active = 1;
......
...@@ -91,16 +91,6 @@ ...@@ -91,16 +91,6 @@
#define MDELAY mdelay #define MDELAY mdelay
#endif #endif
/*
* Lock macros
*/
#define IPS_SCB_LOCK(cpu_flags) spin_lock_irqsave(&ha->scb_lock, cpu_flags)
#define IPS_SCB_UNLOCK(cpu_flags) spin_unlock_irqrestore(&ha->scb_lock, cpu_flags)
#define IPS_QUEUE_LOCK(queue) spin_lock_irqsave(&(queue)->lock, (queue)->cpu_flags)
#define IPS_QUEUE_UNLOCK(queue) spin_unlock_irqrestore(&(queue)->lock, (queue)->cpu_flags)
#define IPS_HA_LOCK(cpu_flags) spin_lock_irqsave(&ha->ips_lock, cpu_flags)
#define IPS_HA_UNLOCK(cpu_flags) spin_unlock_irqrestore(&ha->ips_lock, cpu_flags)
/* /*
* Adapter address map equates * Adapter address map equates
*/ */
...@@ -1054,8 +1044,6 @@ typedef struct ips_scb_queue { ...@@ -1054,8 +1044,6 @@ typedef struct ips_scb_queue {
struct ips_scb *head; struct ips_scb *head;
struct ips_scb *tail; struct ips_scb *tail;
int count; int count;
unsigned long cpu_flags;
spinlock_t lock;
} ips_scb_queue_t; } ips_scb_queue_t;
/* /*
...@@ -1065,13 +1053,10 @@ typedef struct ips_wait_queue { ...@@ -1065,13 +1053,10 @@ typedef struct ips_wait_queue {
Scsi_Cmnd *head; Scsi_Cmnd *head;
Scsi_Cmnd *tail; Scsi_Cmnd *tail;
int count; int count;
unsigned long cpu_flags;
spinlock_t lock;
} ips_wait_queue_t; } ips_wait_queue_t;
typedef struct ips_copp_wait_item { typedef struct ips_copp_wait_item {
Scsi_Cmnd *scsi_cmd; Scsi_Cmnd *scsi_cmd;
struct semaphore *sem;
struct ips_copp_wait_item *next; struct ips_copp_wait_item *next;
} ips_copp_wait_item_t; } ips_copp_wait_item_t;
...@@ -1079,8 +1064,6 @@ typedef struct ips_copp_queue { ...@@ -1079,8 +1064,6 @@ typedef struct ips_copp_queue {
struct ips_copp_wait_item *head; struct ips_copp_wait_item *head;
struct ips_copp_wait_item *tail; struct ips_copp_wait_item *tail;
int count; int count;
unsigned long cpu_flags;
spinlock_t lock;
} ips_copp_queue_t; } ips_copp_queue_t;
/* forward decl for host structure */ /* forward decl for host structure */
...@@ -1129,7 +1112,6 @@ typedef struct ips_ha { ...@@ -1129,7 +1112,6 @@ typedef struct ips_ha {
char *ioctl_data; /* IOCTL data area */ char *ioctl_data; /* IOCTL data area */
uint32_t ioctl_datasize; /* IOCTL data size */ uint32_t ioctl_datasize; /* IOCTL data size */
uint32_t cmd_in_progress; /* Current command in progress*/ uint32_t cmd_in_progress; /* Current command in progress*/
unsigned long flags; /* HA flags */
uint8_t waitflag; /* are we waiting for cmd */ uint8_t waitflag; /* are we waiting for cmd */
uint8_t active; uint8_t active;
int ioctl_reset; /* IOCTL Requested Reset Flag */ int ioctl_reset; /* IOCTL Requested Reset Flag */
...@@ -1149,11 +1131,6 @@ typedef struct ips_ha { ...@@ -1149,11 +1131,6 @@ typedef struct ips_ha {
char *ioremap_ptr; /* ioremapped memory pointer */ char *ioremap_ptr; /* ioremapped memory pointer */
ips_hw_func_t func; /* hw function pointers */ ips_hw_func_t func; /* hw function pointers */
struct pci_dev *pcidev; /* PCI device handle */ struct pci_dev *pcidev; /* PCI device handle */
spinlock_t scb_lock;
spinlock_t copp_lock;
spinlock_t ips_lock;
struct semaphore ioctl_sem; /* Semaphore for new IOCTL's */
struct semaphore flash_ioctl_sem; /* Semaphore for Flashing */
char *flash_data; /* Save Area for flash data */ char *flash_data; /* Save Area for flash data */
u8 flash_order; /* Save Area for flash size order */ u8 flash_order; /* Save Area for flash size order */
u32 flash_datasize; /* Save Area for flash data size */ u32 flash_datasize; /* Save Area for flash data size */
...@@ -1186,7 +1163,6 @@ typedef struct ips_scb { ...@@ -1186,7 +1163,6 @@ typedef struct ips_scb {
Scsi_Cmnd *scsi_cmd; Scsi_Cmnd *scsi_cmd;
struct ips_scb *q_next; struct ips_scb *q_next;
ips_scb_callback callback; ips_scb_callback callback;
struct semaphore *sem;
uint32_t sg_busaddr; uint32_t sg_busaddr;
int sg_count; int sg_count;
} ips_scb_t; } ips_scb_t;
......
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