[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.159

1.159   ! bouyer      1: /*     $NetBSD: scsiconf.c,v 1.158 2001/06/11 13:58:18 pk 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:  */
                     56:
1.10      mycroft    57: #include <sys/types.h>
                     58: #include <sys/param.h>
                     59: #include <sys/systm.h>
1.128     thorpej    60: #include <sys/kernel.h>
                     61: #include <sys/proc.h>
1.157     bouyer     62: #include <sys/kthread.h>
1.12      mycroft    63: #include <sys/malloc.h>
                     64: #include <sys/device.h>
1.111     thorpej    65: #include <sys/conf.h>
1.113     thorpej    66: #include <sys/fcntl.h>
1.112     thorpej    67: #include <sys/scsiio.h>
1.10      mycroft    68:
1.88      bouyer     69: #include <dev/scsipi/scsi_all.h>
                     70: #include <dev/scsipi/scsipi_all.h>
                     71: #include <dev/scsipi/scsiconf.h>
1.92      enami      72:
1.88      bouyer     73: #include "locators.h"
1.1       cgd        74:
1.157     bouyer     75: const struct scsipi_periphsw scsi_probe_dev = {
1.12      mycroft    76:        NULL,
                     77:        NULL,
                     78:        NULL,
                     79:        NULL,
                     80: };
                     81:
1.157     bouyer     82: int    scsi_probe_device __P((struct scsibus_softc *, int, int));
                     83:
                     84: int    scsibusmatch __P((struct device *, struct cfdata *, void *));
                     85: void   scsibusattach __P((struct device *, struct device *, void *));
                     86: int    scsibusactivate __P((struct device *, enum devact));
                     87: int    scsibusdetach __P((struct device *, int flags));
1.126     thorpej    88:
1.157     bouyer     89: int    scsibussubmatch __P((struct device *, struct cfdata *, void *));
1.12      mycroft    90:
1.53      thorpej    91: struct cfattach scsibus_ca = {
1.126     thorpej    92:        sizeof(struct scsibus_softc), scsibusmatch, scsibusattach,
                     93:            scsibusdetach, scsibusactivate,
1.53      thorpej    94: };
                     95:
1.94      thorpej    96: extern struct cfdriver scsibus_cd;
1.12      mycroft    97:
1.157     bouyer     98: int    scsibusprint __P((void *, const char *));
                     99: void   scsibus_config_interrupts __P((struct device *));
1.51      thorpej   100:
1.111     thorpej   101: cdev_decl(scsibus);
1.62      cgd       102:
1.157     bouyer    103: const struct scsipi_bustype scsi_bustype = {
                    104:        SCSIPI_BUSTYPE_SCSI,
                    105:        scsi_scsipi_cmd,
                    106:        scsipi_interpret_sense,
                    107:        scsi_print_addr,
                    108:        scsi_kill_pending,
                    109: };
                    110:
                    111: int
                    112: scsiprint(aux, pnp)
                    113:        void *aux;
                    114:        const char *pnp;
                    115: {
                    116:        struct scsipi_channel *chan = aux;
                    117:        struct scsipi_adapter *adapt = chan->chan_adapter;
                    118:
                    119:        /* only "scsibus"es can attach to "scsi"s; easy. */
                    120:        if (pnp)
                    121:                printf("scsibus at %s", pnp);
                    122:
                    123:        /* don't print channel if the controller says there can be only one. */
                    124:        if (adapt->adapt_nchannels != 1)
                    125:                printf(" channel %d", chan->chan_channel);
                    126:
                    127:        return (UNCONF);
                    128: }
                    129:
1.62      cgd       130: int
1.71      cgd       131: scsibusmatch(parent, cf, aux)
1.62      cgd       132:        struct device *parent;
1.71      cgd       133:        struct cfdata *cf;
                    134:        void *aux;
1.12      mycroft   135: {
1.157     bouyer    136:        struct scsipi_channel *chan = aux;
1.62      cgd       137:
1.157     bouyer    138:        if (chan->type != BUS_SCSI)
                    139:                return 0;
1.62      cgd       140:
1.157     bouyer    141:        if (cf->cf_loc[SCSICF_CHANNEL] != chan->chan_channel &&
1.92      enami     142:            cf->cf_loc[SCSICF_CHANNEL] != SCSICF_CHANNEL_DEFAULT)
1.62      cgd       143:                return (0);
1.12      mycroft   144:
1.62      cgd       145:        return (1);
1.12      mycroft   146: }
                    147:
                    148: void
                    149: scsibusattach(parent, self, aux)
1.88      bouyer    150:        struct device *parent, *self;
                    151:        void *aux;
1.12      mycroft   152: {
1.157     bouyer    153:        struct scsibus_softc *sc = (void *) self;
                    154:        struct scsipi_channel *chan = aux;
1.103     thorpej   155:
1.157     bouyer    156:        sc->sc_channel = chan;
1.72      thorpej   157:
1.157     bouyer    158:        /* Initialize the channel structure first */
                    159:        if (scsipi_channel_init(chan)) {
                    160:                printf(": failed to init channel\n");
                    161:                return;
1.72      thorpej   162:        }
1.12      mycroft   163:
1.157     bouyer    164:        printf(": %d targets, %d luns per target\n",
                    165:            chan->chan_ntargets, chan->chan_nluns);
                    166:
                    167:
1.128     thorpej   168:        /*
                    169:         * Defer configuration of the children until interrupts
                    170:         * are enabled.
                    171:         */
                    172:        config_interrupts(self, scsibus_config_interrupts);
                    173: }
                    174:
                    175: void
                    176: scsibus_config_interrupts(self)
                    177:        struct device *self;
                    178: {
1.157     bouyer    179:        struct scsibus_softc *sc = (void *) self;
                    180:
1.132     soren     181: #ifndef SCSI_DELAY
1.12      mycroft   182: #define SCSI_DELAY 2
1.132     soren     183: #endif
1.157     bouyer    184:
                    185:        if ((sc->sc_channel->chan_flags & SCSIPI_CHAN_NOSETTLE) == 0 &&
                    186:            SCSI_DELAY > 0) {
1.128     thorpej   187:                printf("%s: waiting %d seconds for devices to settle...\n",
                    188:                    self->dv_xname, SCSI_DELAY);
                    189:                /* ...an identifier we know no one will use... */
                    190:                (void) tsleep(scsibus_config_interrupts, PRIBIO,
                    191:                    "scsidly", SCSI_DELAY * hz);
                    192:        }
                    193:
1.157     bouyer    194:        scsi_probe_bus(sc, -1, -1);
1.12      mycroft   195: }
                    196:
1.18      mycroft   197: int
1.71      cgd       198: scsibussubmatch(parent, cf, aux)
1.18      mycroft   199:        struct device *parent;
1.71      cgd       200:        struct cfdata *cf;
                    201:        void *aux;
1.18      mycroft   202: {
1.88      bouyer    203:        struct scsipibus_attach_args *sa = aux;
1.157     bouyer    204:        struct scsipi_periph *periph = sa->sa_periph;
1.18      mycroft   205:
1.88      bouyer    206:        if (cf->cf_loc[SCSIBUSCF_TARGET] != SCSIBUSCF_TARGET_DEFAULT &&
1.157     bouyer    207:            cf->cf_loc[SCSIBUSCF_TARGET] != periph->periph_target)
1.92      enami     208:                return (0);
1.88      bouyer    209:        if (cf->cf_loc[SCSIBUSCF_LUN] != SCSIBUSCF_LUN_DEFAULT &&
1.157     bouyer    210:            cf->cf_loc[SCSIBUSCF_LUN] != periph->periph_lun)
1.92      enami     211:                return (0);
1.71      cgd       212:        return ((*cf->cf_attach->ca_match)(parent, cf, aux));
1.126     thorpej   213: }
                    214:
                    215: int
                    216: scsibusactivate(self, act)
                    217:        struct device *self;
                    218:        enum devact act;
                    219: {
1.157     bouyer    220:        struct scsibus_softc *sc = (void *) self;
                    221:        struct scsipi_channel *chan = sc->sc_channel;
                    222:        struct scsipi_periph *periph;
1.126     thorpej   223:        int target, lun, error = 0, s;
                    224:
                    225:        s = splbio();
                    226:        switch (act) {
                    227:        case DVACT_ACTIVATE:
                    228:                error = EOPNOTSUPP;
                    229:                break;
                    230:
                    231:        case DVACT_DEACTIVATE:
1.157     bouyer    232:                for (target = 0; target < chan->chan_ntargets;
                    233:                     target++) {
                    234:                        if (target == chan->chan_id)
1.126     thorpej   235:                                continue;
1.157     bouyer    236:                        for (lun = 0; lun < chan->chan_nluns; lun++) {
                    237:                                periph = scsipi_lookup_periph(chan,
                    238:                                    target, lun);
                    239:                                if (periph == NULL)
1.126     thorpej   240:                                        continue;
1.157     bouyer    241:                                error = config_deactivate(periph->periph_dev);
1.126     thorpej   242:                                if (error)
                    243:                                        goto out;
                    244:                        }
                    245:                }
                    246:                break;
                    247:        }
                    248:  out:
                    249:        splx(s);
                    250:        return (error);
                    251: }
                    252:
                    253: int
                    254: scsibusdetach(self, flags)
                    255:        struct device *self;
                    256:        int flags;
                    257: {
1.157     bouyer    258:        struct scsibus_softc *sc = (void *) self;
                    259:        struct scsipi_channel *chan = sc->sc_channel;
1.126     thorpej   260:
1.157     bouyer    261:        /*
                    262:         * Shut down the channel.
                    263:         */
                    264:        scsipi_channel_shutdown(chan);
                    265:
                    266:        /*
                    267:         * Now detach all of the periphs.
                    268:         */
1.159   ! bouyer    269:        return scsipi_target_detach(chan, -1, -1, flags);
1.18      mycroft   270: }
                    271:
1.12      mycroft   272: /*
                    273:  * Probe the requested scsi bus. It must be already set up.
1.18      mycroft   274:  * target and lun optionally narrow the search if not -1
1.12      mycroft   275:  */
                    276: int
1.157     bouyer    277: scsi_probe_bus(sc, target, lun)
                    278:        struct scsibus_softc *sc;
                    279:        int target, lun;
1.12      mycroft   280: {
1.157     bouyer    281:        struct scsipi_channel *chan = sc->sc_channel;
1.18      mycroft   282:        int maxtarget, mintarget, maxlun, minlun;
1.116     thorpej   283:        int error;
1.12      mycroft   284:
1.18      mycroft   285:        if (target == -1) {
1.157     bouyer    286:                maxtarget = chan->chan_ntargets - 1;
1.18      mycroft   287:                mintarget = 0;
1.12      mycroft   288:        } else {
1.157     bouyer    289:                if (target < 0 || target >= chan->chan_ntargets)
1.92      enami     290:                        return (EINVAL);
1.18      mycroft   291:                maxtarget = mintarget = target;
1.12      mycroft   292:        }
1.1       cgd       293:
1.12      mycroft   294:        if (lun == -1) {
1.157     bouyer    295:                maxlun = chan->chan_nluns - 1;
1.12      mycroft   296:                minlun = 0;
                    297:        } else {
1.157     bouyer    298:                if (lun < 0 || lun >= chan->chan_nluns)
1.92      enami     299:                        return (EINVAL);
1.12      mycroft   300:                maxlun = minlun = lun;
                    301:        }
                    302:
1.153     ad        303:        /*
                    304:         * Some HBAs provide an abstracted view of the bus; give them an
                    305:         * oppertunity to re-scan it before we do.
                    306:         */
1.157     bouyer    307:        if (chan->chan_adapter->adapt_ioctl != NULL)
                    308:                (*chan->chan_adapter->adapt_ioctl)(chan, SCBUSIOLLSCAN, NULL,
1.153     ad        309:                    0, curproc);
                    310:
1.157     bouyer    311:        if ((error = scsipi_adapter_addref(chan->chan_adapter)) != 0)
1.116     thorpej   312:                return (error);
1.18      mycroft   313:        for (target = mintarget; target <= maxtarget; target++) {
1.157     bouyer    314:                if (target == chan->chan_id)
1.12      mycroft   315:                        continue;
                    316:                for (lun = minlun; lun <= maxlun; lun++) {
                    317:                        /*
1.18      mycroft   318:                         * See if there's a device present, and configure it.
1.12      mycroft   319:                         */
1.157     bouyer    320:                        if (scsi_probe_device(sc, target, lun) == 0)
1.18      mycroft   321:                                break;
1.12      mycroft   322:                        /* otherwise something says we should look further */
                    323:                }
1.157     bouyer    324:
                    325:                /*
                    326:                 * Now that we've discovered all of the LUNs on this
                    327:                 * I_T Nexus, update the xfer mode for all of them
                    328:                 * that we know about.
                    329:                 */
                    330:                scsipi_set_xfer_mode(chan, target, 1);
1.8       deraadt   331:        }
1.157     bouyer    332:        scsipi_adapter_delref(chan->chan_adapter);
1.92      enami     333:        return (0);
1.12      mycroft   334: }
                    335:
1.88      bouyer    336: /*
                    337:  * Print out autoconfiguration information for a subdevice.
                    338:  *
                    339:  * This is a slight abuse of 'standard' autoconfiguration semantics,
                    340:  * because 'print' functions don't normally print the colon and
                    341:  * device information.  However, in this case that's better than
                    342:  * either printing redundant information before the attach message,
                    343:  * or having the device driver call a special function to print out
                    344:  * the standard device information.
                    345:  */
                    346: int
                    347: scsibusprint(aux, pnp)
                    348:        void *aux;
                    349:        const char *pnp;
1.12      mycroft   350: {
1.88      bouyer    351:        struct scsipibus_attach_args *sa = aux;
                    352:        struct scsipi_inquiry_pattern *inqbuf;
                    353:        u_int8_t type;
1.157     bouyer    354:        const char *dtype, *qtype;
1.88      bouyer    355:        char vendor[33], product[65], revision[17];
                    356:        int target, lun;
                    357:
                    358:        if (pnp != NULL)
                    359:                printf("%s", pnp);
                    360:
                    361:        inqbuf = &sa->sa_inqbuf;
                    362:
1.157     bouyer    363:        target = sa->sa_periph->periph_target;
                    364:        lun = sa->sa_periph->periph_lun;
1.88      bouyer    365:        type = inqbuf->type & SID_TYPE;
                    366:
                    367:        /*
                    368:         * Figure out basic device type and qualifier.
                    369:         */
                    370:        dtype = 0;
                    371:        switch (inqbuf->type & SID_QUAL) {
1.157     bouyer    372:        case SID_QUAL_LU_PRESENT:
1.88      bouyer    373:                qtype = "";
                    374:                break;
                    375:
1.157     bouyer    376:        case SID_QUAL_LU_NOTPRESENT:
1.88      bouyer    377:                qtype = " offline";
                    378:                break;
                    379:
1.157     bouyer    380:        case SID_QUAL_reserved:
                    381:        case SID_QUAL_LU_NOT_SUPP:
1.88      bouyer    382:                panic("scsibusprint: impossible qualifier");
1.12      mycroft   383:
1.88      bouyer    384:        default:
                    385:                qtype = "";
                    386:                dtype = "vendor-unique";
                    387:                break;
                    388:        }
1.157     bouyer    389:        if (dtype == NULL)
1.88      bouyer    390:                dtype = scsipi_dtype(type);
1.2       deraadt   391:
1.104     drochner  392:        scsipi_strvis(vendor, 33, inqbuf->vendor, 8);
                    393:        scsipi_strvis(product, 65, inqbuf->product, 16);
                    394:        scsipi_strvis(revision, 17, inqbuf->revision, 4);
1.88      bouyer    395:
1.138     augustss  396:        printf(" target %d lun %d: <%s, %s, %s> SCSI%d %d/%s %s%s",
1.92      enami     397:            target, lun, vendor, product, revision,
                    398:            sa->scsipi_info.scsi_version & SID_ANSII, type, dtype,
                    399:            inqbuf->removable ? "removable" : "fixed", qtype);
1.88      bouyer    400:
                    401:        return (UNCONF);
1.12      mycroft   402: }
1.1       cgd       403:
1.154     jdolecek  404: const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
1.48      christos  405:        {{T_CDROM, T_REMOV,
1.157     bouyer    406:         "CHINON  ", "CD-ROM CDS-431  ", ""},     PQUIRK_NOLUNS},
1.48      christos  407:        {{T_CDROM, T_REMOV,
1.157     bouyer    408:         "Chinon  ", "CD-ROM CDS-525  ", ""},     PQUIRK_NOLUNS},
1.48      christos  409:        {{T_CDROM, T_REMOV,
1.157     bouyer    410:         "CHINON  ", "CD-ROM CDS-535  ", ""},     PQUIRK_NOLUNS},
1.100     thorpej   411:        {{T_CDROM, T_REMOV,
1.157     bouyer    412:         "DEC     ", "RRD42   (C) DEC ", ""},     PQUIRK_NOLUNS},
1.48      christos  413:        {{T_CDROM, T_REMOV,
1.157     bouyer    414:         "DENON   ", "DRD-25X         ", "V"},    PQUIRK_NOLUNS},
1.148     bouyer    415:        {{T_CDROM, T_REMOV,
1.157     bouyer    416:         "GENERIC ", "CRD-BP2         ", ""},     PQUIRK_NOLUNS},
1.83      mycroft   417:        {{T_CDROM, T_REMOV,
1.157     bouyer    418:         "HP      ", "C4324/C4325     ", ""},     PQUIRK_NOLUNS},
1.48      christos  419:        {{T_CDROM, T_REMOV,
1.157     bouyer    420:         "IMS     ", "CDD521/10       ", "2.06"}, PQUIRK_NOLUNS},
1.48      christos  421:        {{T_CDROM, T_REMOV,
1.157     bouyer    422:         "MATSHITA", "CD-ROM CR-5XX   ", "1.0b"}, PQUIRK_NOLUNS},
1.68      mikel     423:        {{T_CDROM, T_REMOV,
1.157     bouyer    424:         "MEDAVIS ", "RENO CD-ROMX2A  ", ""},     PQUIRK_NOLUNS},
1.84      perry     425:        {{T_CDROM, T_REMOV,
1.157     bouyer    426:         "MEDIAVIS", "CDR-H93MV       ", "1.3"},  PQUIRK_NOLUNS},
1.48      christos  427:        {{T_CDROM, T_REMOV,
1.157     bouyer    428:         "NEC     ", "CD-ROM DRIVE:55 ", ""},     PQUIRK_NOLUNS},
1.48      christos  429:        {{T_CDROM, T_REMOV,
1.157     bouyer    430:         "NEC     ", "CD-ROM DRIVE:83 ", ""},     PQUIRK_NOLUNS},
1.48      christos  431:        {{T_CDROM, T_REMOV,
1.157     bouyer    432:         "NEC     ", "CD-ROM DRIVE:84 ", ""},     PQUIRK_NOLUNS},
1.48      christos  433:        {{T_CDROM, T_REMOV,
1.157     bouyer    434:         "NEC     ", "CD-ROM DRIVE:841", ""},     PQUIRK_NOLUNS},
1.70      thorpej   435:        {{T_CDROM, T_REMOV,
1.157     bouyer    436:         "PIONEER ", "CD-ROM DR-124X  ", "1.01"}, PQUIRK_NOLUNS},
1.48      christos  437:        {{T_CDROM, T_REMOV,
1.157     bouyer    438:         "SONY    ", "CD-ROM CDU-541  ", ""},     PQUIRK_NOLUNS},
1.48      christos  439:        {{T_CDROM, T_REMOV,
1.157     bouyer    440:         "SONY    ", "CD-ROM CDU-55S  ", ""},     PQUIRK_NOLUNS},
1.130     hwr       441:        {{T_CDROM, T_REMOV,
1.157     bouyer    442:         "SONY    ", "CD-ROM CDU-561  ", ""},     PQUIRK_NOLUNS},
1.48      christos  443:        {{T_CDROM, T_REMOV,
1.157     bouyer    444:         "SONY    ", "CD-ROM CDU-8003A", ""},     PQUIRK_NOLUNS},
1.48      christos  445:        {{T_CDROM, T_REMOV,
1.157     bouyer    446:         "SONY    ", "CD-ROM CDU-8012 ", ""},     PQUIRK_NOLUNS},
1.48      christos  447:        {{T_CDROM, T_REMOV,
1.157     bouyer    448:         "TEAC    ", "CD-ROM          ", "1.06"}, PQUIRK_NOLUNS},
1.69      explorer  449:        {{T_CDROM, T_REMOV,
1.157     bouyer    450:         "TEAC    ", "CD-ROM CD-56S   ", "1.0B"}, PQUIRK_NOLUNS},
1.48      christos  451:        {{T_CDROM, T_REMOV,
1.157     bouyer    452:         "TEXEL   ", "CD-ROM          ", "1.06"}, PQUIRK_NOLUNS},
1.127     nathanw   453:        {{T_CDROM, T_REMOV,
1.157     bouyer    454:         "TEXEL   ", "CD-ROM DM-XX24 K", "1.09"}, PQUIRK_NOLUNS},
1.48      christos  455:        {{T_CDROM, T_REMOV,
1.157     bouyer    456:         "TEXEL   ", "CD-ROM DM-XX24 K", "1.10"}, PQUIRK_NOLUNS},
1.89      pk        457:        {{T_CDROM, T_REMOV,
1.157     bouyer    458:         "TOSHIBA ", "XM-4101TASUNSLCD", "1755"}, PQUIRK_NOLUNS|PQUIRK_NOSYNC},
1.158     pk        459:        /* "IBM CDRM00201     !F" 0724 is an IBM OEM Toshiba XM-4101BME */
                    460:        {{T_CDROM, T_REMOV,
                    461:         "IBM     ", "CDRM00201     !F", "0724"}, PQUIRK_NOLUNS|PQUIRK_NOSYNC},
1.92      enami     462:        {{T_CDROM, T_REMOV,
1.157     bouyer    463:         "ShinaKen", "CD-ROM DM-3x1S", "1.04"},   PQUIRK_NOLUNS},
1.98      explorer  464:        {{T_CDROM, T_REMOV,
1.157     bouyer    465:         "JVC     ", "R2626",            ""},     PQUIRK_NOLUNS},
1.137     sjg       466:        {{T_CDROM, T_REMOV,
1.157     bouyer    467:         "YAMAHA", "CRW8424S",           ""},     PQUIRK_NOLUNS},
1.156     fvdl      468:        {{T_CDROM, T_REMOV,
                    469:         "VMware", "Virtual",           "1.0"},
1.157     bouyer    470:                                PQUIRK_NOSTARTUNIT|PQUIRK_NODOORLOCK},
1.156     fvdl      471:
1.80      pk        472:        {{T_DIRECT, T_FIXED,
1.157     bouyer    473:         "MICROP  ", "1588-15MBSUN0669", ""},     PQUIRK_AUTOSAVE},
1.110     thorpej   474:        {{T_DIRECT, T_FIXED,
1.157     bouyer    475:         "MICROP  ", "2217-15MQ1091501", ""},     PQUIRK_NOSYNCCACHE},
1.55      scottr    476:        {{T_OPTICAL, T_REMOV,
1.157     bouyer    477:         "EPSON   ", "OMD-5010        ", "3.08"}, PQUIRK_NOLUNS},
1.129     hwr       478:        {{T_DIRECT, T_FIXED,
1.157     bouyer    479:         "TOSHIBA ","CD-ROM XM-3401TA", "0283"},  PQUIRK_CDROM|PQUIRK_NOLUNS},
1.122     mjacob    480:        {{T_DIRECT, T_FIXED,
1.157     bouyer    481:         "TOSHIBA ", "CD-ROM DRIVE:XM", "1971"}, PQUIRK_CDROM|PQUIRK_NOLUNS},
1.143     gmcgarry  482:        {{T_DIRECT, T_FIXED,
1.157     bouyer    483:         "ADAPTEC ", "AEC-4412BD",       "1.2A"}, PQUIRK_NOMODESENSE},
1.50      mycroft   484:        {{T_DIRECT, T_FIXED,
1.157     bouyer    485:         "DEC     ", "RZ55     (C) DEC", ""},     PQUIRK_AUTOSAVE},
1.48      christos  486:        {{T_DIRECT, T_FIXED,
1.157     bouyer    487:         "EMULEX  ", "MD21/S2     ESDI", "A00"},  PQUIRK_FORCELUNS|PQUIRK_AUTOSAVE},
1.91      bouyer    488:        /* Gives non-media hardware failure in response to start-unit command */
                    489:        {{T_DIRECT, T_FIXED,
1.157     bouyer    490:         "HITACHI", "DK515C",           "CP16"},  PQUIRK_NOSTARTUNIT},
1.91      bouyer    491:        {{T_DIRECT, T_FIXED,
1.157     bouyer    492:         "HITACHI", "DK515C",           "CP15"},  PQUIRK_NOSTARTUNIT},
1.76      scottr    493:        {{T_DIRECT, T_FIXED,
1.157     bouyer    494:         "HP      ", "C372",             ""},     PQUIRK_NOTAG},
1.108     mjacob    495:        {{T_DIRECT, T_FIXED,
1.157     bouyer    496:         "IBMRAID ", "0662S",            ""},     PQUIRK_AUTOSAVE},
1.76      scottr    497:        {{T_DIRECT, T_FIXED,
1.157     bouyer    498:         "IBM     ", "0663H",            ""},     PQUIRK_AUTOSAVE},
1.82      thorpej   499:        {{T_DIRECT, T_FIXED,
1.157     bouyer    500:         "IBM",      "0664",             ""},     PQUIRK_AUTOSAVE},
1.84      perry     501:        {{T_DIRECT, T_FIXED,
1.157     bouyer    502:         "IBM     ", "H3171-S2",         ""},     PQUIRK_NOLUNS|PQUIRK_AUTOSAVE},
1.96      scottr    503:        {{T_DIRECT, T_FIXED,
1.157     bouyer    504:         "IBM     ", "KZ-C",             ""},     PQUIRK_AUTOSAVE},
1.81      thorpej   505:        /* Broken IBM disk */
                    506:        {{T_DIRECT, T_FIXED,
1.157     bouyer    507:         ""        , "DFRSS2F",          ""},     PQUIRK_AUTOSAVE},
1.87      mjacob    508:        {{T_DIRECT, T_REMOV,
1.157     bouyer    509:         "MPL     ", "MC-DISK-        ", ""},     PQUIRK_NOLUNS},
1.48      christos  510:        {{T_DIRECT, T_FIXED,
1.157     bouyer    511:         "MAXTOR  ", "XT-3280         ", ""},     PQUIRK_NOLUNS},
1.48      christos  512:        {{T_DIRECT, T_FIXED,
1.157     bouyer    513:         "MAXTOR  ", "XT-4380S        ", ""},     PQUIRK_NOLUNS},
1.48      christos  514:        {{T_DIRECT, T_FIXED,
1.157     bouyer    515:         "MAXTOR  ", "MXT-1240S       ", ""},     PQUIRK_NOLUNS},
1.48      christos  516:        {{T_DIRECT, T_FIXED,
1.157     bouyer    517:         "MAXTOR  ", "XT-4170S        ", ""},     PQUIRK_NOLUNS},
1.48      christos  518:        {{T_DIRECT, T_FIXED,
1.157     bouyer    519:         "MAXTOR  ", "XT-8760S",         ""},     PQUIRK_NOLUNS},
1.48      christos  520:        {{T_DIRECT, T_FIXED,
1.157     bouyer    521:         "MAXTOR  ", "LXT-213S        ", ""},     PQUIRK_NOLUNS},
1.48      christos  522:        {{T_DIRECT, T_FIXED,
1.157     bouyer    523:         "MAXTOR  ", "LXT-213S SUN0207", ""},     PQUIRK_NOLUNS},
1.52      thorpej   524:        {{T_DIRECT, T_FIXED,
1.157     bouyer    525:         "MAXTOR  ", "LXT-200S        ", ""},     PQUIRK_NOLUNS},
1.48      christos  526:        {{T_DIRECT, T_FIXED,
1.157     bouyer    527:         "MEGADRV ", "EV1000",           ""},     PQUIRK_NOMODESENSE},
1.90      mjacob    528:        {{T_DIRECT, T_FIXED,
1.157     bouyer    529:         "MST     ", "SnapLink        ", ""},     PQUIRK_NOLUNS},
1.54      hpeyerl   530:        {{T_DIRECT, T_FIXED,
1.157     bouyer    531:         "NEC     ", "D3847           ", "0307"}, PQUIRK_NOLUNS},
1.96      scottr    532:        {{T_DIRECT, T_FIXED,
1.157     bouyer    533:         "QUANTUM ", "ELS85S          ", ""},     PQUIRK_AUTOSAVE},
1.48      christos  534:        {{T_DIRECT, T_FIXED,
1.157     bouyer    535:         "QUANTUM ", "LPS525S         ", ""},     PQUIRK_NOLUNS},
1.48      christos  536:        {{T_DIRECT, T_FIXED,
1.157     bouyer    537:         "QUANTUM ", "P105S 910-10-94x", ""},     PQUIRK_NOLUNS},
1.48      christos  538:        {{T_DIRECT, T_FIXED,
1.157     bouyer    539:         "QUANTUM ", "PD1225S         ", ""},     PQUIRK_NOLUNS},
1.48      christos  540:        {{T_DIRECT, T_FIXED,
1.157     bouyer    541:         "QUANTUM ", "PD210S   SUN0207", ""},     PQUIRK_NOLUNS},
1.48      christos  542:        {{T_DIRECT, T_FIXED,
1.157     bouyer    543:         "RODIME  ", "RO3000S         ", ""},     PQUIRK_NOLUNS},
1.75      scottr    544:        {{T_DIRECT, T_FIXED,
1.157     bouyer    545:         "SEAGATE ", "ST125N          ", ""},     PQUIRK_NOLUNS},
1.48      christos  546:        {{T_DIRECT, T_FIXED,
1.157     bouyer    547:         "SEAGATE ", "ST157N          ", ""},     PQUIRK_NOLUNS},
1.48      christos  548:        {{T_DIRECT, T_FIXED,
1.157     bouyer    549:         "SEAGATE ", "ST296           ", ""},     PQUIRK_NOLUNS},
1.48      christos  550:        {{T_DIRECT, T_FIXED,
1.157     bouyer    551:         "SEAGATE ", "ST296N          ", ""},     PQUIRK_NOLUNS},
1.86      mjacob    552:        {{T_DIRECT, T_FIXED,
1.157     bouyer    553:         "SEAGATE ", "ST19171",          ""},     PQUIRK_NOMODESENSE},
1.90      mjacob    554:        {{T_DIRECT, T_FIXED,
1.157     bouyer    555:         "SEAGATE ", "ST34501FC       ", ""},     PQUIRK_NOMODESENSE},
1.48      christos  556:        {{T_DIRECT, T_FIXED,
1.157     bouyer    557:         "TOSHIBA ", "MK538FB         ", "6027"}, PQUIRK_NOLUNS},
1.156     fvdl      558:        {{T_DIRECT, T_FIXED,
                    559:         "VMware", "Virtual",           "1.0"},
1.157     bouyer    560:                                PQUIRK_NOSTARTUNIT|PQUIRK_NODOORLOCK},
1.156     fvdl      561:
1.58      christos  562:        {{T_DIRECT, T_REMOV,
1.157     bouyer    563:         "iomega", "jaz 1GB",            ""},     PQUIRK_NOMODESENSE},
1.59      explorer  564:        {{T_DIRECT, T_REMOV,
1.157     bouyer    565:         "IOMEGA", "ZIP 100",            ""},     PQUIRK_NOMODESENSE},
1.118     leo       566:        {{T_DIRECT, T_REMOV,
1.157     bouyer    567:         "IOMEGA", "ZIP 100",            "J.03"}, PQUIRK_NOMODESENSE|PQUIRK_NOLUNS},
1.85      explorer  568:        /* Letting the motor run kills floppy drives and disks quite fast. */
1.67      matthias  569:        {{T_DIRECT, T_REMOV,
1.157     bouyer    570:         "TEAC", "FC-1",                 ""},     PQUIRK_NOSTARTUNIT},
1.145     augustss  571:
                    572:        {{T_DIRECT, T_REMOV,
1.157     bouyer    573:         "Y-E DATA", "USB-FDU",          "3.04"}, PQUIRK_NOMODESENSE},
1.146     augustss  574:        {{T_DIRECT, T_REMOV,
1.157     bouyer    575:         "TEAC", "FD-05PUB",             "1026"}, PQUIRK_NOMODESENSE},
1.18      mycroft   576:
1.37      cgd       577:        /* XXX: QIC-36 tape behind Emulex adapter.  Very broken. */
1.48      christos  578:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    579:         "        ", "                ", "    "}, PQUIRK_NOLUNS},
1.48      christos  580:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    581:         "CALIPER ", "CP150           ", ""},     PQUIRK_NOLUNS},
1.48      christos  582:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    583:         "EXABYTE ", "EXB-8200        ", ""},     PQUIRK_NOLUNS},
1.48      christos  584:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    585:         "SONY    ", "GY-10C          ", ""},     PQUIRK_NOLUNS},
1.87      mjacob    586:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    587:         "SONY    ", "SDT-2000        ", "2.09"}, PQUIRK_NOLUNS},
1.48      christos  588:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    589:         "SONY    ", "SDT-5000        ", "3."},   PQUIRK_NOSYNC|PQUIRK_NOWIDE},
1.48      christos  590:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    591:         "SONY    ", "SDT-5200        ", "3."},   PQUIRK_NOLUNS},
1.48      christos  592:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    593:         "TANDBERG", " TDC 3600       ", ""},     PQUIRK_NOLUNS},
1.47      pk        594:        /* Following entry reported as a Tandberg 3600; ref. PR1933 */
1.48      christos  595:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    596:         "ARCHIVE ", "VIPER 150  21247", ""},     PQUIRK_NOLUNS},
1.91      bouyer    597:        /* Following entry for a Cipher ST150S; ref. PR4171 */
                    598:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    599:         "ARCHIVE ", "VIPER 1500 21247", "2.2G"}, PQUIRK_NOLUNS},
