diff options
| author | Manu Gautam <mgautam@codeaurora.org> | 2017-02-15 16:09:51 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-03-27 22:00:26 -0700 |
| commit | bc8e8071f0db7d35458135c2211481ce2f641092 (patch) | |
| tree | 937b391f461b85bb52d5ba887bd0b113130a852d /drivers/usb/misc | |
| parent | d2cce3278ce7bfa08f2beae5136614b50c33e2e6 (diff) | |
usb: misc: ks_bridge: handle multiple ksb devices enumeration
Driver currently supports enumeration of only one KSB device
connected at a time. Add changes to allow upto four KSB devices
enumeration and update the dev name with suffix to reflect the
HUB port to which they are connected for user to distinguish
between them.
CRs-fixed: 2009286
Change-Id: Ieee6c4d3d0a2ee35d9848b31cdd7038927fad95c
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
Diffstat (limited to 'drivers/usb/misc')
| -rw-r--r-- | drivers/usb/misc/ks_bridge.c | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/drivers/usb/misc/ks_bridge.c b/drivers/usb/misc/ks_bridge.c index fdc9094e48c1..68796b3c68f6 100644 --- a/drivers/usb/misc/ks_bridge.c +++ b/drivers/usb/misc/ks_bridge.c @@ -459,10 +459,10 @@ static struct ksb_dev_info ksb_efs_usb_dev = { static const struct usb_device_id ksb_usb_ids[] = { { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9008, 0), .driver_info = (unsigned long)&ksb_fboot_dev, }, - { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9025, 0), - .driver_info = (unsigned long)&ksb_fboot_dev, }, - { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x901D, 0), - .driver_info = (unsigned long)&ksb_fboot_dev, }, + { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9025, 0), }, + { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9091, 0), }, + { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x901D, 0), }, + { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x900E, 0), }, { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 2), .driver_info = (unsigned long)&ksb_efs_hsic_dev, }, { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904C, 2), @@ -665,7 +665,7 @@ static void ksb_start_rx_work(struct work_struct *w) static int ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id) { - __u8 ifc_num, ifc_count; + __u8 ifc_num, ifc_count, ksb_port_num; struct usb_host_interface *ifc_desc; struct usb_endpoint_descriptor *ep_desc; int i; @@ -675,7 +675,8 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id) struct ksb_dev_info *mdev, *fbdev; struct usb_device *udev; unsigned int bus_id; - int ret; + int ret; + bool free_mdev = false; ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber; @@ -691,12 +692,32 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id) } switch (id->idProduct) { + case 0x900E: case 0x9025: + case 0x9091: case 0x901D: - dev_dbg(&udev->dev, "ifc_count: %u\n", ifc_count); + /* 1-1 mapping between ksb and udev port which starts with 1 */ + ksb_port_num = udev->portnum - 1; + dev_dbg(&udev->dev, "ifc_count: %u, port_num:%u\n", ifc_count, + ksb_port_num); if (ifc_count > 1) return -ENODEV; - /* fall-through */ + if (ksb_port_num >= NO_BRIDGE_INSTANCES) { + dev_err(&udev->dev, "port-num:%u invalid. Try first\n", + ksb_port_num); + ksb_port_num = 0; + } + ksb = __ksb[ksb_port_num]; + if (ksb->ifc) { + dev_err(&udev->dev, "port already in use\n"); + return -ENODEV; + } + mdev = kzalloc(sizeof(struct ksb_dev_info), GFP_KERNEL); + if (!mdev) + return -ENOMEM; + free_mdev = true; + mdev->name = ksb->name; + break; case 0x9008: ksb = __ksb[bus_id]; mdev = &fbdev[bus_id]; @@ -755,6 +776,8 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id) "could not find bulk in and bulk out endpoints"); usb_put_dev(ksb->udev); ksb->ifc = NULL; + if (free_mdev) + kfree(mdev); return -ENODEV; } @@ -808,7 +831,7 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id) goto fail_class_create; } - ksb->device = device_create(ksb->class, NULL, ksb->cdev_start_no, + ksb->device = device_create(ksb->class, &udev->dev, ksb->cdev_start_no, NULL, mdev->name); if (IS_ERR(ksb->device)) { dbg_log_event(ksb, "devcrfailed", PTR_ERR(ksb->device), 0); @@ -820,6 +843,8 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id) usb_enable_autosuspend(ksb->udev); } + if (free_mdev) + kfree(mdev); dev_dbg(&udev->dev, "usb dev connected"); return 0; @@ -832,6 +857,9 @@ fail_chrdev_region: usb_set_intfdata(ifc, NULL); clear_bit(USB_DEV_CONNECTED, &ksb->flags); + if (free_mdev) + kfree(mdev); + return -ENODEV; } @@ -991,7 +1019,7 @@ static int __init ksb_init(void) } __ksb[i] = ksb; - ksb->name = kasprintf(GFP_KERNEL, "ks_bridge:%i", i + 1); + ksb->name = kasprintf(GFP_KERNEL, "ks_usb_bridge.%i", i); if (!ksb->name) { pr_info("unable to allocate name"); kfree(ksb); |
