aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/remote_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/remote_device.c')
-rw-r--r--drivers/scsi/isci/remote_device.c138
1 files changed, 20 insertions, 118 deletions
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c
index fc79a5b47f72..5ba3b5dca4d5 100644
--- a/drivers/scsi/isci/remote_device.c
+++ b/drivers/scsi/isci/remote_device.c
@@ -1533,21 +1533,8 @@ static enum sci_status scic_remote_device_da_construct(struct scic_sds_port *sci
1533 return SCI_SUCCESS; 1533 return SCI_SUCCESS;
1534} 1534}
1535 1535
1536static void scic_sds_remote_device_get_info_from_smp_discover_response(
1537 struct scic_sds_remote_device *sci_dev,
1538 struct smp_response_discover *discover_response)
1539{
1540 /* decode discover_response to set sas_address to sci_dev. */
1541 sci_dev->device_address.high =
1542 discover_response->attached_sas_address.high;
1543
1544 sci_dev->device_address.low =
1545 discover_response->attached_sas_address.low;
1546}
1547
1548/** 1536/**
1549 * scic_remote_device_ea_construct() - construct expander attached device 1537 * scic_remote_device_ea_construct() - construct expander attached device
1550 * @discover_response: data to build remote device
1551 * 1538 *
1552 * Remote node context(s) is/are a global resource allocated by this 1539 * Remote node context(s) is/are a global resource allocated by this
1553 * routine, freed by scic_remote_device_destruct(). 1540 * routine, freed by scic_remote_device_destruct().
@@ -1559,17 +1546,14 @@ static void scic_sds_remote_device_get_info_from_smp_discover_response(
1559 * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted. 1546 * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
1560 */ 1547 */
1561static enum sci_status scic_remote_device_ea_construct(struct scic_sds_port *sci_port, 1548static enum sci_status scic_remote_device_ea_construct(struct scic_sds_port *sci_port,
1562 struct scic_sds_remote_device *sci_dev, 1549 struct scic_sds_remote_device *sci_dev)
1563 struct smp_response_discover *discover_response)
1564{ 1550{
1565 struct scic_sds_controller *scic = sci_port->owning_controller; 1551 struct scic_sds_controller *scic = sci_port->owning_controller;
1566 struct domain_device *dev = sci_dev_to_domain(sci_dev); 1552 struct domain_device *dev = sci_dev_to_domain(sci_dev);
1567 enum sci_status status; 1553 enum sci_status status;
1568 1554
1569 scic_remote_device_construct(sci_port, sci_dev); 1555 scic_remote_device_construct(sci_port, sci_dev);
1570 1556 memcpy(&sci_dev->device_address, dev->sas_addr, SAS_ADDR_SIZE);
1571 scic_sds_remote_device_get_info_from_smp_discover_response(
1572 sci_dev, discover_response);
1573 1557
1574 status = scic_sds_controller_allocate_remote_node_context( 1558 status = scic_sds_controller_allocate_remote_node_context(
1575 scic, sci_dev, &sci_dev->rnc.remote_node_index); 1559 scic, sci_dev, &sci_dev->rnc.remote_node_index);
@@ -1605,7 +1589,7 @@ static enum sci_status scic_remote_device_ea_construct(struct scic_sds_port *sci
1605 * physical. Furthermore, the SAS-2 and SAS-1.1 fields overlay 1589 * physical. Furthermore, the SAS-2 and SAS-1.1 fields overlay
1606 * one another, so this code works for both situations. */ 1590 * one another, so this code works for both situations. */
1607 sci_dev->connection_rate = min_t(u16, scic_sds_port_get_max_allowed_speed(sci_port), 1591 sci_dev->connection_rate = min_t(u16, scic_sds_port_get_max_allowed_speed(sci_port),
1608 discover_response->u2.sas1_1.negotiated_physical_link_rate); 1592 dev->linkrate);
1609 1593
1610 /* / @todo Should I assign the port width by reading all of the phys on the port? */ 1594 /* / @todo Should I assign the port width by reading all of the phys on the port? */
1611 sci_dev->device_port_width = 1; 1595 sci_dev->device_port_width = 1;
@@ -1632,117 +1616,35 @@ static enum sci_status scic_remote_device_start(struct scic_sds_remote_device *s
1632 return sci_dev->state_handlers->start_handler(sci_dev); 1616 return sci_dev->state_handlers->start_handler(sci_dev);
1633} 1617}
1634 1618
1635/** 1619static enum sci_status isci_remote_device_construct(struct isci_port *iport,
1636 * isci_remote_device_construct() - This function calls the scic remote device 1620 struct isci_remote_device *idev)
1637 * construct and start functions, it waits on the remote device start
1638 * completion.
1639 * @port: This parameter specifies the isci port with the remote device.
1640 * @isci_device: This parameter specifies the isci remote device
1641 *
1642 * status from the scic calls, the caller to this function should clean up
1643 * resources as appropriate.
1644 */
1645static enum sci_status isci_remote_device_construct(
1646 struct isci_port *port,
1647 struct isci_remote_device *isci_device)
1648{ 1621{
1649 enum sci_status status = SCI_SUCCESS; 1622 struct scic_sds_port *sci_port = iport->sci_port_handle;
1650 1623 struct isci_host *ihost = iport->isci_host;
1651 if (isci_device->domain_dev->parent && 1624 struct domain_device *dev = idev->domain_dev;
1652 dev_is_expander(isci_device->domain_dev->parent)) { 1625 enum sci_status status;
1653 int i;
1654
1655 /* struct smp_response_discover discover_response; */
1656 struct discover_resp discover_response;
1657 struct domain_device *parent =
1658 isci_device->domain_dev->parent;
1659
1660 struct expander_device *parent_ex = &parent->ex_dev;
1661
1662 for (i = 0; i < parent_ex->num_phys; i++) {
1663
1664 struct ex_phy *phy = &parent_ex->ex_phy[i];
1665
1666 if ((phy->phy_state == PHY_VACANT) ||
1667 (phy->phy_state == PHY_NOT_PRESENT))
1668 continue;
1669
1670 if (SAS_ADDR(phy->attached_sas_addr)
1671 == SAS_ADDR(isci_device->domain_dev->sas_addr)) {
1672
1673 discover_response.attached_dev_type
1674 = phy->attached_dev_type;
1675 discover_response.linkrate
1676 = phy->linkrate;
1677 discover_response.attached_sata_host
1678 = phy->attached_sata_host;
1679 discover_response.attached_sata_dev
1680 = phy->attached_sata_dev;
1681 discover_response.attached_sata_ps
1682 = phy->attached_sata_ps;
1683 discover_response.iproto
1684 = phy->attached_iproto >> 1;
1685 discover_response.tproto
1686 = phy->attached_tproto >> 1;
1687 memcpy(
1688 discover_response.attached_sas_addr,
1689 phy->attached_sas_addr,
1690 SAS_ADDR_SIZE
1691 );
1692 discover_response.attached_phy_id
1693 = phy->attached_phy_id;
1694 discover_response.change_count
1695 = phy->phy_change_count;
1696 discover_response.routing_attr
1697 = phy->routing_attr;
1698 discover_response.hmin_linkrate
1699 = phy->phy->minimum_linkrate_hw;
1700 discover_response.hmax_linkrate
1701 = phy->phy->maximum_linkrate_hw;
1702 discover_response.pmin_linkrate
1703 = phy->phy->minimum_linkrate;
1704 discover_response.pmax_linkrate
1705 = phy->phy->maximum_linkrate;
1706 }
1707 }
1708
1709
1710 dev_dbg(&port->isci_host->pdev->dev,
1711 "%s: parent->dev_type = EDGE_DEV\n",
1712 __func__);
1713
1714 status = scic_remote_device_ea_construct(port->sci_port_handle,
1715 &isci_device->sci,
1716 (struct smp_response_discover *)&discover_response);
1717
1718 } else
1719 status = scic_remote_device_da_construct(port->sci_port_handle,
1720 &isci_device->sci);
1721 1626
1627 if (dev->parent && dev_is_expander(dev->parent))
1628 status = scic_remote_device_ea_construct(sci_port, &idev->sci);
1629 else
1630 status = scic_remote_device_da_construct(sci_port, &idev->sci);
1722 1631
1723 if (status != SCI_SUCCESS) { 1632 if (status != SCI_SUCCESS) {
1724 dev_dbg(&port->isci_host->pdev->dev, 1633 dev_dbg(&ihost->pdev->dev, "%s: construct failed: %d\n",
1725 "%s: scic_remote_device_da_construct failed - " 1634 __func__, status);
1726 "isci_device = %p\n",
1727 __func__,
1728 isci_device);
1729 1635
1730 return status; 1636 return status;
1731 } 1637 }
1732 1638
1733 /* XXX will be killed with sci_base_object removal */ 1639 /* XXX will be killed with sci_base_object removal */
1734 sci_object_set_association(&isci_device->sci, isci_device); 1640 sci_object_set_association(&idev->sci, idev);
1735 1641
1736 /* start the device. */ 1642 /* start the device. */
1737 status = scic_remote_device_start(&isci_device->sci, 1643 status = scic_remote_device_start(&idev->sci, ISCI_REMOTE_DEVICE_START_TIMEOUT);
1738 ISCI_REMOTE_DEVICE_START_TIMEOUT);
1739 1644
1740 if (status != SCI_SUCCESS) { 1645 if (status != SCI_SUCCESS)
1741 dev_warn(&port->isci_host->pdev->dev, 1646 dev_warn(&ihost->pdev->dev, "remote device start failed: %d\n",
1742 "%s: scic_remote_device_start failed\n", 1647 status);
1743 __func__);
1744 return status;
1745 }
1746 1648
1747 return status; 1649 return status;
1748} 1650}