From gassend@MIT.EDU Mon, 7 Jan 2002 22:48:23 -0500 Date: Mon, 7 Jan 2002 22:48:23 -0500 From: Blaise Gassend gassend@MIT.EDU Subject: [cpia] DMA mode in 2.4.x Hi, Having been forced to upgrade to a 2.4.x kernel, I finally took the time to get the DMA going on my parallel port CPiA camera. A working but not very clean piece of code was produced, it has been working fine for a couple of weeks now. I am posting it here for the people who are frustrated with the hopelessly slow speeds of the non-DMA transfer, and who still want to move to 2.4.x. For now, I expect that this code will probably bother Parallel devices other than the CPIA camera if they happen to do block reads with DMA turned on. I hope to fix this shortly. This was taken from a 2.4.6 kernel, but I haven't seen any changes that should prevent it from working with later kernels. In any case, you are trying at your own risk, of course. Cheers, Blaise Two patches follow. Sorry if this isn't the approved way of doing things, I'm new to this list. The firts patch applies to /usr/src/linux/drivers/media/video/cpia_pp.c 39c39 < /*#define _CPIA_DEBUG_ define for verbose debug output */ --- > /* #define _CPIA_DEBUG_ define for verbose debug output */ 205,211c205 < int ecr = ECONTROL(cam->port); < int oecr = inb(ecr); < oecr &= ~(7 << 5); < oecr |= 1 << 5; < outb (oecr, ecr); < < parport_negotiate(cam->port, IEEE1284_MODE_COMPAT); --- > parport_negotiate(cam->port, IEEE1284_MODE_COMPAT); 309d302 < 479d471 < The second patch applies to /usr/src/linux/drivers/parport/parport_pc.c 16d15 < * Added DMA read support, only for CPiA so far. Blaise Gassend 12/01 78c77 < //#define DEBUG --- > #define DEBUG 680,682c679 < DPRINTK (KERN_DEBUG "parport_pc_ecp_write_block_dma\n"); < < dump_parport_state ("enter fifo_write_block_dma", port); --- > dump_parport_state ("enter fifo_write_block_dma", port); 796,1032d792 < static size_t parport_pc_fifo_read_block_dma (struct parport *port, < void *bufv, size_t length, int flags) < { < int ret = 0; < unsigned long dmaflag; < size_t left = length; < const struct parport_pc_private *priv = port->physport->private_data; < dma_addr_t dma_addr, dma_handle = 0; < size_t maxlen = 0x10000; /* max 64k per DMA transfer */ < char *buf = bufv; < unsigned long start = (unsigned long) buf; < unsigned long end = (unsigned long) buf + length - 1; < size_t count; < < DPRINTK (KERN_DEBUG "parport_pc_ecp_read_block_dma\n"); < < if (length == 0) < return 0; < < /* Special case: a timeout of zero means we cannot call schedule(). */ < if (!port->cad->timeout) < return parport_ieee1284_ecp_read_data (port, buf, < length, flags); < < ret = change_mode (port, ECR_ECP); /* ECP FIFO */ < if (ret) printk (KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n", port->name); < < if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE) { < /* change to reverse-idle phase (must be in forward-idle) */ < < /* Event 38: Set nAutoFd low (also make sure nStrobe is high) */ < parport_frob_control (port, < PARPORT_CONTROL_AUTOFD, < PARPORT_CONTROL_AUTOFD); < parport_pc_data_reverse (port); /* Must be in PS2 mode */ < udelay (5); < /* Event 39: Set nInit low to initiate bus reversal */ < parport_frob_control (port, < PARPORT_CONTROL_INIT, < 0); < /* Event 40: Wait for nAckReverse (PError) to go low */ < ret = parport_wait_peripheral (port, PARPORT_STATUS_PAPEROUT, 0); < if (ret) { < printk (KERN_DEBUG "%s: PE timeout Event 40 (%d) " < "in ecp_read_block_dma\n", port->name, ret); < return 0; < } < < port->ieee1284.phase = IEEE1284_PH_REV_DATA; < < parport_frob_control (port, < PARPORT_CONTROL_AUTOFD, < PARPORT_CONTROL_AUTOFD); < < /* the first byte must be collected manually */ < ret = parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0); < if (ret) { < /* timed out while reading -- no data */ < printk (KERN_DEBUG "PIO read timed out (initial byte)\n"); < goto out_no_data; < } < /* read byte */ /* Bogus data for some reason. */ < /**buf++ =*/ inb (DATA (port)); < // left--; < dump_parport_state ("43-44", port); < /* Event 44: nAutoFd (HostAck) goes high to acknowledge */ < parport_pc_frob_control (port, < PARPORT_CONTROL_AUTOFD, < 0); < dump_parport_state ("pre 45", port); < /* Event 45: Wait for nAck to go high */ < ret = parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); < dump_parport_state ("post 45", port); < if (ret) { < /* timed out while waiting for peripheral to respond to ack */ < printk (KERN_DEBUG "ECP PIO read timed out (waiting for nAck)\n"); < < /* keep hold of the byte we've got already */ < goto out_no_data; < } < } < // < // DPRINTK (KERN_DEBUG "first byte has been read\n"); < // < // dump_parport_state ("enter fifo_read_block_dma", port); < if (end < MAX_DMA_ADDRESS) { < /* If it would cross a 64k boundary, cap it at the end. */ < if ((start ^ end) & ~0xffffUL) < maxlen = 0x10000 - (start & 0xffff); < < dma_addr = dma_handle = pci_map_single(priv->dev, (void *)buf, length, < PCI_DMA_FROMDEVICE); < } else { < /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */ < maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */ < dma_addr = priv->dma_handle; < } < < DPRINTK (KERN_DEBUG "DMA buffer is ready\n"); < < port = port->physport; < < /* We don't want to be interrupted every character. */ < parport_pc_disable_irq (port); < /* set nErrIntrEn and serviceIntr */ < frob_econtrol (port, (1<<4) | (1<<2), (1<<4) | (1<<2)); < < /* Forward mode. */ < parport_pc_data_reverse (port); /* Must be in PS2 mode */ < < if (!left) < goto out_no_data; < < while (left) { < long expire = jiffies + port->physport->cad->timeout; < < DPRINTK (KERN_DEBUG "start of while %i left\n", left); < < count = left; < < if (count > maxlen) < count = maxlen; < < dmaflag = claim_dma_lock(); < disable_dma(port->dma); < clear_dma_ff(port->dma); < set_dma_mode(port->dma, DMA_MODE_READ); < set_dma_addr(port->dma, dma_addr); < set_dma_count(port->dma, count); < < /* Set DMA mode */ < frob_econtrol (port, 1<<3, 1<<3); < < /* Clear serviceIntr */ < frob_econtrol (port, 1<<2, 0); < < enable_dma(port->dma); < release_dma_lock(dmaflag); < < /* Wait for interrupt. */ < DPRINTK (KERN_DEBUG "about to wait\n"); < false_alarm: < ret = parport_wait_event (port, HZ); < if (ret < 0) break; < ret = 0; < if (!time_before (jiffies, expire)) { < /* Timed out. */ < printk (KERN_DEBUG "DMA read timed out\n"); < break; < } < /* Is serviceIntr set? */ < if (!(inb (ECONTROL (port)) & (1<<2))) { < if (current->need_resched) < schedule (); < < goto false_alarm; < } < < dmaflag = claim_dma_lock(); < disable_dma(port->dma); < clear_dma_ff(port->dma); < count -= get_dma_residue(port->dma); < release_dma_lock(dmaflag); < < if (current->need_resched) < /* Can't yield the port. */ < schedule (); < < /* Anyone else waiting for the port? */ < if (port->waithead) { < printk (KERN_DEBUG "Somebody wants the port\n"); < break; < } < < /* update for possible DMA residue ! */ < DPRINTK (KERN_DEBUG "read %i in loop\n", count); < if (dma_handle) dma_addr += count; < else memcpy(buf, priv->dma_buf, count); < buf += count; < left -= count; < } < < /* Maybe got here through break, so adjust for DMA residue! */ < if (left) < { < DPRINTK (KERN_DEBUG "exited on break\n"); < dmaflag = claim_dma_lock(); < disable_dma(port->dma); < clear_dma_ff(port->dma); < count -= get_dma_residue(port->dma); < release_dma_lock(dmaflag); < < if (!dma_handle) < memcpy(buf, priv->dma_buf, count); < left -= count; < } < < dump_parport_state ("leave fifo_read_block_dma", port); < out_no_data: < < frob_econtrol (port, 1<<2, 1<<2); < /* Turn off DMA mode */ < frob_econtrol (port, 1<<3, 0); < < // ret = change_mode (port, ECR_PS2); /* ECP FIFO */ < // if (ret) printk (KERN_DEBUG "%s: Warning change_mode ECR_PS2 failed\n", port->name); < < if (dma_handle) < pci_unmap_single(priv->dev, dma_handle, length, PCI_DMA_TODEVICE); < < // /* Go to forward idle mode to shut the peripheral up (event 47). */ < // parport_frob_control (port, PARPORT_CONTROL_INIT | PARPORT_CONTROL_AUTOFD, < // PARPORT_CONTROL_INIT | PARPORT_CONTROL_AUTOFD); < // < // /* event 49: PError goes high */ < // ret = parport_wait_peripheral (port, < // PARPORT_STATUS_PAPEROUT, < // PARPORT_STATUS_PAPEROUT); < // if (ret) { < // printk (KERN_DEBUG < // "%s: PE timeout FWDIDLE (%d) in ecp_read_block_pio\n", < // port->name, ret); < // } < // else < // { < // parport_data_forward (port); < // port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; < // } < // < dump_parport_state ("fwd idle", port); < < port->ieee1284.phase = IEEE1284_PH_REV_IDLE; < < DPRINTK (KERN_DEBUG "returning %i bytes read\n", length - left); < return length - left; < } < 1041,1042d800 < DPRINTK (KERN_DEBUG "parport_pc_compat_write_block_pio\n"); < 1107,1108d864 < DPRINTK (KERN_DEBUG "parport_pc_ecp_write_block_pio\n"); < 1216,1217c972,973 < DPRINTK (KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n"); < dump_parport_state ("enter fcn", port); --- > DPRINTK (KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n"); > dump_parport_state ("enter fcn", port); 1222c978 < length, flags); --- > length, flags); 1238c994 < length, flags); --- > length, flags); 1245,1247c1001,1003 < PARPORT_CONTROL_AUTOFD < | PARPORT_CONTROL_STROBE, < PARPORT_CONTROL_AUTOFD); --- > PARPORT_CONTROL_AUTOFD > | PARPORT_CONTROL_STROBE, > PARPORT_CONTROL_AUTOFD); 1252,1253c1008,1009 < PARPORT_CONTROL_INIT, < 0); --- > PARPORT_CONTROL_INIT, > 0); 1256,1258c1012,1014 < if (r) { < printk (KERN_DEBUG "%s: PE timeout Event 40 (%d) " < "in ecp_read_block_pio\n", port->name, r); --- > if (r) { > printk (KERN_DEBUG "%s: PE timeout Event 40 (%d) " > "in ecp_read_block_pio\n", port->name, r); 1264,1267c1020,1023 < /* parport_pc_frob_control (port, < PARPORT_CONTROL_STROBE | < PARPORT_CONTROL_AUTOFD, < PARPORT_CONTROL_AUTOFD); */ --- > /* parport_pc_frob_control (port, > PARPORT_CONTROL_STROBE | > PARPORT_CONTROL_AUTOFD, > PARPORT_CONTROL_AUTOFD); */ 1274c1030 < dump_parport_state ("pre 43", port); --- > dump_parport_state ("pre 43", port); 1285c1041 < dump_parport_state ("43-44", port); --- > dump_parport_state ("43-44", port); 1288,1290c1044,1046 < PARPORT_CONTROL_AUTOFD, < 0); < dump_parport_state ("pre 45", port); --- > PARPORT_CONTROL_AUTOFD, > 0); > dump_parport_state ("pre 45", port); 1292,1294c1048,1050 < /* r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); */ < dump_parport_state ("post 45", port); < r = 0; --- > /* r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); */ > dump_parport_state ("post 45", port); > r = 0; 1304,1305c1060,1061 < PARPORT_CONTROL_AUTOFD, < PARPORT_CONTROL_AUTOFD); --- > PARPORT_CONTROL_AUTOFD, > PARPORT_CONTROL_AUTOFD); 1308c1064 < dump_parport_state ("rev idle", port); --- > dump_parport_state ("rev idle", port); 1320,1323c1076,1079 < * that case ECP is already holding back the < * peripheral (assuming proper design) with a delayed < * handshake. Work fast to avoid a peripheral < * timeout. */ --- > * that case ECP is already holding back the > * peripheral (assuming proper design) with a delayed > * handshake. Work fast to avoid a peripheral > * timeout. */ 1327c1083 < dump_parport_state ("FIFO empty", port); --- > dump_parport_state ("FIFO empty", port); 1337,1338c1093,1094 < false_alarm: < dump_parport_state ("waiting", port); --- > false_alarm: > dump_parport_state ("waiting", port); 1340c1096 < DPRINTK (KERN_DEBUG "parport_wait_event returned %d\n", ret); --- > DPRINTK (KERN_DEBUG "parport_wait_event returned %d\n", ret); 1346c1102 < dump_parport_state ("timeout", port); --- > dump_parport_state ("timeout", port); 1353c1109 < time_before (jiffies, expire)) { --- > time_before (jiffies, expire)) { 1360,1362c1116,1118 < * set, how long interrupt service took, and < * how fast the peripheral is, we might be < * lucky and have a just filled FIFO. */ --- > * set, how long interrupt service took, and > * how fast the peripheral is, we might be > * lucky and have a just filled FIFO. */ 1368c1124 < dump_parport_state ("FIFO full", port); --- > dump_parport_state ("FIFO full", port); 1375c1131 < DPRINTK (KERN_DEBUG "*** ecp_read_block_pio: reading one byte from the FIFO\n"); --- > DPRINTK (KERN_DEBUG "*** ecp_read_block_pio: reading one byte from the FIFO\n"); 1378,1379c1134,1135 < * and either the peripheral will fill it faster, < * tripping a fast empty with insb, or we empty it. */ --- > * and either the peripheral will fill it faster, > * tripping a fast empty with insb, or we empty it. */ 1391c1147 < dump_parport_state ("rev idle2", port); --- > dump_parport_state ("rev idle2", port); 1400,1401c1156,1157 < PARPORT_STATUS_PAPEROUT, < PARPORT_STATUS_PAPEROUT); --- > PARPORT_STATUS_PAPEROUT, > PARPORT_STATUS_PAPEROUT); 1404,1405c1160,1161 < "%s: PE timeout FWDIDLE (%d) in ecp_read_block_pio\n", < port->name, r); --- > "%s: PE timeout FWDIDLE (%d) in ecp_read_block_pio\n", > port->name, r); 1416c1172 < port->name, lost); --- > port->name, lost); 1419c1175 < dump_parport_state ("fwd idle", port); --- > dump_parport_state ("fwd idle", port); 2503,2504c2259 < /* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; < * */ --- > /* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; */ 2509d2263 < p->ops->ecp_read_data = parport_pc_fifo_read_block_dma; 2610d2363 < { 2612,2613d2364 < change_mode (p, ECR_PS2); < } From onosen@poly.polytechnique.fr Tue, 8 Jan 2002 11:43:09 +0100 Date: Tue, 8 Jan 2002 11:43:09 +0100 From: Nicola ONOSE onosen@poly.polytechnique.fr Subject: [cpia] DMA mode in 2.4.x From: "Blaise Gassend" To: Sent: Tuesday, January 08, 2002 4:48 AM Subject: [cpia] DMA mode in 2.4.x > Hi, > > Having been forced to upgrade to a 2.4.x kernel, I finally took the time > to get the DMA going on my parallel port CPiA camera. > Thanx [from Binet Robot] I've been quite busy lately and your code is of great help. Stupid question: Is any functional difference between your solution and the cpia drivers for the 2.2 kernel ? (Or the "effect" is just the same) Nicola From gleicon@uol.com.br Tue, 8 Jan 2002 09:14:44 -0200 Date: Tue, 8 Jan 2002 09:14:44 -0200 From: Gleicon S. Moraes gleicon@uol.com.br Subject: [cpia] DMA mode in 2.4.x Thanks ! ----- Original Message ----- From: "Blaise Gassend" To: Sent: Tuesday, January 08, 2002 1:48 AM Subject: [cpia] DMA mode in 2.4.x > Hi, > > Having been forced to upgrade to a 2.4.x kernel, I finally took the time > to get the DMA going on my parallel port CPiA camera. > > A working but not very clean piece of code was produced, it has been > working fine for a couple of weeks now. > > I am posting it here for the people who are frustrated with the > hopelessly slow speeds of the non-DMA transfer, and who still want to > move to 2.4.x. > > For now, I expect that this code will probably bother Parallel devices > other than the CPIA camera if they happen to do block reads with DMA > turned on. I hope to fix this shortly. > > This was taken from a 2.4.6 kernel, but I haven't seen any changes that > should prevent it from working with later kernels. In any case, you are > trying at your own risk, of course. > > Cheers, > Blaise > > Two patches follow. Sorry if this isn't the approved way of doing > things, I'm new to this list. > > > > > The firts patch applies to /usr/src/linux/drivers/media/video/cpia_pp.c > > > 39c39 > < /*#define _CPIA_DEBUG_ define for verbose debug output */ > --- > > /* #define _CPIA_DEBUG_ define for verbose debug output */ > 205,211c205 > < int ecr = ECONTROL(cam->port); > < int oecr = inb(ecr); > < oecr &= ~(7 << 5); > < oecr |= 1 << 5; > < outb (oecr, ecr); > < > < parport_negotiate(cam->port, IEEE1284_MODE_COMPAT); > --- > > parport_negotiate(cam->port, IEEE1284_MODE_COMPAT); > 309d302 > < > 479d471 > < > > > > > > > The second patch applies to /usr/src/linux/drivers/parport/parport_pc.c > > > 16d15 > < * Added DMA read support, only for CPiA so far. Blaise Gassend 12/01 > 78c77 > < //#define DEBUG > --- > > #define DEBUG > 680,682c679 > < DPRINTK (KERN_DEBUG "parport_pc_ecp_write_block_dma\n"); > < > < dump_parport_state ("enter fifo_write_block_dma", port); > --- > > dump_parport_state ("enter fifo_write_block_dma", port); > 796,1032d792 > < static size_t parport_pc_fifo_read_block_dma (struct parport *port, > < void *bufv, size_t length, int flags) > < { > < int ret = 0; > < unsigned long dmaflag; > < size_t left = length; > < const struct parport_pc_private *priv = port->physport->private_data; > < dma_addr_t dma_addr, dma_handle = 0; > < size_t maxlen = 0x10000; /* max 64k per DMA transfer */ > < char *buf = bufv; > < unsigned long start = (unsigned long) buf; > < unsigned long end = (unsigned long) buf + length - 1; > < size_t count; > < > < DPRINTK (KERN_DEBUG "parport_pc_ecp_read_block_dma\n"); > < > < if (length == 0) > < return 0; > < > < /* Special case: a timeout of zero means we cannot call schedule(). */ > < if (!port->cad->timeout) > < return parport_ieee1284_ecp_read_data (port, buf, > < length, flags); > < > < ret = change_mode (port, ECR_ECP); /* ECP FIFO */ > < if (ret) printk (KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n", port->name); > < > < if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE) { > < /* change to reverse-idle phase (must be in forward-idle) */ > < > < /* Event 38: Set nAutoFd low (also make sure nStrobe is high) */ > < parport_frob_control (port, > < PARPORT_CONTROL_AUTOFD, > < PARPORT_CONTROL_AUTOFD); > < parport_pc_data_reverse (port); /* Must be in PS2 mode */ > < udelay (5); > < /* Event 39: Set nInit low to initiate bus reversal */ > < parport_frob_control (port, > < PARPORT_CONTROL_INIT, > < 0); > < /* Event 40: Wait for nAckReverse (PError) to go low */ > < ret = parport_wait_peripheral (port, PARPORT_STATUS_PAPEROUT, 0); > < if (ret) { > < printk (KERN_DEBUG "%s: PE timeout Event 40 (%d) " > < "in ecp_read_block_dma\n", port->name, ret); > < return 0; > < } > < > < port->ieee1284.phase = IEEE1284_PH_REV_DATA; > < > < parport_frob_control (port, > < PARPORT_CONTROL_AUTOFD, > < PARPORT_CONTROL_AUTOFD); > < > < /* the first byte must be collected manually */ > < ret = parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0); > < if (ret) { > < /* timed out while reading -- no data */ > < printk (KERN_DEBUG "PIO read timed out (initial byte)\n"); > < goto out_no_data; > < } > < /* read byte */ /* Bogus data for some reason. */ > < /**buf++ =*/ inb (DATA (port)); > < // left--; > < dump_parport_state ("43-44", port); > < /* Event 44: nAutoFd (HostAck) goes high to acknowledge */ > < parport_pc_frob_control (port, > < PARPORT_CONTROL_AUTOFD, > < 0); > < dump_parport_state ("pre 45", port); > < /* Event 45: Wait for nAck to go high */ > < ret = parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); > < dump_parport_state ("post 45", port); > < if (ret) { > < /* timed out while waiting for peripheral to respond to ack */ > < printk (KERN_DEBUG "ECP PIO read timed out (waiting for nAck)\n"); > < > < /* keep hold of the byte we've got already */ > < goto out_no_data; > < } > < } > < // > < // DPRINTK (KERN_DEBUG "first byte has been read\n"); > < // > < // dump_parport_state ("enter fifo_read_block_dma", port); > < if (end < MAX_DMA_ADDRESS) { > < /* If it would cross a 64k boundary, cap it at the end. */ > < if ((start ^ end) & ~0xffffUL) > < maxlen = 0x10000 - (start & 0xffff); > < > < dma_addr = dma_handle = pci_map_single(priv->dev, (void *)buf, length, > < PCI_DMA_FROMDEVICE); > < } else { > < /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */ > < maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */ > < dma_addr = priv->dma_handle; > < } > < > < DPRINTK (KERN_DEBUG "DMA buffer is ready\n"); > < > < port = port->physport; > < > < /* We don't want to be interrupted every character. */ > < parport_pc_disable_irq (port); > < /* set nErrIntrEn and serviceIntr */ > < frob_econtrol (port, (1<<4) | (1<<2), (1<<4) | (1<<2)); > < > < /* Forward mode. */ > < parport_pc_data_reverse (port); /* Must be in PS2 mode */ > < > < if (!left) > < goto out_no_data; > < > < while (left) { > < long expire = jiffies + port->physport->cad->timeout; > < > < DPRINTK (KERN_DEBUG "start of while %i left\n", left); > < > < count = left; > < > < if (count > maxlen) > < count = maxlen; > < > < dmaflag = claim_dma_lock(); > < disable_dma(port->dma); > < clear_dma_ff(port->dma); > < set_dma_mode(port->dma, DMA_MODE_READ); > < set_dma_addr(port->dma, dma_addr); > < set_dma_count(port->dma, count); > < > < /* Set DMA mode */ > < frob_econtrol (port, 1<<3, 1<<3); > < > < /* Clear serviceIntr */ > < frob_econtrol (port, 1<<2, 0); > < > < enable_dma(port->dma); > < release_dma_lock(dmaflag); > < > < /* Wait for interrupt. */ > < DPRINTK (KERN_DEBUG "about to wait\n"); > < false_alarm: > < ret = parport_wait_event (port, HZ); > < if (ret < 0) break; > < ret = 0; > < if (!time_before (jiffies, expire)) { > < /* Timed out. */ > < printk (KERN_DEBUG "DMA read timed out\n"); > < break; > < } > < /* Is serviceIntr set? */ > < if (!(inb (ECONTROL (port)) & (1<<2))) { > < if (current->need_resched) > < schedule (); > < > < goto false_alarm; > < } > < > < dmaflag = claim_dma_lock(); > < disable_dma(port->dma); > < clear_dma_ff(port->dma); > < count -= get_dma_residue(port->dma); > < release_dma_lock(dmaflag); > < > < if (current->need_resched) > < /* Can't yield the port. */ > < schedule (); > < > < /* Anyone else waiting for the port? */ > < if (port->waithead) { > < printk (KERN_DEBUG "Somebody wants the port\n"); > < break; > < } > < > < /* update for possible DMA residue ! */ > < DPRINTK (KERN_DEBUG "read %i in loop\n", count); > < if (dma_handle) dma_addr += count; > < else memcpy(buf, priv->dma_buf, count); > < buf += count; > < left -= count; > < } > < > < /* Maybe got here through break, so adjust for DMA residue! */ > < if (left) > < { > < DPRINTK (KERN_DEBUG "exited on break\n"); > < dmaflag = claim_dma_lock(); > < disable_dma(port->dma); > < clear_dma_ff(port->dma); > < count -= get_dma_residue(port->dma); > < release_dma_lock(dmaflag); > < > < if (!dma_handle) > < memcpy(buf, priv->dma_buf, count); > < left -= count; > < } > < > < dump_parport_state ("leave fifo_read_block_dma", port); > < out_no_data: > < > < frob_econtrol (port, 1<<2, 1<<2); > < /* Turn off DMA mode */ > < frob_econtrol (port, 1<<3, 0); > < > < // ret = change_mode (port, ECR_PS2); /* ECP FIFO */ > < // if (ret) printk (KERN_DEBUG "%s: Warning change_mode ECR_PS2 failed\n", port->name); > < > < if (dma_handle) > < pci_unmap_single(priv->dev, dma_handle, length, PCI_DMA_TODEVICE); > < > < // /* Go to forward idle mode to shut the peripheral up (event 47). */ > < // parport_frob_control (port, PARPORT_CONTROL_INIT | PARPORT_CONTROL_AUTOFD, > < // PARPORT_CONTROL_INIT | PARPORT_CONTROL_AUTOFD); > < // > < // /* event 49: PError goes high */ > < // ret = parport_wait_peripheral (port, > < // PARPORT_STATUS_PAPEROUT, > < // PARPORT_STATUS_PAPEROUT); > < // if (ret) { > < // printk (KERN_DEBUG > < // "%s: PE timeout FWDIDLE (%d) in ecp_read_block_pio\n", > < // port->name, ret); > < // } > < // else > < // { > < // parport_data_forward (port); > < // port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; > < // } > < // > < dump_parport_state ("fwd idle", port); > < > < port->ieee1284.phase = IEEE1284_PH_REV_IDLE; > < > < DPRINTK (KERN_DEBUG "returning %i bytes read\n", length - left); > < return length - left; > < } > < > 1041,1042d800 > < DPRINTK (KERN_DEBUG "parport_pc_compat_write_block_pio\n"); > < > 1107,1108d864 > < DPRINTK (KERN_DEBUG "parport_pc_ecp_write_block_pio\n"); > < > 1216,1217c972,973 > < DPRINTK (KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n"); > < dump_parport_state ("enter fcn", port); > --- > > DPRINTK (KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n"); > > dump_parport_state ("enter fcn", port); > 1222c978 > < length, flags); > --- > > length, flags); > 1238c994 > < length, flags); > --- > > length, flags); > 1245,1247c1001,1003 > < PARPORT_CONTROL_AUTOFD > < | PARPORT_CONTROL_STROBE, > < PARPORT_CONTROL_AUTOFD); > --- > > PARPORT_CONTROL_AUTOFD > > | PARPORT_CONTROL_STROBE, > > PARPORT_CONTROL_AUTOFD); > 1252,1253c1008,1009 > < PARPORT_CONTROL_INIT, > < 0); > --- > > PARPORT_CONTROL_INIT, > > 0); > 1256,1258c1012,1014 > < if (r) { > < printk (KERN_DEBUG "%s: PE timeout Event 40 (%d) " > < "in ecp_read_block_pio\n", port->name, r); > --- > > if (r) { > > printk (KERN_DEBUG "%s: PE timeout Event 40 (%d) " > > "in ecp_read_block_pio\n", port->name, r); > 1264,1267c1020,1023 > < /* parport_pc_frob_control (port, > < PARPORT_CONTROL_STROBE | > < PARPORT_CONTROL_AUTOFD, > < PARPORT_CONTROL_AUTOFD); */ > --- > > /* parport_pc_frob_control (port, > > PARPORT_CONTROL_STROBE | > > PARPORT_CONTROL_AUTOFD, > > PARPORT_CONTROL_AUTOFD); */ > 1274c1030 > < dump_parport_state ("pre 43", port); > --- > > dump_parport_state ("pre 43", port); > 1285c1041 > < dump_parport_state ("43-44", port); > --- > > dump_parport_state ("43-44", port); > 1288,1290c1044,1046 > < PARPORT_CONTROL_AUTOFD, > < 0); > < dump_parport_state ("pre 45", port); > --- > > PARPORT_CONTROL_AUTOFD, > > 0); > > dump_parport_state ("pre 45", port); > 1292,1294c1048,1050 > < /* r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); */ > < dump_parport_state ("post 45", port); > < r = 0; > --- > > /* r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); */ > > dump_parport_state ("post 45", port); > > r = 0; > 1304,1305c1060,1061 > < PARPORT_CONTROL_AUTOFD, > < PARPORT_CONTROL_AUTOFD); > --- > > PARPORT_CONTROL_AUTOFD, > > PARPORT_CONTROL_AUTOFD); > 1308c1064 > < dump_parport_state ("rev idle", port); > --- > > dump_parport_state ("rev idle", port); > 1320,1323c1076,1079 > < * that case ECP is already holding back the > < * peripheral (assuming proper design) with a delayed > < * handshake. Work fast to avoid a peripheral > < * timeout. */ > --- > > * that case ECP is already holding back the > > * peripheral (assuming proper design) with a delayed > > * handshake. Work fast to avoid a peripheral > > * timeout. */ > 1327c1083 > < dump_parport_state ("FIFO empty", port); > --- > > dump_parport_state ("FIFO empty", port); > 1337,1338c1093,1094 > < false_alarm: > < dump_parport_state ("waiting", port); > --- > > false_alarm: > > dump_parport_state ("waiting", port); > 1340c1096 > < DPRINTK (KERN_DEBUG "parport_wait_event returned %d\n", ret); > --- > > DPRINTK (KERN_DEBUG "parport_wait_event returned %d\n", ret); > 1346c1102 > < dump_parport_state ("timeout", port); > --- > > dump_parport_state ("timeout", port); > 1353c1109 > < time_before (jiffies, expire)) { > --- > > time_before (jiffies, expire)) { > 1360,1362c1116,1118 > < * set, how long interrupt service took, and > < * how fast the peripheral is, we might be > < * lucky and have a just filled FIFO. */ > --- > > * set, how long interrupt service took, and > > * how fast the peripheral is, we might be > > * lucky and have a just filled FIFO. */ > 1368c1124 > < dump_parport_state ("FIFO full", port); > --- > > dump_parport_state ("FIFO full", port); > 1375c1131 > < DPRINTK (KERN_DEBUG "*** ecp_read_block_pio: reading one byte from the FIFO\n"); > --- > > DPRINTK (KERN_DEBUG "*** ecp_read_block_pio: reading one byte from the FIFO\n"); > 1378,1379c1134,1135 > < * and either the peripheral will fill it faster, > < * tripping a fast empty with insb, or we empty it. */ > --- > > * and either the peripheral will fill it faster, > > * tripping a fast empty with insb, or we empty it. */ > 1391c1147 > < dump_parport_state ("rev idle2", port); > --- > > dump_parport_state ("rev idle2", port); > 1400,1401c1156,1157 > < PARPORT_STATUS_PAPEROUT, > < PARPORT_STATUS_PAPEROUT); > --- > > PARPORT_STATUS_PAPEROUT, > > PARPORT_STATUS_PAPEROUT); > 1404,1405c1160,1161 > < "%s: PE timeout FWDIDLE (%d) in ecp_read_block_pio\n", > < port->name, r); > --- > > "%s: PE timeout FWDIDLE (%d) in ecp_read_block_pio\n", > > port->name, r); > 1416c1172 > < port->name, lost); > --- > > port->name, lost); > 1419c1175 > < dump_parport_state ("fwd idle", port); > --- > > dump_parport_state ("fwd idle", port); > 2503,2504c2259 > < /* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; > < * */ > --- > > /* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; */ > 2509d2263 > < p->ops->ecp_read_data = parport_pc_fifo_read_block_dma; > 2610d2363 > < { > 2612,2613d2364 > < change_mode (p, ECR_PS2); > < } > > _______________________________________________ > cpia mailing list - cpia@risc.uni-linz.ac.at > http://mailman.risc.uni-linz.ac.at/mailman/cgi-bin/listinfo/cpia > From co2cool@yahoo.com 09 Jan 2002 02:08:25 +0000 Date: 09 Jan 2002 02:08:25 +0000 From: David Irvine co2cool@yahoo.com Subject: [cpia] Capture problems. Hello. I'm currently writing an application which captures a still image from a cpia camera, I'm using the zoom cam usb model. Its a perl script and the core of the image grabbing is as follows: use Video::Capture::V4l; use PDL; use PDL::IO::Pnm; my $grab = new Video::Capture::V4l "/dev/video1" or die "Unable to open video device: $!"; #connects to the video device my $frame = $grab->capture(0, 640, 480); #attempts to capture a frame $grab->sync(0); #waits until the frame has been captured my $img = zeroes byte, 3, 640, 480; #create an image object ${$img->get_dataref} = $fr; $img->upd_data(); #insert the raw data to the image $img = $img->slice("2:0,:,-1:0"); #rotate the bytes in the image from bgr to rgb wpnm $img, 'frame.ppm', 'PPM', 1; #write the file to disk Now the code executes properly but when i look at the file, in the gimp (or any other viewer) it is basically snow. A number of webcam software programs also do this. Do i need to set something on the camera before this will work properly? Any advice appreciated David From simon.thompson@videologic.com Thu, 24 Jan 2002 16:12:12 -0000 Date: Thu, 24 Jan 2002 16:12:12 -0000 From: Simon Thompson simon.thompson@videologic.com Subject: [cpia] stvo680b-001 ? Hi All, I got hold of a camera recently based on the STV0680-001 chip and wondered if anyone has started doing any work on getting this thing working under linux. Does anyone have any idea if this is a huge task or even possible given the datasheet and maybe modifying the existing cpia driver for the VV0670P001? Thanks, Simon From steve.miller@st.com Thu, 24 Jan 2002 09:45:07 -0500 Date: Thu, 24 Jan 2002 09:45:07 -0500 From: Steve Miller steve.miller@st.com Subject: [cpia] stvo680b-001 ? simon.thompson@videologic.com wrote: > > Hi All, > I got hold of a camera recently based on the STV0680-001 chip and wondered > if anyone has started doing any work on getting this thing working under > linux. > > Does anyone have any idea if this is a huge task or even possible given the > datasheet and maybe modifying the existing cpia driver for the VV0670P001? > > Thanks, > > Simon > The 680 has some still mode support under gphoto2. Streaming video is being worked on by Kevin Sisson. His website is http://personal.bellsouth.net/clt/k/j/kjsisson. I know he has it running fairly well with ohci usb ontrollers, less stable with uhci. You can contact him there, and if you want to help, he has all the docs you'll need. His driver is (or will be soon) in the 2.5 kernel. Steve -- Steve Miller Software Engineer STMicroelectronics phone (602) 485-2014 From jon@viperdude.org Sat, 26 Jan 2002 18:15:09 +0000 (GMT) Date: Sat, 26 Jan 2002 18:15:09 +0000 (GMT) From: Jon Farmer jon@viperdude.org Subject: [cpia] Problem compiling Hi all I am trying to compile cpia for usb on a 2.4.17 kernel, distro is Red Hat 7.2 I am getting the following compile errors. Any ideas anyone? cpia.c:3906: warning: initialization from incompatible pointer type cpia.c:3907: warning: missing braces around initializer for `cpia_template.name' cpia.c:3909: warning: initialization makes integer from pointer without a cast cpia.c:3909: initializer element for `cpia_template.name[2]' is not computable at load time cpia.c:3910: warning: initialization makes integer from pointer without a cast cpia.c:3910: initializer element for `cpia_template.name[3]' is not computable at load time cpia.c:3911: warning: initialization makes integer from pointer without a cast cpia.c:3911: initializer element for `cpia_template.name[4]' is not computable at load time cpia.c:3912: warning: initialization makes integer from pointer without a cast cpia.c:3913: warning: initialization makes integer from pointer without a cast cpia.c:3914: warning: initialization makes integer from pointer without a cast cpia.c:3914: initializer element for `cpia_template.name[7]' is not computable at load time cpia.c:3915: warning: initialization makes integer from pointer without a cast cpia.c:3915: initializer element for `cpia_template.name[8]' is not computable at load time cpia.c:3916: warning: initialization makes integer from pointer without a cast cpia.c:3916: initializer element for `cpia_template.name[9]' is not computable at load time cpia.c:3917: warning: initialization makes integer from pointer without a cast cpia.c: In function `cpia_register_camera': cpia.c:4079: too few arguments to function `video_register_device' make: *** [cpia.o] Error 1 -- Jon Farmer Telford, Shropshire, UK From f.duncan.m.haldane@att.net Mon, 28 Jan 2002 00:31:50 +0000 Date: Mon, 28 Jan 2002 00:31:50 +0000 From: f.duncan.m.haldane@att.net f.duncan.m.haldane@att.net Subject: [cpia] Problem compiling You need to patch the cvs source. The cvs is not yet patched for 2.4.17. I posted a patch for updating cpia for this a while back on this list. I guess the cvs maintainers are busy on non-cpia things these days...... You can probably find it in the archives. > Hi all > > I am trying to compile cpia for usb on a 2.4.17 kernel, distro is Red Hat > 7.2 > > I am getting the following compile errors. Any ideas anyone? >