Changeset 3f02935 in mainline for uspace/drv/bus/usb/usbhub/port.c
- Timestamp:
- 2018-01-21T19:33:22Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cd0cf81
- Parents:
- cd3fa47
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhub/port.c
rcd3fa47 r3f02935 99 99 100 100 /** 101 * Routine for adding a new device. 102 * 103 * Separate fibril is needed because the operation blocks on waiting for 104 * requesting default address and resetting port, and we must not block the 105 * control pipe. 106 */ 101 * Routine for adding a new device in USB2. 102 */ 103 static int enumerate_device_usb2(usb_hub_port_t *port, async_exch_t *exch) 104 { 105 int err; 106 107 port_log(debug, port, "Requesting default address."); 108 err = usb_hub_reserve_default_address(port->hub, exch, &port->base); 109 if (err != EOK) { 110 port_log(error, port, "Failed to reserve default address: %s", str_error(err)); 111 return err; 112 } 113 114 /* Reservation of default address could have blocked */ 115 if (port->base.state != PORT_CONNECTING) 116 goto out_address; 117 118 port_log(debug, port, "Resetting port."); 119 if ((err = usb_hub_set_port_feature(port->hub, port->port_number, USB_HUB_FEATURE_PORT_RESET))) { 120 port_log(warning, port, "Port reset request failed: %s", str_error(err)); 121 goto out_address; 122 } 123 124 if ((err = usb_port_wait_for_enabled(&port->base))) { 125 port_log(error, port, "Failed to reset port: %s", str_error(err)); 126 goto out_address; 127 } 128 129 port_log(debug, port, "Enumerating device."); 130 if ((err = usbhc_device_enumerate(exch, port->port_number, port->speed))) { 131 port_log(error, port, "Failed to enumerate device: %s", str_error(err)); 132 /* Disable the port */ 133 usb_hub_clear_port_feature(port->hub, port->port_number, USB2_HUB_FEATURE_PORT_ENABLE); 134 goto out_address; 135 } 136 137 port_log(debug, port, "Device enumerated"); 138 139 out_address: 140 usb_hub_release_default_address(port->hub, exch); 141 return err; 142 } 143 144 /** 145 * Routine for adding a new device in USB 3. 146 */ 147 static int enumerate_device_usb3(usb_hub_port_t *port, async_exch_t *exch) 148 { 149 int err; 150 151 port_log(debug, port, "Issuing a warm reset."); 152 if ((err = usb_hub_set_port_feature(port->hub, port->port_number, USB3_HUB_FEATURE_BH_PORT_RESET))) { 153 port_log(warning, port, "Port reset request failed: %s", str_error(err)); 154 return err; 155 } 156 157 if ((err = usb_port_wait_for_enabled(&port->base))) { 158 port_log(error, port, "Failed to reset port: %s", str_error(err)); 159 return err; 160 } 161 162 port_log(debug, port, "Enumerating device."); 163 if ((err = usbhc_device_enumerate(exch, port->port_number, port->speed))) { 164 port_log(error, port, "Failed to enumerate device: %s", str_error(err)); 165 return err; 166 } 167 168 port_log(debug, port, "Device enumerated"); 169 return EOK; 170 } 171 107 172 static int enumerate_device(usb_port_t *port_base) 108 173 { 109 int err;110 174 usb_hub_port_t *port = get_hub_port(port_base); 111 175 112 176 port_log(debug, port, "Setting up new device."); 113 114 177 async_exch_t *exch = usb_device_bus_exchange_begin(port->hub->usb_device); 115 178 if (!exch) { … … 118 181 } 119 182 120 /* Reserve default address */ 121 err = usb_hub_reserve_default_address(port->hub, exch, &port->base); 122 if (err != EOK) { 123 port_log(error, port, "Failed to reserve default address: %s", str_error(err)); 124 goto out_exch; 125 } 126 127 /* Reservation of default address could have blocked */ 128 if (port->base.state != PORT_CONNECTING) 129 goto out_address; 130 131 port_log(debug, port, "Got default address. Resetting port."); 132 int rc = usb_hub_set_port_feature(port->hub, port->port_number, USB_HUB_FEATURE_PORT_RESET); 133 if (rc != EOK) { 134 port_log(warning, port, "Port reset request failed: %s", str_error(rc)); 135 goto out_address; 136 } 137 138 if ((err = usb_port_wait_for_enabled(&port->base))) { 139 port_log(error, port, "Failed to reset port: %s", str_error(err)); 140 goto out_address; 141 } 142 143 port_log(debug, port, "Port reset, enumerating device."); 144 145 if ((err = usbhc_device_enumerate(exch, port->port_number, port->speed))) { 146 port_log(error, port, "Failed to enumerate device: %s", str_error(err)); 147 /* Disable the port in USB 2 (impossible in USB3) */ 148 if (port->speed <= USB_SPEED_HIGH) 149 usb_hub_clear_port_feature(port->hub, port->port_number, USB2_HUB_FEATURE_PORT_ENABLE); 150 goto out_address; 151 } 152 153 port_log(debug, port, "Device enumerated"); 154 155 out_address: 156 usb_hub_release_default_address(port->hub, exch); 157 out_exch: 183 const int err = port->hub->speed == USB_SPEED_SUPER 184 ? enumerate_device_usb3(port, exch) 185 : enumerate_device_usb2(port, exch); 186 158 187 usb_device_bus_exchange_end(exch); 159 188 return err; … … 165 194 port_log(debug, port, "Connection change: device %s.", connected ? "attached" : "removed"); 166 195 167 if (connected ) {196 if (connected && port->hub->speed == USB_SPEED_SUPER) { 168 197 usb_port_connected(&port->base, &enumerate_device); 169 198 } else { … … 206 235 207 236 if (enabled) { 208 // The connecting fibril do not touch speed until the port is enabled,209 // so we do not have to lock210 237 port->speed = get_port_speed(port, status); 211 238 usb_port_enabled(&port->base);
Note:
See TracChangeset
for help on using the changeset viewer.