*nix Documentation Project
·  Home
 +   man pages
·  Linux HOWTOs
·  FreeBSD Tips
·  *niX Forums

  man pages->NetBSD man pages -> wdc (9)              



NAME    [Toc]    [Back]

     wdc - machine-independent IDE/ATAPI driver

SYNOPSIS    [Toc]    [Back]

     #include <dev/ata/atavar.h>
     #include <sys/dev/ic/wdcvar.h>

     wdcprobe(struct channel_softc * chp);

     wdcattach(struct channel_softc * chp);

DESCRIPTION    [Toc]    [Back]

     The wdc driver provides the machine independent core functions for driving
 IDE devices.  IDE devices-specific drivers ( wd or atapibus) will use
     services provided by wdc.

     The machine-dependent bus front-end provides informations to wdc with the
     wdc_softc and channel_softc structures.  The first one defines global
     controller properties, and the second contains per-channel informations.
     wdc returns informations about the attached devices in the
     ata_drive_datas structure.

     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
             u_int8_t      pio_mode;
             u_int8_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
             u_int8_t ch_status;
             u_int8_t ch_error;
             struct ata_drive_datas ch_drive[2];
             struct channel_queue *ch_queue;

     struct ata_drive_datas {
         u_int8_t drive;
         u_int8_t drive_flags;
     #define DRIVE_ATA   0x01
     #define DRIVE_ATAPI 0x02
     #define DRIVE_CAP32 0x04
     #define DRIVE_DMA   0x08
     #define DRIVE_UDMA  0x10
     #define DRIVE_MODE 0x20
         u_int8_t PIO_mode;
         u_int8_t DMA_mode;
         u_int8_t UDMA_mode;
         u_int8_t state;

         struct device *drv_softc;
         void* chnl_softc;

     The bus front-end needs to fill in the following elements of wdc_softc:
         cap         supports one or more of the WDC_CAPABILITY flags
         nchannels   number of channels supported by this controller
         channels    array of struct channel_softc of size nchannels properly
     The following elements are optional:

     The WDC_CAPABILITY_DATA16 and WDC_CAPABILITY_DATA32 flags informs wdc
     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.

     The WDC_CAPABILITY_DMA and WDC_CAPABILITY_UDMA flags are set for controllers
 supporting the DMA and Ultra-DMA modes.  The bus front-end needs
     to provide the dma_init(), dma_start() and dma_finish() functions.
     dma_init() is called just before issuing a DMA command to the IDE device.
     The arguments are, respectively: 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 WDC_DMA flags.  dma_start() is called just after
     issuing a DMA command to the IDE device.  The arguments are, respectively:
 dma_arg, the channel number, the drive number on this channel,
     and the WDC_DMA flags.  dma_finish() is called once the transfer is complete.
  The arguments are, respectively: dma_arg, the channel number, the
     drive number on this channel, and the WDC_DMA flags.  WDC_DMA_READ indicates
 the direction of the data transfer, and WDC_DMA_POLL indicates if
     the transfer will use (or used) interrupts.

     The WDC_CAPABILITY_MODE flag means that the bus front-end can program the
     PIO and DMA modes, so wdc needs to provide back the supported modes for
     each drive, and set the drives modes.  The pio_mode and dma_mode needs to
     be set to the highest PIO and DMA mode supported.  If WDC_CAPABILITY_UDMA
     is set, then dma_mode must be set to the highest Ultra-DMA mode supported.
  If WDC_CAPABILITY_MODE is not set, wdc will not attempt to
     change the current drive's settings, assuming the host's firmware has
     done it right.

     The 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 claim_hw() and free_hw() functions.
     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 wdcrestart() with the first
     argument passed to claim_hw() as argument.  This arguments will also be
     the one passed to free_hw().  This function is called once the transfer
     is complete, so that the lock can be released.

     Accesses to the data port are done by using the bus_space stream functions,
     WDC_CAPABILITY_ATAPI_NOSTREAM flags are set.  This should not be used,
     unless the data bus is not wired properly (which seems common on bigendian
 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
     channel_softc have to do the appropriate byte-swapping for big-endian

     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.

     The bus front-end needs to fill in the following elements of
         channel     The channel number on the controller
         wdc         A pointer to the controller's wdc_softc
         cmd_iot, cmd_ioh
                     Bus-space tag and handle for access to the command block
                     registers (which includes the 16-bit data port)
         ctl_iot, ctl_ioh
                     Bus-space tag and handle for access to the control block
         ch_queue    A pointer to a struct channel_queue.  This will hold the
                     queues of outstanding commands for this controller.
     The following elements are optional:
         data32iot, data32ioh
                     Bus-space tag and handle for 32-bit data accesses.  Only
                     needed if WDC_CAPABILITY_DATA32 is set in the controller's

     ch_queue can point to a common 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
     ch_queue (for better performance).

     The bus-specific front-end can use the wdcprobe() function, with a properly
 initialised struct channel_softc as argument ( wdc can be set to
     NULL.  This allows 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

     The bus-specific attach function has to call wdcattach() for each channel,
 with a pointer to a properly initialised channel softc as argument.
     This will probe devices attached to the IDE channel and attach them.
     Once this function returns, the ch_drive array of the 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.

     The elements of interest in ata_drive_datas for a bus front-end are:
         drive       The drive number
                     Flags indicating the drive capabilities.  A null
                     drive_flags indicate either that no drive is here, or
                     that no driver was found for this device.
         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.
         drv_softc   A pointer to the drive's softc.  Can be used to print the
                     drive's name.

     drive_flags handles the following flags:
                     Gives the drive type, if any.  The shortcut DRIVE can be
                     used to just test the presence/absence of a drive.
                     This drive works with 32-bit data I/O.
         DRIVE_DMA   This drive supports DMA.
         DRIVE_UDMA  This drive supports Ultra-DMA.
         DRIVE_MODE  This drive properly reported its PIO and DMA mode.

     Once the controller has been initialised, it has to reset the DRIVE_DMA
     and DRIVE_UDMA, as well as the values of PIO_mode, DMA_mode and UDMA_mode
     if the modes to be used are not highest ones supported by the drive.

SEE ALSO    [Toc]    [Back]

     wdc(4), bus_space(9)

CODE REFERENCES    [Toc]    [Back]

     The wdc core functions are implemented in sys/dev/ic/wdc.c.  Low-level
     ATA and ATAPI support is provided by sys/dev/ata_wdc.c and
     sys/dev/scsipi/atapi_wdc.c respectively.

     An example of a simple bus front-end can be found in
     sys/dev/isapnp/wdc_isapnp.c.  A more complex one, with multiple channels
     and bus-master DMA support is sys/dev/pci/pciide.c.
     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.

BSD                            October 18, 1998                            BSD
[ Back ]
 Similar pages
Name OS Title
cd OpenBSD ATAPI and SCSI CD-ROM driver
burncd FreeBSD control the ATAPI CD-R/RW driver
ata FreeBSD generic ATA/ATAPI disk controller driver
afd FreeBSD generic ATA/ATAPI disk controller driver
ast FreeBSD generic ATA/ATAPI disk controller driver
ad FreeBSD generic ATA/ATAPI disk controller driver
acd FreeBSD generic ATA/ATAPI disk controller driver
bus_dmamem_free OpenBSD bus and machine independent DMA mapping interface
bus_dmamap_create FreeBSD Bus and Machine Independent DMA Mapping Interface
bus_dma_tag_destroy FreeBSD Bus and Machine Independent DMA Mapping Interface
Copyright © 2004-2005 DeniX Solutions SRL
newsletter delivery service