Struggling with IDE driver (PIO with interrupts enabled)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
pranjas
Member
Member
Posts: 25
Joined: Sun Jan 16, 2011 9:18 pm

Struggling with IDE driver (PIO with interrupts enabled)

Post by pranjas »

Hi

I'm struggling with writing an IDE driver. Tried everything but this thing just doesn't work. I'm using bochs, Please see what the hell i'm doing wrong... this is very frustrating i'm stuck on this.

#defines

Code: Select all

#define PRIMARY_DATA_PORT			0x1F0
#define PRIMARY_ERROR_PORT			PRIMARY_DATA_PORT+1
#define PRIMARY_SECTOR_COUNT_PORT		PRIMARY_DATA_PORT+2 /*Number of sectors to read/write*/
#define PRIMARY_SECTOR_LBA_LOW_PORT			PRIMARY_DATA_PORT+3 /*LBA28/CHS/LBA48 specific.*/
#define PRIMARY_CYLLOW_LBA_MID_PORT		PRIMARY_DATA_PORT+4 /*Either Cylinder low for CHS or LBA mid bits*/
#define PRIMARY_CYLHIGH_LBA_HIGH_PORT		PRIMARY_DATA_PORT+5 /*High bits for cylinder/lba address*/
#define PRIMARY_DRIVE_SELECT_PORT		PRIMARY_DATA_PORT+6 /*drive/head select*/
#define PRIMARY_COMMAND_PORT			PRIMARY_DATA_PORT+7 /*May also be used to read in status*/
#define PRIMARY_STATUS_PORT			0x3F6		   /*Will read Alternate status register instead.Good for us.*/


#define PRIMARY_STATUS_ERROR			        (1<<0)
#define PRIMARY_STATUS_DATA_READY		(1<<3)
#define PRIMARY_STATUS_MODE_SRV			1<<4 /*Don't really know what this is*/
#define PRIMARY_STATUS_DRIVE_FAULT		1<<5
#define PRIMARY_STATUS_DRIVE_READY		1<<6
#define PRIMARY_STATUS_DRIVE_BUSY		        (1<<7)

#define PRIMARY_COMMAND_INTR_ENABLE		1<<1/*Disable interrupts when set*/
#define PRIMARY_COMMAND_SOFT_RST		1<<2/*Software reset, helpful if device hangs*/
#define PRIMARY_COMMAND_HOB			1<<7/*Read the last High order byte sent to device in LBA48*/
The read_sectors function, cmd is the command variable, first_block is the address of the first block.

Code: Select all


int read_sectors (struct dev_geo* dev,unsigned int first_block,unsigned char howmany,void *buffer)
{
	cmd.lba_address=first_block;
	cmd.count=howmany;
	cmd.buffer=buffer;
unsigned short* buff=(unsigned short*)cmd.buffer;
	unsigned char drive_select=0xa0;
	if(IS_BIT_SET(dev->drive_mode,5))
	{
		drive_select=0xf0;
	}

	volatile unsigned char status;
	drive_select|=(unsigned char)(first_block>>24 & 0x0f);
	printk("drive is %x\n",drive_select);
	
	/*while( !(inb(PRIMARY_COMMAND_PORT) & PRIMARY_STATUS_DRIVE_READY))
			;
		outb(PRIMARY_DRIVE_SELECT_PORT,COMMAND_IDENTIFY_MASTER_DRIVE); Primary, for slave use F0*/

read_again:
	while( !(inb(PRIMARY_STATUS_PORT) & PRIMARY_STATUS_DRIVE_READY))
		;
	outb(PRIMARY_DRIVE_SELECT_PORT,drive_select);
	outb(PRIMARY_SECTOR_COUNT_PORT,howmany);
	outb(PRIMARY_SECTOR_LBA_LOW_PORT,(unsigned char)first_block);
	outb(PRIMARY_CYLLOW_LBA_MID_PORT,(unsigned char)(first_block>>8 & 0xff));
	outb(PRIMARY_CYLHIGH_LBA_HIGH_PORT,(unsigned char)(first_block>>16 &0xff));


//	printk("%s, %x\n",__FUNCTION__,inb(PRIMARY_STATUS_PORT));
	outb(PRIMARY_COMMAND_PORT,COMMAND_READ_SECTORS);
	int buff_index=0;
	while( cmd.count>0);

return howmany;
The following is my ISR, this is being called by an assembly generic ISR handler. This doesn't have any IRET cuz after this ISR handler is over, the control moves back in assembler code which generates the IRET for both primary and slave. So no problem regarding IRET for sure.

Code: Select all

void disk_handler(PushRegisters *reg)
{

if(!(inb(PRIMARY_STATUS_PORT) & PRIMARY_STATUS_DATA_READY)){
	printk("[1]%s ,%x\n",__FUNCTION__,inb(PRIMARY_COMMAND_PORT));
	return;}

printk("[2]%s %x\n",__FUNCTION__,inb(PRIMARY_COMMAND_PORT));
unsigned short* buff=(unsigned short*)cmd.buffer;
//printk("reading sectors[PKS]\n");
int j=0;
for(;j<256;j++)
{
	buff[256*cmd.sectors_served+j]=ins(PRIMARY_DATA_PORT);
}
cmd.count--;
cmd.sectors_served++;
//printk("done\n");
inb(PRIMARY_COMMAND_PORT);
printk("%s %x\n",__FUNCTION__,inb(PRIMARY_COMMAND_PORT));
}
The function disk_handler returns early and the status port value i get is 0x51. I'm not sure about the error nor is command aborted so idk what the error is. Please help or let me see any of your code which is working so i can test on bochs if it works.

This is driving me into desperation, would do anything for correct code!
pranjas
Member
Member
Posts: 25
Joined: Sun Jan 16, 2011 9:18 pm

Re: Struggling with IDE driver (PIO with interrupts enabled)

Post by pranjas »

Does anyone have a working IDE driver code which I can use? I'm not able to get this working. :cry: :cry: :cry:
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Struggling with IDE driver (PIO with interrupts enabled)

Post by gerryg400 »

Code: Select all

for(;j<256;j++)
{
   buff[256*cmd.sectors_served+j]=ins(PRIMARY_DATA_PORT);
}
What does the 'ins' function do in this piece of code ? Does it do an INS ? I wonder why you're not doing a inw. Is this related to your problem ?
If a trainstation is where trains stop, what is a workstation ?
pranjas
Member
Member
Posts: 25
Joined: Sun Jan 16, 2011 9:18 pm

Re: Struggling with IDE driver (PIO with interrupts enabled)

Post by pranjas »

ins is for inshort its a C wrapper for inw. And nope that's not a problem.

Well' I've given up on doing interrupt based disk i/o. So now doing PIO only and even that is giving me problem now. I'm not able to read 1 sector but able to read multiple sectors, no idea what's going on. Again using bochs only.
Post Reply