diff options
Diffstat (limited to 'qemu/roms/openbios/drivers/ide.h')
-rw-r--r-- | qemu/roms/openbios/drivers/ide.h | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/qemu/roms/openbios/drivers/ide.h b/qemu/roms/openbios/drivers/ide.h new file mode 100644 index 000000000..d6c4b9f5d --- /dev/null +++ b/qemu/roms/openbios/drivers/ide.h @@ -0,0 +1,213 @@ +#ifndef IDE_H +#define IDE_H + +#include "hdreg.h" + +/* + * legacy ide ports + */ +#define IDEREG_DATA 0x00 +#define IDEREG_ERROR 0x01 +#define IDEREG_FEATURE IDEREG_ERROR +#define IDEREG_NSECTOR 0x02 +#define IDEREG_SECTOR 0x03 +#define IDEREG_LCYL 0x04 +#define IDEREG_HCYL 0x05 +#define IDEREG_CURRENT 0x06 +#define IDEREG_STATUS 0x07 +#define IDEREG_COMMAND IDEREG_STATUS +#define IDEREG_CONTROL 0x08 +#define IDEREG_ASTATUS IDEREG_CONTROL + +/* + * device control bits + */ +#define IDECON_NIEN 0x02 +#define IDECON_SRST 0x04 + +/* + * device head bits + */ +#define IDEHEAD_LBA 0x40 +#define IDEHEAD_DEV0 0x00 +#define IDEHEAD_DEV1 0x10 + +/* + * status bytes + */ +#define ERR_STAT 0x01 +#define DRQ_STAT 0x08 +#define SEEK_STAT 0x10 +#define WRERR_STAT 0x20 +#define READY_STAT 0x40 +#define BUSY_STAT 0x80 + +#define IREASON_CD 0x01 +#define IREASON_IO 0x02 + +/* + * ATA opcodes + */ +#define WIN_READ 0x20 +#define WIN_READ_EXT 0x24 +#define WIN_IDENTIFY 0xEC +#define WIN_PACKET 0xA0 +#define WIN_IDENTIFY_PACKET 0xA1 + +/* + * ATAPI opcodes + */ +#define ATAPI_TUR 0x00 +#define ATAPI_READ_10 0x28 +#define ATAPI_REQ_SENSE 0x03 +#define ATAPI_START_STOP_UNIT 0x1b +#define ATAPI_READ_CAPACITY 0x25 + +/* + * atapi sense keys + */ +#define ATAPI_SENSE_NOT_READY 0x02 + +/* + * supported device types + */ +enum { + ide_type_unknown, + ide_type_ata, + ide_type_atapi, +}; + +enum { + ide_media_floppy = 0x00, + ide_media_cdrom = 0x05, + ide_media_optical = 0x07, + ide_media_disk = 0x20, +}; + +/* + * drive addressing + */ +enum { + ide_chs = 1, + ide_lba28, + ide_lba48, +}; + +/* + * simple ata command that works for everything (except 48-bit lba commands) + */ +struct ata_command { + unsigned char *buffer; + unsigned int buflen; + + /* + * data register + */ + unsigned char data; + unsigned char feature; + unsigned char nsector; + unsigned char sector; + unsigned char lcyl; + unsigned char hcyl; + unsigned char device_head; + unsigned char command; + unsigned char control; + + /* + * or tasklet, just for lba48 for now (above could be scrapped) + */ + unsigned char task[10]; + + /* + * output + */ + unsigned char stat; + unsigned int bytes; +}; + +struct atapi_command { + unsigned char cdb[12]; + unsigned char *buffer; + unsigned int buflen; + unsigned char data_direction; + + unsigned char stat; + unsigned char sense_valid; + struct request_sense sense; + unsigned char old_cdb; +}; + +struct ide_channel; + +struct ide_drive { + char unit; /* 0: master, 1: slave */ + char present; /* there or not */ + char type; /* ata or atapi */ + char media; /* disk, cdrom, etc */ + char addressing; /* chs/lba28/lba48 */ + + char model[41]; /* name */ + int nr; + + unsigned long sectors; + + unsigned int max_sectors; + + /* + * for legacy chs crap + */ + unsigned int cyl; + unsigned int head; + unsigned int sect; + + unsigned int bs; /* block size */ + + struct ide_channel *channel; +}; + +struct ide_channel { + + char name[32]; + struct ide_channel *next; + + /* + * either mmio or io_regs is set to indicate mmio or not + */ + unsigned long mmio; + int io_regs[10]; + + /* + * can be set to a mmio hook, default it legacy outb/inb + */ + void (*obide_outb)(struct ide_channel *chan, + unsigned char addr, unsigned int port); + unsigned char (*obide_inb)(struct ide_channel *chan, + unsigned int port); + void (*obide_insw)(struct ide_channel *chan, + unsigned int port, unsigned char *addr, + unsigned int count); + void (*obide_outsw)(struct ide_channel *chan, + unsigned int port, unsigned char *addr, + unsigned int count); + + struct ide_drive drives[2]; + char selected; + char present; + + /* + * only one can be busy per channel + */ + struct ata_command ata_cmd; + struct atapi_command atapi_cmd; + +}; + +enum { + atapi_ddir_none, + atapi_ddir_read, + atapi_ddir_write, +}; + +static int ob_ide_atapi_request_sense(struct ide_drive *drive); + +#endif |