1.80      pk        600:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    601:         "ARCHIVE ", "Python 28454-XXX", ""},     PQUIRK_NOLUNS},
1.48      christos  602:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    603:         "WANGTEK ", "5099ES SCSI",      ""},     PQUIRK_NOLUNS},
1.48      christos  604:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    605:         "WANGTEK ", "5150ES SCSI",      ""},     PQUIRK_NOLUNS},
1.125     hwr       606:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    607:         "WANGTEK ", "SCSI-36",          ""},     PQUIRK_NOLUNS},
1.48      christos  608:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    609:         "WangDAT ", "Model 1300      ", "02.4"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE},
1.48      christos  610:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    611:         "WangDAT ", "Model 2600      ", "01.7"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE},
1.48      christos  612:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    613:         "WangDAT ", "Model 3200      ", "02.2"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE},
1.133     nisimura  614:        {{T_SEQUENTIAL, T_REMOV,
1.157     bouyer    615:         "TEAC    ", "MT-2ST/N50      ", ""},     PQUIRK_NOLUNS},
1.87      mjacob    616:
1.101     bouyer    617:        {{T_SCANNER, T_FIXED,
1.157     bouyer    618:         "RICOH   ", "IS60            ", "1R08"}, PQUIRK_NOLUNS},
1.99      thorpej   619:        {{T_SCANNER, T_FIXED,
1.157     bouyer    620:         "UMAX    ", "Astra 1200S     ", "V2.9"}, PQUIRK_NOLUNS},
1.102     fvdl      621:        {{T_SCANNER, T_FIXED,
1.157     bouyer    622:         "UMAX    ", "Astra 1220S     ", ""},     PQUIRK_NOLUNS},
1.85      explorer  623:        {{T_SCANNER, T_FIXED,
1.157     bouyer    624:         "UMAX    ", "UMAX S-6E       ", "V2.0"}, PQUIRK_NOLUNS},
1.95      mikel     625:        {{T_SCANNER, T_FIXED,
1.157     bouyer    626:         "UMAX    ", "UMAX S-12       ", "V2.1"}, PQUIRK_NOLUNS},
1.135     martin    627:        {{T_SCANNER, T_FIXED,
1.157     bouyer    628:         "ULTIMA  ", "A6000C          ", ""}, PQUIRK_NOLUNS},
1.150     mjacob    629:        {{T_PROCESSOR, T_FIXED,
1.157     bouyer    630:         "SYMBIOS", "", ""},     PQUIRK_NOLUNS},
1.87      mjacob    631:        {{T_PROCESSOR, T_FIXED,
1.157     bouyer    632:         "LITRONIC", "PCMCIA          ", ""},     PQUIRK_NOLUNS},
1.109     thorpej   633:        {{T_CHANGER, T_REMOV,
1.157     bouyer    634:         "SONY    ", "CDL1100         ", ""},     PQUIRK_NOLUNS},
1.119     mjacob    635:        {{T_ENCLOSURE, T_FIXED,
1.157     bouyer    636:         "SUN     ", "SENA            ", ""}, PQUIRK_NOLUNS},
1.18      mycroft   637: };
                    638:
