This source file includes following definitions.
- ohci_pci_match
- ohci_pci_attach
- ohci_pci_attach_deferred
- ohci_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
42
43
44
45
46
47
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
51 #include <sys/device.h>
52 #include <sys/proc.h>
53 #include <sys/queue.h>
54
55 #include <machine/bus.h>
56
57 #include <dev/pci/pcivar.h>
58
59 #include <dev/usb/usb.h>
60 #include <dev/usb/usbdi.h>
61 #include <dev/usb/usbdivar.h>
62 #include <dev/usb/usb_mem.h>
63
64 #include <dev/usb/ohcireg.h>
65 #include <dev/usb/ohcivar.h>
66
67 int ohci_pci_match(struct device *, void *, void *);
68 void ohci_pci_attach(struct device *, struct device *, void *);
69 void ohci_pci_attach_deferred(struct device *);
70 int ohci_pci_detach(struct device *, int);
71
72 struct ohci_pci_softc {
73 ohci_softc_t sc;
74 pci_chipset_tag_t sc_pc;
75 void *sc_ih;
76 };
77
78 struct cfattach ohci_pci_ca = {
79 sizeof(struct ohci_pci_softc), ohci_pci_match, ohci_pci_attach,
80 ohci_pci_detach, ohci_activate
81 };
82
83 int
84 ohci_pci_match(struct device *parent, void *match, void *aux)
85 {
86 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
87
88 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SERIALBUS &&
89 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SERIALBUS_USB &&
90 PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_OHCI)
91 return (1);
92
93 return (0);
94 }
95
96 void
97 ohci_pci_attach(struct device *parent, struct device *self, void *aux)
98 {
99 struct ohci_pci_softc *sc = (struct ohci_pci_softc *)self;
100 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
101 pci_chipset_tag_t pc = pa->pa_pc;
102 char const *intrstr;
103 pci_intr_handle_t ih;
104 int s;
105 const char *vendor;
106 char *devname = sc->sc.sc_bus.bdev.dv_xname;
107
108
109 if (pci_mapreg_map(pa, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0,
110 &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size, 0)) {
111 printf(": can't map mem space\n");
112 return;
113 }
114
115
116 sc->sc.sc_intre = bus_space_read_4(sc->sc.iot, sc->sc.ioh,
117 OHCI_INTERRUPT_ENABLE);
118
119
120 bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE,
121 OHCI_MIE);
122
123 sc->sc_pc = pc;
124 sc->sc.sc_bus.dmatag = pa->pa_dmat;
125
126 bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size,
127 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
128 bus_space_write_4(sc->sc.iot, sc->sc.ioh,
129 OHCI_INTERRUPT_DISABLE, OHCI_MIE);
130
131 s = splusb();
132
133 if (pci_intr_map(pa, &ih)) {
134 printf(": couldn't map interrupt\n");
135 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
136 splx(s);
137 return;
138 }
139
140 intrstr = pci_intr_string(pc, ih);
141 sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, ohci_intr, sc, devname);
142 if (sc->sc_ih == NULL) {
143 printf(": couldn't establish interrupt");
144 if (intrstr != NULL)
145 printf(" at %s", intrstr);
146 printf("\n");
147 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
148 splx(s);
149 return;
150 }
151 printf(": %s", intrstr);
152
153
154 vendor = pci_findvendor(pa->pa_id);
155 sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id);
156 if (vendor)
157 strlcpy(sc->sc.sc_vendor, vendor, sizeof (sc->sc.sc_vendor));
158 else
159 snprintf(sc->sc.sc_vendor, sizeof (sc->sc.sc_vendor),
160 "vendor 0x%04x", PCI_VENDOR(pa->pa_id));
161
162
163 if (ohci_checkrev(&sc->sc) != USBD_NORMAL_COMPLETION ||
164 ohci_handover(&sc->sc) != USBD_NORMAL_COMPLETION) {
165 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
166 splx(s);
167 return;
168 }
169
170
171 sc->sc.sc_dying = 1;
172
173 config_defer(self, ohci_pci_attach_deferred);
174
175 splx(s);
176
177 return;
178 }
179
180 void
181 ohci_pci_attach_deferred(struct device *self)
182 {
183 struct ohci_pci_softc *sc = (struct ohci_pci_softc *)self;
184 usbd_status r;
185 int s;
186
187 s = splusb();
188
189 sc->sc.sc_dying = 0;
190
191 r = ohci_init(&sc->sc);
192 if (r != USBD_NORMAL_COMPLETION) {
193 printf("%s: init failed, error=%d\n",
194 sc->sc.sc_bus.bdev.dv_xname, r);
195 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
196 splx(s);
197 return;
198 }
199
200 sc->sc.sc_powerhook = powerhook_establish(ohci_power, &sc->sc);
201 if (sc->sc.sc_powerhook == NULL)
202 printf("%s: unable to establish powerhook\n",
203 sc->sc.sc_bus.bdev.dv_xname);
204
205 splx(s);
206
207
208 sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
209 usbctlprint);
210 }
211
212 int
213 ohci_pci_detach(struct device *self, int flags)
214 {
215 struct ohci_pci_softc *sc = (struct ohci_pci_softc *)self;
216 int rv;
217
218 rv = ohci_detach(&sc->sc, flags);
219 if (rv)
220 return (rv);
221
222 if (sc->sc.sc_powerhook != NULL)
223 powerhook_disestablish(sc->sc.sc_powerhook);
224
225 if (sc->sc_ih != NULL) {
226 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
227 sc->sc_ih = NULL;
228 }
229 if (sc->sc.sc_size) {
230 bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
231 sc->sc.sc_size = 0;
232 }
233 return (0);
234 }