patch-2.3.41 linux/drivers/parport/parport_pc.c
Next file: linux/drivers/parport/procfs.c
Previous file: linux/drivers/parport/parport_mfc3.c
Back to the patch index
Back to the overall index
- Lines: 104
- Date:
Thu Jan 27 09:00:29 2000
- Orig file:
v2.3.40/linux/drivers/parport/parport_pc.c
- Orig date:
Fri Jan 21 18:19:16 2000
diff -u --recursive --new-file v2.3.40/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
@@ -549,8 +549,24 @@
{
int ret = 0;
unsigned long dmaflag;
- size_t left = length;
+ size_t left = length;
const struct parport_pc_private *priv = port->physport->private_data;
+ unsigned long dma_addr;
+ size_t maxlen = 0x10000; /* max 64k per DMA transfer */
+ unsigned long start = (unsigned long) buf;
+ unsigned long end = (unsigned long) buf + length - 1;
+
+ /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */
+ if (end <= MAX_DMA_ADDRESS) {
+ /* If it would cross a 64k boundary, cap it at the end. */
+ if ((start ^ end) & ~0xffff)
+ maxlen = (0x10000 - start) & 0xffff;
+
+ dma_addr = virt_to_bus(buf);
+ } else {
+ dma_addr = priv->dma_handle;
+ maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */
+ }
port = port->physport;
@@ -566,16 +582,17 @@
size_t count = left;
- if (count > PAGE_SIZE)
- count = PAGE_SIZE;
+ if (count > maxlen)
+ count = maxlen;
- memcpy(priv->dma_buf, buf, count);
+ if (maxlen == PAGE_SIZE) /* bounce buffer ! */
+ memcpy(priv->dma_buf, buf, count);
dmaflag = claim_dma_lock();
disable_dma(port->dma);
clear_dma_ff(port->dma);
set_dma_mode(port->dma, DMA_MODE_WRITE);
- set_dma_addr(port->dma, virt_to_bus((volatile char *) priv->dma_buf));
+ set_dma_addr(port->dma, dma_addr);
set_dma_count(port->dma, count);
/* Set DMA mode */
@@ -1499,7 +1516,8 @@
struct parport *__maybe_init parport_pc_probe_port (unsigned long int base,
unsigned long int base_hi,
- int irq, int dma)
+ int irq, int dma,
+ struct pci_dev *dev)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
@@ -1525,6 +1543,8 @@
priv->ecr = 0;
priv->fifo_depth = 0;
priv->dma_buf = 0;
+ priv->dma_handle = 0;
+ priv->dev = dev;
p->base = base;
p->base_hi = base_hi;
p->irq = irq;
@@ -1649,7 +1669,9 @@
p->dma = PARPORT_DMA_NONE;
} else {
priv->dma_buf =
- (char *)__get_dma_pages(GFP_KERNEL, 0);
+ pci_alloc_consistent(priv->dev,
+ PAGE_SIZE,
+ &priv->dma_handle);
if (! priv->dma_buf) {
printk (KERN_WARNING "%s: "
"cannot get buffer for DMA, "
@@ -1805,10 +1827,12 @@
if (parport_pc_probe_port (io_lo,
io_hi,
pcidev->irq,
- dma))
+ dma,
+ pcidev))
count++;
} else if (parport_pc_probe_port (io_lo, io_hi,
- irq, dma))
+ irq, dma,
+ pcidev))
count++;
}
}
@@ -1913,7 +1937,9 @@
release_region(p->base_hi, 3);
parport_proc_unregister(p);
if (priv->dma_buf)
- free_page((unsigned long) priv->dma_buf);
+ pci_free_consistent(priv->dev, PAGE_SIZE,
+ priv->dma_buf,
+ priv->dma_handle);
kfree (p->private_data);
parport_unregister_port(p);
kfree (ops); /* hope no-one cached it */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)