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