I was trying to read sectors after doing an IDENTIFY command.
Identify command works.. i get all information.
Now when i try to read sectors it doesn't work. There's no interrupt and DRQ isn't set, infact whole status is zero always.
If i don't issue IDENTIFY then it works any ideas why?
Why READ sectors don't work after IDENTIFY.
Re: Why READ sectors don't work after IDENTIFY.
Could you please post your source code?
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
Re: Why READ sectors don't work after IDENTIFY.
For a "It doesn't work" Question, you probably would get "There is something wrong" answer
Re: Why READ sectors don't work after IDENTIFY.
What do you try to connect? Floppy? Hard drive?
Re: Why READ sectors don't work after IDENTIFY.
Here is the source code
If i try read_sectors without doing IDENTIFY command, it works like a charm. But if i do Identify I just get the interrupt fired only once. I've tried everything I can but this just doesn't seem to work.
To be able to issue read multiple sectors i'll need to know how many multiple sectors at a time are supported so that's why i was trying IDENTIFY command. Plus i would need to know if it supports 48 bit LBA or not and the maximum addressable LBA value in either 48/28 bit mode.
Thank you for your help.
Code: Select all
int get_drive_param(unsigned int dev_type,unsigned int bus,struct dev_geo * dev_geo_p)
{
if(dev_type==SECONDARY_BUS) return -1;
if(dev_geo_p == NULL) return -1;
/*Send IDENTIFY COMMAND dev_type*/
if(dev_type==PRIMARY_BUS)
{
dev_geo_p->heads=0;
dev_geo_p->sectors=0;
dev_geo_p->cylinders=0;
// outb(PRIMARY_DRIVE_SELECT_PORT,0xe0); /*Primary, for slave use F0*/
// outb(PRIMARY_STATUS_PORT,0x06);/*No interrupts*/
//asm volatile("cli;");
while( get_primary_drive_status() & PRIMARY_STATUS_DRIVE_BUSY); //printk("dum\n");
/*select the master drive on primary bus*/
outb(PRIMARY_DRIVE_SELECT_PORT,COMMAND_IDENTIFY_MASTER_DRIVE);
/*set all input parameters to 0 for identify command*/
outb(PRIMARY_SECTOR_COUNT_PORT,0);
outb(PRIMARY_SECTOR_LBA_LOW_PORT,0);
outb(PRIMARY_CYLLOW_LBA_MID_PORT,0);
outb(PRIMARY_CYLHIGH_LBA_HIGH_PORT,0);
/*send the device identify command to port*/
outb(PRIMARY_COMMAND_PORT,COMMAND_IDENTIFY);
if(get_primary_drive_status()!=0)
{
while(get_primary_drive_status() & PRIMARY_STATUS_DATA_READY)/*loop here*/
{
if(inb(PRIMARY_CYLLOW_LBA_MID_PORT) || inb(PRIMARY_CYLHIGH_LBA_HIGH_PORT))
{
return -1; /*NOT ATA drive*/
}
}
unsigned short buff[SECTOR_SIZE/2];
int i=0;
for(i=0;i<SECTOR_SIZE/2;i++)
{
buff[i]=ins(PRIMARY_DATA_PORT);
}
/*printk("buff[83]=%x\n",buff[83]);
printk("buff[49]=%x\n",buff[49]);*/
dev_geo_p->max_sectors=(unsigned char)(buff[47]& 0xff);
dev_geo_p->drive_mode|=(unsigned char)(buff[59] & (1<<8));
/*Currently only setting drive to master but check this later*/
SET_BIT(dev_geo_p->drive_mode,5);
if(IS_BIT_SET(buff[49],9)){/*bit 9 is set if LBA is supported*/
if(IS_BIT_SET(buff[83],10))
{
SET_BIT(dev_geo_p->drive_mode,2);
dev_geo_p->size_48_upper=*((unsigned int*)&buff[100]);
dev_geo_p->size_48_lower=*((unsigned int*)&buff[102]);
}
if(dev_geo_p->size_48==0) /*48 bit can't be used since no addressable logical sectors, but 28LBA is there*/
{
SET_BIT(dev_geo_p->drive_mode,1);
dev_geo_p->size_28=*((unsigned int*)&buff[60]);
}
}
}
}
To be able to issue read multiple sectors i'll need to know how many multiple sectors at a time are supported so that's why i was trying IDENTIFY command. Plus i would need to know if it supports 48 bit LBA or not and the maximum addressable LBA value in either 48/28 bit mode.
Thank you for your help.
Re: Why READ sectors don't work after IDENTIFY.
Having exact same problem.
Done lots of investigation and found this:-
IDENTIFY is not asserting IRQ unless I do two reads of status register afterward.
The following READ SECTOR command doing the same. No interrupt unless I poll until DRQ then read status <twice> and the read generates the interrupt then. kinda pointless!
Anyone got any ideas, works fine with IRQs firing as expected in vmWare though.
Done lots of investigation and found this:-
IDENTIFY is not asserting IRQ unless I do two reads of status register afterward.
The following READ SECTOR command doing the same. No interrupt unless I poll until DRQ then read status <twice> and the read generates the interrupt then. kinda pointless!
Anyone got any ideas, works fine with IRQs firing as expected in vmWare though.
Re: Why READ sectors don't work after IDENTIFY.
So you mean bochs got a problem? I'll try it on qemu now just to be sure.
Re: Why READ sectors don't work after IDENTIFY.
I only get the problem on real hardware. Vmware works fine. Not tried bochs or qemu.