dman.c revision 96ccc8cb05e8790fcc24931dcb155b76e810295c
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER START
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * The contents of this file are subject to the terms of the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Common Development and Distribution License (the "License").
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You may not use this file except in compliance with the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * See the License for the specific language governing permissions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and limitations under the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * When distributing Covered Code, include this CDDL HEADER in each
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If applicable, add the following below this CDDL HEADER, with the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fields enclosed by brackets "[]" replaced with your own identifying
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * information: Portions Copyright [yyyy] [name of copyright owner]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER END
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Use is subject to license terms.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma ident "%Z%%M% %I% %E% SMI"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Starcat Management Network Driver
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ****** NOTICE **** This file also resides in the SSC gate as
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ****** NOTICE **** usr/src/uts/sun4u/scman/scman.c. Any changes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ****** NOTICE **** made here must be propogated there as well.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int ddi_create_internal_pathname(dev_info_t *, char *, int, minor_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(DEBUG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Set manstr_t dlpistate (upper half of multiplexor)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Set man_dest_t dlpistate (lower half of multiplexor)
static const char *lss[] = {
static char *_mw_type[] = {
typedef struct man_kstat_info_s {
int mk_flags;
#ifndef ETHERTYPE_IPV6
static int man_deconfigure(void);
static int man_open_ctl();
static void man_close_ctl();
static void man_linkcheck_timer(void *);
* Functions supporting/processing work requests.
static void man_bwork(void);
* Functions implementing/supporting failover.
static void man_reset_dlpi(void *);
cred_t *);
static void man_param_cleanup(void);
extern int man_domain_configure(void);
extern int man_domain_deconfigure(void);
extern int man_is_on_domain;
* exclusive) for concurrency/performance reasons.
(void *) &modldrv,
_init(void)
if (status != 0) {
return (status);
if (status != 0) {
return (status);
int status;
return (status);
_fini(void)
int status = 0;
return (EBUSY);
if (status)
goto exit;
if (status != 0)
goto exit;
exit:
return (status);
int status = 0;
if (man_is_on_domain) {
if (status != 0)
goto exit;
exit:
return (status);
int minor_node_created = 0;
int instance;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
goto exit;
goto exit;
#ifdef kstat
(void *)manp);
goto exit;
return (DDI_SUCCESS);
exit:
if (minor_node_created)
return (DDI_FAILURE);
int status = 0;
if (man_is_on_domain) {
return (status);
return (status);
int instance;
return (DDI_FAILURE);
return (DDI_FAILURE);
(void *)dip);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
switch (infocmd) {
case DDI_INFO_DEVT2DEVINFO:
case DDI_INFO_DEVT2INSTANCE:
if (minor == 0) {
return (DDI_SUCCESS);
return (DDI_FAILURE);
int status = 0;
* lock/synchronization info.
if (status != 0)
goto exit;
if (status == 0) {
goto exit;
if (man_config_error) {
goto exit;
minordev = 0;
minordev++;
if (minordev == 0)
exit:
if (status) {
return (status);
int status = 0;
if (!man_ndlist &&
goto exit;
* done. See man_open_ctl for mutex lock/synchronization info.
exit:
if (status != 0)
return (status);
return (ENODEV);
for (i = 0; i < MAN_MAX_DESTS; i++) {
#if DEBUG
case M_DATA:
case M_PROTO:
case M_PCPROTO:
case M_IOCTL:
case M_IOCDATA:
case M_CTL:
case M_FLUSH:
int status = 0;
for (i = 0; i < MAN_MAX_DESTS; i++) {
for (i = 0; i < MAN_MAX_DESTS; i++) {
return (status);
int status = 0;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
(void *)mdp));
goto exit;
goto exit;
exit:
return (status);
#ifdef DEBUG
case I_PLINK:
case I_PUNLINK:
case MAN_SETPATH:
case MAN_GETEADDR:
case MAN_SET_LINKCHECK_TIME:
case MAN_SET_SC_IPADDRS:
case MAN_SET_SC_IP6ADDRS:
case DLIOCRAW:
case DL_IOC_HDR_INFO:
case MAN_ND_GET:
case MAN_ND_SET:
exit:
int status = 0;
goto exit;
exit:
if (status)
static queue_t *
goto exit;
goto exit;
exit:
return (wq);
int error;
if (error != 0)
goto exit;
goto exit;
exit:
if (error)
int error;
if (error != 0)
goto exit;
exit:
if (error)
int error;
if (error != 0) {
int error;
if (error != 0)
goto exit;
#ifdef DEBUG
exit:
if (error)
int error;
if (error != 0)
goto exit;
#ifdef DEBUG
exit:
if (error)
int status = 0;
goto exit;
if (status != 0)
goto exit;
goto exit;
goto exit;
goto exit;
exit:
status));
if (status) {
int status;
goto done;
case M_DATA:
if (manp) {
if (status) {
goto break_loop;
case M_PROTO:
case M_PCPROTO:
if (status) {
goto break_loop;
(void *)mp));
man_iwork();
done:
int flow_status = 0;
case DL_UNITDATA_REQ:
case DL_ATTACH_REQ:
case DL_DETACH_REQ:
case DL_BIND_REQ:
case DL_UNBIND_REQ:
case DL_INFO_REQ:
case DL_PROMISCON_REQ:
case DL_PROMISCOFF_REQ:
case DL_ENABMULTI_REQ:
case DL_DISABMULTI_REQ:
case DL_PHYS_ADDR_REQ:
case DL_SET_PHYS_ADDR_REQ:
return (flow_status);
int flow_status = 0;
return (flow_status);
return (flow_status);
return (flow_status);
return (flow_status);
short ppa;
int dlerror = 0;
int status = 0;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
* man_init_dests/man_start_dest needs these set before call.
goto exit;
exit:
if (dlerror == 0) {
if (did_refcnt) {
return (ENOMEM);
for (i = 0; i < MAN_MAX_DESTS; i++) {
int count = 0;
for (i = 0; i < MAN_MAX_DESTS; i++) {
count++;
int status;
if (status == 0)
return (status);
int status;
if (status == 0)
return (status);
unsigned prim;
int status = 0;
goto exit;
exit:
return (status);
int status = 0;
goto exit;
for (i = 0; i < MAN_MAX_DESTS; i++) {
if (no_dests)
goto exit;
for (i = 0; i < MAN_MAX_DESTS; i++) {
if (dstate[i]) {
if (status == 0) {
for (i = 0; i < MAN_MAX_DESTS; i++)
if (dstate[i]) {
exit:
return (status);
while (rmp) {
(void *)mdp,
goto exit;
goto exit;
if (matched) {
if (matched) {
exit:
if (matched) {
switch (prim1) {
case DL_UNBIND_REQ:
case DL_PROMISCOFF_REQ:
case DL_DISABMULTI_REQ:
return (matched);
if (xidtest) {
int flag;
case DL_PROMISC_PHYS:
case DL_PROMISC_SAP:
case DL_PROMISC_MULTI:
int flag;
case DL_PROMISC_PHYS:
case DL_PROMISC_SAP:
case DL_PROMISC_MULTI:
switch (type) {
case DL_FACT_PHYS_ADDR:
case DL_CURR_PHYS_ADDR:
* tuneable, or a man.conf parameter.
goto exit;
goto exit;
goto exit;
exit:
#if defined(DEBUG)
char *prim_str;
#if defined(DEBUG)
#if defined(DEBUG)
goto exit;
case M_PROTO:
case M_PCPROTO:
case M_IOCNAK:
#if defined(DEBUG)
case M_IOCACK:
case M_CTL:
goto dl_reset;
switch (prim) {
case DL_OK_ACK:
switch (cprim) {
case DL_ATTACH_REQ:
case DL_DETACH_REQ:
case DL_UNBIND_REQ:
case DL_BIND_ACK:
case DL_ERROR_ACK:
switch (cprim) {
case DL_ATTACH_REQ:
case DL_BIND_REQ:
case DL_DISABMULTI_REQ:
case DL_ENABMULTI_REQ:
case DL_PROMISCON_REQ:
case DL_PROMISCOFF_REQ:
case DL_SET_PHYS_ADDR_REQ:
case DL_UNBIND_REQ:
case DL_DETACH_REQ:
case DL_UDERROR_IND:
case DL_INFO_ACK:
prim);
if (need_dl_reset) {
(man_is_on_domain ||
exit:
* from the non-STREAMS half of the driver (see man_bwork.c). The work
int wp_finished;
case MAN_WORK_DRATTACH:
case MAN_WORK_DRSWITCH:
case MAN_WORK_DRDETACH:
case MAN_WORK_SWITCH:
case MAN_WORK_KSTAT_UPDATE:
if (wp_finished) {
int status = 0;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
exit:
if (status) {
return (status);
int status = 0;
goto exit;
goto exit;
exit:
return (status);
int found;
int status = 0;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
if (found) {
exit:
if (switch_ok) {
if (switch_ok) {
if (switch_ok) {
return (switch_ok);
return (mdp);
goto fail;
goto fail;
fail:
while (rmp) {
goto exit;
status = 0;
goto exit;
exit:
return (status);
static mblk_t *
goto exit;
goto exit;
exit:
return (ubreq);
static mblk_t *
goto nomem;
return (listp);
while (listp) {
return (NULL);
static mblk_t *
goto exit;
exit:
return (mp);
int close_cnt = 0;
int status = 0;
goto exit;
close_cnt++;
if (close_cnt == 0)
goto exit;
goto exit;
exit:
return (status);
int status;
return (!status);
int time = 0;
switch (timer) {
case MAN_TIMER_INIT:
if (attached)
case MAN_TIMER_LINKCHECK:
if (attached) {
case MAN_TIMER_DLPIRESET:
if (attached)
int newstate;
int oldstate;
goto exit;
goto do_switch;
(void *)mdp);
goto done;
switch (oldstate) {
case MAN_LINKINIT:
case MAN_LINKGOOD:
case MAN_LINKSTALE:
case MAN_LINKFAIL:
done:
if (send_ping)
if (restart_timer)
exit:
int status = 0;
return (EBUSY);
goto exit;
exit:
if (status != 0) {
return (status);
int sdp_cnt = 0;
int status = 0;
goto exit;
if (status) {
goto exit;
if (sdp_cnt == 0) {
goto exit;
exit:
return (status);
int sdp_cnt = 0;
int status = 0;
sdp_cnt++;
if (sdp_cnt == 0)
goto exit;
goto exit;
tdp++;
status = 0;
exit:
return (status);
static mblk_t *
int ipver;
int iph_hdr_len;
uchar_t i;
goto exit;
if (man_is_on_domain) {
goto exit;
if (man_is_on_domain) {
goto exit;
for (i = 0; i < datalen; i++)
*datap++ = i;
exit:
return (mp);
static mblk_t *
return (NULL);
return (NULL);
return (mp);
* which executes outside of the STREAMS framework (see man_str.c). It is
int done = 0;
int wp_finished;
while (done == 0) {
case MAN_WORK_OPEN_CTL:
case MAN_WORK_CLOSE_CTL:
case MAN_WORK_CLOSE:
case MAN_WORK_CLOSE_STREAM:
case MAN_WORK_SWITCH:
if (wp_finished) {
thread_exit();
int status = 0;
if (status) {
goto exit;
if (status) {
goto exit;
goto exit;
if (status) {
goto exit;
exit:
if (li)
return (status);
int cnt;
for (i = 0; i < cnt; i++) {
int status = 0;
KM_SLEEP);
if (status != 0)
goto exit;
goto exit;
goto exit;
exit:
if (status)
int status;
int muxid;
goto exit;
if (status != 0) {
goto exit;
if (status) {
goto exit;
if (status) {
goto exit;
exit:
if (li)
return (status);
if (status) {
int status = 0;
goto exit;
goto exit;
case MI_PATH_ASSIGN:
case MI_PATH_ADD:
case MI_PATH_UNASSIGN:
case MI_PATH_ACTIVATE:
case MI_PATH_READ:
exit:
return (status);
int cnt;
int status = 0;
if (cnt == 0) {
goto exit;
for (i = 0; i < cnt; i++) {
goto exit;
if (status)
goto exit;
goto exit;
for (i = 0; i < cnt; i++) {
goto exit;
if (status) {
goto exit;
goto exit;
int in_new_list;
for (i = 0; i < cnt; i++) {
if (!in_new_list) {
if (first_pass) {
goto exit;
goto again;
exit:
if (status == 0) {
if (add_paths)
return (status);
int status = 0;
goto exit;
if (status)
goto exit;
goto free_pg;
exit:
return (status);
int status = 0;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
if (status != 0) {
status = 0;
exit:
return (status);
int cnt;
int status = 0;
goto exit;
cnt = 0;
cnt++;
exit:
return (status);
int status = 0;
goto exit;
goto exit;
exit:
return (status);
static man_pg_t *
return (mpg);
return (NULL);
static man_pg_t *
return (mpg);
return (NULL);
static man_path_t *
return (mp);
return (NULL);
static man_path_t *
return (mp);
return (NULL);
static man_path_t *
goto exit;
goto exit;
exit:
return (np);
goto exit;
exit:
int status = 0;
goto exit;
exit:
return (status);
goto exit;
exit:
return (wp);
if (lp) {
if (q == man_bwork_q) {
switch (man_param_display[i]) {
case MAN_NDD_GETABLE:
case MAN_NDD_SETABLE:
goto exit;
goto exit;
goto exit;
goto exit;
exit:
return (status);
int pad_end;
if (man_is_on_domain) {
pad_end = 0;
pad);
if (plist)
int meta_ppa;
int phys_ppa;
int pg_id;
int status = 0;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
exit:
return (status);
char *ipaddr;
int status;
if (!man_is_on_domain)
return (status);
for (i = 0; i < MAN_MAX_EXPANDERS; i++) {
p = (unsigned char *)∈
char *end;
return (EINVAL);
int status = 0;
if (wait_status == 0)
status = 0;
if (status)
goto exit;
for (i = 0; i < MAN_NUMSTATS; i++) {
for (i = 0; i < MAN_NUMSTATS; i++) {
exit:
return (status);
int instance;
int flags;
char *statname;
for (i = 0; i < MAN_NUMSTATS; i++) {
for (i = 0; i < num_stats; i++) {
int found = 0;
knp++) {
found++;
if (!found) {
return (found);
char *physname;
char *physalias;
char *statname;
(void *)phys_last_knp));
for (i = 0; i < MAN_NUMSTATS; i++) {
int found = 0;
int flags = 0;
delta64 = 0;
if (phys_ksp) {
&phys_kn_entry)) {
if (!found) {
case KSTAT_DATA_UINT32:
case KSTAT_DATA_UINT32:
#if defined(DEBUG)
static char *_ms_flags[] = {
static char *_md_state[] = {
if (state == 0) {
static char *_mdev_state[] = {
goto number;
if (state == 0) {
static char *_mip_cmd[] = {
static char *_mw_flags[] = {
void *tmp;
return (tmp);