diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-08-06 07:17:42 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2013-08-19 13:46:38 -0400 |
commit | 243ec0909af052d3f420dd6a4d4376e68346d95c (patch) | |
tree | eb30ec0ec4aed1dc8853bffc48d9f8f6123fe2e1 /drivers/i2c | |
parent | 6d4028c644edc0a2e4a8c948ebf81e8f2f09726e (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')
-rw-r--r-- | drivers/i2c/busses/i2c-tiny-usb.c | 49 |
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 | ||
55 | static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) | 55 | static 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; |
121 | out: | ||
122 | kfree(pstatus); | ||
123 | return ret; | ||
112 | } | 124 | } |
113 | 125 | ||
114 | static u32 usb_func(struct i2c_adapter *adapter) | 126 | static 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); |
142 | out: | ||
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 */ |