mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 12:16:20 +00:00
[SCSI] qla4xxx: ql4_init.c bugfixes
In qla4xxx_get_ddb_entry() and qla4xxx_add_device_dynamically() differentiate between a target which has been newly added vs a target which went offline temporarily and is online again. In qla4xxx_build_ddb_list() firmware ddb state needs to be updated by calling qla4xxx_get_ddb_entry(). Fix qla4x00_pci_config() and clean up code. Signed-off-by: David Somayajulu <david.somayajulu@qlogic.com> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
b285431657
commit
92b7273608
1 changed files with 63 additions and 29 deletions
|
@ -6,6 +6,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ql4_def.h"
|
#include "ql4_def.h"
|
||||||
|
#include "ql4_glbl.h"
|
||||||
|
#include "ql4_dbg.h"
|
||||||
|
#include "ql4_inline.h"
|
||||||
|
|
||||||
static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
|
static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
|
||||||
uint32_t fw_ddb_index);
|
uint32_t fw_ddb_index);
|
||||||
|
@ -300,12 +303,12 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha)
|
||||||
if (!qla4xxx_fw_ready(ha))
|
if (!qla4xxx_fw_ready(ha))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
set_bit(AF_ONLINE, &ha->flags);
|
|
||||||
return qla4xxx_get_firmware_status(ha);
|
return qla4xxx_get_firmware_status(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
|
static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
|
||||||
uint32_t fw_ddb_index)
|
uint32_t fw_ddb_index,
|
||||||
|
uint32_t *new_tgt)
|
||||||
{
|
{
|
||||||
struct dev_db_entry *fw_ddb_entry = NULL;
|
struct dev_db_entry *fw_ddb_entry = NULL;
|
||||||
dma_addr_t fw_ddb_entry_dma;
|
dma_addr_t fw_ddb_entry_dma;
|
||||||
|
@ -313,6 +316,7 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
|
||||||
int found = 0;
|
int found = 0;
|
||||||
uint32_t device_state;
|
uint32_t device_state;
|
||||||
|
|
||||||
|
*new_tgt = 0;
|
||||||
/* Make sure the dma buffer is valid */
|
/* Make sure the dma buffer is valid */
|
||||||
fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
|
fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
|
||||||
sizeof(*fw_ddb_entry),
|
sizeof(*fw_ddb_entry),
|
||||||
|
@ -337,7 +341,7 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
|
||||||
DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no,
|
DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no,
|
||||||
__func__, fw_ddb_index));
|
__func__, fw_ddb_index));
|
||||||
list_for_each_entry(ddb_entry, &ha->ddb_list, list) {
|
list_for_each_entry(ddb_entry, &ha->ddb_list, list) {
|
||||||
if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsiName,
|
if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name,
|
||||||
ISCSI_NAME_SIZE) == 0) {
|
ISCSI_NAME_SIZE) == 0) {
|
||||||
found++;
|
found++;
|
||||||
break;
|
break;
|
||||||
|
@ -348,6 +352,7 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
|
||||||
DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating "
|
DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating "
|
||||||
"new ddb\n", ha->host_no, __func__,
|
"new ddb\n", ha->host_no, __func__,
|
||||||
fw_ddb_index));
|
fw_ddb_index));
|
||||||
|
*new_tgt = 1;
|
||||||
ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index);
|
ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,26 +414,26 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha,
|
||||||
}
|
}
|
||||||
|
|
||||||
status = QLA_SUCCESS;
|
status = QLA_SUCCESS;
|
||||||
ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->TSID);
|
ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid);
|
||||||
ddb_entry->task_mgmt_timeout =
|
ddb_entry->task_mgmt_timeout =
|
||||||
le16_to_cpu(fw_ddb_entry->taskMngmntTimeout);
|
le16_to_cpu(fw_ddb_entry->def_timeout);
|
||||||
ddb_entry->CmdSn = 0;
|
ddb_entry->CmdSn = 0;
|
||||||
ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exeThrottle);
|
ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exec_throttle);
|
||||||
ddb_entry->default_relogin_timeout =
|
ddb_entry->default_relogin_timeout =
|
||||||
le16_to_cpu(fw_ddb_entry->taskMngmntTimeout);
|
le16_to_cpu(fw_ddb_entry->def_timeout);
|
||||||
ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->minTime2Wait);
|
ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);
|
||||||
|
|
||||||
/* Update index in case it changed */
|
/* Update index in case it changed */
|
||||||
ddb_entry->fw_ddb_index = fw_ddb_index;
|
ddb_entry->fw_ddb_index = fw_ddb_index;
|
||||||
ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
|
ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
|
||||||
|
|
||||||
ddb_entry->port = le16_to_cpu(fw_ddb_entry->portNumber);
|
ddb_entry->port = le16_to_cpu(fw_ddb_entry->port);
|
||||||
ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->TargetPortalGroup);
|
ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
|
||||||
memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsiName[0],
|
memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsi_name[0],
|
||||||
min(sizeof(ddb_entry->iscsi_name),
|
min(sizeof(ddb_entry->iscsi_name),
|
||||||
sizeof(fw_ddb_entry->iscsiName)));
|
sizeof(fw_ddb_entry->iscsi_name)));
|
||||||
memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ipAddr[0],
|
memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0],
|
||||||
min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ipAddr)));
|
min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr)));
|
||||||
|
|
||||||
DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n",
|
DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n",
|
||||||
ha->host_no, __func__, fw_ddb_index,
|
ha->host_no, __func__, fw_ddb_index,
|
||||||
|
@ -495,6 +500,7 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
|
||||||
uint32_t ddb_state;
|
uint32_t ddb_state;
|
||||||
uint32_t conn_err, err_code;
|
uint32_t conn_err, err_code;
|
||||||
struct ddb_entry *ddb_entry;
|
struct ddb_entry *ddb_entry;
|
||||||
|
uint32_t new_tgt;
|
||||||
|
|
||||||
dev_info(&ha->pdev->dev, "Initializing DDBs ...\n");
|
dev_info(&ha->pdev->dev, "Initializing DDBs ...\n");
|
||||||
for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES;
|
for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES;
|
||||||
|
@ -526,8 +532,19 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
|
||||||
"completed "
|
"completed "
|
||||||
"or access denied failure\n",
|
"or access denied failure\n",
|
||||||
ha->host_no, __func__));
|
ha->host_no, __func__));
|
||||||
} else
|
} else {
|
||||||
qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0);
|
qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0);
|
||||||
|
if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index,
|
||||||
|
NULL, 0, NULL, &next_fw_ddb_index,
|
||||||
|
&ddb_state, &conn_err, NULL, NULL)
|
||||||
|
== QLA_ERROR) {
|
||||||
|
DEBUG2(printk("scsi%ld: %s:"
|
||||||
|
"get_ddb_entry %d failed\n",
|
||||||
|
ha->host_no,
|
||||||
|
__func__, fw_ddb_index));
|
||||||
|
return QLA_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ddb_state != DDB_DS_SESSION_ACTIVE)
|
if (ddb_state != DDB_DS_SESSION_ACTIVE)
|
||||||
|
@ -540,7 +557,7 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
|
||||||
ha->host_no, __func__, fw_ddb_index));
|
ha->host_no, __func__, fw_ddb_index));
|
||||||
|
|
||||||
/* Add DDB to internal our ddb list. */
|
/* Add DDB to internal our ddb list. */
|
||||||
ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index);
|
ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt);
|
||||||
if (ddb_entry == NULL) {
|
if (ddb_entry == NULL) {
|
||||||
DEBUG2(printk("scsi%ld: %s: Unable to allocate memory "
|
DEBUG2(printk("scsi%ld: %s: Unable to allocate memory "
|
||||||
"for device at fw_ddb_index %d\n",
|
"for device at fw_ddb_index %d\n",
|
||||||
|
@ -865,21 +882,19 @@ static int qla4xxx_config_nvram(struct scsi_qla_host *ha)
|
||||||
|
|
||||||
static void qla4x00_pci_config(struct scsi_qla_host *ha)
|
static void qla4x00_pci_config(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
uint16_t w, mwi;
|
uint16_t w;
|
||||||
|
|
||||||
dev_info(&ha->pdev->dev, "Configuring PCI space...\n");
|
dev_info(&ha->pdev->dev, "Configuring PCI space...\n");
|
||||||
|
|
||||||
pci_set_master(ha->pdev);
|
pci_set_master(ha->pdev);
|
||||||
mwi = 0;
|
pci_set_mwi(ha->pdev);
|
||||||
if (pci_set_mwi(ha->pdev))
|
|
||||||
mwi = PCI_COMMAND_INVALIDATE;
|
|
||||||
/*
|
/*
|
||||||
* We want to respect framework's setting of PCI configuration space
|
* We want to respect framework's setting of PCI configuration space
|
||||||
* command register and also want to make sure that all bits of
|
* command register and also want to make sure that all bits of
|
||||||
* interest to us are properly set in command register.
|
* interest to us are properly set in command register.
|
||||||
*/
|
*/
|
||||||
pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
|
pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
|
||||||
w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
|
w |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
|
||||||
w &= ~PCI_COMMAND_INTX_DISABLE;
|
w &= ~PCI_COMMAND_INTX_DISABLE;
|
||||||
pci_write_config_word(ha->pdev, PCI_COMMAND, w);
|
pci_write_config_word(ha->pdev, PCI_COMMAND, w);
|
||||||
}
|
}
|
||||||
|
@ -911,6 +926,9 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
|
||||||
writel(set_rmask(NVR_WRITE_ENABLE),
|
writel(set_rmask(NVR_WRITE_ENABLE),
|
||||||
&ha->reg->u1.isp4022.nvram);
|
&ha->reg->u1.isp4022.nvram);
|
||||||
|
|
||||||
|
writel(2, &ha->reg->mailbox[6]);
|
||||||
|
readl(&ha->reg->mailbox[6]);
|
||||||
|
|
||||||
writel(set_rmask(CSR_BOOT_ENABLE), &ha->reg->ctrl_status);
|
writel(set_rmask(CSR_BOOT_ENABLE), &ha->reg->ctrl_status);
|
||||||
readl(&ha->reg->ctrl_status);
|
readl(&ha->reg->ctrl_status);
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
@ -958,25 +976,25 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ql4xxx_lock_drvr_wait(struct scsi_qla_host *ha)
|
int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a)
|
||||||
{
|
{
|
||||||
#define QL4_LOCK_DRVR_WAIT 30
|
#define QL4_LOCK_DRVR_WAIT 60
|
||||||
#define QL4_LOCK_DRVR_SLEEP 1
|
#define QL4_LOCK_DRVR_SLEEP 1
|
||||||
|
|
||||||
int drvr_wait = QL4_LOCK_DRVR_WAIT;
|
int drvr_wait = QL4_LOCK_DRVR_WAIT;
|
||||||
while (drvr_wait) {
|
while (drvr_wait) {
|
||||||
if (ql4xxx_lock_drvr(ha) == 0) {
|
if (ql4xxx_lock_drvr(a) == 0) {
|
||||||
ssleep(QL4_LOCK_DRVR_SLEEP);
|
ssleep(QL4_LOCK_DRVR_SLEEP);
|
||||||
if (drvr_wait) {
|
if (drvr_wait) {
|
||||||
DEBUG2(printk("scsi%ld: %s: Waiting for "
|
DEBUG2(printk("scsi%ld: %s: Waiting for "
|
||||||
"Global Init Semaphore(%d)...n",
|
"Global Init Semaphore(%d)...\n",
|
||||||
ha->host_no,
|
a->host_no,
|
||||||
__func__, drvr_wait));
|
__func__, drvr_wait));
|
||||||
}
|
}
|
||||||
drvr_wait -= QL4_LOCK_DRVR_SLEEP;
|
drvr_wait -= QL4_LOCK_DRVR_SLEEP;
|
||||||
} else {
|
} else {
|
||||||
DEBUG2(printk("scsi%ld: %s: Global Init Semaphore "
|
DEBUG2(printk("scsi%ld: %s: Global Init Semaphore "
|
||||||
"acquired.n", ha->host_no, __func__));
|
"acquired\n", a->host_no, __func__));
|
||||||
return QLA_SUCCESS;
|
return QLA_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1142,8 +1160,10 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
|
||||||
* the ddb_list and wait for DHCP lease acquired aen to come in
|
* the ddb_list and wait for DHCP lease acquired aen to come in
|
||||||
* followed by 0x8014 aen" to trigger the tgt discovery process.
|
* followed by 0x8014 aen" to trigger the tgt discovery process.
|
||||||
*/
|
*/
|
||||||
if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS)
|
if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS){
|
||||||
|
set_bit(AF_ONLINE, &ha->flags);
|
||||||
return status;
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip device discovery if ip and subnet is zero */
|
/* Skip device discovery if ip and subnet is zero */
|
||||||
if (memcmp(ha->ip_address, ip_address, IP_ADDR_LEN) == 0 ||
|
if (memcmp(ha->ip_address, ip_address, IP_ADDR_LEN) == 0 ||
|
||||||
|
@ -1177,6 +1197,7 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
|
||||||
ha->host_no));
|
ha->host_no));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_bit(AF_ONLINE, &ha->flags);
|
||||||
exit_init_hba:
|
exit_init_hba:
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
@ -1193,9 +1214,10 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha,
|
||||||
uint32_t fw_ddb_index)
|
uint32_t fw_ddb_index)
|
||||||
{
|
{
|
||||||
struct ddb_entry * ddb_entry;
|
struct ddb_entry * ddb_entry;
|
||||||
|
uint32_t new_tgt;
|
||||||
|
|
||||||
/* First allocate a device structure */
|
/* First allocate a device structure */
|
||||||
ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index);
|
ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt);
|
||||||
if (ddb_entry == NULL) {
|
if (ddb_entry == NULL) {
|
||||||
DEBUG2(printk(KERN_WARNING
|
DEBUG2(printk(KERN_WARNING
|
||||||
"scsi%ld: Unable to allocate memory to add "
|
"scsi%ld: Unable to allocate memory to add "
|
||||||
|
@ -1203,6 +1225,18 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!new_tgt && (ddb_entry->fw_ddb_index != fw_ddb_index)) {
|
||||||
|
/* Target has been bound to a new fw_ddb_index */
|
||||||
|
qla4xxx_free_ddb(ha, ddb_entry);
|
||||||
|
ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index);
|
||||||
|
if (ddb_entry == NULL) {
|
||||||
|
DEBUG2(printk(KERN_WARNING
|
||||||
|
"scsi%ld: Unable to allocate memory"
|
||||||
|
" to add fw_ddb_index %d\n",
|
||||||
|
ha->host_no, fw_ddb_index));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) ==
|
if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) ==
|
||||||
QLA_ERROR) {
|
QLA_ERROR) {
|
||||||
ha->fw_ddb_index_map[fw_ddb_index] =
|
ha->fw_ddb_index_map[fw_ddb_index] =
|
||||||
|
|
Loading…
Reference in a new issue