2011-07-02 22:56:22 -07:00
/*
* This file is provided under a dual BSD / GPLv2 license . When using or
* redistributing this file , you may do so under either license .
*
* GPL LICENSE SUMMARY
*
* Copyright ( c ) 2008 - 2011 Intel Corporation . All rights reserved .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St - Fifth Floor , Boston , MA 02110 - 1301 USA .
* The full GNU General Public License is included in this distribution
* in the file called LICENSE . GPL .
*
* BSD LICENSE
*
* Copyright ( c ) 2008 - 2011 Intel Corporation . All rights reserved .
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in
* the documentation and / or other materials provided with the
* distribution .
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2011-04-22 19:18:03 -07:00
# ifndef _ISCI_REMOTE_DEVICE_H_
2011-07-02 22:56:22 -07:00
# define _ISCI_REMOTE_DEVICE_H_
2011-04-22 19:18:03 -07:00
# include <scsi/libsas.h>
2011-06-13 17:39:44 -07:00
# include <linux/kref.h>
2011-04-22 19:18:03 -07:00
# include "scu_remote_node_context.h"
# include "remote_node_context.h"
# include "port.h"
2011-07-02 22:56:22 -07:00
2011-06-30 19:14:33 -07:00
enum sci_remote_device_not_ready_reason_code {
2011-04-22 19:18:03 -07:00
SCIC_REMOTE_DEVICE_NOT_READY_START_REQUESTED ,
SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED ,
SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED ,
SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED ,
SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED ,
SCIC_REMOTE_DEVICE_NOT_READY_REASON_CODE_MAX
} ;
2011-06-30 16:31:37 -07:00
/**
* isci_remote_device - isci representation of a sas expander / end point
* @ device_port_width : hw setting for number of simultaneous connections
* @ connection_rate : per - taskcontext connection rate for this device
* @ working_request : SATA requests have no tag we for unaccelerated
* protocols we need a method to associate unsolicited
* frames with a pending request
*/
2011-07-02 22:56:22 -07:00
struct isci_remote_device {
2011-03-04 12:10:29 -08:00
# define IDEV_START_PENDING 0
# define IDEV_STOP_PENDING 1
2011-03-03 17:59:32 -08:00
# define IDEV_ALLOCATED 2
2011-05-02 13:59:25 -07:00
# define IDEV_EH 3
2011-06-13 17:39:44 -07:00
# define IDEV_GONE 4
2011-06-16 11:26:12 -07:00
# define IDEV_IO_READY 5
2011-06-23 17:09:02 -07:00
# define IDEV_IO_NCQERROR 6
2011-03-04 12:10:29 -08:00
unsigned long flags ;
2011-06-13 17:39:44 -07:00
struct kref kref ;
2011-07-02 22:56:22 -07:00
struct isci_port * isci_port ;
struct domain_device * domain_dev ;
struct list_head node ;
struct list_head reqs_in_process ;
2011-06-30 16:31:37 -07:00
struct sci_base_state_machine sm ;
u32 device_port_width ;
enum sas_linkrate connection_rate ;
bool is_direct_attached ;
struct isci_port * owning_port ;
2011-06-30 19:14:33 -07:00
struct sci_remote_node_context rnc ;
2011-06-30 16:31:37 -07:00
/* XXX unify with device reference counting and delete */
u32 started_request_count ;
struct isci_request * working_request ;
u32 not_ready_reason ;
2011-07-02 22:56:22 -07:00
} ;
# define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000
2011-06-30 19:14:33 -07:00
/* device reference routines must be called under sci_lock */
2011-06-13 17:39:44 -07:00
static inline struct isci_remote_device * isci_lookup_device ( struct domain_device * dev )
{
struct isci_remote_device * idev = dev - > lldd_dev ;
if ( idev & & ! test_bit ( IDEV_GONE , & idev - > flags ) ) {
kref_get ( & idev - > kref ) ;
return idev ;
}
return NULL ;
}
void isci_remote_device_release ( struct kref * kref ) ;
static inline void isci_put_device ( struct isci_remote_device * idev )
{
if ( idev )
kref_put ( & idev - > kref , isci_remote_device_release ) ;
}
2011-03-04 12:10:29 -08:00
enum sci_status isci_remote_device_stop ( struct isci_host * ihost ,
struct isci_remote_device * idev ) ;
2011-03-31 13:10:44 -07:00
void isci_remote_device_nuke_requests ( struct isci_host * ihost ,
struct isci_remote_device * idev ) ;
void isci_remote_device_gone ( struct domain_device * domain_dev ) ;
int isci_remote_device_found ( struct domain_device * domain_dev ) ;
bool isci_device_is_reset_pending ( struct isci_host * ihost ,
struct isci_remote_device * idev ) ;
void isci_device_clear_reset_pending ( struct isci_host * ihost ,
struct isci_remote_device * idev ) ;
2011-04-22 19:18:03 -07:00
/**
2011-06-30 19:14:33 -07:00
* sci_remote_device_stop ( ) - This method will stop both transmission and
2011-04-22 19:18:03 -07:00
* reception of link activity for the supplied remote device . This method
* disables normal IO requests from flowing through to the remote device .
* @ remote_device : This parameter specifies the device to be stopped .
* @ timeout : This parameter specifies the number of milliseconds in which the
* stop operation should complete .
*
* An indication of whether the device was successfully stopped . SCI_SUCCESS
* This value is returned if the transmission and reception for the device was
* successfully stopped .
*/
2011-06-30 19:14:33 -07:00
enum sci_status sci_remote_device_stop (
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ,
2011-04-22 19:18:03 -07:00
u32 timeout ) ;
/**
2011-06-30 19:14:33 -07:00
* sci_remote_device_reset ( ) - This method will reset the device making it
2011-04-22 19:18:03 -07:00
* ready for operation . This method must be called anytime the device is
* reset either through a SMP phy control or a port hard reset request .
* @ remote_device : This parameter specifies the device to be reset .
*
* This method does not actually cause the device hardware to be reset . This
* method resets the software object so that it will be operational after a
* device hardware reset completes . An indication of whether the device reset
* was accepted . SCI_SUCCESS This value is returned if the device reset is
* started .
*/
2011-06-30 19:14:33 -07:00
enum sci_status sci_remote_device_reset (
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ) ;
2011-04-22 19:18:03 -07:00
/**
2011-06-30 19:14:33 -07:00
* sci_remote_device_reset_complete ( ) - This method informs the device object
2011-04-22 19:18:03 -07:00
* that the reset operation is complete and the device can resume operation
* again .
* @ remote_device : This parameter specifies the device which is to be informed
* of the reset complete operation .
*
* An indication that the device is resuming operation . SCI_SUCCESS the device
* is resuming operation .
*/
2011-06-30 19:14:33 -07:00
enum sci_status sci_remote_device_reset_complete (
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ) ;
2011-04-22 19:18:03 -07:00
/**
2011-06-30 19:14:33 -07:00
* enum sci_remote_device_states - This enumeration depicts all the states
2011-04-22 19:18:03 -07:00
* for the common remote device state machine .
*
*
*/
2011-06-30 19:14:33 -07:00
enum sci_remote_device_states {
2011-04-22 19:18:03 -07:00
/**
* Simply the initial state for the base remote device state machine .
*/
2011-06-02 00:10:43 +00:00
SCI_DEV_INITIAL ,
2011-04-22 19:18:03 -07:00
/**
* This state indicates that the remote device has successfully been
* stopped . In this state no new IO operations are permitted .
* This state is entered from the INITIAL state .
* This state is entered from the STOPPING state .
*/
2011-06-02 00:10:43 +00:00
SCI_DEV_STOPPED ,
2011-04-22 19:18:03 -07:00
/**
* This state indicates the the remote device is in the process of
* becoming ready ( i . e . starting ) . In this state no new IO operations
* are permitted .
* This state is entered from the STOPPED state .
*/
2011-06-02 00:10:43 +00:00
SCI_DEV_STARTING ,
2011-04-22 19:18:03 -07:00
/**
* This state indicates the remote device is now ready . Thus , the user
* is able to perform IO operations on the remote device .
* This state is entered from the STARTING state .
*/
2011-06-02 00:10:43 +00:00
SCI_DEV_READY ,
2011-04-22 19:18:03 -07:00
/**
* This is the idle substate for the stp remote device . When there are no
* active IO for the device it is is in this state .
*/
2011-06-02 00:10:43 +00:00
SCI_STP_DEV_IDLE ,
2011-04-22 19:18:03 -07:00
/**
* This is the command state for for the STP remote device . This state is
* entered when the device is processing a non - NCQ command . The device object
* will fail any new start IO requests until this command is complete .
*/
2011-06-02 00:10:43 +00:00
SCI_STP_DEV_CMD ,
2011-04-22 19:18:03 -07:00
/**
* This is the NCQ state for the STP remote device . This state is entered
* when the device is processing an NCQ reuqest . It will remain in this state
* so long as there is one or more NCQ requests being processed .
*/
2011-06-02 00:10:43 +00:00
SCI_STP_DEV_NCQ ,
2011-04-22 19:18:03 -07:00
/**
* This is the NCQ error state for the STP remote device . This state is
* entered when an SDB error FIS is received by the device object while in the
* NCQ state . The device object will only accept a READ LOG command while in
* this state .
*/
2011-06-02 00:10:43 +00:00
SCI_STP_DEV_NCQ_ERROR ,
2011-04-22 19:18:03 -07:00
/**
* This is the READY substate indicates the device is waiting for the RESET task
* coming to be recovered from certain hardware specific error .
*/
2011-06-02 00:10:43 +00:00
SCI_STP_DEV_AWAIT_RESET ,
2011-04-22 19:18:03 -07:00
/**
* This is the ready operational substate for the remote device . This is the
* normal operational state for a remote device .
*/
2011-06-02 00:10:43 +00:00
SCI_SMP_DEV_IDLE ,
2011-04-22 19:18:03 -07:00
/**
* This is the suspended state for the remote device . This is the state that
* the device is placed in when a RNC suspend is received by the SCU hardware .
*/
2011-06-02 00:10:43 +00:00
SCI_SMP_DEV_CMD ,
2011-04-27 16:32:45 -07:00
/**
* This state indicates that the remote device is in the process of
* stopping . In this state no new IO operations are permitted , but
* existing IO operations are allowed to complete .
* This state is entered from the READY state .
* This state is entered from the FAILED state .
*/
2011-06-02 00:10:43 +00:00
SCI_DEV_STOPPING ,
2011-04-27 16:32:45 -07:00
/**
* This state indicates that the remote device has failed .
* In this state no new IO operations are permitted .
* This state is entered from the INITIALIZING state .
* This state is entered from the READY state .
*/
2011-06-02 00:10:43 +00:00
SCI_DEV_FAILED ,
2011-04-27 16:32:45 -07:00
/**
* This state indicates the device is being reset .
* In this state no new IO operations are permitted .
* This state is entered from the READY state .
*/
2011-06-02 00:10:43 +00:00
SCI_DEV_RESETTING ,
2011-04-27 16:32:45 -07:00
/**
* Simply the final state for the base remote device state machine .
*/
2011-06-02 00:10:43 +00:00
SCI_DEV_FINAL ,
2011-04-22 19:18:03 -07:00
} ;
2011-06-30 19:14:33 -07:00
static inline struct isci_remote_device * rnc_to_dev ( struct sci_remote_node_context * rnc )
2011-04-22 19:18:03 -07:00
{
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ;
2011-04-22 19:18:03 -07:00
2011-06-30 16:31:37 -07:00
idev = container_of ( rnc , typeof ( * idev ) , rnc ) ;
2011-04-21 18:44:45 -07:00
2011-04-28 22:06:21 +00:00
return idev ;
}
2011-04-21 18:44:45 -07:00
static inline bool dev_is_expander ( struct domain_device * dev )
{
return dev - > dev_type = = EDGE_DEV | | dev - > dev_type = = FANOUT_DEV ;
}
2011-07-01 02:25:15 -07:00
static inline void sci_remote_device_decrement_request_count ( struct isci_remote_device * idev )
{
/* XXX delete this voodoo when converting to the top-level device
* reference count
*/
if ( WARN_ONCE ( idev - > started_request_count = = 0 ,
" %s: tried to decrement started_request_count past 0!? " ,
__func__ ) )
/* pass */ ;
else
idev - > started_request_count - - ;
}
2011-04-22 19:18:03 -07:00
2011-06-30 19:14:33 -07:00
enum sci_status sci_remote_device_frame_handler (
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ,
2011-04-22 19:18:03 -07:00
u32 frame_index ) ;
2011-06-30 19:14:33 -07:00
enum sci_status sci_remote_device_event_handler (
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ,
2011-04-22 19:18:03 -07:00
u32 event_code ) ;
2011-06-30 19:14:33 -07:00
enum sci_status sci_remote_device_start_io (
2011-06-30 17:38:32 -07:00
struct isci_host * ihost ,
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ,
2011-06-27 14:57:03 -07:00
struct isci_request * ireq ) ;
2011-04-22 19:18:03 -07:00
2011-06-30 19:14:33 -07:00
enum sci_status sci_remote_device_start_task (
2011-06-30 17:38:32 -07:00
struct isci_host * ihost ,
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ,
2011-06-27 14:57:03 -07:00
struct isci_request * ireq ) ;
2011-04-22 19:18:03 -07:00
2011-06-30 19:14:33 -07:00
enum sci_status sci_remote_device_complete_io (
2011-06-30 17:38:32 -07:00
struct isci_host * ihost ,
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ,
2011-06-27 14:57:03 -07:00
struct isci_request * ireq ) ;
2011-04-22 19:18:03 -07:00
2011-06-30 19:14:33 -07:00
enum sci_status sci_remote_device_suspend (
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ,
2011-04-22 19:18:03 -07:00
u32 suspend_type ) ;
2011-06-30 19:14:33 -07:00
void sci_remote_device_post_request (
2011-06-30 16:31:37 -07:00
struct isci_remote_device * idev ,
2011-04-22 19:18:03 -07:00
u32 request ) ;
2011-07-02 22:56:22 -07:00
# endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */