Deleted Added
sdiff udiff text old ( 194228 ) new ( 194677 )
full compact
1#include <sys/cdefs.h>
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
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
57#include <dev/usb/usb.h>
58#include <dev/usb/usbdi.h>
59#include <dev/usb/usbdi_util.h>
60#include <dev/usb/usbhid.h>
61#include "usbdevs.h"
62
63#define USB_DEBUG_VAR usb_debug
64#include <dev/usb/usb_debug.h>
65#include <dev/usb/usb_process.h>
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
343ucycom_ctrl_write_callback(struct usb_xfer *xfer, usb_error_t error)
344{
345 struct ucycom_softc *sc = usbd_xfer_softc(xfer);
346 struct usb_device_request req;
347 struct usb_page_cache *pc0, *pc1;
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
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
372 if (ucom_get_data(&sc->sc_ucom, pc1, offset,
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
394 usbd_copy_in(pc0, 0, &req, sizeof(req));
395 usbd_copy_in(pc1, 0, data, offset);
396
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);
400 usbd_transfer_submit(xfer);
401 }
402 return;
403
404 default: /* Error */
405 if (error == USB_ERR_CANCELLED) {
406 return;
407 }
408 DPRINTF("error=%s\n",
409 usbd_errstr(error));
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
512ucycom_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
513{
514 struct ucycom_softc *sc = usbd_xfer_softc(xfer);
515 struct usb_page_cache *pc;
516 uint8_t buf[2];
517 uint32_t offset;
518 uint32_t len;
519 int actlen;
520
521 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
522 pc = usbd_xfer_get_frame(xfer, 0);
523
524 switch (USB_GET_STATE(xfer)) {
525 case USB_ST_TRANSFERRED:
526 switch (sc->sc_model) {
527 case MODEL_CY7C63743:
528 if (actlen < 1) {
529 goto tr_setup;
530 }
531 usbd_copy_out(pc, 0, buf, 1);
532
533 sc->sc_ist = buf[0] & ~0x07;
534 len = buf[0] & 0x07;
535
536 actlen--;
537 offset = 1;
538
539 break;
540
541 case MODEL_CY7C64013:
542 if (actlen < 2) {
543 goto tr_setup;
544 }
545 usbd_copy_out(pc, 0, buf, 2);
546
547 sc->sc_ist = buf[0] & ~0x07;
548 len = buf[1];
549
550 actlen -= 2;
551 offset = 2;
552
553 break;
554
555 default:
556 DPRINTFN(0, "unsupported model number!\n");
557 goto tr_setup;
558 }
559
560 if (len > actlen)
561 len = actlen;
562 if (len)
563 ucom_put_data(&sc->sc_ucom, pc, offset, len);
564 /* FALLTHROUGH */
565 case USB_ST_SETUP:
566tr_setup:
567 usbd_xfer_set_frame_len(xfer, 0, sc->sc_ilen);
568 usbd_transfer_submit(xfer);
569 return;
570
571 default: /* Error */
572 if (error != USB_ERR_CANCELLED) {
573 /* try to clear stall first */
574 usbd_xfer_set_stall(xfer);
575 goto tr_setup;
576 }
577 return;
578
579 }
580}