};
-#define SMP_RESPONSE_DISCOVER_FORMAT_1_1_SIZE 52
-#define SMP_RESPONSE_DISCOVER_FORMAT_2_SIZE 116
-
-/**
- * struct smp_discover_response_protocols - This structure depicts the discover
- * response where the supported protocols by the remote phy are specified.
- *
- * For specific information on each of these individual fields please reference
- * the SAS specification Link layer section on address frames.
- */
-struct smp_discover_response_protocols {
- union {
- struct {
- u16 attached_sata_host:1;
- u16 attached_smp_initiator:1;
- u16 attached_stp_initiator:1;
- u16 attached_ssp_initiator:1;
- u16 reserved3:4;
- u16 attached_sata_device:1;
- u16 attached_smp_target:1;
- u16 attached_stp_target:1;
- u16 attached_ssp_target:1;
- u16 reserved4:3;
- u16 attached_sata_port_selector:1;
- } bits;
-
- u16 all;
- } u;
-
-};
-
-/**
- * struct SMP_RESPONSE_DISCOVER_FORMAT - This structure defines the SMP phy
- * discover response format. It handles both SAS1.1 and SAS 2 definitions.
- * The unions indicate locations where the SAS specification versions differ
- * from one another.
- *
- *
- */
-struct smp_response_discover {
-
- union {
- struct {
- u8 reserved[2];
- } sas1_1;
-
- struct {
- u16 expander_change_count;
- } sas2;
-
- } u1;
-
- u8 reserved1[3];
- u8 phy_identifier;
- u8 reserved2[2];
-
- union {
- struct {
- u16 reserved1:4;
- u16 attached_device_type:3;
- u16 reserved2:1;
- u16 negotiated_physical_link_rate:4;
- u16 reserved3:4;
- } sas1_1;
-
- struct {
- u16 attached_reason:4;
- u16 attached_device_type:3;
- u16 reserved2:1;
- u16 negotiated_logical_link_rate:4;
- u16 reserved3:4;
- } sas2;
-
- } u2;
-
- struct smp_discover_response_protocols protocols;
- struct sci_sas_address sas_address;
- struct sci_sas_address attached_sas_address;
-
- u8 attached_phy_identifier;
-
- union {
- struct {
- u8 reserved;
- } sas1_1;
-
- struct {
- u8 attached_break_reply_capable:1;
- u8 attached_requested_inside_zpsds:1;
- u8 attached_inside_zpsds_persistent:1;
- u8 reserved1:5;
- } sas2;
-
- } u3;
-
- u8 reserved_for_identify[6];
-
- u32 hardware_min_physical_link_rate:4;
- u32 programmed_min_physical_link_rate:4;
- u32 hardware_max_physical_link_rate:4;
- u32 programmed_max_physical_link_rate:4;
- u32 phy_change_count:8;
- u32 partial_pathway_timeout_value:4;
- u32 reserved5:3;
- u32 virtual_phy:1;
-
- u32 routing_attribute:4;
- u32 reserved6:4;
- u32 connector_type:7;
- u32 reserved7:1;
- u32 connector_element_index:8;
- u32 connector_physical_link:8;
-
- u16 reserved8;
- u16 vendor_specific;
-
- union {
- struct {
- /**
- * In the SAS 1.1 specification this structure ends after 52 bytes.
- * As a result, the contents of this field should never have a
- * real value. It is undefined.
- */
- u8 undefined[SMP_RESPONSE_DISCOVER_FORMAT_2_SIZE
- - SMP_RESPONSE_DISCOVER_FORMAT_1_1_SIZE];
- } sas1_1;
-
- struct {
- struct sci_sas_address attached_device_name;
-
- u32 zoning_enabled:1;
- u32 inside_zpsds:1;
- u32 zone_group_persistent:1;
- u32 reserved1:1;
- u32 requested_inside_zpsds:1;
- u32 inside_zpsds_persistent:1;
- u32 requested_inside_zpsds_changed_by_expander:1;
- u32 reserved2:1;
- u32 reserved_for_zoning_fields:16;
- u32 zone_group:8;
-
- u8 self_configuration_status;
- u8 self_configuration_levels_completed;
- u16 reserved_for_self_config_fields;
-
- struct sci_sas_address self_configuration_sas_address;
-
- u32 programmed_phy_capabilities;
- u32 current_phy_capabilities;
- u32 attached_phy_capabilities;
-
- u32 reserved3;
-
- u32 reserved4:16;
- u32 negotiated_physical_link_rate:4;
- u32 reason:4;
- u32 hardware_muxing_supported:1;
- u32 negotiated_ssc:1;
- u32 reserved5:6;
-
- u32 default_zoning_enabled:1;
- u32 reserved6:1;
- u32 default_zone_group_persistent:1;
- u32 reserved7:1;
- u32 default_requested_inside_zpsds:1;
- u32 default_inside_zpsds_persistent:1;
- u32 reserved8:2;
- u32 reserved9:16;
- u32 default_zone_group:8;
-
- u32 saved_zoning_enabled:1;
- u32 reserved10:1;
- u32 saved_zone_group_persistent:1;
- u32 reserved11:1;
- u32 saved_requested_inside_zpsds:1;
- u32 saved_inside_zpsds_persistent:1;
- u32 reserved12:18;
- u32 saved_zone_group:8;
-
- u32 reserved14:2;
- u32 shadow_zone_group_persistent:1;
- u32 reserved15:1;
- u32 shadow_requested_inside_zpsds:1;
- u32 shadow_inside_zpsds_persistent:1;
- u32 reserved16:18;
- u32 shadow_zone_group:8;
-
- u8 device_slot_number;
- u8 device_slot_group_number;
- u8 device_slot_group_output_connector[6];
- } sas2;
-
- } u4;
-
-};
-
/**
* struct smp_response_report_phy_sata - This structure depicts the contents of
* the SAS SMP REPORT PHY SATA frame. For specific information on each of
union smp_response_body {
struct smp_response_report_general report_general;
struct smp_response_report_manufacturer_information report_manufacturer_information;
- struct smp_response_discover discover;
struct smp_response_report_phy_sata report_phy_sata;
struct smp_response_vendor_specific vendor_specific_response;
};
return SCI_SUCCESS;
}
-static void scic_sds_remote_device_get_info_from_smp_discover_response(
- struct scic_sds_remote_device *sci_dev,
- struct smp_response_discover *discover_response)
-{
- /* decode discover_response to set sas_address to sci_dev. */
- sci_dev->device_address.high =
- discover_response->attached_sas_address.high;
-
- sci_dev->device_address.low =
- discover_response->attached_sas_address.low;
-}
-
/**
* scic_remote_device_ea_construct() - construct expander attached device
- * @discover_response: data to build remote device
*
* Remote node context(s) is/are a global resource allocated by this
* routine, freed by scic_remote_device_destruct().
* SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
*/
static enum sci_status scic_remote_device_ea_construct(struct scic_sds_port *sci_port,
- struct scic_sds_remote_device *sci_dev,
- struct smp_response_discover *discover_response)
+ struct scic_sds_remote_device *sci_dev)
{
struct scic_sds_controller *scic = sci_port->owning_controller;
struct domain_device *dev = sci_dev_to_domain(sci_dev);
enum sci_status status;
scic_remote_device_construct(sci_port, sci_dev);
-
- scic_sds_remote_device_get_info_from_smp_discover_response(
- sci_dev, discover_response);
+ memcpy(&sci_dev->device_address, dev->sas_addr, SAS_ADDR_SIZE);
status = scic_sds_controller_allocate_remote_node_context(
scic, sci_dev, &sci_dev->rnc.remote_node_index);
* physical. Furthermore, the SAS-2 and SAS-1.1 fields overlay
* one another, so this code works for both situations. */
sci_dev->connection_rate = min_t(u16, scic_sds_port_get_max_allowed_speed(sci_port),
- discover_response->u2.sas1_1.negotiated_physical_link_rate);
+ dev->linkrate);
/* / @todo Should I assign the port width by reading all of the phys on the port? */
sci_dev->device_port_width = 1;
return sci_dev->state_handlers->start_handler(sci_dev);
}
-/**
- * isci_remote_device_construct() - This function calls the scic remote device
- * construct and start functions, it waits on the remote device start
- * completion.
- * @port: This parameter specifies the isci port with the remote device.
- * @isci_device: This parameter specifies the isci remote device
- *
- * status from the scic calls, the caller to this function should clean up
- * resources as appropriate.
- */
-static enum sci_status isci_remote_device_construct(
- struct isci_port *port,
- struct isci_remote_device *isci_device)
+static enum sci_status isci_remote_device_construct(struct isci_port *iport,
+ struct isci_remote_device *idev)
{
- enum sci_status status = SCI_SUCCESS;
-
- if (isci_device->domain_dev->parent &&
- dev_is_expander(isci_device->domain_dev->parent)) {
- int i;
-
- /* struct smp_response_discover discover_response; */
- struct discover_resp discover_response;
- struct domain_device *parent =
- isci_device->domain_dev->parent;
-
- struct expander_device *parent_ex = &parent->ex_dev;
-
- for (i = 0; i < parent_ex->num_phys; i++) {
-
- struct ex_phy *phy = &parent_ex->ex_phy[i];
-
- if ((phy->phy_state == PHY_VACANT) ||
- (phy->phy_state == PHY_NOT_PRESENT))
- continue;
-
- if (SAS_ADDR(phy->attached_sas_addr)
- == SAS_ADDR(isci_device->domain_dev->sas_addr)) {
-
- discover_response.attached_dev_type
- = phy->attached_dev_type;
- discover_response.linkrate
- = phy->linkrate;
- discover_response.attached_sata_host
- = phy->attached_sata_host;
- discover_response.attached_sata_dev
- = phy->attached_sata_dev;
- discover_response.attached_sata_ps
- = phy->attached_sata_ps;
- discover_response.iproto
- = phy->attached_iproto >> 1;
- discover_response.tproto
- = phy->attached_tproto >> 1;
- memcpy(
- discover_response.attached_sas_addr,
- phy->attached_sas_addr,
- SAS_ADDR_SIZE
- );
- discover_response.attached_phy_id
- = phy->attached_phy_id;
- discover_response.change_count
- = phy->phy_change_count;
- discover_response.routing_attr
- = phy->routing_attr;
- discover_response.hmin_linkrate
- = phy->phy->minimum_linkrate_hw;
- discover_response.hmax_linkrate
- = phy->phy->maximum_linkrate_hw;
- discover_response.pmin_linkrate
- = phy->phy->minimum_linkrate;
- discover_response.pmax_linkrate
- = phy->phy->maximum_linkrate;
- }
- }
-
-
- dev_dbg(&port->isci_host->pdev->dev,
- "%s: parent->dev_type = EDGE_DEV\n",
- __func__);
-
- status = scic_remote_device_ea_construct(port->sci_port_handle,
- &isci_device->sci,
- (struct smp_response_discover *)&discover_response);
-
- } else
- status = scic_remote_device_da_construct(port->sci_port_handle,
- &isci_device->sci);
+ struct scic_sds_port *sci_port = iport->sci_port_handle;
+ struct isci_host *ihost = iport->isci_host;
+ struct domain_device *dev = idev->domain_dev;
+ enum sci_status status;
+ if (dev->parent && dev_is_expander(dev->parent))
+ status = scic_remote_device_ea_construct(sci_port, &idev->sci);
+ else
+ status = scic_remote_device_da_construct(sci_port, &idev->sci);
if (status != SCI_SUCCESS) {
- dev_dbg(&port->isci_host->pdev->dev,
- "%s: scic_remote_device_da_construct failed - "
- "isci_device = %p\n",
- __func__,
- isci_device);
+ dev_dbg(&ihost->pdev->dev, "%s: construct failed: %d\n",
+ __func__, status);
return status;
}
/* XXX will be killed with sci_base_object removal */
- sci_object_set_association(&isci_device->sci, isci_device);
+ sci_object_set_association(&idev->sci, idev);
/* start the device. */
- status = scic_remote_device_start(&isci_device->sci,
- ISCI_REMOTE_DEVICE_START_TIMEOUT);
+ status = scic_remote_device_start(&idev->sci, ISCI_REMOTE_DEVICE_START_TIMEOUT);
- if (status != SCI_SUCCESS) {
- dev_warn(&port->isci_host->pdev->dev,
- "%s: scic_remote_device_start failed\n",
- __func__);
- return status;
- }
+ if (status != SCI_SUCCESS)
+ dev_warn(&ihost->pdev->dev, "remote device start failed: %d\n",
+ status);
return status;
}