aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/request.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r--drivers/scsi/isci/request.c197
1 files changed, 67 insertions, 130 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 9d7531ad9a74..f0813d076c50 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -3510,172 +3510,110 @@ static enum sci_status isci_io_request_build(
3510 return SCI_SUCCESS; 3510 return SCI_SUCCESS;
3511} 3511}
3512 3512
3513/** 3513static struct isci_request *isci_request_alloc_core(struct isci_host *ihost,
3514 * isci_request_alloc_core() - This function gets the request object from the 3514 struct isci_remote_device *idev,
3515 * isci_host dma cache. 3515 gfp_t gfp_flags)
3516 * @isci_host: This parameter specifies the ISCI host object
3517 * @isci_request: This parameter will contain the pointer to the new
3518 * isci_request object.
3519 * @isci_device: This parameter is the pointer to the isci remote device object
3520 * that is the destination for this request.
3521 * @gfp_flags: This parameter specifies the os allocation flags.
3522 *
3523 * SCI_SUCCESS on successfull completion, or specific failure code.
3524 */
3525static int isci_request_alloc_core(
3526 struct isci_host *isci_host,
3527 struct isci_request **isci_request,
3528 struct isci_remote_device *isci_device,
3529 gfp_t gfp_flags)
3530{ 3516{
3531 int ret = 0;
3532 dma_addr_t handle; 3517 dma_addr_t handle;
3533 struct isci_request *request; 3518 struct isci_request *ireq;
3534
3535 3519
3536 /* get pointer to dma memory. This actually points 3520 ireq = dma_pool_alloc(ihost->dma_pool, gfp_flags, &handle);
3537 * to both the isci_remote_device object and the 3521 if (!ireq) {
3538 * sci object. The isci object is at the beginning 3522 dev_warn(&ihost->pdev->dev,
3539 * of the memory allocated here.
3540 */
3541 request = dma_pool_alloc(isci_host->dma_pool, gfp_flags, &handle);
3542 if (!request) {
3543 dev_warn(&isci_host->pdev->dev,
3544 "%s: dma_pool_alloc returned NULL\n", __func__); 3523 "%s: dma_pool_alloc returned NULL\n", __func__);
3545 return -ENOMEM; 3524 return NULL;
3546 } 3525 }
3547 3526
3548 /* initialize the request object. */ 3527 /* initialize the request object. */
3549 spin_lock_init(&request->state_lock); 3528 spin_lock_init(&ireq->state_lock);
3550 request->request_daddr = handle; 3529 ireq->request_daddr = handle;
3551 request->isci_host = isci_host; 3530 ireq->isci_host = ihost;
3552 request->isci_device = isci_device; 3531 ireq->isci_device = idev;
3553 request->io_request_completion = NULL; 3532 ireq->io_request_completion = NULL;
3554 request->terminated = false; 3533 ireq->terminated = false;
3555 3534
3556 request->num_sg_entries = 0; 3535 ireq->num_sg_entries = 0;
3557 3536
3558 request->complete_in_target = false; 3537 ireq->complete_in_target = false;
3559 3538
3560 INIT_LIST_HEAD(&request->completed_node); 3539 INIT_LIST_HEAD(&ireq->completed_node);
3561 INIT_LIST_HEAD(&request->dev_node); 3540 INIT_LIST_HEAD(&ireq->dev_node);
3562 3541
3563 *isci_request = request; 3542 isci_request_change_state(ireq, allocated);
3564 isci_request_change_state(request, allocated);
3565 3543
3566 return ret; 3544 return ireq;
3567} 3545}
3568 3546
3569static int isci_request_alloc_io( 3547static struct isci_request *isci_request_alloc_io(struct isci_host *ihost,
3570 struct isci_host *isci_host, 3548 struct sas_task *task,
3571 struct sas_task *task, 3549 struct isci_remote_device *idev,
3572 struct isci_request **isci_request, 3550 gfp_t gfp_flags)
3573 struct isci_remote_device *isci_device,
3574 gfp_t gfp_flags)
3575{ 3551{
3576 int retval = isci_request_alloc_core(isci_host, isci_request, 3552 struct isci_request *ireq;
3577 isci_device, gfp_flags);
3578
3579 if (!retval) {
3580 (*isci_request)->ttype_ptr.io_task_ptr = task;
3581 (*isci_request)->ttype = io_task;
3582 3553
3583 task->lldd_task = *isci_request; 3554 ireq = isci_request_alloc_core(ihost, idev, gfp_flags);
3555 if (ireq) {
3556 ireq->ttype_ptr.io_task_ptr = task;
3557 ireq->ttype = io_task;
3558 task->lldd_task = ireq;
3584 } 3559 }
3585 return retval; 3560 return ireq;
3586} 3561}
3587 3562
3588/** 3563struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost,
3589 * isci_request_alloc_tmf() - This function gets the request object from the 3564 struct isci_tmf *isci_tmf,
3590 * isci_host dma cache and initializes the relevant fields as a sas_task. 3565 struct isci_remote_device *idev,
3591 * @isci_host: This parameter specifies the ISCI host object 3566 gfp_t gfp_flags)
3592 * @sas_task: This parameter is the task struct from the upper layer driver.
3593 * @isci_request: This parameter will contain the pointer to the new
3594 * isci_request object.
3595 * @isci_device: This parameter is the pointer to the isci remote device object
3596 * that is the destination for this request.
3597 * @gfp_flags: This parameter specifies the os allocation flags.
3598 *
3599 * SCI_SUCCESS on successfull completion, or specific failure code.
3600 */
3601int isci_request_alloc_tmf(
3602 struct isci_host *isci_host,
3603 struct isci_tmf *isci_tmf,
3604 struct isci_request **isci_request,
3605 struct isci_remote_device *isci_device,
3606 gfp_t gfp_flags)
3607{ 3567{
3608 int retval = isci_request_alloc_core(isci_host, isci_request, 3568 struct isci_request *ireq;
3609 isci_device, gfp_flags);
3610
3611 if (!retval) {
3612 3569
3613 (*isci_request)->ttype_ptr.tmf_task_ptr = isci_tmf; 3570 ireq = isci_request_alloc_core(ihost, idev, gfp_flags);
3614 (*isci_request)->ttype = tmf_task; 3571 if (ireq) {
3572 ireq->ttype_ptr.tmf_task_ptr = isci_tmf;
3573 ireq->ttype = tmf_task;
3615 } 3574 }
3616 return retval; 3575 return ireq;
3617} 3576}
3618 3577
3619/** 3578int isci_request_execute(struct isci_host *ihost, struct sas_task *task,
3620 * isci_request_execute() - This function allocates the isci_request object, 3579 gfp_t gfp_flags)
3621 * all fills in some common fields.
3622 * @isci_host: This parameter specifies the ISCI host object
3623 * @sas_task: This parameter is the task struct from the upper layer driver.
3624 * @isci_request: This parameter will contain the pointer to the new
3625 * isci_request object.
3626 * @gfp_flags: This parameter specifies the os allocation flags.
3627 *
3628 * SCI_SUCCESS on successfull completion, or specific failure code.
3629 */
3630int isci_request_execute(
3631 struct isci_host *isci_host,
3632 struct sas_task *task,
3633 struct isci_request **isci_request,
3634 gfp_t gfp_flags)
3635{ 3580{
3636 int ret = 0;
3637 struct scic_sds_remote_device *sci_device;
3638 enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; 3581 enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
3639 struct isci_remote_device *isci_device; 3582 struct scic_sds_remote_device *sci_dev;
3640 struct isci_request *request; 3583 struct isci_remote_device *idev;
3584 struct isci_request *ireq;
3641 unsigned long flags; 3585 unsigned long flags;
3586 int ret = 0;
3642 3587
3643 isci_device = task->dev->lldd_dev; 3588 idev = task->dev->lldd_dev;
3644 sci_device = &isci_device->sci; 3589 sci_dev = &idev->sci;
3645 3590
3646 /* do common allocation and init of request object. */ 3591 /* do common allocation and init of request object. */
3647 ret = isci_request_alloc_io( 3592 ireq = isci_request_alloc_io(ihost, task, idev, gfp_flags);
3648 isci_host, 3593 if (!ireq)
3649 task,
3650 &request,
3651 isci_device,
3652 gfp_flags
3653 );
3654
3655 if (ret)
3656 goto out; 3594 goto out;
3657 3595
3658 status = isci_io_request_build(isci_host, request, isci_device); 3596 status = isci_io_request_build(ihost, ireq, idev);
3659 if (status != SCI_SUCCESS) { 3597 if (status != SCI_SUCCESS) {
3660 dev_warn(&isci_host->pdev->dev, 3598 dev_warn(&ihost->pdev->dev,
3661 "%s: request_construct failed - status = 0x%x\n", 3599 "%s: request_construct failed - status = 0x%x\n",
3662 __func__, 3600 __func__,
3663 status); 3601 status);
3664 goto out; 3602 goto out;
3665 } 3603 }
3666 3604
3667 spin_lock_irqsave(&isci_host->scic_lock, flags); 3605 spin_lock_irqsave(&ihost->scic_lock, flags);
3668 3606
3669 /* send the request, let the core assign the IO TAG. */ 3607 /* send the request, let the core assign the IO TAG. */
3670 status = scic_controller_start_io(&isci_host->sci, sci_device, 3608 status = scic_controller_start_io(&ihost->sci, sci_dev,
3671 &request->sci, 3609 &ireq->sci,
3672 SCI_CONTROLLER_INVALID_IO_TAG); 3610 SCI_CONTROLLER_INVALID_IO_TAG);
3673 if (status != SCI_SUCCESS && 3611 if (status != SCI_SUCCESS &&
3674 status != SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) { 3612 status != SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
3675 dev_warn(&isci_host->pdev->dev, 3613 dev_warn(&ihost->pdev->dev,
3676 "%s: failed request start (0x%x)\n", 3614 "%s: failed request start (0x%x)\n",
3677 __func__, status); 3615 __func__, status);
3678 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 3616 spin_unlock_irqrestore(&ihost->scic_lock, flags);
3679 goto out; 3617 goto out;
3680 } 3618 }
3681 3619
@@ -3687,21 +3625,21 @@ int isci_request_execute(
3687 * Update it's status and add it to the list in the 3625 * Update it's status and add it to the list in the
3688 * remote device object. 3626 * remote device object.
3689 */ 3627 */
3690 list_add(&request->dev_node, &isci_device->reqs_in_process); 3628 list_add(&ireq->dev_node, &idev->reqs_in_process);
3691 3629
3692 if (status == SCI_SUCCESS) { 3630 if (status == SCI_SUCCESS) {
3693 /* Save the tag for possible task mgmt later. */ 3631 /* Save the tag for possible task mgmt later. */
3694 request->io_tag = request->sci.io_tag; 3632 ireq->io_tag = ireq->sci.io_tag;
3695 isci_request_change_state(request, started); 3633 isci_request_change_state(ireq, started);
3696 } else { 3634 } else {
3697 /* The request did not really start in the 3635 /* The request did not really start in the
3698 * hardware, so clear the request handle 3636 * hardware, so clear the request handle
3699 * here so no terminations will be done. 3637 * here so no terminations will be done.
3700 */ 3638 */
3701 request->terminated = true; 3639 ireq->terminated = true;
3702 isci_request_change_state(request, completed); 3640 isci_request_change_state(ireq, completed);
3703 } 3641 }
3704 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 3642 spin_unlock_irqrestore(&ihost->scic_lock, flags);
3705 3643
3706 if (status == 3644 if (status ==
3707 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) { 3645 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
@@ -3716,7 +3654,7 @@ int isci_request_execute(
3716 /* Cause this task to be scheduled in the SCSI error 3654 /* Cause this task to be scheduled in the SCSI error
3717 * handler thread. 3655 * handler thread.
3718 */ 3656 */
3719 isci_execpath_callback(isci_host, task, 3657 isci_execpath_callback(ihost, task,
3720 sas_task_abort); 3658 sas_task_abort);
3721 3659
3722 /* Change the status, since we are holding 3660 /* Change the status, since we are holding
@@ -3729,11 +3667,10 @@ int isci_request_execute(
3729 out: 3667 out:
3730 if (status != SCI_SUCCESS) { 3668 if (status != SCI_SUCCESS) {
3731 /* release dma memory on failure. */ 3669 /* release dma memory on failure. */
3732 isci_request_free(isci_host, request); 3670 isci_request_free(ihost, ireq);
3733 request = NULL; 3671 ireq = NULL;
3734 ret = SCI_FAILURE; 3672 ret = SCI_FAILURE;
3735 } 3673 }
3736 3674
3737 *isci_request = request;
3738 return ret; 3675 return ret;
3739} 3676}