uvisor.c revision 187259
1/* $NetBSD: uvisor.c,v 1.9 2001/01/23 14:04:14 augustss Exp $ */ 2/* $FreeBSD: head/sys/dev/usb2/serial/uvisor2.c 187259 2009-01-15 02:35:40Z thompsa $ */ 3 4/* Also already merged from NetBSD: 5 * $NetBSD: uvisor.c,v 1.12 2001/11/13 06:24:57 lukem Exp $ 6 * $NetBSD: uvisor.c,v 1.13 2002/02/11 15:11:49 augustss Exp $ 7 * $NetBSD: uvisor.c,v 1.14 2002/02/27 23:00:03 augustss Exp $ 8 * $NetBSD: uvisor.c,v 1.15 2002/06/16 15:01:31 augustss Exp $ 9 * $NetBSD: uvisor.c,v 1.16 2002/07/11 21:14:36 augustss Exp $ 10 * $NetBSD: uvisor.c,v 1.17 2002/08/13 11:38:15 augustss Exp $ 11 * $NetBSD: uvisor.c,v 1.18 2003/02/05 00:50:14 augustss Exp $ 12 * $NetBSD: uvisor.c,v 1.19 2003/02/07 18:12:37 augustss Exp $ 13 * $NetBSD: uvisor.c,v 1.20 2003/04/11 01:30:10 simonb Exp $ 14 */ 15 16/*- 17 * Copyright (c) 2000 The NetBSD Foundation, Inc. 18 * All rights reserved. 19 * 20 * This code is derived from software contributed to The NetBSD Foundation 21 * by Lennart Augustsson (lennart@augustsson.net) at 22 * Carlstedt Research & Technology. 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 3. All advertising materials mentioning features or use of this software 33 * must display the following acknowledgement: 34 * This product includes software developed by the NetBSD 35 * Foundation, Inc. and its contributors. 36 * 4. Neither the name of The NetBSD Foundation nor the names of its 37 * contributors may be used to endorse or promote products derived 38 * from this software without specific prior written permission. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 41 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 42 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 44 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 45 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 46 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 47 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 48 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50 * POSSIBILITY OF SUCH DAMAGE. 51 */ 52 53/* 54 * Handspring Visor (Palmpilot compatible PDA) driver 55 */ 56 57#include <dev/usb2/include/usb2_devid.h> 58#include <dev/usb2/include/usb2_standard.h> 59#include <dev/usb2/include/usb2_mfunc.h> 60#include <dev/usb2/include/usb2_error.h> 61#include <dev/usb2/include/usb2_cdc.h> 62#include <dev/usb2/include/usb2_ioctl.h> 63 64#define USB_DEBUG_VAR uvisor_debug 65 66#include <dev/usb2/core/usb2_core.h> 67#include <dev/usb2/core/usb2_debug.h> 68#include <dev/usb2/core/usb2_process.h> 69#include <dev/usb2/core/usb2_request.h> 70#include <dev/usb2/core/usb2_lookup.h> 71#include <dev/usb2/core/usb2_util.h> 72#include <dev/usb2/core/usb2_busdma.h> 73 74#include <dev/usb2/serial/usb2_serial.h> 75 76#if USB_DEBUG 77static int uvisor_debug = 0; 78 79SYSCTL_NODE(_hw_usb2, OID_AUTO, uvisor, CTLFLAG_RW, 0, "USB uvisor"); 80SYSCTL_INT(_hw_usb2_uvisor, OID_AUTO, debug, CTLFLAG_RW, 81 &uvisor_debug, 0, "Debug level"); 82#endif 83 84#define UVISOR_CONFIG_INDEX 0 85#define UVISOR_IFACE_INDEX 0 86#define UVISOR_BUFSIZE 1024 /* bytes */ 87 88/* From the Linux driver */ 89/* 90 * UVISOR_REQUEST_BYTES_AVAILABLE asks the visor for the number of bytes that 91 * are available to be transfered to the host for the specified endpoint. 92 * Currently this is not used, and always returns 0x0001 93 */ 94#define UVISOR_REQUEST_BYTES_AVAILABLE 0x01 95 96/* 97 * UVISOR_CLOSE_NOTIFICATION is set to the device to notify it that the host 98 * is now closing the pipe. An empty packet is sent in response. 99 */ 100#define UVISOR_CLOSE_NOTIFICATION 0x02 101 102/* 103 * UVISOR_GET_CONNECTION_INFORMATION is sent by the host during enumeration to 104 * get the endpoints used by the connection. 105 */ 106#define UVISOR_GET_CONNECTION_INFORMATION 0x03 107 108/* 109 * UVISOR_GET_CONNECTION_INFORMATION returns data in the following format 110 */ 111#define UVISOR_MAX_CONN 8 112struct uvisor_connection_info { 113 uWord num_ports; 114 struct { 115 uByte port_function_id; 116 uByte port; 117 } __packed connections[UVISOR_MAX_CONN]; 118} __packed; 119 120#define UVISOR_CONNECTION_INFO_SIZE 18 121 122/* struct uvisor_connection_info.connection[x].port defines: */ 123#define UVISOR_ENDPOINT_1 0x01 124#define UVISOR_ENDPOINT_2 0x02 125 126/* struct uvisor_connection_info.connection[x].port_function_id defines: */ 127#define UVISOR_FUNCTION_GENERIC 0x00 128#define UVISOR_FUNCTION_DEBUGGER 0x01 129#define UVISOR_FUNCTION_HOTSYNC 0x02 130#define UVISOR_FUNCTION_CONSOLE 0x03 131#define UVISOR_FUNCTION_REMOTE_FILE_SYS 0x04 132 133/* 134 * Unknown PalmOS stuff. 135 */ 136#define UVISOR_GET_PALM_INFORMATION 0x04 137#define UVISOR_GET_PALM_INFORMATION_LEN 0x44 138 139struct uvisor_palm_connection_info { 140 uByte num_ports; 141 uByte endpoint_numbers_different; 142 uWord reserved1; 143 struct { 144 uDWord port_function_id; 145 uByte port; 146 uByte end_point_info; 147 uWord reserved; 148 } __packed connections[UVISOR_MAX_CONN]; 149} __packed; 150 151enum { 152 UVISOR_BULK_DT_WR, 153 UVISOR_BULK_DT_RD, 154 UVISOR_BULK_CS_WR, 155 UVISOR_BULK_CS_RD, 156 UVISOR_N_TRANSFER = 4, 157}; 158 159struct uvisor_softc { 160 struct usb2_com_super_softc sc_super_ucom; 161 struct usb2_com_softc sc_ucom; 162 163 struct usb2_xfer *sc_xfer[UVISOR_N_TRANSFER]; 164 struct usb2_device *sc_udev; 165 166 uint16_t sc_flag; 167#define UVISOR_FLAG_PALM4 0x0001 168#define UVISOR_FLAG_VISOR 0x0002 169#define UVISOR_FLAG_PALM35 0x0004 170#define UVISOR_FLAG_SEND_NOTIFY 0x0008 171#define UVISOR_FLAG_WRITE_STALL 0x0010 172#define UVISOR_FLAG_READ_STALL 0x0020 173 174 uint8_t sc_iface_no; 175 uint8_t sc_iface_index; 176}; 177 178/* prototypes */ 179 180static device_probe_t uvisor_probe; 181static device_attach_t uvisor_attach; 182static device_detach_t uvisor_detach; 183 184static usb2_callback_t uvisor_write_callback; 185static usb2_callback_t uvisor_write_clear_stall_callback; 186static usb2_callback_t uvisor_read_callback; 187static usb2_callback_t uvisor_read_clear_stall_callback; 188 189static usb2_error_t uvisor_init(struct uvisor_softc *, struct usb2_device *, 190 struct usb2_config *); 191static void uvisor_cfg_open(struct usb2_com_softc *); 192static void uvisor_cfg_close(struct usb2_com_softc *); 193static void uvisor_start_read(struct usb2_com_softc *); 194static void uvisor_stop_read(struct usb2_com_softc *); 195static void uvisor_start_write(struct usb2_com_softc *); 196static void uvisor_stop_write(struct usb2_com_softc *); 197 198static const struct usb2_config uvisor_config[UVISOR_N_TRANSFER] = { 199 200 [UVISOR_BULK_DT_WR] = { 201 .type = UE_BULK, 202 .endpoint = UE_ADDR_ANY, 203 .direction = UE_DIR_OUT, 204 .mh.bufsize = UVISOR_BUFSIZE, /* bytes */ 205 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 206 .mh.callback = &uvisor_write_callback, 207 }, 208 209 [UVISOR_BULK_DT_RD] = { 210 .type = UE_BULK, 211 .endpoint = UE_ADDR_ANY, 212 .direction = UE_DIR_IN, 213 .mh.bufsize = UVISOR_BUFSIZE, /* bytes */ 214 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 215 .mh.callback = &uvisor_read_callback, 216 }, 217 218 [UVISOR_BULK_CS_WR] = { 219 .type = UE_CONTROL, 220 .endpoint = 0x00, /* Control pipe */ 221 .direction = UE_DIR_ANY, 222 .mh.bufsize = sizeof(struct usb2_device_request), 223 .mh.callback = &uvisor_write_clear_stall_callback, 224 .mh.timeout = 1000, /* 1 second */ 225 .mh.interval = 50, /* 50ms */ 226 }, 227 228 [UVISOR_BULK_CS_RD] = { 229 .type = UE_CONTROL, 230 .endpoint = 0x00, /* Control pipe */ 231 .direction = UE_DIR_ANY, 232 .mh.bufsize = sizeof(struct usb2_device_request), 233 .mh.callback = &uvisor_read_clear_stall_callback, 234 .mh.timeout = 1000, /* 1 second */ 235 .mh.interval = 50, /* 50ms */ 236 }, 237}; 238 239static const struct usb2_com_callback uvisor_callback = { 240 .usb2_com_cfg_open = &uvisor_cfg_open, 241 .usb2_com_cfg_close = &uvisor_cfg_close, 242 .usb2_com_start_read = &uvisor_start_read, 243 .usb2_com_stop_read = &uvisor_stop_read, 244 .usb2_com_start_write = &uvisor_start_write, 245 .usb2_com_stop_write = &uvisor_stop_write, 246}; 247 248static device_method_t uvisor_methods[] = { 249 DEVMETHOD(device_probe, uvisor_probe), 250 DEVMETHOD(device_attach, uvisor_attach), 251 DEVMETHOD(device_detach, uvisor_detach), 252 {0, 0} 253}; 254 255static devclass_t uvisor_devclass; 256 257static driver_t uvisor_driver = { 258 .name = "uvisor", 259 .methods = uvisor_methods, 260 .size = sizeof(struct uvisor_softc), 261}; 262 263DRIVER_MODULE(uvisor, ushub, uvisor_driver, uvisor_devclass, NULL, 0); 264MODULE_DEPEND(uvisor, usb2_serial, 1, 1, 1); 265MODULE_DEPEND(uvisor, usb2_core, 1, 1, 1); 266 267static const struct usb2_device_id uvisor_devs[] = { 268 {USB_VPI(USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000, UVISOR_FLAG_PALM4)}, 269 {USB_VPI(USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_IQUE_3600, UVISOR_FLAG_PALM4)}, 270 {USB_VPI(USB_VENDOR_FOSSIL, USB_PRODUCT_FOSSIL_WRISTPDA, UVISOR_FLAG_PALM4)}, 271 {USB_VPI(USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR, UVISOR_FLAG_VISOR)}, 272 {USB_VPI(USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO, UVISOR_FLAG_PALM4)}, 273 {USB_VPI(USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600, UVISOR_FLAG_PALM4)}, 274 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M500, UVISOR_FLAG_PALM4)}, 275 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M505, UVISOR_FLAG_PALM4)}, 276 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M515, UVISOR_FLAG_PALM4)}, 277 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_I705, UVISOR_FLAG_PALM4)}, 278 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M125, UVISOR_FLAG_PALM4)}, 279 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_M130, UVISOR_FLAG_PALM4)}, 280 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z, UVISOR_FLAG_PALM4)}, 281 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T, UVISOR_FLAG_PALM4)}, 282 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE, UVISOR_FLAG_PALM4)}, 283 {USB_VPI(USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE31, UVISOR_FLAG_PALM4)}, 284 {USB_VPI(USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_I500, UVISOR_FLAG_PALM4)}, 285 {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40, 0)}, 286 {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41, UVISOR_FLAG_PALM4)}, 287 {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360, UVISOR_FLAG_PALM4)}, 288 {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60, UVISOR_FLAG_PALM4)}, 289 {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_35, UVISOR_FLAG_PALM35)}, 290/* {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_25, UVISOR_FLAG_PALM4 )}, */ 291 {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TJ37, UVISOR_FLAG_PALM4)}, 292/* {USB_VPI(USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TH55, UVISOR_FLAG_PALM4 )}, See PR 80935 */ 293 {USB_VPI(USB_VENDOR_TAPWAVE, USB_PRODUCT_TAPWAVE_ZODIAC, UVISOR_FLAG_PALM4)}, 294}; 295 296static int 297uvisor_probe(device_t dev) 298{ 299 struct usb2_attach_arg *uaa = device_get_ivars(dev); 300 301 if (uaa->usb2_mode != USB_MODE_HOST) { 302 return (ENXIO); 303 } 304 if (uaa->info.bConfigIndex != UVISOR_CONFIG_INDEX) { 305 return (ENXIO); 306 } 307 if (uaa->info.bIfaceIndex != UVISOR_IFACE_INDEX) { 308 return (ENXIO); 309 } 310 return (usb2_lookup_id_by_uaa(uvisor_devs, sizeof(uvisor_devs), uaa)); 311} 312 313static int 314uvisor_attach(device_t dev) 315{ 316 struct usb2_attach_arg *uaa = device_get_ivars(dev); 317 struct uvisor_softc *sc = device_get_softc(dev); 318 struct usb2_config uvisor_config_copy[UVISOR_N_TRANSFER]; 319 int error; 320 321 DPRINTF("sc=%p\n", sc); 322 bcopy(uvisor_config, uvisor_config_copy, 323 sizeof(uvisor_config_copy)); 324 if (sc == NULL) { 325 return (ENOMEM); 326 } 327 device_set_usb2_desc(dev); 328 329 sc->sc_udev = uaa->device; 330 331 /* configure the device */ 332 333 sc->sc_flag = USB_GET_DRIVER_INFO(uaa); 334 sc->sc_iface_no = uaa->info.bIfaceNum; 335 sc->sc_iface_index = UVISOR_IFACE_INDEX; 336 337 error = uvisor_init(sc, uaa->device, uvisor_config_copy); 338 339 if (error) { 340 DPRINTF("init failed, error=%s\n", 341 usb2_errstr(error)); 342 goto detach; 343 } 344 error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index, 345 sc->sc_xfer, uvisor_config_copy, UVISOR_N_TRANSFER, 346 sc, &Giant); 347 if (error) { 348 DPRINTF("could not allocate all pipes\n"); 349 goto detach; 350 } 351 /* clear stall at first run */ 352 sc->sc_flag |= (UVISOR_FLAG_WRITE_STALL | 353 UVISOR_FLAG_READ_STALL); 354 355 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc, 356 &uvisor_callback, &Giant); 357 if (error) { 358 DPRINTF("usb2_com_attach failed\n"); 359 goto detach; 360 } 361 return (0); 362 363detach: 364 uvisor_detach(dev); 365 return (ENXIO); 366} 367 368static int 369uvisor_detach(device_t dev) 370{ 371 struct uvisor_softc *sc = device_get_softc(dev); 372 373 DPRINTF("sc=%p\n", sc); 374 375 usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); 376 377 usb2_transfer_unsetup(sc->sc_xfer, UVISOR_N_TRANSFER); 378 379 return (0); 380} 381 382static usb2_error_t 383uvisor_init(struct uvisor_softc *sc, struct usb2_device *udev, struct usb2_config *config) 384{ 385 usb2_error_t err = 0; 386 struct usb2_device_request req; 387 struct uvisor_connection_info coninfo; 388 struct uvisor_palm_connection_info pconinfo; 389 uint16_t actlen; 390 uWord wAvail; 391 uint8_t buffer[256]; 392 393 if (sc->sc_flag & UVISOR_FLAG_VISOR) { 394 DPRINTF("getting connection info\n"); 395 req.bmRequestType = UT_READ_VENDOR_ENDPOINT; 396 req.bRequest = UVISOR_GET_CONNECTION_INFORMATION; 397 USETW(req.wValue, 0); 398 USETW(req.wIndex, 0); 399 USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE); 400 err = usb2_do_request_flags 401 (udev, &Giant, &req, &coninfo, USB_SHORT_XFER_OK, 402 &actlen, USB_DEFAULT_TIMEOUT); 403 404 if (err) { 405 goto done; 406 } 407 } 408#if USB_DEBUG 409 if (sc->sc_flag & UVISOR_FLAG_VISOR) { 410 uint16_t i, np; 411 const char *desc; 412 413 np = UGETW(coninfo.num_ports); 414 if (np > UVISOR_MAX_CONN) { 415 np = UVISOR_MAX_CONN; 416 } 417 DPRINTF("Number of ports: %d\n", np); 418 419 for (i = 0; i < np; ++i) { 420 switch (coninfo.connections[i].port_function_id) { 421 case UVISOR_FUNCTION_GENERIC: 422 desc = "Generic"; 423 break; 424 case UVISOR_FUNCTION_DEBUGGER: 425 desc = "Debugger"; 426 break; 427 case UVISOR_FUNCTION_HOTSYNC: 428 desc = "HotSync"; 429 break; 430 case UVISOR_FUNCTION_REMOTE_FILE_SYS: 431 desc = "Remote File System"; 432 break; 433 default: 434 desc = "unknown"; 435 break; 436 } 437 DPRINTF("Port %d is for %s\n", 438 coninfo.connections[i].port, desc); 439 } 440 } 441#endif 442 443 if (sc->sc_flag & UVISOR_FLAG_PALM4) { 444 uint8_t port; 445 446 /* Palm OS 4.0 Hack */ 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 453 err = usb2_do_request_flags 454 (udev, &Giant, &req, &pconinfo, USB_SHORT_XFER_OK, 455 &actlen, USB_DEFAULT_TIMEOUT); 456 457 if (err) { 458 goto done; 459 } 460 if (actlen < 12) { 461 DPRINTF("too little data\n"); 462 err = USB_ERR_INVAL; 463 goto done; 464 } 465 if (pconinfo.endpoint_numbers_different) { 466 port = pconinfo.connections[0].end_point_info; 467 config[0].endpoint = (port & 0xF); /* output */ 468 config[1].endpoint = (port >> 4); /* input */ 469 } else { 470 port = pconinfo.connections[0].port; 471 config[0].endpoint = (port & 0xF); /* output */ 472 config[1].endpoint = (port & 0xF); /* input */ 473 } 474#if 0 475 req.bmRequestType = UT_READ_VENDOR_ENDPOINT; 476 req.bRequest = UVISOR_GET_PALM_INFORMATION; 477 USETW(req.wValue, 0); 478 USETW(req.wIndex, 0); 479 USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN); 480 err = usb2_do_request(udev, &req, buffer); 481 if (err) { 482 goto done; 483 } 484#endif 485 } 486 if (sc->sc_flag & UVISOR_FLAG_PALM35) { 487 /* get the config number */ 488 DPRINTF("getting config info\n"); 489 req.bmRequestType = UT_READ; 490 req.bRequest = UR_GET_CONFIG; 491 USETW(req.wValue, 0); 492 USETW(req.wIndex, 0); 493 USETW(req.wLength, 1); 494 495 err = usb2_do_request(udev, &Giant, &req, buffer); 496 if (err) { 497 goto done; 498 } 499 /* get the interface number */ 500 DPRINTF("get the interface number\n"); 501 req.bmRequestType = UT_READ_DEVICE; 502 req.bRequest = UR_GET_INTERFACE; 503 USETW(req.wValue, 0); 504 USETW(req.wIndex, 0); 505 USETW(req.wLength, 1); 506 err = usb2_do_request(udev, &Giant, &req, buffer); 507 if (err) { 508 goto done; 509 } 510 } 511 DPRINTF("getting available bytes\n"); 512 req.bmRequestType = UT_READ_VENDOR_ENDPOINT; 513 req.bRequest = UVISOR_REQUEST_BYTES_AVAILABLE; 514 USETW(req.wValue, 0); 515 USETW(req.wIndex, 5); 516 USETW(req.wLength, sizeof(wAvail)); 517 err = usb2_do_request(udev, &Giant, &req, &wAvail); 518 if (err) { 519 goto done; 520 } 521 DPRINTF("avail=%d\n", UGETW(wAvail)); 522 523 DPRINTF("done\n"); 524done: 525 return (err); 526} 527 528static void 529uvisor_cfg_open(struct usb2_com_softc *ucom) 530{ 531 return; 532} 533 534static void 535uvisor_cfg_close(struct usb2_com_softc *ucom) 536{ 537 struct uvisor_softc *sc = ucom->sc_parent; 538 uint8_t buffer[UVISOR_CONNECTION_INFO_SIZE]; 539 struct usb2_device_request req; 540 usb2_error_t err; 541 542 req.bmRequestType = UT_READ_VENDOR_ENDPOINT; /* XXX read? */ 543 req.bRequest = UVISOR_CLOSE_NOTIFICATION; 544 USETW(req.wValue, 0); 545 USETW(req.wIndex, 0); 546 USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE); 547 548 err = usb2_do_request_flags 549 (sc->sc_udev, &Giant, &req, &buffer, 0, NULL, 1000); 550 551 if (err) { 552 DPRINTFN(0, "close notification failed, error=%s\n", 553 usb2_errstr(err)); 554 } 555} 556 557static void 558uvisor_start_read(struct usb2_com_softc *ucom) 559{ 560 struct uvisor_softc *sc = ucom->sc_parent; 561 562 usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_DT_RD]); 563} 564 565static void 566uvisor_stop_read(struct usb2_com_softc *ucom) 567{ 568 struct uvisor_softc *sc = ucom->sc_parent; 569 570 usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_CS_RD]); 571 usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_DT_RD]); 572} 573 574static void 575uvisor_start_write(struct usb2_com_softc *ucom) 576{ 577 struct uvisor_softc *sc = ucom->sc_parent; 578 579 usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_DT_WR]); 580} 581 582static void 583uvisor_stop_write(struct usb2_com_softc *ucom) 584{ 585 struct uvisor_softc *sc = ucom->sc_parent; 586 587 usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_CS_WR]); 588 usb2_transfer_stop(sc->sc_xfer[UVISOR_BULK_DT_WR]); 589} 590 591static void 592uvisor_write_callback(struct usb2_xfer *xfer) 593{ 594 struct uvisor_softc *sc = xfer->priv_sc; 595 uint32_t actlen; 596 597 switch (USB_GET_STATE(xfer)) { 598 case USB_ST_SETUP: 599 case USB_ST_TRANSFERRED: 600 if (sc->sc_flag & UVISOR_FLAG_WRITE_STALL) { 601 usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_CS_WR]); 602 return; 603 } 604 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0, 605 UVISOR_BUFSIZE, &actlen)) { 606 607 xfer->frlengths[0] = actlen; 608 usb2_start_hardware(xfer); 609 } 610 return; 611 612 default: /* Error */ 613 if (xfer->error != USB_ERR_CANCELLED) { 614 sc->sc_flag |= UVISOR_FLAG_WRITE_STALL; 615 usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_CS_WR]); 616 } 617 return; 618 619 } 620} 621 622static void 623uvisor_write_clear_stall_callback(struct usb2_xfer *xfer) 624{ 625 struct uvisor_softc *sc = xfer->priv_sc; 626 struct usb2_xfer *xfer_other = sc->sc_xfer[UVISOR_BULK_DT_WR]; 627 628 if (usb2_clear_stall_callback(xfer, xfer_other)) { 629 DPRINTF("stall cleared\n"); 630 sc->sc_flag &= ~UVISOR_FLAG_WRITE_STALL; 631 usb2_transfer_start(xfer_other); 632 } 633} 634 635static void 636uvisor_read_callback(struct usb2_xfer *xfer) 637{ 638 struct uvisor_softc *sc = xfer->priv_sc; 639 640 switch (USB_GET_STATE(xfer)) { 641 case USB_ST_TRANSFERRED: 642 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen); 643 644 case USB_ST_SETUP: 645 if (sc->sc_flag & UVISOR_FLAG_READ_STALL) { 646 usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_CS_RD]); 647 } else { 648 xfer->frlengths[0] = xfer->max_data_length; 649 usb2_start_hardware(xfer); 650 } 651 return; 652 653 default: /* Error */ 654 if (xfer->error != USB_ERR_CANCELLED) { 655 sc->sc_flag |= UVISOR_FLAG_READ_STALL; 656 usb2_transfer_start(sc->sc_xfer[UVISOR_BULK_CS_RD]); 657 } 658 return; 659 660 } 661} 662 663static void 664uvisor_read_clear_stall_callback(struct usb2_xfer *xfer) 665{ 666 struct uvisor_softc *sc = xfer->priv_sc; 667 struct usb2_xfer *xfer_other = sc->sc_xfer[UVISOR_BULK_DT_RD]; 668 669 if (usb2_clear_stall_callback(xfer, xfer_other)) { 670 DPRINTF("stall cleared\n"); 671 sc->sc_flag &= ~UVISOR_FLAG_READ_STALL; 672 usb2_transfer_start(xfer_other); 673 } 674} 675