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 .
*/
# include "isci.h"
# include "scic_io_request.h"
# include "scic_remote_device.h"
# include "scic_phy.h"
# include "scic_port.h"
# include "port.h"
# include "remote_device.h"
# include "request.h"
# include "task.h"
/**
* isci_remote_device_deconstruct ( ) - This function frees an isci_remote_device .
2011-03-03 17:59:32 -08:00
* @ ihost : This parameter specifies the isci host object .
* @ idev : This parameter specifies the remote device to be freed .
2011-07-02 22:56:22 -07:00
*
*/
2011-03-03 17:59:32 -08:00
static void isci_remote_device_deconstruct ( struct isci_host * ihost , struct isci_remote_device * idev )
2011-07-02 22:56:22 -07:00
{
2011-03-03 17:59:32 -08:00
dev_dbg ( & ihost - > pdev - > dev ,
" %s: isci_device = %p \n " , __func__ , idev ) ;
2011-07-02 22:56:22 -07:00
/* There should not be any outstanding io's. All paths to
* here should go through isci_remote_device_nuke_requests .
* If we hit this condition , we will need a way to complete
* io requests in process */
2011-03-03 17:59:32 -08:00
while ( ! list_empty ( & idev - > reqs_in_process ) ) {
2011-07-02 22:56:22 -07:00
2011-03-03 17:59:32 -08:00
dev_err ( & ihost - > pdev - > dev ,
2011-07-02 22:56:22 -07:00
" %s: ** request list not empty! ** \n " , __func__ ) ;
BUG ( ) ;
}
2011-03-03 17:59:32 -08:00
scic_remote_device_destruct ( to_sci_dev ( idev ) ) ;
idev - > domain_dev - > lldd_dev = NULL ;
idev - > domain_dev = NULL ;
idev - > isci_port = NULL ;
list_del_init ( & idev - > node ) ;
clear_bit ( IDEV_START_PENDING , & idev - > flags ) ;
clear_bit ( IDEV_STOP_PENDING , & idev - > flags ) ;
wake_up ( & ihost - > eventq ) ;
2011-07-02 22:56:22 -07:00
}
/**
* isci_remote_device_construct ( ) - This function calls the scic remote device
* construct and start functions , it waits on the remote device start
* completion .
* @ port : This parameter specifies the isci port with the remote device .
* @ isci_device : This parameter specifies the isci remote device
*
* status from the scic calls , the caller to this function should clean up
* resources as appropriate .
*/
static enum sci_status isci_remote_device_construct (
struct isci_port * port ,
struct isci_remote_device * isci_device )
{
enum sci_status status = SCI_SUCCESS ;
/* let the core do it's common constuction. */
scic_remote_device_construct ( port - > sci_port_handle ,
2011-03-04 11:51:43 -08:00
to_sci_dev ( isci_device ) ) ;
2011-07-02 22:56:22 -07:00
/* let the core do it's device specific constuction. */
if ( isci_device - > domain_dev - > parent & &
( isci_device - > domain_dev - > parent - > dev_type = = EDGE_DEV ) ) {
int i ;
/* struct smp_response_discover discover_response; */
struct discover_resp discover_response ;
struct domain_device * parent =
isci_device - > domain_dev - > parent ;
struct expander_device * parent_ex = & parent - > ex_dev ;
for ( i = 0 ; i < parent_ex - > num_phys ; i + + ) {
struct ex_phy * phy = & parent_ex - > ex_phy [ i ] ;
if ( ( phy - > phy_state = = PHY_VACANT ) | |
( phy - > phy_state = = PHY_NOT_PRESENT ) )
continue ;
if ( SAS_ADDR ( phy - > attached_sas_addr )
= = SAS_ADDR ( isci_device - > domain_dev - > sas_addr ) ) {
discover_response . attached_dev_type
= phy - > attached_dev_type ;
discover_response . linkrate
= phy - > linkrate ;
discover_response . attached_sata_host
= phy - > attached_sata_host ;
discover_response . attached_sata_dev
= phy - > attached_sata_dev ;
discover_response . attached_sata_ps
= phy - > attached_sata_ps ;
discover_response . iproto
= phy - > attached_iproto > > 1 ;
discover_response . tproto
= phy - > attached_tproto > > 1 ;
memcpy (
discover_response . attached_sas_addr ,
phy - > attached_sas_addr ,
SAS_ADDR_SIZE
) ;
discover_response . attached_phy_id
= phy - > attached_phy_id ;
discover_response . change_count
= phy - > phy_change_count ;
discover_response . routing_attr
= phy - > routing_attr ;
discover_response . hmin_linkrate
= phy - > phy - > minimum_linkrate_hw ;
discover_response . hmax_linkrate
= phy - > phy - > maximum_linkrate_hw ;
discover_response . pmin_linkrate
= phy - > phy - > minimum_linkrate ;
discover_response . pmax_linkrate
= phy - > phy - > maximum_linkrate ;
}
}
dev_dbg ( & port - > isci_host - > pdev - > dev ,
" %s: parent->dev_type = EDGE_DEV \n " ,
__func__ ) ;
2011-03-04 11:51:43 -08:00
status = scic_remote_device_ea_construct ( to_sci_dev ( isci_device ) ,
( struct smp_response_discover * ) & discover_response ) ;
2011-07-02 22:56:22 -07:00
} else
2011-03-04 11:51:43 -08:00
status = scic_remote_device_da_construct ( to_sci_dev ( isci_device ) ) ;
2011-07-02 22:56:22 -07:00
if ( status ! = SCI_SUCCESS ) {
dev_dbg ( & port - > isci_host - > pdev - > dev ,
" %s: scic_remote_device_da_construct failed - "
" isci_device = %p \n " ,
__func__ ,
isci_device ) ;
return status ;
}
2011-03-04 11:51:43 -08:00
sci_object_set_association ( to_sci_dev ( isci_device ) , isci_device ) ;
2011-07-02 22:56:22 -07:00
/* start the device. */
2011-03-04 11:51:43 -08:00
status = scic_remote_device_start ( to_sci_dev ( isci_device ) ,
ISCI_REMOTE_DEVICE_START_TIMEOUT ) ;
2011-07-02 22:56:22 -07:00
if ( status ! = SCI_SUCCESS ) {
dev_warn ( & port - > isci_host - > pdev - > dev ,
" %s: scic_remote_device_start failed \n " ,
__func__ ) ;
return status ;
}
return status ;
}
2011-03-31 13:10:44 -07:00
void isci_remote_device_nuke_requests ( struct isci_host * ihost , struct isci_remote_device * idev )
2011-07-02 22:56:22 -07:00
{
DECLARE_COMPLETION_ONSTACK ( aborted_task_completion ) ;
2011-03-31 13:10:44 -07:00
dev_dbg ( & ihost - > pdev - > dev ,
" %s: idev = %p \n " , __func__ , idev ) ;
2011-07-02 22:56:22 -07:00
/* Cleanup all requests pending for this device. */
2011-03-31 13:10:44 -07:00
isci_terminate_pending_requests ( ihost , idev , terminating ) ;
2011-07-02 22:56:22 -07:00
2011-03-31 13:10:44 -07:00
dev_dbg ( & ihost - > pdev - > dev ,
" %s: idev = %p, done \n " , __func__ , idev ) ;
2011-07-02 22:56:22 -07:00
}
/**
* This function builds the isci_remote_device when a libsas dev_found message
* is received .
* @ isci_host : This parameter specifies the isci host object .
* @ port : This parameter specifies the isci_port conected to this device .
*
* pointer to new isci_remote_device .
*/
static struct isci_remote_device *
2011-03-03 17:59:32 -08:00
isci_remote_device_alloc ( struct isci_host * ihost , struct isci_port * iport )
2011-07-02 22:56:22 -07:00
{
2011-03-03 17:59:32 -08:00
struct isci_remote_device * idev ;
int i ;
2011-07-02 22:56:22 -07:00
2011-03-03 17:59:32 -08:00
for ( i = 0 ; i < SCI_MAX_REMOTE_DEVICES ; i + + ) {
idev = idev_by_id ( ihost , i ) ;
if ( ! test_and_set_bit ( IDEV_ALLOCATED , & idev - > flags ) )
break ;
}
2011-07-02 22:56:22 -07:00
2011-03-03 17:59:32 -08:00
if ( i > = SCI_MAX_REMOTE_DEVICES ) {
dev_warn ( & ihost - > pdev - > dev , " %s: failed \n " , __func__ ) ;
2011-07-02 22:56:22 -07:00
return NULL ;
}
2011-04-12 17:28:43 -07:00
if ( WARN_ONCE ( ! list_empty ( & idev - > reqs_in_process ) , " found requests in process \n " ) )
return NULL ;
if ( WARN_ONCE ( ! list_empty ( & idev - > node ) , " found non-idle remote device \n " ) )
return NULL ;
2011-03-03 17:59:32 -08:00
isci_remote_device_change_state ( idev , isci_freed ) ;
2011-07-02 22:56:22 -07:00
2011-03-03 17:59:32 -08:00
return idev ;
2011-07-02 22:56:22 -07:00
}
/**
* isci_remote_device_ready ( ) - This function is called by the scic when the
* remote device is ready . We mark the isci device as ready and signal the
* waiting proccess .
2011-03-31 13:10:42 -07:00
* @ ihost : our valid isci_host
* @ idev : remote device
2011-07-02 22:56:22 -07:00
*
*/
2011-03-31 13:10:42 -07:00
void isci_remote_device_ready ( struct isci_host * ihost , struct isci_remote_device * idev )
2011-07-02 22:56:22 -07:00
{
2011-03-04 12:10:29 -08:00
dev_dbg ( & ihost - > pdev - > dev ,
2011-03-03 18:01:43 -08:00
" %s: idev = %p \n " , __func__ , idev ) ;
2011-07-02 22:56:22 -07:00
2011-03-04 12:10:29 -08:00
isci_remote_device_change_state ( idev , isci_ready_for_io ) ;
if ( test_and_clear_bit ( IDEV_START_PENDING , & idev - > flags ) )
wake_up ( & ihost - > eventq ) ;
2011-07-02 22:56:22 -07:00
}
/**
* isci_remote_device_not_ready ( ) - This function is called by the scic when
* the remote device is not ready . We mark the isci device as ready ( not
* " ready_for_io " ) and signal the waiting proccess .
* @ isci_host : This parameter specifies the isci host object .
* @ isci_device : This parameter specifies the remote device
*
*/
2011-03-31 13:10:42 -07:00
void isci_remote_device_not_ready ( struct isci_host * ihost ,
struct isci_remote_device * idev , u32 reason )
2011-07-02 22:56:22 -07:00
{
2011-03-31 13:10:42 -07:00
dev_dbg ( & ihost - > pdev - > dev ,
" %s: isci_device = %p \n " , __func__ , idev ) ;
2011-07-02 22:56:22 -07:00
2011-03-31 13:10:42 -07:00
if ( reason = = SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED )
isci_remote_device_change_state ( idev , isci_stopping ) ;
2011-07-02 22:56:22 -07:00
else
/* device ready is actually a "not ready for io" state. */
2011-03-31 13:10:42 -07:00
isci_remote_device_change_state ( idev , isci_ready ) ;
2011-07-02 22:56:22 -07:00
}
/**
* isci_remote_device_stop_complete ( ) - This function is called by the scic
* when the remote device stop has completed . We mark the isci device as not
* ready and remove the isci remote device .
* @ isci_host : This parameter specifies the isci host object .
* @ isci_device : This parameter specifies the remote device .
* @ status : This parameter specifies status of the completion .
*
*/
void isci_remote_device_stop_complete (
struct isci_host * isci_host ,
struct isci_remote_device * isci_device ,
enum sci_status status )
{
dev_dbg ( & isci_host - > pdev - > dev ,
" %s: complete isci_device = %p, status = 0x%x \n " ,
__func__ ,
isci_device ,
status ) ;
isci_remote_device_change_state ( isci_device , isci_stopped ) ;
/* after stop, we can tear down resources. */
isci_remote_device_deconstruct ( isci_host , isci_device ) ;
}
/**
* isci_remote_device_start_complete ( ) - This function is called by the scic
* when the remote device start has completed
* @ isci_host : This parameter specifies the isci host object .
* @ isci_device : This parameter specifies the remote device .
* @ status : This parameter specifies status of the completion .
*
*/
void isci_remote_device_start_complete (
struct isci_host * isci_host ,
struct isci_remote_device * isci_device ,
enum sci_status status )
{
}
/**
* isci_remote_device_stop ( ) - This function is called internally to stop the
* remote device .
* @ isci_host : This parameter specifies the isci host object .
* @ isci_device : This parameter specifies the remote device .
*
* The status of the scic request to stop .
*/
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-07-02 22:56:22 -07:00
{
enum sci_status status ;
unsigned long flags ;
2011-03-04 12:10:29 -08:00
dev_dbg ( & ihost - > pdev - > dev ,
" %s: isci_device = %p \n " , __func__ , idev ) ;
2011-07-02 22:56:22 -07:00
2011-03-04 12:10:29 -08:00
isci_remote_device_change_state ( idev , isci_stopping ) ;
2011-03-08 20:32:16 -07:00
/* Kill all outstanding requests. */
2011-03-31 13:10:44 -07:00
isci_remote_device_nuke_requests ( ihost , idev ) ;
2011-03-08 20:32:16 -07:00
2011-03-04 12:10:29 -08:00
set_bit ( IDEV_STOP_PENDING , & idev - > flags ) ;
2011-07-02 22:56:22 -07:00
2011-03-04 12:10:29 -08:00
spin_lock_irqsave ( & ihost - > scic_lock , flags ) ;
status = scic_remote_device_stop ( to_sci_dev ( idev ) , 50 ) ;
spin_unlock_irqrestore ( & ihost - > scic_lock , flags ) ;
2011-07-02 22:56:22 -07:00
/* Wait for the stop complete callback. */
2011-03-03 17:59:32 -08:00
if ( status = = SCI_SUCCESS ) {
2011-03-04 12:10:29 -08:00
wait_for_device_stop ( ihost , idev ) ;
2011-03-03 17:59:32 -08:00
clear_bit ( IDEV_ALLOCATED , & idev - > flags ) ;
}
2011-07-02 22:56:22 -07:00
2011-03-04 12:10:29 -08:00
dev_dbg ( & ihost - > pdev - > dev ,
" %s: idev = %p - after completion wait \n " ,
__func__ , idev ) ;
2011-07-02 22:56:22 -07:00
return status ;
}
/**
* isci_remote_device_gone ( ) - This function is called by libsas when a domain
* device is removed .
* @ domain_device : This parameter specifies the libsas domain device .
*
*/
2011-03-04 12:10:29 -08:00
void isci_remote_device_gone ( struct domain_device * dev )
2011-07-02 22:56:22 -07:00
{
2011-03-31 13:10:44 -07:00
struct isci_host * ihost = dev_to_ihost ( dev ) ;
2011-03-04 12:10:29 -08:00
struct isci_remote_device * idev = dev - > lldd_dev ;
2011-07-02 22:56:22 -07:00
2011-03-04 12:10:29 -08:00
dev_dbg ( & ihost - > pdev - > dev ,
2011-07-02 22:56:22 -07:00
" %s: domain_device = %p, isci_device = %p, isci_port = %p \n " ,
2011-03-04 12:10:29 -08:00
__func__ , dev , idev , idev - > isci_port ) ;
2011-07-02 22:56:22 -07:00
2011-03-04 12:10:29 -08:00
isci_remote_device_stop ( ihost , idev ) ;
2011-07-02 22:56:22 -07:00
}
/**
* isci_remote_device_found ( ) - This function is called by libsas when a remote
* device is discovered . A remote device object is created and started . the
* function then sleeps until the sci core device started message is
* received .
* @ domain_device : This parameter specifies the libsas domain device .
*
* status , zero indicates success .
*/
int isci_remote_device_found ( struct domain_device * domain_dev )
{
2011-03-31 13:10:44 -07:00
struct isci_host * isci_host = dev_to_ihost ( domain_dev ) ;
2011-07-02 22:56:22 -07:00
struct isci_port * isci_port ;
struct isci_phy * isci_phy ;
struct asd_sas_port * sas_port ;
struct asd_sas_phy * sas_phy ;
struct isci_remote_device * isci_device ;
enum sci_status status ;
dev_dbg ( & isci_host - > pdev - > dev ,
" %s: domain_device = %p \n " , __func__ , domain_dev ) ;
2011-02-18 09:25:07 -08:00
wait_for_start ( isci_host ) ;
2011-07-02 22:56:22 -07:00
sas_port = domain_dev - > port ;
sas_phy = list_first_entry ( & sas_port - > phy_list , struct asd_sas_phy ,
port_phy_el ) ;
isci_phy = to_isci_phy ( sas_phy ) ;
isci_port = isci_phy - > isci_port ;
/* we are being called for a device on this port,
* so it has to come up eventually
*/
wait_for_completion ( & isci_port - > start_complete ) ;
if ( ( isci_stopping = = isci_port_get_state ( isci_port ) ) | |
( isci_stopped = = isci_port_get_state ( isci_port ) ) )
return - ENODEV ;
isci_device = isci_remote_device_alloc ( isci_host , isci_port ) ;
2011-03-03 17:59:32 -08:00
if ( ! isci_device )
return - ENODEV ;
2011-07-02 22:56:22 -07:00
INIT_LIST_HEAD ( & isci_device - > node ) ;
domain_dev - > lldd_dev = isci_device ;
isci_device - > domain_dev = domain_dev ;
isci_device - > isci_port = isci_port ;
isci_remote_device_change_state ( isci_device , isci_starting ) ;
2011-03-03 18:01:43 -08:00
spin_lock_irq ( & isci_host - > scic_lock ) ;
2011-07-02 22:56:22 -07:00
list_add_tail ( & isci_device - > node , & isci_port - > remote_dev_list ) ;
2011-03-04 12:10:29 -08:00
set_bit ( IDEV_START_PENDING , & isci_device - > flags ) ;
2011-07-02 22:56:22 -07:00
status = isci_remote_device_construct ( isci_port , isci_device ) ;
2011-03-03 18:01:43 -08:00
spin_unlock_irq ( & isci_host - > scic_lock ) ;
2011-07-02 22:56:22 -07:00
dev_dbg ( & isci_host - > pdev - > dev ,
" %s: isci_device = %p \n " ,
__func__ , isci_device ) ;
if ( status ! = SCI_SUCCESS ) {
2011-03-03 18:01:43 -08:00
spin_lock_irq ( & isci_host - > scic_lock ) ;
2011-07-02 22:56:22 -07:00
isci_remote_device_deconstruct (
isci_host ,
isci_device
) ;
2011-03-03 18:01:43 -08:00
spin_unlock_irq ( & isci_host - > scic_lock ) ;
2011-07-02 22:56:22 -07:00
return - ENODEV ;
}
2011-03-04 12:10:29 -08:00
/* wait for the device ready callback. */
wait_for_device_start ( isci_host , isci_device ) ;
2011-07-02 22:56:22 -07:00
return 0 ;
}
/**
* isci_device_is_reset_pending ( ) - This function will check if there is any
* pending reset condition on the device .
* @ request : This parameter is the isci_device object .
*
* true if there is a reset pending for the device .
*/
bool isci_device_is_reset_pending (
struct isci_host * isci_host ,
struct isci_remote_device * isci_device )
{
struct isci_request * isci_request ;
struct isci_request * tmp_req ;
bool reset_is_pending = false ;
unsigned long flags ;
dev_dbg ( & isci_host - > pdev - > dev ,
" %s: isci_device = %p \n " , __func__ , isci_device ) ;
spin_lock_irqsave ( & isci_host - > scic_lock , flags ) ;
/* Check for reset on all pending requests. */
list_for_each_entry_safe ( isci_request , tmp_req ,
& isci_device - > reqs_in_process , dev_node ) {
dev_dbg ( & isci_host - > pdev - > dev ,
" %s: isci_device = %p request = %p \n " ,
__func__ , isci_device , isci_request ) ;
if ( isci_request - > ttype = = io_task ) {
struct sas_task * task = isci_request_access_task (
isci_request ) ;
2011-04-12 17:28:41 -07:00
spin_lock ( & task - > task_state_lock ) ;
2011-07-02 22:56:22 -07:00
if ( task - > task_state_flags & SAS_TASK_NEED_DEV_RESET )
reset_is_pending = true ;
2011-04-12 17:28:41 -07:00
spin_unlock ( & task - > task_state_lock ) ;
2011-07-02 22:56:22 -07:00
}
}
spin_unlock_irqrestore ( & isci_host - > scic_lock , flags ) ;
dev_dbg ( & isci_host - > pdev - > dev ,
" %s: isci_device = %p reset_is_pending = %d \n " ,
__func__ , isci_device , reset_is_pending ) ;
return reset_is_pending ;
}
/**
* isci_device_clear_reset_pending ( ) - This function will clear if any pending
* reset condition flags on the device .
* @ request : This parameter is the isci_device object .
*
* true if there is a reset pending for the device .
*/
2011-03-31 13:10:44 -07:00
void isci_device_clear_reset_pending ( struct isci_host * ihost , struct isci_remote_device * idev )
2011-07-02 22:56:22 -07:00
{
struct isci_request * isci_request ;
struct isci_request * tmp_req ;
unsigned long flags = 0 ;
2011-03-31 13:10:44 -07:00
dev_dbg ( & ihost - > pdev - > dev , " %s: idev=%p, ihost=%p \n " ,
__func__ , idev , ihost ) ;
2011-07-02 22:56:22 -07:00
2011-03-31 13:10:44 -07:00
spin_lock_irqsave ( & ihost - > scic_lock , flags ) ;
2011-07-02 22:56:22 -07:00
/* Clear reset pending on all pending requests. */
list_for_each_entry_safe ( isci_request , tmp_req ,
2011-03-31 13:10:44 -07:00
& idev - > reqs_in_process , dev_node ) {
dev_dbg ( & ihost - > pdev - > dev , " %s: idev = %p request = %p \n " ,
__func__ , idev , isci_request ) ;
2011-07-02 22:56:22 -07:00
if ( isci_request - > ttype = = io_task ) {
unsigned long flags2 ;
struct sas_task * task = isci_request_access_task (
isci_request ) ;
spin_lock_irqsave ( & task - > task_state_lock , flags2 ) ;
task - > task_state_flags & = ~ SAS_TASK_NEED_DEV_RESET ;
spin_unlock_irqrestore ( & task - > task_state_lock , flags2 ) ;
}
}
2011-03-31 13:10:44 -07:00
spin_unlock_irqrestore ( & ihost - > scic_lock , flags ) ;
2011-07-02 22:56:22 -07:00
}
/**
* isci_remote_device_change_state ( ) - This function gets the status of the
* remote_device object .
* @ isci_device : This parameter points to the isci_remote_device object
*
* status of the object as a isci_status enum .
*/
void isci_remote_device_change_state (
struct isci_remote_device * isci_device ,
enum isci_status status )
{
unsigned long flags ;
spin_lock_irqsave ( & isci_device - > state_lock , flags ) ;
isci_device - > status = status ;
spin_unlock_irqrestore ( & isci_device - > state_lock , flags ) ;
}