Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9dcb4ba authored by Dan Williams's avatar Dan Williams
Browse files

isci: unify isci_host and scic_sds_controller



Remove the distinction between these two implementations and unify on
isci_host (local instances named ihost).  Hmmm, we had two
'oem_parameters' instances, one was unused... nice.

Reported-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 78a6f06e
Loading
Loading
Loading
Loading
+489 −511

File changed.

Preview size limit exceeded, changes collapsed.

+46 −164
Original line number Original line Diff line number Diff line
@@ -106,7 +106,7 @@ struct scic_power_control {
};
};


struct scic_sds_port_configuration_agent;
struct scic_sds_port_configuration_agent;
typedef void (*port_config_fn)(struct scic_sds_controller *,
typedef void (*port_config_fn)(struct isci_host *,
			       struct scic_sds_port_configuration_agent *,
			       struct scic_sds_port_configuration_agent *,
			       struct isci_port *, struct isci_phy *);
			       struct isci_port *, struct isci_phy *);


@@ -124,171 +124,66 @@ struct scic_sds_port_configuration_agent {
};
};


/**
/**
 * struct scic_sds_controller -
 * isci_host - primary host/controller object
 *
 * @timer: timeout start/stop operations
 * This structure represents the SCU controller object.
 * @device_table: rni (hw remote node index) to remote device lookup table
 */
 * @available_remote_nodes: rni allocator
struct scic_sds_controller {
 * @power_control: manage device spin up
	/**
 * @io_request_sequence: generation number for tci's (task contexts)
	 * This field contains the information for the base controller state
 * @task_context_table: hw task context table
	 * machine.
 * @remote_node_context_table: hw remote node context table
	 */
 * @completion_queue: hw-producer driver-consumer communication ring
	struct sci_base_state_machine sm;
 * @completion_queue_get: tracks the driver 'head' of the ring to notify hw
 * @logical_port_entries: min({driver|silicon}-supported-port-count)
 * @remote_node_entries: min({driver|silicon}-supported-node-count)
 * @task_context_entries: min({driver|silicon}-supported-task-count)
 * @phy_timer: phy startup timer
 * @invalid_phy_mask: if an invalid_link_up notification is reported a bit for
 * 		      the phy index is set so further notifications are not
 * 		      made.  Once the phy reports link up and is made part of a
 * 		      port then this bit is cleared.


	/**
	 * Timer for controller start/stop operations.
 */
 */
struct isci_host {
	struct sci_base_state_machine sm;
	/* XXX can we time this externally */
	struct sci_timer timer;
	struct sci_timer timer;

	/* XXX drop reference module params directly */
	/**
	 * This field contains the user parameters to be utilized for this
	 * core controller object.
	 */
	union scic_user_parameters user_parameters;
	union scic_user_parameters user_parameters;

	/* XXX no need to be a union */
	/**
	 * This field contains the OEM parameters to be utilized for this
	 * core controller object.
	 */
	union scic_oem_parameters oem_parameters;
	union scic_oem_parameters oem_parameters;

	/**
	 * This field contains the port configuration agent for this controller.
	 */
	struct scic_sds_port_configuration_agent port_agent;
	struct scic_sds_port_configuration_agent port_agent;

	/**
	 * 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
	 * hardware. The table is RNi based.
	 */
	struct isci_remote_device *device_table[SCI_MAX_REMOTE_DEVICES];
	struct isci_remote_device *device_table[SCI_MAX_REMOTE_DEVICES];

	/**
	 * This field is the free RNi data structure
	 */
	struct scic_remote_node_table available_remote_nodes;
	struct scic_remote_node_table available_remote_nodes;

	/**
	 * This filed is the struct scic_power_control data used to controll when direct
	 * attached devices can consume power.
	 */
	struct scic_power_control power_control;
	struct scic_power_control power_control;

	/* sequence number per tci */
	u8 io_request_sequence[SCI_MAX_IO_REQUESTS];
	u8 io_request_sequence[SCI_MAX_IO_REQUESTS];

	/**
	 * This field is a pointer to the memory allocated by the driver for the task
	 * context table.  This data is shared between the hardware and software.
	 */
	struct scu_task_context *task_context_table;
	struct scu_task_context *task_context_table;
	dma_addr_t task_context_dma;
	dma_addr_t task_context_dma;

	/**
	 * This field is a pointer to the memory allocated by the driver for the
	 * remote node context table.  This table is shared between the hardware and
	 * software.
	 */
	union scu_remote_node_context *remote_node_context_table;
	union scu_remote_node_context *remote_node_context_table;

	/**
	 * This field is a pointer to the completion queue.  This memory is
	 * written to by the hardware and read by the software.
	 */
	u32 *completion_queue;
	u32 *completion_queue;

	/**
	 * This field is the software copy of the completion queue get pointer.  The
	 * controller object writes this value to the hardware after processing the
	 * completion entries.
	 */
	u32 completion_queue_get;
	u32 completion_queue_get;

	/**
	 * This field is the minimum of the number of hardware supported port entries
	 * and the software requested port entries.
	 */
	u32 logical_port_entries;
	u32 logical_port_entries;

	/**
	 * This field is the minimum number of devices supported by the hardware and
	 * the number of devices requested by the software.
	 */
	u32 remote_node_entries;
	u32 remote_node_entries;

	/**
	 * This field is the minimum number of IO requests supported by the hardware
	 * and the number of IO requests requested by the software.
	 */
	u32 task_context_entries;
	u32 task_context_entries;

	/**
	 * This object contains all of the unsolicited frame specific
	 * data utilized by the core controller.
	 */
	struct scic_sds_unsolicited_frame_control uf_control;
	struct scic_sds_unsolicited_frame_control uf_control;


	/* Phy Startup Data */
	/* phy startup */
	/**
	 * Timer for controller phy request startup. On controller start the
	 * controller will start each PHY individually in order of phy index.
	 */
	struct sci_timer phy_timer;
	struct sci_timer phy_timer;

	/* XXX kill */
	/**
	 * This field is set when the phy_timer is running and is cleared when
	 * the phy_timer is stopped.
	 */
	bool phy_startup_timer_pending;
	bool phy_startup_timer_pending;

	/**
	 * This field is the index of the next phy start.  It is initialized to 0 and
	 * increments for each phy index that is started.
	 */
	u32 next_phy_to_start;
	u32 next_phy_to_start;

	/**
	 * This field controlls the invalid link up notifications to the SCI_USER.  If
	 * an invalid_link_up notification is reported a bit for the PHY index is set
	 * so further notifications are not made.  Once the PHY object reports link up
	 * and is made part of a port then this bit for the PHY index is cleared.
	 */
	u8 invalid_phy_mask;
	u8 invalid_phy_mask;


	/*
	/* TODO attempt dynamic interrupt coalescing scheme */
	 * This field saves the current interrupt coalescing number of the controller.
	 */
	u16 interrupt_coalesce_number;
	u16 interrupt_coalesce_number;

	/*
	 * This field saves the current interrupt coalescing timeout value in microseconds.
	 */
	u32 interrupt_coalesce_timeout;
	u32 interrupt_coalesce_timeout;

	/**
	 * This field is a pointer to the memory mapped register space for the
	 * struct smu_registers.
	 */
	struct smu_registers __iomem *smu_registers;
	struct smu_registers __iomem *smu_registers;

	/**
	 * This field is a pointer to the memory mapped register space for the
	 * struct scu_registers.
	 */
	struct scu_registers __iomem *scu_registers;
	struct scu_registers __iomem *scu_registers;


};

struct isci_host {
	struct scic_sds_controller sci;
	u16 tci_head;
	u16 tci_head;
	u16 tci_tail;
	u16 tci_tail;
	u16 tci_pool[SCI_MAX_IO_REQUESTS];
	u16 tci_pool[SCI_MAX_IO_REQUESTS];


	union scic_oem_parameters oem_parameters;

	int id; /* unique within a given pci device */
	int id; /* unique within a given pci device */
	struct isci_phy phys[SCI_MAX_PHYS];
	struct isci_phy phys[SCI_MAX_PHYS];
	struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */
	struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */
@@ -464,14 +359,6 @@ static inline struct isci_host *dev_to_ihost(struct domain_device *dev)
	return dev->port->ha->lldd_ha;
	return dev->port->ha->lldd_ha;
}
}


static inline struct isci_host *scic_to_ihost(struct scic_sds_controller *scic)
{
	/* XXX delete after merging scic_sds_contoller and isci_host */
	struct isci_host *ihost = container_of(scic, typeof(*ihost), sci);

	return ihost;
}

