aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx/ql4_os.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_os.c')
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c160
1 files changed, 107 insertions, 53 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 4cec123a6a6a..6142729167f4 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -1337,18 +1337,18 @@ static int qla4xxx_session_get_param(struct iscsi_cls_session *cls_sess,
1337 sess->password_in, BIDI_CHAP, 1337 sess->password_in, BIDI_CHAP,
1338 &idx); 1338 &idx);
1339 if (rval) 1339 if (rval)
1340 return -EINVAL; 1340 len = sprintf(buf, "\n");
1341 1341 else
1342 len = sprintf(buf, "%hu\n", idx); 1342 len = sprintf(buf, "%hu\n", idx);
1343 break; 1343 break;
1344 case ISCSI_PARAM_CHAP_OUT_IDX: 1344 case ISCSI_PARAM_CHAP_OUT_IDX:
1345 rval = qla4xxx_get_chap_index(ha, sess->username, 1345 rval = qla4xxx_get_chap_index(ha, sess->username,
1346 sess->password, LOCAL_CHAP, 1346 sess->password, LOCAL_CHAP,
1347 &idx); 1347 &idx);
1348 if (rval) 1348 if (rval)
1349 return -EINVAL; 1349 len = sprintf(buf, "\n");
1350 1350 else
1351 len = sprintf(buf, "%hu\n", idx); 1351 len = sprintf(buf, "%hu\n", idx);
1352 break; 1352 break;
1353 default: 1353 default:
1354 return iscsi_session_get_param(cls_sess, param, buf); 1354 return iscsi_session_get_param(cls_sess, param, buf);
@@ -2242,6 +2242,7 @@ static int qla4xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
2242 test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags) || 2242 test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags) ||
2243 !test_bit(AF_ONLINE, &ha->flags) || 2243 !test_bit(AF_ONLINE, &ha->flags) ||
2244 !test_bit(AF_LINK_UP, &ha->flags) || 2244 !test_bit(AF_LINK_UP, &ha->flags) ||
2245 test_bit(AF_LOOPBACK, &ha->flags) ||
2245 test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) 2246 test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))
2246 goto qc_host_busy; 2247 goto qc_host_busy;
2247 2248
@@ -2978,6 +2979,7 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
2978 if (status == QLA_SUCCESS) { 2979 if (status == QLA_SUCCESS) {
2979 if (!test_bit(AF_FW_RECOVERY, &ha->flags)) 2980 if (!test_bit(AF_FW_RECOVERY, &ha->flags))
2980 qla4xxx_cmd_wait(ha); 2981 qla4xxx_cmd_wait(ha);
2982
2981 ha->isp_ops->disable_intrs(ha); 2983 ha->isp_ops->disable_intrs(ha);
2982 qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); 2984 qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
2983 qla4xxx_abort_active_cmds(ha, DID_RESET << 16); 2985 qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
@@ -3479,7 +3481,8 @@ dpc_post_reset_ha:
3479 } 3481 }
3480 3482
3481 /* ---- link change? --- */ 3483 /* ---- link change? --- */
3482 if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) { 3484 if (!test_bit(AF_LOOPBACK, &ha->flags) &&
3485 test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) {
3483 if (!test_bit(AF_LINK_UP, &ha->flags)) { 3486 if (!test_bit(AF_LINK_UP, &ha->flags)) {
3484 /* ---- link down? --- */ 3487 /* ---- link down? --- */
3485 qla4xxx_mark_all_devices_missing(ha); 3488 qla4xxx_mark_all_devices_missing(ha);
@@ -3508,10 +3511,8 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
3508{ 3511{
3509 qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16); 3512 qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16);
3510 3513
3511 if (test_bit(AF_INTERRUPTS_ON, &ha->flags)) { 3514 /* Turn-off interrupts on the card. */
3512 /* Turn-off interrupts on the card. */ 3515 ha->isp_ops->disable_intrs(ha);
3513 ha->isp_ops->disable_intrs(ha);
3514 }
3515 3516
3516 if (is_qla40XX(ha)) { 3517 if (is_qla40XX(ha)) {
3517 writel(set_rmask(CSR_SCSI_PROCESSOR_INTR), 3518 writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
@@ -3547,8 +3548,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
3547 } 3548 }
3548 3549
3549 /* Detach interrupts */ 3550 /* Detach interrupts */
3550 if (test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags)) 3551 qla4xxx_free_irqs(ha);
3551 qla4xxx_free_irqs(ha);
3552 3552
3553 /* free extra memory */ 3553 /* free extra memory */
3554 qla4xxx_mem_free(ha); 3554 qla4xxx_mem_free(ha);
@@ -4687,7 +4687,8 @@ static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha,
4687 struct iscsi_endpoint *ep; 4687 struct iscsi_endpoint *ep;
4688 struct sockaddr_in *addr; 4688 struct sockaddr_in *addr;
4689 struct sockaddr_in6 *addr6; 4689 struct sockaddr_in6 *addr6;
4690 struct sockaddr *dst_addr; 4690 struct sockaddr *t_addr;
4691 struct sockaddr_storage *dst_addr;
4691 char *ip; 4692 char *ip;
4692 4693
4693 /* TODO: need to destroy on unload iscsi_endpoint*/ 4694 /* TODO: need to destroy on unload iscsi_endpoint*/
@@ -4696,21 +4697,23 @@ static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha,
4696 return NULL; 4697 return NULL;
4697 4698
4698 if (fw_ddb_entry->options & DDB_OPT_IPV6_DEVICE) { 4699 if (fw_ddb_entry->options & DDB_OPT_IPV6_DEVICE) {
4699 dst_addr->sa_family = AF_INET6; 4700 t_addr = (struct sockaddr *)dst_addr;
4701 t_addr->sa_family = AF_INET6;
4700 addr6 = (struct sockaddr_in6 *)dst_addr; 4702 addr6 = (struct sockaddr_in6 *)dst_addr;
4701 ip = (char *)&addr6->sin6_addr; 4703 ip = (char *)&addr6->sin6_addr;
4702 memcpy(ip, fw_ddb_entry->ip_addr, IPv6_ADDR_LEN); 4704 memcpy(ip, fw_ddb_entry->ip_addr, IPv6_ADDR_LEN);
4703 addr6->sin6_port = htons(le16_to_cpu(fw_ddb_entry->port)); 4705 addr6->sin6_port = htons(le16_to_cpu(fw_ddb_entry->port));
4704 4706
4705 } else { 4707 } else {
4706 dst_addr->sa_family = AF_INET; 4708 t_addr = (struct sockaddr *)dst_addr;
4709 t_addr->sa_family = AF_INET;
4707 addr = (struct sockaddr_in *)dst_addr; 4710 addr = (struct sockaddr_in *)dst_addr;
4708 ip = (char *)&addr->sin_addr; 4711 ip = (char *)&addr->sin_addr;
4709 memcpy(ip, fw_ddb_entry->ip_addr, IP_ADDR_LEN); 4712 memcpy(ip, fw_ddb_entry->ip_addr, IP_ADDR_LEN);
4710 addr->sin_port = htons(le16_to_cpu(fw_ddb_entry->port)); 4713 addr->sin_port = htons(le16_to_cpu(fw_ddb_entry->port));
4711 } 4714 }
4712 4715
4713 ep = qla4xxx_ep_connect(ha->host, dst_addr, 0); 4716 ep = qla4xxx_ep_connect(ha->host, (struct sockaddr *)dst_addr, 0);
4714 vfree(dst_addr); 4717 vfree(dst_addr);
4715 return ep; 4718 return ep;
4716} 4719}
@@ -4725,7 +4728,8 @@ static int qla4xxx_verify_boot_idx(struct scsi_qla_host *ha, uint16_t idx)
4725} 4728}
4726 4729
4727static void qla4xxx_setup_flash_ddb_entry(struct scsi_qla_host *ha, 4730static void qla4xxx_setup_flash_ddb_entry(struct scsi_qla_host *ha,
4728 struct ddb_entry *ddb_entry) 4731 struct ddb_entry *ddb_entry,
4732 uint16_t idx)
4729{ 4733{
4730 uint16_t def_timeout; 4734 uint16_t def_timeout;
4731 4735
@@ -4745,6 +4749,10 @@ static void qla4xxx_setup_flash_ddb_entry(struct scsi_qla_host *ha,
4745 def_timeout : LOGIN_TOV; 4749 def_timeout : LOGIN_TOV;
4746 ddb_entry->default_time2wait = 4750 ddb_entry->default_time2wait =
4747 le16_to_cpu(ddb_entry->fw_ddb_entry.iscsi_def_time2wait); 4751 le16_to_cpu(ddb_entry->fw_ddb_entry.iscsi_def_time2wait);
4752
4753 if (ql4xdisablesysfsboot &&
4754 (idx == ha->pri_ddb_idx || idx == ha->sec_ddb_idx))
4755 set_bit(DF_BOOT_TGT, &ddb_entry->flags);
4748} 4756}
4749 4757
4750static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha) 4758static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha)
@@ -4881,7 +4889,7 @@ static void qla4xxx_remove_failed_ddb(struct scsi_qla_host *ha,
4881 4889
4882static int qla4xxx_sess_conn_setup(struct scsi_qla_host *ha, 4890static int qla4xxx_sess_conn_setup(struct scsi_qla_host *ha,
4883 struct dev_db_entry *fw_ddb_entry, 4891 struct dev_db_entry *fw_ddb_entry,
4884 int is_reset) 4892 int is_reset, uint16_t idx)
4885{ 4893{
4886 struct iscsi_cls_session *cls_sess; 4894 struct iscsi_cls_session *cls_sess;
4887 struct iscsi_session *sess; 4895 struct iscsi_session *sess;
@@ -4919,7 +4927,7 @@ static int qla4xxx_sess_conn_setup(struct scsi_qla_host *ha,
4919 memcpy(&ddb_entry->fw_ddb_entry, fw_ddb_entry, 4927 memcpy(&ddb_entry->fw_ddb_entry, fw_ddb_entry,
4920 sizeof(struct dev_db_entry)); 4928 sizeof(struct dev_db_entry));
4921 4929
4922 qla4xxx_setup_flash_ddb_entry(ha, ddb_entry); 4930 qla4xxx_setup_flash_ddb_entry(ha, ddb_entry, idx);
4923 4931
4924 cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn), conn_id); 4932 cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn), conn_id);
4925 4933
@@ -5036,7 +5044,7 @@ static void qla4xxx_build_nt_list(struct scsi_qla_host *ha,
5036 goto continue_next_nt; 5044 goto continue_next_nt;
5037 } 5045 }
5038 5046
5039 ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, is_reset); 5047 ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, is_reset, idx);
5040 if (ret == QLA_ERROR) 5048 if (ret == QLA_ERROR)
5041 goto exit_nt_list; 5049 goto exit_nt_list;
5042 5050
@@ -5116,6 +5124,78 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset)
5116} 5124}
5117 5125
5118/** 5126/**
5127 * qla4xxx_wait_login_resp_boot_tgt - Wait for iSCSI boot target login
5128 * response.
5129 * @ha: pointer to adapter structure
5130 *
5131 * When the boot entry is normal iSCSI target then DF_BOOT_TGT flag will be
5132 * set in DDB and we will wait for login response of boot targets during
5133 * probe.
5134 **/
5135static void qla4xxx_wait_login_resp_boot_tgt(struct scsi_qla_host *ha)
5136{
5137 struct ddb_entry *ddb_entry;
5138 struct dev_db_entry *fw_ddb_entry = NULL;
5139 dma_addr_t fw_ddb_entry_dma;
5140 unsigned long wtime;
5141 uint32_t ddb_state;
5142 int max_ddbs, idx, ret;
5143
5144 max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
5145 MAX_DEV_DB_ENTRIES;
5146
5147 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5148 &fw_ddb_entry_dma, GFP_KERNEL);
5149 if (!fw_ddb_entry) {
5150 ql4_printk(KERN_ERR, ha,
5151 "%s: Unable to allocate dma buffer\n", __func__);
5152 goto exit_login_resp;
5153 }
5154
5155 wtime = jiffies + (HZ * BOOT_LOGIN_RESP_TOV);
5156
5157 for (idx = 0; idx < max_ddbs; idx++) {
5158 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);
5159 if (ddb_entry == NULL)
5160 continue;
5161
5162 if (test_bit(DF_BOOT_TGT, &ddb_entry->flags)) {
5163 DEBUG2(ql4_printk(KERN_INFO, ha,
5164 "%s: DDB index [%d]\n", __func__,
5165 ddb_entry->fw_ddb_index));
5166 do {
5167 ret = qla4xxx_get_fwddb_entry(ha,
5168 ddb_entry->fw_ddb_index,
5169 fw_ddb_entry, fw_ddb_entry_dma,
5170 NULL, NULL, &ddb_state, NULL,
5171 NULL, NULL);
5172 if (ret == QLA_ERROR)
5173 goto exit_login_resp;
5174
5175 if ((ddb_state == DDB_DS_SESSION_ACTIVE) ||
5176 (ddb_state == DDB_DS_SESSION_FAILED))
5177 break;
5178
5179 schedule_timeout_uninterruptible(HZ);
5180
5181 } while ((time_after(wtime, jiffies)));
5182
5183 if (!time_after(wtime, jiffies)) {
5184 DEBUG2(ql4_printk(KERN_INFO, ha,
5185 "%s: Login response wait timer expired\n",
5186 __func__));
5187 goto exit_login_resp;
5188 }
5189 }
5190 }
5191
5192exit_login_resp:
5193 if (fw_ddb_entry)
5194 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5195 fw_ddb_entry, fw_ddb_entry_dma);
5196}
5197
5198/**
5119 * qla4xxx_probe_adapter - callback function to probe HBA 5199 * qla4xxx_probe_adapter - callback function to probe HBA
5120 * @pdev: pointer to pci_dev structure 5200 * @pdev: pointer to pci_dev structure
5121 * @pci_device_id: pointer to pci_device entry 5201 * @pci_device_id: pointer to pci_device entry
@@ -5270,7 +5350,7 @@ static int qla4xxx_probe_adapter(struct pci_dev *pdev,
5270 if (is_qla80XX(ha)) { 5350 if (is_qla80XX(ha)) {
5271 ha->isp_ops->idc_lock(ha); 5351 ha->isp_ops->idc_lock(ha);
5272 dev_state = qla4_8xxx_rd_direct(ha, 5352 dev_state = qla4_8xxx_rd_direct(ha,
5273 QLA82XX_CRB_DEV_STATE); 5353 QLA8XXX_CRB_DEV_STATE);
5274 ha->isp_ops->idc_unlock(ha); 5354 ha->isp_ops->idc_unlock(ha);
5275 if (dev_state == QLA8XXX_DEV_FAILED) { 5355 if (dev_state == QLA8XXX_DEV_FAILED) {
5276 ql4_printk(KERN_WARNING, ha, "%s: don't retry " 5356 ql4_printk(KERN_WARNING, ha, "%s: don't retry "
@@ -5368,6 +5448,7 @@ skip_retry_init:
5368 /* Perform the build ddb list and login to each */ 5448 /* Perform the build ddb list and login to each */
5369 qla4xxx_build_ddb_list(ha, INIT_ADAPTER); 5449 qla4xxx_build_ddb_list(ha, INIT_ADAPTER);
5370 iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb); 5450 iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb);
5451 qla4xxx_wait_login_resp_boot_tgt(ha);
5371 5452
5372 qla4xxx_create_chap_list(ha); 5453 qla4xxx_create_chap_list(ha);
5373 5454
@@ -6008,14 +6089,6 @@ static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type)
6008 goto exit_host_reset; 6089 goto exit_host_reset;
6009 } 6090 }
6010 6091
6011 rval = qla4xxx_wait_for_hba_online(ha);
6012 if (rval != QLA_SUCCESS) {
6013 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Unable to reset host "
6014 "adapter\n", __func__));
6015 rval = -EIO;
6016 goto exit_host_reset;
6017 }
6018
6019 if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) 6092 if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
6020 goto recover_adapter; 6093 goto recover_adapter;
6021 6094
@@ -6115,7 +6188,6 @@ qla4xxx_pci_mmio_enabled(struct pci_dev *pdev)
6115static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) 6188static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
6116{ 6189{
6117 uint32_t rval = QLA_ERROR; 6190 uint32_t rval = QLA_ERROR;
6118 uint32_t ret = 0;
6119 int fn; 6191 int fn;
6120 struct pci_dev *other_pdev = NULL; 6192 struct pci_dev *other_pdev = NULL;
6121 6193
@@ -6201,16 +6273,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
6201 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, 0); 6273 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, 0);
6202 qla4_8xxx_set_drv_active(ha); 6274 qla4_8xxx_set_drv_active(ha);
6203 ha->isp_ops->idc_unlock(ha); 6275 ha->isp_ops->idc_unlock(ha);
6204 ret = qla4xxx_request_irqs(ha); 6276 ha->isp_ops->enable_intrs(ha);
6205 if (ret) {
6206 ql4_printk(KERN_WARNING, ha, "Failed to "
6207 "reserve interrupt %d already in use.\n",
6208 ha->pdev->irq);
6209 rval = QLA_ERROR;
6210 } else {
6211 ha->isp_ops->enable_intrs(ha);
6212 rval = QLA_SUCCESS;
6213 }
6214 } 6277 }
6215 } else { 6278 } else {
6216 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn 0x%x is not " 6279 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn 0x%x is not "
@@ -6220,18 +6283,9 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
6220 QLA8XXX_DEV_READY)) { 6283 QLA8XXX_DEV_READY)) {
6221 clear_bit(AF_FW_RECOVERY, &ha->flags); 6284 clear_bit(AF_FW_RECOVERY, &ha->flags);
6222 rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); 6285 rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
6223 if (rval == QLA_SUCCESS) { 6286 if (rval == QLA_SUCCESS)
6224 ret = qla4xxx_request_irqs(ha); 6287 ha->isp_ops->enable_intrs(ha);
6225 if (ret) { 6288
6226 ql4_printk(KERN_WARNING, ha, "Failed to"
6227 " reserve interrupt %d already in"
6228 " use.\n", ha->pdev->irq);
6229 rval = QLA_ERROR;
6230 } else {
6231 ha->isp_ops->enable_intrs(ha);
6232 rval = QLA_SUCCESS;
6233 }
6234 }
6235 ha->isp_ops->idc_lock(ha); 6289 ha->isp_ops->idc_lock(ha);
6236 qla4_8xxx_set_drv_active(ha); 6290 qla4_8xxx_set_drv_active(ha);
6237 ha->isp_ops->idc_unlock(ha); 6291 ha->isp_ops->idc_unlock(ha);