aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_bsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_bsg.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c376
1 files changed, 333 insertions, 43 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index c68883806c54..2f9bddd3c616 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * QLogic Fibre Channel HBA Driver 2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2011 QLogic Corporation 3 * Copyright (c) 2003-2012 QLogic Corporation
4 * 4 *
5 * See LICENSE.qla2xxx for copyright and licensing details. 5 * See LICENSE.qla2xxx for copyright and licensing details.
6 */ 6 */
@@ -530,13 +530,13 @@ done_unmap_sg:
530done: 530done:
531 return rval; 531 return rval;
532} 532}
533 533/*
534/* Set the port configuration to enable the 534 * Set the port configuration to enable the internal or external loopback
535 * internal loopback on ISP81XX 535 * depending on the loopback mode.
536 */ 536 */
537static inline int 537static inline int
538qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config, 538qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
539 uint16_t *new_config) 539 uint16_t *new_config, uint16_t mode)
540{ 540{
541 int ret = 0; 541 int ret = 0;
542 int rval = 0; 542 int rval = 0;
@@ -545,8 +545,14 @@ qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
545 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 545 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
546 goto done_set_internal; 546 goto done_set_internal;
547 547
548 new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1); 548 if (mode == INTERNAL_LOOPBACK)
549 memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ; 549 new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
550 else if (mode == EXTERNAL_LOOPBACK)
551 new_config[0] = config[0] | (ENABLE_EXTERNAL_LOOPBACK << 1);
552 ql_dbg(ql_dbg_user, vha, 0x70be,
553 "new_config[0]=%02x\n", (new_config[0] & INTERNAL_LOOPBACK_MASK));
554
555 memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3);
550 556
551 ha->notify_dcbx_comp = 1; 557 ha->notify_dcbx_comp = 1;
552 ret = qla81xx_set_port_config(vha, new_config); 558 ret = qla81xx_set_port_config(vha, new_config);
@@ -562,9 +568,17 @@ qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
562 if (!wait_for_completion_timeout(&ha->dcbx_comp, (20 * HZ))) { 568 if (!wait_for_completion_timeout(&ha->dcbx_comp, (20 * HZ))) {
563 ql_dbg(ql_dbg_user, vha, 0x7022, 569 ql_dbg(ql_dbg_user, vha, 0x7022,
564 "State change notification not received.\n"); 570 "State change notification not received.\n");
565 } else 571 rval = -EINVAL;
566 ql_dbg(ql_dbg_user, vha, 0x7023, 572 } else {
567 "State change received.\n"); 573 if (ha->flags.idc_compl_status) {
574 ql_dbg(ql_dbg_user, vha, 0x70c3,
575 "Bad status in IDC Completion AEN\n");
576 rval = -EINVAL;
577 ha->flags.idc_compl_status = 0;
578 } else
579 ql_dbg(ql_dbg_user, vha, 0x7023,
580 "State change received.\n");
581 }
568 582
569 ha->notify_dcbx_comp = 0; 583 ha->notify_dcbx_comp = 0;
570 584
@@ -572,11 +586,9 @@ done_set_internal:
572 return rval; 586 return rval;
573} 587}
574 588
575/* Set the port configuration to disable the 589/* Disable loopback mode */
576 * internal loopback on ISP81XX
577 */
578static inline int 590static inline int
579qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config, 591qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
580 int wait) 592 int wait)
581{ 593{
582 int ret = 0; 594 int ret = 0;
@@ -589,8 +601,12 @@ qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
589 601
590 memset(new_config, 0 , sizeof(new_config)); 602 memset(new_config, 0 , sizeof(new_config));
591 if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 == 603 if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
592 ENABLE_INTERNAL_LOOPBACK) { 604 ENABLE_INTERNAL_LOOPBACK ||
605 (config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
606 ENABLE_EXTERNAL_LOOPBACK) {
593 new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK; 607 new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK;
608 ql_dbg(ql_dbg_user, vha, 0x70bf, "new_config[0]=%02x\n",
609 (new_config[0] & INTERNAL_LOOPBACK_MASK));
594 memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ; 610 memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
595 611
596 ha->notify_dcbx_comp = wait; 612 ha->notify_dcbx_comp = wait;
@@ -707,7 +723,8 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
707 723
708 elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1]; 724 elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
709 725
710 if ((ha->current_topology == ISP_CFG_F || 726 if (atomic_read(&vha->loop_state) == LOOP_READY &&
727 (ha->current_topology == ISP_CFG_F ||
711 ((IS_QLA81XX(ha) || IS_QLA8031(ha)) && 728 ((IS_QLA81XX(ha) || IS_QLA8031(ha)) &&
712 le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE 729 le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
713 && req_data_len == MAX_ELS_FRAME_PAYLOAD)) && 730 && req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
@@ -729,30 +746,24 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
729 goto done_free_dma_req; 746 goto done_free_dma_req;
730 } 747 }
731 748
732 if (elreq.options != EXTERNAL_LOOPBACK) { 749 ql_dbg(ql_dbg_user, vha, 0x70c0,
733 ql_dbg(ql_dbg_user, vha, 0x7020, 750 "elreq.options=%04x\n", elreq.options);
734 "Internal: current port config = %x\n", 751
735 config[0]); 752 if (elreq.options == EXTERNAL_LOOPBACK)
736 if (qla81xx_set_internal_loopback(vha, config, 753 if (IS_QLA8031(ha))
737 new_config)) { 754 rval = qla81xx_set_loopback_mode(vha,
738 ql_log(ql_log_warn, vha, 0x7024, 755 config, new_config, elreq.options);
739 "Internal loopback failed.\n"); 756 else
740 bsg_job->reply->result = 757 rval = qla81xx_reset_loopback_mode(vha,
741 (DID_ERROR << 16); 758 config, 1);
742 rval = -EPERM; 759 else
743 goto done_free_dma_req; 760 rval = qla81xx_set_loopback_mode(vha, config,
744 } 761 new_config, elreq.options);
745 } else { 762
746 /* For external loopback to work 763 if (rval) {
747 * ensure internal loopback is disabled 764 bsg_job->reply->result = (DID_ERROR << 16);
748 */ 765 rval = -EPERM;
749 if (qla81xx_reset_internal_loopback(vha, 766 goto done_free_dma_req;
750 config, 1)) {
751 bsg_job->reply->result =
752 (DID_ERROR << 16);
753 rval = -EPERM;
754 goto done_free_dma_req;
755 }
756 } 767 }
757 768
758 type = "FC_BSG_HST_VENDOR_LOOPBACK"; 769 type = "FC_BSG_HST_VENDOR_LOOPBACK";
@@ -766,7 +777,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
766 /* Revert back to original port config 777 /* Revert back to original port config
767 * Also clear internal loopback 778 * Also clear internal loopback
768 */ 779 */
769 qla81xx_reset_internal_loopback(vha, 780 qla81xx_reset_loopback_mode(vha,
770 new_config, 0); 781 new_config, 0);
771 } 782 }
772 783
@@ -1364,7 +1375,7 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
1364 struct qla_hw_data *ha = vha->hw; 1375 struct qla_hw_data *ha = vha->hw;
1365 int rval = 0; 1376 int rval = 0;
1366 1377
1367 if (ha->flags.isp82xx_reset_hdlr_active) 1378 if (ha->flags.nic_core_reset_hdlr_active)
1368 return -EBUSY; 1379 return -EBUSY;
1369 1380
1370 rval = qla2x00_optrom_setup(bsg_job, vha, 0); 1381 rval = qla2x00_optrom_setup(bsg_job, vha, 0);
@@ -1560,6 +1571,276 @@ done:
1560} 1571}
1561 1572
1562static int 1573static int
1574qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
1575{
1576 struct Scsi_Host *host = bsg_job->shost;
1577 scsi_qla_host_t *vha = shost_priv(host);
1578 struct qla_hw_data *ha = vha->hw;
1579 int rval = 0;
1580 uint8_t bsg[DMA_POOL_SIZE];
1581 struct qla_i2c_access *i2c = (void *)bsg;
1582 dma_addr_t sfp_dma;
1583 uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1584 if (!sfp) {
1585 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1586 EXT_STATUS_NO_MEMORY;
1587 goto done;
1588 }
1589
1590 sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1591 bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1592
1593 memcpy(sfp, i2c->buffer, i2c->length);
1594 rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1595 i2c->device, i2c->offset, i2c->length, i2c->option);
1596
1597 if (rval) {
1598 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1599 EXT_STATUS_MAILBOX;
1600 goto dealloc;
1601 }
1602
1603 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1604
1605dealloc:
1606 dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1607
1608done:
1609 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1610 bsg_job->reply->result = DID_OK << 16;
1611 bsg_job->job_done(bsg_job);
1612
1613 return 0;
1614}
1615
1616static int
1617qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
1618{
1619 struct Scsi_Host *host = bsg_job->shost;
1620 scsi_qla_host_t *vha = shost_priv(host);
1621 struct qla_hw_data *ha = vha->hw;
1622 int rval = 0;
1623 uint8_t bsg[DMA_POOL_SIZE];
1624 struct qla_i2c_access *i2c = (void *)bsg;
1625 dma_addr_t sfp_dma;
1626 uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1627 if (!sfp) {
1628 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1629 EXT_STATUS_NO_MEMORY;
1630 goto done;
1631 }
1632
1633 sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1634 bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1635
1636 rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1637 i2c->device, i2c->offset, i2c->length, i2c->option);
1638
1639 if (rval) {
1640 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1641 EXT_STATUS_MAILBOX;
1642 goto dealloc;
1643 }
1644
1645 memcpy(i2c->buffer, sfp, i2c->length);
1646 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1647 bsg_job->reply_payload.sg_cnt, i2c, sizeof(*i2c));
1648
1649 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1650
1651dealloc:
1652 dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1653
1654done:
1655 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1656 bsg_job->reply->reply_payload_rcv_len = sizeof(*i2c);
1657 bsg_job->reply->result = DID_OK << 16;
1658 bsg_job->job_done(bsg_job);
1659
1660 return 0;
1661}
1662
1663static int
1664qla24xx_process_bidir_cmd(struct fc_bsg_job *bsg_job)
1665{
1666 struct Scsi_Host *host = bsg_job->shost;
1667 scsi_qla_host_t *vha = shost_priv(host);
1668 struct qla_hw_data *ha = vha->hw;
1669 uint16_t thread_id;
1670 uint32_t rval = EXT_STATUS_OK;
1671 uint16_t req_sg_cnt = 0;
1672 uint16_t rsp_sg_cnt = 0;
1673 uint16_t nextlid = 0;
1674 uint32_t tot_dsds;
1675 srb_t *sp = NULL;
1676 uint32_t req_data_len = 0;
1677 uint32_t rsp_data_len = 0;
1678
1679 /* Check the type of the adapter */
1680 if (!IS_BIDI_CAPABLE(ha)) {
1681 ql_log(ql_log_warn, vha, 0x70a0,
1682 "This adapter is not supported\n");
1683 rval = EXT_STATUS_NOT_SUPPORTED;
1684 goto done;
1685 }
1686
1687 if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
1688 test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
1689 test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
1690 rval = EXT_STATUS_BUSY;
1691 goto done;
1692 }
1693
1694 /* Check if host is online */
1695 if (!vha->flags.online) {
1696 ql_log(ql_log_warn, vha, 0x70a1,
1697 "Host is not online\n");
1698 rval = EXT_STATUS_DEVICE_OFFLINE;
1699 goto done;
1700 }
1701
1702 /* Check if cable is plugged in or not */
1703 if (vha->device_flags & DFLG_NO_CABLE) {
1704 ql_log(ql_log_warn, vha, 0x70a2,
1705 "Cable is unplugged...\n");
1706 rval = EXT_STATUS_INVALID_CFG;
1707 goto done;
1708 }
1709
1710 /* Check if the switch is connected or not */
1711 if (ha->current_topology != ISP_CFG_F) {
1712 ql_log(ql_log_warn, vha, 0x70a3,
1713 "Host is not connected to the switch\n");
1714 rval = EXT_STATUS_INVALID_CFG;
1715 goto done;
1716 }
1717
1718 /* Check if operating mode is P2P */
1719 if (ha->operating_mode != P2P) {
1720 ql_log(ql_log_warn, vha, 0x70a4,
1721 "Host is operating mode is not P2p\n");
1722 rval = EXT_STATUS_INVALID_CFG;
1723 goto done;
1724 }
1725
1726 thread_id = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
1727
1728 mutex_lock(&ha->selflogin_lock);
1729 if (vha->self_login_loop_id == 0) {
1730 /* Initialize all required fields of fcport */
1731 vha->bidir_fcport.vha = vha;
1732 vha->bidir_fcport.d_id.b.al_pa = vha->d_id.b.al_pa;
1733 vha->bidir_fcport.d_id.b.area = vha->d_id.b.area;
1734 vha->bidir_fcport.d_id.b.domain = vha->d_id.b.domain;
1735 vha->bidir_fcport.loop_id = vha->loop_id;
1736
1737 if (qla2x00_fabric_login(vha, &(vha->bidir_fcport), &nextlid)) {
1738 ql_log(ql_log_warn, vha, 0x70a7,
1739 "Failed to login port %06X for bidirectional IOCB\n",
1740 vha->bidir_fcport.d_id.b24);
1741 mutex_unlock(&ha->selflogin_lock);
1742 rval = EXT_STATUS_MAILBOX;
1743 goto done;
1744 }
1745 vha->self_login_loop_id = nextlid - 1;
1746
1747 }
1748 /* Assign the self login loop id to fcport */
1749 mutex_unlock(&ha->selflogin_lock);
1750
1751 vha->bidir_fcport.loop_id = vha->self_login_loop_id;
1752
1753 req_sg_cnt = dma_map_sg(&ha->pdev->dev,
1754 bsg_job->request_payload.sg_list,
1755 bsg_job->request_payload.sg_cnt,
1756 DMA_TO_DEVICE);
1757
1758 if (!req_sg_cnt) {
1759 rval = EXT_STATUS_NO_MEMORY;
1760 goto done;
1761 }
1762
1763 rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
1764 bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
1765 DMA_FROM_DEVICE);
1766
1767 if (!rsp_sg_cnt) {
1768 rval = EXT_STATUS_NO_MEMORY;
1769 goto done_unmap_req_sg;
1770 }
1771
1772 if ((req_sg_cnt != bsg_job->request_payload.sg_cnt) ||
1773 (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
1774 ql_dbg(ql_dbg_user, vha, 0x70a9,
1775 "Dma mapping resulted in different sg counts "
1776 "[request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt: "
1777 "%x dma_reply_sg_cnt: %x]\n",
1778 bsg_job->request_payload.sg_cnt, req_sg_cnt,
1779 bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
1780 rval = EXT_STATUS_NO_MEMORY;
1781 goto done_unmap_sg;
1782 }
1783
1784 if (req_data_len != rsp_data_len) {
1785 rval = EXT_STATUS_BUSY;
1786 ql_log(ql_log_warn, vha, 0x70aa,
1787 "req_data_len != rsp_data_len\n");
1788 goto done_unmap_sg;
1789 }
1790
1791 req_data_len = bsg_job->request_payload.payload_len;
1792 rsp_data_len = bsg_job->reply_payload.payload_len;
1793
1794
1795 /* Alloc SRB structure */
1796 sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
1797 if (!sp) {
1798 ql_dbg(ql_dbg_user, vha, 0x70ac,
1799 "Alloc SRB structure failed\n");
1800 rval = EXT_STATUS_NO_MEMORY;
1801 goto done_unmap_sg;
1802 }
1803
1804 /*Populate srb->ctx with bidir ctx*/
1805 sp->u.bsg_job = bsg_job;
1806 sp->free = qla2x00_bsg_sp_free;
1807 sp->type = SRB_BIDI_CMD;
1808 sp->done = qla2x00_bsg_job_done;
1809
1810 /* Add the read and write sg count */
1811 tot_dsds = rsp_sg_cnt + req_sg_cnt;
1812
1813 rval = qla2x00_start_bidir(sp, vha, tot_dsds);
1814 if (rval != EXT_STATUS_OK)
1815 goto done_free_srb;
1816 /* the bsg request will be completed in the interrupt handler */
1817 return rval;
1818
1819done_free_srb:
1820 mempool_free(sp, ha->srb_mempool);
1821done_unmap_sg:
1822 dma_unmap_sg(&ha->pdev->dev,
1823 bsg_job->reply_payload.sg_list,
1824 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1825done_unmap_req_sg:
1826 dma_unmap_sg(&ha->pdev->dev,
1827 bsg_job->request_payload.sg_list,
1828 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1829done:
1830
1831 /* Return an error vendor specific response
1832 * and complete the bsg request
1833 */
1834 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
1835 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1836 bsg_job->reply->reply_payload_rcv_len = 0;
1837 bsg_job->reply->result = (DID_OK) << 16;
1838 bsg_job->job_done(bsg_job);
1839 /* Always retrun success, vendor rsp carries correct status */
1840 return 0;
1841}
1842
1843static int
1563qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job) 1844qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
1564{ 1845{
1565 switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) { 1846 switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
@@ -1596,6 +1877,15 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
1596 case QL_VND_WRITE_FRU_STATUS: 1877 case QL_VND_WRITE_FRU_STATUS:
1597 return qla2x00_write_fru_status(bsg_job); 1878 return qla2x00_write_fru_status(bsg_job);
1598 1879
1880 case QL_VND_WRITE_I2C:
1881 return qla2x00_write_i2c(bsg_job);
1882
1883 case QL_VND_READ_I2C:
1884 return qla2x00_read_i2c(bsg_job);
1885
1886 case QL_VND_DIAG_IO_CMD:
1887 return qla24xx_process_bidir_cmd(bsg_job);
1888
1599 default: 1889 default:
1600 bsg_job->reply->result = (DID_ERROR << 16); 1890 bsg_job->reply->result = (DID_ERROR << 16);
1601 bsg_job->job_done(bsg_job); 1891 bsg_job->job_done(bsg_job);