xref: /haiku/src/libs/compat/openbsd_network/compat/machine/bus.h (revision a57635112e87a77e88f0bc869b173dfc54e89545)
1 /*
2  * Copyright 2022, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _OBSD_COMPAT_MACHINE_BUS_H_
6 #define _OBSD_COMPAT_MACHINE_BUS_H_
7 
8 
9 #include_next <machine/bus.h>
10 #include <sys/bus_dma.h>
11 
12 
13 #define	BUS_DMA_READ		(BUS_DMA_NOWRITE)
14 #define	BUS_DMA_WRITE		(0)
15 
16 struct bus_dmamap_obsd {
17 	bus_dma_tag_t _dmat;
18 	bus_dmamap_t _dmamp;
19 	int _error;
20 
21 	bus_size_t dm_mapsize;
22 	int dm_nsegs;
23 	bus_dma_segment_t dm_segs[];
24 };
25 typedef struct bus_dmamap_obsd* bus_dmamap_obsd_t;
26 #define bus_dmamap_t bus_dmamap_obsd_t
27 
28 
29 static int
bus_dmamap_create_obsd(bus_dma_tag_t tag,bus_size_t maxsize,int nsegments,bus_size_t maxsegsz,bus_size_t boundary,int flags,bus_dmamap_t * dmamp)30 bus_dmamap_create_obsd(bus_dma_tag_t tag, bus_size_t maxsize,
31 	int nsegments, bus_size_t maxsegsz, bus_size_t boundary,
32 	int flags, bus_dmamap_t* dmamp)
33 {
34 	*dmamp = calloc(sizeof(struct bus_dmamap_obsd) + (sizeof(bus_dma_segment_t) * nsegments), 1);
35 	if ((*dmamp) == NULL)
36 		return ENOMEM;
37 
38 	int error = bus_dma_tag_create(tag, 1, boundary,
39 		BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
40 		maxsize, nsegments, maxsegsz, flags, NULL, NULL,
41 		&(*dmamp)->_dmat);
42 	if (error != 0)
43 		return error;
44 
45 	error = bus_dmamap_create((*dmamp)->_dmat, flags, &(*dmamp)->_dmamp);
46 	return error;
47 }
48 #define bus_dmamap_create bus_dmamap_create_obsd
49 
50 
51 static void
bus_dmamap_destroy_obsd(bus_dma_tag_t tag,bus_dmamap_t dmam)52 bus_dmamap_destroy_obsd(bus_dma_tag_t tag, bus_dmamap_t dmam)
53 {
54 	bus_dmamap_destroy(dmam->_dmat, dmam->_dmamp);
55 	bus_dma_tag_destroy(dmam->_dmat);
56 	_kernel_free(dmam);
57 }
58 #define bus_dmamap_destroy bus_dmamap_destroy_obsd
59 
60 
61 static void
bus_dmamap_load_obsd_callback(void * arg,bus_dma_segment_t * segs,int nseg,int error)62 bus_dmamap_load_obsd_callback(void* arg, bus_dma_segment_t* segs, int nseg, int error)
63 {
64 	bus_dmamap_t dmam = (bus_dmamap_t)arg;
65 	dmam->_error = error;
66 	dmam->dm_nsegs = nseg;
67 	memcpy(dmam->dm_segs, segs, nseg * sizeof(bus_dma_segment_t));
68 }
69 
70 static int
bus_dmamap_load_obsd(bus_dma_tag_t tag,bus_dmamap_t dmam,void * buf,bus_size_t buflen,struct proc * p,int flags)71 bus_dmamap_load_obsd(bus_dma_tag_t tag, bus_dmamap_t dmam, void *buf, bus_size_t buflen, struct proc *p, int flags)
72 {
73 	int error = bus_dmamap_load(dmam->_dmat, dmam->_dmamp, buf, buflen,
74 		bus_dmamap_load_obsd_callback, dmam, flags | BUS_DMA_NOWAIT);
75 	if (error != 0)
76 		return error;
77 	dmam->dm_mapsize = buflen;
78 	return dmam->_error;
79 }
80 #define bus_dmamap_load bus_dmamap_load_obsd
81 
82 
83 static int
bus_dmamap_load_mbuf_obsd(bus_dma_tag_t tag,bus_dmamap_t dmam,struct mbuf * chain,int flags)84 bus_dmamap_load_mbuf_obsd(bus_dma_tag_t tag, bus_dmamap_t dmam, struct mbuf *chain, int flags)
85 {
86 	dmam->dm_mapsize = chain->m_pkthdr.len;
87 	return bus_dmamap_load_mbuf_sg(dmam->_dmat, dmam->_dmamp, chain,
88 		dmam->dm_segs, &dmam->dm_nsegs, flags);
89 }
90 #define bus_dmamap_load_mbuf bus_dmamap_load_mbuf_obsd
91 
92 
93 static void
bus_dmamap_unload_obsd(bus_dma_tag_t tag,bus_dmamap_t dmam)94 bus_dmamap_unload_obsd(bus_dma_tag_t tag, bus_dmamap_t dmam)
95 {
96 	bus_dmamap_unload(dmam->_dmat, dmam->_dmamp);
97 	dmam->dm_mapsize = 0;
98 	dmam->dm_nsegs = 0;
99 }
100 #define bus_dmamap_unload bus_dmamap_unload_obsd
101 
102 
103 static void
bus_dmamap_sync_obsd(bus_dma_tag_t tag,bus_dmamap_t dmam,bus_addr_t offset,bus_size_t length,int ops)104 bus_dmamap_sync_obsd(bus_dma_tag_t tag, bus_dmamap_t dmam,
105 	bus_addr_t offset, bus_size_t length, int ops)
106 {
107 	bus_dmamap_sync_etc(dmam->_dmat, dmam->_dmamp, offset, length, ops);
108 }
109 #define bus_dmamap_sync bus_dmamap_sync_obsd
110 
111 
112 static int
bus_dmamem_alloc_obsd(bus_dma_tag_t tag,bus_size_t size,bus_size_t alignment,bus_size_t boundary,bus_dma_segment_t * segs,int nsegs,int * rsegs,int flags)113 bus_dmamem_alloc_obsd(bus_dma_tag_t tag, bus_size_t size, bus_size_t alignment, bus_size_t boundary,
114 	bus_dma_segment_t* segs, int nsegs, int* rsegs, int flags)
115 {
116 	// OpenBSD distinguishes between three different types of addresses:
117 	//     1. virtual addresses (caddr_t)
118 	//     2. opaque "bus" addresses
119 	//     3. physical addresses
120 	// This function returns the second type. We simply return the virtual address for it.
121 
122 	bus_dma_tag_t local;
123 	int error = bus_dma_tag_create(tag, alignment, boundary,
124 		BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
125 		size, nsegs, size, flags, NULL, NULL, &local);
126 	if (error)
127 		return error;
128 
129 	error = bus_dmamem_alloc(local, (void**)&segs[0].ds_addr, flags, NULL);
130 	if (error) {
131 		bus_dma_tag_destroy(local);
132 		return error;
133 	}
134 	segs[0].ds_len = size;
135 
136 	error = bus_dma_tag_destroy(local);
137 	if (error)
138 		return error;
139 
140 	*rsegs = 1;
141 	return 0;
142 }
143 #define bus_dmamem_alloc bus_dmamem_alloc_obsd
144 
145 
146 static void
bus_dmamem_free_obsd(bus_dma_tag_t tag,bus_dma_segment_t * segs,int nsegs)147 bus_dmamem_free_obsd(bus_dma_tag_t tag, bus_dma_segment_t* segs, int nsegs)
148 {
149 	for (int i = 0; i < nsegs; i++)
150 		bus_dmamem_free_tagless((void*)segs[i].ds_addr, segs[i].ds_len);
151 }
152 #define bus_dmamem_free bus_dmamem_free_obsd
153 
154 
155 static int
bus_dmamem_map_obsd(bus_dma_tag_t tag,bus_dma_segment_t * segs,int nsegs,size_t size,caddr_t * kvap,int flags)156 bus_dmamem_map_obsd(bus_dma_tag_t tag, bus_dma_segment_t* segs, int nsegs, size_t size, caddr_t* kvap, int flags)
157 {
158 	if (nsegs != 1)
159 		return EINVAL;
160 
161 	*kvap = (caddr_t)segs[0].ds_addr;
162 	return 0;
163 }
164 #define bus_dmamem_map bus_dmamem_map_obsd
165 
166 
167 static void
bus_dmamem_unmap_obsd(bus_dma_tag_t tag,caddr_t kva,size_t size)168 bus_dmamem_unmap_obsd(bus_dma_tag_t tag, caddr_t kva, size_t size)
169 {
170 	// Nothing to do.
171 }
172 #define bus_dmamem_unmap bus_dmamem_unmap_obsd
173 
174 
175 #endif	/* _OBSD_COMPAT_MACHINE_BUS_H_ */
176