ataDrv.c
资源名称:ixp425BSP.rar [点击查看]
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:90k
源码类别:
VxWorks
开发平台:
C/C++
- /* ataDrv.c - ATA/IDE and ATAPI CDROM (LOCAL and PCMCIA) disk device driver */
- /* Copyright 1989-2002 Wind River Systems, Inc. */
- #include "copyright_wrs.h"
- /*
- modification history
- --------------------
- 01y,29apr02,pmr SPR 76487: set up configType properly in ataDrv().
- 01x,15jan02,jkf SPR#72183, ataDevCreate missing ctrl parameter description.
- 01w,10dec01,jkf avoid 32 access to 16 bit boundary in ataPiBlkRd
- 01v,09dec01,jkf changed copyright to 2002
- 01u,08dec01,jkf fixed the NULL pointer accesses in ataPiPktCmdExec().
- 01t,08dec01,jkf SPR#28746, ataInit() caused extra int on some hardware
- 01s,19nov01,jac fixed mishandling of UNIT_ATTENTION condition for ATAPI
- devices.
- 01r,09nov01,jac SPR#67795, added support for ATAPI CD-ROMs (according to
- SFF-8020i) by merging changes from mjc's ATAPI driver
- extensions.
- 01q,24jul00,jkf SPR#29571, nSectors reset change,fixed typo in 01p.
- 01p,12jul00,rcs Reset nSectors back to nSecs in ataRW on retryRW SPR#29571.
- 01o,19sep99,jkf Removed extra SYS_ATA_INIT_RTN, now check wait in ataRW().
- 01n,17jul99,jkf using words 60-61 to determine LBA instead
- of CHS calculation, for big drives, 8.4Gb+. SPR#22830.
- 01m,04mar99,jkf Added SYS_ATA_INIT_RTN. _func_sysAtaInit. SPR#24378.
- 01l,09jun98,dat fixed conflicting prototypes, removed ref to sysMsDelay()
- 01k,09jun98,ms removed IMPORT prototypes conflicting with sysLib.h proto's
- 01j,31mar98,map removed INCLUDE_ATA, redefined sys* prototypes.
- 01i,23mar98,map renamed macros, made endian safe, added docs.
- 01h,30oct97,db added cmd to reinitialize controller with params read. fixed
- bug reported in SPR #9139. used PCI macros for input/output.
- 01g,21apr97,hdn fixed a semaphore timeout problem(SPR 8394).
- 01f,28feb97,dat fixed SPRs 8084, 3273 from ideDrv.
- 01e,06nov96,dgp doc: final formatting
- 01d,01nov96,hdn added support for PCMCIA.
- 01c,25sep96,hdn added support for ATA-2.
- 01b,01mar96,hdn cleaned up.
- 01a,02mar95,hdn written based on ideDrv.c.
- */
- /*
- DESCRIPTION
- This is a driver for ATA/IDE and ATAPI CDROM devices on PCMCIA, ISA, and other
- buses. The driver can be customized via various macros to run on a variety of
- boards and both big-endian, and little endian CPUs.
- USER-CALLABLE ROUTINES
- Most of the routines in this driver are accessible only through the I/O
- system. However, two routines must be called directly: ataDrv() to
- initialize the driver and ataDevCreate() to create devices.
- Before the driver can be used, it must be initialized by calling ataDrv().
- This routine must be called exactly once, before any reads, writes, or
- calls to ataDevCreate(). Normally, it is called from usrRoot() in
- usrConfig.c.
- The routine ataRawio() supports physical I/O access. The first
- argument is a drive number, 0 or 1; the second argument is a pointer
- to an ATA_RAW structure.
- NOTE
- Format is not supported, because ATA/IDE disks are already formatted, and bad
- sectors are mapped.
- During initialization this driver queries each disk to determine
- if the disk supports LBA. 16 bit words 0x60 and 0x61 (returned
- from the ATA IDENTIFY DEVICE command) may report a larger value
- than the product of the CHS fields on newer large disks (8.4Gb+).
- The driver will use strict LBA access commands and LBA geometry for
- drives reporting "total LBA sectors" greater than the product of CHS.
- Although everyone should also be using strict LBA on LBA disks, some
- older systems (mostly PC's) do not and use only CHS. Such system cannot
- view drives larger than 8GB. VxWorks does not have such limitations.
- However, it may be desirable to force VxWorks ignore the LBA information
- in favor of CHS in order to mount a file system originally formatted on
- a CHS only system. Setting the boolean ataForceCHSonLBA to TRUE will
- force the use of CHS parameters on all drives and the LBA parameters
- are ignored. Again, setting this boolean may prevent access to the
- drives full capacity, since some manufacturers have stopped setting
- a drives CHS accurately in favor of LBA.
- PARAMETERS
- The ataDrv() function requires a configuration flag as a parameter.
- The configuration flag is one of the following:
- .TS
- tab(|);
- l l .
- Transfer mode
- ATA_PIO_DEF_0 | PIO default mode
- ATA_PIO_DEF_1 | PIO default mode, no IORDY
- ATA_PIO_0 | PIO mode 0
- ATA_PIO_1 | PIO mode 1
- ATA_PIO_2 | PIO mode 2
- ATA_PIO_3 | PIO mode 3
- ATA_PIO_4 | PIO mode 4
- ATA_PIO_AUTO | PIO max supported mode
- ATA_DMA_0 | DMA mode 0
- ATA_DMA_1 | DMA mode 1
- ATA_DMA_2 | DMA mode 2
- ATA_DMA_AUTO | DMA max supported mode
- Transfer bits
- ATA_BITS_16 | RW bits size, 16 bits
- ATA_BITS_32 | RW bits size, 32 bits
- Transfer unit
- ATA_PIO_SINGLE | RW PIO single sector
- ATA_PIO_MULTI | RW PIO multi sector
- ATA_DMA_SINGLE | RW DMA single word
- ATA_DMA_MULTI | RW DMA multi word
- Geometry parameters
- ATA_GEO_FORCE | set geometry in the table
- ATA_GEO_PHYSICAL | set physical geometry
- ATA_GEO_CURRENT | set current geometry
- .TE
- DMA transfer is not supported in this release. If ATA_PIO_AUTO or ATA_DMA_AUTO
- is specified, the driver automatically chooses the maximum mode supported by the
- device. If ATA_PIO_MULTI or ATA_DMA_MULTI is specified, and the device does
- not support it, the driver automatically chooses single sector or word mode.
- If ATA_BITS_32 is specified, the driver uses 32-bit transfer mode regardless of
- the capability of the drive.
- If ATA_GEO_PHYSICAL is specified, the driver uses the physical geometry
- parameters stored in the drive. If ATA_GEO_CURRENT is specified,
- the driver uses current geometry parameters initialized by BIOS.
- If ATA_GEO_FORCE is specified, the driver uses geometry parameters stored
- in sysLib.c.
- The geometry parameters are stored in the structure table
- `ataTypes[]' in sysLib.c. That table has two entries, the first for
- drive 0, the second for drive 1. The members of the structure
- are:
- .CS
- int cylinders; /@ number of cylinders @/
- int heads; /@ number of heads @/
- int sectors; /@ number of sectors per track @/
- int bytes; /@ number of bytes per sector @/
- int precomp; /@ precompensation cylinder @/
- .CE
- This driver does not access the PCI-chip-set IDE interface, but rather takes
- advantage of BIOS or VxWorks initialization. Thus, the BIOS setting should
- match the modes specified by the configuration flag.
- The BSP may provide a sysAtaInit() routine for situations where an ATA
- controller RESET (0x1f6 or 0x3f6, bit 2 is set) clears ATA specific
- functionality in a chipset that is not re-enabled per the ATA-2 spec.
- This BSP routine should be declared in sysLib.c or sysAta.c as follows:
- .CS
- void sysAtaInit (BOOL ctrl)
- {
- /@ BSP SPECIFIC CODE HERE @/
- }
- .CE
- Then the BSP should perform the following operation
- before ataDrv() is called, in sysHwInit for example:
- .CS
- IMPORT VOIDFUNCPTR _func_sysAtaInit;
- /@ setup during initialization @/
- _func_sysAtaInit = (VOIDFUNCPTR) sysAtaInit;
- .CE
- It should contain chipset specific reset code, such as code which re-enables
- PCI write posting for an integrated PCI-IDE device, for example. This will
- be executed during every ataDrv(), ataInit(), and ataReset() or equivalent
- block device routine. If the sysAtaInit routine is not provided by the
- BSP it is ignored by the driver, therefore it is not a required BSP routine.
- SEE ALSO:
- .pG "I/O System"
- */
- #include "vxWorks.h"
- #include "taskLib.h"
- #include "ioLib.h"
- #include "memLib.h"
- #include "stdlib.h"
- #include "errnoLib.h"
- #include "stdio.h"
- #include "string.h"
- #include "private/semLibP.h"
- #include "intLib.h"
- #include "iv.h"
- #include "wdLib.h"
- #include "sysLib.h"
- #include "sys/fcntlcom.h"
- #include "drv/pcmcia/pcmciaLib.h"
- #include "logLib.h"
- #include "drv/hdisk/ataDrv.h"
- #define VXDOS "VXDOS"
- #define VXEXT "VXEXT"
- /* imports */
- IMPORT ATA_TYPE ataTypes [ATA_MAX_CTRLS][ATA_MAX_DRIVES];
- IMPORT ATA_RESOURCE ataResources [ATA_MAX_CTRLS];
- /* Byte swapping version of sysInWordString(), big-endian CPUs only */
- IMPORT void sysInWordStringRev (int port, short *pData, int count);
- /* defines */
- /* Read a BYTE from IO port, `ioAdrs' */
- #ifndef ATA_IO_BYTE_READ
- #define ATA_IO_BYTE_READ(ioAdrs) sysInByte (ioAdrs)
- #endif /* ATA_IO_BYTE_READ */
- /* Write a BYTE `byte' to IO port, `ioAdrs' */
- #ifndef ATA_IO_BYTE_WRITE
- #define ATA_IO_BYTE_WRITE(ioAdrs, byte) sysOutByte (ioAdrs, byte)
- #endif /* ATA_IO_BYTE_WRITE */
- /* Read 16-bit little-endian `nWords' into `pData' from IO port, `ioAdrs' */
- #ifndef ATA_IO_NWORD_READ
- #define ATA_IO_NWORD_READ(ioAdrs, pData, nWords)
- sysInWordString (ioAdrs, pData, nWords)
- #endif /* ATA_IO_NWORD_READ */
- /* Write 16-bit little-endian `nWords' from `pData' into IO port, `ioAdrs' */
- #ifndef ATA_IO_NWORD_WRITE
- #define ATA_IO_NWORD_WRITE(ioAdrs, pData, nWords)
- sysOutWordString (ioAdrs, pData, nWords)
- #endif /* ATA_IO_NWORD_WRITE */
- /* Read 32-bit little-endian `nLongs' into `pData' from IO port, `ioAdrs' */
- #ifndef ATA_IO_NLONG_READ
- #define ATA_IO_NLONG_READ(ioAdrs, pData, nLongs)
- sysInLongString (ioAdrs, pData, nLongs)
- #endif /* ATA_IO_NLONG_READ */
- /* Write 32-bit little-endian `nLongs' from `pData' into IO port, `ioAdrs' */
- #ifndef ATA_IO_NLONG_WRITE
- #define ATA_IO_NLONG_WRITE(ioAdrs, pData, nLongs)
- sysOutLongString (ioAdrs, pData, nLongs)
- #endif /* ATA_IO_NLONG_WRITE */
- /* Read 32-bit CPU-endian `nWords' into `pData' from IO port, `ioAdrs' */
- #ifndef ATA_IO_NWORD_READ_SWAP
- # if (_BYTE_ORDER == _BIG_ENDIAN)
- # define ATA_IO_NWORD_READ_SWAP(ioAdrs, pData, nWords)
- sysInWordStringRev (ioAdrs, pData, nWords)
- # else /* (_BYTE_ORDER == _BIG_ENDIAN) */
- # define ATA_IO_NWORD_READ_SWAP(ioAdrs, pData, nWords)
- ATA_IO_NWORD_READ (ioAdrs, pData, nWords)
- # endif /* (_BYTE_ORDER == _BIG_ENDIAN) */
- #endif /* ATA_IO_NLONG_READ_SWAP */
- /* Delay to ensure Status Register content is valid */
- #define ATA_WAIT_STATUS sysDelay () /* >= 400 ns */
- /* definitions relating to ATAPI commands */
- #define ATAPI_MAX_CMD_LENGTH 12 /* maximum length in bytes of a ATAPI command */
- #ifdef ATA_DEBUG
- int ataDebugLevel = 0; /* debug verbosity level */
- BOOL ataIntrDebug = 0; /* interrupt notification On */
- char * ataErrStrs [ ] = /* error reason strings */
- {
- "Unknown Error", /* 0 */
- "Wait for Command Packet request time expire", /* 1 */
- "Error in Command Packet Request", /* 2 */
- "Error in Command Packet Request", /* 3 */
- "Wait for Data Request time expire", /* 4 */
- "Data Request for NON Data command", /* 5 */
- "Error in Data Request", /* 6 */
- "Error in End of data transfer condition", /* 7 */
- "Extra transfer request", /* 8 */
- "Transfer size requested exceeds desired size", /* 9 */
- "Transfer direction miscompare", /* 10 */
- "No Sense", /* 11 */
- "Recovered Error", /* 12 */
- "Not Ready", /* 13 */
- "Medium Error", /* 14 */
- "Hardware Error", /* 15 */
- "Illegal Request", /* 16 */
- "Unit Attention", /* 17 */
- "Data Protected", /* 18 */
- "Aborted Command", /* 19 */
- "Miscompare", /* 20 */
- "