diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 21:57:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 21:57:35 -0400 |
commit | 97d41e90fe61399b99d74820cb7f2d6e0fbac91d (patch) | |
tree | f759371424a26963b04badbb4433e360be4e8750 /drivers/scsi/qla2xxx/qla_gs.c | |
parent | 3bdc9d0b408e01c4e556daba0035ba37f603e920 (diff) | |
parent | afaf5a2d341d33b66b47c2716a263ce593460a08 (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.c | 228 |
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 | ||
615 | void | ||
616 | qla2x00_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 | |||
622 | qla2x00_rsnn_nn(scsi_qla_host_t *ha) | 630 | qla2x00_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 | */ | ||
1668 | int | ||
1669 | qla2x00_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 | |||
1723 | static inline void * | ||
1724 | qla24xx_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 | |||
1753 | static inline struct ct_sns_req * | ||
1754 | qla24xx_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 | */ | ||
1775 | int | ||
1776 | qla2x00_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 | } | ||