aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h3
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h6
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h6
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c34
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c132
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c31
6 files changed, 203 insertions, 9 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index bd01af5d1f89..b74a0e20b6ed 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -205,6 +205,7 @@
205 205
206#define MAX_RESET_HA_RETRIES 2 206#define MAX_RESET_HA_RETRIES 2
207#define FW_ALIVE_WAIT_TOV 3 207#define FW_ALIVE_WAIT_TOV 3
208#define IDC_EXTEND_TOV 8
208 209
209#define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr) 210#define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr)
210 211
@@ -562,6 +563,7 @@ struct scsi_qla_host {
562#define DPC_HA_UNRECOVERABLE 21 /* 0x00080000 ISP-82xx only*/ 563#define DPC_HA_UNRECOVERABLE 21 /* 0x00080000 ISP-82xx only*/
563#define DPC_HA_NEED_QUIESCENT 22 /* 0x00100000 ISP-82xx only*/ 564#define DPC_HA_NEED_QUIESCENT 22 /* 0x00100000 ISP-82xx only*/
564#define DPC_POST_IDC_ACK 23 /* 0x00200000 */ 565#define DPC_POST_IDC_ACK 23 /* 0x00200000 */
566#define DPC_RESTORE_ACB 24 /* 0x01000000 */
565 567
566 struct Scsi_Host *host; /* pointer to host data */ 568 struct Scsi_Host *host; /* pointer to host data */
567 uint32_t tot_ddbs; 569 uint32_t tot_ddbs;
@@ -786,6 +788,7 @@ struct scsi_qla_host {
786 and ISP8042 */ 788 and ISP8042 */
787 uint32_t pf_bit; 789 uint32_t pf_bit;
788 struct qla4_83xx_idc_information idc_info; 790 struct qla4_83xx_idc_information idc_info;
791 struct addr_ctrl_blk *saved_acb;
789}; 792};
790 793
791struct ql4_task_data { 794struct ql4_task_data {
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 9a46f5971d56..7aa132350249 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -458,6 +458,7 @@ struct qla_flt_region {
458#define MBOX_CMD_GET_CONN_EVENT_LOG 0x0077 458#define MBOX_CMD_GET_CONN_EVENT_LOG 0x0077
459 459
460#define MBOX_CMD_IDC_ACK 0x0101 460#define MBOX_CMD_IDC_ACK 0x0101
461#define MBOX_CMD_IDC_TIME_EXTEND 0x0102
461#define MBOX_CMD_PORT_RESET 0x0120 462#define MBOX_CMD_PORT_RESET 0x0120
462#define MBOX_CMD_SET_PORT_CONFIG 0x0122 463#define MBOX_CMD_SET_PORT_CONFIG 0x0122
463 464
@@ -502,6 +503,7 @@ struct qla_flt_region {
502#define MBOX_ASTS_SYSTEM_WARNING_EVENT 0x8036 503#define MBOX_ASTS_SYSTEM_WARNING_EVENT 0x8036
503#define MBOX_ASTS_IDC_COMPLETE 0x8100 504#define MBOX_ASTS_IDC_COMPLETE 0x8100
504#define MBOX_ASTS_IDC_REQUEST_NOTIFICATION 0x8101 505#define MBOX_ASTS_IDC_REQUEST_NOTIFICATION 0x8101
506#define MBOX_ASTS_IDC_TIME_EXTEND_NOTIFICATION 0x8102
505#define MBOX_ASTS_DCBX_CONF_CHANGE 0x8110 507#define MBOX_ASTS_DCBX_CONF_CHANGE 0x8110
506#define MBOX_ASTS_TXSCVR_INSERTED 0x8130 508#define MBOX_ASTS_TXSCVR_INSERTED 0x8130
507#define MBOX_ASTS_TXSCVR_REMOVED 0x8131 509#define MBOX_ASTS_TXSCVR_REMOVED 0x8131
@@ -512,6 +514,10 @@ struct qla_flt_region {
512#define MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR 0x8022 514#define MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR 0x8022
513#define MBOX_ASTS_SUBNET_STATE_CHANGE 0x8027 515#define MBOX_ASTS_SUBNET_STATE_CHANGE 0x8027
514 516
517/* ACB Configuration Defines */
518#define ACB_CONFIG_DISABLE 0x00
519#define ACB_CONFIG_SET 0x01
520
515/* ACB State Defines */ 521/* ACB State Defines */
516#define ACB_STATE_UNCONFIGURED 0x00 522#define ACB_STATE_UNCONFIGURED 0x00
517#define ACB_STATE_INVALID 0x01 523#define ACB_STATE_INVALID 0x01
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 4a428009f699..f9963de506d0 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -266,6 +266,12 @@ int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
266 dma_addr_t dma_addr); 266 dma_addr_t dma_addr);
267int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username, 267int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,
268 char *password, uint16_t chap_index); 268 char *password, uint16_t chap_index);
269int qla4xxx_disable_acb(struct scsi_qla_host *ha);
270int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
271 uint32_t *mbox_sts, dma_addr_t acb_dma);
272int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,
273 uint32_t acb_type, uint32_t len);
274int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config);
269 275
270extern int ql4xextended_error_logging; 276extern int ql4xextended_error_logging;
271extern int ql4xdontresethba; 277extern int ql4xdontresethba;
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index fbd415db5a52..4fefa3429a5f 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -745,17 +745,23 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
745 * mbox_sts[3] = new ACB state */ 745 * mbox_sts[3] = new ACB state */
746 if ((mbox_sts[3] == ACB_STATE_VALID) && 746 if ((mbox_sts[3] == ACB_STATE_VALID) &&
747 ((mbox_sts[2] == ACB_STATE_TENTATIVE) || 747 ((mbox_sts[2] == ACB_STATE_TENTATIVE) ||
748 (mbox_sts[2] == ACB_STATE_ACQUIRING))) 748 (mbox_sts[2] == ACB_STATE_ACQUIRING))) {
749 set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags); 749 set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
750 else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) && 750 } else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) &&
751 (mbox_sts[2] == ACB_STATE_VALID)) { 751 (mbox_sts[2] == ACB_STATE_VALID)) {
752 if (is_qla80XX(ha)) 752 if (is_qla80XX(ha))
753 set_bit(DPC_RESET_HA_FW_CONTEXT, 753 set_bit(DPC_RESET_HA_FW_CONTEXT,
754 &ha->dpc_flags); 754 &ha->dpc_flags);
755 else 755 else
756 set_bit(DPC_RESET_HA, &ha->dpc_flags); 756 set_bit(DPC_RESET_HA, &ha->dpc_flags);
757 } else if ((mbox_sts[3] == ACB_STATE_UNCONFIGURED)) 757 } else if (mbox_sts[3] == ACB_STATE_DISABLING) {
758 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ACB in disabling state\n",
759 ha->host_no, __func__);
760 } else if ((mbox_sts[3] == ACB_STATE_UNCONFIGURED)) {
758 complete(&ha->disable_acb_comp); 761 complete(&ha->disable_acb_comp);
762 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ACB state unconfigured\n",
763 ha->host_no, __func__);
764 }
759 break; 765 break;
760 766
761 case MBOX_ASTS_MAC_ADDRESS_CHANGED: 767 case MBOX_ASTS_MAC_ADDRESS_CHANGED:
@@ -869,10 +875,15 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
869 "scsi:%ld: AEN %04x IDC Complete notification\n", 875 "scsi:%ld: AEN %04x IDC Complete notification\n",
870 ha->host_no, mbox_sts[0])); 876 ha->host_no, mbox_sts[0]));
871 877
872 if (qla4_83xx_loopback_in_progress(ha)) 878 if (qla4_83xx_loopback_in_progress(ha)) {
873 set_bit(AF_LOOPBACK, &ha->flags); 879 set_bit(AF_LOOPBACK, &ha->flags);
874 else 880 } else {
875 clear_bit(AF_LOOPBACK, &ha->flags); 881 clear_bit(AF_LOOPBACK, &ha->flags);
882 if (ha->saved_acb)
883 set_bit(DPC_RESTORE_ACB,
884 &ha->dpc_flags);
885 }
886 qla4xxx_wake_dpc(ha);
876 } 887 }
877 break; 888 break;
878 889
@@ -887,6 +898,17 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
887 ha->host_no, mbox_sts[0])); 898 ha->host_no, mbox_sts[0]));
888 break; 899 break;
889 900
901 case MBOX_ASTS_IDC_TIME_EXTEND_NOTIFICATION:
902 DEBUG2(ql4_printk(KERN_INFO, ha,
903 "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x mbox_sts[5]=%08x\n",
904 ha->host_no, mbox_sts[0], mbox_sts[1],
905 mbox_sts[2], mbox_sts[3], mbox_sts[4],
906 mbox_sts[5]));
907 DEBUG2(ql4_printk(KERN_INFO, ha,
908 "scsi%ld: AEN %04x Received IDC Extend Timeout notification\n",
909 ha->host_no, mbox_sts[0]));
910 break;
911
890 case MBOX_ASTS_INITIALIZATION_FAILED: 912 case MBOX_ASTS_INITIALIZATION_FAILED:
891 DEBUG2(ql4_printk(KERN_INFO, ha, 913 DEBUG2(ql4_printk(KERN_INFO, ha,
892 "scsi%ld: AEN %04x, mbox_sts[3]=%08x\n", 914 "scsi%ld: AEN %04x, mbox_sts[3]=%08x\n",
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index e39895cf48f0..fa1a06ab254a 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -1736,6 +1736,45 @@ int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha,
1736 return status; 1736 return status;
1737} 1737}
1738 1738
1739/**
1740 * qla4_84xx_extend_idc_tmo - Extend IDC Timeout.
1741 * @ha: Pointer to host adapter structure.
1742 * @ext_tmo: idc timeout value
1743 *
1744 * Requests firmware to extend the idc timeout value.
1745 **/
1746static int qla4_84xx_extend_idc_tmo(struct scsi_qla_host *ha, uint32_t ext_tmo)
1747{
1748 uint32_t mbox_cmd[MBOX_REG_COUNT];
1749 uint32_t mbox_sts[MBOX_REG_COUNT];
1750 int status;
1751
1752 memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1753 memset(&mbox_sts, 0, sizeof(mbox_sts));
1754 ext_tmo &= 0xf;
1755
1756 mbox_cmd[0] = MBOX_CMD_IDC_TIME_EXTEND;
1757 mbox_cmd[1] = ((ha->idc_info.request_desc & 0xfffff0ff) |
1758 (ext_tmo << 8)); /* new timeout */
1759 mbox_cmd[2] = ha->idc_info.info1;
1760 mbox_cmd[3] = ha->idc_info.info2;
1761 mbox_cmd[4] = ha->idc_info.info3;
1762
1763 status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,
1764 mbox_cmd, mbox_sts);
1765 if (status != QLA_SUCCESS) {
1766 DEBUG2(ql4_printk(KERN_INFO, ha,
1767 "scsi%ld: %s: failed status %04X\n",
1768 ha->host_no, __func__, mbox_sts[0]));
1769 return QLA_ERROR;
1770 } else {
1771 ql4_printk(KERN_INFO, ha, "%s: IDC timeout extended by %d secs\n",
1772 __func__, ext_tmo);
1773 }
1774
1775 return QLA_SUCCESS;
1776}
1777
1739int qla4xxx_disable_acb(struct scsi_qla_host *ha) 1778int qla4xxx_disable_acb(struct scsi_qla_host *ha)
1740{ 1779{
1741 uint32_t mbox_cmd[MBOX_REG_COUNT]; 1780 uint32_t mbox_cmd[MBOX_REG_COUNT];
@@ -1752,6 +1791,23 @@ int qla4xxx_disable_acb(struct scsi_qla_host *ha)
1752 DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_DISABLE_ACB " 1791 DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_DISABLE_ACB "
1753 "failed w/ status %04X %04X %04X", __func__, 1792 "failed w/ status %04X %04X %04X", __func__,
1754 mbox_sts[0], mbox_sts[1], mbox_sts[2])); 1793 mbox_sts[0], mbox_sts[1], mbox_sts[2]));
1794 } else {
1795 if (is_qla8042(ha) &&
1796 (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE)) {
1797 /*
1798 * Disable ACB mailbox command takes time to complete
1799 * based on the total number of targets connected.
1800 * For 512 targets, it took approximately 5 secs to
1801 * complete. Setting the timeout value to 8, with the 3
1802 * secs buffer.
1803 */
1804 qla4_84xx_extend_idc_tmo(ha, IDC_EXTEND_TOV);
1805 if (!wait_for_completion_timeout(&ha->disable_acb_comp,
1806 IDC_EXTEND_TOV * HZ)) {
1807 ql4_printk(KERN_WARNING, ha, "%s: Disable ACB Completion not received\n",
1808 __func__);
1809 }
1810 }
1755 } 1811 }
1756 return status; 1812 return status;
1757} 1813}
@@ -2158,8 +2214,80 @@ int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha)
2158 ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__, 2214 ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__,
2159 mbox_sts[0]); 2215 mbox_sts[0]);
2160 else 2216 else
2161 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IDC ACK posted\n", 2217 ql4_printk(KERN_INFO, ha, "%s: IDC ACK posted\n", __func__);
2162 __func__));
2163 2218
2164 return status; 2219 return status;
2165} 2220}
2221
2222int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config)
2223{
2224 uint32_t mbox_cmd[MBOX_REG_COUNT];
2225 uint32_t mbox_sts[MBOX_REG_COUNT];
2226 struct addr_ctrl_blk *acb = NULL;
2227 uint32_t acb_len = sizeof(struct addr_ctrl_blk);
2228 int rval = QLA_SUCCESS;
2229 dma_addr_t acb_dma;
2230
2231 acb = dma_alloc_coherent(&ha->pdev->dev,
2232 sizeof(struct addr_ctrl_blk),
2233 &acb_dma, GFP_KERNEL);
2234 if (!acb) {
2235 ql4_printk(KERN_ERR, ha, "%s: Unable to alloc acb\n", __func__);
2236 rval = QLA_ERROR;
2237 goto exit_config_acb;
2238 }
2239 memset(acb, 0, acb_len);
2240
2241 switch (acb_config) {
2242 case ACB_CONFIG_DISABLE:
2243 rval = qla4xxx_get_acb(ha, acb_dma, 0, acb_len);
2244 if (rval != QLA_SUCCESS)
2245 goto exit_free_acb;
2246
2247 rval = qla4xxx_disable_acb(ha);
2248 if (rval != QLA_SUCCESS)
2249 goto exit_free_acb;
2250
2251 if (!ha->saved_acb)
2252 ha->saved_acb = kzalloc(acb_len, GFP_KERNEL);
2253
2254 if (!ha->saved_acb) {
2255 ql4_printk(KERN_ERR, ha, "%s: Unable to alloc acb\n",
2256 __func__);
2257 rval = QLA_ERROR;
2258 goto exit_config_acb;
2259 }
2260 memcpy(ha->saved_acb, acb, acb_len);
2261 break;
2262 case ACB_CONFIG_SET:
2263
2264 if (!ha->saved_acb) {
2265 ql4_printk(KERN_ERR, ha, "%s: Can't set ACB, Saved ACB not available\n",
2266 __func__);
2267 rval = QLA_ERROR;
2268 goto exit_free_acb;
2269 }
2270
2271 memcpy(acb, ha->saved_acb, acb_len);
2272 kfree(ha->saved_acb);
2273 ha->saved_acb = NULL;
2274
2275 rval = qla4xxx_set_acb(ha, &mbox_cmd[0], &mbox_sts[0], acb_dma);
2276 if (rval != QLA_SUCCESS)
2277 goto exit_free_acb;
2278
2279 break;
2280 default:
2281 ql4_printk(KERN_ERR, ha, "%s: Invalid ACB Configuration\n",
2282 __func__);
2283 }
2284
2285exit_free_acb:
2286 dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), acb,
2287 acb_dma);
2288exit_config_acb:
2289 DEBUG2(ql4_printk(KERN_INFO, ha,
2290 "%s %s\n", __func__,
2291 rval == QLA_SUCCESS ? "SUCCEEDED" : "FAILED"));
2292 return rval;
2293}
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 4f9651a76997..6956de9d97d3 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -2671,6 +2671,8 @@ static int qla4xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
2671 !test_bit(AF_ONLINE, &ha->flags) || 2671 !test_bit(AF_ONLINE, &ha->flags) ||
2672 !test_bit(AF_LINK_UP, &ha->flags) || 2672 !test_bit(AF_LINK_UP, &ha->flags) ||
2673 test_bit(AF_LOOPBACK, &ha->flags) || 2673 test_bit(AF_LOOPBACK, &ha->flags) ||
2674 test_bit(DPC_POST_IDC_ACK, &ha->dpc_flags) ||
2675 test_bit(DPC_RESTORE_ACB, &ha->dpc_flags) ||
2674 test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) 2676 test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))
2675 goto qc_host_busy; 2677 goto qc_host_busy;
2676 2678
@@ -3863,8 +3865,35 @@ static void qla4xxx_do_dpc(struct work_struct *work)
3863 qla4_8xxx_device_state_handler(ha); 3865 qla4_8xxx_device_state_handler(ha);
3864 } 3866 }
3865 3867
3866 if (test_and_clear_bit(DPC_POST_IDC_ACK, &ha->dpc_flags)) 3868 if (test_bit(DPC_POST_IDC_ACK, &ha->dpc_flags)) {
3869 if (is_qla8042(ha)) {
3870 if (ha->idc_info.info2 &
3871 ENABLE_INTERNAL_LOOPBACK) {
3872 ql4_printk(KERN_INFO, ha, "%s: Disabling ACB\n",
3873 __func__);
3874 status = qla4_84xx_config_acb(ha,
3875 ACB_CONFIG_DISABLE);
3876 if (status != QLA_SUCCESS) {
3877 ql4_printk(KERN_INFO, ha, "%s: ACB config failed\n",
3878 __func__);
3879 }
3880 }
3881 }
3867 qla4_83xx_post_idc_ack(ha); 3882 qla4_83xx_post_idc_ack(ha);
3883 clear_bit(DPC_POST_IDC_ACK, &ha->dpc_flags);
3884 }
3885
3886 if (is_qla8042(ha) &&
3887 test_bit(DPC_RESTORE_ACB, &ha->dpc_flags)) {
3888 ql4_printk(KERN_INFO, ha, "%s: Restoring ACB\n",
3889 __func__);
3890 if (qla4_84xx_config_acb(ha, ACB_CONFIG_SET) !=
3891 QLA_SUCCESS) {
3892 ql4_printk(KERN_INFO, ha, "%s: ACB config failed ",
3893 __func__);
3894 }
3895 clear_bit(DPC_RESTORE_ACB, &ha->dpc_flags);
3896 }
3868 3897
3869 if (test_and_clear_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) { 3898 if (test_and_clear_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) {
3870 qla4_8xxx_need_qsnt_handler(ha); 3899 qla4_8xxx_need_qsnt_handler(ha);