[BACK]Return to scsiconf.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / scsipi

Annotation of src/sys/dev/scsipi/scsiconf.c, Revision 1.209

1.209   ! mycroft     1: /*     $NetBSD: scsiconf.c,v 1.208 2003/08/07 17:54:26 jrf Exp $       */
1.14      cgd         2:
1.106     mycroft     3: /*-
1.157     bouyer      4:  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
1.106     mycroft     5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
1.111     thorpej     8:  * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
                      9:  * Simulation Facility, NASA Ames Research Center.
1.12      mycroft    10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
1.106     mycroft    21:  *        This product includes software developed by the NetBSD
                     22:  *        Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
1.12      mycroft    26:  *
1.106     mycroft    27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
1.12      mycroft    38:  */
                     39:
                     40: /*
                     41:  * Originally written by Julian Elischer (julian@tfs.com)
1.5       deraadt    42:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
1.1       cgd        43:  *
                     44:  * TRW Financial Systems, in accordance with their agreement with Carnegie
                     45:  * Mellon University, makes this software available to CMU to distribute
                     46:  * or use in any manner that they see fit as long as this message is kept with
                     47:  * the software. For this reason TFS also grants any other persons or
                     48:  * organisations permission to use or modify this software.
                     49:  *
                     50:  * TFS supplies this software to be publicly redistributed
                     51:  * on the understanding that TFS is not responsible for the correct
                     52:  * functioning of this software in any circumstances.
1.7       cgd        53:  *
1.12      mycroft    54:  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
1.1       cgd        55:  */
1.165     lukem      56:
                     57: #include <sys/cdefs.h>
1.209   ! mycroft    58: __KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.208 2003/08/07 17:54:26 jrf Exp $");
1.1       cgd        59:
1.10      mycroft    60: #include <sys/param.h>
                     61: #include <sys/systm.h>
1.128     thorpej    62: #include <sys/kernel.h>
                     63: #include <sys/proc.h>
1.157     bouyer     64: #include <sys/kthread.h>
1.12      mycroft    65: #include <sys/malloc.h>
                     66: #include <sys/device.h>
1.111     thorpej    67: #include <sys/conf.h>
1.113     thorpej    68: #include <sys/fcntl.h>
1.112     thorpej    69: #include <sys/scsiio.h>
1.188     jmc        70: #include <sys/queue.h>
                     71: #include <sys/lock.h>
1.10      mycroft    72:
1.88      bouyer     73: #include <dev/scsipi/scsi_all.h>
                     74: #include <dev/scsipi/scsipi_all.h>
                     75: #include <dev/scsipi/scsiconf.h>
1.92      enami      76:
1.88      bouyer     77: #include "locators.h"
1.1       cgd        78:
1.157     bouyer     79: const struct scsipi_periphsw scsi_probe_dev = {
1.12      mycroft    80:        NULL,
                     81:        NULL,
                     82:        NULL,
                     83:        NULL,
                     84: };
                     85:
1.188     jmc        86: struct scsi_initq {
                     87:        struct scsipi_channel *sc_channel;
                     88:        TAILQ_ENTRY(scsi_initq) scsi_initq;
                     89: };
                     90:
                     91: static TAILQ_HEAD(, scsi_initq) scsi_initq_head =
                     92:     TAILQ_HEAD_INITIALIZER(scsi_initq_head);
                     93: static struct simplelock scsibus_interlock = SIMPLELOCK_INITIALIZER;
                     94:
1.157     bouyer     95: int    scsi_probe_device __P((struct scsibus_softc *, int, int));
                     96:
                     97: int    scsibusmatch __P((struct device *, struct cfdata *, void *));
                     98: void   scsibusattach __P((struct device *, struct device *, void *));
                     99: int    scsibusactivate __P((struct device *, enum devact));
                    100: int    scsibusdetach __P((struct device *, int flags));
1.126     thorpej   101:
1.157     bouyer    102: int    scsibussubmatch __P((struct device *, struct cfdata *, void *));
1.12      mycroft   103:
1.191     thorpej   104: CFATTACH_DECL(scsibus, sizeof(struct scsibus_softc),
1.192     thorpej   105:     scsibusmatch, scsibusattach, scsibusdetach, scsibusactivate);
1.53      thorpej   106:
1.94      thorpej   107: extern struct cfdriver scsibus_cd;
1.12      mycroft   108:
1.187     gehenna   109: dev_type_open(scsibusopen);
                    110: dev_type_close(scsibusclose);
                    111: dev_type_ioctl(scsibusioctl);
                    112:
                    113: const struct cdevsw scsibus_cdevsw = {
                    114:        scsibusopen, scsibusclose, noread, nowrite, scsibusioctl,
1.194     jdolecek  115:        nostop, notty, nopoll, nommap, nokqfilter,
1.187     gehenna   116: };
                    117:
1.157     bouyer    118: int    scsibusprint __P((void *, const char *));
1.188     jmc       119: void   scsibus_config __P((struct scsipi_channel *, void *));
1.62      cgd       120:
1.157     bouyer    121: const struct scsipi_bustype scsi_bustype = {
                    122:        SCSIPI_BUSTYPE_SCSI,
                    123:        scsi_scsipi_cmd,
                    124:        scsipi_interpret_sense,
                    125:        scsi_print_addr,
                    126:        scsi_kill_pending,
                    127: };
                    128:
                    129: int
                    130: scsiprint(aux, pnp)
                    131:        void *aux;
                    132:        const char *pnp;
                    133: {
                    134:        struct scsipi_channel *chan = aux;
                    135:        struct scsipi_adapter *adapt = chan->chan_adapter;
                    136:
                    137:        /* only "scsibus"es can attach to "scsi"s; easy. */
                    138:        if (pnp)
1.196     thorpej   139:                aprint_normal("scsibus at %s", pnp);
1.157     bouyer    140:
                    141:        /* don't print channel if the controller says there can be only one. */
                    142:        if (adapt->adapt_nchannels != 1)
1.196     thorpej   143:                aprint_normal(" channel %d", chan->chan_channel);
1.157     bouyer    144:
                    145:        return (UNCONF);
                    146: }
                    147:
1.62      cgd       148: int
1.71      cgd       149: scsibusmatch(parent, cf, aux)
1.62      cgd       150:        struct device *parent;
1.71      cgd       151:        struct cfdata *cf;
                    152:        void *aux;
1.12      mycroft   153: {
1.157     bouyer    154:        struct scsipi_channel *chan = aux;
1.62      cgd       155:
1.172     bouyer    156:        if (chan->chan_bustype->bustype_type != SCSIPI_BUSTYPE_SCSI)
1.157     bouyer    157:                return 0;
1.62      cgd       158:
1.157     bouyer    159:        if (cf->cf_loc[SCSICF_CHANNEL] != chan->chan_channel &&
1.92      enami     160:            cf->cf_loc[SCSICF_CHANNEL] != SCSICF_CHANNEL_DEFAULT)
1.62      cgd       161:                return (0);
1.12      mycroft   162:
1.62      cgd       163:        return (1);
1.12      mycroft   164: }
                    165:
                    166: void
                    167: scsibusattach(parent, self, aux)
1.88      bouyer    168:        struct device *parent, *self;
                    169:        void *aux;
1.12      mycroft   170: {
1.157     bouyer    171:        struct scsibus_softc *sc = (void *) self;
                    172:        struct scsipi_channel *chan = aux;
1.188     jmc       173:        struct scsi_initq *scsi_initq;
1.103     thorpej   174:
1.157     bouyer    175:        sc->sc_channel = chan;
1.179     bouyer    176:        chan->chan_name = sc->sc_dev.dv_xname;
1.72      thorpej   177:
1.205     thorpej   178:        aprint_naive(": SCSI bus\n");
                    179:        aprint_normal(": %d target%s, %d lun%s per target\n",
1.188     jmc       180:            chan->chan_ntargets,
                    181:            chan->chan_ntargets == 1 ? "" : "s",
                    182:            chan->chan_nluns,
                    183:            chan->chan_nluns == 1 ? "" : "s");
                    184:
1.157     bouyer    185:        /* Initialize the channel structure first */
1.188     jmc       186:        chan->chan_init_cb = scsibus_config;
                    187:        chan->chan_init_cb_arg = sc;
                    188:
                    189:        scsi_initq = malloc(sizeof(struct scsi_initq), M_DEVBUF, M_WAITOK);
                    190:        scsi_initq->sc_channel = chan;
                    191:        TAILQ_INSERT_TAIL(&scsi_initq_head, scsi_initq, scsi_initq);
                    192:         config_pending_incr();
1.157     bouyer    193:        if (scsipi_channel_init(chan)) {
1.205     thorpej   194:                aprint_error("%s: failed to init channel\n",
                    195:                    sc->sc_dev.dv_xname);
1.157     bouyer    196:                return;
1.72      thorpej   197:        }
1.128     thorpej   198: }
                    199:
                    200: void
1.188     jmc       201: scsibus_config(chan, arg)
                    202:        struct scsipi_channel *chan;
                    203:        void *arg;
1.128     thorpej   204: {
1.188     jmc       205:        struct scsibus_softc *sc = arg;
                    206:        struct scsi_initq *scsi_initq;
1.157     bouyer    207:
1.132     soren     208: #ifndef SCSI_DELAY
1.12      mycroft   209: #define SCSI_DELAY 2
1.132     soren     210: #endif
1.201     bouyer    211:        if ((chan->chan_flags & SCSIPI_CHAN_NOSETTLE) == 0 &&
                    212:            SCSI_DELAY > 0) {
1.205     thorpej   213:                aprint_normal(
                    214:                    "%s: waiting %d seconds for devices to settle...\n",
1.201     bouyer    215:                    sc->sc_dev.dv_xname, SCSI_DELAY);
                    216:                /* ...an identifier we know no one will use... */
                    217:                (void) tsleep(scsibus_config, PRIBIO,
                    218:                    "scsidly", SCSI_DELAY * hz);
                    219:        }
1.157     bouyer    220:
1.188     jmc       221:        /* Make sure the devices probe in scsibus order to avoid jitter. */
                    222:        simple_lock(&scsibus_interlock);
                    223:        for (;;) {
                    224:                scsi_initq = TAILQ_FIRST(&scsi_initq_head);
                    225:                if (scsi_initq->sc_channel == chan)
                    226:                        break;
                    227:                ltsleep(&scsi_initq_head, PRIBIO, "scsi_initq", 0,
                    228:                    &scsibus_interlock);
                    229:        }
                    230:
                    231:        simple_unlock(&scsibus_interlock);
1.128     thorpej   232:
1.157     bouyer    233:        scsi_probe_bus(sc, -1, -1);
1.188     jmc       234:
                    235:        simple_lock(&scsibus_interlock);
                    236:        TAILQ_REMOVE(&scsi_initq_head, scsi_initq, scsi_initq);
                    237:        simple_unlock(&scsibus_interlock);
                    238:
                    239:        free(scsi_initq, M_DEVBUF);
                    240:        wakeup(&scsi_initq_head);
                    241:
                    242:        config_pending_decr();
1.12      mycroft   243: }
                    244:
1.18      mycroft   245: int
1.71      cgd       246: scsibussubmatch(parent, cf, aux)
1.18      mycroft   247:        struct device *parent;
1.71      cgd       248:        struct cfdata *cf;
                    249:        void *aux;
1.18      mycroft   250: {
1.88      bouyer    251:        struct scsipibus_attach_args *sa = aux;
1.157     bouyer    252:        struct scsipi_periph *periph = sa->sa_periph;
1.18      mycroft   253:
1.88      bouyer    254:        if (cf->cf_loc[SCSIBUSCF_TARGET] != SCSIBUSCF_TARGET_DEFAULT &&
1.157     bouyer    255:            cf->cf_loc[SCSIBUSCF_TARGET] != periph->periph_target)
1.92      enami     256:                return (0);
1.88      bouyer    257:        if (cf->cf_loc[SCSIBUSCF_LUN] != SCSIBUSCF_LUN_DEFAULT &&
1.157     bouyer    258:            cf->cf_loc[SCSIBUSCF_LUN] != periph->periph_lun)
1.92      enami     259:                return (0);
1.189     thorpej   260:        return (config_match(parent, cf, aux));
1.126     thorpej   261: }
                    262:
                    263: int
                    264: scsibusactivate(self, act)
                    265:        struct device *self;
                    266:        enum devact act;
                    267: {
1.157     bouyer    268:        struct scsibus_softc *sc = (void *) self;
                    269:        struct scsipi_channel *chan = sc->sc_channel;
                    270:        struct scsipi_periph *periph;
1.126     thorpej   271:        int target, lun, error = 0, s;
                    272:
                    273:        s = splbio();
                    274:        switch (act) {
                    275:        case DVACT_ACTIVATE:
                    276:                error = EOPNOTSUPP;
                    277:                break;
                    278:
                    279:        case DVACT_DEACTIVATE:
1.157     bouyer    280:                for (target = 0; target < chan->chan_ntargets;
                    281:                     target++) {
                    282:                        if (target == chan->chan_id)
1.126     thorpej   283:                                continue;
1.157     bouyer    284:                        for (lun = 0; lun < chan->chan_nluns; lun++) {
                    285:                                periph = scsipi_lookup_periph(chan,
                    286:                                    target, lun);
                    287:                                if (periph == NULL)
1.126     thorpej   288:                                        continue;
1.157     bouyer    289:                                error = config_deactivate(periph->periph_dev);
1.126     thorpej   290:                                if (error)
                    291:                                        goto out;
                    292:                        }
                    293:                }
                    294:                break;
                    295:        }
                    296:  out:
                    297:        splx(s);
                    298:        return (error);
                    299: }
                    300:
                    301: int
                    302: scsibusdetach(self, flags)
                    303:        struct device *self;
                    304:        int flags;
                    305: {
1.157     bouyer    306:        struct scsibus_softc *sc = (void *) self;
                    307:        struct scsipi_channel *chan = sc->sc_channel;
1.126     thorpej   308:
1.157     bouyer    309:        /*
                    310:         * Shut down the channel.
                    311:         */
                    312:        scsipi_channel_shutdown(chan);
                    313:
                    314:        /*
                    315:         * Now detach all of the periphs.
                    316:         */
1.159     bouyer    317:        return scsipi_target_detach(chan, -1, -1, flags);
1.18      mycroft   318: }
                    319:
1.12      mycroft   320: /*
                    321:  * Probe the requested scsi bus. It must be already set up.
1.18      mycroft   322:  * target and lun optionally narrow the search if not -1
1.12      mycroft   323:  */
                    324: int
1.157     bouyer    325: scsi_probe_bus(sc, target, lun)
                    326:        struct scsibus_softc *sc;
                    327:        int target, lun;
1.12      mycroft   328: {
1.157     bouyer    329:        struct scsipi_channel *chan = sc->sc_channel;
1.18      mycroft   330:        int maxtarget, mintarget, maxlun, minlun;
1.116     thorpej   331:        int error;
1.12      mycroft   332:
1.18      mycroft   333:        if (target == -1) {
1.157     bouyer    334:                maxtarget = chan->chan_ntargets - 1;
1.18      mycroft   335:                mintarget = 0;
1.12      mycroft   336:        } else {
1.157     bouyer    337:                if (target < 0 || target >= chan->chan_ntargets)
1.92      enami     338:                        return (EINVAL);
1.18      mycroft   339:                maxtarget = mintarget = target;
1.12      mycroft   340:        }
1.1       cgd       341:
1.12      mycroft   342:        if (lun == -1) {
1.157     bouyer    343:                maxlun = chan->chan_nluns - 1;
1.12      mycroft   344:                minlun = 0;
                    345:        } else {
1.157     bouyer    346:                if (lun < 0 || lun >= chan->chan_nluns)
1.92      enami     347:                        return (EINVAL);
1.12      mycroft   348:                maxlun = minlun = lun;
                    349:        }
                    350:
1.153     ad        351:        /*
                    352:         * Some HBAs provide an abstracted view of the bus; give them an
                    353:         * oppertunity to re-scan it before we do.
                    354:         */
1.157     bouyer    355:        if (chan->chan_adapter->adapt_ioctl != NULL)
                    356:                (*chan->chan_adapter->adapt_ioctl)(chan, SCBUSIOLLSCAN, NULL,
1.153     ad        357:                    0, curproc);
                    358:
1.157     bouyer    359:        if ((error = scsipi_adapter_addref(chan->chan_adapter)) != 0)
1.116     thorpej   360:                return (error);
1.18      mycroft   361:        for (target = mintarget; target <= maxtarget; target++) {
1.157     bouyer    362:                if (target == chan->chan_id)
1.12      mycroft   363:                        continue;
                    364:                for (lun = minlun; lun <= maxlun; lun++) {
                    365:                        /*
1.18      mycroft   366:                         * See if there's a device present, and configure it.
1.12      mycroft   367:                         */
1.157     bouyer    368:                        if (scsi_probe_device(sc, target, lun) == 0)
1.18      mycroft   369:                                break;
1.12      mycroft   370:                        /* otherwise something says we should look further */
                    371:                }
1.157     bouyer    372:
                    373:                /*
                    374:                 * Now that we've discovered all of the LUNs on this
                    375:                 * I_T Nexus, update the xfer mode for all of them
                    376:                 * that we know about.
                    377:                 */
                    378:                scsipi_set_xfer_mode(chan, target, 1);
1.8       deraadt   379:        }
1.157     bouyer    380:        scsipi_adapter_delref(chan->chan_adapter);
1.92      enami     381:        return (0);
1.12      mycroft   382: }
                    383:
1.88      bouyer    384: /*
                    385:  * Print out autoconfiguration information for a subdevice.
                    386:  *
                    387:  * This is a slight abuse of 'standard' autoconfiguration semantics,
                    388:  * because 'print' functions don't normally print the colon and
                    389:  * device information.  However, in this case that's better than
                    390:  * either printing redundant information before the attach message,
                    391:  * or having the device driver call a special function to print out
                    392:  * the standard device information.
                    393:  */
                    394: int
                    395: scsibusprint(aux, pnp)
                    396:        void *aux;
                    397:        const char *pnp;
1.12      mycroft   398: {
1.88      bouyer    399:        struct scsipibus_attach_args *sa = aux;
                    400:        struct scsipi_inquiry_pattern *inqbuf;
                    401:        u_int8_t type;
1.193     soren     402:        const char *dtype;
1.88      bouyer    403:        char vendor[33], product[65], revision[17];
                    404:        int target, lun;
                    405:
                    406:        if (pnp != NULL)
1.196     thorpej   407:                aprint_normal("%s", pnp);
1.88      bouyer    408:
                    409:        inqbuf = &sa->sa_inqbuf;
                    410:
1.157     bouyer    411:        target = sa->sa_periph->periph_target;
                    412:        lun = sa->sa_periph->periph_lun;
1.88      bouyer    413:        type = inqbuf->type & SID_TYPE;
                    414:
1.193     soren     415:        dtype = scsipi_dtype(type);
1.2       deraadt   416:
1.104     drochner  417:        scsipi_strvis(vendor, 33, inqbuf->vendor, 8);
                    418:        scsipi_strvis(product, 65, inqbuf->product, 16);
                    419:        scsipi_strvis(revision, 17, inqbuf->revision, 4);
1.88      bouyer    420:
1.196     thorpej   421:        aprint_normal(" target %d lun %d: <%s, %s, %s> %s %s",
1.193     soren     422:            target, lun, vendor, product, revision, dtype,
                    423:            inqbuf->removable ? "removable" : "fixed");
1.88      bouyer    424:
                    425:        return (UNCONF);
1.12      mycroft   426: }
1.1       cgd       427:
1.154     jdolecek  428: const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
1.48      christos  429:        {{T_CDROM, T_REMOV,
1.157     bouyer    430:         "CHINON  ", "CD-ROM CDS-431  ", ""},     PQUIRK_NOLUNS},
1.48      christos  431:        {{T_CDROM, T_REMOV,
1.208     jrf       432:         "CHINON  ", "CD-ROM CDS-435  ", ""},     PQUIRK_NOLUNS},
                    433:        {{T_CDROM, T_REMOV,
1.157     bouyer    434:         "Chinon  ", "CD-ROM CDS-525  ", ""},     PQUIRK_NOLUNS},
1.48      christos  435:        {{T_CDROM, T_REMOV,
1.157     bouyer    436:         "CHINON  ", "CD-ROM CDS-535  ", ""},     PQUIRK_NOLUNS},
1.100     thorpej   437:        {{T_CDROM, T_REMOV,
1.157     bouyer    438:         "DEC     ", "RRD42   (C) DEC ", ""},     PQUIRK_NOLUNS},
1.48      christos  439:        {{T_CDROM, T_REMOV,
1.157     bouyer    440:         "DENON   ", "DRD-25X         ", "V"},    PQUIRK_NOLUNS},
1.148     bouyer    441:        {{T_CDROM, T_REMOV,
1.157     bouyer    442:         "GENERIC ", "CRD-BP2         ", ""},     PQUIRK_NOLUNS},
1.83      mycroft   443:        {{T_CDROM, T_REMOV,
1.157     bouyer    444:         "HP      ", "C4324/C4325     ", ""},     PQUIRK_NOLUNS},
1.48      christos  445:        {{T_CDROM, T_REMOV,
1.157     bouyer    446:         "IMS     ", "CDD521/10       ", "2.06"}, PQUIRK_NOLUNS},
1.48      christos  447:        {{T_CDROM, T_REMOV,
1.157     bouyer    448:         "MATSHITA", "CD-ROM CR-5XX   ", "1.0b"}, PQUIRK_NOLUNS},
1.68      mikel     449:        {{T_CDROM, T_REMOV,
1.157     bouyer    450:         "MEDAVIS ", "RENO CD-ROMX2A  ", ""},     PQUIRK_NOLUNS},
1.84      perry     451:        {{T_CDROM, T_REMOV,
1.157     bouyer    452:         "MEDIAVIS", "CDR-H93MV       ", "1.3"},  PQUIRK_NOLUNS},
1.199     bouyer    453:        {{T_CDROM, T_REMOV,
                    454:         "NEC     ", "CD-ROM DRIVE:502", ""},     PQUIRK_NOLUNS},
1.48      christos  455:        {{T_CDROM, T_REMOV,
1.157     bouyer    456:         "NEC     ", "CD-ROM DRIVE:55 ", ""},     PQUIRK_NOLUNS},
1.48      christos  457:        {{T_CDROM, T_REMOV,
1.157     bouyer    458:         "NEC     ", "CD-ROM DRIVE:83 ", ""},     PQUIRK_NOLUNS},
1.48      christos  459:        {{T_CDROM, T_REMOV,
1.157     bouyer    460:         "NEC     ", "CD-ROM DRIVE:84 ", ""},     PQUIRK_NOLUNS},
1.48      christos  461:        {{T_CDROM, T_REMOV,
1.157     bouyer    462:         "NEC     ", "CD-ROM DRIVE:841", ""},     PQUIRK_NOLUNS},
1.208     jrf       463:         {{T_CDROM, T_REMOV,
                    464:         "OLYMPUS ", "CDS620E         ", "1.1d"},
                    465:                               PQUIRK_NOLUNS|PQUIRK_NOSYNC|PQUIRK_NOCAPACITY},
1.70      thorpej   466:        {{T_CDROM, T_REMOV,
1.157     bouyer    467:         "PIONEER ", "CD-ROM DR-124X  ", "1.01"}, PQUIRK_NOLUNS},
1.208     jrf       468:         {{T_CDROM, T_REMOV,
                    469:          "PLEXTOR ", "CD-ROM PX-4XCS  ", "1.01"},
                    470:                                PQUIRK_NOLUNS|PQUIRK_NOSYNC},
