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.66 2004/09/13 12:55:48 drochner 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.66 2004/09/13 12:55:48 drochner 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 locdesc_t *, 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, void *aux)
  119 {
  120         struct scsipi_channel *chan = aux;
  121 
  122         if (chan == NULL)
  123                 return (0);
  124 
  125         if (chan->chan_bustype->bustype_type != SCSIPI_BUSTYPE_ATAPI)
  126                 return (0);
  127 
  128         return (1);
  129 }
  130 
  131 static int
  132 atapibussubmatch(struct device *parent, struct cfdata *cf,
  133                  const locdesc_t *ldesc, void *aux)
  134 {
  135         struct scsipibus_attach_args *sa = aux;
  136         struct scsipi_periph *periph = sa->sa_periph;
  137 
  138         if (cf->cf_loc[ATAPIBUSCF_DRIVE] != ATAPIBUSCF_DRIVE_DEFAULT &&
  139             cf->cf_loc[ATAPIBUSCF_DRIVE] != periph->periph_target)
  140                 return (0);
  141         return (config_match(parent, cf, aux));
  142 }
  143 
  144 static void
  145 atapibusattach(struct device *parent, struct device *self, void *aux)
  146 {
  147         struct atapibus_softc *sc = (void *) self;
  148         struct scsipi_channel *chan = aux;
  149 
  150         sc->sc_channel = chan;
  151 
  152         chan->chan_name = sc->sc_dev.dv_xname;
  153 
  154         /* ATAPI has no LUNs. */
  155         chan->chan_nluns = 1;
  156         printf(": %d targets\n", chan->chan_ntargets);
  157 
  158         /* Initialize the channel. */
  159         chan->chan_init_cb = NULL;
  160         chan->chan_init_cb_arg = NULL;
  161         scsipi_channel_init(chan);
  162 
  163         /* Probe the bus for devices. */
  164         atapi_probe_bus(sc, -1);
  165 }
  166 
  167 static int
  168 atapibusactivate(struct device *self, enum devact act)
  169 {
  170         struct atapibus_softc *sc = (void *) self;
  171         struct scsipi_channel *chan = sc->sc_channel;
  172         struct scsipi_periph *periph;
  173         int target, error = 0, s;
  174 
  175         s = splbio();
  176         switch (act) {
  177         case DVACT_ACTIVATE:
  178                 error = EOPNOTSUPP;
  179                 break;
  180 
  181         case DVACT_DEACTIVATE:
  182                 for (target = 0; target < chan->chan_ntargets; target++) {
  183                         periph = scsipi_lookup_periph(chan, target, 0);
  184                         if (periph == NULL)
  185                                 continue;
  186                         error = config_deactivate(periph->periph_dev);
  187                         if (error)
  188                                 goto out;
  189                 }
  190                 break;
  191         }
  192  out:
  193         splx(s);
  194         return (error);
  195 }
  196 
  197 static int
  198 atapibusdetach(struct device *self, int flags)
  199 {
  200         struct atapibus_softc *sc = (void *)self;
  201         struct scsipi_channel *chan = sc->sc_channel;
  202         struct scsipi_periph *periph;
  203         int target, error;
  204 
  205         /*
  206          * Shut down the channel.
  207          */
  208         scsipi_channel_shutdown(chan);
  209 
  210         /*
  211          * Now detach all of the periphs.
  212          */
  213         for (target = 0; target < chan->chan_ntargets; target++) {
  214                 periph = scsipi_lookup_periph(chan, target, 0);
  215                 if (periph == NULL)
  216                         continue;
  217                 error = config_detach(periph->periph_dev, flags);
  218                 if (error)
  219                         return (error);
  220 
  221                 scsipi_remove_periph(chan, periph);
  222                 free(periph, M_DEVBUF);
  223         }
  224         return (0);
  225 }
  226 
  227 static int
  228 atapi_probe_bus(struct atapibus_softc *sc, int target)
  229 {
  230         struct scsipi_channel *chan = sc->sc_channel;
  231         int maxtarget, mintarget;
  232         int error;
  233         struct atapi_adapter *atapi_adapter;
  234 
  235         if (target == -1) {
  236                 maxtarget = 1;
  237                 mintarget = 0;
  238         } else {
  239                 if (target < 0 || target >= chan->chan_ntargets)
  240                         return (ENXIO);
  241                 maxtarget = mintarget = target;
  242         }
  243 
  244         if ((error = scsipi_adapter_addref(chan->chan_adapter)) != 0)
  245                 return (error);
  246         atapi_adapter = (struct atapi_adapter*)chan->chan_adapter;
  247         for (target = mintarget; target <= maxtarget; target++)
  248                 atapi_adapter->atapi_probe_device(sc, target);
  249         scsipi_adapter_delref(chan->chan_adapter);
  250         return (0);
  251 }
  252 
  253 void *
  254 atapi_probe_device(struct atapibus_softc *sc, int target,
  255     struct scsipi_periph *periph, struct scsipibus_attach_args *sa)
  256 {
  257         struct scsipi_channel *chan = sc->sc_channel;
  258         struct scsi_quirk_inquiry_pattern *finger;
  259         struct cfdata *cf;
  260         int priority, quirks;
  261 
  262         finger = (struct scsi_quirk_inquiry_pattern *)scsipi_inqmatch(
  263             &sa->sa_inqbuf, (caddr_t)atapi_quirk_patterns,
  264             sizeof(atapi_quirk_patterns) /
  265                 sizeof(atapi_quirk_patterns[0]),
  266             sizeof(atapi_quirk_patterns[0]), &priority);
  267 
  268         if (finger != NULL)
  269                 quirks = finger->quirks;
  270         else
  271                 quirks = 0;
  272 
  273         /*
  274          * Now apply any quirks from the table.
  275          */
  276         periph->periph_quirks |= quirks;
  277 
  278         if ((cf = config_search_ia(atapibussubmatch, &sc->sc_dev,
  279             "atapibus", sa)) != 0) {
  280                 scsipi_insert_periph(chan, periph);
  281                 /*
  282                  * XXX Can't assign periph_dev here, because we'll
  283                  * XXX need it before config_attach() returns.  Must
  284                  * XXX assign it in periph driver.
  285                  */
  286                 return config_attach(&sc->sc_dev, cf, sa,
  287                     atapibusprint);
  288         } else {
  289                 atapibusprint(sa, sc->sc_dev.dv_xname);
  290                 printf(" not configured\n");
  291                 free(periph, M_DEVBUF);
  292                 return NULL;
  293         }
  294 }
  295 
  296 static int
  297 atapibusprint(void *aux, const char *pnp)
  298 {
  299         struct scsipibus_attach_args *sa = aux;
  300         struct scsipi_inquiry_pattern *inqbuf;
  301         const char *dtype;
  302 
  303         if (pnp != NULL)
  304                 aprint_normal("%s", pnp);
  305 
  306         inqbuf = &sa->sa_inqbuf;
  307 
  308         dtype = scsipi_dtype(inqbuf->type & SID_TYPE);
  309         aprint_normal(" drive %d: <%s, %s, %s> %s %s",
  310             sa->sa_periph->periph_target, inqbuf->vendor,
  311             inqbuf->product, inqbuf->revision, dtype,
  312             inqbuf->removable ? "removable" : "fixed");
  313         return (UNCONF);
  314 }

Cache object: 958ee3401c035aca5957d02a170d2c3d


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