Skip to content

Commit

Permalink
isci: Move transport layer registers from port to phy
Browse files Browse the repository at this point in the history
At init and RNC resume we need to touch every phy in a port to be sure
we have initialized STP properties in the case where port_index !=
phy_index.  Also add some missing __iomem annotations.

Signed-off-by: Henryk Dembkowski <henryk.dembkowski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Henryk Dembkowski authored and Dan Williams committed Jul 3, 2011
1 parent 06fdb32 commit 2462146
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 162 deletions.
2 changes: 1 addition & 1 deletion drivers/scsi/isci/core/scic_sds_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -2919,6 +2919,7 @@ static enum sci_status scic_sds_controller_reset_state_initialize_handler(
index++) {
result = scic_sds_phy_initialize(
&this_controller->phy_table[index],
&this_controller->scu_registers->peg0.pe[index].tl,
&this_controller->scu_registers->peg0.pe[index].ll
);
}
Expand All @@ -2932,7 +2933,6 @@ static enum sci_status scic_sds_controller_reset_state_initialize_handler(
index++) {
result = scic_sds_port_initialize(
&this_controller->port_table[index],
&this_controller->scu_registers->peg0.pe[index].tl,
&this_controller->scu_registers->peg0.ptsg.port[index],
&this_controller->scu_registers->peg0.ptsg.protocol_engine,
&this_controller->scu_registers->peg0.viit[index]
Expand Down
62 changes: 58 additions & 4 deletions drivers/scsi/isci/core/scic_sds_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include "scic_sds_phy.h"
#include "scic_sds_phy_registers.h"
#include "scic_sds_port.h"
#include "scic_sds_remote_node_context.h"
#include "scic_user_callback.h"
#include "sci_environment.h"
#include "sci_util.h"
Expand All @@ -83,6 +84,31 @@ enum sas_linkrate sci_phy_linkrate(struct scic_sds_phy *sci_phy)
* * SCIC SDS PHY Internal Methods
* ***************************************************************************** */

/**
* This method will initialize the phy transport layer registers
* @this_phy:
* @transport_layer_registers
*
* enum sci_status
*/
static enum sci_status scic_sds_phy_transport_layer_initialization(
struct scic_sds_phy *this_phy,
struct scu_transport_layer_registers __iomem *transport_layer_registers)
{
u32 tl_control;

this_phy->transport_layer_registers = transport_layer_registers;

SCU_STPTLDARNI_WRITE(this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);

/* Hardware team recommends that we enable the STP prefetch for all transports */
tl_control = SCU_TLCR_READ(this_phy);
tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
SCU_TLCR_WRITE(this_phy, tl_control);

return SCI_SUCCESS;
}

/**
* This method will initialize the phy link layer registers
* @this_phy:
Expand All @@ -92,7 +118,7 @@ enum sas_linkrate sci_phy_linkrate(struct scic_sds_phy *sci_phy)
*/
static enum sci_status scic_sds_phy_link_layer_initialization(
struct scic_sds_phy *this_phy,
struct scu_link_layer_registers *link_layer_registers)
struct scu_link_layer_registers __iomem *link_layer_registers)
{
u32 phy_configuration;
struct sas_capabilities phy_capabilities;
Expand Down Expand Up @@ -361,7 +387,8 @@ void scic_sds_phy_set_port(
*/
enum sci_status scic_sds_phy_initialize(
struct scic_sds_phy *sci_phy,
struct scu_link_layer_registers *link_layer_registers)
struct scu_transport_layer_registers __iomem *transport_layer_registers,
struct scu_link_layer_registers __iomem *link_layer_registers)
{
/* Create the SIGNATURE FIS Timeout timer for this phy */
sci_phy->sata_timeout_timer = scic_cb_timer_create(
Expand All @@ -370,6 +397,9 @@ enum sci_status scic_sds_phy_initialize(
sci_phy
);

/* Perfrom the initialization of the TL hardware */
scic_sds_phy_transport_layer_initialization(sci_phy, transport_layer_registers);

/* Perofrm the initialization of the PE hardware */
scic_sds_phy_link_layer_initialization(sci_phy, link_layer_registers);

Expand All @@ -384,6 +414,31 @@ enum sci_status scic_sds_phy_initialize(
return SCI_SUCCESS;
}

/**
* This method assigns the direct attached device ID for this phy.
*
* @this_phy The phy for which the direct attached device id is to
* be assigned.
* @device_id The direct attached device ID to assign to the phy.
* This will either be the RNi for the device or an invalid RNi if there
* is no current device assigned to the phy.
*/
void scic_sds_phy_setup_transport(
struct scic_sds_phy *this_phy,
u32 device_id)
{
u32 tl_control;

SCU_STPTLDARNI_WRITE(this_phy, device_id);

/*
* The read should guarantee that the first write gets posted
* before the next write
*/
tl_control = SCU_TLCR_READ(this_phy);
tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
SCU_TLCR_WRITE(this_phy, tl_control);
}

/**
*
Expand All @@ -398,10 +453,9 @@ void scic_sds_phy_suspend(
u32 scu_sas_pcfg_value;

scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);

scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);

SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
scic_sds_phy_setup_transport(this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
}

/**
Expand Down
15 changes: 13 additions & 2 deletions drivers/scsi/isci/core/scic_sds_phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,16 @@ struct scic_sds_phy {

struct sci_base_state_machine starting_substate_machine;

/**
* This field is the pointer to the transport layer register for the SCU
* hardware.
*/
struct scu_transport_layer_registers __iomem *transport_layer_registers;

/**
* This field points to the link layer register set within the SCU.
*/
struct scu_link_layer_registers *link_layer_registers;
struct scu_link_layer_registers __iomem *link_layer_registers;

};

Expand Down Expand Up @@ -383,7 +389,8 @@ void scic_sds_phy_set_port(

enum sci_status scic_sds_phy_initialize(
struct scic_sds_phy *this_phy,
struct scu_link_layer_registers *link_layer_registers);
struct scu_transport_layer_registers __iomem *transport_layer_registers,
struct scu_link_layer_registers __iomem *link_layer_registers);

enum sci_status scic_sds_phy_start(
struct scic_sds_phy *this_phy);
Expand All @@ -402,6 +409,10 @@ void scic_sds_phy_suspend(
void scic_sds_phy_resume(
struct scic_sds_phy *this_phy);

void scic_sds_phy_setup_transport(
struct scic_sds_phy *this_phy,
u32 device_id);

/* --------------------------------------------------------------------------- */

enum sci_status scic_sds_phy_event_handler(
Expand Down
53 changes: 53 additions & 0 deletions drivers/scsi/isci/core/scic_sds_phy_registers.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,59 @@

#include "scic_sds_controller.h"

/* **************************************************************************
* * SCU TRANSPORT LAYER REGISTER OPERATIONS
* ************************************************************************** */

/**
* Macro to read the transport layer register associated with this phy
* object.
*/
#define scu_transport_layer_read(phy, reg) \
scu_register_read( \
scic_sds_phy_get_controller(phy), \
(phy)->transport_layer_registers->reg \
)

/**
* Macro to write the transport layer register associated with this phy
* object.
*/
#define scu_transport_layer_write(phy, reg, value) \
scu_register_write( \
scic_sds_phy_get_controller(phy), \
(phy)->transport_layer_registers->reg, \
(value) \
)

/* **************************************************************************
* * Transport Layer registers controlled by the phy object
* ************************************************************************** */

/* This macro reads the Transport layer control register */
#define SCU_TLCR_READ(phy) \
scu_transport_layer_read(phy, control)

/* This macro writes the Transport layer control register */
#define SCU_TLCR_WRITE(phy, value) \
scu_transport_layer_write(phy, control, value)

/* This macro reads the Transport layer address translation register */
#define SCU_TLADTR_READ(phy) \
scu_transport_layer_read(phy, address_translation)

/* This macro writes the Transport layer address translation register */
#define SCU_TLADTR_WRITE(phy) \
scu_transport_layer_write(phy, address_translation, value)

/* This macro writes the STP Transport Layer Direct Attached RNi register */
#define SCU_STPTLDARNI_WRITE(phy, index) \
scu_transport_layer_write(phy, stp_rni, index)

/* This macro reads the STP Transport Layer Direct Attached RNi register */
#define SCU_STPTLDARNI_READ(phy) \
scu_transport_layer_read(phy, stp_rni)

/*
* *****************************************************************************
* * SCU LINK LAYER REGISTER OPERATIONS
Expand Down
58 changes: 14 additions & 44 deletions drivers/scsi/isci/core/scic_sds_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,6 @@ void scic_sds_port_construct(

this_port->timer_handle = NULL;

this_port->transport_layer_registers = NULL;
this_port->port_task_scheduler_registers = NULL;

for (index = 0; index < SCI_MAX_PHYS; index++) {
Expand All @@ -553,30 +552,14 @@ void scic_sds_port_construct(
*/
enum sci_status scic_sds_port_initialize(
struct scic_sds_port *this_port,
void *transport_layer_registers,
void *port_task_scheduler_registers,
void *port_configuration_regsiter,
void *viit_registers)
void __iomem *port_task_scheduler_registers,
void __iomem *port_configuration_regsiter,
void __iomem *viit_registers)
{
u32 tl_control;

this_port->transport_layer_registers = transport_layer_registers;
this_port->port_task_scheduler_registers = port_task_scheduler_registers;
this_port->port_pe_configuration_register = port_configuration_regsiter;
this_port->viit_registers = viit_registers;

scic_sds_port_set_direct_attached_device_id(
this_port,
SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
);

/*
* Hardware team recommends that we enable the STP prefetch
* for all ports */
tl_control = SCU_TLCR_READ(this_port);
tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
SCU_TLCR_WRITE(this_port, tl_control);

/*
* If this is not the dummy port make the assignment of
* the timer and start the state machine */
Expand Down Expand Up @@ -693,29 +676,25 @@ enum sci_status scic_port_hard_reset(
}

/**
*
* @this_port: The port for which the direct attached device id is to be
* assigned.
*
* This method assigns the direct attached device ID for this port.
*
* @param[in] this_port The port for which the direct attached device id is to
* be assigned.
* @param[in] device_id The direct attached device ID to assign to the port.
* This will be the RNi for the device
*/
void scic_sds_port_set_direct_attached_device_id(
void scic_sds_port_setup_transports(
struct scic_sds_port *this_port,
u32 device_id)
{
u32 tl_control;

SCU_STPTLDARNI_WRITE(this_port, device_id);
u8 index;

/*
* The read should guarntee that the first write gets posted
* before the next write */
tl_control = SCU_TLCR_READ(this_port);
tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
SCU_TLCR_WRITE(this_port, tl_control);
for (index = 0; index < SCI_MAX_PHYS; index++) {
if (this_port->active_phy_mask & (1 << index))
scic_sds_phy_setup_transport(this_port->phy_table[index], device_id);
}
}


/**
*
* @this_port: This is the port on which the phy should be enabled.
Expand Down Expand Up @@ -1550,16 +1529,12 @@ static void scic_sds_port_suspend_port_task_scheduler(
struct scic_sds_port *this_port)
{
u32 pts_control_value;
u32 tl_control_value;

pts_control_value = scu_port_task_scheduler_read(this_port, control);
tl_control_value = scu_transport_layer_read(this_port, control);

pts_control_value |= SCU_PTSxCR_GEN_BIT(SUSPEND);
tl_control_value |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);

scu_port_task_scheduler_write(this_port, control, pts_control_value);
scu_transport_layer_write(this_port, control, tl_control_value);
}

/**
Expand Down Expand Up @@ -2624,11 +2599,6 @@ static void scic_sds_port_resetting_state_enter(
scic_sds_port_set_base_state_handlers(
this_port, SCI_BASE_PORT_STATE_RESETTING
);

scic_sds_port_set_direct_attached_device_id(
this_port,
SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
);
}

/**
Expand Down
18 changes: 6 additions & 12 deletions drivers/scsi/isci/core/scic_sds_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,12 @@ struct scic_sds_port {
struct sci_base_state_machine ready_substate_machine;

/* / Memory mapped hardware register space */
/**
* This field is the pointer to the transport layer register for the SCU
* hardware.
*/
struct scu_transport_layer_registers *transport_layer_registers;

/**
* This field is the pointer to the port task scheduler registers for the SCU
* hardware.
*/
struct scu_port_task_scheduler_registers *port_task_scheduler_registers;
struct scu_port_task_scheduler_registers __iomem *port_task_scheduler_registers;

/**
* This field is identical for all port objects and points to the port task
Expand All @@ -202,7 +197,7 @@ struct scic_sds_port {
/**
* This field is the VIIT register space for ths port object.
*/
struct scu_viit_entry *viit_registers;
struct scu_viit_entry __iomem *viit_registers;

};

Expand Down Expand Up @@ -345,10 +340,9 @@ void scic_sds_port_construct(

enum sci_status scic_sds_port_initialize(
struct scic_sds_port *this_port,
void *transport_layer_registers,
void *port_task_scheduler_registers,
void *port_configuration_regsiter,
void *viit_registers);
void __iomem *port_task_scheduler_registers,
void __iomem *port_configuration_regsiter,
void __iomem *viit_registers);

/* --------------------------------------------------------------------------- */

Expand All @@ -360,7 +354,7 @@ enum sci_status scic_sds_port_remove_phy(
struct scic_sds_port *this_port,
struct scic_sds_phy *the_phy);

void scic_sds_port_set_direct_attached_device_id(
void scic_sds_port_setup_transports(
struct scic_sds_port *this_port,
u32 device_id);

Expand Down
Loading

0 comments on commit 2462146

Please sign in to comment.