1.48      christos  471:        {{T_CDROM, T_REMOV,
1.157     bouyer    472:         "SONY    ", "CD-ROM CDU-541  ", ""},     PQUIRK_NOLUNS},
1.48      christos  473:        {{T_CDROM, T_REMOV,
1.157     bouyer    474:         "SONY    ", "CD-ROM CDU-55S  ", ""},     PQUIRK_NOLUNS},
1.130     hwr       475:        {{T_CDROM, T_REMOV,
1.157     bouyer    476:         "SONY    ", "CD-ROM CDU-561  ", ""},     PQUIRK_NOLUNS},
1.186     bouyer    477:        {{T_CDROM, T_REMOV,
                    478:         "SONY    ", "CD-ROM CDU-76S", ""},
                    479:                                PQUIRK_NOLUNS|PQUIRK_NOSYNC|PQUIRK_NOWIDE},
1.48      christos  480:        {{T_CDROM, T_REMOV,
1.157     bouyer    481:         "SONY    ", "CD-ROM CDU-8003A", ""},     PQUIRK_NOLUNS},
1.48      christos  482:        {{T_CDROM, T_REMOV,
1.157     bouyer    483:         "SONY    ", "CD-ROM CDU-8012 ", ""},     PQUIRK_NOLUNS},
1.48      christos  484:        {{T_CDROM, T_REMOV,
1.157     bouyer    485:         "TEAC    ", "CD-ROM          ", "1.06"}, PQUIRK_NOLUNS},
1.69      explorer  486:        {{T_CDROM, T_REMOV,
1.157     bouyer    487:         "TEAC    ", "CD-ROM CD-56S   ", "1.0B"}, PQUIRK_NOLUNS},
1.48      christos  488:        {{T_CDROM, T_REMOV,
1.157     bouyer    489:         "TEXEL   ", "CD-ROM          ", "1.06"}, PQUIRK_NOLUNS},
1.127     nathanw   490:        {{T_CDROM, T_REMOV,
1.157     bouyer    491:         "TEXEL   ", "CD-ROM DM-XX24 K", "1.09"}, PQUIRK_NOLUNS},
1.48      christos  492:        {{T_CDROM, T_REMOV,
1.157     bouyer    493:         "TEXEL   ", "CD-ROM DM-XX24 K", "1.10"}, PQUIRK_NOLUNS},
1.89      pk        494:        {{T_CDROM, T_REMOV,
1.198     bouyer    495:         "TOSHIBA ", "XM-4101TASUNSLCD", ""}, PQUIRK_NOLUNS|PQUIRK_NOSYNC},
1.158     pk        496:        /* "IBM CDRM00201     !F" 0724 is an IBM OEM Toshiba XM-4101BME */
                    497:        {{T_CDROM, T_REMOV,
                    498:         "IBM     ", "CDRM00201     !F", "0724"}, PQUIRK_NOLUNS|PQUIRK_NOSYNC},
1.92      enami     499:        {{T_CDROM, T_REMOV,
1.167     tsutsui   500:         "ShinaKen", "CD-ROM DM-3x1S",   "1.04"}, PQUIRK_NOLUNS},
1.98      explorer  501:        {{T_CDROM, T_REMOV,
1.157     bouyer    502:         "JVC     ", "R2626",            ""},     PQUIRK_NOLUNS},
1.137     sjg       503:        {{T_CDROM, T_REMOV,
1.157     bouyer    504:         "YAMAHA", "CRW8424S",           ""},     PQUIRK_NOLUNS},
1.156     fvdl      505:        {{T_CDROM, T_REMOV,
1.209   ! mycroft   506:         "VMware", "Virtual",            "1.0"},  PQUIRK_NODOORLOCK},
1.195     jdolecek  507:        {{T_CDROM, T_REMOV,
                    508:         "NEC     ", "CD-ROM DRIVE:222", ""},     PQUIRK_NOLUNS|PQUIRK_NOSYNC},
1.156     fvdl      509:
1.80      pk        510:        {{T_DIRECT, T_FIXED,
1.157     bouyer    511:         "MICROP  ", "1588-15MBSUN0669", ""},     PQUIRK_AUTOSAVE},
1.110     thorpej   512:        {{T_DIRECT, T_FIXED,
1.157     bouyer    513:         "MICROP  ", "2217-15MQ1091501", ""},     PQUIRK_NOSYNCCACHE},
1.55      scottr    514:        {{T_OPTICAL, T_REMOV,
1.157     bouyer    515:         "EPSON   ", "OMD-5010        ", "3.08"}, PQUIRK_NOLUNS},
1.129     hwr       516:        {{T_DIRECT, T_FIXED,
1.167     tsutsui   517:         "TOSHIBA ","CD-ROM XM-3401TA",  "0283"}, PQUIRK_CDROM|PQUIRK_NOLUNS},
1.122     mjacob    518:        {{T_DIRECT, T_FIXED,
1.167     tsutsui   519:         "TOSHIBA ", "CD-ROM DRIVE:XM",  "1971"}, PQUIRK_CDROM|PQUIRK_NOLUNS},
1.143     gmcgarry  520:        {{T_DIRECT, T_FIXED,
1.157     bouyer    521:         "ADAPTEC ", "AEC-4412BD",       "1.2A"}, PQUIRK_NOMODESENSE},
1.50      mycroft   522:        {{T_DIRECT, T_FIXED,
1.171     fredette  523:         "ADAPTEC ", "ACB-4000",         ""},     PQUIRK_FORCELUNS|PQUIRK_AUTOSAVE|PQUIRK_NOMODESENSE},
                    524:        {{T_DIRECT, T_FIXED,
1.157     bouyer    525:         "DEC     ", "RZ55     (C) DEC", ""},     PQUIRK_AUTOSAVE},
1.48      christos  526:        {{T_DIRECT, T_FIXED,
1.167     tsutsui   527:         "EMULEX  ", "MD21/S2     ESDI", "A00"},
                    528:                                PQUIRK_FORCELUNS|PQUIRK_AUTOSAVE},
1.185     matt      529:        {{T_DIRECT, T_FIXED,
                    530:        /* improperly report DT-only sync mode */
                    531:         "HITACHI", "DX32DJ-72ME",       ""},
                    532:                                PQUIRK_CAP_SYNC|PQUIRK_CAP_WIDE16},
1.162     christos  533:        {{T_DIRECT, T_FIXED,
1.167     tsutsui   534:         "MICROP",  "1548-15MZ1077801",  "HZ2P"}, PQUIRK_NOTAG},
1.76      scottr    535:        {{T_DIRECT, T_FIXED,
1.157     bouyer    536:         "HP      ", "C372",             ""},     PQUIRK_NOTAG},
1.108     mjacob    537:        {{T_DIRECT, T_FIXED,
1.157     bouyer    538:         "IBMRAID ", "0662S",            ""},     PQUIRK_AUTOSAVE},
1.76      scottr    539:        {{T_DIRECT, T_FIXED,
1.157     bouyer    540:         "IBM     ", "0663H",            ""},     PQUIRK_AUTOSAVE},
1.82      thorpej   541:        {{T_DIRECT, T_FIXED,
1.157     bouyer    542:         "IBM",      "0664",             ""},     PQUIRK_AUTOSAVE},
1.84      perry     543:        {{T_DIRECT, T_FIXED,
1.184     bouyer    544:        /* improperly report DT-only sync mode */
                    545:         "IBM     ", "DXHS36D",          ""},
1.203     fvdl      546:                                PQUIRK_CAP_SYNC|PQUIRK_CAP_WIDE16},
                    547:        {{T_DIRECT, T_FIXED,
                    548:         "IBM     ", "DXHS18Y",          ""},
1.184     bouyer    549:                                PQUIRK_CAP_SYNC|PQUIRK_CAP_WIDE16},
                    550:        {{T_DIRECT, T_FIXED,
1.167     tsutsui   551:         "IBM     ", "H3171-S2",         ""},
                    552:                                PQUIRK_NOLUNS|PQUIRK_AUTOSAVE},
1.96      scottr    553:        {{T_DIRECT, T_FIXED,
1.157     bouyer    554:         "IBM     ", "KZ-C",             ""},     PQUIRK_AUTOSAVE},
1.81      thorpej   555:        /* Broken IBM disk */
                    556:        {{T_DIRECT, T_FIXED,
1.157     bouyer    557:         ""        , "DFRSS2F",          ""},     PQUIRK_AUTOSAVE},
1.87      mjacob    558:        {{T_DIRECT, T_REMOV,
1.157     bouyer    559:         "MPL     ", "MC-DISK-        ", ""},     PQUIRK_NOLUNS},
1.48      christos  560:        {{T_DIRECT, T_FIXED,
1.157     bouyer    561:         "MAXTOR  ", "XT-3280         ", ""},     PQUIRK_NOLUNS},
1.48      christos  562:        {{T_DIRECT, T_FIXED,
1.157     bouyer    563:         "MAXTOR  ", "XT-4380S        ", ""},     PQUIRK_NOLUNS},
1.48      christos  564:        {{T_DIRECT, T_FIXED,
1.157     bouyer    565:         "MAXTOR  ", "MXT-1240S       ", ""},     PQUIRK_NOLUNS},
1.48      christos  566:        {{T_DIRECT, T_FIXED,
1.157     bouyer    567:         "MAXTOR  ", "XT-4170S        ", ""},     PQUIRK_NOLUNS},
1.48      christos  568:        {{T_DIRECT, T_FIXED,
1.157     bouyer    569:         "MAXTOR  ", "XT-8760S",         ""},     PQUIRK_NOLUNS},
1.48      christos  570:        {{T_DIRECT, T_FIXED,
1.157     bouyer    571:         "MAXTOR  ", "LXT-213S        ", ""},     PQUIRK_NOLUNS},
1.48      christos  572:        {{T_DIRECT, T_FIXED,
1.157     bouyer    573:         "MAXTOR  ", "LXT-213S SUN0207", ""},     PQUIRK_NOLUNS},
1.52      thorpej   574:        {{T_DIRECT, T_FIXED,
1.157     bouyer    575:         "MAXTOR  ", "LXT-200S        ", ""},     PQUIRK_NOLUNS},
1.48      christos  576:        {{T_DIRECT, T_FIXED,
1.157     bouyer    577:         "MEGADRV ", "EV1000",           ""},     PQUIRK_NOMODESENSE},
1.178     chs       578:        {{T_DIRECT, T_FIXED,
                    579:         "MICROP", "1991-27MZ",          ""},     PQUIRK_NOTAG},
1.90      mjacob    580:        {{T_DIRECT, T_FIXED,
1.157     bouyer    581:         "MST     ", "SnapLink        ", ""},     PQUIRK_NOLUNS},
1.54      hpeyerl   582:        {{T_DIRECT, T_FIXED,
1.157     bouyer    583:         "NEC     ", "D3847           ", "0307"}, PQUIRK_NOLUNS},
1.96      scottr    584:        {{T_DIRECT, T_FIXED,
1.157     bouyer    585:         "QUANTUM ", "ELS85S          ", ""},     PQUIRK_AUTOSAVE},
1.48      christos  586:        {{T_DIRECT, T_FIXED,
1.157     bouyer    587:         "QUANTUM ", "LPS525S         ", ""},     PQUIRK_NOLUNS},
1.48      christos  588:        {{T_DIRECT, T_FIXED,
1.157     bouyer    589:         "QUANTUM ", "P105S 910-10-94x", ""},     PQUIRK_NOLUNS},
1.48      christos  590:        {{T_DIRECT, T_FIXED,
1.157     bouyer    591:         "QUANTUM ", "PD1225S         ", ""},     PQUIRK_NOLUNS},
1.48      christos  592:        {{T_DIRECT, T_FIXED,
1.157     bouyer    593:         "QUANTUM ", "PD210S   SUN0207", ""},     PQUIRK_NOLUNS},
1.48      christos  594:        {{T_DIRECT, T_FIXED,
1.202     fvdl      595:         "QUANTUM ", "ATLAS IV 9 WLS", "0A0A"},   PQUIRK_CAP_NODT},
                    596:        {{T_DIRECT, T_FIXED,
1.157     bouyer    597:         "RODIME  ", "RO3000S         ", ""},     PQUIRK_NOLUNS},
1.75      scottr    598:        {{T_DIRECT, T_FIXED,
1.157     bouyer    599:         "SEAGATE ", "ST125N          ", ""},     PQUIRK_NOLUNS},
1.48      christos  600:        {{T_DIRECT, T_FIXED,
1.157     bouyer    601:         "SEAGATE ", "ST157N          ", ""},     PQUIRK_NOLUNS},
1.48      christos  602:        {{T_DIRECT, T_FIXED,
1.157     bouyer    603:         "SEAGATE ", "ST296           ", ""},     PQUIRK_NOLUNS},
1.48      christos  604:        {{T_DIRECT, T_FIXED,
1.157     bouyer    605:         "SEAGATE ", "ST296N          ", ""},     PQUIRK_NOLUNS},
1.204     fvdl      606:        {{T_DIRECT, T_FIXED,
                    607:         "SEAGATE ", "ST318404LC      ", ""},     PQUIRK_NOLUNS},
1.163     mjl       608:        {{T_DIRECT, T_FIXED,
                    609:         "SEAGATE ", "ST15150N        ", ""},     PQUIRK_NOTAG},
1.86      mjacob    610:        {{T_DIRECT, T_FIXED,
1.157     bouyer    611:         "SEAGATE ", "ST19171",          ""},     PQUIRK_NOMODESENSE},
1.90      mjacob    612:        {{T_DIRECT, T_FIXED,
1.170     tsutsui   613:         "SEAGATE ", "ST32430N",         ""},     PQUIRK_CAP_SYNC},
                    614:        {{T_DIRECT, T_FIXED,
1.157     bouyer    615:         "SEAGATE ", "ST34501FC       ", ""},     PQUIRK_NOMODESENSE},
1.48      christos  616:        {{T_DIRECT, T_FIXED,
1.157     bouyer    617:         "TOSHIBA ", "MK538FB         ", "6027"}, PQUIRK_NOLUNS},
1.156     fvdl      618:        {{T_DIRECT, T_FIXED,
1.209   ! mycroft   619:         "VMware", "Virtual",           "1.0"},   PQUIRK_NODOORLOCK},
1.175     augustss  620:        {{T_DIRECT, T_FIXED,    /* XXX move to umass */
                    621:         "Maxtor 4", "D080H4",           "DAH0"}, PQUIRK_NOMODESENSE},
1.180     joda      622:        {{T_DIRECT, T_FIXED,    /* XXX move to umass */
                    623:         "Maxtor 4", "D040H2",           "DAH0"}, PQUIRK_NOMODESENSE},
1.197     pk        624:        {{T_DIRECT, T_FIXED,
                    625:         "MICROP  ", "1924",          ""},     PQUIRK_CAP_SYNC},
                    626:        {{T_DIRECT, T_FIXED,
                    627:         "FUJITSU ", "M2266",         ""},     PQUIRK_CAP_SYNC},
1.156     fvdl      628:
1.58      christos  629:        {{T_DIRECT, T_REMOV,
1.157     bouyer    630:         "iomega", "jaz 1GB",            ""},     PQUIRK_NOMODESENSE},
1.59      explorer  631:        {{T_DIRECT, T_REMOV,
1.157     bouyer    632:         "IOMEGA", "ZIP 100",            ""},     PQUIRK_NOMODESENSE},
1.118     leo       633:        {{T_DIRECT, T_REMOV,
1.167     tsutsui   634:         "IOMEGA", "ZIP 100",            "J.03"},
                    635:                                PQUIRK_NOMODESENSE|PQUIRK_NOLUNS},
1.168     soren     636:        {{T_DIRECT, T_REMOV,
1.169     soren     637:         "INSITE", "I325VM",             ""},
                    638:                                PQUIRK_NOLUNS|PQUIRK_NODOORLOCK},
