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/geom/geom_apple.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  *
    3  * Copyright (c) 2002 Peter Grehan.
    4  * 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  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * $FreeBSD: releng/5.1/sys/geom/geom_apple.c 114508 2003-05-02 06:36:14Z phk $
   28  */
   29 
   30 /*
   31  * GEOM module for Apple Partition Maps
   32  *  As described in 'Inside Macintosh Vol 3: About the SCSI Manager -
   33  *    The Structure of Block Devices"
   34  */
   35 
   36 #include <sys/param.h>
   37 #include <sys/endian.h>
   38 #include <sys/systm.h>
   39 #include <sys/kernel.h>
   40 #include <sys/malloc.h>
   41 #include <sys/bio.h>
   42 #include <sys/lock.h>
   43 #include <sys/mutex.h>
   44 
   45 #include <sys/sbuf.h>
   46 #include <geom/geom.h>
   47 #include <geom/geom_slice.h>
   48 
   49 #define APPLE_CLASS_NAME "APPLE"
   50 
   51 #define NAPMPART  16    /* Max partitions */
   52 
   53 struct apm_partition {
   54         char       am_sig[2];
   55         u_int32_t  am_mapcnt;
   56         u_int32_t  am_start;
   57         u_int32_t  am_partcnt;
   58         char       am_name[32];
   59         char       am_type[32]; 
   60 };
   61 
   62 struct g_apple_softc {
   63         u_int16_t dd_bsiz;
   64         u_int32_t dd_blkcnt;
   65         u_int16_t dd_drvrcnt;
   66         u_int32_t am_mapcnt0;
   67         struct apm_partition apmpart[NAPMPART];
   68 };
   69 
   70 static void
   71 g_dec_drvrdesc(u_char *ptr, struct g_apple_softc *sc)
   72 {
   73         sc->dd_bsiz = be16dec(ptr + 2);
   74         sc->dd_blkcnt = be32dec(ptr + 4);
   75         sc->dd_drvrcnt = be32dec(ptr + 16);
   76 }
   77 
   78 static void
   79 g_dec_apple_partition(u_char *ptr, struct apm_partition *d)
   80 {
   81         d->am_sig[0] = ptr[0];
   82         d->am_sig[1] = ptr[1];
   83         d->am_mapcnt = be32dec(ptr + 4);
   84         d->am_start = be32dec(ptr + 8);
   85         d->am_partcnt = be32dec(ptr + 12);
   86         memcpy(d->am_name, ptr + 16, 32);
   87         memcpy(d->am_type, ptr + 48, 32);
   88 }
   89 
   90 static int
   91 g_apple_start(struct bio *bp)
   92 {
   93         struct g_provider *pp;
   94         struct g_geom *gp;
   95         struct g_apm_softc *mp;
   96         struct g_slicer *gsp;
   97 
   98         pp = bp->bio_to;
   99         gp = pp->geom;
  100         gsp = gp->softc;
  101         mp = gsp->softc;
  102         if (bp->bio_cmd == BIO_GETATTR) {
  103                 if (g_handleattr_off_t(bp, "APM::offset",
  104                     gsp->slices[pp->index].offset))
  105                         return (1);
  106         }
  107         return (0);
  108 }
  109 
  110 static void
  111 g_apple_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, 
  112     struct g_consumer *cp __unused, struct g_provider *pp)
  113 {
  114         struct g_apple_softc *mp;
  115         struct g_slicer *gsp;
  116 
  117         gsp = gp->softc;
  118         mp = gsp->softc;
  119         g_slice_dumpconf(sb, indent, gp, cp, pp);
  120         if (pp != NULL) {
  121                 if (indent == NULL)
  122                         sbuf_printf(sb, " n %s ty %s",
  123                             mp->apmpart[pp->index].am_name,
  124                             mp->apmpart[pp->index].am_type);
  125                 else {
  126                         sbuf_printf(sb, "%s<name>%s</name>\n", indent,
  127                             mp->apmpart[pp->index].am_name);
  128                         sbuf_printf(sb, "%s<type>%s</type>\n", indent,
  129                             mp->apmpart[pp->index].am_type);
  130                 }
  131         }
  132 }
  133 
  134 #if 0
  135 static void
  136 g_apple_print()
  137 {
  138 
  139         /* XXX */
  140 }
  141 #endif
  142 
  143 static struct g_geom *
  144 g_apple_taste(struct g_class *mp, struct g_provider *pp, int insist)
  145 {
  146         struct g_geom *gp;
  147         struct g_consumer *cp;
  148         int error, i, npart;
  149         struct g_apple_softc *ms;
  150         struct g_slicer *gsp;
  151         struct apm_partition *apm;
  152         u_int sectorsize;
  153         u_char *buf;
  154 
  155         g_trace(G_T_TOPOLOGY, "apple_taste(%s,%s)", mp->name, pp->name);
  156         g_topology_assert();
  157         gp = g_slice_new(mp, NAPMPART, pp, &cp, &ms, sizeof *ms, g_apple_start);
  158         if (gp == NULL)
  159                 return (NULL);
  160         gsp = gp->softc;
  161         g_topology_unlock();
  162         gp->dumpconf = g_apple_dumpconf;
  163         npart = 0;
  164         do {
  165                 if (gp->rank != 2 && insist == 0)
  166                         break;
  167 
  168                 sectorsize = cp->provider->sectorsize;
  169                 if (sectorsize != 512)
  170                         break;
  171 
  172                 buf = g_read_data(cp, 0, sectorsize, &error);
  173                 if (buf == NULL || error != 0)
  174                         break;
  175 
  176                 /*
  177                  * Test for the sector 0 driver record signature, and 
  178                  * validate sector and disk size
  179                  */
  180                 if (buf[0] != 'E' && buf[1] != 'R') {
  181                         g_free(buf);
  182                         break;
  183                 }
  184                 g_dec_drvrdesc(buf, ms);
  185                 g_free(buf);
  186 
  187                 if (ms->dd_bsiz != 512) {
  188                         break;
  189                 }
  190 
  191                 /*
  192                  * Read in the first partition map
  193                  */
  194                 buf = g_read_data(cp, sectorsize, sectorsize,  &error);
  195                 if (buf == NULL || error != 0)
  196                         break;
  197 
  198                 /*
  199                  * Decode the first partition: it's another indication of
  200                  * validity, as well as giving the size of the partition
  201                  * map
  202                  */
  203                 apm = &ms->apmpart[0];
  204                 g_dec_apple_partition(buf, apm);
  205                 g_free(buf);
  206                 
  207                 if (apm->am_sig[0] != 'P' || apm->am_sig[1] != 'M')
  208                         break;
  209                 ms->am_mapcnt0 = apm->am_mapcnt;
  210                
  211                 buf = g_read_data(cp, 2 * sectorsize, 
  212                     (NAPMPART - 1) * sectorsize,  &error);
  213                 if (buf == NULL || error != 0)
  214                         break;
  215 
  216                 for (i = 1; i < NAPMPART; i++) {
  217                         g_dec_apple_partition(buf + ((i - 1) * sectorsize),
  218                             &ms->apmpart[i]);
  219                 }
  220 
  221                 npart = 0;
  222                 for (i = 0; i < NAPMPART; i++) {
  223                         apm = &ms->apmpart[i];
  224 
  225                         /*
  226                          * Validate partition sig and global mapcount
  227                          */
  228                         if (apm->am_sig[0] != 'P' ||
  229                             apm->am_sig[1] != 'M')
  230                                 continue;
  231                         if (apm->am_mapcnt != ms->am_mapcnt0)
  232                                 continue;
  233 
  234                         if (bootverbose) {
  235                                 printf("APM Slice %d (%s/%s) on %s:\n", 
  236                                     i + 1, apm->am_name, apm->am_type, 
  237                                     gp->name);
  238                                 /* g_apple_print(i, dp + i); */
  239                         }
  240                         npart++;
  241                         g_topology_lock();
  242                         g_slice_config(gp, i, G_SLICE_CONFIG_SET,
  243                             (off_t)apm->am_start << 9ULL,
  244                             (off_t)apm->am_partcnt << 9ULL,
  245                             sectorsize,
  246                             "%ss%d", gp->name, i + 1);
  247                         g_topology_unlock();
  248                 }
  249                 g_free(buf);
  250                 break;
  251         } while(0);
  252         g_topology_lock();
  253         g_access_rel(cp, -1, 0, 0);
  254         if (LIST_EMPTY(&gp->provider)) {
  255                 g_slice_spoiled(cp);
  256                 return (NULL);
  257         }
  258         return (gp);
  259 }
  260 
  261 
  262 static struct g_class g_apple_class     = {
  263         .name = APPLE_CLASS_NAME,
  264         .taste = g_apple_taste,
  265         G_CLASS_INITIALIZER
  266 };
  267 
  268 DECLARE_GEOM_CLASS(g_apple_class, g_apple);

Cache object: 7a74deca639a05a8e4eee1a3f6f55798


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