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/ofw/ofw_disk.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 /*-
    2  * Copyright (C) 2002 Benno Rice <benno@FreeBSD.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   17  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  */
   25 
   26 #include <sys/cdefs.h>
   27 __FBSDID("$FreeBSD: releng/9.0/sys/dev/ofw/ofw_disk.c 194139 2009-06-14 00:15:26Z marius $");
   28 
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/bio.h>
   32 #include <sys/kernel.h>
   33 #include <sys/kthread.h>
   34 #include <sys/linker.h>
   35 #include <sys/lock.h>
   36 #include <sys/malloc.h>
   37 #include <sys/mutex.h>
   38 #include <sys/proc.h>
   39 
   40 #include <geom/geom.h>
   41 
   42 #include <dev/ofw/openfirm.h>
   43 
   44 #define OFWD_BLOCKSIZE  512
   45 
   46 struct ofwd_softc
   47 {
   48         struct bio_queue_head ofwd_bio_queue;
   49         struct mtx      ofwd_queue_mtx;
   50         ihandle_t       ofwd_instance;
   51         off_t           ofwd_mediasize;
   52         unsigned        ofwd_sectorsize;
   53         unsigned        ofwd_fwheads;
   54         unsigned        ofwd_fwsectors;
   55         struct proc     *ofwd_procp;
   56         struct g_geom   *ofwd_gp;
   57         struct g_provider *ofwd_pp;
   58 } ofwd_softc;
   59 
   60 static g_init_t g_ofwd_init;
   61 static g_start_t g_ofwd_start;
   62 static g_access_t g_ofwd_access;
   63 
   64 struct g_class g_ofwd_class = {
   65         .name = "OFWD",
   66         .version = G_VERSION,
   67         .init = g_ofwd_init,
   68         .start = g_ofwd_start,
   69         .access = g_ofwd_access,
   70 };
   71 
   72 DECLARE_GEOM_CLASS(g_ofwd_class, g_ofwd);
   73 
   74 static int ofwd_enable = 0;
   75 TUNABLE_INT("kern.ofw.disk", &ofwd_enable);
   76 
   77 static int
   78 ofwd_startio(struct ofwd_softc *sc, struct bio *bp)
   79 {
   80         u_int r;
   81 
   82         r = OF_seek(sc->ofwd_instance, bp->bio_offset);
   83 
   84         switch (bp->bio_cmd) {
   85         case BIO_READ:
   86                 r = OF_read(sc->ofwd_instance, (void *)bp->bio_data,
   87                    bp->bio_length);
   88                 break;
   89         case BIO_WRITE:
   90                 r = OF_write(sc->ofwd_instance, (void *)bp->bio_data,
   91                    bp->bio_length);
   92                 break;
   93         }
   94         if (r != bp->bio_length)
   95                 panic("ofwd: incorrect i/o count");
   96 
   97         bp->bio_resid = 0;
   98         return (0);
   99 }
  100 
  101 static void
  102 ofwd_kthread(void *arg)
  103 {
  104         struct ofwd_softc *sc;
  105         struct bio *bp;
  106         int error;
  107 
  108         sc = arg;
  109         curthread->td_base_pri = PRIBIO;
  110 
  111         for (;;) {
  112                 mtx_lock(&sc->ofwd_queue_mtx);
  113                 bp = bioq_takefirst(&sc->ofwd_bio_queue);
  114                 if (!bp) {
  115                         msleep(sc, &sc->ofwd_queue_mtx, PRIBIO | PDROP,
  116                             "ofwdwait", 0);
  117                         continue;
  118                 }
  119                 mtx_unlock(&sc->ofwd_queue_mtx);
  120                 if (bp->bio_cmd == BIO_GETATTR) {
  121                         error = EOPNOTSUPP;
  122                 } else
  123                         error = ofwd_startio(sc, bp);
  124 
  125                 if (error != -1) {
  126                         bp->bio_completed = bp->bio_length;
  127                         g_io_deliver(bp, error);
  128                 }
  129         }
  130 }
  131 
  132 static void
  133 g_ofwd_init(struct g_class *mp __unused)
  134 {
  135         char path[128];
  136         char fname[32];
  137         phandle_t ofd;
  138         struct ofwd_softc *sc;
  139         struct g_geom *gp;
  140         struct g_provider *pp;
  141         ihandle_t ifd;
  142         int error;
  143 
  144         if (ofwd_enable == 0)
  145                 return;
  146 
  147         ofd = OF_finddevice("ofwdisk");
  148         if (ofd == -1)
  149                 return;
  150 
  151         bzero(path, 128);
  152         OF_package_to_path(ofd, path, 128);
  153         OF_getprop(ofd, "file", fname, sizeof(fname));
  154         printf("ofw_disk located at %s, file %s\n", path, fname);
  155         ifd = OF_open(path);
  156         if (ifd == -1) {
  157                 printf("ofw_disk: could not create instance\n");
  158                 return;
  159         }
  160 
  161         sc = (struct ofwd_softc *)malloc(sizeof *sc, M_DEVBUF,
  162             M_WAITOK | M_ZERO);
  163         bioq_init(&sc->ofwd_bio_queue);
  164         mtx_init(&sc->ofwd_queue_mtx, "ofwd bio queue", NULL, MTX_DEF);
  165         sc->ofwd_instance = ifd;
  166         sc->ofwd_mediasize = (off_t)2 * 33554432;
  167         sc->ofwd_sectorsize = OFWD_BLOCKSIZE;
  168         sc->ofwd_fwsectors = 0;
  169         sc->ofwd_fwheads = 0;
  170         error = kproc_create(ofwd_kthread, sc, &sc->ofwd_procp, 0, 0,
  171             "ofwd0");
  172         if (error != 0) {
  173                 free(sc, M_DEVBUF);
  174                 return;
  175         }
  176 
  177         gp = g_new_geomf(&g_ofwd_class, "ofwd0");
  178         gp->softc = sc;
  179         pp = g_new_providerf(gp, "ofwd0");
  180         pp->mediasize = sc->ofwd_mediasize;
  181         pp->sectorsize = sc->ofwd_sectorsize;
  182         sc->ofwd_gp = gp;
  183         sc->ofwd_pp = pp;
  184         g_error_provider(pp, 0);
  185 }
  186 
  187 static void
  188 g_ofwd_start(struct bio *bp)
  189 {
  190         struct ofwd_softc *sc;
  191 
  192         sc = bp->bio_to->geom->softc;
  193         mtx_lock(&sc->ofwd_queue_mtx);
  194         bioq_disksort(&sc->ofwd_bio_queue, bp);
  195         mtx_unlock(&sc->ofwd_queue_mtx);
  196         wakeup(sc);
  197 }
  198 
  199 static int
  200 g_ofwd_access(struct g_provider *pp, int r, int w, int e)
  201 {
  202 
  203         if (pp->geom->softc == NULL)
  204                 return (ENXIO);
  205         return (0);
  206 }

Cache object: adcbcd7b31e538832fbb6087277d3dd2


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