OSDev.org

The Place to Start for Operating System Developers
It is currently Sat Apr 27, 2024 5:56 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 31 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: ATA driver problem
PostPosted: Tue Dec 27, 2022 3:47 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 94
Octocontrabass wrote:
You have to send a command that involves a data transfer before the drive will set DRQ.

Okay I send the IDENTIFY command and what command I should send or that enough?


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Tue Dec 27, 2022 3:55 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
That should be enough.

Check the other registers for the ATAPI signature. You might be dealing with an ATAPI drive that doesn't follow ATA correctly.


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Wed Dec 28, 2022 11:57 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 94
So my problem is that my driver trying to send command to drive that still reseting after soft reset command, so my question is how I can correctly wait for the reset using only the disk IO ports or I must use the system sleep functions?


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Wed Dec 28, 2022 12:32 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
The status register will tell you when the drive is done resetting and ready to accept commands.


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Fri Dec 30, 2022 12:52 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 94
How I can identify hard drive in SATA IDE mode? My drive with my driver returns me device fault and error code is 0xff


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Fri Dec 30, 2022 1:07 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
Identifying a SATA drive on an IDE controller works the same as any other ATA drive on an IDE controller.

What is the value of the status register? The device fault bit only applies when the busy bit is clear.


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Fri Dec 30, 2022 1:22 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 94
Octocontrabass wrote:
What is the value of the status register?

0x7f


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Fri Dec 30, 2022 1:37 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
That combination of status and error register values means there's no drive present.


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Sun Feb 04, 2024 12:24 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 94
So, hello again! I have some problems with reading the sectors, my driver is getting the base register address and ctrl register address from PCI as descripted in the wiki, when i run this code on bochs, virtualbox or qemu the code successfully read the sectors, but when i runed it on the real hardware i got strange behaivor, the register reports successfully sector reading, but the drive actually doesn't do that(the disk active led doesn't power on and only 0xff transfered from the port). On bochs also i got continiosly interrupt 0x27. Here is my read code:
Code:
static void ata_vdev_readBlock(vfs_node_t *node,int blockNo,int how, void *buf) {
        ata_device_t *dev = node->device;
        if (dev->type == IDE_ATAPI) {
                kprintf("Currently doesn't supported!\n");
                return;
        }
       //outb(dev->base+ATA_REG_CONTROL,2);
      kprintf("ata: read: dev ctrl: 0x%x\n",dev->base);
        void *dd = buf;
        int doCopy = false;
        uint64_t lba = blockNo;
        uint16_t sectors = how/512;
        if (sectors == 0) {
                sectors = 1;
                buf = kmalloc(512);
                doCopy = 1;
        }
        kprintf("Read %d sectors at %d\r\n",sectors,lba);
        if (sectors == 0) sectors = 1;
        outb(dev->base+ATA_REG_HDDEVSEL,0x40);
        ata_io_wait(dev);
        outportb(dev->base + ATA_REG_SECCOUNT0, 0);
       outportb(dev->base + ATA_REG_LBA0, (lba & 0xff000000) >> 24);
       outportb(dev->base + ATA_REG_LBA1, (lba & 0xff00000000) >> 32);
       outportb(dev->base + ATA_REG_LBA2, (lba & 0xff0000000000) >> 40);

       outportb(dev->base + ATA_REG_SECCOUNT0, sectors);
       outportb(dev->base + ATA_REG_LBA0, (lba & 0x000000ff) >>  0);
       outportb(dev->base + ATA_REG_LBA1, (lba & 0x0000ff00) >>  8);
       outportb(dev->base + ATA_REG_LBA2, (lba & 0x00ff0000) >> 16);
        outb(dev->base+ATA_REG_COMMAND,ATA_CMD_READ_PIO_EXT); // ATA_CMD_READ_PIO_EXT
        ata_io_wait(dev);
   //kprintf("ata: command setted\n");
   //kprintf("ata: interrupts disabled\n");
        uint8_t i;
        // convert buffer
        uint8_t *bu = (uint8_t *)buf;
        //arch_sti();
   //kprintf("going to read loop\n");
        for (i = 0; i < sectors; i++) {
                while(1) {
                        uint8_t status = inb(dev->base+ATA_REG_STATUS);
         //kprintf("Waiting untill drive remove the ATA_SR_DRQ\n");
                        if (status & ATA_SR_DRQ) {
                                // Disk is ready to transfer data
                                break;
                        } else if (status & ATA_SR_ERR) {
                                kprintf("ATA: Disk error. Cancel\n");
                                return;
                        }
                }
      //kprintf("ata: sector readed\n");
                insw(dev->base,bu,256);
                bu+=256;
        }
   //kprintf("ata: sectors readed\n");
        if (doCopy) {
                memcpy(dd,buf,how);
                kfree(buf);
        }
   //kprintf("ata: goodbay\n");
}


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Sun Feb 04, 2024 5:36 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
WinExperements wrote:
On bochs also i got continiosly interrupt 0x27.

