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)
88 uprint("%s/ctl", d->path);
89 c = namec(up->genbuf, Aopen, OWRITE, 0);
91 print("sdaoectl: %s\n", up->errstr);
95 devtab[c->type]->write(c, s, strlen(s), 0);
100 /* must call with d qlocked */
102 aoeidentify(Ctlr *d, SDunit *u)
106 uprint("%s/ident", d->path);
107 c = namec(up->genbuf, Aopen, OREAD, 0);
109 iprint("aoeidentify: %s\n", up->errstr);
113 devtab[c->type]->read(c, d->ident, sizeof d->ident, 0);
118 identify(d, (ushort*)d->ident);
120 memset(u->inquiry, 0, sizeof u->inquiry);
123 u->inquiry[4] = sizeof u->inquiry - 4;
124 memmove(u->inquiry+8, d->model, 40);
130 ctlrlookup(char *path)
135 for(c = head; c != nil; c = c->next)
136 if(strcmp(c->path, path) == 0)
150 if((c = malloc(sizeof *c)) == nil)
152 kstrcpy(c->path, path, sizeof c->path);
170 for(prev = 0, x = head; x != nil; prev = x, x = c->next)
171 if(strcmp(c->path, x->path) == 0)
179 prev->next = x->next;
192 aoeprobe(char *path, SDev *s)
199 if((p = strrchr(path, '/')) == nil)
202 uprint("%s/ctl", path);
204 c = namec(up->genbuf, Aopen, OWRITE, 0);
209 n = uprint("discover %s", p+1);
210 devtab[c->type]->write(c, up->genbuf, n, 0);
214 for(i = 0;; i += Probeintvl){
215 if(i > Probemax || waserror())
217 tsleep(&up->sleep, return0, 0, Probeintvl);
220 uprint("%s/ident", path);
223 c = namec(up->genbuf, Aopen, OREAD, 0);
227 ctlr = newctlr(path);
231 if(s == nil && (s = malloc(sizeof *s)) == nil)
239 static char *probef[32];
240 static char *probebuf;
250 if((p = getconf("aoedev")) == nil)
252 kstrdup(&probebuf, p);
253 nprobe = tokenize(probebuf, probef, nelem(probef));
255 for(i = 0; i < nprobe; i++){
265 * shorthand for: id!lun -> id!#æ/aoe/lun
266 * because we cannot type æ in the bootloader console.
268 if(strchr(p, '/') == nil){
271 snprint(tmp, sizeof(tmp), "%c!#æ/aoe/%s", (char)id, p);
274 kstrdup(&probef[i], tmp);
276 s = malloc(sizeof *s);
308 for(j = 0;; j += Probeintvl){
310 print("#æ: pnpprobe: %s: %s\n", probef[i-1], up->errstr);
314 tsleep(&up->sleep, return0, 0, Probeintvl);
317 sd = aoeprobe(p, sd);
321 print("#æ: pnpprobe establishes %s in %dms\n", probef[i-1], j);
322 aoectl(sd->ctlr, "nofail on");
335 if(c == nil && (s->ctlr = c = pnpprobe(s)) == nil)
342 aoeconnect(SDunit *u, Ctlr *c)
350 aoeidentify(u->dev->ctlr, u);
354 uprint("%s/data", c->path);
355 c->c = namec(up->genbuf, Aopen, ORDWR, 0);
371 if((c->feat&Datapi) && c->drivechange){
372 if(aoeconnect(u, c) == 0 && (r = scsionline(u)) > 0)
378 if(aoeconnect(u, c) == -1)
382 u->sectors = c->sectors;
383 u->secsize = Aoesectsz;
391 aoebio(SDunit *u, int, int write, void *a, long count, uvlong lba)
395 long (*rio)(Chan*, void*, long, vlong);
399 // if(c->feat & Datapi)
400 // return scsibio(u, lun, write, a, count, lba);
403 rio = devtab[c->c->type]->write;
405 rio = devtab[c->c->type]->read;
408 if(strcmp(up->errstr, Echange) == 0 ||
409 strcmp(up->errstr, Enotup) == 0)
413 n = rio(c->c, data, Aoesectsz * count, Aoesectsz * lba);
434 // if(c->feat & Datapi)
435 // return aoeriopkt(r, d);
437 if(r->cmd[0] == 0x35 || r->cmd[0] == 0x91){
442 return sdsetsense(r, SDok, 0, 0, 0);
443 return sdsetsense(r, SDcheck, 3, 0xc, 2);
446 if((i = sdfakescsi(r)) != SDnostatus){
450 if((i = sdfakescsirw(r, &lba, &count, &rw)) != SDnostatus)
452 r->rlen = aoebio(u, r->lun, rw == SDwrite, r->data, count, lba);
453 return r->status = SDok;
457 aoerctl(SDunit *u, char *p, int l)
462 if((c = u->dev->ctlr) == nil)
467 p = seprint(p, e, "model\t%s\n", c->model);
468 p = seprint(p, e, "serial\t%s\n", c->serial);
469 p = seprint(p, e, "firm %s\n", c->firmware);
470 p = seprint(p, e, "flag ");
472 p = seprint(p, e, "geometry %llud %d\n", c->sectors, Aoesectsz);
477 aoewctl(SDunit *, Cmdbuf *cmd)
479 cmderror(cmd, Ebadarg);
484 aoeprobew(DevConf *c)
488 p = strchr(c->type, '/');
489 if(p == nil || strlen(p) > Maxpath - 11)
495 return aoeprobe(p, 0);
501 delctlr((Ctlr *)s->ctlr);
505 aoertopctl(SDev *s, char *p, char *e)
510 return seprint(p, e, "%s aoe %s\n", s->name, c? c->path: "");
514 aoewtopctl(SDev *, Cmdbuf *cmd)
518 cmderror(cmd, Ebadarg);
538 aoeprobew, /* probe */
539 aoeclear, /* clear */