aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_gs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 21:57:35 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 21:57:35 -0400
commit97d41e90fe61399b99d74820cb7f2d6e0fbac91d (patch)
treef759371424a26963b04badbb4433e360be4e8750 /drivers/scsi/qla2xxx/qla_gs.c
parent3bdc9d0b408e01c4e556daba0035ba37f603e920 (diff)
parentafaf5a2d341d33b66b47c2716a263ce593460a08 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (54 commits) [SCSI] Initial Commit of qla4xxx [SCSI] raid class: handle component-add errors [SCSI] SCSI megaraid_sas: handle thrown errors [SCSI] SCSI aic94xx: handle sysfs errors [SCSI] SCSI st: fix error handling in module init, sysfs [SCSI] SCSI sd: fix module init/exit error handling [SCSI] SCSI osst: add error handling to module init, sysfs [SCSI] scsi: remove hosts.h [SCSI] scsi: Scsi_Cmnd convertion in aic7xxx_old.c [SCSI] megaraid_sas: sets ioctl timeout and updates version,changelog [SCSI] megaraid_sas: adds tasklet for cmd completion [SCSI] megaraid_sas: prints pending cmds before setting hw_crit_error [SCSI] megaraid_sas: function pointer for disable interrupt [SCSI] megaraid_sas: frame count optimization [SCSI] megaraid_sas: FW transition and q size changes [SCSI] qla2xxx: Update version number to 8.01.07-k2. [SCSI] qla2xxx: Stall mid-layer error handlers while rport is blocked. [SCSI] qla2xxx: Add MODULE_FIRMWARE tags. [SCSI] qla2xxx: Add support for host port state FC transport attribute. [SCSI] qla2xxx: Add support for fabric name FC transport attribute. ...
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_gs.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c228
1 files changed, 212 insertions, 16 deletions
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 2ebf259fccb2..97fbc62ec669 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -612,6 +612,14 @@ qla2x00_rnn_id(scsi_qla_host_t *ha)
612 return (rval); 612 return (rval);
613} 613}
614 614
615void
616qla2x00_get_sym_node_name(scsi_qla_host_t *ha, uint8_t *snn)
617{
618 sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s",ha->model_number,
619 ha->fw_major_version, ha->fw_minor_version,
620 ha->fw_subminor_version, qla2x00_version_str);
621}
622
615/** 623/**
616 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. 624 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
617 * @ha: HA context 625 * @ha: HA context
@@ -622,9 +630,6 @@ int
622qla2x00_rsnn_nn(scsi_qla_host_t *ha) 630qla2x00_rsnn_nn(scsi_qla_host_t *ha)
623{ 631{
624 int rval; 632 int rval;
625 uint8_t *snn;
626 uint8_t version[20];
627
628 ms_iocb_entry_t *ms_pkt; 633 ms_iocb_entry_t *ms_pkt;
629 struct ct_sns_req *ct_req; 634 struct ct_sns_req *ct_req;
630 struct ct_sns_rsp *ct_rsp; 635 struct ct_sns_rsp *ct_rsp;
@@ -649,20 +654,11 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
649 memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE); 654 memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE);
650 655
651 /* Prepare the Symbolic Node Name */ 656 /* Prepare the Symbolic Node Name */
652 /* Board type */ 657 qla2x00_get_sym_node_name(ha, ct_req->req.rsnn_nn.sym_node_name);
653 snn = ct_req->req.rsnn_nn.sym_node_name;
654 strcpy(snn, ha->model_number);
655 /* Firmware version */
656 strcat(snn, " FW:v");
657 sprintf(version, "%d.%02d.%02d", ha->fw_major_version,
658 ha->fw_minor_version, ha->fw_subminor_version);
659 strcat(snn, version);
660 /* Driver version */
661 strcat(snn, " DVR:v");
662 strcat(snn, qla2x00_version_str);
663 658
664 /* Calculate SNN length */ 659 /* Calculate SNN length */
665 ct_req->req.rsnn_nn.name_len = (uint8_t)strlen(snn); 660 ct_req->req.rsnn_nn.name_len =
661 (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
666 662
667 /* Update MS IOCB request */ 663 /* Update MS IOCB request */
668 ms_pkt->req_bytecount = 664 ms_pkt->req_bytecount =
@@ -687,7 +683,6 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
687 return (rval); 683 return (rval);
688} 684}
689 685
690
691/** 686/**
692 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. 687 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
693 * @ha: HA context 688 * @ha: HA context
@@ -1585,6 +1580,21 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
1585 DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no, 1580 DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no,
1586 eiter->a.os_dev_name)); 1581 eiter->a.os_dev_name));
1587 1582
1583 /* Hostname. */
1584 if (strlen(fc_host_system_hostname(ha->host))) {
1585 eiter = (struct ct_fdmi_port_attr *) (entries + size);
1586 eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME);
1587 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
1588 "%s", fc_host_system_hostname(ha->host));
1589 alen = strlen(eiter->a.host_name);
1590 alen += (alen & 3) ? (4 - (alen & 3)) : 4;
1591 eiter->len = cpu_to_be16(4 + alen);
1592 size += 4 + alen;
1593
1594 DEBUG13(printk("%s(%ld): HOSTNAME=%s.\n", __func__,
1595 ha->host_no, eiter->a.host_name));
1596 }
1597
1588 /* Update MS request size. */ 1598 /* Update MS request size. */
1589 qla2x00_update_ms_fdmi_iocb(ha, size + 16); 1599 qla2x00_update_ms_fdmi_iocb(ha, size + 16);
1590 1600
@@ -1647,3 +1657,189 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha)
1647 1657
1648 return rval; 1658 return rval;
1649} 1659}
1660
1661/**
1662 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
1663 * @ha: HA context
1664 * @list: switch info entries to populate
1665 *
1666 * Returns 0 on success.
1667 */
1668int
1669qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list)
1670{
1671 int rval;
1672 uint16_t i;
1673
1674 ms_iocb_entry_t *ms_pkt;
1675 struct ct_sns_req *ct_req;
1676 struct ct_sns_rsp *ct_rsp;
1677
1678 if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
1679 return QLA_FUNCTION_FAILED;
1680
1681 for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
1682 /* Issue GFPN_ID */
1683 memset(list[i].fabric_port_name, 0, WWN_SIZE);
1684
1685 /* Prepare common MS IOCB */
1686 ms_pkt = qla2x00_prep_ms_iocb(ha, GFPN_ID_REQ_SIZE,
1687 GFPN_ID_RSP_SIZE);
1688
1689 /* Prepare CT request */
1690 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD,
1691 GFPN_ID_RSP_SIZE);
1692 ct_rsp = &ha->ct_sns->p.rsp;
1693
1694 /* Prepare CT arguments -- port_id */
1695 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
1696 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
1697 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
1698
1699 /* Execute MS IOCB */
1700 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
1701 sizeof(ms_iocb_entry_t));
1702 if (rval != QLA_SUCCESS) {
1703 /*EMPTY*/
1704 DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB "
1705 "failed (%d).\n", ha->host_no, rval));
1706 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
1707 "GFPN_ID") != QLA_SUCCESS) {
1708 rval = QLA_FUNCTION_FAILED;
1709 } else {
1710 /* Save fabric portname */
1711 memcpy(list[i].fabric_port_name,
1712 ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
1713 }
1714
1715 /* Last device exit. */
1716 if (list[i].d_id.b.rsvd_1 != 0)
1717 break;
1718 }
1719
1720 return (rval);
1721}
1722
1723static inline void *
1724qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size,
1725 uint32_t rsp_size)
1726{
1727 struct ct_entry_24xx *ct_pkt;
1728
1729 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
1730 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
1731
1732 ct_pkt->entry_type = CT_IOCB_TYPE;
1733 ct_pkt->entry_count = 1;
1734 ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
1735 ct_pkt->timeout = __constant_cpu_to_le16(59);
1736 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
1737 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
1738 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
1739 ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
1740
1741 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1742 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1743 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
1744
1745 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
1746 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
1747 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
1748
1749 return ct_pkt;
1750}
1751
1752
1753static inline struct ct_sns_req *
1754qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd,
1755 uint16_t rsp_size)
1756{
1757 memset(ct_req, 0, sizeof(struct ct_sns_pkt));
1758
1759 ct_req->header.revision = 0x01;
1760 ct_req->header.gs_type = 0xFA;
1761 ct_req->header.gs_subtype = 0x01;
1762 ct_req->command = cpu_to_be16(cmd);
1763 ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
1764
1765 return ct_req;
1766}
1767
1768/**
1769 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
1770 * @ha: HA context
1771 * @list: switch info entries to populate
1772 *
1773 * Returns 0 on success.
1774 */
1775int
1776qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list)
1777{
1778 int rval;
1779 uint16_t i;
1780
1781 ms_iocb_entry_t *ms_pkt;
1782 struct ct_sns_req *ct_req;
1783 struct ct_sns_rsp *ct_rsp;
1784
1785 if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
1786 return QLA_FUNCTION_FAILED;
1787
1788 rval = qla2x00_mgmt_svr_login(ha);
1789 if (rval)
1790 return rval;
1791
1792 for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
1793 /* Issue GFPN_ID */
1794 list[i].fp_speeds = list[i].fp_speed = 0;
1795
1796 /* Prepare common MS IOCB */
1797 ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE,
1798 GPSC_RSP_SIZE);
1799
1800 /* Prepare CT request */
1801 ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req,
1802 GPSC_CMD, GPSC_RSP_SIZE);
1803 ct_rsp = &ha->ct_sns->p.rsp;
1804
1805 /* Prepare CT arguments -- port_name */
1806 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
1807 WWN_SIZE);
1808
1809 /* Execute MS IOCB */
1810 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
1811 sizeof(ms_iocb_entry_t));
1812 if (rval != QLA_SUCCESS) {
1813 /*EMPTY*/
1814 DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB "
1815 "failed (%d).\n", ha->host_no, rval));
1816 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
1817 "GPSC") != QLA_SUCCESS) {
1818 rval = QLA_FUNCTION_FAILED;
1819 } else {
1820 /* Save portname */
1821 list[i].fp_speeds = ct_rsp->rsp.gpsc.speeds;
1822 list[i].fp_speed = ct_rsp->rsp.gpsc.speed;
1823
1824 DEBUG2_3(printk("scsi(%ld): GPSC ext entry - "
1825 "fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x "
1826 "speed=%04x.\n", ha->host_no,
1827 list[i].fabric_port_name[0],
1828 list[i].fabric_port_name[1],
1829 list[i].fabric_port_name[2],
1830 list[i].fabric_port_name[3],
1831 list[i].fabric_port_name[4],
1832 list[i].fabric_port_name[5],
1833 list[i].fabric_port_name[6],
1834 list[i].fabric_port_name[7],
1835 be16_to_cpu(list[i].fp_speeds),
1836 be16_to_cpu(list[i].fp_speed)));
1837 }
1838
1839 /* Last device exit. */
1840 if (list[i].d_id.b.rsvd_1 != 0)
1841 break;
1842 }
1843
1844 return (rval);
1845}