/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* PICL Ontario platform plug-in to message the SC to light
* or extinguish the hdd 'OK2RM' ready-to-service light in
* the event of a soft unconfigure or configure, respectively.
*
* Erie platforms (T1000) do not have ok-to-remove LEDs
* so they do not need handlers for the SBL events.
*/
#include <picl.h>
#include <picltree.h>
#include <picldefs.h>
#include <stdio.h>
#include <umem.h>
#include <unistd.h>
#include <libnvpair.h>
#include <strings.h>
#include <syslog.h>
#include <dlfcn.h>
#include <link.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/raidioctl.h>
#include <sys/systeminfo.h>
#include <libpcp.h>
#include "piclsbl.h"
#include "errno.h"
#pragma init(piclsbl_register)
static void *pcp_handle;
static int (* pcp_init_ptr)();
static int (* pcp_send_recv_ptr)();
static int (* pcp_close_ptr)();
static int load_pcp_libs(void);
static void piclsbl_init(void);
static void piclsbl_fini(void);
static void piclsbl_register(void);
"piclsbl",
};
/*
* called from init to load the pcp library
*/
static int
{
/* load the library and set up function pointers */
return (1);
pcp_close_ptr == NULL)
return (1);
return (0);
}
/*
* callback routine for ptree_walk_tree_by_class()
*/
static int
{
char *n;
if (status != PICL_SUCCESS) {
return (PICL_WALK_CONTINUE);
}
/* store the HBA's device path for use in check_raid() */
path);
return (PICL_WALK_TERMINATE);
}
return (PICL_WALK_CONTINUE);
}
/*
* check a target for RAID membership
*/
static int
{
int fd;
int numvols;
int i;
int j;
/*
* hba_devctl is set to the onboard hba, so it will
* always house any onboard RAID volumes
*/
return (0);
}
/*
* look up the RAID configurations for the onboard
* HBA and check target against all member targets
*/
return (0);
}
for (i = 0; i < numvols; i++) {
return (0);
}
return (1);
}
}
}
return (0);
}
/*
* Ontario SBL event handler, subscribed to:
* PICLEVENT_SYSEVENT_DEVICE_ADDED
* PICLEVENT_SYSEVENT_DEVICE_REMOVED
*/
static void
void *cookie)
{
char *devfs_path;
int target;
int channel_fd;
/*
* setup the request data to attach to the libpcp msg
*/
UMEM_DEFAULT)) == NULL)
goto sbl_return;
/*
* This plugin serves to enable or disable the blue RAS
* 'ok-to-remove' LED that is on each of the 4 disks on the
* Ontario. We catch the event via the picl handler, and
* if the event is DEVICE_ADDED for one of our onboard disks,
* then we'll be turning off the LED. Otherwise, if the event
* is DEVICE_REMOVED, then we turn it on.
*/
else
goto sbl_return;
/*
* retrieve the device's physical path from the event payload
*/
goto sbl_return;
goto sbl_return;
/*
* look for this disk in the picl tree, and if it's
* location indicates that it's one of our internal
* disks, then set sbl_id to incdicate which one.
* otherwise, return as it is not one of our disks.
*/
/* first, find the disk */
if (status != PICL_SUCCESS)
goto sbl_return;
/* now, lookup it's location in the node */
(void *)&hdd_location, PICL_PROPNAMELEN_MAX);
if (status != PICL_SUCCESS) {
goto sbl_return;
}
}
/*
* Strip off the target from the NAC name.
* The disk NAC will always be HDD#
*/
strlen(NAC_DISK_PREFIX)) == 0) {
} else {
/* this is not one of the onboard disks */
goto sbl_return;
}
/*
* check the onboard RAID configuration for this disk. if it is
* a member of a RAID and is not the RAID itself, ignore the event
*/
if (check_raid(target))
goto sbl_return;
/*
* we have the information we need, init the platform channel.
* the platform channel driver will only allow one connection
* at a time on this socket. on the offchance that more than
* one event comes in, we'll retry to initialize this connection
* up to 3 times
*/
/* failed to init; wait and retry up to 3 times */
int s = PCPINIT_TIMEOUT;
int retries = 0;
while (++retries) {
(void) sleep(s);
break;
else if (retries == 3) {
"SC channel initialization failed");
goto sbl_return;
}
/* continue */
}
}
/*
* populate the message for libpcp
*/
/*
* send the request, receive the response
*/
PCPCOMM_TIMEOUT) < 0) {
/* we either timed out or erred; either way try again */
int s = PCPCOMM_TIMEOUT;
(void) sleep(s);
PCPCOMM_TIMEOUT) < 0) {
goto sbl_return;
}
}
/*
* validate that this data was meant for us
*/
goto sbl_return;
}
/*
* verify that the LED action has taken place
*/
goto sbl_return;
}
/*
* ensure the LED action taken is the one requested
*/
"configuration");
"unconfiguration");
(*pcp_close_ptr)(channel_fd);
}
static void
piclsbl_init(void)
{
/* check for Erie platform name */
return;
/* retrieve the root node for lookups in the event handler */
return;
/* load libpcp */
if (load_pcp_libs()) {
return;
}
/*
* register piclsbl_handler for both "sysevent-device-added" and
* and for "sysevent-device-removed" PICL events
*/
}
static void
piclsbl_fini(void)
{
/* unregister the event handler */
}
static void
piclsbl_register(void)
{
}