Commit 8a6b088aff969a125cf4ed21f7608112f8b722e5

Authored by Tom Rini

Merge branch 'master' of git://git.denx.de/u-boot-usb

Showing 16 changed files Side-by-side Diff

... ... @@ -430,6 +430,16 @@
430 430 }
431 431 #endif /* CONFIG_USB_STORAGE */
432 432  
  433 +static int do_usb_stop_keyboard(int force)
  434 +{
  435 +#ifdef CONFIG_USB_KEYBOARD
  436 + if (usb_kbd_deregister(force) != 0) {
  437 + printf("USB not stopped: usbkbd still using USB\n");
  438 + return 1;
  439 + }
  440 +#endif
  441 + return 0;
  442 +}
433 443  
434 444 /******************************************************************************
435 445 * usb command intepreter
... ... @@ -450,6 +460,8 @@
450 460 if ((strncmp(argv[1], "reset", 5) == 0) ||
451 461 (strncmp(argv[1], "start", 5) == 0)) {
452 462 bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
  463 + if (do_usb_stop_keyboard(1) != 0)
  464 + return 1;
453 465 usb_stop();
454 466 printf("(Re)start USB...\n");
455 467 if (usb_init() >= 0) {
456 468  
... ... @@ -468,19 +480,10 @@
468 480 return 0;
469 481 }
470 482 if (strncmp(argv[1], "stop", 4) == 0) {
471   -#ifdef CONFIG_USB_KEYBOARD
472   - if (argc == 2) {
473   - if (usb_kbd_deregister() != 0) {
474   - printf("USB not stopped: usbkbd still"
475   - " using USB\n");
476   - return 1;
477   - }
478   - } else {
479   - /* forced stop, switch console in to serial */
  483 + if (argc != 2)
480 484 console_assign(stdin, "serial");
481   - usb_kbd_deregister();
482   - }
483   -#endif
  485 + if (do_usb_stop_keyboard(0) != 0)
  486 + return 1;
484 487 printf("stopping USB..\n");
485 488 usb_stop();
486 489 return 0;
... ... @@ -34,6 +34,9 @@
34 34 #define CONFIG_SYS_DEVICE_NULLDEV 1
35 35 #endif
36 36  
  37 +#ifdef CONFIG_SYS_STDIO_DEREGISTER
  38 +#define CONFIG_SYS_DEVICE_NULLDEV 1
  39 +#endif
37 40  
38 41 #ifdef CONFIG_SYS_DEVICE_NULLDEV
39 42 void nulldev_putc(struct stdio_dev *dev, const char c)
... ... @@ -172,7 +175,7 @@
172 175 * returns 0 if success, -1 if device is assigned and 1 if devname not found
173 176 */
174 177 #ifdef CONFIG_SYS_STDIO_DEREGISTER
175   -int stdio_deregister_dev(struct stdio_dev *dev)
  178 +int stdio_deregister_dev(struct stdio_dev *dev, int force)
176 179 {
177 180 int l;
178 181 struct list_head *pos;
... ... @@ -181,6 +184,10 @@
181 184 /* get stdio devices (ListRemoveItem changes the dev list) */
182 185 for (l=0 ; l< MAX_FILES; l++) {
183 186 if (stdio_devices[l] == dev) {
  187 + if (force) {
  188 + strcpy(temp_names[l], "nulldev");
  189 + continue;
  190 + }
184 191 /* Device is assigned -> report error */
185 192 return -1;
186 193 }
... ... @@ -202,7 +209,7 @@
202 209 return 0;
203 210 }
204 211  
205   -int stdio_deregister(const char *devname)
  212 +int stdio_deregister(const char *devname, int force)
206 213 {
207 214 struct stdio_dev *dev;
208 215  
... ... @@ -211,7 +218,7 @@
211 218 if (!dev) /* device not found */
212 219 return -ENODEV;
213 220  
214   - return stdio_deregister_dev(dev);
  221 + return stdio_deregister_dev(dev, force);
215 222 }
216 223 #endif /* CONFIG_SYS_STDIO_DEREGISTER */
217 224  
... ... @@ -8,6 +8,7 @@
8 8 * SPDX-License-Identifier: GPL-2.0+
9 9 */
10 10 #include <common.h>
  11 +#include <errno.h>
11 12 #include <malloc.h>
12 13 #include <stdio_dev.h>
13 14 #include <asm/byteorder.h>
14 15  
15 16  
... ... @@ -170,11 +171,12 @@
170 171 {
171 172 struct usb_interface *iface = &dev->config.if_desc[0];
172 173 struct usb_kbd_pdata *data = dev->privptr;
173   - uint32_t leds = data->flags & USB_KBD_LEDMASK;
  174 + ALLOC_ALIGN_BUFFER(uint32_t, leds, 1, USB_DMA_MINALIGN);
174 175  
  176 + *leds = data->flags & USB_KBD_LEDMASK;
175 177 usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
176 178 USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
177   - 0x200, iface->desc.bInterfaceNumber, (void *)&leds, 1, 0);
  179 + 0x200, iface->desc.bInterfaceNumber, leds, 1, 0);
178 180 }
179 181  
180 182 #define CAPITAL_MASK 0x20
... ... @@ -488,7 +490,7 @@
488 490 /* Search for keyboard and register it if found. */
489 491 int drv_usb_kbd_init(void)
490 492 {
491   - struct stdio_dev usb_kbd_dev, *old_dev;
  493 + struct stdio_dev usb_kbd_dev;
492 494 struct usb_device *dev;
493 495 char *stdinname = getenv("stdin");
494 496 int error, i;
... ... @@ -507,16 +509,6 @@
507 509 if (usb_kbd_probe(dev, 0) != 1)
508 510 continue;
509 511  
510   - /* We found a keyboard, check if it is already registered. */
511   - debug("USB KBD: found set up device.\n");
512   - old_dev = stdio_get_by_name(DEVNAME);
513   - if (old_dev) {
514   - /* Already registered, just return ok. */
515   - debug("USB KBD: is already registered.\n");
516   - usb_kbd_deregister();
517   - return 1;
518   - }
519   -
520 512 /* Register the keyboard */
521 513 debug("USB KBD: register.\n");
522 514 memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
523 515  
... ... @@ -555,10 +547,14 @@
555 547 }
556 548  
557 549 /* Deregister the keyboard. */
558   -int usb_kbd_deregister(void)
  550 +int usb_kbd_deregister(int force)
