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

1.2.2.3 ! thorpej     1: /*     $NetBSD: atapiconf.c,v 1.2.2.2 1997/09/01 20:58:57 thorpej Exp $        */
1.2.2.2   thorpej     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>
                     38: #include <sys/proc.h>
                     39:
                     40: #include <dev/scsipi/scsipi_all.h>
                     41: #include <dev/scsipi/scsi_all.h>
                     42: #include <dev/scsipi/scsipiconf.h>
                     43: #include <dev/scsipi/atapiconf.h>
                     44: #include "locators.h"
                     45:
                     46: #define SILENT_PRINTF(flags,string) if (!(flags & A_SILENT)) printf string
                     47:
                     48: struct atapibus_softc {
                     49:        struct device sc_dev;
                     50:        struct scsipi_link *adapter_link; /* proto supplied by adapter */
                     51:        struct scsipi_link **sc_link;     /* dynamically allocated */
                     52: };
                     53:
                     54: #ifdef __BROKEN_INDIRECT_CONFIG
                     55: int    atapibusmatch __P((struct device *, void *, void *));
                     56: int    atapibussubmatch __P((struct device *, void *, void *));
                     57: #else
                     58: int    atapibusmatch __P((struct device *, struct cfdata *, void *));
                     59: int    atapibussubmatch __P((struct device *, struct cfdata *, void *));
                     60: #endif
                     61: void   atapibusattach __P((struct device *, struct device *, void *));
                     62: int    atapiprint __P((void *, const char *));
                     63:
                     64: int    atapi_probe_bus __P((int, int));
                     65: void   atapi_probedev __P((struct atapibus_softc *, int ));
                     66:
                     67: struct cfattach atapibus_ca = {
                     68:        sizeof(struct atapibus_softc), atapibusmatch, atapibusattach
                     69: };
                     70:
                     71: struct cfdriver atapibus_cd = {
                     72:        NULL, "atapibus", DV_DULL
                     73: };
                     74:
                     75: int atapibusprint __P((void *, const char *));
                     76:
                     77: struct scsi_quirk_inquiry_pattern atapi_quirk_patterns[] = {
                     78:        {{T_CDROM, T_REMOV,
                     79:         "GCD-R580B", "", "1.00"},                                                      ADEV_LITTLETOC},
                     80:        {{T_CDROM, T_REMOV,
                     81:         "SANYO CRD-256P", "", "1.02"},                                         ADEV_NOCAPACITY},
                     82:        {{T_CDROM, T_REMOV,
1.2.2.3 ! thorpej    83:         "SANYO CRD-254P", "", "1.02"},                                         ADEV_NOCAPACITY},
        !            84:        {{T_CDROM, T_REMOV,
1.2.2.2   thorpej    85:         "UJDCD8730", "", "1.14"},                                                      ADEV_NODOORLOCK},
                     86:        {{T_CDROM, T_REMOV,
                     87:         "ALPS ELECTRIC CO.,LTD. DC544C", "", "SW03D"},         ADEV_NOTUR},
                     88:        {{T_CDROM, T_REMOV,
                     89:         "NEC                 CD-ROM DRIVE:273", "", "4.21"},   ADEV_NOTUR},
1.2.2.3 ! thorpej    90:        {{T_CDROM, T_REMOV,
        !            91:         "MATSHITA CR-574", "", "1.06"},                                        ADEV_NOCAPACITY},
1.2.2.2   thorpej    92: };
                     93:
                     94: int
                     95: #ifdef __BROKEN_INDIRECT_CONFIG
                     96: atapibusmatch(parent, match, aux)
                     97:        struct device *parent;
                     98:        void *match, *aux;
                     99: {
                    100: #else
                    101: atapibusmatch(parent, cf, aux)
                    102:        struct device *parent;
                    103:        struct cfdata *cf;
                    104:        void *aux;
                    105: {
                    106: #endif
                    107:        struct scsipi_link *sc_link = aux;
                    108:
                    109:        if (sc_link == NULL)
                    110:                return 0;
                    111:        if (sc_link->type != BUS_ATAPI)
                    112:                return 0;
                    113:        return 1;
                    114: }
                    115:
                    116: int
                    117: #ifdef __BROKEN_INDIRECT_CONFIG
                    118: atapibussubmatch(parent, match, aux)
                    119:        struct device *parent;
                    120:        void *match, *aux;
                    121: {
                    122:        struct cfdata *cf = match;
                    123: #else
                    124: atapibussubmatch(parent, cf, aux)
                    125:        struct device *parent;
                    126:        struct cfdata *cf;
                    127:        void *aux;
                    128: {
                    129: #endif
                    130:        struct scsipibus_attach_args *sa = aux;
                    131:        struct scsipi_link *sc_link = sa->sa_sc_link;
                    132:
                    133:        if (cf->cf_loc[ATAPIBUSCF_DRIVE] != ATAPIBUSCF_DRIVE_DEFAULT &&
                    134:                cf->cf_loc[ATAPIBUSCF_DRIVE] != sc_link->scsipi_atapi.drive)
                    135:                return 0;
                    136:        return ((*cf->cf_attach->ca_match)(parent, cf, aux));
                    137: }
                    138:
                    139:
                    140: #if 0
                    141: void
                    142: atapi_fixquirk(sc_link)
                    143:         struct scsipi_link *ad_link;
                    144: {
                    145:         struct atapi_identify *id = &ad_link->id;
                    146:         struct atapi_quirk_inquiry_pattern *quirk;
                    147:
                    148:
                    149:         /*
                    150:          * Clean up the model name, serial and
                    151:          * revision numbers.
                    152:          */
                    153:         btrim(id->model, sizeof(id->model));
                    154:         btrim(id->serial_number, sizeof(id->serial_number));
                    155:         btrim(id->firmware_revision, sizeof(id->firmware_revision));
                    156:
                    157: }
                    158: #endif
                    159:
                    160:
                    161: void
                    162: atapibusattach(parent, self, aux)
                    163:         struct device *parent, *self;
                    164:         void *aux;
                    165: {
                    166:        struct atapibus_softc *ab = (struct atapibus_softc *)self;
                    167:        struct scsipi_link *sc_link_proto = aux;
                    168:        int nbytes;
                    169:
                    170:        printf("\n");
                    171:
                    172:        sc_link_proto->scsipi_atapi.atapibus = ab->sc_dev.dv_unit;
                    173:        sc_link_proto->scsipi_cmd = atapi_scsipi_cmd;
                    174:        sc_link_proto->scsipi_interpret_sense = atapi_interpret_sense;
                    175:        sc_link_proto->sc_print_addr = atapi_print_addr;
                    176:
                    177:        ab->adapter_link = sc_link_proto;
                    178:
                    179:        nbytes =  2 * sizeof(struct scsipi_link **);
                    180:        ab->sc_link = (struct scsipi_link **)malloc(nbytes, M_DEVBUF,
                    181:            M_NOWAIT);
                    182:        if (ab->sc_link == NULL)
                    183:                panic("scsibusattach: can't allocate target links");
                    184:        bzero(ab->sc_link, nbytes);
                    185:        atapi_probe_bus(ab->sc_dev.dv_unit, -1);
                    186: }
                    187:
                    188: int
                    189: atapi_probe_bus(bus, target)
                    190: int bus, target;
                    191: {
                    192:        int maxtarget, mintarget;
                    193:        struct atapibus_softc *atapi;
                    194:        if (bus < 0 || bus >= atapibus_cd.cd_ndevs)
                    195:                return ENXIO;
                    196:        atapi = atapibus_cd.cd_devs[bus];
                    197:        if (!atapi)
                    198:                return ENXIO;
                    199:
                    200:        if (target == -1) {
                    201:                maxtarget = 1;
                    202:                mintarget = 0;
                    203:        } else {
                    204:                if (target < 0 || target > 1)
                    205:                        return ENXIO;
                    206:                maxtarget = mintarget = target;
                    207:        }
                    208:        for (target = mintarget; target <= maxtarget; target++) {
                    209:                atapi_probedev(atapi, target);
                    210:        }
                    211:        return 0;
                    212: }
                    213:
                    214: void
                    215: atapi_probedev(atapi, target)
                    216:        struct atapibus_softc *atapi;
                    217:        int target;
                    218: {
                    219:        struct scsipi_link *sc_link;
                    220:        struct scsipibus_attach_args sa;
                    221:        struct atapi_identify ids;
                    222:        struct atapi_identify *id = &ids;
                    223:        struct cfdata *cf;
                    224:        struct scsi_quirk_inquiry_pattern *finger;
                    225:        int priority;
                    226:        char serial_number[20], model[40], firmware_revision[8];
                    227:
                    228:        /* skip if already attached */
                    229:        if (atapi->sc_link[target])
                    230:                return;
                    231:
                    232:        if (wdc_atapi_get_params(atapi->adapter_link, target, id)) {
                    233: #ifdef ATAPI_DEBUG_PROBE
                    234:                printf("%s drive %d: cmdsz 0x%x drqtype 0x%x\n",
                    235:                    atapi->sc_dev.dv_xname, target,
                    236:                    id->config.cmd_drq_rem & ATAPI_PACKET_SIZE_MASK,
                    237:                    id->config.cmd_drq_rem & ATAPI_DRQ_MASK);
                    238: #endif
                    239:                /*
                    240:                 * Shuffle string byte order.
                    241:                 * Mitsumi and NEC drives don't need this.
                    242:                 */
                    243:                if (((id->model[0] == 'N' && id->model[1] == 'E') ||
                    244:                    (id->model[0] == 'F' && id->model[1] == 'X')) == 0)
                    245:                        bswap(id->model, sizeof(id->model));
                    246:                bswap(id->serial_number, sizeof(id->serial_number));
                    247:                bswap(id->firmware_revision, sizeof(id->firmware_revision));
                    248:
                    249:                /*
                    250:                 * Allocate a device link and try and attach
                    251:                 * a driver to this device.  If we fail, free
                    252:                 * the link.
                    253:                 */
                    254:                sc_link = malloc(sizeof(*sc_link), M_DEVBUF, M_NOWAIT);
                    255:                if (sc_link == NULL) {
                    256:                        printf("%s: can't allocate link for drive %d\n",
                    257:                            atapi->sc_dev.dv_xname, target);
                    258:                        return;
                    259:                }
                    260:                /* Fill in link. */
                    261:                *sc_link = *atapi->adapter_link;
                    262:                sc_link->scsipi_atapi.drive = target;
                    263:                sc_link->device = NULL;
                    264: #if defined(SCSIDEBUG) && DEBUGTYPE == BUS_ATAPI
                    265:                if (DEBUGTARGET == -1 || target == DEBUGTARGET)
                    266:                        sc_link->flags |= DEBUGLEVEL;
                    267: #endif /* SCSIDEBUG */
                    268:                if (id->config.cmd_drq_rem & ATAPI_PACKET_SIZE_16)
                    269:                        sc_link->scsipi_atapi.cap |= ACAP_LEN;
                    270:                sc_link->scsipi_atapi.cap |=
                    271:                    (id->config.cmd_drq_rem & ATAPI_DRQ_MASK) << 3;
                    272: #if 0
                    273:                bcopy(id, &ad_link->id, sizeof(*id));
                    274:                /* Fix strings and look through the quirk table. */
                    275:                atapi_fixquirk(ad_link, id);
                    276: #endif
                    277:                sa.sa_sc_link = sc_link;
                    278:                sa.sa_inqbuf.type =  id->config.device_type & SID_TYPE;
                    279:                sa.sa_inqbuf.removable =
                    280:                    id->config.cmd_drq_rem & ATAPI_REMOVABLE ?
                    281:                    T_REMOV : T_FIXED;
                    282:                if (sa.sa_inqbuf.removable)
                    283:                        sc_link->flags |= SDEV_REMOVABLE;
                    284:                scsipi_strvis(model, id->model, 40);
                    285:                scsipi_strvis(serial_number, id->serial_number, 20);
                    286:                scsipi_strvis(firmware_revision, id->firmware_revision, 8);
                    287:                sa.sa_inqbuf.vendor = model;
                    288:                sa.sa_inqbuf.product = serial_number;
                    289:                sa.sa_inqbuf.revision = firmware_revision;
                    290:
                    291:                finger = (struct scsi_quirk_inquiry_pattern *)scsipi_inqmatch(
                    292:                    &sa.sa_inqbuf, (caddr_t)atapi_quirk_patterns,
                    293:                    sizeof(atapi_quirk_patterns) /
                    294:                      sizeof(atapi_quirk_patterns[0]),
                    295:                    sizeof(atapi_quirk_patterns[0]), &priority);
                    296:                if (priority != 0)
                    297:                        sc_link->quirks |= finger->quirks;
                    298:
                    299:                if ((cf = config_search(atapibussubmatch, &atapi->sc_dev,
                    300:                    &sa)) != 0) {
                    301:                        atapi->sc_link[target] = sc_link;
                    302:                        config_attach(&atapi->sc_dev, cf, &sa, atapibusprint);
                    303:                        return;
                    304:                } else {
                    305:                        atapibusprint(&sa, atapi->sc_dev.dv_xname);
                    306:                        printf(" not configured\n");
                    307:                        free(sc_link, M_DEVBUF);
                    308:                        return;
                    309:                }
                    310:
                    311: #if 0 /* WAS: */
                    312:                /* Try to find a match. */
                    313:                if (config_found(self, ad_link, atapiprint) == NULL)
                    314:                        free(ad_link, M_DEVBUF);
                    315: #endif
                    316:        }
                    317: }
                    318:
                    319: int
                    320: atapibusprint(aux, pnp)
                    321:        void *aux;
                    322:        const char *pnp;
                    323: {
                    324:        struct scsipibus_attach_args *sa = aux;
                    325:        struct scsipi_inquiry_pattern *inqbuf;
                    326:        char *dtype;
                    327:
                    328:        if (pnp != NULL)
                    329:                printf("%s", pnp);
                    330:
                    331:        inqbuf = &sa->sa_inqbuf;
                    332:
                    333:        dtype = scsipi_dtype(inqbuf->type & SID_TYPE);
                    334:        printf(" drive %d: <%s, %s, %s> type %d %s %s",
                    335:            sa->sa_sc_link->scsipi_atapi.drive,inqbuf->vendor,
                    336:            inqbuf->product, inqbuf->revision, inqbuf->type, dtype,
                    337:            inqbuf->removable ? "removable" : "fixed");
                    338:        return (UNCONF);
                    339: }

CVSweb <webmaster@jp.NetBSD.org>