Page 1 of 1

Why READ sectors don't work after IDENTIFY.

Posted: Sun Jun 12, 2011 12:11 am
by pranjas
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?

Re: Why READ sectors don't work after IDENTIFY.

Posted: Sun Jun 12, 2011 12:43 am
by Chandra
Could you please post your source code?

Re: Why READ sectors don't work after IDENTIFY.

Posted: Sun Jun 12, 2011 12:57 am
by bluemoon
For a "It doesn't work" Question, you probably would get "There is something wrong" answer :lol:

Re: Why READ sectors don't work after IDENTIFY.

Posted: Sun Jun 12, 2011 1:25 am
by Igor1024
What do you try to connect? Floppy? Hard drive?

Re: Why READ sectors don't work after IDENTIFY.

Posted: Sun Jun 12, 2011 3:11 am
by pranjas
Here is the source code

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]);
			}
			}
		}
	}

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.

Re: Why READ sectors don't work after IDENTIFY.

Posted: Thu Jun 16, 2011 12:55 pm
by cptpingu
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.

Re: Why READ sectors don't work after IDENTIFY.

Posted: Thu Jun 16, 2011 6:34 pm
by pranjas
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.

Posted: Thu Jun 16, 2011 7:12 pm
by cptpingu
I only get the problem on real hardware. Vmware works fine. Not tried bochs or qemu.