Commit 173269ef authored by Manish Rangankar's avatar Manish Rangankar Committed by James Bottomley

[SCSI] qla4xxx: Add support for multiple session per host.

This patch will allow iscsiadm to create multiple session
for the same target on per host.
Signed-off-by: default avatarManish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent fca9f04d
...@@ -291,6 +291,7 @@ struct ql4_tuple_ddb { ...@@ -291,6 +291,7 @@ struct ql4_tuple_ddb {
uint16_t options; uint16_t options;
#define DDB_OPT_IPV6 0x0e0e #define DDB_OPT_IPV6 0x0e0e
#define DDB_OPT_IPV4 0x0f0f #define DDB_OPT_IPV4 0x0f0f
uint8_t isid[6];
}; };
/* /*
......
...@@ -1607,7 +1607,7 @@ int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha, ...@@ -1607,7 +1607,7 @@ int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,
char *ip; char *ip;
uint16_t iscsi_opts = 0; uint16_t iscsi_opts = 0;
uint32_t options = 0; uint32_t options = 0;
uint16_t idx; uint16_t idx, *ptid;
fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
&fw_ddb_entry_dma, GFP_KERNEL); &fw_ddb_entry_dma, GFP_KERNEL);
...@@ -1633,6 +1633,14 @@ int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha, ...@@ -1633,6 +1633,14 @@ int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,
goto exit_set_param; goto exit_set_param;
} }
ptid = (uint16_t *)&fw_ddb_entry->isid[1];
*ptid = cpu_to_le16((uint16_t)ddb_entry->sess->target_id);
DEBUG2(ql4_printk(KERN_INFO, ha, "ISID [%02x%02x%02x%02x%02x%02x]\n",
fw_ddb_entry->isid[5], fw_ddb_entry->isid[4],
fw_ddb_entry->isid[3], fw_ddb_entry->isid[2],
fw_ddb_entry->isid[1], fw_ddb_entry->isid[0]));
iscsi_opts = le16_to_cpu(fw_ddb_entry->iscsi_options); iscsi_opts = le16_to_cpu(fw_ddb_entry->iscsi_options);
memset(fw_ddb_entry->iscsi_alias, 0, sizeof(fw_ddb_entry->iscsi_alias)); memset(fw_ddb_entry->iscsi_alias, 0, sizeof(fw_ddb_entry->iscsi_alias));
......
...@@ -4252,11 +4252,13 @@ static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry, ...@@ -4252,11 +4252,13 @@ static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry,
sprintf(tddb->ip_addr, "%pI4", fw_ddb_entry->ip_addr); sprintf(tddb->ip_addr, "%pI4", fw_ddb_entry->ip_addr);
tddb->port = le16_to_cpu(fw_ddb_entry->port); tddb->port = le16_to_cpu(fw_ddb_entry->port);
memcpy(&tddb->isid[0], &fw_ddb_entry->isid[0], sizeof(tddb->isid));
} }
static int qla4xxx_compare_tuple_ddb(struct scsi_qla_host *ha, static int qla4xxx_compare_tuple_ddb(struct scsi_qla_host *ha,
struct ql4_tuple_ddb *old_tddb, struct ql4_tuple_ddb *old_tddb,
struct ql4_tuple_ddb *new_tddb) struct ql4_tuple_ddb *new_tddb,
uint8_t is_isid_compare)
{ {
if (strcmp(old_tddb->iscsi_name, new_tddb->iscsi_name)) if (strcmp(old_tddb->iscsi_name, new_tddb->iscsi_name))
return QLA_ERROR; return QLA_ERROR;
...@@ -4267,6 +4269,26 @@ static int qla4xxx_compare_tuple_ddb(struct scsi_qla_host *ha, ...@@ -4267,6 +4269,26 @@ static int qla4xxx_compare_tuple_ddb(struct scsi_qla_host *ha,
if (old_tddb->port != new_tddb->port) if (old_tddb->port != new_tddb->port)
return QLA_ERROR; return QLA_ERROR;
/* For multi sessions, driver generates the ISID, so do not compare
* ISID in reset path since it would be a comparision between the
* driver generated ISID and firmware generated ISID. This could
* lead to adding duplicated DDBs in the list as driver generated
* ISID would not match firmware generated ISID.
*/
if (is_isid_compare) {
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: old ISID [%02x%02x%02x"
"%02x%02x%02x] New ISID [%02x%02x%02x%02x%02x%02x]\n",
__func__, old_tddb->isid[5], old_tddb->isid[4],
old_tddb->isid[3], old_tddb->isid[2], old_tddb->isid[1],
old_tddb->isid[0], new_tddb->isid[5], new_tddb->isid[4],
new_tddb->isid[3], new_tddb->isid[2], new_tddb->isid[1],
new_tddb->isid[0]));
if (memcmp(&old_tddb->isid[0], &new_tddb->isid[0],
sizeof(old_tddb->isid)))
return QLA_ERROR;
}
DEBUG2(ql4_printk(KERN_INFO, ha, DEBUG2(ql4_printk(KERN_INFO, ha,
"Match Found, fw[%d,%d,%s,%s], [%d,%d,%s,%s]", "Match Found, fw[%d,%d,%s,%s], [%d,%d,%s,%s]",
old_tddb->port, old_tddb->tpgt, old_tddb->ip_addr, old_tddb->port, old_tddb->tpgt, old_tddb->ip_addr,
...@@ -4309,7 +4331,7 @@ static int qla4xxx_is_session_exists(struct scsi_qla_host *ha, ...@@ -4309,7 +4331,7 @@ static int qla4xxx_is_session_exists(struct scsi_qla_host *ha,
continue; continue;
qla4xxx_get_param_ddb(ddb_entry, tmp_tddb); qla4xxx_get_param_ddb(ddb_entry, tmp_tddb);
if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) { if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb, false)) {
ret = QLA_SUCCESS; /* found */ ret = QLA_SUCCESS; /* found */
goto exit_check; goto exit_check;
} }
...@@ -4352,7 +4374,7 @@ static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha, ...@@ -4352,7 +4374,7 @@ static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha,
list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) { list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) {
qla4xxx_convert_param_ddb(&nt_ddb_idx->fw_ddb, tmp_tddb); qla4xxx_convert_param_ddb(&nt_ddb_idx->fw_ddb, tmp_tddb);
if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) { if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb, true)) {
ret = QLA_SUCCESS; /* found */ ret = QLA_SUCCESS; /* found */
goto exit_check; goto exit_check;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment