summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c78
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h9
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c144
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c50
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c67
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
10 files changed, 200 insertions, 170 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index fbcb82a2f7f4..21e2bc4d7401 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1654,7 +1654,8 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
}
- if (scsi_add_host(vha->host, &fc_vport->dev)) {
+ if (scsi_add_host_with_dma(vha->host, &fc_vport->dev,
+ &ha->pdev->dev)) {
DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n",
vha->host_no, vha->vp_idx));
goto vport_create_failed_2;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index cca8e4ab0372..cb2eca4c26d8 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -377,6 +377,24 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
return ptr + sizeof(struct qla2xxx_mq_chain);
}
+static void
+qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
+{
+ struct qla_hw_data *ha = vha->hw;
+
+ if (rval != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "Failed to dump firmware (%x)!!!\n", rval);
+ ha->fw_dumped = 0;
+ } else {
+ qla_printk(KERN_INFO, ha,
+ "Firmware dump saved to temp buffer (%ld/%p).\n",
+ vha->host_no, ha->fw_dump);
+ ha->fw_dumped = 1;
+ qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
+ }
+}
+
/**
* qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
* @ha: HA context
@@ -530,17 +548,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
if (rval == QLA_SUCCESS)
qla2xxx_copy_queues(ha, nxt);
- if (rval != QLA_SUCCESS) {
- qla_printk(KERN_WARNING, ha,
- "Failed to dump firmware (%x)!!!\n", rval);
- ha->fw_dumped = 0;
-
- } else {
- qla_printk(KERN_INFO, ha,
- "Firmware dump saved to temp buffer (%ld/%p).\n",
- base_vha->host_no, ha->fw_dump);
- ha->fw_dumped = 1;
- }
+ qla2xxx_dump_post_process(base_vha, rval);
qla2300_fw_dump_failed:
if (!hardware_locked)
@@ -737,17 +745,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
if (rval == QLA_SUCCESS)
qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
- if (rval != QLA_SUCCESS) {
- qla_printk(KERN_WARNING, ha,
- "Failed to dump firmware (%x)!!!\n", rval);
- ha->fw_dumped = 0;
-
- } else {
- qla_printk(KERN_INFO, ha,
- "Firmware dump saved to temp buffer (%ld/%p).\n",
- base_vha->host_no, ha->fw_dump);
- ha->fw_dumped = 1;
- }
+ qla2xxx_dump_post_process(base_vha, rval);
qla2100_fw_dump_failed:
if (!hardware_locked)
@@ -984,17 +982,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
qla24xx_copy_eft(ha, nxt);
qla24xx_fw_dump_failed_0:
- if (rval != QLA_SUCCESS) {
- qla_printk(KERN_WARNING, ha,
- "Failed to dump firmware (%x)!!!\n", rval);
- ha->fw_dumped = 0;
-
- } else {
- qla_printk(KERN_INFO, ha,
- "Firmware dump saved to temp buffer (%ld/%p).\n",
- base_vha->host_no, ha->fw_dump);
- ha->fw_dumped = 1;
- }
+ qla2xxx_dump_post_process(base_vha, rval);
qla24xx_fw_dump_failed:
if (!hardware_locked)
@@ -1305,17 +1293,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
}
qla25xx_fw_dump_failed_0:
- if (rval != QLA_SUCCESS) {
- qla_printk(KERN_WARNING, ha,
- "Failed to dump firmware (%x)!!!\n", rval);
- ha->fw_dumped = 0;
-
- } else {
- qla_printk(KERN_INFO, ha,
- "Firmware dump saved to temp buffer (%ld/%p).\n",
- base_vha->host_no, ha->fw_dump);
- ha->fw_dumped = 1;
- }
+ qla2xxx_dump_post_process(base_vha, rval);
qla25xx_fw_dump_failed:
if (!hardware_locked)
@@ -1628,17 +1606,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
}
qla81xx_fw_dump_failed_0:
- if (rval != QLA_SUCCESS) {
- qla_printk(KERN_WARNING, ha,
- "Failed to dump firmware (%x)!!!\n", rval);
- ha->fw_dumped = 0;
-
- } else {
- qla_printk(KERN_INFO, ha,
- "Firmware dump saved to temp buffer (%ld/%p).\n",
- base_vha->host_no, ha->fw_dump);
- ha->fw_dumped = 1;
- }
+ qla2xxx_dump_post_process(base_vha, rval);
qla81xx_fw_dump_failed:
if (!hardware_locked)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 215061861794..6b9bf23c7735 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2123,6 +2123,7 @@ enum qla_work_type {
QLA_EVT_ASYNC_LOGIN_DONE,
QLA_EVT_ASYNC_LOGOUT,
QLA_EVT_ASYNC_LOGOUT_DONE,
+ QLA_EVT_UEVENT,
};
@@ -2146,6 +2147,10 @@ struct qla_work_evt {
#define QLA_LOGIO_LOGIN_RETRIED BIT_0
u16 data[2];
} logio;
+ struct {
+ u32 code;
+#define QLA_UEVENT_CODE_FW_DUMP 0
+ } uevent;
} u;
};
@@ -2435,11 +2440,11 @@ struct qla_hw_data {
dma_addr_t edc_data_dma;
uint16_t edc_data_len;
-#define XGMAC_DATA_SIZE PAGE_SIZE
+#define XGMAC_DATA_SIZE 4096
void *xgmac_data;
dma_addr_t xgmac_data_dma;
-#define DCBX_TLV_DATA_SIZE PAGE_SIZE
+#define DCBX_TLV_DATA_SIZE 4096
void *dcbx_tlv;
dma_addr_t dcbx_tlv_dma;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index f3d1d1afa95b..e21851358509 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -92,6 +92,7 @@ extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
fc_port_t *, uint16_t *);
+extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
@@ -246,7 +247,7 @@ qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *);
extern int
qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *,
- uint16_t *, uint16_t *, uint16_t *);
+ uint16_t *, uint16_t *, uint16_t *, uint16_t *);
extern int
qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 9e3eaac25596..b74924b279ef 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -277,7 +277,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
vha->marker_needed = 0;
ha->isp_abort_cnt = 0;
ha->beacon_blink_led = 0;
- set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
set_bit(0, ha->req_qid_map);
set_bit(0, ha->rsp_qid_map);
@@ -1203,7 +1202,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
}
qla2x00_get_resource_cnts(vha, NULL,
&ha->fw_xcb_count, NULL, NULL,
- &ha->max_npiv_vports);
+ &ha->max_npiv_vports, NULL);
if (!fw_major_version && ql2xallocfwdump)
qla2x00_alloc_fw_dump(vha);
@@ -3573,6 +3572,15 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
ha->isp_abort_cnt = 0;
clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
+ if (IS_QLA81XX(ha))
+ qla2x00_get_fw_version(vha,
+ &ha->fw_major_version,
+ &ha->fw_minor_version,
+ &ha->fw_subminor_version,
+ &ha->fw_attributes, &ha->fw_memory_size,
+ ha->mpi_version, &ha->mpi_capabilities,
+ ha->phy_version);
+
if (ha->fce) {
ha->flags.fce_enabled = 1;
memset(ha->fce, 0,
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index b20a7169aac2..804987397b77 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -313,10 +313,11 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
static char *link_speeds[] = { "1", "2", "?", "4", "8", "10" };
char *link_speed;
uint16_t handle_cnt;
- uint16_t cnt;
+ uint16_t cnt, mbx;
uint32_t handles[5];
struct qla_hw_data *ha = vha->hw;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+ struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
uint32_t rscn_entry, host_pid;
uint8_t rscn_queue_index;
unsigned long flags;
@@ -395,9 +396,10 @@ skip_rio:
break;
case MBA_SYSTEM_ERR: /* System Error */
+ mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox7) : 0;
qla_printk(KERN_INFO, ha,
- "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
- mb[1], mb[2], mb[3]);
+ "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh "
+ "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx);
ha->isp_ops->fw_dump(vha, 1);
@@ -419,9 +421,10 @@ skip_rio:
break;
case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
- DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n",
- vha->host_no));
- qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
+ DEBUG2(printk("scsi(%ld): ISP Request Transfer Error (%x).\n",
+ vha->host_no, mb[1]));
+ qla_printk(KERN_WARNING, ha,
+ "ISP Request Transfer Error (%x).\n", mb[1]);
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
break;
@@ -485,10 +488,13 @@ skip_rio:
break;
case MBA_LOOP_DOWN: /* Loop Down Event */
+ mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox4) : 0;
DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN "
- "(%x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3]));
- qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n",
- mb[1], mb[2], mb[3]);
+ "(%x %x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3],
+ mbx));
+ qla_printk(KERN_INFO, ha,
+ "LOOP DOWN detected (%x %x %x %x).\n", mb[1], mb[2], mb[3],
+ mbx);
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
@@ -1347,16 +1353,22 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
sense_len = rsp_info_len = resid_len = fw_resid_len = 0;
if (IS_FWI2_CAPABLE(ha)) {
- sense_len = le32_to_cpu(sts24->sense_len);
- rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
- resid_len = le32_to_cpu(sts24->rsp_residual_count);
- fw_resid_len = le32_to_cpu(sts24->residual_len);
+ if (scsi_status & SS_SENSE_LEN_VALID)
+ sense_len = le32_to_cpu(sts24->sense_len);
+ if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
+ rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
+ if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER))
+ resid_len = le32_to_cpu(sts24->rsp_residual_count);
+ if (comp_status == CS_DATA_UNDERRUN)
+ fw_resid_len = le32_to_cpu(sts24->residual_len);
rsp_info = sts24->data;
sense_data = sts24->data;
host_to_fcp_swap(sts24->data, sizeof(sts24->data));
} else {
- sense_len = le16_to_cpu(sts->req_sense_length);
- rsp_info_len = le16_to_cpu(sts->rsp_info_len);
+ if (scsi_status & SS_SENSE_LEN_VALID)
+ sense_len = le16_to_cpu(sts->req_sense_length);
+ if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
+ rsp_info_len = le16_to_cpu(sts->rsp_info_len);
resid_len = le32_to_cpu(sts->residual_length);
rsp_info = sts->rsp_info;
sense_data = sts->req_sense_data;
@@ -1443,38 +1455,62 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
break;
case CS_DATA_UNDERRUN:
- resid = resid_len;
+ DEBUG2(printk(KERN_INFO
+ "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x. "
+ "resid=0x%x fw_resid=0x%x cdb=0x%x os_underflow=0x%x\n",
+ vha->host_no, cp->device->id, cp->device->lun, comp_status,
+ scsi_status, resid_len, fw_resid_len, cp->cmnd[0],
+ cp->underflow));
+
/* Use F/W calculated residual length. */
- if (IS_FWI2_CAPABLE(ha)) {
- if (!(scsi_status & SS_RESIDUAL_UNDER)) {
- lscsi_status = 0;
- } else if (resid != fw_resid_len) {
- scsi_status &= ~SS_RESIDUAL_UNDER;
- lscsi_status = 0;
+ resid = IS_FWI2_CAPABLE(ha) ? fw_resid_len : resid_len;
+ scsi_set_resid(cp, resid);
+ if (scsi_status & SS_RESIDUAL_UNDER) {
+ if (IS_FWI2_CAPABLE(ha) && fw_resid_len != resid_len) {
+ DEBUG2(printk(
+ "scsi(%ld:%d:%d:%d) Dropped frame(s) "
+ "detected (%x of %x bytes)...residual "
+ "length mismatch...retrying command.\n",
+ vha->host_no, cp->device->channel,
+ cp->device->id, cp->device->lun, resid,
+ scsi_bufflen(cp)));
+
+ cp->result = DID_ERROR << 16 | lscsi_status;
+ break;
}
- resid = fw_resid_len;
- }
- if (scsi_status & SS_RESIDUAL_UNDER) {
- scsi_set_resid(cp, resid);
- } else {
- DEBUG2(printk(KERN_INFO
- "scsi(%ld:%d:%d) UNDERRUN status detected "
- "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x "
- "os_underflow=0x%x\n", vha->host_no,
- cp->device->id, cp->device->lun, comp_status,
- scsi_status, resid_len, resid, cp->cmnd[0],
- cp->underflow));
+ if (!lscsi_status &&
+ ((unsigned)(scsi_bufflen(cp) - resid) <
+ cp->underflow)) {
+ qla_printk(KERN_INFO, ha,
+ "scsi(%ld:%d:%d:%d): Mid-layer underflow "
+ "detected (%x of %x bytes)...returning "
+ "error status.\n", vha->host_no,
+ cp->device->channel, cp->device->id,
+ cp->device->lun, resid, scsi_bufflen(cp));
+
+ cp->result = DID_ERROR << 16;
+ break;
+ }
+ } else if (!lscsi_status) {
+ DEBUG2(printk(
+ "scsi(%ld:%d:%d:%d) Dropped frame(s) detected "
+ "(%x of %x bytes)...firmware reported underrun..."
+ "retrying command.\n", vha->host_no,
+ cp->device->channel, cp->device->id,
+ cp->device->lun, resid, scsi_bufflen(cp)));
+ cp->result = DID_ERROR << 16;
+ break;
}
+ cp->result = DID_OK << 16 | lscsi_status;
+
/*
* Check to see if SCSI Status is non zero. If so report SCSI
* Status.
*/
if (lscsi_status != 0) {
- cp->result = DID_OK << 16 | lscsi_status;
-
if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
DEBUG2(printk(KERN_INFO
"scsi(%ld): QUEUE FULL status detected "
@@ -1501,42 +1537,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
break;
qla2x00_handle_sense(sp, sense_data, sense_len, rsp);
- } else {
- /*
- * If RISC reports underrun and target does not report
- * it then we must have a lost frame, so tell upper
- * layer to retry it by reporting an error.
- */
- if (!(scsi_status & SS_RESIDUAL_UNDER)) {
- DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
- "frame(s) detected (%x of %x bytes)..."
- "retrying command.\n",
- vha->host_no, cp->device->channel,
- cp->device->id, cp->device->lun, resid,
- scsi_bufflen(cp)));
-
- scsi_set_resid(cp, resid);
- cp->result = DID_ERROR << 16;
- break;
- }
-
- /* Handle mid-layer underflow */
- if ((unsigned)(scsi_bufflen(cp) - resid) <
- cp->underflow) {
- qla_printk(KERN_INFO, ha,
- "scsi(%ld:%d:%d:%d): Mid-layer underflow "
- "detected (%x of %x bytes)...returning "
- "error status.\n", vha->host_no,
- cp->device->channel, cp->device->id,
- cp->device->lun, resid,
- scsi_bufflen(cp));
-
- cp->result = DID_ERROR << 16;
- break;
- }
-
- /* Everybody online, looking good... */
- cp->result = DID_OK << 16;
}
break;
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index b6202fe118ac..05d595d9a7ef 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2006,7 +2006,7 @@ qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
int
qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
- uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports)
+ uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
{
int rval;
mbx_cmd_t mc;
@@ -2017,6 +2017,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
mcp->out_mb = MBX_0;
mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ if (IS_QLA81XX(vha->hw))
+ mcp->in_mb |= MBX_12;
mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
@@ -2027,9 +2029,10 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
vha->host_no, mcp->mb[0]));
} else {
DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
- "mb7=%x mb10=%x mb11=%x.\n", __func__, vha->host_no,
- mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7],
- mcp->mb[10], mcp->mb[11]));
+ "mb7=%x mb10=%x mb11=%x mb12=%x.\n", __func__,
+ vha->host_no, mcp->mb[1], mcp->mb[2], mcp->mb[3],
+ mcp->mb[6], mcp->mb[7], mcp->mb[10], mcp->mb[11],
+ mcp->mb[12]));
if (cur_xchg_cnt)
*cur_xchg_cnt = mcp->mb[3];
@@ -2041,6 +2044,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
*orig_iocb_cnt = mcp->mb[10];
if (vha->hw->flags.npiv_supported && max_npiv_vports)
*max_npiv_vports = mcp->mb[11];
+ if (IS_QLA81XX(vha->hw) && max_fcfs)
+ *max_fcfs = mcp->mb[12];
}
return (rval);
@@ -2313,6 +2318,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
{
int rval, rval2;
struct tsk_mgmt_cmd *tsk;
+ struct sts_entry_24xx *sts;
dma_addr_t tsk_dma;
scsi_qla_host_t *vha;
struct qla_hw_data *ha;
@@ -2352,20 +2358,37 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
sizeof(tsk->p.tsk.lun));
}
+ sts = &tsk->p.sts;
rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
if (rval != QLA_SUCCESS) {
DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB "
"(%x).\n", __func__, vha->host_no, name, rval));
- } else if (tsk->p.sts.entry_status != 0) {
+ } else if (sts->entry_status != 0) {
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
"-- error status (%x).\n", __func__, vha->host_no,
- tsk->p.sts.entry_status));
+ sts->entry_status));
rval = QLA_FUNCTION_FAILED;
- } else if (tsk->p.sts.comp_status !=
+ } else if (sts->comp_status !=
__constant_cpu_to_le16(CS_COMPLETE)) {
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
"-- completion status (%x).\n", __func__,
- vha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
+ vha->host_no, le16_to_cpu(sts->comp_status)));
+ rval = QLA_FUNCTION_FAILED;
+ } else if (!(le16_to_cpu(sts->scsi_status) &
+ SS_RESPONSE_INFO_LEN_VALID)) {
+ DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+ "-- no response info (%x).\n", __func__, vha->host_no,
+ le16_to_cpu(sts->scsi_status)));
+ rval = QLA_FUNCTION_FAILED;
+ } else if (le32_to_cpu(sts->rsp_data_len) < 4) {
+ DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+ "-- not enough response info (%d).\n", __func__,
+ vha->host_no, le32_to_cpu(sts->rsp_data_len)));
+ rval = QLA_FUNCTION_FAILED;
+ } else if (sts->data[3]) {
+ DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+ "-- response (%x).\n", __func__,
+ vha->host_no, sts->data[3]));
rval = QLA_FUNCTION_FAILED;
}
@@ -2759,8 +2782,10 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
vp_idx, MSB(stat),
rptid_entry->port_id[2], rptid_entry->port_id[1],
rptid_entry->port_id[0]));
- if (vp_idx == 0)
- return;
+
+ vp = vha;
+ if (vp_idx == 0 && (MSB(stat) != 1))
+ goto reg_needed;
if (MSB(stat) == 1) {
DEBUG2(printk("scsi(%ld): Could not acquire ID for "
@@ -2783,8 +2808,11 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
* response queue. Handle it in dpc context.
*/
set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
- set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
+reg_needed:
+ set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
+ set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
+ set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
}
}
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index e07b3617f019..a47d34308a3a 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -382,8 +382,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
vha->dpc_flags = 0L;
- set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
- set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
/*
* To fix the issue of processing a parent's RSCN for the vport before
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index b79fca7d461b..41669357b186 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -11,6 +11,7 @@
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
+#include <linux/kobject.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
@@ -137,7 +138,7 @@ static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
-static int qla2x00_change_queue_depth(struct scsi_device *, int);
+static int qla2x00_change_queue_depth(struct scsi_device *, int, int);
static int qla2x00_change_queue_type(struct scsi_device *, int);
struct scsi_host_template qla2xxx_driver_template = {
@@ -727,23 +728,6 @@ qla2x00_abort_fcport_cmds(fc_port_t *fcport)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
-static void
-qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
-{
- struct Scsi_Host *shost = cmnd->device->host;
- struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
- unsigned long flags;
-
- spin_lock_irqsave(shost->host_lock, flags);
- while (rport->port_state == FC_PORTSTATE_BLOCKED) {
- spin_unlock_irqrestore(shost->host_lock, flags);
- msleep(1000);
- spin_lock_irqsave(shost->host_lock, flags);
- }
- spin_unlock_irqrestore(shost->host_lock, flags);
- return;
-}
-
/**************************************************************************
* qla2xxx_eh_abort
*
@@ -773,7 +757,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
struct req_que *req = vha->req;
srb_t *spt;
- qla2x00_block_error_handler(cmd);
+ fc_block_scsi_eh(cmd);
if (!CMD_SP(cmd))
return SUCCESS;
@@ -904,7 +888,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
int err;
- qla2x00_block_error_handler(cmd);
+ fc_block_scsi_eh(cmd);
if (!fcport)
return FAILED;
@@ -984,7 +968,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
unsigned long serial;
srb_t *sp = (srb_t *) CMD_SP(cmd);
- qla2x00_block_error_handler(cmd);
+ fc_block_scsi_eh(cmd);
id = cmd->device->id;
lun = cmd->device->lun;
@@ -1047,7 +1031,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
srb_t *sp = (srb_t *) CMD_SP(cmd);
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
- qla2x00_block_error_handler(cmd);
+ fc_block_scsi_eh(cmd);
id = cmd->device->id;
lun = cmd->device->lun;
@@ -1234,8 +1218,11 @@ qla2xxx_slave_destroy(struct scsi_device *sdev)
}
static int
-qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth)
+qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
{
+ if (reason != SCSI_QDEPTH_DEFAULT)
+ return -EOPNOTSUPP;
+
scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
return sdev->queue_depth;
}
@@ -2653,6 +2640,37 @@ qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE);
qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
+int
+qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code)
+{
+ struct qla_work_evt *e;
+
+ e = qla2x00_alloc_work(vha, QLA_EVT_UEVENT);
+ if (!e)
+ return QLA_FUNCTION_FAILED;
+
+ e->u.uevent.code = code;
+ return qla2x00_post_work(vha, e);
+}
+
+static void
+qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code)
+{
+ char event_string[40];
+ char *envp[] = { event_string, NULL };
+
+ switch (code) {
+ case QLA_UEVENT_CODE_FW_DUMP:
+ snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld",
+ vha->host_no);
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ kobject_uevent_env(&vha->hw->pdev->dev.kobj, KOBJ_CHANGE, envp);
+}
+
void
qla2x00_do_work(struct scsi_qla_host *vha)
{
@@ -2690,6 +2708,9 @@ qla2x00_do_work(struct scsi_qla_host *vha)
qla2x00_async_logout_done(vha, e->u.logio.fcport,
e->u.logio.data);
break;
+ case QLA_EVT_UEVENT:
+ qla2x00_uevent_emit(vha, e->u.uevent.code);
+ break;
}
if (e->flags & QLA_EVT_FLAG_FREE)
kfree(e);
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index ac107a2c34a4..807e0dbc67fa 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.01-k6"
+#define QLA2XXX_VERSION "8.03.01-k7"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3