Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6257a90 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block

* 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block:
  [SCSI] Remove full sg table memset()
  [SCSI] ide-scsi: remove usage of sg_last()
  Fix loop terminating conditions in fill_sg().
  [BLOCK] Clear sg entry before filling in blk_rq_map_sg()
  IA64: iommu uses sg_next with an invalid sg element
  cciss: disable DMA refetch on Smart Array P600
  swiotlb: fix map_sg failure handling
  SPARC64: fix iommu sg chaining
  [SCSI] ide-scsi: use scsi_sg_count() instead of ->use_sg
parents c548f08a f5c0dde4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1179,7 +1179,6 @@ sba_fill_pdir(
	u64 *pdirp = NULL;
	unsigned long dma_offset = 0;

	dma_sg--;
	while (nents-- > 0) {
		int     cnt = startsg->dma_length;
		startsg->dma_length = 0;
@@ -1201,6 +1200,7 @@ sba_fill_pdir(
			u32 pide = startsg->dma_address & ~PIDE_FLAG;
			dma_offset = (unsigned long) pide & ~iovp_mask;
			startsg->dma_address = 0;
			if (n_mappings)
				dma_sg = sg_next(dma_sg);
			dma_sg->dma_address = pide | ioc->ibase;
			pdirp = &(ioc->pdir_base[pide >> iovp_shift]);
+7 −6
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/scatterlist.h>

#ifdef CONFIG_PCI
#include <linux/pci.h>
@@ -476,12 +475,11 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
#define SG_ENT_PHYS_ADDRESS(SG)	\
	(__pa(page_address((SG)->page)) + (SG)->offset)

static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
		    int nused, int nelems,
		    unsigned long iopte_protection)
{
	struct scatterlist *dma_sg = sg;
	struct scatterlist *sg_end = sg_last(sg, nelems);
	int i;

	for (i = 0; i < nused; i++) {
@@ -517,6 +515,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
					break;
				}
				sg = sg_next(sg);
				nelems--;
			}

			pteval = iopte_protection | (pteval & IOPTE_PAGE);
@@ -530,18 +529,20 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,

			pteval = (pteval & IOPTE_PAGE) + len;
			sg = sg_next(sg);
			nelems--;

			/* Skip over any tail mappings we've fully mapped,
			 * adjusting pteval along the way.  Stop when we
			 * detect a page crossing event.
			 */
			while (sg != sg_end &&
			while (nelems &&
			       (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
			       (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
			       ((pteval ^
				 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
				pteval += sg->length;
				sg = sg_next(sg);
				nelems--;
			}
			if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
				pteval = ~0UL;
+30 −21
Original line number Diff line number Diff line
@@ -12,18 +12,22 @@
 */

#ifdef VERIFY_SG
static int verify_lengths(struct scatterlist *sg, int nents, int npages)
static int verify_lengths(struct scatterlist *sglist, int nents, int npages)
{
	int sg_len, dma_len;
	int i, pgcount;
	struct scatterlist *sg;

	sg_len = 0;
	for (i = 0; i < nents; i++)
		sg_len += sg[i].length;
	for_each_sg(sglist, sg, nents, i)
		sg_len += sg->length;

	dma_len = 0;
	for (i = 0; i < nents && sg[i].dma_length; i++)
		dma_len += sg[i].dma_length;
	for_each_sg(sglist, sg, nents, i) {
		if (!sg->dma_length)
			break;
		dma_len += sg->dma_length;
	}

	if (sg_len != dma_len) {
		printk("verify_lengths: Error, different, sg[%d] dma[%d]\n",
@@ -32,13 +36,16 @@ static int verify_lengths(struct scatterlist *sg, int nents, int npages)
	}

	pgcount = 0;
	for (i = 0; i < nents && sg[i].dma_length; i++) {
	for_each_sg(sglist, sg, nents, i) {
		unsigned long start, end;

		start = sg[i].dma_address;
		if (!sg->dma_length)
			break;

		start = sg->dma_address;
		start = start & IO_PAGE_MASK;

		end = sg[i].dma_address + sg[i].dma_length;
		end = sg->dma_address + sg->dma_length;
		end = (end + (IO_PAGE_SIZE - 1)) & IO_PAGE_MASK;

		pgcount += ((end - start) >> IO_PAGE_SHIFT);
@@ -113,7 +120,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
		if (dlen > 0 && ((daddr & ~IO_PAGE_MASK) == 0))
			iopte++;

		sg++;
		sg = sg_next(sg);
		if (--nents <= 0)
			break;
		sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
@@ -147,7 +154,7 @@ static int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte)
		nents = verify_one_map(dma_sg, &sg, nents, &iopte);
		if (nents <= 0)
			break;
		dma_sg++;
		dma_sg = sg_next(dma_sg);
		if (dma_sg->dma_length == 0)
			break;
	}
@@ -169,22 +176,24 @@ static int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte)
	return 0;
}

void verify_sglist(struct scatterlist *sg, int nents, iopte_t *iopte, int npages)
void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int npages)
{
	if (verify_lengths(sg, nents, npages) < 0 ||
	    verify_maps(sg, nents, iopte) < 0) {
	struct scatterlist *sg;

	if (verify_lengths(sglist, nents, npages) < 0 ||
	    verify_maps(sglist, nents, iopte) < 0) {
		int i;

		printk("verify_sglist: Crap, messed up mappings, dumping, iodma at ");
		printk("%016lx.\n", sg->dma_address & IO_PAGE_MASK);
		printk("%016lx.\n", sglist->dma_address & IO_PAGE_MASK);

		for (i = 0; i < nents; i++) {
		for_each_sg(sglist, sg, nents, i) {
			printk("sg(%d): page_addr(%p) off(%x) length(%x) "
			       "dma_address[%016lx] dma_length[%016lx]\n",
			       "dma_address[%016x] dma_length[%016x]\n",
			       i,
			       page_address(sg[i].page), sg[i].offset,
			       sg[i].length,
			       sg[i].dma_address, sg[i].dma_length);
			       page_address(sg->page), sg->offset,
			       sg->length,
			       sg->dma_address, sg->dma_length);
		}
	}

@@ -205,12 +214,12 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
	while (--nents) {
		unsigned long addr;

		sg++;
		sg = sg_next(sg);
		addr = (unsigned long) (page_address(sg->page) + sg->offset);
		if (! VCONTIG(prev, addr)) {
			dma_sg->dma_address = dent_addr;
			dma_sg->dma_length = dent_len;
			dma_sg++;
			dma_sg = sg_next(dma_sg);

			dent_addr = ((dent_addr +
				      dent_len +
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/scatterlist.h>

#include <asm/iommu.h>
#include <asm/scatterlist.h>
+8 −8
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@
#include <linux/irq.h>
#include <linux/msi.h>
#include <linux/log2.h>
#include <linux/scatterlist.h>

#include <asm/iommu.h>
#include <asm/irq.h>
@@ -369,12 +368,11 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
#define SG_ENT_PHYS_ADDRESS(SG)	\
	(__pa(page_address((SG)->page)) + (SG)->offset)

static inline long fill_sg(long entry, struct device *dev,
static long fill_sg(long entry, struct device *dev,
		    struct scatterlist *sg,
		    int nused, int nelems, unsigned long prot)
{
	struct scatterlist *dma_sg = sg;
	struct scatterlist *sg_end = sg_last(sg, nelems);
	unsigned long flags;
	int i;

@@ -415,6 +413,7 @@ static inline long fill_sg(long entry, struct device *dev,
					break;
				}
				sg = sg_next(sg);
				nelems--;
			}

			pteval = (pteval & IOPTE_PAGE);
@@ -433,19 +432,20 @@ static inline long fill_sg(long entry, struct device *dev,

			pteval = (pteval & IOPTE_PAGE) + len;
			sg = sg_next(sg);
			nelems--;

			/* Skip over any tail mappings we've fully mapped,
			 * adjusting pteval along the way.  Stop when we
			 * detect a page crossing event.
			 */
			while ((pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
			while (nelems &&
			       (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
			       (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
			       ((pteval ^
				 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
				pteval += sg->length;
				if (sg == sg_end)
					break;
				sg = sg_next(sg);
				nelems--;
			}
			if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
				pteval = ~0UL;
Loading