1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2025 Oxide Computer Company 14 */ 15 16 /* 17 * libi2c, a magical place that deals with everyone's favorite device class to 18 * hate. 19 */ 20 21 #include <stdlib.h> 22 #include <ctype.h> 23 #include <strings.h> 24 #include <sys/debug.h> 25 #include <sys/ilstr.h> 26 #include <fcntl.h> 27 #include <unistd.h> 28 #include <sys/obpdefs.h> 29 30 #include "libi2c_impl.h" 31 32 void 33 i2c_fini(i2c_hdl_t *hdl) 34 { 35 freelocale(hdl->ih_c_loc); 36 (void) close(hdl->ih_devfd); 37 free(hdl); 38 } 39 40 i2c_hdl_t * 41 i2c_init(void) 42 { 43 i2c_hdl_t *hdl; 44 45 hdl = calloc(1, sizeof (i2c_hdl_t)); 46 if (hdl == NULL) { 47 return (NULL); 48 } 49 50 hdl->ih_devfd = open("/devices", O_RDONLY | O_DIRECTORY); 51 if (hdl->ih_devfd < 0) { 52 free(hdl); 53 return (NULL); 54 } 55 56 hdl->ih_c_loc = newlocale(LC_ALL_MASK, "C", NULL); 57 return (hdl); 58 } 59 60 /* 61 * Provide a simple answer as to whether or not an address is a reserved 62 * address. This function is a bit awkward as invalid addresses are technically 63 * not reserved. 64 */ 65 bool 66 i2c_addr_reserved(const i2c_addr_t *addr) 67 { 68 switch (addr->ia_type) { 69 case I2C_ADDR_7BIT: 70 if (addr->ia_addr >= (1 << 7)) { 71 return (false); 72 } 73 break; 74 case I2C_ADDR_10BIT: 75 if (addr->ia_addr >= (1 << 10)) { 76 return (false); 77 } 78 break; 79 default: 80 return (false); 81 } 82 83 /* 84 * Because we've already done a size check up above we know illegal 85 * 7-bit addresses that are reserved 10-bit addresses will have already 86 * been checked. 87 */ 88 switch (addr->ia_addr) { 89 case I2C_RSVD_ADDR_GEN_CALL: 90 case I2C_RSVD_ADDR_C_BUS: 91 case I2C_RSVD_ADDR_DIFF_BUS: 92 case I2C_RSVD_ADDR_FUTURE: 93 case I2C_RSVD_ADDR_HS_0: 94 case I2C_RSVD_ADDR_HS_1: 95 case I2C_RSVD_ADDR_HS_2: 96 case I2C_RSVD_ADDR_HS_3: 97 case I2C_RSVD_ADDR_10B_0: 98 case I2C_RSVD_ADDR_10B_1: 99 case I2C_RSVD_ADDR_10B_2: 100 case I2C_RSVD_ADDR_10B_3: 101 case I2C_RSVD_ADDR_DID_0: 102 case I2C_RSVD_ADDR_DID_1: 103 case I2C_RSVD_ADDR_DID_2: 104 case I2C_RSVD_ADDR_DID_3: 105 return (true); 106 default: 107 return (false); 108 } 109 } 110 111 bool 112 i2c_addr_validate(i2c_hdl_t *hdl, const i2c_addr_t *addr) 113 { 114 uint16_t max; 115 116 if (addr == NULL) { 117 return (i2c_error(hdl, I2C_ERR_BAD_PTR, 0, "encountered " 118 "invalid i2c_addr_t pointer: %p", addr)); 119 } 120 121 switch (addr->ia_type) { 122 case I2C_ADDR_7BIT: 123 max = 1 << 7; 124 break; 125 case I2C_ADDR_10BIT: 126 max = 1 << 10; 127 break; 128 default: 129 return (i2c_error(hdl, I2C_ERR_BAD_ADDR_TYPE, 0, "invalid " 130 "address type family 0x%x", addr->ia_type)); 131 } 132 133 if (addr->ia_addr >= max) { 134 return (i2c_error(hdl, I2C_ERR_BAD_ADDR, 0, "address 0x%x is " 135 "outside the valid range for the address type: [0x00, " 136 "0x%02x]", addr->ia_addr, max - 1)); 137 } 138 139 return (true); 140 } 141 142 /* 143 * The set of valid characters for the 'name' and 'compatible' properties comes 144 * from IEEE 1275 (which was carried forward into device tree). A name must be 145 * at most 31 characters. It is allowed to contain lower case, upper case, 146 * numbers, and ",.+-_". We require the first character to be a letter. We check 147 * all of this against our copy of the C locale to ensure that a program in a 148 * different locale doesn't get a different answer. 149 */ 150 CTASSERT(I2C_NAME_MAX == OBP_MAXDRVNAME); 151 bool 152 i2c_name_validate(i2c_hdl_t *hdl, const char *name, const char *desc) 153 { 154 size_t len; 155 156 if (name == NULL) { 157 return (i2c_error(hdl, I2C_ERR_BAD_PTR, 0, "encountered " 158 "invalid %s pointer: %p", desc, name)); 159 } 160 161 len = strnlen(name, I2C_NAME_MAX); 162 if (len >= I2C_NAME_MAX) { 163 return (i2c_error(hdl, I2C_ERR_BAD_DEV_NAME, 0, "%s exceeds " 164 "%u character length limit, including NUL", desc, 165 I2C_NAME_MAX)); 166 } else if (len == 0) { 167 return (i2c_error(hdl, I2C_ERR_BAD_DEV_NAME, 0, "%s cannot " 168 "have zero length", desc)); 169 } 170 171 if (isalpha_l(name[0], hdl->ih_c_loc) == 0) { 172 return (i2c_error(hdl, I2C_ERR_BAD_DEV_NAME, 0, "%s must " 173 "have an ASCII upper or lowercase first letter: found 0x%x", 174 desc, name[0])); 175 } 176 177 for (size_t i = 1; i < len; i++) { 178 if (isalpha_l(name[i], hdl->ih_c_loc) || 179 isdigit_l(name[i], hdl->ih_c_loc)) { 180 continue; 181 } 182 183 if (name[i] == ',' || name[i] == '.' || name[i] == '+' || 184 name[i] == '-' || name[i] == '_') { 185 continue; 186 } 187 188 return (i2c_error(hdl, I2C_ERR_BAD_DEV_NAME, 0, "%s character " 189 "%zu is not from the valid set: found 0x%x", desc, i, 190 name[i])); 191 } 192 193 return (true); 194 } 195 196 i2c_node_type_t 197 i2c_node_type(di_node_t dn) 198 { 199 const char *drv = di_driver_name(dn); 200 char *strs; 201 int nstrs; 202 203 nstrs = di_prop_lookup_strings(DDI_DEV_T_ANY, dn, "device_type", 204 &strs); 205 if (nstrs == 1 && strcmp(strs, "i2c") == 0) { 206 return (I2C_NODE_T_DEV); 207 } 208 209 if (drv == NULL || strcmp(drv, I2C_NEX_DRV) != 0) { 210 return (I2C_NODE_T_OTHER); 211 } 212 213 nstrs = di_prop_lookup_strings(DDI_DEV_T_ANY, dn, I2C_NEXUS_TYPE_PROP, 214 &strs); 215 if (nstrs != 1) { 216 return (I2C_NODE_T_OTHER); 217 } 218 219 if (strcmp(strs, I2C_NEXUS_TYPE_PORT) == 0) { 220 return (I2C_NODE_T_PORT); 221 } else if (strcmp(strs, I2C_NEXUS_TYPE_CTRL) == 0) { 222 return (I2C_NODE_T_CTRL); 223 } else if (strcmp(strs, I2C_NEXUS_TYPE_MUX) == 0) { 224 return (I2C_NODE_T_MUX); 225 } 226 227 return (I2C_NODE_T_OTHER); 228 } 229 230 /* 231 * Given a device node, find the corresponding minor node in its parent port. 232 * This node will be named after the kernel form of the device, which is going 233 * to be the type,addr aka reg[0],reg[1]. 234 */ 235 static di_minor_t 236 i2c_node_minor_device(di_node_t dn) 237 { 238 int nreg, *reg; 239 char name[32]; 240 241 nreg = di_prop_lookup_ints(DDI_DEV_T_ANY, dn, "reg", ®); 242 if (nreg == 0 || (nreg % 2) != 0) { 243 return (DI_MINOR_NIL); 244 } 245 246 (void) snprintf(name, sizeof (name), "%x,%x", reg[0], reg[1]); 247 dn = di_parent_node(dn); 248 if (i2c_node_type(dn) != I2C_NODE_T_PORT) { 249 return (DI_MINOR_NIL); 250 } 251 252 for (di_minor_t m = di_minor_next(dn, DI_MINOR_NIL); m != DI_MINOR_NIL; 253 m = di_minor_next(dn, m)) { 254 if (strcmp(di_minor_nodetype(m), DDI_NT_I2C_DEV) == 0 && 255 strcmp(di_minor_name(m), name) == 0) { 256 return (m); 257 } 258 } 259 260 return (DI_MINOR_NIL); 261 } 262 263 di_minor_t 264 i2c_node_minor(di_node_t dn) 265 { 266 const char *nt; 267 i2c_node_type_t type = i2c_node_type(dn); 268 269 switch (type) { 270 case I2C_NODE_T_CTRL: 271 nt = DDI_NT_I2C_CTRL; 272 break; 273 case I2C_NODE_T_PORT: 274 nt = DDI_NT_I2C_PORT; 275 break; 276 case I2C_NODE_T_MUX: 277 nt = DDI_NT_I2C_MUX; 278 break; 279 /* 280 * Device's don't have their control minor under them. The parent port 281 * has it, so when we need that, change this around to go search the 282 * parent for it. 283 */ 284 case I2C_NODE_T_DEV: 285 return (i2c_node_minor_device(dn)); 286 default: 287 return (DI_MINOR_NIL); 288 } 289 290 for (di_minor_t m = di_minor_next(dn, DI_MINOR_NIL); m != DI_MINOR_NIL; 291 m = di_minor_next(dn, m)) { 292 if (strcmp(di_minor_nodetype(m), nt) == 0) { 293 return (m); 294 } 295 } 296 297 return (DI_MINOR_NIL); 298 } 299 300 bool 301 i2c_node_is_type(di_node_t dn, i2c_node_type_t type) 302 { 303 return (i2c_node_type(dn) == type); 304 } 305 306 307 /* 308 * This constructs the named i2c path that can be used to get to the node dn 309 * through a series of '/' delineated pieces. The canonical name to use varies 310 * based on the node type and stop once we hit a controller: 311 * 312 * - controllers: controller name in the di_node_t address 313 * - ports: port name in the di_node_t address 314 * - devices: primary i2c address 315 */ 316 bool 317 i2c_node_to_path(i2c_hdl_t *hdl, di_node_t dn, char *buf, size_t buflen) 318 { 319 ilstr_t ils; 320 bool first = true; 321 i2c_addr_t addr; 322 char addrstr[32]; 323 324 ilstr_init_prealloc(&ils, buf, buflen); 325 326 for (;;) { 327 i2c_node_type_t type = i2c_node_type(dn); 328 329 switch (type) { 330 case I2C_NODE_T_CTRL: 331 case I2C_NODE_T_PORT: 332 if (!first) { 333 ilstr_prepend_str(&ils, "/"); 334 } 335 ilstr_prepend_str(&ils, di_bus_addr(dn)); 336 first = false; 337 break; 338 case I2C_NODE_T_MUX: 339 /* 340 * The i2cnex that represents a mux today is not used in 341 * the logical path that we use with humans. 342 */ 343 break; 344 case I2C_NODE_T_DEV: 345 if (!first) { 346 ilstr_prepend_str(&ils, "/"); 347 } 348 349 /* 350 * While it is tempting to use the bus address here, we 351 * cannot actually assume that a device address is 352 * valid. A device will only be addressed on the bus if 353 * a driver is attached to it. 354 * 355 * Therefore a device is identified with the primary 356 * address that it has, e.g. regs[0]. We use the 357 * somewhat more user firendly form of the address where 358 * 10-bit addresses have the leading '1,' to indicate 359 * the class, but 7-bit do not. As in practice that's 360 * what we'll be dealing with 99% of the time. 361 */ 362 if (!i2c_reg_to_addr(hdl, dn, &addr, 0)) { 363 return (false); 364 } 365 366 VERIFY(i2c_addr_to_string(hdl, &addr, addrstr, 367 sizeof (addrstr))); 368 ilstr_prepend_str(&ils, addrstr); 369 first = false; 370 break; 371 default: 372 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, 373 "encountered unknown node type constructing path: " 374 "0x%x", type)); 375 } 376 377 /* 378 * If we've hit a controller we're done. However, look out in 379 * case we haven't and make sure we have a parent before 380 * continuing. 381 */ 382 if (type == I2C_NODE_T_CTRL) 383 break; 384 385 dn = di_parent_node(dn); 386 if (dn == DI_NODE_NIL) 387 break; 388 } 389 390 if (ilstr_errno(&ils) != ILSTR_ERROR_OK) { 391 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, "failed to " 392 "construct string for node %s: %s", di_node_name(dn), 393 ilstr_errstr(&ils))); 394 } 395 396 return (true); 397 } 398 399 /* 400 * Parse the kernel's I2C device address style, <type>,<address>. The only 401 * thing assumed about str is that it is null terminated. The kernel integers 402 * for type and address are always in hex regardless of whether or not they 403 * have a leading 0x. 404 */ 405 bool 406 i2c_kernel_address_parse(i2c_hdl_t *hdl, const char *str, i2c_addr_t *addr) 407 { 408 char *eptr; 409 unsigned long ul; 410 411 errno = 0; 412 ul = strtoul(str, &eptr, 16); 413 if (errno != 0 || *eptr != ',') { 414 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, "kernel string %s " 415 "did not have a valid leading type", str)); 416 } 417 418 if (ul == I2C_ADDR_7BIT) { 419 addr->ia_type = I2C_ADDR_7BIT; 420 } else if (ul == I2C_ADDR_10BIT) { 421 addr->ia_type = I2C_ADDR_10BIT; 422 } else { 423 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, "kernel string %s " 424 "did not have a valid type, found 0x%lx", str, ul)); 425 } 426 427 errno = 0; 428 ul = strtoul(eptr + 1, &eptr, 16); 429 if (errno != 0 || *eptr != '\0') { 430 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, "kernel string %s " 431 "did not have a valid address", str)); 432 } 433 434 if ((addr->ia_type == I2C_ADDR_7BIT && ul >= 1 << 7) || 435 (addr->ia_type == I2C_ADDR_10BIT && ul >= 1 << 10)) { 436 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, "kernel string %s " 437 "address 0x%lx is too large for type", str, ul)); 438 } 439 440 addr->ia_addr = (uint16_t)ul; 441 return (true); 442 } 443 444 /* 445 * Parse a user address as compared to a kernel address. The main difference 446 * here is that the user address does not use a prefix for the 7-bit addresses 447 * and the 10-bit addresses use the "10b," prefix. 448 */ 449 bool 450 i2c_addr_parse(i2c_hdl_t *hdl, const char *buf, i2c_addr_t *addr) 451 { 452 char *eptr; 453 unsigned long ul; 454 const char *comma; 455 uint16_t max; 456 457 if (buf == NULL) { 458 return (i2c_error(hdl, I2C_ERR_BAD_PTR, 0, "encountered " 459 "invalid address string pointer: %p", buf)); 460 } 461 462 if (addr == NULL) { 463 return (i2c_error(hdl, I2C_ERR_BAD_PTR, 0, "encountered " 464 "invalid i2c_addr_t pointer: %p", addr)); 465 } 466 467 comma = strchr(buf, ','); 468 if (comma != NULL) { 469 size_t len = (uintptr_t)comma - (uintptr_t)buf; 470 if (len != 3 || strncmp("10b", buf, len) != 0) { 471 return (i2c_error(hdl, I2C_ERR_BAD_ADDR_TYPE, 0, 472 "found invalid address type on %s", buf)); 473 } 474 addr->ia_type = I2C_ADDR_10BIT; 475 buf = comma + 1; 476 max = 1 << 10; 477 } else { 478 addr->ia_type = I2C_ADDR_7BIT; 479 max = 1 << 7; 480 } 481 482 errno = 0; 483 ul = strtoul(buf, &eptr, 0); 484 if (errno != 0 || *eptr != '\0') { 485 return (i2c_error(hdl, I2C_ERR_BAD_ADDR, 0, "address %s could " 486 "not be parsed", buf)); 487 } 488 489 if (ul >= max) { 490 return (i2c_error(hdl, I2C_ERR_BAD_ADDR, 0, "address 0x%lx is " 491 "outside the valid range for the address type: [0x00, " 492 "0x%02x]", ul, max - 1)); 493 } 494 495 addr->ia_addr = (uint16_t)ul; 496 return (true); 497 } 498 499 bool 500 i2c_addr_to_string(i2c_hdl_t *hdl, const i2c_addr_t *addr, char *buf, 501 size_t len) 502 { 503 size_t ret; 504 505 if (buf == NULL) { 506 return (i2c_error(hdl, I2C_ERR_BAD_PTR, 0, "encountered " 507 "invalid address string pointer: %p", buf)); 508 } 509 510 if (addr == NULL) { 511 return (i2c_error(hdl, I2C_ERR_BAD_PTR, 0, "encountered " 512 "invalid i2c_addr_t pointer: %p", addr)); 513 } 514 515 if (!i2c_addr_validate(hdl, addr)) { 516 return (false); 517 } 518 519 if (addr->ia_type == I2C_ADDR_10BIT) { 520 ret = snprintf(buf, len, "10b,0x%03x", addr->ia_addr); 521 } else { 522 ret = snprintf(buf, len, "0x%02x", addr->ia_addr); 523 } 524 if (ret >= len) { 525 return (i2c_error(hdl, I2C_ERR_BUF_TOO_SMALL, 0, "output " 526 "buffer is too small: need %zu bytes, have %zu", ret, 527 len)); 528 } 529 530 return (true); 531 } 532 533 /* 534 * Convert the specified index for a device into an address. 535 */ 536 bool 537 i2c_reg_to_addr(i2c_hdl_t *hdl, di_node_t dn, i2c_addr_t *addr, uint32_t n) 538 { 539 int nreg, *reg; 540 uint32_t type_idx = n * 2; 541 uint32_t addr_idx = n * 2 + 1; 542 543 nreg = di_prop_lookup_ints(DDI_DEV_T_ANY, dn, "reg", ®); 544 if (nreg == 0 || (nreg % 2) != 0) { 545 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, "device %s@%s " 546 "does not have a valid i2c reg[] property", 547 di_node_name(dn), di_bus_addr(dn))); 548 } 549 550 if (addr_idx >= nreg) { 551 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, "device %s@%s " 552 "does not have a valid i2c reg[] property", 553 di_node_name(dn), di_bus_addr(dn))); 554 } 555 556 if (reg[type_idx] == I2C_ADDR_7BIT) { 557 addr->ia_type = I2C_ADDR_7BIT; 558 } else if (reg[type_idx] == I2C_ADDR_10BIT) { 559 addr->ia_type = I2C_ADDR_10BIT; 560 } else { 561 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, "device %s@%s " 562 "does not have a valid i2c address type, found 0x%x", 563 di_node_name(dn), di_bus_addr(dn), reg[type_idx])); 564 } 565 566 if ((addr->ia_type == I2C_ADDR_7BIT && reg[addr_idx] >= 1 << 7) || 567 (addr->ia_type == I2C_ADDR_10BIT && reg[addr_idx] >= 1 << 10)) { 568 return (i2c_error(hdl, I2C_ERR_INTERNAL, 0, "device %s@%s " 569 "address 0x%x is too large for type", di_node_name(dn), 570 di_bus_addr(dn), reg[addr_idx])); 571 } 572 573 addr->ia_addr = (uint16_t)reg[1]; 574 575 return (true); 576 } 577 578 bool 579 i2c_addr_equal(const i2c_addr_t *a, const i2c_addr_t *b) 580 { 581 return (a->ia_type == b->ia_type && a->ia_addr == b->ia_addr); 582 } 583 584 di_node_t 585 i2c_path_find_ctrl(di_node_t root, const char *name) 586 { 587 for (di_node_t di = di_drv_first_node(I2C_NEX_DRV, root); di != NULL; 588 di = di_drv_next_node(di)) { 589 if (!i2c_node_is_type(di, I2C_NODE_T_CTRL)) { 590 continue; 591 } 592 593 if (strcmp(name, di_bus_addr(di)) == 0) { 594 return (di); 595 } 596 } 597 598 return (DI_NODE_NIL); 599 } 600 601 di_node_t 602 i2c_path_find_mux(di_node_t dev) 603 { 604 for (di_node_t dn = di_child_node(dev); dn != NULL; 605 dn = di_sibling_node(dn)) { 606 if (i2c_node_type(dn) == I2C_NODE_T_MUX) { 607 return (dn); 608 } 609 } 610 611 return (DI_NODE_NIL); 612 } 613 614 di_node_t 615 i2c_path_find_port(di_node_t parent, const char *name) 616 { 617 for (di_node_t dn = di_child_node(parent); dn != NULL; 618 dn = di_sibling_node(dn)) { 619 if (!i2c_node_is_type(dn, I2C_NODE_T_PORT)) { 620 continue; 621 } 622 623 if (strcmp(di_bus_addr(dn), name) == 0) { 624 return (dn); 625 } 626 } 627 628 return (DI_NODE_NIL); 629 } 630 631 /* 632 * When parsing a device, there are three different options that we accept: 633 * 634 * - The device's name@address 635 * - The device's address 636 * - The device's driver and instance (e.g. spd511x2) 637 * 638 * The address is always reg[0] because the aactual node address may not exist 639 * at this time. Similarly, we cannot assume that a driver is bound and attached 640 * to the node. 641 */ 642 di_node_t 643 i2c_path_find_device(i2c_hdl_t *hdl, di_node_t port, const char *name) 644 { 645 for (di_node_t dn = di_child_node(port); dn != NULL; 646 dn = di_sibling_node(dn)) { 647 i2c_addr_t daddr; 648 char daddrstr[32]; 649 650 if (i2c_node_type(dn) != I2C_NODE_T_DEV) { 651 continue; 652 } 653 654 if (!i2c_reg_to_addr(hdl, dn, &daddr, 0)) { 655 continue; 656 } 657 658 if (!i2c_addr_to_string(hdl, &daddr, daddrstr, 659 sizeof (daddrstr))) { 660 continue; 661 } 662 663 /* 664 * Always check if we match on the converted address. 665 */ 666 if (strcmp(name, daddrstr) == 0) { 667 return (dn); 668 } 669 670 /* 671 * We didn't match on that, is there a driver? 672 */ 673 if (di_driver_name(dn) != NULL && di_instance(dn) != -1) { 674 char buf[128]; 675 676 (void) snprintf(buf, sizeof (buf), "%s%d", 677 di_driver_name(dn), di_instance(dn)); 678 if (strcmp(name, buf) == 0) { 679 return (dn); 680 } 681 } 682 683 /* 684 * Finally check if we match name@addr. Only do this if we have 685 * an actual @ in the user bit. 686 */ 687 const char *at = strchr(name, '@'); 688 if (at != NULL) { 689 char buf[128]; 690 691 (void) snprintf(buf, sizeof (buf), "%s@%s", 692 di_node_name(dn), daddrstr); 693 if (strcmp(name, buf) == 0) { 694 return (dn); 695 } 696 } 697 } 698 699 return (DI_NODE_NIL); 700 } 701 702 bool 703 i2c_path_parse(i2c_hdl_t *hdl, const char *path, di_node_t root, di_node_t *dnp, 704 i2c_node_type_t *typep, i2c_err_t err) 705 { 706 di_node_t cur_devi; 707 char *dup, *state; 708 i2c_node_type_t cur; 709 bool ret = false; 710 711 if (path == NULL) { 712 return (i2c_error(hdl, I2C_ERR_BAD_PTR, 0, "encountered " 713 "invalid I2C path pointer: %p", path)); 714 } 715 716 dup = strdup(path); 717 if (dup == NULL) { 718 int e = errno; 719 return (i2c_error(hdl, I2C_ERR_NO_MEM, e, "failed to duplicate " 720 "I2C path")); 721 } 722 723 cur = I2C_NODE_T_OTHER; 724 cur_devi = NULL; 725 for (const char *ent = strtok_r(dup, "/", &state); ent != NULL; 726 ent = strtok_r(NULL, "/", &state)) { 727 switch (cur) { 728 case I2C_NODE_T_OTHER: 729 /* 730 * This is our top-level state. We need to find a 731 * controller that matches this name. 732 */ 733 cur_devi = i2c_path_find_ctrl(root, ent); 734 if (cur_devi == DI_NODE_NIL) { 735 (void) i2c_error(hdl, err, 0, 736 "failed to find controller %s as part of " 737 "parsing I2C path %s", ent, path); 738 goto err; 739 } 740 cur = I2C_NODE_T_CTRL; 741 break; 742 case I2C_NODE_T_DEV: 743 /* 744 * Today we expect a device to only ever have a single 745 * node under it which is a mux. We walk all the 746 * children and look for this. This is because muxes 747 * aren't named. It's possible someone has created more 748 * than one node, so that's why we don't just go 749 * directly. After we do this, we explicitly fall 750 * through to the controller handling logic, as it has 751 * to do the same class. 752 */ 753 cur_devi = i2c_path_find_mux(cur_devi); 754 if (cur_devi == DI_NODE_NIL) { 755 (void) i2c_error(hdl, err, 0, 756 "failed to find mux %s as part of " 757 "parsing I2C path %s", ent, path); 758 goto err; 759 } 760 /* FALLTHROUGH */ 761 case I2C_NODE_T_CTRL: 762 cur_devi = i2c_path_find_port(cur_devi, ent); 763 if (cur_devi == DI_NODE_NIL) { 764 (void) i2c_error(hdl, err, 0, 765 "failed to find port %s as part of " 766 "parsing I2C path %s", ent, path); 767 goto err; 768 } 769 cur = I2C_NODE_T_PORT; 770 break; 771 case I2C_NODE_T_PORT: 772 cur_devi = i2c_path_find_device(hdl, cur_devi, ent); 773 if (cur_devi == DI_NODE_NIL) { 774 (void) i2c_error(hdl, err, 0, 775 "failed to find device %s as part of " 776 "parsing I2C path %s", ent, path); 777 goto err; 778 } 779 cur = I2C_NODE_T_DEV; 780 break; 781 default: 782 abort(); 783 } 784 } 785 786 *dnp = cur_devi; 787 *typep = cur; 788 ret = true; 789 790 err: 791 free(dup); 792 return (ret); 793 } 794