AHCI - Implement ahci_xpt_poll() - fix livelock during shutdown/reboot/panic
[dragonfly.git] / sys / dev / disk / ahci / ahci_cam.c
blob337cbdf102916f47cb81ea5ed0cbb22fa11dc70e
1 /*
2 * Copyright (c) 2009 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
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.
35 * Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
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.
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.
49 * $OpenBSD: atascsi.c,v 1.64 2009/02/16 21:19:06 miod Exp $
50 * $DragonFly$
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.
57 * Much of the cdb<->xa conversion code was taken from OpenBSD, the rest
58 * was written natively for DragonFly.
61 #include "ahci.h"
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"
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);
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);
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);
118 ahci_cam_attach(struct ahci_port *ap)
120 struct cam_devq *devq;
121 struct cam_sim *sim;
122 int error;
123 int unit;
126 * We want at least one ccb to be available for error processing
127 * so don't let CAM use more then ncmds - 1.
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);
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);
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);
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);
157 error = ahci_cam_probe(ap);
158 if (error) {
159 ahci_cam_detach(ap);
160 return (EIO);
162 ap->ap_flags |= AP_F_CAM_ATTACHED;
164 ahci_cam_rescan(ap);
166 return(0);
169 void
170 ahci_cam_changed(struct ahci_port *ap, int found)
172 struct cam_path *tmppath;
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;
180 if (found) {
181 ahci_cam_probe(ap);
183 * XXX calling AC_FOUND_DEVICE with inquiry data is
184 * basically a NOP. For now just tell CAM to
185 * rescan the bus.
187 xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
188 ahci_cam_rescan(ap);
189 } else {
190 xpt_async(AC_LOST_DEVICE, tmppath, NULL);
192 xpt_free_path(tmppath);
195 void
196 ahci_cam_detach(struct ahci_port *ap)
198 int error;
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);
206 if (ap->ap_path) {
207 xpt_free_path(ap->ap_path);
208 ap->ap_path = NULL;
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;
215 if (ap->ap_sim) {
216 cam_sim_free(ap->ap_sim);
217 ap->ap_sim = NULL;
219 rel_mplock();
220 ap->ap_flags &= ~AP_F_CAM_ATTACHED;
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.
227 static int
228 ahci_cam_probe(struct ahci_port *ap)
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;
243 if (ap->ap_ata.ap_type == ATA_PORT_T_NONE)
244 return (EIO);
247 * Issue identify, saving the result
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";
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;
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);
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);
280 ahci_ata_put_xfer(xa);
282 ata_fix_identify(&ap->ap_ata.ap_identify);
285 * Read capacity using SATA probe info.
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]);
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]);
300 ap->ap_ata.ap_capacity = capacity;
301 ap->ap_ata.ap_features |= ATA_PORT_F_PROBED;
303 capacity_bytes = capacity * 512;
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.
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.
314 * Remember at least one extra CCB needs to be reserved for the
315 * error ccb.
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);
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);
336 } else {
337 devncqdepth = 0;
341 * Make the model string a bit more presentable
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;
352 * Generate informatiive strings.
354 * NOTE: We do not automatically set write caching, lookahead,
355 * or the security state for ATAPI devices.
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";
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";
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";
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,
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),
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
418 * Additional type-specific probing
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;
428 return (0);
432 * DISK-specific probe after initial ident
434 static int
435 ahci_cam_probe_disk(struct ahci_port *ap)
437 struct ata_xfer *xa;
438 int status;
441 * Enable write cache if supported
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.
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);
469 * Enable readahead if supported
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);
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
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);
510 return (0);
514 * ATAPI-specific probe after initial ident
516 static int
517 ahci_cam_probe_atapi(struct ahci_port *ap)
519 return(0);
522 #if 0
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
527 struct ata_xfer *xa;
528 int status;
529 int devncqdepth;
530 struct scsi_inquiry_data *inq_data;
531 struct scsi_inquiry *inq_cmd;
533 inq_data = kmalloc(sizeof(*inq_data), M_TEMP, M_WAITOK | M_ZERO);
536 * Issue identify, saving the result
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;
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;
555 inq_cmd = (void *)xa->packetcmd;
556 inq_cmd->opcode = INQUIRY;
557 inq_cmd->length = SHORT_INQUIRY_LENGTH;
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);
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);
575 ahci_ata_put_xfer(xa);
577 ap->ap_ata.ap_features |= ATA_PORT_F_PROBED;
580 * XXX Negotiate NCQ with ATAPI? How do we do this?
583 devncqdepth = 0;
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,
593 PORTNAME(ap),
594 devncqdepth, ap->ap_sc->sc_ncmds
596 kfree(inq_data, M_TEMP);
597 #endif
600 * Fix byte ordering so buffers can be accessed as
601 * strings.
603 static void
604 ata_fix_identify(struct ata_identify *id)
606 u_int16_t *swap;
607 int i;
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]);
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]);
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]);
623 * Dummy done callback for xa.
625 static void
626 ahci_ata_dummy_done(struct ata_xfer *xa)
631 * Initiate a bus scan.
633 * An asynchronous bus scan is used to avoid reentrancy issues
635 static void
636 ahci_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
638 kfree(ccb, M_TEMP);
641 static void
642 ahci_cam_rescan(struct ahci_port *ap)
644 struct cam_path *path;
645 union ccb *ccb;
646 int status;
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;
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);
660 /* scan is now underway */
664 * Action function - dispatch command
666 static
667 void
668 ahci_xpt_action(struct cam_sim *sim, union ccb *ccb)
670 struct ahci_port *ap;
671 struct ccb_hdr *ccbh;
672 int unit;
674 /* XXX lock */
675 ap = cam_sim_softc(sim);
676 KKASSERT(ap != NULL);
677 ccbh = &ccb->ccb_h;
678 unit = cam_sim_unit(sim);
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.
685 * XXX What do we do with a LUN wildcard?
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;
693 if (ccbh->target_id) {
694 ccbh->status = CAM_DEV_NOT_THERE;
695 xpt_done(ccb);
696 return;
698 if (ccbh->target_lun != CAM_LUN_WILDCARD && ccbh->target_lun) {
699 ccbh->status = CAM_DEV_NOT_THERE;
700 xpt_done(ccb);
701 return;
706 * Switch on the meta XPT command
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;
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.
734 * XXX What do we do with a LUN wildcard?
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;
750 /* XXX check attached, set base xfer speed */
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);
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);
769 xpt_async(AC_BUS_RESET, ap->ap_path, NULL);
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;
805 break;
806 default:
807 ccbh->status = CAM_REQ_INVALID;
808 xpt_done(ccb);
809 break;
814 * Poll function.
816 * Generally this function gets called heavily when interrupts might be
817 * non-operational, during a halt/reboot or panic.
819 static
820 void
821 ahci_xpt_poll(struct cam_sim *sim)
823 struct ahci_port *ap;
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();
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.
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.
842 static
843 void
844 ahci_xpt_scsi_disk_io(struct cam_sim *sim, union ccb *ccb)
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;
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;
866 * Build the FIS or process the csio to completion.
868 cdb = (void *)((ccbh->flags & CAM_CDB_POINTER) ?
869 csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
871 switch(cdb->generic.opcode) {
872 case REQUEST_SENSE:
874 * Auto-sense everything, so explicit sense requests
875 * return no-sense.
877 ccbh->status = CAM_SCSI_STATUS_ERROR;
878 break;
879 case INQUIRY:
881 * Inquiry supported features
883 * [opcode, byte2, page_code, length, control]
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;
897 } else {
898 bzero(rdata, rdata_len);
899 if (rdata_len < SHORT_INQUIRY_LENGTH) {
900 ccbh->status = CAM_CCB_LEN_ERR;
901 break;
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;
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;
924 if (rdata_len < sizeof(rdata->read_capacity_data_16)) {
925 ccbh->status = CAM_CCB_LEN_ERR;
926 break;
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;
935 capacity = ap->ap_ata.ap_capacity;
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);
953 ccbh->status = CAM_REQ_CMP;
954 break;
955 case SYNCHRONIZE_CACHE:
957 * Synchronize cache. Specification says this can take
958 * greater then 30 seconds so give it at least 45.
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:
974 * Just silently return success
976 ccbh->status = CAM_REQ_CMP;
977 rdata_len = 0;
978 break;
979 case ATA_PASS_12:
980 case ATA_PASS_16:
982 * XXX implement pass-through
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;
1032 if (ccbh->status != CAM_REQ_INPROG)
1033 break;
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;
1042 if (ap->ap_ata.ap_ncqdepth > 1 &&
1043 (ap->ap_sc->sc_cap & AHCI_REG_CAP_SNCQ) &&
1044 (ccbh->flags & CAM_POLLED) == 0) {
1046 * Use NCQ - always uses 48 bit addressing
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) {
1059 * Use LBA48
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 {
1070 * Use LBA
1072 * NOTE: 256 sectors is supported, stored as 0.
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;
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;
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.
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);
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.
1113 static
1114 void
1115 ahci_xpt_scsi_atapi_io(struct cam_sim *sim, union ccb *ccb)
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;
1126 ap = cam_sim_softc(sim);
1127 ccbh = &ccb->csio.ccb_h;
1128 csio = &ccb->csio;
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 */
1148 * The command has to fit in the packet command buffer.
1150 if (csio->cdb_len < 6 || csio->cdb_len > 16) {
1151 ccbh->status = CAM_CCB_LEN_ERR;
1152 xpt_done(ccb);
1153 return;
1157 * Initialize the XA and FIS.
1159 xa = ahci_ata_get_xfer(ap);
1160 fis = xa->fis;
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;
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;
1180 * Copy the cdb to the packetcmd buffer in the FIS using a
1181 * convenient pointer in the xa.
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);
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
1194 * Some ATAPI commands do not actually follow the SCSI standard.
1196 cdbd = (void *)xa->packetcmd;
1198 switch(cdbd->generic.opcode) {
1199 case INQUIRY:
1201 * Some ATAPI devices can't handle SI_EVPD being set
1202 * for a basic inquiry (page_code == 0).
1204 * Some ATAPI devices can't handle long inquiry lengths,
1205 * don't ask me why. Truncate the inquiry length.
1207 if ((cdbd->inquiry.byte2 & SI_EVPD) &&
1208 cdbd->inquiry.page_code == 0) {
1209 cdbd->inquiry.byte2 &= ~SI_EVPD;
1211 if (cdbd->inquiry.page_code == 0 &&
1212 cdbd->inquiry.length > SHORT_INQUIRY_LENGTH) {
1213 cdbd->inquiry.length = SHORT_INQUIRY_LENGTH;
1215 break;
1216 case READ_6:
1217 case WRITE_6:
1219 * Convert *_6 to *_10 commands. Most ATAPI devices
1220 * cannot handle the SCSI READ_6 and WRITE_6 commands.
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;
1238 * And dispatch
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);
1247 * Completion function for ATA_PORT_T_DISK cache synchronization.
1249 static
1250 void
1251 ahci_ata_complete_disk_synchronize_cache(struct ata_xfer *xa)
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;
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;
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);
1285 * Completion function for ATA_PORT_T_DISK I/O
1287 static
1288 void
1289 ahci_ata_complete_disk_rw(struct ata_xfer *xa)
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;
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;
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);
1324 * Completion function for ATA_PORT_T_ATAPI I/O
1326 * Sense data is returned in the rfis.
1328 static
1329 void
1330 ahci_atapi_complete_cmd(struct ata_xfer *xa)
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;
1337 cdb = (void *)((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
1338 ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes);
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;
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);
1371 * Construct dummy sense data for errors on DISKs
1373 static
1374 void
1375 ahci_ata_dummy_sense(struct scsi_sense_data *sense_data)
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;
1388 * Construct atapi sense data for errors on ATAPI
1390 * The ATAPI sense data is stored in the passed rfis and must be converted
1391 * to SCSI sense data.
1393 static
1394 void
1395 ahci_ata_atapi_sense(struct ata_fis_d2h *rfis,
1396 struct scsi_sense_data *sense_data)
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;