From 663061f50626464c9f844b84ccd1bb0644abad5d Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Tue, 7 Aug 2007 19:04:01 +0000 Subject: [PATCH] Ported allocation of mite dma rings to modern kernel dma api. --- comedi/drivers/mite.c | 20 ++++++++--------- comedi/drivers/mite.h | 46 +++++++++++++++++++++++--------------- comedi/drivers/ni_pcidio.c | 4 ++-- comedi/drivers/ni_pcimio.c | 16 ++++++------- include/linux/comedidev.h | 3 ++- 5 files changed, 49 insertions(+), 40 deletions(-) diff --git a/comedi/drivers/mite.c b/comedi/drivers/mite.c index 4f2332a5..451f6d11 100644 --- a/comedi/drivers/mite.c +++ b/comedi/drivers/mite.c @@ -316,21 +316,22 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, comedi_async *async) int i; if(ring->descriptors){ - kfree(ring->descriptors); + dma_free_coherent(ring->hw_dev, ring->n_links * sizeof(struct mite_dma_descriptor), + ring->descriptors, ring->descriptors_dma_addr); } ring->descriptors = NULL; + ring->descriptors_dma_addr = 0; ring->n_links = 0; if(async->prealloc_bufsz==0){ return 0; } - n_links = async->prealloc_bufsz >> PAGE_SHIFT; - MDPRINTK("buf=%p buf(bus)=%08lx bufsz=0x%08x n_links=0x%04x\n", - async->prealloc_buf, virt_to_bus(async->prealloc_buf), async->prealloc_bufsz, n_links); + MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links); - ring->descriptors = kmalloc(n_links * sizeof(struct mite_dma_descriptor), GFP_KERNEL); + ring->descriptors = dma_alloc_coherent(ring->hw_dev, n_links * sizeof(struct mite_dma_descriptor), + &ring->descriptors_dma_addr, GFP_KERNEL); if(!ring->descriptors){ printk("mite: ring buffer allocation failed\n"); return -ENOMEM; @@ -340,12 +341,9 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, comedi_async *async) for(i = 0; i < n_links; i++){ ring->descriptors[i].count = cpu_to_le32(PAGE_SIZE); ring->descriptors[i].addr = cpu_to_le32(async->buf_page_list[i].dma_addr); - // FIXME: virt_to_bus is deprecated - ring->descriptors[i].next = cpu_to_le32(virt_to_bus( - ring->descriptors + i + 1)); + ring->descriptors[i].next = cpu_to_le32(ring->descriptors_dma_addr + (i + 1) * sizeof(struct mite_dma_descriptor)); } - ring->descriptors[n_links - 1].next = cpu_to_le32(virt_to_bus( - ring->descriptors)); + ring->descriptors[n_links - 1].next = cpu_to_le32(ring->descriptors_dma_addr); /* barrier is meant to insure that all the writes to the dma descriptors have completed before the dma controller is commanded to read them */ smp_wmb(); @@ -433,7 +431,7 @@ void mite_prep_dma(struct mite_channel *mite_chan, writel(lkcr, mite->mite_io_addr + MITE_LKCR(mite_chan->channel)); /* starting address for link chaining */ - writel(virt_to_bus(mite_chan->ring->descriptors), + writel(mite_chan->ring->descriptors_dma_addr, mite->mite_io_addr + MITE_LKAR(mite_chan->channel)); MDPRINTK("exit mite_prep_dma\n"); diff --git a/comedi/drivers/mite.h b/comedi/drivers/mite.h index 90085f84..1f9e4d37 100644 --- a/comedi/drivers/mite.h +++ b/comedi/drivers/mite.h @@ -50,26 +50,10 @@ struct mite_dma_descriptor{ struct mite_dma_descriptor_ring { + struct device *hw_dev; unsigned int n_links; struct mite_dma_descriptor *descriptors; -}; - -static inline struct mite_dma_descriptor_ring* mite_alloc_ring(void) -{ - struct mite_dma_descriptor_ring *ring = kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL); - if(ring == NULL) return ring; - ring->n_links = 0; - ring->descriptors = NULL; - return ring; -}; - -static inline void mite_free_ring(struct mite_dma_descriptor_ring *ring) -{ - if(ring) - { - if(ring->descriptors) kfree(ring->descriptors); - kfree(ring); - } + dma_addr_t descriptors_dma_addr; }; struct mite_channel{ @@ -96,6 +80,32 @@ struct mite_struct{ spinlock_t lock; }; +static inline struct mite_dma_descriptor_ring* mite_alloc_ring(struct mite_struct *mite) +{ + struct mite_dma_descriptor_ring *ring = kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL); + if(ring == NULL) return ring; + ring->hw_dev = get_device(&mite->pcidev->dev); + if(ring->hw_dev == NULL) + { + kfree(ring); + return NULL; + } + ring->n_links = 0; + ring->descriptors = NULL; + ring->descriptors_dma_addr = 0; + return ring; +}; + +static inline void mite_free_ring(struct mite_dma_descriptor_ring *ring) +{ + if(ring) + { + if(ring->descriptors) kfree(ring->descriptors); + if(ring->hw_dev) put_device(ring->hw_dev); + kfree(ring); + } +}; + extern struct mite_struct *mite_devices; static inline unsigned int mite_irq(struct mite_struct *mite) diff --git a/comedi/drivers/ni_pcidio.c b/comedi/drivers/ni_pcidio.c index 47647b15..ab57a782 100644 --- a/comedi/drivers/ni_pcidio.c +++ b/comedi/drivers/ni_pcidio.c @@ -1105,8 +1105,6 @@ static int nidio_attach(comedi_device *dev,comedi_devconfig *it) if((ret=alloc_private(dev,sizeof(nidio96_private)))<0) return ret; - devpriv->di_mite_ring = mite_alloc_ring(); - if(devpriv->di_mite_ring == NULL) return -ENOMEM; spin_lock_init(&devpriv->mite_channel_lock); ret=nidio_find_device(dev,it->options[0],it->options[1]); @@ -1119,6 +1117,8 @@ static int nidio_attach(comedi_device *dev,comedi_devconfig *it) return ret; } comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); + devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite); + if(devpriv->di_mite_ring == NULL) return -ENOMEM; dev->board_name=this_board->name; irq=mite_irq(devpriv->mite); diff --git a/comedi/drivers/ni_pcimio.c b/comedi/drivers/ni_pcimio.c index 52463766..1d3d731b 100644 --- a/comedi/drivers/ni_pcimio.c +++ b/comedi/drivers/ni_pcimio.c @@ -1533,14 +1533,6 @@ static int pcimio_attach(comedi_device *dev,comedi_devconfig *it) ret=ni_alloc_private(dev); if(ret<0)return ret; - devpriv->ai_mite_ring = mite_alloc_ring(); - if(devpriv->ai_mite_ring == NULL) return -ENOMEM; - devpriv->ao_mite_ring = mite_alloc_ring(); - if(devpriv->ao_mite_ring == NULL) return -ENOMEM; - devpriv->gpct_mite_ring[0] = mite_alloc_ring(); - if(devpriv->gpct_mite_ring[0] == NULL) return -ENOMEM; - devpriv->gpct_mite_ring[1] = mite_alloc_ring(); - if(devpriv->gpct_mite_ring[1] == NULL) return -ENOMEM; ret=pcimio_find_device(dev,it->options[0],it->options[1]); if(ret<0)return ret; @@ -1569,6 +1561,14 @@ static int pcimio_attach(comedi_device *dev,comedi_devconfig *it) return ret; } comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); + devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite); + if(devpriv->ai_mite_ring == NULL) return -ENOMEM; + devpriv->ao_mite_ring = mite_alloc_ring(devpriv->mite); + if(devpriv->ao_mite_ring == NULL) return -ENOMEM; + devpriv->gpct_mite_ring[0] = mite_alloc_ring(devpriv->mite); + if(devpriv->gpct_mite_ring[0] == NULL) return -ENOMEM; + devpriv->gpct_mite_ring[1] = mite_alloc_ring(devpriv->mite); + if(devpriv->gpct_mite_ring[1] == NULL) return -ENOMEM; if(boardtype.reg_type & ni_reg_m_series_mask) m_series_init_eeprom_buffer(dev); diff --git a/include/linux/comedidev.h b/include/linux/comedidev.h index a85266bb..10cf384d 100644 --- a/include/linux/comedidev.h +++ b/include/linux/comedidev.h @@ -460,7 +460,8 @@ static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev) dev->hw_dev = hw_dev; if(dev->hw_dev) { - get_device(dev->hw_dev); + dev->hw_dev = get_device(dev->hw_dev); + BUG_ON(dev->hw_dev == NULL); } } -- 2.26.2