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

Annotation of src/sys/dev/scsipi/atapiconf.c, Revision 1.28.2.10

1.28.2.10! bouyer      1: /*     $NetBSD: atapiconf.c,v 1.28.2.9 2001/03/27 15:32:16 bouyer Exp $        */
1.2       bouyer      2:
                      3: /*
                      4:  * Copyright (c) 1996 Manuel Bouyer.  All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  * 3. All advertising materials mentioning features or use of this software
                     15:  *    must display the following acknowledgement:
                     16:  *     This product includes software developed by Manuel Bouyer.
                     17:  * 4. The name of the author may not be used to endorse or promote products
                     18:  *    derived from this software without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     21:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     22:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     23:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     24:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     25:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     26:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     27:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     28:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     29:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: #include <sys/types.h>
                     33: #include <sys/param.h>
                     34: #include <sys/systm.h>
                     35: #include <sys/malloc.h>
                     36: #include <sys/device.h>
                     37: #include <sys/buf.h>
1.4       enami      38: #include <sys/proc.h>
1.28.2.1  thorpej    39: #include <sys/kthread.h>
1.2       bouyer     40:
1.13      bouyer     41: #include <dev/ata/atavar.h>
1.2       bouyer     42: #include <dev/scsipi/scsipi_all.h>
1.9       cgd        43: #include <dev/scsipi/atapi_all.h>
1.2       bouyer     44: #include <dev/scsipi/scsipiconf.h>
                     45: #include <dev/scsipi/atapiconf.h>
1.4       enami      46:
1.2       bouyer     47: #include "locators.h"
                     48:
                     49: #define SILENT_PRINTF(flags,string) if (!(flags & A_SILENT)) printf string
1.27      enami      50: #define MAX_TARGET 1
1.2       bouyer     51:
1.28.2.1  thorpej    52: const struct scsipi_periphsw atapi_probe_periphsw = {
                     53:        NULL,
                     54:        NULL,
                     55:        NULL,
                     56:        NULL,
                     57: };
                     58:
1.2       bouyer     59: int    atapibusmatch __P((struct device *, struct cfdata *, void *));
                     60: void   atapibusattach __P((struct device *, struct device *, void *));
1.27      enami      61: int    atapibusactivate __P((struct device *, enum devact));
                     62: int    atapibusdetach __P((struct device *, int flags));
                     63:
1.28.2.1  thorpej    64: int    atapibussubmatch __P((struct device *, struct cfdata *, void *));
                     65:
                     66: int    atapi_probe_bus __P((struct atapibus_softc *, int));
1.2       bouyer     67:
                     68: struct cfattach atapibus_ca = {
1.27      enami      69:        sizeof(struct atapibus_softc), atapibusmatch, atapibusattach,
                     70:        atapibusdetach, atapibusactivate,
1.2       bouyer     71: };
                     72:
1.8       thorpej    73: extern struct cfdriver atapibus_cd;
1.2       bouyer     74:
                     75: int atapibusprint __P((void *, const char *));
                     76:
1.28.2.7  bouyer     77: const struct scsi_quirk_inquiry_pattern atapi_quirk_patterns[] = {
1.2       bouyer     78:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    79:         "ALPS ELECTRIC CO.,LTD. DC544C", "", "SW03D"}, PQUIRK_NOTUR},
1.2       bouyer     80:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    81:         "BCD-16X 1997-04-25", "", "VER 2.2"},  PQUIRK_NOSTARTUNIT},
1.26      bouyer     82:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    83:         "BCD-24X 1997-06-27", "", "VER 2.0"},  PQUIRK_NOSTARTUNIT},
1.22      bouyer     84:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    85:         "CR-2801TE", "", "1.07"},              PQUIRK_NOSENSE},
1.23      bouyer     86:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    87:         "CREATIVECD3630E", "", "AC101"},       PQUIRK_NOSENSE},
1.2       bouyer     88:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    89:         "FX320S", "", "q01"},                  PQUIRK_NOSENSE},
1.21      bouyer     90:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    91:         "GCD-R580B", "", "1.00"},              PQUIRK_LITTLETOC},
1.24      bouyer     92:        {{T_CDROM, T_REMOV,
1.28.2.6  bouyer     93:         "HITACHI CDR-7730", "", "0008a"},      PQUIRK_NOSENSE},
                     94:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    95:         "MATSHITA CR-574", "", "1.02"},        PQUIRK_NOCAPACITY},
1.3       bouyer     96:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    97:         "MATSHITA CR-574", "", "1.06"},        PQUIRK_NOCAPACITY},
1.7       bouyer     98:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej    99:         "Memorex CRW-2642", "", "1.0g"},       PQUIRK_NOSENSE},
1.7       bouyer    100:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej   101:         "NEC                 CD-ROM DRIVE:273", "", "4.21"}, PQUIRK_NOTUR},
1.2       bouyer    102:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej   103:         "SANYO CRD-256P", "", "1.02"},         PQUIRK_NOCAPACITY},
1.2       bouyer    104:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej   105:         "SANYO CRD-254P", "", "1.02"},         PQUIRK_NOCAPACITY},
1.3       bouyer    106:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej   107:         "SANYO CRD-S54P", "", "1.08"},         PQUIRK_NOCAPACITY},
1.5       bouyer    108:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej   109:         "CD-ROM  CDR-S1", "", "1.70"},         PQUIRK_NOCAPACITY}, /* Sanyo */
1.18      bouyer    110:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej   111:         "CD-ROM  CDR-N16", "", "1.25"},        PQUIRK_NOCAPACITY}, /* Sanyo */
1.20      bouyer    112:        {{T_CDROM, T_REMOV,
1.28.2.1  thorpej   113:         "UJDCD8730", "", "1.14"},              PQUIRK_NODOORLOCK}, /* Acer */
1.28.2.9  bouyer    114:        {{T_DIRECT, T_REMOV,            /* Panasonic MultiMediaCard */
                    115:          "04DA", "1B00", "0010"},              PQUIRK_BYTE5_ZERO |
                    116:                                                PQUIRK_NO_FLEX_PAGE },
