diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-05 17:18:03 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-05 17:18:03 -0400 |
commit | e9563355ac1175dd3440dc2ea5c28b27ed51a283 (patch) | |
tree | 8546d55832714b5d19ba4c7799266918ca04882e /drivers/staging/usbip | |
parent | cdd854bc42b5e6c79bbbc40c6600d995ffe6e747 (diff) | |
parent | b12d1995f650e92f26184afd28e6cf40bf64467a (diff) |
Staging: Merge staging-next into Linus's tree
Conflicts:
drivers/staging/Kconfig
drivers/staging/batman-adv/bat_sysfs.c
drivers/staging/batman-adv/device.c
drivers/staging/batman-adv/hard-interface.c
drivers/staging/cx25821/cx25821-audups11.c
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/usbip')
-rw-r--r-- | drivers/staging/usbip/stub.h | 17 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_dev.c | 101 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_main.c | 65 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_rx.c | 101 | ||||
-rw-r--r-- | drivers/staging/usbip/usbip_common.h | 2 |
5 files changed, 220 insertions, 66 deletions
diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h index 022d0649ac5..30dbfb6d16f 100644 --- a/drivers/staging/usbip/stub.h +++ b/drivers/staging/usbip/stub.h | |||
@@ -25,6 +25,11 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/net.h> | 26 | #include <linux/net.h> |
27 | 27 | ||
28 | #define STUB_BUSID_OTHER 0 | ||
29 | #define STUB_BUSID_REMOV 1 | ||
30 | #define STUB_BUSID_ADDED 2 | ||
31 | #define STUB_BUSID_ALLOC 3 | ||
32 | |||
28 | struct stub_device { | 33 | struct stub_device { |
29 | struct usb_interface *interface; | 34 | struct usb_interface *interface; |
30 | struct list_head list; | 35 | struct list_head list; |
@@ -72,6 +77,14 @@ struct stub_unlink { | |||
72 | __u32 status; | 77 | __u32 status; |
73 | }; | 78 | }; |
74 | 79 | ||
80 | #define BUSID_SIZE 20 | ||
81 | struct bus_id_priv { | ||
82 | char name[BUSID_SIZE]; | ||
83 | char status; | ||
84 | int interf_count; | ||
85 | struct stub_device *sdev; | ||
86 | char shutdown_busid; | ||
87 | }; | ||
75 | 88 | ||
76 | extern struct kmem_cache *stub_priv_cache; | 89 | extern struct kmem_cache *stub_priv_cache; |
77 | 90 | ||
@@ -91,5 +104,7 @@ void stub_rx_loop(struct usbip_task *); | |||
91 | void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32); | 104 | void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32); |
92 | 105 | ||
93 | /* stub_main.c */ | 106 | /* stub_main.c */ |
94 | int match_busid(const char *busid); | 107 | struct bus_id_priv *get_busid_priv(const char *busid); |
108 | int del_match_busid(char *busid); | ||
109 | |||
95 | void stub_device_cleanup_urbs(struct stub_device *sdev); | 110 | void stub_device_cleanup_urbs(struct stub_device *sdev); |
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index 3f95605427a..b6b753a4934 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c | |||
@@ -393,11 +393,14 @@ static int stub_probe(struct usb_interface *interface, | |||
393 | struct stub_device *sdev = NULL; | 393 | struct stub_device *sdev = NULL; |
394 | const char *udev_busid = dev_name(interface->dev.parent); | 394 | const char *udev_busid = dev_name(interface->dev.parent); |
395 | int err = 0; | 395 | int err = 0; |
396 | struct bus_id_priv *busid_priv; | ||
396 | 397 | ||
397 | dev_dbg(&interface->dev, "Enter\n"); | 398 | dev_dbg(&interface->dev, "Enter\n"); |
398 | 399 | ||
399 | /* check we should claim or not by busid_table */ | 400 | /* check we should claim or not by busid_table */ |
400 | if (match_busid(udev_busid)) { | 401 | busid_priv = get_busid_priv(udev_busid); |
402 | if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) || | ||
403 | (busid_priv->status == STUB_BUSID_OTHER)) { | ||
401 | dev_info(&interface->dev, | 404 | dev_info(&interface->dev, |
402 | "this device %s is not in match_busid table. skip!\n", | 405 | "this device %s is not in match_busid table. skip!\n", |
403 | udev_busid); | 406 | udev_busid); |
@@ -422,28 +425,80 @@ static int stub_probe(struct usb_interface *interface, | |||
422 | return -ENODEV; | 425 | return -ENODEV; |
423 | } | 426 | } |
424 | 427 | ||
428 | |||
429 | if (busid_priv->status == STUB_BUSID_ALLOC) { | ||
430 | busid_priv->interf_count++; | ||
431 | sdev = busid_priv->sdev; | ||
432 | if (!sdev) | ||
433 | return -ENODEV; | ||
434 | |||
435 | dev_info(&interface->dev, | ||
436 | "USB/IP Stub: register a new interface " | ||
437 | "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum, | ||
438 | interface->cur_altsetting->desc.bInterfaceNumber); | ||
439 | |||
440 | /* set private data to usb_interface */ | ||
441 | usb_set_intfdata(interface, sdev); | ||
442 | |||
443 | err = stub_add_files(&interface->dev); | ||
444 | if (err) { | ||
445 | dev_err(&interface->dev, "create sysfs files for %s\n", | ||
446 | udev_busid); | ||
447 | usb_set_intfdata(interface, NULL); | ||
448 | busid_priv->interf_count--; | ||
449 | |||
450 | return err; | ||
451 | } | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
425 | /* ok. this is my device. */ | 456 | /* ok. this is my device. */ |
426 | sdev = stub_device_alloc(interface); | 457 | sdev = stub_device_alloc(interface); |
427 | if (!sdev) | 458 | if (!sdev) |
428 | return -ENOMEM; | 459 | return -ENOMEM; |
429 | 460 | ||
430 | dev_info(&interface->dev, "USB/IP Stub: register a new interface " | 461 | dev_info(&interface->dev, "USB/IP Stub: register a new device " |
431 | "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum, | 462 | "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum, |
432 | interface->cur_altsetting->desc.bInterfaceNumber); | 463 | interface->cur_altsetting->desc.bInterfaceNumber); |
433 | 464 | ||
465 | busid_priv->interf_count = 0; | ||
466 | busid_priv->shutdown_busid = 0; | ||
467 | |||
434 | /* set private data to usb_interface */ | 468 | /* set private data to usb_interface */ |
435 | usb_set_intfdata(interface, sdev); | 469 | usb_set_intfdata(interface, sdev); |
470 | busid_priv->interf_count++; | ||
471 | |||
472 | busid_priv->sdev = sdev; | ||
436 | 473 | ||
437 | err = stub_add_files(&interface->dev); | 474 | err = stub_add_files(&interface->dev); |
438 | if (err) { | 475 | if (err) { |
439 | dev_err(&interface->dev, "create sysfs files for %s\n", | 476 | dev_err(&interface->dev, "create sysfs files for %s\n", |
440 | udev_busid); | 477 | udev_busid); |
478 | usb_set_intfdata(interface, NULL); | ||
479 | busid_priv->interf_count = 0; | ||
480 | |||
481 | busid_priv->sdev = NULL; | ||
482 | stub_device_free(sdev); | ||
441 | return err; | 483 | return err; |
442 | } | 484 | } |
485 | busid_priv->status = STUB_BUSID_ALLOC; | ||
443 | 486 | ||
444 | return 0; | 487 | return 0; |
445 | } | 488 | } |
446 | 489 | ||
490 | static void shutdown_busid(struct bus_id_priv *busid_priv) | ||
491 | { | ||
492 | if (busid_priv->sdev && !busid_priv->shutdown_busid) { | ||
493 | busid_priv->shutdown_busid = 1; | ||
494 | usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED); | ||
495 | |||
496 | /* 2. wait for the stop of the event handler */ | ||
497 | usbip_stop_eh(&busid_priv->sdev->ud); | ||
498 | } | ||
499 | |||
500 | } | ||
501 | |||
447 | 502 | ||
448 | /* | 503 | /* |
449 | * called in usb_disconnect() or usb_deregister() | 504 | * called in usb_disconnect() or usb_deregister() |
@@ -451,10 +506,21 @@ static int stub_probe(struct usb_interface *interface, | |||
451 | */ | 506 | */ |
452 | static void stub_disconnect(struct usb_interface *interface) | 507 | static void stub_disconnect(struct usb_interface *interface) |
453 | { | 508 | { |
454 | struct stub_device *sdev = usb_get_intfdata(interface); | 509 | struct stub_device *sdev; |
510 | const char *udev_busid = dev_name(interface->dev.parent); | ||
511 | struct bus_id_priv *busid_priv; | ||
512 | |||
513 | busid_priv = get_busid_priv(udev_busid); | ||
455 | 514 | ||
456 | usbip_udbg("Enter\n"); | 515 | usbip_udbg("Enter\n"); |
457 | 516 | ||
517 | if (!busid_priv) { | ||
518 | BUG(); | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | sdev = usb_get_intfdata(interface); | ||
523 | |||
458 | /* get stub_device */ | 524 | /* get stub_device */ |
459 | if (!sdev) { | 525 | if (!sdev) { |
460 | err(" could not get device from inteface data"); | 526 | err(" could not get device from inteface data"); |
@@ -464,22 +530,39 @@ static void stub_disconnect(struct usb_interface *interface) | |||
464 | 530 | ||
465 | usb_set_intfdata(interface, NULL); | 531 | usb_set_intfdata(interface, NULL); |
466 | 532 | ||
467 | |||
468 | /* | 533 | /* |
469 | * NOTE: | 534 | * NOTE: |
470 | * rx/tx threads are invoked for each usb_device. | 535 | * rx/tx threads are invoked for each usb_device. |
471 | */ | 536 | */ |
472 | stub_remove_files(&interface->dev); | 537 | stub_remove_files(&interface->dev); |
473 | 538 | ||
474 | /* 1. shutdown the current connection */ | 539 | /*If usb reset called from event handler*/ |
475 | usbip_event_add(&sdev->ud, SDEV_EVENT_REMOVED); | 540 | if (busid_priv->sdev->ud.eh.thread == current) { |
541 | busid_priv->interf_count--; | ||
542 | return; | ||
543 | } | ||
544 | |||
545 | if (busid_priv->interf_count > 1) { | ||
546 | busid_priv->interf_count--; | ||
547 | shutdown_busid(busid_priv); | ||
548 | return; | ||
549 | } | ||
550 | |||
551 | busid_priv->interf_count = 0; | ||
476 | 552 | ||
477 | /* 2. wait for the stop of the event handler */ | 553 | |
478 | usbip_stop_eh(&sdev->ud); | 554 | /* 1. shutdown the current connection */ |
555 | shutdown_busid(busid_priv); | ||
479 | 556 | ||
480 | /* 3. free sdev */ | 557 | /* 3. free sdev */ |
558 | busid_priv->sdev = NULL; | ||
481 | stub_device_free(sdev); | 559 | stub_device_free(sdev); |
482 | 560 | ||
483 | 561 | if (busid_priv->status == STUB_BUSID_ALLOC) { | |
562 | busid_priv->status = STUB_BUSID_ADDED; | ||
563 | } else { | ||
564 | busid_priv->status = STUB_BUSID_OTHER; | ||
565 | del_match_busid((char *)udev_busid); | ||
566 | } | ||
484 | usbip_udbg("bye\n"); | 567 | usbip_udbg("bye\n"); |
485 | } | 568 | } |
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c index 6665cefe573..f3a40968aae 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/staging/usbip/stub_main.c | |||
@@ -41,8 +41,7 @@ struct kmem_cache *stub_priv_cache; | |||
41 | * remote host. | 41 | * remote host. |
42 | */ | 42 | */ |
43 | #define MAX_BUSID 16 | 43 | #define MAX_BUSID 16 |
44 | #define BUSID_SIZE 20 | 44 | static struct bus_id_priv busid_table[MAX_BUSID]; |
45 | static char busid_table[MAX_BUSID][BUSID_SIZE]; | ||
46 | static spinlock_t busid_table_lock; | 45 | static spinlock_t busid_table_lock; |
47 | 46 | ||
48 | 47 | ||
@@ -53,8 +52,8 @@ int match_busid(const char *busid) | |||
53 | spin_lock(&busid_table_lock); | 52 | spin_lock(&busid_table_lock); |
54 | 53 | ||
55 | for (i = 0; i < MAX_BUSID; i++) | 54 | for (i = 0; i < MAX_BUSID; i++) |
56 | if (busid_table[i][0]) | 55 | if (busid_table[i].name[0]) |
57 | if (!strncmp(busid_table[i], busid, BUSID_SIZE)) { | 56 | if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { |
58 | /* already registerd */ | 57 | /* already registerd */ |
59 | spin_unlock(&busid_table_lock); | 58 | spin_unlock(&busid_table_lock); |
60 | return 0; | 59 | return 0; |
@@ -65,6 +64,25 @@ int match_busid(const char *busid) | |||
65 | return 1; | 64 | return 1; |
66 | } | 65 | } |
67 | 66 | ||
67 | struct bus_id_priv *get_busid_priv(const char *busid) | ||
68 | { | ||
69 | int i; | ||
70 | |||
71 | spin_lock(&busid_table_lock); | ||
72 | |||
73 | for (i = 0; i < MAX_BUSID; i++) | ||
74 | if (busid_table[i].name[0]) | ||
75 | if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { | ||
76 | /* already registerd */ | ||
77 | spin_unlock(&busid_table_lock); | ||
78 | return &(busid_table[i]); | ||
79 | } | ||
80 | |||
81 | spin_unlock(&busid_table_lock); | ||
82 | |||
83 | return NULL; | ||
84 | } | ||
85 | |||
68 | static ssize_t show_match_busid(struct device_driver *drv, char *buf) | 86 | static ssize_t show_match_busid(struct device_driver *drv, char *buf) |
69 | { | 87 | { |
70 | int i; | 88 | int i; |
@@ -73,8 +91,8 @@ static ssize_t show_match_busid(struct device_driver *drv, char *buf) | |||
73 | spin_lock(&busid_table_lock); | 91 | spin_lock(&busid_table_lock); |
74 | 92 | ||
75 | for (i = 0; i < MAX_BUSID; i++) | 93 | for (i = 0; i < MAX_BUSID; i++) |
76 | if (busid_table[i][0]) | 94 | if (busid_table[i].name[0]) |
77 | out += sprintf(out, "%s ", busid_table[i]); | 95 | out += sprintf(out, "%s ", busid_table[i].name); |
78 | 96 | ||
79 | spin_unlock(&busid_table_lock); | 97 | spin_unlock(&busid_table_lock); |
80 | 98 | ||
@@ -93,8 +111,11 @@ static int add_match_busid(char *busid) | |||
93 | spin_lock(&busid_table_lock); | 111 | spin_lock(&busid_table_lock); |
94 | 112 | ||
95 | for (i = 0; i < MAX_BUSID; i++) | 113 | for (i = 0; i < MAX_BUSID; i++) |
96 | if (!busid_table[i][0]) { | 114 | if (!busid_table[i].name[0]) { |
97 | strncpy(busid_table[i], busid, BUSID_SIZE); | 115 | strncpy(busid_table[i].name, busid, BUSID_SIZE); |
116 | if ((busid_table[i].status != STUB_BUSID_ALLOC) && | ||
117 | (busid_table[i].status != STUB_BUSID_REMOV)) | ||
118 | busid_table[i].status = STUB_BUSID_ADDED; | ||
98 | spin_unlock(&busid_table_lock); | 119 | spin_unlock(&busid_table_lock); |
99 | return 0; | 120 | return 0; |
100 | } | 121 | } |
@@ -104,16 +125,21 @@ static int add_match_busid(char *busid) | |||
104 | return -1; | 125 | return -1; |
105 | } | 126 | } |
106 | 127 | ||
107 | static int del_match_busid(char *busid) | 128 | int del_match_busid(char *busid) |
108 | { | 129 | { |
109 | int i; | 130 | int i; |
110 | 131 | ||
111 | spin_lock(&busid_table_lock); | 132 | spin_lock(&busid_table_lock); |
112 | 133 | ||
113 | for (i = 0; i < MAX_BUSID; i++) | 134 | for (i = 0; i < MAX_BUSID; i++) |
114 | if (!strncmp(busid_table[i], busid, BUSID_SIZE)) { | 135 | if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { |
115 | /* found */ | 136 | /* found */ |
116 | memset(busid_table[i], 0, BUSID_SIZE); | 137 | if (busid_table[i].status == STUB_BUSID_OTHER) |
138 | memset(busid_table[i].name, 0, BUSID_SIZE); | ||
139 | if ((busid_table[i].status != STUB_BUSID_OTHER) && | ||
140 | (busid_table[i].status != STUB_BUSID_ADDED)) { | ||
141 | busid_table[i].status = STUB_BUSID_REMOV; | ||
142 | } | ||
117 | spin_unlock(&busid_table_lock); | 143 | spin_unlock(&busid_table_lock); |
118 | return 0; | 144 | return 0; |
119 | } | 145 | } |
@@ -122,6 +148,20 @@ static int del_match_busid(char *busid) | |||
122 | 148 | ||
123 | return -1; | 149 | return -1; |
124 | } | 150 | } |
151 | static void init_busid_table(void) | ||
152 | { | ||
153 | int i; | ||
154 | |||
155 | |||
156 | for (i = 0; i < MAX_BUSID; i++) { | ||
157 | memset(busid_table[i].name, 0, BUSID_SIZE); | ||
158 | busid_table[i].status = STUB_BUSID_OTHER; | ||
159 | busid_table[i].interf_count = 0; | ||
160 | busid_table[i].sdev = NULL; | ||
161 | busid_table[i].shutdown_busid = 0; | ||
162 | } | ||
163 | spin_lock_init(&busid_table_lock); | ||
164 | } | ||
125 | 165 | ||
126 | static ssize_t store_match_busid(struct device_driver *dev, const char *buf, | 166 | static ssize_t store_match_busid(struct device_driver *dev, const char *buf, |
127 | size_t count) | 167 | size_t count) |
@@ -261,8 +301,7 @@ static int __init usb_stub_init(void) | |||
261 | printk(KERN_INFO KBUILD_MODNAME ":" | 301 | printk(KERN_INFO KBUILD_MODNAME ":" |
262 | DRIVER_DESC ":" DRIVER_VERSION "\n"); | 302 | DRIVER_DESC ":" DRIVER_VERSION "\n"); |
263 | 303 | ||
264 | memset(busid_table, 0, sizeof(busid_table)); | 304 | init_busid_table(); |
265 | spin_lock_init(&busid_table_lock); | ||
266 | 305 | ||
267 | ret = driver_create_file(&stub_driver.drvwrap.driver, | 306 | ret = driver_create_file(&stub_driver.drvwrap.driver, |
268 | &driver_attr_match_busid); | 307 | &driver_attr_match_busid); |
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index 5972ae70e38..3de6fd2539d 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c | |||
@@ -362,54 +362,16 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev, | |||
362 | return priv; | 362 | return priv; |
363 | } | 363 | } |
364 | 364 | ||
365 | |||
366 | static struct usb_host_endpoint *get_ep_from_epnum(struct usb_device *udev, | ||
367 | int epnum0) | ||
368 | { | ||
369 | struct usb_host_config *config; | ||
370 | int i = 0, j = 0; | ||
371 | struct usb_host_endpoint *ep = NULL; | ||
372 | int epnum; | ||
373 | int found = 0; | ||
374 | |||
375 | if (epnum0 == 0) | ||
376 | return &udev->ep0; | ||
377 | |||
378 | config = udev->actconfig; | ||
379 | if (!config) | ||
380 | return NULL; | ||
381 | |||
382 | for (i = 0; i < config->desc.bNumInterfaces; i++) { | ||
383 | struct usb_host_interface *setting; | ||
384 | |||
385 | setting = config->interface[i]->cur_altsetting; | ||
386 | |||
387 | for (j = 0; j < setting->desc.bNumEndpoints; j++) { | ||
388 | ep = &setting->endpoint[j]; | ||
389 | epnum = (ep->desc.bEndpointAddress & 0x7f); | ||
390 | |||
391 | if (epnum == epnum0) { | ||
392 | /* usbip_uinfo("found epnum %d\n", epnum0);*/ | ||
393 | found = 1; | ||
394 | break; | ||
395 | } | ||
396 | } | ||
397 | } | ||
398 | |||
399 | if (found) | ||
400 | return ep; | ||
401 | else | ||
402 | return NULL; | ||
403 | } | ||
404 | |||
405 | |||
406 | static int get_pipe(struct stub_device *sdev, int epnum, int dir) | 365 | static int get_pipe(struct stub_device *sdev, int epnum, int dir) |
407 | { | 366 | { |
408 | struct usb_device *udev = interface_to_usbdev(sdev->interface); | 367 | struct usb_device *udev = interface_to_usbdev(sdev->interface); |
409 | struct usb_host_endpoint *ep; | 368 | struct usb_host_endpoint *ep; |
410 | struct usb_endpoint_descriptor *epd = NULL; | 369 | struct usb_endpoint_descriptor *epd = NULL; |
411 | 370 | ||
412 | ep = get_ep_from_epnum(udev, epnum); | 371 | if (dir == USBIP_DIR_IN) |
372 | ep = udev->ep_in[epnum & 0x7f]; | ||
373 | else | ||
374 | ep = udev->ep_out[epnum & 0x7f]; | ||
413 | if (!ep) { | 375 | if (!ep) { |
414 | dev_err(&sdev->interface->dev, "no such endpoint?, %d\n", | 376 | dev_err(&sdev->interface->dev, "no such endpoint?, %d\n", |
415 | epnum); | 377 | epnum); |
@@ -462,6 +424,60 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir) | |||
462 | return 0; | 424 | return 0; |
463 | } | 425 | } |
464 | 426 | ||
427 | static void masking_bogus_flags(struct urb *urb) | ||
428 | { | ||
429 | int xfertype; | ||
430 | struct usb_device *dev; | ||
431 | struct usb_host_endpoint *ep; | ||
432 | int is_out; | ||
433 | unsigned int allowed; | ||
434 | |||
435 | if (!urb || urb->hcpriv || !urb->complete) | ||
436 | return; | ||
437 | dev = urb->dev; | ||
438 | if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) | ||
439 | return; | ||
440 | |||
441 | ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out) | ||
442 | [usb_pipeendpoint(urb->pipe)]; | ||
443 | if (!ep) | ||
444 | return; | ||
445 | |||
446 | xfertype = usb_endpoint_type(&ep->desc); | ||
447 | if (xfertype == USB_ENDPOINT_XFER_CONTROL) { | ||
448 | struct usb_ctrlrequest *setup = | ||
449 | (struct usb_ctrlrequest *) urb->setup_packet; | ||
450 | |||
451 | if (!setup) | ||
452 | return; | ||
453 | is_out = !(setup->bRequestType & USB_DIR_IN) || | ||
454 | !setup->wLength; | ||
455 | } else { | ||
456 | is_out = usb_endpoint_dir_out(&ep->desc); | ||
457 | } | ||
458 | |||
459 | /* enforce simple/standard policy */ | ||
460 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | | ||
461 | URB_DIR_MASK | URB_FREE_BUFFER); | ||
462 | switch (xfertype) { | ||
463 | case USB_ENDPOINT_XFER_BULK: | ||
464 | if (is_out) | ||
465 | allowed |= URB_ZERO_PACKET; | ||
466 | /* FALLTHROUGH */ | ||
467 | case USB_ENDPOINT_XFER_CONTROL: | ||
468 | allowed |= URB_NO_FSBR; /* only affects UHCI */ | ||
469 | /* FALLTHROUGH */ | ||
470 | default: /* all non-iso endpoints */ | ||
471 | if (!is_out) | ||
472 | allowed |= URB_SHORT_NOT_OK; | ||
473 | break; | ||
474 | case USB_ENDPOINT_XFER_ISOC: | ||
475 | allowed |= URB_ISO_ASAP; | ||
476 | break; | ||
477 | } | ||
478 | urb->transfer_flags &= allowed; | ||
479 | } | ||
480 | |||
465 | static void stub_recv_cmd_submit(struct stub_device *sdev, | 481 | static void stub_recv_cmd_submit(struct stub_device *sdev, |
466 | struct usbip_header *pdu) | 482 | struct usbip_header *pdu) |
467 | { | 483 | { |
@@ -528,6 +544,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, | |||
528 | /* no need to submit an intercepted request, but harmless? */ | 544 | /* no need to submit an intercepted request, but harmless? */ |
529 | tweak_special_requests(priv->urb); | 545 | tweak_special_requests(priv->urb); |
530 | 546 | ||
547 | masking_bogus_flags(priv->urb); | ||
531 | /* urb is now ready to submit */ | 548 | /* urb is now ready to submit */ |
532 | ret = usb_submit_urb(priv->urb, GFP_KERNEL); | 549 | ret = usb_submit_urb(priv->urb, GFP_KERNEL); |
533 | 550 | ||
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index e1bbd1287e2..d280e234e06 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h | |||
@@ -172,7 +172,7 @@ struct usbip_header_basic { | |||
172 | #define USBIP_RET_UNLINK 0x0004 | 172 | #define USBIP_RET_UNLINK 0x0004 |
173 | __u32 command; | 173 | __u32 command; |
174 | 174 | ||
175 | /* sequencial number which identifies requests. | 175 | /* sequential number which identifies requests. |
176 | * incremented per connections */ | 176 | * incremented per connections */ |
177 | __u32 seqnum; | 177 | __u32 seqnum; |
178 | 178 | ||