Which devices are connected to that interrupt?

WinExperements wrote:
Code:
        outb(dev->base+ATA_REG_COMMAND,ATA_CMD_READ_PIO_EXT); // ATA_CMD_READ_PIO_EXT

Drives smaller than about 128GB often don't support 48-bit LBA.

WinExperements wrote:
Code:
                        uint8_t status = inb(dev->base+ATA_REG_STATUS);
         //kprintf("Waiting untill drive remove the ATA_SR_DRQ\n");
                        if (status & ATA_SR_DRQ) {

If BSY is set, none of the other bits in the status register are valid. You must wait until BSY is clear before trying to interpret the other bits. You should use interrupts instead of polling the status register.


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Tue Apr 09, 2024 11:28 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 94
Hello again! So i have problem sending ATA Identify command to drive.
When i send the command the drive, the drive is raise the IRQ, i read the status register to indicate for the drive that we handle the interrupt, but drive won't stop send there IRQs. I receive infinite count of interrupts from ATA when send the Identify command even if i readed the data from data port.
Also i noticed that the bug occurs if i boot system in Legacy Mode or when i boot it on Legacy BIOS machine.
On virtual machines such as VirtualBox,QEMU all works fine. On Bochs i also got infinite amount of interrupts from ATA, but debug messages are empty.
What i did wrong?
Here is my drive detect code:
Code:
bool ata_device_init(ata_device_t *dev,bool second) {
    arch_sti();
    ata_soft_reset(dev);
    ata_io_wait(dev);
    int bit = (second ? 0xB0 : 0xA0);
    outb(dev->base+ATA_REG_HDDEVSEL, bit | dev->slave << 4);
    ata_io_wait(dev);
    outb(dev->base+ATA_REG_SECCOUNT0,0);
    outb(dev->base+ATA_REG_LBA0,0);
    outb(dev->base+ATA_REG_LBA1,0);
    outb(dev->base+ATA_REG_LBA2,0);
    // Send drive identify command
    inter_ata = dev;
    dev->ident = 1;
    kprintf("ATA: sending command\r\n");
    outb(dev->base+ATA_REG_COMMAND,ATA_CMD_IDENTIFY);
    if (!inb(dev->base + ATA_REG_STATUS)) {
       kprintf("ATA: no drive\r\n");
       return false;
   }
    uint8_t lba1 = inb(dev->base+ATA_REG_LBA1);
    uint8_t lba2 = inb(dev->base+ATA_REG_LBA2);
    if (lba1 != 0 || lba2 != 0) {
       kprintf("Not ATA device\r\n");
       return false;
   }
    kprintf("Waiting until DRQ or ERR to be setted\r\n");
    uint8_t drq,err = 0;
    while(!drq && !err) {
      if (dev->ident == 0) break;
      //kprintf("DRQ: %d ERR: %d. STATUS: %d\r\n",drq,err,inb(dev->base+ATA_REG_STATUS));
       drq = inb(dev->base + ATA_REG_STATUS) & ATA_SR_DRQ;
       err = inb(dev->base + ATA_REG_STATUS) & ATA_SR_ERR;
   }
    if (err) {
       kprintf("ATA: Drive error!\r\n");
       return false;
   }
    kprintf("ATA: Reading using PIO mode\r\n");
    if (dev->ident) {
       kprintf("ATA: No IRQ rised to read\r\n");

  //  kprintf("The device is ready and doesn't reported any errors, reading the identify structure...");
      uint16_t *buf = (uint16_t *)&dev->identify;
      for (int i = 0; i < 256; i++) {
         buf[i] = inw(dev->base);
      }
   }
     kprintf("readed\n");
   uint8_t *ptr = (uint8_t *)&dev->identify.model;
   for (int i = 0; i < 39; i+=2) {
      uint8_t tmp = ptr[i+1];
      ptr[i+1] = ptr[i];
      ptr[i] = tmp;
   }
   return true;
}

And the IRQ handler code:
Code:
void *ata_irq_handler(void *stack) {
   // ATA specifications
   kprintf("ATA IRQ!\r\n");
   inb(inter_ata->base+ATA_REG_STATUS);
   if (inter_ata->ident) {
      uint16_t *data = (uint16_t *)&inter_ata->identify;
      for (int i = 0; i < 256; i++) {
         data[i] = inw(inter_ata->base);
      }
      kprintf("Device identify readed!\r\n");
   inter_ata->ident = 0;
   }
       //inb(inter_ata->base+ATA_REG_STATUS);
   if (inter_ata->busy) {
      inter_ata->busy = 0;
   }
    outb(inter_ata->bar4+4,0x00);
    /*kprintf("ATA IRQ handler!\n");
    kprintf("Status of drive(after sending there commands): 0x%x\n",inb(inter_ata->base+ATA_REG_STATUS));
    kprintf("Error register: 0x%x\n",inb(inter_ata->base+ATA_REG_ERROR));*/
    return stack;
}


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Tue Apr 09, 2024 7:53 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
WinExperements wrote:
Code:
    int bit = (second ? 0xB0 : 0xA0);
    outb(dev->base+ATA_REG_HDDEVSEL, bit | dev->slave << 4);

Why do you have two different methods to set bit 4?

WinExperements wrote:
Code:
    outb(dev->base+ATA_REG_COMMAND,ATA_CMD_IDENTIFY);
    if (!inb(dev->base + ATA_REG_STATUS)) {

This is a race condition. If you need to check the drive's status while you're waiting for an interrupt, use the alternate status register.

WinExperements wrote:
Code:
    uint8_t lba1 = inb(dev->base+ATA_REG_LBA1);
    uint8_t lba2 = inb(dev->base+ATA_REG_LBA2);

You can't read these registers while the drive is busy, and the drive is probably going to be busy if you just sent a command.

WinExperements wrote:
Code:
       drq = inb(dev->base + ATA_REG_STATUS) & ATA_SR_DRQ;
       err = inb(dev->base + ATA_REG_STATUS) & ATA_SR_ERR;

Again, you need to use the alternate status register to prevent a race condition. You must check the status of the BSY bit before trying to interpret other bits in the status register. You don't need to read the status register twice to read two bits.

WinExperements wrote:
Code:
      uint16_t *buf = (uint16_t *)&dev->identify;
      for (int i = 0; i < 256; i++) {
         buf[i] = inw(dev->base);

You have code to read the buffer twice.

WinExperements wrote:
Code:
   inb(inter_ata->base+ATA_REG_STATUS);

You shouldn't discard the value of the status register. It's probably fine if you're just testing, though.

WinExperements wrote:
Code:
      uint16_t *data = (uint16_t *)&inter_ata->identify;
      for (int i = 0; i < 256; i++) {
         data[i] = inw(inter_ata->base);

You have code to read the buffer twice.

WinExperements wrote:
Code:
    outb(inter_ata->bar4+4,0x00);

Which register is this supposed to be? You don't need to touch any DMA registers when you're doing a PIO transfer.


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Wed Apr 10, 2024 1:49 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 94
So, i rewrited the device init code using the Wiki code, but as soon as i enable the device interrupts using the ATA_REG_CONTROL and issue the ATA DMA read command i start to receiving endless count of interrupts from IDE controller.
Here is my new version of device init code:
Code:
bool ata_device_init(ata_device_t *dev,int id) {
   unsigned char err = 0,status;
   ide_write(dev,ATA_REG_CONTROL,2);
   ide_write(dev,ATA_REG_HDDEVSEL,0xA0 | (id << 4));
   ata_io_wait(dev);
   ide_write(dev,ATA_REG_COMMAND,ATA_CMD_IDENTIFY);
   ata_io_wait(dev);
   if (ide_read(dev,ATA_REG_STATUS) == 0) return false;
   kprintf("Waiting device to clear BSY state...");
   while(1) {
      status = ide_read(dev,ATA_REG_STATUS);
      if ((status & ATA_SR_ERR)) {
         // Looks like, we send wrong command?
         uint8_t t1 = ide_read(dev,ATA_REG_LBA1);
         uint8_t t2 = ide_read(dev,ATA_REG_LBA2);
         if (t1 == 0x14 && t2 == 0xEB) {
            // fault caused by WRONG command.
            kprintf("ATAPI device fault(normal,ignore)\r\n");
            dev->type = IDE_ATAPI;
            break;
         } else {
            kprintf("First device fault received 0x%x 0x%x\r\n",t1,t2);
            return false;
         }
      }
      if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ)) break;
   }
   kprintf("cleared\r\n");
   if (dev->type == IDE_ATAPI) {
      // Selected by first fault handler.
      goto atapiDetect;
   }
   uint8_t ch = ide_read(dev,ATA_REG_LBA1);
   uint8_t cl = ide_read(dev,ATA_REG_LBA2);
   if (cl == 0x14 && ch == 0xEB) {
atapiDetect:
      kprintf("ATAPI device detected!\r\n");
      dev->type = IDE_ATAPI;
      ide_write(dev,ATA_REG_COMMAND,ATA_CMD_IDENTIFY_PACKET);
      ata_io_wait(dev);
      // Repeat process
      while(1) {
         status = ide_read(dev,ATA_REG_STATUS);
         if ((status & ATA_SR_ERR)) {
            kprintf("Device fault fallback!\r\n");
            return false;
         }
         if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ)) break;
      }
   } else if (cl == 0x69 && ch == 0x96) {
      kprintf("ATA device!\r\n");
   } else if (cl == 0x0 && ch == 0) {
      kprintf("We skiped something?!\r\n");
   } else {
      kprintf("Unknown type\r\n");
      return false;
   }
   uint16_t *identf = (uint16_t *)&dev->identify;
   for (int i = 0; i < 256; i++) {
      identf[i] = inw(dev->base);
   }
   kprintf("readed\n");
   uint8_t *ptr = (uint8_t *)&dev->identify.model;
   for (int i = 0; i < 39; i+=2) {
      uint8_t tmp = ptr[i+1];
      ptr[i+1] = ptr[i];
      ptr[i] = tmp;
   }
   kprintf("ATA: Detected device name: %s, type: %s\r\n",dev->identify.model,dev->type == IDE_ATAPI ? "ATAPI" : "IDE");
   ata_create_device(dev->type == IDE_ATA,dev);
   dev->type = IDE_ATA;
   return true;
}

