int gport_setup(struct usb_configuration *c)
{
	int ret = 0;
	int port_idx;
	int i;

	pr_debug("%s: no_tty_ports: %u no_sdio_ports: %u"
		" no_smd_ports: %u no_hsic_sports: %u no_hsuart_ports: %u nr_ports: %u\n",
			__func__, no_tty_ports, no_sdio_ports, no_smd_ports,
			no_hsic_sports, no_hsuart_sports, nr_ports);

	if (no_tty_ports) {
		for (i = 0; i < no_tty_ports; i++) {
			ret = gserial_alloc_line(
					&gserial_ports[i].client_port_num);
			if (ret)
				return ret;
		}
	}

	if (no_sdio_ports)
		ret = gsdio_setup(c->cdev->gadget, no_sdio_ports);
	if (no_smd_ports)
		ret = gsmd_setup(c->cdev->gadget, no_smd_ports);
	if (no_hsic_sports) {
		port_idx = ghsic_data_setup(no_hsic_sports, USB_GADGET_SERIAL);
		if (port_idx < 0)
			return port_idx;

		for (i = 0; i < nr_ports; i++) {
			if (gserial_ports[i].transport ==
					USB_GADGET_XPORT_HSIC) {
				gserial_ports[i].client_port_num = port_idx;
				port_idx++;
			}
		}

		/*clinet port num is same for data setup and ctrl setup*/
		ret = ghsic_ctrl_setup(no_hsic_sports, USB_GADGET_SERIAL);
		if (ret < 0)
			return ret;
	}
	if (no_hsuart_sports) {
		port_idx = ghsuart_data_setup(no_hsuart_sports,
					USB_GADGET_SERIAL);
		if (port_idx < 0)
			return port_idx;

		for (i = 0; i < nr_ports; i++) {
			if (gserial_ports[i].transport ==
					USB_GADGET_XPORT_HSUART) {
				gserial_ports[i].client_port_num = port_idx;
				port_idx++;
			}
		}
	}
	return ret;
}
示例#2
0
文件: acm_ms.c 项目: AiWinters/linux
static int __init acm_ms_bind(struct usb_composite_dev *cdev)
{
	struct usb_gadget	*gadget = cdev->gadget;
	int			status;
	void			*retp;

	/* set up serial link layer */
	status = gserial_alloc_line(&tty_line);
	if (status < 0)
		return status;

	/* set up mass storage function */
	retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
	if (IS_ERR(retp)) {
		status = PTR_ERR(retp);
		goto fail0;
	}

	/*
	 * Allocate string descriptor numbers ... note that string
	 * contents can be overridden by the composite_dev glue.
	 */
	status = usb_string_ids_tab(cdev, strings_dev);
	if (status < 0)
		goto fail1;
	device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
	device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;

	/* register our configuration */
	status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config);
	if (status < 0)
		goto fail1;

	usb_composite_overwrite_options(cdev, &coverwrite);
	dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
			DRIVER_DESC);
	fsg_common_put(&fsg_common);
	return 0;

	/* error recovery */
fail1:
	fsg_common_put(&fsg_common);
fail0:
	gserial_free_line(tty_line);
	return status;
}
示例#3
0
static struct usb_function_instance *acm_alloc_instance(void)
{
	struct f_serial_opts *opts;
	int ret;

	opts = kzalloc(sizeof(*opts), GFP_KERNEL);
	if (!opts)
		return ERR_PTR(-ENOMEM);
	opts->func_inst.free_func_inst = acm_free_instance;
	ret = gserial_alloc_line(&opts->port_num);
	if (ret) {
		kfree(opts);
		return ERR_PTR(ret);
	}
	config_group_init_type_name(&opts->func_inst.group, "",
			&acm_func_type);
	return &opts->func_inst;
}
static struct usb_function_instance *gser_alloc_inst(void)
{
	struct f_serial_opts *opts;
	int ret;

	opts = kzalloc(sizeof(*opts), GFP_KERNEL);
	if (!opts)
		return ERR_PTR(-ENOMEM);

	opts->func_inst.free_func_inst = gser_free_inst;

	/* Check if tty registration is handled here or not */
	if (!nr_ports) {
		ret = gserial_alloc_line(&opts->port_num);
		if (ret) {
			kfree(opts);
			return ERR_PTR(ret);
		}
	}
	config_group_init_type_name(&opts->func_inst.group, "",
				    &serial_func_type);

	return &opts->func_inst;
}