enum {
Cmdn = 1,
Cmdf, /* cfa only */
Cmdp, /* packet */
Cmd5sc, /* 512-byte sector size, set sector count */
};
typedef struct Dev Dev;
struct Dev {
Sfis;
int fd;
uint secsize;
uvlong nsect;
uvlong wwn;
};
enum {
Cmdsz = 18,
Replysz = 18,
};
typedef struct Rcmd Rcmd;
struct Rcmd {
uchar sdcmd; /* sd command; 0xff means ata passthrough */
uchar ataproto; /* ata protocol. non-data, pio, reset, dd, etc. */
uchar fis[Fissize];
};
typedef struct Req Req;
struct Req {
int rfd;
int wfd;
uchar fmtrw;
uvlong lba;
uvlong count; /* bytes; allow long sectors to work */
uint nsect;
char haverfis;
uint fisbits; /* bitmask of manually set fields */
Rcmd cmd;
Rcmd reply;
uchar *data;
uchar raw;
};
void sigfmt(Req*);
void idfmt(Req*);
void iofmt(Req*);
void sdfmt(Req*);
void smfmt(Req*);
void slfmt(Req*);
void glfmt(Req*);
typedef struct Btab Btab;
struct Btab {
int bit;
char *name;
};
char *sebtab(char*, char*, Btab*, int, uint);
typedef struct Txtab Txtab;
typedef struct Fetab Fetab;
struct Txtab {
int val;
char *name;
Fetab *fe;
};
struct Fetab {
int reg;
Txtab *tab;
int ntab;
};
/* sct “registers” */
enum {
Sbase = 1<<5,
Sbyte = 0<<6,
Sw = 1<<6,
Sdw = 2<<6,
Sqw = 3<<6,
Ssz = 3<<6,
Saction = 0 | Sbase | Sw,
Sfn = 1 | Sbase | Sw,
Slba = 2 | Sbase | Sqw,
Scnt = 6 | Sbase | Sqw,
Spat = 10 | Sbase | Sdw,
Ssc = 2 | Sbase | Sw,
Stimer = 3 | Sbase | Sw,
Sfe = 2 | Sbase | Sw,
Sstate = 3 | Sbase | Sw,
Soptf = 4 | Sbase | Sw,
Stabid = 2 | Sbase | Sw,
Pbase = 1<<6,
};
void pw(uchar*, ushort);
void pdw(uchar*, uint);
void pqw(uchar*, uvlong);
ushort w(uchar*);
uint dw(uchar*);
uvlong qw(uchar*);
/*
* botch. integrate with fis.h?
*/
enum {
Psct = 1<<6 + 8,
};
typedef struct Atatab Atatab;
struct Atatab {
ushort cc;
uchar flags;
uchar pktflags;
ushort protocol;
Fetab *tab;
void (*fmt)(Req*);
char *name;
};
int eprint(char *, ...);
int opendev(char*, Dev*);
int probe(void);
extern int squelch;
#pragma varargck argpos eprint 1
#pragma varargck type "π" char**
|