2 * aoe sd driver, copyright © 2007-9 coraid
6 #include "../port/lib.h"
11 #include "../port/error.h"
12 #include "../port/sd.h"
13 #include "../port/netif.h"
14 #include "../port/aoe.h"
17 extern char Echange[];
20 #define uprint(...) snprint(up->genbuf, sizeof up->genbuf, __VA_ARGS__);
25 Probeintvl = 100, /* ms. between probes */
26 Probemax = 10*1000, /* max ms. to wait */
29 typedef struct Ctlr Ctlr;
57 identify(Ctlr *c, ushort *id)
62 osectors = c->sectors;
63 memmove(oserial, c->serial, sizeof c->serial);
66 uprint("%s: identify fails", c->unit->name);
67 print("%s\n", up->genbuf);
70 idmove(c->serial, id+10, 20);
71 idmove(c->firmware, id+23, 8);
72 idmove(c->model, id+27, 40);
74 if((osectors == 0 || osectors != s) &&
75 memcmp(oserial, c->serial, sizeof oserial) != 0){
84 aoectl(Ctlr *d, char *s)
92 print("sdaoectl: %s\n", up->errstr);
96 uprint("%s/ctl", d->path);
97 c = namec(up->genbuf, Aopen, OWRITE, 0);
98 devtab[c->type]->write(c, s, strlen(s), 0);
104 /* must call with d qlocked */
106 aoeidentify(Ctlr *d, SDunit *u)
114 iprint("aoeidentify: %s\n", up->errstr);
118 uprint("%s/ident", d->path);
119 c = namec(up->genbuf, Aopen, OREAD, 0);
120 devtab[c->type]->read(c, d->ident, sizeof d->ident, 0);
126 identify(d, (ushort*)d->ident);
128 memset(u->inquiry, 0, sizeof u->inquiry);
131 u->inquiry[4] = sizeof u->inquiry - 4;
132 memmove(u->inquiry+8, d->model, 40);
138 ctlrlookup(char *path)
143 for(c = head; c; c = c->next)
144 if(strcmp(c->path, path) == 0)
158 if((c = malloc(sizeof *c)) == nil)
160 kstrcpy(c->path, path, sizeof c->path);
178 for(prev = 0, x = head; x; prev = x, x = c->next)
179 if(strcmp(c->path, x->path) == 0)
187 prev->next = x->next;
200 aoeprobe(char *path, SDev *s)
207 if((p = strrchr(path, '/')) == 0)
210 uprint("%s/ctl", path);
213 c = namec(up->genbuf, Aopen, OWRITE, 0);
218 n = uprint("discover %s", p+1);
219 devtab[c->type]->write(c, up->genbuf, n, 0);
223 for(i = 0;; i += Probeintvl){
224 if(i > Probemax || waserror())
226 tsleep(&up->sleep, return0, 0, Probeintvl);
229 uprint("%s/ident", path);
232 c = namec(up->genbuf, Aopen, OREAD, 0);
236 ctlr = newctlr(path);
240 if(s == nil && (s = malloc(sizeof *s)) == nil)
248 static char *probef[32];
249 static char *probebuf;
272 if((p = getconf("aoedev")) == 0)
274 kstrdup(&probebuf, p);
275 nprobe = tokenize(probebuf, probef, nelem(probef));
277 for(i = 0; i < nprobe; i++){
278 id = pnpprobeid(probef[i]);
281 s = malloc(sizeof *s);
313 for(j = 0;; j += Probeintvl){
315 print("#æ: pnpprobe: %s: %s\n", probef[i-1], up->errstr);
319 tsleep(&up->sleep, return0, 0, Probeintvl);
322 sd = aoeprobe(p, sd);
326 print("#æ: pnpprobe establishes %s in %dms\n", probef[i-1], j);
327 aoectl(sd->ctlr, "nofail on");
340 if(c == nil && (s->ctlr = c = pnpprobe(s)) == nil)
347 aoeconnect(SDunit *u, Ctlr *c)
355 aoeidentify(u->dev->ctlr, u);
359 uprint("%s/data", c->path);
360 c->c = namec(up->genbuf, Aopen, ORDWR, 0);
376 if((c->feat&Datapi) && c->drivechange){
377 if(aoeconnect(u, c) == 0 && (r = scsionline(u)) > 0)
383 if(aoeconnect(u, c) == -1)
387 u->sectors = c->sectors;
388 u->secsize = Aoesectsz;
396 aoebio(SDunit *u, int, int write, void *a, long count, uvlong lba)
400 long (*rio)(Chan*, void*, long, vlong);
404 // if(c->feat & Datapi)
405 // return scsibio(u, lun, write, a, count, lba);
408 rio = devtab[c->c->type]->write;
410 rio = devtab[c->c->type]->read;
413 if(strcmp(up->errstr, Echange) == 0 ||
414 strcmp(up->errstr, Enotup) == 0)
418 n = rio(c->c, data, Aoesectsz * count, Aoesectsz * lba);
439 // if(c->feat & Datapi)
440 // return aoeriopkt(r, d);
442 if(r->cmd[0] == 0x35 || r->cmd[0] == 0x91){
447 return sdsetsense(r, SDok, 0, 0, 0);
448 return sdsetsense(r, SDcheck, 3, 0xc, 2);
451 if((i = sdfakescsi(r)) != SDnostatus){
455 if((i = sdfakescsirw(r, &lba, &count, &rw)) != SDnostatus)
457 r->rlen = aoebio(u, r->lun, rw == SDwrite, r->data, count, lba);
458 return r->status = SDok;
462 aoerctl(SDunit *u, char *p, int l)
467 if((c = u->dev->ctlr) == nil)
472 p = seprint(p, e, "model\t%s\n", c->model);
473 p = seprint(p, e, "serial\t%s\n", c->serial);
474 p = seprint(p, e, "firm %s\n", c->firmware);
475 p = seprint(p, e, "flag ");
477 p = seprint(p, e, "geometry %llud %d\n", c->sectors, Aoesectsz);
482 aoewctl(SDunit *, Cmdbuf *cmd)
484 cmderror(cmd, Ebadarg);
489 aoeprobew(DevConf *c)
493 p = strchr(c->type, '/');
494 if(p == nil || strlen(p) > Maxpath - 11)
500 return aoeprobe(p, 0);
506 delctlr((Ctlr *)s->ctlr);
510 aoertopctl(SDev *s, char *p, char *e)
515 return seprint(p, e, "%s aoe %s\n", s->name, c? c->path: "");
519 aoewtopctl(SDev *, Cmdbuf *cmd)
523 cmderror(cmd, Ebadarg);
543 aoeprobew, /* probe */
544 aoeclear, /* clear */