1 4582 cth /* 2 4582 cth * CDDL HEADER START 3 4582 cth * 4 4582 cth * The contents of this file are subject to the terms of the 5 4582 cth * Common Development and Distribution License (the "License"). 6 4582 cth * You may not use this file except in compliance with the License. 7 4582 cth * 8 4582 cth * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 4582 cth * or http://www.opensolaris.org/os/licensing. 10 4582 cth * See the License for the specific language governing permissions 11 4582 cth * and limitations under the License. 12 4582 cth * 13 4582 cth * When distributing Covered Code, include this CDDL HEADER in each 14 4582 cth * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 4582 cth * If applicable, add the following below this CDDL HEADER, with the 16 4582 cth * fields enclosed by brackets "[]" replaced with your own identifying 17 4582 cth * information: Portions Copyright [yyyy] [name of copyright owner] 18 4582 cth * 19 4582 cth * CDDL HEADER END 20 4582 cth */ 21 4582 cth /* 22 6640 cth * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 4582 cth * Use is subject to license terms. 24 4582 cth */ 25 4582 cth #pragma ident "%Z%%M% %I% %E% SMI" 26 4582 cth 27 4582 cth #include <strings.h> 28 4582 cth #include <devid.h> 29 4582 cth #include <pthread.h> 30 4582 cth #include <inttypes.h> 31 4582 cth #include <sys/dkio.h> 32 4582 cth #include <sys/scsi/scsi_types.h> 33 4582 cth #include <fm/topo_mod.h> 34 4582 cth #include <fm/topo_list.h> 35 4582 cth #include <fm/libdiskstatus.h> 36 4582 cth #include <sys/fm/protocol.h> 37 4582 cth #include "disk.h" 38 4582 cth 39 4582 cth static int disk_enum(topo_mod_t *, tnode_t *, const char *, 40 4582 cth topo_instance_t, topo_instance_t, void *, void *); 41 4582 cth 42 4582 cth static const topo_modops_t disk_ops = 43 4582 cth { disk_enum, NULL }; 44 4582 cth 45 6640 cth static const topo_modinfo_t disk_info = 46 4582 cth {DISK, FM_FMRI_SCHEME_HC, DISK_VERSION, &disk_ops}; 47 4582 cth 48 6640 cth /*ARGSUSED*/ 49 6640 cth static int 50 6640 cth disk_enum(topo_mod_t *mod, tnode_t *baynode, 51 6640 cth const char *name, topo_instance_t min, topo_instance_t max, 52 6640 cth void *arg, void *notused) 53 6640 cth { 54 6640 cth char *device; 55 6640 cth int err; 56 6640 cth nvlist_t *fmri; 57 6640 cth topo_list_t *dlistp = topo_mod_getspecific(mod); 58 4582 cth 59 6640 cth if (strcmp(name, DISK) != 0) { 60 6640 cth topo_mod_dprintf(mod, "disk_enum: " 61 6640 cth "only know how to enumerate %s components.\n", DISK); 62 6640 cth return (-1); 63 4582 cth } 64 4582 cth 65 4582 cth /* set the parent fru */ 66 6640 cth if (topo_node_resource(baynode, &fmri, &err) != 0) { 67 6640 cth topo_mod_dprintf(mod, "disk_enum: " 68 6640 cth "topo_node_resource error %s\n", topo_strerror(err)); 69 6640 cth return (-1); 70 4582 cth } 71 6640 cth if (topo_node_fru_set(baynode, fmri, 0, &err) != 0) { 72 6640 cth topo_mod_dprintf(mod, "disk_enum: " 73 6640 cth "topo_node_fru error %s\n", topo_strerror(err)); 74 4582 cth nvlist_free(fmri); 75 6640 cth return (-1); 76 4582 cth } 77 4582 cth nvlist_free(fmri); 78 4582 cth 79 6640 cth /* 80 6640 cth * For internal storage, get the path to the occupant from the 81 6640 cth * binding group of the bay node 82 6640 cth */ 83 6640 cth if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING, 84 6640 cth TOPO_BINDING_OCCUPANT, &device, &err) != 0) { 85 6640 cth topo_mod_dprintf(mod, "disk_enum: " 86 6640 cth "binding error %s\n", topo_strerror(err)); 87 4582 cth return (-1); 88 4582 cth } 89 4582 cth 90 4582 cth 91 6640 cth /* locate and topo enumerate the disk with that path */ 92 6640 cth err = disk_declare_path(mod, baynode, dlistp, device); 93 4582 cth 94 4582 cth topo_mod_strfree(mod, device); 95 6640 cth return (err); 96 4582 cth } 97 4582 cth 98 4582 cth /*ARGSUSED*/ 99 4582 cth int 100 4582 cth _topo_init(topo_mod_t *mod, topo_version_t version) 101 4582 cth { 102 6640 cth topo_list_t *dlistp; 103 4582 cth 104 4582 cth /* 105 4582 cth * Turn on module debugging output 106 4582 cth */ 107 4582 cth if (getenv("TOPODISKDEBUG") != NULL) 108 4582 cth topo_mod_setdebug(mod); 109 6640 cth topo_mod_dprintf(mod, "_topo_init: " 110 6640 cth "initializing %s enumerator\n", DISK); 111 4582 cth 112 4582 cth if (topo_mod_register(mod, &disk_info, TOPO_VERSION) != 0) { 113 6640 cth topo_mod_dprintf(mod, "_topo_init: " 114 6640 cth "%s registration failed: %s\n", DISK, topo_mod_errmsg(mod)); 115 6640 cth return (-1); /* mod errno already set */ 116 4582 cth } 117 4582 cth 118 6640 cth if ((dlistp = topo_mod_zalloc(mod, sizeof (topo_list_t))) == NULL) { 119 6640 cth topo_mod_dprintf(mod, "_topo_inti: failed to allocate " 120 6640 cth "disk list"); 121 4582 cth return (-1); 122 4582 cth } 123 6640 cth 124 6640 cth if (disk_list_gather(mod, dlistp) != 0) { 125 4582 cth topo_mod_unregister(mod); 126 6640 cth topo_mod_free(mod, dlistp, sizeof (topo_list_t)); 127 6640 cth topo_mod_dprintf(mod, "_topo_init: " 128 6640 cth "failed to locate disks"); 129 4582 cth return (-1); 130 4582 cth } 131 4582 cth 132 6640 cth topo_mod_dprintf(mod, "_topo_init: " 133 6640 cth "%s enumerator initialized\n", DISK); 134 4582 cth 135 6640 cth topo_mod_setspecific(mod, dlistp); 136 4582 cth 137 4582 cth return (0); 138 4582 cth } 139 4582 cth 140 4582 cth void 141 4582 cth _topo_fini(topo_mod_t *mod) 142 4582 cth { 143 6640 cth topo_list_t *dlistp = topo_mod_getspecific(mod); 144 6640 cth disk_list_free(mod, dlistp); 145 6640 cth topo_mod_free(mod, dlistp, sizeof (topo_list_t)); 146 4582 cth topo_mod_unregister(mod); 147 6640 cth topo_mod_dprintf(mod, "_topo_fini: " 148 6640 cth "%s enumerator uninitialized\n", DISK); 149 4582 cth } 150