Deleted Added
full compact
amr_pci.c (152119) amr_pci.c (153409)
1/*-
2 * Copyright (c) 1999,2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 41 unchanged lines hidden (view full) ---

50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1999,2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 41 unchanged lines hidden (view full) ---

50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57#include <sys/cdefs.h>
58__FBSDID("$FreeBSD: head/sys/dev/amr/amr_pci.c 152119 2005-11-06 15:13:42Z scottl $");
58__FBSDID("$FreeBSD: head/sys/dev/amr/amr_pci.c 153409 2005-12-14 03:26:49Z scottl $");
59
60#include <sys/param.h>
61#include <sys/systm.h>
62#include <sys/kernel.h>
63#include <sys/module.h>
59
60#include <sys/param.h>
61#include <sys/systm.h>
62#include <sys/kernel.h>
63#include <sys/module.h>
64#include <sys/sysctl.h>
64
65#include <sys/bio.h>
66#include <sys/bus.h>
67#include <sys/conf.h>
68
69#include <machine/bus.h>
70#include <machine/resource.h>
71#include <sys/rman.h>

--- 13 unchanged lines hidden (view full) ---

85static int amr_pci_resume(device_t dev);
86static void amr_pci_intr(void *arg);
87static void amr_pci_free(struct amr_softc *sc);
88static void amr_sglist_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
89static int amr_sglist_map(struct amr_softc *sc);
90static void amr_setup_mbox_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
91static int amr_setup_mbox(struct amr_softc *sc);
92
65
66#include <sys/bio.h>
67#include <sys/bus.h>
68#include <sys/conf.h>
69
70#include <machine/bus.h>
71#include <machine/resource.h>
72#include <sys/rman.h>

--- 13 unchanged lines hidden (view full) ---

86static int amr_pci_resume(device_t dev);
87static void amr_pci_intr(void *arg);
88static void amr_pci_free(struct amr_softc *sc);
89static void amr_sglist_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
90static int amr_sglist_map(struct amr_softc *sc);
91static void amr_setup_mbox_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
92static int amr_setup_mbox(struct amr_softc *sc);
93
94static u_int amr_force_sg32 = 0;
95TUNABLE_INT("hw.amr.force_sg32", &amr_force_sg32);
96SYSCTL_DECL(_hw_amr);
97SYSCTL_UINT(_hw_amr, OID_AUTO, force_sg32, CTLFLAG_RDTUN, &amr_force_sg32, 0,
98 "Force the AMR driver to use 32bit scatter gather");
99
93static device_method_t amr_methods[] = {
94 /* Device interface */
95 DEVMETHOD(device_probe, amr_pci_probe),
96 DEVMETHOD(device_attach, amr_pci_attach),
97 DEVMETHOD(device_detach, amr_pci_detach),
98 DEVMETHOD(device_shutdown, amr_pci_shutdown),
99 DEVMETHOD(device_suspend, amr_pci_suspend),
100 DEVMETHOD(device_resume, amr_pci_resume),

--- 7 unchanged lines hidden (view full) ---

