This source file includes following definitions.
- uvisor_match
- uvisor_attach
- uvisor_activate
- uvisor_detach
- uvisor_init
- uvisor_close
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 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/device.h>
49 #include <sys/conf.h>
50 #include <sys/tty.h>
51
52 #include <dev/usb/usb.h>
53 #include <dev/usb/usbhid.h>
54
55 #include <dev/usb/usbdi.h>
56 #include <dev/usb/usbdi_util.h>
57 #include <dev/usb/usbdevs.h>
58
59 #include <dev/usb/ucomvar.h>
60
61 #ifdef UVISOR_DEBUG
62 #define DPRINTF(x) if (uvisordebug) printf x
63 #define DPRINTFN(n,x) if (uvisordebug>(n)) printf x
64 int uvisordebug = 0;
65 #else
66 #define DPRINTF(x)
67 #define DPRINTFN(n,x)
68 #endif
69
70 #define UVISOR_CONFIG_INDEX 0
71 #define UVISOR_IFACE_INDEX 0
72
73
74
75
76
77
78
79 #define UVISOR_REQUEST_BYTES_AVAILABLE 0x01
80
81
82
83
84
85 #define UVISOR_CLOSE_NOTIFICATION 0x02
86
87
88
89
90
91 #define UVISOR_GET_CONNECTION_INFORMATION 0x03
92
93
94
95
96
97 #define UVISOR_MAX_CONN 8
98 struct uvisor_connection_info {
99 uWord num_ports;
100 struct {
101 uByte port_function_id;
102 uByte port;
103 } connections[UVISOR_MAX_CONN];
104 };
105 #define UVISOR_CONNECTION_INFO_SIZE 18
106
107
108 #define UVISOR_FUNCTION_GENERIC 0x00
109 #define UVISOR_FUNCTION_DEBUGGER 0x01
110 #define UVISOR_FUNCTION_HOTSYNC 0x02
111 #define UVISOR_FUNCTION_CONSOLE 0x03
112 #define UVISOR_FUNCTION_REMOTE_FILE_SYS 0x04
113
114
115
116
117 #define UVISOR_GET_PALM_INFORMATION 0x04
118 #define UVISOR_GET_PALM_INFORMATION_LEN 0x44
119
120 struct uvisor_palm_connection_info {
121 uByte num_ports;
122 uByte endpoint_numbers_different;
123 uWord reserved1;
124 struct {
125 uDWord port_function_id;
126 uByte port;
127 uByte end_point_info;
128 uWord reserved;
129 } connections[UVISOR_MAX_CONN];
130 };
131
132 #define UVISORIBUFSIZE 64
133 #define UVISOROBUFSIZE 1024
134
135 struct uvisor_softc {
136 struct device sc_dev;
137 usbd_device_handle sc_udev;
138 usbd_interface_handle sc_iface;
139
140
141
142 int sc_vendor;
143
144 struct device *sc_subdevs[UVISOR_MAX_CONN];
145 int sc_numcon;
146
147 u_int16_t sc_flags;
148
149 u_char sc_dying;
150 };
151
152 usbd_status uvisor_init(struct uvisor_softc *,
153 struct uvisor_connection_info *,
154 struct uvisor_palm_connection_info *);
155
156 void uvisor_close(void *, int);
157
158
159 struct ucom_methods uvisor_methods = {
160 NULL,
161 NULL,
162 NULL,
163 NULL,
164 NULL,
165 uvisor_close,
166 NULL,
167 NULL,
168 };
169
170 struct uvisor_type {
171 struct usb_devno uv_dev;
172 u_int16_t uv_flags;
173 #define PALM4 0x0001
174 #define VISOR 0x0002
175 #define NOFRE 0x0004
176 #define CLIE4 (VISOR|NOFRE)
177 };
178 static const struct uvisor_type uvisor_devs[] = {
179 {{ USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000 }, PALM4 },
180 {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, VISOR },
181 {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO }, PALM4 },
182 {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600 }, VISOR },
183 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M500 }, PALM4 },
184 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M505 }, PALM4 },
185 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M515 }, PALM4 },
186 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_I705 }, PALM4 },
187 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M125 }, PALM4 },
188 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M130 }, PALM4 },
189 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z }, PALM4 },
190 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T }, PALM4 },
191 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE }, PALM4 },
192 {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE_31 }, PALM4 },
193 {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, PALM4 },
194 {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41 }, PALM4 },
195 {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360 }, PALM4 },
196 {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60 }, PALM4 },
197 {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TJ25 }, PALM4 },
198
199 {{ USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_IQUE3600 }, PALM4 },
200 {{ USB_VENDOR_TAPWAVE, USB_PRODUCT_TAPWAVE_ZODIAC }, PALM4 },
201 };
202 #define uvisor_lookup(v, p) ((struct uvisor_type *)usb_lookup(uvisor_devs, v, p))
203
204 int uvisor_match(struct device *, void *, void *);
205 void uvisor_attach(struct device *, struct device *, void *);
206 int uvisor_detach(struct device *, int);
207 int uvisor_activate(struct device *, enum devact);
208
209 struct cfdriver uvisor_cd = {
210 NULL, "uvisor", DV_DULL
211 };
212
213 const struct cfattach uvisor_ca = {
214 sizeof(struct uvisor_softc),
215 uvisor_match,
216 uvisor_attach,
217 uvisor_detach,
218 uvisor_activate,
219 };
220
221 int
222 uvisor_match(struct device *parent, void *match, void *aux)
223 {
224 struct usb_attach_arg *uaa = aux;
225
226 if (uaa->iface != NULL)
227 return (UMATCH_NONE);
228
229 DPRINTFN(20,("uvisor: vendor=0x%x, product=0x%x\n",
230 uaa->vendor, uaa->product));
231
232 return (uvisor_lookup(uaa->vendor, uaa->product) != NULL ?
233 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
234 }
235
236 void
237 uvisor_attach(struct device *parent, struct device *self, void *aux)
238 {
239 struct uvisor_softc *sc = (struct uvisor_softc *)self;
240 struct usb_attach_arg *uaa = aux;
241 usbd_device_handle dev = uaa->device;
242 usbd_interface_handle iface;
243 usb_interface_descriptor_t *id;
244 struct uvisor_connection_info coninfo;
245 struct uvisor_palm_connection_info palmconinfo;
246 usb_endpoint_descriptor_t *ed;
247 char *devinfop;
248 char *devname = sc->sc_dev.dv_xname;
249 int i, j, hasin, hasout, port;
250 usbd_status err;
251 struct ucom_attach_args uca;
252
253 DPRINTFN(10,("\nuvisor_attach: sc=%p\n", sc));
254
255
256 err = usbd_set_config_index(dev, UVISOR_CONFIG_INDEX, 1);
257 if (err) {
258 printf("\n%s: failed to set configuration, err=%s\n",
259 devname, usbd_errstr(err));
260 goto bad;
261 }
262
263 err = usbd_device2interface_handle(dev, UVISOR_IFACE_INDEX, &iface);
264 if (err) {
265 printf("\n%s: failed to get interface, err=%s\n",
266 devname, usbd_errstr(err));
267 goto bad;
268 }
269
270 devinfop = usbd_devinfo_alloc(dev, 0);
271 printf("\n%s: %s\n", devname, devinfop);
272 usbd_devinfo_free(devinfop);
273
274 sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
275 sc->sc_vendor = uaa->vendor;
276
277 if ((sc->sc_flags & (VISOR | PALM4)) == 0) {
278 printf("%s: device is neither visor nor palm\n",
279 sc->sc_dev.dv_xname);
280 goto bad;
281 }
282
283 id = usbd_get_interface_descriptor(iface);
284
285 sc->sc_udev = dev;
286 sc->sc_iface = iface;
287
288 uca.ibufsize = UVISORIBUFSIZE;
289 uca.obufsize = UVISOROBUFSIZE;
290 uca.ibufsizepad = UVISORIBUFSIZE;
291 uca.opkthdrlen = 0;
292 uca.device = dev;
293 uca.iface = iface;
294 uca.methods = &uvisor_methods;
295 uca.arg = sc;
296
297 err = uvisor_init(sc, &coninfo, &palmconinfo);
298 if (err) {
299 printf("%s: init failed, %s\n", sc->sc_dev.dv_xname,
300 usbd_errstr(err));
301 goto bad;
302 }
303
304 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
305 &sc->sc_dev);
306
307 if (sc->sc_flags & VISOR) {
308 sc->sc_numcon = UGETW(coninfo.num_ports);
309 if (sc->sc_numcon > UVISOR_MAX_CONN)
310 sc->sc_numcon = UVISOR_MAX_CONN;
311
312
313 for (i = 0; i < sc->sc_numcon; ++i) {
314 switch (coninfo.connections[i].port_function_id) {
315 case UVISOR_FUNCTION_GENERIC:
316 uca.info = "Generic";
317 break;
318 case UVISOR_FUNCTION_DEBUGGER:
319 uca.info = "Debugger";
320 break;
321 case UVISOR_FUNCTION_HOTSYNC:
322 uca.info = "HotSync";
323 break;
324 case UVISOR_FUNCTION_REMOTE_FILE_SYS:
325 uca.info = "Remote File System";
326 break;
327 default:
328 uca.info = "unknown";
329 break;
330 }
331 port = coninfo.connections[i].port;
332 uca.portno = port;
333 uca.bulkin = port | UE_DIR_IN;
334 uca.bulkout = port | UE_DIR_OUT;
335
336 hasin = 0;
337 hasout = 0;
338 for (j = 0; j < id->bNumEndpoints; j++) {
339 ed = usbd_interface2endpoint_descriptor(iface, j);
340 if (ed == NULL)
341 break;
342 if (UE_GET_ADDR(ed->bEndpointAddress) == port &&
343 (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
344 if (UE_GET_DIR(ed->bEndpointAddress)
345 == UE_DIR_IN)
346 hasin++;
347 else
348 hasout++;
349 }
350 }
351 if (hasin == 1 && hasout == 1)
352 sc->sc_subdevs[i] = config_found_sm(self, &uca,
353 ucomprint, ucomsubmatch);
354 else
355 printf("%s: no proper endpoints for port %d (%d,%d)\n",
356 sc->sc_dev.dv_xname, port, hasin, hasout);
357 }
358 } else {
359 sc->sc_numcon = palmconinfo.num_ports;
360 if (sc->sc_numcon > UVISOR_MAX_CONN)
361 sc->sc_numcon = UVISOR_MAX_CONN;
362
363
364 for (i = 0; i < sc->sc_numcon; ++i) {
365
366
367
368
369
370 uca.info = "sync";
371 uca.portno = i;
372 if (palmconinfo.endpoint_numbers_different) {
373 port = palmconinfo.connections[i].end_point_info;
374 uca.bulkin = (port >> 4) | UE_DIR_IN;
375 uca.bulkout = (port & 0xf) | UE_DIR_OUT;
376 } else {
377 port = palmconinfo.connections[i].port;
378 uca.bulkin = port | UE_DIR_IN;
379 uca.bulkout = port | UE_DIR_OUT;
380 }
381 sc->sc_subdevs[i] = config_found_sm(self, &uca,
382 ucomprint, ucomsubmatch);
383 }
384 }
385
386 return;
387
388 bad:
389 DPRINTF(("uvisor_attach: ATTACH ERROR\n"));
390 sc->sc_dying = 1;
391 }
392
393 int
394 uvisor_activate(struct device *self, enum devact act)
395 {
396 struct uvisor_softc *sc = (struct uvisor_softc *)self;
397 int rv = 0;
398 int i;
399
400 switch (act) {
401 case DVACT_ACTIVATE:
402 break;
403
404 case DVACT_DEACTIVATE:
405 for (i = 0; i < sc->sc_numcon; i++)
406 if (sc->sc_subdevs[i] != NULL)
407 rv = config_deactivate(sc->sc_subdevs[i]);
408 sc->sc_dying = 1;
409 break;
410 }
411 return (rv);
412 }
413
414 int
415 uvisor_detach(struct device *self, int flags)
416 {
417 struct uvisor_softc *sc = (struct uvisor_softc *)self;
418 int rv = 0;
419 int i;
420
421 DPRINTF(("uvisor_detach: sc=%p flags=%d\n", sc, flags));
422 sc->sc_dying = 1;
423 for (i = 0; i < sc->sc_numcon; i++) {
424 if (sc->sc_subdevs[i] != NULL) {
425 rv |= config_detach(sc->sc_subdevs[i], flags);
426 sc->sc_subdevs[i] = NULL;
427 }
428 }
429
430 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
431 &sc->sc_dev);
432
433 return (rv);
434 }
435
436 usbd_status
437 uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci,
438 struct uvisor_palm_connection_info *cpi)
439 {
440 usbd_status err;
441 usb_device_request_t req;
442 int actlen;
443 uWord avail;
444
445 if (sc->sc_flags & PALM4) {
446 DPRINTF(("uvisor_init: getting Palm connection info\n"));
447 req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
448 req.bRequest = UVISOR_GET_PALM_INFORMATION;
449 USETW(req.wValue, 0);
450 USETW(req.wIndex, 0);
451 USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
452 err = usbd_do_request_flags(sc->sc_udev, &req, cpi,
453 USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
454 if (err == USBD_STALLED && sc->sc_vendor == USB_VENDOR_SONY) {
455
456
457
458
459 DPRINTF(("switching role for CLIE probe\n"));
460 sc->sc_flags = CLIE4;
461 err = 0;
462 }
463 if (err)
464 return (err);
465 }
466
467 if (sc->sc_flags & VISOR) {
468 DPRINTF(("uvisor_init: getting Visor connection info\n"));
469 req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
470 req.bRequest = UVISOR_GET_CONNECTION_INFORMATION;
471 USETW(req.wValue, 0);
472 USETW(req.wIndex, 0);
473 USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
474 err = usbd_do_request_flags(sc->sc_udev, &req, ci,
475 USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
476 if (err)
477 return (err);
478 }
479
480 if (sc->sc_flags & NOFRE)
481 return (err);
482
483 DPRINTF(("uvisor_init: getting available bytes\n"));
484 req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
485 req.bRequest = UVISOR_REQUEST_BYTES_AVAILABLE;
486 USETW(req.wValue, 0);
487 USETW(req.wIndex, 5);
488 USETW(req.wLength, sizeof avail);
489 err = usbd_do_request(sc->sc_udev, &req, &avail);
490 if (err)
491 return (err);
492 DPRINTF(("uvisor_init: avail=%d\n", UGETW(avail)));
493 DPRINTF(("uvisor_init: done\n"));
494 return (err);
495 }
496
497 void
498 uvisor_close(void *addr, int portno)
499 {
500 struct uvisor_softc *sc = addr;
501 usb_device_request_t req;
502 struct uvisor_connection_info coninfo;
503 int actlen;
504
505 if (sc->sc_dying)
506 return;
507
508 req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
509 req.bRequest = UVISOR_CLOSE_NOTIFICATION;
510 USETW(req.wValue, 0);
511 USETW(req.wIndex, 0);
512 USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
513 (void)usbd_do_request_flags(sc->sc_udev, &req, &coninfo,
514 USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
515 }