summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/dpt_i2o.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/dpt_i2o.c')
-rw-r--r--drivers/scsi/dpt_i2o.c79
1 files changed, 49 insertions, 30 deletions
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index c28e3aea1c3..6e6b293dcb2 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -61,6 +61,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/ioport.h>
+#include <linux/mutex.h>
#include <asm/processor.h> /* for boot_cpu_data */
#include <asm/pgtable.h>
@@ -106,7 +107,7 @@ static dpt_sig_S DPTI_sig = {
*============================================================================
*/
-static DECLARE_MUTEX(adpt_configuration_lock);
+static DEFINE_MUTEX(adpt_configuration_lock);
static struct i2o_sys_tbl *sys_tbl = NULL;
static int sys_tbl_ind = 0;
@@ -537,13 +538,13 @@ static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, of
*/
// Find HBA (host bus adapter) we are looking for
- down(&adpt_configuration_lock);
+ mutex_lock(&adpt_configuration_lock);
for (pHba = hba_chain; pHba; pHba = pHba->next) {
if (pHba->host == host) {
break; /* found adapter */
}
}
- up(&adpt_configuration_lock);
+ mutex_unlock(&adpt_configuration_lock);
if (pHba == NULL) {
return 0;
}
@@ -660,7 +661,12 @@ static int adpt_abort(struct scsi_cmnd * cmd)
msg[2] = 0;
msg[3]= 0;
msg[4] = (u32)cmd;
- if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){
+ if (pHba->host)
+ spin_lock_irq(pHba->host->host_lock);
+ rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
+ if (pHba->host)
+ spin_unlock_irq(pHba->host->host_lock);
+ if (rcode != 0) {
if(rcode == -EOPNOTSUPP ){
printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
return FAILED;
@@ -697,10 +703,15 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
msg[2] = 0;
msg[3] = 0;
+ if (pHba->host)
+ spin_lock_irq(pHba->host->host_lock);
old_state = d->state;
d->state |= DPTI_DEV_RESET;
- if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){
- d->state = old_state;
+ rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
+ d->state = old_state;
+ if (pHba->host)
+ spin_unlock_irq(pHba->host->host_lock);
+ if (rcode != 0) {
if(rcode == -EOPNOTSUPP ){
printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
return FAILED;
@@ -708,7 +719,6 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
return FAILED;
} else {
- d->state = old_state;
printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
return SUCCESS;
}
@@ -721,6 +731,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
u32 msg[4];
+ u32 rcode;
pHba = (adpt_hba*)cmd->device->host->hostdata[0];
memset(msg, 0, sizeof(msg));
@@ -729,7 +740,12 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd)
msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
msg[2] = 0;
msg[3] = 0;
- if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){
+ if (pHba->host)
+ spin_lock_irq(pHba->host->host_lock);
+ rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
+ if (pHba->host)
+ spin_unlock_irq(pHba->host->host_lock);
+ if (rcode != 0) {
printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
return FAILED;
} else {
@@ -816,7 +832,7 @@ static int adpt_hba_reset(adpt_hba* pHba)
static void adpt_i2o_sys_shutdown(void)
{
adpt_hba *pHba, *pNext;
- struct adpt_i2o_post_wait_data *p1, *p2;
+ struct adpt_i2o_post_wait_data *p1, *old;
printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n");
printk(KERN_INFO" This could take a few minutes if there are many devices attached\n");
@@ -830,13 +846,14 @@ static void adpt_i2o_sys_shutdown(void)
}
/* Remove any timedout entries from the wait queue. */
- p2 = NULL;
// spin_lock_irqsave(&adpt_post_wait_lock, flags);
/* Nothing should be outstanding at this point so just
* free them
*/
- for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p2->next) {
- kfree(p1);
+ for(p1 = adpt_post_wait_queue; p1;) {
+ old = p1;
+ p1 = p1->next;
+ kfree(old);
}
// spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
adpt_post_wait_queue = NULL;
@@ -882,6 +899,12 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
if(pci_enable_device(pDev)) {
return -EINVAL;
}
+
+ if (pci_request_regions(pDev, "dpt_i2o")) {
+ PERROR("dpti: adpt_config_hba: pci request region failed\n");
+ return -EINVAL;
+ }
+
pci_set_master(pDev);
if (pci_set_dma_mask(pDev, 0xffffffffffffffffULL) &&
pci_set_dma_mask(pDev, 0xffffffffULL))
@@ -907,10 +930,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
raptorFlag = TRUE;
}
- if (pci_request_regions(pDev, "dpt_i2o")) {
- PERROR("dpti: adpt_config_hba: pci request region failed\n");
- return -EINVAL;
- }
base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
if (!base_addr_virt) {
pci_release_regions(pDev);
@@ -942,7 +961,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
}
memset(pHba, 0, sizeof(adpt_hba));
- down(&adpt_configuration_lock);
+ mutex_lock(&adpt_configuration_lock);
if(hba_chain != NULL){
for(p = hba_chain; p->next; p = p->next);
@@ -955,7 +974,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
sprintf(pHba->name, "dpti%d", hba_count);
hba_count++;
- up(&adpt_configuration_lock);
+ mutex_unlock(&adpt_configuration_lock);
pHba->pDev = pDev;
pHba->base_addr_phys = base_addr0_phys;
@@ -1011,7 +1030,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
struct adpt_device* pNext;
- down(&adpt_configuration_lock);
+ mutex_lock(&adpt_configuration_lock);
// scsi_unregister calls our adpt_release which
// does a quiese
if(pHba->host){
@@ -1030,7 +1049,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
}
hba_count--;
- up(&adpt_configuration_lock);
+ mutex_unlock(&adpt_configuration_lock);
iounmap(pHba->base_addr_virt);
pci_release_regions(pHba->pDev);
@@ -1533,7 +1552,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
{
- down(&adpt_configuration_lock);
+ mutex_lock(&adpt_configuration_lock);
d->controller=pHba;
d->owner=NULL;
d->next=pHba->devices;
@@ -1544,7 +1563,7 @@ static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
pHba->devices=d;
*d->dev_name = 0;
- up(&adpt_configuration_lock);
+ mutex_unlock(&adpt_configuration_lock);
return 0;
}
@@ -1559,24 +1578,24 @@ static int adpt_open(struct inode *inode, struct file *file)
if (minor >= hba_count) {
return -ENXIO;
}
- down(&adpt_configuration_lock);
+ mutex_lock(&adpt_configuration_lock);
for (pHba = hba_chain; pHba; pHba = pHba->next) {
if (pHba->unit == minor) {
break; /* found adapter */
}
}
if (pHba == NULL) {
- up(&adpt_configuration_lock);
+ mutex_unlock(&adpt_configuration_lock);
return -ENXIO;
}
// if(pHba->in_use){
- // up(&adpt_configuration_lock);
+ // mutex_unlock(&adpt_configuration_lock);
// return -EBUSY;
// }
pHba->in_use = 1;
- up(&adpt_configuration_lock);
+ mutex_unlock(&adpt_configuration_lock);
return 0;
}
@@ -1590,13 +1609,13 @@ static int adpt_close(struct inode *inode, struct file *file)
if (minor >= hba_count) {
return -ENXIO;
}
- down(&adpt_configuration_lock);
+ mutex_lock(&adpt_configuration_lock);
for (pHba = hba_chain; pHba; pHba = pHba->next) {
if (pHba->unit == minor) {
break; /* found adapter */
}
}
- up(&adpt_configuration_lock);
+ mutex_unlock(&adpt_configuration_lock);
if (pHba == NULL) {
return -ENXIO;
}
@@ -1894,13 +1913,13 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
if (minor >= DPTI_MAX_HBA){
return -ENXIO;
}
- down(&adpt_configuration_lock);
+ mutex_lock(&adpt_configuration_lock);
for (pHba = hba_chain; pHba; pHba = pHba->next) {
if (pHba->unit == minor) {
break; /* found adapter */
}
}
- up(&adpt_configuration_lock);
+ mutex_unlock(&adpt_configuration_lock);
if(pHba == NULL){
return -ENXIO;
}