The following reply was made to PR usb/162307; it has been noted by GNATS.

From: dfil...@freebsd.org (dfilter service)
To: bug-follo...@freebsd.org
Cc:  
Subject: Re: usb/162307: commit references a PR
Date: Sat,  5 Nov 2011 12:02:09 +0000 (UTC)

 Author: hselasky
 Date: Sat Nov  5 12:01:51 2011
 New Revision: 227108
 URL: http://svn.freebsd.org/changeset/base/227108
 
 Log:
   Implement support for modem control lines.
   Don't short terminate transmitted BULK data.
   Assume that the chip reads one USB packet at a time.
   
   PR:          usb/162307
   MFC after:   3 days
 
 Modified:
   head/sys/dev/usb/serial/uslcom.c
 
 Modified: head/sys/dev/usb/serial/uslcom.c
 ==============================================================================
 --- head/sys/dev/usb/serial/uslcom.c   Sat Nov  5 11:18:46 2011        
(r227107)
 +++ head/sys/dev/usb/serial/uslcom.c   Sat Nov  5 12:01:51 2011        
(r227108)
 @@ -63,43 +63,61 @@ SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, deb
  
  #define       USLCOM_SET_DATA_BITS(x) ((x) << 8)
  
 +/* Request types */
  #define       USLCOM_WRITE            0x41
  #define       USLCOM_READ             0xc1
  
 +/* Request codes */
  #define       USLCOM_UART             0x00
  #define       USLCOM_BAUD_RATE        0x01    
  #define       USLCOM_DATA             0x03
  #define       USLCOM_BREAK            0x05
  #define       USLCOM_CTRL             0x07
 +#define       USLCOM_RCTRL            0x08
 +#define       USLCOM_SET_FLOWCTRL     0x13
  
 +/* USLCOM_UART values */
  #define       USLCOM_UART_DISABLE     0x00
  #define       USLCOM_UART_ENABLE      0x01
  
 +/* USLCOM_CTRL/USLCOM_RCTRL values */
  #define       USLCOM_CTRL_DTR_ON      0x0001  
  #define       USLCOM_CTRL_DTR_SET     0x0100
  #define       USLCOM_CTRL_RTS_ON      0x0002
  #define       USLCOM_CTRL_RTS_SET     0x0200
  #define       USLCOM_CTRL_CTS         0x0010
  #define       USLCOM_CTRL_DSR         0x0020
 +#define       USLCOM_CTRL_RI          0x0040
  #define       USLCOM_CTRL_DCD         0x0080
  
 +/* USLCOM_BAUD_RATE values */
  #define       USLCOM_BAUD_REF         0x384000
  
 +/* USLCOM_DATA values */
  #define       USLCOM_STOP_BITS_1      0x00
  #define       USLCOM_STOP_BITS_2      0x02
 -
  #define       USLCOM_PARITY_NONE      0x00
  #define       USLCOM_PARITY_ODD       0x10
  #define       USLCOM_PARITY_EVEN      0x20
  
  #define       USLCOM_PORT_NO          0xFFFF /* XXX think this should be 0 