1.28.2.10! bouyer    117:        {{T_DIRECT, T_REMOV,            /* ZiO! MultiMediaCard */
        !           118:          "eUSB", "MultiMediaCard", ""},        PQUIRK_NO_FLEX_PAGE },
1.2       bouyer    119: };
                    120:
                    121: int
                    122: atapibusmatch(parent, cf, aux)
                    123:        struct device *parent;
                    124:        struct cfdata *cf;
                    125:        void *aux;
                    126: {
1.28.2.1  thorpej   127:        struct ata_atapi_attach *aa = aux;
1.2       bouyer    128:
1.28.2.1  thorpej   129:        if (aa == NULL)
1.4       enami     130:                return (0);
1.28.2.1  thorpej   131:
                    132:        if (aa->aa_type != T_ATAPI)
1.4       enami     133:                return (0);
1.28.2.1  thorpej   134:
                    135:        if (cf->cf_loc[ATAPICF_CHANNEL] != aa->aa_channel &&
1.13      bouyer    136:            cf->cf_loc[ATAPICF_CHANNEL] != ATAPICF_CHANNEL_DEFAULT)
1.28.2.1  thorpej   137:                return (0);
                    138:
1.4       enami     139:        return (1);
1.2       bouyer    140: }
                    141:
                    142: int
                    143: atapibussubmatch(parent, cf, aux)
                    144:        struct device *parent;
                    145:        struct cfdata *cf;
                    146:        void *aux;
                    147: {
                    148:        struct scsipibus_attach_args *sa = aux;
1.28.2.1  thorpej   149:        struct scsipi_periph *periph = sa->sa_periph;
1.2       bouyer    150:
                    151:        if (cf->cf_loc[ATAPIBUSCF_DRIVE] != ATAPIBUSCF_DRIVE_DEFAULT &&
1.28.2.1  thorpej   152:            cf->cf_loc[ATAPIBUSCF_DRIVE] != periph->periph_target)
1.4       enami     153:                return (0);
1.2       bouyer    154:        return ((*cf->cf_attach->ca_match)(parent, cf, aux));
                    155: }
                    156:
                    157: void
                    158: atapibusattach(parent, self, aux)
1.4       enami     159:        struct device *parent, *self;
                    160:        void *aux;
