version 1.20, 2005/06/09 09:26:06 |
version 1.20.2.1, 2006/06/21 14:47:48 |
Line 251 struct fd_softc { |
|
Line 251 struct fd_softc { |
|
|
|
TAILQ_ENTRY(fd_softc) sc_drivechain; |
TAILQ_ENTRY(fd_softc) sc_drivechain; |
int sc_ops; /* I/O ops since last switch */ |
int sc_ops; /* I/O ops since last switch */ |
struct bufq_state sc_q; /* pending I/O requests */ |
struct bufq_state *sc_q;/* pending I/O requests */ |
int sc_active; /* number of active I/O operations */ |
int sc_active; /* number of active I/O operations */ |
}; |
}; |
|
|
Line 302 void fdcpseudointr __P((void *arg)); |
|
Line 302 void fdcpseudointr __P((void *arg)); |
|
int fdcintr __P((void *)); |
int fdcintr __P((void *)); |
void fdcretry __P((struct fdc_softc *fdc)); |
void fdcretry __P((struct fdc_softc *fdc)); |
void fdfinish __P((struct fd_softc *fd, struct buf *bp)); |
void fdfinish __P((struct fd_softc *fd, struct buf *bp)); |
__inline struct fd_type *fd_dev_to_type __P((struct fd_softc *, dev_t)); |
inline struct fd_type *fd_dev_to_type __P((struct fd_softc *, dev_t)); |
int fdformat __P((dev_t, struct ne7_fd_formb *, struct proc *)); |
int fdformat __P((dev_t, struct ne7_fd_formb *, struct lwp *)); |
|
|
int |
int |
fdcprobe(parent, cf, aux) |
fdcprobe(parent, cf, aux) |
Line 412 fdcattach(parent, self, aux) |
|
Line 412 fdcattach(parent, self, aux) |
|
* The NVRAM info only tells us about the first two disks on the |
* The NVRAM info only tells us about the first two disks on the |
* `primary' floppy controller. |
* `primary' floppy controller. |
*/ |
*/ |
if (fdc->sc_dev.dv_unit == 0) |
if (device_unit(&fdc->sc_dev) == 0) |
type = mc146818_read(NULL, NVRAM_DISKETTE); /* XXX softc */ |
type = mc146818_read(NULL, NVRAM_DISKETTE); /* XXX softc */ |
else |
else |
type = -1; |
type = -1; |
Line 510 fdattach(parent, self, aux) |
|
Line 510 fdattach(parent, self, aux) |
|
else |
else |
printf(": density unknown\n"); |
printf(": density unknown\n"); |
|
|
bufq_alloc(&fd->sc_q, BUFQ_DISKSORT|BUFQ_SORT_CYLINDER); |
bufq_alloc(&fd->sc_q, "disksort", BUFQ_SORT_CYLINDER); |
fd->sc_cylin = -1; |
fd->sc_cylin = -1; |
fd->sc_drive = drive; |
fd->sc_drive = drive; |
fd->sc_deftype = type; |
fd->sc_deftype = type; |
Line 555 fd_nvtotype(fdc, nvraminfo, drive) |
|
Line 555 fd_nvtotype(fdc, nvraminfo, drive) |
|
} |
} |
} |
} |
|
|
__inline struct fd_type * |
inline struct fd_type * |
fd_dev_to_type(fd, dev) |
fd_dev_to_type(fd, dev) |
struct fd_softc *fd; |
struct fd_softc *fd; |
dev_t dev; |
dev_t dev; |
|
|
|
|
/* Queue transfer on drive, activate drive and controller if idle. */ |
/* Queue transfer on drive, activate drive and controller if idle. */ |
s = splbio(); |
s = splbio(); |
BUFQ_PUT(&fd->sc_q, bp); |
BUFQ_PUT(fd->sc_q, bp); |
callout_stop(&fd->sc_motoroff_ch); /* a good idea */ |
callout_stop(&fd->sc_motoroff_ch); /* a good idea */ |
if (fd->sc_active == 0) |
if (fd->sc_active == 0) |
fdstart(fd); |
fdstart(fd); |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
else { |
else { |
struct fdc_softc *fdc = (void *)fd->sc_dev.dv_parent; |
struct fdc_softc *fdc = (void *) device_parent(&fd->sc_dev); |
if (fdc->sc_state == DEVIDLE) { |
if (fdc->sc_state == DEVIDLE) { |
printf("fdstrategy: controller inactive\n"); |
printf("fdstrategy: controller inactive\n"); |
fdcstart(fdc); |
fdcstart(fdc); |
|
|
fdstart(fd) |
fdstart(fd) |
struct fd_softc *fd; |
struct fd_softc *fd; |
{ |
{ |
struct fdc_softc *fdc = (void *)fd->sc_dev.dv_parent; |
struct fdc_softc *fdc = (void *) device_parent(&fd->sc_dev); |
int active = fdc->sc_drives.tqh_first != 0; |
int active = fdc->sc_drives.tqh_first != 0; |
|
|
/* Link into controller queue. */ |
/* Link into controller queue. */ |
Line 659 fdfinish(fd, bp) |
|
Line 659 fdfinish(fd, bp) |
|
struct fd_softc *fd; |
struct fd_softc *fd; |
struct buf *bp; |
struct buf *bp; |
{ |
{ |
struct fdc_softc *fdc = (void *)fd->sc_dev.dv_parent; |
struct fdc_softc *fdc = (void *) device_parent(&fd->sc_dev); |
|
|
/* |
/* |
* Move this drive to the end of the queue to give others a `fair' |
* Move this drive to the end of the queue to give others a `fair' |
Line 667 fdfinish(fd, bp) |
|
Line 667 fdfinish(fd, bp) |
|
* another drive is waiting to be serviced, since there is a long motor |
* another drive is waiting to be serviced, since there is a long motor |
* startup delay whenever we switch. |
* startup delay whenever we switch. |
*/ |
*/ |
(void)BUFQ_GET(&fd->sc_q); |
(void)BUFQ_GET(fd->sc_q); |
if (fd->sc_drivechain.tqe_next && ++fd->sc_ops >= 8) { |
if (fd->sc_drivechain.tqe_next && ++fd->sc_ops >= 8) { |
fd->sc_ops = 0; |
fd->sc_ops = 0; |
TAILQ_REMOVE(&fdc->sc_drives, fd, sc_drivechain); |
TAILQ_REMOVE(&fdc->sc_drives, fd, sc_drivechain); |
if (BUFQ_PEEK(&fd->sc_q) != NULL) |
if (BUFQ_PEEK(fd->sc_q) != NULL) |
TAILQ_INSERT_TAIL(&fdc->sc_drives, fd, sc_drivechain); |
TAILQ_INSERT_TAIL(&fdc->sc_drives, fd, sc_drivechain); |
else |
else |
fd->sc_active = 0; |
fd->sc_active = 0; |
Line 735 fd_motor_off(arg) |
|
Line 735 fd_motor_off(arg) |
|
|
|
s = splbio(); |
s = splbio(); |
fd->sc_flags &= ~(FD_MOTOR | FD_MOTOR_WAIT); |
fd->sc_flags &= ~(FD_MOTOR | FD_MOTOR_WAIT); |
fd_set_motor((struct fdc_softc *)fd->sc_dev.dv_parent, 0); |
fd_set_motor((struct fdc_softc *) device_parent(&fd->sc_dev), 0); |
splx(s); |
splx(s); |
} |
} |
|
|
Line 744 fd_motor_on(arg) |
|
Line 744 fd_motor_on(arg) |
|
void *arg; |
void *arg; |
{ |
{ |
struct fd_softc *fd = arg; |
struct fd_softc *fd = arg; |
struct fdc_softc *fdc = (void *)fd->sc_dev.dv_parent; |
struct fdc_softc *fdc = (void *) device_parent(&fd->sc_dev); |
int s; |
int s; |
|
|
s = splbio(); |
s = splbio(); |
Line 802 out_fdc(iot, ioh, x) |
|
Line 802 out_fdc(iot, ioh, x) |
|
} |
} |
|
|
int |
int |
fdopen(dev, flags, mode, p) |
fdopen(dev, flags, mode, l) |
dev_t dev; |
dev_t dev; |
int flags; |
int flags; |
int mode; |
int mode; |
struct proc *p; |
struct lwp *l; |
{ |
{ |
int unit; |
int unit; |
struct fd_softc *fd; |
struct fd_softc *fd; |
Line 835 fdopen(dev, flags, mode, p) |
|
Line 835 fdopen(dev, flags, mode, p) |
|
} |
} |
|
|
int |
int |
fdclose(dev, flags, mode, p) |
fdclose(dev, flags, mode, l) |
dev_t dev; |
dev_t dev; |
int flags; |
int flags; |
int mode; |
int mode; |
struct proc *p; |
struct lwp *l; |
{ |
{ |
struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(dev)]; |
struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(dev)]; |
|
|
Line 870 fdcstatus(dv, n, s) |
|
Line 870 fdcstatus(dv, n, s) |
|
int n; |
int n; |
const char *s; |
const char *s; |
{ |
{ |
struct fdc_softc *fdc = (void *)dv->dv_parent; |
struct fdc_softc *fdc = (void *) device_parent(dv); |
char bits[64]; |
char bits[64]; |
|
|
if (n == 0) { |
if (n == 0) { |
|
|
#endif |
#endif |
fdcstatus(&fd->sc_dev, 0, "timeout"); |
fdcstatus(&fd->sc_dev, 0, "timeout"); |
|
|
if (BUFQ_PEEK(&fd->sc_q) != NULL) |
if (BUFQ_PEEK(fd->sc_q) != NULL) |
fdc->sc_state++; |
fdc->sc_state++; |
else |
else |
fdc->sc_state = DEVIDLE; |
fdc->sc_state = DEVIDLE; |
|
|
} |
} |
|
|
/* Is there a transfer to this drive? If not, deactivate drive. */ |
/* Is there a transfer to this drive? If not, deactivate drive. */ |
bp = BUFQ_PEEK(&fd->sc_q); |
bp = BUFQ_PEEK(fd->sc_q); |
if (bp == NULL) { |
if (bp == NULL) { |
fd->sc_ops = 0; |
fd->sc_ops = 0; |
TAILQ_REMOVE(&fdc->sc_drives, fd, sc_drivechain); |
TAILQ_REMOVE(&fdc->sc_drives, fd, sc_drivechain); |
|
|
fd->sc_cylin = -1; |
fd->sc_cylin = -1; |
fdc->sc_state = SEEKWAIT; |
fdc->sc_state = SEEKWAIT; |
|
|
fd->sc_dk.dk_seek++; |
iostat_seek(fd->sc_dk.dk_stats); |
disk_busy(&fd->sc_dk); |
disk_busy(&fd->sc_dk); |
|
|
callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc); |
callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc); |
|
|
struct buf *bp; |
struct buf *bp; |
|
|
fd = fdc->sc_drives.tqh_first; |
fd = fdc->sc_drives.tqh_first; |
bp = BUFQ_PEEK(&fd->sc_q); |
bp = BUFQ_PEEK(fd->sc_q); |
|
|
if (fd->sc_opts & FDOPT_NORETRY) |
if (fd->sc_opts & FDOPT_NORETRY) |
goto fail; |
goto fail; |
|
|
} |
} |
|
|
int |
int |
fdioctl(dev, cmd, addr, flag, p) |
fdioctl(dev, cmd, addr, flag, l) |
dev_t dev; |
dev_t dev; |
u_long cmd; |
u_long cmd; |
caddr_t addr; |
caddr_t addr; |
int flag; |
int flag; |
struct proc *p; |
struct lwp *l; |
{ |
{ |
struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(dev)]; |
struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(dev)]; |
struct fdformat_parms *form_parms; |
struct fdformat_parms *form_parms; |
Line 1483 fdioctl(dev, cmd, addr, flag, p) |
|
Line 1483 fdioctl(dev, cmd, addr, flag, p) |
|
fd_formb->fd_formb_secsize(i) = fd->sc_type->secsize; |
fd_formb->fd_formb_secsize(i) = fd->sc_type->secsize; |
} |
} |
|
|
error = fdformat(dev, fd_formb, p); |
error = fdformat(dev, fd_formb, l); |
free(fd_formb, M_TEMP); |
free(fd_formb, M_TEMP); |
return error; |
return error; |
|
|
Line 1505 fdioctl(dev, cmd, addr, flag, p) |
|
Line 1505 fdioctl(dev, cmd, addr, flag, p) |
|
} |
} |
|
|
int |
int |
fdformat(dev, finfo, p) |
fdformat(dev, finfo, l) |
dev_t dev; |
dev_t dev; |
struct ne7_fd_formb *finfo; |
struct ne7_fd_formb *finfo; |
struct proc *p; |
struct lwp *l; |
{ |
{ |
int rv = 0, s; |
int rv = 0, s; |
struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(dev)]; |
struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(dev)]; |
Line 1521 fdformat(dev, finfo, p) |
|
Line 1521 fdformat(dev, finfo, p) |
|
return ENOBUFS; |
return ENOBUFS; |
memset((void *)bp, 0, sizeof(struct buf)); |
memset((void *)bp, 0, sizeof(struct buf)); |
bp->b_flags = B_BUSY | B_PHYS | B_FORMAT; |
bp->b_flags = B_BUSY | B_PHYS | B_FORMAT; |
bp->b_proc = p; |
bp->b_proc = l->l_proc; |
bp->b_dev = dev; |
bp->b_dev = dev; |
|
|
/* |
/* |
Line 1610 load_memory_disc_from_floppy(md, dev) |
|
Line 1610 load_memory_disc_from_floppy(md, dev) |
|
|
|
s = spl0(); |
s = spl0(); |
|
|
if (fdopen(bp->b_dev, 0, 0, curproc) != 0) { |
if (fdopen(bp->b_dev, 0, 0, curlwp) != 0) { |
brelse(bp); |
brelse(bp); |
printf("Cannot open floppy device\n"); |
printf("Cannot open floppy device\n"); |
return(EINVAL); |
return(EINVAL); |
Line 1638 load_memory_disc_from_floppy(md, dev) |
|
Line 1638 load_memory_disc_from_floppy(md, dev) |
|
printf("\x08\x08\x08\x08\x08\x08%4dK done\n", |
printf("\x08\x08\x08\x08\x08\x08%4dK done\n", |
loop * fd_types[type].sectrac * DEV_BSIZE / 1024); |
loop * fd_types[type].sectrac * DEV_BSIZE / 1024); |
|
|
fdclose(bp->b_dev, 0, 0, curproc); |
fdclose(bp->b_dev, 0, 0, curlwp); |
|
|
brelse(bp); |
brelse(bp); |
|
|