aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorGiridhar Malavali <giridhar.malavali@qlogic.com>2010-02-18 13:07:24 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-02-19 11:44:52 -0500
commitdb3ad7f8852cfdfa03f72b27472e5a8bc9c1e1cf (patch)
treecf71e747b4844cf20e73fd582ee63d38ec7e0080 /drivers/scsi/qla2xxx
parent236b0249c2274cd24bc98a1fbbb5e78d861d4bd9 (diff)
[SCSI] qla2xxx: Proper clean-up of BSG requests when request times out.
Fix for BSG request cleanup when the request timesout. Proper release of driver resources used for BSG request during timeout cleanup. Cc: stable@kernel.org Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c125
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c15
2 files changed, 67 insertions, 73 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index cbce52eb9b94..25596feea162 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1882,12 +1882,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
1882 ha = vha->hw; 1882 ha = vha->hw;
1883 type = "FC_BSG_RPT_ELS"; 1883 type = "FC_BSG_RPT_ELS";
1884 1884
1885 DEBUG2(printk(KERN_INFO
1886 "scsi(%ld): loop-id=%x portid=%02x%02x%02x.\n",
1887 fcport->vha->host_no, fcport->loop_id,
1888 fcport->d_id.b.domain, fcport->d_id.b.area,
1889 fcport->d_id.b.al_pa));
1890
1891 /* make sure the rport is logged in, 1885 /* make sure the rport is logged in,
1892 * if not perform fabric login 1886 * if not perform fabric login
1893 */ 1887 */
@@ -1904,11 +1898,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
1904 ha = vha->hw; 1898 ha = vha->hw;
1905 type = "FC_BSG_HST_ELS_NOLOGIN"; 1899 type = "FC_BSG_HST_ELS_NOLOGIN";
1906 1900
1907 DEBUG2(printk(KERN_INFO
1908 "scsi(%ld): loop-id=%x portid=%02x%02x%02x.\n",
1909 vha->host_no, vha->loop_id,
1910 vha->d_id.b.domain, vha->d_id.b.area, vha->d_id.b.al_pa));
1911
1912 /* Allocate a dummy fcport structure, since functions 1901 /* Allocate a dummy fcport structure, since functions
1913 * preparing the IOCB and mailbox command retrieves port 1902 * preparing the IOCB and mailbox command retrieves port
1914 * specific information from fcport structure. For Host based 1903 * specific information from fcport structure. For Host based
@@ -1934,9 +1923,12 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
1934 NPH_FABRIC_CONTROLLER : NPH_F_PORT; 1923 NPH_FABRIC_CONTROLLER : NPH_F_PORT;
1935 } 1924 }
1936 1925
1937 DEBUG2(printk(KERN_INFO 1926 if (!vha->flags.online) {
1938 "scsi(%ld): vendor-id = %llu\n", 1927 DEBUG2(qla_printk(KERN_WARNING, ha,
1939 vha->host_no, host->hostt->vendor_id)); 1928 "host not online\n"));
1929 rval = -EIO;
1930 goto done;
1931 }
1940 1932
1941 req_sg_cnt = 1933 req_sg_cnt =
1942 dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, 1934 dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
@@ -2059,6 +2051,13 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
2059 goto done_unmap_sg; 2051 goto done_unmap_sg;
2060 } 2052 }
2061 2053
2054 if (!vha->flags.online) {
2055 DEBUG2(qla_printk(KERN_WARNING, ha,
2056 "host not online\n"));
2057 rval = -EIO;
2058 goto done_unmap_sg;
2059 }
2060
2062 loop_id = 2061 loop_id =
2063 (bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000) 2062 (bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
2064 >> 24; 2063 >> 24;
@@ -2161,6 +2160,13 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
2161 goto done; 2160 goto done;
2162 } 2161 }
2163 2162
2163 if (!vha->flags.online) {
2164 DEBUG2(qla_printk(KERN_WARNING, ha,
2165 "host not online\n"));
2166 rval = -EIO;
2167 goto done;
2168 }
2169
2164 elreq.req_sg_cnt = 2170 elreq.req_sg_cnt =
2165 dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, 2171 dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
2166 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); 2172 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
@@ -2219,20 +2225,10 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
2219 if (ha->current_topology != ISP_CFG_F) { 2225 if (ha->current_topology != ISP_CFG_F) {
2220 type = "FC_BSG_HST_VENDOR_LOOPBACK"; 2226 type = "FC_BSG_HST_VENDOR_LOOPBACK";
2221 2227
2222 if ((IS_QLA81XX(ha)) &&
2223 ((elreq.options == 0) || (elreq.options == 2))) {
2224 DEBUG2(qla_printk(KERN_INFO, ha, "scsi(%ld)"
2225 "loopback option:0x%x not supported\n", vha->host_no, elreq.options));
2226 rval = -EINVAL;
2227 goto done_unmap_sg;
2228 }
2229
2230 DEBUG2(qla_printk(KERN_INFO, ha, 2228 DEBUG2(qla_printk(KERN_INFO, ha,
2231 "scsi(%ld) bsg rqst type: %s vendor rqst type: %x options: %x.\n", 2229 "scsi(%ld) bsg rqst type: %s vendor rqst type: %x options: %x.\n",
2232 vha->host_no, type, vendor_cmd, elreq.options)); 2230 vha->host_no, type, vendor_cmd, elreq.options));
2233 DEBUG2(qla_printk(KERN_INFO, ha, 2231
2234 "scsi(%ld) tx_addr: 0x%llx rx_addr: 0x%llx tx_sg_cnt: %x rx_sg_cnt: %x\n",
2235 vha->host_no, (unsigned long long)elreq.send_dma, (unsigned long long)elreq.rcv_dma, elreq.req_sg_cnt, elreq.rsp_sg_cnt));
2236 command_sent = INT_DEF_LB_LOOPBACK_CMD; 2232 command_sent = INT_DEF_LB_LOOPBACK_CMD;
2237 rval = qla2x00_loopback_test(vha, &elreq, response); 2233 rval = qla2x00_loopback_test(vha, &elreq, response);
2238 if (IS_QLA81XX(ha)) { 2234 if (IS_QLA81XX(ha)) {
@@ -2248,9 +2244,7 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
2248 DEBUG2(qla_printk(KERN_INFO, ha, 2244 DEBUG2(qla_printk(KERN_INFO, ha,
2249 "scsi(%ld) bsg rqst type: %s vendor rqst type: %x options: %x.\n", 2245 "scsi(%ld) bsg rqst type: %s vendor rqst type: %x options: %x.\n",
2250 vha->host_no, type, vendor_cmd, elreq.options)); 2246 vha->host_no, type, vendor_cmd, elreq.options));
2251 DEBUG2(qla_printk(KERN_INFO, ha, 2247
2252 "scsi(%ld) tx_addr: 0x%llx rx_addr: 0x%llx tx_sg_cnt: %x rx_sg_cnt: %x\n",
2253 vha->host_no, (unsigned long long)elreq.send_dma, (unsigned long long)elreq.rcv_dma, elreq.req_sg_cnt, elreq.rsp_sg_cnt));
2254 command_sent = INT_DEF_LB_ECHO_CMD; 2248 command_sent = INT_DEF_LB_ECHO_CMD;
2255 rval = qla2x00_echo_test(vha, &elreq, response); 2249 rval = qla2x00_echo_test(vha, &elreq, response);
2256 } 2250 }
@@ -2353,60 +2347,49 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
2353 scsi_qla_host_t *vha = shost_priv(bsg_job->shost); 2347 scsi_qla_host_t *vha = shost_priv(bsg_job->shost);
2354 struct qla_hw_data *ha = vha->hw; 2348 struct qla_hw_data *ha = vha->hw;
2355 srb_t *sp; 2349 srb_t *sp;
2356 int i; 2350 int cnt, que;
2357 unsigned long flags; 2351 unsigned long flags;
2358 uint16_t que_id;
2359 struct req_que *req; 2352 struct req_que *req;
2360 struct rsp_que *rsp;
2361 int found = 0;
2362 struct srb_bsg *sp_bsg; 2353 struct srb_bsg *sp_bsg;
2363 2354
2364 /* find the bsg job from the active list of commands */ 2355 /* find the bsg job from the active list of commands */
2365 spin_lock_irqsave(&ha->hardware_lock, flags); 2356 spin_lock_irqsave(&ha->hardware_lock, flags);
2366 req = ha->req_q_map[0]; 2357 for (que = 0; que < ha->max_req_queues; que++) {
2367 que_id = req->id; 2358 req = ha->req_q_map[que];
2368 if (req->rsp) 2359 if (!req)
2369 rsp = req->rsp; 2360 continue;
2370 else
2371 rsp = ha->rsp_q_map[que_id];
2372
2373 for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++ ) {
2374 sp = req->outstanding_cmds[i];
2375
2376 if (sp == NULL)
2377 continue;
2378
2379 sp_bsg = (struct srb_bsg*)sp->ctx;
2380 2361
2381 if (((sp_bsg->ctx.type == SRB_CT_CMD) || 2362 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++ ) {
2382 (sp_bsg->ctx.type == SRB_ELS_CMD_RPT) 2363 sp = req->outstanding_cmds[cnt];
2383 || ( sp_bsg->ctx.type == SRB_ELS_CMD_HST)) && 2364
2384 (sp_bsg->bsg_job == bsg_job)) { 2365 if (sp) {
2385 DEBUG2(qla_printk(KERN_INFO, ha, 2366 sp_bsg = (struct srb_bsg*)sp->ctx;
2386 "scsi(%ld) req_q: %p rsp_q: %p que_id: %x sp: %p\n", 2367
2387 vha->host_no, req, rsp, que_id, sp)); 2368 if (((sp_bsg->ctx.type == SRB_CT_CMD) ||
2388 found = 1; 2369 (sp_bsg->ctx.type == SRB_ELS_CMD_RPT)
2389 break; 2370 || ( sp_bsg->ctx.type == SRB_ELS_CMD_HST)) &&
2371 (sp_bsg->bsg_job == bsg_job)) {
2372 if (ha->isp_ops->abort_command(sp)) {
2373 DEBUG2(qla_printk(KERN_INFO, ha,
2374 "scsi(%ld): mbx abort_command failed\n", vha->host_no));
2375 bsg_job->req->errors = bsg_job->reply->result = -EIO;
2376 } else {
2377 DEBUG2(qla_printk(KERN_INFO, ha,
2378 "scsi(%ld): mbx abort_command success\n", vha->host_no));
2379 bsg_job->req->errors = bsg_job->reply->result = 0;
2380 }
2381 goto done;
2382 }
2383 }
2390 } 2384 }
2391 } 2385 }
2392 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2386 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2393 if (!found) { 2387 DEBUG2(qla_printk(KERN_INFO, ha,
2394 DEBUG2(qla_printk(KERN_INFO, ha, 2388 "scsi(%ld) SRB not found to abort\n", vha->host_no));
2395 "scsi(%ld) SRB not found to abort\n", vha->host_no)); 2389 bsg_job->req->errors = bsg_job->reply->result = -ENXIO;
2396 bsg_job->req->errors = bsg_job->reply->result = -ENXIO; 2390 return 0;
2397 return 0;
2398 }
2399
2400 if (ha->isp_ops->abort_command(sp)) {
2401 DEBUG2(qla_printk(KERN_INFO, ha,
2402 "scsi(%ld): mbx abort_command failed\n", vha->host_no));
2403 bsg_job->req->errors = bsg_job->reply->result = -EIO;
2404 } else {
2405 DEBUG2(qla_printk(KERN_INFO, ha,
2406 "scsi(%ld): mbx abort_command success\n", vha->host_no));
2407 bsg_job->req->errors = bsg_job->reply->result = 0;
2408 }
2409 2391
2392done:
2410 if (bsg_job->request->msgcode == FC_BSG_HST_CT) 2393 if (bsg_job->request->msgcode == FC_BSG_HST_CT)
2411 kfree(sp->fcport); 2394 kfree(sp->fcport);
2412 kfree(sp->ctx); 2395 kfree(sp->ctx);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 82e57d778428..83615e71fa0d 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1160,8 +1160,19 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1160 qla2x00_sp_compl(ha, sp); 1160 qla2x00_sp_compl(ha, sp);
1161 } else { 1161 } else {
1162 ctx = sp->ctx; 1162 ctx = sp->ctx;
1163 del_timer_sync(&ctx->timer); 1163 if (ctx->type == SRB_LOGIN_CMD || ctx->type == SRB_LOGOUT_CMD) {
1164 ctx->free(sp); 1164 del_timer_sync(&ctx->timer);
1165 ctx->free(sp);
1166 } else {
1167 struct srb_bsg* sp_bsg = (struct srb_bsg*)sp->ctx;
1168 if (sp_bsg->bsg_job->request->msgcode == FC_BSG_HST_CT)
1169 kfree(sp->fcport);
1170 sp_bsg->bsg_job->req->errors = 0;
1171 sp_bsg->bsg_job->reply->result = res;
1172 sp_bsg->bsg_job->job_done(sp_bsg->bsg_job);
1173 kfree(sp->ctx);
1174 mempool_free(sp, ha->srb_mempool);
1175 }
1165 } 1176 }
1166 } 1177 }
1167 } 1178 }