diff --git a/drivers/scsi/isci/core/sci_base_port.h b/drivers/scsi/isci/core/sci_base_port.h index 4e2031d195f0..b931c3c2cdf9 100644 --- a/drivers/scsi/isci/core/sci_base_port.h +++ b/drivers/scsi/isci/core/sci_base_port.h @@ -188,16 +188,4 @@ struct sci_base_port_state_handler { SCI_BASE_PORT_PHY_HANDLER_T remove_phy_handler; }; - -/** - * sci_base_port_construct() - Construct the base port object - * @this_port: This parameter specifies the base port to be constructed. - * @state_table: This parameter specifies the table of state definitions to be - * utilized for the domain state machine. - * - */ -void sci_base_port_construct( - struct sci_base_port *this_port, - const struct sci_base_state *state_table); - #endif /* _SCI_BASE_PORT_H_ */ diff --git a/drivers/scsi/isci/core/scic_config_parameters.h b/drivers/scsi/isci/core/scic_config_parameters.h index f64f24fad5a3..cb6abcc7e7cd 100644 --- a/drivers/scsi/isci/core/scic_config_parameters.h +++ b/drivers/scsi/isci/core/scic_config_parameters.h @@ -260,19 +260,6 @@ enum sci_status scic_user_parameters_set( struct scic_sds_controller *controller, union scic_user_parameters *user_parameters); -/** - * scic_user_parameters_get() - This method allows the user to retrieve the - * user parameters utilized by the controller. - * @controller: This parameter specifies the controller on which to set the - * user parameters. - * @user_parameters: This parameter specifies the USER_PARAMETERS object into - * which the framework shall save it's parameters. - * - */ -void scic_user_parameters_get( - struct scic_sds_controller *controller, - union scic_user_parameters *user_parameters); - /** * scic_oem_parameters_set() - This method allows the user to attempt to change * the OEM parameters utilized by the controller. diff --git a/drivers/scsi/isci/core/scic_controller.h b/drivers/scsi/isci/core/scic_controller.h index 481e0de5148b..236c583162ec 100644 --- a/drivers/scsi/isci/core/scic_controller.h +++ b/drivers/scsi/isci/core/scic_controller.h @@ -56,14 +56,6 @@ #ifndef _SCIC_CONTROLLER_H_ #define _SCIC_CONTROLLER_H_ -/** - * This file contains all of the interface methods that can be called by an - * SCIC user on a controller object. - * - * - */ - - #include "sci_status.h" #include "sci_controller.h" #include "scic_config_parameters.h" @@ -79,417 +71,77 @@ enum sci_controller_mode { SCI_MODE_SIZE /* Optimized for memory use */ }; - -/** - * scic_controller_construct() - This method will attempt to construct a - * controller object utilizing the supplied parameter information. - * @c: This parameter specifies the controller to be constructed. - * @scu_base: mapped base address of the scu registers - * @smu_base: mapped base address of the smu registers - * - * Indicate if the controller was successfully constructed or if it failed in - * some way. SCI_SUCCESS This value is returned if the controller was - * successfully constructed. SCI_WARNING_TIMER_CONFLICT This value is returned - * if the interrupt coalescence timer may cause SAS compliance issues for SMP - * Target mode response processing. SCI_FAILURE_UNSUPPORTED_CONTROLLER_TYPE - * This value is returned if the controller does not support the supplied type. - * SCI_FAILURE_UNSUPPORTED_INIT_DATA_VERSION This value is returned if the - * controller does not support the supplied initialization data version. - */ enum sci_status scic_controller_construct(struct scic_sds_controller *c, void __iomem *scu_base, void __iomem *smu_base); -/** - * scic_controller_enable_interrupts() - This method will enable all controller - * interrupts. - * @controller: This parameter specifies the controller for which to enable - * interrupts. - * - */ void scic_controller_enable_interrupts( struct scic_sds_controller *controller); -/** - * scic_controller_disable_interrupts() - This method will disable all - * controller interrupts. - * @controller: This parameter specifies the controller for which to disable - * interrupts. - * - */ void scic_controller_disable_interrupts( struct scic_sds_controller *controller); - -/** - * scic_controller_initialize() - This method will initialize the controller - * hardware managed by the supplied core controller object. This method - * will bring the physical controller hardware out of reset and enable the - * core to determine the capabilities of the hardware being managed. Thus, - * the core controller can determine it's exact physical (DMA capable) - * memory requirements. - * @controller: This parameter specifies the controller to be initialized. - * - * The SCI Core user must have called scic_controller_construct() on the - * supplied controller object previously. Indicate if the controller was - * successfully initialized or if it failed in some way. SCI_SUCCESS This value - * is returned if the controller hardware was successfully initialized. - */ enum sci_status scic_controller_initialize( struct scic_sds_controller *controller); -/** - * scic_controller_get_suggested_start_timeout() - This method returns the - * suggested scic_controller_start() timeout amount. The user is free to - * use any timeout value, but this method provides the suggested minimum - * start timeout value. The returned value is based upon empirical - * information determined as a result of interoperability testing. - * @controller: the handle to the controller object for which to return the - * suggested start timeout. - * - * This method returns the number of milliseconds for the suggested start - * operation timeout. - */ u32 scic_controller_get_suggested_start_timeout( struct scic_sds_controller *controller); -/** - * scic_controller_start() - This method will start the supplied core - * controller. This method will start the staggered spin up operation. The - * SCI User completion callback is called when the following conditions are - * met: -# the return status of this method is SCI_SUCCESS. -# after all of - * the phys have successfully started or been given the opportunity to start. - * @controller: the handle to the controller object to start. - * @timeout: This parameter specifies the number of milliseconds in which the - * start operation should complete. - * - * The SCI Core user must have filled in the physical memory descriptor - * structure via the sci_controller_get_memory_descriptor_list() method. The - * SCI Core user must have invoked the scic_controller_initialize() method - * prior to invoking this method. The controller must be in the INITIALIZED or - * STARTED state. Indicate if the controller start method succeeded or failed - * in some way. SCI_SUCCESS if the start operation succeeded. - * SCI_WARNING_ALREADY_IN_STATE if the controller is already in the STARTED - * state. SCI_FAILURE_INVALID_STATE if the controller is not either in the - * INITIALIZED or STARTED states. SCI_FAILURE_INVALID_MEMORY_DESCRIPTOR if - * there are inconsistent or invalid values in the supplied - * struct sci_physical_memory_descriptor array. - */ enum sci_status scic_controller_start( struct scic_sds_controller *controller, u32 timeout); -/** - * scic_controller_stop() - This method will stop an individual controller - * object.This method will invoke the associated user callback upon - * completion. The completion callback is called when the following - * conditions are met: -# the method return status is SCI_SUCCESS. -# the - * controller has been quiesced. This method will ensure that all IO - * requests are quiesced, phys are stopped, and all additional operation by - * the hardware is halted. - * @controller: the handle to the controller object to stop. - * @timeout: This parameter specifies the number of milliseconds in which the - * stop operation should complete. - * - * The controller must be in the STARTED or STOPPED state. Indicate if the - * controller stop method succeeded or failed in some way. SCI_SUCCESS if the - * stop operation successfully began. SCI_WARNING_ALREADY_IN_STATE if the - * controller is already in the STOPPED state. SCI_FAILURE_INVALID_STATE if the - * controller is not either in the STARTED or STOPPED states. - */ enum sci_status scic_controller_stop( struct scic_sds_controller *controller, u32 timeout); -/** - * scic_controller_reset() - This method will reset the supplied core - * controller regardless of the state of said controller. This operation is - * considered destructive. In other words, all current operations are wiped - * out. No IO completions for outstanding devices occur. Outstanding IO - * requests are not aborted or completed at the actual remote device. - * @controller: the handle to the controller object to reset. - * - * Indicate if the controller reset method succeeded or failed in some way. - * SCI_SUCCESS if the reset operation successfully started. SCI_FATAL_ERROR if - * the controller reset operation is unable to complete. - */ enum sci_status scic_controller_reset( struct scic_sds_controller *controller); -/** - * scic_controller_start_io() - This method is called by the SCI user to - * send/start an IO request. If the method invocation is successful, then - * the IO request has been queued to the hardware for processing. - * @controller: the handle to the controller object for which to start an IO - * request. - * @remote_device: the handle to the remote device object for which to start an - * IO request. - * @io_request: the handle to the io request object to start. - * @io_tag: This parameter specifies a previously allocated IO tag that the - * user desires to be utilized for this request. This parameter is optional. - * The user is allowed to supply SCI_CONTROLLER_INVALID_IO_TAG as the value - * for this parameter. - * - * - IO tags are a protected resource. It is incumbent upon the SCI Core user - * to ensure that each of the methods that may allocate or free available IO - * tags are handled in a mutually exclusive manner. This method is one of said - * methods requiring proper critical code section protection (e.g. semaphore, - * spin-lock, etc.). - For SATA, the user is required to manage NCQ tags. As a - * result, it is expected the user will have set the NCQ tag field in the host - * to device register FIS prior to calling this method. There is also a - * requirement for the user to call scic_stp_io_set_ncq_tag() prior to invoking - * the scic_controller_start_io() method. scic_controller_allocate_tag() for - * more information on allocating a tag. Indicate if the controller - * successfully started the IO request. SCI_IO_SUCCESS if the IO request was - * successfully started. Determine the failure situations and return values. - */ enum sci_io_status scic_controller_start_io( struct scic_sds_controller *controller, struct scic_sds_remote_device *remote_device, struct scic_sds_request *io_request, u16 io_tag); - -/** - * scic_controller_start_task() - This method is called by the SCIC user to - * send/start a framework task management request. - * @controller: the handle to the controller object for which to start the task - * management request. - * @remote_device: the handle to the remote device object for which to start - * the task management request. - * @task_request: the handle to the task request object to start. - * @io_tag: This parameter specifies a previously allocated IO tag that the - * user desires to be utilized for this request. Note this not the io_tag - * of the request being managed. It is to be utilized for the task request - * itself. This parameter is optional. The user is allowed to supply - * SCI_CONTROLLER_INVALID_IO_TAG as the value for this parameter. - * - * - IO tags are a protected resource. It is incumbent upon the SCI Core user - * to ensure that each of the methods that may allocate or free available IO - * tags are handled in a mutually exclusive manner. This method is one of said - * methods requiring proper critical code section protection (e.g. semaphore, - * spin-lock, etc.). - The user must synchronize this task with completion - * queue processing. If they are not synchronized then it is possible for the - * io requests that are being managed by the task request can complete before - * starting the task request. scic_controller_allocate_tag() for more - * information on allocating a tag. Indicate if the controller successfully - * started the IO request. SCI_TASK_SUCCESS if the task request was - * successfully started. SCI_TASK_FAILURE_REQUIRES_SCSI_ABORT This value is - * returned if there is/are task(s) outstanding that require termination or - * completion before this request can succeed. - */ enum sci_task_status scic_controller_start_task( struct scic_sds_controller *controller, struct scic_sds_remote_device *remote_device, struct scic_sds_request *task_request, u16 io_tag); -/** - * scic_controller_complete_task() - This method will perform core specific - * completion operations for task management request. After this method is - * invoked, the user should consider the task request as invalid until it is - * properly reused (i.e. re-constructed). - * @controller: The handle to the controller object for which to complete the - * task management request. - * @remote_device: The handle to the remote device object for which to complete - * the task management request. - * @task_request: the handle to the task management request object to complete. - * - * Indicate if the controller successfully completed the task management - * request. SCI_SUCCESS if the completion process was successful. - */ enum sci_status scic_controller_complete_task( struct scic_sds_controller *controller, struct scic_sds_remote_device *remote_device, struct scic_sds_request *task_request); - -/** - * scic_controller_terminate_request() - This method is called by the SCI Core - * user to terminate an ongoing (i.e. started) core IO request. This does - * not abort the IO request at the target, but rather removes the IO request - * from the host controller. - * @controller: the handle to the controller object for which to terminate a - * request. - * @remote_device: the handle to the remote device object for which to - * terminate a request. - * @request: the handle to the io or task management request object to - * terminate. - * - * Indicate if the controller successfully began the terminate process for the - * IO request. SCI_SUCCESS if the terminate process was successfully started - * for the request. Determine the failure situations and return values. - */ enum sci_status scic_controller_terminate_request( struct scic_sds_controller *controller, struct scic_sds_remote_device *remote_device, struct scic_sds_request *request); -/** - * scic_controller_complete_io() - This method will perform core specific - * completion operations for an IO request. After this method is invoked, - * the user should consider the IO request as invalid until it is properly - * reused (i.e. re-constructed). - * @controller: The handle to the controller object for which to complete the - * IO request. - * @remote_device: The handle to the remote device object for which to complete - * the IO request. - * @io_request: the handle to the io request object to complete. - * - * - IO tags are a protected resource. It is incumbent upon the SCI Core user - * to ensure that each of the methods that may allocate or free available IO - * tags are handled in a mutually exclusive manner. This method is one of said - * methods requiring proper critical code section protection (e.g. semaphore, - * spin-lock, etc.). - If the IO tag for a request was allocated, by the SCI - * Core user, using the scic_controller_allocate_io_tag() method, then it is - * the responsibility of the caller to invoke the scic_controller_free_io_tag() - * method to free the tag (i.e. this method will not free the IO tag). Indicate - * if the controller successfully completed the IO request. SCI_SUCCESS if the - * completion process was successful. - */ enum sci_status scic_controller_complete_io( struct scic_sds_controller *controller, struct scic_sds_remote_device *remote_device, struct scic_sds_request *io_request); - -/** - * scic_controller_get_port_handle() - This method simply provides the user - * with a unique handle for a given SAS/SATA core port index. - * @controller: This parameter represents the handle to the controller object - * from which to retrieve a port (SAS or SATA) handle. - * @port_index: This parameter specifies the port index in the controller for - * which to retrieve the port handle. 0 <= port_index < maximum number of - * phys. - * @port_handle: This parameter specifies the retrieved port handle to be - * provided to the caller. - * - * Indicate if the retrieval of the port handle was successful. SCI_SUCCESS - * This value is returned if the retrieval was successful. - * SCI_FAILURE_INVALID_PORT This value is returned if the supplied port id is - * not in the supported range. - */ enum sci_status scic_controller_get_port_handle( struct scic_sds_controller *controller, u8 port_index, struct scic_sds_port **port_handle); -/** - * 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 *controller, u8 phy_index, struct scic_sds_phy **phy_handle); -/** - * 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 - * tag if this method is not utilized and the tag is not supplied to the IO - * construct routine. Direct allocation of IO tags may provide additional - * performance improvements in environments capable of supporting this usage - * model. Additionally, direct allocation of IO tags also provides - * additional flexibility to the SCI Core user. Specifically, the user may - * retain IO tags across the lives of multiple IO requests. - * @controller: the handle to the controller object for which to allocate the - * tag. - * - * IO tags are a protected resource. It is incumbent upon the SCI Core user to - * ensure that each of the methods that may allocate or free available IO tags - * are handled in a mutually exclusive manner. This method is one of said - * methods requiring proper critical code section protection (e.g. semaphore, - * spin-lock, etc.). An unsigned integer representing an available IO tag. - * SCI_CONTROLLER_INVALID_IO_TAG This value is returned if there are no - * currently available tags to be allocated. All return other values indicate a - * legitimate tag. - */ u16 scic_controller_allocate_io_tag( struct scic_sds_controller *controller); -/** - * scic_controller_free_io_tag() - This method will free an IO tag to the pool - * of free IO tags. This method provides the SCI Core user more flexibility - * with regards to IO tags. The user may desire to keep an IO tag after an - * IO request has completed, because they plan on re-using the tag for a - * subsequent IO request. This method is only legal if the tag was - * allocated via scic_controller_allocate_io_tag(). - * @controller: This parameter specifies the handle to the controller object - * for which to free/return the tag. - * @io_tag: This parameter represents the tag to be freed to the pool of - * available tags. - * - * - IO tags are a protected resource. It is incumbent upon the SCI Core user - * to ensure that each of the methods that may allocate or free available IO - * tags are handled in a mutually exclusive manner. This method is one of said - * methods requiring proper critical code section protection (e.g. semaphore, - * spin-lock, etc.). - If the IO tag for a request was allocated, by the SCI - * Core user, using the scic_controller_allocate_io_tag() method, then it is - * the responsibility of the caller to invoke this method to free the tag. This - * method returns an indication of whether the tag was successfully put back - * (freed) to the pool of available tags. SCI_SUCCESS This return value - * indicates the tag was successfully placed into the pool of available IO - * tags. SCI_FAILURE_INVALID_IO_TAG This value is returned if the supplied tag - * is not a valid IO tag value. - */ enum sci_status scic_controller_free_io_tag( struct scic_sds_controller *controller, u16 io_tag); - - - -/** - * scic_controller_set_mode() - This method allows the user to configure the - * SCI core into either a performance mode or a memory savings mode. - * @controller: This parameter represents the handle to the controller object - * for which to update the operating mode. - * @mode: This parameter specifies the new mode for the controller. - * - * Indicate if the user successfully change the operating mode of the - * controller. SCI_SUCCESS The user successfully updated the mode. - */ -enum sci_status scic_controller_set_mode( - struct scic_sds_controller *controller, - enum sci_controller_mode mode); - - -/** - * scic_controller_set_interrupt_coalescence() - This method allows the user to - * configure the interrupt coalescence. - * @controller: This parameter represents the handle to the controller object - * for which its interrupt coalesce register is overridden. - * @coalesce_number: Used to control the number of entries in the Completion - * Queue before an interrupt is generated. If the number of entries exceed - * this number, an interrupt will be generated. The valid range of the input - * is [0, 256]. A setting of 0 results in coalescing being disabled. - * @coalesce_timeout: Timeout value in microseconds. The valid range of the - * input is [0, 2700000] . A setting of 0 is allowed and results in no - * interrupt coalescing timeout. - * - * Indicate if the user successfully set the interrupt coalesce parameters. - * SCI_SUCCESS The user successfully updated the interrutp coalescence. - * SCI_FAILURE_INVALID_PARAMETER_VALUE The user input value is out of range. - */ -enum sci_status scic_controller_set_interrupt_coalescence( - struct scic_sds_controller *controller, - u32 coalesce_number, - u32 coalesce_timeout); - struct device; struct scic_sds_controller *scic_controller_alloc(struct device *dev); - - #endif /* _SCIC_CONTROLLER_H_ */ - diff --git a/drivers/scsi/isci/core/scic_io_request.h b/drivers/scsi/isci/core/scic_io_request.h index a52f33d94abd..fea894a0d28e 100644 --- a/drivers/scsi/isci/core/scic_io_request.h +++ b/drivers/scsi/isci/core/scic_io_request.h @@ -325,7 +325,7 @@ enum sci_status scic_io_request_construct( struct scic_sds_remote_device *scic_remote_device, u16 io_tag, void *user_io_request_object, - void *scic_io_request_memory, + struct scic_sds_request *scic_io_request_memory, struct scic_sds_request **new_scic_io_request_handle); /** diff --git a/drivers/scsi/isci/core/scic_port.h b/drivers/scsi/isci/core/scic_port.h index 8222443c9fd7..582953343237 100644 --- a/drivers/scsi/isci/core/scic_port.h +++ b/drivers/scsi/isci/core/scic_port.h @@ -56,14 +56,6 @@ #ifndef _SCIC_PORT_H_ #define _SCIC_PORT_H_ -/** - * This file contains all of the interface methods that can be called by an SCI - * Core user on a SAS or SATA port. - * - * - */ - - #include "sci_status.h" #include "intel_sas.h" @@ -78,118 +70,28 @@ enum SCIC_PORT_NOT_READY_REASON_CODE { SCIC_PORT_NOT_READY_REASON_CODE_MAX }; -/** - * struct scic_port_end_point_properties - This structure defines the - * properties that can be retrieved for each end-point local or remote - * (attached) port in the controller. - * - * - */ struct scic_port_end_point_properties { - /** - * This field indicates the SAS address for the associated end - * point in the port. - */ struct sci_sas_address sas_address; - - /** - * This field indicates the protocols supported by the associated - * end-point in the port. - */ struct sci_sas_identify_address_frame_protocols protocols; }; -/** - * struct scic_port_properties - This structure defines the properties that can - * be retrieved for each port in the controller. - * - * - */ struct scic_port_properties { - /** - * This field specifies the logical index of the port (0 relative). - */ u32 index; - - /** - * This field indicates the local end-point properties for port. - */ struct scic_port_end_point_properties local; - - /** - * This field indicates the remote (attached) end-point properties - * for the port. - */ struct scic_port_end_point_properties remote; - - /** - * This field specifies the phys contained inside the port. - */ u32 phy_mask; - }; -/** - * scic_port_get_properties() - This method simply returns the properties - * regarding the port, such as: physical index, protocols, sas address, etc. - * @port: this parameter specifies the port for which to retrieve the physical - * index. - * @properties: This parameter specifies the properties structure into which to - * copy the requested information. - * - * Indicate if the user specified a valid port. SCI_SUCCESS This value is - * returned if the specified port was valid. SCI_FAILURE_INVALID_PORT This - * value is returned if the specified port is not valid. When this value is - * returned, no data is copied to the properties output parameter. - */ enum sci_status scic_port_get_properties( struct scic_sds_port *port, struct scic_port_properties *properties); -/** - * scic_port_stop() - This method will make the port no longer ready for - * operation. After invoking this method IO operation is not possible. - * @port: This parameter specifies the port to be stopped. - * - * Indicate if the port was successfully stopped. SCI_SUCCESS This value is - * returned if the port was successfully stopped. SCI_WARNING_ALREADY_IN_STATE - * This value is returned if the port is already stopped or in the process of - * stopping. SCI_FAILURE_INVALID_PORT This value is returned if the supplied - * port is not valid. SCI_FAILURE_INVALID_STATE This value is returned if a - * stop operation can't be completed due to the state of port. - */ -enum sci_status scic_port_stop( - struct scic_sds_port *port); - -/** - * scic_port_hard_reset() - This method will request the SCI implementation to - * perform a HARD RESET on the SAS Port. If/When the HARD RESET completes - * the SCI user will be notified via an SCI OS callback indicating a direct - * attached device was found. - * @port: a handle corresponding to the SAS port to be hard reset. - * @reset_timeout: This parameter specifies the number of milliseconds in which - * the port reset operation should complete. - * - * The SCI User callback in SCIC_USER_CALLBACKS_T will only be called once for - * each phy in the SAS Port at completion of the hard reset sequence. Return a - * status indicating whether the hard reset started successfully. SCI_SUCCESS - * This value is returned if the hard reset operation started successfully. - */ enum sci_status scic_port_hard_reset( struct scic_sds_port *port, u32 reset_timeout); -/** - * scic_port_enable_broadcast_change_notification() - This API method enables - * the broadcast change notification from underneath hardware. - * @port: The port upon which broadcast change notifications (BCN) are to be - * enabled. - * - */ void scic_port_enable_broadcast_change_notification( struct scic_sds_port *port); - #endif /* _SCIC_PORT_H_ */ - diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c index 7d25a0aafb66..5cc6f2fa0939 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.c +++ b/drivers/scsi/isci/core/scic_sds_controller.c @@ -219,98 +219,33 @@ sci_controller_get_memory_descriptor_list_handle(struct scic_sds_controller *sci return &scic->parent.mdl; } -/* - * ****************************************************************************- - * * SCIC SDS Controller Initialization Methods - * ****************************************************************************- */ - -/** - * This timer is used to start another phy after we have given up on the - * previous phy to transition to the ready state. - * - * - */ -static void scic_sds_controller_phy_startup_timeout_handler( - void *controller) -{ - enum sci_status status; - struct scic_sds_controller *this_controller; - - this_controller = (struct scic_sds_controller *)controller; - - this_controller->phy_startup_timer_pending = false; - - status = SCI_FAILURE; - - while (status != SCI_SUCCESS) { - status = scic_sds_controller_start_next_phy(this_controller); - } -} - -/** - * - * - * This method initializes the phy startup operations for controller start. - */ -enum sci_status scic_sds_controller_initialize_phy_startup( - struct scic_sds_controller *scic) +static void scic_sds_controller_initialize_power_control(struct scic_sds_controller *scic) { struct isci_host *ihost = sci_object_get_association(scic); + scic->power_control.timer = isci_timer_create(ihost, + scic, + scic_sds_controller_power_control_timer_handler); - scic->phy_startup_timer = isci_timer_create(ihost, - scic, - scic_sds_controller_phy_startup_timeout_handler); - - if (scic->phy_startup_timer == NULL) - return SCI_FAILURE_INSUFFICIENT_RESOURCES; - else { - scic->next_phy_to_start = 0; - scic->phy_startup_timer_pending = false; - } - - return SCI_SUCCESS; -} - -/** - * - * - * This method initializes the power control operations for the controller - * object. - */ -void scic_sds_controller_initialize_power_control( - struct scic_sds_controller *scic) -{ - struct isci_host *ihost = sci_object_get_association(scic); - scic->power_control.timer = isci_timer_create( - ihost, - scic, - scic_sds_controller_power_control_timer_handler); - - memset(scic->power_control.requesters, - 0, + memset(scic->power_control.requesters, 0, sizeof(scic->power_control.requesters)); scic->power_control.phys_waiting = 0; scic->power_control.phys_granted_power = 0; } -/* --------------------------------------------------------------------------- */ - #define SCU_REMOTE_NODE_CONTEXT_ALIGNMENT (32) #define SCU_TASK_CONTEXT_ALIGNMENT (256) #define SCU_UNSOLICITED_FRAME_ADDRESS_ALIGNMENT (64) #define SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT (1024) #define SCU_UNSOLICITED_FRAME_HEADER_ALIGNMENT (64) -/* --------------------------------------------------------------------------- */ - /** * This method builds the memory descriptor table for this controller. * @this_controller: This parameter specifies the controller object for which * to build the memory table. * */ -void scic_sds_controller_build_memory_descriptor_table( +static void scic_sds_controller_build_memory_descriptor_table( struct scic_sds_controller *this_controller) { sci_base_mde_construct( @@ -356,7 +291,7 @@ void scic_sds_controller_build_memory_descriptor_table( * * enum sci_status */ -enum sci_status scic_sds_controller_validate_memory_descriptor_table( +static enum sci_status scic_sds_controller_validate_memory_descriptor_table( struct scic_sds_controller *this_controller) { bool mde_list_valid; @@ -410,7 +345,7 @@ enum sci_status scic_sds_controller_validate_memory_descriptor_table( * @this_controller: * */ -void scic_sds_controller_ram_initialization( +static void scic_sds_controller_ram_initialization( struct scic_sds_controller *this_controller) { struct sci_physical_memory_descriptor *mde; @@ -457,7 +392,7 @@ void scic_sds_controller_ram_initialization( * @this_controller: * */ -void scic_sds_controller_assign_task_entries( +static void scic_sds_controller_assign_task_entries( struct scic_sds_controller *this_controller) { u32 task_assignment; @@ -483,7 +418,7 @@ void scic_sds_controller_assign_task_entries( * * */ -void scic_sds_controller_initialize_completion_queue( +static void scic_sds_controller_initialize_completion_queue( struct scic_sds_controller *this_controller) { u32 index; @@ -533,7 +468,7 @@ void scic_sds_controller_initialize_completion_queue( * * */ -void scic_sds_controller_initialize_unsolicited_frame_queue( +static void scic_sds_controller_initialize_unsolicited_frame_queue( struct scic_sds_controller *this_controller) { u32 frame_queue_control_value; @@ -565,7 +500,7 @@ void scic_sds_controller_initialize_unsolicited_frame_queue( * * */ -void scic_sds_controller_enable_port_task_scheduler( +static void scic_sds_controller_enable_port_task_scheduler( struct scic_sds_controller *this_controller) { u32 port_task_scheduler_value; @@ -578,8 +513,6 @@ void scic_sds_controller_enable_port_task_scheduler( SCU_PTSGCR_WRITE(this_controller, port_task_scheduler_value); } -/* --------------------------------------------------------------------------- */ - /** * * @@ -591,7 +524,7 @@ void scic_sds_controller_enable_port_task_scheduler( /* Initialize the AFE for this phy index. We need to read the AFE setup from * the OEM parameters none */ -void scic_sds_controller_afe_initialization(struct scic_sds_controller *scic) +static void scic_sds_controller_afe_initialization(struct scic_sds_controller *scic) { const struct scic_sds_oem_params *oem = &scic->oem_parameters.sds1; u32 afe_status; @@ -746,7 +679,7 @@ static void scic_sds_controller_transition_to_ready( } } -void scic_sds_controller_timeout_handler(void *_scic) +static void scic_sds_controller_timeout_handler(void *_scic) { struct scic_sds_controller *scic = _scic; struct isci_host *ihost = sci_object_get_association(scic); @@ -764,7 +697,7 @@ void scic_sds_controller_timeout_handler(void *_scic) __func__); } -enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller *scic) +static enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller *scic) { u32 index; enum sci_status port_status; @@ -802,8 +735,7 @@ static inline void scic_sds_controller_phy_timer_start( scic->phy_startup_timer_pending = true; } -inline void scic_sds_controller_phy_timer_stop( - struct scic_sds_controller *scic) +static void scic_sds_controller_phy_timer_stop(struct scic_sds_controller *scic) { isci_timer_stop(scic->phy_startup_timer); @@ -811,16 +743,14 @@ inline void scic_sds_controller_phy_timer_stop( } /** - * This method is called internally by the controller object to start the next - * phy on the controller. If all the phys have been started, then this - * method will attempt to transition the controller to the READY state and - * inform the user (scic_cb_controller_start_complete()). - * @this_controller: This parameter specifies the controller object for which - * to start the next phy. + * scic_sds_controller_start_next_phy - start phy + * @scic: controller * - * enum sci_status + * If all the phys have been started, then attempt to transition the + * controller to the READY state and inform the user + * (scic_cb_controller_start_complete()). */ -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 scic_sds_oem_params *oem = &scic->oem_parameters.sds1; struct scic_sds_phy *sci_phy; @@ -907,14 +837,36 @@ enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_controller *s return status; } -/** - * - * @this_controller: - * - * enum sci_status - */ -enum sci_status scic_sds_controller_stop_phys( - struct scic_sds_controller *this_controller) +static void scic_sds_controller_phy_startup_timeout_handler(void *_scic) +{ + struct scic_sds_controller *scic = _scic; + enum sci_status status; + + scic->phy_startup_timer_pending = false; + status = SCI_FAILURE; + while (status != SCI_SUCCESS) + status = scic_sds_controller_start_next_phy(scic); +} + +static enum sci_status scic_sds_controller_initialize_phy_startup(struct scic_sds_controller *scic) +{ + struct isci_host *ihost = sci_object_get_association(scic); + + scic->phy_startup_timer = isci_timer_create(ihost, + scic, + scic_sds_controller_phy_startup_timeout_handler); + + if (scic->phy_startup_timer == NULL) + return SCI_FAILURE_INSUFFICIENT_RESOURCES; + else { + scic->next_phy_to_start = 0; + scic->phy_startup_timer_pending = false; + } + + return SCI_SUCCESS; +} + +static enum sci_status scic_sds_controller_stop_phys(struct scic_sds_controller *scic) { u32 index; enum sci_status status; @@ -923,7 +875,7 @@ enum sci_status scic_sds_controller_stop_phys( status = SCI_SUCCESS; for (index = 0; index < SCI_MAX_PHYS; index++) { - phy_status = scic_sds_phy_stop(&this_controller->phy_table[index]); + phy_status = scic_sds_phy_stop(&scic->phy_table[index]); if ( (phy_status != SCI_SUCCESS) @@ -931,25 +883,18 @@ enum sci_status scic_sds_controller_stop_phys( ) { status = SCI_FAILURE; - dev_warn(scic_to_dev(this_controller), + dev_warn(scic_to_dev(scic), "%s: Controller stop operation failed to stop " "phy %d because of status %d.\n", __func__, - this_controller->phy_table[index].phy_index, phy_status); + scic->phy_table[index].phy_index, phy_status); } } return status; } -/** - * - * @this_controller: - * - * enum sci_status - */ -enum sci_status scic_sds_controller_stop_devices( - struct scic_sds_controller *this_controller) +static enum sci_status scic_sds_controller_stop_devices(struct scic_sds_controller *scic) { u32 index; enum sci_status status; @@ -957,19 +902,19 @@ enum sci_status scic_sds_controller_stop_devices( status = SCI_SUCCESS; - for (index = 0; index < this_controller->remote_node_entries; index++) { - if (this_controller->device_table[index] != NULL) { + for (index = 0; index < scic->remote_node_entries; index++) { + if (scic->device_table[index] != NULL) { /* / @todo What timeout value do we want to provide to this request? */ - device_status = scic_remote_device_stop(this_controller->device_table[index], 0); + device_status = scic_remote_device_stop(scic->device_table[index], 0); if ((device_status != SCI_SUCCESS) && (device_status != SCI_FAILURE_INVALID_STATE)) { - dev_warn(scic_to_dev(this_controller), + dev_warn(scic_to_dev(scic), "%s: Controller stop operation failed " "to stop device 0x%p because of " "status %d.\n", __func__, - this_controller->device_table[index], device_status); + scic->device_table[index], device_status); } } } @@ -977,18 +922,7 @@ enum sci_status scic_sds_controller_stop_devices( return status; } -/* - * ****************************************************************************- - * * SCIC SDS Controller Power Control (Staggered Spinup) - * ****************************************************************************- */ - -/** - * This function starts the power control timer for this controller object. - * - * @param scic - */ -static inline void scic_sds_controller_power_control_timer_start( - struct scic_sds_controller *scic) +static void scic_sds_controller_power_control_timer_start(struct scic_sds_controller *scic) { isci_timer_start(scic->power_control.timer, SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL); @@ -996,13 +930,7 @@ static inline void scic_sds_controller_power_control_timer_start( scic->power_control.timer_started = true; } -/** - * This method stops the power control timer for this controller object. - * - * @param scic - */ -static inline void scic_sds_controller_power_control_timer_stop( - struct scic_sds_controller *scic) +static void scic_sds_controller_power_control_timer_stop(struct scic_sds_controller *scic) { if (scic->power_control.timer_started) { isci_timer_stop(scic->power_control.timer); @@ -1010,24 +938,12 @@ static inline void scic_sds_controller_power_control_timer_stop( } } -/** - * This method stops and starts the power control timer for this controller - * object. - * - * @param scic - */ -static inline void scic_sds_controller_power_control_timer_restart( - struct scic_sds_controller *scic) +static void scic_sds_controller_power_control_timer_restart(struct scic_sds_controller *scic) { scic_sds_controller_power_control_timer_stop(scic); scic_sds_controller_power_control_timer_start(scic); } -/** - * - * - * - */ static void scic_sds_controller_power_control_timer_handler( void *controller) { @@ -1146,8 +1062,6 @@ static bool scic_sds_controller_completion_queue_has_entries( return false; } -/* --------------------------------------------------------------------------- */ - /** * This method processes a task completion notification. This is called from * within the controller completion handler. @@ -1625,10 +1539,6 @@ void scic_sds_controller_error_handler(struct scic_sds_controller *scic) } -u32 scic_sds_controller_get_object_size(void) -{ - return sizeof(struct scic_sds_controller); -} void scic_sds_controller_link_up( @@ -1703,7 +1613,7 @@ void scic_sds_controller_remote_device_started(struct scic_sds_controller *scic, * controller are still in the stopping state. * */ -bool scic_sds_controller_has_remote_devices_stopping( +static bool scic_sds_controller_has_remote_devices_stopping( struct scic_sds_controller *this_controller) { u32 index; @@ -2042,62 +1952,20 @@ static void scic_sds_controller_set_default_config_parameters(struct scic_sds_co scic->user_parameters.sds1.no_outbound_task_timeout = 20; } - -enum sci_status scic_controller_construct(struct scic_sds_controller *controller, - void __iomem *scu_base, - void __iomem *smu_base) -{ - u8 index; - - sci_base_controller_construct( - &controller->parent, - scic_sds_controller_state_table, - controller->memory_descriptors, - ARRAY_SIZE(controller->memory_descriptors), - NULL - ); - - controller->scu_registers = scu_base; - controller->smu_registers = smu_base; - - scic_sds_port_configuration_agent_construct(&controller->port_agent); - - /* Construct the ports for this controller */ - for (index = 0; index < SCI_MAX_PORTS; index++) - scic_sds_port_construct(&controller->port_table[index], - index, controller); - scic_sds_port_construct(&controller->port_table[index], - SCIC_SDS_DUMMY_PORT, controller); - - /* Construct the phys for this controller */ - for (index = 0; index < SCI_MAX_PHYS; index++) { - /* Add all the PHYs to the dummy port */ - scic_sds_phy_construct( - &controller->phy_table[index], - &controller->port_table[SCI_MAX_PORTS], - index - ); - } - - controller->invalid_phy_mask = 0; - - /* Set the default maximum values */ - controller->completion_event_entries = SCU_EVENT_COUNT; - controller->completion_queue_entries = SCU_COMPLETION_QUEUE_COUNT; - controller->remote_node_entries = SCI_MAX_REMOTE_DEVICES; - controller->logical_port_entries = SCI_MAX_PORTS; - controller->task_context_entries = SCU_IO_REQUEST_COUNT; - controller->uf_control.buffers.count = SCU_UNSOLICITED_FRAME_COUNT; - controller->uf_control.address_table.count = SCU_UNSOLICITED_FRAME_COUNT; - - /* Initialize the User and OEM parameters to default values. */ - scic_sds_controller_set_default_config_parameters(controller); - - return scic_controller_reset(controller); -} - -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_initialize() - This method will initialize the controller + * hardware managed by the supplied core controller object. This method + * will bring the physical controller hardware out of reset and enable the + * core to determine the capabilities of the hardware being managed. Thus, + * the core controller can determine it's exact physical (DMA capable) + * memory requirements. + * @controller: This parameter specifies the controller to be initialized. + * + * The SCI Core user must have called scic_controller_construct() on the + * supplied controller object previously. Indicate if the controller was + * successfully initialized or if it failed in some way. SCI_SUCCESS This value + * is returned if the controller hardware was successfully initialized. + */ enum sci_status scic_controller_initialize( struct scic_sds_controller *scic) { @@ -2118,8 +1986,18 @@ enum sci_status scic_controller_initialize( return status; } -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_get_suggested_start_timeout() - This method returns the + * suggested scic_controller_start() timeout amount. The user is free to + * use any timeout value, but this method provides the suggested minimum + * start timeout value. The returned value is based upon empirical + * information determined as a result of interoperability testing. + * @controller: the handle to the controller object for which to return the + * suggested start timeout. + * + * This method returns the number of milliseconds for the suggested start + * operation timeout. + */ u32 scic_controller_get_suggested_start_timeout( struct scic_sds_controller *sc) { @@ -2146,8 +2024,28 @@ u32 scic_controller_get_suggested_start_timeout( + ((SCI_MAX_PHYS - 1) * SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL); } -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_start() - This method will start the supplied core + * controller. This method will start the staggered spin up operation. The + * SCI User completion callback is called when the following conditions are + * met: -# the return status of this method is SCI_SUCCESS. -# after all of + * the phys have successfully started or been given the opportunity to start. + * @controller: the handle to the controller object to start. + * @timeout: This parameter specifies the number of milliseconds in which the + * start operation should complete. + * + * The SCI Core user must have filled in the physical memory descriptor + * structure via the sci_controller_get_memory_descriptor_list() method. The + * SCI Core user must have invoked the scic_controller_initialize() method + * prior to invoking this method. The controller must be in the INITIALIZED or + * STARTED state. Indicate if the controller start method succeeded or failed + * in some way. SCI_SUCCESS if the start operation succeeded. + * SCI_WARNING_ALREADY_IN_STATE if the controller is already in the STARTED + * state. SCI_FAILURE_INVALID_STATE if the controller is not either in the + * INITIALIZED or STARTED states. SCI_FAILURE_INVALID_MEMORY_DESCRIPTOR if + * there are inconsistent or invalid values in the supplied + * struct sci_physical_memory_descriptor array. + */ enum sci_status scic_controller_start( struct scic_sds_controller *scic, u32 timeout) @@ -2169,8 +2067,24 @@ enum sci_status scic_controller_start( return status; } -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_stop() - This method will stop an individual controller + * object.This method will invoke the associated user callback upon + * completion. The completion callback is called when the following + * conditions are met: -# the method return status is SCI_SUCCESS. -# the + * controller has been quiesced. This method will ensure that all IO + * requests are quiesced, phys are stopped, and all additional operation by + * the hardware is halted. + * @controller: the handle to the controller object to stop. + * @timeout: This parameter specifies the number of milliseconds in which the + * stop operation should complete. + * + * The controller must be in the STARTED or STOPPED state. Indicate if the + * controller stop method succeeded or failed in some way. SCI_SUCCESS if the + * stop operation successfully began. SCI_WARNING_ALREADY_IN_STATE if the + * controller is already in the STOPPED state. SCI_FAILURE_INVALID_STATE if the + * controller is not either in the STARTED or STOPPED states. + */ enum sci_status scic_controller_stop( struct scic_sds_controller *scic, u32 timeout) @@ -2192,8 +2106,18 @@ enum sci_status scic_controller_stop( return status; } -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_reset() - This method will reset the supplied core + * controller regardless of the state of said controller. This operation is + * considered destructive. In other words, all current operations are wiped + * out. No IO completions for outstanding devices occur. Outstanding IO + * requests are not aborted or completed at the actual remote device. + * @controller: the handle to the controller object to reset. + * + * Indicate if the controller reset method succeeded or failed in some way. + * SCI_SUCCESS if the reset operation successfully started. SCI_FATAL_ERROR if + * the controller reset operation is unable to complete. + */ enum sci_status scic_controller_reset( struct scic_sds_controller *scic) { @@ -2214,6 +2138,33 @@ enum sci_status scic_controller_reset( return status; } +/** + * scic_controller_start_io() - This method is called by the SCI user to + * send/start an IO request. If the method invocation is successful, then + * the IO request has been queued to the hardware for processing. + * @controller: the handle to the controller object for which to start an IO + * request. + * @remote_device: the handle to the remote device object for which to start an + * IO request. + * @io_request: the handle to the io request object to start. + * @io_tag: This parameter specifies a previously allocated IO tag that the + * user desires to be utilized for this request. This parameter is optional. + * The user is allowed to supply SCI_CONTROLLER_INVALID_IO_TAG as the value + * for this parameter. + * + * - IO tags are a protected resource. It is incumbent upon the SCI Core user + * to ensure that each of the methods that may allocate or free available IO + * tags are handled in a mutually exclusive manner. This method is one of said + * methods requiring proper critical code section protection (e.g. semaphore, + * spin-lock, etc.). - For SATA, the user is required to manage NCQ tags. As a + * result, it is expected the user will have set the NCQ tag field in the host + * to device register FIS prior to calling this method. There is also a + * requirement for the user to call scic_stp_io_set_ncq_tag() prior to invoking + * the scic_controller_start_io() method. scic_controller_allocate_tag() for + * more information on allocating a tag. Indicate if the controller + * successfully started the IO request. SCI_IO_SUCCESS if the IO request was + * successfully started. Determine the failure situations and return values. + */ enum sci_io_status scic_controller_start_io( struct scic_sds_controller *scic, struct scic_sds_remote_device *remote_device, @@ -2231,8 +2182,22 @@ enum sci_io_status scic_controller_start_io( (struct sci_base_request *)io_request, io_tag); } -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_terminate_request() - This method is called by the SCI Core + * user to terminate an ongoing (i.e. started) core IO request. This does + * not abort the IO request at the target, but rather removes the IO request + * from the host controller. + * @controller: the handle to the controller object for which to terminate a + * request. + * @remote_device: the handle to the remote device object for which to + * terminate a request. + * @request: the handle to the io or task management request object to + * terminate. + * + * Indicate if the controller successfully began the terminate process for the + * IO request. SCI_SUCCESS if the terminate process was successfully started + * for the request. Determine the failure situations and return values. + */ enum sci_status scic_controller_terminate_request( struct scic_sds_controller *scic, struct scic_sds_remote_device *remote_device, @@ -2249,8 +2214,28 @@ enum sci_status scic_controller_terminate_request( (struct sci_base_request *)request); } -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_complete_io() - This method will perform core specific + * completion operations for an IO request. After this method is invoked, + * the user should consider the IO request as invalid until it is properly + * reused (i.e. re-constructed). + * @controller: The handle to the controller object for which to complete the + * IO request. + * @remote_device: The handle to the remote device object for which to complete + * the IO request. + * @io_request: the handle to the io request object to complete. + * + * - IO tags are a protected resource. It is incumbent upon the SCI Core user + * to ensure that each of the methods that may allocate or free available IO + * tags are handled in a mutually exclusive manner. This method is one of said + * methods requiring proper critical code section protection (e.g. semaphore, + * spin-lock, etc.). - If the IO tag for a request was allocated, by the SCI + * Core user, using the scic_controller_allocate_io_tag() method, then it is + * the responsibility of the caller to invoke the scic_controller_free_io_tag() + * method to free the tag (i.e. this method will not free the IO tag). Indicate + * if the controller successfully completed the IO request. SCI_SUCCESS if the + * completion process was successful. + */ enum sci_status scic_controller_complete_io( struct scic_sds_controller *scic, struct scic_sds_remote_device *remote_device, @@ -2267,9 +2252,34 @@ enum sci_status scic_controller_complete_io( (struct sci_base_request *)io_request); } -/* --------------------------------------------------------------------------- */ - - +/** + * scic_controller_start_task() - This method is called by the SCIC user to + * send/start a framework task management request. + * @controller: the handle to the controller object for which to start the task + * management request. + * @remote_device: the handle to the remote device object for which to start + * the task management request. + * @task_request: the handle to the task request object to start. + * @io_tag: This parameter specifies a previously allocated IO tag that the + * user desires to be utilized for this request. Note this not the io_tag + * of the request being managed. It is to be utilized for the task request + * itself. This parameter is optional. The user is allowed to supply + * SCI_CONTROLLER_INVALID_IO_TAG as the value for this parameter. + * + * - IO tags are a protected resource. It is incumbent upon the SCI Core user + * to ensure that each of the methods that may allocate or free available IO + * tags are handled in a mutually exclusive manner. This method is one of said + * methods requiring proper critical code section protection (e.g. semaphore, + * spin-lock, etc.). - The user must synchronize this task with completion + * queue processing. If they are not synchronized then it is possible for the + * io requests that are being managed by the task request can complete before + * starting the task request. scic_controller_allocate_tag() for more + * information on allocating a tag. Indicate if the controller successfully + * started the IO request. SCI_TASK_SUCCESS if the task request was + * successfully started. SCI_TASK_FAILURE_REQUIRES_SCSI_ABORT This value is + * returned if there is/are task(s) outstanding that require termination or + * completion before this request can succeed. + */ enum sci_task_status scic_controller_start_task( struct scic_sds_controller *scic, struct scic_sds_remote_device *remote_device, @@ -2297,8 +2307,20 @@ enum sci_task_status scic_controller_start_task( return status; } -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_complete_task() - This method will perform core specific + * completion operations for task management request. After this method is + * invoked, the user should consider the task request as invalid until it is + * properly reused (i.e. re-constructed). + * @controller: The handle to the controller object for which to complete the + * task management request. + * @remote_device: The handle to the remote device object for which to complete + * the task management request. + * @task_request: the handle to the task management request object to complete. + * + * Indicate if the controller successfully completed the task management + * request. SCI_SUCCESS if the completion process was successful. + */ enum sci_status scic_controller_complete_task( struct scic_sds_controller *scic, struct scic_sds_remote_device *remote_device, @@ -2325,8 +2347,22 @@ enum sci_status scic_controller_complete_task( } -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_get_port_handle() - This method simply provides the user + * with a unique handle for a given SAS/SATA core port index. + * @controller: This parameter represents the handle to the controller object + * from which to retrieve a port (SAS or SATA) handle. + * @port_index: This parameter specifies the port index in the controller for + * which to retrieve the port handle. 0 <= port_index < maximum number of + * phys. + * @port_handle: This parameter specifies the retrieved port handle to be + * provided to the caller. + * + * Indicate if the retrieval of the port handle was successful. SCI_SUCCESS + * This value is returned if the retrieval was successful. + * SCI_FAILURE_INVALID_PORT This value is returned if the supplied port id is + * not in the supported range. + */ enum sci_status scic_controller_get_port_handle( struct scic_sds_controller *scic, u8 port_index, @@ -2341,8 +2377,20 @@ enum sci_status scic_controller_get_port_handle( return SCI_FAILURE_INVALID_PORT; } -/* --------------------------------------------------------------------------- */ - +/** + * 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, @@ -2361,8 +2409,28 @@ enum sci_status scic_controller_get_phy_handle( 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 + * tag if this method is not utilized and the tag is not supplied to the IO + * construct routine. Direct allocation of IO tags may provide additional + * performance improvements in environments capable of supporting this usage + * model. Additionally, direct allocation of IO tags also provides + * additional flexibility to the SCI Core user. Specifically, the user may + * retain IO tags across the lives of multiple IO requests. + * @controller: the handle to the controller object for which to allocate the + * tag. + * + * IO tags are a protected resource. It is incumbent upon the SCI Core user to + * ensure that each of the methods that may allocate or free available IO tags + * are handled in a mutually exclusive manner. This method is one of said + * methods requiring proper critical code section protection (e.g. semaphore, + * spin-lock, etc.). An unsigned integer representing an available IO tag. + * SCI_CONTROLLER_INVALID_IO_TAG This value is returned if there are no + * currently available tags to be allocated. All return other values indicate a + * legitimate tag. + */ u16 scic_controller_allocate_io_tag( struct scic_sds_controller *scic) { @@ -2380,8 +2448,31 @@ u16 scic_controller_allocate_io_tag( return SCI_CONTROLLER_INVALID_IO_TAG; } -/* --------------------------------------------------------------------------- */ - +/** + * scic_controller_free_io_tag() - This method will free an IO tag to the pool + * of free IO tags. This method provides the SCI Core user more flexibility + * with regards to IO tags. The user may desire to keep an IO tag after an + * IO request has completed, because they plan on re-using the tag for a + * subsequent IO request. This method is only legal if the tag was + * allocated via scic_controller_allocate_io_tag(). + * @controller: This parameter specifies the handle to the controller object + * for which to free/return the tag. + * @io_tag: This parameter represents the tag to be freed to the pool of + * available tags. + * + * - IO tags are a protected resource. It is incumbent upon the SCI Core user + * to ensure that each of the methods that may allocate or free available IO + * tags are handled in a mutually exclusive manner. This method is one of said + * methods requiring proper critical code section protection (e.g. semaphore, + * spin-lock, etc.). - If the IO tag for a request was allocated, by the SCI + * Core user, using the scic_controller_allocate_io_tag() method, then it is + * the responsibility of the caller to invoke this method to free the tag. This + * method returns an indication of whether the tag was successfully put back + * (freed) to the pool of available tags. SCI_SUCCESS This return value + * indicates the tag was successfully placed into the pool of available IO + * tags. SCI_FAILURE_INVALID_IO_TAG This value is returned if the supplied tag + * is not a valid IO tag value. + */ enum sci_status scic_controller_free_io_tag( struct scic_sds_controller *scic, u16 io_tag) @@ -2408,8 +2499,6 @@ enum sci_status scic_controller_free_io_tag( return SCI_FAILURE_INVALID_IO_TAG; } -/* --------------------------------------------------------------------------- */ - void scic_controller_enable_interrupts( struct scic_sds_controller *scic) { @@ -2417,8 +2506,6 @@ void scic_controller_enable_interrupts( SMU_IMR_WRITE(scic, 0x00000000); } -/* --------------------------------------------------------------------------- */ - void scic_controller_disable_interrupts( struct scic_sds_controller *scic) { @@ -2426,9 +2513,7 @@ void scic_controller_disable_interrupts( SMU_IMR_WRITE(scic, 0xffffffff); } -/* --------------------------------------------------------------------------- */ - -enum sci_status scic_controller_set_mode( +static enum sci_status scic_controller_set_mode( struct scic_sds_controller *scic, enum sci_controller_mode operating_mode) { @@ -2476,7 +2561,7 @@ enum sci_status scic_controller_set_mode( * * This method will reset the controller hardware. */ -void scic_sds_controller_reset_hardware( +static void scic_sds_controller_reset_hardware( struct scic_sds_controller *scic) { /* Disable interrupts so we dont take any spurious interrupts */ @@ -2495,8 +2580,6 @@ void scic_sds_controller_reset_hardware( SCU_UFQGP_WRITE(scic, 0x00000000); } -/* --------------------------------------------------------------------------- */ - enum sci_status scic_user_parameters_set( struct scic_sds_controller *scic, union scic_user_parameters *scic_parms) @@ -2551,17 +2634,6 @@ enum sci_status scic_user_parameters_set( return SCI_FAILURE_INVALID_STATE; } -/* --------------------------------------------------------------------------- */ - -void scic_user_parameters_get( - struct scic_sds_controller *scic, - union scic_user_parameters *scic_parms) -{ - memcpy(scic_parms, (&scic->user_parameters), sizeof(*scic_parms)); -} - -/* --------------------------------------------------------------------------- */ - enum sci_status scic_oem_parameters_set( struct scic_sds_controller *scic, union scic_oem_parameters *scic_parms) @@ -2616,8 +2688,6 @@ enum sci_status scic_oem_parameters_set( return SCI_FAILURE_INVALID_STATE; } -/* --------------------------------------------------------------------------- */ - void scic_oem_parameters_get( struct scic_sds_controller *scic, union scic_oem_parameters *scic_parms) @@ -2625,9 +2695,6 @@ void scic_oem_parameters_get( memcpy(scic_parms, (&scic->oem_parameters), sizeof(*scic_parms)); } -/* --------------------------------------------------------------------------- */ - - #define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_LOWER_BOUND_NS 853 #define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_UPPER_BOUND_NS 1280 #define INTERRUPT_COALESCE_TIMEOUT_MAX_US 2700000 @@ -2635,7 +2702,24 @@ void scic_oem_parameters_get( #define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MIN 7 #define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX 28 -enum sci_status scic_controller_set_interrupt_coalescence( +/** + * scic_controller_set_interrupt_coalescence() - This method allows the user to + * configure the interrupt coalescence. + * @controller: This parameter represents the handle to the controller object + * for which its interrupt coalesce register is overridden. + * @coalesce_number: Used to control the number of entries in the Completion + * Queue before an interrupt is generated. If the number of entries exceed + * this number, an interrupt will be generated. The valid range of the input + * is [0, 256]. A setting of 0 results in coalescing being disabled. + * @coalesce_timeout: Timeout value in microseconds. The valid range of the + * input is [0, 2700000] . A setting of 0 is allowed and results in no + * interrupt coalescing timeout. + * + * Indicate if the user successfully set the interrupt coalesce parameters. + * SCI_SUCCESS The user successfully updated the interrutp coalescence. + * SCI_FAILURE_INVALID_PARAMETER_VALUE The user input value is out of range. + */ +static enum sci_status scic_controller_set_interrupt_coalescence( struct scic_sds_controller *scic_controller, u32 coalesce_number, u32 coalesce_timeout) @@ -3419,7 +3503,7 @@ static enum sci_status scic_sds_controller_stopping_state_complete_io_handler( * This method is called when the struct scic_sds_controller is in a stopping state * and the remote device has stopped. **/ -void scic_sds_controller_stopping_state_device_stopped_handler( +static void scic_sds_controller_stopping_state_device_stopped_handler( struct scic_sds_controller *controller, struct scic_sds_remote_device *remote_device ) @@ -3638,7 +3722,7 @@ static void scic_sds_controller_resetting_state_enter(struct sci_base_object *ob SCI_BASE_CONTROLLER_STATE_RESET); } -const struct sci_base_state scic_sds_controller_state_table[] = { +static const struct sci_base_state scic_sds_controller_state_table[] = { [SCI_BASE_CONTROLLER_STATE_INITIAL] = { .enter_state = scic_sds_controller_initial_state_enter, }, @@ -3662,3 +3746,64 @@ const struct sci_base_state scic_sds_controller_state_table[] = { [SCI_BASE_CONTROLLER_STATE_STOPPED] = {}, [SCI_BASE_CONTROLLER_STATE_FAILED] = {} }; + +/** + * scic_controller_construct() - This method will attempt to construct a + * controller object utilizing the supplied parameter information. + * @c: This parameter specifies the controller to be constructed. + * @scu_base: mapped base address of the scu registers + * @smu_base: mapped base address of the smu registers + * + * Indicate if the controller was successfully constructed or if it failed in + * some way. SCI_SUCCESS This value is returned if the controller was + * successfully constructed. SCI_WARNING_TIMER_CONFLICT This value is returned + * if the interrupt coalescence timer may cause SAS compliance issues for SMP + * Target mode response processing. SCI_FAILURE_UNSUPPORTED_CONTROLLER_TYPE + * This value is returned if the controller does not support the supplied type. + * SCI_FAILURE_UNSUPPORTED_INIT_DATA_VERSION This value is returned if the + * controller does not support the supplied initialization data version. + */ +enum sci_status scic_controller_construct(struct scic_sds_controller *scic, + void __iomem *scu_base, + void __iomem *smu_base) +{ + u8 i; + + sci_base_controller_construct(&scic->parent, + scic_sds_controller_state_table, + scic->memory_descriptors, + ARRAY_SIZE(scic->memory_descriptors), NULL); + + scic->scu_registers = scu_base; + scic->smu_registers = smu_base; + + scic_sds_port_configuration_agent_construct(&scic->port_agent); + + /* Construct the ports for this controller */ + for (i = 0; i < SCI_MAX_PORTS; i++) + scic_sds_port_construct(&scic->port_table[i], i, scic); + scic_sds_port_construct(&scic->port_table[i], SCIC_SDS_DUMMY_PORT, scic); + + /* 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->port_table[SCI_MAX_PORTS], i); + } + + scic->invalid_phy_mask = 0; + + /* Set the default maximum values */ + scic->completion_event_entries = SCU_EVENT_COUNT; + scic->completion_queue_entries = SCU_COMPLETION_QUEUE_COUNT; + scic->remote_node_entries = SCI_MAX_REMOTE_DEVICES; + scic->logical_port_entries = SCI_MAX_PORTS; + scic->task_context_entries = SCU_IO_REQUEST_COUNT; + scic->uf_control.buffers.count = SCU_UNSOLICITED_FRAME_COUNT; + scic->uf_control.address_table.count = SCU_UNSOLICITED_FRAME_COUNT; + + /* Initialize the User and OEM parameters to default values. */ + scic_sds_controller_set_default_config_parameters(scic); + + return scic_controller_reset(scic); +} diff --git a/drivers/scsi/isci/core/scic_sds_controller.h b/drivers/scsi/isci/core/scic_sds_controller.h index aa2698bb7ca1..fedf5032d898 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.h +++ b/drivers/scsi/isci/core/scic_sds_controller.h @@ -402,7 +402,6 @@ struct scic_sds_controller_state_handler { extern const struct scic_sds_controller_state_handler scic_sds_controller_state_handler_table[]; -extern const struct sci_base_state scic_sds_controller_state_table[]; /** * INCREMENT_QUEUE_GET() - @@ -535,7 +534,6 @@ extern const struct sci_base_state scic_sds_controller_state_table[]; /* --------------------------------------------------------------------------- */ -u32 scic_sds_controller_get_object_size(void); /* --------------------------------------------------------------------------- */ @@ -615,8 +613,6 @@ void scic_sds_controller_link_down( * * CORE CONTROLLER REMOTE DEVICE MESSAGE PROCESSING * ***************************************************************************** */ -bool scic_sds_controller_has_remote_devices_stopping( - struct scic_sds_controller *this_controller); void scic_sds_controller_remote_device_started( struct scic_sds_controller *this_controller, @@ -626,67 +622,11 @@ void scic_sds_controller_remote_device_stopped( struct scic_sds_controller *this_controller, struct scic_sds_remote_device *the_device); - -/* - * ***************************************************************************** - * * CORE CONTROLLER PRIVATE METHODS - * ***************************************************************************** */ - -enum sci_status scic_sds_controller_validate_memory_descriptor_table( - struct scic_sds_controller *this_controller); - -void scic_sds_controller_ram_initialization( - struct scic_sds_controller *this_controller); - -void scic_sds_controller_assign_task_entries( - struct scic_sds_controller *this_controller); - -void scic_sds_controller_afe_initialization( - struct scic_sds_controller *this_controller); - -void scic_sds_controller_enable_port_task_scheduler( - struct scic_sds_controller *this_controller); - -void scic_sds_controller_initialize_completion_queue( - struct scic_sds_controller *this_controller); - -void scic_sds_controller_initialize_unsolicited_frame_queue( - struct scic_sds_controller *this_controller); - -void scic_sds_controller_phy_timer_stop( - struct scic_sds_controller *this_controller); - -enum sci_status scic_sds_controller_start_next_phy( - struct scic_sds_controller *this_controller); - -enum sci_status scic_sds_controller_stop_phys( - struct scic_sds_controller *this_controller); - -enum sci_status scic_sds_controller_stop_ports( - struct scic_sds_controller *this_controller); - -enum sci_status scic_sds_controller_stop_devices( - struct scic_sds_controller *this_controller); - void scic_sds_controller_copy_task_context( struct scic_sds_controller *this_controller, struct scic_sds_request *this_request); -void scic_sds_controller_timeout_handler(void *controller); - -void scic_sds_controller_initialize_power_control( - struct scic_sds_controller *this_controller); - void scic_sds_controller_register_setup( struct scic_sds_controller *this_controller); -void scic_sds_controller_reset_hardware( - struct scic_sds_controller *this_controller); - -enum sci_status scic_sds_controller_initialize_phy_startup( - struct scic_sds_controller *this_controller); - -void scic_sds_controller_build_memory_descriptor_table( - struct scic_sds_controller *this_controller); - #endif /* _SCIC_SDS_CONTROLLER_H_ */ diff --git a/drivers/scsi/isci/core/scic_sds_phy.c b/drivers/scsi/isci/core/scic_sds_phy.c index e546e20f1ffd..532338eb302b 100644 --- a/drivers/scsi/isci/core/scic_sds_phy.c +++ b/drivers/scsi/isci/core/scic_sds_phy.c @@ -257,7 +257,7 @@ scic_sds_phy_link_layer_initialization(struct scic_sds_phy *sci_phy, * restart the starting substate machine since we dont know what has actually * happening. */ -void scic_sds_phy_sata_timeout(void *phy) +static void scic_sds_phy_sata_timeout(void *phy) { struct scic_sds_phy *sci_phy = phy; @@ -273,47 +273,6 @@ void scic_sds_phy_sata_timeout(void *phy) SCI_BASE_PHY_STATE_STARTING); } -/** - * This method will construct the struct scic_sds_phy object - * @this_phy: - * @owning_port: - * @phy_index: - * - */ -void scic_sds_phy_construct( - struct scic_sds_phy *this_phy, - struct scic_sds_port *owning_port, - u8 phy_index) -{ - /* - * Call the base constructor first - */ - sci_base_phy_construct( - &this_phy->parent, - scic_sds_phy_state_table - ); - - /* Copy the rest of the input data to our locals */ - this_phy->owning_port = owning_port; - this_phy->phy_index = phy_index; - this_phy->bcn_received_while_port_unassigned = false; - this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN; - this_phy->link_layer_registers = NULL; - this_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE; - this_phy->sata_timeout_timer = NULL; - - /* Clear out the identification buffer data */ - memset(&this_phy->phy_type, 0, sizeof(this_phy->phy_type)); - - /* Initialize the the substate machines */ - sci_base_state_machine_construct( - &this_phy->starting_substate_machine, - &this_phy->parent.parent, - scic_sds_phy_starting_substates, - SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL - ); -} - /** * This method returns the port currently containing this phy. If the phy is * currently contained by the dummy port, then the phy is considered to not @@ -426,7 +385,7 @@ void scic_sds_phy_setup_transport( * This function will perform the register reads/writes to suspend the SCU * hardware protocol engine. none */ -void scic_sds_phy_suspend( +static void scic_sds_phy_suspend( struct scic_sds_phy *this_phy) { u32 scu_sas_pcfg_value; @@ -1416,7 +1375,62 @@ static enum sci_status scic_sds_phy_starting_substate_await_sata_power_consume_p return SCI_SUCCESS; } -const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table[] = { +static enum sci_status default_phy_handler(struct sci_base_phy *base_phy, const char *func) +{ + struct scic_sds_phy *sci_phy; + + sci_phy = container_of(base_phy, typeof(*sci_phy), parent); + dev_dbg(sciphy_to_dev(sci_phy), + "%s: in wrong state: %d\n", func, + sci_base_state_machine_get_state(&base_phy->state_machine)); + return SCI_FAILURE_INVALID_STATE; +} + +static enum sci_status scic_sds_phy_default_start_handler(struct sci_base_phy *base_phy) +{ + return default_phy_handler(base_phy, __func__); +} + +static enum sci_status scic_sds_phy_default_stop_handler(struct sci_base_phy *base_phy) +{ + return default_phy_handler(base_phy, __func__); +} + +static enum sci_status scic_sds_phy_default_reset_handler(struct sci_base_phy *base_phy) +{ + return default_phy_handler(base_phy, __func__); +} + +static enum sci_status scic_sds_phy_default_destroy_handler(struct sci_base_phy *base_phy) +{ + return default_phy_handler(base_phy, __func__); +} + +static enum sci_status scic_sds_phy_default_frame_handler(struct scic_sds_phy *sci_phy, + u32 frame_index) +{ + struct scic_sds_controller *scic = scic_sds_phy_get_controller(sci_phy); + + default_phy_handler(&sci_phy->parent, __func__); + scic_sds_controller_release_frame(scic, frame_index); + + return SCI_FAILURE_INVALID_STATE; +} + +static enum sci_status scic_sds_phy_default_event_handler(struct scic_sds_phy *sci_phy, + u32 event_code) +{ + return default_phy_handler(&sci_phy->parent, __func__); +} + +static enum sci_status scic_sds_phy_default_consume_power_handler(struct scic_sds_phy *sci_phy) +{ + return default_phy_handler(&sci_phy->parent, __func__); +} + + + +static const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table[] = { [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = { .parent.start_handler = scic_sds_phy_default_start_handler, .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler, @@ -1867,7 +1881,7 @@ static void scic_sds_phy_starting_final_substate_enter(struct sci_base_object *o /* --------------------------------------------------------------------------- */ -const struct sci_base_state scic_sds_phy_starting_substates[] = { +static const struct sci_base_state scic_sds_phy_starting_substates[] = { [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = { .enter_state = scic_sds_phy_starting_initial_substate_enter, }, @@ -1905,196 +1919,6 @@ const struct sci_base_state scic_sds_phy_starting_substates[] = { } }; -/* - * *************************************************************************** - * * DEFAULT HANDLERS - * *************************************************************************** */ - -/** - * - * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy - * object. - * - * This is the default method for phy a start request. It will report a - * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE - */ -enum sci_status scic_sds_phy_default_start_handler( - struct sci_base_phy *phy) -{ - struct scic_sds_phy *this_phy; - - this_phy = (struct scic_sds_phy *)phy; - - dev_warn(sciphy_to_dev(this_phy), - "%s: SCIC Phy 0x%p requested to start from invalid " - "state %d\n", - __func__, - this_phy, - sci_base_state_machine_get_state( - &this_phy->parent.state_machine)); - - return SCI_FAILURE_INVALID_STATE; - -} - -/** - * - * @phy: This is the struct sci_base_phy object which is cast into a - * struct scic_sds_phy object. - * - * This is the default method for phy a stop request. It will report a warning - * and exit. enum sci_status SCI_FAILURE_INVALID_STATE - */ -enum sci_status scic_sds_phy_default_stop_handler(struct sci_base_phy *base_phy) -{ - struct scic_sds_phy *sci_phy; - - sci_phy = (struct scic_sds_phy *)base_phy; - - dev_dbg(sciphy_to_dev(sci_phy), - "%s: SCIC Phy 0x%p requested to stop from invalid state %d\n", - __func__, - sci_phy, - sci_base_state_machine_get_state( - &sci_phy->parent.state_machine)); - - return SCI_FAILURE_INVALID_STATE; -} - -/** - * - * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy - * object. - * - * This is the default method for phy a reset request. It will report a - * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE - */ -enum sci_status scic_sds_phy_default_reset_handler( - struct sci_base_phy *phy) -{ - struct scic_sds_phy *this_phy; - - this_phy = (struct scic_sds_phy *)phy; - - dev_warn(sciphy_to_dev(this_phy), - "%s: SCIC Phy 0x%p requested to reset from invalid state " - "%d\n", - __func__, - this_phy, - sci_base_state_machine_get_state( - &this_phy->parent.state_machine)); - - return SCI_FAILURE_INVALID_STATE; -} - -/** - * - * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy - * object. - * - * This is the default method for phy a destruct request. It will report a - * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE - */ -enum sci_status scic_sds_phy_default_destroy_handler( - struct sci_base_phy *phy) -{ - struct scic_sds_phy *this_phy; - - this_phy = (struct scic_sds_phy *)phy; - - /* / @todo Implement something for the default */ - dev_warn(sciphy_to_dev(this_phy), - "%s: SCIC Phy 0x%p requested to destroy from invalid " - "state %d\n", - __func__, - this_phy, - sci_base_state_machine_get_state( - &this_phy->parent.state_machine)); - - return SCI_FAILURE_INVALID_STATE; -} - -/** - * - * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy - * object. - * @frame_index: This is the frame index that was received from the SCU - * hardware. - * - * This is the default method for a phy frame handling request. It will report - * a warning, release the frame and exit. enum sci_status SCI_FAILURE_INVALID_STATE - */ -enum sci_status scic_sds_phy_default_frame_handler( - struct scic_sds_phy *this_phy, - u32 frame_index) -{ - dev_warn(sciphy_to_dev(this_phy), - "%s: SCIC Phy 0x%p received unexpected frame data %d " - "while in state %d\n", - __func__, - this_phy, - frame_index, - sci_base_state_machine_get_state( - &this_phy->parent.state_machine)); - - scic_sds_controller_release_frame( - scic_sds_phy_get_controller(this_phy), frame_index); - - return SCI_FAILURE_INVALID_STATE; -} - -/** - * - * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy - * object. - * @event_code: This is the event code that was received from the SCU hardware. - * - * This is the default method for a phy event handler. It will report a - * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE - */ -enum sci_status scic_sds_phy_default_event_handler( - struct scic_sds_phy *this_phy, - u32 event_code) -{ - dev_dbg(sciphy_to_dev(this_phy), - "%s: SCIC Phy 0x%p received unexpected event status %x " - "while in state %d\n", - __func__, - this_phy, - event_code, - sci_base_state_machine_get_state( - &this_phy->parent.state_machine)); - - return SCI_FAILURE_INVALID_STATE; -} - -/** - * - * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy - * object. - * - * This is the default method for a phy consume power handler. It will report - * a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE - */ -enum sci_status scic_sds_phy_default_consume_power_handler( - struct scic_sds_phy *this_phy) -{ - dev_warn(sciphy_to_dev(this_phy), - "%s: SCIC Phy 0x%p given unexpected permission to consume " - "power while in state %d\n", - __func__, - this_phy, - sci_base_state_machine_get_state( - &this_phy->parent.state_machine)); - - return SCI_FAILURE_INVALID_STATE; -} - -/* - * ****************************************************************************** - * * PHY STOPPED STATE HANDLERS - * ****************************************************************************** */ - /** * * @phy: This is the struct sci_base_phy object which is cast into a @@ -2219,7 +2043,7 @@ static enum sci_status scic_sds_phy_resetting_state_event_handler(struct scic_sd /* --------------------------------------------------------------------------- */ -const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[] = { +static const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[] = { [SCI_BASE_PHY_STATE_INITIAL] = { .parent.start_handler = scic_sds_phy_default_start_handler, .parent.stop_handler = scic_sds_phy_default_stop_handler, @@ -2563,7 +2387,7 @@ static void scic_sds_phy_final_state_enter( /* --------------------------------------------------------------------------- */ -const struct sci_base_state scic_sds_phy_state_table[] = { +static const struct sci_base_state scic_sds_phy_state_table[] = { [SCI_BASE_PHY_STATE_INITIAL] = { .enter_state = scic_sds_phy_initial_state_enter, }, @@ -2585,3 +2409,29 @@ const struct sci_base_state scic_sds_phy_state_table[] = { }, }; +void scic_sds_phy_construct(struct scic_sds_phy *sci_phy, + struct scic_sds_port *owning_port, u8 phy_index) +{ + /* + * Call the base constructor first + */ + sci_base_phy_construct(&sci_phy->parent, scic_sds_phy_state_table); + + /* Copy the rest of the input data to our locals */ + sci_phy->owning_port = owning_port; + sci_phy->phy_index = phy_index; + sci_phy->bcn_received_while_port_unassigned = false; + sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN; + sci_phy->link_layer_registers = NULL; + sci_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE; + sci_phy->sata_timeout_timer = NULL; + + /* Clear out the identification buffer data */ + memset(&sci_phy->phy_type, 0, sizeof(sci_phy->phy_type)); + + /* Initialize the the substate machines */ + sci_base_state_machine_construct(&sci_phy->starting_substate_machine, + &sci_phy->parent.parent, + scic_sds_phy_starting_substates, + SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL); +} diff --git a/drivers/scsi/isci/core/scic_sds_phy.h b/drivers/scsi/isci/core/scic_sds_phy.h index af9e24c30945..4745a791f15b 100644 --- a/drivers/scsi/isci/core/scic_sds_phy.h +++ b/drivers/scsi/isci/core/scic_sds_phy.h @@ -293,12 +293,6 @@ struct scic_sds_phy_state_handler { }; -extern const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[]; -extern const struct sci_base_state scic_sds_phy_state_table[]; -extern const struct sci_base_state scic_sds_phy_starting_substates[]; -extern const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table[]; - - /** * scic_sds_phy_get_index() - * @@ -362,12 +356,6 @@ enum sci_status scic_sds_phy_stop( enum sci_status scic_sds_phy_reset( struct scic_sds_phy *this_phy); -void scic_sds_phy_sata_timeout( - void *cookie); - -void scic_sds_phy_suspend( - struct scic_sds_phy *this_phy); - void scic_sds_phy_resume( struct scic_sds_phy *this_phy); @@ -402,27 +390,4 @@ void scic_sds_phy_get_attached_phy_protocols( struct scic_sds_phy *this_phy, struct sci_sas_identify_address_frame_protocols *protocols); -enum sci_status scic_sds_phy_default_start_handler( - struct sci_base_phy *phy); - -enum sci_status scic_sds_phy_default_stop_handler( - struct sci_base_phy *phy); - -enum sci_status scic_sds_phy_default_reset_handler( - struct sci_base_phy *phy); - -enum sci_status scic_sds_phy_default_destroy_handler( - struct sci_base_phy *phy); - -enum sci_status scic_sds_phy_default_frame_handler( - struct scic_sds_phy *phy, - u32 frame_index); - -enum sci_status scic_sds_phy_default_event_handler( - struct scic_sds_phy *phy, - u32 evnet_code); - -enum sci_status scic_sds_phy_default_consume_power_handler( - struct scic_sds_phy *phy); - #endif /* _SCIC_SDS_PHY_H_ */ diff --git a/drivers/scsi/isci/core/scic_sds_port.c b/drivers/scsi/isci/core/scic_sds_port.c index 72b815ef98ca..0a95f649c04f 100644 --- a/drivers/scsi/isci/core/scic_sds_port.c +++ b/drivers/scsi/isci/core/scic_sds_port.c @@ -69,19 +69,13 @@ #include "sci_environment.h" #include "scic_sds_controller_registers.h" - -static void scic_sds_port_invalid_link_up( - struct scic_sds_port *this_port, - struct scic_sds_phy *phy); -static void scic_sds_port_timeout_handler( - void *port); #define SCIC_SDS_PORT_MIN_TIMER_COUNT (SCI_MAX_PORTS) #define SCIC_SDS_PORT_MAX_TIMER_COUNT (SCI_MAX_PORTS) #define SCIC_SDS_PORT_HARD_RESET_TIMEOUT (1000) #define SCU_DUMMY_INDEX (0xFFFF) -void sci_base_port_construct( +static void sci_base_port_construct( struct sci_base_port *base_port, const struct sci_base_state *state_table) { @@ -168,7 +162,7 @@ bool scic_sds_port_is_valid_phy_assignment( * Return a bit mask indicating which phys are a part of this port. Each bit * corresponds to a phy identifier (e.g. bit 0 = phy id 0). */ -u32 scic_sds_port_get_phys(struct scic_sds_port *this_port) +static u32 scic_sds_port_get_phys(struct scic_sds_port *this_port) { u32 index; u32 mask; @@ -196,7 +190,7 @@ u32 scic_sds_port_get_phys(struct scic_sds_port *this_port) * phy mask can be supported. true if this is a valid phy assignment for the * port false if this is not a valid phy assignment for the port */ -bool scic_sds_port_is_phy_mask_valid( +static bool scic_sds_port_is_phy_mask_valid( struct scic_sds_port *this_port, u32 phy_mask) { @@ -269,7 +263,7 @@ static struct scic_sds_phy *scic_sds_port_get_a_connected_phy( * is a functional test that only fails if the phy is currently assigned to a * different port. */ -enum sci_status scic_sds_port_set_phy( +static enum sci_status scic_sds_port_set_phy( struct scic_sds_port *port, struct scic_sds_phy *phy) { @@ -304,7 +298,7 @@ enum sci_status scic_sds_port_set_phy( * this phy is not currently assinged to this port. bool true if the phy is * removed from the port. false if this phy is not assined to this port. */ -enum sci_status scic_sds_port_clear_phy( +static enum sci_status scic_sds_port_clear_phy( struct scic_sds_port *port, struct scic_sds_phy *phy) { @@ -485,7 +479,7 @@ void scic_sds_port_get_attached_protocols( * This structure will be posted to the hardware to work around a scheduler * error in the hardware. */ -void scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u16 rni) +static void scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u16 rni) { union scu_remote_node_context *rnc; @@ -520,7 +514,7 @@ void scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u16 rni) * in the hardware. * */ -void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tci) +static void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tci) { struct scu_task_context *task_context; @@ -554,7 +548,7 @@ void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tci) task_context->task_phase = 0x01; } -void scic_sds_port_destroy_dummy_resources(struct scic_sds_port *sci_port) +static void scic_sds_port_destroy_dummy_resources(struct scic_sds_port *sci_port) { struct scic_sds_controller *scic = sci_port->owning_controller; @@ -569,38 +563,6 @@ void scic_sds_port_destroy_dummy_resources(struct scic_sds_port *sci_port) sci_port->reserved_tci = SCU_DUMMY_INDEX; } -void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 port_index, - struct scic_sds_controller *scic) -{ - u32 index; - - sci_base_port_construct(&sci_port->parent, scic_sds_port_state_table); - - sci_base_state_machine_construct(&sci_port->ready_substate_machine, - &sci_port->parent.parent, - scic_sds_port_ready_substate_table, - SCIC_SDS_PORT_READY_SUBSTATE_WAITING); - - sci_port->logical_port_index = SCIC_SDS_DUMMY_PORT; - sci_port->physical_port_index = port_index; - sci_port->active_phy_mask = 0; - - sci_port->owning_controller = scic; - - sci_port->started_request_count = 0; - sci_port->assigned_device_count = 0; - - sci_port->reserved_rni = SCU_DUMMY_INDEX; - sci_port->reserved_tci = SCU_DUMMY_INDEX; - - sci_port->timer_handle = NULL; - - sci_port->port_task_scheduler_registers = NULL; - - for (index = 0; index < SCI_MAX_PHYS; index++) - sci_port->phy_table[index] = NULL; -} - /** * This method performs initialization of the supplied port. Initialization * includes: - state machine initialization - member variable initialization @@ -627,61 +589,18 @@ enum sci_status scic_sds_port_initialize( } /** + * scic_port_get_properties() - This method simply returns the properties + * regarding the port, such as: physical index, protocols, sas address, etc. + * @port: this parameter specifies the port for which to retrieve the physical + * index. + * @properties: This parameter specifies the properties structure into which to + * copy the requested information. * - * @this_port: This is the struct scic_sds_port object for which has a phy that has - * gone link up. - * @the_phy: This is the struct scic_sds_phy object that has gone link up. - * @do_notify_user: This parameter specifies whether to inform the user (via - * scic_cb_port_link_up()) as to the fact that a new phy as become ready. - * - * This method is the a general link up handler for the struct scic_sds_port object. - * This function will determine if this struct scic_sds_phy can be assigned to this - * struct scic_sds_port object. If the struct scic_sds_phy object can is not a valid PHY for - * this port then the function will notify the SCIC_USER. A PHY can only be - * part of a port if it's attached SAS ADDRESS is the same as all other PHYs in - * the same port. none + * Indicate if the user specified a valid port. SCI_SUCCESS This value is + * returned if the specified port was valid. SCI_FAILURE_INVALID_PORT This + * value is returned if the specified port is not valid. When this value is + * returned, no data is copied to the properties output parameter. */ -void scic_sds_port_general_link_up_handler( - struct scic_sds_port *this_port, - struct scic_sds_phy *the_phy, - bool do_notify_user) -{ - struct sci_sas_address port_sas_address; - struct sci_sas_address phy_sas_address; - - scic_sds_port_get_attached_sas_address(this_port, &port_sas_address); - scic_sds_phy_get_attached_sas_address(the_phy, &phy_sas_address); - - /* - * If the SAS address of the new phy matches the SAS address of - * other phys in the port OR this is the first phy in the port, - * then activate the phy and allow it to be used for operations - * in this port. */ - if ( - ( - (phy_sas_address.high == port_sas_address.high) - && (phy_sas_address.low == port_sas_address.low) - ) - || (this_port->active_phy_mask == 0) - ) { - scic_sds_port_activate_phy(this_port, the_phy, do_notify_user); - - if (this_port->parent.state_machine.current_state_id - == SCI_BASE_PORT_STATE_RESETTING) { - sci_base_state_machine_change_state( - &this_port->parent.state_machine, SCI_BASE_PORT_STATE_READY - ); - } - } else { - scic_sds_port_invalid_link_up(this_port, the_phy); - } -} - -enum sci_status scic_port_stop(struct scic_sds_port *port) -{ - return port->state_handlers->parent.stop_handler(&port->parent); -} - enum sci_status scic_port_get_properties( struct scic_sds_port *port, struct scic_port_properties *prop) @@ -700,7 +619,20 @@ enum sci_status scic_port_get_properties( return SCI_SUCCESS; } - +/** + * scic_port_hard_reset() - This method will request the SCI implementation to + * perform a HARD RESET on the SAS Port. If/When the HARD RESET completes + * the SCI user will be notified via an SCI OS callback indicating a direct + * attached device was found. + * @port: a handle corresponding to the SAS port to be hard reset. + * @reset_timeout: This parameter specifies the number of milliseconds in which + * the port reset operation should complete. + * + * The SCI User callback in SCIC_USER_CALLBACKS_T will only be called once for + * each phy in the SAS Port at completion of the hard reset sequence. Return a + * status indicating whether the hard reset started successfully. SCI_SUCCESS + * This value is returned if the hard reset operation started successfully. + */ enum sci_status scic_port_hard_reset( struct scic_sds_port *port, u32 reset_timeout) @@ -741,12 +673,11 @@ void scic_sds_port_setup_transports( * the phy to the port - enabling the Protocol Engine in the silicon. - * notifying the user that the link is up. none */ -void scic_sds_port_activate_phy(struct scic_sds_port *sci_port, - struct scic_sds_phy *sci_phy, - bool do_notify_user) +static void scic_sds_port_activate_phy(struct scic_sds_port *sci_port, + struct scic_sds_phy *sci_phy, + bool do_notify_user) { - 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 sci_sas_identify_address_frame_protocols protocols; struct isci_host *ihost = sci_object_get_association(scic); @@ -764,22 +695,11 @@ void scic_sds_port_activate_phy(struct scic_sds_port *sci_port, isci_port_link_up(ihost, sci_port, sci_phy); } -/** - * - * @this_port: This is the port on which the phy should be deactivated. - * @the_phy: This is the specific phy that is no longer active in the port. - * @do_notify_user: This parameter specifies whether to inform the user (via - * isci_port_link_down()) as to the fact that a new phy as become - * ready. - * - * This function will deactivate the supplied phy in the port. none - */ void scic_sds_port_deactivate_phy(struct scic_sds_port *sci_port, struct scic_sds_phy *sci_phy, bool do_notify_user) { - 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_object_get_association(sci_port); struct isci_host *ihost = sci_object_get_association(scic); struct isci_phy *iphy = sci_object_get_association(sci_phy); @@ -821,6 +741,48 @@ static void scic_sds_port_invalid_link_up( } } +/** + * scic_sds_port_general_link_up_handler - phy can be assigned to port? + * @sci_port: scic_sds_port object for which has a phy that has gone link up. + * @sci_phy: This is the struct scic_sds_phy object that has gone link up. + * @do_notify_user: This parameter specifies whether to inform the user (via + * scic_cb_port_link_up()) as to the fact that a new phy as become ready. + * + * Determine if this phy can be assigned to this + * port . If the phy is not a valid PHY for + * this port then the function will notify the user. A PHY can only be + * part of a port if it's attached SAS ADDRESS is the same as all other PHYs in + * the same port. none + */ +static void scic_sds_port_general_link_up_handler(struct scic_sds_port *sci_port, + struct scic_sds_phy *sci_phy, + bool do_notify_user) +{ + struct sci_sas_address port_sas_address; + struct sci_sas_address phy_sas_address; + + scic_sds_port_get_attached_sas_address(sci_port, &port_sas_address); + scic_sds_phy_get_attached_sas_address(sci_phy, &phy_sas_address); + + /* If the SAS address of the new phy matches the SAS address of + * other phys in the port OR this is the first phy in the port, + * then activate the phy and allow it to be used for operations + * in this port. + */ + if ((phy_sas_address.high == port_sas_address.high && + phy_sas_address.low == port_sas_address.low) || + sci_port->active_phy_mask == 0) { + struct sci_base_state_machine *sm = &sci_port->parent.state_machine; + + scic_sds_port_activate_phy(sci_port, sci_phy, do_notify_user); + if (sm->current_state_id == SCI_BASE_PORT_STATE_RESETTING) + sci_base_state_machine_change_state(sm, SCI_BASE_PORT_STATE_READY); + } else + scic_sds_port_invalid_link_up(sci_port, sci_phy); +} + + + /** * This method returns false if the port only has a single phy object assigned. * If there are no phys or more than one phy then the method will return @@ -1004,7 +966,7 @@ static void scic_sds_port_timeout_handler(void *port) * * */ -void scic_sds_port_update_viit_entry(struct scic_sds_port *this_port) +static void scic_sds_port_update_viit_entry(struct scic_sds_port *this_port) { struct sci_sas_address sas_address; @@ -1483,9 +1445,106 @@ static enum sci_status scic_sds_port_ready_configuring_substate_complete_io_hand return SCI_SUCCESS; } -/* --------------------------------------------------------------------------- */ +static enum sci_status default_port_handler(struct sci_base_port *base_port, const char *func) +{ + struct scic_sds_port *sci_port; -struct scic_sds_port_state_handler + sci_port = container_of(base_port, typeof(*sci_port), parent); + dev_warn(sciport_to_dev(sci_port), + "%s: in wrong state: %d\n", func, + sci_base_state_machine_get_state(&base_port->state_machine)); + return SCI_FAILURE_INVALID_STATE; +} + +static enum sci_status scic_sds_port_default_start_handler(struct sci_base_port *base_port) +{ + return default_port_handler(base_port, __func__); +} + +static enum sci_status scic_sds_port_default_stop_handler(struct sci_base_port *base_port) +{ + return default_port_handler(base_port, __func__); +} + +static enum sci_status scic_sds_port_default_destruct_handler(struct sci_base_port *base_port) +{ + return default_port_handler(base_port, __func__); +} + +static enum sci_status scic_sds_port_default_reset_handler(struct sci_base_port *base_port, + u32 timeout) +{ + return default_port_handler(base_port, __func__); +} + +static enum sci_status scic_sds_port_default_add_phy_handler(struct sci_base_port *base_port, + struct sci_base_phy *base_phy) +{ + return default_port_handler(base_port, __func__); +} + +static enum sci_status scic_sds_port_default_remove_phy_handler(struct sci_base_port *base_port, + struct sci_base_phy *base_phy) +{ + return default_port_handler(base_port, __func__); +} + +/** + * scic_sds_port_default_frame_handler + * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port + * object. + * + * This is the default method for a port unsolicited frame request. It will + * report a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE Is it even + * possible to receive an unsolicited frame directed to a port object? It + * seems possible if we implementing virtual functions but until then? + */ +static enum sci_status scic_sds_port_default_frame_handler(struct scic_sds_port *sci_port, + u32 frame_index) +{ + struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port); + + default_port_handler(&sci_port->parent, __func__); + scic_sds_controller_release_frame(scic, frame_index); + + return SCI_FAILURE_INVALID_STATE; +} + +static enum sci_status scic_sds_port_default_event_handler(struct scic_sds_port *sci_port, + u32 event_code) +{ + return default_port_handler(&sci_port->parent, __func__); +} + +static void scic_sds_port_default_link_up_handler(struct scic_sds_port *sci_port, + struct scic_sds_phy *sci_phy) +{ + default_port_handler(&sci_port->parent, __func__); +} + +static void scic_sds_port_default_link_down_handler(struct scic_sds_port *sci_port, + struct scic_sds_phy *sci_phy) +{ + default_port_handler(&sci_port->parent, __func__); +} + +static enum sci_status scic_sds_port_default_start_io_handler(struct scic_sds_port *sci_port, + struct scic_sds_remote_device *sci_dev, + struct scic_sds_request *sci_req) +{ + return default_port_handler(&sci_port->parent, __func__); +} + +static enum sci_status scic_sds_port_default_complete_io_handler(struct scic_sds_port *sci_port, + struct scic_sds_remote_device *sci_dev, + struct scic_sds_request *sci_req) +{ + return default_port_handler(&sci_port->parent, __func__); +} + + + +static struct scic_sds_port_state_handler scic_sds_port_ready_substate_handler_table[SCIC_SDS_PORT_READY_MAX_SUBSTATES] = { /* SCIC_SDS_PORT_READY_SUBSTATE_WAITING */ @@ -1541,7 +1600,6 @@ scic_sds_port_ready_substate_handler_table[SCIC_SDS_PORT_READY_MAX_SUBSTATES] = } }; - /** * scic_sds_port_set_ready_state_handlers() - * @@ -1584,7 +1642,7 @@ static void scic_sds_port_suspend_port_task_scheduler( * ongoing requests. * */ -void scic_sds_port_post_dummy_request(struct scic_sds_port *sci_port) +static void scic_sds_port_post_dummy_request(struct scic_sds_port *sci_port) { u32 command; struct scu_task_context *task_context; @@ -1609,7 +1667,7 @@ void scic_sds_port_post_dummy_request(struct scic_sds_port *sci_port) * @sci_port: The port on which the task must be aborted. * */ -void scic_sds_port_abort_dummy_request(struct scic_sds_port *sci_port) +static void scic_sds_port_abort_dummy_request(struct scic_sds_port *sci_port) { struct scic_sds_controller *scic = sci_port->owning_controller; u16 tci = sci_port->reserved_tci; @@ -1801,7 +1859,7 @@ static void scic_sds_port_ready_substate_configuring_exit( /* --------------------------------------------------------------------------- */ -const struct sci_base_state scic_sds_port_ready_substate_table[] = { +static const struct sci_base_state scic_sds_port_ready_substate_table[] = { [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = { .enter_state = scic_sds_port_ready_substate_waiting_enter, }, @@ -1815,103 +1873,6 @@ const struct sci_base_state scic_sds_port_ready_substate_table[] = { }, }; -static enum sci_status default_port_handler(struct sci_base_port *base_port, const char *func) -{ - struct scic_sds_port *sci_port; - - sci_port = container_of(base_port, typeof(*sci_port), parent); - dev_warn(sciport_to_dev(sci_port), - "%s: in wrong state: %d\n", func, - sci_base_state_machine_get_state(&base_port->state_machine)); - return SCI_FAILURE_INVALID_STATE; -} - -enum sci_status scic_sds_port_default_start_handler(struct sci_base_port *base_port) -{ - return default_port_handler(base_port, __func__); -} - -static enum sci_status scic_sds_port_default_stop_handler(struct sci_base_port *base_port) -{ - return default_port_handler(base_port, __func__); -} - -enum sci_status scic_sds_port_default_destruct_handler(struct sci_base_port *base_port) -{ - return default_port_handler(base_port, __func__); -} - -enum sci_status scic_sds_port_default_reset_handler(struct sci_base_port *base_port, - u32 timeout) -{ - return default_port_handler(base_port, __func__); -} - -static enum sci_status scic_sds_port_default_add_phy_handler(struct sci_base_port *base_port, - struct sci_base_phy *base_phy) -{ - return default_port_handler(base_port, __func__); -} - -enum sci_status scic_sds_port_default_remove_phy_handler(struct sci_base_port *base_port, - struct sci_base_phy *base_phy) -{ - return default_port_handler(base_port, __func__); -} - -/** - * scic_sds_port_default_frame_handler - * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port - * object. - * - * This is the default method for a port unsolicited frame request. It will - * report a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE Is it even - * possible to receive an unsolicited frame directed to a port object? It - * seems possible if we implementing virtual functions but until then? - */ -enum sci_status scic_sds_port_default_frame_handler(struct scic_sds_port *sci_port, - u32 frame_index) -{ - struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port); - - default_port_handler(&sci_port->parent, __func__); - scic_sds_controller_release_frame(scic, frame_index); - - return SCI_FAILURE_INVALID_STATE; -} - -enum sci_status scic_sds_port_default_event_handler(struct scic_sds_port *sci_port, - u32 event_code) -{ - return default_port_handler(&sci_port->parent, __func__); -} - -void scic_sds_port_default_link_up_handler(struct scic_sds_port *sci_port, - struct scic_sds_phy *sci_phy) -{ - default_port_handler(&sci_port->parent, __func__); -} - -void scic_sds_port_default_link_down_handler(struct scic_sds_port *sci_port, - struct scic_sds_phy *sci_phy) -{ - default_port_handler(&sci_port->parent, __func__); -} - -enum sci_status scic_sds_port_default_start_io_handler(struct scic_sds_port *sci_port, - struct scic_sds_remote_device *sci_dev, - struct scic_sds_request *sci_req) -{ - return default_port_handler(&sci_port->parent, __func__); -} - -static enum sci_status scic_sds_port_default_complete_io_handler(struct scic_sds_port *sci_port, - struct scic_sds_remote_device *sci_dev, - struct scic_sds_request *sci_req) -{ - return default_port_handler(&sci_port->parent, __func__); -} - /** * * @port: This is the struct scic_sds_port object on which the io request count will @@ -2248,9 +2209,7 @@ static void scic_sds_port_reset_state_link_down_handler( scic_sds_port_deactivate_phy(this_port, phy, false); } -/* --------------------------------------------------------------------------- */ - -struct scic_sds_port_state_handler +static struct scic_sds_port_state_handler scic_sds_port_state_handler_table[SCI_BASE_PORT_MAX_STATES] = { /* SCI_BASE_PORT_STATE_STOPPED */ @@ -2384,7 +2343,7 @@ static void scic_sds_port_disable_port_task_scheduler( scu_port_task_scheduler_write(this_port, control, pts_control_value); } -void scic_sds_port_post_dummy_remote_node(struct scic_sds_port *sci_port) +static void scic_sds_port_post_dummy_remote_node(struct scic_sds_port *sci_port) { struct scic_sds_controller *scic = sci_port->owning_controller; u8 phys_index = sci_port->physical_port_index; @@ -2412,7 +2371,7 @@ void scic_sds_port_post_dummy_remote_node(struct scic_sds_port *sci_port) scic_sds_controller_post_request(scic, command); } -void scic_sds_port_invalidate_dummy_remote_node(struct scic_sds_port *sci_port) +static void scic_sds_port_invalidate_dummy_remote_node(struct scic_sds_port *sci_port) { struct scic_sds_controller *scic = sci_port->owning_controller; u8 phys_index = sci_port->physical_port_index; @@ -2639,7 +2598,7 @@ static void scic_sds_port_failed_state_enter(struct sci_base_object *object) /* --------------------------------------------------------------------------- */ -const struct sci_base_state scic_sds_port_state_table[] = { +static const struct sci_base_state scic_sds_port_state_table[] = { [SCI_BASE_PORT_STATE_STOPPED] = { .enter_state = scic_sds_port_stopped_state_enter, .exit_state = scic_sds_port_stopped_state_exit @@ -2661,3 +2620,34 @@ const struct sci_base_state scic_sds_port_state_table[] = { } }; +void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 port_index, + struct scic_sds_controller *scic) +{ + u32 index; + + sci_base_port_construct(&sci_port->parent, scic_sds_port_state_table); + + sci_base_state_machine_construct(&sci_port->ready_substate_machine, + &sci_port->parent.parent, + scic_sds_port_ready_substate_table, + SCIC_SDS_PORT_READY_SUBSTATE_WAITING); + + sci_port->logical_port_index = SCIC_SDS_DUMMY_PORT; + sci_port->physical_port_index = port_index; + sci_port->active_phy_mask = 0; + + sci_port->owning_controller = scic; + + sci_port->started_request_count = 0; + sci_port->assigned_device_count = 0; + + sci_port->reserved_rni = SCU_DUMMY_INDEX; + sci_port->reserved_tci = SCU_DUMMY_INDEX; + + sci_port->timer_handle = NULL; + + sci_port->port_task_scheduler_registers = NULL; + + for (index = 0; index < SCI_MAX_PHYS; index++) + sci_port->phy_table[index] = NULL; +} diff --git a/drivers/scsi/isci/core/scic_sds_port.h b/drivers/scsi/isci/core/scic_sds_port.h index ac81a92c348a..8167f5e3be3d 100644 --- a/drivers/scsi/isci/core/scic_sds_port.h +++ b/drivers/scsi/isci/core/scic_sds_port.h @@ -236,12 +236,6 @@ struct scic_sds_port_state_handler { }; -extern const struct sci_base_state scic_sds_port_state_table[]; -extern const struct sci_base_state scic_sds_port_ready_substate_table[]; - -extern struct scic_sds_port_state_handler scic_sds_port_state_handler_table[]; -extern struct scic_sds_port_state_handler scic_sds_port_ready_substate_handler_table[]; - /** * scic_sds_port_get_controller() - * @@ -351,10 +345,6 @@ void scic_sds_port_setup_transports( struct scic_sds_port *this_port, u32 device_id); -void scic_sds_port_activate_phy( - struct scic_sds_port *this_port, - struct scic_sds_phy *phy, - bool do_notify_user); void scic_sds_port_deactivate_phy( struct scic_sds_port *this_port, @@ -363,10 +353,6 @@ void scic_sds_port_deactivate_phy( -void scic_sds_port_general_link_up_handler( - struct scic_sds_port *this_port, - struct scic_sds_phy *the_phy, - bool do_notify_user); bool scic_sds_port_link_detected( struct scic_sds_port *this_port, @@ -397,47 +383,19 @@ enum sci_status scic_sds_port_complete_io( /* --------------------------------------------------------------------------- */ -void scic_sds_port_update_viit_entry( - struct scic_sds_port *this_port); /* --------------------------------------------------------------------------- */ -enum sci_status scic_sds_port_default_start_handler( - struct sci_base_port *port); -enum sci_status scic_sds_port_default_destruct_handler( - struct sci_base_port *port); - -enum sci_status scic_sds_port_default_reset_handler( - struct sci_base_port *port, - u32 timeout); -enum sci_status scic_sds_port_default_remove_phy_handler( - struct sci_base_port *port, - struct sci_base_phy *phy); -enum sci_status scic_sds_port_default_frame_handler( - struct scic_sds_port *port, - u32 frame_index); -enum sci_status scic_sds_port_default_event_handler( - struct scic_sds_port *port, - u32 event_code); -void scic_sds_port_default_link_up_handler( - struct scic_sds_port *this_port, - struct scic_sds_phy *phy); -void scic_sds_port_default_link_down_handler( - struct scic_sds_port *this_port, - struct scic_sds_phy *phy); -enum sci_status scic_sds_port_default_start_io_handler( - struct scic_sds_port *port, - struct scic_sds_remote_device *device, - struct scic_sds_request *io_request); + enum sci_sas_link_rate scic_sds_port_get_max_allowed_speed( @@ -451,12 +409,7 @@ bool scic_sds_port_is_valid_phy_assignment( struct scic_sds_port *this_port, u32 phy_index); -bool scic_sds_port_is_phy_mask_valid( - struct scic_sds_port *this_port, - u32 phy_mask); -u32 scic_sds_port_get_phys( - struct scic_sds_port *this_port); void scic_sds_port_get_sas_address( struct scic_sds_port *this_port, @@ -470,13 +423,7 @@ void scic_sds_port_get_attached_protocols( struct scic_sds_port *this_port, struct sci_sas_identify_address_frame_protocols *protocols); -enum sci_status scic_sds_port_set_phy( - struct scic_sds_port *port, - struct scic_sds_phy *phy); -enum sci_status scic_sds_port_clear_phy( - struct scic_sds_port *port, - struct scic_sds_phy *phy); diff --git a/drivers/scsi/isci/core/scic_sds_remote_device.c b/drivers/scsi/isci/core/scic_sds_remote_device.c index 05599d178caa..5ab8b0321de5 100644 --- a/drivers/scsi/isci/core/scic_sds_remote_device.c +++ b/drivers/scsi/isci/core/scic_sds_remote_device.c @@ -87,30 +87,6 @@ u32 scic_remote_device_get_object_size(void) + sizeof(struct scic_sds_remote_node_context); } -/* --------------------------------------------------------------------------- */ - -void scic_remote_device_construct(struct scic_sds_port *sci_port, - struct scic_sds_remote_device *sci_dev) -{ - sci_dev->owning_port = sci_port; - sci_dev->started_request_count = 0; - sci_dev->rnc = (struct scic_sds_remote_node_context *) &sci_dev[1]; - - sci_base_remote_device_construct( - &sci_dev->parent, - scic_sds_remote_device_state_table - ); - - scic_sds_remote_node_context_construct( - sci_dev, - sci_dev->rnc, - SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX - ); - - sci_object_set_association(sci_dev->rnc, sci_dev); -} - - enum sci_status scic_remote_device_da_construct( struct scic_sds_remote_device *sci_dev) { @@ -1330,7 +1306,7 @@ static enum sci_status scic_sds_remote_device_resetting_state_complete_request_h /* --------------------------------------------------------------------------- */ -const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = { +static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = { [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = { .parent.start_handler = scic_sds_remote_device_default_start_handler, .parent.stop_handler = scic_sds_remote_device_default_stop_handler, @@ -1741,7 +1717,7 @@ static void scic_sds_remote_device_final_state_enter( /* --------------------------------------------------------------------------- */ -const struct sci_base_state scic_sds_remote_device_state_table[] = { +static const struct sci_base_state scic_sds_remote_device_state_table[] = { [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = { .enter_state = scic_sds_remote_device_initial_state_enter, }, @@ -1771,3 +1747,23 @@ const struct sci_base_state scic_sds_remote_device_state_table[] = { }, }; +void scic_remote_device_construct(struct scic_sds_port *sci_port, + struct scic_sds_remote_device *sci_dev) +{ + sci_dev->owning_port = sci_port; + sci_dev->started_request_count = 0; + sci_dev->rnc = (struct scic_sds_remote_node_context *) &sci_dev[1]; + + sci_base_remote_device_construct( + &sci_dev->parent, + scic_sds_remote_device_state_table + ); + + scic_sds_remote_node_context_construct( + sci_dev, + sci_dev->rnc, + SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX + ); + + sci_object_set_association(sci_dev->rnc, sci_dev); +} diff --git a/drivers/scsi/isci/core/scic_sds_remote_device.h b/drivers/scsi/isci/core/scic_sds_remote_device.h index aa466249f229..725c0588f2ab 100644 --- a/drivers/scsi/isci/core/scic_sds_remote_device.h +++ b/drivers/scsi/isci/core/scic_sds_remote_device.h @@ -316,15 +316,10 @@ struct scic_sds_remote_device_state_handler { scic_sds_remote_device_frame_handler_t frame_handler; }; -extern const struct sci_base_state scic_sds_remote_device_state_table[]; extern const struct sci_base_state scic_sds_ssp_remote_device_ready_substate_table[]; extern const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[]; extern const struct sci_base_state scic_sds_smp_remote_device_ready_substate_table[]; -extern const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[]; -extern const struct scic_sds_remote_device_state_handler scic_sds_stp_remote_device_ready_substate_handler_table[]; -extern const struct scic_sds_remote_device_state_handler scic_sds_smp_remote_device_ready_substate_handler_table[]; - /** * scic_sds_remote_device_increment_request_count() - * diff --git a/drivers/scsi/isci/core/scic_sds_remote_node_context.c b/drivers/scsi/isci/core/scic_sds_remote_node_context.c index 253b2d8aa23b..81e4ab34dd30 100644 --- a/drivers/scsi/isci/core/scic_sds_remote_node_context.c +++ b/drivers/scsi/isci/core/scic_sds_remote_node_context.c @@ -64,26 +64,6 @@ #include "scu_event_codes.h" #include "scu_task_context.h" -void scic_sds_remote_node_context_construct( - struct scic_sds_remote_device *device, - struct scic_sds_remote_node_context *rnc, - u16 remote_node_index) -{ - memset(rnc, 0, sizeof(struct scic_sds_remote_node_context)); - - rnc->remote_node_index = remote_node_index; - rnc->device = device; - rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED; - - sci_base_state_machine_construct( - &rnc->state_machine, - &rnc->parent, - scic_sds_remote_node_context_state_table, - SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE - ); - - sci_base_state_machine_start(&rnc->state_machine); -} /** * @@ -124,7 +104,7 @@ bool scic_sds_remote_node_context_is_ready( * * This method will construct the RNC buffer for this remote device object. none */ -void scic_sds_remote_node_context_construct_buffer( +static void scic_sds_remote_node_context_construct_buffer( struct scic_sds_remote_node_context *this_rnc) { union scu_remote_node_context *rnc; @@ -830,7 +810,7 @@ static enum sci_status scic_sds_remote_node_context_await_suspension_state_event /* --------------------------------------------------------------------------- */ -struct scic_sds_remote_node_context_handlers +static struct scic_sds_remote_node_context_handlers scic_sds_remote_node_context_state_handler_table[ SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES] = { @@ -1218,7 +1198,7 @@ static void scic_sds_remote_node_context_await_suspension_state_enter( /* --------------------------------------------------------------------------- */ -const struct sci_base_state scic_sds_remote_node_context_state_table[] = { +static const struct sci_base_state scic_sds_remote_node_context_state_table[] = { [SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE] = { .enter_state = scic_sds_remote_node_context_initial_state_enter, }, @@ -1245,3 +1225,23 @@ const struct sci_base_state scic_sds_remote_node_context_state_table[] = { }, }; +void scic_sds_remote_node_context_construct( + struct scic_sds_remote_device *device, + struct scic_sds_remote_node_context *rnc, + u16 remote_node_index) +{ + memset(rnc, 0, sizeof(struct scic_sds_remote_node_context)); + + rnc->remote_node_index = remote_node_index; + rnc->device = device; + rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED; + + sci_base_state_machine_construct( + &rnc->state_machine, + &rnc->parent, + scic_sds_remote_node_context_state_table, + SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE + ); + + sci_base_state_machine_start(&rnc->state_machine); +} diff --git a/drivers/scsi/isci/core/scic_sds_remote_node_context.h b/drivers/scsi/isci/core/scic_sds_remote_node_context.h index c7c75ae6f092..eccad55ea571 100644 --- a/drivers/scsi/isci/core/scic_sds_remote_node_context.h +++ b/drivers/scsi/isci/core/scic_sds_remote_node_context.h @@ -279,19 +279,11 @@ struct scic_sds_remote_node_context { struct scic_sds_remote_node_context_handlers *state_handlers; }; -extern const struct sci_base_state scic_sds_remote_node_context_state_table[]; - -extern struct scic_sds_remote_node_context_handlers - scic_sds_remote_node_context_state_handler_table[ - SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES]; - void scic_sds_remote_node_context_construct( struct scic_sds_remote_device *device, struct scic_sds_remote_node_context *rnc, u16 remote_node_index); -void scic_sds_remote_node_context_construct_buffer( - struct scic_sds_remote_node_context *rnc); bool scic_sds_remote_node_context_is_ready( struct scic_sds_remote_node_context *this_rnc); diff --git a/drivers/scsi/isci/core/scic_sds_request.c b/drivers/scsi/isci/core/scic_sds_request.c index 4542f4e75f7f..45b8571726f7 100644 --- a/drivers/scsi/isci/core/scic_sds_request.c +++ b/drivers/scsi/isci/core/scic_sds_request.c @@ -325,59 +325,6 @@ void scic_sds_request_build_sgl(struct scic_sds_request *sds_request) } } -/** - * This method initializes common portions of the io request object. This - * includes construction of the struct sci_base_request parent. - * @the_controller: This parameter specifies the controller for which the - * request is being constructed. - * @the_target: This parameter specifies the remote device for which the - * request is being constructed. - * @io_tag: This parameter specifies the IO tag to be utilized for this - * request. This parameter can be set to SCI_CONTROLLER_INVALID_IO_TAG. - * @user_io_request_object: This parameter specifies the user request object - * for which the request is being constructed. - * @this_request: This parameter specifies the request being constructed. - * - */ -static void scic_sds_general_request_construct( - struct scic_sds_controller *the_controller, - struct scic_sds_remote_device *the_target, - u16 io_tag, - void *user_io_request_object, - struct scic_sds_request *this_request) -{ - sci_base_request_construct( - &this_request->parent, - scic_sds_request_state_table - ); - - this_request->io_tag = io_tag; - this_request->user_request = user_io_request_object; - this_request->owning_controller = the_controller; - this_request->target_device = the_target; - this_request->has_started_substate_machine = false; - this_request->protocol = SCIC_NO_PROTOCOL; - this_request->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX; - this_request->device_sequence = scic_sds_remote_device_get_sequence(the_target); - - this_request->sci_status = SCI_SUCCESS; - this_request->scu_status = 0; - this_request->post_context = 0xFFFFFFFF; - - this_request->is_task_management_request = false; - - if (io_tag == SCI_CONTROLLER_INVALID_IO_TAG) { - this_request->was_tag_assigned_by_user = false; - this_request->task_context_buffer = NULL; - } else { - this_request->was_tag_assigned_by_user = true; - - this_request->task_context_buffer = - scic_sds_controller_get_task_context_buffer( - this_request->owning_controller, io_tag); - } -} - /** * This method build the remainder of the IO request object. * @this_request: This parameter specifies the request object being constructed. @@ -754,16 +701,6 @@ static enum sci_status scic_io_request_construct_sata(struct scic_sds_request *s return status; } -/* - * **************************************************************************** - * * SCIC Interface Implementation - * **************************************************************************** */ - - - - -/* --------------------------------------------------------------------------- */ - u32 scic_io_request_get_object_size(void) { u32 ssp_request_size; @@ -777,128 +714,6 @@ u32 scic_io_request_get_object_size(void) return max(ssp_request_size, max(stp_request_size, smp_request_size)); } -/* --------------------------------------------------------------------------- */ - - -/* --------------------------------------------------------------------------- */ - - -/* --------------------------------------------------------------------------- */ - - -/* --------------------------------------------------------------------------- */ - -enum sci_status scic_io_request_construct( - struct scic_sds_controller *scic_controller, - struct scic_sds_remote_device *scic_remote_device, - u16 io_tag, - void *user_io_request_object, - void *scic_io_request_memory, - struct scic_sds_request **new_scic_io_request_handle) -{ - enum sci_status status = SCI_SUCCESS; - struct scic_sds_request *this_request; - struct smp_discover_response_protocols device_protocol; - - this_request = (struct scic_sds_request *)scic_io_request_memory; - - /* Build the common part of the request */ - scic_sds_general_request_construct( - (struct scic_sds_controller *)scic_controller, - (struct scic_sds_remote_device *)scic_remote_device, - io_tag, - user_io_request_object, - this_request - ); - - if ( - scic_sds_remote_device_get_index((struct scic_sds_remote_device *)scic_remote_device) - == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX - ) { - return SCI_FAILURE_INVALID_REMOTE_DEVICE; - } - - scic_remote_device_get_protocols(scic_remote_device, &device_protocol); - - if (device_protocol.u.bits.attached_ssp_target) { - scic_sds_ssp_io_request_assign_buffers(this_request); - } else if (device_protocol.u.bits.attached_stp_target) { - scic_sds_stp_request_assign_buffers(this_request); - memset(this_request->command_buffer, 0, sizeof(struct sata_fis_reg_h2d)); - } else if (device_protocol.u.bits.attached_smp_target) { - scic_sds_smp_request_assign_buffers(this_request); - memset(this_request->command_buffer, 0, sizeof(struct smp_request)); - } else { - status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; - } - - if (status == SCI_SUCCESS) { - memset( - this_request->task_context_buffer, - 0, - SCI_FIELD_OFFSET(struct scu_task_context, sgl_pair_ab) - ); - *new_scic_io_request_handle = scic_io_request_memory; - } - - return status; -} - -/* --------------------------------------------------------------------------- */ - - -enum sci_status scic_task_request_construct( - struct scic_sds_controller *controller, - struct scic_sds_remote_device *remote_device, - u16 io_tag, - void *user_io_request_object, - void *scic_task_request_memory, - struct scic_sds_request **new_scic_task_request_handle) -{ - enum sci_status status = SCI_SUCCESS; - struct scic_sds_request *this_request = (struct scic_sds_request *) - scic_task_request_memory; - struct smp_discover_response_protocols device_protocol; - - /* Build the common part of the request */ - scic_sds_general_request_construct( - (struct scic_sds_controller *)controller, - (struct scic_sds_remote_device *)remote_device, - io_tag, - user_io_request_object, - this_request - ); - - scic_remote_device_get_protocols(remote_device, &device_protocol); - - if (device_protocol.u.bits.attached_ssp_target) { - scic_sds_ssp_task_request_assign_buffers(this_request); - - this_request->has_started_substate_machine = true; - - /* Construct the started sub-state machine. */ - sci_base_state_machine_construct( - &this_request->started_substate_machine, - &this_request->parent.parent, - scic_sds_io_request_started_task_mgmt_substate_table, - SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION - ); - } else if (device_protocol.u.bits.attached_stp_target) { - scic_sds_stp_request_assign_buffers(this_request); - } else { - status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; - } - - if (status == SCI_SUCCESS) { - this_request->is_task_management_request = true; - memset(this_request->task_context_buffer, 0x00, sizeof(struct scu_task_context)); - *new_scic_task_request_handle = scic_task_request_memory; - } - - return status; -} - - enum sci_status scic_io_request_construct_basic_ssp( struct scic_sds_request *sci_req) { @@ -1915,9 +1730,7 @@ static enum sci_status scic_sds_request_aborting_state_frame_handler( return SCI_SUCCESS; } -/* --------------------------------------------------------------------------- */ - -const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[] = { +static const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[] = { [SCI_BASE_REQUEST_STATE_INITIAL] = { .parent.start_handler = scic_sds_request_default_start_handler, .parent.abort_handler = scic_sds_request_default_abort_handler, @@ -2142,9 +1955,7 @@ static void scic_sds_request_final_state_enter( ); } -/* --------------------------------------------------------------------------- */ - -const struct sci_base_state scic_sds_request_state_table[] = { +static const struct sci_base_state scic_sds_request_state_table[] = { [SCI_BASE_REQUEST_STATE_INITIAL] = { .enter_state = scic_sds_request_initial_state_enter, }, @@ -2166,3 +1977,119 @@ const struct sci_base_state scic_sds_request_state_table[] = { }, }; +static void scic_sds_general_request_construct(struct scic_sds_controller *scic, + struct scic_sds_remote_device *sci_dev, + u16 io_tag, + void *user_io_request_object, + struct scic_sds_request *sci_req) +{ + sci_base_request_construct(&sci_req->parent, scic_sds_request_state_table); + sci_req->io_tag = io_tag; + sci_req->user_request = user_io_request_object; + sci_req->owning_controller = scic; + sci_req->target_device = sci_dev; + sci_req->has_started_substate_machine = false; + sci_req->protocol = SCIC_NO_PROTOCOL; + sci_req->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX; + sci_req->device_sequence = scic_sds_remote_device_get_sequence(sci_dev); + + sci_req->sci_status = SCI_SUCCESS; + sci_req->scu_status = 0; + sci_req->post_context = 0xFFFFFFFF; + + sci_req->is_task_management_request = false; + + if (io_tag == SCI_CONTROLLER_INVALID_IO_TAG) { + sci_req->was_tag_assigned_by_user = false; + sci_req->task_context_buffer = NULL; + } else { + sci_req->was_tag_assigned_by_user = true; + + sci_req->task_context_buffer = + scic_sds_controller_get_task_context_buffer(scic, io_tag); + } +} + +enum sci_status scic_io_request_construct(struct scic_sds_controller *scic, + struct scic_sds_remote_device *sci_dev, + u16 io_tag, + void *user_io_request_object, + struct scic_sds_request *sci_req, + struct scic_sds_request **new_scic_io_request_handle) +{ + enum sci_status status = SCI_SUCCESS; + struct smp_discover_response_protocols device_protocol; + + /* Build the common part of the request */ + scic_sds_general_request_construct(scic, sci_dev, io_tag, + user_io_request_object, sci_req); + + if (sci_dev->rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) + return SCI_FAILURE_INVALID_REMOTE_DEVICE; + + scic_remote_device_get_protocols(sci_dev, &device_protocol); + + if (device_protocol.u.bits.attached_ssp_target) { + scic_sds_ssp_io_request_assign_buffers(sci_req); + } else if (device_protocol.u.bits.attached_stp_target) { + scic_sds_stp_request_assign_buffers(sci_req); + memset(sci_req->command_buffer, 0, sizeof(struct sata_fis_reg_h2d)); + } else if (device_protocol.u.bits.attached_smp_target) { + scic_sds_smp_request_assign_buffers(sci_req); + memset(sci_req->command_buffer, 0, sizeof(struct smp_request)); + } else { + status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; + } + + if (status == SCI_SUCCESS) { + memset(sci_req->task_context_buffer, 0, + SCI_FIELD_OFFSET(struct scu_task_context, sgl_pair_ab)); + *new_scic_io_request_handle = sci_req; + } + + return status; +} + +enum sci_status scic_task_request_construct(struct scic_sds_controller *scic, + struct scic_sds_remote_device *sci_dev, + u16 io_tag, + void *user_io_request_object, + struct scic_sds_request *sci_req, + struct scic_sds_request **new_sci_req) +{ + enum sci_status status = SCI_SUCCESS; + struct smp_discover_response_protocols device_protocol; + + /* Build the common part of the request */ + scic_sds_general_request_construct(scic, sci_dev, io_tag, + user_io_request_object, + sci_req); + + scic_remote_device_get_protocols(sci_dev, &device_protocol); + + if (device_protocol.u.bits.attached_ssp_target) { + scic_sds_ssp_task_request_assign_buffers(sci_req); + + sci_req->has_started_substate_machine = true; + + /* Construct the started sub-state machine. */ + sci_base_state_machine_construct( + &sci_req->started_substate_machine, + &sci_req->parent.parent, + scic_sds_io_request_started_task_mgmt_substate_table, + SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION + ); + } else if (device_protocol.u.bits.attached_stp_target) { + scic_sds_stp_request_assign_buffers(sci_req); + } else { + status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; + } + + if (status == SCI_SUCCESS) { + sci_req->is_task_management_request = true; + memset(sci_req->task_context_buffer, 0, sizeof(struct scu_task_context)); + *new_sci_req = sci_req; + } + + return status; +} diff --git a/drivers/scsi/isci/core/scic_sds_request.h b/drivers/scsi/isci/core/scic_sds_request.h index 06b53c3b0aa0..c54d8ef79ed8 100644 --- a/drivers/scsi/isci/core/scic_sds_request.h +++ b/drivers/scsi/isci/core/scic_sds_request.h @@ -256,14 +256,7 @@ struct scic_sds_io_request_state_handler { }; -extern const struct sci_base_state scic_sds_request_state_table[]; -extern const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[]; - extern const struct sci_base_state scic_sds_io_request_started_task_mgmt_substate_table[]; -extern const struct scic_sds_io_request_state_handler scic_sds_ssp_task_request_started_substate_handler_table[]; - -extern const struct sci_base_state scic_sds_smp_request_started_substate_table[]; -extern const struct scic_sds_io_request_state_handler scic_sds_smp_request_started_substate_handler_table[]; /** * diff --git a/drivers/scsi/isci/core/scic_sds_smp_remote_device.c b/drivers/scsi/isci/core/scic_sds_smp_remote_device.c index fb832ef544e5..55202481e091 100644 --- a/drivers/scsi/isci/core/scic_sds_smp_remote_device.c +++ b/drivers/scsi/isci/core/scic_sds_smp_remote_device.c @@ -207,7 +207,7 @@ static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_frame_handl /* --------------------------------------------------------------------------- */ -const struct scic_sds_remote_device_state_handler scic_sds_smp_remote_device_ready_substate_handler_table[] = { +static const struct scic_sds_remote_device_state_handler scic_sds_smp_remote_device_ready_substate_handler_table[] = { [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { .parent.start_handler = scic_sds_remote_device_default_start_handler, .parent.stop_handler = scic_sds_remote_device_ready_state_stop_handler, diff --git a/drivers/scsi/isci/core/scic_sds_smp_request.c b/drivers/scsi/isci/core/scic_sds_smp_request.c index 962bd3994f10..84b0fdd7ed91 100644 --- a/drivers/scsi/isci/core/scic_sds_smp_request.c +++ b/drivers/scsi/isci/core/scic_sds_smp_request.c @@ -142,73 +142,6 @@ void scic_sds_smp_request_assign_buffers( } } -/** - * This method is called by the SCI user to build an SMP IO request. - * - * - The user must have previously called scic_io_request_construct() on the - * supplied IO request. Indicate if the controller successfully built the IO - * request. SCI_SUCCESS This value is returned if the IO request was - * successfully built. SCI_FAILURE_UNSUPPORTED_PROTOCOL This value is returned - * if the remote_device does not support the SMP protocol. - * SCI_FAILURE_INVALID_ASSOCIATION This value is returned if the user did not - * properly set the association between the SCIC IO request and the user's IO - * request. Please refer to the sci_object_set_association() routine for more - * information. - */ -enum sci_status scic_io_request_construct_smp( - struct scic_sds_request *sci_req) -{ - struct smp_request *smp_req = kmalloc(sizeof(*smp_req), GFP_KERNEL); - - if (!smp_req) - return SCI_FAILURE_INSUFFICIENT_RESOURCES; - - sci_req->protocol = SCIC_SMP_PROTOCOL; - sci_req->has_started_substate_machine = true; - - /* Construct the started sub-state machine. */ - sci_base_state_machine_construct( - &sci_req->started_substate_machine, - &sci_req->parent.parent, - scic_sds_smp_request_started_substate_table, - SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE - ); - - /* Construct the SMP SCU Task Context */ - memcpy(smp_req, sci_req->command_buffer, sizeof(*smp_req)); - - /* - * Look at the SMP requests' header fields; for certain SAS 1.x SMP - * functions under SAS 2.0, a zero request length really indicates - * a non-zero default length. */ - if (smp_req->header.request_length == 0) { - switch (smp_req->header.function) { - case SMP_FUNCTION_DISCOVER: - case SMP_FUNCTION_REPORT_PHY_ERROR_LOG: - case SMP_FUNCTION_REPORT_PHY_SATA: - case SMP_FUNCTION_REPORT_ROUTE_INFORMATION: - smp_req->header.request_length = 2; - break; - case SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION: - case SMP_FUNCTION_PHY_CONTROL: - case SMP_FUNCTION_PHY_TEST: - smp_req->header.request_length = 9; - break; - /* Default - zero is a valid default for 2.0. */ - } - } - - scu_smp_request_construct_task_context(sci_req, smp_req); - - sci_base_state_machine_change_state( - &sci_req->parent.state_machine, - SCI_BASE_REQUEST_STATE_CONSTRUCTED - ); - - kfree(smp_req); - - return SCI_SUCCESS; -} /** * This method is called by the SCI user to build an SMP pass-through IO @@ -595,7 +528,7 @@ static enum sci_status scic_sds_smp_request_await_tc_completion_tc_completion_ha } -const struct scic_sds_io_request_state_handler scic_sds_smp_request_started_substate_handler_table[] = { +static const struct scic_sds_io_request_state_handler scic_sds_smp_request_started_substate_handler_table[] = { [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE] = { .parent.start_handler = scic_sds_request_default_start_handler, .parent.abort_handler = scic_sds_request_started_state_abort_handler, @@ -658,7 +591,7 @@ static void scic_sds_smp_request_started_await_tc_completion_substate_enter( ); } -const struct sci_base_state scic_sds_smp_request_started_substate_table[] = { +static const struct sci_base_state scic_sds_smp_request_started_substate_table[] = { [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE] = { .enter_state = scic_sds_smp_request_started_await_response_substate_enter, }, @@ -667,3 +600,69 @@ const struct sci_base_state scic_sds_smp_request_started_substate_table[] = { }, }; +/** + * This method is called by the SCI user to build an SMP IO request. + * + * - The user must have previously called scic_io_request_construct() on the + * supplied IO request. Indicate if the controller successfully built the IO + * request. SCI_SUCCESS This value is returned if the IO request was + * successfully built. SCI_FAILURE_UNSUPPORTED_PROTOCOL This value is returned + * if the remote_device does not support the SMP protocol. + * SCI_FAILURE_INVALID_ASSOCIATION This value is returned if the user did not + * properly set the association between the SCIC IO request and the user's IO + * request. Please refer to the sci_object_set_association() routine for more + * information. + */ +enum sci_status scic_io_request_construct_smp(struct scic_sds_request *sci_req) +{ + struct smp_request *smp_req = kmalloc(sizeof(*smp_req), GFP_KERNEL); + + if (!smp_req) + return SCI_FAILURE_INSUFFICIENT_RESOURCES; + + sci_req->protocol = SCIC_SMP_PROTOCOL; + sci_req->has_started_substate_machine = true; + + /* Construct the started sub-state machine. */ + sci_base_state_machine_construct( + &sci_req->started_substate_machine, + &sci_req->parent.parent, + scic_sds_smp_request_started_substate_table, + SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE + ); + + /* Construct the SMP SCU Task Context */ + memcpy(smp_req, sci_req->command_buffer, sizeof(*smp_req)); + + /* + * Look at the SMP requests' header fields; for certain SAS 1.x SMP + * functions under SAS 2.0, a zero request length really indicates + * a non-zero default length. */ + if (smp_req->header.request_length == 0) { + switch (smp_req->header.function) { + case SMP_FUNCTION_DISCOVER: + case SMP_FUNCTION_REPORT_PHY_ERROR_LOG: + case SMP_FUNCTION_REPORT_PHY_SATA: + case SMP_FUNCTION_REPORT_ROUTE_INFORMATION: + smp_req->header.request_length = 2; + break; + case SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION: + case SMP_FUNCTION_PHY_CONTROL: + case SMP_FUNCTION_PHY_TEST: + smp_req->header.request_length = 9; + break; + /* Default - zero is a valid default for 2.0. */ + } + } + + scu_smp_request_construct_task_context(sci_req, smp_req); + + sci_base_state_machine_change_state( + &sci_req->parent.state_machine, + SCI_BASE_REQUEST_STATE_CONSTRUCTED + ); + + kfree(smp_req); + + return SCI_SUCCESS; +} diff --git a/drivers/scsi/isci/core/scic_sds_ssp_request.c b/drivers/scsi/isci/core/scic_sds_ssp_request.c index a826e4bf2928..c9aa35f5cd15 100644 --- a/drivers/scsi/isci/core/scic_sds_ssp_request.c +++ b/drivers/scsi/isci/core/scic_sds_ssp_request.c @@ -193,7 +193,7 @@ static enum sci_status scic_sds_ssp_task_request_await_tc_response_frame_handler return SCI_SUCCESS; } -const struct scic_sds_io_request_state_handler scic_sds_ssp_task_request_started_substate_handler_table[] = { +static const struct scic_sds_io_request_state_handler scic_sds_ssp_task_request_started_substate_handler_table[] = { [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = { .parent.start_handler = scic_sds_request_default_start_handler, .parent.abort_handler = scic_sds_request_started_state_abort_handler, diff --git a/drivers/scsi/isci/core/scic_sds_stp_pio_request.h b/drivers/scsi/isci/core/scic_sds_stp_pio_request.h index 64bf40a6e1d2..d4dc118f2deb 100644 --- a/drivers/scsi/isci/core/scic_sds_stp_pio_request.h +++ b/drivers/scsi/isci/core/scic_sds_stp_pio_request.h @@ -99,18 +99,7 @@ enum _SCIC_SDS_STP_REQUEST_STARTED_PIO_SUBSTATES { SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE, }; - -/* --------------------------------------------------------------------------- */ - -extern const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_pio_substate_handler_table[]; - -extern const struct sci_base_state scic_sds_stp_request_started_pio_substate_table[]; - -/* --------------------------------------------------------------------------- */ - struct scic_sds_stp_request; -struct scu_sgl_element *scic_sds_stp_request_pio_get_next_sgl( - struct scic_sds_stp_request *this_request); #endif /* _SCIC_SDS_SATA_PIO_REQUEST_H_ */ diff --git a/drivers/scsi/isci/core/scic_sds_stp_remote_device.c b/drivers/scsi/isci/core/scic_sds_stp_remote_device.c index cb396d127773..193a95fa90e1 100644 --- a/drivers/scsi/isci/core/scic_sds_stp_remote_device.c +++ b/drivers/scsi/isci/core/scic_sds_stp_remote_device.c @@ -565,7 +565,7 @@ enum sci_status scic_sds_stp_remote_device_ready_atapi_error_substate_event_hand /* --------------------------------------------------------------------------- */ -const struct scic_sds_remote_device_state_handler scic_sds_stp_remote_device_ready_substate_handler_table[] = { +static const struct scic_sds_remote_device_state_handler scic_sds_stp_remote_device_ready_substate_handler_table[] = { [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { .parent.start_handler = scic_sds_remote_device_default_start_handler, .parent.stop_handler = scic_sds_remote_device_ready_state_stop_handler, diff --git a/drivers/scsi/isci/core/scic_sds_stp_request.c b/drivers/scsi/isci/core/scic_sds_stp_request.c index 8da309f81ac2..0e961e9cd6eb 100644 --- a/drivers/scsi/isci/core/scic_sds_stp_request.c +++ b/drivers/scsi/isci/core/scic_sds_stp_request.c @@ -267,7 +267,7 @@ static void scu_sata_reqeust_construct_task_context( * This method will perform any general sata request construction. What part of * SATA IO request construction is general? none */ -void scic_sds_stp_non_ncq_request_construct( +static void scic_sds_stp_non_ncq_request_construct( struct scic_sds_request *this_request) { this_request->has_started_substate_machine = true; @@ -318,33 +318,6 @@ static void scic_sds_stp_optimized_request_construct(struct scic_sds_request *sc } } -/** - * - * @sci_req: This parameter specifies the request to be constructed. - * - * This method will construct the STP UDMA request and its associated TC data. - * This method returns an indication as to whether the construction was - * successful. SCI_SUCCESS Currently this method always returns this value. - */ -enum sci_status scic_sds_stp_udma_request_construct(struct scic_sds_request *sci_req, - u32 len, - enum dma_data_direction dir) -{ - scic_sds_stp_non_ncq_request_construct(sci_req); - - scic_sds_stp_optimized_request_construct(sci_req, SCU_TASK_TYPE_DMA_IN, - len, dir); - - sci_base_state_machine_construct( - &sci_req->started_substate_machine, - &sci_req->parent.parent, - scic_sds_stp_request_started_udma_substate_table, - SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE - ); - - return SCI_SUCCESS; -} - /** * * @sci_req: This parameter specifies the request to be constructed. @@ -364,7 +337,7 @@ enum sci_status scic_sds_stp_ncq_request_construct(struct scic_sds_request *sci_ } /** - * + * scu_stp_raw_request_construct_task_context - * @this_request: This parameter specifies the STP request object for which to * construct a RAW command frame task context. * @task_context: This parameter specifies the SCU specific task context buffer @@ -373,7 +346,7 @@ enum sci_status scic_sds_stp_ncq_request_construct(struct scic_sds_request *sci_ * This method performs the operations common to all SATA/STP requests * utilizing the raw frame method. none */ -void scu_stp_raw_request_construct_task_context( +static void scu_stp_raw_request_construct_task_context( struct scic_sds_stp_request *this_request, struct scu_task_context *task_context) { @@ -386,59 +359,6 @@ void scu_stp_raw_request_construct_task_context( task_context->transfer_length_bytes = sizeof(struct sata_fis_reg_h2d) - sizeof(u32); } -/** - * - * @this_request: This parameter specifies the core request object to - * construction into an STP/SATA non-data request. - * - * This method will construct the STP Non-data request and its associated TC - * data. A non-data request essentially behaves like a 0 length read request - * in the SCU. This method currently always returns SCI_SUCCESS - */ -enum sci_status scic_sds_stp_non_data_request_construct( - struct scic_sds_request *this_request) -{ - scic_sds_stp_non_ncq_request_construct(this_request); - - /* Build the STP task context structure */ - scu_stp_raw_request_construct_task_context( - (struct scic_sds_stp_request *)this_request, - this_request->task_context_buffer - ); - - sci_base_state_machine_construct( - &this_request->started_substate_machine, - &this_request->parent.parent, - scic_sds_stp_request_started_non_data_substate_table, - SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE - ); - - return SCI_SUCCESS; -} - - -enum sci_status scic_sds_stp_soft_reset_request_construct( - struct scic_sds_request *this_request) -{ - scic_sds_stp_non_ncq_request_construct(this_request); - - /* Build the STP task context structure */ - scu_stp_raw_request_construct_task_context( - (struct scic_sds_stp_request *)this_request, - this_request->task_context_buffer - ); - - sci_base_state_machine_construct( - &this_request->started_substate_machine, - &this_request->parent.parent, - scic_sds_stp_request_started_soft_reset_substate_table, - SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE - ); - - return SCI_SUCCESS; -} - - void scic_stp_io_request_set_ncq_tag( struct scic_sds_request *req, u16 ncq_tag) @@ -474,7 +394,7 @@ void *scic_stp_io_request_get_d2h_reg_address( * - if there are more SGL element pairs - advance to the next pair and return * element A struct scu_sgl_element* */ -struct scu_sgl_element *scic_sds_stp_request_pio_get_next_sgl(struct scic_sds_stp_request *stp_req) +static struct scu_sgl_element *scic_sds_stp_request_pio_get_next_sgl(struct scic_sds_stp_request *stp_req) { struct scu_sgl_element *current_sgl; struct scic_sds_request *sci_req = &stp_req->parent; @@ -508,60 +428,6 @@ struct scu_sgl_element *scic_sds_stp_request_pio_get_next_sgl(struct scic_sds_st return current_sgl; } -/** - * - * @scic_io_request: The core request object which is cast to a SATA PIO - * request object. - * - * This method will construct the SATA PIO request. This method returns an - * indication as to whether the construction was successful. SCI_SUCCESS - * Currently this method always returns this value. - */ -enum sci_status scic_sds_stp_pio_request_construct( - struct scic_sds_request *scic_io_request, - u8 sat_protocol, - bool copy_rx_frame) -{ - struct scic_sds_stp_request *this_request; - - this_request = (struct scic_sds_stp_request *)scic_io_request; - - scic_sds_stp_non_ncq_request_construct(&this_request->parent); - - scu_stp_raw_request_construct_task_context( - this_request, this_request->parent.task_context_buffer - ); - - this_request->type.pio.current_transfer_bytes = 0; - this_request->type.pio.ending_error = 0; - this_request->type.pio.ending_status = 0; - - this_request->type.pio.request_current.sgl_offset = 0; - this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A; - this_request->type.pio.sat_protocol = sat_protocol; - - if (copy_rx_frame) { - scic_sds_request_build_sgl(&this_request->parent); - /* - * Since the IO request copy of the TC contains the same data as - * the actual TC this pointer is vaild for either. */ - this_request->type.pio.request_current.sgl_pair = - &this_request->parent.task_context_buffer->sgl_pair_ab; - } else { - /* The user does not want the data copied to the SGL buffer location */ - this_request->type.pio.request_current.sgl_pair = NULL; - } - - sci_base_state_machine_construct( - &this_request->parent.started_substate_machine, - &this_request->parent.parent.parent, - scic_sds_stp_request_started_pio_substate_table, - SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE - ); - - return SCI_SUCCESS; -} - /** * * @this_request: @@ -689,7 +555,7 @@ static enum sci_status scic_sds_stp_request_non_data_await_d2h_frame_handler( /* --------------------------------------------------------------------------- */ -const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_non_data_substate_handler_table[] = { +static const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_non_data_substate_handler_table[] = { [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE] = { .parent.start_handler = scic_sds_request_default_start_handler, .parent.abort_handler = scic_sds_request_started_state_abort_handler, @@ -740,7 +606,7 @@ static void scic_sds_stp_request_started_non_data_await_d2h_enter( /* --------------------------------------------------------------------------- */ -const struct sci_base_state scic_sds_stp_request_started_non_data_substate_table[] = { +static const struct sci_base_state scic_sds_stp_request_started_non_data_substate_table[] = { [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE] = { .enter_state = scic_sds_stp_request_started_non_data_await_h2d_completion_enter, }, @@ -749,6 +615,23 @@ const struct sci_base_state scic_sds_stp_request_started_non_data_substate_table }, }; +enum sci_status scic_sds_stp_non_data_request_construct(struct scic_sds_request *sci_req) +{ + struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent); + + scic_sds_stp_non_ncq_request_construct(sci_req); + + /* Build the STP task context structure */ + scu_stp_raw_request_construct_task_context(stp_req, sci_req->task_context_buffer); + + sci_base_state_machine_construct(&sci_req->started_substate_machine, + &sci_req->parent.parent, + scic_sds_stp_request_started_non_data_substate_table, + SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE); + + return SCI_SUCCESS; +} + #define SCU_MAX_FRAME_BUFFER_SIZE 0x400 /* 1K is the maximum SCU frame data payload */ /** @@ -1330,7 +1213,7 @@ static enum sci_status scic_sds_stp_request_pio_data_in_await_data_event_handler /* --------------------------------------------------------------------------- */ -const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_pio_substate_handler_table[] = { +static const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_pio_substate_handler_table[] = { [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE] = { .parent.start_handler = scic_sds_request_default_start_handler, .parent.abort_handler = scic_sds_request_started_state_abort_handler, @@ -1422,7 +1305,7 @@ static void scic_sds_stp_request_started_pio_data_out_transmit_data_enter( /* --------------------------------------------------------------------------- */ -const struct sci_base_state scic_sds_stp_request_started_pio_substate_table[] = { +static const struct sci_base_state scic_sds_stp_request_started_pio_substate_table[] = { [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE] = { .enter_state = scic_sds_stp_request_started_pio_await_h2d_completion_enter, }, @@ -1437,6 +1320,45 @@ const struct sci_base_state scic_sds_stp_request_started_pio_substate_table[] = } }; +enum sci_status scic_sds_stp_pio_request_construct(struct scic_sds_request *sci_req, + u8 sat_protocol, + bool copy_rx_frame) +{ + struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent); + struct scic_sds_stp_pio_request *pio = &stp_req->type.pio; + + scic_sds_stp_non_ncq_request_construct(sci_req); + + scu_stp_raw_request_construct_task_context(stp_req, + sci_req->task_context_buffer); + + pio->current_transfer_bytes = 0; + pio->ending_error = 0; + pio->ending_status = 0; + + pio->request_current.sgl_offset = 0; + pio->request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A; + pio->sat_protocol = sat_protocol; + + if (copy_rx_frame) { + scic_sds_request_build_sgl(sci_req); + /* Since the IO request copy of the TC contains the same data as + * the actual TC this pointer is vaild for either. + */ + pio->request_current.sgl_pair = &sci_req->task_context_buffer->sgl_pair_ab; + } else { + /* The user does not want the data copied to the SGL buffer location */ + pio->request_current.sgl_pair = NULL; + } + + sci_base_state_machine_construct(&sci_req->started_substate_machine, + &sci_req->parent.parent, + scic_sds_stp_request_started_pio_substate_table, + SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE); + + return SCI_SUCCESS; +} + static void scic_sds_stp_request_udma_complete_request( struct scic_sds_request *this_request, u32 scu_status, @@ -1594,7 +1516,7 @@ static enum sci_status scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler /* --------------------------------------------------------------------------- */ -const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_udma_substate_handler_table[] = { +static const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_udma_substate_handler_table[] = { [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE] = { .parent.start_handler = scic_sds_request_default_start_handler, .parent.abort_handler = scic_sds_request_started_state_abort_handler, @@ -1648,7 +1570,7 @@ static void scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter( /* --------------------------------------------------------------------------- */ -const struct sci_base_state scic_sds_stp_request_started_udma_substate_table[] = { +static const struct sci_base_state scic_sds_stp_request_started_udma_substate_table[] = { [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE] = { .enter_state = scic_sds_stp_request_started_udma_await_tc_completion_enter, }, @@ -1657,6 +1579,25 @@ const struct sci_base_state scic_sds_stp_request_started_udma_substate_table[] = }, }; +enum sci_status scic_sds_stp_udma_request_construct(struct scic_sds_request *sci_req, + u32 len, + enum dma_data_direction dir) +{ + scic_sds_stp_non_ncq_request_construct(sci_req); + + scic_sds_stp_optimized_request_construct(sci_req, SCU_TASK_TYPE_DMA_IN, + len, dir); + + sci_base_state_machine_construct( + &sci_req->started_substate_machine, + &sci_req->parent.parent, + scic_sds_stp_request_started_udma_substate_table, + SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE + ); + + return SCI_SUCCESS; +} + /** * * @this_request: @@ -1831,7 +1772,7 @@ static enum sci_status scic_sds_stp_request_soft_reset_await_d2h_frame_handler( /* --------------------------------------------------------------------------- */ -const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_soft_reset_substate_handler_table[] = { +static const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_soft_reset_substate_handler_table[] = { [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE] = { .parent.start_handler = scic_sds_request_default_start_handler, .parent.abort_handler = scic_sds_request_started_state_abort_handler, @@ -1925,9 +1866,7 @@ static void scic_sds_stp_request_started_soft_reset_await_d2h_response_enter( ); } -/* --------------------------------------------------------------------------- */ - -const struct sci_base_state scic_sds_stp_request_started_soft_reset_substate_table[] = { +static const struct sci_base_state scic_sds_stp_request_started_soft_reset_substate_table[] = { [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE] = { .enter_state = scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter, }, @@ -1939,3 +1878,19 @@ const struct sci_base_state scic_sds_stp_request_started_soft_reset_substate_tab }, }; +enum sci_status scic_sds_stp_soft_reset_request_construct(struct scic_sds_request *sci_req) +{ + struct scic_sds_stp_request *stp_req = container_of(sci_req, typeof(*stp_req), parent); + + scic_sds_stp_non_ncq_request_construct(sci_req); + + /* Build the STP task context structure */ + scu_stp_raw_request_construct_task_context(stp_req, sci_req->task_context_buffer); + + sci_base_state_machine_construct(&sci_req->started_substate_machine, + &sci_req->parent.parent, + scic_sds_stp_request_started_soft_reset_substate_table, + SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE); + + return SCI_SUCCESS; +} diff --git a/drivers/scsi/isci/core/scic_sds_stp_request.h b/drivers/scsi/isci/core/scic_sds_stp_request.h index c950bb33ee04..107487978f06 100644 --- a/drivers/scsi/isci/core/scic_sds_stp_request.h +++ b/drivers/scsi/isci/core/scic_sds_stp_request.h @@ -76,7 +76,7 @@ struct scic_sds_stp_request { u32 udma; - struct { + struct scic_sds_stp_pio_request { /** * Total transfer for the entire PIO request recorded at request constuction * time. @@ -169,26 +169,8 @@ enum SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_SUBSTATES { SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE, }; -extern const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_udma_substate_handler_table[]; - -extern const struct sci_base_state scic_sds_stp_request_started_udma_substate_table[]; - -extern const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_non_data_substate_handler_table[]; - -extern const struct sci_base_state scic_sds_stp_request_started_non_data_substate_table[]; - -extern const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_soft_reset_substate_handler_table[]; - -extern const struct sci_base_state scic_sds_stp_request_started_soft_reset_substate_table[]; - -/* --------------------------------------------------------------------------- */ - u32 scic_sds_stp_request_get_object_size(void); - -void scic_sds_stp_non_ncq_request_construct( - struct scic_sds_request *this_request); - enum sci_status scic_sds_stp_pio_request_construct( struct scic_sds_request *scic_io_request, u8 sat_protocol, @@ -214,8 +196,5 @@ enum sci_status scic_sds_stp_ncq_request_construct( u32 transfer_length, enum dma_data_direction dir); -void scu_stp_raw_request_construct_task_context( - struct scic_sds_stp_request *this_request, - struct scu_task_context *task_context); #endif /* _SCIC_SDS_STP_REQUEST_T_ */ diff --git a/drivers/scsi/isci/firmware/README b/drivers/scsi/isci/firmware/README index cf7e4286e896..8056d2bd233b 100644 --- a/drivers/scsi/isci/firmware/README +++ b/drivers/scsi/isci/firmware/README @@ -32,5 +32,5 @@ Header Type - u8: 0xf ============================================================================== Place isci_firmware.bin in /lib/firmware -Be sure to recreate the initramfs image to include the firmware. +Be sure to recreate the initramfs image to include the firmware. diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c index 666076a2834e..74dc96dc6b17 100644 --- a/drivers/scsi/isci/port.c +++ b/drivers/scsi/isci/port.c @@ -201,7 +201,7 @@ void isci_port_link_up( call_status = scic_sata_phy_get_properties(phy, &sata_phy_properties); - /* + /* * XXX I am concerned about this "assert". shouldn't we * handle the return appropriately? */ diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index eba8e0b3c873..c6ce9d0c50c2 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -1263,47 +1263,6 @@ enum dma_data_direction isci_request_io_request_get_data_direction( * * physical address in the specified sge. */ -dma_addr_t isci_request_sge_get_address_field( - struct isci_request *request, - void *sge_address) -{ - struct sas_task *task = isci_request_access_task(request); - dma_addr_t ret; - struct isci_host *isci_host = isci_host_from_sas_ha( - task->dev->port->ha); - - dev_dbg(&isci_host->pdev->dev, - "%s: request = %p, sge_address = %p\n", - __func__, - request, - sge_address); - - if (task->data_dir == PCI_DMA_NONE) - return 0; - - /* the case where num_scatter == 0 is special, in that - * task->scatter is the actual buffer address, not an sgl. - * so a map single is required here. - */ - if ((task->num_scatter == 0) && - !sas_protocol_ata(task->task_proto)) { - ret = dma_map_single( - &isci_host->pdev->dev, - task->scatter, - task->total_xfer_len, - task->data_dir - ); - request->zero_scatter_daddr = ret; - } else - ret = sg_dma_address(((struct scatterlist *)sge_address)); - - dev_dbg(&isci_host->pdev->dev, - "%s: bus address = %lx\n", - __func__, - (unsigned long)ret); - - return ret; -} /** @@ -1314,38 +1273,6 @@ dma_addr_t isci_request_sge_get_address_field( * * length field value in the specified sge. */ -u32 isci_request_sge_get_length_field( - struct isci_request *request, - void *sge_address) -{ - struct sas_task *task = isci_request_access_task(request); - int ret; - - dev_dbg(&request->isci_host->pdev->dev, - "%s: request = %p, sge_address = %p\n", - __func__, - request, - sge_address); - - if (task->data_dir == PCI_DMA_NONE) - return 0; - - /* the case where num_scatter == 0 is special, in that - * task->scatter is the actual buffer address, not an sgl. - * so we return total_xfer_len here. - */ - if (task->num_scatter == 0) - ret = task->total_xfer_len; - else - ret = sg_dma_len((struct scatterlist *)sge_address); - - dev_dbg(&request->isci_host->pdev->dev, - "%s: len = %d\n", - __func__, - ret); - - return ret; -} /** diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h index b45c0f1f057f..4a63bb6de44e 100644 --- a/drivers/scsi/isci/request.h +++ b/drivers/scsi/isci/request.h @@ -391,13 +391,7 @@ static inline void *isci_request_io_request_get_next_sge( return ret; } -dma_addr_t isci_request_sge_get_address_field( - struct isci_request *request, - void *sge_address); -u32 isci_request_sge_get_length_field( - struct isci_request *request, - void *sge_address); void *isci_request_ssp_io_request_get_cdb_address( struct isci_request *request); diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index d48368002504..7e9668402559 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c @@ -588,7 +588,7 @@ void isci_task_build_tmf( tmf->cb_data = cb_data; } -void isci_task_build_abort_task_tmf( +static void isci_task_build_abort_task_tmf( struct isci_tmf *tmf, struct isci_remote_device *isci_device, enum isci_tmf_function_codes code, @@ -1528,15 +1528,6 @@ void isci_task_request_complete( * * lun for specified task request. */ -u32 isci_task_ssp_request_get_lun(struct isci_request *request) -{ - struct isci_tmf *isci_tmf = isci_request_access_tmf(request); - - dev_dbg(&request->isci_host->pdev->dev, - "%s: lun = %d\n", __func__, isci_tmf->lun[0]); -/* @todo: build lun from array of bytes to 32 bit */ - return isci_tmf->lun[0]; -} /** * isci_task_ssp_request_get_function() - This function is called by the sci diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h index 9754b43f5b0b..d7cb6fe268c4 100644 --- a/drivers/scsi/isci/task.h +++ b/drivers/scsi/isci/task.h @@ -202,8 +202,6 @@ u16 isci_task_ssp_request_get_io_tag_to_manage( u8 isci_task_ssp_request_get_function( struct isci_request *request); -u32 isci_task_ssp_request_get_lun( - struct isci_request *request); void *isci_task_ssp_request_get_response_data_address( struct isci_request *request); @@ -226,14 +224,6 @@ void isci_task_build_tmf( void *), void *cb_data); -void isci_task_build_abort_task_tmf( - struct isci_tmf *tmf, - struct isci_remote_device *isci_device, - enum isci_tmf_function_codes code, - void (*tmf_sent_cb)( - enum isci_tmf_cb_state, - struct isci_tmf *, void *), - struct isci_request *old_request); int isci_task_execute_tmf( struct isci_host *isci_host,