The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/scsipi/atapiconf.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: atapiconf.c,v 1.72 2006/11/16 01:33:26 christos Exp $  */
    2 
    3 /*
    4  * Copyright (c) 1996, 2001 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/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: atapiconf.c,v 1.72 2006/11/16 01:33:26 christos Exp $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/malloc.h>
   38 #include <sys/device.h>
   39 #include <sys/buf.h>
   40 #include <sys/proc.h>
   41 #include <sys/kthread.h>
   42 
   43 #include <dev/scsipi/scsipi_all.h>
   44 #include <dev/scsipi/scsipiconf.h>
   45 #include <dev/scsipi/atapiconf.h>
   46 
   47 #include "locators.h"
   48 
   49 #define SILENT_PRINTF(flags,string) if (!(flags & A_SILENT)) printf string
   50 #define MAX_TARGET 1
   51 
   52 const struct scsipi_periphsw atapi_probe_periphsw = {
   53         NULL,
   54         NULL,
   55         NULL,
   56         NULL,
   57 };
   58 
   59 static int      atapibusmatch(struct device *, struct cfdata *, void *);
   60 static void     atapibusattach(struct device *, struct device *, void *);
   61 static int      atapibusactivate(struct device *, enum devact);
   62 static int      atapibusdetach(struct device *, int flags);
   63 
   64 static int      atapibussubmatch(struct device *, struct cfdata *,
   65                                  const int *, void *);
   66 
   67 static int      atapi_probe_bus(struct atapibus_softc *, int);
   68 
   69 static int      atapibusprint(void *, const char *);
   70 
   71 CFATTACH_DECL(atapibus, sizeof(struct atapibus_softc),
   72     atapibusmatch, atapibusattach, atapibusdetach, atapibusactivate);
   73 
   74 extern struct cfdriver atapibus_cd;
   75 
   76 static const struct scsi_quirk_inquiry_pattern atapi_quirk_patterns[] = {
   77         {{T_CDROM, T_REMOV,
   78          "ALPS ELECTRIC CO.,LTD. DC544C", "", "SW03D"}, PQUIRK_NOTUR},
   79         {{T_CDROM, T_REMOV,
   80          "CR-2801TE", "", "1.07"},              PQUIRK_NOSENSE},
   81         {{T_CDROM, T_REMOV,
   82          "CREATIVECD3630E", "", "AC101"},       PQUIRK_NOSENSE},
   83         {{T_CDROM, T_REMOV,
   84          "FX320S", "", "q01"},                  PQUIRK_NOSENSE},
   85         {{T_CDROM, T_REMOV,
   86          "GCD-R580B", "", "1.00"},              PQUIRK_LITTLETOC},
   87         {{T_CDROM, T_REMOV,
   88          "HITACHI CDR-7730", "", "0008a"},      PQUIRK_NOSENSE},
   89         {{T_CDROM, T_REMOV,
   90          "MATSHITA CR-574", "", "1.02"},        PQUIRK_NOCAPACITY},
   91         {{T_CDROM, T_REMOV,
   92          "MATSHITA CR-574", "", "1.06"},        PQUIRK_NOCAPACITY},
   93         {{T_CDROM, T_REMOV,
   94          "Memorex CRW-2642", "", "1.0g"},       PQUIRK_NOSENSE},
   95         {{T_CDROM, T_REMOV,
   96          "NEC                 CD-ROM DRIVE:273", "", "4.21"}, PQUIRK_NOTUR},
   97         {{T_CDROM, T_REMOV,
   98          "SANYO CRD-256P", "", "1.02"},         PQUIRK_NOCAPACITY},
   99         {{T_CDROM, T_REMOV,
  100          "SANYO CRD-254P", "", "1.02"},         PQUIRK_NOCAPACITY},
  101         {{T_CDROM, T_REMOV,
  102          "SANYO CRD-S54P", "", "1.08"},         PQUIRK_NOCAPACITY},
  103         {{T_CDROM, T_REMOV,
  104          "CD-ROM  CDR-S1", "", "1.70"},         PQUIRK_NOCAPACITY}, /* Sanyo */
  105         {{T_CDROM, T_REMOV,
  106          "CD-ROM  CDR-N16", "", "1.25"},        PQUIRK_NOCAPACITY}, /* Sanyo */
  107 };
  108 
  109 int
  110 atapiprint(void *aux, const char *pnp)
  111 {
  112         if (pnp)
  113                 aprint_normal("atapibus at %s", pnp);
  114         return (UNCONF);
  115 }
  116 
  117 static int
  118 atapibusmatch(struct device *parent, struct cfdata *cf,
  119     void *aux)
  120 {
  121         struct scsipi_channel *chan = aux;
  122 
  123         if (chan == NULL)
  124                 return (0);
  125 
  126         if (chan->chan_bustype->bustype_type != SCSIPI_BUSTYPE_ATAPI)
  127                 return (0);
  128 
  129         return (1);
  130 }
  131 
  132 static int
  133 atapibussubmatch(struct device *parent, struct cfdata *cf,
  134     const int *ldesc, void *aux)
  135 {
  136         struct scsipibus_attach_args *sa = aux;
  137         struct scsipi_periph *periph = sa->sa_periph;
  138 
  139         if (cf->cf_loc[ATAPIBUSCF_DRIVE] != ATAPIBUSCF_DRIVE_DEFAULT &&
  140             cf->cf_loc[ATAPIBUSCF_DRIVE] != periph->periph_target)
  141                 return (0);
  142         return (config_match(parent, cf, aux));
  143 }
  144 
  145 static void
  146 atapibusattach(struct device *parent, struct device *self, void *aux)
  147 {
  148         struct atapibus_softc *sc = device_private(self);
  149         struct scsipi_channel *chan = aux;
  150 
  151         sc->sc_channel = chan;
  152 
  153         chan->chan_name = sc->sc_dev.dv_xname;
  154 
  155         /* ATAPI has no LUNs. */
  156         chan->chan_nluns = 1;
  157         printf(": %d targets\n", chan->chan_ntargets);
  158 
  159         /* Initialize the channel. */
  160         chan->chan_init_cb = NULL;
  161         chan->chan_init_cb_arg = NULL;
  162         scsipi_channel_init(chan);
  163 
  164         /* Probe the bus for devices. */
  165         atapi_probe_bus(sc, -1);
  166 }
  167 
  168 static int
  169 atapibusactivate(struct device *self, enum devact act)
  170 {
  171         struct atapibus_softc *sc = device_private(self);
  172         struct scsipi_channel *chan = sc->sc_channel;
  173         struct scsipi_periph *periph;
  174         int target, error = 0, s;
  175 
  176         s = splbio();
  177         switch (act) {
  178         case DVACT_ACTIVATE:
  179                 error = EOPNOTSUPP;
  180                 break;
  181 
  182         case DVACT_DEACTIVATE:
  183                 for (target = 0; target < chan->chan_ntargets; target++) {
  184                         periph = scsipi_lookup_periph(chan, target, 0);
  185                         if (periph == NULL)
  186                                 continue;
  187                         error = config_deactivate(periph->periph_dev);
  188                         if (error)
  189                                 goto out;
  190                 }
  191                 break;
  192         }
  193  out:
  194         splx(s);
  195         return (error);
  196 }
  197 
  198 static int
  199 atapibusdetach(struct device *self, int flags)
  200 {
  201         struct atapibus_softc *sc = device_private(self);
  202         struct scsipi_channel *chan = sc->sc_channel;
  203         struct scsipi_periph *periph;
  204         int target, error;
  205 
  206         /*
  207          * Shut down the channel.
  208          */
  209         scsipi_channel_shutdown(chan);
  210 
  211         /*
  212          * Now detach all of the periphs.
  213          */
  214         for (target = 0; target < chan->chan_ntargets; target++) {
  215                 periph = scsipi_lookup_periph(chan, target, 0);
  216                 if (periph == NULL)
  217                         continue;
  218                 error = config_detach(periph->periph_dev, flags);
  219                 if (error)
  220                         return (error);
  221 
  222                 scsipi_remove_periph(chan, periph);
  223                 free(periph, M_DEVBUF);
  224         }
  225         return (0);
  226 }
  227 
  228 static int
  229 atapi_probe_bus(struct atapibus_softc *sc, int target)
  230 {
  231         struct scsipi_channel *chan = sc->sc_channel;
  232         int maxtarget, mintarget;
  233         int error;
  234         struct atapi_adapter *atapi_adapter;
  235 
  236         if (target == -1) {
  237                 maxtarget = 1;
  238                 mintarget = 0;
  239         } else {
  240                 if (target < 0 || target >= chan->chan_ntargets)
  241                         return (ENXIO);
  242                 maxtarget = mintarget = target;
  243         }
  244 
  245         if ((error = scsipi_adapter_addref(chan->chan_adapter)) != 0)
  246                 return (error);
  247         atapi_adapter = (struct atapi_adapter*)chan->chan_adapter;
  248         for (target = mintarget; target <= maxtarget; target++)
  249                 atapi_adapter->atapi_probe_device(sc, target);
  250         scsipi_adapter_delref(chan->chan_adapter);
  251         return (0);
  252 }
  253 
  254 void *
  255 atapi_probe_device(struct atapibus_softc *sc, int target,
  256     struct scsipi_periph *periph, struct scsipibus_attach_args *sa)
  257 {
  258         struct scsipi_channel *chan = sc->sc_channel;
  259         const struct scsi_quirk_inquiry_pattern *finger;
  260         struct cfdata *cf;
  261         int priority, quirks;
  262 
  263         finger = scsipi_inqmatch(
  264             &sa->sa_inqbuf, (const void *)atapi_quirk_patterns,
  265             sizeof(atapi_quirk_patterns) /
  266                 sizeof(atapi_quirk_patterns[0]),
  267             sizeof(atapi_quirk_patterns[0]), &priority);
  268 
  269         if (finger != NULL)
  270                 quirks = finger->quirks;
  271         else
  272                 quirks = 0;
  273 
  274         /*
  275          * Now apply any quirks from the table.
  276          */
  277         periph->periph_quirks |= quirks;
  278 
  279         if ((cf = config_search_ia(atapibussubmatch, &sc->sc_dev,
  280             "atapibus", sa)) != 0) {
  281                 scsipi_insert_periph(chan, periph);
  282                 /*
  283                  * XXX Can't assign periph_dev here, because we'll
  284                  * XXX need it before config_attach() returns.  Must
  285                  * XXX assign it in periph driver.
  286                  */
  287                 return config_attach(&sc->sc_dev, cf, sa,
  288                     atapibusprint);
  289         } else {
  290                 atapibusprint(sa, sc->sc_dev.dv_xname);
  291                 printf(" not configured\n");
  292                 free(periph, M_DEVBUF);
  293                 return NULL;
  294         }
  295 }
  296 
  297 static int
  298 atapibusprint(void *aux, const char *pnp)
  299 {
  300         struct scsipibus_attach_args *sa = aux;
  301         struct scsipi_inquiry_pattern *inqbuf;
  302         const char *dtype;
  303 
  304         if (pnp != NULL)
  305                 aprint_normal("%s", pnp);
  306 
  307         inqbuf = &sa->sa_inqbuf;
  308 
  309         dtype = scsipi_dtype(inqbuf->type & SID_TYPE);
  310         aprint_normal(" drive %d: <%s, %s, %s> %s %s",
  311             sa->sa_periph->periph_target, inqbuf->vendor,
  312             inqbuf->product, inqbuf->revision, dtype,
  313             inqbuf->removable ? "removable" : "fixed");
  314         return (UNCONF);
  315 }

Cache object: 2b33983b2fb5771ec253200c84c888b3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.