1.12      mycroft   639: /*
1.95      mikel     640:  * given a target and lun, ask the device what
1.12      mycroft   641:  * it is, and find the correct driver table
                    642:  * entry.
                    643:  */
1.119     mjacob    644: int
1.157     bouyer    645: scsi_probe_device(sc, target, lun)
                    646:        struct scsibus_softc *sc;
1.18      mycroft   647:        int target, lun;
                    648: {
1.157     bouyer    649:        struct scsipi_channel *chan = sc->sc_channel;
                    650:        struct scsipi_periph *periph;
1.140     enami     651:        struct scsipi_inquiry_data inqbuf;
1.18      mycroft   652:        struct scsi_quirk_inquiry_pattern *finger;
1.157     bouyer    653:        int checkdtype, priority, docontinue, quirks;
1.88      bouyer    654:        struct scsipibus_attach_args sa;
1.18      mycroft   655:        struct cfdata *cf;
                    656:
1.119     mjacob    657:        /*
                    658:         * Assume no more luns to search after this one.
                    659:         * If we successfully get Inquiry data and after
                    660:         * merging quirks we find we can probe for more
                    661:         * luns, we will.
                    662:         */
                    663:        docontinue = 0;
                    664:
1.18      mycroft   665:        /* Skip this slot if it is already attached. */
1.157     bouyer    666:        if (scsipi_lookup_periph(chan, target, lun) != NULL)
1.119     mjacob    667:                return (docontinue);
1.18      mycroft   668:
1.157     bouyer    669:        periph = scsipi_alloc_periph(M_NOWAIT);
                    670:        if (periph == NULL) {
                    671: #ifdef DIAGNOSTIC
                    672:                printf("%s: cannot allocate periph for target %d lun %d\n",
                    673:                    sc->sc_dev.dv_xname, target, lun);
                    674: #endif
                    675:                return (ENOMEM);
                    676:        }
                    677:        periph->periph_channel = chan;
                    678:        periph->periph_switch = &scsi_probe_dev;
                    679:
                    680:        periph->periph_target = target;
                    681:        periph->periph_lun = lun;
                    682:        periph->periph_quirks = chan->chan_defquirks;
                    683:
                    684: #ifdef SCSIPI_DEBUG
                    685:        if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_SCSI &&
                    686:            SCSIPI_DEBUG_TARGET == target &&
                    687:            SCSIPI_DEBUG_LUN == lun)
                    688:                periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS;
                    689: #endif
