Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16fd5426 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: misc: ks_bridge: handle multiple ksb devices enumeration"

parents a7b196ab 5e4f3a6c
Loading
Loading
Loading
Loading
+38 −10
Original line number Original line Diff line number Diff line
@@ -458,10 +458,10 @@ static struct ksb_dev_info ksb_efs_usb_dev = {
static const struct usb_device_id ksb_usb_ids[] = {
static const struct usb_device_id ksb_usb_ids[] = {
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9008, 0),
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9008, 0),
	.driver_info = (unsigned long)&ksb_fboot_dev, },
	.driver_info = (unsigned long)&ksb_fboot_dev, },
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9025, 0),
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9025, 0), },
	.driver_info = (unsigned long)&ksb_fboot_dev, },
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9091, 0), },
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x901D, 0),
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x901D, 0), },
	.driver_info = (unsigned long)&ksb_fboot_dev, },
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x900E, 0), },
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 2),
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 2),
	.driver_info = (unsigned long)&ksb_efs_hsic_dev, },
	.driver_info = (unsigned long)&ksb_efs_hsic_dev, },
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904C, 2),
	{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x904C, 2),
@@ -664,7 +664,7 @@ static void ksb_start_rx_work(struct work_struct *w)
static int
static int
ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id)
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_host_interface	*ifc_desc;
	struct usb_endpoint_descriptor	*ep_desc;
	struct usb_endpoint_descriptor	*ep_desc;
	int				i;
	int				i;
@@ -675,6 +675,7 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id)
	struct usb_device		*udev;
	struct usb_device		*udev;
	unsigned int			bus_id;
	unsigned int			bus_id;
	int				ret;
	int				ret;
	bool				free_mdev = false;


	ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber;
	ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber;


@@ -690,12 +691,32 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id)
	}
	}


	switch (id->idProduct) {
	switch (id->idProduct) {
	case 0x900E:
	case 0x9025:
	case 0x9025:
	case 0x9091:
	case 0x901D:
	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)
		if (ifc_count > 1)
			return -ENODEV;
			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:
	case 0x9008:
		ksb = __ksb[bus_id];
		ksb = __ksb[bus_id];
		mdev = &fbdev[bus_id];
		mdev = &fbdev[bus_id];
@@ -754,6 +775,8 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id)
			"could not find bulk in and bulk out endpoints");
			"could not find bulk in and bulk out endpoints");
		usb_put_dev(ksb->udev);
		usb_put_dev(ksb->udev);
		ksb->ifc = NULL;
		ksb->ifc = NULL;
		if (free_mdev)
			kfree(mdev);
		return -ENODEV;
		return -ENODEV;
	}
	}


@@ -807,7 +830,7 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id)
		goto fail_class_create;
		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);
				NULL, mdev->name);
	if (IS_ERR(ksb->device)) {
	if (IS_ERR(ksb->device)) {
		dbg_log_event(ksb, "devcrfailed", PTR_ERR(ksb->device), 0);
		dbg_log_event(ksb, "devcrfailed", PTR_ERR(ksb->device), 0);
@@ -819,6 +842,8 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id)
		usb_enable_autosuspend(ksb->udev);
		usb_enable_autosuspend(ksb->udev);
	}
	}


	if (free_mdev)
		kfree(mdev);
	dev_dbg(&udev->dev, "usb dev connected");
	dev_dbg(&udev->dev, "usb dev connected");


	return 0;
	return 0;
@@ -831,6 +856,9 @@ fail_chrdev_region:
	usb_set_intfdata(ifc, NULL);
	usb_set_intfdata(ifc, NULL);
	clear_bit(USB_DEV_CONNECTED, &ksb->flags);
	clear_bit(USB_DEV_CONNECTED, &ksb->flags);


	if (free_mdev)
		kfree(mdev);

	return -ENODEV;
	return -ENODEV;


}
}
@@ -990,7 +1018,7 @@ static int __init ksb_init(void)
		}
		}
		__ksb[i] = ksb;
		__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) {
		if (!ksb->name) {
			pr_info("unable to allocate name");
			pr_info("unable to allocate name");
			kfree(ksb);
			kfree(ksb);