Implement PIO-mode IDE driver that scans primary and secondary channels for ATA hard drives and ATAPI CD/DVD drives using IDENTIFY commands. Features: - Scans 4 possible devices (2 channels x 2 drives each) - ATA IDENTIFY DEVICE for hard drives - ATAPI IDENTIFY PACKET DEVICE for CD/DVD drives - PIO-mode 28-bit LBA sector read/write for ATA drives - Model string extraction and sector count parsing - Registers as kernel driver via REGISTER_DRIVER macro - Registers devices with devicefs: ATA → hdd class, ATAPI → cd class - Added inw/outw to port_io.h for 16-bit I/O Tested: QEMU detects hdd1 (QEMU HARDDISK) and cd1 (QEMU DVD-ROM).
89 lines
2.9 KiB
C
89 lines
2.9 KiB
C
/**
|
||
* @file ide.h
|
||
* @brief IDE/ATA disk driver.
|
||
*
|
||
* Enumerates IDE devices on the primary and secondary channels, identifies
|
||
* ATA hard drives and ATAPI CD-ROMs, and registers them with the devicefs
|
||
* subsystem as block devices (hddN / cdN).
|
||
*/
|
||
|
||
#ifndef IDE_H
|
||
#define IDE_H
|
||
|
||
#include <stdint.h>
|
||
|
||
/** Maximum number of IDE devices (2 channels × 2 drives). */
|
||
#define IDE_MAX_DEVICES 4
|
||
|
||
/** IDE channel I/O port bases. */
|
||
#define IDE_PRIMARY_IO 0x1F0
|
||
#define IDE_PRIMARY_CTRL 0x3F6
|
||
#define IDE_SECONDARY_IO 0x170
|
||
#define IDE_SECONDARY_CTRL 0x376
|
||
|
||
/** IDE register offsets from I/O base. */
|
||
#define IDE_REG_DATA 0x00
|
||
#define IDE_REG_ERROR 0x01
|
||
#define IDE_REG_FEATURES 0x01
|
||
#define IDE_REG_SECCOUNT 0x02
|
||
#define IDE_REG_LBA_LO 0x03
|
||
#define IDE_REG_LBA_MID 0x04
|
||
#define IDE_REG_LBA_HI 0x05
|
||
#define IDE_REG_DRIVE_HEAD 0x06
|
||
#define IDE_REG_STATUS 0x07
|
||
#define IDE_REG_COMMAND 0x07
|
||
|
||
/** IDE status register bits. */
|
||
#define IDE_STATUS_ERR 0x01 /**< Error occurred. */
|
||
#define IDE_STATUS_DRQ 0x08 /**< Data request ready. */
|
||
#define IDE_STATUS_SRV 0x10 /**< Overlapped mode service request. */
|
||
#define IDE_STATUS_DF 0x20 /**< Drive fault. */
|
||
#define IDE_STATUS_DRDY 0x40 /**< Drive ready. */
|
||
#define IDE_STATUS_BSY 0x80 /**< Drive busy. */
|
||
|
||
/** IDE commands. */
|
||
#define IDE_CMD_IDENTIFY 0xEC /**< ATA IDENTIFY DEVICE. */
|
||
#define IDE_CMD_IDENTIFY_PKT 0xA1 /**< ATAPI IDENTIFY PACKET DEVICE. */
|
||
#define IDE_CMD_READ_PIO 0x20 /**< Read sectors (PIO, 28-bit LBA). */
|
||
#define IDE_CMD_WRITE_PIO 0x30 /**< Write sectors (PIO, 28-bit LBA). */
|
||
|
||
/** IDE device types. */
|
||
#define IDE_TYPE_NONE 0 /**< No device present. */
|
||
#define IDE_TYPE_ATA 1 /**< ATA hard disk. */
|
||
#define IDE_TYPE_ATAPI 2 /**< ATAPI CD/DVD drive. */
|
||
|
||
/**
|
||
* IDE device descriptor.
|
||
*/
|
||
typedef struct ide_device {
|
||
uint8_t present; /**< 1 if device is present. */
|
||
uint8_t type; /**< IDE_TYPE_ATA or IDE_TYPE_ATAPI. */
|
||
uint8_t channel; /**< 0 = primary, 1 = secondary. */
|
||
uint8_t drive; /**< 0 = master, 1 = slave. */
|
||
uint16_t io_base; /**< I/O base port for this channel. */
|
||
uint16_t ctrl_base; /**< Control port for this channel. */
|
||
uint32_t sector_count; /**< Total sectors (28-bit LBA max). */
|
||
uint32_t sector_size; /**< Sector size in bytes (usually 512). */
|
||
char model[41]; /**< Model string from IDENTIFY. */
|
||
} ide_device_t;
|
||
|
||
/**
|
||
* Initialize the IDE driver.
|
||
*
|
||
* Scans primary and secondary channels for ATA/ATAPI devices,
|
||
* reads their IDENTIFY data, and registers them with devicefs.
|
||
*
|
||
* @return Number of devices found.
|
||
*/
|
||
int ide_init(void);
|
||
|
||
/**
|
||
* Get an IDE device by index (0–3).
|
||
*
|
||
* @param index Device index.
|
||
* @return Pointer to the device descriptor, or NULL if invalid/not present.
|
||
*/
|
||
ide_device_t *ide_get_device(int index);
|
||
|
||
#endif /* IDE_H */
|