559 551 {
560 552 #ifdef CONFIG_SYS_STDIO_DEREGISTER
561   - return stdio_deregister(DEVNAME);
  553 + int ret = stdio_deregister(DEVNAME, force);
  554 + if (ret && ret != -ENODEV)
  555 + return ret;
  556 +
  557 + return 0;
562 558 #else
563 559 return 1;
564 560 #endif
drivers/serial/serial-uclass.c
... ... @@ -198,7 +198,7 @@
198 198 #ifdef CONFIG_SYS_STDIO_DEREGISTER
199 199 struct serial_dev_priv *upriv = dev->uclass_priv;
200 200  
201   - if (stdio_deregister_dev(upriv->sdev))
  201 + if (stdio_deregister_dev(upriv->sdev), 0)
202 202 return -EPERM;
203 203 #endif
204 204  
drivers/usb/gadget/ci_udc.c
... ... @@ -777,6 +777,11 @@
777 777 /* select DEVICE mode */
778 778 writel(USBMODE_DEVICE, &udc->usbmode);
779 779  
  780 +#if !defined(CONFIG_USB_GADGET_DUALSPEED)
  781 + /* Port force Full-Speed Connect */
  782 + setbits_le32(&udc->portsc, PFSC);
  783 +#endif
  784 +
780 785 writel(0xffffffff, &udc->epflush);
781 786  
782 787 /* Turn on the USB connection by enabling the pullup resistor */
drivers/usb/gadget/f_dfu.c
... ... @@ -81,14 +81,6 @@
81 81 NULL,
82 82 };
83 83  
84   -static const struct usb_qualifier_descriptor dev_qualifier = {
85   - .bLength = sizeof dev_qualifier,
86   - .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
87   - .bcdUSB = __constant_cpu_to_le16(0x0200),
88   - .bDeviceClass = USB_CLASS_VENDOR_SPEC,
89   - .bNumConfigurations = 1,
90   -};
91   -
92 84 static const char dfu_name[] = "Device Firmware Upgrade";
93 85  
94 86 /*
... ... @@ -237,6 +229,7 @@
237 229 {
238 230 f_dfu->usb_function.strings = dfu_strings;
239 231 f_dfu->usb_function.hs_descriptors = f_dfu->function;
  232 + f_dfu->usb_function.descriptors = f_dfu->function;
240 233 f_dfu->dfu_state = DFU_STATE_dfuIDLE;
241 234 }
242 235  
... ... @@ -244,6 +237,7 @@
244 237 {
245 238 f_dfu->usb_function.strings = NULL;
246 239 f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
  240 + f_dfu->usb_function.descriptors = dfu_runtime_descs;
247 241 }
248 242  
249 243 static int handle_upload(struct usb_request *req, u16 len)
... ... @@ -808,6 +802,7 @@
808 802 return -ENOMEM;
809 803 f_dfu->usb_function.name = "dfu";
810 804 f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
  805 + f_dfu->usb_function.descriptors = dfu_runtime_descs;
811 806 f_dfu->usb_function.bind = dfu_bind;
812 807 f_dfu->usb_function.unbind = dfu_unbind;
813 808 f_dfu->usb_function.set_alt = dfu_set_alt;
drivers/usb/gadget/f_fastboot.c
... ... @@ -351,10 +351,11 @@
351 351 strncat(response, FASTBOOT_VERSION, chars_left);
352 352 } else if (!strcmp_l1("bootloader-version", cmd)) {
353 353 strncat(response, U_BOOT_VERSION, chars_left);
354   - } else if (!strcmp_l1("downloadsize", cmd)) {
  354 + } else if (!strcmp_l1("downloadsize", cmd) ||
  355 + !strcmp_l1("max-download-size", cmd)) {
355 356 char str_num[12];
356 357  
357   - sprintf(str_num, "%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
  358 + sprintf(str_num, "0x%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
358 359 strncat(response, str_num, chars_left);
359 360 } else if (!strcmp_l1("serialno", cmd)) {
360 361 s = getenv("serial#");
... ... @@ -386,6 +387,7 @@
386 387 unsigned int transfer_size = download_size - download_bytes;
387 388 const unsigned char *buffer = req->buf;
388 389 unsigned int buffer_size = req->actual;
  390 + unsigned int pre_dot_num, now_dot_num;
389 391  
390 392 if (req->status != 0) {
391 393 printf("Bad status: %d\n", req->status);
392 394  
393 395  
... ... @@ -398,8 +400,16 @@
398 400 memcpy((void *)CONFIG_USB_FASTBOOT_BUF_ADDR + download_bytes,
399 401 buffer, transfer_size);
400 402  
  403 + pre_dot_num = download_bytes / BYTES_PER_DOT;
401 404 download_bytes += transfer_size;
  405 + now_dot_num = download_bytes / BYTES_PER_DOT;
402 406  
  407 + if (pre_dot_num != now_dot_num) {
  408 + putc('.');
  409 + if (!(now_dot_num % 74))
  410 + putc('\n');
  411 + }
  412 +
403 413 /* Check if transfer is done */
404 414 if (download_bytes >= download_size) {
405 415 /*
... ... @@ -420,11 +430,6 @@
420 430 req->length = ep->maxpacket;
421 431 }
422 432  
423   - if (download_bytes && !(download_bytes % BYTES_PER_DOT)) {
424   - putc('.');
425   - if (!(download_bytes % (74 * BYTES_PER_DOT)))
426   - putc('\n');
427   - }
428 433 req->actual = 0;
429 434 usb_ep_queue(ep, req, 0);
430 435 }
... ... @@ -541,7 +546,14 @@
541 546 error("unknown command: %s\n", cmdbuf);
542 547 fastboot_tx_write_str("FAILunknown command");
543 548 } else {
544   - func_cb(ep, req);
  549 + if (req->actual < req->length) {
  550 + u8 *buf = (u8 *)req->buf;
  551 + buf[req->actual] = 0;
  552 + func_cb(ep, req);
  553 + } else {
  554 + error("buffer overflow\n");
  555 + fastboot_tx_write_str("FAILbuffer overflow");
  556 + }
545 557 }
546 558  
547 559 if (req->status == 0) {
drivers/usb/gadget/f_mass_storage.c
... ... @@ -1110,6 +1110,7 @@
1110 1110  
1111 1111 memset(buf, 0, 8);
1112 1112 buf[0] = TYPE_DISK;
  1113 + buf[1] = curlun->removable ? 0x80 : 0;
1113 1114 buf[2] = 2; /* ANSI SCSI level 2 */
1114 1115 buf[3] = 2; /* SCSI-2 INQUIRY data format */
1115 1116 buf[4] = 31; /* Additional length */
drivers/usb/gadget/f_thor.c
... ... @@ -458,16 +458,6 @@
458 458 .bInterval = 0x9,
459 459 };
460 460  
461   -static struct usb_qualifier_descriptor dev_qualifier = {
462   - .bLength = sizeof(dev_qualifier),
463   - .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
464   -
465   - .bcdUSB = __constant_cpu_to_le16(0x0200),
466   - .bDeviceClass = USB_CLASS_VENDOR_SPEC,
467   -
468   - .bNumConfigurations = 2,
469   -};
470   -
471 461 /*
472 462 * This attribute vendor descriptor is necessary for correct operation with
473 463 * Windows version of THOR download program
drivers/usb/host/ehci-hcd.c
... ... @@ -273,6 +273,29 @@
273 273 return QH_FULL_SPEED;
274 274 }
275 275  
  276 +static void ehci_update_endpt2_dev_n_port(struct usb_device *dev,
  277 + struct QH *qh)
  278 +{
  279 + struct usb_device *ttdev;
  280 +
  281 + if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL)
  282 + return;
  283 +
  284 + /*
  285 + * For full / low speed devices we need to get the devnum and portnr of
  286 + * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs
  287 + * in the tree before that one!
  288 + */
  289 + ttdev = dev;
  290 + while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
  291 + ttdev = ttdev->parent;
  292 + if (!ttdev->parent)
  293 + return;
  294 +
  295 + qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
  296 + QH_ENDPT2_HUBADDR(ttdev->parent->devnum));
  297 +}
  298 +