1.2       bouyer    161: {
1.28.2.1  thorpej   162:        struct atapibus_softc *sc = (void *) self;
                    163:        struct ata_atapi_attach *aa = aux;
                    164:        struct scsipi_channel *chan = aa->aa_bus_private;
                    165:
                    166:        sc->sc_channel = chan;
                    167:        sc->sc_drvs = aa->aa_drv_data;
                    168:
                    169:        /* ATAPI has no LUNs. */
                    170:        chan->chan_nluns = 1;
                    171:        printf(": %d targets\n", chan->chan_ntargets);
                    172:
                    173:        /* Initialize the channel. */
                    174:        scsipi_channel_init(chan);
                    175:
                    176:        /* Probe the bus for devices. */
                    177:        atapi_probe_bus(sc, -1);
1.27      enami     178: }
                    179:
                    180: int
                    181: atapibusactivate(self, act)
                    182:        struct device *self;
                    183:        enum devact act;
                    184: {
1.28.2.1  thorpej   185:        struct atapibus_softc *sc = (void *) self;
                    186:        struct scsipi_channel *chan = sc->sc_channel;
                    187:        struct scsipi_periph *periph;
1.27      enami     188:        int target, error = 0, s;
                    189:
                    190:        s = splbio();
                    191:        switch (act) {
                    192:        case DVACT_ACTIVATE:
                    193:                error = EOPNOTSUPP;
                    194:                break;
                    195:
                    196:        case DVACT_DEACTIVATE:
1.28.2.1  thorpej   197:                for (target = 0; target < chan->chan_ntargets; target++) {
1.28.2.5  thorpej   198:                        periph = scsipi_lookup_periph(chan, target, 0);
1.28.2.1  thorpej   199:                        if (periph == NULL)
1.27      enami     200:                                continue;
1.28.2.1  thorpej   201:                        error = config_deactivate(periph->periph_dev);
                    202:                        if (error)
1.27      enami     203:                                goto out;
                    204:                }
                    205:                break;
                    206:        }
                    207:  out:
                    208:        splx(s);
                    209:        return (error);
                    210: }
                    211:
                    212: int
                    213: atapibusdetach(self, flags)
                    214:        struct device *self;
                    215:        int flags;
                    216: {
1.28.2.1  thorpej   217:        struct atapibus_softc *sc = (void *)self;
                    218:        struct scsipi_channel *chan = sc->sc_channel;
                    219:        struct scsipi_periph *periph;
1.27      enami     220:        int target, error;
                    221:
1.28.2.5  thorpej   222:        /*
                    223:         * Shut down the channel.
                    224:         */
                    225:        scsipi_channel_shutdown(chan);
                    226:
                    227:        /*
                    228:         * Now detach all of the periphs.
                    229:         */
1.28.2.1  thorpej   230:        for (target = 0; target < chan->chan_ntargets; target++) {
1.28.2.5  thorpej   231:                periph = scsipi_lookup_periph(chan, target, 0);
1.28.2.1  thorpej   232:                if (periph == NULL)
1.27      enami     233:                        continue;
1.28.2.1  thorpej   234:                error = config_detach(periph->periph_dev, flags);
                    235:                if (error)
1.27      enami     236:                        return (error);
                    237:
                    238:                /*
                    239:                 * We have successfully detached the child.  Drop the
                    240:                 * direct reference for the child so that wdcdetach
                    241:                 * won't call detach routine twice.
                    242:                 */
                    243: #ifdef DIAGNOSTIC
1.28.2.1  thorpej   244:                if (periph->periph_dev != sc->sc_drvs[target].drv_softc)
1.27      enami     245:                        panic("softc mismatch");
                    246: #endif
                    247:                sc->sc_drvs[target].drv_softc = NULL;
                    248:
1.28.2.5  thorpej   249:                scsipi_remove_periph(chan, periph);
1.28.2.1  thorpej   250:                free(periph, M_DEVBUF);
1.27      enami     251:        }
                    252:        return (0);
1.2       bouyer    253: }
                    254:
1.4       enami     255: int
1.28.2.1  thorpej   256: atapi_probe_bus(sc, target)
                    257:        struct atapibus_softc *sc;
                    258:        int target;
