aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-11-17 20:59:52 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 14:55:42 -0500
commitb91bb296188118eea9fdc6093cfcf76bbe8589ba (patch)
tree8fe9dda8894514f9cd1184368eab975583c12f3c /drivers/scsi/libsas
parent87c8331fcf72e501c3a3c0cdc5c9391ec72f7cf2 (diff)
[SCSI] libsas: use ->set_dmamode to notify lldds of NCQ parameters
sas_discover_sata() notifies lldds of sata devices twice. Once to allow the 'identify' to be sent, and a second time to allow aic94xx (the only libsas driver that cares about sata_dev.identify) to setup NCQ parameters before the device becomes known to the midlayer. Replace this double notification and intervening 'identify' with an explicit ->lldd_ata_set_dmamode notification. With this change all ata internal commands are issued by libata, so we no longer need sas_issue_ata_cmd(). The data from the identify command only needs to be cached in one location so ata_device.id replaces domain_device.sata_dev.identify. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r--drivers/scsi/libsas/sas_ata.c324
-rw-r--r--drivers/scsi/libsas/sas_discover.c5
2 files changed, 20 insertions, 309 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 4b6365c6410f..71af919b856c 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -367,6 +367,17 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc)
367 } 367 }
368} 368}
369 369
370
371static void sas_ata_set_dmamode(struct ata_port *ap, struct ata_device *ata_dev)
372{
373 struct domain_device *dev = ap->private_data;
374 struct sas_internal *i =
375 to_sas_internal(dev->port->ha->core.shost->transportt);
376
377 if (i->dft->lldd_ata_set_dmamode)
378 i->dft->lldd_ata_set_dmamode(dev);
379}
380
370static struct ata_port_operations sas_sata_ops = { 381static struct ata_port_operations sas_sata_ops = {
371 .prereset = ata_std_prereset, 382 .prereset = ata_std_prereset,
372 .softreset = sas_ata_soft_reset, 383 .softreset = sas_ata_soft_reset,
@@ -380,6 +391,7 @@ static struct ata_port_operations sas_sata_ops = {
380 .qc_fill_rtf = sas_ata_qc_fill_rtf, 391 .qc_fill_rtf = sas_ata_qc_fill_rtf,
381 .port_start = ata_sas_port_start, 392 .port_start = ata_sas_port_start,
382 .port_stop = ata_sas_port_stop, 393 .port_stop = ata_sas_port_stop,
394 .set_dmamode = sas_ata_set_dmamode,
383}; 395};
384 396
385static struct ata_port_info sata_port_info = { 397static struct ata_port_info sata_port_info = {
@@ -442,163 +454,6 @@ void sas_ata_task_abort(struct sas_task *task)
442 complete(waiting); 454 complete(waiting);
443} 455}
444 456
445static void sas_task_timedout(unsigned long _task)
446{
447 struct sas_task *task = (void *) _task;
448 unsigned long flags;
449
450 spin_lock_irqsave(&task->task_state_lock, flags);
451 if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
452 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
453 spin_unlock_irqrestore(&task->task_state_lock, flags);
454
455 complete(&task->completion);
456}
457
458static void sas_disc_task_done(struct sas_task *task)
459{
460 if (!del_timer(&task->timer))
461 return;
462 complete(&task->completion);
463}
464
465#define SAS_DEV_TIMEOUT 10
466
467/**
468 * sas_execute_task -- Basic task processing for discovery
469 * @task: the task to be executed
470 * @buffer: pointer to buffer to do I/O
471 * @size: size of @buffer
472 * @dma_dir: DMA direction. DMA_xxx
473 */
474static int sas_execute_task(struct sas_task *task, void *buffer, int size,
475 enum dma_data_direction dma_dir)
476{
477 int res = 0;
478 struct scatterlist *scatter = NULL;
479 struct task_status_struct *ts = &task->task_status;
480 int num_scatter = 0;
481 int retries = 0;
482 struct sas_internal *i =
483 to_sas_internal(task->dev->port->ha->core.shost->transportt);
484
485 if (dma_dir != DMA_NONE) {
486 scatter = kzalloc(sizeof(*scatter), GFP_KERNEL);
487 if (!scatter)
488 goto out;
489
490 sg_init_one(scatter, buffer, size);
491 num_scatter = 1;
492 }
493
494 task->task_proto = task->dev->tproto;
495 task->scatter = scatter;
496 task->num_scatter = num_scatter;
497 task->total_xfer_len = size;
498 task->data_dir = dma_dir;
499 task->task_done = sas_disc_task_done;
500 if (dma_dir != DMA_NONE &&
501 sas_protocol_ata(task->task_proto)) {
502 task->num_scatter = dma_map_sg(task->dev->port->ha->dev,
503 task->scatter,
504 task->num_scatter,
505 task->data_dir);
506 }
507
508 for (retries = 0; retries < 5; retries++) {
509 task->task_state_flags = SAS_TASK_STATE_PENDING;
510 init_completion(&task->completion);
511
512 task->timer.data = (unsigned long) task;
513 task->timer.function = sas_task_timedout;
514 task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ;
515 add_timer(&task->timer);
516
517 res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
518 if (res) {
519 del_timer(&task->timer);
520 SAS_DPRINTK("executing SAS discovery task failed:%d\n",
521 res);
522 goto ex_err;
523 }
524 wait_for_completion(&task->completion);
525 res = -ECOMM;
526 if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
527 int res2;
528 SAS_DPRINTK("task aborted, flags:0x%x\n",
529 task->task_state_flags);
530 res2 = i->dft->lldd_abort_task(task);
531 SAS_DPRINTK("came back from abort task\n");
532 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
533 if (res2 == TMF_RESP_FUNC_COMPLETE)
534 continue; /* Retry the task */
535 else
536 goto ex_err;
537 }
538 }
539 if (task->task_status.stat == SAM_STAT_BUSY ||
540 task->task_status.stat == SAM_STAT_TASK_SET_FULL ||
541 task->task_status.stat == SAS_QUEUE_FULL) {
542 SAS_DPRINTK("task: q busy, sleeping...\n");
543 schedule_timeout_interruptible(HZ);
544 } else if (task->task_status.stat == SAM_STAT_CHECK_CONDITION) {
545 struct scsi_sense_hdr shdr;
546
547 if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size,
548 &shdr)) {
549 SAS_DPRINTK("couldn't normalize sense\n");
550 continue;
551 }
552 if ((shdr.sense_key == 6 && shdr.asc == 0x29) ||
553 (shdr.sense_key == 2 && shdr.asc == 4 &&
554 shdr.ascq == 1)) {
555 SAS_DPRINTK("device %016llx LUN: %016llx "
556 "powering up or not ready yet, "
557 "sleeping...\n",
558 SAS_ADDR(task->dev->sas_addr),
559 SAS_ADDR(task->ssp_task.LUN));
560
561 schedule_timeout_interruptible(5*HZ);
562 } else if (shdr.sense_key == 1) {
563 res = 0;
564 break;
565 } else if (shdr.sense_key == 5) {
566 break;
567 } else {
568 SAS_DPRINTK("dev %016llx LUN: %016llx "
569 "sense key:0x%x ASC:0x%x ASCQ:0x%x"
570 "\n",
571 SAS_ADDR(task->dev->sas_addr),
572 SAS_ADDR(task->ssp_task.LUN),
573 shdr.sense_key,
574 shdr.asc, shdr.ascq);
575 }
576 } else if (task->task_status.resp != SAS_TASK_COMPLETE ||
577 task->task_status.stat != SAM_STAT_GOOD) {
578 SAS_DPRINTK("task finished with resp:0x%x, "
579 "stat:0x%x\n",
580 task->task_status.resp,
581 task->task_status.stat);
582 goto ex_err;
583 } else {
584 res = 0;
585 break;
586 }
587 }
588ex_err:
589 if (dma_dir != DMA_NONE) {
590 if (sas_protocol_ata(task->task_proto))
591 dma_unmap_sg(task->dev->port->ha->dev,
592 task->scatter, task->num_scatter,
593 task->data_dir);
594 kfree(scatter);
595 }
596out:
597 return res;
598}
599
600/* ---------- SATA ---------- */
601
602static void sas_get_ata_command_set(struct domain_device *dev) 457static void sas_get_ata_command_set(struct domain_device *dev)
603{ 458{
604 struct dev_to_host_fis *fis = 459 struct dev_to_host_fis *fis =
@@ -642,122 +497,6 @@ static void sas_get_ata_command_set(struct domain_device *dev)
642 dev->sata_dev.command_set = ATAPI_COMMAND_SET; 497 dev->sata_dev.command_set = ATAPI_COMMAND_SET;
643} 498}
644 499
645/**
646 * sas_issue_ata_cmd -- Basic SATA command processing for discovery
647 * @dev: the device to send the command to
648 * @command: the command register
649 * @features: the features register
650 * @buffer: pointer to buffer to do I/O
651 * @size: size of @buffer
652 * @dma_dir: DMA direction. DMA_xxx
653 */
654static int sas_issue_ata_cmd(struct domain_device *dev, u8 command,
655 u8 features, void *buffer, int size,
656 enum dma_data_direction dma_dir)
657{
658 int res = 0;
659 struct sas_task *task;
660 struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *)
661 &dev->frame_rcvd[0];
662
663 res = -ENOMEM;
664 task = sas_alloc_task(GFP_KERNEL);
665 if (!task)
666 goto out;
667
668 task->dev = dev;
669
670 task->ata_task.fis.fis_type = 0x27;
671 task->ata_task.fis.command = command;
672 task->ata_task.fis.features = features;
673 task->ata_task.fis.device = d2h_fis->device;
674 task->ata_task.retry_count = 1;
675
676 res = sas_execute_task(task, buffer, size, dma_dir);
677
678 sas_free_task(task);
679out:
680 return res;
681}
682
683#define ATA_IDENTIFY_DEV 0xEC
684#define ATA_IDENTIFY_PACKET_DEV 0xA1
685#define ATA_SET_FEATURES 0xEF
686#define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07
687
688/**
689 * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV)
690 * @dev: STP/SATA device of interest (ATA/ATAPI)
691 *
692 * The LLDD has already been notified of this device, so that we can
693 * send FISes to it. Here we try to get IDENTIFY DEVICE or IDENTIFY
694 * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its
695 * performance for this device.
696 */
697static int sas_discover_sata_dev(struct domain_device *dev)
698{
699 int res;
700 __le16 *identify_x;
701 u8 command;
702
703 identify_x = kzalloc(512, GFP_KERNEL);
704 if (!identify_x)
705 return -ENOMEM;
706
707 if (dev->sata_dev.command_set == ATA_COMMAND_SET) {
708 dev->sata_dev.identify_device = identify_x;
709 command = ATA_IDENTIFY_DEV;
710 } else {
711 dev->sata_dev.identify_packet_device = identify_x;
712 command = ATA_IDENTIFY_PACKET_DEV;
713 }
714
715 res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
716 DMA_FROM_DEVICE);
717 if (res)
718 goto out_err;
719
720 /* lives on the media? */
721 if (le16_to_cpu(identify_x[0]) & 4) {
722 /* incomplete response */
723 SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
724 "dev %llx\n", SAS_ADDR(dev->sas_addr));
725 if (!(identify_x[83] & cpu_to_le16(1<<6)))
726 goto cont1;
727 res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
728 ATA_FEATURE_PUP_STBY_SPIN_UP,
729 NULL, 0, DMA_NONE);
730 if (res)
731 goto cont1;
732
733 schedule_timeout_interruptible(5*HZ); /* More time? */
734 res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
735 DMA_FROM_DEVICE);
736 if (res)
737 goto out_err;
738 }
739cont1:
740 /* XXX Hint: register this SATA device with SATL.
741 When this returns, dev->sata_dev->lu is alive and
742 present.
743 sas_satl_register_dev(dev);
744 */
745
746 sas_fill_in_rphy(dev, dev->rphy);
747
748 return 0;
749out_err:
750 dev->sata_dev.identify_packet_device = NULL;
751 dev->sata_dev.identify_device = NULL;
752 kfree(identify_x);
753 return res;
754}
755
756static int sas_discover_sata_pm(struct domain_device *dev)
757{
758 return -ENODEV;
759}
760
761void sas_probe_sata(struct work_struct *work) 500void sas_probe_sata(struct work_struct *work)
762{ 501{
763 struct domain_device *dev, *n; 502 struct domain_device *dev, *n;
@@ -791,49 +530,26 @@ void sas_probe_sata(struct work_struct *work)
791 * sas_discover_sata -- discover an STP/SATA domain device 530 * sas_discover_sata -- discover an STP/SATA domain device
792 * @dev: pointer to struct domain_device of interest 531 * @dev: pointer to struct domain_device of interest
793 * 532 *
794 * First we notify the LLDD of this device, so we can send frames to 533 * Devices directly attached to a HA port, have no parents. All other
795 * it. Then depending on the type of device we call the appropriate 534 * devices do, and should have their "parent" pointer set appropriately
796 * discover functions. Once device discover is done, we notify the 535 * before calling this function.
797 * LLDD so that it can fine-tune its parameters for the device, by
798 * removing it and then adding it. That is, the second time around,
799 * the driver would have certain fields, that it is looking at, set.
800 * Finally we initialize the kobj so that the device can be added to
801 * the system at registration time. Devices directly attached to a HA
802 * port, have no parents. All other devices do, and should have their
803 * "parent" pointer set appropriately before calling this function.
804 */ 536 */
805int sas_discover_sata(struct domain_device *dev) 537int sas_discover_sata(struct domain_device *dev)
806{ 538{
807 int res; 539 int res;
808 540
809 sas_get_ata_command_set(dev); 541 if (dev->dev_type == SATA_PM)
810 542 return -ENODEV;
811 res = sas_notify_lldd_dev_found(dev);
812 if (res)
813 return res;
814
815 switch (dev->dev_type) {
816 case SATA_DEV:
817 res = sas_discover_sata_dev(dev);
818 break;
819 case SATA_PM:
820 res = sas_discover_sata_pm(dev);
821 break;
822 default:
823 break;
824 }
825 sas_notify_lldd_dev_gone(dev);
826 543
827 if (res) 544 sas_get_ata_command_set(dev);
828 return res; 545 sas_fill_in_rphy(dev, dev->rphy);
829 546
830 res = sas_notify_lldd_dev_found(dev); 547 res = sas_notify_lldd_dev_found(dev);
831 if (res) 548 if (res)
832 return res; 549 return res;
833 550
834 sas_discover_event(dev->port, DISCE_PROBE); 551 sas_discover_event(dev->port, DISCE_PROBE);
835 552 return 0;
836 return res;
837} 553}
838 554
839void sas_ata_strategy_handler(struct Scsi_Host *shost) 555void sas_ata_strategy_handler(struct Scsi_Host *shost)
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index 7e8fdcb202b7..bad5eba4a92b 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -237,11 +237,6 @@ void sas_free_device(struct kref *kref)
237 if (dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV) 237 if (dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV)
238 kfree(dev->ex_dev.ex_phy); 238 kfree(dev->ex_dev.ex_phy);
239 239
240 if (dev_is_sata(dev)) {
241 kfree(dev->sata_dev.identify_device);
242 kfree(dev->sata_dev.identify_packet_device);
243 }
244
245 kfree(dev); 240 kfree(dev);
246} 241}
247 242