276 299 static int
277 300 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
278 301 int length, struct devrequest *req)
279 302  
... ... @@ -390,10 +413,9 @@
390 413 QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) |
391 414 QH_ENDPT1_DEVADDR(usb_pipedevice(pipe));
392 415 qh->qh_endpt1 = cpu_to_hc32(endpt);
393   - endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_PORTNUM(dev->portnr) |
394   - QH_ENDPT2_HUBADDR(dev->parent->devnum) |
395   - QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
  416 + endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
396 417 qh->qh_endpt2 = cpu_to_hc32(endpt);
  418 + ehci_update_endpt2_dev_n_port(dev, qh);
397 419 qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
398 420 qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
399 421  
... ... @@ -974,6 +996,7 @@
974 996 * Set up periodic list
975 997 * Step 1: Parent QH for all periodic transfers.
976 998 */
  999 + ehcic[index].periodic_schedules = 0;
977 1000 periodic = &ehcic[index].periodic_queue;
978 1001 memset(periodic, 0, sizeof(*periodic));
979 1002 periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
... ... @@ -1132,8 +1155,6 @@
1132 1155 return 0;
1133 1156 }
1134 1157  
1135   -static int periodic_schedules;
1136   -
1137 1158 struct int_queue *
1138 1159 create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
1139 1160 int elementsize, void *buffer)
1140 1161  
... ... @@ -1201,12 +1222,10 @@
1201 1222 (1 << 0)); /* S-mask: microframe 0 */
1202 1223 if (dev->speed == USB_SPEED_LOW ||
1203 1224 dev->speed == USB_SPEED_FULL) {
1204   - debug("TT: port: %d, hub address: %d\n",
1205   - dev->portnr, dev->parent->devnum);
1206   - qh->qh_endpt2 |= cpu_to_hc32((dev->portnr << 23) |
1207   - (dev->parent->devnum << 16) |
1208   - (0x1c << 8)); /* C-mask: microframes 2-4 */
  1225 + /* C-mask: microframes 2-4 */
  1226 + qh->qh_endpt2 |= cpu_to_hc32((0x1c << 8));
1209 1227 }
  1228 + ehci_update_endpt2_dev_n_port(dev, qh);
