I'm trying to write a driver for the hard drive but it seems to load
just 1 sector and that also the same one. I'm using lba mode ( at least
the bit is set to use it!) however i read at some place that i need to
initialize the device first to use in lba mode and another different
version was that the bios does that if drive supports it, which one
should i use?
I'm using Virtual PC for testing and only a single sector is read. Also
no interrupt is generated when data is ready ( i have reset the bit in
interrupt register and the article said it should generate interrupt if
this is done).
Here's the code tell me if i'm right or wrong in the code. Or if
something else is required.
1 more thing can i just first find the Maximun address by using the
identification command and then use lba or do i have to first think in
chs and then convert it into lba? I have done the first option though
but need to know wether i'm correct or not i have calcualted it as
numCylinders*numHeads*numSectorsPerTrack.
void readSectors(unsigned int lbaAddress,short numSectors,void *dest)
{
int i,j;
unsigned short buff[256];
while((inportb(HDD_STATUS_REGISTER) & HDD_BUSY));
kprintf("\n Checked Disk busy status");
outportb(HDD_SECTOR_NUMBER_REGISTER,lbaAddress & 0xff );
outportb(HDD_SECTOR_COUNT_REGISTER,numSectors);
outportb(HDD_CYLINDER_HIGH_REGISTER,(lbaAddress>>16) & 0xff );
outportb(HDD_CYLINDER_LOW_REGISTER,(lbaAddress>>8) & 0xff );
outportb(HDD_HEAD_REGISTER, 0xE0 | ((lbaAddress>>24) & 0x0f) );
outportb(HDD_CONTROL_REGISTER,COMMAND_READ_SECTOR);
for(i=0;i<numSectors;i++)
{
/*This is because i want to be able to read multiple sectors
and interrupts aren't working cuz of some reason*/
while(!(inportb(HDD_STATUS_REGISTER)& HDD_DATA_READY));
for(j=0;j<sizeof(buff);j++)
buff[i]=inport(HDD_DATA_REGISTER);
memcpy(dest+(i*sizeof(buff)),buff,sizeof(buff));
}
}
I tried (comments below), but I don't see anything "wrong" at the moment.
But, my familiarity with this is very low.
> 1 more thing can i just first find the Maximun address by using the
> identification command and then use lba or do i have to first think in
> chs and then convert it into lba? I have done the first option though
> but need to know wether i'm correct or not i have calcualted it as
>
> numCylinders*numHeads*numSectorsPerTrack.
>
I think LBA from CHS is (in C):
LBA=((cylinder*heads_per_cylinder+head)*sectors_per_track+sector-1;
using your notation (assuming numHeads is numHeadsPerCylinder):
lbaAddress=((cylinder*numHeads+head)*numSectorsPerTrack+sector-1;
You can check against Hale Landis' webpages and code:
http://www.ata-atapi.com/
> void readSectors(unsigned int lbaAddress,short numSectors,void *dest)
> {
> int i,j;
> unsigned short buff[256];
> while((inportb(HDD_STATUS_REGISTER) & HDD_BUSY));
0x1f7, 0x__ ? (or appropriate values for device...)
> kprintf("\n Checked Disk busy status");
>
> outportb(HDD_SECTOR_NUMBER_REGISTER,lbaAddress & 0xff );
0x1f3 ?
> outportb(HDD_SECTOR_COUNT_REGISTER,numSectors);
0x1f2 ?
> outportb(HDD_CYLINDER_HIGH_REGISTER,(lbaAddress>>16) & 0xff );
0x1f5 ?
> outportb(HDD_CYLINDER_LOW_REGISTER,(lbaAddress>>8) & 0xff );
0x1f4 ?
> outportb(HDD_HEAD_REGISTER, 0xE0 | ((lbaAddress>>24) & 0x0f) );
0x1f6 ? (good: &0x0f...)
hardcoded to device 0 primary (no slave support...bit4, good: LBA bit and
obsolete CHS 0xA0 is set...)
>
> outportb(HDD_CONTROL_REGISTER,COMMAND_READ_SECTOR);
0x1f7, 0x20 ? (20h is supported by ATA1,2,3,6,7, others have limited
support-see list below)
>
>
> for(i=0;i<numSectors;i++)
> {
> /*This is because i want to be able to read multiple sectors
> and interrupts aren't working cuz of some reason*/
> while(!(inportb(HDD_STATUS_REGISTER)& HDD_DATA_READY));
0x1f7, 0x__ ?
Can you setup and try real hardware?
>
> for(j=0;j<sizeof(buff);j++)
> buff[i]=inport(HDD_DATA_REGISTER);
0x1f0 ?
>
> memcpy(dest+(i*sizeof(buff)),buff,sizeof(buff));
> }
> }
>
I wish I could help more, since I need to do disk routines for my OS, but
they've been low priority for a while due to other serious issues...
You should be able to pickup working drafts of the version 1,2,3,6,7
ATA/ATAPI specs. I haven't found 4,5... I'd recommend 3 and 7. 7 is
current, and 3 appears to be last CHS (but I don't know about 4,5). 6,7
obsoleted many of the commands in 1,2,3. So, I'd definately review which
commands are still valid. Search for:
"Information technology - AT Attachment Interface for Disk Drives"
"Information technology - AT Attachment Interface with Extensions (ATA-2)"
"Information technology - AT Attachment-3 Interface (ATA-3)"
"Information technology - AT Attachment Interface with Packet Interface
(ATA/ATAPI 6)"
"Information technology - AT Attachment Interface with Packet Interface - 7"
I compiled this command summary. The columns should lineup with a fixed
width font, i.e., use notepad, MS-DOS edit, Linux VI, etc...
00h NOP ATA1, ATA2, ATA3, ATA6,
ATA7
03h CFA REQUEST EXTENDED ERROR ----, ----, ----, ATA6,
ATA7
08h ATAPI SOFT RESET/DEVICE RESET ----, ----, ATA3, ATA6,
ATA7
10h RECALIBRATE ATA1, ATA2,
ATA3, ----, ----
20h READ SECTORS w/retry ATA1, ATA2, ATA3, ATA6,
ATA7
21h READ SECTORS w/o retry ATA1, ATA2,
ATA3, ----, ----
22h READ LONG w/retry ATA1, ATA2,
ATA3, ----, ----
23h READ LONG w/o retry ATA1, ATA2,
ATA3, ----, ----
24h READ SECTORS EXT ----, ----, ----, ATA6,
ATA7
25h READ DMA EXT ----, ----, ----, ATA6,
ATA7
26h READ DMA QUEUED EXT ----, ----, ----, ATA6,
ATA7
27h READ NATIVE MAX ADDRESS EXT ----, ----, ----, ATA6,
ATA7
29h READ MULTIPLE EXT ----, ----, ----, ATA6,
ATA7
2Ah READ STREAM DMA EXT ----, ----, ----, ----,
ATA7
2Bh READ STREAM EXT ----, ----, ----, ----,
ATA7
2Fh READ LOG EXT ----, ----, ----, ATA6,
ATA7
30h WRITE SECTORS w/retry ATA1, ATA2, ATA3, ATA6,
ATA7
31h WRITE SECTORS w/o retry ATA1, ATA2,
ATA3, ----, ----
32h WRITE LONG w/retry ATA1, ATA2,
ATA3, ----, ----
33h WRITE LONG w/o retry ATA1, ATA2,
ATA3, ----, ----
34h WRITE SECTORS EXT ----, ----, ----, ATA6,
ATA7
35h WRITE DMA EXT ----, ----, ----, ATA6,
ATA7
36h WRITE DMA QUEUED EXT ----, ----, ----, ATA6,
ATA7
37h SET MAX ADDRESS EXT ----, ----, ----, ATA6,
ATA7
38h CFA WRITE SECTORS WITHOUT ERASE ----, ----, ----, ATA6,
ATA7
39h WRITE MULTIPLE EXT ----, ----, ----, ATA6,
ATA7
3Ah WRITE STREAM DMA EXT ----, ----, ----, ----,
ATA7
3Bh WRITE STREAM EXT ----, ----, ----, ----,
ATA7
3Ch WRITE VERIFY ATA1, ATA2,
ATA3, ----, ----
3Dh WRITE DMA FUA EXT ----, ----, ----, ----,
ATA7
3Eh WRITE DMA QUEUED FUA EXT ----, ----, ----, ----,
ATA7
3Fh WRITE LOG EXT ----, ----, ----, ATA6,
ATA7
40h READ VERIFY SECTORS w/retry ATA1, ATA2, ATA3, ATA6,
ATA7
41h READ VERIFY SECTORS w/o retry ATA1, ATA2,
ATA3, ----, ----
42h READ VERIFY SECTORS EXT ----, ----, ----, ATA6,
ATA7
50h FORMAT TRACK ATA1, ATA2,
ATA3, ----, ----
51h CONFIGURE STREAM ----, ----, ----, ----,
ATA7
70h SEEK ATA1, ATA2, ATA3
,ATA6, ----
87h CFA TRANSLATE SECTOR ----, ----, ----, ATA6,
ATA7
90h EXECUTED DEVICE DIAGNOSTIC ATA1, ATA2, ATA3, ATA6,
ATA7
91h INITIALIZE DEVICE PARAMETERS ATA1, ATA2,
ATA3, ----, ----
92h DOWNLOAD MICROCODE ----, ATA2, ATA3, ATA6,
ATA7
94h STANDBY IMMEDIATE ATA1, ATA2,
ATA3, ----, ----
95h IDLE IMMEDIATE ATA1, ATA2,
ATA3, ----, ----
96h STANBY ATA1, ATA2,
ATA3, ----, ----
97h IDLE ATA1, ATA2,
ATA3, ----, ----
98h CHECK POWER MODE ATA1, ATA2,
ATA3, ----, ----
99h SLEEP ATA1, ATA2,
ATA3, ----, ----
A0h ATAPI PACKET/PACKET ATA3, ATA6,
ATA7, ----, ----
A1h ATAPI IDENTIFY DEVICE/IDENTIFY PACKET DEVICE ----, ----, ATA3, ATA6,
ATA7
A2h ATAPI SERVICE/SERVICE ----, ----, ATA3, ATA6,
ATA7
B0h SMART ----, ----,
ATA3, ----, ----
B0h SMART DISABLE OPERATIONS ----, ----, ----, ATA6,
ATA7
B0h SMART ENABLE/DISABLE AUTOSAVE ----, ----, ----, ATA6,
ATA7
B0h SMART ENABLE OPERATIONS ----, ----, ----, ATA6,
ATA7
B0h SMART EXECUTE OFF-LINE IMMEDIATE ----, ----, ----, ATA6,
ATA7
B0h SMART READ DATA ----, ----, ----, ATA6,
ATA7
B0h SMART READ LOG SECTOR ----, ----, ----, ATA6,
ATA7
B0h SMART RETURN STATUS ----, ----, ----, ATA6,
ATA7
B0h SMART WRITE LOG ----, ----, ----, ATA6,
ATA7
B1h DEVICE CONFIGURATION FREEZE LOCK ----, ----, ----, ATA6,
ATA7
B1h DEVICE CONFIGURATION IDENTIFY ----, ----, ----, ATA6,
ATA7
B1h DEVICE CONFIGURATION RESTORE ----, ----, ----, ATA6,
ATA7
B1h DEVICE CONFIGURATION SET ----, ----, ----, ATA6,
ATA7
C0h CFA ERASE SECTORS ----, ----, ----, ATA6,
ATA7
C4h READ MULTIPLE ATA1, ATA2, ATA3, ATA6,
ATA7
C5h WRITE MULTIPLE ATA1, ATA2, ATA3, ATA6,
ATA7
C6h SET MULTIPLE MODE ATA1, ATA2, ATA3, ATA6,
ATA7
C7h READ DMA QUEUED ----, ----, ----, ATA6,
ATA7
C8h READ DMA w/retry ATA1, ATA2, ATA3, ATA6,
ATA7
C9h READ DMA w/o retry ATA1, ATA2,
ATA3, ----, ----
CAh WRITE DMA w/retry ATA1, ATA2, ATA3, ATA6,
ATA7
CBh WRITE DMA w/o retry ATA1, ATA2,
ATA3, ----, ----
CCh WRITE DMA QUEUED ----, ----, ----, ATA6,
ATA7
CDh CFA WRITE MULTIPLE WITHOUT ERASE ----, ----, ----, ATA6,
ATA7
CEh WRITE MULTIPLE FUA EXT ----, ----, ----, ----,
ATA7
D1h CHECK MEDIA CARD TYPE ----, ----, ----, ATA6,
ATA7
DAh GET MEDIA STATUS ----, ----, ----, ATA6,
ATA7
DBh ACKNOWLEDGE MEDIA CHANGE ATA1,
ATA2, ----, ----, ----
DCh BOOT - POST-BOOT ATA1,
ATA2, ----, ----, ----
DDh BOOT - PRE-BOOT ATA1,
ATA2, ----, ----, ----
DEh DOOR LOCK/MEDIA LOCK ATA1, ATA2, ATA3, ATA6,
ATA7
DFh DOOR UNLOCK/MEDIA UNLOCK ATA1, ATA2, ATA3, ATA6,
ATA7
E0h STANDBY IMMEDIATE ATA1, ATA2, ATA3, ATA6,
ATA7
E1h IDLE IMMEDIATE ATA1, ATA2, ATA3, ATA6,
ATA7
E2h STANDBY ATA1, ATA2, ATA3, ATA6,
ATA7
E3h IDLE ATA1, ATA2, ATA3, ATA6,
ATA7
E4h READ BUFFER ATA1, ATA2, ATA3, ATA6,
ATA7
E5h CHECK POWER MODE ATA1, ATA2, ATA3, ATA6,
ATA7
E6h SLEEP ATA1, ATA2, ATA3, ATA6,
ATA7
E8h WRITE BUFFER ATA1, ATA2, ATA3, ATA6,
ATA7
E9h WRITE SAME ATA1,
ATA2, ----, ----, ----
EAh FLUSH CACHE EXT ----, ----, ----, ATA6,
ATA7
ECh IDENTIFY DEVICE ATA1, ATA2, ATA3, ATA6,
ATA7
EDh MEDIA EJECT ----, ATA2, ATA3, ATA6,
ATA7
EEh IDENTIFY DEVICE DMA ----, ----,
ATA3, ----, ----
EFh SET FEATURES ATA1, ATA2, ATA3, ATA6,
ATA7
F1h SECURITY SET PASSWORD ----, ----, ATA3, ATA6,
ATA7
F2h SECURITY UNLOCK ----, ----, ATA3, ATA6,
ATA7
F3h SECURITY ERASE PREPARE ----, ----, ATA3, ATA6,
ATA7
F4h SECURITY ERASE UNIT ----, ----, ATA3, ATA6,
ATA7
F5h SECURITY FREEZE/SECURITY FREEZE LOCK ----, ----, ATA3, ATA6,
ATA7
F6h SECURITY DISABLE PASSWORD ----, ----, ATA3, ATA6,
ATA7
F8h READ NATIVE MAX ADDRESS ----, ----, ----, ATA6,
ATA7
F9h SET MAX ADDRESS ----, ----, ----, ATA6,
ATA7
HTH,
Rod Pemberton
i have no idea what i'm talking about...
isn't it necessary to clear some flags when an interrupt occurs? perhaps
the harddisk waits for some ack after it fired the interrupt...
regards,
simon
--
----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Reading the Status register clears the interrupt condition.
THAT's A Big LIST! I dunno if i will be able to check every error. i
have a doc file written by tilman reh, its an articel published in
some magazine.
I'm using the values given in that doc file as:
1F0 Data Register Data Register
1F1 Error Register (Write Precomp Reg.)
1F2 Sector Count Sector Count
1F3 Sector Number Sector Number
1F4 Cylinder Low Cylinder Low
1F5 Cylinder High Cylinder High
1F6 SDH Register SDH Register
1F7 Status Register Command Register
3F6 Alternate Status Digital Output
3F7 Drive Address Not Used
Real hardware i dont think is possible at this time cuz i messed up my
spare hard drive couple of days ago ( it had cool movies and videos :-(
). and i dont want to mess up with my current hard drive unless i'm
sure of what i'm doing. So u have the values now, is the code correct?
and what modifications does it need
ATA/ATAPI-5 "working draft" rev 3 of 29 Feb 2000 is on Seagate's web
site: http://www.seagate.com/support/disc/manuals/ata/d1153r17.pdf
ATA/ATAPI-4 "working draft" rev18 of 19 Aug 1998 is on t13.org:
http://www.t13.org/project/d1153r18-ATA-ATAPI-4.pdf
>
> ...
> Rod Pemberton