2 * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
32 #include <sys/endian.h>
33 #include <sys/systm.h>
34 #include <sys/types.h>
35 #include <sys/malloc.h>
36 #include <sys/kernel.h>
39 #include <sys/fcntl.h>
41 #include <sys/interrupt.h>
45 #include <sys/mutex.h>
46 #include <sys/sysctl.h>
49 #include <pc98/pc98/pc98_machdep.h> /* geometry translation */
53 #include <cam/cam_ccb.h>
54 #include <cam/cam_queue.h>
55 #include <cam/cam_periph.h>
56 #include <cam/cam_sim.h>
57 #include <cam/cam_xpt.h>
58 #include <cam/cam_xpt_sim.h>
59 #include <cam/cam_xpt_periph.h>
60 #include <cam/cam_xpt_internal.h>
61 #include <cam/cam_debug.h>
63 #include <cam/scsi/scsi_all.h>
64 #include <cam/scsi/scsi_message.h>
65 #include <cam/ata/ata_all.h>
66 #include <machine/stdarg.h> /* for xpt_print below */
69 struct scsi_quirk_entry {
70 struct scsi_inquiry_pattern inq_pat;
72 #define CAM_QUIRK_NOLUNS 0x01
73 #define CAM_QUIRK_NOSERIAL 0x02
74 #define CAM_QUIRK_HILUNS 0x04
75 #define CAM_QUIRK_NOHILUNS 0x08
79 #define SCSI_QUIRK(dev) ((struct scsi_quirk_entry *)((dev)->quirk))
81 static periph_init_t probe_periph_init;
83 static struct periph_driver probe_driver =
85 probe_periph_init, "aprobe",
86 TAILQ_HEAD_INITIALIZER(probe_driver.units)
89 PERIPHDRIVER_DECLARE(aprobe, probe_driver);
107 static char *probe_action_text[] = {
112 "PROBE_FULL_INQUIRY",
123 #define PROBE_SET_ACTION(softc, newaction) \
126 text = probe_action_text; \
127 CAM_DEBUG((softc)->periph->path, CAM_DEBUG_INFO, \
128 ("Probe %s to %s\n", text[(softc)->action], \
129 text[(newaction)])); \
130 (softc)->action = (newaction); \
134 PROBE_NO_ANNOUNCE = 0x04
138 TAILQ_HEAD(, ccb_hdr) request_ccbs;
148 struct cam_periph *periph;
151 static struct scsi_quirk_entry scsi_quirk_table[] =
154 /* Default tagged queuing parameters for all devices */
156 T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
157 /*vendor*/"*", /*product*/"*", /*revision*/"*"
159 /*quirks*/0, /*mintags*/2, /*maxtags*/32
163 static const int scsi_quirk_table_size =
164 sizeof(scsi_quirk_table) / sizeof(*scsi_quirk_table);
166 static cam_status proberegister(struct cam_periph *periph,
168 static void probeschedule(struct cam_periph *probe_periph);
169 static void probestart(struct cam_periph *periph, union ccb *start_ccb);
170 //static void proberequestdefaultnegotiation(struct cam_periph *periph);
171 //static int proberequestbackoff(struct cam_periph *periph,
172 // struct cam_ed *device);
173 static void probedone(struct cam_periph *periph, union ccb *done_ccb);
174 static void probecleanup(struct cam_periph *periph);
175 static void scsi_find_quirk(struct cam_ed *device);
176 static void ata_scan_bus(struct cam_periph *periph, union ccb *ccb);
177 static void ata_scan_lun(struct cam_periph *periph,
178 struct cam_path *path, cam_flags flags,
180 static void xptscandone(struct cam_periph *periph, union ccb *done_ccb);
181 static struct cam_ed *
182 ata_alloc_device(struct cam_eb *bus, struct cam_et *target,
184 static void ata_device_transport(struct cam_path *path);
185 static void scsi_set_transfer_settings(struct ccb_trans_settings *cts,
186 struct cam_ed *device,
188 static void scsi_toggle_tags(struct cam_path *path);
189 static void ata_dev_async(u_int32_t async_code,
191 struct cam_et *target,
192 struct cam_ed *device,
194 static void ata_action(union ccb *start_ccb);
196 static struct xpt_xport ata_xport = {
197 .alloc_device = ata_alloc_device,
198 .action = ata_action,
199 .async = ata_dev_async,
214 proberegister(struct cam_periph *periph, void *arg)
216 union ccb *request_ccb; /* CCB representing the probe request */
220 request_ccb = (union ccb *)arg;
221 if (periph == NULL) {
222 printf("proberegister: periph was NULL!!\n");
223 return(CAM_REQ_CMP_ERR);
226 if (request_ccb == NULL) {
227 printf("proberegister: no probe CCB, "
228 "can't register device\n");
229 return(CAM_REQ_CMP_ERR);
232 softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_NOWAIT);
235 printf("proberegister: Unable to probe new device. "
236 "Unable to allocate softc\n");
237 return(CAM_REQ_CMP_ERR);
239 TAILQ_INIT(&softc->request_ccbs);
240 TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
243 periph->softc = softc;
244 softc->periph = periph;
245 softc->action = PROBE_INVALID;
246 status = cam_periph_acquire(periph);
247 if (status != CAM_REQ_CMP) {
253 * Ensure we've waited at least a bus settle
254 * delay before attempting to probe the device.
255 * For HBAs that don't do bus resets, this won't make a difference.
257 cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset,
259 probeschedule(periph);
264 probeschedule(struct cam_periph *periph)
266 struct ccb_pathinq cpi;
270 softc = (probe_softc *)periph->softc;
271 ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
273 xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
274 cpi.ccb_h.func_code = XPT_PATH_INQ;
275 xpt_action((union ccb *)&cpi);
277 if (periph->path->device->flags & CAM_DEV_UNCONFIGURED)
278 PROBE_SET_ACTION(softc, PROBE_RESET);
279 else if (periph->path->device->protocol == PROTO_SATAPM)
280 PROBE_SET_ACTION(softc, PROBE_PM_PID);
282 PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
284 if (ccb->crcn.flags & CAM_EXPECT_INQ_CHANGE)
285 softc->flags |= PROBE_NO_ANNOUNCE;
287 softc->flags &= ~PROBE_NO_ANNOUNCE;
289 xpt_schedule(periph, ccb->ccb_h.pinfo.priority);
293 probestart(struct cam_periph *periph, union ccb *start_ccb)
295 /* Probe the device that our peripheral driver points to */
296 struct ccb_ataio *ataio;
297 struct ccb_scsiio *csio;
298 struct ccb_trans_settings cts;
301 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
303 softc = (probe_softc *)periph->softc;
304 ataio = &start_ccb->ataio;
305 csio = &start_ccb->csio;
307 switch (softc->action) {
309 if (start_ccb->ccb_h.target_id == 15) {
310 /* Report SIM that we have no knowledge about PM presence. */
311 bzero(&cts, sizeof(cts));
312 xpt_setup_ccb(&cts.ccb_h, start_ccb->ccb_h.path, 1);
313 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
314 cts.type = CTS_TYPE_CURRENT_SETTINGS;
315 cts.xport_specific.sata.pm_present = 0;
316 cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
317 xpt_action((union ccb *)&cts);
319 cam_fill_ataio(ataio,
322 /*flags*/CAM_DIR_NONE,
326 (start_ccb->ccb_h.target_id == 15 ? 3 : 15) * 1000);
327 ata_reset_cmd(ataio);
331 struct ata_params *ident_buf =
332 &periph->path->device->ident_data;
334 if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
335 /* Prepare check that it is the same device. */
340 (unsigned char *)ident_buf->model,
341 sizeof(ident_buf->model));
343 (unsigned char *)ident_buf->revision,
344 sizeof(ident_buf->revision));
346 (unsigned char *)ident_buf->serial,
347 sizeof(ident_buf->serial));
348 MD5Final(softc->digest, &context);
350 cam_fill_ataio(ataio,
355 /*data_ptr*/(u_int8_t *)ident_buf,
356 /*dxfer_len*/sizeof(struct ata_params),
358 if (periph->path->device->protocol == PROTO_ATA)
359 ata_28bit_cmd(ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
361 ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
366 struct ata_params *ident_buf =
367 &periph->path->device->ident_data;
369 cam_fill_ataio(ataio,
372 /*flags*/CAM_DIR_NONE,
377 ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
378 ata_max_mode(ident_buf, ATA_UDMA6, ATA_UDMA6));
382 case PROBE_FULL_INQUIRY:
385 struct scsi_inquiry_data *inq_buf =
386 &periph->path->device->inq_data;
388 if (softc->action == PROBE_INQUIRY)
389 inquiry_len = SHORT_INQUIRY_LENGTH;
391 inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf);
393 * Some parallel SCSI devices fail to send an
394 * ignore wide residue message when dealing with
395 * odd length inquiry requests. Round up to be
398 inquiry_len = roundup2(inquiry_len, 2);
408 /*timeout*/60 * 1000);
412 cam_fill_ataio(ataio,
415 /*flags*/CAM_DIR_NONE,
420 ata_pm_read_cmd(ataio, 0, 15);
423 cam_fill_ataio(ataio,
426 /*flags*/CAM_DIR_NONE,
431 ata_pm_read_cmd(ataio, 1, 15);
434 cam_fill_ataio(ataio,
437 /*flags*/CAM_DIR_NONE,
442 ata_pm_read_cmd(ataio, 2, 15);
446 struct ata_params *ident_buf =
447 &periph->path->device->ident_data;
448 cam_fill_ataio(ataio,
451 /*flags*/CAM_DIR_NONE,
456 ata_pm_write_cmd(ataio, 2, softc->pm_step,
457 (ident_buf->cylinders & (1 << softc->pm_step)) ? 0 : 1);
458 printf("PM RESET %d %04x %d\n", softc->pm_step, ident_buf->cylinders,
459 (ident_buf->cylinders & (1 << softc->pm_step)) ? 0 : 1);
462 case PROBE_PM_CONNECT:
463 cam_fill_ataio(ataio,
466 /*flags*/CAM_DIR_NONE,
471 ata_pm_write_cmd(ataio, 2, softc->pm_step, 0);
474 cam_fill_ataio(ataio,
477 /*flags*/CAM_DIR_NONE,
482 ata_pm_read_cmd(ataio, 0, softc->pm_step);
485 cam_fill_ataio(ataio,
488 /*flags*/CAM_DIR_NONE,
493 ata_pm_write_cmd(ataio, 1, softc->pm_step, 0xFFFFFFFF);
496 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
497 ("probestart: invalid action state\n"));
501 xpt_action(start_ccb);
505 proberequestdefaultnegotiation(struct cam_periph *periph)
507 struct ccb_trans_settings cts;
509 xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
510 cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
511 cts.type = CTS_TYPE_USER_SETTINGS;
512 xpt_action((union ccb *)&cts);
513 if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
516 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
517 cts.type = CTS_TYPE_CURRENT_SETTINGS;
518 xpt_action((union ccb *)&cts);
522 * Backoff Negotiation Code- only pertinent for SPI devices.
525 proberequestbackoff(struct cam_periph *periph, struct cam_ed *device)
527 struct ccb_trans_settings cts;
528 struct ccb_trans_settings_spi *spi;
530 memset(&cts, 0, sizeof (cts));
531 xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
532 cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
533 cts.type = CTS_TYPE_CURRENT_SETTINGS;
534 xpt_action((union ccb *)&cts);
535 if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
537 xpt_print(periph->path,
538 "failed to get current device settings\n");
542 if (cts.transport != XPORT_SPI) {
544 xpt_print(periph->path, "not SPI transport\n");
548 spi = &cts.xport_specific.spi;
551 * We cannot renegotiate sync rate if we don't have one.
553 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
555 xpt_print(periph->path, "no sync rate known\n");
561 * We'll assert that we don't have to touch PPR options- the
562 * SIM will see what we do with period and offset and adjust
563 * the PPR options as appropriate.
567 * A sync rate with unknown or zero offset is nonsensical.
568 * A sync period of zero means Async.
570 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0
571 || spi->sync_offset == 0 || spi->sync_period == 0) {
573 xpt_print(periph->path, "no sync rate available\n");
578 if (device->flags & CAM_DEV_DV_HIT_BOTTOM) {
579 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
580 ("hit async: giving up on DV\n"));
586 * Jump sync_period up by one, but stop at 5MHz and fall back to Async.
587 * We don't try to remember 'last' settings to see if the SIM actually
588 * gets into the speed we want to set. We check on the SIM telling
589 * us that a requested speed is bad, but otherwise don't try and
590 * check the speed due to the asynchronous and handshake nature
593 spi->valid = CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_SYNC_OFFSET;
596 if (spi->sync_period >= 0xf) {
597 spi->sync_period = 0;
598 spi->sync_offset = 0;
599 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
600 ("setting to async for DV\n"));
602 * Once we hit async, we don't want to try
605 device->flags |= CAM_DEV_DV_HIT_BOTTOM;
606 } else if (bootverbose) {
607 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
608 ("DV: period 0x%x\n", spi->sync_period));
609 printf("setting period to 0x%x\n", spi->sync_period);
611 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
612 cts.type = CTS_TYPE_CURRENT_SETTINGS;
613 xpt_action((union ccb *)&cts);
614 if ((cts.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
617 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
618 ("DV: failed to set period 0x%x\n", spi->sync_period));
619 if (spi->sync_period == 0) {
627 probedone(struct cam_periph *periph, union ccb *done_ccb)
629 struct ata_params *ident_buf;
631 struct cam_path *path;
635 CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
637 softc = (probe_softc *)periph->softc;
638 path = done_ccb->ccb_h.path;
639 priority = done_ccb->ccb_h.pinfo.priority;
640 ident_buf = &path->device->ident_data;
642 switch (softc->action) {
644 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
645 int sign = (done_ccb->ataio.res.lba_high << 8) +
646 done_ccb->ataio.res.lba_mid;
647 xpt_print(path, "SIGNATURE: %04x\n", sign);
648 if (sign == 0x0000 &&
649 done_ccb->ccb_h.target_id != 15) {
650 path->device->protocol = PROTO_ATA;
651 PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
652 } else if (sign == 0x9669 &&
653 done_ccb->ccb_h.target_id == 15) {
654 struct ccb_trans_settings cts;
656 /* Report SIM that PM is present. */
657 bzero(&cts, sizeof(cts));
658 xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
659 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
660 cts.type = CTS_TYPE_CURRENT_SETTINGS;
661 cts.xport_specific.sata.pm_present = 1;
662 cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
663 xpt_action((union ccb *)&cts);
664 path->device->protocol = PROTO_SATAPM;
665 PROBE_SET_ACTION(softc, PROBE_PM_PID);
666 } else if (sign == 0xeb14 &&
667 done_ccb->ccb_h.target_id != 15) {
668 path->device->protocol = PROTO_SCSI;
669 PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
671 if (done_ccb->ccb_h.target_id != 15) {
673 "Unexpected signature 0x%04x\n", sign);
675 xpt_release_ccb(done_ccb);
678 xpt_release_ccb(done_ccb);
679 xpt_schedule(periph, priority);
681 } else if (cam_periph_error(done_ccb, 0, 0,
682 &softc->saved_ccb) == ERESTART) {
684 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
685 /* Don't wedge the queue */
686 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
692 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
695 for (ptr = (int16_t *)ident_buf;
696 ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
697 *ptr = le16toh(*ptr);
699 if (strncmp(ident_buf->model, "FX", 2) &&
700 strncmp(ident_buf->model, "NEC", 3) &&
701 strncmp(ident_buf->model, "Pioneer", 7) &&
702 strncmp(ident_buf->model, "SHARP", 5)) {
703 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
704 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
705 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
707 ata_btrim(ident_buf->model, sizeof(ident_buf->model));
708 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
709 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
710 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
711 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
712 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
714 if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
715 /* Check that it is the same device. */
721 (unsigned char *)ident_buf->model,
722 sizeof(ident_buf->model));
724 (unsigned char *)ident_buf->revision,
725 sizeof(ident_buf->revision));
727 (unsigned char *)ident_buf->serial,
728 sizeof(ident_buf->serial));
729 MD5Final(digest, &context);
730 if (bcmp(digest, softc->digest, sizeof(digest))) {
731 /* Device changed. */
732 xpt_async(AC_LOST_DEVICE, path, NULL);
734 xpt_release_ccb(done_ccb);
738 /* Clean up from previous instance of this device */
739 if (path->device->serial_num != NULL) {
740 free(path->device->serial_num, M_CAMXPT);
741 path->device->serial_num = NULL;
742 path->device->serial_num_len = 0;
744 path->device->serial_num =
745 (u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
747 if (path->device->serial_num != NULL) {
748 bcopy(ident_buf->serial,
749 path->device->serial_num,
750 sizeof(ident_buf->serial));
751 path->device->serial_num[sizeof(ident_buf->serial)]
753 path->device->serial_num_len =
754 strlen(path->device->serial_num);
757 path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
758 ata_device_transport(path);
759 PROBE_SET_ACTION(softc, PROBE_SETMODE);
760 xpt_release_ccb(done_ccb);
761 xpt_schedule(periph, priority);
763 } else if (cam_periph_error(done_ccb, 0, 0,
764 &softc->saved_ccb) == ERESTART) {
766 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
767 /* Don't wedge the queue */
768 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
773 * If we get to this point, we got an error status back
774 * from the inquiry and the error status doesn't require
775 * automatically retrying the command. Therefore, the
776 * inquiry failed. If we had inquiry information before
777 * for this device, but this latest inquiry command failed,
778 * the device has probably gone away. If this device isn't
779 * already marked unconfigured, notify the peripheral
780 * drivers that this device is no more.
782 if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
783 /* Send the async notification. */
784 xpt_async(AC_LOST_DEVICE, path, NULL);
786 xpt_release_ccb(done_ccb);
791 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
792 modedone: if (path->device->protocol == PROTO_ATA) {
793 path->device->flags &= ~CAM_DEV_UNCONFIGURED;
794 done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
795 xpt_action(done_ccb);
796 xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
798 xpt_release_ccb(done_ccb);
801 PROBE_SET_ACTION(softc, PROBE_INQUIRY);
802 xpt_release_ccb(done_ccb);
803 xpt_schedule(periph, priority);
806 } else if (cam_periph_error(done_ccb, 0, 0,
807 &softc->saved_ccb) == ERESTART) {
809 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
810 /* Don't wedge the queue */
811 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
814 /* Old PIO2 devices may not support mode setting. */
815 if (ata_max_pmode(ident_buf) <= ATA_PIO2 &&
816 (ident_buf->capabilities1 & ATA_SUPPORT_IORDY) == 0)
821 case PROBE_FULL_INQUIRY:
823 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
824 struct scsi_inquiry_data *inq_buf;
825 u_int8_t periph_qual;
827 path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
828 inq_buf = &path->device->inq_data;
830 periph_qual = SID_QUAL(inq_buf);
832 if (periph_qual == SID_QUAL_LU_CONNECTED) {
836 * We conservatively request only
837 * SHORT_INQUIRY_LEN bytes of inquiry
838 * information during our first try
839 * at sending an INQUIRY. If the device
840 * has more information to give,
841 * perform a second request specifying
842 * the amount of information the device
843 * is willing to give.
845 len = inq_buf->additional_length
846 + offsetof(struct scsi_inquiry_data,
847 additional_length) + 1;
848 if (softc->action == PROBE_INQUIRY
849 && len > SHORT_INQUIRY_LENGTH) {
850 PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
851 xpt_release_ccb(done_ccb);
852 xpt_schedule(periph, priority);
856 scsi_find_quirk(path->device);
857 ata_device_transport(path);
858 path->device->flags &= ~CAM_DEV_UNCONFIGURED;
859 done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
860 xpt_action(done_ccb);
861 xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
863 xpt_release_ccb(done_ccb);
866 } else if (cam_periph_error(done_ccb, 0, 0,
867 &softc->saved_ccb) == ERESTART) {
869 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
870 /* Don't wedge the queue */
871 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
877 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
878 if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) == 0)
879 bzero(ident_buf, sizeof(*ident_buf));
880 softc->pm_pid = (done_ccb->ataio.res.lba_high << 24) +
881 (done_ccb->ataio.res.lba_mid << 16) +
882 (done_ccb->ataio.res.lba_low << 8) +
883 done_ccb->ataio.res.sector_count;
884 printf("PM Product ID: %08x\n", softc->pm_pid);
885 snprintf(ident_buf->model, sizeof(ident_buf->model),
886 "Port Multiplier %08x", softc->pm_pid);
887 PROBE_SET_ACTION(softc, PROBE_PM_PRV);
888 xpt_release_ccb(done_ccb);
889 xpt_schedule(periph, priority);
891 } else if (cam_periph_error(done_ccb, 0, 0,
892 &softc->saved_ccb) == ERESTART) {
894 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
895 /* Don't wedge the queue */
896 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
901 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
902 softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) +
903 (done_ccb->ataio.res.lba_mid << 16) +
904 (done_ccb->ataio.res.lba_low << 8) +
905 done_ccb->ataio.res.sector_count;
906 printf("PM Revision: %08x\n", softc->pm_prv);
907 snprintf(ident_buf->revision, sizeof(ident_buf->revision),
908 "%04x", softc->pm_prv);
909 PROBE_SET_ACTION(softc, PROBE_PM_PORTS);
910 xpt_release_ccb(done_ccb);
911 xpt_schedule(periph, priority);
913 } else if (cam_periph_error(done_ccb, 0, 0,
914 &softc->saved_ccb) == ERESTART) {
916 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
917 /* Don't wedge the queue */
918 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
923 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
924 softc->pm_ports = (done_ccb->ataio.res.lba_high << 24) +
925 (done_ccb->ataio.res.lba_mid << 16) +
926 (done_ccb->ataio.res.lba_low << 8) +
927 done_ccb->ataio.res.sector_count;
928 /* This PM declares 6 ports, while only 5 of them are real.
929 * Port 5 is enclosure management bridge port, which has implementation
930 * problems, causing probe faults. Hide it for now. */
931 if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
933 /* This PM declares 7 ports, while only 5 of them are real.
934 * Port 5 is some fake "Config Disk" with 640 sectors size,
935 * port 6 is enclosure management bridge port.
936 * Both fake ports has implementation problems, causing
937 * probe faults. Hide them for now. */
938 if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
940 printf("PM ports: %d\n", softc->pm_ports);
941 ident_buf->config = softc->pm_ports;
942 path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
944 PROBE_SET_ACTION(softc, PROBE_PM_RESET);
945 xpt_release_ccb(done_ccb);
946 xpt_schedule(periph, priority);
948 } else if (cam_periph_error(done_ccb, 0, 0,
949 &softc->saved_ccb) == ERESTART) {
951 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
952 /* Don't wedge the queue */
953 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
958 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
960 if (softc->pm_step < softc->pm_ports) {
961 xpt_release_ccb(done_ccb);
962 xpt_schedule(periph, priority);
967 printf("PM reset done\n");
968 PROBE_SET_ACTION(softc, PROBE_PM_CONNECT);
969 xpt_release_ccb(done_ccb);
970 xpt_schedule(periph, priority);
973 } else if (cam_periph_error(done_ccb, 0, 0,
974 &softc->saved_ccb) == ERESTART) {
976 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
977 /* Don't wedge the queue */
978 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
982 case PROBE_PM_CONNECT:
983 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
985 if (softc->pm_step < softc->pm_ports) {
986 xpt_release_ccb(done_ccb);
987 xpt_schedule(periph, priority);
992 printf("PM connect done\n");
993 PROBE_SET_ACTION(softc, PROBE_PM_CHECK);
994 xpt_release_ccb(done_ccb);
995 xpt_schedule(periph, priority);
998 } else if (cam_periph_error(done_ccb, 0, 0,
999 &softc->saved_ccb) == ERESTART) {
1001 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1002 /* Don't wedge the queue */
1003 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
1007 case PROBE_PM_CHECK:
1008 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1009 int res = (done_ccb->ataio.res.lba_high << 24) +
1010 (done_ccb->ataio.res.lba_mid << 16) +
1011 (done_ccb->ataio.res.lba_low << 8) +
1012 done_ccb->ataio.res.sector_count;
1013 if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) {
1014 printf("PM status: %d - %08x\n", softc->pm_step, res);
1015 ident_buf->cylinders |= (1 << softc->pm_step);
1018 if (softc->pm_try < 100) {
1022 printf("PM status: %d - %08x\n", softc->pm_step, res);
1023 ident_buf->cylinders &= ~(1 << softc->pm_step);
1027 if (softc->pm_step < softc->pm_ports) {
1028 xpt_release_ccb(done_ccb);
1029 xpt_schedule(periph, priority);
1033 PROBE_SET_ACTION(softc, PROBE_PM_CLEAR);
1034 xpt_release_ccb(done_ccb);
1035 xpt_schedule(periph, priority);
1038 } else if (cam_periph_error(done_ccb, 0, 0,
1039 &softc->saved_ccb) == ERESTART) {
1041 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1042 /* Don't wedge the queue */
1043 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
1047 case PROBE_PM_CLEAR:
1048 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1050 if (softc->pm_step < softc->pm_ports) {
1051 xpt_release_ccb(done_ccb);
1052 xpt_schedule(periph, priority);
1055 found = ident_buf->cylinders | 0x8000;
1056 if (path->device->flags & CAM_DEV_UNCONFIGURED) {
1057 path->device->flags &= ~CAM_DEV_UNCONFIGURED;
1058 done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
1059 xpt_action(done_ccb);
1060 xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
1062 xpt_release_ccb(done_ccb);
1065 } else if (cam_periph_error(done_ccb, 0, 0,
1066 &softc->saved_ccb) == ERESTART) {
1068 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1069 /* Don't wedge the queue */
1070 xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
1075 CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_INFO,
1076 ("probedone: invalid action state\n"));
1080 done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
1081 TAILQ_REMOVE(&softc->request_ccbs, &done_ccb->ccb_h, periph_links.tqe);
1082 done_ccb->ccb_h.status = CAM_REQ_CMP;
1083 done_ccb->ccb_h.ppriv_field1 = found;
1085 if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
1086 cam_periph_invalidate(periph);
1087 cam_periph_release_locked(periph);
1089 probeschedule(periph);
1094 probecleanup(struct cam_periph *periph)
1096 free(periph->softc, M_CAMXPT);
1100 scsi_find_quirk(struct cam_ed *device)
1102 struct scsi_quirk_entry *quirk;
1105 match = cam_quirkmatch((caddr_t)&device->inq_data,
1106 (caddr_t)scsi_quirk_table,
1107 sizeof(scsi_quirk_table) /
1108 sizeof(*scsi_quirk_table),
1109 sizeof(*scsi_quirk_table), scsi_inquiry_match);
1112 panic("xpt_find_quirk: device didn't match wildcard entry!!");
1114 quirk = (struct scsi_quirk_entry *)match;
1115 device->quirk = quirk;
1116 device->mintags = quirk->mintags;
1117 device->maxtags = quirk->maxtags;
1121 union ccb *request_ccb;
1122 struct ccb_pathinq *cpi;
1125 } ata_scan_bus_info;
1128 * To start a scan, request_ccb is an XPT_SCAN_BUS ccb.
1129 * As the scan progresses, xpt_scan_bus is used as the
1130 * callback on completion function.
1133 ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
1135 struct cam_path *path;
1136 ata_scan_bus_info *scan_info;
1137 union ccb *work_ccb;
1140 CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
1141 ("xpt_scan_bus\n"));
1142 switch (request_ccb->ccb_h.func_code) {
1144 /* Find out the characteristics of the bus */
1145 work_ccb = xpt_alloc_ccb_nowait();
1146 if (work_ccb == NULL) {
1147 request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1148 xpt_done(request_ccb);
1151 xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path,
1152 request_ccb->ccb_h.pinfo.priority);
1153 work_ccb->ccb_h.func_code = XPT_PATH_INQ;
1154 xpt_action(work_ccb);
1155 if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
1156 request_ccb->ccb_h.status = work_ccb->ccb_h.status;
1157 xpt_free_ccb(work_ccb);
1158 xpt_done(request_ccb);
1162 /* Save some state for use while we probe for devices */
1163 scan_info = (ata_scan_bus_info *)
1164 malloc(sizeof(ata_scan_bus_info), M_CAMXPT, M_NOWAIT);
1165 if (scan_info == NULL) {
1166 request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1167 xpt_done(request_ccb);
1170 scan_info->request_ccb = request_ccb;
1171 scan_info->cpi = &work_ccb->cpi;
1172 if (scan_info->cpi->transport == XPORT_ATA)
1173 scan_info->found = 0x0003;
1175 scan_info->found = 0x8001;
1176 scan_info->counter = 0;
1177 /* If PM supported, probe it first. */
1178 if (scan_info->cpi->hba_inquiry & PI_SATAPM)
1179 scan_info->counter = 15;
1181 work_ccb = xpt_alloc_ccb_nowait();
1182 if (work_ccb == NULL) {
1183 free(scan_info, M_CAMXPT);
1184 request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1185 xpt_done(request_ccb);
1190 work_ccb = request_ccb;
1191 /* Reuse the same CCB to query if a device was really found */
1192 scan_info = (ata_scan_bus_info *)work_ccb->ccb_h.ppriv_ptr0;
1193 /* Free the current request path- we're done with it. */
1194 xpt_free_path(work_ccb->ccb_h.path);
1195 /* If there is PM... */
1196 if (scan_info->counter == 15) {
1197 if (work_ccb->ccb_h.ppriv_field1 != 0) {
1198 /* Save PM probe result. */
1199 scan_info->found = work_ccb->ccb_h.ppriv_field1;
1201 struct ccb_trans_settings cts;
1203 /* Report SIM that PM is absent. */
1204 bzero(&cts, sizeof(cts));
1205 xpt_setup_ccb(&cts.ccb_h,
1206 scan_info->request_ccb->ccb_h.path, 1);
1207 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
1208 cts.type = CTS_TYPE_CURRENT_SETTINGS;
1209 cts.xport_specific.sata.pm_present = 0;
1210 cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
1211 xpt_action((union ccb *)&cts);
1215 /* Take next device. Wrap from 15 (PM) to 0. */
1216 scan_info->counter = (scan_info->counter + 1 ) & 0x0f;
1217 if (scan_info->counter > scan_info->cpi->max_target -
1218 ((scan_info->cpi->hba_inquiry & PI_SATAPM) ? 1 : 0)) {
1219 xpt_free_ccb(work_ccb);
1220 xpt_free_ccb((union ccb *)scan_info->cpi);
1221 request_ccb = scan_info->request_ccb;
1222 free(scan_info, M_CAMXPT);
1223 request_ccb->ccb_h.status = CAM_REQ_CMP;
1224 xpt_done(request_ccb);
1228 status = xpt_create_path(&path, xpt_periph,
1229 scan_info->request_ccb->ccb_h.path_id,
1230 scan_info->counter, 0);
1231 if (status != CAM_REQ_CMP) {
1232 printf("xpt_scan_bus: xpt_create_path failed"
1233 " with status %#x, bus scan halted\n",
1235 xpt_free_ccb(work_ccb);
1236 xpt_free_ccb((union ccb *)scan_info->cpi);
1237 request_ccb = scan_info->request_ccb;
1238 free(scan_info, M_CAMXPT);
1239 request_ccb->ccb_h.status = status;
1240 xpt_done(request_ccb);
1243 if ((scan_info->found & (1 << scan_info->counter)) == 0) {
1244 xpt_async(AC_LOST_DEVICE, path, NULL);
1245 xpt_free_path(path);
1248 xpt_setup_ccb(&work_ccb->ccb_h, path,
1249 scan_info->request_ccb->ccb_h.pinfo.priority);
1250 work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
1251 work_ccb->ccb_h.cbfcnp = ata_scan_bus;
1252 work_ccb->ccb_h.ppriv_ptr0 = scan_info;
1253 work_ccb->crcn.flags = scan_info->request_ccb->crcn.flags;
1254 xpt_action(work_ccb);
1262 ata_scan_lun(struct cam_periph *periph, struct cam_path *path,
1263 cam_flags flags, union ccb *request_ccb)
1265 struct ccb_pathinq cpi;
1267 struct cam_path *new_path;
1268 struct cam_periph *old_periph;
1270 CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
1271 ("xpt_scan_lun\n"));
1273 xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
1274 cpi.ccb_h.func_code = XPT_PATH_INQ;
1275 xpt_action((union ccb *)&cpi);
1277 if (cpi.ccb_h.status != CAM_REQ_CMP) {
1278 if (request_ccb != NULL) {
1279 request_ccb->ccb_h.status = cpi.ccb_h.status;
1280 xpt_done(request_ccb);
1285 if (request_ccb == NULL) {
1286 request_ccb = malloc(sizeof(union ccb), M_CAMXPT, M_NOWAIT);
1287 if (request_ccb == NULL) {
1288 xpt_print(path, "xpt_scan_lun: can't allocate CCB, "
1289 "can't continue\n");
1292 new_path = malloc(sizeof(*new_path), M_CAMXPT, M_NOWAIT);
1293 if (new_path == NULL) {
1294 xpt_print(path, "xpt_scan_lun: can't allocate path, "
1295 "can't continue\n");
1296 free(request_ccb, M_CAMXPT);
1299 status = xpt_compile_path(new_path, xpt_periph,
1301 path->target->target_id,
1302 path->device->lun_id);
1304 if (status != CAM_REQ_CMP) {
1305 xpt_print(path, "xpt_scan_lun: can't compile path, "
1306 "can't continue\n");
1307 free(request_ccb, M_CAMXPT);
1308 free(new_path, M_CAMXPT);
1311 xpt_setup_ccb(&request_ccb->ccb_h, new_path, CAM_PRIORITY_NORMAL);
1312 request_ccb->ccb_h.cbfcnp = xptscandone;
1313 request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
1314 request_ccb->crcn.flags = flags;
1317 if ((old_periph = cam_periph_find(path, "aprobe")) != NULL) {
1320 softc = (probe_softc *)old_periph->softc;
1321 TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
1324 status = cam_periph_alloc(proberegister, NULL, probecleanup,
1325 probestart, "aprobe",
1327 request_ccb->ccb_h.path, NULL, 0,
1330 if (status != CAM_REQ_CMP) {
1331 xpt_print(path, "xpt_scan_lun: cam_alloc_periph "
1332 "returned an error, can't continue probe\n");
1333 request_ccb->ccb_h.status = status;
1334 xpt_done(request_ccb);
1340 xptscandone(struct cam_periph *periph, union ccb *done_ccb)
1342 xpt_release_path(done_ccb->ccb_h.path);
1343 free(done_ccb->ccb_h.path, M_CAMXPT);
1344 free(done_ccb, M_CAMXPT);
1347 static struct cam_ed *
1348 ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
1350 struct cam_path path;
1351 struct scsi_quirk_entry *quirk;
1352 struct cam_ed *device;
1353 struct cam_ed *cur_device;
1355 device = xpt_alloc_device(bus, target, lun_id);
1360 * Take the default quirk entry until we have inquiry
1361 * data and can determine a better quirk to use.
1363 quirk = &scsi_quirk_table[scsi_quirk_table_size - 1];
1364 device->quirk = (void *)quirk;
1365 device->mintags = quirk->mintags;
1366 device->maxtags = quirk->maxtags;
1367 bzero(&device->inq_data, sizeof(device->inq_data));
1368 device->inq_flags = 0;
1369 device->queue_flags = 0;
1370 device->serial_num = NULL;
1371 device->serial_num_len = 0;
1374 * XXX should be limited by number of CCBs this bus can
1377 bus->sim->max_ccbs += device->ccbq.devq_openings;
1378 /* Insertion sort into our target's device list */
1379 cur_device = TAILQ_FIRST(&target->ed_entries);
1380 while (cur_device != NULL && cur_device->lun_id < lun_id)
1381 cur_device = TAILQ_NEXT(cur_device, links);
1382 if (cur_device != NULL) {
1383 TAILQ_INSERT_BEFORE(cur_device, device, links);
1385 TAILQ_INSERT_TAIL(&target->ed_entries, device, links);
1387 target->generation++;
1388 if (lun_id != CAM_LUN_WILDCARD) {
1389 xpt_compile_path(&path,
1394 ata_device_transport(&path);
1395 xpt_release_path(&path);
1402 ata_device_transport(struct cam_path *path)
1404 struct ccb_pathinq cpi;
1405 struct ccb_trans_settings cts;
1406 struct scsi_inquiry_data *inq_buf = NULL;
1407 struct ata_params *ident_buf = NULL;
1409 /* Get transport information from the SIM */
1410 xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
1411 cpi.ccb_h.func_code = XPT_PATH_INQ;
1412 xpt_action((union ccb *)&cpi);
1414 path->device->transport = cpi.transport;
1415 if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0)
1416 inq_buf = &path->device->inq_data;
1417 if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) != 0)
1418 ident_buf = &path->device->ident_data;
1419 if (path->device->protocol == PROTO_ATA) {
1420 path->device->protocol_version = ident_buf ?
1421 ata_version(ident_buf->version_major) : cpi.protocol_version;
1422 } else if (path->device->protocol == PROTO_SCSI) {
1423 path->device->protocol_version = inq_buf ?
1424 SID_ANSI_REV(inq_buf) : cpi.protocol_version;
1426 path->device->transport_version = ident_buf ?
1427 ata_version(ident_buf->version_major) : cpi.transport_version;
1429 /* Tell the controller what we think */
1430 xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
1431 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
1432 cts.type = CTS_TYPE_CURRENT_SETTINGS;
1433 cts.transport = path->device->transport;
1434 cts.transport_version = path->device->transport_version;
1435 cts.protocol = path->device->protocol;
1436 cts.protocol_version = path->device->protocol_version;
1437 cts.proto_specific.valid = 0;
1438 cts.xport_specific.valid = 0;
1439 xpt_action((union ccb *)&cts);
1443 ata_action(union ccb *start_ccb)
1446 switch (start_ccb->ccb_h.func_code) {
1447 case XPT_SET_TRAN_SETTINGS:
1449 scsi_set_transfer_settings(&start_ccb->cts,
1450 start_ccb->ccb_h.path->device,
1451 /*async_update*/FALSE);
1455 ata_scan_bus(start_ccb->ccb_h.path->periph, start_ccb);
1458 ata_scan_lun(start_ccb->ccb_h.path->periph,
1459 start_ccb->ccb_h.path, start_ccb->crcn.flags,
1462 case XPT_GET_TRAN_SETTINGS:
1464 struct cam_sim *sim;
1466 sim = start_ccb->ccb_h.path->bus->sim;
1467 (*(sim->sim_action))(sim, start_ccb);
1471 xpt_action_default(start_ccb);
1477 scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device,
1480 struct ccb_pathinq cpi;
1481 struct ccb_trans_settings cur_cts;
1482 struct ccb_trans_settings_scsi *scsi;
1483 struct ccb_trans_settings_scsi *cur_scsi;
1484 struct cam_sim *sim;
1485 struct scsi_inquiry_data *inq_data;
1487 if (device == NULL) {
1488 cts->ccb_h.status = CAM_PATH_INVALID;
1489 xpt_done((union ccb *)cts);
1493 if (cts->protocol == PROTO_UNKNOWN
1494 || cts->protocol == PROTO_UNSPECIFIED) {
1495 cts->protocol = device->protocol;
1496 cts->protocol_version = device->protocol_version;
1499 if (cts->protocol_version == PROTO_VERSION_UNKNOWN
1500 || cts->protocol_version == PROTO_VERSION_UNSPECIFIED)
1501 cts->protocol_version = device->protocol_version;
1503 if (cts->protocol != device->protocol) {
1504 xpt_print(cts->ccb_h.path, "Uninitialized Protocol %x:%x?\n",
1505 cts->protocol, device->protocol);
1506 cts->protocol = device->protocol;
1509 if (cts->protocol_version > device->protocol_version) {
1511 xpt_print(cts->ccb_h.path, "Down reving Protocol "
1512 "Version from %d to %d?\n", cts->protocol_version,
1513 device->protocol_version);
1515 cts->protocol_version = device->protocol_version;
1518 if (cts->transport == XPORT_UNKNOWN
1519 || cts->transport == XPORT_UNSPECIFIED) {
1520 cts->transport = device->transport;
1521 cts->transport_version = device->transport_version;
1524 if (cts->transport_version == XPORT_VERSION_UNKNOWN
1525 || cts->transport_version == XPORT_VERSION_UNSPECIFIED)
1526 cts->transport_version = device->transport_version;
1528 if (cts->transport != device->transport) {
1529 xpt_print(cts->ccb_h.path, "Uninitialized Transport %x:%x?\n",
1530 cts->transport, device->transport);
1531 cts->transport = device->transport;
1534 if (cts->transport_version > device->transport_version) {
1536 xpt_print(cts->ccb_h.path, "Down reving Transport "
1537 "Version from %d to %d?\n", cts->transport_version,
1538 device->transport_version);
1540 cts->transport_version = device->transport_version;
1543 sim = cts->ccb_h.path->bus->sim;
1546 * Nothing more of interest to do unless
1547 * this is a device connected via the
1550 if (cts->protocol != PROTO_SCSI) {
1551 if (async_update == FALSE)
1552 (*(sim->sim_action))(sim, (union ccb *)cts);
1556 inq_data = &device->inq_data;
1557 scsi = &cts->proto_specific.scsi;
1558 xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NORMAL);
1559 cpi.ccb_h.func_code = XPT_PATH_INQ;
1560 xpt_action((union ccb *)&cpi);
1562 /* SCSI specific sanity checking */
1563 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0
1564 || (INQ_DATA_TQ_ENABLED(inq_data)) == 0
1565 || (device->queue_flags & SCP_QUEUE_DQUE) != 0
1566 || (device->mintags == 0)) {
1568 * Can't tag on hardware that doesn't support tags,
1569 * doesn't have it enabled, or has broken tag support.
1571 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1574 if (async_update == FALSE) {
1576 * Perform sanity checking against what the
1577 * controller and device can do.
1579 xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NORMAL);
1580 cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1581 cur_cts.type = cts->type;
1582 xpt_action((union ccb *)&cur_cts);
1583 if ((cur_cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1586 cur_scsi = &cur_cts.proto_specific.scsi;
1587 if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) {
1588 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1589 scsi->flags |= cur_scsi->flags & CTS_SCSI_FLAGS_TAG_ENB;
1591 if ((cur_scsi->valid & CTS_SCSI_VALID_TQ) == 0)
1592 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1595 if (cts->type == CTS_TYPE_CURRENT_SETTINGS
1596 && (scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
1600 * If we are transitioning from tags to no-tags or
1601 * vice-versa, we need to carefully freeze and restart
1602 * the queue so that we don't overlap tagged and non-tagged
1603 * commands. We also temporarily stop tags if there is
1604 * a change in transfer negotiation settings to allow
1605 * "tag-less" negotiation.
1607 if ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
1608 || (device->inq_flags & SID_CmdQue) != 0)
1609 device_tagenb = TRUE;
1611 device_tagenb = FALSE;
1613 if (((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0
1614 && device_tagenb == FALSE)
1615 || ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) == 0
1616 && device_tagenb == TRUE)) {
1618 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
1620 * Delay change to use tags until after a
1621 * few commands have gone to this device so
1622 * the controller has time to perform transfer
1623 * negotiations without tagged messages getting
1626 device->tag_delay_count = CAM_TAG_DELAY_COUNT;
1627 device->flags |= CAM_DEV_TAG_AFTER_COUNT;
1629 struct ccb_relsim crs;
1631 xpt_freeze_devq(cts->ccb_h.path, /*count*/1);
1632 device->inq_flags &= ~SID_CmdQue;
1633 xpt_dev_ccbq_resize(cts->ccb_h.path,
1634 sim->max_dev_openings);
1635 device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
1636 device->tag_delay_count = 0;
1638 xpt_setup_ccb(&crs.ccb_h, cts->ccb_h.path,
1639 CAM_PRIORITY_NORMAL);
1640 crs.ccb_h.func_code = XPT_REL_SIMQ;
1641 crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
1643 = crs.release_timeout
1646 xpt_action((union ccb *)&crs);
1650 if (async_update == FALSE)
1651 (*(sim->sim_action))(sim, (union ccb *)cts);
1655 scsi_toggle_tags(struct cam_path *path)
1660 * Give controllers a chance to renegotiate
1661 * before starting tag operations. We
1662 * "toggle" tagged queuing off then on
1663 * which causes the tag enable command delay
1664 * counter to come into effect.
1667 if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
1668 || ((dev->inq_flags & SID_CmdQue) != 0
1669 && (dev->inq_flags & (SID_Sync|SID_WBus16|SID_WBus32)) != 0)) {
1670 struct ccb_trans_settings cts;
1672 xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
1673 cts.protocol = PROTO_SCSI;
1674 cts.protocol_version = PROTO_VERSION_UNSPECIFIED;
1675 cts.transport = XPORT_UNSPECIFIED;
1676 cts.transport_version = XPORT_VERSION_UNSPECIFIED;
1677 cts.proto_specific.scsi.flags = 0;
1678 cts.proto_specific.scsi.valid = CTS_SCSI_VALID_TQ;
1679 scsi_set_transfer_settings(&cts, path->device,
1680 /*async_update*/TRUE);
1681 cts.proto_specific.scsi.flags = CTS_SCSI_FLAGS_TAG_ENB;
1682 scsi_set_transfer_settings(&cts, path->device,
1683 /*async_update*/TRUE);
1688 * Handle any per-device event notifications that require action by the XPT.
1691 ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
1692 struct cam_ed *device, void *async_arg)
1695 struct cam_path newpath;
1698 * We only need to handle events for real devices.
1700 if (target->target_id == CAM_TARGET_WILDCARD
1701 || device->lun_id == CAM_LUN_WILDCARD)
1705 * We need our own path with wildcards expanded to
1706 * handle certain types of events.
1708 if ((async_code == AC_SENT_BDR)
1709 || (async_code == AC_BUS_RESET)
1710 || (async_code == AC_INQ_CHANGED))
1711 status = xpt_compile_path(&newpath, NULL,
1716 status = CAM_REQ_CMP_ERR;
1718 if (status == CAM_REQ_CMP) {
1721 * Allow transfer negotiation to occur in a
1722 * tag free environment.
1724 if (async_code == AC_SENT_BDR
1725 || async_code == AC_BUS_RESET)
1726 scsi_toggle_tags(&newpath);
1728 if (async_code == AC_INQ_CHANGED) {
1730 * We've sent a start unit command, or
1731 * something similar to a device that
1732 * may have caused its inquiry data to
1733 * change. So we re-scan the device to
1734 * refresh the inquiry data for it.
1736 ata_scan_lun(newpath.periph, &newpath,
1737 CAM_EXPECT_INQ_CHANGE, NULL);
1739 xpt_release_path(&newpath);
1740 } else if (async_code == AC_LOST_DEVICE) {
1741 device->flags |= CAM_DEV_UNCONFIGURED;
1742 } else if (async_code == AC_TRANSFER_NEG) {
1743 struct ccb_trans_settings *settings;
1745 settings = (struct ccb_trans_settings *)async_arg;
1746 scsi_set_transfer_settings(settings, device,
1747 /*async_update*/TRUE);