On 26 февраля 2009, "Igor M. Liplianin" <liplia...@tut.by> wrote: > On Thu, 19 Feb 2009 07:18:47 +0200 > > "Igor M. Liplianin" <liplia...@tut.by> 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, (0x0000f8 << > > 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) { > > б═б═б═б═б═б═б═б═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->PacketErrorCoun > >t++; -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═/* 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; > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═spin_unloc > >k(&dm1105dvb->lock); > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═return > > IRQ_HANDLED; -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═} > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═} > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═if (nextwrp < oldwrp) { > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═piece = > > dm1105dvb->buffer_size - oldwrp; > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═memcpy(dm1105dvb->ts_buf + > > dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp); > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═nbpackets = (piece + > > nextwrp)/188; -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═} elseб═б═{ > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═nbpackets = (nextwrp - > > oldwrp)/188; -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═} > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═dvb_dmx_swfilter_packets(&dm1105dvb->demux > >, &dm1105dvb->ts_buf[oldwrp], nbpackets); > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═dm1105dvb->wrp = nextwrp; > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═spin_unlock(&dm1105dvb->lock); > > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═dm1105dvb->nextwrp = > > inl(dm_io_mem(DM1105_WRP)) - > > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═ > >б═б═б═inl(dm_io_mem(DM1105_STADR)); > > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═schedule_work(&dm1105dvb->work); > > б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═break; > > б═б═б═б═б═б═б═б═case INTSTS_IR: > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═command = inl(dm_io_mem(DM1105_IRCODE)); > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═if (ir_debug) > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═printk("dm1105: received > > byte 0x%04x\n", command); - > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═dm1105dvb->ir.ir_command = command; > > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═dm1105dvb->ir.ir_command = > > inl(dm_io_mem(DM1105_IRCODE)); > > б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═tasklet_schedule(&dm1105dvb->ir.ir_taskle > >t); б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═break; > > б═б═б═б═б═б═б═б═} > > + > > б═б═б═б═б═б═б═б═return IRQ_HANDLED; > > - > > - > > б═} > > б═ > > б═/* register with input layer */ > > @@ -717,7 +732,7 @@ > > б═ > > б═б═б═б═б═б═б═б═dm1105dvb = kzalloc(sizeof(struct dm1105dvb), > > GFP_KERNEL); б═б═б═б═б═б═б═б═if (!dm1105dvb) > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═goto out; > > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═return -ENOMEM; > > б═ > > б═б═б═б═б═б═б═б═dm1105dvb->pdev = pdev; > > б═б═б═б═б═б═б═б═dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; > > @@ -747,13 +762,9 @@ > > б═б═б═б═б═б═б═б═spin_lock_init(&dm1105dvb->lock); > > б═б═б═б═б═б═б═б═pci_set_drvdata(pdev, dm1105dvb); > > б═ > > -б═б═б═б═б═б═б═ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, > > DRIVER_NAME, dm1105dvb); +б═б═б═б═б═б═б═ret = > > dm1105dvb_hw_init(dm1105dvb); > > б═б═б═б═б═б═б═б═if (ret < 0) > > б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═goto err_pci_iounmap; > > - > > -б═б═б═б═б═б═б═ret = dm1105dvb_hw_init(dm1105dvb); > > -б═б═б═б═б═б═б═if (ret < 0) > > -б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═goto err_free_irq; > > б═ > > б═б═б═б═б═б═б═б═/* i2c */ > > б═б═б═б═б═б═б═б═i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb); > > @@ -820,8 +831,19 @@ > > б═ > > б═б═б═б═б═б═б═б═dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx); > > б═б═б═б═б═б═б═б═dm1105_ir_init(dm1105dvb); > > -out: > > -б═б═б═б═б═б═б═return ret; > > + > > +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) > > +б═б═б═б═б═б═б═INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer, dm1105dvb); > > +#else > > +б═б═б═б═б═б═б═INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); > > +#endif > > + > > +б═б═б═б═б═б═б═ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, > > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═ > >б═б═б═б═б═б═б═б═б═б═б═DRIVER_NAME, dm1105dvb); +б═б═б═б═б═б═б═if (ret < 0) > > +б═б═б═б═б═б═б═б═б═б═б═б═б═б═б═goto err_free_irq; > > + > > +б═б═б═б═б═б═б═return 0; > > б═ > > б═err_disconnect_frontend: > > б═б═б═б═б═б═б═б═dmx->disconnect_frontend(dmx); > > @@ -850,7 +872,7 @@ > > б═err_kfree: > > б═б═б═б═б═б═б═б═pci_set_drvdata(pdev, NULL); > > б═б═б═б═б═б═б═б═kfree(dm1105dvb); > > -б═б═б═б═б═б═б═goto out; > > +б═б═б═б═б═б═б═return ret; > > б═} > > б═ > > б═static void __devexit dm1105_remove(struct pci_dev *pdev) > > [Erro ao decodificar BASE64] > > Cheers, > Mauro > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html Today morning I sent pull request for that patch together with patch for infrared remote. I am testing IR support for a few more cards. They will share IR codes, so that patch is needed.
Best Regards Igor N▀╖╡ФЛr╦⌡yЗХ ьb╡X╛╤г╖vь^√)ч╨{.nг+┴╥╔┼{╠≥Гbj)М┘ФХw*jg╛╠╗╤┴ ▌┼щ╒j/│ЙДz╧ч√┼Ю2┼ч≥╗Х╜з&╒)ъ║╚a╤зЧЬ╝G╚²Иh╝Фj:+v┴╗┼wХ├ы╔