[SCSI] qla2xxx: Use FW calculated residual count for underrun handling.
authorRavi Anand <ravi.anand@qlogic.com>
Wed, 17 May 2006 22:08:55 +0000 (15:08 -0700)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Sat, 20 May 2006 14:41:02 +0000 (09:41 -0500)
With ISP24XX and ISP54XX parts.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_isr.c

index 1ee58ad2f4ddc0a1729def96f0c2a538c799a35a..d2f5870628da6d2d76328ad906e316131fa3937e 100644 (file)
@@ -463,7 +463,7 @@ struct sts_entry_24xx {
        uint16_t comp_status;           /* Completion status. */
        uint16_t ox_id;                 /* OX_ID used by the firmware. */
 
-       uint32_t residual_len;          /* Residual transfer length. */
+       uint32_t residual_len;          /* FW calc residual transfer length. */
 
        uint16_t reserved_1;
        uint16_t state_flags;           /* State flags. */
index 2003dbb705793856f0df2b4721a419fd73d495f8..40325ec70056d6992aff4525b2581e598d07df00 100644 (file)
@@ -805,7 +805,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
        uint16_t        scsi_status;
        uint8_t         lscsi_status;
        int32_t         resid;
-       uint32_t        sense_len, rsp_info_len, resid_len;
+       uint32_t        sense_len, rsp_info_len, resid_len, fw_resid_len;
        uint8_t         *rsp_info, *sense_data;
 
        sts = (sts_entry_t *) pkt;
@@ -859,11 +859,12 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
 
        fcport = sp->fcport;
 
-       sense_len = rsp_info_len = resid_len = 0;
+       sense_len = rsp_info_len = resid_len = fw_resid_len = 0;
        if (IS_QLA24XX(ha) || IS_QLA54XX(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);
                rsp_info = sts24->data;
                sense_data = sts24->data;
                host_to_fcp_swap(sts24->data, sizeof(sts24->data));
@@ -963,14 +964,21 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
 
        case CS_DATA_UNDERRUN:
                resid = resid_len;
+               /* Use F/W calculated residual length. */
+               if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+                       resid = fw_resid_len;
+
                if (scsi_status & SS_RESIDUAL_UNDER) {
                        cp->resid = resid;
                        CMD_RESID_LEN(cp) = resid;
                } else {
                        DEBUG2(printk(KERN_INFO
                            "scsi(%ld:%d:%d) UNDERRUN status detected "
-                           "0x%x-0x%x.\n", ha->host_no, cp->device->id,
-                           cp->device->lun, comp_status, scsi_status));
+                           "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x "
+                           "os_underflow=0x%x\n", ha->host_no,
+                           cp->device->id, cp->device->lun, comp_status,
+                           scsi_status, resid_len, resid, cp->cmnd[0],
+                           cp->underflow));
 
                }