1.2       bouyer    259: {
1.28.2.1  thorpej   260:        struct scsipi_channel *chan = sc->sc_channel;
1.2       bouyer    261:        int maxtarget, mintarget;
1.15      thorpej   262:        int error;
1.28.2.6  bouyer    263:        struct atapi_adapter *atapi_adapter;
1.4       enami     264:
1.2       bouyer    265:        if (target == -1) {
                    266:                maxtarget = 1;
                    267:                mintarget = 0;
                    268:        } else {
1.28.2.1  thorpej   269:                if (target < 0 || target >= chan->chan_ntargets)
1.4       enami     270:                        return (ENXIO);
1.2       bouyer    271:                maxtarget = mintarget = target;
                    272:        }
1.28.2.1  thorpej   273:
                    274:        if ((error = scsipi_adapter_addref(chan->chan_adapter)) != 0)
1.15      thorpej   275:                return (error);
1.28.2.6  bouyer    276:        atapi_adapter = (struct atapi_adapter*)chan->chan_adapter;
1.4       enami     277:        for (target = mintarget; target <= maxtarget; target++)
1.28.2.6  bouyer    278:                atapi_adapter->atapi_probe_device(sc, target);
1.28.2.1  thorpej   279:        scsipi_adapter_delref(chan->chan_adapter);
1.4       enami     280:        return (0);
1.2       bouyer    281: }
                    282:
1.28.2.6  bouyer    283: void *
                    284: atapi_probe_device(sc, target, periph, sa)
1.28.2.1  thorpej   285:        struct atapibus_softc *sc;
1.2       bouyer    286:        int target;
1.28.2.6  bouyer    287:        struct scsipi_periph *periph;
                    288:        struct scsipibus_attach_args *sa;
1.2       bouyer    289: {
1.28.2.1  thorpej   290:        struct scsipi_channel *chan = sc->sc_channel;
1.2       bouyer    291:        struct scsi_quirk_inquiry_pattern *finger;
1.28.2.1  thorpej   292:        struct cfdata *cf;
                    293:        int priority, quirks;
1.2       bouyer    294:
1.28.2.6  bouyer    295:        finger = (struct scsi_quirk_inquiry_pattern *)scsipi_inqmatch(
                    296:            &sa->sa_inqbuf, (caddr_t)atapi_quirk_patterns,
                    297:            sizeof(atapi_quirk_patterns) /
                    298:                sizeof(atapi_quirk_patterns[0]),
                    299:            sizeof(atapi_quirk_patterns[0]), &priority);
                    300:
                    301:        if (finger != NULL)
                    302:                quirks = finger->quirks;
                    303:        else
                    304:                quirks = 0;
1.28.2.1  thorpej   305:
1.28.2.6  bouyer    306:        /*
                    307:         * Now apply any quirks from the table.
                    308:         */
                    309:        periph->periph_quirks |= quirks;
1.28.2.1  thorpej   310:
1.28.2.6  bouyer    311:        if ((cf = config_search(atapibussubmatch, &sc->sc_dev,
                    312:            sa)) != 0) {
                    313:                scsipi_insert_periph(chan, periph);
1.28.2.1  thorpej   314:                /*
1.28.2.6  bouyer    315:                 * XXX Can't assign periph_dev here, because we'll
                    316:                 * XXX need it before config_attach() returns.  Must
                    317:                 * XXX assign it in periph driver.
1.28.2.1  thorpej   318:                 */
1.28.2.6  bouyer    319:                return config_attach(&sc->sc_dev, cf, sa,
                    320:                    atapibusprint);
                    321:        } else {
                    322:                atapibusprint(&sa, sc->sc_dev.dv_xname);
                    323:                printf(" not configured\n");
                    324:                free(periph, M_DEVBUF);
                    325:                return NULL;
1.2       bouyer    326:        }
                    327: }
                    328:
                    329: int
                    330: atapibusprint(aux, pnp)
                    331:        void *aux;
                    332:        const char *pnp;
                    333: {
                    334:        struct scsipibus_attach_args *sa = aux;
                    335:        struct scsipi_inquiry_pattern *inqbuf;
                    336:        char *dtype;
                    337:
                    338:        if (pnp != NULL)
                    339:                printf("%s", pnp);
                    340:
                    341:        inqbuf = &sa->sa_inqbuf;
                    342:
                    343:        dtype = scsipi_dtype(inqbuf->type & SID_TYPE);
                    344:        printf(" drive %d: <%s, %s, %s> type %d %s %s",
1.28.2.1  thorpej   345:            sa->sa_periph->periph_target ,inqbuf->vendor,
1.2       bouyer    346:            inqbuf->product, inqbuf->revision, inqbuf->type, dtype,
                    347:            inqbuf->removable ? "removable" : "fixed");
                    348:        return (UNCONF);
                    349: }

CVSweb <webmaster@jp.NetBSD.org>