aboutsummaryrefslogtreecommitdiff
path: root/sys/geom
diff options
context:
space:
mode:
authorYoshihiro Takahashi <nyan@FreeBSD.org>2017-01-28 02:22:15 +0000
committerYoshihiro Takahashi <nyan@FreeBSD.org>2017-01-28 02:22:15 +0000
commit2b375b4edd1b98884c3031d6ccd61acb10bd895d (patch)
treef35e4f57ad890ac86d5cb5d3ef760344a41fc0e6 /sys/geom
parent34bac11eba2841255bf6319ec78728f0f941c6ac (diff)
downloadsrc-2b375b4edd1b98884c3031d6ccd61acb10bd895d.tar.gz
src-2b375b4edd1b98884c3031d6ccd61acb10bd895d.zip
Remove pc98 support completely.
I thank all developers and contributors for pc98. Relnotes: yes
Notes
Notes: svn path=/head/; revision=312910
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/geom_bsd.c10
-rw-r--r--sys/geom/geom_pc98.c372
-rw-r--r--sys/geom/geom_pc98_enc.c78
-rw-r--r--sys/geom/part/g_part_pc98.c617
4 files changed, 0 insertions, 1077 deletions
diff --git a/sys/geom/geom_bsd.c b/sys/geom/geom_bsd.c
index 6cb65cd0366c..be3ec333aec9 100644
--- a/sys/geom/geom_bsd.c
+++ b/sys/geom/geom_bsd.c
@@ -441,16 +441,6 @@ g_bsd_taste(struct g_class *mp, struct g_provider *pp, int flags)
break;
}
- /* Same thing if we are inside a PC98 */
- error = g_getattr("PC98::type", cp, &i);
- if (!error) {
- if (i != 0xc494 && flags == G_TF_NORMAL)
- break;
- error = g_getattr("PC98::offset", cp, &ms->mbroffset);
- if (error)
- break;
- }
-
/* Same thing if we are inside a GPT */
error = g_getattr("GPT::type", cp, &uuid);
if (!error) {
diff --git a/sys/geom/geom_pc98.c b/sys/geom/geom_pc98.c
deleted file mode 100644
index f4435cb103a9..000000000000
--- a/sys/geom/geom_pc98.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*-
- * Copyright (c) 2002 Poul-Henning Kamp
- * Copyright (c) 2002 Networks Associates Technology, Inc.
- * All rights reserved.
- *
- * This software was developed for the FreeBSD Project by Poul-Henning Kamp
- * and NAI Labs, the Security Research Division of Network Associates, Inc.
- * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
- * DARPA CHATS research program.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/endian.h>
-#include <sys/systm.h>
-#include <sys/sysctl.h>
-#include <sys/kernel.h>
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-#include <sys/bio.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/sbuf.h>
-
-#include <sys/diskpc98.h>
-#include <geom/geom.h>
-#include <geom/geom_slice.h>
-
-FEATURE(geom_pc98, "GEOM NEC PC9800 partitioning support");
-
-#define PC98_CLASS_NAME "PC98"
-
-struct g_pc98_softc {
- u_int fwsectors, fwheads, sectorsize;
- int type[PC98_NPARTS];
- u_char sec[8192];
-};
-
-static void
-g_pc98_print(int i, struct pc98_partition *dp)
-{
- char sname[17];
-
- strncpy(sname, dp->dp_name, 16);
- sname[16] = '\0';
-
- hexdump(dp, sizeof(dp[0]), NULL, 0);
- printf("[%d] mid:%d(0x%x) sid:%d(0x%x)",
- i, dp->dp_mid, dp->dp_mid, dp->dp_sid, dp->dp_sid);
- printf(" s:%d/%d/%d", dp->dp_scyl, dp->dp_shd, dp->dp_ssect);
- printf(" e:%d/%d/%d", dp->dp_ecyl, dp->dp_ehd, dp->dp_esect);
- printf(" sname:%s\n", sname);
-}
-
-/*
- * XXX: Add gctl_req arg and give good error msgs.
- * XXX: Check that length argument does not bring boot code inside any slice.
- */
-static int
-g_pc98_modify(struct g_geom *gp, struct g_pc98_softc *ms, u_char *sec, int len __unused)
-{
- int i, error;
- off_t s[PC98_NPARTS], l[PC98_NPARTS];
- struct pc98_partition dp[PC98_NPARTS];
-
- g_topology_assert();
-
- if (sec[0x1fe] != 0x55 || sec[0x1ff] != 0xaa)
- return (EBUSY);
-
-#if 0
- /*
- * By convetion, it seems that the ipl program has a jump at location
- * 0 to the real start of the boot loader. By convetion, it appears
- * that after this jump, there's a string, terminated by at last one,
- * if not more, zeros, followed by the target of the jump. FreeBSD's
- * pc98 boot0 uses 'IPL1' followed by 3 zeros here, likely for
- * compatibility with some older boot loader. Linux98's boot loader
- * appears to use 'Linux 98' followed by only two. GRUB/98 appears to
- * use 'GRUB/98 ' followed by none. These last two appear to be
- * ported from the ia32 versions, but appear to show similar
- * convention. Grub/98 has an additional NOP after the jmp, which
- * isn't present in others.
- *
- * The following test was inspired by looking only at partitions
- * with FreeBSD's boot0 (or one that it is compatible with). As
- * such, if failed when other IPL programs were used.
- */
- if (sec[4] != 'I' || sec[5] != 'P' || sec[6] != 'L' || sec[7] != '1')
- return (EBUSY);
-#endif
-
- for (i = 0; i < PC98_NPARTS; i++)
- pc98_partition_dec(
- sec + 512 + i * sizeof(struct pc98_partition), &dp[i]);
-
- for (i = 0; i < PC98_NPARTS; i++) {
- /* If start and end are identical it's bogus */
- if (dp[i].dp_ssect == dp[i].dp_esect &&
- dp[i].dp_shd == dp[i].dp_ehd &&
- dp[i].dp_scyl == dp[i].dp_ecyl)
- s[i] = l[i] = 0;
- else if (dp[i].dp_ecyl == 0)
- s[i] = l[i] = 0;
- else {
- s[i] = (off_t)dp[i].dp_scyl *
- ms->fwsectors * ms->fwheads * ms->sectorsize;
- l[i] = (off_t)(dp[i].dp_ecyl - dp[i].dp_scyl + 1) *
- ms->fwsectors * ms->fwheads * ms->sectorsize;
- }
- if (bootverbose) {
- printf("PC98 Slice %d on %s:\n", i + 1, gp->name);
- g_pc98_print(i, dp + i);
- }
- if (s[i] < 0 || l[i] < 0)
- error = EBUSY;
- else
- error = g_slice_config(gp, i, G_SLICE_CONFIG_CHECK,
- s[i], l[i], ms->sectorsize,
- "%ss%d", gp->name, i + 1);
- if (error)
- return (error);
- }
-
- for (i = 0; i < PC98_NPARTS; i++) {
- ms->type[i] = (dp[i].dp_sid << 8) | dp[i].dp_mid;
- g_slice_config(gp, i, G_SLICE_CONFIG_SET, s[i], l[i],
- ms->sectorsize, "%ss%d", gp->name, i + 1);
- }
-
- bcopy(sec, ms->sec, sizeof (ms->sec));
-
- return (0);
-}
-
-static int
-g_pc98_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td)
-{
- struct g_geom *gp;
- struct g_pc98_softc *ms;
- struct g_slicer *gsp;
- struct g_consumer *cp;
- int error, opened;
-
- gp = pp->geom;
- gsp = gp->softc;
- ms = gsp->softc;
-
- opened = 0;
- error = 0;
- switch(cmd) {
- case DIOCSPC98: {
- if (!(fflag & FWRITE))
- return (EPERM);
- g_topology_lock();
- cp = LIST_FIRST(&gp->consumer);
- if (cp->acw == 0) {
- error = g_access(cp, 0, 1, 0);
- if (error == 0)
- opened = 1;
- }
- if (!error)
- error = g_pc98_modify(gp, ms, data, 8192);
- if (!error)
- error = g_write_data(cp, 0, data, 8192);
- if (opened)
- g_access(cp, 0, -1 , 0);
- g_topology_unlock();
- return(error);
- }
- default:
- return (ENOIOCTL);
- }
-}
-
-static int
-g_pc98_start(struct bio *bp)
-{
- struct g_provider *pp;
- struct g_geom *gp;
- struct g_pc98_softc *mp;
- struct g_slicer *gsp;
- int idx;
-
- pp = bp->bio_to;
- idx = pp->index;
- gp = pp->geom;
- gsp = gp->softc;
- mp = gsp->softc;
- if (bp->bio_cmd == BIO_GETATTR) {
- if (g_handleattr_int(bp, "PC98::type", mp->type[idx]))
- return (1);
- if (g_handleattr_off_t(bp, "PC98::offset",
- gsp->slices[idx].offset))
- return (1);
- }
-
- return (0);
-}
-
-static void
-g_pc98_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
- struct g_consumer *cp __unused, struct g_provider *pp)
-{
- struct g_pc98_softc *mp;
- struct g_slicer *gsp;
- struct pc98_partition dp;
- char sname[17];
-
- gsp = gp->softc;
- mp = gsp->softc;
- g_slice_dumpconf(sb, indent, gp, cp, pp);
- if (pp != NULL) {
- pc98_partition_dec(
- mp->sec + 512 +
- pp->index * sizeof(struct pc98_partition), &dp);
- strncpy(sname, dp.dp_name, 16);
- sname[16] = '\0';
- if (indent == NULL) {
- sbuf_printf(sb, " ty %d", mp->type[pp->index]);
- sbuf_printf(sb, " sn %s", sname);
- } else {
- sbuf_printf(sb, "%s<type>%d</type>\n", indent,
- mp->type[pp->index]);
- sbuf_printf(sb, "%s<sname>%s</sname>\n", indent,
- sname);
- }
- }
-}
-
-static struct g_geom *
-g_pc98_taste(struct g_class *mp, struct g_provider *pp, int flags)
-{
- struct g_geom *gp;
- struct g_consumer *cp;
- int error;
- struct g_pc98_softc *ms;
- u_int fwsectors, fwheads, sectorsize;
- u_char *buf;
-
- g_trace(G_T_TOPOLOGY, "g_pc98_taste(%s,%s)", mp->name, pp->name);
- g_topology_assert();
- if (flags == G_TF_NORMAL &&
- !strcmp(pp->geom->class->name, PC98_CLASS_NAME))
- return (NULL);
- gp = g_slice_new(mp, PC98_NPARTS, pp, &cp, &ms, sizeof *ms,
- g_pc98_start);
- if (gp == NULL)
- return (NULL);
- g_topology_unlock();
- do {
- if (gp->rank != 2 && flags == G_TF_NORMAL)
- break;
- error = g_getattr("GEOM::fwsectors", cp, &fwsectors);
- if (error || fwsectors == 0) {
- fwsectors = 17;
- if (bootverbose)
- printf("g_pc98_taste: guessing %d sectors\n",
- fwsectors);
- }
- error = g_getattr("GEOM::fwheads", cp, &fwheads);
- if (error || fwheads == 0) {
- fwheads = 8;
- if (bootverbose)
- printf("g_pc98_taste: guessing %d heads\n",
- fwheads);
- }
- sectorsize = cp->provider->sectorsize;
- if (sectorsize % 512 != 0)
- break;
- buf = g_read_data(cp, 0, 8192, NULL);
- if (buf == NULL)
- break;
- ms->fwsectors = fwsectors;
- ms->fwheads = fwheads;
- ms->sectorsize = sectorsize;
- g_topology_lock();
- g_pc98_modify(gp, ms, buf, 8192);
- g_topology_unlock();
- g_free(buf);
- break;
- } while (0);
- g_topology_lock();
- g_access(cp, -1, 0, 0);
- if (LIST_EMPTY(&gp->provider)) {
- g_slice_spoiled(cp);
- return (NULL);
- }
- return (gp);
-}
-
-static void
-g_pc98_config(struct gctl_req *req, struct g_class *mp, const char *verb)
-{
- struct g_geom *gp;
- struct g_consumer *cp;
- struct g_pc98_softc *ms;
- struct g_slicer *gsp;
- int opened = 0, error = 0;
- void *data;
- int len;
-
- g_topology_assert();
- gp = gctl_get_geom(req, mp, "geom");
- if (gp == NULL)
- return;
- if (strcmp(verb, "write PC98")) {
- gctl_error(req, "Unknown verb");
- return;
- }
- gsp = gp->softc;
- ms = gsp->softc;
- data = gctl_get_param(req, "data", &len);
- if (data == NULL)
- return;
- if (len < 8192 || (len % 512)) {
- gctl_error(req, "Wrong request length");
- return;
- }
- cp = LIST_FIRST(&gp->consumer);
- if (cp->acw == 0) {
- error = g_access(cp, 0, 1, 0);
- if (error == 0)
- opened = 1;
- }
- if (!error)
- error = g_pc98_modify(gp, ms, data, len);
- if (error)
- gctl_error(req, "conflict with open slices");
- if (!error)
- error = g_write_data(cp, 0, data, len);
- if (error)
- gctl_error(req, "sector zero write failed");
- if (opened)
- g_access(cp, 0, -1 , 0);
- return;
-}
-
-static struct g_class g_pc98_class = {
- .name = PC98_CLASS_NAME,
- .version = G_VERSION,
- .taste = g_pc98_taste,
- .dumpconf = g_pc98_dumpconf,
- .ctlreq = g_pc98_config,
- .ioctl = g_pc98_ioctl,
-};
-
-DECLARE_GEOM_CLASS(g_pc98_class, g_pc98);
diff --git a/sys/geom/geom_pc98_enc.c b/sys/geom/geom_pc98_enc.c
deleted file mode 100644
index cf0f7f3fe7bc..000000000000
--- a/sys/geom/geom_pc98_enc.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*-
- * Copyright (c) 2003 TAKAHASHI Yoshihiro
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <sys/diskpc98.h>
-#include <sys/endian.h>
-
-void
-pc98_partition_dec(void const *pp, struct pc98_partition *d)
-{
- unsigned char const *ptr = pp;
- u_int i;
-
- d->dp_mid = ptr[0];
- d->dp_sid = ptr[1];
- d->dp_dum1 = ptr[2];
- d->dp_dum2 = ptr[3];
- d->dp_ipl_sct = ptr[4];
- d->dp_ipl_head = ptr[5];
- d->dp_ipl_cyl = le16dec(ptr + 6);
- d->dp_ssect = ptr[8];
- d->dp_shd = ptr[9];
- d->dp_scyl = le16dec(ptr + 10);
- d->dp_esect = ptr[12];
- d->dp_ehd = ptr[13];
- d->dp_ecyl = le16dec(ptr + 14);
- for (i = 0; i < sizeof (d->dp_name); i++)
- d->dp_name[i] = ptr[16 + i];
-}
-
-void
-pc98_partition_enc(void *pp, struct pc98_partition *d)
-{
- unsigned char *ptr = pp;
- u_int i;
-
- ptr[0] = d->dp_mid;
- ptr[1] = d->dp_sid;
- ptr[2] = d->dp_dum1;
- ptr[3] = d->dp_dum2;
- ptr[4] = d->dp_ipl_sct;
- ptr[5] = d->dp_ipl_head;
- le16enc(ptr + 6, d->dp_ipl_cyl);
- ptr[8] = d->dp_ssect;
- ptr[9] = d->dp_shd;
- le16enc(ptr + 10, d->dp_scyl);
- ptr[12] = d->dp_esect;
- ptr[13] = d->dp_ehd;
- le16enc(ptr + 14, d->dp_ecyl);
- for (i = 0; i < sizeof (d->dp_name); i++)
- ptr[16 + i] = d->dp_name[i];
-}
diff --git a/sys/geom/part/g_part_pc98.c b/sys/geom/part/g_part_pc98.c
deleted file mode 100644
index 2012d2b28220..000000000000
--- a/sys/geom/part/g_part_pc98.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/*-
- * Copyright (c) 2008 Marcel Moolenaar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/bio.h>
-#include <sys/diskpc98.h>
-#include <sys/endian.h>
-#include <sys/kernel.h>
-#include <sys/kobj.h>
-#include <sys/limits.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/queue.h>
-#include <sys/sbuf.h>
-#include <sys/systm.h>
-#include <sys/sysctl.h>
-#include <geom/geom.h>
-#include <geom/geom_int.h>
-#include <geom/part/g_part.h>
-
-#include "g_part_if.h"
-
-FEATURE(geom_part_pc98, "GEOM partitioning class for PC-9800 disk partitions");
-
-#define SECSIZE 512
-#define MENUSIZE 7168
-#define BOOTSIZE 8192
-
-struct g_part_pc98_table {
- struct g_part_table base;
- u_char boot[SECSIZE];
- u_char table[SECSIZE];
- u_char menu[MENUSIZE];
-};
-
-struct g_part_pc98_entry {
- struct g_part_entry base;
- struct pc98_partition ent;
-};
-
-static int g_part_pc98_add(struct g_part_table *, struct g_part_entry *,
- struct g_part_parms *);
-static int g_part_pc98_bootcode(struct g_part_table *, struct g_part_parms *);
-static int g_part_pc98_create(struct g_part_table *, struct g_part_parms *);
-static int g_part_pc98_destroy(struct g_part_table *, struct g_part_parms *);
-static void g_part_pc98_dumpconf(struct g_part_table *, struct g_part_entry *,
- struct sbuf *, const char *);
-static int g_part_pc98_dumpto(struct g_part_table *, struct g_part_entry *);
-static int g_part_pc98_modify(struct g_part_table *, struct g_part_entry *,
- struct g_part_parms *);
-static const char *g_part_pc98_name(struct g_part_table *, struct g_part_entry *,
- char *, size_t);
-static int g_part_pc98_probe(struct g_part_table *, struct g_consumer *);
-static int g_part_pc98_read(struct g_part_table *, struct g_consumer *);
-static int g_part_pc98_setunset(struct g_part_table *, struct g_part_entry *,
- const char *, unsigned int);
-static const char *g_part_pc98_type(struct g_part_table *,
- struct g_part_entry *, char *, size_t);
-static int g_part_pc98_write(struct g_part_table *, struct g_consumer *);
-static int g_part_pc98_resize(struct g_part_table *, struct g_part_entry *,
- struct g_part_parms *);
-
-static kobj_method_t g_part_pc98_methods[] = {
- KOBJMETHOD(g_part_add, g_part_pc98_add),
- KOBJMETHOD(g_part_bootcode, g_part_pc98_bootcode),
- KOBJMETHOD(g_part_create, g_part_pc98_create),
- KOBJMETHOD(g_part_destroy, g_part_pc98_destroy),
- KOBJMETHOD(g_part_dumpconf, g_part_pc98_dumpconf),
- KOBJMETHOD(g_part_dumpto, g_part_pc98_dumpto),
- KOBJMETHOD(g_part_modify, g_part_pc98_modify),
- KOBJMETHOD(g_part_resize, g_part_pc98_resize),
- KOBJMETHOD(g_part_name, g_part_pc98_name),
- KOBJMETHOD(g_part_probe, g_part_pc98_probe),
- KOBJMETHOD(g_part_read, g_part_pc98_read),
- KOBJMETHOD(g_part_setunset, g_part_pc98_setunset),
- KOBJMETHOD(g_part_type, g_part_pc98_type),
- KOBJMETHOD(g_part_write, g_part_pc98_write),
- { 0, 0 }
-};
-
-static struct g_part_scheme g_part_pc98_scheme = {
- "PC98",
- g_part_pc98_methods,
- sizeof(struct g_part_pc98_table),
- .gps_entrysz = sizeof(struct g_part_pc98_entry),
- .gps_minent = PC98_NPARTS,
- .gps_maxent = PC98_NPARTS,
- .gps_bootcodesz = BOOTSIZE,
-};
-G_PART_SCHEME_DECLARE(g_part_pc98);
-
-static int
-pc98_parse_type(const char *type, u_char *dp_mid, u_char *dp_sid)
-{
- const char *alias;
- char *endp;
- long lt;
-
- if (type[0] == '!') {
- lt = strtol(type + 1, &endp, 0);
- if (type[1] == '\0' || *endp != '\0' || lt <= 0 ||
- lt >= 65536)
- return (EINVAL);
- /* Make sure the active and bootable flags aren't set. */
- if (lt & ((PC98_SID_ACTIVE << 8) | PC98_MID_BOOTABLE))
- return (ENOATTR);
- *dp_mid = (*dp_mid & PC98_MID_BOOTABLE) | (u_char)lt;
- *dp_sid = (*dp_sid & PC98_SID_ACTIVE) | (u_char)(lt >> 8);
- return (0);
- }
- alias = g_part_alias_name(G_PART_ALIAS_FREEBSD);
- if (!strcasecmp(type, alias)) {
- *dp_mid = (*dp_mid & PC98_MID_BOOTABLE) | PC98_MID_386BSD;
- *dp_sid = (*dp_sid & PC98_SID_ACTIVE) | PC98_SID_386BSD;
- return (0);
- }
- return (EINVAL);
-}
-
-static int
-pc98_set_slicename(const char *label, u_char *dp_name)
-{
- int len;
-
- len = strlen(label);
- if (len > sizeof(((struct pc98_partition *)NULL)->dp_name))
- return (EINVAL);
- bzero(dp_name, sizeof(((struct pc98_partition *)NULL)->dp_name));
- strncpy(dp_name, label, len);
-
- return (0);
-}
-
-static void
-pc98_set_chs(struct g_part_table *table, uint32_t lba, u_short *cylp,
- u_char *hdp, u_char *secp)
-{
- uint32_t cyl, hd, sec;
-
- sec = lba % table->gpt_sectors + 1;
- lba /= table->gpt_sectors;
- hd = lba % table->gpt_heads;
- lba /= table->gpt_heads;
- cyl = lba;
-
- *cylp = htole16(cyl);
- *hdp = hd;
- *secp = sec;
-}
-
-static int
-pc98_align(struct g_part_table *basetable, uint32_t *start, uint32_t *size)
-{
- uint32_t cyl;
-
- cyl = basetable->gpt_heads * basetable->gpt_sectors;
- if (*size < cyl)
- return (EINVAL);
- if (start != NULL && (*start % cyl)) {
- *size += (*start % cyl) - cyl;
- *start -= (*start % cyl) - cyl;
- }
- if (*size % cyl)
- *size -= (*size % cyl);
- if (*size < cyl)
- return (EINVAL);
- return (0);
-}
-
-static int
-g_part_pc98_add(struct g_part_table *basetable, struct g_part_entry *baseentry,
- struct g_part_parms *gpp)
-{
- struct g_part_pc98_entry *entry;
- uint32_t start, size;
- int error;
-
- entry = (struct g_part_pc98_entry *)baseentry;
- start = gpp->gpp_start;
- size = gpp->gpp_size;
- if (pc98_align(basetable, &start, &size) != 0)
- return (EINVAL);
- if (baseentry->gpe_deleted)
- bzero(&entry->ent, sizeof(entry->ent));
- else
- entry->ent.dp_mid = entry->ent.dp_sid = 0;
-
- KASSERT(baseentry->gpe_start <= start, (__func__));
- KASSERT(baseentry->gpe_end >= start + size - 1, (__func__));
- baseentry->gpe_start = start;
- baseentry->gpe_end = start + size - 1;
- pc98_set_chs(basetable, baseentry->gpe_start, &entry->ent.dp_scyl,
- &entry->ent.dp_shd, &entry->ent.dp_ssect);
- pc98_set_chs(basetable, baseentry->gpe_end, &entry->ent.dp_ecyl,
- &entry->ent.dp_ehd, &entry->ent.dp_esect);
-
- error = pc98_parse_type(gpp->gpp_type, &entry->ent.dp_mid,
- &entry->ent.dp_sid);
- if (error)
- return (error);
-
- if (gpp->gpp_parms & G_PART_PARM_LABEL)
- return (pc98_set_slicename(gpp->gpp_label, entry->ent.dp_name));
-
- return (0);
-}
-
-static int
-g_part_pc98_bootcode(struct g_part_table *basetable, struct g_part_parms *gpp)
-{
- struct g_part_pc98_table *table;
- const u_char *codeptr;
-
- if (gpp->gpp_codesize != BOOTSIZE)
- return (EINVAL);
-
- table = (struct g_part_pc98_table *)basetable;
- codeptr = gpp->gpp_codeptr;
- bcopy(codeptr, table->boot, SECSIZE);
- bcopy(codeptr + SECSIZE*2, table->menu, MENUSIZE);
-
- return (0);
-}
-
-static int
-g_part_pc98_create(struct g_part_table *basetable, struct g_part_parms *gpp)
-{
- struct g_provider *pp;
- struct g_part_pc98_table *table;
-
- pp = gpp->gpp_provider;
- if (pp->sectorsize < SECSIZE || pp->mediasize < BOOTSIZE)
- return (ENOSPC);
- if (pp->sectorsize > SECSIZE)
- return (ENXIO);
-
- basetable->gpt_first = basetable->gpt_heads * basetable->gpt_sectors;
- basetable->gpt_last = MIN(pp->mediasize / SECSIZE, UINT32_MAX) - 1;
-
- table = (struct g_part_pc98_table *)basetable;
- le16enc(table->boot + PC98_MAGICOFS, PC98_MAGIC);
- return (0);
-}
-
-static int
-g_part_pc98_destroy(struct g_part_table *basetable, struct g_part_parms *gpp)
-{
-
- /* Wipe the first two sectors to clear the partitioning. */
- basetable->gpt_smhead |= 3;
- return (0);
-}
-
-static void
-g_part_pc98_dumpconf(struct g_part_table *table,
- struct g_part_entry *baseentry, struct sbuf *sb, const char *indent)
-{
- struct g_part_pc98_entry *entry;
- char name[sizeof(entry->ent.dp_name) + 1];
- u_int type;
-
- entry = (struct g_part_pc98_entry *)baseentry;
- if (entry == NULL) {
- /* confxml: scheme information */
- return;
- }
-
- type = entry->ent.dp_mid + (entry->ent.dp_sid << 8);
- strncpy(name, entry->ent.dp_name, sizeof(name) - 1);
- name[sizeof(name) - 1] = '\0';
- if (indent == NULL) {
- /* conftxt: libdisk compatibility */
- sbuf_printf(sb, " xs PC98 xt %u sn %s", type, name);
- } else {
- /* confxml: partition entry information */
- sbuf_printf(sb, "%s<label>", indent);
- g_conf_printf_escaped(sb, "%s", name);
- sbuf_printf(sb, "</label>\n");
- if (entry->ent.dp_mid & PC98_MID_BOOTABLE)
- sbuf_printf(sb, "%s<attrib>bootable</attrib>\n",
- indent);
- if (entry->ent.dp_sid & PC98_SID_ACTIVE)
- sbuf_printf(sb, "%s<attrib>active</attrib>\n", indent);
- sbuf_printf(sb, "%s<rawtype>%u</rawtype>\n", indent,
- type & 0x7f7f);
- }
-}
-
-static int
-g_part_pc98_dumpto(struct g_part_table *table, struct g_part_entry *baseentry)
-{
- struct g_part_pc98_entry *entry;
-
- /* Allow dumping to a FreeBSD partition only. */
- entry = (struct g_part_pc98_entry *)baseentry;
- return (((entry->ent.dp_mid & PC98_MID_MASK) == PC98_MID_386BSD &&
- (entry->ent.dp_sid & PC98_SID_MASK) == PC98_SID_386BSD) ? 1 : 0);
-}
-
-static int
-g_part_pc98_modify(struct g_part_table *basetable,
- struct g_part_entry *baseentry, struct g_part_parms *gpp)
-{
- struct g_part_pc98_entry *entry;
- int error;
-
- entry = (struct g_part_pc98_entry *)baseentry;
-
- if (gpp->gpp_parms & G_PART_PARM_TYPE) {
- error = pc98_parse_type(gpp->gpp_type, &entry->ent.dp_mid,
- &entry->ent.dp_sid);
- if (error)
- return (error);
- }
-
- if (gpp->gpp_parms & G_PART_PARM_LABEL)
- return (pc98_set_slicename(gpp->gpp_label, entry->ent.dp_name));
-
- return (0);
-}
-
-static int
-g_part_pc98_resize(struct g_part_table *basetable,
- struct g_part_entry *baseentry, struct g_part_parms *gpp)
-{
- struct g_part_pc98_entry *entry;
- struct g_provider *pp;
- uint32_t size;
-
- if (baseentry == NULL) {
- pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider;
- basetable->gpt_last = MIN(pp->mediasize / SECSIZE,
- UINT32_MAX) - 1;
- return (0);
- }
- size = gpp->gpp_size;
- if (pc98_align(basetable, NULL, &size) != 0)
- return (EINVAL);
- /* XXX: prevent unexpected shrinking. */
- pp = baseentry->gpe_pp;
- if ((g_debugflags & 0x10) == 0 && size < gpp->gpp_size &&
- pp->mediasize / pp->sectorsize > size)
- return (EBUSY);
- entry = (struct g_part_pc98_entry *)baseentry;
- baseentry->gpe_end = baseentry->gpe_start + size - 1;
- pc98_set_chs(basetable, baseentry->gpe_end, &entry->ent.dp_ecyl,
- &entry->ent.dp_ehd, &entry->ent.dp_esect);
-
- return (0);
-}
-
-static const char *
-g_part_pc98_name(struct g_part_table *table, struct g_part_entry *baseentry,
- char *buf, size_t bufsz)
-{
-
- snprintf(buf, bufsz, "s%d", baseentry->gpe_index);
- return (buf);
-}
-
-static int
-g_part_pc98_probe(struct g_part_table *table, struct g_consumer *cp)
-{
- struct g_provider *pp;
- u_char *buf, *p;
- int error, index, res, sum;
- uint16_t magic, ecyl, scyl;
-
- pp = cp->provider;
-
- /* Sanity-check the provider. */
- if (pp->sectorsize < SECSIZE || pp->mediasize < BOOTSIZE)
- return (ENOSPC);
- if (pp->sectorsize > SECSIZE)
- return (ENXIO);
-
- /* Check that there's a PC98 partition table. */
- buf = g_read_data(cp, 0L, 2 * SECSIZE, &error);
- if (buf == NULL)
- return (error);
-
- /* We goto out on mismatch. */
- res = ENXIO;
-
- magic = le16dec(buf + PC98_MAGICOFS);
- if (magic != PC98_MAGIC)
- goto out;
-
- sum = 0;
- for (index = SECSIZE; index < 2 * SECSIZE; index++)
- sum += buf[index];
- if (sum == 0) {
- res = G_PART_PROBE_PRI_LOW;
- goto out;
- }
-
- for (index = 0; index < PC98_NPARTS; index++) {
- p = buf + SECSIZE + index * PC98_PARTSIZE;
- if (p[0] == 0 || p[1] == 0) /* !dp_mid || !dp_sid */
- continue;
- scyl = le16dec(p + 10);
- ecyl = le16dec(p + 14);
- if (scyl == 0 || ecyl == 0)
- goto out;
- if (p[8] == p[12] && /* dp_ssect == dp_esect */
- p[9] == p[13] && /* dp_shd == dp_ehd */
- scyl == ecyl)
- goto out;
- }
-
- res = G_PART_PROBE_PRI_HIGH;
-
- out:
- g_free(buf);
- return (res);
-}
-
-static int
-g_part_pc98_read(struct g_part_table *basetable, struct g_consumer *cp)
-{
- struct pc98_partition ent;
- struct g_provider *pp;
- struct g_part_pc98_table *table;
- struct g_part_pc98_entry *entry;
- u_char *buf, *p;
- off_t msize;
- off_t start, end;
- u_int cyl;
- int error, index;
-
- pp = cp->provider;
- table = (struct g_part_pc98_table *)basetable;
- msize = MIN(pp->mediasize / SECSIZE, UINT32_MAX);
-
- buf = g_read_data(cp, 0L, BOOTSIZE, &error);
- if (buf == NULL)
- return (error);
-
- cyl = basetable->gpt_heads * basetable->gpt_sectors;
-
- bcopy(buf, table->boot, sizeof(table->boot));
- bcopy(buf + SECSIZE, table->table, sizeof(table->table));
- bcopy(buf + SECSIZE*2, table->menu, sizeof(table->menu));
-
- for (index = PC98_NPARTS - 1; index >= 0; index--) {
- p = buf + SECSIZE + index * PC98_PARTSIZE;
- ent.dp_mid = p[0];
- ent.dp_sid = p[1];
- ent.dp_dum1 = p[2];
- ent.dp_dum2 = p[3];
- ent.dp_ipl_sct = p[4];
- ent.dp_ipl_head = p[5];
- ent.dp_ipl_cyl = le16dec(p + 6);
- ent.dp_ssect = p[8];
- ent.dp_shd = p[9];
- ent.dp_scyl = le16dec(p + 10);
- ent.dp_esect = p[12];
- ent.dp_ehd = p[13];
- ent.dp_ecyl = le16dec(p + 14);
- bcopy(p + 16, ent.dp_name, sizeof(ent.dp_name));
- if (ent.dp_sid == 0)
- continue;
-
- start = ent.dp_scyl * cyl;
- end = (ent.dp_ecyl + 1) * cyl - 1;
- entry = (struct g_part_pc98_entry *)g_part_new_entry(basetable,
- index + 1, start, end);
- entry->ent = ent;
- }
-
- basetable->gpt_entries = PC98_NPARTS;
- basetable->gpt_first = cyl;
- basetable->gpt_last = msize - 1;
-
- g_free(buf);
- return (0);
-}
-
-static int
-g_part_pc98_setunset(struct g_part_table *table, struct g_part_entry *baseentry,
- const char *attrib, unsigned int set)
-{
- struct g_part_entry *iter;
- struct g_part_pc98_entry *entry;
- int changed, mid, sid;
-
- if (baseentry == NULL)
- return (ENODEV);
-
- mid = sid = 0;
- if (strcasecmp(attrib, "active") == 0)
- sid = 1;
- else if (strcasecmp(attrib, "bootable") == 0)
- mid = 1;
- if (mid == 0 && sid == 0)
- return (EINVAL);
-
- LIST_FOREACH(iter, &table->gpt_entry, gpe_entry) {
- if (iter->gpe_deleted)
- continue;
- if (iter != baseentry)
- continue;
- changed = 0;
- entry = (struct g_part_pc98_entry *)iter;
- if (set) {
- if (mid && !(entry->ent.dp_mid & PC98_MID_BOOTABLE)) {
- entry->ent.dp_mid |= PC98_MID_BOOTABLE;
- changed = 1;
- }
- if (sid && !(entry->ent.dp_sid & PC98_SID_ACTIVE)) {
- entry->ent.dp_sid |= PC98_SID_ACTIVE;
- changed = 1;
- }
- } else {
- if (mid && (entry->ent.dp_mid & PC98_MID_BOOTABLE)) {
- entry->ent.dp_mid &= ~PC98_MID_BOOTABLE;
- changed = 1;
- }
- if (sid && (entry->ent.dp_sid & PC98_SID_ACTIVE)) {
- entry->ent.dp_sid &= ~PC98_SID_ACTIVE;
- changed = 1;
- }
- }
- if (changed && !iter->gpe_created)
- iter->gpe_modified = 1;
- }
- return (0);
-}
-
-static const char *
-g_part_pc98_type(struct g_part_table *basetable, struct g_part_entry *baseentry,
- char *buf, size_t bufsz)
-{
- struct g_part_pc98_entry *entry;
- u_int type;
-
- entry = (struct g_part_pc98_entry *)baseentry;
- type = (entry->ent.dp_mid & PC98_MID_MASK) |
- ((entry->ent.dp_sid & PC98_SID_MASK) << 8);
- if (type == (PC98_MID_386BSD | (PC98_SID_386BSD << 8)))
- return (g_part_alias_name(G_PART_ALIAS_FREEBSD));
- snprintf(buf, bufsz, "!%d", type);
- return (buf);
-}
-
-static int
-g_part_pc98_write(struct g_part_table *basetable, struct g_consumer *cp)
-{
- struct g_part_entry *baseentry;
- struct g_part_pc98_entry *entry;
- struct g_part_pc98_table *table;
- u_char *p;
- int error, index;
-
- table = (struct g_part_pc98_table *)basetable;
- baseentry = LIST_FIRST(&basetable->gpt_entry);
- for (index = 1; index <= basetable->gpt_entries; index++) {
- p = table->table + (index - 1) * PC98_PARTSIZE;
- entry = (baseentry != NULL && index == baseentry->gpe_index)
- ? (struct g_part_pc98_entry *)baseentry : NULL;
- if (entry != NULL && !baseentry->gpe_deleted) {
- p[0] = entry->ent.dp_mid;
- p[1] = entry->ent.dp_sid;
- p[2] = entry->ent.dp_dum1;
- p[3] = entry->ent.dp_dum2;
- p[4] = entry->ent.dp_ipl_sct;
- p[5] = entry->ent.dp_ipl_head;
- le16enc(p + 6, entry->ent.dp_ipl_cyl);
- p[8] = entry->ent.dp_ssect;
- p[9] = entry->ent.dp_shd;
- le16enc(p + 10, entry->ent.dp_scyl);
- p[12] = entry->ent.dp_esect;
- p[13] = entry->ent.dp_ehd;
- le16enc(p + 14, entry->ent.dp_ecyl);
- bcopy(entry->ent.dp_name, p + 16,
- sizeof(entry->ent.dp_name));
- } else
- bzero(p, PC98_PARTSIZE);
-
- if (entry != NULL)
- baseentry = LIST_NEXT(baseentry, gpe_entry);
- }
-
- error = g_write_data(cp, 0, table->boot, SECSIZE);
- if (!error)
- error = g_write_data(cp, SECSIZE, table->table, SECSIZE);
- if (!error)
- error = g_write_data(cp, SECSIZE*2, table->menu, MENUSIZE);
- return (error);
-}