Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 88049
b: refs/heads/master
c: f088025
h: refs/heads/master
i:
  88047: 79c7ea8
v: v3
  • Loading branch information
FUJITA Tomonori authored and David S. Miller committed Mar 28, 2008
1 parent a2400c6 commit bc1e6d2
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 76cc86ee6b3c261b96ea3ee2f4c6dfd127335881
refs/heads/master: f08802572965873af97e74337d5740bfa2542941
12 changes: 10 additions & 2 deletions trunk/arch/sparc64/kernel/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,9 +516,11 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
unsigned long flags, handle, prot, ctx;
dma_addr_t dma_next = 0, dma_addr;
unsigned int max_seg_size;
unsigned long seg_boundary_size;
int outcount, incount, i;
struct strbuf *strbuf;
struct iommu *iommu;
unsigned long base_shift;

BUG_ON(direction == DMA_NONE);

Expand Down Expand Up @@ -549,8 +551,11 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
outs->dma_length = 0;

max_seg_size = dma_get_max_seg_size(dev);
seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
IO_PAGE_SIZE) >> IO_PAGE_SHIFT;
base_shift = iommu->page_table_map_base >> IO_PAGE_SHIFT;
for_each_sg(sglist, s, nelems, i) {
unsigned long paddr, npages, entry, slen;
unsigned long paddr, npages, entry, out_entry = 0, slen;
iopte_t *base;

slen = s->length;
Expand Down Expand Up @@ -593,7 +598,9 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
* - allocated dma_addr isn't contiguous to previous allocation
*/
if ((dma_addr != dma_next) ||
(outs->dma_length + s->length > max_seg_size)) {
(outs->dma_length + s->length > max_seg_size) ||
(is_span_boundary(out_entry, base_shift,
seg_boundary_size, outs, s))) {
/* Can't merge: create a new segment */
segstart = s;
outcount++;
Expand All @@ -607,6 +614,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
/* This is a new segment, fill entries */
outs->dma_address = dma_addr;
outs->dma_length = slen;
out_entry = entry;
}

/* Calculate next page pointer for contiguous check */
Expand Down
13 changes: 13 additions & 0 deletions trunk/arch/sparc64/kernel/iommu_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/scatterlist.h>
#include <linux/device.h>
#include <linux/iommu-helper.h>

#include <asm/iommu.h>
#include <asm/scatterlist.h>
Expand Down Expand Up @@ -58,6 +59,18 @@ static inline unsigned long calc_npages(struct scatterlist *sglist, int nelems)
return npages;
}

static inline int is_span_boundary(unsigned long entry,
unsigned long shift,
unsigned long boundary_size,
struct scatterlist *outs,
struct scatterlist *sg)
{
unsigned long paddr = SG_ENT_PHYS_ADDRESS(outs);
int nr = iommu_num_pages(paddr, outs->dma_length + sg->length);

return iommu_is_span_boundary(entry, nr, shift, boundary_size);
}

extern unsigned long iommu_range_alloc(struct device *dev,
struct iommu *iommu,
unsigned long npages,
Expand Down
12 changes: 10 additions & 2 deletions trunk/arch/sparc64/kernel/pci_sun4v.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,10 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
unsigned long flags, handle, prot;
dma_addr_t dma_next = 0, dma_addr;
unsigned int max_seg_size;
unsigned long seg_boundary_size;
int outcount, incount, i;
struct iommu *iommu;
unsigned long base_shift;
long err;

BUG_ON(direction == DMA_NONE);
Expand All @@ -362,8 +364,11 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
iommu_batch_start(dev, prot, ~0UL);

max_seg_size = dma_get_max_seg_size(dev);
seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
IO_PAGE_SIZE) >> IO_PAGE_SHIFT;
base_shift = iommu->page_table_map_base >> IO_PAGE_SHIFT;
for_each_sg(sglist, s, nelems, i) {
unsigned long paddr, npages, entry, slen;
unsigned long paddr, npages, entry, out_entry = 0, slen;

slen = s->length;
/* Sanity check */
Expand Down Expand Up @@ -406,7 +411,9 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
* - allocated dma_addr isn't contiguous to previous allocation
*/
if ((dma_addr != dma_next) ||
(outs->dma_length + s->length > max_seg_size)) {
(outs->dma_length + s->length > max_seg_size) ||
(is_span_boundary(out_entry, base_shift,
seg_boundary_size, outs, s))) {
/* Can't merge: create a new segment */
segstart = s;
outcount++;
Expand All @@ -420,6 +427,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
/* This is a new segment, fill entries */
outs->dma_address = dma_addr;
outs->dma_length = slen;
out_entry = entry;
}

/* Calculate next page pointer for contiguous check */
Expand Down

0 comments on commit bc1e6d2

Please sign in to comment.