summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/vax/mscp/mscp_disk.c368
1 files changed, 149 insertions, 219 deletions
diff --git a/sys/arch/vax/mscp/mscp_disk.c b/sys/arch/vax/mscp/mscp_disk.c
index c9bc08d52fa..e4143827fd6 100644
--- a/sys/arch/vax/mscp/mscp_disk.c
+++ b/sys/arch/vax/mscp/mscp_disk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mscp_disk.c,v 1.37 2011/07/06 04:49:36 matthew Exp $ */
+/* $OpenBSD: mscp_disk.c,v 1.38 2011/11/01 20:52:17 miod Exp $ */
/* $NetBSD: mscp_disk.c,v 1.30 2001/11/13 07:38:28 lukem Exp $ */
/*
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
@@ -45,8 +45,6 @@
* write bad block forwarding code
*/
-#include <sys/cdefs.h>
-
#include <sys/param.h>
#include <sys/buf.h>
#include <sys/device.h>
@@ -87,30 +85,29 @@ struct cfdriver rx_cd = {
* Drive status, per drive
*/
struct ra_softc {
- struct device ra_dev; /* Autoconf struct */
- struct disk ra_disk;
- int ra_state; /* open/closed state */
- u_long ra_mediaid; /* media id */
- int ra_hwunit; /* Hardware unit number */
- int ra_havelabel; /* true if we have a label */
+ struct device ra_dev; /* autoconf struct */
+ struct disk ra_disk;
+ struct mscpv_guse ra_guse; /* status information */
+ u_long ra_unitsize; /* unit size in sectors */
+ int ra_state; /* open/closed state */
+ int ra_hwunit; /* Hardware unit number */
};
#define rx_softc ra_softc
void rxattach(struct device *, struct device *, void *);
int rx_putonline(struct rx_softc *);
-void rrmakelabel(struct disklabel *, long);
#if NRA
int ramatch(struct device *, struct cfdata *, void *);
-void raattach(struct device *, struct device *, void *);
int raread(dev_t, struct uio *);
int rawrite(dev_t, struct uio *);
int ra_putonline(struct ra_softc *);
+int ragetdisklabel(dev_t, struct ra_softc *, struct disklabel *, int);
bdev_decl(ra);
-struct cfattach ra_ca = {
+const struct cfattach ra_ca = {
sizeof(struct ra_softc), (cfmatch_t)ramatch, rxattach
};
@@ -119,13 +116,10 @@ struct cfattach ra_ca = {
*/
int
-ramatch(parent, cf, aux)
- struct device *parent;
- struct cfdata *cf;
- void *aux;
+ramatch(struct device *parent, struct cfdata *cf, void *aux)
{
- struct drive_attach_args *da = aux;
- struct mscp *mp = da->da_mp;
+ struct drive_attach_args *da = aux;
+ struct mscp *mp = da->da_mp;
if ((da->da_typ & MSCPBUS_DISK) == 0)
return 0;
@@ -140,32 +134,81 @@ ramatch(parent, cf, aux)
return 1;
}
-/*
+/*
+ * Read the label from the drive.
+ */
+int
+ragetdisklabel(dev_t dev, struct ra_softc *ra, struct disklabel *lp,
+ int spoofonly)
+{
+ int n, p = 0;
+
+ bzero(lp, sizeof(struct disklabel));
+ lp->d_secsize = DEV_BSIZE;
+ lp->d_nsectors = ra->ra_guse.guse_nspt;
+ lp->d_ntracks = ra->ra_guse.guse_ngpc * ra->ra_guse.guse_group;
+ lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+ DL_SETDSIZE(lp, ra->ra_unitsize); /* XXX might be zero */
+
+ if (lp->d_secpercyl) {
+ lp->d_ncylinders = ra->ra_unitsize / lp->d_secpercyl;
+ lp->d_type = DTYPE_MSCP;
+ } else {
+ lp->d_type = DTYPE_FLOPPY;
+ }
+
+ lp->d_bbsize = BBSIZE;
+ lp->d_sbsize = SBSIZE;
+
+ /* Create the disk name for disklabel. Phew... */
+ lp->d_typename[p++] = MSCP_MID_CHAR(2, ra->ra_guse.guse_mediaid);
+ lp->d_typename[p++] = MSCP_MID_CHAR(1, ra->ra_guse.guse_mediaid);
+ if (MSCP_MID_ECH(0, ra->ra_guse.guse_mediaid))
+ lp->d_typename[p++] =
+ MSCP_MID_CHAR(0, ra->ra_guse.guse_mediaid);
+ n = MSCP_MID_NUM(ra->ra_guse.guse_mediaid);
+ if (n > 99) {
+ lp->d_typename[p++] = '1';
+ n -= 100;
+ }
+ if (n > 9) {
+ lp->d_typename[p++] = (n / 10) + '0';
+ n %= 10;
+ }
+ lp->d_typename[p++] = n + '0';
+ lp->d_typename[p] = 0;
+
+ lp->d_version = 1;
+ lp->d_magic = lp->d_magic2 = DISKMAGIC;
+ lp->d_checksum = dkcksum(lp);
+
+ return readdisklabel(DISKLABELDEV(dev), rastrategy, lp, spoofonly);
+}
+
+/*
* (Try to) put the drive online. This is done the first time the
- * drive is opened, or if it har fallen offline.
+ * drive is opened, or if it has fallen offline.
*/
int
-ra_putonline(ra)
- struct ra_softc *ra;
+ra_putonline(struct ra_softc *ra)
{
- struct disklabel *dl;
+ struct disklabel *dl;
+ int rc;
+ ra->ra_state = DK_RDLABEL;
if (rx_putonline(ra) != MSCP_DONE)
return MSCP_FAILED;
dl = ra->ra_disk.dk_label;
-
- ra->ra_state = DK_RDLABEL;
- printf("%s", ra->ra_dev.dv_xname);
- if ((readdisklabel(MAKEDISKDEV(RAMAJOR, ra->ra_dev.dv_unit,
- RAW_PART), rastrategy, dl, 0)) != 0) {
- /* EIO and others */
- } else {
- ra->ra_havelabel = 1;
+ rc = ragetdisklabel(MAKEDISKDEV(RAMAJOR, ra->ra_dev.dv_unit, RAW_PART),
+ ra, dl, 0);
+ if (rc != EIO)
ra->ra_state = DK_OPEN;
- }
- printf(": size %lld sectors\n", DL_GETDSIZE(dl));
+ printf("%s: %luMB, %lu bytes/sector, %lld sectors\n",
+ ra->ra_dev.dv_xname,
+ ra->ra_unitsize / (1048576 / dl->d_secsize),
+ dl->d_secsize, ra->ra_unitsize);
return MSCP_DONE;
}
@@ -175,13 +218,11 @@ ra_putonline(ra)
*/
/*ARGSUSED*/
int
-raopen(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
- struct proc *p;
+raopen(dev_t dev, int flag, int fmt, struct proc *p)
{
struct ra_softc *ra;
int part, unit, mask;
+
/*
* Make sure this is a reasonable open request.
*/
@@ -232,10 +273,7 @@ raopen(dev, flag, fmt, p)
/* ARGSUSED */
int
-raclose(dev, flags, fmt, p)
- dev_t dev;
- int flags, fmt;
- struct proc *p;
+raclose(dev_t dev, int flags, int fmt, struct proc *p)
{
int unit = DISKUNIT(dev);
struct ra_softc *ra = ra_cd.cd_devs[unit];
@@ -263,7 +301,7 @@ raclose(dev, flags, fmt, p)
(void) tsleep(&udautab[unit], PZERO - 1,
"raclose", 0);
splx(s);
- ra->ra_state = CLOSED;
+ ra->ra_state = DK_CLOSED;
}
#endif
return (0);
@@ -273,8 +311,7 @@ raclose(dev, flags, fmt, p)
* Queue a transfer request, and if possible, hand it to the controller.
*/
void
-rastrategy(bp)
- struct buf *bp;
+rastrategy(struct buf *bp)
{
int unit;
struct ra_softc *ra;
@@ -327,18 +364,14 @@ rastrategy(bp)
}
int
-raread(dev, uio)
- dev_t dev;
- struct uio *uio;
+raread(dev_t dev, struct uio *uio)
{
return (physio(rastrategy, dev, B_READ, minphys, uio));
}
int
-rawrite(dev, uio)
- dev_t dev;
- struct uio *uio;
+rawrite(dev_t dev, struct uio *uio)
{
return (physio(rastrategy, dev, B_WRITE, minphys, uio));
@@ -348,12 +381,7 @@ rawrite(dev, uio)
* I/O controls.
*/
int
-raioctl(dev, cmd, data, flag, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+raioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
int unit = DISKUNIT(dev);
struct disklabel *lp, *tp;
@@ -363,9 +391,11 @@ raioctl(dev, cmd, data, flag, p)
lp = ra->ra_disk.dk_label;
switch (cmd) {
+ case DIOCGPDINFO:
+ ragetdisklabel(dev, ra, (struct disklabel *)data, 1);
+ break;
case DIOCGDINFO:
- case DIOCGPDINFO: /* no separate 'physical' info available. */
bcopy(lp, data, sizeof (struct disklabel));
break;
@@ -398,11 +428,7 @@ raioctl(dev, cmd, data, flag, p)
int
-radump(dev, blkno, va, size)
- dev_t dev;
- daddr64_t blkno;
- caddr_t va;
- size_t size;
+radump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size)
{
return ENXIO;
}
@@ -411,13 +437,13 @@ radump(dev, blkno, va, size)
* Return the size of a partition, if known, or -1 if not.
*/
daddr64_t
-rasize(dev)
- dev_t dev;
+rasize(dev_t dev)
{
- int unit = DISKUNIT(dev);
+ int unit = DISKUNIT(dev), part = DISKPART(dev);
struct ra_softc *ra;
+ struct disklabel *lp;
- if (unit >= ra_cd.cd_ndevs || ra_cd.cd_devs[unit] == 0)
+ if (unit >= ra_cd.cd_ndevs || ra_cd.cd_devs[unit] == NULL)
return -1;
ra = ra_cd.cd_devs[unit];
@@ -426,8 +452,13 @@ rasize(dev)
if (ra_putonline(ra) == MSCP_FAILED)
return -1;
- return DL_GETPSIZE(&ra->ra_disk.dk_label->d_partitions[DISKPART(dev)]) *
- (ra->ra_disk.dk_label->d_secsize / DEV_BSIZE);
+ lp = ra->ra_disk.dk_label;
+ if (part >= lp->d_npartitions ||
+ lp->d_partitions[part].p_fstype != FS_SWAP)
+ return -1;
+ else
+ return DL_GETPSIZE(&lp->d_partitions[part]) *
+ (lp->d_secsize / DEV_BSIZE);
}
#endif /* NRA */
@@ -444,7 +475,7 @@ int rxioctl(dev_t, int, caddr_t, int, struct proc *);
int rxdump(dev_t, daddr64_t, caddr_t, size_t);
daddr64_t rxsize(dev_t);
-struct cfattach rx_ca = {
+const struct cfattach rx_ca = {
sizeof(struct rx_softc), (cfmatch_t)rxmatch, rxattach
};
@@ -453,13 +484,10 @@ struct cfattach rx_ca = {
*/
int
-rxmatch(parent, cf, aux)
- struct device *parent;
- struct cfdata *cf;
- void *aux;
+rxmatch(struct device *parent, struct cfdata *cf, void *aux)
{
- struct drive_attach_args *da = aux;
- struct mscp *mp = da->da_mp;
+ struct drive_attach_args *da = aux;
+ struct mscp *mp = da->da_mp;
if ((da->da_typ & MSCPBUS_DISK) == 0)
return 0;
@@ -479,20 +507,17 @@ rxmatch(parent, cf, aux)
/*
* The attach routine only checks and prints drive type.
* Bringing the disk online is done when the disk is accessed
- * the first time.
+ * the first time.
*/
void
-rxattach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+rxattach(struct device *parent, struct device *self, void *aux)
{
- struct rx_softc *rx = (void *)self;
- struct drive_attach_args *da = aux;
- struct mscp *mp = da->da_mp;
- struct mscp_softc *mi = (void *)parent;
- struct disklabel *dl;
+ struct rx_softc *rx = (void *)self;
+ struct drive_attach_args *da = aux;
+ struct mscp *mp = da->da_mp;
+ struct mscp_softc *mi = (void *)parent;
- rx->ra_mediaid = mp->mscp_guse.guse_mediaid;
+ bcopy(&mp->mscp_guse, &rx->ra_guse, sizeof(struct mscpv_guse));
rx->ra_state = DK_CLOSED;
rx->ra_hwunit = mp->mscp_unit;
mi->mi_dp[mp->mscp_unit] = self;
@@ -500,13 +525,6 @@ rxattach(parent, self, aux)
rx->ra_disk.dk_name = rx->ra_dev.dv_xname;
disk_attach(&rx->ra_dev, &rx->ra_disk);
- /* Fill in what we know. The actual size is gotten later */
- dl = rx->ra_disk.dk_label;
-
- dl->d_secsize = DEV_BSIZE;
- dl->d_nsectors = mp->mscp_guse.guse_nspt;
- dl->d_ntracks = mp->mscp_guse.guse_ngpc * mp->mscp_guse.guse_group;
- dl->d_secpercyl = dl->d_nsectors * dl->d_ntracks;
disk_printtype(mp->mscp_unit, mp->mscp_guse.guse_mediaid);
#ifdef DEBUG
printf("%s: nspt %d group %d ngpc %d rct %d nrpt %d nrct %d\n",
@@ -516,19 +534,20 @@ rxattach(parent, self, aux)
#endif
}
-/*
+/*
* (Try to) put the drive online. This is done the first time the
- * drive is opened, or if it har fallen offline.
+ * drive is opened, or if it has fallen offline.
*/
int
-rx_putonline(rx)
- struct rx_softc *rx;
+rx_putonline(struct rx_softc *rx)
{
- struct mscp *mp;
- struct mscp_softc *mi = (struct mscp_softc *)rx->ra_dev.dv_parent;
+ struct mscp *mp;
+ struct mscp_softc *mi = (struct mscp_softc *)rx->ra_dev.dv_parent;
volatile int i;
- rx->ra_state = DK_CLOSED;
+ /* caller may be in DK_RDLABEL state */
+ if (rx->ra_state == DK_OPEN)
+ rx->ra_state = DK_CLOSED;
mp = mscp_getcp(mi, MSCP_WAIT);
mp->mscp_opcode = M_OP_ONLINE;
mp->mscp_unit = rx->ra_hwunit;
@@ -538,11 +557,10 @@ rx_putonline(rx)
/* Poll away */
i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
- if (tsleep(&rx->ra_dev.dv_unit, PRIBIO, "rxonline", 100*100))
+ if (tsleep(&rx->ra_dev.dv_unit, PRIBIO, "rxonline", 100*100) != 0) {
rx->ra_state = DK_CLOSED;
-
- if (rx->ra_state == DK_CLOSED)
return MSCP_FAILED;
+ }
return MSCP_DONE;
}
@@ -554,10 +572,7 @@ rx_putonline(rx)
*/
/*ARGSUSED*/
int
-rxopen(dev, flag, fmt, p)
- dev_t dev;
- int flag, fmt;
- struct proc *p;
+rxopen(dev_t dev, int flag, int fmt, struct proc *p)
{
struct rx_softc *rx;
int unit;
@@ -585,10 +600,7 @@ rxopen(dev, flag, fmt, p)
/* ARGSUSED */
int
-rxclose(dev, flags, fmt, p)
- dev_t dev;
- int flags, fmt;
- struct proc *p;
+rxclose(dev_t dev, int flags, int fmt, struct proc *p)
{
return (0);
}
@@ -601,8 +613,7 @@ rxclose(dev, flags, fmt, p)
* revectoring routine.
*/
void
-rxstrategy(bp)
- struct buf *bp;
+rxstrategy(struct buf *bp)
{
int unit;
struct rx_softc *rx;
@@ -649,18 +660,14 @@ done:
}
int
-rxread(dev, uio)
- dev_t dev;
- struct uio *uio;
+rxread(dev_t dev, struct uio *uio)
{
return (physio(rxstrategy, dev, B_READ, minphys, uio));
}
int
-rxwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
+rxwrite(dev_t dev, struct uio *uio)
{
return (physio(rxstrategy, dev, B_WRITE, minphys, uio));
@@ -670,12 +677,7 @@ rxwrite(dev, uio)
* I/O controls.
*/
int
-rxioctl(dev, cmd, data, flag, p)
- dev_t dev;
- int cmd;
- caddr_t data;
- int flag;
- struct proc *p;
+rxioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
{
int unit = DISKUNIT(dev);
struct disklabel *lp;
@@ -710,11 +712,7 @@ rxioctl(dev, cmd, data, flag, p)
}
int
-rxdump(dev, blkno, va, size)
- dev_t dev;
- daddr64_t blkno;
- caddr_t va;
- size_t size;
+rxdump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size)
{
/* Not likely. */
@@ -722,8 +720,7 @@ rxdump(dev, blkno, va, size)
}
daddr64_t
-rxsize(dev)
- dev_t dev;
+rxsize(dev_t dev)
{
return -1;
@@ -740,8 +737,7 @@ int rrioerror(struct device *, struct mscp *, struct buf *);
void rrfillin(struct buf *, struct mscp *);
void rrbb(struct device *, struct mscp *, struct buf *);
-
-struct mscp_device ra_device = {
+struct mscp_device ra_device = {
rrdgram,
rriodone,
rronline,
@@ -755,30 +751,25 @@ struct mscp_device ra_device = {
/*
* Handle an error datagram.
* This can come from an unconfigured drive as well.
- */
-void
-rrdgram(usc, mp, mi)
- struct device *usc;
- struct mscp *mp;
- struct mscp_softc *mi;
-{
+ */
+void
+rrdgram(struct device *usc, struct mscp *mp, struct mscp_softc *mi)
+{
if (mscp_decodeerror(usc == NULL?"unconf disk" : usc->dv_xname, mp, mi))
- return;
+ return;
/*
* SDI status information bytes 10 and 11 are the microprocessor
* error code and front panel code respectively. These vary per
* drive type and are printed purely for field service information.
*/
- if (mp->mscp_format == M_FM_SDI)
+ if (mp->mscp_format == M_FM_SDI)
printf("\tsdi uproc error code 0x%x, front panel code 0x%x\n",
mp->mscp_erd.erd_sdistat[10],
mp->mscp_erd.erd_sdistat[11]);
}
-void
-rriodone(usc, bp)
- struct device *usc;
- struct buf *bp;
+void
+rriodone(struct device *usc, struct buf *bp)
{
int s;
struct rx_softc *rx = NULL; /* Wall */
@@ -806,12 +797,9 @@ rriodone(usc, bp)
* sleeping on the drive on-line-ness.
*/
int
-rronline(usc, mp)
- struct device *usc;
- struct mscp *mp;
+rronline(struct device *usc, struct mscp *mp)
{
struct rx_softc *rx = (struct rx_softc *)usc;
- struct disklabel *dl;
wakeup((caddr_t)&usc->dv_unit);
if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
@@ -821,65 +809,17 @@ rronline(usc, mp)
}
rx->ra_state = DK_OPEN;
-
- dl = rx->ra_disk.dk_label;
- DL_SETDSIZE(dl, mp->mscp_onle.onle_unitsize);
-
- if (dl->d_secpercyl) {
- dl->d_ncylinders = DL_GETDSIZE(dl) / dl->d_secpercyl;
- dl->d_type = DTYPE_MSCP;
- } else {
- dl->d_type = DTYPE_FLOPPY;
- }
- rrmakelabel(dl, rx->ra_mediaid);
+ rx->ra_unitsize = mp->mscp_onle.onle_unitsize;
return (MSCP_DONE);
}
-void
-rrmakelabel(dl, type)
- struct disklabel *dl;
- long type;
-{
- int n, p = 0;
-
- dl->d_bbsize = BBSIZE;
- dl->d_sbsize = SBSIZE;
-
- /* Create the disk name for disklabel. Phew... */
- dl->d_typename[p++] = MSCP_MID_CHAR(2, type);
- dl->d_typename[p++] = MSCP_MID_CHAR(1, type);
- if (MSCP_MID_ECH(0, type))
- dl->d_typename[p++] = MSCP_MID_CHAR(0, type);
- n = MSCP_MID_NUM(type);
- if (n > 99) {
- dl->d_typename[p++] = '1';
- n -= 100;
- }
- if (n > 9) {
- dl->d_typename[p++] = (n / 10) + '0';
- n %= 10;
- }
- dl->d_typename[p++] = n + '0';
- dl->d_typename[p] = 0;
- dl->d_npartitions = MAXPARTITIONS;
- DL_SETPSIZE(&dl->d_partitions[0], DL_GETDSIZE(dl));
- DL_SETPSIZE(&dl->d_partitions[2], DL_GETDSIZE(dl));
- DL_SETPOFFSET(&dl->d_partitions[0], 0);
- DL_SETPOFFSET(&dl->d_partitions[2], 0);
- dl->d_version = 1;
- dl->d_magic = dl->d_magic2 = DISKMAGIC;
- dl->d_checksum = dkcksum(dl);
-}
-
-/*
+/*
* We got some (configured) unit's status. Return DONE if it succeeded.
*/
int
-rrgotstatus(usc, mp)
- struct device *usc;
- struct mscp *mp;
-{
+rrgotstatus(struct device *usc, struct mscp *mp)
+{
if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
printf("%s: attempt to get status failed: ", usc->dv_xname);
mscp_printevent(mp);
@@ -892,14 +832,12 @@ rrgotstatus(usc, mp)
return (MSCP_DONE);
}
-/*
+/*
* A replace operation finished.
*/
/*ARGSUSED*/
-void
-rrreplace(usc, mp)
- struct device *usc;
- struct mscp *mp;
+void
+rrreplace(struct device *usc, struct mscp *mp)
{
panic("udareplace");
@@ -910,11 +848,8 @@ rrreplace(usc, mp)
* Need to write the bad block forwaring code first....
*/
/*ARGSUSED*/
-int
-rrioerror(usc, mp, bp)
- struct device *usc;
- struct mscp *mp;
- struct buf *bp;
+int
+rrioerror(struct device *usc, struct mscp *mp, struct buf *bp)
{
struct ra_softc *ra = (void *)usc;
int code = mp->mscp_event;
@@ -946,9 +881,7 @@ rrioerror(usc, mp, bp)
* Fill in disk addresses in a mscp packet waiting for transfer.
*/
void
-rrfillin(bp, mp)
- struct buf *bp;
- struct mscp *mp;
+rrfillin(struct buf *bp, struct mscp *mp)
{
struct rx_softc *rx = 0; /* Wall */
struct disklabel *lp;
@@ -975,10 +908,7 @@ rrfillin(bp, mp)
*/
/*ARGSUSED*/
void
-rrbb(usc, mp, bp)
- struct device *usc;
- struct mscp *mp;
- struct buf *bp;
+rrbb(struct device *usc, struct mscp *mp, struct buf *bp)
{
panic("udabb");