/**
/**
 * scic_sds_controller_get_protocol_engine_group() -
 * scic_sds_controller_get_protocol_engine_group() -
 *
 *
@@ -518,11 +405,6 @@ static inline int scic_sds_remote_device_node_count(struct isci_remote_device *i
#define scic_sds_controller_clear_invalid_phy(controller, phy) \
#define scic_sds_controller_clear_invalid_phy(controller, phy) \
	((controller)->invalid_phy_mask &= ~(1 << (phy)->phy_index))
	((controller)->invalid_phy_mask &= ~(1 << (phy)->phy_index))


static inline struct device *scic_to_dev(struct scic_sds_controller *scic)
{
	return &scic_to_ihost(scic)->pdev->dev;
}

static inline struct device *sciphy_to_dev(struct isci_phy *iphy)
static inline struct device *sciphy_to_dev(struct isci_phy *iphy)
{
{


@@ -578,54 +460,54 @@ static inline bool is_c0(void)
	return isci_si_rev > ISCI_SI_REVB0;
	return isci_si_rev > ISCI_SI_REVB0;
}
}


void scic_sds_controller_post_request(struct scic_sds_controller *scic,
void scic_sds_controller_post_request(struct isci_host *ihost,
				      u32 request);
				      u32 request);
void scic_sds_controller_release_frame(struct scic_sds_controller *scic,
void scic_sds_controller_release_frame(struct isci_host *ihost,
				       u32 frame_index);
				       u32 frame_index);
void scic_sds_controller_copy_sata_response(void *response_buffer,
void scic_sds_controller_copy_sata_response(void *response_buffer,
					    void *frame_header,
					    void *frame_header,
					    void *frame_buffer);
					    void *frame_buffer);
enum sci_status scic_sds_controller_allocate_remote_node_context(struct scic_sds_controller *scic,
enum sci_status scic_sds_controller_allocate_remote_node_context(struct isci_host *ihost,
								 struct isci_remote_device *idev,
								 struct isci_remote_device *idev,
								 u16 *node_id);
								 u16 *node_id);
void scic_sds_controller_free_remote_node_context(
void scic_sds_controller_free_remote_node_context(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_remote_device *idev,
	struct isci_remote_device *idev,
	u16 node_id);
	u16 node_id);
union scu_remote_node_context *scic_sds_controller_get_remote_node_context_buffer(
union scu_remote_node_context *scic_sds_controller_get_remote_node_context_buffer(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	u16 node_id);
	u16 node_id);


struct isci_request *scic_request_by_tag(struct scic_sds_controller *scic,
struct isci_request *scic_request_by_tag(struct isci_host *ihost,
					     u16 io_tag);
					     u16 io_tag);


void scic_sds_controller_power_control_queue_insert(
void scic_sds_controller_power_control_queue_insert(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_phy *iphy);
	struct isci_phy *iphy);


void scic_sds_controller_power_control_queue_remove(
void scic_sds_controller_power_control_queue_remove(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_phy *iphy);
	struct isci_phy *iphy);


void scic_sds_controller_link_up(
void scic_sds_controller_link_up(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_port *iport,
	struct isci_port *iport,
	struct isci_phy *iphy);
	struct isci_phy *iphy);


void scic_sds_controller_link_down(
void scic_sds_controller_link_down(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_port *iport,
	struct isci_port *iport,
	struct isci_phy *iphy);
	struct isci_phy *iphy);


void scic_sds_controller_remote_device_stopped(
void scic_sds_controller_remote_device_stopped(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_remote_device *idev);
	struct isci_remote_device *idev);


void scic_sds_controller_copy_task_context(
void scic_sds_controller_copy_task_context(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_request *ireq);
	struct isci_request *ireq);


void scic_sds_controller_register_setup(struct scic_sds_controller *scic);
void scic_sds_controller_register_setup(struct isci_host *ihost);


enum sci_status scic_controller_continue_io(struct isci_request *ireq);
enum sci_status scic_controller_continue_io(struct isci_request *ireq);
int isci_host_scan_finished(struct Scsi_Host *, unsigned long);
int isci_host_scan_finished(struct Scsi_Host *, unsigned long);
@@ -655,25 +537,25 @@ void isci_host_remote_device_start_complete(
	enum sci_status);
	enum sci_status);


void scic_controller_disable_interrupts(
void scic_controller_disable_interrupts(
	struct scic_sds_controller *scic);
	struct isci_host *ihost);


enum sci_status scic_controller_start_io(
enum sci_status scic_controller_start_io(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_remote_device *idev,
	struct isci_remote_device *idev,
	struct isci_request *ireq);
	struct isci_request *ireq);


enum sci_task_status scic_controller_start_task(
enum sci_task_status scic_controller_start_task(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_remote_device *idev,
	struct isci_remote_device *idev,
	struct isci_request *ireq);
	struct isci_request *ireq);


enum sci_status scic_controller_terminate_request(
enum sci_status scic_controller_terminate_request(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_remote_device *idev,
	struct isci_remote_device *idev,
	struct isci_request *ireq);
	struct isci_request *ireq);


enum sci_status scic_controller_complete_io(
enum sci_status scic_controller_complete_io(
	struct scic_sds_controller *scic,
	struct isci_host *ihost,
	struct isci_remote_device *idev,
	struct isci_remote_device *idev,
	struct isci_request *ireq);
	struct isci_request *ireq);


@@ -681,6 +563,6 @@ void scic_sds_port_configuration_agent_construct(
	struct scic_sds_port_configuration_agent *port_agent);
	struct scic_sds_port_configuration_agent *port_agent);


enum sci_status scic_sds_port_configuration_agent_initialize(
enum sci_status scic_sds_port_configuration_agent_initialize(
	struct scic_sds_controller *controller,
	struct isci_host *ihost,
	struct scic_sds_port_configuration_agent *port_agent);
	struct scic_sds_port_configuration_agent *port_agent);
#endif
#endif
+5 −5
Original line number Original line Diff line number Diff line
@@ -548,13 +548,13 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic


static void __devexit isci_pci_remove(struct pci_dev *pdev)
static void __devexit isci_pci_remove(struct pci_dev *pdev)
{
{
	struct isci_host *isci_host;
	struct isci_host *ihost;
	int i;
	int i;


	for_each_isci_host(i, isci_host, pdev) {
	for_each_isci_host(i, ihost, pdev) {
		isci_unregister(isci_host);
		isci_unregister(ihost);
		isci_host_deinit(isci_host);
		isci_host_deinit(ihost);
		scic_controller_disable_interrupts(&isci_host->sci);
		scic_controller_disable_interrupts(ihost);
	}
	}
}
}


+20 −20
Original line number Original line Diff line number Diff line
@@ -112,13 +112,13 @@ static enum sci_status
scic_sds_phy_link_layer_initialization(struct isci_phy *iphy,
scic_sds_phy_link_layer_initialization(struct isci_phy *iphy,
				       struct scu_link_layer_registers __iomem *link_layer_registers)
				       struct scu_link_layer_registers __iomem *link_layer_registers)
{
{
	struct scic_sds_controller *scic =
	struct isci_host *ihost =
		iphy->owning_port->owning_controller;
		iphy->owning_port->owning_controller;
	int phy_idx = iphy->phy_index;
	int phy_idx = iphy->phy_index;
	struct sci_phy_user_params *phy_user =
	struct sci_phy_user_params *phy_user =
		&scic->user_parameters.sds1.phys[phy_idx];
		&ihost->user_parameters.sds1.phys[phy_idx];
	struct sci_phy_oem_params *phy_oem =
	struct sci_phy_oem_params *phy_oem =
		&scic->oem_parameters.sds1.phys[phy_idx];
		&ihost->oem_parameters.sds1.phys[phy_idx];
	u32 phy_configuration;
	u32 phy_configuration;
	struct scic_phy_cap phy_cap;
	struct scic_phy_cap phy_cap;
	u32 parity_check = 0;
	u32 parity_check = 0;
@@ -169,7 +169,7 @@ scic_sds_phy_link_layer_initialization(struct isci_phy *iphy,
	phy_cap.gen3_no_ssc = 1;
	phy_cap.gen3_no_ssc = 1;
	phy_cap.gen2_no_ssc = 1;
	phy_cap.gen2_no_ssc = 1;
	phy_cap.gen1_no_ssc = 1;
	phy_cap.gen1_no_ssc = 1;
	if (scic->oem_parameters.sds1.controller.do_enable_ssc == true) {
	if (ihost->oem_parameters.sds1.controller.do_enable_ssc == true) {
		phy_cap.gen3_ssc = 1;
		phy_cap.gen3_ssc = 1;
		phy_cap.gen2_ssc = 1;
		phy_cap.gen2_ssc = 1;
		phy_cap.gen1_ssc = 1;
		phy_cap.gen1_ssc = 1;
@@ -216,7 +216,7 @@ scic_sds_phy_link_layer_initialization(struct isci_phy *iphy,
		&iphy->link_layer_registers->afe_lookup_table_control);
		&iphy->link_layer_registers->afe_lookup_table_control);


	llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
	llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
		(u8)scic->user_parameters.sds1.no_outbound_task_timeout);
		(u8)ihost->user_parameters.sds1.no_outbound_task_timeout);


	switch(phy_user->max_speed_generation) {
	switch(phy_user->max_speed_generation) {
	case SCIC_SDS_PARM_GEN3_SPEED:
	case SCIC_SDS_PARM_GEN3_SPEED:
@@ -255,7 +255,7 @@ static void phy_sata_timeout(unsigned long data)
{
{
	struct sci_timer *tmr = (struct sci_timer *)data;
	struct sci_timer *tmr = (struct sci_timer *)data;
	struct isci_phy *iphy = container_of(tmr, typeof(*iphy), sata_timer);
	struct isci_phy *iphy = container_of(tmr, typeof(*iphy), sata_timer);
	struct isci_host *ihost = scic_to_ihost(iphy->owning_port->owning_controller);
	struct isci_host *ihost = iphy->owning_port->owning_controller;
	unsigned long flags;
	unsigned long flags;


	spin_lock_irqsave(&ihost->scic_lock, flags);
	spin_lock_irqsave(&ihost->scic_lock, flags);
@@ -890,7 +890,7 @@ enum sci_status scic_sds_phy_frame_handler(struct isci_phy *iphy,
					   u32 frame_index)
					   u32 frame_index)
{
{
	enum scic_sds_phy_states state = iphy->sm.current_state_id;
	enum scic_sds_phy_states state = iphy->sm.current_state_id;
	struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
	struct isci_host *ihost = iphy->owning_port->owning_controller;
	enum sci_status result;
	enum sci_status result;
	unsigned long flags;
	unsigned long flags;


@@ -899,7 +899,7 @@ enum sci_status scic_sds_phy_frame_handler(struct isci_phy *iphy,
		u32 *frame_words;
		u32 *frame_words;
		struct sas_identify_frame iaf;
		struct sas_identify_frame iaf;


		result = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control,
		result = scic_sds_unsolicited_frame_control_get_header(&ihost->uf_control,
								       frame_index,
								       frame_index,
								       (void **)&frame_words);
								       (void **)&frame_words);


@@ -933,7 +933,7 @@ enum sci_status scic_sds_phy_frame_handler(struct isci_phy *iphy,
				"unexpected frame id %x\n",
				"unexpected frame id %x\n",
				__func__, frame_index);
				__func__, frame_index);


		scic_sds_controller_release_frame(scic, frame_index);
		scic_sds_controller_release_frame(ihost, frame_index);
		return result;
		return result;
	}
	}
	case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: {
	case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: {
@@ -950,7 +950,7 @@ enum sci_status scic_sds_phy_frame_handler(struct isci_phy *iphy,


		if ((frame_header->fis_type == FIS_REGD2H) &&
		if ((frame_header->fis_type == FIS_REGD2H) &&
		    !(frame_header->status & ATA_BUSY)) {
		    !(frame_header->status & ATA_BUSY)) {
			scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control,
			scic_sds_unsolicited_frame_control_get_buffer(&ihost->uf_control,
								      frame_index,
								      frame_index,
								      (void **)&fis_frame_data);
								      (void **)&fis_frame_data);


@@ -971,7 +971,7 @@ enum sci_status scic_sds_phy_frame_handler(struct isci_phy *iphy,
				 __func__, frame_index);
				 __func__, frame_index);


		/* Regardless of the result we are done with this frame with it */
		/* Regardless of the result we are done with this frame with it */
		scic_sds_controller_release_frame(scic, frame_index);
		scic_sds_controller_release_frame(ihost, frame_index);


		return result;
		return result;
	}
	}
