diff options
Diffstat (limited to 'drivers/scsi/bnx2fc/bnx2fc_io.c')
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_io.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 6cc3789075bc..0c64d184d731 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -17,7 +17,7 @@ static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len, int bd_index); static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req); -static void bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req); +static int bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req); static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req); static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req); static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, @@ -1251,7 +1251,6 @@ void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnp_req, seq_clnp_req->xid); goto free_cb_arg; } - kref_get(&orig_io_req->refcount); spin_unlock_bh(&tgt->tgt_lock); rc = bnx2fc_send_srr(orig_io_req, offset, r_ctl); @@ -1569,6 +1568,8 @@ static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len, static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req) { + struct bnx2fc_interface *interface = io_req->port->priv; + struct bnx2fc_hba *hba = interface->hba; struct scsi_cmnd *sc = io_req->sc_cmd; struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl; struct scatterlist *sg; @@ -1580,7 +1581,8 @@ static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req) u64 addr; int i; - sg_count = scsi_dma_map(sc); + sg_count = dma_map_sg(&hba->pcidev->dev, scsi_sglist(sc), + scsi_sg_count(sc), sc->sc_data_direction); scsi_for_each_sg(sc, sg, sg_count, i) { sg_len = sg_dma_len(sg); addr = sg_dma_address(sg); @@ -1605,20 +1607,24 @@ static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req) return bd_count; } -static void bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req) +static int bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req) { struct scsi_cmnd *sc = io_req->sc_cmd; struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl; int bd_count; - if (scsi_sg_count(sc)) + if (scsi_sg_count(sc)) { bd_count = bnx2fc_map_sg(io_req); - else { + if (bd_count == 0) + return -ENOMEM; + } else { bd_count = 0; bd[0].buf_addr_lo = bd[0].buf_addr_hi = 0; bd[0].buf_len = bd[0].flags = 0; } io_req->bd_tbl->bd_valid = bd_count; + + return 0; } static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req) @@ -1790,12 +1796,6 @@ int bnx2fc_queuecommand(struct Scsi_Host *host, tgt = (struct bnx2fc_rport *)&rp[1]; if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) { - if (test_bit(BNX2FC_FLAG_UPLD_REQ_COMPL, &tgt->flags)) { - sc_cmd->result = DID_NO_CONNECT << 16; - sc_cmd->scsi_done(sc_cmd); - return 0; - - } /* * Session is not offloaded yet. Let SCSI-ml retry * the command. @@ -1946,7 +1946,13 @@ int bnx2fc_post_io_req(struct bnx2fc_rport *tgt, xid = io_req->xid; /* Build buffer descriptor list for firmware from sg list */ - bnx2fc_build_bd_list_from_sg(io_req); + if (bnx2fc_build_bd_list_from_sg(io_req)) { + printk(KERN_ERR PFX "BD list creation failed\n"); + spin_lock_bh(&tgt->tgt_lock); + kref_put(&io_req->refcount, bnx2fc_cmd_release); + spin_unlock_bh(&tgt->tgt_lock); + return -EAGAIN; + } task_idx = xid / BNX2FC_TASKS_PER_PAGE; index = xid % BNX2FC_TASKS_PER_PAGE; |