1.18      mycroft   639:
1.37      cgd       640:        /* XXX: QIC-36 tape behind Emulex adapter.  Very broken. */
1.48      christos  641:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    642:         "        ", "                ", "    "}, PQUIRK_NOLUNS},
1.171     fredette  643:        {{T_SEQUENTIAL, T_REMOV,
                    644:         "EMULEX  ", "MT-02 QIC       ", ""},     PQUIRK_NOLUNS},
1.48      christos  645:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    646:         "CALIPER ", "CP150           ", ""},     PQUIRK_NOLUNS},
1.48      christos  647:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    648:         "EXABYTE ", "EXB-8200        ", ""},     PQUIRK_NOLUNS},
1.48      christos  649:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    650:         "SONY    ", "GY-10C          ", ""},     PQUIRK_NOLUNS},
1.87      mjacob    651:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    652:         "SONY    ", "SDT-2000        ", "2.09"}, PQUIRK_NOLUNS},
1.48      christos  653:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    654:         "SONY    ", "SDT-5000        ", "3."},   PQUIRK_NOSYNC|PQUIRK_NOWIDE},
1.48      christos  655:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    656:         "SONY    ", "SDT-5200        ", "3."},   PQUIRK_NOLUNS},
1.48      christos  657:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    658:         "TANDBERG", " TDC 3600       ", ""},     PQUIRK_NOLUNS},
1.47      pk        659:        /* Following entry reported as a Tandberg 3600; ref. PR1933 */
1.48      christos  660:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    661:         "ARCHIVE ", "VIPER 150  21247", ""},     PQUIRK_NOLUNS},
1.91      bouyer    662:        /* Following entry for a Cipher ST150S; ref. PR4171 */
                    663:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    664:         "ARCHIVE ", "VIPER 1500 21247", "2.2G"}, PQUIRK_NOLUNS},
1.80      pk        665:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    666:         "ARCHIVE ", "Python 28454-XXX", ""},     PQUIRK_NOLUNS},
1.48      christos  667:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    668:         "WANGTEK ", "5099ES SCSI",      ""},     PQUIRK_NOLUNS},
1.48      christos  669:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    670:         "WANGTEK ", "5150ES SCSI",      ""},     PQUIRK_NOLUNS},
1.125     hwr       671:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    672:         "WANGTEK ", "SCSI-36",          ""},     PQUIRK_NOLUNS},
1.48      christos  673:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    674:         "WangDAT ", "Model 1300      ", "02.4"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE},
1.48      christos  675:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    676:         "WangDAT ", "Model 2600      ", "01.7"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE},
1.48      christos  677:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    678:         "WangDAT ", "Model 3200      ", "02.2"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE},
1.133     nisimura  679:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    680:         "TEAC    ", "MT-2ST/N50      ", ""},     PQUIRK_NOLUNS},
1.87      mjacob    681:
1.101     bouyer    682:        {{T_SCANNER, T_FIXED,
1.157     bouyer    683:         "RICOH   ", "IS60            ", "1R08"}, PQUIRK_NOLUNS},
1.99      thorpej   684:        {{T_SCANNER, T_FIXED,
1.157     bouyer    685:         "UMAX    ", "Astra 1200S     ", "V2.9"}, PQUIRK_NOLUNS},
1.102     fvdl      686:        {{T_SCANNER, T_FIXED,
1.157     bouyer    687:         "UMAX    ", "Astra 1220S     ", ""},     PQUIRK_NOLUNS},
1.85      explorer  688:        {{T_SCANNER, T_FIXED,
1.157     bouyer    689:         "UMAX    ", "UMAX S-6E       ", "V2.0"}, PQUIRK_NOLUNS},
1.95      mikel     690:        {{T_SCANNER, T_FIXED,
1.157     bouyer    691:         "UMAX    ", "UMAX S-12       ", "V2.1"}, PQUIRK_NOLUNS},
1.135     martin    692:        {{T_SCANNER, T_FIXED,
1.167     tsutsui   693:         "ULTIMA  ", "A6000C          ", ""},     PQUIRK_NOLUNS},
1.150     mjacob    694:        {{T_PROCESSOR, T_FIXED,
1.167     tsutsui   695:         "SYMBIOS",  "",                 ""},     PQUIRK_NOLUNS},
1.87      mjacob    696:        {{T_PROCESSOR, T_FIXED,
1.157     bouyer    697:         "LITRONIC", "PCMCIA          ", ""},     PQUIRK_NOLUNS},
1.109     thorpej   698:        {{T_CHANGER, T_REMOV,
1.157     bouyer    699:         "SONY    ", "CDL1100         ", ""},     PQUIRK_NOLUNS},
1.119     mjacob    700:        {{T_ENCLOSURE, T_FIXED,
1.167     tsutsui   701:         "SUN     ", "SENA            ", ""},     PQUIRK_NOLUNS},
1.209   ! mycroft   702:        {{T_DIRECT, T_REMOV,
        !           703:         "Generic ", "USB Storage-SMC ", ""},     PQUIRK_FORCELUNS},
1.18      mycroft   704: };
                    705:
1.12      mycroft   706: /*
1.95      mikel     707:  * given a target and lun, ask the device what
1.12      mycroft   708:  * it is, and find the correct driver table
                    709:  * entry.
                    710:  */
1.119     mjacob    711: int
1.157     bouyer    712: scsi_probe_device(sc, target, lun)
                    713:        struct scsibus_softc *sc;
1.18      mycroft   714:        int target, lun;
                    715: {
1.157     bouyer    716:        struct scsipi_channel *chan = sc->sc_channel;
                    717:        struct scsipi_periph *periph;
1.140     enami     718:        struct scsipi_inquiry_data inqbuf;
1.18      mycroft   719:        struct scsi_quirk_inquiry_pattern *finger;
1.157     bouyer    720:        int checkdtype, priority, docontinue, quirks;
1.88      bouyer    721:        struct scsipibus_attach_args sa;
1.18      mycroft   722:        struct cfdata *cf;
                    723:
1.119     mjacob    724:        /*
                    725:         * Assume no more luns to search after this one.
                    726:         * If we successfully get Inquiry data and after
                    727:         * merging quirks we find we can probe for more
                    728:         * luns, we will.
                    729:         */
                    730:        docontinue = 0;
                    731:
1.18      mycroft   732:        /* Skip this slot if it is already attached. */
1.157     bouyer    733:        if (scsipi_lookup_periph(chan, target, lun) != NULL)
1.119     mjacob    734:                return (docontinue);
1.18      mycroft   735:
1.157     bouyer    736:        periph = scsipi_alloc_periph(M_NOWAIT);
                    737:        if (periph == NULL) {
                    738: #ifdef DIAGNOSTIC
1.205     thorpej   739:                aprint_error(
                    740:                    "%s: cannot allocate periph for target %d lun %d\n",
1.157     bouyer    741:                    sc->sc_dev.dv_xname, target, lun);
                    742: #endif
                    743:                return (ENOMEM);
                    744:        }
                    745:        periph->periph_channel = chan;
                    746:        periph->periph_switch = &scsi_probe_dev;
                    747:
                    748:        periph->periph_target = target;
                    749:        periph->periph_lun = lun;
                    750:        periph->periph_quirks = chan->chan_defquirks;
                    751:
                    752: #ifdef SCSIPI_DEBUG
                    753:        if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_SCSI &&
                    754:            SCSIPI_DEBUG_TARGET == target &&
                    755:            SCSIPI_DEBUG_LUN == lun)
                    756:                periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS;
                    757: #endif
1.12      mycroft   758:
                    759:        /*
                    760:         * Ask the device what it is
                    761:         */
1.157     bouyer    762:        (void) scsipi_test_unit_ready(periph,
1.128     thorpej   763:            XS_CTL_DISCOVERY | XS_CTL_IGNORE_ILLEGAL_REQUEST |
                    764:            XS_CTL_IGNORE_NOT_READY | XS_CTL_IGNORE_MEDIA_CHANGE);
