diff options
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r-- | drivers/scsi/isci/request.c | 197 |
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 | /** | 3513 | static 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 | */ | ||
3525 | static 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 | ||
3569 | static int isci_request_alloc_io( | 3547 | static 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 | /** | 3563 | struct 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 | */ | ||
3601 | int 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 | /** | 3578 | int 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 | */ | ||
3630 | int 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 | } |