03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License (the "License").
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Domain specific portion of the Starcat Management Network Driver
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/types.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/proc.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/kmem.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/kstat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ksynch.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stream.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/dlpi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stropts.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/strsubr.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/debug.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/conf.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/kstr.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/errno.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ethernet.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/byteorder.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/modctl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/strsun.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/pci.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/callb.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/pci.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/iosramio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/mboxsc.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <netinet/in.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <inet/common.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <inet/mi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <inet/nd.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/socket.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <netinet/igmp_var.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <netinet/ip6.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <netinet/icmp6.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <inet/ip.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <inet/ip6.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/dman.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ddi_impldefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunndi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAN_SCHIZO_BINDING_NAME "pci108e,8001"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAN_XMITS_BINDING_NAME "pci108e,8002"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint man_is_on_domain = TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Domain side function prototypes.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint man_get_iosram(manc_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelint man_domain_configure(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelint man_domain_deconfigure(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelint man_path_discovery(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelint man_dossc_switch(uint32_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevelint man_dr_attach(dev_info_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelint man_dr_detach(dev_info_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_dr_submit_work_wait(dev_info_t *, int);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_find_devs(mi_path_t *, uchar_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_dip_is_schizoxmits0_pcib(dev_info_t *, int *, int *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_dip_is_eri(dev_info_t *, man_dev_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_dip_is_attached(dev_info_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_get_eri_dev_info(dev_info_t *, man_dev_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int man_mbox_initialized = FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Externs
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern int man_pg_cmd(mi_path_t *, man_work_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern kmutex_t man_lock;
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern void *man_softstate;
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern man_work_t *man_work_alloc(int, int);
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern void man_work_free(man_work_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern void man_work_add(man_workq_t *, man_work_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern man_workq_t *man_bwork_q;
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern man_workq_t *man_iwork_q;
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern queue_t *man_ctl_wq;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#if defined(DEBUG)
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void man_print_manc(manc_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern uint32_t man_debug;
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_domain_configure(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * man_mbox_initialized is protected by inner perimiter lock.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_mbox_initialized == TRUE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = mboxsc_init(IOSRAM_KEY_SCMD, MBOXSC_MBOX_IN, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_domain_configure: failed to initialize"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " MBOXSC_MBOX_IN, errno = %d", status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = mboxsc_init(IOSRAM_KEY_MDSC, MBOXSC_MBOX_OUT, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(IOSRAM_KEY_SCMD);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_domain_configure: failed to initialize"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " MBOXSC_MBOX_OUT, errno = %d", status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_mbox_initialized = TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = man_path_discovery();
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(IOSRAM_KEY_SCMD);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(IOSRAM_KEY_MDSC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_mbox_initialized = FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelexit:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Build pathgroup connecting a domain to the SSC. Only called on domains
03831d35f7499c87d51205817c93e9a8d42c4baestevel * at first man_open. On the SSC, pathgroups are built by IOCTL requests
03831d35f7499c87d51205817c93e9a8d42c4baestevel * from the MAN daemon (see man_ioctl and mand(1M)).
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Locks held
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - exclusive innerperim.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_path_discovery(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel manc_t manc;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mi_path_t mpath;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int num_devs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_CONFIG, ("man_path_discovery:"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status = man_get_iosram(&manc)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If manc_ip_type indicates MAN network is not enabled
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for this domain, then lets just bailout from here as if no
03831d35f7499c87d51205817c93e9a8d42c4baestevel * devices were found.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((manc.manc_ip_type != AF_INET) &&
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam (manc.manc_ip_type != AF_INET6)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBGCALL(MAN_CONFIG, man_print_manc(&manc));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Extract SC ethernet address from IOSRAM.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ether_copy(&manc.manc_sc_eaddr, &mpath.mip_eaddr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mpath.mip_pg_id = 0; /* SC is always pathgroup ID 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel mpath.mip_man_ppa = 0; /* Domain only has one ppa, 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get list of present devices, and update man_paths[] as needed.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel num_devs = man_find_devs(&mpath, MAN_MAX_EXPANDERS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (num_devs <= 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = ENODEV;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mpath.mip_cmd = MI_PATH_ASSIGN;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = man_pg_cmd(&mpath, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now activate the ethernet on the golden io board.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < num_devs; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mpath.mip_devs[i].mdev_exp_id == manc.manc_golden_iob)
03831d35f7499c87d51205817c93e9a8d42c4baestevel mpath.mip_devs[0] = mpath.mip_devs[i];
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel mpath.mip_ndevs = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mpath.mip_cmd = MI_PATH_ACTIVATE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = man_pg_cmd(&mpath, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelexit:
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_CONFIG, ("man_path_discovery: returns %d\n", status));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_domain_deconfigure(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(IOSRAM_KEY_SCMD);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(IOSRAM_KEY_MDSC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We are about to unload and know that there are no open
03831d35f7499c87d51205817c93e9a8d42c4baestevel * streams, so this change outside of the perimiter is ok.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_mbox_initialized = FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Add a work request to the inner perimeter with the new eri device info.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* ARGSUSED */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_dr_attach(dev_info_t *dip)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_t *manp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_work_t *wp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_dev_t mdev;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel manp = ddi_get_soft_state(man_softstate, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (manp == NULL || manp->man_pg == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_get_eri_dev_info(dip, &mdev) == FALSE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = ENODEV;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_DR, ("man_dr_attach: dip major = %d instance =%d",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam mdev.mdev_major, mdev.mdev_ppa));
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp = man_work_alloc(MAN_WORK_DRATTACH, KM_NOSLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (wp == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = ENOMEM;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_arg.a_man_ppa = 0; /* Domain only has one ppa, 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_arg.a_pg_id = 0; /* SC is always pathgroup ID 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_arg.a_sf_dev = mdev;
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_flags = MAN_WFLAGS_NOWAITER;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_work_add(man_iwork_q, wp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_ctl_wq)
03831d35f7499c87d51205817c93e9a8d42c4baestevel qenable(man_ctl_wq);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelexit:
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_dr_detach(dev_info_t *dip)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_t *manp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int retries = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel manp = ddi_get_soft_state(man_softstate, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (manp == NULL || manp->man_pg == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Arrange to have the detaching path switched if it is active.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We will cv_wait_sig for the switch to complete if it is needed.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelagain:
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = man_dr_submit_work_wait(dip, MAN_WORK_DRSWITCH);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status == EAGAIN && retries < manp->man_dr_retries) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Delay a bit and retry.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_DR,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ("man_dr_detach(switch): EAGAIN - retrying..."));
03831d35f7499c87d51205817c93e9a8d42c4baestevel retries++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel delay(drv_usectohz(manp->man_dr_delay));
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto again;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel retries = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Detaching device no longer in use, remove it from our
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pathgroup.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = man_dr_submit_work_wait(dip, MAN_WORK_DRDETACH);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status == EAGAIN && retries < manp->man_dr_retries) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_DR,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ("man_dr_detach(detach): EAGAIN - retrying..."));
03831d35f7499c87d51205817c93e9a8d42c4baestevel retries++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto again;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelexit:
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_DR, ("man_dr_detach: returns %d", status));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_dr_submit_work_wait(dev_info_t *dip, int work_type)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_work_t *wp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp = man_work_alloc(work_type, KM_NOSLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (wp == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = ENOMEM;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_arg.a_man_ppa = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_arg.a_pg_id = 0;
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam wp->mw_arg.a_sf_dev.mdev_major = ddi_driver_major(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_arg.a_sf_dev.mdev_ppa = ddi_get_instance(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_flags = MAN_WFLAGS_CVWAITER;
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_work_add(man_iwork_q, wp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* TBD - change to ASSERT ? */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_ctl_wq)
03831d35f7499c87d51205817c93e9a8d42c4baestevel qenable(man_ctl_wq);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (!(wp->mw_flags & MAN_WFLAGS_DONE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!cv_wait_sig(&wp->mw_cv, &man_lock)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel wp->mw_flags &= ~MAN_WFLAGS_CVWAITER;
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = EINTR;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Note that if cv_wait_sig() returns zero because a signal
03831d35f7499c87d51205817c93e9a8d42c4baestevel * was received, MAN_WFLAGS_DONE may not be set.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This will happen if man_dr_submit_work_wait() reacquires
03831d35f7499c87d51205817c93e9a8d42c4baestevel * man_lock before man_iwork() can acquire man_lock just before
03831d35f7499c87d51205817c93e9a8d42c4baestevel * signalling its work is complete.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * In this case, it is not necessary to call man_work_free()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * here because it will be called by man_iwork() because
03831d35f7499c87d51205817c93e9a8d42c4baestevel * MAN_WFLAGS_CVWAITER was cleared.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Should man_iwork() obtain man_lock to signal completion,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * MAN_WFLAGS_DONE will be set which will ensure man_work_free()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is called here.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (wp->mw_flags & MAN_WFLAGS_DONE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = wp->mw_status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_work_free(wp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&man_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelexit:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Notify SSC of switch request and wait for response.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_dossc_switch(uint32_t exp_id)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t req_tid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t req_cmd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t resp_tid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t resp_cmd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_mbox_msg_t req;
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_mbox_msg_t resp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t length;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * There should be nothing in inbound mailbox.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp_tid = resp_cmd = type = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel length = sizeof (man_mbox_msg_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((char *)&resp, sizeof (man_mbox_msg_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (mboxsc_getmsg(IOSRAM_KEY_SCMD, &type, &resp_cmd, &resp_tid,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam &length, &resp, 0) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp_tid = resp_cmd = type = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel length = sizeof (man_mbox_msg_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((char *)&resp, sizeof (man_mbox_msg_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: dumping message"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_IOSRAM, ("\tcommand = 0x%x", resp_cmd));
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: sending message"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((char *)&req, sizeof (man_mbox_msg_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel req.mb_status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel req.mb_exp_id = exp_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_tid = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_cmd = MAN_WORK_SWITCH;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = mboxsc_putmsg(IOSRAM_KEY_MDSC, MBOXSC_MSG_REQUEST,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam req_cmd, &req_tid, sizeof (man_mbox_msg_t), &req,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam MAN_IOSRAM_TIMEOUT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_dossc_switch: mboxsc_putmsg failed,"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " errno = %d", status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((char *)&resp, sizeof (man_mbox_msg_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp_tid = type = resp_cmd = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel length = sizeof (man_mbox_msg_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = mboxsc_getmsg(IOSRAM_KEY_SCMD, &type, &resp_cmd, &resp_tid,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam &length, (void *)&resp, MAN_IOSRAM_TIMEOUT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_dossc_switch: mboxsc_getmsg failed,"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " errno = %d", status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: received message"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (req_cmd != resp_cmd || req_tid != resp_tid) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_dossc_switch: failed,"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " cmd/transid mismatch (%d, %d)/(%d, %d)",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam req_cmd, resp_cmd, (int)req_tid, (int)resp_tid);
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = EINVAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto exit;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = resp.mb_status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_dossc_switch: failed errno == %d",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevelexit:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Read IOSRAM info.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_get_iosram(manc_t *mcp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mcp == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = iosram_rd(IOSRAM_KEY_MANC, 0, sizeof (manc_t), (caddr_t)mcp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (status) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_get_iosram: iosram_rd failed"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " errno = %d\n", status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_get_iosram:"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBGCALL(MAN_PATH, man_print_manc(mcp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mcp->manc_magic != IOSRAM_KEY_MANC) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_get_iosram: bad magic - got(0x%x)"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " expected(0x%x)\n", mcp->manc_magic, IOSRAM_KEY_MANC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = EIO;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (mcp->manc_version != MANC_VERSION) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_get_iosram: version mismatch -"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " got(0x%x) expected(0x%x)\n", mcp->manc_version,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam MANC_VERSION);
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = EIO;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#if defined(MAN_NO_IOSRAM)
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic manc_t manc = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel IOSRAM_KEY_MANC,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MANC_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0,
03831d35f7499c87d51205817c93e9a8d42c4baestevel AF_INET,
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* 0x10010102, Two */
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0x10010103, /* Scot */
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0xFF000000, /* Scot netmask */
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0x10010101, /* SC 10.1.1.1 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel {0}, /* AF_INET6 addrs */
03831d35f7499c87d51205817c93e9a8d42c4baestevel {0}, /* AF_INET6 addrs */
03831d35f7499c87d51205817c93e9a8d42c4baestevel {0},
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* {0x8, 0x0, 0x20, 0x21, 0x44, 0x83}, Domain eaddr "two" */
03831d35f7499c87d51205817c93e9a8d42c4baestevel {0x8, 0x0, 0x20, 0x8f, 0x84, 0x63}, /* Domain eaddr "scot" */
03831d35f7499c87d51205817c93e9a8d42c4baestevel {0x8, 0x0, 0x20, 0x1f, 0xe3, 0x46}, /* SC eaddr "one" */
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0x1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0x1
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get IOSRAM info or release it.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_get_iosram(manc_t *mcp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mcp == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel *mcp = manc;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mcp->manc_magic != IOSRAM_KEY_MANC) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_get_iosram: bad magic - got(0x%x)"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " expected(0x%x)\n", mcp->manc_magic, IOSRAM_KEY_MANC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = EIO;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (mcp->manc_version != MANC_VERSION) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_get_iosram: version mismatch -"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " got(0x%x) expected(0x%x)\n", mcp->manc_version,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam MANC_VERSION);
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = EIO;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* MAN_NO_IOSRAM */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find all RIOs on the IO boards for the domain. We walk all the children
03831d35f7499c87d51205817c93e9a8d42c4baestevel * of the root node looking for a PCI devinfo with a safari port ID of
03831d35f7499c87d51205817c93e9a8d42c4baestevel * 0xDC that has a child with device ID of 3. This is gauranteed to be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the network portion of the RIO by virtue of the way Starcats are
03831d35f7499c87d51205817c93e9a8d42c4baestevel * physically built.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_find_devs(mi_path_t *mipathp, uchar_t golden_iob)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel dev_info_t *bus_dip;
03831d35f7499c87d51205817c93e9a8d42c4baestevel dev_info_t *eri_dip;
03831d35f7499c87d51205817c93e9a8d42c4baestevel dev_info_t *rdip, *pdip;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int exp_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int found = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int circ;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int circ2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel man_dev_t ndev;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int xmits;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_find_devs: mdevpp(0x%p) golden_iob(%d)\n",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam (void *)(mipathp), golden_iob));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Hold parent busy while walking its child list.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel rdip = ddi_root_node();
03831d35f7499c87d51205817c93e9a8d42c4baestevel ndi_devi_enter(rdip, &circ);
03831d35f7499c87d51205817c93e9a8d42c4baestevel bus_dip = ddi_get_child(rdip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (bus_dip != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel exp_id = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel xmits = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_dip_is_schizoxmits0_pcib(bus_dip, &exp_id, &xmits)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel eri_dip = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel pdip = bus_dip;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (xmits) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If this is XMITS0 PCI_B leaf, then the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pci_pci bridge which is the only child,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is the parent to MAN RIO.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel pdip = ddi_get_child(bus_dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pdip == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bus_dip = ddi_get_next_sibling(bus_dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel ndi_devi_enter(pdip, &circ2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel eri_dip = ddi_get_child(pdip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (eri_dip != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_find_devs: "
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam "eri_dip %s\n",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ddi_binding_name(eri_dip)));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_dip_is_eri(eri_dip, &ndev) &&
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam man_dip_is_attached(eri_dip)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(exp_id != -1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ndev.mdev_exp_id = exp_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ndev.mdev_state = MDEV_ASSIGNED;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mipathp->mip_devs[found] = ndev;
03831d35f7499c87d51205817c93e9a8d42c4baestevel found++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH,
03831d35f7499c87d51205817c93e9a8d42c4baestevel ("man_find_devs: found eri maj(%d) "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ppa(%d) on expander(%d)\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel ndev.mdev_major,
03831d35f7499c87d51205817c93e9a8d42c4baestevel ndev.mdev_ppa, exp_id));
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel eri_dip = ddi_get_next_sibling(eri_dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel ndi_devi_exit(pdip, circ2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel bus_dip = ddi_get_next_sibling(bus_dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel ndi_devi_exit(rdip, circ);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_find_devs returns found = %d\n", found));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mipathp->mip_ndevs = found;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (found);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Verify if the dip passed is an instance of 'eri' and set
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the device info in mdevp.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_get_eri_dev_info(dev_info_t *dip, man_dev_t *mdevp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel dev_info_t *parent_dip;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int exp_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int xmits;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(dip != NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Verify if the parent is schizo(xmits)0 and pci B leaf.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (((parent_dip = ddi_get_parent(dip)) == NULL) ||
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ((name = ddi_binding_name(parent_dip)) == NULL))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(name, MAN_SCHIZO_BINDING_NAME) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This RIO could be on XMITS, so get the dip to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * XMITS PCI Leaf.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((parent_dip = ddi_get_parent(parent_dip)) == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (((name = ddi_binding_name(parent_dip)) == NULL) ||
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam (strcmp(name, MAN_XMITS_BINDING_NAME) != 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_dip_is_schizoxmits0_pcib(parent_dip, &exp_id, &xmits) == FALSE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Make sure it is attached.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (man_dip_is_attached(dip) == FALSE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_DR, ("man_get_eri_dev_info: "
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki "dip 0x%p not attached\n", (void *)dip));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel mdevp->mdev_exp_id = exp_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mdevp->mdev_ppa = ddi_get_instance(dip);
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam mdevp->mdev_major = ddi_driver_major(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mdevp->mdev_state = MDEV_ASSIGNED;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (TRUE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * MAN RIO is connected to SCHIZO/XMITS 0 and PCI_B Leaf.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Incase of XMITS, it is actually connected to a PCI Bridge(21154)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * which is directly connected to the PCI_B leaf of XMITS0.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function verifies if the given dip is SCHIZO/XMITS 0 and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * PCI_B Leaf. This is done as follows:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Check the binding name to verify SCHIZO/XMITS.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Verify the Device type to be "pci".
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Verify the PortID to be ending with 0x1C
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Verify the the CSR base to be 0x70.0000.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_dip_is_schizoxmits0_pcib(dev_info_t *dip, int *exp_id, int *xmits)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel char dtype[MAN_DDI_BUFLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel int portid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint_t pci_csr_base;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct pci_phys_spec *regbuf = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int length = MAN_DDI_BUFLEN;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(dip != NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel *exp_id = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((name = ddi_binding_name(dip)) == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(name, MAN_SCHIZO_BINDING_NAME) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_dip_is_schizoxmits0_pcib: "
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki "SCHIZO found 0x%p\n", (void *)dip));
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(name, MAN_XMITS_BINDING_NAME) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel *xmits = TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_dip_is_schizoxmits0_pcib: "
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki "XMITS found 0x%p\n", (void *)dip));
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, MAN_DEVTYPE_PROP,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam (caddr_t)dtype, &length) == DDI_PROP_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("dtype: %s\n", dtype));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(dtype, MAN_DEVTYPE_PCI, 3) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto notfound;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get safari ID (DDI port ID).
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((portid = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 0,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam MAN_PORTID_PROP, -1)) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("ddi_getpropp: failed\n"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto notfound;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * All schizo 0 safari IDs end in 0x1C.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((portid & MAN_SCHIZO_MASK) != MAN_SCHIZO_0_ID)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto notfound;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * All PCI nodes "B" are at configspace 0x70.0000
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam MAN_REG_PROP, (caddr_t)&regbuf,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam &length) != DDI_PROP_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("ddi_getlongprop_buf: failed"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto notfound;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_csr_base = regbuf[0].pci_phys_mid & PCI_CONF_ADDR_MASK;
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(regbuf, length);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_csr_base == MAN_PCI_B_CSR_BASE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_dip_is_schizoxmits0_pcib:"
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam " found PCI B at dip(0x%p)\n", (void *)dip));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel *exp_id = portid >> 5;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (TRUE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelnotfound:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_dip_is_eri(dev_info_t *dip, man_dev_t *ndevp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct pci_phys_spec *regbuf = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int length = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint_t pci_device;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint_t pci_function;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_dip_is_eri: dip(0x%p) ndevp(0x%p)\n",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam (void *)dip, (void *)ndevp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam MAN_REG_PROP, (caddr_t)&regbuf,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam &length) == DDI_PROP_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_device = PCI_REG_DEV_G(regbuf->pci_phys_hi);
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_function = PCI_REG_FUNC_G(regbuf->pci_phys_hi);
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(regbuf, length);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The network function of the RIO ASIC will always
03831d35f7499c87d51205817c93e9a8d42c4baestevel * be device 3 and function 1 ("network@3,1").
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_device == 3 && pci_function == 1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel ndevp->mdev_ppa = ddi_get_instance(dip);
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ndevp->mdev_major = ddi_driver_major(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_dip_is_eri: found eri maj(%d)"
03831d35f7499c87d51205817c93e9a8d42c4baestevel " ppa(%d)\n", ndevp->mdev_major, ndevp->mdev_ppa));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (TRUE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAN_DBG(MAN_PATH, ("man_dip_is_eri: returns FALSE\n"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_dip_is_attached(dev_info_t *dip)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int state;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel state = ddi_get_devstate(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (i_ddi_devi_attached(dip) || (state == DDI_DEVSTATE_UP)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The instance info is more important for us,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so verify.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_get_instance(dip) >= 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (TRUE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "man_dip_is_attached: "
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki "eri 0x%p instance is not set yet", (void *)dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#if defined(DEBUG)
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelman_print_manc(manc_t *mcp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tmcp(0x%p)\n\n", (void *)mcp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mcp == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tmagic: 0x%x\n", mcp->manc_magic);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tversion: 0x%x\n", mcp->manc_version);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tcsum: %d\n", mcp->manc_csum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tdom_eaddr: %s\n",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ether_sprintf(&mcp->manc_dom_eaddr));
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tsc_eaddr: %s\n",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ether_sprintf(&mcp->manc_sc_eaddr));
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tiob_bitmap: 0x%x\n", mcp->manc_iob_bitmap);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, "\tgolden_iob: %d\n", mcp->manc_golden_iob);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */