diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-tiny-usb.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-tiny-usb.c | 25 | 
1 files changed, 21 insertions, 4 deletions
| diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index 0ed77eeff31e..a2e3dd715380 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -178,22 +178,39 @@ static int usb_read(struct i2c_adapter *adapter, int cmd,  		    int value, int index, void *data, int len)  {  	struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; +	void *dmadata = kmalloc(len, GFP_KERNEL); +	int ret; + +	if (!dmadata) +		return -ENOMEM;  	/* do control transfer */ -	return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0), +	ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),  			       cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | -			       USB_DIR_IN, value, index, data, len, 2000); +			       USB_DIR_IN, value, index, dmadata, len, 2000); + +	memcpy(data, dmadata, len); +	kfree(dmadata); +	return ret;  }  static int usb_write(struct i2c_adapter *adapter, int cmd,  		     int value, int index, void *data, int len)  {  	struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; +	void *dmadata = kmemdup(data, len, GFP_KERNEL); +	int ret; + +	if (!dmadata) +		return -ENOMEM;  	/* do control transfer */ -	return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0), +	ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),  			       cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE, -			       value, index, data, len, 2000); +			       value, index, dmadata, len, 2000); + +	kfree(dmadata); +	return ret;  }  static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev) | 