The DMA reading code itself:
Code:
static void ata_vdev_readBlock(vfs_node_t *node,int blockNo,int how, void *buf) {
        ata_device_t *dev = node->device;
        if (dev->type == IDE_ATAPI) {
                kprintf("Currently doesn't supported!\n");
                return;
        }
        void *dd = buf;
        int doCopy = false;
        uint64_t lba = blockNo;
        uint16_t sectors = how/512;
        //kprintf("Read %d sectors at %d\r\n",sectors,lba);
        if (sectors == 0) sectors = 1;
   if (sectors > 255) {
      kprintf("ATA: Maximum count of sectors that able to read per one command is 255!\n");
      sectors = 254;
   }
   if (blockNo == 0) {
      goto readActual;
   }
   kprintf("%s: called\r\n",__func__);
   // Before issusing real READ DMA command, check if we don't readed the sectors previously
readActual:
   ide_write(dev,ATA_REG_CONTROL,0);
   kprintf("%s: actual reading begin\r\n",__func__);
   // DMA support!
   outb(dev->bar4,0x00);
   outl(dev->bar4 + 0x04, dev->dma_prdt_phys);
   outb(dev->bar4 + 0x2, inb(dev->bar4 + 0x02) | 0x04 | 0x02);
   outb(dev->bar4, 0x08);
   while (1) {
      uint8_t status = inb(dev->base + ATA_REG_STATUS);
      if (!(status & ATA_SR_BSY)) break;
   }
   int cache_sectors = sectors;
        outb(dev->base+ATA_REG_HDDEVSEL,0x40);
        ata_io_wait(dev);
        outb(dev->base + ATA_REG_FEATURES, 0x01);
        outb(dev->base+ATA_REG_SECCOUNT0,(cache_sectors >> 8) & 0xFF);
   outb(dev->base+ATA_REG_LBA0, (lba & 0xff000000) >> 24);
   outb(dev->base+ATA_REG_LBA1, (lba & 0xff000000) >> 32);
   outb(dev->base+ATA_REG_LBA2, (lba & 0xff000000) >> 48);
   outb(dev->base+ATA_REG_SECCOUNT0,cache_sectors & 0xFF);
   outb(dev->base+ATA_REG_LBA0,lba & 0xFF);
   outb(dev->base+ATA_REG_LBA1,(lba >> 8) & 0xFF);
   outb(dev->base+ATA_REG_LBA2,(lba >> 16) & 0xFF);
        uint8_t i;
        // convert buffer
        uint8_t *bu = (uint8_t *)buf;
        while (1) {
      uint8_t status = inb(dev->base + ATA_REG_STATUS);
      if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break;
   }
   outb(dev->base + ATA_REG_COMMAND, ATA_CMD_READ_DMA_EXT);
   ata_io_wait(dev);

   outb(dev->bar4, 0x08 | 0x01);
   inter_ata->busy = 1;
   arch_sti();
   /*while (1) {
      int status = inb(dev->bar4 + 0x02);
      int dstatus = inb(dev->base + ATA_REG_STATUS);
      if (!(status & 0x04)) {
         continue;
      }
      if (!(dstatus & ATA_SR_BSY)) {
         break;
      }
   }
*/
   while(inter_ata->busy);
   /* Inform device we are done. */
   outb(dev->bar4 + 0x2, inb(dev->bar4 + 0x02) | 0x04 | 0x02);
        if (doCopy) {
                memcpy(dd,buf,how);
                kfree(buf);
        }
   if (sectors > 255) {
      kprintf("ATA: Sectors count are bigger that 0xFF, repeat process\n");
      sectors-=255;
      ata_vdev_readBlock(node,blockNo+255,sectors*512,bu);
   }
   // Dump the PDRT
   if (how > 8192) {
      kprintf("WARRNING: DMA support only 8 sectors :). So we copy only 8 sectors\r\n");
   }
   if (buf == NULL) {
      //kprintf("Zero buffer!!!\r\n");
      dev->latestSector = blockNo;
      return;
   }
   memcpy(bu,dev->dma_start,(how > 8192) ? 8192 : how);
   kprintf("%s: ended\r\n",__func__);
}

