ataDrv.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:90k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ataDrv.c - ATA/IDE and ATAPI CDROM (LOCAL and PCMCIA) disk device driver */
  2. /* Copyright 1989-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01y,29apr02,pmr  SPR 76487: set up configType properly in ataDrv().
  8. 01x,15jan02,jkf  SPR#72183, ataDevCreate missing ctrl parameter description.
  9. 01w,10dec01,jkf  avoid 32 access to 16 bit boundary in ataPiBlkRd
  10. 01v,09dec01,jkf  changed copyright to 2002
  11. 01u,08dec01,jkf  fixed the NULL pointer accesses in ataPiPktCmdExec().
  12. 01t,08dec01,jkf  SPR#28746, ataInit() caused extra int on some hardware
  13. 01s,19nov01,jac  fixed mishandling of UNIT_ATTENTION condition for ATAPI
  14.                  devices.
  15. 01r,09nov01,jac  SPR#67795, added support for ATAPI CD-ROMs (according to
  16.                  SFF-8020i) by merging changes from mjc's ATAPI driver
  17.                  extensions.
  18. 01q,24jul00,jkf  SPR#29571, nSectors reset change,fixed typo in 01p.
  19. 01p,12jul00,rcs  Reset nSectors back to nSecs in ataRW on retryRW SPR#29571.
  20. 01o,19sep99,jkf  Removed extra SYS_ATA_INIT_RTN, now check wait in ataRW().
  21. 01n,17jul99,jkf  using words 60-61 to determine LBA instead 
  22.  of CHS calculation, for big drives, 8.4Gb+. SPR#22830.
  23. 01m,04mar99,jkf  Added SYS_ATA_INIT_RTN.  _func_sysAtaInit. SPR#24378.
  24. 01l,09jun98,dat  fixed conflicting prototypes, removed ref to sysMsDelay()
  25. 01k,09jun98,ms   removed IMPORT prototypes conflicting with sysLib.h proto's
  26. 01j,31mar98,map  removed INCLUDE_ATA, redefined sys* prototypes.
  27. 01i,23mar98,map  renamed macros, made endian safe, added docs.
  28. 01h,30oct97,db   added cmd to reinitialize controller with params read. fixed
  29.                  bug reported in SPR #9139. used PCI macros for input/output.
  30. 01g,21apr97,hdn  fixed a semaphore timeout problem(SPR 8394).
  31. 01f,28feb97,dat  fixed SPRs 8084, 3273 from ideDrv.
  32. 01e,06nov96,dgp  doc: final formatting
  33. 01d,01nov96,hdn  added support for PCMCIA.
  34. 01c,25sep96,hdn  added support for ATA-2.
  35. 01b,01mar96,hdn  cleaned up.
  36. 01a,02mar95,hdn  written based on ideDrv.c.
  37. */
  38. /*
  39. DESCRIPTION
  40. This is a driver for ATA/IDE and ATAPI CDROM devices on PCMCIA, ISA, and other
  41. buses. The driver can be customized via various macros to run on a variety of
  42. boards and both big-endian, and little endian CPUs.
  43. USER-CALLABLE ROUTINES
  44. Most of the routines in this driver are accessible only through the I/O
  45. system.  However, two routines must be called directly:  ataDrv() to
  46. initialize the driver and ataDevCreate() to create devices.
  47. Before the driver can be used, it must be initialized by calling ataDrv().
  48. This routine must be called exactly once, before any reads, writes, or
  49. calls to ataDevCreate().  Normally, it is called from usrRoot() in
  50. usrConfig.c.
  51. The routine ataRawio() supports physical I/O access. The first
  52. argument is a drive number, 0 or 1; the second argument is a pointer
  53. to an ATA_RAW structure.
  54. NOTE
  55. Format is not supported, because ATA/IDE disks are already formatted, and bad
  56. sectors are mapped.
  57. During initialization this driver queries each disk to determine 
  58. if the disk supports LBA.  16 bit words 0x60 and 0x61 (returned 
  59. from the ATA IDENTIFY DEVICE command) may report a larger value 
  60. than the product of the CHS fields on newer large disks (8.4Gb+).  
  61. The driver will use strict LBA access commands and LBA geometry for 
  62. drives reporting "total LBA sectors" greater than the product of CHS.
  63. Although everyone should also be using strict LBA on LBA disks, some 
  64. older systems (mostly PC's) do not and use only CHS.  Such system cannot 
  65. view drives larger than 8GB.  VxWorks does not have such limitations.    
  66. However, it may be desirable to force VxWorks ignore the LBA information 
  67. in favor of CHS in order to mount a file system originally formatted on 
  68. a CHS only system.  Setting the boolean ataForceCHSonLBA to TRUE will 
  69. force the use of CHS parameters on all drives and the LBA parameters 
  70. are ignored.  Again, setting this boolean may prevent access to the 
  71. drives full capacity, since some manufacturers have stopped setting 
  72. a drives CHS accurately in favor of LBA.
  73. PARAMETERS
  74. The ataDrv() function requires a configuration flag as a parameter.
  75. The configuration flag is one of the following:
  76. .TS
  77. tab(|);
  78. l l .
  79. Transfer mode 
  80. ATA_PIO_DEF_0    | PIO default mode
  81. ATA_PIO_DEF_1    | PIO default mode, no IORDY
  82. ATA_PIO_0        | PIO mode 0
  83. ATA_PIO_1        | PIO mode 1
  84. ATA_PIO_2        | PIO mode 2
  85. ATA_PIO_3        | PIO mode 3
  86. ATA_PIO_4        | PIO mode 4
  87. ATA_PIO_AUTO     | PIO max supported mode
  88. ATA_DMA_0        | DMA mode 0
  89. ATA_DMA_1        | DMA mode 1
  90. ATA_DMA_2        | DMA mode 2
  91. ATA_DMA_AUTO     | DMA max supported mode
  92. Transfer bits
  93. ATA_BITS_16      | RW bits size, 16 bits
  94. ATA_BITS_32      | RW bits size, 32 bits
  95. Transfer unit
  96. ATA_PIO_SINGLE   | RW PIO single sector
  97. ATA_PIO_MULTI    | RW PIO multi sector
  98. ATA_DMA_SINGLE   | RW DMA single word
  99. ATA_DMA_MULTI    | RW DMA multi word
  100. Geometry parameters
  101. ATA_GEO_FORCE    | set geometry in the table
  102. ATA_GEO_PHYSICAL | set physical geometry
  103. ATA_GEO_CURRENT  | set current geometry
  104. .TE
  105. DMA transfer is not supported in this release.  If ATA_PIO_AUTO or ATA_DMA_AUTO
  106. is specified, the driver automatically chooses the maximum mode supported by the
  107. device.  If ATA_PIO_MULTI or ATA_DMA_MULTI is specified, and the device does
  108. not support it, the driver automatically chooses single sector or word mode.
  109. If ATA_BITS_32 is specified, the driver uses 32-bit transfer mode regardless of
  110. the capability of the drive.  
  111. If ATA_GEO_PHYSICAL is specified, the driver uses the physical geometry 
  112. parameters stored in the drive.  If ATA_GEO_CURRENT is specified,
  113. the driver uses current geometry parameters initialized by BIOS.  
  114. If ATA_GEO_FORCE is specified, the driver uses geometry parameters stored 
  115. in sysLib.c.
  116. The geometry parameters are stored in the structure table
  117. `ataTypes[]' in sysLib.c. That table has two entries, the first for
  118. drive 0, the second for drive 1. The members of the structure
  119. are:
  120. .CS
  121.     int cylinders;              /@ number of cylinders @/
  122.     int heads;                  /@ number of heads @/
  123.     int sectors;                /@ number of sectors per track @/
  124.     int bytes;                  /@ number of bytes per sector @/
  125.     int precomp;                /@ precompensation cylinder @/
  126. .CE
  127. This driver does not access the PCI-chip-set IDE interface, but rather takes
  128. advantage of BIOS or VxWorks initialization.  Thus, the BIOS setting should 
  129. match the modes specified by the configuration flag.
  130. The BSP may provide a sysAtaInit() routine for situations where an ATA
  131. controller RESET (0x1f6 or 0x3f6, bit 2 is set) clears ATA specific
  132. functionality in a chipset that is not re-enabled per the ATA-2 spec.
  133.  
  134. This BSP routine should be declared in sysLib.c or sysAta.c as follows:
  135.  
  136. .CS
  137. void sysAtaInit (BOOL ctrl)
  138.     {
  139.     /@ BSP SPECIFIC CODE HERE @/
  140.     }
  141. .CE
  142. Then the BSP should perform the following operation
  143. before ataDrv() is called, in sysHwInit for example:
  144. .CS
  145.     IMPORT VOIDFUNCPTR _func_sysAtaInit;
  146.     /@ setup during initialization @/
  147.     _func_sysAtaInit = (VOIDFUNCPTR) sysAtaInit;
  148. .CE
  149.  
  150. It should contain chipset specific reset code, such as code which re-enables
  151. PCI write posting for an integrated PCI-IDE device, for example.  This will
  152. be executed during every ataDrv(), ataInit(), and ataReset() or equivalent  
  153. block device routine.  If the sysAtaInit routine is not provided by the
  154. BSP it is ignored by the driver, therefore it is not a required BSP routine.
  155. SEE ALSO:
  156. .pG "I/O System"
  157. */
  158. #include "vxWorks.h"
  159. #include "taskLib.h"
  160. #include "ioLib.h"
  161. #include "memLib.h"
  162. #include "stdlib.h"
  163. #include "errnoLib.h"
  164. #include "stdio.h"
  165. #include "string.h"
  166. #include "private/semLibP.h"
  167. #include "intLib.h"
  168. #include "iv.h"
  169. #include "wdLib.h"
  170. #include "sysLib.h"
  171. #include "sys/fcntlcom.h"
  172. #include "drv/pcmcia/pcmciaLib.h"
  173. #include "logLib.h"
  174. #include "drv/hdisk/ataDrv.h"
  175. #define VXDOS                           "VXDOS"
  176. #define VXEXT                           "VXEXT"
  177. /* imports */
  178. IMPORT ATA_TYPE ataTypes [ATA_MAX_CTRLS][ATA_MAX_DRIVES];
  179. IMPORT ATA_RESOURCE ataResources [ATA_MAX_CTRLS];
  180. /* Byte swapping version of sysInWordString(), big-endian CPUs only */
  181. IMPORT void sysInWordStringRev (int port, short *pData, int count);
  182. /* defines */
  183. /* Read a BYTE from IO port, `ioAdrs' */
  184. #ifndef ATA_IO_BYTE_READ
  185. #define ATA_IO_BYTE_READ(ioAdrs) sysInByte (ioAdrs)
  186. #endif /* ATA_IO_BYTE_READ */
  187. /* Write a BYTE `byte' to IO port, `ioAdrs' */
  188. #ifndef ATA_IO_BYTE_WRITE
  189. #define ATA_IO_BYTE_WRITE(ioAdrs, byte) sysOutByte (ioAdrs, byte)
  190. #endif /* ATA_IO_BYTE_WRITE */
  191. /* Read 16-bit little-endian `nWords' into `pData' from IO port, `ioAdrs' */
  192. #ifndef ATA_IO_NWORD_READ
  193. #define ATA_IO_NWORD_READ(ioAdrs, pData, nWords)                        
  194. sysInWordString (ioAdrs, pData, nWords)
  195. #endif /* ATA_IO_NWORD_READ */
  196. /* Write 16-bit little-endian `nWords' from `pData' into IO port, `ioAdrs' */
  197. #ifndef ATA_IO_NWORD_WRITE
  198. #define ATA_IO_NWORD_WRITE(ioAdrs, pData, nWords)                       
  199. sysOutWordString (ioAdrs, pData, nWords)
  200. #endif /* ATA_IO_NWORD_WRITE */
  201.     
  202. /* Read 32-bit little-endian `nLongs' into `pData' from IO port, `ioAdrs' */
  203. #ifndef ATA_IO_NLONG_READ
  204. #define ATA_IO_NLONG_READ(ioAdrs, pData, nLongs)                        
  205. sysInLongString (ioAdrs, pData, nLongs)
  206. #endif /* ATA_IO_NLONG_READ */
  207. /* Write 32-bit little-endian `nLongs' from `pData' into IO port, `ioAdrs' */
  208. #ifndef ATA_IO_NLONG_WRITE
  209. #define ATA_IO_NLONG_WRITE(ioAdrs, pData, nLongs)                       
  210. sysOutLongString (ioAdrs, pData, nLongs)
  211. #endif /* ATA_IO_NLONG_WRITE */
  212. /* Read 32-bit CPU-endian `nWords' into `pData' from IO port, `ioAdrs' */
  213. #ifndef ATA_IO_NWORD_READ_SWAP
  214. #  if (_BYTE_ORDER == _BIG_ENDIAN)
  215. #  define ATA_IO_NWORD_READ_SWAP(ioAdrs, pData, nWords)                 
  216. sysInWordStringRev (ioAdrs, pData, nWords)
  217. #  else /* (_BYTE_ORDER == _BIG_ENDIAN) */
  218. #  define ATA_IO_NWORD_READ_SWAP(ioAdrs, pData, nWords)                 
  219. ATA_IO_NWORD_READ (ioAdrs, pData, nWords)
  220. #  endif /* (_BYTE_ORDER == _BIG_ENDIAN) */
  221. #endif /* ATA_IO_NLONG_READ_SWAP */
  222. /* Delay to ensure Status Register content is valid */
  223. #define ATA_WAIT_STATUS sysDelay () /* >= 400 ns */
  224. /* definitions relating to ATAPI commands */
  225. #define ATAPI_MAX_CMD_LENGTH 12 /* maximum length in bytes of a ATAPI command */
  226. #ifdef ATA_DEBUG
  227. int ataDebugLevel = 0; /* debug verbosity level */
  228. BOOL ataIntrDebug  = 0; /* interrupt notification On */
  229. char * ataErrStrs [ ] =  /* error reason strings */
  230.     {
  231.     "Unknown Error", /*  0 */
  232.     "Wait for Command Packet request time expire", /*  1 */
  233.     "Error in Command Packet Request", /*  2 */
  234.     "Error in Command Packet Request", /*  3 */
  235.     "Wait for Data Request time expire", /*  4 */
  236.     "Data Request for NON Data command", /*  5 */
  237.     "Error in Data Request", /*  6 */
  238.     "Error in End of data transfer condition", /*  7 */
  239.     "Extra transfer request", /*  8 */
  240.     "Transfer size requested exceeds desired size", /*  9 */
  241.     "Transfer direction miscompare", /* 10 */
  242.     "No Sense", /* 11 */
  243.     "Recovered Error", /* 12 */
  244.     "Not Ready", /* 13 */
  245.     "Medium Error", /* 14 */
  246.     "Hardware Error", /* 15 */
  247.     "Illegal Request", /* 16 */
  248.     "Unit Attention", /* 17 */
  249.     "Data Protected", /* 18 */
  250.     "Aborted Command", /* 19 */
  251.     "Miscompare", /* 20 */
  252.     "", /* 21 */
  253.     "", /* 22 */
  254.     "", /* 23 */
  255.     "", /* 24 */
  256.     "", /* 25 */
  257.     "Overlapped commands are not implemented", /* 26 */
  258.     "DMA transfer is not implemented", /* 27 */
  259.     };
  260. #   define ATA_DEBUG_MSG(lvl, fmt, a1, a2, a3, a4, a5, a6)
  261.         if ((lvl) <= ataDebugLevel)
  262.             logMsg (fmt, (int)(a1), (int)(a2), (int)(a3), (int)(a4), 
  263.                     (int)(a5), (int)(a6));
  264. #   define ATA_INTR_MSG(fmt, a1, a2, a3, a4, a5, a6)
  265.         if (ataIntrDebug)
  266.             logMsg (fmt, (int)(a1), (int)(a2), (int)(a3), (int)(a4), 
  267.                     (int)(a5), (int)(a6));
  268. #else
  269. #   define ATA_DEBUG_MSG(lvl, fmt, a1, a2, a3, a4, a5, a6)
  270. #   define ATA_INTR_MSG(fmt, a1, a2, a3, a4, a5, a6)
  271. #endif
  272. /* typedefs */
  273. typedef struct ATAPI_CMD
  274.     {
  275.     uint8_t cmdPkt [ATAPI_MAX_CMD_LENGTH];
  276.     char * * ppBuf;
  277.     uint32_t bufLength;
  278.     t_data_dir direction;
  279.     uint32_t desiredTransferSize;
  280.     BOOL dma;
  281.     BOOL overlap;
  282.     } ATAPI_CMD;
  283. /* Special BSP INIT After ATA Reset */
  284. #ifndef SYS_ATA_INIT_RTN
  285. #define SYS_ATA_INIT_RTN(ctrl)  if (_func_sysAtaInit != NULL)    
  286.                                     {                            
  287.                                     ((*_func_sysAtaInit)(ctrl)); 
  288.                                     }
  289. #endif
  290. /* globals */
  291. BOOL   ataDrvInstalled = FALSE; /* TRUE if installed */
  292. BOOL   ataForceCHSonLBA = FALSE; /* hack, forces use of CHS params */
  293. ATA_CTRL  ataCtrl [ATA_MAX_CTRLS];
  294. /* BSP specific ATA Init/Reset routine */
  295. VOIDFUNCPTR       _func_sysAtaInit = NULL;
  296. /* locals */
  297. LOCAL int       ataRetry = 3; /* max retry count */
  298. /* Used to hold LBA information, if larger than calculated CHS value */
  299. LOCAL UINT32 ataLbaTotalSecs [ATA_MAX_CTRLS][ATA_MAX_DRIVES];
  300. /* function prototypes */
  301. LOCAL STATUS ataBlkRd (ATA_DEV *pDev, int startBlk, int nBlks, char *p);
  302. LOCAL STATUS ataBlkWrt (ATA_DEV *pDev, int startBlk, int nBlks, char *p);
  303. LOCAL STATUS ataReset (ATA_DEV *pDev);
  304. LOCAL STATUS ataStatus (ATA_DEV *pDev);
  305. LOCAL STATUS ataIoctl (ATA_DEV *pDev, int function, int arg);
  306. LOCAL STATUS ataBlkRW (ATA_DEV *pDev, int startBlk, int nBlks, char *p,
  307.  int direction);
  308. LOCAL void   ataWdog (int ctrl);
  309. LOCAL void   ataIntr (int ctrl);
  310. LOCAL STATUS ataInit (int ctrl, int dev);
  311. LOCAL void   ataWait (int ctrl, int request);
  312. LOCAL STATUS ataCmd (int ctrl, int drive, int cmd, int arg0, int arg1);
  313. LOCAL STATUS ataPread (int ctrl, int drive, void *p);
  314. LOCAL STATUS ataRW (int ctrl, int drive, int cylinder, int head, int sec, 
  315.    void *p, int nSecs, int direction);
  316. LOCAL STATUS ataPiWait     (int ctrl, int request, BOOL reset);
  317. LOCAL STATUS ataPiBlkRd     (ATA_DEV *pDev, int startBlk, int nBlks, char *pBuf);
  318. LOCAL STATUS ataPiIoctl     (ATA_DEV *pDev, int function, int arg);
  319. LOCAL STATUS ataPiReset     (ATA_DEV *pAtapiDev);
  320. LOCAL STATUS ataPiStatusChk (ATA_DEV *pDev);
  321. LOCAL STATUS ataPiInit      (int ctrl, int dev);
  322. LOCAL STATUS ataPiPread     (int ctrl, int drive, void * buffer);
  323. LOCAL STATUS ataDevIdentify (int ctrl, int dev);
  324. /*******************************************************************************
  325. *
  326. * ataStub - block device stub
  327. *
  328. * This routine serves a as stub for a block device structure's routine pointers.
  329. *
  330. * RETURNS: ERROR always.
  331. */
  332. LOCAL STATUS ataStub (void)
  333.     {
  334.     return (ERROR);
  335.     } /* ataStub */
  336. /*******************************************************************************
  337. *
  338. * ataDriveInit - initialize ATA drive
  339. *
  340. * This routine checks the drive presents, identifies its type, initializes the 
  341. * drive controller and driver control structers.
  342. *
  343. * RETURNS: OK if drive was initialized successfuly, or ERROR.
  344. */
  345. STATUS ataDriveInit
  346.     (
  347.     int ctrl,
  348.     int drive
  349.     )
  350.     {
  351.     ATA_CTRL    *pCtrl = &ataCtrl[ctrl];
  352.     ATA_DRIVE   *pDrive = &pCtrl->drive[drive];
  353.     ATA_PARAM   *pParam = &pDrive->param;
  354.     ATA_TYPE    *pType = &ataTypes[ctrl][drive];
  355.     int configType = pCtrl->configType; /* configuration type */
  356.     if (!pCtrl->installed)
  357.         return (ERROR);
  358.     if (pType->cylinders == 0)
  359.         return (ERROR); /* user specified the device as not present */
  360.     semTake (&pCtrl->muteSem, WAIT_FOREVER);
  361.     /* Identify device presence and its type */
  362.     if (ataDevIdentify (ctrl, drive) != OK)
  363.         goto driveInitExit;
  364.     /* Set Reset function according to device type */
  365.     if (pDrive->type == ATA_TYPE_ATA)
  366.         pDrive->Reset = ataInit;
  367.     else if (pDrive->type == ATA_TYPE_ATAPI)
  368.         pDrive->Reset = ataPiInit;
  369.     if (pDrive->type == ATA_TYPE_ATA)
  370.         {
  371.         if (ataPread (ctrl, drive, (char *)pParam) == OK)
  372.             {
  373.     if ((pCtrl->ctrlType == ATA_PCMCIA) ||
  374. ((pCtrl->ctrlType != ATA_PCMCIA) && (drive == 0)))
  375. {
  376.                 if (ataCmd (ctrl, drive, ATA_CMD_DIAGNOSE, 0, 0) != OK)
  377.     {
  378.             semGive (&pCtrl->muteSem);
  379.             return (ERROR);
  380.     }
  381. }
  382.             /* find out geometry */
  383.             if ((configType & ATA_GEO_MASK) == ATA_GEO_FORCE)
  384.                 {
  385.                 (void) ataCmd (ctrl, drive, ATA_CMD_INITP, 0, 0);
  386.                 (void) ataPread (ctrl, drive, (char *)pParam);
  387.                 }
  388.             else if ((configType & ATA_GEO_MASK) == ATA_GEO_PHYSICAL)
  389.                 {
  390.                 pType->cylinders = pParam->cylinders - 1;
  391.                 pType->heads     = pParam->heads;
  392.                 pType->sectors   = pParam->sectors;
  393.                 }
  394.             else if ((configType & ATA_GEO_MASK) == ATA_GEO_CURRENT)
  395.                 {
  396.                 if ((pParam->currentCylinders != 0) &&
  397.                     (pParam->currentHeads != 0) &&
  398.                     (pParam->currentSectors != 0))
  399.                     {
  400.                     pType->cylinders = pParam->currentCylinders - 1;
  401.                     pType->heads     = pParam->currentHeads;
  402.                     pType->sectors   = pParam->currentSectors;
  403.                     }
  404.                 else
  405.                     {
  406.                     pType->cylinders = pParam->cylinders - 1;
  407.                     pType->heads     = pParam->heads;
  408.                     pType->sectors   = pParam->sectors;
  409.                     }
  410.                 }
  411.             /* 
  412.              * Not all modern hard drives report a true capacity value 
  413.              * in their IDENTIFY DEVICE CHS fields.
  414.              * For example, a Western Digital 20 Gb drive reports 
  415.              * its CHS as 16383 cylinders, 16 heads, and 63 spt.
  416.              * This is about 8.4GB, but the LBA sectors is reported
  417.              * as 0x02607780, which is closer to 20Gb, the true capacity
  418.              * of the drive.  The reason for this is PC BIOS can have a 
  419.              * 8.4GB limitation, and drive manufacturers have broken the 
  420.              * ATA specification to be compatable.  Negative competition. 
  421.              * Note that the ATA specifications original limit is 
  422.              * about 136.9 Gb, however when combinined with a PC BIOS 
  423.              * interface, a 8.4 Gb limit is produced.    
  424.              * VxWorks does not have such limitations being a true 32bit OS,
  425.              * but since the drive manufactures are not honoring the CHS
  426.              * values, we have to allow for devices that demand "pure" LBA
  427.              * and present incorrect CHS.
  428.              * If the drive supports Logical Block Addresses (LBA)
  429.              * then we need to check the field located at 16bit words 60 & 61,
  430.              * "Total number of user addressable sectors (LBA mode only)". 
  431.              * If this value is greater than the CHS fields report, 
  432.              * then 60-61 holds the true size of the disk and that 
  433.              * will be reported to the block device interface.
  434.              * Note that the CHS values are still left as the disk reported.
  435.              * This is tracked at WRS as SPR#22830
  436.              */
  437.             if (pParam->capabilities & 0x0200)  /* if (drive supports LBA) */
  438.                 {
  439.                 ataLbaTotalSecs[ctrl][drive] =  (UINT32) 
  440. ((((UINT32) ((pParam->sectors0) & 0x0000ffff)) <<  0) | 
  441.  (((UINT32) ((pParam->sectors1) & 0x0000ffff)) << 16));
  442.                 ATA_DEBUG_MSG (1, "ID_DRIVE reports LBA (60-61) as 0x%08lxn",
  443.                                ataLbaTotalSecs[ctrl][drive], 0, 0, 0, 0, 0);
  444.                 }
  445.             /*
  446.              * reinitialize the controller with parameters read from the
  447.              * controller.
  448.              */
  449.             (void) ataCmd (ctrl, drive, ATA_CMD_INITP, 0, 0);
  450.             /* recalibrate (this command !!! is absent in ATA-4) */
  451.             (void) ataCmd (ctrl, drive, ATA_CMD_RECALIB, 0, 0);
  452.             }
  453.         else
  454.             {
  455.             pDrive->state = ATA_DEV_PREAD_F;
  456.             goto driveInitExit;
  457.             }
  458.         }
  459.     else if (pDrive->type == ATA_TYPE_ATAPI)
  460.         {
  461.         /* Although ATAPI device parameters have been read by ataDevIdentify(), 
  462.          * execute ATAPI Identify Device command to allow ATA commands 
  463.          * acceptance by an ATAPI device after Diagnostic or Reset commands. 
  464.          */
  465.         if (ataPiPread (ctrl, drive, pParam) != OK)
  466.             {
  467.             pDrive->state = ATA_DEV_PREAD_F;
  468.             goto driveInitExit;
  469.             }
  470.         }
  471.     /* find out supported capabilities of the drive */
  472.     pDrive->multiSecs = pParam->multiSecs & 0x00ff;
  473.     pDrive->okMulti   = (pDrive->multiSecs != 0) ? TRUE : FALSE;
  474.     pDrive->okIordy   = (pParam->capabilities & 0x0800) ? TRUE : FALSE;
  475.     pDrive->okLba     = (pParam->capabilities & 0x0200) ? TRUE : FALSE;
  476.     pDrive->okDma     = (pParam->capabilities & 0x0100) ? TRUE : FALSE;
  477.     /* find out supported max PIO mode */
  478.     pDrive->pioMode = (pParam->pioMode >> 8) & 0x03; /* PIO 0,1,2 */
  479.     if (pDrive->pioMode > 2)
  480.         pDrive->pioMode = 0;
  481.     if ((pDrive->okIordy) && (pParam->valid & 0x02)) /* PIO 3,4 */
  482.         {
  483.         if (pParam->advancedPio & 0x01)
  484.             pDrive->pioMode = 3;
  485.         if (pParam->advancedPio & 0x02)
  486.             pDrive->pioMode = 4;
  487.         }
  488.     /* find out supported max DMA mode */
  489.     if ((pDrive->okDma) && (pParam->valid & 0x02))
  490.         {
  491.         pDrive->singleDmaMode = (pParam->dmaMode >> 8) & 0x03;
  492.         if (pDrive->singleDmaMode >= 2)
  493.             pDrive->singleDmaMode = 0;
  494.         pDrive->multiDmaMode  = 0;
  495.         if (pParam->singleDma & 0x04)
  496.             pDrive->singleDmaMode = 2;
  497.         else if (pParam->singleDma & 0x02)
  498.             pDrive->singleDmaMode = 1;
  499.         else if (pParam->singleDma & 0x01)
  500.             pDrive->singleDmaMode = 0;
  501.         if (pParam->multiDma & 0x04)
  502.             pDrive->multiDmaMode = 2;
  503.         else if (pParam->multiDma & 0x02)
  504.             pDrive->multiDmaMode = 1;
  505.         else if (pParam->multiDma & 0x01)
  506.             pDrive->multiDmaMode = 0;
  507.         }
  508.     /* find out transfer mode to use */
  509.     pDrive->rwBits = configType & ATA_BITS_MASK;
  510.     pDrive->rwPio  = configType & ATA_PIO_MASK;
  511.     pDrive->rwDma  = configType & ATA_DMA_MASK;
  512.     pDrive->rwMode = ATA_PIO_DEF_W;
  513.     switch (configType & ATA_MODE_MASK)
  514.         {
  515.         case ATA_PIO_0:
  516.         case ATA_PIO_1:
  517.         case ATA_PIO_2:
  518.         case ATA_PIO_3:
  519.         case ATA_PIO_4:
  520.         case ATA_PIO_DEF_0:
  521.         case ATA_PIO_DEF_1:
  522.             pDrive->rwMode = configType & ATA_MODE_MASK;
  523.             break;
  524.         case ATA_PIO_AUTO:
  525.             pDrive->rwMode = ATA_PIO_W_0 + pDrive->pioMode;
  526.             break;
  527.         case ATA_DMA_0:
  528.         case ATA_DMA_1:
  529.         case ATA_DMA_2:
  530.             if (pDrive->okDma)
  531.                 {
  532.                 if (pDrive->rwDma == ATA_DMA_SINGLE)
  533.                     pDrive->rwMode |= ATA_DMA_SINGLE_0;
  534.                 if (pDrive->rwDma == ATA_DMA_MULTI)
  535.                     pDrive->rwMode |= ATA_DMA_MULTI_0;
  536.                 }
  537.             break;
  538.         case ATA_DMA_AUTO:
  539.             if (pDrive->okDma)
  540.                 {
  541.                 if (pDrive->rwDma == ATA_DMA_SINGLE)
  542.                     pDrive->rwMode = ATA_DMA_SINGLE_0 + 
  543.                                      pDrive->singleDmaMode;
  544.                 if (pDrive->rwDma == ATA_DMA_MULTI)
  545.                     pDrive->rwMode = ATA_DMA_MULTI_0 + 
  546.                                      pDrive->multiDmaMode;
  547.                 }
  548.             break;
  549.         default:
  550.             break;
  551.         }
  552.     /* Set the transfer mode */
  553.     (void) ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_SET_RWMODE,
  554.                    pDrive->rwMode);
  555.     /* Disable reverting to power on defaults */
  556.     (void) ataCmd (ctrl, drive, ATA_CMD_SET_FEATURE, ATA_SUB_DISABLE_REVE, 0);
  557.     /* Set multiple mode (multisector read/write) */
  558.     if ((pDrive->rwPio == ATA_PIO_MULTI) && (pDrive->type == ATA_TYPE_ATA))
  559.         {
  560.         if (pDrive->okMulti)
  561.             (void) ataCmd (ctrl, drive, ATA_CMD_SET_MULTI,
  562.                            pDrive->multiSecs, 0);
  563.         else
  564.             pDrive->rwPio = ATA_PIO_SINGLE;
  565.         }
  566.     pDrive->state = ATA_DEV_OK;
  567. driveInitExit:
  568.     semGive (&pCtrl->muteSem);
  569.     if (pDrive->state != ATA_DEV_OK)
  570.         {
  571.         ATA_DEBUG_MSG (1, "ataDriveInit%d/%d: ERROR: state=%d dev=0x%x "
  572.                        "status=0x%x error=0x%xn", ctrl, drive, pDrive->state, 
  573.                        ATA_IO_BYTE_READ (pCtrl->sdh), 
  574.                        ATA_IO_BYTE_READ (pCtrl->status), 
  575.                        ATA_IO_BYTE_READ (pCtrl->error));
  576.         return (ERROR);
  577.         }
  578.     return (OK);
  579.     } /* ataDriveInit */
  580. /*******************************************************************************
  581. *
  582. * ataDrv - initialize the ATA driver
  583. *
  584. * This routine initializes the ATA/IDE/ATAPI CDROM driver, sets up interrupt
  585. * vectors, and performs hardware initialization of the ATA/IDE chip.
  586. *
  587. * This routine must be called exactly once, before any reads, writes,
  588. * or calls to ataDevCreate().  Normally, it is called by usrRoot()
  589. * in usrConfig.c.
  590. *
  591. * RETURNS: OK, or ERROR if initialization fails.
  592. *
  593. * SEE ALSO: ataDevCreate()
  594. */
  595. STATUS ataDrv
  596.     (
  597.     int  ctrl, /* controller no. */
  598.     int  drives, /* number of drives */
  599.     int  vector, /* interrupt vector */
  600.     int  level, /* interrupt level */
  601.     int  configType, /* configuration type */
  602.     int  semTimeout, /* timeout seconds for sync semaphore */
  603.     int  wdgTimeout /* timeout seconds for watch dog */
  604.     )
  605.     {
  606.     ATA_CTRL        *pCtrl = &ataCtrl[ctrl];
  607.     ATA_RESOURCE    *pAta = &ataResources[ctrl];
  608.     PCCARD_RESOURCE *pResource = &pAta->resource;
  609.     ATA_DRIVE       *pDrive;
  610.     ATA_PARAM       *pParam;
  611.     ATA_TYPE        *pType;
  612.     int             drive;
  613.     int             ix;
  614.     if ((ctrl >= ATA_MAX_CTRLS) || (drives > ATA_MAX_DRIVES))
  615. return (ERROR);
  616.     if (!ataDrvInstalled)
  617. {
  618. for (ix = 0; ix < ATA_MAX_CTRLS; ix++)
  619.             ataCtrl[ix].wdgId = wdCreate ();
  620.      ataDrvInstalled = TRUE;
  621. }
  622.     if (!pCtrl->installed)
  623. {
  624. if (semTimeout == 0)
  625.     pCtrl->semTimeout = ATA_SEM_TIMEOUT_DEF;
  626. else
  627.     pCtrl->semTimeout = semTimeout;
  628. if (wdgTimeout == 0)
  629.     pCtrl->wdgTimeout = ATA_WDG_TIMEOUT_DEF;
  630. else
  631.     pCtrl->wdgTimeout = wdgTimeout;
  632.         semBInit (&pCtrl->syncSem, SEM_Q_FIFO, SEM_EMPTY);
  633.         semMInit (&pCtrl->muteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  634.           SEM_INVERSION_SAFE);
  635. pCtrl->data = ATA_DATA (pResource->ioStart[0]);
  636. pCtrl->error = ATA_ERROR (pResource->ioStart[0]);
  637. pCtrl->feature = ATA_FEATURE (pResource->ioStart[0]);
  638. pCtrl->seccnt = ATA_SECCNT (pResource->ioStart[0]);
  639. pCtrl->sector = ATA_SECTOR (pResource->ioStart[0]);
  640. pCtrl->cylLo = ATA_CYL_LO (pResource->ioStart[0]);
  641. pCtrl->cylHi = ATA_CYL_HI (pResource->ioStart[0]);
  642. pCtrl->sdh = ATA_SDH (pResource->ioStart[0]);
  643. pCtrl->command = ATA_COMMAND (pResource->ioStart[0]);
  644. pCtrl->status = ATA_STATUS (pResource->ioStart[0]);
  645. pCtrl->aStatus = ATA_A_STATUS (pResource->ioStart[1]);
  646. pCtrl->dControl = ATA_D_CONTROL (pResource->ioStart[1]);
  647. pCtrl->dAddress = ATA_D_ADDRESS (pResource->ioStart[1]);
  648.         (void) intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (vector),
  649.            (VOIDFUNCPTR)ataIntr, ctrl);
  650.         sysIntEnablePIC (level); /* unmask the interrupt level */
  651. pCtrl->intLevel = level;
  652. pCtrl->wdgOkay  = TRUE;
  653. pCtrl->configType = configType;
  654. semTake (&pCtrl->muteSem, WAIT_FOREVER);
  655. pCtrl->installed = TRUE;
  656.         for (drive = 0; drive < drives; drive++)
  657.     {
  658.     pType  = &ataTypes[ctrl][drive];
  659.     pDrive = &pCtrl->drive[drive];
  660.     pParam = &pDrive->param;
  661.             pDrive->state = ATA_DEV_INIT;
  662.             pDrive->type = ATA_TYPE_INIT;
  663.             pDrive->diagCode = 0;
  664.             pDrive->Reset = ataInit;
  665.             ataDriveInit (ctrl, drive);
  666.             }
  667.         ATA_DEBUG_MSG (1, "ataDrv Calling sysAtaInit (if present):n",
  668.                       0, 0, 0, 0, 0, 0);
  669.  
  670. /* Call system INIT routine to allow proper PIO mode setup */
  671.         SYS_ATA_INIT_RTN (ctrl);
  672.  
  673.         ATA_DEBUG_MSG (1, "ataDrv sysAtaInit returned:n",
  674.                       0, 0, 0, 0, 0, 0);
  675. semGive (&pCtrl->muteSem);
  676. }
  677.     return (OK);
  678.     }
  679. /*******************************************************************************
  680. *
  681. * ataDevCreate - create a device for a ATA/IDE disk
  682. *
  683. * This routine creates a device for a specified ATA/IDE or ATAPI CDROM disk.
  684. *
  685. * <ctrl> is a controller number for the ATA controller; the primary controller
  686. * is 0.  The maximum is specified via ATA_MAX_CTRLS.
  687. *
  688. * <drive> is the drive number for the ATA hard drive; the master drive
  689. * is 0.  The maximum is specified via ATA_MAX_DRIVES.
  690. *
  691. * The <nBlocks> parameter specifies the size of the device in blocks.
  692. * If <nBlocks> is zero, the whole disk is used.
  693. *
  694. * The <blkOffset> parameter specifies an offset, in blocks, from the start
  695. * of the device to be used when writing or reading the hard disk.  This
  696. * offset is added to the block numbers passed by the file system during
  697. * disk accesses.  (VxWorks file systems always use block numbers beginning
  698. * at zero for the start of a device.)
  699. *
  700. *
  701. * RETURNS:
  702. * A pointer to a block device structure (BLK_DEV) or NULL if memory cannot
  703. * be allocated for the device structure.
  704. *
  705. * SEE ALSO: dosFsMkfs(), dosFsDevInit(), rt11FsDevInit(), rt11FsMkfs(),
  706. * rawFsDevInit()
  707. */
  708. BLK_DEV *ataDevCreate
  709.     (
  710.     int ctrl,     /* ATA controller number, 0 is the primary controller */
  711.     int drive,    /* ATA drive number, 0 is the master drive */
  712.     int nBlocks,  /* number of blocks on device, 0 = use entire disc */
  713.     int blkOffset /* offset BLK_DEV nBlocks from the start of the drive */
  714.     )
  715.     {
  716.     ATA_CTRL  *pCtrl = &ataCtrl[ctrl];
  717.     ATA_TYPE  *pType = &ataTypes[ctrl][drive];
  718.     ATA_DRIVE *pDrive = &pCtrl->drive[drive];
  719.     ATA_PARAM *pParam = &pDrive->param; /* move * */
  720.     ATA_DEV   *pDev;
  721.     BLK_DEV   *pBlkdev;
  722.     int       maxBlks;
  723.     if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||
  724.         !ataDrvInstalled || !pCtrl->installed)
  725. return (NULL);
  726.     if ((pDev = (ATA_DEV *)malloc(sizeof (ATA_DEV))) == NULL)
  727. return (NULL);
  728.     pBlkdev = &pDev->blkDev;
  729.     if ((pDrive->state == ATA_DEV_OK) || (pDrive->state == ATA_DEV_MED_CH))
  730.         {
  731.         pDrive->state = ATA_DEV_MED_CH;
  732.         if (pDrive->type == ATA_TYPE_ATA)
  733.             {
  734.     /* 
  735.      * if LBA is supported and ataLbaTotalSecs is not zero
  736.      * and ataLbaTotalSecs is greater than the product of
  737.      * CHS, then we should use the LBA value.
  738.      */
  739.             if ((pDrive->okLba == TRUE)                     && 
  740. (ataLbaTotalSecs[ctrl][drive] != 0)         &&
  741. (ataForceCHSonLBA != TRUE)     &&
  742. (ataLbaTotalSecs[ctrl][drive] > 
  743.  (pType->cylinders * pType->heads * pType->sectors)))   
  744.         {
  745. maxBlks = (ataLbaTotalSecs[ctrl][drive]) - blkOffset;
  746. }
  747.     else /* just use CHS */
  748.         {
  749. maxBlks = ((pType->cylinders * pType->heads * pType->sectors) 
  750.    - blkOffset);
  751. }
  752.     if (nBlocks == 0)
  753.         nBlocks = maxBlks;
  754.     
  755.     if (nBlocks > maxBlks)
  756.         nBlocks = maxBlks;
  757.     pBlkdev->bd_nBlocks = nBlocks;
  758.     pBlkdev->bd_bytesPerBlk = pType->bytes;
  759.     pBlkdev->bd_blksPerTrack = pType->sectors;
  760.     pBlkdev->bd_nHeads = pType->heads;
  761.     pBlkdev->bd_removable = TRUE;
  762.     pBlkdev->bd_retry = 1;
  763.     pBlkdev->bd_mode = O_RDWR;
  764.     pBlkdev->bd_readyChanged = TRUE;
  765.     pBlkdev->bd_blkRd = ataBlkRd;
  766.     pBlkdev->bd_blkWrt = ataBlkWrt;
  767.     pBlkdev->bd_ioctl = ataIoctl;
  768.     pBlkdev->bd_reset = ataReset;
  769.     pBlkdev->bd_statusChk = ataStatus;
  770.     pBlkdev->bd_reset = NULL;
  771.     pBlkdev->bd_statusChk = NULL;
  772.     pDev->ctrl = ctrl;
  773.     pDev->drive = drive;
  774.     pDev->blkOffset = blkOffset;
  775.     }
  776.         else if (pDrive->type == ATA_TYPE_ATAPI)
  777.             {
  778.             pBlkdev->bd_nBlocks         = 100;
  779.             pBlkdev->bd_bytesPerBlk     = 2048;
  780.             pBlkdev->bd_blksPerTrack    = pBlkdev->bd_nBlocks;
  781.             pBlkdev->bd_nHeads          = 1;
  782.             if (pParam->config & CONFIG_REMOVABLE)
  783.                 pBlkdev->bd_removable   = TRUE;
  784.             else
  785.                 pBlkdev->bd_removable   = FALSE;
  786.             pBlkdev->bd_retry           = 1;
  787.             pBlkdev->bd_mode            = O_RDONLY;
  788.             pBlkdev->bd_readyChanged    = TRUE;
  789.             pBlkdev->bd_blkRd           = ataPiBlkRd;
  790.             pBlkdev->bd_blkWrt          = ataStub;
  791.             pBlkdev->bd_ioctl           = ataPiIoctl;
  792.             pBlkdev->bd_reset           = ataPiReset;
  793.             pBlkdev->bd_statusChk       = ataPiStatusChk;
  794.     pDev->ctrl         = ctrl;
  795.     pDev->drive         = drive;
  796.     pDev->blkOffset         = blkOffset;
  797.             pDev->nBlocks               = nBlocks;
  798.     }
  799.         ataDriveInit (ctrl, drive);
  800.         pDrive->state = ATA_DEV_OK;
  801. }
  802.     return (&pDev->blkDev);
  803.     }
  804. /*******************************************************************************
  805. *
  806. * ataRawio - do raw I/O access
  807. *
  808. * This routine is called to perform raw I/O access.
  809. *
  810. * <drive> is a drive number for the hard drive: it must be 0 or 1.
  811. *
  812. * The <pAtaRaw> is a pointer to the structure ATA_RAW which is defined in 
  813. * ataDrv.h.
  814. *
  815. * RETURNS:
  816. * OK, or ERROR if the parameters are not valid.
  817. *
  818. */
  819. STATUS ataRawio
  820.     (
  821.     int      ctrl,
  822.     int      drive,
  823.     ATA_RAW  *pAtaRaw
  824.     )
  825.     {
  826.     ATA_CTRL  *pCtrl = &ataCtrl[ctrl];
  827.     ATA_DRIVE *pDrive = &pCtrl->drive[drive];
  828.     ATA_TYPE  *pType = &ataTypes[ctrl][drive];
  829.     ATA_DEV   ataDev;
  830.     BLK_DEV   *pBlkdev = &ataDev.blkDev;
  831.     UINT      startBlk;
  832.     if ((ctrl >= ATA_MAX_CTRLS) || (drive >= ATA_MAX_DRIVES) ||
  833.         !ataDrvInstalled || !pCtrl->installed)
  834. return (ERROR);
  835.     if ((pAtaRaw->cylinder >= pType->cylinders) ||
  836.         (pAtaRaw->head >= pType->heads) ||
  837.         (pAtaRaw->sector >  pType->sectors) ||
  838.         (pAtaRaw->sector == 0))
  839. return (ERROR);
  840.     /*
  841.      * if LBA is supported and ataLbaTotalSecs is not zero
  842.      * and ataLbaTotalSecs is greater than the product of
  843.      * CHS, then we should use the LBA value.
  844.      */
  845.     if ((pDrive->okLba == TRUE)                     && 
  846.     (ataLbaTotalSecs[ctrl][drive] != 0)         &&
  847. (ataForceCHSonLBA != TRUE)     &&
  848. (ataLbaTotalSecs[ctrl][drive] > 
  849. (pType->cylinders * pType->heads * pType->sectors)))   
  850. {
  851. pBlkdev->bd_nBlocks = ataLbaTotalSecs[ctrl][drive];
  852. }
  853.     else /* just use CHS value */
  854. {
  855.         pBlkdev->bd_nBlocks = pType->cylinders * pType->heads * 
  856.   pType->sectors;
  857. }
  858.     pBlkdev->bd_bytesPerBlk = pType->bytes;
  859.     pBlkdev->bd_blksPerTrack = pType->sectors;
  860.     pBlkdev->bd_nHeads = pType->heads;
  861.     pBlkdev->bd_removable = FALSE;
  862.     pBlkdev->bd_retry = 1;
  863.     pBlkdev->bd_mode = O_RDWR;
  864.     pBlkdev->bd_readyChanged = TRUE;
  865.     pBlkdev->bd_blkRd = ataBlkRd;
  866.     pBlkdev->bd_blkWrt = ataBlkWrt;
  867.     pBlkdev->bd_ioctl = ataIoctl;
  868.     pBlkdev->bd_reset = ataReset;
  869.     pBlkdev->bd_statusChk = ataStatus;
  870.     ataDev.ctrl = ctrl;
  871.     ataDev.drive = drive;
  872.     ataDev.blkOffset = 0;
  873.     startBlk = pAtaRaw->cylinder * (pType->sectors * pType->heads) +
  874.        pAtaRaw->head * pType->sectors + pAtaRaw->sector - 1;
  875.     return (ataBlkRW (&ataDev, startBlk, pAtaRaw->nSecs, pAtaRaw->pBuf,
  876.      pAtaRaw->direction));
  877.     }
  878. /*******************************************************************************
  879. *
  880. * ataBlkRd - read one or more blocks from a ATA/IDE disk
  881. *
  882. * This routine reads one or more blocks from the specified device,
  883. * starting with the specified block number.
  884. *
  885. * If any block offset was specified during ataDevCreate(), it is added
  886. * to <startBlk> before the transfer takes place.
  887. *
  888. * RETURNS: OK, ERROR if the read command didn't succeed.
  889. */
  890. LOCAL STATUS ataBlkRd
  891.     (
  892.     ATA_DEV *pDev,
  893.     int     startBlk,
  894.     int     nBlks,
  895.     char    *pBuf
  896.     )
  897.     {
  898.     return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_RDONLY));
  899.     }
  900. /*******************************************************************************
  901. *
  902. * ataBlkWrt - write one or more blocks to a ATA/IDE disk
  903. *
  904. * This routine writes one or more blocks to the specified device,
  905. * starting with the specified block number.
  906. *
  907. * If any block offset was specified during ataDevCreate(), it is added
  908. * to <startBlk> before the transfer takes place.
  909. *
  910. * RETURNS: OK, ERROR if the write command didn't succeed.
  911. */
  912. LOCAL STATUS ataBlkWrt
  913.     (
  914.     ATA_DEV *pDev,
  915.     int     startBlk,
  916.     int     nBlks,
  917.     char    *pBuf
  918.     )
  919.     {
  920.     return (ataBlkRW (pDev, startBlk, nBlks, pBuf, O_WRONLY));
  921.     }
  922. /*******************************************************************************
  923. *
  924. * ataReset - reset a ATA/IDE disk controller
  925. *
  926. * This routine resets a ATA/IDE disk controller.
  927. *
  928. * RETURNS: OK, always.
  929. */
  930. LOCAL STATUS ataReset
  931.     (
  932.     ATA_DEV  *pDev
  933.     )
  934.     {
  935.     ATA_CTRL *pCtrl = &ataCtrl[pDev->ctrl];
  936.     
  937.     if (!pCtrl->installed)
  938. return (ERROR);
  939.     semTake (&pCtrl->muteSem, WAIT_FOREVER);
  940.     (void) ataInit (pDev->ctrl, 0);
  941.     semGive (&pCtrl->muteSem);
  942.     return (OK);
  943.     }
  944. /*******************************************************************************
  945. *
  946. * ataStatus - check status of a ATA/IDE disk controller
  947. *
  948. * This routine check status of a ATA/IDE disk controller.
  949. *
  950. * RETURNS: OK, ERROR if the card is removed.
  951. */
  952. LOCAL STATUS ataStatus
  953.     (
  954.     ATA_DEV  *pDev
  955.     )
  956.     {
  957.     ATA_CTRL *pCtrl = &ataCtrl[pDev->ctrl];
  958.     BLK_DEV  *pBlkdev = &pDev->blkDev;
  959.     
  960.     if (!pCtrl->installed)
  961. return (ERROR);
  962.     if (pCtrl->changed)
  963. {
  964. pBlkdev->bd_readyChanged = TRUE;
  965. pCtrl->changed  = FALSE;
  966. }
  967.     return (OK);
  968.     }
  969. /*******************************************************************************
  970. *
  971. * ataIoctl - do device specific control function
  972. *
  973. * This routine is called when the file system cannot handle an ioctl()
  974. * function.
  975. *
  976. * RETURNS:  OK or ERROR.
  977. */
  978. LOCAL STATUS ataIoctl
  979.     (
  980.     ATA_DEV  *pDev,
  981.     int      function,
  982.     int      arg
  983.     )
  984.     {
  985.     ATA_CTRL *pCtrl = &ataCtrl[pDev->ctrl];
  986.     FAST int status = ERROR;
  987.     if (!pCtrl->installed)
  988.         return (ERROR);
  989.     semTake (&pCtrl->muteSem, WAIT_FOREVER);
  990.     switch (function)
  991. {
  992. case FIODISKFORMAT:
  993.     (void) errnoSet (S_ioLib_UNKNOWN_REQUEST);
  994.     break;
  995. default:
  996.     (void) errnoSet (S_ioLib_UNKNOWN_REQUEST);
  997. }
  998.     semGive (&pCtrl->muteSem);
  999.     return (status);
  1000.     }
  1001. /*******************************************************************************
  1002. *
  1003. * ataBlkRW - read or write sectors to a ATA/IDE disk.
  1004. *
  1005. * Read or write sectors to a ATA/IDE disk.
  1006. *
  1007. * RETURNS: OK, ERROR if the command didn't succeed.
  1008. */
  1009. LOCAL STATUS ataBlkRW
  1010.     (
  1011.     ATA_DEV *pDev,
  1012.     int     startBlk,
  1013.     int     nBlks,
  1014.     char    *pBuf,
  1015.     int     direction
  1016.     )
  1017.     {
  1018.     ATA_CTRL  *pCtrl = &ataCtrl[pDev->ctrl];
  1019.     ATA_DRIVE *pDrive = &pCtrl->drive[pDev->drive];
  1020.     BLK_DEV   *pBlkdev = &pDev->blkDev;
  1021.     ATA_TYPE  *pType = &ataTypes[pDev->ctrl][pDev->drive];
  1022.     int       status = ERROR;
  1023.     int       retryRW0 = 0;
  1024.     int       retryRW1 = 0;
  1025.     int       retrySeek = 0;
  1026.     int       cylinder;
  1027.     int       head;
  1028.     int       sector;
  1029.     int       nSecs;
  1030.     int       ix;
  1031.     /* sanity check */
  1032.     if (!pCtrl->installed)
  1033.         return (ERROR);
  1034.     nSecs = pBlkdev->bd_nBlocks;
  1035.     if ((startBlk + nBlks) > nSecs)
  1036. {
  1037. ATA_DEBUG_MSG (1, "startBlk=%d nBlks=%d: 0 - %dn", startBlk, nBlks, 
  1038.                        nSecs, 0, 0, 0);
  1039. return (ERROR);
  1040. }
  1041.     startBlk += pDev->blkOffset;
  1042.     semTake (&pCtrl->muteSem, WAIT_FOREVER);
  1043.     for (ix = 0; ix < nBlks; ix += nSecs)
  1044. {
  1045. if (pDrive->okLba)
  1046.     {
  1047.     head     = (startBlk & 0x0f000000) >> 24;
  1048.     cylinder = (startBlk & 0x00ffff00) >> 8;
  1049.     sector   = (startBlk & 0x000000ff);
  1050.     }
  1051. else
  1052.     {
  1053.     cylinder = startBlk / (pType->sectors * pType->heads);
  1054.     sector   = startBlk % (pType->sectors * pType->heads);
  1055.     head     = sector / pType->sectors;
  1056.     sector   = sector % pType->sectors + 1;
  1057.     }
  1058. nSecs    = min (nBlks - ix, ATA_MAX_RW_SECTORS);
  1059. retryRW1 = 0;
  1060. retryRW0 = 0;
  1061. while (ataRW(pDev->ctrl, pDev->drive, cylinder, head, sector, 
  1062.        pBuf, nSecs, direction) != OK)
  1063.     {
  1064.     if (++retryRW0 > ataRetry)
  1065. {
  1066.         (void)ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_RECALIB, 0, 0);
  1067.         if (++retryRW1 > ataRetry)
  1068.     goto done;
  1069.         retrySeek = 0;
  1070.         while (ataCmd (pDev->ctrl, pDev->drive, ATA_CMD_SEEK, cylinder,
  1071.        head) != OK)
  1072.             if (++retrySeek > ataRetry)
  1073.         goto done;
  1074.         retryRW0 = 0;
  1075. }
  1076.     }
  1077.         startBlk += nSecs;
  1078.         pBuf += pBlkdev->bd_bytesPerBlk * nSecs;
  1079. }
  1080.     status = OK;
  1081. done:
  1082.     if (status == ERROR)
  1083.         (void)errnoSet (S_ioLib_DEVICE_ERROR);
  1084.     semGive (&pCtrl->muteSem);
  1085.     return (status);
  1086.     }
  1087. /*******************************************************************************
  1088. *
  1089. * ataIntr - ATA/IDE controller interrupt handler.
  1090. *
  1091. * RETURNS: N/A
  1092. */
  1093. LOCAL void ataIntr
  1094.     (
  1095.     int ctrl
  1096.     )
  1097.     {
  1098.     ATA_CTRL *pCtrl = &ataCtrl[ctrl];
  1099.     pCtrl->intCount++;
  1100.     pCtrl->intStatus = ATA_IO_BYTE_READ (pCtrl->status);
  1101.     semGive (&pCtrl->syncSem);
  1102.     }
  1103. /*******************************************************************************
  1104. *
  1105. * ataWdog - ATA/IDE controller watchdog handler.
  1106. *
  1107. * RETURNS: N/A
  1108. */
  1109. LOCAL void ataWdog
  1110.     (
  1111.     int ctrl
  1112.     )
  1113.     {
  1114.     ATA_CTRL *pCtrl = &ataCtrl[ctrl];
  1115.     pCtrl->wdgOkay = FALSE;
  1116.     }
  1117. /*******************************************************************************
  1118. *
  1119. * ataWait - wait the ATA/ATAPI drive ready
  1120. *
  1121. * Wait the drive ready
  1122. *
  1123. * RETURNS: OK, ERROR if the drive didn't become ready in certain period of time.
  1124. */
  1125. LOCAL void ataWait
  1126.     (
  1127.     int ctrl,
  1128.     int request
  1129.     )
  1130.     {
  1131.     ATA_CTRL *pCtrl = &ataCtrl[ctrl];
  1132.     ATA_DEBUG_MSG (3, "ataWait: ctrl=%d  request=0x%xn", ctrl, request,
  1133.                   0, 0, 0, 0);
  1134.     switch (request)
  1135. {
  1136. case ATA_STAT_READY:
  1137.     wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 
  1138.      (FUNCPTR)ataWdog, ctrl);
  1139.             while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) && 
  1140.    (pCtrl->wdgOkay))
  1141.         ;
  1142.             while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0)
  1143.                    && (pCtrl->wdgOkay))
  1144.         ;
  1145.     wdCancel (pCtrl->wdgId);
  1146.             if (!pCtrl->wdgOkay)
  1147.         {
  1148.         pCtrl->wdgOkay = TRUE;
  1149.         (void) ataInit (ctrl, 0);
  1150.         }
  1151.     break;
  1152. case ATA_STAT_BUSY:
  1153.             while (ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY)
  1154. ;
  1155.     break;
  1156. case ATA_STAT_DRQ:
  1157.             while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) == 0)
  1158.         ;
  1159.     break;
  1160. case ATA_STAT_SEEKCMPLT:
  1161.             while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_SEEKCMPLT) == 0)
  1162.         ;
  1163.     break;
  1164. }
  1165.     ATA_DEBUG_MSG (3, "ataWait end:n", 0, 0, 0, 0, 0, 0);
  1166.     }
  1167. /*******************************************************************************
  1168. *
  1169. * ataPiWait - wait the ATAPI drive ready
  1170. *
  1171. * Wait the drive ready
  1172. *
  1173. * RETURNS: OK, ERROR if the drive didn't become ready in certain period of time.
  1174. */
  1175. LOCAL STATUS ataPiWait
  1176.     (
  1177.     int  ctrl,
  1178.     int  request,
  1179.     BOOL reset
  1180.     )
  1181.     {
  1182.     ATA_CTRL    *pCtrl = &ataCtrl[ctrl]; 
  1183.     ATA_DRIVE   *pDrive;
  1184.     int drive;
  1185.     ATA_DEBUG_MSG (3, "ataPiWait: ctrl=%d  request=0x%xn", ctrl, request,
  1186.                    0, 0, 0, 0);
  1187.     drive = (ATA_IO_BYTE_READ (pCtrl->sdh) >> 4) & 1;
  1188.     pDrive = &pCtrl->drive[drive];
  1189.     switch (request)
  1190. {
  1191. case ATA_STAT_READY:
  1192.     wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 
  1193.      (FUNCPTR)ataWdog, ctrl);
  1194.             while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) && 
  1195.    (pCtrl->wdgOkay))
  1196.         ;
  1197.             while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0)
  1198.                    && (pCtrl->wdgOkay))
  1199.         ;
  1200.             while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) &&
  1201.    (pCtrl->wdgOkay))
  1202.                 ;
  1203.     wdCancel (pCtrl->wdgId);
  1204.             if (!pCtrl->wdgOkay)
  1205.         {
  1206.         pCtrl->wdgOkay = TRUE;
  1207.                 if (reset == TRUE)
  1208.             (void) pDrive->Reset (ctrl, drive);
  1209.                 return (ERROR);
  1210.         }
  1211.     break;
  1212. case ATA_STAT_ACCESS:
  1213.     wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 
  1214.      (FUNCPTR)ataWdog, ctrl);
  1215.             while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) && 
  1216.    (pCtrl->wdgOkay))
  1217.         ;
  1218.             while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) &&
  1219.    (pCtrl->wdgOkay))
  1220.                 ;
  1221.     wdCancel (pCtrl->wdgId);
  1222.             if (!pCtrl->wdgOkay)
  1223.         {
  1224.         pCtrl->wdgOkay = TRUE;
  1225.                 if (reset == TRUE)
  1226.             (void) pDrive->Reset (ctrl, drive);
  1227.                 return (ERROR);
  1228.         }
  1229.     break;
  1230. case ATA_STAT_BUSY:
  1231.             while (ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY)
  1232. ;
  1233.     break;
  1234. case ATA_STAT_DRQ:
  1235.             while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_DRQ) == 0)
  1236.         ;
  1237.     break;
  1238. case ATA_STAT_SEEKCMPLT:
  1239.             while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_SEEKCMPLT) 
  1240.                    == 0)
  1241.         ;
  1242.     break;
  1243. }
  1244.     ATA_DEBUG_MSG (3, "ataPiWait end:n", 0, 0, 0, 0, 0, 0);
  1245.     return (OK);
  1246.     } /* ataPiWait */
  1247. /*******************************************************************************
  1248. *
  1249. * ataInit - init a ATA/IDE disk controller
  1250. *
  1251. * This routine initializes a ATA/IDE disk controller.
  1252. *
  1253. * RETURNS: OK, ERROR if the command didn't succeed.
  1254. */
  1255. LOCAL STATUS ataInit
  1256.     (
  1257.     int ctrl,
  1258.     int dev
  1259.     )
  1260.     {
  1261.     ATA_CTRL *pCtrl = &ataCtrl[ctrl];
  1262.     int      ix;
  1263.     ATA_DEBUG_MSG (2, "ataInit: ctrl=%dn", ctrl, 0, 0, 0, 0, 0);
  1264.     ATA_IO_BYTE_WRITE (pCtrl->dControl,
  1265.                        ATA_CTL_4BIT | ATA_CTL_RST);
  1266.     for (ix = 0; ix < 100; ix++)
  1267.         sysDelay ();
  1268.     ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT);
  1269.     for (ix = 0; ix < 100; ix++)
  1270.         sysDelay ();
  1271.     pCtrl->wdgOkay = TRUE;
  1272.     /* start the ata  watchdog */
  1273.     wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout),
  1274.      (FUNCPTR)ataWdog, ctrl);
  1275.     while ((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_BUSY) &&
  1276.            (pCtrl->wdgOkay))
  1277. ;
  1278.     ATA_IO_BYTE_WRITE (pCtrl->dControl, ATA_CTL_4BIT);
  1279.     for (ix = 0; ix < 100; ix++) 
  1280.         sysDelay ();
  1281.     while (((ATA_IO_BYTE_READ (pCtrl->aStatus) & ATA_STAT_READY) == 0) &&
  1282.    (pCtrl->wdgOkay))
  1283. ;
  1284.     wdCancel (pCtrl->wdgId);
  1285.     if (!pCtrl->wdgOkay)
  1286.         {
  1287. ATA_DEBUG_MSG (1, "ataInit error:n", 0, 0, 0, 0, 0, 0);
  1288.         pCtrl->wdgOkay = TRUE;
  1289.         return (ERROR);
  1290.         }
  1291.     ATA_DEBUG_MSG (3, "ataInit Calling sysAtaInit (if present):n",
  1292.                    0, 0, 0, 0, 0, 0);
  1293.     /* Call out to bsp specific setup routine */
  1294.     SYS_ATA_INIT_RTN (ctrl);
  1295.     ATA_DEBUG_MSG (3, "ataInit sysAtaInit returnedn", 0, 0, 0, 0, 0, 0);
  1296.     /*
  1297.      * The following allows recovery after an interrupt
  1298.      * caused by drive software reset
  1299.      */
  1300.     semBInit(&pCtrl->syncSem, SEM_Q_FIFO, SEM_EMPTY);
  1301.     ATA_DEBUG_MSG (2, "ataInit endn", 0, 0, 0, 0, 0, 0);
  1302.     return (OK);
  1303.     }
  1304. /*******************************************************************************
  1305. *
  1306. * ataCmd - issue non data command
  1307. *
  1308. * Issue a non data command.  Non data commands have the same protocol.
  1309. *
  1310. * RETURNS: OK, ERROR if the command didn't succeed.
  1311. */
  1312. LOCAL STATUS ataCmd
  1313.     (
  1314.     int ctrl,
  1315.     int drive,
  1316.     int cmd,
  1317.     int arg0,
  1318.     int arg1
  1319.     )
  1320.     {
  1321.     ATA_CTRL *pCtrl = &ataCtrl[ctrl];
  1322.     ATA_TYPE *pType = &ataTypes[ctrl][drive];
  1323.     BOOL     retry = TRUE;
  1324.     int      retryCount = 0;
  1325.     int      semStatus;
  1326.     ATA_DEBUG_MSG (2, "ataCmd%d/%d: cmd=0x%xn", ctrl, drive, cmd, arg0, arg1, 0);
  1327.     while (retry)
  1328. {
  1329.         ataWait (ctrl, ATA_STAT_READY);
  1330. switch (cmd)
  1331.     {
  1332.     case ATA_CMD_DIAGNOSE:
  1333.          ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
  1334. break;
  1335.     case ATA_CMD_INITP:
  1336. ATA_IO_BYTE_WRITE (pCtrl->cylLo, pType->cylinders);
  1337. ATA_IO_BYTE_WRITE (pCtrl->cylHi, pType->cylinders >> 8);
  1338. ATA_IO_BYTE_WRITE (pCtrl->seccnt, pType->sectors);
  1339. ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) | 
  1340.     ((pType->heads - 1) & 0x0f));
  1341. break;
  1342.     case ATA_CMD_RECALIB:
  1343. ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
  1344. break;
  1345.     case ATA_CMD_SEEK:
  1346. ATA_IO_BYTE_WRITE (pCtrl->cylLo, arg0);
  1347. ATA_IO_BYTE_WRITE (pCtrl->cylHi, arg0>>8);
  1348. ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4) |
  1349.     (arg1 & 0xf));
  1350. break;
  1351.     case ATA_CMD_SET_FEATURE:
  1352.          ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg1);
  1353.          ATA_IO_BYTE_WRITE (pCtrl->feature, arg0);
  1354.          ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
  1355. break;
  1356.     case ATA_CMD_SET_MULTI:
  1357.          ATA_IO_BYTE_WRITE (pCtrl->seccnt, arg0);
  1358.          ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
  1359. break;
  1360.     }
  1361.         ATA_IO_BYTE_WRITE (pCtrl->command, cmd);
  1362.         semStatus = semTake (&pCtrl->syncSem, 
  1363.      sysClkRateGet() * pCtrl->semTimeout);
  1364.         if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
  1365.     {
  1366.             ATA_DEBUG_MSG (1, "ataCmd err: status=0x%x semStatus=%d err=0x%xn",
  1367.                            pCtrl->intStatus, semStatus,
  1368.                            ATA_IO_BYTE_READ (pCtrl->error), 0, 0, 0);
  1369.     if (++retryCount > ataRetry)
  1370.         return (ERROR);
  1371.     }
  1372. else
  1373.     retry = FALSE;
  1374. }
  1375. switch (cmd)
  1376.     {
  1377.     case ATA_CMD_SEEK:
  1378. ataWait (ctrl, ATA_STAT_SEEKCMPLT);
  1379. break;
  1380.     }
  1381.     ATA_DEBUG_MSG (2, "ataCmd end - ctrl %d, drive %d: Okn", ctrl, drive, 0, 0, 0, 0);
  1382.     return (OK);
  1383.     }
  1384. /*******************************************************************************
  1385. *
  1386. * ataPread - Read drive parameters
  1387. *
  1388. * Read drive parameters.
  1389. *
  1390. * RETURNS: OK, ERROR if the command didn't succeed.
  1391. */
  1392. LOCAL STATUS ataPread
  1393.     (
  1394.     int      ctrl,
  1395.     int      drive,
  1396.     void     *buffer
  1397.     )
  1398.     {
  1399.     ATA_CTRL *pCtrl = &ataCtrl[ctrl];
  1400.     BOOL     retry = TRUE;
  1401.     int      retryCount = 0;
  1402.     int      semStatus;
  1403.     ATA_DEBUG_MSG (2, "ataPread: ctrl=%d drive=%dn", ctrl, drive, 0, 0, 0, 0);
  1404.     while (retry)
  1405. {
  1406.         ataWait (ctrl, ATA_STAT_READY);
  1407.         ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
  1408.         ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READP);
  1409.         semStatus = semTake (&pCtrl->syncSem, 
  1410.      sysClkRateGet() * pCtrl->semTimeout);
  1411.         if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
  1412.     {
  1413.             ATA_DEBUG_MSG (1, "ataPread%d/%d - err: status=0x%x intStatus=0x%x "
  1414.                           "error=0x%x semStatus=%dn", ctrl, drive, 
  1415.                           ATA_IO_BYTE_READ (pCtrl->aStatus), pCtrl->intStatus, 
  1416.                           ATA_IO_BYTE_READ (pCtrl->error), semStatus);
  1417.     if (++retryCount > ataRetry)
  1418.         return (ERROR);
  1419.     }
  1420.         else
  1421.     retry = FALSE;
  1422.         }
  1423.     ataWait (ctrl, ATA_STAT_DRQ);
  1424.     ATA_IO_NWORD_READ_SWAP (pCtrl->data, (short *)buffer, 256);
  1425.     ATA_DEBUG_MSG (2, "ataPread end:n", 0, 0, 0, 0, 0, 0);
  1426.     return (OK);
  1427.     }
  1428. /*******************************************************************************
  1429. *
  1430. * ataRW - read/write a number of sectors on the current track
  1431. *
  1432. * Read/write a number of sectors on the current track
  1433. *
  1434. * RETURNS: OK, ERROR if the command didn't succeed.
  1435. */
  1436. LOCAL STATUS ataRW
  1437.     (
  1438.     int ctrl,
  1439.     int drive,
  1440.     int cylinder,
  1441.     int head,
  1442.     int sector,
  1443.     void *buffer,
  1444.     int nSecs,
  1445.     int direction
  1446.     )
  1447.     {
  1448.     ATA_CTRL *pCtrl = &ataCtrl[ctrl];
  1449.     ATA_DRIVE *pDrive = &pCtrl->drive[drive];
  1450.     ATA_TYPE *pType = &ataTypes[ctrl][drive];
  1451.     int retryCount = 0;
  1452.     int block = 1;
  1453.     int nSectors;
  1454.     int nWords;
  1455.     int semStatus;
  1456.     short *pBuf;
  1457.     ATA_DEBUG_MSG (2, "ataRW: ctrl=%d drive=%d c=%d h=%d s=%d buf=0x%x ",
  1458.                    ctrl, drive, cylinder, head, sector, (int)buffer);
  1459.     ATA_DEBUG_MSG (2, "n=%d dir=%dn", nSecs, direction, 0, 0, 0, 0);
  1460. retryRW:
  1461.     ataWait (ctrl, ATA_STAT_READY);
  1462.     pBuf = (short *)buffer;
  1463.     nSectors = nSecs;
  1464.     ATA_IO_BYTE_WRITE (pCtrl->feature, pType->precomp);
  1465.     ATA_IO_BYTE_WRITE (pCtrl->seccnt, nSecs);
  1466.     ATA_IO_BYTE_WRITE (pCtrl->sector, sector);
  1467.     ATA_IO_BYTE_WRITE (pCtrl->cylLo, cylinder);
  1468.     ATA_IO_BYTE_WRITE (pCtrl->cylHi, cylinder>>8);
  1469.     if (pDrive->okLba)
  1470.         ATA_IO_BYTE_WRITE (pCtrl->sdh,
  1471.                            ATA_SDH_LBA | (drive << 4) | (head & 0xf));
  1472.     else
  1473.         ATA_IO_BYTE_WRITE (pCtrl->sdh,
  1474.                            ATA_SDH_IBM | (drive << 4) | (head & 0xf));
  1475.     if (pDrive->rwPio == ATA_PIO_MULTI)
  1476. block = pDrive->multiSecs;
  1477.     nWords = (pType->bytes * block) >> 1;
  1478.     if (direction == O_WRONLY)
  1479. {
  1480.         if (pDrive->rwPio == ATA_PIO_MULTI)
  1481.     ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_WRITE_MULTI);
  1482. else
  1483.     ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_WRITE);
  1484. while (nSectors > 0)
  1485.     {
  1486.     if ((pDrive->rwPio == ATA_PIO_MULTI) && (nSectors < block))
  1487. {
  1488. block = nSectors;
  1489. nWords = (pType->bytes * block) >> 1;
  1490. }
  1491.             ataWait (ctrl, ATA_STAT_BUSY);
  1492.             ataWait (ctrl, ATA_STAT_DRQ);
  1493.     if (pDrive->rwBits == ATA_BITS_16)
  1494.         ATA_IO_NWORD_WRITE (pCtrl->data, pBuf, nWords);
  1495.     else
  1496.         ATA_IO_NLONG_WRITE (pCtrl->data, (long *)pBuf, nWords >> 1);
  1497.             semStatus = semTake (&pCtrl->syncSem, 
  1498.  sysClkRateGet() * pCtrl->semTimeout);
  1499.          if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
  1500.         goto errorRW;
  1501.     pBuf     += nWords;
  1502.     nSectors -= block;
  1503.             }
  1504. }
  1505.     else
  1506. {
  1507.         if (pDrive->rwPio == ATA_PIO_MULTI)
  1508.     ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READ_MULTI);
  1509. else
  1510.     ATA_IO_BYTE_WRITE (pCtrl->command, ATA_CMD_READ);
  1511. while (nSectors > 0)
  1512.     {
  1513.     if ((pDrive->rwPio == ATA_PIO_MULTI) && (nSectors < block))
  1514. {
  1515. block = nSectors;
  1516. nWords = (pType->bytes * block) >> 1;
  1517. }
  1518.             semStatus = semTake (&pCtrl->syncSem, 
  1519.  sysClkRateGet() * pCtrl->semTimeout);
  1520.          if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
  1521.         goto errorRW;
  1522.             ataWait (ctrl, ATA_STAT_BUSY); /* wait for slow disk */
  1523.             ataWait (ctrl, ATA_STAT_DRQ);
  1524.     if (pDrive->rwBits == ATA_BITS_16)
  1525.         ATA_IO_NWORD_READ (pCtrl->data, pBuf, nWords);
  1526.     else
  1527.         ATA_IO_NLONG_READ (pCtrl->data, (long *)pBuf, nWords >> 1);
  1528.     pBuf     += nWords;
  1529.     nSectors -= block;
  1530.     }
  1531. }
  1532.     ATA_DEBUG_MSG (2, "ataRW: endn", 0, 0, 0, 0, 0, 0);
  1533.     return (OK);
  1534. errorRW:
  1535.     ATA_DEBUG_MSG (1, "ataRW err: stat=0x%x 0x%x semStatus=%d error=0x%xn",
  1536.            pCtrl->intStatus, ATA_IO_BYTE_READ (pCtrl->aStatus), 
  1537.                    semStatus, ATA_IO_BYTE_READ (pCtrl->error), 0, 0);
  1538.     if (++retryCount < ataRetry)
  1539. goto retryRW;
  1540.     return (ERROR);
  1541.     }
  1542. /******************************* ATAPI Devices *********************************/
  1543. /*******************************************************************************
  1544. *
  1545. * ataDevIdentify - identify device
  1546. *
  1547. * This routine checks whether the device is connected to the controller, and if
  1548. * so determines its type.  The routine set `type' field in the corresponding 
  1549. * ATA_DRIVE structure.
  1550. * If device identification failed, the routine set `state' field in the 
  1551. * corresponding ATA_DRIVE structure to ATA_DEV_NONE.
  1552. *
  1553. * RETURNS: TRUE if a device is present, FALSE otherwise
  1554. */
  1555. LOCAL STATUS ataDevIdentify
  1556.     (
  1557.     int ctrl,
  1558.     int dev
  1559.     )
  1560.     {
  1561.     ATA_CTRL    *pCtrl = &ataCtrl[ctrl];
  1562.     ATA_DRIVE   *pDrive = &pCtrl->drive [dev];
  1563.     ATA_PARAM   *pParam = &pDrive->param;
  1564.     pDrive->type = ATA_TYPE_NONE;
  1565.     /* Select device */ 
  1566.     ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (dev << 4));
  1567.  
  1568.     /* Wait for device selection */
  1569.  
  1570.     ATA_WAIT_STATUS;
  1571.  
  1572.     /* Clear semaphore: Selection of nonexistent device may rise an interrupt */
  1573.     semTake (&pCtrl->syncSem, NO_WAIT);
  1574.     ATA_IO_BYTE_WRITE (pCtrl->seccnt, 0xaa);
  1575.     ATA_IO_BYTE_WRITE (pCtrl->sector, 0x55);
  1576.  
  1577.     if (ATA_IO_BYTE_READ (pCtrl->seccnt) == 0xaa)
  1578.         {
  1579.         if (ataPiPread (ctrl, dev, pParam) == OK)
  1580.             {
  1581.             pDrive->type = ATA_TYPE_ATAPI;
  1582.             }
  1583.         else 
  1584.             if ( ((ATA_IO_BYTE_READ (ATAPI_STATUS) & (ATA_STAT_BUSY | 
  1585.    ATA_STAT_WRTFLT | ATA_STAT_DRQ | ATA_STAT_ERR)) == 
  1586.                    ATA_STAT_ERR) &&
  1587.                   (ATA_IO_BYTE_READ (ATAPI_ERROR) == ERR_ABRT) )
  1588.                 {
  1589.                 if (ataPiWait (ctrl, ATA_STAT_READY, FALSE) == OK)
  1590.                     pDrive->type = ATA_TYPE_ATA;
  1591.                 }
  1592.         }
  1593.  
  1594.     if (pDrive->type != ATA_TYPE_NONE)
  1595.         return (OK);
  1596.     ATA_DEBUG_MSG (1, "ataDevIdentify%d/%d: ERROR: status=0x%x dev=0x%x "
  1597.                    "error=0x%xn", ctrl, dev, ATA_IO_BYTE_READ (pCtrl->status),
  1598.                    ATA_IO_BYTE_READ (pCtrl->sdh), 
  1599.                    ATA_IO_BYTE_READ (pCtrl->error), 0);
  1600.     /* Select present device */
  1601.     ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (((~dev) & 0x1) << 4)); /* define macro for 0x1 */
  1602.     pDrive->state = ATA_DEV_NONE;
  1603.     return (ERROR);
  1604.     } /* ataDevIdentify */
  1605. /*******************************************************************************
  1606. *
  1607. * ataPiInit - init a ATAPI CD-ROM disk controller
  1608. *
  1609. * This routine resets a ATAPI CD-ROM disk controller.
  1610. *
  1611. * RETURNS: OK, ERROR if the command didn't succeed.
  1612. */
  1613. LOCAL STATUS ataPiInit 
  1614.     (
  1615.     int ctrl,
  1616.     int drive
  1617.     )
  1618.     {
  1619.     ATA_CTRL    *pCtrl = &ataCtrl[ctrl];
  1620.     int retryCount = 0;
  1621.     int i;
  1622.     ATA_DEBUG_MSG (2, "ataPiInit%d/%d: n", ctrl, drive, 0, 0, 0, 0);
  1623.     while (TRUE) /* Forever */
  1624.         {
  1625.         ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (drive << 4));
  1626.         ATA_WAIT_STATUS;
  1627.         ATA_IO_BYTE_WRITE (ATAPI_COMMAND, ATA_PI_CMD_SRST);
  1628.         for (i = 0; i < 5000; i++) /* 2 ms */
  1629.             {
  1630.             ATA_WAIT_STATUS;
  1631.             }
  1632.         ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (drive << 4));
  1633.         ATA_WAIT_STATUS;
  1634.         pCtrl->wdgOkay = TRUE;
  1635.         wdStart (pCtrl->wdgId, (sysClkRateGet() * pCtrl->wdgTimeout), 
  1636.                  (FUNCPTR)ataWdog, ctrl);
  1637.         while ( (ATA_IO_BYTE_READ (ATAPI_STATUS) & (ATA_STAT_BUSY | 
  1638.                  ATA_STAT_READY | ATA_STAT_WRTFLT | ATA_STAT_DRQ | 
  1639.                  ATA_STAT_ECCCOR | ATA_STAT_ERR)) && (pCtrl->wdgOkay) )
  1640.     ;
  1641.         wdCancel (pCtrl->wdgId);
  1642.         if (pCtrl->wdgOkay)
  1643.             break;
  1644.         pCtrl->wdgOkay = TRUE;
  1645.         ATA_DEBUG_MSG (1, "ataPiInit%d/%d: ERROR: status=0x%x error=0x%xn", 
  1646.                        ctrl, drive, ATA_IO_BYTE_READ(ATAPI_STATUS), 
  1647.                        ATA_IO_BYTE_READ(ATAPI_ERROR), 0, 0);
  1648. if (++retryCount == ataRetry)
  1649.     return (ERROR);
  1650.         }
  1651.     /* The following allow to recover after accidental interrupt */
  1652.     if (semTake (&pCtrl->syncSem, NO_WAIT) == OK)
  1653.         {
  1654.         ATA_DEBUG_MSG (2, "ataPiInit%d/%d: WARNING: interrupt cleared: "
  1655.                        "status=0x%x dev=0x%x error=0x%xn", ctrl, drive, 
  1656.                        ATA_IO_BYTE_READ(ATAPI_STATUS), 
  1657.                        ATA_IO_BYTE_READ(ATAPI_D_SELECT), 
  1658.                        ATA_IO_BYTE_READ(ATAPI_ERROR), 0);
  1659.         }
  1660.     else
  1661.         {
  1662.         ATA_DEBUG_MSG (2, "ataPiInit%d/%d: Ok: status=0x%x dev=0x%x error=0x%x"
  1663.                        "n", ctrl, drive, ATA_IO_BYTE_READ(ATAPI_STATUS), 
  1664.                        ATA_IO_BYTE_READ(ATAPI_D_SELECT), 
  1665.                        ATA_IO_BYTE_READ(ATAPI_ERROR), 0);
  1666.         }
  1667.     return (OK);
  1668.     } /* ataPiInit */
  1669. /*******************************************************************************
  1670. *
  1671. * ataPiPread - Read ATAPI drive parameters
  1672. *
  1673. * This routine reads drive parameters.
  1674. *
  1675. * RETURNS: OK, ERROR if the command didn't succeed.
  1676. */
  1677. LOCAL STATUS ataPiPread
  1678.     (
  1679.     int ctrl,
  1680.     int drive,
  1681.     void        *buffer
  1682.     )
  1683.     {
  1684.     ATA_CTRL    *pCtrl = &ataCtrl[ctrl];
  1685.     int status;
  1686.     int error;
  1687.     int semStatus;
  1688.     ATA_DEBUG_MSG (2, "ataPiPread%d/%d: n", ctrl, drive, 0, 0, 0, 0);
  1689.     ataPiWait (ctrl, ATA_STAT_ACCESS, TRUE);
  1690.     /* Select device */
  1691.     ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (drive << 4));
  1692.     ATA_WAIT_STATUS;
  1693.     if (ataPiWait (ctrl, ATA_STAT_ACCESS, TRUE) != OK)
  1694.         {
  1695.         ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (drive << 4));;
  1696.         ATA_WAIT_STATUS;
  1697.         }
  1698.     /* ATAPI Identify Device Command */
  1699.     ATA_IO_BYTE_WRITE (ATAPI_COMMAND, ATA_PI_CMD_IDENTD);
  1700.     ATA_WAIT_STATUS;
  1701.     /*
  1702.      * Poll Status Register instead of wait for interrupt to avoid needless 
  1703.      * delay.
  1704.      */
  1705.     ataPiWait (ctrl, ATA_STAT_BUSY, FALSE);
  1706.     semStatus = semTake (&pCtrl->syncSem, 1);
  1707.     status = ATA_IO_BYTE_READ (ATAPI_STATUS);
  1708.     if ( (status & ATA_STAT_ERR) || !(status & ATA_STAT_DRQ) || 
  1709.          (semStatus != OK) )
  1710.         {
  1711.         error = ATA_IO_BYTE_READ (ATAPI_ERROR);
  1712.         ATA_DEBUG_MSG (1, "ataPiPread%d/%d: ERROR: status=0x%x intStatus=0x%x "
  1713.                       "error=0x%x semStatus=%dn", ctrl, drive, status, 
  1714.                        pCtrl->intStatus, error, semStatus);
  1715.         return (ERROR);
  1716.         }
  1717.     /* Receive parameter information from the drive */
  1718.     ATA_IO_NWORD_READ_SWAP (ATAPI_DATA, (short *)buffer, 
  1719.                             sizeof(ATA_PARAM)/sizeof(short));
  1720.     /* To prevent from reading status before it is valid */
  1721.     ATA_IO_BYTE_READ (pCtrl->aStatus);
  1722.     /* Wait for device to be ready !!! */
  1723.     ataPiWait (ctrl, ATA_STAT_READY, TRUE);
  1724.     ATA_DEBUG_MSG (2, "ataPiPread%d/%d:Ok: status=0x%x devReg=0x%xn", 
  1725.                   ctrl, drive, ATA_IO_BYTE_READ (pCtrl->status), 
  1726.                   ATA_IO_BYTE_READ (pCtrl->sdh), 0, 0);
  1727.     return (OK);
  1728.     } /* ataPiPread */
  1729. /*******************************************************************************
  1730. *
  1731. * atapiDMAInit - initialize the DMA engine
  1732. *
  1733. * This routine initializes the DMA engine.
  1734. *
  1735. * RETURN: OK, or ERROR
  1736. */
  1737. LOCAL STATUS atapiDMAInit (void)
  1738.     {
  1739.     printErr("ATAPI (DMA Init.) ERROR: DMA transfer is not emplemented.n");
  1740.     return ERROR;
  1741.     }
  1742. /*******************************************************************************
  1743. *
  1744. * atapiDMATransfer - transfer a single data packet via DMA
  1745. *
  1746. * This routine transfers a single data packet via DMA.
  1747. *
  1748. * RETURN: OK, or ERROR
  1749. *
  1750. * SEE ALSO: ataPiPIOTransfer()
  1751. */
  1752. LOCAL STATUS atapiDMATransfer 
  1753.     (
  1754.     ATA_DEV *pAtapiDev
  1755.     )
  1756.     {
  1757.     pAtapiDev->errNum = 27;
  1758.     return ERROR;
  1759.     }
  1760. /*******************************************************************************
  1761. *
  1762. * ataPiOverlapTransferLoop - loop for DRQ Interrupts with Overlapping
  1763. *
  1764. * This routine loops for Data Request Interrupts until all data packets are 
  1765. * transferred.  It is invoked when ataPiPktCmd() executes an Overlapped command.  
  1766. * When Device executes an Overlapped command, it releases the ATA bus until the
  1767. * device is ready to transfer a data or to present the completion status.
  1768. *
  1769. * RETURN: OK, or ERROR
  1770. *
  1771. * SEE ALSO: ataPiNonOverTransferLoop()
  1772. */
  1773. LOCAL STATUS ataPiOverlapTransferLoop
  1774.     (
  1775.     ATA_DEV *pAtapiDev,
  1776.     FUNCPTR pTransferProc
  1777.     )
  1778.     {
  1779.     pAtapiDev->errNum = 26;
  1780.     return ERROR;
  1781.     }
  1782. /*******************************************************************************
  1783. *
  1784. * ataPiPIOTransfer - transfer a single data packet via PIO
  1785. *
  1786. * This routine transfers a single data packet via PIO.
  1787. *
  1788. * RETURN: OK, or ERROR
  1789. *
  1790. * SEE ALSO: atapiDMATransfer()
  1791. */
  1792. LOCAL STATUS ataPiPIOTransfer
  1793.     (
  1794.     ATA_DEV     *pAtapiDev
  1795.     )
  1796.     {
  1797.     ATA_CTRL    *pCtrl = &ataCtrl[pAtapiDev->ctrl];
  1798.     uint32_t desiredSize;
  1799.     uint32_t remainderSize;
  1800.     short bucket;
  1801.     /* Read Byte Count */
  1802.     pAtapiDev->transSize = ((uint16_t)ATA_IO_BYTE_READ (ATAPI_BCOUNT_HI)) << 8;
  1803.     pAtapiDev->transSize += ATA_IO_BYTE_READ (ATAPI_BCOUNT_LO);
  1804.     /*
  1805.      * From ATA Packet Interface for CD-ROMs SFF-8020i:
  1806.      * If the Device requests more data be transfered than required by the 
  1807.      * command protocol, the Host shall pad when sending data to the Device, 
  1808.      * and dump extra data into a bit bucket when reading data from the Device.
  1809.      *
  1810.      * Why device will request more data than required? It is not clear.
  1811.      * (May be some devices can't transfer part of the internal buffer?) !!!
  1812.      */
  1813.     if ( (pAtapiDev->pBufEnd == NULL) && (pAtapiDev->transSize != 0) )
  1814.         {
  1815.         pAtapiDev->errNum = 8;
  1816.         return ERROR;
  1817.         }
  1818.     desiredSize = pAtapiDev->pBufEnd - pAtapiDev->pBuf;
  1819.     if (desiredSize <= pAtapiDev->transSize)
  1820.         {
  1821.         remainderSize = pAtapiDev->transSize - desiredSize;
  1822.         pAtapiDev->pBufEnd = NULL;
  1823.         }
  1824.     else
  1825.         {
  1826.         desiredSize = pAtapiDev->transSize;
  1827.         remainderSize = 0;
  1828.         }
  1829.     /* Transfer Data Bytes */
  1830.     switch (pAtapiDev->direction)
  1831.         {
  1832.         case OUT_DATA:
  1833.             if((pAtapiDev->intReason & INTR_IO) != 0) /* IO cleared */
  1834.                     goto errorPIOTransfer;
  1835.             ATA_IO_NWORD_WRITE (ATAPI_DATA, (short *)pAtapiDev->pBuf, 
  1836.                                 desiredSize / 2);
  1837.             while (remainderSize)
  1838.                 {
  1839.                 bucket = 0;
  1840.                 ATA_IO_NWORD_WRITE (ATAPI_DATA, &bucket, 1);
  1841.                 remainderSize -= 2;
  1842.                 }
  1843.             break;
  1844.         case IN_DATA:
  1845.             if((pAtapiDev->intReason & INTR_IO) == 0) /* IO set */
  1846.                     goto errorPIOTransfer;
  1847.             ATA_IO_NWORD_READ (ATAPI_DATA, (short *)pAtapiDev->pBuf, 
  1848.                                desiredSize / 2);
  1849.             while (remainderSize)
  1850.                 {
  1851.                 ATA_IO_NWORD_READ (ATAPI_DATA, &bucket, 1);
  1852.                 remainderSize -= 2;
  1853.                 }
  1854.             break;
  1855.         default:
  1856.             goto errorPIOTransfer;
  1857.         }
  1858.     pAtapiDev->pBuf += pAtapiDev->transSize;
  1859.     return OK;
  1860. errorPIOTransfer:
  1861.     pAtapiDev->errNum = 10;
  1862.     return ERROR;
  1863.     }
  1864. /*******************************************************************************
  1865. *
  1866. * ataPiNonOverTransferLoop - loop for DRQ Interrupts without Overlapping
  1867. *
  1868. * This routine loops for Data Request Interrupts until all data packets are 
  1869. * transferred.  It is invoked when ataPiPktCmd() executes a NON Overlapped command.
  1870. *
  1871. * RETURN: OK, or ERROR 
  1872. *
  1873. * SEE ALSO: ataPiOverlapTransferLoop()
  1874. */
  1875. LOCAL STATUS ataPiNonOverTransferLoop
  1876.     (
  1877.     ATA_DEV  *pAtapiDev,
  1878.     FUNCPTR  pTransferProc
  1879.     )
  1880.     {
  1881.     ATA_CTRL *pCtrl = &ataCtrl[pAtapiDev->ctrl];
  1882.     int      semStatus;
  1883.     while ( TRUE )
  1884.         {
  1885.         /* Wait for INTRQ */
  1886.         semStatus = semTake (&pCtrl->syncSem, sysClkRateGet() * 
  1887.                                               pCtrl->semTimeout);
  1888.         if ((semStatus == ERROR))
  1889.             {
  1890.             pAtapiDev->errNum = 4;
  1891.             return ERROR;
  1892.             }
  1893.         /* Note: ideIntr() reads Status to negate INTRQ */
  1894.         pAtapiDev->status = pCtrl->intStatus;
  1895.         pAtapiDev->intReason = ATA_IO_BYTE_READ (ATAPI_INTREASON);
  1896.         if ( (pAtapiDev->status & ATA_STAT_DRQ) == 0)
  1897.             break; /* Command terminated */
  1898.         if (pAtapiDev->direction == NON_DATA)     /* non data command */
  1899.             {
  1900.             pAtapiDev->errNum = 5;
  1901.             return ERROR;
  1902.             }
  1903.         if ( ((pAtapiDev->intReason & INTR_COD) != 0) ||/* CoD cleared */
  1904.              ((pAtapiDev->status & ATA_STAT_BUSY) != 0) /* BUSY cleared */
  1905.            )
  1906.             {
  1907.             pAtapiDev->errNum = 6;
  1908.             return ERROR;
  1909.             }
  1910.         /* Transfer single data packet */
  1911.         if (pTransferProc(pAtapiDev) != OK)
  1912.             return ERROR;
  1913.         pAtapiDev->transCount++;
  1914.         } /* while ( TRUE ) */
  1915.     if ( ((pAtapiDev->intReason & INTR_COD) == 0)    || /* CoD set */
  1916.          ((pAtapiDev->intReason & INTR_IO) == 0)     || /* IO set */
  1917.          ((pAtapiDev->status & ATA_STAT_READY) == 0) || /* DRDY set */
  1918.          ((pAtapiDev->status & ATA_STAT_BUSY) != 0) /* BUSY cleared */
  1919.        )
  1920.         {
  1921.         pAtapiDev->errNum = 7;
  1922.         return ERROR;
  1923.         }
  1924.     return OK;
  1925.     }
  1926. /*******************************************************************************
  1927. *
  1928. * ataPiPktCmdExec - execute an ATAPI command without error processing
  1929. *
  1930. * This routine executes a single ATAPI command without checking of completion
  1931. * status, and attempts to recover.
  1932. * An invoking routine is responsible for error processing.
  1933. *
  1934. * RETURN: OK, or ERROR if an error is encountered during data transfer.
  1935. *
  1936. * ERRNO:
  1937. *  S_ioLib_DEVICE_ERROR
  1938. */
  1939. LOCAL STATUS ataPiPktCmdExec
  1940.     (
  1941.     ATA_DEV   *pAtapiDev,
  1942.     ATAPI_CMD *pComPack
  1943.     )
  1944.     {
  1945.     int       device = pAtapiDev->drive;
  1946.     ATA_CTRL  *pCtrl = &ataCtrl[pAtapiDev->ctrl];
  1947.     ATA_DRIVE *pDrive = &pCtrl->drive[device];
  1948.     ATA_PARAM *pParam = &pDrive->param;
  1949.     int       semStatus;
  1950.     FUNCPTR   pTransferProc = (FUNCPTR)ataPiPIOTransfer;
  1951.     FUNCPTR   pTransferLoopProc = (FUNCPTR)ataPiNonOverTransferLoop;
  1952.     UCHAR     featers = 0; /* Features Register */
  1953.     uint32_t  desiredTransferSize = pComPack->desiredTransferSize;
  1954.     ATA_DEBUG_MSG (2, "ataPiPktCmdExec%d/%d: com=0x%xn", pAtapiDev->ctrl, 
  1955.                    device, pComPack->cmdPkt[0], 0, 0, 0);
  1956.     /* Initialize transfer control structure */
  1957.     if (NULL != pComPack->ppBuf)
  1958.          {
  1959.          pAtapiDev->pBuf   = *(pComPack->ppBuf);
  1960.  pAtapiDev->pBufEnd   = *(pComPack->ppBuf) + pComPack->bufLength;
  1961.          }
  1962.     else
  1963.          {
  1964.          pAtapiDev->pBuf   = NULL;
  1965.          pAtapiDev->pBufEnd   = NULL;
  1966.          }
  1967.     pAtapiDev->direction  = pComPack->direction;
  1968.     pAtapiDev->transCount = 0;
  1969.     pAtapiDev->errNum   = 0;
  1970.     pAtapiDev->intReason  = 0;
  1971.     pAtapiDev->status   = 0;
  1972.     pAtapiDev->transSize  = 0;
  1973.     if (pComPack->dma)
  1974.         if (pParam->capabilities & CAPABIL_DMA)
  1975.             if (atapiDMAInit() == OK) /* Initialize the DMA engine */
  1976.                 {
  1977.                 featers |= FEAT_DMA;
  1978.                 pTransferProc = (FUNCPTR)atapiDMATransfer;
  1979.                 }
  1980.     if (pComPack->overlap)
  1981.         if (pParam->capabilities & CAPABIL_OVERLAP)
  1982.             {
  1983.             featers |= FEAT_OVERLAP;
  1984.             pTransferLoopProc = (FUNCPTR)ataPiOverlapTransferLoop;
  1985.             }
  1986.     ataPiWait (pAtapiDev->ctrl, ATA_STAT_ACCESS, TRUE);
  1987.     /* Select device */
  1988.     ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (device << 4));
  1989.     ATA_WAIT_STATUS;
  1990.     if (ataPiWait (pAtapiDev->ctrl, ATA_STAT_ACCESS, TRUE) != OK)
  1991.         {
  1992.         ATA_IO_BYTE_WRITE (ATAPI_D_SELECT, DSEL_FILLER | (device << 4));;
  1993.         ATA_WAIT_STATUS;
  1994.         }
  1995.     /***** Issue `ATAPI Packet Command' *****/
  1996.     /* Initialize Task File */
  1997.     ATA_IO_BYTE_WRITE (ATAPI_FEATURE, featers);
  1998.     ATA_IO_BYTE_WRITE (ATAPI_BCOUNT_LO, (uint8_t)desiredTransferSize);
  1999.     ATA_IO_BYTE_WRITE (ATAPI_BCOUNT_HI, (uint8_t)(desiredTransferSize >> 8));
  2000.     /* Wait for BSY=0 & DRQ=0 */
  2001.     while ( (ATA_IO_BYTE_READ (ATAPI_STATUS) & (ATA_STAT_BUSY | ATA_STAT_DRQ)) 
  2002.             != 0 )
  2003.         ;
  2004.     /* Issue Packet Command */
  2005.     ATA_IO_BYTE_WRITE (ATAPI_COMMAND, ATA_PI_CMD_PKTCMD);
  2006.     /***** Transfer the Command Packet In to Host *****/
  2007.     /* Wait for DRQ or INTRQ */
  2008.     switch (pParam->config & CONFIG_PKT_TYPE) /* CMD DRQ Type */
  2009.         {
  2010.         case CONFIG_PKT_TYPE_INTER: /* Interrupt DRQ */
  2011.             /* Wait for INTRQ */
  2012.             semStatus = semTake (&pCtrl->syncSem, sysClkRateGet() * 
  2013.                                                   pCtrl->semTimeout);
  2014.             if ((semStatus == ERROR))
  2015.                 {
  2016.                 pAtapiDev->errNum = 1;
  2017.                 goto errPktCmdExec;
  2018.                 }
  2019.             /* Note: ideIntr() read Status to negate INTRQ */
  2020.             pAtapiDev->status = pCtrl->intStatus;
  2021.             if ( ((pAtapiDev->status & ATA_STAT_DRQ) == 0) || /* DRQ set */
  2022.                  ((pAtapiDev->status & ATA_STAT_BUSY) != 0)   /* BUSY cleared */
  2023.                 )
  2024.                 {
  2025.                 pAtapiDev->errNum = 2;
  2026.                 goto errPktCmdExec;
  2027.                 }
  2028.             break;
  2029.         case CONFIG_PKT_TYPE_MICRO: /* Microprocessor DRQ */
  2030.         case CONFIG_PKT_TYPE_ACCEL: /* Accelerated DRQ */
  2031.             while ( ((pAtapiDev->status = ATA_IO_BYTE_READ (ATAPI_STATUS)) & 
  2032.                      (ATA_STAT_DRQ | ATA_STAT_BUSY)) != ATA_STAT_DRQ )
  2033.                 ;  /* DRQ set, BUSY cleared */
  2034.         }
  2035.  
  2036.     pAtapiDev->intReason = ATA_IO_BYTE_READ (ATAPI_INTREASON);
  2037.     if ( ((pAtapiDev->intReason & INTR_COD) == 0) || /* CoD set */
  2038.          ((pAtapiDev->intReason & INTR_IO) != 0)     /* IO cleared */
  2039.         )
  2040.         {
  2041.         pAtapiDev->errNum = 3;
  2042.         goto errPktCmdExec;
  2043.         }
  2044.     /* Write Command Packet Bytes (6 words of Command) */
  2045.     ATA_IO_NWORD_WRITE (ATAPI_DATA, (short *)pComPack->cmdPkt, 6);
  2046.     /***** Transfer the Data *****/
  2047.     if (pTransferLoopProc(pAtapiDev, pTransferProc) == OK)
  2048.         {
  2049.         ATA_DEBUG_MSG (2, "ataPiPktCmdExec%d/%d: Ok: bufStart=%p buf=%p n=%d "
  2050.                        "com=0x%xn", pAtapiDev->ctrl, device, 
  2051.                        *(pComPack->ppBuf), pAtapiDev->pBuf, 
  2052.                        pAtapiDev->transCount, pComPack->cmdPkt[0]);
  2053.         if (NULL != pComPack->ppBuf)
  2054.             {
  2055.             if (pAtapiDev->pBufEnd == NULL)
  2056.                 *(pComPack->ppBuf) += pComPack->bufLength;
  2057.             else
  2058.                 *(pComPack->ppBuf) = pAtapiDev->pBuf;
  2059.             }
  2060.         return (OK);
  2061.         }
  2062. errPktCmdExec:
  2063.     ATA_DEBUG_MSG (1, "ataPiPktCmdExec%d/%d: ERROR: %s: status=0x%x "
  2064.                    "dev=0x%x error=0x%xn", pAtapiDev->ctrl, device, 
  2065.                    ataErrStrs[pAtapiDev->errNum], pAtapiDev->status, 
  2066.                    ATA_IO_BYTE_READ(ATAPI_D_SELECT), 
  2067.                    ATA_IO_BYTE_READ(ATAPI_ERROR));
  2068.     ATA_DEBUG_MSG (1, "bufStart=%p buf=%p n=%d com=0x%x intReason=0x%x "
  2069.                    "byteCount=0x%xn", *(pComPack->ppBuf), pAtapiDev->pBuf, 
  2070.                    pAtapiDev->transCount, pComPack->cmdPkt[0], 
  2071.                    pAtapiDev->intReason, pAtapiDev->transSize);
  2072.     return (ERROR);
  2073.     } /* ataPiPktCmdExec */
  2074. /*******************************************************************************
  2075. *
  2076. * ataPiReqSense - issue a REQUEST_SENSE command to a device and read the results
  2077. *
  2078. * This routine issues a REQUEST_SENSE command to a specified ATAPI device and
  2079. * read the results.
  2080. *
  2081. * RETURNS: OK, or ERROR if the command fails.
  2082. */
  2083. LOCAL STATUS ataPiReqSense
  2084.     (
  2085.     ATA_DEV     *pAtapiDev
  2086.     )
  2087.     {
  2088. #ifdef ATA_DEBUG
  2089.     ATA_CTRL    *pCtrl    = &ataCtrl[pAtapiDev->ctrl];
  2090. #endif
  2091.     ATAPI_CMD atapiCmd;
  2092.     char reqSenseData [18];
  2093.     char        *pBuf = (char *)reqSenseData;
  2094.     int  i;
  2095.     int senseKey;
  2096.     int senseCode;
  2097.     ATA_DEBUG_MSG (2, "ataPiReqSense%d/%d: n", pAtapiDev->ctrl, 
  2098.                    pAtapiDev->drive, 0, 0, 0, 0);
  2099.     /* build a REQUEST SENSE command and execute it */
  2100.     atapiCmd.cmdPkt[0] = CDROM_CMD_REQUEST_SENSE;
  2101.     for (i = 1; i < 4; i++)
  2102.         atapiCmd.cmdPkt[i] = 0;
  2103.     atapiCmd.cmdPkt[4] = 18;
  2104.     for (i = 5; i < 12; i++)
  2105.         atapiCmd.cmdPkt[i] = 0;
  2106.     atapiCmd.ppBuf  = &pBuf;
  2107.     atapiCmd.bufLength  = 18;
  2108.     atapiCmd.direction  = IN_DATA;
  2109.     atapiCmd.desiredTransferSize = 18;
  2110.     atapiCmd.dma  = FALSE;
  2111.     atapiCmd.overlap  = FALSE;
  2112.     if (ataPiPktCmdExec (pAtapiDev, &atapiCmd) != OK)
  2113.         return (ERROR);
  2114.     /* REQUEST SENSE command status != GOOD indicates fatal error */
  2115.     if ( (pAtapiDev->status & ATA_STAT_ERR) != 0 )
  2116.         {
  2117.         ATA_DEBUG_MSG (1, "ataPiReqSense%d/%d: ERROR: status=0x%x dev=0x%x "
  2118.                        "error=0x%xn", pAtapiDev->ctrl, pAtapiDev->drive, 
  2119.                        pAtapiDev->status, ATA_IO_BYTE_READ(ATAPI_D_SELECT), 
  2120.                        ATA_IO_BYTE_READ(ATAPI_ERROR), 0);
  2121.         return (ERROR);
  2122.         }
  2123.     bzero (pBuf, 18 - (pBuf - reqSenseData));
  2124.     senseKey  = reqSenseData[2] & 0x0f;
  2125.     senseCode = reqSenseData[12];
  2126.     ATA_DEBUG_MSG (1, "ataPiReqSense%d/%d: Ok: senseKey=0x%x addSenseCode=0x%x"
  2127.                    "n", pAtapiDev->ctrl, pAtapiDev->drive, 
  2128.                    (reqSenseData[2] & 0x0f), reqSenseData[12], 0, 0);
  2129.     return (OK);
  2130.     } /* ataPiReqSense */
  2131. /*******************************************************************************
  2132. *
  2133. * ataPiPktCmd - execute an ATAPI command with error processing
  2134. *
  2135. * This routine executes a single ATAPI command, checks the command completion 
  2136. * status and tries to recover if an error encountered during command execution 
  2137. * at any stage.
  2138. *
  2139. * RETURN: OK, or ERROR if not successful for any reason.
  2140. *
  2141. * ERRNO:
  2142. *  S_ioLib_DEVICE_ERROR
  2143. */
  2144. LOCAL STATUS ataPiPktCmd
  2145.     (
  2146.     ATA_DEV     *pAtapiDev,
  2147.     ATAPI_CMD   *pComPack
  2148.     )
  2149.     {
  2150.     int device    = pAtapiDev->drive;
  2151.     ATA_CTRL    *pCtrl    = &ataCtrl[pAtapiDev->ctrl];
  2152.     ATA_DRIVE   *pDrive    = &pCtrl->drive[device];
  2153.     UCHAR error    = 0; /* Error Register */
  2154.     int retryCount = 0;
  2155.     if (pComPack->bufLength != 0)
  2156.         {
  2157.         if (pComPack->desiredTransferSize == 0)
  2158.             return (ERROR);
  2159.         if (pComPack->desiredTransferSize > 65534)
  2160.             pComPack->desiredTransferSize = 0xfffe;
  2161. /* ATA-4 Rev.18: 0xffff is interpreted by device
  2162.                                  * as though it where 0xfffe */
  2163.         else
  2164.             if (pComPack->desiredTransferSize < pComPack->bufLength)
  2165.                 pComPack->desiredTransferSize &= 0xfffffffe;
  2166. /* ATA-4 Rev.18: shall be even */
  2167.         }
  2168.     else
  2169.         {
  2170.         pComPack->dma = FALSE;
  2171.         pComPack->desiredTransferSize = 0;
  2172.         }
  2173.     semTake (&pCtrl->muteSem, WAIT_FOREVER);
  2174. retryPktCmd:
  2175.     error = 0;
  2176.     if (ataPiPktCmdExec (pAtapiDev, pComPack) == OK)
  2177.         {
  2178.         /* Check the Completion Status */
  2179.         if ( (pAtapiDev->status & ATA_STAT_ERR) == 0 )
  2180.             goto okPktCmd;
  2181.         /* If Error, Read Error Register */
  2182.         error = ATA_IO_BYTE_READ (ATAPI_ERROR);
  2183.         switch (error & ERR_SENSE_KEY)
  2184.             {
  2185.             case SENSE_NO_SENSE:
  2186.                 pAtapiDev->errNum = 11;
  2187.                 break;
  2188.             case SENSE_RECOVERED_ERROR:
  2189.                 if (pAtapiDev->pBuf < pAtapiDev->pBufEnd)
  2190.                     { /* not medium access commands */
  2191.                     pAtapiDev->errNum = 12;
  2192.                     break;
  2193.                     }
  2194.                 else
  2195.     /*
  2196.                      * Mode parameters can specify transfer disabling on 
  2197.                      * recovered error !!!) 
  2198.                      */
  2199.                     goto okPktCmd;
  2200.             case SENSE_NOT_READY:
  2201.                 pAtapiDev->errNum = 13;
  2202.                 break;
  2203.             case SENSE_MEDIUM_ERROR:
  2204.                 pAtapiDev->errNum = 14;
  2205.                 break;
  2206.             case SENSE_HARDWARE_ERROR:
  2207.                 pAtapiDev->errNum = 15;
  2208.                 break;
  2209.             case SENSE_ILLEGAL_REQUEST:
  2210.                 pAtapiDev->errNum = 16;
  2211.                 break;
  2212.             case SENSE_UNIT_ATTENTION:
  2213.                 /*
  2214.                  * Medium may have changed, or Power on or Reset occured, or
  2215.                  * Mode parameter changed
  2216.                  */
  2217.                 pAtapiDev->errNum = 17;
  2218.                 break;
  2219.             case SENSE_DATA_PROTECT:
  2220.                 pAtapiDev->errNum = 18;
  2221.                 break;
  2222.             case SENSE_ABBORTED_COMMAND:
  2223.                 pAtapiDev->errNum = 19;
  2224.                 break;
  2225.             case SENSE_MISCOMPARE:
  2226.                 pAtapiDev->errNum = 20;
  2227.                 break;
  2228.             default:
  2229.                 pAtapiDev->errNum = 0;
  2230.                 break;
  2231.             }
  2232.         ATA_DEBUG_MSG (1, "ataPiPktCmd%d/%d: ERROR: %s: status=0x%x dev=0x%x "
  2233.                        "error=0x%xn", pAtapiDev->ctrl, device, 
  2234.                        ataErrStrs[pAtapiDev->errNum], pAtapiDev->status, 
  2235.                        ATA_IO_BYTE_READ(ATAPI_D_SELECT), error);
  2236.         }
  2237.     /*
  2238.      * Execute a request sense command to try to find out more about what 
  2239.      * went wrong (and clear a unit attention)? 
  2240.      */
  2241.     if (error != 0)
  2242.         {
  2243.         /* Test for transition from NOT READY to READY */
  2244.         if ((error & ERR_SENSE_KEY) == SENSE_UNIT_ATTENTION)
  2245.             {
  2246.             pDrive->state = ATA_DEV_MED_CH;
  2247.             pAtapiDev->blkDev.bd_readyChanged = TRUE;
  2248.             }
  2249.         else if ( ataPiReqSense(pAtapiDev) == OK )
  2250.     {
  2251.     if (++retryCount < ataRetry)
  2252. {
  2253.                 pDrive->state = ATA_DEV_OK;
  2254.                 pAtapiDev->blkDev.bd_readyChanged = FALSE;
  2255.                 pAtapiDev->errNum = 0;
  2256. error = 0;
  2257. goto retryPktCmd;
  2258. }
  2259.             }
  2260.         }
  2261.     else
  2262.         error = -1;
  2263.     if ( (error & ERR_SENSE_KEY) != SENSE_UNIT_ATTENTION )
  2264.         {
  2265.         ataPiInit (pAtapiDev->ctrl, device);
  2266.         if (++retryCount < ataRetry)
  2267.             goto retryPktCmd;
  2268.         }
  2269.     semGive (&pCtrl->muteSem);
  2270.     (void)errnoSet (S_ioLib_DEVICE_ERROR);
  2271.     return error;
  2272. okPktCmd:
  2273.     semGive (&pCtrl->muteSem);
  2274.     return (SENSE_NO_SENSE); 
  2275.     } /* ataPiPktCmd */
  2276. /*******************************************************************************
  2277. *
  2278. * ataPiTestUnitRdy - issue a TEST UNIT READY command to a ATAPI device
  2279. *
  2280. * This routine issues a TEST UNIT READY command to a specified ATAPI device.
  2281. *
  2282. * RETURNS: OK, or ERROR if the command fails.
  2283. */
  2284.  
  2285. LOCAL STATUS ataPiTestUnitRdy
  2286.     (
  2287.     ATA_DEV     *pAtapiDev
  2288.     )
  2289.     {
  2290.     ATAPI_CMD atapiCmd;
  2291.     int  i;
  2292.     int error;
  2293.     ATA_DEBUG_MSG (2, "ataPiTestUnitRdy%d/%d: n", pAtapiDev->ctrl, 
  2294.                    pAtapiDev->drive, 0, 0, 0, 0);
  2295.     /* build a TEST UNIT READY command and execute it */
  2296.     atapiCmd.cmdPkt[0] = CDROM_CMD_TEST_UNIT_READY;
  2297.     for (i = 1; i < 12; i++)
  2298.         atapiCmd.cmdPkt[i] = 0;
  2299.     atapiCmd.ppBuf  = NULL;
  2300.     atapiCmd.bufLength  = 0;
  2301.     atapiCmd.direction  = NON_DATA;
  2302.     atapiCmd.desiredTransferSize = 0;
  2303.     atapiCmd.dma  = FALSE;
  2304.     atapiCmd.overlap  = FALSE;
  2305.     i = 0;
  2306.     do  {
  2307.         error = ataPiPktCmd (pAtapiDev, &atapiCmd) & ERR_SENSE_KEY;
  2308.         if ( ((error != SENSE_NO_SENSE) && (error != SENSE_UNIT_ATTENTION)) ||
  2309.              (++i > 5) ) /* drive may queue unit attention conditions */
  2310.             {
  2311.             return (ERROR); /* problem with the device is detected */
  2312.             }
  2313.         } while (error != SENSE_NO_SENSE);
  2314.     ATA_DEBUG_MSG (2, "ataPiTestUnitRdy%d/%d: Okn", pAtapiDev->ctrl, 
  2315.                    pAtapiDev->drive, 0, 0, 0, 0);
  2316.     return (OK);
  2317.     } /* ataPiTestUnitRdy */
  2318. /*******************************************************************************
  2319. *
  2320. * ataPiReadCapacity - issue a READ_CAPACITY command to a ATAPI device
  2321. *
  2322. * This routine issues a READ_CAPACITY command to a specified ATAPI device.
  2323. *
  2324. * RETURN: OK, or ERROR if the command fails.
  2325. */
  2326. LOCAL STATUS ataPiReadCapacity
  2327.     (
  2328.     ATA_DEV     *pAtapiDev
  2329.     )
  2330.     {
  2331.     BLK_DEV     *pBlkDev = &pAtapiDev->blkDev;
  2332.     ATAPI_CMD atapiCmd;
  2333.     UINT8 resultBuf[8];
  2334.     char        *pBuf = (char *)resultBuf;
  2335.     int i;
  2336.     ATA_DEBUG_MSG (2, "ataPiReadCapacity%d/%d: n", pAtapiDev->ctrl, 
  2337.                    pAtapiDev->drive, 0, 0, 0, 0);
  2338.     /* build a READ CD-ROM CAPACITY command and execute it */
  2339.     atapiCmd.cmdPkt[0] = CDROM_CMD_READ_CDROM_CAP;
  2340.     for (i = 1; i < 12; i++)
  2341.         atapiCmd.cmdPkt[i] = 0;
  2342.     atapiCmd.ppBuf  = &pBuf;
  2343.     atapiCmd.bufLength  = 8;
  2344.     atapiCmd.direction  = IN_DATA;
  2345.     atapiCmd.desiredTransferSize = 8;
  2346.     atapiCmd.dma  = FALSE;
  2347.     atapiCmd.overlap  = FALSE;
  2348.     if (ataPiPktCmd (pAtapiDev, &atapiCmd) != SENSE_NO_SENSE)
  2349.         return (ERROR);
  2350.     pBlkDev->bd_nBlocks = 0;
  2351.     pBlkDev->bd_bytesPerBlk = 0;
  2352.     for (i = 0; i < 4; i++)
  2353.         pBlkDev->bd_nBlocks += ((ULONG)resultBuf[i]) << (8 * (3 - i));
  2354.     pBlkDev->bd_nBlocks++;                 /* ULONG blocks on device */
  2355.     pBlkDev->bd_blksPerTrack = pBlkDev->bd_nBlocks; 
  2356.                                            /* ULONG blocks per track */
  2357.     for (i = 4; i < 8; i++)
  2358.         pBlkDev->bd_bytesPerBlk += ((ULONG)resultBuf[i]) << (8 * (7 - i));
  2359.                                            /* ULONG bytes per block */
  2360.     ATA_DEBUG_MSG (2, "ataPiReadCapacity%d/%d: Ok: nBlocks=%d bytesPerBlk=%dn",
  2361.                    pAtapiDev->ctrl, pAtapiDev->drive, pBlkDev->bd_nBlocks, 
  2362.                    pBlkDev->bd_bytesPerBlk, 0, 0);
  2363.     return (OK);
  2364.     } /* ataPiReadCapacity */
  2365. /*******************************************************************************
  2366. *
  2367. * ataPiBlkRd - read one or more blocks from a ATAPI CD-ROM disk
  2368. *
  2369. * This routine reads one or more blocks from the specified device,
  2370. * starting with the specified block number.
  2371. *
  2372. * RETURNS: OK, ERROR if the read command didn't succeed.
  2373. */
  2374. LOCAL STATUS ataPiBlkRd
  2375.     (
  2376.     ATA_DEV     *pAtapiDev,
  2377.     int         startBlk,
  2378.     int         nBlks,
  2379.     char        *pBuf
  2380.     )
  2381.     {
  2382.     ATA_CTRL    *pCtrl = &ataCtrl[pAtapiDev->ctrl];
  2383.     ATA_DRIVE   *pDrive = &pCtrl->drive[pAtapiDev->drive];
  2384.     ATAPI_CMD atapiCmd;
  2385.     int i;
  2386.     char *pUpdatedBuf = pBuf;
  2387.     ATA_DEBUG_MSG (2, "ataPiBlkRd%d/%d: state=0x%x startBlk=%d nBlks=%d pBuf=%p"
  2388.                    "n", pAtapiDev->ctrl, pAtapiDev->drive, pDrive->state, 
  2389.                    startBlk, nBlks, pBuf);
  2390.     if (!pCtrl->installed)
  2391.         return (ERROR);
  2392.     if (pDrive->state != ATA_DEV_OK)
  2393.         return (ERROR);
  2394.     /* Sanity check */
  2395.     if ( (startBlk >= pAtapiDev->blkDev.bd_nBlocks) || 
  2396.          ((startBlk + nBlks) >= pAtapiDev->blkDev.bd_nBlocks) )
  2397.         {
  2398.         ATA_DEBUG_MSG (1, "ataPiBlkRd%d/%d ERROR: block numbers must be in "
  2399.                        "range 0 - %dn", pAtapiDev->ctrl, pAtapiDev->drive, 
  2400.                        (pAtapiDev->blkDev.bd_nBlocks - 1), 0, 0, 0);
  2401.         return ERROR;
  2402.         }
  2403.     /* Fill Command Packet */
  2404.     atapiCmd.cmdPkt[0] = CDROM_CMD_READ_12;
  2405.     atapiCmd.cmdPkt[1] = 0; /* Reserved */
  2406.     /* clear bytes 2 - 9 */
  2407.     *(u_char *)(&atapiCmd.cmdPkt[2]) = 0; 
  2408.     *(u_char *)(&atapiCmd.cmdPkt[3]) = 0;
  2409.     *(u_char *)(&atapiCmd.cmdPkt[4]) = 0;
  2410.     *(u_char *)(&atapiCmd.cmdPkt[5]) = 0;
  2411.     *(u_char *)(&atapiCmd.cmdPkt[6]) = 0; 
  2412.     *(u_char *)(&atapiCmd.cmdPkt[7]) = 0; 
  2413.     *(u_char *)(&atapiCmd.cmdPkt[8]) = 0; 
  2414.     *(u_char *)(&atapiCmd.cmdPkt[9]) = 0; 
  2415.     for (i = 2; i < 6; i++)
  2416.         atapiCmd.cmdPkt[i] += (UINT8)( startBlk >> (8 * (5 - i)) );
  2417.     for (i = 6; i < 10; i++)
  2418.         atapiCmd.cmdPkt[i] += (UINT8)( nBlks >> (8 * (9 - i)) );
  2419.     atapiCmd.cmdPkt[10] = 0; /* Reserved */
  2420.     atapiCmd.cmdPkt[11] = 0; /* Reserved */
  2421.     i = nBlks * pAtapiDev->blkDev.bd_bytesPerBlk;
  2422.     atapiCmd.ppBuf  = &pUpdatedBuf;
  2423.     atapiCmd.bufLength  = i;
  2424.     atapiCmd.direction  = IN_DATA;
  2425.     atapiCmd.desiredTransferSize = i;
  2426.     atapiCmd.dma  = FALSE;
  2427.     atapiCmd.overlap  = FALSE;
  2428.     /* Execute Packet Command */
  2429.     if (ataPiPktCmd (pAtapiDev, &atapiCmd) != SENSE_NO_SENSE)
  2430.         return (ERROR);
  2431.     ATA_DEBUG_MSG (2, "ataPiBlkRd%d/%d: Okn", pAtapiDev->ctrl, 
  2432.                    pAtapiDev->drive, 0, 0, 0, 0);
  2433.     return (OK);
  2434.     } /* ataPiBlkRd */
  2435. /*******************************************************************************
  2436. *
  2437. * ataPiReset - reset a ATAPI CD-ROM disk controller
  2438. *
  2439. * This routine resets a ATAPI CD-ROM disk controller.
  2440. *
  2441. * RETURNS: OK, or ERROR.
  2442. */
  2443. LOCAL STATUS ataPiReset
  2444.     (
  2445.     ATA_DEV   *pAtapiDev
  2446.     )
  2447.     {
  2448.     ATA_CTRL  *pCtrl = &ataCtrl[pAtapiDev->ctrl];
  2449.     ATA_DRIVE *pDrive = &pCtrl->drive[pAtapiDev->drive];
  2450.     ATA_DEBUG_MSG (2, "ataPiReset%d/%d: state=0x%xn", pAtapiDev->ctrl, 
  2451.                    pAtapiDev->drive, pDrive->state, 0, 0, 0);
  2452.     if (!pCtrl->installed)
  2453.         return (ERROR);
  2454.     if (pDrive->state != ATA_DEV_MED_CH)
  2455.         { /* power on, entire drive changed, or failure recovering */
  2456.         semTake (&pCtrl->muteSem, WAIT_FOREVER);
  2457.         if (pDrive->state != ATA_DEV_INIT)
  2458.             { /* higher level tried to recover after failure */
  2459.             if (pDrive->Reset (pAtapiDev->ctrl, pAtapiDev->drive) != OK)
  2460.                 {
  2461.                 semGive (&pCtrl->muteSem);
  2462.                 return (ERROR);
  2463.                 }
  2464.            }
  2465.         if (ataDriveInit (pAtapiDev->ctrl, pAtapiDev->drive) != OK)
  2466.             {
  2467.             semGive (&pCtrl->muteSem);
  2468.             return (ERROR);
  2469.             }
  2470.         semGive (&pCtrl->muteSem);
  2471.         }
  2472.     /* Identify medium */
  2473.     if (ataPiTestUnitRdy (pAtapiDev) != OK)
  2474.         return (ERROR);
  2475.     if (ataPiReadCapacity (pAtapiDev) != OK)
  2476.         {
  2477.         pAtapiDev->blkDev.bd_readyChanged = TRUE;
  2478.         return (ERROR);
  2479.         }
  2480.     else
  2481.         pDrive->state = ATA_DEV_OK;
  2482.     ATA_DEBUG_MSG (2, "ataPiReset%d/%d: Okn", pAtapiDev->ctrl, 
  2483.                    pAtapiDev->drive, 0, 0, 0, 0);
  2484.     return (OK);
  2485.     } /* ataPiReset */
  2486. /*******************************************************************************
  2487. *
  2488. * ataPiIoctl - do device specific control function
  2489. *
  2490. * This routine is called when the file system cannot handle an ioctl()
  2491. * function.
  2492. *
  2493. * RETURNS:  OK or ERROR.
  2494. */
  2495. LOCAL STATUS ataPiIoctl
  2496.     (
  2497.     ATA_DEV     *pAtapiDev,
  2498.     int         function,
  2499.     int         arg
  2500.     )
  2501.     {
  2502.     ATA_CTRL    *pCtrl = &ataCtrl[pAtapiDev->ctrl];
  2503.     ATA_DRIVE   *pDrive = &pCtrl->drive[pAtapiDev->drive];
  2504.     int status = ERROR;
  2505.     ATA_DEBUG_MSG (2, "ataPiIoctl%d/%d: state=0x%x func=%d arg=%dn", 
  2506.                    pAtapiDev->ctrl, pAtapiDev->drive, pDrive->state, function, 
  2507.                    arg, 0);
  2508.     if (!pCtrl->installed)
  2509.         return (ERROR);
  2510.     if (pDrive->state != ATA_DEV_OK)
  2511.         return (ERROR);
  2512.     ATA_DEBUG_MSG (2, "ataPiIoctl%d/%d: Okn", pAtapiDev->ctrl, 
  2513.                    pAtapiDev->drive, 0, 0, 0, 0);
  2514.     return status;
  2515.     } /* ataPiIoctl */
  2516. /*******************************************************************************
  2517. *
  2518. * ataPiStatusChk - check device status
  2519. *
  2520. * This routine issues a TEST UNIT READY command to a ATAPI device to detect a
  2521. * medium change.  It called by filesystems before doing open()'s or creat()'s.
  2522. *
  2523. * RETURNS: OK or ERROR.
  2524. */
  2525. LOCAL STATUS ataPiStatusChk
  2526.     (
  2527.     ATA_DEV   *pAtapiDev /* pointer to device descriptor */
  2528.     )
  2529.     {
  2530.     ATA_CTRL  *pCtrl = &ataCtrl[pAtapiDev->ctrl];
  2531.     ATA_DRIVE *pDrive = &pCtrl->drive[pAtapiDev->drive];
  2532.     ATA_DEBUG_MSG (2, "ataPiStatusChk%d/%d: state=%d readyChanged=%dn", 
  2533.                    pAtapiDev->ctrl, pAtapiDev->drive, pDrive->state, 
  2534.                    pAtapiDev->blkDev.bd_readyChanged, 0, 0);
  2535.     if (!pCtrl->installed)
  2536.         return (ERROR);
  2537.     if ( (pDrive->state != ATA_DEV_MED_CH) && (pDrive->state != ATA_DEV_OK)  )
  2538.         return (ERROR);
  2539.     if (ataPiTestUnitRdy (pAtapiDev) != OK)
  2540.         return (ERROR);
  2541.     /* Device OK, medium may be changed, check Medium Change */
  2542.     if (pDrive->state == ATA_DEV_MED_CH || pAtapiDev->blkDev.bd_readyChanged )
  2543.         {
  2544.         if (ataPiReadCapacity (pAtapiDev) != OK)
  2545.             {
  2546.             pAtapiDev->blkDev.bd_readyChanged = TRUE;
  2547.             return (ERROR);
  2548.             }
  2549.         else
  2550.             pDrive->state = ATA_DEV_OK;
  2551.         }
  2552.     ATA_DEBUG_MSG (2, "ataPiStatusChk%d/%d: Ok: state=%d readyChanged=%dn", 
  2553.                    pAtapiDev->ctrl, pAtapiDev->drive, pDrive->state, 
  2554.                    pAtapiDev->blkDev.bd_readyChanged, 0, 0);
  2555.     return (OK); /* open or create operations can continue */
  2556.     } /* ataPiStatusChk */
  2557. #ifdef ATA_DEBUG
  2558. /* DEBUG functions */
  2559. STATUS ataIntCheck (ATA_DEV * pAtapiDev)
  2560. {
  2561. ATA_CTRL *  pCtrl   = &ataCtrl[pAtapiDev->ctrl];
  2562. int         semStatus;
  2563. semStatus = semTake (&pCtrl->syncSem, 1);
  2564. if (semStatus == ERROR)
  2565.     return ERROR;
  2566. return OK;
  2567. }
  2568. void ataSemGive (ATA_DEV * pAtapiDev)
  2569. {
  2570. ATA_CTRL *  pCtrl   = &ataCtrl[pAtapiDev->ctrl];
  2571. semGive (&pCtrl->syncSem);
  2572. }
  2573. void ataTimeoutSet (int ctrl, int val)
  2574. {
  2575. ATA_CTRL *pCtrl = &ataCtrl[ctrl];
  2576. pCtrl->semTimeout = val;
  2577. pCtrl->wdgTimeout = val;
  2578. }
  2579. #endif