PERFORCE change 113638 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Jan 28 15:42:02 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=113638
Change 113638 by hselasky at 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[] = {
More information about the p4-projects
mailing list