Date: Sun, 28 Jan 2007 15:42:01 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 113638 for review Message-ID: <200701281542.l0SFg14Q033807@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=113638 Change 113638 by hselasky@hselasky_mini_itx on 2007/01/28 15:40:59 ARM compilation fix and updates with regard to USB. Affected files ... .. //depot/projects/usb/src/sys/arm/at91/ohci_atmelarm.c#2 edit Differences ... ==== //depot/projects/usb/src/sys/arm/at91/ohci_atmelarm.c#2 (text) ==== @@ -25,34 +25,31 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD: src/sys/arm/at91/ohci_atmelarm.c,v 1.1 2006/03/18 01:45:29 imp Exp $"); +#include "opt_bus.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> +#include <sys/endian.h> #include <sys/queue.h> -#include <machine/bus.h> -#include <sys/rman.h> -#include <machine/resource.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <dev/usb/usb_port.h> #include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdivar.h> -#include <dev/usb/usb_mem.h> +#include <dev/usb/usb_subr.h> +#include <dev/usb/ohci.h> -#include <dev/usb/ohcireg.h> -#include <dev/usb/ohcivar.h> - #include <arm/at91/at91_pmcvar.h> #define MEM_RID 0 -static int ohci_atmelarm_attach(device_t dev); -static int ohci_atmelarm_detach(device_t dev); +static device_probe_t ohci_atmelarm_probe; +static device_attach_t ohci_atmelarm_attach; +static device_detach_t ohci_atmelarm_detach; -struct at91_ohci_softc -{ - struct ohci_softc sc_ohci; +struct at91_ohci_softc { + struct ohci_softc sc_ohci; /* must be first */ struct at91_pmc_clock *iclk; struct at91_pmc_clock *fclk; }; @@ -60,7 +57,7 @@ static int ohci_atmelarm_probe(device_t dev) { - device_set_desc(dev, "AT91 integrated ohci controller"); + device_set_desc(dev, "AT91 integrated OHCI controller"); return (BUS_PROBE_DEFAULT); } @@ -71,74 +68,110 @@ int err; int rid; - - sc->iclk = at91_pmc_clock_ref("ohci_clk"); + if (sc == NULL) { + return ENXIO; + } + + sc->sc_ohci.sc_hw_ptr = + usbd_mem_alloc(device_get_dma_tag(dev), + &(sc->sc_ohci.sc_hw_page), sizeof(*(sc->sc_ohci.sc_hw_ptr)), + LOG2(OHCI_HCCA_ALIGN)); + + if (sc->sc_ohci.sc_hw_ptr == NULL) { + return ENXIO; + } + + sc->iclk = at91_pmc_clock_ref("ohci_clk"); sc->fclk = at91_pmc_clock_ref("uhpck"); + mtx_init(&(sc->sc_ohci.sc_bus.mtx), "usb lock", + NULL, MTX_DEF|MTX_RECURSE); + + sc->sc_ohci.sc_dev = dev; + + sc->sc_ohci.sc_bus.dma_tag = usbd_dma_tag_alloc(device_get_dma_tag(dev), + USB_PAGE_SIZE, USB_PAGE_SIZE); + + if (sc->sc_ohci.sc_bus.dma_tag == NULL) { + goto error; + } + rid = MEM_RID; - sc->sc_ohci.io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->sc_ohci.io_res == NULL) { + sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &rid, RF_ACTIVE); + + if (!(sc->sc_ohci.sc_io_res)) { err = ENOMEM; goto error; } - sc->sc_ohci.iot = rman_get_bustag(sc->sc_ohci.io_res); - sc->sc_ohci.ioh = rman_get_bushandle(sc->sc_ohci.io_res); + sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res); + sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res); + sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res); rid = 0; - sc->sc_ohci.irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (sc->sc_ohci.irq_res == NULL) { - err = ENOMEM; + if (!(sc->sc_ohci.sc_irq_res)) { goto error; } + sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usb", -1); - if (sc->sc_ohci.sc_bus.bdev == NULL) { - err = ENOMEM; + if (!(sc->sc_ohci.sc_bus.bdev)) { goto error; } - device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus); + + device_set_ivars(sc->sc_ohci.sc_bus.bdev, &(sc->sc_ohci.sc_bus)); + device_set_softc(sc->sc_ohci.sc_bus.bdev, &(sc->sc_ohci.sc_bus)); + + strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor)); - err = bus_setup_intr(dev, sc->sc_ohci.irq_res, INTR_TYPE_BIO, ohci_intr, sc, - &sc->sc_ohci.ih); + err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO|INTR_MPSAFE, + (void *)(void *)ohci_interrupt, sc, &(sc->sc_ohci.sc_intr_hdl)); if (err) { - err = ENXIO; + sc->sc_ohci.sc_intr_hdl = NULL; goto error; } - strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor)); /* * turn on the clocks from the AT91's point of view. Keep the unit in reset. */ -// bus_space_write_4(sc->sc_ohci.iot, sc->sc_ohci.ioh, OHCI_CONTROL, 0); +// bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, +// OHCI_CONTROL, 0); at91_pmc_clock_enable(sc->iclk); at91_pmc_clock_enable(sc->fclk); - bus_space_write_4(sc->sc_ohci.iot, sc->sc_ohci.ioh, OHCI_CONTROL, 0); + bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, + OHCI_CONTROL, 0); - err = ohci_init(&sc->sc_ohci); + err = ohci_init(&(sc->sc_ohci)); if (!err) { - sc->sc_ohci.sc_flags |= OHCI_SCFLG_DONEINIT; err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev); } -error:; if (err) { - ohci_atmelarm_detach(dev); - return (err); + goto error; } - return (err); + return 0; + + error: + ohci_atmelarm_detach(dev); + return ENXIO; } static int ohci_atmelarm_detach(device_t dev) { struct at91_ohci_softc *sc = device_get_softc(dev); + int err; - if (sc->sc_ohci.sc_flags & OHCI_SCFLG_DONEINIT) { - ohci_detach(&sc->sc_ohci, 0); - sc->sc_ohci.sc_flags &= ~OHCI_SCFLG_DONEINIT; + if (sc->sc_ohci.sc_bus.bdev) { + device_detach(sc->sc_ohci.sc_bus.bdev); + device_delete_child(dev, sc->sc_ohci.sc_bus.bdev); + sc->sc_ohci.sc_bus.bdev = NULL; } + /* during module unload there are lots of children leftover */ + device_delete_all_children(dev); + /* * Put the controller into reset, then disable clocks and do * the MI tear down. We have to disable the clocks/hardware @@ -148,31 +181,44 @@ * clocks after we disable them, so the system could, in * theory, reuse them. */ - bus_space_write_4(sc->sc_ohci.iot, sc->sc_ohci.ioh, OHCI_CONTROL, 0); + bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, + OHCI_CONTROL, 0); + at91_pmc_clock_disable(sc->fclk); at91_pmc_clock_disable(sc->iclk); at91_pmc_clock_deref(sc->fclk); at91_pmc_clock_deref(sc->iclk); - if (sc->sc_ohci.ih) { - bus_teardown_intr(dev, sc->sc_ohci.irq_res, sc->sc_ohci.ih); - sc->sc_ohci.ih = NULL; + if (sc->sc_ohci.sc_irq_res && sc->sc_ohci.sc_intr_hdl) { + /* only call ohci_detach() + * after ohci_init() + */ + ohci_detach(&(sc->sc_ohci)); + + err = bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res, sc->sc_ohci.sc_intr_hdl); + sc->sc_ohci.sc_intr_hdl = NULL; } - if (sc->sc_ohci.sc_bus.bdev) { - device_delete_child(dev, sc->sc_ohci.sc_bus.bdev); - sc->sc_ohci.sc_bus.bdev = NULL; + + if (sc->sc_ohci.sc_irq_res) { + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.sc_irq_res); + sc->sc_ohci.sc_irq_res = NULL; } - if (sc->sc_ohci.irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.irq_res); - sc->sc_ohci.irq_res = NULL; + + if (sc->sc_ohci.sc_io_res) { + bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID, + sc->sc_ohci.sc_io_res); + sc->sc_ohci.sc_io_res = NULL; } - if (sc->sc_ohci.io_res) { - bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID, sc->sc_ohci.io_res); - sc->sc_ohci.io_res = NULL; - sc->sc_ohci.iot = 0; - sc->sc_ohci.ioh = 0; + + if (sc->sc_ohci.sc_bus.dma_tag) { + usbd_dma_tag_free(sc->sc_ohci.sc_bus.dma_tag); } - return (0); + + mtx_destroy(&(sc->sc_ohci.sc_bus.mtx)); + + usbd_mem_free(&(sc->sc_ohci.sc_hw_page)); + + return 0; } static device_method_t ohci_methods[] = {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701281542.l0SFg14Q033807>