Commit 4a4bc2e9 authored by Lalit Chandivade's avatar Lalit Chandivade Committed by James Bottomley

[SCSI] qla4xxx: cleanup, make qla4xxx_build_ddb_list short

Make qla4xxx_build_ddb_list shorter by adding more helper functions.
Signed-off-by: default avatarLalit Chandivade <lalit.chandivade@qlogic.com>
Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 00c4a09b
...@@ -2078,7 +2078,7 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha) ...@@ -2078,7 +2078,7 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
} }
} }
void qla4xxx_check_relogin_flash_ddb(struct iscsi_cls_session *cls_sess) static void qla4xxx_check_relogin_flash_ddb(struct iscsi_cls_session *cls_sess)
{ {
struct iscsi_session *sess; struct iscsi_session *sess;
struct ddb_entry *ddb_entry; struct ddb_entry *ddb_entry;
...@@ -3826,16 +3826,14 @@ static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha, ...@@ -3826,16 +3826,14 @@ static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha,
return ret; return ret;
} }
static void qla4xxx_free_nt_list(struct list_head *list_nt) static void qla4xxx_free_ddb_list(struct list_head *list_ddb)
{ {
struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp; struct qla_ddb_index *ddb_idx, *ddb_idx_tmp;
/* Free up the normaltargets list */ list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, list_ddb, list) {
list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) { list_del_init(&ddb_idx->list);
list_del_init(&nt_ddb_idx->list); vfree(ddb_idx);
vfree(nt_ddb_idx);
} }
} }
static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha, static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha,
...@@ -3934,7 +3932,6 @@ static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha) ...@@ -3934,7 +3932,6 @@ static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha)
ip_state == IP_ADDRSTATE_DEPRICATED || ip_state == IP_ADDRSTATE_DEPRICATED ||
ip_state == IP_ADDRSTATE_DISABLING) ip_state == IP_ADDRSTATE_DISABLING)
ip_idx[idx] = -1; ip_idx[idx] = -1;
} }
/* Break if all IP states checked */ /* Break if all IP states checked */
...@@ -3947,52 +3944,34 @@ static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha) ...@@ -3947,52 +3944,34 @@ static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha)
} while (time_after(wtime, jiffies)); } while (time_after(wtime, jiffies));
} }
void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) static void qla4xxx_build_st_list(struct scsi_qla_host *ha,
struct list_head *list_st)
{ {
struct qla_ddb_index *st_ddb_idx;
int max_ddbs; int max_ddbs;
int fw_idx_size;
struct dev_db_entry *fw_ddb_entry;
dma_addr_t fw_ddb_dma;
int ret; int ret;
uint32_t idx = 0, next_idx = 0; uint32_t idx = 0, next_idx = 0;
uint32_t state = 0, conn_err = 0; uint32_t state = 0, conn_err = 0;
uint16_t conn_id; uint16_t conn_id = 0;
struct dev_db_entry *fw_ddb_entry;
struct ddb_entry *ddb_entry = NULL;
dma_addr_t fw_ddb_dma;
struct iscsi_cls_session *cls_sess;
struct iscsi_session *sess;
struct iscsi_cls_conn *cls_conn;
struct iscsi_endpoint *ep;
uint16_t cmds_max = 32, tmo = 0;
uint32_t initial_cmdsn = 0;
struct list_head list_st, list_nt; /* List of sendtargets */
struct qla_ddb_index *st_ddb_idx, *st_ddb_idx_tmp;
int fw_idx_size;
unsigned long wtime;
struct qla_ddb_index *nt_ddb_idx;
if (!test_bit(AF_LINK_UP, &ha->flags)) {
set_bit(AF_BUILD_DDB_LIST, &ha->flags);
ha->is_reset = is_reset;
return;
}
max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
MAX_DEV_DB_ENTRIES;
fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,
&fw_ddb_dma); &fw_ddb_dma);
if (fw_ddb_entry == NULL) { if (fw_ddb_entry == NULL) {
DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n")); DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n"));
goto exit_ddb_list; goto exit_st_list;
} }
INIT_LIST_HEAD(&list_st); max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
INIT_LIST_HEAD(&list_nt); MAX_DEV_DB_ENTRIES;
fw_idx_size = sizeof(struct qla_ddb_index); fw_idx_size = sizeof(struct qla_ddb_index);
for (idx = 0; idx < max_ddbs; idx = next_idx) { for (idx = 0; idx < max_ddbs; idx = next_idx) {
ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, fw_ddb_dma,
fw_ddb_dma, NULL, NULL, &next_idx, &state,
&next_idx, &state, &conn_err, &conn_err, NULL, &conn_id);
NULL, &conn_id);
if (ret == QLA_ERROR) if (ret == QLA_ERROR)
break; break;
...@@ -4009,110 +3988,76 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) ...@@ -4009,110 +3988,76 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset)
st_ddb_idx->fw_ddb_idx = idx; st_ddb_idx->fw_ddb_idx = idx;
list_add_tail(&st_ddb_idx->list, &list_st); list_add_tail(&st_ddb_idx->list, list_st);
continue_next_st: continue_next_st:
if (next_idx == 0) if (next_idx == 0)
break; break;
} }
/* Before issuing conn open mbox, ensure all IPs states are configured exit_st_list:
* Note, conn open fails if IPs are not configured if (fw_ddb_entry)
*/ dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);
qla4xxx_wait_for_ip_configuration(ha); }
/* Go thru the STs and fire the sendtargets by issuing conn open mbx */
list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) {
qla4xxx_conn_open(ha, st_ddb_idx->fw_ddb_idx);
}
/* Wait to ensure all sendtargets are done for min 12 sec wait */ /**
tmo = ((ha->def_timeout < LOGIN_TOV) ? LOGIN_TOV : ha->def_timeout); * qla4xxx_remove_failed_ddb - Remove inactive or failed ddb from list
DEBUG2(ql4_printk(KERN_INFO, ha, * @ha: pointer to adapter structure
"Default time to wait for build ddb %d\n", tmo)); * @list_ddb: List from which failed ddb to be removed
*
* Iterate over the list of DDBs and find and remove DDBs that are either in
* no connection active state or failed state
**/
static void qla4xxx_remove_failed_ddb(struct scsi_qla_host *ha,
struct list_head *list_ddb)
{
struct qla_ddb_index *ddb_idx, *ddb_idx_tmp;
uint32_t next_idx = 0;
uint32_t state = 0, conn_err = 0;
int ret;
wtime = jiffies + (HZ * tmo); list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, list_ddb, list) {
do { ret = qla4xxx_get_fwddb_entry(ha, ddb_idx->fw_ddb_idx,
list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, NULL, 0, NULL, &next_idx, &state,
list) { &conn_err, NULL, NULL);
ret = qla4xxx_get_fwddb_entry(ha,
st_ddb_idx->fw_ddb_idx,
NULL, 0, NULL, &next_idx,
&state, &conn_err, NULL,
NULL);
if (ret == QLA_ERROR) if (ret == QLA_ERROR)
continue; continue;
if (state == DDB_DS_NO_CONNECTION_ACTIVE || if (state == DDB_DS_NO_CONNECTION_ACTIVE ||
state == DDB_DS_SESSION_FAILED) { state == DDB_DS_SESSION_FAILED) {
list_del_init(&st_ddb_idx->list); list_del_init(&ddb_idx->list);
vfree(st_ddb_idx); vfree(ddb_idx);
}
} }
schedule_timeout_uninterruptible(HZ / 10);
} while (time_after(wtime, jiffies));
/* Free up the sendtargets list */
list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) {
list_del_init(&st_ddb_idx->list);
vfree(st_ddb_idx);
} }
}
for (idx = 0; idx < max_ddbs; idx = next_idx) { static int qla4xxx_sess_conn_setup(struct scsi_qla_host *ha,
ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, struct dev_db_entry *fw_ddb_entry,
fw_ddb_dma, NULL, int is_reset)
&next_idx, &state, &conn_err, {
NULL, &conn_id); struct iscsi_cls_session *cls_sess;
if (ret == QLA_ERROR) struct iscsi_session *sess;
break; struct iscsi_cls_conn *cls_conn;
struct iscsi_endpoint *ep;
if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS) uint16_t cmds_max = 32;
goto continue_next_nt; uint16_t conn_id = 0;
uint32_t initial_cmdsn = 0;
/* Check if NT, then add to list it */ int ret = QLA_SUCCESS;
if (strlen((char *) fw_ddb_entry->iscsi_name) == 0)
goto continue_next_nt;
if (state == DDB_DS_NO_CONNECTION_ACTIVE ||
state == DDB_DS_SESSION_FAILED) {
DEBUG2(ql4_printk(KERN_INFO, ha,
"Adding DDB to session = 0x%x\n",
idx));
if (is_reset == INIT_ADAPTER) {
nt_ddb_idx = vmalloc(fw_idx_size);
if (!nt_ddb_idx)
break;
nt_ddb_idx->fw_ddb_idx = idx;
memcpy(&nt_ddb_idx->fw_ddb, fw_ddb_entry,
sizeof(struct dev_db_entry));
if (qla4xxx_is_flash_ddb_exists(ha, &list_nt, struct ddb_entry *ddb_entry = NULL;
fw_ddb_entry) == QLA_SUCCESS) {
vfree(nt_ddb_idx);
goto continue_next_nt;
}
list_add_tail(&nt_ddb_idx->list, &list_nt);
} else if (is_reset == RESET_ADAPTER) {
if (qla4xxx_is_session_exists(ha,
fw_ddb_entry) == QLA_SUCCESS)
goto continue_next_nt;
}
/* Create session object, with INVALID_ENTRY, /* Create session object, with INVALID_ENTRY,
* the targer_id would get set when we issue the login * the targer_id would get set when we issue the login
*/ */
cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, ha->host,
ha->host, cmds_max, cmds_max, sizeof(struct ddb_entry),
sizeof(struct ddb_entry),
sizeof(struct ql4_task_data), sizeof(struct ql4_task_data),
initial_cmdsn, INVALID_ENTRY); initial_cmdsn, INVALID_ENTRY);
if (!cls_sess) if (!cls_sess) {
goto exit_ddb_list; ret = QLA_ERROR;
goto exit_setup;
}
/* /*
* iscsi_session_setup increments the driver reference
* count which wouldn't let the driver to be unloaded.
* so calling module_put function to decrement the * so calling module_put function to decrement the
* reference count. * reference count.
**/ **/
...@@ -4127,11 +4072,12 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) ...@@ -4127,11 +4072,12 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset)
qla4xxx_setup_flash_ddb_entry(ha, ddb_entry); qla4xxx_setup_flash_ddb_entry(ha, ddb_entry);
cls_conn = iscsi_conn_setup(cls_sess, cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn), conn_id);
sizeof(struct qla_conn),
conn_id); if (!cls_conn) {
if (!cls_conn) ret = QLA_ERROR;
goto exit_ddb_list; goto exit_setup;
}
ddb_entry->conn = cls_conn; ddb_entry->conn = cls_conn;
...@@ -4141,13 +4087,13 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) ...@@ -4141,13 +4087,13 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset)
ep->conn = cls_conn; ep->conn = cls_conn;
cls_conn->ep = ep; cls_conn->ep = ep;
} else { } else {
DEBUG2(ql4_printk(KERN_ERR, ha, DEBUG2(ql4_printk(KERN_ERR, ha, "Unable to get ep\n"));
"Unable to get ep\n")); ret = QLA_ERROR;
goto exit_setup;
} }
/* Update sess/conn params */ /* Update sess/conn params */
qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, cls_conn);
cls_conn);
if (is_reset == RESET_ADAPTER) { if (is_reset == RESET_ADAPTER) {
iscsi_block_session(cls_sess); iscsi_block_session(cls_sess);
...@@ -4159,20 +4105,149 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) ...@@ -4159,20 +4105,149 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset)
set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags); set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);
set_bit(DF_RELOGIN, &ddb_entry->flags); set_bit(DF_RELOGIN, &ddb_entry->flags);
} }
exit_setup:
return ret;
}
static void qla4xxx_build_nt_list(struct scsi_qla_host *ha,
struct list_head *list_nt, int is_reset)
{
struct dev_db_entry *fw_ddb_entry;
dma_addr_t fw_ddb_dma;
int max_ddbs;
int fw_idx_size;
int ret;
uint32_t idx = 0, next_idx = 0;
uint32_t state = 0, conn_err = 0;
uint16_t conn_id = 0;
struct qla_ddb_index *nt_ddb_idx;
fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,
&fw_ddb_dma);
if (fw_ddb_entry == NULL) {
DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n"));
goto exit_nt_list;
}
max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
MAX_DEV_DB_ENTRIES;
fw_idx_size = sizeof(struct qla_ddb_index);
for (idx = 0; idx < max_ddbs; idx = next_idx) {
ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, fw_ddb_dma,
NULL, &next_idx, &state,
&conn_err, NULL, &conn_id);
if (ret == QLA_ERROR)
break;
if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS)
goto continue_next_nt;
/* Check if NT, then add to list it */
if (strlen((char *) fw_ddb_entry->iscsi_name) == 0)
goto continue_next_nt;
if (!(state == DDB_DS_NO_CONNECTION_ACTIVE ||
state == DDB_DS_SESSION_FAILED))
goto continue_next_nt;
DEBUG2(ql4_printk(KERN_INFO, ha,
"Adding DDB to session = 0x%x\n", idx));
if (is_reset == INIT_ADAPTER) {
nt_ddb_idx = vmalloc(fw_idx_size);
if (!nt_ddb_idx)
break;
nt_ddb_idx->fw_ddb_idx = idx;
memcpy(&nt_ddb_idx->fw_ddb, fw_ddb_entry,
sizeof(struct dev_db_entry));
if (qla4xxx_is_flash_ddb_exists(ha, list_nt,
fw_ddb_entry) == QLA_SUCCESS) {
vfree(nt_ddb_idx);
goto continue_next_nt;
}
list_add_tail(&nt_ddb_idx->list, list_nt);
} else if (is_reset == RESET_ADAPTER) {
if (qla4xxx_is_session_exists(ha, fw_ddb_entry) ==
QLA_SUCCESS)
goto continue_next_nt;
} }
ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, is_reset);
if (ret == QLA_ERROR)
goto exit_nt_list;
continue_next_nt: continue_next_nt:
if (next_idx == 0) if (next_idx == 0)
break; break;
} }
exit_ddb_list:
qla4xxx_free_nt_list(&list_nt); exit_nt_list:
if (fw_ddb_entry) if (fw_ddb_entry)
dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);
}
/**
* qla4xxx_build_ddb_list - Build ddb list and setup sessions
* @ha: pointer to adapter structure
* @is_reset: Is this init path or reset path
*
* Create a list of sendtargets (st) from firmware DDBs, issue send targets
* using connection open, then create the list of normal targets (nt)
* from firmware DDBs. Based on the list of nt setup session and connection
* objects.
**/
void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset)
{
uint16_t tmo = 0;
struct list_head list_st, list_nt;
struct qla_ddb_index *st_ddb_idx, *st_ddb_idx_tmp;
unsigned long wtime;
if (!test_bit(AF_LINK_UP, &ha->flags)) {
set_bit(AF_BUILD_DDB_LIST, &ha->flags);
ha->is_reset = is_reset;
return;
}
INIT_LIST_HEAD(&list_st);
INIT_LIST_HEAD(&list_nt);
qla4xxx_build_st_list(ha, &list_st);
/* Before issuing conn open mbox, ensure all IPs states are configured
* Note, conn open fails if IPs are not configured
*/
qla4xxx_wait_for_ip_configuration(ha);
/* Go thru the STs and fire the sendtargets by issuing conn open mbx */
list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) {
qla4xxx_conn_open(ha, st_ddb_idx->fw_ddb_idx);
}
/* Wait to ensure all sendtargets are done for min 12 sec wait */
tmo = ((ha->def_timeout < LOGIN_TOV) ? LOGIN_TOV : ha->def_timeout);
DEBUG2(ql4_printk(KERN_INFO, ha,
"Default time to wait for build ddb %d\n", tmo));
wtime = jiffies + (HZ * tmo);
do {
qla4xxx_remove_failed_ddb(ha, &list_st);
schedule_timeout_uninterruptible(HZ / 10);
} while (time_after(wtime, jiffies));
/* Free up the sendtargets list */
qla4xxx_free_ddb_list(&list_st);
qla4xxx_build_nt_list(ha, &list_nt, is_reset);
qla4xxx_free_ddb_list(&list_nt);
qla4xxx_free_ddb_index(ha); qla4xxx_free_ddb_index(ha);
} }
/** /**
* qla4xxx_probe_adapter - callback function to probe HBA * qla4xxx_probe_adapter - callback function to probe HBA
* @pdev: pointer to pci_dev structure * @pdev: pointer to pci_dev structure
......
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