diff options
author | Yoshihiro Takahashi <nyan@FreeBSD.org> | 2017-01-28 02:22:15 +0000 |
---|---|---|
committer | Yoshihiro Takahashi <nyan@FreeBSD.org> | 2017-01-28 02:22:15 +0000 |
commit | 2b375b4edd1b98884c3031d6ccd61acb10bd895d (patch) | |
tree | f35e4f57ad890ac86d5cb5d3ef760344a41fc0e6 /sys/geom | |
parent | 34bac11eba2841255bf6319ec78728f0f941c6ac (diff) | |
download | src-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.c | 10 | ||||
-rw-r--r-- | sys/geom/geom_pc98.c | 372 | ||||
-rw-r--r-- | sys/geom/geom_pc98_enc.c | 78 | ||||
-rw-r--r-- | sys/geom/part/g_part_pc98.c | 617 |
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); -} |