1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 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 {
phandle_t ph;
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
|