Commit 4393aa4e authored by Dan Williams's avatar Dan Williams

isci: fix fragile/conditional isci_host lookups

A domain_device can always reference back to ->lldd_ha unlike local lldd
structures.  Fix up cases where the driver uses local objects to look up the
isci_host.  This also changes the calling conventions of some routines to
expect a valid isci_host parameter rather than re-lookup the pointer on entry.

Incidentally cleans up some macros that are longer to type than the open-coded
equivalent:
  isci_host_from_sas_ha
  isci_dev_from_domain_dev
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 037afc78
...@@ -129,7 +129,7 @@ void isci_host_start_complete(struct isci_host *ihost, enum sci_status completio ...@@ -129,7 +129,7 @@ void isci_host_start_complete(struct isci_host *ihost, enum sci_status completio
int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time) int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time)
{ {
struct isci_host *ihost = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost)); struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha;
if (test_bit(IHOST_START_PENDING, &ihost->flags)) if (test_bit(IHOST_START_PENDING, &ihost->flags))
return 0; return 0;
...@@ -149,7 +149,7 @@ int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time) ...@@ -149,7 +149,7 @@ int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time)
void isci_host_scan_start(struct Scsi_Host *shost) void isci_host_scan_start(struct Scsi_Host *shost)
{ {
struct isci_host *ihost = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost)); struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha;
struct scic_sds_controller *scic = ihost->core_controller; struct scic_sds_controller *scic = ihost->core_controller;
unsigned long tmo = scic_controller_get_suggested_start_timeout(scic); unsigned long tmo = scic_controller_get_suggested_start_timeout(scic);
......
...@@ -233,15 +233,10 @@ static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_rem ...@@ -233,15 +233,10 @@ static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_rem
wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags)); wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags));
} }
/** static inline struct isci_host *dev_to_ihost(struct domain_device *dev)
* isci_host_from_sas_ha() - This accessor retrieves the isci_host object {
* reference from the Linux sas_ha_struct reference. return dev->port->ha->lldd_ha;
* @ha_struct,: This parameter points to the Linux sas_ha_struct object }
*
* A reference to the associated isci_host structure.
*/
#define isci_host_from_sas_ha(ha_struct) \
((struct isci_host *)(ha_struct)->lldd_ha)
/** /**
* isci_host_scan_finished() - * isci_host_scan_finished() -
......
...@@ -163,7 +163,7 @@ int isci_phy_control(struct asd_sas_phy *sas_phy, ...@@ -163,7 +163,7 @@ int isci_phy_control(struct asd_sas_phy *sas_phy,
return -ENODEV; return -ENODEV;
/* Perform the port reset. */ /* Perform the port reset. */
ret = isci_port_perform_hard_reset(iport, iphy); ret = isci_port_perform_hard_reset(ihost, iport, iphy);
break; break;
......
...@@ -400,55 +400,43 @@ void isci_port_hard_reset_complete(struct isci_port *isci_port, ...@@ -400,55 +400,43 @@ void isci_port_hard_reset_complete(struct isci_port *isci_port,
complete_all(&isci_port->hard_reset_complete); complete_all(&isci_port->hard_reset_complete);
} }
/**
* isci_port_perform_hard_reset() - This function is one of the SAS Domain int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
* Template functions. This is a phy management function. struct isci_phy *iphy)
* @isci_port:
* @isci_phy:
*
* status, TMF_RESP_FUNC_COMPLETE indicates success.
*/
int isci_port_perform_hard_reset(
struct isci_port *isci_port,
struct isci_phy *isci_phy)
{ {
unsigned long flags;
enum sci_status status; enum sci_status status;
int ret = TMF_RESP_FUNC_COMPLETE; int ret = TMF_RESP_FUNC_COMPLETE;
unsigned long flags;
dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n",
__func__, iport);
dev_dbg(&isci_port->isci_host->pdev->dev, init_completion(&iport->hard_reset_complete);
"%s: isci_port = %p\n",
__func__, isci_port);
BUG_ON(isci_port == NULL);
init_completion(&isci_port->hard_reset_complete);
spin_lock_irqsave(&isci_port->isci_host->scic_lock, flags); spin_lock_irqsave(&ihost->scic_lock, flags);
#define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT #define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT
status = scic_port_hard_reset(isci_port->sci_port_handle, status = scic_port_hard_reset(iport->sci_port_handle,
ISCI_PORT_RESET_TIMEOUT); ISCI_PORT_RESET_TIMEOUT);
spin_unlock_irqrestore(&isci_port->isci_host->scic_lock, flags); spin_unlock_irqrestore(&ihost->scic_lock, flags);
if (status == SCI_SUCCESS) { if (status == SCI_SUCCESS) {
wait_for_completion(&isci_port->hard_reset_complete); wait_for_completion(&iport->hard_reset_complete);
dev_dbg(&isci_port->isci_host->pdev->dev, dev_dbg(&ihost->pdev->dev,
"%s: isci_port = %p; hard reset completion\n", "%s: iport = %p; hard reset completion\n",
__func__, isci_port); __func__, iport);
if (isci_port->hard_reset_status != SCI_SUCCESS) if (iport->hard_reset_status != SCI_SUCCESS)
ret = TMF_RESP_FUNC_FAILED; ret = TMF_RESP_FUNC_FAILED;
} else { } else {
ret = TMF_RESP_FUNC_FAILED; ret = TMF_RESP_FUNC_FAILED;
dev_err(&isci_port->isci_host->pdev->dev, dev_err(&ihost->pdev->dev,
"%s: isci_port = %p; scic_port_hard_reset call" "%s: iport = %p; scic_port_hard_reset call"
" failed 0x%x\n", " failed 0x%x\n",
__func__, isci_port, status); __func__, iport, status);
} }
...@@ -456,19 +444,12 @@ int isci_port_perform_hard_reset( ...@@ -456,19 +444,12 @@ int isci_port_perform_hard_reset(
* the same as link failures on all phys in the port. * the same as link failures on all phys in the port.
*/ */
if (ret != TMF_RESP_FUNC_COMPLETE) { if (ret != TMF_RESP_FUNC_COMPLETE) {
BUG_ON(isci_port->isci_host == NULL); dev_err(&ihost->pdev->dev,
"%s: iport = %p; hard reset failed "
dev_err(&isci_port->isci_host->pdev->dev,
"%s: isci_port = %p; hard reset failed "
"(0x%x) - sending link down to libsas for phy %p\n", "(0x%x) - sending link down to libsas for phy %p\n",
__func__, __func__, iport, iport->hard_reset_status, iphy);
isci_port,
isci_port->hard_reset_status, isci_port_link_down(ihost, iphy, iport);
isci_phy);
isci_port_link_down(isci_port->isci_host,
isci_phy,
isci_port);
} }
return ret; return ret;
...@@ -491,8 +472,7 @@ void isci_port_invalid_link_up(struct scic_sds_controller *scic, ...@@ -491,8 +472,7 @@ void isci_port_invalid_link_up(struct scic_sds_controller *scic,
struct scic_sds_port *sci_port, struct scic_sds_port *sci_port,
struct scic_sds_phy *phy) struct scic_sds_phy *phy)
{ {
struct isci_host *ihost = struct isci_host *ihost = sci_object_get_association(scic);
(struct isci_host *)sci_object_get_association(scic);
dev_warn(&ihost->pdev->dev, "Invalid link up!\n"); dev_warn(&ihost->pdev->dev, "Invalid link up!\n");
} }
......
...@@ -143,9 +143,8 @@ void isci_port_hard_reset_complete( ...@@ -143,9 +143,8 @@ void isci_port_hard_reset_complete(
struct isci_port *isci_port, struct isci_port *isci_port,
enum sci_status completion_status); enum sci_status completion_status);
int isci_port_perform_hard_reset( int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
struct isci_port *isci_port_ptr, struct isci_phy *iphy);
struct isci_phy *isci_phy_ptr);
void isci_port_invalid_link_up( void isci_port_invalid_link_up(
struct scic_sds_controller *scic, struct scic_sds_controller *scic,
......
...@@ -218,33 +218,20 @@ static enum sci_status isci_remote_device_construct( ...@@ -218,33 +218,20 @@ static enum sci_status isci_remote_device_construct(
return status; return status;
} }
void isci_remote_device_nuke_requests(struct isci_host *ihost, struct isci_remote_device *idev)
/**
* isci_remote_device_nuke_requests() - This function terminates all requests
* for a given remote device.
* @isci_device: This parameter specifies the remote device
*
*/
void isci_remote_device_nuke_requests(
struct isci_remote_device *isci_device)
{ {
DECLARE_COMPLETION_ONSTACK(aborted_task_completion); DECLARE_COMPLETION_ONSTACK(aborted_task_completion);
struct isci_host *isci_host;
isci_host = isci_device->isci_port->isci_host; dev_dbg(&ihost->pdev->dev,
"%s: idev = %p\n", __func__, idev);
dev_dbg(&isci_host->pdev->dev,
"%s: isci_device = %p\n", __func__, isci_device);
/* Cleanup all requests pending for this device. */ /* Cleanup all requests pending for this device. */
isci_terminate_pending_requests(isci_host, isci_device, terminating); isci_terminate_pending_requests(ihost, idev, terminating);
dev_dbg(&isci_host->pdev->dev, dev_dbg(&ihost->pdev->dev,
"%s: isci_device = %p, done\n", __func__, isci_device); "%s: idev = %p, done\n", __func__, idev);
} }
/** /**
* This function builds the isci_remote_device when a libsas dev_found message * This function builds the isci_remote_device when a libsas dev_found message
* is received. * is received.
...@@ -380,7 +367,7 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem ...@@ -380,7 +367,7 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem
isci_remote_device_change_state(idev, isci_stopping); isci_remote_device_change_state(idev, isci_stopping);
/* Kill all outstanding requests. */ /* Kill all outstanding requests. */
isci_remote_device_nuke_requests(idev); isci_remote_device_nuke_requests(ihost, idev);
set_bit(IDEV_STOP_PENDING, &idev->flags); set_bit(IDEV_STOP_PENDING, &idev->flags);
...@@ -409,7 +396,7 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem ...@@ -409,7 +396,7 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem
*/ */
void isci_remote_device_gone(struct domain_device *dev) void isci_remote_device_gone(struct domain_device *dev)
{ {
struct isci_host *ihost = dev->port->ha->lldd_ha; struct isci_host *ihost = dev_to_ihost(dev);
struct isci_remote_device *idev = dev->lldd_dev; struct isci_remote_device *idev = dev->lldd_dev;
dev_dbg(&ihost->pdev->dev, dev_dbg(&ihost->pdev->dev,
...@@ -431,7 +418,7 @@ void isci_remote_device_gone(struct domain_device *dev) ...@@ -431,7 +418,7 @@ void isci_remote_device_gone(struct domain_device *dev)
*/ */
int isci_remote_device_found(struct domain_device *domain_dev) int isci_remote_device_found(struct domain_device *domain_dev)
{ {
struct isci_host *isci_host; struct isci_host *isci_host = dev_to_ihost(domain_dev);
struct isci_port *isci_port; struct isci_port *isci_port;
struct isci_phy *isci_phy; struct isci_phy *isci_phy;
struct asd_sas_port *sas_port; struct asd_sas_port *sas_port;
...@@ -439,8 +426,6 @@ int isci_remote_device_found(struct domain_device *domain_dev) ...@@ -439,8 +426,6 @@ int isci_remote_device_found(struct domain_device *domain_dev)
struct isci_remote_device *isci_device; struct isci_remote_device *isci_device;
enum sci_status status; enum sci_status status;
isci_host = isci_host_from_sas_ha(domain_dev->port->ha);
dev_dbg(&isci_host->pdev->dev, dev_dbg(&isci_host->pdev->dev,
"%s: domain_device = %p\n", __func__, domain_dev); "%s: domain_device = %p\n", __func__, domain_dev);
...@@ -556,41 +541,22 @@ bool isci_device_is_reset_pending( ...@@ -556,41 +541,22 @@ bool isci_device_is_reset_pending(
* *
* true if there is a reset pending for the device. * true if there is a reset pending for the device.
*/ */
void isci_device_clear_reset_pending(struct isci_remote_device *isci_device) void isci_device_clear_reset_pending(struct isci_host *ihost, struct isci_remote_device *idev)
{ {
struct isci_request *isci_request; struct isci_request *isci_request;
struct isci_request *tmp_req; struct isci_request *tmp_req;
struct isci_host *isci_host = NULL;
unsigned long flags = 0; unsigned long flags = 0;
/* FIXME more port gone confusion, and this time it makes the dev_dbg(&ihost->pdev->dev, "%s: idev=%p, ihost=%p\n",
* locking "fun" __func__, idev, ihost);
*/
if (isci_device->isci_port != NULL)
isci_host = isci_device->isci_port->isci_host;
/*
* FIXME when the isci_host gets sorted out
* use dev_dbg()
*/
pr_debug("%s: isci_device=%p, isci_host=%p\n",
__func__, isci_device, isci_host);
if (isci_host != NULL) spin_lock_irqsave(&ihost->scic_lock, flags);
spin_lock_irqsave(&isci_host->scic_lock, flags);
else
pr_err("%s: isci_device %p; isci_host == NULL!\n",
__func__, isci_device);
/* Clear reset pending on all pending requests. */ /* Clear reset pending on all pending requests. */
list_for_each_entry_safe(isci_request, tmp_req, list_for_each_entry_safe(isci_request, tmp_req,
&isci_device->reqs_in_process, dev_node) { &idev->reqs_in_process, dev_node) {
/* dev_dbg(&ihost->pdev->dev, "%s: idev = %p request = %p\n",
* FIXME when the conditional spinlock is gone __func__, idev, isci_request);
* change to dev_dbg()
*/
pr_debug("%s: isci_device = %p request = %p\n",
__func__, isci_device, isci_request);
if (isci_request->ttype == io_task) { if (isci_request->ttype == io_task) {
...@@ -603,9 +569,7 @@ void isci_device_clear_reset_pending(struct isci_remote_device *isci_device) ...@@ -603,9 +569,7 @@ void isci_device_clear_reset_pending(struct isci_remote_device *isci_device)
spin_unlock_irqrestore(&task->task_state_lock, flags2); spin_unlock_irqrestore(&task->task_state_lock, flags2);
} }
} }
spin_unlock_irqrestore(&ihost->scic_lock, flags);
if (isci_host != NULL)
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
} }
/** /**
......
...@@ -78,59 +78,29 @@ static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_devic ...@@ -78,59 +78,29 @@ static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_devic
return (struct scic_sds_remote_device *) &idev[1]; return (struct scic_sds_remote_device *) &idev[1];
} }
#define to_isci_remote_device(p) \
container_of(p, struct isci_remote_device, sci_remote_device);
#define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000 #define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000
void isci_remote_device_start_complete(struct isci_host *ihost,
/** struct isci_remote_device *idev,
* isci_dev_from_domain_dev() - This accessor retrieves the remote_device enum sci_status);
* object reference from the Linux domain_device reference. void isci_remote_device_stop_complete(struct isci_host *ihost,
* @domdev,: This parameter points to the Linux domain_device object . struct isci_remote_device *idev,
* enum sci_status);
* A reference to the associated isci remote device.
*/
#define isci_dev_from_domain_dev(domdev) \
((struct isci_remote_device *)(domdev)->lldd_dev)
void isci_remote_device_start_complete(
struct isci_host *,
struct isci_remote_device *,
enum sci_status);
void isci_remote_device_stop_complete(
struct isci_host *,
struct isci_remote_device *,
enum sci_status);
enum sci_status isci_remote_device_stop(struct isci_host *ihost, enum sci_status isci_remote_device_stop(struct isci_host *ihost,
struct isci_remote_device *idev); struct isci_remote_device *idev);
void isci_remote_device_nuke_requests( void isci_remote_device_nuke_requests(struct isci_host *ihost,
struct isci_remote_device *isci_device); struct isci_remote_device *idev);
void isci_remote_device_ready(struct isci_host *ihost, void isci_remote_device_ready(struct isci_host *ihost,
struct isci_remote_device *idev); struct isci_remote_device *idev);
void isci_remote_device_not_ready(struct isci_host *ihost, void isci_remote_device_not_ready(struct isci_host *ihost,
struct isci_remote_device *idev, u32 reason); struct isci_remote_device *idev, u32 reason);
void isci_remote_device_gone(struct domain_device *domain_dev);
void isci_remote_device_gone( int isci_remote_device_found(struct domain_device *domain_dev);
struct domain_device *domain_dev); bool isci_device_is_reset_pending(struct isci_host *ihost,
struct isci_remote_device *idev);
int isci_remote_device_found( void isci_device_clear_reset_pending(struct isci_host *ihost,
struct domain_device *domain_dev); struct isci_remote_device *idev);
void isci_remote_device_change_state(struct isci_remote_device *idev,
bool isci_device_is_reset_pending( enum isci_status status);
struct isci_host *isci_host,
struct isci_remote_device *isci_device);
void isci_device_clear_reset_pending(
struct isci_remote_device *isci_device);
void isci_remote_device_change_state(
struct isci_remote_device *isci_device,
enum isci_status status);
#endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */ #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */
...@@ -379,7 +379,7 @@ int isci_request_execute( ...@@ -379,7 +379,7 @@ int isci_request_execute(
struct isci_request *request; struct isci_request *request;
unsigned long flags; unsigned long flags;
isci_device = isci_dev_from_domain_dev(task->dev); isci_device = task->dev->lldd_dev;
sci_device = to_sci_dev(isci_device); sci_device = to_sci_dev(isci_device);
/* do common allocation and init of request object. */ /* do common allocation and init of request object. */
......
...@@ -146,7 +146,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task, ...@@ -146,7 +146,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,
*/ */
int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
{ {
struct isci_host *ihost = task->dev->port->ha->lldd_ha; struct isci_host *ihost = dev_to_ihost(task->dev);
struct isci_request *request = NULL; struct isci_request *request = NULL;
struct isci_remote_device *device; struct isci_remote_device *device;
unsigned long flags; unsigned long flags;
...@@ -169,7 +169,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) ...@@ -169,7 +169,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
"task = %p, num = %d; dev = %p; cmd = %p\n", "task = %p, num = %d; dev = %p; cmd = %p\n",
task, num, task->dev, task->uldd_task); task, num, task->dev, task->uldd_task);
device = isci_dev_from_domain_dev(task->dev); device = task->dev->lldd_dev;
if (device) if (device)
device_status = device->status; device_status = device->status;
...@@ -593,7 +593,6 @@ static void isci_task_build_abort_task_tmf( ...@@ -593,7 +593,6 @@ static void isci_task_build_abort_task_tmf(
static struct isci_request *isci_task_get_request_from_task( static struct isci_request *isci_task_get_request_from_task(
struct sas_task *task, struct sas_task *task,
struct isci_host **isci_host,
struct isci_remote_device **isci_device) struct isci_remote_device **isci_device)
{ {
...@@ -609,9 +608,6 @@ static struct isci_request *isci_task_get_request_from_task( ...@@ -609,9 +608,6 @@ static struct isci_request *isci_task_get_request_from_task(
(task->task_state_flags & SAS_TASK_AT_INITIATOR) && (task->task_state_flags & SAS_TASK_AT_INITIATOR) &&
(request != NULL)) { (request != NULL)) {
if (isci_host != NULL)
*isci_host = request->isci_host;
if (isci_device != NULL) if (isci_device != NULL)
*isci_device = request->isci_device; *isci_device = request->isci_device;
} }
...@@ -1027,26 +1023,17 @@ static int isci_task_send_lu_reset_sas( ...@@ -1027,26 +1023,17 @@ static int isci_task_send_lu_reset_sas(
* *
* status, zero indicates success. * status, zero indicates success.
*/ */
int isci_task_lu_reset( int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
struct domain_device *domain_device,
u8 *lun)
{ {
struct isci_host *isci_host = NULL; struct isci_host *isci_host = dev_to_ihost(domain_device);
struct isci_remote_device *isci_device = NULL; struct isci_remote_device *isci_device = NULL;
int ret; int ret;
bool device_stopping = false; bool device_stopping = false;
if (domain_device == NULL) { isci_device = domain_device->lldd_dev;
pr_warn("%s: domain_device == NULL\n", __func__);
return TMF_RESP_FUNC_FAILED;
}
isci_device = isci_dev_from_domain_dev(domain_device);
if (domain_device->port != NULL)
isci_host = isci_host_from_sas_ha(domain_device->port->ha);
pr_debug("%s: domain_device=%p, isci_host=%p; isci_device=%p\n", dev_dbg(&isci_host->pdev->dev,
"%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
__func__, domain_device, isci_host, isci_device); __func__, domain_device, isci_host, isci_device);
if (isci_device != NULL) if (isci_device != NULL)
...@@ -1057,24 +1044,18 @@ int isci_task_lu_reset( ...@@ -1057,24 +1044,18 @@ int isci_task_lu_reset(
* device's list, fail this LUN reset request in order to * device's list, fail this LUN reset request in order to
* escalate to the device reset. * escalate to the device reset.
*/ */
if ((isci_device == NULL) || if (!isci_device || device_stopping ||
(isci_host == NULL) || isci_device_is_reset_pending(isci_host, isci_device)) {
((isci_host != NULL) &&
(isci_device != NULL) &&
(device_stopping ||
(isci_device_is_reset_pending(isci_host, isci_device))))) {
dev_warn(&isci_host->pdev->dev, dev_warn(&isci_host->pdev->dev,
"%s: No dev (%p), no host (%p), or " "%s: No dev (%p), or "
"RESET PENDING: domain_device=%p\n", "RESET PENDING: domain_device=%p\n",
__func__, isci_device, isci_host, domain_device); __func__, isci_device, domain_device);
return TMF_RESP_FUNC_FAILED; return TMF_RESP_FUNC_FAILED;
} }
/* Send the task management part of the reset. */ /* Send the task management part of the reset. */
if (sas_protocol_ata(domain_device->tproto)) { if (sas_protocol_ata(domain_device->tproto)) {
ret = isci_task_send_lu_reset_sata( ret = isci_task_send_lu_reset_sata(isci_host, isci_device, lun);
isci_host, isci_device, lun
);
} else } else
ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun);
...@@ -1173,11 +1154,11 @@ static void isci_abort_task_process_cb( ...@@ -1173,11 +1154,11 @@ static void isci_abort_task_process_cb(
*/ */
int isci_task_abort_task(struct sas_task *task) int isci_task_abort_task(struct sas_task *task)
{ {
struct isci_host *isci_host = dev_to_ihost(task->dev);
DECLARE_COMPLETION_ONSTACK(aborted_io_completion); DECLARE_COMPLETION_ONSTACK(aborted_io_completion);
struct isci_request *old_request = NULL; struct isci_request *old_request = NULL;
enum isci_request_status old_state; enum isci_request_status old_state;
struct isci_remote_device *isci_device = NULL; struct isci_remote_device *isci_device = NULL;
struct isci_host *isci_host = NULL;
struct isci_tmf tmf; struct isci_tmf tmf;
int ret = TMF_RESP_FUNC_FAILED; int ret = TMF_RESP_FUNC_FAILED;
unsigned long flags; unsigned long flags;
...@@ -1189,8 +1170,7 @@ int isci_task_abort_task(struct sas_task *task) ...@@ -1189,8 +1170,7 @@ int isci_task_abort_task(struct sas_task *task)
* in the device, because tasks driving resets may land here * in the device, because tasks driving resets may land here
* after completion in the core. * after completion in the core.
*/ */
old_request = isci_task_get_request_from_task(task, &isci_host, old_request = isci_task_get_request_from_task(task, &isci_device);
&isci_device);
dev_dbg(&isci_host->pdev->dev, dev_dbg(&isci_host->pdev->dev,
"%s: task = %p\n", __func__, task); "%s: task = %p\n", __func__, task);
...@@ -1610,37 +1590,29 @@ u32 isci_task_ssp_request_get_response_data_length( ...@@ -1610,37 +1590,29 @@ u32 isci_task_ssp_request_get_response_data_length(
*/ */
int isci_bus_reset_handler(struct scsi_cmnd *cmd) int isci_bus_reset_handler(struct scsi_cmnd *cmd)
{ {
struct domain_device *dev = cmd_to_domain_dev(cmd);
struct isci_host *isci_host = dev_to_ihost(dev);
unsigned long flags = 0; unsigned long flags = 0;
struct isci_host *isci_host = NULL;
enum sci_status status; enum sci_status status;
int base_status; int base_status;
struct isci_remote_device *isci_dev struct isci_remote_device *isci_dev = dev->lldd_dev;
= isci_dev_from_domain_dev(
sdev_to_domain_dev(cmd->device));
dev_dbg(&cmd->device->sdev_gendev, dev_dbg(&isci_host->pdev->dev,
"%s: cmd %p, isci_dev %p\n", "%s: cmd %p, isci_dev %p\n",
__func__, cmd, isci_dev); __func__, cmd, isci_dev);
if (!isci_dev) { if (!isci_dev) {
dev_warn(&cmd->device->sdev_gendev, dev_warn(&isci_host->pdev->dev,
"%s: isci_dev is GONE!\n", "%s: isci_dev is GONE!\n",
__func__); __func__);
return TMF_RESP_FUNC_COMPLETE; /* Nothing to reset. */ return TMF_RESP_FUNC_COMPLETE; /* Nothing to reset. */
} }
if (isci_dev->isci_port != NULL) spin_lock_irqsave(&isci_host->scic_lock, flags);
isci_host = isci_dev->isci_port->isci_host;
if (isci_host != NULL)
spin_lock_irqsave(&isci_host->scic_lock, flags);
status = scic_remote_device_reset(to_sci_dev(isci_dev)); status = scic_remote_device_reset(to_sci_dev(isci_dev));
if (status != SCI_SUCCESS) { if (status != SCI_SUCCESS) {
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
if (isci_host != NULL)
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
scmd_printk(KERN_WARNING, cmd, scmd_printk(KERN_WARNING, cmd,
"%s: scic_remote_device_reset(%p) returned %d!\n", "%s: scic_remote_device_reset(%p) returned %d!\n",
...@@ -1648,14 +1620,13 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) ...@@ -1648,14 +1620,13 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
return TMF_RESP_FUNC_FAILED; return TMF_RESP_FUNC_FAILED;
} }
if (isci_host != NULL) spin_unlock_irqrestore(&isci_host->scic_lock, flags);
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
/* Make sure all pending requests are able to be fully terminated. */ /* Make sure all pending requests are able to be fully terminated. */
isci_device_clear_reset_pending(isci_dev); isci_device_clear_reset_pending(isci_host, isci_dev);
/* Terminate in-progress I/O now. */ /* Terminate in-progress I/O now. */
isci_remote_device_nuke_requests(isci_dev); isci_remote_device_nuke_requests(isci_host, isci_dev);
/* Call into the libsas default handler (which calls sas_phy_reset). */ /* Call into the libsas default handler (which calls sas_phy_reset). */
base_status = sas_eh_bus_reset_handler(cmd); base_status = sas_eh_bus_reset_handler(cmd);
...@@ -1672,13 +1643,9 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) ...@@ -1672,13 +1643,9 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
} }
/* WHAT TO DO HERE IF sas_phy_reset FAILS? */ /* WHAT TO DO HERE IF sas_phy_reset FAILS? */
spin_lock_irqsave(&isci_host->scic_lock, flags);
if (isci_host != NULL)
spin_lock_irqsave(&isci_host->scic_lock, flags);
status = scic_remote_device_reset_complete(to_sci_dev(isci_dev)); status = scic_remote_device_reset_complete(to_sci_dev(isci_dev));
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
if (isci_host != NULL)
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
if (status != SCI_SUCCESS) { if (status != SCI_SUCCESS) {
scmd_printk(KERN_WARNING, cmd, scmd_printk(KERN_WARNING, cmd,
...@@ -1688,7 +1655,7 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) ...@@ -1688,7 +1655,7 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
} }
/* WHAT TO DO HERE IF scic_remote_device_reset_complete FAILS? */ /* WHAT TO DO HERE IF scic_remote_device_reset_complete FAILS? */
dev_dbg(&cmd->device->sdev_gendev, dev_dbg(&isci_host->pdev->dev,
"%s: cmd %p, isci_dev %p complete.\n", "%s: cmd %p, isci_dev %p complete.\n",
__func__, cmd, isci_dev); __func__, cmd, isci_dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment