On 26 февраля 2009, "Igor M. Liplianin" <liplianin@xxxxxx> wrote:> On Thu, 19 Feb 2009 07:18:47 +0200>> "Igor M. Liplianin" <liplianin@xxxxxx> 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 majordomo@xxxxxxxxxxxxxxx> More majordomo info at http://vger.kernel.org/majordomo-info.htmlToday 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 RegardsIgorЪТХ╨{.nг+┴╥÷╝┴╜├+%┼кЪ╠Ищ╤╔┼wЪ╨{.nг+┴╥╔┼{╠Чg²┴╞Б·ь^n┤r║Ж╕zк│Кh≥╗Х╜з&ёШЮz©Дz╧ч≈З+─й+zfё╒╥h ┬╖~├╜├шiЪЪО│ЙЪ▒ЙГz_Х╝Фj:+v┴╗Ч)ъёЬm