static int gport_disconnect(struct f_gser *gser)
{
	unsigned port_num;

	pr_debug("%s: transport: %s f_gser: %p gserial: %p port_num: %d\n",
			__func__, xport_to_str(gser->transport),
			gser, &gser->port, gser->port_num);

	port_num = gserial_ports[gser->port_num].client_port_num;

	switch (gser->transport) {
	case USB_GADGET_XPORT_TTY:
		gserial_disconnect(&gser->port);
		break;
	case USB_GADGET_XPORT_SDIO:
		gsdio_disconnect(&gser->port, port_num);
		break;
	case USB_GADGET_XPORT_SMD:
		gsmd_disconnect(&gser->port, port_num);
		break;
	case USB_GADGET_XPORT_HSIC:
		ghsic_ctrl_disconnect(&gser->port, port_num);
		ghsic_data_disconnect(&gser->port, port_num);
		break;
	case USB_GADGET_XPORT_HSUART:
		ghsuart_data_disconnect(&gser->port, port_num);
		break;
	default:
		pr_err("%s: Un-supported transport:%s\n", __func__,
				xport_to_str(gser->transport));
		return -ENODEV;
	}

	return 0;
}
Esempio n. 2
0
/**
 * gserial_init_port - bind a gserial_port to its transport
 */
static int gserial_init_port(int port_num, const char *name, char *serial_type)
{
	enum transport_type transport;
	enum fserial_func_type func_type;

	if (port_num >= GSERIAL_NO_PORTS)
		return -ENODEV;

	transport = str_to_xport(name);
	func_type = serial_str_to_func_type(serial_type);

	pr_info("%s, port:%d, transport:%s, type:%d\n", __func__,
				port_num, xport_to_str(transport), func_type);



	gserial_ports[port_num].transport = transport;
	gserial_ports[port_num].func_type = func_type;
	gserial_ports[port_num].port_num = port_num;

	switch (transport) {
	case USB_GADGET_XPORT_TTY:
		gserial_ports[port_num].client_port_num = no_tty_ports;
		no_tty_ports++;
		break;
	case USB_GADGET_XPORT_SDIO:
		gserial_ports[port_num].client_port_num = no_sdio_ports;
		no_sdio_ports++;
		break;
	case USB_GADGET_XPORT_SMD:
		gserial_ports[port_num].client_port_num = no_smd_ports;
		no_smd_ports++;
		break;
	case USB_GADGET_XPORT_HSIC:
		/*client port number will be updated in gport_setup*/
		no_hsic_sports++;
		break;
	case USB_GADGET_XPORT_HSUART:
		/*client port number will be updated in gport_setup*/
		no_hsuart_sports++;
		break;
	default:
		pr_err("%s: Un-supported transport transport: %u\n",
				__func__, gserial_ports[port_num].transport);
		return -ENODEV;
	}

	nr_ports++;

	return 0;
}
/**
 * gserial_init_port - bind a gserial_port to its transport
 */
