diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-03-31 16:10:44 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:00:36 -0400 |
commit | 4393aa4e6b9517a666f0ef6b774fd421a9dc4c68 (patch) | |
tree | ec5e0c222d16f2368e5589a11fc4ec191ceca365 /drivers | |
parent | 037afc7812e2b202fbc18218e6c0eff34dad36ed (diff) |
isci: fix fragile/conditional isci_host lookups
A domain_device can always reference back to ->lldd_ha unlike local lldd
structures. Fix up cases where the driver uses local objects to look up the
isci_host. This also changes the calling conventions of some routines to
expect a valid isci_host parameter rather than re-lookup the pointer on entry.
Incidentally cleans up some macros that are longer to type than the open-coded
equivalent:
isci_host_from_sas_ha
isci_dev_from_domain_dev
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/host.c | 4 | ||||
-rw-r--r-- | drivers/scsi/isci/host.h | 13 | ||||
-rw-r--r-- | drivers/scsi/isci/phy.c | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/port.c | 68 | ||||
-rw-r--r-- | drivers/scsi/isci/port.h | 5 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 70 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.h | 62 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/task.c | 87 |
9 files changed, 94 insertions, 219 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 79515be5f7c1..66449593aa8c 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -129,7 +129,7 @@ void isci_host_start_complete(struct isci_host *ihost, enum sci_status completio | |||
129 | 129 | ||
130 | int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time) | 130 | int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time) |
131 | { | 131 | { |
132 | struct isci_host *ihost = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost)); | 132 | struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha; |
133 | 133 | ||
134 | if (test_bit(IHOST_START_PENDING, &ihost->flags)) | 134 | if (test_bit(IHOST_START_PENDING, &ihost->flags)) |
135 | return 0; | 135 | return 0; |
@@ -149,7 +149,7 @@ int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time) | |||
149 | 149 | ||
150 | void isci_host_scan_start(struct Scsi_Host *shost) | 150 | void isci_host_scan_start(struct Scsi_Host *shost) |
151 | { | 151 | { |
152 | struct isci_host *ihost = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost)); | 152 | struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha; |
153 | struct scic_sds_controller *scic = ihost->core_controller; | 153 | struct scic_sds_controller *scic = ihost->core_controller; |
154 | unsigned long tmo = scic_controller_get_suggested_start_timeout(scic); | 154 | unsigned long tmo = scic_controller_get_suggested_start_timeout(scic); |
155 | 155 | ||
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index d012b69d8d61..8372094ef5ad 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h | |||
@@ -233,15 +233,10 @@ static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_rem | |||
233 | wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags)); | 233 | wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags)); |
234 | } | 234 | } |
235 | 235 | ||
236 | /** | 236 | static inline struct isci_host *dev_to_ihost(struct domain_device *dev) |
237 | * isci_host_from_sas_ha() - This accessor retrieves the isci_host object | 237 | { |
238 | * reference from the Linux sas_ha_struct reference. | 238 | return dev->port->ha->lldd_ha; |
239 | * @ha_struct,: This parameter points to the Linux sas_ha_struct object | 239 | } |
240 | * | ||
241 | * A reference to the associated isci_host structure. | ||
242 | */ | ||
243 | #define isci_host_from_sas_ha(ha_struct) \ | ||
244 | ((struct isci_host *)(ha_struct)->lldd_ha) | ||
245 | 240 | ||
246 | /** | 241 | /** |
247 | * isci_host_scan_finished() - | 242 | * isci_host_scan_finished() - |
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index decc0c05a3dd..9e081a4c8a3c 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c | |||
@@ -163,7 +163,7 @@ int isci_phy_control(struct asd_sas_phy *sas_phy, | |||
163 | return -ENODEV; | 163 | return -ENODEV; |
164 | 164 | ||
165 | /* Perform the port reset. */ | 165 | /* Perform the port reset. */ |
166 | ret = isci_port_perform_hard_reset(iport, iphy); | 166 | ret = isci_port_perform_hard_reset(ihost, iport, iphy); |
167 | 167 | ||
168 | break; | 168 | break; |
169 | 169 | ||
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c index 74dc96dc6b17..b675a94f4a73 100644 --- a/drivers/scsi/isci/port.c +++ b/drivers/scsi/isci/port.c | |||
@@ -400,55 +400,43 @@ void isci_port_hard_reset_complete(struct isci_port *isci_port, | |||
400 | 400 | ||
401 | complete_all(&isci_port->hard_reset_complete); | 401 | complete_all(&isci_port->hard_reset_complete); |
402 | } | 402 | } |
403 | /** | 403 | |
404 | * isci_port_perform_hard_reset() - This function is one of the SAS Domain | 404 | int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport, |
405 | * Template functions. This is a phy management function. | 405 | struct isci_phy *iphy) |
406 | * @isci_port: | ||
407 | * @isci_phy: | ||
408 | * | ||
409 | * status, TMF_RESP_FUNC_COMPLETE indicates success. | ||
410 | */ | ||
411 | int isci_port_perform_hard_reset( | ||
412 | struct isci_port *isci_port, | ||
413 | struct isci_phy *isci_phy) | ||
414 | { | 406 | { |
407 | unsigned long flags; | ||
415 | enum sci_status status; | 408 | enum sci_status status; |
416 | int ret = TMF_RESP_FUNC_COMPLETE; | 409 | int ret = TMF_RESP_FUNC_COMPLETE; |
417 | unsigned long flags; | ||
418 | 410 | ||
411 | dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n", | ||
412 | __func__, iport); | ||
419 | 413 | ||
420 | dev_dbg(&isci_port->isci_host->pdev->dev, | 414 | init_completion(&iport->hard_reset_complete); |
421 | "%s: isci_port = %p\n", | ||
422 | __func__, isci_port); | ||
423 | |||
424 | BUG_ON(isci_port == NULL); | ||
425 | |||
426 | init_completion(&isci_port->hard_reset_complete); | ||
427 | 415 | ||
428 | spin_lock_irqsave(&isci_port->isci_host->scic_lock, flags); | 416 | spin_lock_irqsave(&ihost->scic_lock, flags); |
429 | 417 | ||
430 | #define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT | 418 | #define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT |
431 | status = scic_port_hard_reset(isci_port->sci_port_handle, | 419 | status = scic_port_hard_reset(iport->sci_port_handle, |
432 | ISCI_PORT_RESET_TIMEOUT); | 420 | ISCI_PORT_RESET_TIMEOUT); |
433 | 421 | ||
434 | spin_unlock_irqrestore(&isci_port->isci_host->scic_lock, flags); | 422 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
435 | 423 | ||
436 | if (status == SCI_SUCCESS) { | 424 | if (status == SCI_SUCCESS) { |
437 | wait_for_completion(&isci_port->hard_reset_complete); | 425 | wait_for_completion(&iport->hard_reset_complete); |
438 | 426 | ||
439 | dev_dbg(&isci_port->isci_host->pdev->dev, | 427 | dev_dbg(&ihost->pdev->dev, |
440 | "%s: isci_port = %p; hard reset completion\n", | 428 | "%s: iport = %p; hard reset completion\n", |
441 | __func__, isci_port); | 429 | __func__, iport); |
442 | 430 | ||
443 | if (isci_port->hard_reset_status != SCI_SUCCESS) | 431 | if (iport->hard_reset_status != SCI_SUCCESS) |
444 | ret = TMF_RESP_FUNC_FAILED; | 432 | ret = TMF_RESP_FUNC_FAILED; |
445 | } else { | 433 | } else { |
446 | ret = TMF_RESP_FUNC_FAILED; | 434 | ret = TMF_RESP_FUNC_FAILED; |
447 | 435 | ||
448 | dev_err(&isci_port->isci_host->pdev->dev, | 436 | dev_err(&ihost->pdev->dev, |
449 | "%s: isci_port = %p; scic_port_hard_reset call" | 437 | "%s: iport = %p; scic_port_hard_reset call" |
450 | " failed 0x%x\n", | 438 | " failed 0x%x\n", |
451 | __func__, isci_port, status); | 439 | __func__, iport, status); |
452 | 440 | ||
453 | } | 441 | } |
454 | 442 | ||
@@ -456,19 +444,12 @@ int isci_port_perform_hard_reset( | |||
456 | * the same as link failures on all phys in the port. | 444 | * the same as link failures on all phys in the port. |
457 | */ | 445 | */ |
458 | if (ret != TMF_RESP_FUNC_COMPLETE) { | 446 | if (ret != TMF_RESP_FUNC_COMPLETE) { |
459 | BUG_ON(isci_port->isci_host == NULL); | 447 | dev_err(&ihost->pdev->dev, |
460 | 448 | "%s: iport = %p; hard reset failed " | |
461 | dev_err(&isci_port->isci_host->pdev->dev, | ||
462 | "%s: isci_port = %p; hard reset failed " | ||
463 | "(0x%x) - sending link down to libsas for phy %p\n", | 449 | "(0x%x) - sending link down to libsas for phy %p\n", |
464 | __func__, | 450 | __func__, iport, iport->hard_reset_status, iphy); |
465 | isci_port, | 451 | |
466 | isci_port->hard_reset_status, | 452 | isci_port_link_down(ihost, iphy, iport); |
467 | isci_phy); | ||
468 | |||
469 | isci_port_link_down(isci_port->isci_host, | ||
470 | isci_phy, | ||
471 | isci_port); | ||
472 | } | 453 | } |
473 | 454 | ||
474 | return ret; | 455 | return ret; |
@@ -491,8 +472,7 @@ void isci_port_invalid_link_up(struct scic_sds_controller *scic, | |||
491 | struct scic_sds_port *sci_port, | 472 | struct scic_sds_port *sci_port, |
492 | struct scic_sds_phy *phy) | 473 | struct scic_sds_phy *phy) |
493 | { | 474 | { |
494 | struct isci_host *ihost = | 475 | struct isci_host *ihost = sci_object_get_association(scic); |
495 | (struct isci_host *)sci_object_get_association(scic); | ||
496 | 476 | ||
497 | dev_warn(&ihost->pdev->dev, "Invalid link up!\n"); | 477 | dev_warn(&ihost->pdev->dev, "Invalid link up!\n"); |
498 | } | 478 | } |
diff --git a/drivers/scsi/isci/port.h b/drivers/scsi/isci/port.h index dfdd12a0f68e..76546fd5b7d0 100644 --- a/drivers/scsi/isci/port.h +++ b/drivers/scsi/isci/port.h | |||
@@ -143,9 +143,8 @@ void isci_port_hard_reset_complete( | |||
143 | struct isci_port *isci_port, | 143 | struct isci_port *isci_port, |
144 | enum sci_status completion_status); | 144 | enum sci_status completion_status); |
145 | 145 | ||
146 | int isci_port_perform_hard_reset( | 146 | int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport, |
147 | struct isci_port *isci_port_ptr, | 147 | struct isci_phy *iphy); |
148 | struct isci_phy *isci_phy_ptr); | ||
149 | 148 | ||
150 | void isci_port_invalid_link_up( | 149 | void isci_port_invalid_link_up( |
151 | struct scic_sds_controller *scic, | 150 | struct scic_sds_controller *scic, |
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index 0fdaa6d62c1b..ab638ec5881c 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -218,33 +218,20 @@ static enum sci_status isci_remote_device_construct( | |||
218 | return status; | 218 | return status; |
219 | } | 219 | } |
220 | 220 | ||
221 | 221 | void isci_remote_device_nuke_requests(struct isci_host *ihost, struct isci_remote_device *idev) | |
222 | /** | ||
223 | * isci_remote_device_nuke_requests() - This function terminates all requests | ||
224 | * for a given remote device. | ||
225 | * @isci_device: This parameter specifies the remote device | ||
226 | * | ||
227 | */ | ||
228 | void isci_remote_device_nuke_requests( | ||
229 | struct isci_remote_device *isci_device) | ||
230 | { | 222 | { |
231 | DECLARE_COMPLETION_ONSTACK(aborted_task_completion); | 223 | DECLARE_COMPLETION_ONSTACK(aborted_task_completion); |
232 | struct isci_host *isci_host; | ||
233 | 224 | ||
234 | isci_host = isci_device->isci_port->isci_host; | 225 | dev_dbg(&ihost->pdev->dev, |
235 | 226 | "%s: idev = %p\n", __func__, idev); | |
236 | dev_dbg(&isci_host->pdev->dev, | ||
237 | "%s: isci_device = %p\n", __func__, isci_device); | ||
238 | 227 | ||
239 | /* Cleanup all requests pending for this device. */ | 228 | /* Cleanup all requests pending for this device. */ |
240 | isci_terminate_pending_requests(isci_host, isci_device, terminating); | 229 | isci_terminate_pending_requests(ihost, idev, terminating); |
241 | 230 | ||
242 | dev_dbg(&isci_host->pdev->dev, | 231 | dev_dbg(&ihost->pdev->dev, |
243 | "%s: isci_device = %p, done\n", __func__, isci_device); | 232 | "%s: idev = %p, done\n", __func__, idev); |
244 | } | 233 | } |
245 | 234 | ||
246 | |||
247 | |||
248 | /** | 235 | /** |
249 | * This function builds the isci_remote_device when a libsas dev_found message | 236 | * This function builds the isci_remote_device when a libsas dev_found message |
250 | * is received. | 237 | * is received. |
@@ -380,7 +367,7 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem | |||
380 | isci_remote_device_change_state(idev, isci_stopping); | 367 | isci_remote_device_change_state(idev, isci_stopping); |
381 | 368 | ||
382 | /* Kill all outstanding requests. */ | 369 | /* Kill all outstanding requests. */ |
383 | isci_remote_device_nuke_requests(idev); | 370 | isci_remote_device_nuke_requests(ihost, idev); |
384 | 371 | ||
385 | set_bit(IDEV_STOP_PENDING, &idev->flags); | 372 | set_bit(IDEV_STOP_PENDING, &idev->flags); |
386 | 373 | ||
@@ -409,7 +396,7 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem | |||
409 | */ | 396 | */ |
410 | void isci_remote_device_gone(struct domain_device *dev) | 397 | void isci_remote_device_gone(struct domain_device *dev) |
411 | { | 398 | { |
412 | struct isci_host *ihost = dev->port->ha->lldd_ha; | 399 | struct isci_host *ihost = dev_to_ihost(dev); |
413 | struct isci_remote_device *idev = dev->lldd_dev; | 400 | struct isci_remote_device *idev = dev->lldd_dev; |
414 | 401 | ||
415 | dev_dbg(&ihost->pdev->dev, | 402 | dev_dbg(&ihost->pdev->dev, |
@@ -431,7 +418,7 @@ void isci_remote_device_gone(struct domain_device *dev) | |||
431 | */ | 418 | */ |
432 | int isci_remote_device_found(struct domain_device *domain_dev) | 419 | int isci_remote_device_found(struct domain_device *domain_dev) |
433 | { | 420 | { |
434 | struct isci_host *isci_host; | 421 | struct isci_host *isci_host = dev_to_ihost(domain_dev); |
435 | struct isci_port *isci_port; | 422 | struct isci_port *isci_port; |
436 | struct isci_phy *isci_phy; | 423 | struct isci_phy *isci_phy; |
437 | struct asd_sas_port *sas_port; | 424 | struct asd_sas_port *sas_port; |
@@ -439,8 +426,6 @@ int isci_remote_device_found(struct domain_device *domain_dev) | |||
439 | struct isci_remote_device *isci_device; | 426 | struct isci_remote_device *isci_device; |
440 | enum sci_status status; | 427 | enum sci_status status; |
441 | 428 | ||
442 | isci_host = isci_host_from_sas_ha(domain_dev->port->ha); | ||
443 | |||
444 | dev_dbg(&isci_host->pdev->dev, | 429 | dev_dbg(&isci_host->pdev->dev, |
445 | "%s: domain_device = %p\n", __func__, domain_dev); | 430 | "%s: domain_device = %p\n", __func__, domain_dev); |
446 | 431 | ||
@@ -556,41 +541,22 @@ bool isci_device_is_reset_pending( | |||
556 | * | 541 | * |
557 | * true if there is a reset pending for the device. | 542 | * true if there is a reset pending for the device. |
558 | */ | 543 | */ |
559 | void isci_device_clear_reset_pending(struct isci_remote_device *isci_device) | 544 | void isci_device_clear_reset_pending(struct isci_host *ihost, struct isci_remote_device *idev) |
560 | { | 545 | { |
561 | struct isci_request *isci_request; | 546 | struct isci_request *isci_request; |
562 | struct isci_request *tmp_req; | 547 | struct isci_request *tmp_req; |
563 | struct isci_host *isci_host = NULL; | ||
564 | unsigned long flags = 0; | 548 | unsigned long flags = 0; |
565 | 549 | ||
566 | /* FIXME more port gone confusion, and this time it makes the | 550 | dev_dbg(&ihost->pdev->dev, "%s: idev=%p, ihost=%p\n", |
567 | * locking "fun" | 551 | __func__, idev, ihost); |
568 | */ | ||
569 | if (isci_device->isci_port != NULL) | ||
570 | isci_host = isci_device->isci_port->isci_host; | ||
571 | |||
572 | /* | ||
573 | * FIXME when the isci_host gets sorted out | ||
574 | * use dev_dbg() | ||
575 | */ | ||
576 | pr_debug("%s: isci_device=%p, isci_host=%p\n", | ||
577 | __func__, isci_device, isci_host); | ||
578 | 552 | ||
579 | if (isci_host != NULL) | 553 | spin_lock_irqsave(&ihost->scic_lock, flags); |
580 | spin_lock_irqsave(&isci_host->scic_lock, flags); | ||
581 | else | ||
582 | pr_err("%s: isci_device %p; isci_host == NULL!\n", | ||
583 | __func__, isci_device); | ||
584 | 554 | ||
585 | /* Clear reset pending on all pending requests. */ | 555 | /* Clear reset pending on all pending requests. */ |
586 | list_for_each_entry_safe(isci_request, tmp_req, | 556 | list_for_each_entry_safe(isci_request, tmp_req, |
587 | &isci_device->reqs_in_process, dev_node) { | 557 | &idev->reqs_in_process, dev_node) { |
588 | /* | 558 | dev_dbg(&ihost->pdev->dev, "%s: idev = %p request = %p\n", |
589 | * FIXME when the conditional spinlock is gone | 559 | __func__, idev, isci_request); |
590 | * change to dev_dbg() | ||
591 | */ | ||
592 | pr_debug("%s: isci_device = %p request = %p\n", | ||
593 | __func__, isci_device, isci_request); | ||
594 | 560 | ||
595 | if (isci_request->ttype == io_task) { | 561 | if (isci_request->ttype == io_task) { |
596 | 562 | ||
@@ -603,9 +569,7 @@ void isci_device_clear_reset_pending(struct isci_remote_device *isci_device) | |||
603 | spin_unlock_irqrestore(&task->task_state_lock, flags2); | 569 | spin_unlock_irqrestore(&task->task_state_lock, flags2); |
604 | } | 570 | } |
605 | } | 571 | } |
606 | 572 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | |
607 | if (isci_host != NULL) | ||
608 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | ||
609 | } | 573 | } |
610 | 574 | ||
611 | /** | 575 | /** |
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h index cf5302abb8b2..9925316ac55a 100644 --- a/drivers/scsi/isci/remote_device.h +++ b/drivers/scsi/isci/remote_device.h | |||
@@ -78,59 +78,29 @@ static inline struct scic_sds_remote_device *to_sci_dev(struct isci_remote_devic | |||
78 | return (struct scic_sds_remote_device *) &idev[1]; | 78 | return (struct scic_sds_remote_device *) &idev[1]; |
79 | } | 79 | } |
80 | 80 | ||
81 | #define to_isci_remote_device(p) \ | ||
82 | container_of(p, struct isci_remote_device, sci_remote_device); | ||
83 | |||
84 | #define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000 | 81 | #define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000 |
85 | 82 | ||
86 | 83 | void isci_remote_device_start_complete(struct isci_host *ihost, | |
87 | /** | 84 | struct isci_remote_device *idev, |
88 | * isci_dev_from_domain_dev() - This accessor retrieves the remote_device | 85 | enum sci_status); |
89 | * object reference from the Linux domain_device reference. | 86 | void isci_remote_device_stop_complete(struct isci_host *ihost, |
90 | * @domdev,: This parameter points to the Linux domain_device object . | 87 | struct isci_remote_device *idev, |
91 | * | 88 | enum sci_status); |
92 | * A reference to the associated isci remote device. | ||
93 | */ | ||
94 | #define isci_dev_from_domain_dev(domdev) \ | ||
95 | ((struct isci_remote_device *)(domdev)->lldd_dev) | ||
96 | |||
97 | void isci_remote_device_start_complete( | ||
98 | struct isci_host *, | ||
99 | struct isci_remote_device *, | ||
100 | enum sci_status); | ||
101 | |||
102 | void isci_remote_device_stop_complete( | ||
103 | struct isci_host *, | ||
104 | struct isci_remote_device *, | ||
105 | enum sci_status); | ||
106 | |||
107 | enum sci_status isci_remote_device_stop(struct isci_host *ihost, | 89 | enum sci_status isci_remote_device_stop(struct isci_host *ihost, |
108 | struct isci_remote_device *idev); | 90 | struct isci_remote_device *idev); |
109 | void isci_remote_device_nuke_requests( | 91 | void isci_remote_device_nuke_requests(struct isci_host *ihost, |
110 | struct isci_remote_device *isci_device); | 92 | struct isci_remote_device *idev); |
111 | |||
112 | void isci_remote_device_ready(struct isci_host *ihost, | 93 | void isci_remote_device_ready(struct isci_host *ihost, |
113 | struct isci_remote_device *idev); | 94 | struct isci_remote_device *idev); |
114 | |||
115 | void isci_remote_device_not_ready(struct isci_host *ihost, | 95 | void isci_remote_device_not_ready(struct isci_host *ihost, |
116 | struct isci_remote_device *idev, u32 reason); | 96 | struct isci_remote_device *idev, u32 reason); |
117 | 97 | void isci_remote_device_gone(struct domain_device *domain_dev); | |
118 | void isci_remote_device_gone( | 98 | int isci_remote_device_found(struct domain_device *domain_dev); |
119 | struct domain_device *domain_dev); | 99 | bool isci_device_is_reset_pending(struct isci_host *ihost, |
120 | 100 | struct isci_remote_device *idev); | |
121 | int isci_remote_device_found( | 101 | void isci_device_clear_reset_pending(struct isci_host *ihost, |
122 | struct domain_device *domain_dev); | 102 | struct isci_remote_device *idev); |
123 | 103 | void isci_remote_device_change_state(struct isci_remote_device *idev, | |
124 | bool isci_device_is_reset_pending( | 104 | enum isci_status status); |
125 | struct isci_host *isci_host, | ||
126 | struct isci_remote_device *isci_device); | ||
127 | |||
128 | void isci_device_clear_reset_pending( | ||
129 | struct isci_remote_device *isci_device); | ||
130 | |||
131 | void isci_remote_device_change_state( | ||
132 | struct isci_remote_device *isci_device, | ||
133 | enum isci_status status); | ||
134 | 105 | ||
135 | #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */ | 106 | #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */ |
136 | |||
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index b519373597a5..37ffedc94ac0 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -379,7 +379,7 @@ int isci_request_execute( | |||
379 | struct isci_request *request; | 379 | struct isci_request *request; |
380 | unsigned long flags; | 380 | unsigned long flags; |
381 | 381 | ||
382 | isci_device = isci_dev_from_domain_dev(task->dev); | 382 | isci_device = task->dev->lldd_dev; |
383 | sci_device = to_sci_dev(isci_device); | 383 | sci_device = to_sci_dev(isci_device); |
384 | 384 | ||
385 | /* do common allocation and init of request object. */ | 385 | /* do common allocation and init of request object. */ |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index 5bcea60fd8c4..c6c97ad58c9f 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -146,7 +146,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task, | |||
146 | */ | 146 | */ |
147 | int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | 147 | int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) |
148 | { | 148 | { |
149 | struct isci_host *ihost = task->dev->port->ha->lldd_ha; | 149 | struct isci_host *ihost = dev_to_ihost(task->dev); |
150 | struct isci_request *request = NULL; | 150 | struct isci_request *request = NULL; |
151 | struct isci_remote_device *device; | 151 | struct isci_remote_device *device; |
152 | unsigned long flags; | 152 | unsigned long flags; |
@@ -169,7 +169,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
169 | "task = %p, num = %d; dev = %p; cmd = %p\n", | 169 | "task = %p, num = %d; dev = %p; cmd = %p\n", |
170 | task, num, task->dev, task->uldd_task); | 170 | task, num, task->dev, task->uldd_task); |
171 | 171 | ||
172 | device = isci_dev_from_domain_dev(task->dev); | 172 | device = task->dev->lldd_dev; |
173 | 173 | ||
174 | if (device) | 174 | if (device) |
175 | device_status = device->status; | 175 | device_status = device->status; |
@@ -593,7 +593,6 @@ static void isci_task_build_abort_task_tmf( | |||
593 | 593 | ||
594 | static struct isci_request *isci_task_get_request_from_task( | 594 | static struct isci_request *isci_task_get_request_from_task( |
595 | struct sas_task *task, | 595 | struct sas_task *task, |
596 | struct isci_host **isci_host, | ||
597 | struct isci_remote_device **isci_device) | 596 | struct isci_remote_device **isci_device) |
598 | { | 597 | { |
599 | 598 | ||
@@ -609,9 +608,6 @@ static struct isci_request *isci_task_get_request_from_task( | |||
609 | (task->task_state_flags & SAS_TASK_AT_INITIATOR) && | 608 | (task->task_state_flags & SAS_TASK_AT_INITIATOR) && |
610 | (request != NULL)) { | 609 | (request != NULL)) { |
611 | 610 | ||
612 | if (isci_host != NULL) | ||
613 | *isci_host = request->isci_host; | ||
614 | |||
615 | if (isci_device != NULL) | 611 | if (isci_device != NULL) |
616 | *isci_device = request->isci_device; | 612 | *isci_device = request->isci_device; |
617 | } | 613 | } |
@@ -1027,26 +1023,17 @@ static int isci_task_send_lu_reset_sas( | |||
1027 | * | 1023 | * |
1028 | * status, zero indicates success. | 1024 | * status, zero indicates success. |
1029 | */ | 1025 | */ |
1030 | int isci_task_lu_reset( | 1026 | int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun) |
1031 | struct domain_device *domain_device, | ||
1032 | u8 *lun) | ||
1033 | { | 1027 | { |
1034 | struct isci_host *isci_host = NULL; | 1028 | struct isci_host *isci_host = dev_to_ihost(domain_device); |
1035 | struct isci_remote_device *isci_device = NULL; | 1029 | struct isci_remote_device *isci_device = NULL; |
1036 | int ret; | 1030 | int ret; |
1037 | bool device_stopping = false; | 1031 | bool device_stopping = false; |
1038 | 1032 | ||
1039 | if (domain_device == NULL) { | 1033 | isci_device = domain_device->lldd_dev; |
1040 | pr_warn("%s: domain_device == NULL\n", __func__); | ||
1041 | return TMF_RESP_FUNC_FAILED; | ||
1042 | } | ||
1043 | |||
1044 | isci_device = isci_dev_from_domain_dev(domain_device); | ||
1045 | |||
1046 | if (domain_device->port != NULL) | ||
1047 | isci_host = isci_host_from_sas_ha(domain_device->port->ha); | ||
1048 | 1034 | ||
1049 | pr_debug("%s: domain_device=%p, isci_host=%p; isci_device=%p\n", | 1035 | dev_dbg(&isci_host->pdev->dev, |
1036 | "%s: domain_device=%p, isci_host=%p; isci_device=%p\n", | ||
1050 | __func__, domain_device, isci_host, isci_device); | 1037 | __func__, domain_device, isci_host, isci_device); |
1051 | 1038 | ||
1052 | if (isci_device != NULL) | 1039 | if (isci_device != NULL) |
@@ -1057,24 +1044,18 @@ int isci_task_lu_reset( | |||
1057 | * device's list, fail this LUN reset request in order to | 1044 | * device's list, fail this LUN reset request in order to |
1058 | * escalate to the device reset. | 1045 | * escalate to the device reset. |
1059 | */ | 1046 | */ |
1060 | if ((isci_device == NULL) || | 1047 | if (!isci_device || device_stopping || |
1061 | (isci_host == NULL) || | 1048 | isci_device_is_reset_pending(isci_host, isci_device)) { |
1062 | ((isci_host != NULL) && | ||
1063 | (isci_device != NULL) && | ||
1064 | (device_stopping || | ||
1065 | (isci_device_is_reset_pending(isci_host, isci_device))))) { | ||
1066 | dev_warn(&isci_host->pdev->dev, | 1049 | dev_warn(&isci_host->pdev->dev, |
1067 | "%s: No dev (%p), no host (%p), or " | 1050 | "%s: No dev (%p), or " |
1068 | "RESET PENDING: domain_device=%p\n", | 1051 | "RESET PENDING: domain_device=%p\n", |
1069 | __func__, isci_device, isci_host, domain_device); | 1052 | __func__, isci_device, domain_device); |
1070 | return TMF_RESP_FUNC_FAILED; | 1053 | return TMF_RESP_FUNC_FAILED; |
1071 | } | 1054 | } |
1072 | 1055 | ||
1073 | /* Send the task management part of the reset. */ | 1056 | /* Send the task management part of the reset. */ |
1074 | if (sas_protocol_ata(domain_device->tproto)) { | 1057 | if (sas_protocol_ata(domain_device->tproto)) { |
1075 | ret = isci_task_send_lu_reset_sata( | 1058 | ret = isci_task_send_lu_reset_sata(isci_host, isci_device, lun); |
1076 | isci_host, isci_device, lun | ||
1077 | ); | ||
1078 | } else | 1059 | } else |
1079 | ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); | 1060 | ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); |
1080 | 1061 | ||
@@ -1173,11 +1154,11 @@ static void isci_abort_task_process_cb( | |||
1173 | */ | 1154 | */ |
1174 | int isci_task_abort_task(struct sas_task *task) | 1155 | int isci_task_abort_task(struct sas_task *task) |
1175 | { | 1156 | { |
1157 | struct isci_host *isci_host = dev_to_ihost(task->dev); | ||
1176 | DECLARE_COMPLETION_ONSTACK(aborted_io_completion); | 1158 | DECLARE_COMPLETION_ONSTACK(aborted_io_completion); |
1177 | struct isci_request *old_request = NULL; | 1159 | struct isci_request *old_request = NULL; |
1178 | enum isci_request_status old_state; | 1160 | enum isci_request_status old_state; |
1179 | struct isci_remote_device *isci_device = NULL; | 1161 | struct isci_remote_device *isci_device = NULL; |
1180 | struct isci_host *isci_host = NULL; | ||
1181 | struct isci_tmf tmf; | 1162 | struct isci_tmf tmf; |
1182 | int ret = TMF_RESP_FUNC_FAILED; | 1163 | int ret = TMF_RESP_FUNC_FAILED; |
1183 | unsigned long flags; | 1164 | unsigned long flags; |
@@ -1189,8 +1170,7 @@ int isci_task_abort_task(struct sas_task *task) | |||
1189 | * in the device, because tasks driving resets may land here | 1170 | * in the device, because tasks driving resets may land here |
1190 | * after completion in the core. | 1171 | * after completion in the core. |
1191 | */ | 1172 | */ |
1192 | old_request = isci_task_get_request_from_task(task, &isci_host, | 1173 | old_request = isci_task_get_request_from_task(task, &isci_device); |
1193 | &isci_device); | ||
1194 | 1174 | ||
1195 | dev_dbg(&isci_host->pdev->dev, | 1175 | dev_dbg(&isci_host->pdev->dev, |
1196 | "%s: task = %p\n", __func__, task); | 1176 | "%s: task = %p\n", __func__, task); |
@@ -1610,37 +1590,29 @@ u32 isci_task_ssp_request_get_response_data_length( | |||
1610 | */ | 1590 | */ |
1611 | int isci_bus_reset_handler(struct scsi_cmnd *cmd) | 1591 | int isci_bus_reset_handler(struct scsi_cmnd *cmd) |
1612 | { | 1592 | { |
1593 | struct domain_device *dev = cmd_to_domain_dev(cmd); | ||
1594 | struct isci_host *isci_host = dev_to_ihost(dev); | ||
1613 | unsigned long flags = 0; | 1595 | unsigned long flags = 0; |
1614 | struct isci_host *isci_host = NULL; | ||
1615 | enum sci_status status; | 1596 | enum sci_status status; |
1616 | int base_status; | 1597 | int base_status; |
1617 | struct isci_remote_device *isci_dev | 1598 | struct isci_remote_device *isci_dev = dev->lldd_dev; |
1618 | = isci_dev_from_domain_dev( | ||
1619 | sdev_to_domain_dev(cmd->device)); | ||
1620 | 1599 | ||
1621 | dev_dbg(&cmd->device->sdev_gendev, | 1600 | dev_dbg(&isci_host->pdev->dev, |
1622 | "%s: cmd %p, isci_dev %p\n", | 1601 | "%s: cmd %p, isci_dev %p\n", |
1623 | __func__, cmd, isci_dev); | 1602 | __func__, cmd, isci_dev); |
1624 | 1603 | ||
1625 | if (!isci_dev) { | 1604 | if (!isci_dev) { |
1626 | dev_warn(&cmd->device->sdev_gendev, | 1605 | dev_warn(&isci_host->pdev->dev, |
1627 | "%s: isci_dev is GONE!\n", | 1606 | "%s: isci_dev is GONE!\n", |
1628 | __func__); | 1607 | __func__); |
1629 | 1608 | ||
1630 | return TMF_RESP_FUNC_COMPLETE; /* Nothing to reset. */ | 1609 | return TMF_RESP_FUNC_COMPLETE; /* Nothing to reset. */ |
1631 | } | 1610 | } |
1632 | 1611 | ||
1633 | if (isci_dev->isci_port != NULL) | 1612 | spin_lock_irqsave(&isci_host->scic_lock, flags); |
1634 | isci_host = isci_dev->isci_port->isci_host; | ||
1635 | |||
1636 | if (isci_host != NULL) | ||
1637 | spin_lock_irqsave(&isci_host->scic_lock, flags); | ||
1638 | |||
1639 | status = scic_remote_device_reset(to_sci_dev(isci_dev)); | 1613 | status = scic_remote_device_reset(to_sci_dev(isci_dev)); |
1640 | if (status != SCI_SUCCESS) { | 1614 | if (status != SCI_SUCCESS) { |
1641 | 1615 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | |
1642 | if (isci_host != NULL) | ||
1643 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | ||
1644 | 1616 | ||
1645 | scmd_printk(KERN_WARNING, cmd, | 1617 | scmd_printk(KERN_WARNING, cmd, |
1646 | "%s: scic_remote_device_reset(%p) returned %d!\n", | 1618 | "%s: scic_remote_device_reset(%p) returned %d!\n", |
@@ -1648,14 +1620,13 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) | |||
1648 | 1620 | ||
1649 | return TMF_RESP_FUNC_FAILED; | 1621 | return TMF_RESP_FUNC_FAILED; |
1650 | } | 1622 | } |
1651 | if (isci_host != NULL) | 1623 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); |
1652 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | ||
1653 | 1624 | ||
1654 | /* Make sure all pending requests are able to be fully terminated. */ | 1625 | /* Make sure all pending requests are able to be fully terminated. */ |
1655 | isci_device_clear_reset_pending(isci_dev); | 1626 | isci_device_clear_reset_pending(isci_host, isci_dev); |
1656 | 1627 | ||
1657 | /* Terminate in-progress I/O now. */ | 1628 | /* Terminate in-progress I/O now. */ |
1658 | isci_remote_device_nuke_requests(isci_dev); | 1629 | isci_remote_device_nuke_requests(isci_host, isci_dev); |
1659 | 1630 | ||
1660 | /* Call into the libsas default handler (which calls sas_phy_reset). */ | 1631 | /* Call into the libsas default handler (which calls sas_phy_reset). */ |
1661 | base_status = sas_eh_bus_reset_handler(cmd); | 1632 | base_status = sas_eh_bus_reset_handler(cmd); |
@@ -1672,13 +1643,9 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) | |||
1672 | } | 1643 | } |
1673 | 1644 | ||
1674 | /* WHAT TO DO HERE IF sas_phy_reset FAILS? */ | 1645 | /* WHAT TO DO HERE IF sas_phy_reset FAILS? */ |
1675 | 1646 | spin_lock_irqsave(&isci_host->scic_lock, flags); | |
1676 | if (isci_host != NULL) | ||
1677 | spin_lock_irqsave(&isci_host->scic_lock, flags); | ||
1678 | status = scic_remote_device_reset_complete(to_sci_dev(isci_dev)); | 1647 | status = scic_remote_device_reset_complete(to_sci_dev(isci_dev)); |
1679 | 1648 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | |
1680 | if (isci_host != NULL) | ||
1681 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | ||
1682 | 1649 | ||
1683 | if (status != SCI_SUCCESS) { | 1650 | if (status != SCI_SUCCESS) { |
1684 | scmd_printk(KERN_WARNING, cmd, | 1651 | scmd_printk(KERN_WARNING, cmd, |
@@ -1688,7 +1655,7 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd) | |||
1688 | } | 1655 | } |
1689 | /* WHAT TO DO HERE IF scic_remote_device_reset_complete FAILS? */ | 1656 | /* WHAT TO DO HERE IF scic_remote_device_reset_complete FAILS? */ |
1690 | 1657 | ||
1691 | dev_dbg(&cmd->device->sdev_gendev, | 1658 | dev_dbg(&isci_host->pdev->dev, |
1692 | "%s: cmd %p, isci_dev %p complete.\n", | 1659 | "%s: cmd %p, isci_dev %p complete.\n", |
1693 | __func__, cmd, isci_dev); | 1660 | __func__, cmd, isci_dev); |
1694 | 1661 | ||