180e56254a6b2946b080115a7de169e4540717b5
[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 const char *ScsiTypeArray[32] = {
64         "DIRECT",
65         "SEQUENTIAL",
66         "PRINTER",
67         "PROCESSOR",
68         "WORM",
69         "CDROM",
70         "SCANNER",
71         "OPTICAL",
72         "CHANGER",
73         "COMM",
74         "ASC0",
75         "ASC1",
76         "STORARRAY",
77         "ENCLOSURE",
78         "RBC",
79         "OCRW",
80         "0x10",
81         "OSD",
82         "ADC",
83         "0x13",
84         "0x14",
85         "0x15",
86         "0x16",
87         "0x17",
88         "0x18",
89         "0x19",
90         "0x1A",
91         "0x1B",
92         "0x1C",
93         "0x1D",
94         "0x1E",
95         "NODEVICE"
96 };
97
98 static void sili_xpt_action(struct cam_sim *sim, union ccb *ccb);
99 static void sili_xpt_poll(struct cam_sim *sim);
100 static void sili_xpt_scsi_disk_io(struct sili_port *ap,
101                         struct ata_port *at, union ccb *ccb);
102 static void sili_xpt_scsi_atapi_io(struct sili_port *ap,
103                         struct ata_port *at, union ccb *ccb);
104
105 static void sili_ata_complete_disk_rw(struct ata_xfer *xa);
106 static void sili_ata_complete_disk_synchronize_cache(struct ata_xfer *xa);
107 static void sili_atapi_complete_cmd(struct ata_xfer *xa);
108 static void sili_ata_dummy_sense(struct scsi_sense_data *sense_data);
109 static void sili_ata_atapi_sense(struct ata_fis_d2h *rfis,
110                      struct scsi_sense_data *sense_data);
111
112 static int sili_cam_probe_disk(struct sili_port *ap, struct ata_port *at);
113 static int sili_cam_probe_atapi(struct sili_port *ap, struct ata_port *at);
114 static void sili_ata_dummy_done(struct ata_xfer *xa);
115 static void ata_fix_identify(struct ata_identify *id);
116 static void sili_cam_rescan(struct sili_port *ap);
117
118 int
119 sili_cam_attach(struct sili_port *ap)
120 {
121         struct cam_devq *devq;
122         struct cam_sim *sim;
123         int error;
124         int unit;
125
126         kprintf("%s: CAM ATTACH\n", PORTNAME(ap));
127         /*
128          * We want at least one ccb to be available for error processing
129          * so don't let CAM use more then ncmds - 1.
130          */
131         unit = device_get_unit(ap->ap_sc->sc_dev);
132         if (ap->ap_sc->sc_ncmds > 1)
133                 devq = cam_simq_alloc(ap->ap_sc->sc_ncmds - 1);
134         else
135                 devq = cam_simq_alloc(ap->ap_sc->sc_ncmds);
136         if (devq == NULL) {
137                 return (ENOMEM);
138         }
139         sim = cam_sim_alloc(sili_xpt_action, sili_xpt_poll, "sili",
140                            (void *)ap, unit, &sim_mplock, 1, 1, devq);
141         cam_simq_release(devq);
142         if (sim == NULL) {
143                 return (ENOMEM);
144         }
145         ap->ap_sim = sim;
146         sili_os_unlock_port(ap);
147         error = xpt_bus_register(ap->ap_sim, ap->ap_num);
148         sili_os_lock_port(ap);
149         if (error != CAM_SUCCESS) {
150                 sili_cam_detach(ap);
151                 return (EINVAL);
152         }
153         kprintf("%s: CAM ATTACH2\n", PORTNAME(ap));
154         ap->ap_flags |= AP_F_BUS_REGISTERED;
155         kprintf("%s: CAM ATTACH3 %d\n", PORTNAME(ap), ap->ap_probe);
156
157         if (ap->ap_probe == ATA_PROBE_NEED_IDENT)
158                 error = sili_cam_probe(ap, NULL);
159         else
160                 error = 0;
161         if (error) {
162                 sili_cam_detach(ap);
163                 return (EIO);
164         }
165         ap->ap_flags |= AP_F_CAM_ATTACHED;
166
167         return(0);
168 }
169
170 /*
171  * The state of the port has changed.
172  *
173  * If at is NULL the physical port has changed state.
174  * If at is non-NULL a particular target behind a PM has changed state.
175  *
176  * If found is -1 the target state must be queued to a non-interrupt context.
177  * (only works with at == NULL).
178  *
179  * If found is 0 the target was removed.
180  * If found is 1 the target was inserted.
181  */
182 void
183 sili_cam_changed(struct sili_port *ap, struct ata_port *atx, int found)
184 {
185         struct cam_path *tmppath;
186         int status;
187         int target;
188
189         target = atx ? atx->at_target : CAM_TARGET_WILDCARD;
190
191         if (ap->ap_sim == NULL)
192                 return;
193         if (found == CAM_TARGET_WILDCARD) {
194                 status = xpt_create_path(&tmppath, NULL,
195                                          cam_sim_path(ap->ap_sim),
196                                          target, CAM_LUN_WILDCARD);
197                 if (status != CAM_REQ_CMP)
198                         return;
199                 sili_cam_rescan(ap);
200         } else {
201                 status = xpt_create_path(&tmppath, NULL,
202                                          cam_sim_path(ap->ap_sim),
203                                          target,
204                                          CAM_LUN_WILDCARD);
205                 if (status != CAM_REQ_CMP)
206                         return;
207 #if 0
208                 /*
209                  * This confuses CAM
210                  */
211                 if (found)
212                         xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
213                 else
214                         xpt_async(AC_LOST_DEVICE, tmppath, NULL);
215 #endif
216         }
217         xpt_free_path(tmppath);
218 }
219
220 void
221 sili_cam_detach(struct sili_port *ap)
222 {
223         int error;
224
225         if ((ap->ap_flags & AP_F_CAM_ATTACHED) == 0)
226                 return;
227         get_mplock();
228         if (ap->ap_sim) {
229                 xpt_freeze_simq(ap->ap_sim, 1);
230         }
231         if (ap->ap_flags & AP_F_BUS_REGISTERED) {
232                 error = xpt_bus_deregister(cam_sim_path(ap->ap_sim));
233                 KKASSERT(error == CAM_REQ_CMP);
234                 ap->ap_flags &= ~AP_F_BUS_REGISTERED;
235         }
236         if (ap->ap_sim) {
237                 cam_sim_free(ap->ap_sim);
238                 ap->ap_sim = NULL;
239         }
240         rel_mplock();
241         ap->ap_flags &= ~AP_F_CAM_ATTACHED;
242 }
243
244 /*
245  * Once the SILI port has been attached we need to probe for a device or
246  * devices on the port and setup various options.
247  *
248  * If at is NULL we are probing the direct-attached device on the port,
249  * which may or may not be a port multiplier.
250  */
251 int
252 sili_cam_probe(struct sili_port *ap, struct ata_port *atx)
253 {
254         struct ata_port *at;
255         struct ata_xfer *xa;
256         u_int64_t       capacity;
257         u_int64_t       capacity_bytes;
258         int             model_len;
259         int             error;
260         int             devncqdepth;
261         int             i;
262         const char      *wcstr;
263         const char      *rastr;
264         const char      *scstr;
265         const char      *type;
266
267         error = EIO;
268
269         /*
270          * Delayed CAM attachment for initial probe, sim may be NULL
271          */
272         if (ap->ap_sim == NULL)
273                 return(0);
274
275         /*
276          * A NULL atx indicates a probe of the directly connected device.
277          * A non-NULL atx indicates a device connected via a port multiplier.
278          * We need to preserve atx for calls to sili_ata_get_xfer().
279          *
280          * at is always non-NULL.  For directly connected devices we supply
281          * an (at) pointing to target 0.
282          */
283         if (atx == NULL) {
284                 at = ap->ap_ata;        /* direct attached - device 0 */
285                 if (ap->ap_type == ATA_PORT_T_PM) {
286                         kprintf("%s: Found Port Multiplier\n",
287                                 ATANAME(ap, atx));
288                         return (0);
289                 }
290                 at->at_type = ap->ap_type;
291         } else {
292                 at = atx;
293                 if (atx->at_type == ATA_PORT_T_PM) {
294                         kprintf("%s: Bogus device, reducing port count to %d\n",
295                                 ATANAME(ap, atx), atx->at_target);
296                         if (ap->ap_pmcount > atx->at_target)
297                                 ap->ap_pmcount = atx->at_target;
298                         goto err;
299                 }
300         }
301         if (ap->ap_type == ATA_PORT_T_NONE)
302                 goto err;
303         if (at->at_type == ATA_PORT_T_NONE)
304                 goto err;
305
306         /*
307          * Issue identify, saving the result
308          */
309         xa = sili_ata_get_xfer(ap, atx);
310         xa->complete = sili_ata_dummy_done;
311         xa->data = &at->at_identify;
312         xa->datalen = sizeof(at->at_identify);
313         xa->fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
314
315         switch(at->at_type) {
316         case ATA_PORT_T_DISK:
317                 xa->fis->command = ATA_C_IDENTIFY;
318                 type = "DISK";
319                 break;
320         case ATA_PORT_T_ATAPI:
321                 xa->fis->command = ATA_C_ATAPI_IDENTIFY;
322                 type = "ATAPI";
323                 break;
324         default:
325                 xa->fis->command = ATA_C_ATAPI_IDENTIFY;
326                 type = "UNKNOWN(ATAPI?)";
327                 break;
328         }
329         xa->fis->features = 0;
330         xa->fis->device = 0;
331         xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL;
332         xa->timeout = 1000;
333
334         if (sili_ata_cmd(xa) != ATA_S_COMPLETE) {
335                 kprintf("%s: Detected %s device but unable to IDENTIFY\n",
336                         ATANAME(ap, atx), type);
337                 sili_ata_put_xfer(xa);
338                 goto err;
339         }
340         sili_ata_put_xfer(xa);
341
342         ata_fix_identify(&at->at_identify);
343
344         /*
345          * Read capacity using SATA probe info.
346          */
347         if (le16toh(at->at_identify.cmdset83) & 0x0400) {
348                 /* LBA48 feature set supported */
349                 capacity = 0;
350                 for (i = 3; i >= 0; --i) {
351                         capacity <<= 16;
352                         capacity +=
353                             le16toh(at->at_identify.addrsecxt[i]);
354                 }
355         } else {
356                 capacity = le16toh(at->at_identify.addrsec[1]);
357                 capacity <<= 16;
358                 capacity += le16toh(at->at_identify.addrsec[0]);
359         }
360         at->at_capacity = capacity;
361         if (atx == NULL)
362                 ap->ap_probe = ATA_PROBE_GOOD;
363
364         capacity_bytes = capacity * 512;
365
366         /*
367          * Negotiate NCQ, throw away any ata_xfer's beyond the negotiated
368          * number of slots and limit the number of CAM ccb's to one less
369          * so we always have a slot available for recovery.
370          *
371          * NCQ is not used if ap_ncqdepth is 1 or the host controller does
372          * not support it, and in that case the driver can handle extra
373          * ccb's.
374          *
375          * NCQ is currently used only with direct-attached disks.  It is
376          * not used with port multipliers or direct-attached ATAPI devices.
377          *
378          * Remember at least one extra CCB needs to be reserved for the
379          * error ccb.
380          */
381         if ((ap->ap_sc->sc_flags & SILI_F_NCQ) &&
382             at->at_type == ATA_PORT_T_DISK &&
383             (le16toh(at->at_identify.satacap) & (1 << 8))) {
384                 at->at_ncqdepth = (le16toh(at->at_identify.qdepth) & 0x1F) + 1;
385                 devncqdepth = at->at_ncqdepth;
386                 if (at->at_ncqdepth > ap->ap_sc->sc_ncmds)
387                         at->at_ncqdepth = ap->ap_sc->sc_ncmds;
388                 if (at->at_ncqdepth > 1) {
389                         for (i = 0; i < ap->ap_sc->sc_ncmds; ++i) {
390                                 xa = sili_ata_get_xfer(ap, atx);
391                                 if (xa->tag < at->at_ncqdepth) {
392                                         xa->state = ATA_S_COMPLETE;
393                                         sili_ata_put_xfer(xa);
394                                 }
395                         }
396                         if (at->at_ncqdepth >= ap->ap_sc->sc_ncmds) {
397                                 cam_devq_resize(ap->ap_sim->devq,
398                                                 at->at_ncqdepth - 1);
399                         }
400                 }
401         } else {
402                 devncqdepth = 0;
403         }
404
405         /*
406          * Make the model string a bit more presentable
407          */
408         for (model_len = 40; model_len; --model_len) {
409                 if (at->at_identify.model[model_len-1] == ' ')
410                         continue;
411                 if (at->at_identify.model[model_len-1] == 0)
412                         continue;
413                 break;
414         }
415
416         /*
417          * Generate informatiive strings.
418          *
419          * NOTE: We do not automatically set write caching, lookahead,
420          *       or the security state for ATAPI devices.
421          */
422         if (at->at_identify.cmdset82 & ATA_IDENTIFY_WRITECACHE) {
423                 if (at->at_identify.features85 & ATA_IDENTIFY_WRITECACHE)
424                         wcstr = "enabled";
425                 else if (at->at_type == ATA_PORT_T_ATAPI)
426                         wcstr = "disabled";
427                 else
428                         wcstr = "enabling";
429         } else {
430                     wcstr = "notsupp";
431         }
432
433         if (at->at_identify.cmdset82 & ATA_IDENTIFY_LOOKAHEAD) {
434                 if (at->at_identify.features85 & ATA_IDENTIFY_LOOKAHEAD)
435                         rastr = "enabled";
436                 else if (at->at_type == ATA_PORT_T_ATAPI)
437                         rastr = "disabled";
438                 else
439                         rastr = "enabling";
440         } else {
441                     rastr = "notsupp";
442         }
443
444         if (at->at_identify.cmdset82 & ATA_IDENTIFY_SECURITY) {
445                 if (at->at_identify.securestatus & ATA_SECURE_FROZEN)
446                         scstr = "frozen";
447                 else if (at->at_type == ATA_PORT_T_ATAPI)
448                         scstr = "unfrozen";
449                 else if (SiliNoFeatures & (1 << ap->ap_num))
450                         scstr = "<disabled>";
451                 else
452                         scstr = "freezing";
453         } else {
454                     scstr = "notsupp";
455         }
456
457         kprintf("%s: Found %s \"%*.*s %8.8s\" serial=\"%20.20s\"\n"
458                 "%s: tags=%d/%d satacap=%04x satafea=%04x NCQ=%s "
459                 "capacity=%lld.%02dMB\n",
460
461                 ATANAME(ap, atx),
462                 type,
463                 model_len, model_len,
464                 at->at_identify.model,
465                 at->at_identify.firmware,
466                 at->at_identify.serial,
467
468                 ATANAME(ap, atx),
469                 devncqdepth, ap->ap_sc->sc_ncmds,
470                 at->at_identify.satacap,
471                 at->at_identify.satafsup,
472                 (at->at_ncqdepth > 1 ? "YES" : "NO"),
473                 (long long)capacity_bytes / (1024 * 1024),
474                 (int)(capacity_bytes % (1024 * 1024)) * 100 / (1024 * 1024)
475         );
476         kprintf("%s: f85=%04x f86=%04x f87=%04x WC=%s RA=%s SEC=%s\n",
477                 ATANAME(ap, atx),
478                 at->at_identify.features85,
479                 at->at_identify.features86,
480                 at->at_identify.features87,
481                 wcstr,
482                 rastr,
483                 scstr
484         );
485
486         /*
487          * Additional type-specific probing
488          */
489         switch(at->at_type) {
490         case ATA_PORT_T_DISK:
491                 error = sili_cam_probe_disk(ap, atx);
492                 break;
493         case ATA_PORT_T_ATAPI:
494                 error = sili_cam_probe_atapi(ap, atx);
495                 break;
496         default:
497                 error = EIO;
498                 break;
499         }
500 err:
501         kprintf("%s: CAM PROBE %d\n", ATANAME(ap, atx), error);
502         if (error) {
503                 at->at_probe = ATA_PROBE_FAILED;
504                 if (atx == NULL)
505                         ap->ap_probe = at->at_probe;
506         } else {
507                 at->at_probe = ATA_PROBE_GOOD;
508                 if (atx == NULL)
509                         ap->ap_probe = at->at_probe;
510         }
511         return (error);
512 }
513
514 /*
515  * DISK-specific probe after initial ident
516  */
517 static int
518 sili_cam_probe_disk(struct sili_port *ap, struct ata_port *atx)
519 {
520         struct ata_port *at;
521         struct ata_xfer *xa;
522
523         at = atx ? atx : ap->ap_ata;
524
525         /*
526          * Enable write cache if supported
527          *
528          * NOTE: "WD My Book" external disk devices have a very poor
529          *       daughter board between the the ESATA and the HD.  Sending
530          *       any ATA_C_SET_FEATURES commands will break the hardware port
531          *       with a fatal protocol error.  However, this device also
532          *       indicates that WRITECACHE is already on and READAHEAD is
533          *       not supported so we avoid the issue.
534          */
535         if ((at->at_identify.cmdset82 & ATA_IDENTIFY_WRITECACHE) &&
536             (at->at_identify.features85 & ATA_IDENTIFY_WRITECACHE) == 0) {
537                 xa = sili_ata_get_xfer(ap, atx);
538                 xa->complete = sili_ata_dummy_done;
539                 xa->fis->command = ATA_C_SET_FEATURES;
540                 /*xa->fis->features = ATA_SF_WRITECACHE_EN;*/
541                 xa->fis->features = ATA_SF_LOOKAHEAD_EN;
542                 xa->fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
543                 xa->fis->device = 0;
544                 xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL;
545                 xa->timeout = 1000;
546                 xa->datalen = 0;
547                 if (sili_ata_cmd(xa) == ATA_S_COMPLETE)
548                         at->at_features |= ATA_PORT_F_WCACHE;
549                 else
550                         kprintf("%s: Unable to enable write-caching\n",
551                                 ATANAME(ap, atx));
552                 sili_ata_put_xfer(xa);
553         }
554
555         /*
556          * Enable readahead if supported
557          */
558         if ((at->at_identify.cmdset82 & ATA_IDENTIFY_LOOKAHEAD) &&
559             (at->at_identify.features85 & ATA_IDENTIFY_LOOKAHEAD) == 0) {
560                 xa = sili_ata_get_xfer(ap, atx);
561                 xa->complete = sili_ata_dummy_done;
562                 xa->fis->command = ATA_C_SET_FEATURES;
563                 xa->fis->features = ATA_SF_LOOKAHEAD_EN;
564                 xa->fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
565                 xa->fis->device = 0;
566                 xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL;
567                 xa->timeout = 1000;
568                 xa->datalen = 0;
569                 if (sili_ata_cmd(xa) == ATA_S_COMPLETE)
570                         at->at_features |= ATA_PORT_F_RAHEAD;
571                 else
572                         kprintf("%s: Unable to enable read-ahead\n",
573                                 ATANAME(ap, atx));
574                 sili_ata_put_xfer(xa);
575         }
576
577         /*
578          * FREEZE LOCK the device so malicious users can't lock it on us.
579          * As there is no harm in issuing this to devices that don't
580          * support the security feature set we just send it, and don't bother
581          * checking if the device sends a command abort to tell us it doesn't
582          * support it
583          */
584         if ((at->at_identify.cmdset82 & ATA_IDENTIFY_SECURITY) &&
585             (at->at_identify.securestatus & ATA_SECURE_FROZEN) == 0 &&
586             (SiliNoFeatures & (1 << ap->ap_num)) == 0) {
587                 xa = sili_ata_get_xfer(ap, atx);
588                 xa->complete = sili_ata_dummy_done;
589                 xa->fis->command = ATA_C_SEC_FREEZE_LOCK;
590                 xa->fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
591                 xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL;
592                 xa->timeout = 1000;
593                 xa->datalen = 0;
594                 if (sili_ata_cmd(xa) == ATA_S_COMPLETE)
595                         at->at_features |= ATA_PORT_F_FRZLCK;
596                 else
597                         kprintf("%s: Unable to set security freeze\n",
598                                 ATANAME(ap, atx));
599                 sili_ata_put_xfer(xa);
600         }
601
602         return (0);
603 }
604
605 /*
606  * ATAPI-specific probe after initial ident
607  */
608 static int
609 sili_cam_probe_atapi(struct sili_port *ap, struct ata_port *atx)
610 {
611         return(0);
612 }
613
614 /*
615  * Fix byte ordering so buffers can be accessed as
616  * strings.
617  */
618 static void
619 ata_fix_identify(struct ata_identify *id)
620 {
621         u_int16_t       *swap;
622         int             i;
623
624         swap = (u_int16_t *)id->serial;
625         for (i = 0; i < sizeof(id->serial) / sizeof(u_int16_t); i++)
626                 swap[i] = bswap16(swap[i]);
627
628         swap = (u_int16_t *)id->firmware;
629         for (i = 0; i < sizeof(id->firmware) / sizeof(u_int16_t); i++)
630                 swap[i] = bswap16(swap[i]);
631
632         swap = (u_int16_t *)id->model;
633         for (i = 0; i < sizeof(id->model) / sizeof(u_int16_t); i++)
634                 swap[i] = bswap16(swap[i]);
635 }
636
637 /*
638  * Dummy done callback for xa.
639  */
640 static void
641 sili_ata_dummy_done(struct ata_xfer *xa)
642 {
643 }
644
645 /*
646  * Use an engineering request to initiate a target scan for devices
647  * behind a port multiplier.
648  *
649  * An asynchronous bus scan is used to avoid reentrancy issues.
650  */
651 static void
652 sili_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
653 {
654         struct sili_port *ap = ccb->ccb_h.sim_priv.entries[0].ptr;
655
656         if (ccb->ccb_h.func_code == XPT_SCAN_BUS) {
657                 kprintf("%s: CAM RESCAN CALLBACK\n", PORTNAME(ap));
658                 ap->ap_flags &= ~AP_F_SCAN_RUNNING;
659                 if (ap->ap_flags & AP_F_SCAN_REQUESTED) {
660                         ap->ap_flags &= ~AP_F_SCAN_REQUESTED;
661                         sili_cam_rescan(ap);
662                 }
663                 ap->ap_flags |= AP_F_SCAN_COMPLETED;
664                 wakeup(&ap->ap_flags);
665         }
666         xpt_free_ccb(ccb);
667 }
668
669 static void
670 sili_cam_rescan(struct sili_port *ap)
671 {
672         struct cam_path *path;
673         union ccb *ccb;
674         int status;
675         int i;
676
677         kprintf("%s: CAM RESCAN-A\n", PORTNAME(ap));
678         if (ap->ap_flags & AP_F_SCAN_RUNNING) {
679                 ap->ap_flags |= AP_F_SCAN_REQUESTED;
680                 return;
681         }
682         ap->ap_flags |= AP_F_SCAN_RUNNING;
683         for (i = 0; i < SILI_MAX_PMPORTS; ++i) {
684                 ap->ap_ata[i].at_features |= ATA_PORT_F_RESCAN;
685         }
686
687         status = xpt_create_path(&path, xpt_periph, cam_sim_path(ap->ap_sim),
688                                  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
689         if (status != CAM_REQ_CMP)
690                 return;
691
692         ccb = xpt_alloc_ccb();
693         xpt_setup_ccb(&ccb->ccb_h, path, 5);    /* 5 = low priority */
694         ccb->ccb_h.func_code = XPT_ENG_EXEC;
695         ccb->ccb_h.cbfcnp = sili_cam_rescan_callback;
696         ccb->ccb_h.sim_priv.entries[0].ptr = ap;
697         ccb->crcn.flags = CAM_FLAG_NONE;
698         xpt_action_async(ccb);
699 }
700
701 static void
702 sili_xpt_rescan(struct sili_port *ap)
703 {
704         struct cam_path *path;
705         union ccb *ccb;
706         int status;
707
708         kprintf("%s: CAM RESCAN-B\n", PORTNAME(ap));
709         status = xpt_create_path(&path, xpt_periph, cam_sim_path(ap->ap_sim),
710                                  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
711         if (status != CAM_REQ_CMP)
712                 return;
713
714         ccb = xpt_alloc_ccb();
715         xpt_setup_ccb(&ccb->ccb_h, path, 5);    /* 5 = low priority */
716         ccb->ccb_h.func_code = XPT_SCAN_BUS;
717         ccb->ccb_h.cbfcnp = sili_cam_rescan_callback;
718         ccb->ccb_h.sim_priv.entries[0].ptr = ap;
719         ccb->crcn.flags = CAM_FLAG_NONE;
720         xpt_action_async(ccb);
721 }
722
723 /*
724  * Action function - dispatch command
725  */
726 static
727 void
728 sili_xpt_action(struct cam_sim *sim, union ccb *ccb)
729 {
730         struct sili_port *ap;
731         struct ata_port  *at, *atx;
732         struct ccb_hdr *ccbh;
733         int unit;
734
735         /* XXX lock */
736         ap = cam_sim_softc(sim);
737         at = ap->ap_ata;
738         atx = NULL;
739         KKASSERT(ap != NULL);
740         ccbh = &ccb->ccb_h;
741         unit = cam_sim_unit(sim);
742
743         /*
744          * Early failure checks.  These checks do not apply to XPT_PATH_INQ,
745          * otherwise the bus rescan will not remove the dead devices when
746          * unplugging a PM.
747          *
748          * For non-wildcards we have one target (0) and one lun (0),
749          * unless we have a port multiplier.
750          *
751          * A wildcard target indicates only the general bus is being
752          * probed.
753          *
754          * Calculate at and atx.  at is always non-NULL.  atx is only
755          * non-NULL for direct-attached devices.  It will be NULL for
756          * devices behind a port multiplier.
757          *
758          * XXX What do we do with a LUN wildcard?
759          */
760         if (ccbh->target_id != CAM_TARGET_WILDCARD &&
761             ccbh->func_code != XPT_PATH_INQ) {
762                 if (ap->ap_type == ATA_PORT_T_NONE) {
763                         ccbh->status = CAM_DEV_NOT_THERE;
764                         xpt_done(ccb);
765                         return;
766                 }
767                 if (ccbh->target_id < 0 || ccbh->target_id >= ap->ap_pmcount) {
768                         ccbh->status = CAM_DEV_NOT_THERE;
769                         xpt_done(ccb);
770                         return;
771                 }
772                 at += ccbh->target_id;
773                 if (ap->ap_type == ATA_PORT_T_PM)
774                         atx = at;
775
776                 if (ccbh->target_lun != CAM_LUN_WILDCARD && ccbh->target_lun) {
777                         ccbh->status = CAM_DEV_NOT_THERE;
778                         xpt_done(ccb);
779                         return;
780                 }
781         }
782
783         /*
784          * Switch on the meta XPT command
785          */
786         switch(ccbh->func_code) {
787         case XPT_ENG_EXEC:
788                 /*
789                  * This routine is called after a port multiplier has been
790                  * probed.
791                  */
792                 ccbh->status = CAM_REQ_CMP;
793                 sili_os_lock_port(ap);
794                 sili_port_state_machine(ap, 0);
795                 sili_os_unlock_port(ap);
796                 xpt_done(ccb);
797                 sili_xpt_rescan(ap);
798                 break;
799         case XPT_PATH_INQ:
800                 /*
801                  * This command always succeeds, otherwise the bus scan
802                  * will not detach dead devices.
803                  */
804                 ccb->cpi.version_num = 1;
805                 ccb->cpi.hba_inquiry = 0;
806                 ccb->cpi.target_sprt = 0;
807                 ccb->cpi.hba_misc = PIM_SEQSCAN;
808                 ccb->cpi.hba_eng_cnt = 0;
809                 bzero(ccb->cpi.vuhba_flags, sizeof(ccb->cpi.vuhba_flags));
810                 ccb->cpi.max_target = SILI_MAX_PMPORTS - 1;
811                 ccb->cpi.max_lun = 0;
812                 ccb->cpi.async_flags = 0;
813                 ccb->cpi.hpath_id = 0;
814                 ccb->cpi.initiator_id = SILI_MAX_PMPORTS - 1;
815                 ccb->cpi.unit_number = cam_sim_unit(sim);
816                 ccb->cpi.bus_id = cam_sim_bus(sim);
817                 ccb->cpi.base_transfer_speed = 150000;
818                 ccb->cpi.transport = XPORT_SATA;
819                 ccb->cpi.transport_version = 1;
820                 ccb->cpi.protocol = PROTO_SCSI;
821                 ccb->cpi.protocol_version = SCSI_REV_2;
822
823                 ccbh->status = CAM_REQ_CMP;
824                 if (ccbh->target_id == CAM_TARGET_WILDCARD) {
825                         sili_os_lock_port(ap);
826                         sili_port_state_machine(ap, 0);
827                         sili_os_unlock_port(ap);
828                 } else {
829                         switch(sili_pread(ap, SILI_PREG_SSTS) &
830                                SILI_PREG_SSTS_SPD) {
831                         case SILI_PREG_SSTS_SPD_GEN1:
832                                 ccb->cpi.base_transfer_speed = 150000;
833                                 break;
834                         case SILI_PREG_SSTS_SPD_GEN2:
835                                 ccb->cpi.base_transfer_speed = 300000;
836                                 break;
837                         default:
838                                 /* unknown */
839                                 ccb->cpi.base_transfer_speed = 1000;
840                                 break;
841                         }
842 #if 0
843                         if (ap->ap_type == ATA_PORT_T_NONE)
844                                 ccbh->status = CAM_DEV_NOT_THERE;
845 #endif
846                 }
847                 xpt_done(ccb);
848                 break;
849         case XPT_RESET_DEV:
850                 sili_os_lock_port(ap);
851                 if (ap->ap_type == ATA_PORT_T_NONE) {
852                         ccbh->status = CAM_DEV_NOT_THERE;
853                 } else {
854                         sili_port_reset(ap, atx, 0);
855                         ccbh->status = CAM_REQ_CMP;
856                 }
857                 sili_os_unlock_port(ap);
858                 xpt_done(ccb);
859                 break;
860         case XPT_RESET_BUS:
861                 sili_os_lock_port(ap);
862                 sili_port_reset(ap, NULL, 1);
863                 sili_os_unlock_port(ap);
864                 ccbh->status = CAM_REQ_CMP;
865                 xpt_done(ccb);
866                 break;
867         case XPT_SET_TRAN_SETTINGS:
868                 ccbh->status = CAM_FUNC_NOTAVAIL;
869                 xpt_done(ccb);
870                 break;
871         case XPT_GET_TRAN_SETTINGS:
872                 ccb->cts.protocol = PROTO_SCSI;
873                 ccb->cts.protocol_version = SCSI_REV_2;
874                 ccb->cts.transport = XPORT_SATA;
875                 ccb->cts.transport_version = XPORT_VERSION_UNSPECIFIED;
876                 ccb->cts.proto_specific.valid = 0;
877                 ccb->cts.xport_specific.valid = 0;
878                 ccbh->status = CAM_REQ_CMP;
879                 xpt_done(ccb);
880                 break;
881         case XPT_CALC_GEOMETRY:
882                 cam_calc_geometry(&ccb->ccg, 1);
883                 xpt_done(ccb);
884                 break;
885         case XPT_SCSI_IO:
886                 /*
887                  * Our parallel startup code might have only probed through
888                  * to the IDENT, so do the last step if necessary.
889                  */
890                 if (at->at_probe == ATA_PROBE_NEED_IDENT)
891                         sili_cam_probe(ap, atx);
892                 if (at->at_probe != ATA_PROBE_GOOD) {
893                         ccbh->status = CAM_DEV_NOT_THERE;
894                         xpt_done(ccb);
895                         break;
896                 }
897                 switch(at->at_type) {
898                 case ATA_PORT_T_DISK:
899                         sili_xpt_scsi_disk_io(ap, atx, ccb);
900                         break;
901                 case ATA_PORT_T_ATAPI:
902                         sili_xpt_scsi_atapi_io(ap, atx, ccb);
903                         break;
904                 default:
905                         ccbh->status = CAM_REQ_INVALID;
906                         xpt_done(ccb);
907                         break;
908                 }
909                 break;
910         default:
911                 ccbh->status = CAM_REQ_INVALID;
912                 xpt_done(ccb);
913                 break;
914         }
915 }
916
917 /*
918  * Poll function.
919  *
920  * Generally this function gets called heavily when interrupts might be
921  * non-operational, during a halt/reboot or panic.
922  */
923 static
924 void
925 sili_xpt_poll(struct cam_sim *sim)
926 {
927         struct sili_port *ap;
928
929         ap = cam_sim_softc(sim);
930         crit_enter();
931         sili_os_lock_port(ap);
932         sili_port_intr(ap, 1);
933         sili_os_unlock_port(ap);
934         crit_exit();
935 }
936
937 /*
938  * Convert the SCSI command in ccb to an ata_xfer command in xa
939  * for ATA_PORT_T_DISK operations.  Set the completion function
940  * to convert the response back, then dispatch to the OpenBSD SILI
941  * layer.
942  *
943  * SILI DISK commands only support a limited command set, and we
944  * fake additional commands to make it play nice with the CAM subsystem.
945  */
946 static
947 void
948 sili_xpt_scsi_disk_io(struct sili_port *ap, struct ata_port *atx,
949                       union ccb *ccb)
950 {
951         struct ccb_hdr *ccbh;
952         struct ccb_scsiio *csio;
953         struct ata_xfer *xa;
954         struct ata_port *at;
955         struct ata_fis_h2d *fis;
956         scsi_cdb_t cdb;
957         union scsi_data *rdata;
958         int rdata_len;
959         u_int64_t capacity;
960         u_int64_t lba;
961         u_int32_t count;
962
963         ccbh = &ccb->csio.ccb_h;
964         csio = &ccb->csio;
965         at = atx ? atx : &ap->ap_ata[0];
966
967         /*
968          * XXX not passing NULL at for direct attach!
969          */
970         xa = sili_ata_get_xfer(ap, atx);
971         rdata = (void *)csio->data_ptr;
972         rdata_len = csio->dxfer_len;
973
974         /*
975          * Build the FIS or process the csio to completion.
976          */
977         cdb = (void *)((ccbh->flags & CAM_CDB_POINTER) ?
978                         csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
979
980         switch(cdb->generic.opcode) {
981         case REQUEST_SENSE:
982                 /*
983                  * Auto-sense everything, so explicit sense requests
984                  * return no-sense.
985                  */
986                 ccbh->status = CAM_SCSI_STATUS_ERROR;
987                 break;
988         case INQUIRY:
989                 /*
990                  * Inquiry supported features
991                  *
992                  * [opcode, byte2, page_code, length, control]
993                  */
994                 if (cdb->inquiry.byte2 & SI_EVPD) {
995                         switch(cdb->inquiry.page_code) {
996                         case SVPD_SUPPORTED_PAGE_LIST:
997                                 /* XXX atascsi_disk_vpd_supported */
998                         case SVPD_UNIT_SERIAL_NUMBER:
999                                 /* XXX atascsi_disk_vpd_serial */
1000                         case SVPD_UNIT_DEVID:
1001                                 /* XXX atascsi_disk_vpd_ident */
1002                         default:
1003                                 ccbh->status = CAM_FUNC_NOTAVAIL;
1004                                 break;
1005                         }
1006                 } else {
1007                         bzero(rdata, rdata_len);
1008                         if (rdata_len < SHORT_INQUIRY_LENGTH) {
1009                                 ccbh->status = CAM_CCB_LEN_ERR;
1010                                 break;
1011                         }
1012                         if (rdata_len > sizeof(rdata->inquiry_data))
1013                                 rdata_len = sizeof(rdata->inquiry_data);
1014                         rdata->inquiry_data.device = T_DIRECT;
1015                         rdata->inquiry_data.version = SCSI_REV_SPC2;
1016                         rdata->inquiry_data.response_format = 2;
1017                         rdata->inquiry_data.additional_length = 32;
1018                         bcopy("SATA    ", rdata->inquiry_data.vendor, 8);
1019                         bcopy(at->at_identify.model,
1020                               rdata->inquiry_data.product,
1021                               sizeof(rdata->inquiry_data.product));
1022                         bcopy(at->at_identify.firmware,
1023                               rdata->inquiry_data.revision,
1024                               sizeof(rdata->inquiry_data.revision));
1025                         ccbh->status = CAM_REQ_CMP;
1026                 }
1027                 break;
1028         case READ_CAPACITY_16:
1029                 if (cdb->read_capacity_16.service_action != SRC16_SERVICE_ACTION) {
1030                         ccbh->status = CAM_REQ_INVALID;
1031                         break;
1032                 }
1033                 if (rdata_len < sizeof(rdata->read_capacity_data_16)) {
1034                         ccbh->status = CAM_CCB_LEN_ERR;
1035                         break;
1036                 }
1037                 /* fall through */
1038         case READ_CAPACITY:
1039                 if (rdata_len < sizeof(rdata->read_capacity_data)) {
1040                         ccbh->status = CAM_CCB_LEN_ERR;
1041                         break;
1042                 }
1043
1044                 capacity = at->at_capacity;
1045
1046                 bzero(rdata, rdata_len);
1047                 if (cdb->generic.opcode == READ_CAPACITY) {
1048                         rdata_len = sizeof(rdata->read_capacity_data);
1049                         if (capacity > 0xFFFFFFFFU)
1050                                 capacity = 0xFFFFFFFFU;
1051                         bzero(&rdata->read_capacity_data, rdata_len);
1052                         scsi_ulto4b((u_int32_t)capacity - 1,
1053                                     rdata->read_capacity_data.addr);
1054                         scsi_ulto4b(512, rdata->read_capacity_data.length);
1055                 } else {
1056                         rdata_len = sizeof(rdata->read_capacity_data_16);
1057                         bzero(&rdata->read_capacity_data_16, rdata_len);
1058                         scsi_u64to8b(capacity - 1,
1059                                      rdata->read_capacity_data_16.addr);
1060                         scsi_ulto4b(512, rdata->read_capacity_data_16.length);
1061                 }
1062                 ccbh->status = CAM_REQ_CMP;
1063                 break;
1064         case SYNCHRONIZE_CACHE:
1065                 /*
1066                  * Synchronize cache.  Specification says this can take
1067                  * greater then 30 seconds so give it at least 45.
1068                  */
1069                 fis = xa->fis;
1070                 fis->flags = ATA_H2D_FLAGS_CMD;
1071                 fis->command = ATA_C_FLUSH_CACHE;
1072                 fis->device = 0;
1073                 if (xa->timeout < 45000)
1074                         xa->timeout = 45000;
1075                 xa->datalen = 0;
1076                 xa->flags = ATA_F_READ;
1077                 xa->complete = sili_ata_complete_disk_synchronize_cache;
1078                 break;
1079         case TEST_UNIT_READY:
1080         case START_STOP_UNIT:
1081         case PREVENT_ALLOW:
1082                 /*
1083                  * Just silently return success
1084                  */
1085                 ccbh->status = CAM_REQ_CMP;
1086                 rdata_len = 0;
1087                 break;
1088         case ATA_PASS_12:
1089         case ATA_PASS_16:
1090                 /*
1091                  * XXX implement pass-through
1092                  */
1093                 ccbh->status = CAM_FUNC_NOTAVAIL;
1094                 break;
1095         default:
1096                 switch(cdb->generic.opcode) {
1097                 case READ_6:
1098                         lba = scsi_3btoul(cdb->rw_6.addr) & 0x1FFFFF;
1099                         count = cdb->rw_6.length ? cdb->rw_6.length : 0x100;
1100                         xa->flags = ATA_F_READ;
1101                         break;
1102                 case READ_10:
1103                         lba = scsi_4btoul(cdb->rw_10.addr);
1104                         count = scsi_2btoul(cdb->rw_10.length);
1105                         xa->flags = ATA_F_READ;
1106                         break;
1107                 case READ_12:
1108                         lba = scsi_4btoul(cdb->rw_12.addr);
1109                         count = scsi_4btoul(cdb->rw_12.length);
1110                         xa->flags = ATA_F_READ;
1111                         break;
1112                 case READ_16:
1113                         lba = scsi_8btou64(cdb->rw_16.addr);
1114                         count = scsi_4btoul(cdb->rw_16.length);
1115                         xa->flags = ATA_F_READ;
1116                         break;
1117                 case WRITE_6:
1118                         lba = scsi_3btoul(cdb->rw_6.addr) & 0x1FFFFF;
1119                         count = cdb->rw_6.length ? cdb->rw_6.length : 0x100;
1120                         xa->flags = ATA_F_WRITE;
1121                         break;
1122                 case WRITE_10:
1123                         lba = scsi_4btoul(cdb->rw_10.addr);
1124                         count = scsi_2btoul(cdb->rw_10.length);
1125                         xa->flags = ATA_F_WRITE;
1126                         break;
1127                 case WRITE_12:
1128                         lba = scsi_4btoul(cdb->rw_12.addr);
1129                         count = scsi_4btoul(cdb->rw_12.length);
1130                         xa->flags = ATA_F_WRITE;
1131                         break;
1132                 case WRITE_16:
1133                         lba = scsi_8btou64(cdb->rw_16.addr);
1134                         count = scsi_4btoul(cdb->rw_16.length);
1135                         xa->flags = ATA_F_WRITE;
1136                         break;
1137                 default:
1138                         ccbh->status = CAM_REQ_INVALID;
1139                         break;
1140                 }
1141                 if (ccbh->status != CAM_REQ_INPROG)
1142                         break;
1143
1144                 fis = xa->fis;
1145                 fis->flags = ATA_H2D_FLAGS_CMD;
1146                 fis->lba_low = (u_int8_t)lba;
1147                 fis->lba_mid = (u_int8_t)(lba >> 8);
1148                 fis->lba_high = (u_int8_t)(lba >> 16);
1149                 fis->device = ATA_H2D_DEVICE_LBA;
1150
1151                 /*
1152                  * NCQ only for direct-attached disks, do not currently
1153                  * try to use NCQ with port multipliers.
1154                  *
1155                  * XXX fixme SII chip can do NCQ w/ port multipliers.
1156                  */
1157                 if (at->at_ncqdepth > 1 &&
1158                     at->at_type == ATA_PORT_T_DISK &&
1159                     (ap->ap_sc->sc_flags & SILI_F_NCQ) &&
1160                     (ccbh->flags & CAM_POLLED) == 0) {
1161                         /*
1162                          * Use NCQ - always uses 48 bit addressing
1163                          */
1164                         xa->flags |= ATA_F_NCQ;
1165                         fis->command = (xa->flags & ATA_F_WRITE) ?
1166                                         ATA_C_WRITE_FPDMA : ATA_C_READ_FPDMA;
1167                         fis->lba_low_exp = (u_int8_t)(lba >> 24);
1168                         fis->lba_mid_exp = (u_int8_t)(lba >> 32);
1169                         fis->lba_high_exp = (u_int8_t)(lba >> 40);
1170                         fis->sector_count = xa->tag << 3;
1171                         fis->features = (u_int8_t)count;
1172                         fis->features_exp = (u_int8_t)(count >> 8);
1173                 } else if (count > 0x100 || lba > 0xFFFFFFFFU) {
1174                         /*
1175                          * Use LBA48
1176                          */
1177                         fis->command = (xa->flags & ATA_F_WRITE) ?
1178                                         ATA_C_WRITEDMA_EXT : ATA_C_READDMA_EXT;
1179                         fis->lba_low_exp = (u_int8_t)(lba >> 24);
1180                         fis->lba_mid_exp = (u_int8_t)(lba >> 32);
1181                         fis->lba_high_exp = (u_int8_t)(lba >> 40);
1182                         fis->sector_count = (u_int8_t)count;
1183                         fis->sector_count_exp = (u_int8_t)(count >> 8);
1184                 } else {
1185                         /*
1186                          * Use LBA
1187                          *
1188                          * NOTE: 256 sectors is supported, stored as 0.
1189                          */
1190                         fis->command = (xa->flags & ATA_F_WRITE) ?
1191                                         ATA_C_WRITEDMA : ATA_C_READDMA;
1192                         fis->device |= (u_int8_t)(lba >> 24) & 0x0F;
1193                         fis->sector_count = (u_int8_t)count;
1194                 }
1195
1196                 xa->data = csio->data_ptr;
1197                 xa->datalen = csio->dxfer_len;
1198                 xa->complete = sili_ata_complete_disk_rw;
1199                 xa->timeout = ccbh->timeout;    /* milliseconds */
1200                 if (ccbh->flags & CAM_POLLED)
1201                         xa->flags |= ATA_F_POLL;
1202                 break;
1203         }
1204
1205         /*
1206          * If the request is still in progress the xa and FIS have
1207          * been set up and must be dispatched.  Otherwise the request
1208          * is complete.
1209          */
1210         if (ccbh->status == CAM_REQ_INPROG) {
1211                 KKASSERT(xa->complete != NULL);
1212                 xa->atascsi_private = ccb;
1213                 ccb->ccb_h.sim_priv.entries[0].ptr = ap;
1214                 sili_os_lock_port(ap);
1215                 fis->flags |= at->at_target;
1216                 sili_ata_cmd(xa);
1217                 sili_os_unlock_port(ap);
1218         } else {
1219                 sili_ata_put_xfer(xa);
1220                 xpt_done(ccb);
1221         }
1222 }
1223
1224 /*
1225  * Convert the SCSI command in ccb to an ata_xfer command in xa
1226  * for ATA_PORT_T_ATAPI operations.  Set the completion function
1227  * to convert the response back, then dispatch to the OpenBSD SILI
1228  * layer.
1229  */
1230 static
1231 void
1232 sili_xpt_scsi_atapi_io(struct sili_port *ap, struct ata_port *atx,
1233                         union ccb *ccb)
1234 {
1235         struct ccb_hdr *ccbh;
1236         struct ccb_scsiio *csio;
1237         struct ata_xfer *xa;
1238         struct ata_fis_h2d *fis;
1239         scsi_cdb_t cdbs;
1240         scsi_cdb_t cdbd;
1241         int flags;
1242         struct ata_port *at;
1243
1244         ccbh = &ccb->csio.ccb_h;
1245         csio = &ccb->csio;
1246         at = atx ? atx : &ap->ap_ata[0];
1247
1248         switch (ccbh->flags & CAM_DIR_MASK) {
1249         case CAM_DIR_IN:
1250                 flags = ATA_F_PACKET | ATA_F_READ;
1251                 break;
1252         case CAM_DIR_OUT:
1253                 flags = ATA_F_PACKET | ATA_F_WRITE;
1254                 break;
1255         case CAM_DIR_NONE:
1256                 flags = ATA_F_PACKET;
1257                 break;
1258         default:
1259                 ccbh->status = CAM_REQ_INVALID;
1260                 xpt_done(ccb);
1261                 return;
1262                 /* NOT REACHED */
1263         }
1264
1265         /*
1266          * The command has to fit in the packet command buffer.
1267          */
1268         if (csio->cdb_len < 6 || csio->cdb_len > 16) {
1269                 ccbh->status = CAM_CCB_LEN_ERR;
1270                 xpt_done(ccb);
1271                 return;
1272         }
1273
1274         /*
1275          * Initialize the XA and FIS.
1276          *
1277          * XXX not passing NULL at for direct attach!
1278          */
1279         xa = sili_ata_get_xfer(ap, atx);
1280         fis = xa->fis;
1281
1282         fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
1283         fis->command = ATA_C_PACKET;
1284         fis->device = 0;
1285         fis->sector_count = xa->tag << 3;
1286         fis->features = ATA_H2D_FEATURES_DMA |
1287                     ((flags & ATA_F_WRITE) ?
1288                     ATA_H2D_FEATURES_DIR_WRITE : ATA_H2D_FEATURES_DIR_READ);
1289         fis->lba_mid = 0x00;
1290         fis->lba_high = 0x20;
1291
1292         xa->flags = flags;
1293         xa->data = csio->data_ptr;
1294         xa->datalen = csio->dxfer_len;
1295         xa->timeout = ccbh->timeout;    /* milliseconds */
1296
1297         if (ccbh->flags & CAM_POLLED)
1298                 xa->flags |= ATA_F_POLL;
1299
1300         /*
1301          * Copy the cdb to the packetcmd buffer in the FIS using a
1302          * convenient pointer in the xa.
1303          */
1304         cdbs = (void *)((ccbh->flags & CAM_CDB_POINTER) ?
1305                         csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
1306         bcopy(cdbs, xa->packetcmd, csio->cdb_len);
1307
1308 #if 0
1309         kprintf("opcode %d cdb_len %d dxfer_len %d\n",
1310                 cdbs->generic.opcode,
1311                 csio->cdb_len, csio->dxfer_len);
1312 #endif
1313
1314         /*
1315          * Some ATAPI commands do not actually follow the SCSI standard.
1316          */
1317         cdbd = (void *)xa->packetcmd;
1318
1319         switch(cdbd->generic.opcode) {
1320         case INQUIRY:
1321                 /*
1322                  * Some ATAPI devices can't handle SI_EVPD being set
1323                  * for a basic inquiry (page_code == 0).
1324                  *
1325                  * Some ATAPI devices can't handle long inquiry lengths,
1326                  * don't ask me why.  Truncate the inquiry length.
1327                  */
1328                 if ((cdbd->inquiry.byte2 & SI_EVPD) &&
1329                     cdbd->inquiry.page_code == 0) {
1330                         cdbd->inquiry.byte2 &= ~SI_EVPD;
1331                 }
1332                 if (cdbd->inquiry.page_code == 0 &&
1333                     cdbd->inquiry.length > SHORT_INQUIRY_LENGTH) {
1334                         cdbd->inquiry.length = SHORT_INQUIRY_LENGTH;
1335                 }
1336                 break;
1337         case READ_6:
1338         case WRITE_6:
1339                 /*
1340                  * Convert *_6 to *_10 commands.  Most ATAPI devices
1341                  * cannot handle the SCSI READ_6 and WRITE_6 commands.
1342                  */
1343                 cdbd->rw_10.opcode |= 0x20;
1344                 cdbd->rw_10.byte2 = 0;
1345                 cdbd->rw_10.addr[0] = cdbs->rw_6.addr[0] & 0x1F;
1346                 cdbd->rw_10.addr[1] = cdbs->rw_6.addr[1];
1347                 cdbd->rw_10.addr[2] = cdbs->rw_6.addr[2];
1348                 cdbd->rw_10.addr[3] = 0;
1349                 cdbd->rw_10.reserved = 0;
1350                 cdbd->rw_10.length[0] = 0;
1351                 cdbd->rw_10.length[1] = cdbs->rw_6.length;
1352                 cdbd->rw_10.control = cdbs->rw_6.control;
1353                 break;
1354         default:
1355                 break;
1356         }
1357
1358         /*
1359          * And dispatch
1360          */
1361         xa->complete = sili_atapi_complete_cmd;
1362         xa->atascsi_private = ccb;
1363         ccb->ccb_h.sim_priv.entries[0].ptr = ap;
1364         sili_os_lock_port(ap);
1365         sili_ata_cmd(xa);
1366         sili_os_unlock_port(ap);
1367 }
1368
1369 /*
1370  * Completion function for ATA_PORT_T_DISK cache synchronization.
1371  */
1372 static
1373 void
1374 sili_ata_complete_disk_synchronize_cache(struct ata_xfer *xa)
1375 {
1376         union ccb *ccb = xa->atascsi_private;
1377         struct ccb_hdr *ccbh = &ccb->ccb_h;
1378         struct sili_port *ap = ccb->ccb_h.sim_priv.entries[0].ptr;
1379
1380         switch(xa->state) {
1381         case ATA_S_COMPLETE:
1382                 ccbh->status = CAM_REQ_CMP;
1383                 ccb->csio.scsi_status = SCSI_STATUS_OK;
1384                 break;
1385         case ATA_S_ERROR:
1386                 kprintf("%s: synchronize_cache: error\n",
1387                         ATANAME(ap, xa->at));
1388                 ccbh->status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
1389                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1390                 sili_ata_dummy_sense(&ccb->csio.sense_data);
1391                 break;
1392         case ATA_S_TIMEOUT:
1393                 kprintf("%s: synchronize_cache: timeout\n",
1394                         ATANAME(ap, xa->at));
1395                 ccbh->status = CAM_CMD_TIMEOUT;
1396                 break;
1397         default:
1398                 kprintf("%s: synchronize_cache: unknown state %d\n",
1399                         ATANAME(ap, xa->at), xa->state);
1400                 ccbh->status = CAM_REQ_CMP_ERR;
1401                 break;
1402         }
1403         sili_ata_put_xfer(xa);
1404         sili_os_unlock_port(ap);
1405         xpt_done(ccb);
1406         sili_os_lock_port(ap);
1407 }
1408
1409 /*
1410  * Completion function for ATA_PORT_T_DISK I/O
1411  */
1412 static
1413 void
1414 sili_ata_complete_disk_rw(struct ata_xfer *xa)
1415 {
1416         union ccb *ccb = xa->atascsi_private;
1417         struct ccb_hdr *ccbh = &ccb->ccb_h;
1418         struct sili_port *ap = ccb->ccb_h.sim_priv.entries[0].ptr;
1419
1420         switch(xa->state) {
1421         case ATA_S_COMPLETE:
1422                 ccbh->status = CAM_REQ_CMP;
1423                 ccb->csio.scsi_status = SCSI_STATUS_OK;
1424                 break;
1425         case ATA_S_ERROR:
1426                 kprintf("%s: disk_rw: error\n", ATANAME(ap, xa->at));
1427                 ccbh->status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID;
1428                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1429                 sili_ata_dummy_sense(&ccb->csio.sense_data);
1430                 break;
1431         case ATA_S_TIMEOUT:
1432                 kprintf("%s: disk_rw: timeout\n", ATANAME(ap, xa->at));
1433                 ccbh->status = CAM_CMD_TIMEOUT;
1434                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1435                 sili_ata_dummy_sense(&ccb->csio.sense_data);
1436                 break;
1437         default:
1438                 kprintf("%s: disk_rw: unknown state %d\n",
1439                         ATANAME(ap, xa->at), xa->state);
1440                 ccbh->status = CAM_REQ_CMP_ERR;
1441                 break;
1442         }
1443         ccb->csio.resid = xa->resid;
1444         sili_ata_put_xfer(xa);
1445         sili_os_unlock_port(ap);
1446         xpt_done(ccb);
1447         sili_os_lock_port(ap);
1448 }
1449
1450 /*
1451  * Completion function for ATA_PORT_T_ATAPI I/O
1452  *
1453  * Sense data is returned in the rfis.
1454  */
1455 static
1456 void
1457 sili_atapi_complete_cmd(struct ata_xfer *xa)
1458 {
1459         union ccb *ccb = xa->atascsi_private;
1460         struct ccb_hdr *ccbh = &ccb->ccb_h;
1461         struct sili_port *ap = ccb->ccb_h.sim_priv.entries[0].ptr;
1462         scsi_cdb_t cdb;
1463
1464         cdb = (void *)((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
1465                         ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes);
1466
1467         switch(xa->state) {
1468         case ATA_S_COMPLETE:
1469                 ccbh->status = CAM_REQ_CMP;
1470                 ccb->csio.scsi_status = SCSI_STATUS_OK;
1471                 break;
1472         case ATA_S_ERROR:
1473                 ccbh->status = CAM_SCSI_STATUS_ERROR;
1474                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1475                 sili_ata_atapi_sense(xa->rfis, &ccb->csio.sense_data);
1476                 break;
1477         case ATA_S_TIMEOUT:
1478                 kprintf("%s: cmd %d: timeout\n",
1479                         PORTNAME(ap), cdb->generic.opcode);
1480                 ccbh->status = CAM_CMD_TIMEOUT;
1481                 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
1482                 sili_ata_dummy_sense(&ccb->csio.sense_data);
1483                 break;
1484         default:
1485                 kprintf("%s: cmd %d: unknown state %d\n",
1486                         PORTNAME(ap), cdb->generic.opcode, xa->state);
1487                 ccbh->status = CAM_REQ_CMP_ERR;
1488                 break;
1489         }
1490         ccb->csio.resid = xa->resid;
1491         sili_ata_put_xfer(xa);
1492         sili_os_unlock_port(ap);
1493         xpt_done(ccb);
1494         sili_os_lock_port(ap);
1495 }
1496
1497 /*
1498  * Construct dummy sense data for errors on DISKs
1499  */
1500 static
1501 void
1502 sili_ata_dummy_sense(struct scsi_sense_data *sense_data)
1503 {
1504         sense_data->error_code = SSD_ERRCODE_VALID | SSD_CURRENT_ERROR;
1505         sense_data->segment = 0;
1506         sense_data->flags = SSD_KEY_MEDIUM_ERROR;
1507         sense_data->info[0] = 0;
1508         sense_data->info[1] = 0;
1509         sense_data->info[2] = 0;
1510         sense_data->info[3] = 0;
1511         sense_data->extra_len = 0;
1512 }
1513
1514 /*
1515  * Construct atapi sense data for errors on ATAPI
1516  *
1517  * The ATAPI sense data is stored in the passed rfis and must be converted
1518  * to SCSI sense data.
1519  */
1520 static
1521 void
1522 sili_ata_atapi_sense(struct ata_fis_d2h *rfis,
1523                      struct scsi_sense_data *sense_data)
1524 {
1525         sense_data->error_code = SSD_ERRCODE_VALID | SSD_CURRENT_ERROR;
1526         sense_data->segment = 0;
1527         sense_data->flags = (rfis->error & 0xF0) >> 4;
1528         if (rfis->error & 0x04)
1529                 sense_data->flags |= SSD_KEY_ILLEGAL_REQUEST;
1530         if (rfis->error & 0x02)
1531                 sense_data->flags |= SSD_EOM;
1532         if (rfis->error & 0x01)
1533                 sense_data->flags |= SSD_ILI;
1534         sense_data->info[0] = 0;
1535         sense_data->info[1] = 0;
1536         sense_data->info[2] = 0;
1537         sense_data->info[3] = 0;
1538         sense_data->extra_len = 0;
1539 }