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

Commit 73b05bf5 authored by Jack Pham's avatar Jack Pham Committed by Matt Wagantall
Browse files

usb: gadget: Fixes to build RNDIS with android gadget



RNDIS is still using the legacy #include f_rndis.c approach. For
now, rig up a custom rndis_bind_config_vendor() API to call when
binding with the android gadget.

Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent 7b0533bd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
#
subdir-ccflags-$(CONFIG_USB_GADGET_DEBUG)	:= -DDEBUG
subdir-ccflags-$(CONFIG_USB_GADGET_VERBOSE)	+= -DVERBOSE_DEBUG
ccflags-y				+= -I$(srctree)/drivers/usb/gadget/udc
ccflags-y				+= -I$(srctree)/drivers/usb/gadget/udc -I$(srctree)/drivers/usb/gadget/function

obj-$(CONFIG_USB_LIBCOMPOSITE)	+= libcomposite.o
libcomposite-y			:= usbstring.o config.o epautoconf.o
+65 −1
Original line number Diff line number Diff line
@@ -725,7 +725,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
	 * with list_for_each_entry, so we assume no race condition
	 * with regard to rndis_opts->bound access
	 */
	if (!rndis_opts->bound) {
	if (f->fi && !rndis_opts->bound) {
		gether_set_gadget(rndis_opts->net, cdev->gadget);
		status = gether_register_netdev(rndis_opts->net);
		if (status)
@@ -870,6 +870,70 @@ fail:
	return status;
}

static void
rndis_old_unbind(struct usb_configuration *c, struct usb_function *f)
{
	struct f_rndis	*rndis = func_to_rndis(f);

	rndis_deregister(rndis->config);

	usb_free_all_descriptors(f);

	kfree(rndis->notify_req->buf);
	usb_ep_free_request(rndis->notify, rndis->notify_req);

	kfree(rndis);
}

int
rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
		u32 vendorID, const char *manufacturer, struct eth_dev *dev)
{
	struct f_rndis	*rndis;
	int		status;

	/* allocate and initialize one new
	   instance */
	status = -ENOMEM;
	rndis = kzalloc(sizeof *rndis, GFP_KERNEL);
	if (!rndis)
		goto fail;

	memcpy(rndis->ethaddr, ethaddr, ETH_ALEN);
	rndis->vendorID = vendorID;
	rndis->manufacturer = manufacturer;

	rndis->port.ioport = dev;
	/* RNDIS activates when the host changes this filter */
	rndis->port.cdc_filter = 0;

	/* RNDIS has special (and complex) framing */
	rndis->port.header_len = sizeof(struct rndis_packet_msg_type);
	rndis->port.wrap = rndis_add_header;
	rndis->port.unwrap = rndis_rm_hdr;

	rndis->port.func.name = "rndis";
	/* descriptors are per-instance copies */
	rndis->port.func.bind = rndis_bind;
	rndis->port.func.unbind = rndis_old_unbind;
	rndis->port.func.set_alt = rndis_set_alt;
	rndis->port.func.setup = rndis_setup;
	rndis->port.func.disable = rndis_disable;

	status = rndis_register(rndis_response_available, rndis);
	if (status < 0) {
		kfree(rndis);
		return status;
	}
	rndis->config = status;

	status = usb_add_function(c, &rndis->port.func);
	if (status)
		kfree(rndis);
fail:
	return status;
}

void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net)
{
	struct f_rndis_opts *opts;
+1 −1
Original line number Diff line number Diff line
@@ -1063,7 +1063,7 @@ int rndis_rm_hdr(struct gether *port,
		}

		if (skb->len < sizeof *hdr) {
			pr_err("invalid rndis pkt: skblen:%u hdr_len:%u",
			pr_err("invalid rndis pkt: skblen:%u hdr_len:%zu",
					skb->len, sizeof *hdr);
			dev_kfree_skb_any(skb);
			return -EINVAL;