17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 22*aeb0348bSmike_s 237c478bd9Sstevel@tonic-gate /* 24*aeb0348bSmike_s * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25*aeb0348bSmike_s * Use is subject to license terms. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #include <fcntl.h> 317c478bd9Sstevel@tonic-gate #include <stdio.h> 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 337c478bd9Sstevel@tonic-gate #include <ctype.h> 347c478bd9Sstevel@tonic-gate #include <string.h> 357c478bd9Sstevel@tonic-gate #include <unistd.h> 367c478bd9Sstevel@tonic-gate #include <libdevice.h> 377c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 387c478bd9Sstevel@tonic-gate #define _KERNEL 397c478bd9Sstevel@tonic-gate #include <sys/dditypes.h> 407c478bd9Sstevel@tonic-gate #include <sys/devctl.h> 417c478bd9Sstevel@tonic-gate #include <sys/bofi.h> 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate static int online_device(char *path); 447c478bd9Sstevel@tonic-gate static int offline_device(char *path); 457c478bd9Sstevel@tonic-gate static int getstate_device(char *path); 467c478bd9Sstevel@tonic-gate static int getnameinst(char *path, int *instance, char *name, int namelen); 477c478bd9Sstevel@tonic-gate static int getpath(char *path, int instance, char *name, int pathlen); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate static char buffer[50*1024]; 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #define CMD_TABLE_SIZE 11 527c478bd9Sstevel@tonic-gate #define BOFI_ONLINE 0 537c478bd9Sstevel@tonic-gate #define BOFI_OFFLINE 1 547c478bd9Sstevel@tonic-gate #define BOFI_GETSTATE 2 557c478bd9Sstevel@tonic-gate #define BOFI_GETPATH 3 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate static struct { 587c478bd9Sstevel@tonic-gate char *string; 597c478bd9Sstevel@tonic-gate int val; 607c478bd9Sstevel@tonic-gate int devctl_val; 617c478bd9Sstevel@tonic-gate } cmd_table[] = { 627c478bd9Sstevel@tonic-gate {"online", -1, BOFI_ONLINE}, 637c478bd9Sstevel@tonic-gate {"offline", -1, BOFI_OFFLINE}, 647c478bd9Sstevel@tonic-gate {"getstate", -1, BOFI_GETSTATE}, 657c478bd9Sstevel@tonic-gate {"getpath", -1, BOFI_GETPATH}, 667c478bd9Sstevel@tonic-gate {"broadcast", BOFI_BROADCAST, -1}, 677c478bd9Sstevel@tonic-gate {"clear_acc_chk", BOFI_CLEAR_ACC_CHK, -1}, 687c478bd9Sstevel@tonic-gate {"clear_errors", BOFI_CLEAR_ERRORS, -1}, 697c478bd9Sstevel@tonic-gate {"clear_errdefs", BOFI_CLEAR_ERRDEFS, -1}, 707c478bd9Sstevel@tonic-gate {"start", BOFI_START, -1}, 717c478bd9Sstevel@tonic-gate {"stop", BOFI_STOP, -1}, 727c478bd9Sstevel@tonic-gate {"get_handles", BOFI_GET_HANDLES, -1} 737c478bd9Sstevel@tonic-gate }; 747c478bd9Sstevel@tonic-gate 75*aeb0348bSmike_s int 767c478bd9Sstevel@tonic-gate main(int argc, char **argv) 777c478bd9Sstevel@tonic-gate { 787c478bd9Sstevel@tonic-gate struct bofi_errctl errctl; 797c478bd9Sstevel@tonic-gate struct bofi_get_handles get_handles; 807c478bd9Sstevel@tonic-gate int command = -1; 817c478bd9Sstevel@tonic-gate int devctl_command = -1; 827c478bd9Sstevel@tonic-gate int i; 837c478bd9Sstevel@tonic-gate int fd; 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate char buf[MAXPATHLEN]; 867c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate if (argc == 3) { 897c478bd9Sstevel@tonic-gate (void) strncpy(path, argv[1], MAXPATHLEN); 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate for (i = 0; i < CMD_TABLE_SIZE; i++) { 927c478bd9Sstevel@tonic-gate if (strcmp(argv[2], cmd_table[i].string) == NULL) { 937c478bd9Sstevel@tonic-gate command = cmd_table[i].val; 947c478bd9Sstevel@tonic-gate devctl_command = cmd_table[i].devctl_val; 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate switch (devctl_command) { 987c478bd9Sstevel@tonic-gate case BOFI_ONLINE: 997c478bd9Sstevel@tonic-gate case BOFI_OFFLINE: 1007c478bd9Sstevel@tonic-gate case BOFI_GETPATH: 1017c478bd9Sstevel@tonic-gate case BOFI_GETSTATE: 1027c478bd9Sstevel@tonic-gate break; 1037c478bd9Sstevel@tonic-gate default: 1047c478bd9Sstevel@tonic-gate if (getnameinst(argv[1], &errctl.instance, buf, 1057c478bd9Sstevel@tonic-gate MAXPATHLEN) == -1) { 1067c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1077c478bd9Sstevel@tonic-gate "th_manage - invalid path\n"); 1087c478bd9Sstevel@tonic-gate exit(1); 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate (void) strncpy(errctl.name, buf, MAXNAMELEN); 1117c478bd9Sstevel@tonic-gate errctl.namesize = strlen(errctl.name); 1127c478bd9Sstevel@tonic-gate } 1137c478bd9Sstevel@tonic-gate } else if (argc == 4) { 1147c478bd9Sstevel@tonic-gate errctl.namesize = strlen(argv[1]); 1157c478bd9Sstevel@tonic-gate (void) strncpy(errctl.name, argv[1], MAXNAMELEN); 1167c478bd9Sstevel@tonic-gate errctl.instance = atoi(argv[2]); 1177c478bd9Sstevel@tonic-gate for (i = 0; i < CMD_TABLE_SIZE; i++) { 1187c478bd9Sstevel@tonic-gate if (strcmp(argv[3], cmd_table[i].string) == NULL) { 1197c478bd9Sstevel@tonic-gate command = cmd_table[i].val; 1207c478bd9Sstevel@tonic-gate devctl_command = cmd_table[i].devctl_val; 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate switch (devctl_command) { 1247c478bd9Sstevel@tonic-gate case BOFI_ONLINE: 1257c478bd9Sstevel@tonic-gate case BOFI_OFFLINE: 1267c478bd9Sstevel@tonic-gate case BOFI_GETPATH: 1277c478bd9Sstevel@tonic-gate case BOFI_GETSTATE: 1287c478bd9Sstevel@tonic-gate (void) strcpy(path, "/devices/"); 1297c478bd9Sstevel@tonic-gate if (getpath(&path[8], errctl.instance, errctl.name, 1307c478bd9Sstevel@tonic-gate MAXPATHLEN) == -1) { 1317c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1327c478bd9Sstevel@tonic-gate "th_manage - invalid name/instance\n"); 1337c478bd9Sstevel@tonic-gate exit(1); 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate default: 1367c478bd9Sstevel@tonic-gate break; 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate } else { 1397c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "usage:\n"); 1407c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1417c478bd9Sstevel@tonic-gate " th_manage name instance state\n"); 1427c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1437c478bd9Sstevel@tonic-gate " th_manage path state\n"); 1447c478bd9Sstevel@tonic-gate exit(2); 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate if (command == -1) { 1487c478bd9Sstevel@tonic-gate /* 1497c478bd9Sstevel@tonic-gate * might have been a devctl command 1507c478bd9Sstevel@tonic-gate */ 1517c478bd9Sstevel@tonic-gate if (devctl_command == BOFI_ONLINE) { 1527c478bd9Sstevel@tonic-gate while (online_device(path) != 0) { 1537c478bd9Sstevel@tonic-gate (void) sleep(3); 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate exit(0); 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate if (devctl_command == BOFI_OFFLINE) { 1587c478bd9Sstevel@tonic-gate while (offline_device(path) != 0) { 1597c478bd9Sstevel@tonic-gate (void) sleep(3); 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate exit(0); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate if (devctl_command == BOFI_GETSTATE) { 1647c478bd9Sstevel@tonic-gate if (getstate_device(path) != 0) { 1657c478bd9Sstevel@tonic-gate perror("th_manage - getstate failed"); 1667c478bd9Sstevel@tonic-gate exit(1); 1677c478bd9Sstevel@tonic-gate } else { 1687c478bd9Sstevel@tonic-gate exit(0); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate if (devctl_command == BOFI_GETPATH) { 1727c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%s\n", path); 1737c478bd9Sstevel@tonic-gate exit(0); 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1767c478bd9Sstevel@tonic-gate "th_manage: invalid command\n"); 1777c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1787c478bd9Sstevel@tonic-gate " Command must be one of start, stop, broadcast, " 1797c478bd9Sstevel@tonic-gate "get_handles,\n"); 1807c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1817c478bd9Sstevel@tonic-gate " clear_acc_chk, clear_errors or clear_errdefs\n"); 1827c478bd9Sstevel@tonic-gate exit(2); 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate fd = open("/devices/pseudo/bofi@0:bofi,ctl", O_RDWR); 1857c478bd9Sstevel@tonic-gate if (fd == -1) { 1867c478bd9Sstevel@tonic-gate perror("th_manage - open of bofi driver"); 1877c478bd9Sstevel@tonic-gate exit(2); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate if (command == BOFI_GET_HANDLES) { 1907c478bd9Sstevel@tonic-gate get_handles.namesize = errctl.namesize; 1917c478bd9Sstevel@tonic-gate (void) strncpy(get_handles.name, errctl.name, MAXNAMELEN); 1927c478bd9Sstevel@tonic-gate get_handles.instance = errctl.instance; 1937c478bd9Sstevel@tonic-gate get_handles.buffer = buffer; 1947c478bd9Sstevel@tonic-gate get_handles.count = sizeof (buffer) - 1; 1957c478bd9Sstevel@tonic-gate if (ioctl(fd, command, &get_handles) == -1) { 1967c478bd9Sstevel@tonic-gate perror("th_manage - setting state failed"); 1977c478bd9Sstevel@tonic-gate exit(2); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate buffer[sizeof (buffer) - 1] = '\0'; 2007c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%s", buffer); 2017c478bd9Sstevel@tonic-gate (void) fflush(stdout); 2027c478bd9Sstevel@tonic-gate exit(0); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate if (errctl.instance == -1) { 2057c478bd9Sstevel@tonic-gate struct bofi_get_hdl_info hdli; 2067c478bd9Sstevel@tonic-gate struct handle_info *hip, *hp; 2077c478bd9Sstevel@tonic-gate int i, j, *instp; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate hdli.namesize = errctl.namesize; 2107c478bd9Sstevel@tonic-gate (void) strncpy(hdli.name, errctl.name, MAXNAMELEN); 2117c478bd9Sstevel@tonic-gate hdli.hdli = 0; 2127c478bd9Sstevel@tonic-gate hdli.count = 0; 2137c478bd9Sstevel@tonic-gate /* 2147c478bd9Sstevel@tonic-gate * Ask the bofi driver for all handles created by the driver 2157c478bd9Sstevel@tonic-gate * under test. 2167c478bd9Sstevel@tonic-gate */ 2177c478bd9Sstevel@tonic-gate if (ioctl(fd, BOFI_GET_HANDLE_INFO, &hdli) == -1) { 2187c478bd9Sstevel@tonic-gate perror("driver failed to return access handles"); 2197c478bd9Sstevel@tonic-gate exit(1); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate if (hdli.count == 0) { 2227c478bd9Sstevel@tonic-gate exit(0); /* no handles */ 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate if ((hip = memalign(sizeof (void *), 2257c478bd9Sstevel@tonic-gate hdli.count * sizeof (*hip))) == 0) { 2267c478bd9Sstevel@tonic-gate perror("out of memory"); 2277c478bd9Sstevel@tonic-gate exit(1); 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate hdli.hdli = (caddr_t)hip; 2307c478bd9Sstevel@tonic-gate if (ioctl(fd, BOFI_GET_HANDLE_INFO, &hdli) == -1) { 2317c478bd9Sstevel@tonic-gate perror("couldn't obtain all handles"); 2327c478bd9Sstevel@tonic-gate exit(1); 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate if ((instp = malloc((hdli.count + 1) * sizeof (*instp))) == 0) { 2357c478bd9Sstevel@tonic-gate perror("out of memory"); 2367c478bd9Sstevel@tonic-gate exit(1); 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate *instp = -1; 2397c478bd9Sstevel@tonic-gate for (i = 0, hp = hip; i < hdli.count; hp++, i++) { 2407c478bd9Sstevel@tonic-gate for (j = 0; instp[j] != -1; j++) 2417c478bd9Sstevel@tonic-gate if (hp->instance == instp[j]) 2427c478bd9Sstevel@tonic-gate break; 2437c478bd9Sstevel@tonic-gate if (instp[j] == -1) { 2447c478bd9Sstevel@tonic-gate instp[j] = hp->instance; 2457c478bd9Sstevel@tonic-gate instp[j+1] = -1; 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate for (i = 0; instp[i] != -1; i++) { 2497c478bd9Sstevel@tonic-gate errctl.instance = instp[i]; 2507c478bd9Sstevel@tonic-gate if (ioctl(fd, command, &errctl) == -1) { 2517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2527c478bd9Sstevel@tonic-gate "command failed on instance %d : %s\n", 2537c478bd9Sstevel@tonic-gate errctl.instance, strerror(errno)); 2547c478bd9Sstevel@tonic-gate exit(1); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate } else { 2587c478bd9Sstevel@tonic-gate if (ioctl(fd, command, &errctl) == -1) { 2597c478bd9Sstevel@tonic-gate perror("th_manage - setting state failed"); 2607c478bd9Sstevel@tonic-gate exit(1); 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate } 263*aeb0348bSmike_s return (0); 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* 2687c478bd9Sstevel@tonic-gate * These functions provide access to the devctl functions, 2697c478bd9Sstevel@tonic-gate */ 2707c478bd9Sstevel@tonic-gate static int 2717c478bd9Sstevel@tonic-gate online_device(char *path) 2727c478bd9Sstevel@tonic-gate { 2737c478bd9Sstevel@tonic-gate devctl_hdl_t dcp; 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate if ((dcp = devctl_device_acquire(path, 0)) == NULL) { 2767c478bd9Sstevel@tonic-gate return (-1); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate if ((devctl_device_online(dcp)) == -1) { 2797c478bd9Sstevel@tonic-gate devctl_release(dcp); 2807c478bd9Sstevel@tonic-gate return (-1); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate devctl_release(dcp); 2837c478bd9Sstevel@tonic-gate return (0); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate static int 2887c478bd9Sstevel@tonic-gate offline_device(char *path) 2897c478bd9Sstevel@tonic-gate { 2907c478bd9Sstevel@tonic-gate devctl_hdl_t dcp; 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate if ((dcp = devctl_device_acquire(path, 0)) == NULL) { 2937c478bd9Sstevel@tonic-gate return (-1); 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate if ((devctl_device_offline(dcp)) == -1) { 2967c478bd9Sstevel@tonic-gate devctl_release(dcp); 2977c478bd9Sstevel@tonic-gate return (-1); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate devctl_release(dcp); 3007c478bd9Sstevel@tonic-gate return (0); 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate static int 3047c478bd9Sstevel@tonic-gate getstate_device(char *path) 3057c478bd9Sstevel@tonic-gate { 3067c478bd9Sstevel@tonic-gate devctl_hdl_t dcp; 3077c478bd9Sstevel@tonic-gate uint_t state = 0; 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate if ((dcp = devctl_device_acquire(path, 0)) == NULL) { 3107c478bd9Sstevel@tonic-gate (void) printf("%s unknown unknown\n", path); 3117c478bd9Sstevel@tonic-gate return (-1); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate if ((devctl_device_getstate(dcp, &state)) == -1) { 3147c478bd9Sstevel@tonic-gate (void) printf("%s unknown unknown\n", path); 3157c478bd9Sstevel@tonic-gate devctl_release(dcp); 3167c478bd9Sstevel@tonic-gate return (-1); 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate devctl_release(dcp); 3197c478bd9Sstevel@tonic-gate switch (state) { 3207c478bd9Sstevel@tonic-gate case DEVICE_DOWN: 3217c478bd9Sstevel@tonic-gate (void) printf("%s down not_busy\n", path); 3227c478bd9Sstevel@tonic-gate break; 3237c478bd9Sstevel@tonic-gate case DEVICE_OFFLINE: 3247c478bd9Sstevel@tonic-gate (void) printf("%s offline not_busy\n", path); 3257c478bd9Sstevel@tonic-gate break; 3267c478bd9Sstevel@tonic-gate case DEVICE_ONLINE: 3277c478bd9Sstevel@tonic-gate (void) printf("%s online not_busy\n", path); 3287c478bd9Sstevel@tonic-gate break; 3297c478bd9Sstevel@tonic-gate case (DEVICE_ONLINE | DEVICE_BUSY): 3307c478bd9Sstevel@tonic-gate (void) printf("%s online busy\n", path); 3317c478bd9Sstevel@tonic-gate break; 3327c478bd9Sstevel@tonic-gate case (DEVICE_DOWN | DEVICE_BUSY): 3337c478bd9Sstevel@tonic-gate (void) printf("%s down busy\n", path); 3347c478bd9Sstevel@tonic-gate break; 3357c478bd9Sstevel@tonic-gate default: 3367c478bd9Sstevel@tonic-gate (void) printf("%s unknown unknown\n", path); 3377c478bd9Sstevel@tonic-gate break; 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate return (0); 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate static int 3437c478bd9Sstevel@tonic-gate getnameinst(char *path, int *instance, char *name, int namelen) 3447c478bd9Sstevel@tonic-gate { 3457c478bd9Sstevel@tonic-gate di_node_t node; 3467c478bd9Sstevel@tonic-gate char *driver_name; 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate if ((node = di_init(&path[8], DINFOSUBTREE)) == DI_NODE_NIL) 3497c478bd9Sstevel@tonic-gate return (-1); 3507c478bd9Sstevel@tonic-gate if ((driver_name = di_driver_name(node)) == NULL) { 3517c478bd9Sstevel@tonic-gate di_fini(node); 3527c478bd9Sstevel@tonic-gate return (-1); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate *instance = di_instance(node); 3557c478bd9Sstevel@tonic-gate (void) strncpy(name, driver_name, namelen); 3567c478bd9Sstevel@tonic-gate di_fini(node); 3577c478bd9Sstevel@tonic-gate return (0); 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate struct walk_arg { 3617c478bd9Sstevel@tonic-gate char *path; 3627c478bd9Sstevel@tonic-gate int instance; 3637c478bd9Sstevel@tonic-gate char name[MAXPATHLEN]; 3647c478bd9Sstevel@tonic-gate int found; 3657c478bd9Sstevel@tonic-gate int pathlen; 3667c478bd9Sstevel@tonic-gate }; 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate static int 3697c478bd9Sstevel@tonic-gate walk_callback(di_node_t node, void *arg) 3707c478bd9Sstevel@tonic-gate { 3717c478bd9Sstevel@tonic-gate struct walk_arg *warg = (struct walk_arg *)arg; 3727c478bd9Sstevel@tonic-gate char *driver_name; 3737c478bd9Sstevel@tonic-gate char *path; 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate driver_name = di_driver_name(node); 3767c478bd9Sstevel@tonic-gate if (driver_name != NULL) { 3777c478bd9Sstevel@tonic-gate if (strcmp(driver_name, warg->name) == 0 && 3787c478bd9Sstevel@tonic-gate di_instance(node) == warg->instance) { 3797c478bd9Sstevel@tonic-gate path = di_devfs_path(node); 3807c478bd9Sstevel@tonic-gate if (path != NULL) { 3817c478bd9Sstevel@tonic-gate warg->found = 1; 3827c478bd9Sstevel@tonic-gate (void) strncpy(warg->path, path, warg->pathlen); 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate return (DI_WALK_TERMINATE); 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate return (DI_WALK_CONTINUE); 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate static int 3917c478bd9Sstevel@tonic-gate getpath(char *path, int instance, char *name, int pathlen) 3927c478bd9Sstevel@tonic-gate { 3937c478bd9Sstevel@tonic-gate di_node_t node; 3947c478bd9Sstevel@tonic-gate struct walk_arg warg; 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate warg.instance = instance; 3977c478bd9Sstevel@tonic-gate (void) strncpy(warg.name, name, MAXPATHLEN); 3987c478bd9Sstevel@tonic-gate warg.path = path; 3997c478bd9Sstevel@tonic-gate warg.pathlen = pathlen; 4007c478bd9Sstevel@tonic-gate warg.found = 0; 4017c478bd9Sstevel@tonic-gate if ((node = di_init("/", DINFOSUBTREE)) == DI_NODE_NIL) 4027c478bd9Sstevel@tonic-gate return (-1); 4037c478bd9Sstevel@tonic-gate if (di_walk_node(node, DI_WALK_CLDFIRST, &warg, walk_callback) == -1) { 4047c478bd9Sstevel@tonic-gate di_fini(node); 4057c478bd9Sstevel@tonic-gate return (-1); 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate if (warg.found == 0) { 4087c478bd9Sstevel@tonic-gate di_fini(node); 4097c478bd9Sstevel@tonic-gate return (-1); 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate di_fini(node); 4127c478bd9Sstevel@tonic-gate return (0); 4137c478bd9Sstevel@tonic-gate } 414