1210 1229  
1211 1230 td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
1212 1231 td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
... ... @@ -1258,7 +1277,7 @@
1258 1277 debug("FATAL: periodic should never fail, but did");
1259 1278 goto fail3;
1260 1279 }
1261   - periodic_schedules++;
  1280 + ctrl->periodic_schedules++;
1262 1281  
1263 1282 debug("Exit create_int_queue\n");
1264 1283 return result;
... ... @@ -1277,6 +1296,7 @@
1277 1296 void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
1278 1297 {
1279 1298 struct QH *cur = queue->current;
  1299 + struct qTD *cur_td;
1280 1300  
1281 1301 /* depleted queue */
1282 1302 if (cur == NULL) {
1283 1303  
... ... @@ -1284,20 +1304,21 @@
1284 1304 return NULL;
1285 1305 }
1286 1306 /* still active */
1287   - invalidate_dcache_range((uint32_t)cur,
1288   - ALIGN_END_ADDR(struct QH, cur, 1));
1289   - if (cur->qh_overlay.qt_token & cpu_to_hc32(0x80)) {
1290   - debug("Exit poll_int_queue with no completed intr transfer. "
1291   - "token is %x\n", cur->qh_overlay.qt_token);
  1307 + cur_td = &queue->tds[queue->current - queue->first];
  1308 + invalidate_dcache_range((uint32_t)cur_td,
  1309 + ALIGN_END_ADDR(struct qTD, cur_td, 1));
  1310 + if (QT_TOKEN_GET_STATUS(hc32_to_cpu(cur_td->qt_token)) &
  1311 + QT_TOKEN_STATUS_ACTIVE) {
  1312 + debug("Exit poll_int_queue with no completed intr transfer. token is %x\n",
  1313 + hc32_to_cpu(cur_td->qt_token));
1292 1314 return NULL;
1293 1315 }
1294 1316 if (!(cur->qh_link & QH_LINK_TERMINATE))
1295 1317 queue->current++;
1296 1318 else
1297 1319 queue->current = NULL;
1298   - debug("Exit poll_int_queue with completed intr transfer. "
1299   - "token is %x at %p (first at %p)\n", cur->qh_overlay.qt_token,
1300   - &cur->qh_overlay.qt_token, queue->first);
  1320 + debug("Exit poll_int_queue with completed intr transfer. token is %x at %p (first at %p)\n",
  1321 + hc32_to_cpu(cur_td->qt_token), cur, queue->first);
1301 1322 return cur->buffer;
1302 1323 }
1303 1324  
... ... @@ -1313,7 +1334,7 @@
1313 1334 debug("FATAL: periodic should never fail, but did");
1314 1335 goto out;
1315 1336 }
1316   - periodic_schedules--;
  1337 + ctrl->periodic_schedules--;
