aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMadhuranath Iyengar <madhuranath.iyengar@qlogic.com>2010-09-03 18:20:54 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-09-05 14:35:01 -0400
commitb1d46989c12ec4d93f274ca8378bb1a6014d244a (patch)
tree3bcae91b1470f09add485e7fcfa5a149d206e29d
parentbddd2d65a48c492d3e585e65df0be89c58b4acda (diff)
[SCSI] qla2xxx: Handle MPI timeout indicated by AE8002
In case the MPI times out, the FW issues an async event AE8002 to indicate this to every FCoE function. The FC/FCoE driver is required to handle this, by doing a soft reset and issuing a Write MPI register mailbox command to reset the MPI. Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c31
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c61
5 files changed, 107 insertions, 1 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 3a432ea0c7a3..ee15f4f10fec 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
@@ -2858,6 +2863,7 @@ typedef struct scsi_qla_host {
2858#define NPIV_CONFIG_NEEDED 16 2863#define NPIV_CONFIG_NEEDED 16
2859#define ISP_UNRECOVERABLE 17 2864#define ISP_UNRECOVERABLE 17
2860#define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */ 2865#define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */
2866#define MPI_RESET_NEEDED 19 /* Initiate MPI FW reset */
2861 2867
2862 uint32_t device_flags; 2868 uint32_t device_flags;
2863#define SWITCH_FOUND BIT_0 2869#define SWITCH_FOUND BIT_0
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 967bc9278bf7..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 *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f2da5c5dacdd..c2d7bb8cd53f 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -944,6 +944,19 @@ qla2x00_reset_chip(scsi_qla_host_t *vha)
944} 944}
945 945
946/** 946/**
947 * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC.
948 *
949 * Returns 0 on success.
950 */
951int
952qla81xx_reset_mpi(scsi_qla_host_t *vha)
953{
954 uint16_t mb[4] = {0x1010, 0, 1, 0};
955
956 return qla81xx_write_mpi_register(vha, mb);
957}
958
959/**
947 * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC. 960 * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC.
948 * @ha: HA context 961 * @ha: HA context
949 * 962 *
@@ -957,6 +970,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
957 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 970 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
958 uint32_t cnt, d2; 971 uint32_t cnt, d2;
959 uint16_t wd; 972 uint16_t wd;
973 static int abts_cnt; /* ISP abort retry counts */
960 974
961 spin_lock_irqsave(&ha->hardware_lock, flags); 975 spin_lock_irqsave(&ha->hardware_lock, flags);
962 976
@@ -990,6 +1004,23 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
990 barrier(); 1004 barrier();
991 } 1005 }
992 1006
1007 /* If required, do an MPI FW reset now */
1008 if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) {
1009 if (qla81xx_reset_mpi(vha) != QLA_SUCCESS) {
1010 if (++abts_cnt < 5) {
1011 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1012 set_bit(MPI_RESET_NEEDED, &vha->dpc_flags);
1013 } else {
1014 /*
1015 * We exhausted the ISP abort retries. We have to
1016 * set the board offline.
1017 */
1018 abts_cnt = 0;
1019 vha->flags.online = 0;
1020 }
1021 }
1022 }
1023
993 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET); 1024 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
994 RD_REG_DWORD(&reg->hccr); 1025 RD_REG_DWORD(&reg->hccr);
995 1026
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 6982ba70e12a..bb4d63a792aa 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 d0413d56887c..52024080c393 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3949,6 +3949,67 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
3949} 3949}
3950 3950
3951int 3951int
3952qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
3953{
3954 int rval;
3955 uint32_t stat, timer;
3956 uint16_t mb0 = 0;
3957 struct qla_hw_data *ha = vha->hw;
3958 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3959
3960 rval = QLA_SUCCESS;
3961
3962 DEBUG11(qla_printk(KERN_INFO, ha,
3963 "%s(%ld): entered.\n", __func__, vha->host_no));
3964
3965 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
3966
3967 /* Write the MBC data to the registers */
3968 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
3969 WRT_REG_WORD(&reg->mailbox1, mb[0]);
3970 WRT_REG_WORD(&reg->mailbox2, mb[1]);
3971 WRT_REG_WORD(&reg->mailbox3, mb[2]);
3972 WRT_REG_WORD(&reg->mailbox4, mb[3]);
3973
3974 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
3975
3976 /* Poll for MBC interrupt */
3977 for (timer = 6000000; timer; timer--) {
3978 /* Check for pending interrupts. */
3979 stat = RD_REG_DWORD(&reg->host_status);
3980 if (stat & HSRX_RISC_INT) {
3981 stat &= 0xff;
3982
3983 if (stat == 0x1 || stat == 0x2 ||
3984 stat == 0x10 || stat == 0x11) {
3985 set_bit(MBX_INTERRUPT,
3986 &ha->mbx_cmd_flags);
3987 mb0 = RD_REG_WORD(&reg->mailbox0);
3988 WRT_REG_DWORD(&reg->hccr,
3989 HCCRX_CLR_RISC_INT);
3990 RD_REG_DWORD(&reg->hccr);
3991 break;
3992 }
3993 }
3994 udelay(5);
3995 }
3996
3997 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
3998 rval = mb0 & MBS_MASK;
3999 else
4000 rval = QLA_FUNCTION_FAILED;
4001
4002 if (rval != QLA_SUCCESS) {
4003 DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n",
4004 __func__, vha->host_no, rval, mb[0]));
4005 } else {
4006 DEBUG11(printk(KERN_INFO
4007 "%s(%ld): done.\n", __func__, vha->host_no));
4008 }
4009
4010 return rval;
4011}
4012int
3952qla2x00_get_data_rate(scsi_qla_host_t *vha) 4013qla2x00_get_data_rate(scsi_qla_host_t *vha)
3953{ 4014{
3954 int rval; 4015 int rval;