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**