Deleted Added
full compact
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}