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} |