1317 1338  
1318 1339 struct QH *cur = &ctrl->periodic_queue;
1319 1340 timeout = get_timer(0) + 500; /* abort after 500ms */
... ... @@ -1322,6 +1343,8 @@
1322 1343 if (NEXT_QH(cur) == queue->first) {
1323 1344 debug("found candidate. removing from chain\n");
1324 1345 cur->qh_link = queue->last->qh_link;
  1346 + flush_dcache_range((uint32_t)cur,
  1347 + ALIGN_END_ADDR(struct QH, cur, 1));
1325 1348 result = 0;
1326 1349 break;
1327 1350 }
... ... @@ -1333,7 +1356,7 @@
1333 1356 }
1334 1357 }
1335 1358  
1336   - if (periodic_schedules > 0) {
  1359 + if (ctrl->periodic_schedules > 0) {
1337 1360 result = enable_periodic(ctrl);
1338 1361 if (result < 0)
1339 1362 debug("FATAL: periodic should never fail, but did");
drivers/usb/host/ehci-tegra.c
... ... @@ -305,11 +305,11 @@
305 305 #if defined(CONFIG_TEGRA20)
306 306 if (config->periph_id == PERIPH_ID_USBD) {
307 307 clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK,
308   - PTS_UTMI << PTS1_SHIFT);
  308 + pts << PTS1_SHIFT);
309 309 clrbits_le32(&usbctlr->port_sc1, STS1);
310 310 } else {
311 311 clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
312   - PTS_UTMI << PTS_SHIFT);
  312 + pts << PTS_SHIFT);
313 313 clrbits_le32(&usbctlr->port_sc1, STS);
314 314 }
315 315 #else
drivers/usb/host/ehci.h
... ... @@ -246,6 +246,7 @@
246 246 struct QH qh_list __aligned(USB_DMA_MINALIGN);
247 247 struct QH periodic_queue __aligned(USB_DMA_MINALIGN);
248 248 uint32_t *periodic_list;
  249 + int periodic_schedules;
249 250 int ntds;
250 251 };
251 252  
drivers/usb/musb-new/musb_core.c
... ... @@ -942,9 +942,7 @@
942 942  
943 943 /* put into basic highspeed mode and start session */
944 944 musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
945   -#ifdef CONFIG_USB_GADGET_DUALSPEED
946 945 | MUSB_POWER_HSENAB
947   -#endif
948 946 /* ENSUSPEND wedges tusb */
949 947 /* | MUSB_POWER_ENSUSPEND */
950 948 );
include/configs/siemens-am33x-common.h
... ... @@ -231,7 +231,7 @@
231 231 #define CONFIG_MUSB_GADGET
232 232 #define CONFIG_MUSB_PIO_ONLY
233 233 #define CONFIG_MUSB_DISABLE_BULK_COMBINE_SPLIT
234   -#define CONFIG_USB_GADGET_DUALSPEED
  234 +#undef CONFIG_USB_GADGET_DUALSPEED
235 235 #define CONFIG_USB_GADGET_VBUS_DRAW 2
236 236 #define CONFIG_MUSB_HOST
237 237  
... ... @@ -103,8 +103,8 @@
103 103  
104 104 void stdio_print_current_devices(void);
105 105 #ifdef CONFIG_SYS_STDIO_DEREGISTER
106   -int stdio_deregister(const char *devname);
107   -int stdio_deregister_dev(struct stdio_dev *dev);
  106 +int stdio_deregister(const char *devname, int force);
  107 +int stdio_deregister_dev(struct stdio_dev *dev, int force);
108 108 #endif
109 109 struct list_head* stdio_get_list(void);
110 110 struct stdio_dev* stdio_get_by_name(const char* name);
... ... @@ -216,7 +216,7 @@
216 216 #ifdef CONFIG_USB_KEYBOARD
217 217  
218 218 int drv_usb_kbd_init(void);
219   -int usb_kbd_deregister(void);
  219 +int usb_kbd_deregister(int force);
220 220  
221 221 #endif
222 222 /* routines */