Commit 968020d4 authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley

[PATCH] PATCH [2/15] qla2xxx: Track DSDs used by an SRB

Track the number of DSDs and request entries required for an
SRB in case of a request-entry or command-slot shortage.
parent b6b13f96
...@@ -266,6 +266,10 @@ typedef struct srb { ...@@ -266,6 +266,10 @@ typedef struct srb {
uint8_t fo_retry_cnt; /* Retry count this request */ uint8_t fo_retry_cnt; /* Retry count this request */
uint8_t err_id; /* error id */ uint8_t err_id; /* error id */
/* Segment/entries counts */
uint16_t req_cnt; /* !0 indicates counts determined */
uint16_t tot_dsds;
/* SRB magic number */ /* SRB magic number */
uint16_t magic; uint16_t magic;
#define SRB_MAGIC 0x10CB #define SRB_MAGIC 0x10CB
......
...@@ -350,7 +350,7 @@ qla2x00_start_scsi(srb_t *sp) ...@@ -350,7 +350,7 @@ qla2x00_start_scsi(srb_t *sp)
uint32_t *clr_ptr; uint32_t *clr_ptr;
uint32_t index; uint32_t index;
uint32_t handle; uint32_t handle;
uint16_t cnt, tot_dsds, req_cnt; uint16_t cnt;
cmd_entry_t *cmd_pkt; cmd_entry_t *cmd_pkt;
uint32_t timeout; uint32_t timeout;
struct scatterlist *sg; struct scatterlist *sg;
...@@ -372,21 +372,23 @@ qla2x00_start_scsi(srb_t *sp) ...@@ -372,21 +372,23 @@ qla2x00_start_scsi(srb_t *sp)
ha->marker_needed = 0; ha->marker_needed = 0;
} }
/* Calculate number of segments and entries required */ /* Calculate number of segments and entries required. */
tot_dsds = 0; if (sp->req_cnt == 0) {
if (cmd->use_sg) { sp->tot_dsds = 0;
sg = (struct scatterlist *) cmd->request_buffer; if (cmd->use_sg) {
tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg, sg = (struct scatterlist *) cmd->request_buffer;
cmd->sc_data_direction); sp->tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg,
} else if (cmd->request_bufflen) { /* Single segment transfer */ cmd->sc_data_direction);
tot_dsds++; } else if (cmd->request_bufflen) {
sp->tot_dsds++;
}
sp->req_cnt = (ha->calc_request_entries)(sp->tot_dsds);
} }
req_cnt = (ha->calc_request_entries)(tot_dsds);
/* Acquire ring specific lock */ /* Acquire ring specific lock */
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
if (ha->req_q_cnt < (req_cnt + 2)) { if (ha->req_q_cnt < (sp->req_cnt + 2)) {
/* Calculate number of free request entries */ /* Calculate number of free request entries */
cnt = RD_REG_WORD(ISP_REQ_Q_OUT(ha, reg)); cnt = RD_REG_WORD(ISP_REQ_Q_OUT(ha, reg));
if (ha->req_ring_index < cnt) if (ha->req_ring_index < cnt)
...@@ -397,10 +399,11 @@ qla2x00_start_scsi(srb_t *sp) ...@@ -397,10 +399,11 @@ qla2x00_start_scsi(srb_t *sp)
} }
/* If no room for request in request ring */ /* If no room for request in request ring */
if (ha->req_q_cnt < (req_cnt + 2)) { if (ha->req_q_cnt < (sp->req_cnt + 2)) {
DEBUG5(printk("scsi(%ld): in-ptr=%x req_q_cnt=%x " DEBUG5(printk("scsi(%ld): in-ptr=%x req_q_cnt=%x "
"tot_dsds=%x.\n", "tot_dsds=%x.\n",
ha->host_no, ha->req_ring_index, ha->req_q_cnt, tot_dsds)); ha->host_no, ha->req_ring_index, ha->req_q_cnt,
sp->tot_dsds));
goto queuing_error; goto queuing_error;
} }
...@@ -427,14 +430,14 @@ qla2x00_start_scsi(srb_t *sp) ...@@ -427,14 +430,14 @@ qla2x00_start_scsi(srb_t *sp)
ha->outstanding_cmds[handle] = sp; ha->outstanding_cmds[handle] = sp;
sp->ha = ha; sp->ha = ha;
sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
ha->req_q_cnt -= req_cnt; ha->req_q_cnt -= sp->req_cnt;
cmd_pkt = (cmd_entry_t *)ha->request_ring_ptr; cmd_pkt = (cmd_entry_t *)ha->request_ring_ptr;
cmd_pkt->handle = handle; cmd_pkt->handle = handle;
/* Zero out remaining portion of packet. */ /* Zero out remaining portion of packet. */
clr_ptr = (uint32_t *)cmd_pkt + 2; clr_ptr = (uint32_t *)cmd_pkt + 2;
memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8); memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
cmd_pkt->dseg_count = cpu_to_le16(tot_dsds); cmd_pkt->dseg_count = cpu_to_le16(sp->tot_dsds);
/* Set target ID */ /* Set target ID */
SET_TARGET_ID(ha, cmd_pkt->target, fclun->fcport->loop_id); SET_TARGET_ID(ha, cmd_pkt->target, fclun->fcport->loop_id);
...@@ -474,10 +477,10 @@ qla2x00_start_scsi(srb_t *sp) ...@@ -474,10 +477,10 @@ qla2x00_start_scsi(srb_t *sp)
cmd_pkt->byte_count = cpu_to_le32((uint32_t)cmd->request_bufflen); cmd_pkt->byte_count = cpu_to_le32((uint32_t)cmd->request_bufflen);
/* Build IOCB segments */ /* Build IOCB segments */
(ha->build_scsi_iocbs)(sp, cmd_pkt, tot_dsds); (ha->build_scsi_iocbs)(sp, cmd_pkt, sp->tot_dsds);
/* Set total data segment count. */ /* Set total data segment count. */
cmd_pkt->entry_count = (uint8_t)req_cnt; cmd_pkt->entry_count = (uint8_t)sp->req_cnt;
/* Adjust ring index. */ /* Adjust ring index. */
ha->req_ring_index++; ha->req_ring_index++;
...@@ -504,9 +507,6 @@ qla2x00_start_scsi(srb_t *sp) ...@@ -504,9 +507,6 @@ qla2x00_start_scsi(srb_t *sp)
queuing_error: queuing_error:
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (cmd->use_sg)
pci_unmap_sg(ha->pdev, sg, cmd->use_sg, cmd->sc_data_direction);
return (QLA_FUNCTION_FAILED); return (QLA_FUNCTION_FAILED);
} }
......
...@@ -3593,6 +3593,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha) ...@@ -3593,6 +3593,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha)
sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL); sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
if (sp) { if (sp) {
atomic_set(&sp->ref_count, 1); atomic_set(&sp->ref_count, 1);
sp->req_cnt = 0;
} }
return (sp); return (sp);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment