File nut/arch/avr/dev/ide.c

* This file is part of the AVRIDE device driver.
* Copyright (c) 2002-2003 by Michael Fischer. All rights reserved.
* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met:
* 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE.
**************************************************************************** * History:
* 14.12.02 mifi First Version * 29.12.02 mifi Support CF-Card too . * 01.01.03 mifi Add support for IDELock, IDEFree. * 08.01.03 mifi Now support several modes, like: * IDE_HARDDISK 16bit 14.7456Mhz / 2 wait states * IDE_HARDDISK_7MHZ 16bit 7.3728Mhz / 2 wait states * IDE_COMPACT_FLASH 16bit 14.7456Mhz / 2 wait states * MEM_8BIT_COMPACT_FLASH 8bit 14.7456Mhz / 2 wait states * 18.01.03 mifi Change Licence from GPL to BSD. * 25.01.03 mifi Fix the bug in ClearEvent. * Change IDEInit and add "AutoMount", "AutoUnMount" * callback function. With these functions we are * independent from the FileSystem. * Now support changing of the CF-Card in a running system. * 19.06.03 mifi Change IDEInit, if the BaseAddress is 0, we use the * default address IDE_BASE_ADDRESS. Now we can use the * address 0 in FAT.C and hide the ide stuff. * 24.06.03 mifi Enable the IDE Reset pin with DDRD = 0x20, * add some stuff to detect PACKET device. * 25.06.03 mifi Fix overflow with IDE_MAX_SUPPORTED_DEVICE * 29.06.03 mifi First ATAPI-Version


Included Files


Preprocessor definitions

#define __IDE_C__

#define HIBYTE( _x )

#define LOBYTE( _x )

#define IDE_IRQ INT7

#define IDE_INT_RISING_EDGE 0xC0

#define CF_IRQ INT6

#define CF_INT_SENS_MASK 0x30

#define CF_INT_FALLING_EDGE 0x20

#define CF_INT_RISING_EDGE 0x30

#define IDE_MAX_SUPPORTED_DEVICE 1

#define CF_AVAILABLE 0

#define CF_NOT_AVAILABLE 1

#define INITTIMEOUT 10000

#define DISKTIMEOUT 10000

#define CONTROLLERTIMEOUT 200

#define ATAPITIMEOUT 5000

#define IDEIn( x )

#define IDEOut( x, y )

#define IDE_SUPPORT_LBA 0x0001

#define IDE_SUPPORT_LBA48 0x0002

#define IDE_SUPPORT_PACKET 0x0004

#define IDE_SUPPORT_INTRQ_PACKET 0x0008

#define IDE_CDROM_DEVICE 0x1000

#define IDE_ZIP_DEVICE 0x2000

#define IDE_READ_ONLY 0x4000

#define IDE_READY 0x8000

#define ATAPI_CFG_12_BYTE_MSK 0x0003

#define ATAPI_CFG_INTRQ 0x0060

#define ATAPI_CFG_REM_MEDIUM 0x0080

#define ATAPI_CFG_DEVICE 0x1F00

#define ATAPI_CFG_ATAPI 0xC000

#define ATAPI_IS_12_BYTE 0x0000

#define ATAPI_USE_INTRQ 0x0020

#define ATAPI_IS_DIRECT_ACCESS 0x0000

#define ATAPI_IS_CDROM 0x0500

#define ATAPI_IS_PACKET 0x8000

#define ATAPI_CMD( _x )

#define CLEAR_ATAPI_CMD


Typedef DRIVE

typedef struct _drive DRIVE
struct _drive  
   {  
      WORD wFlags;  
      BYTE bIDEMode;  
      BYTE bDevice;  
      DWORD dwTotalSectors;  
      WORD wSectorSize;  
   }  

Typedef LPDRIVE

typedef struct _drive* LPDRIVE
See: Typedef DRIVE

Local Variables

hIDEEvent
static HANDLE hIDEEvent
Used in: ATAPISendCommand()  
  DeviceDiag()  
  GetDeviceInfo()  
  GetDeviceInfoPacket()  
  IDEInit()  
  IDEInterrupt()  
  ReadSectors()  
  WaitForInterrupt()  

pIDE
static volatile BYTE* pIDE

Used in: ATAPISendCommand()  
  DeviceDiag()  
  GetDeviceInfo()  
  GetDeviceInfoPacket()  
  IDEInit()  
  IDEInterrupt()  
  IsPacketDevice()  
  ReadSectors()  
  SelectDevice()  
  WaitDRQ()  
  WaitNotBusy()  

gbIntStatus
static volatile BYTE gbIntStatus

Used in: ATAPISendCommand()  
  GetDeviceInfo()  
  GetDeviceInfoPacket()  
  IDEInit()  
  IDEInterrupt()  
  ReadSectors()  

sDrive
static DRIVE sDrive[1]

Used in: CFChange()  
  IDEATAPISetCDSpeed()  
  IDEGetSectorSize()  
  IDEGetTotalSectors()  
  IDEInit()  
  IDEIsCDROMDevice()  
  IDEIsZIPDevice()  
  IDEMountDevice()  
  IDEReadSectors()  
  IDEUnMountDevice()  
  ReadSectors()  

hIDESemaphore
static HANDLE hIDESemaphore

Used in: IDEFree()  
  IDELock()  
  IDESemaInit()  

hCFChangeInt
static HANDLE hCFChangeInt

Used in: CFChange()  
  CFInterrupt()  

gbCFMountStatus
static BYTE gbCFMountStatus

Used in: CFChange()  
  IDEInit()  

aATAPICmd
static BYTE aATAPICmd[12]

Used in: ATAPIGetTotalSectors()  
  ATAPISendCommand()  
  GetDeviceInfoPacket()  
  IDEATAPISetCDSpeed()  
  IDEReadSectors()  

Global Function CFChange()

void CFChange ( void* arg )
Prototyped in: nut/arch/avr/dev/ide.c
Calls: HardwareReset() nut/arch/avr/dev/ide.c
  IDEMountDevice() nut/arch/avr/dev/ide.c
  IDEUnMountDevice() nut/arch/avr/dev/ide.c
  NutEventWaitNext(), NutHeapRootAlloc(), NutHeapRootFree(), NutSleep(), pUserMountFunc(), pUserUnMountFunc()
Used in: IDEInit() nut/arch/avr/dev/ide.c
References Functions: pUserMountFunc(), pUserUnMountFunc()
References Variables: gbCFMountStatus nut/arch/avr/dev/ide.c
  hCFChangeInt nut/arch/avr/dev/ide.c
  sDrive nut/arch/avr/dev/ide.c

Global Function IDEATAPISetCDSpeed()

int IDEATAPISetCDSpeed ( BYTE bDevice, WORD wSpeed )
Prototyped in: nut/include/dev/ide.h
Calls: ATAPISendCommand() nut/arch/avr/dev/ide.c
  memset()
Called by: GetDeviceInfoPacket() nut/arch/avr/dev/ide.c
References Variables: aATAPICmd nut/arch/avr/dev/ide.c
  sDrive nut/arch/avr/dev/ide.c

Global Function IDEFree()

void IDEFree ( void )
Calls: NutEventPost()
Called by: IDEGetSectorSize() nut/arch/avr/dev/ide.c
  IDEGetTotalSectors() nut/arch/avr/dev/ide.c
  IDEIsCDROMDevice() nut/arch/avr/dev/ide.c
  IDEIsZIPDevice() nut/arch/avr/dev/ide.c
  IDEMountDevice() nut/arch/avr/dev/ide.c
  IDEReadSectors() nut/arch/avr/dev/ide.c
  IDEUnMountDevice() nut/arch/avr/dev/ide.c
References Variables: hIDESemaphore nut/arch/avr/dev/ide.c

Global Function IDEGetSectorSize()

int IDEGetSectorSize ( BYTE bDevice )
Prototyped in: nut/include/dev/ide.h
Calls: IDEFree() nut/arch/avr/dev/ide.c
  IDELock() nut/arch/avr/dev/ide.c
References Variables: sDrive nut/arch/avr/dev/ide.c

Global Function IDEGetTotalSectors()

