diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 120 |
1 files changed, 54 insertions, 66 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1104bd2eed40..642a0c3f09c6 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -104,7 +104,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
104 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 104 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
105 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 105 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
106 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 106 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
107 | up(&ha->mbx_intr_sem); | 107 | complete(&ha->mbx_intr_comp); |
108 | } | 108 | } |
109 | 109 | ||
110 | return (IRQ_HANDLED); | 110 | return (IRQ_HANDLED); |
@@ -216,7 +216,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
216 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 216 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
217 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 217 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
218 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 218 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
219 | up(&ha->mbx_intr_sem); | 219 | complete(&ha->mbx_intr_comp); |
220 | } | 220 | } |
221 | 221 | ||
222 | return (IRQ_HANDLED); | 222 | return (IRQ_HANDLED); |
@@ -347,10 +347,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
347 | break; | 347 | break; |
348 | 348 | ||
349 | case MBA_SYSTEM_ERR: /* System Error */ | 349 | case MBA_SYSTEM_ERR: /* System Error */ |
350 | mb[1] = RD_MAILBOX_REG(ha, reg, 1); | ||
351 | mb[2] = RD_MAILBOX_REG(ha, reg, 2); | ||
352 | mb[3] = RD_MAILBOX_REG(ha, reg, 3); | ||
353 | |||
354 | qla_printk(KERN_INFO, ha, | 350 | qla_printk(KERN_INFO, ha, |
355 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", | 351 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", |
356 | mb[1], mb[2], mb[3]); | 352 | mb[1], mb[2], mb[3]); |
@@ -579,12 +575,15 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
579 | /* Check if the Vport has issued a SCR */ | 575 | /* Check if the Vport has issued a SCR */ |
580 | if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) | 576 | if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) |
581 | break; | 577 | break; |
578 | /* Only handle SCNs for our Vport index. */ | ||
579 | if (ha->flags.npiv_supported && ha->vp_idx != mb[3]) | ||
580 | break; | ||
582 | 581 | ||
583 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", | 582 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", |
584 | ha->host_no)); | 583 | ha->host_no)); |
585 | DEBUG(printk(KERN_INFO | 584 | DEBUG(printk(KERN_INFO |
586 | "scsi(%ld): RSCN database changed -- %04x %04x.\n", | 585 | "scsi(%ld): RSCN database changed -- %04x %04x %04x.\n", |
587 | ha->host_no, mb[1], mb[2])); | 586 | ha->host_no, mb[1], mb[2], mb[3])); |
588 | 587 | ||
589 | rscn_entry = (mb[1] << 16) | mb[2]; | 588 | rscn_entry = (mb[1] << 16) | mb[2]; |
590 | host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) | | 589 | host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) | |
@@ -823,6 +822,35 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha) | |||
823 | WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), ha->rsp_ring_index); | 822 | WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), ha->rsp_ring_index); |
824 | } | 823 | } |
825 | 824 | ||
825 | static inline void | ||
826 | qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len) | ||
827 | { | ||
828 | struct scsi_cmnd *cp = sp->cmd; | ||
829 | |||
830 | if (sense_len >= SCSI_SENSE_BUFFERSIZE) | ||
831 | sense_len = SCSI_SENSE_BUFFERSIZE; | ||
832 | |||
833 | CMD_ACTUAL_SNSLEN(cp) = sense_len; | ||
834 | sp->request_sense_length = sense_len; | ||
835 | sp->request_sense_ptr = cp->sense_buffer; | ||
836 | if (sp->request_sense_length > 32) | ||
837 | sense_len = 32; | ||
838 | |||
839 | memcpy(cp->sense_buffer, sense_data, sense_len); | ||
840 | |||
841 | sp->request_sense_ptr += sense_len; | ||
842 | sp->request_sense_length -= sense_len; | ||
843 | if (sp->request_sense_length != 0) | ||
844 | sp->ha->status_srb = sp; | ||
845 | |||
846 | DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) " | ||
847 | "cmd=%p pid=%ld\n", __func__, sp->ha->host_no, cp->device->channel, | ||
848 | cp->device->id, cp->device->lun, cp, cp->serial_number)); | ||
849 | if (sense_len) | ||
850 | DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, | ||
851 | CMD_ACTUAL_SNSLEN(cp))); | ||
852 | } | ||
853 | |||
826 | /** | 854 | /** |
827 | * qla2x00_status_entry() - Process a Status IOCB entry. | 855 | * qla2x00_status_entry() - Process a Status IOCB entry. |
828 | * @ha: SCSI driver HA context | 856 | * @ha: SCSI driver HA context |
@@ -977,36 +1005,11 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
977 | if (lscsi_status != SS_CHECK_CONDITION) | 1005 | if (lscsi_status != SS_CHECK_CONDITION) |
978 | break; | 1006 | break; |
979 | 1007 | ||
980 | /* Copy Sense Data into sense buffer. */ | 1008 | memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
981 | memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer)); | ||
982 | |||
983 | if (!(scsi_status & SS_SENSE_LEN_VALID)) | 1009 | if (!(scsi_status & SS_SENSE_LEN_VALID)) |
984 | break; | 1010 | break; |
985 | 1011 | ||
986 | if (sense_len >= sizeof(cp->sense_buffer)) | 1012 | qla2x00_handle_sense(sp, sense_data, sense_len); |
987 | sense_len = sizeof(cp->sense_buffer); | ||
988 | |||
989 | CMD_ACTUAL_SNSLEN(cp) = sense_len; | ||
990 | sp->request_sense_length = sense_len; | ||
991 | sp->request_sense_ptr = cp->sense_buffer; | ||
992 | |||
993 | if (sp->request_sense_length > 32) | ||
994 | sense_len = 32; | ||
995 | |||
996 | memcpy(cp->sense_buffer, sense_data, sense_len); | ||
997 | |||
998 | sp->request_sense_ptr += sense_len; | ||
999 | sp->request_sense_length -= sense_len; | ||
1000 | if (sp->request_sense_length != 0) | ||
1001 | ha->status_srb = sp; | ||
1002 | |||
1003 | DEBUG5(printk("%s(): Check condition Sense data, " | ||
1004 | "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", __func__, | ||
1005 | ha->host_no, cp->device->channel, cp->device->id, | ||
1006 | cp->device->lun, cp, cp->serial_number)); | ||
1007 | if (sense_len) | ||
1008 | DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, | ||
1009 | CMD_ACTUAL_SNSLEN(cp))); | ||
1010 | break; | 1013 | break; |
1011 | 1014 | ||
1012 | case CS_DATA_UNDERRUN: | 1015 | case CS_DATA_UNDERRUN: |
@@ -1061,34 +1064,11 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1061 | if (lscsi_status != SS_CHECK_CONDITION) | 1064 | if (lscsi_status != SS_CHECK_CONDITION) |
1062 | break; | 1065 | break; |
1063 | 1066 | ||
1064 | /* Copy Sense Data into sense buffer */ | 1067 | memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
1065 | memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer)); | ||
1066 | |||
1067 | if (!(scsi_status & SS_SENSE_LEN_VALID)) | 1068 | if (!(scsi_status & SS_SENSE_LEN_VALID)) |
1068 | break; | 1069 | break; |
1069 | 1070 | ||
1070 | if (sense_len >= sizeof(cp->sense_buffer)) | 1071 | qla2x00_handle_sense(sp, sense_data, sense_len); |
1071 | sense_len = sizeof(cp->sense_buffer); | ||
1072 | |||
1073 | CMD_ACTUAL_SNSLEN(cp) = sense_len; | ||
1074 | sp->request_sense_length = sense_len; | ||
1075 | sp->request_sense_ptr = cp->sense_buffer; | ||
1076 | |||
1077 | if (sp->request_sense_length > 32) | ||
1078 | sense_len = 32; | ||
1079 | |||
1080 | memcpy(cp->sense_buffer, sense_data, sense_len); | ||
1081 | |||
1082 | sp->request_sense_ptr += sense_len; | ||
1083 | sp->request_sense_length -= sense_len; | ||
1084 | if (sp->request_sense_length != 0) | ||
1085 | ha->status_srb = sp; | ||
1086 | |||
1087 | DEBUG5(printk("%s(): Check condition Sense data, " | ||
1088 | "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", | ||
1089 | __func__, ha->host_no, cp->device->channel, | ||
1090 | cp->device->id, cp->device->lun, cp, | ||
1091 | cp->serial_number)); | ||
1092 | 1072 | ||
1093 | /* | 1073 | /* |
1094 | * In case of a Underrun condition, set both the lscsi | 1074 | * In case of a Underrun condition, set both the lscsi |
@@ -1108,10 +1088,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1108 | 1088 | ||
1109 | cp->result = DID_ERROR << 16 | lscsi_status; | 1089 | cp->result = DID_ERROR << 16 | lscsi_status; |
1110 | } | 1090 | } |
1111 | |||
1112 | if (sense_len) | ||
1113 | DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, | ||
1114 | CMD_ACTUAL_SNSLEN(cp))); | ||
1115 | } else { | 1091 | } else { |
1116 | /* | 1092 | /* |
1117 | * If RISC reports underrun and target does not report | 1093 | * If RISC reports underrun and target does not report |
@@ -1621,7 +1597,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1621 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1597 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1622 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1598 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
1623 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 1599 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
1624 | up(&ha->mbx_intr_sem); | 1600 | complete(&ha->mbx_intr_comp); |
1625 | } | 1601 | } |
1626 | 1602 | ||
1627 | return IRQ_HANDLED; | 1603 | return IRQ_HANDLED; |
@@ -1758,7 +1734,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1758 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1734 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1759 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1735 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
1760 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 1736 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
1761 | up(&ha->mbx_intr_sem); | 1737 | complete(&ha->mbx_intr_comp); |
1762 | } | 1738 | } |
1763 | 1739 | ||
1764 | return IRQ_HANDLED; | 1740 | return IRQ_HANDLED; |
@@ -1853,6 +1829,18 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1853 | goto skip_msix; | 1829 | goto skip_msix; |
1854 | } | 1830 | } |
1855 | 1831 | ||
1832 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && | ||
1833 | (ha->pdev->subsystem_device == 0x7040 || | ||
1834 | ha->pdev->subsystem_device == 0x7041 || | ||
1835 | ha->pdev->subsystem_device == 0x1705)) { | ||
1836 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
1837 | "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X, 0x%X).\n", | ||
1838 | ha->pdev->subsystem_vendor, | ||
1839 | ha->pdev->subsystem_device)); | ||
1840 | |||
1841 | goto skip_msi; | ||
1842 | } | ||
1843 | |||
1856 | ret = qla24xx_enable_msix(ha); | 1844 | ret = qla24xx_enable_msix(ha); |
1857 | if (!ret) { | 1845 | if (!ret) { |
1858 | DEBUG2(qla_printk(KERN_INFO, ha, | 1846 | DEBUG2(qla_printk(KERN_INFO, ha, |