M bitsy/devuda1341.c => bitsy/devuda1341.c +49 -26
@@ 114,7 114,7 @@ enum
Vinvert,
Nvol,
- Bufsize = /* 4* */ 1024, /* 46 ms each */
+ Bufsize = 4* 1024, /* 46 ms each */
Nbuf = 32, /* 1.5 seconds total */
Speed = 44100,
@@ 222,8 222,8 @@ static struct
[Vinvert] {"invert", Fin|Fout|Fmono, 0, 0},
[Nvol] {0}
};
-
static int rate = Speed; /* Current sample rate */
+static int bufsize = Bufsize; /* Current buffer size */
static void setreg(char *name, int val, int n);
/*
@@ 758,7 758,7 @@ sendaudio(IOstate *s) {
ilock(&s->ilock);
if ((audio.amode & Aread) && s->next == s->filling && dmaidle(s->dma)) {
// send an empty buffer to provide an input clock
- zerodma |= dmastart(s->dma, Flushbuf, Bufsize) & 0xff;
+ zerodma |= dmastart(s->dma, Flushbuf, bufsize) & 0xff;
if (zerodma == 0)
if (debug) print("emptyfail\n");
iostats.empties++;
@@ 803,7 803,7 @@ recvaudio(IOstate *s) {
ilock(&s->ilock);
while (s->next != s->emptying) {
assert(s->next->nbytes == 0);
- if ((n = dmastart(s->dma, s->next->phys, Bufsize)) == 0) {
+ if ((n = dmastart(s->dma, s->next->phys, bufsize)) == 0) {
iostats.faildma++;
break;
}
@@ 879,7 879,7 @@ audiointr(void *x, ulong ndma) {
/* A dma, not of a zero buffer completed, update current
* Only interrupt routine touches s->current
*/
- s->current->nbytes = (s == &audio.i)? Bufsize: 0;
+ s->current->nbytes = (s == &audio.i)? bufsize: 0;
s->current++;
if (s->current == &s->buf[Nbuf])
s->current = &s->buf[0];
@@ 1107,7 1107,7 @@ audioread(Chan *c, void *v, long n, vlong off)
}
m = (s->emptying->nbytes > n)? n: s->emptying->nbytes;
- memmove(p, s->emptying->virt + Bufsize -
+ memmove(p, s->emptying->virt + bufsize -
s->emptying->nbytes, m);
s->emptying->nbytes -= m;
@@ 1127,7 1127,7 @@ audioread(Chan *c, void *v, long n, vlong off)
case Qspeed:
buf[0] = '\0';
- snprint(buf, sizeof(buf), "speed %d\n", rate);
+ snprint(buf, sizeof(buf), "speed %d\ndmasize %d\n", rate, bufsize);
return readstr(offset, p, n, buf);
case Qvolume:
@@ 1174,6 1174,29 @@ audioread(Chan *c, void *v, long n, vlong off)
return n0-n;
}
+static void
+setrate(int newrate)
+{
+ switch (newrate) {
+ case 16000:
+ case 22050:
+ case 44100:
+ case 48000:
+ volumes[Vspeed].ilval = volumes[Vspeed].irval = rate = newrate;
+ break;
+ default:
+ error(Ebadarg);
+ }
+}
+
+static void
+setbufsize(int newbufsize)
+{
+ if (newbufsize < 0 || newbufsize > 8 * 1024 || newbufsize % sizeof(ulong))
+ error(Ebadarg);
+ bufsize = newbufsize;
+}
+
static long
audiowrite(Chan *c, void *vp, long n, vlong)
{
@@ 1196,24 1219,24 @@ audiowrite(Chan *c, void *vp, long n, vlong)
memmove(buf, p, n);
buf[n] = '\0';
nf = getfields(buf, field, Ncmd, 1, " \t\n");
- if (nf != 2 && nf != 1) error(Ebadarg);
- if (nf == 2) {
- if (strcmp(field[0], "speed"))
- error(Ebadarg);
- i = 1;
- }
- else
+ if (nf == 1)
+ /* The user just supplied a number */
+ setrate((int)strtol(field[0], (char **)nil, 0));
+ else {
i = 0;
- i = (int)strtol(field[i], (char **)nil, 0);
- switch (i) {
- case 16000:
- case 22050:
- case 44100:
- case 48000:
- volumes[Vspeed].ilval = volumes[Vspeed].irval = rate = i;
- break;
- default:
- error(Ebadarg);
+ while (i < nf) {
+ int newval;
+
+ if (i + 1 >= nf) error(Ebadarg);
+ newval = (int)strtol(field[i + 1], (char **)nil, 0);
+ if (!strcmp(field[i], "speed"))
+ setrate(newval);
+ else if (!strcmp(field[i], "dmasize"))
+ setbufsize(newval);
+ else
+ error(Ebadarg);
+ i += 2;
+ }
}
break;
@@ 1316,7 1339,7 @@ audiowrite(Chan *c, void *vp, long n, vlong)
if (debug > 1) print("#A: sleep\n");
sleep(&a->vous, audioqnotfull, a);
}
- m = Bufsize - a->filling->nbytes;
+ m = bufsize - a->filling->nbytes;
if(m > n)
m = n;
memmove(a->filling->virt + a->filling->nbytes, p, m);
@@ 1324,7 1347,7 @@ audiowrite(Chan *c, void *vp, long n, vlong)
a->filling->nbytes += m;
n -= m;
p += m;
- if(a->filling->nbytes >= Bufsize) {
+ if(a->filling->nbytes >= bufsize) {
if (debug > 1) print("#A: filled @%p\n", a->filling);
a->filling++;
if (a->filling == &a->buf[Nbuf])
M pc/devarch.c => pc/devarch.c +5 -0
@@ 133,6 133,11 @@ ioalloc(int port, int size, int align, char *tag)
return -1;
}
} else {
+ // Only 64KB I/O space on the x86.
+ if((port+size) >= 0x10000){
+ unlock(&iomap);
+ return -1;
+ }
// see if the space clashes with previously allocated ports
for(l = &iomap.m; *l; l = &(*l)->next){
m = *l;
M pc/etherelnk3.c => pc/etherelnk3.c +6 -0
@@ 1443,6 1443,12 @@ tcm59Xpci(void)
p = nil;
while(p = pcimatch(p, 0x10B7, 0)){
+ /*
+ * Not prepared to deal with memory-mapped
+ * devices yet.
+ */
+ if(!(p->mem[0].bar & 0x01))
+ continue;
port = p->mem[0].bar & ~0x01;
if(ioalloc(port, p->mem[0].size, 0, "tcm59Xpci") < 0){
print("tcm59Xpci: port 0x%uX in use\n", port);
M port/devenv.c => port/devenv.c +17 -1
@@ 57,7 57,23 @@ envattach(char *spec)
static int
envwalk(Chan *c, char *name)
{
- return devwalk(c, name, 0, 0, envgen);
+ Evalue *e;
+ Egrp *eg;
+ int rv;
+
+ if(c->qid.path == CHDIR && name[0] != '.'){
+ rv = 0;
+ eg = up->egrp;
+ qlock(eg);
+ for(e = eg->entries; e; e = e->link)
+ if(strcmp(e->name, name) == 0){
+ rv = 1;
+ c->qid = e->qid;
+ }
+ qunlock(eg);
+ return rv;
+ } else
+ return devwalk(c, name, 0, 0, envgen);
}
static void
M port/devproc.c => port/devproc.c +15 -1
@@ 150,7 150,21 @@ procattach(char *spec)
static int
procwalk(Chan *c, char *name)
{
- return devwalk(c, name, 0, 0, procgen);
+ int s;
+ int pid;
+
+ if(c->qid.path == CHDIR && name[0] != '.'){
+ /* this is a hack to speed walks through a large directory */
+ pid = strtol(name, &name, 0);
+ if(pid < 0 || *name != 0)
+ return 0;
+ s = procindex(pid);
+ if(s < 0)
+ return 0;
+ c->qid = (Qid){CHDIR|((s+1)<<QSHIFT), pid};
+ return 1;
+ } else
+ return devwalk(c, name, 0, 0, procgen);
}
static void
M port/portdat.h => port/portdat.h +1 -0
@@ 543,6 543,7 @@ struct Proc
QLock seglock; /* locked whenever seg[] changes */
ulong pid;
ulong noteid; /* Equivalent of note group */
+ Proc *pidhash; /* next proc in pid hash */
Lock exl; /* Lock count and waitq */
Waitq *waitq; /* Exited processes wait children */
M port/portfns.h => port/portfns.h +2 -1
@@ 211,8 211,9 @@ ulong procalarm(ulong);
int proccounter(char *name);
void procctl(Proc*);
void procdump(void);
-void procinit0(void);
void procflushseg(Segment*);
+void procinit0(void);
+int procindex(int);
Proc* proctab(int);
void procwired(Proc*, int);
Pte* ptealloc(void);
M port/proc.c => port/proc.c +53 -0
@@ 11,6 11,7 @@ Ref noteidalloc;
struct Procalloc
{
Lock;
+ Proc* ht[128];
Proc* arena;
Proc* free;
}procalloc;
@@ 48,6 49,9 @@ char *statename[] =
"Rendez",
};
+static void pidhash(Proc*);
+static void pidunhash(Proc*);
+
/*
* Always splhi()'ed.
*/
@@ 342,6 346,7 @@ newproc(void)
p->error[0] = '\0';
memset(p->seg, 0, sizeof p->seg);
p->pid = incref(&pidalloc);
+ pidhash(p);
p->noteid = incref(¬eidalloc);
if(p->pid==0 || p->noteid==0)
panic("pidalloc");
@@ 825,6 830,7 @@ pexit(char *exitstr, int freemem)
qunlock(&up->seglock);
lock(&up->exl); /* Prevent my children from leaving waits */
+ pidunhash(up);
up->pid = 0;
wakeup(&up->waitr);
unlock(&up->exl);
@@ 1213,3 1219,50 @@ accounttime(void)
n = (nrdy+n)*1000;
m->load = (m->load*19+n)/20;
}
+
+static void
+pidhash(Proc *p)
+{
+ int h;
+
+ h = p->pid % nelem(procalloc.ht);
+ lock(&procalloc);
+ p->pidhash = procalloc.ht[h];
+ procalloc.ht[h] = p;
+ unlock(&procalloc);
+}
+
+static void
+pidunhash(Proc *p)
+{
+ int h;
+ Proc **l;
+
+ h = p->pid % nelem(procalloc.ht);
+ lock(&procalloc);
+ for(l = &procalloc.ht[h]; *l != nil; l = &(*l)->pidhash)
+ if(*l == p){
+ *l = p->pidhash;
+ break;
+ }
+ unlock(&procalloc);
+}
+
+int
+procindex(int pid)
+{
+ Proc *p;
+ int h;
+ int s;
+
+ s = -1;
+ h = pid % nelem(procalloc.ht);
+ lock(&procalloc);
+ for(p = procalloc.ht[h]; p != nil; p = p->pidhash)
+ if(p->pid == pid){
+ s = p - procalloc.arena;
+ break;
+ }
+ unlock(&procalloc);
+ return s;
+}