📄 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****************************************************************************/#define __IDE_C__#include <stddef.h>#include <string.h>#include <sys/timer.h>#include <sys/thread.h>#include <sys/event.h>#include <sys/atom.h>#include <sys/heap.h>#include <dev/irqreg.h>#include <dev/ide.h>#include <dev/idep.h>#include <fs/typedefs.h>#define HIBYTE(_x) (BYTE)((_x >> 8) & 0x00FF)#define LOBYTE(_x) (BYTE)(_x & 0x00FF)/*==========================================================*//* DEFINE: All Structures and Common Constants *//*==========================================================*///// Here are some important values.// Change these values if you change the hardware.//#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) pIDE[x]#define IDEOut(x,y) pIDE[x] = y//// Drive Flags//#define IDE_SUPPORT_LBA 0x0001#define IDE_SUPPORT_LBA48 0x0002#define IDE_SUPPORT_PACKET 0x0004//// Device shall assert INTRQ when DRQ// is set to one after receiving PACKET.//#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//// Identify packet device// config word[0] bit masks//#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 0x8000typedef struct _drive { // // Interface values // WORD wFlags; BYTE bIDEMode; BYTE bDevice;#if (IDE_SUPPORT_CHS == 1) // // CHS values // WORD wCylinders; WORD wHeads; WORD wSectorsPerTrack; DWORD dwOneSide;#endif // // LBA value // DWORD dwTotalSectors; WORD wSectorSize;} DRIVE, *LPDRIVE;/*==========================================================*//* DEFINE: Prototypes *//*==========================================================*//*==========================================================*//* DEFINE: Definition of all local Data *//*==========================================================*/static HANDLE hIDEEvent;static volatile BYTE *pIDE;static volatile BYTE gbIntStatus = 0;static DRIVE sDrive[IDE_MAX_SUPPORTED_DEVICE];static HANDLE hIDESemaphore;static HANDLE hCFChangeInt;static BYTE gbCFMountStatus = 0;static IDE_MOUNT_FUNC *pUserMountFunc = NULL;static IDE_MOUNT_FUNC *pUserUnMountFunc = NULL;#if (IDE_SUPPORT_ATAPI == 1)//// ATAPI stuff//static BYTE aATAPICmd[12];#define ATAPI_CMD(_x) { \ memset(aATAPICmd, 0x00, sizeof(aATAPICmd)); \ aATAPICmd[0] = _x; \}#define CLEAR_ATAPI_CMD() memset(aATAPICmd, 0x00, sizeof(aATAPICmd));#endif/*==========================================================*//* DEFINE: Definition of all local Procedures *//*==========================================================*//************************************************************//* Wait400ns *//************************************************************/static void Wait400ns(void){ // // Wait at least 400ns, with 14.7456Mhz we need // 8 nop's for 500ns // COMPRESS_DISABLE; _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); COMPRESS_REENABLE;}/************************************************************//* IDELock *//************************************************************/void IDELock(void){ NutEventWait(&hIDESemaphore, 0);}/************************************************************//* IDEFree *//************************************************************/void IDEFree(void){ NutEventPost(&hIDESemaphore);}/************************************************************//* IDESemaInit *//************************************************************/void IDESemaInit(void){ NutEventPost(&hIDESemaphore);}/************************************************************//* HardwareReset *//************************************************************/static void HardwareReset(DRIVE * pDrive){ if (pDrive->bIDEMode == MEM_8BIT_COMPACT_FLASH) { // // Set Reset // PORTD |= 0x20; _NOP(); NutSleep(1000); // // Remove Reset // PORTD &= ~0x20; _NOP(); NutSleep(1000); } else { /* HD */ // // Set RESET // PORTD &= ~0x20; _NOP(); NutSleep(1000); // // Remove RESET // PORTD |= 0x20; _NOP(); if (pDrive->bIDEMode == IDE_COMPACT_FLASH) { NutSleep(1000); } else { // // It can takes up to 10 seconds (2.5-Inch drive) // from reset high to NOT busy. // Take a look in the drive manual "Reset timings" // NutSleep(10000); } }}/************************************************************//* CFInterrupt *//************************************************************/static void CFInterrupt(void *p){ p = p; NutEventPostFromIrq(&hCFChangeInt);}/************************************************************//* IDEInterrupt *//************************************************************/static void IDEInterrupt(void *p){ p = p; gbIntStatus = IDEIn(STATUS_REG); NutEventPostFromIrq(&hIDEEvent);}/************************************************************//* ClearEvent *//************************************************************/static void ClearEvent(HANDLE * pEvent){ NutEnterCritical(); *pEvent = 0; NutExitCritical();}/************************************************************//* WaitForInterrupt *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int WaitForInterrupt(DWORD dwTimeout){ int nError; int nTimeout; nError = IDE_OK; nTimeout = NutEventWait(&hIDEEvent, dwTimeout); if (nTimeout == -1) { nError = IDE_ERROR; } return (nError);}#if ((IDE_SUPPORT_WRITE == 1) || (IDE_SUPPORT_ATAPI == 1))/************************************************************//* WaitDRQ *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int WaitDRQ(DWORD dwTimeout){ int nError; BYTE bStatus; nError = IDE_OK; bStatus = IDEIn(STATUS_REG); if ((bStatus & (STATUS_BUSY | STATUS_DATA_REQUEST)) != STATUS_DATA_REQUEST) { dwTimeout = (DWORD) (((dwTimeout * 10UL) / 625UL) + 1UL); dwTimeout += NutGetTickCount(); bStatus = IDEIn(STATUS_REG); while ((bStatus & (STATUS_BUSY | STATUS_DATA_REQUEST)) != STATUS_DATA_REQUEST) { if (NutGetTickCount() > dwTimeout) { nError = IDE_ERROR; break; } bStatus = IDEIn(STATUS_REG); } } return (nError);}#endif/************************************************************//* WaitNotBusy (see ATAPI-4 r17 p223 9.6) *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int WaitNotBusy(DWORD dwTimeout){ int nError; BYTE bStatus; nError = IDE_OK; bStatus = IDEIn(STATUS_REG); if (bStatus & (STATUS_BUSY | STATUS_DATA_REQUEST)) { dwTimeout = ((dwTimeout * 10) / 625) + 1; dwTimeout += NutGetTickCount(); bStatus = IDEIn(STATUS_REG); while (bStatus & (STATUS_BUSY | STATUS_DATA_REQUEST)) { if (NutGetTickCount() > dwTimeout) { nError = IDE_BUSY; break; } bStatus = IDEIn(STATUS_REG); } } return (nError);}/************************************************************//* SelectDevice (see ATAPI-4 r17 p223 9.6) *//* *//* Return: IDE_OK, IDE_ERROR *//************************************************************/static int SelectDevice(BYTE bDevice){ int nError;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -