aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-22 20:34:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-22 20:34:15 -0400
commitc70b5296e775cde46cfcb2d860ba160108a5ec7a (patch)
tree30419cb982acca44499236adcca65f2f87698c74 /drivers/scsi/qla2xxx
parent80c226fbef56576946c9655fcb2ab62e63404d12 (diff)
parent58ff4bd042adf8013c8f70fd03c2c0f8d022e387 (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.c30
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h8
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h15
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c54
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c66
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c431
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c156
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
1559static void 1559static void
@@ -1676,14 +1676,14 @@ static void
1676qla2x00_get_host_fabric_name(struct Scsi_Host *shost) 1676qla2x00_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
1689static void 1689static 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
3006enum nexus_wait_type { 3014enum 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 *);
352extern int 352extern int
353qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); 353qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t);
354 354
355extern int
356qla81xx_write_mpi_register(scsi_qla_host_t *, uint16_t *);
355extern int qla2x00_get_data_rate(scsi_qla_host_t *); 357extern int qla2x00_get_data_rate(scsi_qla_host_t *);
356extern int qla24xx_set_fcp_prio(scsi_qla_host_t *, uint16_t, uint16_t, 358extern 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 */
502extern int qla82xx_pci_config(struct scsi_qla_host *); 504extern int qla82xx_pci_config(struct scsi_qla_host *);
503extern int qla82xx_pci_mem_read_2M(struct qla_hw_data *, u64, void *, int); 505extern int qla82xx_pci_mem_read_2M(struct qla_hw_data *, u64, void *, int);
504extern int qla82xx_pci_mem_write_2M(struct qla_hw_data *, u64, void *, int);
505extern char *qla82xx_pci_info_str(struct scsi_qla_host *, char *); 506extern char *qla82xx_pci_info_str(struct scsi_qla_host *, char *);
506extern int qla82xx_pci_region_offset(struct pci_dev *, int); 507extern int qla82xx_pci_region_offset(struct pci_dev *, int);
507extern int qla82xx_iospace_config(struct qla_hw_data *); 508extern 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 */
510extern void qla82xx_reset_chip(struct scsi_qla_host *); 511extern void qla82xx_reset_chip(struct scsi_qla_host *);
511extern void qla82xx_config_rings(struct scsi_qla_host *); 512extern void qla82xx_config_rings(struct scsi_qla_host *);
512extern int qla82xx_pinit_from_rom(scsi_qla_host_t *);
513extern void qla82xx_watchdog(scsi_qla_host_t *); 513extern void qla82xx_watchdog(scsi_qla_host_t *);
514extern int qla82xx_start_firmware(scsi_qla_host_t *);
514 515
515/* Firmware and flash related functions */ 516/* Firmware and flash related functions */
516extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *); 517extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *);
@@ -533,25 +534,17 @@ extern irqreturn_t qla82xx_msix_default(int, void *);
533extern irqreturn_t qla82xx_msix_rsp_q(int, void *); 534extern irqreturn_t qla82xx_msix_rsp_q(int, void *);
534extern void qla82xx_enable_intrs(struct qla_hw_data *); 535extern void qla82xx_enable_intrs(struct qla_hw_data *);
535extern void qla82xx_disable_intrs(struct qla_hw_data *); 536extern void qla82xx_disable_intrs(struct qla_hw_data *);
536extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t);
537extern void qla82xx_poll(int, void *); 537extern void qla82xx_poll(int, void *);
538extern void qla82xx_init_flags(struct qla_hw_data *); 538extern void qla82xx_init_flags(struct qla_hw_data *);
539 539
540/* ISP 8021 hardware related */ 540/* ISP 8021 hardware related */
541extern int qla82xx_crb_win_lock(struct qla_hw_data *); 541extern void qla82xx_set_drv_active(scsi_qla_host_t *);
542extern void qla82xx_crb_win_unlock(struct qla_hw_data *); 542extern void qla82xx_crb_win_unlock(struct qla_hw_data *);
543extern int qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *, ulong *);
544extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32); 543extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32);
545extern int qla82xx_rd_32(struct qla_hw_data *, ulong); 544extern int qla82xx_rd_32(struct qla_hw_data *, ulong);
546extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int); 545extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int);
547extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int); 546extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int);
548extern int qla82xx_check_for_bad_spd(struct qla_hw_data *);
549extern int qla82xx_load_fw(scsi_qla_host_t *);
550extern int qla82xx_rom_lock(struct qla_hw_data *);
551extern void qla82xx_rom_unlock(struct qla_hw_data *); 547extern void qla82xx_rom_unlock(struct qla_hw_data *);
552extern int qla82xx_rom_fast_read(struct qla_hw_data *, int , int *);
553extern int qla82xx_do_rom_fast_read(struct qla_hw_data *, int, int *);
554extern unsigned long qla82xx_decode_crb_addr(unsigned long);
555 548
556/* ISP 8021 IDC */ 549/* ISP 8021 IDC */
557extern void qla82xx_clear_drv_active(struct qla_hw_data *); 550extern 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 */
961int
962qla81xx_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(&reg->hccr, HCCRX_SET_RISC_RESET); 1034 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
1004 RD_REG_DWORD(&reg->hccr); 1035 RD_REG_DWORD(&reg->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
3896int 3895int
3897qla84xx_reset_chip(scsi_qla_host_t *ha, uint16_t enable_diagnostic) 3896qla84xx_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
3955int 3954int
3955qla81xx_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(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
3972 WRT_REG_WORD(&reg->mailbox1, mb[0]);
3973 WRT_REG_WORD(&reg->mailbox2, mb[1]);
3974 WRT_REG_WORD(&reg->mailbox3, mb[2]);
3975 WRT_REG_WORD(&reg->mailbox4, mb[3]);
3976
3977 WRT_REG_DWORD(&reg->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(&reg->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(&reg->mailbox0);
3991 WRT_REG_DWORD(&reg->hccr,
3992 HCCRX_CLR_RISC_INT);
3993 RD_REG_DWORD(&reg->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}
4015int
3956qla2x00_get_data_rate(scsi_qla_host_t *vha) 4016qla2x00_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
406static int
407qla82xx_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
437static 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
406int 454int
407qla82xx_wr_32(struct qla_hw_data *ha, ulong off, u32 data) 455qla82xx_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
457int 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
475int qla82xx_idc_lock(struct qla_hw_data *ha) 505int 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
507int
508qla82xx_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
558int qla82xx_pci_set_window_warning_count; 558int qla82xx_pci_set_window_warning_count;
559 559
560unsigned long 560static unsigned long
561qla82xx_pci_set_window(struct qla_hw_data *ha, unsigned long long addr) 561qla82xx_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
801unsigned long qla82xx_decode_crb_addr(unsigned long addr) 801static unsigned long
802qla82xx_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)
824static long rom_max_timeout = 100; 825static long rom_max_timeout = 100;
825static long qla82xx_rom_lock_timeout = 100; 826static long qla82xx_rom_lock_timeout = 100;
826 827
827int 828static int
828qla82xx_rom_lock(struct qla_hw_data *ha) 829qla82xx_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
845int 846static int
846qla82xx_wait_rom_busy(struct qla_hw_data *ha) 847qla82xx_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
865int 866static int
866qla82xx_wait_rom_done(struct qla_hw_data *ha) 867qla82xx_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
885int 886static int
886qla82xx_do_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) 887qla82xx_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
908int 909static int
909qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) 910qla82xx_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
929int 930static int
930qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val) 931qla82xx_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
943int 944static int
944qla82xx_flash_wait_write_finish(struct qla_hw_data *ha) 945qla82xx_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
967int 968static int
968qla82xx_flash_set_write_enable(struct qla_hw_data *ha) 969qla82xx_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
984int 985static int
985qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val) 986qla82xx_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
999int 1000static int
1000qla82xx_write_disable_flash(struct qla_hw_data *ha) 1001qla82xx_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
1011int 1012static int
1012ql82xx_rom_lock_d(struct qla_hw_data *ha) 1013ql82xx_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
1027int 1028static int
1028qla82xx_write_flash_dword(struct qla_hw_data *ha, uint32_t flashaddr, 1029qla82xx_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 */
1064int qla82xx_pinit_from_rom(scsi_qla_host_t *vha) 1065static int
1066qla82xx_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
1210int qla82xx_check_for_bad_spd(struct qla_hw_data *ha) 1212static int
1213qla82xx_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
1228int 1231static int
1232qla82xx_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
1340static int
1229qla82xx_fw_load_from_flash(struct qla_hw_data *ha) 1341qla82xx_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
1360int
1361qla82xx_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
1469static struct qla82xx_uri_table_desc * 1473static struct qla82xx_uri_table_desc *
1470qla82xx_get_table_desc(const u8 *unirom, int section) 1474qla82xx_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
1728int qla82xx_fw_load_from_blob(struct qla_hw_data *ha) 1732static int
1733qla82xx_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
1839int qla82xx_check_cmdpeg_state(struct qla_hw_data *ha) 1844static int
1845qla82xx_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
1877int qla82xx_check_rcvpeg_state(struct qla_hw_data *ha) 1883static int
1884qla82xx_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 */
1936void 1943static void
1937qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) 1944qla82xx_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
2260static inline void 2267inline void
2261qla82xx_set_drv_active(scsi_qla_host_t *vha) 2268qla82xx_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
2338int qla82xx_load_fw(scsi_qla_host_t *vha) 2346static int
2347qla82xx_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
2414static int 2423int
2415qla82xx_start_firmware(scsi_qla_host_t *vha) 2424qla82xx_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
2885uint32_t * 2894static uint32_t *
2886qla82xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, 2895qla82xx_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
2906int 2915static int
2907qla82xx_unprotect_flash(struct qla_hw_data *ha) 2916qla82xx_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
2937int 2946static int
2938qla82xx_protect_flash(struct qla_hw_data *ha) 2947qla82xx_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
2966int 2975static int
2967qla82xx_erase_sector(struct qla_hw_data *ha, int addr) 2976qla82xx_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
3168void 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)
3170static int 3193static int
3171qla82xx_device_bootstrap(scsi_qla_host_t *vha) 3194qla82xx_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
3195dev_initialize: 3237dev_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
1295qla2xxx_slave_configure(struct scsi_device *sdev) 1295qla2xxx_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(&reg->hccr); 3833 stat = RD_REG_DWORD(&reg->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
3857uint32_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
3833static pci_ers_result_t 3960static pci_ers_result_t
3834qla2xxx_pci_slot_reset(struct pci_dev *pdev) 3961qla2xxx_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
4019exit_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