aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c93
1 files changed, 60 insertions, 33 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c79b4dc8aa4a..be11bb9cb176 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -899,9 +899,12 @@ lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba)
899 int num_posted, rc = 0; 899 int num_posted, rc = 0;
900 900
901 /* get all SCSI buffers need to repost to a local list */ 901 /* get all SCSI buffers need to repost to a local list */
902 spin_lock_irq(&phba->scsi_buf_list_lock); 902 spin_lock_irq(&phba->scsi_buf_list_get_lock);
903 list_splice_init(&phba->lpfc_scsi_buf_list, &post_sblist); 903 spin_lock_irq(&phba->scsi_buf_list_put_lock);
904 spin_unlock_irq(&phba->scsi_buf_list_lock); 904 list_splice_init(&phba->lpfc_scsi_buf_list_get, &post_sblist);
905 list_splice(&phba->lpfc_scsi_buf_list_put, &post_sblist);
906 spin_unlock_irq(&phba->scsi_buf_list_put_lock);
907 spin_unlock_irq(&phba->scsi_buf_list_get_lock);
905 908
906 /* post the list of scsi buffer sgls to port if available */ 909 /* post the list of scsi buffer sgls to port if available */
907 if (!list_empty(&post_sblist)) { 910 if (!list_empty(&post_sblist)) {
@@ -1053,9 +1056,9 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
1053 1056
1054 /* add the scsi buffer to a post list */ 1057 /* add the scsi buffer to a post list */
1055 list_add_tail(&psb->list, &post_sblist); 1058 list_add_tail(&psb->list, &post_sblist);
1056 spin_lock_irq(&phba->scsi_buf_list_lock); 1059 spin_lock_irq(&phba->scsi_buf_list_get_lock);
1057 phba->sli4_hba.scsi_xri_cnt++; 1060 phba->sli4_hba.scsi_xri_cnt++;
1058 spin_unlock_irq(&phba->scsi_buf_list_lock); 1061 spin_unlock_irq(&phba->scsi_buf_list_get_lock);
1059 } 1062 }
1060 lpfc_printf_log(phba, KERN_INFO, LOG_BG, 1063 lpfc_printf_log(phba, KERN_INFO, LOG_BG,
1061 "3021 Allocate %d out of %d requested new SCSI " 1064 "3021 Allocate %d out of %d requested new SCSI "
@@ -1104,17 +1107,23 @@ static struct lpfc_scsi_buf*
1104lpfc_get_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) 1107lpfc_get_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1105{ 1108{
1106 struct lpfc_scsi_buf * lpfc_cmd = NULL; 1109 struct lpfc_scsi_buf * lpfc_cmd = NULL;
1107 struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; 1110 struct list_head *scsi_buf_list_get = &phba->lpfc_scsi_buf_list_get;
1108 unsigned long iflag = 0; 1111 unsigned long gflag = 0;
1109 1112 unsigned long pflag = 0;
1110 spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); 1113
1111 list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); 1114 spin_lock_irqsave(&phba->scsi_buf_list_get_lock, gflag);
1112 if (lpfc_cmd) { 1115 list_remove_head(scsi_buf_list_get, lpfc_cmd, struct lpfc_scsi_buf,
1113 lpfc_cmd->seg_cnt = 0; 1116 list);
1114 lpfc_cmd->nonsg_phys = 0; 1117 if (!lpfc_cmd) {
1115 lpfc_cmd->prot_seg_cnt = 0; 1118 spin_lock_irqsave(&phba->scsi_buf_list_put_lock, pflag);
1119 list_splice(&phba->lpfc_scsi_buf_list_put,
1120 &phba->lpfc_scsi_buf_list_get);
1121 INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_put);
1122 list_remove_head(scsi_buf_list_get, lpfc_cmd,
1123 struct lpfc_scsi_buf, list);
1124 spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, pflag);
1116 } 1125 }
1117 spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); 1126 spin_unlock_irqrestore(&phba->scsi_buf_list_get_lock, gflag);
1118 return lpfc_cmd; 1127 return lpfc_cmd;
1119} 1128}
1120/** 1129/**
@@ -1132,28 +1141,39 @@ static struct lpfc_scsi_buf*
1132lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) 1141lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
1133{ 1142{
1134 struct lpfc_scsi_buf *lpfc_cmd ; 1143 struct lpfc_scsi_buf *lpfc_cmd ;
1135 unsigned long iflag = 0; 1144 unsigned long gflag = 0;
1145 unsigned long pflag = 0;
1136 int found = 0; 1146 int found = 0;
1137 1147
1138 spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); 1148 spin_lock_irqsave(&phba->scsi_buf_list_get_lock, gflag);
1139 list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list, 1149 list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list_get, list) {
1140 list) {
1141 if (lpfc_test_rrq_active(phba, ndlp, 1150 if (lpfc_test_rrq_active(phba, ndlp,
1142 lpfc_cmd->cur_iocbq.sli4_lxritag)) 1151 lpfc_cmd->cur_iocbq.sli4_lxritag))
1143 continue; 1152 continue;
1144 list_del(&lpfc_cmd->list); 1153 list_del(&lpfc_cmd->list);
1145 found = 1; 1154 found = 1;
1146 lpfc_cmd->seg_cnt = 0;
1147 lpfc_cmd->nonsg_phys = 0;
1148 lpfc_cmd->prot_seg_cnt = 0;
1149 break; 1155 break;
1150 } 1156 }
1151 spin_unlock_irqrestore(&phba->scsi_buf_list_lock, 1157 if (!found) {
1152 iflag); 1158 spin_lock_irqsave(&phba->scsi_buf_list_put_lock, pflag);
1159 list_splice(&phba->lpfc_scsi_buf_list_put,
1160 &phba->lpfc_scsi_buf_list_get);
1161 INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_put);
1162 spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, pflag);
1163 list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list_get,
1164 list) {
1165 if (lpfc_test_rrq_active(
1166 phba, ndlp, lpfc_cmd->cur_iocbq.sli4_lxritag))
1167 continue;
1168 list_del(&lpfc_cmd->list);
1169 found = 1;
1170 break;
1171 }
1172 }
1173 spin_unlock_irqrestore(&phba->scsi_buf_list_get_lock, gflag);
1153 if (!found) 1174 if (!found)
1154 return NULL; 1175 return NULL;
1155 else 1176 return lpfc_cmd;
1156 return lpfc_cmd;
1157} 1177}
1158/** 1178/**
1159 * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA 1179 * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA
@@ -1185,10 +1205,14 @@ lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
1185{ 1205{
1186 unsigned long iflag = 0; 1206 unsigned long iflag = 0;
1187 1207
1188 spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); 1208 psb->seg_cnt = 0;
1209 psb->nonsg_phys = 0;
1210 psb->prot_seg_cnt = 0;
1211
1212 spin_lock_irqsave(&phba->scsi_buf_list_put_lock, iflag);
1189 psb->pCmd = NULL; 1213 psb->pCmd = NULL;
1190 list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list); 1214 list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list_put);
1191 spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); 1215 spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, iflag);
1192} 1216}
1193 1217
1194/** 1218/**
@@ -1206,6 +1230,10 @@ lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
1206{ 1230{
1207 unsigned long iflag = 0; 1231 unsigned long iflag = 0;
1208 1232
1233 psb->seg_cnt = 0;
1234 psb->nonsg_phys = 0;
1235 psb->prot_seg_cnt = 0;
1236
1209 if (psb->exch_busy) { 1237 if (psb->exch_busy) {
1210 spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, 1238 spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock,
1211 iflag); 1239 iflag);
@@ -1215,11 +1243,10 @@ lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
1215 spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock, 1243 spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock,
1216 iflag); 1244 iflag);
1217 } else { 1245 } else {
1218
1219 spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
1220 psb->pCmd = NULL; 1246 psb->pCmd = NULL;
1221 list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list); 1247 spin_lock_irqsave(&phba->scsi_buf_list_put_lock, iflag);
1222 spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); 1248 list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list_put);
1249 spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, iflag);
1223 } 1250 }
1224} 1251}
1225 1252