aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-tiny-usb.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2013-08-06 07:17:42 -0400
committerWolfram Sang <wsa@the-dreams.de>2013-08-19 13:46:38 -0400
commit243ec0909af052d3f420dd6a4d4376e68346d95c (patch)
treeeb30ec0ec4aed1dc8853bffc48d9f8f6123fe2e1 /drivers/i2c/busses/i2c-tiny-usb.c
parent6d4028c644edc0a2e4a8c948ebf81e8f2f09726e (diff)
i2c: tiny-usb: do not use stack as URB transfer_buffer
Patch fixes i2c-tiny-usb not to use stack as URB transfer_buffer. URB buffers need to be DMA-able, which stack is not. Patch is only compile tested. Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/busses/i2c-tiny-usb.c')
-rw-r--r--drivers/i2c/busses/i2c-tiny-usb.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c
index 05106368d405..e7d3b755af3b 100644
--- a/drivers/i2c/busses/i2c-tiny-usb.c
+++ b/drivers/i2c/busses/i2c-tiny-usb.c
@@ -54,12 +54,16 @@ static int usb_write(struct i2c_adapter *adapter, int cmd,
54 54
55static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) 55static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
56{ 56{
57 unsigned char status; 57 unsigned char *pstatus;
58 struct i2c_msg *pmsg; 58 struct i2c_msg *pmsg;
59 int i; 59 int i, ret;
60 60
61 dev_dbg(&adapter->dev, "master xfer %d messages:\n", num); 61 dev_dbg(&adapter->dev, "master xfer %d messages:\n", num);
62 62
63 pstatus = kmalloc(sizeof(*pstatus), GFP_KERNEL);
64 if (!pstatus)
65 return -ENOMEM;
66
63 for (i = 0 ; i < num ; i++) { 67 for (i = 0 ; i < num ; i++) {
64 int cmd = CMD_I2C_IO; 68 int cmd = CMD_I2C_IO;
65 69
@@ -84,7 +88,8 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
84 pmsg->buf, pmsg->len) != pmsg->len) { 88 pmsg->buf, pmsg->len) != pmsg->len) {
85 dev_err(&adapter->dev, 89 dev_err(&adapter->dev,
86 "failure reading data\n"); 90 "failure reading data\n");
87 return -EREMOTEIO; 91 ret = -EREMOTEIO;
92 goto out;
88 } 93 }
89 } else { 94 } else {
90 /* write data */ 95 /* write data */
@@ -93,36 +98,50 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
93 pmsg->buf, pmsg->len) != pmsg->len) { 98 pmsg->buf, pmsg->len) != pmsg->len) {
94 dev_err(&adapter->dev, 99 dev_err(&adapter->dev,
95 "failure writing data\n"); 100 "failure writing data\n");
96 return -EREMOTEIO; 101 ret = -EREMOTEIO;
102 goto out;
97 } 103 }
98 } 104 }
99 105
100 /* read status */ 106 /* read status */
101 if (usb_read(adapter, CMD_GET_STATUS, 0, 0, &status, 1) != 1) { 107 if (usb_read(adapter, CMD_GET_STATUS, 0, 0, pstatus, 1) != 1) {
102 dev_err(&adapter->dev, "failure reading status\n"); 108 dev_err(&adapter->dev, "failure reading status\n");
103 return -EREMOTEIO; 109 ret = -EREMOTEIO;
110 goto out;
104 } 111 }
105 112
106 dev_dbg(&adapter->dev, " status = %d\n", status); 113 dev_dbg(&adapter->dev, " status = %d\n", *pstatus);
107 if (status == STATUS_ADDRESS_NAK) 114 if (*pstatus == STATUS_ADDRESS_NAK) {
108 return -EREMOTEIO; 115 ret = -EREMOTEIO;
116 goto out;
117 }
109 } 118 }
110 119
111 return i; 120 ret = i;
121out:
122 kfree(pstatus);
123 return ret;
112} 124}
113 125
114static u32 usb_func(struct i2c_adapter *adapter) 126static u32 usb_func(struct i2c_adapter *adapter)
115{ 127{
116 __le32 func; 128 __le32 *pfunc;
129 u32 ret;
130
131 pfunc = kmalloc(sizeof(*pfunc), GFP_KERNEL);
117 132
118 /* get functionality from adapter */ 133 /* get functionality from adapter */
119 if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) != 134 if (!pfunc || usb_read(adapter, CMD_GET_FUNC, 0, 0, pfunc,
120 sizeof(func)) { 135 sizeof(*pfunc)) != sizeof(*pfunc)) {
121 dev_err(&adapter->dev, "failure reading functionality\n"); 136 dev_err(&adapter->dev, "failure reading functionality\n");
122 return 0; 137 ret = 0;
138 goto out;
123 } 139 }
124 140
125 return le32_to_cpu(func); 141 ret = le32_to_cpup(pfunc);
142out:
143 kfree(pfunc);
144 return ret;
126} 145}
127 146
128/* This is the actual algorithm we define */ 147/* This is the actual algorithm we define */