| plan 9 kernel history: overview | file list | diff list |
1991/0823/port/devwren.c (diff list | history)
| 1991/0706/sys/src/9/port/devwren.c:7,47 – 1991/0823/sys/src/9/port/devwren.c:7,47 (short | long | prev | next) | ||
| 1991/0110 | #include "devtab.h" #include "io.h" | |
| 1991/0112 |
| |
| 1991/0823 | typedef struct Partition Partition; typedef struct Drive Drive; | |
| 1991/0112 | ||
| 1991/0110 | enum { | |
| 1991/0112 |
| |
| 1991/0823 | Npart= 8+2, /* 8 sub partitions, disk, and partition */ | |
| 1991/0112 | Ndisk= 64, /* maximum disks */ | |
| 1991/0110 | ||
| 1991/0823 | /* file types */ | |
| 1991/0112 | Qdir= 0, | |
| 1991/0110 | }; | |
| 1991/0823 | #define PART(x) ((x)&0xF) #define DRIVE(x) (((x)>>4)&0x7) #define MKQID(d,p) (((d)<<4) | (p)) | |
| 1991/0110 | ||
| 1991/0112 |
| |
| 1991/0110 | ||
| 1991/0112 |
| |
| 1991/0823 | struct Partition | |
| 1991/0112 | { | |
| 1991/0823 | ulong start; ulong end; char name[NAMELEN+1]; | |
| 1991/0112 | }; | |
| 1991/0823 | struct Drive | |
| 1991/0112 | { | |
| 1991/0823 | ulong bytes; /* bytes per block */ int npart; /* actual number of partitions */ int drive; Partition p[Npart]; | |
| 1991/0112 | }; | |
| 1991/0110 | ||
| 1991/0112 |
| |
| 1991/0823 | static Drive wren[Ndisk]; | |
| 1991/0110 | ||
| 1991/0603 |
| |
| 1991/0423 | #define DATASIZE (8*1024) /* BUG */ | |
| 1991/0112 | ||
| 1991/0115 |
| |
| 1991/0823 | static void wrenpart(int); static long wrenio(Drive *, Partition *, int, char *, ulong, ulong); | |
| 1991/0115 | ||
| 1991/0110 | /* * accepts [0-7].[0-7], or abbreviation | |
| 1991/0706/sys/src/9/port/devwren.c:50,70 – 1991/0823/sys/src/9/port/devwren.c:50,71 | ||
| 1991/0110 | wrendev(char *p) { int dev = 0; | |
| 1991/0823 | if(p == 0 || p[0] == 0) | |
| 1991/0110 | goto out; | |
| 1991/0823 | if(p[0] < '0' || p[0] > '7') | |
| 1991/0110 | goto cant; | |
| 1991/0823 | dev = (p[0] - '0') << 3; if(p[1] == 0) | |
| 1991/0110 | goto out; | |
| 1991/0823 | if(p[1] != '.') | |
| 1991/0110 | goto cant; | |
| 1991/0823 | if(p[2] == 0) | |
| 1991/0110 | goto out; | |
| 1991/0823 | if(p[2] < '0' || p[2] > '7') | |
| 1991/0110 | goto cant; | |
| 1991/0823 | dev |= p[2] - '0'; if(p[3] != 0) | |
| 1991/0110 | goto cant; out: | |
| 1991/0112 | if(dev >= Ndisk) | |
| 1991/0706/sys/src/9/port/devwren.c:75,99 – 1991/0823/sys/src/9/port/devwren.c:76,106 | ||
| 1991/0110 | } static int | |
| 1991/0823 | wrengen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dirp) | |
| 1991/0110 | { | |
| 1991/0112 |
| |
| 1991/0823 | Qid qid; int drive; char name[NAMELEN+4]; Drive *dp; Partition *pp; ulong l; | |
| 1991/0112 |
| |
| 1991/0823 | qid.vers = 0; drive = s/Npart; s = s % Npart; if(drive >= Ndisk) | |
| 1991/0110 | return -1; | |
| 1991/0112 |
| |
| 1991/0823 | dp = &wren[drive]; | |
| 1991/0112 |
| |
| 1991/0110 |
| |
| 1991/0112 |
| |
| 1991/0110 |
| |
| 1991/0823 | if(s >= dp->npart) return 0; pp = &dp->p[s]; sprint(name, "hd%d%s", drive, pp->name); name[NAMELEN] = 0; qid.path = MKQID(drive, s); l = (pp->end - pp->start) * dp->bytes; devdir(c, qid, name, l, 0600, dirp); | |
| 1991/0110 | return 1; } | |
| 1991/0706/sys/src/9/port/devwren.c:100,132 – 1991/0823/sys/src/9/port/devwren.c:107,118 | ||
| 1991/0110 | void wrenreset(void) | |
| 1991/0112 | { | |
| 1991/0110 | ||
| 1991/0112 |
| |
| 1991/0115 |
| |
| 1991/0112 |
| |
| 1991/0110 | void wreninit(void) | |
| 1991/0423 |
| |
| 1991/0823 | { } | |
| 1991/0110 | /* * param is #r<target>.<lun> | |
| 1991/0706/sys/src/9/port/devwren.c:134,167 – 1991/0823/sys/src/9/port/devwren.c:120,136 | ||
| 1991/0110 | Chan * wrenattach(char *param) { | |
| 1991/0112 |
| |
| 1991/0823 | int drive; | |
| 1991/0112 | ||
| 1991/0110 |
| |
| 1991/0823 | drive = wrendev(param); wrenpart(drive); | |
| 1991/0110 | c = devattach('r', param); | |
| 1991/0112 |
| |
| 1991/0429 | ||
| 1991/0706 |
| |
| 1991/0112 |
| |
| 1991/0823 | c->dev = drive; | |
| 1991/0110 | return c; } | |
| 1991/0823 | Chan* | |
| 1991/0110 | wrenclone(Chan *c, Chan *nc) { return devclone(c, nc); | |
| 1991/0706/sys/src/9/port/devwren.c:170,190 – 1991/0823/sys/src/9/port/devwren.c:139,157 | ||
| 1991/0110 | int wrenwalk(Chan *c, char *name) { | |
| 1991/0823 | return devwalk(c, name, 0, 0, wrengen); | |
| 1991/0110 | } void | |
| 1991/0823 | wrenstat(Chan *c, char *dp) | |
| 1991/0110 | { | |
| 1991/0823 | devstat(c, dp, 0, 0, wrengen); | |
| 1991/0110 | } | |
| 1991/0823 | Chan* | |
| 1991/0110 | wrenopen(Chan *c, int omode) { | |
| 1991/0823 | return devopen(c, omode, 0, 0, wrengen); | |
| 1991/0110 | } void | |
| 1991/0706/sys/src/9/port/devwren.c:195,317 – 1991/0823/sys/src/9/port/devwren.c:162,325 | ||
| 1991/0110 | void wrenclose(Chan *c) | |
| 1991/0823 | { } | |
| 1991/0110 | ||
| 1991/0823 | void wrenremove(Chan *c) { error(Eperm); } void wrenwstat(Chan *c, char *dp) { error(Eperm); } | |
| 1991/0110 | long | |
| 1991/0411 | wrenread(Chan *c, char *a, long n, ulong offset) | |
| 1991/0110 | { | |
| 1991/0423 |
| |
| 1991/0112 |
| |
| 1991/0823 | Drive *d; Partition *p; | |
| 1991/0112 | ||
| 1991/0110 |
| |
| 1991/0112 | if(c->qid.path == CHDIR) | |
| 1991/0110 |
| |
| 1991/0823 | return devdirread(c, a, n, 0, 0, wrengen); | |
| 1991/0112 |
| |
| 1991/0110 |
| |
| 1991/0411 |
| |
| 1991/0110 |
| |
| 1991/0411 |
| |
| 1991/0112 |
| |
| 1991/0110 |
| |
| 1991/0423 |
| |
| 1991/0110 |
| |
| 1991/0112 |
| |
| 1991/0110 |
| |
| 1991/0318 |
| |
| 1991/0110 |
| |
| 1991/0604 |
| |
| 1991/0110 |
| |
| 1991/0603 |
| |
| 1991/0110 |
| |
| 1991/0603 |
| |
| 1991/0110 |
| |
| 1991/0603 |
| |
| 1991/0110 |
| |
| 1991/0823 | d = &wren[DRIVE(c->qid.path)]; p = &d->p[PART(c->qid.path)]; return wrenio(d, p, 0, a, n, offset); | |
| 1991/0110 | } long | |
| 1991/0411 | wrenwrite(Chan *c, char *a, long n, ulong offset) | |
| 1991/0110 | { | |
| 1991/0823 | Drive *d; Partition *p; d = &wren[DRIVE(c->qid.path)]; p = &d->p[PART(c->qid.path)]; return wrenio(d, p, 1, a, n, offset); } static long wrenio(Drive *d, Partition *p, int write, char *a, ulong n, ulong offset) { | |
| 1991/0423 | Scsi *cmd; | |
| 1991/0112 |
| |
| 1991/0823 | void *b; ulong block; | |
| 1991/0112 | ||
| 1991/0110 |
| |
| 1991/0823 | if(n % d->bytes || offset % d->bytes) error(Ebadarg); block = offset / d->bytes + p->start; if(block >= p->end) | |
| 1991/0110 | return 0; | |
| 1991/0112 |
| |
| 1991/0110 |
| |
| 1991/0411 |
| |
| 1991/0110 |
| |
| 1991/0411 |
| |
| 1991/0112 |
| |
| 1991/0110 |
| |
| 1991/0423 |
| |
| 1991/0110 |
| |
| 1991/0112 |
| |
| 1991/0318 |
| |
| 1991/0110 |
| |
| 1991/0823 | if(n > DATASIZE) n = DATASIZE; n /= d->bytes; if(block + n > p->end) n = p->end - block; if(n == 0) return 0; if(write) cmd = scsicmd(d->drive, 0x0a, n*d->bytes); else cmd = scsicmd(d->drive, 0x08, n*d->bytes); if(waserror()){ | |
| 1991/0110 | qunlock(cmd); | |
| 1991/0604 |
| |
| 1991/0110 |
| |
| 1991/0823 | nexterror(); | |
| 1991/0110 | } | |
| 1991/0823 | cmd->cmdblk[1] = block>>16; cmd->cmdblk[2] = block>>8; cmd->cmdblk[3] = block; cmd->cmdblk[4] = n; if(write) memmove(cmd->data.base, a, n*d->bytes); scsiexec(cmd, !write); n = cmd->data.ptr - cmd->data.base; if(!write) memmove(a, cmd->data.base, n); qunlock(cmd); poperror(); | |
| 1991/0110 | return n; } | |
| 1991/0823 | /* * read partition table. The partition table is just ascii strings. */ #define MAGIC "plan9 partitions" static void wrenpart(int dev) | |
| 1991/0110 | { | |
| 1991/0823 | Scsi *cmd; Drive *dp; Partition *pp; uchar buf[32]; char *b; char *line[Npart+1]; char *field[3]; ulong n; int i; | |
| 1991/0110 |
| |
| 1991/0603 |
| |
| 1991/0823 | scsiready(dev); scsisense(dev, buf); scsicap(dev, buf); dp = &wren[dev]; dp->drive = dev; if(dp->npart) return; /* * we always have a partition for the whole disk * and one for the partition table */ dp->bytes = (buf[4]<<24)+(buf[5]<<16)+(buf[6]<<8)+(buf[7]); pp = &dp->p[0]; strcpy(pp->name, "disk"); pp->start = 0; pp->end = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]) + 1; pp++; strcpy(pp->name, "partition"); pp->start = dp->p[0].end - 1; pp->end = dp->p[0].end; dp->npart = 2; | |
| 1991/0603 |
| |
| 1991/0823 | /* * read partition table from disk, null terminate */ cmd = scsicmd(dev, 0x08, dp->bytes); if(waserror()){ qunlock(cmd); nexterror(); } n = dp->p[0].end-1; cmd->cmdblk[1] = n>>16; cmd->cmdblk[2] = n>>8; cmd->cmdblk[3] = n; cmd->cmdblk[4] = 1; scsiexec(cmd, 1); cmd->data.base[dp->bytes-1] = 0; /* * parse partition table. */ n = getfields((char *)cmd->data.base, line, Npart+1, '\n'); if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) != 0) goto out; for(i = 1; i < n; i++){ pp++; if(getfields(line[i], field, 3, ' ') != 3){ break; } strncpy(pp->name, field[0], NAMELEN); pp->start = strtoul(field[1], 0, 0); pp->end = strtoul(field[2], 0, 0); if(pp->start > pp->end || pp->start >= dp->p[0].end){ break; } dp->npart++; } out: qunlock(cmd); poperror(); | |
| 1991/0110 | } | |