aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c30
-rw-r--r--drivers/media/video/hdpvr/hdpvr.h3
2 files changed, 16 insertions, 17 deletions
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
index 45b88cf60d68..89b71faeaac2 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -57,23 +57,21 @@ static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
57 unsigned char addr, char *data, int len) 57 unsigned char addr, char *data, int len)
58{ 58{
59 int ret; 59 int ret;
60 char *buf = kmalloc(len, GFP_KERNEL); 60
61 if (!buf) 61 if (len > sizeof(dev->i2c_buf))
62 return -ENOMEM; 62 return -EINVAL;
63 63
64 ret = usb_control_msg(dev->udev, 64 ret = usb_control_msg(dev->udev,
65 usb_rcvctrlpipe(dev->udev, 0), 65 usb_rcvctrlpipe(dev->udev, 0),
66 REQTYPE_I2C_READ, CTRL_READ_REQUEST, 66 REQTYPE_I2C_READ, CTRL_READ_REQUEST,
67 (bus << 8) | addr, 0, buf, len, 1000); 67 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
68 68
69 if (ret == len) { 69 if (ret == len) {
70 memcpy(data, buf, len); 70 memcpy(data, &dev->i2c_buf, len);
71 ret = 0; 71 ret = 0;
72 } else if (ret >= 0) 72 } else if (ret >= 0)
73 ret = -EIO; 73 ret = -EIO;
74 74
75 kfree(buf);
76
77 return ret; 75 return ret;
78} 76}
79 77
@@ -81,31 +79,29 @@ static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus,
81 unsigned char addr, char *data, int len) 79 unsigned char addr, char *data, int len)
82{ 80{
83 int ret; 81 int ret;
84 char *buf = kmalloc(len, GFP_KERNEL);
85 if (!buf)
86 return -ENOMEM;
87 82
88 memcpy(buf, data, len); 83 if (len > sizeof(dev->i2c_buf))
84 return -EINVAL;
85
86 memcpy(&dev->i2c_buf, data, len);
89 ret = usb_control_msg(dev->udev, 87 ret = usb_control_msg(dev->udev,
90 usb_sndctrlpipe(dev->udev, 0), 88 usb_sndctrlpipe(dev->udev, 0),
91 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, 89 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
92 (bus << 8) | addr, 0, buf, len, 1000); 90 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
93 91
94 if (ret < 0) 92 if (ret < 0)
95 goto error; 93 return ret;
96 94
97 ret = usb_control_msg(dev->udev, 95 ret = usb_control_msg(dev->udev,
98 usb_rcvctrlpipe(dev->udev, 0), 96 usb_rcvctrlpipe(dev->udev, 0),
99 REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST, 97 REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
100 0, 0, buf, 2, 1000); 98 0, 0, &dev->i2c_buf, 2, 1000);
101 99
102 if ((ret == 2) && (buf[1] == (len - 1))) 100 if ((ret == 2) && (dev->i2c_buf[1] == (len - 1)))
103 ret = 0; 101 ret = 0;
104 else if (ret >= 0) 102 else if (ret >= 0)
105 ret = -EIO; 103 ret = -EIO;
106 104
107error:
108 kfree(buf);
109 return ret; 105 return ret;
110} 106}
111 107
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
index 29f74269400c..ee74e3be9a6a 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -25,6 +25,7 @@
25 KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE) 25 KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE)
26 26
27#define HDPVR_MAX 8 27#define HDPVR_MAX 8
28#define HDPVR_I2C_MAX_SIZE 128
28 29
29/* Define these values to match your devices */ 30/* Define these values to match your devices */
30#define HD_PVR_VENDOR_ID 0x2040 31#define HD_PVR_VENDOR_ID 0x2040
@@ -109,6 +110,8 @@ struct hdpvr_device {
109 struct i2c_adapter i2c_adapter; 110 struct i2c_adapter i2c_adapter;
110 /* I2C lock */ 111 /* I2C lock */
111 struct mutex i2c_mutex; 112 struct mutex i2c_mutex;
113 /* I2C message buffer space */
114 char i2c_buf[HDPVR_I2C_MAX_SIZE];
112 115
113 /* For passing data to ir-kbd-i2c */ 116 /* For passing data to ir-kbd-i2c */
114 struct IR_i2c_init_data ir_i2c_init_data; 117 struct IR_i2c_init_data ir_i2c_init_data;