@@ -994,33 +994,33 @@ static void scic_sds_phy_starting_initial_substate_enter(struct sci_base_state_m
static void scic_sds_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm)
static void scic_sds_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm)
{
{
	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
	struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
	struct isci_host *ihost = iphy->owning_port->owning_controller;


	scic_sds_controller_power_control_queue_insert(scic, iphy);
	scic_sds_controller_power_control_queue_insert(ihost, iphy);
}
}


static void scic_sds_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm)
static void scic_sds_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm)
{
{
	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
	struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
	struct isci_host *ihost = iphy->owning_port->owning_controller;


	scic_sds_controller_power_control_queue_remove(scic, iphy);
	scic_sds_controller_power_control_queue_remove(ihost, iphy);
}
}


static void scic_sds_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm)
static void scic_sds_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm)
{
{
	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
	struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
	struct isci_host *ihost = iphy->owning_port->owning_controller;


	scic_sds_controller_power_control_queue_insert(scic, iphy);
	scic_sds_controller_power_control_queue_insert(ihost, iphy);
}
}


static void scic_sds_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm)
static void scic_sds_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm)
{
{
	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
	struct scic_sds_controller *scic = iphy->owning_port->owning_controller;
	struct isci_host *ihost = iphy->owning_port->owning_controller;


	scic_sds_controller_power_control_queue_remove(scic, iphy);
	scic_sds_controller_power_control_queue_remove(ihost, iphy);
}
}


