diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 19 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 5 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_devtbl.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 10 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 60 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 63 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 56 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 12 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 38 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 25 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_version.h | 2 |
12 files changed, 199 insertions, 95 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index c7acef50d5da..f4c57227ec18 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1016,6 +1016,9 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) struct Scsi_Host *host = rport_to_shost(rport); fc_port_t *fcport = *(fc_port_t **)rport->dd_data; + if (!fcport) + return; + qla2x00_abort_fcport_cmds(fcport); /* @@ -1033,6 +1036,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) { fc_port_t *fcport = *(fc_port_t **)rport->dd_data; + if (!fcport) + return; + /* * At this point all fcport's software-states are cleared. Perform any * final cleanup of firmware resources (PCBs and XCBs). @@ -1259,13 +1265,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) msleep(1000); - if (ha->mqenable) { - if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS) - qla_printk(KERN_WARNING, ha, - "Queue delete failed.\n"); - vha->req_ques[0] = ha->req_q_map[0]->id; - } - qla24xx_disable_vp(vha); fc_remove_host(vha->host); @@ -1287,6 +1286,12 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) vha->host_no, vha->vp_idx, vha)); } + if (ha->mqenable) { + if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS) + qla_printk(KERN_WARNING, ha, + "Queue delete failed.\n"); + } + scsi_host_put(vha->host); qla_printk(KERN_INFO, ha, "vport %d deleted\n", id); return 0; diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 023ee77fb027..e0c5bb54b258 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2135,6 +2135,7 @@ struct qla_msix_entry { /* Work events. */ enum qla_work_type { QLA_EVT_AEN, + QLA_EVT_IDC_ACK, }; @@ -2149,6 +2150,10 @@ struct qla_work_evt { enum fc_host_event_code code; u32 data; } aen; + struct { +#define QLA_IDC_ACK_REGS 7 + uint16_t mb[QLA_IDC_ACK_REGS]; + } idc_ack; } u; }; diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h index d78d35e681ab..d6ea69df7c5c 100644 --- a/drivers/scsi/qla2xxx/qla_devtbl.h +++ b/drivers/scsi/qla2xxx/qla_devtbl.h @@ -72,7 +72,7 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = { "QLA2462", "Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */ "QLE2460", "Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */ "QLE2462", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x143 */ - "QEM2462" "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */ + "QEM2462", "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */ "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 7abb045a0410..ffff42554087 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1402,6 +1402,8 @@ struct access_chip_rsp_84xx { #define MBA_IDC_NOTIFY 0x8101 #define MBA_IDC_TIME_EXT 0x8102 +#define MBC_IDC_ACK 0x101 + struct nvram_81xx { /* NVRAM header. */ uint8_t id[4]; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index ba4913353752..6de283f8f111 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -34,6 +34,7 @@ extern void qla24xx_update_fw_options(scsi_qla_host_t *); extern void qla81xx_update_fw_options(scsi_qla_host_t *); extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *); extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *); +extern int qla81xx_load_risc(scsi_qla_host_t *, uint32_t *); extern int qla2x00_loop_resync(scsi_qla_host_t *); @@ -71,6 +72,7 @@ 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_idc_ack_work(struct scsi_qla_host *, uint16_t *); extern void qla2x00_abort_fcport_cmds(fc_port_t *); extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *, @@ -265,6 +267,8 @@ 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 *); +extern int qla81xx_idc_ack(scsi_qla_host_t *, uint16_t *); + /* * Global Function Prototypes in qla_isr.c source file. */ @@ -375,10 +379,8 @@ extern int qla2x00_dfs_remove(scsi_qla_host_t *); /* Globa function prototypes for multi-q */ extern int qla25xx_request_irq(struct rsp_que *); -extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *, - uint8_t); -extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *, - uint8_t); +extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *); +extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *); extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t, uint16_t, uint8_t, uint8_t); extern int qla25xx_create_rsp_que(struct qla_hw_data *, uint16_t, uint8_t, diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 9ad4d0968e5c..986501759ad4 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1226,9 +1226,8 @@ qla24xx_config_rings(struct scsi_qla_host *vha) icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_18); - icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_22); + icb->firmware_options_2 &= __constant_cpu_to_le32(~BIT_22); icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23); - ha->rsp_q_map[0]->options = icb->firmware_options_2; WRT_REG_DWORD(®->isp25mq.req_q_in, 0); WRT_REG_DWORD(®->isp25mq.req_q_out, 0); @@ -3493,7 +3492,7 @@ qla25xx_init_queues(struct qla_hw_data *ha) rsp = ha->rsp_q_map[i]; if (rsp) { rsp->options &= ~BIT_0; - ret = qla25xx_init_rsp_que(base_vha, rsp, rsp->options); + ret = qla25xx_init_rsp_que(base_vha, rsp); if (ret != QLA_SUCCESS) DEBUG2_17(printk(KERN_WARNING "%s Rsp que:%d init failed\n", __func__, @@ -3507,7 +3506,7 @@ qla25xx_init_queues(struct qla_hw_data *ha) if (req) { /* Clear outstanding commands array. */ req->options &= ~BIT_0; - ret = qla25xx_init_req_que(base_vha, req, req->options); + ret = qla25xx_init_req_que(base_vha, req); if (ret != QLA_SUCCESS) DEBUG2_17(printk(KERN_WARNING "%s Req que:%d init failed\n", __func__, @@ -3562,6 +3561,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha) WRT_REG_DWORD(®->hccr, HCCRX_REL_RISC_PAUSE); RD_REG_DWORD(®->hccr); spin_unlock_irqrestore(&ha->hardware_lock, flags); + + if (IS_NOPOLLING_TYPE(ha)) + ha->isp_ops->enable_intrs(ha); } /* On sparc systems, obtain port and node WWN from firmware @@ -3847,6 +3849,10 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr) uint32_t i; struct qla_hw_data *ha = vha->hw; struct req_que *req = ha->req_q_map[0]; + + qla_printk(KERN_INFO, ha, + "FW: Loading from flash (%x)...\n", ha->flt_region_fw); + rval = QLA_SUCCESS; segments = FA_RISC_CODE_SEGMENTS; @@ -4022,8 +4028,8 @@ fail_fw_integrity: return QLA_FUNCTION_FAILED; } -int -qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) +static int +qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) { int rval; int segments, fragment; @@ -4043,12 +4049,12 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) qla_printk(KERN_ERR, ha, "Firmware images can be retrieved " "from: " QLA_FW_URL ".\n"); - /* Try to load RISC code from flash. */ - qla_printk(KERN_ERR, ha, "Attempting to load (potentially " - "outdated) firmware from flash.\n"); - return qla24xx_load_risc_flash(vha, srisc_addr); + return QLA_FUNCTION_FAILED; } + qla_printk(KERN_INFO, ha, + "FW: Loading via request-firmware...\n"); + rval = QLA_SUCCESS; segments = FA_RISC_CODE_SEGMENTS; @@ -4133,6 +4139,40 @@ fail_fw_integrity: return QLA_FUNCTION_FAILED; } +int +qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) +{ + int rval; + + /* + * FW Load priority: + * 1) Firmware via request-firmware interface (.bin file). + * 2) Firmware residing in flash. + */ + rval = qla24xx_load_risc_blob(vha, srisc_addr); + if (rval == QLA_SUCCESS) + return rval; + + return qla24xx_load_risc_flash(vha, srisc_addr); +} + +int +qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) +{ + int rval; + + /* + * FW Load priority: + * 1) Firmware residing in flash. + * 2) Firmware via request-firmware interface (.bin file). + */ + rval = qla24xx_load_risc_flash(vha, srisc_addr); + if (rval == QLA_SUCCESS) + return rval; + + return qla24xx_load_risc_blob(vha, srisc_addr); +} + void qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha) { diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 789fc576f222..f250e5b7897c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -266,6 +266,40 @@ qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) } } +static void +qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr) +{ + static char *event[] = + { "Complete", "Request Notification", "Time Extension" }; + int rval; + struct device_reg_24xx __iomem *reg24 = &vha->hw->iobase->isp24; + uint16_t __iomem *wptr; + uint16_t cnt, timeout, mb[QLA_IDC_ACK_REGS]; + + /* Seed data -- mailbox1 -> mailbox7. */ + wptr = (uint16_t __iomem *)®24->mailbox1; + for (cnt = 0; cnt < QLA_IDC_ACK_REGS; cnt++, wptr++) + mb[cnt] = RD_REG_WORD(wptr); + + DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- " + "%04x %04x %04x %04x %04x %04x %04x.\n", vha->host_no, + event[aen & 0xff], + mb[0], mb[1], mb[2], mb[3], mb[4], mb[5], mb[6])); + + /* Acknowledgement needed? [Notify && non-zero timeout]. */ + timeout = (descr >> 8) & 0xf; + if (aen != MBA_IDC_NOTIFY || !timeout) + return; + + DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- " + "ACK timeout=%d.\n", vha->host_no, event[aen & 0xff], timeout)); + + rval = qla2x00_post_idc_ack_work(vha, mb); + if (rval != QLA_SUCCESS) + qla_printk(KERN_WARNING, vha->hw, + "IDC failed to post ACK.\n"); +} + /** * qla2x00_async_event() - Process aynchronous events. * @ha: SCSI driver HA context @@ -714,21 +748,9 @@ skip_rio: "%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3])); break; case MBA_IDC_COMPLETE: - DEBUG2(printk("scsi(%ld): Inter-Driver Commucation " - "Complete -- %04x %04x %04x\n", vha->host_no, mb[1], mb[2], - mb[3])); - break; case MBA_IDC_NOTIFY: - DEBUG2(printk("scsi(%ld): Inter-Driver Commucation " - "Request Notification -- %04x %04x %04x\n", vha->host_no, - mb[1], mb[2], mb[3])); - /**** Mailbox registers 4 - 7 valid!!! */ - break; case MBA_IDC_TIME_EXT: - DEBUG2(printk("scsi(%ld): Inter-Driver Commucation " - "Time Extension -- %04x %04x %04x\n", vha->host_no, mb[1], - mb[2], mb[3])); - /**** Mailbox registers 4 - 7 valid!!! */ + qla81xx_idc_event(vha, mb[0], mb[1]); break; } @@ -1707,7 +1729,6 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) struct qla_hw_data *ha; struct rsp_que *rsp; struct device_reg_24xx __iomem *reg; - uint16_t msix_disabled_hccr = 0; rsp = (struct rsp_que *) dev_id; if (!rsp) { @@ -1720,17 +1741,8 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) spin_lock_irq(&ha->hardware_lock); - msix_disabled_hccr = rsp->options; - if (!rsp->id) - msix_disabled_hccr &= __constant_cpu_to_le32(BIT_22); - else - msix_disabled_hccr &= __constant_cpu_to_le32(BIT_6); - qla24xx_process_response_queue(rsp); - if (!msix_disabled_hccr) - WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); - spin_unlock_irq(&ha->hardware_lock); return IRQ_HANDLED; @@ -1868,6 +1880,7 @@ qla24xx_disable_msix(struct qla_hw_data *ha) static int qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) { +#define MIN_MSIX_COUNT 2 int i, ret; struct msix_entry *entries; struct qla_msix_entry *qentry; @@ -1883,12 +1896,16 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) ret = pci_enable_msix(ha->pdev, entries, ha->msix_count); if (ret) { + if (ret < MIN_MSIX_COUNT) + goto msix_failed; + qla_printk(KERN_WARNING, ha, "MSI-X: Failed to enable support -- %d/%d\n" " Retry with %d vectors\n", ha->msix_count, ret, ret); ha->msix_count = ret; ret = pci_enable_msix(ha->pdev, entries, ha->msix_count); if (ret) { +msix_failed: qla_printk(KERN_WARNING, ha, "MSI-X: Failed to enable" " support, giving up -- %d/%d\n", ha->msix_count, ret); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index db4df45234a5..4c7504cb3990 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -58,14 +58,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) * seconds. This is to serialize actual issuing of mailbox cmds during * non ISP abort time. */ - if (!abort_active) { - if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, - mcp->tov * HZ)) { - /* Timeout occurred. Return error. */ - DEBUG2_3_11(printk("%s(%ld): cmd access timeout. " - "Exiting.\n", __func__, base_vha->host_no)); - return QLA_FUNCTION_TIMEOUT; - } + if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) { + /* Timeout occurred. Return error. */ + DEBUG2_3_11(printk("%s(%ld): cmd access timeout. " + "Exiting.\n", __func__, base_vha->host_no)); + return QLA_FUNCTION_TIMEOUT; } ha->flags.mbox_busy = 1; @@ -265,8 +262,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) } /* Allow next mbx cmd to come in. */ - if (!abort_active) - complete(&ha->mbx_cmd_comp); + complete(&ha->mbx_cmd_comp); if (rval) { DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, " @@ -3094,8 +3090,7 @@ verify_done: } int -qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req, - uint8_t options) +qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) { int rval; unsigned long flags; @@ -3105,7 +3100,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req, struct qla_hw_data *ha = vha->hw; mcp->mb[0] = MBC_INITIALIZE_MULTIQ; - mcp->mb[1] = options; + mcp->mb[1] = req->options; mcp->mb[2] = MSW(LSD(req->dma)); mcp->mb[3] = LSW(LSD(req->dma)); mcp->mb[6] = MSW(MSD(req->dma)); @@ -3132,7 +3127,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req, mcp->tov = 60; spin_lock_irqsave(&ha->hardware_lock, flags); - if (!(options & BIT_0)) { + if (!(req->options & BIT_0)) { WRT_REG_DWORD(®->req_q_in, 0); WRT_REG_DWORD(®->req_q_out, 0); } @@ -3146,8 +3141,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req, } int -qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp, - uint8_t options) +qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) { int rval; unsigned long flags; @@ -3157,7 +3151,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp, struct qla_hw_data *ha = vha->hw; mcp->mb[0] = MBC_INITIALIZE_MULTIQ; - mcp->mb[1] = options; + mcp->mb[1] = rsp->options; mcp->mb[2] = MSW(LSD(rsp->dma)); mcp->mb[3] = LSW(LSD(rsp->dma)); mcp->mb[6] = MSW(MSD(rsp->dma)); @@ -3182,7 +3176,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp, mcp->tov = 60; spin_lock_irqsave(&ha->hardware_lock, flags); - if (!(options & BIT_0)) { + if (!(rsp->options & BIT_0)) { WRT_REG_DWORD(®->rsp_q_out, 0); WRT_REG_DWORD(®->rsp_q_in, 0); } @@ -3197,3 +3191,29 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp, return rval; } +int +qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb) +{ + int rval; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + + DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); + + mcp->mb[0] = MBC_IDC_ACK; + memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); + mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; + mcp->in_mb = MBX_0; + mcp->tov = MBX_TOV_SECONDS; + mcp->flags = 0; + rval = qla2x00_mailbox_command(vha, mcp); + + if (rval != QLA_SUCCESS) { + DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, + vha->host_no, rval, mcp->mb[0])); + } else { + DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no)); + } + + return rval; +} diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index f53179c46423..3f23932210c4 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -396,7 +396,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL); - memset(vha->req_ques, 0, sizeof(vha->req_ques) * QLA_MAX_HOST_QUES); + memset(vha->req_ques, 0, sizeof(vha->req_ques)); vha->req_ques[0] = ha->req_q_map[0]->id; host->can_queue = ha->req_q_map[0]->length + 128; host->this_id = 255; @@ -471,7 +471,7 @@ qla25xx_delete_req_que(struct scsi_qla_host *vha, struct req_que *req) if (req) { req->options |= BIT_0; - ret = qla25xx_init_req_que(vha, req, req->options); + ret = qla25xx_init_req_que(vha, req); } if (ret == QLA_SUCCESS) qla25xx_free_req_que(vha, req); @@ -486,7 +486,7 @@ qla25xx_delete_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) if (rsp) { rsp->options |= BIT_0; - ret = qla25xx_init_rsp_que(vha, rsp, rsp->options); + ret = qla25xx_init_rsp_que(vha, rsp); } if (ret == QLA_SUCCESS) qla25xx_free_rsp_que(vha, rsp); @@ -502,7 +502,7 @@ int qla25xx_update_req_que(struct scsi_qla_host *vha, uint8_t que, uint8_t qos) req->options |= BIT_3; req->qos = qos; - ret = qla25xx_init_req_que(vha, req, req->options); + ret = qla25xx_init_req_que(vha, req); if (ret != QLA_SUCCESS) DEBUG2_17(printk(KERN_WARNING "%s failed\n", __func__)); /* restore options bit */ @@ -632,7 +632,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, req->max_q_depth = ha->req_q_map[0]->max_q_depth; mutex_unlock(&ha->vport_lock); - ret = qla25xx_init_req_que(base_vha, req, options); + ret = qla25xx_init_req_que(base_vha, req); if (ret != QLA_SUCCESS) { qla_printk(KERN_WARNING, ha, "%s failed\n", __func__); mutex_lock(&ha->vport_lock); @@ -710,7 +710,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, if (ret) goto que_failed; - ret = qla25xx_init_rsp_que(base_vha, rsp, options); + ret = qla25xx_init_rsp_que(base_vha, rsp); if (ret != QLA_SUCCESS) { qla_printk(KERN_WARNING, ha, "%s failed\n", __func__); mutex_lock(&ha->vport_lock); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index cf32653fe01a..2f5f72531e23 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -65,8 +65,6 @@ MODULE_PARM_DESC(ql2xextended_error_logging, static void qla2x00_free_device(scsi_qla_host_t *); -static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); - int ql2xfdmienable=1; module_param(ql2xfdmienable, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xfdmienable, @@ -800,6 +798,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) if (ha->isp_ops->abort_command(vha, sp, req)) { DEBUG2(printk("%s(%ld): abort_command " "mbx failed.\n", __func__, vha->host_no)); + ret = FAILED; } else { DEBUG3(printk("%s(%ld): abort_command " "mbx success.\n", __func__, vha->host_no)); @@ -1241,9 +1240,8 @@ qla2x00_change_queue_type(struct scsi_device *sdev, int tag_type) * supported addressing method. */ static void -qla2x00_config_dma_addressing(scsi_qla_host_t *vha) +qla2x00_config_dma_addressing(struct qla_hw_data *ha) { - struct qla_hw_data *ha = vha->hw; /* Assume a 32bit DMA mask. */ ha->flags.enable_64bit_addressing = 0; @@ -1480,7 +1478,7 @@ static struct isp_operations qla81xx_isp_ops = { .reset_adapter = qla24xx_reset_adapter, .nvram_config = qla81xx_nvram_config, .update_fw_options = qla81xx_update_fw_options, - .load_risc = qla24xx_load_risc, + .load_risc = qla81xx_load_risc, .pci_info_str = qla24xx_pci_info_str, .fw_version_str = qla24xx_fw_version_str, .intr_handler = qla24xx_intr_handler, @@ -1869,6 +1867,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) set_bit(0, (unsigned long *) ha->vp_idx_map); + qla2x00_config_dma_addressing(ha); ret = qla2x00_mem_alloc(ha, req_length, rsp_length, &req, &rsp); if (!ret) { qla_printk(KERN_WARNING, ha, @@ -1888,13 +1887,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) "[ERROR] Failed to allocate memory for scsi_host\n"); ret = -ENOMEM; + qla2x00_mem_free(ha); + qla2x00_free_que(ha, req, rsp); goto probe_hw_failed; } pci_set_drvdata(pdev, base_vha); - qla2x00_config_dma_addressing(base_vha); - host = base_vha->host; base_vha->req_ques[0] = req->id; host->can_queue = req->length + 128; @@ -1917,14 +1916,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) /* Set up the irqs */ ret = qla2x00_request_irqs(ha, rsp); if (ret) - goto probe_failed; - + goto probe_init_failed; /* Alloc arrays of request and response ring ptrs */ if (!qla2x00_alloc_queues(ha)) { qla_printk(KERN_WARNING, ha, "[ERROR] Failed to allocate memory for queue" " pointers\n"); - goto probe_failed; + goto probe_init_failed; } ha->rsp_q_map[0] = rsp; ha->req_q_map[0] = req; @@ -1997,6 +1995,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) return 0; +probe_init_failed: + qla2x00_free_que(ha, req, rsp); + ha->max_queues = 0; + probe_failed: qla2x00_free_device(base_vha); @@ -2520,6 +2522,19 @@ qla2x00_post_aen_work(struct scsi_qla_host *vha, enum fc_host_event_code code, return qla2x00_post_work(vha, e, 1); } +int +qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb) +{ + struct qla_work_evt *e; + + e = qla2x00_alloc_work(vha, QLA_EVT_IDC_ACK, 1); + if (!e) + return QLA_FUNCTION_FAILED; + + memcpy(e->u.idc_ack.mb, mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); + return qla2x00_post_work(vha, e, 1); +} + static void qla2x00_do_work(struct scsi_qla_host *vha) { @@ -2537,6 +2552,9 @@ qla2x00_do_work(struct scsi_qla_host *vha) fc_host_post_event(vha->host, fc_get_event_number(), e->u.aen.code, e->u.aen.data); break; + case QLA_EVT_IDC_ACK: + qla81xx_idc_ack(vha, e->u.idc_ack.mb); + break; } if (e->flags & QLA_EVT_FLAG_FREE) kfree(e); diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 303f8ee11f25..284827926eff 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -684,7 +684,7 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) "end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start, le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size))); - switch (le32_to_cpu(region->code)) { + switch (le32_to_cpu(region->code) & 0xff) { case FLT_REG_FW: ha->flt_region_fw = start; break; @@ -944,9 +944,9 @@ qla24xx_unprotect_flash(struct qla_hw_data *ha) if (!ha->fdt_wrt_disable) return; - /* Disable flash write-protection. */ + /* Disable flash write-protection, first clear SR protection bit */ qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0); - /* Some flash parts need an additional zero-write to clear bits.*/ + /* Then write zero again to clear remaining SR bits.*/ qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0); } @@ -980,12 +980,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, uint32_t dwords) { int ret; - uint32_t liter, miter; + uint32_t liter; uint32_t sec_mask, rest_addr; - uint32_t fdata, findex; + uint32_t fdata; dma_addr_t optrom_dma; void *optrom = NULL; - uint32_t *s, *d; struct qla_hw_data *ha = vha->hw; ret = QLA_SUCCESS; @@ -1003,17 +1002,15 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, } rest_addr = (ha->fdt_block_size >> 2) - 1; - sec_mask = (ha->optrom_size >> 2) - (ha->fdt_block_size >> 2); + sec_mask = ~rest_addr; qla24xx_unprotect_flash(ha); for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { - - findex = faddr; - fdata = (findex & sec_mask) << 2; + fdata = (faddr & sec_mask) << 2; /* Are we at the beginning of a sector? */ - if ((findex & rest_addr) == 0) { + if ((faddr & rest_addr) == 0) { /* Do sector unprotect. */ if (ha->fdt_unprotect_sec_cmd) qla24xx_write_flash_dword(ha, @@ -1024,7 +1021,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, (fdata & 0xff00) |((fdata << 16) & 0xff0000) | ((fdata >> 16) & 0xff)); if (ret != QLA_SUCCESS) { - DEBUG9(qla_printk("Unable to flash sector: " + DEBUG9(qla_printk("Unable to erase sector: " "address=%x.\n", faddr)); break; } @@ -1033,9 +1030,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, /* Go with burst-write. */ if (optrom && (liter + OPTROM_BURST_DWORDS) <= dwords) { /* Copy data to DMA'ble buffer. */ - for (miter = 0, s = optrom, d = dwptr; - miter < OPTROM_BURST_DWORDS; miter++, s++, d++) - *s = cpu_to_le32(*d); + memcpy(optrom, dwptr, OPTROM_BURST_SIZE); ret = qla2x00_load_ram(vha, optrom_dma, flash_data_addr(ha, faddr), diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 808bab6ef06b..79f7053da99b 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.00-k1" +#define QLA2XXX_VERSION "8.03.00-k3" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 |