aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-22 14:36:49 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-22 14:36:49 -0400
commite6f194d8f6f50da6837af637b2fd839c34185f7a (patch)
treef3c479a2bc24d49a150ff183e2614ee0f76cb366 /drivers/scsi/libsas
parent7578634990fb47cc30083fbd812689aa6deacfc0 (diff)
parentb91421749a1840148d8c81637c03c0ace3f35269 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (60 commits) [SCSI] libsas: make ATA functions selectable by a config option [SCSI] bsg: unexport sg v3 helper functions [SCSI] bsg: fix bsg_unregister_queue [SCSI] bsg: make class backlinks [SCSI] 3w-9xxx: add support for 9690SA [SCSI] bsg: fix bsg_register_queue error path [SCSI] ESP: Increase ESP_BUS_TIMEOUT to 275. [SCSI] libsas: fix scr_read/write users and update the libata documentation [SCSI] mpt fusion: update Kconfig help [SCSI] scsi_transport_sas: add destructor for bsg [SCSI] iscsi_tcp: buggered kmalloc() [SCSI] qla2xxx: Update version number to 8.02.00-k2. [SCSI] qla2xxx: Add ISP25XX support. [SCSI] qla2xxx: Use pci_try_set_mwi(). [SCSI] qla2xxx: Use PCI-X/PCI-Express read control interfaces. [SCSI] qla2xxx: Re-factor isp_operations to static structures. [SCSI] qla2xxx: Validate mid-layer 'underflow' during check-condition handling. [SCSI] qla2xxx: Correct setting of 'current' and 'supported' speeds during FDMI registration. [SCSI] qla2xxx: Generalize iIDMA support. [SCSI] qla2xxx: Generalize FW-Interface-2 support. ...
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r--drivers/scsi/libsas/Kconfig7
-rw-r--r--drivers/scsi/libsas/Makefile1
-rw-r--r--drivers/scsi/libsas/sas_ata.c817
-rw-r--r--drivers/scsi/libsas/sas_discover.c402
-rw-r--r--drivers/scsi/libsas/sas_expander.c230
-rw-r--r--drivers/scsi/libsas/sas_init.c1
-rw-r--r--drivers/scsi/libsas/sas_internal.h3
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c74
8 files changed, 1024 insertions, 511 deletions
diff --git a/drivers/scsi/libsas/Kconfig b/drivers/scsi/libsas/Kconfig
index aafdc92f8312..3a3c1ac9c6cd 100644
--- a/drivers/scsi/libsas/Kconfig
+++ b/drivers/scsi/libsas/Kconfig
@@ -30,6 +30,13 @@ config SCSI_SAS_LIBSAS
30 This provides transport specific helpers for SAS drivers which 30 This provides transport specific helpers for SAS drivers which
31 use the domain device construct (like the aic94xxx). 31 use the domain device construct (like the aic94xxx).
32 32
33config 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
33config SCSI_SAS_LIBSAS_DEBUG 40config SCSI_SAS_LIBSAS_DEBUG
34 bool "Compile the SAS Domain Transport Attributes in debug mode" 41 bool "Compile the SAS Domain Transport Attributes in debug mode"
35 default y 42 default y
diff --git a/drivers/scsi/libsas/Makefile b/drivers/scsi/libsas/Makefile
index 44d972a3b4bd..fd387b91856e 100644
--- a/drivers/scsi/libsas/Makefile
+++ b/drivers/scsi/libsas/Makefile
@@ -34,3 +34,4 @@ libsas-y += sas_init.o \
34 sas_discover.o \ 34 sas_discover.o \
35 sas_expander.o \ 35 sas_expander.o \
36 sas_scsi_host.o 36 sas_scsi_host.o
37libsas-$(CONFIG_SCSI_SAS_ATA) += sas_ata.o
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
new file mode 100644
index 000000000000..ced2de32c511
--- /dev/null
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -0,0 +1,817 @@
1/*
2 * Support for SATA devices on Serial Attached SCSI (SAS) controllers
3 *
4 * Copyright (C) 2006 IBM Corporation
5 *
6 * Written by: Darrick J. Wong <djwong@us.ibm.com>, IBM Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 */
23
24#include <linux/scatterlist.h>
25
26#include <scsi/sas_ata.h>
27#include "sas_internal.h"
28#include <scsi/scsi_host.h>
29#include <scsi/scsi_device.h>
30#include <scsi/scsi_tcq.h>
31#include <scsi/scsi.h>
32#include <scsi/scsi_transport.h>
33#include <scsi/scsi_transport_sas.h>
34#include "../scsi_sas_internal.h"
35#include "../scsi_transport_api.h"
36#include <scsi/scsi_eh.h>
37
38static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts)
39{
40 /* Cheesy attempt to translate SAS errors into ATA. Hah! */
41
42 /* transport error */
43 if (ts->resp == SAS_TASK_UNDELIVERED)
44 return AC_ERR_ATA_BUS;
45
46 /* ts->resp == SAS_TASK_COMPLETE */
47 /* task delivered, what happened afterwards? */
48 switch (ts->stat) {
49 case SAS_DEV_NO_RESPONSE:
50 return AC_ERR_TIMEOUT;
51
52 case SAS_INTERRUPTED:
53 case SAS_PHY_DOWN:
54 case SAS_NAK_R_ERR:
55 return AC_ERR_ATA_BUS;
56
57
58 case SAS_DATA_UNDERRUN:
59 /*
60 * Some programs that use the taskfile interface
61 * (smartctl in particular) can cause underrun
62 * problems. Ignore these errors, perhaps at our
63 * peril.
64 */
65 return 0;
66
67 case SAS_DATA_OVERRUN:
68 case SAS_QUEUE_FULL:
69 case SAS_DEVICE_UNKNOWN:
70 case SAS_SG_ERR:
71 return AC_ERR_INVALID;
72
73 case SAM_CHECK_COND:
74 case SAS_OPEN_TO:
75 case SAS_OPEN_REJECT:
76 SAS_DPRINTK("%s: Saw error %d. What to do?\n",
77 __FUNCTION__, ts->stat);
78 return AC_ERR_OTHER;
79
80 case SAS_ABORTED_TASK:
81 return AC_ERR_DEV;
82
83 case SAS_PROTO_RESPONSE:
84 /* This means the ending_fis has the error
85 * value; return 0 here to collect it */
86 return 0;
87 default:
88 return 0;
89 }
90}
91
92static void sas_ata_task_done(struct sas_task *task)
93{
94 struct ata_queued_cmd *qc = task->uldd_task;
95 struct domain_device *dev;
96 struct task_status_struct *stat = &task->task_status;
97 struct ata_task_resp *resp = (struct ata_task_resp *)stat->buf;
98 struct sas_ha_struct *sas_ha;
99 enum ata_completion_errors ac;
100 unsigned long flags;
101
102 if (!qc)
103 goto qc_already_gone;
104
105 dev = qc->ap->private_data;
106 sas_ha = dev->port->ha;
107
108 spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
109 if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_GOOD) {
110 ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf);
111 qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command);
112 dev->sata_dev.sstatus = resp->sstatus;
113 dev->sata_dev.serror = resp->serror;
114 dev->sata_dev.scontrol = resp->scontrol;
115 } else if (stat->stat != SAM_STAT_GOOD) {
116 ac = sas_to_ata_err(stat);
117 if (ac) {
118 SAS_DPRINTK("%s: SAS error %x\n", __FUNCTION__,
119 stat->stat);
120 /* We saw a SAS error. Send a vague error. */
121 qc->err_mask = ac;
122 dev->sata_dev.tf.feature = 0x04; /* status err */
123 dev->sata_dev.tf.command = ATA_ERR;
124 }
125 }
126
127 qc->lldd_task = NULL;
128 if (qc->scsicmd)
129 ASSIGN_SAS_TASK(qc->scsicmd, NULL);
130 ata_qc_complete(qc);
131 spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
132
133 /*
134 * If the sas_task has an ata qc, a scsi_cmnd and the aborted
135 * flag is set, then we must have come in via the libsas EH
136 * functions. When we exit this function, we need to put the
137 * scsi_cmnd on the list of finished errors. The ata_qc_complete
138 * call cleans up the libata side of things but we're protected
139 * from the scsi_cmnd going away because the scsi_cmnd is owned
140 * by the EH, making libata's call to scsi_done a NOP.
141 */
142 spin_lock_irqsave(&task->task_state_lock, flags);
143 if (qc->scsicmd && task->task_state_flags & SAS_TASK_STATE_ABORTED)
144 scsi_eh_finish_cmd(qc->scsicmd, &sas_ha->eh_done_q);
145 spin_unlock_irqrestore(&task->task_state_lock, flags);
146
147qc_already_gone:
148 list_del_init(&task->list);
149 sas_free_task(task);
150}
151
152static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
153{
154 int res;
155 struct sas_task *task;
156 struct domain_device *dev = qc->ap->private_data;
157 struct sas_ha_struct *sas_ha = dev->port->ha;
158 struct Scsi_Host *host = sas_ha->core.shost;
159 struct sas_internal *i = to_sas_internal(host->transportt);
160 struct scatterlist *sg;
161 unsigned int num = 0;
162 unsigned int xfer = 0;
163
164 task = sas_alloc_task(GFP_ATOMIC);
165 if (!task)
166 return AC_ERR_SYSTEM;
167 task->dev = dev;
168 task->task_proto = SAS_PROTOCOL_STP;
169 task->task_done = sas_ata_task_done;
170
171 if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
172 qc->tf.command == ATA_CMD_FPDMA_READ) {
173 /* Need to zero out the tag libata assigned us */
174 qc->tf.nsect = 0;
175 }
176
177 ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis);
178 task->uldd_task = qc;
179 if (is_atapi_taskfile(&qc->tf)) {
180 memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
181 task->total_xfer_len = qc->nbytes + qc->pad_len;
182 task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
183 } else {
184 ata_for_each_sg(sg, qc) {
185 num++;
186 xfer += sg->length;
187 }
188
189 task->total_xfer_len = xfer;
190 task->num_scatter = num;
191 }
192
193 task->data_dir = qc->dma_dir;
194 task->scatter = qc->__sg;
195 task->ata_task.retry_count = 1;
196 task->task_state_flags = SAS_TASK_STATE_PENDING;
197 qc->lldd_task = task;
198
199 switch (qc->tf.protocol) {
200 case ATA_PROT_NCQ:
201 task->ata_task.use_ncq = 1;
202 /* fall through */
203 case ATA_PROT_ATAPI_DMA:
204 case ATA_PROT_DMA:
205 task->ata_task.dma_xfer = 1;
206 break;
207 }
208
209 if (qc->scsicmd)
210 ASSIGN_SAS_TASK(qc->scsicmd, task);
211
212 if (sas_ha->lldd_max_execute_num < 2)
213 res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC);
214 else
215 res = sas_queue_up(task);
216
217 /* Examine */
218 if (res) {
219 SAS_DPRINTK("lldd_execute_task returned: %d\n", res);
220
221 if (qc->scsicmd)
222 ASSIGN_SAS_TASK(qc->scsicmd, NULL);
223 sas_free_task(task);
224 return AC_ERR_SYSTEM;
225 }
226
227 return 0;
228}
229
230static u8 sas_ata_check_status(struct ata_port *ap)
231{
232 struct domain_device *dev = ap->private_data;
233 return dev->sata_dev.tf.command;
234}
235
236static void sas_ata_phy_reset(struct ata_port *ap)
237{
238 struct domain_device *dev = ap->private_data;
239 struct sas_internal *i =
240 to_sas_internal(dev->port->ha->core.shost->transportt);
241 int res = 0;
242
243 if (i->dft->lldd_I_T_nexus_reset)
244 res = i->dft->lldd_I_T_nexus_reset(dev);
245
246 if (res)
247 SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__);
248
249 switch (dev->sata_dev.command_set) {
250 case ATA_COMMAND_SET:
251 SAS_DPRINTK("%s: Found ATA device.\n", __FUNCTION__);
252 ap->device[0].class = ATA_DEV_ATA;
253 break;
254 case ATAPI_COMMAND_SET:
255 SAS_DPRINTK("%s: Found ATAPI device.\n", __FUNCTION__);
256 ap->device[0].class = ATA_DEV_ATAPI;
257 break;
258 default:
259 SAS_DPRINTK("%s: Unknown SATA command set: %d.\n",
260 __FUNCTION__,
261 dev->sata_dev.command_set);
262 ap->device[0].class = ATA_DEV_UNKNOWN;
263 break;
264 }
265
266 ap->cbl = ATA_CBL_SATA;
267}
268
269static void sas_ata_post_internal(struct ata_queued_cmd *qc)
270{
271 if (qc->flags & ATA_QCFLAG_FAILED)
272 qc->err_mask |= AC_ERR_OTHER;
273
274 if (qc->err_mask) {
275 /*
276 * Find the sas_task and kill it. By this point,
277 * libata has decided to kill the qc, so we needn't
278 * bother with sas_ata_task_done. But we still
279 * ought to abort the task.
280 */
281 struct sas_task *task = qc->lldd_task;
282 unsigned long flags;
283
284 qc->lldd_task = NULL;
285 if (task) {
286 /* Should this be a AT(API) device reset? */
287 spin_lock_irqsave(&task->task_state_lock, flags);
288 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
289 spin_unlock_irqrestore(&task->task_state_lock, flags);
290
291 task->uldd_task = NULL;
292 __sas_task_abort(task);
293 }
294 }
295}
296
297static void sas_ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
298{
299 struct domain_device *dev = ap->private_data;
300 memcpy(tf, &dev->sata_dev.tf, sizeof (*tf));
301}
302
303static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
304 u32 val)
305{
306 struct domain_device *dev = ap->private_data;
307
308 SAS_DPRINTK("STUB %s\n", __FUNCTION__);
309 switch (sc_reg_in) {
310 case SCR_STATUS:
311 dev->sata_dev.sstatus = val;
312 break;
313 case SCR_CONTROL:
314 dev->sata_dev.scontrol = val;
315 break;
316 case SCR_ERROR:
317 dev->sata_dev.serror = val;
318 break;
319 case SCR_ACTIVE:
320 dev->sata_dev.ap->sactive = val;
321 break;
322 default:
323 return -EINVAL;
324 }
325 return 0;
326}
327
328static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
329 u32 *val)
330{
331 struct domain_device *dev = ap->private_data;
332
333 SAS_DPRINTK("STUB %s\n", __FUNCTION__);
334 switch (sc_reg_in) {
335 case SCR_STATUS:
336 *val = dev->sata_dev.sstatus;
337 return 0;
338 case SCR_CONTROL:
339 *val = dev->sata_dev.scontrol;
340 return 0;
341 case SCR_ERROR:
342 *val = dev->sata_dev.serror;
343 return 0;
344 case SCR_ACTIVE:
345 *val = dev->sata_dev.ap->sactive;
346 return 0;
347 default:
348 return -EINVAL;
349 }
350}
351
352static struct ata_port_operations sas_sata_ops = {
353 .port_disable = ata_port_disable,
354 .check_status = sas_ata_check_status,
355 .check_altstatus = sas_ata_check_status,
356 .dev_select = ata_noop_dev_select,
357 .phy_reset = sas_ata_phy_reset,
358 .post_internal_cmd = sas_ata_post_internal,
359 .tf_read = sas_ata_tf_read,
360 .qc_prep = ata_noop_qc_prep,
361 .qc_issue = sas_ata_qc_issue,
362 .port_start = ata_sas_port_start,
363 .port_stop = ata_sas_port_stop,
364 .scr_read = sas_ata_scr_read,
365 .scr_write = sas_ata_scr_write
366};
367
368static struct ata_port_info sata_port_info = {
369 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET |
370 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ,
371 .pio_mask = 0x1f, /* PIO0-4 */
372 .mwdma_mask = 0x07, /* MWDMA0-2 */
373 .udma_mask = ATA_UDMA6,
374 .port_ops = &sas_sata_ops
375};
376
377int sas_ata_init_host_and_port(struct domain_device *found_dev,
378 struct scsi_target *starget)
379{
380 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
381 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
382 struct ata_port *ap;
383
384 ata_host_init(&found_dev->sata_dev.ata_host,
385 &ha->pcidev->dev,
386 sata_port_info.flags,
387 &sas_sata_ops);
388 ap = ata_sas_port_alloc(&found_dev->sata_dev.ata_host,
389 &sata_port_info,
390 shost);
391 if (!ap) {
392 SAS_DPRINTK("ata_sas_port_alloc failed.\n");
393 return -ENODEV;
394 }
395
396 ap->private_data = found_dev;
397 ap->cbl = ATA_CBL_SATA;
398 ap->scsi_host = shost;
399 found_dev->sata_dev.ap = ap;
400
401 return 0;
402}
403
404void sas_ata_task_abort(struct sas_task *task)
405{
406 struct ata_queued_cmd *qc = task->uldd_task;
407 struct completion *waiting;
408
409 /* Bounce SCSI-initiated commands to the SCSI EH */
410 if (qc->scsicmd) {
411 scsi_req_abort_cmd(qc->scsicmd);
412 scsi_schedule_eh(qc->scsicmd->device->host);
413 return;
414 }
415
416 /* Internal command, fake a timeout and complete. */
417 qc->flags &= ~ATA_QCFLAG_ACTIVE;
418 qc->flags |= ATA_QCFLAG_FAILED;
419 qc->err_mask |= AC_ERR_TIMEOUT;
420 waiting = qc->private_data;
421 complete(waiting);
422}
423
424static 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
437static 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 */
453static 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 }
567ex_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 }
575out:
576 return res;
577}
578
579/* ---------- SATA ---------- */
580
581static 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 */
633static 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);
658out:
659 return res;
660}
661
662static 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 */
691static 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 }
733cont1:
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;
763out_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
770static 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 */
790int 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;
817}
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index a65598b1e536..6ac9f61d006a 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -55,149 +55,6 @@ void sas_init_dev(struct domain_device *dev)
55 } 55 }
56} 56}
57 57
58static 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
71static 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 */
87static 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
114 for (retries = 0; retries < 5; retries++) {
115 task->task_state_flags = SAS_TASK_STATE_PENDING;
116 init_completion(&task->completion);
117
118 task->timer.data = (unsigned long) task;
119 task->timer.function = sas_task_timedout;
120 task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ;
121 add_timer(&task->timer);
122
123 res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
124 if (res) {
125 del_timer(&task->timer);
126 SAS_DPRINTK("executing SAS discovery task failed:%d\n",
127 res);
128 goto ex_err;
129 }
130 wait_for_completion(&task->completion);
131 res = -ETASK;
132 if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
133 int res2;
134 SAS_DPRINTK("task aborted, flags:0x%x\n",
135 task->task_state_flags);
136 res2 = i->dft->lldd_abort_task(task);
137 SAS_DPRINTK("came back from abort task\n");
138 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
139 if (res2 == TMF_RESP_FUNC_COMPLETE)
140 continue; /* Retry the task */
141 else
142 goto ex_err;
143 }
144 }
145 if (task->task_status.stat == SAM_BUSY ||
146 task->task_status.stat == SAM_TASK_SET_FULL ||
147 task->task_status.stat == SAS_QUEUE_FULL) {
148 SAS_DPRINTK("task: q busy, sleeping...\n");
149 schedule_timeout_interruptible(HZ);
150 } else if (task->task_status.stat == SAM_CHECK_COND) {
151 struct scsi_sense_hdr shdr;
152
153 if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size,
154 &shdr)) {
155 SAS_DPRINTK("couldn't normalize sense\n");
156 continue;
157 }
158 if ((shdr.sense_key == 6 && shdr.asc == 0x29) ||
159 (shdr.sense_key == 2 && shdr.asc == 4 &&
160 shdr.ascq == 1)) {
161 SAS_DPRINTK("device %016llx LUN: %016llx "
162 "powering up or not ready yet, "
163 "sleeping...\n",
164 SAS_ADDR(task->dev->sas_addr),
165 SAS_ADDR(task->ssp_task.LUN));
166
167 schedule_timeout_interruptible(5*HZ);
168 } else if (shdr.sense_key == 1) {
169 res = 0;
170 break;
171 } else if (shdr.sense_key == 5) {
172 break;
173 } else {
174 SAS_DPRINTK("dev %016llx LUN: %016llx "
175 "sense key:0x%x ASC:0x%x ASCQ:0x%x"
176 "\n",
177 SAS_ADDR(task->dev->sas_addr),
178 SAS_ADDR(task->ssp_task.LUN),
179 shdr.sense_key,
180 shdr.asc, shdr.ascq);
181 }
182 } else if (task->task_status.resp != SAS_TASK_COMPLETE ||
183 task->task_status.stat != SAM_GOOD) {
184 SAS_DPRINTK("task finished with resp:0x%x, "
185 "stat:0x%x\n",
186 task->task_status.resp,
187 task->task_status.stat);
188 goto ex_err;
189 } else {
190 res = 0;
191 break;
192 }
193 }
194ex_err:
195 if (pci_dma_dir != PCI_DMA_NONE)
196 kfree(scatter);
197out:
198 return res;
199}
200
201/* ---------- Domain device discovery ---------- */ 58/* ---------- Domain device discovery ---------- */
202 59
203/** 60/**
@@ -255,6 +112,7 @@ static int sas_get_port_device(struct asd_sas_port *port)
255 112
256 switch (dev->dev_type) { 113 switch (dev->dev_type) {
257 case SAS_END_DEV: 114 case SAS_END_DEV:
115 case SATA_DEV:
258 rphy = sas_end_device_alloc(port->port); 116 rphy = sas_end_device_alloc(port->port);
259 break; 117 break;
260 case EDGE_DEV: 118 case EDGE_DEV:
@@ -265,7 +123,6 @@ static int sas_get_port_device(struct asd_sas_port *port)
265 rphy = sas_expander_alloc(port->port, 123 rphy = sas_expander_alloc(port->port,
266 SAS_FANOUT_EXPANDER_DEVICE); 124 SAS_FANOUT_EXPANDER_DEVICE);
267 break; 125 break;
268 case SATA_DEV:
269 default: 126 default:
270 printk("ERROR: Unidentified device type %d\n", dev->dev_type); 127 printk("ERROR: Unidentified device type %d\n", dev->dev_type);
271 rphy = NULL; 128 rphy = NULL;
@@ -292,207 +149,15 @@ static int sas_get_port_device(struct asd_sas_port *port)
292 port->disc.max_level = 0; 149 port->disc.max_level = 0;
293 150
294 dev->rphy = rphy; 151 dev->rphy = rphy;
295 spin_lock(&port->dev_list_lock); 152 spin_lock_irq(&port->dev_list_lock);
296 list_add_tail(&dev->dev_list_node, &port->dev_list); 153 list_add_tail(&dev->dev_list_node, &port->dev_list);
297 spin_unlock(&port->dev_list_lock); 154 spin_unlock_irq(&port->dev_list_lock);
298 155
299 return 0; 156 return 0;
300} 157}
301 158
302/* ---------- Discover and Revalidate ---------- */ 159/* ---------- Discover and Revalidate ---------- */
303 160
304/* ---------- SATA ---------- */
305
306static void sas_get_ata_command_set(struct domain_device *dev)
307{
308 struct dev_to_host_fis *fis =
309 (struct dev_to_host_fis *) dev->frame_rcvd;
310
311 if ((fis->sector_count == 1 && /* ATA */
312 fis->lbal == 1 &&
313 fis->lbam == 0 &&
314 fis->lbah == 0 &&
315 fis->device == 0)
316 ||
317 (fis->sector_count == 0 && /* CE-ATA (mATA) */
318 fis->lbal == 0 &&
319 fis->lbam == 0xCE &&
320 fis->lbah == 0xAA &&
321 (fis->device & ~0x10) == 0))
322
323 dev->sata_dev.command_set = ATA_COMMAND_SET;
324
325 else if ((fis->interrupt_reason == 1 && /* ATAPI */
326 fis->lbal == 1 &&
327 fis->byte_count_low == 0x14 &&
328 fis->byte_count_high == 0xEB &&
329 (fis->device & ~0x10) == 0))
330
331 dev->sata_dev.command_set = ATAPI_COMMAND_SET;
332
333 else if ((fis->sector_count == 1 && /* SEMB */
334 fis->lbal == 1 &&
335 fis->lbam == 0x3C &&
336 fis->lbah == 0xC3 &&
337 fis->device == 0)
338 ||
339 (fis->interrupt_reason == 1 && /* SATA PM */
340 fis->lbal == 1 &&
341 fis->byte_count_low == 0x69 &&
342 fis->byte_count_high == 0x96 &&
343 (fis->device & ~0x10) == 0))
344
345 /* Treat it as a superset? */
346 dev->sata_dev.command_set = ATAPI_COMMAND_SET;
347}
348
349/**
350 * sas_issue_ata_cmd -- Basic SATA command processing for discovery
351 * @dev: the device to send the command to
352 * @command: the command register
353 * @features: the features register
354 * @buffer: pointer to buffer to do I/O
355 * @size: size of @buffer
356 * @pci_dma_dir: PCI_DMA_...
357 */
358static int sas_issue_ata_cmd(struct domain_device *dev, u8 command,
359 u8 features, void *buffer, int size,
360 int pci_dma_dir)
361{
362 int res = 0;
363 struct sas_task *task;
364 struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *)
365 &dev->frame_rcvd[0];
366
367 res = -ENOMEM;
368 task = sas_alloc_task(GFP_KERNEL);
369 if (!task)
370 goto out;
371
372 task->dev = dev;
373
374 task->ata_task.fis.command = command;
375 task->ata_task.fis.features = features;
376 task->ata_task.fis.device = d2h_fis->device;
377 task->ata_task.retry_count = 1;
378
379 res = sas_execute_task(task, buffer, size, pci_dma_dir);
380
381 sas_free_task(task);
382out:
383 return res;
384}
385
386static void sas_sata_propagate_sas_addr(struct domain_device *dev)
387{
388 unsigned long flags;
389 struct asd_sas_port *port = dev->port;
390 struct asd_sas_phy *phy;
391
392 BUG_ON(dev->parent);
393
394 memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
395 spin_lock_irqsave(&port->phy_list_lock, flags);
396 list_for_each_entry(phy, &port->phy_list, port_phy_el)
397 memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
398 spin_unlock_irqrestore(&port->phy_list_lock, flags);
399}
400
401#define ATA_IDENTIFY_DEV 0xEC
402#define ATA_IDENTIFY_PACKET_DEV 0xA1
403#define ATA_SET_FEATURES 0xEF
404#define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07
405
406/**
407 * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV)
408 * @dev: STP/SATA device of interest (ATA/ATAPI)
409 *
410 * The LLDD has already been notified of this device, so that we can
411 * send FISes to it. Here we try to get IDENTIFY DEVICE or IDENTIFY
412 * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its
413 * performance for this device.
414 */
415static int sas_discover_sata_dev(struct domain_device *dev)
416{
417 int res;
418 __le16 *identify_x;
419 u8 command;
420
421 identify_x = kzalloc(512, GFP_KERNEL);
422 if (!identify_x)
423 return -ENOMEM;
424
425 if (dev->sata_dev.command_set == ATA_COMMAND_SET) {
426 dev->sata_dev.identify_device = identify_x;
427 command = ATA_IDENTIFY_DEV;
428 } else {
429 dev->sata_dev.identify_packet_device = identify_x;
430 command = ATA_IDENTIFY_PACKET_DEV;
431 }
432
433 res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
434 PCI_DMA_FROMDEVICE);
435 if (res)
436 goto out_err;
437
438 /* lives on the media? */
439 if (le16_to_cpu(identify_x[0]) & 4) {
440 /* incomplete response */
441 SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
442 "dev %llx\n", SAS_ADDR(dev->sas_addr));
443 if (!le16_to_cpu(identify_x[83] & (1<<6)))
444 goto cont1;
445 res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
446 ATA_FEATURE_PUP_STBY_SPIN_UP,
447 NULL, 0, PCI_DMA_NONE);
448 if (res)
449 goto cont1;
450
451 schedule_timeout_interruptible(5*HZ); /* More time? */
452 res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
453 PCI_DMA_FROMDEVICE);
454 if (res)
455 goto out_err;
456 }
457cont1:
458 /* Get WWN */
459 if (dev->port->oob_mode != SATA_OOB_MODE) {
460 memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr,
461 SAS_ADDR_SIZE);
462 } else if (dev->sata_dev.command_set == ATA_COMMAND_SET &&
463 (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000)
464 == 0x5000) {
465 int i;
466
467 for (i = 0; i < 4; i++) {
468 dev->sas_addr[2*i] =
469 (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8;
470 dev->sas_addr[2*i+1] =
471 le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF;
472 }
473 }
474 sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
475 if (!dev->parent)
476 sas_sata_propagate_sas_addr(dev);
477
478 /* XXX Hint: register this SATA device with SATL.
479 When this returns, dev->sata_dev->lu is alive and
480 present.
481 sas_satl_register_dev(dev);
482 */
483 return 0;
484out_err:
485 dev->sata_dev.identify_packet_device = NULL;
486 dev->sata_dev.identify_device = NULL;
487 kfree(identify_x);
488 return res;
489}
490
491static int sas_discover_sata_pm(struct domain_device *dev)
492{
493 return -ENODEV;
494}
495
496int sas_notify_lldd_dev_found(struct domain_device *dev) 161int sas_notify_lldd_dev_found(struct domain_device *dev)
497{ 162{
498 int res = 0; 163 int res = 0;
@@ -525,60 +190,6 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev)
525 190
526/* ---------- Common/dispatchers ---------- */ 191/* ---------- Common/dispatchers ---------- */
527 192
528/**
529 * sas_discover_sata -- discover an STP/SATA domain device
530 * @dev: pointer to struct domain_device of interest
531 *
532 * First we notify the LLDD of this device, so we can send frames to
533 * it. Then depending on the type of device we call the appropriate
534 * discover functions. Once device discover is done, we notify the
535 * LLDD so that it can fine-tune its parameters for the device, by
536 * removing it and then adding it. That is, the second time around,
537 * the driver would have certain fields, that it is looking at, set.
538 * Finally we initialize the kobj so that the device can be added to
539 * the system at registration time. Devices directly attached to a HA
540 * port, have no parents. All other devices do, and should have their
541 * "parent" pointer set appropriately before calling this function.
542 */
543int sas_discover_sata(struct domain_device *dev)
544{
545 int res;
546
547 sas_get_ata_command_set(dev);
548
549 res = sas_notify_lldd_dev_found(dev);
550 if (res)
551 goto out_err2;
552
553 switch (dev->dev_type) {
554 case SATA_DEV:
555 res = sas_discover_sata_dev(dev);
556 break;
557 case SATA_PM:
558 res = sas_discover_sata_pm(dev);
559 break;
560 default:
561 break;
562 }
563 if (res)
564 goto out_err;
565
566 sas_notify_lldd_dev_gone(dev);
567 res = sas_notify_lldd_dev_found(dev);
568 if (res)
569 goto out_err2;
570
571 res = sas_rphy_add(dev->rphy);
572 if (res)
573 goto out_err;
574
575 return res;
576
577out_err:
578 sas_notify_lldd_dev_gone(dev);
579out_err2:
580 return res;
581}
582 193
583/** 194/**
584 * sas_discover_end_dev -- discover an end device (SSP, etc) 195 * sas_discover_end_dev -- discover an end device (SSP, etc)
@@ -685,11 +296,14 @@ static void sas_discover_domain(struct work_struct *work)
685 case FANOUT_DEV: 296 case FANOUT_DEV:
686 error = sas_discover_root_expander(dev); 297 error = sas_discover_root_expander(dev);
687 break; 298 break;
299#ifdef CONFIG_SCSI_SAS_ATA
688 case SATA_DEV: 300 case SATA_DEV:
689 case SATA_PM: 301 case SATA_PM:
690 error = sas_discover_sata(dev); 302 error = sas_discover_sata(dev);
691 break; 303 break;
304#endif
692 default: 305 default:
306 error = -ENXIO;
693 SAS_DPRINTK("unhandled device %d\n", dev->dev_type); 307 SAS_DPRINTK("unhandled device %d\n", dev->dev_type);
694 break; 308 break;
695 } 309 }
@@ -698,9 +312,9 @@ static void sas_discover_domain(struct work_struct *work)
698 sas_rphy_free(dev->rphy); 312 sas_rphy_free(dev->rphy);
699 dev->rphy = NULL; 313 dev->rphy = NULL;
700 314
701 spin_lock(&port->dev_list_lock); 315 spin_lock_irq(&port->dev_list_lock);
702 list_del_init(&dev->dev_list_node); 316 list_del_init(&dev->dev_list_node);
703 spin_unlock(&port->dev_list_lock); 317 spin_unlock_irq(&port->dev_list_lock);
704 318
705 kfree(dev); /* not kobject_register-ed yet */ 319 kfree(dev); /* not kobject_register-ed yet */
706 port->port_dev = NULL; 320 port->port_dev = NULL;
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 23e90c5f8f35..b500f0c1449c 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <linux/scatterlist.h> 25#include <linux/scatterlist.h>
26#include <linux/blkdev.h>
26 27
27#include "sas_internal.h" 28#include "sas_internal.h"
28 29
@@ -36,14 +37,6 @@ static int sas_configure_phy(struct domain_device *dev, int phy_id,
36 u8 *sas_addr, int include); 37 u8 *sas_addr, int include);
37static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr); 38static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr);
38 39
39#if 0
40/* FIXME: smp needs to migrate into the sas class */
41static ssize_t smp_portal_read(struct kobject *, struct bin_attribute *,
42 char *, loff_t, size_t);
43static ssize_t smp_portal_write(struct kobject *, struct bin_attribute *,
44 char *, loff_t, size_t);
45#endif
46
47/* ---------- SMP task management ---------- */ 40/* ---------- SMP task management ---------- */
48 41
49static void smp_task_timedout(unsigned long _task) 42static void smp_task_timedout(unsigned long _task)
@@ -220,6 +213,36 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
220#define DISCOVER_REQ_SIZE 16 213#define DISCOVER_REQ_SIZE 16
221#define DISCOVER_RESP_SIZE 56 214#define DISCOVER_RESP_SIZE 56
222 215
216static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
217 u8 *disc_resp, int single)
218{
219 int i, res;
220
221 disc_req[9] = single;
222 for (i = 1 ; i < 3; i++) {
223 struct discover_resp *dr;
224
225 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
226 disc_resp, DISCOVER_RESP_SIZE);
227 if (res)
228 return res;
229 /* This is detecting a failure to transmit inital
230 * dev to host FIS as described in section G.5 of
231 * sas-2 r 04b */
232 dr = &((struct smp_resp *)disc_resp)->disc;
233 if (!(dr->attached_dev_type == 0 &&
234 dr->attached_sata_dev))
235 break;
236 /* In order to generate the dev to host FIS, we
237 * send a link reset to the expander port */
238 sas_smp_phy_control(dev, single, PHY_FUNC_LINK_RESET, NULL);
239 /* Wait for the reset to trigger the negotiation */
240 msleep(500);
241 }
242 sas_set_ex_phy(dev, single, disc_resp);
243 return 0;
244}
245
223static int sas_ex_phy_discover(struct domain_device *dev, int single) 246static int sas_ex_phy_discover(struct domain_device *dev, int single)
224{ 247{
225 struct expander_device *ex = &dev->ex_dev; 248 struct expander_device *ex = &dev->ex_dev;
@@ -240,23 +263,15 @@ static int sas_ex_phy_discover(struct domain_device *dev, int single)
240 disc_req[1] = SMP_DISCOVER; 263 disc_req[1] = SMP_DISCOVER;
241 264
242 if (0 <= single && single < ex->num_phys) { 265 if (0 <= single && single < ex->num_phys) {
243 disc_req[9] = single; 266 res = sas_ex_phy_discover_helper(dev, disc_req, disc_resp, single);
244 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
245 disc_resp, DISCOVER_RESP_SIZE);
246 if (res)
247 goto out_err;
248 sas_set_ex_phy(dev, single, disc_resp);
249 } else { 267 } else {
250 int i; 268 int i;
251 269
252 for (i = 0; i < ex->num_phys; i++) { 270 for (i = 0; i < ex->num_phys; i++) {
253 disc_req[9] = i; 271 res = sas_ex_phy_discover_helper(dev, disc_req,
254 res = smp_execute_task(dev, disc_req, 272 disc_resp, i);
255 DISCOVER_REQ_SIZE, disc_resp,
256 DISCOVER_RESP_SIZE);
257 if (res) 273 if (res)
258 goto out_err; 274 goto out_err;
259 sas_set_ex_phy(dev, i, disc_resp);
260 } 275 }
261 } 276 }
262out_err: 277out_err:
@@ -520,6 +535,8 @@ int sas_smp_get_phy_events(struct sas_phy *phy)
520 535
521} 536}
522 537
538#ifdef CONFIG_SCSI_SAS_ATA
539
523#define RPS_REQ_SIZE 16 540#define RPS_REQ_SIZE 16
524#define RPS_RESP_SIZE 60 541#define RPS_RESP_SIZE 60
525 542
@@ -529,6 +546,7 @@ static int sas_get_report_phy_sata(struct domain_device *dev,
529{ 546{
530 int res; 547 int res;
531 u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE); 548 u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
549 u8 *resp = (u8 *)rps_resp;
532 550
533 if (!rps_req) 551 if (!rps_req)
534 return -ENOMEM; 552 return -ENOMEM;
@@ -539,9 +557,30 @@ static int sas_get_report_phy_sata(struct domain_device *dev,
539 res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE, 557 res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE,
540 rps_resp, RPS_RESP_SIZE); 558 rps_resp, RPS_RESP_SIZE);
541 559
560 /* 0x34 is the FIS type for the D2H fis. There's a potential
561 * standards cockup here. sas-2 explicitly specifies the FIS
562 * should be encoded so that FIS type is in resp[24].
563 * However, some expanders endian reverse this. Undo the
564 * reversal here */
565 if (!res && resp[27] == 0x34 && resp[24] != 0x34) {
566 int i;
567
568 for (i = 0; i < 5; i++) {
569 int j = 24 + (i*4);
570 u8 a, b;
571 a = resp[j + 0];
572 b = resp[j + 1];
573 resp[j + 0] = resp[j + 3];
574 resp[j + 1] = resp[j + 2];
575 resp[j + 2] = b;
576 resp[j + 3] = a;
577 }
578 }
579
542 kfree(rps_req); 580 kfree(rps_req);
543 return 0; 581 return res;
544} 582}
583#endif
545 584
546static void sas_ex_get_linkrate(struct domain_device *parent, 585static void sas_ex_get_linkrate(struct domain_device *parent,
547 struct domain_device *child, 586 struct domain_device *child,
@@ -609,6 +648,7 @@ static struct domain_device *sas_ex_discover_end_dev(
609 } 648 }
610 sas_ex_get_linkrate(parent, child, phy); 649 sas_ex_get_linkrate(parent, child, phy);
611 650
651#ifdef CONFIG_SCSI_SAS_ATA
612 if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) { 652 if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) {
613 child->dev_type = SATA_DEV; 653 child->dev_type = SATA_DEV;
614 if (phy->attached_tproto & SAS_PROTO_STP) 654 if (phy->attached_tproto & SAS_PROTO_STP)
@@ -625,16 +665,30 @@ static struct domain_device *sas_ex_discover_end_dev(
625 } 665 }
626 memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis, 666 memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
627 sizeof(struct dev_to_host_fis)); 667 sizeof(struct dev_to_host_fis));
668
669 rphy = sas_end_device_alloc(phy->port);
670 if (unlikely(!rphy))
671 goto out_free;
672
628 sas_init_dev(child); 673 sas_init_dev(child);
674
675 child->rphy = rphy;
676
677 spin_lock_irq(&parent->port->dev_list_lock);
678 list_add_tail(&child->dev_list_node, &parent->port->dev_list);
679 spin_unlock_irq(&parent->port->dev_list_lock);
680
629 res = sas_discover_sata(child); 681 res = sas_discover_sata(child);
630 if (res) { 682 if (res) {
631 SAS_DPRINTK("sas_discover_sata() for device %16llx at " 683 SAS_DPRINTK("sas_discover_sata() for device %16llx at "
632 "%016llx:0x%x returned 0x%x\n", 684 "%016llx:0x%x returned 0x%x\n",
633 SAS_ADDR(child->sas_addr), 685 SAS_ADDR(child->sas_addr),
634 SAS_ADDR(parent->sas_addr), phy_id, res); 686 SAS_ADDR(parent->sas_addr), phy_id, res);
635 goto out_free; 687 goto out_list_del;
636 } 688 }
637 } else if (phy->attached_tproto & SAS_PROTO_SSP) { 689 } else
690#endif
691 if (phy->attached_tproto & SAS_PROTO_SSP) {
638 child->dev_type = SAS_END_DEV; 692 child->dev_type = SAS_END_DEV;
639 rphy = sas_end_device_alloc(phy->port); 693 rphy = sas_end_device_alloc(phy->port);
640 /* FIXME: error handling */ 694 /* FIXME: error handling */
@@ -646,9 +700,9 @@ static struct domain_device *sas_ex_discover_end_dev(
646 child->rphy = rphy; 700 child->rphy = rphy;
647 sas_fill_in_rphy(child, rphy); 701 sas_fill_in_rphy(child, rphy);
648 702
649 spin_lock(&parent->port->dev_list_lock); 703 spin_lock_irq(&parent->port->dev_list_lock);
650 list_add_tail(&child->dev_list_node, &parent->port->dev_list); 704 list_add_tail(&child->dev_list_node, &parent->port->dev_list);
651 spin_unlock(&parent->port->dev_list_lock); 705 spin_unlock_irq(&parent->port->dev_list_lock);
652 706
653 res = sas_discover_end_dev(child); 707 res = sas_discover_end_dev(child);
654 if (res) { 708 if (res) {
@@ -662,6 +716,7 @@ static struct domain_device *sas_ex_discover_end_dev(
662 SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", 716 SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n",
663 phy->attached_tproto, SAS_ADDR(parent->sas_addr), 717 phy->attached_tproto, SAS_ADDR(parent->sas_addr),
664 phy_id); 718 phy_id);
719 goto out_free;
665 } 720 }
666 721
667 list_add_tail(&child->siblings, &parent_ex->children); 722 list_add_tail(&child->siblings, &parent_ex->children);
@@ -761,9 +816,9 @@ static struct domain_device *sas_ex_discover_expander(
761 sas_fill_in_rphy(child, rphy); 816 sas_fill_in_rphy(child, rphy);
762 sas_rphy_add(rphy); 817 sas_rphy_add(rphy);
763 818
764 spin_lock(&parent->port->dev_list_lock); 819 spin_lock_irq(&parent->port->dev_list_lock);
765 list_add_tail(&child->dev_list_node, &parent->port->dev_list); 820 list_add_tail(&child->dev_list_node, &parent->port->dev_list);
766 spin_unlock(&parent->port->dev_list_lock); 821 spin_unlock_irq(&parent->port->dev_list_lock);
767 822
768 res = sas_discover_expander(child); 823 res = sas_discover_expander(child);
769 if (res) { 824 if (res) {
@@ -1359,30 +1414,6 @@ static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr)
1359 return 0; 1414 return 0;
1360} 1415}
1361 1416
1362#if 0
1363#define SMP_BIN_ATTR_NAME "smp_portal"
1364
1365static void sas_ex_smp_hook(struct domain_device *dev)
1366{
1367 struct expander_device *ex_dev = &dev->ex_dev;
1368 struct bin_attribute *bin_attr = &ex_dev->smp_bin_attr;
1369
1370 memset(bin_attr, 0, sizeof(*bin_attr));
1371
1372 bin_attr->attr.name = SMP_BIN_ATTR_NAME;
1373 bin_attr->attr.mode = 0600;
1374
1375 bin_attr->size = 0;
1376 bin_attr->private = NULL;
1377 bin_attr->read = smp_portal_read;
1378 bin_attr->write= smp_portal_write;
1379 bin_attr->mmap = NULL;
1380
1381 ex_dev->smp_portal_pid = -1;
1382 init_MUTEX(&ex_dev->smp_sema);
1383}
1384#endif
1385
1386/** 1417/**
1387 * sas_discover_expander -- expander discovery 1418 * sas_discover_expander -- expander discovery
1388 * @ex: pointer to expander domain device 1419 * @ex: pointer to expander domain device
@@ -1844,76 +1875,49 @@ out:
1844 return res; 1875 return res;
1845} 1876}
1846 1877
1847#if 0 1878int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1848/* ---------- SMP portal ---------- */ 1879 struct request *req)
1849
1850static ssize_t smp_portal_write(struct kobject *kobj,
1851 struct bin_attribute *bin_attr,
1852 char *buf, loff_t offs, size_t size)
1853{ 1880{
1854 struct domain_device *dev = to_dom_device(kobj); 1881 struct domain_device *dev;
1855 struct expander_device *ex = &dev->ex_dev; 1882 int ret, type = rphy->identify.device_type;
1856 1883 struct request *rsp = req->next_rq;
1857 if (offs != 0)
1858 return -EFBIG;
1859 else if (size == 0)
1860 return 0;
1861 1884
1862 down_interruptible(&ex->smp_sema); 1885 if (!rsp) {
1863 if (ex->smp_req) 1886 printk("%s: space for a smp response is missing\n",
1864 kfree(ex->smp_req); 1887 __FUNCTION__);
1865 ex->smp_req = kzalloc(size, GFP_USER); 1888 return -EINVAL;
1866 if (!ex->smp_req) {
1867 up(&ex->smp_sema);
1868 return -ENOMEM;
1869 } 1889 }
1870 memcpy(ex->smp_req, buf, size);
1871 ex->smp_req_size = size;
1872 ex->smp_portal_pid = current->pid;
1873 up(&ex->smp_sema);
1874 1890
1875 return size; 1891 /* seems aic94xx doesn't support */
1876} 1892 if (!rphy) {
1877 1893 printk("%s: can we send a smp request to a host?\n",
1878static ssize_t smp_portal_read(struct kobject *kobj, 1894 __FUNCTION__);
1879 struct bin_attribute *bin_attr, 1895 return -EINVAL;
1880 char *buf, loff_t offs, size_t size) 1896 }
1881{
1882 struct domain_device *dev = to_dom_device(kobj);
1883 struct expander_device *ex = &dev->ex_dev;
1884 u8 *smp_resp;
1885 int res = -EINVAL;
1886
1887 /* XXX: sysfs gives us an offset of 0x10 or 0x8 while in fact
1888 * it should be 0.
1889 */
1890 1897
1891 down_interruptible(&ex->smp_sema); 1898 if (type != SAS_EDGE_EXPANDER_DEVICE &&
1892 if (!ex->smp_req || ex->smp_portal_pid != current->pid) 1899 type != SAS_FANOUT_EXPANDER_DEVICE) {
1893 goto out; 1900 printk("%s: can we send a smp request to a device?\n",
1901 __FUNCTION__);
1902 return -EINVAL;
1903 }
1894 1904
1895 res = 0; 1905 dev = sas_find_dev_by_rphy(rphy);
1896 if (size == 0) 1906 if (!dev) {
1897 goto out; 1907 printk("%s: fail to find a domain_device?\n", __FUNCTION__);
1908 return -EINVAL;
1909 }
1898 1910
1899 res = -ENOMEM; 1911 /* do we need to support multiple segments? */
1900 smp_resp = alloc_smp_resp(size); 1912 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
1901 if (!smp_resp) 1913 printk("%s: multiple segments req %u %u, rsp %u %u\n",
1902 goto out; 1914 __FUNCTION__, req->bio->bi_vcnt, req->data_len,
1903 res = smp_execute_task(dev, ex->smp_req, ex->smp_req_size, 1915 rsp->bio->bi_vcnt, rsp->data_len);
1904 smp_resp, size); 1916 return -EINVAL;
1905 if (!res) {
1906 memcpy(buf, smp_resp, size);
1907 res = size;
1908 } 1917 }
1909 1918
1910 kfree(smp_resp); 1919 ret = smp_execute_task(dev, bio_data(req->bio), req->data_len,
1911out: 1920 bio_data(rsp->bio), rsp->data_len);
1912 kfree(ex->smp_req); 1921
1913 ex->smp_req = NULL; 1922 return ret;
1914 ex->smp_req_size = 0;
1915 ex->smp_portal_pid = -1;
1916 up(&ex->smp_sema);
1917 return res;
1918} 1923}
1919#endif
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index 1396c83b0c9c..9cd5abe9e714 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -259,6 +259,7 @@ static struct sas_function_template sft = {
259 .phy_reset = sas_phy_reset, 259 .phy_reset = sas_phy_reset,
260 .set_phy_speed = sas_set_phy_speed, 260 .set_phy_speed = sas_set_phy_speed,
261 .get_linkerrors = sas_get_linkerrors, 261 .get_linkerrors = sas_get_linkerrors,
262 .smp_handler = sas_smp_handler,
262}; 263};
263 264
264struct scsi_transport_template * 265struct scsi_transport_template *
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index a78638df2018..2b8213b1832d 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -39,6 +39,9 @@
39#define SAS_DPRINTK(fmt, ...) 39#define SAS_DPRINTK(fmt, ...)
40#endif 40#endif
41 41
42#define TO_SAS_TASK(_scsi_cmd) ((void *)(_scsi_cmd)->host_scribble)
43#define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0)
44
42void sas_scsi_recover_host(struct Scsi_Host *shost); 45void sas_scsi_recover_host(struct Scsi_Host *shost);
43 46
44int sas_show_class(enum sas_class class, char *buf); 47int sas_show_class(enum sas_class class, char *buf);
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 9c5342e7a69c..7663841eb4cf 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -34,6 +34,7 @@
34#include <scsi/scsi_eh.h> 34#include <scsi/scsi_eh.h>
35#include <scsi/scsi_transport.h> 35#include <scsi/scsi_transport.h>
36#include <scsi/scsi_transport_sas.h> 36#include <scsi/scsi_transport_sas.h>
37#include <scsi/sas_ata.h>
37#include "../scsi_sas_internal.h" 38#include "../scsi_sas_internal.h"
38#include "../scsi_transport_api.h" 39#include "../scsi_transport_api.h"
39#include "../scsi_priv.h" 40#include "../scsi_priv.h"
@@ -42,12 +43,10 @@
42#include <linux/blkdev.h> 43#include <linux/blkdev.h>
43#include <linux/freezer.h> 44#include <linux/freezer.h>
44#include <linux/scatterlist.h> 45#include <linux/scatterlist.h>
46#include <linux/libata.h>
45 47
46/* ---------- SCSI Host glue ---------- */ 48/* ---------- SCSI Host glue ---------- */
47 49
48#define TO_SAS_TASK(_scsi_cmd) ((void *)(_scsi_cmd)->host_scribble)
49#define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0)
50
51static void sas_scsi_task_done(struct sas_task *task) 50static void sas_scsi_task_done(struct sas_task *task)
52{ 51{
53 struct task_status_struct *ts = &task->task_status; 52 struct task_status_struct *ts = &task->task_status;
@@ -172,7 +171,7 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
172 return task; 171 return task;
173} 172}
174 173
175static int sas_queue_up(struct sas_task *task) 174int sas_queue_up(struct sas_task *task)
176{ 175{
177 struct sas_ha_struct *sas_ha = task->dev->port->ha; 176 struct sas_ha_struct *sas_ha = task->dev->port->ha;
178 struct scsi_core *core = &sas_ha->core; 177 struct scsi_core *core = &sas_ha->core;
@@ -213,6 +212,16 @@ int sas_queuecommand(struct scsi_cmnd *cmd,
213 struct sas_ha_struct *sas_ha = dev->port->ha; 212 struct sas_ha_struct *sas_ha = dev->port->ha;
214 struct sas_task *task; 213 struct sas_task *task;
215 214
215 if (dev_is_sata(dev)) {
216 unsigned long flags;
217
218 spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
219 res = ata_sas_queuecmd(cmd, scsi_done,
220 dev->sata_dev.ap);
221 spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
222 goto out;
223 }
224
216 res = -ENOMEM; 225 res = -ENOMEM;
217 task = sas_create_task(cmd, dev, GFP_ATOMIC); 226 task = sas_create_task(cmd, dev, GFP_ATOMIC);
218 if (!task) 227 if (!task)
@@ -684,6 +693,16 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
684 return EH_NOT_HANDLED; 693 return EH_NOT_HANDLED;
685} 694}
686 695
696int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
697{
698 struct domain_device *dev = sdev_to_domain_dev(sdev);
699
700 if (dev_is_sata(dev))
701 return ata_scsi_ioctl(sdev, cmd, arg);
702
703 return -EINVAL;
704}
705
687struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy) 706struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
688{ 707{
689 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent); 708 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent);
@@ -723,10 +742,17 @@ static inline struct domain_device *sas_find_target(struct scsi_target *starget)
723int sas_target_alloc(struct scsi_target *starget) 742int sas_target_alloc(struct scsi_target *starget)
724{ 743{
725 struct domain_device *found_dev = sas_find_target(starget); 744 struct domain_device *found_dev = sas_find_target(starget);
745 int res;
726 746
727 if (!found_dev) 747 if (!found_dev)
728 return -ENODEV; 748 return -ENODEV;
729 749
750 if (dev_is_sata(found_dev)) {
751 res = sas_ata_init_host_and_port(found_dev, starget);
752 if (res)
753 return res;
754 }
755
730 starget->hostdata = found_dev; 756 starget->hostdata = found_dev;
731 return 0; 757 return 0;
732} 758}
@@ -741,6 +767,11 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
741 767
742 BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE); 768 BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE);
743 769
770 if (dev_is_sata(dev)) {
771 ata_sas_slave_configure(scsi_dev, dev->sata_dev.ap);
772 return 0;
773 }
774
744 sas_ha = dev->port->ha; 775 sas_ha = dev->port->ha;
745 776
746 sas_read_port_mode_page(scsi_dev); 777 sas_read_port_mode_page(scsi_dev);
@@ -764,6 +795,10 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
764 795
765void sas_slave_destroy(struct scsi_device *scsi_dev) 796void sas_slave_destroy(struct scsi_device *scsi_dev)
766{ 797{
798 struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
799
800 if (dev_is_sata(dev))
801 ata_port_disable(dev->sata_dev.ap);
767} 802}
768 803
769int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth) 804int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
@@ -980,10 +1015,38 @@ void sas_task_abort(struct sas_task *task)
980 return; 1015 return;
981 } 1016 }
982 1017
1018 if (dev_is_sata(task->dev)) {
1019 sas_ata_task_abort(task);
1020 return;
1021 }
1022
983 scsi_req_abort_cmd(sc); 1023 scsi_req_abort_cmd(sc);
984 scsi_schedule_eh(sc->device->host); 1024 scsi_schedule_eh(sc->device->host);
985} 1025}
986 1026
1027int sas_slave_alloc(struct scsi_device *scsi_dev)
1028{
1029 struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
1030
1031 if (dev_is_sata(dev))
1032 return ata_sas_port_init(dev->sata_dev.ap);
1033
1034 return 0;
1035}
1036
1037void sas_target_destroy(struct scsi_target *starget)
1038{
1039 struct domain_device *found_dev = sas_find_target(starget);
1040
1041 if (!found_dev)
1042 return;
1043
1044 if (dev_is_sata(found_dev))
1045 ata_sas_port_destroy(found_dev->sata_dev.ap);
1046
1047 return;
1048}
1049
987EXPORT_SYMBOL_GPL(sas_queuecommand); 1050EXPORT_SYMBOL_GPL(sas_queuecommand);
988EXPORT_SYMBOL_GPL(sas_target_alloc); 1051EXPORT_SYMBOL_GPL(sas_target_alloc);
989EXPORT_SYMBOL_GPL(sas_slave_configure); 1052EXPORT_SYMBOL_GPL(sas_slave_configure);
@@ -997,3 +1060,6 @@ EXPORT_SYMBOL_GPL(sas_phy_reset);
997EXPORT_SYMBOL_GPL(sas_phy_enable); 1060EXPORT_SYMBOL_GPL(sas_phy_enable);
998EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler); 1061EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler);
999EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler); 1062EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler);
1063EXPORT_SYMBOL_GPL(sas_slave_alloc);
1064EXPORT_SYMBOL_GPL(sas_target_destroy);
1065EXPORT_SYMBOL_GPL(sas_ioctl);