aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-03-31 16:10:44 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:00:36 -0400
commit4393aa4e6b9517a666f0ef6b774fd421a9dc4c68 (patch)
treeec5e0c222d16f2368e5589a11fc4ec191ceca365 /drivers
parent037afc7812e2b202fbc18218e6c0eff34dad36ed (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.c4
-rw-r--r--drivers/scsi/isci/host.h13
-rw-r--r--drivers/scsi/isci/phy.c2
-rw-r--r--drivers/scsi/isci/port.c68
-rw-r--r--drivers/scsi/isci/port.h5
-rw-r--r--drivers/scsi/isci/remote_device.c70
-rw-r--r--drivers/scsi/isci/remote_device.h62
-rw-r--r--drivers/scsi/isci/request.c2
-rw-r--r--drivers/scsi/isci/task.c87
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
130int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time) 130int 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
150void isci_host_scan_start(struct Scsi_Host *shost) 150void 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/** 236static 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 404int 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 */
411int 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
146int isci_port_perform_hard_reset( 146int 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
150void isci_port_invalid_link_up( 149void 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 221void 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 */
228void 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 */
410void isci_remote_device_gone(struct domain_device *dev) 397void 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 */
432int isci_remote_device_found(struct domain_device *domain_dev) 419int 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 */
559void isci_device_clear_reset_pending(struct isci_remote_device *isci_device) 544void 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 83void 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. 86void 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
97void isci_remote_device_start_complete(
98 struct isci_host *,
99 struct isci_remote_device *,
100 enum sci_status);
101
102void isci_remote_device_stop_complete(
103 struct isci_host *,
104 struct isci_remote_device *,
105 enum sci_status);
106
107enum sci_status isci_remote_device_stop(struct isci_host *ihost, 89enum sci_status isci_remote_device_stop(struct isci_host *ihost,
108 struct isci_remote_device *idev); 90 struct isci_remote_device *idev);
109void isci_remote_device_nuke_requests( 91void isci_remote_device_nuke_requests(struct isci_host *ihost,
110 struct isci_remote_device *isci_device); 92 struct isci_remote_device *idev);
111
112void isci_remote_device_ready(struct isci_host *ihost, 93void isci_remote_device_ready(struct isci_host *ihost,
113 struct isci_remote_device *idev); 94 struct isci_remote_device *idev);
114
115void isci_remote_device_not_ready(struct isci_host *ihost, 95void 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 97void isci_remote_device_gone(struct domain_device *domain_dev);
118void isci_remote_device_gone( 98int isci_remote_device_found(struct domain_device *domain_dev);
119 struct domain_device *domain_dev); 99bool isci_device_is_reset_pending(struct isci_host *ihost,
120 100 struct isci_remote_device *idev);
121int isci_remote_device_found( 101void isci_device_clear_reset_pending(struct isci_host *ihost,
122 struct domain_device *domain_dev); 102 struct isci_remote_device *idev);
123 103void isci_remote_device_change_state(struct isci_remote_device *idev,
124bool isci_device_is_reset_pending( 104 enum isci_status status);
125 struct isci_host *isci_host,
126 struct isci_remote_device *isci_device);
127
128void isci_device_clear_reset_pending(
129 struct isci_remote_device *isci_device);
130
131void 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 */
147int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) 147int 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
594static struct isci_request *isci_task_get_request_from_task( 594static 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 */
1030int isci_task_lu_reset( 1026int 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 */
1174int isci_task_abort_task(struct sas_task *task) 1155int 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 */
1611int isci_bus_reset_handler(struct scsi_cmnd *cmd) 1591int 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