| plan 9 kernel history: overview | file list | diff list |
1999/0517/pc/devlml.c (diff list | history)
| 1999/0422/sys/src/9/pc/devlml.c:13,22 – 1999/0423/sys/src/9/pc/devlml.c:13,20 (short | long) | ||
| 1999/0422 | enum{ Q819, Q856, | |
| 1999/0422/sys/src/9/pc/devlml.c:25,34 – 1999/0423/sys/src/9/pc/devlml.c:23,30 | ||
| 1999/0422 | // name, qid, size, mode "vid819", {Q819}, 0, 0644, "vid856", {Q856}, 0, 0644, | |
| 1999/0422/sys/src/9/pc/devlml.c:36,49 – 1999/0423/sys/src/9/pc/devlml.c:32,361 | ||
| 1999/0422 | CodeData * codeData; MjpgDrv * mjpgDrv; | |
| 1999/0423 | static void lml33_i2c_pause(void) { | |
| 1999/0422 | ||
| 1999/0423 | microdelay(I2C_DELAY); } | |
| 1999/0422 | static void | |
| 1999/0423 | lml33_i2c_waitscl(void) { int i; ulong a; for(i=0;;i++) { a = readl(pciBaseAddr + ZR36057_I2C_BUS); if (a & ZR36057_I2C_SCL) break; if (i>I2C_TIMEOUT) error(Eio); } } static void lml33_i2c_start(void) { writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_waitscl(); lml33_i2c_pause(); writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_pause(); writel(0, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_pause(); } static void lml33_i2c_stop(void) { // the clock should already be low, make sure data is writel(0, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_pause(); // set clock high and wait for device to catch up writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_waitscl(); lml33_i2c_pause(); // set the data high to indicate the stop bit writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_pause(); } static void lml33_i2c_wrbit(int bit) { if (bit){ writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); // set data lml33_i2c_pause(); writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_waitscl(); lml33_i2c_pause(); writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_pause(); } else { writel(0, pciBaseAddr + ZR36057_I2C_BUS); // clr data lml33_i2c_pause(); writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_waitscl(); lml33_i2c_pause(); writel(0, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_pause(); } } static int lml33_i2c_rdbit(void) { int bit; // the clk line should be low // ensure we are not asserting the data line writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_pause(); // set the clock high and wait for device to catch up writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_waitscl(); lml33_i2c_pause(); // the data line should be a valid bit bit = readl(pciBaseAddr+ZR36057_I2C_BUS); if (bit & ZR36057_I2C_SDA){ bit = 1; } else { bit = 0; } // set the clock low to indicate end of cycle writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); lml33_i2c_pause(); return bit; } static int lml33_i2c_rdbyte(uchar *v) { int i, ack; uchar res; res = 0; for (i=0;i<8;i++){ res = res << 1; res += lml33_i2c_rdbit(); } ack = lml33_i2c_rdbit(); *v = res; return ack; } static int lml33_i2c_wrbyte(uchar v) { int i, ack; for (i=0;i<8;i++){ lml33_i2c_wrbit(v & 0x80); v = v << 1; } ack = lml33_i2c_rdbit(); return ack; } static void lml33_i2c_write_bytes(uchar addr, uchar sub, uchar *bytes, long num) { int ack; long i; lml33_i2c_start(); ack = lml33_i2c_wrbyte(addr); if (ack == 1) error(Eio); ack = lml33_i2c_wrbyte(sub); if (ack == 1) error(Eio); for(i=0;i<num;i+=1){ ack = lml33_i2c_wrbyte(bytes[i]); if (ack == 1) error(Eio); } lml33_i2c_stop(); } static uchar lml33_i2c_rd8(int addr, int sub) { int ack; uchar msb; lml33_i2c_start(); ack = lml33_i2c_wrbyte(addr); if (ack == 1){ lml33_i2c_stop(); error(Eio); } ack = lml33_i2c_wrbyte(sub); if (ack == 1){ lml33_i2c_stop(); error(Eio); } lml33_i2c_start(); ack = lml33_i2c_wrbyte(addr+1); if (ack == 1){ lml33_i2c_stop(); error(Eio); } ack = lml33_i2c_rdbyte(&msb); if (ack == 0){ lml33_i2c_stop(); error(Eio); } lml33_i2c_stop(); return msb; } /* * The following mapping applies for the guests in the LML33 * * Guest Device * 0 zr36060 * uses subaddress GADR[0..1] * 1 zr36060 START# * 2 - * 3 zr36060 RESET# * 4 - * 5 - * 6 - * 7 - */ // lml33_post_idle waits for the guest bus to become free static int lml33_post_idle(void) { ulong a; int timeout; for(timeout = 0;;timeout += 1){ a = readl(pciBaseAddr + ZR36057_POST_OFFICE); if ((a & ZR36057_POST_PEND) == 0) return a; if (timeout == GUEST_TIMEOUT) return -1; } } // lml33_post_write writes a byte to a guest using postoffice mechanism static void lml33_post_write(int guest, int reg, int v) { int w; // wait for postoffice not busy lml33_post_idle(); // Trim the values, just in case guest &= 0x07; reg &= 0x07; v &= 0xFF; // write postoffice operation w = ZR36057_POST_DIR + (guest<<20) + (reg<<16) + v; writel(w, pciBaseAddr + ZR36057_POST_OFFICE); // wait for postoffice not busy w = lml33_post_idle(); // decide if write went ok if (w == -1) error(Eio); } // lml33_post_read reads a byte from a guest using postoffice mechanism static uchar lml33_post_read(int guest, int reg) { int w; // wait for postoffice not busy lml33_post_idle(); // Trim the values, just in case guest &= 0x07; reg &= 0x07; // write postoffice operation w = (guest<<20) + (reg<<16); writel(w, pciBaseAddr + ZR36057_POST_OFFICE); // wait for postoffice not busy, get result w = lml33_post_idle(); // decide if read went ok if (w == -1) error(Eio); return (uchar)(w & 0xFF); } static void lml33_zr060_write(int reg, int v) { int guest_id; guest_id = GID060; lml33_post_write(guest_id, 1, reg>>8 & 0x03); lml33_post_write(guest_id, 2, reg & 0xff); lml33_post_write(guest_id, 3, v); } static uchar lml33_zr060_read(int reg) { int guest_id; guest_id = GID060; lml33_post_write(guest_id, 1, reg>>8 & 0x03); lml33_post_write(guest_id, 2, reg & 0xff); return lml33_post_read(guest_id, 3); } long chipread(long addr, char *buf, long n, long off) { long i; for (i = 0; i < n; i++) { *buf++ = lml33_i2c_rd8(addr, off++); } return i; } long post060read(char *buf, long n, long off) { long i; for (i = 0; i < n; i++) { *buf++ = lml33_zr060_read(off++); } return i; } static void lmlintr(Ureg *, void *); static void | |
| 1999/0422 | vidreset(void) { ulong regpa; int i; | |
| 1999/0423 | pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067); if (pcidev == nil) { print("No zr36067 found.\n"); return; } | |
| 1999/0422 | codeData = (CodeData*)xspanalloc(sizeof(CodeData), BY2PG, 0); if (codeData == nil) { print("devlml: xspanalloc(%ux, %ux, 0)\n", sizeof(CodeData), BY2PG); | |
| 1999/0422/sys/src/9/pc/devlml.c:61,67 – 1999/0423/sys/src/9/pc/devlml.c:373,379 | ||
| 1999/0422 | codeData->statCom[i] = PADDR(&(codeData->fragmDescr[i])); codeData->statComInitial[i] = codeData->statCom[i]; codeData->fragmDescr[i].fragmAddress = | |
| 1999/0423 | (Fragment *)PADDR(&(codeData->frag[i])); | |
| 1999/0422 | // Length is in double words, in position 1..20 codeData->fragmDescr[i].fragmLength = (FRAGSIZE >> 1) | FRAGM_FINAL_B; } | |
| 1999/0422/sys/src/9/pc/devlml.c:71,109 – 1999/0423/sys/src/9/pc/devlml.c:383,411 | ||
| 1999/0422 | print("LML33: can't allocate dynamic memory for MjpgDrv\n"); return; } | |
| 1999/0423 | pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F); | |
| 1999/0422 |
| |
| 1999/0423 | print("zr36067 found at %lux\n", pciPhysBaseAddr); | |
| 1999/0422 |
| |
| 1999/0423 | regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0); | |
| 1999/0422 | if (regpa == 0) { print("lml: failed to map registers\n"); return; } | |
| 1999/0423 | pciBaseAddr = (ulong)KADDR(regpa); | |
| 1999/0422 | // make sure the device will respond to mem accesses // (pcicmd_master | pcicmd_memory) -- probably superfluous | |
| 1999/0423 | // pcicfgw32(pcidev, PciPCR, 0x04 | 0x02); | |
| 1999/0422 | // set bus latency -- probably superfluous | |
| 1999/0423 | // pcicfgw8(pcidev, PciLTR, 64); | |
| 1999/0422 | // Interrupt handler | |
| 1999/0423 | intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); | |
| 1999/0422 | print("LML33 Installed\n"); return; | |
| 1999/0422/sys/src/9/pc/devlml.c:134,147 – 1999/0423/sys/src/9/pc/devlml.c:436,445 | ||
| 1999/0422 | switch(c->qid.path){ case Q819: case Q856: | |
| 1999/0422/sys/src/9/pc/devlml.c:156,165 – 1999/0423/sys/src/9/pc/devlml.c:454,461 | ||
| 1999/0422 | switch(c->qid.path){ case Q819: case Q856: | |
| 1999/0422/sys/src/9/pc/devlml.c:167,183 – 1999/0423/sys/src/9/pc/devlml.c:463,485 | ||
| 1999/0422 | } static long | |
| 1999/0423 | vidread(Chan *c, void *buf, long n, vlong off) { | |
| 1999/0422 | switch(c->qid.path){ case Q819: | |
| 1999/0423 | if (off < 0 || off + n > 20) return 0; return chipread(BT819Addr, buf, n, off); | |
| 1999/0422 | case Q856: | |
| 1999/0423 | if (off < 0xda || off + n > 0xe0) return 0; return chipread(BT856Addr, buf, n, off); | |
| 1999/0422 | case Q060: | |
| 1999/0423 | return post060read(buf, n, off); | |
| 1999/0422 | case Q067: | |
| 1999/0423 | if (off < 0 || off + n > 20 || (off & 0x3) || n != 4) return 0; *(long *)buf = readl(pciBaseAddr + off); return 4; | |
| 1999/0422 | case Qvideo: case Qjframe: return videoread(c, buf, n, off); | |
| 1999/0422/sys/src/9/pc/devlml.c:187,192 – 1999/0423/sys/src/9/pc/devlml.c:489,514 | ||
| 1999/0422 | static long vidwrite(Chan *c, void *va, long n, vlong off) { | |
| 1999/0423 | switch(c->qid.path){ case Q819: if (off < 0 || off + n > 20) return 0; return chipwrite(BT819Addr, buf, n, off); case Q856: if (off < 0xda || off + n > 0xe0) return 0; return chipwrite(BT856Addr, buf, n, off); case Q060: return post060write(buf, n, off); case Q067: if (off < 0 || off + n > 20 || (off & 0x3) || n != 4) return 0; writel(*(long *)buf, pciBaseAddr + off); return 4; case Qvideo: case Qjframe: return videowrite(c, buf, n, off); } | |
| 1999/0422 | } Dev viddevtab = { | |
| 1999/0422/sys/src/9/pc/devlml.c:211,219 – 1999/0423/sys/src/9/pc/devlml.c:533,540 | ||
| 1999/0422 | }; static void | |
| 1999/0423 | lmlintr(Ureg *ur, void *) | |
| 1999/0422 | { | |
| 1999/0423 | ||
| 1999/0422 | } | |
| 1999/0423/sys/src/9/pc/devlml.c:30,37 – 1999/0424/sys/src/9/pc/devlml.c:30,52 (short | long) | ||
| 1999/0422 | }; CodeData * codeData; | |
| 1999/0424 | int currentBuffer; int currentBufferLength; void * currentBufferPtr; int frameNo; Rendez sleeper; int singleFrame; int bufferPrepared; int hdrPos; int nopens; static FrameHeader frameHeader = { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, { 'L', 'M', 'L', '\0'}, -1, 0, 0, 0, 0 }; | |
| 1999/0423 | static void lml33_i2c_pause(void) { | |
| 1999/0422 | ||
| 1999/0423/sys/src/9/pc/devlml.c:182,226 – 1999/0424/sys/src/9/pc/devlml.c:197,243 | ||
| 1999/0423 | lml33_i2c_stop(); } | |
| 1999/0424 | static int | |
| 1999/0423 | lml33_i2c_rd8(int addr, int sub) { | |
| 1999/0424 | if (lml33_i2c_wrbyte(addr) == 1 || lml33_i2c_wrbyte(sub) == 1) { | |
| 1999/0423 | lml33_i2c_stop(); | |
| 1999/0424 | return -1; | |
| 1999/0423 | } | |
| 1999/0424 | if (lml33_i2c_wrbyte(addr+1) == 1 || lml33_i2c_rdbyte(&msb) == 0){ | |
| 1999/0423 | lml33_i2c_stop(); | |
| 1999/0424 | return -1; | |
| 1999/0423 | } | |
| 1999/0424 | static int lml33_i2c_wr8(uchar addr, uchar sub, uchar msb) { lml33_i2c_start(); if (lml33_i2c_wrbyte(addr) == 1 || lml33_i2c_wrbyte(sub) == 1 || lml33_i2c_wrbyte(msb) == 1) return 0; lml33_i2c_stop(); return 1; } | |
| 1999/0423 | /* * The following mapping applies for the guests in the LML33 * | |
| 1999/0423/sys/src/9/pc/devlml.c:252,258 – 1999/0424/sys/src/9/pc/devlml.c:269,275 | ||
| 1999/0423 | } // lml33_post_write writes a byte to a guest using postoffice mechanism | |
| 1999/0424 | static int | |
| 1999/0423 | lml33_post_write(int guest, int reg, int v) { int w; | |
| 1999/0423/sys/src/9/pc/devlml.c:269,282 – 1999/0424/sys/src/9/pc/devlml.c:286,296 | ||
| 1999/0423 | writel(w, pciBaseAddr + ZR36057_POST_OFFICE); // wait for postoffice not busy | |
| 1999/0424 | return lml33_post_idle() == -1; | |
| 1999/0423 | } // lml33_post_read reads a byte from a guest using postoffice mechanism | |
| 1999/0424 | static int | |
| 1999/0423 | lml33_post_read(int guest, int reg) { int w; | |
| 1999/0423/sys/src/9/pc/devlml.c:295,306 – 1999/0424/sys/src/9/pc/devlml.c:309,320 | ||
| 1999/0423 | w = lml33_post_idle(); // decide if read went ok | |
| 1999/0424 | if (w == -1) return -1; | |
| 1999/0423 |
| |
| 1999/0424 | return w & 0xFF; | |
| 1999/0423 | } | |
| 1999/0424 | static int | |
| 1999/0423 | lml33_zr060_write(int reg, int v) { int guest_id; | |
| 1999/0423/sys/src/9/pc/devlml.c:308,317 – 1999/0424/sys/src/9/pc/devlml.c:322,331 | ||
| 1999/0423 | lml33_post_write(guest_id, 1, reg>>8 & 0x03); lml33_post_write(guest_id, 2, reg & 0xff); | |
| 1999/0424 | return lml33_post_write(guest_id, 3, v); | |
| 1999/0423 | } | |
| 1999/0424 | static int | |
| 1999/0423 | lml33_zr060_read(int reg) { int guest_id; | |
| 1999/0423/sys/src/9/pc/devlml.c:323,348 – 1999/0424/sys/src/9/pc/devlml.c:337,541 | ||
| 1999/0423 | return lml33_post_read(guest_id, 3); } | |
| 1999/0424 | static int prepareBuffer(CodeData * this, int bufferNo) { if(bufferNo >= 0 && bufferNo < NBUF && (this->statCom[bufferNo] & STAT_BIT)) { this->statCom[bufferNo] = this->statComInitial[bufferNo]; return this->fragmDescr[bufferNo].fragmLength; } else return -1; } | |
| 1999/0423 |
| |
| 1999/0424 | static int getProcessedBuffer(CodeData* this){ static lastBuffer=NBUF-1; int lastBuffer0 = lastBuffer; while (1) { lastBuffer = (lastBuffer+1) % NBUF; if(this->statCom[lastBuffer]&STAT_BIT) return lastBuffer; if(lastBuffer==lastBuffer0) break; | |
| 1999/0423 | } | |
| 1999/0424 | return -1; | |
| 1999/0423 | } | |
| 1999/0424 | static int getBuffer(CodeData *this, int bufferNo, void** bufferPtr, int* frameNo) { int codeLength; if(this->statCom[bufferNo] & STAT_BIT) { *bufferPtr = (void*)this->fragmDescr[bufferNo].fragmAddress; *frameNo = this->statCom[bufferNo] >> 24; codeLength=((this->statCom[bufferNo] & 0x00FFFFFF) >> 1); return codeLength; } else return -1; } | |
| 1999/0423 |
| |
| 1999/0424 | static long vread(Chan *, void *va, long count, vlong pos) { int prevFrame; // how much bytes left to transfer for the header int hdrLeft; // Count of bytes that we need to copy into buf from code-buffer // (different from count only while in header reading mode) int cpcount = count; // Count of bytes that we copied into buf altogether and will return int retcount=0; vlong thetime; uchar *buf = va; //print("devlml::vread() count=%ld pos=%lld\n", count, pos); // If we just begin reading a file, pos would never be 0 otherwise if (pos == 0 && hdrPos == -1) { currentBuffer = -1; currentBufferLength = 0; frameNo = -1; | |
| 1999/0423 | } | |
| 1999/0424 | prevFrame = frameNo; // We get to the end of the current buffer, also covers just // open file, since 0 >= -1 if(hdrPos == -1 && pos >= currentBufferLength) { prepareBuffer(codeData, currentBuffer); // if not the first buffer read and single frame mode - return EOF if (currentBuffer != -1 && singleFrame) return 0; while((currentBuffer = getProcessedBuffer(codeData)) == -1) sleep(&sleeper, return0, 0); currentBufferLength = getBuffer(codeData, currentBuffer, ¤tBufferPtr, &frameNo); pos = 0; // ?????????????? // print("getBufffer %d -> %d 0x%x %d\n",currentBuffer, currentBufferLength, currentBufferPtr, frameNo); if(frameNo != (prevFrame + 1) % 256) print("Frames out of sequence: %d %d\n", prevFrame, frameNo); // Fill in APP marker fields here thetime = todget(); frameHeader.sec = (ulong)(thetime / 1000000000LL); frameHeader.usec = (ulong)(thetime % 1000000000LL) / 1000; frameHeader.frameSize = currentBufferLength - 2 + sizeof(FrameHeader); frameHeader.frameSeqNo++; frameHeader.frameNo = frameNo; hdrPos=0; } if (hdrPos != -1) { hdrLeft = sizeof(FrameHeader) - hdrPos; // Write the frame size here if (count >= hdrLeft) { memmove(buf, (char*)&frameHeader + hdrPos, hdrLeft); retcount += hdrLeft; cpcount = count - hdrLeft; pos = sizeof(frameHeader.mrkSOI); hdrPos = -1; } else { memmove(buf, (char*)&frameHeader + hdrPos, count); hdrPos += count; return count; } } if(cpcount + pos > currentBufferLength) cpcount = currentBufferLength - pos; memmove(buf + retcount, (char *)currentBufferPtr + pos, cpcount); retcount += cpcount; //pr_debug("return %d %d\n",cpcount,retcount); return retcount; | |
| 1999/0423 | } | |
| 1999/0424 | static long vwrite(Chan *, void *va, long count, vlong pos) { // how much bytes left to transfer for the header int hdrLeft; char *buf = va; //print("devlml::vwrite() count=0x%x pos=0x%x\n", count, pos); // We just started writing, not into the header copy if(pos==0 && hdrPos == -1) { currentBuffer=-1; currentBufferLength=0; frameNo=-1; bufferPrepared = 0; } // We need next buffer to fill (either because we're done with the // current buffer) of because we're just beginning (but not into the header) if (hdrPos == -1 && pos >= currentBufferLength) { while((currentBuffer = getProcessedBuffer(codeData)) == -1) sleep(&sleeper, return0, 0); // print("current buffer %d\n",currentBuffer); getBuffer(codeData, currentBuffer, ¤tBufferPtr, &frameNo); // We need to receive the header now hdrPos = 0; } // We're into the header processing if (hdrPos != -1) { // Calculate how many bytes we need to receive to fill the header hdrLeft = sizeof(FrameHeader) - hdrPos; // If we complete or go over the header with this count if (count >= hdrLeft) { // Adjust count of bytes that remain to be copied into video buffer count = count - hdrLeft; memmove((char*)&frameHeader + hdrPos, buf, hdrLeft); // Make sure we have a standard LML33 header if (frameHeader.mrkSOI == MRK_SOI && frameHeader.mrkAPP3==MRK_APP3 && strcmp(frameHeader.nm,APP_NAME) == 0) { //print("Starting new buffer len=0x%x frame=%d\n", frameHeader.frameSize, frameHeader.frameSeqNo); // Obtain values we need for playback process from the header currentBufferLength = frameHeader.frameSize; } else if (singleFrame) { currentBufferLength = FRAGSIZE; } else { // We MUST have header for motion video decompression print("No frame size (APP3 marker) in MJPEG file\n"); error(Eio); } // Finish header processing hdrPos = -1; // Copy the header into the playback buffer memmove(currentBufferPtr, (char*)&frameHeader, sizeof(FrameHeader)); // And set position just behind header for playback buffer write pos = sizeof(FrameHeader); } else { memmove((char*)&frameHeader + hdrPos, buf, count); hdrPos += count; return count; } } else hdrLeft = 0; if(count + pos > currentBufferLength) { count = currentBufferLength - pos; } memmove((char *)currentBufferPtr + pos, buf + hdrLeft, count); pos += count; // print("return 0x%x 0x%x\n",pos,count); // Now is the right moment to initiate playback of the frame (if it's full) if(pos >= currentBufferLength) { // We have written the frame, time to display it //print("Passing written buffer to 067\n"); prepareBuffer(codeData, currentBuffer); bufferPrepared = 1; } //print("return 0x%lx 0x%x 0x%x 0x%x\n",pos,count,hdrLeft+count,currentBufferLength); return hdrLeft + count; } | |
| 1999/0423 | static void lmlintr(Ureg *, void *); static void | |
| 1999/0423/sys/src/9/pc/devlml.c:378,389 – 1999/0424/sys/src/9/pc/devlml.c:571,576 | ||
| 1999/0422 | codeData->fragmDescr[i].fragmLength = (FRAGSIZE >> 1) | FRAGM_FINAL_B; } | |
| 1999/0423 | pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F); | |
| 1999/0423/sys/src/9/pc/devlml.c:438,447 – 1999/0424/sys/src/9/pc/devlml.c:625,643 | ||
| 1999/0422 | case Q856: case Q060: case Q067: | |
| 1999/0424 | if (nopens) error(Einuse); nopens = 1; singleFrame = (c->qid.path == Qjframe) ? 1 : 0;; currentBuffer = 0; currentBufferLength = 0; currentBufferPtr = 0; frameNo = 0; bufferPrepared = 0; hdrPos = -1; | |
| 1999/0422 | // allow one open total for these two break; } | |
| 1999/0423/sys/src/9/pc/devlml.c:463,513 – 1999/0424/sys/src/9/pc/devlml.c:659,747 | ||
| 1999/0422 | } static long | |
| 1999/0423 |
| |
| 1999/0424 | vidread(Chan *c, void *va, long n, vlong off) { int i, d; uchar *buf = va; | |
| 1999/0423 | ||
| 1999/0422 | switch(c->qid.path){ case Q819: | |
| 1999/0423 |
| |
| 1999/0424 | if (off < 0 || off + n > 0x20) | |
| 1999/0423 | return 0; | |
| 1999/0424 | for (i = 0; i < n; i++) { if ((d = lml33_i2c_rd8(BT819Addr, off++)) < 0) break; *buf++ = d; } return n - i; | |
| 1999/0422 | case Q856: | |
| 1999/0423 | if (off < 0xda || off + n > 0xe0) return 0; | |
| 1999/0424 | for (i = 0; i < n; i++) { if ((d = lml33_i2c_rd8(BT856Addr, off++)) < 0) break; *buf++ = d; } return n - i; | |
| 1999/0422 | case Q060: | |
| 1999/0423 |
| |
| 1999/0424 | if (off < 0 || off + n > 0x60) return 0; for (i = 0; i < n; i++) { if ((d = lml33_zr060_read(off++)) < 0) break; *buf++ = d; } return n - i; | |
| 1999/0422 | case Q067: | |
| 1999/0423 |
| |
| 1999/0424 | if (off < 0 || off + n > 0x200 || (off & 0x3)) return 0; for (i = n; i >= 4; i -= 4) { *(long *)buf = readl(pciBaseAddr + off); buf += 4; off += 4; } return n-i; | |
| 1999/0422 | case Qvideo: case Qjframe: | |
| 1999/0424 | return vread(c, buf, n, off); | |
| 1999/0422 | } } static long | |
| 1999/0424 | vidwrite(Chan *c, void *va, long n, vlong off) { int i; uchar *buf = va; | |
| 1999/0423 | switch(c->qid.path){ case Q819: | |
| 1999/0424 | if (off < 0 || off + n > 0x20) | |
| 1999/0423 | return 0; | |
| 1999/0424 | for (i = n; i > 0; i--) if (lml33_i2c_wr8(BT819Addr, off++, *buf++) == 0) break; return n - i; | |
| 1999/0423 | case Q856: if (off < 0xda || off + n > 0xe0) return 0; | |
| 1999/0424 | for (i = n; i > 0; i--) if (lml33_i2c_wr8(BT856Addr, off++, *buf++) == 0) break; return n - i; | |
| 1999/0423 | case Q060: | |
| 1999/0424 | if (off < 0 || off + n > 0x60) return 0; for (i = 0; i < n; i++) if (lml33_zr060_write(off++, *buf++) < 0) break; return n - i; | |
| 1999/0423 | case Q067: | |
| 1999/0424 | if (off < 0 || off + n > 0x200 || (off & 0x3)) return 0; for (i = n; i >= 4; i -= 4) { writel(*(long *)buf, pciBaseAddr + off); buf += 4; off += 4; } return n-i; | |
| 1999/0423 | case Qvideo: case Qjframe: | |
| 1999/0424 | return vwrite(c, buf, n, off); | |
| 1999/0423 | } | |
| 1999/0422 | } | |
| 1999/0423/sys/src/9/pc/devlml.c:533,540 – 1999/0424/sys/src/9/pc/devlml.c:767,781 | ||
| 1999/0422 | }; static void | |
| 1999/0423 |
| |
| 1999/0422 |
| |
| 1999/0424 | lmlintr(Ureg *, void *) { ulong flags = readl(pciBaseAddr+ZR36057_INTR_STAT); // print("MjpgDrv_intrHandler stat=0x%08x\n", flags); | |
| 1999/0422 | ||
| 1999/0424 | // Reset all interrupts from 067 writel(0xff000000, pciBaseAddr + ZR36057_INTR_STAT); | |
| 1999/0423 | ||
| 1999/0424 | if(flags & ZR36057_INTR_JPEGREP) wakeup(&sleeper); return; | |
| 1999/0422 | } | |
| 1999/0424/sys/src/9/pc/devlml.c:13,20 – 1999/0428/sys/src/9/pc/devlml.c:13,19 (short | long) | ||
| 1999/0422 | enum{ Q819, Q856, | |
| 1999/0428 | Qreg, | |
| 1999/0422 | Qvideo, Qjframe, }; | |
| 1999/0424/sys/src/9/pc/devlml.c:23,30 – 1999/0428/sys/src/9/pc/devlml.c:22,28 | ||
| 1999/0422 | // name, qid, size, mode "vid819", {Q819}, 0, 0644, "vid856", {Q856}, 0, 0644, | |
| 1999/0428 | "vidreg", {Qreg}, 0, 0644, | |
| 1999/0422 | "video", {Qvideo}, 0, 0666, "jframe", {Qjframe}, 0, 0666, }; | |
| 1999/0424/sys/src/9/pc/devlml.c:238,343 – 1999/0428/sys/src/9/pc/devlml.c:236,242 | ||
| 1999/0424 | return 1; } | |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 | ||
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0424/sys/src/9/pc/devlml.c:623,630 – 1999/0428/sys/src/9/pc/devlml.c:522,528 | ||
| 1999/0422 | switch(c->qid.path){ case Q819: case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0422 | break; case Qvideo: case Qjframe: | |
| 1999/0424/sys/src/9/pc/devlml.c:650,657 – 1999/0428/sys/src/9/pc/devlml.c:548,554 | ||
| 1999/0422 | switch(c->qid.path){ case Q819: case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0422 | case Qvideo: case Qjframe: authclose(c); | |
| 1999/0424/sys/src/9/pc/devlml.c:680,702 – 1999/0428/sys/src/9/pc/devlml.c:577,599 | ||
| 1999/0424 | *buf++ = d; } return n - i; | |
| 1999/0422 |
| |
| 1999/0424 |
| |
| 1999/0422 |
| |
| 1999/0428 | case Qreg: | |
| 1999/0424 | if (off < 0 || off + n > 0x200 || (off & 0x3)) return 0; | |
| 1999/0428 | switch(n) { case 1: *buf = readb(pciBaseAddr + off); break; case 2: *(short *)buf = readw(pciBaseAddr + off); break; case 4: | |
| 1999/0424 | *(long *)buf = readl(pciBaseAddr + off); | |
| 1999/0428 | break; default: return 0; | |
| 1999/0424 | } | |
| 1999/0428 | return n; | |
| 1999/0422 | case Qvideo: case Qjframe: | |
| 1999/0424 | return vread(c, buf, n, off); | |
| 1999/0424/sys/src/9/pc/devlml.c:723,744 – 1999/0428/sys/src/9/pc/devlml.c:620,642 | ||
| 1999/0424 | if (lml33_i2c_wr8(BT856Addr, off++, *buf++) == 0) break; return n - i; | |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0428 | case Qreg: | |
| 1999/0424 | if (off < 0 || off + n > 0x200 || (off & 0x3)) return 0; | |
| 1999/0428 | switch (n) { case 1: writeb(*buf, pciBaseAddr + off); break; case 2: writew(*(short *)buf, pciBaseAddr + off); break; case 4: | |
| 1999/0424 | writel(*(long *)buf, pciBaseAddr + off); | |
| 1999/0428 | break; default: return 0; | |
| 1999/0424 | } | |
| 1999/0428 | return n; | |
| 1999/0423 | case Qvideo: case Qjframe: | |
| 1999/0424 | return vwrite(c, buf, n, off); | |
| 1999/0428/sys/src/9/pc/devlml.c:38,43 – 1999/0429/sys/src/9/pc/devlml.c:38,44 (short | long) | ||
| 1999/0424 | int bufferPrepared; int hdrPos; int nopens; | |
| 1999/0429 | uchar q856[3]; | |
| 1999/0424 | static FrameHeader frameHeader = { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, | |
| 1999/0428/sys/src/9/pc/devlml.c:46,58 – 1999/0429/sys/src/9/pc/devlml.c:47,59 | ||
| 1999/0424 | }; | |
| 1999/0423 | static void | |
| 1999/0429 | i2c_pause(void) { | |
| 1999/0422 | ||
| 1999/0423 | microdelay(I2C_DELAY); } | |
| 1999/0422 | static void | |
| 1999/0423 |
| |
| 1999/0429 | i2c_waitscl(void) { | |
| 1999/0423 | int i; ulong a; | |
| 1999/0428/sys/src/9/pc/devlml.c:64,131 – 1999/0429/sys/src/9/pc/devlml.c:65,132 | ||
| 1999/0423 | } static void | |
| 1999/0429 | i2c_start(void) { | |
| 1999/0423 | writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 | writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | writel(0, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | } static void | |
| 1999/0429 | i2c_stop(void) { | |
| 1999/0423 | // the clock should already be low, make sure data is writel(0, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | // set clock high and wait for device to catch up writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 | // set the data high to indicate the stop bit writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | } | |
| 1999/0429 | static void i2c_wrbit(int bit) { | |
| 1999/0423 | if (bit){ writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); // set data | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 | writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | } else { writel(0, pciBaseAddr + ZR36057_I2C_BUS); // clr data | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 | writel(0, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | } } static int | |
| 1999/0429 | i2c_rdbit(void) { | |
| 1999/0423 | int bit; // the clk line should be low // ensure we are not asserting the data line writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | // set the clock high and wait for device to catch up writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 | // the data line should be a valid bit bit = readl(pciBaseAddr+ZR36057_I2C_BUS); | |
| 1999/0428/sys/src/9/pc/devlml.c:137,149 – 1999/0429/sys/src/9/pc/devlml.c:138,150 | ||
| 1999/0423 | // set the clock low to indicate end of cycle writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | return bit; } static int | |
| 1999/0429 | i2c_rdbyte(uchar *v) { | |
| 1999/0423 | int i, ack; uchar res; | |
| 1999/0428/sys/src/9/pc/devlml.c:150,159 – 1999/0429/sys/src/9/pc/devlml.c:151,160 | ||
| 1999/0423 | res = 0; for (i=0;i<8;i++){ res = res << 1; | |
| 1999/0429 | res += i2c_rdbit(); | |
| 1999/0423 | } | |
| 1999/0429 | ack = i2c_rdbit(); | |
| 1999/0423 | *v = res; | |
| 1999/0428/sys/src/9/pc/devlml.c:161,237 – 1999/0429/sys/src/9/pc/devlml.c:162,254 | ||
| 1999/0423 | } static int | |
| 1999/0429 | i2c_wrbyte(uchar v) { | |
| 1999/0423 | int i, ack; for (i=0;i<8;i++){ | |
| 1999/0429 | i2c_wrbit(v & 0x80); | |
| 1999/0423 | v = v << 1; } | |
| 1999/0429 | ack = i2c_rdbit(); | |
| 1999/0423 | return ack; } static void | |
| 1999/0429 | i2c_write_bytes(uchar addr, uchar sub, uchar *bytes, long num) { | |
| 1999/0423 | int ack; long i; | |
| 1999/0429 | i2c_start(); | |
| 1999/0423 |
| |
| 1999/0429 | ack = i2c_wrbyte(addr); | |
| 1999/0423 | if (ack == 1) error(Eio); | |
| 1999/0429 | ack = i2c_wrbyte(sub); | |
| 1999/0423 | if (ack == 1) error(Eio); for(i=0;i<num;i+=1){ | |
| 1999/0429 | ack = i2c_wrbyte(bytes[i]); | |
| 1999/0423 | if (ack == 1) error(Eio); } | |
| 1999/0429 | i2c_stop(); | |
| 1999/0423 | } | |
| 1999/0424 | static int | |
| 1999/0423 |
| |
| 1999/0429 | i2c_bt856rd8(void) { uchar ret; i2c_start (); if (i2c_wrbyte(BT856Addr + 1) == 1 || i2c_rdbyte(&ret) == 0) { i2c_stop (); return -1; } i2c_stop (); return ret; } static int i2c_rd8(int addr, int sub) | |
| 1999/0423 | { uchar msb; | |
| 1999/0429 | i2c_start(); | |
| 1999/0423 | ||
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0429 | if (i2c_wrbyte(addr) == 1 || i2c_wrbyte(sub) == 1) { i2c_stop(); | |
| 1999/0424 | return -1; | |
| 1999/0423 | } | |
| 1999/0429 | i2c_start(); | |
| 1999/0423 | ||
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0429 | if (i2c_wrbyte(addr+1) == 1 || i2c_rdbyte(&msb) == 0){ i2c_stop(); | |
| 1999/0424 | return -1; | |
| 1999/0423 | } | |
| 1999/0429 | i2c_stop(); | |
| 1999/0423 | return msb; } | |
| 1999/0424 | static int | |
| 1999/0429 | i2c_wr8(uchar addr, uchar sub, uchar msb) { | |
| 1999/0424 |
| |
| 1999/0429 | i2c_start(); | |
| 1999/0424 |
| |
| 1999/0429 | if (i2c_wrbyte(addr) == 1 || i2c_wrbyte(sub) == 1 || i2c_wrbyte(msb) == 1) | |
| 1999/0424 | return 0; | |
| 1999/0429 | i2c_stop(); | |
| 1999/0424 | return 1; } | |
| 1999/0428/sys/src/9/pc/devlml.c:565,582 – 1999/0429/sys/src/9/pc/devlml.c:582,613 | ||
| 1999/0424 | if (off < 0 || off + n > 0x20) | |
| 1999/0423 | return 0; | |
| 1999/0424 | for (i = 0; i < n; i++) { | |
| 1999/0429 | if ((d = i2c_rd8(BT819Addr, off++)) < 0) break; | |
| 1999/0424 | *buf++ = d; } return n - i; | |
| 1999/0422 | case Q856: | |
| 1999/0423 |
| |
| 1999/0429 | if (n != 1) | |
| 1999/0423 | return 0; | |
| 1999/0424 |
| |
| 1999/0429 | switch ((int)off) { case 0: if ((d = i2c_bt856rd8()) < 0) return 0; *buf = d; break; case 0xDA: *buf = q856[0]; break; case 0xDC: *buf = q856[1]; break; case 0xDE: *buf = q856[2]; break; default: return 0; | |
| 1999/0424 | } | |
| 1999/0429 | return 1; | |
| 1999/0428 | case Qreg: | |
| 1999/0424 | if (off < 0 || off + n > 0x200 || (off & 0x3)) return 0; | |
| 1999/0428/sys/src/9/pc/devlml.c:610,625 – 1999/0429/sys/src/9/pc/devlml.c:641,666 | ||
| 1999/0424 | if (off < 0 || off + n > 0x20) | |
| 1999/0423 | return 0; | |
| 1999/0424 | for (i = n; i > 0; i--) | |
| 1999/0429 | if (i2c_wr8(BT819Addr, off++, *buf++) == 0) | |
| 1999/0424 | break; return n - i; | |
| 1999/0423 | case Q856: | |
| 1999/0429 | if (n != 1 || off < 0xda || off + n > 0xe0) | |
| 1999/0423 | return 0; | |
| 1999/0424 |
| |
| 1999/0429 | if (i2c_wr8(BT856Addr, off, *buf) == 0) return 0; switch ((int)off) { case 0xDA: q856[0] = *buf; break; case 0xDC: q856[1] = *buf; break; case 0xDE: q856[2] = *buf; break; } return 1; | |
| 1999/0428 | case Qreg: | |
| 1999/0424 | if (off < 0 || off + n > 0x200 || (off & 0x3)) return 0; | |
| 1999/0429/sys/src/9/pc/devlml.c:405,412 – 1999/0430/sys/src/9/pc/devlml.c:405,412 (short | long) | ||
| 1999/0424 | memmove((char*)&frameHeader + hdrPos, buf, hdrLeft); // Make sure we have a standard LML33 header if (frameHeader.mrkSOI == MRK_SOI | |
| 1999/0430 | && frameHeader.mrkAPP3 == MRK_APP3 && strcmp(frameHeader.nm, APP_NAME) == 0) { | |
| 1999/0424 | //print("Starting new buffer len=0x%x frame=%d\n", frameHeader.frameSize, frameHeader.frameSeqNo); // Obtain values we need for playback process from the header currentBufferLength = frameHeader.frameSize; | |
| 1999/0429/sys/src/9/pc/devlml.c:609,615 – 1999/0430/sys/src/9/pc/devlml.c:609,615 | ||
| 1999/0424 | } | |
| 1999/0429 | return 1; | |
| 1999/0428 | case Qreg: | |
| 1999/0424 |
| |
| 1999/0430 | if (off < 0 || off + n > 0x400) | |
| 1999/0424 | return 0; | |
| 1999/0428 | switch(n) { case 1: | |
| 1999/0429/sys/src/9/pc/devlml.c:616,624 – 1999/0430/sys/src/9/pc/devlml.c:616,626 | ||
| 1999/0428 | *buf = readb(pciBaseAddr + off); break; case 2: | |
| 1999/0430 | if (off & (n-1)) return 0; | |
| 1999/0428 | *(short *)buf = readw(pciBaseAddr + off); break; case 4: | |
| 1999/0430 | if (off & (n-1)) return 0; | |
| 1999/0424 | *(long *)buf = readl(pciBaseAddr + off); | |
| 1999/0428 | break; default: | |
| 1999/0430/sys/src/9/pc/devlml.c:11,43 – 1999/0513/sys/src/9/pc/devlml.c:11,44 (short | long) | ||
| 1999/0422 | // Lml 22 driver enum{ | |
| 1999/0513 | Qdir, | |
| 1999/0422 | Q819, Q856, | |
| 1999/0428 | Qreg, | |
| 1999/0422 |
| |
| 1999/0513 | Qjvideo, | |
| 1999/0422 | Qjframe, }; | |
| 1999/0428 |
| |
| 1999/0422 |
| |
| 1999/0513 | static Dirtab lmldir[]={ // name, qid, size, mode "lml819", {Q819}, 0, 0644, "lml856", {Q856}, 0, 0644, "lmlreg", {Qreg}, 0, 0644, "jvideo", {Qjvideo}, 0, 0666, | |
| 1999/0422 | "jframe", {Qjframe}, 0, 0666, }; CodeData * codeData; | |
| 1999/0424 |
| |
| 1999/0513 | int currentBuffer; int currentBufferLength; | |
| 1999/0424 | void * currentBufferPtr; | |
| 1999/0513 | int frameNo; | |
| 1999/0424 | Rendez sleeper; | |
| 1999/0513 | int singleFrame; int bufferPrepared; int hdrPos; int nopens; | |
| 1999/0429 | uchar q856[3]; | |
| 1999/0424 | static FrameHeader frameHeader = { | |
| 1999/0430/sys/src/9/pc/devlml.c:455,461 – 1999/0513/sys/src/9/pc/devlml.c:456,462 | ||
| 1999/0423 | static void lmlintr(Ureg *, void *); static void | |
| 1999/0422 |
| |
| 1999/0513 | lmlreset(void) | |
| 1999/0422 | { ulong regpa; int i; | |
| 1999/0430/sys/src/9/pc/devlml.c:462,468 – 1999/0513/sys/src/9/pc/devlml.c:463,468 | ||
| 1999/0422 | ||
| 1999/0423 | pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067); if (pcidev == nil) { | |
| 1999/0422 | codeData = (CodeData*)xspanalloc(sizeof(CodeData), BY2PG, 0); | |
| 1999/0430/sys/src/9/pc/devlml.c:472,478 – 1999/0513/sys/src/9/pc/devlml.c:472,478 | ||
| 1999/0422 | } print("Installing Motion JPEG driver %s\n", MJPG_VERSION); | |
| 1999/0513 | print("Buffer at 0x%.8lux, size 0x%.8ux\n", codeData, sizeof(CodeData)); | |
| 1999/0422 | // Get access to DMA memory buffer memset(codeData, 0xAA, sizeof(CodeData)); | |
| 1999/0430/sys/src/9/pc/devlml.c:491,497 – 1999/0513/sys/src/9/pc/devlml.c:491,497 | ||
| 1999/0422 | ||
| 1999/0423 | pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F); | |
| 1999/0422 | ||
| 1999/0423 |
| |
| 1999/0513 | print("zr36067 found at 0x%.8lux", pciPhysBaseAddr); | |
| 1999/0422 | ||
| 1999/0423 | regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0); | |
| 1999/0422 | if (regpa == 0) { | |
| 1999/0430/sys/src/9/pc/devlml.c:499,504 – 1999/0513/sys/src/9/pc/devlml.c:499,505 | ||
| 1999/0422 | return; } | |
| 1999/0423 | pciBaseAddr = (ulong)KADDR(regpa); | |
| 1999/0513 | print(", mapped at 0x%.8lux\n", pciBaseAddr); | |
| 1999/0422 | // make sure the device will respond to mem accesses // (pcicmd_master | pcicmd_memory) -- probably superfluous | |
| 1999/0430/sys/src/9/pc/devlml.c:510,539 – 1999/0513/sys/src/9/pc/devlml.c:511,539 | ||
| 1999/0422 | // Interrupt handler | |
| 1999/0423 | intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); | |
| 1999/0422 |
| |
| 1999/0513 | lmlattach(char *spec) | |
| 1999/0422 | { return devattach('V', spec); } static int | |
| 1999/0513 | lmlwalk(Chan *c, char *name) | |
| 1999/0422 | { | |
| 1999/0513 | return devwalk(c, name, lmldir, nelem(lmldir), devgen); | |
| 1999/0422 | } static void | |
| 1999/0513 | lmlstat(Chan *c, char *dp) | |
| 1999/0422 | { | |
| 1999/0513 | devstat(c, dp, lmldir, nelem(lmldir), devgen); | |
| 1999/0422 | } static Chan* | |
| 1999/0513 | lmlopen(Chan *c, int omode) | |
| 1999/0422 | { c->aux = 0; switch(c->qid.path){ | |
| 1999/0430/sys/src/9/pc/devlml.c:541,547 – 1999/0513/sys/src/9/pc/devlml.c:541,547 | ||
| 1999/0422 | case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0422 | break; | |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0424 | if (nopens) error(Einuse); | |
| 1999/0430/sys/src/9/pc/devlml.c:556,572 – 1999/0513/sys/src/9/pc/devlml.c:556,572 | ||
| 1999/0422 | // allow one open total for these two break; } | |
| 1999/0513 | return devopen(c, omode, lmldir, nelem(lmldir), devgen); | |
| 1999/0422 | } static void | |
| 1999/0513 | lmlclose(Chan *c) | |
| 1999/0422 | { switch(c->qid.path){ case Q819: case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0422 |
| |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: authclose(c); } | |
| 1999/0430/sys/src/9/pc/devlml.c:573,583 – 1999/0513/sys/src/9/pc/devlml.c:573,589 | ||
| 1999/0422 | } static long | |
| 1999/0424 |
| |
| 1999/0513 | lmlread(Chan *c, void *va, long n, vlong voff) { | |
| 1999/0424 | int i, d; uchar *buf = va; | |
| 1999/0513 | long off = voff; long v; | |
| 1999/0423 | ||
| 1999/0422 |
| |
| 1999/0513 | switch(c->qid.path & ~CHDIR){ case Qdir: return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen); | |
| 1999/0422 | case Q819: | |
| 1999/0424 | if (off < 0 || off + n > 0x20) | |
| 1999/0423 | return 0; | |
| 1999/0430/sys/src/9/pc/devlml.c:621,633 – 1999/0513/sys/src/9/pc/devlml.c:627,641 | ||
| 1999/0428 | break; case 4: | |
| 1999/0430 | if (off & (n-1)) return 0; | |
| 1999/0424 |
| |
| 1999/0513 | v = readl(pciBaseAddr + off); *(long *)buf = v; print("reading %lux at %lux (%lux)\n", v, pciBaseAddr + off, off); | |
| 1999/0428 | break; default: return 0; | |
| 1999/0424 | } | |
| 1999/0428 | return n; | |
| 1999/0422 |
| |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0424 | return vread(c, buf, n, off); | |
| 1999/0422 | } | |
| 1999/0430/sys/src/9/pc/devlml.c:634,644 – 1999/0513/sys/src/9/pc/devlml.c:642,656 | ||
| 1999/0422 | } static long | |
| 1999/0424 |
| |
| 1999/0513 | lmlwrite(Chan *c, void *va, long n, vlong off) { | |
| 1999/0424 | int i; uchar *buf = va; | |
| 1999/0423 |
| |
| 1999/0513 | switch(c->qid.path & ~CHDIR){ case Qdir: error(Eperm); | |
| 1999/0423 | case Q819: | |
| 1999/0424 | if (off < 0 || off + n > 0x20) | |
| 1999/0423 | return 0; | |
| 1999/0430/sys/src/9/pc/devlml.c:680,707 – 1999/0513/sys/src/9/pc/devlml.c:692,719 | ||
| 1999/0428 | return 0; | |
| 1999/0424 | } | |
| 1999/0428 | return n; | |
| 1999/0423 |
| |
| 1999/0513 | case Qjvideo: | |
| 1999/0423 | case Qjframe: | |
| 1999/0424 | return vwrite(c, buf, n, off); | |
| 1999/0423 | } | |
| 1999/0422 | } | |
| 1999/0513 | Dev lmldevtab = { | |
| 1999/0422 | 'V', "video", | |
| 1999/0513 | lmlreset, | |
| 1999/0422 | devinit, | |
| 1999/0513 | lmlattach, | |
| 1999/0422 | devclone, | |
| 1999/0513 | lmlwalk, lmlstat, lmlopen, | |
| 1999/0422 | devcreate, | |
| 1999/0513 | lmlclose, lmlread, | |
| 1999/0422 | devbread, | |
| 1999/0513 | lmlwrite, | |
| 1999/0422 | devbwrite, devremove, devwstat, | |
| 1999/0513/sys/src/9/pc/devlml.c:642,650 – 1999/0514/sys/src/9/pc/devlml.c:642,651 (short | long) | ||
| 1999/0422 | } static long | |
| 1999/0513 |
| |
| 1999/0514 | lmlwrite(Chan *c, void *va, long n, vlong voff) { | |
| 1999/0424 | int i; uchar *buf = va; | |
| 1999/0514 | long off = voff; | |
| 1999/0423 | ||
| 1999/0513 | switch(c->qid.path & ~CHDIR){ | |
| 1999/0513/sys/src/9/pc/devlml.c:686,691 – 1999/0514/sys/src/9/pc/devlml.c:687,693 | ||
| 1999/0428 | writew(*(short *)buf, pciBaseAddr + off); break; case 4: | |
| 1999/0514 | print("writing %lux to %lux (%lux)\n", *(long *)buf, pciBaseAddr + off, off); | |
| 1999/0424 | writel(*(long *)buf, pciBaseAddr + off); | |
| 1999/0428 | break; default: | |
| 1999/0514/sys/src/9/pc/devlml.c:8,13 – 1999/0515/sys/src/9/pc/devlml.c:8,18 (short | long) | ||
| 1999/0422 | #include "devlml.h" | |
| 1999/0515 | #define DBGREGS 0x1 #define DBGREAD 0x2 #define DBGWRIT 0x4 int debug = DBGREAD|DBGWRIT; | |
| 1999/0422 | // Lml 22 driver enum{ | |
| 1999/0514/sys/src/9/pc/devlml.c:15,20 – 1999/0515/sys/src/9/pc/devlml.c:20,26 | ||
| 1999/0422 | Q819, Q856, | |
| 1999/0428 | Qreg, | |
| 1999/0515 | Qmap, | |
| 1999/0513 | Qjvideo, | |
| 1999/0422 | Qjframe, }; | |
| 1999/0514/sys/src/9/pc/devlml.c:24,29 – 1999/0515/sys/src/9/pc/devlml.c:30,36 | ||
| 1999/0513 | "lml819", {Q819}, 0, 0644, "lml856", {Q856}, 0, 0644, "lmlreg", {Qreg}, 0, 0644, | |
| 1999/0515 | "lmlmap", {Qmap}, 0, 0444, | |
| 1999/0513 | "jvideo", {Qjvideo}, 0, 0666, | |
| 1999/0422 | "jframe", {Qjframe}, 0, 0666, }; | |
| 1999/0514/sys/src/9/pc/devlml.c:41,46 – 1999/0515/sys/src/9/pc/devlml.c:48,59 | ||
| 1999/0513 | int nopens; | |
| 1999/0429 | uchar q856[3]; | |
| 1999/0424 | ||
| 1999/0515 | struct { ulong pci; ulong dma; ulong codedata; } lmlmap; | |
| 1999/0424 | static FrameHeader frameHeader = { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, { 'L', 'M', 'L', '\0'}, | |
| 1999/0514/sys/src/9/pc/devlml.c:47,52 – 1999/0515/sys/src/9/pc/devlml.c:60,122 | ||
| 1999/0424 | -1, 0, 0, 0, 0 }; | |
| 1999/0515 | ulong writel(ulong v, ulong a) { if (debug&DBGREGS) pprint("writing %.8lux to %.8lux (%.4lux)\n", v, a, (ulong)a-pciBaseAddr); return *(ulong *)a = v; } ushort writew(ushort v, ulong a) { if (debug&DBGREGS) pprint("writing %.4ux to %.8lux (%.4lux)\n", v, a, (ulong)a-pciBaseAddr); return *(ushort *)a = v; } uchar writeb(uchar v, ulong a) { if (debug&DBGREGS) pprint("writing %.2ux to %.8lux (%.4lux)\n", v, a, (ulong)a-pciBaseAddr); return *(uchar *)a = v; } ulong readl(ulong a) { ulong v; v = *(ulong*)a; if (debug&DBGREGS) pprint("reading %.8lux from %.8lux (%.4lux)\n", v, a, (ulong)a-pciBaseAddr); return v; } ushort readw(ulong a) { ushort v; v = *(ushort*)a; if (debug&DBGREGS) pprint("reading %.4ux from %.8lux (%.4lux)\n", v, a, (ulong)a-pciBaseAddr); return v; } uchar readb(ulong a) { uchar v; v = *(uchar*)a; if (debug&DBGREGS) pprint("reading %.2ux from %.8lux (%.4lux)\n", v, a, (ulong)a-pciBaseAddr); return v; } | |
| 1999/0423 | static void | |
| 1999/0429 | i2c_pause(void) { | |
| 1999/0422 | ||
| 1999/0514/sys/src/9/pc/devlml.c:222,227 – 1999/0515/sys/src/9/pc/devlml.c:292,298 | ||
| 1999/0423 | ||
| 1999/0429 | if (i2c_wrbyte(addr) == 1 || i2c_wrbyte(sub) == 1) { | |
| 1999/0515 | if (debug&DBGREGS) pprint("i2c_rd8, failure 1\n"); | |
| 1999/0429 | i2c_stop(); | |
| 1999/0424 | return -1; | |
| 1999/0423 | } | |
| 1999/0514/sys/src/9/pc/devlml.c:230,235 – 1999/0515/sys/src/9/pc/devlml.c:301,307 | ||
| 1999/0423 | ||
| 1999/0429 | if (i2c_wrbyte(addr+1) == 1 || i2c_rdbyte(&msb) == 0){ | |
| 1999/0515 | if (debug&DBGREGS) pprint("i2c_rd8, failure 2\n"); | |
| 1999/0429 | i2c_stop(); | |
| 1999/0424 | return -1; | |
| 1999/0423 | } | |
| 1999/0514/sys/src/9/pc/devlml.c:303,312 – 1999/0515/sys/src/9/pc/devlml.c:375,387 | ||
| 1999/0424 | vlong thetime; uchar *buf = va; | |
| 1999/0515 | if(debug&DBGREAD) pprint("devlml::vread() count=%ld pos=%lld\n", count, pos); | |
| 1999/0424 | // If we just begin reading a file, pos would never be 0 otherwise if (pos == 0 && hdrPos == -1) { | |
| 1999/0515 | if(debug&DBGREAD) pprint("devlml::first read\n"); | |
| 1999/0424 | currentBuffer = -1; currentBufferLength = 0; frameNo = -1; | |
| 1999/0514/sys/src/9/pc/devlml.c:316,327 – 1999/0515/sys/src/9/pc/devlml.c:391,408 | ||
| 1999/0424 | // We get to the end of the current buffer, also covers just // open file, since 0 >= -1 if(hdrPos == -1 && pos >= currentBufferLength) { | |
| 1999/0515 | if(debug&DBGREAD) pprint("devlml::prepareBuffer\n"); | |
| 1999/0424 | prepareBuffer(codeData, currentBuffer); // if not the first buffer read and single frame mode - return EOF if (currentBuffer != -1 && singleFrame) return 0; | |
| 1999/0515 | if(debug&DBGREAD) pprint("devlml::sleep\n"); | |
| 1999/0424 | while((currentBuffer = getProcessedBuffer(codeData)) == -1) sleep(&sleeper, return0, 0); | |
| 1999/0515 | if(debug&DBGREAD) pprint("devlml::wokeup\n"); | |
| 1999/0424 | currentBufferLength = getBuffer(codeData, currentBuffer, ¤tBufferPtr, &frameNo); | |
| 1999/0514/sys/src/9/pc/devlml.c:362,368 – 1999/0515/sys/src/9/pc/devlml.c:443,449 | ||
| 1999/0424 | memmove(buf + retcount, (char *)currentBufferPtr + pos, cpcount); retcount += cpcount; | |
| 1999/0515 | //pr_debug&DBGREGS("return %d %d\n",cpcount,retcount); | |
| 1999/0424 | return retcount; | |
| 1999/0423 | } | |
| 1999/0514/sys/src/9/pc/devlml.c:511,516 – 1999/0515/sys/src/9/pc/devlml.c:592,601 | ||
| 1999/0422 | // Interrupt handler | |
| 1999/0423 | intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); | |
| 1999/0422 | ||
| 1999/0515 | lmlmap.pci = pciBaseAddr; lmlmap.dma = PADDR(codeData); lmlmap.codedata = (ulong)codeData; | |
| 1999/0422 | return; } | |
| 1999/0514/sys/src/9/pc/devlml.c:540,545 – 1999/0515/sys/src/9/pc/devlml.c:625,631 | ||
| 1999/0422 | case Q819: case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0515 | case Qmap: | |
| 1999/0422 | break; | |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0514/sys/src/9/pc/devlml.c:566,573 – 1999/0515/sys/src/9/pc/devlml.c:652,663 | ||
| 1999/0422 | case Q819: case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0515 | case Qmap: authclose(c); break; | |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0515 | nopens = 0; | |
| 1999/0422 | authclose(c); } } | |
| 1999/0514/sys/src/9/pc/devlml.c:577,583 – 1999/0515/sys/src/9/pc/devlml.c:667,672 | ||
| 1999/0424 | int i, d; uchar *buf = va; | |
| 1999/0513 | long off = voff; | |
| 1999/0423 | ||
| 1999/0513 | switch(c->qid.path & ~CHDIR){ | |
| 1999/0514/sys/src/9/pc/devlml.c:591,597 – 1999/0515/sys/src/9/pc/devlml.c:680,686 | ||
| 1999/0429 | if ((d = i2c_rd8(BT819Addr, off++)) < 0) break; | |
| 1999/0424 | *buf++ = d; } | |
| 1999/0515 | return i; | |
| 1999/0422 | case Q856: | |
| 1999/0429 | if (n != 1) | |
| 1999/0423 | return 0; | |
| 1999/0514/sys/src/9/pc/devlml.c:614,619 – 1999/0515/sys/src/9/pc/devlml.c:703,717 | ||
| 1999/0429 | return 0; | |
| 1999/0424 | } | |
| 1999/0429 | return 1; | |
| 1999/0515 | case Qmap: if (off < 0) return 0; for (i = 0; i < n; i++) { if (off + i > sizeof lmlmap) break; buf[i] = ((uchar *)&lmlmap)[off + i]; } return i; | |
| 1999/0428 | case Qreg: | |
| 1999/0430 | if (off < 0 || off + n > 0x400) | |
| 1999/0424 | return 0; | |
| 1999/0514/sys/src/9/pc/devlml.c:627,635 – 1999/0515/sys/src/9/pc/devlml.c:725,731 | ||
| 1999/0428 | break; case 4: | |
| 1999/0430 | if (off & (n-1)) return 0; | |
| 1999/0513 |
| |
| 1999/0515 | *(long *)buf = readl(pciBaseAddr + off); | |
| 1999/0428 | break; default: return 0; | |
| 1999/0514/sys/src/9/pc/devlml.c:658,664 – 1999/0515/sys/src/9/pc/devlml.c:754,760 | ||
| 1999/0424 | for (i = n; i > 0; i--) | |
| 1999/0429 | if (i2c_wr8(BT819Addr, off++, *buf++) == 0) | |
| 1999/0424 | break; | |
| 1999/0515 | return i; | |
| 1999/0423 | case Q856: | |
| 1999/0429 | if (n != 1 || off < 0xda || off + n > 0xe0) | |
| 1999/0423 | return 0; | |
| 1999/0514/sys/src/9/pc/devlml.c:677,683 – 1999/0515/sys/src/9/pc/devlml.c:773,779 | ||
| 1999/0429 | } return 1; | |
| 1999/0428 | case Qreg: | |
| 1999/0424 |
| |
| 1999/0515 | if (off < 0 || off + n > 0x400) | |
| 1999/0424 | return 0; | |
| 1999/0428 | switch (n) { case 1: | |
| 1999/0514/sys/src/9/pc/devlml.c:684,693 – 1999/0515/sys/src/9/pc/devlml.c:780,792 | ||
| 1999/0428 | writeb(*buf, pciBaseAddr + off); break; case 2: | |
| 1999/0515 | if (off & 0x1) return 0; | |
| 1999/0428 | writew(*(short *)buf, pciBaseAddr + off); break; case 4: | |
| 1999/0514 |
| |
| 1999/0515 | if (off & 0x3) return 0; | |
| 1999/0424 | writel(*(long *)buf, pciBaseAddr + off); | |
| 1999/0428 | break; default: | |
| 1999/0514/sys/src/9/pc/devlml.c:725,736 – 1999/0515/sys/src/9/pc/devlml.c:824,839 | ||
| 1999/0424 | lmlintr(Ureg *, void *) { ulong flags = readl(pciBaseAddr+ZR36057_INTR_STAT); | |
| 1999/0515 | if(debug&(DBGREAD|DBGWRIT)) print("MjpgDrv_intrHandler stat=0x%.8lux\n", flags); | |
| 1999/0422 | ||
| 1999/0424 | // Reset all interrupts from 067 writel(0xff000000, pciBaseAddr + ZR36057_INTR_STAT); | |
| 1999/0423 | ||
| 1999/0424 |
| |
| 1999/0515 | if(flags & ZR36057_INTR_JPEGREP) { if(debug&(DBGREAD|DBGWRIT)) print("MjpgDrv_intrHandler wakeup\n"); wakeup(&sleeper); } | |
| 1999/0424 | return; | |
| 1999/0422 | } | |
| 1999/0515/sys/src/9/pc/devlml.c:11,20 – 1999/0517/sys/src/9/pc/devlml.c:11,26 (short | long) | ||
| 1999/0515 | #define DBGREGS 0x1 #define DBGREAD 0x2 #define DBGWRIT 0x4 | |
| 1999/0517 | int debug = DBGREAD|DBGWRIT|DBGREGS; | |
| 1999/0515 | ||
| 1999/0422 | // Lml 22 driver | |
| 1999/0517 | struct { ulong pci; ulong dma; ulong codedata; } lmlmap; | |
| 1999/0422 | enum{ | |
| 1999/0513 | Qdir, | |
| 1999/0422 | Q819, | |
| 1999/0515/sys/src/9/pc/devlml.c:29,36 – 1999/0517/sys/src/9/pc/devlml.c:35,42 | ||
| 1999/0513 | // name, qid, size, mode "lml819", {Q819}, 0, 0644, "lml856", {Q856}, 0, 0644, | |
| 1999/0515 |
| |
| 1999/0517 | "lmlreg", {Qreg}, 0x400, 0644, "lmlmap", {Qmap}, sizeof lmlmap, 0444, | |
| 1999/0513 | "jvideo", {Qjvideo}, 0, 0666, | |
| 1999/0422 | "jframe", {Qjframe}, 0, 0666, }; | |
| 1999/0515/sys/src/9/pc/devlml.c:48,59 – 1999/0517/sys/src/9/pc/devlml.c:54,59 | ||
| 1999/0513 | int nopens; | |
| 1999/0429 | uchar q856[3]; | |
| 1999/0424 | ||
| 1999/0515 |
| |
| 1999/0424 | static FrameHeader frameHeader = { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, { 'L', 'M', 'L', '\0'}, | |
| 1999/0515/sys/src/9/pc/devlml.c:63,70 – 1999/0517/sys/src/9/pc/devlml.c:63,70 | ||
| 1999/0515 | ulong writel(ulong v, ulong a) { if (debug&DBGREGS) | |
| 1999/0517 | pprint("%.8lux (%.8lux) <-- %.8lux\n", a, (ulong)a-pciBaseAddr, v); | |
| 1999/0515 | return *(ulong *)a = v; } | |
| 1999/0515/sys/src/9/pc/devlml.c:71,78 – 1999/0517/sys/src/9/pc/devlml.c:71,78 | ||
| 1999/0515 | ushort writew(ushort v, ulong a) { if (debug&DBGREGS) | |
| 1999/0517 | pprint("%.8lux (%.8lux) <-- %.4ux\n", a, (ulong)a-pciBaseAddr, v); | |
| 1999/0515 | return *(ushort *)a = v; } | |
| 1999/0515/sys/src/9/pc/devlml.c:79,86 – 1999/0517/sys/src/9/pc/devlml.c:79,86 | ||
| 1999/0515 | uchar writeb(uchar v, ulong a) { if (debug&DBGREGS) | |
| 1999/0517 | pprint("%.8lux (%.8lux) <-- %.2ux\n", a, (ulong)a-pciBaseAddr, v); | |
| 1999/0515 | return *(uchar *)a = v; } | |
| 1999/0515/sys/src/9/pc/devlml.c:90,97 – 1999/0517/sys/src/9/pc/devlml.c:90,97 | ||
| 1999/0515 | v = *(ulong*)a; if (debug&DBGREGS) | |
| 1999/0517 | pprint("%.8lux (%.8lux) --> %.8lux\n", a, (ulong)a-pciBaseAddr, v); | |
| 1999/0515 | return v; } | |
| 1999/0515/sys/src/9/pc/devlml.c:101,108 – 1999/0517/sys/src/9/pc/devlml.c:101,108 | ||
| 1999/0515 | v = *(ushort*)a; if (debug&DBGREGS) | |
| 1999/0517 | pprint("%.8lux (%.8lux) --> %.4ux\n", a, (ulong)a-pciBaseAddr, v); | |
| 1999/0515 | return v; } | |
| 1999/0515/sys/src/9/pc/devlml.c:112,119 – 1999/0517/sys/src/9/pc/devlml.c:112,119 | ||
| 1999/0515 | v = *(uchar*)a; if (debug&DBGREGS) | |
| 1999/0517 | pprint("%.8lux (%.8lux) --> %.2ux\n", a, (ulong)a-pciBaseAddr, v); | |
| 1999/0515 | return v; } | |
| 1999/0515/sys/src/9/pc/devlml.c:330,336 – 1999/0517/sys/src/9/pc/devlml.c:330,336 | ||
| 1999/0424 | prepareBuffer(CodeData * this, int bufferNo) { if(bufferNo >= 0 && bufferNo < NBUF && (this->statCom[bufferNo] & STAT_BIT)) { this->statCom[bufferNo] = this->statComInitial[bufferNo]; | |
| 1999/0517 | return this->fragdesc[bufferNo].leng; | |
| 1999/0424 | } else return -1; } | |
| 1999/0515/sys/src/9/pc/devlml.c:354,360 – 1999/0517/sys/src/9/pc/devlml.c:354,360 | ||
| 1999/0424 | getBuffer(CodeData *this, int bufferNo, void** bufferPtr, int* frameNo) { int codeLength; if(this->statCom[bufferNo] & STAT_BIT) { | |
| 1999/0517 | *bufferPtr = (void*)this->fragdesc[bufferNo].addr; | |
| 1999/0424 | *frameNo = this->statCom[bufferNo] >> 24; codeLength=((this->statCom[bufferNo] & 0x00FFFFFF) >> 1); return codeLength; | |
| 1999/0515/sys/src/9/pc/devlml.c:560,571 – 1999/0517/sys/src/9/pc/devlml.c:560,570 | ||
| 1999/0422 | strncpy(codeData->idString, MJPG_VERSION, strlen(MJPG_VERSION)); for(i = 0; i < NBUF; i++) { | |
| 1999/0517 | codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); | |
| 1999/0422 | codeData->statComInitial[i] = codeData->statCom[i]; | |
| 1999/0423 |
| |
| 1999/0517 | codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i])); | |
| 1999/0422 | // Length is in double words, in position 1..20 | |
| 1999/0517 | codeData->fragdesc[i].leng = (FRAGSIZE >> 1) | FRAGM_FINAL_B; | |
| 1999/0422 | } print("initializing LML33 board..."); | |
| 1999/0515/sys/src/9/pc/devlml.c:620,625 – 1999/0517/sys/src/9/pc/devlml.c:619,626 | ||
| 1999/0422 | static Chan* | |
| 1999/0513 | lmlopen(Chan *c, int omode) | |
| 1999/0422 | { | |
| 1999/0517 | int i; | |
| 1999/0422 | c->aux = 0; switch(c->qid.path){ case Q819: | |
| 1999/0515/sys/src/9/pc/devlml.c:639,645 – 1999/0517/sys/src/9/pc/devlml.c:640,653 | ||
| 1999/0424 | frameNo = 0; bufferPrepared = 0; hdrPos = -1; | |
| 1999/0517 | for (i = 0; i < 4; i++) { codeData->statCom[i] = codeData->statComInitial[i]; // Also memset the buffer with some fill value memset(&(codeData->frag[i]),0x55,sizeof codeData->frag[i]); } | |
| 1999/0422 | // allow one open total for these two | |
| 1999/0517 | intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); | |
| 1999/0422 | break; } | |
| 1999/0513 | return devopen(c, omode, lmldir, nelem(lmldir), devgen); | |
| 1999/0515/sys/src/9/pc/devlml.c:707,713 – 1999/0517/sys/src/9/pc/devlml.c:715,721 | ||
| 1999/0515 | if (off < 0) return 0; for (i = 0; i < n; i++) { | |
| 1999/0517 | if (off + i >= sizeof lmlmap) | |
| 1999/0515 | break; buf[i] = ((uchar *)&lmlmap)[off + i]; } | |
| 1999/0515/sys/src/9/pc/devlml.c:749,755 – 1999/0517/sys/src/9/pc/devlml.c:757,763 | ||
| 1999/0513 | error(Eperm); | |
| 1999/0423 | case Q819: | |
| 1999/0424 |
| |
| 1999/0517 | if (off < 0 || off + n >= 0x20) | |
| 1999/0423 | return 0; | |
| 1999/0424 | for (i = n; i > 0; i--) | |
| 1999/0429 | if (i2c_wr8(BT819Addr, off++, *buf++) == 0) | |
| 1999/0517/sys/src/9/pc/devlml.c:17,23 – 1999/0518/sys/src/9/pc/devlml.c:17,23 (short | long) | ||
| 1999/0422 | ||
| 1999/0517 | struct { ulong pci; | |
| 1999/0518 | ulong statcom; | |
| 1999/0517 | ulong codedata; } lmlmap; | |
| 1999/0517/sys/src/9/pc/devlml.c:27,32 – 1999/0518/sys/src/9/pc/devlml.c:27,33 | ||
| 1999/0422 | Q856, | |
| 1999/0428 | Qreg, | |
| 1999/0515 | Qmap, | |
| 1999/0518 | Qbuf, | |
| 1999/0513 | Qjvideo, | |
| 1999/0422 | Qjframe, }; | |
| 1999/0517/sys/src/9/pc/devlml.c:37,42 – 1999/0518/sys/src/9/pc/devlml.c:38,44 | ||
| 1999/0513 | "lml856", {Q856}, 0, 0644, | |
| 1999/0517 | "lmlreg", {Qreg}, 0x400, 0644, "lmlmap", {Qmap}, sizeof lmlmap, 0444, | |
| 1999/0518 | "lmlbuf", {Qbuf}, 0, 0644, | |
| 1999/0513 | "jvideo", {Qjvideo}, 0, 0666, | |
| 1999/0422 | "jframe", {Qjframe}, 0, 0666, }; | |
| 1999/0517/sys/src/9/pc/devlml.c:327,350 – 1999/0518/sys/src/9/pc/devlml.c:329,352 | ||
| 1999/0424 | } | |
| 1999/0423 | static int | |
| 1999/0424 |
| |
| 1999/0517 |
| |
| 1999/0424 |
| |
| 1999/0518 | prepareBuffer(int i) { if (i >= 0 && i < NBUF && (codeData->statCom[i] & STAT_BIT)) { codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); return codeData->fragdesc[i].leng; } else return -1; | |
| 1999/0424 | } | |
| 1999/0423 | ||
| 1999/0424 | static int | |
| 1999/0518 | getProcessedBuffer(void){ static lastBuffer = NBUF-1; int l = lastBuffer; | |
| 1999/0424 | while (1) { lastBuffer = (lastBuffer+1) % NBUF; | |
| 1999/0518 | if (codeData->statCom[lastBuffer] & STAT_BIT) | |
| 1999/0424 | return lastBuffer; | |
| 1999/0518 | if (lastBuffer == l) | |
| 1999/0424 | break; | |
| 1999/0423 | } | |
| 1999/0424 | return -1; | |
| 1999/0517/sys/src/9/pc/devlml.c:351,363 – 1999/0518/sys/src/9/pc/devlml.c:353,364 | ||
| 1999/0423 | } | |
| 1999/0424 | static int | |
| 1999/0517 |
| |
| 1999/0424 |
| |
| 1999/0518 | getBuffer(int i, void** bufferPtr, int* frameNo) { if(codeData->statCom[i] & STAT_BIT) { *bufferPtr = (void*)(&codeData->frag[i]); *frameNo = codeData->statCom[i] >> 24; return (codeData->statCom[i] & 0x00FFFFFF) >> 1; | |
| 1999/0424 | } else return -1; } | |
| 1999/0517/sys/src/9/pc/devlml.c:393,409 – 1999/0518/sys/src/9/pc/devlml.c:394,410 | ||
| 1999/0424 | if(hdrPos == -1 && pos >= currentBufferLength) { | |
| 1999/0515 | if(debug&DBGREAD) pprint("devlml::prepareBuffer\n"); | |
| 1999/0424 |
| |
| 1999/0518 | prepareBuffer(currentBuffer); | |
| 1999/0424 | // if not the first buffer read and single frame mode - return EOF if (currentBuffer != -1 && singleFrame) return 0; | |
| 1999/0515 | if(debug&DBGREAD) pprint("devlml::sleep\n"); | |
| 1999/0424 |
| |
| 1999/0518 | while((currentBuffer = getProcessedBuffer()) == -1) | |
| 1999/0424 | sleep(&sleeper, return0, 0); | |
| 1999/0515 | if(debug&DBGREAD) pprint("devlml::wokeup\n"); | |
| 1999/0424 |
| |
| 1999/0518 | currentBufferLength = getBuffer(currentBuffer, | |
| 1999/0424 | ¤tBufferPtr, &frameNo); pos = 0; // ?????????????? | |
| 1999/0517/sys/src/9/pc/devlml.c:466,476 – 1999/0518/sys/src/9/pc/devlml.c:467,477 | ||
| 1999/0424 | // We need next buffer to fill (either because we're done with the // current buffer) of because we're just beginning (but not into the header) if (hdrPos == -1 && pos >= currentBufferLength) { | |
| 1999/0518 | while((currentBuffer = getProcessedBuffer()) == -1) | |
| 1999/0424 | sleep(&sleeper, return0, 0); // print("current buffer %d\n",currentBuffer); | |
| 1999/0518 | getBuffer(currentBuffer, ¤tBufferPtr, &frameNo); | |
| 1999/0424 | // We need to receive the header now hdrPos = 0; } | |
| 1999/0517/sys/src/9/pc/devlml.c:526,532 – 1999/0518/sys/src/9/pc/devlml.c:527,533 | ||
| 1999/0424 | if(pos >= currentBufferLength) { // We have written the frame, time to display it //print("Passing written buffer to 067\n"); | |
| 1999/0518 | prepareBuffer(currentBuffer); | |
| 1999/0424 | bufferPrepared = 1; } //print("return 0x%lx 0x%x 0x%x 0x%x\n",pos,count,hdrLeft+count,currentBufferLength); | |
| 1999/0517/sys/src/9/pc/devlml.c:557,570 – 1999/0518/sys/src/9/pc/devlml.c:558,568 | ||
| 1999/0422 | // Get access to DMA memory buffer memset(codeData, 0xAA, sizeof(CodeData)); | |
| 1999/0517 | codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); | |
| 1999/0422 |
| |
| 1999/0517 | codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i])); | |
| 1999/0422 | // Length is in double words, in position 1..20 | |
| 1999/0517 |
| |
| 1999/0518 | codeData->fragdesc[i].leng = ((sizeof codeData->frag[i]) >> 1) | FRAGM_FINAL_B; | |
| 1999/0422 | } print("initializing LML33 board..."); | |
| 1999/0517/sys/src/9/pc/devlml.c:592,598 – 1999/0518/sys/src/9/pc/devlml.c:590,596 | ||
| 1999/0423 | intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); | |
| 1999/0422 | ||
| 1999/0515 | lmlmap.pci = pciBaseAddr; | |
| 1999/0518 | lmlmap.statcom = PADDR(codeData->statCom); | |
| 1999/0515 | lmlmap.codedata = (ulong)codeData; | |
| 1999/0422 | return; | |
| 1999/0517/sys/src/9/pc/devlml.c:617,625 – 1999/0518/sys/src/9/pc/devlml.c:615,621 | ||
| 1999/0422 | } static Chan* | |
| 1999/0513 |
| |
| 1999/0422 |
| |
| 1999/0517 |
| |
| 1999/0518 | lmlopen(Chan *c, int omode) { | |
| 1999/0517 | ||
| 1999/0422 | c->aux = 0; switch(c->qid.path){ | |
| 1999/0517/sys/src/9/pc/devlml.c:627,632 – 1999/0518/sys/src/9/pc/devlml.c:623,629 | ||
| 1999/0422 | case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0515 | case Qmap: | |
| 1999/0518 | case Qbuf: | |
| 1999/0422 | break; | |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0517/sys/src/9/pc/devlml.c:641,653 – 1999/0518/sys/src/9/pc/devlml.c:638,644 | ||
| 1999/0424 | bufferPrepared = 0; hdrPos = -1; | |
| 1999/0517 |
| |
| 1999/0422 | // allow one open total for these two | |
| 1999/0517 |
| |
| 1999/0422 | break; } | |
| 1999/0513 | return devopen(c, omode, lmldir, nelem(lmldir), devgen); | |
| 1999/0517/sys/src/9/pc/devlml.c:654,666 – 1999/0518/sys/src/9/pc/devlml.c:645,658 | ||
| 1999/0422 | } static void | |
| 1999/0513 |
| |
| 1999/0422 |
| |
| 1999/0518 | lmlclose(Chan *c) { | |
| 1999/0422 | switch(c->qid.path){ case Q819: case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0515 | case Qmap: | |
| 1999/0518 | case Qbuf: | |
| 1999/0515 | authclose(c); break; | |
| 1999/0513 | case Qjvideo: | |
| 1999/0517/sys/src/9/pc/devlml.c:721,727 – 1999/0518/sys/src/9/pc/devlml.c:713,719 | ||
| 1999/0515 | } return i; | |
| 1999/0428 | case Qreg: | |
| 1999/0430 |
| |
| 1999/0518 | if (off < 0 || off + n >= 0x400) | |
| 1999/0424 | return 0; | |
| 1999/0428 | switch(n) { case 1: | |
| 1999/0517/sys/src/9/pc/devlml.c:739,744 – 1999/0518/sys/src/9/pc/devlml.c:731,755 | ||
| 1999/0428 | return 0; | |
| 1999/0424 | } | |
| 1999/0428 | return n; | |
| 1999/0518 | case Qbuf: if (off < 0 || off + n >= sizeof *codeData) return 0; switch(n) { case 1: *buf = readb((ulong)codeData + off); break; case 2: if (off & (n-1)) return 0; *(short *)buf = readw((ulong)codeData + off); break; case 4: if (off & (n-1)) return 0; *(long *)buf = readl((ulong)codeData + off); break; default: return 0; } return n; | |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0424 | return vread(c, buf, n, off); | |
| 1999/0517/sys/src/9/pc/devlml.c:781,787 – 1999/0518/sys/src/9/pc/devlml.c:792,798 | ||
| 1999/0429 | } return 1; | |
| 1999/0428 | case Qreg: | |
| 1999/0515 |
| |
| 1999/0518 | if (off < 0 || off + n >= 0x400) | |
| 1999/0424 | return 0; | |
| 1999/0428 | switch (n) { case 1: | |
| 1999/0517/sys/src/9/pc/devlml.c:796,801 – 1999/0518/sys/src/9/pc/devlml.c:807,833 | ||
| 1999/0515 | if (off & 0x3) return 0; | |
| 1999/0424 | writel(*(long *)buf, pciBaseAddr + off); | |
| 1999/0518 | break; default: return 0; } return n; case Qbuf: if (off < 0 || off + n >= sizeof *codeData) return 0; switch (n) { case 1: writeb(*buf, (ulong)codeData + off); break; case 2: if (off & 0x1) return 0; writew(*(short *)buf, (ulong)codeData + off); break; case 4: if (off & 0x3) return 0; writel(*(long *)buf, (ulong)codeData + off); | |
| 1999/0428 | break; default: return 0; | |
| 1999/0518/sys/src/9/pc/devlml.c:11,17 – 1999/0519/sys/src/9/pc/devlml.c:11,17 (short | long) | ||
| 1999/0515 | #define DBGREGS 0x1 #define DBGREAD 0x2 #define DBGWRIT 0x4 | |
| 1999/0517 |
| |
| 1999/0519 | int debug = DBGREAD|DBGWRIT; | |
| 1999/0515 | ||
| 1999/0422 | // Lml 22 driver | |
| 1999/0519/sys/src/9/pc/devlml.c:8,18 – 1999/0520/sys/src/9/pc/devlml.c:8,26 (short | long) | ||
| 1999/0422 | #include "devlml.h" | |
| 1999/0515 |
| |
| 1999/0519 |
| |
| 1999/0520 | static void * pciPhysBaseAddr; static ulong pciBaseAddr; static Pcidev * pcidev; | |
| 1999/0515 | ||
| 1999/0520 | #define DBGREGS 0x01 #define DBGREAD 0x02 #define DBGWRIT 0x04 #define DBG819 0x08 #define DBGINTR 0x10 #define DBGINTS 0x20 int debug = DBGREAD; | |
| 1999/0422 | // Lml 22 driver | |
| 1999/0517 | struct { | |
| 1999/0519/sys/src/9/pc/devlml.c:23,28 – 1999/0520/sys/src/9/pc/devlml.c:31,37 | ||
| 1999/0517 | ||
| 1999/0422 | enum{ | |
| 1999/0513 | Qdir, | |
| 1999/0520 | Q060, | |
| 1999/0422 | Q819, Q856, | |
| 1999/0428 | Qreg, | |
| 1999/0519/sys/src/9/pc/devlml.c:34,39 – 1999/0520/sys/src/9/pc/devlml.c:43,49 | ||
| 1999/0422 | ||
| 1999/0513 | static Dirtab lmldir[]={ // name, qid, size, mode | |
| 1999/0520 | "lml060", {Q060}, 0x400, 0644, | |
| 1999/0513 | "lml819", {Q819}, 0, 0644, "lml856", {Q856}, 0, 0644, | |
| 1999/0517 | "lmlreg", {Qreg}, 0x400, 0644, | |
| 1999/0519/sys/src/9/pc/devlml.c:45,50 – 1999/0520/sys/src/9/pc/devlml.c:55,67 | ||
| 1999/0422 | CodeData * codeData; | |
| 1999/0520 | typedef enum { New, Header, Body, Error, } State; | |
| 1999/0513 | int currentBuffer; int currentBufferLength; | |
| 1999/0424 | void * currentBufferPtr; | |
| 1999/0519/sys/src/9/pc/devlml.c:55,60 – 1999/0520/sys/src/9/pc/devlml.c:72,78 | ||
| 1999/0513 | int hdrPos; int nopens; | |
| 1999/0429 | uchar q856[3]; | |
| 1999/0520 | State state = New; | |
| 1999/0424 | static FrameHeader frameHeader = { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, | |
| 1999/0519/sys/src/9/pc/devlml.c:128,153 – 1999/0520/sys/src/9/pc/devlml.c:146,169 | ||
| 1999/0422 | static void | |
| 1999/0429 | i2c_waitscl(void) { | |
| 1999/0423 | int i; | |
| 1999/0520 | for (i = 0; i < I2C_TIMEOUT; i++) if (readl(pciBaseAddr + I2C_BUS) & I2C_SCL) return; error(Eio); | |
| 1999/0423 | } static void | |
| 1999/0429 | i2c_start(void) { | |
| 1999/0423 |
| |
| 1999/0520 | writel(I2C_SCL|I2C_SDA, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 |
| |
| 1999/0520 | writel(I2C_SCL, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 |
| |
| 1999/0520 | writel(0, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | } | |
| 1999/0519/sys/src/9/pc/devlml.c:154,188 – 1999/0520/sys/src/9/pc/devlml.c:170,204 | ||
| 1999/0423 | static void | |
| 1999/0429 | i2c_stop(void) { | |
| 1999/0423 | // the clock should already be low, make sure data is | |
| 1999/0520 | writel(0, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | // set clock high and wait for device to catch up | |
| 1999/0520 | writel(I2C_SCL, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 | // set the data high to indicate the stop bit | |
| 1999/0520 | writel(I2C_SCL|I2C_SDA, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | } | |
| 1999/0429 | static void i2c_wrbit(int bit) { | |
| 1999/0423 | if (bit){ | |
| 1999/0520 | writel(I2C_SDA, pciBaseAddr + I2C_BUS); // set data | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 |
| |
| 1999/0520 | writel(I2C_SDA|I2C_SCL, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 |
| |
| 1999/0520 | writel(I2C_SDA, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | } else { | |
| 1999/0520 | writel(0, pciBaseAddr + I2C_BUS); // clr data | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 |
| |
| 1999/0520 | writel(I2C_SCL, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 |
| |
| 1999/0520 | writel(0, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | } } | |
| 1999/0519/sys/src/9/pc/devlml.c:193,209 – 1999/0520/sys/src/9/pc/devlml.c:209,225 | ||
| 1999/0423 | // the clk line should be low // ensure we are not asserting the data line | |
| 1999/0520 | writel(I2C_SDA, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | // set the clock high and wait for device to catch up | |
| 1999/0520 | writel(I2C_SDA|I2C_SCL, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_waitscl(); i2c_pause(); | |
| 1999/0423 | // the data line should be a valid bit | |
| 1999/0520 | bit = readl(pciBaseAddr+I2C_BUS); if (bit & I2C_SDA){ | |
| 1999/0423 | bit = 1; } else { bit = 0; | |
| 1999/0519/sys/src/9/pc/devlml.c:210,216 – 1999/0520/sys/src/9/pc/devlml.c:226,232 | ||
| 1999/0423 | } // set the clock low to indicate end of cycle | |
| 1999/0520 | writel(I2C_SDA, pciBaseAddr + I2C_BUS); | |
| 1999/0429 | i2c_pause(); | |
| 1999/0423 | return bit; | |
| 1999/0519/sys/src/9/pc/devlml.c:222,228 – 1999/0520/sys/src/9/pc/devlml.c:238,244 | ||
| 1999/0423 | uchar res; res = 0; | |
| 1999/0520 | for (i = 0; i < 8; i++) { | |
| 1999/0423 | res = res << 1; | |
| 1999/0429 | res += i2c_rdbit(); | |
| 1999/0423 | } | |
| 1999/0519/sys/src/9/pc/devlml.c:238,244 – 1999/0520/sys/src/9/pc/devlml.c:254,260 | ||
| 1999/0429 | i2c_wrbyte(uchar v) { | |
| 1999/0423 | int i, ack; | |
| 1999/0520 | for (i = 0; i < 8; i++) { | |
| 1999/0429 | i2c_wrbit(v & 0x80); | |
| 1999/0423 | v = v << 1; } | |
| 1999/0519/sys/src/9/pc/devlml.c:261,267 – 1999/0520/sys/src/9/pc/devlml.c:277,283 | ||
| 1999/0429 | ack = i2c_wrbyte(sub); | |
| 1999/0423 | if (ack == 1) error(Eio); | |
| 1999/0520 | for (i = 0; i < num; i++) { | |
| 1999/0429 | ack = i2c_wrbyte(bytes[i]); | |
| 1999/0423 | if (ack == 1) error(Eio); } | |
| 1999/0519/sys/src/9/pc/devlml.c:328,334 – 1999/0520/sys/src/9/pc/devlml.c:344,444 | ||
| 1999/0424 | return 1; } | |
| 1999/0520 | /* * The following mapping applies for the guests in the LML33 * * Guest Device * 0 zr36060 * uses subaddress GADR[0..1] * 1 zr36060 START# * 2 - * 3 zr36060 RESET# * 4 - * 5 - * 6 - * 7 - */ // post_idle waits for the guest bus to become free | |
| 1999/0423 | static int | |
| 1999/0520 | post_idle(void) { ulong a; int timeout; for (timeout = 0; timeout < GUEST_TIMEOUT; timeout++){ a = readl(pciBaseAddr + POST_OFFICE); if ((a & POST_PEND) == 0) return a; } pprint("post_idle timeout\n"); return -1; } // post_write writes a byte to a guest using postoffice mechanism int post_write(unsigned int guest, unsigned int reg, unsigned int v) { int w; // wait for postoffice not busy post_idle(); // Trim the values, just in case guest &= 0x07; reg &= 0x07; v &= 0xFF; // write postoffice operation w = POST_DIR | (guest<<20) | (reg<<16) | v; writel(w, pciBaseAddr + POST_OFFICE); // wait for postoffice not busy return post_idle() == -1; } // post_read reads a byte from a guest using postoffice mechanism int post_read(int guest, int reg) { int w; // wait for postoffice not busy post_idle(); // Trim the values, just in case guest &= 0x07; reg &= 0x07; // write postoffice operation w = (guest<<20) + (reg<<16); writel(w, pciBaseAddr + POST_OFFICE); // wait for postoffice not busy, get result w = post_idle(); // decide if read went ok if (w == -1) return -1; return w & 0xFF; } static int zr060_write(int reg, int v) { if (post_write(GID060, 1, (reg>>8) & 0x03) || post_write(GID060, 2, reg & 0xff) || post_write(GID060, 3, v)) return -1; } static int zr060_read(int reg) { if (post_write(GID060, 1, (reg>>8) & 0x03) || post_write(GID060, 2, reg & 0xff)) return -1; return post_read(GID060, 3); } static int | |
| 1999/0518 | prepareBuffer(int i) { if (i >= 0 && i < NBUF && (codeData->statCom[i] & STAT_BIT)) { codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); | |
| 1999/0519/sys/src/9/pc/devlml.c:353,362 – 1999/0520/sys/src/9/pc/devlml.c:463,471 | ||
| 1999/0423 | } | |
| 1999/0424 | static int | |
| 1999/0518 |
| |
| 1999/0520 | getBuffer(int i, int* frameNo) { | |
| 1999/0518 | if(codeData->statCom[i] & STAT_BIT) { | |
| 1999/0424 | } else | |
| 1999/0519/sys/src/9/pc/devlml.c:364,369 – 1999/0520/sys/src/9/pc/devlml.c:473,554 | ||
| 1999/0424 | } | |
| 1999/0423 | ||
| 1999/0424 | static long | |
| 1999/0520 | 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: while((curbuf = getProcessedBuffer()) == -1) sleep(&sleeper, return0, 0); fragsize = getBuffer(curbuf, &frameno); if (debug & DBGREAD) pprint("devlml: got read buf %d, fr %d, size %d\n", curbuf, frameNo, fragsize); if(frameno != (frameprev + 1) % 256) pprint("Frames out of sequence: %d %d\n", frameno, frameprev); frameprev = frameno; // Fill in APP marker fields here thetime = todget(); 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 = Body; 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; 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 prepareBuffer(curbuf); state = New; break; case Error: return 0; } } } /* static long | |
| 1999/0424 | vread(Chan *, void *va, long count, vlong pos) { int prevFrame; // how much bytes left to transfer for the header | |
| 1999/0519/sys/src/9/pc/devlml.c:404,417 – 1999/0520/sys/src/9/pc/devlml.c:589,602 | ||
| 1999/0424 | sleep(&sleeper, return0, 0); | |
| 1999/0515 | if(debug&DBGREAD) pprint("devlml::wokeup\n"); | |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0520 | currentBufferLength = getBuffer(currentBuffer, &frameNo); currentBufferPtr = (void*)(&codeData->frag[currentBuffer]); | |
| 1999/0424 | pos = 0; // ?????????????? | |
| 1999/0520 | // pprint("getBufffer %d -> %d 0x%x %d\n",currentBuffer, currentBufferLength, currentBufferPtr, frameNo); | |
| 1999/0424 | if(frameNo != (prevFrame + 1) % 256) | |
| 1999/0520 | pprint("Frames out of sequence: %d %d\n", prevFrame, frameNo); | |
| 1999/0424 | // Fill in APP marker fields here thetime = todget(); frameHeader.sec = (ulong)(thetime / 1000000000LL); | |
| 1999/0519/sys/src/9/pc/devlml.c:447,538 – 1999/0520/sys/src/9/pc/devlml.c:632,723 | ||
| 1999/0515 | //pr_debug&DBGREGS("return %d %d\n",cpcount,retcount); | |
| 1999/0424 | return retcount; | |
| 1999/0423 | } | |
| 1999/0520 | */ | |
| 1999/0423 | ||
| 1999/0424 | static long | |
| 1999/0520 | 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; | |
| 1999/0424 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0430 |
| |
| 1999/0424 |
| |
| 1999/0520 | p = (char *)va; while (count > 0) { switch (state) { case New: while((curbuf = getProcessedBuffer()) == -1) { if (debug&DBGWRIT) pprint("devlml::sleep\n"); sleep(&sleeper, return0, 0); | |
| 1999/0424 | } | |
| 1999/0520 | 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 p - (char *)va; } 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 p - (char *)va; } state = Body; // Fall through case Body: if (count < fragsize - bufpos) { memmove(bufptr, p, count); bufptr += count; bufpos += count; return nbytes; } i = fragsize - bufpos; memmove(bufptr, p, i); bufptr += i; bufpos += i; p += i; count -= i; // We have written the frame, time to display it i = prepareBuffer(curbuf); if (debug&DBGWRIT) pprint("Sending buffer %d: %d\n", curbuf, i); state = New; break; case Error: return 0; | |
| 1999/0424 | } | |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0423 | static void lmlintr(Ureg *, void *); | |
| 1999/0519/sys/src/9/pc/devlml.c:558,564 – 1999/0520/sys/src/9/pc/devlml.c:743,749 | ||
| 1999/0422 | // Get access to DMA memory buffer memset(codeData, 0xAA, sizeof(CodeData)); | |
| 1999/0520 | for (i = 0; i < NBUF; i++) { | |
| 1999/0517 | codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i])); | |
| 1999/0422 | // Length is in double words, in position 1..20 | |
| 1999/0519/sys/src/9/pc/devlml.c:619,624 – 1999/0520/sys/src/9/pc/devlml.c:804,810 | ||
| 1999/0517 | ||
| 1999/0422 | c->aux = 0; switch(c->qid.path){ | |
| 1999/0520 | case Q060: | |
| 1999/0422 | case Q819: case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0519/sys/src/9/pc/devlml.c:637,642 – 1999/0520/sys/src/9/pc/devlml.c:823,829 | ||
| 1999/0424 | frameNo = 0; bufferPrepared = 0; hdrPos = -1; | |
| 1999/0520 | state = New; | |
| 1999/0517 | ||
| 1999/0422 | // allow one open total for these two break; | |
| 1999/0519/sys/src/9/pc/devlml.c:648,653 – 1999/0520/sys/src/9/pc/devlml.c:835,841 | ||
| 1999/0518 | lmlclose(Chan *c) { | |
| 1999/0422 | switch(c->qid.path){ | |
| 1999/0520 | case Q060: | |
| 1999/0422 | case Q819: case Q856: | |
| 1999/0428 | case Qreg: | |
| 1999/0519/sys/src/9/pc/devlml.c:673,678 – 1999/0520/sys/src/9/pc/devlml.c:861,874 | ||
| 1999/0513 | case Qdir: return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen); | |
| 1999/0520 | case Q060: if (off < 0 || off + n > 0x400) return 0; for (i = 0; i < n; i++) { if ((d = zr060_read(off + i)) < 0) break; *buf++ = d; } return i; | |
| 1999/0422 | case Q819: | |
| 1999/0424 | if (off < 0 || off + n > 0x20) | |
| 1999/0423 | return 0; | |
| 1999/0519/sys/src/9/pc/devlml.c:767,777 – 1999/0520/sys/src/9/pc/devlml.c:963,980 | ||
| 1999/0513 | case Qdir: error(Eperm); | |
| 1999/0520 | case Q060: if (off < 0 || off + n > 0x400) return 0; for (i = 0; i < n; i++) { if (zr060_write(off + i, *buf++) < 0) break; } return i; | |
| 1999/0423 | case Q819: | |
| 1999/0517 | if (off < 0 || off + n >= 0x20) | |
| 1999/0423 | return 0; | |
| 1999/0424 |
| |
| 1999/0429 |
| |
| 1999/0520 | for (i = 0; i < n; i++) if (i2c_wr8(BT819Addr, off + i, *buf++) == 0) | |
| 1999/0424 | break; | |
| 1999/0515 | return i; | |
| 1999/0423 | case Q856: | |
| 1999/0519/sys/src/9/pc/devlml.c:862,877 – 1999/0520/sys/src/9/pc/devlml.c:1065,1081 | ||
| 1999/0422 | static void | |
| 1999/0424 | lmlintr(Ureg *, void *) { | |
| 1999/0520 | static count; ulong flags = readl(pciBaseAddr+INTR_STAT); | |
| 1999/0424 | ||
| 1999/0515 |
| |
| 1999/0520 | if(debug&(DBGINTR)) | |
| 1999/0515 | print("MjpgDrv_intrHandler stat=0x%.8lux\n", flags); | |
| 1999/0422 | ||
| 1999/0424 | // Reset all interrupts from 067 | |
| 1999/0520 | writel(0xff000000, pciBaseAddr + INTR_STAT); | |
| 1999/0423 | ||
| 1999/0515 |
| |
| 1999/0520 | if(flags & INTR_JPEGREP) { if ((debug&DBGINTR) || ((debug&DBGINTS) && (count++ % 128) == 0)) | |
| 1999/0515 | print("MjpgDrv_intrHandler wakeup\n"); wakeup(&sleeper); } | |
| 1999/0520/sys/src/9/pc/devlml.c:19,25 – 1999/0521/sys/src/9/pc/devlml.c:19,25 (short | long) | ||
| 1999/0520 | #define DBGINTR 0x10 #define DBGINTS 0x20 | |
| 1999/0521 | int debug = 0; | |
| 1999/0520 | ||
| 1999/0422 | // Lml 22 driver | |
| 1999/0520/sys/src/9/pc/devlml.c:62,75 – 1999/0521/sys/src/9/pc/devlml.c:62,70 | ||
| 1999/0520 | Error, } State; | |
| 1999/0513 |
| |
| 1999/0424 |
| |
| 1999/0513 | int frameNo; | |
| 1999/0424 | Rendez sleeper; | |
| 1999/0513 | int singleFrame; | |
| 1999/0429 | uchar q856[3]; | |
| 1999/0520 | State state = New; | |
| 1999/0520/sys/src/9/pc/devlml.c:489,504 – 1999/0521/sys/src/9/pc/devlml.c:484,505 | ||
| 1999/0520 | while (count > 0) { switch (state) { case New: | |
| 1999/0521 | while ((curbuf = getProcessedBuffer()) == -1) | |
| 1999/0520 | sleep(&sleeper, return0, 0); fragsize = getBuffer(curbuf, &frameno); if (debug & DBGREAD) pprint("devlml: got read buf %d, fr %d, size %d\n", curbuf, frameNo, fragsize); | |
| 1999/0521 | if (frameno != (frameprev + 1) % 256) pprint("Frame out of sequence: %d %d\n", frameprev, frameno); | |
| 1999/0520 | frameprev = frameno; | |
| 1999/0521 | if (fragsize <= 0 || fragsize > sizeof(Fragment)) { pprint("Wrong sized fragment, %d (ignored)\n", fragsize); prepareBuffer(curbuf); break; } | |
| 1999/0520 | // Fill in APP marker fields here thetime = todget(); frameHeader.sec = (ulong)(thetime / 1000000000LL); | |
| 1999/0520/sys/src/9/pc/devlml.c:507,513 – 1999/0521/sys/src/9/pc/devlml.c:508,514 | ||
| 1999/0520 | frameHeader.frameSeqNo++; frameHeader.frameNo = frameno; bufpos = 0; | |
| 1999/0521 | state = Header; | |
| 1999/0520 | bufptr = (char *)(&frameHeader); // Fall through case Header: | |
| 1999/0520/sys/src/9/pc/devlml.c:522,533 – 1999/0521/sys/src/9/pc/devlml.c:523,534 | ||
| 1999/0520 | count -= i; p += i; bufpos = 2; | |
| 1999/0521 | bufptr = codeData->frag[curbuf].fb + 2; | |
| 1999/0520 | state = Body; // Fall through case Body: i = fragsize - bufpos; | |
| 1999/0521 | if (count < i) { | |
| 1999/0520 | memmove(p, bufptr, count); bufptr += count; bufpos += count; | |
| 1999/0520/sys/src/9/pc/devlml.c:540,545 – 1999/0521/sys/src/9/pc/devlml.c:541,550 | ||
| 1999/0520 | // Allow reuse of current buffer prepareBuffer(curbuf); state = New; | |
| 1999/0521 | if (singleFrame) { state = Error; return nbytes - count; } | |
| 1999/0520 | break; case Error: return 0; | |
| 1999/0520/sys/src/9/pc/devlml.c:547,640 – 1999/0521/sys/src/9/pc/devlml.c:552,558 | ||
| 1999/0520 | } } | |
| 1999/0424 |
| |
| 1999/0515 |
| |
| 1999/0424 |
| |
| 1999/0515 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0515 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0515 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0515 |
| |
| 1999/0520 |
| |
| 1999/0424 |
| |
| 1999/0520 |
| |
| 1999/0424 |
| |
| 1999/0520 |
| |
| 1999/0424 |
| |
| 1999/0515 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0423 | ||
| 1999/0424 |
| |
| 1999/0520 | vwrite(Chan *, void *va, long nbytes, vlong) { static int bufpos; static char *bufptr; | |
| 1999/0520/sys/src/9/pc/devlml.c:683,689 – 1999/0521/sys/src/9/pc/devlml.c:601,607 | ||
| 1999/0520 | codeData->frag[curbuf].fh.mrkAPP3, codeData->frag[curbuf].fh.nm); state = Error; | |
| 1999/0521 | return nbytes - count; | |
| 1999/0520 | } fragsize = codeData->frag[curbuf].fh.frameSize; if (fragsize <= sizeof(FrameHeader) | |
| 1999/0520/sys/src/9/pc/devlml.c:691,708 – 1999/0521/sys/src/9/pc/devlml.c:609,626 | ||
| 1999/0520 | pprint("devlml: frame size error: 0x%.8ux\n", fragsize); state = Error; | |
| 1999/0521 | return nbytes - count; | |
| 1999/0520 | } state = Body; // Fall through case Body: | |
| 1999/0521 | i = fragsize - bufpos; if (count < i) { | |
| 1999/0520 | memmove(bufptr, p, count); bufptr += count; bufpos += count; return nbytes; } | |
| 1999/0520/sys/src/9/pc/devlml.c:712,717 – 1999/0521/sys/src/9/pc/devlml.c:630,639 | ||
| 1999/0520 | i = prepareBuffer(curbuf); if (debug&DBGWRIT) pprint("Sending buffer %d: %d\n", curbuf, i); | |
| 1999/0521 | if (singleFrame) { state = Error; return nbytes - count; } | |
| 1999/0520 | state = New; break; case Error: | |
| 1999/0520/sys/src/9/pc/devlml.c:801,806 – 1999/0521/sys/src/9/pc/devlml.c:723,729 | ||
| 1999/0422 | static Chan* | |
| 1999/0518 | lmlopen(Chan *c, int omode) { | |
| 1999/0521 | int i; | |
| 1999/0517 | ||
| 1999/0422 | c->aux = 0; switch(c->qid.path){ | |
| 1999/0520/sys/src/9/pc/devlml.c:811,829 – 1999/0521/sys/src/9/pc/devlml.c:734,748 | ||
| 1999/0515 | case Qmap: | |
| 1999/0518 | case Qbuf: | |
| 1999/0422 | break; | |
| 1999/0513 |
| |
| 1999/0422 | case Qjframe: | |
| 1999/0521 | case Qjvideo: | |
| 1999/0424 | if (nopens) error(Einuse); nopens = 1; singleFrame = (c->qid.path == Qjframe) ? 1 : 0;; | |
| 1999/0520 | state = New; | |
| 1999/0521 | for (i = 0; i < NBUF; i++) codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); | |
| 1999/0517 | ||
| 1999/0422 | // allow one open total for these two break; | |
| 1999/0521/sys/src/9/pc/devlml.c:647,652 – 1999/0522/sys/src/9/pc/devlml.c:647,656 (short | long) | ||
| 1999/0423 | static void | |
| 1999/0513 | lmlreset(void) | |
| 1999/0422 | { | |
| 1999/0522 | // LMLSEG Physseg segbuf; Physseg segreg; // | |
| 1999/0422 | ulong regpa; int i; | |
| 1999/0521/sys/src/9/pc/devlml.c:699,704 – 1999/0522/sys/src/9/pc/devlml.c:703,726 | ||
| 1999/0515 | lmlmap.pci = pciBaseAddr; | |
| 1999/0518 | lmlmap.statcom = PADDR(codeData->statCom); | |
| 1999/0515 | lmlmap.codedata = (ulong)codeData; | |
| 1999/0522 | // LMLSEG memset(&segbuf, 0, sizeof(segbuf)); segbuf.attr = SG_PHYSICAL; segbuf.name = smalloc(NAMELEN); snprint(segbuf.name, NAMELEN, "lmlmjpg"); segbuf.pa = PADDR(codeData); segbuf.size = sizeof(CodeData); addphysseg(&segbuf); memset(&segreg, 0, sizeof(segreg)); segreg.attr = SG_PHYSICAL; segreg.name = smalloc(NAMELEN); snprint(segreg.name, NAMELEN, "lmlregs"); segreg.pa = (ulong)regpa; segreg.size = pcidev->mem[0].size; addphysseg(&segreg); // | |
| 1999/0515 | ||
| 1999/0422 | return; } | |
| 1999/0522/sys/src/9/pc/devlml.c:23,36 – 1999/0525/sys/src/9/pc/devlml.c:23,39 (short | long) | ||
| 1999/0520 | ||
| 1999/0422 | // Lml 22 driver | |
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0517 | struct { ulong pci; | |
| 1999/0518 | ulong statcom; | |
| 1999/0517 | ulong codedata; } lmlmap; | |
| 1999/0525 | #endif | |
| 1999/0517 | ||
| 1999/0422 | enum{ | |
| 1999/0513 | Qdir, | |
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0520 | Q060, | |
| 1999/0422 | Q819, Q856, | |
| 1999/0522/sys/src/9/pc/devlml.c:37,42 – 1999/0525/sys/src/9/pc/devlml.c:40,46 | ||
| 1999/0428 | Qreg, | |
| 1999/0515 | Qmap, | |
| 1999/0518 | Qbuf, | |
| 1999/0525 | #endif | |
| 1999/0513 | Qjvideo, | |
| 1999/0422 | Qjframe, }; | |
| 1999/0522/sys/src/9/pc/devlml.c:43,48 – 1999/0525/sys/src/9/pc/devlml.c:47,53 | ||
| 1999/0422 | ||
| 1999/0513 | static Dirtab lmldir[]={ // name, qid, size, mode | |
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0520 | "lml060", {Q060}, 0x400, 0644, | |
| 1999/0513 | "lml819", {Q819}, 0, 0644, "lml856", {Q856}, 0, 0644, | |
| 1999/0522/sys/src/9/pc/devlml.c:49,54 – 1999/0525/sys/src/9/pc/devlml.c:54,60 | ||
| 1999/0517 | "lmlreg", {Qreg}, 0x400, 0644, "lmlmap", {Qmap}, sizeof lmlmap, 0444, | |
| 1999/0518 | "lmlbuf", {Qbuf}, 0, 0644, | |
| 1999/0525 | #endif | |
| 1999/0513 | "jvideo", {Qjvideo}, 0, 0666, | |
| 1999/0422 | "jframe", {Qjframe}, 0, 0666, }; | |
| 1999/0522/sys/src/9/pc/devlml.c:75,80 – 1999/0525/sys/src/9/pc/devlml.c:81,91 | ||
| 1999/0424 | -1, 0, 0, 0, 0 }; | |
| 1999/0525 | #ifndef MEMMAP #define writel(v, a) *(ulong *)(a) = (v) #define readl(a) *(ulong*)(a) #else | |
| 1999/0515 | ulong writel(ulong v, ulong a) { if (debug&DBGREGS) | |
| 1999/0522/sys/src/9/pc/devlml.c:83,88 – 1999/0525/sys/src/9/pc/devlml.c:94,109 | ||
| 1999/0515 | return *(ulong *)a = v; } | |
| 1999/0525 | ulong readl(ulong a) { ulong v; v = *(ulong*)a; if (debug&DBGREGS) pprint("%.8lux (%.8lux) --> %.8lux\n", a, (ulong)a-pciBaseAddr, v); return v; } | |
| 1999/0515 | ushort writew(ushort v, ulong a) { if (debug&DBGREGS) | |
| 1999/0522/sys/src/9/pc/devlml.c:99,115 – 1999/0525/sys/src/9/pc/devlml.c:120,125 | ||
| 1999/0515 | return *(uchar *)a = v; } | |
| 1999/0517 |
| |
| 1999/0515 |
| |
| 1999/0522/sys/src/9/pc/devlml.c:432,437 – 1999/0525/sys/src/9/pc/devlml.c:442,448 | ||
| 1999/0520 | return -1; return post_read(GID060, 3); } | |
| 1999/0525 | #endif | |
| 1999/0520 | static int | |
| 1999/0518 | prepareBuffer(int i) { | |
| 1999/0522/sys/src/9/pc/devlml.c:652,657 – 1999/0525/sys/src/9/pc/devlml.c:663,669 | ||
| 1999/0522 | Physseg segreg; // | |
| 1999/0422 | ulong regpa; | |
| 1999/0525 | ulong cdsize; | |
| 1999/0422 | int i; | |
| 1999/0423 | pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067); | |
| 1999/0522/sys/src/9/pc/devlml.c:658,674 – 1999/0525/sys/src/9/pc/devlml.c:670,688 | ||
| 1999/0423 | if (pcidev == nil) { return; } | |
| 1999/0422 |
| |
| 1999/0525 | cdsize = (sizeof(CodeData) + BY2PG - 1) & ~(BY2PG - 1); codeData = (CodeData*)xspanalloc(cdsize, BY2PG, 0); | |
| 1999/0422 | if (codeData == nil) { | |
| 1999/0525 | print("devlml: xspanalloc(%lux, %ux, 0)\n", cdsize, BY2PG); | |
| 1999/0422 | return; } print("Installing Motion JPEG driver %s\n", MJPG_VERSION); | |
| 1999/0513 |
| |
| 1999/0525 | print("Buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize); | |
| 1999/0422 | // Get access to DMA memory buffer memset(codeData, 0xAA, sizeof(CodeData)); | |
| 1999/0525 | codeData->physaddr = PADDR(&(codeData->statCom[0])); | |
| 1999/0520 | for (i = 0; i < NBUF; i++) { | |
| 1999/0517 | codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i])); | |
| 1999/0522/sys/src/9/pc/devlml.c:700,708 – 1999/0525/sys/src/9/pc/devlml.c:714,724 | ||
| 1999/0422 | // Interrupt handler | |
| 1999/0423 | intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); | |
| 1999/0422 | ||
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0515 | lmlmap.pci = pciBaseAddr; | |
| 1999/0518 | lmlmap.statcom = PADDR(codeData->statCom); | |
| 1999/0515 | lmlmap.codedata = (ulong)codeData; | |
| 1999/0525 | #endif | |
| 1999/0522 | // LMLSEG memset(&segbuf, 0, sizeof(segbuf)); | |
| 1999/0522/sys/src/9/pc/devlml.c:710,717 – 1999/0525/sys/src/9/pc/devlml.c:726,736 | ||
| 1999/0522 | segbuf.name = smalloc(NAMELEN); snprint(segbuf.name, NAMELEN, "lmlmjpg"); segbuf.pa = PADDR(codeData); | |
| 1999/0525 | segbuf.size = cdsize; if (addphysseg(&segbuf) == -1) { print("lml: physsegment: lmlmjpg\n"); return; } | |
| 1999/0522 | memset(&segreg, 0, sizeof(segreg)); segreg.attr = SG_PHYSICAL; | |
| 1999/0522/sys/src/9/pc/devlml.c:719,725 – 1999/0525/sys/src/9/pc/devlml.c:738,747 | ||
| 1999/0522 | snprint(segreg.name, NAMELEN, "lmlregs"); segreg.pa = (ulong)regpa; segreg.size = pcidev->mem[0].size; | |
| 1999/0525 | if (addphysseg(&segreg) == -1) { print("lml: physsegment: lmlmjpg\n"); return; } | |
| 1999/0522 | // | |
| 1999/0515 | ||
| 1999/0422 | return; | |
| 1999/0522/sys/src/9/pc/devlml.c:749,754 – 1999/0525/sys/src/9/pc/devlml.c:771,777 | ||
| 1999/0517 | ||
| 1999/0422 | c->aux = 0; switch(c->qid.path){ | |
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0520 | case Q060: | |
| 1999/0422 | case Q819: case Q856: | |
| 1999/0522/sys/src/9/pc/devlml.c:756,761 – 1999/0525/sys/src/9/pc/devlml.c:779,785 | ||
| 1999/0515 | case Qmap: | |
| 1999/0518 | case Qbuf: | |
| 1999/0422 | break; | |
| 1999/0525 | #endif | |
| 1999/0422 | case Qjframe: | |
| 1999/0521 | case Qjvideo: | |
| 1999/0424 | if (nopens) | |
| 1999/0522/sys/src/9/pc/devlml.c:776,781 – 1999/0525/sys/src/9/pc/devlml.c:800,806 | ||
| 1999/0518 | lmlclose(Chan *c) { | |
| 1999/0422 | switch(c->qid.path){ | |
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0520 | case Q060: | |
| 1999/0422 | case Q819: case Q856: | |
| 1999/0522/sys/src/9/pc/devlml.c:784,789 – 1999/0525/sys/src/9/pc/devlml.c:809,815 | ||
| 1999/0518 | case Qbuf: | |
| 1999/0515 | authclose(c); break; | |
| 1999/0525 | #endif | |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0515 | nopens = 0; | |
| 1999/0522/sys/src/9/pc/devlml.c:793,799 – 1999/0525/sys/src/9/pc/devlml.c:819,827 | ||
| 1999/0422 | static long | |
| 1999/0513 | lmlread(Chan *c, void *va, long n, vlong voff) { | |
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0424 | int i, d; | |
| 1999/0525 | #endif | |
| 1999/0424 | uchar *buf = va; | |
| 1999/0513 | long off = voff; | |
| 1999/0423 | ||
| 1999/0522/sys/src/9/pc/devlml.c:802,807 – 1999/0525/sys/src/9/pc/devlml.c:830,836 | ||
| 1999/0513 | case Qdir: return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen); | |
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0520 | case Q060: if (off < 0 || off + n > 0x400) return 0; | |
| 1999/0522/sys/src/9/pc/devlml.c:887,892 – 1999/0525/sys/src/9/pc/devlml.c:916,922 | ||
| 1999/0518 | return 0; } return n; | |
| 1999/0525 | #endif | |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0424 | return vread(c, buf, n, off); | |
| 1999/0522/sys/src/9/pc/devlml.c:895,901 – 1999/0525/sys/src/9/pc/devlml.c:925,933 | ||
| 1999/0422 | static long | |
| 1999/0514 | lmlwrite(Chan *c, void *va, long n, vlong voff) { | |
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0424 | int i; | |
| 1999/0525 | #endif | |
| 1999/0424 | uchar *buf = va; | |
| 1999/0514 | long off = voff; | |
| 1999/0423 | ||
| 1999/0522/sys/src/9/pc/devlml.c:904,909 – 1999/0525/sys/src/9/pc/devlml.c:936,942 | ||
| 1999/0513 | case Qdir: error(Eperm); | |
| 1999/0525 | #ifdef MEMMAP | |
| 1999/0520 | case Q060: if (off < 0 || off + n > 0x400) return 0; | |
| 1999/0522/sys/src/9/pc/devlml.c:977,982 – 1999/0525/sys/src/9/pc/devlml.c:1010,1016 | ||
| 1999/0428 | return 0; | |
| 1999/0424 | } | |
| 1999/0428 | return n; | |
| 1999/0525 | #endif | |
| 1999/0513 | case Qjvideo: | |
| 1999/0423 | case Qjframe: | |
| 1999/0424 | return vwrite(c, buf, n, off); | |
| 1999/0525/sys/src/9/pc/devlml.c:12,62 – 1999/0526/sys/src/9/pc/devlml.c:12,38 (short | long) | ||
| 1999/0520 | static ulong pciBaseAddr; static Pcidev * pcidev; | |
| 1999/0515 | ||
| 1999/0520 |
| |
| 1999/0526 | #define DBGREAD 0x01 #define DBGWRIT 0x02 #define DBGINTR 0x04 #define DBGINTS 0x08 | |
| 1999/0520 | ||
| 1999/0521 | int debug = 0; | |
| 1999/0520 | ||
| 1999/0422 | // Lml 22 driver | |
| 1999/0525 |
| |
| 1999/0517 |
| |
| 1999/0518 |
| |
| 1999/0517 |
| |
| 1999/0525 |
| |
| 1999/0517 | ||
| 1999/0422 | enum{ | |
| 1999/0513 | Qdir, | |
| 1999/0525 |
| |
| 1999/0520 |
| |
| 1999/0422 |
| |
| 1999/0428 |
| |
| 1999/0515 |
| |
| 1999/0518 |
| |
| 1999/0525 |
| |
| 1999/0513 | Qjvideo, | |
| 1999/0422 | Qjframe, | |
| 1999/0526 | Qjcount, | |
| 1999/0422 | }; | |
| 1999/0513 | static Dirtab lmldir[]={ // name, qid, size, mode | |
| 1999/0525 |
| |
| 1999/0520 |
| |
| 1999/0513 |
| |
| 1999/0517 |
| |
| 1999/0518 |
| |
| 1999/0525 |
| |
| 1999/0513 | "jvideo", {Qjvideo}, 0, 0666, | |
| 1999/0422 | "jframe", {Qjframe}, 0, 0666, | |
| 1999/0526 | "jcount", {Qjcount}, 0, 0444, | |
| 1999/0422 | }; CodeData * codeData; | |
| 1999/0525/sys/src/9/pc/devlml.c:82,483 – 1999/0526/sys/src/9/pc/devlml.c:58,91 | ||
| 1999/0424 | }; | |
| 1999/0525 |
| |
| 1999/0515 |
| |
| 1999/0517 |
| |
| 1999/0515 |
| |
| 1999/0525 |
| |
| 1999/0515 |
| |
| 1999/0517 |
| |
| 1999/0515 |
| |
| 1999/0517 |
| |
| 1999/0515 |
| |
| 1999/0517 |
| |
| 1999/0515 |
| |
| 1999/0517 |
| |
| 1999/0515 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0422 | ||
| 1999/0423 |
| |
| 1999/0422 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 | ||
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 | ||
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 | ||
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0526 | getbuffer(void){ static last = NBUF-1; int l = last; | |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0423 |
| |
| 1999/0526 | for (;;) { last = (last+1) % NBUF; if (codeData->statCom[last] & STAT_BIT) return last; if (last == l) sleep(&sleeper, return0, 0); | |
| 1999/0423 | } | |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0526 | return 0; | |
| 1999/0423 | } | |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0526 | static long vcount(Chan *, void *va, long nbytes, vlong) { char *p = (char *)va; | |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 | ||
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 | ||
| 1999/0429 |
| |
| 1999/0515 |
| |
| 1999/0429 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 | ||
| 1999/0429 |
| |
| 1999/0515 |
| |
| 1999/0429 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0429 |
| |
| 1999/0424 | ||
| 1999/0429 |
| |
| 1999/0424 | ||
| 1999/0429 |
| |
| 1999/0424 |
| |
| 1999/0429 |
| |
| 1999/0424 | ||
| 1999/0526 | // reads always return one byte: the next available buffer number if (nbytes <= 0) return 0; *p = getbuffer(); | |
| 1999/0424 | return 1; } | |
| 1999/0520 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0525 |
| |
| 1999/0520 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0423 | ||
| 1999/0424 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0520 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0423 | ||
| 1999/0424 | static long | |
| 1999/0520 | vread(Chan *, void *va, long nbytes, vlong) { static int bufpos; | |
| 1999/0525/sys/src/9/pc/devlml.c:495,507 – 1999/0526/sys/src/9/pc/devlml.c:103,115 | ||
| 1999/0520 | while (count > 0) { switch (state) { case New: | |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0526 | curbuf = getbuffer(); frameNo = codeData->statCom[curbuf] >> 24; fragsize = (codeData->statCom[curbuf] & 0x00ffffff)>>1; | |
| 1999/0520 | if (debug & DBGREAD) pprint("devlml: got read buf %d, fr %d, size %d\n", curbuf, frameNo, fragsize); | |
| 1999/0521 |
| |
| 1999/0526 | if (!singleFrame && frameno != (frameprev + 1) % 256) | |
| 1999/0521 | pprint("Frame out of sequence: %d %d\n", frameprev, frameno); | |
| 1999/0520 | frameprev = frameno; | |
| 1999/0525/sys/src/9/pc/devlml.c:508,514 – 1999/0526/sys/src/9/pc/devlml.c:116,122 | ||
| 1999/0521 | if (fragsize <= 0 || fragsize > sizeof(Fragment)) { pprint("Wrong sized fragment, %d (ignored)\n", fragsize); | |
| 1999/0526 | codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf])); | |
| 1999/0521 | break; } | |
| 1999/0520 | // Fill in APP marker fields here | |
| 1999/0525/sys/src/9/pc/devlml.c:550,556 – 1999/0526/sys/src/9/pc/devlml.c:158,164 | ||
| 1999/0520 | p += i; // Allow reuse of current buffer | |
| 1999/0526 | codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf])); | |
| 1999/0520 | state = New; | |
| 1999/0521 | if (singleFrame) { state = Error; | |
| 1999/0525/sys/src/9/pc/devlml.c:577,587 – 1999/0526/sys/src/9/pc/devlml.c:185,191 | ||
| 1999/0520 | while (count > 0) { switch (state) { case New: | |
| 1999/0424 |
| |
| 1999/0526 | curbuf = getbuffer(); | |
| 1999/0520 | if (debug&DBGWRIT) pprint("current buffer %d\n", curbuf); bufptr = codeData->frag[curbuf].fb; | |
| 1999/0525/sys/src/9/pc/devlml.c:638,646 – 1999/0526/sys/src/9/pc/devlml.c:242,250 | ||
| 1999/0520 | p += i; count -= i; // We have written the frame, time to display it | |
| 1999/0526 | codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf])); | |
| 1999/0520 | if (debug&DBGWRIT) | |
| 1999/0526 | pprint("Sending buffer %d\n", curbuf); | |
| 1999/0521 | if (singleFrame) { state = Error; return nbytes - count; | |
| 1999/0525/sys/src/9/pc/devlml.c:658,667 – 1999/0526/sys/src/9/pc/devlml.c:262,269 | ||
| 1999/0423 | static void | |
| 1999/0513 | lmlreset(void) | |
| 1999/0422 | { | |
| 1999/0522 |
| |
| 1999/0422 | ulong regpa; | |
| 1999/0525 | ulong cdsize; | |
| 1999/0422 | int i; | |
| 1999/0525/sys/src/9/pc/devlml.c:682,688 – 1999/0526/sys/src/9/pc/devlml.c:284,290 | ||
| 1999/0422 | // Get access to DMA memory buffer memset(codeData, 0xAA, sizeof(CodeData)); | |
| 1999/0525 |
| |
| 1999/0526 | codeData->physaddr = PADDR(codeData->statCom); | |
| 1999/0520 | for (i = 0; i < NBUF; i++) { | |
| 1999/0517 | codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i])); | |
| 1999/0525/sys/src/9/pc/devlml.c:704,726 – 1999/0526/sys/src/9/pc/devlml.c:306,314 | ||
| 1999/0423 | pciBaseAddr = (ulong)KADDR(regpa); | |
| 1999/0513 | print(", mapped at 0x%.8lux\n", pciBaseAddr); | |
| 1999/0422 |
| |
| 1999/0423 |
| |
| 1999/0422 |
| |
| 1999/0423 |
| |
| 1999/0422 |
| |
| 1999/0423 | intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); | |
| 1999/0422 | ||
| 1999/0525 |
| |
| 1999/0515 |
| |
| 1999/0518 |
| |
| 1999/0515 |
| |
| 1999/0525 |
| |
| 1999/0522 |
| |
| 1999/0525/sys/src/9/pc/devlml.c:742,749 – 1999/0526/sys/src/9/pc/devlml.c:330,335 | ||
| 1999/0525 | print("lml: physsegment: lmlmjpg\n"); return; } | |
| 1999/0522 |
| |
| 1999/0515 | ||
| 1999/0422 | return; } | |
| 1999/0525/sys/src/9/pc/devlml.c:771,787 – 1999/0526/sys/src/9/pc/devlml.c:357,365 | ||
| 1999/0517 | ||
| 1999/0422 | c->aux = 0; switch(c->qid.path){ | |
| 1999/0525 |
| |
| 1999/0520 |
| |
| 1999/0422 |
| |
| 1999/0428 |
| |
| 1999/0515 |
| |
| 1999/0518 |
| |
| 1999/0422 |
| |
| 1999/0525 |
| |
| 1999/0422 | case Qjframe: | |
| 1999/0521 | case Qjvideo: | |
| 1999/0526 | case Qjcount: | |
| 1999/0424 | if (nopens) error(Einuse); nopens = 1; | |
| 1999/0525/sys/src/9/pc/devlml.c:800,817 – 1999/0526/sys/src/9/pc/devlml.c:378,386 | ||
| 1999/0518 | lmlclose(Chan *c) { | |
| 1999/0422 | switch(c->qid.path){ | |
| 1999/0525 |
| |
| 1999/0520 |
| |
| 1999/0422 |
| |
| 1999/0428 |
| |
| 1999/0515 |
| |
| 1999/0518 |
| |
| 1999/0515 |
| |
| 1999/0525 |
| |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0526 | case Qjcount: | |
| 1999/0515 | nopens = 0; | |
| 1999/0422 | authclose(c); } | |
| 1999/0525/sys/src/9/pc/devlml.c:819,827 – 1999/0526/sys/src/9/pc/devlml.c:388,393 | ||
| 1999/0422 | static long | |
| 1999/0513 | lmlread(Chan *c, void *va, long n, vlong voff) { | |
| 1999/0525 |
| |
| 1999/0424 |
| |
| 1999/0525 |
| |
| 1999/0424 | uchar *buf = va; | |
| 1999/0513 | long off = voff; | |
| 1999/0423 | ||
| 1999/0525/sys/src/9/pc/devlml.c:829,1016 – 1999/0526/sys/src/9/pc/devlml.c:395,417 | ||
| 1999/0513 | case Qdir: return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen); | |
| 1999/0525 |
| |
| 1999/0520 |
| |
| 1999/0422 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0429 |
| |
| 1999/0424 |
| |
| 1999/0515 |
| |
| 1999/0422 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0424 |
| |
| 1999/0429 |
| |
| 1999/0515 |
| |
| 1999/0517 |
| |
| 1999/0515 |
| |
| 1999/0428 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0428 |
| |
| 1999/0430 |
| |
| 1999/0428 |
| |
| 1999/0430 |
| |
| 1999/0515 |
| |
| 1999/0428 |
| |
| 1999/0424 |
| |
| 1999/0428 |
| |
| 1999/0518 |
| |
| 1999/0525 |
| |
| 1999/0513 | case Qjvideo: | |
| 1999/0422 | case Qjframe: | |
| 1999/0424 | return vread(c, buf, n, off); | |
| 1999/0526 | case Qjcount: return vcount(c, buf, n, off); | |
| 1999/0422 | } } static long | |
| 1999/0514 | lmlwrite(Chan *c, void *va, long n, vlong voff) { | |
| 1999/0525 |
| |
| 1999/0424 |
| |
| 1999/0525 |
| |
| 1999/0424 | uchar *buf = va; | |
| 1999/0514 | long off = voff; | |
| 1999/0423 | ||
| 1999/0513 | switch(c->qid.path & ~CHDIR){ | |
| 1999/0526 | case Qjcount: | |
| 1999/0513 | error(Eperm); | |
| 1999/0525 |
| |
| 1999/0520 |
| |
| 1999/0423 |
| |
| 1999/0517 |
| |
| 1999/0423 |
| |
| 1999/0520 |
| |
| 1999/0424 |
| |
| 1999/0515 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0423 |
| |
| 1999/0429 |
| |
| 1999/0428 |
| |
| 1999/0518 |
| |
| 1999/0424 |
| |
| 1999/0428 |
| |
| 1999/0515 |
| |
| 1999/0428 |
| |
| 1999/0515 |
| |
| 1999/0424 |
| |
| 1999/0518 |
| |
| 1999/0428 |
| |
| 1999/0424 |
| |
| 1999/0428 |
| |
| 1999/0525 |
| |
| 1999/0513 | case Qjvideo: | |
| 1999/0423 | case Qjframe: | |
| 1999/0424 | return vwrite(c, buf, n, off); | |
| 1999/0526/sys/src/9/pc/devlml.c:264,271 – 1999/0527/sys/src/9/pc/devlml.c:264,274 (short | long) | ||
| 1999/0422 | { | |
| 1999/0522 | Physseg segbuf; Physseg segreg; | |
| 1999/0527 | Physseg seggrab; | |
| 1999/0422 | ulong regpa; | |
| 1999/0525 | ulong cdsize; | |
| 1999/0527 | ulong *grabpa; ulong grablen; | |
| 1999/0422 | int i; | |
| 1999/0423 | pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067); | |
| 1999/0526/sys/src/9/pc/devlml.c:279,286 – 1999/0527/sys/src/9/pc/devlml.c:282,298 | ||
| 1999/0422 | return; } | |
| 1999/0527 | grablen = (720 * 480 * 2 * 2 + BY2PG - 1) & ~(BY2PG - 1); grabpa = (ulong *)xspanalloc(grablen, BY2PG, 0); if (grabpa == nil) { print("devlml: xspanalloc(%lux, %ux, 0)\n", grablen, BY2PG); return; } *grabpa = PADDR(grabpa); | |
| 1999/0422 | print("Installing Motion JPEG driver %s\n", MJPG_VERSION); | |
| 1999/0525 |
| |
| 1999/0527 | print("MJPG buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize); print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabpa, grablen); | |
| 1999/0422 | // Get access to DMA memory buffer memset(codeData, 0xAA, sizeof(CodeData)); | |
| 1999/0526/sys/src/9/pc/devlml.c:327,333 – 1999/0527/sys/src/9/pc/devlml.c:339,356 | ||
| 1999/0522 | segreg.pa = (ulong)regpa; segreg.size = pcidev->mem[0].size; | |
| 1999/0525 | if (addphysseg(&segreg) == -1) { | |
| 1999/0527 | print("lml: physsegment: lmlregs\n"); return; } memset(&seggrab, 0, sizeof(seggrab)); seggrab.attr = SG_PHYSICAL; seggrab.name = smalloc(NAMELEN); snprint(seggrab.name, NAMELEN, "lmlgrab"); seggrab.pa = (ulong)PADDR(grabpa); seggrab.size = grablen; if (addphysseg(&seggrab) == -1) { print("lml: physsegment: lmlgrab\n"); | |
| 1999/0525 | return; } | |
| 1999/0422 | return; | |
| 1999/0527/sys/src/9/pc/devlml.c:267,273 – 1999/0529/sys/src/9/pc/devlml.c:267,273 (short | long) | ||
| 1999/0527 | Physseg seggrab; | |
| 1999/0422 | ulong regpa; | |
| 1999/0525 | ulong cdsize; | |
| 1999/0527 |
| |
| 1999/0529 | void *grabbuf; | |
| 1999/0527 | ulong grablen; | |
| 1999/0422 | int i; | |
| 1999/0527/sys/src/9/pc/devlml.c:275,281 – 1999/0529/sys/src/9/pc/devlml.c:275,281 | ||
| 1999/0423 | if (pcidev == nil) { return; } | |
| 1999/0525 |
| |
| 1999/0529 | cdsize = CODEDATASIZE; | |
| 1999/0525 | codeData = (CodeData*)xspanalloc(cdsize, BY2PG, 0); | |
| 1999/0422 | if (codeData == nil) { | |
| 1999/0525 | print("devlml: xspanalloc(%lux, %ux, 0)\n", cdsize, BY2PG); | |
| 1999/0527/sys/src/9/pc/devlml.c:282,302 – 1999/0529/sys/src/9/pc/devlml.c:282,304 | ||
| 1999/0422 | return; } | |
| 1999/0527 |
| |
| 1999/0529 | grablen = GRABDATASIZE; grabbuf = xspanalloc(grablen, BY2PG, 0); if (grabbuf == nil) { | |
| 1999/0527 | print("devlml: xspanalloc(%lux, %ux, 0)\n", grablen, BY2PG); return; } | |
| 1999/0529 | memset(grabbuf, 0x33, grablen); | |
| 1999/0422 | print("Installing Motion JPEG driver %s\n", MJPG_VERSION); | |
| 1999/0527 | print("MJPG buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize); | |
| 1999/0529 | print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabbuf, grablen); | |
| 1999/0422 | // Get access to DMA memory buffer memset(codeData, 0xAA, sizeof(CodeData)); | |
| 1999/0526 |
| |
| 1999/0529 | codeData->pamjpg = PADDR(codeData->statCom); codeData->pagrab = PADDR(grabbuf); | |
| 1999/0520 | for (i = 0; i < NBUF; i++) { | |
| 1999/0517 | codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i])); | |
| 1999/0527/sys/src/9/pc/devlml.c:347,359 – 1999/0529/sys/src/9/pc/devlml.c:349,361 | ||
| 1999/0527 | seggrab.attr = SG_PHYSICAL; seggrab.name = smalloc(NAMELEN); snprint(seggrab.name, NAMELEN, "lmlgrab"); | |
| 1999/0529 | seggrab.pa = PADDR(grabbuf); | |
| 1999/0527 | seggrab.size = grablen; if (addphysseg(&seggrab) == -1) { print("lml: physsegment: lmlgrab\n"); | |
| 1999/0525 | return; } | |
| 1999/0422 |
| |
| 1999/0529 | return; | |
| 1999/0422 | } static Chan* | |
| 1999/0529/sys/src/9/pc/devlml.c:120,126 – 1999/0531/sys/src/9/pc/devlml.c:120,126 (short | long) | ||
| 1999/0521 | break; } | |
| 1999/0520 | // Fill in APP marker fields here | |
| 1999/0531 | thetime = todget(nil); | |
| 1999/0520 | frameHeader.sec = (ulong)(thetime / 1000000000LL); frameHeader.usec = (ulong)(thetime % 1000000000LL) / 1000; frameHeader.frameSize = fragsize - 2 + sizeof(FrameHeader); | |
| 1999/0531/sys/src/9/pc/devlml.c:23,63 – 1999/0601/sys/src/9/pc/devlml.c:23,43 (short | long) | ||
| 1999/0422 | enum{ | |
| 1999/0513 | Qdir, | |
| 1999/0422 |
| |
| 1999/0526 | Qjcount, | |
| 1999/0422 | }; | |
| 1999/0513 | static Dirtab lmldir[]={ // name, qid, size, mode | |
| 1999/0422 |
| |
| 1999/0526 | "jcount", {Qjcount}, 0, 0444, | |
| 1999/0422 | }; CodeData * codeData; | |
| 1999/0520 |
| |
| 1999/0513 | int frameNo; | |
| 1999/0424 | Rendez sleeper; | |
| 1999/0513 | int singleFrame; int nopens; | |
| 1999/0429 |
| |
| 1999/0520 |
| |
| 1999/0424 |
| |
| 1999/0525 |
| |
| 1999/0515 | ||
| 1999/0531/sys/src/9/pc/devlml.c:86,262 – 1999/0601/sys/src/9/pc/devlml.c:66,71 | ||
| 1999/0424 | return 1; } | |
| 1999/0520 |
| |
| 1999/0526 |
| |
| 1999/0520 |
| |
| 1999/0526 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0521 |
| |
| 1999/0526 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0531 |
| |
| 1999/0520 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0526 |
| |
| 1999/0520 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0424 | ||
| 1999/0520 |
| |
| 1999/0526 |
| |
| 1999/0520 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0526 |
| |
| 1999/0520 |
| |
| 1999/0526 |
| |
| 1999/0521 |
| |
| 1999/0520 |
| |
| 1999/0424 |
| |
| 1999/0423 | static void lmlintr(Ureg *, void *); static void | |
| 1999/0531/sys/src/9/pc/devlml.c:289,302 – 1999/0601/sys/src/9/pc/devlml.c:98,108 | ||
| 1999/0527 | return; } | |
| 1999/0529 |
| |
| 1999/0422 | print("Installing Motion JPEG driver %s\n", MJPG_VERSION); | |
| 1999/0527 | print("MJPG buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize); | |
| 1999/0529 | print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabbuf, grablen); | |
| 1999/0422 | // Get access to DMA memory buffer | |
| 1999/0529 | codeData->pamjpg = PADDR(codeData->statCom); codeData->pagrab = PADDR(grabbuf); | |
| 1999/0520 | for (i = 0; i < NBUF; i++) { | |
| 1999/0531/sys/src/9/pc/devlml.c:306,313 – 1999/0601/sys/src/9/pc/devlml.c:112,117 | ||
| 1999/0518 | codeData->fragdesc[i].leng = ((sizeof codeData->frag[i]) >> 1) | FRAGM_FINAL_B; | |
| 1999/0422 | } | |
| 1999/0423 | pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F); | |
| 1999/0422 | ||
| 1999/0513 | print("zr36067 found at 0x%.8lux", pciPhysBaseAddr); | |
| 1999/0531/sys/src/9/pc/devlml.c:320,328 – 1999/0601/sys/src/9/pc/devlml.c:124,129 | ||
| 1999/0423 | pciBaseAddr = (ulong)KADDR(regpa); | |
| 1999/0513 | print(", mapped at 0x%.8lux\n", pciBaseAddr); | |
| 1999/0422 |
| |
| 1999/0423 |
| |
| 1999/0422 | ||
| 1999/0522 | memset(&segbuf, 0, sizeof(segbuf)); segbuf.attr = SG_PHYSICAL; segbuf.name = smalloc(NAMELEN); | |
| 1999/0531/sys/src/9/pc/devlml.c:355,360 – 1999/0601/sys/src/9/pc/devlml.c:156,165 | ||
| 1999/0527 | print("lml: physsegment: lmlgrab\n"); | |
| 1999/0525 | return; } | |
| 1999/0601 | // Interrupt handler intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); | |
| 1999/0529 | return; | |
| 1999/0422 | } | |
| 1999/0531/sys/src/9/pc/devlml.c:378,399 – 1999/0601/sys/src/9/pc/devlml.c:183,196 | ||
| 1999/0422 | static Chan* | |
| 1999/0518 | lmlopen(Chan *c, int omode) { | |
| 1999/0521 |
| |
| 1999/0517 | ||
| 1999/0422 | c->aux = 0; switch(c->qid.path){ | |
| 1999/0521 |
| |
| 1999/0526 | case Qjcount: | |
| 1999/0601 | // allow one open | |
| 1999/0424 | if (nopens) error(Einuse); nopens = 1; | |
| 1999/0520 |
| |
| 1999/0521 |
| |
| 1999/0517 | ||
| 1999/0422 |
| |
| 1999/0513 | return devopen(c, omode, lmldir, nelem(lmldir), devgen); | |
| 1999/0531/sys/src/9/pc/devlml.c:403,410 – 1999/0601/sys/src/9/pc/devlml.c:200,205 | ||
| 1999/0518 | lmlclose(Chan *c) { | |
| 1999/0422 | switch(c->qid.path){ | |
| 1999/0513 |
| |
| 1999/0422 |
| |
| 1999/0526 | case Qjcount: | |
| 1999/0515 | nopens = 0; | |
| 1999/0422 | authclose(c); | |
| 1999/0531/sys/src/9/pc/devlml.c:420,428 – 1999/0601/sys/src/9/pc/devlml.c:215,220 | ||
| 1999/0513 | case Qdir: return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen); | |
| 1999/0422 |
| |
| 1999/0424 |
| |
| 1999/0526 | case Qjcount: return vcount(c, buf, n, off); | |
| 1999/0422 | } | |
| 1999/0531/sys/src/9/pc/devlml.c:429,446 – 1999/0601/sys/src/9/pc/devlml.c:221,230 | ||
| 1999/0422 | } static long | |
| 1999/0514 |
| |
| 1999/0424 |
| |
| 1999/0514 |
| |
| 1999/0601 | lmlwrite(Chan *, void *, long, vlong) { | |
| 1999/0423 | ||
| 1999/0513 |
| |
| 1999/0526 |
| |
| 1999/0513 |
| |
| 1999/0423 |
| |
| 1999/0424 |
| |
| 1999/0423 |
| |
| 1999/0601 | error(Eperm); return 0; | |
| 1999/0422 | } | |
| 1999/0513 | Dev lmldevtab = { | |
| 1999/0601/sys/src/9/pc/devlml.c:23,42 – 1999/0610/sys/src/9/pc/devlml.c:23,71 (short | long) | ||
| 1999/0422 | enum{ | |
| 1999/0513 | Qdir, | |
| 1999/0526 |
| |
| 1999/0610 | Qjpg, // Qraw, | |
| 1999/0422 | }; | |
| 1999/0513 | static Dirtab lmldir[]={ | |
| 1999/0526 |
| |
| 1999/0610 | // name, qid, size, mode "lmljpg", {Qjpg}, 0, 0444, // "lmlraw", {Qraw}, 0, 0444, | |
| 1999/0422 | }; | |
| 1999/0610 | static CodeData * codeData; | |
| 1999/0422 | ||
| 1999/0610 | static ulong jpgframeno; //static ulong rawframeno; //static FrameHeader rawheader; static FrameHeader jpgheader[NBUF] = { { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, { 'L', 'M', 'L', '\0'}, -1, 0, 0, 0, 0 }, { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, { 'L', 'M', 'L', '\0'}, -1, 0, 0, 0, 0 }, { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, { 'L', 'M', 'L', '\0'}, -1, 0, 0, 0, 0 }, { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, { 'L', 'M', 'L', '\0'}, -1, 0, 0, 0, 0 } }; | |
| 1999/0513 | int frameNo; | |
| 1999/0424 |
| |
| 1999/0610 | Rendez sleepjpg; //Rendez sleepraw; | |
| 1999/0513 | int singleFrame; | |
| 1999/0610 | int jpgopens; //int rawopens; | |
| 1999/0424 | ||
| 1999/0525 | #define writel(v, a) *(ulong *)(a) = (v) #define readl(a) *(ulong*)(a) | |
| 1999/0601/sys/src/9/pc/devlml.c:51,74 – 1999/0610/sys/src/9/pc/devlml.c:80,136 | ||
| 1999/0526 | if (codeData->statCom[last] & STAT_BIT) return last; if (last == l) | |
| 1999/0610 | sleep(&sleepjpg, return0, 0); | |
| 1999/0423 | } | |
| 1999/0526 | return 0; | |
| 1999/0423 | } | |
| 1999/0526 | static long | |
| 1999/0610 | jpgread(Chan *, void *va, long nbytes, vlong) { int bufno; | |
| 1999/0423 | ||
| 1999/0526 |
| |
| 1999/0424 |
| |
| 1999/0610 | // reads should be of size 1 or sizeof(FrameHeader) // Frameno is the number of the buffer containing the data bufno = getbuffer(); if (nbytes == sizeof(FrameHeader)) { memmove(va, &jpgheader[bufno], sizeof jpgheader[bufno]); return sizeof jpgheader[bufno]; } if (nbytes == 1) { *(char *)va = bufno; return 1; } return 0; | |
| 1999/0424 | } | |
| 1999/0610 | /* static long rawread(Chan *, void *va, long nbytes, vlong) { // reads should be at least sizeof(FrameHeader) long // Frameno is the number of the buffer containing the data if (nbytes < sizeof(FrameHeader)) return 0; sleep(&sleepraw, return0, 0); memmove(va, &rawheader, sizeof rawheader); return sizeof rawheader; } */ | |
| 1999/0423 | static void lmlintr(Ureg *, void *); static void | |
| 1999/0610 | prepbuf(void) { int i; for (i = 0; i < NBUF; i++) { codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i])); // Length is in double words, in position 1..20 codeData->fragdesc[i].leng = ((sizeof codeData->frag[i]) >> 1) | FRAGM_FINAL_B; } } static void | |
| 1999/0513 | lmlreset(void) | |
| 1999/0422 | { | |
| 1999/0522 | Physseg segbuf; | |
| 1999/0601/sys/src/9/pc/devlml.c:78,84 – 1999/0610/sys/src/9/pc/devlml.c:140,145 | ||
| 1999/0525 | ulong cdsize; | |
| 1999/0529 | void *grabbuf; | |
| 1999/0527 | ulong grablen; | |
| 1999/0422 |
| |
| 1999/0423 | pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067); if (pcidev == nil) { | |
| 1999/0601/sys/src/9/pc/devlml.c:105,117 – 1999/0610/sys/src/9/pc/devlml.c:166,174 | ||
| 1999/0422 | // Get access to DMA memory buffer | |
| 1999/0529 | codeData->pamjpg = PADDR(codeData->statCom); codeData->pagrab = PADDR(grabbuf); | |
| 1999/0520 |
| |
| 1999/0517 |
| |
| 1999/0422 |
| |
| 1999/0518 |
| |
| 1999/0422 |
| |
| 1999/0610 | prepbuf(); | |
| 1999/0423 | pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F); | |
| 1999/0422 | ||
| 1999/0513 | print("zr36067 found at 0x%.8lux", pciPhysBaseAddr); | |
| 1999/0601/sys/src/9/pc/devlml.c:186,197 – 1999/0610/sys/src/9/pc/devlml.c:243,264 | ||
| 1999/0517 | ||
| 1999/0422 | c->aux = 0; switch(c->qid.path){ | |
| 1999/0526 |
| |
| 1999/0610 | case Qjpg: | |
| 1999/0601 | // allow one open | |
| 1999/0424 |
| |
| 1999/0610 | if (jpgopens) | |
| 1999/0424 | error(Einuse); | |
| 1999/0610 | jpgopens = 1; jpgframeno = 0; prepbuf(); | |
| 1999/0422 | break; | |
| 1999/0610 | /* case Qraw: // allow one open if (rawopens) error(Einuse); rawopens = 1; rawframeno = 0; break; */ | |
| 1999/0422 | } | |
| 1999/0513 | return devopen(c, omode, lmldir, nelem(lmldir), devgen); | |
| 1999/0422 | } | |
| 1999/0601/sys/src/9/pc/devlml.c:200,209 – 1999/0610/sys/src/9/pc/devlml.c:267,281 | ||
| 1999/0518 | lmlclose(Chan *c) { | |
| 1999/0422 | switch(c->qid.path){ | |
| 1999/0526 |
| |
| 1999/0515 |
| |
| 1999/0422 |
| |
| 1999/0610 | case Qjpg: jpgopens = 0; break; /* case Qraw: rawopens = 0; break; */ | |
| 1999/0422 | } | |
| 1999/0610 | authclose(c); | |
| 1999/0422 | } static long | |
| 1999/0601/sys/src/9/pc/devlml.c:215,222 – 1999/0610/sys/src/9/pc/devlml.c:287,297 | ||
| 1999/0513 | case Qdir: return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen); | |
| 1999/0526 |
| |
| 1999/0610 | case Qjpg: return jpgread(c, buf, n, off); /* case Qraw: return rawread(c, buf, n, off); */ | |
| 1999/0422 | } } | |
| 1999/0601/sys/src/9/pc/devlml.c:250,256 – 1999/0610/sys/src/9/pc/devlml.c:325,331 | ||
| 1999/0422 | static void | |
| 1999/0424 | lmlintr(Ureg *, void *) { | |
| 1999/0520 |
| |
| 1999/0610 | ulong fstart, fno; | |
| 1999/0520 | ulong flags = readl(pciBaseAddr+INTR_STAT); | |
| 1999/0424 | ||
| 1999/0520 | if(debug&(DBGINTR)) | |
| 1999/0601/sys/src/9/pc/devlml.c:260,268 – 1999/0610/sys/src/9/pc/devlml.c:335,362 | ||
| 1999/0520 | writel(0xff000000, pciBaseAddr + INTR_STAT); | |
| 1999/0423 | ||
| 1999/0520 | if(flags & INTR_JPEGREP) { | |
| 1999/0515 |
| |
| 1999/0610 | vlong thetime; fstart = jpgframeno & 0x00000003; for (;;) { jpgframeno++; fno = jpgframeno & 0x00000003; if (codeData->statCom[fno] & STAT_BIT) break; if (fno == fstart) { if (debug & DBGINTR) print("Spurious lml jpg intr?\n"); return; } } thetime = todget(nil); jpgheader[fno].sec = (ulong)(thetime / 1000000000LL); jpgheader[fno].usec = (ulong)(thetime % 1000000000LL) / 1000; jpgheader[fno].frameSize = (codeData->statCom[fno] & 0x00ffffff) >> 1; jpgheader[fno].frameSeqNo = codeData->statCom[fno] >> 24; jpgheader[fno].frameNo = jpgframeno; wakeup(&sleepjpg); | |
| 1999/0515 | } | |
| 1999/0424 | return; | |
| 1999/0422 | } | |
| 1999/0610/sys/src/9/pc/devlml.c:215,221 – 1999/0819/sys/src/9/pc/devlml.c:215,221 (short | long) | ||
| 1999/0525 | } | |
| 1999/0601 | // Interrupt handler | |
| 1999/0819 | intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf, "lml"); | |
| 1999/0601 | ||
| 1999/0529 | return; | |
| 1999/0422 | } | |
| 1999/0819/sys/src/9/pc/devlml.c:351,357 – 1999/0909/sys/src/9/pc/devlml.c:351,357 (short | long) | ||
| 1999/0610 | } thetime = todget(nil); jpgheader[fno].sec = (ulong)(thetime / 1000000000LL); | |
| 1999/0909 | jpgheader[fno].nsec = (ulong)(thetime % 1000000000LL); | |
| 1999/0610 | jpgheader[fno].frameSize = (codeData->statCom[fno] & 0x00ffffff) >> 1; jpgheader[fno].frameSeqNo = codeData->statCom[fno] >> 24; | |
| 1999/0909/sys/src/9/pc/devlml.c:7,12 – 1999/0915/sys/src/9/pc/devlml.c:7,20 (short | long) | ||
| 1999/0422 | #include "io.h" #include "devlml.h" | |
| 1999/0915 | #include "index.h" #include "avctl.h" #include "misc.h" Medium *m; AVctl *ctl = &ctlinit; | |
| 1999/0422 | ||
| 1999/0520 | static void * pciPhysBaseAddr; static ulong pciBaseAddr; | |
| 1999/0915/sys/src/9/pc/devlml.c:7,20 – 1999/1005/sys/src/9/pc/devlml.c:7,12 (short | long) | ||
| 1999/0422 | #include "io.h" #include "devlml.h" | |
| 1999/0915 |
| |
| 1999/0422 | ||
| 1999/0520 | static void * pciPhysBaseAddr; static ulong pciBaseAddr; | |
| Too many diffs (26 > 25). Stopping. | ||