pub fn pio_identify(&self) -> Result<ATADiskInfo, ATAError> {
        let mut result: [u8; 512] = [0; 512];

        let drive = match self {
            ATADriver::PRIMARY => 0xA0,
            ATADriver::SECONDARY => 0xB0
        };

        outb(self.drive_reg(), drive);
        outb(self.sector_num_reg(), 0);
        outb(self.lba_lo_reg(), 0);
        outb(self.lba_mid_reg(), 0);
        outb(self.lba_hi_reg(), 0);

        outb(self.command_reg(), ATACommand::Identify as u8);

        let mut status = inb(self.status_reg());
        if status == 0 {
            return Err(ATAError::DeviceNotExist)
        }

        while status & (ATAStatus::BSY as u8) != 0 {
            spin_loop();
            status = inb(self.status_reg());
        }

        if inb(self.lba_mid_reg()) | inb(self.lba_hi_reg()) != 0 {
            return Err(ATAError::NotATADevice)
        }

        loop {
            if status & (ATAStatus::ERR as u8) != 0 {
                return Err(ATAError::DiskError(inb(self.error_reg())))
            } else if status & (ATAStatus::DRQ as u8) != 0 {
                self.pio_read_port(self.data_reg(), &mut result);
                return Ok(unsafe { transmute(result) })
            }
            spin_loop();
            status = inb(self.status_reg());
        }
    }
/// To use the IDENTIFY command, select a target drive by sending 0xA0 for the 
/// master drive, or 0xB0 for the slave, to the "drive select" IO port. On the 
/// Primary bus, this would be port 0x1F6. Then set the Sectorcount, LBAlo, 
/// LBAmid, and LBAhi IO ports to 0 (port 0x1F2 to 0x1F5). Then send the IDENTIFY 
/// command (0xEC) to the Command IO port (0x1F7). Then read the Status port 
/// (0x1F7) again. If the value read is 0, the drive does not exist. For any other 
/// value: poll the Status port (0x1F7) until bit 7 (BSY, value = 0x80) clears. 
/// Because of some ATAPI drives that do not follow spec, at this point you need 
/// to check the LBAmid and LBAhi ports (0x1F4 and 0x1F5) to see if they are 
/// non-zero. If so, the drive is not ATA, and you should stop polling. Otherwise, 
/// continue polling one of the Status ports until bit 3 (DRQ, value = 8) sets, 
/// or until bit 0 (ERR, value = 1) sets.
/// At that point, if ERR is clear, the data is ready to read from the Data 
/// port (0x1F0). Read 256 16-bit values, and store them.
To use the IDENTIFY command, select a target drive by sending 0xA0 for the
master drive, or 0xB0 for the slave, to the "drive select" IO port. On the
Primary bus, this would be port 0x1F6. Then set the Sectorcount, LBAlo,
LBAmid, and LBAhi IO ports to 0 (port 0x1F2 to 0x1F5). Then send the IDENTIFY
command (0xEC) to the Command IO port (0x1F7). Then read the Status port
(0x1F7) again. If the value read is 0, the drive does not exist. For any other
value: poll the Status port (0x1F7) until bit 7 (BSY, value = 0x80) clears.
Because of some ATAPI drives that do not follow spec, at this point you need
to check the LBAmid and LBAhi ports (0x1F4 and 0x1F5) to see if they are
non-zero. If so, the drive is not ATA, and you should stop polling. Otherwise,
continue polling one of the Status ports until bit 3 (DRQ, value = 8) sets,
or until bit 0 (ERR, value = 1) sets.
At that point, if ERR is clear, the data is ready to read from the Data
port (0x1F0). Read 256 16-bit values, and store them.
To use the IDENTIFY command select a target drive by sending 0xA0 for the master drive or 0xB0 for the slave to the " drive select " IO port . On the Primary bus this would be port 0x1F6 . Then set the Sectorcount LBAlo LBAmid and LBAhi IO ports to 0 ( port 0x1F2 to 0x1F5 ) . Then send the IDENTIFY command ( 0xEC ) to the Command IO port ( 0x1F7 ) . Then read the Status port ( 0x1F7 ) again . If the value read is 0 the drive does not exist . For any other value : poll the Status port ( 0x1F7 ) until bit 7 ( BSY value = 0x80 ) clears . Because of some ATAPI drives that do not follow spec at this point you need to check the LBAmid and LBAhi ports ( 0x1F4 and 0x1F5 ) to see if they are non - zero . If so the drive is not ATA and you should stop polling . Otherwise continue polling one of the Status ports until bit 3 ( DRQ value = 8 ) sets or until bit 0 ( ERR value = 1 ) sets . At that point if ERR is clear the data is ready to read from the Data port ( 0x1F0 ) . Read 256 16 - bit values and store them .
pub fn pio_identify(&self) -> Result<ATADiskInfo, ATAError> {
        let mut result: [u8; 512] = [0; 512];
        let drive = match self {
            ATADriver::PRIMARY => 0xA0,
            ATADriver::SECONDARY => 0xB0
        };
        outb(self.drive_reg(), drive);
        outb(self.sector_num_reg(), 0);
        outb(self.lba_lo_reg(), 0);
        outb(self.lba_mid_reg(), 0);
        outb(self.lba_hi_reg(), 0);
        outb(self.command_reg(), ATACommand::Identify as u8);
        let mut status = inb(self.status_reg());
        if status == 0 {
            return Err(ATAError::DeviceNotExist)
        }
        while status & (ATAStatus::BSY as u8) != 0 {
            spin_loop();
            status = inb(self.status_reg());
        }
        if inb(self.lba_mid_reg()) | inb(self.lba_hi_reg()) != 0 {
            return Err(ATAError::NotATADevice)
        }
        loop {
            if status & (ATAStatus::ERR as u8) != 0 {
                return Err(ATAError::DiskError(inb(self.error_reg())))
            } else if status & (ATAStatus::DRQ as u8) != 0 {
                self.pio_read_port(self.data_reg(), &mut result);
                return Ok(unsafe { transmute(result) })
            }
            spin_loop();
            status = inb(self.status_reg());
        }
    }
pub fn pio_identify ( & self ) -> Result < ATADiskInfo , ATAError > { let mut result : [ u8 ; 512 ] = [ 0 ; 512 ] ; let drive = match self { ATADriver :: PRIMARY => 0xA0 , ATADriver :: SECONDARY => 0xB0 } ; outb ( self . drive_reg ( ) , drive ) ; outb ( self . sector_num_reg ( ) , 0 ) ; outb ( self . lba_lo_reg ( ) , 0 ) ; outb ( self . lba_mid_reg ( ) , 0 ) ; outb ( self . lba_hi_reg ( ) , 0 ) ; outb ( self . command_reg ( ) , ATACommand :: Identify as u8 ) ; let mut status = inb ( self . status_reg ( ) ) ; if status == 0 { return Err ( ATAError :: DeviceNotExist ) } while status & ( ATAStatus :: BSY as u8 ) != 0 { spin_loop ( ) ; status = inb ( self . status_reg ( ) ) ; } if inb ( self . lba_mid_reg ( ) ) | inb ( self . lba_hi_reg ( ) ) != 0 { return Err ( ATAError :: NotATADevice ) } loop { if status & ( ATAStatus :: ERR as u8 ) != 0 { return Err ( ATAError :: DiskError ( inb ( self . error_reg ( ) ) ) ) } else if status & ( ATAStatus :: DRQ as u8 ) != 0 { self . pio_read_port ( self . data_reg ( ) , & mut result ) ; return Ok ( unsafe { transmute ( result ) } ) } spin_loop ( ) ; status = inb ( self . status_reg ( ) ) ; } }
To use the IDENTIFY command, select a target drive by sending 0xA0 for the
master drive, or 0xB0 for the slave, to the "drive select" IO port.
To use the IDENTIFY command select a target drive by sending 0xA0 for the master drive or 0xB0 for the slave to the " drive select " IO port .
&self