diff options
| author | Giridhar Malavali <giridhar.malavali@qlogic.com> | 2010-02-18 13:07:24 -0500 |
|---|---|---|
| committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-19 11:44:52 -0500 |
| commit | db3ad7f8852cfdfa03f72b27472e5a8bc9c1e1cf (patch) | |
| tree | cf71e747b4844cf20e73fd582ee63d38ec7e0080 | |
| parent | 236b0249c2274cd24bc98a1fbbb5e78d861d4bd9 (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>
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 125 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 15 |
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 | ||
| 2392 | done: | ||
| 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 | } |
