diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-08-29 03:30:41 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-08-29 03:31:47 -0400 |
| commit | eebc57f73d42095b778e899f6aa90ad050c72655 (patch) | |
| tree | 2ba80c75e9284093e6d7606dbb1b6a4bb752a2a5 /drivers/scsi | |
| parent | d3a247bfb2c26f5b67367d58af7ad8c2efbbc6c1 (diff) | |
| parent | 2a4ab640d3c28c2952967e5f63ea495555bf2a5f (diff) | |
Merge branch 'for-ingo' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-sfi-2.6 into x86/apic
Merge reason: the SFI (Simple Firmware Interface) feature in the ACPI
tree needs this cleanup, pull it into the APIC branch as
well so that there's no interactions.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/scsi')
| -rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 23 | ||||
| -rw-r--r-- | drivers/scsi/libiscsi.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/libsas/sas_expander.c | 147 | ||||
| -rw-r--r-- | drivers/scsi/libsas/sas_port.c | 19 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 98 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 6 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_config.c | 91 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 124 | ||||
| -rw-r--r-- | drivers/scsi/qla4xxx/ql4_dbg.c | 15 | ||||
| -rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 9 | ||||
| -rw-r--r-- | drivers/scsi/qla4xxx/ql4_fw.h | 7 | ||||
| -rw-r--r-- | drivers/scsi/qla4xxx/ql4_iocb.c | 133 | ||||
| -rw-r--r-- | drivers/scsi/qla4xxx/ql4_isr.c | 145 | ||||
| -rw-r--r-- | drivers/scsi/qla4xxx/ql4_mbx.c | 10 | ||||
| -rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 40 | ||||
| -rw-r--r-- | drivers/scsi/qla4xxx/ql4_version.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/sd.c | 20 |
18 files changed, 553 insertions, 344 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 2bc22be5f849..145ab9ba55ea 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
| @@ -415,9 +415,9 @@ static void fc_exch_timeout(struct work_struct *work) | |||
| 415 | e_stat = ep->esb_stat; | 415 | e_stat = ep->esb_stat; |
| 416 | if (e_stat & ESB_ST_COMPLETE) { | 416 | if (e_stat & ESB_ST_COMPLETE) { |
| 417 | ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL; | 417 | ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL; |
| 418 | spin_unlock_bh(&ep->ex_lock); | ||
| 418 | if (e_stat & ESB_ST_REC_QUAL) | 419 | if (e_stat & ESB_ST_REC_QUAL) |
| 419 | fc_exch_rrq(ep); | 420 | fc_exch_rrq(ep); |
| 420 | spin_unlock_bh(&ep->ex_lock); | ||
| 421 | goto done; | 421 | goto done; |
| 422 | } else { | 422 | } else { |
| 423 | resp = ep->resp; | 423 | resp = ep->resp; |
| @@ -1624,14 +1624,14 @@ static void fc_exch_rrq(struct fc_exch *ep) | |||
| 1624 | struct fc_lport *lp; | 1624 | struct fc_lport *lp; |
| 1625 | struct fc_els_rrq *rrq; | 1625 | struct fc_els_rrq *rrq; |
| 1626 | struct fc_frame *fp; | 1626 | struct fc_frame *fp; |
| 1627 | struct fc_seq *rrq_sp; | ||
| 1628 | u32 did; | 1627 | u32 did; |
| 1629 | 1628 | ||
| 1630 | lp = ep->lp; | 1629 | lp = ep->lp; |
| 1631 | 1630 | ||
| 1632 | fp = fc_frame_alloc(lp, sizeof(*rrq)); | 1631 | fp = fc_frame_alloc(lp, sizeof(*rrq)); |
| 1633 | if (!fp) | 1632 | if (!fp) |
| 1634 | return; | 1633 | goto retry; |
| 1634 | |||
| 1635 | rrq = fc_frame_payload_get(fp, sizeof(*rrq)); | 1635 | rrq = fc_frame_payload_get(fp, sizeof(*rrq)); |
| 1636 | memset(rrq, 0, sizeof(*rrq)); | 1636 | memset(rrq, 0, sizeof(*rrq)); |
| 1637 | rrq->rrq_cmd = ELS_RRQ; | 1637 | rrq->rrq_cmd = ELS_RRQ; |
| @@ -1647,13 +1647,20 @@ static void fc_exch_rrq(struct fc_exch *ep) | |||
| 1647 | fc_host_port_id(lp->host), FC_TYPE_ELS, | 1647 | fc_host_port_id(lp->host), FC_TYPE_ELS, |
| 1648 | FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); | 1648 | FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); |
| 1649 | 1649 | ||
| 1650 | rrq_sp = fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep, | 1650 | if (fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep, lp->e_d_tov)) |
| 1651 | lp->e_d_tov); | 1651 | return; |
| 1652 | if (!rrq_sp) { | 1652 | |
| 1653 | ep->esb_stat |= ESB_ST_REC_QUAL; | 1653 | retry: |
| 1654 | fc_exch_timer_set_locked(ep, ep->r_a_tov); | 1654 | spin_lock_bh(&ep->ex_lock); |
| 1655 | if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) { | ||
| 1656 | spin_unlock_bh(&ep->ex_lock); | ||
| 1657 | /* drop hold for rec qual */ | ||
| 1658 | fc_exch_release(ep); | ||
| 1655 | return; | 1659 | return; |
| 1656 | } | 1660 | } |
| 1661 | ep->esb_stat |= ESB_ST_REC_QUAL; | ||
| 1662 | fc_exch_timer_set_locked(ep, ep->r_a_tov); | ||
| 1663 | spin_unlock_bh(&ep->ex_lock); | ||
| 1657 | } | 1664 | } |
| 1658 | 1665 | ||
| 1659 | 1666 | ||
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 716cc344c5df..a751f6230c22 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -1974,10 +1974,10 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
| 1974 | * good and have never sent us a successful tmf response | 1974 | * good and have never sent us a successful tmf response |
| 1975 | * then sent more data for the cmd. | 1975 | * then sent more data for the cmd. |
| 1976 | */ | 1976 | */ |
| 1977 | spin_lock(&session->lock); | 1977 | spin_lock_bh(&session->lock); |
| 1978 | fail_scsi_task(task, DID_ABORT); | 1978 | fail_scsi_task(task, DID_ABORT); |
| 1979 | conn->tmf_state = TMF_INITIAL; | 1979 | conn->tmf_state = TMF_INITIAL; |
| 1980 | spin_unlock(&session->lock); | 1980 | spin_unlock_bh(&session->lock); |
| 1981 | iscsi_start_tx(conn); | 1981 | iscsi_start_tx(conn); |
| 1982 | goto success_unlocked; | 1982 | goto success_unlocked; |
| 1983 | case TMF_TIMEDOUT: | 1983 | case TMF_TIMEDOUT: |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 54fa1e42dc4d..b3381959acce 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
| @@ -766,6 +766,7 @@ static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) | |||
| 766 | if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr, | 766 | if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr, |
| 767 | SAS_ADDR_SIZE) && ephy->port) { | 767 | SAS_ADDR_SIZE) && ephy->port) { |
| 768 | sas_port_add_phy(ephy->port, phy->phy); | 768 | sas_port_add_phy(ephy->port, phy->phy); |
| 769 | phy->port = ephy->port; | ||
| 769 | phy->phy_state = PHY_DEVICE_DISCOVERED; | 770 | phy->phy_state = PHY_DEVICE_DISCOVERED; |
| 770 | return 0; | 771 | return 0; |
| 771 | } | 772 | } |
| @@ -945,11 +946,21 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
| 945 | if (ex->ex_phy[i].phy_state == PHY_VACANT || | 946 | if (ex->ex_phy[i].phy_state == PHY_VACANT || |
| 946 | ex->ex_phy[i].phy_state == PHY_NOT_PRESENT) | 947 | ex->ex_phy[i].phy_state == PHY_NOT_PRESENT) |
| 947 | continue; | 948 | continue; |
| 948 | 949 | /* | |
| 950 | * Due to races, the phy might not get added to the | ||
| 951 | * wide port, so we add the phy to the wide port here. | ||
| 952 | */ | ||
| 949 | if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) == | 953 | if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) == |
| 950 | SAS_ADDR(child->sas_addr)) | 954 | SAS_ADDR(child->sas_addr)) { |
| 951 | ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; | 955 | ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; |
| 956 | res = sas_ex_join_wide_port(dev, i); | ||
| 957 | if (!res) | ||
| 958 | SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", | ||
| 959 | i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); | ||
| 960 | |||
| 961 | } | ||
| 952 | } | 962 | } |
| 963 | res = 0; | ||
| 953 | } | 964 | } |
| 954 | 965 | ||
| 955 | return res; | 966 | return res; |
| @@ -1598,7 +1609,7 @@ static int sas_get_phy_attached_sas_addr(struct domain_device *dev, | |||
| 1598 | } | 1609 | } |
| 1599 | 1610 | ||
| 1600 | static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, | 1611 | static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, |
| 1601 | int from_phy) | 1612 | int from_phy, bool update) |
| 1602 | { | 1613 | { |
| 1603 | struct expander_device *ex = &dev->ex_dev; | 1614 | struct expander_device *ex = &dev->ex_dev; |
| 1604 | int res = 0; | 1615 | int res = 0; |
| @@ -1611,7 +1622,9 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, | |||
| 1611 | if (res) | 1622 | if (res) |
| 1612 | goto out; | 1623 | goto out; |
| 1613 | else if (phy_change_count != ex->ex_phy[i].phy_change_count) { | 1624 | else if (phy_change_count != ex->ex_phy[i].phy_change_count) { |
| 1614 | ex->ex_phy[i].phy_change_count = phy_change_count; | 1625 | if (update) |
| 1626 | ex->ex_phy[i].phy_change_count = | ||
| 1627 | phy_change_count; | ||
| 1615 | *phy_id = i; | 1628 | *phy_id = i; |
| 1616 | return 0; | 1629 | return 0; |
| 1617 | } | 1630 | } |
| @@ -1653,31 +1666,52 @@ out: | |||
| 1653 | kfree(rg_req); | 1666 | kfree(rg_req); |
| 1654 | return res; | 1667 | return res; |
| 1655 | } | 1668 | } |
| 1669 | /** | ||
| 1670 | * sas_find_bcast_dev - find the device issue BROADCAST(CHANGE). | ||
| 1671 | * @dev:domain device to be detect. | ||
| 1672 | * @src_dev: the device which originated BROADCAST(CHANGE). | ||
| 1673 | * | ||
| 1674 | * Add self-configuration expander suport. Suppose two expander cascading, | ||
| 1675 | * when the first level expander is self-configuring, hotplug the disks in | ||
| 1676 | * second level expander, BROADCAST(CHANGE) will not only be originated | ||
| 1677 | * in the second level expander, but also be originated in the first level | ||
| 1678 | * expander (see SAS protocol SAS 2r-14, 7.11 for detail), it is to say, | ||
| 1679 | * expander changed count in two level expanders will all increment at least | ||
| 1680 | * once, but the phy which chang count has changed is the source device which | ||
| 1681 | * we concerned. | ||
| 1682 | */ | ||
| 1656 | 1683 | ||
| 1657 | static int sas_find_bcast_dev(struct domain_device *dev, | 1684 | static int sas_find_bcast_dev(struct domain_device *dev, |
| 1658 | struct domain_device **src_dev) | 1685 | struct domain_device **src_dev) |
| 1659 | { | 1686 | { |
| 1660 | struct expander_device *ex = &dev->ex_dev; | 1687 | struct expander_device *ex = &dev->ex_dev; |
| 1661 | int ex_change_count = -1; | 1688 | int ex_change_count = -1; |
| 1689 | int phy_id = -1; | ||
| 1662 | int res; | 1690 | int res; |
| 1691 | struct domain_device *ch; | ||
| 1663 | 1692 | ||
| 1664 | res = sas_get_ex_change_count(dev, &ex_change_count); | 1693 | res = sas_get_ex_change_count(dev, &ex_change_count); |
| 1665 | if (res) | 1694 | if (res) |
| 1666 | goto out; | 1695 | goto out; |
| 1667 | if (ex_change_count != -1 && | 1696 | if (ex_change_count != -1 && ex_change_count != ex->ex_change_count) { |
| 1668 | ex_change_count != ex->ex_change_count) { | 1697 | /* Just detect if this expander phys phy change count changed, |
| 1669 | *src_dev = dev; | 1698 | * in order to determine if this expander originate BROADCAST, |
| 1670 | ex->ex_change_count = ex_change_count; | 1699 | * and do not update phy change count field in our structure. |
| 1671 | } else { | 1700 | */ |
| 1672 | struct domain_device *ch; | 1701 | res = sas_find_bcast_phy(dev, &phy_id, 0, false); |
| 1673 | 1702 | if (phy_id != -1) { | |
| 1674 | list_for_each_entry(ch, &ex->children, siblings) { | 1703 | *src_dev = dev; |
| 1675 | if (ch->dev_type == EDGE_DEV || | 1704 | ex->ex_change_count = ex_change_count; |
| 1676 | ch->dev_type == FANOUT_DEV) { | 1705 | SAS_DPRINTK("Expander phy change count has changed\n"); |
| 1677 | res = sas_find_bcast_dev(ch, src_dev); | 1706 | return res; |
| 1678 | if (src_dev) | 1707 | } else |
| 1679 | return res; | 1708 | SAS_DPRINTK("Expander phys DID NOT change\n"); |
| 1680 | } | 1709 | } |
| 1710 | list_for_each_entry(ch, &ex->children, siblings) { | ||
| 1711 | if (ch->dev_type == EDGE_DEV || ch->dev_type == FANOUT_DEV) { | ||
| 1712 | res = sas_find_bcast_dev(ch, src_dev); | ||
| 1713 | if (src_dev) | ||
| 1714 | return res; | ||
| 1681 | } | 1715 | } |
| 1682 | } | 1716 | } |
| 1683 | out: | 1717 | out: |
| @@ -1700,24 +1734,26 @@ static void sas_unregister_ex_tree(struct domain_device *dev) | |||
| 1700 | } | 1734 | } |
| 1701 | 1735 | ||
| 1702 | static void sas_unregister_devs_sas_addr(struct domain_device *parent, | 1736 | static void sas_unregister_devs_sas_addr(struct domain_device *parent, |
| 1703 | int phy_id) | 1737 | int phy_id, bool last) |
| 1704 | { | 1738 | { |
| 1705 | struct expander_device *ex_dev = &parent->ex_dev; | 1739 | struct expander_device *ex_dev = &parent->ex_dev; |
| 1706 | struct ex_phy *phy = &ex_dev->ex_phy[phy_id]; | 1740 | struct ex_phy *phy = &ex_dev->ex_phy[phy_id]; |
| 1707 | struct domain_device *child, *n; | 1741 | struct domain_device *child, *n; |
| 1708 | 1742 | if (last) { | |
| 1709 | list_for_each_entry_safe(child, n, &ex_dev->children, siblings) { | 1743 | list_for_each_entry_safe(child, n, |
| 1710 | if (SAS_ADDR(child->sas_addr) == | 1744 | &ex_dev->children, siblings) { |
| 1711 | SAS_ADDR(phy->attached_sas_addr)) { | 1745 | if (SAS_ADDR(child->sas_addr) == |
| 1712 | if (child->dev_type == EDGE_DEV || | 1746 | SAS_ADDR(phy->attached_sas_addr)) { |
| 1713 | child->dev_type == FANOUT_DEV) | 1747 | if (child->dev_type == EDGE_DEV || |
| 1714 | sas_unregister_ex_tree(child); | 1748 | child->dev_type == FANOUT_DEV) |
| 1715 | else | 1749 | sas_unregister_ex_tree(child); |
| 1716 | sas_unregister_dev(child); | 1750 | else |
| 1717 | break; | 1751 | sas_unregister_dev(child); |
| 1752 | break; | ||
| 1753 | } | ||
| 1718 | } | 1754 | } |
| 1755 | sas_disable_routing(parent, phy->attached_sas_addr); | ||
| 1719 | } | 1756 | } |
| 1720 | sas_disable_routing(parent, phy->attached_sas_addr); | ||
| 1721 | memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); | 1757 | memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); |
| 1722 | sas_port_delete_phy(phy->port, phy->phy); | 1758 | sas_port_delete_phy(phy->port, phy->phy); |
| 1723 | if (phy->port->num_phys == 0) | 1759 | if (phy->port->num_phys == 0) |
| @@ -1770,15 +1806,31 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) | |||
| 1770 | { | 1806 | { |
| 1771 | struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id]; | 1807 | struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id]; |
| 1772 | struct domain_device *child; | 1808 | struct domain_device *child; |
| 1773 | int res; | 1809 | bool found = false; |
| 1810 | int res, i; | ||
| 1774 | 1811 | ||
| 1775 | SAS_DPRINTK("ex %016llx phy%d new device attached\n", | 1812 | SAS_DPRINTK("ex %016llx phy%d new device attached\n", |
| 1776 | SAS_ADDR(dev->sas_addr), phy_id); | 1813 | SAS_ADDR(dev->sas_addr), phy_id); |
| 1777 | res = sas_ex_phy_discover(dev, phy_id); | 1814 | res = sas_ex_phy_discover(dev, phy_id); |
| 1778 | if (res) | 1815 | if (res) |
| 1779 | goto out; | 1816 | goto out; |
| 1817 | /* to support the wide port inserted */ | ||
| 1818 | for (i = 0; i < dev->ex_dev.num_phys; i++) { | ||
| 1819 | struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i]; | ||
| 1820 | if (i == phy_id) | ||
| 1821 | continue; | ||
| 1822 | if (SAS_ADDR(ex_phy_temp->attached_sas_addr) == | ||
| 1823 | SAS_ADDR(ex_phy->attached_sas_addr)) { | ||
| 1824 | found = true; | ||
| 1825 | break; | ||
| 1826 | } | ||
| 1827 | } | ||
| 1828 | if (found) { | ||
| 1829 | sas_ex_join_wide_port(dev, phy_id); | ||
| 1830 | return 0; | ||
| 1831 | } | ||
| 1780 | res = sas_ex_discover_devices(dev, phy_id); | 1832 | res = sas_ex_discover_devices(dev, phy_id); |
| 1781 | if (res) | 1833 | if (!res) |
| 1782 | goto out; | 1834 | goto out; |
| 1783 | list_for_each_entry(child, &dev->ex_dev.children, siblings) { | 1835 | list_for_each_entry(child, &dev->ex_dev.children, siblings) { |
| 1784 | if (SAS_ADDR(child->sas_addr) == | 1836 | if (SAS_ADDR(child->sas_addr) == |
| @@ -1793,7 +1845,7 @@ out: | |||
| 1793 | return res; | 1845 | return res; |
| 1794 | } | 1846 | } |
| 1795 | 1847 | ||
| 1796 | static int sas_rediscover_dev(struct domain_device *dev, int phy_id) | 1848 | static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) |
| 1797 | { | 1849 | { |
| 1798 | struct expander_device *ex = &dev->ex_dev; | 1850 | struct expander_device *ex = &dev->ex_dev; |
| 1799 | struct ex_phy *phy = &ex->ex_phy[phy_id]; | 1851 | struct ex_phy *phy = &ex->ex_phy[phy_id]; |
| @@ -1804,11 +1856,11 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id) | |||
| 1804 | switch (res) { | 1856 | switch (res) { |
| 1805 | case SMP_RESP_NO_PHY: | 1857 | case SMP_RESP_NO_PHY: |
| 1806 | phy->phy_state = PHY_NOT_PRESENT; | 1858 | phy->phy_state = PHY_NOT_PRESENT; |
| 1807 | sas_unregister_devs_sas_addr(dev, phy_id); | 1859 | sas_unregister_devs_sas_addr(dev, phy_id, last); |
| 1808 | goto out; break; | 1860 | goto out; break; |
| 1809 | case SMP_RESP_PHY_VACANT: | 1861 | case SMP_RESP_PHY_VACANT: |
| 1810 | phy->phy_state = PHY_VACANT; | 1862 | phy->phy_state = PHY_VACANT; |
| 1811 | sas_unregister_devs_sas_addr(dev, phy_id); | 1863 | sas_unregister_devs_sas_addr(dev, phy_id, last); |
| 1812 | goto out; break; | 1864 | goto out; break; |
| 1813 | case SMP_RESP_FUNC_ACC: | 1865 | case SMP_RESP_FUNC_ACC: |
| 1814 | break; | 1866 | break; |
| @@ -1816,7 +1868,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id) | |||
| 1816 | 1868 | ||
| 1817 | if (SAS_ADDR(attached_sas_addr) == 0) { | 1869 | if (SAS_ADDR(attached_sas_addr) == 0) { |
| 1818 | phy->phy_state = PHY_EMPTY; | 1870 | phy->phy_state = PHY_EMPTY; |
| 1819 | sas_unregister_devs_sas_addr(dev, phy_id); | 1871 | sas_unregister_devs_sas_addr(dev, phy_id, last); |
| 1820 | } else if (SAS_ADDR(attached_sas_addr) == | 1872 | } else if (SAS_ADDR(attached_sas_addr) == |
| 1821 | SAS_ADDR(phy->attached_sas_addr)) { | 1873 | SAS_ADDR(phy->attached_sas_addr)) { |
| 1822 | SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter\n", | 1874 | SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter\n", |
| @@ -1828,12 +1880,27 @@ out: | |||
| 1828 | return res; | 1880 | return res; |
| 1829 | } | 1881 | } |
| 1830 | 1882 | ||
| 1883 | /** | ||
| 1884 | * sas_rediscover - revalidate the domain. | ||
| 1885 | * @dev:domain device to be detect. | ||
| 1886 | * @phy_id: the phy id will be detected. | ||
| 1887 | * | ||
| 1888 | * NOTE: this process _must_ quit (return) as soon as any connection | ||
| 1889 | * errors are encountered. Connection recovery is done elsewhere. | ||
| 1890 | * Discover process only interrogates devices in order to discover the | ||
| 1891 | * domain.For plugging out, we un-register the device only when it is | ||
| 1892 | * the last phy in the port, for other phys in this port, we just delete it | ||
| 1893 | * from the port.For inserting, we do discovery when it is the | ||
| 1894 | * first phy,for other phys in this port, we add it to the port to | ||
| 1895 | * forming the wide-port. | ||
| 1896 | */ | ||
| 1831 | static int sas_rediscover(struct domain_device *dev, const int phy_id) | 1897 | static int sas_rediscover(struct domain_device *dev, const int phy_id) |
| 1832 | { | 1898 | { |
| 1833 | struct expander_device *ex = &dev->ex_dev; | 1899 | struct expander_device *ex = &dev->ex_dev; |
| 1834 | struct ex_phy *changed_phy = &ex->ex_phy[phy_id]; | 1900 | struct ex_phy *changed_phy = &ex->ex_phy[phy_id]; |
| 1835 | int res = 0; | 1901 | int res = 0; |
| 1836 | int i; | 1902 | int i; |
| 1903 | bool last = true; /* is this the last phy of the port */ | ||
| 1837 | 1904 | ||
| 1838 | SAS_DPRINTK("ex %016llx phy%d originated BROADCAST(CHANGE)\n", | 1905 | SAS_DPRINTK("ex %016llx phy%d originated BROADCAST(CHANGE)\n", |
| 1839 | SAS_ADDR(dev->sas_addr), phy_id); | 1906 | SAS_ADDR(dev->sas_addr), phy_id); |
| @@ -1848,13 +1915,13 @@ static int sas_rediscover(struct domain_device *dev, const int phy_id) | |||
| 1848 | SAS_ADDR(changed_phy->attached_sas_addr)) { | 1915 | SAS_ADDR(changed_phy->attached_sas_addr)) { |
| 1849 | SAS_DPRINTK("phy%d part of wide port with " | 1916 | SAS_DPRINTK("phy%d part of wide port with " |
| 1850 | "phy%d\n", phy_id, i); | 1917 | "phy%d\n", phy_id, i); |
| 1851 | goto out; | 1918 | last = false; |
| 1919 | break; | ||
| 1852 | } | 1920 | } |
| 1853 | } | 1921 | } |
| 1854 | res = sas_rediscover_dev(dev, phy_id); | 1922 | res = sas_rediscover_dev(dev, phy_id, last); |
| 1855 | } else | 1923 | } else |
| 1856 | res = sas_discover_new(dev, phy_id); | 1924 | res = sas_discover_new(dev, phy_id); |
| 1857 | out: | ||
| 1858 | return res; | 1925 | return res; |
| 1859 | } | 1926 | } |
| 1860 | 1927 | ||
| @@ -1881,7 +1948,7 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) | |||
| 1881 | 1948 | ||
| 1882 | do { | 1949 | do { |
| 1883 | phy_id = -1; | 1950 | phy_id = -1; |
| 1884 | res = sas_find_bcast_phy(dev, &phy_id, i); | 1951 | res = sas_find_bcast_phy(dev, &phy_id, i, true); |
| 1885 | if (phy_id == -1) | 1952 | if (phy_id == -1) |
| 1886 | break; | 1953 | break; |
| 1887 | res = sas_rediscover(dev, phy_id); | 1954 | res = sas_rediscover(dev, phy_id); |
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index e6ac59c023f1..fe8b74c706d2 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c | |||
| @@ -56,7 +56,7 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
| 56 | } | 56 | } |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | /* find a port */ | 59 | /* see if the phy should be part of a wide port */ |
| 60 | spin_lock_irqsave(&sas_ha->phy_port_lock, flags); | 60 | spin_lock_irqsave(&sas_ha->phy_port_lock, flags); |
| 61 | for (i = 0; i < sas_ha->num_phys; i++) { | 61 | for (i = 0; i < sas_ha->num_phys; i++) { |
| 62 | port = sas_ha->sas_port[i]; | 62 | port = sas_ha->sas_port[i]; |
| @@ -69,12 +69,23 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
| 69 | SAS_DPRINTK("phy%d matched wide port%d\n", phy->id, | 69 | SAS_DPRINTK("phy%d matched wide port%d\n", phy->id, |
| 70 | port->id); | 70 | port->id); |
| 71 | break; | 71 | break; |
| 72 | } else if (*(u64 *) port->sas_addr == 0 && port->num_phys==0) { | ||
| 73 | memcpy(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE); | ||
| 74 | break; | ||
| 75 | } | 72 | } |
| 76 | spin_unlock(&port->phy_list_lock); | 73 | spin_unlock(&port->phy_list_lock); |
| 77 | } | 74 | } |
| 75 | /* The phy does not match any existing port, create a new one */ | ||
| 76 | if (i == sas_ha->num_phys) { | ||
| 77 | for (i = 0; i < sas_ha->num_phys; i++) { | ||
| 78 | port = sas_ha->sas_port[i]; | ||
| 79 | spin_lock(&port->phy_list_lock); | ||
| 80 | if (*(u64 *)port->sas_addr == 0 | ||
| 81 | && port->num_phys == 0) { | ||
| 82 | memcpy(port->sas_addr, phy->sas_addr, | ||
| 83 | SAS_ADDR_SIZE); | ||
| 84 | break; | ||
| 85 | } | ||
| 86 | spin_unlock(&port->phy_list_lock); | ||
| 87 | } | ||
| 88 | } | ||
| 78 | 89 | ||
| 79 | if (i >= sas_ha->num_phys) { | 90 | if (i >= sas_ha->num_phys) { |
| 80 | printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n", | 91 | printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n", |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index f3da592f7bcc..35a13867495e 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
| @@ -119,6 +119,64 @@ _base_fault_reset_work(struct work_struct *work) | |||
| 119 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 119 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | /** | ||
| 123 | * mpt2sas_base_start_watchdog - start the fault_reset_work_q | ||
| 124 | * @ioc: pointer to scsi command object | ||
| 125 | * Context: sleep. | ||
| 126 | * | ||
| 127 | * Return nothing. | ||
| 128 | */ | ||
| 129 | void | ||
| 130 | mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc) | ||
| 131 | { | ||
| 132 | unsigned long flags; | ||
| 133 | |||
| 134 | if (ioc->fault_reset_work_q) | ||
| 135 | return; | ||
| 136 | |||
| 137 | /* initialize fault polling */ | ||
| 138 | INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work); | ||
| 139 | snprintf(ioc->fault_reset_work_q_name, | ||
| 140 | sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id); | ||
| 141 | ioc->fault_reset_work_q = | ||
| 142 | create_singlethread_workqueue(ioc->fault_reset_work_q_name); | ||
| 143 | if (!ioc->fault_reset_work_q) { | ||
| 144 | printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n", | ||
| 145 | ioc->name, __func__, __LINE__); | ||
| 146 | return; | ||
| 147 | } | ||
| 148 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | ||
| 149 | if (ioc->fault_reset_work_q) | ||
| 150 | queue_delayed_work(ioc->fault_reset_work_q, | ||
| 151 | &ioc->fault_reset_work, | ||
| 152 | msecs_to_jiffies(FAULT_POLLING_INTERVAL)); | ||
| 153 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | ||
| 154 | } | ||
| 155 | |||
| 156 | /** | ||
| 157 | * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q | ||
| 158 | * @ioc: pointer to scsi command object | ||
| 159 | * Context: sleep. | ||
| 160 | * | ||
| 161 | * Return nothing. | ||
| 162 | */ | ||
| 163 | void | ||
| 164 | mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc) | ||
| 165 | { | ||
| 166 | unsigned long flags; | ||
| 167 | struct workqueue_struct *wq; | ||
| 168 | |||
| 169 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | ||
| 170 | wq = ioc->fault_reset_work_q; | ||
| 171 | ioc->fault_reset_work_q = NULL; | ||
| 172 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | ||
| 173 | if (wq) { | ||
| 174 | if (!cancel_delayed_work(&ioc->fault_reset_work)) | ||
| 175 | flush_workqueue(wq); | ||
| 176 | destroy_workqueue(wq); | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 122 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 180 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
| 123 | /** | 181 | /** |
| 124 | * _base_sas_ioc_info - verbose translation of the ioc status | 182 | * _base_sas_ioc_info - verbose translation of the ioc status |
| @@ -440,6 +498,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info) | |||
| 440 | if (sas_loginfo.dw.bus_type != 3 /*SAS*/) | 498 | if (sas_loginfo.dw.bus_type != 3 /*SAS*/) |
| 441 | return; | 499 | return; |
| 442 | 500 | ||
| 501 | /* each nexus loss loginfo */ | ||
| 502 | if (log_info == 0x31170000) | ||
| 503 | return; | ||
| 504 | |||
| 443 | /* eat the loginfos associated with task aborts */ | 505 | /* eat the loginfos associated with task aborts */ |
| 444 | if (ioc->ignore_loginfos && (log_info == 30050000 || log_info == | 506 | if (ioc->ignore_loginfos && (log_info == 30050000 || log_info == |
| 445 | 0x31140000 || log_info == 0x31130000)) | 507 | 0x31140000 || log_info == 0x31130000)) |
| @@ -1109,7 +1171,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
| 1109 | } | 1171 | } |
| 1110 | } | 1172 | } |
| 1111 | 1173 | ||
| 1112 | pci_set_drvdata(pdev, ioc->shost); | ||
| 1113 | _base_mask_interrupts(ioc); | 1174 | _base_mask_interrupts(ioc); |
| 1114 | r = _base_enable_msix(ioc); | 1175 | r = _base_enable_msix(ioc); |
| 1115 | if (r) | 1176 | if (r) |
| @@ -1132,7 +1193,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
| 1132 | ioc->pci_irq = -1; | 1193 | ioc->pci_irq = -1; |
| 1133 | pci_release_selected_regions(ioc->pdev, ioc->bars); | 1194 | pci_release_selected_regions(ioc->pdev, ioc->bars); |
| 1134 | pci_disable_device(pdev); | 1195 | pci_disable_device(pdev); |
| 1135 | pci_set_drvdata(pdev, NULL); | ||
| 1136 | return r; | 1196 | return r; |
| 1137 | } | 1197 | } |
| 1138 | 1198 | ||
| @@ -3191,7 +3251,6 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc) | |||
| 3191 | ioc->chip_phys = 0; | 3251 | ioc->chip_phys = 0; |
| 3192 | pci_release_selected_regions(ioc->pdev, ioc->bars); | 3252 | pci_release_selected_regions(ioc->pdev, ioc->bars); |
| 3193 | pci_disable_device(pdev); | 3253 | pci_disable_device(pdev); |
| 3194 | pci_set_drvdata(pdev, NULL); | ||
| 3195 | return; | 3254 | return; |
| 3196 | } | 3255 | } |
| 3197 | 3256 | ||
| @@ -3205,7 +3264,6 @@ int | |||
| 3205 | mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | 3264 | mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) |
| 3206 | { | 3265 | { |
| 3207 | int r, i; | 3266 | int r, i; |
| 3208 | unsigned long flags; | ||
| 3209 | 3267 | ||
| 3210 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3268 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, |
| 3211 | __func__)); | 3269 | __func__)); |
| @@ -3214,6 +3272,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 3214 | if (r) | 3272 | if (r) |
| 3215 | return r; | 3273 | return r; |
| 3216 | 3274 | ||
| 3275 | pci_set_drvdata(ioc->pdev, ioc->shost); | ||
| 3217 | r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); | 3276 | r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); |
| 3218 | if (r) | 3277 | if (r) |
| 3219 | goto out_free_resources; | 3278 | goto out_free_resources; |
| @@ -3288,23 +3347,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 3288 | if (r) | 3347 | if (r) |
| 3289 | goto out_free_resources; | 3348 | goto out_free_resources; |
| 3290 | 3349 | ||
| 3291 | /* initialize fault polling */ | 3350 | mpt2sas_base_start_watchdog(ioc); |
| 3292 | INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work); | ||
| 3293 | snprintf(ioc->fault_reset_work_q_name, | ||
| 3294 | sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id); | ||
| 3295 | ioc->fault_reset_work_q = | ||
| 3296 | create_singlethread_workqueue(ioc->fault_reset_work_q_name); | ||
| 3297 | if (!ioc->fault_reset_work_q) { | ||
| 3298 | printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n", | ||
| 3299 | ioc->name, __func__, __LINE__); | ||
| 3300 | goto out_free_resources; | ||
| 3301 | } | ||
| 3302 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | ||
| 3303 | if (ioc->fault_reset_work_q) | ||
| 3304 | queue_delayed_work(ioc->fault_reset_work_q, | ||
| 3305 | &ioc->fault_reset_work, | ||
| 3306 | msecs_to_jiffies(FAULT_POLLING_INTERVAL)); | ||
| 3307 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | ||
| 3308 | return 0; | 3351 | return 0; |
| 3309 | 3352 | ||
| 3310 | out_free_resources: | 3353 | out_free_resources: |
| @@ -3312,6 +3355,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 3312 | ioc->remove_host = 1; | 3355 | ioc->remove_host = 1; |
| 3313 | mpt2sas_base_free_resources(ioc); | 3356 | mpt2sas_base_free_resources(ioc); |
| 3314 | _base_release_memory_pools(ioc); | 3357 | _base_release_memory_pools(ioc); |
| 3358 | pci_set_drvdata(ioc->pdev, NULL); | ||
| 3315 | kfree(ioc->tm_cmds.reply); | 3359 | kfree(ioc->tm_cmds.reply); |
| 3316 | kfree(ioc->transport_cmds.reply); | 3360 | kfree(ioc->transport_cmds.reply); |
| 3317 | kfree(ioc->config_cmds.reply); | 3361 | kfree(ioc->config_cmds.reply); |
| @@ -3337,22 +3381,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 3337 | void | 3381 | void |
| 3338 | mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) | 3382 | mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) |
| 3339 | { | 3383 | { |
| 3340 | unsigned long flags; | ||
| 3341 | struct workqueue_struct *wq; | ||
| 3342 | 3384 | ||
| 3343 | dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3385 | dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, |
| 3344 | __func__)); | 3386 | __func__)); |
| 3345 | 3387 | ||
| 3346 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | 3388 | mpt2sas_base_stop_watchdog(ioc); |
| 3347 | wq = ioc->fault_reset_work_q; | ||
| 3348 | ioc->fault_reset_work_q = NULL; | ||
| 3349 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | ||
| 3350 | if (!cancel_delayed_work(&ioc->fault_reset_work)) | ||
| 3351 | flush_workqueue(wq); | ||
| 3352 | destroy_workqueue(wq); | ||
| 3353 | |||
| 3354 | mpt2sas_base_free_resources(ioc); | 3389 | mpt2sas_base_free_resources(ioc); |
| 3355 | _base_release_memory_pools(ioc); | 3390 | _base_release_memory_pools(ioc); |
| 3391 | pci_set_drvdata(ioc->pdev, NULL); | ||
| 3356 | kfree(ioc->pfacts); | 3392 | kfree(ioc->pfacts); |
| 3357 | kfree(ioc->ctl_cmds.reply); | 3393 | kfree(ioc->ctl_cmds.reply); |
| 3358 | kfree(ioc->base_cmds.reply); | 3394 | kfree(ioc->base_cmds.reply); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 286c185fa9e4..acdcff150a35 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
| @@ -69,10 +69,10 @@ | |||
| 69 | #define MPT2SAS_DRIVER_NAME "mpt2sas" | 69 | #define MPT2SAS_DRIVER_NAME "mpt2sas" |
| 70 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" | 70 | #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" |
| 71 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" | 71 | #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" |
| 72 | #define MPT2SAS_DRIVER_VERSION "01.100.03.00" | 72 | #define MPT2SAS_DRIVER_VERSION "01.100.04.00" |
| 73 | #define MPT2SAS_MAJOR_VERSION 01 | 73 | #define MPT2SAS_MAJOR_VERSION 01 |
| 74 | #define MPT2SAS_MINOR_VERSION 100 | 74 | #define MPT2SAS_MINOR_VERSION 100 |
| 75 | #define MPT2SAS_BUILD_VERSION 03 | 75 | #define MPT2SAS_BUILD_VERSION 04 |
| 76 | #define MPT2SAS_RELEASE_VERSION 00 | 76 | #define MPT2SAS_RELEASE_VERSION 00 |
| 77 | 77 | ||
| 78 | /* | 78 | /* |
| @@ -673,6 +673,8 @@ typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, | |||
| 673 | 673 | ||
| 674 | /* base shared API */ | 674 | /* base shared API */ |
| 675 | extern struct list_head mpt2sas_ioc_list; | 675 | extern struct list_head mpt2sas_ioc_list; |
| 676 | void mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc); | ||
| 677 | void mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc); | ||
| 676 | 678 | ||
| 677 | int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc); | 679 | int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc); |
| 678 | void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc); | 680 | void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 58cfb97846f7..6ddee161beb3 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c | |||
| @@ -236,17 +236,25 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
| 236 | Mpi2ConfigRequest_t *config_request; | 236 | Mpi2ConfigRequest_t *config_request; |
| 237 | int r; | 237 | int r; |
| 238 | u8 retry_count; | 238 | u8 retry_count; |
| 239 | u8 issue_reset; | 239 | u8 issue_host_reset = 0; |
| 240 | u16 wait_state_count; | 240 | u16 wait_state_count; |
| 241 | 241 | ||
| 242 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 242 | if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) { | 243 | if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) { |
| 243 | printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n", | 244 | printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n", |
| 244 | ioc->name, __func__); | 245 | ioc->name, __func__); |
| 246 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 245 | return -EAGAIN; | 247 | return -EAGAIN; |
| 246 | } | 248 | } |
| 247 | retry_count = 0; | 249 | retry_count = 0; |
| 248 | 250 | ||
| 249 | retry_config: | 251 | retry_config: |
| 252 | if (retry_count) { | ||
| 253 | if (retry_count > 2) /* attempt only 2 retries */ | ||
| 254 | return -EFAULT; | ||
| 255 | printk(MPT2SAS_INFO_FMT "%s: attempting retry (%d)\n", | ||
| 256 | ioc->name, __func__, retry_count); | ||
| 257 | } | ||
| 250 | wait_state_count = 0; | 258 | wait_state_count = 0; |
| 251 | ioc_state = mpt2sas_base_get_iocstate(ioc, 1); | 259 | ioc_state = mpt2sas_base_get_iocstate(ioc, 1); |
| 252 | while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { | 260 | while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { |
| @@ -254,8 +262,8 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
| 254 | printk(MPT2SAS_ERR_FMT | 262 | printk(MPT2SAS_ERR_FMT |
| 255 | "%s: failed due to ioc not operational\n", | 263 | "%s: failed due to ioc not operational\n", |
| 256 | ioc->name, __func__); | 264 | ioc->name, __func__); |
| 257 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; | 265 | r = -EFAULT; |
| 258 | return -EFAULT; | 266 | goto out; |
| 259 | } | 267 | } |
| 260 | ssleep(1); | 268 | ssleep(1); |
| 261 | ioc_state = mpt2sas_base_get_iocstate(ioc, 1); | 269 | ioc_state = mpt2sas_base_get_iocstate(ioc, 1); |
| @@ -271,8 +279,8 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
| 271 | if (!smid) { | 279 | if (!smid) { |
| 272 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", | 280 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", |
| 273 | ioc->name, __func__); | 281 | ioc->name, __func__); |
| 274 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; | 282 | r = -EAGAIN; |
| 275 | return -EAGAIN; | 283 | goto out; |
| 276 | } | 284 | } |
| 277 | 285 | ||
| 278 | r = 0; | 286 | r = 0; |
| @@ -292,9 +300,15 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
| 292 | ioc->name, __func__); | 300 | ioc->name, __func__); |
| 293 | _debug_dump_mf(mpi_request, | 301 | _debug_dump_mf(mpi_request, |
| 294 | sizeof(Mpi2ConfigRequest_t)/4); | 302 | sizeof(Mpi2ConfigRequest_t)/4); |
| 295 | if (!(ioc->config_cmds.status & MPT2_CMD_RESET)) | 303 | retry_count++; |
| 296 | issue_reset = 1; | 304 | if (ioc->config_cmds.smid == smid) |
| 297 | goto issue_host_reset; | 305 | mpt2sas_base_free_smid(ioc, smid); |
| 306 | if ((ioc->shost_recovery) || | ||
| 307 | (ioc->config_cmds.status & MPT2_CMD_RESET)) | ||
| 308 | goto retry_config; | ||
| 309 | issue_host_reset = 1; | ||
| 310 | r = -EFAULT; | ||
| 311 | goto out; | ||
| 298 | } | 312 | } |
| 299 | if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID) | 313 | if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID) |
| 300 | memcpy(mpi_reply, ioc->config_cmds.reply, | 314 | memcpy(mpi_reply, ioc->config_cmds.reply, |
| @@ -302,21 +316,13 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
| 302 | if (retry_count) | 316 | if (retry_count) |
| 303 | printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n", | 317 | printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n", |
| 304 | ioc->name, __func__); | 318 | ioc->name, __func__); |
| 319 | out: | ||
| 305 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; | 320 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; |
| 306 | return r; | 321 | mutex_unlock(&ioc->config_cmds.mutex); |
| 307 | 322 | if (issue_host_reset) | |
| 308 | issue_host_reset: | ||
| 309 | if (issue_reset) | ||
| 310 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, | 323 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, |
| 311 | FORCE_BIG_HAMMER); | 324 | FORCE_BIG_HAMMER); |
| 312 | ioc->config_cmds.status = MPT2_CMD_NOT_USED; | 325 | return r; |
| 313 | if (!retry_count) { | ||
| 314 | printk(MPT2SAS_INFO_FMT "%s: attempting retry\n", | ||
| 315 | ioc->name, __func__); | ||
| 316 | retry_count++; | ||
| 317 | goto retry_config; | ||
| 318 | } | ||
| 319 | return -EFAULT; | ||
| 320 | } | 326 | } |
| 321 | 327 | ||
| 322 | /** | 328 | /** |
| @@ -375,7 +381,6 @@ mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
| 375 | int r; | 381 | int r; |
| 376 | struct config_request mem; | 382 | struct config_request mem; |
| 377 | 383 | ||
| 378 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 379 | memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t)); | 384 | memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t)); |
| 380 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 385 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 381 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 386 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -417,7 +422,6 @@ mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
| 417 | _config_free_config_dma_memory(ioc, &mem); | 422 | _config_free_config_dma_memory(ioc, &mem); |
| 418 | 423 | ||
| 419 | out: | 424 | out: |
| 420 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 421 | return r; | 425 | return r; |
| 422 | } | 426 | } |
| 423 | 427 | ||
| @@ -438,7 +442,6 @@ mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc, | |||
| 438 | int r; | 442 | int r; |
| 439 | struct config_request mem; | 443 | struct config_request mem; |
| 440 | 444 | ||
| 441 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 442 | memset(config_page, 0, sizeof(Mpi2BiosPage2_t)); | 445 | memset(config_page, 0, sizeof(Mpi2BiosPage2_t)); |
| 443 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 446 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 444 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 447 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -480,7 +483,6 @@ mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc, | |||
| 480 | _config_free_config_dma_memory(ioc, &mem); | 483 | _config_free_config_dma_memory(ioc, &mem); |
| 481 | 484 | ||
| 482 | out: | 485 | out: |
| 483 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 484 | return r; | 486 | return r; |
| 485 | } | 487 | } |
| 486 | 488 | ||
| @@ -501,7 +503,6 @@ mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 501 | int r; | 503 | int r; |
| 502 | struct config_request mem; | 504 | struct config_request mem; |
| 503 | 505 | ||
| 504 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 505 | memset(config_page, 0, sizeof(Mpi2BiosPage3_t)); | 506 | memset(config_page, 0, sizeof(Mpi2BiosPage3_t)); |
| 506 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 507 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 507 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 508 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -543,7 +544,6 @@ mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 543 | _config_free_config_dma_memory(ioc, &mem); | 544 | _config_free_config_dma_memory(ioc, &mem); |
| 544 | 545 | ||
| 545 | out: | 546 | out: |
| 546 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 547 | return r; | 547 | return r; |
| 548 | } | 548 | } |
| 549 | 549 | ||
| @@ -564,7 +564,6 @@ mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
| 564 | int r; | 564 | int r; |
| 565 | struct config_request mem; | 565 | struct config_request mem; |
| 566 | 566 | ||
| 567 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 568 | memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t)); | 567 | memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t)); |
| 569 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 568 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 570 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 569 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -606,7 +605,6 @@ mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
| 606 | _config_free_config_dma_memory(ioc, &mem); | 605 | _config_free_config_dma_memory(ioc, &mem); |
| 607 | 606 | ||
| 608 | out: | 607 | out: |
| 609 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 610 | return r; | 608 | return r; |
| 611 | } | 609 | } |
| 612 | 610 | ||
| @@ -627,7 +625,6 @@ mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
| 627 | int r; | 625 | int r; |
| 628 | struct config_request mem; | 626 | struct config_request mem; |
| 629 | 627 | ||
| 630 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 631 | memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t)); | 628 | memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t)); |
| 632 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 629 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 633 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 630 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -669,7 +666,6 @@ mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
| 669 | _config_free_config_dma_memory(ioc, &mem); | 666 | _config_free_config_dma_memory(ioc, &mem); |
| 670 | 667 | ||
| 671 | out: | 668 | out: |
| 672 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 673 | return r; | 669 | return r; |
| 674 | } | 670 | } |
| 675 | 671 | ||
| @@ -690,7 +686,6 @@ mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
| 690 | int r; | 686 | int r; |
| 691 | struct config_request mem; | 687 | struct config_request mem; |
| 692 | 688 | ||
| 693 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 694 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 689 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 695 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 690 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| 696 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | 691 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; |
| @@ -732,7 +727,6 @@ mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
| 732 | _config_free_config_dma_memory(ioc, &mem); | 727 | _config_free_config_dma_memory(ioc, &mem); |
| 733 | 728 | ||
| 734 | out: | 729 | out: |
| 735 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 736 | return r; | 730 | return r; |
| 737 | } | 731 | } |
| 738 | 732 | ||
| @@ -753,7 +747,6 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, | |||
| 753 | int r; | 747 | int r; |
| 754 | struct config_request mem; | 748 | struct config_request mem; |
| 755 | 749 | ||
| 756 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 757 | memset(config_page, 0, sizeof(Mpi2IOCPage8_t)); | 750 | memset(config_page, 0, sizeof(Mpi2IOCPage8_t)); |
| 758 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 751 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 759 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 752 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -795,7 +788,6 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, | |||
| 795 | _config_free_config_dma_memory(ioc, &mem); | 788 | _config_free_config_dma_memory(ioc, &mem); |
| 796 | 789 | ||
| 797 | out: | 790 | out: |
| 798 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 799 | return r; | 791 | return r; |
| 800 | } | 792 | } |
| 801 | 793 | ||
| @@ -818,7 +810,6 @@ mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 818 | int r; | 810 | int r; |
| 819 | struct config_request mem; | 811 | struct config_request mem; |
| 820 | 812 | ||
| 821 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 822 | memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t)); | 813 | memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t)); |
| 823 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 814 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 824 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 815 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -863,7 +854,6 @@ mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 863 | _config_free_config_dma_memory(ioc, &mem); | 854 | _config_free_config_dma_memory(ioc, &mem); |
| 864 | 855 | ||
| 865 | out: | 856 | out: |
| 866 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 867 | return r; | 857 | return r; |
| 868 | } | 858 | } |
| 869 | 859 | ||
| @@ -886,7 +876,6 @@ mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 886 | int r; | 876 | int r; |
| 887 | struct config_request mem; | 877 | struct config_request mem; |
| 888 | 878 | ||
| 889 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 890 | memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t)); | 879 | memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t)); |
| 891 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 880 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 892 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 881 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -931,7 +920,6 @@ mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 931 | _config_free_config_dma_memory(ioc, &mem); | 920 | _config_free_config_dma_memory(ioc, &mem); |
| 932 | 921 | ||
| 933 | out: | 922 | out: |
| 934 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 935 | return r; | 923 | return r; |
| 936 | } | 924 | } |
| 937 | 925 | ||
| @@ -953,7 +941,6 @@ mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys) | |||
| 953 | Mpi2ConfigReply_t mpi_reply; | 941 | Mpi2ConfigReply_t mpi_reply; |
| 954 | Mpi2SasIOUnitPage0_t config_page; | 942 | Mpi2SasIOUnitPage0_t config_page; |
| 955 | 943 | ||
| 956 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 957 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 944 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 958 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 945 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| 959 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | 946 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; |
| @@ -1002,7 +989,6 @@ mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys) | |||
| 1002 | _config_free_config_dma_memory(ioc, &mem); | 989 | _config_free_config_dma_memory(ioc, &mem); |
| 1003 | 990 | ||
| 1004 | out: | 991 | out: |
| 1005 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1006 | return r; | 992 | return r; |
| 1007 | } | 993 | } |
| 1008 | 994 | ||
| @@ -1026,8 +1012,6 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1026 | Mpi2ConfigRequest_t mpi_request; | 1012 | Mpi2ConfigRequest_t mpi_request; |
| 1027 | int r; | 1013 | int r; |
| 1028 | struct config_request mem; | 1014 | struct config_request mem; |
| 1029 | |||
| 1030 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1031 | memset(config_page, 0, sz); | 1015 | memset(config_page, 0, sz); |
| 1032 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1016 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1033 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1017 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1070,7 +1054,6 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1070 | _config_free_config_dma_memory(ioc, &mem); | 1054 | _config_free_config_dma_memory(ioc, &mem); |
| 1071 | 1055 | ||
| 1072 | out: | 1056 | out: |
| 1073 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1074 | return r; | 1057 | return r; |
| 1075 | } | 1058 | } |
| 1076 | 1059 | ||
| @@ -1095,7 +1078,6 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1095 | int r; | 1078 | int r; |
| 1096 | struct config_request mem; | 1079 | struct config_request mem; |
| 1097 | 1080 | ||
| 1098 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1099 | memset(config_page, 0, sz); | 1081 | memset(config_page, 0, sz); |
| 1100 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1082 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1101 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1083 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1138,7 +1120,6 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1138 | _config_free_config_dma_memory(ioc, &mem); | 1120 | _config_free_config_dma_memory(ioc, &mem); |
| 1139 | 1121 | ||
| 1140 | out: | 1122 | out: |
| 1141 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1142 | return r; | 1123 | return r; |
| 1143 | } | 1124 | } |
| 1144 | 1125 | ||
| @@ -1161,7 +1142,6 @@ mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1161 | int r; | 1142 | int r; |
| 1162 | struct config_request mem; | 1143 | struct config_request mem; |
| 1163 | 1144 | ||
| 1164 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1165 | memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t)); | 1145 | memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t)); |
| 1166 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1146 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1167 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1147 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1206,7 +1186,6 @@ mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1206 | _config_free_config_dma_memory(ioc, &mem); | 1186 | _config_free_config_dma_memory(ioc, &mem); |
| 1207 | 1187 | ||
| 1208 | out: | 1188 | out: |
| 1209 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1210 | return r; | 1189 | return r; |
| 1211 | } | 1190 | } |
| 1212 | 1191 | ||
| @@ -1230,7 +1209,6 @@ mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1230 | int r; | 1209 | int r; |
| 1231 | struct config_request mem; | 1210 | struct config_request mem; |
| 1232 | 1211 | ||
| 1233 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1234 | memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t)); | 1212 | memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t)); |
| 1235 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1213 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1236 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1214 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1277,7 +1255,6 @@ mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1277 | _config_free_config_dma_memory(ioc, &mem); | 1255 | _config_free_config_dma_memory(ioc, &mem); |
| 1278 | 1256 | ||
| 1279 | out: | 1257 | out: |
| 1280 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1281 | return r; | 1258 | return r; |
| 1282 | } | 1259 | } |
| 1283 | 1260 | ||
| @@ -1300,7 +1277,6 @@ mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1300 | int r; | 1277 | int r; |
| 1301 | struct config_request mem; | 1278 | struct config_request mem; |
| 1302 | 1279 | ||
| 1303 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1304 | memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t)); | 1280 | memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t)); |
| 1305 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1281 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1306 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1282 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1345,7 +1321,6 @@ mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1345 | _config_free_config_dma_memory(ioc, &mem); | 1321 | _config_free_config_dma_memory(ioc, &mem); |
| 1346 | 1322 | ||
| 1347 | out: | 1323 | out: |
| 1348 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1349 | return r; | 1324 | return r; |
| 1350 | } | 1325 | } |
| 1351 | 1326 | ||
| @@ -1367,7 +1342,6 @@ mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1367 | int r; | 1342 | int r; |
| 1368 | struct config_request mem; | 1343 | struct config_request mem; |
| 1369 | 1344 | ||
| 1370 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1371 | memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t)); | 1345 | memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t)); |
| 1372 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1346 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1373 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1347 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1413,7 +1387,6 @@ mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1413 | _config_free_config_dma_memory(ioc, &mem); | 1387 | _config_free_config_dma_memory(ioc, &mem); |
| 1414 | 1388 | ||
| 1415 | out: | 1389 | out: |
| 1416 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1417 | return r; | 1390 | return r; |
| 1418 | } | 1391 | } |
| 1419 | 1392 | ||
| @@ -1435,7 +1408,6 @@ mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1435 | int r; | 1408 | int r; |
| 1436 | struct config_request mem; | 1409 | struct config_request mem; |
| 1437 | 1410 | ||
| 1438 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1439 | memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t)); | 1411 | memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t)); |
| 1440 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1412 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1441 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1413 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1481,7 +1453,6 @@ mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1481 | _config_free_config_dma_memory(ioc, &mem); | 1453 | _config_free_config_dma_memory(ioc, &mem); |
| 1482 | 1454 | ||
| 1483 | out: | 1455 | out: |
| 1484 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1485 | return r; | 1456 | return r; |
| 1486 | } | 1457 | } |
| 1487 | 1458 | ||
| @@ -1505,7 +1476,6 @@ mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
| 1505 | int r; | 1476 | int r; |
| 1506 | struct config_request mem; | 1477 | struct config_request mem; |
| 1507 | 1478 | ||
| 1508 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1509 | memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t)); | 1479 | memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t)); |
| 1510 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1480 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1511 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1481 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1548,7 +1518,6 @@ mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc, | |||
| 1548 | _config_free_config_dma_memory(ioc, &mem); | 1518 | _config_free_config_dma_memory(ioc, &mem); |
| 1549 | 1519 | ||
| 1550 | out: | 1520 | out: |
| 1551 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1552 | return r; | 1521 | return r; |
| 1553 | } | 1522 | } |
| 1554 | 1523 | ||
| @@ -1572,7 +1541,6 @@ mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
| 1572 | struct config_request mem; | 1541 | struct config_request mem; |
| 1573 | u16 ioc_status; | 1542 | u16 ioc_status; |
| 1574 | 1543 | ||
| 1575 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1576 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1544 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1577 | *num_pds = 0; | 1545 | *num_pds = 0; |
| 1578 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1546 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1620,7 +1588,6 @@ mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
| 1620 | _config_free_config_dma_memory(ioc, &mem); | 1588 | _config_free_config_dma_memory(ioc, &mem); |
| 1621 | 1589 | ||
| 1622 | out: | 1590 | out: |
| 1623 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1624 | return r; | 1591 | return r; |
| 1625 | } | 1592 | } |
| 1626 | 1593 | ||
| @@ -1645,7 +1612,6 @@ mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
| 1645 | int r; | 1612 | int r; |
| 1646 | struct config_request mem; | 1613 | struct config_request mem; |
| 1647 | 1614 | ||
| 1648 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1649 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1615 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1650 | memset(config_page, 0, sz); | 1616 | memset(config_page, 0, sz); |
| 1651 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1617 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1687,7 +1653,6 @@ mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc, | |||
| 1687 | _config_free_config_dma_memory(ioc, &mem); | 1653 | _config_free_config_dma_memory(ioc, &mem); |
| 1688 | 1654 | ||
| 1689 | out: | 1655 | out: |
| 1690 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1691 | return r; | 1656 | return r; |
| 1692 | } | 1657 | } |
| 1693 | 1658 | ||
| @@ -1711,7 +1676,6 @@ mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1711 | int r; | 1676 | int r; |
| 1712 | struct config_request mem; | 1677 | struct config_request mem; |
| 1713 | 1678 | ||
| 1714 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1715 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1679 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1716 | memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t)); | 1680 | memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t)); |
| 1717 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1681 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1754,7 +1718,6 @@ mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
| 1754 | _config_free_config_dma_memory(ioc, &mem); | 1718 | _config_free_config_dma_memory(ioc, &mem); |
| 1755 | 1719 | ||
| 1756 | out: | 1720 | out: |
| 1757 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1758 | return r; | 1721 | return r; |
| 1759 | } | 1722 | } |
| 1760 | 1723 | ||
| @@ -1778,7 +1741,6 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle, | |||
| 1778 | struct config_request mem; | 1741 | struct config_request mem; |
| 1779 | u16 ioc_status; | 1742 | u16 ioc_status; |
| 1780 | 1743 | ||
| 1781 | mutex_lock(&ioc->config_cmds.mutex); | ||
| 1782 | *volume_handle = 0; | 1744 | *volume_handle = 0; |
| 1783 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | 1745 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); |
| 1784 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | 1746 | mpi_request.Function = MPI2_FUNCTION_CONFIG; |
| @@ -1842,7 +1804,6 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle, | |||
| 1842 | _config_free_config_dma_memory(ioc, &mem); | 1804 | _config_free_config_dma_memory(ioc, &mem); |
| 1843 | 1805 | ||
| 1844 | out: | 1806 | out: |
| 1845 | mutex_unlock(&ioc->config_cmds.mutex); | ||
| 1846 | return r; | 1807 | return r; |
| 1847 | } | 1808 | } |
| 1848 | 1809 | ||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 2a01a5f2a84d..2e9a4445596f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
| @@ -2767,6 +2767,10 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
| 2767 | char *desc_ioc_state = NULL; | 2767 | char *desc_ioc_state = NULL; |
| 2768 | char *desc_scsi_status = NULL; | 2768 | char *desc_scsi_status = NULL; |
| 2769 | char *desc_scsi_state = ioc->tmp_string; | 2769 | char *desc_scsi_state = ioc->tmp_string; |
| 2770 | u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo); | ||
| 2771 | |||
| 2772 | if (log_info == 0x31170000) | ||
| 2773 | return; | ||
| 2770 | 2774 | ||
| 2771 | switch (ioc_status) { | 2775 | switch (ioc_status) { |
| 2772 | case MPI2_IOCSTATUS_SUCCESS: | 2776 | case MPI2_IOCSTATUS_SUCCESS: |
| @@ -3426,7 +3430,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
| 3426 | __le64 sas_address; | 3430 | __le64 sas_address; |
| 3427 | int i; | 3431 | int i; |
| 3428 | unsigned long flags; | 3432 | unsigned long flags; |
| 3429 | struct _sas_port *mpt2sas_port; | 3433 | struct _sas_port *mpt2sas_port = NULL; |
| 3430 | int rc = 0; | 3434 | int rc = 0; |
| 3431 | 3435 | ||
| 3432 | if (!handle) | 3436 | if (!handle) |
| @@ -3518,12 +3522,20 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
| 3518 | &expander_pg1, i, handle))) { | 3522 | &expander_pg1, i, handle))) { |
| 3519 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 3523 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
| 3520 | ioc->name, __FILE__, __LINE__, __func__); | 3524 | ioc->name, __FILE__, __LINE__, __func__); |
| 3521 | continue; | 3525 | rc = -1; |
| 3526 | goto out_fail; | ||
| 3522 | } | 3527 | } |
| 3523 | sas_expander->phy[i].handle = handle; | 3528 | sas_expander->phy[i].handle = handle; |
| 3524 | sas_expander->phy[i].phy_id = i; | 3529 | sas_expander->phy[i].phy_id = i; |
| 3525 | mpt2sas_transport_add_expander_phy(ioc, &sas_expander->phy[i], | 3530 | |
| 3526 | expander_pg1, sas_expander->parent_dev); | 3531 | if ((mpt2sas_transport_add_expander_phy(ioc, |
| 3532 | &sas_expander->phy[i], expander_pg1, | ||
| 3533 | sas_expander->parent_dev))) { | ||
| 3534 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
| 3535 | ioc->name, __FILE__, __LINE__, __func__); | ||
| 3536 | rc = -1; | ||
| 3537 | goto out_fail; | ||
| 3538 | } | ||
| 3527 | } | 3539 | } |
| 3528 | 3540 | ||
| 3529 | if (sas_expander->enclosure_handle) { | 3541 | if (sas_expander->enclosure_handle) { |
| @@ -3540,8 +3552,9 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
| 3540 | 3552 | ||
| 3541 | out_fail: | 3553 | out_fail: |
| 3542 | 3554 | ||
| 3543 | if (sas_expander) | 3555 | if (mpt2sas_port) |
| 3544 | kfree(sas_expander->phy); | 3556 | mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, |
| 3557 | sas_expander->parent_handle); | ||
| 3545 | kfree(sas_expander); | 3558 | kfree(sas_expander); |
| 3546 | return rc; | 3559 | return rc; |
| 3547 | } | 3560 | } |
| @@ -3663,12 +3676,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
| 3663 | sas_device->hidden_raid_component = is_pd; | 3676 | sas_device->hidden_raid_component = is_pd; |
| 3664 | 3677 | ||
| 3665 | /* get enclosure_logical_id */ | 3678 | /* get enclosure_logical_id */ |
| 3666 | if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, &enclosure_pg0, | 3679 | if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0( |
| 3667 | MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, | 3680 | ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, |
| 3668 | sas_device->enclosure_handle))) { | 3681 | sas_device->enclosure_handle))) |
| 3669 | sas_device->enclosure_logical_id = | 3682 | sas_device->enclosure_logical_id = |
| 3670 | le64_to_cpu(enclosure_pg0.EnclosureLogicalID); | 3683 | le64_to_cpu(enclosure_pg0.EnclosureLogicalID); |
| 3671 | } | ||
| 3672 | 3684 | ||
| 3673 | /* get device name */ | 3685 | /* get device name */ |
| 3674 | sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); | 3686 | sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); |
| @@ -4250,12 +4262,6 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc, | |||
| 4250 | u16 handle = le16_to_cpu(element->VolDevHandle); | 4262 | u16 handle = le16_to_cpu(element->VolDevHandle); |
| 4251 | int rc; | 4263 | int rc; |
| 4252 | 4264 | ||
| 4253 | #if 0 /* RAID_HACKS */ | ||
| 4254 | if (le32_to_cpu(event_data->Flags) & | ||
| 4255 | MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) | ||
| 4256 | return; | ||
| 4257 | #endif | ||
| 4258 | |||
| 4259 | mpt2sas_config_get_volume_wwid(ioc, handle, &wwid); | 4265 | mpt2sas_config_get_volume_wwid(ioc, handle, &wwid); |
| 4260 | if (!wwid) { | 4266 | if (!wwid) { |
| 4261 | printk(MPT2SAS_ERR_FMT | 4267 | printk(MPT2SAS_ERR_FMT |
| @@ -4310,12 +4316,6 @@ _scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, | |||
| 4310 | unsigned long flags; | 4316 | unsigned long flags; |
| 4311 | struct MPT2SAS_TARGET *sas_target_priv_data; | 4317 | struct MPT2SAS_TARGET *sas_target_priv_data; |
| 4312 | 4318 | ||
| 4313 | #if 0 /* RAID_HACKS */ | ||
| 4314 | if (le32_to_cpu(event_data->Flags) & | ||
| 4315 | MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) | ||
| 4316 | return; | ||
| 4317 | #endif | ||
| 4318 | |||
| 4319 | spin_lock_irqsave(&ioc->raid_device_lock, flags); | 4319 | spin_lock_irqsave(&ioc->raid_device_lock, flags); |
| 4320 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); | 4320 | raid_device = _scsih_raid_device_find_by_handle(ioc, handle); |
| 4321 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 4321 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
| @@ -4428,14 +4428,38 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc, | |||
| 4428 | struct _sas_device *sas_device; | 4428 | struct _sas_device *sas_device; |
| 4429 | unsigned long flags; | 4429 | unsigned long flags; |
| 4430 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); | 4430 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); |
| 4431 | Mpi2ConfigReply_t mpi_reply; | ||
| 4432 | Mpi2SasDevicePage0_t sas_device_pg0; | ||
| 4433 | u32 ioc_status; | ||
| 4431 | 4434 | ||
| 4432 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4435 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
| 4433 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 4436 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); |
| 4434 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4437 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
| 4435 | if (sas_device) | 4438 | if (sas_device) { |
| 4436 | sas_device->hidden_raid_component = 1; | 4439 | sas_device->hidden_raid_component = 1; |
| 4437 | else | 4440 | return; |
| 4438 | _scsih_add_device(ioc, handle, 0, 1); | 4441 | } |
| 4442 | |||
| 4443 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, | ||
| 4444 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { | ||
| 4445 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
| 4446 | ioc->name, __FILE__, __LINE__, __func__); | ||
| 4447 | return; | ||
| 4448 | } | ||
| 4449 | |||
| 4450 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
| 4451 | MPI2_IOCSTATUS_MASK; | ||
| 4452 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
| 4453 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
| 4454 | ioc->name, __FILE__, __LINE__, __func__); | ||
| 4455 | return; | ||
| 4456 | } | ||
| 4457 | |||
| 4458 | _scsih_link_change(ioc, | ||
| 4459 | le16_to_cpu(sas_device_pg0.ParentDevHandle), | ||
| 4460 | handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | ||
| 4461 | |||
| 4462 | _scsih_add_device(ioc, handle, 0, 1); | ||
| 4439 | } | 4463 | } |
| 4440 | 4464 | ||
| 4441 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4465 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
| @@ -4535,12 +4559,15 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, | |||
| 4535 | { | 4559 | { |
| 4536 | Mpi2EventIrConfigElement_t *element; | 4560 | Mpi2EventIrConfigElement_t *element; |
| 4537 | int i; | 4561 | int i; |
| 4562 | u8 foreign_config; | ||
| 4538 | 4563 | ||
| 4539 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4564 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
| 4540 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) | 4565 | if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) |
| 4541 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); | 4566 | _scsih_sas_ir_config_change_event_debug(ioc, event_data); |
| 4542 | 4567 | ||
| 4543 | #endif | 4568 | #endif |
| 4569 | foreign_config = (le32_to_cpu(event_data->Flags) & | ||
| 4570 | MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; | ||
| 4544 | 4571 | ||
| 4545 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; | 4572 | element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; |
| 4546 | for (i = 0; i < event_data->NumElements; i++, element++) { | 4573 | for (i = 0; i < event_data->NumElements; i++, element++) { |
| @@ -4548,11 +4575,13 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, | |||
| 4548 | switch (element->ReasonCode) { | 4575 | switch (element->ReasonCode) { |
| 4549 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: | 4576 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: |
| 4550 | case MPI2_EVENT_IR_CHANGE_RC_ADDED: | 4577 | case MPI2_EVENT_IR_CHANGE_RC_ADDED: |
| 4551 | _scsih_sas_volume_add(ioc, element); | 4578 | if (!foreign_config) |
| 4579 | _scsih_sas_volume_add(ioc, element); | ||
| 4552 | break; | 4580 | break; |
| 4553 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: | 4581 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: |
| 4554 | case MPI2_EVENT_IR_CHANGE_RC_REMOVED: | 4582 | case MPI2_EVENT_IR_CHANGE_RC_REMOVED: |
| 4555 | _scsih_sas_volume_delete(ioc, element); | 4583 | if (!foreign_config) |
| 4584 | _scsih_sas_volume_delete(ioc, element); | ||
| 4556 | break; | 4585 | break; |
| 4557 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: | 4586 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: |
| 4558 | _scsih_sas_pd_hide(ioc, element); | 4587 | _scsih_sas_pd_hide(ioc, element); |
| @@ -4671,6 +4700,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, | |||
| 4671 | u32 state; | 4700 | u32 state; |
| 4672 | struct _sas_device *sas_device; | 4701 | struct _sas_device *sas_device; |
| 4673 | unsigned long flags; | 4702 | unsigned long flags; |
| 4703 | Mpi2ConfigReply_t mpi_reply; | ||
| 4704 | Mpi2SasDevicePage0_t sas_device_pg0; | ||
| 4705 | u32 ioc_status; | ||
| 4674 | 4706 | ||
| 4675 | if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) | 4707 | if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) |
| 4676 | return; | 4708 | return; |
| @@ -4687,22 +4719,40 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, | |||
| 4687 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4719 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
| 4688 | 4720 | ||
| 4689 | switch (state) { | 4721 | switch (state) { |
| 4690 | #if 0 | ||
| 4691 | case MPI2_RAID_PD_STATE_OFFLINE: | ||
| 4692 | if (sas_device) | ||
| 4693 | _scsih_remove_device(ioc, handle); | ||
| 4694 | break; | ||
| 4695 | #endif | ||
| 4696 | case MPI2_RAID_PD_STATE_ONLINE: | 4722 | case MPI2_RAID_PD_STATE_ONLINE: |
| 4697 | case MPI2_RAID_PD_STATE_DEGRADED: | 4723 | case MPI2_RAID_PD_STATE_DEGRADED: |
| 4698 | case MPI2_RAID_PD_STATE_REBUILDING: | 4724 | case MPI2_RAID_PD_STATE_REBUILDING: |
| 4699 | case MPI2_RAID_PD_STATE_OPTIMAL: | 4725 | case MPI2_RAID_PD_STATE_OPTIMAL: |
| 4700 | if (sas_device) | 4726 | if (sas_device) { |
| 4701 | sas_device->hidden_raid_component = 1; | 4727 | sas_device->hidden_raid_component = 1; |
| 4702 | else | 4728 | return; |
| 4703 | _scsih_add_device(ioc, handle, 0, 1); | 4729 | } |
| 4730 | |||
| 4731 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, | ||
| 4732 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, | ||
| 4733 | handle))) { | ||
| 4734 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
| 4735 | ioc->name, __FILE__, __LINE__, __func__); | ||
| 4736 | return; | ||
| 4737 | } | ||
| 4738 | |||
| 4739 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
| 4740 | MPI2_IOCSTATUS_MASK; | ||
| 4741 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
| 4742 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
| 4743 | ioc->name, __FILE__, __LINE__, __func__); | ||
| 4744 | return; | ||
| 4745 | } | ||
| 4746 | |||
| 4747 | _scsih_link_change(ioc, | ||
| 4748 | le16_to_cpu(sas_device_pg0.ParentDevHandle), | ||
| 4749 | handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); | ||
| 4750 | |||
| 4751 | _scsih_add_device(ioc, handle, 0, 1); | ||
| 4752 | |||
| 4704 | break; | 4753 | break; |
| 4705 | 4754 | ||
| 4755 | case MPI2_RAID_PD_STATE_OFFLINE: | ||
| 4706 | case MPI2_RAID_PD_STATE_NOT_CONFIGURED: | 4756 | case MPI2_RAID_PD_STATE_NOT_CONFIGURED: |
| 4707 | case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: | 4757 | case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: |
| 4708 | case MPI2_RAID_PD_STATE_HOT_SPARE: | 4758 | case MPI2_RAID_PD_STATE_HOT_SPARE: |
| @@ -5774,6 +5824,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 5774 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); | 5824 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); |
| 5775 | u32 device_state; | 5825 | u32 device_state; |
| 5776 | 5826 | ||
| 5827 | mpt2sas_base_stop_watchdog(ioc); | ||
| 5777 | flush_scheduled_work(); | 5828 | flush_scheduled_work(); |
| 5778 | scsi_block_requests(shost); | 5829 | scsi_block_requests(shost); |
| 5779 | device_state = pci_choose_state(pdev, state); | 5830 | device_state = pci_choose_state(pdev, state); |
| @@ -5816,6 +5867,7 @@ _scsih_resume(struct pci_dev *pdev) | |||
| 5816 | 5867 | ||
| 5817 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET); | 5868 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET); |
| 5818 | scsi_unblock_requests(shost); | 5869 | scsi_unblock_requests(shost); |
| 5870 | mpt2sas_base_start_watchdog(ioc); | ||
| 5819 | return 0; | 5871 | return 0; |
| 5820 | } | 5872 | } |
| 5821 | #endif /* CONFIG_PM */ | 5873 | #endif /* CONFIG_PM */ |
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c index fcc184cd066d..cbceb0ebabf7 100644 --- a/drivers/scsi/qla4xxx/ql4_dbg.c +++ b/drivers/scsi/qla4xxx/ql4_dbg.c | |||
| @@ -15,19 +15,18 @@ void qla4xxx_dump_buffer(void *b, uint32_t size) | |||
| 15 | uint32_t cnt; | 15 | uint32_t cnt; |
| 16 | uint8_t *c = b; | 16 | uint8_t *c = b; |
| 17 | 17 | ||
| 18 | printk(" 0 1 2 3 4 5 6 7 8 9 Ah Bh Ch Dh Eh " | 18 | printk(" 0 1 2 3 4 5 6 7 8 9 Ah Bh Ch Dh Eh " |
| 19 | "Fh\n"); | 19 | "Fh\n"); |
| 20 | printk("------------------------------------------------------------" | 20 | printk("------------------------------------------------------------" |
| 21 | "--\n"); | 21 | "--\n"); |
| 22 | for (cnt = 0; cnt < size; cnt++, c++) { | 22 | for (cnt = 0; cnt < size; c++) { |
| 23 | printk(KERN_DEBUG "%02x", *c); | 23 | printk(KERN_INFO "%02x", *c); |
| 24 | if (!(cnt % 16)) | 24 | if (!(++cnt % 16)) |
| 25 | printk(KERN_DEBUG "\n"); | 25 | printk(KERN_INFO "\n"); |
| 26 | 26 | ||
| 27 | else | 27 | else |
| 28 | printk(KERN_DEBUG " "); | 28 | printk(KERN_INFO " "); |
| 29 | } | 29 | } |
| 30 | if (cnt % 16) | 30 | printk(KERN_INFO "\n"); |
| 31 | printk(KERN_DEBUG "\n"); | ||
| 32 | } | 31 | } |
| 33 | 32 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index b586f27c3bd4..81b5f29254e2 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
| @@ -100,7 +100,6 @@ | |||
| 100 | #define MAX_SRBS MAX_CMDS_TO_RISC | 100 | #define MAX_SRBS MAX_CMDS_TO_RISC |
| 101 | #define MBOX_AEN_REG_COUNT 5 | 101 | #define MBOX_AEN_REG_COUNT 5 |
| 102 | #define MAX_INIT_RETRIES 5 | 102 | #define MAX_INIT_RETRIES 5 |
| 103 | #define IOCB_HIWAT_CUSHION 16 | ||
| 104 | 103 | ||
| 105 | /* | 104 | /* |
| 106 | * Buffer sizes | 105 | * Buffer sizes |
| @@ -184,6 +183,11 @@ struct srb { | |||
| 184 | uint16_t cc_stat; | 183 | uint16_t cc_stat; |
| 185 | u_long r_start; /* Time we recieve a cmd from OS */ | 184 | u_long r_start; /* Time we recieve a cmd from OS */ |
| 186 | u_long u_start; /* Time when we handed the cmd to F/W */ | 185 | u_long u_start; /* Time when we handed the cmd to F/W */ |
| 186 | |||
| 187 | /* Used for extended sense / status continuation */ | ||
| 188 | uint8_t *req_sense_ptr; | ||
| 189 | uint16_t req_sense_len; | ||
| 190 | uint16_t reserved2; | ||
| 187 | }; | 191 | }; |
| 188 | 192 | ||
| 189 | /* | 193 | /* |
| @@ -302,7 +306,6 @@ struct scsi_qla_host { | |||
| 302 | uint32_t tot_ddbs; | 306 | uint32_t tot_ddbs; |
| 303 | 307 | ||
| 304 | uint16_t iocb_cnt; | 308 | uint16_t iocb_cnt; |
| 305 | uint16_t iocb_hiwat; | ||
| 306 | 309 | ||
| 307 | /* SRB cache. */ | 310 | /* SRB cache. */ |
| 308 | #define SRB_MIN_REQ 128 | 311 | #define SRB_MIN_REQ 128 |
| @@ -436,6 +439,8 @@ struct scsi_qla_host { | |||
| 436 | /* Map ddb_list entry by FW ddb index */ | 439 | /* Map ddb_list entry by FW ddb index */ |
| 437 | struct ddb_entry *fw_ddb_index_map[MAX_DDB_ENTRIES]; | 440 | struct ddb_entry *fw_ddb_index_map[MAX_DDB_ENTRIES]; |
| 438 | 441 | ||
| 442 | /* Saved srb for status continuation entry processing */ | ||
| 443 | struct srb *status_srb; | ||
| 439 | }; | 444 | }; |
| 440 | 445 | ||
| 441 | static inline int is_qla4010(struct scsi_qla_host *ha) | 446 | static inline int is_qla4010(struct scsi_qla_host *ha) |
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index 1b667a70cffa..9cd7a608df38 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h | |||
| @@ -572,6 +572,7 @@ struct conn_event_log_entry { | |||
| 572 | *************************************************************************/ | 572 | *************************************************************************/ |
| 573 | #define IOCB_MAX_CDB_LEN 16 /* Bytes in a CBD */ | 573 | #define IOCB_MAX_CDB_LEN 16 /* Bytes in a CBD */ |
| 574 | #define IOCB_MAX_SENSEDATA_LEN 32 /* Bytes of sense data */ | 574 | #define IOCB_MAX_SENSEDATA_LEN 32 /* Bytes of sense data */ |
| 575 | #define IOCB_MAX_EXT_SENSEDATA_LEN 60 /* Bytes of extended sense data */ | ||
| 575 | 576 | ||
| 576 | /* IOCB header structure */ | 577 | /* IOCB header structure */ |
| 577 | struct qla4_header { | 578 | struct qla4_header { |
| @@ -733,6 +734,12 @@ struct status_entry { | |||
| 733 | 734 | ||
| 734 | }; | 735 | }; |
| 735 | 736 | ||
| 737 | /* Status Continuation entry */ | ||
| 738 | struct status_cont_entry { | ||
| 739 | struct qla4_header hdr; /* 00-03 */ | ||
| 740 | uint8_t ext_sense_data[IOCB_MAX_EXT_SENSEDATA_LEN]; /* 04-63 */ | ||
| 741 | }; | ||
| 742 | |||
| 736 | struct passthru0 { | 743 | struct passthru0 { |
| 737 | struct qla4_header hdr; /* 00-03 */ | 744 | struct qla4_header hdr; /* 00-03 */ |
| 738 | uint32_t handle; /* 04-07 */ | 745 | uint32_t handle; /* 04-07 */ |
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index 912a67494adf..e0c32159749c 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c | |||
| @@ -10,9 +10,42 @@ | |||
| 10 | #include "ql4_dbg.h" | 10 | #include "ql4_dbg.h" |
| 11 | #include "ql4_inline.h" | 11 | #include "ql4_inline.h" |
| 12 | 12 | ||
| 13 | |||
| 14 | #include <scsi/scsi_tcq.h> | 13 | #include <scsi/scsi_tcq.h> |
| 15 | 14 | ||
| 15 | static int | ||
| 16 | qla4xxx_space_in_req_ring(struct scsi_qla_host *ha, uint16_t req_cnt) | ||
| 17 | { | ||
| 18 | uint16_t cnt; | ||
| 19 | |||
| 20 | /* Calculate number of free request entries. */ | ||
| 21 | if ((req_cnt + 2) >= ha->req_q_count) { | ||
| 22 | cnt = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out); | ||
| 23 | if (ha->request_in < cnt) | ||
| 24 | ha->req_q_count = cnt - ha->request_in; | ||
| 25 | else | ||
| 26 | ha->req_q_count = REQUEST_QUEUE_DEPTH - | ||
| 27 | (ha->request_in - cnt); | ||
| 28 | } | ||
| 29 | |||
| 30 | /* Check if room for request in request ring. */ | ||
| 31 | if ((req_cnt + 2) < ha->req_q_count) | ||
| 32 | return 1; | ||
| 33 | else | ||
| 34 | return 0; | ||
| 35 | } | ||
| 36 | |||
| 37 | static void qla4xxx_advance_req_ring_ptr(struct scsi_qla_host *ha) | ||
| 38 | { | ||
| 39 | /* Advance request queue pointer */ | ||
| 40 | if (ha->request_in == (REQUEST_QUEUE_DEPTH - 1)) { | ||
| 41 | ha->request_in = 0; | ||
| 42 | ha->request_ptr = ha->request_ring; | ||
| 43 | } else { | ||
| 44 | ha->request_in++; | ||
| 45 | ha->request_ptr++; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 16 | /** | 49 | /** |
| 17 | * qla4xxx_get_req_pkt - returns a valid entry in request queue. | 50 | * qla4xxx_get_req_pkt - returns a valid entry in request queue. |
| 18 | * @ha: Pointer to host adapter structure. | 51 | * @ha: Pointer to host adapter structure. |
| @@ -26,35 +59,18 @@ | |||
| 26 | static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, | 59 | static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, |
| 27 | struct queue_entry **queue_entry) | 60 | struct queue_entry **queue_entry) |
| 28 | { | 61 | { |
| 29 | uint16_t request_in; | 62 | uint16_t req_cnt = 1; |
| 30 | uint8_t status = QLA_SUCCESS; | ||
| 31 | |||
| 32 | *queue_entry = ha->request_ptr; | ||
| 33 | 63 | ||
| 34 | /* get the latest request_in and request_out index */ | 64 | if (qla4xxx_space_in_req_ring(ha, req_cnt)) { |
| 35 | request_in = ha->request_in; | 65 | *queue_entry = ha->request_ptr; |
| 36 | ha->request_out = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out); | ||
| 37 | |||
| 38 | /* Advance request queue pointer and check for queue full */ | ||
| 39 | if (request_in == (REQUEST_QUEUE_DEPTH - 1)) { | ||
| 40 | request_in = 0; | ||
| 41 | ha->request_ptr = ha->request_ring; | ||
| 42 | } else { | ||
| 43 | request_in++; | ||
| 44 | ha->request_ptr++; | ||
| 45 | } | ||
| 46 | |||
| 47 | /* request queue is full, try again later */ | ||
| 48 | if ((ha->iocb_cnt + 1) >= ha->iocb_hiwat) { | ||
| 49 | /* restore request pointer */ | ||
| 50 | ha->request_ptr = *queue_entry; | ||
| 51 | status = QLA_ERROR; | ||
| 52 | } else { | ||
| 53 | ha->request_in = request_in; | ||
| 54 | memset(*queue_entry, 0, sizeof(**queue_entry)); | 66 | memset(*queue_entry, 0, sizeof(**queue_entry)); |
| 67 | |||
| 68 | qla4xxx_advance_req_ring_ptr(ha); | ||
| 69 | ha->req_q_count -= req_cnt; | ||
| 70 | return QLA_SUCCESS; | ||
| 55 | } | 71 | } |
| 56 | 72 | ||
| 57 | return status; | 73 | return QLA_ERROR; |
| 58 | } | 74 | } |
| 59 | 75 | ||
| 60 | /** | 76 | /** |
| @@ -100,21 +116,14 @@ exit_send_marker: | |||
| 100 | return status; | 116 | return status; |
| 101 | } | 117 | } |
| 102 | 118 | ||
| 103 | static struct continuation_t1_entry* qla4xxx_alloc_cont_entry( | 119 | static struct continuation_t1_entry * |
| 104 | struct scsi_qla_host *ha) | 120 | qla4xxx_alloc_cont_entry(struct scsi_qla_host *ha) |
| 105 | { | 121 | { |
| 106 | struct continuation_t1_entry *cont_entry; | 122 | struct continuation_t1_entry *cont_entry; |
| 107 | 123 | ||
| 108 | cont_entry = (struct continuation_t1_entry *)ha->request_ptr; | 124 | cont_entry = (struct continuation_t1_entry *)ha->request_ptr; |
| 109 | 125 | ||
| 110 | /* Advance request queue pointer */ | 126 | qla4xxx_advance_req_ring_ptr(ha); |
| 111 | if (ha->request_in == (REQUEST_QUEUE_DEPTH - 1)) { | ||
| 112 | ha->request_in = 0; | ||
| 113 | ha->request_ptr = ha->request_ring; | ||
| 114 | } else { | ||
| 115 | ha->request_in++; | ||
| 116 | ha->request_ptr++; | ||
| 117 | } | ||
| 118 | 127 | ||
| 119 | /* Load packet defaults */ | 128 | /* Load packet defaults */ |
| 120 | cont_entry->hdr.entryType = ET_CONTINUE; | 129 | cont_entry->hdr.entryType = ET_CONTINUE; |
| @@ -197,13 +206,10 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |||
| 197 | struct scsi_cmnd *cmd = srb->cmd; | 206 | struct scsi_cmnd *cmd = srb->cmd; |
| 198 | struct ddb_entry *ddb_entry; | 207 | struct ddb_entry *ddb_entry; |
| 199 | struct command_t3_entry *cmd_entry; | 208 | struct command_t3_entry *cmd_entry; |
| 200 | |||
| 201 | int nseg; | 209 | int nseg; |
| 202 | uint16_t tot_dsds; | 210 | uint16_t tot_dsds; |
| 203 | uint16_t req_cnt; | 211 | uint16_t req_cnt; |
| 204 | |||
| 205 | unsigned long flags; | 212 | unsigned long flags; |
| 206 | uint16_t cnt; | ||
| 207 | uint32_t index; | 213 | uint32_t index; |
| 208 | char tag[2]; | 214 | char tag[2]; |
| 209 | 215 | ||
| @@ -217,6 +223,19 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |||
| 217 | 223 | ||
| 218 | index = (uint32_t)cmd->request->tag; | 224 | index = (uint32_t)cmd->request->tag; |
| 219 | 225 | ||
| 226 | /* | ||
| 227 | * Check to see if adapter is online before placing request on | ||
| 228 | * request queue. If a reset occurs and a request is in the queue, | ||
| 229 | * the firmware will still attempt to process the request, retrieving | ||
| 230 | * garbage for pointers. | ||
| 231 | */ | ||
| 232 | if (!test_bit(AF_ONLINE, &ha->flags)) { | ||
| 233 | DEBUG2(printk("scsi%ld: %s: Adapter OFFLINE! " | ||
| 234 | "Do not issue command.\n", | ||
| 235 | ha->host_no, __func__)); | ||
| 236 | goto queuing_error; | ||
| 237 | } | ||
| 238 | |||
| 220 | /* Calculate the number of request entries needed. */ | 239 | /* Calculate the number of request entries needed. */ |
| 221 | nseg = scsi_dma_map(cmd); | 240 | nseg = scsi_dma_map(cmd); |
| 222 | if (nseg < 0) | 241 | if (nseg < 0) |
| @@ -224,17 +243,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |||
| 224 | tot_dsds = nseg; | 243 | tot_dsds = nseg; |
| 225 | 244 | ||
| 226 | req_cnt = qla4xxx_calc_request_entries(tot_dsds); | 245 | req_cnt = qla4xxx_calc_request_entries(tot_dsds); |
| 227 | 246 | if (!qla4xxx_space_in_req_ring(ha, req_cnt)) | |
| 228 | if (ha->req_q_count < (req_cnt + 2)) { | ||
| 229 | cnt = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out); | ||
| 230 | if (ha->request_in < cnt) | ||
| 231 | ha->req_q_count = cnt - ha->request_in; | ||
| 232 | else | ||
| 233 | ha->req_q_count = REQUEST_QUEUE_DEPTH - | ||
| 234 | (ha->request_in - cnt); | ||
| 235 | } | ||
| 236 | |||
| 237 | if (ha->req_q_count < (req_cnt + 2)) | ||
| 238 | goto queuing_error; | 247 | goto queuing_error; |
| 239 | 248 | ||
| 240 | /* total iocbs active */ | 249 | /* total iocbs active */ |
| @@ -286,32 +295,10 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |||
| 286 | break; | 295 | break; |
| 287 | } | 296 | } |
| 288 | 297 | ||
| 289 | 298 | qla4xxx_advance_req_ring_ptr(ha); | |
| 290 | /* Advance request queue pointer */ | ||
| 291 | ha->request_in++; | ||
| 292 | if (ha->request_in == REQUEST_QUEUE_DEPTH) { | ||
| 293 | ha->request_in = 0; | ||
| 294 | ha->request_ptr = ha->request_ring; | ||
| 295 | } else | ||
| 296 | ha->request_ptr++; | ||
| 297 | |||
| 298 | |||
| 299 | qla4xxx_build_scsi_iocbs(srb, cmd_entry, tot_dsds); | 299 | qla4xxx_build_scsi_iocbs(srb, cmd_entry, tot_dsds); |
| 300 | wmb(); | 300 | wmb(); |
| 301 | 301 | ||
| 302 | /* | ||
| 303 | * Check to see if adapter is online before placing request on | ||
| 304 | * request queue. If a reset occurs and a request is in the queue, | ||
| 305 | * the firmware will still attempt to process the request, retrieving | ||
| 306 | * garbage for pointers. | ||
| 307 | */ | ||
| 308 | if (!test_bit(AF_ONLINE, &ha->flags)) { | ||
| 309 | DEBUG2(printk("scsi%ld: %s: Adapter OFFLINE! " | ||
| 310 | "Do not issue command.\n", | ||
| 311 | ha->host_no, __func__)); | ||
| 312 | goto queuing_error; | ||
| 313 | } | ||
| 314 | |||
| 315 | srb->cmd->host_scribble = (unsigned char *)srb; | 302 | srb->cmd->host_scribble = (unsigned char *)srb; |
| 316 | 303 | ||
| 317 | /* update counters */ | 304 | /* update counters */ |
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index 799120fcb9be..8025ee16588e 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c | |||
| @@ -11,6 +11,98 @@ | |||
| 11 | #include "ql4_inline.h" | 11 | #include "ql4_inline.h" |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | * qla4xxx_copy_sense - copy sense data into cmd sense buffer | ||
| 15 | * @ha: Pointer to host adapter structure. | ||
| 16 | * @sts_entry: Pointer to status entry structure. | ||
| 17 | * @srb: Pointer to srb structure. | ||
| 18 | **/ | ||
| 19 | static void qla4xxx_copy_sense(struct scsi_qla_host *ha, | ||
| 20 | struct status_entry *sts_entry, | ||
| 21 | struct srb *srb) | ||
| 22 | { | ||
| 23 | struct scsi_cmnd *cmd = srb->cmd; | ||
| 24 | uint16_t sense_len; | ||
| 25 | |||
| 26 | memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
| 27 | sense_len = le16_to_cpu(sts_entry->senseDataByteCnt); | ||
| 28 | if (sense_len == 0) | ||
| 29 | return; | ||
| 30 | |||
| 31 | /* Save total available sense length, | ||
| 32 | * not to exceed cmd's sense buffer size */ | ||
| 33 | sense_len = min_t(uint16_t, sense_len, SCSI_SENSE_BUFFERSIZE); | ||
| 34 | srb->req_sense_ptr = cmd->sense_buffer; | ||
| 35 | srb->req_sense_len = sense_len; | ||
| 36 | |||
| 37 | /* Copy sense from sts_entry pkt */ | ||
| 38 | sense_len = min_t(uint16_t, sense_len, IOCB_MAX_SENSEDATA_LEN); | ||
| 39 | memcpy(cmd->sense_buffer, sts_entry->senseData, sense_len); | ||
| 40 | |||
| 41 | DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: %s: sense key = %x, " | ||
| 42 | "ASL= %02x, ASC/ASCQ = %02x/%02x\n", ha->host_no, | ||
| 43 | cmd->device->channel, cmd->device->id, | ||
| 44 | cmd->device->lun, __func__, | ||
| 45 | sts_entry->senseData[2] & 0x0f, | ||
| 46 | sts_entry->senseData[7], | ||
| 47 | sts_entry->senseData[12], | ||
| 48 | sts_entry->senseData[13])); | ||
| 49 | |||
| 50 | DEBUG5(qla4xxx_dump_buffer(cmd->sense_buffer, sense_len)); | ||
| 51 | srb->flags |= SRB_GOT_SENSE; | ||
| 52 | |||
| 53 | /* Update srb, in case a sts_cont pkt follows */ | ||
| 54 | srb->req_sense_ptr += sense_len; | ||
| 55 | srb->req_sense_len -= sense_len; | ||
| 56 | if (srb->req_sense_len != 0) | ||
| 57 | ha->status_srb = srb; | ||
| 58 | else | ||
| 59 | ha->status_srb = NULL; | ||
| 60 | } | ||
| 61 | |||
| 62 | /** | ||
| 63 | * qla4xxx_status_cont_entry - Process a Status Continuations entry. | ||
| 64 | * @ha: SCSI driver HA context | ||
| 65 | * @sts_cont: Entry pointer | ||
| 66 | * | ||
| 67 | * Extended sense data. | ||
| 68 | */ | ||
| 69 | static void | ||
| 70 | qla4xxx_status_cont_entry(struct scsi_qla_host *ha, | ||
| 71 | struct status_cont_entry *sts_cont) | ||
| 72 | { | ||
| 73 | struct srb *srb = ha->status_srb; | ||
| 74 | struct scsi_cmnd *cmd; | ||
| 75 | uint8_t sense_len; | ||
| 76 | |||
| 77 | if (srb == NULL) | ||
| 78 | return; | ||
| 79 | |||
| 80 | cmd = srb->cmd; | ||
| 81 | if (cmd == NULL) { | ||
| 82 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: Cmd already returned " | ||
| 83 | "back to OS srb=%p srb->state:%d\n", ha->host_no, | ||
| 84 | __func__, srb, srb->state)); | ||
| 85 | ha->status_srb = NULL; | ||
| 86 | return; | ||
| 87 | } | ||
| 88 | |||
| 89 | /* Copy sense data. */ | ||
| 90 | sense_len = min_t(uint16_t, srb->req_sense_len, | ||
| 91 | IOCB_MAX_EXT_SENSEDATA_LEN); | ||
| 92 | memcpy(srb->req_sense_ptr, sts_cont->ext_sense_data, sense_len); | ||
| 93 | DEBUG5(qla4xxx_dump_buffer(srb->req_sense_ptr, sense_len)); | ||
| 94 | |||
| 95 | srb->req_sense_ptr += sense_len; | ||
| 96 | srb->req_sense_len -= sense_len; | ||
| 97 | |||
| 98 | /* Place command on done queue. */ | ||
| 99 | if (srb->req_sense_len == 0) { | ||
| 100 | qla4xxx_srb_compl(ha, srb); | ||
| 101 | ha->status_srb = NULL; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | /** | ||
| 14 | * qla4xxx_status_entry - processes status IOCBs | 106 | * qla4xxx_status_entry - processes status IOCBs |
| 15 | * @ha: Pointer to host adapter structure. | 107 | * @ha: Pointer to host adapter structure. |
| 16 | * @sts_entry: Pointer to status entry structure. | 108 | * @sts_entry: Pointer to status entry structure. |
| @@ -23,7 +115,6 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
| 23 | struct srb *srb; | 115 | struct srb *srb; |
| 24 | struct ddb_entry *ddb_entry; | 116 | struct ddb_entry *ddb_entry; |
| 25 | uint32_t residual; | 117 | uint32_t residual; |
| 26 | uint16_t sensebytecnt; | ||
| 27 | 118 | ||
| 28 | srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); | 119 | srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); |
| 29 | if (!srb) { | 120 | if (!srb) { |
| @@ -92,24 +183,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
| 92 | break; | 183 | break; |
| 93 | 184 | ||
| 94 | /* Copy Sense Data into sense buffer. */ | 185 | /* Copy Sense Data into sense buffer. */ |
| 95 | memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | 186 | qla4xxx_copy_sense(ha, sts_entry, srb); |
| 96 | |||
| 97 | sensebytecnt = le16_to_cpu(sts_entry->senseDataByteCnt); | ||
| 98 | if (sensebytecnt == 0) | ||
| 99 | break; | ||
| 100 | |||
| 101 | memcpy(cmd->sense_buffer, sts_entry->senseData, | ||
| 102 | min_t(uint16_t, sensebytecnt, SCSI_SENSE_BUFFERSIZE)); | ||
| 103 | |||
| 104 | DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, " | ||
| 105 | "ASC/ASCQ = %02x/%02x\n", ha->host_no, | ||
| 106 | cmd->device->channel, cmd->device->id, | ||
| 107 | cmd->device->lun, __func__, | ||
| 108 | sts_entry->senseData[2] & 0x0f, | ||
| 109 | sts_entry->senseData[12], | ||
| 110 | sts_entry->senseData[13])); | ||
| 111 | |||
| 112 | srb->flags |= SRB_GOT_SENSE; | ||
| 113 | break; | 187 | break; |
| 114 | 188 | ||
| 115 | case SCS_INCOMPLETE: | 189 | case SCS_INCOMPLETE: |
| @@ -176,23 +250,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
| 176 | break; | 250 | break; |
| 177 | 251 | ||
| 178 | /* Copy Sense Data into sense buffer. */ | 252 | /* Copy Sense Data into sense buffer. */ |
| 179 | memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | 253 | qla4xxx_copy_sense(ha, sts_entry, srb); |
| 180 | |||
| 181 | sensebytecnt = | ||
| 182 | le16_to_cpu(sts_entry->senseDataByteCnt); | ||
| 183 | if (sensebytecnt == 0) | ||
| 184 | break; | ||
| 185 | |||
| 186 | memcpy(cmd->sense_buffer, sts_entry->senseData, | ||
| 187 | min_t(uint16_t, sensebytecnt, SCSI_SENSE_BUFFERSIZE)); | ||
| 188 | |||
| 189 | DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, " | ||
| 190 | "ASC/ASCQ = %02x/%02x\n", ha->host_no, | ||
| 191 | cmd->device->channel, cmd->device->id, | ||
| 192 | cmd->device->lun, __func__, | ||
| 193 | sts_entry->senseData[2] & 0x0f, | ||
| 194 | sts_entry->senseData[12], | ||
| 195 | sts_entry->senseData[13])); | ||
| 196 | } else { | 254 | } else { |
| 197 | /* | 255 | /* |
| 198 | * If RISC reports underrun and target does not | 256 | * If RISC reports underrun and target does not |
| @@ -268,9 +326,10 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
| 268 | 326 | ||
| 269 | status_entry_exit: | 327 | status_entry_exit: |
| 270 | 328 | ||
| 271 | /* complete the request */ | 329 | /* complete the request, if not waiting for status_continuation pkt */ |
| 272 | srb->cc_stat = sts_entry->completionStatus; | 330 | srb->cc_stat = sts_entry->completionStatus; |
| 273 | qla4xxx_srb_compl(ha, srb); | 331 | if (ha->status_srb == NULL) |
| 332 | qla4xxx_srb_compl(ha, srb); | ||
| 274 | } | 333 | } |
| 275 | 334 | ||
| 276 | /** | 335 | /** |
| @@ -305,10 +364,7 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha) | |||
| 305 | /* process entry */ | 364 | /* process entry */ |
| 306 | switch (sts_entry->hdr.entryType) { | 365 | switch (sts_entry->hdr.entryType) { |
| 307 | case ET_STATUS: | 366 | case ET_STATUS: |
| 308 | /* | 367 | /* Common status */ |
| 309 | * Common status - Single completion posted in single | ||
| 310 | * IOSB. | ||
| 311 | */ | ||
| 312 | qla4xxx_status_entry(ha, sts_entry); | 368 | qla4xxx_status_entry(ha, sts_entry); |
| 313 | break; | 369 | break; |
| 314 | 370 | ||
| @@ -316,9 +372,8 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha) | |||
| 316 | break; | 372 | break; |
| 317 | 373 | ||
| 318 | case ET_STATUS_CONTINUATION: | 374 | case ET_STATUS_CONTINUATION: |
| 319 | /* Just throw away the status continuation entries */ | 375 | qla4xxx_status_cont_entry(ha, |
| 320 | DEBUG2(printk("scsi%ld: %s: Status Continuation entry " | 376 | (struct status_cont_entry *) sts_entry); |
| 321 | "- ignoring\n", ha->host_no, __func__)); | ||
| 322 | break; | 377 | break; |
| 323 | 378 | ||
| 324 | case ET_COMMAND: | 379 | case ET_COMMAND: |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 051b0f5e8c8e..09d6d4b76f39 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
| @@ -385,16 +385,6 @@ int qla4xxx_get_firmware_status(struct scsi_qla_host * ha) | |||
| 385 | mbox_sts[0])); | 385 | mbox_sts[0])); |
| 386 | return QLA_ERROR; | 386 | return QLA_ERROR; |
| 387 | } | 387 | } |
| 388 | |||
| 389 | /* High-water mark of IOCBs */ | ||
| 390 | ha->iocb_hiwat = mbox_sts[2]; | ||
| 391 | if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION) | ||
| 392 | ha->iocb_hiwat -= IOCB_HIWAT_CUSHION; | ||
| 393 | else | ||
| 394 | dev_info(&ha->pdev->dev, "WARNING!!! You have less than %d " | ||
| 395 | "firmware IOCBs available (%d).\n", | ||
| 396 | IOCB_HIWAT_CUSHION, ha->iocb_hiwat); | ||
| 397 | |||
| 398 | return QLA_SUCCESS; | 388 | return QLA_SUCCESS; |
| 399 | } | 389 | } |
| 400 | 390 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index ec9da6ce8489..40e3cafb3a9c 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
| @@ -66,6 +66,7 @@ static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess, | |||
| 66 | static int qla4xxx_host_get_param(struct Scsi_Host *shost, | 66 | static int qla4xxx_host_get_param(struct Scsi_Host *shost, |
| 67 | enum iscsi_host_param param, char *buf); | 67 | enum iscsi_host_param param, char *buf); |
| 68 | static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session); | 68 | static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session); |
| 69 | static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc); | ||
| 69 | 70 | ||
| 70 | /* | 71 | /* |
| 71 | * SCSI host template entry points | 72 | * SCSI host template entry points |
| @@ -89,6 +90,7 @@ static struct scsi_host_template qla4xxx_driver_template = { | |||
| 89 | .eh_device_reset_handler = qla4xxx_eh_device_reset, | 90 | .eh_device_reset_handler = qla4xxx_eh_device_reset, |
| 90 | .eh_target_reset_handler = qla4xxx_eh_target_reset, | 91 | .eh_target_reset_handler = qla4xxx_eh_target_reset, |
| 91 | .eh_host_reset_handler = qla4xxx_eh_host_reset, | 92 | .eh_host_reset_handler = qla4xxx_eh_host_reset, |
| 93 | .eh_timed_out = qla4xxx_eh_cmd_timed_out, | ||
| 92 | 94 | ||
| 93 | .slave_configure = qla4xxx_slave_configure, | 95 | .slave_configure = qla4xxx_slave_configure, |
| 94 | .slave_alloc = qla4xxx_slave_alloc, | 96 | .slave_alloc = qla4xxx_slave_alloc, |
| @@ -124,6 +126,21 @@ static struct iscsi_transport qla4xxx_iscsi_transport = { | |||
| 124 | 126 | ||
| 125 | static struct scsi_transport_template *qla4xxx_scsi_transport; | 127 | static struct scsi_transport_template *qla4xxx_scsi_transport; |
| 126 | 128 | ||
| 129 | static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc) | ||
| 130 | { | ||
| 131 | struct iscsi_cls_session *session; | ||
| 132 | struct ddb_entry *ddb_entry; | ||
| 133 | |||
| 134 | session = starget_to_session(scsi_target(sc->device)); | ||
| 135 | ddb_entry = session->dd_data; | ||
| 136 | |||
| 137 | /* if we are not logged in then the LLD is going to clean up the cmd */ | ||
| 138 | if (atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) | ||
| 139 | return BLK_EH_RESET_TIMER; | ||
| 140 | else | ||
| 141 | return BLK_EH_NOT_HANDLED; | ||
| 142 | } | ||
| 143 | |||
| 127 | static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session) | 144 | static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session) |
| 128 | { | 145 | { |
| 129 | struct ddb_entry *ddb_entry = session->dd_data; | 146 | struct ddb_entry *ddb_entry = session->dd_data; |
| @@ -904,18 +921,17 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | |||
| 904 | /* Flush any pending ddb changed AENs */ | 921 | /* Flush any pending ddb changed AENs */ |
| 905 | qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); | 922 | qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); |
| 906 | 923 | ||
| 924 | qla4xxx_flush_active_srbs(ha); | ||
| 925 | |||
| 907 | /* Reset the firmware. If successful, function | 926 | /* Reset the firmware. If successful, function |
| 908 | * returns with ISP interrupts enabled. | 927 | * returns with ISP interrupts enabled. |
| 909 | */ | 928 | */ |
| 910 | if (status == QLA_SUCCESS) { | 929 | DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n", |
| 911 | DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n", | 930 | ha->host_no, __func__)); |
| 912 | ha->host_no, __func__)); | 931 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) |
| 913 | qla4xxx_flush_active_srbs(ha); | 932 | status = qla4xxx_soft_reset(ha); |
| 914 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) | 933 | else |
| 915 | status = qla4xxx_soft_reset(ha); | 934 | status = QLA_ERROR; |
| 916 | else | ||
| 917 | status = QLA_ERROR; | ||
| 918 | } | ||
| 919 | 935 | ||
| 920 | /* Flush any pending ddb changed AENs */ | 936 | /* Flush any pending ddb changed AENs */ |
| 921 | qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); | 937 | qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); |
| @@ -1527,11 +1543,9 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
| 1527 | { | 1543 | { |
| 1528 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); | 1544 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); |
| 1529 | struct ddb_entry *ddb_entry = cmd->device->hostdata; | 1545 | struct ddb_entry *ddb_entry = cmd->device->hostdata; |
| 1530 | struct srb *sp; | ||
| 1531 | int ret = FAILED, stat; | 1546 | int ret = FAILED, stat; |
| 1532 | 1547 | ||
| 1533 | sp = (struct srb *) cmd->SCp.ptr; | 1548 | if (!ddb_entry) |
| 1534 | if (!sp || !ddb_entry) | ||
| 1535 | return ret; | 1549 | return ret; |
| 1536 | 1550 | ||
| 1537 | dev_info(&ha->pdev->dev, | 1551 | dev_info(&ha->pdev->dev, |
| @@ -1644,7 +1658,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
| 1644 | ha = (struct scsi_qla_host *) cmd->device->host->hostdata; | 1658 | ha = (struct scsi_qla_host *) cmd->device->host->hostdata; |
| 1645 | 1659 | ||
| 1646 | dev_info(&ha->pdev->dev, | 1660 | dev_info(&ha->pdev->dev, |
| 1647 | "scsi(%ld:%d:%d:%d): ADAPTER RESET ISSUED.\n", ha->host_no, | 1661 | "scsi(%ld:%d:%d:%d): HOST RESET ISSUED.\n", ha->host_no, |
| 1648 | cmd->device->channel, cmd->device->id, cmd->device->lun); | 1662 | cmd->device->channel, cmd->device->id, cmd->device->lun); |
| 1649 | 1663 | ||
| 1650 | if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) { | 1664 | if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) { |
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index ab984cb89cea..6980cb279c81 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h | |||
| @@ -5,5 +5,5 @@ | |||
| 5 | * See LICENSE.qla4xxx for copyright and licensing details. | 5 | * See LICENSE.qla4xxx for copyright and licensing details. |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #define QLA4XXX_DRIVER_VERSION "5.01.00-k8" | 8 | #define QLA4XXX_DRIVER_VERSION "5.01.00-k9" |
| 9 | 9 | ||
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 783e33c65eb7..b47240ca4b19 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
| @@ -990,7 +990,7 @@ int iscsi_offload_mesg(struct Scsi_Host *shost, | |||
| 990 | struct iscsi_uevent *ev; | 990 | struct iscsi_uevent *ev; |
| 991 | int len = NLMSG_SPACE(sizeof(*ev) + data_size); | 991 | int len = NLMSG_SPACE(sizeof(*ev) + data_size); |
| 992 | 992 | ||
| 993 | skb = alloc_skb(len, GFP_NOIO); | 993 | skb = alloc_skb(len, GFP_ATOMIC); |
| 994 | if (!skb) { | 994 | if (!skb) { |
| 995 | printk(KERN_ERR "can not deliver iscsi offload message:OOM\n"); | 995 | printk(KERN_ERR "can not deliver iscsi offload message:OOM\n"); |
| 996 | return -ENOMEM; | 996 | return -ENOMEM; |
| @@ -1012,7 +1012,7 @@ int iscsi_offload_mesg(struct Scsi_Host *shost, | |||
| 1012 | 1012 | ||
| 1013 | memcpy((char *)ev + sizeof(*ev), data, data_size); | 1013 | memcpy((char *)ev + sizeof(*ev), data, data_size); |
| 1014 | 1014 | ||
| 1015 | return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_NOIO); | 1015 | return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_ATOMIC); |
| 1016 | } | 1016 | } |
| 1017 | EXPORT_SYMBOL_GPL(iscsi_offload_mesg); | 1017 | EXPORT_SYMBOL_GPL(iscsi_offload_mesg); |
| 1018 | 1018 | ||
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 5616cd780ff3..b7b9fec67a98 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -1840,6 +1840,18 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) | |||
| 1840 | kfree(buffer); | 1840 | kfree(buffer); |
| 1841 | } | 1841 | } |
| 1842 | 1842 | ||
| 1843 | static int sd_try_extended_inquiry(struct scsi_device *sdp) | ||
| 1844 | { | ||
| 1845 | /* | ||
| 1846 | * Although VPD inquiries can go to SCSI-2 type devices, | ||
| 1847 | * some USB ones crash on receiving them, and the pages | ||
| 1848 | * we currently ask for are for SPC-3 and beyond | ||
| 1849 | */ | ||
| 1850 | if (sdp->scsi_level > SCSI_SPC_2) | ||
| 1851 | return 1; | ||
| 1852 | return 0; | ||
| 1853 | } | ||
| 1854 | |||
| 1843 | /** | 1855 | /** |
| 1844 | * sd_revalidate_disk - called the first time a new disk is seen, | 1856 | * sd_revalidate_disk - called the first time a new disk is seen, |
| 1845 | * performs disk spin up, read_capacity, etc. | 1857 | * performs disk spin up, read_capacity, etc. |
| @@ -1877,8 +1889,12 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
| 1877 | */ | 1889 | */ |
| 1878 | if (sdkp->media_present) { | 1890 | if (sdkp->media_present) { |
| 1879 | sd_read_capacity(sdkp, buffer); | 1891 | sd_read_capacity(sdkp, buffer); |
| 1880 | sd_read_block_limits(sdkp); | 1892 | |
| 1881 | sd_read_block_characteristics(sdkp); | 1893 | if (sd_try_extended_inquiry(sdp)) { |
| 1894 | sd_read_block_limits(sdkp); | ||
| 1895 | sd_read_block_characteristics(sdkp); | ||
| 1896 | } | ||
| 1897 | |||
| 1882 | sd_read_write_protect_flag(sdkp, buffer); | 1898 | sd_read_write_protect_flag(sdkp, buffer); |
| 1883 | sd_read_cache_type(sdkp, buffer); | 1899 | sd_read_cache_type(sdkp, buffer); |
| 1884 | sd_read_app_tag_own(sdkp, buffer); | 1900 | sd_read_app_tag_own(sdkp, buffer); |