108 "amr",
109 amr_methods,
110 sizeof(struct amr_softc)
111};
112
113static devclass_t amr_devclass;
114DRIVER_MODULE(amr, pci, amr_pci_driver, amr_devclass, 0, 0);
115
100static device_method_t amr_methods[] = {
101 /* Device interface */
102 DEVMETHOD(device_probe, amr_pci_probe),
103 DEVMETHOD(device_attach, amr_pci_attach),
104 DEVMETHOD(device_detach, amr_pci_detach),
105 DEVMETHOD(device_shutdown, amr_pci_shutdown),
106 DEVMETHOD(device_suspend, amr_pci_suspend),
107 DEVMETHOD(device_resume, amr_pci_resume),

--- 7 unchanged lines hidden (view full) ---

115 "amr",
116 amr_methods,
117 sizeof(struct amr_softc)
118};
119
120static devclass_t amr_devclass;
121DRIVER_MODULE(amr, pci, amr_pci_driver, amr_devclass, 0, 0);
122
116static struct
123static struct amr_ident
117{
118 int vendor;
119 int device;
124{
125 int vendor;
126 int device;
120 int flag;
121#define PROBE_SIGNATURE (1<<0)
127 int flags;
128#define AMR_ID_PROBE_SIG (1<<0) /* generic i960RD, check signature */
129#define AMR_ID_DO_SG64 (1<<1)
130#define AMR_ID_QUARTZ (1<<2)
122} amr_device_ids[] = {
123 {0x101e, 0x9010, 0},
124 {0x101e, 0x9060, 0},
131} amr_device_ids[] = {
132 {0x101e, 0x9010, 0},
133 {0x101e, 0x9060, 0},
125 {0x8086, 0x1960, PROBE_SIGNATURE},/* generic i960RD, check for signature */
126 {0x101e, 0x1960, 0},
127 {0x1000, 0x1960, PROBE_SIGNATURE},
128 {0x1000, 0x0407, 0},
129 {0x1000, 0x0408, 0},
130 {0x1000, 0x0409, 0},
131 {0x1028, 0x000e, PROBE_SIGNATURE}, /* perc4/di i960 */
132 {0x1028, 0x000f, 0}, /* perc4/di Verde*/
133 {0x1028, 0x0013, 0}, /* perc4/di */
134 {0x8086, 0x1960, AMR_ID_QUARTZ | AMR_ID_PROBE_SIG},
135 {0x101e, 0x1960, AMR_ID_QUARTZ},
136 {0x1000, 0x1960, AMR_ID_QUARTZ | AMR_ID_PROBE_SIG},
137 {0x1000, 0x0407, AMR_ID_QUARTZ | AMR_ID_DO_SG64},
138 {0x1000, 0x0408, AMR_ID_QUARTZ | AMR_ID_DO_SG64},
139 {0x1000, 0x0409, AMR_ID_QUARTZ | AMR_ID_DO_SG64},
140 {0x1028, 0x000e, AMR_ID_QUARTZ | AMR_ID_DO_SG64 | AMR_ID_PROBE_SIG}, /* perc4/di i960 */
141 {0x1028, 0x000f, AMR_ID_QUARTZ | AMR_ID_DO_SG64}, /* perc4/di Verde*/
142 {0x1028, 0x0013, AMR_ID_QUARTZ | AMR_ID_DO_SG64}, /* perc4/di */
134 {0, 0, 0}
135};
136
143 {0, 0, 0}
144};
145
137static int
138amr_pci_probe(device_t dev)
146static struct amr_ident *
147amr_find_ident(device_t dev)
139{
148{
140 int i, sig;
149 struct amr_ident *id;
150 int sig;
141
151
142 debug_called(1);
152 for (id = amr_device_ids; id->vendor != 0; id++) {
153 if ((pci_get_vendor(dev) == id->vendor) &&
154 (pci_get_device(dev) == id->device)) {
143
155
144 for (i = 0; amr_device_ids[i].vendor != 0; i++) {
145 if ((pci_get_vendor(dev) == amr_device_ids[i].vendor) &&
146 (pci_get_device(dev) == amr_device_ids[i].device)) {
147
148 /* do we need to test for a signature? */
156 /* do we need to test for a signature? */
149 if (amr_device_ids[i].flag & PROBE_SIGNATURE) {
157 if (id->flags & AMR_ID_PROBE_SIG) {
150 sig = pci_read_config(dev, AMR_CFG_SIG, 2);
151 if ((sig != AMR_SIGNATURE_1) && (sig != AMR_SIGNATURE_2))
152 continue;
153 }
158 sig = pci_read_config(dev, AMR_CFG_SIG, 2);
159 if ((sig != AMR_SIGNATURE_1) && (sig != AMR_SIGNATURE_2))
160 continue;
161 }
154 device_set_desc(dev, LSI_DESC_PCI);
155 return(BUS_PROBE_DEFAULT);
162 return (id);
156 }
157 }
163 }
164 }
165 return (NULL);
166}
167
168static int
169amr_pci_probe(device_t dev)
170{
171
172 debug_called(1);
173
174 if (amr_find_ident(dev) != NULL) {
175 device_set_desc(dev, LSI_DESC_PCI);
176 return(BUS_PROBE_DEFAULT);
177 }
158 return(ENXIO);
159}
160
161static int
162amr_pci_attach(device_t dev)
163{
164 struct amr_softc *sc;
178 return(ENXIO);
179}
180
181static int
182amr_pci_attach(device_t dev)
183{
184 struct amr_softc *sc;
185 struct amr_ident *id;
165 int rid, rtype, error;
166 u_int32_t command;
167
168 debug_called(1);
169
170 /*
171 * Initialise softc.
172 */
173 sc = device_get_softc(dev);
174 bzero(sc, sizeof(*sc));
175 sc->amr_dev = dev;
186 int rid, rtype, error;
187 u_int32_t command;
188
189 debug_called(1);
190
191 /*
192 * Initialise softc.
193 */
194 sc = device_get_softc(dev);
195 bzero(sc, sizeof(*sc));
196 sc->amr_dev = dev;
176 mtx_init(&sc->amr_io_lock, "AMR IO Lock", NULL, MTX_DEF);
177
178 /* assume failure is 'not configured' */
179 error = ENXIO;
180
181 /*
182 * Determine board type.
183 */
197
198 /* assume failure is 'not configured' */
199 error = ENXIO;
200
201 /*
202 * Determine board type.
203 */
204 if ((id = amr_find_ident(dev)) == NULL)
205 return (ENXIO);
206
184 command = pci_read_config(dev, PCIR_COMMAND, 1);
207 command = pci_read_config(dev, PCIR_COMMAND, 1);
185 if ((pci_get_device(dev) == 0x1960) || (pci_get_device(dev) == 0x0407) ||
186 (pci_get_device(dev) == 0x0408) || (pci_get_device(dev) == 0x0409) ||
187 (pci_get_device(dev) == 0x000e) || (pci_get_device(dev) == 0x000f) ||
188 (pci_get_device(dev) == 0x0013)) {
208 if (id->flags & AMR_ID_QUARTZ) {
189 /*
190 * Make sure we are going to be able to talk to this board.
191 */
192 if ((command & PCIM_CMD_MEMEN) == 0) {
193 device_printf(dev, "memory window not available\n");
209 /*
210 * Make sure we are going to be able to talk to this board.
211 */
212 if ((command & PCIM_CMD_MEMEN) == 0) {
213 device_printf(dev, "memory window not available\n");
194 goto out;
214 return (ENXIO);
195 }
196 sc->amr_type |= AMR_TYPE_QUARTZ;
215 }
216 sc->amr_type |= AMR_TYPE_QUARTZ;
197
198 } else {
199 /*
200 * Make sure we are going to be able to talk to this board.
201 */
202 if ((command & PCIM_CMD_PORTEN) == 0) {
203 device_printf(dev, "I/O window not available\n");
217 } else {
218 /*
219 * Make sure we are going to be able to talk to this board.
220 */
221 if ((command & PCIM_CMD_PORTEN) == 0) {
222 device_printf(dev, "I/O window not available\n");
204 goto out;
223 return (ENXIO);
205 }
206 }
207
224 }
225 }
226
227 if ((amr_force_sg32 == 0) && (id->flags & AMR_ID_DO_SG64) &&
228 (sizeof(vm_paddr_t) > 4)) {
229 device_printf(dev, "Using 64-bit DMA\n");
230 sc->amr_type |= AMR_TYPE_SG64;
231 }
232
208 /* force the busmaster enable bit on */
209 if (!(command & PCIM_CMD_BUSMASTEREN)) {
210 device_printf(dev, "busmaster bit not set, enabling\n");
211 command |= PCIM_CMD_BUSMASTEREN;
212 pci_write_config(dev, PCIR_COMMAND, command, 2);
213 }
214
215 /*

--- 14 unchanged lines hidden (view full) ---

230 */
231 rid = 0;
232 sc->amr_irq = bus_alloc_resource_any(sc->amr_dev, SYS_RES_IRQ, &rid,
233 RF_SHAREABLE | RF_ACTIVE);
234 if (sc->amr_irq == NULL) {
235 device_printf(sc->amr_dev, "can't allocate interrupt\n");
236 goto out;
237 }
233 /* force the busmaster enable bit on */
234 if (!(command & PCIM_CMD_BUSMASTEREN)) {
235 device_printf(dev, "busmaster bit not set, enabling\n");
236 command |= PCIM_CMD_BUSMASTEREN;
237 pci_write_config(dev, PCIR_COMMAND, command, 2);
238 }
239
240 /*

--- 14 unchanged lines hidden (view full) ---

255 */
256 rid = 0;
257 sc->amr_irq = bus_alloc_resource_any(sc->amr_dev, SYS_RES_IRQ, &rid,
258 RF_SHAREABLE | RF_ACTIVE);
259 if (sc->amr_irq == NULL) {
260 device_printf(sc->amr_dev, "can't allocate interrupt\n");
261 goto out;
262 }
238 if (bus_setup_intr(sc->amr_dev, sc->amr_irq, INTR_TYPE_BIO | INTR_ENTROPY | INTR_MPSAFE, amr_pci_intr, sc, &sc->amr_intr)) {
263 if (bus_setup_intr(sc->amr_dev, sc->amr_irq,
264 INTR_TYPE_BIO | INTR_ENTROPY | INTR_MPSAFE, amr_pci_intr,
265 sc, &sc->amr_intr)) {
239 device_printf(sc->amr_dev, "can't set up interrupt\n");
240 goto out;
241 }
242
243 debug(2, "interrupt attached");
244
245 /* assume failure is 'out of memory' */
246 error = ENOMEM;
247
248 /*
249 * Allocate the parent bus DMA tag appropriate for PCI.
250 */
251 if (bus_dma_tag_create(NULL, /* parent */
266 device_printf(sc->amr_dev, "can't set up interrupt\n");
267 goto out;
268 }
269
270 debug(2, "interrupt attached");
271
272 /* assume failure is 'out of memory' */
273 error = ENOMEM;
274
275 /*
276 * Allocate the parent bus DMA tag appropriate for PCI.
277 */
278 if (bus_dma_tag_create(NULL, /* parent */
252 1, 0, /* alignment, boundary */
279 1, 0, /* alignment,boundary */
280 AMR_IS_SG64(sc) ?
281 BUS_SPACE_MAXADDR :
253 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
254 BUS_SPACE_MAXADDR, /* highaddr */
255 NULL, NULL, /* filter, filterarg */
256 MAXBSIZE, AMR_NSEG, /* maxsize, nsegments */
257 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
258 0, /* flags */
259 NULL, NULL, /* lockfunc, lockarg */
260 &sc->amr_parent_dmat)) {
261 device_printf(dev, "can't allocate parent DMA tag\n");
262 goto out;
263 }
264
265 /*
266 * Create DMA tag for mapping buffers into controller-addressable space.
267 */
268 if (bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
282 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
283 BUS_SPACE_MAXADDR, /* highaddr */
284 NULL, NULL, /* filter, filterarg */
285 MAXBSIZE, AMR_NSEG, /* maxsize, nsegments */
286 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
287 0, /* flags */
288 NULL, NULL, /* lockfunc, lockarg */
289 &sc->amr_parent_dmat)) {
290 device_printf(dev, "can't allocate parent DMA tag\n");
291 goto out;
292 }
293
294 /*
295 * Create DMA tag for mapping buffers into controller-addressable space.
296 */
297 if (bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
269 1, 0, /* alignment, boundary */
298 1, 0, /* alignment,boundary */
270 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
271 BUS_SPACE_MAXADDR, /* highaddr */
272 NULL, NULL, /* filter, filterarg */
273 MAXBSIZE, AMR_NSEG, /* maxsize, nsegments */
274 MAXBSIZE, /* maxsegsize */
275 BUS_DMA_ALLOCNOW, /* flags */
299 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
300 BUS_SPACE_MAXADDR, /* highaddr */
301 NULL, NULL, /* filter, filterarg */
302 MAXBSIZE, AMR_NSEG, /* maxsize, nsegments */
303 MAXBSIZE, /* maxsegsize */
304 BUS_DMA_ALLOCNOW, /* flags */
276 busdma_lock_mutex, &sc->amr_io_lock, /* lockfunc, lockarg */
305 busdma_lock_mutex, /* lockfunc */
306 &sc->amr_list_lock, /* lockarg */
277 &sc->amr_buffer_dmat)) {
278 device_printf(sc->amr_dev, "can't allocate buffer DMA tag\n");
279 goto out;
280 }
281
307 &sc->amr_buffer_dmat)) {
308 device_printf(sc->amr_dev, "can't allocate buffer DMA tag\n");
309 goto out;
310 }
311
312 if (bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
313 1, 0, /* alignment,boundary */
314 BUS_SPACE_MAXADDR, /* lowaddr */
315 BUS_SPACE_MAXADDR, /* highaddr */
316 NULL, NULL, /* filter, filterarg */
317 MAXBSIZE, AMR_NSEG, /* maxsize, nsegments */
318 MAXBSIZE, /* maxsegsize */
319 BUS_DMA_ALLOCNOW, /* flags */
320 busdma_lock_mutex, /* lockfunc */
321 &sc->amr_list_lock, /* lockarg */
322 &sc->amr_buffer64_dmat)) {
323 device_printf(sc->amr_dev, "can't allocate buffer DMA tag\n");
324 goto out;
325 }
326
282 debug(2, "dma tag done");
283
284 /*
285 * Allocate and set up mailbox in a bus-visible fashion.
286 */
327 debug(2, "dma tag done");
328
329 /*
330 * Allocate and set up mailbox in a bus-visible fashion.
331 */
332 mtx_init(&sc->amr_list_lock, "AMR List Lock", NULL, MTX_DEF);
333 mtx_init(&sc->amr_hw_lock, "AMR HW Lock", NULL, MTX_DEF);
287 if ((error = amr_setup_mbox(sc)) != 0)
288 goto out;
289
290 debug(2, "mailbox setup");
291
292 /*
293 * Build the scatter/gather buffers.
294 */

