From owner-svn-src-head@FreeBSD.ORG Sat Jan 17 12:31:28 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 151F1B4F; Sat, 17 Jan 2015 12:31:28 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0167C20B; Sat, 17 Jan 2015 12:31:28 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0HCVRim024762; Sat, 17 Jan 2015 12:31:27 GMT (envelope-from br@FreeBSD.org) Received: (from br@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0HCVR2p024759; Sat, 17 Jan 2015 12:31:27 GMT (envelope-from br@FreeBSD.org) Message-Id: <201501171231.t0HCVR2p024759@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: br set sender to br@FreeBSD.org using -f From: Ruslan Bukin Date: Sat, 17 Jan 2015 12:31:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r277298 - head/sys/dev/usb/net X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 Jan 2015 12:31:28 -0000 Author: br Date: Sat Jan 17 12:31:26 2015 New Revision: 277298 URL: https://svnweb.freebsd.org/changeset/base/277298 Log: o Notify USB host about connection when operating in device mode. Required when communicating to Mac OS X USB host stack. o Also don't set stall bit to TX pipe in device mode as seems Mac OS X don't clears it as it should. Discussed with: hselasky@ Modified: head/sys/dev/usb/net/if_cdce.c head/sys/dev/usb/net/if_cdcereg.h Modified: head/sys/dev/usb/net/if_cdce.c ============================================================================== --- head/sys/dev/usb/net/if_cdce.c Sat Jan 17 11:43:13 2015 (r277297) +++ head/sys/dev/usb/net/if_cdce.c Sat Jan 17 12:31:26 2015 (r277298) @@ -898,8 +898,14 @@ cdce_init(struct usb_ether *ue) usbd_transfer_start(sc->sc_xfer[CDCE_INTR_RX]); usbd_transfer_start(sc->sc_xfer[CDCE_INTR_TX]); - /* stall data write direction, which depends on USB mode */ - usbd_xfer_set_stall(sc->sc_xfer[CDCE_BULK_TX]); + /* + * Stall data write direction, which depends on USB mode. + * + * Some USB host stacks (e.g. Mac OS X) don't clears stall + * bit as it should, so set it in our host mode only. + */ + if (usbd_get_mode(sc->sc_ue.ue_udev) == USB_MODE_HOST) + usbd_xfer_set_stall(sc->sc_xfer[CDCE_BULK_TX]); /* start data transfers */ cdce_start(ue); @@ -1065,6 +1071,10 @@ tr_setup: static void cdce_intr_write_callback(struct usb_xfer *xfer, usb_error_t error) { + struct cdce_softc *sc = usbd_xfer_softc(xfer); + struct usb_cdc_notification req; + struct usb_page_cache *pc; + uint32_t speed; int actlen; usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); @@ -1077,10 +1087,50 @@ cdce_intr_write_callback(struct usb_xfer /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: -#if 0 - usbd_xfer_set_frame_len(xfer, 0, XXX); - usbd_transfer_submit(xfer); -#endif + /* + * Inform host about connection. Required according to USB CDC + * specification and communicating to Mac OS X USB host stack. + * Some of the values seems ignored by Mac OS X though. + */ + if (sc->sc_notify_state == CDCE_NOTIFY_NETWORK_CONNECTION) { + req.bmRequestType = UCDC_NOTIFICATION; + req.bNotification = UCDC_N_NETWORK_CONNECTION; + req.wIndex[0] = sc->sc_ifaces_index[1]; + req.wIndex[1] = 0; + USETW(req.wValue, 1); /* Connected */ + USETW(req.wLength, 0); + + pc = usbd_xfer_get_frame(xfer, 0); + usbd_copy_in(pc, 0, &req, sizeof(req)); + usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); + usbd_xfer_set_frames(xfer, 1); + usbd_transfer_submit(xfer); + sc->sc_notify_state = CDCE_NOTIFY_SPEED_CHANGE; + + } else if (sc->sc_notify_state == CDCE_NOTIFY_SPEED_CHANGE) { + req.bmRequestType = UCDC_NOTIFICATION; + req.bNotification = UCDC_N_CONNECTION_SPEED_CHANGE; + req.wIndex[0] = sc->sc_ifaces_index[1]; + req.wIndex[1] = 0; + USETW(req.wValue, 0); + USETW(req.wLength, 8); + + /* Peak theoretical bulk trasfer rate in bits/s */ + if (usbd_get_speed(sc->sc_ue.ue_udev) == USB_SPEED_HIGH) + speed = (13 * 512 * 8 * 1000 * 8); + else + speed = (19 * 64 * 1 * 1000 * 8); + + USETDW(req.data + 0, speed); /* Upstream bit rate */ + USETDW(req.data + 4, speed); /* Downstream bit rate */ + + pc = usbd_xfer_get_frame(xfer, 0); + usbd_copy_in(pc, 0, &req, sizeof(req)); + usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); + usbd_xfer_set_frames(xfer, 1); + usbd_transfer_submit(xfer); + sc->sc_notify_state = CDCE_NOTIFY_DONE; + } break; default: /* Error */ Modified: head/sys/dev/usb/net/if_cdcereg.h ============================================================================== --- head/sys/dev/usb/net/if_cdcereg.h Sat Jan 17 11:43:13 2015 (r277297) +++ head/sys/dev/usb/net/if_cdcereg.h Sat Jan 17 12:31:26 2015 (r277298) @@ -93,6 +93,10 @@ struct cdce_softc { uint8_t sc_eaddr_str_index; uint8_t sc_ifaces_index[2]; + uint8_t sc_notify_state; +#define CDCE_NOTIFY_NETWORK_CONNECTION 0 +#define CDCE_NOTIFY_SPEED_CHANGE 1 +#define CDCE_NOTIFY_DONE 2 }; #define CDCE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)