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>
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c
index b595482..4ad3155 100644
--- a/drivers/scsi/isci/core/scic_sds_controller.c
+++ b/drivers/scsi/isci/core/scic_sds_controller.c
@@ -673,6 +673,7 @@
  */
 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_phy *sci_phy;
 	enum sci_status status;
@@ -688,7 +689,7 @@
 		u8 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;
 
 			if (!scic_sds_phy_get_port(sci_phy))
@@ -719,7 +720,7 @@
 			scic_sds_controller_phy_timer_stop(scic);
 		}
 	} 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 (scic_sds_phy_get_port(sci_phy) == NULL) {
@@ -748,7 +749,7 @@
 				 "to stop phy %d because of status "
 				 "%d.\n",
 				 __func__,
-				 scic->phy_table[scic->next_phy_to_start].phy_index,
+				 ihost->phys[scic->next_phy_to_start].sci.phy_index,
 				 status);
 		}
 
@@ -792,23 +793,22 @@
 	u32 index;
 	enum sci_status status;
 	enum sci_status phy_status;
+	struct isci_host *ihost = scic_to_ihost(scic);
 
 	status = SCI_SUCCESS;
 
 	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 (
-			(phy_status != SCI_SUCCESS)
-			&& (phy_status != SCI_FAILURE_INVALID_STATE)
-			) {
+		if (phy_status != SCI_SUCCESS &&
+		    phy_status != SCI_FAILURE_INVALID_STATE) {
 			status = SCI_FAILURE;
 
 			dev_warn(scic_to_dev(scic),
 				 "%s: Controller stop operation failed to stop "
 				 "phy %d because of status %d.\n",
 				 __func__,
-				 scic->phy_table[index].phy_index, phy_status);
+				 ihost->phys[index].sci.phy_index, phy_status);
 		}
 	}
 
@@ -1069,21 +1069,13 @@
 	}
 }
 
-/**
- *
- * @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)
+static void scic_sds_controller_unsolicited_frame(struct scic_sds_controller *scic,
+						  u32 completion_entry)
 {
 	u32 index;
 	u32 frame_index;
 
+	struct isci_host *ihost = scic_to_ihost(scic);
 	struct scu_unsolicited_frame_header *frame_header;
 	struct scic_sds_phy *phy;
 	struct scic_sds_remote_device *device;
@@ -1092,10 +1084,8 @@
 
 	frame_index = SCU_GET_FRAME_INDEX(completion_entry);
 
-	frame_header
-		= scic->uf_control.buffers.array[frame_index].header;
-	scic->uf_control.buffers.array[frame_index].state
-		= UNSOLICITED_FRAME_IN_USE;
+	frame_header = scic->uf_control.buffers.array[frame_index].header;
+	scic->uf_control.buffers.array[frame_index].state = UNSOLICITED_FRAME_IN_USE;
 
 	if (SCU_GET_FRAME_ERROR(completion_entry)) {
 		/*
@@ -1108,10 +1098,8 @@
 
 	if (frame_header->is_address_frame) {
 		index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
-		phy = &scic->phy_table[index];
-		if (phy != NULL) {
-			result = scic_sds_phy_frame_handler(phy, frame_index);
-		}
+		phy = &ihost->phys[index].sci;
+		result = scic_sds_phy_frame_handler(phy, frame_index);
 	} else {
 
 		index = SCU_GET_COMPLETION_INDEX(completion_entry);
@@ -1122,7 +1110,7 @@
 			 * 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. */
 			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);
 		} else {
 			if (index < scic->remote_node_entries)
@@ -1144,21 +1132,14 @@
 	}
 }
 
