[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ohci at cardbus



Below is another patch that includes the ohci at cardbus stuff talked about
in my original posting, but adds ehci support too.

To test it, you still have to add lines to your kernel config files, eg:

ohci* at cardbus?
ehci* at cardbus?

On Wed, Oct 27, 2004 at 11:45:48PM +1000, David Gwynne wrote:
> This adds support for ohci cardbus adapters. It is based on code from
> NetBSD with minor tweaks. I probably could have passed ohci_pci.c through
> sed and got the same result.

Again, I have tested this on macppc, but tests on other platforms with cardbus
support would still be welcome.

DG


Index: dev/cardbus/ehci_cardbus.c
===================================================================
RCS file: dev/cardbus/ehci_cardbus.c
diff -N dev/cardbus/ehci_cardbus.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dev/cardbus/ehci_cardbus.c	6 Dec 2004 11:45:13 -0000
@@ -0,0 +1,276 @@
+/*	$OpenBSD$ */
+/*	$NetBSD: ehci_cardbus.c,v 1.6.6.3 2004/09/21 13:27:25 skrll Exp $	*/
+
+/*
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart_(_at_)_augustsson_(_dot_)_net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef __NetBSD__
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ehci_cardbus.c,v 1.6.6.3 2004/09/21 13:27:25 skrll Exp $");
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+
+#include <machine/bus.h>
+
+#ifdef __NetBSD__
+#if defined pciinc
+#include <dev/pci/pcidevs.h>
+#endif
+#endif __NetBSD__
+
+#include <dev/cardbus/cardbusvar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/cardbus/usb_cardbus.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/ehcireg.h>
+#include <dev/usb/ehcivar.h>
+
+#ifdef EHCI_DEBUG
+#define DPRINTF(x)	if (ehcidebug) printf x
+extern int ehcidebug;
+#else
+#define DPRINTF(x)
+#endif
+
+
+#ifdef __NetBSD__
+int	ehci_cardbus_match(struct device *, struct cfdata *, void *);
+#else
+int	ehci_cardbus_match(struct device *, void *, void *);
+#endif
+void	ehci_cardbus_attach(struct device *, struct device *, void *);
+#ifdef __NetBSD__
+int	ehci_cardbus_detach(device_ptr_t, int);
+#else
+int	ehci_cardbus_detach(struct device *, int);
+#endif
+
+struct ehci_cardbus_softc {
+	ehci_softc_t		sc;
+	cardbus_chipset_tag_t	sc_cc;
+	cardbus_function_tag_t	sc_cf;
+	cardbus_devfunc_t	sc_ct;
+	void 			*sc_ih;		/* interrupt vectoring */
+};
+
+#ifdef __NetBSD__
+CFATTACH_DECL(ehci_cardbus, sizeof(struct ehci_cardbus_softc),
+    ehci_cardbus_match, ehci_cardbus_attach, ehci_cardbus_detach, ehci_activate);
+#else
+struct cfattach ehci_cardbus_ca = {
+	sizeof(struct ehci_cardbus_softc), ehci_cardbus_match,
+	    ehci_cardbus_attach, ehci_cardbus_detach, ehci_activate
+};
+#endif
+
+#define CARDBUS_INTERFACE_EHCI PCI_INTERFACE_EHCI
+#define CARDBUS_CBMEM PCI_CBMEM
+#define cardbus_findvendor pci_findvendor
+#define cardbus_devinfo pci_devinfo
+
+static TAILQ_HEAD(, usb_cardbus) ehci_cardbus_alldevs =
+	TAILQ_HEAD_INITIALIZER(ehci_cardbus_alldevs);
+
+int
+#ifdef __NetBSD__
+ehci_cardbus_match(struct device *parent, struct cfdata *match, void *aux)
+#else
+ehci_cardbus_match(struct device *parent, void *match, void *aux)
+#endif
+{
+	struct cardbus_attach_args *ca = (struct cardbus_attach_args *)aux;
+
+	if (CARDBUS_CLASS(ca->ca_class) == CARDBUS_CLASS_SERIALBUS &&
+	    CARDBUS_SUBCLASS(ca->ca_class) == CARDBUS_SUBCLASS_SERIALBUS_USB &&
+	    CARDBUS_INTERFACE(ca->ca_class) == CARDBUS_INTERFACE_EHCI)
+		return (1);
+ 
+	return (0);
+}
+
+void
+ehci_cardbus_attach(struct device *parent, struct device *self, void *aux)
+{
+	struct ehci_cardbus_softc *sc = (struct ehci_cardbus_softc *)self;
+	struct cardbus_attach_args *ca = aux;
+	cardbus_devfunc_t ct = ca->ca_ct;
+	cardbus_chipset_tag_t cc = ct->ct_cc;
+	cardbus_function_tag_t cf = ct->ct_cf;
+	cardbusreg_t csr;
+	char devinfo[256];
+	usbd_status r;
+	const char *vendor;
+	u_int ncomp;
+	const char *devname = sc->sc.sc_bus.bdev.dv_xname;
+	struct usb_cardbus *up;
+
+	cardbus_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo));
+	printf(": %s (rev. 0x%02x)\n", devinfo,
+	       CARDBUS_REVISION(ca->ca_class));
+
+	/* Map I/O registers */
+	if (Cardbus_mapreg_map(ct, CARDBUS_CBMEM, CARDBUS_MAPREG_TYPE_MEM, 0,
+			   &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) {
+		printf("%s: can't map mem space\n", devname);
+		return;
+	}
+
+	sc->sc_cc = cc;
+	sc->sc_cf = cf;
+	sc->sc_ct = ct;
+	sc->sc.sc_bus.dmatag = ca->ca_dmat;
+
+#if rbus
+#else
+XXX	(ct->ct_cf->cardbus_mem_open)(cc, 0, iob, iob + 0x40);
+#endif
+	(ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
+	(ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
+
+	/* Enable the device. */
+	csr = cardbus_conf_read(cc, cf, ca->ca_tag,
+				CARDBUS_COMMAND_STATUS_REG);
+	cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_COMMAND_STATUS_REG,
+		       csr | CARDBUS_COMMAND_MASTER_ENABLE
+			   | CARDBUS_COMMAND_MEM_ENABLE);
+
+	/* Disable interrupts, so we don't get any spurious ones. */
+	sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH);
+	DPRINTF(("%s: offs=%d\n", devname, sc->sc.sc_offs));
+	EOWRITE2(&sc->sc, EHCI_USBINTR, 0);
+
+	sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline,
+					   IPL_USB, ehci_intr, sc);
+	if (sc->sc_ih == NULL) {
+		printf("%s: couldn't establish interrupt\n", devname);
+		return;
+	}
+	printf("%s: interrupting at %d\n", devname, ca->ca_intrline);
+
+	/* Figure out vendor for root hub descriptor. */
+	vendor = cardbus_findvendor(ca->ca_id);
+	sc->sc.sc_id_vendor = CARDBUS_VENDOR(ca->ca_id);
+	if (vendor)
+		strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor));
+	else
+		snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
+		    "vendor 0x%04x", CARDBUS_VENDOR(ca->ca_id));
+	
+	/*
+	 * Find companion controllers.  According to the spec they always
+	 * have lower function numbers so they should be enumerated already.
+	 */
+	ncomp = 0;
+	TAILQ_FOREACH(up, &ehci_cardbus_alldevs, next) {
+		if (up->bus == ca->ca_bus && up->device == ca->ca_device) {
+			DPRINTF(("ehci_cardbus_attach: companion %s\n",
+				 USBDEVNAME(up->usb->bdev)));
+			sc->sc.sc_comps[ncomp++] = up->usb;
+			if (ncomp >= EHCI_COMPANION_MAX)
+				break;
+		}
+	}
+	sc->sc.sc_ncomp = ncomp;
+
+	r = ehci_init(&sc->sc);
+	if (r != USBD_NORMAL_COMPLETION) {
+		printf("%s: init failed, error=%d\n", devname, r);
+
+		/* Avoid spurious interrupts. */
+		cardbus_intr_disestablish(sc->sc_cc, sc->sc_cf, sc->sc_ih);
+		sc->sc_ih = NULL;
+
+		return;
+	}
+
+	/* Attach usb device. */
+	sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
+				       usbctlprint);
+}
+
+int
+#ifdef __NetBSD__
+ehci_cardbus_detach(device_ptr_t self, int flags)
+#else
+ehci_cardbus_detach(struct device *self, int flags)
+#endif
+{
+	struct ehci_cardbus_softc *sc = (struct ehci_cardbus_softc *)self;
+	struct cardbus_devfunc *ct = sc->sc_ct;
+	int rv;
+
+	rv = ehci_detach(&sc->sc, flags);
+	if (rv)
+		return (rv);
+	if (sc->sc_ih != NULL) {
+		cardbus_intr_disestablish(sc->sc_cc, sc->sc_cf, sc->sc_ih);
+		sc->sc_ih = NULL;
+	}
+	if (sc->sc.sc_size) {
+		Cardbus_mapreg_unmap(ct, CARDBUS_CBMEM, sc->sc.iot,
+		    sc->sc.ioh, sc->sc.sc_size);
+		sc->sc.sc_size = 0;
+	}
+	return (0);
+}
+
+void
+usb_cardbus_add(struct usb_cardbus *up, struct cardbus_attach_args *ca, struct usbd_bus *bu)
+{
+	TAILQ_INSERT_TAIL(&ehci_cardbus_alldevs, up, next);
+	up->bus = ca->ca_bus;
+	up->device = ca->ca_device;
+	up->function = ca->ca_function;
+	up->usb = bu;
+}
+
+void
+usb_cardbus_rem(struct usb_cardbus *up)
+{
+	TAILQ_REMOVE(&ehci_cardbus_alldevs, up, next);
+}
Index: dev/cardbus/files.cardbus
===================================================================
RCS file: /cvs/openbsd/src/sys/dev/cardbus/files.cardbus,v
retrieving revision 1.10
diff -u -p -r1.10 files.cardbus
--- dev/cardbus/files.cardbus	20 Nov 2004 20:07:54 -0000	1.10
+++ dev/cardbus/files.cardbus	6 Dec 2004 11:45:13 -0000
@@ -62,10 +62,16 @@ attach	atw at cardbus with atw_cardbus
 file	dev/cardbus/if_atw_cardbus.c		atw_cardbus
 
 #
