@@ 23,40 23,20 @@ int debug = 0;
enum{
Qdir,
- Qjvideo,
- Qjframe,
Qjcount,
};
static Dirtab lmldir[]={
// name, qid, size, mode
- "jvideo", {Qjvideo}, 0, 0666,
- "jframe", {Qjframe}, 0, 0666,
"jcount", {Qjcount}, 0, 0444,
};
CodeData * codeData;
-typedef enum {
- New,
- Header,
- Body,
- Error,
-} State;
-
int frameNo;
Rendez sleeper;
int singleFrame;
int nopens;
-uchar q856[3];
-State state = New;
-
-static FrameHeader frameHeader = {
- MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
- { 'L', 'M', 'L', '\0'},
- -1, 0, 0, 0, 0
-};
-
#define writel(v, a) *(ulong *)(a) = (v)
#define readl(a) *(ulong*)(a)
@@ 86,177 66,6 @@ vcount(Chan *, void *va, long nbytes, vlong) {
return 1;
}
-static long
-vread(Chan *, void *va, long nbytes, vlong) {
- static int bufpos;
- static char *bufptr;
- static int curbuf;
- static int fragsize;
- static int frameno;
- static int frameprev;
- char *p;
- long count = nbytes;
- int i;
- vlong thetime;
-
- p = (char *)va;
- while (count > 0) {
- switch (state) {
- case New:
- curbuf = getbuffer();
- frameNo = codeData->statCom[curbuf] >> 24;
- fragsize = (codeData->statCom[curbuf] & 0x00ffffff)>>1;
- if (debug & DBGREAD)
- pprint("devlml: got read buf %d, fr %d, size %d\n",
- curbuf, frameNo, fragsize);
- if (!singleFrame && frameno != (frameprev + 1) % 256)
- pprint("Frame out of sequence: %d %d\n",
- frameprev, frameno);
- frameprev = frameno;
- if (fragsize <= 0 || fragsize > sizeof(Fragment)) {
- pprint("Wrong sized fragment, %d (ignored)\n",
- fragsize);
- codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf]));
- break;
- }
- // Fill in APP marker fields here
- thetime = todget(nil);
- frameHeader.sec = (ulong)(thetime / 1000000000LL);
- frameHeader.usec = (ulong)(thetime % 1000000000LL) / 1000;
- frameHeader.frameSize = fragsize - 2 + sizeof(FrameHeader);
- frameHeader.frameSeqNo++;
- frameHeader.frameNo = frameno;
- bufpos = 0;
- state = Header;
- bufptr = (char *)(&frameHeader);
- // Fall through
- case Header:
- i = sizeof(FrameHeader) - bufpos;
- if (count <= i) {
- memmove(p, bufptr, count);
- bufptr += count;
- bufpos += count;
- return nbytes;
- }
- memmove(p, bufptr, i);
- count -= i;
- p += i;
- bufpos = 2;
- bufptr = codeData->frag[curbuf].fb + 2;
- state = Body;
- // Fall through
- case Body:
- i = fragsize - bufpos;
- if (count < i) {
- memmove(p, bufptr, count);
- bufptr += count;
- bufpos += count;
- return nbytes;
- }
- memmove(p, bufptr, i);
- count -= i;
- p += i;
-
- // Allow reuse of current buffer
- codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf]));
- state = New;
- if (singleFrame) {
- state = Error;
- return nbytes - count;
- }
- break;
- case Error:
- return 0;
- }
- }
-}
-
-static long
-vwrite(Chan *, void *va, long nbytes, vlong) {
- static int bufpos;
- static char *bufptr;
- static int curbuf;
- static int fragsize;
- char *p;
- long count = nbytes;
- int i;
-
- p = (char *)va;
- while (count > 0) {
- switch (state) {
- case New:
- curbuf = getbuffer();
- if (debug&DBGWRIT)
- pprint("current buffer %d\n", curbuf);
- bufptr = codeData->frag[curbuf].fb;
- bufpos = 0;
- state = Header;
- // Fall through
- case Header:
- if (count < sizeof(FrameHeader) - bufpos) {
- memmove(bufptr, p, count);
- bufptr += count;
- bufpos += count;
- return nbytes;
- }
- // Fill remainder of header
- i = sizeof(FrameHeader) - bufpos;
- memmove(bufptr, p, i);
- bufptr += i;
- bufpos += i;
- p += i;
- count -= i;
- // verify header
- if (codeData->frag[curbuf].fh.mrkSOI != MRK_SOI
- || codeData->frag[curbuf].fh.mrkAPP3 != MRK_APP3
- || strcmp(codeData->frag[curbuf].fh.nm, APP_NAME)) {
- // Header is bad
- pprint("devlml: header error: 0x%.4ux, 0x%.4ux, `%.4s'\n",
- codeData->frag[curbuf].fh.mrkSOI,
- codeData->frag[curbuf].fh.mrkAPP3,
- codeData->frag[curbuf].fh.nm);
- state = Error;
- return nbytes - count;
- }
- fragsize = codeData->frag[curbuf].fh.frameSize;
- if (fragsize <= sizeof(FrameHeader)
- || fragsize > sizeof(Fragment)) {
- pprint("devlml: frame size error: 0x%.8ux\n",
- fragsize);
- state = Error;
- return nbytes - count;
- }
- state = Body;
- // Fall through
- case Body:
- i = fragsize - bufpos;
- if (count < i) {
- memmove(bufptr, p, count);
- bufptr += count;
- bufpos += count;
- return nbytes;
- }
- memmove(bufptr, p, i);
- bufptr += i;
- bufpos += i;
- p += i;
- count -= i;
- // We have written the frame, time to display it
- codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf]));
- if (debug&DBGWRIT)
- pprint("Sending buffer %d\n", curbuf);
- if (singleFrame) {
- state = Error;
- return nbytes - count;
- }
- state = New;
- break;
- case Error:
- return 0;
- }
- }
-}
-
static void lmlintr(Ureg *, void *);
static void
@@ 289,14 98,11 @@ lmlreset(void)
return;
}
- memset(grabbuf, 0x33, grablen);
-
print("Installing Motion JPEG driver %s\n", MJPG_VERSION);
print("MJPG buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize);
print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabbuf, grablen);
// Get access to DMA memory buffer
- memset(codeData, 0xAA, sizeof(CodeData));
codeData->pamjpg = PADDR(codeData->statCom);
codeData->pagrab = PADDR(grabbuf);
for (i = 0; i < NBUF; i++) {
@@ 306,8 112,6 @@ lmlreset(void)
codeData->fragdesc[i].leng = ((sizeof codeData->frag[i]) >> 1) | FRAGM_FINAL_B;
}
- print("initializing LML33 board...");
-
pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F);
print("zr36067 found at 0x%.8lux", pciPhysBaseAddr);
@@ 320,9 124,6 @@ lmlreset(void)
pciBaseAddr = (ulong)KADDR(regpa);
print(", mapped at 0x%.8lux\n", pciBaseAddr);
- // Interrupt handler
- intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);
-
memset(&segbuf, 0, sizeof(segbuf));
segbuf.attr = SG_PHYSICAL;
segbuf.name = smalloc(NAMELEN);
@@ 355,6 156,10 @@ lmlreset(void)
print("lml: physsegment: lmlgrab\n");
return;
}
+
+ // Interrupt handler
+ intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);
+
return;
}
@@ 378,22 183,14 @@ lmlstat(Chan *c, char *dp)
static Chan*
lmlopen(Chan *c, int omode) {
- int i;
c->aux = 0;
switch(c->qid.path){
- case Qjframe:
- case Qjvideo:
case Qjcount:
+ // allow one open
if (nopens)
error(Einuse);
nopens = 1;
- singleFrame = (c->qid.path == Qjframe) ? 1 : 0;;
- state = New;
- for (i = 0; i < NBUF; i++)
- codeData->statCom[i] = PADDR(&(codeData->fragdesc[i]));
-
- // allow one open total for these two
break;
}
return devopen(c, omode, lmldir, nelem(lmldir), devgen);
@@ 403,8 200,6 @@ static void
lmlclose(Chan *c) {
switch(c->qid.path){
- case Qjvideo:
- case Qjframe:
case Qjcount:
nopens = 0;
authclose(c);
@@ 420,27 215,16 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
case Qdir:
return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen);
- case Qjvideo:
- case Qjframe:
- return vread(c, buf, n, off);
case Qjcount:
return vcount(c, buf, n, off);
}
}
static long
-lmlwrite(Chan *c, void *va, long n, vlong voff) {
- uchar *buf = va;
- long off = voff;
+lmlwrite(Chan *, void *, long, vlong) {
- switch(c->qid.path & ~CHDIR){
- case Qdir:
- case Qjcount:
- error(Eperm);
- case Qjvideo:
- case Qjframe:
- return vwrite(c, buf, n, off);
- }
+ error(Eperm);
+ return 0;
}
Dev lmldevtab = {
@@ 15,16 15,8 @@ static void fault386(Ureg*, void*);
static Lock vctllock;
static Vctl *vctl[256];
-/* interrupt timestamps, l.s knows fills intrts each interupt */
- uvlong intrts;
-static struct {
- Lock;
- int vno; /* vector to save timestamps for */
- int n; /* number of valid timestamps in ts[] */
- uvlong ts[128]; /* time stamps */
-} tsalloc;
-
-static void savets(void);
+/* interrupt timestamps, l.s fills intrts each interupt */
+uvlong intrts;
void
intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf)
@@ 41,8 33,6 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf)
ilock(&vctllock);
vno = arch->intrenable(v);
- if(irq == IrqUART0)
- tsalloc.vno = vno;
if(vno == -1){
iunlock(&vctllock);
print("intrenable: couldn't enable irq %d, tbdf 0x%uX\n",
@@ 192,8 182,6 @@ trap(Ureg* ureg)
}
vno = ureg->trap;
- if(vno == tsalloc.vno)
- savets();
if(ctl = vctl[vno]){
if(ctl->isintr){
m->intr++;
@@ 752,29 740,3 @@ dbgpc(Proc *p)
return ureg->pc;
}
-
-/* called with interrupts off */
-static void
-savets(void)
-{
- lock(&tsalloc);
- if(tsalloc.n < nelem(tsalloc.ts))
- tsalloc.ts[tsalloc.n++] = intrts;
- unlock(&tsalloc);
-}
-
-/* read interrupt timestamps */
-long
-readintrts(void *buf, int n)
-{
- n /= sizeof(uvlong);
- if(n <= 0)
- return 0;
- ilock(&tsalloc);
- if(n > tsalloc.n)
- n = tsalloc.n;
- memmove(buf, tsalloc.ts, n*sizeof(uvlong));
- tsalloc.n = 0;
- iunlock(&tsalloc);
- return n*sizeof(uvlong);
-}
@@ 131,7 131,7 @@ struct Uart
int modem; /* hardware flow control on */
int xonoff; /* software flow control on */
int blocked;
- int cts, dsr, dcd; /* keep track of modem status */
+ int cts, dsr, dcd, dcdts; /* keep track of modem status */
int ctsbackoff;
int hup_dsr, hup_dcd; /* send hangup upstream? */
int dohup;
@@ 149,6 149,41 @@ struct Uartalloc {
void ns16552intr(int);
+/* interrupt timestamps, l.s fills intrts each interupt */
+uvlong intrts;
+static struct {
+ Lock;
+ int vno; /* vector to save timestamps for */
+ int n; /* number of valid timestamps in ts[] */
+ uvlong ts[128]; /* time stamps */
+} tsalloc;
+
+/* called with interrupts off by interrupt routine */
+static void
+savets(void)
+{
+ lock(&tsalloc);
+ if(tsalloc.n < nelem(tsalloc.ts))
+ tsalloc.ts[tsalloc.n++] = intrts;
+ unlock(&tsalloc);
+}
+
+/* read interrupt timestamps */
+long
+readintrts(void *buf, int n)
+{
+ n /= sizeof(uvlong);
+ if(n <= 0)
+ return 0;
+ ilock(&tsalloc);
+ if(n > tsalloc.n)
+ n = tsalloc.n;
+ memmove(buf, tsalloc.ts, n*sizeof(uvlong));
+ tsalloc.n = 0;
+ iunlock(&tsalloc);
+ return n*sizeof(uvlong);
+}
+
/*
* pick up architecture specific routines and definitions
*/
@@ 254,6 289,15 @@ ns16552rts(Uart *p, int n)
}
/*
+ * save dcd timestamps for gps clock
+ */
+static void
+ns16552dcdts(Uart *p, int n)
+{
+ p->dcdts = n;
+}
+
+/*
* send break
*/
static void
@@ 669,6 713,8 @@ ns16552intr(int dev)
}
if (ch & Dcdc) {
l = ch & Dcd;
+ if(l == 0 && p->dcd != 0 && p->dcdts)
+ savets();
if(p->hup_dcd && p->dcd && !l){
ilock(&p->rlock);
p->dohup = 1;
@@ 997,6 1043,10 @@ ns16552ctl(Uart *p, char *cmd)
qsetlimit(p->iq, n);
qsetlimit(p->oq, n);
break;
+ case 'T':
+ case 't':
+ ns16552dcdts(p, n);
+ break;
case 'W':
case 'w':
/* obsolete */