1/* $NetBSD: usb/uvscom.c,v 1.1 2002/03/19 15:08:42 augustss Exp $ */ 2 3#include <sys/cdefs.h>
|
4__FBSDID("$FreeBSD: head/sys/dev/usb/serial/uvscom.c 193045 2009-05-29 18:46:57Z thompsa $");
|
4__FBSDID("$FreeBSD: head/sys/dev/usb/serial/uvscom.c 194228 2009-06-15 01:02:43Z thompsa $"); |
5 6/*- 7 * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 */ 32 33/* 34 * uvscom: SUNTAC Slipper U VS-10U driver. 35 * Slipper U is a PC Card to USB converter for data communication card 36 * adapter. It supports DDI Pocket's Air H" C@rd, C@rd H" 64, NTT's P-in, 37 * P-in m@ater and various data communication card adapters. 38 */ 39 40#include "usbdevs.h" 41#include <dev/usb/usb.h> 42#include <dev/usb/usb_mfunc.h> 43#include <dev/usb/usb_error.h> 44#include <dev/usb/usb_cdc.h> 45 46#define USB_DEBUG_VAR uvscom_debug 47 48#include <dev/usb/usb_core.h> 49#include <dev/usb/usb_debug.h> 50#include <dev/usb/usb_process.h> 51#include <dev/usb/usb_request.h> 52#include <dev/usb/usb_lookup.h> 53#include <dev/usb/usb_util.h> 54#include <dev/usb/usb_busdma.h> 55 56#include <dev/usb/serial/usb_serial.h> 57 58#if USB_DEBUG 59static int uvscom_debug = 0; 60 61SYSCTL_NODE(_hw_usb, OID_AUTO, uvscom, CTLFLAG_RW, 0, "USB uvscom"); 62SYSCTL_INT(_hw_usb_uvscom, OID_AUTO, debug, CTLFLAG_RW, 63 &uvscom_debug, 0, "Debug level"); 64#endif 65 66#define UVSCOM_MODVER 1 /* module version */ 67 68#define UVSCOM_CONFIG_INDEX 0 69#define UVSCOM_IFACE_INDEX 0 70 71/* Request */ 72#define UVSCOM_SET_SPEED 0x10 73#define UVSCOM_LINE_CTL 0x11 74#define UVSCOM_SET_PARAM 0x12 75#define UVSCOM_READ_STATUS 0xd0 76#define UVSCOM_SHUTDOWN 0xe0 77 78/* UVSCOM_SET_SPEED parameters */ 79#define UVSCOM_SPEED_150BPS 0x00 80#define UVSCOM_SPEED_300BPS 0x01 81#define UVSCOM_SPEED_600BPS 0x02 82#define UVSCOM_SPEED_1200BPS 0x03 83#define UVSCOM_SPEED_2400BPS 0x04 84#define UVSCOM_SPEED_4800BPS 0x05 85#define UVSCOM_SPEED_9600BPS 0x06 86#define UVSCOM_SPEED_19200BPS 0x07 87#define UVSCOM_SPEED_38400BPS 0x08 88#define UVSCOM_SPEED_57600BPS 0x09 89#define UVSCOM_SPEED_115200BPS 0x0a 90 91/* UVSCOM_LINE_CTL parameters */ 92#define UVSCOM_BREAK 0x40 93#define UVSCOM_RTS 0x02 94#define UVSCOM_DTR 0x01 95#define UVSCOM_LINE_INIT 0x08 96 97/* UVSCOM_SET_PARAM parameters */ 98#define UVSCOM_DATA_MASK 0x03 99#define UVSCOM_DATA_BIT_8 0x03 100#define UVSCOM_DATA_BIT_7 0x02 101#define UVSCOM_DATA_BIT_6 0x01 102#define UVSCOM_DATA_BIT_5 0x00 103 104#define UVSCOM_STOP_MASK 0x04 105#define UVSCOM_STOP_BIT_2 0x04 106#define UVSCOM_STOP_BIT_1 0x00 107 108#define UVSCOM_PARITY_MASK 0x18 109#define UVSCOM_PARITY_EVEN 0x18 110#define UVSCOM_PARITY_ODD 0x08 111#define UVSCOM_PARITY_NONE 0x00 112 113/* Status bits */ 114#define UVSCOM_TXRDY 0x04 115#define UVSCOM_RXRDY 0x01 116 117#define UVSCOM_DCD 0x08 118#define UVSCOM_NOCARD 0x04 119#define UVSCOM_DSR 0x02 120#define UVSCOM_CTS 0x01 121#define UVSCOM_USTAT_MASK (UVSCOM_NOCARD | UVSCOM_DSR | UVSCOM_CTS) 122 123#define UVSCOM_BULK_BUF_SIZE 1024 /* bytes */ 124 125enum { 126 UVSCOM_BULK_DT_WR, 127 UVSCOM_BULK_DT_RD, 128 UVSCOM_INTR_DT_RD, 129 UVSCOM_N_TRANSFER, 130}; 131 132struct uvscom_softc { 133 struct ucom_super_softc sc_super_ucom; 134 struct ucom_softc sc_ucom; 135 136 struct usb_xfer *sc_xfer[UVSCOM_N_TRANSFER]; 137 struct usb_device *sc_udev; 138 struct mtx sc_mtx; 139 140 uint16_t sc_line; /* line control register */ 141 142 uint8_t sc_iface_no; /* interface number */ 143 uint8_t sc_iface_index; /* interface index */ 144 uint8_t sc_lsr; /* local status register */ 145 uint8_t sc_msr; /* uvscom status register */ 146 uint8_t sc_unit_status; /* unit status */ 147}; 148 149/* prototypes */ 150 151static device_probe_t uvscom_probe; 152static device_attach_t uvscom_attach; 153static device_detach_t uvscom_detach; 154 155static usb_callback_t uvscom_write_callback; 156static usb_callback_t uvscom_read_callback; 157static usb_callback_t uvscom_intr_callback; 158 159static void uvscom_cfg_set_dtr(struct ucom_softc *, uint8_t); 160static void uvscom_cfg_set_rts(struct ucom_softc *, uint8_t); 161static void uvscom_cfg_set_break(struct ucom_softc *, uint8_t); 162static int uvscom_pre_param(struct ucom_softc *, struct termios *); 163static void uvscom_cfg_param(struct ucom_softc *, struct termios *); 164static int uvscom_pre_open(struct ucom_softc *); 165static void uvscom_cfg_open(struct ucom_softc *); 166static void uvscom_cfg_close(struct ucom_softc *); 167static void uvscom_start_read(struct ucom_softc *); 168static void uvscom_stop_read(struct ucom_softc *); 169static void uvscom_start_write(struct ucom_softc *); 170static void uvscom_stop_write(struct ucom_softc *); 171static void uvscom_cfg_get_status(struct ucom_softc *, uint8_t *, 172 uint8_t *); 173static void uvscom_cfg_write(struct uvscom_softc *, uint8_t, uint16_t); 174static uint16_t uvscom_cfg_read_status(struct uvscom_softc *); 175 176static const struct usb_config uvscom_config[UVSCOM_N_TRANSFER] = { 177 178 [UVSCOM_BULK_DT_WR] = { 179 .type = UE_BULK, 180 .endpoint = UE_ADDR_ANY, 181 .direction = UE_DIR_OUT, 182 .bufsize = UVSCOM_BULK_BUF_SIZE, 183 .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 184 .callback = &uvscom_write_callback, 185 }, 186 187 [UVSCOM_BULK_DT_RD] = { 188 .type = UE_BULK, 189 .endpoint = UE_ADDR_ANY, 190 .direction = UE_DIR_IN, 191 .bufsize = UVSCOM_BULK_BUF_SIZE, 192 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 193 .callback = &uvscom_read_callback, 194 }, 195 196 [UVSCOM_INTR_DT_RD] = { 197 .type = UE_INTERRUPT, 198 .endpoint = UE_ADDR_ANY, 199 .direction = UE_DIR_IN, 200 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 201 .bufsize = 0, /* use wMaxPacketSize */ 202 .callback = &uvscom_intr_callback, 203 }, 204}; 205 206static const struct ucom_callback uvscom_callback = {
|
207 .usb2_com_cfg_get_status = &uvscom_cfg_get_status,
208 .usb2_com_cfg_set_dtr = &uvscom_cfg_set_dtr,
209 .usb2_com_cfg_set_rts = &uvscom_cfg_set_rts,
210 .usb2_com_cfg_set_break = &uvscom_cfg_set_break,
211 .usb2_com_cfg_param = &uvscom_cfg_param,
212 .usb2_com_cfg_open = &uvscom_cfg_open,
213 .usb2_com_cfg_close = &uvscom_cfg_close,
214 .usb2_com_pre_open = &uvscom_pre_open,
215 .usb2_com_pre_param = &uvscom_pre_param,
216 .usb2_com_start_read = &uvscom_start_read,
217 .usb2_com_stop_read = &uvscom_stop_read,
218 .usb2_com_start_write = &uvscom_start_write,
219 .usb2_com_stop_write = &uvscom_stop_write,
|
207 .ucom_cfg_get_status = &uvscom_cfg_get_status, 208 .ucom_cfg_set_dtr = &uvscom_cfg_set_dtr, 209 .ucom_cfg_set_rts = &uvscom_cfg_set_rts, 210 .ucom_cfg_set_break = &uvscom_cfg_set_break, 211 .ucom_cfg_param = &uvscom_cfg_param, 212 .ucom_cfg_open = &uvscom_cfg_open, 213 .ucom_cfg_close = &uvscom_cfg_close, 214 .ucom_pre_open = &uvscom_pre_open, 215 .ucom_pre_param = &uvscom_pre_param, 216 .ucom_start_read = &uvscom_start_read, 217 .ucom_stop_read = &uvscom_stop_read, 218 .ucom_start_write = &uvscom_start_write, 219 .ucom_stop_write = &uvscom_stop_write, |
220}; 221 222static const struct usb_device_id uvscom_devs[] = { 223 /* SUNTAC U-Cable type A4 */ 224 {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS144L4, 0)}, 225 /* SUNTAC U-Cable type D2 */ 226 {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_DS96L, 0)}, 227 /* SUNTAC Ir-Trinity */ 228 {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_IS96U, 0)}, 229 /* SUNTAC U-Cable type P1 */ 230 {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_PS64P1, 0)}, 231 /* SUNTAC Slipper U */ 232 {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_VS10U, 0)}, 233}; 234 235static device_method_t uvscom_methods[] = { 236 DEVMETHOD(device_probe, uvscom_probe), 237 DEVMETHOD(device_attach, uvscom_attach), 238 DEVMETHOD(device_detach, uvscom_detach), 239 {0, 0} 240}; 241 242static devclass_t uvscom_devclass; 243 244static driver_t uvscom_driver = { 245 .name = "uvscom", 246 .methods = uvscom_methods, 247 .size = sizeof(struct uvscom_softc), 248}; 249 250DRIVER_MODULE(uvscom, uhub, uvscom_driver, uvscom_devclass, NULL, 0); 251MODULE_DEPEND(uvscom, ucom, 1, 1, 1); 252MODULE_DEPEND(uvscom, usb, 1, 1, 1); 253MODULE_VERSION(uvscom, UVSCOM_MODVER); 254 255static int 256uvscom_probe(device_t dev) 257{ 258 struct usb_attach_arg *uaa = device_get_ivars(dev); 259 260 if (uaa->usb_mode != USB_MODE_HOST) { 261 return (ENXIO); 262 } 263 if (uaa->info.bConfigIndex != UVSCOM_CONFIG_INDEX) { 264 return (ENXIO); 265 } 266 if (uaa->info.bIfaceIndex != UVSCOM_IFACE_INDEX) { 267 return (ENXIO); 268 }
|
269 return (usb2_lookup_id_by_uaa(uvscom_devs, sizeof(uvscom_devs), uaa));
|
269 return (usbd_lookup_id_by_uaa(uvscom_devs, sizeof(uvscom_devs), uaa)); |
270} 271 272static int 273uvscom_attach(device_t dev) 274{ 275 struct usb_attach_arg *uaa = device_get_ivars(dev); 276 struct uvscom_softc *sc = device_get_softc(dev); 277 int error; 278
|
279 device_set_usb2_desc(dev);
|
279 device_set_usb_desc(dev); |
280 mtx_init(&sc->sc_mtx, "uvscom", NULL, MTX_DEF); 281 282 sc->sc_udev = uaa->device; 283 284 DPRINTF("sc=%p\n", sc); 285 286 sc->sc_iface_no = uaa->info.bIfaceNum; 287 sc->sc_iface_index = UVSCOM_IFACE_INDEX; 288
|
289 error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index,
|
289 error = usbd_transfer_setup(uaa->device, &sc->sc_iface_index, |
290 sc->sc_xfer, uvscom_config, UVSCOM_N_TRANSFER, sc, &sc->sc_mtx); 291 292 if (error) { 293 DPRINTF("could not allocate all USB transfers!\n"); 294 goto detach; 295 } 296 sc->sc_line = UVSCOM_LINE_INIT; 297 298 /* clear stall at first run */ 299 mtx_lock(&sc->sc_mtx);
|
300 usb2_transfer_set_stall(sc->sc_xfer[UVSCOM_BULK_DT_WR]);
301 usb2_transfer_set_stall(sc->sc_xfer[UVSCOM_BULK_DT_RD]);
|
300 usbd_transfer_set_stall(sc->sc_xfer[UVSCOM_BULK_DT_WR]); 301 usbd_transfer_set_stall(sc->sc_xfer[UVSCOM_BULK_DT_RD]); |
302 mtx_unlock(&sc->sc_mtx); 303
|
304 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
|
304 error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc, |
305 &uvscom_callback, &sc->sc_mtx); 306 if (error) { 307 goto detach; 308 } 309 /* start interrupt pipe */ 310 mtx_lock(&sc->sc_mtx);
|
311 usb2_transfer_start(sc->sc_xfer[UVSCOM_INTR_DT_RD]);
|
311 usbd_transfer_start(sc->sc_xfer[UVSCOM_INTR_DT_RD]); |
312 mtx_unlock(&sc->sc_mtx); 313 314 return (0); 315 316detach: 317 uvscom_detach(dev); 318 return (ENXIO); 319} 320 321static int 322uvscom_detach(device_t dev) 323{ 324 struct uvscom_softc *sc = device_get_softc(dev); 325 326 DPRINTF("sc=%p\n", sc); 327 328 /* stop interrupt pipe */ 329 330 if (sc->sc_xfer[UVSCOM_INTR_DT_RD])
|
331 usb2_transfer_stop(sc->sc_xfer[UVSCOM_INTR_DT_RD]);
|
331 usbd_transfer_stop(sc->sc_xfer[UVSCOM_INTR_DT_RD]); |
332
|
333 usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
334 usb2_transfer_unsetup(sc->sc_xfer, UVSCOM_N_TRANSFER);
|
333 ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); 334 usbd_transfer_unsetup(sc->sc_xfer, UVSCOM_N_TRANSFER); |
335 mtx_destroy(&sc->sc_mtx); 336 337 return (0); 338} 339 340static void 341uvscom_write_callback(struct usb_xfer *xfer) 342{ 343 struct uvscom_softc *sc = xfer->priv_sc; 344 uint32_t actlen; 345 346 switch (USB_GET_STATE(xfer)) { 347 case USB_ST_SETUP: 348 case USB_ST_TRANSFERRED: 349tr_setup:
|
350 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
|
350 if (ucom_get_data(&sc->sc_ucom, xfer->frbuffers, 0, |
351 UVSCOM_BULK_BUF_SIZE, &actlen)) { 352 353 xfer->frlengths[0] = actlen;
|
354 usb2_start_hardware(xfer);
|
354 usbd_transfer_submit(xfer); |
355 } 356 return; 357 358 default: /* Error */ 359 if (xfer->error != USB_ERR_CANCELLED) { 360 /* try to clear stall first */ 361 xfer->flags.stall_pipe = 1; 362 goto tr_setup; 363 } 364 return; 365 } 366} 367 368static void 369uvscom_read_callback(struct usb_xfer *xfer) 370{ 371 struct uvscom_softc *sc = xfer->priv_sc; 372 373 switch (USB_GET_STATE(xfer)) { 374 case USB_ST_TRANSFERRED:
|
375 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
|
375 ucom_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen); |
376 377 case USB_ST_SETUP: 378tr_setup: 379 xfer->frlengths[0] = xfer->max_data_length;
|
380 usb2_start_hardware(xfer);
|
380 usbd_transfer_submit(xfer); |
381 return; 382 383 default: /* Error */ 384 if (xfer->error != USB_ERR_CANCELLED) { 385 /* try to clear stall first */ 386 xfer->flags.stall_pipe = 1; 387 goto tr_setup; 388 } 389 return; 390 } 391} 392 393static void 394uvscom_intr_callback(struct usb_xfer *xfer) 395{ 396 struct uvscom_softc *sc = xfer->priv_sc; 397 uint8_t buf[2]; 398 399 switch (USB_GET_STATE(xfer)) { 400 case USB_ST_TRANSFERRED: 401 if (xfer->actlen >= 2) { 402
|
403 usb2_copy_out(xfer->frbuffers, 0, buf, sizeof(buf));
|
403 usbd_copy_out(xfer->frbuffers, 0, buf, sizeof(buf)); |
404 405 sc->sc_lsr = 0; 406 sc->sc_msr = 0; 407 sc->sc_unit_status = buf[1]; 408 409 if (buf[0] & UVSCOM_TXRDY) { 410 sc->sc_lsr |= ULSR_TXRDY; 411 } 412 if (buf[0] & UVSCOM_RXRDY) { 413 sc->sc_lsr |= ULSR_RXRDY; 414 } 415 if (buf[1] & UVSCOM_CTS) { 416 sc->sc_msr |= SER_CTS; 417 } 418 if (buf[1] & UVSCOM_DSR) { 419 sc->sc_msr |= SER_DSR; 420 } 421 if (buf[1] & UVSCOM_DCD) { 422 sc->sc_msr |= SER_DCD; 423 } 424 /* 425 * the UCOM layer will ignore this call if the TTY 426 * device is closed! 427 */
|
428 usb2_com_status_change(&sc->sc_ucom);
|
428 ucom_status_change(&sc->sc_ucom); |
429 } 430 case USB_ST_SETUP: 431tr_setup: 432 xfer->frlengths[0] = xfer->max_data_length;
|
433 usb2_start_hardware(xfer);
|
433 usbd_transfer_submit(xfer); |
434 return; 435 436 default: /* Error */ 437 if (xfer->error != USB_ERR_CANCELLED) { 438 /* try to clear stall first */ 439 xfer->flags.stall_pipe = 1; 440 goto tr_setup; 441 } 442 return; 443 } 444} 445 446static void 447uvscom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff) 448{ 449 struct uvscom_softc *sc = ucom->sc_parent; 450 451 DPRINTF("onoff = %d\n", onoff); 452 453 if (onoff) 454 sc->sc_line |= UVSCOM_DTR; 455 else 456 sc->sc_line &= ~UVSCOM_DTR; 457 458 uvscom_cfg_write(sc, UVSCOM_LINE_CTL, sc->sc_line); 459} 460 461static void 462uvscom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff) 463{ 464 struct uvscom_softc *sc = ucom->sc_parent; 465 466 DPRINTF("onoff = %d\n", onoff); 467 468 if (onoff) 469 sc->sc_line |= UVSCOM_RTS; 470 else 471 sc->sc_line &= ~UVSCOM_RTS; 472 473 uvscom_cfg_write(sc, UVSCOM_LINE_CTL, sc->sc_line); 474} 475 476static void 477uvscom_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff) 478{ 479 struct uvscom_softc *sc = ucom->sc_parent; 480 481 DPRINTF("onoff = %d\n", onoff); 482 483 if (onoff) 484 sc->sc_line |= UVSCOM_BREAK; 485 else 486 sc->sc_line &= ~UVSCOM_BREAK; 487 488 uvscom_cfg_write(sc, UVSCOM_LINE_CTL, sc->sc_line); 489} 490 491static int 492uvscom_pre_param(struct ucom_softc *ucom, struct termios *t) 493{ 494 switch (t->c_ospeed) { 495 case B150: 496 case B300: 497 case B600: 498 case B1200: 499 case B2400: 500 case B4800: 501 case B9600: 502 case B19200: 503 case B38400: 504 case B57600: 505 case B115200: 506 default: 507 return (EINVAL); 508 } 509 return (0); 510} 511 512static void 513uvscom_cfg_param(struct ucom_softc *ucom, struct termios *t) 514{ 515 struct uvscom_softc *sc = ucom->sc_parent; 516 uint16_t value; 517 518 DPRINTF("\n"); 519 520 switch (t->c_ospeed) { 521 case B150: 522 value = UVSCOM_SPEED_150BPS; 523 break; 524 case B300: 525 value = UVSCOM_SPEED_300BPS; 526 break; 527 case B600: 528 value = UVSCOM_SPEED_600BPS; 529 break; 530 case B1200: 531 value = UVSCOM_SPEED_1200BPS; 532 break; 533 case B2400: 534 value = UVSCOM_SPEED_2400BPS; 535 break; 536 case B4800: 537 value = UVSCOM_SPEED_4800BPS; 538 break; 539 case B9600: 540 value = UVSCOM_SPEED_9600BPS; 541 break; 542 case B19200: 543 value = UVSCOM_SPEED_19200BPS; 544 break; 545 case B38400: 546 value = UVSCOM_SPEED_38400BPS; 547 break; 548 case B57600: 549 value = UVSCOM_SPEED_57600BPS; 550 break; 551 case B115200: 552 value = UVSCOM_SPEED_115200BPS; 553 break; 554 default: 555 return; 556 } 557 558 uvscom_cfg_write(sc, UVSCOM_SET_SPEED, value); 559 560 value = 0; 561 562 if (t->c_cflag & CSTOPB) { 563 value |= UVSCOM_STOP_BIT_2; 564 } 565 if (t->c_cflag & PARENB) { 566 if (t->c_cflag & PARODD) { 567 value |= UVSCOM_PARITY_ODD; 568 } else { 569 value |= UVSCOM_PARITY_EVEN; 570 } 571 } else { 572 value |= UVSCOM_PARITY_NONE; 573 } 574 575 switch (t->c_cflag & CSIZE) { 576 case CS5: 577 value |= UVSCOM_DATA_BIT_5; 578 break; 579 case CS6: 580 value |= UVSCOM_DATA_BIT_6; 581 break; 582 case CS7: 583 value |= UVSCOM_DATA_BIT_7; 584 break; 585 default: 586 case CS8: 587 value |= UVSCOM_DATA_BIT_8; 588 break; 589 } 590 591 uvscom_cfg_write(sc, UVSCOM_SET_PARAM, value); 592} 593 594static int 595uvscom_pre_open(struct ucom_softc *ucom) 596{ 597 struct uvscom_softc *sc = ucom->sc_parent; 598 599 DPRINTF("sc = %p\n", sc); 600 601 /* check if PC card was inserted */ 602 603 if (sc->sc_unit_status & UVSCOM_NOCARD) { 604 DPRINTF("no PC card!\n"); 605 return (ENXIO); 606 } 607 return (0); 608} 609 610static void 611uvscom_cfg_open(struct ucom_softc *ucom) 612{ 613 struct uvscom_softc *sc = ucom->sc_parent; 614 615 DPRINTF("sc = %p\n", sc); 616 617 uvscom_cfg_read_status(sc); 618} 619 620static void 621uvscom_cfg_close(struct ucom_softc *ucom) 622{ 623 struct uvscom_softc *sc = ucom->sc_parent; 624 625 DPRINTF("sc=%p\n", sc); 626 627 uvscom_cfg_write(sc, UVSCOM_SHUTDOWN, 0); 628} 629 630static void 631uvscom_start_read(struct ucom_softc *ucom) 632{ 633 struct uvscom_softc *sc = ucom->sc_parent; 634
|
635 usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_DT_RD]);
|
635 usbd_transfer_start(sc->sc_xfer[UVSCOM_BULK_DT_RD]); |
636} 637 638static void 639uvscom_stop_read(struct ucom_softc *ucom) 640{ 641 struct uvscom_softc *sc = ucom->sc_parent; 642
|
643 usb2_transfer_stop(sc->sc_xfer[UVSCOM_BULK_DT_RD]);
|
643 usbd_transfer_stop(sc->sc_xfer[UVSCOM_BULK_DT_RD]); |
644} 645 646static void 647uvscom_start_write(struct ucom_softc *ucom) 648{ 649 struct uvscom_softc *sc = ucom->sc_parent; 650
|
651 usb2_transfer_start(sc->sc_xfer[UVSCOM_BULK_DT_WR]);
|
651 usbd_transfer_start(sc->sc_xfer[UVSCOM_BULK_DT_WR]); |
652} 653 654static void 655uvscom_stop_write(struct ucom_softc *ucom) 656{ 657 struct uvscom_softc *sc = ucom->sc_parent; 658
|
659 usb2_transfer_stop(sc->sc_xfer[UVSCOM_BULK_DT_WR]);
|
659 usbd_transfer_stop(sc->sc_xfer[UVSCOM_BULK_DT_WR]); |
660} 661 662static void 663uvscom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr) 664{ 665 struct uvscom_softc *sc = ucom->sc_parent; 666 667 *lsr = sc->sc_lsr; 668 *msr = sc->sc_msr; 669} 670 671static void 672uvscom_cfg_write(struct uvscom_softc *sc, uint8_t index, uint16_t value) 673{ 674 struct usb_device_request req; 675 usb_error_t err; 676 677 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 678 req.bRequest = index; 679 USETW(req.wValue, value); 680 USETW(req.wIndex, 0); 681 USETW(req.wLength, 0); 682
|
683 err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
|
683 err = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, |
684 &req, NULL, 0, 1000); 685 if (err) { 686 DPRINTFN(0, "device request failed, err=%s "
|
687 "(ignored)\n", usb2_errstr(err));
|
687 "(ignored)\n", usbd_errstr(err)); |
688 } 689} 690 691static uint16_t 692uvscom_cfg_read_status(struct uvscom_softc *sc) 693{ 694 struct usb_device_request req; 695 usb_error_t err; 696 uint8_t data[2]; 697 698 req.bmRequestType = UT_READ_VENDOR_DEVICE; 699 req.bRequest = UVSCOM_READ_STATUS; 700 USETW(req.wValue, 0); 701 USETW(req.wIndex, 0); 702 USETW(req.wLength, 2); 703
|
704 err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
|
704 err = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, |
705 &req, data, 0, 1000); 706 if (err) { 707 DPRINTFN(0, "device request failed, err=%s "
|
708 "(ignored)\n", usb2_errstr(err));
|
708 "(ignored)\n", usbd_errstr(err)); |
709 } 710 return (data[0] | (data[1] << 8)); 711}
|