+# EHCI USB controller
+#
+attach	ehci at cardbus with ehci_cardbus
+file	dev/cardbus/ehci_cardbus.c		ehci_cardbus needs-flag
+
+#
 # OHCI USB controller
 #
-#attach	ohci at cardbus with ohci_cardbus
-#file	dev/cardbus/ohci_cardbus.c		ohci_cardbus
+attach	ohci at cardbus with ohci_cardbus
+file	dev/cardbus/ohci_cardbus.c		ohci_cardbus
 
 #
 # Adaptec ADP-1480 SCSI controller
Index: dev/cardbus/ohci_cardbus.c
===================================================================
RCS file: dev/cardbus/ohci_cardbus.c
diff -N dev/cardbus/ohci_cardbus.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dev/cardbus/ohci_cardbus.c	6 Dec 2004 11:45:13 -0000
@@ -0,0 +1,247 @@
+/*	$OpenBSD$ */
+/*	$NetBSD: ohci_cardbus.c,v 1.19 2004/08/02 19:14:28 mycroft Exp $	*/
+
+/*
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart_(_at_)_augustsson_(_dot_)_net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * USB Open Host Controller driver.
+ *
+ * OHCI spec: http://www.intel.com/design/usb/ohci11d.pdf
+ * USB spec: http://www.teleport.com/cgi-bin/mailmerge.cgi/~usb/cgiform.tpl
+ */
+
+#include <sys/cdefs.h>
+#ifdef __NetBSD__
+__KERNEL_RCSID(0, "$NetBSD: ohci_cardbus.c,v 1.19 2004/08/02 19:14:28 mycroft Exp $");
+#endif
+
+#include "ehci_cardbus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+
+#include <machine/bus.h>
+
+#include <dev/cardbus/cardbusvar.h>
+#include <dev/pci/pcidevs.h>
+
+#if NEHCI_CARDBUS > 0
+#include <dev/cardbus/usb_cardbus.h>
+#endif
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usb_mem.h>
+
+#include <dev/usb/ohcireg.h>
+#include <dev/usb/ohcivar.h>
+
+#ifdef __NetBSD__
+int	ohci_cardbus_match(struct device *, struct cfdata *, void *);
+#else
+int	ohci_cardbus_match(struct device *, void *, void *);
+#endif
+void	ohci_cardbus_attach(struct device *, struct device *, void *);
+#ifdef __NetBSD__
+int	ohci_cardbus_detach(device_ptr_t, int);
+#else
+int	ohci_cardbus_detach(struct device *, int);
+#endif
+
+struct ohci_cardbus_softc {
+	ohci_softc_t		sc;
+#if NEHCI_CARDBUS > 0
+	struct usb_cardbus	sc_cardbus;
+#endif
+	cardbus_chipset_tag_t	sc_cc;
+	cardbus_function_tag_t	sc_cf;
+	cardbus_devfunc_t	sc_ct;
+	void 			*sc_ih;		/* interrupt vectoring */
+};
+
+#ifdef __NetBSD__
+CFATTACH_DECL(ohci_cardbus, sizeof(struct ohci_cardbus_softc),
+    ohci_cardbus_match, ohci_cardbus_attach, ohci_cardbus_detach, ohci_activate);
+#else
+struct cfattach ohci_cardbus_ca = {
+	sizeof(struct ohci_cardbus_softc), ohci_cardbus_match,
+	    ohci_cardbus_attach, ohci_cardbus_detach, ohci_activate
+};
+#endif
+
+#define CARDBUS_INTERFACE_OHCI PCI_INTERFACE_OHCI
+#define CARDBUS_CBMEM PCI_CBMEM
+#define cardbus_findvendor pci_findvendor
+#define cardbus_devinfo pci_devinfo
+
+int
+#ifdef __NetBSD__
+ohci_cardbus_match(struct device *parent, struct cfdata *match, void *aux)
+#else
+ohci_cardbus_match(struct device *parent, void *match, void *aux)
+#endif
+{
+	struct cardbus_attach_args *ca = (struct cardbus_attach_args *)aux;
+
+	if (CARDBUS_CLASS(ca->ca_class) == CARDBUS_CLASS_SERIALBUS &&
+	    CARDBUS_SUBCLASS(ca->ca_class) == CARDBUS_SUBCLASS_SERIALBUS_USB &&
+	    CARDBUS_INTERFACE(ca->ca_class) == CARDBUS_INTERFACE_OHCI)
+		return (1);
+ 
+	return (0);
+}
+
+void
+ohci_cardbus_attach(struct device *parent, struct device *self, void *aux)
+{
+	struct ohci_cardbus_softc *sc = (struct ohci_cardbus_softc *)self;
+	struct cardbus_attach_args *ca = aux;
+	cardbus_devfunc_t ct = ca->ca_ct;
+	cardbus_chipset_tag_t cc = ct->ct_cc;
+	cardbus_function_tag_t cf = ct->ct_cf;
+	cardbusreg_t csr;
+	usbd_status r;
+	const char *vendor;
+	const char *devname = sc->sc.sc_bus.bdev.dv_xname;
+
+#if defined(__NetBSD__)
+	char devinfo[256];
+	cardbus_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo));
+	printf(": %s (rev. 0x%02x)\n", devinfo,
+	    CARDBUS_REVISION(ca->ca_class));
+#endif
+
+	/* Map I/O registers */
+	if (Cardbus_mapreg_map(ct, CARDBUS_CBMEM, CARDBUS_MAPREG_TYPE_MEM, 0,
+			   &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) {
+		printf("%s: can't map mem space\n", devname);
+		return;
+	}
+
+	/* Disable interrupts, so we don't get any spurious ones. */
+	bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
+			  OHCI_MIE);
+
+	sc->sc_cc = cc;
+	sc->sc_cf = cf;
+	sc->sc_ct = ct;
+	sc->sc.sc_bus.dmatag = ca->ca_dmat;
+
+#if rbus
+#else
+XXX	(ct->ct_cf->cardbus_mem_open)(cc, 0, iob, iob + 0x40);
+#endif
+	(ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
+	(ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
+
+	/* Enable the device. */
+	csr = cardbus_conf_read(cc, cf, ca->ca_tag,
+				CARDBUS_COMMAND_STATUS_REG);
+	cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_COMMAND_STATUS_REG,
+		       csr | CARDBUS_COMMAND_MASTER_ENABLE
+			   | CARDBUS_COMMAND_MEM_ENABLE);
+
+	sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline,
+					   IPL_USB, ohci_intr, sc);
+	if (sc->sc_ih == NULL) {
+		printf("%s: couldn't establish interrupt\n", devname);
+		return;
+	}
+	printf(": irq %d", ca->ca_intrline);
+
+	/* Figure out vendor for root hub descriptor. */
+	vendor = cardbus_findvendor(ca->ca_id);
+	sc->sc.sc_id_vendor = CARDBUS_VENDOR(ca->ca_id);
+	if (vendor)
+		strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor));
+	else
+		snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
+		    "vendor 0x%04x", CARDBUS_VENDOR(ca->ca_id));
+	
+	r = ohci_init(&sc->sc);
+	if (r != USBD_NORMAL_COMPLETION) {
+		printf("%s: init failed, error=%d\n", devname, r);
+
+		/* Avoid spurious interrupts. */
+		cardbus_intr_disestablish(sc->sc_cc, sc->sc_cf, sc->sc_ih);
+		sc->sc_ih = 0;
+
+		return;
+	}
+
+#if NEHCI_CARDBUS > 0
+	usb_cardbus_add(&sc->sc_cardbus, ca, &sc->sc.sc_bus);
+#endif
+
+	/* Attach usb device. */
+	sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
+				       usbctlprint);
+}
+
+int
+#ifdef __NetBSD__
+ohci_cardbus_detach(device_ptr_t self, int flags)
+#else
+ohci_cardbus_detach(struct device *self, int flags)
+#endif
+{
+	struct ohci_cardbus_softc *sc = (struct ohci_cardbus_softc *)self;
+	struct cardbus_devfunc *ct = sc->sc_ct;
+	int rv;
+
+	rv = ohci_detach(&sc->sc, flags);
+	if (rv)
+		return (rv);
+	if (sc->sc_ih != NULL) {
+		cardbus_intr_disestablish(sc->sc_cc, sc->sc_cf, sc->sc_ih);
+		sc->sc_ih = NULL;
+	}
+	if (sc->sc.sc_size) {
+		Cardbus_mapreg_unmap(ct, CARDBUS_CBMEM, sc->sc.iot,
+		    sc->sc.ioh, sc->sc.sc_size);
+		sc->sc.sc_size = 0;
+	}
+#if NEHCI_CARDBUS > 0
+	usb_cardbus_rem(&sc->sc_cardbus);
+#endif
+	return (0);
+}
Index: dev/cardbus/usb_cardbus.h
===================================================================
RCS file: dev/cardbus/usb_cardbus.h
diff -N dev/cardbus/usb_cardbus.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dev/cardbus/usb_cardbus.h	6 Dec 2004 11:45:13 -0000
@@ -0,0 +1,55 @@
+/*	$OpenBSD$ */
+/*	$NetBSD: usb_cardbus.h,v 1.1.6.1 2002/01/10 19:53:47 thorpej Exp $	*/
+
+/*
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart_(_at_)_augustsson_(_dot_)_net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * EHCI controllers need a way to find their compainion controllers
+ * so we keep track of them as we attach.
+ */
+
+struct usb_cardbus {
+	TAILQ_ENTRY(usb_cardbus) next;
+	u_int		bus;
+	u_int		device;
+	u_int		function;
+	struct usbd_bus *usb;
+};
+void usb_cardbus_add(struct usb_cardbus *, struct cardbus_attach_args *,
+		     struct usbd_bus *);
+void usb_cardbus_rem(struct usb_cardbus *);
Index: dev/usb/usb.c
===================================================================
RCS file: /cvs/openbsd/src/sys/dev/usb/usb.c,v
retrieving revision 1.29
diff -u -p -r1.29 usb.c
--- dev/usb/usb.c	8 Jul 2004 22:18:44 -0000	1.29
+++ dev/usb/usb.c	6 Dec 2004 11:45:14 -0000
@@ -234,7 +234,10 @@ USB_ATTACH(usb)
 		sc->sc_bus->use_polling--;
 
 	config_pending_incr();
-	usb_kthread_create(usb_create_event_thread, sc);
+	if (cold)
+		usb_kthread_create(usb_create_event_thread, sc);
+	else
+		usb_create_event_thread(sc);
 
 	USB_ATTACH_SUCCESS_RETURN;
 }



Visit your host, monkey.org