diff options
author | Manish Rangankar <manish.rangankar@qlogic.com> | 2012-04-24 01:32:34 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-05-30 04:58:30 -0400 |
commit | 90599b62ca80a0d2f88aa88bc05bf8795731fab8 (patch) | |
tree | 74241acf30bd69fed2c91907413daa595b7048f6 /drivers | |
parent | 3d948e2a21ed8641a84ad437d2544b215d747916 (diff) |
[SCSI] qla4xxx: Fix clear ddb mbx command failure issue.
Allow ddb state to change to DDB_DS_NO_CONNECTION_ACTIVE or
DDB_DS_SESSION_FAILED before issuing clear ddb mailbox cmd,
because clear ddb mailbox cmd fails if the ddb state is not
equal to DDB_DS_NO_CONNECTION_ACTIVE or DDB_DS_SESSION_FAILED.
Signed-off-by: Manish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index ee47820c30a6..45144aa04433 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -1555,19 +1555,53 @@ static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess) | |||
1555 | struct iscsi_session *sess; | 1555 | struct iscsi_session *sess; |
1556 | struct ddb_entry *ddb_entry; | 1556 | struct ddb_entry *ddb_entry; |
1557 | struct scsi_qla_host *ha; | 1557 | struct scsi_qla_host *ha; |
1558 | unsigned long flags; | 1558 | unsigned long flags, wtime; |
1559 | struct dev_db_entry *fw_ddb_entry = NULL; | ||
1560 | dma_addr_t fw_ddb_entry_dma; | ||
1561 | uint32_t ddb_state; | ||
1562 | int ret; | ||
1559 | 1563 | ||
1560 | DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); | 1564 | DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); |
1561 | sess = cls_sess->dd_data; | 1565 | sess = cls_sess->dd_data; |
1562 | ddb_entry = sess->dd_data; | 1566 | ddb_entry = sess->dd_data; |
1563 | ha = ddb_entry->ha; | 1567 | ha = ddb_entry->ha; |
1564 | 1568 | ||
1569 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | ||
1570 | &fw_ddb_entry_dma, GFP_KERNEL); | ||
1571 | if (!fw_ddb_entry) { | ||
1572 | ql4_printk(KERN_ERR, ha, | ||
1573 | "%s: Unable to allocate dma buffer\n", __func__); | ||
1574 | goto destroy_session; | ||
1575 | } | ||
1576 | |||
1577 | wtime = jiffies + (HZ * LOGOUT_TOV); | ||
1578 | do { | ||
1579 | ret = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, | ||
1580 | fw_ddb_entry, fw_ddb_entry_dma, | ||
1581 | NULL, NULL, &ddb_state, NULL, | ||
1582 | NULL, NULL); | ||
1583 | if (ret == QLA_ERROR) | ||
1584 | goto destroy_session; | ||
1585 | |||
1586 | if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) || | ||
1587 | (ddb_state == DDB_DS_SESSION_FAILED)) | ||
1588 | goto destroy_session; | ||
1589 | |||
1590 | schedule_timeout_uninterruptible(HZ); | ||
1591 | } while ((time_after(wtime, jiffies))); | ||
1592 | |||
1593 | destroy_session: | ||
1565 | qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index); | 1594 | qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index); |
1566 | 1595 | ||
1567 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1596 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1568 | qla4xxx_free_ddb(ha, ddb_entry); | 1597 | qla4xxx_free_ddb(ha, ddb_entry); |
1569 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1598 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1599 | |||
1570 | iscsi_session_teardown(cls_sess); | 1600 | iscsi_session_teardown(cls_sess); |
1601 | |||
1602 | if (fw_ddb_entry) | ||
1603 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | ||
1604 | fw_ddb_entry, fw_ddb_entry_dma); | ||
1571 | } | 1605 | } |
1572 | 1606 | ||
1573 | static struct iscsi_cls_conn * | 1607 | static struct iscsi_cls_conn * |