diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2010-07-23 06:28:27 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-28 10:06:10 -0400 |
commit | 5544213be7b4fb693730106a6d70a8cc1aa7cdf6 (patch) | |
tree | dce08f8b11c2a8a35ccbc929b269de1a228bc14a /drivers | |
parent | 0f2d962f4d120e93b4d74d13c2e8038e9e4358b9 (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')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 27 |
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 | ||
1322 | static inline void | 1322 | static inline void |
1323 | qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len, | 1323 | |
1324 | struct rsp_que *rsp) | 1324 | qla2x00_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 | ||