patch-2.3.47 linux/arch/sparc64/kernel/sbus.c
Next file: linux/arch/sparc64/kernel/sys_sparc.c
Previous file: linux/arch/sparc64/kernel/pci_sabre.c
Back to the patch index
Back to the overall index
- Lines: 142
- Date:
Fri Feb 18 15:07:20 2000
- Orig file:
v2.3.46/linux/arch/sparc64/kernel/sbus.c
- Orig date:
Wed Feb 16 17:03:51 2000
diff -u --recursive --new-file v2.3.46/linux/arch/sparc64/kernel/sbus.c linux/arch/sparc64/kernel/sbus.c
@@ -1,4 +1,4 @@
-/* $Id: sbus.c,v 1.7 2000/01/28 13:41:58 jj Exp $
+/* $Id: sbus.c,v 1.9 2000/02/18 13:48:57 davem Exp $
* sbus.c: UltraSparc SBUS controller support.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -308,12 +308,16 @@
free_pages((unsigned long)cpu, order);
}
-dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size)
+dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int dir)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
unsigned long npages, phys_base, flags;
iopte_t *iopte;
u32 dma_base, offset;
+ unsigned long iopte_bits;
+
+ if (dir == SBUS_DMA_NONE)
+ BUG();
phys_base = (unsigned long) ptr;
offset = (u32) (phys_base & ~PAGE_MASK);
@@ -325,10 +329,11 @@
iopte = alloc_streaming_cluster(iommu, npages);
dma_base = MAP_BASE + ((iopte - iommu->page_table) << PAGE_SHIFT);
npages = size >> PAGE_SHIFT;
+ iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE;
+ if (dir != SBUS_DMA_TODEVICE)
+ iopte_bits |= IOPTE_WRITE;
while (npages--) {
- *iopte++ = __iopte(IOPTE_VALID | IOPTE_STBUF |
- IOPTE_CACHE | IOPTE_WRITE |
- (phys_base & IOPTE_PAGE));
+ *iopte++ = __iopte(iopte_bits | (phys_base & IOPTE_PAGE));
phys_base += PAGE_SIZE;
}
npages = size >> PAGE_SHIFT;
@@ -338,7 +343,7 @@
return (dma_base | offset);
}
-void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size)
+void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, int direction)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
u32 dma_base = dma_addr & PAGE_MASK;
@@ -352,7 +357,7 @@
spin_unlock_irqrestore(&iommu->lock, flags);
}
-static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused)
+static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, unsigned long iopte_bits)
{
struct scatterlist *dma_sg = sg;
int i;
@@ -392,9 +397,7 @@
sg++;
}
- pteval = ((pteval & IOPTE_PAGE) |
- IOPTE_VALID | IOPTE_STBUF |
- IOPTE_CACHE | IOPTE_WRITE);
+ pteval = ((pteval & IOPTE_PAGE) | iopte_bits);
while (len > 0) {
*iopte++ = __iopte(pteval);
pteval += PAGE_SIZE;
@@ -424,7 +427,7 @@
}
}
-int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents)
+int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int dir)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
unsigned long flags, npages;
@@ -432,10 +435,14 @@
u32 dma_base;
struct scatterlist *sgtmp;
int used;
+ unsigned long iopte_bits;
+
+ if (dir == SBUS_DMA_NONE)
+ BUG();
/* Fast path single entry scatterlists. */
if (nents == 1) {
- sg->dvma_address = sbus_map_single(sdev, sg->address, sg->length);
+ sg->dvma_address = sbus_map_single(sdev, sg->address, sg->length, dir);
sg->dvma_length = sg->length;
return 1;
}
@@ -457,7 +464,11 @@
}
used = nents - used;
- fill_sg(iopte, sg, used);
+ iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE;
+ if (dir != SBUS_DMA_TODEVICE)
+ iopte_bits |= IOPTE_WRITE;
+
+ fill_sg(iopte, sg, used, iopte_bits);
#ifdef VERIFY_SG
verify_sglist(sg, nents, iopte, npages);
#endif
@@ -467,7 +478,7 @@
return used;
}
-void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents)
+void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction)
{
unsigned long size, flags;
struct sbus_iommu *iommu;
@@ -476,7 +487,7 @@
/* Fast path single entry scatterlists. */
if (nents == 1) {
- sbus_unmap_single(sdev, sg->dvma_address, sg->dvma_length);
+ sbus_unmap_single(sdev, sg->dvma_address, sg->dvma_length, direction);
return;
}
@@ -495,7 +506,7 @@
spin_unlock_irqrestore(&iommu->lock, flags);
}
-void sbus_dma_sync_single(struct sbus_dev *sdev, dma_addr_t base, size_t size)
+void sbus_dma_sync_single(struct sbus_dev *sdev, dma_addr_t base, size_t size, int direction)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
unsigned long flags;
@@ -507,7 +518,7 @@
spin_unlock_irqrestore(&iommu->lock, flags);
}
-void sbus_dma_sync_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents)
+void sbus_dma_sync_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
unsigned long flags, size;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)