Why READ sectors don't work after IDENTIFY.

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

Why READ sectors don't work after IDENTIFY.

Post 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?
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

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

Post by Chandra »

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 !
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

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

Post by bluemoon »

For a "It doesn't work" Question, you probably would get "There is something wrong" answer :lol:
Igor1024
Member
Member
Posts: 32
Joined: Mon Apr 11, 2011 12:19 am

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

Post by Igor1024 »

What do you try to connect? Floppy? Hard drive?
pranjas
Member
Member
Posts: 25
Joined: Sun Jan 16, 2011 9:18 pm

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

Post 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.
cptpingu
Posts: 5
Joined: Sat Feb 05, 2011 3:58 am

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

Post 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.
pranjas
Member
Member
Posts: 25
Joined: Sun Jan 16, 2011 9:18 pm

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

Post by pranjas »

So you mean bochs got a problem? I'll try it on qemu now just to be sure.
cptpingu
Posts: 5
Joined: Sat Feb 05, 2011 3:58 am

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

Post by cptpingu »

I only get the problem on real hardware. Vmware works fine. Not tried bochs or qemu.
Post Reply