Return to BSD News archive
Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!simtel!news.sprintlink.net!in1.uu.net!spcuna!wlbr!sms
From: sms@wlv.iipo.gtegsc.com (Steven M. Schultz)
Subject: SMD (xp driver) disklabel capability added (#271)
Sender: news@wlbr.iipo.gtegsc.com (System Administrator)
Organization: GTE Government Systems, Westlake Village
Message-ID: <DDr51K.Ipn@wlbr.iipo.gtegsc.com>
X-Nntp-Posting-Host: wlv.iipo.gtegsc.com
Date: Wed, 23 Aug 1995 07:05:43 GMT
Lines: 2769
Subject: SMD (xp driver) disklabel capability added (#271)
Index: sys/{pdpuba,pdpstand,conf}/xp.c,conf.c,... 2.11BSD
Description:
The SMD (xp) driver which handles RM04,5,6, RM02,3,5, Fuji-160
and many other SMD drives has been updated to be disklabel
capable.
Repeat-By:
N/A
Fix:
All previous updates (*especially* 250 - 267) thru 270 must
have been applied to the system.
Cut where indicated and save to a file (/tmp/271). Then:
patch -p0 < /tmp/271
and follow the directions in #250. The instructions in update #250
are not repeated here but are available (as are all 2.11BSD updates)
via anonymous ftp to the host FTP.IIPO.GTEGSC.COM in the directory
/pub/2.11BSD.
NOTE: If you do not have any SMD drives present in the system then
all you need to do is recompile and install the 'boot' program.
=====================cut here=================
*** /usr/src/sys/pdpuba/hpreg.h.old Thu Jul 1 19:52:33 1993
--- /usr/src/sys/pdpuba/hpreg.h Thu Jul 20 19:48:12 1995
***************
*** 3,82 ****
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)hpreg.h 1.1 (2.10BSD Berkeley) 12/1/86
*/
/*
! * Definitions for SMD-type disk drives and drivers. That includes
! * RM02/03/05's, RP04/05/06's, and everything using the XP driver.
! * Also added RP07. /BQT 930612
*/
! /*
! * Defines for disk drive type registers
! */
! #define RP04 020 /* RP04 */
! #define RP05 021 /* RP05 */
! #define RP06 022 /* RP06 */
! #define RP07 042 /* RP07 */
! #define RM03 024 /* RM03 */
! #define RM02 025 /* RM02 */
! #define RM05 027 /* RM05 or SI 9500, CDC 9766 */
! /*
! * These drive types are dummies because the actual numbers conflict
! * with DEC controllers. The RM5X and the RM2X actually read as 25; the
! * Diva Comp VI reads as 22. Xp_drive must be patched at boot time or
! * initialized.
! */
! #define CAP 072 /* Ampex Capricorn */
! #define SI5 073 /* SI, CDC 9775 Direct */
! #define SI 074 /* SI 6100, Fuji Eagle 2351A */
! #define RM2X 075 /* Emulex SC01B or SI 9400, Fuji 160 */
! #define RM5X 076 /* Emulex SC-21, Ampex 815 cylider RM05 */
! #define DV 077 /* Diva Comp V, Ampex 9300 */
- #define HP_SECT 22 /* RP04/05/06 */
- #define HP_TRAC 19
- #define RP04_CYL 411 /* RP04/05 */
- #define RP06_CYL 815 /* RP06 */
-
- #define RP7_SECT 50 /* DEC RP07 */
- #define RP7_TRAC 32
- #define RP7_CYL 630
-
- #define RM_SECT 32 /* RM02/03 */
- #define RM_TRAC 5
- #define RM_CYL 823
-
- #define RM5_SECT 32 /* RM05, CDC 9766 */
- #define RM5_TRAC 19
- #define RM5_CYL 823
-
- #define CAP_SECT 32 /* Ampex Capricorn */
- #define CAP_TRAC 16
- #define CAP_CYL 1024
-
- #define SI5_SECT 32 /* SI, CDC 9775 direct */
- #define SI5_TRAC 40
- #define SI5_CYL 843
-
- #define SI_SECT 48 /* SI 6100, Fuji Eagle 2351A */
- #define SI_TRAC 20
- #define SI_CYL 842
-
- #define RM2X_SECT 32 /* Emulex SC01B or SI 9400, Fuji 160 */
- #define RM2X_TRAC 10
- #define RM2X_CYL 823
-
- #define RM5X_SECT 32 /* Emulex, Ampex 815 cylider RM05 */
- #define RM5X_TRAC 19
- #define RM5X_CYL 815
-
- #define DV_SECT 33 /* Diva Comp V, Ampex 9300 */
- #define DV_TRAC 19
- #define DV_CYL 815
-
-
/*
* Controller registers and bits
*/
--- 3,20 ----
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)hpreg.h 2.0 (2.11BSD) 1995/07/20
*/
/*
! * Definitions for SMD-type disk drives and drivers.
*/
! #define XP_CC 0x1 /* drivedata[0] bit indicating presence of current
! * cylinder 'hpcc' register. Only set for RP04,5,6,7.
! */
! #define XP_NOSEARCH 0x2 /* drivedata[0] bit indicating lack of search cmd */
/*
* Controller registers and bits
*/
***************
*** 104,110 ****
short hpof; /* offset register */
short hpdc; /* desired cylinder address register */
short hpcc; /* HP: current cylinder register */
! #define rmhr hpcc; /* RM: holding register */
short hper2; /* HP: error register 2 */
#define rmmr2 hper2 /* RM: maintenance register 2 */
short hper3; /* HP: error register 3 */
--- 42,48 ----
short hpof; /* offset register */
short hpdc; /* desired cylinder address register */
short hpcc; /* HP: current cylinder register */
! #define rmhr hpcc /* RM: holding register */
short hper2; /* HP: error register 2 */
#define rmmr2 hper2 /* RM: maintenance register 2 */
short hper3; /* HP: error register 3 */
***************
*** 131,136 ****
--- 69,75 ----
/* commands */
#define HP_NOP 000
+ #define HP_UNLOAD 002 /* offline drive */
#define HP_SEEK 004 /* seek */
#define HP_RECAL 006 /* recalibrate */
#define HP_DCLR 010 /* drive clear */
***************
*** 220,229 ****
#define HPDT_DRR 0004000 /* drive request required */
/* bits 10-9 are unused */
/* bits 8-0 are drive type; the correct values are hard to determine */
- #define HPDT_RM05SP 0000047 /* single ported rm05 */
- #define HPDT_RM05DP 0000027 /* dual ported rm05 */
#define HPDT_RM02 0000025 /* rm02, possibly rm03? */
#define HPDT_RM03 0000024 /* rm03 */
#define HPDT_RP06 0000022 /* rp06 */
#define HPDT_RP07 0000042 /* rp07 */
--- 159,170 ----
#define HPDT_DRR 0004000 /* drive request required */
/* bits 10-9 are unused */
/* bits 8-0 are drive type; the correct values are hard to determine */
#define HPDT_RM02 0000025 /* rm02, possibly rm03? */
+ #define HPDT_RM80 0000026 /* rm80 */
+ #define HPDT_RM05 0000027 /* rm05 */
#define HPDT_RM03 0000024 /* rm03 */
+ #define HPDT_RP04 0000020 /* rp04 */
+ #define HPDT_RP05 0000021 /* rp05 */
#define HPDT_RP06 0000022 /* rp06 */
#define HPDT_RP07 0000042 /* rp07 */
***************
*** 243,248 ****
--- 184,199 ----
#define HPOF_BITS \
"\10\15FMT22\14ECI\13HCI\10OD"
+ /*
+ * rmhr
+ *
+ * Emulex (i.e non DEC) controllers implement the ability to query for
+ * the drive geometry by placing these codes into the 'holding register'.
+ */
+ #define HPHR_MAXCYL 0x8017 /* max cylinder */
+ #define HPHR_MAXTRAK 0x8018 /* max track/cylinder */
+ #define HPHR_MAXSECT 0x8019 /* max sector/track */
+
/* rmer2: These are the bits for an RM error register 2 */
#define RMER2_BSE 0100000 /* bad sector error */
#define RMER2_SKI 0040000 /* seek incomplete */
***************
*** 279,285 ****
#define SIMB_MB 0xff00 /* model byte value */
#define SIMB_S6 0x2000 /* switch s6 */
#define SIMB_LU 0x0007 /* logical unit (should = drive #) */
- #define SIMB_XX 0x4000 /* for some reason this is sometimes set */
#define SI9775D 0x0700 /* 9775 direct */
#define SI9775M 0x0e00 /* 9775 mapped */
--- 230,235 ----
*** /usr/src/sys/pdpuba/xp.c.old Thu Apr 13 22:41:12 1995
--- /usr/src/sys/pdpuba/xp.c Mon Aug 21 21:08:34 1995
***************
*** 3,21 ****
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)xp.c 1.8 (2.11BSD GTE) 1995/04/13
*/
/*
! * RM02/03/05, RP04/05/06, Ampex 9300, CDC 9766, DIVA, Fuji 160, and SI
! * Eagle. This driver will handle most variants of SMD drives on one or more
! * controllers. If XP_PROBE is defined, it includes a probe routine that
! * will determine the number and type of drives attached to each controller;
! * otherwise, the data structures must be initialized.
! * Added RP07. /BQT 930612
! *
! * For simplicity we use hpreg.h instead of an xpreg.h.
! * The bits are the same.
*/
#include "xp.h"
--- 3,14 ----
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)xp.c 2.2 (2.11BSD GTE) 1995/08/21
*/
/*
! * RM02/03/05, RP04/05/06/07, CDC 9766, SI, Fuji 160 and Eagle. This
! * driver will handle most variants of SMD drives on one or more controllers.
*/
#include "xp.h"
***************
*** 33,45 ****
#include "dk.h"
#include "disklabel.h"
#include "disk.h"
#include "map.h"
#include "uba.h"
#define XP_SDIST 2
#define XP_RDIST 6
- #define xpunit(dev) ((minor(dev) >> 3) & 07)
int xp_offset[] = {
HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400,
HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800,
--- 26,52 ----
#include "dk.h"
#include "disklabel.h"
#include "disk.h"
+ #include "file.h"
#include "map.h"
#include "uba.h"
+ #include "stat.h"
+ #include "syslog.h"
#define XP_SDIST 2
#define XP_RDIST 6
+ /*
+ * 'xp' is unique amoung 2.11BSD disk drivers. Drives are not organized
+ * into groups of 8 drives per controller. Instead drives are numbered
+ * across controllers: the second drive ("unit 1") could be on the 2nd
+ * controller. This has the effect of turning the high 5 bits of the minor
+ * device number into the unit number and drives are thus numbered 0 thru 31.
+ *
+ * NOTE: this is different than /boot's view of the world. Sigh.
+ */
+
+ #define XPUNIT(dev) ((minor(dev) >> 3) & 0x1f)
+
int xp_offset[] = {
HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400,
HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800,
***************
*** 51,287 ****
struct buf *xp_actf; /* pointer to next active xputab */
struct buf *xp_actl; /* pointer to last active xputab */
struct hpdevice *xp_addr; /* csr address */
! char xp_flags; /* controller-type flags */
char xp_active; /* nonzero if doing a transfer */
};
struct xp_drive {
struct xp_controller *xp_ctlr; /* controller to which slave attached */
! char xp_type; /* drive type */
! char xp_unit; /* slave number */
! struct size *xp_sizes; /* pointer to sizes array */
! char xp_nsect;
! char xp_ntrack;
! int xp_nspc; /* sectors/cylinder */
! int xp_cc; /* current cylinder, for RM's */
! #ifdef BADSECT
! int xp_ncyl; /* cylinders per pack */
! #endif
! };
!
/*
! * bits in xp_flags:
! */
! #define XP_NOCC 1 /* has no current cylinder register */
! #define XP_RH70 2 /* uses 22-bit addressing */
! #define XP_NOSEARCH 4 /* won't do search commands */
! #ifdef BADSECT
! #define NCYL(x) (x)
! #else !BADSECT
! #define NCYL(x) /* not used */
! #endif BADSECT
- #ifndef XP_PROBE
- /*
- * Macros to inititialize xp_drive entries. These can be used as examples,
- * or as the actual initializers in ioconf.c. The arguments are the number
- * of the controller to which the drive is attached, and the physical
- * drive unit number. Used only if XP_PROBE is not defined. See xp.c
- * for more information.
- */
- #define RM02_INIT(c,u) \
- { &xp_controller[c], RM02, u, &rm_sizes, \
- RM_SECT, RM_TRAC, RM_SECT*RM_TRAC, 0, NCYL(RM_CYL) }
- #define RM03_INIT(c,u) \
- { &xp_controller[c], RM03, u, &rm_sizes, \
- RM_SECT, RM_TRAC, RM_SECT*RM_TRAC, 0, NCYL(RM_CYL) }
- #define RM05_INIT(c,u) \
- { &xp_controller[c], RM05, u, &rm5_sizes, \
- RM5_SECT, RM5_TRAC, RM5_SECT*RM5_TRAC, 0, NCYL(RM5_CYL) }
- #define RM05X_INIT(c,u) \
- { &xp_controller[c], RM05X, u, &rm5_sizes, \
- RM5_SECT, RM5_TRAC, RM5_SECT*RM5_TRAC, 0, NCYL(RM5X_CYL) }
- #define RP06_INIT(c,u) \
- { &xp_controller[c], RP06, u, &hp_sizes, \
- HP_SECT, HP_TRAC, HP_SECT*HP_TRAC, 0, NCYL(RP06_CYL) }
- #define RP05_INIT(c,u) \
- { &xp_controller[c], RP05, u, &hp_sizes, \
- HP_SECT, HP_TRAC, HP_SECT*HP_TRAC, 0, NCYL(RP04_CYL) }
- #define RP04_INIT(c,u) \
- { &xp_controller[c], RP04, u, &hp_sizes, \
- HP_SECT, HP_TRAC, HP_SECT*HP_TRAC, 0, NCYL(RP04_CYL) }
- #define SI_INIT(c,u) \
- { &xp_controller[c], SI, u, &si_sizes, \
- SI_SECT, SI_TRAC, SI_SECT*SI_TRAC, 0, NCYL(SI_CYL) }
- #define DV_INIT(c,u) \
- { &xp_controller[c], DV, u, &dv_sizes, \
- DV_SECT, DV_TRAC, DV_SECT*DV_TRAC, 0, NCYL(DV_CYL) }
- #define RM2X_INIT(c,u) \
- { &xp_controller[c], RM2X, u, &rm2x_sizes, \
- RM2X_SECT, RM2X_TRAC, RM2X_SECT*RM2X_TRAC, 0, NCYL(RM2X_CYL) }
- #endif !XP_PROBE
-
-
- /*
- * xp_drive and xp_controller may be initialized here, or filled in at boot
- * time if XP_PROBE is enabled. xp_controller address fields must be
- * initialized for any boot devices, however.
- *
- * xp_controller structure: one line per controller. Only the address need
- * be initialized in the controller structure if XP_PROBE is defined (at least
- * the address for the root device); otherwise the flags must be here also.
- * The XP_NOCC flag is set for RM02/03/05's (with no current cylinder
- * register); XP_NOSEARCH is set for Diva's without the search command. The
- * XP_RH70 flag need not be set here, the driver will always check that.
- */
- #define XPADDR ((struct hpdevice *)0176700)
-
- struct xp_controller xp_controller[NXPC] = {
- /* 0 0 addr flags 0 */
- #ifdef XP_PROBE
- 0, 0, XPADDR, 0, 0
- #else
- 0, 0, XPADDR, XP_NOCC|XP_NOSEARCH, 0
- #endif
- };
-
- /*
- * xp_drive structure: one entry per drive. The drive structure must be
- * initialized if XP_PROBE is not enabled. Macros are provided in hpreg.h
- * to initialize entries according to drive type, and controller and drive
- * numbers. See those for examples on how to set up other types of drives.
- * With XP_PROBE defined, xpslave will fill in this structure, and any
- * initialization will be overridden. There is one exception; if the
- * drive-type field is set, it will be used instead of the drive-type register
- * to determine the drive's type.
- */
- struct xp_drive xp_drive[NXPD]
- #ifndef XP_PROBE
- = {
- RM02_INIT(0,0), /* RM02, controller 0, drive 0 */
- RM02_INIT(0,1), /* RM02, controller 0, drive 1 */
- RM2X_INIT(0,0) /* Fuji 160, controller 0, drive 0 */
- RM2X_INIT(0,1) /* Fuji 160, controller 0, drive 1 */
- RM05X_INIT(0,2) /* 815-cyl RM05, controller 0, drive 2 */
- }
- #endif
- ;
-
- /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
- struct size {
- daddr_t nblocks;
- int cyloff;
- } hp_sizes[8] = { /* RP04/05/06 */
- 9614, 0, /* a: cyl 0 - 22 */
- 8778, 23, /* b: cyl 23 - 43 */
- 153406, 44, /* c: cyl 44 - 410, RP04/05 */
- 168872, 411, /* d: cyl 411 - 814, RP06 */
- 322278, 44, /* e: cyl 44 - 814, RP06 */
- 0, 0, /* f: Not Defined */
- 171798, 0, /* g: cyl 0 - 410, whole RP04/05 */
- 340670, 0, /* h: cyl 0 - 814, whole RP06 */
- }, rp_sizes[8] = { /* RP07 */
- 19200, 0, /* a: cyl 0 - 11 */
- 51200, 12, /* b: cyl 12 - 43 */
- 1008000, 0, /* c: cyl 0 - 629, whole RP07 */
- 320000, 44, /* d: cyl 44 - 243 */
- 320000, 244, /* e: cyl 244 - 443 */
- 297600, 444, /* f: cyl 444 - 629 */
- 937600, 44, /* g: cyl 44 - 629 */
- 1008000, 0, /* h: cyl 0 - 629, whole RP07 */
- }, rm_sizes[8] = { /* RM02/03 */
- 9600, 0, /* a: cyl 0 - 59 */
- 9600, 60, /* b: cyl 60 - 119 */
- 131680, 0, /* c: cyl 0 - 822, whole RM02/03 */
- 0, 0, /* d: Not Defined */
- 0, 0, /* e: Not Defined */
- 121920, 60, /* f: cyl 60 - 821 */
- 112320, 120, /* g: cyl 120 - 821 */
- 131680, 0, /* h: cyl 0 - 822, whole RM02/03 */
- }, rm5_sizes[8] = { /* RM05, or SI 9500, CDC 9766 */
- 9120, 0, /* a: cyl 0 - 14 */
- 9120, 15, /* b: cyl 15 - 29 */
- 234080, 30, /* c: cyl 30 - 414 */
- 248064, 415, /* d: cyl 415 - 822 */
- 164160, 30, /* e: cyl 30 - 299 */
- 152000, 300, /* f: cyl 300 - 549 */
- 165984, 550, /* g: cyl 550 - 822 */
- 500384, 0, /* h: cyl 0 - 822 */
- }, cap_sizes[8] = { /* Ampex Capricorn */
- 16384, 0, /* a: cyl 0 thru 31 */
- 33792, 32, /* b: cyl 32 thru 97 */
- 291840, 98, /* c: cyl 98 thru 667 */
- 16384, 668, /* d: cyl 668 thru 699 */
- 56320, 700, /* e: cyl 700 thru 809 */
- 109568, 810, /* f: cyl 810 thru 1023 */
- 182272, 668, /* g: cyl 668 thru 1023 */
- 524288, 0, /* h: cyl 0 thru 1023 */
- }, si5_sizes[8] = { /* SI, CDC 9775, direct mapping */
- 10240, 0, /* a: cyl 0 - 7 */
- 10240, 8, /* b: cyl 8 - 15 */
- 510720, 16, /* c: cyl 16 - 414 */
- 547840, 415, /* d: cyl 415 - 842 */
- 363520, 16, /* e: cyl 16 - 299 */
- 320000, 300, /* f: cyl 300 - 549 */
- 375040, 550, /* g: cyl 550 - 842 */
- 1079040, 0, /* h: cyl 0 - 842 */
- }, si_sizes[8] = { /* SI 6100, Fuji Eagle 2351A */
- 11520, 0, /* a: cyl 0 - 11 */
- 11520, 12, /* b: cyl 12 - 23 */
- 474240, 24, /* c: cyl 24 - 517 */
- 92160, 518, /* d: cyl 518 - 613 */
- 218880, 614, /* e: cyl 614 - 841 */
- 0, 0, /* f: Not Defined */
- 0, 0, /* g: Not Defined */
- 808320, 0, /* h: cyl 0 - 841 (everything) */
- }, rm2x_sizes[8] = { /* Emulex SC01B or SI 9400, Fuji 160 */
- 9600, 0, /* a: cyl 0 - 29 */
- 9600, 30, /* b: cyl 30 - 59 */
- 244160, 60, /* c: cyl 60 - 822 */
- 164800, 60, /* d: cyl 60 - 574 */
- 79360, 575, /* e: cyl 575 - 822 */
- 39680, 575, /* f: cyl 575 - 698 */
- 39680, 699, /* g: cyl 699 - 822 */
- 263360, 0, /* h: cyl 0 - 822 */
- }, dv_sizes[8] = { /* Diva Comp V, Ampex 9300 in direct mode */
- 9405, 0, /* a: cyl 0 - 14 */
- 9405, 15, /* b: cyl 15 - 29 */
- 241395, 30, /* c: cyl 30 - 414 */
- 250800, 415, /* d: cyl 415 - 814 */
- 169290, 30, /* e: cyl 30 - 299 */
- 156750, 300, /* f: cyl 300 - 549 */
- 166155, 550, /* g: cyl 550 - 814 */
- 511005, 0, /* h: cyl 0 - 814 */
- };
- /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
-
- #ifdef XP_PROBE
- struct xpst {
- short type; /* value from controller type register */
- short nsect; /* number of sectors/track */
- short ntrack; /* number of tracks/cylinder */
- short ncyl; /* number of cylinders */
- struct size *sizes; /* partition tables */
- short flags; /* controller flags */
- } xpst[] = {
- { RP04, HP_SECT, HP_TRAC, RP04_CYL, hp_sizes, 0 },
- { RP05, HP_SECT, HP_TRAC, RP04_CYL, hp_sizes, 0 },
- { RP06, HP_SECT, HP_TRAC, RP06_CYL, hp_sizes, 0 },
- { RP07, RP7_SECT, RP7_TRAC, RP7_CYL, rp_sizes, 0 },
- { RM02, RM_SECT, RM_TRAC, RM_CYL, rm_sizes, XP_NOCC },
- { RM03, RM_SECT, RM_TRAC, RM_CYL, rm_sizes, XP_NOCC },
- { RM05, RM5_SECT, RM5_TRAC, RM5_CYL, rm5_sizes, XP_NOCC },
- { CAP, CAP_SECT, CAP_TRAC, CAP_CYL, cap_sizes, XP_NOCC },
- { SI5, SI5_SECT, SI5_TRAC, SI5_CYL, si5_sizes, XP_NOCC },
- { SI, SI_SECT, SI_TRAC, SI_CYL, si_sizes, XP_NOCC },
- { RM2X, RM2X_SECT, RM2X_TRAC, RM2X_CYL, rm2x_sizes, XP_NOCC },
- { RM5X, RM5X_SECT, RM5X_TRAC, RM5X_CYL, rm5_sizes, XP_NOCC },
- { DV, DV_SECT, DV_TRAC, DV_CYL, dv_sizes, XP_NOSEARCH },
- { 0, 0, 0, 0, 0 }
- };
- #endif
-
struct buf xptab;
struct buf xputab[NXPD];
--- 58,91 ----
struct buf *xp_actf; /* pointer to next active xputab */
struct buf *xp_actl; /* pointer to last active xputab */
struct hpdevice *xp_addr; /* csr address */
! char xp_rh70; /* massbus flag */
char xp_active; /* nonzero if doing a transfer */
};
struct xp_drive {
struct xp_controller *xp_ctlr; /* controller to which slave attached */
! int xp_unit; /* slave number */
! u_short xp_nsect;
! u_short xp_ntrack;
! u_short xp_nspc; /* sectors/cylinder */
! u_short xp_cc; /* current cylinder, for RM's */
! u_long xp_dd0; /* drivedata longword 0 */
! struct dkdevice xp_dk; /* kernel resident portion of label */
! u_short xp_ncyl; /* cylinders per pack */
! };
/*
! * Some shorthand for accessing the in-kernel label structure.
! */
! #define xp_bopen xp_dk.dk_bopenmask
! #define xp_copen xp_dk.dk_copenmask
! #define xp_open xp_dk.dk_openmask
! #define xp_flags xp_dk.dk_flags
! #define xp_label xp_dk.dk_label
! #define xp_parts xp_dk.dk_parts
! struct xp_controller xp_controller[NXPC];
! struct xp_drive xp_drive[NXPD];
struct buf xptab;
struct buf xputab[NXPD];
***************
*** 288,294 ****
#ifdef BADSECT
struct dkbad xpbad[NXPD];
struct buf bxpbuf[NXPD];
- bool_t xp_init[NXPD];
#endif
#ifdef UCB_METER
--- 92,97 ----
***************
*** 295,365 ****
static int xp_dkn = -1; /* number for iostat */
#endif
/*
! * Attach controllers whose addresses are known at boot time. Stop at the
! * first not found, so that the drive numbering won't get confused.
*/
- xproot()
- {
- register int i;
- register struct hpdevice *xpaddr;
! #ifdef GENERIC
! printf("\nxp_drive=0%o xp_controller=0%o\n",xp_drive,xp_controller);
! delay(10000000L); /* 10 secs to halt and patch xp_drive */
! #endif
! for (i = 0; i < NXPC; i++)
! if (((xpaddr = xp_controller[i].xp_addr) == 0)
! || (xpattach(xpaddr, i) == 0))
! break;
! }
/*
* Attach controller at xpaddr. Mark as nonexistent if xpaddr is 0; otherwise
! * attach slaves if probing. NOTE: if probing for drives, this routine must
! * be called once per controller, in ascending controller numbers.
*/
xpattach(xpaddr, unit)
register struct hpdevice *xpaddr;
! int unit;
{
register struct xp_controller *xc = &xp_controller[unit];
- #ifdef XP_PROBE
static int last_attached = -1;
- #endif
#ifdef UCB_METER
! if (xp_dkn < 0) {
dk_alloc(&xp_dkn, NXPD+NXPC, "xp", 0L);
- #ifndef XP_PROBE
- /*
- * Hard coded drive configuration - snag the number of
- * sectors per track for each drive and compute drive
- * transfer rate assuming 3600rpm (the Fujitsu Eagle 2351A
- * (SI Eagle) is actually 3961rpm; it's just not worth the
- * effort to fix the assumption.) If XP_PROBE is defined we
- * grab the number of sectors/track for each drive in
- * xpslave.
- */
- if (xp_dkn >= 0) {
- register int i;
- register long *lp;
-
- for (i = 0, lp = &dk_wps[xp_dkn]; i < NXPD; i++)
- *lp++ = (long)xp_drive[i].xp_nsect
- * (60L * 256L);
- }
#endif
- }
- #endif
if ((unsigned)unit >= NXPC)
return(0);
! if ((xpaddr != 0) && (fioword(xpaddr) != -1)) {
xc->xp_addr = xpaddr;
if (fioword(&xpaddr->hpbae) != -1)
! xc->xp_flags |= XP_RH70;
! #ifdef XP_PROBE
/*
* If already attached, ignore (don't want to renumber drives)
*/
--- 98,158 ----
static int xp_dkn = -1; /* number for iostat */
#endif
+ int xpstrategy();
+ void xpgetinfo();
+ daddr_t xpsize();
+ extern size_t physmem;
+
/*
! * Setup root SMD ('xp') device (use bootcsr passed from ROMs). In the event
! * that the system was not booted from a SMD drive but swapdev is a SMD device
! * we attach the first (0176700) controller. This would be a very unusual
! * configuration and is unlikely to be encountered.
! *
! * This is very confusing, it is an ugly hack, but short of moving autoconfig
! * back into the kernel there's nothing else I can think of to do.
! *
! * NOTE: the swap device must be on the controller used for booting since
! * that is the only one attached here - the other controllers are attached
! * by /etc/autoconfig when it runs later.
*/
! xproot(csr)
! register struct hpdevice *csr;
! {
+ if (!csr) /* XXX */
+ csr = (struct hpdevice *)0176700; /* XXX */
+ xpattach(csr, 0);
+ }
+
/*
* Attach controller at xpaddr. Mark as nonexistent if xpaddr is 0; otherwise
! * attach slaves. This routine must be called once per controller
! * in ascending controller numbers.
! *
! * NOTE: This means that the 'xp' lines in /etc/dtab _MUST_ be in order
! * starting with 'xp 0' first.
*/
+
xpattach(xpaddr, unit)
register struct hpdevice *xpaddr;
! int unit; /* controller number */
{
register struct xp_controller *xc = &xp_controller[unit];
static int last_attached = -1;
#ifdef UCB_METER
! if (xp_dkn < 0)
dk_alloc(&xp_dkn, NXPD+NXPC, "xp", 0L);
#endif
if ((unsigned)unit >= NXPC)
return(0);
! if (xpaddr && (fioword(xpaddr) != -1)) {
xc->xp_addr = xpaddr;
if (fioword(&xpaddr->hpbae) != -1)
! xc->xp_rh70 = 1;
/*
* If already attached, ignore (don't want to renumber drives)
*/
***************
*** 367,373 ****
last_attached = unit;
xpslave(xpaddr, xc);
}
- #endif
return(1);
}
xc->xp_addr = 0;
--- 160,165 ----
***************
*** 374,383 ****
return(0);
}
- #ifdef XP_PROBE
/*
! * Determine what drives are attached to a controller; guess their types and
! * fill in the drive structures.
*/
xpslave(xpaddr, xc)
register struct hpdevice *xpaddr;
--- 166,174 ----
return(0);
}
/*
! * Determine what drives are attached to a controller; the type and geometry
! * information will be retrieved at open time from the disklabel.
*/
xpslave(xpaddr, xc)
register struct hpdevice *xpaddr;
***************
*** 389,395 ****
static int nxp = 0;
for (j = 0; j < 8; j++) {
! xpaddr->hpcs1.w = 0;
xpaddr->hpcs2.w = j;
xpaddr->hpcs1.w = HP_GO; /* testing... */
delay(6000L);
--- 180,186 ----
static int nxp = 0;
for (j = 0; j < 8; j++) {
! xpaddr->hpcs1.w = HP_NOP;
xpaddr->hpcs2.w = j;
xpaddr->hpcs1.w = HP_GO; /* testing... */
delay(6000L);
***************
*** 402,536 ****
xd = &xp_drive[nxp++];
xd->xp_ctlr = xc;
xd->xp_unit = j;
! /* If drive type is initialized, believe it. */
! if (xd->xp_type == 0) {
! xd->xp_type = xpaddr->hpdt & 077;
! xd->xp_type = xpmaptype(xd, xpaddr->hpsn);
! }
! for (st = xpst; st->type; st++)
! if (st->type == xd->xp_type) {
! xd->xp_nsect = st->nsect;
! xd->xp_ntrack = st->ntrack;
! xd->xp_nspc = st->nsect * st->ntrack;
! #ifdef BADSECT
! xd->xp_ncyl = st->ncyl;
! #endif
! xd->xp_sizes = st->sizes;
! xd->xp_ctlr->xp_flags |= st->flags;
! break;
! }
! if (!st->type) {
! printf("xp%d: drive type %o unrecognized\n",nxp - 1, xd->xp_type);
! xd->xp_ctlr = NULL;
! }
!
! #ifdef UCB_METER
! if (xp_dkn >= 0 && xd->xp_ctlr)
! dk_wps[xd - &xp_drive[0]]
! = (long)xd->xp_nsect * (60L * 256L);
! #endif
}
}
}
! static
! xpmaptype(xd, hpsn)
! register struct xp_drive *xd;
! register u_short hpsn;
! {
! register u_short type = xd->xp_type;
! /*
! * Model-byte processing for SI controllers.
! * NB: Only deals with RM02, RM03 and RM05 emulations.
! */
! if ((type == RM02 || type == RM03 || type == RM05)
! && (hpsn & SIMB_LU) == xd->xp_unit) {
! switch (hpsn & (SIMB_MB & ~(SIMB_S6|SIMB_XX|SIRM03|SIRM05))) {
! case SI9775D:
! type = SI5;
! break;
! case SI9775M:
! type = RM05;
! break;
! case SI9730D:
! type = RM2X;
! break;
! case SI9766:
! type = RM05;
! break;
! case SI9762:
! type = RM03;
! break;
! case SICAPD:
! type = CAP;
! break;
! case SI9751D:
! type = SI;
! break;
! }
}
- return(type);
- }
- #endif XP_PROBE
! xpopen(dev)
! dev_t dev;
! {
register struct xp_drive *xd;
! register int unit = xpunit(dev);
! if (unit >= NXPD || !(xd = &xp_drive[unit])->xp_ctlr ||
! !xd->xp_ctlr->xp_addr)
! return (ENXIO);
! return (0);
! }
xpstrategy(bp)
register struct buf *bp;
! {
register struct xp_drive *xd;
! register int unit;
struct buf *dp;
! short pseudo_unit;
! int s;
! long bn;
! unit = dkunit(bp->b_dev);
! pseudo_unit = dkpart(bp->b_dev);
! if ((unit >= NXPD) || ((xd = &xp_drive[unit])->xp_ctlr == 0) ||
! (xd->xp_ctlr->xp_addr == 0)) {
bp->b_error = ENXIO;
! goto errexit;
! }
! if ((bp->b_blkno < 0) || ((bn = bp->b_blkno) + ((bp->b_bcount + 511)
! >> 9) > xd->xp_sizes[pseudo_unit].nblocks)) {
! bp->b_error = EINVAL;
! errexit:
! bp->b_flags |= B_ERROR;
! iodone(bp);
! return;
! }
! if ((xd->xp_ctlr->xp_flags & XP_RH70) == 0)
mapalloc(bp);
! bp->b_cylin = bn / xd->xp_nspc + xd->xp_sizes[pseudo_unit].cyloff;
dp = &xputab[unit];
s = splbio();
disksort(dp, bp);
! if (dp->b_active == 0) {
xpustart(unit);
! if (xd->xp_ctlr->xp_active == 0)
xpstart(xd->xp_ctlr);
! }
splx(s);
! }
/*
* Unit start routine. Seek the drive to where the data are and then generate
--- 193,455 ----
xd = &xp_drive[nxp++];
xd->xp_ctlr = xc;
xd->xp_unit = j;
! /*
! * Allocate the disklabel now. This is very early in the system's life
! * so fragmentation will be minimized if any labels are allocated from
! * main memory. Then initialize the flags to indicate a drive is present.
! */
! xd->xp_label = disklabelalloc();
! xd->xp_flags = DKF_ALIVE;
}
}
}
! xpopen(dev, flags, mode)
! dev_t dev;
! int flags, mode;
! {
! register struct xp_drive *xd;
! int unit = XPUNIT(dev);
! int i, part = dkpart(dev), rpm;
! register int mask;
! if (unit >= NXPD)
! return(ENXIO);
! xd = &xp_drive[unit];
! if ((xd->xp_flags & DKF_ALIVE) == 0)
! return(ENXIO);
! /*
! * Now we read the label. First wait for any pending opens/closes to
! * complete.
! */
! while (xd->xp_flags & (DKF_OPENING|DKF_CLOSING))
! sleep(xd, PRIBIO);
! /*
! * On first open get label (which has the geometry information as well as
! * the partition tables). We may block reading the label so be careful to
! * stop any other opens.
! */
! if (xd->xp_open == 0)
! {
! xd->xp_flags |= DKF_OPENING;
! xpgetinfo(xd, dev);
! xd->xp_flags &= ~DKF_OPENING;
! wakeup(xd);
! }
! /*
! * Need to make sure the partition is not out of bounds. This requires
! * mapping in the external label. Since this only happens when a partition
! * is opened (at mount time for example) it is unlikely to be an efficiency
! * concern.
! */
! mapseg5(xd->xp_label, LABELDESC);
! i = ((struct disklabel *)SEG5)->d_npartitions;
! rpm = ((struct disklabel *)SEG5)->d_rpm;
! normalseg5();
! if (part >= i)
! return(ENXIO);
! #ifdef UCB_METER
! if (xp_dkn >= 0)
! dk_wps[xd - xp_drive] = (long) xd->xp_nsect * (rpm / 60) * 256L;
! #endif
! mask = 1 << part;
! dkoverlapchk(xd->xp_open, dev, xd->xp_label, "xp");
! if (mode == S_IFCHR)
! xd->xp_copen |= mask;
! else if (mode == S_IFBLK)
! xd->xp_bopen |= mask;
! else
! return(EINVAL);
! xd->xp_open |= mask;
! return(0);
! }
! xpclose(dev, flags, mode)
! dev_t dev;
! int flags, mode;
! {
! int s;
! register int mask;
! register struct xp_drive *xd;
! int unit = XPUNIT(dev);
! xd = &xp_drive[unit];
! mask = 1 << dkpart(dev);
! if (mode == S_IFCHR)
! xd->xp_copen &= ~mask;
! else if (mode == S_IFBLK)
! xd->xp_bopen &= ~mask;
! else
! return(EINVAL);
! xd->xp_open = xd->xp_copen | xd->xp_bopen;
! if (xd->xp_open == 0)
! {
! xd->xp_flags |= DKF_CLOSING;
! s = splbio();
! while (xputab[unit].b_actf)
! sleep(&xputab[unit], PRIBIO);
! xd->xp_flags &= ~DKF_CLOSING;
! splx(s);
! wakeup(xd);
! }
! return(0);
! }
! void
! xpdfltlbl(xd, lp)
! register struct xp_drive *xd;
! register struct disklabel *lp;
! {
! register struct partition *pi = &lp->d_partitions[0];
! /*
! * NOTE: partition 0 ('a') is used to read the label. Therefore 'a' must
! * start at the beginning of the disk! If there is no label or the label
! * is corrupted then a label containing a geometry sufficient *only* to
! * read/write sector 1 (LABELSECTOR) is created. 1 track, 1 cylinder and
! * 2 sectors per track.
! */
! bzero(lp, sizeof (*lp));
! lp->d_type = DTYPE_SMD;
! lp->d_secsize = 512; /* XXX */
! lp->d_nsectors = LABELSECTOR + 1; /* # sectors/track */
! lp->d_ntracks = 1; /* # tracks/cylinder */
! lp->d_secpercyl = LABELSECTOR + 1; /* # sectors/cylinder */
! lp->d_ncylinders = 1; /* # cylinders */
! lp->d_npartitions = 1; /* 1 partition = 'a' */
! /*
! * Need to put the information where the driver expects it. This is normally
! * done after reading the label. Since we're creating a fake label we have to
! * copy the invented geometry information to the right place.
! */
! xd->xp_nsect = lp->d_nsectors;
! xd->xp_ntrack = lp->d_ntracks;
! xd->xp_nspc = lp->d_secpercyl;
! xd->xp_ncyl = lp->d_ncylinders;
! xd->xp_dd0 = lp->d_drivedata[0];
! pi->p_size = LABELSECTOR + 1;
! pi->p_fstype = FS_V71K;
! pi->p_frag = 1;
! pi->p_fsize = 1024;
! bcopy(pi, xd->xp_parts, sizeof (lp->d_partitions));
}
! /*
! * Read disklabel. It is tempting to generalize this routine so that
! * all disk drivers could share it. However by the time all of the
! * necessary parameters are setup and passed the savings vanish. Also,
! * each driver has a different method of calculating the number of blocks
! * to use if one large partition must cover the disk.
! *
! * This routine used to always return success and callers carefully checked
! * the return status. Silly. This routine will fake a label (a single
! * partition spanning the drive) if necessary but will never return an error.
! *
! * It is the caller's responsibility to check the validity of partition
! * numbers, etc.
! */
!
! void
! xpgetinfo(xd, dev)
register struct xp_drive *xd;
! dev_t dev;
! {
! struct disklabel locallabel;
! char *msg;
! register struct disklabel *lp = &locallabel;
! xpdfltlbl(xd, lp);
! msg = readdisklabel((dev & ~7) | 0, xpstrategy, lp); /* 'a' */
! if (msg != 0)
! {
! log(LOG_NOTICE, "xp%da using labelonly geometry: %s\n",
! XPUNIT(dev), msg);
! xpdfltlbl(xd, lp);
! }
! mapseg5(xd->xp_label, LABELDESC);
! bcopy(lp, (struct disklabel *)SEG5, sizeof (struct disklabel));
! normalseg5();
! bcopy(lp->d_partitions, xd->xp_parts, sizeof (lp->d_partitions));
! xd->xp_nsect = lp->d_nsectors;
! xd->xp_ntrack = lp->d_ntracks;
! xd->xp_nspc = lp->d_secpercyl;
! xd->xp_ncyl = lp->d_ncylinders;
! xd->xp_dd0 = lp->d_drivedata[0];
! return;
! }
xpstrategy(bp)
register struct buf *bp;
! {
register struct xp_drive *xd;
! register struct partition *pi;
! int unit, part;
struct buf *dp;
! int s;
! daddr_t sz;
! unit = XPUNIT(bp->b_dev);
! part = dkpart(bp->b_dev);
! xd = &xp_drive[unit];
! if (unit >= NXPD || !xd->xp_ctlr || !(xd->xp_flags & DKF_ALIVE))
! {
bp->b_error = ENXIO;
! goto bad;
! }
! pi = &xd->xp_parts[part];
!
! sz = (bp->b_bcount + 511) >> 9;
! if (bp->b_blkno < 0 || bp->b_blkno + sz > pi->p_size)
! {
! sz = pi->p_size - bp->b_blkno;
! /* If exactly at end of disk, return an EOF */
! if (sz == 0)
! {
! bp->b_resid = bp->b_bcount;
! goto done;
! }
! /* or truncate if part of it fits */
! if (sz < 0)
! {
! bp->b_error = EINVAL;
! goto bad;
! }
! bp->b_bcount = dbtob(sz); /* compute byte count */
! }
! /*
! * Check for write to write-protected label area. This does not include
! * sector 0 which is the boot block.
! */
! if (bp->b_blkno + pi->p_offset <= LABELSECTOR &&
! bp->b_blkno + pi->p_offset + sz > LABELSECTOR &&
! !(bp->b_flags & B_READ) && !(xd->xp_flags & DKF_WLABEL))
! {
! bp->b_error = EROFS;
! goto bad;
! }
! if (xd->xp_ctlr->xp_rh70 == 0)
mapalloc(bp);
! bp->b_cylin = (bp->b_blkno + pi->p_offset) / xd->xp_nspc;
dp = &xputab[unit];
s = splbio();
disksort(dp, bp);
! if (dp->b_active == 0)
! {
xpustart(unit);
! if (xd->xp_ctlr->xp_active == 0)
xpstart(xd->xp_ctlr);
! }
splx(s);
! return;
! bad:
! bp->b_flags |= B_ERROR;
! done:
! iodone(bp);
! return;
! }
/*
* Unit start routine. Seek the drive to where the data are and then generate
***************
*** 540,551 ****
* for transfer (to avoid positioning forever without transferring).
*/
xpustart(unit)
! int unit;
{
register struct xp_drive *xd;
register struct hpdevice *xpaddr;
register struct buf *dp;
! struct buf *bp;
daddr_t bn;
int sn, cn, csn;
--- 459,470 ----
* for transfer (to avoid positioning forever without transferring).
*/
xpustart(unit)
! int unit;
{
register struct xp_drive *xd;
register struct hpdevice *xpaddr;
register struct buf *dp;
! struct buf *bp, *bbp;
daddr_t bn;
int sn, cn, csn;
***************
*** 554,561 ****
xpaddr->hpcs2.w = xd->xp_unit;
xpaddr->hpcs1.c[0] = HP_IE;
xpaddr->hpas = 1 << xd->xp_unit;
- if (unit >= NXPD)
- return;
#ifdef UCB_METER
if (xp_dkn >= 0)
dk_busy &= ~(1 << (xp_dkn + unit));
--- 473,478 ----
***************
*** 573,595 ****
/*
* If drive has just come up, set up the pack.
*/
! #ifdef BADSECT
! if (((xpaddr->hpds & HPDS_VV) == 0) || (xp_init[unit] == 0)) {
! struct buf *bbp = &bxpbuf[unit];
! #else
! if ((xpaddr->hpds & HPDS_VV) == 0) {
! #endif
! /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
! #ifdef XP_DEBUG
! printf("preset-unit=%d\n", unit);
! #endif
xpaddr->hpcs1.c[0] = HP_IE | HP_PRESET | HP_GO;
- #ifdef XP_DEBUG
- printf("preset done\n");
- #endif
xpaddr->hpof = HPOF_FMT22;
#ifdef BADSECT
! xp_init[unit] = 1;
bbp->b_flags = B_READ | B_BUSY | B_PHYS;
bbp->b_dev = bp->b_dev | 7; /* "h" partition whole disk */
bbp->b_bcount = sizeof(struct dkbad);
--- 490,511 ----
/*
* If drive has just come up, set up the pack.
*/
! if (((xpaddr->hpds & HPDS_VV) == 0) || !(xd->xp_flags & DKF_ONLINE)) {
xpaddr->hpcs1.c[0] = HP_IE | HP_PRESET | HP_GO;
xpaddr->hpof = HPOF_FMT22;
+ xd->xp_flags |= DKF_ONLINE;
+ #ifdef XPDEBUG
+ log(LOG_NOTICE, "xp%d preset done\n", unit);
+ #endif
+ }
+ /*
+ * XXX - The 'h' partition is used below to access the bad block area. This
+ * XXX - will almost certainly be wrong if the user has defined another
+ * XXX - partition to span the entire drive including the bad block area. It
+ * XXX - is not known what to do about this.
+ */
#ifdef BADSECT
! bbp = &bxpbuf[unit];
bbp->b_flags = B_READ | B_BUSY | B_PHYS;
bbp->b_dev = bp->b_dev | 7; /* "h" partition whole disk */
bbp->b_bcount = sizeof(struct dkbad);
***************
*** 596,614 ****
bbp->b_un.b_addr = (caddr_t)&xpbad[unit];
bbp->b_blkno = (daddr_t)xd->xp_ncyl * xd->xp_nspc - xd->xp_nsect;
bbp->b_cylin = xd->xp_ncyl - 1;
! if ((xd->xp_ctlr->xp_flags & XP_RH70) == 0)
mapalloc(bbp);
dp->b_actf = bbp;
bbp->av_forw = bp;
bp = bbp;
#endif BADSECT
! }
#if NXPD > 1
/*
* If drive is offline, forget about positioning.
*/
! if ((xpaddr->hpds & (HPDS_DPR | HPDS_MOL)) != (HPDS_DPR | HPDS_MOL))
goto done;
/*
* Figure out where this transfer is going to
* and see if we are close enough to justify not searching.
--- 512,533 ----
bbp->b_un.b_addr = (caddr_t)&xpbad[unit];
bbp->b_blkno = (daddr_t)xd->xp_ncyl * xd->xp_nspc - xd->xp_nsect;
bbp->b_cylin = xd->xp_ncyl - 1;
! if (xd->xp_ctlr->xp_rh70 == 0)
mapalloc(bbp);
dp->b_actf = bbp;
bbp->av_forw = bp;
bp = bbp;
#endif BADSECT
!
#if NXPD > 1
/*
* If drive is offline, forget about positioning.
*/
! if (xpaddr->hpds & (HPDS_DREADY) != (HPDS_DREADY))
! {
! xd->xp_flags &= ~DKF_ONLINE;
goto done;
+ }
/*
* Figure out where this transfer is going to
* and see if we are close enough to justify not searching.
***************
*** 619,628 ****
sn += xd->xp_nsect - XP_SDIST;
sn %= xd->xp_nsect;
! if (((xd->xp_ctlr->xp_flags & XP_NOCC) && (xd->xp_cc != cn))
! || xpaddr->hpcc != cn)
goto search;
! if (xd->xp_ctlr->xp_flags & XP_NOSEARCH)
goto done;
csn = (xpaddr->hpla >> 6) - sn + XP_SDIST - 1;
if (csn < 0)
--- 538,547 ----
sn += xd->xp_nsect - XP_SDIST;
sn %= xd->xp_nsect;
! if ((!(xd->xp_dd0 & XP_CC) && (xd->xp_cc != cn))
! || xpaddr->hpcc != cn)
goto search;
! if (xd->xp_dd0 & XP_NOSEARCH)
goto done;
csn = (xpaddr->hpla >> 6) - sn + XP_SDIST - 1;
if (csn < 0)
***************
*** 632,638 ****
search:
xpaddr->hpdc = cn;
xpaddr->hpda = sn;
! xpaddr->hpcs1.c[0] = (xd->xp_ctlr->xp_flags & XP_NOSEARCH) ?
(HP_IE | HP_SEEK | HP_GO) : (HP_IE | HP_SEARCH | HP_GO);
xd->xp_cc = cn;
#ifdef UCB_METER
--- 551,557 ----
search:
xpaddr->hpdc = cn;
xpaddr->hpda = sn;
! xpaddr->hpcs1.c[0] = (xd->xp_dd0 & XP_NOSEARCH) ?
(HP_IE | HP_SEEK | HP_GO) : (HP_IE | HP_SEARCH | HP_GO);
xd->xp_cc = cn;
#ifdef UCB_METER
***************
*** 671,679 ****
register struct buf *bp;
struct xp_drive *xd;
struct buf *dp;
- short pseudo_unit;
daddr_t bn;
! int unit, sn, tn, cn;
xpaddr = xc->xp_addr;
loop:
--- 590,597 ----
register struct buf *bp;
struct xp_drive *xd;
struct buf *dp;
daddr_t bn;
! int unit, part, sn, tn, cn;
xpaddr = xc->xp_addr;
loop:
***************
*** 683,689 ****
--- 601,618 ----
if ((dp = xc->xp_actf) == NULL)
return;
if ((bp = dp->b_actf) == NULL) {
+ /*
+ * No more requests for this drive, remove from controller queue and
+ * look at next drive. We know we're at the head of the controller queue.
+ * The drive may not need anything, in which case it might be shutting
+ * down in xpclose() and a wakeup is done.
+ */
+ dp->b_active = 0;
xc->xp_actf = dp->b_forw;
+ unit = dp - xputab;
+ xd = &xp_drive[unit];
+ if (xd->xp_open == 0)
+ wakeup(dp); /* finish close protocol */
goto loop;
}
/*
***************
*** 690,701 ****
* Mark controller busy and determine destination of this request.
*/
xc->xp_active++;
! pseudo_unit = dkpart(bp->b_dev);
! unit = dkunit(bp->b_dev);
xd = &xp_drive[unit];
bn = bp->b_blkno;
! cn = xd->xp_sizes[pseudo_unit].cyloff;
! cn += bn / xd->xp_nspc;
sn = bn % xd->xp_nspc;
tn = sn / xd->xp_nsect;
sn = sn % xd->xp_nsect;
--- 619,629 ----
* Mark controller busy and determine destination of this request.
*/
xc->xp_active++;
! part = dkpart(bp->b_dev);
! unit = XPUNIT(bp->b_dev);
xd = &xp_drive[unit];
bn = bp->b_blkno;
! cn = (xd->xp_parts[part].p_offset + bn) / xd->xp_nspc;
sn = bn % xd->xp_nspc;
tn = sn / xd->xp_nsect;
sn = sn % xd->xp_nsect;
***************
*** 706,712 ****
/*
* Check that it is ready and online.
*/
! if ((xpaddr->hpds & (HPDS_DPR | HPDS_MOL)) != (HPDS_DPR | HPDS_MOL)) {
xc->xp_active = 0;
dp->b_errcnt = 0;
dp->b_actf = bp->av_forw;
--- 634,641 ----
/*
* Check that it is ready and online.
*/
! if ((xpaddr->hpds & HPDS_DREADY) != (HPDS_DREADY)) {
! xd->xp_flags &= ~DKF_ONLINE;
xc->xp_active = 0;
dp->b_errcnt = 0;
dp->b_actf = bp->av_forw;
***************
*** 714,719 ****
--- 643,650 ----
iodone(bp);
goto loop;
}
+ xd->xp_flags |= DKF_ONLINE;
+
if (dp->b_errcnt >= 16 && (bp->b_flags & B_READ)) {
xpaddr->hpof = xp_offset[dp->b_errcnt & 017] | HPOF_FMT22;
xpaddr->hpcs1.w = HP_OFFSET | HP_GO;
***************
*** 722,728 ****
xpaddr->hpdc = cn;
xpaddr->hpda = (tn << 8) + sn;
xpaddr->hpba = bp->b_un.b_addr;
! if (xc->xp_flags & XP_RH70)
xpaddr->hpbae = bp->b_xmem;
xpaddr->hpwc = -(bp->b_bcount >> 1);
/*
--- 653,659 ----
xpaddr->hpdc = cn;
xpaddr->hpda = (tn << 8) + sn;
xpaddr->hpba = bp->b_un.b_addr;
! if (xc->xp_rh70)
xpaddr->hpbae = bp->b_xmem;
xpaddr->hpwc = -(bp->b_bcount >> 1);
/*
***************
*** 784,790 ****
if (xpecc(bp, CONT))
return;
#endif
! unit = dkunit(bp->b_dev);
xd = &xp_drive[unit];
xpaddr->hpcs2.c[0] = xd->xp_unit;
/*
--- 715,721 ----
if (xpecc(bp, CONT))
return;
#endif
! unit = XPUNIT(bp->b_dev);
xd = &xp_drive[unit];
xpaddr->hpcs2.c[0] = xd->xp_unit;
/*
***************
*** 796,802 ****
/*
* Give up on write locked deviced immediately.
*/
! printf("xp%d: write locked\n", unit);
bp->b_flags |= B_ERROR;
#ifdef BADSECT
}
--- 727,733 ----
/*
* Give up on write locked deviced immediately.
*/
! log(LOG_NOTICE, "xp%d: write locked\n", unit);
bp->b_flags |= B_ERROR;
#ifdef BADSECT
}
***************
*** 823,836 ****
if (++dp->b_errcnt > 28) {
hard:
harderr(bp, "xp");
! #ifdef XP_DEBUG
! /*
! * for RM drives
! */
! printf("cs2=%b er1=%b er2=%b\n",xpaddr->hpcs2.w, HPCS2_BITS, xpaddr->hper1, HPER1_BITS, xpaddr->rmer2, RMER2_BITS);
! #else
! printf("cs2=%b er1=%b\n", xpaddr->hpcs2.w, HPCS2_BITS, xpaddr->hper1, HPER1_BITS);
! #endif
bp->b_flags |= B_ERROR;
}
else
--- 754,763 ----
if (++dp->b_errcnt > 28) {
hard:
harderr(bp, "xp");
! log(LOG_NOTICE,"cs2=%b er1=%b er2=%b\n",
! xpaddr->hpcs2.w, HPCS2_BITS,
! xpaddr->hper1, HPER1_BITS,
! xpaddr->rmer2, RMER2_BITS);
bp->b_flags |= B_ERROR;
}
else
***************
*** 892,897 ****
--- 819,825 ----
*/
xpecc(bp, flag)
register struct buf *bp;
+ int flag;
{
register struct xp_drive *xd;
register struct hpdevice *xpaddr;
***************
*** 910,916 ****
* ndone is #bytes including the error which is assumed to be in the
* last disk page transferred.
*/
! unit = dkunit(bp->b_dev);
xd = &xp_drive[unit];
xpaddr = xd->xp_ctlr->xp_addr;
#ifdef BADSECT
--- 838,844 ----
* ndone is #bytes including the error which is assumed to be in the
* last disk page transferred.
*/
! unit = XPUNIT(bp->b_dev);
xd = &xp_drive[unit];
xpaddr = xd->xp_ctlr->xp_addr;
#ifdef BADSECT
***************
*** 940,946 ****
sn %= xd->xp_nsect;
switch (flag) {
case ECC:
! printf("xp%d%c: soft ecc sn%D\n",unit, 'a' + (minor(bp->b_dev) & 07), bp->b_blkno + (npx - 1));
wrong = xpaddr->hpec2;
if (wrong == 0) {
xpaddr->hpof = HPOF_FMT22;
--- 868,876 ----
sn %= xd->xp_nsect;
switch (flag) {
case ECC:
! log(LOG_NOTICE, "xp%d%c: soft ecc sn%D\n",
! unit, 'a' + dkpart(bp->b_dev),
! bp->b_blkno + (npx - 1));
wrong = xpaddr->hpec2;
if (wrong == 0) {
xpaddr->hpof = HPOF_FMT22;
***************
*** 988,1003 ****
tn = sn;
tn /= xd->xp_nsect;
sn %= xd->xp_nsect;
! #ifdef DEBUG
! printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
! #endif
wc = -(512 / (int)NBPW);
break;
case CONT:
bp->b_flags &= ~B_BAD;
! #ifdef DEBUG
! printf("xpecc CONT: bn %D cn %d tn %d sn %d\n", bn, cn, tn, sn);
! #endif
break;
#endif BADSECT
}
--- 918,931 ----
tn = sn;
tn /= xd->xp_nsect;
sn %= xd->xp_nsect;
! log(LOG_NOTICE, "revector to cn %d tn %d sn %d\n",
! cn, tn, sn);
wc = -(512 / (int)NBPW);
break;
case CONT:
bp->b_flags &= ~B_BAD;
! log(LOG_NOTICE, "xpecc CONT: bn %D cn %d tn %d sn %d\n",
! bn, cn, tn, sn);
break;
#endif BADSECT
}
***************
*** 1017,1028 ****
xpaddr->hpda = (tn << 8) + sn;
xpaddr->hpwc = wc;
xpaddr->hpba = (caddr_t)addr;
! if (xd->xp_ctlr->xp_flags & XP_RH70)
xpaddr->hpbae = (int)(addr >> 16);
xpaddr->hpcs1.w = ocmd;
return (1);
}
#ifdef XP_DUMP
/*
* Dump routine. Dumps from dumplo to end of memory/end of disk section for
--- 945,969 ----
xpaddr->hpda = (tn << 8) + sn;
xpaddr->hpwc = wc;
xpaddr->hpba = (caddr_t)addr;
! if (xd->xp_ctlr->xp_rh70)
xpaddr->hpbae = (int)(addr >> 16);
xpaddr->hpcs1.w = ocmd;
return (1);
}
+ xpioctl(dev, cmd, data, flag)
+ dev_t dev;
+ int cmd;
+ caddr_t data;
+ int flag;
+ {
+ register int error;
+ struct dkdevice *disk = &xp_drive[XPUNIT(dev)].xp_dk;
+
+ error = ioctldisklabel(dev, cmd, data, flag, disk, xpstrategy);
+ return(error);
+ }
+
#ifdef XP_DUMP
/*
* Dump routine. Dumps from dumplo to end of memory/end of disk section for
***************
*** 1032,1120 ****
xpdump(dev)
dev_t dev;
! {
! /*
! * ONLY USE 2 REGISTER VARIABLES, OR C COMPILER CHOKES
! */
! register struct xp_drive *xd;
register struct hpdevice *xpaddr;
daddr_t bn, dumpsize;
! long paddr;
! int sn, count;
! struct ubmap *ubp;
! if ((bdevsw[major(dev)].d_strategy != xpstrategy) /* paranoia */
! || ((dev=minor(dev)) > (NXPD << 3)))
return(EINVAL);
! xd = &xp_drive[xpunit(dev)];
! dev &= 07;
! if (xd->xp_ctlr == 0)
! return(EINVAL);
xpaddr = xd->xp_ctlr->xp_addr;
! dumpsize = xd->xp_sizes[dev].nblocks;
! if ((dumplo < 0) || (dumplo >= dumpsize))
return(EINVAL);
! dumpsize -= dumplo;
xpaddr->hpcs2.w = xd->xp_unit;
! if ((xpaddr->hpds & HPDS_VV) == 0) {
xpaddr->hpcs1.w = HP_DCLR | HP_GO;
xpaddr->hpcs1.w = HP_PRESET | HP_GO;
xpaddr->hpof = HPOF_FMT22;
! }
! if ((xpaddr->hpds & (HPDS_DPR | HPDS_MOL)) != (HPDS_DPR | HPDS_MOL))
return(EFAULT);
ubp = &UBMAP[0];
! for (paddr = 0L; dumpsize > 0; dumpsize -= count) {
! count = dumpsize>DBSIZE? DBSIZE: dumpsize;
! bn = dumplo + (paddr >> PGSHIFT);
! xpaddr->hpdc = bn / xd->xp_nspc + xd->xp_sizes[dev].cyloff;
sn = bn % xd->xp_nspc;
xpaddr->hpda = ((sn / xd->xp_nsect) << 8) | (sn % xd->xp_nsect);
xpaddr->hpwc = -(count << (PGSHIFT - 1));
xpaddr->hper1 = 0;
xpaddr->hper3 = 0;
! if (ubmap && ((xd->xp_ctlr->xp_flags & XP_RH70) == 0)) {
ubp->ub_lo = loint(paddr);
ubp->ub_hi = hiint(paddr);
xpaddr->hpba = 0;
xpaddr->hpcs1.w = HP_WCOM | HP_GO;
! }
! else {
/*
* Non-UNIBUS map, or 11/70 RH70 (MASSBUS)
*/
! xpaddr->hpba = loint(paddr);
! if (xd->xp_ctlr->xp_flags & XP_RH70)
xpaddr->hpbae = hiint(paddr);
xpaddr->hpcs1.w = HP_WCOM | HP_GO | ((paddr >> 8) & (03 << 8));
! }
/* Emulex controller emulating two RM03's needs a delay */
delay(50000L);
! while (xpaddr->hpcs1.w & HP_GO)
continue;
! if (xpaddr->hpcs1.w & HP_TRE) {
! if (xpaddr->hpcs2.w & HPCS2_NEM)
! return(0); /* made it to end of memory */
return(EIO);
- }
paddr += (DBSIZE << PGSHIFT);
! }
! return(0); /* filled disk minor dev */
}
#endif XP_DUMP
/*
! * By this time either the slaves have been "probed" for or the drive
! * information was statically initialized - either way the lookup of
! * partition size is straightforward.
*/
daddr_t
xpsize(dev)
! register dev_t dev;
{
register struct xp_drive *xd;
! xd = &xp_drive[xpunit(dev)];
! return(xd->xp_sizes[dev & 7].nblocks);
}
! #endif NXPD
--- 973,1087 ----
xpdump(dev)
dev_t dev;
! {
! struct xp_drive *xd;
register struct hpdevice *xpaddr;
+ struct partition *pi;
daddr_t bn, dumpsize;
! long paddr;
! int sn, count, memblks, unit;
! register struct ubmap *ubp;
! unit = XPUNIT(dev);
! xd = &xp_drive[unit];
!
! if (unit > NXPD || xd->xp_ctlr == 0)
return(EINVAL);
! if (!(xd->xp_flags & DKF_ALIVE))
! return(ENXIO);
! if (pi->p_fstype != FS_SWAP)
! return(EFTYPE);
!
! pi = &xd->xp_parts[dkpart(dev)];
xpaddr = xd->xp_ctlr->xp_addr;
!
! dumpsize = xpsize(dev) - dumplo;
! memblks = ctod(physmem);
!
! if (dumplo < 0 || dumpsize <= 0)
return(EINVAL);
! if (memblks > dumpsize)
! memblks = dumpsize;
! bn = dumplo + pi->p_offset;
!
xpaddr->hpcs2.w = xd->xp_unit;
! if ((xpaddr->hpds & HPDS_VV) == 0)
! {
xpaddr->hpcs1.w = HP_DCLR | HP_GO;
xpaddr->hpcs1.w = HP_PRESET | HP_GO;
xpaddr->hpof = HPOF_FMT22;
! }
! if ((xpaddr->hpds & HPDS_DREADY) != (HPDS_DREADY))
return(EFAULT);
ubp = &UBMAP[0];
! for (paddr = 0L; memblks > 0; )
! {
! count = MIN(memblks, DBSIZE);
! xpaddr->hpdc = bn / xd->xp_nspc;
sn = bn % xd->xp_nspc;
xpaddr->hpda = ((sn / xd->xp_nsect) << 8) | (sn % xd->xp_nsect);
xpaddr->hpwc = -(count << (PGSHIFT - 1));
xpaddr->hper1 = 0;
xpaddr->hper3 = 0;
! if (ubmap && (xd->xp_ctlr->xp_rh70 == 0))
! {
ubp->ub_lo = loint(paddr);
ubp->ub_hi = hiint(paddr);
xpaddr->hpba = 0;
xpaddr->hpcs1.w = HP_WCOM | HP_GO;
! }
! else
! {
/*
* Non-UNIBUS map, or 11/70 RH70 (MASSBUS)
*/
! xpaddr->hpba = (caddr_t)loint(paddr);
! if (xd->xp_ctlr->xp_rh70)
xpaddr->hpbae = hiint(paddr);
xpaddr->hpcs1.w = HP_WCOM | HP_GO | ((paddr >> 8) & (03 << 8));
! }
/* Emulex controller emulating two RM03's needs a delay */
delay(50000L);
! while (xpaddr->hpcs1.w & HP_GO)
continue;
! if (xpaddr->hpcs1.w & HP_TRE)
return(EIO);
paddr += (DBSIZE << PGSHIFT);
! bn += count;
! memblks -= count;
! }
! return(0);
}
#endif XP_DUMP
/*
! * Return the number of blocks in a partition. Call xpopen() to read the
! * label if necessary. If an open is necessary then a matching close
! * will be done.
*/
daddr_t
xpsize(dev)
! register dev_t dev;
{
register struct xp_drive *xd;
+ daddr_t psize;
+ int didopen = 0;
! xd = &xp_drive[XPUNIT(dev)];
! /*
! * This should never happen but if we get called early in the kernel's
! * life (before opening the swap or root devices) then we have to do
! * the open here.
! */
! if (xd->xp_open == 0)
! {
! if (xpopen(dev, FREAD|FWRITE, S_IFBLK))
! return(-1);
! didopen = 1;
! }
! psize = xd->xp_parts[dkpart(dev)].p_size;
! if (didopen)
! xpclose(dev, FREAD|FWRITE, S_IFBLK);
! return(psize);
}
! #endif /* NXPD */
*** /usr/src/sys/conf/config.old Tue Feb 28 20:10:03 1995
--- /usr/src/sys/conf/config Fri Jul 21 20:55:37 1995
***************
*** 1,6 ****
--- 1,9 ----
#! /bin/sh
# 2.11BSD script to set up a new kernel configuration directory.
#
+ # 1995/07/21 - remove XP_PROBE, the kernel no longer probes for disk
+ # type because that information is obtained from the
+ # disklabel.
# 2/28/95 - fixed errors introduced earlier. remove the chmod at the
# end, rely instead on the system administrator's choice of
# umask.
***************
*** 237,245 ****
echo "#define NXPC $NXPC" >> ../$MACHINE/xp.h
if [ $DUMPROUTINE = xpdump ]; then
echo "#define XP_DUMP 1" >> ../$MACHINE/xp.h
- fi
- if [ $XP_PROBE = YES ]; then
- echo "#define XP_PROBE 1" >> ../$MACHINE/xp.h
fi
echo "Creating Makefile for $MACHINE".
--- 240,245 ----
*** /usr/src/sys/conf/GENERIC.old Tue Feb 14 20:41:01 1995
--- /usr/src/sys/conf/GENERIC Fri Jul 21 20:52:39 1995
***************
*** 1,3 ****
--- 1,5 ----
+ # 1995/07/21 - XP_PROBE removed.
+ #
# Machine configuration file for 2.11BSD distributed kernel.
#
# Format:
***************
*** 145,158 ****
NSI 0 # SI 9500 driver for CDC 9766 disks
- # Because the disk drive type registers conflict with other DEC
- # controllers, you cannot use XP_PROBE for the Ampex 9300 and
- # Diva drives. Read through /sys/pdpuba/hpreg.h and /sys/pdpuba/xp.c
- # for information on how to initialize for these drives.
NXPC 1 # NXPD controllers (RH70/RH11 style)
NXPD 2 # RM02/03/05, RP04/05/06, CDC 9766,
# Ampex 9300, Diva, Fuji 160, SI Eagle.
- XP_PROBE YES # check drive types at boot
NRAM 0 # RAM disk size (512-byte blocks)
--- 147,155 ----
*** /usr/src/sys/pdp/conf.c.old Mon Jun 19 20:36:34 1995
--- /usr/src/sys/pdp/conf.c Mon Jul 24 21:46:47 1995
***************
*** 3,9 ****
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)conf.c 2.7 (2.11BSD GTE) 1995/06/19
*/
#include "param.h"
--- 3,9 ----
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)conf.c 2.8 (2.11BSD GTE) 1995/07/24
*/
#include "param.h"
***************
*** 58,69 ****
#include "xp.h"
#if NXPD > 0
! int xpopen(), xpstrategy(), xproot();
daddr_t xpsize();
- #define xpclose nulldev
#else
#define xpopen nodev
#define xpclose nodev
#define xproot nulldev
#define xpstrategy nodev
#define xpsize NULL
--- 58,69 ----
#include "xp.h"
#if NXPD > 0
! int xpopen(), xpstrategy(), xproot(), xpclose(), xpioctl();
daddr_t xpsize();
#else
#define xpopen nodev
#define xpclose nodev
+ #define xpioctl nodev
#define xproot nulldev
#define xpstrategy nodev
#define xpsize NULL
***************
*** 431,437 ****
sistrategy,
/* xp = 19 */
xpopen, xpclose, rawrw, rawrw,
! nodev, nulldev, 0, seltrue,
xpstrategy,
/* br = 20 */
bropen, brclose, rawrw, rawrw,
--- 431,437 ----
sistrategy,
/* xp = 19 */
xpopen, xpclose, rawrw, rawrw,
! xpioctl, nulldev, 0, seltrue,
xpstrategy,
/* br = 20 */
bropen, brclose, rawrw, rawrw,
*** /usr/src/sys/pdpstand/xp.c.old Thu Jun 8 19:38:21 1995
--- /usr/src/sys/pdpstand/xp.c Tue Aug 1 22:51:44 1995
***************
*** 3,9 ****
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)xp.c 2.1 (2.11BSD) 1995/06/08
*/
/*
--- 3,9 ----
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)xp.c 2.2 (2.11BSD) 1995/08/01
*/
/*
***************
*** 23,117 ****
(struct hpdevice *)-1
};
/*
! * Drive type; declared so we can patch; see hpreg.h for more information.
! */
! int xptype[NXP] = 0;
xpstrategy(io, func)
register struct iob *io;
{
- int unit = io->i_unit;
- int ctlr = io->i_ctlr;
int i;
- register nm_sect_per_cyl, nsect;
daddr_t bn;
int sn, cn, tn, bae, lo16;
! struct hpdevice *xpaddr = XPcsr[ctlr];
bn = io->i_bn;
! /*
! * The weirdness involving bit 2 (04) in the unit # was removed
! * because 1) the xp driver in the kernel didn't know about it,
! * 2) no mention was made in any .h file or documentation/notes
! */
! xpaddr->hpcs2.w = unit;
if ((xpaddr->hpds & HPDS_VV) == 0) {
xpaddr->hpcs1.c[0] = HP_PRESET|HP_GO;
xpaddr->hpof = HPOF_FMT22;
}
! /*
! * The weirdness of (possibly) looking at the console switch
! * register to tell what type of disk we have here was removed
! * because 1) most systems do not have one, 2) space contraints
! * imposed by adding multi controller support were creating a
! * size problem, and 3) an alternative method is provided for
! * setting the type (the address and content is printed).
! */
!
! if (xptype[ctlr] == 0) {
! xptype[ctlr] = (xpaddr->hpdt & 077);
! printf("\n&xptype=0%o xptype[%d]=0%o\n", xptype, ctlr,
! xptype[ctlr]);
! }
- switch (xptype[ctlr]) {
- case RP04:
- case RP05:
- case RP06:
- nm_sect_per_cyl = HP_SECT * HP_TRAC;
- nsect = HP_SECT;
- break;
- case RM02:
- case RM03:
- nm_sect_per_cyl = RM_SECT * RM_TRAC;
- nsect = RM_SECT;
- break;
- case RM05:
- case RM5X:
- nm_sect_per_cyl = RM5_SECT * RM5_TRAC;
- nsect = RM5_SECT;
- break;
- case CAP:
- nm_sect_per_cyl = CAP_SECT * CAP_TRAC;
- nsect = CAP_SECT;
- break;
- case SI5:
- nm_sect_per_cyl = SI5_SECT * SI5_TRAC;
- nsect = SI5_SECT;
- break;
- case SI:
- nm_sect_per_cyl = SI_SECT * SI_TRAC;
- nsect = SI_SECT;
- break;
- case RM2X:
- nm_sect_per_cyl = RM2X_SECT * RM2X_TRAC;
- nsect = RM2X_SECT;
- break;
- case DV:
- nm_sect_per_cyl = DV_SECT * DV_TRAC;
- nsect = DV_SECT;
- break;
- default:
- printf("xp%d: unknown type 0%o\n", ctlr, xptype[ctlr]);
- return(-1);
- }
- cn = bn/(nm_sect_per_cyl);
- sn = bn%(nm_sect_per_cyl);
- tn = sn/nsect;
- sn = sn%nsect;
-
iomapadr(io->i_ma, &bae, &lo16);
xpaddr->hpdc = cn;
xpaddr->hpda = (tn << 8) + sn;
--- 23,93 ----
(struct hpdevice *)-1
};
+ static char xpinit[NXP][8]; /* XXX */
+
+ xpopen(io)
+ register struct iob *io;
+ {
+ register struct disklabel *lp = &io->i_label;
+ register struct hpdevice *xpaddr;
+ int dummy;
+
+ if (genopen(NXP, io) < 0)
+ return(-1);
/*
! * If this is the first access for the drive check to see if it is
! * present. If the drive is present then read the label.
! */
! if (xpinit[io->i_ctlr][io->i_unit] == 0)
! {
! xpaddr = XPcsr[io->i_ctlr];
! xpaddr->hpcs1.w = HP_NOP;
! xpaddr->hpcs2.w = io->i_unit;
! xpaddr->hpcs1.w = HP_GO;
! delay(6000);
! dummy = xpaddr->hpds;
! if (xpaddr->hpcs2.w & HPCS2_NED)
! {
! xpaddr->hpcs2.w = HPCS2_CLR;
! return(-1);
! }
! if (devlabel(io, READLABEL) == -1)
! return(-1);
! xpinit[io->i_ctlr][io->i_unit] = 1;
! }
! io->i_boff = lp->d_partitions[io->i_part].p_offset;
! return(0);
! }
+ xpclose(io)
+ struct iob *io;
+ {
+
+ xpinit[io->i_ctlr][io->i_unit] = 0;
+ return(0);
+ }
+
xpstrategy(io, func)
register struct iob *io;
{
int i;
daddr_t bn;
int sn, cn, tn, bae, lo16;
! register struct hpdevice *xpaddr = XPcsr[io->i_ctlr];
! register struct disklabel *lp = &io->i_label;
bn = io->i_bn;
! xpaddr->hpcs2.w = io->i_unit;
if ((xpaddr->hpds & HPDS_VV) == 0) {
xpaddr->hpcs1.c[0] = HP_PRESET|HP_GO;
xpaddr->hpof = HPOF_FMT22;
}
! cn = bn / lp->d_secpercyl;
! sn = bn % lp->d_secpercyl;
! tn = sn / lp->d_nsectors;
! sn = sn % lp->d_nsectors;
iomapadr(io->i_ma, &bae, &lo16);
xpaddr->hpdc = cn;
xpaddr->hpda = (tn << 8) + sn;
***************
*** 127,140 ****
continue;
if (xpaddr->hpcs1.w & HP_TRE) {
printf("xp%d,%d err cy=%d tr=%d sc=%d cs2=%o er1=%o\n",
! ctlr, unit, cn, tn, sn, xpaddr->hpcs2, xpaddr->hper1);
return(-1);
}
return(io->i_cc);
}
! xpopen(io)
struct iob *io;
! {
! return(genopen(NXP, io));
! }
--- 103,280 ----
continue;
if (xpaddr->hpcs1.w & HP_TRE) {
printf("xp%d,%d err cy=%d tr=%d sc=%d cs2=%o er1=%o\n",
! io->i_ctlr, io->i_unit, cn, tn, sn, xpaddr->hpcs2,
! xpaddr->hper1);
return(-1);
}
return(io->i_cc);
}
! /*
! * ALL drive type identification has been removed from the kernel's XP
! * driver and placed here.
! *
! * These tables are used to provide "the best guess" of the geometry
! * of the drive. DEC RP0{4,5,6,7} and RM0{3,5} drives will match exactly.
! * Non DEC controllers (performing an emulation) often use the DEC drive
! * type to mean completely different geometry/capacity drives.
! */
!
! struct xpst
! {
! int flags; /* flags: XP_CC, XP_NOSEARCH */
! int ncyl; /* number of cylinders */
! int nspc; /* number of sectors per cylinder */
! int ntpc; /* number of tracks per cylinder */
! int nspt; /* number of sectors per track */
! daddr_t nspd; /* number of sectors per drive */
! };
!
! static struct xpst rp04_st = { XP_CC, 411, 22 * 19, 19, 22, 411L * 22 * 19 };
! /* rp05 uses same table as rp04 */
! static struct xpst rp06_st = { XP_CC, 815, 22 * 19, 19, 22, 815L * 22 * 19 };
! static struct xpst rp07_st = { XP_CC, 630, 50 * 32, 32, 50, 630L * 50 * 32 };
!
! static struct xpst rm02_st; /* filled in dynamically */
! static struct xpst rm03_st = { 0, 823, 32 * 5, 5, 32, 823L * 32 * 5 };
! static struct xpst rm05_st = { 0, 823, 32 * 19, 19, 32, 823L * 32 * 19 };
! static struct xpst rm80_st = { 0, 559, 31 * 14, 14, 31, 559L * 31 * 14 };
!
! /*
! * SI controller stuff - likely not used any longer and will probably go away
! * eventually (when the D space is needed for something more important).
! */
!
! static struct xpst cdc9775_st = { 0, 843, 32 * 40, 40, 32, 843L * 32 * 40 };
! static struct xpst cdc9730_st = { 0, 823, 32 * 10, 10, 32, 823L * 32 * 10 };
! static struct xpst cdc9766_st = { 0, 823, 32 * 19, 19, 32, 823L * 32 * 19 };
! static struct xpst cdc9762_st = { 0, 823, 32 * 5, 5, 32, 823L * 32 * 5 };
! static struct xpst capric_st = { 0, 1024, 32 * 16, 16, 32, 1024L * 32 * 16 };
! static struct xpst eagle_st = { 0, 842, 48 * 20, 20, 48, 842L * 48 * 20 };
!
! /*
! * A "default". If none of the above are useable then a default geometry
! * suitable for writing a label (sector 1) is used.
! */
!
! static struct xpst default_st = { 0, 1, 2 * 1, 1, 2, 2 };
!
! /*
! * This routine does not return an error (-1). If the drive is totally
! * unrecognizeable then the default above is used.
! */
!
! xplabel(io)
struct iob *io;
! {
! register struct xpst *st = NULL;
! int type, xpsn;
! register struct hpdevice *xpaddr = XPcsr[io->i_ctlr];
! register struct disklabel *lp;
!
! type = xpaddr->hpdt & 077;
! switch (type)
! {
! case HPDT_RP04: /* 020 */
! case HPDT_RP05: /* 021 */
! st = &rp04_st;
! break;
! case HPDT_RP06: /* 022 */
! st = &rp06_st;
! break;
! case HPDT_RP07: /* 042 */
! st = &rp07_st;
! break;
! case HPDT_RM80: /* 026 */
! st = &rm80_st;
! break;
! case HPDT_RM05: /* 027 */
! st = &rm05_st;
! break;
! case HPDT_RM03: /* 024 */
! st = &rm03_st;
! break;
! case HPDT_RM02: /* 025 */
! /*
! * Borrowing a quote from 4BSD:
! * "We know this isn't a dec controller, so we can assume sanity."
! */
! st = &rm02_st;
! xpaddr->hpcs1.w = HP_NOP;
! xpaddr->hpcs2.w = io->i_unit;
!
! xpaddr->rmhr = HPHR_MAXTRAK;
! st->ntpc = xpaddr->rmhr + 1;
!
! xpaddr->rmhr = HPHR_MAXSECT;
! st->nspt = xpaddr->rmhr + 1;
!
! xpaddr->rmhr = HPHR_MAXCYL;
! st->ncyl = xpaddr->rmhr + 1;
!
! xpaddr->hpcs1.w = HP_DCLR | HP_GO;
!
! st->nspc = st->nspt * st->ntpc;
! st->nspd = (long)st->nspc * st->ncyl;
! printf("type: RM02 c=%d t/c=%d s/t=%d\n", st->ncyl,
! st->ntpc, st->nspt);
! break;
! default:
! printf("xp%d,%d unknown drive type: %d -- ",
! io->i_ctlr, io->i_unit, type);
! printf("using 1 cyl, 1 trk, 2 sec/trk\n");
! st = &default_st;
! break;
! }
!
! /*
! * Handle SI model byte stuff when we think it's an RM05 or RM03. Is any
! * one still using one of these? Is it worth all this code?
! */
! if (type == HPDT_RM05 || type == HPDT_RM03)
! {
! xpsn = xpaddr->hpsn;
! if ((xpsn & SIMB_LU) != io->i_unit)
! goto notsi;
! switch ((xpsn & SIMB_MB) &~ (SIMB_S6|SIRM03|SIRM05))
! {
! case SI9775D:
! st = &cdc9775_st;
! break;
! case SI9730D:
! st = &cdc9730_st;
! break;
! case SI9766:
! st = &cdc9766_st;
! break;
! case SI9762:
! st = &cdc9762_st;
! break;
! case SICAPD:
! st = &capric_st;
! break;
! case SI9751D:
! st = &eagle_st;
! break;
! default:
! printf("xp%d,%d unknown SI drive model %d -- ",
! io->i_ctlr, io->i_unit, xpsn);
! printf("using 1 cyl, 1 trk, 2 sec/trk\n");
! st = &default_st;
! break;
! }
! }
! notsi:
! lp = &io->i_label;
! lp->d_type = DTYPE_SMD;
! lp->d_secsize = 512; /* XXX */
! lp->d_secperunit = st->nspd;
! lp->d_partitions[0].p_size = st->nspd;
! lp->d_nsectors = st->nspt;
! lp->d_ntracks = st->ntpc;
! lp->d_secpercyl = st->nspc;
! lp->d_ncylinders = st->ncyl;
! lp->d_drivedata[0] = st->flags;
! strcpy(lp->d_typename, "SMD");
! return(0);
! }
*** /usr/src/sys/pdpstand/conf.c.old Thu Jun 15 20:09:14 1995
--- /usr/src/sys/pdpstand/conf.c Mon Jul 17 21:43:26 1995
***************
*** 3,9 ****
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)conf.c 2.3 (2.11BSD) 1995/06/15
*/
#include "../h/param.h"
--- 3,9 ----
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)conf.c 2.4 (2.11BSD) 1995/07/17
*/
#include "../h/param.h"
***************
*** 11,17 ****
int nullsys();
! extern int xpstrategy(), xpopen();
extern int brstrategy(), bropen();
extern int rkstrategy(), rkopen();
extern int hkstrategy(), hkopen();
--- 11,17 ----
int nullsys();
! extern int xpstrategy(), xpopen(), xpclose(), xplabel();
extern int brstrategy(), bropen();
extern int rkstrategy(), rkopen();
extern int hkstrategy(), hkopen();
***************
*** 52,59 ****
nullsys, nullsys,
"si", sistrategy, siopen, nullsys, SIcsr, /* 9 */
nullsys, nullsys,
! "xp", xpstrategy, xpopen, nullsys, XPcsr, /* 10 */
! nullsys, nullsys,
"br", brstrategy, bropen, nullsys, BRcsr, /* 11 */
nullsys, nullsys,
"tms", tmscpstrategy, tmscpopen, tmscpclose, TMScsr,/* 12 */
--- 52,59 ----
nullsys, nullsys,
"si", sistrategy, siopen, nullsys, SIcsr, /* 9 */
nullsys, nullsys,
! "xp", xpstrategy, xpopen, xpclose, XPcsr, /* 10 */
! xplabel, nullsys,
"br", brstrategy, bropen, nullsys, BRcsr, /* 11 */
nullsys, nullsys,
"tms", tmscpstrategy, tmscpopen, tmscpclose, TMScsr,/* 12 */
*** /usr/src/sys/pdpdist/disktab.old Thu Jul 13 19:36:39 1995
--- /usr/src/sys/pdpdist/disktab Fri Aug 18 21:56:07 1995
***************
*** 129,140 ****
:b0=/mdec/si94uboot:\
:pa#9600:oa#0:ba#1024:fa#1024:ta=2.11BSD:\
:pb#9600:ob#9600:bb#1024:fb#1024:tb=swap:\
! :pc#244002:oc#19200:bc#1024:fc#1024:tc=2.11BSD:\
! :pd#164800:od#19200:bd#1024:fd#1024:td=2.11BSD:\
! :pe#79360:oe#184000:be#1024:fe#1024:te=2.11BSD:\
! :pf#39680:of#184000:bf#1024:ff#1024:tf=2.11BSD:\
! :pg#39680:og#223680:bg#1024:fg#1024:tg=2.11BSD:\
! :ph#263202:bh#1024:fh#1024:th=2.11BSD
diva|DIVA|9300|Diva Comp V, Ampex 9300 (in direct mode):\
:ty=fixed:ns#33:nt#19:nc#815:sf:\
--- 129,140 ----
:b0=/mdec/si94uboot:\
:pa#9600:oa#0:ba#1024:fa#1024:ta=2.11BSD:\
:pb#9600:ob#9600:bb#1024:fb#1024:tb=swap:\
! :pc#244160:oc#19200:bc#1024:fc#1024:tc=2.11BSD:\
! :pd#164800:od#19200:bd#1024:fd#1024:td=unused:\
! :pe#79360:oe#184000:be#1024:fe#1024:te=unused:\
! :pf#39680:of#184000:bf#1024:ff#1024:tf=unused:\
! :pg#39680:og#223680:bg#1024:fg#1024:tg=unused:\
! :ph#263360:oh#0:bh#1024:fh#1024:th=unused
diva|DIVA|9300|Diva Comp V, Ampex 9300 (in direct mode):\
:ty=fixed:ns#33:nt#19:nc#815:sf:\
*** /usr/src/man/man4/xp.4.old Wed Dec 30 14:58:00 1992
--- /usr/src/man/man4/xp.4 Tue Aug 15 20:28:30 1995
***************
*** 2,10 ****
.\" All rights reserved. The Berkeley software License Agreement
.\" specifies the terms and conditions for redistribution.
.\"
! .\" @(#)xp.4 6.3 (2.11BSD GTE) 12/30/92
.\"
! .TH XP 4 "September 7, 1988"
.UC 2
.SH NAME
xp \- generic SMD moving-head disk
--- 2,10 ----
.\" All rights reserved. The Berkeley software License Agreement
.\" specifies the terms and conditions for redistribution.
.\"
! .\" @(#)xp.4 6.4 (2.11BSD GTE) 1995/08/14
.\"
! .TH XP 4 "August 14, 1995"
.UC 2
.SH NAME
xp \- generic SMD moving-head disk
***************
*** 12,26 ****
.ft B
.nf
/sys/conf/SYSTEM:
! .ta .5i +\w'XP_PROBE 'u +\w'xp_controllers 'u
! # Because the disk drive type registers conflict with other DEC
! # controllers, you cannot use XP_PROBE for the Ampex 9300 and
! # Diva drives. Read through /sys/pdpuba/hpreg.h and /sys/pdpuba/xp.c
! # for information on how to initialize for these drives.
! NXPC \fIxp_controllers\fP # NXPD controllers (RH70/RH11 style)
! NXPD \fIxp_drives\fP # RM02/03/05, RP04/05/06, CDC 9766,
! # Ampex 9300, Diva, Fuji 160, SI Eagle.
! XP_PROBE \fIYES\fP # check drive types at boot
.DT
/etc/dtab:
--- 12,22 ----
.ft B
.nf
/sys/conf/SYSTEM:
! .ta .5i +\w'BADSECT 'u +\w'xp_controllers 'u
! NXPC \fIxp_controllers\fP # Number of controllers
! NXPD \fIxp_drives\fP # RM02/03/05, RP04/05/06,
! # CDC 9766, Fuji 160, etc.
! BADSECT \fINO\fP # Bad sector handling (see BUGS)
.DT
/etc/dtab:
***************
*** 34,40 ****
block: 10
minor device encoding:
bits 0007 specify partition of XP drive
! bits 0070 specify XP drive
.fi
.ft R
.SH DESCRIPTION
--- 30,36 ----
block: 10
minor device encoding:
bits 0007 specify partition of XP drive
! bits 0370 specify XP drive
.fi
.ft R
.SH DESCRIPTION
***************
*** 41,48 ****
The
.I xp
driver is a generic SMD storage module disk driver. It can be adapted to
! most SMD controllers (although bootstrapping will not necessarily be
! directly possible.) The drives are numbered from 0 to
.I n
on
controller 0, from
--- 37,44 ----
The
.I xp
driver is a generic SMD storage module disk driver. It can be adapted to
! most SMD controllers although bootstrapping will not necessarily be
! directly possible. The drives are numbered from 0 to
.I n
on
controller 0, from
***************
*** 49,56 ****
.IR n +1
to
.I m
! on controller 1, etc. The drives may have different geometries.
.PP
Files with minor device numbers 0 through 7 refer to various portions
of drive 0;
minor devices 8 through 15 refer to drive 1, etc.
--- 45,61 ----
.IR n +1
to
.I m
! on controller 1, etc. The drives may have different geometries.
.PP
+ The \fIxp\fP
+ driver is unique amoungst 2BSD drivers in its numbering of drives.
+ Other drivers (\fIra\fP for example) number drives 0 thru 7 on controller
+ 1, 8 thru 15 on controller 2 and so on. \fIxp\fP on the other hand can
+ have drives 0 and 1 on controller 1, drives 2, 3, 4 and 5 on controller 2 and
+ drives 6, 7 and 8 on controller 3. This is different from \fBboot\fP's
+ view of the world, so if you are booting from other than unit 0 you may
+ have to experiment a bit.
+ .PP
Files with minor device numbers 0 through 7 refer to various portions
of drive 0;
minor devices 8 through 15 refer to drive 1, etc.
***************
*** 71,218 ****
In raw I/O the buffer must begin on a word (even) boundary,
and counts should be a multiple of 512 bytes (a disk sector).
Likewise
! .I seek
calls should specify a multiple of 512 bytes.
.SH "DISK SUPPORT"
! If the option
! .B XP_PROBE
! is selected the driver interrogates the controller's drive type register
! to determine the type of drive attached. The driver recognizes the
! following drives automatically: RM02/03/05 (the CDC 9766 is recognized
! as an RM05), SI 9775, RP04/05/06, Fuji 160, Capricorn and SI Eagle. The
! following drives are also supported, but must either be patched at boot
! time or initialized at compile time: Ampex 9300 in direct mode and DIVA
! Comp V.
.PP
- The origin and size (in sectors) of the pseudo-disks on each drive are as
- follows:
- .nf
- .ta .5i +\w'disk 'u +\w'0000000 'u +\w'0000000 'u +\w'000 - 0000 'u
- .PP
- .ne 10
- RP04/05 partitions:
- disk start length cyls comments
- xp?a 0 9614 0 - 22 /
- xp?b 9614 8778 23 - 43 swap
- xp?c 18392 153406 44 - 410* /usr
- xp?d unusable
- xp?e unusable
- xp?f unused
- xp?g 0 171798 0 - 410* whole pack
- xp?h unusable
- .PP
- .ne 10
- RP06 partitions:
- disk start length cyls comments
- xp?a 0 9614 0 - 22 /
- xp?b 9614 8778 23 - 43 swap
- xp?c 18392 153406 44 - 410 /usr
- xp?d 171798 168872 411 - 814*
- xp?e 18392 322278 44 - 814*
- xp?f unused
- xp?g 0 171798 0 - 410
- xp?h 0 340670 0 - 814* whole pack
- .PP
- .ne 10
- RM02/RM03 partitions:
- disk start length cyls comments
- xp?a 0 9600 0 - 59 /
- xp?b 9600 9600 60 - 119 swap
- xp?c 0 131680 0 - 822* whole pack + bad144 track
- xp?d unused
- xp?e unused
- xp?f unused
- xp?g 19200 112320 120 - 821
- xp?h 0 131520 0 - 821 whole pack - bad144 track
- .PP
- .ne 10
- RM05 (or SI 9500, CDC 9766) partitions:
- disk start length cyls comments
- xp?a 0 9120 0 - 14 /
- xp?b 9120 9120 15 - 29 swap
- xp?c 18240 234080 30 - 414
- xp?d 252320 248064 415 - 822*
- xp?e 18240 164160 30 - 299 /usr
- xp?f 182400 152000 300 - 549
- xp?g 334400 165984 550 - 822*
- xp?h 0 500384 0 - 822* whole pack
- .PP
- .ne 10
- Capricorn partitions:
- disk start length cyls comments
- xp?a 0 16384 0 - 31 /
- xp?b 16384 33792 32 - 97 swap
- xp?c 50176 291840 98 - 667 /usr
- xp?d 342016 16384 668 - 699
- xp?e 358400 56320 700 - 809
- xp?f 414720 109568 810 - 1023*
- xp?g 342016 182272 668 - 1023*
- xp?h 0 524288 0 - 1023* whole pack
- .PP
- .ne 10
- SI, CDC 9775 (direct) partitions:
- disk start length cyls comments
- xp?a 0 10240 0 - 7 /
- xp?b 10240 10240 8 - 15 swap
- xp?c 20480 510720 16 - 414
- xp?d 531200 547840 415 - 842*
- xp?e 20480 363520 16 - 299 /usr
- xp?f 384000 320000 300 - 549
- xp?g 704000 375040 550 - 842*
- xp?h 0 1079040 0 - 842* whole pack
- .PP
- .ne 10
- SI 6100, Fuji Eagle 2351A partitions:
- disk start length cyls comments
- xp?a 0 11520 0 - 11 /
- xp?b 9600 11520 12 - 23 swap
- xp?c 19200 474240 24 - 517
- xp?d 19200 92160 518 - 613 /usr
- xp?e 144640 218880 614 - 841*
- xp?f unused
- xp?g unused
- xp?h 0 808320 0 - 841* whole pack
- .PP
- .ne 10
- Emulex SC01B or SI 9400, Fuji 160 partitions:
- disk start length cyls comments
- xp?a 0 9600 0 - 29 /
- xp?b 9600 9600 30 - 59 swap
- xp?c 19200 244160 60 - 822*
- xp?d 19200 125440 60 - 451 /usr
- xp?e 144640 118720 452 - 822*
- xp?f 144640 59520 452 - 637
- xp?g 204160 59200 638 - 822*
- xp?h 0 263360 0 - 822* whole pack
- .PP
- .ne 10
- Diva Comp V, Ampex 9300 partitions:
- disk start length cyls comments
- xp?a 0 9405 0 - 14 /
- xp?b 9405 9405 15 - 29 swap
- xp?c 18810 241395 30 - 414
- xp?d 260205 250800 415 - 814*
- xp?e 18810 169290 30 - 299 /usr
- xp?f 188100 156750 300 - 549
- xp?g 313500 166155 550 - 814*
- xp?h 0 511005 0 - 814* whole pack
- .DT
- .fi
- .PP
- Those partitions marked with an asterisk (``*'') allow access to bad block
- information stored at the end of some packs. Extreme care must be taken when
- creating file systems on these partitions to avoid overwriting any bad block
- information present. In general it's best to use
- .IR newfs (8)
- to create file systems since it uses the ``safe'' partition sizes recored in
- .IR /etc/disktab .
- .PP
Special files should only be created for the
partitions that are actually used,
as the overlap in these addresses could lead to confusion otherwise.
! The xp?a partition is normally used for the root file system,
the xp?b partition as a swap area,
! and the xp?h partition for pack-pack copying (it maps the entire disk).
.SH FILES
.ta \w'/dev/MAKEDEV.local 'u
/dev/xp[0-7][a-h] block files
--- 76,99 ----
In raw I/O the buffer must begin on a word (even) boundary,
and counts should be a multiple of 512 bytes (a disk sector).
Likewise
! .I lseek
calls should specify a multiple of 512 bytes.
.SH "DISK SUPPORT"
! Disks must be labeled using either the standalone \fIdisklabel\fP program
! on the boot tape or with the
! .IR disklabel (8)
! program. The kernel no longer attempts to determine the drive type and
! geometry, instead reading this information from the disklabel. There are
! no partition tables coded into the \fIxp\fP driver, these must be placed
! on the drive with \fIdisklabel\fP.
.PP
Special files should only be created for the
partitions that are actually used,
as the overlap in these addresses could lead to confusion otherwise.
! Traditionally
! the xp?a partition is normally used for the root file system,
the xp?b partition as a swap area,
! and the xp?c partition for pack-pack copying (it maps the entire disk).
.SH FILES
.ta \w'/dev/MAKEDEV.local 'u
/dev/xp[0-7][a-h] block files
***************
*** 273,284 ****
.PP
DEC-standard error logging should be supported.
.PP
! The partition tables for the file systems should be read off of each
! pack, as they are never quite what any single installation would prefer,
! and this would make packs more portable.
! .PP
! If the drive types and parameters are not initialized, the
! .I xp
! driver uses drive type registers to discern the type of disk attached
! to each drive. Because of numbering conflicts, foreign disks and/or
! controllers frequently cause this automatic recognition scheme to fail.
--- 154,162 ----
.PP
DEC-standard error logging should be supported.
.PP
! The kernel uses partition 'h' to access the badblock information. This
! should have been 'c' except that almost all of the /etc/disktab entries
! (and thus existing systems) use 'h' for this purpose. Unless you are
! very careful with \fIdisklabel\fP|(8) (to make certain that no data
! partition overlaps the badblock area) you should probably leave BADSECT
! undefined in the kernel config file.
*** /etc/disktab.old Thu Jul 13 19:36:39 1995
--- /etc/disktab Fri Aug 18 23:13:27 1995
***************
*** 129,140 ****
:b0=/mdec/si94uboot:\
:pa#9600:oa#0:ba#1024:fa#1024:ta=2.11BSD:\
:pb#9600:ob#9600:bb#1024:fb#1024:tb=swap:\
! :pc#244002:oc#19200:bc#1024:fc#1024:tc=2.11BSD:\
! :pd#164800:od#19200:bd#1024:fd#1024:td=2.11BSD:\
! :pe#79360:oe#184000:be#1024:fe#1024:te=2.11BSD:\
! :pf#39680:of#184000:bf#1024:ff#1024:tf=2.11BSD:\
! :pg#39680:og#223680:bg#1024:fg#1024:tg=2.11BSD:\
! :ph#263202:bh#1024:fh#1024:th=2.11BSD
diva|DIVA|9300|Diva Comp V, Ampex 9300 (in direct mode):\
:ty=fixed:ns#33:nt#19:nc#815:sf:\
--- 129,140 ----
:b0=/mdec/si94uboot:\
:pa#9600:oa#0:ba#1024:fa#1024:ta=2.11BSD:\
:pb#9600:ob#9600:bb#1024:fb#1024:tb=swap:\
! :pc#244160:oc#19200:bc#1024:fc#1024:tc=2.11BSD:\
! :pd#164800:od#19200:bd#1024:fd#1024:td=unused:\
! :pe#79360:oe#184000:be#1024:fe#1024:te=unused:\
! :pf#39680:of#184000:bf#1024:ff#1024:tf=unused:\
! :pg#39680:og#223680:bg#1024:fg#1024:tg=unused:\
! :ph#263360:oh#0:bh#1024:fh#1024:th=unused
diva|DIVA|9300|Diva Comp V, Ampex 9300 (in direct mode):\
:ty=fixed:ns#33:nt#19:nc#815:sf:\
*** /VERSION.old Sat Aug 12 00:13:20 1995
--- /VERSION Mon Aug 21 22:14:22 1995
***************
*** 1,4 ****
! Current Patch Level: 270
2.11 BSD
============
--- 1,4 ----
! Current Patch Level: 271
2.11 BSD
============