lkml.org 
[lkml]   [2001]   [Mar]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] QIC-02 tape broken buffaddr
    I don't have a QIC-02 tape drive to test, but its driver source
    looks long broken. Note the comment at line 2836 "TODO:
    does _get_dma_pages() really return the physical address?" and
    follow uses of buffaddr - sometimes physical, sometimes virtual.

    Which worked in 2.2, with ISA DMA ignoring PAGE_OFFSET bits, and
    bus_to_virt() or'ing them; but 2.4 bus_to_virt() adds PAGE_OFFSET.
    Patch below against 2.4.2-ac9, applies to 2.4.[012] offset -2 lines.

    Hugh

    --- 2.4.2-ac9/drivers/char/tpqic02.c Fri Mar 2 18:22:36 2001
    +++ linux/drivers/char/tpqic02.c Fri Mar 2 18:23:42 2001
    @@ -210,7 +210,7 @@
    * must ensure that a large enough buffer is passed to the kernel, in order
    * to reduce tape repositioning wear and tear.
    */
    -static unsigned long buffaddr; /* physical address of buffer */
    +static void *buffaddr; /* virtual address of buffer */

    /* This translates minor numbers to the corresponding recording format: */
    static const char *format_names[] = {
    @@ -1378,7 +1378,7 @@
    flags=claim_dma_lock();
    clear_dma_ff(QIC02_TAPE_DMA);
    set_dma_mode(QIC02_TAPE_DMA, dma_mode);
    - set_dma_addr(QIC02_TAPE_DMA, buffaddr+dma_bytes_done); /* full address */
    + set_dma_addr(QIC02_TAPE_DMA, virt_to_bus(buffaddr) + dma_bytes_done);
    set_dma_count(QIC02_TAPE_DMA, TAPE_BLKSIZE);

    /* start tape DMA controller */
    @@ -1923,7 +1923,7 @@
    /* copy buffer to user-space in one go */
    if (bytes_done>0)
    {
    - err = copy_to_user( (void *) buf, (void *) bus_to_virt(buffaddr), bytes_done);
    + err = copy_to_user(buf, buffaddr, bytes_done);
    if (err)
    {
    return -EFAULT;
    @@ -2076,7 +2076,7 @@
    /* copy from user to DMA buffer and initiate transfer. */
    if (bytes_todo>0)
    {
    - err = copy_from_user( (void *) bus_to_virt(buffaddr), (const void *) buf, bytes_todo);
    + err = copy_from_user(buffaddr, buf, bytes_todo);
    if (err)
    {
    return -EFAULT;
    @@ -2782,7 +2782,7 @@
    release_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
    if (buffaddr)
    {
    - free_pages(buffaddr, get_order(TPQBUF_SIZE));
    + free_pages((unsigned long)buffaddr, get_order(TPQBUF_SIZE));
    }
    buffaddr = 0; /* Better to cause a panic than overwite someone else */
    status_zombie = YES;
    @@ -2832,9 +2832,7 @@
    request_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE, TPQIC02_NAME);

    /* Setup the page-address for the dma transfer. */
    -
    - /*** TODO: does _get_dma_pages() really return the physical address?? ****/
    - buffaddr = __get_dma_pages(GFP_KERNEL,get_order(TPQBUF_SIZE));
    + buffaddr = (void *)__get_dma_pages(GFP_KERNEL, get_order(TPQBUF_SIZE));

    if (!buffaddr)
    {
    @@ -2842,7 +2840,7 @@
    return -EBUSY; /* Not ideal, EAGAIN perhaps? */
    }

    - memset( (void*) buffaddr, 0, TPQBUF_SIZE );
    + memset(buffaddr, 0, TPQBUF_SIZE);

    printk(TPQIC02_NAME ": Settings: IRQ %d, DMA %d, IO 0x%x, IFC %s\n",
    QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
    -
    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: 2005-03-22 13:29    [W:0.024 / U:32.096 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site