From 00d680ef84570bc7aea023772d27e85b0052004c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 25 Apr 2011 14:29:29 -0700 Subject: [PATCH] isci: kill smp_discover_response An lldd need never look at the contents of an smp_discover_response frame. Kill the remaining locations where isci is looking at it: 1/ covering for expanders that do not set the stp_attached bit (already handled by sas_ex_discover_end_dev) 2/ an overkill method to notifiy the rest of the driver about remote_device sas addresses Signed-off-by: Dan Williams --- drivers/scsi/isci/core/intel_sas.h | 197 ------------------ drivers/scsi/isci/core/scic_sds_smp_request.c | 20 -- drivers/scsi/isci/remote_device.c | 138 ++---------- drivers/scsi/isci/remote_node_context.c | 5 +- 4 files changed, 23 insertions(+), 337 deletions(-) diff --git a/drivers/scsi/isci/core/intel_sas.h b/drivers/scsi/isci/core/intel_sas.h index d9c9f33a7af5..b57f39c2cfc2 100644 --- a/drivers/scsi/isci/core/intel_sas.h +++ b/drivers/scsi/isci/core/intel_sas.h @@ -628,202 +628,6 @@ struct smp_response_report_manufacturer_information { }; -#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 @@ -857,7 +661,6 @@ struct smp_response_vendor_specific { 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; }; diff --git a/drivers/scsi/isci/core/scic_sds_smp_request.c b/drivers/scsi/isci/core/scic_sds_smp_request.c index 1790f25758d1..d4009e57acaf 100644 --- a/drivers/scsi/isci/core/scic_sds_smp_request.c +++ b/drivers/scsi/isci/core/scic_sds_smp_request.c @@ -339,26 +339,6 @@ static enum sci_status scic_sds_smp_request_await_response_frame_handler( smp_response_buffer, sizeof(union smp_response_body) / sizeof(u32) ); - if (rsp_hdr->function == SMP_FUNCTION_DISCOVER) { - struct smp_response *smp_resp; - - smp_resp = (struct smp_response *)user_smp_buffer; - - /* - * Some expanders only report an attached SATA device, and - * not an STP target. Since the core depends on the STP - * target attribute to correctly build I/O, set the bit now - * if necessary. */ - if (smp_resp->response.discover.protocols.u.bits.attached_sata_device - && !smp_resp->response.discover.protocols.u.bits.attached_stp_target) { - smp_resp->response.discover.protocols.u.bits.attached_stp_target = 1; - - dev_dbg(scic_to_dev(sci_req->owning_controller), - "%s: scic_sds_smp_request_await_response_frame_handler(0x%p) Found SATA dev, setting STP bit.\n", - __func__, sci_req); - } - } - /* * Don't need to copy to user space. User instead will refer to * core request's response buffer. */ 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 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(). @@ -1559,17 +1546,14 @@ static void scic_sds_remote_device_get_info_from_smp_discover_response( * 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); @@ -1605,7 +1589,7 @@ static enum sci_status scic_remote_device_ea_construct(struct scic_sds_port *sci * 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; @@ -1632,117 +1616,35 @@ static enum sci_status scic_remote_device_start(struct scic_sds_remote_device *s 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; } diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c index 285232fd5e63..59f878f11f33 100644 --- a/drivers/scsi/isci/remote_node_context.c +++ b/drivers/scsi/isci/remote_node_context.c @@ -124,8 +124,9 @@ static void scic_sds_remote_node_context_construct_buffer( rnc->ssp.logical_port_index = scic_sds_remote_device_get_port_index(sci_dev); - rnc->ssp.remote_sas_address_hi = SCIC_SWAP_DWORD(sci_dev->device_address.high); - rnc->ssp.remote_sas_address_lo = SCIC_SWAP_DWORD(sci_dev->device_address.low); + /* address is always big endian, destination is always little */ + rnc->ssp.remote_sas_address_hi = swab32(sci_dev->device_address.high); + rnc->ssp.remote_sas_address_lo = swab32(sci_dev->device_address.low); rnc->ssp.nexus_loss_timer_enable = true; rnc->ssp.check_bit = false; -- 2.20.1