📄 cf卡.txt
字号:
printf("error reg: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
return -1;
}
/* PIO read step (h) */
usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
usStatus = IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base);
/* PIO read step (i) */
if (usStatus & AltStatusRegBitDRQ)
{
for (i = 0; i < 256; ++i)
{
iIndex = i + 256 * iSect;
// printf("writing byte at index %d\r", iIndex);
pusBuffer[iIndex] = IORD_ALTERA_AVALON_CF_IDE_DATA(ide_base);
}
}
else
{
printf("readSectorsGuts(): error: DRQ not set in status reg\n");
return -1;
}
}
return 0;
}
//++++++++++++++++++读扇区 LBA模式!!!!关键++++++++++++++++++++++++++++//
/*
* readSectorsLBA()
*
* Read sector(s) in LBA mode addressing.
*/
int readSectorsLBA(int iDevice, unsigned long ulLBA,
int iSectorCount, unsigned short *pusBuffer)
{
if (gbVerbose)
{
printf("LBA = %u; numSectors: %d\r", (unsigned int)ulLBA, iSectorCount);
}
/* PIO read steps (a) through (c) */
if (PIODataInOrOutPreamble(iDevice))
{
printf("readSectorsLBA(): PIODataInOrOutPreamble failed.\r");
return -1;
}
/* PIO read step (d) */
IOWR_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base, iSectorCount); //写入扇区计数寄存器
IOWR_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base, ulLBA & 0xFF); //扇区寄存器
ulLBA >>= 8;
IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_LOW(ide_base, ulLBA & 0xFF); //柱面低位寄存器
ulLBA >>= 8;
IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_HIGH(ide_base, ulLBA & 0xFF); //柱面高位寄存器
ulLBA >>= 8;
IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base,
(ulLBA & 0x0F) | 0xE0 | // LBA on
(iDevice ? DevHeadRegBitDEV : 0)); //设置磁头寄存器(高3位、设定lba模式,设备号)
/* PIO read step (e) */
IDEinterrupt = 0;
IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, ReadSectorWithRetries); //写入命令寄存器命令字
/* PIO read steps (f-j) */
return readSectorsGuts(iSectorCount, pusBuffer); //返回读扇区!?函数在上面看星号处
}
/*
* Brief primer on PIO mode IDE writes. The comments below are referenced
* in relevant code in the low-level write routines:
*
* PIO Data Out:
* a) The host reads the status or alt status reg until BSY=0.
* b) The host writes the dev/head register with the appropriate dev
* bit value.
* c) The host reads the status or alt status register until BSY=0 and
* DRDY=1.
* d) The host writes any required command parameters to the Features,
* Sector Count, Sector Number, Cylinder High, Cylinder Low and
* Device/Head registers.
* e) The host writes the command code to the Command register.
* f) The device sets the BSY bit and prepares to execute the command
* including preparation to transfer the first block of data to the
* host. (Note: it may take up to 400ns for BSY to go high.)
* g) When ready to receive the first block of data from the host, the device
* sets the DRQ bit (setting the DRQ bit is optional if an error condition
* exists) and any other status or error bits as required and clears the BSY
* bit.
* h) The host reads the status or alternate status register until BSY is
* equal to 0.
* i) If the DRQ bit is set, the host transfers a complete block of data to
* the device by writing the Data register.
* j) Next, one of the following actions is taken:
* - if an error status was present in the status read in step h), the device
* clears the DRQ bit, asserts INTRQ and the command execution is complete.
* The data transferred in steup i) is not processed by the device.
* - if no error status was presented to the host in step h), the device sets
* the BSY bit and processing continues with the next step.
* k) The device processes the data block just received from the host. When
* this processing is completed, one of the following actions is taken:
* - If no error occurred while processing the data block and if no add'l
* blocks are to be transferred, the device clears the BSY bit and then
* asserts INTRQ. Command execution is complete;
* - If an error occured while processing the data block the device sets the
* appropriate bits as required by the error condition. The device clears
* the BSY bit and then asserts INTRQ. Command execution is complete.
* - If no error occurred while processing the data block and if the transfer
* of another block is required, processing continues with the next step.
* l) When ready to receive the next block from the host, the device sets the
* DRQ bit, clears the BSY bit and then asserts INTRQ;
* m) After detecting either BSY=0 (alternate status) or INTRQ, the host reads
* the contents of the status register.
* n) The host transfers a complete block of data to the device by writing
* the data register.
* o) The device sets the BSY bit and processing continues at step k).
*/
/*
* writeSectorsGuts()
*
* Low-level write comands common to both CHS & LBA PIO-mode IDE writes
*/
int writeSectorsGuts(int iSectorCount, unsigned short *pusBuffer)
{
int i, iNumSectorsWritten = 0;
unsigned short usStatus;
/* PIO write step (e) */
IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, WriteSectorWithRetries);
/* PIO write step (f) */
usleep(1);
/* PIO write steps (g) & (h) */
if (awaitBSYZero(1000))
{
printf("writeSectorsGuts(): error: timeout (2) awaiting BSY=0\n");
return -1;
}
usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
/* PIO write step (i) */
usStatus = IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base);
if (usStatus & StatusRegBitDRQ)
{
for (i = 0; i < 256; ++i)
{
IOWR_ALTERA_AVALON_CF_IDE_DATA(ide_base, pusBuffer[i]);
}
}
else
{
printf("writeSectorsGuts(): error: DRQ not set.\r");
return -1;
}
/* PIO write step (j) */
if (usStatus & AltStatusRegBitERR)
{
printf("writeSectorsGuts(): error occurred during write (error reg=0x%X)\n",
IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
awaitINTRQ(1000);
return -1;
}
iNumSectorsWritten++;
while (1)
{
/* PIO write step (k) */
if (awaitBSYZero(1000))
{
printf("writeSectorsGuts(): error: timeout (3) awaiting BSY=0\n");
return -1;
}
if (awaitINTRQ(5000))
{
printf("writeSectorsGuts(): error: timeout awaiting INTRQ=1\n");
printf("error reg: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
return -1;
}
usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
if (usStatus & StatusRegBitERR)
{
printf("writeSectorsGuts(): error occured (error reg=0x%X\n",
IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
return -1;
}
if (iNumSectorsWritten >= iSectorCount)
{
return 0;
}
/* PIO write step (l) */
if (awaitDRQ(1000))
{
printf("writeSectorsGuts(): timeout awaiting DRQ for multi-sector write.\n");
return -1;
}
/* PIO write step (m) */
if (awaitBSYZeroOrINTRQ(1000))
{
printf("writeSectorsGuts(): timeout awaiting BSY=0 or INTRQ\n");
return -1;
}
usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
/* PIO write step (n) */
for (i = 0; i < 256; ++i)
{
IOWR_ALTERA_AVALON_CF_IDE_DATA(ide_base,
pusBuffer[i + iNumSectorsWritten * 256]);
}
/* PIO write step (o) */
iNumSectorsWritten++;
}
return 0;
}
///***********************写扇区lba方式********************************/////
/*
* writeSectorsLBA()
*
* Write sector(s) in LBA mode addressing.
*/
int writeSectorsLBA(int iDevice, unsigned long ulLBA,
int iSectorCount, unsigned short *pusBuffer)
{
if (gbVerbose)
{
printf("LBA = %u; numSectors: %d\r", (unsigned int)ulLBA, iSectorCount);
}
/* PIO write steps (a) through (c) */
if (PIODataInOrOutPreamble(iDevice))
{
printf("writeSectorsLBA(): PIODataInOrOutPreamble failed.\r");
return -1;
}
/* PIO write step (d) */
IOWR_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base, iSectorCount);
IOWR_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base, ulLBA & 0xFF);
ulLBA >>= 8;
IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_LOW(ide_base, ulLBA & 0xFF);
ulLBA >>= 8;
IOWR_ALTERA_AVALON_CF_IDE_CYLINDER_HIGH(ide_base, ulLBA & 0xFF);
ulLBA >>= 8;
IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base,
(ulLBA & 0x0F) | 0xE0 | // LBA on
(iDevice ? DevHeadRegBitDEV : 0));
/* PIO write steps (e) through (o) */
if(writeSectorsGuts(iSectorCount, pusBuffer))
{
printf("writeSectorsCHS(): writeSectorsGuts failed.\n");
return -1;
}
return 0;
}
/*
* IDE_initializeDeviceParameters() //ide设备参数初始化
*
* For some reason IDE devices need their parameters written into them after
* initialization where these same parameters were earlier read out. Bizarre.
*/
int IDE_initializeDeviceParameters(int iDevice,
unsigned short usLogicalHeads, unsigned short usLogicalCylinders,
unsigned short usSectorsPerTrack)
{
unsigned short usStatus, usError;
/* PIO read/write steps (a) through (c) */
if (PIODataInOrOutPreamble(iDevice))
{
printf("IDE_initializeDeviceParameters(): PIODataInOrOutPreamble failed.\r");
return -1;
}
IOWR_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base, usSectorsPerTrack);
IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base,
(iDevice ? DevHeadRegBitDEV : 0) | (usLogicalHeads - 1));
IDEinterrupt = 0; //ide中断标志付
IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, InitializeDeviceParameters);
/* Wait for INTRQ. */
if (awaitINTRQ(5000))
{
printf("timeout awaiting INTRQ=1 in initializeDeviceParameters()\r");
printf("error register: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
printf("status register: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base));
return -1;
}
usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
if (usStatus & StatusRegBitERR)
{
usError = IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base);
printf("Error? status: 0x%X; error: 0x%X\r", usStatus, usError);
}
else
{
if (IDE_getVerbosity())
{
printf("successfully wrote default parameters to IDE drive.\n"); //顺利写入默认参数到ide设备
}
}
return 0;
}
//===-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=--=-=-=-=-解析识别设备缓存=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=--=-=-=-=-==-=-===-==-=-=-=-=-=-=-=-//
/*
* parseIdentifyDeviceBuffer()//解析识别设备缓存
*
* Parse read IDE device parameters & store them in relevant variables. Also
* displays a handy print-out of information about the attached device, in
* verbose mode.解析读ide设备参数或者存储他们在相应的变量中,同时,显示一个附上设备的易得的信息,用详细的方式
*/
void parseIdentifyDeviceBuffer(unsigned short *pusBuffer)
{
int i;
char *p;
p = gModel;
for (i = 27; i <= 46; ++i)
{
*p++ = (char) (pusBuffer[i] >> 8);
*p++ = (char) (pusBuffer[i] & 0xFF);
}
if (gbVerbose) //@@@#!#!#!#!#!#@#$!@#$@#$@#$@#$@#$@#$@#$@#$ 冗余参数
{
#if IDE_DEBUG
printf("buffer: \n");
for (i = 0; i < 256; ++i)
{
printf("%d: 0x%x\n", i, pusBuffer[i]);
}
#endif
printf("serial number: "); //序列号
for (i = 10; i < 20; ++i)
{
printf("%c%c", pusBuffer[i] >> 8, pusBuffer[i] & 0xFF);
}
printf("\n");
printf("firmware revision: ");//固件修订本
for (i = 23; i < 27; ++i)
{
printf("%c%c", pusBuffer[i] >> 8, pusBuffer[i] & 0xFF);
}
printf("\n");
printf("model number: %s\n", gModel); //模式
}
if(((0x2<<8) & pusBuffer[49] ) != 0) //lba模式支持 49字:功能 第九位被设置为1,说明支持lba模式
{
gusLBAmode = 1;
gulLBAcapacity = pusBuffer[60] + (pusBuffer[61]<<16); //磁盘的容量
}
if((0x2 & pusBuffer[64] ) != 0) //
{
gusPIOmode = 4;
}
else if ((0x01 & pusBuffer[64] ) != 0) //高级pio模式支持
{
gusPIOmode = 3;
}
else
{
gusPIOmode = pusBuffer[51] >> 8;
}
if (gusPIOmode > 4)
{
gusPIOmode = 0;
}
gusLogicalCylinders = pusBuffer[1]; //获得设备真正的柱面
gusLogicalHeads = pusBuffer[3]; //磁头数
gusSectorsPerTrack = pusBuffer[6]; //扇区数
if (gbVerbose)
{
printf("LBA mode %ssupported\n", gusLBAmode ? "" : "not ");
printf("PIO mode supported: %d\n", gusPIOmode);
printf("device parameters:\n");
printf(
" # logical cylinders: %d\n"
" # logical heads: %d\n"
" # logical sectors/track: %d\n",
gusLogicalCylinders, gusLogicalHeads, gusSectorsPerTrack);
if(gusLBAmode)
{
printf(" LBA capacity = %u sectors\n", (unsigned int)gulLBAcapacity);
}
}
}
//=======================IDE_identifyDevice() ==============================================================================================//
/*
* IDE_identifyDevice()
*
* Attempt to identify parameters for the specified IDE device.//尝试识别特定的ide设备参数
*/
int IDE_identifyDevice(unsigned int uiDeviceNumber)
{
int i;
unsigned short usStatus, usBuffer[256];//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -