Page 1 of 1

Unable to read sector for atapi device

Posted: Sat Dec 07, 2013 12:38 pm
by dansmahajan
Hi, I am writing a atapi driver to implement iso9660 filesystem but after reading a sector i am unable to read the same sector or any other sector

Code: Select all

void atapi_read_pio(u32int bus, u32int drive, u32int lba, u32int num_lba,u8int *buffer)
{	
	u8int read_pkt[12] = {0,0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0 }; 

	read_pkt[2] = (lba >> 0x18) & 0xFF;   /* most sig. byte of LBA */
    read_pkt[3] = (lba >> 0x10) & 0xFF;
    read_pkt[4] = (lba >> 0x08) & 0xFF;
    read_pkt[5] = (lba >> 0x00) & 0xFF;   /* least sig. byte of LBA */
	
	if(num_lba > 0xFFFF)
	{
		//read12 command
		read_pkt[0] = ATAPI_READ12_CMD;
		read_pkt[6] = (num_lba >> 0x18) & 0xFF;		//msb transfer len
		read_pkt[7] = (num_lba >> 0x10) & 0xFF;
		read_pkt[8] = (num_lba >> 0x08) & 0xFF;
		read_pkt[9] = (num_lba >> 0x00) & 0xFF;		//lsb transfer len
	}
	else
	{
		//read10 command
		read_pkt[0] = ATAPI_READ10_CMD;
		read_pkt[7] = (num_lba >> 0x08) & 0xFF;		//msb transfer len
		read_pkt[8] = (num_lba >> 0x00) & 0xFF;	//lsb transfer len
	}
	
	//atapi pkt req 6 words to be pushed not 12 bytes
	u16int read_pkt_w[6];
	int i,j;
	for(i=0,j=0;i<6;i++,j+=2)
	read_pkt_w[i] = read_pkt[j+1]<<8 | read_pkt[j];
	
	//Selecting up device to be read from
	outportb(ATA_DRIVE_SELECT_PORT(bus),drive);
	outportb(ATA_FEATURES_PORT(bus),0);
		
	outportb (ATA_LBA_MID_PORT(bus), ATAPI_SECTOR_SIZE & 0xFF);
    outportb (ATA_LBA_HI_PORT(bus), ATAPI_SECTOR_SIZE >> 8);
	
	
	//ATATPI PKT cmd
	outportb(ATA_COMMAND_PORT(bus),ATAPI_PKT_CMD);
	
	//waiting for dev to get ready
	while((inportb(ATA_STATUS_PORT(bus)) & ATA_STATUS_REG_BSY)
	&& !(inportb(ATA_STATUS_PORT(bus)) & ATA_STATUS_REG_DRQ) );
	
	//pushing the packet to the data port
	for(i=0;i<6;i++)
		outportw(ATA_DATA_PORT(bus),read_pkt_w[i]);
	
	//IRQ response wait***not implemented
	while((inportb(ATA_STATUS_PORT(bus)) & ATA_STATUS_REG_BSY)
	&& !(inportb(ATA_STATUS_PORT(bus)) & ATA_STATUS_REG_DRQ) );
	if(( inportb(ATA_STATUS_PORT(bus)) & ATA_STATUS_REG_ERR))kprintf("WTF JJJJJJJJ");
	//timer_wait(12);
	//a=true;
	//wait_for_interrupt();
	
	//Actual size that is to transferred
	u32int size =
      (((u32int) inportb (ATA_LBA_HI_PORT (bus))) << 8) | (u32int) (inportb (ATA_LBA_MID_PORT (bus)));
    
    kprintf("\nActual Size to be transferred 0x%x",size);
    
    u16int words = size/2;
    //transferring data
    u16int temp;
    for(i=0,j=0;i<words;i++)
    {
		temp = inportw (ATA_DATA_PORT (bus));
		buffer[j++] = temp & 0xFF;
		buffer[j++] = (temp>>8) & 0xFF;
	}
}
above is the code to read a sector from atapi device

Code: Select all

iso9660_vol_desc_primary *pri;
	
	iso9660_vol_desc *vol_desc = (iso9660_vol_desc *)kmalloc(sizeof(iso9660_vol_desc));
	
	atapi_read_pio(bus, drive, ISO9660_VOL_DESC_START_SECTOR+0, 1,(u8int *)vol_desc);

	pri = (iso9660_vol_desc_primary *)vol_desc;
	
	iso9660_dir_record root_dir = (iso9660_dir_record)&pri->root_dir_entry;
	
	iso9660_dir_table root = (iso9660_dir_table)kmalloc(ISO9660_LOGICAL_SECTOR_SIZE);	//*******
	
	atapi_read_pio(bus, drive, iso9660_dir_record_get_lba(root_dir),1,root);
	
for the first time i can read the sector properly ie i am able to see all the directories and files in the root dir but if i try to read the root dir again or some sub dir only 0xc bytes are transferred

so what am i missing here ??

PS i know IRQ should be used for transfer but interrupt is fired too quickly before the scheduler can queue the process to the driver queue

Re: Unable to read sector for atapi device

Posted: Sun Dec 08, 2013 5:13 am
by Combuster
dansmahajan wrote:PS i know IRQ should be used for transfer but interrupt is fired too quickly before the scheduler can queue the process to the driver queue
Which means you have bigger issues.

Re: Unable to read sector for atapi device

Posted: Sun Dec 08, 2013 6:36 am
by dansmahajan
yeah...but right now i am not concentrating on that
If the problem was related to IRQ then i wouldn't have read the sector in the first place

Re: Unable to read sector for atapi device

Posted: Mon Dec 09, 2013 6:20 am
by dansmahajan
i guess i found a temporary solution...since after reading a sector i was not able to read that sector again so i tried to reset the device and then it worked-was able to read the sector again..

so every time reading a sector i have to reset the device ??? or there is a better way to do it ??