1.12      mycroft   690:
                    691:        /*
                    692:         * Ask the device what it is
                    693:         */
1.157     bouyer    694:        (void) scsipi_test_unit_ready(periph,
1.128     thorpej   695:            XS_CTL_DISCOVERY | XS_CTL_IGNORE_ILLEGAL_REQUEST |
                    696:            XS_CTL_IGNORE_NOT_READY | XS_CTL_IGNORE_MEDIA_CHANGE);
1.18      mycroft   697:
1.23      mycroft   698: #ifdef SCSI_2_DEF
1.12      mycroft   699:        /* some devices need to be told to go to SCSI2 */
                    700:        /* However some just explode if you tell them this.. leave it out */
1.157     bouyer    701:        scsi_change_def(periph, XS_CTL_DISCOVERY | XS_CTL_SILENT);
1.18      mycroft   702: #endif /* SCSI_2_DEF */
                    703:
                    704:        /* Now go ask the device all about itself. */
1.157     bouyer    705:        memset(&inqbuf, 0, sizeof(inqbuf));
                    706:        if (scsipi_inquire(periph, &inqbuf,
1.147     enami     707:            XS_CTL_DISCOVERY | XS_CTL_DATA_ONSTACK) != 0)
1.18      mycroft   708:                goto bad;
                    709:        {
1.141     dante     710:                u_int8_t *extension = &inqbuf.flags1;
1.18      mycroft   711:                int len = inqbuf.additional_length;
1.20      mycroft   712:                while (len < 3)
1.141     dante     713:                        extension[len++] = '\0';
1.20      mycroft   714:                while (len < 3 + 28)
1.141     dante     715:                        extension[len++] = ' ';
                    716:                while (len < 3 + 28 + 20)
                    717:                        extension[len++] = '\0';
                    718:                while (len < 3 + 28 + 20 + 1)
                    719:                        extension[len++] = '\0';
1.142     dante     720:                while (len < 3 + 28 + 20 + 1 + 1)
                    721:                        extension[len++] = '\0';
                    722:                while (len < 3 + 28 + 20 + 1 + 1 + (8*2))
                    723:                        extension[len++] = ' ';
1.18      mycroft   724:        }
                    725:
