From 56f80667320562b36ab312dee8adf2e1aa342064 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 13 Sep 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-09-13 --- pc/devhard.c | 20 ++- pc/fns.h | 10 +- port/devmouse.c | 2 + port/devsd.c | 352 ++++++++++++++++++++++++++++++++++++++++++++++++ port/portfns.h | 7 + 5 files changed, 381 insertions(+), 10 deletions(-) create mode 100644 port/devsd.c diff --git a/pc/devhard.c b/pc/devhard.c index 89e85975d675c49358f0f5de1d24e4fda1ab72a1..426942e9e33db474fd8f6d67edafe8e7127f5ce4 100644 --- a/pc/devhard.c +++ b/pc/devhard.c @@ -290,7 +290,25 @@ hardcreate(Chan *c, char *name, int omode, ulong perm) void hardclose(Chan *c) { - USED(c); + Drive *d; + Partition *p; + + if(c->mode != OWRITE && c->mode != ORDWR) + return; + + d = &hard[DRIVE(c->qid.path)]; + p = &d->p[PART(c->qid.path)]; + if(strcmp(p->name, "partition") != 0) + return; + + if(waserror()){ + qunlock(d); + nexterror(); + } + qlock(d); + hardpart(d); + qunlock(d); + poperror(); } void diff --git a/pc/fns.h b/pc/fns.h index 1fad7cb51c9a9884fcbb07e3f0b7a346a97680e6..1aa9252e4ac14bb9f27f3c0828ffc529e5d9eec6 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -2,6 +2,7 @@ void aamloop(int); void addconf(char*, char*); +void addscsicard(char*, Scsiio (*)(int, ISAConf*)); void bbinit(void); void bigcursor(void); void bootargs(ulong); @@ -118,12 +119,3 @@ Block* iallocb(int); void* ifroute(ulong); ulong ifunroute(ulong); void parseip(char*, char*); - -#define scsialloc(n) mallocz((n)+512, 0) -#define scsifree(p) free(p) - -void addscsicard(char*, Scsiio (*)(int, ISAConf*)); -int scsistart(Target*, char, int); -int scsireqsense(Target*, char, int); -int scsicap(Target*, char, ulong*, ulong*); -int scsibio(Target*, char, int, void*, long, long, long); diff --git a/port/devmouse.c b/port/devmouse.c index 65341528ab21ffcd6a815552b9ede875feafe9a4..9a5b58f0efbff8195f25d3d6a482d4cd57687a07 100644 --- a/port/devmouse.c +++ b/port/devmouse.c @@ -324,6 +324,7 @@ mouseclock(void) mouse.redraw = cursoron(0); unlock(&cursor); } + graphicsactive(0); } /* @@ -350,6 +351,7 @@ mousetrack(int b, int dx, int dy) mouse.buttons = b; mouse.redraw = 1; wakeup(&mouse.r); + graphicsactive(1); } /* diff --git a/port/devsd.c b/port/devsd.c new file mode 100644 index 0000000000000000000000000000000000000000..9e2985d328f89b635b21cd0c0507e2c4715d7928 --- /dev/null +++ b/port/devsd.c @@ -0,0 +1,352 @@ +/* + * SCSI disc driver + */ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" +#include "devtab.h" + +enum +{ + LogNpart = 3, + Npart = 1<>LogNpart) +#define PART(qid) ((qid).path&(Npart-1)) + +typedef struct Part Part; +typedef struct Disk Disk; + +struct Part +{ + ulong beg; + ulong end; + char name[NAMELEN]; +}; + +struct Disk +{ + QLock; + Target* t; + uchar lun; + char id[NAMELEN]; + char vol[NAMELEN]; + + uchar* inquire; + ulong size; + ulong bsize; + + int npart; + Part table[Npart]; +}; + +int ndisk; +Disk disk[Ndisk]; + +static void sdrdpart(Disk*); +static long sdio(Chan*, int, char*, ulong, ulong); + +static int +sdgen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dirp) +{ + Qid qid; + Disk *d; + Part *p; + int unit; + char name[2*NAMELEN]; + + USED(tab, ntab); + + d = disk; + while(s >= d->npart) { + s -= d->npart; + d++; + } + unit = d - disk; + if(unit > ndisk) + return -1; + + p = d->table+s; + sprint(name, "%s%s", d->vol, p->name); + name[NAMELEN-1] = '\0'; + qid = (Qid){(unit<end - p->beg) * d->bsize, eve, 0666, dirp); + return 1; +} + +void +sdreset(void) +{ +} + +void +sdinit(void) +{ + Disk *d; + ulong s, b; + int dev, i; + + dev = 0; + for(;;) { + d = &disk[ndisk]; + dev = scsiinv(dev, 0, &d->t, &d->inquire, d->id); + if(dev < 0) + break; + + if(scsistart(d->t, 0, 1) != STok) + continue; + + /* Search for other lun's */ + for(i = 0; i < Nlun; i++) { + d->lun = i; + scsireqsense(d->t, d->lun, 1); + + /* NCR Raid only seems to answer second capacity + * command if lun != 0 + */ + if(scsicap(d->t, d->lun, &s, &b) != STok) { + scsireqsense(d->t, 0, 1); + continue; + } + scsireqsense(d->t, 0, 1); + + s = 0; + b = 0; + if(scsicap(d->t, d->lun, &s, &b) != STok) { + scsireqsense(d->t, 0, 1); + continue; + } + + if(scsireqsense(d->t, d->lun, 1) != STok) + continue; + + if(s == 0 || b == 0) + continue; + + d->size = s; + d->bsize = b; + sprint(d->vol, "sd%d", ndisk); + + if(++ndisk >= Ndisk) + break; + d++; + d->t = d[-1].t; + d->inquire = d[-1].inquire; + strcpy(d->id, d[-1].id); + } + + if(ndisk >= Ndisk) { + print("devsd: configure more disks\n"); + break; + } + } +} + +Chan* +sdattach(char *spec) +{ + int i; + + for(i = 0; i < ndisk; i++) + sdrdpart(&disk[i]); + + return devattach('w', spec); +} + +Chan * +sdclone(Chan *c, Chan *nc) +{ + return devclone(c, nc); +} + +int +sdwalk(Chan *c, char *name) +{ + return devwalk(c, name, 0, 0, sdgen); +} + +void +sdstat(Chan *c, char *db) +{ + devstat(c, db, 0, 0, sdgen); +} + +Chan * +sdopen(Chan *c, int omode) +{ + return devopen(c, omode, 0, 0, sdgen); +} + +void +sdcreate(Chan *c, char *name, int omode, ulong perm) +{ + USED(c, name, omode, perm); + error(Eperm); +} + +void +sdremove(Chan *c) +{ + USED(c); + error(Eperm); +} + +void +sdwstat(Chan *c, char *dp) +{ + USED(c, dp); + error(Eperm); +} + +void +sdclose(Chan *c) +{ + Disk *d; + Part *p; + + if(c->mode != OWRITE && c->mode != ORDWR) + return; + + d = &disk[DRIVE(c->qid)]; + p = &d->table[PART(c->qid)]; + if(strcmp(p->name, "partition")) + return; + + sdrdpart(d); +} + +long +sdread(Chan *c, void *a, long n, ulong offset) +{ + if(c->qid.path == CHDIR) + return devdirread(c, a, n, 0, 0, sdgen); + + return sdio(c, 0, a, n, offset); +} + +long +sdwrite(Chan *c, char *a, long n, ulong offset) +{ + return sdio(c, 1, a, n, offset); +} + +static void +sdrdpart(Disk *d) +{ + Part *p; + int n, i; + char *b, *line[Npart+2], *field[3]; + static char MAGIC[] = "plan9 partitions"; + + b = scsialloc(d->bsize); + if(b == 0) + error(Enomem); + + qlock(d); + + p = d->table; + + strcpy(p->name, "disk"); + p->beg = 0; + p->end = d->size + 1; + p++; + strcpy(p->name, "partition"); + p->beg = d->table[0].end - 1; + p->end = d->table[0].end; + p++; + d->npart = 2; + + scsibio(d->t, d->lun, SCSIread, b, 1, d->bsize, d->table[0].end-1); + b[d->bsize-1] = '\0'; + + /* + * parse partition table. + */ + n = getfields(b, line, Npart+2, '\n'); + if(n > 0 && strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0) { + for(i = 1; i < n; i++) { + switch(getfields(line[i], field, 3, ' ')) { + case 2: + if(strcmp(field[0], "unit") == 0) + strncpy(d->vol, field[1], NAMELEN); + break; + case 3: + strncpy(p->name, field[0], NAMELEN); + p->beg = strtoul(field[1], 0, 0); + p->end = strtoul(field[2], 0, 0); + if(p->beg > p->end || p->beg >= d->table[0].end) + break; + p++; + } + } + } + d->npart = p - d->table; + scsifree(b); + qunlock(d); +} + +static long +sdio(Chan *c, int write, char *a, ulong len, ulong offset) +{ + Disk *d; + Part *p; + uchar *b; + ulong block, n, max, x; + + d = &disk[DRIVE(c->qid)]; + p = &d->table[PART(c->qid)]; + + block = (offset / d->bsize) + p->beg; + n = (offset + len + d->bsize - 1) / d->bsize + p->beg - block; + max = SCSImaxxfer / d->bsize; + if(n > max) + n = max; + if(block + n > p->end) + n = p->end - block; + if(block >= p->end || n == 0) + return 0; + + b = scsialloc(n*d->bsize); + if(b == 0) + error(Enomem); + if(waserror()) { + scsifree(b); + nexterror(); + } + offset %= d->bsize; + if(write) { + if(offset || len % d->bsize) { + x = scsibio(d->t, d->lun, SCSIread, b, n, d->bsize, block); + if(x < n * d->bsize) { + n = x / d->bsize; + x = n * d->bsize - offset; + if(len > x) + len = x; + } + } + memmove(b + offset, a, len); + x = scsibio(d->t, d->lun, SCSIwrite, b, n, d->bsize, block); + if(x < offset) + len = 0; + else + if(len > x - offset) + len = x - offset; + } + else { + x = scsibio(d->t, d->lun, SCSIread, b, n, d->bsize, block); + if(x < offset) + len = 0; + else + if(len > x - offset) + len = x - offset; + memmove(a, b+offset, len); + } + poperror(); + scsifree(b); + return len; +} diff --git a/port/portfns.h b/port/portfns.h index 531928cb123c081e850763a89ec338c426761bf5..040f21e348ba9a660e1dbe1c6846855026d642f7 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -88,6 +88,7 @@ void freesession(Session*); void getcolor(ulong, ulong*, ulong*, ulong*); int getfields(char*, char**, int, char); void gotolabel(Label*); +void graphicsactive(int); int haswaitq(void*); long hostdomainwrite(char*, int); long hostownerwrite(char*, int); @@ -225,8 +226,14 @@ void sccsetup(void*, ulong, int); void sched(void); void schedinit(void); int screenbits(void); +#define scsialloc(n) mallocz((n)+512, 0) +int scsibio(Target*, char, int, void*, long, long, long); +int scsicap(Target*, char, ulong*, ulong*); int scsiexec(Target*, int, uchar*, int, void*, int*); +#define scsifree(p) free(p) int scsiinv(int, int, Target**, uchar**, char*); +int scsireqsense(Target*, char, int); +int scsistart(Target*, char, int); Target* scsiunit(int, int); long seconds(void); ulong segattach(Proc*, ulong, char *, ulong, ulong);