aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/Kconfig3
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c36
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c124
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h23
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h78
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h173
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h33
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c16
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c192
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h87
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c223
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c318
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c30
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c443
-rw-r--r--drivers/scsi/qla2xxx/qla_settings.h16
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c315
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h6
19 files changed, 1266 insertions, 857 deletions
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
index 8c865b9e02b..6208d562890 100644
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -16,7 +16,8 @@ config SCSI_QLA_FC
22xx ql2200_fw.bin
2300, 2312, 6312 ql2300_fw.bin
2322, 6322 ql2322_fw.bin
- 24xx ql2400_fw.bin
+ 24xx, 54xx ql2400_fw.bin
+ 25xx ql2500_fw.bin
Upon request, the driver caches the firmware image until
the driver is unloaded.
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 4894dc886b6..413d8cd6a32 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2005 QLogic Corporation
+ * Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -849,20 +849,20 @@ static void
qla2x00_get_host_speed(struct Scsi_Host *shost)
{
scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
- uint32_t speed = 0;
+ u32 speed = FC_PORTSPEED_UNKNOWN;
switch (ha->link_data_rate) {
case PORT_SPEED_1GB:
- speed = 1;
+ speed = FC_PORTSPEED_1GBIT;
break;
case PORT_SPEED_2GB:
- speed = 2;
+ speed = FC_PORTSPEED_2GBIT;
break;
case PORT_SPEED_4GB:
- speed = 4;
+ speed = FC_PORTSPEED_4GBIT;
break;
case PORT_SPEED_8GB:
- speed = 8;
+ speed = FC_PORTSPEED_8GBIT;
break;
}
fc_host_speed(shost) = speed;
@@ -900,7 +900,8 @@ qla2x00_get_starget_node_name(struct scsi_target *starget)
u64 node_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
- if (starget->id == fcport->os_target_id) {
+ if (fcport->rport &&
+ starget->id == fcport->rport->scsi_target_id) {
node_name = wwn_to_u64(fcport->node_name);
break;
}
@@ -918,7 +919,8 @@ qla2x00_get_starget_port_name(struct scsi_target *starget)
u64 port_name = 0;
list_for_each_entry(fcport, &ha->fcports, list) {
- if (starget->id == fcport->os_target_id) {
+ if (fcport->rport &&
+ starget->id == fcport->rport->scsi_target_id) {
port_name = wwn_to_u64(fcport->port_name);
break;
}
@@ -936,7 +938,8 @@ qla2x00_get_starget_port_id(struct scsi_target *starget)
uint32_t port_id = ~0U;
list_for_each_entry(fcport, &ha->fcports, list) {
- if (starget->id == fcport->os_target_id) {
+ if (fcport->rport &&
+ starget->id == fcport->rport->scsi_target_id) {
port_id = fcport->d_id.b.domain << 16 |
fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
break;
@@ -1196,6 +1199,7 @@ struct fc_function_template qla2xxx_transport_functions = {
.show_host_node_name = 1,
.show_host_port_name = 1,
.show_host_supported_classes = 1,
+ .show_host_supported_speeds = 1,
.get_host_port_id = qla2x00_get_host_port_id,
.show_host_port_id = 1,
@@ -1276,9 +1280,23 @@ struct fc_function_template qla2xxx_transport_vport_functions = {
void
qla2x00_init_host_attr(scsi_qla_host_t *ha)
{
+ u32 speed = FC_PORTSPEED_UNKNOWN;
+
fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;;
fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count;
+
+ if (IS_QLA25XX(ha))
+ speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
+ FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
+ else if (IS_QLA24XX_TYPE(ha))
+ speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
+ FC_PORTSPEED_1GBIT;
+ else if (IS_QLA23XX(ha))
+ speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
+ else
+ speed = FC_PORTSPEED_1GBIT;
+ fc_host_supported_speeds(ha->host) = speed;
}
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index d88e98c476b..9d12d9f2620 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2005 QLogic Corporation
+ * Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -1410,125 +1410,3 @@ qla2x00_dump_buffer(uint8_t * b, uint32_t size)
if (cnt % 16)
printk("\n");
}
-
-/**************************************************************************
- * qla2x00_print_scsi_cmd
- * Dumps out info about the scsi cmd and srb.
- * Input
- * cmd : struct scsi_cmnd
- **************************************************************************/
-void
-qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd)
-{
- int i;
- struct scsi_qla_host *ha;
- srb_t *sp;
-
- ha = shost_priv(cmd->device->host);
-
- sp = (srb_t *) cmd->SCp.ptr;
- printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble);
- printk(" chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n",
- cmd->device->channel, cmd->device->id, cmd->device->lun,
- cmd->cmd_len);
- printk(" CDB: ");
- for (i = 0; i < cmd->cmd_len; i++) {
- printk("0x%02x ", cmd->cmnd[i]);
- }
- printk("\n seg_cnt=%d, allowed=%d, retries=%d\n",
- scsi_sg_count(cmd), cmd->allowed, cmd->retries);
- printk(" request buffer=0x%p, request buffer len=0x%x\n",
- scsi_sglist(cmd), scsi_bufflen(cmd));
- printk(" tag=%d, transfersize=0x%x\n",
- cmd->tag, cmd->transfersize);
- printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp);
- printk(" data direction=%d\n", cmd->sc_data_direction);
-
- if (!sp)
- return;
-
- printk(" sp flags=0x%x\n", sp->flags);
-}
-
-#if defined(QL_DEBUG_ROUTINES)
-/*
- * qla2x00_formatted_dump_buffer
- * Prints string plus buffer.
- *
- * Input:
- * string = Null terminated string (no newline at end).
- * buffer = buffer address.
- * wd_size = word size 8, 16, 32 or 64 bits
- * count = number of words.
- */
-void
-qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer,
- uint8_t wd_size, uint32_t count)
-{
- uint32_t cnt;
- uint16_t *buf16;
- uint32_t *buf32;
-
- if (strcmp(string, "") != 0)
- printk("%s\n",string);
-
- switch (wd_size) {
- case 8:
- printk(" 0 1 2 3 4 5 6 7 "
- "8 9 Ah Bh Ch Dh Eh Fh\n");
- printk("-----------------------------------------"
- "-------------------------------------\n");
-
- for (cnt = 1; cnt <= count; cnt++, buffer++) {
- printk("%02x",*buffer);
- if (cnt % 16 == 0)
- printk("\n");
- else
- printk(" ");
- }
- if (cnt % 16 != 0)
- printk("\n");
- break;
- case 16:
- printk(" 0 2 4 6 8 Ah "
- " Ch Eh\n");
- printk("-----------------------------------------"
- "-------------\n");
-
- buf16 = (uint16_t *) buffer;
- for (cnt = 1; cnt <= count; cnt++, buf16++) {
- printk("%4x",*buf16);
-
- if (cnt % 8 == 0)
- printk("\n");
- else if (*buf16 < 10)
- printk(" ");
- else
- printk(" ");
- }
- if (cnt % 8 != 0)
- printk("\n");
- break;
- case 32:
- printk(" 0 4 8 Ch\n");
- printk("------------------------------------------\n");
-
- buf32 = (uint32_t *) buffer;
- for (cnt = 1; cnt <= count; cnt++, buf32++) {
- printk("%8x", *buf32);
-
- if (cnt % 4 == 0)
- printk("\n");
- else if (*buf32 < 10)
- printk(" ");
- else
- printk(" ");
- }
- if (cnt % 4 != 0)
- printk("\n");
- break;
- default:
- break;
- }
-}
-#endif
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index 524598afc81..2e9c0c097f5 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2005 QLogic Corporation
+ * Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -22,19 +22,7 @@
/* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */
/* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */
/* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */
-/*
- * Local Macro Definitions.
- */
-#if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \
- defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \
- defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \
- defined(QL_DEBUG_LEVEL_7) || defined(QL_DEBUG_LEVEL_8) || \
- defined(QL_DEBUG_LEVEL_9) || defined(QL_DEBUG_LEVEL_10) || \
- defined(QL_DEBUG_LEVEL_11) || defined(QL_DEBUG_LEVEL_12) || \
- defined(QL_DEBUG_LEVEL_13) || defined(QL_DEBUG_LEVEL_14) || \
- defined(QL_DEBUG_LEVEL_15)
- #define QL_DEBUG_ROUTINES
-#endif
+/* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */
/*
* Macros use for debugging the driver.
@@ -54,6 +42,7 @@
#define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_16(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#if defined(QL_DEBUG_LEVEL_3)
#define DEBUG3(x) do {x;} while (0)
@@ -133,6 +122,12 @@
#define DEBUG15(x) do {} while (0)
#endif
+#if defined(QL_DEBUG_LEVEL_16)
+#define DEBUG16(x) do {x;} while (0)
+#else
+#define DEBUG16(x) do {} while (0)
+#endif
+
/*
* Firmware Dump structure definition
*/
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 3750319f496..094d95f0764 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2005 QLogic Corporation
+ * Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -24,6 +24,7 @@
#include <linux/workqueue.h>
#include <linux/firmware.h>
#include <linux/aer.h>
+#include <linux/mutex.h>
#include <asm/semaphore.h>
#include <scsi/scsi.h>
@@ -192,9 +193,6 @@ typedef struct srb {
uint16_t flags;
- /* Single transfer DMA context */
- dma_addr_t dma_handle;
-
uint32_t request_sense_length;
uint8_t *request_sense_ptr;
} srb_t;
@@ -1542,8 +1540,6 @@ typedef struct fc_port {
atomic_t state;
uint32_t flags;
- unsigned int os_target_id;
-
int port_login_retry_count;
int login_retry;
atomic_t port_down_timer;
@@ -1613,6 +1609,7 @@ typedef struct fc_port {
#define CT_ACCEPT_RESPONSE 0x8002
#define CT_REASON_INVALID_COMMAND_CODE 0x01
#define CT_REASON_CANNOT_PERFORM 0x09
+#define CT_REASON_COMMAND_UNSUPPORTED 0x0b
#define CT_EXPL_ALREADY_REGISTERED 0x10
#define NS_N_PORT_TYPE 0x01
@@ -2063,7 +2060,8 @@ struct isp_operations {
void (*disable_intrs) (struct scsi_qla_host *);
int (*abort_command) (struct scsi_qla_host *, srb_t *);
- int (*abort_target) (struct fc_port *);
+ int (*target_reset) (struct fc_port *, unsigned int);
+ int (*lun_reset) (struct fc_port *, unsigned int);
int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t,
uint8_t, uint8_t, uint16_t *, uint8_t);
int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t,
@@ -2117,6 +2115,46 @@ struct qla_msix_entry {
#define WATCH_INTERVAL 1 /* number of seconds */
+/* Work events. */
+enum qla_work_type {
+ QLA_EVT_AEN,
+ QLA_EVT_HWE_LOG,
+};
+
+
+struct qla_work_evt {
+ struct list_head list;
+ enum qla_work_type type;
+ u32 flags;
+#define QLA_EVT_FLAG_FREE 0x1
+
+ union {
+ struct {
+ enum fc_host_event_code code;
+ u32 data;
+ } aen;
+ struct {
+ uint16_t code;
+ uint16_t d1, d2, d3;
+ } hwe;
+ } u;
+};
+
+struct qla_chip_state_84xx {
+ struct list_head list;
+ struct kref kref;
+
+ void *bus;
+ spinlock_t access_lock;
+ struct mutex fw_update_mutex;
+ uint32_t fw_update;
+ uint32_t op_fw_version;
+ uint32_t op_fw_size;
+ uint32_t op_fw_seq_size;
+ uint32_t diag_fw_version;
+ uint32_t gold_fw_version;
+};
+
/*
* Linux Host Adapter structure
*/
@@ -2155,6 +2193,7 @@ typedef struct scsi_qla_host {
uint32_t vsan_enabled :1;
uint32_t npiv_supported :1;
uint32_t fce_enabled :1;
+ uint32_t hw_event_marker_found :1;
} flags;
atomic_t loop_state;
@@ -2204,6 +2243,7 @@ typedef struct scsi_qla_host {
#define DFLG_NO_CABLE BIT_4
#define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532
+#define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432
uint32_t device_type;
#define DT_ISP2100 BIT_0
#define DT_ISP2200 BIT_1
@@ -2217,7 +2257,8 @@ typedef struct scsi_qla_host {
#define DT_ISP5422 BIT_9
#define DT_ISP5432 BIT_10
#define DT_ISP2532 BIT_11
-#define DT_ISP_LAST (DT_ISP2532 << 1)
+#define DT_ISP8432 BIT_12
+#define DT_ISP_LAST (DT_ISP8432 << 1)
#define DT_IIDMA BIT_26
#define DT_FWI2 BIT_27
@@ -2239,12 +2280,16 @@ typedef struct scsi_qla_host {
#define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422)
#define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432)
#define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532)
+#define IS_QLA8432(ha) (DT_MASK(ha) & DT_ISP8432)
#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
IS_QLA6312(ha) || IS_QLA6322(ha))
#define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha))
#define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha))
#define IS_QLA25XX(ha) (IS_QLA2532(ha))
+#define IS_QLA84XX(ha) (IS_QLA8432(ha))
+#define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
+ IS_QLA84XX(ha))
#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA)
#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2)
@@ -2356,6 +2401,8 @@ typedef struct scsi_qla_host {
uint32_t login_retry_count;
int max_q_depth;
+ struct list_head work_list;
+
/* Fibre Channel Device List. */
struct list_head fcports;
@@ -2423,8 +2470,6 @@ typedef struct scsi_qla_host {
#define MBX_TIMEDOUT BIT_5
#define MBX_ACCESS_TIMEDOUT BIT_6
- mbx_cmd_t mc;
-
/* Basic firmware related information. */
uint16_t fw_major_version;
uint16_t fw_minor_version;
@@ -2458,6 +2503,10 @@ typedef struct scsi_qla_host {
uint64_t fce_wr, fce_rd;
struct mutex fce_mutex;
+ uint32_t hw_event_start;
+ uint32_t hw_event_ptr;
+ uint32_t hw_event_pause_errors;
+
uint8_t host_str[16];
uint32_t pci_attr;
uint16_t chip_revision;
@@ -2493,6 +2542,13 @@ typedef struct scsi_qla_host {
uint8_t fcode_revision[16];
uint32_t fw_revision[4];
+ uint16_t fdt_odd_index;
+ uint32_t fdt_wrt_disable;
+ uint32_t fdt_erase_cmd;
+ uint32_t fdt_block_size;
+ uint32_t fdt_unprotect_sec_cmd;
+ uint32_t fdt_protect_sec_cmd;
+
/* Needed for BEACON */
uint16_t beacon_blink_led;
uint8_t beacon_color_state;
@@ -2538,6 +2594,8 @@ typedef struct scsi_qla_host {
#define VP_ERR_ADAP_NORESOURCES 5
uint16_t max_npiv_vports; /* 63 or 125 per topoloty */
int cur_vport_count;
+
+ struct qla_chip_state_84xx *cs84xx;
} scsi_qla_host_t;
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 2cd899bfe84..561a4411719 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2005 QLogic Corporation
+ * Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 9337e138ed6..078f2a15f40 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2005 QLogic Corporation
+ * Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -719,7 +719,7 @@ struct tsk_mgmt_entry {
uint16_t timeout; /* Command timeout. */
- uint8_t lun[8]; /* FCP LUN (BE). */
+ struct scsi_lun lun; /* FCP LUN (BE). */
uint32_t control_flags; /* Control Flags. */
#define TCF_NOTMCMD_TO_TARGET BIT_31
@@ -793,7 +793,19 @@ struct device_reg_24xx {
#define FA_VPD_NVRAM_ADDR 0x48000
#define FA_FEATURE_ADDR 0x4C000
#define FA_FLASH_DESCR_ADDR 0x50000
-#define FA_HW_EVENT_ADDR 0x54000
+#define FA_HW_EVENT0_ADDR 0x54000
+#define FA_HW_EVENT1_ADDR 0x54200
+#define FA_HW_EVENT_SIZE 0x200
+#define FA_HW_EVENT_ENTRY_SIZE 4
+/*
+ * Flash Error Log Event Codes.
+ */
+#define HW_EVENT_RESET_ERR 0xF00B
+#define HW_EVENT_ISP_ERR 0xF020
+#define HW_EVENT_PARITY_ERR 0xF022
+#define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023
+#define HW_EVENT_FLASH_FW_ERR 0xF024
+
#define FA_BOOT_LOG_ADDR 0x58000
#define FA_FW_DUMP0_ADDR 0x60000
#define FA_FW_DUMP1_ADDR 0x70000
@@ -1174,4 +1186,159 @@ struct vf_evfp_entry_24xx {
};
/* END MID Support ***********************************************************/
+
+/* Flash Description Table ***************************************************/
+
+struct qla_fdt_layout {
+ uint8_t sig[4];
+ uint16_t version;
+ uint16_t len;
+ uint16_t checksum;
+ uint8_t unused1[2];
+ uint8_t model[16];
+ uint16_t man_id;
+ uint16_t id;
+ uint8_t flags;
+ uint8_t erase_cmd;
+ uint8_t alt_erase_cmd;
+ uint8_t wrt_enable_cmd;
+ uint8_t wrt_enable_bits;
+ uint8_t wrt_sts_reg_cmd;
+ uint8_t unprotect_sec_cmd;
+ uint8_t read_man_id_cmd;
+ uint32_t block_size;
+ uint32_t alt_block_size;
+ uint32_t flash_size;
+ uint32_t wrt_enable_data;
+ uint8_t read_id_addr_len;
+ uint8_t wrt_disable_bits;
+ uint8_t read_dev_id_len;
+ uint8_t chip_erase_cmd;
+ uint16_t read_timeout;
+ uint8_t protect_sec_cmd;
+ uint8_t unused2[65];
+};
+
+/* 84XX Support **************************************************************/
+
+#define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */
+#define A84_PANIC_RECOVERY 0x1
+#define A84_OP_LOGIN_COMPLETE 0x2
+#define A84_DIAG_LOGIN_COMPLETE 0x3
+#define A84_GOLD_LOGIN_COMPLETE 0x4
+
+#define MBC_ISP84XX_RESET 0x3a /* Reset. */
+
+#define FSTATE_REMOTE_FC_DOWN BIT_0
+#define FSTATE_NSL_LINK_DOWN BIT_1
+#define FSTATE_IS_DIAG_FW BIT_2
+#define FSTATE_LOGGED_IN BIT_3
+#define FSTATE_WAITING_FOR_VERIFY BIT_4
+
+#define VERIFY_CHIP_IOCB_TYPE 0x1B
+struct verify_chip_entry_84xx {
+ uint8_t entry_type;
+ uint8_t entry_count;
+ uint8_t sys_defined;
+ uint8_t entry_status;
+
+ uint32_t handle;
+
+ uint16_t options;
+#define VCO_DONT_UPDATE_FW BIT_0
+#define VCO_FORCE_UPDATE BIT_1
+#define VCO_DONT_RESET_UPDATE BIT_2
+#define VCO_DIAG_FW BIT_3
+#define VCO_END_OF_DATA BIT_14
+#define VCO_ENABLE_DSD BIT_15
+
+ uint16_t reserved_1;
+
+ uint16_t data_seg_cnt;
+ uint16_t reserved_2[3];
+
+ uint32_t fw_ver;
+ uint32_t exchange_address;
+
+ uint32_t reserved_3[3];
+ uint32_t fw_size;
+ uint32_t fw_seq_size;
+ uint32_t relative_offset;
+
+ uint32_t dseg_address[2];
+ uint32_t dseg_length;
+};
+
+struct verify_chip_rsp_84xx {
+ uint8_t entry_type;
+ uint8_t entry_count;
+ uint8_t sys_defined;
+ uint8_t entry_status;
+
+ uint32_t handle;
+
+ uint16_t comp_status;
+#define CS_VCS_CHIP_FAILURE 0x3
+#define CS_VCS_BAD_EXCHANGE 0x8
+#define CS_VCS_SEQ_COMPLETEi 0x40
+
+ uint16_t failure_code;
+#define VFC_CHECKSUM_ERROR 0x1
+#define VFC_INVALID_LEN 0x2
+#define VFC_ALREADY_IN_PROGRESS 0x8
+
+ uint16_t reserved_1[4];
+
+ uint32_t fw_ver;
+ uint32_t exchange_address;
+
+ uint32_t reserved_2[6];
+};
+
+#define ACCESS_CHIP_IOCB_TYPE 0x2B
+struct access_chip_84xx {
+ uint8_t entry_type;
+ uint8_t entry_count;
+ uint8_t sys_defined;
+ uint8_t entry_status;
+
+ uint32_t handle;
+
+ uint16_t options;
+#define ACO_DUMP_MEMORY 0x0
+#define ACO_LOAD_MEMORY 0x1
+#define ACO_CHANGE_CONFIG_PARAM 0x2
+#define ACO_REQUEST_INFO 0x3
+
+ uint16_t reserved1;
+
+ uint16_t dseg_count;
+ uint16_t reserved2[3];
+
+ uint32_t parameter1;
+ uint32_t parameter2;
+ uint32_t parameter3;
+
+ uint32_t reserved3[3];
+ uint32_t total_byte_cnt;
+ uint32_t reserved4;
+
+ uint32_t dseg_address[2];
+ uint32_t dseg_length;
+};
+
+struct access_chip_rsp_84xx {
+ uint8_t entry_type;
+ uint8_t entry_count;
+ uint8_t sys_defined;
+ uint8_t entry_status;
+
+ uint32_t handle;
+
+ uint16_t comp_status;
+ uint16_t failure_code;
+ uint32_t residual_count;
+
+ uint32_t reserved[12];
+};
#endif
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 193f688ec3d..a9571c214a9 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2005 QLogic Corporation
+ * Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -38,9 +38,6 @@ extern int qla2x00_loop_resync(scsi_qla_host_t *);
extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
-extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);
-
-extern void qla2x00_rescan_fcports(scsi_qla_host_t *);
extern void qla2x00_update_fcports(scsi_qla_host_t *);
extern int qla2x00_abort_isp(scsi_qla_host_t *);
@@ -50,6 +47,8 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
+extern void qla84xx_put_chip(struct scsi_qla_host *);
+
/*
* Global Data in qla_os.c source file.
*/
@@ -67,6 +66,10 @@ extern int num_hosts;
extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
+extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
+ fc_host_event_code, u32);
+extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t,
+ uint16_t, uint16_t);
/*
* Global Functions in qla_mid.c source file.
@@ -149,12 +152,17 @@ extern int
qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t);
extern int
+qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t,
+ uint32_t);
+
+extern int
qla2x00_abort_command(scsi_qla_host_t *, srb_t *);
-#if USE_ABORT_TGT
extern int
-qla2x00_abort_target(fc_port_t *);
-#endif
+qla2x00_abort_target(struct fc_port *, unsigned int);
+
+extern int
+qla2x00_lun_reset(struct fc_port *, unsigned int);
extern int
qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
@@ -220,7 +228,8 @@ qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
dma_addr_t);
extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
-extern int qla24xx_abort_target(fc_port_t *);
+extern int qla24xx_abort_target(struct fc_port *, unsigned int);
+extern int qla24xx_lun_reset(struct fc_port *, unsigned int);
extern int
qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
@@ -246,6 +255,8 @@ qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
extern int
qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
+extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
+
/*
* Global Function Prototypes in qla_isr.c source file.
*/
@@ -298,6 +309,11 @@ extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
+extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
+ uint16_t, uint16_t);
+
+extern void qla2xxx_get_flash_info(scsi_qla_host_t *);
+
/*
* Global Function Prototypes in qla_dbg.c source file.
*/
@@ -307,7 +323,6 @@ extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
extern void qla25xx_fw_dump(scsi_qla_host_t *, int);
extern void qla2x00_dump_regs(scsi_qla_host_t *);
extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
-extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *);
/*
* Global Function Prototypes in qla_gs.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index c1808763d40..750d7ef83aa 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -1,17 +1,11 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2005 QLogic Corporation
+ * Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
-static inline struct ct_sns_req *
-qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t);
-
-static inline struct sns_cmd_pkt *
-qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
-
static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
@@ -1538,7 +1532,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
eiter->a.sup_speed = __constant_cpu_to_be32(
FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB);
- else if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+ else if (IS_QLA24XX_TYPE(ha))
eiter->a.sup_speed = __constant_cpu_to_be32(
FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
FDMI_PORT_SPEED_4GB);
@@ -1847,8 +1841,10 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list)
"GPSC")) != QLA_SUCCESS) {
/* FM command unsupported? */
if (rval == QLA_INVALID_COMMAND &&
- ct_rsp->header.reason_code ==
- CT_REASON_INVALID_COMMAND_CODE) {
+ (ct_rsp->header.reason_code ==
+ CT_REASON_INVALID_COMMAND_CODE ||
+ ct_rsp->header.reason_code ==
+ CT_REASON_COMMAND_UNSUPPORTED)) {
DEBUG2(printk("scsi(%ld): GPSC command "
"unsupported, disabling query...\n",
ha->host_no));
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 364be7d0687..01e26087c1d 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2005 QLogic Corporation
+ * Copyright (c) 2003-2008 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -15,14 +15,6 @@
#include <asm/prom.h>
#endif
-/* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */
-#ifndef EXT_IS_LUN_BIT_SET
-#define EXT_IS_LUN_BIT_SET(P,L) \
- (((P)->mask[L/8] & (0x80 >> (L%8)))?1:0)
-#define EXT_SET_LUN_BIT(P,L) \
- ((P)->mask[L/8] |= (0x80 >> (L%8)))
-#endif
-
/*
* QLogic ISP2x00 Hardware Support Function Prototypes.
*/
@@ -45,6 +37,9 @@ static int qla2x00_restart_isp(scsi_qla_host_t *);
static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev);
+static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
+static int qla84xx_init_chip(scsi_qla_host_t *);
+
/****************************************************************************/
/* QLogic ISP2x00 Hardware Support Functions. */
/****************************************************************************/
@@ -114,6 +109,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
rval = qla2x00_setup_chip(ha);
if (rval)
return (rval);
+ qla2xxx_get_flash_info(ha);
+ }
+ if (IS_QLA84XX(ha)) {
+ ha->cs84xx = qla84xx_get_chip(ha);
+ if (!ha->cs84xx) {
+ qla_printk(KERN_ERR, ha,
+ "Unable to configure ISP84XX.\n");
+ return QLA_FUNCTION_FAILED;
+ }
}
rval = qla2x00_init_rings(ha);
@@ -500,6 +504,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha)
static inline void
qla24xx_reset_risc(scsi_qla_host_t *ha)
{
+ int hw_evt = 0;
unsigned long flags = 0;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
uint32_t cnt, d2;
@@ -528,6 +533,8 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
barrier();
}
+ if (cnt == 0)
+ hw_evt = 1;
/* Wait for soft-reset to complete. */
d2 = RD_REG_DWORD(&reg->ctrl_status);
@@ -536,6 +543,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
d2 = RD_REG_DWORD(&reg->ctrl_status);
barrier();
}
+ if (cnt == 0 || hw_evt)
+ qla2xxx_hw_event_log(ha, HW_EVENT_RESET_ERR,
+ RD_REG_WORD(&reg->mailbox1), RD_REG_WORD(&reg->mailbox2),
+ RD_REG_WORD(&reg->mailbox3));
WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
RD_REG_DWORD(&reg->hccr);
@@ -1243,10 +1254,10 @@ static int
qla2x00_fw_ready(scsi_qla_host_t *ha)
{
int rval;
- unsigned long wtime, mtime;
+ unsigned long wtime, mtime, cs84xx_time;
uint16_t min_wait; /* Minimum wait time if loop is down */
uint16_t wait_time; /* Wait time if loop is coming ready */
- uint16_t fw_state;
+ uint16_t state[3];
rval = QLA_SUCCESS;
@@ -1275,12 +1286,34 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
ha->host_no));
do {
- rval = qla2x00_get_firmware_state(ha, &fw_state);
+ rval = qla2x00_get_firmware_state(ha, state);
if (rval == QLA_SUCCESS) {
- if (fw_state < FSTATE_LOSS_OF_SYNC) {
+ if (state[0] < FSTATE_LOSS_OF_SYNC) {
ha->device_flags &= ~DFLG_NO_CABLE;
}
- if (fw_state == FSTATE_READY) {