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

Cache object: 394182611a3691d3d3b6540d92a64681


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