blob: f6abb7b89d910974334a1dce3f98739b11af93e7 [file] [log] [blame]
#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