admin管理员组

文章数量:1567567

2023年12月17日发(作者:)

58 hub_quiesce(hub, HUB_DISCONNECT); 59 goto loop; 60 } 61

62 /* Autoresume */ 63 ret = usb_autopm_get_interface(intf); 64 if (ret) { 65 dev_dbg(hub_dev, "Can't autoresume: %dn", ret); 66 goto loop; 67 } 68

69 /* If this is an inactive hub, do nothing */ 70 if (hub->quiescing) 71 goto loop_autopm; 72

73 if (hub->error) { 74 dev_dbg (hub_dev, "resetting for error %dn", 75 hub->error); 76

77 ret = usb_reset_device(hdev); 78 if (ret) { 79 dev_dbg (hub_dev, 80 "error resetting hub: %dn", ret); 81 goto loop_autopm; 82 } 83

84 hub->nerrors = 0; 85 hub->error = 0; 86 } 87

88 /* deal with port status changes */ 89 for (i = 1; i <= hub->descriptor->bNbrPorts; i++) { 90 if (test_bit(i, hub->busy_bits)) 91 continue; 92 connect_change = test_bit(i, hub->change_bits); 93 wakeup_change = test_and_clear_bit(i, hub->wakeup_bits); 94 if (!test_and_clear_bit(i, hub->event_bits) && 95 !connect_change && !wakeup_change) 96 continue; 97

98 ret = hub_port_status(hub, i, 99 &portstatus, &portchange);100 if (ret < 0)101 continue;102

103 if (portchange & USB_PORT_STAT_C_CONNECTION) {104 usb_clear_port_feature(hdev, i,105 USB_PORT_FEAT_C_CONNECTION);106 connect_change = 1;107 }108

109 if (portchange & USB_PORT_STAT_C_ENABLE) {110 if (!connect_change)111 dev_dbg (hub_dev,112 "port %d enable change, "113 "status %08xn",114 i, portstatus);115 usb_clear_port_feature(hdev, i,116 USB_PORT_FEAT_C_ENABLE);117

118 /*119 * EM interference sometimes causes badly120 * shielded USB devices to be shutdown by121 * the hub, this hack enables them again.122 * Works at least with mouse driver.

123 */124 if (!(portstatus & USB_PORT_STAT_ENABLE)125 && !connect_change126 && hub->ports[i - 1]->child) {127 dev_err (hub_dev,128 "port %i "129 "disabled by hub (EMI?), "130 "",131 i);132 connect_change = 1;133 }134 }135

136 if (hub_handle_remote_wakeup(hub, i,137 portstatus, portchange))138 connect_change = 1;139

140 if (portchange & USB_PORT_STAT_C_OVERCURRENT) {141 u16 status = 0;

48 * For Wireless USB devices, ep0 max packet is always 512 (tho 49 * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. 50 */ 51 switch (udev->speed) { 52 case USB_SPEED_SUPER: 53 case USB_SPEED_WIRELESS: /* fixed at 512 */ 54 udev->cketSize = cpu_to_le16(512); 55 break; 56 case USB_SPEED_HIGH: /* fixed at 64 */ 57 udev->cketSize = cpu_to_le16(64); 58 break; 59 case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ 60 /* to determine the ep0 maxpacket size, try to read 61 * the device descriptor to get bMaxPacketSize0 and 62 * then correct our initial guess. 63 */ 64 udev->cketSize = cpu_to_le16(64); 65 break; 66 case USB_SPEED_LOW: /* fixed at 8 */ 67 udev->cketSize = cpu_to_le16(8); 68 break; 69 default: 70 goto fail; 71 } 72

73 if (udev->speed == USB_SPEED_WIRELESS) 74 speed = "variable speed Wireless"; 75 else 76 speed = usb_speed_string(udev->speed); 77

78 if (udev->speed != USB_SPEED_SUPER) 79 dev_info(&udev->dev, 80 "%s %s USB device number %d using %sn", 81 (udev->config) ? "reset" : "new", speed, 82 devnum, udev->bus->controller->driver->name); 83

84 /* Set up TT records, if needed */ 85 if (hdev->tt) { 86 udev->tt = hdev->tt; 87 udev->ttport = hdev->ttport; 88 } else if (udev->speed != USB_SPEED_HIGH 89 && hdev->speed == USB_SPEED_HIGH) { 90 if (!hub->) { 91 dev_err(&udev->dev, "parent hub has no TTn"); 92 retval = -EINVAL; 93 goto fail; 94 } 95 udev->tt = &hub->tt; 96 udev->ttport = port1; 97 } 98

99 /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?100 * Because device hardware and firmware is sometimes buggy in101 * this area, and this is how Linux has done it for ages.102 * Change it cautiously.103 *104 * NOTE: If USE_NEW_SCHEME() is true we will start by issuing105 * a 64-byte GET_DESCRIPTOR request. This is what Windows does,106 * so it may help with some non-standards-compliant devices.107 * Otherwise we start with SET_ADDRESS and then try to read the108 * first 8 bytes of the device descriptor to get the ep0 maxpacket109 * value.110 */111 for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {112 if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) {113 struct usb_device_descriptor *buf;114 int r = 0;115

116 #define GET_DESCRIPTOR_BUFSIZE 64117 buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);118 if (!buf) {119 retval = -ENOMEM;120 continue;121 }122

123 /* Retry on all errors; some devices are flakey.124 * 255 is for WUSB devices, we actually need to use125 * 512 (WUSB1.0[4.8.1]).126 */127 for (j = 0; j < 3; ++j) {128 buf->bMaxPacketSize0 = 0;129 r = usb_control_msg(udev, usb_rcvaddr0pipe(),130 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,131 USB_DT_DEVICE << 8, 0,

132 buf, GET_DESCRIPTOR_BUFSIZE,133 initial_descriptor_timeout);134 switch (buf->bMaxPacketSize0) {135 case 8: case 16: case 32: case 64: case 255:136 if (buf->bDescriptorType ==137 USB_DT_DEVICE) {138 r = 0;139 break;140 }141 /* FALL THROUGH */142 default:143 if (r == 0)144 r = -EPROTO;145 break;146 }147 if (r == 0)148 break;149 }150 udev->cketSize0 =151 buf->bMaxPacketSize0;152 kfree(buf);153

154 retval = hub_port_reset(hub, port1, udev, delay, false);155 if (retval < 0) /* error or disconnect */156 goto fail;157 if (oldspeed != udev->speed) {158 dev_dbg(&udev->dev,159 "device reset changed speed!n");160 retval = -ENODEV;161 goto fail;162 }163 if (r) {164 if (r != -ENODEV)165 dev_err(&udev->dev, "device descriptor read/64, error %dn",166 r);167 retval = -EMSGSIZE;168 continue;169 }170 #undef GET_DESCRIPTOR_BUFSIZE171 }172

173 /*174 * If device is WUSB, we already assigned an175 * unauthorized address in the Connect Ack sequence;176 * authorization will assign the final address.177 */178 if (udev->wusb == 0) {179 for (j = 0; j < SET_ADDRESS_TRIES; ++j) {180 retval = hub_set_address(udev, devnum);//设置地址,告诉USB设备新的地址编号181 if (retval >= 0)182 break;183 msleep(200);184 }185 if (retval < 0) {186 if (retval != -ENODEV)187 dev_err(&udev->dev, "device not accepting address %d, error %dn",188 devnum, retval);189 goto fail;190 }191 if (udev->speed == USB_SPEED_SUPER) {192 devnum = udev->devnum;193 dev_info(&udev->dev,194 "%s SuperSpeed USB device number %d using %sn",195 (udev->config) ? "reset" : "new",196 devnum, udev->bus->controller->driver->name);197 }198

199 /* cope with hardware quirkiness:200 * - let SET_ADDRESS settle, some device hardware wants it201 * - read ep0 maxpacket even for high and low speed,202 */203 msleep(10);204 if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3))205 break;206 }207

208 retval = usb_get_device_descriptor(udev, 8);//获得USB设备描述符前8个字节209 if (retval < 8) {210 if (retval != -ENODEV)211 dev_err(&udev->dev,212 "device descriptor read/8, error %dn",213 retval);214 if (retval >= 0)215 retval = -EMSGSIZE;

43 strlen(udev->manufacturer));44

45 device_enable_async_suspend(&udev->dev);46

47 /*48 * check whether the hub marks this port as non-removable. Do it49 * now so that platform-specific data can override it in50 * device_add()51 */52 if (udev->parent)53 set_usb_port_removable(udev);54

55 /* Register the device. The device driver is responsible56 * for configuring the device and invoking the add-device57 * notifier chain (used by usbfs and possibly others).58 */59 err = device_add(&udev->dev);//添加usb设备60 if (err) {61 dev_err(&udev->dev, "can't device_add, error %dn", err);62 goto fail;63 }64

65 /* Create link files between child device and usb port device. */66 if (udev->parent) {67 struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);68 struct usb_port *port_dev = hub->ports[udev->portnum - 1];69

70 err = sysfs_create_link(&udev->,71 &port_dev->, "port");72 if (err)73 goto fail;74

75 err = sysfs_create_link(&port_dev->,76 &udev->, "device");77 if (err) {78 sysfs_remove_link(&udev->, "port");79 goto fail;80 }81

82 pm_runtime_get_sync(&port_dev->dev);83 }84

85 (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);86 usb_mark_last_busy(udev);87 pm_runtime_put_sync_autosuspend(&udev->dev);88 return err;89

90 fail:91 usb_set_device_state(udev, USB_STATE_NOTATTACHED);92 pm_runtime_disable(&udev->dev);93 pm_runtime_set_suspended(&udev->dev);94 return err;95 }2.11 函数usb_enumerate_device 1 static int usb_enumerate_device(struct usb_device *udev) 2 { 3 int err; 4

5 if (udev->config == NULL) { 6 err = usb_get_configuration(udev);//获取配置描述符,具体定义位于driversusbcoreconfig.c 7 if (err < 0) { 8 if (err != -ENODEV) 9 dev_err(&udev->dev, "can't read configurations, error %dn",10 err);11 return err;12 }13 }14

15 /* read the standard strings and cache them if present */16 udev->product = usb_cache_string(udev, udev->ct);17 udev->manufacturer = usb_cache_string(udev,18 udev->acturer);19 udev->serial = usb_cache_string(udev, udev->lNumber);20

21 err = usb_enumerate_device_otg(udev);22 if (err < 0)23 return err;24

25 usb_detect_interface_quirks(udev);26

27 return 0;

本文标签: 设备描述符驱动地址配置