lkml.org 
[lkml]   [2007]   [Oct]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    SubjectRe: [bug] ata subsystem related crash with latest -git
    From
    From: Jens Axboe <jens.axboe@oracle.com>
    Date: Thu, 18 Oct 2007 10:21:45 +0200

    > I like it. Basically the only real change is using bit 2 as a
    > termination point, so we avoid going beyond the end of the sgtable.
    > Here's a starting point, it actually booted for me in the first go
    > (boggle). Only x86 so far, archs will need to be converted. And lots
    > more drivers I'm sure, I only fixed up the ones that botched my compile.
    >
    > So just consider this a directional patch.

    Here are some sparc64 bits:

    diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
    index 29af777..73852a2 100644
    --- a/arch/sparc64/kernel/iommu.c
    +++ b/arch/sparc64/kernel/iommu.c
    @@ -473,7 +473,7 @@ 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)
    + (__pa(page_address(sg_page(SG))) + (SG)->offset)

    static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
    int nused, int nelems,
    @@ -566,7 +566,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
    if (nelems == 1) {
    sglist->dma_address =
    dma_4u_map_single(dev,
    - (page_address(sglist->page) +
    + (page_address(sg_page(sglist)) +
    sglist->offset),
    sglist->length, direction);
    if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
    diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
    index d7ca900..ec863e0 100644
    --- a/arch/sparc64/kernel/iommu_common.c
    +++ b/arch/sparc64/kernel/iommu_common.c
    @@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,

    daddr = dma_sg->dma_address;
    sglen = sg->length;
    - sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
    + sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
    while (dlen > 0) {
    unsigned long paddr;

    @@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
    sg = sg_next(sg);
    if (--nents <= 0)
    break;
    - sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
    + sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
    sglen = sg->length;
    }
    if (dlen < 0) {
    @@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
    printk("sg(%d): page_addr(%p) off(%x) length(%x) "
    "dma_address[%016x] dma_length[%016x]\n",
    i,
    - page_address(sg->page), sg->offset,
    + page_address(sg_page(sg)), sg->offset,
    sg->length,
    sg->dma_address, sg->dma_length);
    }
    @@ -207,15 +207,15 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
    unsigned long prev;
    u32 dent_addr, dent_len;

    - prev = (unsigned long) (page_address(sg->page) + sg->offset);
    + prev = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
    prev += (unsigned long) (dent_len = sg->length);
    - dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
    + dent_addr = (u32) ((unsigned long)(page_address(sg_page(sg)) + sg->offset)
    & (IO_PAGE_SIZE - 1UL));
    while (--nents) {
    unsigned long addr;

    sg = sg_next(sg);
    - addr = (unsigned long) (page_address(sg->page) + sg->offset);
    + addr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
    if (! VCONTIG(prev, addr)) {
    dma_sg->dma_address = dent_addr;
    dma_sg->dma_length = dent_len;
    diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
    index fe46ace..5324a34 100644
    --- a/arch/sparc64/kernel/pci_sun4v.c
    +++ b/arch/sparc64/kernel/pci_sun4v.c
    @@ -366,7 +366,7 @@ 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)
    + (__pa(page_address(sg_page(SG))) + (SG)->offset)

    static long fill_sg(long entry, struct device *dev,
    struct scatterlist *sg,
    @@ -478,7 +478,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
    if (nelems == 1) {
    sglist->dma_address =
    dma_4v_map_single(dev,
    - (page_address(sglist->page) +
    + (page_address(sg_page(sglist)) +
    sglist->offset),
    sglist->length, direction);
    if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
    diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
    index 703c5bb..6df23f0 100644
    --- a/include/asm-sparc64/scatterlist.h
    +++ b/include/asm-sparc64/scatterlist.h
    @@ -6,7 +6,10 @@
    #include <asm/types.h>

    struct scatterlist {
    - struct page *page;
    +#ifdef CONFIG_DEBUG_SG
    + unsigned long sg_magic;
    +#endif
    + unsigned long page_link;
    unsigned int offset;

    unsigned int length;
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-10-18 13:57    [W:0.028 / U:119.836 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site