/* * This is a nasty, slow hack. But we're stuck with it until we do some * major surgery on the instance assignment subsystem, to allow pseudonode * instance assignment to be tracked there. * * To auto-assign an instance number, we exhaustively search the instance * list for each possible instance number until we find one which is unused. */ static int pseudonex_auto_assign(dev_info_t *child) { dev_info_t *tdip; kmutex_t *dmp; const char *childname = ddi_driver_name(child); major_t childmaj = ddi_name_to_major((char *)childname); int inst = 0; dmp = &devnamesp[childmaj].dn_lock; LOCK_DEV_OPS(dmp); for (inst = 0; inst <= MAXMIN32; inst++) { for (tdip = devnamesp[childmaj].dn_head; tdip != NULL; tdip = ddi_get_next(tdip)) { /* is this the current node? */ if (tdip == child) continue; if (inst == ddi_get_instance(tdip)) { break; } } if (tdip == NULL) { UNLOCK_DEV_OPS(dmp); return (inst); } } UNLOCK_DEV_OPS(dmp); return (-1); }
static void in_preassign_instance() { major_t m; extern major_t devcnt; for (m = 0; m < devcnt; m++) { struct devnames *dnp = &devnamesp[m]; dev_info_t *dip = dnp->dn_head; while (dip) { DEVI(dip)->devi_instance = dnp->dn_instance; dnp->dn_instance++; dip = ddi_get_next(dip); } } }
/* * Load drivers required for a platform * Since all hardware nodes should be available in the device * tree, walk the per-driver list and load the parents of * each node found. If not a hardware node, try to load it. * Pseudo nexus is already loaded. */ static int load_boot_platform_modules(char *drv) { major_t major; dev_info_t *dip; char *drvname; int rval = 0; if ((major = ddi_name_to_major(drv)) == (major_t)-1) { cmn_err(CE_CONT, "%s: no major number\n", drv); return (-1); } /* * resolve aliases */ drvname = ddi_major_to_name(major); if ((major = ddi_name_to_major(drvname)) == (major_t)-1) return (-1); #ifdef DEBUG if (strcmp(drv, drvname) == 0) { BMDPRINTF(("load_boot_platform_modules: %s\n", drv)); } else { BMDPRINTF(("load_boot_platform_modules: %s -> %s\n", drv, drvname)); } #endif /* DEBUG */ dip = devnamesp[major].dn_head; if (dip == NULL) { /* pseudo node, not-enumerated, needs to be loaded */ if (modloadonly("drv", drvname) == -1) { cmn_err(CE_CONT, "%s: cannot load platform driver\n", drvname); rval = -1; } } else { while (dip) { if (load_parent_drivers(dip, NULL) != 0) rval = -1; dip = ddi_get_next(dip); } } return (rval); }
static char * plat_ttypath(int inum) { static char *defaultpath[] = { "/isa/asy@1,3f8:a", "/isa/asy@1,2f8:b" }; static char path[MAXPATHLEN]; char *bp; major_t major; dev_info_t *dip; if (pseudo_isa) return (defaultpath[inum]); if ((major = ddi_name_to_major("asy")) == (major_t)-1) return (NULL); if ((dip = devnamesp[major].dn_head) == NULL) return (NULL); for (; dip != NULL; dip = ddi_get_next(dip)) { if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS) return (NULL); if (DEVI(dip)->devi_minor->ddm_name[0] == ('a' + (char)inum)) break; } if (dip == NULL) return (NULL); (void) ddi_pathname(dip, path); bp = path + strlen(path); (void) snprintf(bp, 3, ":%s", DEVI(dip)->devi_minor->ddm_name); return (path); }
static int pseudonex_check_assignment(dev_info_t *child, int test_inst) { dev_info_t *tdip; kmutex_t *dmp; const char *childname = ddi_driver_name(child); major_t childmaj = ddi_name_to_major((char *)childname); dmp = &devnamesp[childmaj].dn_lock; LOCK_DEV_OPS(dmp); for (tdip = devnamesp[childmaj].dn_head; tdip != NULL; tdip = ddi_get_next(tdip)) { /* is this the current node? */ if (tdip == child) continue; /* is this a duplicate instance? */ if (test_inst == ddi_get_instance(tdip)) { UNLOCK_DEV_OPS(dmp); return (DDI_FAILURE); } } UNLOCK_DEV_OPS(dmp); return (DDI_SUCCESS); }