13e12c5d1SDavid du Colombier #include "u.h"
23e12c5d1SDavid du Colombier #include "../port/lib.h"
33e12c5d1SDavid du Colombier #include "mem.h"
43e12c5d1SDavid du Colombier #include "dat.h"
53e12c5d1SDavid du Colombier #include "fns.h"
63e12c5d1SDavid du Colombier #include "../port/error.h"
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier extern ulong kerndate;
93e12c5d1SDavid du Colombier
109a747e4fSDavid du Colombier void
mkqid(Qid * q,vlong path,ulong vers,int type)119a747e4fSDavid du Colombier mkqid(Qid *q, vlong path, ulong vers, int type)
129a747e4fSDavid du Colombier {
139a747e4fSDavid du Colombier q->type = type;
149a747e4fSDavid du Colombier q->vers = vers;
159a747e4fSDavid du Colombier q->path = path;
169a747e4fSDavid du Colombier }
179a747e4fSDavid du Colombier
183e12c5d1SDavid du Colombier int
devno(int c,int user)193e12c5d1SDavid du Colombier devno(int c, int user)
203e12c5d1SDavid du Colombier {
21bd389b36SDavid du Colombier int i;
223e12c5d1SDavid du Colombier
237dd7cddfSDavid du Colombier for(i = 0; devtab[i] != nil; i++) {
247dd7cddfSDavid du Colombier if(devtab[i]->dc == c)
25bd389b36SDavid du Colombier return i;
26bd389b36SDavid du Colombier }
277dd7cddfSDavid du Colombier if(user == 0)
28*567483c8SDavid du Colombier panic("devno %C %#ux", c, c);
297dd7cddfSDavid du Colombier
307dd7cddfSDavid du Colombier return -1;
313e12c5d1SDavid du Colombier }
323e12c5d1SDavid du Colombier
333e12c5d1SDavid du Colombier void
devdir(Chan * c,Qid qid,char * n,vlong length,char * user,long perm,Dir * db)347dd7cddfSDavid du Colombier devdir(Chan *c, Qid qid, char *n, vlong length, char *user, long perm, Dir *db)
353e12c5d1SDavid du Colombier {
369a747e4fSDavid du Colombier db->name = n;
379a747e4fSDavid du Colombier if(c->flag&CMSG)
389a747e4fSDavid du Colombier qid.type |= QTMOUNT;
393e12c5d1SDavid du Colombier db->qid = qid;
407dd7cddfSDavid du Colombier db->type = devtab[c->type]->dc;
413e12c5d1SDavid du Colombier db->dev = c->dev;
423e12c5d1SDavid du Colombier db->mode = perm;
439a747e4fSDavid du Colombier db->mode |= qid.type << 24;
443e12c5d1SDavid du Colombier db->atime = seconds();
453e12c5d1SDavid du Colombier db->mtime = kerndate;
463e12c5d1SDavid du Colombier db->length = length;
479a747e4fSDavid du Colombier db->uid = user;
489a747e4fSDavid du Colombier db->gid = eve;
499a747e4fSDavid du Colombier db->muid = user;
503e12c5d1SDavid du Colombier }
513e12c5d1SDavid du Colombier
529a747e4fSDavid du Colombier /*
535e96a66cSDavid du Colombier * (here, Devgen is the prototype; devgen is the function in dev.c.)
545e96a66cSDavid du Colombier *
555e96a66cSDavid du Colombier * a Devgen is expected to return the directory entry for ".."
565e96a66cSDavid du Colombier * if you pass it s==DEVDOTDOT (-1). otherwise...
575e96a66cSDavid du Colombier *
585e96a66cSDavid du Colombier * there are two contradictory rules.
595e96a66cSDavid du Colombier *
605e96a66cSDavid du Colombier * (i) if c is a directory, a Devgen is expected to list its children
615e96a66cSDavid du Colombier * as you iterate s.
625e96a66cSDavid du Colombier *
635e96a66cSDavid du Colombier * (ii) whether or not c is a directory, a Devgen is expected to list
645e96a66cSDavid du Colombier * its siblings as you iterate s.
655e96a66cSDavid du Colombier *
665e96a66cSDavid du Colombier * devgen always returns the list of children in the root
675e96a66cSDavid du Colombier * directory. thus it follows (i) when c is the root and (ii) otherwise.
685e96a66cSDavid du Colombier * many other Devgens follow (i) when c is a directory and (ii) otherwise.
695e96a66cSDavid du Colombier *
705e96a66cSDavid du Colombier * devwalk assumes (i). it knows that devgen breaks (i)
715e96a66cSDavid du Colombier * for children that are themselves directories, and explicitly catches them.
725e96a66cSDavid du Colombier *
735e96a66cSDavid du Colombier * devstat assumes (ii). if the Devgen in question follows (i)
745e96a66cSDavid du Colombier * for this particular c, devstat will not find the necessary info.
755e96a66cSDavid du Colombier * with our particular Devgen functions, this happens only for
765e96a66cSDavid du Colombier * directories, so devstat makes something up, assuming
775e96a66cSDavid du Colombier * c->name, c->qid, eve, DMDIR|0555.
785e96a66cSDavid du Colombier *
795e96a66cSDavid du Colombier * devdirread assumes (i). the callers have to make sure
805e96a66cSDavid du Colombier * that the Devgen satisfies (i) for the chan being read.
815e96a66cSDavid du Colombier */
825e96a66cSDavid du Colombier /*
839a747e4fSDavid du Colombier * the zeroth element of the table MUST be the directory itself for ..
849a747e4fSDavid du Colombier */
853e12c5d1SDavid du Colombier int
devgen(Chan * c,char * name,Dirtab * tab,int ntab,int i,Dir * dp)86fb7f0c93SDavid du Colombier devgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
873e12c5d1SDavid du Colombier {
887dd7cddfSDavid du Colombier if(tab == 0)
897dd7cddfSDavid du Colombier return -1;
90fb7f0c93SDavid du Colombier if(i == DEVDOTDOT){
91fb7f0c93SDavid du Colombier /* nothing */
92fb7f0c93SDavid du Colombier }else if(name){
93fb7f0c93SDavid du Colombier for(i=1; i<ntab; i++)
94fb7f0c93SDavid du Colombier if(strcmp(tab[i].name, name) == 0)
95fb7f0c93SDavid du Colombier break;
96fb7f0c93SDavid du Colombier if(i==ntab)
97fb7f0c93SDavid du Colombier return -1;
98fb7f0c93SDavid du Colombier tab += i;
99fb7f0c93SDavid du Colombier }else{
1009a747e4fSDavid du Colombier /* skip over the first element, that for . itself */
1019a747e4fSDavid du Colombier i++;
1027dd7cddfSDavid du Colombier if(i >= ntab)
1033e12c5d1SDavid du Colombier return -1;
1043e12c5d1SDavid du Colombier tab += i;
1057dd7cddfSDavid du Colombier }
1063e12c5d1SDavid du Colombier devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
1073e12c5d1SDavid du Colombier return 1;
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier
1107dd7cddfSDavid du Colombier void
devreset(void)1117dd7cddfSDavid du Colombier devreset(void)
1127dd7cddfSDavid du Colombier {
1137dd7cddfSDavid du Colombier }
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier void
devinit(void)1167dd7cddfSDavid du Colombier devinit(void)
1177dd7cddfSDavid du Colombier {
1187dd7cddfSDavid du Colombier }
1197dd7cddfSDavid du Colombier
1209a747e4fSDavid du Colombier void
devshutdown(void)1219a747e4fSDavid du Colombier devshutdown(void)
1229a747e4fSDavid du Colombier {
1239a747e4fSDavid du Colombier }
1249a747e4fSDavid du Colombier
1253e12c5d1SDavid du Colombier Chan*
devattach(int tc,char * spec)1263e12c5d1SDavid du Colombier devattach(int tc, char *spec)
1273e12c5d1SDavid du Colombier {
128cdf9e71cSDavid du Colombier int n;
1293e12c5d1SDavid du Colombier Chan *c;
1309a747e4fSDavid du Colombier char *buf;
1313e12c5d1SDavid du Colombier
1323e12c5d1SDavid du Colombier c = newchan();
1339a747e4fSDavid du Colombier mkqid(&c->qid, 0, 0, QTDIR);
1343e12c5d1SDavid du Colombier c->type = devno(tc, 0);
1359a747e4fSDavid du Colombier if(spec == nil)
1369a747e4fSDavid du Colombier spec = "";
137cdf9e71cSDavid du Colombier n = 1+UTFmax+strlen(spec)+1;
138cdf9e71cSDavid du Colombier buf = smalloc(n);
139cdf9e71cSDavid du Colombier snprint(buf, n, "#%C%s", tc, spec);
1404afe124fSDavid du Colombier c->path = newpath(buf);
1419a747e4fSDavid du Colombier free(buf);
1423e12c5d1SDavid du Colombier return c;
1433e12c5d1SDavid du Colombier }
1443e12c5d1SDavid du Colombier
1459a747e4fSDavid du Colombier
1463e12c5d1SDavid du Colombier Chan*
devclone(Chan * c)1479a747e4fSDavid du Colombier devclone(Chan *c)
1483e12c5d1SDavid du Colombier {
1499a747e4fSDavid du Colombier Chan *nc;
1509a747e4fSDavid du Colombier
1513e12c5d1SDavid du Colombier if(c->flag & COPEN)
1527dd7cddfSDavid du Colombier panic("clone of open file type %C\n", devtab[c->type]->dc);
1537dd7cddfSDavid du Colombier
1543e12c5d1SDavid du Colombier nc = newchan();
1557dd7cddfSDavid du Colombier
1563e12c5d1SDavid du Colombier nc->type = c->type;
1573e12c5d1SDavid du Colombier nc->dev = c->dev;
1583e12c5d1SDavid du Colombier nc->mode = c->mode;
1593e12c5d1SDavid du Colombier nc->qid = c->qid;
1603e12c5d1SDavid du Colombier nc->offset = c->offset;
1619a747e4fSDavid du Colombier nc->umh = nil;
1623e12c5d1SDavid du Colombier nc->aux = c->aux;
1633e12c5d1SDavid du Colombier nc->mqid = c->mqid;
1647dd7cddfSDavid du Colombier nc->mcp = c->mcp;
1653e12c5d1SDavid du Colombier return nc;
1663e12c5d1SDavid du Colombier }
1673e12c5d1SDavid du Colombier
1689a747e4fSDavid du Colombier Walkqid*
devwalk(Chan * c,Chan * nc,char ** name,int nname,Dirtab * tab,int ntab,Devgen * gen)1699a747e4fSDavid du Colombier devwalk(Chan *c, Chan *nc, char **name, int nname, Dirtab *tab, int ntab, Devgen *gen)
1703e12c5d1SDavid du Colombier {
1719a747e4fSDavid du Colombier int i, j, alloc;
1729a747e4fSDavid du Colombier Walkqid *wq;
1739a747e4fSDavid du Colombier char *n;
1743e12c5d1SDavid du Colombier Dir dir;
1753e12c5d1SDavid du Colombier
1769a747e4fSDavid du Colombier if(nname > 0)
1773e12c5d1SDavid du Colombier isdir(c);
1789a747e4fSDavid du Colombier
1799a747e4fSDavid du Colombier alloc = 0;
1809a747e4fSDavid du Colombier wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
1819a747e4fSDavid du Colombier if(waserror()){
1829a747e4fSDavid du Colombier if(alloc && wq->clone!=nil)
1839a747e4fSDavid du Colombier cclose(wq->clone);
1849a747e4fSDavid du Colombier free(wq);
1859a747e4fSDavid du Colombier return nil;
1867dd7cddfSDavid du Colombier }
1879a747e4fSDavid du Colombier if(nc == nil){
1889a747e4fSDavid du Colombier nc = devclone(c);
1899a747e4fSDavid du Colombier nc->type = 0; /* device doesn't know about this channel yet */
1909a747e4fSDavid du Colombier alloc = 1;
1919a747e4fSDavid du Colombier }
1929a747e4fSDavid du Colombier wq->clone = nc;
1939a747e4fSDavid du Colombier
1949a747e4fSDavid du Colombier for(j=0; j<nname; j++){
1959a747e4fSDavid du Colombier if(!(nc->qid.type&QTDIR)){
1969a747e4fSDavid du Colombier if(j==0)
1979a747e4fSDavid du Colombier error(Enotdir);
1989a747e4fSDavid du Colombier goto Done;
1999a747e4fSDavid du Colombier }
2009a747e4fSDavid du Colombier n = name[j];
2019a747e4fSDavid du Colombier if(strcmp(n, ".") == 0){
2029a747e4fSDavid du Colombier Accept:
2039a747e4fSDavid du Colombier wq->qid[wq->nqid++] = nc->qid;
2049a747e4fSDavid du Colombier continue;
2059a747e4fSDavid du Colombier }
2069a747e4fSDavid du Colombier if(strcmp(n, "..") == 0){
2077abd426fSDavid du Colombier if((*gen)(nc, nil, tab, ntab, DEVDOTDOT, &dir) != 1){
2087abd426fSDavid du Colombier print("devgen walk .. in dev%s %llux broken\n",
2097abd426fSDavid du Colombier devtab[nc->type]->name, nc->qid.path);
2107abd426fSDavid du Colombier error("broken devgen");
2117abd426fSDavid du Colombier }
2129a747e4fSDavid du Colombier nc->qid = dir.qid;
2139a747e4fSDavid du Colombier goto Accept;
2149a747e4fSDavid du Colombier }
2159a747e4fSDavid du Colombier /*
2169a747e4fSDavid du Colombier * Ugly problem: If we're using devgen, make sure we're
2179a747e4fSDavid du Colombier * walking the directory itself, represented by the first
2189a747e4fSDavid du Colombier * entry in the table, and not trying to step into a sub-
2199a747e4fSDavid du Colombier * directory of the table, e.g. /net/net. Devgen itself
2209a747e4fSDavid du Colombier * should take care of the problem, but it doesn't have
2219a747e4fSDavid du Colombier * the necessary information (that we're doing a walk).
2229a747e4fSDavid du Colombier */
2239a747e4fSDavid du Colombier if(gen==devgen && nc->qid.path!=tab[0].qid.path)
2249a747e4fSDavid du Colombier goto Notfound;
2257dd7cddfSDavid du Colombier for(i=0;; i++) {
2269a747e4fSDavid du Colombier switch((*gen)(nc, n, tab, ntab, i, &dir)){
2273e12c5d1SDavid du Colombier case -1:
2289a747e4fSDavid du Colombier Notfound:
2299a747e4fSDavid du Colombier if(j == 0)
2309a747e4fSDavid du Colombier error(Enonexist);
2319a747e4fSDavid du Colombier kstrcpy(up->errstr, Enonexist, ERRMAX);
2329a747e4fSDavid du Colombier goto Done;
2333e12c5d1SDavid du Colombier case 0:
2343e12c5d1SDavid du Colombier continue;
2353e12c5d1SDavid du Colombier case 1:
2369a747e4fSDavid du Colombier if(strcmp(n, dir.name) == 0){
2379a747e4fSDavid du Colombier nc->qid = dir.qid;
2389a747e4fSDavid du Colombier goto Accept;
2393e12c5d1SDavid du Colombier }
2403e12c5d1SDavid du Colombier continue;
2413e12c5d1SDavid du Colombier }
2427dd7cddfSDavid du Colombier }
2439a747e4fSDavid du Colombier }
2449a747e4fSDavid du Colombier /*
2459a747e4fSDavid du Colombier * We processed at least one name, so will return some data.
2469a747e4fSDavid du Colombier * If we didn't process all nname entries succesfully, we drop
2479a747e4fSDavid du Colombier * the cloned channel and return just the Qids of the walks.
2489a747e4fSDavid du Colombier */
2499a747e4fSDavid du Colombier Done:
2509a747e4fSDavid du Colombier poperror();
2519a747e4fSDavid du Colombier if(wq->nqid < nname){
2529a747e4fSDavid du Colombier if(alloc)
2539a747e4fSDavid du Colombier cclose(wq->clone);
2549a747e4fSDavid du Colombier wq->clone = nil;
2559a747e4fSDavid du Colombier }else if(wq->clone){
2569a747e4fSDavid du Colombier /* attach cloned channel to same device */
2579a747e4fSDavid du Colombier wq->clone->type = c->type;
2589a747e4fSDavid du Colombier }
2599a747e4fSDavid du Colombier return wq;
2603e12c5d1SDavid du Colombier }
2613e12c5d1SDavid du Colombier
2629a747e4fSDavid du Colombier int
devstat(Chan * c,uchar * db,int n,Dirtab * tab,int ntab,Devgen * gen)2639a747e4fSDavid du Colombier devstat(Chan *c, uchar *db, int n, Dirtab *tab, int ntab, Devgen *gen)
2643e12c5d1SDavid du Colombier {
2653e12c5d1SDavid du Colombier int i;
2663e12c5d1SDavid du Colombier Dir dir;
2677dd7cddfSDavid du Colombier char *p, *elem;
2683e12c5d1SDavid du Colombier
2699acf0835SDavid du Colombier for(i=0;; i++){
2709a747e4fSDavid du Colombier switch((*gen)(c, nil, tab, ntab, i, &dir)){
2713e12c5d1SDavid du Colombier case -1:
2729a747e4fSDavid du Colombier if(c->qid.type & QTDIR){
2734afe124fSDavid du Colombier if(c->path == nil)
2747dd7cddfSDavid du Colombier elem = "???";
2754afe124fSDavid du Colombier else if(strcmp(c->path->s, "/") == 0)
2767dd7cddfSDavid du Colombier elem = "/";
2777dd7cddfSDavid du Colombier else
2784afe124fSDavid du Colombier for(elem=p=c->path->s; *p; p++)
2797dd7cddfSDavid du Colombier if(*p == '/')
2807dd7cddfSDavid du Colombier elem = p+1;
2819a747e4fSDavid du Colombier devdir(c, c->qid, elem, 0, eve, DMDIR|0555, &dir);
2829a747e4fSDavid du Colombier n = convD2M(&dir, db, n);
2839a747e4fSDavid du Colombier if(n == 0)
2849a747e4fSDavid du Colombier error(Ebadarg);
2859a747e4fSDavid du Colombier return n;
2863e12c5d1SDavid du Colombier }
2877dd7cddfSDavid du Colombier
2883e12c5d1SDavid du Colombier error(Enonexist);
2893e12c5d1SDavid du Colombier case 0:
2903e12c5d1SDavid du Colombier break;
2913e12c5d1SDavid du Colombier case 1:
2927dd7cddfSDavid du Colombier if(c->qid.path == dir.qid.path) {
293219b2ee8SDavid du Colombier if(c->flag&CMSG)
2949a747e4fSDavid du Colombier dir.mode |= DMMOUNT;
2959a747e4fSDavid du Colombier n = convD2M(&dir, db, n);
2969a747e4fSDavid du Colombier if(n == 0)
2979a747e4fSDavid du Colombier error(Ebadarg);
2989a747e4fSDavid du Colombier return n;
2993e12c5d1SDavid du Colombier }
3003e12c5d1SDavid du Colombier break;
3013e12c5d1SDavid du Colombier }
3029acf0835SDavid du Colombier }
3033e12c5d1SDavid du Colombier }
3043e12c5d1SDavid du Colombier
3053e12c5d1SDavid du Colombier long
devdirread(Chan * c,char * d,long n,Dirtab * tab,int ntab,Devgen * gen)3063e12c5d1SDavid du Colombier devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen)
3073e12c5d1SDavid du Colombier {
3089a747e4fSDavid du Colombier long m, dsz;
309e288d156SDavid du Colombier Dir dir;
3103e12c5d1SDavid du Colombier
3119a747e4fSDavid du Colombier for(m=0; m<n; c->dri++) {
3129a747e4fSDavid du Colombier switch((*gen)(c, nil, tab, ntab, c->dri, &dir)){
3133e12c5d1SDavid du Colombier case -1:
3143e12c5d1SDavid du Colombier return m;
3153e12c5d1SDavid du Colombier
3163e12c5d1SDavid du Colombier case 0:
3173e12c5d1SDavid du Colombier break;
3183e12c5d1SDavid du Colombier
3193e12c5d1SDavid du Colombier case 1:
3209a747e4fSDavid du Colombier dsz = convD2M(&dir, (uchar*)d, n-m);
3219a747e4fSDavid du Colombier if(dsz <= BIT16SZ){ /* <= not < because this isn't stat; read is stuck */
3229a747e4fSDavid du Colombier if(m == 0)
3233ff48bf5SDavid du Colombier error(Eshort);
3249a747e4fSDavid du Colombier return m;
3259a747e4fSDavid du Colombier }
3269a747e4fSDavid du Colombier m += dsz;
3279a747e4fSDavid du Colombier d += dsz;
3283e12c5d1SDavid du Colombier break;
3293e12c5d1SDavid du Colombier }
3307dd7cddfSDavid du Colombier }
3317dd7cddfSDavid du Colombier
3323e12c5d1SDavid du Colombier return m;
3333e12c5d1SDavid du Colombier }
3343e12c5d1SDavid du Colombier
33559cc4ca5SDavid du Colombier /*
33659cc4ca5SDavid du Colombier * error(Eperm) if open permission not granted for up->user.
33759cc4ca5SDavid du Colombier */
33859cc4ca5SDavid du Colombier void
devpermcheck(char * fileuid,ulong perm,int omode)33959cc4ca5SDavid du Colombier devpermcheck(char *fileuid, ulong perm, int omode)
34059cc4ca5SDavid du Colombier {
34159cc4ca5SDavid du Colombier ulong t;
34259cc4ca5SDavid du Colombier static int access[] = { 0400, 0200, 0600, 0100 };
34359cc4ca5SDavid du Colombier
34459cc4ca5SDavid du Colombier if(strcmp(up->user, fileuid) == 0)
34559cc4ca5SDavid du Colombier perm <<= 0;
34659cc4ca5SDavid du Colombier else
34759cc4ca5SDavid du Colombier if(strcmp(up->user, eve) == 0)
34859cc4ca5SDavid du Colombier perm <<= 3;
34959cc4ca5SDavid du Colombier else
35059cc4ca5SDavid du Colombier perm <<= 6;
35159cc4ca5SDavid du Colombier
35259cc4ca5SDavid du Colombier t = access[omode&3];
35359cc4ca5SDavid du Colombier if((t&perm) != t)
35459cc4ca5SDavid du Colombier error(Eperm);
35559cc4ca5SDavid du Colombier }
35659cc4ca5SDavid du Colombier
3573e12c5d1SDavid du Colombier Chan*
devopen(Chan * c,int omode,Dirtab * tab,int ntab,Devgen * gen)3583e12c5d1SDavid du Colombier devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen)
3593e12c5d1SDavid du Colombier {
3603e12c5d1SDavid du Colombier int i;
3613e12c5d1SDavid du Colombier Dir dir;
3623e12c5d1SDavid du Colombier
3637dd7cddfSDavid du Colombier for(i=0;; i++) {
3649a747e4fSDavid du Colombier switch((*gen)(c, nil, tab, ntab, i, &dir)){
3653e12c5d1SDavid du Colombier case -1:
3663e12c5d1SDavid du Colombier goto Return;
3673e12c5d1SDavid du Colombier case 0:
3683e12c5d1SDavid du Colombier break;
3693e12c5d1SDavid du Colombier case 1:
3707dd7cddfSDavid du Colombier if(c->qid.path == dir.qid.path) {
37159cc4ca5SDavid du Colombier devpermcheck(dir.uid, dir.mode, omode);
3723e12c5d1SDavid du Colombier goto Return;
3733e12c5d1SDavid du Colombier }
3743e12c5d1SDavid du Colombier break;
3753e12c5d1SDavid du Colombier }
3767dd7cddfSDavid du Colombier }
3773e12c5d1SDavid du Colombier Return:
3783e12c5d1SDavid du Colombier c->offset = 0;
3799a747e4fSDavid du Colombier if((c->qid.type&QTDIR) && omode!=OREAD)
3803e12c5d1SDavid du Colombier error(Eperm);
3813e12c5d1SDavid du Colombier c->mode = openmode(omode);
3823e12c5d1SDavid du Colombier c->flag |= COPEN;
3833e12c5d1SDavid du Colombier return c;
3843e12c5d1SDavid du Colombier }
3857dd7cddfSDavid du Colombier
3867dd7cddfSDavid du Colombier void
devcreate(Chan *,char *,int,ulong)3877dd7cddfSDavid du Colombier devcreate(Chan*, char*, int, ulong)
3887dd7cddfSDavid du Colombier {
3897dd7cddfSDavid du Colombier error(Eperm);
3907dd7cddfSDavid du Colombier }
3917dd7cddfSDavid du Colombier
3927dd7cddfSDavid du Colombier Block*
devbread(Chan * c,long n,ulong offset)3937dd7cddfSDavid du Colombier devbread(Chan *c, long n, ulong offset)
3947dd7cddfSDavid du Colombier {
3957dd7cddfSDavid du Colombier Block *bp;
3967dd7cddfSDavid du Colombier
3977dd7cddfSDavid du Colombier bp = allocb(n);
3987dd7cddfSDavid du Colombier if(bp == 0)
3997dd7cddfSDavid du Colombier error(Enomem);
4007dd7cddfSDavid du Colombier if(waserror()) {
4017dd7cddfSDavid du Colombier freeb(bp);
4027dd7cddfSDavid du Colombier nexterror();
4037dd7cddfSDavid du Colombier }
4047dd7cddfSDavid du Colombier bp->wp += devtab[c->type]->read(c, bp->wp, n, offset);
4057dd7cddfSDavid du Colombier poperror();
4067dd7cddfSDavid du Colombier return bp;
4077dd7cddfSDavid du Colombier }
4087dd7cddfSDavid du Colombier
4097dd7cddfSDavid du Colombier long
devbwrite(Chan * c,Block * bp,ulong offset)4107dd7cddfSDavid du Colombier devbwrite(Chan *c, Block *bp, ulong offset)
4117dd7cddfSDavid du Colombier {
4127dd7cddfSDavid du Colombier long n;
4137dd7cddfSDavid du Colombier
41459cc4ca5SDavid du Colombier if(waserror()) {
41559cc4ca5SDavid du Colombier freeb(bp);
41659cc4ca5SDavid du Colombier nexterror();
41759cc4ca5SDavid du Colombier }
4187dd7cddfSDavid du Colombier n = devtab[c->type]->write(c, bp->rp, BLEN(bp), offset);
41959cc4ca5SDavid du Colombier poperror();
4207dd7cddfSDavid du Colombier freeb(bp);
4217dd7cddfSDavid du Colombier
4227dd7cddfSDavid du Colombier return n;
4237dd7cddfSDavid du Colombier }
4247dd7cddfSDavid du Colombier
4257dd7cddfSDavid du Colombier void
devremove(Chan *)4267dd7cddfSDavid du Colombier devremove(Chan*)
4277dd7cddfSDavid du Colombier {
4287dd7cddfSDavid du Colombier error(Eperm);
4297dd7cddfSDavid du Colombier }
4307dd7cddfSDavid du Colombier
4319a747e4fSDavid du Colombier int
devwstat(Chan *,uchar *,int)4329a747e4fSDavid du Colombier devwstat(Chan*, uchar*, int)
4337dd7cddfSDavid du Colombier {
4347dd7cddfSDavid du Colombier error(Eperm);
4359a747e4fSDavid du Colombier return 0;
4369a747e4fSDavid du Colombier }
4379a747e4fSDavid du Colombier
4389a747e4fSDavid du Colombier void
devpower(int)4399a747e4fSDavid du Colombier devpower(int)
4409a747e4fSDavid du Colombier {
4419a747e4fSDavid du Colombier error(Eperm);
4429a747e4fSDavid du Colombier }
4439a747e4fSDavid du Colombier
4449a747e4fSDavid du Colombier int
devconfig(int,char *,DevConf *)4459a747e4fSDavid du Colombier devconfig(int, char *, DevConf *)
4469a747e4fSDavid du Colombier {
4479a747e4fSDavid du Colombier error(Eperm);
4489a747e4fSDavid du Colombier return 0;
4497dd7cddfSDavid du Colombier }
450