static void scic_sds_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm)
static void scic_sds_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm)
@@ -1313,7 +1313,7 @@ void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
	u64 sci_sas_addr;
	u64 sci_sas_addr;
	__be64 sas_addr;
	__be64 sas_addr;


	scic_oem_parameters_get(&ihost->sci, &oem);
	scic_oem_parameters_get(ihost, &oem);
	sci_sas_addr = oem.sds1.phys[index].sas_address.high;
	sci_sas_addr = oem.sds1.phys[index].sas_address.high;
	sci_sas_addr <<= 32;
	sci_sas_addr <<= 32;
	sci_sas_addr |= oem.sds1.phys[index].sas_address.low;
	sci_sas_addr |= oem.sds1.phys[index].sas_address.low;
+40 −49
Original line number Original line Diff line number Diff line
@@ -365,11 +365,11 @@ static void isci_port_not_ready(struct isci_host *isci_host, struct isci_port *i
		"%s: isci_port = %p\n", __func__, isci_port);
		"%s: isci_port = %p\n", __func__, isci_port);
}
}


static void isci_port_stop_complete(struct scic_sds_controller *scic,
static void isci_port_stop_complete(struct isci_host *ihost,
				    struct isci_port *iport,
				    struct isci_port *iport,
				    enum sci_status completion_status)
				    enum sci_status completion_status)
{
{
	dev_dbg(&scic_to_ihost(scic)->pdev->dev, "Port stop complete\n");
	dev_dbg(&ihost->pdev->dev, "Port stop complete\n");
}
}


