@@ 1,121 0,0 @@
-/*
- * Storage Device.
- */
-typedef struct SDev SDev;
-typedef struct SDifc SDifc;
-typedef struct SDpart SDpart;
-typedef struct SDperm SDperm;
-typedef struct SDreq SDreq;
-typedef struct SDunit SDunit;
-
-typedef struct SDperm {
- char name[NAMELEN];
- char user[NAMELEN];
- ulong perm;
-} SDperm;
-
-typedef struct SDpart {
- ulong start;
- ulong end;
- SDperm;
- int valid;
- ulong vers;
-} SDpart;
-
-typedef struct SDunit {
- SDev* dev;
- int subno;
- uchar inquiry[256]; /* format follows SCSI spec */
- SDperm;
- Rendez rendez;
-
- QLock ctl;
- ulong sectors;
- ulong secsize;
- SDpart* part; /* nil or array of size npart */
- int npart;
- ulong vers;
- SDperm ctlperm;
-
- Lock rawinuse; /* really just a test-and-set */
- int state;
- SDreq* req;
- SDperm rawperm;
-} SDunit;
-
-typedef struct SDev {
- SDifc* ifc; /* pnp/legacy */
- void *ctlr;
- int idno;
- char name[NAMELEN];
- int index; /* into unit space */
- int nunit;
- SDev* next;
-
- QLock; /* enable/disable */
- int enabled;
-} SDev;
-
-typedef struct SDifc {
- char* name;
-
- SDev* (*pnp)(void);
- SDev* (*legacy)(int, int);
- SDev* (*id)(SDev*);
- int (*enable)(SDev*);
- int (*disable)(SDev*);
-
- int (*verify)(SDunit*);
- int (*online)(SDunit*);
- int (*rio)(SDreq*);
- int (*rctl)(SDunit*, char*, int);
- int (*wctl)(SDunit*, Cmdbuf*);
-
- long (*bio)(SDunit*, int, int, void*, long, long);
-} SDifc;
-
-typedef struct SDreq {
- SDunit* unit;
- int lun;
- int write;
- uchar cmd[16];
- int clen;
- void* data;
- int dlen;
-
- int flags;
-
- int status;
- long rlen;
- uchar sense[256];
-} SDreq;
-
-enum {
- SDnosense = 0x00000001,
- SDvalidsense = 0x00010000,
-};
-
-enum {
- SDretry = -5, /* internal to controllers */
- SDmalloc = -4,
- SDeio = -3,
- SDtimeout = -2,
- SDnostatus = -1,
-
- SDok = 0,
-
- SDcheck = 0x02, /* check condition */
- SDbusy = 0x08, /* busy */
-
- SDmaxio = 2048*1024,
- SDnpart = 16,
-};
-
-#define sdmalloc(n) malloc(n)
-#define sdfree(p) free(p)
-
-/* sdscsi.c */
-extern int scsiverify(SDunit*);
-extern int scsionline(SDunit*);
-extern long scsibio(SDunit*, int, int, void*, long, long);
-extern SDev* scsiid(SDev*, SDifc*);
@@ 10,7 10,7 @@
#include "ureg.h"
#include "../port/error.h"
-#include "sd.h"
+#include "../port/sd.h"
extern Dev sddevtab;
extern SDifc* sdifc[];
@@ 34,6 34,7 @@ enum {
Qunitdir, /* directory per unit */
Qunitbase,
Qctl = Qunitbase,
+ Qlog,
Qraw,
Qpart,
};
@@ 229,6 230,10 @@ sdgetunit(SDev* sdev, int subno)
unit->subno = subno;
unit->dev = sdev;
+ unit->log.logmask = ~0;
+ unit->log.nlog = 16*1024;
+ unit->log.minread = 4*1024;
+
/*
* No need to lock anything here as this is only
* called before the unit is made available in the
@@ 334,6 339,15 @@ sd2gen(Chan* c, int i, Dir* dp)
unit = sdunit[UNIT(c->qid)];
switch(i){
+ case Qlog:
+ q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qlog), unit->vers};
+ perm = &unit->rawperm;
+ if(perm->user[0] == '\0'){
+ strncpy(perm->user, eve, NAMELEN);
+ perm->perm = 0666;
+ }
+ devdir(c, q, "log", 0, perm->user, perm->perm, dp);
+ return 1;
case Qctl:
q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qctl), unit->vers};
perm = &unit->ctlperm;
@@ 452,6 466,7 @@ sdgen(Chan* c, Dirtab*, int, int s, Dir* dp)
case Qraw:
case Qctl:
case Qpart:
+ case Qlog:
unit = sdunit[UNIT(c->qid)];
qlock(&unit->ctl);
r = sd2gen(c, TYPE(c->qid), dp);
@@ 525,6 540,10 @@ sdopen(Chan* c, int omode)
switch(TYPE(c->qid)){
default:
break;
+ case Qlog:
+ unit = sdunit[UNIT(c->qid)];
+ logopen(&unit->log);
+ break;
case Qctl:
unit = sdunit[UNIT(c->qid)];
c->qid.vers = unit->vers;
@@ 568,6 587,10 @@ sdclose(Chan* c)
switch(TYPE(c->qid)){
default:
break;
+ case Qlog:
+ unit = sdunit[UNIT(c->qid)];
+ logclose(&unit->log);
+ break;
case Qraw:
unit = sdunit[UNIT(c->qid)];
unlock(&unit->rawinuse);
@@ 634,6 657,26 @@ sdbio(Chan* c, int write, char* a, long len, vlong off)
poperror();
}
+ if(unit->log.opens) {
+ int i;
+ uchar lbuf[1+4+8], *p;
+ ulong x[3];
+
+ p = lbuf;
+ *p++ = write ? 'w' : 'r';
+ x[0] = off>>32;
+ x[1] = off;
+ x[2] = len;
+ for(i=0; i<3; i++) {
+ *p++ = x[i]>>24;
+ *p++ = x[i]>>16;
+ *p++ = x[i]>>8;
+ *p++ = x[i];
+ }
+
+ logn(&unit->log, 1, lbuf, 1+4+8);
+ }
+
b = sdmalloc(nb*unit->secsize);
if(b == nil)
error(Enomem);
@@ 741,6 784,9 @@ sdread(Chan *c, void *a, long n, vlong off)
case Qtopdir:
case Qunitdir:
return devdirread(c, a, n, 0, 0, sdgen);
+ case Qlog:
+ unit = sdunit[UNIT(c->qid)];
+ return logread(&unit->log, a, 0, n);
case Qctl:
unit = sdunit[UNIT(c->qid)];
p = malloc(READSTR);
@@ 777,18 823,26 @@ sdread(Chan *c, void *a, long n, vlong off)
return l;
case Qraw:
unit = sdunit[UNIT(c->qid)];
+ qlock(&unit->raw);
+ if(waserror()){
+ qunlock(&unit->raw);
+ nexterror();
+ }
if(unit->state == Rawdata){
unit->state = Rawstatus;
- return sdrio(unit->req, a, n);
+ i = sdrio(unit->req, a, n);
}
else if(unit->state == Rawstatus){
status = unit->req->status;
unit->state = Rawcmd;
free(unit->req);
unit->req = nil;
- return readnum(0, a, n, status, NUMSIZE);
- }
- break;
+ i = readnum(0, a, n, status, NUMSIZE);
+ } else
+ i = 0;
+ qunlock(&unit->raw);
+ poperror();
+ return i;
case Qpart:
return sdbio(c, 0, a, n, off);
}
@@ 807,6 861,10 @@ sdwrite(Chan *c, void *a, long n, vlong off)
switch(TYPE(c->qid)){
default:
error(Eperm);
+
+ case Qlog:
+ error(Ebadctl);
+
case Qctl:
cb = parsecmd(a, n);
unit = sdunit[UNIT(c->qid)];
@@ 847,6 905,11 @@ sdwrite(Chan *c, void *a, long n, vlong off)
case Qraw:
unit = sdunit[UNIT(c->qid)];
+ qlock(&unit->raw);
+ if(waserror()){
+ qunlock(&unit->raw);
+ nexterror();
+ }
switch(unit->state){
case Rawcmd:
if(n < 6 || n > sizeof(req->cmd))
@@ 875,9 938,12 @@ sdwrite(Chan *c, void *a, long n, vlong off)
unit->state = Rawstatus;
unit->req->write = 1;
- return sdrio(unit->req, a, n);
+ n = sdrio(unit->req, a, n);
}
- break;
+ qunlock(&unit->raw);
+ poperror();
+ return n;
+
case Qpart:
return sdbio(c, 1, a, n, off);
}