From 4836e8f92c46890b969127b09b8a7e30877266ca Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 9 Oct 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-10-09 --- pc/devfloppy.c | 166 ++++++++++++++++++++++++++++--------------------- port/devcons.c | 1 - port/devscsi.c | 24 +++++++ port/devwren.c | 1 + port/portdat.h | 2 + port/portfns.h | 1 + 6 files changed, 123 insertions(+), 72 deletions(-) diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 0a5645418e9e7056b353f61d809558557035ecd5..90491154ed4b4af61ee49aa5a7a3d33b28da18cf 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -5,6 +5,7 @@ #include "fns.h" #include "io.h" #include "../port/error.h" +#include "devtab.h" /* Intel 82077A (8272A compatible) floppy controller */ @@ -194,7 +195,7 @@ static long floppyseek(Drive*, long); static int floppysense(void); static void floppywait(void); static long floppyxfer(Drive*, int, void*, long, long); -static int floppyformat(Drive*, ulong, ulong); +static void floppyformat(Drive*, char*); static long floppythrice(Drive*, int, void*, long, long); static int cmddone(void*); void Xdelay(int); @@ -362,9 +363,9 @@ floppywstat(Chan *c, char *dp) } static void -islegal(Chan *c, long n, Drive *dp) +islegal(ulong offset, long n, Drive *dp) { - if(c->offset % dp->t->bytes) + if(offset % dp->t->bytes) error(Ebadarg); if(n % dp->t->bytes) error(Ebadarg); @@ -400,7 +401,7 @@ changed(Chan *c, Drive *dp) } long -floppyread(Chan *c, void *a, long n) +floppyread(Chan *c, void *a, long n, ulong offset) { Drive *dp; long rv, i; @@ -415,7 +416,7 @@ floppyread(Chan *c, void *a, long n) dp = &fl.d[c->qid.path & ~Qmask]; switch ((int)(c->qid.path & Qmask)) { case Qdata: - islegal(c, n, dp); + islegal(offset, n, dp); aa = a; qlock(&fl); @@ -430,7 +431,7 @@ floppyread(Chan *c, void *a, long n) * truncate xfer at track boundary */ dp->len = n - rv; - floppypos(dp, c->offset+rv); + floppypos(dp, offset+rv); cyl = dp->tcyl; head = dp->thead; len = dp->len; @@ -470,19 +471,18 @@ floppyread(Chan *c, void *a, long n) #define SNCMP(a, b) strncmp(a, b, sizeof(b)-1) long -floppywrite(Chan *c, void *a, long n) +floppywrite(Chan *c, void *a, long n, ulong offset) { Drive *dp; long rv, i; char *aa = a; - char *f[3]; char ctlmsg[64]; rv = 0; dp = &fl.d[c->qid.path & ~Qmask]; switch ((int)(c->qid.path & Qmask)) { case Qdata: - islegal(c, n, dp); + islegal(offset, n, dp); qlock(&fl); if(waserror()){ qunlock(&fl); @@ -491,10 +491,10 @@ floppywrite(Chan *c, void *a, long n) floppyon(dp); changed(c, dp); for(rv = 0; rv < n; rv += i){ - floppypos(dp, c->offset+rv); + floppypos(dp, offset+rv); if(dp->tcyl == dp->ccyl) dp->ccyl = -1; - i = floppythrice(dp, Fwrite, aa+rv, c->offset+rv, n-rv); + i = floppythrice(dp, Fwrite, aa+rv, offset+rv, n-rv); if(i < 0) break; if(i == 0) @@ -504,6 +504,7 @@ floppywrite(Chan *c, void *a, long n) poperror(); break; case Qctl: + rv = n; qlock(&fl); if(waserror()){ qunlock(&fl); @@ -519,9 +520,7 @@ floppywrite(Chan *c, void *a, long n) fl.confused = 1; floppyon(dp); } else if(SNCMP(ctlmsg, "format") == 0){ - if(getfields(ctlmsg, f, 3, ' ') != 3) - error(Ebadarg); - rv = n*floppyformat(dp, strtoul(f[1], 0, 0), strtoul(f[2], 0, 0)); + floppyformat(dp, ctlmsg); } poperror(); qunlock(&fl); @@ -956,82 +955,107 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n) /* * format a track */ -static int -floppyformat(Drive *dp, ulong track, ulong filler) +static void +floppyformat(Drive *dp, char *params) { int cyl, h, sec; + ulong track; uchar *buf, *bp; Type *t; - - t = dp->t; - cyl = track/t->heads; - h = track % t->heads; - if(track >= t->tracks * t->heads) - return 0; - setdef(dp); - buf = smalloc(t->sectors*4); - if(waserror()){ - free(buf); - nexterror(); - } - if(!waserror()){ - floppyon(dp); - poperror(); - } - floppyseek(dp, track*t->tsize); - dp->cyl = cyl; - dp->confused = 0; + char *f[3]; /* - * set up the dma (dp->len may be trimmed) + * set the type */ - bp = buf; - for(sec = 1; sec <= t->sectors; sec++){ - *bp++ = cyl; - *bp++ = h; - *bp++ = sec; - *bp++ = t->bcode; + if(getfields(params, f, 3, ' ') > 1){ + for(t = floppytype; t < &floppytype[NTYPES]; t++) + if(strcmp(f[1], t->name)==0 && t->dt==dp->dt){ + dp->t = t; + floppydir[NFDIR*dp->dev].length = dp->t->cap; + break; + } + } else { + setdef(dp); + t = dp->t; } - dmasetup(DMAchan, buf, bp-buf, 0); /* - * start operation + * buffer for per track info */ - fl.ncmd = 0; - fl.cmd[fl.ncmd++] = Fformat; - fl.cmd[fl.ncmd++] = (h<<2) | dp->dev; - fl.cmd[fl.ncmd++] = t->bcode; - fl.cmd[fl.ncmd++] = t->sectors; - fl.cmd[fl.ncmd++] = t->fgpl; - fl.cmd[fl.ncmd++] = filler; - if(floppycmd() < 0){ - DPRINT("xfer cmd failed\n"); - error(Eio); + buf = smalloc(t->sectors*4); + if(waserror()){ + free(buf); + nexterror(); } /* - * give bus to DMA, floppyintr() will read result + * format a track at time */ - floppywait(); - dmaend(DMAchan); + for(track = 0; track < t->tracks*t->heads; track++){ + cyl = track/t->heads; + h = track % t->heads; - /* - * check for errors - */ - if(fl.nstat < 7){ - DPRINT("format result failed %lux\n", inb(Pmsr)); - fl.confused = 1; - error(Eio); - } - if((fl.stat[0]&Codemask)!=0 || fl.stat[1] || fl.stat[2]){ - DPRINT("format failed %lux %lux %lux\n", - fl.stat[0], fl.stat[1], fl.stat[2]); - dp->confused = 1; - error(Eio); + /* + * seek to track, ignore errors + */ + if(!waserror()){ + floppyon(dp); + poperror(); + } + floppyseek(dp, track*t->tsize); + dp->cyl = cyl; + dp->confused = 0; + + /* + * set up the dma (dp->len may be trimmed) + */ + bp = buf; + for(sec = 1; sec <= t->sectors; sec++){ + *bp++ = cyl; + *bp++ = h; + *bp++ = sec; + *bp++ = t->bcode; + } + dmasetup(DMAchan, buf, bp-buf, 0); + + /* + * start operation + */ + fl.ncmd = 0; + fl.cmd[fl.ncmd++] = Fformat; + fl.cmd[fl.ncmd++] = (h<<2) | dp->dev; + fl.cmd[fl.ncmd++] = t->bcode; + fl.cmd[fl.ncmd++] = t->sectors; + fl.cmd[fl.ncmd++] = t->fgpl; + fl.cmd[fl.ncmd++] = 0x5a; + if(floppycmd() < 0){ + DPRINT("xfer cmd failed\n"); + error(Eio); + } + + /* + * give bus to DMA, floppyintr() will read result + */ + floppywait(); + dmaend(DMAchan); + + /* + * check for errors + */ + if(fl.nstat < 7){ + DPRINT("format result failed %lux\n",inb(Pmsr)); + fl.confused = 1; + error(Eio); + } + if((fl.stat[0]&Codemask)!=0 || fl.stat[1]|| fl.stat[2]){ + DPRINT("format failed %lux %lux %lux\n", + fl.stat[0], fl.stat[1], fl.stat[2]); + dp->confused = 1; + error(Eio); + } } free(buf); poperror(); - return 1; } static void diff --git a/port/devcons.c b/port/devcons.c index efcc3554b555c3ae08692eac0d8a8e34a8f10e31..a455ab6570f7bc8af1b47a35999b21b231c8f188 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -837,7 +837,6 @@ conswrite(Chan *c, void *va, long n, ulong offset) memmove(u->p->user, buf, NAMELEN); else error(Eperm); - memset(u->p->pgrp->crypt->key, 0, DESKEYLEN); if(!cpuserver && strcmp(eve, "bootes")==0) memmove(eve, u->p->user, NAMELEN); break; diff --git a/port/devscsi.c b/port/devscsi.c index 50d6637d7feea2cd4e5f8abfc131759c5a06a1c0..989b21fea18f71b79934991eb16bab8e18286cff 100644 --- a/port/devscsi.c +++ b/port/devscsi.c @@ -324,6 +324,9 @@ scsicmd(int dev, int cmdbyte, Scsibuf *b, long size) switch(cmdbyte){ case ScsiTestunit: break; + case ScsiStartunit: + cmd->cmdblk[4] = 1; + break; case ScsiModesense: cmd->cmdblk[2] = 1; /* fall through */ @@ -363,6 +366,27 @@ scsiready(int dev) return status&0xff; } +int +scsistartstop(int dev, int cmdbyte) +{ + Scsi *cmd; + int status; + + cmd = scsicmd(dev, cmdbyte, scsibuf(), 0); + if(waserror()){ + scsifree(cmd->b); + qunlock(cmd); + nexterror(); + } + status = scsiexec(cmd, ScsiOut); + poperror(); + scsifree(cmd->b); + qunlock(cmd); + if((status&0xff00) != 0x6000) + error(Eio); + return status&0xff; +} + int scsisense(int dev, void *p) { diff --git a/port/devwren.c b/port/devwren.c index 054d9e0ee685238744912403f7b97beb7cce2e72..b4de5aaa0b755de5356b3f163c65a4aafa967168 100644 --- a/port/devwren.c +++ b/port/devwren.c @@ -275,6 +275,7 @@ wrenpart(int dev) qlock(dp); scsiready(dev); scsisense(dev, buf); + scsistartstop(dev, ScsiStartunit); if(scsicap(dev, buf)) error(Eio); dp->drive = dev; diff --git a/port/portdat.h b/port/portdat.h index 878e65176bff0b63e5944bea3023eb04e61d6577..cd9c417fdf41e57a4f7cebcea5cf5b35e1aabd45 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -230,6 +230,8 @@ enum ScsiExtsens = 0x03, ScsiInquiry = 0x12, ScsiModesense = 0x1a, + ScsiStartunit = 0x1B, + ScsiStopunit = 0x1B, ScsiGetcap = 0x25, ScsiRead = 0x08, ScsiWrite = 0x0a, diff --git a/port/portfns.h b/port/portfns.h index a106cce2abb10a3b7f6210910da70c841989e502..fc43a7cde8eafea9e96f44f5432874067d23db08 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -208,6 +208,7 @@ void scsifree(Scsibuf*); int scsiinquiry(int, void*, int); int scsimodesense(int, int, void*, int); int scsiready(int); +int scsistartstop(int, int); int scsisense(int, void*); int scsiwp(int); long seconds(void);