Sync with sys/i386/isa/fd.c revision 1.109.

This commit is contained in:
KATO Takenori 1998-04-20 13:50:58 +00:00
parent 1a373dbe8a
commit 9a3c443d5a
2 changed files with 538 additions and 34 deletions

View File

@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
* $Id: fd.c,v 1.27 1998/01/24 02:54:37 eivind Exp $
* $Id: fd.c,v 1.28 1998/04/17 22:37:00 des Exp $
*
*/
@ -90,9 +90,13 @@
#include <sys/ftape.h>
#include <i386/isa/ftreg.h>
#endif
#ifdef DEVFS
#ifdef DEVFS
#include <sys/devfsext.h>
#endif
#ifdef SLICE
#include <sys/device.h>
#include <dev/slice/slice.h>
#endif /* SLICE */
#endif /* DEVFS */
/* misuse a flag to identify format operation */
#define B_FORMAT B_XXX
@ -217,8 +221,21 @@ static struct fd_data {
struct callout_handle toffhandle;
struct callout_handle tohandle;
#ifdef DEVFS
#ifdef SLICE
int unit; /* as in fd0 */
void *bdevs[MAXPARTITIONS];
void *cdevs[MAXPARTITIONS];
struct subdev{
struct slice *slice;
int minor;
struct fd_data *drive;
struct slicelimits limit;
}subdevs[16];
struct intr_config_hook ich;
#else /* SLICE */
void *bdevs[1 + NUMDENS + MAXPARTITIONS];
void *cdevs[1 + NUMDENS + MAXPARTITIONS];
#endif /* SLICE */
#endif
#ifdef PC98
int pc98_trans;
@ -322,7 +339,9 @@ static timeout_t fd_timeout;
static timeout_t fd_pseudointr;
static int fdstate(fdcu_t, fdc_p);
static int retrier(fdcu_t);
#ifndef SLICE
static int fdformat(dev_t, struct fd_formb *, struct proc *);
#endif
static int enable_fifo(fdc_p fdc);
@ -379,6 +398,7 @@ static d_close_t fdclose;
static d_ioctl_t fdioctl;
static d_strategy_t fdstrategy;
/* even if SLICE defined, these are needed for the ft support. */
#define CDEV_MAJOR 9
#define BDEV_MAJOR 2
static struct cdevsw fd_cdevsw;
@ -389,6 +409,30 @@ static struct bdevsw fd_bdevsw =
static struct isa_device *fdcdevs[NFDC];
#ifdef SLICE
static sl_h_IO_req_t fdsIOreq; /* IO req downward (to device) */
static sl_h_ioctl_t fdsioctl; /* ioctl req downward (to device) */
static sl_h_open_t fdsopen; /* downwards travelling open */
static sl_h_close_t fdsclose; /* downwards travelling close */
static void fdsinit(void *);
static struct slice_handler slicetype = {
"floppy",
0,
NULL,
0,
NULL, /* constructor */
&fdsIOreq,
&fdsioctl,
&fdsopen,
&fdsclose,
NULL, /* revoke */
NULL, /* claim */
NULL, /* verify */
NULL /* upconfig */
};
#endif /* SLICE */
static int
fdc_err(fdcu_t fdcu, const char *s)
{
@ -712,8 +756,12 @@ fdattach(struct isa_device *dev)
struct isa_device *fdup;
int ic_type = 0;
#ifdef DEVFS
#ifdef SLICE
char namebuf[64];
#else
int mynor;
int typemynor;
#endif /* SLICE */
int typesize;
#endif
@ -922,6 +970,9 @@ fdattach(struct isa_device *dev)
#endif
fd->track = FD_NO_TRACK;
#ifdef SLICE
fd->unit = fdu;
#endif
fd->fdc = fdc;
fd->fdsu = fdsu;
fd->options = 0;
@ -983,6 +1034,30 @@ fdattach(struct isa_device *dev)
continue;
}
#ifdef DEVFS
#ifdef SLICE
sprintf(namebuf,"fd%d",fdu);
fd->subdevs[0].minor = 0;
fd->subdevs[0].drive = fd;
fd->subdevs[0].limit.blksize =
128 << (fd_types[fd->type - 1].secsize);
fd->subdevs[0].limit.slicesize =
fd_types[fd->type - 1].size
* fd->subdevs[0].limit.blksize;
fd->ft = fd_types + (fd->type - 1); /* default value */
sl_make_slice(&slicetype,
&fd->subdevs[0],
&fd->subdevs[0].limit,
&fd->subdevs[0].slice,
NULL,
namebuf);
/* Allow full probing */
fd->subdevs[0].slice->probeinfo.typespecific = NULL;
fd->subdevs[0].slice->probeinfo.type = NULL;
fd->ich.ich_func = fdsinit;
fd->ich.ich_arg = &fd->subdevs[0];
config_intrhook_establish(&fd->ich);
#else /* SLICE */
mynor = fdu << 6;
fd->bdevs[0] = devfs_add_devswf(&fd_bdevsw, mynor, DV_BLK,
UID_ROOT, GID_OPERATOR, 0640,
@ -990,6 +1065,7 @@ fdattach(struct isa_device *dev)
fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
UID_ROOT, GID_OPERATOR, 0640,
"rfd%d", fdu);
#endif /* SLICE */
for (i = 1; i < 1 + NUMDENS; i++) {
/*
* XXX this and the lookup in Fdopen() should be
@ -1033,7 +1109,6 @@ fdattach(struct isa_device *dev)
break;
}
#endif
typemynor = mynor | i;
#ifdef PC98
if (i == FD_1232)
typesize = fd_types[i - 1].size;
@ -1050,6 +1125,27 @@ fdattach(struct isa_device *dev)
if (typesize == 1722)
typesize = 1720;
#endif
#ifdef SLICE
sprintf(namebuf,"fd%d.%d",fdu,typesize);
fd->subdevs[i].minor = i;
fd->subdevs[i].drive = fd;
fd->subdevs[i].limit.blksize =
128 << (fd_types[i - 1].secsize);
fd->subdevs[i].limit.slicesize =
fd_types[i - 1].size
* fd->subdevs[i].limit.blksize;
sl_make_slice(&slicetype,
&fd->subdevs[i],
&fd->subdevs[i].limit,
&fd->subdevs[i].slice,
NULL,
namebuf);
/* Allow full probing */
fd->subdevs[i].slice->probeinfo.typespecific = NULL;
fd->subdevs[i].slice->probeinfo.type = NO_SUBPART;
}
#else /* SLICE */
typemynor = mynor | i;
fd->bdevs[i] =
devfs_add_devswf(&fd_bdevsw, typemynor, DV_BLK,
UID_ROOT, GID_OPERATOR, 0640,
@ -1059,14 +1155,15 @@ fdattach(struct isa_device *dev)
UID_ROOT, GID_OPERATOR, 0640,
"rfd%d.%d", fdu, typesize);
}
for (i = 0; i < MAXPARTITIONS; i++) {
fd->bdevs[1 + NUMDENS + i] =
devfs_link(fd->bdevs[0],
fd->bdevs[1 + NUMDENS + i] = devfs_link(fd->bdevs[0],
"fd%d%c", fdu, 'a' + i);
fd->cdevs[1 + NUMDENS + i] =
devfs_link(fd->cdevs[0],
"rfd%d%c", fdu, 'a' + i);
}
#endif /* SLICE */
#endif /* DEVFS */
#ifdef notyet
if (dk_ndrive < DK_NDRIVE) {
@ -1085,6 +1182,22 @@ fdattach(struct isa_device *dev)
return (1);
}
#ifdef SLICE
static void
fdsinit(void *arg)
{
struct subdev *sd = arg;
sh_p tp;
if ((tp = slice_probeall(sd->slice)) != NULL) {
(*tp->constructor)(sd->slice);
}
config_intrhook_disestablish(&sd->drive->ich);
}
#endif /* SLICE */
/****************************************************************************/
/* motor control stuff */
/* remember to not deselect the drive we're working on */
@ -1343,6 +1456,10 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
type = fd_data[fdu].type;
#ifndef PC98
else {
/*
* For each type of basic drive, make sure we are trying
* to open a type it can do,
*/
if (type != fd_data[fdu].type) {
switch (fd_data[fdu].type) {
case FD_360:
@ -1512,6 +1629,49 @@ bad:
biodone(bp);
}
#ifdef SLICE
/****************************************************************************/
/* fdsIOreq */
/****************************************************************************/
static void
fdsIOreq(void *private ,struct buf *bp)
{
unsigned nblocks, blknum, cando;
int s;
fdcu_t fdcu;
fdu_t fdu;
fdc_p fdc;
fd_p fd;
size_t fdblk;
struct subdev *sd;
sd = private;
fd = sd->drive;
fdu = fd->unit;
fdc = fd->fdc;
fdcu = fdc->fdcu;
/* check for controller already busy with tape */
if (fdc->flags & FDC_TAPE_BUSY) {
bp->b_error = EBUSY;
bp->b_flags |= B_ERROR;
goto bad;
}
bp->b_driver1 = sd; /* squirrel away which device.. */
bp->b_resid = 0;
s = splbio();
bufqdisksort(&fdc->head, bp);
untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); /* a good idea */
fdstart(fdcu);
splx(s);
return;
bad:
biodone(bp);
return;
}
#endif /* SLICE */
/***************************************************************\
* fdstart *
* We have just queued something.. if the controller is not busy *
@ -1623,6 +1783,7 @@ fdintr(fdcu_t fdcu)
static int
fdstate(fdcu_t fdcu, fdc_p fdc)
{
struct subdev *sd;
int read, format, head, sec = 0, sectrac, st0, cyl, st3;
unsigned blknum = 0, b_cylinder = 0;
fdu_t fdu = fdc->fdu;
@ -1648,8 +1809,14 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
TRACE1("[fdc%d IDLE]", fdcu);
return(0);
}
#ifdef SLICE
sd = bp->b_driver1;
fd = sd->drive;
fdu = fd->unit;
#else
fdu = FDUNIT(minor(bp->b_dev));
fd = fd_data + fdu;
#endif
fdblk = 128 << fd->ft->secsize;
if (fdc->fd && (fd != fdc->fd))
{
@ -1663,7 +1830,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
- (char *)finfo;
}
if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) {
blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk +
blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk +
fd->skip/fdblk;
b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
}
@ -2134,13 +2301,26 @@ static int
retrier(fdcu)
fdcu_t fdcu;
{
struct subdev *sd;
fdc_p fdc = fdc_data + fdcu;
register struct buf *bp;
#ifdef SLICE
struct fd_data *fd;
int fdu;
#endif
bp = bufq_first(&fdc->head);
#ifdef SLICE
sd = bp->b_driver1;
fd = sd->drive;
fdu = fd->unit;
if(fd->options & FDOPT_NORETRY)
goto fail;
#else
if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY)
goto fail;
#endif
switch(fdc->retry)
{
case 0: case 1: case 2:
@ -2157,14 +2337,19 @@ retrier(fdcu)
default:
fail:
{
#ifdef SLICE
printf("fd%d: hard error, block %d ", fdu,
fd->skip / DEV_BSIZE);
#else
dev_t sav_b_dev = bp->b_dev;
/* Trick diskerr */
bp->b_dev = makedev(major(bp->b_dev),
(FDUNIT(minor(bp->b_dev))<<3)|RAW_PART);
(FDUNIT(minor(bp->b_dev))<<3)|RAW_PART);
diskerr(bp, "fd", "hard error", LOG_PRINTF,
fdc->fd->skip / DEV_BSIZE,
(struct disklabel *)NULL);
bp->b_dev = sav_b_dev;
#endif /* !SLICE */
if (fdc->flags & FDC_STAT_VALID)
{
printf(
@ -2194,11 +2379,16 @@ retrier(fdcu)
return(1);
}
#ifdef SLICE
static int
fdformat( struct subdev *sd, struct fd_formb *finfo, struct proc *p)
#else /* !SLICE */
static int
fdformat(dev, finfo, p)
dev_t dev;
struct fd_formb *finfo;
struct proc *p;
#endif /* !SLICE */
{
fdu_t fdu;
fd_p fd;
@ -2207,8 +2397,13 @@ fdformat(dev, finfo, p)
int rv = 0, s;
size_t fdblk;
fdu = FDUNIT(minor(dev));
fd = &fd_data[fdu];
#ifdef SLICE
fd = sd->drive;
fdu = fd->unit;
#else
fdu = FDUNIT(minor(dev));
fd = &fd_data[fdu];
#endif
fdblk = 128 << fd->ft->secsize;
/* set up a buffer header for fdstrategy() */
@ -2222,7 +2417,6 @@ fdformat(dev, finfo, p)
bzero((void *)bp, sizeof(struct buf));
bp->b_flags = B_BUSY | B_PHYS | B_FORMAT;
bp->b_proc = p;
bp->b_dev = dev;
/*
* calculate a fake blkno, so fdstrategy() would initiate a
@ -2235,7 +2429,13 @@ fdformat(dev, finfo, p)
bp->b_data = (caddr_t)finfo;
/* now do the format */
#ifdef SLICE
bp->b_driver1 = sd;
fdsIOreq(sd, bp);
#else /* !SLICE */
bp->b_dev = dev;
fdstrategy(bp);
#endif /* !SLICE */
/* ...and wait for it to complete */
s = splbio();
@ -2266,7 +2466,7 @@ fdformat(dev, finfo, p)
* TODO: don't allocate buffer on stack.
*/
int
static int
fdioctl(dev, cmd, addr, flag, p)
dev_t dev;
int cmd;
@ -2291,6 +2491,28 @@ fdioctl(dev, cmd, addr, flag, p)
return ftioctl(dev, cmd, addr, flag, p);
#endif
#ifdef SLICE
/*
* if SLICE is defined then only ft accesses come here
* so break the rest off to another function for SLICE access.
*/
return (ENOTTY);
}
/*
* Slice ioctls come here
*/
static int
fdsioctl( void *private, int cmd, caddr_t addr, int flag, struct proc *p)
{
struct subdev *sd = private;
fd_p fd = sd->drive;
fdu_t fdu = fd->unit;
fdc_p fdc = fd->fdc;
fdcu_t fdcu = fdc->fdcu;
size_t fdblk;
int error = 0;
#endif /* SLICE */
fdblk = 128 << fd->ft->secsize;
#ifdef PC98
@ -2298,6 +2520,7 @@ fdioctl(dev, cmd, addr, flag, p)
#endif
switch (cmd)
{
#ifndef SLICE
case DIOCGDINFO:
bzero(buffer, sizeof (buffer));
dl = (struct disklabel *)buffer;
@ -2341,7 +2564,7 @@ fdioctl(dev, cmd, addr, flag, p)
error = writedisklabel(dev, fdstrategy,
(struct disklabel *)buffer);
break;
#endif /* !SLICE */
case FD_FORM:
if((flag & FWRITE) == 0)
error = EBADF; /* must be opened for writing */
@ -2349,26 +2572,30 @@ fdioctl(dev, cmd, addr, flag, p)
FD_FORMAT_VERSION)
error = EINVAL; /* wrong version of formatting prog */
else
#ifdef SLICE
error = fdformat(sd, (struct fd_formb *)addr, p);
#else
error = fdformat(dev, (struct fd_formb *)addr, p);
#endif
break;
case FD_GTYPE: /* get drive type */
*(struct fd_type *)addr = *fd_data[FDUNIT(minor(dev))].ft;
*(struct fd_type *)addr = *fd->ft;
break;
case FD_STYPE: /* set drive type */
/* this is considered harmful; only allow for superuser */
if(suser(p->p_ucred, &p->p_acflag) != 0)
return EPERM;
*fd_data[FDUNIT(minor(dev))].ft = *(struct fd_type *)addr;
*fd->ft = *(struct fd_type *)addr;
break;
case FD_GOPTS: /* get drive options */
*(int *)addr = fd_data[FDUNIT(minor(dev))].options;
*(int *)addr = fd->options;
break;
case FD_SOPTS: /* set drive options */
fd_data[FDUNIT(minor(dev))].options = *(int *)addr;
fd->options = *(int *)addr;
break;
default:
@ -2392,7 +2619,32 @@ static void fd_drvinit(void *notused )
SYSINIT(fddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,fd_drvinit,NULL)
#ifdef SLICE
static int
fdsopen(void *private, int flags, int mode, struct proc *p)
{
struct subdev *sd;
sd = private;
return(Fdopen(makedev(0,sd->minor), 0 , 0, p));
}
static void
fdsclose(void *private, int flags, int mode, struct proc *p)
{
struct subdev *sd;
sd = private;
fdclose(makedev(0,sd->minor), 0 , 0, p);
return ;
}
#endif /* SLICE */
#endif
/*
* Hello emacs, these are the
* Local Variables:

View File

@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
* $Id: fd.c,v 1.27 1998/01/24 02:54:37 eivind Exp $
* $Id: fd.c,v 1.28 1998/04/17 22:37:00 des Exp $
*
*/
@ -90,9 +90,13 @@
#include <sys/ftape.h>
#include <i386/isa/ftreg.h>
#endif
#ifdef DEVFS
#ifdef DEVFS
#include <sys/devfsext.h>
#endif
#ifdef SLICE
#include <sys/device.h>
#include <dev/slice/slice.h>
#endif /* SLICE */
#endif /* DEVFS */
/* misuse a flag to identify format operation */
#define B_FORMAT B_XXX
@ -217,8 +221,21 @@ static struct fd_data {
struct callout_handle toffhandle;
struct callout_handle tohandle;
#ifdef DEVFS
#ifdef SLICE
int unit; /* as in fd0 */
void *bdevs[MAXPARTITIONS];
void *cdevs[MAXPARTITIONS];
struct subdev{
struct slice *slice;
int minor;
struct fd_data *drive;
struct slicelimits limit;
}subdevs[16];
struct intr_config_hook ich;
#else /* SLICE */
void *bdevs[1 + NUMDENS + MAXPARTITIONS];
void *cdevs[1 + NUMDENS + MAXPARTITIONS];
#endif /* SLICE */
#endif
#ifdef PC98
int pc98_trans;
@ -322,7 +339,9 @@ static timeout_t fd_timeout;
static timeout_t fd_pseudointr;
static int fdstate(fdcu_t, fdc_p);
static int retrier(fdcu_t);
#ifndef SLICE
static int fdformat(dev_t, struct fd_formb *, struct proc *);
#endif
static int enable_fifo(fdc_p fdc);
@ -379,6 +398,7 @@ static d_close_t fdclose;
static d_ioctl_t fdioctl;
static d_strategy_t fdstrategy;
/* even if SLICE defined, these are needed for the ft support. */
#define CDEV_MAJOR 9
#define BDEV_MAJOR 2
static struct cdevsw fd_cdevsw;
@ -389,6 +409,30 @@ static struct bdevsw fd_bdevsw =
static struct isa_device *fdcdevs[NFDC];
#ifdef SLICE
static sl_h_IO_req_t fdsIOreq; /* IO req downward (to device) */
static sl_h_ioctl_t fdsioctl; /* ioctl req downward (to device) */
static sl_h_open_t fdsopen; /* downwards travelling open */
static sl_h_close_t fdsclose; /* downwards travelling close */
static void fdsinit(void *);
static struct slice_handler slicetype = {
"floppy",
0,
NULL,
0,
NULL, /* constructor */
&fdsIOreq,
&fdsioctl,
&fdsopen,
&fdsclose,
NULL, /* revoke */
NULL, /* claim */
NULL, /* verify */
NULL /* upconfig */
};
#endif /* SLICE */
static int
fdc_err(fdcu_t fdcu, const char *s)
{
@ -712,8 +756,12 @@ fdattach(struct isa_device *dev)
struct isa_device *fdup;
int ic_type = 0;
#ifdef DEVFS
#ifdef SLICE
char namebuf[64];
#else
int mynor;
int typemynor;
#endif /* SLICE */
int typesize;
#endif
@ -922,6 +970,9 @@ fdattach(struct isa_device *dev)
#endif
fd->track = FD_NO_TRACK;
#ifdef SLICE
fd->unit = fdu;
#endif
fd->fdc = fdc;
fd->fdsu = fdsu;
fd->options = 0;
@ -983,6 +1034,30 @@ fdattach(struct isa_device *dev)
continue;
}
#ifdef DEVFS
#ifdef SLICE
sprintf(namebuf,"fd%d",fdu);
fd->subdevs[0].minor = 0;
fd->subdevs[0].drive = fd;
fd->subdevs[0].limit.blksize =
128 << (fd_types[fd->type - 1].secsize);
fd->subdevs[0].limit.slicesize =
fd_types[fd->type - 1].size
* fd->subdevs[0].limit.blksize;
fd->ft = fd_types + (fd->type - 1); /* default value */
sl_make_slice(&slicetype,
&fd->subdevs[0],
&fd->subdevs[0].limit,
&fd->subdevs[0].slice,
NULL,
namebuf);
/* Allow full probing */
fd->subdevs[0].slice->probeinfo.typespecific = NULL;
fd->subdevs[0].slice->probeinfo.type = NULL;
fd->ich.ich_func = fdsinit;
fd->ich.ich_arg = &fd->subdevs[0];
config_intrhook_establish(&fd->ich);
#else /* SLICE */
mynor = fdu << 6;
fd->bdevs[0] = devfs_add_devswf(&fd_bdevsw, mynor, DV_BLK,
UID_ROOT, GID_OPERATOR, 0640,
@ -990,6 +1065,7 @@ fdattach(struct isa_device *dev)
fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
UID_ROOT, GID_OPERATOR, 0640,
"rfd%d", fdu);
#endif /* SLICE */
for (i = 1; i < 1 + NUMDENS; i++) {
/*
* XXX this and the lookup in Fdopen() should be
@ -1033,7 +1109,6 @@ fdattach(struct isa_device *dev)
break;
}
#endif
typemynor = mynor | i;
#ifdef PC98
if (i == FD_1232)
typesize = fd_types[i - 1].size;
@ -1050,6 +1125,27 @@ fdattach(struct isa_device *dev)
if (typesize == 1722)
typesize = 1720;
#endif
#ifdef SLICE
sprintf(namebuf,"fd%d.%d",fdu,typesize);
fd->subdevs[i].minor = i;
fd->subdevs[i].drive = fd;
fd->subdevs[i].limit.blksize =
128 << (fd_types[i - 1].secsize);
fd->subdevs[i].limit.slicesize =
fd_types[i - 1].size
* fd->subdevs[i].limit.blksize;
sl_make_slice(&slicetype,
&fd->subdevs[i],
&fd->subdevs[i].limit,
&fd->subdevs[i].slice,
NULL,
namebuf);
/* Allow full probing */
fd->subdevs[i].slice->probeinfo.typespecific = NULL;
fd->subdevs[i].slice->probeinfo.type = NO_SUBPART;
}
#else /* SLICE */
typemynor = mynor | i;
fd->bdevs[i] =
devfs_add_devswf(&fd_bdevsw, typemynor, DV_BLK,
UID_ROOT, GID_OPERATOR, 0640,
@ -1059,14 +1155,15 @@ fdattach(struct isa_device *dev)
UID_ROOT, GID_OPERATOR, 0640,
"rfd%d.%d", fdu, typesize);
}
for (i = 0; i < MAXPARTITIONS; i++) {
fd->bdevs[1 + NUMDENS + i] =
devfs_link(fd->bdevs[0],
fd->bdevs[1 + NUMDENS + i] = devfs_link(fd->bdevs[0],
"fd%d%c", fdu, 'a' + i);
fd->cdevs[1 + NUMDENS + i] =
devfs_link(fd->cdevs[0],
"rfd%d%c", fdu, 'a' + i);
}
#endif /* SLICE */
#endif /* DEVFS */
#ifdef notyet
if (dk_ndrive < DK_NDRIVE) {
@ -1085,6 +1182,22 @@ fdattach(struct isa_device *dev)
return (1);
}
#ifdef SLICE
static void
fdsinit(void *arg)
{
struct subdev *sd = arg;
sh_p tp;
if ((tp = slice_probeall(sd->slice)) != NULL) {
(*tp->constructor)(sd->slice);
}
config_intrhook_disestablish(&sd->drive->ich);
}
#endif /* SLICE */
/****************************************************************************/
/* motor control stuff */
/* remember to not deselect the drive we're working on */
@ -1343,6 +1456,10 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
type = fd_data[fdu].type;
#ifndef PC98
else {
/*
* For each type of basic drive, make sure we are trying
* to open a type it can do,
*/
if (type != fd_data[fdu].type) {
switch (fd_data[fdu].type) {
case FD_360:
@ -1512,6 +1629,49 @@ bad:
biodone(bp);
}
#ifdef SLICE
/****************************************************************************/
/* fdsIOreq */
/****************************************************************************/
static void
fdsIOreq(void *private ,struct buf *bp)
{
unsigned nblocks, blknum, cando;
int s;
fdcu_t fdcu;
fdu_t fdu;
fdc_p fdc;
fd_p fd;
size_t fdblk;
struct subdev *sd;
sd = private;
fd = sd->drive;
fdu = fd->unit;
fdc = fd->fdc;
fdcu = fdc->fdcu;
/* check for controller already busy with tape */
if (fdc->flags & FDC_TAPE_BUSY) {
bp->b_error = EBUSY;
bp->b_flags |= B_ERROR;
goto bad;
}
bp->b_driver1 = sd; /* squirrel away which device.. */
bp->b_resid = 0;
s = splbio();
bufqdisksort(&fdc->head, bp);
untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); /* a good idea */
fdstart(fdcu);
splx(s);
return;
bad:
biodone(bp);
return;
}
#endif /* SLICE */
/***************************************************************\
* fdstart *
* We have just queued something.. if the controller is not busy *
@ -1623,6 +1783,7 @@ fdintr(fdcu_t fdcu)
static int
fdstate(fdcu_t fdcu, fdc_p fdc)
{
struct subdev *sd;
int read, format, head, sec = 0, sectrac, st0, cyl, st3;
unsigned blknum = 0, b_cylinder = 0;
fdu_t fdu = fdc->fdu;
@ -1648,8 +1809,14 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
TRACE1("[fdc%d IDLE]", fdcu);
return(0);
}
#ifdef SLICE
sd = bp->b_driver1;
fd = sd->drive;
fdu = fd->unit;
#else
fdu = FDUNIT(minor(bp->b_dev));
fd = fd_data + fdu;
#endif
fdblk = 128 << fd->ft->secsize;
if (fdc->fd && (fd != fdc->fd))
{
@ -1663,7 +1830,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
- (char *)finfo;
}
if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) {
blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk +
blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk +
fd->skip/fdblk;
b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
}
@ -2134,13 +2301,26 @@ static int
retrier(fdcu)
fdcu_t fdcu;
{
struct subdev *sd;
fdc_p fdc = fdc_data + fdcu;
register struct buf *bp;
#ifdef SLICE
struct fd_data *fd;
int fdu;
#endif
bp = bufq_first(&fdc->head);
#ifdef SLICE
sd = bp->b_driver1;
fd = sd->drive;
fdu = fd->unit;
if(fd->options & FDOPT_NORETRY)
goto fail;
#else
if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY)
goto fail;
#endif
switch(fdc->retry)
{
case 0: case 1: case 2:
@ -2157,14 +2337,19 @@ retrier(fdcu)
default:
fail:
{
#ifdef SLICE
printf("fd%d: hard error, block %d ", fdu,
fd->skip / DEV_BSIZE);
#else
dev_t sav_b_dev = bp->b_dev;
/* Trick diskerr */
bp->b_dev = makedev(major(bp->b_dev),
(FDUNIT(minor(bp->b_dev))<<3)|RAW_PART);
(FDUNIT(minor(bp->b_dev))<<3)|RAW_PART);
diskerr(bp, "fd", "hard error", LOG_PRINTF,
fdc->fd->skip / DEV_BSIZE,
(struct disklabel *)NULL);
bp->b_dev = sav_b_dev;
#endif /* !SLICE */
if (fdc->flags & FDC_STAT_VALID)
{
printf(
@ -2194,11 +2379,16 @@ retrier(fdcu)
return(1);
}
#ifdef SLICE
static int
fdformat( struct subdev *sd, struct fd_formb *finfo, struct proc *p)
#else /* !SLICE */
static int
fdformat(dev, finfo, p)
dev_t dev;
struct fd_formb *finfo;
struct proc *p;
#endif /* !SLICE */
{
fdu_t fdu;
fd_p fd;
@ -2207,8 +2397,13 @@ fdformat(dev, finfo, p)
int rv = 0, s;
size_t fdblk;
fdu = FDUNIT(minor(dev));
fd = &fd_data[fdu];
#ifdef SLICE
fd = sd->drive;
fdu = fd->unit;
#else
fdu = FDUNIT(minor(dev));
fd = &fd_data[fdu];
#endif
fdblk = 128 << fd->ft->secsize;
/* set up a buffer header for fdstrategy() */
@ -2222,7 +2417,6 @@ fdformat(dev, finfo, p)
bzero((void *)bp, sizeof(struct buf));
bp->b_flags = B_BUSY | B_PHYS | B_FORMAT;
bp->b_proc = p;
bp->b_dev = dev;
/*
* calculate a fake blkno, so fdstrategy() would initiate a
@ -2235,7 +2429,13 @@ fdformat(dev, finfo, p)
bp->b_data = (caddr_t)finfo;
/* now do the format */
#ifdef SLICE
bp->b_driver1 = sd;
fdsIOreq(sd, bp);
#else /* !SLICE */
bp->b_dev = dev;
fdstrategy(bp);
#endif /* !SLICE */
/* ...and wait for it to complete */
s = splbio();
@ -2266,7 +2466,7 @@ fdformat(dev, finfo, p)
* TODO: don't allocate buffer on stack.
*/
int
static int
fdioctl(dev, cmd, addr, flag, p)
dev_t dev;
int cmd;
@ -2291,6 +2491,28 @@ fdioctl(dev, cmd, addr, flag, p)
return ftioctl(dev, cmd, addr, flag, p);
#endif
#ifdef SLICE
/*
* if SLICE is defined then only ft accesses come here
* so break the rest off to another function for SLICE access.
*/
return (ENOTTY);
}
/*
* Slice ioctls come here
*/
static int
fdsioctl( void *private, int cmd, caddr_t addr, int flag, struct proc *p)
{
struct subdev *sd = private;
fd_p fd = sd->drive;
fdu_t fdu = fd->unit;
fdc_p fdc = fd->fdc;
fdcu_t fdcu = fdc->fdcu;
size_t fdblk;
int error = 0;
#endif /* SLICE */
fdblk = 128 << fd->ft->secsize;
#ifdef PC98
@ -2298,6 +2520,7 @@ fdioctl(dev, cmd, addr, flag, p)
#endif
switch (cmd)
{
#ifndef SLICE
case DIOCGDINFO:
bzero(buffer, sizeof (buffer));
dl = (struct disklabel *)buffer;
@ -2341,7 +2564,7 @@ fdioctl(dev, cmd, addr, flag, p)
error = writedisklabel(dev, fdstrategy,
(struct disklabel *)buffer);
break;
#endif /* !SLICE */
case FD_FORM:
if((flag & FWRITE) == 0)
error = EBADF; /* must be opened for writing */
@ -2349,26 +2572,30 @@ fdioctl(dev, cmd, addr, flag, p)
FD_FORMAT_VERSION)
error = EINVAL; /* wrong version of formatting prog */
else
#ifdef SLICE
error = fdformat(sd, (struct fd_formb *)addr, p);
#else
error = fdformat(dev, (struct fd_formb *)addr, p);
#endif
break;
case FD_GTYPE: /* get drive type */
*(struct fd_type *)addr = *fd_data[FDUNIT(minor(dev))].ft;
*(struct fd_type *)addr = *fd->ft;
break;
case FD_STYPE: /* set drive type */
/* this is considered harmful; only allow for superuser */
if(suser(p->p_ucred, &p->p_acflag) != 0)
return EPERM;
*fd_data[FDUNIT(minor(dev))].ft = *(struct fd_type *)addr;
*fd->ft = *(struct fd_type *)addr;
break;
case FD_GOPTS: /* get drive options */
*(int *)addr = fd_data[FDUNIT(minor(dev))].options;
*(int *)addr = fd->options;
break;
case FD_SOPTS: /* set drive options */
fd_data[FDUNIT(minor(dev))].options = *(int *)addr;
fd->options = *(int *)addr;
break;
default:
@ -2392,7 +2619,32 @@ static void fd_drvinit(void *notused )
SYSINIT(fddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,fd_drvinit,NULL)
#ifdef SLICE
static int
fdsopen(void *private, int flags, int mode, struct proc *p)
{
struct subdev *sd;
sd = private;
return(Fdopen(makedev(0,sd->minor), 0 , 0, p));
}
static void
fdsclose(void *private, int flags, int mode, struct proc *p)
{
struct subdev *sd;
sd = private;
fdclose(makedev(0,sd->minor), 0 , 0, p);
return ;
}
#endif /* SLICE */
#endif
/*
* Hello emacs, these are the
* Local Variables: