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