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) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <strings.h> 26 #include <devid.h> 27 #include <pthread.h> 28 #include <inttypes.h> 29 #include <sys/dkio.h> 30 #include <sys/scsi/scsi_types.h> 31 #include <fm/topo_mod.h> 32 #include <fm/topo_list.h> 33 #include <fm/libdiskstatus.h> 34 #include <sys/fm/protocol.h> 35 #include "disk.h" 36 37 static int disk_enum(topo_mod_t *, tnode_t *, const char *, 38 topo_instance_t, topo_instance_t, void *, void *); 39 40 static const topo_modops_t disk_ops = 41 { disk_enum, NULL }; 42 43 static const topo_modinfo_t disk_info = 44 {DISK, FM_FMRI_SCHEME_HC, DISK_VERSION, &disk_ops}; 45 46 /*ARGSUSED*/ 47 static int 48 disk_enum(topo_mod_t *mod, tnode_t *baynode, 49 const char *name, topo_instance_t min, topo_instance_t max, 50 void *arg, void *notused) 51 { 52 char *device; 53 int err; 54 nvlist_t *fmri; 55 topo_list_t *dlistp = topo_mod_getspecific(mod); 56 57 if (strcmp(name, DISK) != 0) { 58 topo_mod_dprintf(mod, "disk_enum: " 59 "only know how to enumerate %s components.\n", DISK); 60 return (-1); 61 } 62 63 /* set the parent fru */ 64 if (topo_node_resource(baynode, &fmri, &err) != 0) { 65 topo_mod_dprintf(mod, "disk_enum: " 66 "topo_node_resource error %s\n", topo_strerror(err)); 67 return (-1); 68 } 69 if (topo_node_fru_set(baynode, fmri, 0, &err) != 0) { 70 topo_mod_dprintf(mod, "disk_enum: " 71 "topo_node_fru error %s\n", topo_strerror(err)); 72 nvlist_free(fmri); 73 return (-1); 74 } 75 nvlist_free(fmri); 76 77 /* 78 * For internal storage, get the path to the occupant from the 79 * binding group of the bay node 80 */ 81 if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING, 82 TOPO_BINDING_OCCUPANT, &device, &err) != 0) { 83 topo_mod_dprintf(mod, "disk_enum: " 84 "binding error %s\n", topo_strerror(err)); 85 return (-1); 86 } 87 88 89 /* locate and topo enumerate the disk with that path */ 90 err = disk_declare_path(mod, baynode, dlistp, device); 91 92 topo_mod_strfree(mod, device); 93 return (err); 94 } 95 96 /*ARGSUSED*/ 97 int 98 _topo_init(topo_mod_t *mod, topo_version_t version) 99 { 100 topo_list_t *dlistp; 101 102 /* 103 * Turn on module debugging output 104 */ 105 if (getenv("TOPODISKDEBUG") != NULL) 106 topo_mod_setdebug(mod); 107 topo_mod_dprintf(mod, "_topo_init: " 108 "initializing %s enumerator\n", DISK); 109 110 if (topo_mod_register(mod, &disk_info, TOPO_VERSION) != 0) { 111 topo_mod_dprintf(mod, "_topo_init: " 112 "%s registration failed: %s\n", DISK, topo_mod_errmsg(mod)); 113 return (-1); /* mod errno already set */ 114 } 115 116 if ((dlistp = topo_mod_zalloc(mod, sizeof (topo_list_t))) == NULL) { 117 topo_mod_dprintf(mod, "_topo_inti: failed to allocate " 118 "disk list"); 119 return (-1); 120 } 121 122 if (dev_list_gather(mod, dlistp) != 0) { 123 topo_mod_unregister(mod); 124 topo_mod_free(mod, dlistp, sizeof (topo_list_t)); 125 topo_mod_dprintf(mod, "_topo_init: " 126 "failed to locate disks"); 127 return (-1); 128 } 129 130 topo_mod_dprintf(mod, "_topo_init: " 131 "%s enumerator initialized\n", DISK); 132 133 topo_mod_setspecific(mod, dlistp); 134 135 return (0); 136 } 137 138 void 139 _topo_fini(topo_mod_t *mod) 140 { 141 topo_list_t *dlistp = topo_mod_getspecific(mod); 142 dev_list_free(mod, dlistp); 143 topo_mod_free(mod, dlistp, sizeof (topo_list_t)); 144 topo_mod_unregister(mod); 145 topo_mod_dprintf(mod, "_topo_fini: " 146 "%s enumerator uninitialized\n", DISK); 147 } 148