aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorGiuseppe Scrivano <giuseppe@southpole.se>2011-08-03 18:10:29 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-04 04:43:30 -0400
commit36c35416a94f5632c3addad05217ff02c39b3b61 (patch)
treecd62778aeb57b3958228e2cd325d18fd1cd1cc35 /drivers/net/usb
parent5ee5a07ce3a54de3d1192f8c9c2378d51a51e3bd (diff)
cdc_ncm: fix endianness problem.
Fix a misusage of the struct usb_cdc_notification to pass arguments to the usb_control_msg function. The usb_control_msg function expects host endian arguments but usb_cdc_notification stores these values as little endian. Now usb_control_msg is directly invoked with host endian values. Signed-off-by: Giuseppe Scrivano <giuseppe@southpole.se> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/cdc_ncm.c156
1 files changed, 56 insertions, 100 deletions
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index fd622a66ebbf..a03336e086d5 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -53,7 +53,7 @@
53#include <linux/usb/usbnet.h> 53#include <linux/usb/usbnet.h>
54#include <linux/usb/cdc.h> 54#include <linux/usb/cdc.h>
55 55
56#define DRIVER_VERSION "01-June-2011" 56#define DRIVER_VERSION "04-Aug-2011"
57 57
58/* CDC NCM subclass 3.2.1 */ 58/* CDC NCM subclass 3.2.1 */
59#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 59#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
@@ -163,35 +163,8 @@ cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
163 usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); 163 usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info));
164} 164}
165 165
166static int
167cdc_ncm_do_request(struct cdc_ncm_ctx *ctx, struct usb_cdc_notification *req,
168 void *data, u16 flags, u16 *actlen, u16 timeout)
169{
170 int err;
171
172 err = usb_control_msg(ctx->udev, (req->bmRequestType & USB_DIR_IN) ?
173 usb_rcvctrlpipe(ctx->udev, 0) :
174 usb_sndctrlpipe(ctx->udev, 0),
175 req->bNotificationType, req->bmRequestType,
176 req->wValue,
177 req->wIndex, data,
178 req->wLength, timeout);
179
180 if (err < 0) {
181 if (actlen)
182 *actlen = 0;
183 return err;
184 }
185
186 if (actlen)
187 *actlen = err;
188
189 return 0;
190}
191
192static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) 166static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
193{ 167{
194 struct usb_cdc_notification req;
195 u32 val; 168 u32 val;
196 u8 flags; 169 u8 flags;
197 u8 iface_no; 170 u8 iface_no;
@@ -200,14 +173,14 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
200 173
201 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; 174 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
202 175
203 req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE; 176 err = usb_control_msg(ctx->udev,
204 req.bNotificationType = USB_CDC_GET_NTB_PARAMETERS; 177 usb_rcvctrlpipe(ctx->udev, 0),
205 req.wValue = 0; 178 USB_CDC_GET_NTB_PARAMETERS,
206 req.wIndex = cpu_to_le16(iface_no); 179 USB_TYPE_CLASS | USB_DIR_IN
207 req.wLength = cpu_to_le16(sizeof(ctx->ncm_parm)); 180 | USB_RECIP_INTERFACE,
208 181 0, iface_no, &ctx->ncm_parm,
209 err = cdc_ncm_do_request(ctx, &req, &ctx->ncm_parm, 0, NULL, 1000); 182 sizeof(ctx->ncm_parm), 10000);
210 if (err) { 183 if (err < 0) {
211 pr_debug("failed GET_NTB_PARAMETERS\n"); 184 pr_debug("failed GET_NTB_PARAMETERS\n");
212 return 1; 185 return 1;
213 } 186 }
@@ -253,31 +226,26 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
253 226
254 /* inform device about NTB input size changes */ 227 /* inform device about NTB input size changes */
255 if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { 228 if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) {
256 req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT |
257 USB_RECIP_INTERFACE;
258 req.bNotificationType = USB_CDC_SET_NTB_INPUT_SIZE;
259 req.wValue = 0;
260 req.wIndex = cpu_to_le16(iface_no);
261 229
262 if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) { 230 if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) {
263 struct usb_cdc_ncm_ndp_input_size ndp_in_sz; 231 struct usb_cdc_ncm_ndp_input_size ndp_in_sz;
264 232 err = usb_control_msg(ctx->udev,
265 req.wLength = 8; 233 usb_sndctrlpipe(ctx->udev, 0),
266 ndp_in_sz.dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); 234 USB_CDC_SET_NTB_INPUT_SIZE,
267 ndp_in_sz.wNtbInMaxDatagrams = 235 USB_TYPE_CLASS | USB_DIR_OUT
268 cpu_to_le16(CDC_NCM_DPT_DATAGRAMS_MAX); 236 | USB_RECIP_INTERFACE,
269 ndp_in_sz.wReserved = 0; 237 0, iface_no, &ndp_in_sz, 8, 1000);
270 err = cdc_ncm_do_request(ctx, &req, &ndp_in_sz, 0, NULL,
271 1000);
272 } else { 238 } else {
273 __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); 239 __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
274 240 err = usb_control_msg(ctx->udev,
275 req.wLength = 4; 241 usb_sndctrlpipe(ctx->udev, 0),
276 err = cdc_ncm_do_request(ctx, &req, &dwNtbInMaxSize, 0, 242 USB_CDC_SET_NTB_INPUT_SIZE,
277 NULL, 1000); 243 USB_TYPE_CLASS | USB_DIR_OUT
244 | USB_RECIP_INTERFACE,
245 0, iface_no, &dwNtbInMaxSize, 4, 1000);
278 } 246 }
279 247
280 if (err) 248 if (err < 0)
281 pr_debug("Setting NTB Input Size failed\n"); 249 pr_debug("Setting NTB Input Size failed\n");
282 } 250 }
283 251
@@ -332,29 +300,24 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
332 300
333 /* set CRC Mode */ 301 /* set CRC Mode */
334 if (flags & USB_CDC_NCM_NCAP_CRC_MODE) { 302 if (flags & USB_CDC_NCM_NCAP_CRC_MODE) {
335 req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | 303 err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0),
336 USB_RECIP_INTERFACE; 304 USB_CDC_SET_CRC_MODE,
337 req.bNotificationType = USB_CDC_SET_CRC_MODE; 305 USB_TYPE_CLASS | USB_DIR_OUT
338 req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED); 306 | USB_RECIP_INTERFACE,
339 req.wIndex = cpu_to_le16(iface_no); 307 USB_CDC_NCM_CRC_NOT_APPENDED,
340 req.wLength = 0; 308 iface_no, NULL, 0, 1000);
341 309 if (err < 0)
342 err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000);
343 if (err)
344 pr_debug("Setting CRC mode off failed\n"); 310 pr_debug("Setting CRC mode off failed\n");
345 } 311 }
346 312
347 /* set NTB format, if both formats are supported */ 313 /* set NTB format, if both formats are supported */
348 if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) { 314 if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) {
349 req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | 315 err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0),
350 USB_RECIP_INTERFACE; 316 USB_CDC_SET_NTB_FORMAT, USB_TYPE_CLASS
351 req.bNotificationType = USB_CDC_SET_NTB_FORMAT; 317 | USB_DIR_OUT | USB_RECIP_INTERFACE,
352 req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT); 318 USB_CDC_NCM_NTB16_FORMAT,
353 req.wIndex = cpu_to_le16(iface_no); 319 iface_no, NULL, 0, 1000);
354 req.wLength = 0; 320 if (err < 0)
355
356 err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000);
357 if (err)
358 pr_debug("Setting NTB format to 16-bit failed\n"); 321 pr_debug("Setting NTB format to 16-bit failed\n");
359 } 322 }
360 323
@@ -364,17 +327,13 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
364 if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) { 327 if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) {
365 __le16 max_datagram_size; 328 __le16 max_datagram_size;
366 u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); 329 u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
367 330 err = usb_control_msg(ctx->udev, usb_rcvctrlpipe(ctx->udev, 0),
368 req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | 331 USB_CDC_GET_MAX_DATAGRAM_SIZE,
369 USB_RECIP_INTERFACE; 332 USB_TYPE_CLASS | USB_DIR_IN
370 req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE; 333 | USB_RECIP_INTERFACE,
371 req.wValue = 0; 334 0, iface_no, &max_datagram_size,
372 req.wIndex = cpu_to_le16(iface_no); 335 2, 1000);
373 req.wLength = cpu_to_le16(2); 336 if (err < 0) {
374
375 err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL,
376 1000);
377 if (err) {
378 pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", 337 pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
379 CDC_NCM_MIN_DATAGRAM_SIZE); 338 CDC_NCM_MIN_DATAGRAM_SIZE);
380 } else { 339 } else {
@@ -395,17 +354,15 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
395 CDC_NCM_MIN_DATAGRAM_SIZE; 354 CDC_NCM_MIN_DATAGRAM_SIZE;
396 355
397 /* if value changed, update device */ 356 /* if value changed, update device */
398 req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | 357 err = usb_control_msg(ctx->udev,
399 USB_RECIP_INTERFACE; 358 usb_sndctrlpipe(ctx->udev, 0),
400 req.bNotificationType = USB_CDC_SET_MAX_DATAGRAM_SIZE; 359 USB_CDC_SET_MAX_DATAGRAM_SIZE,
401 req.wValue = 0; 360 USB_TYPE_CLASS | USB_DIR_OUT
402 req.wIndex = cpu_to_le16(iface_no); 361 | USB_RECIP_INTERFACE,
403 req.wLength = 2; 362 0,
404 max_datagram_size = cpu_to_le16(ctx->max_datagram_size); 363 iface_no, &max_datagram_size,
405 364 2, 1000);
406 err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 365 if (err < 0)
407 0, NULL, 1000);
408 if (err)
409 pr_debug("SET_MAX_DATAGRAM_SIZE failed\n"); 366 pr_debug("SET_MAX_DATAGRAM_SIZE failed\n");
410 } 367 }
411 368
@@ -671,7 +628,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
671 u32 rem; 628 u32 rem;
672 u32 offset; 629 u32 offset;
673 u32 last_offset; 630 u32 last_offset;
674 u16 n = 0; 631 u16 n = 0, index;
675 u8 ready2send = 0; 632 u8 ready2send = 0;
676 633
677 /* if there is a remaining skb, it gets priority */ 634 /* if there is a remaining skb, it gets priority */
@@ -859,8 +816,8 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
859 cpu_to_le16(sizeof(ctx->tx_ncm.nth16)); 816 cpu_to_le16(sizeof(ctx->tx_ncm.nth16));
860 ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq); 817 ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq);
861 ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); 818 ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset);
862 ctx->tx_ncm.nth16.wNdpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16), 819 index = ALIGN(sizeof(struct usb_cdc_ncm_nth16), ctx->tx_ndp_modulus);
863 ctx->tx_ndp_modulus); 820 ctx->tx_ncm.nth16.wNdpIndex = cpu_to_le16(index);
864 821
865 memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16)); 822 memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16));
866 ctx->tx_seq++; 823 ctx->tx_seq++;
@@ -873,12 +830,11 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
873 ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem); 830 ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem);
874 ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */ 831 ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */
875 832
876 memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex, 833 memcpy(((u8 *)skb_out->data) + index,
877 &(ctx->tx_ncm.ndp16), 834 &(ctx->tx_ncm.ndp16),
878 sizeof(ctx->tx_ncm.ndp16)); 835 sizeof(ctx->tx_ncm.ndp16));
879 836
880 memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex + 837 memcpy(((u8 *)skb_out->data) + index + sizeof(ctx->tx_ncm.ndp16),
881 sizeof(ctx->tx_ncm.ndp16),
882 &(ctx->tx_ncm.dpe16), 838 &(ctx->tx_ncm.dpe16),
883 (ctx->tx_curr_frame_num + 1) * 839 (ctx->tx_curr_frame_num + 1) *
884 sizeof(struct usb_cdc_ncm_dpe16)); 840 sizeof(struct usb_cdc_ncm_dpe16));