Page MenuHomeFreeBSD

D20097.id56861.diff
No OneTemporary

D20097.id56861.diff

Index: sys/compat/linuxkpi/common/include/linux/scatterlist.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/scatterlist.h
+++ sys/compat/linuxkpi/common/include/linux/scatterlist.h
@@ -44,7 +44,6 @@
unsigned int offset;
unsigned int length;
dma_addr_t dma_address;
- unsigned int dma_length;
};
CTASSERT((sizeof(struct scatterlist) & SG_PAGE_LINK_MASK) == 0);
@@ -79,7 +78,7 @@
((struct scatterlist *) ((sg)->page_link & ~SG_PAGE_LINK_MASK))
#define sg_dma_address(sg) (sg)->dma_address
-#define sg_dma_len(sg) (sg)->dma_length
+#define sg_dma_len(sg) (sg)->length
#define for_each_sg_page(sgl, iter, nents, pgoffset) \
for (_sg_iter_init(sgl, iter, nents, pgoffset); \
Index: sys/compat/linuxkpi/common/src/linux_pci.c
===================================================================
--- sys/compat/linuxkpi/common/src/linux_pci.c
+++ sys/compat/linuxkpi/common/src/linux_pci.c
@@ -492,6 +492,7 @@
{
struct linux_dma_priv *priv;
struct linux_dma_obj *obj;
+ struct linux_dma_obj *old;
int error, nseg;
bus_dma_segment_t seg;
@@ -518,6 +519,16 @@
KASSERT(++nseg == 1, ("More than one segment (nseg=%d)", nseg));
obj->dma_addr = seg.ds_addr;
+ /* check if there is an existing mapping and remove it */
+ old = LINUX_DMA_PCTRIE_LOOKUP(&priv->ptree, obj->dma_addr);
+ if (obj != NULL) {
+ LINUX_DMA_PCTRIE_REMOVE(&priv->ptree, obj->dma_addr);
+ bus_dmamap_unload(priv->dmat, old->dmamap);
+ bus_dmamap_destroy(priv->dmat, old->dmamap);
+ uma_zfree(linux_dma_obj_zone, old);
+ }
+
+ /* insert new mapping */
error = LINUX_DMA_PCTRIE_INSERT(&priv->ptree, obj);
if (error != 0) {
bus_dmamap_unload(priv->dmat, obj->dmamap);
@@ -558,10 +569,9 @@
{
struct linux_dma_priv *priv;
struct linux_dma_obj *obj;
- struct scatterlist *dma_sg, *sg;
- int dma_nents, error, nseg;
- size_t seg_len;
- vm_paddr_t seg_phys, prev_phys_end;
+ struct linux_dma_obj *old;
+ struct scatterlist *sg;
+ int error, i, nseg;
bus_dma_segment_t seg;
priv = dev->dma_priv;
@@ -575,24 +585,10 @@
return (0);
}
- sg = sgl;
- dma_sg = sg;
- dma_nents = 0;
-
- while (nents > 0) {
- seg_phys = sg_phys(sg);
- seg_len = sg->length;
- while (--nents > 0) {
- prev_phys_end = sg_phys(sg) + sg->length;
- sg = sg_next(sg);
- if (prev_phys_end != sg_phys(sg))
- break;
- seg_len += sg->length;
- }
-
+ for_each_sg(sgl, sg, nents, i) {
nseg = -1;
if (_bus_dmamap_load_phys(priv->dmat, obj->dmamap,
- seg_phys, seg_len, BUS_DMA_NOWAIT,
+ sg_phys(sg), sg->length, BUS_DMA_NOWAIT,
&seg, &nseg) != 0) {
bus_dmamap_unload(priv->dmat, obj->dmamap);
bus_dmamap_destroy(priv->dmat, obj->dmamap);
@@ -601,16 +597,21 @@
return (0);
}
KASSERT(++nseg == 1, ("More than one segment (nseg=%d)", nseg));
+ sg_dma_address(sg) = seg.ds_addr;
+ }
- sg_dma_address(dma_sg) = seg.ds_addr;
- sg_dma_len(dma_sg) = seg.ds_len;
+ obj->dma_addr = sg_dma_address(sgl);
- dma_sg = sg_next(dma_sg);
- dma_nents++;
- }
+ /* check if there is an existing mapping and remove it */
+ old = LINUX_DMA_PCTRIE_LOOKUP(&priv->ptree, obj->dma_addr);
+ if (obj != NULL) {
+ LINUX_DMA_PCTRIE_REMOVE(&priv->ptree, obj->dma_addr);
+ bus_dmamap_unload(priv->dmat, old->dmamap);
+ bus_dmamap_destroy(priv->dmat, old->dmamap);
+ uma_zfree(linux_dma_obj_zone, old);
+ }
- obj->dma_addr = sg_dma_address(sgl);
-
+ /* insert new mapping */
error = LINUX_DMA_PCTRIE_INSERT(&priv->ptree, obj);
if (error != 0) {
bus_dmamap_unload(priv->dmat, obj->dmamap);
@@ -620,7 +621,7 @@
return (0);
}
DMA_PRIV_UNLOCK(priv);
- return (dma_nents);
+ return (nents);
}
void

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 20, 10:12 PM (4 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25709059
Default Alt Text
D20097.id56861.diff (3 KB)

Event Timeline