-/**
- * 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)
+static void scic_sds_controller_event_completion(struct scic_sds_controller *scic,
+						 u32 completion_entry)
 {
-	u32 index;
+	struct isci_host *ihost = scic_to_ihost(scic);
 	struct scic_sds_request *io_request;
 	struct scic_sds_remote_device *device;
 	struct scic_sds_phy *phy;
+	u32 index;
 
 	index = SCU_GET_COMPLETION_INDEX(completion_entry);
 
@@ -1237,7 +1218,7 @@
 	 * we get the event notification.  This is a type 4 event. */
 	case SCU_EVENT_TYPE_OSSP_EVENT:
 		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);
 		break;
 
@@ -2155,38 +2136,6 @@
 }
 
 /**
- * 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
  *    pool of free IO tags. Direct allocation of IO tags by the SCI Core user
  *    is optional. The scic_controller_start_io() method will allocate an IO
@@ -2724,7 +2673,7 @@
 		     (result == SCI_SUCCESS) && (index < SCI_MAX_PHYS);
 		     index++) {
 			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].ll);
 		}
@@ -2979,6 +2928,7 @@
 					  void __iomem *scu_base,
 					  void __iomem *smu_base)
 {
+	struct isci_host *ihost = scic_to_ihost(scic);
 	u8 i;
 
 	sci_base_state_machine_construct(&scic->state_machine,
@@ -3000,7 +2950,7 @@
 	/* Construct the phys for this controller */
 	for (i = 0; i < SCI_MAX_PHYS; i++) {
 		/* 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);
 	}
 
diff --git a/drivers/scsi/isci/core/scic_sds_controller.h b/drivers/scsi/isci/core/scic_sds_controller.h
index 0a9bb8b..aaaf15a 100644
--- a/drivers/scsi/isci/core/scic_sds_controller.h
+++ b/drivers/scsi/isci/core/scic_sds_controller.h
@@ -168,12 +168,6 @@
 	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
 	 * for this controller object.  This table is used as a fast lookup of device
 	 * objects that need to handle device completion notifications from the
diff --git a/drivers/scsi/isci/core/scic_sds_phy.c b/drivers/scsi/isci/core/scic_sds_phy.c
index 8f1e3db..f0f4c74 100644
--- a/drivers/scsi/isci/core/scic_sds_phy.c
+++ b/drivers/scsi/isci/core/scic_sds_phy.c
@@ -436,7 +436,7 @@
 					   struct sci_sas_address *sas_address)
 {
 	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;
 	memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE);
@@ -1099,7 +1099,7 @@
 	enum sci_status result;
 	u32 *frame_words;
 	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(
 		&(scic_sds_phy_get_controller(sci_phy)->uf_control),
@@ -1164,7 +1164,7 @@
 	enum sci_status result;
 	struct dev_to_host_fis *frame_header;
 	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(
 		&(scic_sds_phy_get_controller(sci_phy)->uf_control),
diff --git a/drivers/scsi/isci/core/scic_sds_phy.h b/drivers/scsi/isci/core/scic_sds_phy.h
index b6a0ed1..c40c09b 100644
--- a/drivers/scsi/isci/core/scic_sds_phy.h
+++ b/drivers/scsi/isci/core/scic_sds_phy.h
@@ -217,7 +217,6 @@
 	SCIC_SDS_MAX_PHY_PROTOCOLS
 };
 
-struct isci_phy;
 /**
  * struct scic_sds_phy - This structure  contains or references all of the data
  *    necessary to represent the core phy object and SCU harware protocol
@@ -227,11 +226,6 @@
  */
 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.
 	 */
 	struct sci_base_state_machine state_machine;
diff --git a/drivers/scsi/isci/core/scic_sds_port.c b/drivers/scsi/isci/core/scic_sds_port.c
index e1c8734..84b8abb 100644
--- a/drivers/scsi/isci/core/scic_sds_port.c
+++ b/drivers/scsi/isci/core/scic_sds_port.c
@@ -645,7 +645,7 @@
 	struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port);
 	struct isci_port *iport = sci_port->iport;
 	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);
 
diff --git a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c
index 6b2fb44..aa7ac95 100644
--- a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c
+++ b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c
@@ -170,32 +170,27 @@
 	struct scic_sds_controller *controller,
 	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 second_address;
 
 	/*
 	 * Sanity check the max ranges for all the phys the max index
 	 * is always equal to the port range index */
