AHCI/SILI - Send dummy SETXFER mode even though it is SATA
[dragonfly.git] / sys / dev / disk / sili / sili_cam.c
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *
35  * Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
36  *
37  * Permission to use, copy, modify, and distribute this software for any
38  * purpose with or without fee is hereby granted, provided that the above
39  * copyright notice and this permission notice appear in all copies.
40  *
41  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
42  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
43  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
44  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
45  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
46  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
47  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
48  *
49  * $OpenBSD: atascsi.c,v 1.64 2009/02/16 21:19:06 miod Exp $
50  * $DragonFly$
51  */
52 /*
53  * Implement each SATA port as its own SCSI bus on CAM.  This way we can
54  * implement future port multiplier features as individual devices on the
55  * bus.
56  *
57  * Much of the cdb<->xa conversion code was taken from OpenBSD, the rest
58  * was written natively for DragonFly.
59  */
60
61 #include "sili.h"
62
63 static void sili_xpt_action(struct cam_sim *sim, union ccb *ccb);
64 static void sili_xpt_poll(struct cam_sim *sim);
65 static void sili_xpt_scsi_disk_io(struct sili_port *ap,
66                         struct ata_port *at, union ccb *ccb);
67 static void sili_xpt_scsi_atapi_io(struct sili_port *ap,
68                         struct ata_port *at, union ccb *ccb);
69 static void sili_xpt_page_inquiry(struct sili_port *ap,
70                         struct ata_port *at, union ccb *ccb);
71
72 static void sili_ata_complete_disk_rw(struct ata_xfer *xa);
73 static void sili_ata_complete_disk_synchronize_cache(struct ata_xfer *xa);
74 static void sili_atapi_complete_cmd(struct ata_xfer *xa);
75 static void sili_ata_dummy_sense(struct scsi_sense_data *sense_data);
76 static void sili_ata_atapi_sense(struct ata_fis_d2h *rfis,
77                      struct scsi_sense_data *sense_data);
78
79 static int sili_cam_probe_disk(struct sili_port *ap, struct ata_port *at);
80 static int sili_cam_probe_atapi(struct sili_port *ap, struct ata_port *at);
81 static void sili_ata_dummy_done(struct ata_xfer *xa);
82 static void ata_fix_identify(struct ata_identify *id);
83 static int sili_set_xfer(struct sili_port *ap, struct ata_port *atx);
84 static void sili_cam_rescan(struct sili_port *ap);
85 static void sili_strip_string(const char **basep, int *lenp);
86
87 int
88 sili_cam_attach(struct sili_port *ap)
89 {
90         struct cam_devq *devq;
91         struct cam_sim *sim;
92         int error;
93         int unit;
94
95         /*
96          * We want at least one ccb to be available for error processing
97          * so don't let CAM use more then ncmds - 1.
98          */
99         unit = device_get_unit(ap->ap_sc->sc_dev);
100         if (ap->ap_sc->sc_ncmds > 1)
101                 devq = cam_simq_alloc(ap->ap_sc->sc_ncmds - 1);
102         else
103                 devq = cam_simq_alloc(ap->ap_sc->sc_ncmds);
104         if (devq == NULL) {
105                 return (ENOMEM);
106         }
107         sim = cam_sim_alloc(sili_xpt_action, sili_xpt_poll, "sili",
108                            (void *)ap, unit, &sim_mplock, 1, 1, devq);
109         cam_simq_release(devq);
110         if (sim == NULL) {
111                 return (ENOMEM);
112         }
113         ap->ap_sim = sim;
114         sili_os_unlock_port(ap);
115         error = xpt_bus_register(ap->ap_sim, ap->ap_num);
116         sili_os_lock_port(ap);
117         if (error != CAM_SUCCESS) {
118                 sili_cam_detach(ap);
119                 return (EINVAL);
120         }
121         ap->ap_flags |= AP_F_BUS_REGISTERED;
122
123         if (ap->ap_probe == ATA_PROBE_NEED_IDENT)
124                 error = sili_cam_probe(ap, NULL);
125         else
126                 error = 0;
127         if (error) {
128                 sili_cam_detach(ap);
129                 return (EIO);
130         }
131         ap->ap_flags |= AP_F_CAM_ATTACHED;
132
133         return(0);
134 }
135
136 /*
137  * The state of the port has changed.
138  *
139  * If at is NULL the physical port has changed state.
140  * If at is non-NULL a particular target behind a PM has changed state.
141  *
142  * If found is -1 the target state must be queued to a non-interrupt context.
143  * (only works with at == NULL).
144  *
145  * If found is 0 the target was removed.
146  * If found is 1 the target was inserted.
147  */
148 void
149 sili_cam_changed(struct sili_port *ap, struct ata_port *atx, int found)
150 {
151         struct cam_path *tmppath;
152         int status;
153         int target;
154
155         target = atx ? atx->at_target : CAM_TARGET_WILDCARD;
156
157         if (ap->ap_sim == NULL)
158                 return;
159         if (found == CAM_TARGET_WILDCARD) {
160                 status = xpt_create_path(&tmppath, NULL,
161                                          cam_sim_path(ap->ap_sim),
162                                          target, CAM_LUN_WILDCARD);
163                 if (status != CAM_REQ_CMP)
164                         return;
165                 sili_cam_rescan(ap);
166         } else {
167                 status = xpt_create_path(&tmppath, NULL,
168                                          cam_sim_path(ap->ap_sim),
169                                          target,
170                                          CAM_LUN_WILDCARD);
171                 if (status != CAM_REQ_CMP)
172                         return;
173 #if 0
174                 /*
175                  * This confuses CAM
176                  */
177                 if (found)
178                         xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
179                 else
180                         xpt_async(AC_LOST_DEVICE, tmppath, NULL);
181 #endif
182         }
183         xpt_free_path(tmppath);
184 }
185
186 void
187 sili_cam_detach(struct sili_port *ap)
188 {
189         int error;
190
191         if ((ap->ap_flags & AP_F_CAM_ATTACHED) == 0)
192                 return;
193         get_mplock();
194         if (ap->ap_sim) {
195                 xpt_freeze_simq(ap->ap_sim, 1);
196         }
197         if (ap->ap_flags & AP_F_BUS_REGISTERED) {
198                 error = xpt_bus_deregister(cam_sim_path(ap->ap_sim));
199                 KKASSERT(error == CAM_REQ_CMP);
200                 ap->ap_flags &= ~AP_F_BUS_REGISTERED;
201         }
202         if (ap->ap_sim) {
203                 cam_sim_free(ap->ap_sim);
204                 ap->ap_sim = NULL;
205         }
206         rel_mplock();
207         ap->ap_flags &= ~AP_F_CAM_ATTACHED;
208 }
209
210 /*
211  * Once the SILI port has been attached we need to probe for a device or
212  * devices on the port and setup various options.
213  *
214  * If at is NULL we are probing the direct-attached device on the port,
215  * which may or may not be a port multiplier.
216  */
217 int
218 sili_cam_probe(struct sili_port *ap, struct ata_port *atx)
219 {
220         struct ata_port *at;
221         struct ata_xfer *xa;
222         u_int64_t       capacity;
223         u_int64_t       capacity_bytes;
224         int             model_len;
225         int             firmware_len;
226         int             serial_len;
227         int             error;
228         int             devncqdepth;
229         int             i;
230         const char      *model_id;
231         const char      *firmware_id;
232         const char      *serial_id;
233         const char      *wcstr;
234         const char      *rastr;
235         const char      *scstr;
236         const char      *type;
237
238         error = EIO;
239
240         /*
241          * Delayed CAM attachment for initial probe, sim may be NULL
242          */
243         if (ap->ap_sim == NULL)
244                 return(0);
245
246         /*
247          * A NULL atx indicates a probe of the directly connected device.
248          * A non-NULL atx indicates a device connected via a port multiplier.
249          * We need to preserve atx for calls to sili_ata_get_xfer().
250          *
251          * at is always non-NULL.  For directly connected devices we supply
252          * an (at) pointing to target 0.
253          */
254         if (atx == NULL) {
255                 at = ap->ap_ata;        /* direct attached - device 0 */
256                 if (ap->ap_type == ATA_PORT_T_PM) {
257                         kprintf("%s: Found Port Multiplier\n",
258                                 ATANAME(ap, atx));
259                         return (0);
260                 }
261                 at->at_type = ap->ap_type;
262         } else {
263                 at = atx;
264                 if (atx->at_type == ATA_PORT_T_PM) {
265                         kprintf("%s: Bogus device, reducing port count to %d\n",
266                                 ATANAME(ap, atx), atx->at_target);
267                         if (ap->ap_pmcount > atx->at_target)
268                                 ap->ap_pmcount = atx->at_target;
269                         goto err;
270                 }
271         }
272         if (ap->ap_type == ATA_PORT_T_NONE)
273                 goto err;
274         if (at->at_type == ATA_PORT_T_NONE)
275                 goto err;
276
277         /*
278          * Issue identify, saving the result
279          */
280         xa = sili_ata_get_xfer(ap, atx);
281         xa->complete = sili_ata_dummy_done;
282         xa->data = &at->at_identify;
283         xa->datalen = sizeof(at->at_identify);
284         xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL;
285         xa->fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
286
287         switch(at->at_type) {
288         case ATA_PORT_T_DISK:
289                 xa->fis->command = ATA_C_IDENTIFY;
290                 type = "DISK";
291                 break;
292         case ATA_PORT_T_ATAPI:
293                 xa->fis->command = ATA_C_ATAPI_IDENTIFY;
294                 xa->flags |= ATA_F_AUTOSENSE;
295                 type = "ATAPI";
296                 break;
297         default:
298                 xa->fis->command = ATA_C_ATAPI_IDENTIFY;
299                 type = "UNKNOWN(ATAPI?)";
300                 break;
301         }
302         xa->fis->features = 0;
303         xa->fis->device = 0;
304         xa->timeout = 1000;
305
306         if (sili_ata_cmd(xa) != ATA_S_COMPLETE) {
307                 kprintf("%s: Detected %s device but unable to IDENTIFY\n",
308                         ATANAME(ap, atx), type);
309                 sili_ata_put_xfer(xa);
310                 goto err;
311         }
312         sili_ata_put_xfer(xa);
313
314         ata_fix_identify(&at->at_identify);
315
316         /*
317          * Read capacity using SATA probe info.
318          */
319         if (le16toh(at->at_identify.cmdset83) & 0x0400) {
320                 /* LBA48 feature set supported */
321                 capacity = 0;
322                 for (i = 3; i >= 0; --i) {
323                         capacity <<= 16;
324                         capacity +=
325                             le16toh(at->at_identify.addrsecxt[i]);
326                 }
327         } else {
328                 capacity = le16toh(at->at_identify.addrsec[1]);
329                 capacity <<= 16;
330                 capacity += le16toh(at->at_identify.addrsec[0]);
331         }
332         at->at_capacity = capacity;
333         if (atx == NULL)
334                 ap->ap_probe = ATA_PROBE_GOOD;
335
336         capacity_bytes = capacity * 512;
337
338         /*
339          * Negotiate NCQ, throw away any ata_xfer's beyond the negotiated
340          * number of slots and limit the number of CAM ccb's to one less
341          * so we always have a slot available for recovery.
342          *
343          * NCQ is not used if ap_ncqdepth is 1 or the host controller does
344          * not support it, and in that case the driver can handle extra
345          * ccb's.
346          *
347          * NCQ is currently used only with direct-attached disks.  It is
348          * not used with port multipliers or direct-attached ATAPI devices.
349          *
350          * Remember at least one extra CCB needs to be reserved for the
351          * error ccb.
352          */
353         if ((ap->ap_sc->sc_flags & SILI_F_NCQ) &&
354             at->at_type == ATA_PORT_T_DISK &&
355             (le16toh(at->at_identify.satacap) & (1 << 8))) {
356                 at->at_ncqdepth = (le16toh(at->at_identify.qdepth) & 0x1F) + 1;
357                 devncqdepth = at->at_ncqdepth;
358                 if (at->at_ncqdepth > ap->ap_sc->sc_ncmds)
359                         at->at_ncqdepth = ap->ap_sc->sc_ncmds;
360                 if (at->at_ncqdepth > 1) {
361                         for (i = 0; i < ap->ap_sc->sc_ncmds; ++i) {
362                                 xa = sili_ata_get_xfer(ap, atx);
363                                 if (xa->tag < at->at_ncqdepth) {
364                                         xa->state = ATA_S_COMPLETE;
365                                         sili_ata_put_xfer(xa);
366                                 }
367                         }
368                         if (at->at_ncqdepth >= ap->ap_sc->sc_ncmds) {
369                                 cam_devq_resize(ap->ap_sim->devq,
370                                                 at->at_ncqdepth - 1);
371                         }
372                 }
373         } else {
374                 devncqdepth = 0;
375         }
376
377         /*
378          * Make the model string a bit more presentable
379          */
380         for (model_len = 40; model_len; --model_len) {
381                 if (at->at_identify.model[model_len-1] == ' ')
382                         continue;
383                 if (at->at_identify.model[model_len-1] == 0)
384                         continue;
385                 break;
386         }
387
388         model_len = sizeof(at->at_identify.model);
389         model_id = at->at_identify.model;
390         sili_strip_string(&model_id, &model_len);
391
392         firmware_len = sizeof(at->at_identify.firmware);
393         firmware_id = at->at_identify.firmware;
394         sili_strip_string(&firmware_id, &firmware_len);
395
396         serial_len = sizeof(at->at_identify.serial);
397         serial_id = at->at_identify.serial;
398         sili_strip_string(&serial_id, &serial_len);
399
400         /*
401          * Generate informatiive strings.
402          *
403          * NOTE: We do not automatically set write caching, lookahead,
404          *       or the security state for ATAPI devices.
405          */
406         if (at->at_identify.cmdset82 & ATA_IDENTIFY_WRITECACHE) {
407                 if (at->at_identify.features85 & ATA_IDENTIFY_WRITECACHE)
408                         wcstr = "enabled";
409                 else if (at->at_type == ATA_PORT_T_ATAPI)
410                         wcstr = "disabled";
411                 else
412                         wcstr = "enabling";
413         } else {
414                     wcstr = "notsupp";
415         }
416
417         if (at->at_identify.cmdset82 & ATA_IDENTIFY_LOOKAHEAD) {
418                 if (at->at_identify.features85 & ATA_IDENTIFY_LOOKAHEAD)
419                         rastr = "enabled";
420                 else if (at->at_type == ATA_PORT_T_ATAPI)
421                         rastr = "disabled";
422                 else
423                         rastr = "enabling";
424         } else {
425                     rastr = "notsupp";
426         }
427
428         if (at->at_identify.cmdset82 & ATA_IDENTIFY_SECURITY) {
429                 if (at->at_identify.securestatus & ATA_SECURE_FROZEN)
430                         scstr = "frozen";
431                 else if (at->at_type == ATA_PORT_T_ATAPI)
432                         scstr = "unfrozen";
433                 else if (SiliNoFeatures & (1 << ap->ap_num))
434                         scstr = "<disabled>";
435                 else
436                         scstr = "freezing";
437         } else {
438                     scstr = "notsupp";
439         }
440
441         kprintf("%s: Found %s \"%*.*s %*.*s\" serial=\"%*.*s\"\n"
442                 "%s: tags=%d/%d satacap=%04x satafea=%04x NCQ=%s "
443                 "capacity=%lld.%02dMB\n",
444
445                 ATANAME(ap, atx),
446                 type,
447                 model_len, model_len, model_id,
448                 firmware_len, firmware_len, firmware_id,
449                 serial_len, serial_len, serial_id,
450
451                 ATANAME(ap, atx),
452                 devncqdepth, ap->ap_sc->sc_ncmds,
453                 at->at_identify.satacap,
454                 at->at_identify.satafsup,
455                 (at->at_ncqdepth > 1 ? "YES" : "NO"),
456                 (long long)capacity_bytes / (1024 * 1024),
457                 (int)(capacity_bytes % (1024 * 1024)) * 100 / (1024 * 1024)
458         );
459         kprintf("%s: f85=%04x f86=%04x f87=%04x WC=%s RA=%s SEC=%s\n",
460                 ATANAME(ap, atx),
461                 at->at_identify.features85,
462                 at->at_identify.features86,
463                 at->at_identify.features87,
464                 wcstr,
465                 rastr,
466                 scstr
467         );
468
469         /*
470          * Additional type-specific probing
471          */
472         switch(at->at_type) {
473         case ATA_PORT_T_DISK:
474                 error = sili_cam_probe_disk(ap, atx);
475                 break;
476         case ATA_PORT_T_ATAPI:
477                 error = sili_cam_probe_atapi(ap, atx);
478                 break;
479         default:
480                 error = EIO;
481                 break;
482         }
483 err:
484         if (error) {
485                 at->at_probe = ATA_PROBE_FAILED;
486                 if (atx == NULL)
487                         ap->ap_probe = at->at_probe;
488         } else {
489                 at->at_probe = ATA_PROBE_GOOD;
490                 if (atx == NULL)
491                         ap->ap_probe = at->at_probe;
492         }
493         return (error);
494 }
495
496 /*
497  * DISK-specific probe after initial ident
498  */
499 static int
500 sili_cam_probe_disk(struct sili_port *ap, struct ata_port *atx)
501 {
502         struct ata_port *at;
503         struct ata_xfer *xa;
504
505         at = atx ? atx : ap->ap_ata;
506
507         /*
508          * Set dummy xfer mode
509          */
510         sili_set_xfer(ap, atx);
511
512         /*
513          * Enable write cache if supported
514          *
515          * NOTE: "WD My Book" external disk devices have a very poor
516          *       daughter board between the the ESATA and the HD.  Sending
517          *       any ATA_C_SET_FEATURES commands will break the hardware port
518          *       with a fatal protocol error.  However, this device also
519          *       indicates that WRITECACHE is already on and READAHEAD is
520          *       not supported so we avoid the issue.
521          */
522         if ((at->at_identify.cmdset82 & ATA_IDENTIFY_WRITECACHE) &&
523             (at->at_identify.features85 & ATA_IDENTIFY_WRITECACHE) == 0) {
524                 xa = sili_ata_get_xfer(ap, atx);
525                 xa->complete = sili_ata_dummy_done;
526                 xa->fis->command = ATA_C_SET_FEATURES;
527                 /*xa->fis->features = ATA_SF_WRITECACHE_EN;*/
528                 xa->fis->features = ATA_SF_LOOKAHEAD_EN;
529                 xa->fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
530                 xa->fis->device = 0;
531                 xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL;
532                 xa->timeout = 1000;
533                 xa->datalen = 0;
534                 if (sili_ata_cmd(xa) == ATA_S_COMPLETE)
535                         at->at_features |= ATA_PORT_F_WCACHE;
536                 else
537                         kprintf("%s: Unable to enable write-caching\n",
538                                 ATANAME(ap, atx));
539                 sili_ata_put_xfer(xa);
540         }
541
542         /*
543          * Enable readahead if supported
544          */
545         if ((at->at_identify.cmdset82 & ATA_IDENTIFY_LOOKAHEAD) &&
546             (at->at_identify.features85 & ATA_IDENTIFY_LOOKAHEAD) == 0) {
547                 xa = sili_ata_get_xfer(ap, atx);
548                 xa->complete = sili_ata_dummy_done;
549                 xa->fis->command = ATA_C_SET_FEATURES;
550                 xa->fis->features = ATA_SF_LOOKAHEAD_EN;
551                 xa->fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
552                 xa->fis->device = 0;
553                 xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL;
554                 xa->timeout = 1000;
555                 xa->datalen = 0;
556                 if (sili_ata_cmd(xa) == ATA_S_COMPLETE)
557                         at->at_features |= ATA_PORT_F_RAHEAD;
558                 else
559                         kprintf("%s: Unable to enable read-ahead\n",
560                                 ATANAME(ap, atx));
561                 sili_ata_put_xfer(xa);
562         }
563
564         /*
565          * FREEZE LOCK the device so malicious users can't lock it on us.
566          * As there is no harm in issuing this to devices that don't
567          * support the security feature set we just send it, and don't bother
568          * checking if the device sends a command abort to tell us it doesn't
569          * support it
570          */
571         if ((at->at_identify.cmdset82 & ATA_IDENTIFY_SECURITY) &&
572             (at->at_identify.securestatus & ATA_SECURE_FROZEN) == 0 &&
573             (SiliNoFeatures & (1 << ap->ap_num)) == 0) {
574                 xa = sili_ata_get_xfer(ap, atx);
575                 xa->complete = sili_ata_dummy_done;
576                 xa->fis->command = ATA_C_SEC_FREEZE_LOCK;
577                 xa->fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
578                 xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL;
579                 xa->timeout = 1000;
580                 xa->datalen = 0;
581                 if (sili_ata_cmd(xa) == ATA_S_COMPLETE)
582                         at->at_features |= ATA_PORT_F_FRZLCK;
583                 else
584                         kprintf("%s: Unable to set security freeze\n",
585                                 ATANAME(ap, atx));
586                 sili_ata_put_xfer(xa);
587         }
588
589         return (0);
590 }
591
592 /*
593  * ATAPI-specific probe after initial ident
594  */
595 static int
596 sili_cam_probe_atapi(struct sili_port *ap, struct ata_port *atx)
597 {
598         sili_set_xfer(ap, atx);
599         return(0);
600 }
601
602 /*
603  * Setting the transfer mode is irrelevant for the SATA transport
604  * but some (atapi) devices seem to need it anyway.  In addition
605  * if we are running through a SATA->PATA converter for some reason
606  * beyond my comprehension we might have to set the mode.
607  */
608 static int
609 sili_set_xfer(struct sili_port *ap, struct ata_port *atx)
610 {
611         struct ata_port *at;
612         struct ata_xfer *xa;
613         u_int16_t mode;
614
615         at = atx ? atx : ap->ap_ata;
616
617         /*
618          * Get the supported mode.  SATA hard drives usually set this
619          * field to zero because it's irrelevant for SATA.  The general
620          * ATA spec allows unsupported fields to be 0 or bits all 1's.
621          *
622          * If the dmamode is not set the device understands that it is
623          * SATA and we don't have to send the obsolete SETXFER command.
624          */
625         mode = le16toh(at->at_identify.dmamode);
626         if (mode == 0 || mode == 0xFFFF)
627                 return(0);
628
629         /*
630          * SATA atapi devices often still report a dma mode, even though
631          * it is irrelevant for SATA transport.  It is also possible that
632          * we are running through a SATA->PATA converter and seeing the
633          * PATA dma mode.
634          *
635          * In this case the device may require a (dummy) SETXFER to be
636          * sent before it will work properly.
637          */
638         xa = sili_ata_get_xfer(ap, atx);
639         xa->complete = sili_ata_dummy_done;
640         xa->fis->command = ATA_C_SET_FEATURES;
641         xa->fis->features = ATA_SF_SETXFER;
642         xa->fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
643         xa->fis->device = 0;
644         xa->fis->sector_count = 0x40 | mode;
645         xa->fis->lba_low = 0;
646         xa->fis->lba_mid = 0;
647         xa->fis->lba_high = 0;
648         xa->flags = ATA_F_PIO | ATA_F_POLL;
649         xa->timeout = 1000;
650         xa->datalen = 0;
651         if (sili_ata_cmd(xa) != ATA_S_COMPLETE) {
652                 kprintf("%s: Unable to set dummy xfer mode \n",
653                         ATANAME(ap, atx));
654         } else if (bootverbose) {
655                 kprintf("%s: Set dummy xfer mode to %02x\n",
656                         ATANAME(ap, atx), 0x40 | mode);
657         }
658         sili_ata_put_xfer(xa);
659         return(0);
660 }
661
662 /*
663  * Fix byte ordering so buffers can be accessed as
664  * strings.
665  */
666 static void
667 ata_fix_identify(struct ata_identify *id)
668 {
669         u_int16_t       *swap;
670         int             i;
671
672         swap = (u_int16_t *)id->serial;
673         for (i = 0; i < sizeof(id->serial) / sizeof(u_int16_t); i++)
674                 swap[i] = bswap16(swap[i]);
675
676         swap = (u_int16_t *)id->firmware;
677         for (i = 0; i < sizeof(id->firmware) / sizeof(u_int16_t); i++)
678                 swap[i] = bswap16(swap[i]);
679
680         swap = (u_int16_t *)id->model;
681         for (i = 0; i < sizeof(id->model) / sizeof(u_int16_t); i++)
682                 swap[i] = bswap16(swap[i]);
683 }
684
685 /*
686  * Dummy done callback for xa.
687  */
688 static void
689 sili_ata_dummy_done(struct ata_xfer *xa)
690 {
691 }
692
693 /*
694  * Use an engineering request to initiate a target scan for devices
695  * behind a port multiplier.
696  *
697  * An asynchronous bus scan is used to avoid reentrancy issues.
698  */
699 static void
700 sili_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
701 {
702         struct sili_port *ap = ccb->ccb_h.sim_priv.entries[0].ptr;
703
704         if (ccb->ccb_h.func_code == XPT_SCAN_BUS) {
705                 ap->ap_flags &= ~AP_F_SCAN_RUNNING;
706                 if (ap->ap_flags & AP_F_SCAN_REQUESTED) {
707                         ap->ap_flags &= ~AP_F_SCAN_REQUESTED;
708                         sili_cam_rescan(ap);
709                 }
710                 ap->ap_flags |= AP_F_SCAN_COMPLETED;
711                 wakeup(&ap->ap_flags);
712         }
713         xpt_free_ccb(ccb);
714 }
715
716 static void
717 sili_cam_rescan(struct sili_port *ap)
718 {
719         struct cam_path *path;
720         union ccb *ccb;
721         int status;
722         int i;
723
724         if (ap->ap_flags & AP_F_SCAN_RUNNING) {
725                 ap->ap_flags |= AP_F_SCAN_REQUESTED;
726                 return;
727         }
728         ap->ap_flags |= AP_F_SCAN_RUNNING;
729         for (i = 0; i < SILI_MAX_PMPORTS; ++i) {
730                 ap->ap_ata[i].at_features |= ATA_PORT_F_RESCAN;
731         }
732
733         status = xpt_create_path(&path, xpt_periph, cam_sim_path(ap->ap_sim),
734                                  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
735         if (status != CAM_REQ_CMP)
736                 return;
737
738         ccb = xpt_alloc_ccb();
739         xpt_setup_ccb(&ccb->ccb_h, path, 5);    /* 5 = low priority */
740         ccb->ccb_h.func_code = XPT_ENG_EXEC;
741         ccb->ccb_h.cbfcnp = sili_cam_rescan_callback;
742         ccb->ccb_h.sim_priv.entries[0].ptr = ap;
743         ccb->crcn.flags = CAM_FLAG_NONE;
744         xpt_action_async(ccb);
745 }
746
747 static void
748 sili_xpt_rescan(struct sili_port *ap)
749 {
750         struct cam_path *path;
751         union ccb *ccb;
752         int status;
753
754         status = xpt_create_path(&path, xpt_periph, cam_sim_path(ap->ap_sim),
755                                  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
756         if (status != CAM_REQ_CMP)
757                 return;
758
759         ccb = xpt_alloc_ccb();
760         xpt_setup_ccb(&ccb->ccb_h, path, 5);    /* 5 = low priority */
761         ccb->ccb_h.func_code = XPT_SCAN_BUS;
762         ccb->ccb_h.cbfcnp = sili_cam_rescan_callback;
763         ccb->ccb_h.sim_priv.entries[0].ptr = ap;
764         ccb->crcn.flags = CAM_FLAG_NONE;
765         xpt_action_async(ccb);
766 }
767
768 /*
769  * Action function - dispatch command
770  */
771 static
772 void
773 sili_xpt_action(struct cam_sim *sim, union ccb *ccb)
774 {
775         struct sili_port *ap;
776         struct ata_port  *at, *atx;
777         struct ccb_hdr *ccbh;
778         int unit;
779
780         /* XXX lock */
781         ap = cam_sim_softc(sim);
782         at = ap->ap_ata;
783         atx = NULL;
784         KKASSERT(ap != NULL);
785         ccbh = &ccb->ccb_h;
786         unit = cam_sim_unit(sim);
787
788         /*
789          * Early failure checks.  These checks do not apply to XPT_PATH_INQ,
790          * otherwise the bus rescan will not remove the dead devices when
791          * unplugging a PM.
792          *
793          * For non-wildcards we have one target (0) and one lun (0),
794          * unless we have a port multiplier.
795          *
796          * A wildcard target indicates only the general bus is being
797          * probed.
798          *
799          * Calculate at and atx.  at is always non-NULL.  atx is only
800          * non-NULL for direct-attached devices.  It will be NULL for
801          * devices behind a port multiplier.
802          *
803          * XXX What do we do with a LUN wildcard?
804          */
805         if (ccbh->target_id != CAM_TARGET_WILDCARD &&
806             ccbh->func_code != XPT_PATH_INQ) {
807                 if (ap->ap_type == ATA_PORT_T_NONE) {
808                         ccbh->status = CAM_DEV_NOT_THERE;
809                         xpt_done(ccb);
810                         return;
811                 }
812                 if (ccbh->target_id < 0 || ccbh->target_id >= ap->ap_pmcount) {
813                         ccbh->status = CAM_DEV_NOT_THERE;
814                         xpt_done(ccb);
815                         return;
816                 }
817                 at += ccbh->target_id;
818                 if (ap->ap_type == ATA_PORT_T_PM)
819                         atx = at;
820
821                 if (ccbh->target_lun != CAM_LUN_WILDCARD && ccbh->target_lun) {
822                         ccbh->status = CAM_DEV_NOT_THERE;
823                         xpt_done(ccb);
824                         return;
825                 }
826         }
827
828         /*
829          * Switch on the meta XPT command
830          */
831         switch(ccbh->func_code) {
832         case XPT_ENG_EXEC:
833                 /*
834                  * This routine is called after a port multiplier has been
835                  * probed.
836                  */
837                 ccbh->status = CAM_REQ_CMP;
838                 sili_os_lock_port(ap);
839                 sili_port_state_machine(ap, 0);
840                 sili_os_unlock_port(ap);
841                 xpt_done(ccb);
842                 sili_xpt_rescan(ap);
843                 break;
844         case XPT_PATH_INQ:
845                 /*
846                  * This command always succeeds, otherwise the bus scan
847                  * will not detach dead devices.
848                  */
849                 ccb->cpi.version_num = 1;
850                 ccb->cpi.hba_inquiry = 0;
851                 ccb->cpi.target_sprt = 0;
852                 ccb->cpi.hba_misc = PIM_SEQSCAN;
853                 ccb->cpi.hba_eng_cnt = 0;
854                 bzero(ccb->cpi.vuhba_flags, sizeof(ccb->cpi.vuhba_flags));
855                 ccb->cpi.max_target = SILI_MAX_PMPORTS - 1;
856                 ccb->cpi.max_lun = 0;
857                 ccb->cpi.async_flags = 0;
858                 ccb->cpi.hpath_id = 0;
859                 ccb->cpi.initiator_id = SILI_MAX_PMPORTS - 1;
860                 ccb->cpi.unit_number = cam_sim_unit(sim);
861                 ccb->cpi.bus_id = cam_sim_bus(sim);
862                 ccb->cpi.base_transfer_speed = 150000;
863                 ccb->cpi.transport = XPORT_SATA;
864                 ccb->cpi.transport_version = 1;
865                 ccb->cpi.protocol = PROTO_SCSI;
866                 ccb->cpi.protocol_version = SCSI_REV_2;
867
868                 ccbh->status = CAM_REQ_CMP;
869                 if (ccbh->target_id == CAM_TARGET_WILDCARD) {
870                         sili_os_lock_port(ap);
871                         sili_port_state_machine(ap, 0);
872                         sili_os_unlock_port(ap);
873                 } else {
874                         switch(sili_pread(ap, SILI_PREG_SSTS) &
875                                SILI_PREG_SSTS_SPD) {
876                         case SILI_PREG_SSTS_SPD_GEN1:
877                                 ccb->cpi.base_transfer_speed = 150000;
878                                 break;
879                         case SILI_PREG_SSTS_SPD_GEN2:
880                                 ccb->cpi.base_transfer_speed = 300000;
881                                 break;
882                         default:
883                                 /* unknown */
884                                 ccb->cpi.base_transfer_speed = 1000;
885                                 break;
886                         }
887 #if 0
888                         if (ap->ap_type == ATA_PORT_T_NONE)
889                                 ccbh->status = CAM_DEV_NOT_THERE;
890 #endif
891                 }
892                 xpt_done(ccb);
893                 break;
894         case XPT_RESET_DEV:
895                 sili_os_lock_port(ap);
896                 if (ap->ap_type == ATA_PORT_T_NONE) {
897                         ccbh->status = CAM_DEV_NOT_THERE;
898                 } else {
899                         sili_port_reset(ap, atx, 0);
900                         ccbh->status = CAM_REQ_CMP;
901                 }
902                 sili_os_unlock_port(ap);
903                 xpt_done(ccb);
904                 break;
905         case XPT_RESET_BUS:
906                 sili_os_lock_port(ap);
907                 sili_port_reset(ap, NULL, 1);
908                 sili_os_unlock_port(ap);
909                 ccbh->status = CAM_REQ_CMP;
910                 xpt_done(ccb);
911                 break;
912         case XPT_SET_TRAN_SETTINGS:
913                 ccbh->status = CAM_FUNC_NOTAVAIL;
914                 xpt_done(ccb);
915                 break;
916         case XPT_GET_TRAN_SETTINGS:
917                 ccb->cts.protocol = PROTO_SCSI;
918                 ccb->cts.protocol_version = SCSI_REV_2;
919                 ccb->cts.transport = XPORT_SATA;
920                 ccb->cts.transport_version = XPORT_VERSION_UNSPECIFIED;
921                 ccb->cts.proto_specific.valid = 0;
922                 ccb->cts.xport_specific.valid = 0;
923                 ccbh->status = CAM_REQ_CMP;
924                 xpt_done(ccb);
925                 break;
926         case XPT_CALC_GEOMETRY:
927                 cam_calc_geometry(&ccb->ccg, 1);
928                 xpt_done(ccb);
929                 break;
930         case XPT_SCSI_IO:
931                 /*
932                  * Our parallel startup code might have only probed through
933                  * to the IDENT, so do the last step if necessary.
934                  */
935                 if (at->at_probe == ATA_PROBE_NEED_IDENT)
936                         sili_cam_probe(ap, atx);
937                 if (at->at_probe != ATA_PROBE_GOOD) {
938                         ccbh->status = CAM_DEV_NOT_THERE;
939                         xpt_done(ccb);
940                         break;
941                 }
942                 switch(at->at_type) {
943                 case ATA_PORT_T_DISK:
944                         sili_xpt_scsi_disk_io(ap, atx, ccb);
945                         break;
946                 case ATA_PORT_T_ATAPI:
947                         sili_xpt_scsi_atapi_io(ap, atx, ccb);
948                         break;
949                 default:
950                         ccbh->status = CAM_REQ_INVALID;
951                         xpt_done(ccb);
952                         break;
953                 }
954                 break;
955         default:
956                 ccbh->status = CAM_REQ_INVALID;
957                 xpt_done(ccb);
958                 break;
959         }
960 }
961
962 /*
963  * Poll function.
964  *
965  * Generally this function gets called heavily when interrupts might be
966  * non-operational, during a halt/reboot or panic.
967  */
968 static
969 void
970 sili_xpt_poll(struct cam_sim *sim)
971 {
972         struct sili_port *ap;
973
974         ap = cam_sim_softc(sim);
975         crit_enter();
976         sili_os_lock_port(ap);
977         sili_port_intr(ap, 1);
978         sili_os_unlock_port(ap);
979         crit_exit();
980 }
981
982 /*
983  * Convert the SCSI command in ccb to an ata_xfer command in xa
984  * for ATA_PORT_T_DISK operations.  Set the completion function
985  * to convert the response back, then dispatch to the OpenBSD SILI
986  * layer.
987  *
988  * SILI DISK commands only support a limited command set, and we
989  * fake additional commands to make it play nice with the CAM subsystem.
990  */
991 static
992 void
993 sili_xpt_scsi_disk_io(struct sili_port *ap, struct ata_port *atx,
994                       union ccb *ccb)
995 {
996         struct ccb_hdr *ccbh;
997         struct ccb_scsiio *csio;
998         struct ata_xfer *xa;
999         struct ata_port *at;
1000         struct ata_fis_h2d *fis;
1001         struct ata_pass_12 *atp12;
1002         struct ata_pass_16 *atp16;
1003         scsi_cdb_t cdb;
1004         union scsi_data *rdata;
1005         int rdata_len;
1006         u_int64_t capacity;
1007         u_int64_t lba;
1008         u_int32_t count;
1009
1010         ccbh = &ccb->csio.ccb_h;
1011         csio = &ccb->csio;
1012         at = atx ? atx : &ap->ap_ata[0];
1013
1014         /*
1015          * XXX not passing NULL at for direct attach!
1016          */
1017         xa = sili_ata_get_xfer(ap, atx);
1018         rdata = (void *)csio->data_ptr;
1019         rdata_len = csio->dxfer_len;
1020
1021         /*
1022          * Build the FIS or process the csio to completion.
1023          */
1024         cdb = (void *)((ccbh->flags & CAM_CDB_POINTER) ?
1025                         csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
1026
1027         switch(cdb->generic.opcode) {
1028         case REQUEST_SENSE:
1029                 /*
1030                  * Auto-sense everything, so explicit sense requests
1031                  * return no-sense.
1032                  */
1033                 ccbh->status = CAM_SCSI_STATUS_ERROR;
1034                 break;
1035         case INQUIRY:
1036                 /*
1037                  * Inquiry supported features
1038                  *
1039                  * [opcode, byte2, page_code, length, control]
1040                  */
1041                 if (cdb->inquiry.byte2 & SI_EVPD) {
1042                         sili_xpt_page_inquiry(ap, at, ccb);
1043                 } else {
1044                         bzero(rdata, rdata_len);
1045                         if (rdata_len < SHORT_INQUIRY_LENGTH) {
1046                                 ccbh->status = CAM_CCB_LEN_ERR;
1047                                 break;
1048                         }
1049                         if (rdata_len > sizeof(rdata->inquiry_data))
1050                                 rdata_len = sizeof(rdata->inquiry_data);
1051                         rdata->inquiry_data.device = T_DIRECT;
1052                         rdata->inquiry_data.version = SCSI_REV_SPC2;
1053                         rdata->inquiry_data.response_format = 2;
1054                         rdata->inquiry_data.additional_length = 32;
1055                         bcopy("SATA    ", rdata->inquiry_data.vendor, 8);
1056                         bcopy(at->at_identify.model,
1057                               rdata->inquiry_data.product,
1058                               sizeof(rdata->inquiry_data.product));
1059                         bcopy(at->at_identify.firmware,
1060                               rdata->inquiry_data.revision,
1061                               sizeof(rdata->inquiry_data.revision));
1062                         ccbh->status = CAM_REQ_CMP;
1063                 }
1064                 break;
1065         case READ_CAPACITY_16:
1066                 if (cdb->read_capacity_16.service_action != SRC16_SERVICE_ACTION) {
1067                         ccbh->status = CAM_REQ_INVALID;
1068                         break;
1069                 }
1070                 if (rdata_len < sizeof(rdata->read_capacity_data_16)) {
1071                         ccbh->status = CAM_CCB_LEN_ERR;
1072                         break;
1073                 }
1074                 /* fall through */
1075         case READ_CAPACITY:
1076                 if (rdata_len < sizeof(rdata->read_capacity_data)) {
1077                         ccbh->status = CAM_CCB_LEN_ERR;
1078                         break;
1079                 }
1080
1081                 capacity = at->at_capacity;
1082
1083                 bzero(rdata, rdata_len);
1084                 if (cdb->generic.opcode == READ_CAPACITY) {
1085                         rdata_len = sizeof(rdata->read_capacity_data);
1086                         if (capacity > 0xFFFFFFFFU)
1087                                 capacity = 0xFFFFFFFFU;
1088                         bzero(&rdata->read_capacity_data, rdata_len);
1089                         scsi_ulto4b((u_int32_t)capacity - 1,
1090                                     rdata->read_capacity_data.addr);
1091                         scsi_ulto4b(512, rdata->read_capacity_data.length);
1092                 } else {
1093                         rdata_len = sizeof(rdata->read_capacity_data_16);
1094                         bzero(&rdata->read_capacity_data_16, rdata_len);
1095                         scsi_u64to8b(capacity - 1,
1096                                      rdata->read_capacity_data_16.addr);
1097                         scsi_ulto4b(512, rdata->read_capacity_data_16.length);
1098                 }
1099                 ccbh->status = CAM_REQ_CMP;
1100                 break;
1101         case SYNCHRONIZE_CACHE:
1102                 /*
1103                  * Synchronize cache.  Specification says this can take
1104                  * greater then 30 seconds so give it at least 45.
1105                  */
1106                 fis = xa->fis;
1107                 fis->flags = ATA_H2D_FLAGS_CMD;
1108                 fis->command = ATA_C_FLUSH_CACHE;
1109                 fis->device = 0;
1110                 if (xa->timeout < 45000)
1111                         xa->timeout = 45000;
1112                 xa->datalen = 0;
1113                 xa->flags = ATA_F_READ;
1114                 xa->complete = sili_ata_complete_disk_synchronize_cache;
1115                 break;
1116         case TEST_UNIT_READY:
1117         case START_STOP_UNIT:
1118         case PREVENT_ALLOW:
1119                 /*
1120                  * Just silently return success
1121                  */
1122                 ccbh->status = CAM_REQ_CMP;
1123                 rdata_len = 0;
1124                 break;
1125         case ATA_PASS_12:
1126                 atp12 = &cdb->ata_pass_12;
1127                 fis = xa->fis;
1128                 /*
1129                  * Figure out the flags to be used, depending on the
1130                  * direction of the CAM request.
1131                  */
1132                 switch (ccbh->flags & CAM_DIR_MASK) {
1133                 case CAM_DIR_IN:
1134                         xa->flags = ATA_F_READ;
1135                         break;
1136                 case CAM_DIR_OUT:
1137                         xa->flags = ATA_F_WRITE;
1138                         break;
1139                 default:
1140                         xa->flags = 0;
1141                 }
1142                 xa->flags |= ATA_F_POLL;
1143                 xa->data = csio->data_ptr;
1144                 xa->datalen = csio->dxfer_len;
1145                 xa->complete = sili_ata_complete_disk_rw;
1146                 xa->timeout = ccbh->timeout;
1147
1148                 /*
1149                  * Populate the fis from the information we received through CAM
1150                  * ATA passthrough.
1151                  */
1152                 fis->flags = ATA_H2D_FLAGS_CMD; /* maybe also atp12->flags ? */
1153                 fis->features = atp12->features;
1154                 fis->sector_count = atp12->sector_count;
1155                 fis->lba_low = atp12->lba_low;
1156                 fis->lba_mid = atp12->lba_mid;
1157                 fis->lba_high = atp12->lba_high;
1158                 fis->device = atp12->device;    /* maybe always 0? */
1159                 fis->command = atp12->command;
1160                 fis->control = atp12->control;
1161
1162                 /*
1163                  * Mark as in progress so it is sent to the device.
1164                  */
1165                 ccbh->status = CAM_REQ_INPROG;
1166                 break;
1167         case ATA_PASS_16:
1168                 atp16 = &cdb->ata_pass_16;
1169                 fis = xa->fis;
1170                 /*
1171                  * Figure out the flags to be used, depending on the direction of the
1172                  * CAM request.
1173                  */
1174                 switch (ccbh->flags & CAM_DIR_MASK) {
1175                 case CAM_DIR_IN:
1176                         xa->flags = ATA_F_READ;
1177                         break;
1178                 case CAM_DIR_OUT:
1179                         xa->flags = ATA_F_WRITE;
1180                         break;
1181                 default:
1182                         xa->flags = 0;
1183                 }
1184                 xa->flags |= ATA_F_POLL;
1185                 xa->data = csio->data_ptr;
1186                 xa->datalen = csio->dxfer_len;
1187                 xa->complete = sili_ata_complete_disk_rw;
1188                 xa->timeout = ccbh->timeout;
1189
1190                 /*
1191                  * Populate the fis from the information we received through CAM
1192                  * ATA passthrough.
1193                  */
1194                 fis->flags = ATA_H2D_FLAGS_CMD; /* maybe also atp16->flags ? */
1195                 fis->features = atp16->features;
1196                 fis->features_exp = atp16->features_ext;
1197                 fis->sector_count = atp16->sector_count;
1198                 fis->sector_count_exp = atp16->sector_count_ext;
1199                 fis->lba_low = atp16->lba_low;
1200                 fis->lba_low_exp = atp16->lba_low_ext;
1201                 fis->lba_mid = atp16->lba_mid;
1202                 fis->lba_mid_exp = atp16->lba_mid_ext;
1203                 fis->lba_high = atp16->lba_high;
1204                 fis->lba_mid_exp = atp16->lba_mid_ext;
1205                 fis->device = atp16->device;    /* maybe always 0? */
1206                 fis->command = atp16->command;
1207
1208                 /*
1209                  * Mark as in progress so it is sent to the device.
1210                  */
1211                 ccbh->status = CAM_REQ_INPROG;
1212                 break;
1213         default:
1214                 switch(cdb->generic.opcode) {
1215                 case READ_6:
1216                         lba = scsi_3btoul(cdb->rw_6.addr) & 0x1FFFFF;
1217                         count = cdb->rw_6.length ? cdb->rw_6.length : 0x100;
1218                         xa->flags = ATA_F_READ;
1219                         break;
1220                 case READ_10:
1221                         lba = scsi_4btoul(cdb->rw_10.addr);
1222                         count = scsi_2btoul(cdb->rw_10.length);
1223                         xa->flags = ATA_F_READ;
1224                         break;
1225                 case READ_12:
1226                         lba = scsi_4btoul(cdb->rw_12.addr);
1227                         count = scsi_4btoul(cdb->rw_12.length);
1228                         xa->flags = ATA_F_READ;
1229                         break;
1230                 case READ_16:
1231                         lba = scsi_8btou64(cdb->rw_16.addr);
1232                         count = scsi_4btoul(cdb->rw_16.length);
1233                         xa->flags = ATA_F_READ;
1234                         break;
1235                 case WRITE_6:
1236                         lba = scsi_3btoul(cdb->rw_6.addr) & 0x1FFFFF;
1237                         count = cdb->rw_6.length ? cdb->rw_6.length : 0x100;
1238                         xa->flags = ATA_F_WRITE;
1239                         break;
1240                 case WRITE_10:
1241                         lba = scsi_4btoul(cdb->rw_10.addr);
1242                         count = scsi_2btoul(cdb->rw_10.length);
1243                         xa->flags = ATA_F_WRITE;
1244                         break;
1245                 case WRITE_12:
1246                         lba = scsi_4btoul(cdb->rw_12.addr);
1247                         count = scsi_4btoul(cdb->rw_12.length);
1248                         xa->flags = ATA_F_WRITE;
1249                         break;
1250                 case WRITE_16:
1251                         lba = scsi_8btou64(cdb->rw_16.addr);
1252                         count = scsi_4btoul(cdb->rw_16.length);
1253                         xa->flags = ATA_F_WRITE;
1254                         break;
1255                 default:
1256                         ccbh->status = CAM_REQ_INVALID;
1257                         break;
1258                 }
1259                 if (ccbh->status != CAM_REQ_INPROG)
1260                         break;
1261
1262                 fis = xa->fis;
1263                 fis->flags = ATA_H2D_FLAGS_CMD;
1264                 fis->lba_low = (u_int8_t)lba;
1265                 fis->lba_mid = (u_int8_t)(lba >> 8);
1266                 fis->lba_high = (u_int8_t)(lba >> 16);
1267                 fis->device = ATA_H2D_DEVICE_LBA;
1268
1269                 /*
1270                  * NCQ only for direct-attached disks, do not currently
1271                  * try to use NCQ with port multipliers.
1272                  *
1273                  * XXX fixme SII chip can do NCQ w/ port multipliers.
1274                  */
1275                 if (at->at_ncqdepth > 1 &&
1276                     at->at_type == ATA_PORT_T_DISK &&
1277                     (ap->ap_sc->sc_flags & SILI_F_NCQ) &&
1278                     (ccbh->flags & CAM_POLLED) == 0) {
1279                         /*
1280                          * Use NCQ - always uses 48 bit addressing
1281                          */
1282                         xa->flags |= ATA_F_NCQ;
1283                         fis->command = (xa->flags & ATA_F_WRITE) ?
1284                                         ATA_C_WRITE_FPDMA : ATA_C_READ_FPDMA;
1285                         fis->lba_low_exp = (u_int8_t)(lba >> 24);
1286                         fis->lba_mid_exp = (u_int8_t)(lba >> 32);
1287                         fis->lba_high_exp = (u_int8_t)(lba >> 40);
1288                         fis->sector_count = xa->tag << 3;
1289                         fis->features = (u_int8_t)count;
1290                         fis->features_exp = (u_int8_t)(count >> 8);
1291                 } else if (count > 0x100 || lba > 0x0FFFFFFFU) {
1292                         /*
1293                          * Use LBA48
1294                          */
1295                         fis->command = (xa->flags & ATA_F_WRITE) ?
1296                                         ATA_C_WRITEDMA_EXT : ATA_C_READDMA_EXT;
1297                         fis->lba_low_exp = (u_int8_t)(lba >> 24);
1298                         fis->lba_mid_exp = (u_int8_t)(lba >> 32);
1299                         fis->lba_high_exp = (u_int8_t)(lba >> 40);
1300                         fis->sector_count = (u_int8_t)count;
1301                         fis->sector_count_exp = (u_int8_t)(count >> 8);
1302                 } else {
1303                         /*
1304                          * Use LBA
1305                          *
1306                          * NOTE: 256 sectors is supported, stored as 0.
1307                          */
1308                         fis->command = (xa->flags & ATA_F_WRITE) ?
1309                                         ATA_C_WRITEDMA : ATA_C_READDMA;
1310                         fis->device |= (u_int8_t)(lba >> 24) & 0x0F;
1311                         fis->sector_count = (u_int8_t)count;
1312                 }
1313
1314                 xa->data = csio->data_ptr;
1315                 xa->datalen = csio->dxfer_len;
1316                 xa->complete = sili_ata_complete_disk_rw;
1317                 xa->timeout = ccbh->timeout;    /* milliseconds */
1318                 if (ccbh->flags & CAM_POLLED)
1319                         xa->flags |= ATA_F_POLL;
1320                 break;
1321         }
1322
1323         /*
1324          * If the request is still in progress the xa and FIS have
1325          * been set up (except for the PM target), and must be dispatched.
1326          * Otherwise the request was completed.
1327          */
1328         if (ccbh->status == CAM_REQ_INPROG) {
1329                 KKASSERT(xa->complete != NULL);
1330                 xa->atascsi_private = ccb;
1331                 ccb->ccb_h.sim_priv.entries[0].ptr = ap;
1332                 sili_os_lock_port(ap);
1333                 xa->fis->flags |= at->at_target;
1334                 sili_ata_cmd(xa);
1335                 sili_os_unlock_port(ap);
1336         } else {
1337                 sili_ata_put_xfer(xa);
1338                 xpt_done(ccb);
1339         }
1340 }
1341
1342 /*
1343  * Convert the SCSI command in ccb to an ata_xfer command in xa
1344  * for ATA_PORT_T_ATAPI operations.  Set the completion function
1345  * to convert the response back, then dispatch to the OpenBSD SILI
1346  * layer.
1347  */
1348 static
1349 void
1350 sili_xpt_scsi_atapi_io(struct sili_port *ap, struct ata_port *atx,
1351                         union ccb *ccb)
1352 {
1353         struct ccb_hdr *ccbh;
1354         struct ccb_scsiio *csio;
1355         struct ata_xfer *xa;
1356         struct ata_fis_h2d *fis;
1357         scsi_cdb_t cdbs;
1358         scsi_cdb_t cdbd;
1359         int flags;
1360         struct ata_port *at;
1361
1362         ccbh = &ccb->csio.ccb_h;
1363         csio = &ccb->csio;
1364         at = atx ? atx : &ap->ap_ata[0];
1365
1366         switch (ccbh->flags & CAM_DIR_MASK) {
1367         case CAM_DIR_IN:
1368                 flags = ATA_F_PACKET | ATA_F_READ;
1369                 break;
1370         case CAM_DIR_OUT:
1371                 flags = ATA_F_PACKET | ATA_F_WRITE;
1372                 break;
1373         case CAM_DIR_NONE:
1374                 flags = ATA_F_PACKET;
1375                 break;
1376         default:
1377                 ccbh->status = CAM_REQ_INVALID;
1378                 xpt_done(ccb);
1379                 return;
1380                 /* NOT REACHED */
1381         }
1382
1383         /*
1384          * Special handling to get the rfis back into host memory while
1385          * still allowing the chip to run commands in parallel to
1386          * ATAPI devices behind a PM.
1387          */
1388         flags |= ATA_F_AUTOSENSE;
1389
1390         /*
1391          * The command has to fit in the packet command buffer.
1392          */
1393         if (csio->cdb_len < 6 || csio->cdb_len > 16) {
1394                 ccbh->status = CAM_CCB_LEN_ERR;
1395                 xpt_done(ccb);
1396                 return;
1397         }
1398
1399         /*
1400          * Initialize the XA and FIS.  It is unclear how much of
1401          * this has to mimic the equivalent ATA command.
1402          *
1403          * XXX not passing NULL at for direct attach!
1404          */
1405         xa = sili_ata_get_xfer(ap, atx);
1406         fis = xa->fis;
1407
1408         fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
1409         fis->command = ATA_C_PACKET;
1410         fis->device = ATA_H2D_DEVICE_LBA;
1411         fis->sector_count = xa->tag << 3;
1412         if (flags & (ATA_F_READ | ATA_F_WRITE)) {
1413                 if (flags & ATA_F_WRITE) {
1414                         fis->features = ATA_H2D_FEATURES_DMA |
1415                                         ATA_H2D_FEATURES_DIR_WRITE;
1416                 } else {
1417                         fis->features = ATA_H2D_FEATURES_DMA |
1418                                         ATA_H2D_FEATURES_DIR_READ;
1419                 }
1420         } else {
1421                 fis->lba_mid = 0;
1422                 fis->lba_high = 0;
1423         }
1424         fis->control = ATA_FIS_CONTROL_4BIT;
1425
1426         xa->flags = flags;
1427         xa->data = csio->data_ptr;
1428         xa->datalen = csio->dxfer_len;
1429         xa->timeout = ccbh->timeout;    /* milliseconds */
1430
1431         if (ccbh->flags & CAM_POLLED)
1432                 xa->flags |= ATA_F_POLL;
1433
1434         /*
1435          * Copy the cdb to the packetcmd buffer in the FIS using a
1436          * convenient pointer in the xa.
1437          */
1438         cdbs = (void *)((ccbh->flags & CAM_CDB_POINTER) ?
1439                         csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
1440         bcopy(cdbs, xa->packetcmd, csio->cdb_len);
1441
1442 #if 0
1443         kprintf("opcode %d cdb_len %d dxfer_len %d\n",
1444                 cdbs->generic.opcode,
1445                 csio->cdb_len, csio->dxfer_len);
1446 #endif
1447
1448         /*
1449          * Some ATAPI commands do not actually follow the SCSI standard.
1450          */
1451         cdbd = (void *)xa->packetcmd;
1452
1453         switch(cdbd->generic.opcode) {
1454         case REQUEST_SENSE:
1455                 /*
1456                  * Force SENSE requests to the ATAPI sense length.
1457                  *
1458                  * It is unclear if this is needed or not.
1459                  */
1460                 if (cdbd->sense.length == SSD_FULL_SIZE) {
1461                         kprintf("%s: Shortening sense request\n",
1462                                 PORTNAME(ap));
1463                         cdbd->sense.length = offsetof(struct scsi_sense_data,
1464                                                       extra_bytes[0]);
1465                 }
1466                 break;
1467         case INQUIRY:
1468                 /*
1469                  * Some ATAPI devices can't handle long inquiry lengths,
1470                  * don't ask me why.  Truncate the inquiry length.
1471                  */
1472                 if (cdbd->inquiry.page_code == 0 &&
1473                     cdbd->inquiry.length > SHORT_INQUIRY_LENGTH) {
1474                         cdbd->inquiry.length = SHORT_INQUIRY_LENGTH;
1475                 }
1476                 break;
1477         case READ_6:
1478         case WRITE_6:
1479                 /*
1480                  * Convert *_6 to *_10 commands.  Most ATAPI devices
1481                  * cannot handle the SCSI READ_6 and WRITE_6 commands.
1482                  */
1483                 cdbd->rw_10.opcode |= 0x20;
1484                 cdbd->rw_10.byte2 = 0;
1485                 cdbd->rw_10.addr[0] = cdbs->rw_6.addr[0] & 0x1F;
1486                 cdbd->rw_10.addr[1] = cdbs->rw_6.addr[1];
1487                 cdbd->rw_10.addr[2] = cdbs->rw_6.addr[2];
1488                 cdbd->rw_10.addr[3] = 0;
1489                 cdbd->rw_10.reserved = 0;
1490                 cdbd->rw_10.length[0] = 0;
1491                 cdbd->rw_10.length[1] = cdbs->rw_6.length;
1492                 cdbd->rw_10.control = cdbs->rw_6.control;
1493                 break;
1494         default:
1495                 break;
1496         }
1497
1498         /*
1499          * And dispatch
1500          */
1501         xa->complete = sili_atapi_complete_cmd;
1502         xa->atascsi_private = ccb;
1503         ccb->ccb_h.sim_priv.entries[0].ptr = ap;
1504         sili_os_lock_port(ap);
1505         sili_ata_cmd(xa);
1506         sili_os_unlock_port(ap);
1507 }
1508
1509 /*
1510  * Simulate page inquiries for disk attachments.
1511  */
1512 static
1513 void
1514 sili_xpt_page_inquiry(struct sili_port *ap, struct ata_port *at, union ccb *ccb)
1515 {
1516         union {
1517                 struct scsi_vpd_supported_page_list     list;
1518                 struct scsi_vpd_unit_serial_number      serno;
1519                 struct scsi_vpd_unit_devid              devid;
1520                 char                                    buf[256];
1521         } *page;
1522         scsi_cdb_t cdb;
1523         int i;
1524         int j;
1525         int len;
1526
1527         page = kmalloc(sizeof(*page), M_DEVBUF, M_WAITOK | M_ZERO);
1528
1529         cdb = (void *)((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
1530                         ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes);
1531
1532         switch(cdb->inquiry.page_code) {
1533         case SVPD_SUPPORTED_PAGE_LIST:
1534                 i = 0;
1535                 page->list.device = T_DIRECT;
1536                 page->list.page_code = SVPD_SUPPORTED_PAGE_LIST;
1537                 page->list.list[i++] = SVPD_SUPPORTED_PAGE_LIST;
1538                 page->list.list[i++] = SVPD_UNIT_SERIAL_NUMBER;
1539                 page->list.list[i++] = SVPD_UNIT_DEVID;
1540                 page->list.length = i;
1541                 len = offsetof(struct scsi_vpd_supported_page_list, list[3]);
1542                 break;
1543         case SVPD_UNIT_SERIAL_NUMBER:
1544                 i = 0;
1545                 j = sizeof(at->at_identify.serial);
1546                 for (i = 0; i < j && at->at_identify.serial[i] == ' '; ++i)
1547                         ;
1548                 while (j > i && at->at_identify.serial[j-1] == ' ')
1549                         --j;
1550                 page->serno.device = T_DIRECT;
1551                 page->serno.page_code = SVPD_UNIT_SERIAL_NUMBER;
1552                 page->serno.length = j - i;
1553                 bcopy(at->at_identify.serial + i,
1554                       page->serno.serial_num, j - i);
1555                 len = offsetof(struct scsi_vpd_unit_serial_number,
1556                                serial_num[j-i]);
1557                 break;
1558         case SVPD_UNIT_DEVID:
1559                 /* fall through for now */
1560         default:
1561                 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1562                 len = 0;
1563                 break;
1564         }
1565         if (ccb->ccb_h.status == CAM_REQ_INPROG) {
1566                 if (len <= ccb->csio.dxfer_len) {
1567                         ccb->ccb_h.status = CAM_REQ_CMP;
1568                         bzero(ccb->csio.data_ptr, ccb->csio.dxfer_len);
1569                         bcopy(page, ccb->csio.data_ptr, len);
1570                         ccb->csio.resid = ccb->csio.dxfer_len - len;
1571                 } else {
1572                         ccb->ccb_h.status = CAM_CCB_LEN_ERR;
1573                 }
1574         }
1575         kfree(page, M_DEVBUF);
1576 }
1577
1578 /*
1579  * Completion function for ATA_PORT_T_DISK cache synchronization.
1580  */
1581 static
1582 void
1583 sili_ata_complete_disk_synchronize_cache(struct ata_xfer *xa)
1584 {
1585         union ccb *ccb = xa->atascsi_private;
1586         struct ccb_hdr *ccbh = &ccb->ccb_h;
1587         struct sili_port *ap = ccb->ccb_h.sim_priv.entries[0].ptr;
1588
1589         switch(xa->state) {
1590         case ATA_S_COMPLETE:
1591                 ccbh->status = CAM_REQ_CMP;
1592                 ccb->csio.scsi_status = SCSI_STATUS_OK;
1593                 break;
1594         case ATA_S_ERROR:
1595                 kprintf("%s: synchronize_cache: error\n",
1596                         ATANAME(ap, xa->at));
1597                 ccbh->status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
1598                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1599                 sili_ata_dummy_sense(&ccb->csio.sense_data);
1600                 break;
1601         case ATA_S_TIMEOUT:
1602                 kprintf("%s: synchronize_cache: timeout\n",
1603                         ATANAME(ap, xa->at));
1604                 ccbh->status = CAM_CMD_TIMEOUT;
1605                 break;
1606         default:
1607                 kprintf("%s: synchronize_cache: unknown state %d\n",
1608                         ATANAME(ap, xa->at), xa->state);
1609                 ccbh->status = CAM_REQ_CMP_ERR;
1610                 break;
1611         }
1612         sili_ata_put_xfer(xa);
1613         sili_os_unlock_port(ap);
1614         xpt_done(ccb);
1615         sili_os_lock_port(ap);
1616 }
1617
1618 /*
1619  * Completion function for ATA_PORT_T_DISK I/O
1620  */
1621 static
1622 void
1623 sili_ata_complete_disk_rw(struct ata_xfer *xa)
1624 {
1625         union ccb *ccb = xa->atascsi_private;
1626         struct ccb_hdr *ccbh = &ccb->ccb_h;
1627         struct sili_port *ap = ccb->ccb_h.sim_priv.entries[0].ptr;
1628
1629         switch(xa->state) {
1630         case ATA_S_COMPLETE:
1631                 ccbh->status = CAM_REQ_CMP;
1632                 ccb->csio.scsi_status = SCSI_STATUS_OK;
1633                 break;
1634         case ATA_S_ERROR:
1635                 kprintf("%s: disk_rw: error\n", ATANAME(ap, xa->at));
1636                 ccbh->status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
1637                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1638                 sili_ata_dummy_sense(&ccb->csio.sense_data);
1639                 break;
1640         case ATA_S_TIMEOUT:
1641                 kprintf("%s: disk_rw: timeout\n", ATANAME(ap, xa->at));
1642                 ccbh->status = CAM_CMD_TIMEOUT;
1643                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1644                 sili_ata_dummy_sense(&ccb->csio.sense_data);
1645                 break;
1646         default:
1647                 kprintf("%s: disk_rw: unknown state %d\n",
1648                         ATANAME(ap, xa->at), xa->state);
1649                 ccbh->status = CAM_REQ_CMP_ERR;
1650                 break;
1651         }
1652         ccb->csio.resid = xa->resid;
1653         sili_ata_put_xfer(xa);
1654         sili_os_unlock_port(ap);
1655         xpt_done(ccb);
1656         sili_os_lock_port(ap);
1657 }
1658
1659 /*
1660  * Completion function for ATA_PORT_T_ATAPI I/O
1661  *
1662  * Sense data is returned in the rfis.
1663  */
1664 static
1665 void
1666 sili_atapi_complete_cmd(struct ata_xfer *xa)
1667 {
1668         union ccb *ccb = xa->atascsi_private;
1669         struct ccb_hdr *ccbh = &ccb->ccb_h;
1670         struct sili_port *ap = ccb->ccb_h.sim_priv.entries[0].ptr;
1671         scsi_cdb_t cdb;
1672
1673         cdb = (void *)((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
1674                         ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes);
1675
1676         switch(xa->state) {
1677         case ATA_S_COMPLETE:
1678                 ccbh->status = CAM_REQ_CMP;
1679                 ccb->csio.scsi_status = SCSI_STATUS_OK;
1680                 break;
1681         case ATA_S_ERROR:
1682                 ccbh->status = CAM_SCSI_STATUS_ERROR;
1683                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1684                 sili_ata_atapi_sense(xa->rfis, &ccb->csio.sense_data);
1685                 break;
1686         case ATA_S_TIMEOUT:
1687                 kprintf("%s: cmd %d: timeout\n",
1688                         PORTNAME(ap), cdb->generic.opcode);
1689                 ccbh->status = CAM_CMD_TIMEOUT;
1690                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1691                 sili_ata_dummy_sense(&ccb->csio.sense_data);
1692                 break;
1693         default:
1694                 kprintf("%s: cmd %d: unknown state %d\n",
1695                         PORTNAME(ap), cdb->generic.opcode, xa->state);
1696                 ccbh->status = CAM_REQ_CMP_ERR;
1697                 break;
1698         }
1699         ccb->csio.resid = xa->resid;
1700         sili_ata_put_xfer(xa);
1701         sili_os_unlock_port(ap);
1702         xpt_done(ccb);
1703         sili_os_lock_port(ap);
1704 }
1705
1706 /*
1707  * Construct dummy sense data for errors on DISKs
1708  */
1709 static
1710 void
1711 sili_ata_dummy_sense(struct scsi_sense_data *sense_data)
1712 {
1713         sense_data->error_code = SSD_ERRCODE_VALID | SSD_CURRENT_ERROR;
1714         sense_data->segment = 0;
1715         sense_data->flags = SSD_KEY_MEDIUM_ERROR;
1716         sense_data->info[0] = 0;
1717         sense_data->info[1] = 0;
1718         sense_data->info[2] = 0;
1719         sense_data->info[3] = 0;
1720         sense_data->extra_len = 0;
1721 }
1722
1723 /*
1724  * Construct atapi sense data for errors on ATAPI
1725  *
1726  * The ATAPI sense data is stored in the passed rfis and must be converted
1727  * to SCSI sense data.
1728  */
1729 static
1730 void
1731 sili_ata_atapi_sense(struct ata_fis_d2h *rfis,
1732                      struct scsi_sense_data *sense_data)
1733 {
1734         sense_data->error_code = SSD_ERRCODE_VALID | SSD_CURRENT_ERROR;
1735         sense_data->segment = 0;
1736         sense_data->flags = (rfis->error & 0xF0) >> 4;
1737         if (rfis->error & 0x04)
1738                 sense_data->flags |= SSD_KEY_ILLEGAL_REQUEST;
1739         if (rfis->error & 0x02)
1740                 sense_data->flags |= SSD_EOM;
1741         if (rfis->error & 0x01)
1742                 sense_data->flags |= SSD_ILI;
1743         sense_data->info[0] = 0;
1744         sense_data->info[1] = 0;
1745         sense_data->info[2] = 0;
1746         sense_data->info[3] = 0;
1747         sense_data->extra_len = 0;
1748 }
1749
1750 static
1751 void
1752 sili_strip_string(const char **basep, int *lenp)
1753 {
1754         const char *base = *basep;
1755         int len = *lenp;
1756
1757         while (len && (*base == 0 || *base == ' ')) {
1758                 --len;
1759                 ++base;
1760         }
1761         while (len && (base[len-1] == 0 || base[len-1] == ' '))
1762                 --len;
1763         *basep = base;
1764         *lenp = len;
1765 }