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