Changes in uspace/lib/usb/src/dev.c [f9b2cb4c:b7fd2a0] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/dev.c
rf9b2cb4c rb7fd2a0 29 29 30 30 #include <usb/dev.h> 31 #include <usb/hc.h>32 31 #include <errno.h> 33 32 #include <usb_iface.h> 34 33 #include <str.h> 35 34 #include <stdio.h> 36 37 #define MAX_DEVICE_PATH 102438 39 /** Find host controller handle, address and iface number for the device.40 *41 * @param[in] device_handle Device devman handle.42 * @param[out] hc_handle Where to store handle of host controller43 * controlling device with @p device_handle handle.44 * @param[out] address Place to store the device's address45 * @param[out] iface Place to stoer the assigned USB interface number.46 * @return Error code.47 */48 int usb_get_info_by_handle(devman_handle_t device_handle,49 devman_handle_t *hc_handle, usb_address_t *address, int *iface)50 {51 async_sess_t *parent_sess =52 devman_parent_device_connect(device_handle, IPC_FLAG_BLOCKING);53 if (!parent_sess)54 return ENOMEM;55 56 async_exch_t *exch = async_exchange_begin(parent_sess);57 if (!exch) {58 async_hangup(parent_sess);59 return ENOMEM;60 }61 62 usb_address_t tmp_address;63 devman_handle_t tmp_handle;64 int tmp_iface;65 66 if (address) {67 const int ret = usb_get_my_address(exch, &tmp_address);68 if (ret != EOK) {69 async_exchange_end(exch);70 async_hangup(parent_sess);71 return ret;72 }73 }74 75 if (hc_handle) {76 const int ret = usb_get_hc_handle(exch, &tmp_handle);77 if (ret != EOK) {78 async_exchange_end(exch);79 async_hangup(parent_sess);80 return ret;81 }82 }83 84 if (iface) {85 const int ret = usb_get_my_interface(exch, &tmp_iface);86 switch (ret) {87 case ENOTSUP:88 /* Implementing GET_MY_INTERFACE is voluntary. */89 tmp_iface = -1;90 case EOK:91 break;92 default:93 async_exchange_end(exch);94 async_hangup(parent_sess);95 return ret;96 }97 }98 99 if (hc_handle)100 *hc_handle = tmp_handle;101 102 if (address)103 *address = tmp_address;104 105 if (iface)106 *iface = tmp_iface;107 108 async_exchange_end(exch);109 async_hangup(parent_sess);110 111 return EOK;112 }113 114 static bool try_parse_bus_and_address(const char *path,115 const char **func_start,116 devman_handle_t *out_hc_handle, usb_address_t *out_device_address)117 {118 uint64_t sid;119 size_t address;120 int rc;121 const char *ptr;122 123 rc = str_uint64_t(path, &ptr, 10, false, &sid);124 if (rc != EOK) {125 return false;126 }127 if ((*ptr == ':') || (*ptr == '.')) {128 ptr++;129 } else {130 return false;131 }132 rc = str_size_t(ptr, func_start, 10, false, &address);133 if (rc != EOK) {134 return false;135 }136 rc = usb_ddf_get_hc_handle_by_sid(sid, out_hc_handle);137 if (rc != EOK) {138 return false;139 }140 if (out_device_address != NULL) {141 *out_device_address = (usb_address_t) address;142 }143 return true;144 }145 146 static int get_device_handle_by_address(devman_handle_t hc_handle, int addr,147 devman_handle_t *dev_handle)148 {149 usb_hc_connection_t conn;150 usb_hc_connection_initialize(&conn, hc_handle);151 152 const int rc = usb_hc_get_handle_by_address(&conn, addr, dev_handle);153 154 return rc;155 }156 35 157 36 /** Resolve handle and address of USB device from its path. … … 174 53 * @return Error code. 175 54 */ 176 int usb_resolve_device_handle(const char *dev_path, devman_handle_t *out_hc_handle, 177 usb_address_t *out_dev_addr, devman_handle_t *out_dev_handle) 55 errno_t usb_resolve_device_handle(const char *dev_path, devman_handle_t *dev_handle) 178 56 { 179 if (dev_path == NULL ) {57 if (dev_path == NULL || dev_handle == NULL) { 180 58 return EBADMEM; 181 59 } 182 60 183 bool found_hc = false; 184 bool found_addr = false; 185 devman_handle_t hc_handle, dev_handle; 186 usb_address_t dev_addr = -1; 187 int rc; 188 bool is_bus_addr; 189 const char *func_start = NULL; 190 char *path = NULL; 61 /* First, try to get the device handle. */ 62 errno_t rc = devman_fun_get_handle(dev_path, dev_handle, 0); 191 63 192 /* First try the BUS.ADDR format. */ 193 is_bus_addr = try_parse_bus_and_address(dev_path, &func_start, 194 &hc_handle, &dev_addr); 195 if (is_bus_addr) { 196 found_hc = true; 197 found_addr = true; 198 /* 199 * Now get the handle of the device. We will need that 200 * in both cases. If there is only BUS.ADDR, it will 201 * be the handle to be returned to the caller, otherwise 202 * we will need it to resolve the path to which the 203 * suffix would be appended. 204 */ 205 /* If there is nothing behind the BUS.ADDR, we will 206 * get the device handle from the host controller. 207 * Otherwise, we will 208 */ 209 rc = get_device_handle_by_address(hc_handle, dev_addr, 210 &dev_handle); 211 if (rc != EOK) { 212 return rc; 213 } 214 if (str_length(func_start) > 0) { 215 char tmp_path[MAX_DEVICE_PATH]; 216 rc = devman_fun_get_path(dev_handle, 217 tmp_path, MAX_DEVICE_PATH); 218 if (rc != EOK) { 219 return rc; 220 } 221 rc = asprintf(&path, "%s%s", tmp_path, func_start); 222 if (rc < 0) { 223 return ENOMEM; 224 } 225 } else { 226 /* Everything is resolved. Get out of here. */ 227 goto copy_out; 228 } 229 } else { 230 path = str_dup(dev_path); 231 if (path == NULL) { 232 return ENOMEM; 233 } 64 /* Next, try parsing dev_handle from the provided string */ 65 if (rc != EOK) { 66 *dev_handle = strtoul(dev_path, NULL, 10); 67 //FIXME: check errno 68 rc = EOK; 234 69 } 235 236 /* First try to get the device handle. */ 237 rc = devman_fun_get_handle(path, &dev_handle, 0); 238 if (rc != EOK) { 239 free(path); 240 /* Invalid path altogether. */ 241 return rc; 242 } 243 244 /* Remove suffixes and hope that we will encounter device node. */ 245 while (str_length(path) > 0) { 246 /* Get device handle first. */ 247 devman_handle_t tmp_handle; 248 rc = devman_fun_get_handle(path, &tmp_handle, 0); 249 if (rc != EOK) { 250 free(path); 251 return rc; 252 } 253 254 /* Try to find its host controller. */ 255 if (!found_hc) { 256 rc = usb_get_hc_by_handle(tmp_handle, &hc_handle); 257 if (rc == EOK) { 258 found_hc = true; 259 } 260 } 261 262 /* Try to get its address. */ 263 if (!found_addr) { 264 rc = usb_get_address_by_handle(tmp_handle, &dev_addr); 265 if (rc == 0) { 266 found_addr = true; 267 } 268 } 269 270 /* Speed-up. */ 271 if (found_hc && found_addr) { 272 break; 273 } 274 275 /* Remove the last suffix. */ 276 char *slash_pos = str_rchr(path, '/'); 277 if (slash_pos != NULL) { 278 *slash_pos = 0; 279 } 280 } 281 282 free(path); 283 284 if (!found_addr || !found_hc) { 285 return ENOENT; 286 } 287 288 copy_out: 289 if (out_dev_addr != NULL) { 290 *out_dev_addr = dev_addr; 291 } 292 if (out_hc_handle != NULL) { 293 *out_hc_handle = hc_handle; 294 } 295 if (out_dev_handle != NULL) { 296 *out_dev_handle = dev_handle; 297 } 298 299 return EOK; 70 return rc; 300 71 }
Note:
See TracChangeset
for help on using the changeset viewer.