nsc_gen.c revision 3270659f55e0928d6edec3d26217cc29398a8149
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#endif
#define __NSC_GEN__
#include "nsc_gen.h"
#include "nsc_mem.h"
#include "../nsctl.h"
#ifdef DS_DDICT
#include "../contract.h"
#endif
static kcondvar_t _nsc_delay_cv;
static kmutex_t _nsc_delay_mutex;
static nsc_service_t *_nsc_services;
static kmutex_t _nsc_svc_mutex;
static void _nsc_sprint_dec(char **, int, int, int);
static void _nsc_sprint_hex(char **, unsigned int, int, int, int, int);
extern nsc_rmhdr_t *_nsc_rmhdr_ptr;
void
{
}
void
{
break;
}
}
}
}
{
#ifdef _SunOS_5_6
return (lbolt);
return ((clock_t)0);
#else
return (ddi_get_lbolt());
#endif
}
nsc_time()
{
return ((time_t)0);
return (time);
}
int
nsc_node_up(int node)
{
return (node == ncall_self());
}
/*
* HACK increment nodeid in data parameter
*/
int
{
int data;
}
int
nsc_node_id(void)
{
return (ncall_self());
}
char *
{
return (ncall_nodename(ncall_self()));
}
/*
* int
* _nsc_rmmap_init (nsc_rmmap_t *map, char *name, int nslot,
* size_t size, ulong_t offset)
* Initialise a global resource map.
*
* Returns TRUE if the map was successfully created. Otherwise
* returns FALSE.
*
* Description:
* Initialises a global resource map. If the map already exists
* the arguments are validated against it.
*/
int
{
if (!size)
return (0);
if (_nsc_rm_nvmem_base)
/* actually we only need to do this if an update occurred above */
if (nvmap) {
sizeof (nsc_rmmap_t), nsc_cm_errhdlr);
}
return (0);
}
return (1);
}
/*
* ulong_t
* _nsc_rmmap_alloc (nsc_rmmap_t *map, char *name,
* size_t size, void (*alloc)())
* Allocate entry in a global resource map.
*
* On success, returns the base of the allocated area. Otherwise,
* returns NULL. The function 'alloc' will be called if the
* allocated area is not currently in use.
*
* Description:
* Allocates an entry in the global resource map. If the entry
* already exists but is a different size an error is returned.
*/
{
if (!size)
return (0);
if (_nsc_rm_nvmem_base)
for (i = 1; i < nslot; i++) {
continue;
continue;
if (nvmap) {
sizeof (nsc_rmmap_t), nsc_cm_errhdlr);
}
}
return (0);
}
continue;
continue;
}
for (i = 1; i < nslot; i++)
break;
if (i == nslot)
break;
if (nvmap) { /* update the map and hdr dirty bit. */
sizeof (nsc_rmmap_t), nsc_cm_errhdlr);
}
if (alloc)
return (offset);
}
return (0);
}
/*
* void
* _nsc_rmmap_free (nsc_rmmap_t *map, char *name)
* Free entry in a global resource map.
*
* Description:
* Frees an entry in the global resource map.
*/
void
{
if (_nsc_rm_nvmem_base)
for (i = 1; i < nslot; i++) {
continue;
continue;
if (nvmap) {
/*
* if dirty, set the inuse bit so this area
* will not be _nsc_global_zero'd on restart.
*/
}
sizeof (nsc_rmmap_t), nsc_cm_errhdlr);
}
return;
}
}
/*
* size_t
* _nsc_rmmap_size (nsc_rmmap_t *map, char *name)
* Find size of area in map.
*
* Returns the size of the specified area in the map,
* or 0 if it is currently unallocated.
*/
{
for (i = 1; i < nslot; i++) {
continue;
break;
}
}
return (size);
}
/*
* size_t
* _nsc_rmmap_avail (nsc_rmmap_t *map)
* Find available space in global resource map.
*
* Returns the size of the largest available area in
* the global resource map.
*/
{
size = 1;
size = 1;
}
return (avail);
}
/*
* static int
* _nsc_rmmap_inuse (nsc_rmmap_t *map, ulong_t *offsetp, size_t *sizep)
* Check if a section of the map is in use.
*
* The global lock must be held across calls to the function.
*
* Returns TRUE if the specified area is currently in use and
* updates offset to point just past the section that was found
* to be in use.
*
* Otherwise, returns FALSE and updates size to reflect the
* amount of free space at the specified offset.
*
* Description:
* Checks the specified global map to determine if any part
* of the area is in use.
*/
static int
{
int i, nslot;
for (i = 1; i < nslot; i++) {
continue;
return (1);
}
}
return (0);
}
/*
* int
* nsc_delay_sig (clock_t tics)
* Delay for a number of clock ticks.
*
* Returns FALSE if the delay was interrupted by a
* signal, TRUE otherwise.
*
* Description:
* Delays execution for the specified number of ticks
* or until a signal is received.
*/
int
{
rc = 1;
/* CONSTCOND */
while (1) {
/* timeout */
break;
}
if (rc == 0) {
/* signalled */
return (FALSE);
}
}
return (TRUE);
}
/*
* void
* nsc_sprintf (char *s, char *fmt, ...)
* String printf.
*
* Builds a NULL terminated string in the buffer
* pointed to by 's', using the format 'fmt'.
*
* Description:
* Simple version of sprintf supporting fairly
* basic formats.
*/
/* PRINTFLIKE2 */
void
nsc_sprintf(char *s, char *fmt, ...)
{
char c, *cp;
va_list p;
/* CONSTCOND */
while (1) {
if ((c = *fmt++) != '%') {
if (!c)
break;
*s++ = c;
continue;
}
if ((c = *fmt++) == 0) {
*s++ = '%';
break;
}
alt = (c == '#');
break;
zero = (c == '0');
break;
if (!(c = *fmt++))
break;
}
if (c == 's') {
while (*cp)
*s++ = *cp++;
continue;
}
if (c == 'd' || c == 'u') {
continue;
}
if (c == 'x' || c == 'X') {
continue;
}
*s++ = '%';
if (alt)
*s++ = '#';
if (zero)
*s++ = '0';
if (len)
_nsc_sprint_dec(&s, len, 0, 0);
*s++ = c;
}
*s++ = '%';
if (alt)
*s++ = '#';
if (zero)
*s++ = '0';
if (len)
_nsc_sprint_dec(&s, len, 0, 0);
}
va_end(p);
*s = 0;
}
/*
* static void
* _nsc_sprint_dec (char **sptr, int n, int zero, int len)
* Decimal to string conversion.
*
* Stores a character representation of 'n' in the
* buffer referenced by 'sptr' and updates the pointer
* accordingly.
*
* Description:
* Generates a string representation of a signed decimal
* integer.
*/
static void
{
unsigned int v = (n < 0) ? (-n) : n;
char c[20];
int i;
for (i = 0; v; i++) {
c[i] = (v % 10) + '0';
v /= 10;
}
len -= (i ? i : 1);
if (n < 0 && !zero)
*(*sptr)++ = ' ';
if (n < 0) {
*(*sptr)++ = '-';
len--;
}
if (!i)
*(*sptr)++ = '0';
while (i--)
*(*sptr)++ = c[i];
}
/*
* static void
* _nsc_sprint_hex (char **sptr, unsigned int v,
* int up, int alt, int zero, int len)
* Hexadecimal to string conversion.
*
* Stores a character representation of 'v' in the
* buffer referenced by 'sptr' and updates the pointer
* accordingly.
*
* Description:
* Generates a string representation of an unsigned
* hexadecimal integer.
*/
static void
{
char *str = "0123456789abcdef";
char c[20];
int i;
if (up)
str = "0123456789ABCDEF";
for (i = 0; v; i++) {
c[i] = str[(v % 16)];
v /= 16;
}
if (alt) {
*(*sptr)++ = '0';
}
if (!i)
*(*sptr)++ = '0';
while (i--)
*(*sptr)++ = c[i];
}
/*
* char *
* nsc_strdup (char *s)
* Duplicate string.
*
* Returns the address of the new string.
*
* Description:
* Allocates a suitably sized area of memory and
* copies the string into it. The string should be
* free'd using nsc_strfree().
*/
char *
nsc_strdup(char *s)
{
char *cp;
if (s == NULL)
return (NULL);
return (cp);
}
/*
* void
* nsc_strfree (char *s)
* Free string.
*
* Description:
* Frees a string previously allocated by nsc_strdup.
*/
void
nsc_strfree(char *s)
{
if (s)
}
/*
* int
* nsc_strmatch (char *s, char *pat)
* Match string against pattern.
*
* Returns TRUE if the string matches against the
* pattern, FALSE otherwise.
*
* Description:
* Compares string against regular expression which
* can contain '*', '?' and '[]' constructs.
*/
int
nsc_strmatch(char *s, char *pat)
{
int neg;
if (*pat == '*') {
while (*pat == '*')
pat++;
if (!*pat)
return (1);
for (; *s; s++)
if (nsc_strmatch(s, pat))
return (1);
return (0);
}
if (!*s)
return (0);
if (*pat == '[') {
pat++;
while (*pat) {
if (*pat == *s)
break;
break;
pat += 2;
}
if (*++pat == ']') {
if (neg)
goto lp;
else
return (0);
}
}
;
return (0);
lp:
continue;
}
return (0);
}
return (!*s);
}
/*
* uint64_t
* nsc_strhash(char *str)
* Calculate a simple hash for the specified string
*
* Returns a simple hash of the NULL terminated string, str.
*
* Description:
*/
nsc_strhash(char *str)
{
return (hash);
while (*str != '\0') {
hash <<= 1;
str++;
}
return (hash);
}
/*
* int
* nsc_fatal(void)
* Fatal error stub function
*
* Returns EINVAL (non-DEBUG) or forces a panic.
*
* Description:
* This is a stub function suitable for default actions in
* nsctl i/o provider definitions. It should be used when
* calling the stub would be a programming error. The most
* common reason for nsc_fatal() being called is that an
* nsctl client module has called an nsc_fd_t i/o function
* without the fd already reserved.
*
* The function will display a diagnostic message and when
* built -DDEBUG will force a panic and display the textual
* name of the symbol closest to the caller address of this
* function.
*/
int
{
void *caller = nsc_caller();
#ifdef DEBUG
#ifndef DS_DDICT
#endif /* !DS_DDICT */
/*
* Force TRAP due to NULL pointer dereference
* - CE_PANIC can result in the stack trace being unreadable
* by (k)adb.
*/
*(int *)0 = 0x12345678;
#else /* !DEBUG */
#endif /* DEBUG */
return (EINVAL);
}
int nsc_null() { return (0); }
int nsc_true() { return (1); }
int nsc_inval() { return (-1); }
/*ARGSUSED*/
int
{
return (0);
}
static int _nsc_nvmem_errs;
/* ARGSUSED */
void
{
static int _nsc_baddma_already_seen = 0;
if (!(_nsc_baddma_already_seen % 100)) {
_nsc_baddma_already_seen += 1;
if (_nsc_baddma_already_seen >= 100) {
"!nsc_cm_errhdlr: this message "
"displayed every 100 errors");
}
}
(void) nsc_node_hints_set(NSC_FORCED_WRTHRU);
}
void
_nsc_init_svc(void)
{
}
void
_nsc_deinit_svc(void)
{
if (_nsc_services != NULL) {
"nsctl: services registered in _nsc_deinit_svc");
/* NOTREACHED */
}
}
{
return (NULL);
return (NULL);
}
break;
return (NULL);
}
_nsc_services = sp;
}
} else {
}
return (svc);
}
int
{
return (EINVAL);
return (EINVAL);
break;
if (*svcp)
break;
if (*spp)
return (0);
}
return (0);
}
int
{
int found;
return (EINVAL);
return (EINVAL);
if (found == 0)
return (ENOSYS);
return (0);
}