1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /*
26 * Instance number assignment code
27 */
28
29 #include <sys/types.h>
30 #include <sys/param.h>
31 #include <sys/errno.h>
32 #include <sys/systm.h>
33 #include <sys/kobj.h>
34 #include <sys/t_lock.h>
35 #include <sys/kmem.h>
36 #include <sys/cmn_err.h>
37 #include <sys/ddi.h>
38 #include <sys/sunddi.h>
39 #include <sys/autoconf.h>
40 #include <sys/systeminfo.h>
41 #include <sys/hwconf.h>
42 #include <sys/reboot.h>
43 #include <sys/ddi_impldefs.h>
44 #include <sys/instance.h>
45 #include <sys/debug.h>
46 #include <sys/sysevent.h>
47 #include <sys/modctl.h>
48 #include <sys/console.h>
49 #include <sys/cladm.h>
50 #include <sys/sysmacros.h>
51 #include <sys/crc32.h>
52
53
54 static void in_preassign_instance(void);
55 static void i_log_devfs_instance_mod(void);
56 static int in_get_infile(char *);
57 static void in_removenode(struct devnames *dnp, in_node_t *mp, in_node_t *ap);
58 static in_node_t *in_alloc_node(char *name, char *addr);
59 static int in_eqstr(char *a, char *b);
60 static char *in_name_addr(char **cpp, char **addrp);
61 static in_node_t *in_devwalk(dev_info_t *dip, in_node_t **ap, char *addr);
62 static void in_dealloc_node(in_node_t *np);
63 static in_node_t *in_make_path(char *path);
64 static void in_enlist(in_node_t *ap, in_node_t *np);
65 static int in_inuse(int instance, char *name);
66 static void in_hashdrv(in_drv_t *dp);
67 static in_drv_t *in_drvwalk(in_node_t *np, char *binding_name);
68 static in_drv_t *in_alloc_drv(char *bindingname);
69 static void in_endrv(in_node_t *np, in_drv_t *dp);
70 static void in_dq_drv(in_drv_t *np);
71 static void in_removedrv(struct devnames *dnp, in_drv_t *mp);
72 static int in_pathin(char *cp, int instance, char *bname, struct bind **args);
73 static int in_next_instance_block(major_t, int);
74 static int in_next_instance(major_t);
75
76 #pragma weak plat_ioaliases_init
77
78
79 /* external functions */
80 extern char *i_binding_to_drv_name(char *bname);
81 extern void plat_ioaliases_init(void);
82
83 /*
84 * This plus devnames defines the entire software state of the instance world.
85 */
86 typedef struct in_softstate {
87 in_node_t *ins_root; /* the root of our instance tree */
88 in_drv_t *ins_no_major; /* majorless drv entries */
89 /*
90 * Used to serialize access to data structures
91 */
92 void *ins_thread;
93 kmutex_t ins_serial;
94 kcondvar_t ins_serial_cv;
95 int ins_busy;
96 boolean_t ins_dirty; /* instance info needs flush */
97 } in_softstate_t;
98
99 static in_softstate_t e_ddi_inst_state;
100
101 /*
102 * State transition information:
103 * e_ddi_inst_state contains, among other things, the root of a tree of
104 * device nodes used to track instance number assignments.
105 * Each device node may contain multiple driver bindings, represented
106 * by a linked list of in_drv_t nodes, each with an instance assignment
107 * (except for root node). Each in_drv node can be in one of 3 states,
108 * indicated by ind_state:
109 *
110 * IN_UNKNOWN: Each node created in this state. The instance number of
111 * this node is not known. ind_instance is set to -1.
112 * IN_PROVISIONAL: When a node is assigned an instance number in
113 * e_ddi_assign_instance(), its state is set to IN_PROVISIONAL.
114 * Subsequently, the framework will always call either
115 * e_ddi_keep_instance() which makes the node IN_PERMANENT
116 * or e_ddi_free_instance(), which deletes the node.
117 * IN_PERMANENT:
118 * If e_ddi_keep_instance() is called on an IN_PROVISIONAL node,
119 * its state is set to IN_PERMANENT.
120 */
121
122 static char *instance_file = INSTANCE_FILE;
123 static char *instance_file_backup = INSTANCE_FILE INSTANCE_FILE_SUFFIX;
124
125 /*
126 * Return values for in_get_infile().
127 */
128 #define PTI_FOUND 0
129 #define PTI_NOT_FOUND 1
130 #define PTI_REBUILD 2
131
132 int instance_searchme = 0; /* testing: use complex code path */
133
134 /*
135 * Path to instance file magic string used for first time boot after
136 * an install. If this is the first string in the file we will
137 * automatically rebuild the file.
138 */
139 #define PTI_MAGIC_STR "#path_to_inst_bootstrap_1"
140 #define PTI_MAGIC_STR_LEN (sizeof (PTI_MAGIC_STR) - 1)
141
142 void
e_ddi_instance_init(void)143 e_ddi_instance_init(void)
144 {
145 char *file;
146 int rebuild = 1;
147 struct in_drv *dp;
148
149 mutex_init(&e_ddi_inst_state.ins_serial, NULL, MUTEX_DEFAULT, NULL);
150 cv_init(&e_ddi_inst_state.ins_serial_cv, NULL, CV_DEFAULT, NULL);
151
152 /*
153 * Only one thread is allowed to change the state of the instance
154 * number assignments on the system at any given time.
155 * Note that this is not really necessary, as we are single-threaded
156 * here, but it won't hurt, and it allows us to keep ASSERTS for
157 * our assumptions in the code.
158 */
159 e_ddi_enter_instance();
160
161 /*
162 * Init the ioaliases if the platform supports it
163 */
164 if (&plat_ioaliases_init)
165 plat_ioaliases_init();
166
167 /*
168 * Create the root node, instance zallocs to 0.
169 * The name and address of this node never get examined, we always
170 * start searching with its first child.
171 */
172 ASSERT(e_ddi_inst_state.ins_root == NULL);
173 e_ddi_inst_state.ins_root = in_alloc_node(NULL, NULL);
174 dp = in_alloc_drv("rootnex");
175 in_endrv(e_ddi_inst_state.ins_root, dp);
176
177 file = instance_file;
178 switch (in_get_infile(file)) {
179 default:
180 case PTI_NOT_FOUND:
181 /* make sure path_to_inst is recreated */
182 boothowto |= RB_RECONFIG;
183
184 /*
185 * Something is wrong. First try the backup file.
186 * If not found, rebuild path_to_inst. Emit a
187 * message about the problem.
188 */
189 cmn_err(CE_WARN, "%s empty or not found", file);
190
191 file = instance_file_backup;
192 if (in_get_infile(file) != PTI_FOUND) {
193 cmn_err(CE_NOTE, "rebuilding device instance data");
194 break;
195 }
196 cmn_err(CE_NOTE, "using backup instance data in %s", file);
197 /*FALLTHROUGH*/
198
199 case PTI_FOUND:
200 /*
201 * We've got a readable file
202 * parse the file into the instance tree
203 */
204 (void) read_binding_file(file, NULL, in_pathin);
205 rebuild = 0;
206 break;
207
208 case PTI_REBUILD:
209 /*
210 * path_to_inst has magic str requesting a create
211 * Convert boot to reconfig boot to ensure /dev is
212 * in sync with new path_to_inst.
213 */
214 boothowto |= RB_RECONFIG;
215 cmn_err(CE_CONT,
216 "?Using default device instance data\n");
217 break;
218 }
219
220 /*
221 * The OBP device tree has been copied to the kernel and
222 * bound to drivers at this point. We walk the per-driver
223 * list to preassign instances. Since the bus addr is
224 * unknown at this point, we cannot place the instance
225 * number in the instance tree. This will be done at
226 * a later time.
227 */
228 if (rebuild)
229 in_preassign_instance();
230
231 e_ddi_exit_instance();
232 }
233
234 static void
in_preassign_instance()235 in_preassign_instance()
236 {
237 major_t m;
238 struct devnames *dnp;
239 dev_info_t *dip;
240 extern major_t devcnt;
241
242 for (m = 0; m < devcnt; m++) {
243 dnp = &devnamesp[m];
244 dip = dnp->dn_head;
245 while (dip) {
246 DEVI(dip)->devi_instance = dnp->dn_instance;
247 dnp->dn_instance++;
248 dip = ddi_get_next(dip);
249 }
250
251 /*
252 * The preassign instance numbers are not fully
253 * accounted for until e_ddi_assign_instance().
254 * We can't fully account for them now because we
255 * don't currently have a unit-address. Because of
256 * this, we need to remember the preassign boundary
257 * to avoid ordering issues related to
258 * e_ddi_assign_instance of a preassigned value .vs.
259 * re-assignment of the same value for a dynamic
260 * SID node created by bus_config.
261 */
262 dnp->dn_pinstance = dnp->dn_instance;
263 dnp->dn_instance = IN_SEARCHME;
264 }
265 }
266
267 /*
268 * Checks to see if the /etc/path_to_inst file exists and whether or not
269 * it has the magic string in it.
270 *
271 * Returns one of the following:
272 *
273 * PTI_FOUND - We have found the /etc/path_to_inst file
274 * PTI_REBUILD - We have found the /etc/path_to_inst file and the
275 * first line was PTI_MAGIC_STR.
276 * PTI_NOT_FOUND - We did not find the /etc/path_to_inst file
277 *
278 */
279 static int
in_get_infile(char * filename)280 in_get_infile(char *filename)
281 {
282 struct _buf *file;
283 int return_val;
284 char buf[PTI_MAGIC_STR_LEN];
285
286 /*
287 * Try to open the file.
288 */
289 if ((file = kobj_open_file(filename)) == (struct _buf *)-1) {
290 return (PTI_NOT_FOUND);
291 }
292 return_val = PTI_FOUND;
293
294 /*
295 * Read the first PTI_MAGIC_STR_LEN bytes from the file to see if
296 * it contains the magic string. If there aren't that many bytes
297 * in the file, then assume file is correct and no magic string
298 * and move on.
299 */
300 switch (kobj_read_file(file, buf, PTI_MAGIC_STR_LEN, 0)) {
301
302 case PTI_MAGIC_STR_LEN:
303 /*
304 * If the first PTI_MAGIC_STR_LEN bytes are the magic string
305 * then return PTI_REBUILD.
306 */
307 if (strncmp(PTI_MAGIC_STR, buf, PTI_MAGIC_STR_LEN) == 0)
308 return_val = PTI_REBUILD;
309 break;
310
311 case 0:
312 /*
313 * If the file is zero bytes in length, then consider the
314 * file to not be found
315 */
316 return_val = PTI_NOT_FOUND;
317
318 default: /* Do nothing we have a good file */
319 break;
320 }
321
322 kobj_close_file(file);
323 return (return_val);
324 }
325
326 int
is_pseudo_device(dev_info_t * dip)327 is_pseudo_device(dev_info_t *dip)
328 {
329 dev_info_t *pdip;
330
331 for (pdip = ddi_get_parent(dip); pdip && pdip != ddi_root_node();
332 pdip = ddi_get_parent(pdip)) {
333 if (strcmp(ddi_get_name(pdip), DEVI_PSEUDO_NEXNAME) == 0)
334 return (1);
335 }
336 return (0);
337 }
338
339
340 static void
in_set_instance(dev_info_t * dip,in_drv_t * dp,major_t major)341 in_set_instance(dev_info_t *dip, in_drv_t *dp, major_t major)
342 {
343 /* use preassigned instance if available */
344 if (DEVI(dip)->devi_instance != -1)
345 dp->ind_instance = DEVI(dip)->devi_instance;
346 else
347 dp->ind_instance = in_next_instance(major);
348 }
349
350 /*
351 * Return 1 if instance block was assigned for the path.
352 *
353 * For multi-port NIC cards, sequential instance assignment across all
354 * ports on a card is highly desirable since the ppa is typically the
355 * same as the instance number, and the ppa is used in the NIC's public
356 * /dev name. This sequential assignment typically occurs as a result
357 * of in_preassign_instance() after initial install, or by
358 * i_ndi_init_hw_children() for NIC ports that share a common parent.
359 *
360 * Some NIC cards however use multi-function bridge chips, and to
361 * support sequential instance assignment accross all ports, without
362 * disabling multi-threaded attach, we have a (currently) undocumented
363 * hack to allocate instance numbers in contiguous blocks based on
364 * driver.conf properties.
365 *
366 * ^
367 * /---------- ------------\
368 * pci@0 pci@0,1 MULTI-FUNCTION BRIDGE CHIP
369 * / \ / \
370 * FJSV,e4ta@4 FJSV,e4ta@4,1 FJSV,e4ta@6 FJSV,e4ta@6,1 NIC PORTS
371 * n n+2 n+2 n+3 INSTANCE
372 *
373 * For the above example, the following driver.conf properties would be
374 * used to guarantee sequential instance number assignment.
375 *
376 * ddi-instance-blocks ="ib-FJSVe4ca", "ib-FJSVe4ta", "ib-generic";
377 * ib-FJSVe4ca = "/pci@0/FJSV,e4ca@4", "/pci@0/FJSV,e4ca@4,1",
378 * "/pci@0,1/FJSV,e4ca@6", "/pci@0,1/FJSV,e4ca@6,1";
379 * ib-FJSVe4ta = "/pci@0/FJSV,e4ta@4", "/pci@0/FJSV,e4ta@4,1",
380 * "/pci@0,1/FJSV,e4ta@6", "/pci@0,1/FJSV,e4ta@6,1";
381 * ib-generic = "/pci@0/network@4", "/pci@0/network@4,1",
382 * "/pci@0,1/network@6", "/pci@0,1/network@6,1";
383 *
384 * The value of the 'ddi-instance-blocks' property references a series
385 * of card specific properties, like 'ib-FJSV-e4ta', who's value
386 * defines a single 'instance block'. The 'instance block' describes
387 * all the paths below a multi-function bridge, where each path is
388 * called an 'instance path'. The 'instance block' property value is a
389 * series of 'instance paths'. The number of 'instance paths' in an
390 * 'instance block' defines the size of the instance block, and the
391 * ordering of the 'instance paths' defines the instance number
392 * assignment order for paths going through the 'instance block'.
393 *
394 * In the instance assignment code below, if a (path, driver) that
395 * currently has no instance number has a path that goes through an
396 * 'instance block', then block instance number allocation occurs. The
397 * block allocation code will find a sequential set of unused instance
398 * numbers, and assign instance numbers for all the paths in the
399 * 'instance block'. Each path is assigned a persistent instance
400 * number, even paths that don't exist in the device tree or fail
401 * probe(9E).
402 */
403 static int
in_assign_instance_block(dev_info_t * dip)404 in_assign_instance_block(dev_info_t *dip)
405 {
406 char **ibn; /* instance block names */
407 uint_t nibn; /* number of instance block names */
408 uint_t ibni; /* ibn index */
409 char *driver;
410 major_t major;
411 char *path;
412 char *addr;
413 int plen;
414 char **ibp; /* instance block paths */
415 uint_t nibp; /* number of paths in instance block */
416 uint_t ibpi; /* ibp index */
417 int ibplen; /* length of instance block path */
418 char *ipath;
419 int instance_base;
420 int splice;
421 int i;
422
423 /* check for fresh install case (in miniroot) */
424 if (DEVI(dip)->devi_instance != -1)
425 return (0); /* already assigned */
426
427 /*
428 * Check to see if we need to allocate a block of contiguous instance
429 * numbers by looking for the 'ddi-instance-blocks' property.
430 */
431 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
432 "ddi-instance-blocks", &ibn, &nibn) != DDI_SUCCESS)
433 return (0); /* no instance block needed */
434
435 /*
436 * Get information out about node we are processing.
437 *
438 * NOTE: Since the node is not yet at DS_INITIALIZED, ddi_pathname()
439 * will not return the unit-address of the final path component even
440 * though the node has an established devi_addr unit-address - so we
441 * need to add the unit-address by hand.
442 */
443 driver = (char *)ddi_driver_name(dip);
444 major = ddi_driver_major(dip);
445 path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
446 (void) ddi_pathname(dip, path);
447 if ((addr = ddi_get_name_addr(dip)) != NULL) {
448 (void) strcat(path, "@");
449 (void) strcat(path, addr);
450 }
451 plen = strlen(path);
452
453 /* loop through instance block names */
454 for (ibni = 0; ibni < nibn; ibni++) {
455 if (ibn[ibni] == NULL)
456 continue;
457
458 /* lookup instance block */
459 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip,
460 DDI_PROP_DONTPASS, ibn[ibni],
461 &ibp, &nibp) != DDI_SUCCESS) {
462 cmn_err(CE_WARN,
463 "no devinition for instance block '%s' in %s.conf",
464 ibn[ibni], driver);
465 continue;
466 }
467
468 /* Does 'path' go through this instance block? */
469 for (ibpi = 0; ibpi < nibp; ibpi++) {
470 if (ibp[ibpi] == NULL)
471 continue;
472 ibplen = strlen(ibp[ibpi]);
473 if ((ibplen <= plen) &&
474 (strcmp(ibp[ibpi], path + plen - ibplen) == 0))
475 break;
476
477 }
478 if (ibpi >= nibp) {
479 ddi_prop_free(ibp);
480 continue; /* no try next instance block */
481 }
482
483 /* yes, allocate and assign instances for all paths in block */
484
485 /*
486 * determine where we splice in instance paths and verify
487 * that none of the paths are too long.
488 */
489 splice = plen - ibplen;
490 for (i = 0; i < nibp; i++) {
491 if ((splice + strlen(ibp[i])+ 1) >= MAXPATHLEN) {
492 cmn_err(CE_WARN,
493 "path %d through instance block '%s' from "
494 "%s.conf too long", i, ibn[ibni], driver);
495 break;
496 }
497 }
498 if (i < nibp) {
499 ddi_prop_free(ibp);
500 continue; /* too long */
501 }
502
503 /* allocate the instance block - no more failures */
504 instance_base = in_next_instance_block(major, nibp);
505
506 ipath = kmem_alloc(MAXPATHLEN, KM_SLEEP);
507 for (ibpi = 0; ibpi < nibp; ibpi++) {
508 if (ibp[ibpi] == NULL)
509 continue;
510 (void) strcpy(ipath, path);
511 (void) strcpy(ipath + splice, ibp[ibpi]);
512 (void) in_pathin(ipath,
513 instance_base + ibpi, driver, NULL);
514 }
515
516 /* free allocations */
517 kmem_free(ipath, MAXPATHLEN);
518 ddi_prop_free(ibp);
519 kmem_free(path, MAXPATHLEN);
520 ddi_prop_free(ibn);
521
522 /* notify devfsadmd to sync of path_to_inst file */
523 mutex_enter(&e_ddi_inst_state.ins_serial);
524 i_log_devfs_instance_mod();
525 e_ddi_inst_state.ins_dirty = B_TRUE;
526 mutex_exit(&e_ddi_inst_state.ins_serial);
527 return (1);
528 }
529
530 /* our path did not go through any of of the instance blocks */
531 kmem_free(path, MAXPATHLEN);
532 ddi_prop_free(ibn);
533 return (0);
534 }
535
536 /*
537 * Look up an instance number for a dev_info node, and assign one if it does
538 * not have one (the dev_info node has devi_name and devi_addr already set).
539 */
540 uint_t
e_ddi_assign_instance(dev_info_t * dip)541 e_ddi_assign_instance(dev_info_t *dip)
542 {
543 char *name;
544 in_node_t *ap, *np;
545 in_drv_t *dp;
546 major_t major;
547 uint_t ret;
548 char *bname;
549
550 /*
551 * Allow implementation to override
552 */
553 if ((ret = impl_assign_instance(dip)) != (uint_t)-1)
554 return (ret);
555
556 /*
557 * If this is a pseudo-device, use the instance number
558 * assigned by the pseudo nexus driver. The mutex is
559 * not needed since the instance tree is not used.
560 */
561 if (is_pseudo_device(dip)) {
562 return (ddi_get_instance(dip));
563 }
564
565 /*
566 * Only one thread is allowed to change the state of the instance
567 * number assignments on the system at any given time.
568 */
569 e_ddi_enter_instance();
570
571 /*
572 * Look for instance node, allocate one if not found
573 */
574 np = in_devwalk(dip, &ap, NULL);
575 if (np == NULL) {
576 if (in_assign_instance_block(dip)) {
577 np = in_devwalk(dip, &ap, NULL);
578 } else {
579 name = ddi_node_name(dip);
580 np = in_alloc_node(name, ddi_get_name_addr(dip));
581 ASSERT(np != NULL);
582 in_enlist(ap, np); /* insert into tree */
583 }
584 }
585 ASSERT(np == in_devwalk(dip, &ap, NULL));
586
587 /*
588 * Link the devinfo node and in_node_t
589 */
590 if (DEVI(dip)->devi_in_node || np->in_devi) {
591 ddi_err(DER_MODE, dip, "devinfo and instance node (%p) "
592 "interlink fields are not NULL", (void *)np);
593 }
594 DEVI(dip)->devi_in_node = np;
595 np->in_devi = dip;
596
597 /*
598 * Look for driver entry, allocate one if not found
599 */
600 bname = (char *)ddi_driver_name(dip);
601 dp = in_drvwalk(np, bname);
602 if (dp == NULL) {
603
604 if (ddi_aliases_present == B_TRUE) {
605 e_ddi_borrow_instance(dip, np);
606 }
607
608 if ((dp = in_drvwalk(np, bname)) == NULL) {
609 dp = in_alloc_drv(bname);
610 ASSERT(dp != NULL);
611 major = ddi_driver_major(dip);
612 ASSERT(major != DDI_MAJOR_T_NONE);
613 in_endrv(np, dp);
614 in_set_instance(dip, dp, major);
615 dp->ind_state = IN_PROVISIONAL;
616 in_hashdrv(dp);
617 } else {
618 dp->ind_state = IN_BORROWED;
619 }
620 }
621
622 ret = dp->ind_instance;
623
624 e_ddi_exit_instance();
625 return (ret);
626 }
627
628 static int
mkpathname(char * path,in_node_t * np,int len)629 mkpathname(char *path, in_node_t *np, int len)
630 {
631 int len_needed;
632
633 if (np == e_ddi_inst_state.ins_root)
634 return (DDI_SUCCESS);
635
636 if (mkpathname(path, np->in_parent, len) == DDI_FAILURE)
637 return (DDI_FAILURE);
638
639 len_needed = strlen(path);
640 len_needed += strlen(np->in_node_name) + 1; /* for '/' */
641 if (np->in_unit_addr) {
642 len_needed += strlen(np->in_unit_addr) + 1; /* for '@' */
643 }
644 len_needed += 1; /* for '\0' */
645
646 /*
647 * XX complain
648 */
649 if (len_needed > len)
650 return (DDI_FAILURE);
651
652 if (np->in_unit_addr[0] == '\0')
653 (void) sprintf(path+strlen(path), "/%s", np->in_node_name);
654 else
655 (void) sprintf(path+strlen(path), "/%s@%s", np->in_node_name,
656 np->in_unit_addr);
657
658 return (DDI_SUCCESS);
659 }
660
661 /*
662 * produce the path to the given instance of a major number.
663 * path must hold MAXPATHLEN string
664 */
665 int
e_ddi_instance_majorinstance_to_path(major_t major,uint_t inst,char * path)666 e_ddi_instance_majorinstance_to_path(major_t major, uint_t inst, char *path)
667 {
668 struct devnames *dnp;
669 in_drv_t *dp;
670 int ret;
671
672 e_ddi_enter_instance();
673
674 /* look for the instance threaded off major */
675 dnp = &devnamesp[major];
676 for (dp = dnp->dn_inlist; dp != NULL; dp = dp->ind_next)
677 if (dp->ind_instance == inst)
678 break;
679
680 /* produce path from the node that uses the instance */
681 if (dp) {
682 *path = 0;
683 ret = mkpathname(path, dp->ind_node, MAXPATHLEN);
684 } else
685 ret = DDI_FAILURE;
686
687 e_ddi_exit_instance();
688 return (ret);
689 }
690
691 /*
692 * Allocate a sequential block of instance numbers for the specified driver,
693 * and return the base instance number of the block. The implementation
694 * depends on the list being sorted in ascending instance number sequence.
695 * When there are no 'holes' in the allocation sequence, dn_instance is the
696 * next available instance number. When dn_instance is IN_SEARCHME, hole(s)
697 * exists and a slower code path executes which tries to fill holes.
698 *
699 * The block returned can't be in the preassigned range.
700 */
701 static int
in_next_instance_block(major_t major,int block_size)702 in_next_instance_block(major_t major, int block_size)
703 {
704 int prev;
705 struct devnames *dnp;
706 in_drv_t *dp;
707 int base;
708 int hole;
709
710 dnp = &devnamesp[major];
711 ASSERT(major != DDI_MAJOR_T_NONE);
712 ASSERT(e_ddi_inst_state.ins_busy);
713 ASSERT(block_size);
714
715 /* check to see if we can do a quick allocation */
716 if (!instance_searchme && (dnp->dn_instance != IN_SEARCHME)) {
717 base = dnp->dn_instance;
718 dnp->dn_instance += block_size;
719 return (base);
720 }
721
722 /*
723 * Use more complex code path, start by skipping preassign entries.
724 */
725 for (dp = dnp->dn_inlist; dp; dp = dp->ind_next)
726 if (dp->ind_instance >= dnp->dn_pinstance)
727 break; /* beyond preassign */
728
729 /* No non-preassign entries, allocate block at preassign base. */
730 if (dp == NULL) {
731 base = dnp->dn_pinstance;
732 if (base == 0)
733 dnp->dn_instance = block_size;
734 return (base);
735 }
736
737 /* See if we fit in hole at beginning (after preassigns) */
738 prev = dp->ind_instance;
739 if ((prev - dnp->dn_pinstance) >= block_size)
740 return (dnp->dn_pinstance); /* we fit in beginning hole */
741
742 /* search the list for a large enough hole */
743 for (dp = dp->ind_next, hole = 0; dp; dp = dp->ind_next) {
744 if (dp->ind_instance != (prev + 1))
745 hole++; /* we have a hole */
746 if (dp->ind_instance >= (prev + block_size + 1))
747 break; /* we fit in hole */
748 prev = dp->ind_instance;
749 }
750
751 /*
752 * If hole is zero then all holes are patched and we can resume
753 * quick allocations, but don't resume quick allocation if there is
754 * a preassign.
755 */
756 if ((hole == 0) && (dnp->dn_pinstance == 0))
757 dnp->dn_instance = prev + 1 + block_size;
758
759 return (prev + 1);
760 }
761
762 /* assign instance block of size 1 */
763 static int
in_next_instance(major_t major)764 in_next_instance(major_t major)
765 {
766 return (in_next_instance_block(major, 1));
767 }
768
769 /*
770 * This call causes us to *forget* the instance number we've generated
771 * for a given device if it was not permanent.
772 */
773 void
e_ddi_free_instance(dev_info_t * dip,char * addr)774 e_ddi_free_instance(dev_info_t *dip, char *addr)
775 {
776 char *name;
777 in_node_t *np;
778 in_node_t *ap; /* ancestor node */
779 major_t major;
780 struct devnames *dnp;
781 in_drv_t *dp; /* in_drv entry */
782
783 /*
784 * Allow implementation override
785 */
786 if (impl_free_instance(dip) == DDI_SUCCESS)
787 return;
788
789 /*
790 * If this is a pseudo-device, no instance number
791 * was assigned.
792 */
793 if (is_pseudo_device(dip)) {
794 return;
795 }
796
797 name = (char *)ddi_driver_name(dip);
798 major = ddi_driver_major(dip);
799 ASSERT(major != DDI_MAJOR_T_NONE);
800 dnp = &devnamesp[major];
801 /*
802 * Only one thread is allowed to change the state of the instance
803 * number assignments on the system at any given time.
804 */
805 e_ddi_enter_instance();
806 np = in_devwalk(dip, &ap, addr);
807 ASSERT(np);
808
809 /*
810 * Break the interlink between dip and np
811 */
812 if (DEVI(dip)->devi_in_node != np || np->in_devi != dip) {
813 ddi_err(DER_MODE, dip, "devinfo node linked to "
814 "wrong instance node: %p", (void *)np);
815 }
816 DEVI(dip)->devi_in_node = NULL;
817 np->in_devi = NULL;
818
819 dp = in_drvwalk(np, name);
820 ASSERT(dp);
821 if (dp->ind_state == IN_PROVISIONAL) {
822 in_removedrv(dnp, dp);
823 } else if (dp->ind_state == IN_BORROWED) {
824 dp->ind_state = IN_PERMANENT;
825 e_ddi_return_instance(dip, addr, np);
826 }
827 if (np->in_drivers == NULL) {
828 in_removenode(dnp, np, ap);
829 }
830 e_ddi_exit_instance();
831 }
832
833 /*
834 * This makes our memory of an instance assignment permanent
835 */
836 void
e_ddi_keep_instance(dev_info_t * dip)837 e_ddi_keep_instance(dev_info_t *dip)
838 {
839 in_node_t *np, *ap;
840 in_drv_t *dp;
841
842 /* Don't make nulldriver instance assignments permanent */
843 if (ddi_driver_major(dip) == nulldriver_major)
844 return;
845
846 /*
847 * Allow implementation override
848 */
849 if (impl_keep_instance(dip) == DDI_SUCCESS)
850 return;
851
852 /*
853 * Nothing to do for pseudo devices.
854 */
855 if (is_pseudo_device(dip))
856 return;
857
858 /*
859 * Only one thread is allowed to change the state of the instance
860 * number assignments on the system at any given time.
861 */
862 e_ddi_enter_instance();
863 np = in_devwalk(dip, &ap, NULL);
864 ASSERT(np);
865 dp = in_drvwalk(np, (char *)ddi_driver_name(dip));
866 ASSERT(dp);
867
868 mutex_enter(&e_ddi_inst_state.ins_serial);
869 if (dp->ind_state == IN_PROVISIONAL || dp->ind_state == IN_BORROWED) {
870 dp->ind_state = IN_PERMANENT;
871 i_log_devfs_instance_mod();
872 e_ddi_inst_state.ins_dirty = B_TRUE;
873 }
874 mutex_exit(&e_ddi_inst_state.ins_serial);
875 e_ddi_exit_instance();
876 }
877
878 /*
879 * A new major has been added to the system. Run through the orphan list
880 * and try to attach each one to a driver's list.
881 */
882 void
e_ddi_unorphan_instance_nos()883 e_ddi_unorphan_instance_nos()
884 {
885 in_drv_t *dp, *ndp;
886
887 /*
888 * disconnect the orphan list, and call in_hashdrv for each item
889 * on it
890 */
891
892 /*
893 * Only one thread is allowed to change the state of the instance
894 * number assignments on the system at any given time.
895 */
896 e_ddi_enter_instance();
897 if (e_ddi_inst_state.ins_no_major == NULL) {
898 e_ddi_exit_instance();
899 return;
900 }
901 /*
902 * Hash instance list to devnames structure of major.
903 * Note that if there is not a valid major number for the
904 * node, in_hashdrv will put it back on the no_major list.
905 */
906 dp = e_ddi_inst_state.ins_no_major;
907 e_ddi_inst_state.ins_no_major = NULL;
908 while (dp) {
909 ndp = dp->ind_next;
910 ASSERT(dp->ind_state != IN_UNKNOWN);
911 dp->ind_next = NULL;
912 in_hashdrv(dp);
913 dp = ndp;
914 }
915 e_ddi_exit_instance();
916 }
917
918 static void
in_removenode(struct devnames * dnp,in_node_t * mp,in_node_t * ap)919 in_removenode(struct devnames *dnp, in_node_t *mp, in_node_t *ap)
920 {
921 in_node_t *np;
922
923 ASSERT(e_ddi_inst_state.ins_busy);
924
925 /*
926 * Assertion: parents are always instantiated by the framework
927 * before their children, destroyed after them
928 */
929 ASSERT(mp->in_child == NULL);
930 /*
931 * Assertion: drv entries are always removed before their owning nodes
932 */
933 ASSERT(mp->in_drivers == NULL);
934 /*
935 * Take the node out of the tree
936 */
937 if (ap->in_child == mp) {
938 ap->in_child = mp->in_sibling;
939 in_dealloc_node(mp);
940 return;
941 } else {
942 for (np = ap->in_child; np; np = np->in_sibling) {
943 if (np->in_sibling == mp) {
944 np->in_sibling = mp->in_sibling;
945 in_dealloc_node(mp);
946 return;
947 }
948 }
949 }
950 panic("in_removenode dnp %p mp %p", (void *)dnp, (void *)mp);
951 }
952
953 /*
954 * Recursive ascent
955 *
956 * This now only does half the job. It finds the node, then the caller
957 * has to search the node for the binding name
958 */
959 static in_node_t *
in_devwalk(dev_info_t * dip,in_node_t ** ap,char * addr)960 in_devwalk(dev_info_t *dip, in_node_t **ap, char *addr)
961 {
962 in_node_t *np;
963 char *name;
964
965 ASSERT(dip);
966 ASSERT(e_ddi_inst_state.ins_busy);
967 if (dip == ddi_root_node()) {
968 *ap = NULL;
969 return (e_ddi_inst_state.ins_root);
970 }
971 /*
972 * call up to find parent, then look through the list of kids
973 * for a match
974 */
975 np = in_devwalk(ddi_get_parent(dip), ap, NULL);
976 if (np == NULL)
977 return (np);
978 *ap = np;
979 np = np->in_child;
980 name = ddi_node_name(dip);
981 if (addr == NULL)
982 addr = ddi_get_name_addr(dip);
983
984 while (np) {
985 if (in_eqstr(np->in_node_name, name) &&
986 in_eqstr(np->in_unit_addr, addr)) {
987 return (np);
988 }
989 np = np->in_sibling;
990 }
991
992 return (np);
993 }
994
995 /*
996 * Create a node specified by cp and assign it the given instance no.
997 */
998 static int
in_pathin(char * cp,int instance,char * bname,struct bind ** args)999 in_pathin(char *cp, int instance, char *bname, struct bind **args)
1000 {
1001 in_node_t *np;
1002 in_drv_t *dp;
1003 char *name;
1004
1005 ASSERT(e_ddi_inst_state.ins_busy);
1006 ASSERT(args == NULL);
1007
1008 /*
1009 * Give a warning to the console.
1010 * return value ignored
1011 */
1012 if (cp[0] != '/' || instance == -1 || bname == NULL) {
1013 cmn_err(CE_WARN,
1014 "invalid instance file entry %s %d",
1015 cp, instance);
1016 return (0);
1017 }
1018
1019 if ((name = i_binding_to_drv_name(bname)) != NULL)
1020 bname = name;
1021
1022 np = in_make_path(cp);
1023 ASSERT(np);
1024
1025 dp = in_drvwalk(np, bname);
1026 if (dp != NULL) {
1027 cmn_err(CE_WARN,
1028 "multiple instance number assignments for "
1029 "'%s' (driver %s), %d used",
1030 cp, bname, dp->ind_instance);
1031 return (0);
1032 }
1033
1034 if (in_inuse(instance, bname)) {
1035 cmn_err(CE_WARN,
1036 "instance already in use: %s %d", cp, instance);
1037 return (0);
1038 }
1039
1040 dp = in_alloc_drv(bname);
1041 in_endrv(np, dp);
1042 dp->ind_instance = instance;
1043 dp->ind_state = IN_PERMANENT;
1044 in_hashdrv(dp);
1045
1046 return (0);
1047 }
1048
1049 /*
1050 * Create (or find) the node named by path by recursively descending from the
1051 * root's first child (we ignore the root, which is never named)
1052 */
1053 static in_node_t *
in_make_path(char * path)1054 in_make_path(char *path)
1055 {
1056 in_node_t *ap; /* ancestor pointer */
1057 in_node_t *np; /* working node pointer */
1058 in_node_t *rp; /* return node pointer */
1059 char buf[MAXPATHLEN]; /* copy of string so we can change it */
1060 char *cp, *name, *addr;
1061
1062 ASSERT(e_ddi_inst_state.ins_busy);
1063
1064 if (path == NULL || path[0] != '/')
1065 return (NULL);
1066
1067 (void) snprintf(buf, sizeof (buf), "%s", path);
1068 cp = buf + 1; /* skip over initial '/' in path */
1069 name = in_name_addr(&cp, &addr);
1070
1071 /*
1072 * In S9 and earlier releases, the path_to_inst file
1073 * SunCluster was prepended with "/node@#". This was
1074 * removed in S10. We skip the prefix if the prefix
1075 * still exists in /etc/path_to_inst. It is needed for
1076 * various forms of Solaris upgrade to work properly
1077 * in the SunCluster environment.
1078 */
1079 if ((cluster_bootflags & CLUSTER_CONFIGURED) &&
1080 (strcmp(name, "node") == 0))
1081 name = in_name_addr(&cp, &addr);
1082
1083 ap = e_ddi_inst_state.ins_root;
1084 np = e_ddi_inst_state.ins_root->in_child;
1085 rp = np;
1086 while (name) {
1087 while (name && np) {
1088 if (in_eqstr(name, np->in_node_name) &&
1089 in_eqstr(addr, np->in_unit_addr)) {
1090 name = in_name_addr(&cp, &addr);
1091 if (name == NULL)
1092 return (np);
1093 ap = np;
1094 np = np->in_child;
1095 } else {
1096 np = np->in_sibling;
1097 }
1098 }
1099 np = in_alloc_node(name, addr);
1100 in_enlist(ap, np); /* insert into tree */
1101 rp = np; /* value to return if we quit */
1102 ap = np; /* new parent */
1103 np = NULL; /* can have no children */
1104 name = in_name_addr(&cp, &addr);
1105 }
1106
1107 return (rp);
1108 }
1109
1110 /*
1111 * Insert node np into the tree as one of ap's children.
1112 */
1113 static void
in_enlist(in_node_t * ap,in_node_t * np)1114 in_enlist(in_node_t *ap, in_node_t *np)
1115 {
1116 in_node_t *mp;
1117 ASSERT(e_ddi_inst_state.ins_busy);
1118 /*
1119 * Make this node some other node's child or child's sibling
1120 */
1121 ASSERT(ap && np);
1122 if (ap->in_child == NULL) {
1123 ap->in_child = np;
1124 } else {
1125 for (mp = ap->in_child; mp; mp = mp->in_sibling)
1126 if (mp->in_sibling == NULL) {
1127 mp->in_sibling = np;
1128 break;
1129 }
1130 }
1131 np->in_parent = ap;
1132 }
1133
1134 /*
1135 * Insert drv entry dp onto a node's driver list
1136 */
1137 static void
in_endrv(in_node_t * np,in_drv_t * dp)1138 in_endrv(in_node_t *np, in_drv_t *dp)
1139 {
1140 in_drv_t *mp;
1141 ASSERT(e_ddi_inst_state.ins_busy);
1142 ASSERT(np && dp);
1143 mp = np->in_drivers;
1144 np->in_drivers = dp;
1145 dp->ind_next_drv = mp;
1146 dp->ind_node = np;
1147 }
1148
1149 /*
1150 * Parse the next name out of the path, null terminate it and update cp.
1151 * caller has copied string so we can mess with it.
1152 * Upon return *cpp points to the next section to be parsed, *addrp points
1153 * to the current address substring (or NULL if none) and we return the
1154 * current name substring (or NULL if none). name and address substrings
1155 * are null terminated in place.
1156 */
1157
1158 static char *
in_name_addr(char ** cpp,char ** addrp)1159 in_name_addr(char **cpp, char **addrp)
1160 {
1161 char *namep; /* return value holder */
1162 char *ap; /* pointer to '@' in string */
1163 char *sp; /* pointer to '/' in string */
1164
1165 if (*cpp == NULL || **cpp == '\0') {
1166 *addrp = NULL;
1167 return (NULL);
1168 }
1169 namep = *cpp;
1170 sp = strchr(*cpp, '/');
1171 if (sp != NULL) { /* more to follow */
1172 *sp = '\0';
1173 *cpp = sp + 1;
1174 } else { /* this is last component. */
1175 *cpp = NULL;
1176 }
1177 ap = strchr(namep, '@');
1178 if (ap == NULL) {
1179 *addrp = NULL;
1180 } else {
1181 *ap = '\0'; /* terminate the name */
1182 *addrp = ap + 1;
1183 }
1184 return (namep);
1185 }
1186
1187 /*
1188 * Allocate a node and storage for name and addr strings, and fill them in.
1189 */
1190 static in_node_t *
in_alloc_node(char * name,char * addr)1191 in_alloc_node(char *name, char *addr)
1192 {
1193 in_node_t *np;
1194 char *cp;
1195 size_t namelen;
1196
1197 ASSERT(e_ddi_inst_state.ins_busy);
1198 /*
1199 * Has name or will become root
1200 */
1201 ASSERT(name || e_ddi_inst_state.ins_root == NULL);
1202 if (addr == NULL)
1203 addr = "";
1204 if (name == NULL)
1205 namelen = 0;
1206 else
1207 namelen = strlen(name) + 1;
1208 cp = kmem_zalloc(sizeof (in_node_t) + namelen + strlen(addr) + 1,
1209 KM_SLEEP);
1210 np = (in_node_t *)cp;
1211 if (name) {
1212 np->in_node_name = cp + sizeof (in_node_t);
1213 (void) strcpy(np->in_node_name, name);
1214 }
1215 np->in_unit_addr = cp + sizeof (in_node_t) + namelen;
1216 (void) strcpy(np->in_unit_addr, addr);
1217 return (np);
1218 }
1219
1220 /*
1221 * Allocate a drv entry and storage for binding name string, and fill it in.
1222 */
1223 static in_drv_t *
in_alloc_drv(char * bindingname)1224 in_alloc_drv(char *bindingname)
1225 {
1226 in_drv_t *dp;
1227 char *cp;
1228 size_t namelen;
1229
1230 ASSERT(e_ddi_inst_state.ins_busy);
1231 /*
1232 * Has name or will become root
1233 */
1234 ASSERT(bindingname || e_ddi_inst_state.ins_root == NULL);
1235 if (bindingname == NULL)
1236 namelen = 0;
1237 else
1238 namelen = strlen(bindingname) + 1;
1239 cp = kmem_zalloc(sizeof (in_drv_t) + namelen, KM_SLEEP);
1240 dp = (in_drv_t *)cp;
1241 if (bindingname) {
1242 dp->ind_driver_name = cp + sizeof (in_drv_t);
1243 (void) strcpy(dp->ind_driver_name, bindingname);
1244 }
1245 dp->ind_state = IN_UNKNOWN;
1246 dp->ind_instance = -1;
1247 return (dp);
1248 }
1249
1250 static void
in_dealloc_node(in_node_t * np)1251 in_dealloc_node(in_node_t *np)
1252 {
1253 /*
1254 * The root node can never be de-allocated
1255 */
1256 ASSERT(np->in_node_name && np->in_unit_addr);
1257 ASSERT(e_ddi_inst_state.ins_busy);
1258 kmem_free(np, sizeof (in_node_t) + strlen(np->in_node_name)
1259 + strlen(np->in_unit_addr) + 2);
1260 }
1261
1262 static void
in_dealloc_drv(in_drv_t * dp)1263 in_dealloc_drv(in_drv_t *dp)
1264 {
1265 ASSERT(dp->ind_driver_name);
1266 ASSERT(e_ddi_inst_state.ins_busy);
1267 kmem_free(dp, sizeof (in_drv_t) + strlen(dp->ind_driver_name)
1268 + 1);
1269 }
1270
1271 /*
1272 * Handle the various possible versions of "no address"
1273 */
1274 static int
in_eqstr(char * a,char * b)1275 in_eqstr(char *a, char *b)
1276 {
1277 if (a == b) /* covers case where both are nulls */
1278 return (1);
1279 if (a == NULL && *b == 0)
1280 return (1);
1281 if (b == NULL && *a == 0)
1282 return (1);
1283 if (a == NULL || b == NULL)
1284 return (0);
1285 return (strcmp(a, b) == 0);
1286 }
1287
1288 /*
1289 * Returns true if instance no. is already in use by named driver
1290 */
1291 static int
in_inuse(int instance,char * name)1292 in_inuse(int instance, char *name)
1293 {
1294 major_t major;
1295 in_drv_t *dp;
1296 struct devnames *dnp;
1297
1298 ASSERT(e_ddi_inst_state.ins_busy);
1299 /*
1300 * For now, if we've never heard of this device we assume it is not
1301 * in use, since we can't tell
1302 * XXX could do the weaker search through the nomajor list checking
1303 * XXX for the same name
1304 */
1305 if ((major = ddi_name_to_major(name)) == DDI_MAJOR_T_NONE)
1306 return (0);
1307 dnp = &devnamesp[major];
1308
1309 dp = dnp->dn_inlist;
1310 while (dp) {
1311 if (dp->ind_instance == instance)
1312 return (1);
1313 dp = dp->ind_next;
1314 }
1315 return (0);
1316 }
1317
1318 static void
in_hashdrv(in_drv_t * dp)1319 in_hashdrv(in_drv_t *dp)
1320 {
1321 struct devnames *dnp;
1322 in_drv_t *mp, *pp;
1323 major_t major;
1324
1325 /* hash to no major list */
1326 major = ddi_name_to_major(dp->ind_driver_name);
1327 if (major == DDI_MAJOR_T_NONE) {
1328 dp->ind_next = e_ddi_inst_state.ins_no_major;
1329 e_ddi_inst_state.ins_no_major = dp;
1330 return;
1331 }
1332
1333 /*
1334 * dnp->dn_inlist is sorted by instance number.
1335 * Adding a new instance entry may introduce holes,
1336 * set dn_instance to IN_SEARCHME so the next instance
1337 * assignment may fill in holes.
1338 */
1339 dnp = &devnamesp[major];
1340 pp = mp = dnp->dn_inlist;
1341 if (mp == NULL || dp->ind_instance < mp->ind_instance) {
1342 /* prepend as the first entry, turn on IN_SEARCHME */
1343 dnp->dn_instance = IN_SEARCHME;
1344 dp->ind_next = mp;
1345 dnp->dn_inlist = dp;
1346 return;
1347 }
1348
1349 ASSERT(mp->ind_instance != dp->ind_instance);
1350 while (mp->ind_instance < dp->ind_instance && mp->ind_next) {
1351 pp = mp;
1352 mp = mp->ind_next;
1353 ASSERT(mp->ind_instance != dp->ind_instance);
1354 }
1355
1356 if (mp->ind_instance < dp->ind_instance) { /* end of list */
1357 dp->ind_next = NULL;
1358 mp->ind_next = dp;
1359 } else {
1360 dp->ind_next = pp->ind_next;
1361 pp->ind_next = dp;
1362 }
1363 }
1364
1365 /*
1366 * Remove a driver entry from the list, given a previous pointer
1367 */
1368 static void
in_removedrv(struct devnames * dnp,in_drv_t * mp)1369 in_removedrv(struct devnames *dnp, in_drv_t *mp)
1370 {
1371 in_drv_t *dp;
1372 in_drv_t *prevp;
1373
1374 if (dnp->dn_inlist == mp) { /* head of list */
1375 dnp->dn_inlist = mp->ind_next;
1376 dnp->dn_instance = IN_SEARCHME;
1377 in_dq_drv(mp);
1378 in_dealloc_drv(mp);
1379 return;
1380 }
1381 prevp = dnp->dn_inlist;
1382 for (dp = prevp->ind_next; dp; dp = dp->ind_next) {
1383 if (dp == mp) { /* found it */
1384 break;
1385 }
1386 prevp = dp;
1387 }
1388
1389 ASSERT(dp == mp);
1390 dnp->dn_instance = IN_SEARCHME;
1391 prevp->ind_next = mp->ind_next;
1392 in_dq_drv(mp);
1393 in_dealloc_drv(mp);
1394 }
1395
1396 static void
in_dq_drv(in_drv_t * mp)1397 in_dq_drv(in_drv_t *mp)
1398 {
1399 struct in_node *node = mp->ind_node;
1400 in_drv_t *ptr, *prev;
1401
1402 if (mp == node->in_drivers) {
1403 node->in_drivers = mp->ind_next_drv;
1404 return;
1405 }
1406 prev = node->in_drivers;
1407 for (ptr = prev->ind_next_drv; ptr != (struct in_drv *)NULL;
1408 ptr = ptr->ind_next_drv) {
1409 if (ptr == mp) {
1410 prev->ind_next_drv = ptr->ind_next_drv;
1411 return;
1412 }
1413 prev = ptr;
1414 }
1415 panic("in_dq_drv: in_drv not found on node driver list");
1416 }
1417
1418
1419 in_drv_t *
in_drvwalk(in_node_t * np,char * binding_name)1420 in_drvwalk(in_node_t *np, char *binding_name)
1421 {
1422 char *name;
1423 in_drv_t *dp = np->in_drivers;
1424 while (dp) {
1425 if ((name = i_binding_to_drv_name(dp->ind_driver_name))
1426 == NULL) {
1427 name = dp->ind_driver_name;
1428 }
1429 if (strcmp(binding_name, name) == 0) {
1430 break;
1431 }
1432 dp = dp->ind_next_drv;
1433 }
1434 return (dp);
1435 }
1436
1437
1438
1439 static void
i_log_devfs_instance_mod(void)1440 i_log_devfs_instance_mod(void)
1441 {
1442 sysevent_t *ev;
1443 sysevent_id_t eid;
1444 static int sent_one = 0;
1445
1446 /*
1447 * Prevent unnecessary event generation. Do not generate more than
1448 * one event during boot.
1449 */
1450 if (sent_one && !i_ddi_io_initialized())
1451 return;
1452
1453 ev = sysevent_alloc(EC_DEVFS, ESC_DEVFS_INSTANCE_MOD, EP_DDI,
1454 SE_NOSLEEP);
1455 if (ev == NULL) {
1456 return;
1457 }
1458 if (log_sysevent(ev, SE_NOSLEEP, &eid) != 0) {
1459 cmn_err(CE_WARN, "i_log_devfs_instance_mod: failed to post "
1460 "event");
1461 } else {
1462 sent_one = 1;
1463 }
1464 sysevent_free(ev);
1465 }
1466
1467 void
e_ddi_enter_instance(void)1468 e_ddi_enter_instance(void)
1469 {
1470 mutex_enter(&e_ddi_inst_state.ins_serial);
1471 if (e_ddi_inst_state.ins_thread == curthread)
1472 e_ddi_inst_state.ins_busy++;
1473 else {
1474 while (e_ddi_inst_state.ins_busy)
1475 cv_wait(&e_ddi_inst_state.ins_serial_cv,
1476 &e_ddi_inst_state.ins_serial);
1477 e_ddi_inst_state.ins_thread = curthread;
1478 e_ddi_inst_state.ins_busy = 1;
1479 }
1480 mutex_exit(&e_ddi_inst_state.ins_serial);
1481 }
1482
1483 void
e_ddi_exit_instance(void)1484 e_ddi_exit_instance(void)
1485 {
1486 mutex_enter(&e_ddi_inst_state.ins_serial);
1487 e_ddi_inst_state.ins_busy--;
1488 if (e_ddi_inst_state.ins_busy == 0) {
1489 cv_broadcast(&e_ddi_inst_state.ins_serial_cv);
1490 e_ddi_inst_state.ins_thread = NULL;
1491 }
1492 mutex_exit(&e_ddi_inst_state.ins_serial);
1493 }
1494
1495 int
e_ddi_instance_is_clean(void)1496 e_ddi_instance_is_clean(void)
1497 {
1498 return (e_ddi_inst_state.ins_dirty == B_FALSE);
1499 }
1500
1501 void
e_ddi_instance_set_clean(void)1502 e_ddi_instance_set_clean(void)
1503 {
1504 e_ddi_inst_state.ins_dirty = B_FALSE;
1505 }
1506
1507 in_node_t *
e_ddi_instance_root(void)1508 e_ddi_instance_root(void)
1509 {
1510 return (e_ddi_inst_state.ins_root);
1511 }
1512
1513 /*
1514 * Visit a node in the instance tree
1515 */
1516 static int
in_walk_instances(in_node_t * np,char * path,char * this,int (* f)(const char *,in_node_t *,in_drv_t *,void *),void * arg)1517 in_walk_instances(in_node_t *np, char *path, char *this,
1518 int (*f)(const char *, in_node_t *, in_drv_t *, void *), void *arg)
1519 {
1520 in_drv_t *dp;
1521 int rval = INST_WALK_CONTINUE;
1522 char *next;
1523
1524 while (np != NULL) {
1525
1526 if (np->in_unit_addr[0] == 0)
1527 (void) sprintf(this, "/%s", np->in_node_name);
1528 else
1529 (void) sprintf(this, "/%s@%s", np->in_node_name,
1530 np->in_unit_addr);
1531 next = this + strlen(this);
1532
1533 for (dp = np->in_drivers; dp; dp = dp->ind_next_drv) {
1534 if (dp->ind_state == IN_PERMANENT) {
1535 rval = (*f)(path, np, dp, arg);
1536 if (rval == INST_WALK_TERMINATE)
1537 break;
1538 }
1539 }
1540
1541 if (np->in_child) {
1542 rval = in_walk_instances(np->in_child,
1543 path, next, f, arg);
1544 if (rval == INST_WALK_TERMINATE)
1545 break;
1546 }
1547
1548 np = np->in_sibling;
1549 }
1550
1551 return (rval);
1552 }
1553
1554 /*
1555 * A general interface for walking the instance tree,
1556 * calling a user-supplied callback for each node.
1557 */
1558 int
e_ddi_walk_instances(int (* f)(const char *,in_node_t *,in_drv_t *,void *),void * arg)1559 e_ddi_walk_instances(int (*f)(const char *,
1560 in_node_t *, in_drv_t *, void *), void *arg)
1561 {
1562 in_node_t *root;
1563 int rval;
1564 char *path;
1565
1566 path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1567
1568 e_ddi_enter_instance();
1569 root = e_ddi_instance_root();
1570 rval = in_walk_instances(root->in_child, path, path, f, arg);
1571
1572 e_ddi_exit_instance();
1573
1574 kmem_free(path, MAXPATHLEN);
1575 return (rval);
1576 }
1577
1578 in_node_t *
e_ddi_path_to_instance(char * path)1579 e_ddi_path_to_instance(char *path)
1580 {
1581 in_node_t *np;
1582
1583 np = in_make_path(path);
1584 if (np && np->in_drivers && np->in_drivers->ind_state == IN_PERMANENT) {
1585 return (np);
1586 }
1587 return (NULL);
1588 }
1589
1590 void
e_ddi_borrow_instance(dev_info_t * cdip,in_node_t * cnp)1591 e_ddi_borrow_instance(dev_info_t *cdip, in_node_t *cnp)
1592 {
1593 char *alias;
1594 in_node_t *anp;
1595 char *curr = kmem_alloc(MAXPATHLEN, KM_NOSLEEP);
1596
1597 if (curr == NULL) {
1598 ddi_err(DER_PANIC, cdip, "curr alloc failed");
1599 /*NOTREACHED*/
1600 }
1601
1602 (void) ddi_pathname(cdip, curr);
1603
1604 if (cnp->in_drivers) {
1605 /* there can be multiple drivers bound */
1606 ddi_err(DER_LOG, cdip, "%s has previous binding: %s", curr,
1607 cnp->in_drivers->ind_driver_name);
1608 }
1609
1610 alias = ddi_curr_redirect(curr);
1611
1612 /* bail here if the alias matches any other current path or itself */
1613 if (alias && ((strcmp(curr, alias) == 0) ||
1614 (ddi_curr_redirect(alias) != 0))) {
1615 DDI_MP_DBG((CE_NOTE, "not borrowing current: %s alias: %s",
1616 curr, alias));
1617 goto out;
1618 }
1619
1620 if (alias && (anp = e_ddi_path_to_instance(alias)) != NULL) {
1621 /*
1622 * Since pcieb nodes can split and merge, it is dangerous
1623 * to borrow and instance for them. However since they do
1624 * not expose their instance numbers it is safe to never
1625 * borrow one.
1626 */
1627 if (anp->in_drivers->ind_driver_name &&
1628 (strcmp(anp->in_drivers->ind_driver_name, "pcieb") == 0)) {
1629 DDI_MP_DBG((CE_NOTE, "not borrowing pcieb: "
1630 "%s alias: %s", curr, alias));
1631 goto out;
1632 }
1633 DDI_MP_DBG((CE_NOTE, "borrowing current: %s alias: %s",
1634 curr, alias));
1635 cnp->in_drivers = anp->in_drivers;
1636 anp->in_drivers = NULL;
1637 }
1638 out:
1639 kmem_free(curr, MAXPATHLEN);
1640 }
1641
1642 void
e_ddi_return_instance(dev_info_t * cdip,char * addr,in_node_t * cnp)1643 e_ddi_return_instance(dev_info_t *cdip, char *addr, in_node_t *cnp)
1644 {
1645 in_node_t *anp;
1646 char *alias;
1647 char *curr = kmem_alloc(MAXPATHLEN, KM_NOSLEEP);
1648
1649 if (curr == NULL) {
1650 ddi_err(DER_PANIC, cdip, "alloc of curr failed");
1651 /*NOTREACHED*/
1652 }
1653
1654 (void) ddi_pathname(cdip, curr);
1655 if (addr) {
1656 (void) strlcat(curr, "@", MAXPATHLEN);
1657 (void) strlcat(curr, addr, MAXPATHLEN);
1658
1659 }
1660 if (cnp->in_drivers == NULL) {
1661 ddi_err(DER_PANIC, cdip, "cnp has no inst: %p", cnp);
1662 /*NOTREACHED*/
1663 }
1664
1665 alias = ddi_curr_redirect(curr);
1666 kmem_free(curr, MAXPATHLEN);
1667
1668 if (alias && (anp = e_ddi_path_to_instance(alias)) != NULL) {
1669 ASSERT(anp->in_drivers == NULL);
1670 anp->in_drivers = cnp->in_drivers;
1671 cnp->in_drivers = NULL;
1672 }
1673 }
1674