--hps */
  
 +/* USLCOM_BREAK values */
  #define       USLCOM_BREAK_OFF        0x00
  #define       USLCOM_BREAK_ON         0x01
  
 +/* USLCOM_SET_FLOWCTRL values - 1st word */
 +#define       USLCOM_FLOW_DTR_ON      0x00000001
 +#define       USLCOM_FLOW_CTS_HS      0x00000008 /* CTS handshake */
 +#define       USLCOM_FLOW_RESERVED    0xFFFFFF80
 +/* USLCOM_SET_FLOWCTRL values - 2nd word */
 +#define       USLCOM_FLOW_RTS_ON      0x00000040
 +#define       USLCOM_FLOW_RTS_HS      0x00000080 /* RTS handshake */
 +
  enum {
        USLCOM_BULK_DT_WR,
        USLCOM_BULK_DT_RD,
 +      USLCOM_CTRL_DT_RD,
        USLCOM_N_TRANSFER,
  };
  
 @@ -121,6 +139,7 @@ static device_detach_t uslcom_detach;
  
  static usb_callback_t uslcom_write_callback;
  static usb_callback_t uslcom_read_callback;
 +static usb_callback_t uslcom_control_callback;
  
  static void uslcom_open(struct ucom_softc *);
  static void uslcom_close(struct ucom_softc *);
 @@ -143,7 +162,7 @@ static const struct usb_config uslcom_co
                .endpoint = UE_ADDR_ANY,
                .direction = UE_DIR_OUT,
                .bufsize = USLCOM_BULK_BUF_SIZE,
 -              .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
 +               .flags = {.pipe_bof = 1,},
                .callback = &uslcom_write_callback,
        },
  
 @@ -155,6 +174,16 @@ static const struct usb_config uslcom_co
                .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
                .callback = &uslcom_read_callback,
        },
 +      [USLCOM_CTRL_DT_RD] = {
 +              .type = UE_CONTROL,
 +              .endpoint = 0x00,
 +              .direction = UE_DIR_ANY,
 +              .interval = 150,        /* poll status every 150 ms */
 +              .bufsize = sizeof(struct usb_device_request) + 8,
 +              .flags = {.pipe_bof = 1,},
 +              .callback = &uslcom_control_callback,
 +              .timeout = 1000,        /* 1 second timeout */
 +      },
  };
  
  static struct ucom_callback uslcom_callback = {
 @@ -371,6 +400,8 @@ uslcom_open(struct ucom_softc *ucom)
            &req, NULL, 0, 1000)) {
                DPRINTF("UART enable failed (ignored)\n");
        }
 +      /* Start polling status */
 +      usbd_transfer_start(sc->sc_xfer[USLCOM_CTRL_DT_RD]);
  }
  
  static void
 @@ -379,13 +410,16 @@ uslcom_close(struct ucom_softc *ucom)
        struct uslcom_softc *sc = ucom->sc_parent;
        struct usb_device_request req;
  
 +      /* Stop polling status */
 +      usbd_transfer_stop(sc->sc_xfer[USLCOM_CTRL_DT_RD]);
 +
        req.bmRequestType = USLCOM_WRITE;
        req.bRequest = USLCOM_UART;
        USETW(req.wValue, USLCOM_UART_DISABLE);
        USETW(req.wIndex, USLCOM_PORT_NO);
        USETW(req.wLength, 0);
  
 -        if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, 
 +      if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, 
            &req, NULL, 0, 1000)) {
                DPRINTF("UART disable failed (ignored)\n");
        }
 @@ -452,6 +486,7 @@ uslcom_param(struct ucom_softc *ucom, st
  {
        struct uslcom_softc *sc = ucom->sc_parent;
        struct usb_device_request req;
 +      uint32_t flowctrl[4];
        uint16_t data;
  
        DPRINTF("\n");
 @@ -503,7 +538,30 @@ uslcom_param(struct ucom_softc *ucom, st
            &req, NULL, 0, 1000)) {
                DPRINTF("Set format failed (ignored)\n");
        }
 -      return;
 +       
 +      if (t->c_cflag & CRTSCTS) {
 +              flowctrl[0] = htole32(USLCOM_FLOW_RESERVED |
 +                  USLCOM_FLOW_DTR_ON | USLCOM_FLOW_CTS_HS);
 +              flowctrl[1] = htole32(USLCOM_FLOW_RTS_HS);
 +              flowctrl[2] = 0;
 +              flowctrl[3] = 0;
 +      } else {
 +              flowctrl[0] = htole32(USLCOM_FLOW_RESERVED |
 +                  USLCOM_FLOW_DTR_ON);
 +              flowctrl[1] = htole32(USLCOM_FLOW_RTS_ON);
 +              flowctrl[2] = 0;
 +              flowctrl[3] = 0;
 +      }
 +      req.bmRequestType = USLCOM_WRITE;
 +      req.bRequest = USLCOM_SET_FLOWCTRL;
 +      USETW(req.wValue, 0);
 +      USETW(req.wIndex, USLCOM_PORT_NO);
 +      USETW(req.wLength, sizeof(flowctrl));
 +
 +      if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, 
 +          &req, flowctrl, 0, 1000)) {
 +              DPRINTF("Set flowcontrol failed (ignored)\n");
 +      }
  }
  
  static void
 @@ -599,6 +657,63 @@ tr_setup:
  }
  
  static void
 +uslcom_control_callback(struct usb_xfer *xfer, usb_error_t error)
 +{
 +      struct uslcom_softc *sc = usbd_xfer_softc(xfer);
 +      struct usb_page_cache *pc;
 +      struct usb_device_request req;
 +      uint8_t msr = 0;
 +      uint8_t buf;
 +
 +      switch (USB_GET_STATE(xfer)) {
 +      case USB_ST_TRANSFERRED:
 +              pc = usbd_xfer_get_frame(xfer, 1);
 +              usbd_copy_out(pc, 0, &buf, sizeof(buf));
 +              if (buf & USLCOM_CTRL_CTS)
 +                      msr |= SER_CTS;
 +              if (buf & USLCOM_CTRL_DSR)
 +                      msr |= SER_DSR;
 +              if (buf & USLCOM_CTRL_RI)
 +                      msr |= SER_RI;
 +              if (buf & USLCOM_CTRL_DCD)
 +                      msr |= SER_DCD;
 +
 +              if (msr != sc->sc_msr) {
 +                      DPRINTF("status change msr=0x%02x "
 +                          "(was 0x%02x)\n", msr, sc->sc_msr);
 +                      sc->sc_msr = msr;
 +                      ucom_status_change(&sc->sc_ucom);
 +              }
 +
 +              /* FALLTHROUGH */
 +
 +      case USB_ST_SETUP:
 +tr_setup:              
 +              req.bmRequestType = USLCOM_READ;
 +              req.bRequest = USLCOM_RCTRL;
 +              USETW(req.wValue, 0);
 +              USETW(req.wIndex, 0);
 +              USETW(req.wLength, sizeof(buf));
 +               
 +              usbd_xfer_set_frames(xfer, 2);
 +              usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
 +              usbd_xfer_set_frame_len(xfer, 1, sizeof(buf));
 +
 +              pc = usbd_xfer_get_frame(xfer, 0);
 +              usbd_copy_in(pc, 0, &req, sizeof(req));
 +              usbd_transfer_submit(xfer);
 +              break;
 +
 +      default:                /* error */
 +              if (error != USB_ERR_CANCELLED) {
 +                      DPRINTF("error=%s\n", usbd_errstr(error));
 +                      goto tr_setup;
 +              }
 +              break;
 +      }
 +}
 +
 +static void
  uslcom_start_read(struct ucom_softc *ucom)
  {
        struct uslcom_softc *sc = ucom->sc_parent;
 _______________________________________________
 svn-src-...@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
 
_______________________________________________
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"

Reply via email to