diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 20:34:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 20:34:15 -0400 |
commit | c70b5296e775cde46cfcb2d860ba160108a5ec7a (patch) | |
tree | 30419cb982acca44499236adcca65f2f87698c74 /drivers/scsi/qla2xxx | |
parent | 80c226fbef56576946c9655fcb2ab62e63404d12 (diff) | |
parent | 58ff4bd042adf8013c8f70fd03c2c0f8d022e387 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (84 commits)
[SCSI] be2iscsi: SGE Len == 64K
[SCSI] be2iscsi: Remove premature free of cid
[SCSI] be2iscsi: More time for FW
[SCSI] libsas: fix bug for vacant phy
[SCSI] sd: Fix overflow with big physical blocks
[SCSI] st: add MTWEOFI to write filemarks without flushing drive buffer
[SCSI] libsas: Don't issue commands to devices that have been hot-removed
[SCSI] megaraid_sas: Add Online Controller Reset to MegaRAID SAS drive
[SCSI] lpfc 8.3.17: Update lpfc driver version to 8.3.17
[SCSI] lpfc 8.3.17: Replace function reset methodology
[SCSI] lpfc 8.3.17: SCSI fixes
[SCSI] lpfc 8.3.17: BSG fixes
[SCSI] lpfc 8.3.17: SLI Additions and Fixes
[SCSI] lpfc 8.3.17: Code Cleanup and Locking fixes
[SCSI] zfcp: Remove scsi_cmnd->serial_number from debug traces
[SCSI] ipr: fix array error logging
[SCSI] aha152x: enable PCMCIA on 64bit
[SCSI] scsi_dh_alua: Handle all states correctly
[SCSI] cxgb4i: connection and ddp setting update
[SCSI] cxgb3i: fixed connection over vlan
...
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 30 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.c | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 8 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 15 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 54 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 8 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 66 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.c | 431 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.h | 5 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 156 |
10 files changed, 535 insertions, 245 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 114bc5a81171..2ff4342ae362 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1538,22 +1538,22 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
1538 | if (!fcport) | 1538 | if (!fcport) |
1539 | return; | 1539 | return; |
1540 | 1540 | ||
1541 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) | ||
1542 | return; | ||
1543 | |||
1544 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { | ||
1545 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); | ||
1546 | return; | ||
1547 | } | ||
1548 | |||
1549 | /* | 1541 | /* |
1550 | * Transport has effectively 'deleted' the rport, clear | 1542 | * Transport has effectively 'deleted' the rport, clear |
1551 | * all local references. | 1543 | * all local references. |
1552 | */ | 1544 | */ |
1553 | spin_lock_irq(host->host_lock); | 1545 | spin_lock_irq(host->host_lock); |
1554 | fcport->rport = NULL; | 1546 | fcport->rport = fcport->drport = NULL; |
1555 | *((fc_port_t **)rport->dd_data) = NULL; | 1547 | *((fc_port_t **)rport->dd_data) = NULL; |
1556 | spin_unlock_irq(host->host_lock); | 1548 | spin_unlock_irq(host->host_lock); |
1549 | |||
1550 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) | ||
1551 | return; | ||
1552 | |||
1553 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { | ||
1554 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); | ||
1555 | return; | ||
1556 | } | ||
1557 | } | 1557 | } |
1558 | 1558 | ||
1559 | static void | 1559 | static void |
@@ -1676,14 +1676,14 @@ static void | |||
1676 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) | 1676 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) |
1677 | { | 1677 | { |
1678 | scsi_qla_host_t *vha = shost_priv(shost); | 1678 | scsi_qla_host_t *vha = shost_priv(shost); |
1679 | u64 node_name; | 1679 | uint8_t node_name[WWN_SIZE] = { 0xFF, 0xFF, 0xFF, 0xFF, \ |
1680 | 0xFF, 0xFF, 0xFF, 0xFF}; | ||
1681 | u64 fabric_name = wwn_to_u64(node_name); | ||
1680 | 1682 | ||
1681 | if (vha->device_flags & SWITCH_FOUND) | 1683 | if (vha->device_flags & SWITCH_FOUND) |
1682 | node_name = wwn_to_u64(vha->fabric_node_name); | 1684 | fabric_name = wwn_to_u64(vha->fabric_node_name); |
1683 | else | ||
1684 | node_name = wwn_to_u64(vha->node_name); | ||
1685 | 1685 | ||
1686 | fc_host_fabric_name(shost) = node_name; | 1686 | fc_host_fabric_name(shost) = fabric_name; |
1687 | } | 1687 | } |
1688 | 1688 | ||
1689 | static void | 1689 | static void |
@@ -1776,6 +1776,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | |||
1776 | } | 1776 | } |
1777 | 1777 | ||
1778 | /* initialize attributes */ | 1778 | /* initialize attributes */ |
1779 | fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count; | ||
1779 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); | 1780 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); |
1780 | fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); | 1781 | fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); |
1781 | fc_host_supported_classes(vha->host) = | 1782 | fc_host_supported_classes(vha->host) = |
@@ -1984,6 +1985,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha) | |||
1984 | struct qla_hw_data *ha = vha->hw; | 1985 | struct qla_hw_data *ha = vha->hw; |
1985 | u32 speed = FC_PORTSPEED_UNKNOWN; | 1986 | u32 speed = FC_PORTSPEED_UNKNOWN; |
1986 | 1987 | ||
1988 | fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count; | ||
1987 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); | 1989 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); |
1988 | fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); | 1990 | fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); |
1989 | fc_host_supported_classes(vha->host) = FC_COS_CLASS3; | 1991 | fc_host_supported_classes(vha->host) = FC_COS_CLASS3; |
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 9067629817ea..fdfbf83a6330 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c | |||
@@ -1254,10 +1254,9 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job) | |||
1254 | return -EINVAL; | 1254 | return -EINVAL; |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | if (fcport->loop_id == FC_NO_LOOP_ID) { | 1257 | if (atomic_read(&fcport->state) != FCS_ONLINE) { |
1258 | DEBUG2(printk(KERN_ERR "%s(%ld): Invalid port loop id, " | 1258 | DEBUG2(printk(KERN_ERR "%s(%ld): Port not online\n", |
1259 | "loop_id = 0x%x\n", | 1259 | __func__, vha->host_no)); |
1260 | __func__, vha->host_no, fcport->loop_id)); | ||
1261 | return -EINVAL; | 1260 | return -EINVAL; |
1262 | } | 1261 | } |
1263 | 1262 | ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index d2a4e1530708..e1d3ad40a946 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -706,6 +706,11 @@ typedef struct { | |||
706 | #define MBC_SET_PORT_CONFIG 0x122 /* Set port configuration */ | 706 | #define MBC_SET_PORT_CONFIG 0x122 /* Set port configuration */ |
707 | #define MBC_GET_PORT_CONFIG 0x123 /* Get port configuration */ | 707 | #define MBC_GET_PORT_CONFIG 0x123 /* Get port configuration */ |
708 | 708 | ||
709 | /* | ||
710 | * ISP81xx mailbox commands | ||
711 | */ | ||
712 | #define MBC_WRITE_MPI_REGISTER 0x01 /* Write MPI Register. */ | ||
713 | |||
709 | /* Firmware return data sizes */ | 714 | /* Firmware return data sizes */ |
710 | #define FCAL_MAP_SIZE 128 | 715 | #define FCAL_MAP_SIZE 128 |
711 | 716 | ||
@@ -2860,6 +2865,7 @@ typedef struct scsi_qla_host { | |||
2860 | #define NPIV_CONFIG_NEEDED 16 | 2865 | #define NPIV_CONFIG_NEEDED 16 |
2861 | #define ISP_UNRECOVERABLE 17 | 2866 | #define ISP_UNRECOVERABLE 17 |
2862 | #define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */ | 2867 | #define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */ |
2868 | #define MPI_RESET_NEEDED 19 /* Initiate MPI FW reset */ | ||
2863 | 2869 | ||
2864 | uint32_t device_flags; | 2870 | uint32_t device_flags; |
2865 | #define SWITCH_FOUND BIT_0 | 2871 | #define SWITCH_FOUND BIT_0 |
@@ -3003,6 +3009,8 @@ typedef struct scsi_qla_host { | |||
3003 | 3009 | ||
3004 | #define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr) | 3010 | #define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr) |
3005 | 3011 | ||
3012 | #define QLA_SG_ALL 1024 | ||
3013 | |||
3006 | enum nexus_wait_type { | 3014 | enum nexus_wait_type { |
3007 | WAIT_HOST = 0, | 3015 | WAIT_HOST = 0, |
3008 | WAIT_TARGET, | 3016 | WAIT_TARGET, |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 1a1b281cea33..c33dec827e1e 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -352,6 +352,8 @@ qla2x00_read_ram_word(scsi_qla_host_t *, uint32_t, uint32_t *); | |||
352 | extern int | 352 | extern int |
353 | qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); | 353 | qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); |
354 | 354 | ||
355 | extern int | ||
356 | qla81xx_write_mpi_register(scsi_qla_host_t *, uint16_t *); | ||
355 | extern int qla2x00_get_data_rate(scsi_qla_host_t *); | 357 | extern int qla2x00_get_data_rate(scsi_qla_host_t *); |
356 | extern int qla24xx_set_fcp_prio(scsi_qla_host_t *, uint16_t, uint16_t, | 358 | extern int qla24xx_set_fcp_prio(scsi_qla_host_t *, uint16_t, uint16_t, |
357 | uint16_t *); | 359 | uint16_t *); |
@@ -501,7 +503,6 @@ extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | |||
501 | /* PCI related functions */ | 503 | /* PCI related functions */ |
502 | extern int qla82xx_pci_config(struct scsi_qla_host *); | 504 | extern int qla82xx_pci_config(struct scsi_qla_host *); |
503 | extern int qla82xx_pci_mem_read_2M(struct qla_hw_data *, u64, void *, int); | 505 | extern int qla82xx_pci_mem_read_2M(struct qla_hw_data *, u64, void *, int); |
504 | extern int qla82xx_pci_mem_write_2M(struct qla_hw_data *, u64, void *, int); | ||
505 | extern char *qla82xx_pci_info_str(struct scsi_qla_host *, char *); | 506 | extern char *qla82xx_pci_info_str(struct scsi_qla_host *, char *); |
506 | extern int qla82xx_pci_region_offset(struct pci_dev *, int); | 507 | extern int qla82xx_pci_region_offset(struct pci_dev *, int); |
507 | extern int qla82xx_iospace_config(struct qla_hw_data *); | 508 | extern int qla82xx_iospace_config(struct qla_hw_data *); |
@@ -509,8 +510,8 @@ extern int qla82xx_iospace_config(struct qla_hw_data *); | |||
509 | /* Initialization related functions */ | 510 | /* Initialization related functions */ |
510 | extern void qla82xx_reset_chip(struct scsi_qla_host *); | 511 | extern void qla82xx_reset_chip(struct scsi_qla_host *); |
511 | extern void qla82xx_config_rings(struct scsi_qla_host *); | 512 | extern void qla82xx_config_rings(struct scsi_qla_host *); |
512 | extern int qla82xx_pinit_from_rom(scsi_qla_host_t *); | ||
513 | extern void qla82xx_watchdog(scsi_qla_host_t *); | 513 | extern void qla82xx_watchdog(scsi_qla_host_t *); |
514 | extern int qla82xx_start_firmware(scsi_qla_host_t *); | ||
514 | 515 | ||
515 | /* Firmware and flash related functions */ | 516 | /* Firmware and flash related functions */ |
516 | extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *); | 517 | extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *); |
@@ -533,25 +534,17 @@ extern irqreturn_t qla82xx_msix_default(int, void *); | |||
533 | extern irqreturn_t qla82xx_msix_rsp_q(int, void *); | 534 | extern irqreturn_t qla82xx_msix_rsp_q(int, void *); |
534 | extern void qla82xx_enable_intrs(struct qla_hw_data *); | 535 | extern void qla82xx_enable_intrs(struct qla_hw_data *); |
535 | extern void qla82xx_disable_intrs(struct qla_hw_data *); | 536 | extern void qla82xx_disable_intrs(struct qla_hw_data *); |
536 | extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t); | ||
537 | extern void qla82xx_poll(int, void *); | 537 | extern void qla82xx_poll(int, void *); |
538 | extern void qla82xx_init_flags(struct qla_hw_data *); | 538 | extern void qla82xx_init_flags(struct qla_hw_data *); |
539 | 539 | ||
540 | /* ISP 8021 hardware related */ | 540 | /* ISP 8021 hardware related */ |
541 | extern int qla82xx_crb_win_lock(struct qla_hw_data *); | 541 | extern void qla82xx_set_drv_active(scsi_qla_host_t *); |
542 | extern void qla82xx_crb_win_unlock(struct qla_hw_data *); | 542 | extern void qla82xx_crb_win_unlock(struct qla_hw_data *); |
543 | extern int qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *, ulong *); | ||
544 | extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32); | 543 | extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32); |
545 | extern int qla82xx_rd_32(struct qla_hw_data *, ulong); | 544 | extern int qla82xx_rd_32(struct qla_hw_data *, ulong); |
546 | extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int); | 545 | extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int); |
547 | extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int); | 546 | extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int); |
548 | extern int qla82xx_check_for_bad_spd(struct qla_hw_data *); | ||
549 | extern int qla82xx_load_fw(scsi_qla_host_t *); | ||
550 | extern int qla82xx_rom_lock(struct qla_hw_data *); | ||
551 | extern void qla82xx_rom_unlock(struct qla_hw_data *); | 547 | extern void qla82xx_rom_unlock(struct qla_hw_data *); |
552 | extern int qla82xx_rom_fast_read(struct qla_hw_data *, int , int *); | ||
553 | extern int qla82xx_do_rom_fast_read(struct qla_hw_data *, int, int *); | ||
554 | extern unsigned long qla82xx_decode_crb_addr(unsigned long); | ||
555 | 548 | ||
556 | /* ISP 8021 IDC */ | 549 | /* ISP 8021 IDC */ |
557 | extern void qla82xx_clear_drv_active(struct qla_hw_data *); | 550 | extern void qla82xx_clear_drv_active(struct qla_hw_data *); |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 9c383baebe27..3cafbef40737 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -954,6 +954,19 @@ qla2x00_reset_chip(scsi_qla_host_t *vha) | |||
954 | } | 954 | } |
955 | 955 | ||
956 | /** | 956 | /** |
957 | * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC. | ||
958 | * | ||
959 | * Returns 0 on success. | ||
960 | */ | ||
961 | int | ||
962 | qla81xx_reset_mpi(scsi_qla_host_t *vha) | ||
963 | { | ||
964 | uint16_t mb[4] = {0x1010, 0, 1, 0}; | ||
965 | |||
966 | return qla81xx_write_mpi_register(vha, mb); | ||
967 | } | ||
968 | |||
969 | /** | ||
957 | * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC. | 970 | * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC. |
958 | * @ha: HA context | 971 | * @ha: HA context |
959 | * | 972 | * |
@@ -967,6 +980,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) | |||
967 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 980 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
968 | uint32_t cnt, d2; | 981 | uint32_t cnt, d2; |
969 | uint16_t wd; | 982 | uint16_t wd; |
983 | static int abts_cnt; /* ISP abort retry counts */ | ||
970 | 984 | ||
971 | spin_lock_irqsave(&ha->hardware_lock, flags); | 985 | spin_lock_irqsave(&ha->hardware_lock, flags); |
972 | 986 | ||
@@ -1000,6 +1014,23 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) | |||
1000 | barrier(); | 1014 | barrier(); |
1001 | } | 1015 | } |
1002 | 1016 | ||
1017 | /* If required, do an MPI FW reset now */ | ||
1018 | if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) { | ||
1019 | if (qla81xx_reset_mpi(vha) != QLA_SUCCESS) { | ||
1020 | if (++abts_cnt < 5) { | ||
1021 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | ||
1022 | set_bit(MPI_RESET_NEEDED, &vha->dpc_flags); | ||
1023 | } else { | ||
1024 | /* | ||
1025 | * We exhausted the ISP abort retries. We have to | ||
1026 | * set the board offline. | ||
1027 | */ | ||
1028 | abts_cnt = 0; | ||
1029 | vha->flags.online = 0; | ||
1030 | } | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1003 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); | 1034 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); |
1004 | RD_REG_DWORD(®->hccr); | 1035 | RD_REG_DWORD(®->hccr); |
1005 | 1036 | ||
@@ -2799,6 +2830,9 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
2799 | if (!IS_IIDMA_CAPABLE(ha)) | 2830 | if (!IS_IIDMA_CAPABLE(ha)) |
2800 | return; | 2831 | return; |
2801 | 2832 | ||
2833 | if (atomic_read(&fcport->state) != FCS_ONLINE) | ||
2834 | return; | ||
2835 | |||
2802 | if (fcport->fp_speed == PORT_SPEED_UNKNOWN || | 2836 | if (fcport->fp_speed == PORT_SPEED_UNKNOWN || |
2803 | fcport->fp_speed > ha->link_data_rate) | 2837 | fcport->fp_speed > ha->link_data_rate) |
2804 | return; | 2838 | return; |
@@ -3878,17 +3912,19 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) | |||
3878 | LOOP_DOWN_TIME); | 3912 | LOOP_DOWN_TIME); |
3879 | } | 3913 | } |
3880 | 3914 | ||
3881 | /* Make sure for ISP 82XX IO DMA is complete */ | 3915 | if (!ha->flags.eeh_busy) { |
3882 | if (IS_QLA82XX(ha)) { | 3916 | /* Make sure for ISP 82XX IO DMA is complete */ |
3883 | if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, | 3917 | if (IS_QLA82XX(ha)) { |
3884 | WAIT_HOST) == QLA_SUCCESS) { | 3918 | if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, |
3885 | DEBUG2(qla_printk(KERN_INFO, ha, | 3919 | WAIT_HOST) == QLA_SUCCESS) { |
3886 | "Done wait for pending commands\n")); | 3920 | DEBUG2(qla_printk(KERN_INFO, ha, |
3921 | "Done wait for pending commands\n")); | ||
3922 | } | ||
3887 | } | 3923 | } |
3888 | } | ||
3889 | 3924 | ||
3890 | /* Requeue all commands in outstanding command list. */ | 3925 | /* Requeue all commands in outstanding command list. */ |
3891 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); | 3926 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); |
3927 | } | ||
3892 | } | 3928 | } |
3893 | 3929 | ||
3894 | /* | 3930 | /* |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 28f65be19dad..e0e43d9e7ed1 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -412,8 +412,14 @@ skip_rio: | |||
412 | "Unrecoverable Hardware Error: adapter " | 412 | "Unrecoverable Hardware Error: adapter " |
413 | "marked OFFLINE!\n"); | 413 | "marked OFFLINE!\n"); |
414 | vha->flags.online = 0; | 414 | vha->flags.online = 0; |
415 | } else | 415 | } else { |
416 | /* Check to see if MPI timeout occured */ | ||
417 | if ((mbx & MBX_3) && (ha->flags.port0)) | ||
418 | set_bit(MPI_RESET_NEEDED, | ||
419 | &vha->dpc_flags); | ||
420 | |||
416 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | 421 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
422 | } | ||
417 | } else if (mb[1] == 0) { | 423 | } else if (mb[1] == 0) { |
418 | qla_printk(KERN_INFO, ha, | 424 | qla_printk(KERN_INFO, ha, |
419 | "Unrecoverable Hardware Error: adapter marked " | 425 | "Unrecoverable Hardware Error: adapter marked " |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index a595ec8264f8..effd8a1403d9 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -3828,8 +3828,6 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, | |||
3828 | 3828 | ||
3829 | /* Copy mailbox information */ | 3829 | /* Copy mailbox information */ |
3830 | memcpy( mresp, mcp->mb, 64); | 3830 | memcpy( mresp, mcp->mb, 64); |
3831 | mresp[3] = mcp->mb[18]; | ||
3832 | mresp[4] = mcp->mb[19]; | ||
3833 | return rval; | 3831 | return rval; |
3834 | } | 3832 | } |
3835 | 3833 | ||
@@ -3890,9 +3888,10 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, | |||
3890 | } | 3888 | } |
3891 | 3889 | ||
3892 | /* Copy mailbox information */ | 3890 | /* Copy mailbox information */ |
3893 | memcpy( mresp, mcp->mb, 32); | 3891 | memcpy(mresp, mcp->mb, 64); |
3894 | return rval; | 3892 | return rval; |
3895 | } | 3893 | } |
3894 | |||
3896 | int | 3895 | int |
3897 | qla84xx_reset_chip(scsi_qla_host_t *ha, uint16_t enable_diagnostic) | 3896 | qla84xx_reset_chip(scsi_qla_host_t *ha, uint16_t enable_diagnostic) |
3898 | { | 3897 | { |
@@ -3953,6 +3952,67 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) | |||
3953 | } | 3952 | } |
3954 | 3953 | ||
3955 | int | 3954 | int |
3955 | qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb) | ||
3956 | { | ||
3957 | int rval; | ||
3958 | uint32_t stat, timer; | ||
3959 | uint16_t mb0 = 0; | ||
3960 | struct qla_hw_data *ha = vha->hw; | ||
3961 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
3962 | |||
3963 | rval = QLA_SUCCESS; | ||
3964 | |||
3965 | DEBUG11(qla_printk(KERN_INFO, ha, | ||
3966 | "%s(%ld): entered.\n", __func__, vha->host_no)); | ||
3967 | |||
3968 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
3969 | |||
3970 | /* Write the MBC data to the registers */ | ||
3971 | WRT_REG_WORD(®->mailbox0, MBC_WRITE_MPI_REGISTER); | ||
3972 | WRT_REG_WORD(®->mailbox1, mb[0]); | ||
3973 | WRT_REG_WORD(®->mailbox2, mb[1]); | ||
3974 | WRT_REG_WORD(®->mailbox3, mb[2]); | ||
3975 | WRT_REG_WORD(®->mailbox4, mb[3]); | ||
3976 | |||
3977 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | ||
3978 | |||
3979 | /* Poll for MBC interrupt */ | ||
3980 | for (timer = 6000000; timer; timer--) { | ||
3981 | /* Check for pending interrupts. */ | ||
3982 | stat = RD_REG_DWORD(®->host_status); | ||
3983 | if (stat & HSRX_RISC_INT) { | ||
3984 | stat &= 0xff; | ||
3985 | |||
3986 | if (stat == 0x1 || stat == 0x2 || | ||
3987 | stat == 0x10 || stat == 0x11) { | ||
3988 | set_bit(MBX_INTERRUPT, | ||
3989 | &ha->mbx_cmd_flags); | ||
3990 | mb0 = RD_REG_WORD(®->mailbox0); | ||
3991 | WRT_REG_DWORD(®->hccr, | ||
3992 | HCCRX_CLR_RISC_INT); | ||
3993 | RD_REG_DWORD(®->hccr); | ||
3994 | break; | ||
3995 | } | ||
3996 | } | ||
3997 | udelay(5); | ||
3998 | } | ||
3999 | |||
4000 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) | ||
4001 | rval = mb0 & MBS_MASK; | ||
4002 | else | ||
4003 | rval = QLA_FUNCTION_FAILED; | ||
4004 | |||
4005 | if (rval != QLA_SUCCESS) { | ||
4006 | DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n", | ||
4007 | __func__, vha->host_no, rval, mb[0])); | ||
4008 | } else { | ||
4009 | DEBUG11(printk(KERN_INFO | ||
4010 | "%s(%ld): done.\n", __func__, vha->host_no)); | ||
4011 | } | ||
4012 | |||
4013 | return rval; | ||
4014 | } | ||
4015 | int | ||
3956 | qla2x00_get_data_rate(scsi_qla_host_t *vha) | 4016 | qla2x00_get_data_rate(scsi_qla_host_t *vha) |
3957 | { | 4017 | { |
3958 | int rval; | 4018 | int rval; |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 0a71cc71eab2..8d9edfb39803 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -403,6 +403,54 @@ qla82xx_pci_set_crbwindow(struct qla_hw_data *ha, u64 off) | |||
403 | return off; | 403 | return off; |
404 | } | 404 | } |
405 | 405 | ||
406 | static int | ||
407 | qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong *off) | ||
408 | { | ||
409 | struct crb_128M_2M_sub_block_map *m; | ||
410 | |||
411 | if (*off >= QLA82XX_CRB_MAX) | ||
412 | return -1; | ||
413 | |||
414 | if (*off >= QLA82XX_PCI_CAMQM && (*off < QLA82XX_PCI_CAMQM_2M_END)) { | ||
415 | *off = (*off - QLA82XX_PCI_CAMQM) + | ||
416 | QLA82XX_PCI_CAMQM_2M_BASE + ha->nx_pcibase; | ||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | if (*off < QLA82XX_PCI_CRBSPACE) | ||
421 | return -1; | ||
422 | |||
423 | *off -= QLA82XX_PCI_CRBSPACE; | ||
424 | |||
425 | /* Try direct map */ | ||
426 | m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)]; | ||
427 | |||
428 | if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) { | ||
429 | *off = *off + m->start_2M - m->start_128M + ha->nx_pcibase; | ||
430 | return 0; | ||
431 | } | ||
432 | /* Not in direct map, use crb window */ | ||
433 | return 1; | ||
434 | } | ||
435 | |||
436 | #define CRB_WIN_LOCK_TIMEOUT 100000000 | ||
437 | static int qla82xx_crb_win_lock(struct qla_hw_data *ha) | ||
438 | { | ||
439 | int done = 0, timeout = 0; | ||
440 | |||
441 | while (!done) { | ||
442 | /* acquire semaphore3 from PCI HW block */ | ||
443 | done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK)); | ||
444 | if (done == 1) | ||
445 | break; | ||
446 | if (timeout >= CRB_WIN_LOCK_TIMEOUT) | ||
447 | return -1; | ||
448 | timeout++; | ||
449 | } | ||
450 | qla82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->portnum); | ||
451 | return 0; | ||
452 | } | ||
453 | |||
406 | int | 454 | int |
407 | qla82xx_wr_32(struct qla_hw_data *ha, ulong off, u32 data) | 455 | qla82xx_wr_32(struct qla_hw_data *ha, ulong off, u32 data) |
408 | { | 456 | { |
@@ -453,24 +501,6 @@ qla82xx_rd_32(struct qla_hw_data *ha, ulong off) | |||
453 | return data; | 501 | return data; |
454 | } | 502 | } |
455 | 503 | ||
456 | #define CRB_WIN_LOCK_TIMEOUT 100000000 | ||
457 | int qla82xx_crb_win_lock(struct qla_hw_data *ha) | ||
458 | { | ||
459 | int done = 0, timeout = 0; | ||
460 | |||
461 | while (!done) { | ||
462 | /* acquire semaphore3 from PCI HW block */ | ||
463 | done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK)); | ||
464 | if (done == 1) | ||
465 | break; | ||
466 | if (timeout >= CRB_WIN_LOCK_TIMEOUT) | ||
467 | return -1; | ||
468 | timeout++; | ||
469 | } | ||
470 | qla82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->portnum); | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | #define IDC_LOCK_TIMEOUT 100000000 | 504 | #define IDC_LOCK_TIMEOUT 100000000 |
475 | int qla82xx_idc_lock(struct qla_hw_data *ha) | 505 | int qla82xx_idc_lock(struct qla_hw_data *ha) |
476 | { | 506 | { |
@@ -504,36 +534,6 @@ void qla82xx_idc_unlock(struct qla_hw_data *ha) | |||
504 | qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_UNLOCK)); | 534 | qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_UNLOCK)); |
505 | } | 535 | } |
506 | 536 | ||
507 | int | ||
508 | qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong *off) | ||
509 | { | ||
510 | struct crb_128M_2M_sub_block_map *m; | ||
511 | |||
512 | if (*off >= QLA82XX_CRB_MAX) | ||
513 | return -1; | ||
514 | |||
515 | if (*off >= QLA82XX_PCI_CAMQM && (*off < QLA82XX_PCI_CAMQM_2M_END)) { | ||
516 | *off = (*off - QLA82XX_PCI_CAMQM) + | ||
517 | QLA82XX_PCI_CAMQM_2M_BASE + ha->nx_pcibase; | ||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | if (*off < QLA82XX_PCI_CRBSPACE) | ||
522 | return -1; | ||
523 | |||
524 | *off -= QLA82XX_PCI_CRBSPACE; | ||
525 | |||
526 | /* Try direct map */ | ||
527 | m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)]; | ||
528 | |||
529 | if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) { | ||
530 | *off = *off + m->start_2M - m->start_128M + ha->nx_pcibase; | ||
531 | return 0; | ||
532 | } | ||
533 | /* Not in direct map, use crb window */ | ||
534 | return 1; | ||
535 | } | ||
536 | |||
537 | /* PCI Windowing for DDR regions. */ | 537 | /* PCI Windowing for DDR regions. */ |
538 | #define QLA82XX_ADDR_IN_RANGE(addr, low, high) \ | 538 | #define QLA82XX_ADDR_IN_RANGE(addr, low, high) \ |
539 | (((addr) <= (high)) && ((addr) >= (low))) | 539 | (((addr) <= (high)) && ((addr) >= (low))) |
@@ -557,7 +557,7 @@ qla82xx_pci_mem_bound_check(struct qla_hw_data *ha, | |||
557 | 557 | ||
558 | int qla82xx_pci_set_window_warning_count; | 558 | int qla82xx_pci_set_window_warning_count; |
559 | 559 | ||
560 | unsigned long | 560 | static unsigned long |
561 | qla82xx_pci_set_window(struct qla_hw_data *ha, unsigned long long addr) | 561 | qla82xx_pci_set_window(struct qla_hw_data *ha, unsigned long long addr) |
562 | { | 562 | { |
563 | int window; | 563 | int window; |
@@ -798,7 +798,8 @@ qla82xx_pci_mem_write_direct(struct qla_hw_data *ha, | |||
798 | } | 798 | } |
799 | 799 | ||
800 | #define MTU_FUDGE_FACTOR 100 | 800 | #define MTU_FUDGE_FACTOR 100 |
801 | unsigned long qla82xx_decode_crb_addr(unsigned long addr) | 801 | static unsigned long |
802 | qla82xx_decode_crb_addr(unsigned long addr) | ||
802 | { | 803 | { |
803 | int i; | 804 | int i; |
804 | unsigned long base_addr, offset, pci_base; | 805 | unsigned long base_addr, offset, pci_base; |
@@ -824,7 +825,7 @@ unsigned long qla82xx_decode_crb_addr(unsigned long addr) | |||
824 | static long rom_max_timeout = 100; | 825 | static long rom_max_timeout = 100; |
825 | static long qla82xx_rom_lock_timeout = 100; | 826 | static long qla82xx_rom_lock_timeout = 100; |
826 | 827 | ||
827 | int | 828 | static int |
828 | qla82xx_rom_lock(struct qla_hw_data *ha) | 829 | qla82xx_rom_lock(struct qla_hw_data *ha) |
829 | { | 830 | { |
830 | int done = 0, timeout = 0; | 831 | int done = 0, timeout = 0; |
@@ -842,7 +843,7 @@ qla82xx_rom_lock(struct qla_hw_data *ha) | |||
842 | return 0; | 843 | return 0; |
843 | } | 844 | } |
844 | 845 | ||
845 | int | 846 | static int |
846 | qla82xx_wait_rom_busy(struct qla_hw_data *ha) | 847 | qla82xx_wait_rom_busy(struct qla_hw_data *ha) |
847 | { | 848 | { |
848 | long timeout = 0; | 849 | long timeout = 0; |
@@ -862,7 +863,7 @@ qla82xx_wait_rom_busy(struct qla_hw_data *ha) | |||
862 | return 0; | 863 | return 0; |
863 | } | 864 | } |
864 | 865 | ||
865 | int | 866 | static int |
866 | qla82xx_wait_rom_done(struct qla_hw_data *ha) | 867 | qla82xx_wait_rom_done(struct qla_hw_data *ha) |
867 | { | 868 | { |
868 | long timeout = 0; | 869 | long timeout = 0; |
@@ -882,7 +883,7 @@ qla82xx_wait_rom_done(struct qla_hw_data *ha) | |||
882 | return 0; | 883 | return 0; |
883 | } | 884 | } |
884 | 885 | ||
885 | int | 886 | static int |
886 | qla82xx_do_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) | 887 | qla82xx_do_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) |
887 | { | 888 | { |
888 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr); | 889 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr); |
@@ -905,7 +906,7 @@ qla82xx_do_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) | |||
905 | return 0; | 906 | return 0; |
906 | } | 907 | } |
907 | 908 | ||
908 | int | 909 | static int |
909 | qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) | 910 | qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) |
910 | { | 911 | { |
911 | int ret, loops = 0; | 912 | int ret, loops = 0; |
@@ -926,7 +927,7 @@ qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) | |||
926 | return ret; | 927 | return ret; |
927 | } | 928 | } |
928 | 929 | ||
929 | int | 930 | static int |
930 | qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val) | 931 | qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val) |
931 | { | 932 | { |
932 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_RDSR); | 933 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_RDSR); |
@@ -940,7 +941,7 @@ qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val) | |||
940 | return 0; | 941 | return 0; |
941 | } | 942 | } |
942 | 943 | ||
943 | int | 944 | static int |
944 | qla82xx_flash_wait_write_finish(struct qla_hw_data *ha) | 945 | qla82xx_flash_wait_write_finish(struct qla_hw_data *ha) |
945 | { | 946 | { |
946 | long timeout = 0; | 947 | long timeout = 0; |
@@ -964,7 +965,7 @@ qla82xx_flash_wait_write_finish(struct qla_hw_data *ha) | |||
964 | return ret; | 965 | return ret; |
965 | } | 966 | } |
966 | 967 | ||
967 | int | 968 | static int |
968 | qla82xx_flash_set_write_enable(struct qla_hw_data *ha) | 969 | qla82xx_flash_set_write_enable(struct qla_hw_data *ha) |
969 | { | 970 | { |
970 | uint32_t val; | 971 | uint32_t val; |
@@ -981,7 +982,7 @@ qla82xx_flash_set_write_enable(struct qla_hw_data *ha) | |||
981 | return 0; | 982 | return 0; |
982 | } | 983 | } |
983 | 984 | ||
984 | int | 985 | static int |
985 | qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val) | 986 | qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val) |
986 | { | 987 | { |
987 | if (qla82xx_flash_set_write_enable(ha)) | 988 | if (qla82xx_flash_set_write_enable(ha)) |
@@ -996,7 +997,7 @@ qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val) | |||
996 | return qla82xx_flash_wait_write_finish(ha); | 997 | return qla82xx_flash_wait_write_finish(ha); |
997 | } | 998 | } |
998 | 999 | ||
999 | int | 1000 | static int |
1000 | qla82xx_write_disable_flash(struct qla_hw_data *ha) | 1001 | qla82xx_write_disable_flash(struct qla_hw_data *ha) |
1001 | { | 1002 | { |
1002 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WRDI); | 1003 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WRDI); |
@@ -1008,7 +1009,7 @@ qla82xx_write_disable_flash(struct qla_hw_data *ha) | |||
1008 | return 0; | 1009 | return 0; |
1009 | } | 1010 | } |
1010 | 1011 | ||
1011 | int | 1012 | static int |
1012 | ql82xx_rom_lock_d(struct qla_hw_data *ha) | 1013 | ql82xx_rom_lock_d(struct qla_hw_data *ha) |
1013 | { | 1014 | { |
1014 | int loops = 0; | 1015 | int loops = 0; |
@@ -1024,7 +1025,7 @@ ql82xx_rom_lock_d(struct qla_hw_data *ha) | |||
1024 | return 0;; | 1025 | return 0;; |
1025 | } | 1026 | } |
1026 | 1027 | ||
1027 | int | 1028 | static int |
1028 | qla82xx_write_flash_dword(struct qla_hw_data *ha, uint32_t flashaddr, | 1029 | qla82xx_write_flash_dword(struct qla_hw_data *ha, uint32_t flashaddr, |
1029 | uint32_t data) | 1030 | uint32_t data) |
1030 | { | 1031 | { |
@@ -1061,7 +1062,8 @@ done_write: | |||
1061 | /* This routine does CRB initialize sequence | 1062 | /* This routine does CRB initialize sequence |
1062 | * to put the ISP into operational state | 1063 | * to put the ISP into operational state |
1063 | */ | 1064 | */ |
1064 | int qla82xx_pinit_from_rom(scsi_qla_host_t *vha) | 1065 | static int |
1066 | qla82xx_pinit_from_rom(scsi_qla_host_t *vha) | ||
1065 | { | 1067 | { |
1066 | int addr, val; | 1068 | int addr, val; |
1067 | int i ; | 1069 | int i ; |
@@ -1207,7 +1209,8 @@ int qla82xx_pinit_from_rom(scsi_qla_host_t *vha) | |||
1207 | return 0; | 1209 | return 0; |
1208 | } | 1210 | } |
1209 | 1211 | ||
1210 | int qla82xx_check_for_bad_spd(struct qla_hw_data *ha) | 1212 | static int |
1213 | qla82xx_check_for_bad_spd(struct qla_hw_data *ha) | ||
1211 | { | 1214 | { |
1212 | u32 val = 0; | 1215 | u32 val = 0; |
1213 | val = qla82xx_rd_32(ha, BOOT_LOADER_DIMM_STATUS); | 1216 | val = qla82xx_rd_32(ha, BOOT_LOADER_DIMM_STATUS); |
@@ -1225,7 +1228,116 @@ int qla82xx_check_for_bad_spd(struct qla_hw_data *ha) | |||
1225 | return 0; | 1228 | return 0; |
1226 | } | 1229 | } |
1227 | 1230 | ||
1228 | int | 1231 | static int |
1232 | qla82xx_pci_mem_write_2M(struct qla_hw_data *ha, | ||
1233 | u64 off, void *data, int size) | ||
1234 | { | ||
1235 | int i, j, ret = 0, loop, sz[2], off0; | ||
1236 | int scale, shift_amount, startword; | ||
1237 | uint32_t temp; | ||
1238 | uint64_t off8, mem_crb, tmpw, word[2] = {0, 0}; | ||
1239 | |||
1240 | /* | ||
1241 | * If not MN, go check for MS or invalid. | ||
1242 | */ | ||
1243 | if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX) | ||
1244 | mem_crb = QLA82XX_CRB_QDR_NET; | ||
1245 | else { | ||
1246 | mem_crb = QLA82XX_CRB_DDR_NET; | ||
1247 | if (qla82xx_pci_mem_bound_check(ha, off, size) == 0) | ||
1248 | return qla82xx_pci_mem_write_direct(ha, | ||
1249 | off, data, size); | ||
1250 | } | ||
1251 | |||
1252 | off0 = off & 0x7; | ||
1253 | sz[0] = (size < (8 - off0)) ? size : (8 - off0); | ||
1254 | sz[1] = size - sz[0]; | ||
1255 | |||
1256 | off8 = off & 0xfffffff0; | ||
1257 | loop = (((off & 0xf) + size - 1) >> 4) + 1; | ||
1258 | shift_amount = 4; | ||
1259 | scale = 2; | ||
1260 | startword = (off & 0xf)/8; | ||
1261 | |||
1262 | for (i = 0; i < loop; i++) { | ||
1263 | if (qla82xx_pci_mem_read_2M(ha, off8 + | ||
1264 | (i << shift_amount), &word[i * scale], 8)) | ||
1265 | return -1; | ||
1266 | } | ||
1267 | |||
1268 | switch (size) { | ||
1269 | case 1: | ||
1270 | tmpw = *((uint8_t *)data); | ||
1271 | break; | ||
1272 | case 2: | ||
1273 | tmpw = *((uint16_t *)data); | ||
1274 | break; | ||
1275 | case 4: | ||
1276 | tmpw = *((uint32_t *)data); | ||
1277 | break; | ||
1278 | case 8: | ||
1279 | default: | ||
1280 | tmpw = *((uint64_t *)data); | ||
1281 | break; | ||
1282 | } | ||
1283 | |||
1284 | if (sz[0] == 8) { | ||
1285 | word[startword] = tmpw; | ||
1286 | } else { | ||
1287 | word[startword] &= | ||
1288 | ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); | ||
1289 | word[startword] |= tmpw << (off0 * 8); | ||
1290 | } | ||
1291 | if (sz[1] != 0) { | ||
1292 | word[startword+1] &= ~(~0ULL << (sz[1] * 8)); | ||
1293 | word[startword+1] |= tmpw >> (sz[0] * 8); | ||
1294 | } | ||
1295 | |||
1296 | /* | ||
1297 | * don't lock here - write_wx gets the lock if each time | ||
1298 | * write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1299 | * netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1300 | */ | ||
1301 | for (i = 0; i < loop; i++) { | ||
1302 | temp = off8 + (i << shift_amount); | ||
1303 | qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp); | ||
1304 | temp = 0; | ||
1305 | qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_HI, temp); | ||
1306 | temp = word[i * scale] & 0xffffffff; | ||
1307 | qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp); | ||
1308 | temp = (word[i * scale] >> 32) & 0xffffffff; | ||
1309 | qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp); | ||
1310 | temp = word[i*scale + 1] & 0xffffffff; | ||
1311 | qla82xx_wr_32(ha, mem_crb + | ||
1312 | MIU_TEST_AGT_WRDATA_UPPER_LO, temp); | ||
1313 | temp = (word[i*scale + 1] >> 32) & 0xffffffff; | ||
1314 | qla82xx_wr_32(ha, mem_crb + | ||
1315 | MIU_TEST_AGT_WRDATA_UPPER_HI, temp); | ||
1316 | |||
1317 | temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; | ||
1318 | qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp); | ||
1319 | temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; | ||
1320 | qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp); | ||
1321 | |||
1322 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1323 | temp = qla82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL); | ||
1324 | if ((temp & MIU_TA_CTL_BUSY) == 0) | ||
1325 | break; | ||
1326 | } | ||
1327 | |||
1328 | if (j >= MAX_CTL_CHECK) { | ||
1329 | if (printk_ratelimit()) | ||
1330 | dev_err(&ha->pdev->dev, | ||
1331 | "failed to write through agent\n"); | ||
1332 | ret = -1; | ||
1333 | break; | ||
1334 | } | ||
1335 | } | ||
1336 | |||
1337 | return ret; | ||
1338 | } | ||
1339 | |||
1340 | static int | ||
1229 | qla82xx_fw_load_from_flash(struct qla_hw_data *ha) | 1341 | qla82xx_fw_load_from_flash(struct qla_hw_data *ha) |
1230 | { | 1342 | { |
1231 | int i; | 1343 | int i; |
@@ -1357,114 +1469,6 @@ qla82xx_pci_mem_read_2M(struct qla_hw_data *ha, | |||
1357 | return 0; | 1469 | return 0; |
1358 | } | 1470 | } |
1359 | 1471 | ||
1360 | int | ||
1361 | qla82xx_pci_mem_write_2M(struct qla_hw_data *ha, | ||
1362 | u64 off, void *data, int size) | ||
1363 | { | ||
1364 | int i, j, ret = 0, loop, sz[2], off0; | ||
1365 | int scale, shift_amount, startword; | ||
1366 | uint32_t temp; | ||
1367 | uint64_t off8, mem_crb, tmpw, word[2] = {0, 0}; | ||
1368 | |||
1369 | /* | ||
1370 | * If not MN, go check for MS or invalid. | ||
1371 | */ | ||
1372 | if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX) | ||
1373 | mem_crb = QLA82XX_CRB_QDR_NET; | ||
1374 | else { | ||
1375 | mem_crb = QLA82XX_CRB_DDR_NET; | ||
1376 | if (qla82xx_pci_mem_bound_check(ha, off, size) == 0) | ||
1377 | return qla82xx_pci_mem_write_direct(ha, | ||
1378 | off, data, size); | ||
1379 | } | ||
1380 | |||
1381 | off0 = off & 0x7; | ||
1382 | sz[0] = (size < (8 - off0)) ? size : (8 - off0); | ||
1383 | sz[1] = size - sz[0]; | ||
1384 | |||
1385 | off8 = off & 0xfffffff0; | ||
1386 | loop = (((off & 0xf) + size - 1) >> 4) + 1; | ||
1387 | shift_amount = 4; | ||
1388 | scale = 2; | ||
1389 | startword = (off & 0xf)/8; | ||
1390 | |||
1391 | for (i = 0; i < loop; i++) { | ||
1392 | if (qla82xx_pci_mem_read_2M(ha, off8 + | ||
1393 | (i << shift_amount), &word[i * scale], 8)) | ||
1394 | return -1; | ||
1395 | } | ||
1396 | |||
1397 | switch (size) { | ||
1398 | case 1: | ||
1399 | tmpw = *((uint8_t *)data); | ||
1400 | break; | ||
1401 | case 2: | ||
1402 | tmpw = *((uint16_t *)data); | ||
1403 | break; | ||
1404 | case 4: | ||
1405 | tmpw = *((uint32_t *)data); | ||
1406 | break; | ||
1407 | case 8: | ||
1408 | default: | ||
1409 | tmpw = *((uint64_t *)data); | ||
1410 | break; | ||
1411 | } | ||
1412 | |||
1413 | if (sz[0] == 8) { | ||
1414 | word[startword] = tmpw; | ||
1415 | } else { | ||
1416 | word[startword] &= | ||
1417 | ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); | ||
1418 | word[startword] |= tmpw << (off0 * 8); | ||
1419 | } | ||
1420 | if (sz[1] != 0) { | ||
1421 | word[startword+1] &= ~(~0ULL << (sz[1] * 8)); | ||
1422 | word[startword+1] |= tmpw >> (sz[0] * 8); | ||
1423 | } | ||
1424 | |||
1425 | /* | ||
1426 | * don't lock here - write_wx gets the lock if each time | ||
1427 | * write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1428 | * netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1429 | */ | ||
1430 | for (i = 0; i < loop; i++) { | ||
1431 | temp = off8 + (i << shift_amount); | ||
1432 | qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp); | ||
1433 | temp = 0; | ||
1434 | qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_HI, temp); | ||
1435 | temp = word[i * scale] & 0xffffffff; | ||
1436 | qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp); | ||
1437 | temp = (word[i * scale] >> 32) & 0xffffffff; | ||
1438 | qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp); | ||
1439 | temp = word[i*scale + 1] & 0xffffffff; | ||
1440 | qla82xx_wr_32(ha, mem_crb + | ||
1441 | MIU_TEST_AGT_WRDATA_UPPER_LO, temp); | ||
1442 | temp = (word[i*scale + 1] >> 32) & 0xffffffff; | ||
1443 | qla82xx_wr_32(ha, mem_crb + | ||
1444 | MIU_TEST_AGT_WRDATA_UPPER_HI, temp); | ||
1445 | |||
1446 | temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; | ||
1447 | qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp); | ||
1448 | temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; | ||
1449 | qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp); | ||
1450 | |||
1451 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1452 | temp = qla82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL); | ||
1453 | if ((temp & MIU_TA_CTL_BUSY) == 0) | ||
1454 | break; | ||
1455 | } | ||
1456 | |||
1457 | if (j >= MAX_CTL_CHECK) { | ||
1458 | if (printk_ratelimit()) | ||
1459 | dev_err(&ha->pdev->dev, | ||
1460 | "failed to write through agent\n"); | ||
1461 | ret = -1; | ||
1462 | break; | ||
1463 | } | ||
1464 | } | ||
1465 | |||
1466 | return ret; | ||
1467 | } | ||
1468 | 1472 | ||
1469 | static struct qla82xx_uri_table_desc * | 1473 | static struct qla82xx_uri_table_desc * |
1470 | qla82xx_get_table_desc(const u8 *unirom, int section) | 1474 | qla82xx_get_table_desc(const u8 *unirom, int section) |
@@ -1725,7 +1729,8 @@ void qla82xx_reset_adapter(struct scsi_qla_host *vha) | |||
1725 | ha->isp_ops->disable_intrs(ha); | 1729 | ha->isp_ops->disable_intrs(ha); |
1726 | } | 1730 | } |
1727 | 1731 | ||
1728 | int qla82xx_fw_load_from_blob(struct qla_hw_data *ha) | 1732 | static int |
1733 | qla82xx_fw_load_from_blob(struct qla_hw_data *ha) | ||
1729 | { | 1734 | { |
1730 | u64 *ptr64; | 1735 | u64 *ptr64; |
1731 | u32 i, flashaddr, size; | 1736 | u32 i, flashaddr, size; |
@@ -1836,7 +1841,8 @@ qla82xx_validate_firmware_blob(scsi_qla_host_t *vha, uint8_t fw_type) | |||
1836 | return 0; | 1841 | return 0; |
1837 | } | 1842 | } |
1838 | 1843 | ||
1839 | int qla82xx_check_cmdpeg_state(struct qla_hw_data *ha) | 1844 | static int |
1845 | qla82xx_check_cmdpeg_state(struct qla_hw_data *ha) | ||
1840 | { | 1846 | { |
1841 | u32 val = 0; | 1847 | u32 val = 0; |
1842 | int retries = 60; | 1848 | int retries = 60; |
@@ -1874,7 +1880,8 @@ int qla82xx_check_cmdpeg_state(struct qla_hw_data *ha) | |||
1874 | return QLA_FUNCTION_FAILED; | 1880 | return QLA_FUNCTION_FAILED; |
1875 | } | 1881 | } |
1876 | 1882 | ||
1877 | int qla82xx_check_rcvpeg_state(struct qla_hw_data *ha) | 1883 | static int |
1884 | qla82xx_check_rcvpeg_state(struct qla_hw_data *ha) | ||
1878 | { | 1885 | { |
1879 | u32 val = 0; | 1886 | u32 val = 0; |
1880 | int retries = 60; | 1887 | int retries = 60; |
@@ -1933,7 +1940,7 @@ static struct qla82xx_legacy_intr_set legacy_intr[] = \ | |||
1933 | * @ha: SCSI driver HA context | 1940 | * @ha: SCSI driver HA context |
1934 | * @mb0: Mailbox0 register | 1941 | * @mb0: Mailbox0 register |
1935 | */ | 1942 | */ |
1936 | void | 1943 | static void |
1937 | qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) | 1944 | qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) |
1938 | { | 1945 | { |
1939 | uint16_t cnt; | 1946 | uint16_t cnt; |
@@ -2257,7 +2264,7 @@ void qla82xx_init_flags(struct qla_hw_data *ha) | |||
2257 | ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg; | 2264 | ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg; |
2258 | } | 2265 | } |
2259 | 2266 | ||
2260 | static inline void | 2267 | inline void |
2261 | qla82xx_set_drv_active(scsi_qla_host_t *vha) | 2268 | qla82xx_set_drv_active(scsi_qla_host_t *vha) |
2262 | { | 2269 | { |
2263 | uint32_t drv_active; | 2270 | uint32_t drv_active; |
@@ -2267,10 +2274,11 @@ qla82xx_set_drv_active(scsi_qla_host_t *vha) | |||
2267 | 2274 | ||
2268 | /* If reset value is all FF's, initialize DRV_ACTIVE */ | 2275 | /* If reset value is all FF's, initialize DRV_ACTIVE */ |
2269 | if (drv_active == 0xffffffff) { | 2276 | if (drv_active == 0xffffffff) { |
2270 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, 0); | 2277 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, |
2278 | QLA82XX_DRV_NOT_ACTIVE); | ||
2271 | drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); | 2279 | drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); |
2272 | } | 2280 | } |
2273 | drv_active |= (1 << (ha->portnum * 4)); | 2281 | drv_active |= (QLA82XX_DRV_ACTIVE << (ha->portnum * 4)); |
2274 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active); | 2282 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active); |
2275 | } | 2283 | } |
2276 | 2284 | ||
@@ -2280,7 +2288,7 @@ qla82xx_clear_drv_active(struct qla_hw_data *ha) | |||
2280 | uint32_t drv_active; | 2288 | uint32_t drv_active; |
2281 | 2289 | ||
2282 | drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); | 2290 | drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); |
2283 | drv_active &= ~(1 << (ha->portnum * 4)); | 2291 | drv_active &= ~(QLA82XX_DRV_ACTIVE << (ha->portnum * 4)); |
2284 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active); | 2292 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active); |
2285 | } | 2293 | } |
2286 | 2294 | ||
@@ -2291,7 +2299,7 @@ qla82xx_need_reset(struct qla_hw_data *ha) | |||
2291 | int rval; | 2299 | int rval; |
2292 | 2300 | ||
2293 | drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE); | 2301 | drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE); |
2294 | rval = drv_state & (1 << (ha->portnum * 4)); | 2302 | rval = drv_state & (QLA82XX_DRVST_RST_RDY << (ha->portnum * 4)); |
2295 | return rval; | 2303 | return rval; |
2296 | } | 2304 | } |
2297 | 2305 | ||
@@ -2305,7 +2313,7 @@ qla82xx_set_rst_ready(struct qla_hw_data *ha) | |||
2305 | 2313 | ||
2306 | /* If reset value is all FF's, initialize DRV_STATE */ | 2314 | /* If reset value is all FF's, initialize DRV_STATE */ |
2307 | if (drv_state == 0xffffffff) { | 2315 | if (drv_state == 0xffffffff) { |
2308 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0); | 2316 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, QLA82XX_DRVST_NOT_RDY); |
2309 | drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE); | 2317 | drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE); |
2310 | } | 2318 | } |
2311 | drv_state |= (QLA82XX_DRVST_RST_RDY << (ha->portnum * 4)); | 2319 | drv_state |= (QLA82XX_DRVST_RST_RDY << (ha->portnum * 4)); |
@@ -2335,7 +2343,8 @@ qla82xx_set_qsnt_ready(struct qla_hw_data *ha) | |||
2335 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state); | 2343 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state); |
2336 | } | 2344 | } |
2337 | 2345 | ||
2338 | int qla82xx_load_fw(scsi_qla_host_t *vha) | 2346 | static int |
2347 | qla82xx_load_fw(scsi_qla_host_t *vha) | ||
2339 | { | 2348 | { |
2340 | int rst; | 2349 | int rst; |
2341 | struct fw_blob *blob; | 2350 | struct fw_blob *blob; |
@@ -2411,7 +2420,7 @@ fw_load_failed: | |||
2411 | return QLA_FUNCTION_FAILED; | 2420 | return QLA_FUNCTION_FAILED; |
2412 | } | 2421 | } |
2413 | 2422 | ||
2414 | static int | 2423 | int |
2415 | qla82xx_start_firmware(scsi_qla_host_t *vha) | 2424 | qla82xx_start_firmware(scsi_qla_host_t *vha) |
2416 | { | 2425 | { |
2417 | int pcie_cap; | 2426 | int pcie_cap; |
@@ -2419,7 +2428,7 @@ qla82xx_start_firmware(scsi_qla_host_t *vha) | |||
2419 | struct qla_hw_data *ha = vha->hw; | 2428 | struct qla_hw_data *ha = vha->hw; |
2420 | 2429 | ||
2421 | /* scrub dma mask expansion register */ | 2430 | /* scrub dma mask expansion register */ |
2422 | qla82xx_wr_32(ha, CRB_DMA_SHIFT, 0x55555555); | 2431 | qla82xx_wr_32(ha, CRB_DMA_SHIFT, QLA82XX_DMA_SHIFT_VALUE); |
2423 | 2432 | ||
2424 | /* Put both the PEG CMD and RCV PEG to default state | 2433 | /* Put both the PEG CMD and RCV PEG to default state |
2425 | * of 0 before resetting the hardware | 2434 | * of 0 before resetting the hardware |
@@ -2882,7 +2891,7 @@ queuing_error: | |||
2882 | return QLA_FUNCTION_FAILED; | 2891 | return QLA_FUNCTION_FAILED; |
2883 | } | 2892 | } |
2884 | 2893 | ||
2885 | uint32_t * | 2894 | static uint32_t * |
2886 | qla82xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | 2895 | qla82xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, |
2887 | uint32_t length) | 2896 | uint32_t length) |
2888 | { | 2897 | { |
@@ -2903,7 +2912,7 @@ done_read: | |||
2903 | return dwptr; | 2912 | return dwptr; |
2904 | } | 2913 | } |
2905 | 2914 | ||
2906 | int | 2915 | static int |
2907 | qla82xx_unprotect_flash(struct qla_hw_data *ha) | 2916 | qla82xx_unprotect_flash(struct qla_hw_data *ha) |
2908 | { | 2917 | { |
2909 | int ret; | 2918 | int ret; |
@@ -2934,7 +2943,7 @@ done_unprotect: | |||
2934 | return ret; | 2943 | return ret; |
2935 | } | 2944 | } |
2936 | 2945 | ||
2937 | int | 2946 | static int |
2938 | qla82xx_protect_flash(struct qla_hw_data *ha) | 2947 | qla82xx_protect_flash(struct qla_hw_data *ha) |
2939 | { | 2948 | { |
2940 | int ret; | 2949 | int ret; |
@@ -2963,7 +2972,7 @@ done_protect: | |||
2963 | return ret; | 2972 | return ret; |
2964 | } | 2973 | } |
2965 | 2974 | ||
2966 | int | 2975 | static int |
2967 | qla82xx_erase_sector(struct qla_hw_data *ha, int addr) | 2976 | qla82xx_erase_sector(struct qla_hw_data *ha, int addr) |
2968 | { | 2977 | { |
2969 | int ret = 0; | 2978 | int ret = 0; |
@@ -3156,6 +3165,20 @@ qla82xx_start_iocbs(srb_t *sp) | |||
3156 | } | 3165 | } |
3157 | } | 3166 | } |
3158 | 3167 | ||
3168 | void qla82xx_rom_lock_recovery(struct qla_hw_data *ha) | ||
3169 | { | ||
3170 | if (qla82xx_rom_lock(ha)) | ||
3171 | /* Someone else is holding the lock. */ | ||
3172 | qla_printk(KERN_INFO, ha, "Resetting rom_lock\n"); | ||
3173 | |||
3174 | /* | ||
3175 | * Either we got the lock, or someone | ||
3176 | * else died while holding it. | ||
3177 | * In either case, unlock. | ||
3178 | */ | ||
3179 | qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK)); | ||
3180 | } | ||
3181 | |||
3159 | /* | 3182 | /* |
3160 | * qla82xx_device_bootstrap | 3183 | * qla82xx_device_bootstrap |
3161 | * Initialize device, set DEV_READY, start fw | 3184 | * Initialize device, set DEV_READY, start fw |
@@ -3170,12 +3193,13 @@ qla82xx_start_iocbs(srb_t *sp) | |||
3170 | static int | 3193 | static int |
3171 | qla82xx_device_bootstrap(scsi_qla_host_t *vha) | 3194 | qla82xx_device_bootstrap(scsi_qla_host_t *vha) |
3172 | { | 3195 | { |
3173 | int rval, i, timeout; | 3196 | int rval = QLA_SUCCESS; |
3197 | int i, timeout; | ||
3174 | uint32_t old_count, count; | 3198 | uint32_t old_count, count; |
3175 | struct qla_hw_data *ha = vha->hw; | 3199 | struct qla_hw_data *ha = vha->hw; |
3200 | int need_reset = 0, peg_stuck = 1; | ||
3176 | 3201 | ||
3177 | if (qla82xx_need_reset(ha)) | 3202 | need_reset = qla82xx_need_reset(ha); |
3178 | goto dev_initialize; | ||
3179 | 3203 | ||
3180 | old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); | 3204 | old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); |
3181 | 3205 | ||
@@ -3189,9 +3213,27 @@ qla82xx_device_bootstrap(scsi_qla_host_t *vha) | |||
3189 | 3213 | ||
3190 | count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); | 3214 | count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); |
3191 | if (count != old_count) | 3215 | if (count != old_count) |
3216 | peg_stuck = 0; | ||
3217 | } | ||
3218 | |||
3219 | if (need_reset) { | ||
3220 | /* We are trying to perform a recovery here. */ | ||
3221 | if (peg_stuck) | ||
3222 | qla82xx_rom_lock_recovery(ha); | ||
3223 | goto dev_initialize; | ||
3224 | } else { | ||
3225 | /* Start of day for this ha context. */ | ||
3226 | if (peg_stuck) { | ||
3227 | /* Either we are the first or recovery in progress. */ | ||
3228 | qla82xx_rom_lock_recovery(ha); | ||
3229 | goto dev_initialize; | ||
3230 | } else | ||
3231 | /* Firmware already running. */ | ||
3192 | goto dev_ready; | 3232 | goto dev_ready; |
3193 | } | 3233 | } |
3194 | 3234 | ||
3235 | return rval; | ||
3236 | |||
3195 | dev_initialize: | 3237 | dev_initialize: |
3196 | /* set to DEV_INITIALIZING */ | 3238 | /* set to DEV_INITIALIZING */ |
3197 | qla_printk(KERN_INFO, ha, "HW State: INITIALIZING\n"); | 3239 | qla_printk(KERN_INFO, ha, "HW State: INITIALIZING\n"); |
@@ -3304,6 +3346,9 @@ qla82xx_check_fw_alive(scsi_qla_host_t *vha) | |||
3304 | struct qla_hw_data *ha = vha->hw; | 3346 | struct qla_hw_data *ha = vha->hw; |
3305 | 3347 | ||
3306 | fw_heartbeat_counter = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); | 3348 | fw_heartbeat_counter = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); |
3349 | /* all 0xff, assume AER/EEH in progress, ignore */ | ||
3350 | if (fw_heartbeat_counter == 0xffffffff) | ||
3351 | return; | ||
3307 | if (vha->fw_heartbeat_counter == fw_heartbeat_counter) { | 3352 | if (vha->fw_heartbeat_counter == fw_heartbeat_counter) { |
3308 | vha->seconds_since_last_heartbeat++; | 3353 | vha->seconds_since_last_heartbeat++; |
3309 | /* FW not alive after 2 seconds */ | 3354 | /* FW not alive after 2 seconds */ |
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h index 15559cab39f8..51ec0c5380e8 100644 --- a/drivers/scsi/qla2xxx/qla_nx.h +++ b/drivers/scsi/qla2xxx/qla_nx.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #define CRB_RCVPEG_STATE QLA82XX_REG(0x13c) | 26 | #define CRB_RCVPEG_STATE QLA82XX_REG(0x13c) |
27 | #define BOOT_LOADER_DIMM_STATUS QLA82XX_REG(0x54) | 27 | #define BOOT_LOADER_DIMM_STATUS QLA82XX_REG(0x54) |
28 | #define CRB_DMA_SHIFT QLA82XX_REG(0xcc) | 28 | #define CRB_DMA_SHIFT QLA82XX_REG(0xcc) |
29 | #define QLA82XX_DMA_SHIFT_VALUE 0x55555555 | ||
29 | 30 | ||
30 | #define QLA82XX_HW_H0_CH_HUB_ADR 0x05 | 31 | #define QLA82XX_HW_H0_CH_HUB_ADR 0x05 |
31 | #define QLA82XX_HW_H1_CH_HUB_ADR 0x0E | 32 | #define QLA82XX_HW_H1_CH_HUB_ADR 0x0E |
@@ -583,6 +584,10 @@ | |||
583 | #define QLA82XX_DRVST_RST_RDY 1 | 584 | #define QLA82XX_DRVST_RST_RDY 1 |
584 | #define QLA82XX_DRVST_QSNT_RDY 2 | 585 | #define QLA82XX_DRVST_QSNT_RDY 2 |
585 | 586 | ||
587 | /* Different drive active state */ | ||
588 | #define QLA82XX_DRV_NOT_ACTIVE 0 | ||
589 | #define QLA82XX_DRV_ACTIVE 1 | ||
590 | |||
586 | /* | 591 | /* |
587 | * The PCI VendorID and DeviceID for our board. | 592 | * The PCI VendorID and DeviceID for our board. |
588 | */ | 593 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 9946fac54255..800ea9269752 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1295,17 +1295,12 @@ static int | |||
1295 | qla2xxx_slave_configure(struct scsi_device *sdev) | 1295 | qla2xxx_slave_configure(struct scsi_device *sdev) |
1296 | { | 1296 | { |
1297 | scsi_qla_host_t *vha = shost_priv(sdev->host); | 1297 | scsi_qla_host_t *vha = shost_priv(sdev->host); |
1298 | struct qla_hw_data *ha = vha->hw; | ||
1299 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); | ||
1300 | struct req_que *req = vha->req; | 1298 | struct req_que *req = vha->req; |
1301 | 1299 | ||
1302 | if (sdev->tagged_supported) | 1300 | if (sdev->tagged_supported) |
1303 | scsi_activate_tcq(sdev, req->max_q_depth); | 1301 | scsi_activate_tcq(sdev, req->max_q_depth); |
1304 | else | 1302 | else |
1305 | scsi_deactivate_tcq(sdev, req->max_q_depth); | 1303 | scsi_deactivate_tcq(sdev, req->max_q_depth); |
1306 | |||
1307 | rport->dev_loss_tmo = ha->port_down_retry_count; | ||
1308 | |||
1309 | return 0; | 1304 | return 0; |
1310 | } | 1305 | } |
1311 | 1306 | ||
@@ -2141,8 +2136,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2141 | else | 2136 | else |
2142 | base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER + | 2137 | base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER + |
2143 | base_vha->vp_idx; | 2138 | base_vha->vp_idx; |
2144 | if (IS_QLA2100(ha)) | 2139 | |
2145 | host->sg_tablesize = 32; | 2140 | /* Set the SG table size based on ISP type */ |
2141 | if (!IS_FWI2_CAPABLE(ha)) { | ||
2142 | if (IS_QLA2100(ha)) | ||
2143 | host->sg_tablesize = 32; | ||
2144 | } else { | ||
2145 | if (!IS_QLA82XX(ha)) | ||
2146 | host->sg_tablesize = QLA_SG_ALL; | ||
2147 | } | ||
2148 | |||
2146 | host->max_id = max_id; | 2149 | host->max_id = max_id; |
2147 | host->this_id = 255; | 2150 | host->this_id = 255; |
2148 | host->cmd_per_lun = 3; | 2151 | host->cmd_per_lun = 3; |
@@ -3553,6 +3556,11 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
3553 | struct qla_hw_data *ha = vha->hw; | 3556 | struct qla_hw_data *ha = vha->hw; |
3554 | struct req_que *req; | 3557 | struct req_que *req; |
3555 | 3558 | ||
3559 | if (ha->flags.eeh_busy) { | ||
3560 | qla2x00_restart_timer(vha, WATCH_INTERVAL); | ||
3561 | return; | ||
3562 | } | ||
3563 | |||
3556 | if (IS_QLA82XX(ha)) | 3564 | if (IS_QLA82XX(ha)) |
3557 | qla82xx_watchdog(vha); | 3565 | qla82xx_watchdog(vha); |
3558 | 3566 | ||
@@ -3782,8 +3790,21 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | |||
3782 | return PCI_ERS_RESULT_CAN_RECOVER; | 3790 | return PCI_ERS_RESULT_CAN_RECOVER; |
3783 | case pci_channel_io_frozen: | 3791 | case pci_channel_io_frozen: |
3784 | ha->flags.eeh_busy = 1; | 3792 | ha->flags.eeh_busy = 1; |
3793 | /* For ISP82XX complete any pending mailbox cmd */ | ||
3794 | if (IS_QLA82XX(ha)) { | ||
3795 | ha->flags.fw_hung = 1; | ||
3796 | if (ha->flags.mbox_busy) { | ||
3797 | ha->flags.mbox_int = 1; | ||
3798 | DEBUG2(qla_printk(KERN_ERR, ha, | ||
3799 | "Due to pci channel io frozen, doing premature " | ||
3800 | "completion of mbx command\n")); | ||
3801 | complete(&ha->mbx_intr_comp); | ||
3802 | } | ||
3803 | } | ||
3785 | qla2x00_free_irqs(vha); | 3804 | qla2x00_free_irqs(vha); |
3786 | pci_disable_device(pdev); | 3805 | pci_disable_device(pdev); |
3806 | /* Return back all IOs */ | ||
3807 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); | ||
3787 | return PCI_ERS_RESULT_NEED_RESET; | 3808 | return PCI_ERS_RESULT_NEED_RESET; |
3788 | case pci_channel_io_perm_failure: | 3809 | case pci_channel_io_perm_failure: |
3789 | ha->flags.pci_channel_io_perm_failure = 1; | 3810 | ha->flags.pci_channel_io_perm_failure = 1; |
@@ -3804,6 +3825,9 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) | |||
3804 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 3825 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
3805 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; | 3826 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; |
3806 | 3827 | ||
3828 | if (IS_QLA82XX(ha)) | ||
3829 | return PCI_ERS_RESULT_RECOVERED; | ||
3830 | |||
3807 | spin_lock_irqsave(&ha->hardware_lock, flags); | 3831 | spin_lock_irqsave(&ha->hardware_lock, flags); |
3808 | if (IS_QLA2100(ha) || IS_QLA2200(ha)){ | 3832 | if (IS_QLA2100(ha) || IS_QLA2200(ha)){ |
3809 | stat = RD_REG_DWORD(®->hccr); | 3833 | stat = RD_REG_DWORD(®->hccr); |
@@ -3830,6 +3854,109 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) | |||
3830 | return PCI_ERS_RESULT_RECOVERED; | 3854 | return PCI_ERS_RESULT_RECOVERED; |
3831 | } | 3855 | } |
3832 | 3856 | ||
3857 | uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha) | ||
3858 | { | ||
3859 | uint32_t rval = QLA_FUNCTION_FAILED; | ||
3860 | uint32_t drv_active = 0; | ||
3861 | struct qla_hw_data *ha = base_vha->hw; | ||
3862 | int fn; | ||
3863 | struct pci_dev *other_pdev = NULL; | ||
3864 | |||
3865 | DEBUG17(qla_printk(KERN_INFO, ha, | ||
3866 | "scsi(%ld): In qla82xx_error_recovery\n", base_vha->host_no)); | ||
3867 | |||
3868 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | ||
3869 | |||
3870 | if (base_vha->flags.online) { | ||
3871 | /* Abort all outstanding commands, | ||
3872 | * so as to be requeued later */ | ||
3873 | qla2x00_abort_isp_cleanup(base_vha); | ||
3874 | } | ||
3875 | |||
3876 | |||
3877 | fn = PCI_FUNC(ha->pdev->devfn); | ||
3878 | while (fn > 0) { | ||
3879 | fn--; | ||
3880 | DEBUG17(qla_printk(KERN_INFO, ha, | ||
3881 | "Finding pci device at function = 0x%x\n", fn)); | ||
3882 | other_pdev = | ||
3883 | pci_get_domain_bus_and_slot(pci_domain_nr(ha->pdev->bus), | ||
3884 | ha->pdev->bus->number, PCI_DEVFN(PCI_SLOT(ha->pdev->devfn), | ||
3885 | fn)); | ||
3886 | |||
3887 | if (!other_pdev) | ||
3888 | continue; | ||
3889 | if (atomic_read(&other_pdev->enable_cnt)) { | ||
3890 | DEBUG17(qla_printk(KERN_INFO, ha, | ||
3891 | "Found PCI func availabe and enabled at 0x%x\n", | ||
3892 | fn)); | ||
3893 | pci_dev_put(other_pdev); | ||
3894 | break; | ||
3895 | } | ||
3896 | pci_dev_put(other_pdev); | ||
3897 | } | ||
3898 | |||
3899 | if (!fn) { | ||
3900 | /* Reset owner */ | ||
3901 | DEBUG17(qla_printk(KERN_INFO, ha, | ||
3902 | "This devfn is reset owner = 0x%x\n", ha->pdev->devfn)); | ||
3903 | qla82xx_idc_lock(ha); | ||
3904 | |||
3905 | qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | ||
3906 | QLA82XX_DEV_INITIALIZING); | ||
3907 | |||
3908 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, | ||
3909 | QLA82XX_IDC_VERSION); | ||
3910 | |||
3911 | drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); | ||
3912 | DEBUG17(qla_printk(KERN_INFO, ha, | ||
3913 | "drv_active = 0x%x\n", drv_active)); | ||
3914 | |||
3915 | qla82xx_idc_unlock(ha); | ||
3916 | /* Reset if device is not already reset | ||
3917 | * drv_active would be 0 if a reset has already been done | ||
3918 | */ | ||
3919 | if (drv_active) | ||
3920 | rval = qla82xx_start_firmware(base_vha); | ||
3921 | else | ||
3922 | rval = QLA_SUCCESS; | ||
3923 | qla82xx_idc_lock(ha); | ||
3924 | |||
3925 | if (rval != QLA_SUCCESS) { | ||
3926 | qla_printk(KERN_INFO, ha, "HW State: FAILED\n"); | ||
3927 | qla82xx_clear_drv_active(ha); | ||
3928 | qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | ||
3929 | QLA82XX_DEV_FAILED); | ||
3930 | } else { | ||
3931 | qla_printk(KERN_INFO, ha, "HW State: READY\n"); | ||
3932 | qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | ||
3933 | QLA82XX_DEV_READY); | ||
3934 | qla82xx_idc_unlock(ha); | ||
3935 | ha->flags.fw_hung = 0; | ||
3936 | rval = qla82xx_restart_isp(base_vha); | ||
3937 | qla82xx_idc_lock(ha); | ||
3938 | /* Clear driver state register */ | ||
3939 | qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0); | ||
3940 | qla82xx_set_drv_active(base_vha); | ||
3941 | } | ||
3942 | qla82xx_idc_unlock(ha); | ||
3943 | } else { | ||
3944 | DEBUG17(qla_printk(KERN_INFO, ha, | ||
3945 | "This devfn is not reset owner = 0x%x\n", ha->pdev->devfn)); | ||
3946 | if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == | ||
3947 | QLA82XX_DEV_READY)) { | ||
3948 | ha->flags.fw_hung = 0; | ||
3949 | rval = qla82xx_restart_isp(base_vha); | ||
3950 | qla82xx_idc_lock(ha); | ||
3951 | qla82xx_set_drv_active(base_vha); | ||
3952 | qla82xx_idc_unlock(ha); | ||
3953 | } | ||
3954 | } | ||
3955 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | ||
3956 | |||
3957 | return rval; | ||
3958 | } | ||
3959 | |||
3833 | static pci_ers_result_t | 3960 | static pci_ers_result_t |
3834 | qla2xxx_pci_slot_reset(struct pci_dev *pdev) | 3961 | qla2xxx_pci_slot_reset(struct pci_dev *pdev) |
3835 | { | 3962 | { |
@@ -3862,15 +3989,23 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
3862 | if (rc) { | 3989 | if (rc) { |
3863 | qla_printk(KERN_WARNING, ha, | 3990 | qla_printk(KERN_WARNING, ha, |
3864 | "Can't re-enable PCI device after reset.\n"); | 3991 | "Can't re-enable PCI device after reset.\n"); |
3865 | return ret; | 3992 | goto exit_slot_reset; |
3866 | } | 3993 | } |
3867 | 3994 | ||
3868 | rsp = ha->rsp_q_map[0]; | 3995 | rsp = ha->rsp_q_map[0]; |
3869 | if (qla2x00_request_irqs(ha, rsp)) | 3996 | if (qla2x00_request_irqs(ha, rsp)) |
3870 | return ret; | 3997 | goto exit_slot_reset; |
3871 | 3998 | ||
3872 | if (ha->isp_ops->pci_config(base_vha)) | 3999 | if (ha->isp_ops->pci_config(base_vha)) |
3873 | return ret; | 4000 | goto exit_slot_reset; |
4001 | |||
4002 | if (IS_QLA82XX(ha)) { | ||
4003 | if (qla82xx_error_recovery(base_vha) == QLA_SUCCESS) { | ||
4004 | ret = PCI_ERS_RESULT_RECOVERED; | ||
4005 | goto exit_slot_reset; | ||
4006 | } else | ||
4007 | goto exit_slot_reset; | ||
4008 | } | ||
3874 | 4009 | ||
3875 | while (ha->flags.mbox_busy && retries--) | 4010 | while (ha->flags.mbox_busy && retries--) |
3876 | msleep(1000); | 4011 | msleep(1000); |
@@ -3881,6 +4016,7 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
3881 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | 4016 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
3882 | 4017 | ||
3883 | 4018 | ||
4019 | exit_slot_reset: | ||
3884 | DEBUG17(qla_printk(KERN_WARNING, ha, | 4020 | DEBUG17(qla_printk(KERN_WARNING, ha, |
3885 | "slot_reset-return:ret=%x\n", ret)); | 4021 | "slot_reset-return:ret=%x\n", ret)); |
3886 | 4022 | ||