--- /dev/null
+# $NetBSD: Makefile,v 1.1.1.1 1996/01/07 21:54:16 leo Exp $
+
+PROG = aptck.ttp
+
+OBJS = aptck.o biosrw.o diskio.o disklabel.o
+HEADERS = aptck.h disklabel.h
+
+LIBS = -lxhdi
+CLEAN = aptck.c
+
+include ../Makefile.inc
+
+aptck.c: aptck.in biosrw.s diskio.c disklabel.c
+ ${AWK} -f ./setversion $^ > aptck.c
+
+${PROG}: ${OBJS} ${LDADD}
+ ${CC} ${LDFLAGS} -o $@ ${OBJS} ${LDADD} ${LIBS}
--- /dev/null
+/* $NetBSD: aptck.h,v 1.1.1.1 1996/01/07 21:54:15 leo Exp $ */
+
+/*
+ * Copyright (c) 1995 Waldi Ravens.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Waldi Ravens.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#ifndef APTCK_H
+#define APTCK_H
+
+#define MINOR(bus, target, lun) (lun)
+#define MAJOR(bus, target, lun) (((bus) << 3) + (target))
+
+#define LUN(major, minor) (minor)
+#define TARGET(major, minor) ((major) & 0x0007)
+#define BUS(major, minor) (((major) >> 3) & 0x1FFF)
+#define BIOSDEV(major, minor) (((minor) == 0) ? ((major) + 2) : 0)
+
+typedef signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef signed short int16_t;
+typedef unsigned short u_int16_t;
+typedef signed long int32_t;
+typedef unsigned long u_int32_t;
+
+typedef enum {
+ ACSI = 0,
+ SCSI = 1,
+ IDE = 2
+} bus_t;
+
+typedef struct {
+ char id[4];
+ u_int start;
+ u_int end;
+ u_int rsec;
+ u_int rent;
+} part_t;
+
+typedef struct {
+ u_int major; /* XHDI major number */
+ u_int minor; /* XHDI minor number */
+ char * sname; /* short name (s00) */
+ char * fname; /* full name (scsi target 0 lun 0)*/
+ char * product; /* product name */
+ u_long bsize; /* block size in bytes */
+ u_long msize; /* medium size in blocks */
+ u_int bblock; /* NetBSD boot block */
+ u_int lblofs; /* label offset in boot block */
+ u_int hdsize; /* medium size from root sector */
+ u_int bslst; /* start of bad sector list */
+ u_int bslend; /* end of bad sector list */
+ u_int nroots; /* # of auxilary root sectors */
+ u_int *roots; /* list of auxilary roots */
+ u_int nparts; /* number of regular partitions */
+ part_t *parts; /* list of partition descriptors */
+} disk_t;
+
+
+/*
+ * biosrw.s
+ */
+EXTERN int bios_read PROTO((void *, u_int, u_int, u_int));
+EXTERN int bios_write PROTO((void *, u_int, u_int, u_int));
+EXTERN void bios_critic PROTO((void));
+
+/*
+ * diskio.c
+ */
+EXTERN disk_t * disk_open PROTO((char *));
+EXTERN void disk_close PROTO((disk_t *));
+EXTERN void * disk_read PROTO((disk_t *, u_int, u_int));
+EXTERN int disk_write PROTO((disk_t *, u_int, u_int, void *));
+
+/*
+ * disklabel.c
+ */
+EXTERN int readdisklabel PROTO((disk_t *));
+
+#endif /* APTCK_H */
--- /dev/null
+/* $NetBSD: aptck.in,v 1.1.1.1 1996/01/07 21:54:17 leo Exp $ */
+
+/*
+ * Copyright (c) 1995 Waldi Ravens.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Waldi Ravens.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "libtos.h"
+#include "aptck.h"
+
+int main PROTO((int, char **));
+
+static void version PROTO((void)) NORETURN;
+static void usage PROTO((void)) NORETURN;
+
+static void
+version()
+{
+ eprintf("%s\n", "$Revision: 1.1 $");
+ xexit(EXIT_SUCCESS);
+}
+
+static void
+usage()
+{
+ eprintf("Usage: aptck [OPTIONS] DISK..\n"
+ "where OPTIONS are:\n"
+ "\t-V display version information and exit\n"
+ "\t-h display this help and exit\n"
+ "\t-o FILE send output to FILE instead of stdout\n"
+ "\t-w wait for key press before exiting\n\n"
+ "DISK is the concatenation of BUS, TARGET and LUN.\n"
+ "BUS is one of `i' (IDE), `a' (ACSI) or `s' (SCSI).\n"
+ "TARGET and LUN are one decimal digit each. LUN must\n"
+ "not be specified for IDE devices and is optional for\n"
+ "ACSI/SCSI devices (if omitted, LUN defaults to 0).\n\n"
+ "Examples: a0 refers to ACSI target 0 lun 0\n"
+ " s21 refers to SCSI target 2 lun 1\n"
+ );
+ xexit(EXIT_SUCCESS);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern int optind;
+ extern char *optarg;
+
+ disk_t *dd;
+ int rv, c;
+
+ init_toslib(*argv);
+
+ while ((c = getopt(argc, argv, "Vho:w")) != -1) {
+ switch (c) {
+ case 'o':
+ redirect_output(optarg);
+ break;
+ case 'w':
+ set_wait_for_key();
+ break;
+ case 'V':
+ version();
+ /* NOT REACHED */
+ case 'h':
+ default:
+ usage();
+ /* NOT REACHED */
+ }
+ }
+ argv += optind;
+
+ if (!*argv) {
+ error(-1, "missing DISK argument");
+ usage();
+ /* NOT REACHED */
+ }
+
+ c = isatty(STDOUT_FILENO);
+ rv = EXIT_SUCCESS;
+ while (*argv) {
+ dd = disk_open(*argv++);
+ if (dd) {
+ if (readdisklabel(dd))
+ rv = EXIT_FAILURE;
+ disk_close(dd);
+ if (c)
+ press_any_key();
+ }
+ else rv = EXIT_FAILURE;
+ }
+ return(rv);
+}
--- /dev/null
+/* $NetBSD: biosrw.s,v 1.1.1.1 1996/01/07 21:54:15 leo Exp $ */
+
+/*
+ * Copyright (c) 1995 Waldi Ravens.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Waldi Ravens.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+/* int bios_read(buffer, offset, count, dev) */
+
+ .globl _bios_read
+ .text
+ .even
+
+_bios_read:
+ movml d1-d2/a1-a2,sp@-
+ movl sp@(24),sp@- | offset
+ movw sp@(38),sp@- | device
+ movw #-1,sp@-
+ movw sp@(38),sp@- | count
+ movl sp@(30),sp@- | buffer
+ movw #8,sp@- | read, physical mode
+ movw #4,sp@-
+ trap #13 | Rwabs()
+ lea sp@(18),sp
+ movml sp@+,d1-d2/a1-a2
+ rts
+
+/* int bios_write(buffer, offset, count, dev) */
+
+ .globl _bios_write
+ .text
+ .even
+
+_bios_write:
+ movml d1-d2/a1-a2,sp@-
+ movl sp@(20),sp@- | offset
+ movw sp@(34),sp@- | device
+ movw #-1,sp@-
+ movw sp@(34),sp@- | count
+ movl sp@(26),sp@- | buffer
+ movw #9,sp@- | write, physical mode
+ movw #4,sp@-
+ trap #13 | Rwabs()
+ lea sp@(18),sp
+ movml sp@+,d1-d2/a1-a2
+ rts
+
+/* int bios_critic(error) */
+
+ .globl _bios_critic
+ .text
+ .even
+
+_bios_critic:
+ movw sp@(4),d0
+ extl d0
+ rts
--- /dev/null
+/* $NetBSD: diskio.c,v 1.1.1.1 1996/01/07 21:54:16 leo Exp $ */
+
+/*
+ * Copyright (c) 1995 Waldi Ravens.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Waldi Ravens.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <xhdi.h>
+#include "libtos.h"
+#include "aptck.h"
+#include "disklabel.h"
+#include <osbind.h>
+
+struct pun_info {
+ u_int16_t puns;
+ u_int8_t pun[16];
+ u_int32_t part_start[16];
+ u_int32_t P_cookie;
+ u_int32_t *P_cookptr;
+ u_int16_t P_version;
+ u_int16_t P_max_sector;
+ u_int32_t reserved[16];
+};
+
+static char * strbd PROTO((char *, ...));
+static int setmami PROTO((disk_t *, char *));
+static int setnames PROTO((disk_t *));
+static int setsizes PROTO((disk_t *));
+static int ahdi_compatible PROTO((void));
+
+disk_t *
+disk_open(name)
+ char *name;
+{
+ disk_t *dd;
+
+ dd = xmalloc(sizeof *dd);
+ memset(dd, 0, sizeof *dd);
+
+ if (setmami(dd, name) || setnames(dd) || setsizes(dd)) {
+ disk_close(dd);
+ return(NULL);
+ }
+ return(dd);
+}
+
+void
+disk_close(dd)
+ disk_t *dd;
+{
+ if (dd) {
+ free(dd->product);
+ free(dd->sname);
+ free(dd->fname);
+ free(dd->roots);
+ free(dd->parts);
+ free(dd);
+ }
+}
+
+void *
+disk_read(dd, start, count)
+ disk_t *dd;
+ u_int start,
+ count;
+{
+ char *buffer;
+ int bdev;
+ long e;
+
+ buffer = xmalloc(count * dd->bsize);
+
+ e = XHReadWrite(dd->major, dd->minor, 0, start, count, buffer);
+ if (!e)
+ return(buffer);
+ if (e == -32 || (e == -1 && XHGetVersion() == -1)) {
+ if (!ahdi_compatible())
+ fatal(-1, "AHDI 3.0 compatible harddisk driver required");
+ bdev = BIOSDEV(dd->major, dd->minor);
+ if (bdev && !bios_read(buffer, start, count, bdev))
+ return(buffer);
+ }
+
+ free(buffer);
+ return(NULL);
+}
+
+int
+disk_write(dd, start, count, buffer)
+ disk_t *dd;
+ u_int start,
+ count;
+ void *buffer;
+{
+ int bdev;
+ long e;
+
+ e = XHReadWrite(dd->major, dd->minor, 1, start, count, buffer);
+ if (e == -32 || (e == -1 && XHGetVersion() == -1)) {
+ if (!ahdi_compatible())
+ fatal(-1, "AHDI 3.0 compatible harddisk driver required");
+ bdev = BIOSDEV(dd->major, dd->minor);
+ if (bdev)
+ e = bios_write(buffer, start, count, bdev);
+ }
+
+ return((int)e);
+}
+
+static int
+ahdi_compatible()
+{
+ static int ahdi_compat;
+
+ if (!ahdi_compat) {
+ long oldsp = Super(0L);
+ struct pun_info *punp = *((struct pun_info **)0x0516);
+ Super(oldsp);
+ if (punp && punp->P_cookie == 0x41484449
+ && punp->P_cookptr == &punp->P_cookie
+ && punp->P_version >= 0x0300)
+ ahdi_compat = 1;
+ }
+ return(ahdi_compat);
+}
+
+static int
+setmami(dd, name)
+ disk_t *dd;
+ char *name;
+{
+ char *p = name;
+ u_int target, lun;
+ bus_t bus;
+
+ if (*p == 'i') {
+ bus = IDE;
+ if (*++p < '0' || *p > '1') {
+ if (*p)
+ error(-1, "%s: invalid IDE target `%c'", name, *p);
+ else
+ error(-1, "%s: missing IDE target", name);
+ return(-1);
+ }
+ target = *p++ - '0';
+ lun = 0;
+ } else {
+ char *b;
+
+ if (*p == 'a') {
+ bus = ACSI;
+ b = "ACSI";
+ } else if (*p == 's') {
+ bus = SCSI;
+ b = "SCSI";
+ } else {
+ error(-1, "%s: invalid DISK argument", name);
+ return(-1);
+ }
+ if (*++p < '0' || *p > '7') {
+ if (*p)
+ error(-1, "%s: invalid %s target `%c'", name, b, *p);
+ else
+ error(-1, "%s: missing %s target", name, b);
+ return(-1);
+ }
+ target = *p++ - '0';
+
+ if (*p < '0' || *p > '7') {
+ if (*p) {
+ error(-1, "%s: invalid %s lun `%c'", name, b, *p);
+ return(-1);
+ }
+ lun = 0;
+ } else
+ lun = *p++ - '0';
+ }
+ if (*p) {
+ error(-1, "%s: invalid DISK argument", name);
+ return(-1);
+ }
+ dd->major = MAJOR(bus, target, lun);
+ dd->minor = MINOR(bus, target, lun);
+ return(0);
+}
+
+static int
+setnames(dd)
+ disk_t *dd;
+{
+ char sn[16], us[16], ls[16], *bs;
+ int b, u, l;
+
+ b = BUS(dd->major, dd->minor);
+ u = TARGET(dd->major, dd->minor);
+ l = LUN(dd->major, dd->minor);
+
+ switch (b) {
+ case IDE: bs = "IDE";
+ break;
+ case ACSI: bs = "ACSI";
+ break;
+ case SCSI: bs = "SCSI";
+ break;
+ default: error(-1, "invalid bus no. %d", b);
+ return(-1);
+ }
+
+ if (u < 0 || u > 7 || (b == IDE && u > 1)) {
+ error(-1, "invalid %s target `%d'", bs, u);
+ return(-1);
+ }
+ sprintf(us, " target %d", u);
+
+ if (l < 0 || l > 7 || (b == IDE && l > 0)) {
+ error(-1, "invalid %s lun `%d'", bs, l);
+ return(-1);
+ }
+ if (b == IDE) {
+ sprintf(sn, "i%d", u);
+ ls[0] = '\0';
+ } else {
+ sprintf(sn, "%c%d%d", tolower(*bs), u, l);
+ sprintf(ls, " lun %d", l);
+ }
+
+ dd->fname = strbd(bs, us, ls, NULL);
+ dd->sname = strbd(sn, NULL);
+ return(0);
+}
+
+static int
+setsizes(dd)
+ disk_t *dd;
+{
+ if (XHGetVersion() != -1) {
+ char *p, prod[1024];
+
+ if (XHInqTarget2(dd->major, dd->minor, &dd->bsize, NULL, prod, sizeof(prod))) {
+ if (XHInqTarget(dd->major, dd->minor, &dd->bsize, NULL, prod)) {
+ error(-1, "%s: device not configured", dd->sname);
+ return(-1);
+ }
+ }
+ p = strrchr(prod, '\0');
+ while (isspace(*--p))
+ *p = '\0';
+ dd->product = strbd(prod, NULL);
+ if (!XHGetCapacity(dd->major, dd->minor, &dd->msize, &dd->bsize))
+ return(0);
+ } else {
+ dd->product = strbd("unknown", NULL);
+ dd->bsize = AHDI_BSIZE; /* XXX */
+ }
+
+ /* Trial&error search for last sector on medium */
+ {
+ u_int u, l, m;
+ void *p, (*oldvec)();
+
+ /* turn off etv_critic handler */
+ oldvec = Setexc(257, bios_critic);
+
+ u = (u_int)-2; l = 0;
+ while (u != l) {
+ m = l + ((u - l + 1) / 2);
+ p = disk_read(dd, m, 1);
+ free(p);
+ if (p == NULL)
+ u = m - 1;
+ else
+ l = m;
+ }
+
+ /* turn on etv_critic handler */
+ (void)Setexc(257, oldvec);
+
+ if (l) {
+ dd->msize = l + 1;
+ return(0);
+ }
+ error(-1, "%s: device not configured", dd->sname);
+ return(-1);
+ }
+}
+
+char *
+strbd(string1)
+ char *string1;
+{
+ char *p, *result;
+ size_t length = 1;
+ va_list ap;
+
+ va_start(ap, string1);
+ for (p = string1; p; p = va_arg(ap, char *))
+ length += strlen(p);
+ va_end(ap);
+
+ *(result = xmalloc(length)) = '\0';
+
+ va_start(ap, string1);
+ for (p = string1; p; p = va_arg(ap, char *))
+ strcat(result, p);
+ va_end(ap);
+
+ return(result);
+}
--- /dev/null
+/* $NetBSD: disklabel.c,v 1.1.1.1 1996/01/07 21:54:16 leo Exp $ */
+
+/*
+ * Copyright (c) 1995 Waldi Ravens.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Waldi Ravens.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "libtos.h"
+#include "aptck.h"
+#include "disklabel.h"
+
+static int dkcksum PROTO((struct disklabel *));
+static int bsd_label PROTO((disk_t *, u_int));
+static int ahdi_label PROTO((disk_t *));
+static int ahdi_display PROTO((disk_t *));
+static u_int ahdi_getparts PROTO((disk_t *, u_int, u_int));
+
+int
+readdisklabel(dd)
+ disk_t *dd;
+{
+ int e;
+
+ printf("Device : %s (%s) [%s]\n", dd->sname, dd->fname, dd->product);
+ printf("Medium size: %lu sectors\n", (u_long)dd->msize);
+ printf("Sector size: %lu bytes\n\n", (u_long)dd->bsize);
+
+ e = bsd_label(dd, LABELSECTOR);
+ if (e < 0) {
+ printf("Device I/O error (hardware problem?)\n\n");
+ return(-1);
+ }
+ if (!e) {
+ printf("NetBSD/Atari format, boot block: "
+ "sector %u labeloffset %u\n\n",
+ dd->bblock, dd->lblofs);
+ return(0);
+ }
+
+ e = ahdi_label(dd);
+ if (e < 0) {
+ printf("Device I/O error (hardware problem?)\n\n");
+ return(-1);
+ }
+ if (!e) {
+ printf("AHDI format, NetBSD boot block: ");
+ if (dd->bblock != NO_BOOT_BLOCK)
+ printf("sector %u labeloffset %u\n\n",
+ dd->bblock, dd->lblofs);
+ else printf("none\n\n");
+ return(0);
+ }
+
+ printf("Unknown label format.\n\n");
+ return(-1);
+}
+
+static int
+bsd_label(dd, offset)
+ disk_t *dd;
+ u_int offset;
+{
+ u_char *bblk;
+ u_int nsec;
+ int rv;
+
+ nsec = (BBSIZE + (dd->bsize - 1)) / dd->bsize;
+ bblk = disk_read(dd, offset, nsec);
+ if (bblk) {
+ u_short *end, *p;
+
+ end = (u_short *)&bblk[BBSIZE - sizeof(struct disklabel)];
+ rv = 1;
+ for (p = (u_short *)bblk; p < end; ++p) {
+ struct disklabel *dl = (struct disklabel *)p;
+ if (dl->d_magic == DISKMAGIC && dl->d_magic2 == DISKMAGIC
+ && dl->d_npartitions <= MAXPARTITIONS && !dkcksum(dl)) {
+ dd->lblofs = (u_char *)p - bblk;
+ dd->bblock = offset;
+ rv = 0;
+ break;
+ }
+ }
+ free(bblk);
+ }
+ else rv = -1;
+
+ return(rv);
+}
+
+static int
+dkcksum(dl)
+ struct disklabel *dl;
+{
+ u_short *start, *end, sum = 0;
+
+ start = (u_short *)dl;
+ end = (u_short *)&dl->d_partitions[dl->d_npartitions];
+ while (start < end)
+ sum ^= *start++;
+ return(sum);
+}
+
+int
+ahdi_label(dd)
+ disk_t *dd;
+{
+ u_int i;
+ int e;
+
+ /*
+ * The AHDI format requires a specific block size.
+ */
+ if (dd->bsize != AHDI_BSIZE)
+ return(1);
+
+ /*
+ * Fetch the AHDI partition descriptors.
+ */
+ i = ahdi_getparts(dd, AHDI_BBLOCK, AHDI_BBLOCK);
+ if (i) {
+ if (i < dd->msize)
+ return(-1); /* disk read error */
+ else return(1); /* reading past end of medium */
+ }
+
+ /*
+ * Display and perform sanity checks.
+ */
+ i = ahdi_display(dd);
+ if (i)
+ return(i);
+
+ /*
+ * Search for a NetBSD disk label
+ */
+ dd->bblock = NO_BOOT_BLOCK;
+ for (i = 0; i < dd->nparts; ++i) {
+ part_t *pd = &dd->parts[i];
+ u_int id = *((u_int32_t *)&pd->id) >> 8;
+ if (id == AHDI_PID_NBD || id == AHDI_PID_RAW) {
+ u_int offs = pd->start;
+ if ((e = bsd_label(dd, offs)) < 0) {
+ return(e); /* I/O error */
+ }
+ if (!e) {
+ dd->bblock = offs; /* got it */
+ return(0);
+ }
+ if (id == AHDI_PID_NBD && dd->bblock == NO_BOOT_BLOCK)
+ dd->bblock = offs;
+ }
+ }
+ return(0);
+}
+
+static int
+root_cmp(x1, x2)
+ const void *x1, *x2;
+{
+ const u_int *r1 = x1,
+ *r2 = x2;
+
+ if (*r1 < *r2)
+ return(-1);
+ if (*r1 > *r2)
+ return(1);
+ return(0);
+}
+
+static int
+part_cmp(x1, x2)
+ const void *x1, *x2;
+{
+ const part_t *p1 = x1,
+ *p2 = x2;
+
+ if (p1->start < p2->start)
+ return(-1);
+ if (p1->start > p2->start)
+ return(1);
+ if (p1->end < p2->end)
+ return(-1);
+ if (p1->end > p2->end)
+ return(1);
+ if (p1->rsec < p2->rsec)
+ return(-1);
+ if (p1->rsec > p2->rsec)
+ return(1);
+ if (p1->rent < p2->rent)
+ return(-1);
+ if (p1->rent > p2->rent)
+ return(1);
+ return(0);
+}
+
+static int
+ahdi_display(dd)
+ disk_t *dd;
+{
+ int i, j, rv = 0;
+
+ printf("Start of bad sector list : %u\n", dd->bslst);
+ if (dd->bslst == 0) {
+ printf("* Illegal value (zero) *\n"); rv = 1;
+ }
+ printf("End of bad sector list : %u\n", dd->bslend);
+ if (dd->bslend == 0) {
+ printf("* Illegal value (zero) *\n"); rv = 1;
+ }
+ printf("Medium size (in root sec): %u\n", dd->hdsize);
+ if (dd->hdsize == 0) {
+ printf("* Illegal value (zero) *\n"); rv = 1;
+ }
+
+ qsort(dd->roots, dd->nroots, sizeof *dd->roots, root_cmp);
+ qsort(dd->parts, dd->nparts, sizeof *dd->parts, part_cmp);
+ printf("\n root desc id start end MBs\n");
+
+ for (i = 0; i < dd->nparts; ++i) {
+ part_t *p1 = &dd->parts[i];
+ u_int megs = p1->end - p1->start + 1,
+ blpm = (1024 * 1024) / dd->bsize;
+ megs = (megs + (blpm >> 1)) / blpm;
+ printf("%8u %4u %s %8u %8u (%3u)\n",
+ p1->rsec, p1->rent, p1->id,
+ p1->start, p1->end, megs);
+ for (j = 0; j < dd->nroots; ++j) {
+ u_int aux = dd->roots[j];
+ if (aux >= p1->start && aux <= p1->end) {
+ printf("FATAL: auxilary root at %u\n", aux); rv = 1;
+ }
+ }
+ for (j = i; j--;) {
+ part_t *p2 = &dd->parts[j];
+ if (p1->start >= p2->start && p1->start <= p2->end) {
+ printf("FATAL: clash with %u/%u\n", p2->rsec, p2->rent); rv = 1;
+ }
+ if (p2->start >= p1->start && p2->start <= p1->end) {
+ printf("FATAL: clash with %u/%u\n", p2->rsec, p2->rent); rv = 1;
+ }
+ }
+ if (p1->start >= dd->bslst && p1->start <= dd->bslend) {
+ printf("FATAL: partition overlaps with bad sector list\n"); rv = 1;
+ }
+ if (dd->bslst >= p1->start && dd->bslst <= p1->end) {
+ printf("FATAL: partition overlaps with bad sector list\n"); rv = 1;
+ }
+ }
+
+ printf("\nTotal number of auxilary roots: %u\n", dd->nroots);
+ printf("Total number of partitions : %u\n", dd->nparts);
+ if (dd->nparts == 0) {
+ printf("* Weird # of partitions (zero) *\n"); rv = 1;
+ }
+ if (dd->nparts > AHDI_MAXPARTS) {
+ printf("* Too many AHDI partitions for NetBSD *\n");
+ printf(" Increase MAXAUXROOTS in machine/disklabel.h,\n");
+ printf(" then recompile the NetBSD kernel.\n");
+ rv = -1;
+ }
+ return(rv);
+}
+
+static u_int
+ahdi_getparts(dd, rsec, esec)
+ disk_t *dd;
+ u_int rsec,
+ esec;
+{
+ struct ahdi_part *part, *end;
+ struct ahdi_root *root;
+ u_int rv;
+
+ root = disk_read(dd, rsec, 1);
+ if (!root) {
+ rv = rsec + (rsec == 0);
+ goto done;
+ }
+
+ if (rsec == AHDI_BBLOCK)
+ end = &root->ar_parts[AHDI_MAXRPD];
+ else end = &root->ar_parts[AHDI_MAXARPD];
+ for (part = root->ar_parts; part < end; ++part) {
+ u_int id = *((u_int32_t *)&part->ap_flg);
+ if (!(id & 0x01000000))
+ continue;
+ if ((id &= 0x00ffffff) == AHDI_PID_XGM) {
+ u_int offs = part->ap_offs + esec;
+ u_int i = ++dd->nroots;
+ dd->roots = xrealloc(dd->roots, i * sizeof *dd->roots);
+ dd->roots[--i] = offs;
+ rv = ahdi_getparts(dd, offs, esec == AHDI_BBLOCK ? offs : esec);
+ if (rv)
+ goto done;
+ } else {
+ part_t *p;
+ u_int i = ++dd->nparts;
+ dd->parts = xrealloc(dd->parts, i * sizeof *dd->parts);
+ p = &dd->parts[--i];
+ *((u_int32_t *)&p->id) = id << 8;
+ p->start = part->ap_offs + rsec;
+ p->end = p->start + part->ap_size - 1;
+ p->rsec = rsec;
+ p->rent = part - root->ar_parts;
+ }
+ }
+ dd->hdsize = root->ar_hdsize;
+ dd->bslst = root->ar_bslst;
+ dd->bslend = root->ar_bslst + root->ar_bslsize - 1;
+ rv = 0;
+done:
+ free(root);
+ return(rv);
+}
--- /dev/null
+/* $NetBSD: disklabel.h,v 1.1.1.1 1996/01/07 21:54:16 leo Exp $ */
+
+/*
+ * Copyright (c) 1995 Leo Weppelman.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Leo Weppelman.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * 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.
+ */
+
+#ifndef DISKLABEL_H
+#define DISKLABEL_H
+
+/*
+ * On a volume, exclusively used by NetBSD, the boot block starts at
+ * sector 0. To allow shared use of a volume between two or more OS's
+ * the vendor specific AHDI format is supported. In this case the boot
+ * block is located at the start of an AHDI partition. In any case the
+ * size of the boot block is 8KB, the disk label is at offset 7KB.
+ */
+#define LABELSECTOR 0 /* `natural' start of boot block */
+#define LABELOFFSET (7 * 1024) /* offset of disk label in bytes,
+ relative to start of boot block */
+#define BBSIZE (8 * 1024) /* size of boot block in bytes */
+#define MAXPARTITIONS 16 /* max. # of NetBSD partitions */
+#define RAW_PART 2 /* xx?c is raw partition */
+
+#define NO_BOOT_BLOCK ((u_int) -1)
+#define MAXAUXROOTS 60 /* max. # of auxilary root sectors */
+
+/***************************************************************************/
+
+#define AHDI_BSIZE 512 /* AHDI blocksize */
+#define AHDI_BBLOCK 0 /* AHDI bootblock (root sector) */
+#define AHDI_MAXROOTS (MAXAUXROOTS) /* max. # of AHDI rootsectors */
+#define AHDI_MAXPARTS (AHDI_MAXROOTS+3) /* max. # of AHDI partitions */
+
+/*
+ * Various `well known' AHDI partition identifiers.
+ */
+#define AHDI_MKPID(x,y,z) ( ((u_int32_t)(x) << 16) \
+ | ((u_int32_t)(y) << 8) \
+ | ((u_int32_t)(z)) \
+ )
+#define AHDI_PID_XGM AHDI_MKPID('X','G','M')
+#define AHDI_PID_GEM AHDI_MKPID('G','E','M')
+#define AHDI_PID_BGM AHDI_MKPID('B','G','M')
+#define AHDI_PID_RAW AHDI_MKPID('R','A','W')
+#define AHDI_PID_SWP AHDI_MKPID('S','W','P')
+#define AHDI_PID_NBD AHDI_MKPID('N','B','D')
+#define AHDI_PID_NBR AHDI_MKPID('N','B','R')
+#define AHDI_PID_NBS AHDI_MKPID('N','B','S')
+#define AHDI_PID_NBU AHDI_MKPID('N','B','U')
+
+/*
+ * Format of AHDI boot block.
+ */
+#define AHDI_MAXRPD 4 /* max. # of partition descriptors */
+ /* in the AHDI bootblock (aka root)*/
+#define AHDI_MAXARPD 2 /* max. # of partition descriptors */
+ /* in an AHDI auxilary root sector */
+
+struct ahdi_part {
+ u_int8_t ap_flg; /* bit 0 is in-use flag */
+ u_int8_t ap_id[3]; /* id: GEM, BGM, XGM, UNX, MIX */
+ u_int32_t ap_offs; /* block where partition starts */
+ u_int32_t ap_size; /* partition size in blocks */
+#define ap_end ap_size /* in the in-core copy, store end instead of size */
+};
+
+struct ahdi_root {
+ u_int8_t ar_fill[0x1c2];/* filler, can be boot code */
+ u_int32_t ar_hdsize; /* size of entire volume in blocks */
+ struct ahdi_part ar_parts[AHDI_MAXRPD]; /* root partition table */
+ u_int32_t ar_bslst; /* start of bad-sector list */
+ u_int32_t ar_bslsize; /* # of blocks in bad-sector list */
+ u_int16_t ar_cksum;
+};
+
+/***************************************************************************/
+
+#define DISKMAGIC ((u_int32_t)0x82564557) /* The disk magic number */
+
+struct disklabel {
+ u_int32_t d_magic; /* the magic number */
+ u_int16_t d_type; /* drive type */
+ u_int16_t d_subtype; /* controller/d_type specific */
+ char d_typename[16]; /* type name, e.g. "eagle" */
+
+ /*
+ * d_packname contains the pack identifier and is returned when
+ * the disklabel is read off the disk or in-core copy.
+ * d_boot0 and d_boot1 are the (optional) names of the
+ * primary (block 0) and secondary (block 1-15) bootstraps
+ * as found in /usr/mdec. These are returned when using
+ * getdiskbyname(3) to retrieve the values from /etc/disktab.
+ */
+ union {
+ char un_d_packname[16]; /* pack identifier */
+ struct {
+ char *un_d_boot0; /* primary bootstrap name */
+ char *un_d_boot1; /* secondary bootstrap name */
+ } un_b;
+ } d_un;
+#define d_packname d_un.un_d_packname
+#define d_boot0 d_un.un_b.un_d_boot0
+#define d_boot1 d_un.un_b.un_d_boot1
+
+ /* disk geometry: */
+ u_int32_t d_secsize; /* # of bytes per sector */
+ u_int32_t d_nsectors; /* # of data sectors per track */
+ u_int32_t d_ntracks; /* # of tracks per cylinder */
+ u_int32_t d_ncylinders; /* # of data cylinders per unit */
+ u_int32_t d_secpercyl; /* # of data sectors per cylinder */
+ u_int32_t d_secperunit; /* # of data sectors per unit */
+
+ /*
+ * Spares (bad sector replacements) below are not counted in
+ * d_nsectors or d_secpercyl. Spare sectors are assumed to
+ * be physical sectors which occupy space at the end of each
+ * track and/or cylinder.
+ */
+ u_int16_t d_sparespertrack; /* # of spare sectors per track */
+ u_int16_t d_sparespercyl; /* # of spare sectors per cylinder */
+ /*
+ * Alternate cylinders include maintenance, replacement, configuration
+ * description areas, etc.
+ */
+ u_int32_t d_acylinders; /* # of alt. cylinders per unit */
+
+ /* hardware characteristics: */
+ /*
+ * d_interleave, d_trackskew and d_cylskew describe perturbations
+ * in the media format used to compensate for a slow controller.
+ * Interleave is physical sector interleave, set up by the
+ * formatter or controller when formatting. When interleaving is
+ * in use, logically adjacent sectors are not physically
+ * contiguous, but instead are separated by some number of
+ * sectors. It is specified as the ratio of physical sectors
+ * traversed per logical sector. Thus an interleave of 1:1
+ * implies contiguous layout, while 2:1 implies that logical
+ * sector 0 is separated by one sector from logical sector 1.
+ * d_trackskew is the offset of sector 0 on track N relative to
+ * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew
+ * is the offset of sector 0 on cylinder N relative to sector 0
+ * on cylinder N-1.
+ */
+ u_int16_t d_rpm; /* rotational speed */
+ u_int16_t d_interleave; /* hardware sector interleave */
+ u_int16_t d_trackskew; /* sector 0 skew, per track */
+ u_int16_t d_cylskew; /* sector 0 skew, per cylinder */
+ u_int32_t d_headswitch; /* head switch time, usec */
+ u_int32_t d_trkseek; /* track-to-track seek, usec */
+ u_int32_t d_flags; /* generic flags */
+#define NDDATA 5
+ u_int32_t d_drivedata[NDDATA]; /* drive-type specific information */
+#define NSPARE 5
+ u_int32_t d_spare[NSPARE]; /* reserved for future use */
+ u_int32_t d_magic2; /* the magic number (again) */
+ u_int16_t d_checksum; /* xor of data incl. partitions */
+
+ /* filesystem and partition information: */
+ u_int16_t d_npartitions; /* number of partitions in following */
+ u_int32_t d_bbsize; /* size of boot area at sn0, bytes */
+ u_int32_t d_sbsize; /* max size of fs superblock, bytes */
+ struct partition { /* the partition table */
+ u_int32_t p_size; /* number of sectors in partition */
+ u_int32_t p_offset; /* starting sector */
+ u_int32_t p_fsize; /* filesystem basic fragment size */
+ u_int8_t p_fstype; /* filesystem type, see below */
+ u_int8_t p_frag; /* filesystem fragments per block */
+ union {
+ u_int16_t cpg; /* UFS: FS cylinders per group */
+ u_int16_t sgs; /* LFS: FS segment shift */
+ } __partition_u1;
+#define p_cpg __partition_u1.cpg
+#define p_sgs __partition_u1.sgs
+ } d_partitions[MAXPARTITIONS]; /* actually may be more */
+};
+
+#endif /* DISKLABEL_H */
--- /dev/null
+#!/usr/bin/awk -f
+#
+# $NetBSD: setversion,v 1.1.1.1 1996/01/07 21:54:17 leo Exp $
+#
+function revcmp(r1, r2, n1, n2, a1, a2, n, i) {
+ n1 = split(r1, a1, "\.")
+ n2 = split(r2, a2, "\.")
+ n = (n1 < n2) ? n1 : n2
+
+ for (i = 1; i <= n; ++i) {
+ if (a1[i] != a2[i])
+ return(a1[i] - a2[i])
+ }
+ if (n1 != n2)
+ return(n1 - n2)
+ return(0)
+}
+
+BEGIN {
+ destfile = ARGV[1]
+ rev = "0.0"
+}
+
+{
+ if (revcmp($4, rev) > 0)
+ rev = $4
+ next file
+}
+
+END {
+ while ((e = getline <destfile) > 0) {
+ if (/"\$Revision.*\$"/)
+ sub("\\\$Revision.*\\\$", "Revision " rev)
+ print
+ }
+ if (e)
+ exit(1)
+ exit(0)
+}