/**
/**
@@ -541,8 +541,7 @@ static enum sci_status scic_sds_port_clear_phy(struct isci_port *iport,
	/* Make sure that this phy is part of this port */
	/* Make sure that this phy is part of this port */
	if (iport->phy_table[iphy->phy_index] == iphy &&
	if (iport->phy_table[iphy->phy_index] == iphy &&
	    phy_get_non_dummy_port(iphy) == iport) {
	    phy_get_non_dummy_port(iphy) == iport) {
		struct scic_sds_controller *scic = iport->owning_controller;
		struct isci_host *ihost = iport->owning_controller;
		struct isci_host *ihost = scic_to_ihost(scic);


		/* Yep it is assigned to this port so remove it */
		/* Yep it is assigned to this port so remove it */
		scic_sds_phy_set_port(iphy, &ihost->ports[SCI_MAX_PORTS]);
		scic_sds_phy_set_port(iphy, &ihost->ports[SCI_MAX_PORTS]);
@@ -654,10 +653,10 @@ static void scic_sds_port_construct_dummy_rnc(struct isci_port *iport, u16 rni)
 */
 */
static void scic_sds_port_construct_dummy_task(struct isci_port *iport, u16 tag)
static void scic_sds_port_construct_dummy_task(struct isci_port *iport, u16 tag)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	struct scu_task_context *task_context;
	struct scu_task_context *task_context;


	task_context = &scic->task_context_table[ISCI_TAG_TCI(tag)];
	task_context = &ihost->task_context_table[ISCI_TAG_TCI(tag)];
	memset(task_context, 0, sizeof(struct scu_task_context));
	memset(task_context, 0, sizeof(struct scu_task_context));


	task_context->initiator_request = 1;
	task_context->initiator_request = 1;
@@ -674,13 +673,13 @@ static void scic_sds_port_construct_dummy_task(struct isci_port *iport, u16 tag)


static void scic_sds_port_destroy_dummy_resources(struct isci_port *iport)
static void scic_sds_port_destroy_dummy_resources(struct isci_port *iport)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;


	if (iport->reserved_tag != SCI_CONTROLLER_INVALID_IO_TAG)
	if (iport->reserved_tag != SCI_CONTROLLER_INVALID_IO_TAG)
		isci_free_tag(scic_to_ihost(scic), iport->reserved_tag);
		isci_free_tag(ihost, iport->reserved_tag);


	if (iport->reserved_rni != SCU_DUMMY_INDEX)
	if (iport->reserved_rni != SCU_DUMMY_INDEX)
		scic_sds_remote_node_table_release_remote_node_index(&scic->available_remote_nodes,
		scic_sds_remote_node_table_release_remote_node_index(&ihost->available_remote_nodes,
								     1, iport->reserved_rni);
								     1, iport->reserved_rni);


	iport->reserved_rni = SCU_DUMMY_INDEX;
	iport->reserved_rni = SCU_DUMMY_INDEX;
@@ -749,15 +748,14 @@ static void scic_sds_port_activate_phy(struct isci_port *iport,
				       struct isci_phy *iphy,
				       struct isci_phy *iphy,
				       bool do_notify_user)
				       bool do_notify_user)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);


	if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA)
	if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA)
		scic_sds_phy_resume(iphy);
		scic_sds_phy_resume(iphy);


	iport->active_phy_mask |= 1 << iphy->phy_index;
	iport->active_phy_mask |= 1 << iphy->phy_index;


	scic_sds_controller_clear_invalid_phy(scic, iphy);
	scic_sds_controller_clear_invalid_phy(ihost, iphy);


	if (do_notify_user == true)
	if (do_notify_user == true)
		isci_port_link_up(ihost, iport, iphy);
		isci_port_link_up(ihost, iport, iphy);
@@ -767,8 +765,7 @@ void scic_sds_port_deactivate_phy(struct isci_port *iport,
				  struct isci_phy *iphy,
				  struct isci_phy *iphy,
				  bool do_notify_user)
				  bool do_notify_user)
{
{
	struct scic_sds_controller *scic = scic_sds_port_get_controller(iport);
	struct isci_host *ihost = scic_sds_port_get_controller(iport);
	struct isci_host *ihost = scic_to_ihost(scic);


	iport->active_phy_mask &= ~(1 << iphy->phy_index);
	iport->active_phy_mask &= ~(1 << iphy->phy_index);


@@ -793,16 +790,16 @@ void scic_sds_port_deactivate_phy(struct isci_port *iport,
static void scic_sds_port_invalid_link_up(struct isci_port *iport,
static void scic_sds_port_invalid_link_up(struct isci_port *iport,
					  struct isci_phy *iphy)
					  struct isci_phy *iphy)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;


	/*
	/*
	 * Check to see if we have alreay reported this link as bad and if
	 * Check to see if we have alreay reported this link as bad and if
	 * not go ahead and tell the SCI_USER that we have discovered an
	 * not go ahead and tell the SCI_USER that we have discovered an
	 * invalid link.
	 * invalid link.
	 */
	 */
	if ((scic->invalid_phy_mask & (1 << iphy->phy_index)) == 0) {
	if ((ihost->invalid_phy_mask & (1 << iphy->phy_index)) == 0) {
		scic_sds_controller_set_invalid_phy(scic, iphy);
		scic_sds_controller_set_invalid_phy(ihost, iphy);
		dev_warn(&scic_to_ihost(scic)->pdev->dev, "Invalid link up!\n");
		dev_warn(&ihost->pdev->dev, "Invalid link up!\n");
	}
	}
}
}


@@ -931,7 +928,7 @@ static void port_timeout(unsigned long data)
{
{
	struct sci_timer *tmr = (struct sci_timer *)data;
	struct sci_timer *tmr = (struct sci_timer *)data;
	struct isci_port *iport = container_of(tmr, typeof(*iport), timer);
	struct isci_port *iport = container_of(tmr, typeof(*iport), timer);
	struct isci_host *ihost = scic_to_ihost(iport->owning_controller);
	struct isci_host *ihost = iport->owning_controller;
	unsigned long flags;
	unsigned long flags;
	u32 current_state;
	u32 current_state;


@@ -1041,19 +1038,19 @@ static void scic_sds_port_suspend_port_task_scheduler(struct isci_port *iport)
 */
 */
static void scic_sds_port_post_dummy_request(struct isci_port *iport)
static void scic_sds_port_post_dummy_request(struct isci_port *iport)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	u16 tag = iport->reserved_tag;
	u16 tag = iport->reserved_tag;
	struct scu_task_context *tc;
	struct scu_task_context *tc;
	u32 command;
	u32 command;


	tc = &scic->task_context_table[ISCI_TAG_TCI(tag)];
	tc = &ihost->task_context_table[ISCI_TAG_TCI(tag)];
	tc->abort = 0;
	tc->abort = 0;


	command = SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
	command = SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
		  iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
		  iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
		  ISCI_TAG_TCI(tag);
		  ISCI_TAG_TCI(tag);


	scic_sds_controller_post_request(scic, command);
	scic_sds_controller_post_request(ihost, command);
}
}


/**
/**
@@ -1065,19 +1062,19 @@ static void scic_sds_port_post_dummy_request(struct isci_port *iport)
 */
 */
static void scic_sds_port_abort_dummy_request(struct isci_port *iport)
static void scic_sds_port_abort_dummy_request(struct isci_port *iport)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	u16 tag = iport->reserved_tag;
	u16 tag = iport->reserved_tag;
	struct scu_task_context *tc;
	struct scu_task_context *tc;
	u32 command;
	u32 command;


	tc = &scic->task_context_table[ISCI_TAG_TCI(tag)];
	tc = &ihost->task_context_table[ISCI_TAG_TCI(tag)];
	tc->abort = 1;
	tc->abort = 1;


	command = SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT |
	command = SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT |
		  iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
		  iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
		  ISCI_TAG_TCI(tag);
		  ISCI_TAG_TCI(tag);


	scic_sds_controller_post_request(scic, command);
	scic_sds_controller_post_request(ihost, command);
}
}


