1995-12-08 11:19:42 +00:00
|
|
|
/*
|
1993-06-12 14:58:17 +00:00
|
|
|
* Copyright (c) 1990 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This code is derived from software contributed to Berkeley by
|
|
|
|
* Don Ahn.
|
|
|
|
*
|
1998-12-12 08:16:01 +00:00
|
|
|
* Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu)
|
|
|
|
* aided by the Linux floppy driver modifications from David Bateman
|
|
|
|
* (dbateman@eng.uts.edu.au).
|
|
|
|
*
|
1995-01-11 16:13:01 +00:00
|
|
|
* Copyright (c) 1993, 1994 by
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
* jc@irbs.UUCP (John Capo)
|
|
|
|
* vak@zebub.msk.su (Serge Vakulenko)
|
|
|
|
* ache@astral.msk.su (Andrew A. Chernov)
|
1995-01-11 16:13:01 +00:00
|
|
|
*
|
|
|
|
* Copyright (c) 1993, 1994, 1995 by
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
* joerg_wunsch@uriah.sax.de (Joerg Wunsch)
|
1995-01-06 15:20:00 +00:00
|
|
|
* dufault@hda.com (Peter Dufault)
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
*
|
2001-05-14 20:20:11 +00:00
|
|
|
* Copyright (c) 2001 Joerg Wunsch,
|
2001-06-03 20:41:21 +00:00
|
|
|
* joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch)
|
2001-05-14 20:20:11 +00:00
|
|
|
*
|
1993-06-12 14:58:17 +00:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2001-06-28 12:35:28 +00:00
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by the University of
|
|
|
|
* California, Berkeley and its contributors.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
1993-06-12 14:58:17 +00:00
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
1993-09-15 23:27:45 +00:00
|
|
|
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
1999-08-28 01:08:13 +00:00
|
|
|
* $FreeBSD$
|
1993-06-12 14:58:17 +00:00
|
|
|
*/
|
|
|
|
|
1997-09-16 07:45:45 +00:00
|
|
|
#include "opt_fdc.h"
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
#include "card.h"
|
1994-02-07 04:27:13 +00:00
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
2000-05-05 09:59:14 +00:00
|
|
|
#include <sys/bio.h>
|
1999-04-16 21:22:55 +00:00
|
|
|
#include <sys/bus.h>
|
1994-02-07 04:27:13 +00:00
|
|
|
#include <sys/conf.h>
|
1998-09-15 08:15:30 +00:00
|
|
|
#include <sys/devicestat.h>
|
2001-05-01 08:13:21 +00:00
|
|
|
#include <sys/disklabel.h>
|
1999-04-16 21:22:55 +00:00
|
|
|
#include <sys/fcntl.h>
|
2001-06-06 06:15:03 +00:00
|
|
|
#include <sys/fdcio.h>
|
2001-05-01 08:13:21 +00:00
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/lock.h>
|
1994-02-07 04:27:13 +00:00
|
|
|
#include <sys/malloc.h>
|
1999-04-16 21:22:55 +00:00
|
|
|
#include <sys/module.h>
|
2001-05-01 08:13:21 +00:00
|
|
|
#include <sys/mutex.h>
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
#include <sys/proc.h>
|
1994-02-07 04:27:13 +00:00
|
|
|
#include <sys/syslog.h>
|
1999-04-16 21:22:55 +00:00
|
|
|
|
|
|
|
#include <machine/bus.h>
|
|
|
|
#include <sys/rman.h>
|
|
|
|
|
|
|
|
#include <machine/clock.h>
|
|
|
|
#include <machine/resource.h>
|
1995-01-06 15:20:00 +00:00
|
|
|
#include <machine/stdarg.h>
|
1999-04-16 21:22:55 +00:00
|
|
|
|
|
|
|
#include <isa/isavar.h>
|
1999-05-31 18:39:17 +00:00
|
|
|
#include <isa/isareg.h>
|
|
|
|
#include <isa/fdreg.h>
|
|
|
|
#include <isa/fdc.h>
|
|
|
|
#include <isa/rtc.h>
|
1999-04-16 21:22:55 +00:00
|
|
|
|
1997-10-19 13:12:02 +00:00
|
|
|
/* configuration flags */
|
|
|
|
#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */
|
1999-12-21 08:33:03 +00:00
|
|
|
#define FDC_NO_FIFO (1 << 2) /* do not enable FIFO */
|
1997-10-19 13:12:02 +00:00
|
|
|
|
|
|
|
/* internally used only, not really from CMOS: */
|
|
|
|
#define RTCFDT_144M_PRETENDED 0x1000
|
|
|
|
|
1995-01-06 15:20:00 +00:00
|
|
|
/* error returns for fd_cmd() */
|
|
|
|
#define FD_FAILED -1
|
|
|
|
#define FD_NOT_VALID -2
|
|
|
|
#define FDC_ERRMAX 100 /* do not log more */
|
2001-07-09 20:46:45 +00:00
|
|
|
/*
|
|
|
|
* Stop retrying after this many DMA overruns. Since each retry takes
|
2001-07-09 20:53:19 +00:00
|
|
|
* one revolution, with 300 rpm., 25 retries take approximately 5
|
2001-07-09 20:46:45 +00:00
|
|
|
* seconds which the read attempt will block in case the DMA overrun
|
|
|
|
* is persistent.
|
|
|
|
*/
|
|
|
|
#define FDC_DMAOV_MAX 25
|
1995-01-06 15:20:00 +00:00
|
|
|
|
1999-12-28 07:38:38 +00:00
|
|
|
#define NUMTYPES 17
|
|
|
|
#define NUMDENS (NUMTYPES - 7)
|
1993-12-16 04:28:42 +00:00
|
|
|
|
1994-02-07 04:27:13 +00:00
|
|
|
#define NO_TYPE 0 /* must match NO_TYPE in ft.c */
|
|
|
|
#define FD_1720 1
|
|
|
|
#define FD_1480 2
|
|
|
|
#define FD_1440 3
|
|
|
|
#define FD_1200 4
|
|
|
|
#define FD_820 5
|
|
|
|
#define FD_800 6
|
|
|
|
#define FD_720 7
|
|
|
|
#define FD_360 8
|
1999-12-28 07:38:38 +00:00
|
|
|
#define FD_640 9
|
|
|
|
#define FD_1232 10
|
1994-02-07 04:27:13 +00:00
|
|
|
|
1999-12-28 07:38:38 +00:00
|
|
|
#define FD_1480in5_25 11
|
|
|
|
#define FD_1440in5_25 12
|
|
|
|
#define FD_820in5_25 13
|
|
|
|
#define FD_800in5_25 14
|
|
|
|
#define FD_720in5_25 15
|
|
|
|
#define FD_360in5_25 16
|
|
|
|
#define FD_640in5_25 17
|
1994-02-07 04:27:13 +00:00
|
|
|
|
2001-06-29 15:30:48 +00:00
|
|
|
#define BIO_RDSECTID BIO_CMD1
|
1993-12-16 04:28:42 +00:00
|
|
|
|
1995-12-10 13:40:44 +00:00
|
|
|
static struct fd_type fd_types[NUMTYPES] =
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
1993-12-21 05:09:21 +00:00
|
|
|
{ 21,2,0xFF,0x04,82,3444,1,FDC_500KBPS,2,0x0C,2 }, /* 1.72M in HD 3.5in */
|
|
|
|
{ 18,2,0xFF,0x1B,82,2952,1,FDC_500KBPS,2,0x6C,1 }, /* 1.48M in HD 3.5in */
|
|
|
|
{ 18,2,0xFF,0x1B,80,2880,1,FDC_500KBPS,2,0x6C,1 }, /* 1.44M in HD 3.5in */
|
|
|
|
{ 15,2,0xFF,0x1B,80,2400,1,FDC_500KBPS,2,0x54,1 }, /* 1.2M in HD 5.25/3.5 */
|
|
|
|
{ 10,2,0xFF,0x10,82,1640,1,FDC_250KBPS,2,0x2E,1 }, /* 820K in HD 3.5in */
|
|
|
|
{ 10,2,0xFF,0x10,80,1600,1,FDC_250KBPS,2,0x2E,1 }, /* 800K in HD 3.5in */
|
|
|
|
{ 9,2,0xFF,0x20,80,1440,1,FDC_250KBPS,2,0x50,1 }, /* 720K in HD 3.5in */
|
1994-03-02 18:34:41 +00:00
|
|
|
{ 9,2,0xFF,0x2A,40, 720,1,FDC_250KBPS,2,0x50,1 }, /* 360K in DD 5.25in */
|
1999-12-28 07:38:38 +00:00
|
|
|
{ 8,2,0xFF,0x2A,80,1280,1,FDC_250KBPS,2,0x50,1 }, /* 640K in DD 5.25in */
|
|
|
|
{ 8,3,0xFF,0x35,77,1232,1,FDC_500KBPS,2,0x74,1 }, /* 1.23M in HD 5.25in */
|
1993-12-21 05:09:21 +00:00
|
|
|
|
|
|
|
{ 18,2,0xFF,0x02,82,2952,1,FDC_500KBPS,2,0x02,2 }, /* 1.48M in HD 5.25in */
|
|
|
|
{ 18,2,0xFF,0x02,80,2880,1,FDC_500KBPS,2,0x02,2 }, /* 1.44M in HD 5.25in */
|
|
|
|
{ 10,2,0xFF,0x10,82,1640,1,FDC_300KBPS,2,0x2E,1 }, /* 820K in HD 5.25in */
|
|
|
|
{ 10,2,0xFF,0x10,80,1600,1,FDC_300KBPS,2,0x2E,1 }, /* 800K in HD 5.25in */
|
|
|
|
{ 9,2,0xFF,0x20,80,1440,1,FDC_300KBPS,2,0x50,1 }, /* 720K in HD 5.25in */
|
|
|
|
{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */
|
1999-12-28 07:38:38 +00:00
|
|
|
{ 8,2,0xFF,0x2A,80,1280,1,FDC_300KBPS,2,0x50,1 }, /* 640K in HD 5.25in */
|
1993-06-12 14:58:17 +00:00
|
|
|
};
|
|
|
|
|
1994-02-07 04:27:13 +00:00
|
|
|
#define DRVS_PER_CTLR 2 /* 2 floppies */
|
1995-01-11 16:13:01 +00:00
|
|
|
|
2001-06-11 10:48:10 +00:00
|
|
|
#define MAX_SEC_SIZE (128 << 3)
|
2001-06-28 12:35:28 +00:00
|
|
|
#define MAX_CYLINDER 85 /* some people really stress their drives
|
|
|
|
* up to cyl 82 */
|
2001-06-26 22:16:30 +00:00
|
|
|
#define MAX_HEAD 1
|
2001-06-11 10:48:10 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
/***********************************************************************\
|
|
|
|
* Per controller structure. *
|
|
|
|
\***********************************************************************/
|
1999-04-16 21:22:55 +00:00
|
|
|
static devclass_t fdc_devclass;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
|
|
|
/***********************************************************************\
|
|
|
|
* Per drive structure. *
|
1994-02-07 04:27:13 +00:00
|
|
|
* N per controller (DRVS_PER_CTLR) *
|
1993-06-12 14:58:17 +00:00
|
|
|
\***********************************************************************/
|
1999-04-16 21:22:55 +00:00
|
|
|
struct fd_data {
|
1994-02-07 04:27:13 +00:00
|
|
|
struct fdc_data *fdc; /* pointer to controller structure */
|
1993-06-12 14:58:17 +00:00
|
|
|
int fdsu; /* this units number on this controller */
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
int type; /* Drive type (FD_1440...) */
|
1993-06-12 14:58:17 +00:00
|
|
|
struct fd_type *ft; /* pointer to the type descriptor */
|
|
|
|
int flags;
|
|
|
|
#define FD_OPEN 0x01 /* it's open */
|
|
|
|
#define FD_ACTIVE 0x02 /* it's active */
|
|
|
|
#define FD_MOTOR 0x04 /* motor should be on */
|
|
|
|
#define FD_MOTOR_WAIT 0x08 /* motor coming up */
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
int skip;
|
|
|
|
int hddrv;
|
1995-01-06 15:20:00 +00:00
|
|
|
#define FD_NO_TRACK -2
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
int track; /* where we think the head is */
|
|
|
|
int options; /* user configurable options, see ioctl_fd.h */
|
1997-09-21 21:41:49 +00:00
|
|
|
struct callout_handle toffhandle;
|
|
|
|
struct callout_handle tohandle;
|
1998-09-15 08:15:30 +00:00
|
|
|
struct devstat device_stats;
|
2001-06-29 07:36:29 +00:00
|
|
|
eventhandler_tag clonetag;
|
|
|
|
dev_t masterdev;
|
2001-07-04 22:10:33 +00:00
|
|
|
#define NCLONEDEVS 10 /* must match the table below */
|
|
|
|
dev_t clonedevs[NCLONEDEVS];
|
1999-04-16 21:22:55 +00:00
|
|
|
device_t dev;
|
|
|
|
fdu_t fdu;
|
|
|
|
};
|
2000-01-05 16:31:27 +00:00
|
|
|
|
|
|
|
struct fdc_ivars {
|
|
|
|
int fdunit;
|
|
|
|
};
|
1999-04-16 21:22:55 +00:00
|
|
|
static devclass_t fd_devclass;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
|
|
|
/***********************************************************************\
|
|
|
|
* Throughout this file the following conventions will be used: *
|
|
|
|
* fd is a pointer to the fd_data struct for the drive in question *
|
|
|
|
* fdc is a pointer to the fdc_data struct for the controller *
|
|
|
|
* fdu is the floppy drive unit number *
|
|
|
|
* fdcu is the floppy controller unit number *
|
|
|
|
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
|
|
|
|
\***********************************************************************/
|
1994-02-07 04:27:13 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
/* internal functions */
|
2001-06-28 12:35:28 +00:00
|
|
|
static driver_intr_t fdc_intr;
|
1999-04-16 21:22:55 +00:00
|
|
|
static void set_motor(struct fdc_data *, int, int);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
# define TURNON 1
|
|
|
|
# define TURNOFF 0
|
|
|
|
static timeout_t fd_turnoff;
|
|
|
|
static timeout_t fd_motor_on;
|
1999-04-16 21:22:55 +00:00
|
|
|
static void fd_turnon(struct fd_data *);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
static void fdc_reset(fdc_p);
|
1999-04-16 21:22:55 +00:00
|
|
|
static int fd_in(struct fdc_data *, int *);
|
2001-06-20 20:21:55 +00:00
|
|
|
static int out_fdc(struct fdc_data *, int);
|
1999-04-16 21:22:55 +00:00
|
|
|
static void fdstart(struct fdc_data *);
|
1998-07-29 13:00:42 +00:00
|
|
|
static timeout_t fd_iotimeout;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
static timeout_t fd_pseudointr;
|
1999-04-16 21:22:55 +00:00
|
|
|
static int fdstate(struct fdc_data *);
|
|
|
|
static int retrier(struct fdc_data *);
|
2001-06-29 15:30:48 +00:00
|
|
|
static int fdmisccmd(dev_t, u_int, void *);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
|
1997-09-17 20:16:17 +00:00
|
|
|
static int enable_fifo(fdc_p fdc);
|
2001-06-20 20:21:55 +00:00
|
|
|
static void fd_clone (void *arg, char *name, int namelen, dev_t *dev);
|
1997-09-17 20:16:17 +00:00
|
|
|
|
|
|
|
static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */
|
|
|
|
|
1997-09-16 07:45:45 +00:00
|
|
|
#ifdef FDC_DEBUG
|
1996-07-12 07:41:34 +00:00
|
|
|
static char const * const fdstates[] =
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
|
|
|
"DEVIDLE",
|
|
|
|
"FINDWORK",
|
|
|
|
"DOSEEK",
|
|
|
|
"SEEKCOMPLETE",
|
|
|
|
"IOCOMPLETE",
|
|
|
|
"RECALCOMPLETE",
|
|
|
|
"STARTRECAL",
|
|
|
|
"RESETCTLR",
|
|
|
|
"SEEKWAIT",
|
|
|
|
"RECALWAIT",
|
|
|
|
"MOTORWAIT",
|
1998-07-29 13:00:42 +00:00
|
|
|
"IOTIMEDOUT",
|
|
|
|
"RESETCOMPLETE",
|
1998-12-14 16:29:58 +00:00
|
|
|
"PIOREAD",
|
1993-06-12 14:58:17 +00:00
|
|
|
};
|
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
/* CAUTION: fd_debug causes huge amounts of logging output */
|
1996-07-12 07:41:34 +00:00
|
|
|
static int volatile fd_debug = 0;
|
2001-07-09 21:11:10 +00:00
|
|
|
#define TRACE0(arg) do { if (fd_debug) printf(arg); } while (0)
|
|
|
|
#define TRACE1(arg1, arg2) do { if (fd_debug) printf(arg1, arg2); } while (0)
|
1997-09-16 07:45:45 +00:00
|
|
|
#else /* FDC_DEBUG */
|
2001-07-09 21:11:10 +00:00
|
|
|
#define TRACE0(arg) do { } while (0)
|
|
|
|
#define TRACE1(arg1, arg2) do { } while (0)
|
1997-09-16 07:45:45 +00:00
|
|
|
#endif /* FDC_DEBUG */
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1999-11-11 08:48:40 +00:00
|
|
|
static void
|
|
|
|
fdout_wr(fdc_p fdc, u_int8_t v)
|
|
|
|
{
|
|
|
|
bus_space_write_1(fdc->portt, fdc->porth, FDOUT+fdc->port_off, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
static u_int8_t
|
|
|
|
fdsts_rd(fdc_p fdc)
|
|
|
|
{
|
|
|
|
return bus_space_read_1(fdc->portt, fdc->porth, FDSTS+fdc->port_off);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
fddata_wr(fdc_p fdc, u_int8_t v)
|
|
|
|
{
|
|
|
|
bus_space_write_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
static u_int8_t
|
|
|
|
fddata_rd(fdc_p fdc)
|
|
|
|
{
|
|
|
|
return bus_space_read_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
fdctl_wr_isa(fdc_p fdc, u_int8_t v)
|
1999-11-11 08:48:40 +00:00
|
|
|
{
|
2000-01-08 09:33:09 +00:00
|
|
|
bus_space_write_1(fdc->ctlt, fdc->ctlh, 0, v);
|
1999-11-11 08:48:40 +00:00
|
|
|
}
|
|
|
|
|
2000-07-28 23:00:00 +00:00
|
|
|
#if NCARD > 0
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
static void
|
|
|
|
fdctl_wr_pcmcia(fdc_p fdc, u_int8_t v)
|
|
|
|
{
|
|
|
|
bus_space_write_1(fdc->portt, fdc->porth, FDCTL+fdc->port_off, v);
|
|
|
|
}
|
2000-07-28 23:00:00 +00:00
|
|
|
#endif
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
|
1999-11-11 08:48:40 +00:00
|
|
|
#if 0
|
|
|
|
|
|
|
|
static u_int8_t
|
|
|
|
fdin_rd(fdc_p fdc)
|
|
|
|
{
|
|
|
|
return bus_space_read_1(fdc->portt, fdc->porth, FDIN);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2001-06-11 10:48:10 +00:00
|
|
|
/*
|
2001-06-28 12:35:28 +00:00
|
|
|
* The open function is named Fdopen() to avoid confusion with fdopen()
|
|
|
|
* in fd(4). The difference is now only meaningful for debuggers.
|
2001-06-11 10:48:10 +00:00
|
|
|
*/
|
|
|
|
static d_open_t Fdopen;
|
1995-12-08 11:19:42 +00:00
|
|
|
static d_close_t fdclose;
|
|
|
|
static d_ioctl_t fdioctl;
|
|
|
|
static d_strategy_t fdstrategy;
|
|
|
|
|
|
|
|
#define CDEV_MAJOR 9
|
1999-05-30 16:53:49 +00:00
|
|
|
static struct cdevsw fd_cdevsw = {
|
|
|
|
/* open */ Fdopen,
|
|
|
|
/* close */ fdclose,
|
|
|
|
/* read */ physread,
|
|
|
|
/* write */ physwrite,
|
|
|
|
/* ioctl */ fdioctl,
|
|
|
|
/* poll */ nopoll,
|
|
|
|
/* mmap */ nommap,
|
|
|
|
/* strategy */ fdstrategy,
|
|
|
|
/* name */ "fd",
|
|
|
|
/* maj */ CDEV_MAJOR,
|
|
|
|
/* dump */ nodump,
|
|
|
|
/* psize */ nopsize,
|
|
|
|
/* flags */ D_DISK,
|
|
|
|
};
|
|
|
|
|
1995-01-06 15:20:00 +00:00
|
|
|
static int
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc_err(struct fdc_data *fdc, const char *s)
|
1995-01-06 15:20:00 +00:00
|
|
|
{
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc->fdc_errs++;
|
|
|
|
if (s) {
|
2000-01-08 09:33:09 +00:00
|
|
|
if (fdc->fdc_errs < FDC_ERRMAX)
|
|
|
|
device_printf(fdc->fdc_dev, "%s", s);
|
|
|
|
else if (fdc->fdc_errs == FDC_ERRMAX)
|
|
|
|
device_printf(fdc->fdc_dev, "too many errors, not "
|
|
|
|
"logging any more\n");
|
1995-10-04 07:01:23 +00:00
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
1995-01-06 15:20:00 +00:00
|
|
|
return FD_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* fd_cmd: Send a command to the chip. Takes a varargs with this structure:
|
|
|
|
* Unit number,
|
|
|
|
* # of output bytes, output bytes as ints ...,
|
1995-05-30 08:16:23 +00:00
|
|
|
* # of input bytes, input bytes as ints ...
|
1995-01-06 15:20:00 +00:00
|
|
|
*/
|
1995-12-10 13:40:44 +00:00
|
|
|
static int
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_cmd(struct fdc_data *fdc, int n_out, ...)
|
1995-01-06 15:20:00 +00:00
|
|
|
{
|
|
|
|
u_char cmd;
|
|
|
|
int n_in;
|
|
|
|
int n;
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, n_out);
|
|
|
|
cmd = (u_char)(va_arg(ap, int));
|
|
|
|
va_end(ap);
|
|
|
|
va_start(ap, n_out);
|
|
|
|
for (n = 0; n < n_out; n++)
|
|
|
|
{
|
1999-04-16 21:22:55 +00:00
|
|
|
if (out_fdc(fdc, va_arg(ap, int)) < 0)
|
1995-01-06 15:20:00 +00:00
|
|
|
{
|
|
|
|
char msg[50];
|
1998-12-04 22:54:57 +00:00
|
|
|
snprintf(msg, sizeof(msg),
|
1995-01-06 15:20:00 +00:00
|
|
|
"cmd %x failed at out byte %d of %d\n",
|
|
|
|
cmd, n + 1, n_out);
|
1999-04-16 21:22:55 +00:00
|
|
|
return fdc_err(fdc, msg);
|
1995-01-06 15:20:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
n_in = va_arg(ap, int);
|
|
|
|
for (n = 0; n < n_in; n++)
|
|
|
|
{
|
|
|
|
int *ptr = va_arg(ap, int *);
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fd_in(fdc, ptr) < 0)
|
1995-01-06 15:20:00 +00:00
|
|
|
{
|
|
|
|
char msg[50];
|
1998-12-04 22:54:57 +00:00
|
|
|
snprintf(msg, sizeof(msg),
|
1995-01-06 15:20:00 +00:00
|
|
|
"cmd %02x failed at in byte %d of %d\n",
|
|
|
|
cmd, n + 1, n_in);
|
1999-04-16 21:22:55 +00:00
|
|
|
return fdc_err(fdc, msg);
|
1995-01-06 15:20:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1997-09-17 20:16:17 +00:00
|
|
|
static int
|
|
|
|
enable_fifo(fdc_p fdc)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
if ((fdc->flags & FDC_HAS_FIFO) == 0) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cannot use fd_cmd the normal way here, since
|
|
|
|
* this might be an invalid command. Thus we send the
|
|
|
|
* first byte, and check for an early turn of data directon.
|
|
|
|
*/
|
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if (out_fdc(fdc, I8207X_CONFIGURE) < 0)
|
|
|
|
return fdc_err(fdc, "Enable FIFO failed\n");
|
1997-09-17 20:16:17 +00:00
|
|
|
|
|
|
|
/* If command is invalid, return */
|
|
|
|
j = 100000;
|
1999-11-11 08:48:40 +00:00
|
|
|
while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM))
|
1997-09-17 20:16:17 +00:00
|
|
|
!= NE7_RQM && j-- > 0)
|
|
|
|
if (i == (NE7_DIO | NE7_RQM)) {
|
|
|
|
fdc_reset(fdc);
|
|
|
|
return FD_FAILED;
|
|
|
|
}
|
|
|
|
if (j<0 ||
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_cmd(fdc, 3,
|
1997-09-17 20:16:17 +00:00
|
|
|
0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
|
|
|
|
fdc_reset(fdc);
|
1999-04-16 21:22:55 +00:00
|
|
|
return fdc_err(fdc, "Enable FIFO failed\n");
|
1997-09-17 20:16:17 +00:00
|
|
|
}
|
|
|
|
fdc->flags |= FDC_HAS_FIFO;
|
|
|
|
return 0;
|
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fd_cmd(fdc, 4,
|
1997-09-17 20:16:17 +00:00
|
|
|
I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0)
|
1999-04-16 21:22:55 +00:00
|
|
|
return fdc_err(fdc, "Re-enable FIFO failed\n");
|
1997-09-17 20:16:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1995-12-10 13:40:44 +00:00
|
|
|
static int
|
1995-01-06 15:20:00 +00:00
|
|
|
fd_sense_drive_status(fdc_p fdc, int *st3p)
|
|
|
|
{
|
|
|
|
int st3;
|
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
|
1995-01-06 15:20:00 +00:00
|
|
|
{
|
1999-04-16 21:22:55 +00:00
|
|
|
return fdc_err(fdc, "Sense Drive Status failed\n");
|
1995-01-06 15:20:00 +00:00
|
|
|
}
|
|
|
|
if (st3p)
|
|
|
|
*st3p = st3;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1995-12-10 13:40:44 +00:00
|
|
|
static int
|
1995-01-06 15:20:00 +00:00
|
|
|
fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
|
|
|
|
{
|
1999-04-16 21:22:55 +00:00
|
|
|
int cyl, st0, ret;
|
1995-01-06 15:20:00 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0);
|
|
|
|
if (ret) {
|
|
|
|
(void)fdc_err(fdc,
|
1995-01-06 15:20:00 +00:00
|
|
|
"sense intr err reading stat reg 0\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (st0p)
|
|
|
|
*st0p = st0;
|
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) {
|
1995-01-06 15:20:00 +00:00
|
|
|
/*
|
|
|
|
* There doesn't seem to have been an interrupt.
|
|
|
|
*/
|
|
|
|
return FD_NOT_VALID;
|
|
|
|
}
|
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fd_in(fdc, &cyl) < 0) {
|
|
|
|
return fdc_err(fdc, "can't get cyl num\n");
|
1995-01-06 15:20:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (cylp)
|
|
|
|
*cylp = cyl;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1995-12-10 13:40:44 +00:00
|
|
|
static int
|
2001-06-28 12:35:28 +00:00
|
|
|
fd_read_status(fdc_p fdc)
|
1995-01-06 15:20:00 +00:00
|
|
|
{
|
|
|
|
int i, ret;
|
1995-03-16 18:17:34 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
for (i = 0; i < 7; i++) {
|
1995-03-16 18:17:34 +00:00
|
|
|
/*
|
2001-06-28 12:35:28 +00:00
|
|
|
* XXX types are poorly chosen. Only bytes can be read
|
1998-07-11 06:35:39 +00:00
|
|
|
* from the hardware, but fdc->status[] wants u_ints and
|
1995-03-16 18:17:34 +00:00
|
|
|
* fd_in() gives ints.
|
|
|
|
*/
|
|
|
|
int status;
|
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
ret = fd_in(fdc, &status);
|
1995-03-16 18:17:34 +00:00
|
|
|
fdc->status[i] = status;
|
|
|
|
if (ret != 0)
|
1995-01-06 15:20:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret == 0)
|
|
|
|
fdc->flags |= FDC_STAT_VALID;
|
|
|
|
else
|
|
|
|
fdc->flags &= ~FDC_STAT_VALID;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
/****************************************************************************/
|
|
|
|
/* autoconfiguration stuff */
|
|
|
|
/****************************************************************************/
|
1995-01-06 15:20:00 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
static int
|
2000-01-05 16:31:27 +00:00
|
|
|
fdc_alloc_resources(struct fdc_data *fdc)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
2000-01-05 16:31:27 +00:00
|
|
|
device_t dev;
|
2001-06-29 07:36:29 +00:00
|
|
|
int ispnp, ispcmcia, nports;
|
1999-05-31 18:39:17 +00:00
|
|
|
|
2000-01-05 16:31:27 +00:00
|
|
|
dev = fdc->fdc_dev;
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
ispnp = (fdc->flags & FDC_ISPNP) != 0;
|
|
|
|
ispcmcia = (fdc->flags & FDC_ISPCMCIA) != 0;
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0;
|
|
|
|
fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0;
|
|
|
|
|
2000-01-08 09:33:09 +00:00
|
|
|
/*
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
* On standard ISA, we don't just use an 8 port range
|
|
|
|
* (e.g. 0x3f0-0x3f7) since that covers an IDE control
|
|
|
|
* register at 0x3f6.
|
|
|
|
*
|
2000-01-08 09:33:09 +00:00
|
|
|
* Isn't PC hardware wonderful.
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
*
|
|
|
|
* The Y-E Data PCMCIA FDC doesn't have this problem, it
|
|
|
|
* uses the register with offset 6 for pseudo-DMA, and the
|
|
|
|
* one with offset 7 as control register.
|
2000-01-08 09:33:09 +00:00
|
|
|
*/
|
2001-06-29 07:36:29 +00:00
|
|
|
nports = ispcmcia ? 8 : (ispnp ? 1 : 6);
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
|
|
|
|
&fdc->rid_ioport, 0ul, ~0ul,
|
2001-06-29 07:36:29 +00:00
|
|
|
nports, RF_ACTIVE);
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fdc->res_ioport == 0) {
|
2001-06-29 07:36:29 +00:00
|
|
|
device_printf(dev, "cannot reserve I/O port range (%d ports)\n",
|
|
|
|
nports);
|
2000-01-05 16:31:27 +00:00
|
|
|
return ENXIO;
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
1999-11-11 08:48:40 +00:00
|
|
|
fdc->portt = rman_get_bustag(fdc->res_ioport);
|
|
|
|
fdc->porth = rman_get_bushandle(fdc->res_ioport);
|
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
if (!ispcmcia) {
|
|
|
|
/*
|
|
|
|
* Some BIOSen report the device at 0x3f2-0x3f5,0x3f7
|
|
|
|
* and some at 0x3f0-0x3f5,0x3f7. We detect the former
|
|
|
|
* by checking the size and adjust the port address
|
|
|
|
* accordingly.
|
|
|
|
*/
|
|
|
|
if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 4)
|
|
|
|
fdc->port_off = -2;
|
2000-01-08 09:33:09 +00:00
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
/*
|
|
|
|
* Register the control port range as rid 1 if it
|
|
|
|
* isn't there already. Most PnP BIOSen will have
|
|
|
|
* already done this but non-PnP configurations don't.
|
|
|
|
*
|
|
|
|
* And some (!!) report 0x3f2-0x3f5 and completely
|
|
|
|
* leave out the control register! It seems that some
|
|
|
|
* non-antique controller chips have a different
|
|
|
|
* method of programming the transfer speed which
|
|
|
|
* doesn't require the control register, but it's
|
|
|
|
* mighty bogus as the chip still responds to the
|
|
|
|
* address for the control register.
|
|
|
|
*/
|
|
|
|
if (bus_get_resource_count(dev, SYS_RES_IOPORT, 1) == 0) {
|
|
|
|
u_long ctlstart;
|
2000-01-08 09:33:09 +00:00
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
/* Find the control port, usually 0x3f7 */
|
|
|
|
ctlstart = rman_get_start(fdc->res_ioport) +
|
|
|
|
fdc->port_off + 7;
|
2000-01-08 09:33:09 +00:00
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
bus_set_resource(dev, SYS_RES_IOPORT, 1, ctlstart, 1);
|
|
|
|
}
|
2000-01-08 09:33:09 +00:00
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
/*
|
|
|
|
* Now (finally!) allocate the control port.
|
|
|
|
*/
|
|
|
|
fdc->rid_ctl = 1;
|
|
|
|
fdc->res_ctl = bus_alloc_resource(dev, SYS_RES_IOPORT,
|
|
|
|
&fdc->rid_ctl,
|
|
|
|
0ul, ~0ul, 1, RF_ACTIVE);
|
|
|
|
if (fdc->res_ctl == 0) {
|
|
|
|
device_printf(dev,
|
2001-06-29 07:36:29 +00:00
|
|
|
"cannot reserve control I/O port range (control port)\n");
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
fdc->ctlt = rman_get_bustag(fdc->res_ctl);
|
|
|
|
fdc->ctlh = rman_get_bushandle(fdc->res_ctl);
|
1999-11-11 08:48:40 +00:00
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
|
|
|
|
fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ,
|
|
|
|
&fdc->rid_irq, 0ul, ~0ul, 1,
|
|
|
|
RF_ACTIVE);
|
|
|
|
if (fdc->res_irq == 0) {
|
1999-11-11 08:48:40 +00:00
|
|
|
device_printf(dev, "cannot reserve interrupt line\n");
|
2000-01-05 16:31:27 +00:00
|
|
|
return ENXIO;
|
1999-04-16 21:22:55 +00:00
|
|
|
}
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
|
|
|
|
if ((fdc->flags & FDC_NODMA) == 0) {
|
|
|
|
fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ,
|
|
|
|
&fdc->rid_drq, 0ul, ~0ul, 1,
|
|
|
|
RF_ACTIVE);
|
|
|
|
if (fdc->res_drq == 0) {
|
|
|
|
device_printf(dev, "cannot reserve DMA request line\n");
|
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
fdc->dmachan = fdc->res_drq->r_start;
|
1999-04-16 21:22:55 +00:00
|
|
|
}
|
2000-01-05 16:31:27 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
fdc_release_resources(struct fdc_data *fdc)
|
|
|
|
{
|
|
|
|
device_t dev;
|
|
|
|
|
|
|
|
dev = fdc->fdc_dev;
|
|
|
|
if (fdc->res_irq != 0) {
|
|
|
|
bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
|
|
|
|
fdc->res_irq);
|
|
|
|
bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
|
|
|
|
fdc->res_irq);
|
|
|
|
}
|
|
|
|
if (fdc->res_ctl != 0) {
|
|
|
|
bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
|
|
|
|
fdc->res_ctl);
|
|
|
|
bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl,
|
|
|
|
fdc->res_ctl);
|
|
|
|
}
|
|
|
|
if (fdc->res_ioport != 0) {
|
|
|
|
bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
|
|
|
|
fdc->res_ioport);
|
|
|
|
bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
|
|
|
|
fdc->res_ioport);
|
|
|
|
}
|
|
|
|
if (fdc->res_drq != 0) {
|
|
|
|
bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
|
|
|
|
fdc->res_drq);
|
|
|
|
bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
|
|
|
|
fdc->res_drq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
/* autoconfiguration stuff */
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
static struct isa_pnp_id fdc_ids[] = {
|
|
|
|
{0x0007d041, "PC standard floppy disk controller"}, /* PNP0700 */
|
|
|
|
{0x0107d041, "Standard floppy controller supporting MS Device Bay Spec"}, /* PNP0701 */
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
2000-04-30 10:01:56 +00:00
|
|
|
fdc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
|
2000-01-05 16:31:27 +00:00
|
|
|
{
|
|
|
|
struct fdc_ivars *ivars = device_get_ivars(child);
|
|
|
|
|
|
|
|
switch (which) {
|
|
|
|
case FDC_IVAR_FDUNIT:
|
|
|
|
*result = ivars->fdunit;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return ENOENT;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* fdc controller section.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
fdc_probe(device_t dev)
|
|
|
|
{
|
|
|
|
int error, ic_type;
|
|
|
|
struct fdc_data *fdc;
|
|
|
|
|
|
|
|
fdc = device_get_softc(dev);
|
|
|
|
bzero(fdc, sizeof *fdc);
|
|
|
|
fdc->fdc_dev = dev;
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
fdc->fdctl_wr = fdctl_wr_isa;
|
2000-01-05 16:31:27 +00:00
|
|
|
|
|
|
|
/* Check pnp ids */
|
|
|
|
error = ISA_PNP_PROBE(device_get_parent(dev), dev, fdc_ids);
|
|
|
|
if (error == ENXIO)
|
|
|
|
return ENXIO;
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
if (error == 0)
|
|
|
|
fdc->flags |= FDC_ISPNP;
|
2000-01-05 16:31:27 +00:00
|
|
|
|
|
|
|
/* Attempt to allocate our resources for the duration of the probe */
|
|
|
|
error = fdc_alloc_resources(fdc);
|
|
|
|
if (error)
|
|
|
|
goto out;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1993-12-03 05:01:40 +00:00
|
|
|
/* First - lets reset the floppy controller */
|
1999-11-11 08:48:40 +00:00
|
|
|
fdout_wr(fdc, 0);
|
1993-12-03 05:01:40 +00:00
|
|
|
DELAY(100);
|
1999-11-11 08:48:40 +00:00
|
|
|
fdout_wr(fdc, FDO_FRST);
|
1993-12-03 05:01:40 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
/* see if it can handle a command */
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
|
|
|
|
NE7_SPEC_2(2, 0), 0)) {
|
|
|
|
error = ENXIO;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) {
|
|
|
|
ic_type = (u_char)ic_type;
|
|
|
|
switch (ic_type) {
|
|
|
|
case 0x80:
|
|
|
|
device_set_desc(dev, "NEC 765 or clone");
|
|
|
|
fdc->fdct = FDC_NE765;
|
|
|
|
break;
|
|
|
|
case 0x81:
|
|
|
|
device_set_desc(dev, "Intel 82077 or clone");
|
|
|
|
fdc->fdct = FDC_I82077;
|
|
|
|
break;
|
|
|
|
case 0x90:
|
|
|
|
device_set_desc(dev, "NEC 72065B or clone");
|
|
|
|
fdc->fdct = FDC_NE72065;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
device_set_desc(dev, "generic floppy controller");
|
|
|
|
fdc->fdct = FDC_UNKNOWN;
|
|
|
|
break;
|
|
|
|
}
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
|
|
|
|
out:
|
2000-01-05 16:31:27 +00:00
|
|
|
fdc_release_resources(fdc);
|
1999-04-16 21:22:55 +00:00
|
|
|
return (error);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
#if NCARD > 0
|
|
|
|
|
|
|
|
static int
|
|
|
|
fdc_pccard_probe(device_t dev)
|
|
|
|
{
|
|
|
|
int error;
|
|
|
|
struct fdc_data *fdc;
|
|
|
|
|
|
|
|
fdc = device_get_softc(dev);
|
|
|
|
bzero(fdc, sizeof *fdc);
|
|
|
|
fdc->fdc_dev = dev;
|
|
|
|
fdc->fdctl_wr = fdctl_wr_pcmcia;
|
|
|
|
|
|
|
|
fdc->flags |= FDC_ISPCMCIA | FDC_NODMA;
|
|
|
|
|
|
|
|
/* Attempt to allocate our resources for the duration of the probe */
|
|
|
|
error = fdc_alloc_resources(fdc);
|
|
|
|
if (error)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
/* First - lets reset the floppy controller */
|
|
|
|
fdout_wr(fdc, 0);
|
|
|
|
DELAY(100);
|
|
|
|
fdout_wr(fdc, FDO_FRST);
|
|
|
|
|
|
|
|
/* see if it can handle a command */
|
|
|
|
if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
|
|
|
|
NE7_SPEC_2(2, 0), 0)) {
|
|
|
|
error = ENXIO;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
device_set_desc(dev, "Y-E Data PCMCIA floppy");
|
|
|
|
fdc->fdct = FDC_NE765;
|
|
|
|
|
|
|
|
out:
|
|
|
|
fdc_release_resources(fdc);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2001-06-29 07:36:29 +00:00
|
|
|
#endif /* NCARD > 0 */
|
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
static int
|
2001-06-29 07:36:29 +00:00
|
|
|
fdc_detach(device_t dev)
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
{
|
|
|
|
struct fdc_data *fdc;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
fdc = device_get_softc(dev);
|
|
|
|
|
|
|
|
/* have our children detached first */
|
|
|
|
if ((error = bus_generic_detach(dev)))
|
|
|
|
return (error);
|
|
|
|
|
2001-06-29 07:36:29 +00:00
|
|
|
/* reset controller, turn motor off */
|
|
|
|
fdout_wr(fdc, 0);
|
|
|
|
|
|
|
|
if ((fdc->flags & FDC_NODMA) == 0)
|
|
|
|
isa_dma_release(fdc->dmachan);
|
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
if ((fdc->flags & FDC_ATTACHED) == 0) {
|
|
|
|
device_printf(dev, "already unloaded\n");
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
fdc->flags &= ~FDC_ATTACHED;
|
|
|
|
|
|
|
|
BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
|
|
|
|
fdc->fdc_intr);
|
|
|
|
fdc_release_resources(fdc);
|
|
|
|
device_printf(dev, "unload\n");
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
/*
|
2000-01-05 16:31:27 +00:00
|
|
|
* Add a child device to the fdc controller. It will then be probed etc.
|
1993-06-12 14:58:17 +00:00
|
|
|
*/
|
1999-04-16 21:22:55 +00:00
|
|
|
static void
|
2000-01-05 16:31:27 +00:00
|
|
|
fdc_add_child(device_t dev, const char *name, int unit)
|
1999-04-16 21:22:55 +00:00
|
|
|
{
|
2000-01-05 16:31:27 +00:00
|
|
|
int disabled;
|
|
|
|
struct fdc_ivars *ivar;
|
1999-04-16 21:22:55 +00:00
|
|
|
device_t child;
|
|
|
|
|
2000-12-08 21:51:06 +00:00
|
|
|
ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO);
|
2000-01-05 16:31:27 +00:00
|
|
|
if (ivar == NULL)
|
1999-04-16 21:22:55 +00:00
|
|
|
return;
|
2000-01-05 16:31:27 +00:00
|
|
|
if (resource_int_value(name, unit, "drive", &ivar->fdunit) != 0)
|
|
|
|
ivar->fdunit = 0;
|
1999-12-03 08:41:24 +00:00
|
|
|
child = device_add_child(dev, name, unit);
|
2000-01-05 16:31:27 +00:00
|
|
|
if (child == NULL)
|
1999-04-16 21:22:55 +00:00
|
|
|
return;
|
2000-01-05 16:31:27 +00:00
|
|
|
device_set_ivars(child, ivar);
|
1999-05-31 18:39:17 +00:00
|
|
|
if (resource_int_value(name, unit, "disabled", &disabled) == 0
|
|
|
|
&& disabled != 0)
|
1999-04-16 21:22:55 +00:00
|
|
|
device_disable(child);
|
|
|
|
}
|
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
static int
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc_attach(device_t dev)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
2000-01-05 16:31:27 +00:00
|
|
|
struct fdc_data *fdc;
|
2001-06-12 09:40:04 +00:00
|
|
|
const char *name, *dname;
|
2001-07-09 21:00:02 +00:00
|
|
|
int i, error, dunit;
|
1994-10-19 00:08:07 +00:00
|
|
|
|
2000-01-05 16:31:27 +00:00
|
|
|
fdc = device_get_softc(dev);
|
|
|
|
error = fdc_alloc_resources(fdc);
|
|
|
|
if (error) {
|
2001-06-11 10:48:10 +00:00
|
|
|
device_printf(dev, "cannot re-acquire resources\n");
|
2000-01-05 16:31:27 +00:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq,
|
2001-03-03 14:53:50 +00:00
|
|
|
INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc,
|
|
|
|
&fdc->fdc_intr);
|
2000-01-05 16:31:27 +00:00
|
|
|
if (error) {
|
|
|
|
device_printf(dev, "cannot setup interrupt\n");
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
fdc->fdcu = device_get_unit(dev);
|
2001-07-08 20:50:20 +00:00
|
|
|
fdc->flags |= FDC_ATTACHED | FDC_NEEDS_RESET;
|
1999-04-16 21:22:55 +00:00
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
if ((fdc->flags & FDC_NODMA) == 0) {
|
2001-06-11 10:48:10 +00:00
|
|
|
/*
|
|
|
|
* Acquire the DMA channel forever, the driver will do
|
|
|
|
* the rest
|
|
|
|
* XXX should integrate with rman
|
|
|
|
*/
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
isa_dma_acquire(fdc->dmachan);
|
2001-06-11 10:48:10 +00:00
|
|
|
isa_dmainit(fdc->dmachan, MAX_SEC_SIZE);
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
}
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->state = DEVIDLE;
|
1999-04-16 21:22:55 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
/* reset controller, turn motor off, clear fdout mirror reg */
|
2001-06-28 12:35:28 +00:00
|
|
|
fdout_wr(fdc, fdc->fdout = 0);
|
2000-04-15 05:54:02 +00:00
|
|
|
bioq_init(&fdc->head);
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
/*
|
2000-01-05 16:31:27 +00:00
|
|
|
* Probe and attach any children. We should probably detect
|
|
|
|
* devices from the BIOS unless overridden.
|
1999-04-16 21:22:55 +00:00
|
|
|
*/
|
2000-10-15 08:50:45 +00:00
|
|
|
name = device_get_nameunit(dev);
|
2001-06-12 09:40:04 +00:00
|
|
|
i = 0;
|
|
|
|
while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0)
|
|
|
|
fdc_add_child(dev, dname, dunit);
|
2000-01-05 16:31:27 +00:00
|
|
|
|
2001-07-04 22:10:33 +00:00
|
|
|
if ((error = bus_generic_attach(dev)) != 0)
|
|
|
|
return (error);
|
|
|
|
|
|
|
|
return (0);
|
1999-04-16 21:22:55 +00:00
|
|
|
}
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1999-07-29 01:03:04 +00:00
|
|
|
static int
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc_print_child(device_t me, device_t child)
|
|
|
|
{
|
1999-07-29 01:03:04 +00:00
|
|
|
int retval = 0;
|
|
|
|
|
|
|
|
retval += bus_print_child_header(me, child);
|
|
|
|
retval += printf(" on %s drive %d\n", device_get_nameunit(me),
|
2000-01-05 16:31:27 +00:00
|
|
|
fdc_get_fdunit(child));
|
1999-07-29 01:03:04 +00:00
|
|
|
|
|
|
|
return (retval);
|
1999-04-16 21:22:55 +00:00
|
|
|
}
|
1995-01-06 15:20:00 +00:00
|
|
|
|
1999-09-03 11:32:21 +00:00
|
|
|
static device_method_t fdc_methods[] = {
|
|
|
|
/* Device interface */
|
|
|
|
DEVMETHOD(device_probe, fdc_probe),
|
|
|
|
DEVMETHOD(device_attach, fdc_attach),
|
2001-06-29 07:36:29 +00:00
|
|
|
DEVMETHOD(device_detach, fdc_detach),
|
1999-09-03 11:32:21 +00:00
|
|
|
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
|
|
|
DEVMETHOD(device_suspend, bus_generic_suspend),
|
|
|
|
DEVMETHOD(device_resume, bus_generic_resume),
|
|
|
|
|
|
|
|
/* Bus interface */
|
|
|
|
DEVMETHOD(bus_print_child, fdc_print_child),
|
2000-01-05 16:31:27 +00:00
|
|
|
DEVMETHOD(bus_read_ivar, fdc_read_ivar),
|
1999-09-03 11:32:21 +00:00
|
|
|
/* Our children never use any other bus interface methods. */
|
|
|
|
|
|
|
|
{ 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static driver_t fdc_driver = {
|
|
|
|
"fdc",
|
|
|
|
fdc_methods,
|
|
|
|
sizeof(struct fdc_data)
|
|
|
|
};
|
|
|
|
|
|
|
|
DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0);
|
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
#if NCARD > 0
|
|
|
|
|
|
|
|
static device_method_t fdc_pccard_methods[] = {
|
|
|
|
/* Device interface */
|
|
|
|
DEVMETHOD(device_probe, fdc_pccard_probe),
|
|
|
|
DEVMETHOD(device_attach, fdc_attach),
|
2001-06-29 07:36:29 +00:00
|
|
|
DEVMETHOD(device_detach, fdc_detach),
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
|
|
|
DEVMETHOD(device_suspend, bus_generic_suspend),
|
|
|
|
DEVMETHOD(device_resume, bus_generic_resume),
|
|
|
|
|
|
|
|
/* Bus interface */
|
|
|
|
DEVMETHOD(bus_print_child, fdc_print_child),
|
|
|
|
DEVMETHOD(bus_read_ivar, fdc_read_ivar),
|
|
|
|
/* Our children never use any other bus interface methods. */
|
|
|
|
|
|
|
|
{ 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static driver_t fdc_pccard_driver = {
|
|
|
|
"fdc",
|
|
|
|
fdc_pccard_methods,
|
|
|
|
sizeof(struct fdc_data)
|
|
|
|
};
|
|
|
|
|
|
|
|
DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, 0, 0);
|
|
|
|
|
|
|
|
#endif /* NCARD > 0 */
|
|
|
|
|
2000-08-20 21:34:39 +00:00
|
|
|
static struct {
|
|
|
|
char *match;
|
|
|
|
int minor;
|
|
|
|
int link;
|
|
|
|
} fd_suffix[] = {
|
2001-07-04 22:10:33 +00:00
|
|
|
/*
|
|
|
|
* Genuine clone devices must come first, and their number must
|
|
|
|
* match NCLONEDEVS above.
|
|
|
|
*/
|
2000-08-20 21:34:39 +00:00
|
|
|
{ ".1720", 1, 0 },
|
|
|
|
{ ".1480", 2, 0 },
|
|
|
|
{ ".1440", 3, 0 },
|
|
|
|
{ ".1200", 4, 0 },
|
|
|
|
{ ".820", 5, 0 },
|
|
|
|
{ ".800", 6, 0 },
|
|
|
|
{ ".720", 7, 0 },
|
|
|
|
{ ".360", 8, 0 },
|
|
|
|
{ ".640", 9, 0 },
|
|
|
|
{ ".1232", 10, 0 },
|
2001-07-04 22:10:33 +00:00
|
|
|
{ "a", 0, 1 },
|
|
|
|
{ "b", 0, 1 },
|
|
|
|
{ "c", 0, 1 },
|
|
|
|
{ "d", 0, 1 },
|
|
|
|
{ "e", 0, 1 },
|
|
|
|
{ "f", 0, 1 },
|
|
|
|
{ "g", 0, 1 },
|
|
|
|
{ "h", 0, 1 },
|
2000-08-20 21:34:39 +00:00
|
|
|
{ 0, 0 }
|
|
|
|
};
|
|
|
|
static void
|
2001-07-04 22:10:33 +00:00
|
|
|
fd_clone(void *arg, char *name, int namelen, dev_t *dev)
|
2000-08-20 21:34:39 +00:00
|
|
|
{
|
2001-07-04 22:10:33 +00:00
|
|
|
struct fd_data *fd;
|
2000-08-20 21:34:39 +00:00
|
|
|
int u, d, i;
|
|
|
|
char *n;
|
|
|
|
|
2001-07-04 22:10:33 +00:00
|
|
|
fd = (struct fd_data *)arg;
|
2000-08-20 21:34:39 +00:00
|
|
|
if (*dev != NODEV)
|
|
|
|
return;
|
2000-09-02 19:17:34 +00:00
|
|
|
if (dev_stdclone(name, &n, "fd", &u) != 2)
|
2000-08-20 21:34:39 +00:00
|
|
|
return;
|
|
|
|
for (i = 0; ; i++) {
|
|
|
|
if (fd_suffix[i].match == NULL)
|
|
|
|
return;
|
|
|
|
if (strcmp(n, fd_suffix[i].match))
|
|
|
|
continue;
|
|
|
|
d = fd_suffix[i].minor;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (fd_suffix[i].link == 0) {
|
|
|
|
*dev = make_dev(&fd_cdevsw, (u << 6) + d,
|
|
|
|
UID_ROOT, GID_OPERATOR, 0640, name);
|
2001-07-04 22:10:33 +00:00
|
|
|
fd->clonedevs[i] = *dev;
|
2000-08-20 21:34:39 +00:00
|
|
|
} else {
|
2001-07-04 22:10:33 +00:00
|
|
|
*dev = make_dev_alias(fd->masterdev, name);
|
2000-08-20 21:34:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-03 11:32:21 +00:00
|
|
|
/******************************************************************/
|
|
|
|
/*
|
|
|
|
* devices attached to the controller section.
|
|
|
|
*/
|
1999-04-16 21:22:55 +00:00
|
|
|
static int
|
|
|
|
fd_probe(device_t dev)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
u_int fdt, st0, st3;
|
|
|
|
struct fd_data *fd;
|
|
|
|
struct fdc_data *fdc;
|
|
|
|
fdsu_t fdsu;
|
|
|
|
static int fd_fifo = 0;
|
|
|
|
|
|
|
|
fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */
|
|
|
|
fd = device_get_softc(dev);
|
|
|
|
fdc = device_get_softc(device_get_parent(dev));
|
|
|
|
|
|
|
|
bzero(fd, sizeof *fd);
|
|
|
|
fd->dev = dev;
|
|
|
|
fd->fdc = fdc;
|
|
|
|
fd->fdsu = fdsu;
|
|
|
|
fd->fdu = device_get_unit(dev);
|
|
|
|
|
1999-05-31 18:39:17 +00:00
|
|
|
#ifdef __i386__
|
1999-04-16 21:22:55 +00:00
|
|
|
/* look up what bios thinks we have */
|
|
|
|
switch (fd->fdu) {
|
|
|
|
case 0:
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
if ((fdc->flags & FDC_ISPCMCIA))
|
|
|
|
fdt = RTCFDT_144M;
|
|
|
|
else if (device_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0)
|
1999-04-16 21:22:55 +00:00
|
|
|
fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED;
|
|
|
|
else
|
|
|
|
fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fdt = RTCFDT_NONE;
|
|
|
|
break;
|
|
|
|
}
|
1999-05-31 18:39:17 +00:00
|
|
|
#else
|
|
|
|
fdt = RTCFDT_144M; /* XXX probably */
|
|
|
|
#endif
|
1999-04-16 21:22:55 +00:00
|
|
|
|
|
|
|
/* is there a unit? */
|
|
|
|
if (fdt == RTCFDT_NONE)
|
|
|
|
return (ENXIO);
|
|
|
|
|
|
|
|
/* select it */
|
|
|
|
set_motor(fdc, fdsu, TURNON);
|
2001-07-08 20:50:20 +00:00
|
|
|
fdc_reset(fdc); /* XXX reset, then unreset, etc. */
|
1999-04-16 21:22:55 +00:00
|
|
|
DELAY(1000000); /* 1 sec */
|
|
|
|
|
1999-11-18 05:15:09 +00:00
|
|
|
/* XXX This doesn't work before the first set_motor() */
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN
|
1999-12-21 08:33:03 +00:00
|
|
|
&& (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0
|
1999-04-16 21:22:55 +00:00
|
|
|
&& enable_fifo(fdc) == 0) {
|
2000-01-08 09:33:09 +00:00
|
|
|
device_printf(device_get_parent(dev),
|
|
|
|
"FIFO enabled, %d bytes threshold\n", fifo_threshold);
|
1999-04-16 21:22:55 +00:00
|
|
|
}
|
|
|
|
fd_fifo = 1;
|
1995-01-06 15:20:00 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0)
|
|
|
|
&& (st3 & NE7_ST3_T0)) {
|
|
|
|
/* if at track 0, first seek inwards */
|
|
|
|
/* seek some steps: */
|
|
|
|
fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0);
|
|
|
|
DELAY(300000); /* ...wait a moment... */
|
|
|
|
fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we're at track 0 first seek inwards. */
|
|
|
|
if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) {
|
|
|
|
/* Seek some steps... */
|
|
|
|
if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
|
|
|
|
/* ...wait a moment... */
|
|
|
|
DELAY(300000);
|
|
|
|
/* make ctrlr happy: */
|
|
|
|
fd_sense_int(fdc, 0, 0);
|
1994-09-17 18:08:36 +00:00
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
}
|
1995-01-06 15:20:00 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
/*
|
|
|
|
* we must recalibrate twice, just in case the
|
|
|
|
* heads have been beyond cylinder 76, since most
|
|
|
|
* FDCs still barf when attempting to recalibrate
|
|
|
|
* more than 77 steps
|
|
|
|
*/
|
|
|
|
/* go back to 0: */
|
|
|
|
if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
|
|
|
|
/* a second being enough for full stroke seek*/
|
|
|
|
DELAY(i == 0 ? 1000000 : 300000);
|
1995-01-06 15:20:00 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
/* anything responding? */
|
|
|
|
if (fd_sense_int(fdc, &st0, 0) == 0 &&
|
|
|
|
(st0 & NE7_ST0_EC) == 0)
|
|
|
|
break; /* already probed succesfully */
|
1994-09-17 18:08:36 +00:00
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
set_motor(fdc, fdsu, TURNOFF);
|
1995-05-30 08:16:23 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
|
|
|
|
return (ENXIO);
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
fd->track = FD_NO_TRACK;
|
|
|
|
fd->fdc = fdc;
|
|
|
|
fd->fdsu = fdsu;
|
|
|
|
fd->options = 0;
|
|
|
|
callout_handle_init(&fd->toffhandle);
|
|
|
|
callout_handle_init(&fd->tohandle);
|
|
|
|
|
|
|
|
switch (fdt) {
|
|
|
|
case RTCFDT_12M:
|
|
|
|
device_set_desc(dev, "1200-KB 5.25\" drive");
|
|
|
|
fd->type = FD_1200;
|
|
|
|
break;
|
|
|
|
case RTCFDT_144M | RTCFDT_144M_PRETENDED:
|
|
|
|
device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive");
|
|
|
|
fdt = RTCFDT_144M;
|
|
|
|
fd->type = FD_1440;
|
|
|
|
case RTCFDT_144M:
|
|
|
|
device_set_desc(dev, "1440-KB 3.5\" drive");
|
|
|
|
fd->type = FD_1440;
|
|
|
|
break;
|
|
|
|
case RTCFDT_288M:
|
|
|
|
case RTCFDT_288M_1:
|
|
|
|
device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)");
|
|
|
|
fd->type = FD_1440;
|
|
|
|
break;
|
|
|
|
case RTCFDT_360K:
|
|
|
|
device_set_desc(dev, "360-KB 5.25\" drive");
|
|
|
|
fd->type = FD_360;
|
|
|
|
break;
|
|
|
|
case RTCFDT_720K:
|
|
|
|
printf("720-KB 3.5\" drive");
|
|
|
|
fd->type = FD_720;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return (ENXIO);
|
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
fd_attach(device_t dev)
|
|
|
|
{
|
|
|
|
struct fd_data *fd;
|
2001-06-28 12:35:28 +00:00
|
|
|
static int cdevsw_add_done;
|
2001-07-04 22:10:33 +00:00
|
|
|
int i;
|
1999-04-16 21:22:55 +00:00
|
|
|
|
2000-08-09 12:45:04 +00:00
|
|
|
if (!cdevsw_add_done) {
|
2000-09-02 19:17:34 +00:00
|
|
|
cdevsw_add(&fd_cdevsw); /* XXX */
|
2001-06-28 12:35:28 +00:00
|
|
|
cdevsw_add_done = 1;
|
2000-08-20 21:34:39 +00:00
|
|
|
}
|
2001-06-28 12:35:28 +00:00
|
|
|
fd = device_get_softc(dev);
|
2001-07-04 22:10:33 +00:00
|
|
|
fd->clonetag = EVENTHANDLER_REGISTER(dev_clone, fd_clone, fd, 1000);
|
2001-06-29 07:53:45 +00:00
|
|
|
fd->masterdev = make_dev(&fd_cdevsw, fd->fdu << 6,
|
|
|
|
UID_ROOT, GID_OPERATOR, 0640, "fd%d", fd->fdu);
|
2001-07-04 22:10:33 +00:00
|
|
|
for (i = 0; i < NCLONEDEVS; i++)
|
|
|
|
fd->clonedevs[i] = NODEV;
|
1999-04-16 21:22:55 +00:00
|
|
|
devstat_add_entry(&fd->device_stats, device_get_name(dev),
|
2001-06-11 10:48:10 +00:00
|
|
|
device_get_unit(dev), 0, DEVSTAT_NO_ORDERED_TAGS,
|
1999-04-16 21:22:55 +00:00
|
|
|
DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER,
|
|
|
|
DEVSTAT_PRIORITY_FD);
|
|
|
|
return (0);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
static int
|
|
|
|
fd_detach(device_t dev)
|
|
|
|
{
|
|
|
|
struct fd_data *fd;
|
2001-07-04 22:10:33 +00:00
|
|
|
int i;
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
|
|
|
|
fd = device_get_softc(dev);
|
2001-07-04 22:10:33 +00:00
|
|
|
untimeout(fd_turnoff, fd, fd->toffhandle);
|
2001-06-29 07:36:29 +00:00
|
|
|
devstat_remove_entry(&fd->device_stats);
|
|
|
|
destroy_dev(fd->masterdev);
|
2001-07-04 22:10:33 +00:00
|
|
|
for (i = 0; i < NCLONEDEVS; i++)
|
|
|
|
if (fd->clonedevs[i] != NODEV)
|
|
|
|
destroy_dev(fd->clonedevs[i]);
|
2001-06-29 07:36:29 +00:00
|
|
|
cdevsw_remove(&fd_cdevsw);
|
|
|
|
EVENTHANDLER_DEREGISTER(dev_clone, fd->clonetag);
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
1999-09-03 11:32:21 +00:00
|
|
|
static device_method_t fd_methods[] = {
|
|
|
|
/* Device interface */
|
|
|
|
DEVMETHOD(device_probe, fd_probe),
|
|
|
|
DEVMETHOD(device_attach, fd_attach),
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
DEVMETHOD(device_detach, fd_detach),
|
1999-09-03 11:32:21 +00:00
|
|
|
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
|
|
|
DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX */
|
|
|
|
DEVMETHOD(device_resume, bus_generic_resume), /* XXX */
|
|
|
|
|
|
|
|
{ 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static driver_t fd_driver = {
|
|
|
|
"fd",
|
|
|
|
fd_methods,
|
|
|
|
sizeof(struct fd_data)
|
|
|
|
};
|
|
|
|
|
1999-11-08 07:32:06 +00:00
|
|
|
DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, 0, 0);
|
1999-09-03 11:32:21 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
/****************************************************************************/
|
|
|
|
/* motor control stuff */
|
1994-11-02 09:08:40 +00:00
|
|
|
/* remember to not deselect the drive we're working on */
|
1993-06-12 14:58:17 +00:00
|
|
|
/****************************************************************************/
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
static void
|
1999-04-16 21:22:55 +00:00
|
|
|
set_motor(struct fdc_data *fdc, int fdsu, int turnon)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
2001-07-08 20:50:20 +00:00
|
|
|
int fdout;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
2001-07-08 20:50:20 +00:00
|
|
|
fdout = fdc->fdout;
|
|
|
|
if (turnon) {
|
1995-05-30 08:16:23 +00:00
|
|
|
fdout &= ~FDO_FDSEL;
|
2001-07-08 20:50:20 +00:00
|
|
|
fdout |= (FDO_MOEN0 << fdsu) | FDO_FDMAEN | FDO_FRST | fdsu;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
} else
|
|
|
|
fdout &= ~(FDO_MOEN0 << fdsu);
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc->fdout = fdout;
|
2001-07-08 20:50:20 +00:00
|
|
|
fdout_wr(fdc, fdout);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
TRACE1("[0x%x->FDOUT]", fdout);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
1993-11-25 01:38:01 +00:00
|
|
|
static void
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_turnoff(void *xfd)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
1993-09-14 19:34:32 +00:00
|
|
|
int s;
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_p fd = xfd;
|
1995-01-11 16:13:01 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
TRACE1("[fd%d: turnoff]", fd->fdu);
|
1996-02-25 21:01:31 +00:00
|
|
|
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
s = splbio();
|
1996-02-25 21:01:31 +00:00
|
|
|
/*
|
|
|
|
* Don't turn off the motor yet if the drive is active.
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
*
|
|
|
|
* If we got here, this could only mean we missed an interrupt.
|
|
|
|
* This can e. g. happen on the Y-E Date PCMCIA floppy controller
|
|
|
|
* after a controller reset. Just schedule a pseudo-interrupt
|
|
|
|
* so the state machine gets re-entered.
|
1996-02-25 21:01:31 +00:00
|
|
|
*/
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) {
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
fdc_intr(fd->fdc);
|
|
|
|
splx(s);
|
1996-02-25 21:01:31 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
fd->flags &= ~FD_MOTOR;
|
1999-04-16 21:22:55 +00:00
|
|
|
set_motor(fd->fdc, fd->fdsu, TURNOFF);
|
1993-09-14 19:34:32 +00:00
|
|
|
splx(s);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
static void
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_motor_on(void *xfd)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
1993-09-14 19:34:32 +00:00
|
|
|
int s;
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_p fd = xfd;
|
1993-09-14 19:34:32 +00:00
|
|
|
|
|
|
|
s = splbio();
|
1993-06-12 14:58:17 +00:00
|
|
|
fd->flags &= ~FD_MOTOR_WAIT;
|
|
|
|
if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT))
|
|
|
|
{
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc_intr(fd->fdc);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
1993-09-14 19:34:32 +00:00
|
|
|
splx(s);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
static void
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_turnon(fd_p fd)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
|
|
|
if(!(fd->flags & FD_MOTOR))
|
|
|
|
{
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT);
|
1999-04-16 21:22:55 +00:00
|
|
|
set_motor(fd->fdc, fd->fdsu, TURNON);
|
|
|
|
timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1993-11-25 01:38:01 +00:00
|
|
|
static void
|
1995-01-06 15:20:00 +00:00
|
|
|
fdc_reset(fdc_p fdc)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
/* Try a reset, keep motor on */
|
1999-11-11 08:48:40 +00:00
|
|
|
fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
|
|
|
|
DELAY(100);
|
|
|
|
/* enable FDC, but defer interrupts a moment */
|
1999-11-11 08:48:40 +00:00
|
|
|
fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN);
|
|
|
|
DELAY(100);
|
1999-11-11 08:48:40 +00:00
|
|
|
fdout_wr(fdc, fdc->fdout);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
TRACE1("[0x%x->FDOUT]", fdc->fdout);
|
|
|
|
|
2001-06-28 12:35:28 +00:00
|
|
|
/* XXX after a reset, silently believe the FDC will accept commands */
|
1999-04-16 21:22:55 +00:00
|
|
|
(void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
|
1995-01-06 15:20:00 +00:00
|
|
|
NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
|
|
|
|
0);
|
1997-09-17 20:16:17 +00:00
|
|
|
if (fdc->flags & FDC_HAS_FIFO)
|
|
|
|
(void) enable_fifo(fdc);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
/* fdc in/out */
|
|
|
|
/****************************************************************************/
|
1995-03-16 18:17:34 +00:00
|
|
|
static int
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_in(struct fdc_data *fdc, int *ptr)
|
1995-01-06 15:20:00 +00:00
|
|
|
{
|
|
|
|
int i, j = 100000;
|
1999-11-11 08:48:40 +00:00
|
|
|
while ((i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM))
|
1995-01-06 15:20:00 +00:00
|
|
|
!= (NE7_DIO|NE7_RQM) && j-- > 0)
|
|
|
|
if (i == NE7_RQM)
|
1999-04-16 21:22:55 +00:00
|
|
|
return fdc_err(fdc, "ready for output in input\n");
|
1995-01-06 15:20:00 +00:00
|
|
|
if (j <= 0)
|
1999-04-16 21:22:55 +00:00
|
|
|
return fdc_err(fdc, bootverbose? "input ready timeout\n": 0);
|
1997-09-16 07:45:45 +00:00
|
|
|
#ifdef FDC_DEBUG
|
1999-11-11 08:48:40 +00:00
|
|
|
i = fddata_rd(fdc);
|
1995-01-06 15:20:00 +00:00
|
|
|
TRACE1("[FDDATA->0x%x]", (unsigned char)i);
|
|
|
|
*ptr = i;
|
|
|
|
return 0;
|
1997-09-16 07:45:45 +00:00
|
|
|
#else /* !FDC_DEBUG */
|
1999-11-11 08:48:40 +00:00
|
|
|
i = fddata_rd(fdc);
|
1995-01-06 15:20:00 +00:00
|
|
|
if (ptr)
|
|
|
|
*ptr = i;
|
|
|
|
return 0;
|
1997-09-16 07:45:45 +00:00
|
|
|
#endif /* FDC_DEBUG */
|
1995-01-06 15:20:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1999-04-16 21:22:55 +00:00
|
|
|
out_fdc(struct fdc_data *fdc, int x)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
1993-08-12 09:21:20 +00:00
|
|
|
int i;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1993-08-12 09:21:20 +00:00
|
|
|
/* Check that the direction bit is set */
|
|
|
|
i = 100000;
|
1999-11-11 08:48:40 +00:00
|
|
|
while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0);
|
1999-04-16 21:22:55 +00:00
|
|
|
if (i <= 0) return fdc_err(fdc, "direction bit not set\n");
|
1993-08-12 09:21:20 +00:00
|
|
|
|
|
|
|
/* Check that the floppy controller is ready for a command */
|
|
|
|
i = 100000;
|
1999-11-11 08:48:40 +00:00
|
|
|
while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0);
|
1995-10-04 07:01:23 +00:00
|
|
|
if (i <= 0)
|
1999-04-16 21:22:55 +00:00
|
|
|
return fdc_err(fdc, bootverbose? "output ready timeout\n": 0);
|
1993-08-12 09:21:20 +00:00
|
|
|
|
|
|
|
/* Send the command and return */
|
1999-11-11 08:48:40 +00:00
|
|
|
fddata_wr(fdc, x);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
TRACE1("[0x%x->FDDATA]", x);
|
1993-06-12 14:58:17 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
/* fdopen/fdclose */
|
|
|
|
/****************************************************************************/
|
1993-11-25 01:38:01 +00:00
|
|
|
int
|
1995-02-26 01:37:51 +00:00
|
|
|
Fdopen(dev_t dev, int flags, int mode, struct proc *p)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
|
|
|
fdu_t fdu = FDUNIT(minor(dev));
|
1993-12-12 16:46:54 +00:00
|
|
|
int type = FDTYPE(minor(dev));
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_p fd;
|
1994-02-07 04:27:13 +00:00
|
|
|
fdc_p fdc;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
|
|
|
/* check bounds */
|
1999-04-16 21:22:55 +00:00
|
|
|
if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0)
|
|
|
|
return (ENXIO);
|
|
|
|
fdc = fd->fdc;
|
|
|
|
if ((fdc == NULL) || (fd->type == NO_TYPE))
|
|
|
|
return (ENXIO);
|
1994-02-07 04:27:13 +00:00
|
|
|
if (type > NUMDENS)
|
1999-04-16 21:22:55 +00:00
|
|
|
return (ENXIO);
|
1993-12-16 04:28:42 +00:00
|
|
|
if (type == 0)
|
1999-04-16 21:22:55 +00:00
|
|
|
type = fd->type;
|
1993-12-16 04:28:42 +00:00
|
|
|
else {
|
1998-04-19 23:32:49 +00:00
|
|
|
/*
|
|
|
|
* For each type of basic drive, make sure we are trying
|
|
|
|
* to open a type it can do,
|
|
|
|
*/
|
1999-04-16 21:22:55 +00:00
|
|
|
if (type != fd->type) {
|
|
|
|
switch (fd->type) {
|
1993-12-16 04:28:42 +00:00
|
|
|
case FD_360:
|
1999-04-16 21:22:55 +00:00
|
|
|
return (ENXIO);
|
1993-12-18 01:16:26 +00:00
|
|
|
case FD_720:
|
1993-12-19 00:40:49 +00:00
|
|
|
if ( type != FD_820
|
|
|
|
&& type != FD_800
|
1999-12-28 07:38:38 +00:00
|
|
|
&& type != FD_640
|
1993-12-19 00:40:49 +00:00
|
|
|
)
|
1999-04-16 21:22:55 +00:00
|
|
|
return (ENXIO);
|
1993-12-18 01:16:26 +00:00
|
|
|
break;
|
1993-12-16 04:28:42 +00:00
|
|
|
case FD_1200:
|
1993-12-19 00:40:49 +00:00
|
|
|
switch (type) {
|
|
|
|
case FD_1480:
|
|
|
|
type = FD_1480in5_25;
|
|
|
|
break;
|
|
|
|
case FD_1440:
|
|
|
|
type = FD_1440in5_25;
|
|
|
|
break;
|
1999-12-28 07:38:38 +00:00
|
|
|
case FD_1232:
|
|
|
|
break;
|
1993-12-19 00:40:49 +00:00
|
|
|
case FD_820:
|
|
|
|
type = FD_820in5_25;
|
|
|
|
break;
|
|
|
|
case FD_800:
|
|
|
|
type = FD_800in5_25;
|
|
|
|
break;
|
|
|
|
case FD_720:
|
|
|
|
type = FD_720in5_25;
|
|
|
|
break;
|
1999-12-28 07:38:38 +00:00
|
|
|
case FD_640:
|
|
|
|
type = FD_640in5_25;
|
|
|
|
break;
|
1993-12-19 00:40:49 +00:00
|
|
|
case FD_360:
|
|
|
|
type = FD_360in5_25;
|
|
|
|
break;
|
|
|
|
default:
|
1993-12-16 04:28:42 +00:00
|
|
|
return(ENXIO);
|
1993-12-19 00:40:49 +00:00
|
|
|
}
|
1993-12-16 04:28:42 +00:00
|
|
|
break;
|
|
|
|
case FD_1440:
|
1993-12-19 00:40:49 +00:00
|
|
|
if ( type != FD_1720
|
|
|
|
&& type != FD_1480
|
|
|
|
&& type != FD_1200
|
|
|
|
&& type != FD_820
|
|
|
|
&& type != FD_800
|
|
|
|
&& type != FD_720
|
1999-12-28 07:38:38 +00:00
|
|
|
&& type != FD_640
|
1993-12-19 00:40:49 +00:00
|
|
|
)
|
1993-12-16 04:28:42 +00:00
|
|
|
return(ENXIO);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1993-12-13 01:34:28 +00:00
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
fd->ft = fd_types + type - 1;
|
|
|
|
fd->flags |= FD_OPEN;
|
2001-07-09 20:46:45 +00:00
|
|
|
/*
|
|
|
|
* Clearing the DMA overrun counter at open time is a bit messy.
|
|
|
|
* Since we're only managing one counter per controller, opening
|
|
|
|
* the second drive could mess it up. Anyway, if the DMA overrun
|
|
|
|
* condition is really persistent, it will eventually time out
|
|
|
|
* still. OTOH, clearing it here will ensure we'll at least start
|
|
|
|
* trying again after a previous (maybe even long ago) failure.
|
|
|
|
* Also, this is merely a stop-gap measure only that should not
|
|
|
|
* happen during normal operation, so we can tolerate it to be a
|
|
|
|
* bit sloppy about this.
|
|
|
|
*/
|
|
|
|
fdc->dma_overruns = 0;
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1993-11-25 01:38:01 +00:00
|
|
|
int
|
1995-02-26 01:37:51 +00:00
|
|
|
fdclose(dev_t dev, int flags, int mode, struct proc *p)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
|
|
|
fdu_t fdu = FDUNIT(minor(dev));
|
1999-04-16 21:22:55 +00:00
|
|
|
struct fd_data *fd;
|
1994-02-07 04:27:13 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
fd = devclass_get_softc(fd_devclass, fdu);
|
|
|
|
fd->flags &= ~FD_OPEN;
|
2001-05-14 20:20:11 +00:00
|
|
|
fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR);
|
1995-01-11 16:13:01 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
return (0);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
/****************************************************************************/
|
|
|
|
/* fdstrategy */
|
|
|
|
/****************************************************************************/
|
|
|
|
void
|
2000-04-15 05:54:02 +00:00
|
|
|
fdstrategy(struct bio *bp)
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
{
|
2001-07-08 20:50:20 +00:00
|
|
|
long blknum, nblocks;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
int s;
|
|
|
|
fdu_t fdu;
|
|
|
|
fdc_p fdc;
|
|
|
|
fd_p fd;
|
|
|
|
size_t fdblk;
|
|
|
|
|
2000-04-15 05:54:02 +00:00
|
|
|
fdu = FDUNIT(minor(bp->bio_dev));
|
1999-04-16 21:22:55 +00:00
|
|
|
fd = devclass_get_softc(fd_devclass, fdu);
|
|
|
|
if (fd == 0)
|
|
|
|
panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)",
|
2000-04-15 05:54:02 +00:00
|
|
|
(u_long)major(bp->bio_dev), (u_long)minor(bp->bio_dev));
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fdc = fd->fdc;
|
1998-12-12 08:16:01 +00:00
|
|
|
if (fd->type == NO_TYPE) {
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_error = ENXIO;
|
|
|
|
bp->bio_flags |= BIO_ERROR;
|
2000-01-06 07:13:54 +00:00
|
|
|
goto bad;
|
2001-06-28 12:35:28 +00:00
|
|
|
}
|
1995-06-11 19:33:05 +00:00
|
|
|
fdblk = 128 << (fd->ft->secsize);
|
2001-06-29 15:30:48 +00:00
|
|
|
if (bp->bio_cmd != BIO_FORMAT && bp->bio_cmd != BIO_RDSECTID) {
|
2000-04-15 05:54:02 +00:00
|
|
|
if (bp->bio_blkno < 0) {
|
1995-01-06 15:20:00 +00:00
|
|
|
printf(
|
1995-03-26 19:28:22 +00:00
|
|
|
"fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n",
|
2000-04-15 05:54:02 +00:00
|
|
|
fdu, (u_long)bp->bio_blkno, bp->bio_bcount);
|
|
|
|
bp->bio_error = EINVAL;
|
|
|
|
bp->bio_flags |= BIO_ERROR;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
goto bad;
|
|
|
|
}
|
2000-04-15 05:54:02 +00:00
|
|
|
if ((bp->bio_bcount % fdblk) != 0) {
|
|
|
|
bp->bio_error = EINVAL;
|
|
|
|
bp->bio_flags |= BIO_ERROR;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
goto bad;
|
|
|
|
}
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
/*
|
|
|
|
* Set up block calculations.
|
|
|
|
*/
|
2000-04-15 05:54:02 +00:00
|
|
|
if (bp->bio_blkno > 20000000) {
|
1996-11-02 23:31:11 +00:00
|
|
|
/*
|
|
|
|
* Reject unreasonably high block number, prevent the
|
|
|
|
* multiplication below from overflowing.
|
|
|
|
*/
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_error = EINVAL;
|
|
|
|
bp->bio_flags |= BIO_ERROR;
|
1996-11-02 23:31:11 +00:00
|
|
|
goto bad;
|
|
|
|
}
|
2001-07-08 20:50:20 +00:00
|
|
|
blknum = bp->bio_blkno * DEV_BSIZE / fdblk;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
nblocks = fd->ft->size;
|
2001-07-08 20:50:20 +00:00
|
|
|
if (blknum + bp->bio_bcount / fdblk > nblocks) {
|
|
|
|
if (blknum >= nblocks) {
|
|
|
|
if (bp->bio_cmd == BIO_READ)
|
|
|
|
bp->bio_resid = bp->bio_bcount;
|
|
|
|
else {
|
|
|
|
bp->bio_error = ENOSPC;
|
|
|
|
bp->bio_flags |= BIO_ERROR;
|
|
|
|
}
|
|
|
|
goto bad; /* not always bad, but EOF */
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
}
|
2001-07-08 20:50:20 +00:00
|
|
|
bp->bio_bcount = (nblocks - blknum) * fdblk;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
}
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_pblkno = bp->bio_blkno;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
s = splbio();
|
2000-04-15 05:54:02 +00:00
|
|
|
bioqdisksort(&fdc->head, bp);
|
1999-04-16 21:22:55 +00:00
|
|
|
untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */
|
1998-09-15 08:15:30 +00:00
|
|
|
devstat_start_transaction(&fd->device_stats);
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
device_busy(fd->dev);
|
1999-04-16 21:22:55 +00:00
|
|
|
fdstart(fdc);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
splx(s);
|
|
|
|
return;
|
|
|
|
|
|
|
|
bad:
|
|
|
|
biodone(bp);
|
|
|
|
}
|
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
/***************************************************************\
|
|
|
|
* fdstart *
|
|
|
|
* We have just queued something.. if the controller is not busy *
|
|
|
|
* then simulate the case where it has just finished a command *
|
|
|
|
* So that it (the interrupt routine) looks on the queue for more*
|
|
|
|
* work to do and picks up what we just added. *
|
|
|
|
* If the controller is already busy, we need do nothing, as it *
|
|
|
|
* will pick up our work when the present work completes *
|
|
|
|
\***************************************************************/
|
1993-11-25 01:38:01 +00:00
|
|
|
static void
|
1999-04-16 21:22:55 +00:00
|
|
|
fdstart(struct fdc_data *fdc)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
|
|
|
int s;
|
|
|
|
|
|
|
|
s = splbio();
|
1999-04-16 21:22:55 +00:00
|
|
|
if(fdc->state == DEVIDLE)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc_intr(fdc);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
splx(s);
|
|
|
|
}
|
|
|
|
|
1993-11-25 01:38:01 +00:00
|
|
|
static void
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_iotimeout(void *xfdc)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
1998-07-29 13:00:42 +00:00
|
|
|
fdc_p fdc;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
int s;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc = xfdc;
|
1998-07-29 13:00:42 +00:00
|
|
|
TRACE1("fd%d[fd_iotimeout()]", fdc->fdu);
|
1993-06-12 14:58:17 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
/*
|
|
|
|
* Due to IBM's brain-dead design, the FDC has a faked ready
|
|
|
|
* signal, hardwired to ready == true. Thus, any command
|
|
|
|
* issued if there's no diskette in the drive will _never_
|
|
|
|
* complete, and must be aborted by resetting the FDC.
|
|
|
|
* Many thanks, Big Blue!
|
1998-07-29 13:00:42 +00:00
|
|
|
* The FDC must not be reset directly, since that would
|
|
|
|
* interfere with the state machine. Instead, pretend that
|
|
|
|
* the command completed but was invalid. The state machine
|
|
|
|
* will reset the FDC and retry once.
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
*/
|
|
|
|
s = splbio();
|
1998-07-29 13:00:42 +00:00
|
|
|
fdc->status[0] = NE7_ST0_IC_IV;
|
|
|
|
fdc->flags &= ~FDC_STAT_VALID;
|
|
|
|
fdc->state = IOTIMEDOUT;
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc_intr(fdc);
|
1993-09-14 19:34:32 +00:00
|
|
|
splx(s);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* just ensure it has the right spl */
|
1993-11-25 01:38:01 +00:00
|
|
|
static void
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_pseudointr(void *xfdc)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
|
|
|
int s;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
s = splbio();
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc_intr(xfdc);
|
1993-06-12 14:58:17 +00:00
|
|
|
splx(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************\
|
2001-06-28 12:35:28 +00:00
|
|
|
* fdc_intr *
|
1993-06-12 14:58:17 +00:00
|
|
|
* keep calling the state machine until it returns a 0 *
|
|
|
|
* ALWAYS called at SPLBIO *
|
|
|
|
\***********************************************************************/
|
1998-10-22 05:58:45 +00:00
|
|
|
static void
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc_intr(void *xfdc)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
1999-04-16 21:22:55 +00:00
|
|
|
fdc_p fdc = xfdc;
|
|
|
|
while(fdstate(fdc))
|
|
|
|
;
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
1998-12-12 08:16:01 +00:00
|
|
|
/*
|
|
|
|
* magic pseudo-DMA initialization for YE FDC. Sets count and
|
|
|
|
* direction
|
|
|
|
*/
|
2000-01-06 07:13:54 +00:00
|
|
|
#define SET_BCDR(fdc,wr,cnt,port) \
|
|
|
|
bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port, \
|
|
|
|
((cnt)-1) & 0xff); \
|
|
|
|
bus_space_write_1(fdc->portt, fdc->porth, fdc->port_off + port + 1, \
|
|
|
|
((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f)));
|
1998-12-12 08:16:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* fdcpio(): perform programmed IO read/write for YE PCMCIA floppy
|
|
|
|
*/
|
2001-06-26 22:07:25 +00:00
|
|
|
static int
|
|
|
|
fdcpio(fdc_p fdc, long flags, caddr_t addr, u_int count)
|
1998-12-12 08:16:01 +00:00
|
|
|
{
|
|
|
|
u_char *cptr = (u_char *)addr;
|
|
|
|
|
2000-03-20 10:44:49 +00:00
|
|
|
if (flags == BIO_READ) {
|
1998-12-12 08:16:01 +00:00
|
|
|
if (fdc->state != PIOREAD) {
|
|
|
|
fdc->state = PIOREAD;
|
|
|
|
return(0);
|
2001-06-28 12:35:28 +00:00
|
|
|
}
|
2000-01-06 07:13:54 +00:00
|
|
|
SET_BCDR(fdc, 0, count, 0);
|
|
|
|
bus_space_read_multi_1(fdc->portt, fdc->porth, fdc->port_off +
|
|
|
|
FDC_YE_DATAPORT, cptr, count);
|
1998-12-12 08:16:01 +00:00
|
|
|
} else {
|
2000-01-06 07:13:54 +00:00
|
|
|
bus_space_write_multi_1(fdc->portt, fdc->porth, fdc->port_off +
|
|
|
|
FDC_YE_DATAPORT, cptr, count);
|
|
|
|
SET_BCDR(fdc, 0, count, 0);
|
2001-06-28 12:35:28 +00:00
|
|
|
}
|
1998-12-12 08:16:01 +00:00
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
/***********************************************************************\
|
|
|
|
* The controller state machine. *
|
|
|
|
* if it returns a non zero value, it should be called again immediatly *
|
|
|
|
\***********************************************************************/
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
static int
|
1999-04-16 21:22:55 +00:00
|
|
|
fdstate(fdc_p fdc)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
2001-06-28 12:35:28 +00:00
|
|
|
struct fdc_readid *idp;
|
2001-07-08 20:50:20 +00:00
|
|
|
int read, format, rdsectid, cylinder, head, i, sec = 0, sectrac;
|
|
|
|
int st0, cyl, st3, idf;
|
|
|
|
unsigned long blknum;
|
1993-06-12 14:58:17 +00:00
|
|
|
fdu_t fdu = fdc->fdu;
|
|
|
|
fd_p fd;
|
2000-04-15 05:54:02 +00:00
|
|
|
register struct bio *bp;
|
1993-12-19 00:40:49 +00:00
|
|
|
struct fd_formb *finfo = NULL;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
size_t fdblk;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1999-01-15 09:15:27 +00:00
|
|
|
bp = fdc->bp;
|
|
|
|
if (bp == NULL) {
|
2000-04-15 05:54:02 +00:00
|
|
|
bp = bioq_first(&fdc->head);
|
1999-01-15 09:15:27 +00:00
|
|
|
if (bp != NULL) {
|
2000-04-15 05:54:02 +00:00
|
|
|
bioq_remove(&fdc->head, bp);
|
1999-01-15 09:15:27 +00:00
|
|
|
fdc->bp = bp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (bp == NULL) {
|
1993-06-12 14:58:17 +00:00
|
|
|
/***********************************************\
|
|
|
|
* nothing left for this controller to do *
|
|
|
|
* Force into the IDLE state, *
|
|
|
|
\***********************************************/
|
|
|
|
fdc->state = DEVIDLE;
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fdc->fd) {
|
2000-01-08 09:33:09 +00:00
|
|
|
device_printf(fdc->fdc_dev,
|
|
|
|
"unexpected valid fd pointer\n");
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->fd = (fd_p) 0;
|
|
|
|
fdc->fdu = -1;
|
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
TRACE1("[fdc%d IDLE]", fdc->fdcu);
|
|
|
|
return (0);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
2000-04-15 05:54:02 +00:00
|
|
|
fdu = FDUNIT(minor(bp->bio_dev));
|
1999-04-16 21:22:55 +00:00
|
|
|
fd = devclass_get_softc(fd_devclass, fdu);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fdblk = 128 << fd->ft->secsize;
|
2000-01-08 09:33:09 +00:00
|
|
|
if (fdc->fd && (fd != fdc->fd))
|
|
|
|
device_printf(fd->dev, "confused fd pointers\n");
|
2000-04-15 05:54:02 +00:00
|
|
|
read = bp->bio_cmd == BIO_READ;
|
2000-03-25 21:20:23 +00:00
|
|
|
if (read)
|
|
|
|
idf = ISADMA_READ;
|
|
|
|
else
|
|
|
|
idf = ISADMA_WRITE;
|
2001-06-28 12:35:28 +00:00
|
|
|
format = bp->bio_cmd == BIO_FORMAT;
|
2001-06-29 15:30:48 +00:00
|
|
|
rdsectid = bp->bio_cmd == BIO_RDSECTID;
|
2001-07-08 20:50:20 +00:00
|
|
|
if (format)
|
2000-04-15 05:54:02 +00:00
|
|
|
finfo = (struct fd_formb *)bp->bio_data;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
TRACE1("fd%d", fdu);
|
|
|
|
TRACE1("[%s]", fdstates[fdc->state]);
|
|
|
|
TRACE1("(0x%x)", fd->flags);
|
1999-04-16 21:22:55 +00:00
|
|
|
untimeout(fd_turnoff, fd, fd->toffhandle);
|
|
|
|
fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);
|
1993-06-12 14:58:17 +00:00
|
|
|
switch (fdc->state)
|
|
|
|
{
|
|
|
|
case DEVIDLE:
|
|
|
|
case FINDWORK: /* we have found new work */
|
|
|
|
fdc->retry = 0;
|
|
|
|
fd->skip = 0;
|
|
|
|
fdc->fd = fd;
|
|
|
|
fdc->fdu = fdu;
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
fdc->fdctl_wr(fdc, fd->ft->trans);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
TRACE1("[0x%x->FDCTL]", fd->ft->trans);
|
1993-06-12 14:58:17 +00:00
|
|
|
/*******************************************************\
|
|
|
|
* If the next drive has a motor startup pending, then *
|
2001-06-28 12:35:28 +00:00
|
|
|
* it will start up in its own good time *
|
1993-06-12 14:58:17 +00:00
|
|
|
\*******************************************************/
|
1999-04-16 21:22:55 +00:00
|
|
|
if(fd->flags & FD_MOTOR_WAIT) {
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->state = MOTORWAIT;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (0); /* come back later */
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
/*******************************************************\
|
|
|
|
* Maybe if it's not starting, it SHOULD be starting *
|
|
|
|
\*******************************************************/
|
|
|
|
if (!(fd->flags & FD_MOTOR))
|
|
|
|
{
|
|
|
|
fdc->state = MOTORWAIT;
|
1999-04-16 21:22:55 +00:00
|
|
|
fd_turnon(fd);
|
|
|
|
return (0);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
else /* at least make sure we are selected */
|
|
|
|
{
|
1999-04-16 21:22:55 +00:00
|
|
|
set_motor(fdc, fd->fdsu, TURNON);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
1998-07-29 13:00:42 +00:00
|
|
|
if (fdc->flags & FDC_NEEDS_RESET) {
|
|
|
|
fdc->state = RESETCTLR;
|
|
|
|
fdc->flags &= ~FDC_NEEDS_RESET;
|
|
|
|
} else
|
|
|
|
fdc->state = DOSEEK;
|
2001-07-08 20:50:20 +00:00
|
|
|
return (1); /* come back immediately */
|
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
case DOSEEK:
|
2001-07-08 20:50:20 +00:00
|
|
|
blknum = bp->bio_pblkno + fd->skip / fdblk;
|
|
|
|
cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
|
|
|
|
if (cylinder == fd->track)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
|
|
|
fdc->state = SEEKCOMPLETE;
|
2001-07-08 20:50:20 +00:00
|
|
|
return (1); /* come back immediately */
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fd_cmd(fdc, 3, NE7CMD_SEEK,
|
2001-07-08 20:50:20 +00:00
|
|
|
fd->fdsu, cylinder * fd->ft->steptrac,
|
1995-01-06 15:20:00 +00:00
|
|
|
0))
|
1994-10-21 16:58:50 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* seek command not accepted, looks like
|
|
|
|
* the FDC went off to the Saints...
|
|
|
|
*/
|
|
|
|
fdc->retry = 6; /* try a reset */
|
1999-04-16 21:22:55 +00:00
|
|
|
return(retrier(fdc));
|
1994-10-21 16:58:50 +00:00
|
|
|
}
|
1995-01-06 15:20:00 +00:00
|
|
|
fd->track = FD_NO_TRACK;
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->state = SEEKWAIT;
|
|
|
|
return(0); /* will return later */
|
2001-07-08 20:50:20 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
case SEEKWAIT:
|
|
|
|
/* allow heads to settle */
|
1999-04-16 21:22:55 +00:00
|
|
|
timeout(fd_pseudointr, fdc, hz / 16);
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->state = SEEKCOMPLETE;
|
|
|
|
return(0); /* will return later */
|
2001-07-08 20:50:20 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
case SEEKCOMPLETE : /* SEEK DONE, START DMA */
|
2001-07-08 20:50:20 +00:00
|
|
|
blknum = bp->bio_pblkno + fd->skip / fdblk;
|
|
|
|
cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
|
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
/* Make sure seek really happened*/
|
1999-04-16 21:22:55 +00:00
|
|
|
if(fd->track == FD_NO_TRACK) {
|
2001-07-08 20:50:20 +00:00
|
|
|
int descyl = cylinder * fd->ft->steptrac;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
do {
|
|
|
|
/*
|
1995-01-06 15:20:00 +00:00
|
|
|
* This might be a "ready changed" interrupt,
|
|
|
|
* which cannot really happen since the
|
|
|
|
* RDY pin is hardwired to + 5 volts. This
|
|
|
|
* generally indicates a "bouncing" intr
|
|
|
|
* line, so do one of the following:
|
|
|
|
*
|
|
|
|
* When running on an enhanced FDC that is
|
|
|
|
* known to not go stuck after responding
|
|
|
|
* with INVALID, fetch all interrupt states
|
|
|
|
* until seeing either an INVALID or a
|
|
|
|
* real interrupt condition.
|
|
|
|
*
|
|
|
|
* When running on a dumb old NE765, give
|
|
|
|
* up immediately. The controller will
|
|
|
|
* provide up to four dummy RC interrupt
|
|
|
|
* conditions right after reset (for the
|
|
|
|
* corresponding four drives), so this is
|
|
|
|
* our only chance to get notice that it
|
|
|
|
* was not the FDC that caused the interrupt.
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
*/
|
1995-01-06 15:20:00 +00:00
|
|
|
if (fd_sense_int(fdc, &st0, &cyl)
|
|
|
|
== FD_NOT_VALID)
|
|
|
|
return 0;
|
|
|
|
if(fdc->fdct == FDC_NE765
|
|
|
|
&& (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
|
|
|
|
return 0; /* hope for a real intr */
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
} while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
|
1995-01-06 15:20:00 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if (0 == descyl) {
|
1995-01-06 15:20:00 +00:00
|
|
|
int failed = 0;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
/*
|
|
|
|
* seek to cyl 0 requested; make sure we are
|
|
|
|
* really there
|
|
|
|
*/
|
1995-01-06 15:20:00 +00:00
|
|
|
if (fd_sense_drive_status(fdc, &st3))
|
|
|
|
failed = 1;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
if ((st3 & NE7_ST3_T0) == 0) {
|
|
|
|
printf(
|
|
|
|
"fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n",
|
|
|
|
fdu, st3, NE7_ST3BITS);
|
1995-01-06 15:20:00 +00:00
|
|
|
failed = 1;
|
|
|
|
}
|
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if (failed) {
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
if(fdc->retry < 3)
|
|
|
|
fdc->retry = 3;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (retrier(fdc));
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
}
|
|
|
|
}
|
1995-01-06 15:20:00 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if (cyl != descyl) {
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
printf(
|
|
|
|
"fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
|
1995-05-09 12:26:00 +00:00
|
|
|
fdu, descyl, cyl, st0);
|
1998-07-18 03:15:33 +00:00
|
|
|
if (fdc->retry < 3)
|
|
|
|
fdc->retry = 3;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (retrier(fdc));
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-08 20:50:20 +00:00
|
|
|
fd->track = cylinder;
|
|
|
|
if (format)
|
|
|
|
fd->skip = (char *)&(finfo->fd_formb_cylno(0))
|
|
|
|
- (char *)finfo;
|
2001-06-26 22:16:30 +00:00
|
|
|
if (!rdsectid && !(fdc->flags & FDC_NODMA))
|
2000-04-15 05:54:02 +00:00
|
|
|
isa_dmastart(idf, bp->bio_data+fd->skip,
|
|
|
|
format ? bp->bio_bcount : fdblk, fdc->dmachan);
|
2001-07-08 20:50:20 +00:00
|
|
|
blknum = bp->bio_pblkno + fd->skip / fdblk;
|
1993-06-12 14:58:17 +00:00
|
|
|
sectrac = fd->ft->sectrac;
|
|
|
|
sec = blknum % (sectrac * fd->ft->heads);
|
|
|
|
head = sec / sectrac;
|
|
|
|
sec = sec % sectrac + 1;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fd->hddrv = ((head&1)<<2)+fdu;
|
|
|
|
|
2001-06-26 22:16:30 +00:00
|
|
|
if(format || !(read || rdsectid))
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
{
|
|
|
|
/* make sure the drive is writable */
|
1995-01-06 15:20:00 +00:00
|
|
|
if(fd_sense_drive_status(fdc, &st3) != 0)
|
1994-10-21 16:58:50 +00:00
|
|
|
{
|
|
|
|
/* stuck controller? */
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
if (!(fdc->flags & FDC_NODMA))
|
2000-03-25 21:20:23 +00:00
|
|
|
isa_dmadone(idf,
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_data + fd->skip,
|
|
|
|
format ? bp->bio_bcount : fdblk,
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
fdc->dmachan);
|
1994-10-21 16:58:50 +00:00
|
|
|
fdc->retry = 6; /* reset the beast */
|
1999-04-16 21:22:55 +00:00
|
|
|
return (retrier(fdc));
|
1994-10-21 16:58:50 +00:00
|
|
|
}
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
if(st3 & NE7_ST3_WP)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* XXX YES! this is ugly.
|
|
|
|
* in order to force the current operation
|
|
|
|
* to fail, we will have to fake an FDC
|
|
|
|
* error - all error handling is done
|
|
|
|
* by the retrier()
|
|
|
|
*/
|
|
|
|
fdc->status[0] = NE7_ST0_IC_AT;
|
|
|
|
fdc->status[1] = NE7_ST1_NW;
|
|
|
|
fdc->status[2] = 0;
|
|
|
|
fdc->status[3] = fd->track;
|
|
|
|
fdc->status[4] = head;
|
|
|
|
fdc->status[5] = sec;
|
|
|
|
fdc->retry = 8; /* break out immediately */
|
|
|
|
fdc->state = IOTIMEDOUT; /* not really... */
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
}
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
if (format) {
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
if (fdc->flags & FDC_NODMA) {
|
|
|
|
/*
|
|
|
|
* This seems to be necessary for
|
|
|
|
* whatever obscure reason; if we omit
|
|
|
|
* it, we end up filling the sector ID
|
|
|
|
* fields of the newly formatted track
|
|
|
|
* entirely with garbage, causing
|
|
|
|
* `wrong cylinder' errors all over
|
|
|
|
* the place when trying to read them
|
|
|
|
* back.
|
|
|
|
*
|
|
|
|
* Umpf.
|
|
|
|
*/
|
2000-04-15 05:54:02 +00:00
|
|
|
SET_BCDR(fdc, 1, bp->bio_bcount, 0);
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
|
2000-04-15 05:54:02 +00:00
|
|
|
(void)fdcpio(fdc,bp->bio_cmd,
|
|
|
|
bp->bio_data+fd->skip,
|
|
|
|
bp->bio_bcount);
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
|
|
|
|
}
|
1993-12-19 00:40:49 +00:00
|
|
|
/* formatting */
|
1999-04-16 21:22:55 +00:00
|
|
|
if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu,
|
1995-01-06 15:20:00 +00:00
|
|
|
finfo->fd_formb_secshift,
|
|
|
|
finfo->fd_formb_nsecs,
|
|
|
|
finfo->fd_formb_gaplen,
|
1999-04-16 21:22:55 +00:00
|
|
|
finfo->fd_formb_fillbyte, 0)) {
|
1994-10-21 16:58:50 +00:00
|
|
|
/* controller fell over */
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
if (!(fdc->flags & FDC_NODMA))
|
2000-03-25 21:20:23 +00:00
|
|
|
isa_dmadone(idf,
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_data + fd->skip,
|
|
|
|
format ? bp->bio_bcount : fdblk,
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
fdc->dmachan);
|
1994-10-21 16:58:50 +00:00
|
|
|
fdc->retry = 6;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (retrier(fdc));
|
1994-10-21 16:58:50 +00:00
|
|
|
}
|
2001-06-26 22:16:30 +00:00
|
|
|
} else if (rdsectid) {
|
|
|
|
if (fd_cmd(fdc, 2, NE7CMD_READID, head << 2 | fdu, 0)) {
|
|
|
|
/* controller jamming */
|
|
|
|
fdc->retry = 6;
|
|
|
|
return (retrier(fdc));
|
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
} else {
|
2001-06-26 22:16:30 +00:00
|
|
|
/* read or write operation */
|
2000-01-06 07:13:54 +00:00
|
|
|
if (fdc->flags & FDC_NODMA) {
|
1998-12-12 08:16:01 +00:00
|
|
|
/*
|
|
|
|
* this seems to be necessary even when
|
|
|
|
* reading data
|
|
|
|
*/
|
2000-01-06 07:13:54 +00:00
|
|
|
SET_BCDR(fdc, 1, fdblk, 0);
|
1998-12-12 08:16:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* perform the write pseudo-DMA before
|
|
|
|
* the WRITE command is sent
|
|
|
|
*/
|
|
|
|
if (!read)
|
2000-04-15 05:54:02 +00:00
|
|
|
(void)fdcpio(fdc,bp->bio_cmd,
|
|
|
|
bp->bio_data+fd->skip,
|
1998-12-12 08:16:01 +00:00
|
|
|
fdblk);
|
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fd_cmd(fdc, 9,
|
1995-01-06 15:20:00 +00:00
|
|
|
(read ? NE7CMD_READ : NE7CMD_WRITE),
|
|
|
|
head << 2 | fdu, /* head & unit */
|
|
|
|
fd->track, /* track */
|
|
|
|
head,
|
|
|
|
sec, /* sector + 1 */
|
|
|
|
fd->ft->secsize, /* sector size */
|
|
|
|
sectrac, /* sectors/track */
|
|
|
|
fd->ft->gap, /* gap size */
|
|
|
|
fd->ft->datalen, /* data length */
|
1999-04-16 21:22:55 +00:00
|
|
|
0)) {
|
1994-10-21 16:58:50 +00:00
|
|
|
/* the beast is sleeping again */
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
if (!(fdc->flags & FDC_NODMA))
|
2000-03-25 21:20:23 +00:00
|
|
|
isa_dmadone(idf,
|
2000-04-15 05:54:02 +00:00
|
|
|
bp->bio_data + fd->skip,
|
|
|
|
format ? bp->bio_bcount : fdblk,
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
fdc->dmachan);
|
1994-10-21 16:58:50 +00:00
|
|
|
fdc->retry = 6;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (retrier(fdc));
|
1993-12-19 00:40:49 +00:00
|
|
|
}
|
|
|
|
}
|
2001-06-26 22:16:30 +00:00
|
|
|
if (!rdsectid && (fdc->flags & FDC_NODMA))
|
1998-12-12 08:16:01 +00:00
|
|
|
/*
|
|
|
|
* if this is a read, then simply await interrupt
|
|
|
|
* before performing PIO
|
|
|
|
*/
|
2000-04-15 05:54:02 +00:00
|
|
|
if (read && !fdcpio(fdc,bp->bio_cmd,
|
|
|
|
bp->bio_data+fd->skip,fdblk)) {
|
2000-01-06 07:13:54 +00:00
|
|
|
fd->tohandle = timeout(fd_iotimeout, fdc, hz);
|
1998-12-12 08:16:01 +00:00
|
|
|
return(0); /* will return later */
|
2001-06-28 12:35:28 +00:00
|
|
|
}
|
1998-12-12 08:16:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* write (or format) operation will fall through and
|
|
|
|
* await completion interrupt
|
|
|
|
*/
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->state = IOCOMPLETE;
|
1999-04-16 21:22:55 +00:00
|
|
|
fd->tohandle = timeout(fd_iotimeout, fdc, hz);
|
|
|
|
return (0); /* will return later */
|
2001-07-08 20:50:20 +00:00
|
|
|
|
1998-12-12 08:16:01 +00:00
|
|
|
case PIOREAD:
|
|
|
|
/*
|
|
|
|
* actually perform the PIO read. The IOCOMPLETE case
|
|
|
|
* removes the timeout for us.
|
|
|
|
*/
|
2000-04-15 05:54:02 +00:00
|
|
|
(void)fdcpio(fdc,bp->bio_cmd,bp->bio_data+fd->skip,fdblk);
|
1998-12-12 08:16:01 +00:00
|
|
|
fdc->state = IOCOMPLETE;
|
|
|
|
/* FALLTHROUGH */
|
1993-06-12 14:58:17 +00:00
|
|
|
case IOCOMPLETE: /* IO DONE, post-analyze */
|
1999-04-16 21:22:55 +00:00
|
|
|
untimeout(fd_iotimeout, fdc, fd->tohandle);
|
1995-01-06 15:20:00 +00:00
|
|
|
|
2001-06-28 12:35:28 +00:00
|
|
|
if (fd_read_status(fdc)) {
|
2001-06-26 22:16:30 +00:00
|
|
|
if (!rdsectid && !(fdc->flags & FDC_NODMA))
|
2000-04-15 05:54:02 +00:00
|
|
|
isa_dmadone(idf, bp->bio_data + fd->skip,
|
|
|
|
format ? bp->bio_bcount : fdblk,
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
fdc->dmachan);
|
1995-01-06 15:20:00 +00:00
|
|
|
if (fdc->retry < 6)
|
|
|
|
fdc->retry = 6; /* force a reset */
|
1999-04-16 21:22:55 +00:00
|
|
|
return (retrier(fdc));
|
1995-01-06 15:20:00 +00:00
|
|
|
}
|
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fdc->state = IOTIMEDOUT;
|
1995-01-06 15:20:00 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
/* FALLTHROUGH */
|
|
|
|
case IOTIMEDOUT:
|
2001-06-26 22:16:30 +00:00
|
|
|
if (!rdsectid && !(fdc->flags & FDC_NODMA))
|
2000-04-15 05:54:02 +00:00
|
|
|
isa_dmadone(idf, bp->bio_data + fd->skip,
|
|
|
|
format ? bp->bio_bcount : fdblk, fdc->dmachan);
|
1999-04-16 21:22:55 +00:00
|
|
|
if (fdc->status[0] & NE7_ST0_IC) {
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
|
|
|
|
&& fdc->status[1] & NE7_ST1_OR) {
|
1993-12-19 00:40:49 +00:00
|
|
|
/*
|
2001-07-09 20:46:45 +00:00
|
|
|
* DMA overrun. Someone hogged the bus and
|
|
|
|
* didn't release it in time for the next
|
|
|
|
* FDC transfer.
|
|
|
|
*
|
|
|
|
* We normally restart this without bumping
|
|
|
|
* the retry counter. However, in case
|
|
|
|
* something is seriously messed up (like
|
|
|
|
* broken hardware), we rather limit the
|
|
|
|
* number of retries so the IO operation
|
|
|
|
* doesn't block indefinately.
|
|
|
|
*/
|
|
|
|
if (fdc->dma_overruns++ < FDC_DMAOV_MAX) {
|
|
|
|
fdc->state = SEEKCOMPLETE;
|
|
|
|
return (1);
|
|
|
|
} /* else fall through */
|
1993-12-19 00:40:49 +00:00
|
|
|
}
|
2001-07-09 20:46:45 +00:00
|
|
|
if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
&& fdc->retry < 6)
|
|
|
|
fdc->retry = 6; /* force a reset */
|
|
|
|
else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
|
|
|
|
&& fdc->status[2] & NE7_ST2_WC
|
|
|
|
&& fdc->retry < 3)
|
|
|
|
fdc->retry = 3; /* force recalibrate */
|
1999-04-16 21:22:55 +00:00
|
|
|
return (retrier(fdc));
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
/* All OK */
|
2001-06-26 22:16:30 +00:00
|
|
|
if (rdsectid) {
|
|
|
|
/* copy out ID field contents */
|
2001-06-28 12:35:28 +00:00
|
|
|
idp = (struct fdc_readid *)bp->bio_data;
|
2001-06-26 22:16:30 +00:00
|
|
|
idp->cyl = fdc->status[3];
|
|
|
|
idp->head = fdc->status[4];
|
|
|
|
idp->sec = fdc->status[5];
|
|
|
|
idp->secshift = fdc->status[6];
|
|
|
|
}
|
2001-07-09 20:46:45 +00:00
|
|
|
/* Operation successful, retry DMA overruns again next time. */
|
|
|
|
fdc->dma_overruns = 0;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fd->skip += fdblk;
|
2001-07-08 20:50:20 +00:00
|
|
|
if (!rdsectid && !format && fd->skip < bp->bio_bcount) {
|
1993-06-12 14:58:17 +00:00
|
|
|
/* set up next transfer */
|
|
|
|
fdc->state = DOSEEK;
|
1999-04-16 21:22:55 +00:00
|
|
|
} else {
|
1993-06-12 14:58:17 +00:00
|
|
|
/* ALL DONE */
|
|
|
|
fd->skip = 0;
|
2001-07-08 20:50:20 +00:00
|
|
|
bp->bio_resid = 0;
|
1999-01-15 09:15:27 +00:00
|
|
|
fdc->bp = NULL;
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
device_unbusy(fd->dev);
|
2001-05-06 20:00:03 +00:00
|
|
|
biofinish(bp, &fd->device_stats, 0);
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->fd = (fd_p) 0;
|
|
|
|
fdc->fdu = -1;
|
|
|
|
fdc->state = FINDWORK;
|
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
return (1);
|
2001-07-08 20:50:20 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
case RESETCTLR:
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fdc_reset(fdc);
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->retry++;
|
1998-07-29 13:00:42 +00:00
|
|
|
fdc->state = RESETCOMPLETE;
|
|
|
|
return (0);
|
2001-07-08 20:50:20 +00:00
|
|
|
|
1998-07-29 13:00:42 +00:00
|
|
|
case RESETCOMPLETE:
|
|
|
|
/*
|
|
|
|
* Discard all the results from the reset so that they
|
|
|
|
* can't cause an unexpected interrupt later.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
(void)fd_sense_int(fdc, &st0, &cyl);
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->state = STARTRECAL;
|
2001-07-08 20:50:20 +00:00
|
|
|
/* FALLTHROUGH */
|
1993-06-12 14:58:17 +00:00
|
|
|
case STARTRECAL:
|
1999-04-16 21:22:55 +00:00
|
|
|
if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) {
|
1994-10-21 16:58:50 +00:00
|
|
|
/* arrgl */
|
|
|
|
fdc->retry = 6;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (retrier(fdc));
|
1994-10-21 16:58:50 +00:00
|
|
|
}
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->state = RECALWAIT;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (0); /* will return later */
|
2001-07-08 20:50:20 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
case RECALWAIT:
|
|
|
|
/* allow heads to settle */
|
1999-04-16 21:22:55 +00:00
|
|
|
timeout(fd_pseudointr, fdc, hz / 8);
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->state = RECALCOMPLETE;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (0); /* will return later */
|
2001-07-08 20:50:20 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
case RECALCOMPLETE:
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
do {
|
|
|
|
/*
|
1995-01-06 15:20:00 +00:00
|
|
|
* See SEEKCOMPLETE for a comment on this:
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
*/
|
1995-01-06 15:20:00 +00:00
|
|
|
if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID)
|
|
|
|
return 0;
|
|
|
|
if(fdc->fdct == FDC_NE765
|
|
|
|
&& (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC)
|
|
|
|
return 0; /* hope for a real intr */
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
} while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
|
|
|
|
if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
1994-10-21 16:58:50 +00:00
|
|
|
if(fdc->retry > 3)
|
|
|
|
/*
|
|
|
|
* a recalibrate from beyond cylinder 77
|
|
|
|
* will "fail" due to the FDC limitations;
|
|
|
|
* since people used to complain much about
|
|
|
|
* the failure message, try not logging
|
|
|
|
* this one if it seems to be the first
|
|
|
|
* time in a line
|
|
|
|
*/
|
|
|
|
printf("fd%d: recal failed ST0 %b cyl %d\n",
|
|
|
|
fdu, st0, NE7_ST0BITS, cyl);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
if(fdc->retry < 3) fdc->retry = 3;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (retrier(fdc));
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
fd->track = 0;
|
|
|
|
/* Seek (probably) necessary */
|
|
|
|
fdc->state = DOSEEK;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (1); /* will return immediatly */
|
2001-07-08 20:50:20 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
case MOTORWAIT:
|
1993-06-12 14:58:17 +00:00
|
|
|
if(fd->flags & FD_MOTOR_WAIT)
|
|
|
|
{
|
1999-04-16 21:22:55 +00:00
|
|
|
return (0); /* time's not up yet */
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
1998-07-29 13:00:42 +00:00
|
|
|
if (fdc->flags & FDC_NEEDS_RESET) {
|
|
|
|
fdc->state = RESETCTLR;
|
|
|
|
fdc->flags &= ~FDC_NEEDS_RESET;
|
2001-07-08 20:50:20 +00:00
|
|
|
} else
|
|
|
|
fdc->state = DOSEEK;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (1); /* will return immediatly */
|
2001-07-08 20:50:20 +00:00
|
|
|
|
1993-06-12 14:58:17 +00:00
|
|
|
default:
|
2000-01-08 09:33:09 +00:00
|
|
|
device_printf(fdc->fdc_dev, "unexpected FD int->");
|
2001-06-28 12:35:28 +00:00
|
|
|
if (fd_read_status(fdc) == 0)
|
1998-07-11 06:35:39 +00:00
|
|
|
printf("FDC status :%x %x %x %x %x %x %x ",
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fdc->status[0],
|
|
|
|
fdc->status[1],
|
|
|
|
fdc->status[2],
|
|
|
|
fdc->status[3],
|
|
|
|
fdc->status[4],
|
|
|
|
fdc->status[5],
|
|
|
|
fdc->status[6] );
|
|
|
|
else
|
1995-01-12 19:20:28 +00:00
|
|
|
printf("No status available ");
|
|
|
|
if (fd_sense_int(fdc, &st0, &cyl) != 0)
|
|
|
|
{
|
|
|
|
printf("[controller is dead now]\n");
|
1999-04-16 21:22:55 +00:00
|
|
|
return (0);
|
1995-01-12 19:20:28 +00:00
|
|
|
}
|
|
|
|
printf("ST0 = %x, PCN = %x\n", st0, cyl);
|
1999-04-16 21:22:55 +00:00
|
|
|
return (0);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
2001-07-08 20:50:20 +00:00
|
|
|
/* keep the compiler happy -- noone should ever get here */
|
|
|
|
return (999999);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
1993-12-19 00:55:01 +00:00
|
|
|
static int
|
1999-04-16 21:22:55 +00:00
|
|
|
retrier(struct fdc_data *fdc)
|
1993-06-12 14:58:17 +00:00
|
|
|
{
|
2000-04-15 05:54:02 +00:00
|
|
|
struct bio *bp;
|
1999-04-16 21:22:55 +00:00
|
|
|
struct fd_data *fd;
|
|
|
|
int fdu;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1999-01-15 09:15:27 +00:00
|
|
|
bp = fdc->bp;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
/* XXX shouldn't this be cached somewhere? */
|
2000-04-15 05:54:02 +00:00
|
|
|
fdu = FDUNIT(minor(bp->bio_dev));
|
1999-04-16 21:22:55 +00:00
|
|
|
fd = devclass_get_softc(fd_devclass, fdu);
|
|
|
|
if (fd->options & FDOPT_NORETRY)
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
goto fail;
|
1999-04-16 21:22:55 +00:00
|
|
|
|
|
|
|
switch (fdc->retry) {
|
1993-06-12 14:58:17 +00:00
|
|
|
case 0: case 1: case 2:
|
|
|
|
fdc->state = SEEKCOMPLETE;
|
|
|
|
break;
|
|
|
|
case 3: case 4: case 5:
|
|
|
|
fdc->state = STARTRECAL;
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
fdc->state = RESETCTLR;
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
break;
|
|
|
|
default:
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fail:
|
2001-07-08 20:50:20 +00:00
|
|
|
if ((fd->options & FDOPT_NOERRLOG) == 0) {
|
|
|
|
diskerr(bp, "hard error", fdc->fd->skip / DEV_BSIZE,
|
|
|
|
(struct disklabel *)NULL);
|
|
|
|
if (fdc->flags & FDC_STAT_VALID) {
|
|
|
|
printf(
|
2001-06-28 12:35:28 +00:00
|
|
|
" (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n",
|
2001-07-08 20:50:20 +00:00
|
|
|
fdc->status[0], NE7_ST0BITS,
|
|
|
|
fdc->status[1], NE7_ST1BITS,
|
|
|
|
fdc->status[2], NE7_ST2BITS,
|
|
|
|
fdc->status[3], fdc->status[4],
|
|
|
|
fdc->status[5]);
|
2001-05-14 20:20:11 +00:00
|
|
|
}
|
2001-07-08 20:50:20 +00:00
|
|
|
else
|
|
|
|
printf(" (No status)\n");
|
2001-05-14 20:20:11 +00:00
|
|
|
}
|
|
|
|
if ((fd->options & FDOPT_NOERROR) == 0) {
|
|
|
|
bp->bio_flags |= BIO_ERROR;
|
|
|
|
bp->bio_error = EIO;
|
2001-07-08 20:50:20 +00:00
|
|
|
bp->bio_resid = bp->bio_bcount - fdc->fd->skip;
|
|
|
|
} else
|
|
|
|
bp->bio_resid = 0;
|
1999-01-15 09:15:27 +00:00
|
|
|
fdc->bp = NULL;
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->fd->skip = 0;
|
Make the Y-E Data PCMCIA floppy of the Toshiba Libretto work under
-current. It doesn't work yet as stable as the 3.x/PAO version of the
driver does, however, i get occasional `FDC direction bit not set' and
other weird messages, but it basically works at least.
The old (defunct) #ifdef FDC_YE stuff has been eliminated completely
now, PCMCIA-FDC specific functions have been implemented differently
where needed.
Unfortunately, due to the fact that the traditional PeeCee FDC with
its funny non-contiguous register space (one register for WD1003
harddisk controllers is interleaved into the FDC register set), and
Peter's subsequent changes involving two different bus space handles
for normal FDCs, the changes required for the Y-E stuff are more
complex than i'd love them to be. I've done my best to keep the logic
for normal FDCs intact.
Since the Y-E FDC seems to lose interrupts after a FDC reset
sometimes, i've also replaced the timeout logic in fd_turnoff() to
generate an artificial pseudo interrupt in case of a timeout while the
drive has still outstanding transfers waiting. This avoids the total
starvation of the driver that could be observed with highly damaged
media under 3.x/PAO. This part of the patch has been revied by bde
previously.
I've fixed a number of occasions where previous commits have been
missing the encapuslation of ISA DMA related functions inside
FDC_NODMA checks.
I've added one call to SET_BCDR() during preparation of the format
floppy operation. Floppy formatting has been totally broken before in
3.x/PAO (garbage ID fields have been written to the medium, causing
`wrong cylinder' errors upon media reading). This is just black
magic, i don't have the slightes idea _why_ this needs to be but just
copied over the hack that has been used by the PAO folks in the normal
read/write case anyway.
The entired device_busy() stuff seems to be pointless to me. In any
case, i had to add device_unbusy() calls symmetrical to the
device_busy() calls, otherwise the PCMCIA floppy driver could never be
deactivated. (As it used to be, it caused a `mark the device busier
and busier' situation.) IMHO, all block device drivers should be
marked busy based on active buffers still waiting for the driver, so
the device_unbusy() calls should probably go to biodone(). Only one
other driver (whose name escapes me at the moment) uses device_busy()
calls at all, so i question the value of all this...
I think this entire `device busy' logic simply doesn't fit for PCMCIA
&al. It cannot be the decision of some piece of kernel software to
declare a device `busy by now, you can't remove it', when the actual
physical power of removing it is the user pulling the card. The
kernel simply has to cope with the removal, however busy the device
might have been by the time of the removal, period. Perhaps a force
flag needs to be added?
Upon inserting the card a second time, i get:
WARNING: "fd" is usurping "fd"'s cdevsw[]
WARNING: "fd" is usurping "fd"'s bmaj
I suspect this is related to the XXX comment at the call to
cdevsw_add(). Does anybody know what the correct way is to cleanup
this?
2000-03-18 18:27:01 +00:00
|
|
|
device_unbusy(fd->dev);
|
2001-05-06 20:00:03 +00:00
|
|
|
biofinish(bp, &fdc->fd->device_stats, 0);
|
>From: bde@kralizec.zeta.org.au (Bruce Evans)
Date: Thu, 16 Sep 93 01:35:10 +1000
Julian writes:
>In fact DEVIDLE and FINDWORK ended up being basically equivalent.
>the bit I wonder about, is the returning of 0.. What (other than
>another request from somewhere else in the kernel) is going to start
>work on the next item on the queue?
I think removing FINDWORK would make things clearer.
Nothing much is going to start work on the next item. However, it is
pointless to continue processing the queue for the same unready drive.
Aborting all reads and trying harder to perform all writes would be
better.
Julian writes.
> no, actually it should be:
> fdt = fd_data[FDUNIT(minor(dev))].ft;
Fixed.
From: bde@kralizec.zeta.org.au (Bruce Evans)
Date: Thu, 16 Sep 93 22:56:01 +1000
The fd driver reported the wrong cylinder/head/sector numbers after an
error (ST3 is only valid after a sense-drive command), and didn't report
fs block numbers (diskerr was not used).
There was an old problem with writes to block fd devices. Try this:
1. write protect floppy in fd0.
2. tar cf /dev/fd0a /dev/null. Repeat a few times. Later writes tend to
terminate earlier.
3. un-write protect floppy.
4. repeat step 2. The writes tend to return 0, 2048, 4096, ... and then
succeed.
This was caused by a bug in vfs__bios.c. (The bug is fixed in NetBSD's
vfs_bio.c.) fd.c sets bp->b_resid to nonzero after an error. vfs__bios.c
was not initializing bp->b_resid. This causes some writes to terminate
early (e.g., writes to block devices; see spec_write()).
Related funnies:
1. Nothing tries to write the residual bytes.
2. The wd driver sets bp->b_resid to 0 after an error, so there's no
way anything else could write the residual bytes.
3. I use the block fd device for tar because the raw device seemed to
have more bugs long ago, and because it ought to be able to handle
buffering more transparently (I don't want to have to know the
device size). But spec_write() always uses the size BLKDEV_IOSIZE
== 2048 which is too small. For disks it should use the size of
one track (rounded down to meet the next track boundary or the i/o
size). Here it would help if the DIOCGPART ioctl worked. But
DIOCGPART is not implemented for floppies, and the disk size is
ignored except for partitions of type FS_BSDFFS.
Bruce
1993-09-23 15:22:57 +00:00
|
|
|
fdc->state = FINDWORK;
|
1998-07-29 13:00:42 +00:00
|
|
|
fdc->flags |= FDC_NEEDS_RESET;
|
1993-06-12 14:58:17 +00:00
|
|
|
fdc->fd = (fd_p) 0;
|
|
|
|
fdc->fdu = -1;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (1);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
fdc->retry++;
|
1999-04-16 21:22:55 +00:00
|
|
|
return (1);
|
1993-06-12 14:58:17 +00:00
|
|
|
}
|
|
|
|
|
2000-05-06 07:01:47 +00:00
|
|
|
static void
|
|
|
|
fdbiodone(struct bio *bp)
|
|
|
|
{
|
|
|
|
wakeup(bp);
|
|
|
|
}
|
|
|
|
|
1993-12-19 00:40:49 +00:00
|
|
|
static int
|
2001-06-29 15:30:48 +00:00
|
|
|
fdmisccmd(dev_t dev, u_int cmd, void *data)
|
1993-12-19 00:40:49 +00:00
|
|
|
{
|
2001-06-29 15:30:48 +00:00
|
|
|
fdu_t fdu;
|
|
|
|
fd_p fd;
|
2000-05-06 07:01:47 +00:00
|
|
|
struct bio *bp;
|
2001-06-29 15:30:48 +00:00
|
|
|
struct fd_formb *finfo;
|
|
|
|
struct fdc_readid *idfield;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
size_t fdblk;
|
|
|
|
|
2001-06-29 15:30:48 +00:00
|
|
|
fdu = FDUNIT(minor(dev));
|
|
|
|
fd = devclass_get_softc(fd_devclass, fdu);
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fdblk = 128 << fd->ft->secsize;
|
2001-06-29 15:30:48 +00:00
|
|
|
finfo = (struct fd_formb *)data;
|
|
|
|
idfield = (struct fdc_readid *)data;
|
1993-12-19 00:40:49 +00:00
|
|
|
|
2001-07-08 20:50:20 +00:00
|
|
|
bp = malloc(sizeof(struct bio), M_TEMP, M_ZERO);
|
1993-12-19 00:40:49 +00:00
|
|
|
|
|
|
|
/*
|
2001-06-29 15:30:48 +00:00
|
|
|
* Set up a bio request for fdstrategy(). bio_blkno is faked
|
|
|
|
* so that fdstrategy() will seek to the the requested
|
|
|
|
* cylinder, and use the desired head. Since we are not
|
|
|
|
* interested in bioqdisksort() munging with our faked bio
|
|
|
|
* request, we mark it as being an ordered request.
|
1993-12-19 00:40:49 +00:00
|
|
|
*/
|
2001-06-29 15:30:48 +00:00
|
|
|
bp->bio_cmd = cmd;
|
|
|
|
if (cmd == BIO_FORMAT) {
|
|
|
|
bp->bio_blkno =
|
|
|
|
(finfo->cyl * (fd->ft->sectrac * fd->ft->heads) +
|
|
|
|
finfo->head * fd->ft->sectrac) *
|
|
|
|
fdblk / DEV_BSIZE;
|
|
|
|
bp->bio_bcount = sizeof(struct fd_idfield_data) *
|
|
|
|
finfo->fd_formb_nsecs;
|
|
|
|
} else if (cmd == BIO_RDSECTID) {
|
|
|
|
bp->bio_blkno =
|
|
|
|
(idfield->cyl * (fd->ft->sectrac * fd->ft->heads) +
|
|
|
|
idfield->head * fd->ft->sectrac) *
|
|
|
|
fdblk / DEV_BSIZE;
|
|
|
|
bp->bio_bcount = sizeof(struct fdc_readid);
|
|
|
|
} else
|
|
|
|
panic("wrong cmd in fdmisccmd()");
|
|
|
|
bp->bio_data = data;
|
2000-05-06 07:01:47 +00:00
|
|
|
bp->bio_dev = dev;
|
|
|
|
bp->bio_done = fdbiodone;
|
2001-06-29 15:30:48 +00:00
|
|
|
bp->bio_flags = BIO_ORDERED;
|
2001-06-26 22:16:30 +00:00
|
|
|
|
|
|
|
/*
|
2001-07-08 20:50:20 +00:00
|
|
|
* Now run the command. The wait loop is a version of bufwait()
|
|
|
|
* adapted for struct bio instead of struct buf and specialized
|
|
|
|
* for the current context.
|
2001-06-26 22:16:30 +00:00
|
|
|
*/
|
|
|
|
fdstrategy(bp);
|
2001-07-08 20:50:20 +00:00
|
|
|
while ((bp->bio_flags & BIO_DONE) == 0)
|
2001-06-29 15:30:48 +00:00
|
|
|
tsleep(bp, PRIBIO, "fdcmd", 0);
|
2001-06-26 22:16:30 +00:00
|
|
|
|
|
|
|
free(bp, M_TEMP);
|
2001-06-29 15:30:48 +00:00
|
|
|
return (bp->bio_flags & BIO_ERROR ? bp->bio_error : 0);
|
2001-06-26 22:16:30 +00:00
|
|
|
}
|
|
|
|
|
1998-04-19 23:32:49 +00:00
|
|
|
static int
|
2001-06-26 22:07:25 +00:00
|
|
|
fdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
|
1993-09-14 19:34:32 +00:00
|
|
|
{
|
2001-06-29 15:30:48 +00:00
|
|
|
fdu_t fdu;
|
|
|
|
fd_p fd;
|
1993-12-19 00:40:49 +00:00
|
|
|
struct fd_type *fdt;
|
2001-07-08 20:50:20 +00:00
|
|
|
struct disklabel *lp;
|
2001-05-14 20:20:11 +00:00
|
|
|
struct fdc_status *fsp;
|
2001-06-26 22:16:30 +00:00
|
|
|
struct fdc_readid *rid;
|
2001-06-29 15:30:48 +00:00
|
|
|
size_t fdblk;
|
2001-07-08 20:50:20 +00:00
|
|
|
int error;
|
|
|
|
|
|
|
|
fdu = FDUNIT(minor(dev));
|
|
|
|
fd = devclass_get_softc(fd_devclass, fdu);
|
|
|
|
|
1993-09-14 19:34:32 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
fdblk = 128 << fd->ft->secsize;
|
2001-07-08 20:50:20 +00:00
|
|
|
error = 0;
|
1993-09-14 19:34:32 +00:00
|
|
|
|
1999-04-16 21:22:55 +00:00
|
|
|
switch (cmd) {
|
1993-12-19 00:40:49 +00:00
|
|
|
case DIOCGDINFO:
|
2001-07-08 20:50:20 +00:00
|
|
|
lp = malloc(sizeof(*lp), M_TEMP, M_ZERO);
|
|
|
|
lp->d_secsize = fdblk;
|
1999-04-16 21:22:55 +00:00
|
|
|
fdt = fd->ft;
|
2001-07-08 20:50:20 +00:00
|
|
|
lp->d_secpercyl = fdt->size / fdt->tracks;
|
|
|
|
lp->d_type = DTYPE_FLOPPY;
|
|
|
|
if (readdisklabel(dkmodpart(dev, RAW_PART), lp) != NULL)
|
1993-12-19 00:40:49 +00:00
|
|
|
error = EINVAL;
|
2001-07-08 20:50:20 +00:00
|
|
|
else
|
|
|
|
*(struct disklabel *)addr = *lp;
|
|
|
|
free(lp, M_TEMP);
|
1993-12-19 00:40:49 +00:00
|
|
|
break;
|
1993-09-14 19:34:32 +00:00
|
|
|
|
1993-12-19 00:40:49 +00:00
|
|
|
case DIOCSDINFO:
|
|
|
|
if ((flag & FWRITE) == 0)
|
2001-07-08 20:50:20 +00:00
|
|
|
return (EBADF);
|
|
|
|
/*
|
|
|
|
* XXX perhaps should call setdisklabel() to do error checking
|
|
|
|
* although there is nowhere to "set" the result. Perhaps
|
|
|
|
* should always just fail.
|
|
|
|
*/
|
1993-12-19 00:40:49 +00:00
|
|
|
break;
|
1993-06-12 14:58:17 +00:00
|
|
|
|
1993-12-19 00:40:49 +00:00
|
|
|
case DIOCWLABEL:
|
|
|
|
if ((flag & FWRITE) == 0)
|
2001-07-08 20:50:20 +00:00
|
|
|
return (EBADF);
|
1993-12-19 00:40:49 +00:00
|
|
|
break;
|
1993-09-14 19:34:32 +00:00
|
|
|
|
1993-12-19 00:40:49 +00:00
|
|
|
case DIOCWDINFO:
|
2001-07-08 20:50:20 +00:00
|
|
|
if ((flag & FWRITE) == 0)
|
|
|
|
return (EBADF);
|
|
|
|
lp = malloc(DEV_BSIZE, M_TEMP, M_ZERO);
|
|
|
|
error = setdisklabel(lp, (struct disklabel *)addr, (u_long)0);
|
|
|
|
if (error != 0)
|
|
|
|
error = writedisklabel(dev, lp);
|
|
|
|
free(lp, M_TEMP);
|
1993-12-19 00:40:49 +00:00
|
|
|
break;
|
2001-06-29 15:30:48 +00:00
|
|
|
|
1993-12-19 00:40:49 +00:00
|
|
|
case FD_FORM:
|
1999-04-16 21:22:55 +00:00
|
|
|
if ((flag & FWRITE) == 0)
|
2001-07-08 20:50:20 +00:00
|
|
|
return (EBADF); /* must be opened for writing */
|
|
|
|
if (((struct fd_formb *)addr)->format_version !=
|
|
|
|
FD_FORMAT_VERSION)
|
|
|
|
return (EINVAL); /* wrong version of formatting prog */
|
|
|
|
error = fdmisccmd(dev, BIO_FORMAT, addr);
|
1993-12-19 00:40:49 +00:00
|
|
|
break;
|
1993-09-14 19:34:32 +00:00
|
|
|
|
1993-12-19 00:40:49 +00:00
|
|
|
case FD_GTYPE: /* get drive type */
|
1998-04-19 23:32:49 +00:00
|
|
|
*(struct fd_type *)addr = *fd->ft;
|
1993-12-19 00:40:49 +00:00
|
|
|
break;
|
1993-09-14 19:34:32 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
case FD_STYPE: /* set drive type */
|
|
|
|
/* this is considered harmful; only allow for superuser */
|
1999-04-27 11:18:52 +00:00
|
|
|
if (suser(p) != 0)
|
2001-07-08 20:50:20 +00:00
|
|
|
return (EPERM);
|
1998-04-19 23:32:49 +00:00
|
|
|
*fd->ft = *(struct fd_type *)addr;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FD_GOPTS: /* get drive options */
|
1998-04-19 23:32:49 +00:00
|
|
|
*(int *)addr = fd->options;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
break;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
case FD_SOPTS: /* set drive options */
|
1998-04-19 23:32:49 +00:00
|
|
|
fd->options = *(int *)addr;
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
break;
|
|
|
|
|
2001-06-29 15:30:48 +00:00
|
|
|
#ifdef FDC_DEBUG
|
|
|
|
case FD_DEBUG:
|
2001-07-09 21:11:10 +00:00
|
|
|
if ((fd_debug != 0) != (*(int *)addr != 0)) {
|
|
|
|
fd_debug = (*(int *)addr != 0);
|
|
|
|
printf("fd%d: debugging turned %s\n",
|
|
|
|
fd->fdu, fd_debug ? "on" : "off");
|
|
|
|
}
|
2001-06-29 15:30:48 +00:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
2001-05-14 20:20:11 +00:00
|
|
|
case FD_CLRERR:
|
|
|
|
if (suser(p) != 0)
|
2001-07-08 20:50:20 +00:00
|
|
|
return (EPERM);
|
2001-05-14 20:20:11 +00:00
|
|
|
fd->fdc->fdc_errs = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FD_GSTAT:
|
|
|
|
fsp = (struct fdc_status *)addr;
|
|
|
|
if ((fd->fdc->flags & FDC_STAT_VALID) == 0)
|
2001-07-08 20:50:20 +00:00
|
|
|
return (EINVAL);
|
2001-05-14 20:20:11 +00:00
|
|
|
memcpy(fsp->status, fd->fdc->status, 7 * sizeof(u_int));
|
|
|
|
break;
|
|
|
|
|
2001-06-26 22:16:30 +00:00
|
|
|
case FD_READID:
|
|
|
|
rid = (struct fdc_readid *)addr;
|
|
|
|
if (rid->cyl > MAX_CYLINDER || rid->head > MAX_HEAD)
|
2001-07-08 20:50:20 +00:00
|
|
|
return (EINVAL);
|
2001-06-29 15:30:48 +00:00
|
|
|
error = fdmisccmd(dev, BIO_RDSECTID, addr);
|
2001-06-26 22:16:30 +00:00
|
|
|
break;
|
|
|
|
|
1993-12-19 00:40:49 +00:00
|
|
|
default:
|
Updated driver to the 1.1.5 version:
date: 1994/05/22 12:35:38; author: joerg; state: Exp; lines: +6 -6
First round of floppy changes. Try making `fd' more robust.
New features:
. ioctl command for setting the drive type (density etc.); restricted
to the super-user
. ioctl for getting/seting `drive options'; currently only option
is FDOPT_NORETRY: inhibit the usual retries; used when verifying
a newly formatted track
Fixes:
. function prototypes
. made all internal functions `static'
. cleaned up & corrected .h files
. restructured, to make the chaotic function sequence more rational
. compiled with -Wall, and cleared all warnings
. introduced a mirror for the (write-only) `digital output register',
to avoid the current kludge
. device probing completed by seeking/recalibrating, and looking
for track 0 being found
. holding the controller down in reset state while it is idle (and
thus saving allot of headaches)
. make requests fail that are not a multiple of the (physical)
sector size
. removed the fixed physical sector size (512 bytes), allowing for any
size the controller could handle (128/256/512/1024 bytes)
. replaced some silly messages
. fixed the TRACE* macro usage, debugging reports should be complete
now again (debugging output is HUGE! though)
. removed fd_timeout for SEEK command; seeks are always reported by
the controller to succeed, since the `success' only refers to the
controller's idea of success - there is no hardware line to tell about
the seek end (other than the `track 0' line)
. catch SENSEI's that report about a `terminated due to READY changed'
status - could happen after a controller reset
. converted ``hz / <something>'' divide operations to divisors that are
powers of two, so gcc can optimize them into shifts
. write/format operations are checked against a write-protected medium
now *prior* starting the operation
. error reports of `invalid command' and `wrong cylinder' will cause
shortcuts in the retrier() now
. fixed a bug in the retrier() causing bogus block numbers to be reported
. fdformat() does care for errors now
Known Bugs:
. no attempts have been made (yet) to improve the performance
. sometimes, bogus ``seek/recalib failed'' messages are logged; this
is still a bug in the driver, but it's not harmful since it's
usually caught by the retrier()
Reviewed by:
Submitted by:
Obtained from:
1994-09-17 16:56:10 +00:00
|
|
|
error = ENOTTY;
|
1993-12-19 00:40:49 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return (error);
|
1993-09-14 19:34:32 +00:00
|
|
|
}
|