[PATCH] CDC-NCM: add support for Apple iDevices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Which lack a status endpoint, presumably because there isn't a physical
cable that can be unplugged, nor any speed changes to be notified about.

Note that NCM interfaces are not exposed until a mode switch is requested,
which macOS does automatically.

The mode switch can be performed like this:

        uint8_t status;
        libusb_control_transfer(device_handle,
                LIBUSB_RECIPIENT_DEVICE | LIBUSB_REQUEST_TYPE_VENDOR |
                LIBUSB_ENDPOINT_IN,
                82, /* bRequest */
                0,  /* wValue   */
                3,  /* wIndex   */
                &status,
                sizeof(status),
                0);

Co-developed-by: Håvard Sørbø <havard@xxxxxxxxx>
Signed-off-by: Håvard Sørbø <havard@xxxxxxxxx>
Signed-off-by: Ole André Vadla Ravnås <oleavr@xxxxxxxx>
---
 drivers/net/usb/cdc_ncm.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index db05622f1f70..e97c83b7c51d 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -933,7 +933,8 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct
usb_interface *intf, u8 data_

  cdc_ncm_find_endpoints(dev, ctx->data);
  cdc_ncm_find_endpoints(dev, ctx->control);
- if (!dev->in || !dev->out || !dev->status) {
+ if (!dev->in || !dev->out || (!dev->status &&
+ dev->driver_info->flags & FLAG_LINK_INTR)) {
  dev_dbg(&intf->dev, "failed to collect endpoints\n");
  goto error2;
  }
@@ -1925,6 +1926,20 @@ static const struct driver_info cdc_ncm_zlp_info = {
  .set_rx_mode = usbnet_cdc_update_filter,
 };

+/* Same as cdc_ncm_info, but without FLAG_LINK_INTR, and with FLAG_SEND_ZLP */
+static const struct driver_info idevice_info = {
+ .description = "Apple iDevice NCM",
+ .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
+ | FLAG_ETHER | FLAG_SEND_ZLP,
+ .bind = cdc_ncm_bind,
+ .unbind = cdc_ncm_unbind,
+ .manage_power = usbnet_manage_power,
+ .status = cdc_ncm_status,
+ .rx_fixup = cdc_ncm_rx_fixup,
+ .tx_fixup = cdc_ncm_tx_fixup,
+ .set_rx_mode = usbnet_cdc_update_filter,
+};
+
 /* Same as cdc_ncm_info, but with FLAG_WWAN */
 static const struct driver_info wwan_info = {
  .description = "Mobile Broadband Network Device",
@@ -1954,6 +1969,18 @@ static const struct driver_info wwan_noarp_info = {
 };

 static const struct usb_device_id cdc_devs[] = {
+ /* iPhone */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x05ac, 0x12a8, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long)&idevice_info,
+ },
+
+ /* iPad */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x05ac, 0x12ab, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long)&idevice_info,
+ },
+
  /* Ericsson MBM devices like F5521gw */
  { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
  | USB_DEVICE_ID_MATCH_VENDOR,
-- 
2.43.0





[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux