Deal with disk change notification.

This commit is contained in:
pk 2003-07-11 12:09:12 +00:00
parent e0e6a115ce
commit c7a9b61e64
3 changed files with 67 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fd.c,v 1.109 2003/06/29 22:28:55 fvdl Exp $ */
/* $NetBSD: fd.c,v 1.110 2003/07/11 12:09:12 pk Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -139,6 +139,9 @@ enum fdc_state {
RECALWAIT, /* 15 */
RECALTIMEDOUT, /* 16 */
RECALCOMPLETE, /* 17 */
DODSKCHG, /* 18 */
DSKCHGWAIT, /* 19 */
DSKCHGTIMEDOUT, /* 20 */
};
/* software state, per controller */
@ -165,6 +168,7 @@ struct fdc_softc {
#define sc_reg_msr sc_io.fdcio_reg_msr
#define sc_reg_fifo sc_io.fdcio_reg_fifo
#define sc_reg_dor sc_io.fdcio_reg_dor
#define sc_reg_dir sc_io.fdcio_reg_dir
#define sc_reg_drs sc_io.fdcio_reg_msr
#define sc_itask sc_io.fdcio_itask
#define sc_istatus sc_io.fdcio_istatus
@ -299,6 +303,7 @@ int fdc_wrfifo __P((struct fdc_softc *fdc, u_char x));
void fdcstart __P((struct fdc_softc *fdc));
void fdcstatus __P((struct fdc_softc *fdc, char *s));
void fdc_reset __P((struct fdc_softc *fdc));
int fdc_diskchange __P((struct fdc_softc *fdc));
void fdctimeout __P((void *arg));
void fdcpseudointr __P((void *arg));
int fdc_c_hwintr __P((void *));
@ -599,6 +604,7 @@ fdcattach(fdc, pri)
fdc->sc_reg_msr = FDREG77_MSR;
fdc->sc_reg_fifo = FDREG77_FIFO;
fdc->sc_reg_dor = FDREG77_DOR;
fdc->sc_reg_dir = FDREG77_DIR;
code = '7';
fdc->sc_flags |= FDC_NEEDMOTORWAIT;
} else {
@ -1062,6 +1068,21 @@ fdc_wrfifo(fdc, x)
return (-1);
}
int
fdc_diskchange(fdc)
struct fdc_softc *fdc;
{
if (CPU_ISSUN4M && (fdc->sc_flags & FDC_82077) != 0) {
bus_space_tag_t t = fdc->sc_bustag;
bus_space_handle_t h = fdc->sc_handle;
u_int8_t v = bus_space_read_1(t, h, fdc->sc_reg_dir);
return ((v & FDI_DCHG) != 0);
} else if (CPU_ISSUN4C) {
return ((*AUXIO4C_REG & AUXIO4C_FDC) != 0);
}
return (0);
}
int
fdopen(dev, flags, fmt, p)
dev_t dev;
@ -1466,6 +1487,9 @@ loop:
/* Make sure the right drive is selected. */
fd_set_motor(fdc);
if (fdc_diskchange(fdc))
goto dodskchg;
/*FALLTHROUGH*/
case DOSEEK:
doseek:
@ -1501,6 +1525,42 @@ loop:
FDC_WRFIFO(fdc, bp->b_cylinder * fd->sc_type->step);
return (1);
case DODSKCHG:
dodskchg:
/*
* Disk change: force a seek operation by going to cyl 1
* followed by a recalibrate.
*/
disk_busy(&fd->sc_dk);
callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);
fd->sc_cylin = -1;
fdc->sc_nstat = 0;
fdc->sc_state = DSKCHGWAIT;
fdc->sc_itask = FDC_ITASK_SENSEI;
/* seek function */
FDC_WRFIFO(fdc, NE7CMD_SEEK);
FDC_WRFIFO(fdc, fd->sc_drive); /* drive number */
FDC_WRFIFO(fdc, 1 * fd->sc_type->step);
return (1);
case DSKCHGWAIT:
callout_stop(&fdc->sc_timo_ch);
disk_unbusy(&fd->sc_dk, 0, 0);
if (fdc->sc_nstat != 2 || (st0 & 0xf8) != 0x20 ||
cyl != 1 * fd->sc_type->step) {
fdcstatus(fdc, "dskchg seek failed");
fdc->sc_state = DORESET;
} else
fdc->sc_state = DORECAL;
if (fdc_diskchange(fdc)) {
printf("%s: cannot clear disk change status\n",
fdc->sc_dev.dv_xname);
fdc->sc_state = DORESET;
}
goto loop;
case DOIO:
doio:
if (finfo != NULL)
@ -1620,6 +1680,7 @@ loop:
case SEEKTIMEDOUT:
case RECALTIMEDOUT:
case RESETTIMEDOUT:
case DSKCHGTIMEDOUT:
fdcstatus(fdc, "timeout");
/* All other timeouts always roll through to a chip reset */

View File

@ -1,4 +1,4 @@
/* $NetBSD: fdreg.h,v 1.7 2000/01/17 16:57:15 pk Exp $ */
/* $NetBSD: fdreg.h,v 1.8 2003/07/11 12:09:13 pk Exp $ */
/*-
* Copyright (c) 1991 The Regents of the University of California.
@ -56,7 +56,7 @@
#define FDREG77_CCR 7 /* Configuration Control (W) */
/*
* Register offsets for the 82077 controller.
* Register offsets for the 82072 controller.
*/
#define FDREG72_MSR 0 /* Main Status Register (R) */
#define FDREG72_DRS 0 /* Data Rate Select Register (W) */
@ -80,6 +80,7 @@
#define FDO_DEN 0x40 /* Density select */
#define FDO_EJ 0x80 /* Eject disk */
/* Digital Input Register bits */
#define FDI_DCHG 0x80 /* diskette has been changed */
/* XXX - find a place for these... */

View File

@ -1,4 +1,4 @@
/* $NetBSD: fdvar.h,v 1.11 2003/05/03 18:11:00 wiz Exp $ */
/* $NetBSD: fdvar.h,v 1.12 2003/07/11 12:09:13 pk Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -51,6 +51,7 @@ struct fdcio {
u_int fdcio_reg_msr;
u_int fdcio_reg_fifo;
u_int fdcio_reg_dor; /* 82077 only */
u_int fdcio_reg_dir; /* 82077 only */
/*
* Interrupt state.