summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx/ql4_init.c
diff options
context:
space:
mode:
authorLalit Chandivade <lalit.chandivade@qlogic.com>2011-10-08 01:55:45 +0200
committerJames Bottomley <JBottomley@Parallels.com>2011-10-16 18:09:49 +0200
commit166dd20d794e7885b23c8d5fc533949ed82cc337 (patch)
tree821795655f9a153261eabfec9374d1acee88be61 /drivers/scsi/qla4xxx/ql4_init.c
parent[SCSI] qla4xxx: Fix getting BIDI CHAP for boot targets (diff)
downloadlinux-166dd20d794e7885b23c8d5fc533949ed82cc337.tar.xz
linux-166dd20d794e7885b23c8d5fc533949ed82cc337.zip
[SCSI] qla4xxx: Free Device Database (DDB) reserved by FW
Firmware reserves DDBs if there are entries in the FLASH. So there are no free DDBs left when a iSCSI login is initiated by user space tool like iscsiadm. Since now login is not controlled by firmware, LLD need to free up the DDBs after firmware init. This will ensure free DDBs are available for iSCSI logins using iscsiadm. JIRA Key: UPSISCSI-151 Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to '')
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index b0bffe15c287..064a3a311e77 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -765,6 +765,44 @@ int qla4xxx_start_firmware(struct scsi_qla_host *ha)
}
return status;
}
+/**
+ * qla4xxx_free_ddb_index - Free DDBs reserved by firmware
+ * @ha: pointer to adapter structure
+ *
+ * Since firmware is not running in autoconnect mode the DDB indices should
+ * be freed so that when login happens from user space there are free DDB
+ * indices available.
+ **/
+static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha)
+{
+ int max_ddbs;
+ int ret;
+ uint32_t idx = 0, next_idx = 0;
+ uint32_t state = 0, conn_err = 0;
+
+ max_ddbs = is_qla40XX(ha) ? MAX_PRST_DEV_DB_ENTRIES :
+ MAX_DEV_DB_ENTRIES;
+
+ for (idx = 0; idx < max_ddbs; idx = next_idx) {
+ ret = qla4xxx_get_fwddb_entry(ha, idx, NULL, 0, NULL,
+ &next_idx, &state, &conn_err,
+ NULL, NULL);
+ if (ret == QLA_ERROR)
+ continue;
+ if (state == DDB_DS_NO_CONNECTION_ACTIVE ||
+ state == DDB_DS_SESSION_FAILED) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "Freeing DDB index = 0x%x\n", idx));
+ ret = qla4xxx_clear_ddb_entry(ha, idx);
+ if (ret == QLA_ERROR)
+ ql4_printk(KERN_ERR, ha,
+ "Unable to clear DDB index = "
+ "0x%x\n", idx);
+ }
+ if (next_idx == 0)
+ break;
+ }
+}
/**
@@ -802,6 +840,8 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha)
if (status == QLA_ERROR)
goto exit_init_hba;
+ qla4xxx_free_ddb_index(ha);
+
set_bit(AF_ONLINE, &ha->flags);
exit_init_hba:
if (is_qla8022(ha) && (status == QLA_ERROR)) {