lkml.org 
[lkml]   [2007]   [Dec]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH] sata_nv: fix ADMA ATAPI issues with memory over 4GB (v3)
    Please apply the attached patch and try to use cdrom w/o specifying any
    parameter and report kernel log.

    Thanks.

    --
    tejun
    diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
    index 4753a18..acaa8b8 100644
    --- a/drivers/ata/libata-core.c
    +++ b/drivers/ata/libata-core.c
    @@ -4537,6 +4537,10 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
    * Note h/w doesn't support 64-bit, so we unconditionally
    * truncate dma_addr_t to u32.
    */
    + if (sg_dma_address(sg) & ~DMA_BIT_MASK(32))
    + ata_dev_printk(qc->dev, KERN_WARNING,
    + "XXX DMA address %llx is above 32bit\n",
    + sg_dma_address(sg));
    addr = (u32) sg_dma_address(sg);
    sg_len = sg_dma_len(sg);

    @@ -6628,6 +6632,10 @@ int ata_port_start(struct ata_port *ap)
    if (rc)
    return rc;

    + ata_port_printk(ap, KERN_INFO, "XXX: prd %p/%llx pad %p/%llx\n",
    + ap->prd, (unsigned long long)ap->prd_dma,
    + ap->pad, (unsigned long long)ap->pad_dma);
    +
    DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd,
    (unsigned long long)ap->prd_dma);
    return 0;
    diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
    index ed5dc7c..c55d2ae 100644
    --- a/drivers/ata/sata_nv.c
    +++ b/drivers/ata/sata_nv.c
    @@ -247,6 +247,7 @@ struct nv_adma_port_priv {
    void __iomem *ctl_block;
    void __iomem *gen_block;
    void __iomem *notifier_clear_block;
    + u64 adma_dma_mask;
    u8 flags;
    int last_issue_ncq;
    };
    @@ -748,7 +749,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
    adma_enable = 0;
    nv_adma_register_mode(ap);
    } else {
    - bounce_limit = *ap->dev->dma_mask;
    + bounce_limit = pp->adma_dma_mask;
    segment_boundary = NV_ADMA_DMA_BOUNDARY;
    sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN;
    adma_enable = 1;
    @@ -1134,10 +1135,20 @@ static int nv_adma_port_start(struct ata_port *ap)
    void *mem;
    dma_addr_t mem_dma;
    void __iomem *mmio;
    + struct pci_dev *pdev = to_pci_dev(dev);
    u16 tmp;

    VPRINTK("ENTER\n");

    + /* Ensure DMA mask is set to 32-bit before allocating legacy PRD and
    + pad buffers */
    + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
    + if (rc)
    + return rc;
    + rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
    + if (rc)
    + return rc;
    +
    rc = ata_port_start(ap);
    if (rc)
    return rc;
    @@ -1153,6 +1164,15 @@ static int nv_adma_port_start(struct ata_port *ap)
    pp->notifier_clear_block = pp->gen_block +
    NV_ADMA_NOTIFIER_CLEAR + (4 * ap->port_no);

    + /* Now that the legacy PRD and padding buffer are allocated we can
    + safely raise the DMA mask to allocate the CPB/APRD table.
    + These are allowed to fail since we store the value that ends up
    + being used to set as the bounce limit in slave_config later if
    + needed. */
    + pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
    + pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
    + pp->adma_dma_mask = *dev->dma_mask;
    +
    mem = dmam_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ,
    &mem_dma, GFP_KERNEL);
    if (!mem)
    @@ -2418,12 +2438,6 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
    hpriv->type = type;
    host->private_data = hpriv;

    - /* set 64bit dma masks, may fail */
    - if (type == ADMA) {
    - if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0)
    - pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
    - }
    -
    /* request and iomap NV_MMIO_BAR */
    rc = pcim_iomap_regions(pdev, 1 << NV_MMIO_BAR, DRV_NAME);
    if (rc)
    diff --git a/include/linux/libata.h b/include/linux/libata.h
    \
     
     \ /
      Last update: 2007-12-18 04:55    [W:0.052 / U:0.164 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site