diff options
| -rw-r--r-- | drivers/usb/serial/ch341.c | 85 | ||||
| -rw-r--r-- | drivers/usb/serial/cp210x.c | 109 | ||||
| -rw-r--r-- | drivers/usb/serial/f81232.c | 96 | ||||
| -rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 53 | ||||
| -rw-r--r-- | drivers/usb/serial/keyspan.c | 15 | ||||
| -rw-r--r-- | drivers/usb/serial/keyspan_pda.c | 67 | ||||
| -rw-r--r-- | drivers/usb/serial/kl5kusb105.c | 115 | ||||
| -rw-r--r-- | drivers/usb/serial/usb-serial.c | 59 | 
8 files changed, 215 insertions, 384 deletions
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 2db917eab799..29f4b87a9e74 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -131,17 +131,11 @@ static int ch341_control_in(struct usb_device *dev,  	dev_dbg(&dev->dev, "%s - (%02x,%04x,%04x,%u)\n", __func__,  		request, value, index, bufsize); -	r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, -			    USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, -			    value, index, buf, bufsize, DEFAULT_TIMEOUT); -	if (r < (int)bufsize) { -		if (r >= 0) { -			dev_err(&dev->dev, -				"short control message received (%d < %u)\n", -				r, bufsize); -			r = -EIO; -		} - +	r = usb_control_msg_recv(dev, 0, request, +				 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, +				 value, index, buf, bufsize, DEFAULT_TIMEOUT, +				 GFP_KERNEL); +	if (r) {  		dev_err(&dev->dev, "failed to receive control message: %d\n",  			r);  		return r; @@ -287,24 +281,19 @@ static int ch341_set_handshake(struct usb_device *dev, u8 control)  static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)  {  	const unsigned int size = 2; -	char *buffer; +	u8 buffer[2];  	int r;  	unsigned long flags; -	buffer = kmalloc(size, GFP_KERNEL); -	if (!buffer) -		return -ENOMEM; -  	r = ch341_control_in(dev, CH341_REQ_READ_REG, 0x0706, 0, buffer, size); -	if (r < 0) -		goto out; +	if (r) +		return r;  	spin_lock_irqsave(&priv->lock, flags);  	priv->msr = (~(*buffer)) & CH341_BITS_MODEM_STAT;  	spin_unlock_irqrestore(&priv->lock, flags); -out:	kfree(buffer); -	return r; +	return 0;  }  /* -------------------------------------------------------------------------- */ @@ -312,31 +301,28 @@ out:	kfree(buffer);  static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)  {  	const unsigned int size = 2; -	char *buffer; +	u8 buffer[2];  	int r; -	buffer = kmalloc(size, GFP_KERNEL); -	if (!buffer) -		return -ENOMEM; -  	/* expect two bytes 0x27 0x00 */  	r = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size); -	if (r < 0) -		goto out; +	if (r) +		return r;  	dev_dbg(&dev->dev, "Chip version: 0x%02x\n", buffer[0]);  	r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0);  	if (r < 0) -		goto out; +		return r;  	r = ch341_set_baudrate_lcr(dev, priv, priv->baud_rate, priv->lcr);  	if (r < 0) -		goto out; +		return r;  	r = ch341_set_handshake(dev, priv->mcr); +	if (r < 0) +		return r; -out:	kfree(buffer); -	return r; +	return 0;  }  static int ch341_detect_quirks(struct usb_serial_port *port) @@ -345,40 +331,27 @@ static int ch341_detect_quirks(struct usb_serial_port *port)  	struct usb_device *udev = port->serial->dev;  	const unsigned int size = 2;  	unsigned long quirks = 0; -	char *buffer; +	u8 buffer[2];  	int r; -	buffer = kmalloc(size, GFP_KERNEL); -	if (!buffer) -		return -ENOMEM; -  	/*  	 * A subset of CH34x devices does not support all features. The  	 * prescaler is limited and there is no support for sending a RS232  	 * break condition. A read failure when trying to set up the latter is  	 * used to detect these devices.  	 */ -	r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), CH341_REQ_READ_REG, -			    USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, -			    CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT); +	r = usb_control_msg_recv(udev, 0, CH341_REQ_READ_REG, +				 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, +				 CH341_REG_BREAK, 0, &buffer, size, +				 DEFAULT_TIMEOUT, GFP_KERNEL);  	if (r == -EPIPE) {  		dev_info(&port->dev, "break control not supported, using simulated break\n");  		quirks = CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK;  		r = 0; -		goto out; -	} - -	if (r != size) { -		if (r >= 0) -			r = -EIO; +	} else if (r) {  		dev_err(&port->dev, "failed to read break control: %d\n", r); -		goto out;  	} -	r = 0; -out: -	kfree(buffer); -  	if (quirks) {  		dev_dbg(&port->dev, "enabling quirk flags: 0x%02lx\n", quirks);  		priv->quirks |= quirks; @@ -647,23 +620,19 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)  	struct ch341_private *priv = usb_get_serial_port_data(port);  	int r;  	uint16_t reg_contents; -	uint8_t *break_reg; +	uint8_t break_reg[2];  	if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK) {  		ch341_simulate_break(tty, break_state);  		return;  	} -	break_reg = kmalloc(2, GFP_KERNEL); -	if (!break_reg) -		return; -  	r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG,  			ch341_break_reg, 0, break_reg, 2); -	if (r < 0) { +	if (r) {  		dev_err(&port->dev, "%s - USB control read error (%d)\n",  				__func__, r); -		goto out; +		return;  	}  	dev_dbg(&port->dev, "%s - initial ch341 break register contents - reg1: %x, reg2: %x\n",  		__func__, break_reg[0], break_reg[1]); @@ -684,8 +653,6 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)  	if (r < 0)  		dev_err(&port->dev, "%s - USB control write error (%d)\n",  				__func__, r); -out: -	kfree(break_reg);  }  static int ch341_tiocmset(struct tty_struct *tty, diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 189279869a8b..7705328034ca 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -631,30 +631,20 @@ static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req,  {  	struct usb_serial *serial = port->serial;  	struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); -	void *dmabuf;  	int result; -	dmabuf = kmalloc(bufsize, GFP_KERNEL); -	if (!dmabuf) -		return -ENOMEM; -	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), -			req, REQTYPE_INTERFACE_TO_HOST, 0, -			port_priv->bInterfaceNumber, dmabuf, bufsize, -			USB_CTRL_GET_TIMEOUT); -	if (result == bufsize) { -		memcpy(buf, dmabuf, bufsize); -		result = 0; -	} else { +	result = usb_control_msg_recv(serial->dev, 0, req, +			REQTYPE_INTERFACE_TO_HOST, 0, +			port_priv->bInterfaceNumber, buf, bufsize, +			USB_CTRL_SET_TIMEOUT, GFP_KERNEL); +	if (result) {  		dev_err(&port->dev, "failed get req 0x%x size %d status: %d\n",  				req, bufsize, result); -		if (result >= 0) -			result = -EIO; +		return result;  	} -	kfree(dmabuf); - -	return result; +	return 0;  }  /* @@ -672,31 +662,19 @@ static int cp210x_read_u8_reg(struct usb_serial_port *port, u8 req, u8 *val)  static int cp210x_read_vendor_block(struct usb_serial *serial, u8 type, u16 val,  				    void *buf, int bufsize)  { -	void *dmabuf;  	int result; -	dmabuf = kmalloc(bufsize, GFP_KERNEL); -	if (!dmabuf) -		return -ENOMEM; - -	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), -				 CP210X_VENDOR_SPECIFIC, type, val, -				 cp210x_interface_num(serial), dmabuf, bufsize, -				 USB_CTRL_GET_TIMEOUT); -	if (result == bufsize) { -		memcpy(buf, dmabuf, bufsize); -		result = 0; -	} else { +	result = usb_control_msg_recv(serial->dev, 0, CP210X_VENDOR_SPECIFIC, +			type, val, cp210x_interface_num(serial), buf, bufsize, +			USB_CTRL_GET_TIMEOUT, GFP_KERNEL); +	if (result) {  		dev_err(&serial->interface->dev,  			"failed to get vendor val 0x%04x size %d: %d\n", val,  			bufsize, result); -		if (result >= 0) -			result = -EIO; +		return result;  	} -	kfree(dmabuf); - -	return result; +	return 0;  }  /* @@ -730,21 +708,13 @@ static int cp210x_write_reg_block(struct usb_serial_port *port, u8 req,  {  	struct usb_serial *serial = port->serial;  	struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); -	void *dmabuf;  	int result; -	dmabuf = kmemdup(buf, bufsize, GFP_KERNEL); -	if (!dmabuf) -		return -ENOMEM; - -	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), -			req, REQTYPE_HOST_TO_INTERFACE, 0, -			port_priv->bInterfaceNumber, dmabuf, bufsize, -			USB_CTRL_SET_TIMEOUT); - -	kfree(dmabuf); - -	if (result < 0) { +	result = usb_control_msg_send(serial->dev, 0, req, +			REQTYPE_HOST_TO_INTERFACE, 0, +			port_priv->bInterfaceNumber, buf, bufsize, +			USB_CTRL_SET_TIMEOUT, GFP_KERNEL); +	if (result) {  		dev_err(&port->dev, "failed set req 0x%x size %d status: %d\n",  				req, bufsize, result);  		return result; @@ -773,21 +743,12 @@ static int cp210x_write_u32_reg(struct usb_serial_port *port, u8 req, u32 val)  static int cp210x_write_vendor_block(struct usb_serial *serial, u8 type,  				     u16 val, void *buf, int bufsize)  { -	void *dmabuf;  	int result; -	dmabuf = kmemdup(buf, bufsize, GFP_KERNEL); -	if (!dmabuf) -		return -ENOMEM; - -	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), -				 CP210X_VENDOR_SPECIFIC, type, val, -				 cp210x_interface_num(serial), dmabuf, bufsize, -				 USB_CTRL_SET_TIMEOUT); - -	kfree(dmabuf); - -	if (result < 0) { +	result = usb_control_msg_send(serial->dev, 0, CP210X_VENDOR_SPECIFIC, +			type, val, cp210x_interface_num(serial), buf, bufsize, +			USB_CTRL_SET_TIMEOUT, GFP_KERNEL); +	if (result) {  		dev_err(&serial->interface->dev,  			"failed to set vendor val 0x%04x size %d: %d\n", val,  			bufsize, result); @@ -952,29 +913,21 @@ static int cp210x_get_tx_queue_byte_count(struct usb_serial_port *port,  {  	struct usb_serial *serial = port->serial;  	struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); -	struct cp210x_comm_status *sts; +	struct cp210x_comm_status sts;  	int result; -	sts = kmalloc(sizeof(*sts), GFP_KERNEL); -	if (!sts) -		return -ENOMEM; - -	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), -			CP210X_GET_COMM_STATUS, REQTYPE_INTERFACE_TO_HOST, -			0, port_priv->bInterfaceNumber, sts, sizeof(*sts), -			USB_CTRL_GET_TIMEOUT); -	if (result == sizeof(*sts)) { -		*count = le32_to_cpu(sts->ulAmountInOutQueue); -		result = 0; -	} else { +	result = usb_control_msg_recv(serial->dev, 0, CP210X_GET_COMM_STATUS, +			REQTYPE_INTERFACE_TO_HOST, 0, +			port_priv->bInterfaceNumber, &sts, sizeof(sts), +			USB_CTRL_GET_TIMEOUT, GFP_KERNEL); +	if (result) {  		dev_err(&port->dev, "failed to get comm status: %d\n", result); -		if (result >= 0) -			result = -EIO; +		return result;  	} -	kfree(sts); +	*count = le32_to_cpu(sts.ulAmountInOutQueue); -	return result; +	return 0;  }  static bool cp210x_tx_empty(struct usb_serial_port *port) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index a7a7af8d05bf..3ad1f515fb68 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -139,67 +139,46 @@ static int calc_baud_divisor(speed_t baudrate, speed_t clockrate)  static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *val)  {  	int status; -	u8 *tmp;  	struct usb_device *dev = port->serial->dev; -	tmp = kmalloc(sizeof(*val), GFP_KERNEL); -	if (!tmp) -		return -ENOMEM; - -	status = usb_control_msg(dev, -				usb_rcvctrlpipe(dev, 0), -				F81232_REGISTER_REQUEST, -				F81232_GET_REGISTER, -				reg, -				0, -				tmp, -				sizeof(*val), -				USB_CTRL_GET_TIMEOUT); -	if (status != sizeof(*val)) { +	status = usb_control_msg_recv(dev, +				      0, +				      F81232_REGISTER_REQUEST, +				      F81232_GET_REGISTER, +				      reg, +				      0, +				      val, +				      sizeof(*val), +				      USB_CTRL_GET_TIMEOUT, +				      GFP_KERNEL); +	if (status) {  		dev_err(&port->dev, "%s failed status: %d\n", __func__, status); - -		if (status < 0) -			status = usb_translate_errors(status); -		else -			status = -EIO; -	} else { -		status = 0; -		*val = *tmp; +		status = usb_translate_errors(status);  	} -	kfree(tmp);  	return status;  }  static int f81232_set_register(struct usb_serial_port *port, u16 reg, u8 val)  {  	int status; -	u8 *tmp;  	struct usb_device *dev = port->serial->dev; -	tmp = kmalloc(sizeof(val), GFP_KERNEL); -	if (!tmp) -		return -ENOMEM; - -	*tmp = val; - -	status = usb_control_msg(dev, -				usb_sndctrlpipe(dev, 0), -				F81232_REGISTER_REQUEST, -				F81232_SET_REGISTER, -				reg, -				0, -				tmp, -				sizeof(val), -				USB_CTRL_SET_TIMEOUT); -	if (status < 0) { +	status = usb_control_msg_send(dev, +				      0, +				      F81232_REGISTER_REQUEST, +				      F81232_SET_REGISTER, +				      reg, +				      0, +				      &val, +				      sizeof(val), +				      USB_CTRL_SET_TIMEOUT, +				      GFP_KERNEL); +	if (status) {  		dev_err(&port->dev, "%s failed status: %d\n", __func__, status);  		status = usb_translate_errors(status); -	} else { -		status = 0;  	} -	kfree(tmp);  	return status;  } @@ -857,28 +836,22 @@ static int f81534a_ctrl_set_register(struct usb_interface *intf, u16 reg,  	struct usb_device *dev = interface_to_usbdev(intf);  	int retry = F81534A_ACCESS_REG_RETRY;  	int status; -	u8 *tmp; - -	tmp = kmemdup(val, size, GFP_KERNEL); -	if (!tmp) -		return -ENOMEM;  	while (retry--) { -		status = usb_control_msg(dev, -					usb_sndctrlpipe(dev, 0), -					F81232_REGISTER_REQUEST, -					F81232_SET_REGISTER, -					reg, -					0, -					tmp, -					size, -					USB_CTRL_SET_TIMEOUT); -		if (status < 0) { +		status = usb_control_msg_send(dev, +					      0, +					      F81232_REGISTER_REQUEST, +					      F81232_SET_REGISTER, +					      reg, +					      0, +					      val, +					      size, +					      USB_CTRL_SET_TIMEOUT, +					      GFP_KERNEL); +		if (status) {  			status = usb_translate_errors(status);  			if (status == -EIO)  				continue; -		} else { -			status = 0;  		}  		break; @@ -889,7 +862,6 @@ static int f81534a_ctrl_set_register(struct usb_interface *intf, u16 reg,  				reg, status);  	} -	kfree(tmp);  	return status;  } diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 99d19828dae6..4edebd14ef29 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1437,27 +1437,15 @@ static int _read_latency_timer(struct usb_serial_port *port)  {  	struct ftdi_private *priv = usb_get_serial_port_data(port);  	struct usb_device *udev = port->serial->dev; -	unsigned char *buf; +	u8 buf;  	int rv; -	buf = kmalloc(1, GFP_KERNEL); -	if (!buf) -		return -ENOMEM; - -	rv = usb_control_msg(udev, -			     usb_rcvctrlpipe(udev, 0), -			     FTDI_SIO_GET_LATENCY_TIMER_REQUEST, -			     FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, -			     0, priv->interface, -			     buf, 1, WDR_TIMEOUT); -	if (rv < 1) { -		if (rv >= 0) -			rv = -EIO; -	} else { -		rv = buf[0]; -	} - -	kfree(buf); +	rv = usb_control_msg_recv(udev, 0, FTDI_SIO_GET_LATENCY_TIMER_REQUEST, +				  FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, 0, +				  priv->interface, &buf, 1, WDR_TIMEOUT, +				  GFP_KERNEL); +	if (rv == 0) +		rv = buf;  	return rv;  } @@ -1852,32 +1840,21 @@ static int ftdi_read_cbus_pins(struct usb_serial_port *port)  {  	struct ftdi_private *priv = usb_get_serial_port_data(port);  	struct usb_serial *serial = port->serial; -	unsigned char *buf; +	u8 buf;  	int result;  	result = usb_autopm_get_interface(serial->interface);  	if (result)  		return result; -	buf = kmalloc(1, GFP_KERNEL); -	if (!buf) { -		usb_autopm_put_interface(serial->interface); -		return -ENOMEM; -	} - -	result = usb_control_msg(serial->dev, -				 usb_rcvctrlpipe(serial->dev, 0), -				 FTDI_SIO_READ_PINS_REQUEST, -				 FTDI_SIO_READ_PINS_REQUEST_TYPE, 0, -				 priv->interface, buf, 1, WDR_TIMEOUT); -	if (result < 1) { -		if (result >= 0) -			result = -EIO; -	} else { -		result = buf[0]; -	} +	result = usb_control_msg_recv(serial->dev, 0, +				      FTDI_SIO_READ_PINS_REQUEST, +				      FTDI_SIO_READ_PINS_REQUEST_TYPE, 0, +				      priv->interface, &buf, 1, WDR_TIMEOUT, +				      GFP_KERNEL); +	if (result == 0) +		result = buf; -	kfree(buf);  	usb_autopm_put_interface(serial->interface);  	return result; diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 87b89c99d517..1cfcd805f286 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -2890,22 +2890,22 @@ static int keyspan_port_probe(struct usb_serial_port *port)  	for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i) {  		p_priv->in_buffer[i] = kzalloc(IN_BUFLEN, GFP_KERNEL);  		if (!p_priv->in_buffer[i]) -			goto err_in_buffer; +			goto err_free_in_buffer;  	}  	for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i) {  		p_priv->out_buffer[i] = kzalloc(OUT_BUFLEN, GFP_KERNEL);  		if (!p_priv->out_buffer[i]) -			goto err_out_buffer; +			goto err_free_out_buffer;  	}  	p_priv->inack_buffer = kzalloc(INACK_BUFLEN, GFP_KERNEL);  	if (!p_priv->inack_buffer) -		goto err_inack_buffer; +		goto err_free_out_buffer;  	p_priv->outcont_buffer = kzalloc(OUTCONT_BUFLEN, GFP_KERNEL);  	if (!p_priv->outcont_buffer) -		goto err_outcont_buffer; +		goto err_free_inack_buffer;  	p_priv->device_details = d_details; @@ -2951,15 +2951,14 @@ static int keyspan_port_probe(struct usb_serial_port *port)  	return 0; -err_outcont_buffer: +err_free_inack_buffer:  	kfree(p_priv->inack_buffer); -err_inack_buffer: +err_free_out_buffer:  	for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i)  		kfree(p_priv->out_buffer[i]); -err_out_buffer: +err_free_in_buffer:  	for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i)  		kfree(p_priv->in_buffer[i]); -err_in_buffer:  	kfree(p_priv);  	return -ENOMEM; diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 39b0f5f344c2..3e7628becdcd 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -77,36 +77,27 @@ static int keyspan_pda_get_write_room(struct keyspan_pda_private *priv)  {  	struct usb_serial_port *port = priv->port;  	struct usb_serial *serial = port->serial; -	u8 *room; +	u8 room;  	int rc; -	room = kmalloc(1, GFP_KERNEL); -	if (!room) -		return -ENOMEM; - -	rc = usb_control_msg(serial->dev, -			     usb_rcvctrlpipe(serial->dev, 0), -			     6, /* write_room */ -			     USB_TYPE_VENDOR | USB_RECIP_INTERFACE -			     | USB_DIR_IN, -			     0, /* value: 0 means "remaining room" */ -			     0, /* index */ -			     room, -			     1, -			     2000); -	if (rc != 1) { -		if (rc >= 0) -			rc = -EIO; +	rc = usb_control_msg_recv(serial->dev, +				  0, +				  6, /* write_room */ +				  USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_IN, +				  0, /* value: 0 means "remaining room" */ +				  0, /* index */ +				  &room, +				  1, +				  2000, +				  GFP_KERNEL); +	if (rc) {  		dev_dbg(&port->dev, "roomquery failed: %d\n", rc); -		goto out_free; +		return rc;  	} -	dev_dbg(&port->dev, "roomquery says %d\n", *room); -	rc = *room; -out_free: -	kfree(room); +	dev_dbg(&port->dev, "roomquery says %d\n", room); -	return rc; +	return room;  }  static void keyspan_pda_request_unthrottle(struct work_struct *work) @@ -381,22 +372,20 @@ static int keyspan_pda_get_modem_info(struct usb_serial *serial,  				      unsigned char *value)  {  	int rc; -	u8 *data; - -	data = kmalloc(1, GFP_KERNEL); -	if (!data) -		return -ENOMEM; - -	rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), -			     3, /* get pins */ -			     USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN, -			     0, 0, data, 1, 2000); -	if (rc == 1) -		*value = *data; -	else if (rc >= 0) -		rc = -EIO; +	u8 data; + +	rc = usb_control_msg_recv(serial->dev, 0, +				  3, /* get pins */ +				  USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_IN, +				  0, +				  0, +				  &data, +				  1, +				  2000, +				  GFP_KERNEL); +	if (rc == 0) +		*value = data; -	kfree(data);  	return rc;  } diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index f1e9628a9907..edcc57bd9b5e 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -124,16 +124,18 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port,  {  	int rc; -	rc = usb_control_msg(port->serial->dev, -			usb_sndctrlpipe(port->serial->dev, 0), -			KL5KUSB105A_SIO_SET_DATA, -			USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_INTERFACE, -			0, /* value */ -			0, /* index */ -			settings, -			sizeof(struct klsi_105_port_settings), -			KLSI_TIMEOUT); -	if (rc < 0) +	rc = usb_control_msg_send(port->serial->dev, +				  0, +				  KL5KUSB105A_SIO_SET_DATA, +				  USB_TYPE_VENDOR | USB_DIR_OUT | +				  USB_RECIP_INTERFACE, +				  0, /* value */ +				  0, /* index */ +				  settings, +				  sizeof(struct klsi_105_port_settings), +				  KLSI_TIMEOUT, +				  GFP_KERNEL); +	if (rc)  		dev_err(&port->dev,  			"Change port settings failed (error = %d)\n", rc); @@ -145,61 +147,37 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port,  	return rc;  } -/* translate a 16-bit status value from the device to linux's TIO bits */ -static unsigned long klsi_105_status2linestate(const __u16 status) -{ -	unsigned long res = 0; - -	res =   ((status & KL5KUSB105A_DSR) ? TIOCM_DSR : 0) -	      | ((status & KL5KUSB105A_CTS) ? TIOCM_CTS : 0) -	      ; - -	return res; -} -  /*   * Read line control via vendor command and return result through - * *line_state_p + * the state pointer.   */ -/* It seems that the status buffer has always only 2 bytes length */ -#define KLSI_STATUSBUF_LEN	2  static int klsi_105_get_line_state(struct usb_serial_port *port, -				   unsigned long *line_state_p) +				   unsigned long *state)  { +	u16 status;  	int rc; -	u8 *status_buf; -	__u16 status; - -	status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL); -	if (!status_buf) -		return -ENOMEM; -	status_buf[0] = 0xff; -	status_buf[1] = 0xff; -	rc = usb_control_msg(port->serial->dev, -			     usb_rcvctrlpipe(port->serial->dev, 0), -			     KL5KUSB105A_SIO_POLL, -			     USB_TYPE_VENDOR | USB_DIR_IN, -			     0, /* value */ -			     0, /* index */ -			     status_buf, KLSI_STATUSBUF_LEN, -			     10000 -			     ); -	if (rc != KLSI_STATUSBUF_LEN) { +	rc = usb_control_msg_recv(port->serial->dev, 0, +				  KL5KUSB105A_SIO_POLL, +				  USB_TYPE_VENDOR | USB_DIR_IN, +				  0, /* value */ +				  0, /* index */ +				  &status, sizeof(status), +				  10000, +				  GFP_KERNEL); +	if (rc) {  		dev_err(&port->dev, "reading line status failed: %d\n", rc); -		if (rc >= 0) -			rc = -EIO; -	} else { -		status = get_unaligned_le16(status_buf); +		return rc; +	} -		dev_dbg(&port->dev, "read status %02x %02x\n", -			status_buf[0], status_buf[1]); +	le16_to_cpus(&status); -		*line_state_p = klsi_105_status2linestate(status); -	} +	dev_dbg(&port->dev, "read status %04x\n", status); -	kfree(status_buf); -	return rc; +	*state = ((status & KL5KUSB105A_DSR) ? TIOCM_DSR : 0) | +		 ((status & KL5KUSB105A_CTS) ? TIOCM_CTS : 0); + +	return 0;  } @@ -245,7 +223,7 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)  	int retval = 0;  	int rc;  	unsigned long line_state; -	struct klsi_105_port_settings *cfg; +	struct klsi_105_port_settings cfg;  	unsigned long flags;  	/* Do a defined restart: @@ -255,27 +233,22 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)  	 * Then read the modem line control and store values in  	 * priv->line_state.  	 */ -	cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); -	if (!cfg) -		return -ENOMEM; -	cfg->pktlen   = 5; -	cfg->baudrate = kl5kusb105a_sio_b9600; -	cfg->databits = kl5kusb105a_dtb_8; -	cfg->unknown1 = 0; -	cfg->unknown2 = 1; -	klsi_105_chg_port_settings(port, cfg); +	cfg.pktlen   = 5; +	cfg.baudrate = kl5kusb105a_sio_b9600; +	cfg.databits = kl5kusb105a_dtb_8; +	cfg.unknown1 = 0; +	cfg.unknown2 = 1; +	klsi_105_chg_port_settings(port, &cfg);  	spin_lock_irqsave(&priv->lock, flags); -	priv->cfg.pktlen   = cfg->pktlen; -	priv->cfg.baudrate = cfg->baudrate; -	priv->cfg.databits = cfg->databits; -	priv->cfg.unknown1 = cfg->unknown1; -	priv->cfg.unknown2 = cfg->unknown2; +	priv->cfg.pktlen   = cfg.pktlen; +	priv->cfg.baudrate = cfg.baudrate; +	priv->cfg.databits = cfg.databits; +	priv->cfg.unknown1 = cfg.unknown1; +	priv->cfg.unknown2 = cfg.unknown2;  	spin_unlock_irqrestore(&priv->lock, flags); -	kfree(cfg); -  	/* READ_ON and urb submission */  	rc = usb_serial_generic_open(tty, port);  	if (rc) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 090a78c948f2..24101bd7fcad 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -208,8 +208,8 @@ void usb_serial_put(struct usb_serial *serial)   *   * This is the first place a new tty gets used.  Hence this is where we   * acquire references to the usb_serial structure and the driver module, - * where we store a pointer to the port, and where we do an autoresume. - * All these actions are reversed in serial_cleanup(). + * where we store a pointer to the port.  All these actions are reversed + * in serial_cleanup().   */  static int serial_install(struct tty_driver *driver, struct tty_struct *tty)  { @@ -225,17 +225,13 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty)  	serial = port->serial;  	if (!try_module_get(serial->type->driver.owner)) -		goto error_module_get; - -	retval = usb_autopm_get_interface(serial->interface); -	if (retval) -		goto error_get_interface; +		goto err_put_serial;  	init_termios = (driver->termios[idx] == NULL);  	retval = tty_standard_install(driver, tty);  	if (retval) -		goto error_init_termios; +		goto err_put_module;  	mutex_unlock(&serial->disc_mutex); @@ -247,11 +243,9 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty)  	return retval; - error_init_termios: -	usb_autopm_put_interface(serial->interface); - error_get_interface: +err_put_module:  	module_put(serial->type->driver.owner); - error_module_get: +err_put_serial:  	usb_serial_put(serial);  	mutex_unlock(&serial->disc_mutex);  	return retval; @@ -265,10 +259,19 @@ static int serial_port_activate(struct tty_port *tport, struct tty_struct *tty)  	int retval;  	mutex_lock(&serial->disc_mutex); -	if (serial->disconnected) +	if (serial->disconnected) {  		retval = -ENODEV; -	else -		retval = port->serial->type->open(tty, port); +		goto out_unlock; +	} + +	retval = usb_autopm_get_interface(serial->interface); +	if (retval) +		goto out_unlock; + +	retval = port->serial->type->open(tty, port); +	if (retval) +		usb_autopm_put_interface(serial->interface); +out_unlock:  	mutex_unlock(&serial->disc_mutex);  	if (retval < 0) @@ -304,6 +307,8 @@ static void serial_port_shutdown(struct tty_port *tport)  	if (drv->close)  		drv->close(port); + +	usb_autopm_put_interface(port->serial->interface);  }  static void serial_hangup(struct tty_struct *tty) @@ -352,8 +357,6 @@ static void serial_cleanup(struct tty_struct *tty)  	serial = port->serial;  	owner = serial->type->driver.owner; -	usb_autopm_put_interface(serial->interface); -  	usb_serial_put(serial);  	module_put(owner);  } @@ -1328,7 +1331,7 @@ static int __init usb_serial_init(void)  	result = bus_register(&usb_serial_bus_type);  	if (result) {  		pr_err("%s - registering bus driver failed\n", __func__); -		goto exit_bus; +		goto err_put_driver;  	}  	usb_serial_tty_driver->driver_name = "usbserial"; @@ -1346,25 +1349,23 @@ static int __init usb_serial_init(void)  	result = tty_register_driver(usb_serial_tty_driver);  	if (result) {  		pr_err("%s - tty_register_driver failed\n", __func__); -		goto exit_reg_driver; +		goto err_unregister_bus;  	}  	/* register the generic driver, if we should */  	result = usb_serial_generic_register();  	if (result < 0) {  		pr_err("%s - registering generic driver failed\n", __func__); -		goto exit_generic; +		goto err_unregister_driver;  	}  	return result; -exit_generic: +err_unregister_driver:  	tty_unregister_driver(usb_serial_tty_driver); - -exit_reg_driver: +err_unregister_bus:  	bus_unregister(&usb_serial_bus_type); - -exit_bus: +err_put_driver:  	pr_err("%s - returning with error %d\n", __func__, result);  	tty_driver_kref_put(usb_serial_tty_driver);  	return result; @@ -1509,13 +1510,13 @@ int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[]  	rc = usb_register(udriver);  	if (rc) -		goto failed_usb_register; +		goto err_free_driver;  	for (sd = serial_drivers; *sd; ++sd) {  		(*sd)->usb_driver = udriver;  		rc = usb_serial_register(*sd);  		if (rc) -			goto failed; +			goto err_deregister_drivers;  	}  	/* Now set udriver's id_table and look for matches */ @@ -1523,11 +1524,11 @@ int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[]  	rc = driver_attach(&udriver->drvwrap.driver);  	return 0; - failed: +err_deregister_drivers:  	while (sd-- > serial_drivers)  		usb_serial_deregister(*sd);  	usb_deregister(udriver); -failed_usb_register: +err_free_driver:  	kfree(udriver);  	return rc;  }  | 
