Date: Mon, 16 Aug 1999 04:35:57 -0400 (EDT) From: Bill Paul <wpaul@skynet.ctr.columbia.edu> To: mike@smith.net.au (Mike Smith) Cc: lile@stdio.com, hackers@freebsd.org Subject: Re: How do you allocate dma channel with newbus? Message-ID: <199908160835.EAA20312@skynet.ctr.columbia.edu> In-Reply-To: <199908160606.XAA16944@dingo.cdrom.com> from "Mike Smith" at Aug 15, 99 11:06:11 pm
next in thread | previous in thread | raw e-mail | index | archive | help
Of all the gin joints in all the towns in all the world, Mike Smith had to walk into mine and say: > > > > I am feeling a little dense today, how do you allocate a > > dma channel for a PCI busmaster device with newbus? > > It's a bus master, so you don't. The logical conclusion is that Larry really does have a question, but he asked it badly. Since he asked it so badly that we really don't know what he meant, we should attempt to throw information at him in the hopes that we'll end up telling him what he wants. This is not as efficient as asking the question correctly the first time, but communication seems to be a lost art these days, so what can you do. First of all, with newbus, you now have pci_read_config() and pci_write_config() instead of pci_conf_read() and pci_conf_write(). The former accept a device_t and let you specify the register width (as opposed to forcing to you to use 32-bit accesses all the time). You may need to enable bus mastering and PIO/memory mapping mode in the PCI command register as before. Once you do that, you have to allocate the "resources" that you need. The first resource is the register access space. This can be either an I/O address in iospace or a memory base address. The second is the interrupt. You need to keep track of these resources in your softc structure. They are allocated with bus_alloc_resource(). For PCI devices, you used to use pci_map_port() or pci_map_mem(); now you use bus_alloc_resource() instead, which ultimately has the same effect. When you allocate the register space resource, you have to pass a pointer to a resource ID, which for PCI devices is the register to use. For the SYS_RES_IOPORT resource type, you specify the PCI iobase address register. For SYS_RES_MEMORY, you specify the the memory base address register. Once you have allocated the iospace resource, you can then use rman_get_bustag() and rman_get_bushandle() to get the bustag and bushandle that you can use with the bus_space_read()/bus_space_write() routines to read/write the device registers. The bustag and bushandle should be treated as opaque; they will let you read from iospace or memory mapped space depending on the resource type that you allocated. You also use bus_space_alloc() to allocate the interrupt resource using SYS_RES_IRQ (the resource ID is 0). To actually map the interrupt to a handler function, you need to use bus_setup_intr(). Resources can be released with bus_release_resource(), and the interrupt handler can be detached with bus_teardown_intr(). This allows you to unload drivers. For bus master DMA, you can still use vtophys() to map kernel virtual addresses to physical addresses as before. Ideally one should use the busdma routines for that, however I haven't figured out how to use them with network device drivers yet, and nobody has come forward with a nice simple example that shows how to do it (and no, I don't mean a NetBSD driver: I mean an example which will actually work in FreeBSD). The fxp, xl, sf, sk, ti and other drivers have been newbused and use bus master DMA; hopefully these should provide decent examples. -Bill -- ============================================================================= -Bill Paul (212) 854-6020 | System Manager, Master of Unix-Fu Work: wpaul@ctr.columbia.edu | Center for Telecommunications Research Home: wpaul@skynet.ctr.columbia.edu | Columbia University, New York City ============================================================================= "It is not I who am crazy; it is I who am mad!" - Ren Hoek, "Space Madness" ============================================================================= To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199908160835.EAA20312>