aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>2011-09-19 19:52:13 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-09-22 07:17:11 -0400
commit822f29032b98ee44eb8ef2684ba4c7df6c967198 (patch)
treeaa5717261acff2a0bc82239e572e7d561a25e563
parent3ce41ea1478e9dcc3a0e47189c443ba3c7670b70 (diff)
[SCSI] bnx2fc: Handle bnx2fc_map_sg failure
Gracefully handle bnx2fc_map_sg failure, so that queuecommand returns host busy and SCSI-ml can retry the IO. Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_io.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 86da3014d150..0c64d184d731 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -17,7 +17,7 @@
17static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len, 17static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len,
18 int bd_index); 18 int bd_index);
19static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req); 19static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req);
20static void bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req); 20static int bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req);
21static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req); 21static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req);
22static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req); 22static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req);
23static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, 23static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req,
@@ -1607,20 +1607,24 @@ static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req)
1607 return bd_count; 1607 return bd_count;
1608} 1608}
1609 1609
1610static void bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req) 1610static int bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req)
1611{ 1611{
1612 struct scsi_cmnd *sc = io_req->sc_cmd; 1612 struct scsi_cmnd *sc = io_req->sc_cmd;
1613 struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl; 1613 struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl;
1614 int bd_count; 1614 int bd_count;
1615 1615
1616 if (scsi_sg_count(sc)) 1616 if (scsi_sg_count(sc)) {
1617 bd_count = bnx2fc_map_sg(io_req); 1617 bd_count = bnx2fc_map_sg(io_req);
1618 else { 1618 if (bd_count == 0)
1619 return -ENOMEM;
1620 } else {
1619 bd_count = 0; 1621 bd_count = 0;
1620 bd[0].buf_addr_lo = bd[0].buf_addr_hi = 0; 1622 bd[0].buf_addr_lo = bd[0].buf_addr_hi = 0;
1621 bd[0].buf_len = bd[0].flags = 0; 1623 bd[0].buf_len = bd[0].flags = 0;
1622 } 1624 }
1623 io_req->bd_tbl->bd_valid = bd_count; 1625 io_req->bd_tbl->bd_valid = bd_count;
1626
1627 return 0;
1624} 1628}
1625 1629
1626static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req) 1630static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req)
@@ -1942,7 +1946,13 @@ int bnx2fc_post_io_req(struct bnx2fc_rport *tgt,
1942 xid = io_req->xid; 1946 xid = io_req->xid;
1943 1947
1944 /* Build buffer descriptor list for firmware from sg list */ 1948 /* Build buffer descriptor list for firmware from sg list */
1945 bnx2fc_build_bd_list_from_sg(io_req); 1949 if (bnx2fc_build_bd_list_from_sg(io_req)) {
1950 printk(KERN_ERR PFX "BD list creation failed\n");
1951 spin_lock_bh(&tgt->tgt_lock);
1952 kref_put(&io_req->refcount, bnx2fc_cmd_release);
1953 spin_unlock_bh(&tgt->tgt_lock);
1954 return -EAGAIN;
1955 }
1946 1956
1947 task_idx = xid / BNX2FC_TASKS_PER_PAGE; 1957 task_idx = xid / BNX2FC_TASKS_PER_PAGE;
1948 index = xid % BNX2FC_TASKS_PER_PAGE; 1958 index = xid % BNX2FC_TASKS_PER_PAGE;