19 typedef struct Atatab Atatab;
27 [Nop] 0x00, Pnd|P28, "nop",
28 [Idall] 0xff, Pin|Ppio|P28, "identify * device",
29 [Idpkt] 0xa1, Pin|Ppio|P28, "identify packet device",
30 [Smart] 0xb0, Pnd|P28, "smart",
31 [Id] 0xec, Pin|Ppio|P28, "identify device",
32 [Sig] 0xf000, Pnd|P28, "signature",
35 typedef struct Rcmd Rcmd;
37 uchar sdcmd; /* sd command; 0xff means ata passthrough */
38 uchar ataproto; /* ata protocol. non-data, pio, reset, dd, etc. */
42 typedef struct Req Req;
52 issueata(Req *r, Sdisk *d, int errok)
57 if((rv = write(d->fd, &r->cmd, Cmdsz)) != Cmdsz){
58 /* handle non-atazz compatable kernels */
59 rerrstr(buf, sizeof buf);
60 if(rv != -1 || strstr(buf, "bad arg in system call") != 0)
61 eprint(d, "fis write error: %r\n");
66 switch(r->cmd.ataproto & Pdatam){
68 ok = read(d->fd, "", 0) == 0;
71 ok = read(d->fd, r->data, r->count) == r->count;
74 ok = write(d->fd, r->data, r->count) == r->count;
79 rerrstr(buf, sizeof buf);
80 if(!errok && strstr(buf, "not sata") == 0)
81 eprint(d, "xfer error: %.2ux%.2ux: %r\n", r->cmd.fis[0], r->cmd.fis[2]);
84 if(read(d->fd, &r->reply, Replysz) != Replysz){
86 eprint(d, "status fis read error: %r\n");
94 issueatat(Req *r, int i, Sdisk *d, int e)
102 r->cmd.ataproto = a->protocol;
110 return issueata(r, d, e);
119 memset(&r, 0, sizeof r);
120 if(issueatat(&r, Sig, d, 1) == -1)
122 setfissig(d, fistosig(r.reply.fis));
123 memset(&r, 0, sizeof r);
125 identifyfis(d, r.cmd.fis);
126 if((rv = issueatat(&r, Idall, d, 1)) != -1){
127 idfeat(d, (ushort*)r.data);
128 if((d->feat & Dsmart) == 0)
135 smartfis(Sfis *f, uchar *c, int n)
137 if((f->feat & Dsmart) == 0)
141 c[3] = 0xd8 + n; /* able smart */
153 memset(&r, 0, sizeof r);
154 smartfis(d, r.cmd.fis, 0);
155 rv = issueatat(&r, Smart, d, 0);
160 smartrsfis(Sfis*, uchar *c)
164 c[3] = 0xda; /* return smart status */
170 atastatus(Sdisk *d, char *s, int l)
176 memset(&r, 0, sizeof r);
177 smartrsfis(d, r.cmd.fis);
178 rv = issueatat(&r, Smart, d, 0);
184 snprint(s, l, "normal");
186 snprint(s, l, "threshold exceeded");
190 snprint(s, l, "smart error");