| #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 { |
| |
| 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 |