DWORD IDEGetTotalSectors ( BYTE bDevice )
Prototyped in: nut/include/dev/ide.h
Calls: IDEFree() nut/arch/avr/dev/ide.c
  IDELock() nut/arch/avr/dev/ide.c
References Variables: sDrive nut/arch/avr/dev/ide.c

Global Function IDEInit()

int IDEInit ( int nBaseAddress, int nIDEMode, IDE_MOUNT_FUNC* pMountFunc, IDE_MOUNT_FUNC* pUnMountFunc )
Prototyped in: nut/include/dev/ide.h
Calls: ClearEvent() nut/arch/avr/dev/ide.c
  HardwareReset() nut/arch/avr/dev/ide.c
  IDESemaInit() nut/arch/avr/dev/ide.c
  NutRegisterIrqHandler(), NutThreadCreate(), memset()
References Functions: CFChange() nut/arch/avr/dev/ide.c
  CFInterrupt() nut/arch/avr/dev/ide.c
  IDEInterrupt() nut/arch/avr/dev/ide.c
  pUserMountFunc(), pUserUnMountFunc()
References Variables: gbCFMountStatus nut/arch/avr/dev/ide.c
  gbIntStatus nut/arch/avr/dev/ide.c
  hIDEEvent nut/arch/avr/dev/ide.c
  pIDE nut/arch/avr/dev/ide.c
  sDrive nut/arch/avr/dev/ide.c

Global Function IDEIsCDROMDevice()

int IDEIsCDROMDevice ( BYTE bDevice )
Prototyped in: nut/include/dev/ide.h
Calls: IDEFree() nut/arch/avr/dev/ide.c
  IDELock() nut/arch/avr/dev/ide.c
References Variables: sDrive nut/arch/avr/dev/ide.c

Global Function IDEIsZIPDevice()

int IDEIsZIPDevice ( BYTE bDevice )
Prototyped in: nut/include/dev/ide.h
Calls: IDEFree() nut/arch/avr/dev/ide.c
  IDELock() nut/arch/avr/dev/ide.c
References Variables: sDrive nut/arch/avr/dev/ide.c

Global Function IDELock()

void IDELock ( void )
Calls: NutEventWait()
Called by: IDEGetSectorSize() nut/arch/avr/dev/ide.c
  IDEGetTotalSectors() nut/arch/avr/dev/ide.c
  IDEIsCDROMDevice() nut/arch/avr/dev/ide.c
  IDEIsZIPDevice() nut/arch/avr/dev/ide.c
  IDEMountDevice() nut/arch/avr/dev/ide.c
  IDEReadSectors() nut/arch/avr/dev/ide.c
  IDEUnMountDevice() nut/arch/avr/dev/ide.c
References Variables: hIDESemaphore nut/arch/avr/dev/ide.c

Global Function IDEMountDevice()

int IDEMountDevice ( BYTE bDevice, BYTE* pSectorBuffer )
Prototyped in: nut/include/dev/ide.h
Calls: DeviceDiag() nut/arch/avr/dev/ide.c
  GetDeviceInfo() nut/arch/avr/dev/ide.c
  GetDeviceInfoPacket() nut/arch/avr/dev/ide.c
  IDEFree() nut/arch/avr/dev/ide.c
  IDELock() nut/arch/avr/dev/ide.c
Called by: CFChange() nut/arch/avr/dev/ide.c
References Variables: sDrive nut/arch/avr/dev/ide.c

Global Function IDEReadSectors()

int IDEReadSectors ( BYTE bDevice, void* pData, DWORD dwStartSector, WORD wSectorCount )
Prototyped in: nut/include/dev/ide.h
Calls: ATAPISendCommand() nut/arch/avr/dev/ide.c
  IDEFree() nut/arch/avr/dev/ide.c
  IDELock() nut/arch/avr/dev/ide.c
  ReadSectors() nut/arch/avr/dev/ide.c
  memset()
References Variables: aATAPICmd nut/arch/avr/dev/ide.c
  sDrive nut/arch/avr/dev/ide.c

Global Function IDESemaInit()

void IDESemaInit ( void )
Calls: NutEventPost()
Called by: IDEInit() nut/arch/avr/dev/ide.c
References Variables: hIDESemaphore nut/arch/avr/dev/ide.c

Global Function IDEUnMountDevice()

int IDEUnMountDevice ( BYTE bDevice )
Prototyped in: nut/include/dev/ide.h
Calls: IDEFree() nut/arch/avr/dev/ide.c
  IDELock() nut/arch/avr/dev/ide.c
Called by: CFChange() nut/arch/avr/dev/ide.c
References Variables: sDrive nut/arch/avr/dev/ide.c

Local Function ATAPIGetTotalSectors()

static int ATAPIGetTotalSectors ( LPDRIVE pDrive, BYTE* pSectorBuffer, DWORD* pMaxSectors )
Calls: ATAPISendCommand() nut/arch/avr/dev/ide.c
  NutSleep(), memset()
Called by: GetDeviceInfoPacket() nut/arch/avr/dev/ide.c
References Variables: aATAPICmd nut/arch/avr/dev/ide.c

Local Function ATAPISendCommand()

static int ATAPISendCommand ( LPDRIVE pDrive, BYTE* pSectorBuffer, WORD* pReadCount )
Calls: ClearEvent() nut/arch/avr/dev/ide.c
  SelectDevice() nut/arch/avr/dev/ide.c
  Wait400ns() nut/arch/avr/dev/ide.c
  WaitDRQ() nut/arch/avr/dev/ide.c
  WaitForInterrupt() nut/arch/avr/dev/ide.c
  WaitNotBusy() nut/arch/avr/dev/ide.c
Called by: ATAPIGetTotalSectors() nut/arch/avr/dev/ide.c
  GetDeviceInfoPacket() nut/arch/avr/dev/ide.c
  IDEATAPISetCDSpeed() nut/arch/avr/dev/ide.c
  IDEReadSectors() nut/arch/avr/dev/ide.c
References Variables: aATAPICmd nut/arch/avr/dev/ide.c
  gbIntStatus nut/arch/avr/dev/ide.c
  hIDEEvent nut/arch/avr/dev/ide.c
  pIDE nut/arch/avr/dev/ide.c

Local Function CFInterrupt()

static void CFInterrupt ( void* p )
Used in: IDEInit() nut/arch/avr/dev/ide.c
References Variables: hCFChangeInt nut/arch/avr/dev/ide.c

Local Function ClearEvent()

static void ClearEvent ( HANDLE* pEvent )
Called by: ATAPISendCommand() nut/arch/avr/dev/ide.c
  DeviceDiag() nut/arch/avr/dev/ide.c
  GetDeviceInfo() nut/arch/avr/dev/ide.c
  GetDeviceInfoPacket() nut/arch/avr/dev/ide.c
  IDEInit() nut/arch/avr/dev/ide.c
  ReadSectors() nut/arch/avr/dev/ide.c

Local Function DeviceDiag()

static int DeviceDiag ( LPDRIVE pDrive )
Calls: ClearEvent() nut/arch/avr/dev/ide.c
  IsPacketDevice() nut/arch/avr/dev/ide.c
  SelectDevice() nut/arch/avr/dev/ide.c
  WaitForInterrupt() nut/arch/avr/dev/ide.c
Called by: IDEMountDevice() nut/arch/avr/dev/ide.c
References Variables: hIDEEvent nut/arch/avr/dev/ide.c
  pIDE nut/arch/avr/dev/ide.c

Local Function GetDeviceInfo()

static int GetDeviceInfo ( LPDRIVE pDrive, BYTE* pSectorBuffer )
Calls: ClearEvent() nut/arch/avr/dev/ide.c
  SelectDevice() nut/arch/avr/dev/ide.c
  WaitForInterrupt() nut/arch/avr/dev/ide.c
Called by: IDEMountDevice() nut/arch/avr/dev/ide.c
References Variables: gbIntStatus nut/arch/avr/dev/ide.c
  hIDEEvent nut/arch/avr/dev/ide.c
  pIDE nut/arch/avr/dev/ide.c

Local Function GetDeviceInfoPacket()

static int GetDeviceInfoPacket ( LPDRIVE pDrive, BYTE* pSectorBuffer )
Calls: ATAPIGetTotalSectors() nut/arch/avr/dev/ide.c
  ATAPISendCommand() nut/arch/avr/dev/ide.c
  ClearEvent() nut/arch/avr/dev/ide.c
  IDEATAPISetCDSpeed() nut/arch/avr/dev/ide.c
  SelectDevice() nut/arch/avr/dev/ide.c
  WaitForInterrupt() nut/arch/avr/dev/ide.c
  memset()
Called by: IDEMountDevice() nut/arch/avr/dev/ide.c
References Variables: aATAPICmd nut/arch/avr/dev/ide.c
  gbIntStatus nut/arch/avr/dev/ide.c
  hIDEEvent nut/arch/avr/dev/ide.c
  pIDE nut/arch/avr/dev/ide.c

Local Function HardwareReset()

static void HardwareReset ( DRIVE* pDrive )
Calls: NutSleep()
Called by: CFChange() nut/arch/avr/dev/ide.c
  IDEInit() nut/arch/avr/dev/ide.c

Local Function IDEInterrupt()

static void IDEInterrupt ( void* p )
Used in: IDEInit() nut/arch/avr/dev/ide.c
References Variables: gbIntStatus nut/arch/avr/dev/ide.c
  hIDEEvent nut/arch/avr/dev/ide.c
  pIDE nut/arch/avr/dev/ide.c

Local Function IsPacketDevice()

static int IsPacketDevice ( void )
Called by: DeviceDiag() nut/arch/avr/dev/ide.c
References Variables: pIDE nut/arch/avr/dev/ide.c

Local Function ReadSectors()

static int ReadSectors ( BYTE bDevice, BYTE* pData, DWORD dwStartSector, WORD wSectorCount )
Calls: ClearEvent() nut/arch/avr/dev/ide.c
  SelectDevice() nut/arch/avr/dev/ide.c
  WaitForInterrupt() nut/arch/avr/dev/ide.c
Called by: IDEReadSectors() nut/arch/avr/dev/ide.c
References Variables: gbIntStatus nut/arch/avr/dev/ide.c
  hIDEEvent nut/arch/avr/dev/ide.c
  pIDE nut/arch/avr/dev/ide.c
  sDrive nut/arch/avr/dev/ide.c

Local Function SelectDevice()

static int SelectDevice ( BYTE bDevice )
Calls: Wait400ns() nut/arch/avr/dev/ide.c
  WaitNotBusy() nut/arch/avr/dev/ide.c
Called by: ATAPISendCommand() nut/arch/avr/dev/ide.c
  DeviceDiag() nut/arch/avr/dev/ide.c
  GetDeviceInfo() nut/arch/avr/dev/ide.c
  GetDeviceInfoPacket() nut/arch/avr/dev/ide.c
  ReadSectors() nut/arch/avr/dev/ide.c
References Variables: pIDE nut/arch/avr/dev/ide.c

Local Function Wait400ns()

static void Wait400ns ( void )
Called by: ATAPISendCommand() nut/arch/avr/dev/ide.c
  SelectDevice() nut/arch/avr/dev/ide.c

Local Function WaitDRQ()

static int WaitDRQ ( DWORD dwTimeout )
Calls: NutGetTickCount()
Called by: ATAPISendCommand() nut/arch/avr/dev/ide.c
References Variables: pIDE nut/arch/avr/dev/ide.c

Local Function WaitForInterrupt()

static int WaitForInterrupt ( DWORD dwTimeout )
Calls: NutEventWait()
Called by: ATAPISendCommand() nut/arch/avr/dev/ide.c
  DeviceDiag() nut/arch/avr/dev/ide.c
  GetDeviceInfo() nut/arch/avr/dev/ide.c
  GetDeviceInfoPacket() nut/arch/avr/dev/ide.c
  ReadSectors() nut/arch/avr/dev/ide.c
References Variables: hIDEEvent nut/arch/avr/dev/ide.c

Local Function WaitNotBusy()

static int WaitNotBusy ( DWORD dwTimeout )
Calls: NutGetTickCount()
Called by: ATAPISendCommand() nut/arch/avr/dev/ide.c
  SelectDevice() nut/arch/avr/dev/ide.c
References Variables: pIDE nut/arch/avr/dev/ide.c