diff options
Diffstat (limited to 'drivers/scsi/isci/task.c')
-rw-r--r-- | drivers/scsi/isci/task.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index 0835a2c2dc71..157e9978183a 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -133,6 +133,15 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task, | |||
133 | for (; num > 0; num--,\ | 133 | for (; num > 0; num--,\ |
134 | task = list_entry(task->list.next, struct sas_task, list)) | 134 | task = list_entry(task->list.next, struct sas_task, list)) |
135 | 135 | ||
136 | |||
137 | static inline int isci_device_io_ready(struct isci_remote_device *idev, | ||
138 | struct sas_task *task) | ||
139 | { | ||
140 | return idev ? test_bit(IDEV_IO_READY, &idev->flags) || | ||
141 | (test_bit(IDEV_IO_NCQERROR, &idev->flags) && | ||
142 | isci_task_is_ncq_recovery(task)) | ||
143 | : 0; | ||
144 | } | ||
136 | /** | 145 | /** |
137 | * isci_task_execute_task() - This function is one of the SAS Domain Template | 146 | * isci_task_execute_task() - This function is one of the SAS Domain Template |
138 | * functions. This function is called by libsas to send a task down to | 147 | * functions. This function is called by libsas to send a task down to |
@@ -165,7 +174,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
165 | for_each_sas_task(num, task) { | 174 | for_each_sas_task(num, task) { |
166 | spin_lock_irqsave(&ihost->scic_lock, flags); | 175 | spin_lock_irqsave(&ihost->scic_lock, flags); |
167 | idev = isci_lookup_device(task->dev); | 176 | idev = isci_lookup_device(task->dev); |
168 | io_ready = idev ? test_bit(IDEV_IO_READY, &idev->flags) : 0; | 177 | io_ready = isci_device_io_ready(idev, task); |
169 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | 178 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
170 | 179 | ||
171 | dev_dbg(&ihost->pdev->dev, | 180 | dev_dbg(&ihost->pdev->dev, |
@@ -178,6 +187,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
178 | SAS_DEVICE_UNKNOWN); | 187 | SAS_DEVICE_UNKNOWN); |
179 | isci_host_can_dequeue(ihost, 1); | 188 | isci_host_can_dequeue(ihost, 1); |
180 | } else if (!io_ready) { | 189 | } else if (!io_ready) { |
190 | |||
181 | /* Indicate QUEUE_FULL so that the scsi midlayer | 191 | /* Indicate QUEUE_FULL so that the scsi midlayer |
182 | * retries. | 192 | * retries. |
183 | */ | 193 | */ |
@@ -299,7 +309,9 @@ int isci_task_execute_tmf(struct isci_host *ihost, | |||
299 | /* sanity check, return TMF_RESP_FUNC_FAILED | 309 | /* sanity check, return TMF_RESP_FUNC_FAILED |
300 | * if the device is not there and ready. | 310 | * if the device is not there and ready. |
301 | */ | 311 | */ |
302 | if (!isci_device || !test_bit(IDEV_IO_READY, &isci_device->flags)) { | 312 | if (!isci_device || |
313 | (!test_bit(IDEV_IO_READY, &isci_device->flags) && | ||
314 | !test_bit(IDEV_IO_NCQERROR, &isci_device->flags))) { | ||
303 | dev_dbg(&ihost->pdev->dev, | 315 | dev_dbg(&ihost->pdev->dev, |
304 | "%s: isci_device = %p not ready (%#lx)\n", | 316 | "%s: isci_device = %p not ready (%#lx)\n", |
305 | __func__, | 317 | __func__, |