## diffname port/devsd.c 1994/0913 ## diff -e /dev/null /n/fornaxdump/1994/0913/sys/src/brazil/port/devsd.c 0a /* * 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; } . ## diffname port/devsd.c 1994/1228 ## diff -e /n/fornaxdump/1994/0913/sys/src/brazil/port/devsd.c /n/fornaxdump/1994/1228/sys/src/brazil/port/devsd.c 278a if(p >= &d->table[Npart]) break; . 147a print("sd out\n"); . 14c LogNpart = 4, . ## diffname port/devsd.c 1994/1230 ## diff -e /n/fornaxdump/1994/1228/sys/src/brazil/port/devsd.c /n/fornaxdump/1994/1230/sys/src/brazil/port/devsd.c 148d ## diffname port/devsd.c 1995/0108 ## diff -e /n/fornaxdump/1994/1230/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0108/sys/src/brazil/port/devsd.c 235a } long sdbwrite(Chan *c, Block *bp, ulong offset) { return devbwrite(c, bp, offset); . 231a Block* sdbread(Chan *c, long n, ulong offset) { return devbread(c, n, offset); } . ## diffname port/devsd.c 1995/0117 ## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0117/sys/src/brazil/port/devsd.c 285c switch(getfields(line[i], field, 3, " ")) { . 282c n = getfields(b, line, Npart+2, "\n"); . ## diffname port/devsd.c 1995/0324 ## diff -e /n/fornaxdump/1995/0117/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0324/sys/src/brazil/port/devsd.c 214a print("sdclose: qid 0x%lux drive %d, part %d\n", c->qid, DRIVE(c->qid), PART(c->qid)); . ## diffname port/devsd.c 1995/0325 ## diff -e /n/fornaxdump/1995/0324/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0325/sys/src/brazil/port/devsd.c 227c if(c->qid.path & CHDIR) . 218,221c if((c->mode&3) != OREAD && strcmp(p->name, "partition") == 0) sdrdpart(d); . 215d 212c if(c->qid.path & CHDIR) . 202d 200c sdwstat(Chan*, char*) . 195d 193c sdremove(Chan*) . 188d 186c sdcreate(Chan*, char*, int, ulong) . 63,64d 55c sdgen(Chan *c, Dirtab*, long, long s, Dir *dirp) . ## diffname port/devsd.c 1995/0329 ## diff -e /n/fornaxdump/1995/0325/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0329/sys/src/brazil/port/devsd.c 105a /* * A SCSI target does not support a lun if the * the peripheral device type and qualifier fields * in the response to an inquiry command are 0x7F. */ memset(inq, 0, sizeof(inq)); nbytes = sizeof(inq); if(scsiinquiry(d->t, d->lun, inq, &nbytes) != STok || inq[0] == 0x7F) continue; . 104a . 90c uchar inq[255]; int dev, i, nbytes; . ## diffname port/devsd.c 1995/0403 ## diff -e /n/fornaxdump/1995/0329/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0403/sys/src/brazil/port/devsd.c 321a if(write && (d->inquire[0] & 0x1F) == TypeCD) error(Eperm); . 280a if((d->inquire[0] & 0x1F) == TypeCD){ scsifree(b); qunlock(d); return; } . 144a case TypeDA: case TypeWO: case TypeMO: sprint(d->vol, "sd%d", ndisk); break; case TypeCD: sprint(d->vol, "cd%d", ndisk); break; default: continue; } . 143c switch(d->inquire[0] & 0x1F){ . 96c dev = scsiinv(dev, types, &d->t, &d->inquire, d->id); . 53a static int types[] = { TypeDA, TypeWO, TypeCD, TypeMO, -1, }; . 11a enum { TypeDA = 0x00, /* Direct Access */ TypeWO = 0x04, /* Worm */ TypeCD = 0x05, /* CD-ROM */ TypeMO = 0x07, /* rewriteable Magneto-Optical */ }; . ## diffname port/devsd.c 1995/0404 ## diff -e /n/fornaxdump/1995/0403/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0404/sys/src/brazil/port/devsd.c 169a print("sd6|"); . 158d 151a print("sd5/0x%2.2ux|", d->inquire[0]); . 147,149d 145a print("sd4/%d/%d|", s, b); . 143c scsireqsense(d->t, 0, 0); . 131,139d 129a print("sd3|"); . 119,120d 117a print("sd2|"); . 112,113c if(scsitest(d->t, 0) < 0) scsireqsense(d->t, 0, 0); if(scsistart(d->t, 0, 1) < 0) scsireqsense(d->t, 0, 0); print("sd1|"); . 62c TypeDA, TypeCD, TypeMO, . 16a TYpeMC = 0x08, /* Medium Changer */ . 13a TypeSA = 0x01, /* Sequential Access */ . ## diffname port/devsd.c 1995/0405 ## diff -e /n/fornaxdump/1995/0404/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0405/sys/src/brazil/port/devsd.c 287d 283a /* * If the drive wasn't ready when we tried to do a * read-capacity earlier (in sdinit()), try again. * It might be possible to be smarter here, and look at the * response from a test-unit-ready which would show if the * target was in the process of becoming ready. */ if(d->size == 0 || d->bsize == 0){ if(scsicap(d->t, d->lun, &d->size, &d->bsize) != STok){ d->size = d->bsize = 0; error(Eio); } } . 164d 148,151d 144,146c switch(type){ . 142d 140a type = scratch[0] & 0x1F; /* * Read-capacity is mandatory for TypeDA, TypeMO and TypeCD. * It may return 'not ready' if TypeDA is not spun up, * TypeMO or TypeCD are not loaded or just plain slow getting * their act together after a reset. * If 'not ready' comes back, try starting a TypeDA and punt * the get capacity until the drive is attached. * It might be possible to be smarter here, and look at the * response from a test-unit-ready which would show if the * target was in the process of becoming ready. */ if(scsicap(d->t, d->lun, &d->size, &d->bsize) != STok) { nbytes = sizeof(scratch); memset(scratch, 0, nbytes); scsireqsense(d->t, 0, scratch, &nbytes, 1); if((scratch[2] & 0x0F) != 0x02) continue; if(type == TypeDA) scsistart(d->t, d->lun, 0); d->size = d->bsize = 0; . 134,139c if(scratch[0] == 0x7F) . 130,132c nbytes = sizeof(scratch); memset(scratch, 0, nbytes); if(scsiinquiry(d->t, d->lun, scratch, &nbytes) != STok) . 123d 114,120c /* * Search for all the lun's. */ . 103,104c uchar scratch[0xFF], type; . ## diffname port/devsd.c 1995/0416 ## diff -e /n/fornaxdump/1995/0405/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0416/sys/src/brazil/port/devsd.c 364a if(d->bsize == 0) error(Eio); . 287,300d 189,191c /* * If the drive wasn't ready when we tried to do a * read-capacity earlier (in sdinit()), try again. * It might be possible to be smarter here, and look at the * response from a test-unit-ready which would show if the * target was in the process of becoming ready. */ nfound = 0; for(i = 0; i < ndisk; i++){ d = &disk[i]; if(waserror()){ poperror(); continue; } if(d->size == 0 || d->bsize == 0){ if(scsicap(d->t, d->lun, &d->size, &d->bsize) != STok){ d->size = d->bsize = 0; continue; } } sdrdpart(d); nfound++; poperror(); } if(nfound == 0) return 0; . 187c int i, nfound; Disk *d; . ## diffname port/devsd.c 1995/0417 ## diff -e /n/fornaxdump/1995/0416/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0417/sys/src/brazil/port/devsd.c 376,378d 311a /* * If the drive wasn't ready when we tried to do a * read-capacity earlier (in sdinit()), try again. * It might be possible to be smarter here, and look at the * response from a test-unit-ready which would show if the * target was in the process of becoming ready. */ if(d->size == 0 || d->bsize == 0){ if(scsicap(d->t, d->lun, &d->size, &d->bsize) != STok){ d->size = d->bsize = 0; error(Eio); } } . 190,216c for(i = 0; i < ndisk; i++) sdrdpart(&disk[i]); . 187,188c int i; . ## diffname port/devsd.c 1995/0722 ## diff -e /n/fornaxdump/1995/0417/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0722/sys/src/brazil/port/devsd.c 63c static int types[] = { . 12c enum { . ## diffname port/devsd.c 1995/0909 ## diff -e /n/fornaxdump/1995/0722/sys/src/brazil/port/devsd.c /n/fornaxdump/1995/0909/sys/src/brazil/port/devsd.c 149c if((scratch[2] & 0x0F) != 0x02 && (scratch[2] & 0x0F) != 0) . ## diffname port/devsd.c 1996/0223 ## diff -e /n/fornaxdump/1995/0909/sys/src/brazil/port/devsd.c /n/fornaxdump/1996/0223/sys/src/brazil/port/devsd.c 10d ## diffname port/devsd.c 1996/0315 ## diff -e /n/fornaxdump/1996/0223/sys/src/brazil/port/devsd.c /n/fornaxdump/1996/0315/sys/src/brazil/port/devsd.c 334c switch(parsefields(line[i], field, 3, " ")) { . 331c n = parsefields(b, line, Npart+2, "\n"); . ## diffname port/devsd.c 1996/0607 ## diff -e /n/fornaxdump/1996/0315/sys/src/brazil/port/devsd.c /n/fornaxdump/1996/0607/sys/src/brazil/port/devsd.c 415c buggery: . 407a if(x < 0){ len = -1; goto buggery; } . 399a if(x < 0){ len = -1; goto buggery; } . 390a if(x < 0){ len = -1; goto buggery; } . 382,386c return scsierrstr(STnomem); . 367,369d 353c d->partok = 1; return STok; . 334,348c if(parsefields(line[i], field, 3, " ") != 3) break; if(p >= &d->table[Npart]) break; 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++; . 319,324d 309,311d 304,307c return scsierrstr(STnomem); . 301a p->end = d->size + 1; if((d->inquire[0] & 0x1F) == TypeCD) return STok; . 298c return scsierrstr(n); . 296c n = scsicap(d->t, d->lun, &d->size, &d->bsize); if(n != STok){ . 289,293c * If the drive wasn't ready when a read-capacity was tried * earlier (in sdinit()), try again. . 287a if(d->partok) return STok; p = d->table; strcpy(p->name, "disk"); p->beg = 0; p->end = 0; d->npart = 1; . 280c static int . 270a Disk *d; d = &disk[DRIVE(c->qid)]; if((d->inquire[0] & 0x1F) == TypeCD) error(Eperm); . 250a qunlock(d); } . 249c if((c->mode&3) != OREAD && strcmp(p->name, "partition") == 0){ qlock(d); d->partok = 0; . 190,191c for(i = 0; i < ndisk; i++){ qlock(&disk[i]); if(disk[i].partok == 0) sdrdpart(&disk[i]); qunlock(&disk[i]); } . 140,142d 60c static int sdrdpart(Disk*); . 49a int partok; ulong version; . ## diffname port/devsd.c 1996/0710 ## diff -e /n/fornaxdump/1996/0607/sys/src/brazil/port/devsd.c /n/fornaxdump/1996/0710/sys/src/brazil/port/devsd.c 181a scsifree(scratch); . 127c nbytes = 0xFF; . 109a scratch = scsialloc(0xFF); . 106c uchar *scratch, type; . ## diffname port/devsd.c 1996/1225 ## diff -e /n/fornaxdump/1996/0710/sys/src/brazil/port/devsd.c /n/fornaxdump/1996/1225/sys/src/brazil/port/devsd.c 72c sdgen(Chan *c, Dirtab*, int, int s, Dir *dirp) . ## diffname port/devsd.c 1997/0327 ## diff -e /n/fornaxdump/1996/1225/sys/src/brazil/port/devsd.c /n/emeliedump/1997/0327/sys/src/brazil/port/devsd.c 349c if(parsefields(line[i], field, nelem(field), " ") != 3) . 346c n = parsefields(b, line, nelem(line), "\n"); . 289,293c Dev sddevtab = { devreset, sdinit, sdattach, devclone, sdwalk, sdstat, sdopen, devcreate, sdclose, sdread, devbread, sdwrite, devbwrite, devremove, devwstat, }; . 271,277c static long . 262c static long . 225,243c static void . 219c static Chan* . 213c static void . 201,207c static int . 186c static Chan* . 145c nbytes = 0xFF; . 97,102c static void . ## diffname port/devsd.c 1997/0408 ## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/devsd.c /n/emeliedump/1997/0408/sys/src/brazil/port/devsd.c 254a 'w', "sd", . ## diffname port/devsd.c 1998/0319 ## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/devsd.c /n/emeliedump/1998/0319/sys/src/brazil/port/devsd.c 245a ulong offset = off; . 243c sdwrite(Chan *c, char *a, long n, vlong off) . 235a ulong offset = off; . 234c sdread(Chan *c, void *a, long n, vlong off) . ## diffname port/devsd.c 1998/0325 ## diff -e /n/emeliedump/1998/0319/sys/src/brazil/port/devsd.c /n/emeliedump/1998/0325/sys/src/brazil/port/devsd.c 358a ulong offset = off; . 353c sdio(Chan *c, int write, char *a, ulong len, vlong off) . 248d 245c sdwrite(Chan *c, char *a, long n, vlong offset) . 236d 234c sdread(Chan *c, void *a, long n, vlong offset) . 63c static long sdio(Chan*, int, char*, ulong, vlong); . ## diffname port/devsd.c 1998/0327 ## diff -e /n/emeliedump/1998/0325/sys/src/brazil/port/devsd.c /n/emeliedump/1998/0327/sys/src/brazil/port/devsd.c 376c offset = off % d->bsize; . 362,363c block = (off / d->bsize) + p->beg; n = (off + len + d->bsize - 1) / d->bsize + p->beg - block; . 357c ulong offset; . 252c return sdio(c, 1, a, n, off); . 244c sdwrite(Chan *c, char *a, long n, vlong off) . 240c return sdio(c, 0, a, n, off); . 234c sdread(Chan *c, void *a, long n, vlong off) . ## diffname port/devsd.c 1998/0512 ## diff -e /n/emeliedump/1998/0327/sys/src/brazil/port/devsd.c /n/emeliedump/1998/0512/sys/src/brazil/port/devsd.c 192c . ## diffname port/devsd.c 1998/0930 ## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/devsd.c /n/emeliedump/1998/0930/sys/src/brazil/port/devsd.c 144a } . 143c switch(scratch[2] & 0x0F){ case 0x00: case 0x01: case 0x02: break; case 0x06: if(scratch[12] == 0x28 && scratch[13] == 0) break; if(scratch[12] == 0x29 && scratch[13] == 0) break; /*FALLTHROUGH*/ default: . 124a . ## diffname port/devsd.c 1998/1022 ## diff -e /n/emeliedump/1998/0930/sys/src/brazil/port/devsd.c /n/emeliedump/1998/1022/sys/src/brazil/port/devsd.c 93c l = (p->end - p->beg) * (vlong)d->bsize; devdir(c, qid, name, l, eve, 0666, dirp); . 78a vlong l; . ## diffname port/devsd.c 1999/0228 ## diff -e /n/emeliedump/1998/1022/sys/src/brazil/port/devsd.c /n/emeliedump/1999/0228/sys/src/brazil/port/devsd.c 155c if(scratch[12] == 0x29 && !scratch[13]) . 153c if(scratch[12] == 0x28 && !scratch[13]) . 135,140c * Read-capacity is mandatory for TypeDA, TypeMO and * TypeCD. It may return 'not ready' if TypeDA is not * spun up, TypeMO or TypeCD are not loaded or just * plain slow getting their act together after a reset. * If 'not ready' comes back, try starting a TypeDA and * punt the get capacity until the drive is attached. . ## diffname port/devsd.c 1999/0320 ## diff -e /n/emeliedump/1999/0228/sys/src/brazil/port/devsd.c /n/emeliedump/1999/0320/sys/src/brazil/port/devsd.c 260c sdwrite(Chan *c, void *a, long n, vlong off) . ## diffname port/devsd.c 1999/0507 ## diff -e /n/emeliedump/1999/0320/sys/src/brazil/port/devsd.c /n/emeliedump/1999/0507/sys/src/brazil/port/devsd.c 45c int lun; . ## diffname port/devsd.c 1999/0728 ## diff -e /n/emeliedump/1999/0507/sys/src/brazil/port/devsd.c /n/emeliedump/1999/0728/sys/src/brazil/port/devsd.c 73a . ## diffname port/devsd.c 1999/1230 ## diff -e /n/emeliedump/1999/0728/sys/src/brazil/port/devsd.c /n/emeliedump/1999/1230/sys/src/9/port/devsd.c 81a if(s == DEVDOTDOT){ devdir(c, qid, "#w", 0, eve, 0555, dirp); return 1; } . ## diffname port/devsd.c 2000/0104 ## diff -e /n/emeliedump/1999/1230/sys/src/9/port/devsd.c /n/emeliedump/2000/0104/sys/src/9/port/devsd.c 349d 344a n = parsefields(b, line, nelem(line), "\n"); if(n <= 0 || strncmp(line[0], MAGIC, sizeof(MAGIC)-1) != 0){ /* try the last */ scsibio(d->t, d->lun, SCSIread, b, 1, d->bsize, d->table[0].end-1); b[d->bsize-1] = '\0'; n = parsefields(b, line, nelem(line), "\n"); /* only point partition file at last sector if there is one there */ if(n > 0 && strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){ d->table[1].beg++; d->table[1].end++; } } . 343c /* * Read second last sector from disk, null terminate. * The last sector used to hold the partition tables. * However, this sector is special on some PC's so we've * started to use the second last sector as the partition * table instead. To avoid reconfiguring all our old systems * we still check if there is a valid partition table in * the last sector if none is found in the second last. */ scsibio(d->t, d->lun, SCSIread, b, 1, d->bsize, d->table[0].end-2); . 338,339c p->beg = d->table[0].end - 2; p->end = d->table[0].end - 1; . 74d ## diffname port/devsd.c 2000/0308 ## diff -e /n/emeliedump/2000/0104/sys/src/9/port/devsd.c /n/emeliedump/2000/0308/sys/src/9/port/devsd.c 371c if(getfields(line[i], field, nelem(field), 1, " ") != 3) . 358c n = getfields(b, line, nelem(line), 1, "\n"); . 353c n = getfields(b, line, nelem(line), 1, "\n"); . ## diffname port/devsd.c 2000/0506 ## diff -e /n/emeliedump/2000/0308/sys/src/9/port/devsd.c /n/emeliedump/2000/0506/sys/src/9/port/devsd.c 461a Dev sddevtab = { 'S', "sd", sdreset, devinit, sdattach, sdclone, sdwalk, sdstat, sdopen, devcreate, sdclose, sdread, devbread, sdwrite, devbwrite, devremove, sdwstat, }; . 458,460c if(unit->changed) error(Enonexist); pp = &unit->part[PART(c->qid)]; if(!pp->valid) error(Enonexist); if(strcmp(up->user, pp->user) && !iseve()) error(Eperm); convM2D(dp, &d); strncpy(pp->user, d.uid, NAMELEN); pp->perm = d.mode&0777; qunlock(&unit->ctl); poperror(); . 444,455c return n; } static void sdwstat(Chan* c, char* dp) { Dir d; SDpart *pp; SDunit *unit; if((c->qid.path & CHDIR) || TYPE(c->qid) != Qpart) error(Eperm); unit = sdunit[UNIT(c->qid)]; qlock(&unit->ctl); if(waserror()){ qunlock(&unit->ctl); nexterror(); . 438,442c break; case Qpart: return sdbio(c, 1, a, n, off); . 432,436c else{ if(unit->pid != up->pid) error(Eperm); if(unit->state != Rawdata) error(Ebadusefd); unit->state = Rawstatus; unit->req->write = 1; return sdrio(unit->req, a, n); . 430a if((req = malloc(sizeof(SDreq))) == nil){ qunlock(&unit->raw); error(Enomem); } req->unit = unit; memmove(req->cmd, a, n); req->clen = n; req->flags = SDnosense; req->status = ~0; unit->req = req; unit->pid = up->pid; unit->state = Rawdata; . 425,429c if(n < 6 || n > sizeof(req->cmd)){ qunlock(&unit->raw); error(Ebadarg); . 413,423c if(cb->nf < 1) error(Ebadctl); if(strcmp(cb->f[0], "part") == 0){ if(cb->nf != 4 || unit->npart >= SDnpart) error(Ebadctl); if(unit->sectors == 0 && !sdinitpart(unit)) error(Eio); start = strtoul(cb->f[2], 0, 0); end = strtoul(cb->f[3], 0, 0); sdaddpart(unit, cb->f[1], start, end); } else if(strcmp(cb->f[0], "delpart") == 0){ if(cb->nf != 2 || unit->part == nil) error(Ebadctl); sddelpart(unit, cb->f[1]); } else if(unit->dev->ifc->wctl) unit->dev->ifc->wctl(unit, cb); else error(Ebadctl); qunlock(&unit->ctl); poperror(); free(cb); break; case Qraw: unit = sdunit[UNIT(c->qid)]; if(canqlock(&unit->raw)){ if(unit->state != Rawcmd){ qunlock(&unit->raw); error(Ebadusefd); . 403,411c qlock(&unit->ctl); if(waserror()){ qunlock(&unit->ctl); free(cb); nexterror(); } if(unit->changed) error(Eio); . 400,401c switch(TYPE(c->qid)){ default: error(Eperm); case Qctl: cb = parsecmd(a, n); unit = sdunit[UNIT(c->qid)]; . 394,398c Cmdbuf *cb; SDreq *req; SDunit *unit; ulong end, start; . 392c sdwrite(Chan *c, void *a, long n, vlong off) . 386,388c return 0; . 383,384d 381a if(unit->pid != up->pid) error(Eperm); if(unit->state == Rawdata){ unit->state = Rawstatus; return sdrio(unit->req, a, n); } else if(unit->state == Rawstatus){ status = unit->req->status; unit->pid = 0; unit->state = Rawcmd; free(unit->req); unit->req = nil; qunlock(&unit->raw); return readnum(0, a, n, status, NUMSIZE); } break; case Qpart: return sdbio(c, 0, a, n, off); . 364,380c qunlock(&unit->ctl); l = readstr(offset, a, n, p); free(p); return l; case Qraw: unit = sdunit[UNIT(c->qid)]; if(canqlock(&unit->raw)){ qunlock(&unit->raw); error(Ebadusefd); . 342,362c offset = off; switch(TYPE(c->qid)){ default: error(Eperm); case Qtopdir: case Qunitdir: return devdirread(c, a, n, 0, 0, sdgen); case Qctl: unit = sdunit[UNIT(c->qid)]; p = malloc(READSTR); l = snprint(p, READSTR, "inquiry %.48s\n", (char*)unit->inquiry+8); qlock(&unit->ctl); if(!unit->changed && unit->sectors){ /* * If there's a device specific routine it must * provide all information pertaining to night geometry * and the garscadden trains. */ if(unit->dev->ifc->rctl) l += unit->dev->ifc->rctl(unit, p+l, READSTR-l); else l += snprint(p+l, READSTR-l, "geometry %ld %ld\n", unit->sectors, unit->secsize); pp = unit->part; for(i = 0; i < SDnpart; i++){ if(pp->valid) l += snprint(p+l, READSTR-l, "part %.*s %lud %lud\n", NAMELEN, pp->name, pp->start, pp->end); pp++; } . 335,340c static long sdread(Chan *c, void *a, long n, vlong off) { char *p; SDpart *pp; SDunit *unit; ulong offset; int i, l, status; . 331,333c return r->rlen; } . 328,329c if(!r->write && r->rlen > 0) memmove(a, data, r->rlen); if(data != nil){ sdfree(data); r->data = nil; } poperror(); . 326c if(r->unit->dev->ifc->rio(r) != SDok) error(Eio); . 323a nexterror(); . 314,322c if(waserror()){ if(data != nil){ sdfree(data); r->data = nil; . 308,312c data = nil; if(n){ if((data = sdmalloc(n)) == nil) error(Enomem); if(r->write) memmove(data, a, n); } r->data = data; r->dlen = n; . 305,306c if(n >= SDmaxio || n < 0) error(Etoobig); . 300,303c void *data; . 297,298c static long sdrio(SDreq* r, void* a, long n) . 280,295c return len; } . 276,278c if(unit->inquiry[1] & 0x80){ qunlock(&unit->ctl); poperror(); } . 271,274c offset = off%unit->secsize; if(write){ if(offset || (len%unit->secsize)){ if((l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno)) < 0) error(Eio); if(l < (nb*unit->secsize)){ nb = l/unit->secsize; l = nb*unit->secsize - offset; if(len > l) len = l; } } memmove(b+offset, a, len); if((l = unit->dev->ifc->bio(unit, 0, 1, b, nb, bno)) < 0) error(Eio); if(l < offset) len = 0; else if(len > l - offset) len = l - offset; } else { if((l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno)) < 0) error(Eio); if(l < offset) len = 0; else if(len > l - offset) len = l - offset; memmove(a, b+offset, len); } sdfree(b); poperror(); . 269c b = sdmalloc(nb*unit->secsize); if(b == nil) error(Enomem); if(waserror()){ sdfree(b); nexterror(); } . 264,267c /* * Check the request is within bounds. * Removeable drives are locked throughout the I/O * in case the media changes unexpectedly. * Non-removeable drives are not locked during the I/O * to allow the hardware to optimise if it can; this is * a little fast and loose. * It's assumed that non-removeable media parameters * (sectors, secsize) can't change once the drive has * been brought online. */ pp = &unit->part[PART(c->qid)]; bno = (off/unit->secsize) + pp->start; nb = ((off+len+unit->secsize-1)/unit->secsize) + pp->start - bno; max = SDmaxio/unit->secsize; if(nb > max) nb = max; if(bno+nb > pp->end) nb = pp->end - bno; if(bno >= pp->end || nb == 0){ if(write) error(Eio); qunlock(&unit->ctl); poperror(); return 0; } if(!(unit->inquiry[1] & 0x80)){ qunlock(&unit->ctl); poperror(); } . 261,262c qlock(&unit->ctl); if(waserror()){ qunlock(&unit->ctl); nexterror(); } if(unit->changed) error(Eio); . 258,259c unit = sdunit[UNIT(c->qid)]; . 256a long l; uchar *b; SDpart *pp; SDunit *unit; ulong bno, max, nb, offset; . 255c sdbio(Chan* c, int write, char* a, long len, vlong off) . 244,250c switch(TYPE(c->qid)){ default: break; case Qraw: unit = sdunit[UNIT(c->qid)]; if(canqlock(&unit->raw) || unit->pid == up->pid){ unit->pid = 0; unit->state = Rawcmd; qunlock(&unit->raw); } break; case Qpart: unit = sdunit[UNIT(c->qid)]; qlock(&unit->ctl); if(waserror()){ qunlock(&unit->ctl); c->flag &= ~COPEN; nexterror(); } pp = &unit->part[PART(c->qid)]; pp->nopen--; unit->nopen--; if(unit->nopen == 0) unit->changed = 0; qunlock(&unit->ctl); poperror(); break; . 242a if(!(c->flag & COPEN)) return; . 238,239c SDpart *pp; SDunit *unit; . 236c sdclose(Chan* c) . 232c SDpart *pp; SDunit *unit; c = devopen(c, omode, 0, 0, sdgen); switch(TYPE(c->qid)){ default: break; case Qpart: unit = sdunit[UNIT(c->qid)]; qlock(&unit->ctl); if(waserror()){ qunlock(&unit->ctl); c->flag &= ~COPEN; nexterror(); } if(unit->changed) error(Eio); pp = &unit->part[PART(c->qid)]; pp->nopen++; unit->nopen++; qunlock(&unit->ctl); poperror(); break; } return c; . 230c sdopen(Chan* c, int omode) . 226c devstat(c, db, nil, 0, sdgen); . 224c sdstat(Chan* c, char* db) . 220c return devwalk(c, name, nil, 0, sdgen); . 218c sdwalk(Chan* c, char* name) . 216a static Chan* sdclone(Chan* c, Chan* nc) { return devclone(c, nc); } . 214c if(spec[0] != 's' || spec[1] != 'd') error(Ebadspec); idno = spec[2]; subno = strtol(&spec[3], &p, 0); if(p == &spec[3]) error(Ebadspec); for(sdev = sdlist; sdev != nil; sdev = sdev->next){ if(sdev->idno == idno && subno < sdev->nunit) break; } if(sdev == nil || sdgetunit(sdev, subno) == nil) error(Enonexist); c = devattach(sddevtab.dc, spec); c->qid = (Qid){QID(sdev->index+subno, 0, Qunitdir)|CHDIR, 0}; c->dev = sdev->index+subno; return c; . 207,211c if(sdnunit == 0 || *spec == '\0'){ c = devattach(sddevtab.dc, spec); c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; return c; . 205c Chan *c; char *p; SDev *sdev; int idno, subno; . 203c sdattach(char* spec) . 199c return -1; . 197a if(s < sdnunit){ if(sdunit[s] == nil && sdindex2unit(s) == nil) return 0; q = (Qid){QID(s, 0, Qunitdir)|CHDIR, 0}; devdir(c, q, sdunit[s]->name, 0, eve, 0555, dp); return 1; } s -= sdnunit; return sd1gen(c, s+Qtopbase, dp); case Qunitdir: if(s == DEVDOTDOT){ q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; snprint(name, NAMELEN, "#%C", sddevtab.dc); devdir(c, q, name, 0, eve, 0555, dp); return 1; } unit = sdunit[UNIT(c->qid)]; qlock(&unit->ctl); if(!unit->changed && unit->sectors == 0) sdinitpart(unit); i = s+Qunitbase; if(i < Qpart){ r = sd2gen(c, i, dp); qunlock(&unit->ctl); return r; } i -= Qpart; if(unit->npart == 0 || i >= SDnpart){ qunlock(&unit->ctl); break; } pp = &unit->part[i]; if(unit->changed || !pp->valid){ qunlock(&unit->ctl); return 0; } l = (pp->end - pp->start) * (vlong)unit->secsize; q = (Qid){QID(UNIT(c->qid), i, Qpart), c->qid.vers}; devdir(c, q, pp->name, l, pp->user, pp->perm, dp); qunlock(&unit->ctl); return 1; case Qraw: case Qctl: case Qpart: unit = sdunit[UNIT(c->qid)]; qlock(&unit->ctl); r = sd2gen(c, TYPE(c->qid), dp); qunlock(&unit->ctl); return r; default: break; . 196a pp = &unit->part[PART(c->qid)]; l = (pp->end - pp->start) * (vlong)unit->secsize; q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qpart), c->qid.vers}; devdir(c, q, pp->name, l, pp->user, pp->perm, dp); return 1; } return -1; } static int sd1gen(Chan*, int i, Dir*) { switch(i){ default: return -1; } return -1; } static int sdgen(Chan* c, Dirtab*, int, int s, Dir* dp) { Qid q; vlong l; int i, r; SDpart *pp; SDunit *unit; char name[NAMELEN]; switch(TYPE(c->qid)){ case Qtopdir: if(s == DEVDOTDOT){ q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; snprint(name, NAMELEN, "#%C", sddevtab.dc); devdir(c, q, name, 0, eve, 0555, dp); return 1; . 194,195c /* * Legacy and option code goes here. This will be hard... */ /* * The maximum number of possible units is known, allocate * placeholders for their datastructures; the units will be * probed and structures allocated when attached. * Allocate controller names for the different types. */ if(sdnunit == 0) return; if((sdunit = malloc(sdnunit*sizeof(SDunit*))) == nil) return; if((sdunitflg = malloc(sdnunit*sizeof(int))) == nil){ free(sdunit); sdunit = nil; return; } for(i = 0; sdifc[i] != nil; i++){ if(sdifc[i]->id) sdifc[i]->id(sdlist); } } static int sd2gen(Chan* c, int i, Dir* dp) { Qid q; vlong l; SDpart *pp; SDunit *unit; switch(i){ case Qctl: q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qctl), c->qid.vers}; devdir(c, q, "ctl", 0, eve, 0640, dp); return 1; case Qraw: q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qraw), c->qid.vers}; devdir(c, q, "raw", 0, eve, 0600, dp); return 1; case Qpart: unit = sdunit[UNIT(c->qid)]; if(unit->changed) . 192a tail->index = sdnunit; sdnunit += tail->nunit; } . 186,191c static void sdreset(void) { int i; SDev *sdev, *tail; /* * Probe all configured controllers and make a list * of devices found, accumulating a possible maximum number * of units attached and marking each device with an index * into the linear top-level directory array of units. */ tail = nil; for(i = 0; sdifc[i] != nil; i++){ if(sdifc[i]->pnp == nil || (sdev = sdifc[i]->pnp()) == nil) continue; if(sdlist != nil) tail->next = sdev; else sdlist = sdev; for(tail = sdev; tail->next != nil; tail = tail->next){ sdev->index = sdnunit; sdnunit += tail->nunit; . 182,184c } . 178,180c return nil; . 173,176c /* * Associate a unit with a given index into the top-level * device directory. * The device will be probed if it has not already been * successfully accessed. */ for(sdev = sdlist; sdev != nil; sdev = sdev->next){ if(index >= sdev->index && index < sdev->index+sdev->nunit) return sdgetunit(sdev, index-sdev->index); } . 171c static SDunit* sdindex2unit(int index) { SDev *sdev; . 153,169c return unit; } . 139,151c /* * No need to lock anything here as this is only * called before the unit is made available in the * sdunit[] array. */ if(unit->dev->ifc->verify(unit) == 0){ qunlock(&sdqlock); free(unit); return nil; } sdunit[index] = unit; } qunlock(&sdqlock); . 133,137c snprint(unit->name, NAMELEN, "%s%d", sdev->name, subno); unit->subno = subno; unit->dev = sdev; . 125,131c if(sdev->enabled == 0 && sdev->ifc->enable) sdev->ifc->enable(sdev); sdev->enabled = 1; . 122,123c if(sdunitflg[index]){ qunlock(&sdqlock); return nil; } if((unit = malloc(sizeof(SDunit))) == nil){ qunlock(&sdqlock); return nil; } sdunitflg[index] = 1; . 120c * Probe the unit only once. This decision * may be a little severe and reviewed later. . 111,118c /* * Associate a unit with a given device and sub-unit * number on that device. * The device will be probed if it has not already been * successfully accessed. */ qlock(&sdqlock); index = sdev->index+subno; unit = sdunit[index]; if(unit == nil){ . 107,109c int index; SDunit *unit; . 104,105c static SDunit* sdgetunit(SDev* sdev, int subno) . 95,100c if(unit->dev->ifc->online) unit->dev->ifc->online(unit); if(unit->sectors){ sdaddpart(unit, "data", 0, unit->sectors); /* * Use partitions passed from boot program, * e.g. * sdC0=dos 63 123123/plan9 123123 456456 */ for(p = getconf(unit->name); p != nil; p = q){ if(q = strchr(p, '/')) *q++ = '\0'; nf = getfields(p, f, nelem(f), 1, " \t\r"); if(nf < 3) continue; start = strtoul(f[1], 0, 0); end = strtoul(f[2], 0, 0); if(!waserror()){ sdaddpart(unit, f[0], start, end); poperror(); } } } . 91,93d 86,89c if(unit->inquiry[0] & 0xC0) return 0; switch(unit->inquiry[0] & 0x1F){ case 0x00: /* DA */ case 0x04: /* WORM */ case 0x05: /* CD-ROM */ case 0x07: /* MO */ break; default: return 0; . 81,83c unit->sectors = unit->secsize = 0; unit->npart = 0; if(unit->part){ free(unit->part); unit->part = nil; . 74,79c int nf; ulong start, end; char *f[4], *p, *q; . 72c sdinitpart(SDunit* unit) . 65,69c unit->npart--; if(unit->npart == 0){ free(unit->part); unit->part = nil; } } . 62,63c /* * Look for the partition to delete. * Can't delete if someone still has it open. * If it's the last valid partition zap the * whole table. */ pp = unit->part; for(i = 0; i < SDnpart; i++){ if(strncmp(name, pp->name, NAMELEN) == 0) break; pp++; } if(i >= SDnpart) error(Ebadctl); if(pp->nopen) error(Einuse); pp->valid = 0; . 59,60c static void sddelpart(SDunit* unit, char* name) { int i; SDpart *pp; . 55,57c /* * Check there is a free slot and size and extent are valid. */ if(partno == -1 || start > end || end > unit->sectors) error(Eio); pp = &unit->part[partno]; pp->start = start; pp->end = end; strncpy(pp->name, name, NAMELEN); strncpy(pp->user, eve, NAMELEN); pp->perm = 0640; pp->valid = 1; unit->npart++; } . 49,53c /* * Check name not already used * and look for a free slot. */ if(unit->part != nil){ partno = -1; for(i = 0; i < SDnpart; i++){ pp = &unit->part[i]; if(!pp->valid){ if(partno == -1) partno = i; break; } if(strcmp(name, pp->name) == 0){ if(pp->start == start && pp->end == end) return; error(Ebadctl); } } } else{ if((unit->part = malloc(sizeof(SDpart)*SDnpart)) == nil) error(Enomem); partno = 0; } . 43,47c SDpart *pp; int i, partno; . 41c #define TYPE(q) ((q).path & 0x0F) #define PART(q) (((q).path>>4) & 0x0F) #define UNIT(q) (((q).path>>8) & 0xFF) #define QID(u, p, t) (((u)<<8)|((p)<<4)|(t)) static void sdaddpart(SDunit* unit, char* name, ulong start, ulong end) . 34,38c Qunitdir, /* directory per unit */ Qunitbase, Qctl = Qunitbase, Qraw, Qpart, . 31,32c enum { Qtopdir = 1, /* top level directory */ Qtopbase, . 28,29d 21,26c extern Dev sddevtab; extern SDifc* sdifc[]; static QLock sdqlock; static SDev* sdlist; static SDunit** sdunit; static int* sdunitflg; static int sdnunit; enum { Rawcmd, Rawdata, Rawstatus, . 11,19c #include "sd.h" . 4,9c #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "ureg.h" #include "../port/error.h" . 2c * Storage Device. . ## diffname port/devsd.c 2000/0515 ## diff -e /n/emeliedump/2000/0506/sys/src/9/port/devsd.c /n/emeliedump/2000/0515/sys/src/9/port/devsd.c 301a /* * BUG: no check is made here or later when a * unit is attached that the id and name are set. */ . ## diffname port/devsd.c 2000/0524 ## diff -e /n/emeliedump/2000/0515/sys/src/9/port/devsd.c /n/emeliedump/2000/0524/sys/src/9/port/devsd.c 875c if(strncmp(up->user, pp->user, NAMELEN) && !iseve()) . 626c l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno); if(l < 0) . 618c l = unit->dev->ifc->bio(unit, 0, 1, b, nb, bno); if(l < 0) . 608c l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno); if(l < 0) . 406a if(pp->user[0] == '\0') strncpy(pp->user, eve, NAMELEN); . 334a if(pp->user[0] == '\0') strncpy(pp->user, eve, NAMELEN); . 158a * This happens before /boot sets hostname so the * partitions will have the null-string for user. * The gen functions patch it up. . 112a if(strncmp(up->user, pp->user, NAMELEN) && !iseve()) error(Eperm); . 65c if(strncmp(name, pp->name, NAMELEN) == 0){ . ## diffname port/devsd.c 2000/0526 ## diff -e /n/emeliedump/2000/0524/sys/src/9/port/devsd.c /n/emeliedump/2000/0526/sys/src/9/port/devsd.c 846,849c break; case Rawstatus: unit->state = Rawcmd; free(unit->req); unit->req = nil; error(Ebadusefd); case Rawdata: . 844d 836d 832,834c if((req = malloc(sizeof(SDreq))) == nil) . 824,830c switch(unit->state){ case Rawcmd: if(n < 6 || n > sizeof(req->cmd)) . 821a . 763d 759d 747,752d 531,535c unlock(&unit->rawinuse); . 494a case Qraw: unit = sdunit[UNIT(c->qid)]; if(!canlock(&unit->rawinuse)) error(Einuse); unit->state = Rawcmd; break; . 331c devdir(c, q, "raw", 0, eve, CHEXCL|0600, dp); . ## diffname port/devsd.c 2000/0530 ## diff -e /n/emeliedump/2000/0526/sys/src/9/port/devsd.c /n/emeliedump/2000/0530/sys/src/9/port/devsd.c 165c snprint(buf, sizeof buf, "%spart", unit->name); for(p = getconf(buf); p != nil; p = q){ . 160c * sdC0part=dos 63 123123/plan9 123123 456456 . 131c char *f[4], *p, *q, buf[10]; . ## diffname port/devsd.c 2000/0531 ## diff -e /n/emeliedump/2000/0530/sys/src/9/port/devsd.c /n/emeliedump/2000/0531/sys/src/9/port/devsd.c 499a } . 498c if(!canlock(&unit->rawinuse)){ c->flag &= ~COPEN; . ## diffname port/devsd.c 2000/0607 ## diff -e /n/emeliedump/2000/0531/sys/src/9/port/devsd.c /n/emeliedump/2000/0607/sys/src/9/port/devsd.c 725,732c if(unit->dev->ifc->rctl == nil) . 723a /* * If there's a device specific routine it must * provide all information pertaining to night geometry * and the garscadden trains. */ if(unit->dev->ifc->rctl) l += unit->dev->ifc->rctl(unit, p+l, READSTR-l); . ## diffname port/devsd.c 2000/0617 ## diff -e /n/emeliedump/2000/0607/sys/src/9/port/devsd.c /n/emeliedump/2000/0617/sys/src/9/port/devsd.c 880c if(unit->vers+pp->vers != c->qid.vers) . 877,878d 798c if(cb->nf != 4) . 792c if(unit->vers != c->qid.vers) . 731c if(unit->sectors == 0) sdinitpart(unit); if(unit->sectors){ . 591d 577c pp = &unit->part[PART(c->qid)]; if(unit->vers+pp->vers != c->qid.vers) . 573c while(waserror()){ /* notification of media change; go around again */ if(strcmp(up->error, Eio) == 0 && unit->sectors == 0 && nchange++ == 0){ sdinitpart(unit); continue; } /* other errors; give up */ . 571a nchange = 0; . 563a int nchange; . 542,557d 527d 515,516c c->qid.vers = unit->vers+pp->vers; . 512,513d 497a c->qid.vers = unit->vers; . 495a case Qctl: unit = sdunit[UNIT(c->qid)]; c->qid.vers = unit->vers; break; . 414c q = (Qid){QID(UNIT(c->qid), i, Qpart), unit->vers+pp->vers}; . 409c if(!pp->valid){ . 404c if(unit->part == nil || i >= SDnpart){ . 396a . 395c /* * Check for media change. * If one has already been detected, sectors will be zero. * If there is one waiting to be detected, online will return > 1. * Online is a bit of a large hammer but does the job. */ if(unit->sectors == 0 || (unit->dev->ifc->online && unit->dev->ifc->online(unit) > 1)) . 340c q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qpart), unit->vers+pp->vers}; . 335,337d 331c q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qraw), unit->vers}; . 327c q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qctl), unit->vers}; . 324a unit = sdunit[UNIT(c->qid)]; . 136,137c for(i = 0; i < SDnpart; i++){ unit->part[i].valid = 0; unit->part[i].vers++; } . 134d 132a unit->vers++; . 129c int i, nf; . 118,123c pp->vers++; . 115,116d 102,103d 90d 81c if(partno == -1) error(Ebadctl); if(start > end || end > unit->sectors) . ## diffname port/devsd.c 2000/0706 ## diff -e /n/emeliedump/2000/0617/sys/src/9/port/devsd.c /n/emeliedump/2000/0706/sys/src/9/port/devsd.c 880,881c strncpy(perm->user, d.uid, NAMELEN); perm->perm = (perm->perm & ~0777) | (d.mode & 0777); . 878a if(strncmp(up->user, perm->user, NAMELEN) && !iseve()) error(Eperm); . 877a case Qctl: perm = &unit->ctlperm; break; case Qraw: perm = &unit->rawperm; break; case Qpart: pp = &unit->part[PART(c->qid)]; if(unit->vers+pp->vers != c->qid.vers) error(Enonexist); perm = &pp->SDperm; break; } . 873,876c switch(TYPE(c->qid)){ default: . 863c if(c->qid.path & CHDIR) . 860a SDperm *perm; . 394c if(unit->sectors == 0 || (unit->dev->ifc->online && unit->dev->ifc->online(unit) > 1)) . 391c * If there is one waiting to be detected, online * will return > 1. . 373c if(unit->user[0] == '\0') strncpy(unit->user, eve, NAMELEN); devdir(c, q, unit->name, 0, unit->user, unit->perm, dp); . 370,371c if((unit = sdunit[s]) == nil){ if((unit = sdindex2unit(s)) == nil) return 0; } . 327c perm = &unit->rawperm; if(perm->user[0] == '\0'){ strncpy(perm->user, eve, NAMELEN); perm->perm = CHEXCL|0600; } devdir(c, q, "raw", 0, perm->user, perm->perm, dp); . 323c perm = &unit->ctlperm; if(perm->user[0] == '\0'){ strncpy(perm->user, eve, NAMELEN); perm->perm = 0640; } devdir(c, q, "ctl", 0, perm->user, perm->perm, dp); . 316a SDperm *perm; . 213a strncpy(unit->user, eve, NAMELEN); unit->perm = 0555; . ## diffname port/devsd.c 2000/0809 ## diff -e /n/emeliedump/2000/0706/sys/src/9/port/devsd.c /n/emeliedump/2000/0809/sys/src/9/port/devsd.c 752c for(i = 0; i < unit->npart; i++){ . 423c if(unit->part == nil || i >= unit->npart){ . 128c for(i = 0; i < unit->npart; i++){ . 110c if(i >= unit->npart) . 105c for(i = 0; i < unit->npart; i++){ . 81,83c if(partno == -1){ if((pp = malloc(sizeof(SDpart)*(unit->npart+SDnpart))) == nil) error(Enomem); memmove(pp, unit->part, sizeof(SDpart)*unit->npart); free(unit->part); unit->part = pp; partno = unit->npart; unit->npart += SDnpart; } /* * Check size and extent are valid. */ if(start > end || end > unit->sectors) . 79c * If no free slot found then increase the * array size (can't get here with unit->part == nil). . 74a unit->npart = SDnpart; . 58c for(i = 0; i < unit->npart; i++){ . ## diffname port/devsd.c 2000/1129 ## diff -e /n/emeliedump/2000/0809/sys/src/9/port/devsd.c /n/emeliedump/2000/1129/sys/src/9/port/devsd.c 880c qunlock(&unit->raw); poperror(); return n; . 878c n = sdrio(unit->req, a, n); . 849a qlock(&unit->raw); if(waserror()){ qunlock(&unit->raw); nexterror(); } . 809a case Qlog: error(Ebadctl); . 789,791c i = readnum(0, a, n, status, NUMSIZE); } else i = 0; qunlock(&unit->raw); poperror(); return i; . 782c i = sdrio(unit->req, a, n); . 779a qlock(&unit->raw); if(waserror()){ qunlock(&unit->raw); nexterror(); } . 743a case Qlog: unit = sdunit[UNIT(c->qid)]; return logread(&unit->log, a, 0, n); . 636a 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); } . 570a case Qlog: unit = sdunit[UNIT(c->qid)]; logclose(&unit->log); break; . 527a case Qlog: unit = sdunit[UNIT(c->qid)]; logopen(&unit->log); break; . 454a case Qlog: . 336a 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; . 231a unit->log.logmask = ~0; unit->log.nlog = 16*1024; unit->log.minread = 4*1024; . 36a Qlog, . 13c #include "../port/sd.h" . ## diffname port/devsd.c 2001/0213 ## diff -e /n/emeliedump/2000/1129/sys/src/9/port/devsd.c /n/emeliedump/2001/0213/sys/src/9/port/devsd.c 126,127d ## diffname port/devsd.c 2001/0527 ## diff -e /n/emeliedump/2001/0213/sys/src/9/port/devsd.c /n/emeliedump/2001/0527/sys/src/9/port/devsd.c 1004d 994a return n; . 989,991c n = convM2D(dp, n, &d[0], (char*)&d[1]); if(n == 0) error(Eshortstat); kstrdup(&perm->user, d[0].uid); perm->perm = (perm->perm & ~0777) | (d[0].mode & 0777); . 987c if(strcmp(up->user, perm->user) && !iseve()) . 960c if(c->qid.type & QTDIR) . 955c Dir d[2]; . 952,953c static int sdwstat(Chan* c, uchar* dp, int n) . 943,944c break; . 862,865d 812,814c "part %s %lud %lud\n", pp->name, pp->start, pp->end); . 785,787d 658,677d 588,591d 580c if(c->qid.type & QTDIR) . 541,544d 525,530d 522c return devstat(c, db, n, nil, 0, sdgen); . 520c sdstat(Chan* c, uchar* db, int n) . 516c return devwalk(c, nc, name, nname, nil, 0, sdgen); . 513,514c static Walkqid* sdwalk(Chan* c, Chan* nc, char** name, int nname) . 508c mkqid(&c->qid, QID(sdev->index+subno, 0, Qunitdir), 0, QTDIR); . 490c mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR); . 467d 458,460c mkqid(&q, QID(UNIT(c->qid), i, Qpart), unit->vers+pp->vers, QTFILE); if(emptystr(pp->user)) kstrdup(&pp->user, eve); . 422,424c mkqid(&q, QID(s, 0, Qtopdir), 0, QTDIR); sprint(up->genbuf, "#%C", sddevtab.dc); devdir(c, q, up->genbuf, 0, eve, 0555, dp); . 412,414c mkqid(&q, QID(s, 0, Qunitdir), 0, QTDIR); if(emptystr(unit->user)) kstrdup(&unit->user, eve); . 402,404c mkqid(&q, QID(s, 0, Qtopdir), 0, QTDIR); sprint(up->genbuf, "#%C", sddevtab.dc); devdir(c, q, up->genbuf, 0, eve, 0555, dp); . 397d 390c sdgen(Chan* c, char*, Dirtab*, int, int s, Dir* dp) . 370,372c mkqid(&q, QID(UNIT(c->qid), PART(c->qid), Qpart), unit->vers+pp->vers, QTFILE); if(emptystr(pp->user)) kstrdup(&pp->user, eve); . 361,363c if(emptystr(perm->user)){ kstrdup(&perm->user, eve); perm->perm = DMEXCL|0600; . 359c mkqid(&q, QID(UNIT(c->qid), PART(c->qid), Qraw), unit->vers, QTFILE); . 352,353c if(emptystr(perm->user)){ kstrdup(&perm->user, eve); . 350c mkqid(&q, QID(UNIT(c->qid), PART(c->qid), Qctl), unit->vers, QTFILE); . 340,348d 231,234d 225,226c snprint(buf, sizeof(buf), "%s%d", sdev->name, subno); kstrdup(&unit->name, buf); kstrdup(&unit->user, eve); . 195a char buf[32]; . 125a if(strcmp(up->user, pp->user) && !iseve()) error(Eperm); . 120c if(strcmp(name, pp->name) == 0) . 102,103c kstrdup(&pp->name, name); kstrdup(&pp->user, eve); . 66c if(strcmp(name, pp->name) == 0){ . 42,44c #define TYPE(q) (((ulong)(q).path) & 0x0F) #define PART(q) ((((ulong)(q).path)>>4) & 0x0F) #define UNIT(q) ((((ulong)(q).path)>>8) & 0xFF) . 37d ## diffname port/devsd.c 2001/0613 ## diff -e /n/emeliedump/2001/0527/sys/src/9/port/devsd.c /n/emeliedump/2001/0613/sys/src/9/port/devsd.c 310a if(sdnunit > NUnit) sdnunit = NUnit; . 83a if(unit->npart >= NPart) error(Enomem); . 41,44c #define TYPE(q) ((((ulong)(q).path)>>TypeSHIFT) & TypeMASK) #define PART(q) ((((ulong)(q).path)>>PartSHIFT) & PartMASK) #define UNIT(q) ((((ulong)(q).path)>>UnitSHIFT) & UnitMASK) #define QID(u, p, t) (((u)<idno == base) break; if (i == ndevs) return base; base++; } return '\0'; } static int configure(char *spec, DevConf *cf) { ISAConf isa; dev_t *_devs; SDev *tail, *sdev, *(*probe)(DevConf *); char *p, name[32]; int i, added_devs; if ((p = strchr(cf->type, '/')) != nil) *p++ = '\0'; for(i = 0; sdifc[i] != nil; i++) if(!strcmp(sdifc[i]->name, cf->type)) break; if (sdifc[i] == nil) error("type not found"); if ((probe = sdifc[i]->probe) == nil) error("No probe function"); if (p) { /* Try to find the card on the ISA bus. This code really belongs in sdata and I'll move it later. Really! */ memset(&isa, 0, sizeof(isa)); isa.port = cf->ports[0].port; isa.irq = cf->interrupt; if (pcmspecial(p, &isa) < 0) error("Cannot find controller"); } qlock(&devslock); if (waserror()) { qunlock(&devslock); nexterror(); } for (i = 0; i != ndevs; i++) if ((sdev = devs[i].dt_dev) != nil && sdev->idno == *spec) break; if (i != ndevs) error(Eexist); if ((sdev = (*probe)(cf)) == nil) error("Cannot probe controller"); poperror(); added_devs = 0; tail = sdev; while (tail) { added_devs++; tail = tail->next; } _devs = (dev_t *)malloc((ndevs + added_devs) * sizeof(dev_t)); memmove(_devs, devs, ndevs * sizeof(dev_t)); free(devs); devs = _devs; while (sdev) { /* Assign `spec' to the device */ *spec = getspec(*spec); snprint(name, sizeof(name), "sd%c", *spec); kstrdup(&sdev->name, name); sdev->idno = *spec; devs[ndevs].dt_dev = sdev; devs[ndevs].dt_nunits = sdev->nunit; sdev = sdev->next; devs[ndevs].dt_dev->next = nil; ndevs++; } qunlock(&devslock); return 0; } static int unconfigure(char *spec) { int i; SDev *sdev; qlock(&devslock); if (waserror()) { qunlock(&devslock); nexterror(); } for (sdev = nil, i = 0; i != ndevs; i++) if ((sdev = devs[i].dt_dev) != nil && sdev->idno == *spec) break; if (i == ndevs) error(Enonexist); if (sdev->r.ref) error(Einuse); /* make sure no interrupts arrive anymore before removing resources */ if (sdev->enabled && sdev->ifc->disable) sdev->ifc->disable(sdev); /* we're alone and the device tab is locked; make the device unavailable */ memmove(&devs[i], &devs[ndevs - 1], sizeof(dev_t)); memset(&devs[ndevs - 1], 0, sizeof(dev_t)); ndevs--; qunlock(&devslock); poperror(); for (i = 0; i != sdev->nunit; i++) if (sdev->unit[i]) { SDunit *unit = sdev->unit[i]; free(unit->name); free(unit->user); free(unit); } if (sdev->ifc->clear) sdev->ifc->clear(sdev); return 0; } static int sdconfig(int on, char *spec, DevConf *cf) { return on? configure(spec, cf): unconfigure(spec); } . 959a decref(&sdev->r); . 930a decref(&sdev->r); . 927c sdev = sdgetdev(DEV(c->qid)); if (sdev == nil) error(Enonexist); unit = sdev->unit[UNIT(c->qid)]; . 925c error(Eperm); . 922a SDev *sdev; . 906a decref(&sdev->r); . 873a decref(&sdev->r); . 870c sdev = sdgetdev(DEV(c->qid)); if (sdev == nil) error(Enonexist); unit = sdev->unit[UNIT(c->qid)]; . 864a decref(&sdev->r); . 837a decref(&sdev->r); . 833c sdev = sdgetdev(DEV(c->qid)); if (sdev == nil) error(Enonexist); unit = sdev->unit[UNIT(c->qid)]; . 830a case Qtopctl: { confdata_t cd; char buf[256], *field[Ncmd]; int nf, i, j; memset(&cd, 0, sizeof(confdata_t)); if(n > sizeof(buf)-1) n = sizeof(buf)-1; memmove(buf, a, n); buf[n] = '\0'; cd.o_on = -1; cd.o_spec = '\0'; memset(&cd.o_cf, 0, sizeof(DevConf)); nf = getfields(buf, field, Ncmd, 1, " \t\n"); for (i = 0; i < nf; i++) { char *opt = field[i++]; if (i >= nf) error(Ebadarg); for (j = 0; j != nelem(options); j++) if (!strcmp(opt, options[j].option)) break; if (j == nelem(options)) error(Ebadarg); options[j].parse(&cd, field[i]); } if (cd.o_on < 0) error(Ebadarg); if (cd.o_on) { if (cd.o_spec == '\0' || cd.o_cf.nports == 0 || cd.o_cf.interrupt == 0 || cd.o_cf.type == nil) error(Ebadarg); } else { if (cd.o_spec == '\0') error(Ebadarg); } if (sddevtab.config == nil) error("No configuration function"); sddevtab.config(cd.o_on, cd.o_spec, &cd.o_cf); break; } . 825a SDev *sdev; . 819a typedef struct { int o_on; char *o_spec; DevConf o_cf; } confdata_t; static void parse_switch(confdata_t *cd, char *option) { if (!strcmp("on", option)) cd->o_on = 1; else if (!strcmp("off", option)) cd->o_on = 0; else error(Ebadarg); } static void parse_spec(confdata_t *cd, char *option) { if (strlen(option) > 1) error(Ebadarg); cd->o_spec = option; } static port_t * getnewport(DevConf *dc) { port_t *p; p = (port_t *)malloc((dc->nports + 1) * sizeof(port_t)); if (dc->nports > 0) { memmove(p, dc->ports, dc->nports * sizeof(port_t)); free(dc->ports); } dc->ports = p; p = &dc->ports[dc->nports++]; p->size = -1; p->port = (ulong)-1; return p; } static void parse_port(confdata_t *cd, char *option) { char *e; port_t *p; p = (cd->o_cf.nports == 0 || cd->o_cf.ports[cd->o_cf.nports -1].port != (ulong)-1)? getnewport(&cd->o_cf): &cd->o_cf.ports[cd->o_cf.nports - 1]; p->port = strtol(option, &e, 0); if (e == nil || *e != '\0') error(Ebadarg); } static void parse_size(confdata_t *cd, char *option) { char *e; port_t *p; p = (cd->o_cf.nports == 0 || cd->o_cf.ports[cd->o_cf.nports -1].size != -1)? getnewport(&cd->o_cf): &cd->o_cf.ports[cd->o_cf.nports - 1]; p->size = (int)strtol(option, &e, 0); if (e == nil || *e != '\0') error(Ebadarg); } static void parse_irq(confdata_t *cd, char *option) { char *e; cd->o_cf.interrupt = strtoul(option, &e, 0); if (e == nil || *e != '\0') error(Ebadarg); } static void parse_type(confdata_t *cd, char *option) { cd->o_cf.type = option; } static struct { char *option; void (*parse)(confdata_t *, char *); } options[] = { { "switch", parse_switch, }, { "spec", parse_spec, }, { "port", parse_port, }, { "size", parse_size, }, { "irq", parse_irq, }, { "type", parse_type, }, }; . 812a . 810a decref(&sdev->r); . 795a decref(&sdev->r); . 792c sdev = sdgetdev(DEV(c->qid)); if (sdev == nil) error(Enonexist); unit = sdev->unit[UNIT(c->qid)]; . 790a . 787a decref(&sdev->r); . 759c sdev = sdgetdev(DEV(c->qid)); if (sdev == nil) error(Enonexist); unit = sdev->unit[UNIT(c->qid)]; . 757a . 754a case Qtopstat: p = buf = malloc(READSTR); assert(p); e = p + READSTR; qlock(&devslock); for (i = 0; i != ndevs; i++) { SDev *sdev = devs[i].dt_dev; if (sdev->ifc->stat) p = sdev->ifc->stat(sdev, p, e); else p = seprint(e, "%s; no statistics available\n", sdev->name); } qunlock(&devslock); n = readstr(off, a, n, buf); free(buf); return n; . 747a SDev *sdev; . 745c char *p, *e, *buf; . 698a decref(&sdev->r); . 655a if(!(unit->inquiry[1] & 0x80)) decref(&sdev->r); /* gadverdamme! */ . 642a decref(&sdev->r); . 614a decref(&sdev->r); . 602c sdev = sdgetdev(DEV(c->qid)); if (sdev == nil) error(Enonexist); unit = sdev->unit[UNIT(c->qid)]; if (unit == nil) error(Enonexist); . 599a SDev *sdev; . 586,587c sdev = sdgetdev(DEV(c->qid)); if (sdev) { unit = sdev->unit[UNIT(c->qid)]; unlock(&unit->rawinuse); decref(&sdev->r); } . 575a SDev *sdev; . 568a decref(&sdev->r); . 556d 547d 543d 540,541d 538a if ((tp = TYPE(c->qid)) != Qctl && tp != Qraw && tp != Qpart) return c; sdev = sdgetdev(DEV(c->qid)); if (sdev == nil) error(Enonexist); unit = sdev->unit[UNIT(c->qid)]; . 536a SDev *sdev; uchar tp; . 515,516c mkqid(&c->qid, QID(sdev->idno, subno, 0, Qunitdir), 0, QTDIR); c->dev = (sdev->idno << UnitLOG) + subno; decref(&sdev->r); . 512a } incref(&sdev->r); qunlock(&devslock); . 510,511c if (i == ndevs || subno >= sdev->nunit || sdgetunit(sdev, subno) == nil) { qunlock(&devslock); . 507,508c qlock(&devslock); for (sdev = nil, i = 0; i != ndevs; i++) if ((sdev = devs[i].dt_dev) != nil && sdev->idno == idno) . 497c mkqid(&c->qid, QID(0, 0, 0, Qtopdir), 0, QTDIR); . 495c if(ndevs == 0 || *spec == '\0'){ . 493c int idno, subno, i; . 478a decref(&sdev->r); . 475c if ((sdev = sdgetdev(DEV(c->qid))) == nil) { devdir(c, q, "unavailable", 0, eve, 0, dp); return 1; } unit = sdev->unit[UNIT(c->qid)]; . 470a decref(&sdev->r); . 466c mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), i, Qpart), unit->vers+pp->vers, QTFILE); . 462a decref(&sdev->r); . 457a decref(&sdev->r); . 452a decref(&sdev->r); . 435c if ((sdev = sdgetdev(DEV(c->qid))) == nil) { devdir(c, q, "unavailable", 0, eve, 0, dp); return 1; } unit = sdev->unit[UNIT(c->qid)]; . 430c mkqid(&q, QID(0, s, 0, Qtopdir), 0, QTDIR); . 426,427c if (i == ndevs) { /* Run of the end of the list */ qunlock(&devslock); return -1; } if ((sdev = devs[i].dt_dev) == nil) { qunlock(&devslock); return 0; } incref(&sdev->r); qunlock(&devslock); if((unit = sdev->unit[s]) == nil) if((unit = sdgetunit(sdev, s)) == nil) { decref(&sdev->r); return 0; } mkqid(&q, QID(sdev->idno, s, 0, Qunitdir), 0, QTDIR); if(emptystr(unit->user)) kstrdup(&unit->user, eve); devdir(c, q, unit->name, 0, unit->user, unit->perm, dp); decref(&sdev->r); return 1; } . 415,424c if (s == 0 || s == 1) return sd1gen(c, s + Qtopbase, dp); s -= 2; qlock(&devslock); for (i = 0; i != ndevs; i++) { if (s < devs[i].dt_nunits) break; s -= devs[i].dt_nunits; . 410c mkqid(&q, QID(0, s, 0, Qtopdir), 0, QTDIR); . 408c case Qtopdir: { . 405a SDev *sdev; . 392,393c case Qtopctl: mkqid(&q, QID(0, 0, 0, Qtopctl), 0, QTFILE); devdir(c, q, "sdctl", 0, eve, 0640, dp); return 1; case Qtopstat: mkqid(&q, QID(0, 0, 0, Qtopstat), 0, QTFILE); devdir(c, q, "sdstat", 0, eve, 0640, dp); return 1; . 390a Qid q; . 389c sd1gen(Chan* c, int i, Dir* dp) . 383,385c rv = 1; break; } decref(&sdev->r); return rv; . 379c mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qpart), unit->vers+pp->vers, QTFILE); . 375c rv = 1; break; . 368c mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qraw), unit->vers, QTFILE); . 366c rv = 1; break; . 359c mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qctl), unit->vers, QTFILE); . 356c sdev = sdgetdev(DEV(c->qid)); assert(sdev); unit = sdev->unit[UNIT(c->qid)]; rv = -1; . 354a SDev *sdev; int rv; . 344a /* * The IDs have been set, unlink the sdlist and copy the spec to * the devtab. */ devs = (dev_t *)malloc(ndevs * sizeof(dev_t)); memset(devs, 0, ndevs * sizeof(dev_t)); i = 0; while (sdlist != nil) { devs[i].dt_dev = sdlist; devs[i].dt_nunits = sdlist->nunit; sdlist = sdlist->next; devs[i].dt_dev->next = nil; i++; } . 328,336d 326c if(ndevs == 0) . 315c . 308,313c for(tail = sdev; tail->next != nil; tail = tail->next) ndevs++; ndevs++; . 300c tail = sdlist = nil; . 292c SDev *sdev, *tail, *sdlist; . 268,287d 263,264c qunlock(&sdev->unitlock); . 261c sdev->unit[subno] = unit; . 257c qunlock(&sdev->unitlock); . 238c sdev->unitflg[subno] = 1; . 235c qunlock(&sdev->unitlock); . 230,231c if(sdev->unitflg[subno]){ qunlock(&sdev->unitlock); . 222,224c qlock(&sdev->unitlock); if (subno > sdev->nunit) { qunlock(&sdev->unitlock); return nil; } unit = sdev->unit[subno]; . 212d 208a static SDev * sdgetdev(int idno) { SDev *sdev; int i; qlock(&devslock); for (i = 0; i != ndevs; i++) if (devs[i].dt_dev->idno == idno) break; if (i == ndevs) sdev = nil; else { sdev = devs[i].dt_dev; incref(&sdev->r); } qunlock(&devslock); return sdev; } . 60a . 59c #define DEV(q) ((((ulong)(q).path)>>DevSHIFT) & DevMASK) #define QID(d,u, p, t) (((d)<qid), dp); . 327a } tail->unit = (SDunit **)malloc(tail->nunit * sizeof(SDunit *)); tail->unitflg = (int *)malloc(tail->nunit * sizeof(int)); . 326c for(tail = sdev; tail->next != nil; tail = tail->next) { tail->unit = (SDunit **)malloc(tail->nunit * sizeof(SDunit *)); tail->unitflg = (int *)malloc(tail->nunit * sizeof(int)); assert(tail->unit && tail->unitflg); . ## diffname port/devsd.c 2001/0911 ## diff -e /n/emeliedump/2001/0907/sys/src/9/port/devsd.c /n/emeliedump/2001/0911/sys/src/9/port/devsd.c 1368a sdev->unit = (SDunit **)malloc(sdev->nunit * sizeof(SDunit *)); sdev->unitflg = (int *)malloc(sdev->nunit * sizeof(int)); assert(sdev->unit && sdev->unitflg); . ## diffname port/devsd.c 2001/0924 ## diff -e /n/emeliedump/2001/0911/sys/src/9/port/devsd.c /n/emeliedump/2001/0924/sys/src/9/port/devsd.c 730c if(strcmp(up->errstr, Eio) == 0 && unit->sectors == 0 && nchange++ == 0){ . ## diffname port/devsd.c 2001/1106 ## diff -e /n/emeliedump/2001/0924/sys/src/9/port/devsd.c /n/emeliedump/2001/1106/sys/src/9/port/devsd.c 1277a free(d); . 1275,1276c if(!emptystr(d[0].uid)) kstrdup(&perm->user, d[0].uid); if(d[0].mode != ~0UL) perm->perm = (perm->perm & ~0777) | (d[0].mode & 0777); . 1271a d = smalloc(sizeof(Dir)+n); . 1247a free(d); . 1246a d = nil; . 1233c Dir *d; . ## diffname port/devsd.c 2001/1117 ## diff -e /n/emeliedump/2001/1106/sys/src/9/port/devsd.c /n/emeliedump/2001/1117/sys/src/9/port/devsd.c 1103c nf = tokenize(buf, field, Ncmd); . 208c nf = tokenize(p, f, nelem(f)); . ## diffname port/devsd.c 2002/0109 ## diff -e /n/emeliedump/2001/1117/sys/src/9/port/devsd.c /n/emeliedump/2002/0109/sys/src/9/port/devsd.c 1450a devshutdown, . ## diffname port/devsd.c 2002/0316 ## diff -e /n/emeliedump/2002/0109/sys/src/9/port/devsd.c /n/emeliedump/2002/0316/sys/src/9/port/devsd.c 1442c if(on) return configure(spec, cf); return unconfigure(spec); . 1440c sdconfig(int on, char* spec, DevConf* cf) . 1434c if(sdev->ifc->clear) . 1425,1426c for(i = 0; i != sdev->nunit; i++) if(sdev->unit[i]){ . 1414c if(sdev->enabled && sdev->ifc->disable) . 1410c if(sdev->r.ref) . 1407c if(i == ndevs) . 1403,1404c sdev = nil; for(i = 0; i != ndevs; i++) if((sdev = devs[i].dt_dev) != nil && sdev->idno == *spec) . 1398c if(waserror()){ . 1392c unconfigure(char* spec) . 1376c sdev->unit = (SDunit **)malloc(sdev->nunit * sizeof(SDunit*)); . 1370c while(sdev){ . 1365c _devs = (dev_t*)malloc((ndevs + added_devs) * sizeof(dev_t)); . 1360c while(tail){ . 1354c if((sdev = (*probe)(cf)) == nil) . 1351c if(i != ndevs) . 1348,1349c for(i = 0; i != ndevs; i++) if((sdev = devs[i].dt_dev) != nil && sdev->idno == *spec) . 1343c if(waserror()){ . 1338c if(pcmspecial(p, &isa) < 0) . 1331c if(p){ . 1328c if((probe = sdifc[i]->probe) == nil) . 1325c if(sdifc[i] == nil) . 1318c if((p = strchr(cf->type, '/')) != nil) . 1314c SDev *tail, *sdev, *(*probe)(DevConf*); . 1310c configure(char* spec, DevConf* cf) . 1302c if(i == ndevs) . 1298,1299c for(i = 0; i != ndevs; i++) if((sdev = devs[i].dt_dev) != nil && (char)sdev->idno == base) . 1294c while(1){ . 1180c if(sdev == nil) . 1130c if(sddevtab.config == nil) . 1125,1126c else{ if(cd.o_spec == '\0') . 1120,1121c if(cd.o_on){ if(cd.o_spec == '\0' || cd.o_cf.nports == 0 || . 1117c if(cd.o_on < 0) . 1112c if(j == nelem(options)) . 1108,1109c for(j = 0; j != nelem(options); j++) if(!strcmp(opt, options[j].option)) . 1106c if(i >= nf) . 1104c for(i = 0; i < nf; i++){ . 1078c sdwrite(Chan* c, void* a, long n, vlong off) . 1073c { "irq", parse_irq, }, . 1069c { "switch", parse_switch, }, . 1066,1067c char *option; void (*parse)(confdata_t*, char*); . 1060c parse_type(confdata_t* cd, char* option) . 1055c if(e == nil || *e != '\0') . 1050c parse_irq(confdata_t* cd, char* option) . 1042,1045c if(cd->o_cf.nports == 0 || cd->o_cf.ports[cd->o_cf.nports-1].size != -1) p = getnewport(&cd->o_cf); else p = &cd->o_cf.ports[cd->o_cf.nports-1]; p->size = (int)strtol(option, &e, 0); if(e == nil || *e != '\0') . 1037c parse_size(confdata_t* cd, char* option) . 1032c if(e == nil || *e != '\0') . 1027,1030c if(cd->o_cf.nports == 0 || cd->o_cf.ports[cd->o_cf.nports-1].port != (ulong)-1) p = getnewport(&cd->o_cf); else p = &cd->o_cf.ports[cd->o_cf.nports-1]; . 1023c parse_port(confdata_t* cd, char* option) . 1011c if(dc->nports > 0){ . 1005,1006c static port_t* getnewport(DevConf* dc) . 1000c if(strlen(option) > 1) . 998c parse_spec(confdata_t* cd, char* option) . 991c else if(!strcmp("off", option)) . 989c if(!strcmp("on", option)) . 987c parse_switch(confdata_t* cd, char* option) . 981,982c int o_on; char* o_spec; . 891c if(sdev->ifc->stat) . 888c for(i = 0; i != ndevs; i++){ . 807c else{ . 723c if(unit == nil) . 720c if(sdev == nil) . 650c if(sdev == nil) . 646c if((tp = TYPE(c->qid)) != Qctl && tp != Qraw && tp != Qpart) . 611c if(i == ndevs || subno >= sdev->nunit || sdgetunit(sdev, subno) == nil){ . 565c if((sdev = sdgetdev(DEV(c->qid))) == nil){ . 515c if((sdev = sdgetdev(DEV(c->qid))) == nil){ . 505d 494c if((unit = sdgetunit(sdev, s)) == nil){ . 485c if ((sdev = devs[i].dt_dev) == nil){ . 479c if(i == ndevs){ . 473c for(i = 0; i != ndevs; i++){ . 468c if(s == 0 || s == 1) . 460c case Qtopdir: . 365c while(sdlist != nil){ . 362c devs = (dev_t*)malloc(ndevs * sizeof(dev_t)); . 332,333c tail->unit = (SDunit**)malloc(tail->nunit * sizeof(SDunit*)); tail->unitflg = (int*)malloc(tail->nunit * sizeof(int)); . 326,328c for(tail = sdev; tail->next != nil; tail = tail->next){ tail->unit = (SDunit**)malloc(tail->nunit * sizeof(SDunit*)); tail->unitflg = (int*)malloc(tail->nunit * sizeof(int)); . 258c if(subno > sdev->nunit){ . 237c else{ . 235c if(i == ndevs) . 231c for(i = 0; i != ndevs; i++) . 224c static SDev* . 71c #define DEV(q) ((((ulong)(q).path)>>DevSHIFT) & DevMASK) . 23,25c static dev_t* devs; /* all devices */ static QLock devslock; /* insertion and removal of devices */ static int ndevs; /* total number of devices in the system */ . 19,20c SDev* dt_dev; int dt_nunits; /* num units in dev */ . ## diffname port/devsd.c 2002/0330 ## diff -e /n/emeliedump/2002/0316/sys/src/9/port/devsd.c /n/emeliedump/2002/0330/sys/src/9/port/devsd.c 784a if(offset+len > nb*unit->secsize) len = nb*unit->secsize - offset; . ## diffname port/devsd.c 2002/0402 ## diff -e /n/emeliedump/2002/0330/sys/src/9/port/devsd.c /n/emeliedump/2002/0402/sys/src/9/port/devsd.c 700c unit->rawinuse = 0; . 659c if(tas(&unit->rawinuse) != 0){ . ## diffname port/devsd.c 2002/0703 ## diff -e /n/emeliedump/2002/0402/sys/src/9/port/devsd.c /n/emeliedump/2002/0703/sys/src/9/port/devsd.c 1340c isa.irq = cf->intnum; . 1126c cd.o_cf.intnum == 0 || cd.o_cf.type == nil) . 1058c cd->o_cf.intnum = strtoul(option, &e, 0); . ## diffname port/devsd.c 2003/0406 ## diff -e /n/emeliedump/2002/0703/sys/src/9/port/devsd.c /n/emeliedump/2003/0406/sys/src/9/port/devsd.c 1247c if(sdev == nil) . 1142c if(sdev == nil) . 947c if(sdev == nil) . 908c if(sdev == nil) . 698c if(sdev) { . 607c if((sdev = devs[i].dt_dev) != nil && sdev->idno == idno) . 485c if((sdev = devs[i].dt_dev) == nil){ . 474c if(s < devs[i].dt_nunits) . 232c if(devs[i].dt_dev->idno == idno) . ## diffname port/devsd.c 2003/0507 ## diff -e /n/emeliedump/2003/0406/sys/src/9/port/devsd.c /n/emeliedump/2003/0507/sys/src/9/port/devsd.c 288a if(sdev->enabled == 0 && sdev->ifc->enable) sdev->ifc->enable(sdev); sdev->enabled = 1; . 279,282d