Current version of device block reading code is for testing, so for example we don't read the real count of cache sectors.
Also i notice that the bug/problem shows only if system boots in Legacy Mode using the EFI legacy boot or by real legacy BIOS.
EDIT: Rewrite some parts of code like in the wiki, nothing changed.


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Wed Apr 10, 2024 7:16 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
WinExperements wrote:
Code:
      if ((status & ATA_SR_ERR)) {

You must wait for the BSY bit to clear before you try to interpret any other status bits.

WinExperements wrote:
Code:
   } else if (cl == 0x69 && ch == 0x96) {

SATA devices only return SATA-specific signatures after reset, not after an IDENTIFY DEVICE command. This signature indicates a SATA port multiplier.

WinExperements wrote:
Code:
   } else if (cl == 0x0 && ch == 0) {

This signature indicates an IDE disk.

WinExperements wrote:
Code:
      kprintf("ATA: Maximum count of sectors that able to read per one command is 255!\n");

No, the maximum is 65536 with READ DMA EXT (and 256 with READ DMA).

WinExperements wrote:
Code:
   while (1) {
      uint8_t status = inb(dev->base + ATA_REG_STATUS);
      if (!(status & ATA_SR_BSY)) break;
   }

Why are you polling the status register? You should already know whether you're waiting for the drive to finish the last command you sent.

WinExperements wrote:
Code:
        outb(dev->base+ATA_REG_HDDEVSEL,0x40);

I'm sure it makes no difference for READ DMA EXT, but it's a good idea to use 0xE0 instead of 0x40.

WinExperements wrote:
Code:
        outb(dev->base + ATA_REG_FEATURES, 0x01);

READ DMA EXT doesn't use the features register.

WinExperements wrote:
Code:
   outb(dev->base+ATA_REG_LBA1, (lba & 0xff000000) >> 32);
   outb(dev->base+ATA_REG_LBA2, (lba & 0xff000000) >> 48);

These values will always be zero instead of the correct LBA bits.

WinExperements wrote:
Code:
        while (1) {
      uint8_t status = inb(dev->base + ATA_REG_STATUS);
      if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRDY)) break;
   }

