aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/isci/events.c30
-rw-r--r--drivers/scsi/isci/host.c2
-rw-r--r--drivers/scsi/isci/host.h13
-rw-r--r--drivers/scsi/isci/remote_device.c98
-rw-r--r--drivers/scsi/isci/remote_device.h11
5 files changed, 69 insertions, 85 deletions
diff --git a/drivers/scsi/isci/events.c b/drivers/scsi/isci/events.c
index c5cbaedac041..9d58e458a37b 100644
--- a/drivers/scsi/isci/events.c
+++ b/drivers/scsi/isci/events.c
@@ -526,7 +526,7 @@ void isci_event_remote_device_start_complete(
526/** 526/**
527 * isci_event_remote_device_stop_complete() - This user callback method will 527 * isci_event_remote_device_stop_complete() - This user callback method will
528 * inform the user that a stop operation has completed. 528 * inform the user that a stop operation has completed.
529 * @controller: This parameter specifies the core controller associated with 529 * @scic: This parameter specifies the core controller associated with
530 * the completion callback. 530 * the completion callback.
531 * @remote_device: This parameter specifies the remote device associated with 531 * @remote_device: This parameter specifies the remote device associated with
532 * the completion callback. 532 * the completion callback.
@@ -534,28 +534,20 @@ void isci_event_remote_device_start_complete(
534 * operation. 534 * operation.
535 * 535 *
536 */ 536 */
537void isci_event_remote_device_stop_complete( 537void isci_event_remote_device_stop_complete(struct scic_sds_controller *scic,
538 struct scic_sds_controller *controller, 538 struct scic_sds_remote_device *sci_dev,
539 struct scic_sds_remote_device *remote_device, 539 enum sci_status completion_status)
540 enum sci_status completion_status)
541{ 540{
542 struct isci_host *isci_host; 541 struct isci_host *ihost;
543 struct isci_remote_device *isci_device; 542 struct isci_remote_device *idev;
544 543
545 isci_host = 544 ihost = sci_object_get_association(scic);
546 (struct isci_host *)sci_object_get_association(controller); 545 idev = sci_object_get_association(sci_dev);
547 546
548 isci_device = 547 dev_dbg(&ihost->pdev->dev,
549 (struct isci_remote_device *)sci_object_get_association( 548 "%s: idev = %p\n", __func__, idev);
550 remote_device
551 );
552
553 dev_dbg(&isci_host->pdev->dev,
554 "%s: isci_device = %p\n", __func__, isci_device);
555
556 isci_remote_device_stop_complete(
557 isci_host, isci_device, completion_status);
558 549
550 isci_remote_device_stop_complete(ihost, idev, completion_status);
559} 551}
560 552
561/** 553/**
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index da0c0da4198f..8d255666a657 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -345,7 +345,7 @@ void isci_host_deinit(struct isci_host *ihost)
345 345
346 list_for_each_entry_safe(idev, d, &port->remote_dev_list, node) { 346 list_for_each_entry_safe(idev, d, &port->remote_dev_list, node) {
347 isci_remote_device_change_state(idev, isci_stopping); 347 isci_remote_device_change_state(idev, isci_stopping);
348 isci_remote_device_stop(idev); 348 isci_remote_device_stop(ihost, idev);
349 } 349 }
350 } 350 }
351 351
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 7c1f0b5cee7d..6a6304c06976 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -212,6 +212,19 @@ static inline void wait_for_stop(struct isci_host *ihost)
212 wait_event(ihost->eventq, !test_bit(IHOST_STOP_PENDING, &ihost->flags)); 212 wait_event(ihost->eventq, !test_bit(IHOST_STOP_PENDING, &ihost->flags));
213} 213}
214 214
215static inline void wait_for_device_start(struct isci_host *ihost, struct isci_remote_device *idev)
216{
217 wait_event(ihost->eventq, !test_bit(IDEV_START_PENDING, &idev->flags));
218}
219
220static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
221{
222 /* todo switch to:
223 * wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags));
224 * once devices are statically allocated
225 */
226 wait_for_completion(idev->cmp);
227}
215 228
216/** 229/**
217 * isci_host_from_sas_ha() - This accessor retrieves the isci_host object 230 * isci_host_from_sas_ha() - This accessor retrieves the isci_host object
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c
index fc1f24449170..db2259ce003f 100644
--- a/drivers/scsi/isci/remote_device.c
+++ b/drivers/scsi/isci/remote_device.c
@@ -95,6 +95,11 @@ static void isci_remote_device_deconstruct(
95 scic_remote_device_destruct(to_sci_dev(isci_device)); 95 scic_remote_device_destruct(to_sci_dev(isci_device));
96 isci_device->domain_dev->lldd_dev = NULL; 96 isci_device->domain_dev->lldd_dev = NULL;
97 list_del(&isci_device->node); 97 list_del(&isci_device->node);
98
99 clear_bit(IDEV_STOP_PENDING, &isci_device->flags);
100 clear_bit(IDEV_START_PENDING, &isci_device->flags);
101 wake_up(&isci_host->eventq);
102 complete(isci_device->cmp);
98 kmem_cache_free(isci_kmem_cache, isci_device); 103 kmem_cache_free(isci_kmem_cache, isci_device);
99} 104}
100 105
@@ -279,30 +284,22 @@ isci_remote_device_alloc(struct isci_host *isci_host, struct isci_port *port)
279 * isci_remote_device_ready() - This function is called by the scic when the 284 * isci_remote_device_ready() - This function is called by the scic when the
280 * remote device is ready. We mark the isci device as ready and signal the 285 * remote device is ready. We mark the isci device as ready and signal the
281 * waiting proccess. 286 * waiting proccess.
282 * @isci_host: This parameter specifies the isci host object. 287 * @idev: This parameter specifies the remote device
283 * @isci_device: This parameter specifies the remote device
284 * 288 *
285 */ 289 */
286void isci_remote_device_ready(struct isci_remote_device *isci_device) 290void isci_remote_device_ready(struct isci_remote_device *idev)
287{ 291{
292 struct isci_host *ihost = idev->isci_port->isci_host;
288 unsigned long flags; 293 unsigned long flags;
289 294
290 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev, 295 dev_dbg(&ihost->pdev->dev,
291 "%s: isci_device = %p\n", __func__, isci_device); 296 "%s: isci_device = %p\n", __func__, idev);
292
293 /* device ready is actually a "ready for io" state. */
294 if (isci_device->status == isci_starting ||
295 isci_device->status == isci_ready) {
296 spin_lock_irqsave(&isci_device->isci_port->remote_device_lock,
297 flags);
298 isci_remote_device_change_state(isci_device, isci_ready_for_io);
299 if (isci_device->completion)
300 complete(isci_device->completion);
301 spin_unlock_irqrestore(
302 &isci_device->isci_port->remote_device_lock,
303 flags);
304 }
305 297
298 spin_lock_irqsave(&idev->isci_port->remote_device_lock, flags);
299 isci_remote_device_change_state(idev, isci_ready_for_io);
300 if (test_and_clear_bit(IDEV_START_PENDING, &idev->flags))
301 wake_up(&ihost->eventq);
302 spin_unlock_irqrestore(&idev->isci_port->remote_device_lock, flags);
306} 303}
307 304
308/** 305/**
@@ -341,8 +338,6 @@ void isci_remote_device_stop_complete(
341 struct isci_remote_device *isci_device, 338 struct isci_remote_device *isci_device,
342 enum sci_status status) 339 enum sci_status status)
343{ 340{
344 struct completion *completion = isci_device->completion;
345
346 dev_dbg(&isci_host->pdev->dev, 341 dev_dbg(&isci_host->pdev->dev,
347 "%s: complete isci_device = %p, status = 0x%x\n", 342 "%s: complete isci_device = %p, status = 0x%x\n",
348 __func__, 343 __func__,
@@ -354,9 +349,6 @@ void isci_remote_device_stop_complete(
354 /* after stop, we can tear down resources. */ 349 /* after stop, we can tear down resources. */
355 isci_remote_device_deconstruct(isci_host, isci_device); 350 isci_remote_device_deconstruct(isci_host, isci_device);
356 351
357 /* notify interested parties. */
358 if (completion)
359 complete(completion);
360} 352}
361 353
362/** 354/**
@@ -385,40 +377,33 @@ void isci_remote_device_start_complete(
385 * 377 *
386 * The status of the scic request to stop. 378 * The status of the scic request to stop.
387 */ 379 */
388enum sci_status isci_remote_device_stop( 380enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
389 struct isci_remote_device *isci_device)
390{ 381{
391 enum sci_status status; 382 enum sci_status status;
392 unsigned long flags; 383 unsigned long flags;
393
394 DECLARE_COMPLETION_ONSTACK(completion); 384 DECLARE_COMPLETION_ONSTACK(completion);
395 385
396 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev, 386 dev_dbg(&ihost->pdev->dev,
397 "%s: isci_device = %p\n", __func__, isci_device); 387 "%s: isci_device = %p\n", __func__, idev);
398
399 isci_remote_device_change_state(isci_device, isci_stopping);
400
401 /* We need comfirmation that stop completed. */
402 isci_device->completion = &completion;
403 388
404 BUG_ON(isci_device->isci_port == NULL); 389 isci_remote_device_change_state(idev, isci_stopping);
405 BUG_ON(isci_device->isci_port->isci_host == NULL); 390 set_bit(IDEV_STOP_PENDING, &idev->flags);
391 idev->cmp = &completion;
406 392
407 spin_lock_irqsave(&isci_device->isci_port->isci_host->scic_lock, flags); 393 spin_lock_irqsave(&ihost->scic_lock, flags);
408 394
409 status = scic_remote_device_stop(to_sci_dev(isci_device), 50); 395 status = scic_remote_device_stop(to_sci_dev(idev), 50);
410 396
411 spin_unlock_irqrestore(&isci_device->isci_port->isci_host->scic_lock, flags); 397 spin_unlock_irqrestore(&ihost->scic_lock, flags);
412 398
413 /* Wait for the stop complete callback. */ 399 /* Wait for the stop complete callback. */
414 if (status == SCI_SUCCESS) 400 if (status == SCI_SUCCESS)
415 wait_for_completion(&completion); 401 wait_for_device_stop(ihost, idev);
416 402
417 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev, 403 dev_dbg(&ihost->pdev->dev,
418 "%s: isci_device = %p - after completion wait\n", 404 "%s: idev = %p - after completion wait\n",
419 __func__, isci_device); 405 __func__, idev);
420 406
421 isci_device->completion = NULL;
422 return status; 407 return status;
423} 408}
424 409
@@ -428,18 +413,16 @@ enum sci_status isci_remote_device_stop(
428 * @domain_device: This parameter specifies the libsas domain device. 413 * @domain_device: This parameter specifies the libsas domain device.
429 * 414 *
430 */ 415 */
431void isci_remote_device_gone( 416void isci_remote_device_gone(struct domain_device *dev)
432 struct domain_device *domain_dev)
433{ 417{
434 struct isci_remote_device *isci_device = isci_dev_from_domain_dev( 418 struct isci_host *ihost = dev->port->ha->lldd_ha;
435 domain_dev); 419 struct isci_remote_device *idev = dev->lldd_dev;
436 420
437 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev, 421 dev_dbg(&ihost->pdev->dev,
438 "%s: domain_device = %p, isci_device = %p, isci_port = %p\n", 422 "%s: domain_device = %p, isci_device = %p, isci_port = %p\n",
439 __func__, domain_dev, isci_device, isci_device->isci_port); 423 __func__, dev, idev, idev->isci_port);
440 424
441 if (isci_device != NULL) 425 isci_remote_device_stop(ihost, idev);
442 isci_remote_device_stop(isci_device);
443} 426}
444 427
445 428
@@ -462,7 +445,6 @@ int isci_remote_device_found(struct domain_device *domain_dev)
462 struct asd_sas_phy *sas_phy; 445 struct asd_sas_phy *sas_phy;
463 struct isci_remote_device *isci_device; 446 struct isci_remote_device *isci_device;
464 enum sci_status status; 447 enum sci_status status;
465 DECLARE_COMPLETION_ONSTACK(completion);
466 448
467 isci_host = isci_host_from_sas_ha(domain_dev->port->ha); 449 isci_host = isci_host_from_sas_ha(domain_dev->port->ha);
468 450
@@ -498,17 +480,10 @@ int isci_remote_device_found(struct domain_device *domain_dev)
498 spin_lock_irqsave(&isci_port->remote_device_lock, flags); 480 spin_lock_irqsave(&isci_port->remote_device_lock, flags);
499 list_add_tail(&isci_device->node, &isci_port->remote_dev_list); 481 list_add_tail(&isci_device->node, &isci_port->remote_dev_list);
500 482
501 /* for the device ready event. */ 483 set_bit(IDEV_START_PENDING, &isci_device->flags);
502 isci_device->completion = &completion;
503
504 status = isci_remote_device_construct(isci_port, isci_device); 484 status = isci_remote_device_construct(isci_port, isci_device);
505
506 spin_unlock_irqrestore(&isci_port->remote_device_lock, flags); 485 spin_unlock_irqrestore(&isci_port->remote_device_lock, flags);
507 486
508 /* wait for the device ready callback. */
509 wait_for_completion(isci_device->completion);
510 isci_device->completion = NULL;
511
512 dev_dbg(&isci_host->pdev->dev, 487 dev_dbg(&isci_host->pdev->dev,
513 "%s: isci_device = %p\n", 488 "%s: isci_device = %p\n",
514 __func__, isci_device); 489 __func__, isci_device);
@@ -524,6 +499,9 @@ int isci_remote_device_found(struct domain_device *domain_dev)
524 return -ENODEV; 499 return -ENODEV;
525 } 500 }
526 501
502 /* wait for the device ready callback. */
503 wait_for_device_start(isci_host, isci_device);
504
527 return 0; 505 return 0;
528} 506}
529/** 507/**
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h
index af03039c12f1..3c22137c9f65 100644
--- a/drivers/scsi/isci/remote_device.h
+++ b/drivers/scsi/isci/remote_device.h
@@ -61,12 +61,14 @@ struct scic_sds_remote_device;
61 61
62struct isci_remote_device { 62struct isci_remote_device {
63 enum isci_status status; 63 enum isci_status status;
64 #define IDEV_START_PENDING 0
65 #define IDEV_STOP_PENDING 1
66 unsigned long flags;
67 struct completion *cmp;
64 struct isci_port *isci_port; 68 struct isci_port *isci_port;
65 struct domain_device *domain_dev; 69 struct domain_device *domain_dev;
66 struct completion *completion;
67 struct list_head node; 70 struct list_head node;
68 struct list_head reqs_in_process; 71 struct list_head reqs_in_process;
69 struct work_struct stop_work;
70 spinlock_t state_lock; 72 spinlock_t state_lock;
71}; 73};
72 74
@@ -102,9 +104,8 @@ void isci_remote_device_stop_complete(
102 struct isci_remote_device *, 104 struct isci_remote_device *,
103 enum sci_status); 105 enum sci_status);
104 106
105enum sci_status isci_remote_device_stop( 107enum sci_status isci_remote_device_stop(struct isci_host *ihost,
106 struct isci_remote_device *isci_device); 108 struct isci_remote_device *idev);
107
108void isci_remote_device_nuke_requests( 109void isci_remote_device_nuke_requests(
109 struct isci_remote_device *isci_device); 110 struct isci_remote_device *isci_device);
110 111