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
i2c_fini(i2c_hdl_t * hdl)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 *
i2c_init(void)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
i2c_addr_reserved(const i2c_addr_t * addr)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
i2c_addr_validate(i2c_hdl_t * hdl,const i2c_addr_t * addr)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
i2c_name_validate(i2c_hdl_t * hdl,const char * name,const char * desc)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
i2c_node_type(di_node_t dn)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
i2c_node_minor_device(di_node_t dn)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
i2c_node_minor(di_node_t dn)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
i2c_node_is_type(di_node_t dn,i2c_node_type_t type)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
i2c_node_to_path(i2c_hdl_t * hdl,di_node_t dn,char * buf,size_t buflen)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
i2c_kernel_address_parse(i2c_hdl_t * hdl,const char * str,i2c_addr_t * addr)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
i2c_addr_parse(i2c_hdl_t * hdl,const char * buf,i2c_addr_t * addr)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
i2c_addr_to_string(i2c_hdl_t * hdl,const i2c_addr_t * addr,char * buf,size_t len)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
i2c_reg_to_addr(i2c_hdl_t * hdl,di_node_t dn,i2c_addr_t * addr,uint32_t n)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
i2c_addr_equal(const i2c_addr_t * a,const i2c_addr_t * b)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
i2c_path_find_ctrl(di_node_t root,const char * name)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
i2c_path_find_mux(di_node_t dev)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
i2c_path_find_port(di_node_t parent,const char * name)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
i2c_path_find_device(i2c_hdl_t * hdl,di_node_t port,const char * name)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
i2c_path_parse(i2c_hdl_t * hdl,const char * path,di_node_t root,di_node_t * dnp,i2c_node_type_t * typep,i2c_err_t err)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