version 1.51, 2011/07/19 15:59:53 |
version 1.51.12.2, 2014/08/20 00:02:40 |
Line 152 enum fdc_state { |
|
Line 152 enum fdc_state { |
|
|
|
/* software state, per controller */ |
/* software state, per controller */ |
struct fdc_softc { |
struct fdc_softc { |
struct device sc_dev; /* boilerplate */ |
device_t sc_dev; /* boilerplate */ |
void *sc_ih; |
void *sc_ih; |
|
|
bus_space_tag_t sc_iot; /* ISA i/o space identifier */ |
bus_space_tag_t sc_iot; /* ISA i/o space identifier */ |
Line 178 int fdcprobe(device_t, cfdata_t, void *) |
|
Line 178 int fdcprobe(device_t, cfdata_t, void *) |
|
int fdprint(void *, const char *); |
int fdprint(void *, const char *); |
void fdcattach(device_t, device_t, void *); |
void fdcattach(device_t, device_t, void *); |
|
|
CFATTACH_DECL(fdc, sizeof(struct fdc_softc), |
CFATTACH_DECL_NEW(fdc, sizeof(struct fdc_softc), |
fdcprobe, fdcattach, NULL, NULL); |
fdcprobe, fdcattach, NULL, NULL); |
|
|
/* |
/* |
Line 216 struct fd_type fd_types[] = { |
|
Line 216 struct fd_type fd_types[] = { |
|
|
|
/* software state, per disk (with up to 4 disks per ctlr) */ |
/* software state, per disk (with up to 4 disks per ctlr) */ |
struct fd_softc { |
struct fd_softc { |
struct device sc_dev; |
device_t sc_dev; |
struct disk sc_dk; |
struct disk sc_dk; |
|
|
struct fd_type *sc_deftype; /* default type descriptor */ |
struct fd_type *sc_deftype; /* default type descriptor */ |
Line 255 void fdattach(device_t, device_t, void * |
|
Line 255 void fdattach(device_t, device_t, void * |
|
extern char floppy_read_fiq[], floppy_read_fiq_end[]; |
extern char floppy_read_fiq[], floppy_read_fiq_end[]; |
extern char floppy_write_fiq[], floppy_write_fiq_end[]; |
extern char floppy_write_fiq[], floppy_write_fiq_end[]; |
|
|
CFATTACH_DECL(fd, sizeof(struct fd_softc), |
CFATTACH_DECL_NEW(fd, sizeof(struct fd_softc), |
fdprobe, fdattach, NULL, NULL); |
fdprobe, fdattach, NULL, NULL); |
|
|
extern struct cfdriver fd_cd; |
extern struct cfdriver fd_cd; |
Line 268 dev_type_ioctl(fdioctl); |
|
Line 268 dev_type_ioctl(fdioctl); |
|
dev_type_strategy(fdstrategy); |
dev_type_strategy(fdstrategy); |
|
|
const struct bdevsw fd_bdevsw = { |
const struct bdevsw fd_bdevsw = { |
fdopen, fdclose, fdstrategy, fdioctl, nodump, nosize, D_DISK |
.d_open = fdopen, |
|
.d_close = fdclose, |
|
.d_strategy = fdstrategy, |
|
.d_ioctl = fdioctl, |
|
.d_dump = nodump, |
|
.d_psize = nosize, |
|
.d_discard = nodiscard, |
|
.d_flag = D_DISK |
}; |
}; |
|
|
const struct cdevsw fd_cdevsw = { |
const struct cdevsw fd_cdevsw = { |
fdopen, fdclose, fdread, fdwrite, fdioctl, |
.d_open = fdopen, |
nostop, notty, nopoll, nommap, nokqfilter, D_DISK |
.d_close = fdclose, |
|
.d_read = fdread, |
|
.d_write = fdwrite, |
|
.d_ioctl = fdioctl, |
|
.d_stop = nostop, |
|
.d_tty = notty, |
|
.d_poll = nopoll, |
|
.d_mmap = nommap, |
|
.d_kqfilter = nokqfilter, |
|
.d_discard = nodiscard, |
|
.d_flag = D_DISK |
}; |
}; |
|
|
void fdgetdisklabel(struct fd_softc *); |
void fdgetdisklabel(struct fd_softc *); |
Line 376 fdcattach(device_t parent, device_t self |
|
Line 393 fdcattach(device_t parent, device_t self |
|
if (bus_space_map(iot, pa->pa_iobase + pa->pa_offset, FDC_NPORT, 0, &ioh)) |
if (bus_space_map(iot, pa->pa_iobase + pa->pa_offset, FDC_NPORT, 0, &ioh)) |
panic("fdcattach: couldn't map I/O ports"); |
panic("fdcattach: couldn't map I/O ports"); |
|
|
|
fdc->sc_dev = self; |
fdc->sc_iot = iot; |
fdc->sc_iot = iot; |
fdc->sc_ioh = ioh; |
fdc->sc_ioh = ioh; |
|
|
Line 398 fdcattach(device_t parent, device_t self |
|
Line 416 fdcattach(device_t parent, device_t self |
|
* 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 (device_unit(&fdc->sc_dev) == 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 408 fdcattach(device_t parent, device_t self |
|
Line 426 fdcattach(device_t parent, device_t self |
|
/* physical limit: four drives per controller. */ |
/* physical limit: four drives per controller. */ |
for (fa.fa_drive = 0; fa.fa_drive < 4; fa.fa_drive++) { |
for (fa.fa_drive = 0; fa.fa_drive < 4; fa.fa_drive++) { |
if (type >= 0 && fa.fa_drive < 2) |
if (type >= 0 && fa.fa_drive < 2) |
fa.fa_deftype = fd_nvtotype(device_xname(&fdc->sc_dev), |
fa.fa_deftype = fd_nvtotype(device_xname(fdc->sc_dev), |
type, fa.fa_drive); |
type, fa.fa_drive); |
else |
else |
fa.fa_deftype = NULL; /* unknown */ |
fa.fa_deftype = NULL; /* unknown */ |
Line 480 fdattach(device_t parent, device_t self, |
|
Line 498 fdattach(device_t parent, device_t self, |
|
struct fd_type *type = fa->fa_deftype; |
struct fd_type *type = fa->fa_deftype; |
int drive = fa->fa_drive; |
int drive = fa->fa_drive; |
|
|
|
fd->sc_dev = self; |
|
|
callout_init(&fd->sc_motoron_ch, 0); |
callout_init(&fd->sc_motoron_ch, 0); |
callout_init(&fd->sc_motoroff_ch, 0); |
callout_init(&fd->sc_motoroff_ch, 0); |
|
|
Line 500 fdattach(device_t parent, device_t self, |
|
Line 520 fdattach(device_t parent, device_t self, |
|
/* |
/* |
* Initialize and attach the disk structure. |
* Initialize and attach the disk structure. |
*/ |
*/ |
disk_init(&fd->sc_dk, device_xname(&fd->sc_dev), &fddkdriver); |
disk_init(&fd->sc_dk, device_xname(fd->sc_dev), &fddkdriver); |
disk_attach(&fd->sc_dk); |
disk_attach(&fd->sc_dk); |
|
|
/* Needed to power off if the motor is on when we halt. */ |
/* Needed to power off if the motor is on when we halt. */ |
Line 596 fdstrategy(struct buf *bp) |
|
Line 616 fdstrategy(struct buf *bp) |
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
else { |
else { |
struct fdc_softc *fdc = |
struct fdc_softc *fdc = |
device_private(device_parent(&fd->sc_dev)); |
device_private(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); |
|
|
void |
void |
fdstart(struct fd_softc *fd) |
fdstart(struct fd_softc *fd) |
{ |
{ |
struct fdc_softc *fdc = (void *) device_parent(&fd->sc_dev); |
struct fdc_softc *fdc = device_private(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 630 fdstart(struct fd_softc *fd) |
|
Line 650 fdstart(struct fd_softc *fd) |
|
void |
void |
fdfinish(struct fd_softc *fd, struct buf *bp) |
fdfinish(struct fd_softc *fd, struct buf *bp) |
{ |
{ |
struct fdc_softc *fdc = (void *) device_parent(&fd->sc_dev); |
struct fdc_softc *fdc = device_private(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 697 fd_motor_off(void *arg) |
|
Line 717 fd_motor_off(void *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 *) device_parent(&fd->sc_dev), 0); |
fd_set_motor(device_private(device_parent(fd->sc_dev)), 0); |
splx(s); |
splx(s); |
} |
} |
|
|
|
|
fd_motor_on(void *arg) |
fd_motor_on(void *arg) |
{ |
{ |
struct fd_softc *fd = arg; |
struct fd_softc *fd = arg; |
struct fdc_softc *fdc = (void *) device_parent(&fd->sc_dev); |
struct fdc_softc *fdc = device_private(device_parent(fd->sc_dev)); |
int s; |
int s; |
|
|
s = splbio(); |
s = splbio(); |
Line 842 fdcpstatus(int n, struct fdc_softc *fdc) |
|
Line 862 fdcpstatus(int n, struct fdc_softc *fdc) |
|
void |
void |
fdcstatus(device_t dv, int n, const char *s) |
fdcstatus(device_t dv, int n, const char *s) |
{ |
{ |
struct fdc_softc *fdc = (void *) device_parent(dv); |
struct fdc_softc *fdc = device_private(device_parent(dv)); |
|
|
if (n == 0) { |
if (n == 0) { |
out_fdc(fdc->sc_iot, fdc->sc_ioh, NE7CMD_SENSEI); |
out_fdc(fdc->sc_iot, fdc->sc_ioh, NE7CMD_SENSEI); |
Line 865 fdctimeout(void *arg) |
|
Line 885 fdctimeout(void *arg) |
|
#ifdef DEBUG |
#ifdef DEBUG |
log(LOG_ERR,"fdctimeout: state %d\n", fdc->sc_state); |
log(LOG_ERR,"fdctimeout: state %d\n", fdc->sc_state); |
#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++; |
|
|
#endif |
#endif |
if (fiq_claim(&fdc->sc_fh) == -1) |
if (fiq_claim(&fdc->sc_fh) == -1) |
panic("%s: Cannot claim FIQ vector", |
panic("%s: Cannot claim FIQ vector", |
device_xname(&fdc->sc_dev)); |
device_xname(fdc->sc_dev)); |
IOMD_WRITE_BYTE(IOMD_FIQMSK, 0x01); |
IOMD_WRITE_BYTE(IOMD_FIQMSK, 0x01); |
bus_space_write_2(iot, ioh, fdctl, type->rate); |
bus_space_write_2(iot, ioh, fdctl, type->rate); |
#ifdef FD_DEBUG |
#ifdef FD_DEBUG |
|
|
if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 || |
if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 || |
cyl != bp->b_cylinder * fd->sc_type->step) { |
cyl != bp->b_cylinder * fd->sc_type->step) { |
#ifdef FD_DEBUG |
#ifdef FD_DEBUG |
fdcstatus(&fd->sc_dev, 2, "seek failed"); |
fdcstatus(fd->sc_dev, 2, "seek failed"); |
#endif |
#endif |
fdcretry(fdc); |
fdcretry(fdc); |
goto loop; |
goto loop; |
|
|
fiq_release(&fdc->sc_fh); |
fiq_release(&fdc->sc_fh); |
IOMD_WRITE_BYTE(IOMD_FIQMSK, 0x00); |
IOMD_WRITE_BYTE(IOMD_FIQMSK, 0x00); |
#ifdef FD_DEBUG |
#ifdef FD_DEBUG |
fdcstatus(&fd->sc_dev, 7, bp->b_flags & B_READ ? |
fdcstatus(fd->sc_dev, 7, bp->b_flags & B_READ ? |
"read failed" : "write failed"); |
"read failed" : "write failed"); |
printf("blkno %d nblks %d\n", |
printf("blkno %d nblks %d\n", |
fd->sc_blkno, fd->sc_nblks); |
fd->sc_blkno, fd->sc_nblks); |
|
|
out_fdc(iot, ioh, NE7CMD_SENSEI); |
out_fdc(iot, ioh, NE7CMD_SENSEI); |
if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 || cyl != 0) { |
if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 || cyl != 0) { |
#ifdef FD_DEBUG |
#ifdef FD_DEBUG |
fdcstatus(&fd->sc_dev, 2, "recalibrate failed"); |
fdcstatus(fd->sc_dev, 2, "recalibrate failed"); |
#endif |
#endif |
fdcretry(fdc); |
fdcretry(fdc); |
goto loop; |
goto loop; |
|
|
goto doseek; |
goto doseek; |
|
|
default: |
default: |
fdcstatus(&fd->sc_dev, 0, "stray interrupt"); |
fdcstatus(fd->sc_dev, 0, "stray interrupt"); |
return 1; |
return 1; |
} |
} |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |