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/part/g_part_pc98.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) 2008 Marcel Moolenaar
    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  *
    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 ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD: releng/10.0/sys/geom/part/g_part_pc98.c 254015 2013-08-07 00:00:48Z marcel $");
   29 
   30 #include <sys/param.h>
   31 #include <sys/bio.h>
   32 #include <sys/diskpc98.h>
   33 #include <sys/endian.h>
   34 #include <sys/kernel.h>
   35 #include <sys/kobj.h>
   36 #include <sys/limits.h>
   37 #include <sys/lock.h>
   38 #include <sys/malloc.h>
   39 #include <sys/mutex.h>
   40 #include <sys/queue.h>
   41 #include <sys/sbuf.h>
   42 #include <sys/systm.h>
   43 #include <sys/sysctl.h>
   44 #include <geom/geom.h>
   45 #include <geom/part/g_part.h>
   46 
   47 #include "g_part_if.h"
   48 
   49 FEATURE(geom_part_pc98, "GEOM partitioning class for PC-9800 disk partitions");
   50 
   51 #define SECSIZE         512
   52 #define MENUSIZE        7168
   53 #define BOOTSIZE        8192
   54 
   55 struct g_part_pc98_table {
   56         struct g_part_table     base;
   57         u_char          boot[SECSIZE];
   58         u_char          table[SECSIZE];
   59         u_char          menu[MENUSIZE];
   60 };
   61 
   62 struct g_part_pc98_entry {
   63         struct g_part_entry     base;
   64         struct pc98_partition ent;
   65 };
   66 
   67 static int g_part_pc98_add(struct g_part_table *, struct g_part_entry *,
   68     struct g_part_parms *);
   69 static int g_part_pc98_bootcode(struct g_part_table *, struct g_part_parms *);
   70 static int g_part_pc98_create(struct g_part_table *, struct g_part_parms *);
   71 static int g_part_pc98_destroy(struct g_part_table *, struct g_part_parms *);
   72 static void g_part_pc98_dumpconf(struct g_part_table *, struct g_part_entry *,
   73     struct sbuf *, const char *);
   74 static int g_part_pc98_dumpto(struct g_part_table *, struct g_part_entry *);
   75 static int g_part_pc98_modify(struct g_part_table *, struct g_part_entry *,  
   76     struct g_part_parms *);
   77 static const char *g_part_pc98_name(struct g_part_table *, struct g_part_entry *,
   78     char *, size_t);
   79 static int g_part_pc98_probe(struct g_part_table *, struct g_consumer *);
   80 static int g_part_pc98_read(struct g_part_table *, struct g_consumer *);
   81 static int g_part_pc98_setunset(struct g_part_table *, struct g_part_entry *,
   82     const char *, unsigned int);
   83 static const char *g_part_pc98_type(struct g_part_table *,
   84     struct g_part_entry *, char *, size_t);
   85 static int g_part_pc98_write(struct g_part_table *, struct g_consumer *);
   86 static int g_part_pc98_resize(struct g_part_table *, struct g_part_entry *,  
   87     struct g_part_parms *);
   88 
   89 static kobj_method_t g_part_pc98_methods[] = {
   90         KOBJMETHOD(g_part_add,          g_part_pc98_add),
   91         KOBJMETHOD(g_part_bootcode,     g_part_pc98_bootcode),
   92         KOBJMETHOD(g_part_create,       g_part_pc98_create),
   93         KOBJMETHOD(g_part_destroy,      g_part_pc98_destroy),
   94         KOBJMETHOD(g_part_dumpconf,     g_part_pc98_dumpconf),
   95         KOBJMETHOD(g_part_dumpto,       g_part_pc98_dumpto),
   96         KOBJMETHOD(g_part_modify,       g_part_pc98_modify),
   97         KOBJMETHOD(g_part_resize,       g_part_pc98_resize),
   98         KOBJMETHOD(g_part_name,         g_part_pc98_name),
   99         KOBJMETHOD(g_part_probe,        g_part_pc98_probe),
  100         KOBJMETHOD(g_part_read,         g_part_pc98_read),
  101         KOBJMETHOD(g_part_setunset,     g_part_pc98_setunset),
  102         KOBJMETHOD(g_part_type,         g_part_pc98_type),
  103         KOBJMETHOD(g_part_write,        g_part_pc98_write),
  104         { 0, 0 }
  105 };
  106 
  107 static struct g_part_scheme g_part_pc98_scheme = {
  108         "PC98",
  109         g_part_pc98_methods,
  110         sizeof(struct g_part_pc98_table),
  111         .gps_entrysz = sizeof(struct g_part_pc98_entry),
  112         .gps_minent = PC98_NPARTS,
  113         .gps_maxent = PC98_NPARTS,
  114         .gps_bootcodesz = BOOTSIZE,
  115 };
  116 G_PART_SCHEME_DECLARE(g_part_pc98);
  117 
  118 static int
  119 pc98_parse_type(const char *type, u_char *dp_mid, u_char *dp_sid)
  120 {
  121         const char *alias;
  122         char *endp;
  123         long lt;
  124 
  125         if (type[0] == '!') {
  126                 lt = strtol(type + 1, &endp, 0);
  127                 if (type[1] == '\0' || *endp != '\0' || lt <= 0 ||
  128                     lt >= 65536)
  129                         return (EINVAL);
  130                 /* Make sure the active and bootable flags aren't set. */
  131                 if (lt & ((PC98_SID_ACTIVE << 8) | PC98_MID_BOOTABLE))
  132                         return (ENOATTR);
  133                 *dp_mid = (*dp_mid & PC98_MID_BOOTABLE) | (u_char)lt;
  134                 *dp_sid = (*dp_sid & PC98_SID_ACTIVE) | (u_char)(lt >> 8);
  135                 return (0);
  136         }
  137         alias = g_part_alias_name(G_PART_ALIAS_FREEBSD);
  138         if (!strcasecmp(type, alias)) {
  139                 *dp_mid = (*dp_mid & PC98_MID_BOOTABLE) | PC98_MID_386BSD;
  140                 *dp_sid = (*dp_sid & PC98_SID_ACTIVE) | PC98_SID_386BSD;
  141                 return (0);
  142         }
  143         return (EINVAL);
  144 }
  145 
  146 static int
  147 pc98_set_slicename(const char *label, u_char *dp_name)
  148 {
  149         int len;
  150 
  151         len = strlen(label);
  152         if (len > sizeof(((struct pc98_partition *)NULL)->dp_name))
  153                 return (EINVAL);
  154         bzero(dp_name, sizeof(((struct pc98_partition *)NULL)->dp_name));
  155         strncpy(dp_name, label, len);
  156 
  157         return (0);
  158 }
  159 
  160 static void
  161 pc98_set_chs(struct g_part_table *table, uint32_t lba, u_short *cylp,
  162     u_char *hdp, u_char *secp)
  163 {
  164         uint32_t cyl, hd, sec;
  165 
  166         sec = lba % table->gpt_sectors + 1;
  167         lba /= table->gpt_sectors;
  168         hd = lba % table->gpt_heads;
  169         lba /= table->gpt_heads;
  170         cyl = lba;
  171 
  172         *cylp = htole16(cyl);
  173         *hdp = hd;
  174         *secp = sec;
  175 }
  176 
  177 static int
  178 g_part_pc98_add(struct g_part_table *basetable, struct g_part_entry *baseentry,
  179     struct g_part_parms *gpp)
  180 {
  181         struct g_part_pc98_entry *entry;
  182         struct g_part_pc98_table *table;
  183         uint32_t cyl, start, size;
  184         int error;
  185 
  186         cyl = basetable->gpt_heads * basetable->gpt_sectors;
  187 
  188         entry = (struct g_part_pc98_entry *)baseentry;
  189         table = (struct g_part_pc98_table *)basetable;
  190 
  191         start = gpp->gpp_start;
  192         size = gpp->gpp_size;
  193         if (size < cyl)
  194                 return (EINVAL);
  195         if (start % cyl) {
  196                 size = size - cyl + (start % cyl);
  197                 start = start - (start % cyl) + cyl;
  198         }
  199         if (size % cyl)
  200                 size = size - (size % cyl);
  201         if (size < cyl)
  202                 return (EINVAL);
  203 
  204         if (baseentry->gpe_deleted)
  205                 bzero(&entry->ent, sizeof(entry->ent));
  206         else
  207                 entry->ent.dp_mid = entry->ent.dp_sid = 0;
  208 
  209         KASSERT(baseentry->gpe_start <= start, (__func__));
  210         KASSERT(baseentry->gpe_end >= start + size - 1, (__func__));
  211         baseentry->gpe_start = start;
  212         baseentry->gpe_end = start + size - 1;
  213         pc98_set_chs(basetable, baseentry->gpe_start, &entry->ent.dp_scyl,
  214             &entry->ent.dp_shd, &entry->ent.dp_ssect);
  215         pc98_set_chs(basetable, baseentry->gpe_end, &entry->ent.dp_ecyl,
  216             &entry->ent.dp_ehd, &entry->ent.dp_esect);
  217 
  218         error = pc98_parse_type(gpp->gpp_type, &entry->ent.dp_mid,
  219             &entry->ent.dp_sid);
  220         if (error)
  221                 return (error);
  222 
  223         if (gpp->gpp_parms & G_PART_PARM_LABEL)
  224                 return (pc98_set_slicename(gpp->gpp_label, entry->ent.dp_name));
  225 
  226         return (0);
  227 }
  228 
  229 static int
  230 g_part_pc98_bootcode(struct g_part_table *basetable, struct g_part_parms *gpp)
  231 {
  232         struct g_part_pc98_table *table;
  233         const u_char *codeptr;
  234 
  235         if (gpp->gpp_codesize != BOOTSIZE)
  236                 return (EINVAL);
  237 
  238         table = (struct g_part_pc98_table *)basetable;
  239         codeptr = gpp->gpp_codeptr;
  240         bcopy(codeptr, table->boot, SECSIZE);
  241         bcopy(codeptr + SECSIZE*2, table->menu, MENUSIZE);
  242 
  243         return (0);
  244 }
  245 
  246 static int
  247 g_part_pc98_create(struct g_part_table *basetable, struct g_part_parms *gpp)
  248 {
  249         struct g_provider *pp;
  250         struct g_part_pc98_table *table;
  251 
  252         pp = gpp->gpp_provider;
  253         if (pp->sectorsize < SECSIZE || pp->mediasize < BOOTSIZE)
  254                 return (ENOSPC);
  255         if (pp->sectorsize > SECSIZE)
  256                 return (ENXIO);
  257 
  258         basetable->gpt_first = basetable->gpt_heads * basetable->gpt_sectors;
  259         basetable->gpt_last = MIN(pp->mediasize / SECSIZE, UINT32_MAX) - 1;
  260 
  261         table = (struct g_part_pc98_table *)basetable;
  262         le16enc(table->boot + PC98_MAGICOFS, PC98_MAGIC);
  263         return (0);
  264 }
  265 
  266 static int
  267 g_part_pc98_destroy(struct g_part_table *basetable, struct g_part_parms *gpp)
  268 {
  269 
  270         /* Wipe the first two sectors to clear the partitioning. */
  271         basetable->gpt_smhead |= 3;
  272         return (0);
  273 }
  274 
  275 static void
  276 g_part_pc98_dumpconf(struct g_part_table *table,
  277     struct g_part_entry *baseentry, struct sbuf *sb, const char *indent)
  278 {
  279         struct g_part_pc98_entry *entry;
  280         char name[sizeof(entry->ent.dp_name) + 1];
  281         u_int type;
  282 
  283         entry = (struct g_part_pc98_entry *)baseentry;
  284         if (entry == NULL) {
  285                 /* confxml: scheme information */
  286                 return;
  287         }
  288 
  289         type = entry->ent.dp_mid + (entry->ent.dp_sid << 8);
  290         strncpy(name, entry->ent.dp_name, sizeof(name) - 1);
  291         name[sizeof(name) - 1] = '\0';
  292         if (indent == NULL) {
  293                 /* conftxt: libdisk compatibility */
  294                 sbuf_printf(sb, " xs PC98 xt %u sn %s", type, name);
  295         } else {
  296                 /* confxml: partition entry information */
  297                 sbuf_printf(sb, "%s<label>%s</label>\n", indent, name);
  298                 if (entry->ent.dp_mid & PC98_MID_BOOTABLE)
  299                         sbuf_printf(sb, "%s<attrib>bootable</attrib>\n",
  300                             indent);
  301                 if (entry->ent.dp_sid & PC98_SID_ACTIVE)
  302                         sbuf_printf(sb, "%s<attrib>active</attrib>\n", indent);
  303                 sbuf_printf(sb, "%s<rawtype>%u</rawtype>\n", indent,
  304                     type & 0x7f7f);
  305         }
  306 }
  307 
  308 static int
  309 g_part_pc98_dumpto(struct g_part_table *table, struct g_part_entry *baseentry)  
  310 {
  311         struct g_part_pc98_entry *entry;
  312 
  313         /* Allow dumping to a FreeBSD partition only. */
  314         entry = (struct g_part_pc98_entry *)baseentry;
  315         return (((entry->ent.dp_mid & PC98_MID_MASK) == PC98_MID_386BSD &&
  316             (entry->ent.dp_sid & PC98_SID_MASK) == PC98_SID_386BSD) ? 1 : 0);
  317 }
  318 
  319 static int
  320 g_part_pc98_modify(struct g_part_table *basetable,
  321     struct g_part_entry *baseentry, struct g_part_parms *gpp)
  322 {
  323         struct g_part_pc98_entry *entry;
  324         int error;
  325 
  326         entry = (struct g_part_pc98_entry *)baseentry;
  327 
  328         if (gpp->gpp_parms & G_PART_PARM_TYPE) {
  329                 error = pc98_parse_type(gpp->gpp_type, &entry->ent.dp_mid,
  330                     &entry->ent.dp_sid);
  331                 if (error)
  332                         return (error);
  333         }
  334 
  335         if (gpp->gpp_parms & G_PART_PARM_LABEL)
  336                 return (pc98_set_slicename(gpp->gpp_label, entry->ent.dp_name));
  337 
  338         return (0);
  339 }
  340 
  341 static int
  342 g_part_pc98_resize(struct g_part_table *basetable,
  343     struct g_part_entry *baseentry, struct g_part_parms *gpp)
  344 {
  345         struct g_part_pc98_entry *entry;
  346         uint32_t size, cyl;
  347 
  348         cyl = basetable->gpt_heads * basetable->gpt_sectors;
  349         size = gpp->gpp_size;
  350 
  351         if (size < cyl)
  352                 return (EINVAL);
  353         if (size % cyl)
  354                 size = size - (size % cyl);
  355         if (size < cyl)
  356                 return (EINVAL);
  357 
  358         entry = (struct g_part_pc98_entry *)baseentry;
  359         baseentry->gpe_end = baseentry->gpe_start + size - 1;
  360         pc98_set_chs(basetable, baseentry->gpe_end, &entry->ent.dp_ecyl,
  361             &entry->ent.dp_ehd, &entry->ent.dp_esect);
  362 
  363         return (0);
  364 }
  365 
  366 static const char *
  367 g_part_pc98_name(struct g_part_table *table, struct g_part_entry *baseentry,
  368     char *buf, size_t bufsz)
  369 {
  370 
  371         snprintf(buf, bufsz, "s%d", baseentry->gpe_index);
  372         return (buf);
  373 }
  374 
  375 static int
  376 g_part_pc98_probe(struct g_part_table *table, struct g_consumer *cp)
  377 {
  378         struct g_provider *pp;
  379         u_char *buf, *p;
  380         int error, index, res, sum;
  381         uint16_t magic, ecyl, scyl;
  382 
  383         pp = cp->provider;
  384 
  385         /* Sanity-check the provider. */
  386         if (pp->sectorsize < SECSIZE || pp->mediasize < BOOTSIZE)
  387                 return (ENOSPC);
  388         if (pp->sectorsize > SECSIZE)
  389                 return (ENXIO);
  390 
  391         /* Check that there's a PC98 partition table. */
  392         buf = g_read_data(cp, 0L, 2 * SECSIZE, &error);
  393         if (buf == NULL)
  394                 return (error);
  395 
  396         /* We goto out on mismatch. */
  397         res = ENXIO;
  398 
  399         magic = le16dec(buf + PC98_MAGICOFS);
  400         if (magic != PC98_MAGIC)
  401                 goto out;
  402 
  403         sum = 0;
  404         for (index = SECSIZE; index < 2 * SECSIZE; index++)
  405                 sum += buf[index];
  406         if (sum == 0) {
  407                 res = G_PART_PROBE_PRI_LOW;
  408                 goto out;
  409         }
  410 
  411         for (index = 0; index < PC98_NPARTS; index++) {
  412                 p = buf + SECSIZE + index * PC98_PARTSIZE;
  413                 if (p[0] == 0 || p[1] == 0)     /* !dp_mid || !dp_sid */
  414                         continue;
  415                 scyl = le16dec(p + 10);
  416                 ecyl = le16dec(p + 14);
  417                 if (scyl == 0 || ecyl == 0)
  418                         goto out;
  419                 if (p[8] == p[12] &&            /* dp_ssect == dp_esect */
  420                     p[9] == p[13] &&            /* dp_shd == dp_ehd */
  421                     scyl == ecyl)
  422                         goto out;
  423         }
  424 
  425         res = G_PART_PROBE_PRI_HIGH;
  426 
  427  out:
  428         g_free(buf);
  429         return (res);
  430 }
  431 
  432 static int
  433 g_part_pc98_read(struct g_part_table *basetable, struct g_consumer *cp)
  434 {
  435         struct pc98_partition ent;
  436         struct g_provider *pp;
  437         struct g_part_pc98_table *table;
  438         struct g_part_pc98_entry *entry;
  439         u_char *buf, *p;
  440         off_t msize;
  441         off_t start, end;
  442         u_int cyl;
  443         int error, index;
  444 
  445         pp = cp->provider;
  446         table = (struct g_part_pc98_table *)basetable;
  447         msize = MIN(pp->mediasize / SECSIZE, UINT32_MAX);
  448 
  449         buf = g_read_data(cp, 0L, BOOTSIZE, &error);
  450         if (buf == NULL)
  451                 return (error);
  452 
  453         cyl = basetable->gpt_heads * basetable->gpt_sectors;
  454 
  455         bcopy(buf, table->boot, sizeof(table->boot));
  456         bcopy(buf + SECSIZE, table->table, sizeof(table->table));
  457         bcopy(buf + SECSIZE*2, table->menu, sizeof(table->menu));
  458 
  459         for (index = PC98_NPARTS - 1; index >= 0; index--) {
  460                 p = buf + SECSIZE + index * PC98_PARTSIZE;
  461                 ent.dp_mid = p[0];
  462                 ent.dp_sid = p[1];
  463                 ent.dp_dum1 = p[2];
  464                 ent.dp_dum2 = p[3];
  465                 ent.dp_ipl_sct = p[4];
  466                 ent.dp_ipl_head = p[5];
  467                 ent.dp_ipl_cyl = le16dec(p + 6);
  468                 ent.dp_ssect = p[8];
  469                 ent.dp_shd = p[9];
  470                 ent.dp_scyl = le16dec(p + 10);
  471                 ent.dp_esect = p[12];
  472                 ent.dp_ehd = p[13];
  473                 ent.dp_ecyl = le16dec(p + 14);
  474                 bcopy(p + 16, ent.dp_name, sizeof(ent.dp_name));
  475                 if (ent.dp_sid == 0)
  476                         continue;
  477 
  478                 start = ent.dp_scyl * cyl;
  479                 end = (ent.dp_ecyl + 1) * cyl - 1;
  480                 entry = (struct g_part_pc98_entry *)g_part_new_entry(basetable,
  481                     index + 1, start, end);
  482                 entry->ent = ent;
  483         }
  484 
  485         basetable->gpt_entries = PC98_NPARTS;
  486         basetable->gpt_first = cyl;
  487         basetable->gpt_last = msize - 1;
  488 
  489         g_free(buf);
  490         return (0);
  491 }
  492 
  493 static int
  494 g_part_pc98_setunset(struct g_part_table *table, struct g_part_entry *baseentry,
  495     const char *attrib, unsigned int set)
  496 {
  497         struct g_part_entry *iter;
  498         struct g_part_pc98_entry *entry;
  499         int changed, mid, sid;
  500 
  501         if (baseentry == NULL)
  502                 return (ENODEV);
  503 
  504         mid = sid = 0;
  505         if (strcasecmp(attrib, "active") == 0)
  506                 sid = 1;
  507         else if (strcasecmp(attrib, "bootable") == 0)
  508                 mid = 1;
  509         if (mid == 0 && sid == 0)
  510                 return (EINVAL);
  511 
  512         LIST_FOREACH(iter, &table->gpt_entry, gpe_entry) {
  513                 if (iter->gpe_deleted)
  514                         continue;
  515                 if (iter != baseentry)
  516                         continue;
  517                 changed = 0;
  518                 entry = (struct g_part_pc98_entry *)iter;
  519                 if (set) {
  520                         if (mid && !(entry->ent.dp_mid & PC98_MID_BOOTABLE)) {
  521                                 entry->ent.dp_mid |= PC98_MID_BOOTABLE;
  522                                 changed = 1;
  523                         }
  524                         if (sid && !(entry->ent.dp_sid & PC98_SID_ACTIVE)) {
  525                                 entry->ent.dp_sid |= PC98_SID_ACTIVE;
  526                                 changed = 1;
  527                         }
  528                 } else {
  529                         if (mid && (entry->ent.dp_mid & PC98_MID_BOOTABLE)) {
  530                                 entry->ent.dp_mid &= ~PC98_MID_BOOTABLE;
  531                                 changed = 1;
  532                         }
  533                         if (sid && (entry->ent.dp_sid & PC98_SID_ACTIVE)) {
  534                                 entry->ent.dp_sid &= ~PC98_SID_ACTIVE;
  535                                 changed = 1;
  536                         }
  537                 }
  538                 if (changed && !iter->gpe_created)
  539                         iter->gpe_modified = 1;
  540         }
  541         return (0);
  542 }
  543 
  544 static const char *
  545 g_part_pc98_type(struct g_part_table *basetable, struct g_part_entry *baseentry, 
  546     char *buf, size_t bufsz)
  547 {
  548         struct g_part_pc98_entry *entry;
  549         u_int type;
  550 
  551         entry = (struct g_part_pc98_entry *)baseentry;
  552         type = (entry->ent.dp_mid & PC98_MID_MASK) |
  553             ((entry->ent.dp_sid & PC98_SID_MASK) << 8);
  554         if (type == (PC98_MID_386BSD | (PC98_SID_386BSD << 8)))
  555                 return (g_part_alias_name(G_PART_ALIAS_FREEBSD));
  556         snprintf(buf, bufsz, "!%d", type);
  557         return (buf);
  558 }
  559 
  560 static int
  561 g_part_pc98_write(struct g_part_table *basetable, struct g_consumer *cp)
  562 {
  563         struct g_part_entry *baseentry;
  564         struct g_part_pc98_entry *entry;
  565         struct g_part_pc98_table *table;
  566         u_char *p;
  567         int error, index;
  568 
  569         table = (struct g_part_pc98_table *)basetable;
  570         baseentry = LIST_FIRST(&basetable->gpt_entry);
  571         for (index = 1; index <= basetable->gpt_entries; index++) {
  572                 p = table->table + (index - 1) * PC98_PARTSIZE;
  573                 entry = (baseentry != NULL && index == baseentry->gpe_index)
  574                     ? (struct g_part_pc98_entry *)baseentry : NULL;
  575                 if (entry != NULL && !baseentry->gpe_deleted) {
  576                         p[0] = entry->ent.dp_mid;
  577                         p[1] = entry->ent.dp_sid;
  578                         p[2] = entry->ent.dp_dum1;
  579                         p[3] = entry->ent.dp_dum2;
  580                         p[4] = entry->ent.dp_ipl_sct;
  581                         p[5] = entry->ent.dp_ipl_head;
  582                         le16enc(p + 6, entry->ent.dp_ipl_cyl);
  583                         p[8] = entry->ent.dp_ssect;
  584                         p[9] = entry->ent.dp_shd;
  585                         le16enc(p + 10, entry->ent.dp_scyl);
  586                         p[12] = entry->ent.dp_esect;
  587                         p[13] = entry->ent.dp_ehd;
  588                         le16enc(p + 14, entry->ent.dp_ecyl);
  589                         bcopy(entry->ent.dp_name, p + 16,
  590                             sizeof(entry->ent.dp_name));
  591                 } else
  592                         bzero(p, PC98_PARTSIZE);
  593 
  594                 if (entry != NULL)
  595                         baseentry = LIST_NEXT(baseentry, gpe_entry);
  596         }
  597 
  598         error = g_write_data(cp, 0, table->boot, SECSIZE);
  599         if (!error)
  600                 error = g_write_data(cp, SECSIZE, table->table, SECSIZE);
  601         if (!error)
  602                 error = g_write_data(cp, SECSIZE*2, table->menu, MENUSIZE);
  603         return (error);
  604 }

Cache object: d16fa647b68c90e30653358ef2c6f73a


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