Commit b91421749a1840148d8c81637c03c0ace3f35269

Authored by James Bottomley
Committed by James Bottomley
1 parent 41e1703b9b

[SCSI] libsas: make ATA functions selectable by a config option

Not everyone wants libsas automatically to pull in libata.  This patch
makes the behaviour configurable, so you can build libsas with or
without ATA support.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

Showing 6 changed files with 436 additions and 397 deletions Side-by-side Diff

drivers/scsi/libsas/Kconfig
... ... @@ -30,6 +30,13 @@
30 30 This provides transport specific helpers for SAS drivers which
31 31 use the domain device construct (like the aic94xxx).
32 32  
  33 +config SCSI_SAS_ATA
  34 + bool "ATA support for libsas (requires libata)"
  35 + depends on SCSI_SAS_LIBSAS && ATA
  36 + help
  37 + Builds in ATA support into libsas. Will necessitate
  38 + the loading of libata along with libsas.
  39 +
33 40 config SCSI_SAS_LIBSAS_DEBUG
34 41 bool "Compile the SAS Domain Transport Attributes in debug mode"
35 42 default y
drivers/scsi/libsas/Makefile
... ... @@ -33,6 +33,6 @@
33 33 sas_dump.o \
34 34 sas_discover.o \
35 35 sas_expander.o \
36   - sas_scsi_host.o \
37   - sas_ata.o
  36 + sas_scsi_host.o
  37 +libsas-$(CONFIG_SCSI_SAS_ATA) += sas_ata.o
drivers/scsi/libsas/sas_ata.c
... ... @@ -21,6 +21,8 @@
21 21 * USA
22 22 */
23 23  
  24 +#include <linux/scatterlist.h>
  25 +
