Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 301744 Details for
Bug 441445
[QLogic 4.7 feat] Update qla2xxx - qla84xx variant support.
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
ISP84xx support
qla2xxx_rhel4.7_isp84xx_patch7.txt (text/plain), 29.87 KB, created by
Marcus Barrow
on 2008-04-09 03:20:45 UTC
(
hide
)
Description:
ISP84xx support
Filename:
MIME Type:
Creator:
Marcus Barrow
Created:
2008-04-09 03:20:45 UTC
Size:
29.87 KB
patch
obsolete
> >BZ 441445 [rhel 4.7 feat] [1/2] Update qla2xxx - ISP84xx variant support. > >This patch provides support for a varient of the 4 Gb/S Fibre Channel HBA's. > >This card uses the standard qla24xx hardware but contains an ethernet router downstream >from the Fibre Channel part. The system just sees the standard HBA, but it is identified >by a different PCI ID, which requires changing the driver code. There is also a small >ammount of setup code. > >The driver changes are simple, mostly handling the different PCI ID. > >No firmware changes are required. > >These patches are tested in the standard driver and submitted or queued for upstream. > > > > drivers/scsi/qla2xxx/qim_inioct.c | 2 +- > drivers/scsi/qla2xxx/ql2400.c | 13 ++++ > drivers/scsi/qla2xxx/qla_dbg.h | 8 ++ > drivers/scsi/qla2xxx/qla_def.h | 27 +++++++- > drivers/scsi/qla2xxx/qla_fw.h | 123 +++++++++++++++++++++++++++++++ > drivers/scsi/qla2xxx/qla_gbl.h | 11 +++ > drivers/scsi/qla2xxx/qla_gs.c | 2 +- > drivers/scsi/qla2xxx/qla_init.c | 136 ++++++++++++++++++++++++++++++----- > drivers/scsi/qla2xxx/qla_inline.h | 6 +- > drivers/scsi/qla2xxx/qla_isr.c | 46 +++++++++++- > drivers/scsi/qla2xxx/qla_mbx.c | 143 ++++++++++++++++++++++++++++++------- > drivers/scsi/qla2xxx/qla_os.c | 15 +++- > drivers/scsi/qla2xxx/qla_sup.c | 4 +- > 13 files changed, 477 insertions(+), 59 deletions(-) > >diff --git a/drivers/scsi/qla2xxx/qim_inioct.c b/drivers/scsi/qla2xxx/qim_inioct.c >index 918b2f6..b748a1e 100644 >--- a/drivers/scsi/qla2xxx/qim_inioct.c >+++ b/drivers/scsi/qla2xxx/qim_inioct.c >@@ -311,7 +311,7 @@ qim_get_vpd(struct qla_host_ioctl *ha, E > struct scsi_qla_host *dr_ha = ha->dr_data; > > >- if (!(IS_FWI2_CAPABLE(dr_ha))) { >+ if (!(IS_QLA24XX_TYPE(dr_ha) || IS_QLA25XX(dr_ha))) { > pext->Status = EXT_STATUS_INVALID_REQUEST; > DEBUG9_10(printk( > "%s(%ld): inst=%ld not 24xx or 25xx. got %x. exiting.\n", >diff --git a/drivers/scsi/qla2xxx/ql2400.c b/drivers/scsi/qla2xxx/ql2400.c >index 7612e7a..128e836 100644 >--- a/drivers/scsi/qla2xxx/ql2400.c >+++ b/drivers/scsi/qla2xxx/ql2400.c >@@ -62,6 +62,12 @@ static struct qla_board_info qla_board_t > .fw_info = qla_fw_tbl, > .fw_fname = "ql2400_fw.bin", > }, >+ { >+ .drv_name = qla_driver_name, >+ .isp_name = "ISP8432", >+ .fw_info = qla_fw_tbl, >+ .fw_fname = "ql2400_fw.bin", >+ }, > }; > > static struct pci_device_id qla24xx_pci_tbl[] = { >@@ -93,6 +99,13 @@ static struct pci_device_id qla24xx_pci_ > .subdevice = PCI_ANY_ID, > .driver_data = (unsigned long)&qla_board_tbl[3], > }, >+ { >+ .vendor = PCI_VENDOR_ID_QLOGIC, >+ .device = PCI_DEVICE_ID_QLOGIC_ISP8432, >+ .subvendor = PCI_ANY_ID, >+ .subdevice = PCI_ANY_ID, >+ .driver_data = (unsigned long)&qla_board_tbl[4], >+ }, > > {0, 0}, > }; >diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h >index e8f4a16..fa66637 100644 >--- a/drivers/scsi/qla2xxx/qla_dbg.h >+++ b/drivers/scsi/qla2xxx/qla_dbg.h >@@ -34,6 +34,7 @@ > /* #define QL_DEBUG_LEVEL_12 */ /* Output IP trace msgs */ > /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ > /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ >+/* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ > /* > * Local Macro Definitions. > */ >@@ -77,6 +78,7 @@ > #define DEBUG2_9_10(x) do { if (extended_error_logging) { x; } } while (0); > #define DEBUG2_11(x) do { if (extended_error_logging) { x; } } while (0); > #define DEBUG2_13(x) do { if (extended_error_logging) { x; } } while (0); >+#define DEBUG2_16(x) do { if (extended_error_logging) { x; } } while (0); > > #if defined(QL_DEBUG_LEVEL_3) > #define DEBUG3(x) do {x;} while (0); >@@ -150,6 +152,12 @@ > #define DEBUG14(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 bd5eb4c..14d9282 100644 >--- a/drivers/scsi/qla2xxx/qla_def.h >+++ b/drivers/scsi/qla2xxx/qla_def.h >@@ -89,6 +89,10 @@ > #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 > #endif > >+#ifndef PCI_DEVICE_ID_QLOGIC_ISP8432 >+#define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432 >+#endif >+ > /* > * We have MAILBOX_REGISTER_COUNT sized arrays in a few places, > * but that's fine as we don't look at the last 24 ones for >@@ -2303,6 +2307,21 @@ struct gid_list_info { > }; > #define GID_LIST_SIZE (sizeof(struct gid_list_info) * MAX_FIBRE_DEVICES) > >+struct qla_chip_state_84xx { >+ struct list_head list; >+ struct kref kref; >+ >+ void *bus; >+ spinlock_t access_lock; >+ struct semaphore 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 > */ >@@ -2398,7 +2417,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 >@@ -2419,12 +2439,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) >@@ -2732,6 +2756,7 @@ typedef struct scsi_qla_host { > #define QLA_LED_ALL_ON 0x07 /* yellow, green, amber */ > #define QLA_LED_RGA_ON 0x07 /* isp2322: red, green, amber */ > >+ struct qla_chip_state_84xx *cs84xx; > } scsi_qla_host_t; > > >diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h >index 7753b2c..fd65b94 100644 >--- a/drivers/scsi/qla2xxx/qla_fw.h >+++ b/drivers/scsi/qla2xxx/qla_fw.h >@@ -1099,4 +1099,127 @@ struct vp_rpt_id_entry_24xx { > }; > > /* END MID Support ***********************************************************/ >+ >+/* 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 b065c30..133bcbe 100644 >--- a/drivers/scsi/qla2xxx/qla_gbl.h >+++ b/drivers/scsi/qla2xxx/qla_gbl.h >@@ -50,6 +50,8 @@ extern int qla2x00_abort_isp(scsi_qla_ho > > 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. > */ >@@ -155,6 +157,10 @@ 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 >@@ -241,6 +247,10 @@ qla2x00_get_idma_speed(scsi_qla_host_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. > */ >@@ -264,6 +274,7 @@ extern uint8_t *qla2x00_read_nvram_data( > extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, > uint32_t); > >+ > /* > * Global Function Prototypes in qla_dbg.c source file. > */ >diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c >index 0f0d5da..7acf89d 100644 >--- a/drivers/scsi/qla2xxx/qla_gs.c >+++ b/drivers/scsi/qla2xxx/qla_gs.c >@@ -1550,7 +1550,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); >diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c >index 9563c84..a3cd7a7 100644 >--- a/drivers/scsi/qla2xxx/qla_init.c >+++ b/drivers/scsi/qla2xxx/qla_init.c >@@ -83,6 +83,9 @@ static int qla24xx_load_risc_hotplug(scs > static int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *); > static void qla24xx_update_fw_options(scsi_qla_host_t *); > >+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. */ > /****************************************************************************/ >@@ -155,6 +158,15 @@ qla2x00_initialize_adapter(scsi_qla_host > } > } > >+ if (IS_QLA84XX(ha) && !ha->cs84xx) { >+ ha->cs84xx = qla84xx_get_chip(ha); >+ if (!ha->cs84xx) { >+ qla_printk(KERN_ERR, ha, >+ "Unable to configure ISP84XX.\n"); >+ rval = QLA_FUNCTION_FAILED; >+ } >+ } >+ > if (rval == QLA_SUCCESS && > (rval = qla2x00_init_rings(ha)) == QLA_SUCCESS) { > check_fw_ready_again: >@@ -264,7 +276,7 @@ qla2x00_pci_config(scsi_qla_host_t *ha) > pci_read_config_word(ha->pdev, PCI_COMMAND, &w); > w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); > >- if (IS_QLA24XX(ha) || IS_QLA54XX(ha) || IS_QLA25XX(ha)) { >+ if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) { > int pcix_cmd_reg, pcie_dctl_reg; > struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; > >@@ -485,7 +497,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) > uint16_t cmd; > > >- if (IS_QLA24XX(ha) || IS_QLA54XX(ha) || IS_QLA25XX(ha)) { >+ if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) { > /* Disable ISP interrupts. */ > qla2x00_disable_intrs(ha); > >@@ -653,7 +665,7 @@ qla2x00_chip_diag(scsi_qla_host_t *ha) > uint32_t cnt; > uint16_t mb[5]; > >- if (IS_QLA24XX(ha) || IS_QLA54XX(ha) || IS_QLA25XX(ha)) { >+ if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) { > /* Perform RISC reset. */ > qla24xx_reset_risc(ha); > >@@ -1246,10 +1258,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; > >@@ -1278,12 +1290,33 @@ 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) { >+ if (IS_QLA84XX(ha) && state[0] != FSTATE_READY) { >+ DEBUG16(printk("scsi(%ld): fw_state=%x " >+ "84xx=%x.\n", ha->host_no, state[0], >+ state[2])); >+ if (state[2] & (FSTATE_LOGGED_IN | >+ FSTATE_WAITING_FOR_VERIFY)) { >+ DEBUG16(printk("scsi(%ld): Sending " >+ "verify iocb.\n", ha->host_no)); >+ >+ cs84xx_time = jiffies; >+ rval = qla84xx_init_chip(ha); >+ if (rval != QLA_SUCCESS) >+ break; >+ >+ /* Add time taken to initialize. */ >+ cs84xx_time = jiffies - cs84xx_time; >+ wtime += cs84xx_time * 2; >+ DEBUG16(printk("scsi(%ld): Increasing " >+ "wait time by %ld. New time %ld\n", >+ ha->host_no, cs84xx_time, wtime)); >+ } >+ } else if (state[0] == FSTATE_READY) { > DEBUG(printk("scsi(%ld): F/W Ready - OK \n", > ha->host_no)); > >@@ -1297,8 +1330,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) > rval = QLA_FUNCTION_FAILED; > > if (atomic_read(&ha->loop_down_timer) && >- (fw_state >= FSTATE_LOSS_OF_SYNC || >- fw_state == FSTATE_WAIT_AL_PA)) { >+ state[0] != FSTATE_READY) { > /* Loop down. Timeout on min_wait for states > * other than Wait for Login. > */ >@@ -1323,11 +1355,11 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) > msleep(500); > > DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", >- ha->host_no, fw_state, jiffies)); >+ ha->host_no, state[0], jiffies)); > } while (1); > > DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", >- ha->host_no, fw_state, jiffies)); >+ ha->host_no, state[0], jiffies)); > > if (rval) { > DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", >@@ -1475,7 +1507,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha > struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; > uint8_t timer_mode; > >- if (IS_QLA24XX(ha) || IS_QLA54XX(ha) || IS_QLA25XX(ha)) >+ if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) > return qla24xx_nvram_config(ha); > > rval = QLA_SUCCESS; >@@ -4417,8 +4449,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) > > spin_lock_irqsave(&ha->hardware_lock, flags); > >- if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha) && >- !IS_QLA25XX(ha)) { >+ if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) { > /* > * Disable SRAM, Instruction RAM and GP RAM > * parity. >@@ -4434,8 +4465,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) > > spin_lock_irqsave(&ha->hardware_lock, flags); > >- if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha) && >- !IS_QLA25XX(ha)) { >+ if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) { > /* Enable proper parity */ > if (IS_QLA2300(ha)) > /* SRAM parity */ >@@ -4507,7 +4537,7 @@ qla2x00_reset_adapter(scsi_qla_host_t *h > > spin_lock_irqsave(&ha->hardware_lock, flags); > /* Reset RISC processor. */ >- if (IS_QLA24XX(ha) || IS_QLA54XX(ha) || IS_QLA25XX(ha)) { >+ if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) { > struct device_reg_24xx __iomem *reg24 = > (struct device_reg_24xx __iomem *)ha->iobase; > WRT_REG_DWORD(®24->hccr, HCCRX_SET_RISC_RESET); >@@ -5200,3 +5230,73 @@ qla2x00_try_to_stop_firmware(scsi_qla_ho > ret = qla2x00_stop_firmware(ha); > } > } >+ >+/* 84XX Support **************************************************************/ >+ >+static LIST_HEAD(qla_cs84xx_list); >+static DECLARE_MUTEX(qla_cs84xx_mutex); >+ >+static struct qla_chip_state_84xx * >+qla84xx_get_chip(struct scsi_qla_host *ha) >+{ >+ struct qla_chip_state_84xx *cs84xx; >+ >+ down(&qla_cs84xx_mutex); >+ >+ /* Find any shared 84xx chip. */ >+ list_for_each_entry(cs84xx, &qla_cs84xx_list, list) { >+ if (cs84xx->bus == ha->pdev->bus) { >+ kref_get(&cs84xx->kref); >+ goto done; >+ } >+ } >+ >+ cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL); >+ if (!cs84xx) >+ goto done; >+ >+ kref_init(&cs84xx->kref); >+ spin_lock_init(&cs84xx->access_lock); >+ init_MUTEX(&cs84xx->fw_update_mutex); >+ cs84xx->bus = ha->pdev->bus; >+ >+ list_add_tail(&cs84xx->list, &qla_cs84xx_list); >+done: >+ up(&qla_cs84xx_mutex); >+ return cs84xx; >+} >+ >+static void >+__qla84xx_chip_release(struct kref *kref) >+{ >+ struct qla_chip_state_84xx *cs84xx = >+ container_of(kref, struct qla_chip_state_84xx, kref); >+ >+ down(&qla_cs84xx_mutex); >+ list_del(&cs84xx->list); >+ up(&qla_cs84xx_mutex); >+ kfree(cs84xx); >+} >+ >+void >+qla84xx_put_chip(struct scsi_qla_host *ha) >+{ >+ if (ha->cs84xx) >+ kref_put(&ha->cs84xx->kref, __qla84xx_chip_release); >+} >+ >+static int >+qla84xx_init_chip(scsi_qla_host_t *ha) >+{ >+ int rval; >+ uint16_t status[2]; >+ >+ down(&ha->cs84xx->fw_update_mutex); >+ >+ rval = qla84xx_verify_chip(ha, status); >+ >+ up(&ha->cs84xx->fw_update_mutex); >+ >+ return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED: >+ QLA_SUCCESS; >+} >diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h >index dac2efb..f1ee223 100644 >--- a/drivers/scsi/qla2xxx/qla_inline.h >+++ b/drivers/scsi/qla2xxx/qla_inline.h >@@ -137,8 +137,7 @@ qla2x00_enable_intrs(scsi_qla_host_t *ha > struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; > > spin_lock_irqsave(&ha->hardware_lock, flags); >- if (IS_QLA24XX(ha) || IS_QLA54XX(ha) || IS_QLA25XX(ha)) { >- reg24 = (struct device_reg_24xx __iomem *)ha->iobase; >+ if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) { > WRT_REG_DWORD(®24->ictrl, ICRX_EN_RISC_INT); > RD_REG_DWORD(®24->ictrl); > } else { >@@ -159,8 +158,7 @@ qla2x00_disable_intrs(scsi_qla_host_t *h > > spin_lock_irqsave(&ha->hardware_lock, flags); > ha->interrupts_on = 0; >- if (IS_QLA24XX(ha) || IS_QLA54XX(ha) || IS_QLA25XX(ha)) { >- reg24 = (struct device_reg_24xx __iomem *)ha->iobase; >+ if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) { > WRT_REG_DWORD(®24->ictrl, 0); > RD_REG_DWORD(®24->ictrl); > >diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c >index b21a2b2..345a3f1 100644 >--- a/drivers/scsi/qla2xxx/qla_isr.c >+++ b/drivers/scsi/qla2xxx/qla_isr.c >@@ -297,6 +297,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, > struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; > uint32_t rscn_entry, host_pid; > uint8_t rscn_queue_index; >+ unsigned long flags; > > /* Setup to process RIO completion. */ > handle_cnt = 0; >@@ -376,7 +377,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, > qla2100_fw_dump(ha, 1); > else if (IS_QLA23XX(ha)) > qla2300_fw_dump(ha, 1); >- else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) >+ else if (IS_QLA24XX_TYPE(ha)) > qla24xx_fw_dump(ha, 1); > else if (IS_QLA25XX(ha)) > qla25xx_fw_dump(ha, 1); >@@ -464,9 +465,10 @@ qla2x00_async_event(scsi_qla_host_t *ha, > break; > > case MBA_LOOP_DOWN: /* Loop Down Event */ >- DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n", >- ha->host_no, mb[1])); >- qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]); >+ DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN " >+ "(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3])); >+ qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n", >+ mb[1], mb[2], mb[3]); > > if (atomic_read(&ha->loop_state) != LOOP_DOWN) { > atomic_set(&ha->loop_state, LOOP_DOWN); >@@ -687,6 +689,42 @@ qla2x00_async_event(scsi_qla_host_t *ha, > DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x " > "%04x.\n", ha->host_no, mb[1], mb[2], mb[3])); > break; >+ >+ case MBA_ISP84XX_ALERT: >+ DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- " >+ "%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3])); >+ >+ spin_lock_irqsave(&ha->cs84xx->access_lock, flags); >+ switch (mb[1]) { >+ case A84_PANIC_RECOVERY: >+ qla_printk(KERN_INFO, ha, "Alert 84XX: panic recovery " >+ "%04x %04x\n", mb[2], mb[3]); >+ break; >+ case A84_OP_LOGIN_COMPLETE: >+ ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2]; >+ DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" >+ "firmware version %x\n", ha->cs84xx->op_fw_version)); >+ break; >+ case A84_DIAG_LOGIN_COMPLETE: >+ ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; >+ DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" >+ "diagnostic firmware version %x\n", >+ ha->cs84xx->diag_fw_version)); >+ break; >+ case A84_GOLD_LOGIN_COMPLETE: >+ ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; >+ ha->cs84xx->fw_update = 1; >+ DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX: gold " >+ "firmware version %x\n", >+ ha->cs84xx->gold_fw_version)); >+ break; >+ default: >+ qla_printk(KERN_ERR, ha, >+ "Alert 84xx: Invalid Alert %04x %04x %04x\n", >+ mb[1], mb[2], mb[3]); >+ } >+ spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags); >+ break; > } > } > >diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c >index 2354f93..00ed792 100644 >--- a/drivers/scsi/qla2xxx/qla_mbx.c >+++ b/drivers/scsi/qla2xxx/qla_mbx.c >@@ -814,27 +814,9 @@ qla2x00_verify_checksum(scsi_qla_host_t > return rval; > } > >-/* >- * qla2x00_issue_iocb >- * Issue IOCB using mailbox command >- * >- * Input: >- * ha = adapter state pointer. >- * buffer = buffer pointer. >- * phys_addr = physical address of buffer. >- * size = size of buffer. >- * TARGET_QUEUE_LOCK must be released. >- * ADAPTER_STATE_LOCK must be released. >- * >- * Returns: >- * qla2x00 local function return status code. >- * >- * Context: >- * Kernel context. >- */ > int >-qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, >- size_t size) >+qla2x00_issue_iocb_timeout(scsi_qla_host_t *ha, void *buffer, >+ dma_addr_t phys_addr, size_t size, uint32_t tov) > { > int rval; > mbx_cmd_t mc; >@@ -848,7 +830,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, > mcp->mb[7] = LSW(MSD(phys_addr)); > mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; > mcp->in_mb = MBX_2|MBX_0; >- mcp->tov = 30; >+ mcp->tov = tov; > mcp->flags = 0; > rval = qla2x00_mailbox_command(ha, mcp); > >@@ -871,6 +853,14 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, > return rval; > } > >+int >+qla2x00_issue_iocb(scsi_qla_host_t *ha, void *buffer, dma_addr_t phys_addr, >+ size_t size) >+{ >+ return qla2x00_issue_iocb_timeout(ha, buffer, phys_addr, size, >+ MBX_TOV_SECONDS); >+} >+ > /* > * qla2x00_abort_command > * Abort command aborts a specified IOCB. >@@ -1335,7 +1325,7 @@ gpd_error_out: > * Kernel context. > */ > int >-qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) >+qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *state) > { > int rval; > mbx_cmd_t mc; >@@ -1346,13 +1336,15 @@ qla2x00_get_firmware_state(scsi_qla_host > > mcp->mb[0] = MBC_GET_FIRMWARE_STATE; > mcp->out_mb = MBX_0; >- mcp->in_mb = MBX_2|MBX_1|MBX_0; >- mcp->tov = 30; >+ mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; >+ mcp->tov = MBX_TOV_SECONDS; > mcp->flags = 0; > rval = qla2x00_mailbox_command(ha, mcp); > > /* Return firmware state. */ >- *dptr = mcp->mb[1]; >+ state[0] = mcp->mb[1]; >+ state[1] = mcp->mb[2]; >+ state[2] = mcp->mb[3]; > > if (rval != QLA_SUCCESS) { > /*EMPTY*/ >@@ -2765,4 +2757,105 @@ qla2x00_set_idma_speed(scsi_qla_host_t * > > return rval; > } >+ >+/* 84XX Support **************************************************************/ >+ >+struct cs84xx_mgmt_cmd { >+ union { >+ struct verify_chip_entry_84xx req; >+ struct verify_chip_rsp_84xx rsp; >+ } p; >+}; >+ >+int >+qla84xx_verify_chip(struct scsi_qla_host *ha, uint16_t *status) >+{ >+ int rval, retry; >+ struct cs84xx_mgmt_cmd *mn; >+ dma_addr_t mn_dma; >+ uint16_t options; >+ unsigned long flags; >+ >+ DEBUG16(printk("%s(%ld): entered.\n", __func__, ha->host_no)); >+ >+ mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); >+ if (mn == NULL) { >+ DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX " >+ "IOCB.\n", __func__, ha->host_no)); >+ return QLA_MEMORY_ALLOC_FAILED; >+ } >+ >+ /* Force Update? */ >+ options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0; >+ /* Diagnostic firmware? */ >+ /* options |= MENLO_DIAG_FW; */ >+ /* We update the firmware with only one data sequence. */ >+ options |= VCO_END_OF_DATA; >+ >+ retry = 0; >+ do { >+ memset(mn, 0, sizeof(*mn)); >+ mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE; >+ mn->p.req.entry_count = 1; >+ mn->p.req.options = cpu_to_le16(options); >+ >+ DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__, >+ ha->host_no)); >+ DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, >+ sizeof(*mn))); >+ >+ rval = qla2x00_issue_iocb_timeout(ha, mn, mn_dma, 0, 120); >+ if (rval != QLA_SUCCESS) { >+ DEBUG2_16(printk("%s(%ld): failed to issue Verify " >+ "IOCB (%x).\n", __func__, ha->host_no, rval)); >+ goto verify_done; >+ } >+ >+ DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__, >+ ha->host_no)); >+ DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, >+ sizeof(*mn))); >+ >+ status[0] = le16_to_cpu(mn->p.rsp.comp_status); >+ status[1] = status[0] == CS_VCS_CHIP_FAILURE ? >+ le16_to_cpu(mn->p.rsp.failure_code) : 0; >+ DEBUG16(printk("%s(%ld): cs=%x fc=%x\n", __func__, >+ ha->host_no, status[0], status[1])); >+ >+ if (status[0] != CS_COMPLETE) { >+ rval = QLA_FUNCTION_FAILED; >+ if (!(options & VCO_DONT_UPDATE_FW)) { >+ DEBUG2_16(printk("%s(%ld): Firmware update " >+ "failed. Retrying without update " >+ "firmware.\n", __func__, ha->host_no)); >+ options |= VCO_DONT_UPDATE_FW; >+ options &= ~VCO_FORCE_UPDATE; >+ retry = 1; >+ } >+ } else { >+ DEBUG16(printk("%s(%ld): firmware updated to %x.\n", >+ __func__, ha->host_no, >+ le32_to_cpu(mn->p.rsp.fw_ver))); >+ >+ /* NOTE: we only update OP firmware. */ >+ spin_lock_irqsave(&ha->cs84xx->access_lock, flags); >+ ha->cs84xx->op_fw_version = >+ le32_to_cpu(mn->p.rsp.fw_ver); >+ spin_unlock_irqrestore(&ha->cs84xx->access_lock, >+ flags); >+ } >+ } while (retry); >+ >+verify_done: >+ dma_pool_free(ha->s_dma_pool, mn, mn_dma); >+ >+ if (rval != QLA_SUCCESS) { >+ DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__, >+ ha->host_no, rval)); >+ } else { >+ DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no)); >+ } >+ >+ return rval; >+} > EXPORT_SYMBOL_GPL(qla2x00_set_idma_speed); >diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c >index 98d289c..a5094aa 100644 >--- a/drivers/scsi/qla2xxx/qla_os.c >+++ b/drivers/scsi/qla2xxx/qla_os.c >@@ -705,7 +705,7 @@ qla2x00_get_pci_info_str(struct scsi_qla > } > > strcpy(str, "PCI"); >- if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { /* XXX, Marcus */ >+ if (IS_QLA24XX_TYPE(ha)) { > pci_bus = (ha->pci_attr & CSRX_PCIX_BUS_MODE_MASK) >> 8; > if (pci_bus == 0 || pci_bus == 8) { > strcat(str, " ("); >@@ -751,6 +751,8 @@ qla2x00_get_fw_version_str(struct scsi_q > strcat(str, "[IP] "); > if (ha->fw_attributes & BIT_2) > strcat(str, "[Multi-ID] "); >+ if (ha->fw_attributes & BIT_10) >+ strcat(str, "[84XX] "); > if (ha->fw_attributes & BIT_13) > strcat(str, "[Experimental] "); > return str; >@@ -1162,6 +1164,11 @@ qla2x00_set_isp_flags(scsi_qla_host_t *h > ha->device_type |= DT_FWI2; > ha->device_type |= DT_IIDMA; > break; >+ case PCI_DEVICE_ID_QLOGIC_ISP8432: >+ ha->device_type |= DT_ISP8432; >+ ha->device_type |= DT_FWI2; >+ ha->device_type |= DT_IIDMA; >+ break; > case PCI_DEVICE_ID_QLOGIC_ISP5422: > ha->device_type |= DT_ISP5422; > ha->device_type |= DT_FWI2; >@@ -2218,7 +2225,7 @@ int qla2x00_probe_one(struct pci_dev *pd > ha->request_q_length = REQUEST_ENTRY_CNT_2200; > ha->response_q_length = RESPONSE_ENTRY_CNT_2300; > ha->last_loop_id = SNS_LAST_LOOP_ID_2300; >- } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha) || IS_QLA25XX(ha)) { >+ } else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) { > ha->max_targets = MAX_TARGETS_2200; > ha->mbx_count = MAILBOX_REGISTER_COUNT; > ha->request_q_length = REQUEST_ENTRY_CNT_24XX; >@@ -2469,6 +2476,8 @@ void qla2x00_remove_one(struct pci_dev * > &sysfs_fw_dump_attr); > sysfs_remove_bin_file(&ha->host->shost_gendev.kobj, &sysfs_nvram_attr); > >+ qla84xx_put_chip(ha); >+ > scsi_remove_host(ha->host); > > qla2x00_free_device(ha); >@@ -2655,7 +2664,7 @@ qla2x00_proc_info(struct Scsi_Host *shos > copy_info(&info, "Driver version %s\n", qla2x00_version_str); > > copy_info(&info, "ISP: %s", ha->brd_info->isp_name); >- if (IS_FWI2_CAPABLE(ha)) { >+ if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) { > copy_info(&info, "\n"); > } else { > tmp_sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | >diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c >index 0bc5f24..9bec319 100644 >--- a/drivers/scsi/qla2xxx/qla_sup.c >+++ b/drivers/scsi/qla2xxx/qla_sup.c >@@ -513,7 +513,7 @@ qla2x00_read_nvram_data(scsi_qla_host_t > if (IS_QLA25XX(ha)) { > qla2xxx_read_flash_data(ha, buf, > ((FA_VPD_NVRAM_ADDR << 2) | (naddr << 2)), bytes ); >- } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { >+ } else if (IS_QLA24XX_TYPE(ha)) { > /* Dword reads to flash. */ > dwptr = (uint32_t *)buf; > for (i = 0; i < bytes >> 2; i++, naddr++) >@@ -665,7 +665,7 @@ qla2x00_write_nvram_data(scsi_qla_host_t > if (IS_QLA25XX(ha)) { > ret = qla24xx_write_flash_data(ha, (uint32_t *)buf, > FA_VPD_NVRAM_ADDR | naddr, bytes >> 2); >- } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { >+ } else if (IS_QLA24XX_TYPE(ha)) { > /* Enable flash write. */ > WRT_REG_DWORD(®->ctrl_status, > RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); >-- >1.4.4.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 441445
: 301744 |
301745