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.c1084
1 files changed, 1030 insertions, 54 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 30f31b127f3..4169c8baa11 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -8,6 +8,7 @@
8#include <linux/slab.h> 8#include <linux/slab.h>
9#include <linux/blkdev.h> 9#include <linux/blkdev.h>
10#include <linux/iscsi_boot_sysfs.h> 10#include <linux/iscsi_boot_sysfs.h>
11#include <linux/inet.h>
11 12
12#include <scsi/scsi_tcq.h> 13#include <scsi/scsi_tcq.h>
13#include <scsi/scsicam.h> 14#include <scsi/scsicam.h>
@@ -31,6 +32,13 @@ static struct kmem_cache *srb_cachep;
31/* 32/*
32 * Module parameter information and variables 33 * Module parameter information and variables
33 */ 34 */
35int ql4xdisablesysfsboot = 1;
36module_param(ql4xdisablesysfsboot, int, S_IRUGO | S_IWUSR);
37MODULE_PARM_DESC(ql4xdisablesysfsboot,
38 "Set to disable exporting boot targets to sysfs\n"
39 " 0 - Export boot targets\n"
40 " 1 - Do not export boot targets (Default)");
41
34int ql4xdontresethba = 0; 42int ql4xdontresethba = 0;
35module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR); 43module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR);
36MODULE_PARM_DESC(ql4xdontresethba, 44MODULE_PARM_DESC(ql4xdontresethba,
@@ -63,7 +71,7 @@ static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO;
63module_param(ql4xsess_recovery_tmo, int, S_IRUGO); 71module_param(ql4xsess_recovery_tmo, int, S_IRUGO);
64MODULE_PARM_DESC(ql4xsess_recovery_tmo, 72MODULE_PARM_DESC(ql4xsess_recovery_tmo,
65 "Target Session Recovery Timeout.\n" 73 "Target Session Recovery Timeout.\n"
66 " Default: 30 sec."); 74 " Default: 120 sec.");
67 75
68static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha); 76static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha);
69/* 77/*
@@ -415,7 +423,7 @@ static int qla4xxx_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
415 qla_ep = ep->dd_data; 423 qla_ep = ep->dd_data;
416 ha = to_qla_host(qla_ep->host); 424 ha = to_qla_host(qla_ep->host);
417 425
418 if (adapter_up(ha)) 426 if (adapter_up(ha) && !test_bit(AF_BUILD_DDB_LIST, &ha->flags))
419 ret = 1; 427 ret = 1;
420 428
421 return ret; 429 return ret;
@@ -975,6 +983,150 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn,
975 983
976} 984}
977 985
986int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index)
987{
988 uint32_t mbx_sts = 0;
989 uint16_t tmp_ddb_index;
990 int ret;
991
992get_ddb_index:
993 tmp_ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES);
994
995 if (tmp_ddb_index >= MAX_DDB_ENTRIES) {
996 DEBUG2(ql4_printk(KERN_INFO, ha,
997 "Free DDB index not available\n"));
998 ret = QLA_ERROR;
999 goto exit_get_ddb_index;
1000 }
1001
1002 if (test_and_set_bit(tmp_ddb_index, ha->ddb_idx_map))
1003 goto get_ddb_index;
1004
1005 DEBUG2(ql4_printk(KERN_INFO, ha,
1006 "Found a free DDB index at %d\n", tmp_ddb_index));
1007 ret = qla4xxx_req_ddb_entry(ha, tmp_ddb_index, &mbx_sts);
1008 if (ret == QLA_ERROR) {
1009 if (mbx_sts == MBOX_STS_COMMAND_ERROR) {
1010 ql4_printk(KERN_INFO, ha,
1011 "DDB index = %d not available trying next\n",
1012 tmp_ddb_index);
1013 goto get_ddb_index;
1014 }
1015 DEBUG2(ql4_printk(KERN_INFO, ha,
1016 "Free FW DDB not available\n"));
1017 }
1018
1019 *ddb_index = tmp_ddb_index;
1020
1021exit_get_ddb_index:
1022 return ret;
1023}
1024
1025static int qla4xxx_match_ipaddress(struct scsi_qla_host *ha,
1026 struct ddb_entry *ddb_entry,
1027 char *existing_ipaddr,
1028 char *user_ipaddr)
1029{
1030 uint8_t dst_ipaddr[IPv6_ADDR_LEN];
1031 char formatted_ipaddr[DDB_IPADDR_LEN];
1032 int status = QLA_SUCCESS, ret = 0;
1033
1034 if (ddb_entry->fw_ddb_entry.options & DDB_OPT_IPV6_DEVICE) {
1035 ret = in6_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr,
1036 '\0', NULL);
1037 if (ret == 0) {
1038 status = QLA_ERROR;
1039 goto out_match;
1040 }
1041 ret = sprintf(formatted_ipaddr, "%pI6", dst_ipaddr);
1042 } else {
1043 ret = in4_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr,
1044 '\0', NULL);
1045 if (ret == 0) {
1046 status = QLA_ERROR;
1047 goto out_match;
1048 }
1049 ret = sprintf(formatted_ipaddr, "%pI4", dst_ipaddr);
1050 }
1051
1052 if (strcmp(existing_ipaddr, formatted_ipaddr))
1053 status = QLA_ERROR;
1054
1055out_match:
1056 return status;
1057}
1058
1059static int qla4xxx_match_fwdb_session(struct scsi_qla_host *ha,
1060 struct iscsi_cls_conn *cls_conn)
1061{
1062 int idx = 0, max_ddbs, rval;
1063 struct iscsi_cls_session *cls_sess = iscsi_conn_to_session(cls_conn);
1064 struct iscsi_session *sess, *existing_sess;
1065 struct iscsi_conn *conn, *existing_conn;
1066 struct ddb_entry *ddb_entry;
1067
1068 sess = cls_sess->dd_data;
1069 conn = cls_conn->dd_data;
1070
1071 if (sess->targetname == NULL ||
1072 conn->persistent_address == NULL ||
1073 conn->persistent_port == 0)
1074 return QLA_ERROR;
1075
1076 max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
1077 MAX_DEV_DB_ENTRIES;
1078
1079 for (idx = 0; idx < max_ddbs; idx++) {
1080 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);
1081 if (ddb_entry == NULL)
1082 continue;
1083
1084 if (ddb_entry->ddb_type != FLASH_DDB)
1085 continue;
1086
1087 existing_sess = ddb_entry->sess->dd_data;
1088 existing_conn = ddb_entry->conn->dd_data;
1089
1090 if (existing_sess->targetname == NULL ||
1091 existing_conn->persistent_address == NULL ||
1092 existing_conn->persistent_port == 0)
1093 continue;
1094
1095 DEBUG2(ql4_printk(KERN_INFO, ha,
1096 "IQN = %s User IQN = %s\n",
1097 existing_sess->targetname,
1098 sess->targetname));
1099
1100 DEBUG2(ql4_printk(KERN_INFO, ha,
1101 "IP = %s User IP = %s\n",
1102 existing_conn->persistent_address,
1103 conn->persistent_address));
1104
1105 DEBUG2(ql4_printk(KERN_INFO, ha,
1106 "Port = %d User Port = %d\n",
1107 existing_conn->persistent_port,
1108 conn->persistent_port));
1109
1110 if (strcmp(existing_sess->targetname, sess->targetname))
1111 continue;
1112 rval = qla4xxx_match_ipaddress(ha, ddb_entry,
1113 existing_conn->persistent_address,
1114 conn->persistent_address);
1115 if (rval == QLA_ERROR)
1116 continue;
1117 if (existing_conn->persistent_port != conn->persistent_port)
1118 continue;
1119 break;
1120 }
1121
1122 if (idx == max_ddbs)
1123 return QLA_ERROR;
1124
1125 DEBUG2(ql4_printk(KERN_INFO, ha,
1126 "Match found in fwdb sessions\n"));
1127 return QLA_SUCCESS;
1128}
1129
978static struct iscsi_cls_session * 1130static struct iscsi_cls_session *
979qla4xxx_session_create(struct iscsi_endpoint *ep, 1131qla4xxx_session_create(struct iscsi_endpoint *ep,
980 uint16_t cmds_max, uint16_t qdepth, 1132 uint16_t cmds_max, uint16_t qdepth,
@@ -984,8 +1136,7 @@ qla4xxx_session_create(struct iscsi_endpoint *ep,
984 struct scsi_qla_host *ha; 1136 struct scsi_qla_host *ha;
985 struct qla_endpoint *qla_ep; 1137 struct qla_endpoint *qla_ep;
986 struct ddb_entry *ddb_entry; 1138 struct ddb_entry *ddb_entry;
987 uint32_t ddb_index; 1139 uint16_t ddb_index;
988 uint32_t mbx_sts = 0;
989 struct iscsi_session *sess; 1140 struct iscsi_session *sess;
990 struct sockaddr *dst_addr; 1141 struct sockaddr *dst_addr;
991 int ret; 1142 int ret;
@@ -1000,32 +1151,9 @@ qla4xxx_session_create(struct iscsi_endpoint *ep,
1000 dst_addr = (struct sockaddr *)&qla_ep->dst_addr; 1151 dst_addr = (struct sockaddr *)&qla_ep->dst_addr;
1001 ha = to_qla_host(qla_ep->host); 1152 ha = to_qla_host(qla_ep->host);
1002 1153
1003get_ddb_index: 1154 ret = qla4xxx_get_ddb_index(ha, &ddb_index);
1004 ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES); 1155 if (ret == QLA_ERROR)
1005
1006 if (ddb_index >= MAX_DDB_ENTRIES) {
1007 DEBUG2(ql4_printk(KERN_INFO, ha,
1008 "Free DDB index not available\n"));
1009 return NULL;
1010 }
1011
1012 if (test_and_set_bit(ddb_index, ha->ddb_idx_map))
1013 goto get_ddb_index;
1014
1015 DEBUG2(ql4_printk(KERN_INFO, ha,
1016 "Found a free DDB index at %d\n", ddb_index));
1017 ret = qla4xxx_req_ddb_entry(ha, ddb_index, &mbx_sts);
1018 if (ret == QLA_ERROR) {
1019 if (mbx_sts == MBOX_STS_COMMAND_ERROR) {
1020 ql4_printk(KERN_INFO, ha,
1021 "DDB index = %d not available trying next\n",
1022 ddb_index);
1023 goto get_ddb_index;
1024 }
1025 DEBUG2(ql4_printk(KERN_INFO, ha,
1026 "Free FW DDB not available\n"));
1027 return NULL; 1156 return NULL;
1028 }
1029 1157
1030 cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, qla_ep->host, 1158 cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, qla_ep->host,
1031 cmds_max, sizeof(struct ddb_entry), 1159 cmds_max, sizeof(struct ddb_entry),
@@ -1040,6 +1168,8 @@ get_ddb_index:
1040 ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE; 1168 ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE;
1041 ddb_entry->ha = ha; 1169 ddb_entry->ha = ha;
1042 ddb_entry->sess = cls_sess; 1170 ddb_entry->sess = cls_sess;
1171 ddb_entry->unblock_sess = qla4xxx_unblock_ddb;
1172 ddb_entry->ddb_change = qla4xxx_ddb_change;
1043 cls_sess->recovery_tmo = ql4xsess_recovery_tmo; 1173 cls_sess->recovery_tmo = ql4xsess_recovery_tmo;
1044 ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry; 1174 ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry;
1045 ha->tot_ddbs++; 1175 ha->tot_ddbs++;
@@ -1077,6 +1207,9 @@ qla4xxx_conn_create(struct iscsi_cls_session *cls_sess, uint32_t conn_idx)
1077 DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); 1207 DEBUG2(printk(KERN_INFO "Func: %s\n", __func__));
1078 cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn), 1208 cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn),
1079 conn_idx); 1209 conn_idx);
1210 if (!cls_conn)
1211 return NULL;
1212
1080 sess = cls_sess->dd_data; 1213 sess = cls_sess->dd_data;
1081 ddb_entry = sess->dd_data; 1214 ddb_entry = sess->dd_data;
1082 ddb_entry->conn = cls_conn; 1215 ddb_entry->conn = cls_conn;
@@ -1109,7 +1242,7 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn)
1109 struct iscsi_session *sess; 1242 struct iscsi_session *sess;
1110 struct ddb_entry *ddb_entry; 1243 struct ddb_entry *ddb_entry;
1111 struct scsi_qla_host *ha; 1244 struct scsi_qla_host *ha;
1112 struct dev_db_entry *fw_ddb_entry; 1245 struct dev_db_entry *fw_ddb_entry = NULL;
1113 dma_addr_t fw_ddb_entry_dma; 1246 dma_addr_t fw_ddb_entry_dma;
1114 uint32_t mbx_sts = 0; 1247 uint32_t mbx_sts = 0;
1115 int ret = 0; 1248 int ret = 0;
@@ -1120,12 +1253,25 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn)
1120 ddb_entry = sess->dd_data; 1253 ddb_entry = sess->dd_data;
1121 ha = ddb_entry->ha; 1254 ha = ddb_entry->ha;
1122 1255
1256 /* Check if we have matching FW DDB, if yes then do not
1257 * login to this target. This could cause target to logout previous
1258 * connection
1259 */
1260 ret = qla4xxx_match_fwdb_session(ha, cls_conn);
1261 if (ret == QLA_SUCCESS) {
1262 ql4_printk(KERN_INFO, ha,
1263 "Session already exist in FW.\n");
1264 ret = -EEXIST;
1265 goto exit_conn_start;
1266 }
1267
1123 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1268 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1124 &fw_ddb_entry_dma, GFP_KERNEL); 1269 &fw_ddb_entry_dma, GFP_KERNEL);
1125 if (!fw_ddb_entry) { 1270 if (!fw_ddb_entry) {
1126 ql4_printk(KERN_ERR, ha, 1271 ql4_printk(KERN_ERR, ha,
1127 "%s: Unable to allocate dma buffer\n", __func__); 1272 "%s: Unable to allocate dma buffer\n", __func__);
1128 return -ENOMEM; 1273 ret = -ENOMEM;
1274 goto exit_conn_start;
1129 } 1275 }
1130 1276
1131 ret = qla4xxx_set_param_ddbentry(ha, ddb_entry, cls_conn, &mbx_sts); 1277 ret = qla4xxx_set_param_ddbentry(ha, ddb_entry, cls_conn, &mbx_sts);
@@ -1138,9 +1284,7 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn)
1138 if (mbx_sts) 1284 if (mbx_sts)
1139 if (ddb_entry->fw_ddb_device_state == 1285 if (ddb_entry->fw_ddb_device_state ==
1140 DDB_DS_SESSION_ACTIVE) { 1286 DDB_DS_SESSION_ACTIVE) {
1141 iscsi_conn_start(ddb_entry->conn); 1287 ddb_entry->unblock_sess(ddb_entry->sess);
1142 iscsi_conn_login_event(ddb_entry->conn,
1143 ISCSI_CONN_STATE_LOGGED_IN);
1144 goto exit_set_param; 1288 goto exit_set_param;
1145 } 1289 }
1146 1290
@@ -1167,8 +1311,9 @@ exit_set_param:
1167 ret = 0; 1311 ret = 0;
1168 1312
1169exit_conn_start: 1313exit_conn_start:
1170 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1314 if (fw_ddb_entry)
1171 fw_ddb_entry, fw_ddb_entry_dma); 1315 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1316 fw_ddb_entry, fw_ddb_entry_dma);
1172 return ret; 1317 return ret;
1173} 1318}
1174 1319
@@ -1344,6 +1489,101 @@ static int qla4xxx_task_xmit(struct iscsi_task *task)
1344 return -ENOSYS; 1489 return -ENOSYS;
1345} 1490}
1346 1491
1492static void qla4xxx_copy_fwddb_param(struct scsi_qla_host *ha,
1493 struct dev_db_entry *fw_ddb_entry,
1494 struct iscsi_cls_session *cls_sess,
1495 struct iscsi_cls_conn *cls_conn)
1496{
1497 int buflen = 0;
1498 struct iscsi_session *sess;
1499 struct iscsi_conn *conn;
1500 char ip_addr[DDB_IPADDR_LEN];
1501 uint16_t options = 0;
1502
1503 sess = cls_sess->dd_data;
1504 conn = cls_conn->dd_data;
1505
1506 conn->max_recv_dlength = BYTE_UNITS *
1507 le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len);
1508
1509 conn->max_xmit_dlength = BYTE_UNITS *
1510 le16_to_cpu(fw_ddb_entry->iscsi_max_snd_data_seg_len);
1511
1512 sess->initial_r2t_en =
1513 (BIT_10 & le16_to_cpu(fw_ddb_entry->iscsi_options));
1514
1515 sess->max_r2t = le16_to_cpu(fw_ddb_entry->iscsi_max_outsnd_r2t);
1516
1517 sess->imm_data_en = (BIT_11 & le16_to_cpu(fw_ddb_entry->iscsi_options));
1518
1519 sess->first_burst = BYTE_UNITS *
1520 le16_to_cpu(fw_ddb_entry->iscsi_first_burst_len);
1521
1522 sess->max_burst = BYTE_UNITS *
1523 le16_to_cpu(fw_ddb_entry->iscsi_max_burst_len);
1524
1525 sess->time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);
1526
1527 sess->time2retain = le16_to_cpu(fw_ddb_entry->iscsi_def_time2retain);
1528
1529 conn->persistent_port = le16_to_cpu(fw_ddb_entry->port);
1530
1531 sess->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
1532
1533 options = le16_to_cpu(fw_ddb_entry->options);
1534 if (options & DDB_OPT_IPV6_DEVICE)
1535 sprintf(ip_addr, "%pI6", fw_ddb_entry->ip_addr);
1536 else
1537 sprintf(ip_addr, "%pI4", fw_ddb_entry->ip_addr);
1538
1539 iscsi_set_param(cls_conn, ISCSI_PARAM_TARGET_NAME,
1540 (char *)fw_ddb_entry->iscsi_name, buflen);
1541 iscsi_set_param(cls_conn, ISCSI_PARAM_INITIATOR_NAME,
1542 (char *)ha->name_string, buflen);
1543 iscsi_set_param(cls_conn, ISCSI_PARAM_PERSISTENT_ADDRESS,
1544 (char *)ip_addr, buflen);
1545}
1546
1547void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha,
1548 struct ddb_entry *ddb_entry)
1549{
1550 struct iscsi_cls_session *cls_sess;
1551 struct iscsi_cls_conn *cls_conn;
1552 uint32_t ddb_state;
1553 dma_addr_t fw_ddb_entry_dma;
1554 struct dev_db_entry *fw_ddb_entry;
1555
1556 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1557 &fw_ddb_entry_dma, GFP_KERNEL);
1558 if (!fw_ddb_entry) {
1559 ql4_printk(KERN_ERR, ha,
1560 "%s: Unable to allocate dma buffer\n", __func__);
1561 goto exit_session_conn_fwddb_param;
1562 }
1563
1564 if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry,
1565 fw_ddb_entry_dma, NULL, NULL, &ddb_state,
1566 NULL, NULL, NULL) == QLA_ERROR) {
1567 DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "
1568 "get_ddb_entry for fw_ddb_index %d\n",
1569 ha->host_no, __func__,
1570 ddb_entry->fw_ddb_index));
1571 goto exit_session_conn_fwddb_param;
1572 }
1573
1574 cls_sess = ddb_entry->sess;
1575
1576 cls_conn = ddb_entry->conn;
1577
1578 /* Update params */
1579 qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, cls_conn);
1580
1581exit_session_conn_fwddb_param:
1582 if (fw_ddb_entry)
1583 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1584 fw_ddb_entry, fw_ddb_entry_dma);
1585}
1586
1347void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, 1587void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1348 struct ddb_entry *ddb_entry) 1588 struct ddb_entry *ddb_entry)
1349{ 1589{
@@ -1360,7 +1600,7 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1360 if (!fw_ddb_entry) { 1600 if (!fw_ddb_entry) {
1361 ql4_printk(KERN_ERR, ha, 1601 ql4_printk(KERN_ERR, ha,
1362 "%s: Unable to allocate dma buffer\n", __func__); 1602 "%s: Unable to allocate dma buffer\n", __func__);
1363 return; 1603 goto exit_session_conn_param;
1364 } 1604 }
1365 1605
1366 if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry, 1606 if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry,
@@ -1370,7 +1610,7 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1370 "get_ddb_entry for fw_ddb_index %d\n", 1610 "get_ddb_entry for fw_ddb_index %d\n",
1371 ha->host_no, __func__, 1611 ha->host_no, __func__,
1372 ddb_entry->fw_ddb_index)); 1612 ddb_entry->fw_ddb_index));
1373 return; 1613 goto exit_session_conn_param;
1374 } 1614 }
1375 1615
1376 cls_sess = ddb_entry->sess; 1616 cls_sess = ddb_entry->sess;
@@ -1379,6 +1619,12 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1379 cls_conn = ddb_entry->conn; 1619 cls_conn = ddb_entry->conn;
1380 conn = cls_conn->dd_data; 1620 conn = cls_conn->dd_data;
1381 1621
1622 /* Update timers after login */
1623 ddb_entry->default_relogin_timeout =
1624 le16_to_cpu(fw_ddb_entry->def_timeout);
1625 ddb_entry->default_time2wait =
1626 le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);
1627
1382 /* Update params */ 1628 /* Update params */
1383 conn->max_recv_dlength = BYTE_UNITS * 1629 conn->max_recv_dlength = BYTE_UNITS *
1384 le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len); 1630 le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len);
@@ -1407,6 +1653,11 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1407 1653
1408 memcpy(sess->initiatorname, ha->name_string, 1654 memcpy(sess->initiatorname, ha->name_string,
1409 min(sizeof(ha->name_string), sizeof(sess->initiatorname))); 1655 min(sizeof(ha->name_string), sizeof(sess->initiatorname)));
1656
1657exit_session_conn_param:
1658 if (fw_ddb_entry)
1659 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1660 fw_ddb_entry, fw_ddb_entry_dma);
1410} 1661}
1411 1662
1412/* 1663/*
@@ -1607,6 +1858,9 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha)
1607 vfree(ha->chap_list); 1858 vfree(ha->chap_list);
1608 ha->chap_list = NULL; 1859 ha->chap_list = NULL;
1609 1860
1861 if (ha->fw_ddb_dma_pool)
1862 dma_pool_destroy(ha->fw_ddb_dma_pool);
1863
1610 /* release io space registers */ 1864 /* release io space registers */
1611 if (is_qla8022(ha)) { 1865 if (is_qla8022(ha)) {
1612 if (ha->nx_pcibase) 1866 if (ha->nx_pcibase)
@@ -1689,6 +1943,16 @@ static int qla4xxx_mem_alloc(struct scsi_qla_host *ha)
1689 goto mem_alloc_error_exit; 1943 goto mem_alloc_error_exit;
1690 } 1944 }
1691 1945
1946 ha->fw_ddb_dma_pool = dma_pool_create("ql4_fw_ddb", &ha->pdev->dev,
1947 DDB_DMA_BLOCK_SIZE, 8, 0);
1948
1949 if (ha->fw_ddb_dma_pool == NULL) {
1950 ql4_printk(KERN_WARNING, ha,
1951 "%s: fw_ddb_dma_pool allocation failed..\n",
1952 __func__);
1953 goto mem_alloc_error_exit;
1954 }
1955
1692 return QLA_SUCCESS; 1956 return QLA_SUCCESS;
1693 1957
1694mem_alloc_error_exit: 1958mem_alloc_error_exit:
@@ -1800,6 +2064,60 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
1800 } 2064 }
1801} 2065}
1802 2066
2067void qla4xxx_check_relogin_flash_ddb(struct iscsi_cls_session *cls_sess)
2068{
2069 struct iscsi_session *sess;
2070 struct ddb_entry *ddb_entry;
2071 struct scsi_qla_host *ha;
2072
2073 sess = cls_sess->dd_data;
2074 ddb_entry = sess->dd_data;
2075 ha = ddb_entry->ha;
2076
2077 if (!(ddb_entry->ddb_type == FLASH_DDB))
2078 return;
2079
2080 if (adapter_up(ha) && !test_bit(DF_RELOGIN, &ddb_entry->flags) &&
2081 !iscsi_is_session_online(cls_sess)) {
2082 if (atomic_read(&ddb_entry->retry_relogin_timer) !=
2083 INVALID_ENTRY) {
2084 if (atomic_read(&ddb_entry->retry_relogin_timer) ==
2085 0) {
2086 atomic_set(&ddb_entry->retry_relogin_timer,
2087 INVALID_ENTRY);
2088 set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);
2089 set_bit(DF_RELOGIN, &ddb_entry->flags);
2090 DEBUG2(ql4_printk(KERN_INFO, ha,
2091 "%s: index [%d] login device\n",
2092 __func__, ddb_entry->fw_ddb_index));
2093 } else
2094 atomic_dec(&ddb_entry->retry_relogin_timer);
2095 }
2096 }
2097
2098 /* Wait for relogin to timeout */
2099 if (atomic_read(&ddb_entry->relogin_timer) &&
2100 (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) {
2101 /*
2102 * If the relogin times out and the device is
2103 * still NOT ONLINE then try and relogin again.
2104 */
2105 if (!iscsi_is_session_online(cls_sess)) {
2106 /* Reset retry relogin timer */
2107 atomic_inc(&ddb_entry->relogin_retry_count);
2108 DEBUG2(ql4_printk(KERN_INFO, ha,
2109 "%s: index[%d] relogin timed out-retrying"
2110 " relogin (%d), retry (%d)\n", __func__,
2111 ddb_entry->fw_ddb_index,
2112 atomic_read(&ddb_entry->relogin_retry_count),
2113 ddb_entry->default_time2wait + 4));
2114 set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);
2115 atomic_set(&ddb_entry->retry_relogin_timer,
2116 ddb_entry->default_time2wait + 4);
2117 }
2118 }
2119}
2120
1803/** 2121/**
1804 * qla4xxx_timer - checks every second for work to do. 2122 * qla4xxx_timer - checks every second for work to do.
1805 * @ha: Pointer to host adapter structure. 2123 * @ha: Pointer to host adapter structure.
@@ -1809,6 +2127,8 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
1809 int start_dpc = 0; 2127 int start_dpc = 0;
1810 uint16_t w; 2128 uint16_t w;
1811 2129
2130 iscsi_host_for_each_session(ha->host, qla4xxx_check_relogin_flash_ddb);
2131
1812 /* If we are in the middle of AER/EEH processing 2132 /* If we are in the middle of AER/EEH processing
1813 * skip any processing and reschedule the timer 2133 * skip any processing and reschedule the timer
1814 */ 2134 */
@@ -2078,7 +2398,12 @@ static void qla4xxx_fail_session(struct iscsi_cls_session *cls_session)
2078 sess = cls_session->dd_data; 2398 sess = cls_session->dd_data;
2079 ddb_entry = sess->dd_data; 2399 ddb_entry = sess->dd_data;
2080 ddb_entry->fw_ddb_device_state = DDB_DS_SESSION_FAILED; 2400 ddb_entry->fw_ddb_device_state = DDB_DS_SESSION_FAILED;
2081 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); 2401
2402 if (ddb_entry->ddb_type == FLASH_DDB)
2403 iscsi_block_session(ddb_entry->sess);
2404 else
2405 iscsi_session_failure(cls_session->dd_data,
2406 ISCSI_ERR_CONN_FAILED);
2082} 2407}
2083 2408
2084/** 2409/**
@@ -2163,7 +2488,7 @@ recover_ha_init_adapter:
2163 2488
2164 /* NOTE: AF_ONLINE flag set upon successful completion of 2489 /* NOTE: AF_ONLINE flag set upon successful completion of
2165 * qla4xxx_initialize_adapter */ 2490 * qla4xxx_initialize_adapter */
2166 status = qla4xxx_initialize_adapter(ha); 2491 status = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
2167 } 2492 }
2168 2493
2169 /* Retry failed adapter initialization, if necessary 2494 /* Retry failed adapter initialization, if necessary
@@ -2245,17 +2570,108 @@ static void qla4xxx_relogin_devices(struct iscsi_cls_session *cls_session)
2245 iscsi_unblock_session(ddb_entry->sess); 2570 iscsi_unblock_session(ddb_entry->sess);
2246 } else { 2571 } else {
2247 /* Trigger relogin */ 2572 /* Trigger relogin */
2248 iscsi_session_failure(cls_session->dd_data, 2573 if (ddb_entry->ddb_type == FLASH_DDB) {
2249 ISCSI_ERR_CONN_FAILED); 2574 if (!test_bit(DF_RELOGIN, &ddb_entry->flags))
2575 qla4xxx_arm_relogin_timer(ddb_entry);
2576 } else
2577 iscsi_session_failure(cls_session->dd_data,
2578 ISCSI_ERR_CONN_FAILED);
2250 } 2579 }
2251 } 2580 }
2252} 2581}
2253 2582
2583int qla4xxx_unblock_flash_ddb(struct iscsi_cls_session *cls_session)
2584{
2585 struct iscsi_session *sess;
2586 struct ddb_entry *ddb_entry;
2587 struct scsi_qla_host *ha;
2588
2589 sess = cls_session->dd_data;
2590 ddb_entry = sess->dd_data;
2591 ha = ddb_entry->ha;
2592 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"
2593 " unblock session\n", ha->host_no, __func__,
2594 ddb_entry->fw_ddb_index);
2595
2596 iscsi_unblock_session(ddb_entry->sess);
2597
2598 /* Start scan target */
2599 if (test_bit(AF_ONLINE, &ha->flags)) {
2600 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"
2601 " start scan\n", ha->host_no, __func__,
2602 ddb_entry->fw_ddb_index);
2603 scsi_queue_work(ha->host, &ddb_entry->sess->scan_work);
2604 }
2605 return QLA_SUCCESS;
2606}
2607
2608int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session)
2609{
2610 struct iscsi_session *sess;
2611 struct ddb_entry *ddb_entry;
2612 struct scsi_qla_host *ha;
2613
2614 sess = cls_session->dd_data;
2615 ddb_entry = sess->dd_data;
2616 ha = ddb_entry->ha;
2617 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"
2618 " unblock user space session\n", ha->host_no, __func__,
2619 ddb_entry->fw_ddb_index);
2620 iscsi_conn_start(ddb_entry->conn);
2621 iscsi_conn_login_event(ddb_entry->conn,
2622 ISCSI_CONN_STATE_LOGGED_IN);
2623
2624 return QLA_SUCCESS;
2625}
2626
2254static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha) 2627static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha)
2255{ 2628{
2256 iscsi_host_for_each_session(ha->host, qla4xxx_relogin_devices); 2629 iscsi_host_for_each_session(ha->host, qla4xxx_relogin_devices);
2257} 2630}
2258 2631
2632static void qla4xxx_relogin_flash_ddb(struct iscsi_cls_session *cls_sess)
2633{
2634 uint16_t relogin_timer;
2635 struct iscsi_session *sess;
2636 struct ddb_entry *ddb_entry;
2637 struct scsi_qla_host *ha;
2638
2639 sess = cls_sess->dd_data;
2640 ddb_entry = sess->dd_data;
2641 ha = ddb_entry->ha;
2642
2643 relogin_timer = max(ddb_entry->default_relogin_timeout,
2644 (uint16_t)RELOGIN_TOV);
2645 atomic_set(&ddb_entry->relogin_timer, relogin_timer);
2646
2647 DEBUG2(ql4_printk(KERN_INFO, ha,
2648 "scsi%ld: Relogin index [%d]. TOV=%d\n", ha->host_no,
2649 ddb_entry->fw_ddb_index, relogin_timer));
2650
2651 qla4xxx_login_flash_ddb(cls_sess);
2652}
2653
2654static void qla4xxx_dpc_relogin(struct iscsi_cls_session *cls_sess)
2655{
2656 struct iscsi_session *sess;
2657 struct ddb_entry *ddb_entry;
2658 struct scsi_qla_host *ha;
2659
2660 sess = cls_sess->dd_data;
2661 ddb_entry = sess->dd_data;
2662 ha = ddb_entry->ha;
2663
2664 if (!(ddb_entry->ddb_type == FLASH_DDB))
2665 return;
2666
2667 if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags) &&
2668 !iscsi_is_session_online(cls_sess)) {
2669 DEBUG2(ql4_printk(KERN_INFO, ha,
2670 "relogin issued\n"));
2671 qla4xxx_relogin_flash_ddb(cls_sess);
2672 }
2673}
2674
2259void qla4xxx_wake_dpc(struct scsi_qla_host *ha) 2675void qla4xxx_wake_dpc(struct scsi_qla_host *ha)
2260{ 2676{
2261 if (ha->dpc_thread) 2677 if (ha->dpc_thread)
@@ -2356,6 +2772,12 @@ dpc_post_reset_ha:
2356 if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags)) 2772 if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags))
2357 qla4xxx_get_dhcp_ip_address(ha); 2773 qla4xxx_get_dhcp_ip_address(ha);
2358 2774
2775 /* ---- relogin device? --- */
2776 if (adapter_up(ha) &&
2777 test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) {
2778 iscsi_host_for_each_session(ha->host, qla4xxx_dpc_relogin);
2779 }
2780
2359 /* ---- link change? --- */ 2781 /* ---- link change? --- */
2360 if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) { 2782 if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) {
2361 if (!test_bit(AF_LINK_UP, &ha->flags)) { 2783 if (!test_bit(AF_LINK_UP, &ha->flags)) {
@@ -2368,8 +2790,12 @@ dpc_post_reset_ha:
2368 * fatal error recovery. Therefore, the driver must 2790 * fatal error recovery. Therefore, the driver must
2369 * manually relogin to devices when recovering from 2791 * manually relogin to devices when recovering from
2370 * connection failures, logouts, expired KATO, etc. */ 2792 * connection failures, logouts, expired KATO, etc. */
2371 2793 if (test_and_clear_bit(AF_BUILD_DDB_LIST, &ha->flags)) {
2372 qla4xxx_relogin_all_devices(ha); 2794 qla4xxx_build_ddb_list(ha, ha->is_reset);
2795 iscsi_host_for_each_session(ha->host,
2796 qla4xxx_login_flash_ddb);
2797 } else
2798 qla4xxx_relogin_all_devices(ha);
2373 } 2799 }
2374 } 2800 }
2375} 2801}
@@ -2867,6 +3293,9 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[])
2867 " target ID %d\n", __func__, ddb_index[0], 3293 " target ID %d\n", __func__, ddb_index[0],
2868 ddb_index[1])); 3294 ddb_index[1]));
2869 3295
3296 ha->pri_ddb_idx = ddb_index[0];
3297 ha->sec_ddb_idx = ddb_index[1];
3298
2870exit_boot_info_free: 3299exit_boot_info_free:
2871 dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma); 3300 dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma);
2872exit_boot_info: 3301exit_boot_info:
@@ -3034,6 +3463,9 @@ static int qla4xxx_get_boot_info(struct scsi_qla_host *ha)
3034 return ret; 3463 return ret;
3035 } 3464 }
3036 3465
3466 if (ql4xdisablesysfsboot)
3467 return QLA_SUCCESS;
3468
3037 if (ddb_index[0] == 0xffff) 3469 if (ddb_index[0] == 0xffff)
3038 goto sec_target; 3470 goto sec_target;
3039 3471
@@ -3066,7 +3498,15 @@ static int qla4xxx_setup_boot_info(struct scsi_qla_host *ha)
3066 struct iscsi_boot_kobj *boot_kobj; 3498 struct iscsi_boot_kobj *boot_kobj;
3067 3499
3068 if (qla4xxx_get_boot_info(ha) != QLA_SUCCESS) 3500 if (qla4xxx_get_boot_info(ha) != QLA_SUCCESS)
3069 return 0; 3501 return QLA_ERROR;
3502
3503 if (ql4xdisablesysfsboot) {
3504 ql4_printk(KERN_INFO, ha,
3505 "%s: syfsboot disabled - driver will trigger login"
3506 "and publish session for discovery .\n", __func__);
3507 return QLA_SUCCESS;
3508 }
3509
3070 3510
3071 ha->boot_kset = iscsi_boot_create_host_kset(ha->host->host_no); 3511 ha->boot_kset = iscsi_boot_create_host_kset(ha->host->host_no);
3072 if (!ha->boot_kset) 3512 if (!ha->boot_kset)
@@ -3108,7 +3548,7 @@ static int qla4xxx_setup_boot_info(struct scsi_qla_host *ha)
3108 if (!boot_kobj) 3548 if (!boot_kobj)
3109 goto put_host; 3549 goto put_host;
3110 3550
3111 return 0; 3551 return QLA_SUCCESS;
3112 3552
3113put_host: 3553put_host:
3114 scsi_host_put(ha->host); 3554 scsi_host_put(ha->host);
@@ -3174,9 +3614,507 @@ static void qla4xxx_create_chap_list(struct scsi_qla_host *ha)
3174exit_chap_list: 3614exit_chap_list:
3175 dma_free_coherent(&ha->pdev->dev, chap_size, 3615 dma_free_coherent(&ha->pdev->dev, chap_size,
3176 chap_flash_data, chap_dma); 3616 chap_flash_data, chap_dma);
3177 return;
3178} 3617}
3179 3618
3619static void qla4xxx_get_param_ddb(struct ddb_entry *ddb_entry,
3620 struct ql4_tuple_ddb *tddb)
3621{
3622 struct scsi_qla_host *ha;
3623 struct iscsi_cls_session *cls_sess;
3624 struct iscsi_cls_conn *cls_conn;
3625 struct iscsi_session *sess;
3626 struct iscsi_conn *conn;
3627
3628 DEBUG2(printk(KERN_INFO "Func: %s\n", __func__));
3629 ha = ddb_entry->ha;
3630 cls_sess = ddb_entry->sess;
3631 sess = cls_sess->dd_data;
3632 cls_conn = ddb_entry->conn;
3633 conn = cls_conn->dd_data;
3634
3635 tddb->tpgt = sess->tpgt;
3636 tddb->port = conn->persistent_port;
3637 strncpy(tddb->iscsi_name, sess->targetname, ISCSI_NAME_SIZE);
3638 strncpy(tddb->ip_addr, conn->persistent_address, DDB_IPADDR_LEN);
3639}
3640
3641static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry,
3642 struct ql4_tuple_ddb *tddb)
3643{
3644 uint16_t options = 0;
3645
3646 tddb->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
3647 memcpy(&tddb->iscsi_name[0], &fw_ddb_entry->iscsi_name[0],
3648 min(sizeof(tddb->iscsi_name), sizeof(fw_ddb_entry->iscsi_name)));
3649
3650 options = le16_to_cpu(fw_ddb_entry->options);
3651 if (options & DDB_OPT_IPV6_DEVICE)
3652 sprintf(tddb->ip_addr, "%pI6", fw_ddb_entry->ip_addr);
3653 else
3654 sprintf(tddb->ip_addr, "%pI4", fw_ddb_entry->ip_addr);
3655
3656 tddb->port = le16_to_cpu(fw_ddb_entry->port);
3657}
3658
3659static int qla4xxx_compare_tuple_ddb(struct scsi_qla_host *ha,
3660 struct ql4_tuple_ddb *old_tddb,
3661 struct ql4_tuple_ddb *new_tddb)
3662{
3663 if (strcmp(old_tddb->iscsi_name, new_tddb->iscsi_name))
3664 return QLA_ERROR;
3665
3666 if (strcmp(old_tddb->ip_addr, new_tddb->ip_addr))
3667 return QLA_ERROR;
3668
3669 if (old_tddb->port != new_tddb->port)
3670 return QLA_ERROR;
3671
3672 DEBUG2(ql4_printk(KERN_INFO, ha,
3673 "Match Found, fw[%d,%d,%s,%s], [%d,%d,%s,%s]",
3674 old_tddb->port, old_tddb->tpgt, old_tddb->ip_addr,
3675 old_tddb->iscsi_name, new_tddb->port, new_tddb->tpgt,
3676 new_tddb->ip_addr, new_tddb->iscsi_name));
3677
3678 return QLA_SUCCESS;
3679}
3680
3681static int qla4xxx_is_session_exists(struct scsi_qla_host *ha,
3682 struct dev_db_entry *fw_ddb_entry)
3683{
3684 struct ddb_entry *ddb_entry;
3685 struct ql4_tuple_ddb *fw_tddb = NULL;
3686 struct ql4_tuple_ddb *tmp_tddb = NULL;
3687 int idx;
3688 int ret = QLA_ERROR;
3689
3690 fw_tddb = vzalloc(sizeof(*fw_tddb));
3691 if (!fw_tddb) {
3692 DEBUG2(ql4_printk(KERN_WARNING, ha,
3693 "Memory Allocation failed.\n"));
3694 ret = QLA_SUCCESS;
3695 goto exit_check;
3696 }
3697
3698 tmp_tddb = vzalloc(sizeof(*tmp_tddb));
3699 if (!tmp_tddb) {
3700 DEBUG2(ql4_printk(KERN_WARNING, ha,
3701 "Memory Allocation failed.\n"));
3702 ret = QLA_SUCCESS;
3703 goto exit_check;
3704 }
3705
3706 qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb);
3707
3708 for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) {
3709 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);
3710 if (ddb_entry == NULL)
3711 continue;
3712
3713 qla4xxx_get_param_ddb(ddb_entry, tmp_tddb);
3714 if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) {
3715 ret = QLA_SUCCESS; /* found */
3716 goto exit_check;
3717 }
3718 }
3719
3720exit_check:
3721 if (fw_tddb)
3722 vfree(fw_tddb);
3723 if (tmp_tddb)
3724 vfree(tmp_tddb);
3725 return ret;
3726}
3727
3728static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha,
3729 struct list_head *list_nt,
3730 struct dev_db_entry *fw_ddb_entry)
3731{
3732 struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp;
3733 struct ql4_tuple_ddb *fw_tddb = NULL;
3734 struct ql4_tuple_ddb *tmp_tddb = NULL;
3735 int ret = QLA_ERROR;
3736
3737 fw_tddb = vzalloc(sizeof(*fw_tddb));
3738 if (!fw_tddb) {
3739 DEBUG2(ql4_printk(KERN_WARNING, ha,
3740 "Memory Allocation failed.\n"));
3741 ret = QLA_SUCCESS;
3742 goto exit_check;
3743 }
3744
3745 tmp_tddb = vzalloc(sizeof(*tmp_tddb));
3746 if (!tmp_tddb) {
3747 DEBUG2(ql4_printk(KERN_WARNING, ha,
3748 "Memory Allocation failed.\n"));
3749 ret = QLA_SUCCESS;
3750 goto exit_check;
3751 }
3752
3753 qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb);
3754
3755 list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) {
3756 qla4xxx_convert_param_ddb(&nt_ddb_idx->fw_ddb, tmp_tddb);
3757 if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) {
3758 ret = QLA_SUCCESS; /* found */
3759 goto exit_check;
3760 }
3761 }
3762
3763exit_check:
3764 if (fw_tddb)
3765 vfree(fw_tddb);
3766 if (tmp_tddb)
3767 vfree(tmp_tddb);
3768 return ret;
3769}
3770
3771static void qla4xxx_free_nt_list(struct list_head *list_nt)
3772{
3773 struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp;
3774
3775 /* Free up the normaltargets list */
3776 list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) {
3777 list_del_init(&nt_ddb_idx->list);
3778 vfree(nt_ddb_idx);
3779 }
3780
3781}
3782
3783static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha,
3784 struct dev_db_entry *fw_ddb_entry)
3785{
3786 struct iscsi_endpoint *ep;
3787 struct sockaddr_in *addr;
3788 struct sockaddr_in6 *addr6;
3789 struct sockaddr *dst_addr;
3790 char *ip;
3791
3792 /* TODO: need to destroy on unload iscsi_endpoint*/
3793 dst_addr = vmalloc(sizeof(*dst_addr));
3794 if (!dst_addr)
3795 return NULL;
3796
3797 if (fw_ddb_entry->options & DDB_OPT_IPV6_DEVICE) {
3798 dst_addr->sa_family = AF_INET6;
3799 addr6 = (struct sockaddr_in6 *)dst_addr;
3800 ip = (char *)&addr6->sin6_addr;
3801 memcpy(ip, fw_ddb_entry->ip_addr, IPv6_ADDR_LEN);
3802 addr6->sin6_port = htons(le16_to_cpu(fw_ddb_entry->port));
3803
3804 } else {
3805 dst_addr->sa_family = AF_INET;
3806 addr = (struct sockaddr_in *)dst_addr;
3807 ip = (char *)&addr->sin_addr;
3808 memcpy(ip, fw_ddb_entry->ip_addr, IP_ADDR_LEN);
3809 addr->sin_port = htons(le16_to_cpu(fw_ddb_entry->port));
3810 }
3811
3812 ep = qla4xxx_ep_connect(ha->host, dst_addr, 0);
3813 vfree(dst_addr);
3814 return ep;
3815}
3816
3817static int qla4xxx_verify_boot_idx(struct scsi_qla_host *ha, uint16_t idx)
3818{
3819 if (ql4xdisablesysfsboot)
3820 return QLA_SUCCESS;
3821 if (idx == ha->pri_ddb_idx || idx == ha->sec_ddb_idx)
3822 return QLA_ERROR;
3823 return QLA_SUCCESS;
3824}
3825
3826static void qla4xxx_setup_flash_ddb_entry(struct scsi_qla_host *ha,
3827 struct ddb_entry *ddb_entry)
3828{
3829 ddb_entry->ddb_type = FLASH_DDB;
3830 ddb_entry->fw_ddb_index = INVALID_ENTRY;
3831 ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE;
3832 ddb_entry->ha = ha;
3833 ddb_entry->unblock_sess = qla4xxx_unblock_flash_ddb;
3834 ddb_entry->ddb_change = qla4xxx_flash_ddb_change;
3835
3836 atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY);
3837 atomic_set(&ddb_entry->relogin_timer, 0);
3838 atomic_set(&ddb_entry->relogin_retry_count, 0);
3839
3840 ddb_entry->default_relogin_timeout =
3841 le16_to_cpu(ddb_entry->fw_ddb_entry.def_timeout);
3842 ddb_entry->default_time2wait =
3843 le16_to_cpu(ddb_entry->fw_ddb_entry.iscsi_def_time2wait);
3844}
3845
3846static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha)
3847{
3848 uint32_t idx = 0;
3849 uint32_t ip_idx[IP_ADDR_COUNT] = {0, 1, 2, 3}; /* 4 IP interfaces */
3850 uint32_t sts[MBOX_REG_COUNT];
3851 uint32_t ip_state;
3852 unsigned long wtime;
3853 int ret;
3854
3855 wtime = jiffies + (HZ * IP_CONFIG_TOV);
3856 do {
3857 for (idx = 0; idx < IP_ADDR_COUNT; idx++) {
3858 if (ip_idx[idx] == -1)
3859 continue;
3860
3861 ret = qla4xxx_get_ip_state(ha, 0, ip_idx[idx], sts);
3862
3863 if (ret == QLA_ERROR) {
3864 ip_idx[idx] = -1;
3865 continue;
3866 }
3867
3868 ip_state = (sts[1] & IP_STATE_MASK) >> IP_STATE_SHIFT;
3869
3870 DEBUG2(ql4_printk(KERN_INFO, ha,
3871 "Waiting for IP state for idx = %d, state = 0x%x\n",
3872 ip_idx[idx], ip_state));
3873 if (ip_state == IP_ADDRSTATE_UNCONFIGURED ||
3874 ip_state == IP_ADDRSTATE_INVALID ||
3875 ip_state == IP_ADDRSTATE_PREFERRED ||
3876 ip_state == IP_ADDRSTATE_DEPRICATED ||
3877 ip_state == IP_ADDRSTATE_DISABLING)
3878 ip_idx[idx] = -1;
3879
3880 }
3881
3882 /* Break if all IP states checked */
3883 if ((ip_idx[0] == -1) &&
3884 (ip_idx[1] == -1) &&
3885 (ip_idx[2] == -1) &&
3886 (ip_idx[3] == -1))
3887 break;
3888 schedule_timeout_uninterruptible(HZ);
3889 } while (time_after(wtime, jiffies));
3890}
3891
3892void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset)
3893{
3894 int max_ddbs;
3895 int ret;
3896 uint32_t idx = 0, next_idx = 0;
3897 uint32_t state = 0, conn_err = 0;
3898 uint16_t conn_id;
3899 struct dev_db_entry *fw_ddb_entry;
3900 struct ddb_entry *ddb_entry = NULL;
3901 dma_addr_t fw_ddb_dma;
3902 struct iscsi_cls_session *cls_sess;
3903 struct iscsi_session *sess;
3904 struct iscsi_cls_conn *cls_conn;
3905 struct iscsi_endpoint *ep;
3906 uint16_t cmds_max = 32, tmo = 0;
3907 uint32_t initial_cmdsn = 0;
3908 struct list_head list_st, list_nt; /* List of sendtargets */
3909 struct qla_ddb_index *st_ddb_idx, *st_ddb_idx_tmp;
3910 int fw_idx_size;
3911 unsigned long wtime;
3912 struct qla_ddb_index *nt_ddb_idx;
3913
3914 if (!test_bit(AF_LINK_UP, &ha->flags)) {
3915 set_bit(AF_BUILD_DDB_LIST, &ha->flags);
3916 ha->is_reset = is_reset;
3917 return;
3918 }
3919 max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
3920 MAX_DEV_DB_ENTRIES;
3921
3922 fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,
3923 &fw_ddb_dma);
3924 if (fw_ddb_entry == NULL) {
3925 DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n"));
3926 goto exit_ddb_list;
3927 }
3928
3929 INIT_LIST_HEAD(&list_st);
3930 INIT_LIST_HEAD(&list_nt);
3931 fw_idx_size = sizeof(struct qla_ddb_index);
3932
3933 for (idx = 0; idx < max_ddbs; idx = next_idx) {
3934 ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry,
3935 fw_ddb_dma, NULL,
3936 &next_idx, &state, &conn_err,
3937 NULL, &conn_id);
3938 if (ret == QLA_ERROR)
3939 break;
3940
3941 if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS)
3942 goto continue_next_st;
3943
3944 /* Check if ST, add to the list_st */
3945 if (strlen((char *) fw_ddb_entry->iscsi_name) != 0)
3946 goto continue_next_st;
3947
3948 st_ddb_idx = vzalloc(fw_idx_size);
3949 if (!st_ddb_idx)
3950 break;
3951
3952 st_ddb_idx->fw_ddb_idx = idx;
3953
3954 list_add_tail(&st_ddb_idx->list, &list_st);
3955continue_next_st:
3956 if (next_idx == 0)
3957 break;
3958 }
3959
3960 /* Before issuing conn open mbox, ensure all IPs states are configured
3961 * Note, conn open fails if IPs are not configured
3962 */
3963 qla4xxx_wait_for_ip_configuration(ha);
3964
3965 /* Go thru the STs and fire the sendtargets by issuing conn open mbx */
3966 list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) {
3967 qla4xxx_conn_open(ha, st_ddb_idx->fw_ddb_idx);
3968 }
3969
3970 /* Wait to ensure all sendtargets are done for min 12 sec wait */
3971 tmo = ((ha->def_timeout < LOGIN_TOV) ? LOGIN_TOV : ha->def_timeout);
3972 DEBUG2(ql4_printk(KERN_INFO, ha,
3973 "Default time to wait for build ddb %d\n", tmo));
3974
3975 wtime = jiffies + (HZ * tmo);
3976 do {
3977 list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st,
3978 list) {
3979 ret = qla4xxx_get_fwddb_entry(ha,
3980 st_ddb_idx->fw_ddb_idx,
3981 NULL, 0, NULL, &next_idx,
3982 &state, &conn_err, NULL,
3983 NULL);
3984 if (ret == QLA_ERROR)
3985 continue;
3986
3987 if (state == DDB_DS_NO_CONNECTION_ACTIVE ||
3988 state == DDB_DS_SESSION_FAILED) {
3989 list_del_init(&st_ddb_idx->list);
3990 vfree(st_ddb_idx);
3991 }
3992 }
3993 schedule_timeout_uninterruptible(HZ / 10);
3994 } while (time_after(wtime, jiffies));
3995
3996 /* Free up the sendtargets list */
3997 list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) {
3998 list_del_init(&st_ddb_idx->list);
3999 vfree(st_ddb_idx);
4000 }
4001
4002 for (idx = 0; idx < max_ddbs; idx = next_idx) {
4003 ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry,
4004 fw_ddb_dma, NULL,
4005 &next_idx, &state, &conn_err,
4006 NULL, &conn_id);
4007 if (ret == QLA_ERROR)
4008 break;
4009
4010 if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS)
4011 goto continue_next_nt;
4012
4013 /* Check if NT, then add to list it */
4014 if (strlen((char *) fw_ddb_entry->iscsi_name) == 0)
4015 goto continue_next_nt;
4016
4017 if (state == DDB_DS_NO_CONNECTION_ACTIVE ||
4018 state == DDB_DS_SESSION_FAILED) {
4019 DEBUG2(ql4_printk(KERN_INFO, ha,
4020 "Adding DDB to session = 0x%x\n",
4021 idx));
4022 if (is_reset == INIT_ADAPTER) {
4023 nt_ddb_idx = vmalloc(fw_idx_size);
4024 if (!nt_ddb_idx)
4025 break;
4026
4027 nt_ddb_idx->fw_ddb_idx = idx;
4028
4029 memcpy(&nt_ddb_idx->fw_ddb, fw_ddb_entry,
4030 sizeof(struct dev_db_entry));
4031
4032 if (qla4xxx_is_flash_ddb_exists(ha, &list_nt,
4033 fw_ddb_entry) == QLA_SUCCESS) {
4034 vfree(nt_ddb_idx);
4035 goto continue_next_nt;
4036 }
4037 list_add_tail(&nt_ddb_idx->list, &list_nt);
4038 } else if (is_reset == RESET_ADAPTER) {
4039 if (qla4xxx_is_session_exists(ha,
4040 fw_ddb_entry) == QLA_SUCCESS)
4041 goto continue_next_nt;
4042 }
4043
4044 /* Create session object, with INVALID_ENTRY,
4045 * the targer_id would get set when we issue the login
4046 */
4047 cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport,
4048 ha->host, cmds_max,
4049 sizeof(struct ddb_entry),
4050 sizeof(struct ql4_task_data),
4051 initial_cmdsn, INVALID_ENTRY);
4052 if (!cls_sess)
4053 goto exit_ddb_list;
4054
4055 /*
4056 * iscsi_session_setup increments the driver reference
4057 * count which wouldn't let the driver to be unloaded.
4058 * so calling module_put function to decrement the
4059 * reference count.
4060 **/
4061 module_put(qla4xxx_iscsi_transport.owner);
4062 sess = cls_sess->dd_data;
4063 ddb_entry = sess->dd_data;
4064 ddb_entry->sess = cls_sess;
4065
4066 cls_sess->recovery_tmo = ql4xsess_recovery_tmo;
4067 memcpy(&ddb_entry->fw_ddb_entry, fw_ddb_entry,
4068 sizeof(struct dev_db_entry));
4069
4070 qla4xxx_setup_flash_ddb_entry(ha, ddb_entry);
4071
4072 cls_conn = iscsi_conn_setup(cls_sess,
4073 sizeof(struct qla_conn),
4074 conn_id);
4075 if (!cls_conn)
4076 goto exit_ddb_list;
4077
4078 ddb_entry->conn = cls_conn;
4079
4080 /* Setup ep, for displaying attributes in sysfs */
4081 ep = qla4xxx_get_ep_fwdb(ha, fw_ddb_entry);
4082 if (ep) {
4083 ep->conn = cls_conn;
4084 cls_conn->ep = ep;
4085 } else {
4086 DEBUG2(ql4_printk(KERN_ERR, ha,
4087 "Unable to get ep\n"));
4088 }
4089
4090 /* Update sess/conn params */
4091 qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess,
4092 cls_conn);
4093
4094 if (is_reset == RESET_ADAPTER) {
4095 iscsi_block_session(cls_sess);
4096 /* Use the relogin path to discover new devices
4097 * by short-circuting the logic of setting
4098 * timer to relogin - instead set the flags
4099 * to initiate login right away.
4100 */
4101 set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);
4102 set_bit(DF_RELOGIN, &ddb_entry->flags);
4103 }
4104 }
4105continue_next_nt:
4106 if (next_idx == 0)
4107 break;
4108 }
4109exit_ddb_list:
4110 qla4xxx_free_nt_list(&list_nt);
4111 if (fw_ddb_entry)
4112 dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);
4113
4114 qla4xxx_free_ddb_index(ha);
4115}
4116
4117
3180/** 4118/**
3181 * qla4xxx_probe_adapter - callback function to probe HBA 4119 * qla4xxx_probe_adapter - callback function to probe HBA
3182 * @pdev: pointer to pci_dev structure 4120 * @pdev: pointer to pci_dev structure
@@ -3298,7 +4236,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
3298 * firmware 4236 * firmware
3299 * NOTE: interrupts enabled upon successful completion 4237 * NOTE: interrupts enabled upon successful completion
3300 */ 4238 */
3301 status = qla4xxx_initialize_adapter(ha); 4239 status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);
3302 while ((!test_bit(AF_ONLINE, &ha->flags)) && 4240 while ((!test_bit(AF_ONLINE, &ha->flags)) &&
3303 init_retry_count++ < MAX_INIT_RETRIES) { 4241 init_retry_count++ < MAX_INIT_RETRIES) {
3304 4242
@@ -3319,7 +4257,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
3319 if (ha->isp_ops->reset_chip(ha) == QLA_ERROR) 4257 if (ha->isp_ops->reset_chip(ha) == QLA_ERROR)
3320 continue; 4258 continue;
3321 4259
3322 status = qla4xxx_initialize_adapter(ha); 4260 status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);
3323 } 4261 }
3324 4262
3325 if (!test_bit(AF_ONLINE, &ha->flags)) { 4263 if (!test_bit(AF_ONLINE, &ha->flags)) {
@@ -3386,12 +4324,16 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
3386 ha->host_no, ha->firmware_version[0], ha->firmware_version[1], 4324 ha->host_no, ha->firmware_version[0], ha->firmware_version[1],
3387 ha->patch_number, ha->build_number); 4325 ha->patch_number, ha->build_number);
3388 4326
3389 qla4xxx_create_chap_list(ha);
3390
3391 if (qla4xxx_setup_boot_info(ha)) 4327 if (qla4xxx_setup_boot_info(ha))
3392 ql4_printk(KERN_ERR, ha, "%s:ISCSI boot info setup failed\n", 4328 ql4_printk(KERN_ERR, ha, "%s:ISCSI boot info setup failed\n",
3393 __func__); 4329 __func__);
3394 4330
4331 /* Perform the build ddb list and login to each */
4332 qla4xxx_build_ddb_list(ha, INIT_ADAPTER);
4333 iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb);
4334
4335 qla4xxx_create_chap_list(ha);
4336
3395 qla4xxx_create_ifaces(ha); 4337 qla4xxx_create_ifaces(ha);
3396 return 0; 4338 return 0;
3397 4339
@@ -3449,6 +4391,38 @@ static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha)
3449 } 4391 }
3450} 4392}
3451 4393
4394static void qla4xxx_destroy_fw_ddb_session(struct scsi_qla_host *ha)
4395{
4396 struct ddb_entry *ddb_entry;
4397 int options;
4398 int idx;
4399
4400 for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) {
4401
4402 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);
4403 if ((ddb_entry != NULL) &&
4404 (ddb_entry->ddb_type == FLASH_DDB)) {
4405
4406 options = LOGOUT_OPTION_CLOSE_SESSION;
4407 if (qla4xxx_session_logout_ddb(ha, ddb_entry, options)
4408 == QLA_ERROR)
4409 ql4_printk(KERN_ERR, ha, "%s: Logout failed\n",
4410 __func__);
4411
4412 qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);
4413 /*
4414 * we have decremented the reference count of the driver
4415 * when we setup the session to have the driver unload
4416 * to be seamless without actually destroying the
4417 * session
4418 **/
4419 try_module_get(qla4xxx_iscsi_transport.owner);
4420 iscsi_destroy_endpoint(ddb_entry->conn->ep);
4421 qla4xxx_free_ddb(ha, ddb_entry);
4422 iscsi_session_teardown(ddb_entry->sess);
4423 }
4424 }
4425}
3452/** 4426/**
3453 * qla4xxx_remove_adapter - calback function to remove adapter. 4427 * qla4xxx_remove_adapter - calback function to remove adapter.
3454 * @pci_dev: PCI device pointer 4428 * @pci_dev: PCI device pointer
@@ -3465,9 +4439,11 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
3465 /* destroy iface from sysfs */ 4439 /* destroy iface from sysfs */
3466 qla4xxx_destroy_ifaces(ha); 4440 qla4xxx_destroy_ifaces(ha);
3467 4441
3468 if (ha->boot_kset) 4442 if ((!ql4xdisablesysfsboot) && ha->boot_kset)
3469 iscsi_boot_destroy_kset(ha->boot_kset); 4443 iscsi_boot_destroy_kset(ha->boot_kset);
3470 4444
4445 qla4xxx_destroy_fw_ddb_session(ha);
4446
3471 scsi_remove_host(ha->host); 4447 scsi_remove_host(ha->host);
3472 4448
3473 qla4xxx_free_adapter(ha); 4449 qla4xxx_free_adapter(ha);
@@ -4115,7 +5091,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
4115 5091
4116 qla4_8xxx_idc_unlock(ha); 5092 qla4_8xxx_idc_unlock(ha);
4117 clear_bit(AF_FW_RECOVERY, &ha->flags); 5093 clear_bit(AF_FW_RECOVERY, &ha->flags);
4118 rval = qla4xxx_initialize_adapter(ha); 5094 rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
4119 qla4_8xxx_idc_lock(ha); 5095 qla4_8xxx_idc_lock(ha);
4120 5096
4121 if (rval != QLA_SUCCESS) { 5097 if (rval != QLA_SUCCESS) {
@@ -4151,7 +5127,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
4151 if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == 5127 if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
4152 QLA82XX_DEV_READY)) { 5128 QLA82XX_DEV_READY)) {
4153 clear_bit(AF_FW_RECOVERY, &ha->flags); 5129 clear_bit(AF_FW_RECOVERY, &ha->flags);
4154 rval = qla4xxx_initialize_adapter(ha); 5130 rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
4155 if (rval == QLA_SUCCESS) { 5131 if (rval == QLA_SUCCESS) {
4156 ret = qla4xxx_request_irqs(ha); 5132 ret = qla4xxx_request_irqs(ha);
4157 if (ret) { 5133 if (ret) {