24 26 #include <scsi/sas_ata.h>
25 27 #include "sas_internal.h"
26 28 #include <scsi/scsi_host.h>
... ... @@ -417,5 +419,400 @@
417 419 qc->err_mask |= AC_ERR_TIMEOUT;
418 420 waiting = qc->private_data;
419 421 complete(waiting);
  422 +}
  423 +
  424 +static void sas_task_timedout(unsigned long _task)
  425 +{
  426 + struct sas_task *task = (void *) _task;
  427 + unsigned long flags;
  428 +
  429 + spin_lock_irqsave(&task->task_state_lock, flags);
  430 + if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
  431 + task->task_state_flags |= SAS_TASK_STATE_ABORTED;
  432 + spin_unlock_irqrestore(&task->task_state_lock, flags);
  433 +
  434 + complete(&task->completion);
  435 +}
  436 +
  437 +static void sas_disc_task_done(struct sas_task *task)
  438 +{
  439 + if (!del_timer(&task->timer))
  440 + return;
  441 + complete(&task->completion);
  442 +}
  443 +
  444 +#define SAS_DEV_TIMEOUT 10
  445 +
  446 +/**
  447 + * sas_execute_task -- Basic task processing for discovery
  448 + * @task: the task to be executed
  449 + * @buffer: pointer to buffer to do I/O
  450 + * @size: size of @buffer
  451 + * @pci_dma_dir: PCI_DMA_...
  452 + */
  453 +static int sas_execute_task(struct sas_task *task, void *buffer, int size,
  454 + int pci_dma_dir)
  455 +{
  456 + int res = 0;
  457 + struct scatterlist *scatter = NULL;
  458 + struct task_status_struct *ts = &task->task_status;
  459 + int num_scatter = 0;
  460 + int retries = 0;
  461 + struct sas_internal *i =
  462 + to_sas_internal(task->dev->port->ha->core.shost->transportt);
  463 +
  464 + if (pci_dma_dir != PCI_DMA_NONE) {
  465 + scatter = kzalloc(sizeof(*scatter), GFP_KERNEL);
  466 + if (!scatter)
  467 + goto out;
  468 +
  469 + sg_init_one(scatter, buffer, size);
  470 + num_scatter = 1;
  471 + }
  472 +
  473 + task->task_proto = task->dev->tproto;
  474 + task->scatter = scatter;
  475 + task->num_scatter = num_scatter;
  476 + task->total_xfer_len = size;
  477 + task->data_dir = pci_dma_dir;
  478 + task->task_done = sas_disc_task_done;
  479 + if (pci_dma_dir != PCI_DMA_NONE &&
  480 + sas_protocol_ata(task->task_proto)) {
  481 + task->num_scatter = pci_map_sg(task->dev->port->ha->pcidev,
  482 + task->scatter,
  483 + task->num_scatter,
  484 + task->data_dir);
  485 + }
  486 +
  487 + for (retries = 0; retries < 5; retries++) {
  488 + task->task_state_flags = SAS_TASK_STATE_PENDING;
  489 + init_completion(&task->completion);
  490 +
  491 + task->timer.data = (unsigned long) task;
  492 + task->timer.function = sas_task_timedout;
  493 + task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ;
  494 + add_timer(&task->timer);
  495 +
  496 + res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
  497 + if (res) {
  498 + del_timer(&task->timer);
  499 + SAS_DPRINTK("executing SAS discovery task failed:%d\n",
  500 + res);
  501 + goto ex_err;
  502 + }
  503 + wait_for_completion(&task->completion);
  504 + res = -ETASK;
  505 + if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
  506 + int res2;
  507 + SAS_DPRINTK("task aborted, flags:0x%x\n",
  508 + task->task_state_flags);
  509 + res2 = i->dft->lldd_abort_task(task);
  510 + SAS_DPRINTK("came back from abort task\n");
  511 + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
  512 + if (res2 == TMF_RESP_FUNC_COMPLETE)
  513 + continue; /* Retry the task */
  514 + else
  515 + goto ex_err;
  516 + }
  517 + }
  518 + if (task->task_status.stat == SAM_BUSY ||
  519 + task->task_status.stat == SAM_TASK_SET_FULL ||
  520 + task->task_status.stat == SAS_QUEUE_FULL) {
  521 + SAS_DPRINTK("task: q busy, sleeping...\n");
  522 + schedule_timeout_interruptible(HZ);
  523 + } else if (task->task_status.stat == SAM_CHECK_COND) {
  524 + struct scsi_sense_hdr shdr;
  525 +
  526 + if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size,
  527 + &shdr)) {
  528 + SAS_DPRINTK("couldn't normalize sense\n");
  529 + continue;
  530 + }
  531 + if ((shdr.sense_key == 6 && shdr.asc == 0x29) ||
  532 + (shdr.sense_key == 2 && shdr.asc == 4 &&
  533 + shdr.ascq == 1)) {
  534 + SAS_DPRINTK("device %016llx LUN: %016llx "
  535 + "powering up or not ready yet, "
  536 + "sleeping...\n",
  537 + SAS_ADDR(task->dev->sas_addr),
  538 + SAS_ADDR(task->ssp_task.LUN));
  539 +
  540 + schedule_timeout_interruptible(5*HZ);
  541 + } else if (shdr.sense_key == 1) {
  542 + res = 0;
  543 + break;
  544 + } else if (shdr.sense_key == 5) {
  545 + break;
  546 + } else {
  547 + SAS_DPRINTK("dev %016llx LUN: %016llx "
  548 + "sense key:0x%x ASC:0x%x ASCQ:0x%x"
  549 + "\n",
  550 + SAS_ADDR(task->dev->sas_addr),
  551 + SAS_ADDR(task->ssp_task.LUN),
  552 + shdr.sense_key,
  553 + shdr.asc, shdr.ascq);
  554 + }
  555 + } else if (task->task_status.resp != SAS_TASK_COMPLETE ||
  556 + task->task_status.stat != SAM_GOOD) {
  557 + SAS_DPRINTK("task finished with resp:0x%x, "
  558 + "stat:0x%x\n",
  559 + task->task_status.resp,
  560 + task->task_status.stat);
  561 + goto ex_err;
  562 + } else {
  563 + res = 0;
  564 + break;
  565 + }
  566 + }
  567 +ex_err:
  568 + if (pci_dma_dir != PCI_DMA_NONE) {
  569 + if (sas_protocol_ata(task->task_proto))
  570 + pci_unmap_sg(task->dev->port->ha->pcidev,
  571 + task->scatter, task->num_scatter,
  572 + task->data_dir);
  573 + kfree(scatter);
  574 + }
  575 +out:
  576 + return res;
  577 +}
  578 +
  579 +/* ---------- SATA ---------- */
  580 +
  581 +static void sas_get_ata_command_set(struct domain_device *dev)
  582 +{
  583 + struct dev_to_host_fis *fis =
  584 + (struct dev_to_host_fis *) dev->frame_rcvd;
  585 +
  586 + if ((fis->sector_count == 1 && /* ATA */
  587 + fis->lbal == 1 &&
  588 + fis->lbam == 0 &&
  589 + fis->lbah == 0 &&
  590 + fis->device == 0)
  591 + ||
  592 + (fis->sector_count == 0 && /* CE-ATA (mATA) */
  593 + fis->lbal == 0 &&
  594 + fis->lbam == 0xCE &&
  595 + fis->lbah == 0xAA &&
  596 + (fis->device & ~0x10) == 0))
  597 +
  598 + dev->sata_dev.command_set = ATA_COMMAND_SET;
  599 +
  600 + else if ((fis->interrupt_reason == 1 && /* ATAPI */
  601 + fis->lbal == 1 &&
  602 + fis->byte_count_low == 0x14 &&
  603 + fis->byte_count_high == 0xEB &&
  604 + (fis->device & ~0x10) == 0))
  605 +
  606 + dev->sata_dev.command_set = ATAPI_COMMAND_SET;
  607 +
  608 + else if ((fis->sector_count == 1 && /* SEMB */
  609 + fis->lbal == 1 &&
  610 + fis->lbam == 0x3C &&
  611 + fis->lbah == 0xC3 &&
  612 + fis->device == 0)
  613 + ||
  614 + (fis->interrupt_reason == 1 && /* SATA PM */
  615 + fis->lbal == 1 &&
  616 + fis->byte_count_low == 0x69 &&
  617 + fis->byte_count_high == 0x96 &&
  618 + (fis->device & ~0x10) == 0))
  619 +
  620 + /* Treat it as a superset? */
  621 + dev->sata_dev.command_set = ATAPI_COMMAND_SET;
  622 +}
  623 +
  624 +/**
  625 + * sas_issue_ata_cmd -- Basic SATA command processing for discovery
  626 + * @dev: the device to send the command to
  627 + * @command: the command register
  628 + * @features: the features register
  629 + * @buffer: pointer to buffer to do I/O
  630 + * @size: size of @buffer
  631 + * @pci_dma_dir: PCI_DMA_...
  632 + */
  633 +static int sas_issue_ata_cmd(struct domain_device *dev, u8 command,
  634 + u8 features, void *buffer, int size,
  635 + int pci_dma_dir)
  636 +{
  637 + int res = 0;
  638 + struct sas_task *task;
  639 + struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *)
  640 + &dev->frame_rcvd[0];
  641 +
  642 + res = -ENOMEM;
  643 + task = sas_alloc_task(GFP_KERNEL);
  644 + if (!task)
  645 + goto out;
  646 +
  647 + task->dev = dev;
  648 +
  649 + task->ata_task.fis.fis_type = 0x27;
  650 + task->ata_task.fis.command = command;
  651 + task->ata_task.fis.features = features;
  652 + task->ata_task.fis.device = d2h_fis->device;
  653 + task->ata_task.retry_count = 1;
  654 +
  655 + res = sas_execute_task(task, buffer, size, pci_dma_dir);
  656 +
  657 + sas_free_task(task);
  658 +out:
  659 + return res;
  660 +}
  661 +
  662 +static void sas_sata_propagate_sas_addr(struct domain_device *dev)
  663 +{
  664 + unsigned long flags;
  665 + struct asd_sas_port *port = dev->port;
  666 + struct asd_sas_phy *phy;
  667 +
  668 + BUG_ON(dev->parent);
  669 +
  670 + memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
  671 + spin_lock_irqsave(&port->phy_list_lock, flags);
  672 + list_for_each_entry(phy, &port->phy_list, port_phy_el)
  673 + memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
  674 + spin_unlock_irqrestore(&port->phy_list_lock, flags);
  675 +}
  676 +
  677 +#define ATA_IDENTIFY_DEV 0xEC
  678 +#define ATA_IDENTIFY_PACKET_DEV 0xA1
  679 +#define ATA_SET_FEATURES 0xEF
  680 +#define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07
  681 +
  682 +/**
  683 + * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV)
  684 + * @dev: STP/SATA device of interest (ATA/ATAPI)
  685 + *
  686 + * The LLDD has already been notified of this device, so that we can
  687 + * send FISes to it. Here we try to get IDENTIFY DEVICE or IDENTIFY
  688 + * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its
  689 + * performance for this device.
  690 + */
  691 +static int sas_discover_sata_dev(struct domain_device *dev)
  692 +{
  693 + int res;
  694 + __le16 *identify_x;
  695 + u8 command;
  696 +
  697 + identify_x = kzalloc(512, GFP_KERNEL);
  698 + if (!identify_x)
  699 + return -ENOMEM;
  700 +
  701 + if (dev->sata_dev.command_set == ATA_COMMAND_SET) {
  702 + dev->sata_dev.identify_device = identify_x;
  703 + command = ATA_IDENTIFY_DEV;
  704 + } else {
  705 + dev->sata_dev.identify_packet_device = identify_x;
  706 + command = ATA_IDENTIFY_PACKET_DEV;
  707 + }
  708 +
  709 + res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
  710 + PCI_DMA_FROMDEVICE);
  711 + if (res)
  712 + goto out_err;
  713 +
  714 + /* lives on the media? */
  715 + if (le16_to_cpu(identify_x[0]) & 4) {
  716 + /* incomplete response */
  717 + SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
  718 + "dev %llx\n", SAS_ADDR(dev->sas_addr));
  719 + if (!le16_to_cpu(identify_x[83] & (1<<6)))
  720 + goto cont1;
  721 + res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
  722 + ATA_FEATURE_PUP_STBY_SPIN_UP,
  723 + NULL, 0, PCI_DMA_NONE);
  724 + if (res)
  725 + goto cont1;
  726 +
  727 + schedule_timeout_interruptible(5*HZ); /* More time? */
  728 + res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
  729 + PCI_DMA_FROMDEVICE);
  730 + if (res)
  731 + goto out_err;
  732 + }
  733 +cont1:
  734 + /* Get WWN */
  735 + if (dev->port->oob_mode != SATA_OOB_MODE) {
  736 + memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr,
  737 + SAS_ADDR_SIZE);
  738 + } else if (dev->sata_dev.command_set == ATA_COMMAND_SET &&
  739 + (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000)
  740 + == 0x5000) {
  741 + int i;
  742 +
  743 + for (i = 0; i < 4; i++) {
  744 + dev->sas_addr[2*i] =
  745 + (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8;
  746 + dev->sas_addr[2*i+1] =
  747 + le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF;
  748 + }
  749 + }
  750 + sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
  751 + if (!dev->parent)
  752 + sas_sata_propagate_sas_addr(dev);
  753 +
  754 + /* XXX Hint: register this SATA device with SATL.
  755 + When this returns, dev->sata_dev->lu is alive and
  756 + present.
  757 + sas_satl_register_dev(dev);
  758 + */
  759 +
  760 + sas_fill_in_rphy(dev, dev->rphy);
  761 +
  762 + return 0;
  763 +out_err:
  764 + dev->sata_dev.identify_packet_device = NULL;
  765 + dev->sata_dev.identify_device = NULL;
  766 + kfree(identify_x);
  767 + return res;
  768 +}
  769 +
  770 +static int sas_discover_sata_pm(struct domain_device *dev)
  771 +{
  772 + return -ENODEV;
  773 +}
  774 +
  775 +/**
  776 + * sas_discover_sata -- discover an STP/SATA domain device
  777 + * @dev: pointer to struct domain_device of interest
  778 + *
  779 + * First we notify the LLDD of this device, so we can send frames to
  780 + * it. Then depending on the type of device we call the appropriate
  781 + * discover functions. Once device discover is done, we notify the
  782 + * LLDD so that it can fine-tune its parameters for the device, by
  783 + * removing it and then adding it. That is, the second time around,
  784 + * the driver would have certain fields, that it is looking at, set.
  785 + * Finally we initialize the kobj so that the device can be added to
  786 + * the system at registration time. Devices directly attached to a HA
  787 + * port, have no parents. All other devices do, and should have their
  788 + * "parent" pointer set appropriately before calling this function.
  789 + */
  790 +int sas_discover_sata(struct domain_device *dev)
  791 +{
  792 + int res;
  793 +
  794 + sas_get_ata_command_set(dev);
  795 +
  796 + res = sas_notify_lldd_dev_found(dev);
  797 + if (res)
  798 + return res;
  799 +
  800 + switch (dev->dev_type) {
  801 + case SATA_DEV:
  802 + res = sas_discover_sata_dev(dev);
  803 + break;
  804 + case SATA_PM:
  805 + res = sas_discover_sata_pm(dev);
  806 + break;
  807 + default:
  808 + break;
  809 + }
  810 + sas_notify_lldd_dev_gone(dev);
  811 + if (!res) {
  812 + sas_notify_lldd_dev_found(dev);
  813 + res = sas_rphy_add(dev->rphy);
  814 + }
  815 +
  816 + return res;
420 817 }
drivers/scsi/libsas/sas_discover.c
... ... @@ -55,161 +55,6 @@
55 55 }
56 56 }
57 57  
58   -static void sas_task_timedout(unsigned long _task)
59   -{
60   - struct sas_task *task = (void *) _task;
61   - unsigned long flags;
62   -
63   - spin_lock_irqsave(&task->task_state_lock, flags);
64   - if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
65   - task->task_state_flags |= SAS_TASK_STATE_ABORTED;
66   - spin_unlock_irqrestore(&task->task_state_lock, flags);
67   -
68   - complete(&task->completion);
69   -}
70   -
71   -static void sas_disc_task_done(struct sas_task *task)
72   -{
73   - if (!del_timer(&task->timer))
74   - return;
75   - complete(&task->completion);
76   -}
77   -
78   -#define SAS_DEV_TIMEOUT 10
79   -
80   -/**
81   - * sas_execute_task -- Basic task processing for discovery
82   - * @task: the task to be executed
83   - * @buffer: pointer to buffer to do I/O
84   - * @size: size of @buffer
85   - * @pci_dma_dir: PCI_DMA_...
86   - */
87   -static int sas_execute_task(struct sas_task *task, void *buffer, int size,
88   - int pci_dma_dir)
89   -{
90   - int res = 0;
91   - struct scatterlist *scatter = NULL;
92   - struct task_status_struct *ts = &task->task_status;
93   - int num_scatter = 0;
94   - int retries = 0;
95   - struct sas_internal *i =
96   - to_sas_internal(task->dev->port->ha->core.shost->transportt);
97   -
98   - if (pci_dma_dir != PCI_DMA_NONE) {
99   - scatter = kzalloc(sizeof(*scatter), GFP_KERNEL);
100   - if (!scatter)
101   - goto out;
102   -
103   - sg_init_one(scatter, buffer, size);
104   - num_scatter = 1;
105   - }
106   -
107   - task->task_proto = task->dev->tproto;
108   - task->scatter = scatter;
109   - task->num_scatter = num_scatter;
110   - task->total_xfer_len = size;
111   - task->data_dir = pci_dma_dir;
112   - task->task_done = sas_disc_task_done;
113   - if (pci_dma_dir != PCI_DMA_NONE &&
114   - sas_protocol_ata(task->task_proto)) {
115   - task->num_scatter = pci_map_sg(task->dev->port->ha->pcidev,
116   - task->scatter,
117   - task->num_scatter,
118   - task->data_dir);
119   - }
120   -
121   - for (retries = 0; retries < 5; retries++) {
122   - task->task_state_flags = SAS_TASK_STATE_PENDING;
123   - init_completion(&task->completion);
124   -
125   - task->timer.data = (unsigned long) task;
126   - task->timer.function = sas_task_timedout;
127   - task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ;
128   - add_timer(&task->timer);
129   -
130   - res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
131   - if (res) {
132   - del_timer(&task->timer);
133   - SAS_DPRINTK("executing SAS discovery task failed:%d\n",
134   - res);
135   - goto ex_err;
136   - }
137   - wait_for_completion(&task->completion);
138   - res = -ETASK;
139   - if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
140   - int res2;
141   - SAS_DPRINTK("task aborted, flags:0x%x\n",
142   - task->task_state_flags);
143   - res2 = i->dft->lldd_abort_task(task);
144   - SAS_DPRINTK("came back from abort task\n");
145   - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
146   - if (res2 == TMF_RESP_FUNC_COMPLETE)
147   - continue; /* Retry the task */
148   - else
149   - goto ex_err;
150   - }
151   - }
152   - if (task->task_status.stat == SAM_BUSY ||
153   - task->task_status.stat == SAM_TASK_SET_FULL ||
154   - task->task_status.stat == SAS_QUEUE_FULL) {
155   - SAS_DPRINTK("task: q busy, sleeping...\n");
156   - schedule_timeout_interruptible(HZ);
157   - } else if (task->task_status.stat == SAM_CHECK_COND) {
158   - struct scsi_sense_hdr shdr;
159   -
160   - if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size,
161   - &shdr)) {
162   - SAS_DPRINTK("couldn't normalize sense\n");
163   - continue;
164   - }
165   - if ((shdr.sense_key == 6 && shdr.asc == 0x29) ||
166   - (shdr.sense_key == 2 && shdr.asc == 4 &&
167   - shdr.ascq == 1)) {
168   - SAS_DPRINTK("device %016llx LUN: %016llx "
169   - "powering up or not ready yet, "
170   - "sleeping...\n",
171   - SAS_ADDR(task->dev->sas_addr),
172   - SAS_ADDR(task->ssp_task.LUN));
173   -
174   - schedule_timeout_interruptible(5*HZ);
175   - } else if (shdr.sense_key == 1) {
176   - res = 0;
177   - break;
178   - } else if (shdr.sense_key == 5) {
179   - break;
180   - } else {
181   - SAS_DPRINTK("dev %016llx LUN: %016llx "
182   - "sense key:0x%x ASC:0x%x ASCQ:0x%x"
183   - "\n",
184   - SAS_ADDR(task->dev->sas_addr),
185   - SAS_ADDR(task->ssp_task.LUN),
186   - shdr.sense_key,
187   - shdr.asc, shdr.ascq);
188   - }
189   - } else if (task->task_status.resp != SAS_TASK_COMPLETE ||
190   - task->task_status.stat != SAM_GOOD) {
191   - SAS_DPRINTK("task finished with resp:0x%x, "
192   - "stat:0x%x\n",
193   - task->task_status.resp,
194   - task->task_status.stat);
195   - goto ex_err;
196   - } else {
197   - res = 0;
198   - break;
199   - }
200   - }
201   -ex_err:
202   - if (pci_dma_dir != PCI_DMA_NONE) {
203   - if (sas_protocol_ata(task->task_proto))
204   - pci_unmap_sg(task->dev->port->ha->pcidev,
205   - task->scatter, task->num_scatter,
206   - task->data_dir);
207   - kfree(scatter);
208   - }
209   -out:
210   - return res;
211   -}
212   -
213 58 /* ---------- Domain device discovery ---------- */
214 59  
215 60 /**
... ... @@ -313,202 +158,6 @@
313 158  
314 159 /* ---------- Discover and Revalidate ---------- */
315 160  
316   -/* ---------- SATA ---------- */
317   -
318   -static void sas_get_ata_command_set(struct domain_device *dev)
319   -{
320   - struct dev_to_host_fis *fis =
321   - (struct dev_to_host_fis *) dev->frame_rcvd;
322   -
323   - if ((fis->sector_count == 1 && /* ATA */
324   - fis->lbal == 1 &&
325   - fis->lbam == 0 &&
326   - fis->lbah == 0 &&
327   - fis->device == 0)
328   - ||
329   - (fis->sector_count == 0 && /* CE-ATA (mATA) */
330   - fis->lbal == 0 &&
331   - fis->lbam == 0xCE &&
332   - fis->lbah == 0xAA &&
333   - (fis->device & ~0x10) == 0))
334   -
335   - dev->sata_dev.command_set = ATA_COMMAND_SET;
336   -
337   - else if ((fis->interrupt_reason == 1 && /* ATAPI */
338   - fis->lbal == 1 &&
339   - fis->byte_count_low == 0x14 &&
340   - fis->byte_count_high == 0xEB &&
341   - (fis->device & ~0x10) == 0))
342   -
343   - dev->sata_dev.command_set = ATAPI_COMMAND_SET;
344   -
345   - else if ((fis->sector_count == 1 && /* SEMB */
346   - fis->lbal == 1 &&
347   - fis->lbam == 0x3C &&
348   - fis->lbah == 0xC3 &&
349   - fis->device == 0)
350   - ||
351   - (fis->interrupt_reason == 1 && /* SATA PM */
352   - fis->lbal == 1 &&
353   - fis->byte_count_low == 0x69 &&
354   - fis->byte_count_high == 0x96 &&
355   - (fis->device & ~0x10) == 0))
356   -
357   - /* Treat it as a superset? */
358   - dev->sata_dev.command_set = ATAPI_COMMAND_SET;
359   -}
360   -
361   -/**
362   - * sas_issue_ata_cmd -- Basic SATA command processing for discovery
363   - * @dev: the device to send the command to
364   - * @command: the command register
365   - * @features: the features register
366   - * @buffer: pointer to buffer to do I/O
367   - * @size: size of @buffer
368   - * @pci_dma_dir: PCI_DMA_...
369   - */
370   -static int sas_issue_ata_cmd(struct domain_device *dev, u8 command,
371   - u8 features, void *buffer, int size,
372   - int pci_dma_dir)
373   -{
374   - int res = 0;
375   - struct sas_task *task;
376   - struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *)
377   - &dev->frame_rcvd[0];
378   -
379   - res = -ENOMEM;
380   - task = sas_alloc_task(GFP_KERNEL);
381   - if (!task)
382   - goto out;
383   -
384   - task->dev = dev;
385   -
386   - task->ata_task.fis.fis_type = 0x27;
387   - task->ata_task.fis.command = command;
388   - task->ata_task.fis.features = features;
389   - task->ata_task.fis.device = d2h_fis->device;
390   - task->ata_task.retry_count = 1;
391   -
392   - res = sas_execute_task(task, buffer, size, pci_dma_dir);
393   -
394   - sas_free_task(task);
395   -out:
396   - return res;
397   -}
398   -
399   -static void sas_sata_propagate_sas_addr(struct domain_device *dev)
400   -{
401   - unsigned long flags;
402   - struct asd_sas_port *port = dev->port;
403   - struct asd_sas_phy *phy;
404   -
405   - BUG_ON(dev->parent);
406   -
407   - memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
408   - spin_lock_irqsave(&port->phy_list_lock, flags);
409   - list_for_each_entry(phy, &port->phy_list, port_phy_el)
410   - memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
411   - spin_unlock_irqrestore(&port->phy_list_lock, flags);
412   -}
413   -
414   -#define ATA_IDENTIFY_DEV 0xEC
415   -#define ATA_IDENTIFY_PACKET_DEV 0xA1
416   -#define ATA_SET_FEATURES 0xEF
417   -#define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07
418   -
419   -/**
420   - * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV)
421   - * @dev: STP/SATA device of interest (ATA/ATAPI)
422   - *
423   - * The LLDD has already been notified of this device, so that we can
424   - * send FISes to it. Here we try to get IDENTIFY DEVICE or IDENTIFY
425   - * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its
426   - * performance for this device.
427   - */
428   -static int sas_discover_sata_dev(struct domain_device *dev)
429   -{
430   - int res;
431   - __le16 *identify_x;
432   - u8 command;
433   -
434   - identify_x = kzalloc(512, GFP_KERNEL);
435   - if (!identify_x)
436   - return -ENOMEM;
437   -
438   - if (dev->sata_dev.command_set == ATA_COMMAND_SET) {
439   - dev->sata_dev.identify_device = identify_x;
440   - command = ATA_IDENTIFY_DEV;
441   - } else {
442   - dev->sata_dev.identify_packet_device = identify_x;
443   - command = ATA_IDENTIFY_PACKET_DEV;
444   - }
445   -
446   - res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
447   - PCI_DMA_FROMDEVICE);
448   - if (res)
449   - goto out_err;
450   -
451   - /* lives on the media? */
452   - if (le16_to_cpu(identify_x[0]) & 4) {
453   - /* incomplete response */
454   - SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
455   - "dev %llx\n", SAS_ADDR(dev->sas_addr));
456   - if (!le16_to_cpu(identify_x[83] & (1<<6)))
457   - goto cont1;
458   - res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
459   - ATA_FEATURE_PUP_STBY_SPIN_UP,
460   - NULL, 0, PCI_DMA_NONE);
461   - if (res)
462   - goto cont1;
463   -
464   - schedule_timeout_interruptible(5*HZ); /* More time? */
465   - res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
466   - PCI_DMA_FROMDEVICE);
467   - if (res)
468   - goto out_err;
469   - }
470   -cont1:
471   - /* Get WWN */
472   - if (dev->port->oob_mode != SATA_OOB_MODE) {
473   - memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr,
474   - SAS_ADDR_SIZE);
475   - } else if (dev->sata_dev.command_set == ATA_COMMAND_SET &&
476   - (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000)
477   - == 0x5000) {
478   - int i;
479   -
480   - for (i = 0; i < 4; i++) {
481   - dev->sas_addr[2*i] =
482   - (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8;
483   - dev->sas_addr[2*i+1] =
484   - le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF;
485   - }
486   - }
487   - sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
488   - if (!dev->parent)
489   - sas_sata_propagate_sas_addr(dev);
490   -
491   - /* XXX Hint: register this SATA device with SATL.
492   - When this returns, dev->sata_dev->lu is alive and
493   - present.
494   - sas_satl_register_dev(dev);
495   - */
496   -
497   - sas_fill_in_rphy(dev, dev->rphy);
498   -
499   - return 0;
500   -out_err:
501   - dev->sata_dev.identify_packet_device = NULL;
502   - dev->sata_dev.identify_device = NULL;
503   - kfree(identify_x);
504   - return res;
505   -}
506   -
507   -static int sas_discover_sata_pm(struct domain_device *dev)
508   -{
509   - return -ENODEV;
510   -}
511   -
512 161 int sas_notify_lldd_dev_found(struct domain_device *dev)
513 162 {
514 163 int res = 0;
515 164  
... ... @@ -541,50 +190,7 @@
541 190  
542 191 /* ---------- Common/dispatchers ---------- */
543 192  
544   -/**
545   - * sas_discover_sata -- discover an STP/SATA domain device
546   - * @dev: pointer to struct domain_device of interest
547   - *
548   - * First we notify the LLDD of this device, so we can send frames to
549   - * it. Then depending on the type of device we call the appropriate
550   - * discover functions. Once device discover is done, we notify the
551   - * LLDD so that it can fine-tune its parameters for the device, by
552   - * removing it and then adding it. That is, the second time around,
553   - * the driver would have certain fields, that it is looking at, set.
554   - * Finally we initialize the kobj so that the device can be added to
555   - * the system at registration time. Devices directly attached to a HA
556   - * port, have no parents. All other devices do, and should have their
557   - * "parent" pointer set appropriately before calling this function.
558   - */
559   -int sas_discover_sata(struct domain_device *dev)
560   -{
561   - int res;
562 193  
563   - sas_get_ata_command_set(dev);
564   -
565   - res = sas_notify_lldd_dev_found(dev);
566   - if (res)
567   - return res;
568   -
569   - switch (dev->dev_type) {
570   - case SATA_DEV:
571   - res = sas_discover_sata_dev(dev);
572   - break;
573   - case SATA_PM:
574   - res = sas_discover_sata_pm(dev);
575   - break;
576   - default:
577   - break;
578   - }
579   - sas_notify_lldd_dev_gone(dev);
580   - if (!res) {
581   - sas_notify_lldd_dev_found(dev);
582   - res = sas_rphy_add(dev->rphy);
583   - }
584   -
585   - return res;
586   -}
587   -
588 194 /**
589 195 * sas_discover_end_dev -- discover an end device (SSP, etc)
590 196 * @end: pointer to domain device of interest
591 197  
592 198  
... ... @@ -690,11 +296,14 @@
690 296 case FANOUT_DEV:
691 297 error = sas_discover_root_expander(dev);
692 298 break;
  299 +#ifdef CONFIG_SCSI_SAS_ATA
693 300 case SATA_DEV:
694 301 case SATA_PM:
695 302 error = sas_discover_sata(dev);
696 303 break;
  304 +#endif
697 305 default:
  306 + error = -ENXIO;
698 307 SAS_DPRINTK("unhandled device %d\n", dev->dev_type);
699 308 break;
700 309 }
drivers/scsi/libsas/sas_expander.c
... ... @@ -535,6 +535,8 @@
535 535  
536 536 }
537 537  
  538 +#ifdef CONFIG_SCSI_SAS_ATA
  539 +
538 540 #define RPS_REQ_SIZE 16
539 541 #define RPS_RESP_SIZE 60
540 542  
... ... @@ -578,6 +580,7 @@
578 580 kfree(rps_req);
579 581 return res;
580 582 }
  583 +#endif
581 584  
582 585 static void sas_ex_get_linkrate(struct domain_device *parent,
583 586 struct domain_device *child,
... ... @@ -645,6 +648,7 @@
645 648 }
646 649 sas_ex_get_linkrate(parent, child, phy);
647 650  
  651 +#ifdef CONFIG_SCSI_SAS_ATA
648 652 if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) {
649 653 child->dev_type = SATA_DEV;
650 654 if (phy->attached_tproto & SAS_PROTO_STP)
... ... @@ -682,7 +686,9 @@
682 686 SAS_ADDR(parent->sas_addr), phy_id, res);
683 687 goto out_list_del;
684 688 }
685   - } else if (phy->attached_tproto & SAS_PROTO_SSP) {
  689 + } else
  690 +#endif
  691 + if (phy->attached_tproto & SAS_PROTO_SSP) {
686 692 child->dev_type = SAS_END_DEV;
687 693 rphy = sas_end_device_alloc(phy->port);
688 694 /* FIXME: error handling */
... ... @@ -710,6 +716,7 @@
710 716 SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n",
711 717 phy->attached_tproto, SAS_ADDR(parent->sas_addr),
712 718 phy_id);
  719 + goto out_free;
713 720 }
714 721  
715 722 list_add_tail(&child->siblings, &parent_ex->children);
include/scsi/sas_ata.h
... ... @@ -28,6 +28,8 @@
28 28 #include <linux/libata.h>
29 29 #include <scsi/libsas.h>
30 30  
  31 +#ifdef CONFIG_SCSI_SAS_ATA
  32 +
31 33 static inline int dev_is_sata(struct domain_device *dev)
32 34 {
33 35 return (dev->rphy->identify.target_port_protocols & SAS_PROTOCOL_SATA);
... ... @@ -37,6 +39,23 @@
37 39 struct scsi_target *starget);
38 40  
39 41 void sas_ata_task_abort(struct sas_task *task);
  42 +
  43 +#else
  44 +
  45 +
  46 +static inline int dev_is_sata(struct domain_device *dev)
  47 +{
  48 + return 0;
  49 +}
  50 +int sas_ata_init_host_and_port(struct domain_device *found_dev,
  51 + struct scsi_target *starget)
  52 +{
  53 + return 0;
  54 +}
  55 +void sas_ata_task_abort(struct sas_task *task)
  56 +{
  57 +}
  58 +#endif
40 59  
41 60 #endif /* _SAS_ATA_H_ */