[ARM] Remove '__address' from scatterlist and convert to DMA API
The old __address element in struct scatterlist remained from older kernels because the ARM DMA emulation code made use of it. Move this field into struct dma_struct, and convert DMA emulation code to setup a SG entry as required. Also, convert DMA emulation code to use the new DMA API rather than the PCI DMA API. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
333c9624b7
commit
7cdad48297
5 changed files with 31 additions and 28 deletions
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
|
||||||
#include <asm/dma.h>
|
#include <asm/dma.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
@ -65,37 +65,41 @@ static void isa_enable_dma(dmach_t channel, dma_t *dma)
|
||||||
{
|
{
|
||||||
if (dma->invalid) {
|
if (dma->invalid) {
|
||||||
unsigned long address, length;
|
unsigned long address, length;
|
||||||
unsigned int mode, direction;
|
unsigned int mode;
|
||||||
|
enum dma_data_direction direction;
|
||||||
|
|
||||||
mode = channel & 3;
|
mode = channel & 3;
|
||||||
switch (dma->dma_mode & DMA_MODE_MASK) {
|
switch (dma->dma_mode & DMA_MODE_MASK) {
|
||||||
case DMA_MODE_READ:
|
case DMA_MODE_READ:
|
||||||
mode |= ISA_DMA_MODE_READ;
|
mode |= ISA_DMA_MODE_READ;
|
||||||
direction = PCI_DMA_FROMDEVICE;
|
direction = DMA_FROM_DEVICE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DMA_MODE_WRITE:
|
case DMA_MODE_WRITE:
|
||||||
mode |= ISA_DMA_MODE_WRITE;
|
mode |= ISA_DMA_MODE_WRITE;
|
||||||
direction = PCI_DMA_TODEVICE;
|
direction = DMA_TO_DEVICE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DMA_MODE_CASCADE:
|
case DMA_MODE_CASCADE:
|
||||||
mode |= ISA_DMA_MODE_CASCADE;
|
mode |= ISA_DMA_MODE_CASCADE;
|
||||||
direction = PCI_DMA_BIDIRECTIONAL;
|
direction = DMA_BIDIRECTIONAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
direction = PCI_DMA_NONE;
|
direction = DMA_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dma->using_sg) {
|
if (!dma->sg) {
|
||||||
/*
|
/*
|
||||||
* Cope with ISA-style drivers which expect cache
|
* Cope with ISA-style drivers which expect cache
|
||||||
* coherence.
|
* coherence.
|
||||||
*/
|
*/
|
||||||
dma->buf.dma_address = pci_map_single(NULL,
|
dma->sg = &dma->buf;
|
||||||
dma->buf.__address, dma->buf.length,
|
dma->sgcount = 1;
|
||||||
|
dma->buf.length = dma->count;
|
||||||
|
dma->buf.dma_address = dma_map_single(NULL,
|
||||||
|
dma->addr, dma->count,
|
||||||
direction);
|
direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,6 @@ void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg)
|
||||||
|
|
||||||
dma->sg = sg;
|
dma->sg = sg;
|
||||||
dma->sgcount = nr_sg;
|
dma->sgcount = nr_sg;
|
||||||
dma->using_sg = 1;
|
|
||||||
dma->invalid = 1;
|
dma->invalid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,10 +138,8 @@ void __set_dma_addr (dmach_t channel, void *addr)
|
||||||
printk(KERN_ERR "dma%d: altering DMA address while "
|
printk(KERN_ERR "dma%d: altering DMA address while "
|
||||||
"DMA active\n", channel);
|
"DMA active\n", channel);
|
||||||
|
|
||||||
dma->sg = &dma->buf;
|
dma->sg = NULL;
|
||||||
dma->sgcount = 1;
|
dma->addr = addr;
|
||||||
dma->buf.__address = addr;
|
|
||||||
dma->using_sg = 0;
|
|
||||||
dma->invalid = 1;
|
dma->invalid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,10 +155,8 @@ void set_dma_count (dmach_t channel, unsigned long count)
|
||||||
printk(KERN_ERR "dma%d: altering DMA count while "
|
printk(KERN_ERR "dma%d: altering DMA count while "
|
||||||
"DMA active\n", channel);
|
"DMA active\n", channel);
|
||||||
|
|
||||||
dma->sg = &dma->buf;
|
dma->sg = NULL;
|
||||||
dma->sgcount = 1;
|
dma->count = count;
|
||||||
dma->buf.length = count;
|
|
||||||
dma->using_sg = 0;
|
|
||||||
dma->invalid = 1;
|
dma->invalid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <linux/mman.h>
|
#include <linux/mman.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/dma.h>
|
#include <asm/dma.h>
|
||||||
|
@ -148,11 +148,14 @@ static void iomd_enable_dma(dmach_t channel, dma_t *dma)
|
||||||
* Cope with ISA-style drivers which expect cache
|
* Cope with ISA-style drivers which expect cache
|
||||||
* coherence.
|
* coherence.
|
||||||
*/
|
*/
|
||||||
if (!dma->using_sg) {
|
if (!dma->sg) {
|
||||||
dma->buf.dma_address = pci_map_single(NULL,
|
dma->sg = &dma->buf;
|
||||||
dma->buf.__address, dma->buf.length,
|
dma->sgcount = 1;
|
||||||
|
dma->buf.length = dma->count;
|
||||||
|
dma->buf.dma_address = dma_map_single(NULL,
|
||||||
|
dma->addr, dma->count,
|
||||||
dma->dma_mode == DMA_MODE_READ ?
|
dma->dma_mode == DMA_MODE_READ ?
|
||||||
PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
|
DMA_FROM_DEVICE : DMA_TO_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iomd_writeb(DMA_CR_C, dma_base + CR);
|
iomd_writeb(DMA_CR_C, dma_base + CR);
|
||||||
|
@ -239,7 +242,7 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma)
|
||||||
unsigned int fiqhandler_length;
|
unsigned int fiqhandler_length;
|
||||||
struct pt_regs regs;
|
struct pt_regs regs;
|
||||||
|
|
||||||
if (dma->using_sg)
|
if (dma->sg)
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
if (dma->dma_mode == DMA_MODE_READ) {
|
if (dma->dma_mode == DMA_MODE_READ) {
|
||||||
|
@ -252,8 +255,8 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma)
|
||||||
fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
|
fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.ARM_r9 = dma->buf.length;
|
regs.ARM_r9 = dma->count;
|
||||||
regs.ARM_r10 = (unsigned long)dma->buf.__address;
|
regs.ARM_r10 = (unsigned long)dma->addr;
|
||||||
regs.ARM_fp = (unsigned long)FLOPPYDMA_BASE;
|
regs.ARM_fp = (unsigned long)FLOPPYDMA_BASE;
|
||||||
|
|
||||||
if (claim_fiq(&fh)) {
|
if (claim_fiq(&fh)) {
|
||||||
|
|
|
@ -25,13 +25,15 @@ struct dma_ops {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dma_struct {
|
struct dma_struct {
|
||||||
|
void *addr; /* single DMA address */
|
||||||
|
unsigned long count; /* single DMA size */
|
||||||
struct scatterlist buf; /* single DMA */
|
struct scatterlist buf; /* single DMA */
|
||||||
int sgcount; /* number of DMA SG */
|
int sgcount; /* number of DMA SG */
|
||||||
struct scatterlist *sg; /* DMA Scatter-Gather List */
|
struct scatterlist *sg; /* DMA Scatter-Gather List */
|
||||||
|
|
||||||
unsigned int active:1; /* Transfer active */
|
unsigned int active:1; /* Transfer active */
|
||||||
unsigned int invalid:1; /* Address/Count changed */
|
unsigned int invalid:1; /* Address/Count changed */
|
||||||
unsigned int using_sg:1; /* using scatter list? */
|
|
||||||
dmamode_t dma_mode; /* DMA mode */
|
dmamode_t dma_mode; /* DMA mode */
|
||||||
int speed; /* DMA speed */
|
int speed; /* DMA speed */
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ struct scatterlist {
|
||||||
unsigned int offset; /* buffer offset */
|
unsigned int offset; /* buffer offset */
|
||||||
dma_addr_t dma_address; /* dma address */
|
dma_addr_t dma_address; /* dma address */
|
||||||
unsigned int length; /* length */
|
unsigned int length; /* length */
|
||||||
char *__address; /* for set_dma_addr */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue