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