isci: cleanup request allocation
Rather than return an error code and update a pointer that was passed by reference just return the request object directly (or null if allocation failed). Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
994a9303d3
commit
0d0cf14c9b
|
@ -3510,172 +3510,110 @@ static enum sci_status isci_io_request_build(
|
||||||
return SCI_SUCCESS;
|
return SCI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static struct isci_request *isci_request_alloc_core(struct isci_host *ihost,
|
||||||
* isci_request_alloc_core() - This function gets the request object from the
|
struct isci_remote_device *idev,
|
||||||
* isci_host dma cache.
|
gfp_t gfp_flags)
|
||||||
* @isci_host: This parameter specifies the ISCI host object
|
|
||||||
* @isci_request: This parameter will contain the pointer to the new
|
|
||||||
* isci_request object.
|
|
||||||
* @isci_device: This parameter is the pointer to the isci remote device object
|
|
||||||
* that is the destination for this request.
|
|
||||||
* @gfp_flags: This parameter specifies the os allocation flags.
|
|
||||||
*
|
|
||||||
* SCI_SUCCESS on successfull completion, or specific failure code.
|
|
||||||
*/
|
|
||||||
static int isci_request_alloc_core(
|
|
||||||
struct isci_host *isci_host,
|
|
||||||
struct isci_request **isci_request,
|
|
||||||
struct isci_remote_device *isci_device,
|
|
||||||
gfp_t gfp_flags)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
dma_addr_t handle;
|
dma_addr_t handle;
|
||||||
struct isci_request *request;
|
struct isci_request *ireq;
|
||||||
|
|
||||||
|
ireq = dma_pool_alloc(ihost->dma_pool, gfp_flags, &handle);
|
||||||
/* get pointer to dma memory. This actually points
|
if (!ireq) {
|
||||||
* to both the isci_remote_device object and the
|
dev_warn(&ihost->pdev->dev,
|
||||||
* sci object. The isci object is at the beginning
|
|
||||||
* of the memory allocated here.
|
|
||||||
*/
|
|
||||||
request = dma_pool_alloc(isci_host->dma_pool, gfp_flags, &handle);
|
|
||||||
if (!request) {
|
|
||||||
dev_warn(&isci_host->pdev->dev,
|
|
||||||
"%s: dma_pool_alloc returned NULL\n", __func__);
|
"%s: dma_pool_alloc returned NULL\n", __func__);
|
||||||
return -ENOMEM;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize the request object. */
|
/* initialize the request object. */
|
||||||
spin_lock_init(&request->state_lock);
|
spin_lock_init(&ireq->state_lock);
|
||||||
request->request_daddr = handle;
|
ireq->request_daddr = handle;
|
||||||
request->isci_host = isci_host;
|
ireq->isci_host = ihost;
|
||||||
request->isci_device = isci_device;
|
ireq->isci_device = idev;
|
||||||
request->io_request_completion = NULL;
|
ireq->io_request_completion = NULL;
|
||||||
request->terminated = false;
|
ireq->terminated = false;
|
||||||
|
|
||||||
request->num_sg_entries = 0;
|
ireq->num_sg_entries = 0;
|
||||||
|
|
||||||
request->complete_in_target = false;
|
ireq->complete_in_target = false;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&request->completed_node);
|
INIT_LIST_HEAD(&ireq->completed_node);
|
||||||
INIT_LIST_HEAD(&request->dev_node);
|
INIT_LIST_HEAD(&ireq->dev_node);
|
||||||
|
|
||||||
*isci_request = request;
|
isci_request_change_state(ireq, allocated);
|
||||||
isci_request_change_state(request, allocated);
|
|
||||||
|
|
||||||
return ret;
|
return ireq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isci_request_alloc_io(
|
static struct isci_request *isci_request_alloc_io(struct isci_host *ihost,
|
||||||
struct isci_host *isci_host,
|
struct sas_task *task,
|
||||||
struct sas_task *task,
|
struct isci_remote_device *idev,
|
||||||
struct isci_request **isci_request,
|
gfp_t gfp_flags)
|
||||||
struct isci_remote_device *isci_device,
|
|
||||||
gfp_t gfp_flags)
|
|
||||||
{
|
{
|
||||||
int retval = isci_request_alloc_core(isci_host, isci_request,
|
struct isci_request *ireq;
|
||||||
isci_device, gfp_flags);
|
|
||||||
|
|
||||||
if (!retval) {
|
ireq = isci_request_alloc_core(ihost, idev, gfp_flags);
|
||||||
(*isci_request)->ttype_ptr.io_task_ptr = task;
|
if (ireq) {
|
||||||
(*isci_request)->ttype = io_task;
|
ireq->ttype_ptr.io_task_ptr = task;
|
||||||
|
ireq->ttype = io_task;
|
||||||
task->lldd_task = *isci_request;
|
task->lldd_task = ireq;
|
||||||
}
|
}
|
||||||
return retval;
|
return ireq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost,
|
||||||
* isci_request_alloc_tmf() - This function gets the request object from the
|
struct isci_tmf *isci_tmf,
|
||||||
* isci_host dma cache and initializes the relevant fields as a sas_task.
|
struct isci_remote_device *idev,
|
||||||
* @isci_host: This parameter specifies the ISCI host object
|
gfp_t gfp_flags)
|
||||||
* @sas_task: This parameter is the task struct from the upper layer driver.
|
|
||||||
* @isci_request: This parameter will contain the pointer to the new
|
|
||||||
* isci_request object.
|
|
||||||
* @isci_device: This parameter is the pointer to the isci remote device object
|
|
||||||
* that is the destination for this request.
|
|
||||||
* @gfp_flags: This parameter specifies the os allocation flags.
|
|
||||||
*
|
|
||||||
* SCI_SUCCESS on successfull completion, or specific failure code.
|
|
||||||
*/
|
|
||||||
int isci_request_alloc_tmf(
|
|
||||||
struct isci_host *isci_host,
|
|
||||||
struct isci_tmf *isci_tmf,
|
|
||||||
struct isci_request **isci_request,
|
|
||||||
struct isci_remote_device *isci_device,
|
|
||||||
gfp_t gfp_flags)
|
|
||||||
{
|
{
|
||||||
int retval = isci_request_alloc_core(isci_host, isci_request,
|
struct isci_request *ireq;
|
||||||
isci_device, gfp_flags);
|
|
||||||
|
|
||||||
if (!retval) {
|
ireq = isci_request_alloc_core(ihost, idev, gfp_flags);
|
||||||
|
if (ireq) {
|
||||||
(*isci_request)->ttype_ptr.tmf_task_ptr = isci_tmf;
|
ireq->ttype_ptr.tmf_task_ptr = isci_tmf;
|
||||||
(*isci_request)->ttype = tmf_task;
|
ireq->ttype = tmf_task;
|
||||||
}
|
}
|
||||||
return retval;
|
return ireq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int isci_request_execute(struct isci_host *ihost, struct sas_task *task,
|
||||||
* isci_request_execute() - This function allocates the isci_request object,
|
gfp_t gfp_flags)
|
||||||
* all fills in some common fields.
|
|
||||||
* @isci_host: This parameter specifies the ISCI host object
|
|
||||||
* @sas_task: This parameter is the task struct from the upper layer driver.
|
|
||||||
* @isci_request: This parameter will contain the pointer to the new
|
|
||||||
* isci_request object.
|
|
||||||
* @gfp_flags: This parameter specifies the os allocation flags.
|
|
||||||
*
|
|
||||||
* SCI_SUCCESS on successfull completion, or specific failure code.
|
|
||||||
*/
|
|
||||||
int isci_request_execute(
|
|
||||||
struct isci_host *isci_host,
|
|
||||||
struct sas_task *task,
|
|
||||||
struct isci_request **isci_request,
|
|
||||||
gfp_t gfp_flags)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
struct scic_sds_remote_device *sci_device;
|
|
||||||
enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
|
enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
|
||||||
struct isci_remote_device *isci_device;
|
struct scic_sds_remote_device *sci_dev;
|
||||||
struct isci_request *request;
|
struct isci_remote_device *idev;
|
||||||
|
struct isci_request *ireq;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
isci_device = task->dev->lldd_dev;
|
idev = task->dev->lldd_dev;
|
||||||
sci_device = &isci_device->sci;
|
sci_dev = &idev->sci;
|
||||||
|
|
||||||
/* do common allocation and init of request object. */
|
/* do common allocation and init of request object. */
|
||||||
ret = isci_request_alloc_io(
|
ireq = isci_request_alloc_io(ihost, task, idev, gfp_flags);
|
||||||
isci_host,
|
if (!ireq)
|
||||||
task,
|
|
||||||
&request,
|
|
||||||
isci_device,
|
|
||||||
gfp_flags
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
status = isci_io_request_build(isci_host, request, isci_device);
|
status = isci_io_request_build(ihost, ireq, idev);
|
||||||
if (status != SCI_SUCCESS) {
|
if (status != SCI_SUCCESS) {
|
||||||
dev_warn(&isci_host->pdev->dev,
|
dev_warn(&ihost->pdev->dev,
|
||||||
"%s: request_construct failed - status = 0x%x\n",
|
"%s: request_construct failed - status = 0x%x\n",
|
||||||
__func__,
|
__func__,
|
||||||
status);
|
status);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&isci_host->scic_lock, flags);
|
spin_lock_irqsave(&ihost->scic_lock, flags);
|
||||||
|
|
||||||
/* send the request, let the core assign the IO TAG. */
|
/* send the request, let the core assign the IO TAG. */
|
||||||
status = scic_controller_start_io(&isci_host->sci, sci_device,
|
status = scic_controller_start_io(&ihost->sci, sci_dev,
|
||||||
&request->sci,
|
&ireq->sci,
|
||||||
SCI_CONTROLLER_INVALID_IO_TAG);
|
SCI_CONTROLLER_INVALID_IO_TAG);
|
||||||
if (status != SCI_SUCCESS &&
|
if (status != SCI_SUCCESS &&
|
||||||
status != SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
|
status != SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
|
||||||
dev_warn(&isci_host->pdev->dev,
|
dev_warn(&ihost->pdev->dev,
|
||||||
"%s: failed request start (0x%x)\n",
|
"%s: failed request start (0x%x)\n",
|
||||||
__func__, status);
|
__func__, status);
|
||||||
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
|
spin_unlock_irqrestore(&ihost->scic_lock, flags);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3687,21 +3625,21 @@ int isci_request_execute(
|
||||||
* Update it's status and add it to the list in the
|
* Update it's status and add it to the list in the
|
||||||
* remote device object.
|
* remote device object.
|
||||||
*/
|
*/
|
||||||
list_add(&request->dev_node, &isci_device->reqs_in_process);
|
list_add(&ireq->dev_node, &idev->reqs_in_process);
|
||||||
|
|
||||||
if (status == SCI_SUCCESS) {
|
if (status == SCI_SUCCESS) {
|
||||||
/* Save the tag for possible task mgmt later. */
|
/* Save the tag for possible task mgmt later. */
|
||||||
request->io_tag = request->sci.io_tag;
|
ireq->io_tag = ireq->sci.io_tag;
|
||||||
isci_request_change_state(request, started);
|
isci_request_change_state(ireq, started);
|
||||||
} else {
|
} else {
|
||||||
/* The request did not really start in the
|
/* The request did not really start in the
|
||||||
* hardware, so clear the request handle
|
* hardware, so clear the request handle
|
||||||
* here so no terminations will be done.
|
* here so no terminations will be done.
|
||||||
*/
|
*/
|
||||||
request->terminated = true;
|
ireq->terminated = true;
|
||||||
isci_request_change_state(request, completed);
|
isci_request_change_state(ireq, completed);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
|
spin_unlock_irqrestore(&ihost->scic_lock, flags);
|
||||||
|
|
||||||
if (status ==
|
if (status ==
|
||||||
SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
|
SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
|
||||||
|
@ -3716,7 +3654,7 @@ int isci_request_execute(
|
||||||
/* Cause this task to be scheduled in the SCSI error
|
/* Cause this task to be scheduled in the SCSI error
|
||||||
* handler thread.
|
* handler thread.
|
||||||
*/
|
*/
|
||||||
isci_execpath_callback(isci_host, task,
|
isci_execpath_callback(ihost, task,
|
||||||
sas_task_abort);
|
sas_task_abort);
|
||||||
|
|
||||||
/* Change the status, since we are holding
|
/* Change the status, since we are holding
|
||||||
|
@ -3729,11 +3667,10 @@ int isci_request_execute(
|
||||||
out:
|
out:
|
||||||
if (status != SCI_SUCCESS) {
|
if (status != SCI_SUCCESS) {
|
||||||
/* release dma memory on failure. */
|
/* release dma memory on failure. */
|
||||||
isci_request_free(isci_host, request);
|
isci_request_free(ihost, ireq);
|
||||||
request = NULL;
|
ireq = NULL;
|
||||||
ret = SCI_FAILURE;
|
ret = SCI_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*isci_request = request;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -679,16 +679,13 @@ static inline void isci_request_free(struct isci_host *isci_host,
|
||||||
|
|
||||||
#define isci_request_access_tmf(req) ((req)->ttype_ptr.tmf_task_ptr)
|
#define isci_request_access_tmf(req) ((req)->ttype_ptr.tmf_task_ptr)
|
||||||
|
|
||||||
int isci_request_alloc_tmf(struct isci_host *isci_host,
|
struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost,
|
||||||
struct isci_tmf *isci_tmf,
|
struct isci_tmf *isci_tmf,
|
||||||
struct isci_request **isci_request,
|
struct isci_remote_device *idev,
|
||||||
struct isci_remote_device *isci_device,
|
gfp_t gfp_flags);
|
||||||
gfp_t gfp_flags);
|
|
||||||
|
|
||||||
|
|
||||||
int isci_request_execute(struct isci_host *isci_host,
|
int isci_request_execute(struct isci_host *isci_host,
|
||||||
struct sas_task *task,
|
struct sas_task *task,
|
||||||
struct isci_request **request,
|
|
||||||
gfp_t gfp_flags);
|
gfp_t gfp_flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -146,7 +146,6 @@ 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 = dev_to_ihost(task->dev);
|
struct isci_host *ihost = dev_to_ihost(task->dev);
|
||||||
struct isci_request *request = NULL;
|
|
||||||
struct isci_remote_device *device;
|
struct isci_remote_device *device;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -226,8 +225,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
|
||||||
spin_unlock_irqrestore(&task->task_state_lock, flags);
|
spin_unlock_irqrestore(&task->task_state_lock, flags);
|
||||||
|
|
||||||
/* build and send the request. */
|
/* build and send the request. */
|
||||||
status = isci_request_execute(ihost, task, &request,
|
status = isci_request_execute(ihost, task, gfp_flags);
|
||||||
gfp_flags);
|
|
||||||
|
|
||||||
if (status != SCI_SUCCESS) {
|
if (status != SCI_SUCCESS) {
|
||||||
|
|
||||||
|
@ -254,54 +252,34 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct isci_request *isci_task_request_build(struct isci_host *ihost,
|
||||||
|
struct isci_tmf *isci_tmf)
|
||||||
/**
|
|
||||||
* isci_task_request_build() - This function builds the task request object.
|
|
||||||
* @isci_host: This parameter specifies the ISCI host object
|
|
||||||
* @request: This parameter points to the isci_request object allocated in the
|
|
||||||
* request construct function.
|
|
||||||
* @tmf: This parameter is the task management struct to be built
|
|
||||||
*
|
|
||||||
* SCI_SUCCESS on successfull completion, or specific failure code.
|
|
||||||
*/
|
|
||||||
static enum sci_status isci_task_request_build(
|
|
||||||
struct isci_host *isci_host,
|
|
||||||
struct isci_request **isci_request,
|
|
||||||
struct isci_tmf *isci_tmf)
|
|
||||||
{
|
{
|
||||||
struct scic_sds_remote_device *sci_device;
|
struct scic_sds_remote_device *sci_dev;
|
||||||
enum sci_status status = SCI_FAILURE;
|
enum sci_status status = SCI_FAILURE;
|
||||||
struct isci_request *request = NULL;
|
struct isci_request *ireq = NULL;
|
||||||
struct isci_remote_device *isci_device;
|
struct isci_remote_device *idev;
|
||||||
struct domain_device *dev;
|
struct domain_device *dev;
|
||||||
|
|
||||||
dev_dbg(&isci_host->pdev->dev,
|
dev_dbg(&ihost->pdev->dev,
|
||||||
"%s: isci_tmf = %p\n", __func__, isci_tmf);
|
"%s: isci_tmf = %p\n", __func__, isci_tmf);
|
||||||
|
|
||||||
isci_device = isci_tmf->device;
|
idev = isci_tmf->device;
|
||||||
sci_device = &isci_device->sci;
|
sci_dev = &idev->sci;
|
||||||
dev = isci_device->domain_dev;
|
dev = idev->domain_dev;
|
||||||
|
|
||||||
/* do common allocation and init of request object. */
|
/* do common allocation and init of request object. */
|
||||||
status = isci_request_alloc_tmf(
|
ireq = isci_request_alloc_tmf(ihost, isci_tmf, idev, GFP_ATOMIC);
|
||||||
isci_host,
|
if (!ireq)
|
||||||
isci_tmf,
|
return NULL;
|
||||||
&request,
|
|
||||||
isci_device,
|
|
||||||
GFP_ATOMIC
|
|
||||||
);
|
|
||||||
|
|
||||||
if (status != SCI_SUCCESS)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* let the core do it's construct. */
|
/* let the core do it's construct. */
|
||||||
status = scic_task_request_construct(&isci_host->sci, sci_device,
|
status = scic_task_request_construct(&ihost->sci, sci_dev,
|
||||||
SCI_CONTROLLER_INVALID_IO_TAG,
|
SCI_CONTROLLER_INVALID_IO_TAG,
|
||||||
&request->sci);
|
&ireq->sci);
|
||||||
|
|
||||||
if (status != SCI_SUCCESS) {
|
if (status != SCI_SUCCESS) {
|
||||||
dev_warn(&isci_host->pdev->dev,
|
dev_warn(&ihost->pdev->dev,
|
||||||
"%s: scic_task_request_construct failed - "
|
"%s: scic_task_request_construct failed - "
|
||||||
"status = 0x%x\n",
|
"status = 0x%x\n",
|
||||||
__func__,
|
__func__,
|
||||||
|
@ -312,30 +290,23 @@ static enum sci_status isci_task_request_build(
|
||||||
/* XXX convert to get this from task->tproto like other drivers */
|
/* XXX convert to get this from task->tproto like other drivers */
|
||||||
if (dev->dev_type == SAS_END_DEV) {
|
if (dev->dev_type == SAS_END_DEV) {
|
||||||
isci_tmf->proto = SAS_PROTOCOL_SSP;
|
isci_tmf->proto = SAS_PROTOCOL_SSP;
|
||||||
status = scic_task_request_construct_ssp(&request->sci);
|
status = scic_task_request_construct_ssp(&ireq->sci);
|
||||||
if (status != SCI_SUCCESS)
|
if (status != SCI_SUCCESS)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
|
if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
|
||||||
isci_tmf->proto = SAS_PROTOCOL_SATA;
|
isci_tmf->proto = SAS_PROTOCOL_SATA;
|
||||||
status = isci_sata_management_task_request_build(request);
|
status = isci_sata_management_task_request_build(ireq);
|
||||||
|
|
||||||
if (status != SCI_SUCCESS)
|
if (status != SCI_SUCCESS)
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
return ireq;
|
||||||
goto out;
|
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
|
isci_request_free(ihost, ireq);
|
||||||
/* release the dma memory if we fail. */
|
ireq = NULL;
|
||||||
isci_request_free(isci_host, request);
|
return ireq;
|
||||||
request = NULL;
|
|
||||||
|
|
||||||
out:
|
|
||||||
*isci_request = request;
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -350,16 +321,14 @@ static enum sci_status isci_task_request_build(
|
||||||
* TMF_RESP_FUNC_COMPLETE on successful completion of the TMF (this includes
|
* TMF_RESP_FUNC_COMPLETE on successful completion of the TMF (this includes
|
||||||
* error conditions reported in the IU status), or TMF_RESP_FUNC_FAILED.
|
* error conditions reported in the IU status), or TMF_RESP_FUNC_FAILED.
|
||||||
*/
|
*/
|
||||||
int isci_task_execute_tmf(
|
int isci_task_execute_tmf(struct isci_host *ihost, struct isci_tmf *tmf,
|
||||||
struct isci_host *isci_host,
|
unsigned long timeout_ms)
|
||||||
struct isci_tmf *tmf,
|
|
||||||
unsigned long timeout_ms)
|
|
||||||
{
|
{
|
||||||
DECLARE_COMPLETION_ONSTACK(completion);
|
DECLARE_COMPLETION_ONSTACK(completion);
|
||||||
enum sci_task_status status = SCI_TASK_FAILURE;
|
enum sci_task_status status = SCI_TASK_FAILURE;
|
||||||
struct scic_sds_remote_device *sci_device;
|
struct scic_sds_remote_device *sci_device;
|
||||||
struct isci_remote_device *isci_device = tmf->device;
|
struct isci_remote_device *isci_device = tmf->device;
|
||||||
struct isci_request *request;
|
struct isci_request *ireq;
|
||||||
int ret = TMF_RESP_FUNC_FAILED;
|
int ret = TMF_RESP_FUNC_FAILED;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long timeleft;
|
unsigned long timeleft;
|
||||||
|
@ -368,13 +337,13 @@ int isci_task_execute_tmf(
|
||||||
* if the device is not there and ready.
|
* if the device is not there and ready.
|
||||||
*/
|
*/
|
||||||
if (!isci_device || isci_device->status != isci_ready_for_io) {
|
if (!isci_device || isci_device->status != isci_ready_for_io) {
|
||||||
dev_dbg(&isci_host->pdev->dev,
|
dev_dbg(&ihost->pdev->dev,
|
||||||
"%s: isci_device = %p not ready (%d)\n",
|
"%s: isci_device = %p not ready (%d)\n",
|
||||||
__func__,
|
__func__,
|
||||||
isci_device, isci_device->status);
|
isci_device, isci_device->status);
|
||||||
return TMF_RESP_FUNC_FAILED;
|
return TMF_RESP_FUNC_FAILED;
|
||||||
} else
|
} else
|
||||||
dev_dbg(&isci_host->pdev->dev,
|
dev_dbg(&ihost->pdev->dev,
|
||||||
"%s: isci_device = %p\n",
|
"%s: isci_device = %p\n",
|
||||||
__func__, isci_device);
|
__func__, isci_device);
|
||||||
|
|
||||||
|
@ -383,64 +352,59 @@ int isci_task_execute_tmf(
|
||||||
/* Assign the pointer to the TMF's completion kernel wait structure. */
|
/* Assign the pointer to the TMF's completion kernel wait structure. */
|
||||||
tmf->complete = &completion;
|
tmf->complete = &completion;
|
||||||
|
|
||||||
isci_task_request_build(
|
ireq = isci_task_request_build(ihost, tmf);
|
||||||
isci_host,
|
if (!ireq) {
|
||||||
&request,
|
dev_warn(&ihost->pdev->dev,
|
||||||
tmf
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!request) {
|
|
||||||
dev_warn(&isci_host->pdev->dev,
|
|
||||||
"%s: isci_task_request_build failed\n",
|
"%s: isci_task_request_build failed\n",
|
||||||
__func__);
|
__func__);
|
||||||
return TMF_RESP_FUNC_FAILED;
|
return TMF_RESP_FUNC_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&isci_host->scic_lock, flags);
|
spin_lock_irqsave(&ihost->scic_lock, flags);
|
||||||
|
|
||||||
/* start the TMF io. */
|
/* start the TMF io. */
|
||||||
status = scic_controller_start_task(
|
status = scic_controller_start_task(
|
||||||
&isci_host->sci,
|
&ihost->sci,
|
||||||
sci_device,
|
sci_device,
|
||||||
&request->sci,
|
&ireq->sci,
|
||||||
SCI_CONTROLLER_INVALID_IO_TAG);
|
SCI_CONTROLLER_INVALID_IO_TAG);
|
||||||
|
|
||||||
if (status != SCI_TASK_SUCCESS) {
|
if (status != SCI_TASK_SUCCESS) {
|
||||||
dev_warn(&isci_host->pdev->dev,
|
dev_warn(&ihost->pdev->dev,
|
||||||
"%s: start_io failed - status = 0x%x, request = %p\n",
|
"%s: start_io failed - status = 0x%x, request = %p\n",
|
||||||
__func__,
|
__func__,
|
||||||
status,
|
status,
|
||||||
request);
|
ireq);
|
||||||
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
|
spin_unlock_irqrestore(&ihost->scic_lock, flags);
|
||||||
goto cleanup_request;
|
goto cleanup_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmf->cb_state_func != NULL)
|
if (tmf->cb_state_func != NULL)
|
||||||
tmf->cb_state_func(isci_tmf_started, tmf, tmf->cb_data);
|
tmf->cb_state_func(isci_tmf_started, tmf, tmf->cb_data);
|
||||||
|
|
||||||
isci_request_change_state(request, started);
|
isci_request_change_state(ireq, started);
|
||||||
|
|
||||||
/* add the request to the remote device request list. */
|
/* add the request to the remote device request list. */
|
||||||
list_add(&request->dev_node, &isci_device->reqs_in_process);
|
list_add(&ireq->dev_node, &isci_device->reqs_in_process);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
|
spin_unlock_irqrestore(&ihost->scic_lock, flags);
|
||||||
|
|
||||||
/* Wait for the TMF to complete, or a timeout. */
|
/* Wait for the TMF to complete, or a timeout. */
|
||||||
timeleft = wait_for_completion_timeout(&completion,
|
timeleft = wait_for_completion_timeout(&completion,
|
||||||
jiffies + msecs_to_jiffies(timeout_ms));
|
jiffies + msecs_to_jiffies(timeout_ms));
|
||||||
|
|
||||||
if (timeleft == 0) {
|
if (timeleft == 0) {
|
||||||
spin_lock_irqsave(&isci_host->scic_lock, flags);
|
spin_lock_irqsave(&ihost->scic_lock, flags);
|
||||||
|
|
||||||
if (tmf->cb_state_func != NULL)
|
if (tmf->cb_state_func != NULL)
|
||||||
tmf->cb_state_func(isci_tmf_timed_out, tmf, tmf->cb_data);
|
tmf->cb_state_func(isci_tmf_timed_out, tmf, tmf->cb_data);
|
||||||
|
|
||||||
status = scic_controller_terminate_request(
|
status = scic_controller_terminate_request(
|
||||||
&request->isci_host->sci,
|
&ireq->isci_host->sci,
|
||||||
&request->isci_device->sci,
|
&ireq->isci_device->sci,
|
||||||
&request->sci);
|
&ireq->sci);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&isci_host->scic_lock, flags);
|
spin_unlock_irqrestore(&ihost->scic_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
isci_print_tmf(tmf);
|
isci_print_tmf(tmf);
|
||||||
|
@ -448,7 +412,7 @@ int isci_task_execute_tmf(
|
||||||
if (tmf->status == SCI_SUCCESS)
|
if (tmf->status == SCI_SUCCESS)
|
||||||
ret = TMF_RESP_FUNC_COMPLETE;
|
ret = TMF_RESP_FUNC_COMPLETE;
|
||||||
else if (tmf->status == SCI_FAILURE_IO_RESPONSE_VALID) {
|
else if (tmf->status == SCI_FAILURE_IO_RESPONSE_VALID) {
|
||||||
dev_dbg(&isci_host->pdev->dev,
|
dev_dbg(&ihost->pdev->dev,
|
||||||
"%s: tmf.status == "
|
"%s: tmf.status == "
|
||||||
"SCI_FAILURE_IO_RESPONSE_VALID\n",
|
"SCI_FAILURE_IO_RESPONSE_VALID\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -456,18 +420,18 @@ int isci_task_execute_tmf(
|
||||||
}
|
}
|
||||||
/* Else - leave the default "failed" status alone. */
|
/* Else - leave the default "failed" status alone. */
|
||||||
|
|
||||||
dev_dbg(&isci_host->pdev->dev,
|
dev_dbg(&ihost->pdev->dev,
|
||||||
"%s: completed request = %p\n",
|
"%s: completed request = %p\n",
|
||||||
__func__,
|
__func__,
|
||||||
request);
|
ireq);
|
||||||
|
|
||||||
if (request->io_request_completion != NULL) {
|
if (ireq->io_request_completion != NULL) {
|
||||||
/* A thread is waiting for this TMF to finish. */
|
/* A thread is waiting for this TMF to finish. */
|
||||||
complete(request->io_request_completion);
|
complete(ireq->io_request_completion);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup_request:
|
cleanup_request:
|
||||||
isci_request_free(isci_host, request);
|
isci_request_free(ihost, ireq);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue