| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694 |
- /****************************************************************************
- * 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 0x8000
- typedef 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;
- int nTimeout;
- BYTE bStatus;
- BYTE bDummy;
- nError = IDE_OK;
- if (WaitNotBusy(CONTROLLERTIMEOUT) == IDE_OK) {
- IDEOut(DISK_HEAD_REG, 0xA0 + (bDevice << 4));
- Wait400ns();
- nError = WaitNotBusy(CONTROLLERTIMEOUT);
- } else {
- nError = IDE_BUSY;
- }
- if (nError != IDE_OK) {
- //
- // Test for special case, data available.
- // If data available, read the data!!
- //
- bStatus = IDEIn(STATUS_REG);
- if (bStatus & STATUS_DATA_REQUEST) {
- nTimeout = 512;
- while ((bStatus & STATUS_DATA_REQUEST) && (nTimeout)) {
- bDummy = IDEIn(DATA_READ_REG_LOW);
- bDummy = IDEIn(DATA_READ_REG_LOW);
- bStatus = IDEIn(STATUS_REG);
- nTimeout--;
- }
- }
- }
- return (nError);
- }
- #if (IDE_SUPPORT_ATAPI == 1)
- /************************************************************/
- /* ATAPISendCommand */
- /* */
- /* Return: IDE_OK, IDE_ERROR */
- /************************************************************/
- static int ATAPISendCommand(LPDRIVE pDrive, BYTE * pSectorBuffer, WORD * pReadCount)
- {
- int nError;
- BYTE bStatus;
- BYTE bDevice;
- WORD x, y;
- BYTE bDummy;
- WORD wSectorSize;
- nError = IDE_ERROR;
- bDummy = 0;
- bDevice = pDrive->bDevice;
- wSectorSize = pDrive->wSectorSize;
- *pReadCount = 0;
- if (SelectDevice(bDevice) == IDE_OK) {
- ClearEvent(&hIDEEvent);
- if (WaitNotBusy(ATAPITIMEOUT) == IDE_OK) {
- IDEOut(FEATURE_REG, 0x00);
- IDEOut(SECTOR_COUNT_REG, 0x00);
- IDEOut(SECTOR_REG, 0x00);
- IDEOut(CYLINDER_LOW_REG, LOBYTE(wSectorSize));
- IDEOut(CYLINDER_HIGH_REG, HIBYTE(wSectorSize));
- IDEOut(COMMAND_REG, 0xA0);
- if (pDrive->wFlags & IDE_SUPPORT_INTRQ_PACKET) {
- nError = WaitForInterrupt(ATAPITIMEOUT);
- if (nError == IDE_OK) {
- ClearEvent(&hIDEEvent);
- }
- } else {
- nError = WaitDRQ(ATAPITIMEOUT);
- }
- if (nError == IDE_OK) {
- for (x = 0; x < 12; x = x + 2) {
- IDEOut(DATA_WRITE_REG_HIGH, aATAPICmd[x + 1]);
- IDEOut(DATA_WRITE_REG_LOW, aATAPICmd[x]);
- }
- if (WaitForInterrupt(ATAPITIMEOUT) == IDE_OK) {
- if (gbIntStatus & STATUS_ERROR) {
- nError = IDE_ERROR;
- } else {
- nError = IDE_OK;
- if (gbIntStatus & STATUS_DATA_REQUEST) {
- Wait400ns();
- y = IDEIn(CYLINDER_HIGH_REG) << 8;
- y |= IDEIn(CYLINDER_LOW_REG);
- if (y > wSectorSize) {
- y = wSectorSize;
- }
- if (pSectorBuffer != NULL) {
- for (x = 0; x < y; x = x + 2) {
- pSectorBuffer[x] = pIDE[DATA_READ_REG_LOW];
- pSectorBuffer[x + 1] = pIDE[DATA_READ_REG_HIGH];
- }
- } else {
- for (x = 0; x < y; x = x + 2) {
- bDummy += pIDE[DATA_READ_REG_LOW];
- bDummy += pIDE[DATA_READ_REG_HIGH];
- }
- }
- *pReadCount = y;
- bStatus = IDEIn(STATUS_REG);
- } /* endif STATUS_DATA_REQUEST */
- } /* endif STATUS_ERROR */
- } /* endif WaitForInterrupt(ATAPITIMEOUT) */
- } /* endif (WaitDRQ(ATAPITIMEOUT) */
- } /* endif WaitNotBusy(ATAPITIMEOUT) */
- }
- /* endif SelectDevice(bDevice) */
- return (nError);
- }
- /************************************************************/
- /* ATAPIGetTotalSectors */
- /* */
- /* Return: IDE_OK, IDE_ERROR */
- /************************************************************/
- static int ATAPIGetTotalSectors(LPDRIVE pDrive, BYTE * pSectorBuffer, DWORD * pMaxSectors)
- {
- int nError;
- WORD wReadCount;
- WORD wErrorCount;
- DWORD dwValue;
- nError = IDE_OK;
- *pMaxSectors = 0;
- wErrorCount = 4;
- while (wErrorCount) {
- ATAPI_CMD(ATAPI_CMD_READ_CAPACITY);
- nError = ATAPISendCommand(pDrive, pSectorBuffer, &wReadCount);
- if ((nError == IDE_OK) && (wReadCount == 8)) {
- dwValue = pSectorBuffer[0];
- dwValue = dwValue << 8;
- dwValue |= pSectorBuffer[1];
- dwValue = dwValue << 8;
- dwValue |= pSectorBuffer[2];
- dwValue = dwValue << 8;
- dwValue |= pSectorBuffer[3];
- *pMaxSectors = dwValue;
- //
- // Get SectorSize
- //
- dwValue = pSectorBuffer[4];
- dwValue = dwValue << 8;
- dwValue |= pSectorBuffer[5];
- dwValue = dwValue << 8;
- dwValue |= pSectorBuffer[6];
- dwValue = dwValue << 8;
- dwValue |= pSectorBuffer[7];
- if (dwValue > ATAPI_SECTOR_SIZE) {
- dwValue = ATAPI_SECTOR_SIZE;
- }
- pDrive->wSectorSize = (WORD) (dwValue & 0x0000FFFF);
- break;
- }
- wErrorCount--;
- NutSleep(2000);
- }
- return (nError);
- }
- /************************************************************/
- /* GetDeviceInfoPacket */
- /* */
- /* PIO data in command protocol (see ATAPI-4 r17 p224 9.7) */
- /* */
- /* Return: IDE_OK, IDE_ERROR */
- /************************************************************/
- static int GetDeviceInfoPacket(LPDRIVE pDrive, BYTE * pSectorBuffer)
- {
- WORD i;
- int nError;
- BYTE bStatus;
- BYTE bErrorReg;
- BYTE bDevice;
- WORD wConfig;
- DWORD dwTotalSectors;
- nError = IDE_ERROR;
- bDevice = pDrive->bDevice;
- if (SelectDevice(bDevice) == IDE_OK) {
- ClearEvent(&hIDEEvent);
- IDEOut(COMMAND_REG, COMMAND_DEVICE_INFO_P);
- if (WaitForInterrupt(DISKTIMEOUT) == IDE_OK) {
- if (gbIntStatus & STATUS_DATA_REQUEST) {
- for (i = 0; i < IDE_SECTOR_SIZE; i = i + 2) {
- pSectorBuffer[i] = pIDE[DATA_READ_REG_LOW];
- if (pDrive->bIDEMode == MEM_8BIT_COMPACT_FLASH) {
- pSectorBuffer[i + 1] = pIDE[DATA_READ_REG_LOW];
- } else {
- pSectorBuffer[i + 1] = pIDE[DATA_READ_REG_HIGH];
- }
- }
- //
- // Status register is read to clear
- // pending interrupts.
- //
- bStatus = IDEIn(STATUS_REG);
- pDrive->wFlags = 0;
- wConfig = *(WORD *) & pSectorBuffer[0];
- if ((wConfig & ATAPI_CFG_INTRQ) == ATAPI_USE_INTRQ) {
- pDrive->wFlags |= IDE_SUPPORT_INTRQ_PACKET;
- }
- if ((wConfig & ATAPI_CFG_DEVICE) == ATAPI_IS_DIRECT_ACCESS) {
- pDrive->wFlags |= IDE_ZIP_DEVICE;
- }
- if ((wConfig & ATAPI_CFG_DEVICE) == ATAPI_IS_CDROM) {
- pDrive->wFlags |= (IDE_READ_ONLY | IDE_CDROM_DEVICE);
- }
- if ((wConfig & ATAPI_CFG_ATAPI) == ATAPI_IS_PACKET) {
- pDrive->wFlags |= IDE_SUPPORT_PACKET;
- }
- if ((wConfig & ATAPI_CFG_12_BYTE_MSK) == ATAPI_IS_12_BYTE) {
- pDrive->wFlags |= IDE_READY;
- nError = ATAPIGetTotalSectors(pDrive, pSectorBuffer, &dwTotalSectors);
- if (nError == IDE_OK) {
- pDrive->dwTotalSectors = dwTotalSectors;
- //
- // ModeSense
- //
- ATAPI_CMD(0x5A);
- aATAPICmd[2] = 0x2A;
- aATAPICmd[7] = 0x08;
- aATAPICmd[8] = 0x00;
- ATAPISendCommand(pDrive, pSectorBuffer, &i);
- //
- // Set Speed to 150KByte
- //
- IDEATAPISetCDSpeed(bDevice, 150);
- } else {
- pDrive->dwTotalSectors = 0;
- }
- //ATAPITest(pDrive, pSectorBuffer);
- }
- }
- if (gbIntStatus & STATUS_ERROR) {
- bErrorReg = IDEIn(ERROR_REG);
- }
- }
- }
- return (nError);
- }
- #endif
- /************************************************************/
- /* GetDeviceInfo */
- /* */
- /* PIO data in command protocol (see ATAPI-4 r17 p224 9.7) */
- /* */
- /* Return: IDE_OK, IDE_ERROR */
- /************************************************************/
- static int GetDeviceInfo(LPDRIVE pDrive, BYTE * pSectorBuffer)
- {
- WORD i;
- int nError;
- BYTE bStatus;
- BYTE bErrorReg;
- BYTE bDevice;
- IDEDEVICEINFO *pInfo;
- nError = IDE_ERROR;
- bDevice = pDrive->bDevice;
- if (SelectDevice(bDevice) == IDE_OK) {
- ClearEvent(&hIDEEvent);
- #if 0
- IDEOut(FEATURE_REG, 0);
- IDEOut(SECTOR_COUNT_REG, 1);
- IDEOut(SECTOR_REG, 0);
- IDEOut(CYLINDER_LOW_REG, 0);
- IDEOut(CYLINDER_HIGH_REG, 0);
- #endif
- IDEOut(COMMAND_REG, COMMAND_DEVICE_INFO);
- if (WaitForInterrupt(DISKTIMEOUT) == IDE_OK) {
- if (gbIntStatus & STATUS_DATA_REQUEST) {
- for (i = 0; i < IDE_SECTOR_SIZE; i = i + 2) {
- pSectorBuffer[i] = pIDE[DATA_READ_REG_LOW];
- if (pDrive->bIDEMode == MEM_8BIT_COMPACT_FLASH) {
- pSectorBuffer[i + 1] = pIDE[DATA_READ_REG_LOW];
- } else {
- pSectorBuffer[i + 1] = pIDE[DATA_READ_REG_HIGH];
- }
- }
- //
- // Status register is read to clear
- // pending interrupts.
- //
- bStatus = IDEIn(STATUS_REG);
- pInfo = (IDEDEVICEINFO *) pSectorBuffer;
- #if (IDE_SUPPORT_CHS == 1)
- pDrive->wCylinders = (WORD) pInfo->Cylinders;
- pDrive->wHeads = (BYTE) pInfo->Heads;
- pDrive->wSectorsPerTrack = (BYTE) pInfo->SectorsPerTrack;
- pDrive->dwOneSide = pDrive->wCylinders * pDrive->wSectorsPerTrack;
- #endif
- if (pInfo->LBASectors > 0) {
- pDrive->wFlags = IDE_READY | IDE_SUPPORT_LBA;
- pDrive->dwTotalSectors = pInfo->LBASectors;
- } else {
- #if (IDE_SUPPORT_CHS == 1)
- pDrive->wFlags = IDE_READY;
- pDrive->dwTotalSectors = pInfo->Cylinders;
- pDrive->dwTotalSectors *= pInfo->Heads;
- pDrive->dwTotalSectors *= pInfo->SectorsPerTrack;
- #endif
- }
- nError = IDE_OK;
- }
- if (gbIntStatus & STATUS_ERROR) {
- bErrorReg = IDEIn(ERROR_REG);
- }
- }
- }
- return (nError);
- }
- /************************************************************/
- /* IsPacketDevice */
- /* */
- /* Check Command block register, */
- /* see page 210, 9.1 Signature and persistence */
- /* */
- /* Return: TRUE, FALSE */
- /************************************************************/
- #if (IDE_SUPPORT_ATAPI == 1)
- static int IsPacketDevice(void)
- {
- int nPacketDevice;
- BYTE bSectorCount;
- BYTE bSectorNumber;
- BYTE bCylinderLow;
- BYTE bCylinderHigh;
- nPacketDevice = FALSE;
- bSectorCount = IDEIn(SECTOR_COUNT_REG);
- bSectorNumber = IDEIn(SECTOR_REG);
- bCylinderLow = IDEIn(CYLINDER_LOW_REG);
- bCylinderHigh = IDEIn(CYLINDER_HIGH_REG);
- if ((bCylinderLow == 0x14) && (bCylinderHigh == 0xEB)) {
- nPacketDevice = TRUE;
- }
- return (nPacketDevice);
- }
- #else
- static int IsPacketDevice(void)
- {
- return (FALSE);
- }
- #endif
- /************************************************************/
- /* DeviceDiag */
- /* */
- /* NON-data command protocol (see ATAPI-4 r17 p231 9.9) */
- /* */
- /* Return: IDE_OK, IDE_ERROR */
- /************************************************************/
- static int DeviceDiag(LPDRIVE pDrive)
- {
- int nError;
- BYTE bResult;
- nError = IDE_ERROR;
- if (SelectDevice(0) == IDE_OK) {
- #if 0
- IDEOut(FEATURE_REG, 0);
- IDEOut(SECTOR_COUNT_REG, 1);
- IDEOut(SECTOR_REG, 0);
- IDEOut(CYLINDER_LOW_REG, 0);
- IDEOut(CYLINDER_HIGH_REG, 0);
- #endif
- ClearEvent(&hIDEEvent);
- //
- // Check if we are a PACKET device
- //
- if (IsPacketDevice() == TRUE) {
- nError = IDE_OK;
- pDrive->wFlags = IDE_SUPPORT_PACKET;
- } else {
- IDEOut(COMMAND_REG, COMMAND_DIAG);
- if (WaitForInterrupt(INITTIMEOUT) == IDE_OK) {
- bResult = IDEIn(ERROR_REG);
- if (bResult == 0x01) { // see ATAPI-4 r17 p72
- nError = IDE_OK;
- }
- }
- }
- }
- return (nError);
- }
- /************************************************************/
- /* ReadSectors */
- /* */
- /* PIO data in command protocol, see ATAPI-4 r17 p224 9.7 */
- /* */
- /* Return: IDE_OK, IDE_ERROR */
- /************************************************************/
- static int ReadSectors(BYTE bDevice, BYTE * pData, DWORD dwStartSector, WORD wSectorCount)
- {
- WORD i, x;
- int nError;
- BYTE bValue;
- BYTE bErrorReg;
- BYTE bStatus;
- LPDRIVE pDrive;
- #if (IDE_SUPPORT_CHS == 1)
- WORD wCHSSector;
- WORD wCHSHead;
- WORD wCHSCylinder;
- #endif
- pDrive = &sDrive[bDevice];
- nError = SelectDevice(bDevice);
- #if (IDE_SUPPORT_CHS == 0)
- //
- // NO CHS support
- //
- if ((pDrive->wFlags & IDE_SUPPORT_LBA) == 0) {
- //
- // If we have a CHS device, this is an ERROR
- //
- nError = IDE_ERROR;
- }
- #endif
- if (nError == IDE_OK) {
- ClearEvent(&hIDEEvent);
- if (pDrive->wFlags & IDE_SUPPORT_LBA) {
- //
- // LBA
- //
- bValue = (BYTE) ((bDevice << 4) | 0xE0 | (dwStartSector >> 24));
- IDEOut(DISK_HEAD_REG, bValue);
- IDEOut(LBA_16_23, (BYTE) (dwStartSector >> 16));
- IDEOut(LBA_8_15, (BYTE) (dwStartSector >> 8));
- IDEOut(LBA_0_7, (BYTE) (dwStartSector));
- IDEOut(SECTOR_COUNT_REG, (BYTE) (wSectorCount & 0xff));
- IDEOut(COMMAND_REG, COMMAND_READ_SECTORS);
- #if (IDE_SUPPORT_CHS == 1)
- } else {
- //
- // CHS
- //
- wCHSSector = (WORD) (dwStartSector % pDrive->wSectorsPerTrack) + 1;
- wCHSHead = (WORD) (dwStartSector / pDrive->dwOneSide);
- dwStartSector = dwStartSector % pDrive->dwOneSide;
- wCHSCylinder = (WORD) (dwStartSector / pDrive->wSectorsPerTrack);
- wCHSHead |= (bDevice << 4) | 0xA0;
- IDEOut(DISK_HEAD_REG, (BYTE) wCHSHead);
- IDEOut(SECTOR_REG, (BYTE) wCHSSector);
- IDEOut(CYLINDER_LOW_REG, (BYTE) (wCHSCylinder & 0x00FF));
- IDEOut(CYLINDER_HIGH_REG, (BYTE) (wCHSCylinder >> 8));
- IDEOut(SECTOR_COUNT_REG, (BYTE) (wSectorCount & 0xff));
- IDEOut(COMMAND_REG, COMMAND_READ_SECTORS);
- #endif
- }
- for (i = 0; i < wSectorCount; i++) {
- nError = WaitForInterrupt(DISKTIMEOUT);
- if (nError == IDE_OK) {
- bStatus = gbIntStatus;
- if (bStatus & STATUS_ERROR) {
- bErrorReg = IDEIn(ERROR_REG);
- nError = IDE_ERROR;
- break;
- }
- for (x = 0; x < IDE_SECTOR_SIZE; x = x + 2) {
- pData[x] = pIDE[DATA_READ_REG_LOW];
- if (pDrive->bIDEMode == MEM_8BIT_COMPACT_FLASH) {
- pData[x + 1] = pIDE[DATA_READ_REG_LOW];
- } else {
- pData[x + 1] = pIDE[DATA_READ_REG_HIGH];
- }
- }
- pData += IDE_SECTOR_SIZE;
- } else {
- bStatus = IDEIn(STATUS_REG);
- bErrorReg = IDEIn(ERROR_REG);
- }
- }
- bStatus = IDEIn(STATUS_REG);
- }
- /* SelectDevice */
- return (nError);
- }
- #if (IDE_SUPPORT_WRITE == 1)
- /************************************************************/
- /* WriteSectors */
- /* */
- /* PIO data out command protocol, see ATAPI-4 r17 p227 9.8 */
- /* */
- /* Return: IDE_OK, IDE_ERROR */
- /************************************************************/
- static BYTE WriteSectors(WORD bDevice, BYTE * pData, DWORD dwStartSector, WORD wSectorCount)
- {
- WORD i;
- int x;
- int nError;
- BYTE bValue;
- BYTE bStatus;
- BYTE bErrorReg;
- LPDRIVE pDrive;
- #if (IDE_SUPPORT_CHS == 1)
- WORD wCHSSector;
- WORD wCHSHead;
- WORD wCHSCylinder;
- #endif
- pDrive = &sDrive[bDevice];
- nError = SelectDevice(bDevice);
- #if (IDE_SUPPORT_CHS == 0)
- //
- // NO CHS support
- //
- if ((pDrive->wFlags & IDE_SUPPORT_LBA) == 0) {
- //
- // If we found a CHS device, this is an ERROR
- //
- nError = IDE_ERROR;
- }
- #endif
- if (nError == IDE_OK) {
- if (pDrive->wFlags & IDE_SUPPORT_LBA) {
- //
- // LBA
- //
- bValue = (BYTE) ((bDevice << 4) | 0xE0 | (dwStartSector >> 24));
- IDEOut(DISK_HEAD_REG, bValue);
- IDEOut(LBA_16_23, (BYTE) (dwStartSector >> 16));
- IDEOut(LBA_8_15, (BYTE) (dwStartSector >> 8));
- IDEOut(LBA_0_7, (BYTE) (dwStartSector));
- IDEOut(SECTOR_COUNT_REG, (BYTE) (wSectorCount & 0xff));
- IDEOut(COMMAND_REG, COMMAND_WRITE_SECTORS);
- #if (IDE_SUPPORT_CHS == 1)
- } else {
- //
- // CHS
- //
- wCHSSector = (WORD) (dwStartSector % pDrive->wSectorsPerTrack) + 1;
- wCHSHead = (WORD) (dwStartSector / pDrive->dwOneSide);
- dwStartSector = dwStartSector % pDrive->dwOneSide;
- wCHSCylinder = (WORD) (dwStartSector / pDrive->wSectorsPerTrack);
- wCHSHead |= (bDevice << 4) | 0xA0;
- IDEOut(DISK_HEAD_REG, (BYTE) wCHSHead);
- IDEOut(SECTOR_REG, (BYTE) wCHSSector);
- IDEOut(CYLINDER_LOW_REG, (BYTE) (wCHSCylinder & 0x00FF));
- IDEOut(CYLINDER_HIGH_REG, (BYTE) (wCHSCylinder >> 8));
- IDEOut(SECTOR_COUNT_REG, (BYTE) (wSectorCount & 0xff));
- IDEOut(COMMAND_REG, COMMAND_WRITE_SECTORS);
- #endif
- }
- if (WaitDRQ(CONTROLLERTIMEOUT) == IDE_OK) {
- bStatus = IDEIn(STATUS_REG);
- for (i = 0; i < wSectorCount; i++) {
- for (x = 0; x < IDE_SECTOR_SIZE; x = x + 2) {
- if (pDrive->bIDEMode == MEM_8BIT_COMPACT_FLASH) {
- IDEOut(DATA_WRITE_REG_LOW, pData[x]);
- IDEOut(DATA_WRITE_REG_LOW, pData[x + 1]);
- } else {
- IDEOut(DATA_WRITE_REG_HIGH, pData[x + 1]);
- IDEOut(DATA_WRITE_REG_LOW, pData[x]);
- }
- }
- pData += IDE_SECTOR_SIZE;
- nError = WaitForInterrupt(DISKTIMEOUT);
- if (nError == IDE_OK) {
- bStatus = gbIntStatus;
- if ((bStatus & STATUS_ERROR) == STATUS_ERROR) {
- bErrorReg = IDEIn(ERROR_REG);
- nError = IDE_ERROR;
- break;
- }
- } else {
- //
- // Error
- //
- nError = IDE_ERROR;
- break;
- }
- }
- } else {
- //
- // Device: Set error status (D)
- //
- WaitForInterrupt(DISKTIMEOUT);
- bErrorReg = IDEIn(ERROR_REG);
- } /* endif WaitDRQ */
- }
- /* SelectDevice */
- return (nError);
- }
- #endif
- /************************************************************/
- /* CFChange */
- /************************************************************/
- THREAD(CFChange, arg)
- {
- BYTE bNewStatus;
- BYTE *pSectorBuffer;
- while (1) {
- NutEventWaitNext(&hCFChangeInt, 0);
- //
- // Wait a while, that the cf contact is stable and not to bounce.
- //
- NutSleep(2000);
- bNewStatus = (PINE & BV(CF_IRQ));
- if (bNewStatus != gbCFMountStatus) {
- if (bNewStatus == CF_AVAILABLE) {
- gbCFMountStatus = CF_AVAILABLE;
- //
- // We must mount the new CF card.
- //
- HardwareReset(&sDrive[0]);
- pSectorBuffer = (BYTE *) NutHeapAlloc(IDE_SECTOR_SIZE);
- if (pSectorBuffer != NULL) {
- IDEMountDevice(IDE_DRIVE_C, pSectorBuffer);
- NutHeapFree(pSectorBuffer);
- if (pUserMountFunc != NULL) {
- pUserMountFunc(IDE_DRIVE_C);
- }
- }
- NutEnterCritical();
- EICR &= ~CF_INT_SENS_MASK;
- EICR |= CF_INT_RISING_EDGE;
- NutExitCritical();
- } else {
- gbCFMountStatus = CF_NOT_AVAILABLE;
- //
- // The user has removed the CF card,
- // now UnMount the device.
- //
- IDEUnMountDevice(IDE_DRIVE_C);
- if (pUserUnMountFunc != NULL) {
- pUserUnMountFunc(IDE_DRIVE_C);
- }
- NutEnterCritical();
- EICR &= ~CF_INT_SENS_MASK;
- EICR |= CF_INT_FALLING_EDGE;
- NutExitCritical();
- }
- } /* endif bValue != gbCFMountStatus */
- } /* end while */
- }
- /*==========================================================*/
- /* DEFINE: All code exported */
- /*==========================================================*/
- /************************************************************/
- /* IDEInit */
- /************************************************************/
- int IDEInit(int nBaseAddress, int nIDEMode, IDE_MOUNT_FUNC * pMountFunc, IDE_MOUNT_FUNC * pUnMountFunc)
- {
- int i;
- int nError;
- BYTE bValue;
- pUserMountFunc = pMountFunc;
- pUserUnMountFunc = pUnMountFunc;
- //
- // If nBaseAddress is 0, we use the default address
- //
- if (nBaseAddress == 0) {
- nBaseAddress = IDE_BASE_ADDRESS;
- }
- //
- // With MCUCR 0xC0 and XMCRA 0x02 we set:
- //
- // Wait two cycles during read/write and
- // wait one cycle before driving out new address.
- // This setting is for 0x1100 - 0xffff
- //
- #ifdef __AVR_ENHANCED__
- XMCRA = _BV(SRW11);
- #endif
- //
- // Enable the IDE Reset
- //
- DDRD = 0x20;
- for (i = 0; i < IDE_MAX_SUPPORTED_DEVICE; i++) {
- memset((BYTE *) & sDrive[i], 0x00, sizeof(DRIVE));
- sDrive[i].bDevice = (BYTE) i;
- sDrive[i].bIDEMode = (BYTE) nIDEMode;
- }
- IDESemaInit();
- pIDE = (unsigned char *) nBaseAddress;
- ClearEvent(&hIDEEvent);
- NutEnterCritical();
- //
- // Clear interrupt status
- //
- gbIntStatus = 0;
- //
- // Install IDE interrupt
- //
- nError = NutRegisterIrqHandler(&sig_INTERRUPT7, IDEInterrupt, NULL);
- if (nError == FALSE) {
- EICR |= IDE_INT_RISING_EDGE;
- sbi(EIMSK, IDE_IRQ);
- }
- switch (nIDEMode) {
- case IDE_HARDDISK:{
- break;
- }
- //
- // If your drive does not work correct with 14.7456Mhz,
- // try to devide the clock by 2.
- //
- // Important: You must correct the baudrate in your app.
- // if you set 115200, you get only 57600.
- //
- case IDE_HARDDISK_7MHZ:{
- #if defined(CLKPR) /* AT90MEGA128 uses a clock prescaler register */
- CLKPR = _BV(CLKPCE); // Enable clock speed change
- CLKPR = 2; // Run at half the clock speed
- #else
- XDIV = 0xff;
- #endif
- break;
- }
- case IDE_COMPACT_FLASH:{
- break;
- }
- case MEM_8BIT_COMPACT_FLASH:{
- //
- // Now we will support to change the CF-Card in
- // a running system, therefore we must install
- // a INT handler and some other parts :-)
- //
- //
- // Clear CF_INT_SENS_MASK.
- //
- EICR &= ~CF_INT_SENS_MASK;
- //
- // Check the status of the compact flash.
- //
- bValue = (PINE & BV(CF_IRQ));
- if (bValue == CF_AVAILABLE) {
- gbCFMountStatus = CF_AVAILABLE;
- //
- // The rising edge between two samples
- // of INTX generates an interrupt request.
- //
- EICR |= CF_INT_RISING_EDGE;
- } else {
- gbCFMountStatus = CF_NOT_AVAILABLE;
- //
- // The falling edge between two samples
- // of INTX generates an interrupt request.
- //
- EICR |= CF_INT_FALLING_EDGE;
- }
- nError = NutRegisterIrqHandler(&sig_INTERRUPT6, CFInterrupt, NULL);
- if (nError == FALSE) {
- NutThreadCreate("cfchange", CFChange, NULL, 640);
- sbi(EIMSK, CF_IRQ);
- }
- break;
- }
- }
- NutExitCritical();
- HardwareReset(&sDrive[0]);
- nError = IDE_OK;
- return (nError);
- }
- /************************************************************/
- /* IDEMountDevice */
- /************************************************************/
- int IDEMountDevice(BYTE bDevice, BYTE * pSectorBuffer)
- {
- int nError;
- LPDRIVE pDrive;
- pDrive = NULL;
- IDELock();
- if (bDevice >= IDE_MAX_SUPPORTED_DEVICE) {
- nError = IDE_ERROR;
- } else {
- pDrive = &sDrive[bDevice];
- pDrive->wFlags = 0;
- #if (IDE_SUPPORT_CHS == 1)
- //
- // CHS values
- //
- pDrive->wCylinders = 0;
- pDrive->wHeads = 0;
- pDrive->wSectorsPerTrack = 0;
- #endif
- //
- // LBA value
- //
- pDrive->dwTotalSectors = 0;
- nError = DeviceDiag(pDrive);
- if (pDrive->wFlags & IDE_SUPPORT_PACKET) {
- #if (IDE_SUPPORT_ATAPI == 1)
- pDrive->wSectorSize = ATAPI_SECTOR_SIZE;
- nError = GetDeviceInfoPacket(pDrive, pSectorBuffer);
- if (pDrive->wFlags & IDE_READY) {
- nError = IDE_OK;
- }
- #endif
- } else {
- if (nError != IDE_OK) {
- //
- // Try it again
- //
- nError = DeviceDiag(pDrive);
- }
- if (nError == IDE_OK) {
- pDrive->wSectorSize = IDE_SECTOR_SIZE;
- nError = GetDeviceInfo(pDrive, pSectorBuffer);
- if (pDrive->wFlags & IDE_READY) {
- nError = IDE_OK;
- }
- }
- }
- } /* (bDevice >= IDE_MAX_SUPPORTED_DEVICE) */
- IDEFree();
- return (nError);
- }
- /************************************************************/
- /* IDEGetSectorSize */
- /************************************************************/
- int IDEGetSectorSize(BYTE bDevice)
- {
- int nSectorSize;
- LPDRIVE pDrive;
- nSectorSize = 0;
- IDELock();
- if (bDevice >= IDE_MAX_SUPPORTED_DEVICE) {
- nSectorSize = 0;
- } else {
- pDrive = &sDrive[bDevice];
- nSectorSize = pDrive->wSectorSize;
- }
- IDEFree();
- return (nSectorSize);
- }
- /************************************************************/
- /* IDEIsCDROMDevice */
- /************************************************************/
- int IDEIsCDROMDevice(BYTE bDevice)
- {
- int nIsCDROM;
- LPDRIVE pDrive;
- nIsCDROM = FALSE;
- IDELock();
- if (bDevice >= IDE_MAX_SUPPORTED_DEVICE) {
- nIsCDROM = FALSE;
- } else {
- pDrive = &sDrive[bDevice];
- if ((pDrive->wFlags & IDE_READY) && (pDrive->wFlags & IDE_CDROM_DEVICE)) {
- nIsCDROM = TRUE;
- }
- }
- IDEFree();
- return (nIsCDROM);
- }
- /************************************************************/
- /* IDEIsZIPDevice */
- /************************************************************/
- int IDEIsZIPDevice(BYTE bDevice)
- {
- int nIsZIP;
- LPDRIVE pDrive;
- nIsZIP = FALSE;
- IDELock();
- if (bDevice >= IDE_MAX_SUPPORTED_DEVICE) {
- nIsZIP = FALSE;
- } else {
- pDrive = &sDrive[bDevice];
- if ((pDrive->wFlags & IDE_READY) && (pDrive->wFlags & IDE_ZIP_DEVICE)) {
- nIsZIP = TRUE;
- }
- }
- IDEFree();
- return (nIsZIP);
- }
- /************************************************************/
- /* IDEUnMountDevice */
- /************************************************************/
- int IDEUnMountDevice(BYTE bDevice)
- {
- int nError = 0;
- LPDRIVE pDrive;
- pDrive = NULL;
- IDELock();
- if (bDevice >= IDE_MAX_SUPPORTED_DEVICE) {
- nError = IDE_ERROR;
- } else {
- pDrive = &sDrive[bDevice];
- pDrive->wFlags = 0;
- }
- IDEFree();
- return (nError);
- }
- /************************************************************/
- /* IDEGetTotalSectors */
- /************************************************************/
- DWORD IDEGetTotalSectors(BYTE bDevice)
- {
- DWORD dwTotalSectors;
- LPDRIVE pDrive;
- dwTotalSectors = 0;
- IDELock();
- if (bDevice >= IDE_MAX_SUPPORTED_DEVICE) {
- dwTotalSectors = 0;
- } else {
- pDrive = &sDrive[bDevice];
- dwTotalSectors = pDrive->dwTotalSectors;
- dwTotalSectors -= 64;
- }
- IDEFree();
- return (dwTotalSectors);
- }
- /************************************************************/
- /* IDEReadSectors */
- /************************************************************/
- int IDEReadSectors(BYTE bDevice, void *pData, DWORD dwStartSector, WORD wSectorCount)
- {
- WORD i;
- int nError;
- WORD wReadCount;
- LPDRIVE pDrive = 0;
- BYTE *pByte;
- nError = IDE_OK;
- IDELock();
- if (bDevice >= IDE_MAX_SUPPORTED_DEVICE) {
- nError = IDE_DRIVE_NOT_FOUND;
- } else {
- pDrive = &sDrive[bDevice];
- if ((pDrive->wFlags & IDE_READY) == 0) {
- nError = IDE_DRIVE_NOT_FOUND;
- } else {
- if ((dwStartSector + wSectorCount) > pDrive->dwTotalSectors) {
- nError = IDE_PARAM_ERROR;
- }
- }
- }
- if ((pDrive->wFlags & IDE_SUPPORT_PACKET) && ((wSectorCount > 1))) {
- //
- // Sorry, in this version we support
- // only 1 sector for PACKET devices.
- //
- nError = IDE_PARAM_ERROR;
- }
- if ((pDrive->wFlags & IDE_SUPPORT_PACKET) && (nError == IDE_OK)) {
- #if (IDE_SUPPORT_ATAPI == 1)
- //
- // ATAPI
- //
- ATAPI_CMD(ATAPI_CMD_READ12);
- i = 5;
- while (dwStartSector) {
- aATAPICmd[i--] = (BYTE) dwStartSector;
- dwStartSector >>= 8;
- }
- //
- // Reading one sector only
- //
- aATAPICmd[9] = 1;
- nError = ATAPISendCommand(pDrive, pData, &i);
- if ((nError != IDE_OK) || (i != pDrive->wSectorSize)) {
- nError = IDE_ERROR;
- }
- #else
- nError = IDE_ERROR;
- #endif
- } else {
- if (nError == IDE_OK) {
- pByte = (BYTE *) pData;
- while (wSectorCount > 0) {
- if (wSectorCount < 256) {
- wReadCount = wSectorCount;
- } else {
- wReadCount = 256;
- }
- nError = ReadSectors(bDevice, pByte, dwStartSector, wReadCount);
- if (nError != IDE_OK) {
- break;
- }
- dwStartSector += wReadCount;
- wSectorCount -= wReadCount;
- pByte += (wReadCount * pDrive->wSectorSize);
- }
- }
- }
- IDEFree();
- return (nError);
- }
- #if (IDE_SUPPORT_WRITE == 1)
- /************************************************************/
- /* IDEWriteSectors */
- /************************************************************/
- int IDEWriteSectors(BYTE bDevice, void *pData, DWORD dwStartSector, WORD wSectorCount)
- {
- int nError;
- WORD wWriteCount;
- LPDRIVE pDrive;
- BYTE *pByte;
- nError = IDE_OK;
- pDrive = NULL;
- IDELock();
- if (bDevice >= IDE_MAX_SUPPORTED_DEVICE) {
- nError = IDE_DRIVE_NOT_FOUND;
- } else {
- pDrive = &sDrive[bDevice];
- if ((dwStartSector + wSectorCount) > pDrive->dwTotalSectors) {
- nError = IDE_PARAM_ERROR;
- }
- if ((pDrive->wFlags & IDE_READY) == 0) {
- nError = IDE_DRIVE_NOT_FOUND;
- }
- if (pDrive->wFlags & IDE_READ_ONLY) {
- nError = IDE_NOT_SUPPORTED;
- }
- }
- if (nError == IDE_OK) {
- pByte = (BYTE *) pData;
- while (wSectorCount > 0) {
- if (wSectorCount < 256) {
- wWriteCount = wSectorCount;
- } else {
- wWriteCount = 256;
- }
- nError = WriteSectors(bDevice, pByte, dwStartSector, wWriteCount);
- if (nError != IDE_OK) {
- break;
- }
- dwStartSector += wWriteCount;
- wSectorCount -= wWriteCount;
- pByte += (wWriteCount * IDE_SECTOR_SIZE);
- }
- }
- IDEFree();
- return (nError);
- }
- #endif
- #if (IDE_SUPPORT_ATAPI == 1)
- /************************************************************/
- /* IDEATAPISetCDSpeed */
- /************************************************************/
- int IDEATAPISetCDSpeed(BYTE bDevice, WORD wSpeed)
- {
- WORD i;
- int nError;
- LPDRIVE pDrive;
- nError = IDE_OK;
- pDrive = NULL;
- if (bDevice >= IDE_MAX_SUPPORTED_DEVICE) {
- nError = IDE_DRIVE_NOT_FOUND;
- } else {
- pDrive = &sDrive[bDevice];
- if ((pDrive->wFlags & IDE_READY) == 0) {
- nError = IDE_DRIVE_NOT_FOUND;
- }
- if ((pDrive->wFlags & IDE_SUPPORT_PACKET) == 0) {
- nError = IDE_NOT_SUPPORTED;
- }
- }
- if (nError == IDE_OK) {
- ATAPI_CMD(0xBB);
- aATAPICmd[2] = (BYTE) ((wSpeed >> 8) & 0x00FF);
- aATAPICmd[3] = (BYTE) (wSpeed & 0x00FF);
- nError = ATAPISendCommand(pDrive, NULL, &i);
- }
- return (nError);
- }
- #endif
|