413 lines
12 KiB
Groff
413 lines
12 KiB
Groff
.\" $NetBSD: wdc.9,v 1.19 2015/04/28 09:48:31 prlw1 Exp $
|
|
.\"
|
|
.\" Copyright (c) 1998 Manuel Bouyer.
|
|
.\"
|
|
.\" 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.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
|
.\"
|
|
.\"
|
|
.Dd April 18, 2010
|
|
.Dt WDC 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm wdc
|
|
.Nd machine-independent IDE/ATAPI driver
|
|
.Sh SYNOPSIS
|
|
.In dev/ata/atavar.h
|
|
.In sys/dev/ic/wdcvar.h
|
|
.Ft int
|
|
.Fn wdcprobe "struct channel_softc * chp"
|
|
.Ft void
|
|
.Fn wdcattach "struct channel_softc * chp"
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm
|
|
driver provides the machine independent core functions for driving IDE
|
|
devices.
|
|
IDE devices-specific drivers
|
|
.Po
|
|
.Xr wd 4
|
|
or
|
|
.Xr atapibus 4
|
|
.Pc
|
|
will use services provided by
|
|
.Nm .
|
|
.Pp
|
|
The machine-dependent bus front-end provides information to
|
|
.Nm
|
|
with the
|
|
.Va wdc_softc
|
|
and
|
|
.Va channel_softc
|
|
structures.
|
|
The first one defines global controller properties, and the second contains
|
|
per-channel information.
|
|
.Nm
|
|
returns information about the attached devices in the
|
|
.Va ata_drive_datas
|
|
structure.
|
|
.Bd -literal
|
|
struct wdc_softc { /* Per controller state */
|
|
struct device sc_dev;
|
|
int cap;
|
|
#define WDC_CAPABILITY_DATA16 0x0001
|
|
#define WDC_CAPABILITY_DATA32 0x0002
|
|
#define WDC_CAPABILITY_MODE 0x0004
|
|
#define WDC_CAPABILITY_DMA 0x0008
|
|
#define WDC_CAPABILITY_UDMA 0x0010
|
|
#define WDC_CAPABILITY_HWLOCK 0x0020
|
|
#define WDC_CAPABILITY_ATA_NOSTREAM 0x0040
|
|
#define WDC_CAPABILITY_ATAPI_NOSTREAM 0x0080
|
|
#define WDC_CAPABILITY_NO_EXTRA_RESETS 0x0100
|
|
#define WDC_CAPABILITY_PREATA 0x0200
|
|
#define WDC_CAPABILITY_IRQACK 0x0400
|
|
#define WDC_CAPABILITY_SINGLE_DRIVE 0x0800
|
|
#define WDC_CAPABILITY_NOIRQ 0x1000
|
|
#define WDC_CAPABILITY_SELECT 0x2000
|
|
uint8_t pio_mode;
|
|
uint8_t dma_mode;
|
|
int nchannels;
|
|
struct channel_softc *channels;
|
|
|
|
void *dma_arg;
|
|
int (*dma_init)(void *, int, int, void *, size_t, int);
|
|
void (*dma_start)(void *, int, int, int);
|
|
int (*dma_finish)(void *, int, int, int);
|
|
#define WDC_DMA_READ 0x01
|
|
#define WDC_DMA_POLL 0x02
|
|
|
|
int (*claim_hw)(void *, int);
|
|
void (*free_hw)(void *);
|
|
};
|
|
|
|
struct channel_softc { /* Per channel data */
|
|
int channel;
|
|
struct wdc_softc *wdc;
|
|
bus_space_tag_t cmd_iot;
|
|
bus_space_handle_t cmd_ioh;
|
|
bus_space_tag_t ctl_iot;
|
|
bus_space_handle_t ctl_ioh;
|
|
bus_space_tag_t data32iot;
|
|
bus_space_handle_t data32ioh;
|
|
int ch_flags;
|
|
#define WDCF_ACTIVE 0x01
|
|
#define WDCF_IRQ_WAIT 0x10
|
|
uint8_t ch_status;
|
|
uint8_t ch_error;
|
|
struct ata_drive_datas ch_drive[2];
|
|
struct channel_queue *ch_queue;
|
|
};
|
|
|
|
struct ata_drive_datas {
|
|
uint8_t drive;
|
|
uint8_t drive_flags;
|
|
#define DRIVE_ATA 0x01
|
|
#define DRIVE_ATAPI 0x02
|
|
#define DRIVE (DRIVE_ATA|DRIVE_ATAPI)
|
|
#define DRIVE_CAP32 0x04
|
|
#define DRIVE_DMA 0x08
|
|
#define DRIVE_UDMA 0x10
|
|
#define DRIVE_MODE 0x20
|
|
uint8_t PIO_mode;
|
|
uint8_t DMA_mode;
|
|
uint8_t UDMA_mode;
|
|
uint8_t state;
|
|
|
|
struct device *drv_softc;
|
|
void* chnl_softc;
|
|
};
|
|
.Ed
|
|
.Pp
|
|
The bus front-end needs to fill in the following elements of
|
|
.Va wdc_softc :
|
|
.Bl -tag -compact -width "dma_finish" -offset "xxxx"
|
|
.It cap
|
|
supports one or more of the WDC_CAPABILITY flags
|
|
.It nchannels
|
|
number of channels supported by this controller
|
|
.It channels
|
|
array of
|
|
.Va struct channel_softc
|
|
of size
|
|
.Va nchannels
|
|
properly initialised
|
|
.El
|
|
The following elements are optional:
|
|
.Bl -tag -compact -width "dma_finish" -offset "xxxx"
|
|
.It pio_mode
|
|
.It dma_mode
|
|
.It dma_arg
|
|
.It dma_init
|
|
.It dma_start
|
|
.It dma_finish
|
|
.It claim_hw
|
|
.It free_hw
|
|
.El
|
|
.Pp
|
|
The
|
|
.Dv WDC_CAPABILITY_DATA16
|
|
and
|
|
.Dv WDC_CAPABILITY_DATA32
|
|
flags informs
|
|
.Nm
|
|
whether the controller supports 16- or 32-bit I/O accesses on the data port.
|
|
If both are set, a test will be done for each drive using the ATA or
|
|
ATAPI IDENTIFY command, to automatically select the working mode.
|
|
.Pp
|
|
The
|
|
.Dv WDC_CAPABILITY_DMA
|
|
and
|
|
.Dv WDC_CAPABILITY_UDMA
|
|
flags are set for controllers supporting the DMA and Ultra-DMA modes.
|
|
The bus front-end needs to provide the
|
|
.Fn dma_init ,
|
|
.Fn dma_start
|
|
and
|
|
.Fn dma_finish
|
|
functions.
|
|
.Fn dma_init
|
|
is called just before issuing a DMA command to the IDE device.
|
|
The arguments are, respectively:
|
|
.Va dma_arg ,
|
|
the channel number, the drive number on this channel,
|
|
the virtual address of the DMA buffer, the size of the transfer, and the
|
|
.Dv WDC_DMA
|
|
flags.
|
|
.Fn dma_start
|
|
is called just after issuing a DMA command to the IDE device.
|
|
The arguments are, respectively:
|
|
.Va dma_arg ,
|
|
the channel number, the drive number on this channel, and the
|
|
.Dv WDC_DMA
|
|
flags.
|
|
.Fn dma_finish
|
|
is called once the transfer is complete.
|
|
The arguments are, respectively:
|
|
.Va dma_arg ,
|
|
the channel number, the drive number on this channel, and the
|
|
.Dv WDC_DMA
|
|
flags.
|
|
.Dv WDC_DMA_READ
|
|
indicates the direction of the data transfer, and
|
|
.Dv WDC_DMA_POLL
|
|
indicates if the transfer will use (or used) interrupts.
|
|
.Pp
|
|
The
|
|
.Dv WDC_CAPABILITY_MODE
|
|
flag means that the bus front-end can program the PIO and DMA modes, so
|
|
.Nm
|
|
needs to provide back the supported modes for each drive, and set the drives
|
|
modes.
|
|
The
|
|
.Va pio_mode
|
|
and
|
|
.Va dma_mode
|
|
needs to be set to the highest PIO and DMA mode supported.
|
|
If
|
|
.Dv WDC_CAPABILITY_UDMA
|
|
is set, then
|
|
.Va dma_mode
|
|
must be set to the highest Ultra-DMA mode supported.
|
|
If
|
|
.Dv WDC_CAPABILITY_MODE
|
|
is not set,
|
|
.Nm
|
|
will not attempt to change the current drive's settings, assuming the host's
|
|
firmware has done it right.
|
|
.Pp
|
|
The
|
|
.Dv WDC_CAPABILITY_HWLOCK
|
|
flag is set for controllers needing hardware looking before accessing the
|
|
I/O ports.
|
|
If this flag is set, the bus front-end needs to provide the
|
|
.Fn claim_hw
|
|
and
|
|
.Fn free_hw
|
|
functions.
|
|
.Fn claim_hw
|
|
will be called when the driver wants to access the controller ports.
|
|
The second parameter is set to 1 when it is possible to sleep waiting
|
|
for the lock, 0 otherwise.
|
|
It should return 1 when access has been granted, 0 otherwise.
|
|
When access has not been granted and sleep is not allowed, the bus
|
|
front-end shall call
|
|
.Fn wdcrestart
|
|
with the first argument passed to
|
|
.Fn claim_hw
|
|
as argument.
|
|
This arguments will also be the one passed to
|
|
.Fn free_hw .
|
|
This function is called once the transfer is complete, so that the lock can
|
|
be released.
|
|
.Pp
|
|
Accesses to the data port are done by using the bus_space stream functions,
|
|
unless the
|
|
.Dv WDC_CAPABILITY_ATA_NOSTREAM
|
|
or
|
|
.Dv WDC_CAPABILITY_ATAPI_NOSTREAM
|
|
flags are set.
|
|
This should not be used, unless the data bus is not wired properly (which
|
|
seems common on big-endian systems), and byte-order needs to be preserved
|
|
for compatibility with the host's firmware.
|
|
Also note that the IDE bus is a little-endian bus, so the bus_space
|
|
functions used for the bus_space tag passed in the
|
|
.Va channel_softc
|
|
have to do the appropriate byte-swapping for big-endian systems.
|
|
.Pp
|
|
.Dv WDC_CAPABILITY_NO_EXTRA_RESETS
|
|
avoid the controller reset at the end of the disks probe.
|
|
This reset is needed for some controllers, but causes problems with some
|
|
others.
|
|
.Pp
|
|
.Dv WDC_CAPABILITY_NOIRQ
|
|
tells the driver that this controller doesn't have its interrupt lines
|
|
wired up usefully, so it should always use polled transfers.
|
|
.Pp
|
|
The bus front-end needs to fill in the following
|
|
elements of
|
|
.Va channel_softc :
|
|
.Bl -tag -compact -width "dma_finish" -offset "xxxx"
|
|
.It channel
|
|
The channel number on the controller
|
|
.It wdc
|
|
A pointer to the controller's wdc_softc
|
|
.It cmd_iot, cmd_ioh
|
|
Bus-space tag and handle for access to the command block registers (which
|
|
includes the 16-bit data port)
|
|
.It ctl_iot, ctl_ioh
|
|
Bus-space tag and handle for access to the control block registers
|
|
.It ch_queue
|
|
A pointer to a
|
|
.Va struct channel_queue .
|
|
This will hold the queues of outstanding commands for this controller.
|
|
.El
|
|
The following elements are optional:
|
|
.Bl -tag -compact -width "dma_finish" -offset "xxxx"
|
|
.It data32iot, data32ioh
|
|
Bus-space tag and handle for 32-bit data accesses.
|
|
Only needed if
|
|
.Dv WDC_CAPABILITY_DATA32
|
|
is set in the controller's
|
|
.Va wdc_softc .
|
|
.El
|
|
.Pp
|
|
.Va ch_queue
|
|
can point to a common
|
|
.Va struct channel_queue
|
|
if the controller doesn't support concurrent access to its different channels.
|
|
If all channels are independent, it is recommended that each channel has
|
|
its own
|
|
.Va ch_queue
|
|
(for better performance).
|
|
.Pp
|
|
The bus-specific front-end can use the
|
|
.Fn wdcprobe
|
|
function, with a properly initialised
|
|
.Va struct channel_softc
|
|
as argument (
|
|
.Va wdc
|
|
can be set to NULL.
|
|
This allows
|
|
.Fn wdcprobe
|
|
to be easily used in bus front-end probe functions).
|
|
This function will return an integer where bit 0 will be set if the master
|
|
device has been found, and 1 if the slave device has been found.
|
|
.Pp
|
|
The bus-specific attach function has to call
|
|
.Fn wdcattach
|
|
for each channel, with a pointer to a properly initialised
|
|
.Va channel softc
|
|
as argument.
|
|
This will probe devices attached to the IDE channel and attach them.
|
|
Once this function returns, the
|
|
.Va ch_drive
|
|
array of the
|
|
.Va channel_softc
|
|
will contain the drive's capabilities.
|
|
This can be used to properly initialise the controller's mode, or disable a
|
|
channel without drives.
|
|
.Pp
|
|
The elements of interest in
|
|
.Va ata_drive_datas
|
|
for a bus front-end are:
|
|
.Bl -tag -compact -width "dma_finish" -offset "xxxx"
|
|
.It drive
|
|
The drive number
|
|
.It drive_flags
|
|
Flags indicating the drive capabilities.
|
|
A null
|
|
.Va drive_flags
|
|
indicate either that no drive is here, or that no driver was
|
|
found for this device.
|
|
.It PIO_mode, DMA_mode, UDMA_mode
|
|
the highest supported modes for this drive compatible with the controller's
|
|
capabilities.
|
|
Needs to be reset to the mode to use by the drive, if known.
|
|
.It drv_softc
|
|
A pointer to the drive's softc.
|
|
Can be used to print the drive's name.
|
|
.El
|
|
.Pp
|
|
.Va drive_flags
|
|
handles the following flags:
|
|
.Bl -tag -compact -width "dma_finish" -offset "xxxx"
|
|
.It DRIVE_ATA, DRIVE_ATAPI
|
|
Gives the drive type, if any.
|
|
The shortcut DRIVE can be used to just test the presence/absence of a drive.
|
|
.It DRIVE_CAP32
|
|
This drive works with 32-bit data I/O.
|
|
.It DRIVE_DMA
|
|
This drive supports DMA.
|
|
.It DRIVE_UDMA
|
|
This drive supports Ultra-DMA.
|
|
.It DRIVE_MODE
|
|
This drive properly reported its PIO and DMA mode.
|
|
.El
|
|
.Pp
|
|
Once the controller has been initialised, it has to reset the
|
|
.Dv DRIVE_DMA
|
|
and
|
|
.Dv DRIVE_UDMA ,
|
|
as well as the values of
|
|
.Va PIO_mode ,
|
|
.Va DMA_mode
|
|
and
|
|
.Va UDMA_mode
|
|
if the modes to be used are not highest ones supported by the drive.
|
|
.Sh CODE REFERENCES
|
|
The wdc core functions are implemented in
|
|
.Pa sys/dev/ic/wdc.c .
|
|
Low-level ATA and ATAPI support is provided by
|
|
.Pa sys/dev/ata_wdc.c
|
|
and
|
|
.Pa sys/dev/scsipi/atapi_wdc.c
|
|
respectively.
|
|
.Pp
|
|
An example of a simple bus front-end can be found in
|
|
.Pa sys/dev/isapnp/wdc_isapnp.c .
|
|
A more complex one, with multiple channels and bus-master DMA support is
|
|
.Pa sys/dev/pci/pciide.c .
|
|
.Pa sys/arch/atari/dev/wdc_mb.c
|
|
makes use of hardware locking, and also provides an example of bus-front
|
|
end for a big-endian system, which needs byte-swapping bus_space functions.
|
|
.Sh SEE ALSO
|
|
.Xr wdc 4 ,
|
|
.Xr bus_space 9
|