aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2011-03-04 17:06:40 -0500
committerDan Williams <dan.j.williams@intel.com>2011-07-03 06:55:29 -0400
commit11b00c194cfbd0eb0d90f32c096508b2bb8be6ec (patch)
tree81e258a7715742d97eaa8675f45fac97a2118e20
parent18d3d72a42a846d46b71131982c51d63eba2b7b3 (diff)
isci: Changes in isci_host_completion_routine
Changes to move management of the reqs_in_process entry for the request here. Made changes to note when the task is already in the abort path and cannot be completed through callbacks. Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com> Signed-off-by: Jacek Danecki <Jacek.Danecki@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/host.c75
-rw-r--r--drivers/scsi/isci/host.h2
-rw-r--r--drivers/scsi/isci/request.c12
3 files changed, 64 insertions, 25 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index ae5d46022073..153f419f1618 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -270,27 +270,40 @@ static int isci_host_mdl_allocate_coherent(
270static void isci_host_completion_routine(unsigned long data) 270static void isci_host_completion_routine(unsigned long data)
271{ 271{
272 struct isci_host *isci_host = (struct isci_host *)data; 272 struct isci_host *isci_host = (struct isci_host *)data;
273 struct list_head completed_request_list; 273 struct list_head completed_request_list;
274 struct list_head aborted_request_list; 274 struct list_head errored_request_list;
275 struct list_head *current_position; 275 struct list_head *current_position;
276 struct list_head *next_position; 276 struct list_head *next_position;
277 struct isci_request *request; 277 struct isci_request *request;
278 struct isci_request *next_request; 278 struct isci_request *next_request;
279 struct sas_task *task; 279 struct sas_task *task;
280 280
281 INIT_LIST_HEAD(&completed_request_list); 281 INIT_LIST_HEAD(&completed_request_list);
282 INIT_LIST_HEAD(&aborted_request_list); 282 INIT_LIST_HEAD(&errored_request_list);
283 283
284 spin_lock_irq(&isci_host->scic_lock); 284 spin_lock_irq(&isci_host->scic_lock);
285 285
286 scic_sds_controller_completion_handler(isci_host->core_controller); 286 scic_sds_controller_completion_handler(isci_host->core_controller);
287 287
288 /* Take the lists of completed I/Os from the host. */ 288 /* Take the lists of completed I/Os from the host. */
289
289 list_splice_init(&isci_host->requests_to_complete, 290 list_splice_init(&isci_host->requests_to_complete,
290 &completed_request_list); 291 &completed_request_list);
291 292
292 list_splice_init(&isci_host->requests_to_abort, 293 /* While holding the scic_lock take all of the normally completed
293 &aborted_request_list); 294 * I/Os off of the device's pending lists.
295 */
296 list_for_each_entry(request, &completed_request_list, completed_node) {
297
298 /* Remove the request from the remote device's list
299 * of pending requests.
300 */
301 list_del_init(&request->dev_node);
302 }
303
304 /* Take the list of errored I/Os from the host. */
305 list_splice_init(&isci_host->requests_to_errorback,
306 &errored_request_list);
294 307
295 spin_unlock_irq(&isci_host->scic_lock); 308 spin_unlock_irq(&isci_host->scic_lock);
296 309
@@ -309,13 +322,22 @@ static void isci_host_completion_routine(unsigned long data)
309 request, 322 request,
310 task); 323 task);
311 324
312 task->task_done(task); 325 /* Return the task to libsas */
313 task->lldd_task = NULL; 326 if (task != NULL) {
327
328 task->lldd_task = NULL;
329 if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
314 330
331 /* If the task is already in the abort path,
332 * the task_done callback cannot be called.
333 */
334 task->task_done(task);
335 }
336 }
315 /* Free the request object. */ 337 /* Free the request object. */
316 isci_request_free(isci_host, request); 338 isci_request_free(isci_host, request);
317 } 339 }
318 list_for_each_entry_safe(request, next_request, &aborted_request_list, 340 list_for_each_entry_safe(request, next_request, &errored_request_list,
319 completed_node) { 341 completed_node) {
320 342
321 task = isci_request_access_task(request); 343 task = isci_request_access_task(request);
@@ -327,8 +349,33 @@ static void isci_host_completion_routine(unsigned long data)
327 request, 349 request,
328 task); 350 task);
329 351
330 /* Put the task into the abort path. */ 352 if (task != NULL) {
331 sas_task_abort(task); 353
354 /* Put the task into the abort path if it's not there
355 * already.
356 */
357 if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED))
358 sas_task_abort(task);
359
360 } else {
361 /* This is a case where the request has completed with a
362 * status such that it needed further target servicing,
363 * but the sas_task reference has already been removed
364 * from the request. Since it was errored, it was not
365 * being aborted, so there is nothing to do except free
366 * it.
367 */
368
369 spin_lock_irq(&isci_host->scic_lock);
370 /* Remove the request from the remote device's list
371 * of pending requests.
372 */
373 list_del_init(&request->dev_node);
374 spin_unlock_irq(&isci_host->scic_lock);
375
376 /* Free the request object. */
377 isci_request_free(isci_host, request);
378 }
332 } 379 }
333 380
334} 381}
@@ -477,7 +524,7 @@ int isci_host_init(struct isci_host *isci_host)
477 INIT_LIST_HEAD(&(isci_host->mdl_struct_list)); 524 INIT_LIST_HEAD(&(isci_host->mdl_struct_list));
478 525
479 INIT_LIST_HEAD(&isci_host->requests_to_complete); 526 INIT_LIST_HEAD(&isci_host->requests_to_complete);
480 INIT_LIST_HEAD(&isci_host->requests_to_abort); 527 INIT_LIST_HEAD(&isci_host->requests_to_errorback);
481 528
482 spin_lock_irq(&isci_host->scic_lock); 529 spin_lock_irq(&isci_host->scic_lock);
483 status = scic_controller_initialize(isci_host->core_controller); 530 status = scic_controller_initialize(isci_host->core_controller);
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 3c69f1ffb1c3..889a7850255a 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -116,7 +116,7 @@ struct isci_host {
116 struct tasklet_struct completion_tasklet; 116 struct tasklet_struct completion_tasklet;
117 struct list_head mdl_struct_list; 117 struct list_head mdl_struct_list;
118 struct list_head requests_to_complete; 118 struct list_head requests_to_complete;
119 struct list_head requests_to_abort; 119 struct list_head requests_to_errorback;
120 spinlock_t scic_lock; 120 spinlock_t scic_lock;
121 121
122 /* careful only access this via idev_by_id */ 122 /* careful only access this via idev_by_id */
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 6b0863e73f22..8039f1c72f72 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -836,7 +836,7 @@ static void isci_task_save_for_upper_layer_completion(
836 status); 836 status);
837 /* Add to the aborted list. */ 837 /* Add to the aborted list. */
838 list_add(&request->completed_node, 838 list_add(&request->completed_node,
839 &host->requests_to_abort); 839 &host->requests_to_errorback);
840 break; 840 break;
841 841
842 default: 842 default:
@@ -849,7 +849,7 @@ static void isci_task_save_for_upper_layer_completion(
849 849
850 /* Add to the aborted list. */ 850 /* Add to the aborted list. */
851 list_add(&request->completed_node, 851 list_add(&request->completed_node,
852 &host->requests_to_abort); 852 &host->requests_to_errorback);
853 break; 853 break;
854 } 854 }
855} 855}
@@ -1185,14 +1185,6 @@ void isci_request_io_request_complete(
1185 */ 1185 */
1186 request->sci_request_handle = NULL; 1186 request->sci_request_handle = NULL;
1187 1187
1188 /* Only remove the request from the remote device list
1189 * of pending requests if we have not requested error
1190 * handling on this request.
1191 */
1192 if (complete_to_host != isci_perform_error_io_completion)
1193 list_del_init(&request->dev_node);
1194
1195
1196 /* Save possible completion ptr. */ 1188 /* Save possible completion ptr. */
1197 io_request_completion = request->io_request_completion; 1189 io_request_completion = request->io_request_completion;
1198 1190