From e7549b926dd3ceec048f5689df90d4ec970c9419 Mon Sep 17 00:00:00 2001 From: Wolfgang Wiedmeyer Date: Fri, 23 Oct 2015 13:30:20 +0200 Subject: more driver stuff from 3.2.72 --- drivers/scsi/isci/remote_device.c | 109 +++++++++----------------------------- 1 file changed, 24 insertions(+), 85 deletions(-) (limited to 'drivers/scsi/isci/remote_device.c') diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index b6e6368..b207cd3 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c @@ -386,6 +386,18 @@ static bool is_remote_device_ready(struct isci_remote_device *idev) } } +/* + * called once the remote node context has transisitioned to a ready + * state (after suspending RX and/or TX due to early D2H fis) + */ +static void atapi_remote_device_resume_done(void *_dev) +{ + struct isci_remote_device *idev = _dev; + struct isci_request *ireq = idev->working_request; + + sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); +} + enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, u32 event_code) { @@ -432,6 +444,16 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, if (status != SCI_SUCCESS) return status; + if (state == SCI_STP_DEV_ATAPI_ERROR) { + /* For ATAPI error state resume the RNC right away. */ + if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX || + scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) { + return sci_remote_node_context_resume(&idev->rnc, + atapi_remote_device_resume_done, + idev); + } + } + if (state == SCI_STP_DEV_IDLE) { /* We pick up suspension events to handle specifically to this @@ -625,6 +647,7 @@ enum sci_status sci_remote_device_complete_io(struct isci_host *ihost, case SCI_STP_DEV_CMD: case SCI_STP_DEV_NCQ: case SCI_STP_DEV_NCQ_ERROR: + case SCI_STP_DEV_ATAPI_ERROR: status = common_complete_io(iport, idev, ireq); if (status != SCI_SUCCESS) break; @@ -1020,6 +1043,7 @@ static const struct sci_base_state sci_remote_device_state_table[] = { [SCI_STP_DEV_NCQ_ERROR] = { .enter_state = sci_stp_remote_device_ready_ncq_error_substate_enter, }, + [SCI_STP_DEV_ATAPI_ERROR] = { }, [SCI_STP_DEV_AWAIT_RESET] = { }, [SCI_SMP_DEV_IDLE] = { .enter_state = sci_smp_remote_device_ready_idle_substate_enter, @@ -1414,88 +1438,3 @@ int isci_remote_device_found(struct domain_device *domain_dev) return status == SCI_SUCCESS ? 0 : -ENODEV; } -/** - * 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); - - spin_lock(&task->task_state_lock); - if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET) - reset_is_pending = true; - spin_unlock(&task->task_state_lock); - } - } - - 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. - */ -void isci_device_clear_reset_pending(struct isci_host *ihost, struct isci_remote_device *idev) -{ - struct isci_request *isci_request; - struct isci_request *tmp_req; - unsigned long flags = 0; - - dev_dbg(&ihost->pdev->dev, "%s: idev=%p, ihost=%p\n", - __func__, idev, ihost); - - spin_lock_irqsave(&ihost->scic_lock, flags); - - /* Clear reset pending on all pending requests. */ - list_for_each_entry_safe(isci_request, tmp_req, - &idev->reqs_in_process, dev_node) { - dev_dbg(&ihost->pdev->dev, "%s: idev = %p request = %p\n", - __func__, idev, isci_request); - - 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); - } - } - spin_unlock_irqrestore(&ihost->scic_lock, flags); -} -- cgit v1.1