static int gserial_init_port(int port_num, const char *name,
		const char *port_name)
{
	enum transport_type transport;
	int ret = 0;

	if (port_num >= GSERIAL_NO_PORTS)
		return -ENODEV;

	transport = str_to_xport(name);
	pr_debug("%s, port:%d, transport:%s\n", __func__,
			port_num, xport_to_str(transport));

	gserial_ports[port_num].transport = transport;
	gserial_ports[port_num].port_num = port_num;

	switch (transport) {
	case USB_GADGET_XPORT_TTY:
		gserial_ports[port_num].client_port_num = no_tty_ports;
		no_tty_ports++;
		break;
	case USB_GADGET_XPORT_SDIO:
		gserial_ports[port_num].client_port_num = no_sdio_ports;
		no_sdio_ports++;
		break;
	case USB_GADGET_XPORT_SMD:
		gserial_ports[port_num].client_port_num = no_smd_ports;
		no_smd_ports++;
		break;
	case USB_GADGET_XPORT_HSIC:
		ghsic_ctrl_set_port_name(port_name, name);
		ghsic_data_set_port_name(port_name, name);

		/*client port number will be updated in gport_setup*/
		no_hsic_sports++;
		break;
	case USB_GADGET_XPORT_HSUART:
		/*client port number will be updated in gport_setup*/
		no_hsuart_sports++;
		break;
	default:
		pr_err("%s: Un-supported transport transport: %u\n",
				__func__, gserial_ports[port_num].transport);
		return -ENODEV;
	}

	nr_ports++;

	return ret;
}
int gser_bind_config(struct usb_configuration *c, u8 port_num)
{
	struct f_gser	*gser;
	int		status;
	struct port_info *p = &gserial_ports[port_num];

	if (p->func_type == USB_FSER_FUNC_NONE) {
		pr_info("%s: non function port : %d\n", __func__, port_num);
		return 0;
	}
	pr_info("%s: type:%d, trasport: %s\n", __func__, p->func_type,
			xport_to_str(p->transport));


	
	
#if 0
	if (port_num != 0) {
	if (gser_string_defs[0].id == 0) {
		status = usb_string_id(c->cdev);
		if (status < 0)
			return status;
		gser_string_defs[0].id = status;
	}
	}
#endif

	if (modem_string_defs[0].id == 0 &&
			p->func_type == USB_FSER_FUNC_MODEM) {
		status = usb_string_id(c->cdev);
		if (status < 0) {
			printk(KERN_ERR "%s: return %d\n", __func__, status);
			return status;
		}
		modem_string_defs[0].id = status;
	}

	if (modem_string_defs[1].id == 0 &&
			p->func_type == USB_FSER_FUNC_MODEM_MDM) {
		status = usb_string_id(c->cdev);
		if (status < 0) {
			printk(KERN_ERR "%s: return %d\n", __func__, status);
			return status;
		}
		modem_string_defs[1].id = status;
	}

	if (gser_string_defs[0].id == 0 &&
			(p->func_type == USB_FSER_FUNC_SERIAL
			|| p->func_type == USB_FSER_FUNC_AUTOBOT)) {
		status = usb_string_id(c->cdev);
		if (status < 0) {
			printk(KERN_ERR "%s: return %d\n", __func__, status);
			return status;
		}
		gser_string_defs[0].id = status;
	}

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

#ifdef CONFIG_MODEM_SUPPORT
	spin_lock_init(&gser->lock);
#endif
	gser->port_num = port_num;

	gser->port.func.name = "gser";
	gser->port.func.strings = gser_strings;
	gser->port.func.bind = gser_bind;
	gser->port.func.unbind = gser_unbind;
	gser->port.func.set_alt = gser_set_alt;
	gser->port.func.disable = gser_disable;
	gser->transport		= gserial_ports[port_num].transport;
#ifdef CONFIG_MODEM_SUPPORT
	
	if (port_num == 0)
		gser->port.func.name = "modem";
	else
		gser->port.func.name = "nmea";
	gser->port.func.setup = gser_setup;
	gser->port.connect = gser_connect;
	gser->port.get_dtr = gser_get_dtr;
	gser->port.get_rts = gser_get_rts;
	gser->port.send_carrier_detect = gser_send_carrier_detect;
	gser->port.send_ring_indicator = gser_send_ring_indicator;
	gser->port.send_modem_ctrl_bits = gser_send_modem_ctrl_bits;
	gser->port.disconnect = gser_disconnect;
	gser->port.send_break = gser_send_break;
#endif

	switch (p->func_type) {
	case USB_FSER_FUNC_MODEM:
		gser->port.func.name = "modem";
		gser->port.func.strings = modem_strings;
		gser_interface_desc.iInterface = modem_string_defs[0].id;
		break;
	case USB_FSER_FUNC_MODEM_MDM:
		gser->port.func.name = "modem_mdm";
		gser->port.func.strings = modem_strings;
		gser_interface_desc.iInterface = modem_string_defs[1].id;
		break;
	case USB_FSER_FUNC_SERIAL:
	case USB_FSER_FUNC_AUTOBOT:
		gser->port.func.name = "serial";
		gser->port.func.strings = gser_strings;
		gser_interface_desc.iInterface = gser_string_defs[0].id;
		break;
	case USB_FSER_FUNC_NONE:
	default	:
		break;
	}


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