lkml.org 
[lkml]   [2006]   [Jan]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 5/8] block: convert libata to use blk_kmap helpers
    Date
    From
    Convert direct uses of kmap/unmap to blk_kmap/unmap in libata.  This
    combined with the previous bio helper change fixes PIO cache coherency
    bugs on architectures with aliased caches.

    Signed-off-by: Tejun Heo <htejun@gmail.com>

    ---

    drivers/scsi/libata-core.c | 24 +++++++++++++++---------
    drivers/scsi/libata-scsi.c | 5 +++--
    2 files changed, 18 insertions(+), 11 deletions(-)

    c1a1417612a1dc346baf783904d716c2e1d5f223
    diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
    index f55b9b3..877a33c 100644
    --- a/drivers/scsi/libata-core.c
    +++ b/drivers/scsi/libata-core.c
    @@ -2491,9 +2491,10 @@ static void ata_sg_clean(struct ata_queu
    sg[qc->orig_n_elem - 1].length += qc->pad_len;
    if (pad_buf) {
    struct scatterlist *psg = &qc->pad_sgent;
    - void *addr = kmap_atomic(psg->page, KM_IRQ0);
    + void *addr = blk_kmap_atomic(psg->page, KM_IRQ0,
    + DMA_FROM_DEVICE);
    memcpy(addr + psg->offset, pad_buf, qc->pad_len);
    - kunmap_atomic(addr, KM_IRQ0);
    + blk_kunmap_atomic(addr, KM_IRQ0, DMA_FROM_DEVICE);
    }
    } else {
    if (sg_dma_len(&sg[0]) > 0)
    @@ -2765,9 +2766,10 @@ static int ata_sg_setup(struct ata_queue
    psg->offset = offset_in_page(offset);

    if (qc->tf.flags & ATA_TFLAG_WRITE) {
    - void *addr = kmap_atomic(psg->page, KM_IRQ0);
    + void *addr = blk_kmap_atomic(psg->page, KM_IRQ0,
    + DMA_TO_DEVICE);
    memcpy(pad_buf, addr + psg->offset, qc->pad_len);
    - kunmap_atomic(addr, KM_IRQ0);
    + blk_kunmap_atomic(addr, KM_IRQ0, DMA_TO_DEVICE);
    }

    sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
    @@ -3077,6 +3079,7 @@ static void ata_pio_sector(struct ata_qu
    int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
    struct scatterlist *sg = qc->__sg;
    struct ata_port *ap = qc->ap;
    + enum dma_data_direction dir;
    struct page *page;
    unsigned int offset;
    unsigned char *buf;
    @@ -3084,6 +3087,7 @@ static void ata_pio_sector(struct ata_qu
    if (qc->cursect == (qc->nsect - 1))
    ap->hsm_task_state = HSM_ST_LAST;

    + dir = do_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
    page = sg[qc->cursg].page;
    offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;

    @@ -3091,7 +3095,7 @@ static void ata_pio_sector(struct ata_qu
    page = nth_page(page, (offset >> PAGE_SHIFT));
    offset %= PAGE_SIZE;

    - buf = kmap(page) + offset;
    + buf = blk_kmap(page, dir) + offset;

    qc->cursect++;
    qc->cursg_ofs++;
    @@ -3104,10 +3108,9 @@ static void ata_pio_sector(struct ata_qu
    DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");

    /* do the actual data transfer */
    - do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
    ata_data_xfer(ap, buf, ATA_SECT_SIZE, do_write);

    - kunmap(page);
    + blk_kunmap(page, dir);
    }

    /**
    @@ -3127,6 +3130,7 @@ static void __atapi_pio_bytes(struct ata
    int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
    struct scatterlist *sg = qc->__sg;
    struct ata_port *ap = qc->ap;
    + enum dma_data_direction dir;
    struct page *page;
    unsigned char *buf;
    unsigned int offset, count;
    @@ -3134,6 +3138,8 @@ static void __atapi_pio_bytes(struct ata
    if (qc->curbytes + bytes >= qc->nbytes)
    ap->hsm_task_state = HSM_ST_LAST;

    + dir = do_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
    +
    next_sg:
    if (unlikely(qc->cursg >= qc->n_elem)) {
    /*
    @@ -3173,7 +3179,7 @@ next_sg:
    /* don't cross page boundaries */
    count = min(count, (unsigned int)PAGE_SIZE - offset);

    - buf = kmap(page) + offset;
    + buf = blk_kmap(page, dir) + offset;

    bytes -= count;
    qc->curbytes += count;
    @@ -3189,7 +3195,7 @@ next_sg:
    /* do the actual data transfer */
    ata_data_xfer(ap, buf, count, do_write);

    - kunmap(page);
    + blk_kunmap(page, dir);

    if (bytes)
    goto next_sg;
    diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
    index cfbceb5..8f8a19a 100644
    --- a/drivers/scsi/libata-scsi.c
    +++ b/drivers/scsi/libata-scsi.c
    @@ -1372,7 +1372,8 @@ static unsigned int ata_scsi_rbuf_get(st
    struct scatterlist *sg;

    sg = (struct scatterlist *) cmd->request_buffer;
    - buf = kmap_atomic(sg->page, KM_USER0) + sg->offset;
    + buf = blk_kmap_atomic(sg->page, KM_USER0, DMA_FROM_DEVICE);
    + buf += sg->offset;
    buflen = sg->length;
    } else {
    buf = cmd->request_buffer;
    @@ -1400,7 +1401,7 @@ static inline void ata_scsi_rbuf_put(str
    struct scatterlist *sg;

    sg = (struct scatterlist *) cmd->request_buffer;
    - kunmap_atomic(buf - sg->offset, KM_USER0);
    + blk_kunmap_atomic(buf - sg->offset, KM_USER0, DMA_FROM_DEVICE);
    }
    }

    --
    1.0.6

    -
    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: 2006-01-13 16:28    [W:0.031 / U:1.056 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site