1994-02-14 22:24:28 +00:00
|
|
|
/*-
|
|
|
|
* Copyright (c) 1990 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
1999-08-28 01:08:13 +00:00
|
|
|
* $FreeBSD$
|
1994-02-14 22:24:28 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1995-01-06 15:20:00 +00:00
|
|
|
enum fdc_type
|
|
|
|
{
|
|
|
|
FDC_NE765, FDC_I82077, FDC_NE72065, FDC_UNKNOWN = -1
|
|
|
|
};
|
|
|
|
|
1994-02-07 22:12:45 +00:00
|
|
|
|
|
|
|
/***********************************************************************\
|
|
|
|
* Per controller structure. *
|
|
|
|
\***********************************************************************/
|
|
|
|
struct fdc_data
|
|
|
|
{
|
|
|
|
int fdcu; /* our unit number */
|
|
|
|
int dmachan;
|
|
|
|
int flags;
|
|
|
|
#define FDC_ATTACHED 0x01
|
1995-01-06 15:20:00 +00:00
|
|
|
#define FDC_STAT_VALID 0x08
|
1997-09-17 20:16:17 +00:00
|
|
|
#define FDC_HAS_FIFO 0x10
|
1998-07-29 13:00:42 +00:00
|
|
|
#define FDC_NEEDS_RESET 0x20
|
2000-01-06 07:13:54 +00:00
|
|
|
#define FDC_NODMA 0x40
|
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
|
|
|
#define FDC_ISPNP 0x80
|
|
|
|
#define FDC_ISPCMCIA 0x100
|
1994-02-07 22:12:45 +00:00
|
|
|
struct fd_data *fd;
|
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 fdu; /* the active drive */
|
|
|
|
int state;
|
|
|
|
int retry;
|
|
|
|
int fdout; /* mirror of the w/o digital output reg */
|
1998-07-11 06:35:39 +00:00
|
|
|
u_int status[7]; /* copy of the registers */
|
1995-01-06 15:20:00 +00:00
|
|
|
enum fdc_type fdct; /* chip version of FDC */
|
|
|
|
int fdc_errs; /* number of logged errors */
|
2000-04-15 05:54:02 +00:00
|
|
|
struct bio_queue_head head;
|
|
|
|
struct bio *bp; /* active buffer */
|
1999-11-11 08:48:40 +00:00
|
|
|
struct resource *res_ioport, *res_ctl, *res_irq, *res_drq;
|
|
|
|
int rid_ioport, rid_ctl, rid_irq, rid_drq;
|
|
|
|
int port_off;
|
|
|
|
bus_space_tag_t portt;
|
|
|
|
bus_space_handle_t porth;
|
|
|
|
bus_space_tag_t ctlt;
|
|
|
|
bus_space_handle_t ctlh;
|
1999-04-16 21:22:55 +00:00
|
|
|
void *fdc_intr;
|
|
|
|
struct device *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
|
|
|
void (*fdctl_wr)(struct fdc_data *fdc, u_int8_t v);
|
1994-02-07 22:12:45 +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) *
|
|
|
|
\***********************************************************************/
|
|
|
|
typedef int fdu_t;
|
|
|
|
typedef int fdcu_t;
|
|
|
|
typedef int fdsu_t;
|
|
|
|
typedef struct fd_data *fd_p;
|
|
|
|
typedef struct fdc_data *fdc_p;
|
1995-01-06 15:20:00 +00:00
|
|
|
typedef enum fdc_type fdc_t;
|
1994-02-07 22:12:45 +00:00
|
|
|
|
2000-01-09 17:13:35 +00:00
|
|
|
#define FDUNIT(s) (((s) >> 6) & 3)
|
|
|
|
#define FDTYPE(s) ((s) & 0x3f)
|
2000-01-05 16:31:27 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* fdc maintains a set (1!) of ivars per child of each controller.
|
|
|
|
*/
|
|
|
|
enum fdc_device_ivars {
|
|
|
|
FDC_IVAR_FDUNIT,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Simple access macros for the ivars.
|
|
|
|
*/
|
|
|
|
#define FDC_ACCESSOR(A, B, T) \
|
|
|
|
static __inline T fdc_get_ ## A(device_t dev) \
|
|
|
|
{ \
|
|
|
|
uintptr_t v; \
|
|
|
|
BUS_READ_IVAR(device_get_parent(dev), dev, FDC_IVAR_ ## B, &v); \
|
|
|
|
return (T) v; \
|
|
|
|
}
|
|
|
|
FDC_ACCESSOR(fdunit, FDUNIT, int)
|