1.18      mycroft   765:
1.23      mycroft   766: #ifdef SCSI_2_DEF
1.12      mycroft   767:        /* some devices need to be told to go to SCSI2 */
                    768:        /* However some just explode if you tell them this.. leave it out */
1.157     bouyer    769:        scsi_change_def(periph, XS_CTL_DISCOVERY | XS_CTL_SILENT);
1.18      mycroft   770: #endif /* SCSI_2_DEF */
                    771:
                    772:        /* Now go ask the device all about itself. */
1.157     bouyer    773:        memset(&inqbuf, 0, sizeof(inqbuf));
                    774:        if (scsipi_inquire(periph, &inqbuf,
1.147     enami     775:            XS_CTL_DISCOVERY | XS_CTL_DATA_ONSTACK) != 0)
1.18      mycroft   776:                goto bad;
                    777:        {
1.141     dante     778:                u_int8_t *extension = &inqbuf.flags1;
1.18      mycroft   779:                int len = inqbuf.additional_length;
1.20      mycroft   780:                while (len < 3)
1.141     dante     781:                        extension[len++] = '\0';
1.20      mycroft   782:                while (len < 3 + 28)
1.141     dante     783:                        extension[len++] = ' ';
                    784:                while (len < 3 + 28 + 20)
                    785:                        extension[len++] = '\0';
                    786:                while (len < 3 + 28 + 20 + 1)
                    787:                        extension[len++] = '\0';
1.142     dante     788:                while (len < 3 + 28 + 20 + 1 + 1)
                    789:                        extension[len++] = '\0';
                    790:                while (len < 3 + 28 + 20 + 1 + 1 + (8*2))
                    791:                        extension[len++] = ' ';
1.18      mycroft   792:        }
                    793:
1.157     bouyer    794:        periph->periph_type = inqbuf.device & SID_TYPE;
                    795:        if (inqbuf.dev_qual2 & SID_REMOVABLE)
                    796:                periph->periph_flags |= PERIPH_REMOVABLE;
                    797:        periph->periph_version = inqbuf.version & SID_ANSII;
1.12      mycroft   798:
                    799:        /*
                    800:         * Any device qualifier that has the top bit set (qualifier&4 != 0)
                    801:         * is vendor specific and won't match in this switch.
1.51      thorpej   802:         * All we do here is throw out bad/negative responses.
1.12      mycroft   803:         */
1.51      thorpej   804:        checkdtype = 0;
1.18      mycroft   805:        switch (inqbuf.device & SID_QUAL) {
1.157     bouyer    806:        case SID_QUAL_LU_PRESENT:
                    807:        case SID_QUAL_LU_NOTPRESENT:
1.51      thorpej   808:                checkdtype = 1;
1.2       deraadt   809:                break;
1.12      mycroft   810:
1.157     bouyer    811:        case SID_QUAL_reserved:
                    812:        case SID_QUAL_LU_NOT_SUPP:
1.18      mycroft   813:                goto bad;
1.12      mycroft   814:
1.2       deraadt   815:        default:
                    816:                break;
                    817:        }
1.151     ad        818:
                    819:        /* Let the adapter driver handle the device separatley if it wants. */
1.157     bouyer    820:        if (chan->chan_adapter->adapt_accesschk != NULL &&
                    821:            (*chan->chan_adapter->adapt_accesschk)(periph, &sa.sa_inqbuf))
1.151     ad        822:                goto bad;
                    823:
1.149     mjacob    824:        if (checkdtype) {
1.157     bouyer    825:                switch (periph->periph_type) {
1.2       deraadt   826:                case T_DIRECT:
                    827:                case T_SEQUENTIAL:
                    828:                case T_PRINTER:
                    829:                case T_PROCESSOR:
1.93      thorpej   830:                case T_WORM:
1.18      mycroft   831:                case T_CDROM:
1.2       deraadt   832:                case T_SCANNER:
                    833:                case T_OPTICAL:
                    834:                case T_CHANGER:
                    835:                case T_COMM:
1.93      thorpej   836:                case T_IT8_1:
                    837:                case T_IT8_2:
                    838:                case T_STORARRAY:
                    839:                case T_ENCLOSURE:
1.142     dante     840:                case T_SIMPLE_DIRECT:
                    841:                case T_OPTIC_CARD_RW:
                    842:                case T_OBJECT_STORED:
1.51      thorpej   843:                default:
1.2       deraadt   844:                        break;
1.12      mycroft   845:                case T_NODEVICE:
1.18      mycroft   846:                        goto bad;
1.1       cgd       847:                }
1.157     bouyer    848:        }
                    849:
                    850:        sa.sa_periph = periph;
                    851:        sa.sa_inqbuf.type = inqbuf.device;
                    852:        sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ?
                    853:            T_REMOV : T_FIXED;
                    854:        sa.sa_inqbuf.vendor = inqbuf.vendor;
                    855:        sa.sa_inqbuf.product = inqbuf.product;
                    856:        sa.sa_inqbuf.revision = inqbuf.revision;
                    857:        sa.scsipi_info.scsi_version = inqbuf.version;
                    858:        sa.sa_inqptr = &inqbuf;
                    859:
                    860:        finger = (struct scsi_quirk_inquiry_pattern *)scsipi_inqmatch(
                    861:            &sa.sa_inqbuf, (caddr_t)scsi_quirk_patterns,
                    862:            sizeof(scsi_quirk_patterns)/sizeof(scsi_quirk_patterns[0]),
                    863:            sizeof(scsi_quirk_patterns[0]), &priority);
                    864:
                    865:        if (finger != NULL)
                    866:                quirks = finger->quirks;
                    867:        else
                    868:                quirks = 0;
                    869:
                    870:        /*
                    871:         * Determine the operating mode capabilities of the device.
                    872:         */
                    873:        if (periph->periph_version >= 2) {
                    874:                if ((inqbuf.flags3 & SID_CmdQue) != 0 &&
                    875:                    (quirks & PQUIRK_NOTAG) == 0)
                    876:                        periph->periph_cap |= PERIPH_CAP_TQING;
                    877:                if ((inqbuf.flags3 & SID_Linked) != 0)
                    878:                        periph->periph_cap |= PERIPH_CAP_LINKCMDS;
                    879:                if ((inqbuf.flags3 & SID_Sync) != 0 &&
                    880:                    (quirks & PQUIRK_NOSYNC) == 0)
                    881:                        periph->periph_cap |= PERIPH_CAP_SYNC;
                    882:                if ((inqbuf.flags3 & SID_WBus16) != 0 &&
                    883:                    (quirks & PQUIRK_NOWIDE) == 0)
                    884:                        periph->periph_cap |= PERIPH_CAP_WIDE16;
                    885:                if ((inqbuf.flags3 & SID_WBus32) != 0 &&
                    886:                    (quirks & PQUIRK_NOWIDE) == 0)
                    887:                        periph->periph_cap |= PERIPH_CAP_WIDE32;
                    888:                if ((inqbuf.flags3 & SID_SftRe) != 0)
                    889:                        periph->periph_cap |= PERIPH_CAP_SFTRESET;
                    890:                if ((inqbuf.flags3 & SID_RelAdr) != 0)
                    891:                        periph->periph_cap |= PERIPH_CAP_RELADR;
1.202     fvdl      892:                /* SPC-2 */
                    893:                if (periph->periph_version >= 3 &&
                    894:                    !(quirks & PQUIRK_CAP_NODT)){
1.181     bouyer    895:                        /*
                    896:                         * Report ST clocking though CAP_WIDExx/CAP_SYNC.
                    897:                         * If the device only supports DT, clear these
                    898:                         * flags (DT implies SYNC and WIDE)
                    899:                         */
                    900:                        switch (inqbuf.flags4 & SID_Clocking) {
                    901:                        case SID_CLOCKING_DT_ONLY:
                    902:                                periph->periph_cap &=
                    903:                                    ~(PERIPH_CAP_SYNC |
                    904:                                      PERIPH_CAP_WIDE16 |
                    905:                                      PERIPH_CAP_WIDE32);
                    906:                                /* FALLTHOUGH */
                    907:                        case SID_CLOCKING_SD_DT:
                    908:                                periph->periph_cap |= PERIPH_CAP_DT;
                    909:                                break;
                    910:                        default: /* ST only or invalid */
                    911:                                /* nothing to do */
1.183     thorpej   912:                                break;
1.181     bouyer    913:                        }
1.202     fvdl      914:                }
                    915:                if (periph->periph_version >= 3) {
1.181     bouyer    916:                        if (inqbuf.flags4 & SID_IUS)
                    917:                                periph->periph_cap |= PERIPH_CAP_IUS;
                    918:                        if (inqbuf.flags4 & SID_QAS)
                    919:                                periph->periph_cap |= PERIPH_CAP_QAS;
                    920:                }
1.157     bouyer    921:        }
1.184     bouyer    922:        if (quirks & PQUIRK_CAP_SYNC)
                    923:                periph->periph_cap |= PERIPH_CAP_SYNC;
                    924:        if (quirks & PQUIRK_CAP_WIDE16)
                    925:                periph->periph_cap |= PERIPH_CAP_WIDE16;
