1 /* $Id: ioport.c,v 1.14 1998/05/11 06:23:36 davem Exp $
2 * ioport.c: Simple io mapping allocator.
4 * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/types.h>
12 #include <linux/ioport.h>
16 #include <asm/vaddrs.h>
17 #include <asm/oplib.h>
19 #include <asm/pgtable.h>
21 /* This points to the next to use virtual memory for io mappings */
22 static unsigned long dvma_next_free
= DVMA_VADDR
;
24 extern void mmu_map_dma_area(unsigned long addr
, int len
, __u32
*dvma_addr
);
28 * Map and allocates an obio device.
29 * Implements a simple linear allocator, you can force the function
30 * to use your own mapping, but in practice this should not be used.
33 * address: Physical address to map
34 * virtual: if non zero, specifies a fixed virtual address where
35 * the mapping should take place, not supported on Ultra
36 * and this feature is scheduled to be removed as nobody
38 * len: the length of the mapping
39 * bus_type: Optional high word of physical address.
42 * The virtual address where the mapping actually took place.
45 void *sparc_alloc_io (u32 address
, void *virtual, int len
, char *name
,
46 u32 bus_type
, int rdonly
)
48 unsigned long addr
= ((unsigned long)address
) + (((unsigned long)bus_type
)<<32);
49 unsigned long vaddr
= (unsigned long) __va(addr
);
52 panic("sparc_alloc_io: Fixed virtual mappings unsupported on Ultra.");
54 if(!check_region(vaddr
, len
))
55 request_region(vaddr
, len
, name
);
57 return (void *) vaddr
;
60 void sparc_free_io (void *virtual, int len
)
62 unsigned long vaddr
= (unsigned long) virtual & PAGE_MASK
;
63 unsigned long plen
= (((unsigned long)virtual & ~PAGE_MASK
) +
64 len
+ PAGE_SIZE
-1) & PAGE_MASK
;
65 release_region(vaddr
, plen
);
68 /* Does DVMA allocations with PAGE_SIZE granularity. How this basically
69 * works is that the ESP chip can do DVMA transfers at ANY address with
70 * certain size and boundary restrictions. But other devices that are
71 * attached to it and would like to do DVMA have to set things up in
72 * a special way, if the DVMA sees a device attached to it transfer data
73 * at addresses above DVMA_VADDR it will grab them, this way it does not
74 * now have to know the peculiarities of where to read the Lance data
77 * Returns CPU visible address for the buffer returned, dvma_addr is
78 * set to the DVMA visible address.
80 void *sparc_dvma_malloc (int len
, char *name
, __u32
*dvma_addr
)
82 unsigned long vaddr
, base_address
;
84 vaddr
= dvma_next_free
;
85 if(check_region (vaddr
, len
)) {
86 prom_printf("alloc_dma: 0x%lx is already in use\n", vaddr
);
89 if(vaddr
+ len
> (DVMA_VADDR
+ DVMA_LEN
)) {
90 prom_printf("alloc_dvma: out of dvma memory\n");
94 /* Basically these can be mapped just like any old
95 * IO pages, cacheable bit off, etc. The physical
96 * pages are now mapped dynamically to save space.
99 mmu_map_dma_area(base_address
, len
, dvma_addr
);
101 /* Assign the memory area. */
102 dvma_next_free
= PAGE_ALIGN(dvma_next_free
+len
);
104 request_region(base_address
, len
, name
);
106 return (void *) base_address
;