Re: dm1105: not demuxing from interrupt context

2009-02-26 Thread Igor M. Liplianin
On 26 февраля 2009, "Igor M. Liplianin"  wrote:
> On Thu, 19 Feb 2009 07:18:47 +0200
>
> "Igor M. Liplianin"  wrote:
> > I read in mailing list about design error in dm1105.
> > So I am designer.
> > DMA buffer in the driver itself organized like ringbuffer
> > and not difficult to bind it to tasklet or work queue.
> > I choose work queue, because it is like trend :)
> > The code tested by me on quite fast computer and it works as usual.
> > I think, on slow computer difference must be noticeable.
> > The patch is preliminary.
> > Anyone can criticize.
>
> The patch looks fine for me, but, as you said this i preliminary, I'm
> marking it as RFC on patchwork. Please send me the final revision of it,
> after having a final version.
>
> Cheers,
> Mauro.
>
> > diff -r 359d95e1d541 -r f22da8d6a83c
> > linux/drivers/media/dvb/dm1105/dm1105.c ---
> > a/linux/drivers/media/dvb/dm1105/dm1105.cб═б═б═Wed Feb 18 09:49:37 2009
> > -0300 +++ b/linux/drivers/media/dvb/dm1105/dm1105.cб═б═б═Thu Feb 19
> > 04:38:32 2009 +0200 @@ -220,10 +220,14 @@
> > б═б═б═б═б═б═б═б═/* i2c */
> > б═б═б═б═б═б═б═б═struct i2c_adapter i2c_adap;
> > б═
> > +б═б═б═б═б═б═б═/* irq */
> > +б═б═б═б═б═б═б═struct work_struct work;
> > +
> > б═б═б═б═б═б═б═б═/* dma */
> > б═б═б═б═б═б═б═б═dma_addr_t dma_addr;
> > б═б═б═б═б═б═б═б═unsigned char *ts_buf;
> > б═б═б═б═б═б═б═б═u32 wrp;
> > +б═б═б═б═б═б═б═u32 nextwrp;
> > б═б═б═б═б═б═б═б═u32 buffer_size;
> > б═б═б═б═б═б═б═б═unsigned intб═б═б═б═PacketErrorCount;
> > б═б═б═б═б═б═б═б═unsigned int dmarst;
> > @@ -418,6 +422,9 @@
> > б═б═б═б═б═б═б═б═u8 data;
> > б═б═б═б═б═б═б═б═u16 keycode;
> > б═
> > +б═б═б═б═б═б═б═if (ir_debug)
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═printk(KERN_INFO "%s: received byte
> > 0x%04x\n", __func__, ircom); +
> > б═б═б═б═б═б═б═б═data = (ircom >> 8) & 0x7f;
> > б═
> > б═б═б═б═б═б═б═б═input_event(ir->input_dev, EV_MSC, MSC_RAW, (0xf8 <<
> > 16) | data); @@ -434,6 +441,50 @@
> > б═
> > б═}
> > б═
> > +/* work handler */
> > +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
> > +static void dm1105_dmx_buffer(void *_dm1105dvb)
> > +#else
> > +static void dm1105_dmx_buffer(struct work_struct *work)
> > +#endif
> > +{
> > +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
> > +б═б═б═б═б═б═б═struct dm1105dvb *dm1105dvb = _dm1105dvb;
> > +#else
> > +б═б═б═б═б═б═б═struct dm1105dvb *dm1105dvb =
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═container_
> >of(work, struct dm1105dvb, work); +#endif
> > +б═б═б═б═б═б═б═unsigned int nbpackets;
> > +б═б═б═б═б═б═б═u32 oldwrp = dm1105dvb->wrp;
> > +б═б═б═б═б═б═б═u32 nextwrp = dm1105dvb->nextwrp;
> > +
> > +б═б═б═б═б═б═б═if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═(dm1105dvb->ts_buf[oldwrp
> > + 188] == 0x47) &&
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═(dm1105dvb->ts_buf[oldwrp
> > + 188 * 2] == 0x47))) {
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═dm1105dvb->PacketErrorCount++;
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═/* bad packet found */
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═if ((dm1105dvb->PacketErrorCount >= 2) &&
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═(dm1105dvb
> >->dmarst == 0)) { +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═outb(1,
> > dm_io_mem(DM1105_RST));
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═dm1105dvb->wrp = 0;
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═dm1105dvb->PacketErrorCoun
> >t = 0; +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═dm1105dvb->dmarst =
> > 0; +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═return;
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═}
> > +б═б═б═б═б═б═б═}
> > +
> > +б═б═б═б═б═б═б═if (nextwrp < oldwrp) {
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═memcpy(dm1105dvb->ts_buf +
> > dm1105dvb->buffer_size,
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═
> >б═б═б═б═б═б═б═б═б═б═б═dm1105dvb->ts_buf, nextwrp);
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═nbpackets = ((dm1105dvb->buffer_size -
> > oldwrp) + nextwrp) / 188; +б═б═б═б═б═б═б═} else
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═nbpackets = (nextwrp - oldwrp) / 188;
> > +
> > +б═б═б═б═б═б═б═dm1105dvb->wrp = nextwrp;
> > +б═б═б═б═б═б═б═dvb_dmx_swfilter_packets(&dm1105dvb->demux,
> > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═
> >б═б═б═&dm1105dvb->ts_buf[oldwrp], nbpackets); +}
> > +
> > б═#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
> > б═static irqreturn_t dm1105dvb_irq(int irq, void *dev_id, struct pt_regs
> > *regs) б═#else
> > @@ -441,11 +492,6 @@
> > б═#endif
> > б═{
> > б═б═б═б═б═б═б═б═struct dm1105dvb *dm1105dvb = dev_id;
> > -б═б═б═б═б═б═б═unsigned int piece;
> > -б═б═б═б═б═б═б═unsigned int nbpackets;
> > -б═б═б═б═б═б═б═u32 command;
> > -б═б═б═б═б═б═б═u32 nextwrp;
> > -б═б═б═б═б═б═б═u32 oldwrp;
> > б═
> > б═б═б═б═б═б═б═б═/* Read-Write INSTS Ack's Interrupt for DM1105 chip
> > 16.03.2008 */ б═б═б═б═б═б═б═б═unsigned int intsts =
> > inb(dm_io_mem(DM1105_INTSTS)); @@ -454,48 +500,17 @@
> > б═б═б═б═б═б═б═б═switch (intsts) {

Re: dm1105: not demuxing from interrupt context

2009-02-26 Thread Mauro Carvalho Chehab
On Thu, 19 Feb 2009 07:18:47 +0200
"Igor M. Liplianin"  wrote:

> I read in mailing list about design error in dm1105.
> So I am designer.
> DMA buffer in the driver itself organized like ringbuffer
> and not difficult to bind it to tasklet or work queue.
> I choose work queue, because it is like trend :)
> The code tested by me on quite fast computer and it works as usual.
> I think, on slow computer difference must be noticeable.
> The patch is preliminary.
> Anyone can criticize.

The patch looks fine for me, but, as you said this i preliminary, I'm marking
it as RFC on patchwork. Please send me the final revision of it, after having a
final version.

Cheers,
Mauro.
> 
> diff -r 359d95e1d541 -r f22da8d6a83c linux/drivers/media/dvb/dm1105/dm1105.c
> --- a/linux/drivers/media/dvb/dm1105/dm1105.c   Wed Feb 18 09:49:37 2009 -0300
> +++ b/linux/drivers/media/dvb/dm1105/dm1105.c   Thu Feb 19 04:38:32 2009 +0200
> @@ -220,10 +220,14 @@
> /* i2c */
> struct i2c_adapter i2c_adap;
>  
> +   /* irq */
> +   struct work_struct work;
> +
> /* dma */
> dma_addr_t dma_addr;
> unsigned char *ts_buf;
> u32 wrp;
> +   u32 nextwrp;
> u32 buffer_size;
> unsigned intPacketErrorCount;
> unsigned int dmarst;
> @@ -418,6 +422,9 @@
> u8 data;
> u16 keycode;
>  
> +   if (ir_debug)
> +   printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, 
> ircom);
> +
> data = (ircom >> 8) & 0x7f;
>  
> input_event(ir->input_dev, EV_MSC, MSC_RAW, (0xf8 << 16) | data);
> @@ -434,6 +441,50 @@
>  
>  }
>  
> +/* work handler */
> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
> +static void dm1105_dmx_buffer(void *_dm1105dvb)
> +#else
> +static void dm1105_dmx_buffer(struct work_struct *work)
> +#endif
> +{
> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
> +   struct dm1105dvb *dm1105dvb = _dm1105dvb;
> +#else
> +   struct dm1105dvb *dm1105dvb =
> +   container_of(work, struct dm1105dvb, work);
> +#endif
> +   unsigned int nbpackets;
> +   u32 oldwrp = dm1105dvb->wrp;
> +   u32 nextwrp = dm1105dvb->nextwrp;
> +
> +   if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
> +   (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
> +   (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) {
> +   dm1105dvb->PacketErrorCount++;
> +   /* bad packet found */
> +   if ((dm1105dvb->PacketErrorCount >= 2) &&
> +   (dm1105dvb->dmarst == 0)) {
> +   outb(1, dm_io_mem(DM1105_RST));
> +   dm1105dvb->wrp = 0;
> +   dm1105dvb->PacketErrorCount = 0;
> +   dm1105dvb->dmarst = 0;
> +   return;
> +   }
> +   }
> +
> +   if (nextwrp < oldwrp) {
> +   memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size,
> +   dm1105dvb->ts_buf, nextwrp);
> +   nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 
> 188;
> +   } else
> +   nbpackets = (nextwrp - oldwrp) / 188;
> +
> +   dm1105dvb->wrp = nextwrp;
> +   dvb_dmx_swfilter_packets(&dm1105dvb->demux,
> +   &dm1105dvb->ts_buf[oldwrp], 
> nbpackets);
> +}
> +
>  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
>  static irqreturn_t dm1105dvb_irq(int irq, void *dev_id, struct pt_regs *regs)
>  #else
> @@ -441,11 +492,6 @@
>  #endif
>  {
> struct dm1105dvb *dm1105dvb = dev_id;
> -   unsigned int piece;
> -   unsigned int nbpackets;
> -   u32 command;
> -   u32 nextwrp;
> -   u32 oldwrp;
>  
> /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */
> unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS));
> @@ -454,48 +500,17 @@
> switch (intsts) {
> case INTSTS_TSIRQ:
> case (INTSTS_TSIRQ | INTSTS_IR):
> -   nextwrp = inl(dm_io_mem(DM1105_WRP)) -
> -   inl(dm_io_mem(DM1105_STADR)) ;
> -   oldwrp = dm1105dvb->wrp;
> -   spin_lock(&dm1105dvb->lock);
> -   if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
> -   (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
> -   (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 
> 0x47))) {
> -   dm1105dvb->PacketErrorCount++;
> -   /* bad packet found */
> -   if ((dm1105dvb->PacketErrorCount >= 2) &&
> -   (dm1105dvb->dmarst == 0)) {
> -   outb(1, dm_io_mem(DM1105_RST));
> -   dm1105dvb->wrp = 0;
> -   dm1105dvb->PacketErrorCount = 0;
> -   dm1105dvb->dmarst = 0;
> -