1.157     bouyer    726:        periph->periph_type = inqbuf.device & SID_TYPE;
                    727:        if (inqbuf.dev_qual2 & SID_REMOVABLE)
                    728:                periph->periph_flags |= PERIPH_REMOVABLE;
                    729:        periph->periph_version = inqbuf.version & SID_ANSII;
1.12      mycroft   730:
                    731:        /*
                    732:         * Any device qualifier that has the top bit set (qualifier&4 != 0)
                    733:         * is vendor specific and won't match in this switch.
1.51      thorpej   734:         * All we do here is throw out bad/negative responses.
1.12      mycroft   735:         */
1.51      thorpej   736:        checkdtype = 0;
1.18      mycroft   737:        switch (inqbuf.device & SID_QUAL) {
1.157     bouyer    738:        case SID_QUAL_LU_PRESENT:
                    739:        case SID_QUAL_LU_NOTPRESENT:
1.51      thorpej   740:                checkdtype = 1;
1.2       deraadt   741:                break;
1.12      mycroft   742:
1.157     bouyer    743:        case SID_QUAL_reserved:
                    744:        case SID_QUAL_LU_NOT_SUPP:
1.18      mycroft   745:                goto bad;
1.12      mycroft   746:
1.2       deraadt   747:        default:
                    748:                break;
                    749:        }