-	if (
-		(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[2].max_index != 2)
-		|| (port_agent->phy_valid_port_range[3].max_index != 3)
-		) {
+	if (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[2].max_index != 2 ||
+	    port_agent->phy_valid_port_range[3].max_index != 3)
 		return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
-	}
 
 	/*
 	 * This is a request to configure a single x4 port or at least attempt
 	 * to make all the phys into a single port */
-	if (
-		(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[2].min_index == 0)
-		&& (port_agent->phy_valid_port_range[3].min_index == 0)
-		) {
+	if (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[2].min_index == 0 &&
+	    port_agent->phy_valid_port_range[3].min_index == 0)
 		return SCI_SUCCESS;
-	}
 
 	/*
 	 * This is a degenerate case where phy 1 and phy 2 are assigned
@@ -210,8 +205,8 @@
 	 * 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
 	 * for this condition. */
-	scic_sds_phy_get_sas_address(&controller->phy_table[0], &first_address);
-	scic_sds_phy_get_sas_address(&controller->phy_table[3], &second_address);
+	scic_sds_phy_get_sas_address(&ihost->phys[0].sci, &first_address);
+	scic_sds_phy_get_sas_address(&ihost->phys[3].sci, &second_address);
 
 	if (sci_sas_address_compare(first_address, second_address) == 0) {
 		return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
@@ -221,12 +216,10 @@
 	 * 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
 	 * part of the same port. */
-	if (
-		(port_agent->phy_valid_port_range[0].min_index == 0)
-		&& (port_agent->phy_valid_port_range[1].min_index == 1)
-		) {
-		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 (port_agent->phy_valid_port_range[0].min_index == 0 &&
+	    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);
 
 		if (sci_sas_address_compare(first_address, second_address) == 0) {
 			return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
@@ -237,12 +230,10 @@
 	 * 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
 	 * part of the same port. */
-	if (
-		(port_agent->phy_valid_port_range[2].min_index == 2)
-		&& (port_agent->phy_valid_port_range[3].min_index == 3)
-		) {
-		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 (port_agent->phy_valid_port_range[2].min_index == 2 &&
+	    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);
 
 		if (sci_sas_address_compare(first_address, second_address) == 0) {
 			return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
@@ -267,6 +258,7 @@
 	struct scic_sds_controller *controller,
 	struct scic_sds_port_configuration_agent *port_agent)
 {
+	struct isci_host *ihost = scic_to_ihost(controller);
 	u32 phy_mask;
 	u32 assigned_phy_mask;
 	struct sci_sas_address sas_address;
@@ -281,68 +273,64 @@
 	for (port_index = 0; port_index < SCI_MAX_PORTS; port_index++) {
 		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
+		 * a different port. */
+		if ((phy_mask & ~assigned_phy_mask) == 0) {
+			return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+		}
+
+		/* Find the starting phy index for this round through the loop */
+		for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) {
+			if ((phy_mask & (1 << phy_index)) == 0)
+				continue;
+			scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci,
+						     &sas_address);
+
 			/*
-			 * Make sure that one or more of the phys were not already assinged to
-			 * a different port. */
-			if ((phy_mask & ~assigned_phy_mask) == 0) {
+			 * The phy_index can be used as the starting point for the
+			 * port range since the hardware starts all logical ports
+			 * the same as the PE 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;
+
+			if (phy_index != port_index) {
 				return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
 			}
 
-			/* Find the starting phy index for this round through the loop */
-			for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) {
-				if ((1 << phy_index) & phy_mask) {
-					scic_sds_phy_get_sas_address(
-						&controller->phy_table[phy_index], &sas_address
-						);
-
-					/*
-					 * The phy_index can be used as the starting point for the
-					 * port range since the hardware starts all logical ports
-					 * the same as the PE 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;
-
-					if (phy_index != port_index) {
-						return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
-					}
-
-					break;
-				}
-			}
-
-			/*
-			 * See how many additional phys are being added to this logical port.
-			 * Note: We have not moved the current phy_index so we will actually
-			 *       compare the startting phy with itself.
-			 *       This is expected and required to add the phy to the port. */
-			while (phy_index < SCI_MAX_PHYS) {
-				if ((1 << phy_index) & phy_mask) {
-					scic_sds_phy_get_sas_address(
-						&controller->phy_table[phy_index], &phy_assigned_address
-						);
-
-					if (sci_sas_address_compare(sas_address, phy_assigned_address) != 0) {
-						/*
-						 * The phy mask specified that this phy is part of the same port
-						 * as the starting phy and it is not so fail this configuration */
-						return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
-					}
-
-					port_agent->phy_valid_port_range[phy_index].min_index = port_index;
-					port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
-
-					scic_sds_port_add_phy(
-						&controller->port_table[port_index],
-						&controller->phy_table[phy_index]
-						);
-
-					assigned_phy_mask |= (1 << phy_index);
-				}
-
-				phy_index++;
-			}
+			break;
 		}
+
+		/*
+		 * See how many additional phys are being added to this logical port.
+		 * Note: We have not moved the current phy_index so we will actually
+		 *       compare the startting phy with itself.
+		 *       This is expected and required to add the phy to the port. */
+		while (phy_index < SCI_MAX_PHYS) {
+			if ((phy_mask & (1 << phy_index)) == 0)
+				continue;
+			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) {
+				/*
+				 * The phy mask specified that this phy is part of the same port
+				 * as the starting phy and it is not so fail this configuration */
+				return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+			}
+
+			port_agent->phy_valid_port_range[phy_index].min_index = port_index;
+			port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
+
+			scic_sds_port_add_phy(&controller->port_table[port_index],
+					      &ihost->phys[phy_index].sci);
+
+			assigned_phy_mask |= (1 << phy_index);
+		}
+
+		phy_index++;
 	}
 
 	return scic_sds_port_configuration_agent_validate_ports(controller, port_agent);
@@ -355,12 +343,12 @@
  * device objects before a new series of link up notifications because a link
  * down has allowed a better port configuration.
  */
-static void scic_sds_mpc_agent_timeout_handler(
-	void *object)
+static void scic_sds_mpc_agent_timeout_handler(void *object)
 {
 	u8 index;
-	struct scic_sds_controller *controller = (struct scic_sds_controller *)object;
-	struct scic_sds_port_configuration_agent *port_agent = &controller->port_agent;
+	struct scic_sds_controller *scic = object;
+	struct isci_host *ihost = scic_to_ihost(scic);
+	struct scic_sds_port_configuration_agent *port_agent = &scic->port_agent;
 	u16 configure_phy_mask;
 
 	port_agent->timer_pending = false;
@@ -369,13 +357,12 @@
 	configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
 
 	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		struct scic_sds_phy *sci_phy = &ihost->phys[index].sci;
+
 		if (configure_phy_mask & (1 << index)) {
-			port_agent->link_up_handler(
-				controller,
-				port_agent,
-				scic_sds_phy_get_port(&controller->phy_table[index]),
-				&controller->phy_table[index]
-				);
+			port_agent->link_up_handler(scic, port_agent,
+						    scic_sds_phy_get_port(sci_phy),
+						    sci_phy);
 		}
 	}
 }
@@ -489,6 +476,7 @@
 	u8 port_index;
 	struct sci_sas_address sas_address;
 	struct sci_sas_address phy_assigned_address;
+	struct isci_host *ihost = scic_to_ihost(controller);
 
 	phy_index = 0;
 
@@ -496,14 +484,12 @@
 		port_index = phy_index;
 
 		/* Get the assigned SAS Address for the first PHY on the controller. */
-		scic_sds_phy_get_sas_address(
-			&controller->phy_table[phy_index], &sas_address
-			);
+		scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci,
+					    &sas_address);
 
 		while (++phy_index < SCI_MAX_PHYS) {
-			scic_sds_phy_get_sas_address(
-				&controller->phy_table[phy_index], &phy_assigned_address
-				);
+			scic_sds_phy_get_sas_address(&ihost->phys[phy_index].sci,
+						     &phy_assigned_address);
 
 			/* Verify each of the SAS address are all the same for every PHY */
 			if (sci_sas_address_compare(sas_address, phy_assigned_address) == 0) {
@@ -739,33 +725,30 @@
 	}
 }
 
-/**
- *
- *
- * This routine will try to configure the phys into ports when the timer fires.
- */
-static void scic_sds_apc_agent_timeout_handler(
-	void *object)
+/* configure the phys into ports when the timer fires */
+static void scic_sds_apc_agent_timeout_handler(void *object)
 {
 	u32 index;
 	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;
 
-	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;
 
 	configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
 
-	if (configure_phy_mask != 0x00) {
-		for (index = 0; index < SCI_MAX_PHYS; index++) {
-			if (configure_phy_mask & (1 << index)) {
-				scic_sds_apc_agent_configure_ports(
-					controller, port_agent, &controller->phy_table[index], false
-					);
-			}
-		}
+	if (!configure_phy_mask)
+		return;
+
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		if ((configure_phy_mask & (1 << index)) == 0)
+			continue;
+
+		scic_sds_apc_agent_configure_ports(scic, port_agent,
+						   &ihost->phys[index].sci, false);
 	}
 }
 
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index 160790a..3280049 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -63,61 +63,35 @@
 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);
 
-/**
- * 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)
+void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
 {
-	struct scic_sds_phy *scic_phy;
 	union scic_oem_parameters oem;
-	enum sci_status status = SCI_SUCCESS;
-	u64 sas_addr;
+	u64 sci_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);
-	if (status == SCI_SUCCESS) {
-		phy->sci_phy_handle = scic_phy;
-		scic_phy->iphy = phy;
-	} else
-		dev_err(&isci_host->pdev->dev,
-			"failed scic_controller_get_phy_handle\n");
-
-	scic_oem_parameters_get(&isci_host->sci, &oem);
-	sas_addr = oem.sds1.phys[index].sas_address.high;
-	sas_addr <<= 32;
-	sas_addr |= oem.sds1.phys[index].sas_address.low;
-	swab64s(&sas_addr);
-
-	memcpy(phy->sas_addr, &sas_addr, sizeof(sas_addr));
-
-	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));
+	iphy->isci_port = NULL;
+	iphy->sas_phy.enabled = 0;
+	iphy->sas_phy.id = index;
+	iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
+	iphy->sas_phy.frame_rcvd = (u8 *)&iphy->frame_rcvd;
+	iphy->sas_phy.ha = &ihost->sas_ha;
+	iphy->sas_phy.lldd_phy = iphy;
+	iphy->sas_phy.enabled = 1;
+	iphy->sas_phy.class = SAS;
+	iphy->sas_phy.iproto = SAS_PROTOCOL_ALL;
+	iphy->sas_phy.tproto = 0;
+	iphy->sas_phy.type = PHY_TYPE_PHYSICAL;
+	iphy->sas_phy.role = PHY_ROLE_INITIATOR;
+	iphy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
+	iphy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
+	memset(&iphy->frame_rcvd, 0, sizeof(iphy->frame_rcvd));
 }
 
 
@@ -147,14 +121,14 @@
 	switch (func) {
 	case PHY_FUNC_DISABLE:
 		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);
 		break;
 
 	case PHY_FUNC_LINK_RESET:
 		spin_lock_irqsave(&ihost->scic_lock, flags);
-		scic_sds_phy_stop(iphy->sci_phy_handle);
-		scic_sds_phy_start(iphy->sci_phy_handle);
+		scic_sds_phy_stop(&iphy->sci);
+		scic_sds_phy_start(&iphy->sci);
 		spin_unlock_irqrestore(&ihost->scic_lock, flags);
 		break;
 
diff --git a/drivers/scsi/isci/phy.h b/drivers/scsi/isci/phy.h
index 21f6050..93ec2d4 100644
--- a/drivers/scsi/isci/phy.h
+++ b/drivers/scsi/isci/phy.h
@@ -54,24 +54,17 @@
  */
 
 
-#if !defined(_ISCI_PHY_H_)
+#ifndef _ISCI_PHY_H_
 #define _ISCI_PHY_H_
 
-#include "port.h"
-#include "host.h"
 #include <scsi/sas.h>
 #include <scsi/libsas.h>
-
-
-/**
- * struct isci_phy - This class implements the ISCI specific representation of
- *    the phy object.
- *
- *
- */
+#include "scic_sds_phy.h"
+#include "port.h"
+#include "host.h"
 
 struct isci_phy {
-	struct scic_sds_phy *sci_phy_handle;
+	struct scic_sds_phy sci;
 	struct asd_sas_phy sas_phy;
 	struct isci_port *isci_port;
 	u8 sas_addr[SAS_ADDR_SIZE];
@@ -82,17 +75,21 @@
 	} frame_rcvd;
 };
 
