2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
12 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
16 #include <sys/types.h>
24 #include <fm/topo_mod.h>
25 #include <fm/topo_list.h>
27 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
28 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
29 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
30 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
33 #include "disk_drivers.h"
36 get_sas_address(topo_mod_t
*mod
, char *devctl
, uint32_t enclosure
,
37 uint32_t slot
, char **sas_address
)
40 mptsas_get_disk_info_t gdi
;
41 mptsas_disk_info_t
*di
;
44 bzero(&gdi
, sizeof (gdi
));
46 if ((fd
= open(devctl
, O_RDWR
)) == -1) {
47 topo_mod_dprintf(mod
, "could not open '%s' for ioctl: %s\n",
48 devctl
, strerror(errno
));
52 if (ioctl(fd
, MPTIOCTL_GET_DISK_INFO
, &gdi
) == -1) {
53 topo_mod_dprintf(mod
, "ioctl 1 on '%s' failed: %s\n", devctl
,
59 gdi
.DiskInfoArraySize
= disz
= sizeof (mptsas_disk_info_t
) *
61 gdi
.PtrDiskInfoArray
= di
= topo_mod_alloc(mod
, disz
);
63 topo_mod_dprintf(mod
, "memory allocation failed\n");
68 if (ioctl(fd
, MPTIOCTL_GET_DISK_INFO
, &gdi
) == -1) {
69 topo_mod_dprintf(mod
, "ioctl 2 on '%s' failed: %s\n", devctl
,
71 topo_mod_free(mod
, di
, disz
);
77 for (i
= 0; i
< gdi
.DiskCount
; i
++) {
78 if (di
[i
].Enclosure
== enclosure
&& di
[i
].Slot
== slot
) {
79 char sas
[17]; /* 16 hex digits and NUL */
80 (void) snprintf(sas
, 17, "%llx", di
[i
].SasAddress
);
81 topo_mod_dprintf(mod
, "found mpt_sas disk (%d/%d) "
82 "with adddress %s\n", enclosure
, slot
, sas
);
83 *sas_address
= topo_mod_strdup(mod
, sas
);
89 topo_mod_free(mod
, di
, disz
);
95 disk_mptsas_find_disk(topo_mod_t
*mod
, tnode_t
*baynode
, char **sas_address
)
98 uint32_t enclosure
, slot
;
102 * Get the required properties from the node. These come from
103 * the static XML mapping.
105 if (topo_prop_get_string(baynode
, TOPO_PGROUP_BINDING
,
106 TOPO_BINDING_DEVCTL
, &devctl
, &err
) != 0 ||
107 topo_prop_get_uint32(baynode
, TOPO_PGROUP_BINDING
,
108 TOPO_BINDING_ENCLOSURE
, &enclosure
, &err
) != 0 ||
109 topo_prop_get_uint32(baynode
, TOPO_PGROUP_BINDING
,
110 TOPO_BINDING_SLOT
, &slot
, &err
) != 0) {
112 topo_mod_strfree(mod
, devctl
);
113 topo_mod_dprintf(mod
, "bay node was missing mpt_sas binding "
118 return (get_sas_address(mod
, devctl
, enclosure
, slot
, sas_address
));