diff options
Diffstat (limited to 'drivers/scsi/dpt_i2o.c')
-rw-r--r-- | drivers/scsi/dpt_i2o.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index c28e3aea1c3c..6252b9ddc01e 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
@@ -660,7 +660,12 @@ static int adpt_abort(struct scsi_cmnd * cmd) | |||
660 | msg[2] = 0; | 660 | msg[2] = 0; |
661 | msg[3]= 0; | 661 | msg[3]= 0; |
662 | msg[4] = (u32)cmd; | 662 | msg[4] = (u32)cmd; |
663 | if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){ | 663 | if (pHba->host) |
664 | spin_lock_irq(pHba->host->host_lock); | ||
665 | rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); | ||
666 | if (pHba->host) | ||
667 | spin_unlock_irq(pHba->host->host_lock); | ||
668 | if (rcode != 0) { | ||
664 | if(rcode == -EOPNOTSUPP ){ | 669 | if(rcode == -EOPNOTSUPP ){ |
665 | printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name); | 670 | printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name); |
666 | return FAILED; | 671 | return FAILED; |
@@ -697,10 +702,15 @@ static int adpt_device_reset(struct scsi_cmnd* cmd) | |||
697 | msg[2] = 0; | 702 | msg[2] = 0; |
698 | msg[3] = 0; | 703 | msg[3] = 0; |
699 | 704 | ||
705 | if (pHba->host) | ||
706 | spin_lock_irq(pHba->host->host_lock); | ||
700 | old_state = d->state; | 707 | old_state = d->state; |
701 | d->state |= DPTI_DEV_RESET; | 708 | d->state |= DPTI_DEV_RESET; |
702 | if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){ | 709 | rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); |
703 | d->state = old_state; | 710 | d->state = old_state; |
711 | if (pHba->host) | ||
712 | spin_unlock_irq(pHba->host->host_lock); | ||
713 | if (rcode != 0) { | ||
704 | if(rcode == -EOPNOTSUPP ){ | 714 | if(rcode == -EOPNOTSUPP ){ |
705 | printk(KERN_INFO"%s: Device reset not supported\n",pHba->name); | 715 | printk(KERN_INFO"%s: Device reset not supported\n",pHba->name); |
706 | return FAILED; | 716 | return FAILED; |
@@ -708,7 +718,6 @@ static int adpt_device_reset(struct scsi_cmnd* cmd) | |||
708 | printk(KERN_INFO"%s: Device reset failed\n",pHba->name); | 718 | printk(KERN_INFO"%s: Device reset failed\n",pHba->name); |
709 | return FAILED; | 719 | return FAILED; |
710 | } else { | 720 | } else { |
711 | d->state = old_state; | ||
712 | printk(KERN_INFO"%s: Device reset successful\n",pHba->name); | 721 | printk(KERN_INFO"%s: Device reset successful\n",pHba->name); |
713 | return SUCCESS; | 722 | return SUCCESS; |
714 | } | 723 | } |
@@ -721,6 +730,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd) | |||
721 | { | 730 | { |
722 | adpt_hba* pHba; | 731 | adpt_hba* pHba; |
723 | u32 msg[4]; | 732 | u32 msg[4]; |
733 | u32 rcode; | ||
724 | 734 | ||
725 | pHba = (adpt_hba*)cmd->device->host->hostdata[0]; | 735 | pHba = (adpt_hba*)cmd->device->host->hostdata[0]; |
726 | memset(msg, 0, sizeof(msg)); | 736 | memset(msg, 0, sizeof(msg)); |
@@ -729,7 +739,12 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd) | |||
729 | msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid); | 739 | msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid); |
730 | msg[2] = 0; | 740 | msg[2] = 0; |
731 | msg[3] = 0; | 741 | msg[3] = 0; |
732 | if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){ | 742 | if (pHba->host) |
743 | spin_lock_irq(pHba->host->host_lock); | ||
744 | rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); | ||
745 | if (pHba->host) | ||
746 | spin_unlock_irq(pHba->host->host_lock); | ||
747 | if (rcode != 0) { | ||
733 | printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name); | 748 | printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name); |
734 | return FAILED; | 749 | return FAILED; |
735 | } else { | 750 | } else { |
@@ -816,7 +831,7 @@ static int adpt_hba_reset(adpt_hba* pHba) | |||
816 | static void adpt_i2o_sys_shutdown(void) | 831 | static void adpt_i2o_sys_shutdown(void) |
817 | { | 832 | { |
818 | adpt_hba *pHba, *pNext; | 833 | adpt_hba *pHba, *pNext; |
819 | struct adpt_i2o_post_wait_data *p1, *p2; | 834 | struct adpt_i2o_post_wait_data *p1, *old; |
820 | 835 | ||
821 | printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n"); | 836 | printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n"); |
822 | printk(KERN_INFO" This could take a few minutes if there are many devices attached\n"); | 837 | printk(KERN_INFO" This could take a few minutes if there are many devices attached\n"); |
@@ -830,13 +845,14 @@ static void adpt_i2o_sys_shutdown(void) | |||
830 | } | 845 | } |
831 | 846 | ||
832 | /* Remove any timedout entries from the wait queue. */ | 847 | /* Remove any timedout entries from the wait queue. */ |
833 | p2 = NULL; | ||
834 | // spin_lock_irqsave(&adpt_post_wait_lock, flags); | 848 | // spin_lock_irqsave(&adpt_post_wait_lock, flags); |
835 | /* Nothing should be outstanding at this point so just | 849 | /* Nothing should be outstanding at this point so just |
836 | * free them | 850 | * free them |
837 | */ | 851 | */ |
838 | for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p2->next) { | 852 | for(p1 = adpt_post_wait_queue; p1;) { |
839 | kfree(p1); | 853 | old = p1; |
854 | p1 = p1->next; | ||
855 | kfree(old); | ||
840 | } | 856 | } |
841 | // spin_unlock_irqrestore(&adpt_post_wait_lock, flags); | 857 | // spin_unlock_irqrestore(&adpt_post_wait_lock, flags); |
842 | adpt_post_wait_queue = NULL; | 858 | adpt_post_wait_queue = NULL; |