ucycom.c (194228) | ucycom.c (194677) |
---|---|
1#include <sys/cdefs.h> | 1#include <sys/cdefs.h> |
2__FBSDID("$FreeBSD: head/sys/dev/usb/serial/ucycom.c 194228 2009-06-15 01:02:43Z thompsa $"); | 2__FBSDID("$FreeBSD: head/sys/dev/usb/serial/ucycom.c 194677 2009-06-23 02:19:59Z thompsa $"); |
3 4/*- 5 * Copyright (c) 2004 Dag-Erling Co�dan Sm�rgrav 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: --- 18 unchanged lines hidden (view full) --- 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * Device driver for Cypress CY7C637xx and CY7C640/1xx series USB to 34 * RS232 bridges. 35 */ 36 | 3 4/*- 5 * Copyright (c) 2004 Dag-Erling Co�dan Sm�rgrav 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: --- 18 unchanged lines hidden (view full) --- 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * Device driver for Cypress CY7C637xx and CY7C640/1xx series USB to 34 * RS232 bridges. 35 */ 36 |
37#include "usbdevs.h" | 37#include <sys/stdint.h> 38#include <sys/stddef.h> 39#include <sys/param.h> 40#include <sys/queue.h> 41#include <sys/types.h> 42#include <sys/systm.h> 43#include <sys/kernel.h> 44#include <sys/bus.h> 45#include <sys/linker_set.h> 46#include <sys/module.h> 47#include <sys/lock.h> 48#include <sys/mutex.h> 49#include <sys/condvar.h> 50#include <sys/sysctl.h> 51#include <sys/sx.h> 52#include <sys/unistd.h> 53#include <sys/callout.h> 54#include <sys/malloc.h> 55#include <sys/priv.h> 56 |
38#include <dev/usb/usb.h> | 57#include <dev/usb/usb.h> |
39#include <dev/usb/usb_mfunc.h> 40#include <dev/usb/usb_error.h> 41#include <dev/usb/usb_cdc.h> 42#include <dev/usb/usb_ioctl.h> | 58#include <dev/usb/usbdi.h> 59#include <dev/usb/usbdi_util.h> |
43#include <dev/usb/usbhid.h> | 60#include <dev/usb/usbhid.h> |
61#include "usbdevs.h" |
|
44 45#define USB_DEBUG_VAR usb_debug | 62 63#define USB_DEBUG_VAR usb_debug |
46 47#include <dev/usb/usb_core.h> | |
48#include <dev/usb/usb_debug.h> 49#include <dev/usb/usb_process.h> | 64#include <dev/usb/usb_debug.h> 65#include <dev/usb/usb_process.h> |
50#include <dev/usb/usb_request.h> 51#include <dev/usb/usb_lookup.h> 52#include <dev/usb/usb_util.h> 53#include <dev/usb/usb_busdma.h> 54#include <dev/usb/usb_hid.h> | |
55 56#include <dev/usb/serial/usb_serial.h> 57 58#define UCYCOM_MAX_IOLEN (1024 + 2) /* bytes */ 59 60#define UCYCOM_IFACE_INDEX 0 61 62enum { --- 261 unchanged lines hidden (view full) --- 324ucycom_stop_write(struct ucom_softc *ucom) 325{ 326 struct ucycom_softc *sc = ucom->sc_parent; 327 328 usbd_transfer_stop(sc->sc_xfer[UCYCOM_CTRL_RD]); 329} 330 331static void | 66 67#include <dev/usb/serial/usb_serial.h> 68 69#define UCYCOM_MAX_IOLEN (1024 + 2) /* bytes */ 70 71#define UCYCOM_IFACE_INDEX 0 72 73enum { --- 261 unchanged lines hidden (view full) --- 335ucycom_stop_write(struct ucom_softc *ucom) 336{ 337 struct ucycom_softc *sc = ucom->sc_parent; 338 339 usbd_transfer_stop(sc->sc_xfer[UCYCOM_CTRL_RD]); 340} 341 342static void |
332ucycom_ctrl_write_callback(struct usb_xfer *xfer) | 343ucycom_ctrl_write_callback(struct usb_xfer *xfer, usb_error_t error) |
333{ | 344{ |
334 struct ucycom_softc *sc = xfer->priv_sc; | 345 struct ucycom_softc *sc = usbd_xfer_softc(xfer); |
335 struct usb_device_request req; | 346 struct usb_device_request req; |
347 struct usb_page_cache *pc0, *pc1; |
|
336 uint8_t data[2]; 337 uint8_t offset; 338 uint32_t actlen; 339 | 348 uint8_t data[2]; 349 uint8_t offset; 350 uint32_t actlen; 351 |
352 pc0 = usbd_xfer_get_frame(xfer, 0); 353 pc1 = usbd_xfer_get_frame(xfer, 1); 354 |
|
340 switch (USB_GET_STATE(xfer)) { 341 case USB_ST_TRANSFERRED: 342tr_transferred: 343 case USB_ST_SETUP: 344 345 switch (sc->sc_model) { 346 case MODEL_CY7C63743: 347 offset = 1; 348 break; 349 case MODEL_CY7C64013: 350 offset = 2; 351 break; 352 default: 353 offset = 0; 354 break; 355 } 356 | 355 switch (USB_GET_STATE(xfer)) { 356 case USB_ST_TRANSFERRED: 357tr_transferred: 358 case USB_ST_SETUP: 359 360 switch (sc->sc_model) { 361 case MODEL_CY7C63743: 362 offset = 1; 363 break; 364 case MODEL_CY7C64013: 365 offset = 2; 366 break; 367 default: 368 offset = 0; 369 break; 370 } 371 |
357 if (ucom_get_data(&sc->sc_ucom, xfer->frbuffers + 1, offset, | 372 if (ucom_get_data(&sc->sc_ucom, pc1, offset, |
358 sc->sc_olen - offset, &actlen)) { 359 360 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 361 req.bRequest = UR_SET_REPORT; 362 USETW2(req.wValue, UHID_OUTPUT_REPORT, sc->sc_oid); 363 req.wIndex[0] = sc->sc_iface_no; 364 req.wIndex[1] = 0; 365 USETW(req.wLength, sc->sc_olen); --- 5 unchanged lines hidden (view full) --- 371 case MODEL_CY7C64013: 372 data[0] = 0; 373 data[1] = actlen; 374 break; 375 default: 376 break; 377 } 378 | 373 sc->sc_olen - offset, &actlen)) { 374 375 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 376 req.bRequest = UR_SET_REPORT; 377 USETW2(req.wValue, UHID_OUTPUT_REPORT, sc->sc_oid); 378 req.wIndex[0] = sc->sc_iface_no; 379 req.wIndex[1] = 0; 380 USETW(req.wLength, sc->sc_olen); --- 5 unchanged lines hidden (view full) --- 386 case MODEL_CY7C64013: 387 data[0] = 0; 388 data[1] = actlen; 389 break; 390 default: 391 break; 392 } 393 |
379 usbd_copy_in(xfer->frbuffers, 0, &req, sizeof(req)); 380 usbd_copy_in(xfer->frbuffers + 1, 0, data, offset); | 394 usbd_copy_in(pc0, 0, &req, sizeof(req)); 395 usbd_copy_in(pc1, 0, data, offset); |
381 | 396 |
382 xfer->frlengths[0] = sizeof(req); 383 xfer->frlengths[1] = sc->sc_olen; 384 xfer->nframes = xfer->frlengths[1] ? 2 : 1; | 397 usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); 398 usbd_xfer_set_frame_len(xfer, 1, sc->sc_olen); 399 usbd_xfer_set_frames(xfer, sc->sc_olen ? 2 : 1); |
385 usbd_transfer_submit(xfer); 386 } 387 return; 388 389 default: /* Error */ | 400 usbd_transfer_submit(xfer); 401 } 402 return; 403 404 default: /* Error */ |
390 if (xfer->error == USB_ERR_CANCELLED) { | 405 if (error == USB_ERR_CANCELLED) { |
391 return; 392 } 393 DPRINTF("error=%s\n", | 406 return; 407 } 408 DPRINTF("error=%s\n", |
394 usbd_errstr(xfer->error)); | 409 usbd_errstr(error)); |
395 goto tr_transferred; 396 } 397} 398 399static void 400ucycom_cfg_write(struct ucycom_softc *sc, uint32_t baud, uint8_t cfg) 401{ 402 struct usb_device_request req; --- 86 unchanged lines hidden (view full) --- 489 if (t->c_cflag & PARODD) 490 cfg |= UCYCOM_CFG_PARODD; 491 } 492 493 ucycom_cfg_write(sc, t->c_ospeed, cfg); 494} 495 496static void | 410 goto tr_transferred; 411 } 412} 413 414static void 415ucycom_cfg_write(struct ucycom_softc *sc, uint32_t baud, uint8_t cfg) 416{ 417 struct usb_device_request req; --- 86 unchanged lines hidden (view full) --- 504 if (t->c_cflag & PARODD) 505 cfg |= UCYCOM_CFG_PARODD; 506 } 507 508 ucycom_cfg_write(sc, t->c_ospeed, cfg); 509} 510 511static void |
497ucycom_intr_read_callback(struct usb_xfer *xfer) | 512ucycom_intr_read_callback(struct usb_xfer *xfer, usb_error_t error) |
498{ | 513{ |
499 struct ucycom_softc *sc = xfer->priv_sc; | 514 struct ucycom_softc *sc = usbd_xfer_softc(xfer); 515 struct usb_page_cache *pc; |
500 uint8_t buf[2]; 501 uint32_t offset; 502 uint32_t len; | 516 uint8_t buf[2]; 517 uint32_t offset; 518 uint32_t len; |
519 int actlen; |
|
503 | 520 |
521 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 522 pc = usbd_xfer_get_frame(xfer, 0); 523 |
|
504 switch (USB_GET_STATE(xfer)) { 505 case USB_ST_TRANSFERRED: 506 switch (sc->sc_model) { 507 case MODEL_CY7C63743: | 524 switch (USB_GET_STATE(xfer)) { 525 case USB_ST_TRANSFERRED: 526 switch (sc->sc_model) { 527 case MODEL_CY7C63743: |
508 if (xfer->actlen < 1) { | 528 if (actlen < 1) { |
509 goto tr_setup; 510 } | 529 goto tr_setup; 530 } |
511 usbd_copy_out(xfer->frbuffers, 0, buf, 1); | 531 usbd_copy_out(pc, 0, buf, 1); |
512 513 sc->sc_ist = buf[0] & ~0x07; 514 len = buf[0] & 0x07; 515 | 532 533 sc->sc_ist = buf[0] & ~0x07; 534 len = buf[0] & 0x07; 535 |
516 (xfer->actlen)--; 517 | 536 actlen--; |
518 offset = 1; 519 520 break; 521 522 case MODEL_CY7C64013: | 537 offset = 1; 538 539 break; 540 541 case MODEL_CY7C64013: |
523 if (xfer->actlen < 2) { | 542 if (actlen < 2) { |
524 goto tr_setup; 525 } | 543 goto tr_setup; 544 } |
526 usbd_copy_out(xfer->frbuffers, 0, buf, 2); | 545 usbd_copy_out(pc, 0, buf, 2); |
527 528 sc->sc_ist = buf[0] & ~0x07; 529 len = buf[1]; 530 | 546 547 sc->sc_ist = buf[0] & ~0x07; 548 len = buf[1]; 549 |
531 (xfer->actlen) -= 2; 532 | 550 actlen -= 2; |
533 offset = 2; 534 535 break; 536 537 default: 538 DPRINTFN(0, "unsupported model number!\n"); 539 goto tr_setup; 540 } 541 | 551 offset = 2; 552 553 break; 554 555 default: 556 DPRINTFN(0, "unsupported model number!\n"); 557 goto tr_setup; 558 } 559 |
542 if (len > xfer->actlen) { 543 len = xfer->actlen; 544 } 545 if (len) { 546 ucom_put_data(&sc->sc_ucom, xfer->frbuffers, 547 offset, len); 548 } | 560 if (len > actlen) 561 len = actlen; 562 if (len) 563 ucom_put_data(&sc->sc_ucom, pc, offset, len); 564 /* FALLTHROUGH */ |
549 case USB_ST_SETUP: 550tr_setup: | 565 case USB_ST_SETUP: 566tr_setup: |
551 xfer->frlengths[0] = sc->sc_ilen; | 567 usbd_xfer_set_frame_len(xfer, 0, sc->sc_ilen); |
552 usbd_transfer_submit(xfer); 553 return; 554 555 default: /* Error */ | 568 usbd_transfer_submit(xfer); 569 return; 570 571 default: /* Error */ |
556 if (xfer->error != USB_ERR_CANCELLED) { | 572 if (error != USB_ERR_CANCELLED) { |
557 /* try to clear stall first */ | 573 /* try to clear stall first */ |
558 xfer->flags.stall_pipe = 1; | 574 usbd_xfer_set_stall(xfer); |
559 goto tr_setup; 560 } 561 return; 562 563 } 564} | 575 goto tr_setup; 576 } 577 return; 578 579 } 580} |