1.151     ad        750:
                    751:        /* Let the adapter driver handle the device separatley if it wants. */
1.157     bouyer    752:        if (chan->chan_adapter->adapt_accesschk != NULL &&
                    753:            (*chan->chan_adapter->adapt_accesschk)(periph, &sa.sa_inqbuf))
1.151     ad        754:                goto bad;
                    755:
1.149     mjacob    756:        if (checkdtype) {
1.157     bouyer    757:                switch (periph->periph_type) {
1.2       deraadt   758:                case T_DIRECT:
                    759:                case T_SEQUENTIAL:
                    760:                case T_PRINTER:
                    761:                case T_PROCESSOR:
1.93      thorpej   762:                case T_WORM:
1.18      mycroft   763:                case T_CDROM:
1.2       deraadt   764:                case T_SCANNER:
                    765:                case T_OPTICAL:
                    766:                case T_CHANGER:
                    767:                case T_COMM:
1.93      thorpej   768:                case T_IT8_1:
                    769:                case T_IT8_2:
                    770:                case T_STORARRAY:
                    771:                case T_ENCLOSURE:
1.142     dante     772:                case T_SIMPLE_DIRECT:
                    773:                case T_OPTIC_CARD_RW:
                    774:                case T_OBJECT_STORED:
1.51      thorpej   775:                default:
1.2       deraadt   776:                        break;
1.12      mycroft   777:                case T_NODEVICE:
1.18      mycroft   778:                        goto bad;
1.1       cgd       779:                }
1.157     bouyer    780:        }
                    781:
                    782:        sa.sa_periph = periph;
                    783:        sa.sa_inqbuf.type = inqbuf.device;
                    784:        sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ?
                    785:            T_REMOV : T_FIXED;
                    786:        sa.sa_inqbuf.vendor = inqbuf.vendor;
                    787:        sa.sa_inqbuf.product = inqbuf.product;
                    788:        sa.sa_inqbuf.revision = inqbuf.revision;
                    789:        sa.scsipi_info.scsi_version = inqbuf.version;
                    790:        sa.sa_inqptr = &inqbuf;
                    791:
                    792:        finger = (struct scsi_quirk_inquiry_pattern *)scsipi_inqmatch(
                    793:            &sa.sa_inqbuf, (caddr_t)scsi_quirk_patterns,
                    794:            sizeof(scsi_quirk_patterns)/sizeof(scsi_quirk_patterns[0]),
                    795:            sizeof(scsi_quirk_patterns[0]), &priority);
                    796:
                    797:        if (finger != NULL)
                    798:                quirks = finger->quirks;
                    799:        else
                    800:                quirks = 0;
                    801:
                    802:        /*
                    803:         * Determine the operating mode capabilities of the device.
                    804:         */
                    805:        if (periph->periph_version >= 2) {
                    806:                if ((inqbuf.flags3 & SID_CmdQue) != 0 &&
                    807:                    (quirks & PQUIRK_NOTAG) == 0)
                    808:                        periph->periph_cap |= PERIPH_CAP_TQING;
                    809:                if ((inqbuf.flags3 & SID_Linked) != 0)
                    810:                        periph->periph_cap |= PERIPH_CAP_LINKCMDS;
                    811:                if ((inqbuf.flags3 & SID_Sync) != 0 &&
                    812:                    (quirks & PQUIRK_NOSYNC) == 0)
                    813:                        periph->periph_cap |= PERIPH_CAP_SYNC;
                    814:                if ((inqbuf.flags3 & SID_WBus16) != 0 &&
                    815:                    (quirks & PQUIRK_NOWIDE) == 0)
                    816:                        periph->periph_cap |= PERIPH_CAP_WIDE16;
                    817:                if ((inqbuf.flags3 & SID_WBus32) != 0 &&
                    818:                    (quirks & PQUIRK_NOWIDE) == 0)
                    819:                        periph->periph_cap |= PERIPH_CAP_WIDE32;
                    820:                if ((inqbuf.flags3 & SID_SftRe) != 0)
                    821:                        periph->periph_cap |= PERIPH_CAP_SFTRESET;
                    822:                if ((inqbuf.flags3 & SID_RelAdr) != 0)
                    823:                        periph->periph_cap |= PERIPH_CAP_RELADR;
                    824:        }
                    825:
                    826:        /*
                    827:         * Now apply any quirks from the table.
                    828:         */
                    829:        periph->periph_quirks |= quirks;
                    830:        if (periph->periph_version == 0 &&
                    831:            (periph->periph_quirks & PQUIRK_FORCELUNS) == 0)
                    832:                periph->periph_quirks |= PQUIRK_NOLUNS;
                    833:
                    834:        if (periph->periph_quirks & PQUIRK_CDROM) {
                    835:                periph->periph_quirks ^= PQUIRK_CDROM;
                    836:                inqbuf.dev_qual2 |= SID_REMOVABLE;
                    837:                sa.sa_inqbuf.type = inqbuf.device = ((inqbuf.device & ~SID_REMOVABLE) | T_CDROM);
                    838:                sa.sa_inqbuf.removable = T_REMOV;
                    839:        }
                    840:
                    841:        if ((periph->periph_quirks & PQUIRK_NOLUNS) == 0)
                    842:                docontinue = 1;
                    843:
                    844:        if ((cf = config_search(scsibussubmatch, &sc->sc_dev, &sa)) != NULL) {
                    845:                scsipi_insert_periph(chan, periph);
1.149     mjacob    846:                /*
1.157     bouyer    847:                 * XXX Can't assign periph_dev here, because we'll
                    848:                 * XXX need it before config_attach() returns.  Must
                    849:                 * XXX assign it in periph driver.
1.149     mjacob    850:                 */
1.157     bouyer    851:                (void) config_attach(&sc->sc_dev, cf, &sa, scsibusprint);
1.51      thorpej   852:        } else {
1.157     bouyer    853:                scsibusprint(&sa, sc->sc_dev.dv_xname);
1.65      christos  854:                printf(" not configured\n");
1.18      mycroft   855:                goto bad;
1.51      thorpej   856:        }
1.18      mycroft   857:
1.119     mjacob    858:        return (docontinue);
1.12      mycroft   859:
1.18      mycroft   860: bad:
1.157     bouyer    861:        free(periph, M_DEVBUF);
1.119     mjacob    862:        return (docontinue);
1.111     thorpej   863: }
                    864:
                    865: /****** Entry points for user control of the SCSI bus. ******/
                    866:
                    867: int
                    868: scsibusopen(dev, flag, fmt, p)
                    869:        dev_t dev;
                    870:        int flag, fmt;
                    871:        struct proc *p;
                    872: {
                    873:        struct scsibus_softc *sc;
1.117     thorpej   874:        int error, unit = minor(dev);
1.111     thorpej   875:
                    876:        if (unit >= scsibus_cd.cd_ndevs ||
                    877:            (sc = scsibus_cd.cd_devs[unit]) == NULL)
                    878:                return (ENXIO);
                    879:
1.114     thorpej   880:        if (sc->sc_flags & SCSIBUSF_OPEN)
1.111     thorpej   881:                return (EBUSY);
1.117     thorpej   882:
1.157     bouyer    883:        if ((error = scsipi_adapter_addref(sc->sc_channel->chan_adapter)) != 0)
1.117     thorpej   884:                return (error);
                    885:
1.114     thorpej   886:        sc->sc_flags |= SCSIBUSF_OPEN;
1.111     thorpej   887:
                    888:        return (0);
                    889: }
                    890:
                    891: int
                    892: scsibusclose(dev, flag, fmt, p)
                    893:        dev_t dev;
                    894:        int flag, fmt;
                    895:        struct proc *p;
                    896: {
                    897:        struct scsibus_softc *sc = scsibus_cd.cd_devs[minor(dev)];
1.117     thorpej   898:
1.157     bouyer    899:        scsipi_adapter_delref(sc->sc_channel->chan_adapter);
1.111     thorpej   900:
1.114     thorpej   901:        sc->sc_flags &= ~SCSIBUSF_OPEN;
1.111     thorpej   902:
                    903:        return (0);
                    904: }
                    905:
                    906: int
                    907: scsibusioctl(dev, cmd, addr, flag, p)
                    908:        dev_t dev;
                    909:        u_long cmd;
                    910:        caddr_t addr;
                    911:        int flag;
                    912:        struct proc *p;
                    913: {
                    914:        struct scsibus_softc *sc = scsibus_cd.cd_devs[minor(dev)];
1.157     bouyer    915:        struct scsipi_channel *chan = sc->sc_channel;
1.111     thorpej   916:        int error;
                    917:
1.113     thorpej   918:        /*
                    919:         * Enforce write permission for ioctls that change the
                    920:         * state of the bus.  Host adapter specific ioctls must
                    921:         * be checked by the adapter driver.
                    922:         */
                    923:        switch (cmd) {
                    924:        case SCBUSIOSCAN:
1.159   ! bouyer    925:        case SCBUSIODETACH:
1.113     thorpej   926:        case SCBUSIORESET:
                    927:                if ((flag & FWRITE) == 0)
                    928:                        return (EBADF);
                    929:        }
                    930:
1.111     thorpej   931:        switch (cmd) {
1.112     thorpej   932:        case SCBUSIOSCAN:
                    933:            {
                    934:                struct scbusioscan_args *a =
                    935:                    (struct scbusioscan_args *)addr;
                    936:
1.157     bouyer    937:                error = scsi_probe_bus(sc, a->sa_target, a->sa_lun);
1.112     thorpej   938:                break;
                    939:            }
1.159   ! bouyer    940:
        !           941:        case SCBUSIODETACH:
        !           942:            {
        !           943:                struct scbusiodetach_args *a =
        !           944:                    (struct scbusiodetach_args *)addr;
        !           945:
        !           946:                error = scsipi_target_detach(chan, a->sa_target, a->sa_lun, 0);
        !           947:                break;
        !           948:            }
        !           949:
1.112     thorpej   950:
1.113     thorpej   951:        case SCBUSIORESET:
                    952:                /* FALLTHROUGH */
1.111     thorpej   953:        default:
1.157     bouyer    954:                if (chan->chan_adapter->adapt_ioctl == NULL)
1.113     thorpej   955:                        error = ENOTTY;
                    956:                else
1.157     bouyer    957:                        error = (*chan->chan_adapter->adapt_ioctl)(chan,
1.113     thorpej   958:                            cmd, addr, flag, p);
                    959:                break;
1.111     thorpej   960:        }
                    961:
                    962:        return (error);
1.1       cgd       963: }

CVSweb <webmaster@jp.NetBSD.org>