This source file includes following definitions.
- ehci_cardbus_match
- ehci_cardbus_attach
- ehci_cardbus_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/rwlock.h>
45 #include <sys/device.h>
46 #include <sys/proc.h>
47
48 #include <machine/bus.h>
49
50 #include <dev/cardbus/cardbusvar.h>
51 #include <dev/pci/pcidevs.h>
52
53 #include <dev/usb/usb.h>
54 #include <dev/usb/usbdi.h>
55 #include <dev/usb/usbdivar.h>
56 #include <dev/usb/usb_mem.h>
57
58 #include <dev/usb/ehcireg.h>
59 #include <dev/usb/ehcivar.h>
60
61 #ifdef EHCI_DEBUG
62 #define DPRINTF(x) if (ehcidebug) printf x
63 extern int ehcidebug;
64 #else
65 #define DPRINTF(x)
66 #endif
67
68
69 int ehci_cardbus_match(struct device *, void *, void *);
70 void ehci_cardbus_attach(struct device *, struct device *, void *);
71 int ehci_cardbus_detach(struct device *, int);
72
73 struct ehci_cardbus_softc {
74 ehci_softc_t sc;
75 cardbus_chipset_tag_t sc_cc;
76 cardbus_function_tag_t sc_cf;
77 cardbus_devfunc_t sc_ct;
78 void *sc_ih;
79 };
80
81 struct cfattach ehci_cardbus_ca = {
82 sizeof(struct ehci_cardbus_softc), ehci_cardbus_match,
83 ehci_cardbus_attach, ehci_cardbus_detach, ehci_activate
84 };
85
86 #define CARDBUS_INTERFACE_EHCI PCI_INTERFACE_EHCI
87 #define CARDBUS_CBMEM PCI_CBMEM
88 #define cardbus_findvendor pci_findvendor
89 #define cardbus_devinfo pci_devinfo
90
91 int
92 ehci_cardbus_match(struct device *parent, void *match, void *aux)
93 {
94 struct cardbus_attach_args *ca = (struct cardbus_attach_args *)aux;
95
96 if (CARDBUS_CLASS(ca->ca_class) == CARDBUS_CLASS_SERIALBUS &&
97 CARDBUS_SUBCLASS(ca->ca_class) == CARDBUS_SUBCLASS_SERIALBUS_USB &&
98 CARDBUS_INTERFACE(ca->ca_class) == CARDBUS_INTERFACE_EHCI)
99 return (1);
100
101 return (0);
102 }
103
104 void
105 ehci_cardbus_attach(struct device *parent, struct device *self, void *aux)
106 {
107 struct ehci_cardbus_softc *sc = (struct ehci_cardbus_softc *)self;
108 struct cardbus_attach_args *ca = aux;
109 cardbus_devfunc_t ct = ca->ca_ct;
110 cardbus_chipset_tag_t cc = ct->ct_cc;
111 cardbus_function_tag_t cf = ct->ct_cf;
112 cardbusreg_t csr;
113 char devinfo[256];
114 usbd_status r;
115 const char *vendor;
116 const char *devname = sc->sc.sc_bus.bdev.dv_xname;
117
118 cardbus_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo));
119 printf(" %s", devinfo);
120
121
122 if (Cardbus_mapreg_map(ct, CARDBUS_CBMEM, CARDBUS_MAPREG_TYPE_MEM, 0,
123 &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) {
124 printf("%s: can't map mem space\n", devname);
125 return;
126 }
127
128 sc->sc_cc = cc;
129 sc->sc_cf = cf;
130 sc->sc_ct = ct;
131 sc->sc.sc_bus.dmatag = ca->ca_dmat;
132
133 (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
134 (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
135
136
137 csr = cardbus_conf_read(cc, cf, ca->ca_tag,
138 CARDBUS_COMMAND_STATUS_REG);
139 cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_COMMAND_STATUS_REG,
140 csr | CARDBUS_COMMAND_MASTER_ENABLE
141 | CARDBUS_COMMAND_MEM_ENABLE);
142
143
144 sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH);
145 DPRINTF((": offs=%d", devname, sc->sc.sc_offs));
146 EOWRITE2(&sc->sc, EHCI_USBINTR, 0);
147
148 sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline,
149 IPL_USB, ehci_intr, sc, devname);
150 if (sc->sc_ih == NULL) {
151 printf(": unable to establish interrupt\n");
152 return;
153 }
154 printf(": irq %d\n", ca->ca_intrline);
155
156
157 vendor = cardbus_findvendor(ca->ca_id);
158 sc->sc.sc_id_vendor = CARDBUS_VENDOR(ca->ca_id);
159 if (vendor)
160 strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor));
161 else
162 snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
163 "vendor 0x%04x", CARDBUS_VENDOR(ca->ca_id));
164
165 r = ehci_init(&sc->sc);
166 if (r != USBD_NORMAL_COMPLETION) {
167 printf("%s: init failed, error=%d\n", devname, r);
168
169
170 cardbus_intr_disestablish(sc->sc_cc, sc->sc_cf, sc->sc_ih);
171 sc->sc_ih = NULL;
172
173 return;
174 }
175
176 sc->sc.sc_shutdownhook = shutdownhook_establish(ehci_shutdown, &sc->sc);
177
178
179 sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
180 usbctlprint);
181 }
182
183 int
184 ehci_cardbus_detach(struct device *self, int flags)
185 {
186 struct ehci_cardbus_softc *sc = (struct ehci_cardbus_softc *)self;
187 struct cardbus_devfunc *ct = sc->sc_ct;
188 int rv;
189
190 rv = ehci_detach(&sc->sc, flags);
191 if (rv)
192 return (rv);
193 if (sc->sc_ih != NULL) {
194 cardbus_intr_disestablish(sc->sc_cc, sc->sc_cf, sc->sc_ih);
195 sc->sc_ih = NULL;
196 }
197 if (sc->sc.sc_size) {
198 Cardbus_mapreg_unmap(ct, CARDBUS_CBMEM, sc->sc.iot,
199 sc->sc.ioh, sc->sc.sc_size);
200 sc->sc.sc_size = 0;
201 }
202 return (0);
203 }
204