xref: /titanic_44/usr/src/uts/sun4u/starcat/io/dman_domain.c (revision 07d06da50d310a325b457d6330165aebab1e0064)
103831d35Sstevel /*
203831d35Sstevel  * CDDL HEADER START
303831d35Sstevel  *
403831d35Sstevel  * The contents of this file are subject to the terms of the
503831d35Sstevel  * Common Development and Distribution License (the "License").
603831d35Sstevel  * You may not use this file except in compliance with the License.
703831d35Sstevel  *
803831d35Sstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
903831d35Sstevel  * or http://www.opensolaris.org/os/licensing.
1003831d35Sstevel  * See the License for the specific language governing permissions
1103831d35Sstevel  * and limitations under the License.
1203831d35Sstevel  *
1303831d35Sstevel  * When distributing Covered Code, include this CDDL HEADER in each
1403831d35Sstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1503831d35Sstevel  * If applicable, add the following below this CDDL HEADER, with the
1603831d35Sstevel  * fields enclosed by brackets "[]" replaced with your own identifying
1703831d35Sstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
1803831d35Sstevel  *
1903831d35Sstevel  * CDDL HEADER END
2003831d35Sstevel  */
2103831d35Sstevel 
2203831d35Sstevel /*
23*07d06da5SSurya Prakki  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2403831d35Sstevel  * Use is subject to license terms.
2503831d35Sstevel  */
2603831d35Sstevel 
2703831d35Sstevel /*
2803831d35Sstevel  * Domain specific portion of the Starcat Management Network Driver
2903831d35Sstevel  */
3003831d35Sstevel 
3103831d35Sstevel #include <sys/types.h>
3203831d35Sstevel #include <sys/proc.h>
3303831d35Sstevel #include <sys/kmem.h>
3403831d35Sstevel #include <sys/stat.h>
3503831d35Sstevel #include <sys/kstat.h>
3603831d35Sstevel #include <sys/ksynch.h>
3703831d35Sstevel #include <sys/stream.h>
3803831d35Sstevel #include <sys/dlpi.h>
3903831d35Sstevel #include <sys/stropts.h>
4003831d35Sstevel #include <sys/strsubr.h>
4103831d35Sstevel #include <sys/debug.h>
4203831d35Sstevel #include <sys/conf.h>
4303831d35Sstevel #include <sys/kstr.h>
4403831d35Sstevel #include <sys/errno.h>
4503831d35Sstevel #include <sys/ethernet.h>
4603831d35Sstevel #include <sys/byteorder.h>
4703831d35Sstevel #include <sys/ddi.h>
4803831d35Sstevel #include <sys/sunddi.h>
4903831d35Sstevel #include <sys/modctl.h>
5003831d35Sstevel #include <sys/strsun.h>
5103831d35Sstevel #include <sys/pci.h>
5203831d35Sstevel #include <sys/callb.h>
5303831d35Sstevel #include <sys/pci.h>
5403831d35Sstevel #include <sys/iosramio.h>
5503831d35Sstevel #include <sys/mboxsc.h>
5603831d35Sstevel #include <netinet/in.h>
5703831d35Sstevel #include <inet/common.h>
5803831d35Sstevel #include <inet/mi.h>
5903831d35Sstevel #include <inet/nd.h>
6003831d35Sstevel #include <sys/socket.h>
6103831d35Sstevel #include <netinet/igmp_var.h>
6203831d35Sstevel #include <netinet/ip6.h>
6303831d35Sstevel #include <netinet/icmp6.h>
6403831d35Sstevel #include <inet/ip.h>
6503831d35Sstevel #include <inet/ip6.h>
6603831d35Sstevel #include <sys/dman.h>
6703831d35Sstevel #include <sys/ddi_impldefs.h>
6803831d35Sstevel #include <sys/sunndi.h>
6903831d35Sstevel 
7003831d35Sstevel #define	MAN_SCHIZO_BINDING_NAME		"pci108e,8001"
7103831d35Sstevel #define	MAN_XMITS_BINDING_NAME		"pci108e,8002"
7203831d35Sstevel 
7303831d35Sstevel int	man_is_on_domain = TRUE;
7403831d35Sstevel 
7503831d35Sstevel /*
7603831d35Sstevel  * Domain side function prototypes.
7703831d35Sstevel  */
7803831d35Sstevel int	man_get_iosram(manc_t *);
7903831d35Sstevel int	man_domain_configure(void);
8003831d35Sstevel int	man_domain_deconfigure(void);
8103831d35Sstevel int	man_path_discovery(void);
8203831d35Sstevel int	man_dossc_switch(uint32_t);
8303831d35Sstevel int	man_dr_attach(dev_info_t *);
8403831d35Sstevel int	man_dr_detach(dev_info_t *);
8503831d35Sstevel static int	man_dr_submit_work_wait(dev_info_t *, int);
8603831d35Sstevel static int	man_find_devs(mi_path_t *, uchar_t);
8703831d35Sstevel static int 	man_dip_is_schizoxmits0_pcib(dev_info_t *, int *, int *);
8803831d35Sstevel static int	man_dip_is_eri(dev_info_t *, man_dev_t *);
8903831d35Sstevel static int	man_dip_is_attached(dev_info_t *);
9003831d35Sstevel static int 	man_get_eri_dev_info(dev_info_t *, man_dev_t *);
9103831d35Sstevel static int	man_mbox_initialized = FALSE;
9203831d35Sstevel 
9303831d35Sstevel /*
9403831d35Sstevel  * Externs
9503831d35Sstevel  */
9603831d35Sstevel extern int	man_pg_cmd(mi_path_t *, man_work_t *);
9703831d35Sstevel extern kmutex_t		man_lock;
9803831d35Sstevel extern void		*man_softstate;
9903831d35Sstevel extern man_work_t	*man_work_alloc(int, int);
10003831d35Sstevel extern void		man_work_free(man_work_t *);
10103831d35Sstevel extern void		man_work_add(man_workq_t *, man_work_t *);
10203831d35Sstevel extern man_workq_t	*man_bwork_q;
10303831d35Sstevel extern man_workq_t	*man_iwork_q;
10403831d35Sstevel extern queue_t		*man_ctl_wq;
10503831d35Sstevel 
10603831d35Sstevel #if defined(DEBUG)
10703831d35Sstevel static void man_print_manc(manc_t *);
10803831d35Sstevel extern uint32_t	man_debug;
10903831d35Sstevel #endif  /* DEBUG */
11003831d35Sstevel 
11103831d35Sstevel int
man_domain_configure(void)11203831d35Sstevel man_domain_configure(void)
11303831d35Sstevel {
11403831d35Sstevel 	int		status = 0;
11503831d35Sstevel 
11603831d35Sstevel 	/*
11703831d35Sstevel 	 * man_mbox_initialized is protected by inner perimiter lock.
11803831d35Sstevel 	 */
11903831d35Sstevel 	if (man_mbox_initialized == TRUE)
12003831d35Sstevel 		goto exit;
12103831d35Sstevel 
12203831d35Sstevel 	status = mboxsc_init(IOSRAM_KEY_SCMD, MBOXSC_MBOX_IN, NULL);
12303831d35Sstevel 
12403831d35Sstevel 	if (status != 0) {
12503831d35Sstevel 		cmn_err(CE_WARN, "man_domain_configure: failed to initialize"
12603831d35Sstevel 		    " MBOXSC_MBOX_IN, errno = %d", status);
12703831d35Sstevel 		goto exit;
12803831d35Sstevel 	}
12903831d35Sstevel 
13003831d35Sstevel 	status = mboxsc_init(IOSRAM_KEY_MDSC, MBOXSC_MBOX_OUT, NULL);
13103831d35Sstevel 	if (status != 0) {
132*07d06da5SSurya Prakki 		(void) mboxsc_fini(IOSRAM_KEY_SCMD);
13303831d35Sstevel 		cmn_err(CE_WARN, "man_domain_configure: failed to initialize"
13403831d35Sstevel 		    " MBOXSC_MBOX_OUT, errno = %d", status);
13503831d35Sstevel 		goto exit;
13603831d35Sstevel 	}
13703831d35Sstevel 
13803831d35Sstevel 	man_mbox_initialized = TRUE;
13903831d35Sstevel 
14003831d35Sstevel 	status = man_path_discovery();
14103831d35Sstevel 	if (status != 0) {
142*07d06da5SSurya Prakki 		(void) mboxsc_fini(IOSRAM_KEY_SCMD);
143*07d06da5SSurya Prakki 		(void) mboxsc_fini(IOSRAM_KEY_MDSC);
14403831d35Sstevel 		man_mbox_initialized = FALSE;
14503831d35Sstevel 	}
14603831d35Sstevel 
14703831d35Sstevel exit:
14803831d35Sstevel 	return (status);
14903831d35Sstevel }
15003831d35Sstevel 
15103831d35Sstevel /*
15203831d35Sstevel  * Build pathgroup connecting a domain to the SSC. Only called on domains
15303831d35Sstevel  * at first man_open. On the SSC, pathgroups are built by IOCTL requests
15403831d35Sstevel  * from the MAN daemon (see man_ioctl and mand(1M)).
15503831d35Sstevel  *
15603831d35Sstevel  * Locks held
15703831d35Sstevel  *	- exclusive innerperim.
15803831d35Sstevel  */
15903831d35Sstevel int
man_path_discovery(void)16003831d35Sstevel man_path_discovery(void)
16103831d35Sstevel {
16203831d35Sstevel 	manc_t		manc;
16303831d35Sstevel 	mi_path_t	mpath;
16403831d35Sstevel 	int		num_devs;
16503831d35Sstevel 	int		status = 0;
16603831d35Sstevel 	int		i;
16703831d35Sstevel 
16803831d35Sstevel 	MAN_DBG(MAN_CONFIG, ("man_path_discovery:"));
16903831d35Sstevel 
17003831d35Sstevel 	if (status = man_get_iosram(&manc)) {
17103831d35Sstevel 		goto exit;
17203831d35Sstevel 	}
17303831d35Sstevel 
17403831d35Sstevel 	/*
17503831d35Sstevel 	 * If manc_ip_type indicates MAN network is not enabled
17603831d35Sstevel 	 * for this domain, then lets just bailout from here as if no
17703831d35Sstevel 	 * devices were found.
17803831d35Sstevel 	 */
17903831d35Sstevel 	if ((manc.manc_ip_type != AF_INET) &&
18003831d35Sstevel 	    (manc.manc_ip_type != AF_INET6)) {
18103831d35Sstevel 		goto exit;
18203831d35Sstevel 	}
18303831d35Sstevel 
18403831d35Sstevel 	MAN_DBGCALL(MAN_CONFIG, man_print_manc(&manc));
18503831d35Sstevel 
18603831d35Sstevel 	/*
18703831d35Sstevel 	 * Extract SC ethernet address from IOSRAM.
18803831d35Sstevel 	 */
18903831d35Sstevel 	ether_copy(&manc.manc_sc_eaddr, &mpath.mip_eaddr);
19003831d35Sstevel 
19103831d35Sstevel 	mpath.mip_pg_id = 0;	/* SC is always pathgroup ID 0 */
19203831d35Sstevel 	mpath.mip_man_ppa = 0;	/* Domain only has one ppa, 0 */
19303831d35Sstevel 
19403831d35Sstevel 	/*
19503831d35Sstevel 	 * Get list of present devices, and update man_paths[] as needed.
19603831d35Sstevel 	 */
19703831d35Sstevel 	num_devs = man_find_devs(&mpath, MAN_MAX_EXPANDERS);
19803831d35Sstevel 	if (num_devs <= 0) {
19903831d35Sstevel 		status = ENODEV;
20003831d35Sstevel 		goto exit;
20103831d35Sstevel 	}
20203831d35Sstevel 
20303831d35Sstevel 	mpath.mip_cmd = MI_PATH_ASSIGN;
20403831d35Sstevel 
20503831d35Sstevel 	mutex_enter(&man_lock);
20603831d35Sstevel 	status = man_pg_cmd(&mpath, NULL);
20703831d35Sstevel 	if (status) {
20803831d35Sstevel 		mutex_exit(&man_lock);
20903831d35Sstevel 		goto exit;
21003831d35Sstevel 	}
21103831d35Sstevel 
21203831d35Sstevel 	/*
21303831d35Sstevel 	 * Now activate the ethernet on the golden io board.
21403831d35Sstevel 	 */
21503831d35Sstevel 	for (i = 0; i < num_devs; i++) {
21603831d35Sstevel 		if (mpath.mip_devs[i].mdev_exp_id == manc.manc_golden_iob)
21703831d35Sstevel 			mpath.mip_devs[0] = mpath.mip_devs[i];
21803831d35Sstevel 	}
21903831d35Sstevel 	mpath.mip_ndevs = 1;
22003831d35Sstevel 	mpath.mip_cmd = MI_PATH_ACTIVATE;
22103831d35Sstevel 	status = man_pg_cmd(&mpath, NULL);
22203831d35Sstevel 	mutex_exit(&man_lock);
22303831d35Sstevel 
22403831d35Sstevel exit:
22503831d35Sstevel 	MAN_DBG(MAN_CONFIG, ("man_path_discovery: returns %d\n", status));
22603831d35Sstevel 
22703831d35Sstevel 	return (status);
22803831d35Sstevel }
22903831d35Sstevel 
23003831d35Sstevel int
man_domain_deconfigure(void)23103831d35Sstevel man_domain_deconfigure(void)
23203831d35Sstevel {
23303831d35Sstevel 
234*07d06da5SSurya Prakki 	(void) mboxsc_fini(IOSRAM_KEY_SCMD);
235*07d06da5SSurya Prakki 	(void) mboxsc_fini(IOSRAM_KEY_MDSC);
23603831d35Sstevel 	/*
23703831d35Sstevel 	 * We are about to unload and know that there are no open
23803831d35Sstevel 	 * streams, so this change outside of the perimiter is ok.
23903831d35Sstevel 	 */
24003831d35Sstevel 	man_mbox_initialized = FALSE;
24103831d35Sstevel 
24203831d35Sstevel 	return (0);
24303831d35Sstevel }
24403831d35Sstevel 
24503831d35Sstevel /*
24603831d35Sstevel  * Add a work request to the inner perimeter with the new eri device info.
24703831d35Sstevel  */
24803831d35Sstevel /* ARGSUSED */
24903831d35Sstevel int
man_dr_attach(dev_info_t * dip)25003831d35Sstevel man_dr_attach(dev_info_t *dip)
25103831d35Sstevel {
25203831d35Sstevel 	man_t		*manp;
25303831d35Sstevel 	man_work_t	*wp;
25403831d35Sstevel 	int		status = 0;
25503831d35Sstevel 	man_dev_t	mdev;
25603831d35Sstevel 
25703831d35Sstevel 
25803831d35Sstevel 	mutex_enter(&man_lock);
25903831d35Sstevel 	manp = ddi_get_soft_state(man_softstate, 0);
26003831d35Sstevel 	if (manp == NULL || manp->man_pg == NULL) {
26103831d35Sstevel 		goto exit;
26203831d35Sstevel 	}
26303831d35Sstevel 
26403831d35Sstevel 	if (man_get_eri_dev_info(dip, &mdev) == FALSE) {
26503831d35Sstevel 		status = ENODEV;
26603831d35Sstevel 		goto exit;
26703831d35Sstevel 	}
26803831d35Sstevel 	MAN_DBG(MAN_DR, ("man_dr_attach: dip major = %d instance =%d",
26903831d35Sstevel 	    mdev.mdev_major, mdev.mdev_ppa));
27003831d35Sstevel 	wp = man_work_alloc(MAN_WORK_DRATTACH, KM_NOSLEEP);
27103831d35Sstevel 	if (wp == NULL) {
27203831d35Sstevel 		status = ENOMEM;
27303831d35Sstevel 		goto exit;
27403831d35Sstevel 	}
27503831d35Sstevel 
27603831d35Sstevel 	wp->mw_arg.a_man_ppa = 0;	/* Domain only has one ppa, 0 */
27703831d35Sstevel 	wp->mw_arg.a_pg_id = 0;		/* SC is always pathgroup ID 0 */
27803831d35Sstevel 	wp->mw_arg.a_sf_dev = mdev;
27903831d35Sstevel 	wp->mw_flags = MAN_WFLAGS_NOWAITER;
28003831d35Sstevel 
28103831d35Sstevel 	man_work_add(man_iwork_q, wp);
28203831d35Sstevel 
28303831d35Sstevel 	if (man_ctl_wq)
28403831d35Sstevel 		qenable(man_ctl_wq);
28503831d35Sstevel 
28603831d35Sstevel exit:
28703831d35Sstevel 	mutex_exit(&man_lock);
28803831d35Sstevel 
28903831d35Sstevel 	return (status);
29003831d35Sstevel }
29103831d35Sstevel 
29203831d35Sstevel int
man_dr_detach(dev_info_t * dip)29303831d35Sstevel man_dr_detach(dev_info_t *dip)
29403831d35Sstevel {
29503831d35Sstevel 	man_t		*manp;
29603831d35Sstevel 	int		status = 0;
29703831d35Sstevel 	int		retries = 0;
29803831d35Sstevel 
29903831d35Sstevel 
30003831d35Sstevel 	mutex_enter(&man_lock);
30103831d35Sstevel 	manp = ddi_get_soft_state(man_softstate, 0);
30203831d35Sstevel 	if (manp == NULL || manp->man_pg == NULL) {
30303831d35Sstevel 		mutex_exit(&man_lock);
30403831d35Sstevel 		goto exit;
30503831d35Sstevel 	}
30603831d35Sstevel 	mutex_exit(&man_lock);
30703831d35Sstevel 
30803831d35Sstevel 	/*
30903831d35Sstevel 	 * Arrange to have the detaching path switched if it is active.
31003831d35Sstevel 	 * We will cv_wait_sig for the switch to complete if it is needed.
31103831d35Sstevel 	 */
31203831d35Sstevel again:
31303831d35Sstevel 	status = man_dr_submit_work_wait(dip, MAN_WORK_DRSWITCH);
31403831d35Sstevel 	if (status == EAGAIN && retries < manp->man_dr_retries) {
31503831d35Sstevel 		/*
31603831d35Sstevel 		 * Delay a bit and retry.
31703831d35Sstevel 		 */
31803831d35Sstevel 		MAN_DBG(MAN_DR,
31903831d35Sstevel 		    ("man_dr_detach(switch): EAGAIN - retrying..."));
32003831d35Sstevel 		retries++;
32103831d35Sstevel 		delay(drv_usectohz(manp->man_dr_delay));
32203831d35Sstevel 		goto again;
32303831d35Sstevel 	}
32403831d35Sstevel 
32503831d35Sstevel 	if (status)
32603831d35Sstevel 		goto exit;
32703831d35Sstevel 
32803831d35Sstevel 	retries = 0;
32903831d35Sstevel 
33003831d35Sstevel 	/*
33103831d35Sstevel 	 * Detaching device no longer in use, remove it from our
33203831d35Sstevel 	 * pathgroup.
33303831d35Sstevel 	 */
33403831d35Sstevel 	status = man_dr_submit_work_wait(dip, MAN_WORK_DRDETACH);
33503831d35Sstevel 	if (status == EAGAIN && retries < manp->man_dr_retries) {
33603831d35Sstevel 		MAN_DBG(MAN_DR,
33703831d35Sstevel 		    ("man_dr_detach(detach): EAGAIN - retrying..."));
33803831d35Sstevel 		retries++;
33903831d35Sstevel 		goto again;
34003831d35Sstevel 	}
34103831d35Sstevel 
34203831d35Sstevel exit:
34303831d35Sstevel 	MAN_DBG(MAN_DR, ("man_dr_detach: returns %d", status));
34403831d35Sstevel 	return (status);
34503831d35Sstevel }
34603831d35Sstevel 
34703831d35Sstevel static int
man_dr_submit_work_wait(dev_info_t * dip,int work_type)34803831d35Sstevel man_dr_submit_work_wait(dev_info_t *dip, int work_type)
34903831d35Sstevel {
35003831d35Sstevel 	man_work_t	*wp;
35103831d35Sstevel 	int		status = 0;
35203831d35Sstevel 
35303831d35Sstevel 	wp = man_work_alloc(work_type, KM_NOSLEEP);
35403831d35Sstevel 	if (wp == NULL) {
35503831d35Sstevel 		status = ENOMEM;
35603831d35Sstevel 		goto exit;
35703831d35Sstevel 	}
35803831d35Sstevel 
35903831d35Sstevel 	wp->mw_arg.a_man_ppa = 0;
36003831d35Sstevel 	wp->mw_arg.a_pg_id = 0;
3615c066ec2SJerry Gilliam 	wp->mw_arg.a_sf_dev.mdev_major = ddi_driver_major(dip);
36203831d35Sstevel 	wp->mw_arg.a_sf_dev.mdev_ppa = ddi_get_instance(dip);
36303831d35Sstevel 
36403831d35Sstevel 	mutex_enter(&man_lock);
36503831d35Sstevel 	wp->mw_flags = MAN_WFLAGS_CVWAITER;
36603831d35Sstevel 	man_work_add(man_iwork_q, wp);
36703831d35Sstevel 
36803831d35Sstevel 	/* TBD - change to ASSERT ? */
36903831d35Sstevel 	if (man_ctl_wq)
37003831d35Sstevel 		qenable(man_ctl_wq);
37103831d35Sstevel 
37203831d35Sstevel 	while (!(wp->mw_flags & MAN_WFLAGS_DONE)) {
37303831d35Sstevel 		if (!cv_wait_sig(&wp->mw_cv, &man_lock)) {
37403831d35Sstevel 			wp->mw_flags &= ~MAN_WFLAGS_CVWAITER;
37503831d35Sstevel 			status = EINTR;
37603831d35Sstevel 			break;
37703831d35Sstevel 		}
37803831d35Sstevel 	}
37903831d35Sstevel 
38003831d35Sstevel 	/*
38103831d35Sstevel 	 * Note that if cv_wait_sig() returns zero because a signal
38203831d35Sstevel 	 * was received, MAN_WFLAGS_DONE may not be set.
38303831d35Sstevel 	 * This will happen if man_dr_submit_work_wait() reacquires
38403831d35Sstevel 	 * man_lock before man_iwork() can acquire man_lock just before
38503831d35Sstevel 	 * signalling its work is complete.
38603831d35Sstevel 	 * In this case, it is not necessary to call man_work_free()
38703831d35Sstevel 	 * here because it will be called by man_iwork() because
38803831d35Sstevel 	 * MAN_WFLAGS_CVWAITER was cleared.
38903831d35Sstevel 	 * Should man_iwork() obtain man_lock to signal completion,
39003831d35Sstevel 	 * MAN_WFLAGS_DONE will be set which will ensure man_work_free()
39103831d35Sstevel 	 * is called here.
39203831d35Sstevel 	 */
39303831d35Sstevel 	if (wp->mw_flags & MAN_WFLAGS_DONE) {
39403831d35Sstevel 		status = wp->mw_status;
39503831d35Sstevel 		man_work_free(wp);
39603831d35Sstevel 	}
39703831d35Sstevel 
39803831d35Sstevel 	mutex_exit(&man_lock);
39903831d35Sstevel 
40003831d35Sstevel exit:
40103831d35Sstevel 	return (status);
40203831d35Sstevel }
40303831d35Sstevel 
40403831d35Sstevel /*
40503831d35Sstevel  * Notify SSC of switch request and wait for response.
40603831d35Sstevel  */
40703831d35Sstevel int
man_dossc_switch(uint32_t exp_id)40803831d35Sstevel man_dossc_switch(uint32_t exp_id)
40903831d35Sstevel {
41003831d35Sstevel 	uint64_t	req_tid;
41103831d35Sstevel 	uint32_t	req_cmd;
41203831d35Sstevel 	uint64_t	resp_tid;
41303831d35Sstevel 	uint32_t	resp_cmd;
41403831d35Sstevel 	uint32_t	type;
41503831d35Sstevel 	man_mbox_msg_t	req;
41603831d35Sstevel 	man_mbox_msg_t	resp;
41703831d35Sstevel 	uint32_t	length;
41803831d35Sstevel 	int		status = 0;
41903831d35Sstevel 
42003831d35Sstevel 	/*
42103831d35Sstevel 	 *  There should be nothing in inbound mailbox.
42203831d35Sstevel 	 */
42303831d35Sstevel 	resp_tid = resp_cmd = type = 0;
42403831d35Sstevel 	length = sizeof (man_mbox_msg_t);
42503831d35Sstevel 	bzero((char *)&resp, sizeof (man_mbox_msg_t));
42603831d35Sstevel 	while (mboxsc_getmsg(IOSRAM_KEY_SCMD, &type, &resp_cmd, &resp_tid,
42703831d35Sstevel 	    &length, &resp, 0) == 0) {
42803831d35Sstevel 
42903831d35Sstevel 		resp_tid = resp_cmd = type = 0;
43003831d35Sstevel 		length = sizeof (man_mbox_msg_t);
43103831d35Sstevel 		bzero((char *)&resp, sizeof (man_mbox_msg_t));
43203831d35Sstevel 
43303831d35Sstevel 		MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: dumping message"));
43403831d35Sstevel 		MAN_DBG(MAN_IOSRAM, ("\tcommand = 0x%x", resp_cmd));
43503831d35Sstevel 	}
43603831d35Sstevel 
43703831d35Sstevel 	MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: sending message"));
43803831d35Sstevel 
43903831d35Sstevel 	bzero((char *)&req, sizeof (man_mbox_msg_t));
44003831d35Sstevel 	req.mb_status = 0;
44103831d35Sstevel 	req.mb_exp_id = exp_id;
44203831d35Sstevel 	req_tid = 0;
44303831d35Sstevel 	req_cmd = MAN_WORK_SWITCH;
44403831d35Sstevel 
44503831d35Sstevel 	status = mboxsc_putmsg(IOSRAM_KEY_MDSC, MBOXSC_MSG_REQUEST,
44603831d35Sstevel 	    req_cmd, &req_tid, sizeof (man_mbox_msg_t), &req,
44703831d35Sstevel 	    MAN_IOSRAM_TIMEOUT);
44803831d35Sstevel 
44903831d35Sstevel 	if (status != 0) {
45003831d35Sstevel 		cmn_err(CE_WARN, "man_dossc_switch: mboxsc_putmsg failed,"
45103831d35Sstevel 		    " errno = %d", status);
45203831d35Sstevel 		goto exit;
45303831d35Sstevel 	}
45403831d35Sstevel 
45503831d35Sstevel 	bzero((char *)&resp, sizeof (man_mbox_msg_t));
45603831d35Sstevel 
45703831d35Sstevel 	resp_tid = type = resp_cmd = 0;
45803831d35Sstevel 	length = sizeof (man_mbox_msg_t);
45903831d35Sstevel 	status = mboxsc_getmsg(IOSRAM_KEY_SCMD, &type, &resp_cmd, &resp_tid,
46003831d35Sstevel 	    &length, (void *)&resp, MAN_IOSRAM_TIMEOUT);
46103831d35Sstevel 	if (status != 0) {
46203831d35Sstevel 		cmn_err(CE_WARN, "man_dossc_switch: mboxsc_getmsg failed,"
46303831d35Sstevel 		    " errno = %d", status);
46403831d35Sstevel 		goto exit;
46503831d35Sstevel 	}
46603831d35Sstevel 
46703831d35Sstevel 	MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: received message"));
46803831d35Sstevel 
46903831d35Sstevel 	if (req_cmd != resp_cmd || req_tid != resp_tid) {
47003831d35Sstevel 		cmn_err(CE_WARN, "man_dossc_switch: failed,"
47103831d35Sstevel 		    " cmd/transid mismatch (%d, %d)/(%d, %d)",
47203831d35Sstevel 		    req_cmd, resp_cmd, (int)req_tid, (int)resp_tid);
47303831d35Sstevel 		status = EINVAL;
47403831d35Sstevel 		goto exit;
47503831d35Sstevel 	}
47603831d35Sstevel 
47703831d35Sstevel 	status = resp.mb_status;
47803831d35Sstevel 	if (status != 0) {
47903831d35Sstevel 		cmn_err(CE_WARN, "man_dossc_switch: failed errno == %d",
48003831d35Sstevel 		    status);
48103831d35Sstevel 	}
48203831d35Sstevel exit:
48303831d35Sstevel 	return (status);
48403831d35Sstevel }
48503831d35Sstevel 
48603831d35Sstevel 
48703831d35Sstevel /*
48803831d35Sstevel  *  Read IOSRAM info.
48903831d35Sstevel  */
49003831d35Sstevel int
man_get_iosram(manc_t * mcp)49103831d35Sstevel man_get_iosram(manc_t *mcp)
49203831d35Sstevel {
49303831d35Sstevel 	int	status;
49403831d35Sstevel 
49503831d35Sstevel 	if (mcp == NULL)
49603831d35Sstevel 		return (EINVAL);
49703831d35Sstevel 
49803831d35Sstevel 	status = iosram_rd(IOSRAM_KEY_MANC, 0, sizeof (manc_t), (caddr_t)mcp);
49903831d35Sstevel 	if (status) {
50003831d35Sstevel 		cmn_err(CE_WARN, "man_get_iosram: iosram_rd failed"
50103831d35Sstevel 		    " errno = %d\n", status);
50203831d35Sstevel 		return (status);
50303831d35Sstevel 	}
50403831d35Sstevel 
50503831d35Sstevel 	MAN_DBG(MAN_PATH, ("man_get_iosram:"));
50603831d35Sstevel 	MAN_DBGCALL(MAN_PATH, man_print_manc(mcp));
50703831d35Sstevel 
50803831d35Sstevel 	if (mcp->manc_magic != IOSRAM_KEY_MANC) {
50903831d35Sstevel 		cmn_err(CE_WARN, "man_get_iosram: bad magic - got(0x%x)"
51003831d35Sstevel 		    " expected(0x%x)\n", mcp->manc_magic, IOSRAM_KEY_MANC);
51103831d35Sstevel 		status = EIO;
51203831d35Sstevel 	} else if (mcp->manc_version != MANC_VERSION) {
51303831d35Sstevel 		cmn_err(CE_WARN, "man_get_iosram: version mismatch -"
51403831d35Sstevel 		    " got(0x%x) expected(0x%x)\n", mcp->manc_version,
51503831d35Sstevel 		    MANC_VERSION);
51603831d35Sstevel 		status = EIO;
51703831d35Sstevel 	}
51803831d35Sstevel 
51903831d35Sstevel 	return (status);
52003831d35Sstevel }
52103831d35Sstevel 
52203831d35Sstevel #if defined(MAN_NO_IOSRAM)
52303831d35Sstevel 
52403831d35Sstevel static manc_t	manc = {
52503831d35Sstevel 	IOSRAM_KEY_MANC,
52603831d35Sstevel 	MANC_VERSION,
52703831d35Sstevel 	0,
52803831d35Sstevel 	AF_INET,
52903831d35Sstevel /*	0x10010102,		Two */
53003831d35Sstevel 	0x10010103,		/* Scot */
53103831d35Sstevel 	0xFF000000,		/* Scot netmask */
53203831d35Sstevel 	0x10010101,		/* SC 10.1.1.1 */
53303831d35Sstevel 	{0},	/* AF_INET6 addrs */
53403831d35Sstevel 	{0},	/* AF_INET6 addrs */
53503831d35Sstevel 	{0},
53603831d35Sstevel /*	{0x8, 0x0, 0x20, 0x21, 0x44, 0x83},	Domain eaddr "two" */
53703831d35Sstevel 	{0x8, 0x0, 0x20, 0x8f, 0x84, 0x63},	/* Domain eaddr "scot" */
53803831d35Sstevel 	{0x8, 0x0, 0x20, 0x1f, 0xe3, 0x46},	/* SC eaddr "one" */
53903831d35Sstevel 	0x1,
54003831d35Sstevel 	0x1
54103831d35Sstevel };
54203831d35Sstevel 
54303831d35Sstevel 
54403831d35Sstevel /*
54503831d35Sstevel  *  Get IOSRAM info or release it.
54603831d35Sstevel  */
54703831d35Sstevel int
man_get_iosram(manc_t * mcp)54803831d35Sstevel man_get_iosram(manc_t *mcp)
54903831d35Sstevel {
55003831d35Sstevel 	int	status = 0;
55103831d35Sstevel 
55203831d35Sstevel 	if (mcp == NULL)
55303831d35Sstevel 		return (EINVAL);
55403831d35Sstevel 
55503831d35Sstevel 	*mcp = manc;
55603831d35Sstevel 
55703831d35Sstevel 	if (mcp->manc_magic != IOSRAM_KEY_MANC) {
55803831d35Sstevel 		cmn_err(CE_WARN, "man_get_iosram: bad magic - got(0x%x)"
55903831d35Sstevel 		    " expected(0x%x)\n", mcp->manc_magic, IOSRAM_KEY_MANC);
56003831d35Sstevel 		status = EIO;
56103831d35Sstevel 	} else if (mcp->manc_version != MANC_VERSION) {
56203831d35Sstevel 		cmn_err(CE_WARN, "man_get_iosram: version mismatch -"
56303831d35Sstevel 		    " got(0x%x) expected(0x%x)\n", mcp->manc_version,
56403831d35Sstevel 		    MANC_VERSION);
56503831d35Sstevel 		status = EIO;
56603831d35Sstevel 	}
56703831d35Sstevel 
56803831d35Sstevel 	return (status);
56903831d35Sstevel }
57003831d35Sstevel #endif  /* MAN_NO_IOSRAM */
57103831d35Sstevel 
57203831d35Sstevel /*
57303831d35Sstevel  * Find all RIOs on the IO boards for the domain. We walk all the children
57403831d35Sstevel  * of the root node looking for a PCI devinfo with a safari port ID of
57503831d35Sstevel  * 0xDC that has a child with device ID of 3.  This is gauranteed to be
57603831d35Sstevel  * the network portion of the RIO by virtue of the way Starcats are
57703831d35Sstevel  * physically built.
57803831d35Sstevel  */
57903831d35Sstevel static int
man_find_devs(mi_path_t * mipathp,uchar_t golden_iob)58003831d35Sstevel man_find_devs(mi_path_t *mipathp, uchar_t golden_iob)
58103831d35Sstevel {
58203831d35Sstevel 	dev_info_t	*bus_dip;
58303831d35Sstevel 	dev_info_t	*eri_dip;
58403831d35Sstevel 	dev_info_t	*rdip, *pdip;
58503831d35Sstevel 	int		exp_id;
58603831d35Sstevel 	int		found = 0;
58703831d35Sstevel 	int		circ;
58803831d35Sstevel 	int		circ2;
58903831d35Sstevel 	man_dev_t	ndev;
59003831d35Sstevel 	int		xmits;
59103831d35Sstevel 
59203831d35Sstevel 	MAN_DBG(MAN_PATH, ("man_find_devs: mdevpp(0x%p) golden_iob(%d)\n",
59303831d35Sstevel 	    (void *)(mipathp), golden_iob));
59403831d35Sstevel 
59503831d35Sstevel 	/*
59603831d35Sstevel 	 * Hold parent busy while walking its child list.
59703831d35Sstevel 	 */
59803831d35Sstevel 	rdip = ddi_root_node();
59903831d35Sstevel 	ndi_devi_enter(rdip, &circ);
60003831d35Sstevel 	bus_dip = ddi_get_child(rdip);
60103831d35Sstevel 
60203831d35Sstevel 	while (bus_dip != NULL) {
60303831d35Sstevel 		exp_id = -1;
60403831d35Sstevel 		xmits = 0;
60503831d35Sstevel 		if (man_dip_is_schizoxmits0_pcib(bus_dip, &exp_id, &xmits)) {
60603831d35Sstevel 			eri_dip = NULL;
60703831d35Sstevel 			pdip = bus_dip;
60803831d35Sstevel 			if (xmits) {
60903831d35Sstevel 				/*
61003831d35Sstevel 				 * If this is XMITS0 PCI_B leaf, then the
61103831d35Sstevel 				 * pci_pci bridge which is the only child,
61203831d35Sstevel 				 * is the parent to MAN RIO.
61303831d35Sstevel 				 */
61403831d35Sstevel 				pdip = ddi_get_child(bus_dip);
61503831d35Sstevel 				if (pdip == NULL) {
61603831d35Sstevel 					bus_dip = ddi_get_next_sibling(bus_dip);
61703831d35Sstevel 					continue;
61803831d35Sstevel 				}
61903831d35Sstevel 			}
62003831d35Sstevel 			ndi_devi_enter(pdip, &circ2);
62103831d35Sstevel 			eri_dip = ddi_get_child(pdip);
62203831d35Sstevel 			while (eri_dip != NULL) {
62303831d35Sstevel 				MAN_DBG(MAN_PATH, ("man_find_devs: "
62403831d35Sstevel 				    "eri_dip %s\n",
62503831d35Sstevel 				    ddi_binding_name(eri_dip)));
62603831d35Sstevel 				if (man_dip_is_eri(eri_dip, &ndev) &&
62703831d35Sstevel 				    man_dip_is_attached(eri_dip)) {
62803831d35Sstevel 
62903831d35Sstevel 					ASSERT(exp_id != -1);
63003831d35Sstevel 					ndev.mdev_exp_id = exp_id;
63103831d35Sstevel 					ndev.mdev_state = MDEV_ASSIGNED;
63203831d35Sstevel 					mipathp->mip_devs[found] = ndev;
63303831d35Sstevel 					found++;
63403831d35Sstevel 
63503831d35Sstevel 					MAN_DBG(MAN_PATH,
63603831d35Sstevel 					    ("man_find_devs: found eri maj(%d) "
63703831d35Sstevel 					    "ppa(%d) on expander(%d)\n",
63803831d35Sstevel 					    ndev.mdev_major,
63903831d35Sstevel 					    ndev.mdev_ppa, exp_id));
64003831d35Sstevel 				}
64103831d35Sstevel 				eri_dip = ddi_get_next_sibling(eri_dip);
64203831d35Sstevel 			}
64303831d35Sstevel 			ndi_devi_exit(pdip, circ2);
64403831d35Sstevel 		}
64503831d35Sstevel 		bus_dip = ddi_get_next_sibling(bus_dip);
64603831d35Sstevel 	}
64703831d35Sstevel 	ndi_devi_exit(rdip, circ);
64803831d35Sstevel 
64903831d35Sstevel 	MAN_DBG(MAN_PATH, ("man_find_devs returns found = %d\n", found));
65003831d35Sstevel 
65103831d35Sstevel 	mipathp->mip_ndevs = found;
65203831d35Sstevel 	return (found);
65303831d35Sstevel }
65403831d35Sstevel 
65503831d35Sstevel /*
65603831d35Sstevel  * Verify if the dip passed is an instance of 'eri' and set
65703831d35Sstevel  * the device info in mdevp.
65803831d35Sstevel  */
65903831d35Sstevel static int
man_get_eri_dev_info(dev_info_t * dip,man_dev_t * mdevp)66003831d35Sstevel man_get_eri_dev_info(dev_info_t *dip, man_dev_t *mdevp)
66103831d35Sstevel {
66203831d35Sstevel 	dev_info_t	*parent_dip;
66303831d35Sstevel 	int		exp_id;
66403831d35Sstevel 	int		xmits;
66503831d35Sstevel 	char		*name;
66603831d35Sstevel 
66703831d35Sstevel 	ASSERT(dip != NULL);
66803831d35Sstevel 	/*
66903831d35Sstevel 	 * Verify if the parent is schizo(xmits)0 and pci B leaf.
67003831d35Sstevel 	 */
67103831d35Sstevel 	if (((parent_dip = ddi_get_parent(dip)) == NULL) ||
67203831d35Sstevel 	    ((name = ddi_binding_name(parent_dip)) == NULL))
67303831d35Sstevel 		return (FALSE);
67403831d35Sstevel 	if (strcmp(name, MAN_SCHIZO_BINDING_NAME) != 0) {
67503831d35Sstevel 		/*
67603831d35Sstevel 		 * This RIO could be on XMITS, so get the dip to
67703831d35Sstevel 		 * XMITS PCI Leaf.
67803831d35Sstevel 		 */
67903831d35Sstevel 		if ((parent_dip = ddi_get_parent(parent_dip)) == NULL)
68003831d35Sstevel 			return (FALSE);
68103831d35Sstevel 		if (((name = ddi_binding_name(parent_dip)) == NULL) ||
68203831d35Sstevel 		    (strcmp(name, MAN_XMITS_BINDING_NAME) != 0)) {
68303831d35Sstevel 			return (FALSE);
68403831d35Sstevel 		}
68503831d35Sstevel 	}
68603831d35Sstevel 	if (man_dip_is_schizoxmits0_pcib(parent_dip, &exp_id, &xmits) == FALSE)
68703831d35Sstevel 		return (FALSE);
68803831d35Sstevel 
68903831d35Sstevel 	/*
69003831d35Sstevel 	 * Make sure it is attached.
69103831d35Sstevel 	 */
69203831d35Sstevel 	if (man_dip_is_attached(dip) == FALSE) {
69303831d35Sstevel 		MAN_DBG(MAN_DR, ("man_get_eri_dev_info: "
694*07d06da5SSurya Prakki 		    "dip 0x%p not attached\n", (void *)dip));
69503831d35Sstevel 		return (FALSE);
69603831d35Sstevel 	}
69703831d35Sstevel 	mdevp->mdev_exp_id = exp_id;
69803831d35Sstevel 	mdevp->mdev_ppa = ddi_get_instance(dip);
6995c066ec2SJerry Gilliam 	mdevp->mdev_major = ddi_driver_major(dip);
70003831d35Sstevel 	mdevp->mdev_state = MDEV_ASSIGNED;
70103831d35Sstevel 	return (TRUE);
70203831d35Sstevel }
70303831d35Sstevel 
70403831d35Sstevel /*
70503831d35Sstevel  * MAN RIO is connected to SCHIZO/XMITS 0 and PCI_B Leaf.
70603831d35Sstevel  * Incase of XMITS, it is actually connected to a PCI Bridge(21154)
70703831d35Sstevel  * which is directly connected to the PCI_B leaf of XMITS0.
70803831d35Sstevel  *
70903831d35Sstevel  * This function verifies if the given dip is SCHIZO/XMITS 0 and
71003831d35Sstevel  * PCI_B Leaf. This is done as follows:
71103831d35Sstevel  *
71203831d35Sstevel  * 	- Check the binding name to verify SCHIZO/XMITS.
71303831d35Sstevel  * 	- Verify the Device type to be "pci".
71403831d35Sstevel  *	- Verify the PortID to be ending with 0x1C
71503831d35Sstevel  * 	- Verify the the CSR base to be 0x70.0000.
71603831d35Sstevel  */
71703831d35Sstevel static int
man_dip_is_schizoxmits0_pcib(dev_info_t * dip,int * exp_id,int * xmits)71803831d35Sstevel man_dip_is_schizoxmits0_pcib(dev_info_t *dip, int *exp_id, int *xmits)
71903831d35Sstevel {
72003831d35Sstevel 	char			dtype[MAN_DDI_BUFLEN];
72103831d35Sstevel 	int			portid;
72203831d35Sstevel 	uint_t			pci_csr_base;
72303831d35Sstevel 	struct pci_phys_spec	*regbuf = NULL;
72403831d35Sstevel 	int			length = MAN_DDI_BUFLEN;
72503831d35Sstevel 	char			*name;
72603831d35Sstevel 
72703831d35Sstevel 	ASSERT(dip != NULL);
72803831d35Sstevel 	*exp_id = -1;
72903831d35Sstevel 	if ((name = ddi_binding_name(dip)) == NULL)
73003831d35Sstevel 		return (FALSE);
73103831d35Sstevel 	if (strcmp(name, MAN_SCHIZO_BINDING_NAME) == 0) {
73203831d35Sstevel 		MAN_DBG(MAN_PATH, ("man_dip_is_schizoxmits0_pcib: "
733*07d06da5SSurya Prakki 		    "SCHIZO found 0x%p\n", (void *)dip));
73403831d35Sstevel 	} else if (strcmp(name, MAN_XMITS_BINDING_NAME) == 0) {
73503831d35Sstevel 		*xmits = TRUE;
73603831d35Sstevel 		MAN_DBG(MAN_PATH, ("man_dip_is_schizoxmits0_pcib: "
737*07d06da5SSurya Prakki 		    "XMITS found 0x%p\n", (void *)dip));
73803831d35Sstevel 	} else
73903831d35Sstevel 		return (FALSE);
74003831d35Sstevel 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, MAN_DEVTYPE_PROP,
74103831d35Sstevel 	    (caddr_t)dtype, &length) == DDI_PROP_SUCCESS) {
74203831d35Sstevel 
74303831d35Sstevel 		MAN_DBG(MAN_PATH, ("dtype: %s\n", dtype));
74403831d35Sstevel 		if (strncmp(dtype, MAN_DEVTYPE_PCI, 3) != 0)
74503831d35Sstevel 			goto notfound;
74603831d35Sstevel 
74703831d35Sstevel 		/*
74803831d35Sstevel 		 * Get safari ID (DDI port ID).
74903831d35Sstevel 		 */
75003831d35Sstevel 		if ((portid = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 0,
75103831d35Sstevel 		    MAN_PORTID_PROP, -1)) == -1) {
75203831d35Sstevel 
75303831d35Sstevel 			MAN_DBG(MAN_PATH, ("ddi_getpropp: failed\n"));
75403831d35Sstevel 			goto notfound;
75503831d35Sstevel 		}
75603831d35Sstevel 
75703831d35Sstevel 		/*
75803831d35Sstevel 		 * All schizo 0 safari IDs end in 0x1C.
75903831d35Sstevel 		 */
76003831d35Sstevel 		if ((portid & MAN_SCHIZO_MASK) != MAN_SCHIZO_0_ID)
76103831d35Sstevel 			goto notfound;
76203831d35Sstevel 
76303831d35Sstevel 		/*
76403831d35Sstevel 		 * All PCI nodes "B" are at configspace 0x70.0000
76503831d35Sstevel 		 */
76603831d35Sstevel 		if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
76703831d35Sstevel 		    MAN_REG_PROP, (caddr_t)&regbuf,
76803831d35Sstevel 		    &length) != DDI_PROP_SUCCESS) {
76903831d35Sstevel 
77003831d35Sstevel 			MAN_DBG(MAN_PATH, ("ddi_getlongprop_buf: failed"));
77103831d35Sstevel 			goto notfound;
77203831d35Sstevel 		}
77303831d35Sstevel 
77403831d35Sstevel 		pci_csr_base = regbuf[0].pci_phys_mid & PCI_CONF_ADDR_MASK;
77503831d35Sstevel 		kmem_free(regbuf, length);
77603831d35Sstevel 		if (pci_csr_base == MAN_PCI_B_CSR_BASE) {
77703831d35Sstevel 
77803831d35Sstevel 			MAN_DBG(MAN_PATH, ("man_dip_is_schizoxmits0_pcib:"
77903831d35Sstevel 			    " found PCI B at dip(0x%p)\n", (void *)dip));
78003831d35Sstevel 
78103831d35Sstevel 			*exp_id = portid >> 5;
78203831d35Sstevel 			return (TRUE);
78303831d35Sstevel 		}
78403831d35Sstevel 	}
78503831d35Sstevel 
78603831d35Sstevel notfound:
78703831d35Sstevel 	return (FALSE);
78803831d35Sstevel }
78903831d35Sstevel 
79003831d35Sstevel static int
man_dip_is_eri(dev_info_t * dip,man_dev_t * ndevp)79103831d35Sstevel man_dip_is_eri(dev_info_t *dip, man_dev_t *ndevp)
79203831d35Sstevel {
79303831d35Sstevel 	struct pci_phys_spec	*regbuf = NULL;
79403831d35Sstevel 	int			length = 0;
79503831d35Sstevel 	uint_t			pci_device;
79603831d35Sstevel 	uint_t			pci_function;
79703831d35Sstevel 
79803831d35Sstevel 	MAN_DBG(MAN_PATH, ("man_dip_is_eri: dip(0x%p) ndevp(0x%p)\n",
79903831d35Sstevel 	    (void *)dip, (void *)ndevp));
80003831d35Sstevel 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
80103831d35Sstevel 	    MAN_REG_PROP, (caddr_t)&regbuf,
80203831d35Sstevel 	    &length) == DDI_PROP_SUCCESS) {
80303831d35Sstevel 
80403831d35Sstevel 		pci_device = PCI_REG_DEV_G(regbuf->pci_phys_hi);
80503831d35Sstevel 		pci_function = PCI_REG_FUNC_G(regbuf->pci_phys_hi);
80603831d35Sstevel 		kmem_free(regbuf, length);
80703831d35Sstevel 
80803831d35Sstevel 		/*
80903831d35Sstevel 		 * The network function of the RIO ASIC will always
81003831d35Sstevel 		 * be device 3 and function 1 ("network@3,1").
81103831d35Sstevel 		 */
81203831d35Sstevel 		if (pci_device == 3 && pci_function == 1) {
81303831d35Sstevel 			ndevp->mdev_ppa = ddi_get_instance(dip);
8145c066ec2SJerry Gilliam 			ndevp->mdev_major = ddi_driver_major(dip);
81503831d35Sstevel 
81603831d35Sstevel 			MAN_DBG(MAN_PATH, ("man_dip_is_eri: found eri maj(%d)"
81703831d35Sstevel 			    " ppa(%d)\n", ndevp->mdev_major, ndevp->mdev_ppa));
81803831d35Sstevel 
81903831d35Sstevel 			return (TRUE);
82003831d35Sstevel 		}
82103831d35Sstevel 	}
82203831d35Sstevel 
82303831d35Sstevel 	MAN_DBG(MAN_PATH, ("man_dip_is_eri: returns FALSE\n"));
82403831d35Sstevel 
82503831d35Sstevel 	return (FALSE);
82603831d35Sstevel }
82703831d35Sstevel 
82803831d35Sstevel static int
man_dip_is_attached(dev_info_t * dip)82903831d35Sstevel man_dip_is_attached(dev_info_t *dip)
83003831d35Sstevel {
83103831d35Sstevel 	int state;
83203831d35Sstevel 
83303831d35Sstevel 	state = ddi_get_devstate(dip);
83403831d35Sstevel 	if (i_ddi_devi_attached(dip) || (state == DDI_DEVSTATE_UP)) {
83503831d35Sstevel 		/*
83603831d35Sstevel 		 * The instance info is more important for us,
83703831d35Sstevel 		 * so verify.
83803831d35Sstevel 		 */
83903831d35Sstevel 		if (ddi_get_instance(dip) >=  0) {
84003831d35Sstevel 			return (TRUE);
84103831d35Sstevel 		}
84203831d35Sstevel 		cmn_err(CE_WARN, "man_dip_is_attached: "
843*07d06da5SSurya Prakki 		    "eri 0x%p instance is not set yet", (void *)dip);
84403831d35Sstevel 
84503831d35Sstevel 	}
84603831d35Sstevel 	return (FALSE);
84703831d35Sstevel }
84803831d35Sstevel 
84903831d35Sstevel #if defined(DEBUG)
85003831d35Sstevel static void
man_print_manc(manc_t * mcp)85103831d35Sstevel man_print_manc(manc_t *mcp)
85203831d35Sstevel {
85303831d35Sstevel 	cmn_err(CE_CONT, "\tmcp(0x%p)\n\n", (void *)mcp);
85403831d35Sstevel 
85503831d35Sstevel 	if (mcp == NULL)
85603831d35Sstevel 		return;
85703831d35Sstevel 
85803831d35Sstevel 	cmn_err(CE_CONT, "\tmagic: 0x%x\n", mcp->manc_magic);
85903831d35Sstevel 	cmn_err(CE_CONT, "\tversion: 0x%x\n", mcp->manc_version);
86003831d35Sstevel 	cmn_err(CE_CONT, "\tcsum: %d\n", mcp->manc_csum);
86103831d35Sstevel 	cmn_err(CE_CONT, "\tdom_eaddr: %s\n",
86203831d35Sstevel 	    ether_sprintf(&mcp->manc_dom_eaddr));
86303831d35Sstevel 	cmn_err(CE_CONT, "\tsc_eaddr: %s\n",
86403831d35Sstevel 	    ether_sprintf(&mcp->manc_sc_eaddr));
86503831d35Sstevel 	cmn_err(CE_CONT, "\tiob_bitmap: 0x%x\n", mcp->manc_iob_bitmap);
86603831d35Sstevel 	cmn_err(CE_CONT, "\tgolden_iob: %d\n", mcp->manc_golden_iob);
86703831d35Sstevel 
86803831d35Sstevel }
86903831d35Sstevel 
87003831d35Sstevel #endif  /* DEBUG */
871