aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx/ql4_mbx.c
diff options
context:
space:
mode:
authorNilesh Javali <nilesh.javali@qlogic.com>2013-08-16 07:03:03 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-09-03 10:27:54 -0400
commit7ab284c9fb8b2e9d6e8e16ebde9c1b015ba607cb (patch)
tree246cdec652b9e3e1034b6c238790a4d02c4ee8d1 /drivers/scsi/qla4xxx/ql4_mbx.c
parentb37ca4183c287448ad0096381d030ca5fc788059 (diff)
[SCSI] qla4xxx: Implementation of ACB configuration during Loopback for ISP8042
While loopback diagnostic is in progress, disable the ACB which resets all the active connections to target. Disable ACB would filter out all the DHCP multicast and broadcast packets which otherwise cause the diagnostic test to take longer time to complete or failures in some other cases. Signed-off-by: Nilesh Javali <nilesh.javali@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_mbx.c')
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c132
1 files changed, 130 insertions, 2 deletions
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}