Changes in / [0c00dac:026d6e2] in mainline
- Location:
- uspace
- Files:
-
- 3 added
- 2 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/iface.c
r0c00dac r026d6e2 54 54 } 55 55 /*----------------------------------------------------------------------------*/ 56 static int reserve_default_address(device_t *dev, bool full_speed)56 static int reserve_default_address(device_t *dev, usb_speed_t speed) 57 57 { 58 58 assert(dev); … … 72 72 } 73 73 /*----------------------------------------------------------------------------*/ 74 static int request_address(device_t *dev, bool full_speed,74 static int request_address(device_t *dev, usb_speed_t speed, 75 75 usb_address_t *address) 76 76 { -
uspace/drv/uhci-rhd/port.c
r0c00dac r026d6e2 131 131 return EOK; 132 132 } 133 /*----------------------------------------------------------------------------*/ 134 static int uhci_port_new_device(uhci_port_t *port) 135 { 136 assert(port); 137 assert(usb_hc_connection_is_opened(&port->hc_connection)); 138 139 usb_log_info("Adding new device on port %d.\n", port->number); 140 141 /* get address of the future device */ 142 const usb_address_t usb_address = usb_hc_request_address( 143 &port->hc_connection, true); 144 145 if (usb_address <= 0) { 146 usb_log_error("Recieved invalid address(%d).\n", usb_address); 147 return usb_address; 148 } 149 usb_log_debug("Sucessfully obtained address %d for port %d.\n", 150 usb_address, port->number); 151 152 /* get default address */ 153 int ret = usb_hc_reserve_default_address(&port->hc_connection, true); 154 if (ret != EOK) { 155 usb_log_error("Failed to reserve default address on port %d.\n", 156 port->number); 157 int ret2 = usb_hc_unregister_device(&port->hc_connection, 158 usb_address); 159 if (ret2 != EOK) { 160 usb_log_fatal("Failed to return requested address on port %d.\n", 161 port->number); 162 return ret2; 163 } 164 usb_log_debug("Successfully returned reserved address on port %d.\n", 165 port->number); 166 return ret; 167 } 168 usb_log_debug("Sucessfully obtained default address for port %d.\n", 169 port->number); 133 134 /** Callback for enabling port during adding a new device. 135 * 136 * @param portno Port number (unused). 137 * @param arg Pointer to uhci_port_t of port with the new device. 138 * @return Error code. 139 */ 140 static int new_device_enable_port(int portno, void *arg) 141 { 142 uhci_port_t *port = (uhci_port_t *) arg; 143 144 usb_log_debug("new_device_enable_port(%d)\n", port->number); 170 145 171 146 /* 172 * the host then waits for at least 100 ms to allow completion of147 * The host then waits for at least 100 ms to allow completion of 173 148 * an insertion process and for power at the device to become stable. 174 149 */ 175 150 async_usleep(100000); 176 151 177 /* enable port*/152 /* Enable the port. */ 178 153 uhci_port_set_enabled(port, true); 179 154 … … 197 172 } 198 173 199 /* 200 * Initialize connection to the device. 201 */ 202 /* FIXME: check for errors. */ 203 usb_device_connection_t new_dev_connection; 204 usb_endpoint_pipe_t new_dev_ctrl_pipe; 205 usb_device_connection_initialize_on_default_address( 206 &new_dev_connection, &port->hc_connection); 207 usb_endpoint_pipe_initialize_default_control(&new_dev_ctrl_pipe, 208 &new_dev_connection); 209 210 /* 211 * Assign new address to the device. This function updates 212 * the backing connection to still point to the same device. 213 */ 214 /* FIXME: check for errors. */ 215 usb_endpoint_pipe_start_session(&new_dev_ctrl_pipe); 216 ret = usb_request_set_address(&new_dev_ctrl_pipe, usb_address); 217 usb_endpoint_pipe_end_session(&new_dev_ctrl_pipe); 218 219 if (ret != EOK) { /* address assigning went wrong */ 220 usb_log_error("Failed(%d) to assign address to the device.\n", ret); 174 return EOK; 175 } 176 177 /*----------------------------------------------------------------------------*/ 178 static int uhci_port_new_device(uhci_port_t *port) 179 { 180 assert(port); 181 assert(usb_hc_connection_is_opened(&port->hc_connection)); 182 183 usb_log_info("Detected new device on port %u.\n", port->number); 184 185 usb_address_t dev_addr; 186 int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 187 USB_SPEED_FULL, 188 new_device_enable_port, port->number, port, 189 &dev_addr, &port->attached_device); 190 if (rc != EOK) { 191 usb_log_error("Failed adding new device on port %u: %s.\n", 192 port->number, str_error(rc)); 221 193 uhci_port_set_enabled(port, false); 222 int release = usb_hc_release_default_address(&port->hc_connection); 223 if (release != EOK) { 224 usb_log_error("Failed to release default address on port %d.\n", 225 port->number); 226 return release; 227 } 228 usb_log_debug("Sucessfully released default address on port %d.\n", 229 port->number); 230 return ret; 231 } 232 usb_log_debug("Sucessfully assigned address %d for port %d.\n", 233 usb_address, port->number); 234 235 /* release default address */ 236 ret = usb_hc_release_default_address(&port->hc_connection); 237 if (ret != EOK) { 238 usb_log_error("Failed to release default address on port %d.\n", 239 port->number); 240 return ret; 241 } 242 usb_log_debug("Sucessfully released default address on port %d.\n", 243 port->number); 244 245 /* communicate and possibly report to devman */ 246 assert(port->attached_device == 0); 247 248 ret = usb_device_register_child_in_devman(new_dev_connection.address, 249 new_dev_connection.hc_handle, port->rh, &port->attached_device); 250 251 if (ret != EOK) { /* something went wrong */ 252 usb_log_error("Failed(%d) in usb_drv_register_child.\n", ret); 253 uhci_port_set_enabled(port, false); 254 return ENOMEM; 255 } 256 usb_log_info("Sucessfully added device on port(%d) address(%d) handle %d.\n", 257 port->number, usb_address, port->attached_device); 258 259 /* 260 * Register the device in the host controller. 261 */ 262 usb_hc_attached_device_t new_device = { 263 .address = new_dev_connection.address, 264 .handle = port->attached_device 265 }; 266 267 ret = usb_hc_register_device(&port->hc_connection, &new_device); 268 // TODO: proper error check here 269 assert(ret == EOK); 270 271 return EOK; 272 } 194 return rc; 195 } 196 197 usb_log_info("New device on port %u has address %d (handle %zu).\n", 198 port->number, dev_addr, port->attached_device); 199 200 return EOK; 201 } 202 273 203 /*----------------------------------------------------------------------------*/ 274 204 static int uhci_port_remove_device(uhci_port_t *port) -
uspace/drv/vhc/connhost.c
r0c00dac r026d6e2 390 390 391 391 392 static int reserve_default_address(device_t *dev, boolignored)392 static int reserve_default_address(device_t *dev, usb_speed_t ignored) 393 393 { 394 394 usb_address_keeping_reserve_default(&addresses); … … 402 402 } 403 403 404 static int request_address(device_t *dev, bool ignored, usb_address_t *address) 404 static int request_address(device_t *dev, usb_speed_t ignored, 405 usb_address_t *address) 405 406 { 406 407 usb_address_t addr = usb_address_keeping_request(&addresses); -
uspace/lib/c/generic/str_error.c
r0c00dac r026d6e2 73 73 case EBADCHECKSUM: 74 74 return "Bad checksum"; 75 case ESTALL: 76 return "Operation stalled"; 75 77 case EAGAIN: 76 78 return "Resource temporarily unavailable"; -
uspace/lib/c/include/errno.h
r0c00dac r026d6e2 59 59 #define EBADCHECKSUM (-300) 60 60 61 /** USB: stalled operation. */ 62 #define ESTALL (-301) 63 61 64 /** An API function is called while another blocking function is in progress. */ 62 65 #define EINPROGRESS (-10036) -
uspace/lib/drv/generic/remote_usbhc.c
r0c00dac r026d6e2 166 166 } 167 167 168 bool full_speed = DEV_IPC_GET_ARG1(*call);168 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 169 169 170 int rc = usb_iface->reserve_default_address(device, full_speed);170 int rc = usb_iface->reserve_default_address(device, speed); 171 171 172 172 async_answer_0(callid, rc); … … 198 198 } 199 199 200 bool full_speed = DEV_IPC_GET_ARG1(*call);200 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 201 201 202 202 usb_address_t address; 203 int rc = usb_iface->request_address(device, full_speed, &address);203 int rc = usb_iface->request_address(device, speed, &address); 204 204 if (rc != EOK) { 205 205 async_answer_0(callid, rc); -
uspace/lib/drv/include/usbhc_iface.h
r0c00dac r026d6e2 232 232 int (*tell_address)(device_t *, devman_handle_t, usb_address_t *); 233 233 234 int (*reserve_default_address)(device_t *, bool);234 int (*reserve_default_address)(device_t *, usb_speed_t); 235 235 int (*release_default_address)(device_t *); 236 int (*request_address)(device_t *, bool, usb_address_t *);236 int (*request_address)(device_t *, usb_speed_t, usb_address_t *); 237 237 int (*bind_address)(device_t *, usb_address_t, devman_handle_t); 238 238 int (*release_address)(device_t *, usb_address_t); -
uspace/lib/usb/include/usb/hub.h
r0c00dac r026d6e2 39 39 #include <usb/usbdevice.h> 40 40 41 int usb_hc_new_device_wrapper(device_t *, usb_hc_connection_t *, usb_speed_t, 42 int (*)(int, void *), int, void *, usb_address_t *, devman_handle_t *); 43 41 44 /** Info about device attached to host controller. 42 45 * … … 52 55 } usb_hc_attached_device_t; 53 56 54 int usb_hc_reserve_default_address(usb_hc_connection_t *, bool);57 int usb_hc_reserve_default_address(usb_hc_connection_t *, usb_speed_t); 55 58 int usb_hc_release_default_address(usb_hc_connection_t *); 56 59 57 usb_address_t usb_hc_request_address(usb_hc_connection_t *, bool);60 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t); 58 61 int usb_hc_register_device(usb_hc_connection_t *, 59 62 const usb_hc_attached_device_t *); -
uspace/lib/usb/include/usb/usb.h
r0c00dac r026d6e2 68 68 USB_DIRECTION_BOTH 69 69 } usb_direction_t; 70 71 /** USB speeds. */ 72 typedef enum { 73 /** USB 1.1 low speed (1.5Mbits/s). */ 74 USB_SPEED_LOW, 75 /** USB 1.1 full speed (12Mbits/s). */ 76 USB_SPEED_FULL, 77 /** USB 2.0 high speed (480Mbits/s). */ 78 USB_SPEED_HIGH 79 } usb_speed_t; 70 80 71 81 /** USB request type target. */ -
uspace/lib/usb/src/hub.c
r0c00dac r026d6e2 34 34 */ 35 35 #include <usb/hub.h> 36 #include <usb/pipes.h> 37 #include <usb/request.h> 38 #include <usb/recognise.h> 36 39 #include <usbhc_iface.h> 37 40 #include <errno.h> … … 56 59 */ 57 60 int usb_hc_reserve_default_address(usb_hc_connection_t *connection, 58 bool full_speed)61 usb_speed_t speed) 59 62 { 60 63 CHECK_CONNECTION(connection); … … 62 65 return async_req_2_0(connection->hc_phone, 63 66 DEV_IFACE_ID(USBHC_DEV_IFACE), 64 IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, full_speed);67 IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed); 65 68 } 66 69 … … 85 88 */ 86 89 usb_address_t usb_hc_request_address(usb_hc_connection_t *connection, 87 bool full_speed)90 usb_speed_t speed) 88 91 { 89 92 CHECK_CONNECTION(connection); … … 92 95 int rc = async_req_2_1(connection->hc_phone, 93 96 DEV_IFACE_ID(USBHC_DEV_IFACE), 94 IPC_M_USBHC_REQUEST_ADDRESS, full_speed,97 IPC_M_USBHC_REQUEST_ADDRESS, speed, 95 98 &address); 96 99 if (rc != EOK) { … … 138 141 139 142 143 /** Wrapper for registering attached device to the hub. 144 * 145 * The @p enable_port function is expected to enable singalling on given 146 * port. 147 * The two arguments to it can have arbitrary meaning 148 * (the @p port_no is only a suggestion) 149 * and are not touched at all by this function 150 * (they are passed as is to the @p enable_port function). 151 * 152 * If the @p enable_port fails (i.e. does not return EOK), the device 153 * addition is cancelled. 154 * The return value is then returned (it is good idea to use different 155 * error codes than those listed as return codes by this function itself). 156 * 157 * @param parent Parent device (i.e. the hub device). 158 * @param connection Opened connection to host controller. 159 * @param dev_speed New device speed. 160 * @param enable_port Function for enabling signalling through the port the 161 * device is attached to. 162 * @param port_no Port number (passed through to @p enable_port). 163 * @param arg Any data argument to @p enable_port. 164 * @param[out] assigned_address USB address of the device. 165 * @param[out] assigned_handle Devman handle of the new device. 166 * @return Error code. 167 * @retval ENOENT Connection to HC not opened. 168 * @retval EADDRNOTAVAIL Failed retrieving free address from host controller. 169 * @retval EBUSY Failed reserving default USB address. 170 * @retval ENOTCONN Problem connecting to the host controller via USB pipe. 171 * @retval ESTALL Problem communication with device (either SET_ADDRESS 172 * request or requests for descriptors when creating match ids). 173 */ 174 int usb_hc_new_device_wrapper(device_t *parent, usb_hc_connection_t *connection, 175 usb_speed_t dev_speed, 176 int (*enable_port)(int port_no, void *arg), int port_no, void *arg, 177 usb_address_t *assigned_address, devman_handle_t *assigned_handle) 178 { 179 CHECK_CONNECTION(connection); 180 181 /* 182 * Request new address. 183 */ 184 usb_address_t dev_addr = usb_hc_request_address(connection, dev_speed); 185 if (dev_addr < 0) { 186 return EADDRNOTAVAIL; 187 } 188 189 int rc; 190 191 /* 192 * Reserve the default address. 193 */ 194 rc = usb_hc_reserve_default_address(connection, dev_speed); 195 if (rc != EOK) { 196 rc = EBUSY; 197 goto leave_release_free_address; 198 } 199 200 /* 201 * Enable the port (i.e. allow signalling through this port). 202 */ 203 rc = enable_port(port_no, arg); 204 if (rc != EOK) { 205 goto leave_release_default_address; 206 } 207 208 /* 209 * Change the address from default to the free one. 210 * We need to create a new control pipe for that. 211 */ 212 usb_device_connection_t dev_conn; 213 rc = usb_device_connection_initialize_on_default_address(&dev_conn, 214 connection); 215 if (rc != EOK) { 216 rc = ENOTCONN; 217 goto leave_release_default_address; 218 } 219 220 usb_endpoint_pipe_t ctrl_pipe; 221 rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe, 222 &dev_conn); 223 if (rc != EOK) { 224 rc = ENOTCONN; 225 goto leave_release_default_address; 226 } 227 228 rc = usb_endpoint_pipe_start_session(&ctrl_pipe); 229 if (rc != EOK) { 230 rc = ENOTCONN; 231 goto leave_release_default_address; 232 } 233 234 rc = usb_request_set_address(&ctrl_pipe, dev_addr); 235 if (rc != EOK) { 236 rc = ESTALL; 237 goto leave_stop_session; 238 } 239 240 usb_endpoint_pipe_end_session(&ctrl_pipe); 241 242 /* 243 * Once the address is changed, we can return the default address. 244 */ 245 usb_hc_release_default_address(connection); 246 247 /* 248 * It is time to register the device with devman. 249 */ 250 /* FIXME: create device_register that will get opened ctrl pipe. */ 251 devman_handle_t child_handle; 252 rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle, 253 parent, &child_handle); 254 if (rc != EOK) { 255 rc = ESTALL; 256 goto leave_release_free_address; 257 } 258 259 /* 260 * And now inform the host controller about the handle. 261 */ 262 usb_hc_attached_device_t new_device = { 263 .address = dev_addr, 264 .handle = child_handle 265 }; 266 rc = usb_hc_register_device(connection, &new_device); 267 if (rc != EOK) { 268 rc = EDESTADDRREQ; 269 goto leave_release_free_address; 270 } 271 272 /* 273 * And we are done. 274 */ 275 if (assigned_address != NULL) { 276 *assigned_address = dev_addr; 277 } 278 if (assigned_handle != NULL) { 279 *assigned_handle = child_handle; 280 } 281 282 return EOK; 283 284 285 286 /* 287 * Error handling (like nested exceptions) starts here. 288 * Completely ignoring errors here. 289 */ 290 291 leave_stop_session: 292 usb_endpoint_pipe_end_session(&ctrl_pipe); 293 294 leave_release_default_address: 295 usb_hc_release_default_address(connection); 296 297 leave_release_free_address: 298 usb_hc_unregister_device(connection, dev_addr); 299 300 return rc; 301 } 302 303 140 304 /** 141 305 * @}
Note:
See TracChangeset
for help on using the changeset viewer.