103f9f63dSTom Pothier /*
203f9f63dSTom Pothier * CDDL HEADER START
303f9f63dSTom Pothier *
403f9f63dSTom Pothier * The contents of this file are subject to the terms of the
503f9f63dSTom Pothier * Common Development and Distribution License (the "License").
603f9f63dSTom Pothier * You may not use this file except in compliance with the License.
703f9f63dSTom Pothier *
803f9f63dSTom Pothier * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
903f9f63dSTom Pothier * or http://www.opensolaris.org/os/licensing.
1003f9f63dSTom Pothier * See the License for the specific language governing permissions
1103f9f63dSTom Pothier * and limitations under the License.
1203f9f63dSTom Pothier *
1303f9f63dSTom Pothier * When distributing Covered Code, include this CDDL HEADER in each
1403f9f63dSTom Pothier * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1503f9f63dSTom Pothier * If applicable, add the following below this CDDL HEADER, with the
1603f9f63dSTom Pothier * fields enclosed by brackets "[]" replaced with your own identifying
1703f9f63dSTom Pothier * information: Portions Copyright [yyyy] [name of copyright owner]
1803f9f63dSTom Pothier *
1903f9f63dSTom Pothier * CDDL HEADER END
2003f9f63dSTom Pothier */
2103f9f63dSTom Pothier
2203f9f63dSTom Pothier /*
23efd31e1dSTrang Do * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
248abca89fSRob Johnston * Copyright (c) 2019, Joyent, Inc.
2503f9f63dSTom Pothier */
2603f9f63dSTom Pothier
2703f9f63dSTom Pothier /*
2803f9f63dSTom Pothier * Create bay topology node from SMBIOS Type 136 structure, call the disk
2903f9f63dSTom Pothier * enumerator to enumerate a SATA direct attached disk.
3003f9f63dSTom Pothier */
3103f9f63dSTom Pothier
3203f9f63dSTom Pothier #include <sys/types.h>
3303f9f63dSTom Pothier #include <strings.h>
3403f9f63dSTom Pothier #include <fm/topo_mod.h>
358abca89fSRob Johnston #include <fm/topo_method.h>
3603f9f63dSTom Pothier #include <fm/topo_hc.h>
3703f9f63dSTom Pothier #include <sys/systeminfo.h>
3803f9f63dSTom Pothier #include <sys/smbios_impl.h>
3903f9f63dSTom Pothier #include <x86pi_impl.h>
4003f9f63dSTom Pothier
4103f9f63dSTom Pothier #define DEVICES "/devices"
4203f9f63dSTom Pothier #define HBA_DRV_NAME "ahci"
4303f9f63dSTom Pothier
4403f9f63dSTom Pothier #define BDF(b, df) ((uint16_t)((((uint16_t)(b) << 8) & 0xFF00) | \
4503f9f63dSTom Pothier ((uint16_t)(df) & 0x00FF)));
4603f9f63dSTom Pothier
4703f9f63dSTom Pothier static const topo_pgroup_info_t io_pgroup = {
4803f9f63dSTom Pothier TOPO_PGROUP_IO,
4903f9f63dSTom Pothier TOPO_STABILITY_PRIVATE,
5003f9f63dSTom Pothier TOPO_STABILITY_PRIVATE,
5103f9f63dSTom Pothier 1
5203f9f63dSTom Pothier };
5303f9f63dSTom Pothier
5403f9f63dSTom Pothier static const topo_pgroup_info_t binding_pgroup = {
5503f9f63dSTom Pothier TOPO_PGROUP_BINDING,
5603f9f63dSTom Pothier TOPO_STABILITY_PRIVATE,
5703f9f63dSTom Pothier TOPO_STABILITY_PRIVATE,
5803f9f63dSTom Pothier 1
5903f9f63dSTom Pothier };
6003f9f63dSTom Pothier
618abca89fSRob Johnston static const topo_method_t bay_methods[] = {
628abca89fSRob Johnston { TOPO_METH_OCCUPIED, TOPO_METH_OCCUPIED_DESC,
638abca89fSRob Johnston TOPO_METH_OCCUPIED_VERSION, TOPO_STABILITY_INTERNAL,
648abca89fSRob Johnston topo_mod_hc_occupied },
658abca89fSRob Johnston { NULL }
668abca89fSRob Johnston };
678abca89fSRob Johnston
6803f9f63dSTom Pothier /*
6903f9f63dSTom Pothier * Return PCI Bus/Dev/Func
7003f9f63dSTom Pothier */
7103f9f63dSTom Pothier int
bay_bdf(topo_mod_t * mod,smbios_port_ext_t * epp,uint16_t * bdf)72efd31e1dSTrang Do bay_bdf(topo_mod_t *mod, smbios_port_ext_t *epp, uint16_t *bdf)
7303f9f63dSTom Pothier {
7403f9f63dSTom Pothier int devt;
7503f9f63dSTom Pothier id_t dev_id;
7603f9f63dSTom Pothier uint8_t bus, dev_funct;
7703f9f63dSTom Pothier
7803f9f63dSTom Pothier char *f = "bay_bdf";
79efd31e1dSTrang Do smbios_hdl_t *shp;
8003f9f63dSTom Pothier
81efd31e1dSTrang Do shp = topo_mod_smbios(mod);
82efd31e1dSTrang Do if (shp == NULL) {
83efd31e1dSTrang Do topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f);
84efd31e1dSTrang Do return (-1);
85efd31e1dSTrang Do }
8603f9f63dSTom Pothier /*
8703f9f63dSTom Pothier * Depending on device type, BDF comes from either slot (type-9) or
8803f9f63dSTom Pothier * on-board (type-41) SMBIOS structure.
8903f9f63dSTom Pothier */
9003f9f63dSTom Pothier devt = epp->smbporte_dtype;
9103f9f63dSTom Pothier dev_id = epp->smbporte_devhdl;
9203f9f63dSTom Pothier
9303f9f63dSTom Pothier if (devt == SMB_TYPE_SLOT) {
9403f9f63dSTom Pothier smbios_slot_t slot;
9503f9f63dSTom Pothier (void) smbios_info_slot(shp, dev_id, &slot);
9603f9f63dSTom Pothier bus = slot.smbl_bus;
9703f9f63dSTom Pothier dev_funct = slot.smbl_df;
9803f9f63dSTom Pothier } else if (devt == SMB_TYPE_OBDEVEXT) {
9903f9f63dSTom Pothier smbios_obdev_ext_t ob;
10003f9f63dSTom Pothier (void) smbios_info_obdevs_ext(shp, dev_id, &ob);
10103f9f63dSTom Pothier bus = ob.smboe_bus;
10203f9f63dSTom Pothier dev_funct = ob.smboe_df;
10303f9f63dSTom Pothier } else {
10403f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: unknown device type: %d\n",
10503f9f63dSTom Pothier f, devt);
10603f9f63dSTom Pothier return (-1);
10703f9f63dSTom Pothier }
10803f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: %s: bus(0x%02x) dev/func(0x%02x)\n", f,
10903f9f63dSTom Pothier devt == SMB_TYPE_SLOT ? "slot" : "ob dev", bus, dev_funct);
11003f9f63dSTom Pothier
11103f9f63dSTom Pothier *bdf = BDF(bus, dev_funct);
11203f9f63dSTom Pothier
11303f9f63dSTom Pothier return (0);
11403f9f63dSTom Pothier }
11503f9f63dSTom Pothier
11603f9f63dSTom Pothier /*
11703f9f63dSTom Pothier * Decorate topo node with pgroups.
11803f9f63dSTom Pothier */
11903f9f63dSTom Pothier int
bay_pgroups(topo_mod_t * mod,tnode_t * tnp,di_node_t * dnp,di_node_t * sibp,char * minor_name)12003f9f63dSTom Pothier bay_pgroups(topo_mod_t *mod, tnode_t *tnp, di_node_t *dnp, di_node_t *sibp,
12103f9f63dSTom Pothier char *minor_name)
12203f9f63dSTom Pothier {
12303f9f63dSTom Pothier int rv, err;
12403f9f63dSTom Pothier char *ap_path, *oc_path;
12503f9f63dSTom Pothier
12603f9f63dSTom Pothier char *f = "bay_pgoups";
12703f9f63dSTom Pothier
12803f9f63dSTom Pothier /*
12903f9f63dSTom Pothier * Create "io" pgroup and attachment point path.
13003f9f63dSTom Pothier */
13103f9f63dSTom Pothier rv = topo_pgroup_create(tnp, &io_pgroup, &err);
13203f9f63dSTom Pothier if (rv != 0) {
13303f9f63dSTom Pothier topo_mod_dprintf(mod,
13403f9f63dSTom Pothier "%s: failed to create \"io\" pgroup: %s\n",
13503f9f63dSTom Pothier f, topo_strerror(err));
13603f9f63dSTom Pothier (void) topo_mod_seterrno(mod, err);
13703f9f63dSTom Pothier return (err);
13803f9f63dSTom Pothier }
13903f9f63dSTom Pothier
14003f9f63dSTom Pothier ap_path = topo_mod_alloc(mod, MAXPATHLEN);
14103f9f63dSTom Pothier if (ap_path == NULL) {
142*6597d6fcSRobert Mustacchi topo_mod_dprintf(mod, "%s: ap_path alloc failed\n", f);
14303f9f63dSTom Pothier return (topo_mod_seterrno(mod, EMOD_NOMEM));
14403f9f63dSTom Pothier }
14503f9f63dSTom Pothier (void) snprintf(ap_path, MAXPATHLEN, "%s%s:%s", DEVICES,
14603f9f63dSTom Pothier di_devfs_path(*dnp), minor_name);
14703f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: ap_path(%s)\n", f, ap_path);
14803f9f63dSTom Pothier
14903f9f63dSTom Pothier /* add ap-path */
15003f9f63dSTom Pothier rv = topo_prop_set_string(tnp, TOPO_PGROUP_IO, TOPO_IO_AP_PATH,
15103f9f63dSTom Pothier TOPO_PROP_IMMUTABLE, ap_path, &err);
15203f9f63dSTom Pothier if (rv != 0) {
15303f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: failed to set ap-path: %s\n",
15403f9f63dSTom Pothier f, topo_strerror(err));
15503f9f63dSTom Pothier topo_mod_free(mod, ap_path, MAXPATHLEN);
15603f9f63dSTom Pothier (void) topo_mod_seterrno(mod, err);
15703f9f63dSTom Pothier return (err);
15803f9f63dSTom Pothier }
15903f9f63dSTom Pothier topo_mod_free(mod, ap_path, MAXPATHLEN);
16003f9f63dSTom Pothier
16103f9f63dSTom Pothier /*
16203f9f63dSTom Pothier * Create "binding" pgroup and occupant path.
16303f9f63dSTom Pothier */
16403f9f63dSTom Pothier rv = topo_pgroup_create(tnp, &binding_pgroup, &err);
16503f9f63dSTom Pothier if (rv != 0) {
16603f9f63dSTom Pothier topo_mod_dprintf(mod,
16703f9f63dSTom Pothier "%s: failed to create \"io\" pgroup: %s\n",
16803f9f63dSTom Pothier f, topo_strerror(err));
16903f9f63dSTom Pothier (void) topo_mod_seterrno(mod, err);
17003f9f63dSTom Pothier return (err);
17103f9f63dSTom Pothier }
17203f9f63dSTom Pothier
17303f9f63dSTom Pothier oc_path = di_devfs_path(*sibp);
17403f9f63dSTom Pothier if (oc_path == NULL) {
17503f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: no occupant path\n", f);
17603f9f63dSTom Pothier return (-1);
17703f9f63dSTom Pothier }
17803f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: oc_path(%s)\n", f, oc_path);
17903f9f63dSTom Pothier
18003f9f63dSTom Pothier /* add ocupant-path */
18103f9f63dSTom Pothier rv = topo_prop_set_string(tnp, TOPO_PGROUP_BINDING,
18203f9f63dSTom Pothier TOPO_BINDING_OCCUPANT, TOPO_PROP_IMMUTABLE, oc_path,
18303f9f63dSTom Pothier &err);
18403f9f63dSTom Pothier if (rv != 0) {
18503f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: failed to set ap-path: %s\n",
18603f9f63dSTom Pothier f, topo_strerror(err));
18703f9f63dSTom Pothier di_devfs_path_free(oc_path);
18803f9f63dSTom Pothier (void) topo_mod_seterrno(mod, err);
18903f9f63dSTom Pothier return (err);
19003f9f63dSTom Pothier }
19103f9f63dSTom Pothier di_devfs_path_free(oc_path);
19203f9f63dSTom Pothier
19303f9f63dSTom Pothier return (0);
19403f9f63dSTom Pothier }
19503f9f63dSTom Pothier
19603f9f63dSTom Pothier int
bay_update_tnode(topo_mod_t * mod,tnode_t * tnodep,uint16_t bdf,int phy)19703f9f63dSTom Pothier bay_update_tnode(topo_mod_t *mod, tnode_t *tnodep, uint16_t bdf, int phy)
19803f9f63dSTom Pothier {
19903f9f63dSTom Pothier int rv;
20003f9f63dSTom Pothier int minor_cnt = 0;
20103f9f63dSTom Pothier char *minor_name = NULL;
20203f9f63dSTom Pothier di_node_t devtree, dnode, sib;
20303f9f63dSTom Pothier di_minor_t minor = DI_MINOR_NIL;
20403f9f63dSTom Pothier
20503f9f63dSTom Pothier char *f = "bay_update_tnode";
20603f9f63dSTom Pothier
20703f9f63dSTom Pothier /*
20803f9f63dSTom Pothier * Find HBA device node from BDF.
20903f9f63dSTom Pothier */
21003f9f63dSTom Pothier devtree = topo_mod_devinfo(mod);
21103f9f63dSTom Pothier if (devtree == DI_NODE_NIL) {
21203f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: failed to get dev tree\n", f);
21303f9f63dSTom Pothier return (-1);
21403f9f63dSTom Pothier }
21503f9f63dSTom Pothier for (dnode = di_drv_first_node(HBA_DRV_NAME, devtree);
21603f9f63dSTom Pothier dnode != DI_NODE_NIL;
21703f9f63dSTom Pothier dnode = di_drv_next_node(dnode)) {
21803f9f63dSTom Pothier if (bdf == x86pi_bdf(mod, dnode)) {
21903f9f63dSTom Pothier /*
22003f9f63dSTom Pothier * Match child node from PHY.
22103f9f63dSTom Pothier */
22203f9f63dSTom Pothier sib = di_child_node(dnode);
22303f9f63dSTom Pothier while (sib != DI_NODE_NIL) {
22403f9f63dSTom Pothier if (phy == x86pi_phy(mod, sib))
22503f9f63dSTom Pothier break;
22603f9f63dSTom Pothier sib = di_sibling_node(sib);
22703f9f63dSTom Pothier }
22803f9f63dSTom Pothier break;
22903f9f63dSTom Pothier }
23003f9f63dSTom Pothier }
23103f9f63dSTom Pothier if (dnode == DI_NODE_NIL) {
23203f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: no HBA di_node\n", f);
23303f9f63dSTom Pothier return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
23403f9f63dSTom Pothier }
23503f9f63dSTom Pothier
23603f9f63dSTom Pothier /*
23703f9f63dSTom Pothier * HBA attachment point minor node name.
23803f9f63dSTom Pothier */
23903f9f63dSTom Pothier while ((minor = di_minor_next(dnode, minor)) != DI_MINOR_NIL) {
24003f9f63dSTom Pothier if (strncmp(DDI_NT_SATA_ATTACHMENT_POINT,
24103f9f63dSTom Pothier di_minor_nodetype(minor),
24203f9f63dSTom Pothier strlen(DDI_NT_SATA_ATTACHMENT_POINT)) == 0) {
24303f9f63dSTom Pothier if (phy == minor_cnt++) {
24403f9f63dSTom Pothier minor_name = di_minor_name(minor);
24503f9f63dSTom Pothier topo_mod_dprintf(mod,
24603f9f63dSTom Pothier "%s: phy(%d) minor name(%s)\n",
24703f9f63dSTom Pothier f, phy, minor_name);
24803f9f63dSTom Pothier break;
24903f9f63dSTom Pothier }
25003f9f63dSTom Pothier }
25103f9f63dSTom Pothier }
25203f9f63dSTom Pothier
25303f9f63dSTom Pothier rv = bay_pgroups(mod, tnodep, &dnode, &sib, minor_name);
25403f9f63dSTom Pothier if (rv != 0) {
25503f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: failed to add pgroups\n", f);
25603f9f63dSTom Pothier return (-1);
25703f9f63dSTom Pothier }
25803f9f63dSTom Pothier
25903f9f63dSTom Pothier
26003f9f63dSTom Pothier return (0);
26103f9f63dSTom Pothier }
26203f9f63dSTom Pothier
26303f9f63dSTom Pothier /*
26403f9f63dSTom Pothier * x86pi_gen_bay:
26503f9f63dSTom Pothier * create "bay" node
26603f9f63dSTom Pothier * call "disk" enum passing in "bay" node
26703f9f63dSTom Pothier */
26803f9f63dSTom Pothier int
x86pi_gen_bay(topo_mod_t * mod,tnode_t * t_parent,smbios_port_ext_t * eport,int instance)269efd31e1dSTrang Do x86pi_gen_bay(topo_mod_t *mod, tnode_t *t_parent, smbios_port_ext_t *eport,
270efd31e1dSTrang Do int instance)
27103f9f63dSTom Pothier {
27203f9f63dSTom Pothier int rv;
27303f9f63dSTom Pothier int min = 0, max = 0;
27403f9f63dSTom Pothier id_t port_id;
27503f9f63dSTom Pothier uint16_t bdf;
27603f9f63dSTom Pothier smbios_port_t smb_port;
27703f9f63dSTom Pothier x86pi_hcfmri_t hcfmri = {0};
27803f9f63dSTom Pothier tnode_t *tn_bay;
27903f9f63dSTom Pothier
28003f9f63dSTom Pothier char *f = "x86pi_gen_disk";
281efd31e1dSTrang Do smbios_hdl_t *shp;
282efd31e1dSTrang Do
283efd31e1dSTrang Do shp = topo_mod_smbios(mod);
284efd31e1dSTrang Do if (shp == NULL) {
285efd31e1dSTrang Do topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f);
286efd31e1dSTrang Do return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
287efd31e1dSTrang Do }
28803f9f63dSTom Pothier
28903f9f63dSTom Pothier /*
29003f9f63dSTom Pothier * Label comes from the port (type-8) SMBIOS structure.
29103f9f63dSTom Pothier */
29203f9f63dSTom Pothier port_id = eport->smbporte_port;
29303f9f63dSTom Pothier
29403f9f63dSTom Pothier rv = smbios_info_port(shp, port_id, &smb_port);
29503f9f63dSTom Pothier if (rv != 0) {
29603f9f63dSTom Pothier topo_mod_dprintf(mod,
297*6597d6fcSRobert Mustacchi "%s: failed to get port %ld SMBIOS struct\n",
29803f9f63dSTom Pothier f, port_id);
29903f9f63dSTom Pothier return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
30003f9f63dSTom Pothier }
30103f9f63dSTom Pothier
30203f9f63dSTom Pothier /*
30303f9f63dSTom Pothier * Fill in hcfmri info.
30403f9f63dSTom Pothier */
30503f9f63dSTom Pothier hcfmri.hc_name = BAY;
30603f9f63dSTom Pothier hcfmri.instance = instance;
30703f9f63dSTom Pothier hcfmri.location = x86pi_cleanup_smbios_str(mod, smb_port.smbo_eref, 0);
30803f9f63dSTom Pothier
30903f9f63dSTom Pothier /*
31003f9f63dSTom Pothier * Create "bay" node.
31103f9f63dSTom Pothier */
31203f9f63dSTom Pothier rv = x86pi_enum_generic(mod, &hcfmri, t_parent, t_parent, &tn_bay, 0);
31303f9f63dSTom Pothier if (rv != 0) {
31403f9f63dSTom Pothier topo_mod_dprintf(mod,
31503f9f63dSTom Pothier "%s: failed to create %s topo node: %d\n",
31603f9f63dSTom Pothier f, BAY, instance);
31703f9f63dSTom Pothier return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
31803f9f63dSTom Pothier }
31903f9f63dSTom Pothier
32003f9f63dSTom Pothier /* free up location string */
32103f9f63dSTom Pothier if (hcfmri.location != NULL) {
32203f9f63dSTom Pothier topo_mod_strfree(mod, (char *)hcfmri.location);
32303f9f63dSTom Pothier }
32403f9f63dSTom Pothier
32503f9f63dSTom Pothier /*
32603f9f63dSTom Pothier * Determine the bay BDF.
32703f9f63dSTom Pothier */
328efd31e1dSTrang Do rv = bay_bdf(mod, eport, &bdf);
32903f9f63dSTom Pothier if (rv != 0) {
33003f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: failed to get BDF\n", f);
33103f9f63dSTom Pothier return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
33203f9f63dSTom Pothier }
33303f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: BDF(0x%04x)\n", f, bdf);
33403f9f63dSTom Pothier
33503f9f63dSTom Pothier /*
33603f9f63dSTom Pothier * Decorate bay topo node.
33703f9f63dSTom Pothier */
33803f9f63dSTom Pothier rv = bay_update_tnode(mod, tn_bay, bdf, eport->smbporte_phy);
33903f9f63dSTom Pothier if (rv != 0) {
34003f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: failed to decorate bay node\n", f);
34103f9f63dSTom Pothier return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
34203f9f63dSTom Pothier }
34303f9f63dSTom Pothier
3448abca89fSRob Johnston if (topo_method_register(mod, tn_bay, bay_methods) != 0) {
3458abca89fSRob Johnston topo_mod_dprintf(mod, "topo_method_register() failed on "
3468abca89fSRob Johnston "%s=%d: %s", BAY, instance,
3478abca89fSRob Johnston topo_mod_errmsg(mod));
3488abca89fSRob Johnston /* errno set */
3498abca89fSRob Johnston return (-1);
3508abca89fSRob Johnston }
3518abca89fSRob Johnston
35203f9f63dSTom Pothier /*
35303f9f63dSTom Pothier * Call disk enum passing in decorated bay topo node.
35403f9f63dSTom Pothier */
35503f9f63dSTom Pothier if (topo_mod_load(mod, DISK, TOPO_VERSION) == NULL) {
35603f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: Failed to load %s module: %s\n",
35703f9f63dSTom Pothier f, DISK, topo_strerror(topo_mod_errno(mod)));
35803f9f63dSTom Pothier return (topo_mod_errno(mod));
35903f9f63dSTom Pothier }
36003f9f63dSTom Pothier
36103f9f63dSTom Pothier rv = topo_node_range_create(mod, tn_bay, DISK, min, max);
36203f9f63dSTom Pothier if (rv != 0) {
36303f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: failed to create range: %s\n", f,
36403f9f63dSTom Pothier topo_strerror(topo_mod_errno(mod)));
36503f9f63dSTom Pothier return (topo_mod_errno(mod));
36603f9f63dSTom Pothier }
36703f9f63dSTom Pothier
36803f9f63dSTom Pothier rv = topo_mod_enumerate(mod, tn_bay, DISK, DISK, min, max, NULL);
36903f9f63dSTom Pothier if (rv != 0) {
37003f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: %s enumeration failed: %s\n", f,
37103f9f63dSTom Pothier DISK, topo_strerror(topo_mod_errno(mod)));
37203f9f63dSTom Pothier return (topo_mod_errno(mod));
37303f9f63dSTom Pothier }
37403f9f63dSTom Pothier
37503f9f63dSTom Pothier topo_mod_dprintf(mod, "%s: done.\n", f);
37603f9f63dSTom Pothier
37703f9f63dSTom Pothier return (0);
37803f9f63dSTom Pothier }
379