aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_isr.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2010-07-23 06:28:27 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 10:06:10 -0400
commit5544213be7b4fb693730106a6d70a8cc1aa7cdf6 (patch)
treedce08f8b11c2a8a35ccbc929b269de1a228bc14a /drivers/scsi/qla2xxx/qla_isr.c
parent0f2d962f4d120e93b4d74d13c2e8038e9e4358b9 (diff)
[SCSI] qla2xxx: Correct extended sense-data handling.
Earlier implementation did not take into account the varying sizes of data buffers returned from structures sts_entry_t and sts_entry_24xx. Sense-data after the 20th byte could be incorrect. Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index ba971ac1c4e8..88b5774085ad 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1320,8 +1320,9 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
1320} 1320}
1321 1321
1322static inline void 1322static inline void
1323qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len, 1323
1324 struct rsp_que *rsp) 1324qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
1325 uint32_t sense_len, struct rsp_que *rsp)
1325{ 1326{
1326 struct scsi_cmnd *cp = sp->cmd; 1327 struct scsi_cmnd *cp = sp->cmd;
1327 1328
@@ -1330,8 +1331,8 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len,
1330 1331
1331 sp->request_sense_length = sense_len; 1332 sp->request_sense_length = sense_len;
1332 sp->request_sense_ptr = cp->sense_buffer; 1333 sp->request_sense_ptr = cp->sense_buffer;
1333 if (sp->request_sense_length > 32) 1334 if (sp->request_sense_length > par_sense_len)
1334 sense_len = 32; 1335 sense_len = par_sense_len;
1335 1336
1336 memcpy(cp->sense_buffer, sense_data, sense_len); 1337 memcpy(cp->sense_buffer, sense_data, sense_len);
1337 1338
@@ -1438,7 +1439,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1438 uint16_t ox_id; 1439 uint16_t ox_id;
1439 uint8_t lscsi_status; 1440 uint8_t lscsi_status;
1440 int32_t resid; 1441 int32_t resid;
1441 uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len; 1442 uint32_t sense_len, par_sense_len, rsp_info_len, resid_len,
1443 fw_resid_len;
1442 uint8_t *rsp_info, *sense_data; 1444 uint8_t *rsp_info, *sense_data;
1443 struct qla_hw_data *ha = vha->hw; 1445 struct qla_hw_data *ha = vha->hw;
1444 uint32_t handle; 1446 uint32_t handle;
@@ -1496,7 +1498,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1496 fcport = sp->fcport; 1498 fcport = sp->fcport;
1497 1499
1498 ox_id = 0; 1500 ox_id = 0;
1499 sense_len = rsp_info_len = resid_len = fw_resid_len = 0; 1501 sense_len = par_sense_len = rsp_info_len = resid_len =
1502 fw_resid_len = 0;
1500 if (IS_FWI2_CAPABLE(ha)) { 1503 if (IS_FWI2_CAPABLE(ha)) {
1501 if (scsi_status & SS_SENSE_LEN_VALID) 1504 if (scsi_status & SS_SENSE_LEN_VALID)
1502 sense_len = le32_to_cpu(sts24->sense_len); 1505 sense_len = le32_to_cpu(sts24->sense_len);
@@ -1510,6 +1513,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1510 sense_data = sts24->data; 1513 sense_data = sts24->data;
1511 host_to_fcp_swap(sts24->data, sizeof(sts24->data)); 1514 host_to_fcp_swap(sts24->data, sizeof(sts24->data));
1512 ox_id = le16_to_cpu(sts24->ox_id); 1515 ox_id = le16_to_cpu(sts24->ox_id);
1516 par_sense_len = sizeof(sts24->data);
1513 } else { 1517 } else {
1514 if (scsi_status & SS_SENSE_LEN_VALID) 1518 if (scsi_status & SS_SENSE_LEN_VALID)
1515 sense_len = le16_to_cpu(sts->req_sense_length); 1519 sense_len = le16_to_cpu(sts->req_sense_length);
@@ -1518,13 +1522,16 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1518 resid_len = le32_to_cpu(sts->residual_length); 1522 resid_len = le32_to_cpu(sts->residual_length);
1519 rsp_info = sts->rsp_info; 1523 rsp_info = sts->rsp_info;
1520 sense_data = sts->req_sense_data; 1524 sense_data = sts->req_sense_data;
1525 par_sense_len = sizeof(sts->req_sense_data);
1521 } 1526 }
1522 1527
1523 /* Check for any FCP transport errors. */ 1528 /* Check for any FCP transport errors. */
1524 if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) { 1529 if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
1525 /* Sense data lies beyond any FCP RESPONSE data. */ 1530 /* Sense data lies beyond any FCP RESPONSE data. */
1526 if (IS_FWI2_CAPABLE(ha)) 1531 if (IS_FWI2_CAPABLE(ha)) {
1527 sense_data += rsp_info_len; 1532 sense_data += rsp_info_len;
1533 par_sense_len -= rsp_info_len;
1534 }
1528 if (rsp_info_len > 3 && rsp_info[3]) { 1535 if (rsp_info_len > 3 && rsp_info[3]) {
1529 DEBUG2(qla_printk(KERN_INFO, ha, 1536 DEBUG2(qla_printk(KERN_INFO, ha,
1530 "scsi(%ld:%d:%d): FCP I/O protocol failure " 1537 "scsi(%ld:%d:%d): FCP I/O protocol failure "
@@ -1584,7 +1591,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1584 if (!(scsi_status & SS_SENSE_LEN_VALID)) 1591 if (!(scsi_status & SS_SENSE_LEN_VALID))
1585 break; 1592 break;
1586 1593
1587 qla2x00_handle_sense(sp, sense_data, sense_len, rsp); 1594 qla2x00_handle_sense(sp, sense_data, par_sense_len, sense_len,
1595 rsp);
1588 break; 1596 break;
1589 1597
1590 case CS_DATA_UNDERRUN: 1598 case CS_DATA_UNDERRUN:
@@ -1648,7 +1656,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1648 if (!(scsi_status & SS_SENSE_LEN_VALID)) 1656 if (!(scsi_status & SS_SENSE_LEN_VALID))
1649 break; 1657 break;
1650 1658
1651 qla2x00_handle_sense(sp, sense_data, sense_len, rsp); 1659 qla2x00_handle_sense(sp, sense_data, par_sense_len,
1660 sense_len, rsp);
1652 } 1661 }
1653 break; 1662 break;
1654 1663