/**
/**
@@ -1115,8 +1112,7 @@ static void scic_sds_port_ready_substate_operational_enter(struct sci_base_state
{
{
	u32 index;
	u32 index;
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);


	isci_port_ready(ihost, iport);
	isci_port_ready(ihost, iport);


@@ -1141,13 +1137,13 @@ static void scic_sds_port_ready_substate_operational_enter(struct sci_base_state


static void scic_sds_port_invalidate_dummy_remote_node(struct isci_port *iport)
static void scic_sds_port_invalidate_dummy_remote_node(struct isci_port *iport)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	u8 phys_index = iport->physical_port_index;
	u8 phys_index = iport->physical_port_index;
	union scu_remote_node_context *rnc;
	union scu_remote_node_context *rnc;
	u16 rni = iport->reserved_rni;
	u16 rni = iport->reserved_rni;
	u32 command;
	u32 command;


	rnc = &scic->remote_node_context_table[rni];
	rnc = &ihost->remote_node_context_table[rni];


	rnc->ssp.is_valid = false;
	rnc->ssp.is_valid = false;


@@ -1155,13 +1151,13 @@ static void scic_sds_port_invalidate_dummy_remote_node(struct isci_port *iport)
	 * controller and give it ample time to act before posting the rnc
	 * controller and give it ample time to act before posting the rnc
	 * invalidate
	 * invalidate
	 */
	 */
	readl(&scic->smu_registers->interrupt_status); /* flush */
	readl(&ihost->smu_registers->interrupt_status); /* flush */
	udelay(10);
	udelay(10);


	command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
	command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;


	scic_sds_controller_post_request(scic, command);
	scic_sds_controller_post_request(ihost, command);
}
}


