MentOS
0.8.0
The Mentoring Operating System
|
Stores information about an ATA device. More...
Public Attributes | |
char | name [NAME_MAX] |
Name of the device. | |
char | path [PATH_MAX] |
Name of the device. | |
ata_device_type_t | type |
Does the device support ATA Packet Interface (ATAPI). | |
uint16_t | io_base |
The "I/O" port base. | |
struct { | |
uint16_t data | |
[R/W] Data Register. Read/Write PIO data bytes (16-bit). | |
uint16_t error | |
[R ] Error Register. Read error generated by the last ATA command executed (8-bit). | |
uint16_t feature | |
[ W] Features Register. Used to control command specific interface features (8-bit). | |
uint16_t sector_count | |
[R/W] Sector Count Register. Number of sectors to read/write (0 is a special value) (8-bit). | |
uint16_t lba_lo | |
[R/W] Sector Number Register. This is CHS/LBA28/LBA48 specific (8-bit). | |
uint16_t lba_mid | |
[R/W] Cylinder Low Register. Partial Disk Sector address (8-bit). | |
uint16_t lba_hi | |
[R/W] Cylinder High Register. Partial Disk Sector address (8-bit). | |
uint16_t hddevsel | |
[R/W] Drive / Head Register. Used to select a drive and/or head. Supports extra address/flag bits (8-bit). | |
uint16_t status | |
[R ] Status Register. Used to read the current status (8-bit). | |
uint16_t command | |
[ W] Command Register. Used to send ATA commands to the device (8-bit). | |
} | io_reg |
I/O registers. | |
uint16_t | io_control |
The "Control" port base. | |
bool_t | primary: 8 |
If the device is connected to the primary bus. | |
bool_t | secondary: 8 |
If the device is connected to the secondary bus. | |
bool_t | master: 8 |
If the device is master. | |
bool_t | slave: 8 |
If the device is slave. | |
ata_identity_t | identity |
The device identity data. | |
struct { | |
unsigned command | |
unsigned status | |
unsigned prdt | |
} | bmr |
struct { | |
prdt_t * prdt | |
Pointer to the first entry of the PRDT. | |
uintptr_t prdt_phys | |
Physical address of the first entry of the PRDT. | |
uint8_t * start | |
Pointer to the DMA memory area. | |
uintptr_t start_phys | |
Physical address of the DMA memory area. | |
} | dma |
Direct Memroy Access (DMA) variables. | |
vfs_file_t * | fs_root |
Device root file. | |
spinlock_t | lock |
For device lock. | |
Stores information about an ATA device.
struct { ... } ata_device_t::bmr |
Bus Master Register. The "address" of the Bus Master Register is stored in BAR4, in the PCI Configuration Space of the disk controller. The Bus Master Register is generally a set of 16 sequential IO ports. It can also be a 16 byte memory mapped space.
unsigned ata_device_t::command |
The command byte has only 2 operational bits. All the rest should be 0. Bit 0 (value = 1) is the Start/Stop bit. Setting the bit puts the controller in DMA mode for that ATA channel, and it starts at the beginning of the respective PRDT. Clearing the bit terminates DMA mode for that ATA channel. If the controller was in the middle of a transfer, the remaining data is thrown away. Also, the controller does not remember how far it got in the PRDT. That information is lost, if the OS does not save it. The bit must be cleared when a transfer completes. Bit 3 (value = 8) is the Read/Write bit. This bit is a huge problem. The disk controller does not automatically detect whether the next disk operation is a read or write. You have to tell it, in advance, by setting this bit. Note that when reading from the disk, you must set this bit to 1, and clear it when writing to the disk. You must first stop DMA transfers (by clearing bit 0) before you can change the Read/Write bit! Please note all the bad consequences of clearing bit 0, above! The controller loses its place in the PRDT. In essence, this means that each PRDT must consist exclusively of either read or write entries. You set the Read/Write bit in advance, then "use up" the entire PRDT – before you can do the opposite operation.
unsigned ata_device_t::prdt |
Physical Region Descriptor Table (PRDT). The PRDT must be uint32_t aligned, contiguous in physical memory, and cannot cross a 64K boundary.
unsigned ata_device_t::status |
The bits in the status byte are not usually useful. However, you are required to read it after every IRQ on disk reads anyway. Reading this byte may perform a necessary final cache flush of the DMA data to memory.