-#define to_isci_phy(p)	\
-	container_of(p, struct isci_phy, sas_phy);
+static inline struct isci_phy *to_isci_phy(struct asd_sas_phy *sas_phy)
+{
+	struct isci_phy *iphy = container_of(sas_phy, typeof(*iphy), sas_phy);
 
-void isci_phy_init(
-	struct isci_phy *phy,
-	struct isci_host *isci_host,
-	int index);
+	return iphy;
+}
 
-int isci_phy_control(
-	struct asd_sas_phy *phy,
-	enum phy_func func,
-	void *buf);
+static inline struct isci_phy *sci_phy_to_iphy(struct scic_sds_phy *sci_phy)
+{
+	struct isci_phy *iphy = container_of(sci_phy, typeof(*iphy), sci);
+
+	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_) */
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index 6110306..5e87fed 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -120,44 +120,26 @@
 	spin_unlock_irqrestore(&isci_port->state_lock, flags);
 }
 
-void isci_port_bc_change_received(
-	struct isci_host *isci_host,
-	struct scic_sds_port *port,
-	struct scic_sds_phy *phy)
+void isci_port_bc_change_received(struct isci_host *ihost,
+				  struct scic_sds_port *sci_port,
+				  struct scic_sds_phy *sci_phy)
 {
-	struct isci_phy *isci_phy = phy->iphy;
+	struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
 
-	dev_dbg(&isci_host->pdev->dev,
-		"%s: isci_phy = %p, sas_phy = %p\n",
-		__func__,
-		isci_phy,
-		&isci_phy->sas_phy);
+	dev_dbg(&ihost->pdev->dev, "%s: iphy = %p, sas_phy = %p\n",
+		__func__, iphy, &iphy->sas_phy);
 
-	isci_host->sas_ha.notify_port_event(
-		&isci_phy->sas_phy,
-		PORTE_BROADCAST_RCVD
-		);
-
-	scic_port_enable_broadcast_change_notification(port);
+	ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD);
+	scic_port_enable_broadcast_change_notification(sci_port);
 }
 
-/**
- * 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_phy *phy)
+void isci_port_link_up(struct isci_host *isci_host,
+		       struct scic_sds_port *port,
+		       struct scic_sds_phy *phy)
 {
 	unsigned long flags;
 	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;
 	unsigned long success = true;
 
diff --git a/drivers/scsi/isci/sci_environment.h b/drivers/scsi/isci/sci_environment.h
index 8394f60..bb07ed3 100644
--- a/drivers/scsi/isci/sci_environment.h
+++ b/drivers/scsi/isci/sci_environment.h
@@ -67,7 +67,7 @@
 
 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)
 		return NULL;