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.
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.
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]
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
33 #include <sys/scsi/scsi_types.h>
34 #include <fm/topo_mod.h>
35 #include <fm/topo_list.h>
36 #include <fm/libdiskstatus.h>
37 #include <sys/fm/protocol.h>
39 #include "disk_drivers.h"
41 static int disk_enum(topo_mod_t
*, tnode_t
*, const char *,
42 topo_instance_t
, topo_instance_t
, void *, void *);
44 static const topo_modops_t disk_ops
=
47 static const topo_modinfo_t disk_info
=
48 {DISK
, FM_FMRI_SCHEME_HC
, DISK_VERSION
, &disk_ops
};
51 disk_declare_driver(topo_mod_t
*mod
, tnode_t
*baynode
, topo_list_t
*dlistp
,
56 if (strcmp("mpt_sas", driver
) == 0) {
57 char *sas_address
= NULL
;
58 tnode_t
*child
= NULL
;
60 if ((err
= disk_mptsas_find_disk(mod
, baynode
,
64 err
= disk_declare_addr(mod
, baynode
, dlistp
,
66 topo_mod_strfree(mod
, sas_address
);
71 topo_mod_dprintf(mod
, "unknown disk driver '%s'\n", driver
);
77 disk_enum(topo_mod_t
*mod
, tnode_t
*baynode
,
78 const char *name
, topo_instance_t min
, topo_instance_t max
,
79 void *arg
, void *notused
)
81 char *device
, *driver
;
84 topo_list_t
*dlistp
= topo_mod_getspecific(mod
);
86 if (strcmp(name
, DISK
) != 0) {
87 topo_mod_dprintf(mod
, "disk_enum: "
88 "only know how to enumerate %s components.\n", DISK
);
92 /* set the parent fru */
93 if (topo_node_resource(baynode
, &fmri
, &err
) != 0) {
94 topo_mod_dprintf(mod
, "disk_enum: "
95 "topo_node_resource error %s\n", topo_strerror(err
));
98 if (topo_node_fru_set(baynode
, fmri
, 0, &err
) != 0) {
99 topo_mod_dprintf(mod
, "disk_enum: "
100 "topo_node_fru error %s\n", topo_strerror(err
));
107 * For internal storage, first check to see if we need to
108 * request more detail from an HBA driver.
110 if (topo_prop_get_string(baynode
, TOPO_PGROUP_BINDING
,
111 TOPO_BINDING_DRIVER
, &driver
, &err
) == 0) {
112 err
= disk_declare_driver(mod
, baynode
, dlistp
, driver
);
114 topo_mod_strfree(mod
, driver
);
116 } else if (err
!= ETOPO_PROP_NOENT
) {
117 topo_mod_dprintf(mod
, "disk_enum: "
118 "binding error %s\n", topo_strerror(err
));
123 * For internal storage, get the path to the occupant from the
124 * binding group of the bay node
126 if (topo_prop_get_string(baynode
, TOPO_PGROUP_BINDING
,
127 TOPO_BINDING_OCCUPANT
, &device
, &err
) != 0) {
128 topo_mod_dprintf(mod
, "disk_enum: "
129 "binding error %s\n", topo_strerror(err
));
134 /* locate and topo enumerate the disk with that path */
135 err
= disk_declare_path(mod
, baynode
, dlistp
, device
);
137 topo_mod_strfree(mod
, device
);
143 _topo_init(topo_mod_t
*mod
, topo_version_t version
)
148 * Turn on module debugging output
150 if (getenv("TOPODISKDEBUG") != NULL
)
151 topo_mod_setdebug(mod
);
152 topo_mod_dprintf(mod
, "_topo_init: "
153 "initializing %s enumerator\n", DISK
);
155 if (topo_mod_register(mod
, &disk_info
, TOPO_VERSION
) != 0) {
156 topo_mod_dprintf(mod
, "_topo_init: "
157 "%s registration failed: %s\n", DISK
, topo_mod_errmsg(mod
));
158 return (-1); /* mod errno already set */
161 if ((dlistp
= topo_mod_zalloc(mod
, sizeof (topo_list_t
))) == NULL
) {
162 topo_mod_dprintf(mod
, "_topo_inti: failed to allocate "
167 if (dev_list_gather(mod
, dlistp
) != 0) {
168 topo_mod_unregister(mod
);
169 topo_mod_free(mod
, dlistp
, sizeof (topo_list_t
));
170 topo_mod_dprintf(mod
, "_topo_init: "
171 "failed to locate disks");
175 topo_mod_dprintf(mod
, "_topo_init: "
176 "%s enumerator initialized\n", DISK
);
178 topo_mod_setspecific(mod
, dlistp
);
184 _topo_fini(topo_mod_t
*mod
)
186 topo_list_t
*dlistp
= topo_mod_getspecific(mod
);
187 dev_list_free(mod
, dlistp
);
188 topo_mod_free(mod
, dlistp
, sizeof (topo_list_t
));
189 topo_mod_unregister(mod
);
190 topo_mod_dprintf(mod
, "_topo_fini: "
191 "%s enumerator uninitialized\n", DISK
);