/**
* $Id: k10sensor_link.c 743 2012-06-18 06:10:35Z elkner $
*
* * 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
* http://www.opensolaris.org/os/licensing.
* 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.
* 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]
*
* All Rights reserved.
* CDDL HEADER END
*/
/*
* Copyright (c) 2012 by Jens Elkner,
* Otto-von-Guericke Universitaet Magdeburg. All rights reserved.
*/
/*
* Admins like to just 'cat /dev/$device/$xy' and get all related info -
* no need for extra utils or to keep more garbage in their head ;-)
*/
#include <strings.h>
#include <stdio.h>
#include <sys/dtrace.h>
#ifdef HAVE_DEVFSADM_H
#include <devfsadm.h>
#else
/* duplicate required stuff from usr/src/cmd/devfsadm/devfsadm.h */
#include <libdevinfo.h>
typedef struct devfsadm_create {
char *device_class; /* eg "disk", "tape", "display" */
char *node_type; /* eg DDI_NT_TAPE, DDI_NT_BLOCK, etc */
char *drv_name; /* eg sd, ssd */
int flags; /* TYPE_{EXACT,RE,PARTIAL}, DRV_{EXACT,RE} */
int interpose_lvl; /* eg ILEVEL_0.. ILEVEL_10 */
int (*callback_fcn)(di_minor_t minor, di_node_t node);
} devfsadm_create_t;
typedef struct _devfsadm_create_reg {
uint_t version;
uint_t count; /* number of node type registration */
/* structures */
devfsadm_create_t *tblp;
} _devfsadm_create_reg_t;
#define ILEVEL_0 0
#define TYPE_EXACT 0x01
#define DEVFSADM_V0 0
#define DEVFSADM_CONTINUE 0
#define DEVFSADM_TERMINATE 1
#define DEVFSADM_CREATE_INIT_V0(tbl) \
_devfsadm_create_reg_t _devfsadm_create_reg = { \
DEVFSADM_V0, (sizeof (tbl) / sizeof (devfsadm_create_t)), \
((devfsadm_create_t *)(tbl)) \
}
#endif
#define MAXDEVCHARS 32
static int devfs_k10sensor_ln(di_minor_t minor, di_node_t node);
static devfsadm_create_t devfs_k10sensor_create_cbt[] = {
{ "pseudo", "ddi_pseudo", NULL, TYPE_EXACT, ILEVEL_0, devfs_k10sensor_ln }
};
DEVFSADM_CREATE_INIT_V0(devfs_k10sensor_create_cbt);
/* Create /dev/k10sensor/$instance links to the real device path like
* /devices/pci@0,0/pci1022,1103@18,3:k10sensor */
static int
devfs_k10sensor_ln(di_minor_t minor, di_node_t node)
{
char devname[MAXDEVCHARS];
char *mn;
if (strcmp(di_driver_name(node), KMODNAME) != 0) {
return (DEVFSADM_CONTINUE);
}
if (di_minor_name(minor) == NULL) {
return (DEVFSADM_CONTINUE);
}
devname[0] = '\0';
if (snprintf(devname, MAXDEVCHARS, "%s/%d", KMODNAME, minor->dev_minor)
>= MAXDEVCHARS)
{
return (DEVFSADM_CONTINUE); /* not enough space */
}
/* devfsadm_mklink() one is actually part of devfsadm - we use mapfile-vars
to make ld happy */
(void) devfsadm_mklink(devname, node, minor, 0);
return (DEVFSADM_CONTINUE);
}