Why are you polling the status register again?

WinExperements wrote:
Code:
      kprintf("WARRNING: DMA support only 8 sectors :). So we copy only 8 sectors\r\n");

DMA is not limited to 8 sectors, and 8192 bytes is either 16 sectors or 2 sectors depending on the sector size.

How does your interrupt handler acknowledge the interrupt? I could see you receiving an interrupt storm if that isn't done correctly.


Top
 Profile  
 
 Post subject: Re: ATA driver problem
PostPosted: Thu Apr 11, 2024 9:40 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 94
Octocontrabass wrote:
How does your interrupt handler acknowledge the interrupt? I could see you receiving an interrupt storm if that isn't done correctly.

This is my IDE IRQ handler code:
Code:
void *ata_irq_handler(void *stack) {
   // ATA specifications
   kprintf("ATA IRQ!\r\n");
   inb(inter_ata->base+ATA_REG_STATUS);
       //inb(inter_ata->base+ATA_REG_STATUS);
   if (inter_ata->busy) {
      inter_ata->busy = 0;
   }
    outb(inter_ata->bar4+4,0x00);
    /*kprintf("ATA IRQ handler!\n");
    kprintf("Status of drive(after sending there commands): 0x%x\n",inb(inter_ata->base+ATA_REG_STATUS));
    kprintf("Error register: 0x%x\n",inb(inter_ata->base+ATA_REG_ERROR));*/
    return stack;
}

Currently inter_ata is setted by the ata_vdev_readBlock before writing the command to the command register.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 31 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], eekee and 22 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group