diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/atascsi.c | 72 |
1 files changed, 40 insertions, 32 deletions
diff --git a/sys/dev/ata/atascsi.c b/sys/dev/ata/atascsi.c index 33eb01a3005..b8ae4c31d84 100644 --- a/sys/dev/ata/atascsi.c +++ b/sys/dev/ata/atascsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atascsi.c,v 1.82 2010/04/23 01:39:05 dlg Exp $ */ +/* $OpenBSD: atascsi.c,v 1.83 2010/04/29 22:28:39 krw Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -55,6 +55,8 @@ struct atascsi_port { struct atascsi *ap_as; int ap_port; int ap_type; + int ap_features; +#define ATA_PORT_F_PROBED 1 int ap_ncqdepth; }; @@ -244,36 +246,6 @@ atascsi_probe(struct scsi_link *link) as->as_ports[port] = ap; - if (as->as_capability & ASAA_CAP_NCQ && - (letoh16(ap->ap_identify.satacap) & (1 << 8))) { - int host_ncqdepth; - /* - * At this point, openings should be the number of commands the - * host controller supports, less any reserved slot the host - * controller needs for recovery. - */ - host_ncqdepth = link->openings + - ((as->as_capability & ASAA_CAP_NEEDS_RESERVED) ? 1 : 0); - - ap->ap_ncqdepth = (letoh16(ap->ap_identify.qdepth) & 0x1f) + 1; - - /* Limit the number of openings to what the device supports. */ - if (host_ncqdepth > ap->ap_ncqdepth) - link->openings -= (host_ncqdepth - ap->ap_ncqdepth); - - /* - * XXX throw away any xfers that have tag numbers higher than - * what the device supports. - */ - while (host_ncqdepth--) { - xa = scsi_io_get(&ap->ap_iopool, SCSI_NOSLEEP); - if (xa->tag < ap->ap_ncqdepth) { - xa->state = ATA_S_COMPLETE; - scsi_io_put(&ap->ap_iopool, xa); - } - } - } - if (type != ATA_PORT_T_DISK) return (0); @@ -566,10 +538,11 @@ atascsi_disk_inq(struct scsi_xfer *xs) void atascsi_disk_inquiry(struct scsi_xfer *xs) { + struct scsi_inquiry_data inq; struct scsi_link *link = xs->sc_link; struct atascsi *as = link->adapter_softc; struct atascsi_port *ap = as->as_ports[link->target]; - struct scsi_inquiry_data inq; + struct ata_xfer *xa; bzero(&inq, sizeof(inq)); @@ -586,6 +559,41 @@ atascsi_disk_inquiry(struct scsi_xfer *xs) bcopy(&inq, xs->data, MIN(sizeof(inq), xs->datalen)); atascsi_done(xs, XS_NOERROR); + + if (ap->ap_features & ATA_PORT_F_PROBED) + return; + + ap->ap_features = ATA_PORT_F_PROBED; + + if (as->as_capability & ASAA_CAP_NCQ && + (letoh16(ap->ap_identify.satacap) & (1 << 8))) { + int host_ncqdepth; + /* + * At this point, openings should be the number of commands the + * host controller supports, less any reserved slot the host + * controller needs for recovery. + */ + host_ncqdepth = link->openings + + ((as->as_capability & ASAA_CAP_NEEDS_RESERVED) ? 1 : 0); + + ap->ap_ncqdepth = (letoh16(ap->ap_identify.qdepth) & 0x1f) + 1; + + /* Limit the number of openings to what the device supports. */ + if (host_ncqdepth > ap->ap_ncqdepth) + link->openings -= (host_ncqdepth - ap->ap_ncqdepth); + + /* + * XXX throw away any xfers that have tag numbers higher than + * what the device supports. + */ + while (host_ncqdepth--) { + xa = scsi_io_get(&ap->ap_iopool, SCSI_NOSLEEP); + if (xa->tag < ap->ap_ncqdepth) { + xa->state = ATA_S_COMPLETE; + scsi_io_put(&ap->ap_iopool, xa); + } + } + } } void |