/**
/**
@@ -1175,8 +1171,7 @@ static void scic_sds_port_invalidate_dummy_remote_node(struct isci_port *iport)
static void scic_sds_port_ready_substate_operational_exit(struct sci_base_state_machine *sm)
static void scic_sds_port_ready_substate_operational_exit(struct sci_base_state_machine *sm)
{
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);


	/*
	/*
	 * Kill the dummy task for this port if it has not yet posted
	 * Kill the dummy task for this port if it has not yet posted
@@ -1194,8 +1189,7 @@ static void scic_sds_port_ready_substate_operational_exit(struct sci_base_state_
static void scic_sds_port_ready_substate_configuring_enter(struct sci_base_state_machine *sm)
static void scic_sds_port_ready_substate_configuring_enter(struct sci_base_state_machine *sm)
{
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);


	if (iport->active_phy_mask == 0) {
	if (iport->active_phy_mask == 0) {
		isci_port_not_ready(ihost, iport);
		isci_port_not_ready(ihost, iport);
@@ -1218,7 +1212,7 @@ static void scic_sds_port_ready_substate_configuring_exit(struct sci_base_state_


enum sci_status scic_sds_port_start(struct isci_port *iport)
enum sci_status scic_sds_port_start(struct isci_port *iport)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	enum sci_status status = SCI_SUCCESS;
	enum sci_status status = SCI_SUCCESS;
	enum scic_sds_port_states state;
	enum scic_sds_port_states state;
	u32 phy_mask;
	u32 phy_mask;
@@ -1241,7 +1235,7 @@ enum sci_status scic_sds_port_start(struct isci_port *iport)


	if (iport->reserved_rni == SCU_DUMMY_INDEX) {
	if (iport->reserved_rni == SCU_DUMMY_INDEX) {
		u16 rni = scic_sds_remote_node_table_allocate_remote_node(
		u16 rni = scic_sds_remote_node_table_allocate_remote_node(
				&scic->available_remote_nodes, 1);
				&ihost->available_remote_nodes, 1);


		if (rni != SCU_DUMMY_INDEX)
		if (rni != SCU_DUMMY_INDEX)
			scic_sds_port_construct_dummy_rnc(iport, rni);
			scic_sds_port_construct_dummy_rnc(iport, rni);
@@ -1251,7 +1245,6 @@ enum sci_status scic_sds_port_start(struct isci_port *iport)
	}
	}


	if (iport->reserved_tag == SCI_CONTROLLER_INVALID_IO_TAG) {
	if (iport->reserved_tag == SCI_CONTROLLER_INVALID_IO_TAG) {
		struct isci_host *ihost = scic_to_ihost(scic);
		u16 tag;
		u16 tag;


		tag = isci_alloc_tag(ihost);
		tag = isci_alloc_tag(ihost);
@@ -1634,30 +1627,30 @@ scic_sds_port_disable_port_task_scheduler(struct isci_port *iport)


static void scic_sds_port_post_dummy_remote_node(struct isci_port *iport)
static void scic_sds_port_post_dummy_remote_node(struct isci_port *iport)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	u8 phys_index = iport->physical_port_index;
	u8 phys_index = iport->physical_port_index;
	union scu_remote_node_context *rnc;
	union scu_remote_node_context *rnc;
	u16 rni = iport->reserved_rni;
	u16 rni = iport->reserved_rni;
	u32 command;
	u32 command;


	rnc = &scic->remote_node_context_table[rni];
	rnc = &ihost->remote_node_context_table[rni];
	rnc->ssp.is_valid = true;
	rnc->ssp.is_valid = true;


	command = SCU_CONTEXT_COMMAND_POST_RNC_32 |
	command = SCU_CONTEXT_COMMAND_POST_RNC_32 |
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;


	scic_sds_controller_post_request(scic, command);
	scic_sds_controller_post_request(ihost, command);


	/* ensure hardware has seen the post rnc command and give it
	/* ensure hardware has seen the post rnc command and give it
	 * ample time to act before sending the suspend
	 * ample time to act before sending the suspend
	 */
	 */
	readl(&scic->smu_registers->interrupt_status); /* flush */
	readl(&ihost->smu_registers->interrupt_status); /* flush */
	udelay(10);
	udelay(10);


	command = SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX |
	command = SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX |
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;


	scic_sds_controller_post_request(scic, command);
	scic_sds_controller_post_request(ihost, command);
}
}


static void scic_sds_port_stopped_state_enter(struct sci_base_state_machine *sm)
static void scic_sds_port_stopped_state_enter(struct sci_base_state_machine *sm)
@@ -1684,8 +1677,7 @@ static void scic_sds_port_stopped_state_exit(struct sci_base_state_machine *sm)
static void scic_sds_port_ready_state_enter(struct sci_base_state_machine *sm)
static void scic_sds_port_ready_state_enter(struct sci_base_state_machine *sm)
{
{
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);
	u32 prev_state;
	u32 prev_state;


	prev_state = iport->sm.previous_state_id;
	prev_state = iport->sm.previous_state_id;
@@ -1758,7 +1750,7 @@ static const struct sci_base_state scic_sds_port_state_table[] = {
};
};


void scic_sds_port_construct(struct isci_port *iport, u8 index,
void scic_sds_port_construct(struct isci_port *iport, u8 index,
			     struct scic_sds_controller *scic)
			     struct isci_host *ihost)
{
{
	sci_init_sm(&iport->sm, scic_sds_port_state_table, SCI_PORT_STOPPED);
	sci_init_sm(&iport->sm, scic_sds_port_state_table, SCI_PORT_STOPPED);


@@ -1767,7 +1759,7 @@ void scic_sds_port_construct(struct isci_port *iport, u8 index,
	iport->active_phy_mask     = 0;
	iport->active_phy_mask     = 0;
	iport->ready_exit	      = false;
	iport->ready_exit	      = false;


	iport->owning_controller = scic;
	iport->owning_controller = ihost;


	iport->started_request_count = 0;
	iport->started_request_count = 0;
	iport->assigned_device_count = 0;
	iport->assigned_device_count = 0;
@@ -1810,8 +1802,7 @@ void scic_sds_port_broadcast_change_received(
	struct isci_port *iport,
	struct isci_port *iport,
	struct isci_phy *iphy)
	struct isci_phy *iphy)
{
{
	struct scic_sds_controller *scic = iport->owning_controller;
	struct isci_host *ihost = iport->owning_controller;
	struct isci_host *ihost = scic_to_ihost(scic);


	/* notify the user. */
	/* notify the user. */
	isci_port_bc_change_received(ihost, iport, iphy);
	isci_port_bc_change_received(ihost, iport, iphy);
Loading