--- 123 unchanged lines hidden (view full) ---

418static void
419amr_pci_intr(void *arg)
420{
421 struct amr_softc *sc = (struct amr_softc *)arg;
422
423 debug_called(2);
424
425 /* collect finished commands, queue anything waiting */
334 if ((error = amr_setup_mbox(sc)) != 0)
335 goto out;
336
337 debug(2, "mailbox setup");
338
339 /*
340 * Build the scatter/gather buffers.
341 */

--- 123 unchanged lines hidden (view full) ---

465static void
466amr_pci_intr(void *arg)
467{
468 struct amr_softc *sc = (struct amr_softc *)arg;
469
470 debug_called(2);
471
472 /* collect finished commands, queue anything waiting */
426 mtx_lock(&sc->amr_io_lock);
427 amr_done(sc);
473 amr_done(sc);
428 mtx_unlock(&sc->amr_io_lock);
429}
430
431/********************************************************************************
432 * Free all of the resources associated with (sc)
433 *
434 * Should not be called if the controller is active.
435 */
436static void
437amr_pci_free(struct amr_softc *sc)
438{
474}
475
476/********************************************************************************
477 * Free all of the resources associated with (sc)
478 *
479 * Should not be called if the controller is active.
480 */
481static void
482amr_pci_free(struct amr_softc *sc)
483{
439 u_int8_t *p;
440
484 u_int8_t *p
485
441 debug_called(1);
442
443 amr_free(sc);
444
445 /* destroy data-transfer DMA tag */
446 if (sc->amr_buffer_dmat)
447 bus_dma_tag_destroy(sc->amr_buffer_dmat);
486 debug_called(1);
487
488 amr_free(sc);
489
490 /* destroy data-transfer DMA tag */
491 if (sc->amr_buffer_dmat)
492 bus_dma_tag_destroy(sc->amr_buffer_dmat);
493 if (sc->amr_buffer64_dmat)
494 bus_dma_tag_destroy(sc->amr_buffer64_dmat);
448
449 /* free and destroy DMA memory and tag for s/g lists */
450 if (sc->amr_sgtable)
451 bus_dmamem_free(sc->amr_sg_dmat, sc->amr_sgtable, sc->amr_sg_dmamap);
452 if (sc->amr_sg_dmat)
453 bus_dma_tag_destroy(sc->amr_sg_dmat);
454
455 /* free and destroy DMA memory and tag for mailbox */
495
496 /* free and destroy DMA memory and tag for s/g lists */
497 if (sc->amr_sgtable)
498 bus_dmamem_free(sc->amr_sg_dmat, sc->amr_sgtable, sc->amr_sg_dmamap);
499 if (sc->amr_sg_dmat)
500 bus_dma_tag_destroy(sc->amr_sg_dmat);
501
502 /* free and destroy DMA memory and tag for mailbox */
503 /* XXX Brain damaged GCC Alert! */
504 p = (u_int8_t *)(uintptr_t)(volatile void *)sc->amr_mailbox64;
456 if (sc->amr_mailbox) {
505 if (sc->amr_mailbox) {
457 p = (u_int8_t *)(uintptr_t)(volatile void *)sc->amr_mailbox;
458 bus_dmamem_free(sc->amr_mailbox_dmat, p - 16, sc->amr_mailbox_dmamap);
506 bus_dmamem_free(sc->amr_mailbox_dmat, p, sc->amr_mailbox_dmamap);
459 }
460 if (sc->amr_mailbox_dmat)
461 bus_dma_tag_destroy(sc->amr_mailbox_dmat);
462
463 /* disconnect the interrupt handler */
464 if (sc->amr_intr)
465 bus_teardown_intr(sc->amr_dev, sc->amr_irq, sc->amr_intr);
466 if (sc->amr_irq != NULL)

--- 23 unchanged lines hidden (view full) ---

490 /* save base of s/g table's address in bus space */
491 sc->amr_sgbusaddr = segs->ds_addr;
492}
493
494static int
495amr_sglist_map(struct amr_softc *sc)
496{
497 size_t segsize;
507 }
508 if (sc->amr_mailbox_dmat)
509 bus_dma_tag_destroy(sc->amr_mailbox_dmat);
510
511 /* disconnect the interrupt handler */
512 if (sc->amr_intr)
513 bus_teardown_intr(sc->amr_dev, sc->amr_irq, sc->amr_intr);
514 if (sc->amr_irq != NULL)

--- 23 unchanged lines hidden (view full) ---

538 /* save base of s/g table's address in bus space */
539 sc->amr_sgbusaddr = segs->ds_addr;
540}
541
542static int
543amr_sglist_map(struct amr_softc *sc)
544{
545 size_t segsize;
546 u_int8_t *p;
498 int error;
499
500 debug_called(1);
501
502 /*
503 * Create a single tag describing a region large enough to hold all of
504 * the s/g lists we will need.
505 *
547 int error;
548
549 debug_called(1);
550
551 /*
552 * Create a single tag describing a region large enough to hold all of
553 * the s/g lists we will need.
554 *
506 * Note that we could probably use AMR_LIMITCMD here, but that may become tunable.
555 * Note that we could probably use AMR_LIMITCMD here, but that may become
556 * tunable.
507 */
557 */
508 segsize = sizeof(struct amr_sgentry) * AMR_NSEG * AMR_MAXCMD;
558 if (AMR_IS_SG64(sc))
559 segsize = sizeof(struct amr_sg64entry) * AMR_NSEG * AMR_MAXCMD;
560 else
561 segsize = sizeof(struct amr_sgentry) * AMR_NSEG * AMR_MAXCMD;
562
509 error = bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
563 error = bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
510 1, 0, /* alignment, boundary */
564 1, 0, /* alignment,boundary */
511 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
512 BUS_SPACE_MAXADDR, /* highaddr */
513 NULL, NULL, /* filter, filterarg */
514 segsize, 1, /* maxsize, nsegments */
515 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
516 0, /* flags */
565 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
566 BUS_SPACE_MAXADDR, /* highaddr */
567 NULL, NULL, /* filter, filterarg */
568 segsize, 1, /* maxsize, nsegments */
569 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
570 0, /* flags */
517 busdma_lock_mutex, /* lockfunc */
518 &Giant, /* lockarg */
571 NULL, NULL, /* lockfunc, lockarg */
519 &sc->amr_sg_dmat);
520 if (error != 0) {
521 device_printf(sc->amr_dev, "can't allocate scatter/gather DMA tag\n");
522 return(ENOMEM);
523 }
524
525 /*
526 * Allocate enough s/g maps for all commands and permanently map them into
527 * controller-visible space.
528 *
529 * XXX this assumes we can get enough space for all the s/g maps in one
572 &sc->amr_sg_dmat);
573 if (error != 0) {
574 device_printf(sc->amr_dev, "can't allocate scatter/gather DMA tag\n");
575 return(ENOMEM);
576 }
577
578 /*
579 * Allocate enough s/g maps for all commands and permanently map them into
580 * controller-visible space.
581 *
582 * XXX this assumes we can get enough space for all the s/g maps in one
530 * contiguous slab. We may need to switch to a more complex arrangement where
531 * we allocate in smaller chunks and keep a lookup table from slot to bus address.
583 * contiguous slab. We may need to switch to a more complex arrangement
584 * where we allocate in smaller chunks and keep a lookup table from slot
585 * to bus address.
532 *
586 *
533 * XXX HACK ALERT: at least some controllers don't like the s/g memory being
534 * allocated below 0x2000. We leak some memory if we get some
535 * below this mark and allocate again. We should be able to
536 * avoid this with the tag setup, but that does't seem to work.
587 * XXX HACK ALERT: at least some controllers don't like the s/g memory
588 * being allocated below 0x2000. We leak some memory if
589 * we get some below this mark and allocate again. We
590 * should be able to avoid this with the tag setup, but
591 * that does't seem to work.
537 */
538retry:
592 */
593retry:
539 error = bus_dmamem_alloc(sc->amr_sg_dmat, (void **)&sc->amr_sgtable, BUS_DMA_NOWAIT, &sc->amr_sg_dmamap);
594 error = bus_dmamem_alloc(sc->amr_sg_dmat, (void **)&p, BUS_DMA_NOWAIT, &sc->amr_sg_dmamap);
540 if (error) {
541 device_printf(sc->amr_dev, "can't allocate s/g table\n");
542 return(ENOMEM);
543 }
595 if (error) {
596 device_printf(sc->amr_dev, "can't allocate s/g table\n");
597 return(ENOMEM);
598 }
544 bus_dmamap_load(sc->amr_sg_dmat, sc->amr_sg_dmamap, sc->amr_sgtable, segsize, amr_sglist_map_helper, sc, 0);
599 bus_dmamap_load(sc->amr_sg_dmat, sc->amr_sg_dmamap, p, segsize, amr_sglist_map_helper, sc, 0);
545 if (sc->amr_sgbusaddr < 0x2000) {
546 debug(1, "s/g table too low (0x%x), reallocating\n", sc->amr_sgbusaddr);
547 goto retry;
548 }
600 if (sc->amr_sgbusaddr < 0x2000) {
601 debug(1, "s/g table too low (0x%x), reallocating\n", sc->amr_sgbusaddr);
602 goto retry;
603 }
604
605 if (AMR_IS_SG64(sc))
606 sc->amr_sg64table = (struct amr_sg64entry *)p;
607 sc->amr_sgtable = (struct amr_sgentry *)p;
608
549 return(0);
550}
551
552/********************************************************************************
553 * Allocate and set up mailbox areas for the controller (sc)
554 *
555 * The basic mailbox structure should be 16-byte aligned. This means that the
556 * mailbox64 structure has 4 bytes hanging off the bottom.
557 */
558static void
559amr_setup_mbox_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
560{
561 struct amr_softc *sc = (struct amr_softc *)arg;
562
563 debug_called(1);
564
565 /* save phsyical base of the basic mailbox structure */
609 return(0);
610}
611
612/********************************************************************************
613 * Allocate and set up mailbox areas for the controller (sc)
614 *
615 * The basic mailbox structure should be 16-byte aligned. This means that the
616 * mailbox64 structure has 4 bytes hanging off the bottom.
617 */
618static void
619amr_setup_mbox_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
620{
621 struct amr_softc *sc = (struct amr_softc *)arg;
622
623 debug_called(1);
624
625 /* save phsyical base of the basic mailbox structure */
566 sc->amr_mailboxphys = segs->ds_addr + 16;
626 sc->amr_mailboxphys = segs->ds_addr + offsetof(struct amr_mailbox64, mb);
567}
568
569static int
570amr_setup_mbox(struct amr_softc *sc)
571{
572 int error;
573 u_int8_t *p;
574
575 debug_called(1);
576
577 /*
578 * Create a single tag describing a region large enough to hold the entire
579 * mailbox.
580 */
581 error = bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
627}
628
629static int
630amr_setup_mbox(struct amr_softc *sc)
631{
632 int error;
633 u_int8_t *p;
634
635 debug_called(1);
636
637 /*
638 * Create a single tag describing a region large enough to hold the entire
639 * mailbox.
640 */
641 error = bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
582 16, 0, /* alignment, boundary */
642 16, 0, /* alignment,boundary */
583 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
584 BUS_SPACE_MAXADDR, /* highaddr */
585 NULL, NULL, /* filter, filterarg */
643 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
644 BUS_SPACE_MAXADDR, /* highaddr */
645 NULL, NULL, /* filter, filterarg */
586 sizeof(struct amr_mailbox) + 16, 1, /* maxsize, nsegments */
646 sizeof(struct amr_mailbox64), /* maxsize */
647 1, /* nsegments */
587 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
588 0, /* flags */
648 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
649 0, /* flags */
589 busdma_lock_mutex, /* lockfunc */
590 &Giant, /* lockarg */
650 NULL, NULL, /* lockfunc, lockarg */
591 &sc->amr_mailbox_dmat);
592 if (error != 0) {
593 device_printf(sc->amr_dev, "can't allocate mailbox tag\n");
594 return(ENOMEM);
595 }
596
597 /*
598 * Allocate the mailbox structure and permanently map it into

--- 6 unchanged lines hidden (view full) ---

605 return(ENOMEM);
606 }
607 bus_dmamap_load(sc->amr_mailbox_dmat, sc->amr_mailbox_dmamap, p,
608 sizeof(struct amr_mailbox64), amr_setup_mbox_helper, sc, 0);
609 /*
610 * Conventional mailbox is inside the mailbox64 region.
611 */
612 bzero(p, sizeof(struct amr_mailbox64));
651 &sc->amr_mailbox_dmat);
652 if (error != 0) {
653 device_printf(sc->amr_dev, "can't allocate mailbox tag\n");
654 return(ENOMEM);
655 }
656
657 /*
658 * Allocate the mailbox structure and permanently map it into

--- 6 unchanged lines hidden (view full) ---

665 return(ENOMEM);
666 }
667 bus_dmamap_load(sc->amr_mailbox_dmat, sc->amr_mailbox_dmamap, p,
668 sizeof(struct amr_mailbox64), amr_setup_mbox_helper, sc, 0);
669 /*
670 * Conventional mailbox is inside the mailbox64 region.
671 */
672 bzero(p, sizeof(struct amr_mailbox64));
613 sc->amr_mailbox64 = (struct amr_mailbox64 *)(p + 12);
614 sc->amr_mailbox = (struct amr_mailbox *)(p + 16);
673 sc->amr_mailbox64 = (struct amr_mailbox64 *)p;
674 sc->amr_mailbox = &sc->amr_mailbox64->mb;
615
616 return(0);
617}
675
676 return(0);
677}