kern/103841: [fdc] fdc(4) does not work (regression)
Eugene Grosbein
eugen at grosbein.pp.ru
Fri Jan 26 13:00:56 UTC 2007
The following reply was made to PR kern/103841; it has been noted by GNATS.
From: Eugene Grosbein <eugen at grosbein.pp.ru>
To: bug-followup at freebsd.org
Cc:
Subject: Re: kern/103841: [fdc] fdc(4) does not work (regression)
Date: Fri, 26 Jan 2007 19:55:51 +0700
Hi!
The patch mentioned by Andrey Zadorozhny follows.
This is just a backport of some commits from 7.0-CURRENT
to RELENG_6. Requested acpidump.asl was sent to Jung-uk Kim
some time ago and now I put latest version here:
http://www.grosbein.pp.ru/acpidump.asl.bz2
It corresponds to D975XBD Standard BIOS version 1474 of
December 20, 2006.
--- sys/dev/fdc/fdc.c.orig Sat Sep 30 12:18:40 2006
+++ sys/dev/fdc/fdc.c Fri Oct 6 04:09:31 2006
@@ -191,6 +191,7 @@
#define FDO_MOEN3 0x80 /* motor enable drive 3 */
#define FDSTS 4 /* NEC 765 Main Status Register (R) */
+#define FDDSR 4 /* Data Rate Select Register (W) */
#define FDDATA 5 /* NEC 765 Data Register (R/W) */
#define FDCTL 7 /* Control Register (W) */
@@ -344,6 +345,13 @@
}
static void
+fddsr_wr(struct fdc_data *fdc, u_int8_t v)
+{
+
+ fdregwr(fdc, FDDSR, v);
+}
+
+static void
fddata_wr(struct fdc_data *fdc, u_int8_t v)
{
@@ -494,11 +502,16 @@
{
int i, r[10];
- /* Try a reset, keep motor on */
- fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
- DELAY(100);
- /* enable FDC, but defer interrupts a moment */
- fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
+ if (fdc->fdct == FDC_ENHANCED) {
+ /* Try a software reset, default precomp, and 500 kb/s */
+ fddsr_wr(fdc, 0x80);
+ } else {
+ /* Try a hardware reset, keep motor on */
+ fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
+ DELAY(100);
+ /* enable FDC, but defer interrupts a moment */
+ fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
+ }
DELAY(100);
fdout_wr(fdc, fdc->fdout);
@@ -519,7 +532,7 @@
" CONFIGURE failed in reset\n");
if (debugflags & 1) {
if (fdc_cmd(fdc, 1,
- 0x0e, /* DUMPREG */
+ 0x0e,
10, &r[0], &r[1], &r[2], &r[3], &r[4],
&r[5], &r[6], &r[7], &r[8], &r[9]))
device_printf(fdc->fdc_dev,
@@ -745,6 +758,9 @@
(fdc->retry >= retries || (fd->options & FDOPT_NORETRY))) {
if ((debugflags & 4))
printf("Too many retries (EIO)\n");
+ mtx_lock(&fdc->fdc_mtx);
+ fd->flags |= FD_EMPTY;
+ mtx_unlock(&fdc->fdc_mtx);
return (fdc_biodone(fdc, EIO));
}
@@ -804,7 +820,10 @@
/* Select drive, setup params */
fd_select(fd);
- fdctl_wr(fdc, fd->ft->trans);
+ if (fdc->fdct == FDC_ENHANCED)
+ fddsr_wr(fdc, fd->ft->trans);
+ else
+ fdctl_wr(fdc, fd->ft->trans);
if (bp->bio_cmd & BIO_PROBE) {
--- sys/dev/fdc/fdc_acpi.c.orig Thu Oct 5 23:42:29 2006
+++ sys/dev/fdc/fdc_acpi.c Fri Oct 6 03:53:51 2006
@@ -98,7 +98,6 @@
device_t bus;
int error, fde_count, i;
ACPI_OBJECT *obj, *pkg;
- ACPI_HANDLE h;
uint32_t fde[ACPI_FDC_MAXDEVS];
/* Get our softc and use the same accessor as ISA. */
@@ -107,7 +106,6 @@
/* Initialize variables and get a temporary buffer for _FDE. */
error = ENXIO;
- h = acpi_get_handle(dev);
buf.Length = ACPI_FDC_BUFLEN;
buf.Pointer = malloc(buf.Length, M_TEMP, M_NOWAIT | M_ZERO);
if (buf.Pointer == NULL)
More information about the freebsd-bugs
mailing list