aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
authorGiridhar Malavali <giridhar.malavali@qlogic.com>2010-04-12 20:59:55 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-01 15:11:17 -0400
commita9083016a5314b3aeba6e0d2e814872e72168c08 (patch)
tree5b8dbdfe6abfe1c452dc6684ed81eea65edc1a28 /drivers/scsi/qla2xxx/qla_init.c
parentc446c1f9907e84d014edb0bf3501f30cb512e06a (diff)
[SCSI] qla2xxx: Add ISP82XX support.
Enhanced the driver to support new FCoE host bus adapter. Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c233
1 files changed, 207 insertions, 26 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 8517aa49744a..55540d2d4e38 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -328,6 +328,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
328 if (rval) 328 if (rval)
329 return (rval); 329 return (rval);
330 } 330 }
331
331 if (IS_QLA84XX(ha)) { 332 if (IS_QLA84XX(ha)) {
332 ha->cs84xx = qla84xx_get_chip(vha); 333 ha->cs84xx = qla84xx_get_chip(vha);
333 if (!ha->cs84xx) { 334 if (!ha->cs84xx) {
@@ -961,6 +962,9 @@ qla24xx_chip_diag(scsi_qla_host_t *vha)
961 struct qla_hw_data *ha = vha->hw; 962 struct qla_hw_data *ha = vha->hw;
962 struct req_que *req = ha->req_q_map[0]; 963 struct req_que *req = ha->req_q_map[0];
963 964
965 if (IS_QLA82XX(ha))
966 return QLA_SUCCESS;
967
964 ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length; 968 ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length;
965 969
966 rval = qla2x00_mbx_reg_test(vha); 970 rval = qla2x00_mbx_reg_test(vha);
@@ -1183,6 +1187,12 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
1183 unsigned long flags; 1187 unsigned long flags;
1184 uint16_t fw_major_version; 1188 uint16_t fw_major_version;
1185 1189
1190 if (IS_QLA82XX(ha)) {
1191 rval = ha->isp_ops->load_risc(vha, &srisc_address);
1192 if (rval == QLA_SUCCESS)
1193 goto enable_82xx_npiv;
1194 }
1195
1186 if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) { 1196 if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
1187 /* Disable SRAM, Instruction RAM and GP RAM parity. */ 1197 /* Disable SRAM, Instruction RAM and GP RAM parity. */
1188 spin_lock_irqsave(&ha->hardware_lock, flags); 1198 spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -1208,6 +1218,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
1208 rval = qla2x00_execute_fw(vha, srisc_address); 1218 rval = qla2x00_execute_fw(vha, srisc_address);
1209 /* Retrieve firmware information. */ 1219 /* Retrieve firmware information. */
1210 if (rval == QLA_SUCCESS) { 1220 if (rval == QLA_SUCCESS) {
1221enable_82xx_npiv:
1211 fw_major_version = ha->fw_major_version; 1222 fw_major_version = ha->fw_major_version;
1212 rval = qla2x00_get_fw_version(vha, 1223 rval = qla2x00_get_fw_version(vha,
1213 &ha->fw_major_version, 1224 &ha->fw_major_version,
@@ -1232,8 +1243,10 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
1232 &ha->fw_xcb_count, NULL, NULL, 1243 &ha->fw_xcb_count, NULL, NULL,
1233 &ha->max_npiv_vports, NULL); 1244 &ha->max_npiv_vports, NULL);
1234 1245
1235 if (!fw_major_version && ql2xallocfwdump) 1246 if (!fw_major_version && ql2xallocfwdump) {
1236 qla2x00_alloc_fw_dump(vha); 1247 if (!IS_QLA82XX(ha))
1248 qla2x00_alloc_fw_dump(vha);
1249 }
1237 } 1250 }
1238 } else { 1251 } else {
1239 DEBUG2(printk(KERN_INFO 1252 DEBUG2(printk(KERN_INFO
@@ -1390,6 +1403,9 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
1390 int rval; 1403 int rval;
1391 struct qla_hw_data *ha = vha->hw; 1404 struct qla_hw_data *ha = vha->hw;
1392 1405
1406 if (IS_QLA82XX(ha))
1407 return;
1408
1393 /* Update Serial Link options. */ 1409 /* Update Serial Link options. */
1394 if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0) 1410 if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
1395 return; 1411 return;
@@ -1824,7 +1840,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
1824 return(rval); 1840 return(rval);
1825} 1841}
1826 1842
1827static inline void 1843inline void
1828qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len, 1844qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
1829 char *def) 1845 char *def)
1830{ 1846{
@@ -1832,7 +1848,7 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
1832 uint16_t index; 1848 uint16_t index;
1833 struct qla_hw_data *ha = vha->hw; 1849 struct qla_hw_data *ha = vha->hw;
1834 int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && 1850 int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
1835 !IS_QLA81XX(ha); 1851 !IS_QLA8XXX_TYPE(ha);
1836 1852
1837 if (memcmp(model, BINZERO, len) != 0) { 1853 if (memcmp(model, BINZERO, len) != 0) {
1838 strncpy(ha->model_number, model, len); 1854 strncpy(ha->model_number, model, len);
@@ -3552,6 +3568,45 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
3552 qla2x00_rport_del(fcport); 3568 qla2x00_rport_del(fcport);
3553} 3569}
3554 3570
3571void
3572qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
3573{
3574 struct qla_hw_data *ha = vha->hw;
3575 struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev);
3576 struct scsi_qla_host *tvp;
3577
3578 vha->flags.online = 0;
3579 ha->flags.chip_reset_done = 0;
3580 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
3581 ha->qla_stats.total_isp_aborts++;
3582
3583 qla_printk(KERN_INFO, ha,
3584 "Performing ISP error recovery - ha= %p.\n", ha);
3585
3586 /* Chip reset does not apply to 82XX */
3587 if (!IS_QLA82XX(ha))
3588 ha->isp_ops->reset_chip(vha);
3589
3590 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
3591 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
3592 atomic_set(&vha->loop_state, LOOP_DOWN);
3593 qla2x00_mark_all_devices_lost(vha, 0);
3594 list_for_each_entry_safe(vp, tvp, &base_vha->hw->vp_list, list)
3595 qla2x00_mark_all_devices_lost(vp, 0);
3596 } else {
3597 if (!atomic_read(&vha->loop_down_timer))
3598 atomic_set(&vha->loop_down_timer,
3599 LOOP_DOWN_TIME);
3600 }
3601
3602 /* Make sure for ISP 82XX IO DMA is complete */
3603 if (IS_QLA82XX(ha))
3604 qla82xx_wait_for_pending_commands(vha);
3605
3606 /* Requeue all commands in outstanding command list. */
3607 qla2x00_abort_all_cmds(vha, DID_RESET << 16);
3608}
3609
3555/* 3610/*
3556* qla2x00_abort_isp 3611* qla2x00_abort_isp
3557* Resets ISP and aborts all outstanding commands. 3612* Resets ISP and aborts all outstanding commands.
@@ -3573,27 +3628,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
3573 struct req_que *req = ha->req_q_map[0]; 3628 struct req_que *req = ha->req_q_map[0];
3574 3629
3575 if (vha->flags.online) { 3630 if (vha->flags.online) {
3576 vha->flags.online = 0; 3631 qla2x00_abort_isp_cleanup(vha);
3577 ha->flags.chip_reset_done = 0;
3578 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
3579 ha->qla_stats.total_isp_aborts++;
3580
3581 qla_printk(KERN_INFO, ha,
3582 "Performing ISP error recovery - ha= %p.\n", ha);
3583 ha->isp_ops->reset_chip(vha);
3584
3585 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
3586 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
3587 atomic_set(&vha->loop_state, LOOP_DOWN);
3588 qla2x00_mark_all_devices_lost(vha, 0);
3589 } else {
3590 if (!atomic_read(&vha->loop_down_timer))
3591 atomic_set(&vha->loop_down_timer,
3592 LOOP_DOWN_TIME);
3593 }
3594
3595 /* Requeue all commands in outstanding command list. */
3596 qla2x00_abort_all_cmds(vha, DID_RESET << 16);
3597 3632
3598 if (unlikely(pci_channel_offline(ha->pdev) && 3633 if (unlikely(pci_channel_offline(ha->pdev) &&
3599 ha->flags.pci_channel_io_perm_failure)) { 3634 ha->flags.pci_channel_io_perm_failure)) {
@@ -3849,6 +3884,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha)
3849 struct qla_hw_data *ha = vha->hw; 3884 struct qla_hw_data *ha = vha->hw;
3850 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 3885 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3851 3886
3887 if (IS_QLA82XX(ha))
3888 return;
3889
3852 vha->flags.online = 0; 3890 vha->flags.online = 0;
3853 ha->isp_ops->disable_intrs(ha); 3891 ha->isp_ops->disable_intrs(ha);
3854 3892
@@ -3912,6 +3950,8 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
3912 } 3950 }
3913 ha->nvram_size = sizeof(struct nvram_24xx); 3951 ha->nvram_size = sizeof(struct nvram_24xx);
3914 ha->vpd_size = FA_NVRAM_VPD_SIZE; 3952 ha->vpd_size = FA_NVRAM_VPD_SIZE;
3953 if (IS_QLA82XX(ha))
3954 ha->vpd_size = FA_VPD_SIZE_82XX;
3915 3955
3916 /* Get VPD data into cache */ 3956 /* Get VPD data into cache */
3917 ha->vpd = ha->nvram + VPD_OFFSET; 3957 ha->vpd = ha->nvram + VPD_OFFSET;
@@ -4775,7 +4815,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
4775 * Setup driver NVRAM options. 4815 * Setup driver NVRAM options.
4776 */ 4816 */
4777 qla2x00_set_model_info(vha, nv->model_name, sizeof(nv->model_name), 4817 qla2x00_set_model_info(vha, nv->model_name, sizeof(nv->model_name),
4778 "QLE81XX"); 4818 "QLE8XXX");
4779 4819
4780 /* Use alternate WWN? */ 4820 /* Use alternate WWN? */
4781 if (nv->host_p & __constant_cpu_to_le32(BIT_15)) { 4821 if (nv->host_p & __constant_cpu_to_le32(BIT_15)) {
@@ -4898,6 +4938,147 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
4898 return (rval); 4938 return (rval);
4899} 4939}
4900 4940
4941int
4942qla82xx_restart_isp(scsi_qla_host_t *vha)
4943{
4944 int status, rval;
4945 uint32_t wait_time;
4946 struct qla_hw_data *ha = vha->hw;
4947 struct req_que *req = ha->req_q_map[0];
4948 struct rsp_que *rsp = ha->rsp_q_map[0];
4949 struct scsi_qla_host *vp;
4950 struct scsi_qla_host *tvp;
4951
4952 status = qla2x00_init_rings(vha);
4953 if (!status) {
4954 clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
4955 ha->flags.chip_reset_done = 1;
4956
4957 status = qla2x00_fw_ready(vha);
4958 if (!status) {
4959 qla_printk(KERN_INFO, ha,
4960 "%s(): Start configure loop, "
4961 "status = %d\n", __func__, status);
4962
4963 /* Issue a marker after FW becomes ready. */
4964 qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
4965
4966 vha->flags.online = 1;
4967 /* Wait at most MAX_TARGET RSCNs for a stable link. */
4968 wait_time = 256;
4969 do {
4970 clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
4971 qla2x00_configure_loop(vha);
4972 wait_time--;
4973 } while (!atomic_read(&vha->loop_down_timer) &&
4974 !(test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) &&
4975 wait_time &&
4976 (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)));
4977 }
4978
4979 /* if no cable then assume it's good */
4980 if ((vha->device_flags & DFLG_NO_CABLE))
4981 status = 0;
4982
4983 qla_printk(KERN_INFO, ha,
4984 "%s(): Configure loop done, status = 0x%x\n",
4985 __func__, status);
4986 }
4987
4988 if (!status) {
4989 clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
4990
4991 if (!atomic_read(&vha->loop_down_timer)) {
4992 /*
4993 * Issue marker command only when we are going
4994 * to start the I/O .
4995 */
4996 vha->marker_needed = 1;
4997 }
4998
4999 vha->flags.online = 1;
5000
5001 ha->isp_ops->enable_intrs(ha);
5002
5003 ha->isp_abort_cnt = 0;
5004 clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
5005
5006 if (ha->fce) {
5007 ha->flags.fce_enabled = 1;
5008 memset(ha->fce, 0,
5009 fce_calc_size(ha->fce_bufs));
5010 rval = qla2x00_enable_fce_trace(vha,
5011 ha->fce_dma, ha->fce_bufs, ha->fce_mb,
5012 &ha->fce_bufs);
5013 if (rval) {
5014 qla_printk(KERN_WARNING, ha,
5015 "Unable to reinitialize FCE "
5016 "(%d).\n", rval);
5017 ha->flags.fce_enabled = 0;
5018 }
5019 }
5020
5021 if (ha->eft) {
5022 memset(ha->eft, 0, EFT_SIZE);
5023 rval = qla2x00_enable_eft_trace(vha,
5024 ha->eft_dma, EFT_NUM_BUFFERS);
5025 if (rval) {
5026 qla_printk(KERN_WARNING, ha,
5027 "Unable to reinitialize EFT "
5028 "(%d).\n", rval);
5029 }
5030 }
5031 } else { /* failed the ISP abort */
5032 vha->flags.online = 1;
5033 if (test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
5034 if (ha->isp_abort_cnt == 0) {
5035 qla_printk(KERN_WARNING, ha,
5036 "ISP error recovery failed - "
5037 "board disabled\n");
5038 /*
5039 * The next call disables the board
5040 * completely.
5041 */
5042 ha->isp_ops->reset_adapter(vha);
5043 vha->flags.online = 0;
5044 clear_bit(ISP_ABORT_RETRY,
5045 &vha->dpc_flags);
5046 status = 0;
5047 } else { /* schedule another ISP abort */
5048 ha->isp_abort_cnt--;
5049 qla_printk(KERN_INFO, ha,
5050 "qla%ld: ISP abort - "
5051 "retry remaining %d\n",
5052 vha->host_no, ha->isp_abort_cnt);
5053 status = 1;
5054 }
5055 } else {
5056 ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT;
5057 qla_printk(KERN_INFO, ha,
5058 "(%ld): ISP error recovery "
5059 "- retrying (%d) more times\n",
5060 vha->host_no, ha->isp_abort_cnt);
5061 set_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
5062 status = 1;
5063 }
5064 }
5065
5066 if (!status) {
5067 DEBUG(printk(KERN_INFO
5068 "qla82xx_restart_isp(%ld): succeeded.\n",
5069 vha->host_no));
5070 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
5071 if (vp->vp_idx)
5072 qla2x00_vp_abort_isp(vp);
5073 }
5074 } else {
5075 qla_printk(KERN_INFO, ha,
5076 "qla82xx_restart_isp: **** FAILED ****\n");
5077 }
5078
5079 return status;
5080}
5081
4901void 5082void
4902qla81xx_update_fw_options(scsi_qla_host_t *vha) 5083qla81xx_update_fw_options(scsi_qla_host_t *vha)
4903{ 5084{