Annotation of sys/dev/cardbus/uhci_cardbus.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: uhci_cardbus.c,v 1.5 2006/10/12 16:35:52 grange Exp $ */
2:
3: /*
4: * Copyright (c) 1998 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Lennart Augustsson (lennart@augustsson.net) at
9: * Carlstedt Research & Technology.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
38: */
39:
40: #include <sys/param.h>
41: #include <sys/systm.h>
42: #include <sys/kernel.h>
43: #include <sys/device.h>
44: #include <sys/proc.h>
45:
46: #include <machine/bus.h>
47:
48: #include <dev/cardbus/cardbusvar.h>
49: #include <dev/pci/pcidevs.h>
50:
51: #include <dev/usb/usb.h>
52: #include <dev/usb/usbdi.h>
53: #include <dev/usb/usbdivar.h>
54: #include <dev/usb/usb_mem.h>
55:
56: #include <dev/usb/uhcireg.h>
57: #include <dev/usb/uhcivar.h>
58:
59: int uhci_cardbus_match(struct device *, void *, void *);
60: void uhci_cardbus_attach(struct device *, struct device *, void *);
61: int uhci_cardbus_detach(struct device *, int);
62:
63: struct uhci_cardbus_softc {
64: uhci_softc_t sc;
65: cardbus_chipset_tag_t sc_cc;
66: cardbus_function_tag_t sc_cf;
67: cardbus_devfunc_t sc_ct;
68: void *sc_ih; /* interrupt vectoring */
69: };
70:
71: struct cfattach uhci_cardbus_ca = {
72: sizeof(struct uhci_cardbus_softc), uhci_cardbus_match,
73: uhci_cardbus_attach, uhci_cardbus_detach, uhci_activate
74: };
75:
76: #define CARDBUS_INTERFACE_UHCI PCI_INTERFACE_UHCI
77: #define cardbus_findvendor pci_findvendor
78: #define cardbus_devinfo pci_devinfo
79:
80: int
81: uhci_cardbus_match(struct device *parent, void *match, void *aux)
82: {
83: struct cardbus_attach_args *ca = (struct cardbus_attach_args *)aux;
84:
85: if (CARDBUS_CLASS(ca->ca_class) == CARDBUS_CLASS_SERIALBUS &&
86: CARDBUS_SUBCLASS(ca->ca_class) == CARDBUS_SUBCLASS_SERIALBUS_USB &&
87: CARDBUS_INTERFACE(ca->ca_class) == CARDBUS_INTERFACE_UHCI)
88: return (1);
89:
90: return (0);
91: }
92:
93: void
94: uhci_cardbus_attach(struct device *parent, struct device *self, void *aux)
95: {
96: struct uhci_cardbus_softc *sc = (struct uhci_cardbus_softc *)self;
97: struct cardbus_attach_args *ca = aux;
98: cardbus_devfunc_t ct = ca->ca_ct;
99: cardbus_chipset_tag_t cc = ct->ct_cc;
100: cardbus_function_tag_t cf = ct->ct_cf;
101: cardbusreg_t csr;
102: char devinfo[256];
103: usbd_status r;
104: const char *vendor;
105: const char *devname = sc->sc.sc_bus.bdev.dv_xname;
106:
107: cardbus_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo));
108: printf(" %s", devinfo);
109:
110: /* Map I/O registers */
111: if (Cardbus_mapreg_map(ct, PCI_CBIO, CARDBUS_MAPREG_TYPE_IO, 0,
112: &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) {
113: printf("%s: can't map io space\n", devname);
114: return;
115: }
116:
117: /* Disable interrupts, so we don't get any spurious ones. */
118: bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
119:
120: sc->sc_cc = cc;
121: sc->sc_cf = cf;
122: sc->sc_ct = ct;
123: sc->sc.sc_bus.dmatag = ca->ca_dmat;
124:
125: (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE);
126: (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
127:
128: /* Enable the device. */
129: csr = cardbus_conf_read(cc, cf, ca->ca_tag,
130: CARDBUS_COMMAND_STATUS_REG);
131: cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_COMMAND_STATUS_REG,
132: csr | CARDBUS_COMMAND_MASTER_ENABLE
133: | CARDBUS_COMMAND_IO_ENABLE);
134:
135: sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline,
136: IPL_USB, uhci_intr, sc, devname);
137: if (sc->sc_ih == NULL) {
138: printf("%s: couldn't establish interrupt\n", devname);
139: return;
140: }
141: printf(": irq %d\n", ca->ca_intrline);
142:
143: /* Set LEGSUP register to its default value. */
144: cardbus_conf_write(cc, cf, ca->ca_tag, PCI_LEGSUP,
145: PCI_LEGSUP_USBPIRQDEN);
146:
147: switch(cardbus_conf_read(cc, cf, ca->ca_tag, PCI_USBREV) & PCI_USBREV_MASK) {
148: case PCI_USBREV_PRE_1_0:
149: sc->sc.sc_bus.usbrev = USBREV_PRE_1_0;
150: break;
151: case PCI_USBREV_1_0:
152: sc->sc.sc_bus.usbrev = USBREV_1_0;
153: break;
154: case PCI_USBREV_1_1:
155: sc->sc.sc_bus.usbrev = USBREV_1_1;
156: break;
157: default:
158: sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
159: break;
160: }
161:
162: uhci_run(&sc->sc, 0); /* stop the controller */
163: /* disable interrupts */
164: bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size,
165: BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
166: bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
167:
168: /* Figure out vendor for root hub descriptor. */
169: vendor = cardbus_findvendor(ca->ca_id);
170: sc->sc.sc_id_vendor = CARDBUS_VENDOR(ca->ca_id);
171: if (vendor)
172: strlcpy(sc->sc.sc_vendor, vendor, sizeof (sc->sc.sc_vendor));
173: else
174: snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
175: "vendor 0x%04x", CARDBUS_VENDOR(ca->ca_id));
176:
177: r = uhci_init(&sc->sc);
178: if (r != USBD_NORMAL_COMPLETION) {
179: printf("%s: init failed, error=%d\n", devname, r);
180: bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
181: return;
182: }
183:
184: /* Attach usb device. */
185: sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
186: usbctlprint);
187: }
188:
189: int
190: uhci_cardbus_detach(struct device *self, int flags)
191: {
192: struct uhci_cardbus_softc *sc = (struct uhci_cardbus_softc *)self;
193: struct cardbus_devfunc *ct = sc->sc_ct;
194: int rv;
195:
196: rv = uhci_detach(&sc->sc, flags);
197: if (rv)
198: return (rv);
199:
200: if (sc->sc_ih != NULL) {
201: cardbus_intr_disestablish(sc->sc_cc, sc->sc_cf, sc->sc_ih);
202: sc->sc_ih = NULL;
203: }
204:
205: if (sc->sc.sc_size) {
206: Cardbus_mapreg_unmap(ct, PCI_CBIO, sc->sc.iot,
207: sc->sc.ioh, sc->sc.sc_size);
208: sc->sc.sc_size = 0;
209: }
210:
211: return (0);
212: }
CVSweb