aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave C Boutcher <sleddog@us.ibm.com>2005-08-15 17:52:58 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-08-28 12:14:08 -0400
commitbe042f240a8528b8f6b741a484cdbbf515698388 (patch)
tree2015cb8448cdfb0350cfd582c660535e4242fed0
parent3b2946cc96bfafa90a555c70b2e876cbbd0fae98 (diff)
[SCSI] ibmvscsi eh locking
With the removal of the spinlocking around eh calls, we need to add a little more locking back in, otherwise we do some naked list manipulation. Signed-off-by: Dave Boutcher <boutcher@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index fe09d145542a..1ae800ae93d7 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -826,11 +826,13 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
826 struct srp_event_struct *tmp_evt, *found_evt; 826 struct srp_event_struct *tmp_evt, *found_evt;
827 union viosrp_iu srp_rsp; 827 union viosrp_iu srp_rsp;
828 int rsp_rc; 828 int rsp_rc;
829 unsigned long flags;
829 u16 lun = lun_from_dev(cmd->device); 830 u16 lun = lun_from_dev(cmd->device);
830 831
831 /* First, find this command in our sent list so we can figure 832 /* First, find this command in our sent list so we can figure
832 * out the correct tag 833 * out the correct tag
833 */ 834 */
835 spin_lock_irqsave(hostdata->host->host_lock, flags);
834 found_evt = NULL; 836 found_evt = NULL;
835 list_for_each_entry(tmp_evt, &hostdata->sent, list) { 837 list_for_each_entry(tmp_evt, &hostdata->sent, list) {
836 if (tmp_evt->cmnd == cmd) { 838 if (tmp_evt->cmnd == cmd) {
@@ -839,11 +841,14 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
839 } 841 }
840 } 842 }
841 843
842 if (!found_evt) 844 if (!found_evt) {
845 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
843 return FAILED; 846 return FAILED;
847 }
844 848
845 evt = get_event_struct(&hostdata->pool); 849 evt = get_event_struct(&hostdata->pool);
846 if (evt == NULL) { 850 if (evt == NULL) {
851 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
847 printk(KERN_ERR "ibmvscsi: failed to allocate abort event\n"); 852 printk(KERN_ERR "ibmvscsi: failed to allocate abort event\n");
848 return FAILED; 853 return FAILED;
849 } 854 }
@@ -867,7 +872,9 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
867 872
868 evt->sync_srp = &srp_rsp; 873 evt->sync_srp = &srp_rsp;
869 init_completion(&evt->comp); 874 init_completion(&evt->comp);
870 if (ibmvscsi_send_srp_event(evt, hostdata) != 0) { 875 rsp_rc = ibmvscsi_send_srp_event(evt, hostdata);
876 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
877 if (rsp_rc != 0) {
871 printk(KERN_ERR "ibmvscsi: failed to send abort() event\n"); 878 printk(KERN_ERR "ibmvscsi: failed to send abort() event\n");
872 return FAILED; 879 return FAILED;
873 } 880 }
@@ -901,6 +908,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
901 * The event is no longer in our list. Make sure it didn't 908 * The event is no longer in our list. Make sure it didn't
902 * complete while we were aborting 909 * complete while we were aborting
903 */ 910 */
911 spin_lock_irqsave(hostdata->host->host_lock, flags);
904 found_evt = NULL; 912 found_evt = NULL;
905 list_for_each_entry(tmp_evt, &hostdata->sent, list) { 913 list_for_each_entry(tmp_evt, &hostdata->sent, list) {
906 if (tmp_evt->cmnd == cmd) { 914 if (tmp_evt->cmnd == cmd) {
@@ -910,6 +918,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
910 } 918 }
911 919
912 if (found_evt == NULL) { 920 if (found_evt == NULL) {
921 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
913 printk(KERN_INFO 922 printk(KERN_INFO
914 "ibmvscsi: aborted task tag 0x%lx completed\n", 923 "ibmvscsi: aborted task tag 0x%lx completed\n",
915 tsk_mgmt->managed_task_tag); 924 tsk_mgmt->managed_task_tag);
@@ -924,6 +933,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
924 list_del(&found_evt->list); 933 list_del(&found_evt->list);
925 unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt->hostdata->dev); 934 unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt->hostdata->dev);
926 free_event_struct(&found_evt->hostdata->pool, found_evt); 935 free_event_struct(&found_evt->hostdata->pool, found_evt);
936 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
927 atomic_inc(&hostdata->request_limit); 937 atomic_inc(&hostdata->request_limit);
928 return SUCCESS; 938 return SUCCESS;
929} 939}
@@ -943,10 +953,13 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
943 struct srp_event_struct *tmp_evt, *pos; 953 struct srp_event_struct *tmp_evt, *pos;
944 union viosrp_iu srp_rsp; 954 union viosrp_iu srp_rsp;
945 int rsp_rc; 955 int rsp_rc;
956 unsigned long flags;
946 u16 lun = lun_from_dev(cmd->device); 957 u16 lun = lun_from_dev(cmd->device);
947 958
959 spin_lock_irqsave(hostdata->host->host_lock, flags);
948 evt = get_event_struct(&hostdata->pool); 960 evt = get_event_struct(&hostdata->pool);
949 if (evt == NULL) { 961 if (evt == NULL) {
962 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
950 printk(KERN_ERR "ibmvscsi: failed to allocate reset event\n"); 963 printk(KERN_ERR "ibmvscsi: failed to allocate reset event\n");
951 return FAILED; 964 return FAILED;
952 } 965 }
@@ -969,7 +982,9 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
969 982
970 evt->sync_srp = &srp_rsp; 983 evt->sync_srp = &srp_rsp;
971 init_completion(&evt->comp); 984 init_completion(&evt->comp);
972 if (ibmvscsi_send_srp_event(evt, hostdata) != 0) { 985 rsp_rc = ibmvscsi_send_srp_event(evt, hostdata);
986 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
987 if (rsp_rc != 0) {
973 printk(KERN_ERR "ibmvscsi: failed to send reset event\n"); 988 printk(KERN_ERR "ibmvscsi: failed to send reset event\n");
974 return FAILED; 989 return FAILED;
975 } 990 }
@@ -1002,6 +1017,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
1002 /* We need to find all commands for this LUN that have not yet been 1017 /* We need to find all commands for this LUN that have not yet been
1003 * responded to, and fail them with DID_RESET 1018 * responded to, and fail them with DID_RESET
1004 */ 1019 */
1020 spin_lock_irqsave(hostdata->host->host_lock, flags);
1005 list_for_each_entry_safe(tmp_evt, pos, &hostdata->sent, list) { 1021 list_for_each_entry_safe(tmp_evt, pos, &hostdata->sent, list) {
1006 if ((tmp_evt->cmnd) && (tmp_evt->cmnd->device == cmd->device)) { 1022 if ((tmp_evt->cmnd) && (tmp_evt->cmnd->device == cmd->device)) {
1007 if (tmp_evt->cmnd) 1023 if (tmp_evt->cmnd)
@@ -1017,6 +1033,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
1017 tmp_evt->done(tmp_evt); 1033 tmp_evt->done(tmp_evt);
1018 } 1034 }
1019 } 1035 }
1036 spin_unlock_irqrestore(hostdata->host->host_lock, flags);
1020 return SUCCESS; 1037 return SUCCESS;
1021} 1038}
1022 1039