isci: unify phy data structures
Make scic_sds_phy a member of isci_phy and merge their lifetimes which means removing the phy table from scic_sds_controller in favor of the one at that isci_host level. Reported-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
@@ -673,6 +673,7 @@ static void scic_sds_controller_phy_timer_stop(struct scic_sds_controller *scic)
|
|||||||
*/
|
*/
|
||||||
static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_controller *scic)
|
static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_controller *scic)
|
||||||
{
|
{
|
||||||
|
struct isci_host *ihost = scic_to_ihost(scic);
|
||||||
struct scic_sds_oem_params *oem = &scic->oem_parameters.sds1;
|
struct scic_sds_oem_params *oem = &scic->oem_parameters.sds1;
|
||||||
struct scic_sds_phy *sci_phy;
|
struct scic_sds_phy *sci_phy;
|
||||||
enum sci_status status;
|
enum sci_status status;
|
||||||
@@ -688,7 +689,7 @@ static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_contro
|
|||||||
u8 index;
|
u8 index;
|
||||||
|
|
||||||
for (index = 0; index < SCI_MAX_PHYS; index++) {
|
for (index = 0; index < SCI_MAX_PHYS; index++) {
|
||||||
sci_phy = &scic->phy_table[index];
|
sci_phy = &ihost->phys[index].sci;
|
||||||
state = sci_phy->state_machine.current_state_id;
|
state = sci_phy->state_machine.current_state_id;
|
||||||
|
|
||||||
if (!scic_sds_phy_get_port(sci_phy))
|
if (!scic_sds_phy_get_port(sci_phy))
|
||||||
@@ -719,7 +720,7 @@ static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_contro
|
|||||||
scic_sds_controller_phy_timer_stop(scic);
|
scic_sds_controller_phy_timer_stop(scic);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sci_phy = &scic->phy_table[scic->next_phy_to_start];
|
sci_phy = &ihost->phys[scic->next_phy_to_start].sci;
|
||||||
|
|
||||||
if (oem->controller.mode_type == SCIC_PORT_MANUAL_CONFIGURATION_MODE) {
|
if (oem->controller.mode_type == SCIC_PORT_MANUAL_CONFIGURATION_MODE) {
|
||||||
if (scic_sds_phy_get_port(sci_phy) == NULL) {
|
if (scic_sds_phy_get_port(sci_phy) == NULL) {
|
||||||
@@ -748,7 +749,7 @@ static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_contro
|
|||||||
"to stop phy %d because of status "
|
"to stop phy %d because of status "
|
||||||
"%d.\n",
|
"%d.\n",
|
||||||
__func__,
|
__func__,
|
||||||
scic->phy_table[scic->next_phy_to_start].phy_index,
|
ihost->phys[scic->next_phy_to_start].sci.phy_index,
|
||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,23 +793,22 @@ static enum sci_status scic_sds_controller_stop_phys(struct scic_sds_controller
|
|||||||
u32 index;
|
u32 index;
|
||||||
enum sci_status status;
|
enum sci_status status;
|
||||||
enum sci_status phy_status;
|
enum sci_status phy_status;
|
||||||
|
struct isci_host *ihost = scic_to_ihost(scic);
|
||||||
|
|
||||||
status = SCI_SUCCESS;
|
status = SCI_SUCCESS;
|
||||||
|
|
||||||
for (index = 0; index < SCI_MAX_PHYS; index++) {
|
for (index = 0; index < SCI_MAX_PHYS; index++) {
|
||||||
phy_status = scic_sds_phy_stop(&scic->phy_table[index]);
|
phy_status = scic_sds_phy_stop(&ihost->phys[index].sci);
|
||||||
|
|
||||||
if (
|
if (phy_status != SCI_SUCCESS &&
|
||||||
(phy_status != SCI_SUCCESS)
|
phy_status != SCI_FAILURE_INVALID_STATE) {
|
||||||
&& (phy_status != SCI_FAILURE_INVALID_STATE)
|
|
||||||
) {
|
|
||||||
status = SCI_FAILURE;
|
status = SCI_FAILURE;
|
||||||
|
|
||||||
dev_warn(scic_to_dev(scic),
|
dev_warn(scic_to_dev(scic),
|
||||||
"%s: Controller stop operation failed to stop "
|
"%s: Controller stop operation failed to stop "
|
||||||
"phy %d because of status %d.\n",
|
"phy %d because of status %d.\n",
|
||||||
__func__,
|
__func__,
|
||||||
scic->phy_table[index].phy_index, phy_status);
|
ihost->phys[index].sci.phy_index, phy_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,21 +1069,13 @@ static void scic_sds_controller_sdma_completion(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void scic_sds_controller_unsolicited_frame(struct scic_sds_controller *scic,
|
||||||
*
|
|
||||||
* @scic:
|
|
||||||
* @completion_entry:
|
|
||||||
*
|
|
||||||
* This method processes an unsolicited frame message. This is called from
|
|
||||||
* within the controller completion handler. none
|
|
||||||
*/
|
|
||||||
static void scic_sds_controller_unsolicited_frame(
|
|
||||||
struct scic_sds_controller *scic,
|
|
||||||
u32 completion_entry)
|
u32 completion_entry)
|
||||||
{
|
{
|
||||||
u32 index;
|
u32 index;
|
||||||
u32 frame_index;
|
u32 frame_index;
|
||||||
|
|
||||||
|
struct isci_host *ihost = scic_to_ihost(scic);
|
||||||
struct scu_unsolicited_frame_header *frame_header;
|
struct scu_unsolicited_frame_header *frame_header;
|
||||||
struct scic_sds_phy *phy;
|
struct scic_sds_phy *phy;
|
||||||
struct scic_sds_remote_device *device;
|
struct scic_sds_remote_device *device;
|
||||||
@@ -1092,10 +1084,8 @@ static void scic_sds_controller_unsolicited_frame(
|
|||||||
|
|
||||||
frame_index = SCU_GET_FRAME_INDEX(completion_entry);
|
frame_index = SCU_GET_FRAME_INDEX(completion_entry);
|
||||||
|
|
||||||
frame_header
|
frame_header = scic->uf_control.buffers.array[frame_index].header;
|
||||||
= scic->uf_control.buffers.array[frame_index].header;
|
scic->uf_control.buffers.array[frame_index].state = UNSOLICITED_FRAME_IN_USE;
|
||||||
scic->uf_control.buffers.array[frame_index].state
|
|
||||||
= UNSOLICITED_FRAME_IN_USE;
|
|
||||||
|
|
||||||
if (SCU_GET_FRAME_ERROR(completion_entry)) {
|
if (SCU_GET_FRAME_ERROR(completion_entry)) {
|
||||||
/*
|
/*
|
||||||
@@ -1108,10 +1098,8 @@ static void scic_sds_controller_unsolicited_frame(
|
|||||||
|
|
||||||
if (frame_header->is_address_frame) {
|
if (frame_header->is_address_frame) {
|
||||||
index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
|
index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
|
||||||
phy = &scic->phy_table[index];
|
phy = &ihost->phys[index].sci;
|
||||||
if (phy != NULL) {
|
|
||||||
result = scic_sds_phy_frame_handler(phy, frame_index);
|
result = scic_sds_phy_frame_handler(phy, frame_index);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
index = SCU_GET_COMPLETION_INDEX(completion_entry);
|
index = SCU_GET_COMPLETION_INDEX(completion_entry);
|
||||||
@@ -1122,7 +1110,7 @@ static void scic_sds_controller_unsolicited_frame(
|
|||||||
* device that has not yet been created. In either case forwared
|
* device that has not yet been created. In either case forwared
|
||||||
* the frame to the PE and let it take care of the frame data. */
|
* the frame to the PE and let it take care of the frame data. */
|
||||||
index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
|
index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
|
||||||
phy = &scic->phy_table[index];
|
phy = &ihost->phys[index].sci;
|
||||||
result = scic_sds_phy_frame_handler(phy, frame_index);
|
result = scic_sds_phy_frame_handler(phy, frame_index);
|
||||||
} else {
|
} else {
|
||||||
if (index < scic->remote_node_entries)
|
if (index < scic->remote_node_entries)
|
||||||
@@ -1144,21 +1132,14 @@ static void scic_sds_controller_unsolicited_frame(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void scic_sds_controller_event_completion(struct scic_sds_controller *scic,
|
||||||
* This method processes an event completion entry. This is called from within
|
|
||||||
* the controller completion handler.
|
|
||||||
* @scic:
|
|
||||||
* @completion_entry:
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void scic_sds_controller_event_completion(
|
|
||||||
struct scic_sds_controller *scic,
|
|
||||||
u32 completion_entry)
|
u32 completion_entry)
|
||||||
{
|
{
|
||||||
u32 index;
|
struct isci_host *ihost = scic_to_ihost(scic);
|
||||||
struct scic_sds_request *io_request;
|
struct scic_sds_request *io_request;
|
||||||
struct scic_sds_remote_device *device;
|
struct scic_sds_remote_device *device;
|
||||||
struct scic_sds_phy *phy;
|
struct scic_sds_phy *phy;
|
||||||
|
u32 index;
|
||||||
|
|
||||||
index = SCU_GET_COMPLETION_INDEX(completion_entry);
|
index = SCU_GET_COMPLETION_INDEX(completion_entry);
|
||||||
|
|
||||||
@@ -1237,7 +1218,7 @@ static void scic_sds_controller_event_completion(
|
|||||||
* we get the event notification. This is a type 4 event. */
|
* we get the event notification. This is a type 4 event. */
|
||||||
case SCU_EVENT_TYPE_OSSP_EVENT:
|
case SCU_EVENT_TYPE_OSSP_EVENT:
|
||||||
index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
|
index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
|
||||||
phy = &scic->phy_table[index];
|
phy = &ihost->phys[index].sci;
|
||||||
scic_sds_phy_event_handler(phy, completion_entry);
|
scic_sds_phy_event_handler(phy, completion_entry);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2154,38 +2135,6 @@ enum sci_task_status scic_controller_start_task(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* scic_controller_get_phy_handle() - This method simply provides the user with
|
|
||||||
* a unique handle for a given SAS/SATA phy index/identifier.
|
|
||||||
* @controller: This parameter represents the handle to the controller object
|
|
||||||
* from which to retrieve a phy (SAS or SATA) handle.
|
|
||||||
* @phy_index: This parameter specifies the phy index in the controller for
|
|
||||||
* which to retrieve the phy handle. 0 <= phy_index < maximum number of phys.
|
|
||||||
* @phy_handle: This parameter specifies the retrieved phy handle to be
|
|
||||||
* provided to the caller.
|
|
||||||
*
|
|
||||||
* Indicate if the retrieval of the phy handle was successful. SCI_SUCCESS This
|
|
||||||
* value is returned if the retrieval was successful. SCI_FAILURE_INVALID_PHY
|
|
||||||
* This value is returned if the supplied phy id is not in the supported range.
|
|
||||||
*/
|
|
||||||
enum sci_status scic_controller_get_phy_handle(
|
|
||||||
struct scic_sds_controller *scic,
|
|
||||||
u8 phy_index,
|
|
||||||
struct scic_sds_phy **phy_handle)
|
|
||||||
{
|
|
||||||
if (phy_index < ARRAY_SIZE(scic->phy_table)) {
|
|
||||||
*phy_handle = &scic->phy_table[phy_index];
|
|
||||||
|
|
||||||
return SCI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_err(scic_to_dev(scic),
|
|
||||||
"%s: Controller:0x%p PhyId:0x%x invalid phy index\n",
|
|
||||||
__func__, scic, phy_index);
|
|
||||||
|
|
||||||
return SCI_FAILURE_INVALID_PHY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scic_controller_allocate_io_tag() - This method will allocate a tag from the
|
* scic_controller_allocate_io_tag() - This method will allocate a tag from the
|
||||||
* pool of free IO tags. Direct allocation of IO tags by the SCI Core user
|
* pool of free IO tags. Direct allocation of IO tags by the SCI Core user
|
||||||
@@ -2724,7 +2673,7 @@ enum sci_status scic_controller_initialize(struct scic_sds_controller *scic)
|
|||||||
(result == SCI_SUCCESS) && (index < SCI_MAX_PHYS);
|
(result == SCI_SUCCESS) && (index < SCI_MAX_PHYS);
|
||||||
index++) {
|
index++) {
|
||||||
result = scic_sds_phy_initialize(
|
result = scic_sds_phy_initialize(
|
||||||
&scic->phy_table[index],
|
&ihost->phys[index].sci,
|
||||||
&scic->scu_registers->peg0.pe[index].tl,
|
&scic->scu_registers->peg0.pe[index].tl,
|
||||||
&scic->scu_registers->peg0.pe[index].ll);
|
&scic->scu_registers->peg0.pe[index].ll);
|
||||||
}
|
}
|
||||||
@@ -2979,6 +2928,7 @@ enum sci_status scic_controller_construct(struct scic_sds_controller *scic,
|
|||||||
void __iomem *scu_base,
|
void __iomem *scu_base,
|
||||||
void __iomem *smu_base)
|
void __iomem *smu_base)
|
||||||
{
|
{
|
||||||
|
struct isci_host *ihost = scic_to_ihost(scic);
|
||||||
u8 i;
|
u8 i;
|
||||||
|
|
||||||
sci_base_state_machine_construct(&scic->state_machine,
|
sci_base_state_machine_construct(&scic->state_machine,
|
||||||
@@ -3000,7 +2950,7 @@ enum sci_status scic_controller_construct(struct scic_sds_controller *scic,
|
|||||||
/* Construct the phys for this controller */
|
/* Construct the phys for this controller */
|
||||||
for (i = 0; i < SCI_MAX_PHYS; i++) {
|
for (i = 0; i < SCI_MAX_PHYS; i++) {
|
||||||
/* Add all the PHYs to the dummy port */
|
/* Add all the PHYs to the dummy port */
|
||||||
scic_sds_phy_construct(&scic->phy_table[i],
|
scic_sds_phy_construct(&ihost->phys[i].sci,
|
||||||
&scic->port_table[SCI_MAX_PORTS], i);
|
&scic->port_table[SCI_MAX_PORTS], i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -167,12 +167,6 @@ struct scic_sds_controller {
|
|||||||
*/
|
*/
|
||||||
struct scic_sds_port port_table[SCI_MAX_PORTS + 1];
|
struct scic_sds_port port_table[SCI_MAX_PORTS + 1];
|
||||||
|
|
||||||
/**
|
|
||||||
* This field is the array of phy objects that are controlled by this
|
|
||||||
* controller object.
|
|
||||||
*/
|
|
||||||
struct scic_sds_phy phy_table[SCI_MAX_PHYS];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This field is the array of device objects that are currently constructed
|
* This field is the array of device objects that are currently constructed
|
||||||
* for this controller object. This table is used as a fast lookup of device
|
* for this controller object. This table is used as a fast lookup of device
|
||||||
|
@@ -436,7 +436,7 @@ void scic_sds_phy_get_attached_sas_address(struct scic_sds_phy *sci_phy,
|
|||||||
struct sci_sas_address *sas_address)
|
struct sci_sas_address *sas_address)
|
||||||
{
|
{
|
||||||
struct sas_identify_frame *iaf;
|
struct sas_identify_frame *iaf;
|
||||||
struct isci_phy *iphy = sci_phy->iphy;
|
struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
|
||||||
|
|
||||||
iaf = &iphy->frame_rcvd.iaf;
|
iaf = &iphy->frame_rcvd.iaf;
|
||||||
memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE);
|
memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE);
|
||||||
@@ -1099,7 +1099,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler
|
|||||||
enum sci_status result;
|
enum sci_status result;
|
||||||
u32 *frame_words;
|
u32 *frame_words;
|
||||||
struct sas_identify_frame iaf;
|
struct sas_identify_frame iaf;
|
||||||
struct isci_phy *iphy = sci_phy->iphy;
|
struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
|
||||||
|
|
||||||
result = scic_sds_unsolicited_frame_control_get_header(
|
result = scic_sds_unsolicited_frame_control_get_header(
|
||||||
&(scic_sds_phy_get_controller(sci_phy)->uf_control),
|
&(scic_sds_phy_get_controller(sci_phy)->uf_control),
|
||||||
@@ -1164,7 +1164,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_frame_handle
|
|||||||
enum sci_status result;
|
enum sci_status result;
|
||||||
struct dev_to_host_fis *frame_header;
|
struct dev_to_host_fis *frame_header;
|
||||||
u32 *fis_frame_data;
|
u32 *fis_frame_data;
|
||||||
struct isci_phy *iphy = sci_phy->iphy;
|
struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
|
||||||
|
|
||||||
result = scic_sds_unsolicited_frame_control_get_header(
|
result = scic_sds_unsolicited_frame_control_get_header(
|
||||||
&(scic_sds_phy_get_controller(sci_phy)->uf_control),
|
&(scic_sds_phy_get_controller(sci_phy)->uf_control),
|
||||||
|
@@ -217,7 +217,6 @@ enum scic_sds_phy_protocol {
|
|||||||
SCIC_SDS_MAX_PHY_PROTOCOLS
|
SCIC_SDS_MAX_PHY_PROTOCOLS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct isci_phy;
|
|
||||||
/**
|
/**
|
||||||
* struct scic_sds_phy - This structure contains or references all of the data
|
* struct scic_sds_phy - This structure contains or references all of the data
|
||||||
* necessary to represent the core phy object and SCU harware protocol
|
* necessary to represent the core phy object and SCU harware protocol
|
||||||
@@ -226,11 +225,6 @@ struct isci_phy;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct scic_sds_phy {
|
struct scic_sds_phy {
|
||||||
/**
|
|
||||||
* This field depicts the peer object for the phy.
|
|
||||||
*/
|
|
||||||
struct isci_phy *iphy;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This field contains the information for the base phy state machine.
|
* This field contains the information for the base phy state machine.
|
||||||
*/
|
*/
|
||||||
|
@@ -645,7 +645,7 @@ void scic_sds_port_deactivate_phy(struct scic_sds_port *sci_port,
|
|||||||
struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port);
|
struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port);
|
||||||
struct isci_port *iport = sci_port->iport;
|
struct isci_port *iport = sci_port->iport;
|
||||||
struct isci_host *ihost = scic_to_ihost(scic);
|
struct isci_host *ihost = scic_to_ihost(scic);
|
||||||
struct isci_phy *iphy = sci_phy->iphy;
|
struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
|
||||||
|
|
||||||
sci_port->active_phy_mask &= ~(1 << sci_phy->phy_index);
|
sci_port->active_phy_mask &= ~(1 << sci_phy->phy_index);
|
||||||
|
|
||||||
|
@@ -170,32 +170,27 @@ static enum sci_status scic_sds_port_configuration_agent_validate_ports(
|
|||||||
struct scic_sds_controller *controller,
|
struct scic_sds_controller *controller,
|
||||||
struct scic_sds_port_configuration_agent *port_agent)
|
struct scic_sds_port_configuration_agent *port_agent)
|
||||||
{
|
{
|
||||||
|
struct isci_host *ihost = scic_to_ihost(controller);
|
||||||
struct sci_sas_address first_address;
|
struct sci_sas_address first_address;
|
||||||
struct sci_sas_address second_address;
|
struct sci_sas_address second_address;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check the max ranges for all the phys the max index
|
* Sanity check the max ranges for all the phys the max index
|
||||||
* is always equal to the port range index */
|
* is always equal to the port range index */
|
||||||
if (
|
if (port_agent->phy_valid_port_range[0].max_index != 0 ||
|
||||||
(port_agent->phy_valid_port_range[0].max_index != 0)
|
port_agent->phy_valid_port_range[1].max_index != 1 ||
|
||||||
|| (port_agent->phy_valid_port_range[1].max_index != 1)
|
port_agent->phy_valid_port_range[2].max_index != 2 ||
|
||||||
|| (port_agent->phy_valid_port_range[2].max_index != 2)
|
port_agent->phy_valid_port_range[3].max_index != 3)
|
||||||
|| (port_agent->phy_valid_port_range[3].max_index != 3)
|
|
||||||
) {
|
|
||||||
return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
|
return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a request to configure a single x4 port or at least attempt
|
* This is a request to configure a single x4 port or at least attempt
|
||||||
* to make all the phys into a single port */
|
* to make all the phys into a single port */
|
||||||
if (
|
if (port_agent->phy_valid_port_range[0].min_index == 0 &&
|
||||||
(port_agent->phy_valid_port_range[0].min_index == 0)
|
port_agent->phy_valid_port_range[1].min_index == 0 &&
|
||||||
&& (port_agent->phy_valid_port_range[1].min_index == 0)
|
port_agent->phy_valid_port_range[2].min_index == 0 &&
|
||||||
&& (port_agent->phy_valid_port_range[2].min_index == 0)
|
port_agent->phy_valid_port_range[3].min_index == 0)
|
||||||
&& (port_agent->phy_valid_port_range[3].min_index == 0)
|
|
||||||
) {
|
|
||||||
return SCI_SUCCESS;
|
return SCI_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a degenerate case where phy 1 and phy 2 are assigned
|
* This is a degenerate case where phy 1 and phy 2 are assigned
|
||||||
@@ -210,8 +205,8 @@ static enum sci_status scic_sds_port_configuration_agent_validate_ports(
|
|||||||
* PE0 and PE3 can never have the same SAS Address unless they
|
* PE0 and PE3 can never have the same SAS Address unless they
|
||||||
* are part of the same x4 wide port and we have already checked
|
* are part of the same x4 wide port and we have already checked
|
||||||
* for this condition. */
|
* for this condition. */
|
||||||
scic_sds_phy_get_sas_address(&controller->phy_table[0], &first_address);
|
scic_sds_phy_get_sas_address(&ihost->phys[0].sci, &first_address);
|
||||||
scic_sds_phy_get_sas_address(&controller->phy_table[3], &second_address);
|
scic_sds_phy_get_sas_address(&ihost->phys[3].sci, &second_address);
|
||||||
|
|
||||||
if (sci_sas_address_compare(first_address, second_address) == 0) {
|
if (sci_sas_address_compare(first_address, second_address) == 0) {
|
||||||
return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
|
return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
|
||||||
@@ -221,12 +216,10 @@ static enum sci_status scic_sds_port_configuration_agent_validate_ports(
|
|||||||
* PE0 and PE1 are configured into a 2x1 ports make sure that the
|
* PE0 and PE1 are configured into a 2x1 ports make sure that the
|
||||||
* SAS Address for PE0 and PE2 are different since they can not be
|
* SAS Address for PE0 and PE2 are different since they can not be
|
||||||
* part of the same port. */
|
* part of the same port. */
|
||||||
if (
|
if (port_agent->phy_valid_port_range[0].min_index == 0 &&
|
||||||
(port_agent->phy_valid_port_range[0].min_index == 0)
|
port_agent->phy_valid_port_range[1].min_index == 1) {
|
||||||
&& (port_agent->phy_valid_port_range[1].min_index == 1)
|
scic_sds_phy_get_sas_address(&ihost->phys[0].sci, &first_address);
|
||||||
) {
|
scic_sds_phy_get_sas_address(&ihost->phys[2].sci, &second_address);
|
||||||
scic_sds_phy_get_sas_address(&controller->phy_table[0], &first_address);
|
|
||||||
scic_sds_phy_get_sas_address(&controller->phy_table[2], &second_address);
|
|
||||||
|
|
||||||
if (sci_sas_address_compare(first_address, second_address) == 0) {
|
if (sci_sas_address_compare(first_address, second_address) == 0) {
|
||||||
return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
|
return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
|
||||||
@@ -237,12 +230,10 @@ static enum sci_status scic_sds_port_configuration_agent_validate_ports(
|
|||||||
* PE2 and PE3 are configured into a 2x1 ports make sure that the
|
* PE2 and PE3 are configured into a 2x1 ports make sure that the
|
||||||
* SAS Address for PE1 and PE3 are different since they can not be
|
* SAS Address for PE1 and PE3 are different since they can not be
|
||||||
* part of the same port. */
|
* part of the same port. */
|
||||||
if (
|
if (port_agent->phy_valid_port_range[2].min_index == 2 &&
|
||||||
(port_agent->phy_valid_port_range[2].min_index == 2)
|
port_agent->phy_valid_port_range[3].min_index == 3) {
|
||||||
&& (port_agent->phy_valid_port_range[3].min_index == 3)
|
scic_sds_phy_get_sas_address(&ihost->phys[1].sci, &first_address);
|
||||||
) {
|
scic_sds_phy_get_sas_address(&ihost->phys[3].sci, &second_address);
|
||||||
scic_sds_phy_get_sas_address(&controller->phy_table[1], &first_address);
|
|
||||||
scic_sds_phy_get_sas_address(&controller->phy_table[3], &second_address);
|
|
||||||
|
|
||||||
if (sci_sas_address_compare(first_address, second_address) == 0) {
|
if (sci_sas_address_compare(first_address, second_address) == 0) {
|
||||||
return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
|
return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
|
||||||
@@ -267,6 +258,7 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
|
|||||||
struct scic_sds_controller *controller,
|
struct scic_sds_controller *controller,
|
||||||
struct scic_sds_port_configuration_agent *port_agent)
|
struct scic_sds_port_configuration_agent *port_agent)
|
||||||
{
|
{
|
||||||
|
struct isci_host *ihost = scic_to_ihost(controller);
|
||||||
u32 phy_mask;
|
u32 phy_mask;
|
||||||
u32 assigned_phy_mask;
|
u32 assigned_phy_mask;
|
||||||
struct sci_sas_address sas_address;
|
struct sci_sas_address sas_address;
|
||||||
@@ -281,7 +273,8 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
|
|||||||
for (port_index = 0; port_index < SCI_MAX_PORTS; port_index++) {
|
for (port_index = 0; port_index < SCI_MAX_PORTS; port_index++) {
|
||||||
phy_mask = controller->oem_parameters.sds1.ports[port_index].phy_mask;
|
phy_mask = controller->oem_parameters.sds1.ports[port_index].phy_mask;
|
||||||
|
|
||||||
if (phy_mask != 0) {
|
if (!phy_mask)
|
||||||
|
continue;
|
||||||
/*
|
/*
|
||||||
* Make sure that one or more of the phys were not already assinged to
|
* Make sure that one or more of the phys were not already assinged to
|
||||||
* a different port. */
|
* a different port. */
|
||||||
@@ -291,10 +284,10 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
|
|||||||
|
|
||||||
/* Find the starting phy index for this round through the loop */
|
/* Find the starting phy index for this round through the loop */
|
||||||
for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) {
|
for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) {
|
||||||
if ((1 << phy_index) & phy_mask) {
|
if ((phy_mask & (1 << phy_index)) == 0)
|
||||||
scic_sds_phy_get_sas_address(
|
continue;
|
||||||
&controller->phy_table[phy_index], &sas_address
|
scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci,
|
||||||
);
|
&sas_address);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The phy_index can be used as the starting point for the
|
* The phy_index can be used as the starting point for the
|
||||||
@@ -309,7 +302,6 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See how many additional phys are being added to this logical port.
|
* See how many additional phys are being added to this logical port.
|
||||||
@@ -317,10 +309,10 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
|
|||||||
* compare the startting phy with itself.
|
* compare the startting phy with itself.
|
||||||
* This is expected and required to add the phy to the port. */
|
* This is expected and required to add the phy to the port. */
|
||||||
while (phy_index < SCI_MAX_PHYS) {
|
while (phy_index < SCI_MAX_PHYS) {
|
||||||
if ((1 << phy_index) & phy_mask) {
|
if ((phy_mask & (1 << phy_index)) == 0)
|
||||||
scic_sds_phy_get_sas_address(
|
continue;
|
||||||
&controller->phy_table[phy_index], &phy_assigned_address
|
scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci,
|
||||||
);
|
&phy_assigned_address);
|
||||||
|
|
||||||
if (sci_sas_address_compare(sas_address, phy_assigned_address) != 0) {
|
if (sci_sas_address_compare(sas_address, phy_assigned_address) != 0) {
|
||||||
/*
|
/*
|
||||||
@@ -332,18 +324,14 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
|
|||||||
port_agent->phy_valid_port_range[phy_index].min_index = port_index;
|
port_agent->phy_valid_port_range[phy_index].min_index = port_index;
|
||||||
port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
|
port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
|
||||||
|
|
||||||
scic_sds_port_add_phy(
|
scic_sds_port_add_phy(&controller->port_table[port_index],
|
||||||
&controller->port_table[port_index],
|
&ihost->phys[phy_index].sci);
|
||||||
&controller->phy_table[phy_index]
|
|
||||||
);
|
|
||||||
|
|
||||||
assigned_phy_mask |= (1 << phy_index);
|
assigned_phy_mask |= (1 << phy_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
phy_index++;
|
phy_index++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return scic_sds_port_configuration_agent_validate_ports(controller, port_agent);
|
return scic_sds_port_configuration_agent_validate_ports(controller, port_agent);
|
||||||
}
|
}
|
||||||
@@ -355,12 +343,12 @@ static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
|
|||||||
* device objects before a new series of link up notifications because a link
|
* device objects before a new series of link up notifications because a link
|
||||||
* down has allowed a better port configuration.
|
* down has allowed a better port configuration.
|
||||||
*/
|
*/
|
||||||
static void scic_sds_mpc_agent_timeout_handler(
|
static void scic_sds_mpc_agent_timeout_handler(void *object)
|
||||||
void *object)
|
|
||||||
{
|
{
|
||||||
u8 index;
|
u8 index;
|
||||||
struct scic_sds_controller *controller = (struct scic_sds_controller *)object;
|
struct scic_sds_controller *scic = object;
|
||||||
struct scic_sds_port_configuration_agent *port_agent = &controller->port_agent;
|
struct isci_host *ihost = scic_to_ihost(scic);
|
||||||
|
struct scic_sds_port_configuration_agent *port_agent = &scic->port_agent;
|
||||||
u16 configure_phy_mask;
|
u16 configure_phy_mask;
|
||||||
|
|
||||||
port_agent->timer_pending = false;
|
port_agent->timer_pending = false;
|
||||||
@@ -369,13 +357,12 @@ static void scic_sds_mpc_agent_timeout_handler(
|
|||||||
configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
|
configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
|
||||||
|
|
||||||
for (index = 0; index < SCI_MAX_PHYS; index++) {
|
for (index = 0; index < SCI_MAX_PHYS; index++) {
|
||||||
|
struct scic_sds_phy *sci_phy = &ihost->phys[index].sci;
|
||||||
|
|
||||||
if (configure_phy_mask & (1 << index)) {
|
if (configure_phy_mask & (1 << index)) {
|
||||||
port_agent->link_up_handler(
|
port_agent->link_up_handler(scic, port_agent,
|
||||||
controller,
|
scic_sds_phy_get_port(sci_phy),
|
||||||
port_agent,
|
sci_phy);
|
||||||
scic_sds_phy_get_port(&controller->phy_table[index]),
|
|
||||||
&controller->phy_table[index]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -489,6 +476,7 @@ static enum sci_status scic_sds_apc_agent_validate_phy_configuration(
|
|||||||
u8 port_index;
|
u8 port_index;
|
||||||
struct sci_sas_address sas_address;
|
struct sci_sas_address sas_address;
|
||||||
struct sci_sas_address phy_assigned_address;
|
struct sci_sas_address phy_assigned_address;
|
||||||
|
struct isci_host *ihost = scic_to_ihost(controller);
|
||||||
|
|
||||||
phy_index = 0;
|
phy_index = 0;
|
||||||
|
|
||||||
@@ -496,14 +484,12 @@ static enum sci_status scic_sds_apc_agent_validate_phy_configuration(
|
|||||||
port_index = phy_index;
|
port_index = phy_index;
|
||||||
|
|
||||||
/* Get the assigned SAS Address for the first PHY on the controller. */
|
/* Get the assigned SAS Address for the first PHY on the controller. */
|
||||||
scic_sds_phy_get_sas_address(
|
scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci,
|
||||||
&controller->phy_table[phy_index], &sas_address
|
&sas_address);
|
||||||
);
|
|
||||||
|
|
||||||
while (++phy_index < SCI_MAX_PHYS) {
|
while (++phy_index < SCI_MAX_PHYS) {
|
||||||
scic_sds_phy_get_sas_address(
|
scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci,
|
||||||
&controller->phy_table[phy_index], &phy_assigned_address
|
&phy_assigned_address);
|
||||||
);
|
|
||||||
|
|
||||||
/* Verify each of the SAS address are all the same for every PHY */
|
/* Verify each of the SAS address are all the same for every PHY */
|
||||||
if (sci_sas_address_compare(sas_address, phy_assigned_address) == 0) {
|
if (sci_sas_address_compare(sas_address, phy_assigned_address) == 0) {
|
||||||
@@ -739,33 +725,30 @@ static void scic_sds_apc_agent_link_down(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* configure the phys into ports when the timer fires */
|
||||||
*
|
static void scic_sds_apc_agent_timeout_handler(void *object)
|
||||||
*
|
|
||||||
* This routine will try to configure the phys into ports when the timer fires.
|
|
||||||
*/
|
|
||||||
static void scic_sds_apc_agent_timeout_handler(
|
|
||||||
void *object)
|
|
||||||
{
|
{
|
||||||
u32 index;
|
u32 index;
|
||||||
struct scic_sds_port_configuration_agent *port_agent;
|
struct scic_sds_port_configuration_agent *port_agent;
|
||||||
struct scic_sds_controller *controller = (struct scic_sds_controller *)object;
|
struct scic_sds_controller *scic = object;
|
||||||
|
struct isci_host *ihost = scic_to_ihost(scic);
|
||||||
u16 configure_phy_mask;
|
u16 configure_phy_mask;
|
||||||
|
|
||||||
port_agent = scic_sds_controller_get_port_configuration_agent(controller);
|
port_agent = scic_sds_controller_get_port_configuration_agent(scic);
|
||||||
|
|
||||||
port_agent->timer_pending = false;
|
port_agent->timer_pending = false;
|
||||||
|
|
||||||
configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
|
configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
|
||||||
|
|
||||||
if (configure_phy_mask != 0x00) {
|
if (!configure_phy_mask)
|
||||||
|
return;
|
||||||
|
|
||||||
for (index = 0; index < SCI_MAX_PHYS; index++) {
|
for (index = 0; index < SCI_MAX_PHYS; index++) {
|
||||||
if (configure_phy_mask & (1 << index)) {
|
if ((configure_phy_mask & (1 << index)) == 0)
|
||||||
scic_sds_apc_agent_configure_ports(
|
continue;
|
||||||
controller, port_agent, &controller->phy_table[index], false
|
|
||||||
);
|
scic_sds_apc_agent_configure_ports(scic, port_agent,
|
||||||
}
|
&ihost->phys[index].sci, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -63,61 +63,35 @@ struct scic_sds_phy;
|
|||||||
extern enum sci_status scic_sds_phy_start(struct scic_sds_phy *sci_phy);
|
extern enum sci_status scic_sds_phy_start(struct scic_sds_phy *sci_phy);
|
||||||
extern enum sci_status scic_sds_phy_stop(struct scic_sds_phy *sci_phy);
|
extern enum sci_status scic_sds_phy_stop(struct scic_sds_phy *sci_phy);
|
||||||
|
|
||||||
/**
|
void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
|
||||||
* isci_phy_init() - This function is called by the probe function to
|
|
||||||
* initialize the phy objects. This func assumes that the isci_port objects
|
|
||||||
* associated with the SCU have been initialized.
|
|
||||||
* @isci_phy: This parameter specifies the isci_phy object to initialize
|
|
||||||
* @isci_host: This parameter specifies the parent SCU host object for this
|
|
||||||
* isci_phy
|
|
||||||
* @index: This parameter specifies which SCU phy associates with this
|
|
||||||
* isci_phy. Generally, SCU phy 0 relates isci_phy 0, etc.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void isci_phy_init(
|
|
||||||
struct isci_phy *phy,
|
|
||||||
struct isci_host *isci_host,
|
|
||||||
int index)
|
|
||||||
{
|
{
|
||||||
struct scic_sds_phy *scic_phy;
|
|
||||||
union scic_oem_parameters oem;
|
union scic_oem_parameters oem;
|
||||||
enum sci_status status = SCI_SUCCESS;
|
u64 sci_sas_addr;
|
||||||
u64 sas_addr;
|
__be64 sas_addr;
|
||||||
|
|
||||||
/*--------------- SCU_Phy Initialization Stuff -----------------------*/
|
scic_oem_parameters_get(&ihost->sci, &oem);
|
||||||
|
sci_sas_addr = oem.sds1.phys[index].sas_address.high;
|
||||||
|
sci_sas_addr <<= 32;
|
||||||
|
sci_sas_addr |= oem.sds1.phys[index].sas_address.low;
|
||||||
|
sas_addr = cpu_to_be64(sci_sas_addr);
|
||||||
|
memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr));
|
||||||
|
|
||||||
status = scic_controller_get_phy_handle(&isci_host->sci, index, &scic_phy);
|
iphy->isci_port = NULL;
|
||||||
if (status == SCI_SUCCESS) {
|
iphy->sas_phy.enabled = 0;
|
||||||
phy->sci_phy_handle = scic_phy;
|
iphy->sas_phy.id = index;
|
||||||
scic_phy->iphy = phy;
|
iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
|
||||||
} else
|
iphy->sas_phy.frame_rcvd = (u8 *)&iphy->frame_rcvd;
|
||||||
dev_err(&isci_host->pdev->dev,
|
iphy->sas_phy.ha = &ihost->sas_ha;
|
||||||
"failed scic_controller_get_phy_handle\n");
|
iphy->sas_phy.lldd_phy = iphy;
|
||||||
|
iphy->sas_phy.enabled = 1;
|
||||||
scic_oem_parameters_get(&isci_host->sci, &oem);
|
iphy->sas_phy.class = SAS;
|
||||||
sas_addr = oem.sds1.phys[index].sas_address.high;
|
iphy->sas_phy.iproto = SAS_PROTOCOL_ALL;
|
||||||
sas_addr <<= 32;
|
iphy->sas_phy.tproto = 0;
|
||||||
sas_addr |= oem.sds1.phys[index].sas_address.low;
|
iphy->sas_phy.type = PHY_TYPE_PHYSICAL;
|
||||||
swab64s(&sas_addr);
|
iphy->sas_phy.role = PHY_ROLE_INITIATOR;
|
||||||
|
iphy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
|
||||||
memcpy(phy->sas_addr, &sas_addr, sizeof(sas_addr));
|
iphy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
|
||||||
|
memset(&iphy->frame_rcvd, 0, sizeof(iphy->frame_rcvd));
|
||||||
phy->isci_port = NULL;
|
|
||||||
phy->sas_phy.enabled = 0;
|
|
||||||
phy->sas_phy.id = index;
|
|
||||||
phy->sas_phy.sas_addr = &phy->sas_addr[0];
|
|
||||||
phy->sas_phy.frame_rcvd = (u8 *)&phy->frame_rcvd;
|
|
||||||
phy->sas_phy.ha = &isci_host->sas_ha;
|
|
||||||
phy->sas_phy.lldd_phy = phy;
|
|
||||||
phy->sas_phy.enabled = 1;
|
|
||||||
phy->sas_phy.class = SAS;
|
|
||||||
phy->sas_phy.iproto = SAS_PROTOCOL_ALL;
|
|
||||||
phy->sas_phy.tproto = 0;
|
|
||||||
phy->sas_phy.type = PHY_TYPE_PHYSICAL;
|
|
||||||
phy->sas_phy.role = PHY_ROLE_INITIATOR;
|
|
||||||
phy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
|
|
||||||
phy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
|
|
||||||
memset((u8 *)&phy->frame_rcvd, 0, sizeof(phy->frame_rcvd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -147,14 +121,14 @@ int isci_phy_control(struct asd_sas_phy *sas_phy,
|
|||||||
switch (func) {
|
switch (func) {
|
||||||
case PHY_FUNC_DISABLE:
|
case PHY_FUNC_DISABLE:
|
||||||
spin_lock_irqsave(&ihost->scic_lock, flags);
|
spin_lock_irqsave(&ihost->scic_lock, flags);
|
||||||
scic_sds_phy_stop(iphy->sci_phy_handle);
|
scic_sds_phy_stop(&iphy->sci);
|
||||||
spin_unlock_irqrestore(&ihost->scic_lock, flags);
|
spin_unlock_irqrestore(&ihost->scic_lock, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PHY_FUNC_LINK_RESET:
|
case PHY_FUNC_LINK_RESET:
|
||||||
spin_lock_irqsave(&ihost->scic_lock, flags);
|
spin_lock_irqsave(&ihost->scic_lock, flags);
|
||||||
scic_sds_phy_stop(iphy->sci_phy_handle);
|
scic_sds_phy_stop(&iphy->sci);
|
||||||
scic_sds_phy_start(iphy->sci_phy_handle);
|
scic_sds_phy_start(&iphy->sci);
|
||||||
spin_unlock_irqrestore(&ihost->scic_lock, flags);
|
spin_unlock_irqrestore(&ihost->scic_lock, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -54,24 +54,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if !defined(_ISCI_PHY_H_)
|
#ifndef _ISCI_PHY_H_
|
||||||
#define _ISCI_PHY_H_
|
#define _ISCI_PHY_H_
|
||||||
|
|
||||||
#include "port.h"
|
|
||||||
#include "host.h"
|
|
||||||
#include <scsi/sas.h>
|
#include <scsi/sas.h>
|
||||||
#include <scsi/libsas.h>
|
#include <scsi/libsas.h>
|
||||||
|
#include "scic_sds_phy.h"
|
||||||
|
#include "port.h"
|
||||||
/**
|
#include "host.h"
|
||||||
* struct isci_phy - This class implements the ISCI specific representation of
|
|
||||||
* the phy object.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct isci_phy {
|
struct isci_phy {
|
||||||
struct scic_sds_phy *sci_phy_handle;
|
struct scic_sds_phy sci;
|
||||||
struct asd_sas_phy sas_phy;
|
struct asd_sas_phy sas_phy;
|
||||||
struct isci_port *isci_port;
|
struct isci_port *isci_port;
|
||||||
u8 sas_addr[SAS_ADDR_SIZE];
|
u8 sas_addr[SAS_ADDR_SIZE];
|
||||||
@@ -82,17 +75,21 @@ struct isci_phy {
|
|||||||
} frame_rcvd;
|
} frame_rcvd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_isci_phy(p) \
|
static inline struct isci_phy *to_isci_phy(struct asd_sas_phy *sas_phy)
|
||||||
container_of(p, struct isci_phy, sas_phy);
|
{
|
||||||
|
struct isci_phy *iphy = container_of(sas_phy, typeof(*iphy), sas_phy);
|
||||||
|
|
||||||
void isci_phy_init(
|
return iphy;
|
||||||
struct isci_phy *phy,
|
}
|
||||||
struct isci_host *isci_host,
|
|
||||||
int index);
|
|
||||||
|
|
||||||
int isci_phy_control(
|
static inline struct isci_phy *sci_phy_to_iphy(struct scic_sds_phy *sci_phy)
|
||||||
struct asd_sas_phy *phy,
|
{
|
||||||
enum phy_func func,
|
struct isci_phy *iphy = container_of(sci_phy, typeof(*iphy), sci);
|
||||||
void *buf);
|
|
||||||
|
return iphy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index);
|
||||||
|
int isci_phy_control(struct asd_sas_phy *phy, enum phy_func func, void *buf);
|
||||||
|
|
||||||
#endif /* !defined(_ISCI_PHY_H_) */
|
#endif /* !defined(_ISCI_PHY_H_) */
|
||||||
|
@@ -120,44 +120,26 @@ static void isci_port_change_state(
|
|||||||
spin_unlock_irqrestore(&isci_port->state_lock, flags);
|
spin_unlock_irqrestore(&isci_port->state_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void isci_port_bc_change_received(
|
void isci_port_bc_change_received(struct isci_host *ihost,
|
||||||
struct isci_host *isci_host,
|
struct scic_sds_port *sci_port,
|
||||||
struct scic_sds_port *port,
|
struct scic_sds_phy *sci_phy)
|
||||||
struct scic_sds_phy *phy)
|
|
||||||
{
|
{
|
||||||
struct isci_phy *isci_phy = phy->iphy;
|
struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
|
||||||
|
|
||||||
dev_dbg(&isci_host->pdev->dev,
|
dev_dbg(&ihost->pdev->dev, "%s: iphy = %p, sas_phy = %p\n",
|
||||||
"%s: isci_phy = %p, sas_phy = %p\n",
|
__func__, iphy, &iphy->sas_phy);
|
||||||
__func__,
|
|
||||||
isci_phy,
|
|
||||||
&isci_phy->sas_phy);
|
|
||||||
|
|
||||||
isci_host->sas_ha.notify_port_event(
|
ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD);
|
||||||
&isci_phy->sas_phy,
|
scic_port_enable_broadcast_change_notification(sci_port);
|
||||||
PORTE_BROADCAST_RCVD
|
|
||||||
);
|
|
||||||
|
|
||||||
scic_port_enable_broadcast_change_notification(port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void isci_port_link_up(struct isci_host *isci_host,
|
||||||
* isci_port_link_up() - This function is called by the sci core when a link
|
|
||||||
* becomes active. the identify address frame is retrieved from the core and
|
|
||||||
* a notify port event is sent to libsas.
|
|
||||||
* @isci_host: This parameter specifies the isci host object.
|
|
||||||
* @port: This parameter specifies the sci port with the active link.
|
|
||||||
* @phy: This parameter specifies the sci phy with the active link.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void isci_port_link_up(
|
|
||||||
struct isci_host *isci_host,
|
|
||||||
struct scic_sds_port *port,
|
struct scic_sds_port *port,
|
||||||
struct scic_sds_phy *phy)
|
struct scic_sds_phy *phy)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct scic_port_properties properties;
|
struct scic_port_properties properties;
|
||||||
struct isci_phy *isci_phy = phy->iphy;
|
struct isci_phy *isci_phy = sci_phy_to_iphy(phy);
|
||||||
struct isci_port *isci_port = port->iport;
|
struct isci_port *isci_port = port->iport;
|
||||||
unsigned long success = true;
|
unsigned long success = true;
|
||||||
|
|
||||||
|
@@ -67,7 +67,7 @@ static inline struct device *scic_to_dev(struct scic_sds_controller *scic)
|
|||||||
|
|
||||||
static inline struct device *sciphy_to_dev(struct scic_sds_phy *sci_phy)
|
static inline struct device *sciphy_to_dev(struct scic_sds_phy *sci_phy)
|
||||||
{
|
{
|
||||||
struct isci_phy *iphy = sci_phy->iphy;
|
struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
|
||||||
|
|
||||||
if (!iphy || !iphy->isci_port || !iphy->isci_port->isci_host)
|
if (!iphy || !iphy->isci_port || !iphy->isci_port->isci_host)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Reference in New Issue
Block a user