This source file includes following definitions.
- uhci_pci_match
- uhci_pci_attach
- uhci_pci_attach_deferred
- uhci_pci_detach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/device.h>
45 #include <sys/proc.h>
46 #include <sys/queue.h>
47
48 #include <machine/bus.h>
49
50 #include <dev/pci/pcivar.h>
51
52 #include <dev/usb/usb.h>
53 #include <dev/usb/usbdi.h>
54 #include <dev/usb/usbdivar.h>
55 #include <dev/usb/usb_mem.h>
56
57 #include <dev/usb/uhcireg.h>
58 #include <dev/usb/uhcivar.h>
59
60 int uhci_pci_match(struct device *, void *, void *);
61 void uhci_pci_attach(struct device *, struct device *, void *);
62 void uhci_pci_attach_deferred(struct device *);
63 int uhci_pci_detach(struct device *, int);
64
65 struct uhci_pci_softc {
66 uhci_softc_t sc;
67 pci_chipset_tag_t sc_pc;
68 pcitag_t sc_tag;
69 void *sc_ih;
70 };
71
72 struct cfattach uhci_pci_ca = {
73 sizeof(struct uhci_pci_softc), uhci_pci_match, uhci_pci_attach,
74 uhci_pci_detach, uhci_activate
75 };
76
77 int
78 uhci_pci_match(struct device *parent, void *match, void *aux)
79 {
80 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
81
82 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SERIALBUS &&
83 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SERIALBUS_USB &&
84 PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_UHCI)
85 return (1);
86
87 return (0);
88 }
89
90 void
91 uhci_pci_attach(struct device *parent, struct device *self, void *aux)
92 {
93 struct uhci_pci_softc *sc = (struct uhci_pci_softc *)self;
94 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
95 pci_chipset_tag_t pc = pa->pa_pc;
96 pcitag_t tag = pa->pa_tag;
97 char const *intrstr;
98 pci_intr_handle_t ih;
99 const char *vendor;
100 char *devname = sc->sc.sc_bus.bdev.dv_xname;
101 int s;
102
103 #if defined(__NetBSD__)
104 char devinfo[256];
105
106 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
107 printf(": %s (rev. 0x%02x)", devinfo, PCI_REVISION(pa->pa_class));
108 #endif
109
110
111 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
112 &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size, 0)) {
113 printf(": can't map i/o space\n");
114 return;
115 }
116
117
118
119 s = splhardusb();
120 bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
121
122 sc->sc_pc = pc;
123 sc->sc_tag = tag;
124 sc->sc.sc_bus.dmatag = pa->pa_dmat;
125
126
127 if (pci_intr_map(pa, &ih)) {
128 printf(": couldn't map interrupt\n");
129 goto unmap_ret;
130 }
131 intrstr = pci_intr_string(pc, ih);
132 sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, uhci_intr, sc,
133 devname);
134 if (sc->sc_ih == NULL) {
135 printf(": couldn't establish interrupt");
136 if (intrstr != NULL)
137 printf(" at %s", intrstr);
138 printf("\n");
139 goto unmap_ret;
140 }
141 printf(": %s\n", intrstr);
142
143
144 pci_conf_write(pc, tag, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN);
145
146 switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) {
147 case PCI_USBREV_PRE_1_0:
148 sc->sc.sc_bus.usbrev = USBREV_PRE_1_0;
149 break;
150 case PCI_USBREV_1_0:
151 sc->sc.sc_bus.usbrev = USBREV_1_0;
152 break;
153 case PCI_USBREV_1_1:
154 sc->sc.sc_bus.usbrev = USBREV_1_1;
155 break;
156 default:
157 sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
158 break;
159 }
160
161 uhci_run(&sc->sc, 0);
162
163 bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size,
164 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
165 bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
166
167
168 vendor = pci_findvendor(pa->pa_id);
169 sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id);
170 if (vendor)
171 strlcpy(sc->sc.sc_vendor, vendor, sizeof (sc->sc.sc_vendor));
172 else
173 snprintf(sc->sc.sc_vendor, sizeof (sc->sc.sc_vendor),
174 "vendor 0x%04x", PCI_VENDOR(pa->pa_id));
175
176 config_defer(self, uhci_pci_attach_deferred);
177
178
179 sc->sc.sc_dying = 1;
180
181 splx(s);
182
183 return;
184
185 unmap_ret:
186 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
187 splx(s);
188 }
189
190 void
191 uhci_pci_attach_deferred(struct device *self)
192 {
193 struct uhci_pci_softc *sc = (struct uhci_pci_softc *)self;
194 char *devname = sc->sc.sc_bus.bdev.dv_xname;
195 usbd_status r;
196 int s;
197
198 s = splhardusb();
199
200 sc->sc.sc_dying = 0;
201 r = uhci_init(&sc->sc);
202 if (r != USBD_NORMAL_COMPLETION) {
203 printf("%s: init failed, error=%d\n", devname, r);
204 goto unmap_ret;
205 }
206 splx(s);
207
208
209 sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
210 usbctlprint);
211
212 return;
213
214 unmap_ret:
215 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
216 splx(s);
217 }
218
219 int
220 uhci_pci_detach(struct device *self, int flags)
221 {
222 struct uhci_pci_softc *sc = (struct uhci_pci_softc *)self;
223 int rv;
224
225 rv = uhci_detach(&sc->sc, flags);
226 if (rv)
227 return (rv);
228 if (sc->sc_ih != NULL) {
229 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
230 sc->sc_ih = NULL;
231 }
232 if (sc->sc.sc_size) {
233 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
234 sc->sc.sc_size = 0;
235 }
236
237 return (0);
238 }