1.157     bouyer    926:
                    927:        /*
                    928:         * Now apply any quirks from the table.
                    929:         */
                    930:        periph->periph_quirks |= quirks;
                    931:        if (periph->periph_version == 0 &&
                    932:            (periph->periph_quirks & PQUIRK_FORCELUNS) == 0)
                    933:                periph->periph_quirks |= PQUIRK_NOLUNS;
                    934:
                    935:        if (periph->periph_quirks & PQUIRK_CDROM) {
                    936:                periph->periph_quirks ^= PQUIRK_CDROM;
                    937:                inqbuf.dev_qual2 |= SID_REMOVABLE;
1.167     tsutsui   938:                sa.sa_inqbuf.type = inqbuf.device =
                    939:                    ((inqbuf.device & ~SID_REMOVABLE) | T_CDROM);
1.157     bouyer    940:                sa.sa_inqbuf.removable = T_REMOV;
                    941:        }
                    942:
                    943:        if ((periph->periph_quirks & PQUIRK_NOLUNS) == 0)
                    944:                docontinue = 1;
                    945:
                    946:        if ((cf = config_search(scsibussubmatch, &sc->sc_dev, &sa)) != NULL) {
                    947:                scsipi_insert_periph(chan, periph);
1.149     mjacob    948:                /*
1.157     bouyer    949:                 * XXX Can't assign periph_dev here, because we'll
                    950:                 * XXX need it before config_attach() returns.  Must
                    951:                 * XXX assign it in periph driver.
1.149     mjacob    952:                 */
1.157     bouyer    953:                (void) config_attach(&sc->sc_dev, cf, &sa, scsibusprint);
1.51      thorpej   954:        } else {
1.157     bouyer    955:                scsibusprint(&sa, sc->sc_dev.dv_xname);
1.205     thorpej   956:                aprint_normal(" not configured\n");
1.18      mycroft   957:                goto bad;
1.51      thorpej   958:        }
1.18      mycroft   959:
1.119     mjacob    960:        return (docontinue);
1.12      mycroft   961:
1.18      mycroft   962: bad:
1.157     bouyer    963:        free(periph, M_DEVBUF);
1.119     mjacob    964:        return (docontinue);
1.111     thorpej   965: }
                    966:
                    967: /****** Entry points for user control of the SCSI bus. ******/
                    968:
                    969: int
1.207     fvdl      970: scsibusopen(dev, flag, fmt, p)
1.111     thorpej   971:        dev_t dev;
                    972:        int flag, fmt;
1.207     fvdl      973:        struct proc *p;
1.111     thorpej   974: {
                    975:        struct scsibus_softc *sc;
1.117     thorpej   976:        int error, unit = minor(dev);
1.111     thorpej   977:
                    978:        if (unit >= scsibus_cd.cd_ndevs ||
                    979:            (sc = scsibus_cd.cd_devs[unit]) == NULL)
                    980:                return (ENXIO);
                    981:
1.114     thorpej   982:        if (sc->sc_flags & SCSIBUSF_OPEN)
1.111     thorpej   983:                return (EBUSY);
1.117     thorpej   984:
1.157     bouyer    985:        if ((error = scsipi_adapter_addref(sc->sc_channel->chan_adapter)) != 0)
1.117     thorpej   986:                return (error);
                    987:
1.114     thorpej   988:        sc->sc_flags |= SCSIBUSF_OPEN;
1.111     thorpej   989:
                    990:        return (0);
                    991: }
                    992:
                    993: int
1.207     fvdl      994: scsibusclose(dev, flag, fmt, p)
1.111     thorpej   995:        dev_t dev;
                    996:        int flag, fmt;
1.207     fvdl      997:        struct proc *p;
1.111     thorpej   998: {
                    999:        struct scsibus_softc *sc = scsibus_cd.cd_devs[minor(dev)];
1.117     thorpej  1000:
1.157     bouyer   1001:        scsipi_adapter_delref(sc->sc_channel->chan_adapter);
1.111     thorpej  1002:
1.114     thorpej  1003:        sc->sc_flags &= ~SCSIBUSF_OPEN;
1.111     thorpej  1004:
                   1005:        return (0);
                   1006: }
                   1007:
                   1008: int
1.207     fvdl     1009: scsibusioctl(dev, cmd, addr, flag, p)
1.111     thorpej  1010:        dev_t dev;
                   1011:        u_long cmd;
                   1012:        caddr_t addr;
                   1013:        int flag;
1.207     fvdl     1014:        struct proc *p;
1.111     thorpej  1015: {
                   1016:        struct scsibus_softc *sc = scsibus_cd.cd_devs[minor(dev)];
1.157     bouyer   1017:        struct scsipi_channel *chan = sc->sc_channel;
1.111     thorpej  1018:        int error;
                   1019:
1.113     thorpej  1020:        /*
                   1021:         * Enforce write permission for ioctls that change the
                   1022:         * state of the bus.  Host adapter specific ioctls must
                   1023:         * be checked by the adapter driver.
                   1024:         */
                   1025:        switch (cmd) {
                   1026:        case SCBUSIOSCAN:
1.159     bouyer   1027:        case SCBUSIODETACH:
1.113     thorpej  1028:        case SCBUSIORESET:
                   1029:                if ((flag & FWRITE) == 0)
                   1030:                        return (EBADF);
                   1031:        }
                   1032:
1.111     thorpej  1033:        switch (cmd) {
1.112     thorpej  1034:        case SCBUSIOSCAN:
                   1035:            {
                   1036:                struct scbusioscan_args *a =
                   1037:                    (struct scbusioscan_args *)addr;
                   1038:
1.157     bouyer   1039:                error = scsi_probe_bus(sc, a->sa_target, a->sa_lun);
1.112     thorpej  1040:                break;
                   1041:            }
1.159     bouyer   1042:
                   1043:        case SCBUSIODETACH:
                   1044:            {
                   1045:                struct scbusiodetach_args *a =
                   1046:                    (struct scbusiodetach_args *)addr;
                   1047:
                   1048:                error = scsipi_target_detach(chan, a->sa_target, a->sa_lun, 0);
                   1049:                break;
                   1050:            }
                   1051:
1.112     thorpej  1052:
1.113     thorpej  1053:        case SCBUSIORESET:
                   1054:                /* FALLTHROUGH */
1.111     thorpej  1055:        default:
1.157     bouyer   1056:                if (chan->chan_adapter->adapt_ioctl == NULL)
1.113     thorpej  1057:                        error = ENOTTY;
                   1058:                else
1.157     bouyer   1059:                        error = (*chan->chan_adapter->adapt_ioctl)(chan,
1.207     fvdl     1060:                            cmd, addr, flag, p);
1.113     thorpej  1061:                break;
1.111     thorpej  1062:        }
                   1063:
                   1064:        return (error);
1.1       cgd      1065: }

CVSweb <webmaster@jp.NetBSD.org>