usb_device.c (196219) | usb_device.c (196498) |
---|---|
1/* $FreeBSD: head/sys/dev/usb/usb_device.c 196219 2009-08-14 20:03:53Z jhb $ */ | 1/* $FreeBSD: head/sys/dev/usb/usb_device.c 196498 2009-08-24 05:05:38Z alfred $ */ |
2/*- 3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. --- 387 unchanged lines hidden (view full) --- 397 * Flag values, see "USB_UNCFG_FLAG_XXX". 398 *------------------------------------------------------------------------*/ 399static void 400usb_unconfigure(struct usb_device *udev, uint8_t flag) 401{ 402 uint8_t do_unlock; 403 404 /* automatic locking */ | 2/*- 3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. --- 387 unchanged lines hidden (view full) --- 397 * Flag values, see "USB_UNCFG_FLAG_XXX". 398 *------------------------------------------------------------------------*/ 399static void 400usb_unconfigure(struct usb_device *udev, uint8_t flag) 401{ 402 uint8_t do_unlock; 403 404 /* automatic locking */ |
405 if (sx_xlocked(udev->default_sx + 1)) { | 405 if (usbd_enum_is_locked(udev)) { |
406 do_unlock = 0; 407 } else { 408 do_unlock = 1; | 406 do_unlock = 0; 407 } else { 408 do_unlock = 1; |
409 sx_xlock(udev->default_sx + 1); | 409 usbd_enum_lock(udev); |
410 } 411 412 /* detach all interface drivers */ 413 usb_detach_device(udev, USB_IFACE_INDEX_ANY, flag); 414 415#if USB_HAVE_UGEN 416 /* free all FIFOs except control endpoint FIFOs */ 417 usb_fifo_free_wrap(udev, USB_IFACE_INDEX_ANY, flag); --- 19 unchanged lines hidden (view full) --- 437 if (udev->flags.usb_mode != USB_MODE_DEVICE) 438 free(udev->cdesc, M_USB); 439 udev->cdesc = NULL; 440 } 441 /* set unconfigured state */ 442 udev->curr_config_no = USB_UNCONFIG_NO; 443 udev->curr_config_index = USB_UNCONFIG_INDEX; 444 | 410 } 411 412 /* detach all interface drivers */ 413 usb_detach_device(udev, USB_IFACE_INDEX_ANY, flag); 414 415#if USB_HAVE_UGEN 416 /* free all FIFOs except control endpoint FIFOs */ 417 usb_fifo_free_wrap(udev, USB_IFACE_INDEX_ANY, flag); --- 19 unchanged lines hidden (view full) --- 437 if (udev->flags.usb_mode != USB_MODE_DEVICE) 438 free(udev->cdesc, M_USB); 439 udev->cdesc = NULL; 440 } 441 /* set unconfigured state */ 442 udev->curr_config_no = USB_UNCONFIG_NO; 443 udev->curr_config_index = USB_UNCONFIG_INDEX; 444 |
445 if (do_unlock) { 446 sx_unlock(udev->default_sx + 1); 447 } | 445 if (do_unlock) 446 usbd_enum_unlock(udev); |
448} 449 450/*------------------------------------------------------------------------* 451 * usbd_set_config_index 452 * 453 * This function selects configuration by index, independent of the 454 * actual configuration number. This function should not be used by 455 * USB drivers. --- 11 unchanged lines hidden (view full) --- 467 uint16_t max_power; 468 uint8_t selfpowered; 469 uint8_t do_unlock; 470 usb_error_t err; 471 472 DPRINTFN(6, "udev=%p index=%d\n", udev, index); 473 474 /* automatic locking */ | 447} 448 449/*------------------------------------------------------------------------* 450 * usbd_set_config_index 451 * 452 * This function selects configuration by index, independent of the 453 * actual configuration number. This function should not be used by 454 * USB drivers. --- 11 unchanged lines hidden (view full) --- 466 uint16_t max_power; 467 uint8_t selfpowered; 468 uint8_t do_unlock; 469 usb_error_t err; 470 471 DPRINTFN(6, "udev=%p index=%d\n", udev, index); 472 473 /* automatic locking */ |
475 if (sx_xlocked(udev->default_sx + 1)) { | 474 if (usbd_enum_is_locked(udev)) { |
476 do_unlock = 0; 477 } else { 478 do_unlock = 1; | 475 do_unlock = 0; 476 } else { 477 do_unlock = 1; |
479 sx_xlock(udev->default_sx + 1); | 478 usbd_enum_lock(udev); |
480 } 481 482 usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); 483 484 if (index == USB_UNCONFIG_INDEX) { 485 /* 486 * Leave unallocated when unconfiguring the 487 * device. "usb_unconfigure()" will also reset --- 92 unchanged lines hidden (view full) --- 580 usb_cdev_create(udev); 581#endif 582 583done: 584 DPRINTF("error=%s\n", usbd_errstr(err)); 585 if (err) { 586 usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); 587 } | 479 } 480 481 usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); 482 483 if (index == USB_UNCONFIG_INDEX) { 484 /* 485 * Leave unallocated when unconfiguring the 486 * device. "usb_unconfigure()" will also reset --- 92 unchanged lines hidden (view full) --- 579 usb_cdev_create(udev); 580#endif 581 582done: 583 DPRINTF("error=%s\n", usbd_errstr(err)); 584 if (err) { 585 usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); 586 } |
588 if (do_unlock) { 589 sx_unlock(udev->default_sx + 1); 590 } | 587 if (do_unlock) 588 usbd_enum_unlock(udev); |
591 return (err); 592} 593 594/*------------------------------------------------------------------------* 595 * usb_config_parse 596 * 597 * This function will allocate and free USB interfaces and USB endpoints, 598 * parse the USB configuration structure and initialise the USB endpoints --- 219 unchanged lines hidden (view full) --- 818usbd_set_alt_interface_index(struct usb_device *udev, 819 uint8_t iface_index, uint8_t alt_index) 820{ 821 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 822 usb_error_t err; 823 uint8_t do_unlock; 824 825 /* automatic locking */ | 589 return (err); 590} 591 592/*------------------------------------------------------------------------* 593 * usb_config_parse 594 * 595 * This function will allocate and free USB interfaces and USB endpoints, 596 * parse the USB configuration structure and initialise the USB endpoints --- 219 unchanged lines hidden (view full) --- 816usbd_set_alt_interface_index(struct usb_device *udev, 817 uint8_t iface_index, uint8_t alt_index) 818{ 819 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 820 usb_error_t err; 821 uint8_t do_unlock; 822 823 /* automatic locking */ |
826 if (sx_xlocked(udev->default_sx + 1)) { | 824 if (usbd_enum_is_locked(udev)) { |
827 do_unlock = 0; 828 } else { 829 do_unlock = 1; | 825 do_unlock = 0; 826 } else { 827 do_unlock = 1; |
830 sx_xlock(udev->default_sx + 1); | 828 usbd_enum_lock(udev); |
831 } 832 if (iface == NULL) { 833 err = USB_ERR_INVAL; 834 goto done; 835 } 836 if (iface->alt_index == alt_index) { 837 /* 838 * Optimise away duplicate setting of --- 19 unchanged lines hidden (view full) --- 858 err = USB_ERR_INVAL; 859 goto done; 860 } 861 862 err = usbd_req_set_alt_interface_no(udev, NULL, iface_index, 863 iface->idesc->bAlternateSetting); 864 865done: | 829 } 830 if (iface == NULL) { 831 err = USB_ERR_INVAL; 832 goto done; 833 } 834 if (iface->alt_index == alt_index) { 835 /* 836 * Optimise away duplicate setting of --- 19 unchanged lines hidden (view full) --- 856 err = USB_ERR_INVAL; 857 goto done; 858 } 859 860 err = usbd_req_set_alt_interface_no(udev, NULL, iface_index, 861 iface->idesc->bAlternateSetting); 862 863done: |
866 if (do_unlock) { 867 sx_unlock(udev->default_sx + 1); 868 } | 864 if (do_unlock) 865 usbd_enum_unlock(udev); 866 |
869 return (err); 870} 871 872/*------------------------------------------------------------------------* 873 * usbd_set_endpoint_stall 874 * 875 * This function is used to make a BULK or INTERRUPT endpoint 876 * send STALL tokens. --- 348 unchanged lines hidden (view full) --- 1225 uint8_t j; 1226 uint8_t do_unlock; 1227 1228 if (udev == NULL) { 1229 DPRINTF("udev == NULL\n"); 1230 return (USB_ERR_INVAL); 1231 } 1232 /* automatic locking */ | 867 return (err); 868} 869 870/*------------------------------------------------------------------------* 871 * usbd_set_endpoint_stall 872 * 873 * This function is used to make a BULK or INTERRUPT endpoint 874 * send STALL tokens. --- 348 unchanged lines hidden (view full) --- 1223 uint8_t j; 1224 uint8_t do_unlock; 1225 1226 if (udev == NULL) { 1227 DPRINTF("udev == NULL\n"); 1228 return (USB_ERR_INVAL); 1229 } 1230 /* automatic locking */ |
1233 if (sx_xlocked(udev->default_sx + 1)) { | 1231 if (usbd_enum_is_locked(udev)) { |
1234 do_unlock = 0; 1235 } else { 1236 do_unlock = 1; | 1232 do_unlock = 0; 1233 } else { 1234 do_unlock = 1; |
1237 sx_xlock(udev->default_sx + 1); | 1235 usbd_enum_lock(udev); |
1238 } 1239 1240 if (udev->curr_config_index == USB_UNCONFIG_INDEX) { 1241 /* do nothing - no configuration has been set */ 1242 goto done; 1243 } 1244 /* setup USB attach arguments */ 1245 --- 64 unchanged lines hidden (view full) --- 1310 if (uaa.temp_dev) { 1311 /* remove the last created child; it is unused */ 1312 1313 if (device_delete_child(udev->parent_dev, uaa.temp_dev)) { 1314 DPRINTFN(0, "device delete child failed!\n"); 1315 } 1316 } 1317done: | 1236 } 1237 1238 if (udev->curr_config_index == USB_UNCONFIG_INDEX) { 1239 /* do nothing - no configuration has been set */ 1240 goto done; 1241 } 1242 /* setup USB attach arguments */ 1243 --- 64 unchanged lines hidden (view full) --- 1308 if (uaa.temp_dev) { 1309 /* remove the last created child; it is unused */ 1310 1311 if (device_delete_child(udev->parent_dev, uaa.temp_dev)) { 1312 DPRINTFN(0, "device delete child failed!\n"); 1313 } 1314 } 1315done: |
1318 if (do_unlock) { 1319 sx_unlock(udev->default_sx + 1); 1320 } | 1316 if (do_unlock) 1317 usbd_enum_unlock(udev); 1318 |
1321 return (0); 1322} 1323 1324/*------------------------------------------------------------------------* 1325 * usb_suspend_resume_sub 1326 * 1327 * This function is called when the suspend or resume methods should 1328 * be executed on an USB device. --- 445 unchanged lines hidden (view full) --- 1774 DPRINTFN(0, "Found possible auto-install " 1775 "disk (trying next config)\n"); 1776 config_index++; 1777 goto repeat_set_config; 1778 } 1779 } 1780 } else if (usb_test_huawei_autoinst_p(udev, &uaa) == 0) { 1781 DPRINTFN(0, "Found Huawei auto-install disk!\n"); | 1319 return (0); 1320} 1321 1322/*------------------------------------------------------------------------* 1323 * usb_suspend_resume_sub 1324 * 1325 * This function is called when the suspend or resume methods should 1326 * be executed on an USB device. --- 445 unchanged lines hidden (view full) --- 1772 DPRINTFN(0, "Found possible auto-install " 1773 "disk (trying next config)\n"); 1774 config_index++; 1775 goto repeat_set_config; 1776 } 1777 } 1778 } else if (usb_test_huawei_autoinst_p(udev, &uaa) == 0) { 1779 DPRINTFN(0, "Found Huawei auto-install disk!\n"); |
1782 err = USB_ERR_STALLED; /* fake an error */ | 1780 /* leave device unconfigured */ 1781 usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_SUBDEV); |
1783 } 1784 } else { 1785 err = 0; /* set success */ 1786 } 1787 1788 DPRINTF("new dev (addr %d), udev=%p, parent_hub=%p\n", 1789 udev->address, udev, udev->parent_hub); 1790 --- 106 unchanged lines hidden (view full) --- 1897 LIST_INSERT_HEAD(&udev->pd_list, pd, pd_next); 1898 } 1899} 1900 1901static void 1902usb_cdev_free(struct usb_device *udev) 1903{ 1904 struct usb_fs_privdata* pd; | 1782 } 1783 } else { 1784 err = 0; /* set success */ 1785 } 1786 1787 DPRINTF("new dev (addr %d), udev=%p, parent_hub=%p\n", 1788 udev->address, udev, udev->parent_hub); 1789 --- 106 unchanged lines hidden (view full) --- 1896 LIST_INSERT_HEAD(&udev->pd_list, pd, pd_next); 1897 } 1898} 1899 1900static void 1901usb_cdev_free(struct usb_device *udev) 1902{ 1903 struct usb_fs_privdata* pd; |
1904 struct cdev* pcdev; |
|
1905 1906 DPRINTFN(2, "Freeing device nodes\n"); 1907 1908 while ((pd = LIST_FIRST(&udev->pd_list)) != NULL) { 1909 KASSERT(pd->cdev->si_drv1 == pd, ("privdata corrupt")); 1910 | 1905 1906 DPRINTFN(2, "Freeing device nodes\n"); 1907 1908 while ((pd = LIST_FIRST(&udev->pd_list)) != NULL) { 1909 KASSERT(pd->cdev->si_drv1 == pd, ("privdata corrupt")); 1910 |
1911 destroy_dev_sched_cb(pd->cdev, usb_cdev_cleanup, pd); | 1911 pcdev = pd->cdev; |
1912 pd->cdev = NULL; 1913 LIST_REMOVE(pd, pd_next); | 1912 pd->cdev = NULL; 1913 LIST_REMOVE(pd, pd_next); |
1914 if (pcdev != NULL) 1915 destroy_dev_sched_cb(pcdev, usb_cdev_cleanup, pd); |
|
1914 } 1915} 1916 1917static void 1918usb_cdev_cleanup(void* arg) 1919{ 1920 free(arg, M_USBDEV); 1921} --- 521 unchanged lines hidden (view full) --- 2443 udev->state = state; 2444} 2445 2446uint8_t 2447usbd_device_attached(struct usb_device *udev) 2448{ 2449 return (udev->state > USB_STATE_DETACHED); 2450} | 1916 } 1917} 1918 1919static void 1920usb_cdev_cleanup(void* arg) 1921{ 1922 free(arg, M_USBDEV); 1923} --- 521 unchanged lines hidden (view full) --- 2445 udev->state = state; 2446} 2447 2448uint8_t 2449usbd_device_attached(struct usb_device *udev) 2450{ 2451 return (udev->state > USB_STATE_DETACHED); 2452} |
2453 2454/* The following function locks enumerating the given USB device. */ 2455 2456void 2457usbd_enum_lock(struct usb_device *udev) 2458{ 2459 sx_xlock(udev->default_sx + 1); 2460 /* 2461 * NEWBUS LOCK NOTE: We should check if any parent SX locks 2462 * are locked before locking Giant. Else the lock can be 2463 * locked multiple times. 2464 */ 2465 mtx_lock(&Giant); 2466} 2467 2468/* The following function unlocks enumerating the given USB device. */ 2469 2470void 2471usbd_enum_unlock(struct usb_device *udev) 2472{ 2473 mtx_unlock(&Giant); 2474 sx_xunlock(udev->default_sx + 1); 2475} 2476 2477/* 2478 * The following function checks the enumerating lock for the given 2479 * USB device. 2480 */ 2481 2482uint8_t 2483usbd_enum_is_locked(struct usb_device *udev) 2484{ 2485 return (sx_xlocked(udev->default_sx + 1)); 2486} |
|