summaryrefslogtreecommitdiffstats
path: root/sys/dev/fdc
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1994-11-02 09:08:40 +0000
committerjkh <jkh@FreeBSD.org>1994-11-02 09:08:40 +0000
commitd0d249ac2d1f37c0063ce93d5a63797cbe737528 (patch)
tree35b9b6a0e116c3e07fd7fa923b25aac56707db76 /sys/dev/fdc
parent144bc301e9ff130e2b9a5d8c74dd37f375bf7251 (diff)
downloadFreeBSD-src-d0d249ac2d1f37c0063ce93d5a63797cbe737528.zip
FreeBSD-src-d0d249ac2d1f37c0063ce93d5a63797cbe737528.tar.gz
Back out Joerg's latest commit. Sorry, Joerg, but this breaks the install
floppies now. I'm not sure why, but things hang when it gets to the `changing root to fd0c' part. Without your latest commit, everything works fine. Maybe you can figure out what you broke after ALPHA! :)
Diffstat (limited to 'sys/dev/fdc')
-rw-r--r--sys/dev/fdc/fdc.c241
1 files changed, 98 insertions, 143 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 3883fd3..8315344 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -80,8 +80,74 @@
static int fd_goaway(struct kern_devconf *, int);
static int fdc_goaway(struct kern_devconf *, int);
-static int fd_externalize(struct proc *, struct kern_devconf *,
- void *, size_t);
+static int fd_externalize(struct proc *, struct kern_devconf *, void *, size_t);
+
+/*
+ * Templates for the kern_devconf structures used when we attach.
+ */
+static struct kern_devconf kdc_fd[NFD] = { {
+ 0, 0, 0, /* filled in by kern_devconf.c */
+ "fd", 0, { MDDT_DISK, 0 },
+ fd_externalize, 0, fd_goaway, DISK_EXTERNALLEN,
+ 0, /* parent */
+ 0, /* parentdata */
+ DC_UNKNOWN, /* state */
+ "floppy disk"
+} };
+
+struct kern_devconf kdc_fdc[NFDC] = { {
+ 0, 0, 0, /* filled in by kern_devconf.c */
+ "fdc", 0, { MDDT_ISA, 0, "bio" },
+ isa_generic_externalize, 0, fdc_goaway, ISA_EXTERNALLEN,
+ 0, /* parent */
+ 0, /* parentdata */
+ DC_UNKNOWN, /* state */
+ "floppy disk/tape controller"
+} };
+
+static inline void
+fd_registerdev(int ctlr, int unit)
+{
+ if(unit != 0)
+ kdc_fd[unit] = kdc_fd[0];
+
+ kdc_fd[unit].kdc_unit = unit;
+ kdc_fd[unit].kdc_parent = &kdc_fdc[ctlr];
+ kdc_fd[unit].kdc_parentdata = 0;
+ dev_attach(&kdc_fd[unit]);
+}
+
+static inline void
+fdc_registerdev(struct isa_device *dvp)
+{
+ int unit = dvp->id_unit;
+
+ if(unit != 0)
+ kdc_fdc[unit] = kdc_fdc[0];
+
+ kdc_fdc[unit].kdc_unit = unit;
+ kdc_fdc[unit].kdc_parent = &kdc_isa0;
+ kdc_fdc[unit].kdc_parentdata = dvp;
+ dev_attach(&kdc_fdc[unit]);
+}
+
+static int
+fdc_goaway(struct kern_devconf *kdc, int force)
+{
+ if(force) {
+ dev_detach(kdc);
+ return 0;
+ } else {
+ return EBUSY; /* XXX fix */
+ }
+}
+
+static int
+fd_goaway(struct kern_devconf *kdc, int force)
+{
+ dev_detach(kdc);
+ return 0;
+}
#define RAW_PART 2
#define b_cylin b_resid
@@ -90,17 +156,6 @@ static int fd_externalize(struct proc *, struct kern_devconf *,
#define B_FORMAT B_XXX
/*
- * Since several people happen to have problems with their drives,
- * it might be a good idea to allow a config file override for the
- * floppy seek settle time; the value is in 1s / FDSEEKWAIT;
- * Preferrable values are powers of two, since the compiler can
- * replace the divide operations by simple shifts then!
- */
-#ifndef FDSEEKWAIT
-# define FDSEEKWAIT 16 /* has been 32 in FreeBSD 1.1.5.1 */
-#endif
-
-/*
* this biotab field doubles as a field for the physical unit number
* on the controller
*/
@@ -268,87 +323,17 @@ int fd_debug = 0;
struct isa_device *fdcdevs[NFDC];
-
-/*
- * Templates for the kern_devconf structures used when we attach.
- */
-static struct kern_devconf kdc_fd[NFD] = { {
- 0, 0, 0, /* filled in by kern_devconf.c */
- "fd", 0, { MDDT_DISK, 0 },
- fd_externalize, 0, fd_goaway, DISK_EXTERNALLEN,
- 0, /* parent */
- 0, /* parentdata */
- DC_UNKNOWN, /* state */
- "floppy disk"
-} };
-
-struct kern_devconf kdc_fdc[NFDC] = { {
- 0, 0, 0, /* filled in by kern_devconf.c */
- "fdc", 0, { MDDT_ISA, 0, "bio" },
- isa_generic_externalize, 0, fdc_goaway, ISA_EXTERNALLEN,
- 0, /* parent */
- 0, /* parentdata */
- DC_UNKNOWN, /* state */
- "floppy disk/tape controller"
-} };
-
-static inline void
-fd_registerdev(int ctlr, int unit)
-{
- if(unit != 0)
- kdc_fd[unit] = kdc_fd[0];
-
- kdc_fd[unit].kdc_unit = unit;
- kdc_fd[unit].kdc_parent = &kdc_fdc[ctlr];
- kdc_fd[unit].kdc_parentdata = 0;
- dev_attach(&kdc_fd[unit]);
-}
-
-static inline void
-fdc_registerdev(struct isa_device *dvp)
-{
- int unit = dvp->id_unit;
-
- if(unit != 0)
- kdc_fdc[unit] = kdc_fdc[0];
-
- kdc_fdc[unit].kdc_unit = unit;
- kdc_fdc[unit].kdc_parent = &kdc_isa0;
- kdc_fdc[unit].kdc_parentdata = dvp;
- dev_attach(&kdc_fdc[unit]);
-}
-
-static int
-fdc_goaway(struct kern_devconf *kdc, int force)
-{
- if(force) {
- dev_detach(kdc);
- return 0;
- } else {
- return EBUSY; /* XXX fix */
- }
-}
-
-static int
-fd_goaway(struct kern_devconf *kdc, int force)
-{
- dev_detach(kdc);
- return 0;
-}
-
/*
* Provide hw.devconf information.
*/
static int
-fd_externalize(struct proc *p, struct kern_devconf *kdc, void *userp,
- size_t len)
+fd_externalize(struct proc *p, struct kern_devconf *kdc, void *userp, size_t len)
{
return disk_externalize(fd_data[kdc->kdc_unit].fdsu, userp, &len);
}
static int
-fdc_externalize(struct proc *p, struct kern_devconf *kdc, void *userp,
- size_t len)
+fdc_externalize(struct proc *p, struct kern_devconf *kdc, void *userp, size_t len)
{
return isa_externalize(fdcdevs[kdc->kdc_unit], userp, &len);
}
@@ -544,30 +529,10 @@ fdsize(dev)
return(0);
}
-
/****************************************************************************/
/* motor control stuff */
+/* remember to not deselect the drive we're working on */
/****************************************************************************/
-
-static void
-fdc_gotobed(void *arg1)
-{
- int fdcu = (int)arg1;
- int fdout = fdc_data[fdcu].fdout;
-
- if((fdout & FDO_FRST) == 0)
- /* huh? */
- return;
-
- /* reset controller */
- fdout &= ~ (FDO_FRST|FDO_FDMAEN);
-
- outb(fdc_data[fdcu].baseport+FDOUT, fdout);
- fdc_data[fdcu].fdout = fdout;
- TRACE1("[0x%x->FDOUT]", fdout);
-}
-
-
static void
set_motor(fdcu, fdsu, turnon)
fdcu_t fdcu;
@@ -576,31 +541,22 @@ set_motor(fdcu, fdsu, turnon)
{
int fdout = fdc_data[fdcu].fdout;
int needspecify = 0;
- int x;
- /* if a timeout is almost due, avoid killing the FDC */
- x = splsoftclock();
if(turnon) {
- if((fdout & (FDO_FRST|FDO_FDMAEN)))
- untimeout(fdc_gotobed, (void *)fdcu);
fdout &= ~FDO_FDSEL;
fdout |= (FDO_MOEN0 << fdsu) + fdsu;
} else
fdout &= ~(FDO_MOEN0 << fdsu);
- splx(x);
- if(turnon) {
+ if(!turnon
+ && (fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0)
+ /* gonna turn off the last drive, put FDC to bed */
+ fdout &= ~ (FDO_FRST|FDO_FDMAEN);
+ else {
/* make sure controller is selected and specified */
if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0)
needspecify = 1;
fdout |= (FDO_FRST|FDO_FDMAEN);
- } else {
- if((fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0)
- /*
- * gonna turn off the last drive, schedule a timeout
- * to put the FDC to bed later (just for sanity)
- */
- timeout(fdc_gotobed, (void *)fdcu, hz * 60);
}
outb(fdc_data[fdcu].baseport+FDOUT, fdout);
@@ -616,10 +572,10 @@ set_motor(fdcu, fdsu, turnon)
out_fdc(fdcu, NE7CMD_SPECIFY);
out_fdc(fdcu, NE7_SPEC_1(3, 240));
out_fdc(fdcu, NE7_SPEC_2(2, 0));
- fdc_data[fdcu].state = STARTRECAL; /* need to recalib now */
}
}
+/* ARGSUSED */
static void
fd_turnoff(void *arg1)
{
@@ -633,6 +589,7 @@ fd_turnoff(void *arg1)
splx(s);
}
+/* ARGSUSED */
static void
fd_motor_on(void *arg1)
{
@@ -658,7 +615,7 @@ fd_turnon(fdu)
{
fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT);
set_motor(fd->fdc->fdcu, fd->fdsu, TURNON);
- timeout(fd_motor_on, (void *)fdu, hz); /* in 1 sec its ok */
+ timeout(fd_motor_on, (caddr_t)fdu, hz); /* in 1 sec its ok */
}
}
@@ -900,7 +857,7 @@ fdstrategy(struct buf *bp)
dp = &(fdc->head);
s = splbio();
disksort(dp, bp);
- untimeout(fd_turnoff, (void *)fdu); /* a good idea */
+ untimeout(fd_turnoff, (caddr_t)fdu); /* a good idea */
fdstart(fdcu);
splx(s);
return;
@@ -932,6 +889,7 @@ fdstart(fdcu)
splx(s);
}
+/* ARGSUSED */
static void
fd_timeout(void *arg1)
{
@@ -983,6 +941,7 @@ fd_timeout(void *arg1)
}
/* just ensure it has the right spl */
+/* ARGSUSED */
static void
fd_pseudointr(void *arg1)
{
@@ -1064,8 +1023,8 @@ fdstate(fdcu, fdc)
TRACE1("fd%d", fdu);
TRACE1("[%s]", fdstates[fdc->state]);
TRACE1("(0x%x)", fd->flags);
- untimeout(fd_turnoff, (void *)fdu);
- timeout(fd_turnoff, (void *)fdu, 4 * hz);
+ untimeout(fd_turnoff, (caddr_t)fdu);
+ timeout(fd_turnoff, (caddr_t)fdu, 4 * hz);
switch (fdc->state)
{
case DEVIDLE:
@@ -1096,9 +1055,9 @@ fdstate(fdcu, fdc)
}
else /* at least make sure we are selected */
{
- fdc->state = DOSEEK;
set_motor(fdcu, fd->fdsu, TURNON);
}
+ fdc->state = DOSEEK;
break;
case DOSEEK:
if (bp->b_cylin == fd->track)
@@ -1122,7 +1081,7 @@ fdstate(fdcu, fdc)
return(0); /* will return later */
case SEEKWAIT:
/* allow heads to settle */
- timeout(fd_pseudointr, (void *)fdcu, hz / FDSEEKWAIT);
+ timeout(fd_pseudointr, (caddr_t)fdcu, hz / 32);
fdc->state = SEEKCOMPLETE;
return(0); /* will return later */
case SEEKCOMPLETE : /* SEEK DONE, START DMA */
@@ -1162,7 +1121,7 @@ fdstate(fdcu, fdc)
{
printf(
"fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
- fdu, descyl, cyl, st0);
+ fdu, descyl, cyl, st0, NE7_ST0BITS);
return(retrier(fdcu));
}
}
@@ -1248,10 +1207,10 @@ fdstate(fdcu, fdc)
out_fdc(fdcu, fd->ft->datalen); /* data length */
}
fdc->state = IOCOMPLETE;
- timeout(fd_timeout, (void *)fdcu, hz);
+ timeout(fd_timeout, (caddr_t)fdcu, hz);
return(0); /* will return later */
case IOCOMPLETE: /* IO DONE, post-analyze */
- untimeout(fd_timeout, (void *)fdcu);
+ untimeout(fd_timeout, (caddr_t)fdcu);
for(i=0;i<7;i++)
{
fdc->status[i] = in_fdc(fdcu);
@@ -1324,7 +1283,7 @@ fdstate(fdcu, fdc)
return(0); /* will return later */
case RECALWAIT:
/* allow heads to settle */
- timeout(fd_pseudointr, (void *)fdcu, hz / FDSEEKWAIT);
+ timeout(fd_pseudointr, (caddr_t)fdcu, hz / 32);
fdc->state = RECALCOMPLETE;
return(0); /* will return later */
case RECALCOMPLETE:
@@ -1363,7 +1322,12 @@ fdstate(fdcu, fdc)
{
return(0); /* time's not up yet */
}
- fdc->state = DOSEEK;
+ /*
+ * since the controller was off, it has lost its
+ * idea about the current track it were; thus,
+ * recalibrate the bastard
+ */
+ fdc->state = STARTRECAL;
return(1); /* will return immediatly */
default:
printf("Unexpected FD int->");
@@ -1488,7 +1452,7 @@ fdformat(dev, finfo, p)
+ finfo->head * fd->ft->sectrac) * fdblk / DEV_BSIZE;
bp->b_bcount = sizeof(struct fd_idfield_data) * finfo->fd_formb_nsecs;
- bp->b_un.b_addr = (void *)finfo;
+ bp->b_un.b_addr = (caddr_t)finfo;
/* now do the format */
fdstrategy(bp);
@@ -1497,7 +1461,7 @@ fdformat(dev, finfo, p)
s = splbio();
while(!(bp->b_flags & B_DONE))
{
- rv = tsleep((void *)bp, PRIBIO, "fdform", 20 * hz);
+ rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz);
if(rv == EWOULDBLOCK)
break;
}
@@ -1622,15 +1586,6 @@ fdioctl(dev, cmd, addr, flag, p)
fd_data[FDUNIT(minor(dev))].options = *(int *)addr;
break;
-#ifdef DEBUG
- case FD_DEBUG:
- /* this is considered harmful; only allow for superuser */
- if(suser(p->p_ucred, &p->p_acflag) != 0)
- return EPERM;
- fd_debug = *(int *)addr;
- break;
-#endif
-
default:
error = ENOTTY;
break;
OpenPOWER on IntegriCloud