summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorPeter Tribble <peter.tribble@gmail.com>2019-05-24 10:39:16 -0700
committerJoshua M. Clulow <josh@sysmgr.org>2019-05-24 10:39:16 -0700
commit1f4c6dbc37f14382f7ff4575a74da056dbd34d66 (patch)
tree45a6fc8ffc476fbad5df34b36be83eac7ac8be06 /usr/src
parent7811b028df2f34164be65174d666b570b73d32c3 (diff)
downloadillumos-gate-1f4c6dbc37f14382f7ff4575a74da056dbd34d66.tar.gz
10864 Remove starcat support
Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Andy Fiddaman <andy@omniosce.org> Reviewed by: John Levon <john.levon@joyent.com> Approved by: Joshua M. Clulow <josh@sysmgr.org>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/Makefile1
-rw-r--r--usr/src/cmd/Makefile.check2
-rw-r--r--usr/src/cmd/cvcd/Makefile63
-rw-r--r--usr/src/cmd/cvcd/cvc.xml119
-rw-r--r--usr/src/cmd/cvcd/sparc/Makefile47
-rw-r--r--usr/src/cmd/cvcd/sparc/sun4u/Makefile47
-rw-r--r--usr/src/cmd/cvcd/sparc/sun4u/starcat/Makefile62
-rw-r--r--usr/src/cmd/cvcd/sparc/sun4u/starcat/cvcd.c888
-rw-r--r--usr/src/cmd/cvcd/svc-cvcd61
-rw-r--r--usr/src/cmd/dcs/sparc/sun4u/dcs.xml16
-rw-r--r--usr/src/cmd/dcs/sparc/sun4u/svc-dcs30
-rw-r--r--usr/src/cmd/fm/eversholt/files/sparc/Makefile5
-rw-r--r--usr/src/cmd/fm/eversholt/files/sparc/SUNW,Sun-Fire-15000/Makefile32
-rw-r--r--usr/src/cmd/fm/eversholt/files/sparc/SUNW,Sun-Fire-15000/SUNW,Sun-Fire-15000.esc81
-rw-r--r--usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c22
-rw-r--r--usr/src/cmd/fm/modules/sun4u/datapath-retire/cda_main.c9
-rw-r--r--usr/src/cmd/fm/schemes/mem/mem_unum.c11
-rw-r--r--usr/src/cmd/sckmd/sparc/sun4u/Makefile3
-rw-r--r--usr/src/cmd/sckmd/svc-sckmd11
-rw-r--r--usr/src/cmd/svc/profile/Makefile1
-rw-r--r--usr/src/cmd/svc/profile/platform_SUNW,Sun-Fire-15000.xml47
-rw-r--r--usr/src/lib/cfgadm_plugins/Makefile.com1
-rw-r--r--usr/src/lib/fm/topo/maps/Makefile2
-rw-r--r--usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Makefile34
-rw-r--r--usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Sun-Fire-15000-hc-topology.xml52
-rw-r--r--usr/src/lib/fm/topo/modules/Makefile3
-rw-r--r--usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/Makefile32
-rw-r--r--usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/Makefile31
-rw-r--r--usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/iob_platform.c145
-rw-r--r--usr/src/lib/libc/capabilities/sun4u-us3/common/mapfile-cap1
-rw-r--r--usr/src/lib/libprtdiag_psr/sparc/Makefile2
-rw-r--r--usr/src/lib/libprtdiag_psr/sparc/starcat/Makefile74
-rw-r--r--usr/src/lib/libprtdiag_psr/sparc/starcat/common/starcat.c1168
-rw-r--r--usr/src/man/man1m/Makefile6
-rw-r--r--usr/src/man/man1m/cvcd.1m162
-rw-r--r--usr/src/man/man1m/dcs.1m88
-rw-r--r--usr/src/man/man1m/sckmd.1m19
-rw-r--r--usr/src/man/man7d/Makefile5
-rw-r--r--usr/src/man/man7d/cvc.7d61
-rw-r--r--usr/src/man/man7d/cvcredir.7d48
-rw-r--r--usr/src/man/man7d/schpc.7d38
-rw-r--r--usr/src/man/man7d/wscons.7d25
-rw-r--r--usr/src/pkg/manifests/SUNWcs.mf2
-rw-r--r--usr/src/pkg/manifests/SUNWcvc.mf29
-rw-r--r--usr/src/pkg/manifests/SUNWdrcr.mf31
-rw-r--r--usr/src/pkg/manifests/developer-apptrace-platform.mf2
-rw-r--r--usr/src/pkg/manifests/service-fault-management.mf17
-rw-r--r--usr/src/pkg/manifests/service-key-management-sun-fire-15000.mf40
-rw-r--r--usr/src/pkg/manifests/system-domain-service-processor-protocol-sparc-enterprise.mf7
-rw-r--r--usr/src/pkg/manifests/system-header.mf3
-rw-r--r--usr/src/pkg/manifests/system-kernel-dynamic-reconfiguration-sun-fire-15000.mf31
-rw-r--r--usr/src/pkg/manifests/system-kernel-platform.mf60
-rw-r--r--usr/src/pkg/manifests/system-library-platform.mf10
-rw-r--r--usr/src/pkg/manifests/system-network-console.mf37
-rw-r--r--usr/src/psm/promif/ieee1275/sun4u/Makefile.files3
-rw-r--r--usr/src/psm/promif/ieee1275/sun4u/prom_starcat.c219
-rw-r--r--usr/src/psm/stand/boot/sparcv9/sun4u/Makefile3
-rw-r--r--usr/src/psm/stand/bootblks/ufs/sparc/sun4u/Makefile1
-rw-r--r--usr/src/tools/chk4ubin/chk4ubin.c3
-rw-r--r--usr/src/uts/sun4/sys/platform_module.h7
-rw-r--r--usr/src/uts/sun4u/Makefile.files11
-rw-r--r--usr/src/uts/sun4u/Makefile.sun4u71
-rw-r--r--usr/src/uts/sun4u/io/gptwocfg.c28
-rw-r--r--usr/src/uts/sun4u/io/pci/pci.c32
-rw-r--r--usr/src/uts/sun4u/io/pci/pci_axq.c406
-rw-r--r--usr/src/uts/sun4u/io/pci/pci_fm.c34
-rw-r--r--usr/src/uts/sun4u/io/pci/pci_pbm.c36
-rw-r--r--usr/src/uts/sun4u/io/todstarcat.c263
-rw-r--r--usr/src/uts/sun4u/opl/oplkmdrv/Makefile5
-rw-r--r--usr/src/uts/sun4u/opl/sys/Makefile4
-rw-r--r--usr/src/uts/sun4u/opl/sys/sckm_io.h (renamed from usr/src/uts/sun4u/starcat/sys/sckm_io.h)6
-rw-r--r--usr/src/uts/sun4u/starcat/Makefile118
-rw-r--r--usr/src/uts/sun4u/starcat/Makefile.files70
-rw-r--r--usr/src/uts/sun4u/starcat/Makefile.rules85
-rw-r--r--usr/src/uts/sun4u/starcat/Makefile.starcat155
-rw-r--r--usr/src/uts/sun4u/starcat/Makefile.targ96
-rw-r--r--usr/src/uts/sun4u/starcat/axq/Makefile93
-rw-r--r--usr/src/uts/sun4u/starcat/cheetah/Makefile123
-rw-r--r--usr/src/uts/sun4u/starcat/cheetahplus/Makefile130
-rw-r--r--usr/src/uts/sun4u/starcat/cvc/Makefile99
-rw-r--r--usr/src/uts/sun4u/starcat/cvcredir/Makefile100
-rw-r--r--usr/src/uts/sun4u/starcat/dman/Makefile92
-rw-r--r--usr/src/uts/sun4u/starcat/dr/Makefile95
-rw-r--r--usr/src/uts/sun4u/starcat/drmach/Makefile98
-rw-r--r--usr/src/uts/sun4u/starcat/fcgp2/Makefile94
-rw-r--r--usr/src/uts/sun4u/starcat/genassym/Makefile97
-rw-r--r--usr/src/uts/sun4u/starcat/gptwo_pci/Makefile101
-rw-r--r--usr/src/uts/sun4u/starcat/io/axq.c1746
-rw-r--r--usr/src/uts/sun4u/starcat/io/cvc.c1437
-rw-r--r--usr/src/uts/sun4u/starcat/io/cvc.conf28
-rw-r--r--usr/src/uts/sun4u/starcat/io/cvcredir.c274
-rw-r--r--usr/src/uts/sun4u/starcat/io/cvcredir.conf28
-rw-r--r--usr/src/uts/sun4u/starcat/io/dman.c8327
-rw-r--r--usr/src/uts/sun4u/starcat/io/dman.conf28
-rw-r--r--usr/src/uts/sun4u/starcat/io/dman_domain.c870
-rw-r--r--usr/src/uts/sun4u/starcat/io/dr.conf28
-rw-r--r--usr/src/uts/sun4u/starcat/io/drmach.c8878
-rw-r--r--usr/src/uts/sun4u/starcat/io/fcgp2.c997
-rw-r--r--usr/src/uts/sun4u/starcat/io/gptwo_pci.c492
-rw-r--r--usr/src/uts/sun4u/starcat/io/iosram.c3532
-rw-r--r--usr/src/uts/sun4u/starcat/io/mboxsc.c2460
-rw-r--r--usr/src/uts/sun4u/starcat/io/sc_gptwocfg.c1547
-rw-r--r--usr/src/uts/sun4u/starcat/io/schpc.c4509
-rw-r--r--usr/src/uts/sun4u/starcat/io/schpc.conf32
-rw-r--r--usr/src/uts/sun4u/starcat/io/sckmdrv.c910
-rw-r--r--usr/src/uts/sun4u/starcat/io/sckmdrv.conf28
-rw-r--r--usr/src/uts/sun4u/starcat/io/scosmb.c1258
-rw-r--r--usr/src/uts/sun4u/starcat/iosram/Makefile93
-rw-r--r--usr/src/uts/sun4u/starcat/mboxsc/Makefile92
-rw-r--r--usr/src/uts/sun4u/starcat/ml/drmach.il.cpp210
-rw-r--r--usr/src/uts/sun4u/starcat/ml/drmach_asm.s975
-rw-r--r--usr/src/uts/sun4u/starcat/ml/starcat_asm.s78
-rw-r--r--usr/src/uts/sun4u/starcat/os/starcat.c1329
-rw-r--r--usr/src/uts/sun4u/starcat/platmod/Makefile98
-rw-r--r--usr/src/uts/sun4u/starcat/sc_gptwocfg/Makefile94
-rw-r--r--usr/src/uts/sun4u/starcat/schpc/Makefile96
-rw-r--r--usr/src/uts/sun4u/starcat/sckmdrv/Makefile97
-rw-r--r--usr/src/uts/sun4u/starcat/scosmb/Makefile94
-rw-r--r--usr/src/uts/sun4u/starcat/sys/Makefile74
-rw-r--r--usr/src/uts/sun4u/starcat/sys/axq.h368
-rw-r--r--usr/src/uts/sun4u/starcat/sys/dman.h552
-rw-r--r--usr/src/uts/sun4u/starcat/sys/domaind.h79
-rw-r--r--usr/src/uts/sun4u/starcat/sys/dr_mbx.h265
-rw-r--r--usr/src/uts/sun4u/starcat/sys/drmach.h169
-rw-r--r--usr/src/uts/sun4u/starcat/sys/gptwo_pci.h52
-rw-r--r--usr/src/uts/sun4u/starcat/sys/iosramio.h141
-rw-r--r--usr/src/uts/sun4u/starcat/sys/iosramreg.h134
-rw-r--r--usr/src/uts/sun4u/starcat/sys/iosramvar.h327
-rw-r--r--usr/src/uts/sun4u/starcat/sys/mboxsc.h119
-rw-r--r--usr/src/uts/sun4u/starcat/sys/mboxsc_impl.h136
-rw-r--r--usr/src/uts/sun4u/starcat/sys/post/scat_asicbrd_types.h120
-rw-r--r--usr/src/uts/sun4u/starcat/sys/post/scat_const.h299
-rw-r--r--usr/src/uts/sun4u/starcat/sys/post/scat_dcd.h509
-rw-r--r--usr/src/uts/sun4u/starcat/sys/post/scat_pa_space.h79
-rw-r--r--usr/src/uts/sun4u/starcat/sys/sc_cvc.h88
-rw-r--r--usr/src/uts/sun4u/starcat/sys/sc_cvcio.h139
-rw-r--r--usr/src/uts/sun4u/starcat/sys/sc_gptwocfg.h50
-rw-r--r--usr/src/uts/sun4u/starcat/sys/schpc.h184
-rw-r--r--usr/src/uts/sun4u/starcat/sys/schpc_msg.h185
-rw-r--r--usr/src/uts/sun4u/starcat/sys/sckm_msg.h101
-rw-r--r--usr/src/uts/sun4u/starcat/sys/starcat.h165
-rw-r--r--usr/src/uts/sun4u/starcat/unix/Makefile195
-rw-r--r--usr/src/uts/sun4u/sys/pci/pci_axq.h63
-rw-r--r--usr/src/uts/sun4u/sys/pci/pci_obj.h5
-rw-r--r--usr/src/uts/sun4u/sys/prom_plat.h10
-rw-r--r--usr/src/uts/sun4u/todstarcat/Makefile88
146 files changed, 187 insertions, 51776 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index 36ef810055..c91ddfa2b5 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -492,7 +492,6 @@ i386_SUBDIRS= \
xvm
sparc_SUBDIRS= \
- cvcd \
dcs \
device_remap \
drd \
diff --git a/usr/src/cmd/Makefile.check b/usr/src/cmd/Makefile.check
index 2ad038596b..91507c9ad9 100644
--- a/usr/src/cmd/Makefile.check
+++ b/usr/src/cmd/Makefile.check
@@ -23,6 +23,7 @@
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
# Copyright 2017 Nexenta Systems, Inc.
+# Copyright 2019 Peter Tribble
#
include ../Makefile.master
@@ -38,7 +39,6 @@ MANIFEST_TOPDIRS= \
consadm \
coreadm \
cron \
- cvcd \
dispadmin \
drd \
dumpadm \
diff --git a/usr/src/cmd/cvcd/Makefile b/usr/src/cmd/cvcd/Makefile
deleted file mode 100644
index b2b85d4613..0000000000
--- a/usr/src/cmd/cvcd/Makefile
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-# Copyright 2019 Peter Tribble.
-#
-# Makefile definitions for Starcat Network Console related items.
-#
-# cmd/cvcd/Makefile
-#
-# These utilities are specific to the Sun-Fire-15000 platform at this
-# time.
-#
-
-PROG= cvcd
-MANIFEST= cvc.xml
-SVCMETHOD= svc-$(PROG)
-
-include ../Makefile.cmd
-
-SUBDIRS = sparc
-
-ROOTMANIFESTDIR= $(ROOTSVCSYSTEM)
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-all lint clean clobber: $(SUBDIRS)
-
-install: $(SUBDIRS) $(ROOTMANIFEST) $(ROOTSVCMETHOD)
-
-check: $(CHKMANIFEST)
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-FRC:
-
-include ../Makefile.targ
diff --git a/usr/src/cmd/cvcd/cvc.xml b/usr/src/cmd/cvcd/cvc.xml
deleted file mode 100644
index 4b88288850..0000000000
--- a/usr/src/cmd/cvcd/cvc.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
-<!--
- Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- Use is subject to license terms.
- Copyright 2019 Peter Tribble.
-
- CDDL HEADER START
-
- The contents of this file are subject to the terms of the
- Common Development and Distribution License (the "License").
- You may not use this file except in compliance with the License.
-
- You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- or http://www.opensolaris.org/os/licensing.
- See the License for the specific language governing permissions
- and limitations under the License.
-
- When distributing Covered Code, include this CDDL HEADER in each
- file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- If applicable, add the following below this CDDL HEADER, with the
- fields enclosed by brackets "[]" replaced with your own identifying
- information: Portions Copyright [yyyy] [name of copyright owner]
-
- CDDL HEADER END
-
- NOTE: This service manifest is not editable; its contents will
- be overwritten by package or patch operations, including
- operating system upgrade. Make customizations in a different
- file.
-
- Service manifest for cvcd.
--->
-
-<service_bundle type='manifest' name='SUNWcvcr.u:cvcd'>
-
-<service name='system/cvc' type='service' version='1'>
-
- <create_default_instance enabled='false' />
-
- <single_instance />
-
- <dependency
- name='network'
- grouping='require_all'
- restart_on='none'
- type='service'>
- <service_fmri value='svc:/network/loopback' />
- </dependency>
-
- <!-- sckmd is required on OPL and Starcat -->
- <dependency
- name='sckmd'
- grouping='optional_all'
- restart_on='none'
- type='service'>
- <service_fmri value='svc:/platform/sun4u/sckmd' />
- </dependency>
-
- <dependency
- name='cryptosvc'
- grouping='require_all'
- restart_on='none'
- type='service'>
- <service_fmri value='svc:/system/cryptosvc' />
- </dependency>
-
- <dependency
- name='nodename'
- grouping='require_all'
- restart_on='none'
- type='service'>
- <service_fmri value='svc:/system/identity:node' />
- </dependency>
-
- <dependency
- name='filesystem_usr'
- grouping='require_all'
- restart_on='none'
- type='service'>
- <service_fmri value='svc:/system/filesystem/usr' />
- </dependency>
-
- <exec_method
- type='method'
- name='start'
- exec='/lib/svc/method/svc-cvcd'
- timeout_seconds='60' />
-
- <exec_method
- type='method'
- name='stop'
- exec=':kill -9'
- timeout_seconds='60' />
-
- <!-- these are passed to cvcd in the method script -->
- <property_group name='cvc' type='application'>
- <propval name='ah_auth' type='astring' value='md5' />
- <propval name='esp_encr' type='astring' value='none' />
- <propval name='esp_auth' type='astring' value='none' />
- </property_group>
-
- <stability value='Unstable' />
-
- <template>
- <common_name>
- <loctext xml:lang='C'>
- network virtual console
- </loctext>
- </common_name>
-
- <documentation>
- <manpage title='cvcd' section='1M'
- manpath='/usr/share/man' />
- </documentation>
- </template>
-</service>
-
-</service_bundle>
diff --git a/usr/src/cmd/cvcd/sparc/Makefile b/usr/src/cmd/cvcd/sparc/Makefile
deleted file mode 100644
index e5c629cfc3..0000000000
--- a/usr/src/cmd/cvcd/sparc/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright (c) 1997 by Sun Microsystems, Inc.
-# All rights reserved.
-# Copyright 2019 Peter Tribble.
-#
-# Makefile definitions for Starcat's Network Console related items.
-#
-# cmd/cvcd/sparc/Makefile
-#
-
-SUBDIRS = sun4u
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-all install lint clean clobber: $(SUBDIRS)
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-FRC:
diff --git a/usr/src/cmd/cvcd/sparc/sun4u/Makefile b/usr/src/cmd/cvcd/sparc/sun4u/Makefile
deleted file mode 100644
index e9bbcd1148..0000000000
--- a/usr/src/cmd/cvcd/sparc/sun4u/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-# Copyright 2019 Peter Tribble.
-#
-# Makefile definitions for Starcat Network Console related items.
-#
-# cmd/cvcd/sparc/sun4u/Makefile
-#
-
-SUBDIRS = starcat
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-all install lint clean clobber: $(SUBDIRS)
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-FRC:
diff --git a/usr/src/cmd/cvcd/sparc/sun4u/starcat/Makefile b/usr/src/cmd/cvcd/sparc/sun4u/starcat/Makefile
deleted file mode 100644
index 05c02a9d28..0000000000
--- a/usr/src/cmd/cvcd/sparc/sun4u/starcat/Makefile
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# cmd/cvcd/sparc/sun4u/starcat/cvcd
-#
-PROG= cvcd
-ROOTFS_PROG= $(PROG)
-PLATFORM= SUNW,Sun-Fire-15000
-
-# Create default so empty rules don't confuse make
-CLASS= 32
-
-SRCS= $(PROG:%=%.c)
-OBJS= $(PROG:%=%.o)
-
-include ../../../../Makefile.cmd
-include ../../../../../Makefile.psm
-
-FILEMODE= 0755
-
-ROOTPSMPROG = $(ROOT_PSM_LIB_DIR)/$(PROG)
-
-CPPFLAGS = -I$(USR_PSM_INCL_DIR) -I$(SRC)/uts/sun4u/starcat $(CPPFLAGS.master)
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-uninitialized
-
-LDLIBS += -lsocket
-
-.KEEP_STATE:
-
-all: $(ROOTFS_PROG)
-
-install: all .WAIT $(ROOTPSMPROG)
-
-clean:
- $(RM) $(PROG) $(OBJS)
-
-lint: lint_PROG
-
-include ../../../../Makefile.targ
-include ../../../../../Makefile.psm.targ
diff --git a/usr/src/cmd/cvcd/sparc/sun4u/starcat/cvcd.c b/usr/src/cmd/cvcd/sparc/sun4u/starcat/cvcd.c
deleted file mode 100644
index 044391da7c..0000000000
--- a/usr/src/cmd/cvcd/sparc/sun4u/starcat/cvcd.c
+++ /dev/null
@@ -1,888 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This code implements the Starcat Virtual Console host daemon (see cvcd(1M)).
- * It accepts one TCP connection at a time on a well-known port. Once a
- * connection is accepted, the console redirection driver (cvcdredir(7D)) is
- * opened, and console I/O is routed back and forth between the two file
- * descriptors (network and redirection driver). Per-socket IPsec is used to
- * secure the connection if it is enabled with the "-a", "-u" and or "-e"
- * command line options.
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <ctype.h>
-
-#include <fcntl.h>
-#include <sys/filio.h> /* Just to get FIONBIO... */
-#include <unistd.h>
-#include <errno.h>
-#include <stropts.h>
-#include <signal.h>
-#include <syslog.h>
-#include <sys/utsname.h>
-#include <sys/stat.h>
-#include <locale.h>
-#include <limits.h>
-
-#include <sys/priocntl.h>
-#include <sys/tspriocntl.h>
-#include <sys/rtpriocntl.h>
-
-#include <netdb.h>
-#include <sys/socket.h>
-#include <tiuser.h>
-
-#include <sys/sc_cvcio.h>
-
-
-/*
- * Header files for per-socket IPsec
- */
-#include <netinet/in.h>
-#include <net/pfkeyv2.h>
-
-/*
- * The IPsec socket option struct, from ipsec(7P):
- *
- * typedef struct ipsec_req {
- * uint_t ipsr_ah_req; AH request
- * uint_t ipsr_esp_req; ESP request
- * uint_t ipsr_self_encap_req; Self-Encap request
- * uint8_t ipsr_auth_alg; Auth algs for AH
- * uint8_t ipsr_esp_alg; Encr algs for ESP
- * uint8_t ipsr_esp_auth_alg; Auth algs for ESP
- * } ipsec_req_t;
- *
- * The -a option sets the ipsr_auth_alg field. Allowable arguments
- * are "none", "md5", or "sha1". The -e option sets the ipsr_esp_alg
- * field. Allowable arguments are "none", "des", or "3des". "none"
- * is the default for both options. The -u option sets ipsr_esp_auth_alg.
- * Allowable arguments are the same as -a.
- *
- * The arguments ("md5", "des", etc.) are named so that they match
- * kmd(1m)'s accepted arguments which are listed on the SC in
- * /etc/opt/SUNWSMS/SMS/config/kmd_policy.cf.
- */
-#define AH_REQ (IPSEC_PREF_REQUIRED | IPSEC_PREF_UNIQUE)
-#define ESP_REQ (IPSEC_PREF_REQUIRED | IPSEC_PREF_UNIQUE)
-#define SELF_ENCAP_REQ 0x0
-
-/*
- * A type to hold the command line argument string used to select a
- * particular authentication header (AH) or encapsulating security
- * payload (ESP) algorithm and the ID used for that algorithm when
- * filling the ipsec_req_t structure which is passed to
- * setsockopt(3SOCKET).
- */
-typedef struct cvcd_alg {
- char *arg_name;
- uint8_t alg_id;
-} cvcd_alg_t;
-
-/*
- * Misc. defines.
- */
-#define NODENAME "/etc/nodename"
-#define NETWORK_PFD 0
-#define REDIR_PFD 1
-#define LISTEN_PFD 2
-#define NUM_PFDS 3
-
-/*
- * Function prototypes
- */
-static void cvcd_set_priority(void);
-static int cvcd_init_host_socket(int port, uint8_t ah_auth_alg,
- uint8_t esp_encr_alg, uint8_t esp_auth_alg);
-static void cvcd_do_network_console(void);
-static void cvcd_err(int code, char *format, ...);
-static void cvcd_usage(void);
-static uint8_t cvcd_get_alg(cvcd_alg_t *algs, char *arg);
-static boolean_t cvcd_global_policy(void);
-
-/*
- * Globals
- */
-static struct pollfd pfds[NUM_PFDS];
-static char progname[MAXPATHLEN];
-static int debug = 0;
-
-/*
- * Array of acceptable -a, -u and -e arguments.
- */
-static cvcd_alg_t auth_algs_array[] = {
- { "none", SADB_AALG_NONE }, /* -a none or -u none */
- { "md5", SADB_AALG_MD5HMAC }, /* -a md5 or -u md5 */
- { "sha1", SADB_AALG_SHA1HMAC }, /* -a sha1 or -u sha1 */
- { NULL, 0x0 }
-}, esp_algs_array[] = {
- { "none", SADB_EALG_NONE }, /* -e none */
- { "des", SADB_EALG_DESCBC }, /* -e des */
- { "3des", SADB_EALG_3DESCBC }, /* -e 3des */
- { NULL, 0x0 }
-};
-
-
-int
-main(int argc, char **argv)
-{
- int err;
- int opt;
- int tport = 0;
- char *hostname;
- struct utsname utsname;
- int fd;
- int i;
- struct servent *se;
- char prefix[256];
- uint8_t ah_auth_alg = SADB_AALG_NONE;
- uint8_t esp_encr_alg = SADB_EALG_NONE;
- uint8_t esp_auth_alg = SADB_AALG_NONE;
-
- (void) setlocale(LC_ALL, "");
- (void) strcpy(progname, argv[0]);
-
-#ifdef DEBUG
- while ((opt = getopt(argc, argv, "a:e:u:dp:")) != EOF) {
-#else
- while ((opt = getopt(argc, argv, "a:e:u:")) != EOF) {
-#endif
- switch (opt) {
- case 'a' :
- case 'u' :
- if (opt == 'a')
- ah_auth_alg = cvcd_get_alg(
- auth_algs_array, optarg);
- else
- esp_auth_alg = cvcd_get_alg(
- auth_algs_array, optarg);
- break;
-
- case 'e' : esp_encr_alg = cvcd_get_alg(
- esp_algs_array, optarg);
- break;
-#ifdef DEBUG
- case 'd' : debug = 1;
- break;
-
- case 'p' : tport = atoi(optarg);
- break;
-#endif /* DEBUG */
-
- default : cvcd_usage();
- exit(1);
- }
- }
-
- if (uname(&utsname) == -1) {
- perror("HOSTNAME not defined");
- exit(1);
- }
- hostname = utsname.nodename;
-
- /*
- * hostname may still be NULL, depends on when cvcd was started
- * in the boot sequence. If it is NULL, try one more time
- * to get a hostname -> look in the /etc/nodename file.
- */
- if (!strlen(hostname)) {
- /*
- * try to get the hostname from the /etc/nodename file
- * we reuse the utsname.nodename buffer here! hostname
- * already points to it.
- */
- if ((fd = open(NODENAME, O_RDONLY)) > 0) {
- if ((i = read(fd, utsname.nodename, SYS_NMLN)) <= 0) {
- cvcd_err(LOG_WARNING,
- "failed to acquire hostname");
- } else {
- utsname.nodename[i-1] = '\0';
- }
- (void) close(fd);
- }
- }
- /*
- * If all attempts to get the hostname have failed, put something
- * meaningful in the buffer.
- */
- if (!strlen(hostname)) {
- (void) strcpy(utsname.nodename, "(unknown)");
- }
-
- /*
- * Must be root.
- */
- if (debug == 0 && geteuid() != 0) {
- fprintf(stderr, "cvcd: Must be root");
- exit(1);
- }
-
- /*
- * Daemonize...
- */
- if (debug == 0) {
- closefrom(0);
- (void) chdir("/");
- (void) umask(0);
- if (fork() != 0) {
- exit(0);
- }
- (void) setpgrp();
- (void) sprintf(prefix, "%s-(HOSTNAME:%s)", progname, hostname);
- openlog(prefix, LOG_CONS | LOG_NDELAY, LOG_LOCAL0);
- }
-
- /*
- * Initialize the array of pollfds used to track the listening socket,
- * the connection to the console redirection driver, and the network
- * connection.
- */
- (void) memset((void *)pfds, 0, NUM_PFDS * sizeof (struct pollfd));
- for (i = 0; i < NUM_PFDS; i++) {
- pfds[i].fd = -1;
- }
-
- /* SPR 94004 */
- (void) sigignore(SIGTERM);
-
- /*
- * SPR 83644: cvc and kadb are not compatible under heavy loads.
- * Fix: will give cvcd highest TS priority at execution time.
- */
- cvcd_set_priority();
-
- /*
- * If not already determined by a command-line flag, figure out which
- * port we're supposed to be listening on.
- */
- if (tport == 0) {
- if ((se = getservbyname(CVCD_SERVICE, "tcp")) == NULL) {
- cvcd_err(LOG_ERR, "getservbyname(%s) not found",
- CVCD_SERVICE);
- exit(1);
- }
- tport = se->s_port;
- }
-
- if (debug == 1) {
- cvcd_err(LOG_DEBUG, "tport = %d, debug = %d", tport, debug);
- }
-
- /*
- * Attempt to initialize the socket we'll use to listen for incoming
- * connections. No need to check the return value, as the call will
- * exit if it fails.
- */
- pfds[LISTEN_PFD].fd = cvcd_init_host_socket(tport, ah_auth_alg,
- esp_encr_alg, esp_auth_alg);
-
- /*
- * Now that we're all set up, we loop forever waiting for connections
- * (one at a time) and then driving network console activity over them.
- */
- for (;;) {
- /*
- * Start by waiting for an incoming connection.
- */
- do {
- pfds[LISTEN_PFD].events = POLLIN;
- err = poll(&(pfds[LISTEN_PFD]), 1, -1);
- if (err == -1) {
- cvcd_err(LOG_ERR, "poll: %s", strerror(errno));
- exit(1);
- }
- if ((err > 0) &&
- (pfds[LISTEN_PFD].revents & POLLIN)) {
- fd = accept(pfds[LISTEN_PFD].fd, NULL, NULL);
- if ((fd == -1) && (errno != EWOULDBLOCK)) {
- cvcd_err(LOG_ERR, "accept: %s",
- strerror(errno));
- exit(1);
- }
- }
- } while (fd == -1);
-
- /*
- * We have a connection. Set the new socket nonblocking, and
- * initialize the appropriate pollfd. In theory, the new socket
- * is _already_ non-blocking because accept() is supposed to
- * hand us a socket with the same properties as the socket we're
- * listening on, but it won't hurt to make sure.
- */
- opt = 1;
- err = ioctl(fd, FIONBIO, &opt);
- if (err == -1) {
- cvcd_err(LOG_ERR, "ioctl: %s", strerror(errno));
- (void) close(fd);
- continue;
- }
- pfds[NETWORK_PFD].fd = fd;
-
- /*
- * Since we're ready to do network console stuff, go ahead and
- * open the Network Console redirection driver, which will
- * switch traffic from the IOSRAM path to the network path if
- * the network path has been selected in cvc.
- */
- fd = open(CVCREDIR_DEV, O_RDWR|O_NDELAY);
- if (fd == -1) {
- cvcd_err(LOG_ERR, "open(redir): %s", strerror(errno));
- exit(1);
- }
- pfds[REDIR_PFD].fd = fd;
-
- /*
- * We have a network connection and we have the redirection
- * driver open, so drive the network console until something
- * changes.
- */
- cvcd_do_network_console();
-
- /*
- * cvcd_do_network_console doesn't return until there's a
- * problem, so we need to close the network connection and the
- * redirection driver and start the whole loop over again.
- */
- (void) close(pfds[NETWORK_PFD].fd);
- pfds[NETWORK_PFD].fd = -1;
- (void) close(pfds[REDIR_PFD].fd);
- pfds[REDIR_PFD].fd = -1;
- }
-
- /* NOTREACHED */
- return (1);
-}
-
-/*
- * cvcd_get_alg
- *
- * Returns the ID of the first algorithm found in
- * the 'algs' array with a name matching 'arg'. If
- * there is no matching algorithm, the function does
- * not return. The 'algs' array must be terminated
- * by an entry containing a NULL 'arg_name' field.
- */
-static uint8_t
-cvcd_get_alg(cvcd_alg_t *algs, char *arg)
-{
- cvcd_alg_t *alg;
-
- for (alg = algs; alg->arg_name != NULL && arg != NULL; alg++) {
- if (strncmp(alg->arg_name, arg, strlen(alg->arg_name) + 1)
- == 0) {
- return (alg->alg_id);
- }
- }
-
- cvcd_usage();
- exit(1);
- /* NOTREACHED */
-}
-
-/*
- * cvcd_set_priority
- *
- * DESCRIBE
- * SPR 83644: cvc and kadb are not compatible under heavy loads.
- * Fix: will give cvcd highest TS priority at execution time.
- */
-static void
-cvcd_set_priority(void)
-{
- id_t pid, tsID;
- pcparms_t pcparms;
- tsparms_t *tsparmsp;
- short tsmaxpri;
- pcinfo_t info;
-
- pid = getpid();
- pcparms.pc_cid = PC_CLNULL;
- tsparmsp = (tsparms_t *)pcparms.pc_clparms;
-
- /* Get scheduler properties for this PID */
- if (priocntl(P_PID, pid, PC_GETPARMS, (caddr_t)&pcparms) == -1L) {
- cvcd_err(LOG_ERR, "Warning: can't set priority.");
- cvcd_err(LOG_ERR, "priocntl(GETPARMS): %s", strerror(errno));
- return;
- }
-
- /* Get class ID and maximum priority for TS process class */
- (void) strcpy(info.pc_clname, "TS");
- if (priocntl(0L, 0L, PC_GETCID, (caddr_t)&info) == -1L) {
- cvcd_err(LOG_ERR, "Warning: can't set priority.");
- cvcd_err(LOG_ERR, "priocntl(GETCID): %s", strerror(errno));
- return;
- }
- tsmaxpri = ((struct tsinfo *)info.pc_clinfo)->ts_maxupri;
- tsID = info.pc_cid;
-
- /* Print priority info in debug mode */
- if (debug) {
- if (pcparms.pc_cid == tsID) {
- cvcd_err(LOG_DEBUG,
- "PID: %d, current priority: %d, Max priority: %d.",
- pid, tsparmsp->ts_upri, tsmaxpri);
- }
- }
- /* Change proc's priority to maxtspri */
- pcparms.pc_cid = tsID;
- tsparmsp->ts_upri = tsmaxpri;
- tsparmsp->ts_uprilim = tsmaxpri;
-
- if (priocntl(P_PID, pid, PC_SETPARMS, (caddr_t)&pcparms) == -1L) {
- cvcd_err(LOG_ERR, "Warning: can't set priority.");
- cvcd_err(LOG_ERR, "priocntl(SETPARMS): %s", strerror(errno));
- }
-
- /* Print new priority info in debug mode */
- if (debug) {
- if (priocntl(P_PID, pid, PC_GETPARMS, (caddr_t)&pcparms) ==
- -1L) {
- cvcd_err(LOG_ERR, "priocntl(GETPARMS): %s",
- strerror(errno));
- } else {
- cvcd_err(LOG_DEBUG, "PID: %d, new priority: %d.", pid,
- tsparmsp->ts_upri);
- }
- }
-}
-
-
-/*
- * cvcd_init_host_socket
- *
- * Given a TCP port number, create and initialize a socket appropriate for
- * accepting incoming connections to that port.
- */
-static int
-cvcd_init_host_socket(int port, uint8_t ah_auth_alg, uint8_t esp_encr_alg,
- uint8_t esp_auth_alg)
-{
- int err;
- int fd;
- int optval;
- int optlen = sizeof (optval);
- ipsec_req_t ipsec_req; /* For per-socket IPsec */
- struct sockaddr_in6 sin6; /* IPv6 listen socket */
-
- /*
- * Start by creating the socket, which needs to support IPv6.
- */
- fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
- if (fd == -1) {
- cvcd_err(LOG_ERR, "socket: %s", strerror(errno));
- exit(1);
- }
-
- /*
- * Set the SO_REUSEADDR option, and make the socket non-blocking.
- */
- optval = 1;
- err = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen);
- if (err == -1) {
- cvcd_err(LOG_ERR, "setsockopt: %s", strerror(errno));
- exit(1);
- }
-
- err = ioctl(fd, FIONBIO, &optval);
- if (err == -1) {
- cvcd_err(LOG_ERR, "ioctl: %s", strerror(errno));
- exit(1);
- }
-
- /*
- * Enable per-socket IPsec if the user specified an AH or ESP
- * algorithm to use and global policy is not in effect.
- */
- if (!cvcd_global_policy() &&
- (ah_auth_alg != SADB_AALG_NONE || esp_encr_alg != SADB_EALG_NONE ||
- esp_auth_alg != SADB_AALG_NONE)) {
- bzero(&ipsec_req, sizeof (ipsec_req));
-
- /* Hardcoded values */
- ipsec_req.ipsr_self_encap_req = SELF_ENCAP_REQ;
- /* User defined */
- ipsec_req.ipsr_auth_alg = ah_auth_alg;
- ipsec_req.ipsr_esp_alg = esp_encr_alg;
- if (ah_auth_alg != SADB_AALG_NONE)
- ipsec_req.ipsr_ah_req = AH_REQ;
- if (esp_encr_alg != SADB_EALG_NONE ||
- esp_auth_alg != SADB_AALG_NONE) {
- ipsec_req.ipsr_esp_req = ESP_REQ;
- ipsec_req.ipsr_esp_auth_alg = esp_auth_alg;
- }
-
- err = setsockopt(fd, IPPROTO_IPV6, IPV6_SEC_OPT,
- (void *)&ipsec_req, sizeof (ipsec_req));
-
- if (err == -1) {
- cvcd_err(LOG_ERR, "failed to enable per-socket IPsec");
- cvcd_err(LOG_ERR, "setsockopt: %s", strerror(errno));
- exit(1);
- }
- }
-
- /*
- * Bind the socket to our local address and port.
- */
- bzero(&sin6, sizeof (sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_port = htons(port);
- sin6.sin6_addr = in6addr_any;
- err = bind(fd, (struct sockaddr *)&sin6, sizeof (sin6));
- if (err == -1) {
- cvcd_err(LOG_ERR, "bind: %s", strerror(errno));
- exit(1);
- }
-
- /*
- * Indicate that we want to accept connections on this socket. Since we
- * only allow one connection at a time anyway, specify a maximum backlog
- * of 1.
- */
- err = listen(fd, 1);
- if (err == -1) {
- cvcd_err(LOG_ERR, "listen: %s", strerror(errno));
- exit(1);
- }
-
- return (fd);
-}
-
-
-/*
- * cvcd_do_network_console
- *
- * With established connections to the network and the redirection driver,
- * shuttle data between the two until something goes wrong.
- */
-static void
-cvcd_do_network_console(void)
-{
- int i;
- int err;
- int count;
- short revents;
- int input_len = 0;
- int output_len = 0;
- int input_off = 0;
- int output_off = 0;
- char input_buf[MAXPKTSZ];
- char output_buf[MAXPKTSZ];
-
- for (;;) {
- /*
- * Wait for activity on any of the open file descriptors, which
- * includes the ability to write data if we have any to write.
- * If poll() fails, break out of the network console processing
- * loop.
- */
- pfds[LISTEN_PFD].events = POLLIN;
- pfds[NETWORK_PFD].events = POLLIN;
- if (output_len != 0) {
- pfds[NETWORK_PFD].events |= POLLOUT;
- }
- pfds[REDIR_PFD].events = POLLIN;
- if (input_len != 0) {
- pfds[REDIR_PFD].events |= POLLOUT;
- }
- err = poll(pfds, NUM_PFDS, -1);
- if (err == -1) {
- cvcd_err(LOG_ERR, "poll: %s", strerror(errno));
- break;
- }
-
- /*
- * If any errors or hangups were detected, or one of our file
- * descriptors is bad, bail out of the network console
- * processing loop.
- */
- for (i = 0; i < NUM_PFDS; i++) {
- revents = pfds[i].revents;
- if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
- cvcd_err(LOG_NOTICE,
- "poll: status on %s fd:%s%s%s",
- ((i == LISTEN_PFD) ? "listen" :
- ((i == NETWORK_PFD) ? "network" : "redir")),
- (revents & POLLERR) ? " error" : "",
- (revents & POLLHUP) ? " hangup" : "",
- (revents & POLLNVAL) ? " bad fd" : "");
- goto fail; /* 'break' wouldn't work here */
- }
- }
-
- /*
- * Start by rejecting any connection attempts, since we only
- * allow one network connection at a time.
- */
- if (pfds[LISTEN_PFD].revents & POLLIN) {
- int fd;
-
- fd = accept(pfds[LISTEN_PFD].fd, NULL, NULL);
- if (fd > 0) {
- (void) close(fd);
- }
- }
-
- /*
- * If we have data waiting to be written in one direction or the
- * other, go ahead and try to send the data on its way. We're
- * going to attempt the writes regardless of whether the poll
- * indicated that the destinations are ready, because we want to
- * find out if either descriptor has a problem (e.g. broken
- * network link).
- * If an "unexpected" error is detected, give up and break out
- * of the network console processing loop.
- */
- if (output_len != 0) {
- count = write(pfds[NETWORK_PFD].fd,
- &(output_buf[output_off]), output_len);
- if ((count == -1) && (errno != EAGAIN)) {
- cvcd_err(LOG_ERR, "write(network): %s",
- strerror(errno));
- break;
- } else if (count > 0) {
- output_len -= count;
- if (output_len == 0) {
- output_off = 0;
- } else {
- output_off += count;
- }
- }
- }
-
- if (input_len != 0) {
- count = write(pfds[REDIR_PFD].fd,
- &(input_buf[input_off]), input_len);
- if ((count == -1) && (errno != EAGAIN)) {
- cvcd_err(LOG_ERR, "write(redir): %s",
- strerror(errno));
- break;
- } else if (count > 0) {
- input_len -= count;
- if (input_len == 0) {
- input_off = 0;
- } else {
- input_off += count;
- }
- }
- }
-
- /*
- * Finally, take a look at each data source and, if there isn't
- * any residual data from that source still waiting to be
- * processed, see if more data can be read. We don't want to
- * read more data from a source if we haven't finished
- * processing the last data we read from it because doing so
- * would maximize the amount of data lost if the network console
- * failed or was closed.
- * If an "unexpected" error is detected, give up and break out
- * of the network console processing loop.
- * The call to read() appears to be in the habit of returning 0
- * when you've read all of the data from a stream that has been
- * hung up, and poll apparently feels that that condition
- * justifies setting POLLIN, so we're going to treat 0 as an
- * error return from read().
- */
- if ((output_len == 0) && (pfds[REDIR_PFD].revents & POLLIN)) {
- count = read(pfds[REDIR_PFD].fd, output_buf, MAXPKTSZ);
- if (count <= 0) {
- /*
- * Reading 0 simply means there is no data
- * available, since this is a terminal.
- */
- if ((count < 0) && (errno != EAGAIN)) {
- cvcd_err(LOG_ERR, "read(redir): %s",
- strerror(errno));
- break;
- }
- } else {
- output_len = count;
- output_off = 0;
- }
- }
-
- if ((input_len == 0) && (pfds[NETWORK_PFD].revents & POLLIN)) {
- count = read(pfds[NETWORK_PFD].fd, input_buf, MAXPKTSZ);
- if (count <= 0) {
- /*
- * Reading 0 here implies a hangup, since this
- * is a non-blocking socket that poll() reported
- * as having data available. This will
- * typically occur when the console user drops
- * to OBP or intentially switches to IOSRAM
- * mode.
- */
- if (count == 0) {
- cvcd_err(LOG_NOTICE,
- "read(network): hangup detected");
- break;
- } else if (errno != EAGAIN) {
- cvcd_err(LOG_ERR, "read(network): %s",
- strerror(errno));
- break;
- }
- } else {
- input_len = count;
- input_off = 0;
- }
- }
- } /* End forever loop */
-
- /*
- * If we get here, something bad happened during an attempt to access
- * either the redirection driver or the network connection. There
- * doesn't appear to be any way to avoid the possibility of losing
- * console input and/or input in that case, so we should at least report
- * the loss if it happens.
- * XXX - We could do more, but is it worth the effort? Logging the
- * lost data would be pretty easy... actually preserving it
- * in the console flow would be a lot harder. We're more robust
- * than the previous generation at this point, at least, so
- * perhaps that's enough for now?
- */
-fail:
- if (input_len != 0) {
- cvcd_err(LOG_ERR, "console input lost");
- }
- if (output_len != 0) {
- cvcd_err(LOG_ERR, "console output lost");
- }
-}
-
-
-static void
-cvcd_usage()
-{
-#if defined(DEBUG)
- (void) printf("%s [-d] [-p port] "
- "[-a none|md5|sha1] [-e none|des|3des] [-u none|md5|sha1]\n",
- progname);
-#else
- (void) printf("%s [-a none|md5|sha1] [-e none|des|3des] "
- "[-u none|md5|sha1]\n", progname);
-#endif /* DEBUG */
-}
-
-/*
- * cvcd_err ()
- *
- * Description:
- * Log messages via syslog daemon.
- *
- * Input:
- * code - logging code
- * format - messages to log
- *
- * Output:
- * void
- *
- */
-static void
-cvcd_err(int code, char *format, ...)
-{
- va_list varg_ptr;
- char buf[MAXPKTSZ];
-
- va_start(varg_ptr, format);
- (void) vsnprintf(buf, MAXPKTSZ, format, varg_ptr);
- va_end(varg_ptr);
-
- if (debug == 0) {
- syslog(code, buf);
- } else {
- (void) fprintf(stderr, "%s: %s\n", progname, buf);
- }
-}
-
-/*
- * has_cvcd_token
- *
- * Look for "?port [cvc_hostd|442]" in input buf.
- * Assume only a single thread calls here.
- */
-static boolean_t
-has_cvcd_token(char *buf)
-{
- char *token;
- char *delims = "{} \t\n";
- boolean_t port = B_FALSE;
-
- while ((token = strtok(buf, delims)) != NULL) {
- buf = NULL;
- if (port == B_TRUE) {
- if (strcmp(token, "cvc_hostd") == 0 ||
- strcmp(token, "442") == 0) {
- return (B_TRUE);
- } else {
- return (B_FALSE);
- }
- }
- if (strlen(token) == 5) {
- token++;
- if (strcmp(token, "port") == 0) {
- port = B_TRUE;
- continue;
- }
- }
- }
- return (B_FALSE);
-}
-
-/*
- * cvcd_global_policy
- *
- * Check global policy file for cvcd entry. Just covers common cases.
- */
-static boolean_t
-cvcd_global_policy()
-{
- FILE *fp;
- char buf[256];
- boolean_t rv = B_FALSE;
-
- fp = fopen("/etc/inet/ipsecinit.conf", "r");
- if (fp == NULL)
- return (B_FALSE);
- while (fgets(buf, sizeof (buf), fp) != NULL) {
- if (buf[0] == '#')
- continue;
- if (has_cvcd_token(buf)) {
- rv = B_TRUE;
- cvcd_err(LOG_NOTICE, "cvcd using global policy");
- break;
- }
- }
- (void) fclose(fp);
- return (rv);
-}
diff --git a/usr/src/cmd/cvcd/svc-cvcd b/usr/src/cmd/cvcd/svc-cvcd
deleted file mode 100644
index caeeb9b54c..0000000000
--- a/usr/src/cmd/cvcd/svc-cvcd
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/sbin/sh
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-# Copyright 2019 Peter Tribble.
-#
-# Start script for cvcd
-#
-# For modifying parameters passed to cvcd, do not edit
-# this script. Instead use svccfg(1m) to modify the SMF
-# repository. For example:
-#
-# svccfg
-# svc:> select system/cvc
-# svc:system/cvc> setprop cvc/ah_auth = "md5"
-# svc:/system/cvc> exit
-
-
-. /lib/svc/share/smf_include.sh
-
-getproparg() {
- val=`svcprop -p $2 $SMF_FMRI`
- [ -n "$val" ] && [ "$val" != 'none' ] && echo $1 $val
-}
-
-platform=`/sbin/uname -i`
-starcat="SUNW,Sun-Fire-15000"
-
-if [ $platform = "$starcat" ]; then
- args=""
- args="$args `getproparg -a cvc/ah_auth`"
- args="$args `getproparg -e cvc/esp_encr`"
- args="$args `getproparg -u cvc/esp_auth`"
- /platform/$platform/lib/cvcd $args # Fail if can't execute
- exit # Use cvcd's exit status
-else
- echo "$SMF_FMRI is not supported on this platform."
- exit $SMF_EXIT_ERR_CONFIG
-fi
-
-exit 0
diff --git a/usr/src/cmd/dcs/sparc/sun4u/dcs.xml b/usr/src/cmd/dcs/sparc/sun4u/dcs.xml
index 1fa7be34d7..a14f03eeb4 100644
--- a/usr/src/cmd/dcs/sparc/sun4u/dcs.xml
+++ b/usr/src/cmd/dcs/sparc/sun4u/dcs.xml
@@ -4,6 +4,7 @@
<!--
Copyright 2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
+ Copyright 2019 Peter Tribble.
CDDL HEADER START
@@ -24,8 +25,6 @@
CDDL HEADER END
- ident "%Z%%M% %I% %E% SMI"
-
NOTE: This service manifest is not editable; its contents will
be overwritten by package or patch operations, including
operating system upgrade. Make customizations in a different
@@ -49,7 +48,7 @@
<service_fmri value='svc:/network/loopback' />
</dependency>
- <!-- sckmd is required on OPL and Starcat but Not Starfile -->
+ <!-- sckmd is only required on OPL -->
<dependency
name='sckmd'
grouping='optional_all'
@@ -58,7 +57,7 @@
<service_fmri value='svc:/platform/sun4u/sckmd' />
</dependency>
- <dependency
+ <dependency
name='cryptosvc'
grouping='require_all'
restart_on='none'
@@ -66,7 +65,7 @@
<service_fmri value='svc:/system/cryptosvc' />
</dependency>
- <dependency
+ <dependency
name='filesystem_usr'
grouping='require_all'
restart_on='none'
@@ -96,13 +95,6 @@
timeout_seconds='60'>
</exec_method>
- <!-- these are passed to dcs in the method script -->
- <property_group name='dcs' type='application'>
- <propval name='ah_auth' type='astring' value='md5' />
- <propval name='esp_encr' type='astring' value='none' />
- <propval name='esp_auth' type='astring' value='none' />
- </property_group>
-
<stability value='Unstable' />
<template>
diff --git a/usr/src/cmd/dcs/sparc/sun4u/svc-dcs b/usr/src/cmd/dcs/sparc/sun4u/svc-dcs
index 4054ca111a..f0fb49d22a 100644
--- a/usr/src/cmd/dcs/sparc/sun4u/svc-dcs
+++ b/usr/src/cmd/dcs/sparc/sun4u/svc-dcs
@@ -27,40 +27,16 @@
#
# Start script for dcs
#
-# For modifying parameters passed to dcs, do not edit
-# this script. Instead use svccfg(1m) to modify the SMF
-# repository. For example:
-#
-# svccfg
-# svc:> select platform/sun4u/dcs
-# svc:/platform/sun4u/dcs> setprop dcs/ah_auth = "md5"
-# svc:/platform/sun4u/dcs> exit
-
. /lib/svc/share/smf_include.sh
-getproparg() {
- val=`svcprop -p $2 $SMF_FMRI`
- [ -n "$val" ] && [ "$val" != 'none' ] && echo $1 $val
-}
-
DCS=/usr/lib/dcs
platform=`/sbin/uname -i`
-sf15k="SUNW,Sun-Fire-15000"
opl="SUNW,SPARC-Enterprise"
-args=""
-if [ $platform = "$sf15k" ]; then
- args="$args `getproparg -a dcs/ah_auth`"
- args="$args `getproparg -e dcs/esp_encr`"
- args="$args `getproparg -u dcs/esp_auth`"
-elif [ $platform = "$opl" ]; then
- args="-l"
-fi
-
-if [ $platform = "$sf15k" -o $platform = "$opl" ]; then
- $DCS $args # Fail if can't execute
- exit # Use dcs's exit status
+if [ $platform = "$opl" ]; then
+ $DCS -l # Fail if can't execute
+ exit # Use dcs's exit status
else
echo "$SMF_FMRI is not supported on this platform."
exit $SMF_EXIT_ERR_CONFIG
diff --git a/usr/src/cmd/fm/eversholt/files/sparc/Makefile b/usr/src/cmd/fm/eversholt/files/sparc/Makefile
index 6539f752aa..4e5655cbf7 100644
--- a/usr/src/cmd/fm/eversholt/files/sparc/Makefile
+++ b/usr/src/cmd/fm/eversholt/files/sparc/Makefile
@@ -20,9 +20,10 @@
#
#
# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2019 Peter Tribble.
#
-SUBDIRS=sun4u sun4v SUNW,Sun-Fire-15000
+SUBDIRS=sun4u sun4v
EFT_COMMON_FILES= \
disk.eft \
neptune_xaui.eft \
@@ -31,7 +32,7 @@ EFT_COMMON_FILES= \
pciex.eft \
pciexrc.eft \
sca500.eft \
- sca1000.eft \
+ sca1000.eft \
sensor.eft \
storage.eft
diff --git a/usr/src/cmd/fm/eversholt/files/sparc/SUNW,Sun-Fire-15000/Makefile b/usr/src/cmd/fm/eversholt/files/sparc/SUNW,Sun-Fire-15000/Makefile
deleted file mode 100644
index da0042814d..0000000000
--- a/usr/src/cmd/fm/eversholt/files/sparc/SUNW,Sun-Fire-15000/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-EFT_PLAT= SUNW,Sun-Fire-15000
-EFT_PLAT_FILES= SUNW,Sun-Fire-15000.eft
-
-include ../../Makefile.com
diff --git a/usr/src/cmd/fm/eversholt/files/sparc/SUNW,Sun-Fire-15000/SUNW,Sun-Fire-15000.esc b/usr/src/cmd/fm/eversholt/files/sparc/SUNW,Sun-Fire-15000/SUNW,Sun-Fire-15000.esc
deleted file mode 100644
index 1e7f06be8e..0000000000
--- a/usr/src/cmd/fm/eversholt/files/sparc/SUNW,Sun-Fire-15000/SUNW,Sun-Fire-15000.esc
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#pragma dictionary "SUN4U"
-
-#define AGENT_ID_MASK 0x1f
-#define AGENT_ID_SHIFT 24
-
-#define CPU_FIT 500
-
-fru cpu;
-
-event fault.io.datapath@cpu, retire=0,
- FITrate=CPU_FIT, FRU=cpu;
-
-event ereport.io.psy.ecc.pue@hostbridge{within(5s)};
-event ereport.io.sch.ecc.pue@hostbridge{within(5s)};
-event ereport.io.xmits.ecc.pue@hostbridge{within(5s)};
-event ereport.io.cpu.ecc.thresh@cpu;
-
-/*
- * For Starcat we need to apply the following logic to calculate the
- * Agentid of the system board in question.
- */
-prop fault.io.datapath@cpu[cpuid] (0)->
- ereport.io.psy.ecc.pue@hostbridge
- {((payloadprop("ecc-afsr") >> AGENT_ID_SHIFT) & AGENT_ID_MASK) ==
- ((cpuid >> 5) & AGENT_ID_MASK)},
- ereport.io.sch.ecc.pue@hostbridge
- {((payloadprop("ecc-afsr") >> AGENT_ID_SHIFT) & AGENT_ID_MASK) ==
- ((cpuid >> 5) & AGENT_ID_MASK)},
- ereport.io.xmits.ecc.pue@hostbridge
- {((payloadprop("ecc-afsr") >> AGENT_ID_SHIFT) & AGENT_ID_MASK) ==
- ((cpuid >> 5) & AGENT_ID_MASK)},
- ereport.io.cpu.ecc.thresh@cpu[cpuid];
-
-engine serd.io.cpu.ecc@cpu,
- N=3, T=1day, method=persistent,
- trip=ereport.io.cpu.ecc.thresh@cpu;
-
-event upset.io.datapath@cpu,
- engine=serd.io.cpu.ecc@cpu;
-
-event ereport.io.psy.ecc.pce@hostbridge{within(5s)};
-event ereport.io.sch.ecc.pce@hostbridge{within(5s)};
-event ereport.io.xmits.ecc.pce@hostbridge{within(5s)};
-
-prop upset.io.datapath@cpu[cpuid] (0)->
- ereport.io.psy.ecc.pce@hostbridge
- {((payloadprop("ecc-afsr") >> AGENT_ID_SHIFT) & AGENT_ID_MASK) ==
- ((cpuid >> 5) & AGENT_ID_MASK)},
- ereport.io.sch.ecc.pce@hostbridge
- {((payloadprop("ecc-afsr") >> AGENT_ID_SHIFT) & AGENT_ID_MASK) ==
- ((cpuid >> 5) & AGENT_ID_MASK)},
- ereport.io.xmits.ecc.pce@hostbridge
- {((payloadprop("ecc-afsr") >> AGENT_ID_SHIFT) & AGENT_ID_MASK) ==
- ((cpuid >> 5) & AGENT_ID_MASK)};
diff --git a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c
index b06532a7f3..a86318e0bc 100644
--- a/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c
+++ b/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_cpu.c
@@ -21,6 +21,7 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright (c) 2019 Peter Tribble.
*/
/*
@@ -115,8 +116,6 @@ cpu_nname2type(fmd_hdl_t *hdl, const char *name, size_t n)
}
const char *fmd_fmri_get_platform();
-#define is_starcat (strcmp(fmd_fmri_get_platform(), \
-"SUNW,Sun-Fire-15000") == 0)
#define is_serengeti (strcmp(fmd_fmri_get_platform(), \
"SUNW,Sun-Fire") == 0)
@@ -127,8 +126,6 @@ core2cpus(uint32_t core, cmd_cpu_type_t type, uint8_t level,
switch (type) {
#ifdef sun4u
-#define US4P_SCAT_CPUS_PER_CORE 2
-#define US4P_SCAT_CPU_CORE_STEP 4
#define US4P_SGTI_CPUS_PER_CORE 2
#define US4P_SGTI_CPU_CORE_STEP 512
#define US4P_DAKC_CPUS_PER_CORE 2
@@ -137,9 +134,7 @@ core2cpus(uint32_t core, cmd_cpu_type_t type, uint8_t level,
case CPU_ULTRASPARC_IVplus:
switch (level) {
case CMD_CPU_LEVEL_CORE:
- if (is_starcat)
- *cpustep = US4P_SCAT_CPU_CORE_STEP;
- else if (is_serengeti)
+ if (is_serengeti)
*cpustep = US4P_SGTI_CPU_CORE_STEP;
else
*cpustep = US4P_DAKC_CPU_CORE_STEP;
@@ -207,22 +202,15 @@ core2cpus(uint32_t core, cmd_cpu_type_t type, uint8_t level,
}
uint32_t
-cmd_cpu2core(uint32_t cpuid, cmd_cpu_type_t type, uint8_t level) {
-
+cmd_cpu2core(uint32_t cpuid, cmd_cpu_type_t type, uint8_t level)
+{
switch (type) {
#ifdef sun4u
-#define US4P_SCAT_CORE_SYSBD_STEP 32
-
case CPU_ULTRASPARC_IVplus:
switch (level) {
case CMD_CPU_LEVEL_CORE:
- if (is_starcat)
- return ((cpuid /
- US4P_SCAT_CORE_SYSBD_STEP) *
- US4P_SCAT_CORE_SYSBD_STEP +
- (cpuid % US4P_SCAT_CPU_CORE_STEP));
- else if (is_serengeti)
+ if (is_serengeti)
return (cpuid % US4P_SGTI_CPU_CORE_STEP);
else
return (cpuid % US4P_DAKC_CPU_CORE_STEP);
diff --git a/usr/src/cmd/fm/modules/sun4u/datapath-retire/cda_main.c b/usr/src/cmd/fm/modules/sun4u/datapath-retire/cda_main.c
index 5f0054775f..6cf411e49d 100644
--- a/usr/src/cmd/fm/modules/sun4u/datapath-retire/cda_main.c
+++ b/usr/src/cmd/fm/modules/sun4u/datapath-retire/cda_main.c
@@ -25,7 +25,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2019 Peter Tribble.
+ */
#include <cda.h>
@@ -175,8 +177,7 @@ cda_platform_check_support(fmd_hdl_t *hdl)
return (0);
}
- if (strcmp(buf, "SUNW,Sun-Fire-15000") == 0 ||
- strcmp(buf, "SUNW,Sun-Fire") == 0 ||
+ if (strcmp(buf, "SUNW,Sun-Fire") == 0 ||
strcmp(buf, "SUNW,Netra-T12") == 0)
return (1);
else
@@ -209,7 +210,7 @@ _fmd_init(fmd_hdl_t *hdl)
cda.cda_cpu_delay.tv_nsec = nsec % NANOSEC;
cda.cda_cpu_dooffline = fmd_prop_get_int32(hdl,
- "cpu_offline_enable");
+ "cpu_offline_enable");
cda.cda_cpu_forcedoffline = fmd_prop_get_int32(hdl,
"cpu_forced_offline");
}
diff --git a/usr/src/cmd/fm/schemes/mem/mem_unum.c b/usr/src/cmd/fm/schemes/mem/mem_unum.c
index dbc8e23bdf..51c9708878 100644
--- a/usr/src/cmd/fm/schemes/mem/mem_unum.c
+++ b/usr/src/cmd/fm/schemes/mem/mem_unum.c
@@ -24,7 +24,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2019 Peter Tribble.
+ */
#include <mem.h>
#include <fm/fmd_fmri.h>
@@ -113,7 +115,7 @@ static const bank_dimm_t bank_dimm[] = {
};
/*
- * Burst Serengeti and Starcat-style unums.
+ * Burst Serengeti-style unums.
* A DIMM unum string is expected to be in this form:
* "[/N0/]SB12/P0/B0/D2 [J13500]"
* A bank unum string is expected to be in this form:
@@ -259,12 +261,11 @@ mem_unum_burst(const char *pat, char ***dimmsp, size_t *ndimmsp)
const char *platform = fmd_fmri_get_platform();
/*
- * Call mem_unum_burst_sgsc() for Starcat, Serengeti, and
+ * Call mem_unum_burst_sgsc() for Serengeti and
* Lightweight 8 platforms. Call mem_unum_burst_pattern()
* for all other platforms.
*/
- if (strcmp(platform, "SUNW,Sun-Fire-15000") == 0 ||
- strcmp(platform, "SUNW,Sun-Fire") == 0 ||
+ if (strcmp(platform, "SUNW,Sun-Fire") == 0 ||
strcmp(platform, "SUNW,Netra-T12") == 0)
return (mem_unum_burst_sgsc(pat, dimmsp, ndimmsp));
else
diff --git a/usr/src/cmd/sckmd/sparc/sun4u/Makefile b/usr/src/cmd/sckmd/sparc/sun4u/Makefile
index e9a415991f..fc89b4ba4a 100644
--- a/usr/src/cmd/sckmd/sparc/sun4u/Makefile
+++ b/usr/src/cmd/sckmd/sparc/sun4u/Makefile
@@ -21,6 +21,7 @@
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2019 Peter Tribble.
#
# Makefile definitions for Sun Fire 15000 Key Management Daemon (sckmd)
#
@@ -50,7 +51,7 @@ $(USRPSMPROG) := FILEMODE = 0755
#
# FLAGS:
#
-CPPFLAGS= -I$(USR_PSM_INCL_DIR) -I$(SRC)/uts/sun4u/starcat $(CPPFLAGS.master)
+CPPFLAGS= -I$(USR_PSM_INCL_DIR) -I$(SRC)/uts/sun4u/opl $(CPPFLAGS.master)
LINT_FLAGS= -c -Nlevel=4 -Ncheck
diff --git a/usr/src/cmd/sckmd/svc-sckmd b/usr/src/cmd/sckmd/svc-sckmd
index 4261c7c849..0bf66c2776 100644
--- a/usr/src/cmd/sckmd/svc-sckmd
+++ b/usr/src/cmd/sckmd/svc-sckmd
@@ -22,8 +22,7 @@
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
+# Copyright 2019 Peter Tribble.
#
#
@@ -33,13 +32,11 @@
. /lib/svc/share/smf_include.sh
platform=${_INIT_UTS_PLATFORM:-`/sbin/uname -i`}
-starcat="SUNW,Sun-Fire-15000"
-opl="SUNW,SPARC-Enterprise"
+opl="SUNW,SPARC-Enterprise"
sckmd="/usr/platform/sun4u/lib/sckmd"
-if [ ${platform} = "${starcat}" -o \
- ${platform} = "${opl}" ]; then
- if [ -x ${sckmd} ]; then
+if [ ${platform} = "${opl}" ]; then
+ if [ -x ${sckmd} ]; then
${sckmd}
exit $SMF_EXIT_OK
fi
diff --git a/usr/src/cmd/svc/profile/Makefile b/usr/src/cmd/svc/profile/Makefile
index 43ee2779bd..32ec303879 100644
--- a/usr/src/cmd/svc/profile/Makefile
+++ b/usr/src/cmd/svc/profile/Makefile
@@ -42,7 +42,6 @@ PROFILESRCS = \
ns_nis.xml \
ns_none.xml \
platform_SUNW,SPARC-Enterprise.xml \
- platform_SUNW,Sun-Fire-15000.xml \
platform_SUNW,Sun-Fire-880.xml \
platform_SUNW,Sun-Fire.xml \
platform_SUNW,UltraSPARC-IIi-Netract.xml \
diff --git a/usr/src/cmd/svc/profile/platform_SUNW,Sun-Fire-15000.xml b/usr/src/cmd/svc/profile/platform_SUNW,Sun-Fire-15000.xml
deleted file mode 100644
index 1f8b61f2e8..0000000000
--- a/usr/src/cmd/svc/profile/platform_SUNW,Sun-Fire-15000.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version='1.0'?>
-<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
-<!--
- Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- Use is subject to license terms.
-
- CDDL HEADER START
-
- The contents of this file are subject to the terms of the
- Common Development and Distribution License (the "License").
- You may not use this file except in compliance with the License.
-
- You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- or http://www.opensolaris.org/os/licensing.
- See the License for the specific language governing permissions
- and limitations under the License.
-
- When distributing Covered Code, include this CDDL HEADER in each
- file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- If applicable, add the following below this CDDL HEADER, with the
- fields enclosed by brackets "[]" replaced with your own identifying
- information: Portions Copyright [yyyy] [name of copyright owner]
-
- CDDL HEADER END
-
- ident "%Z%%M% %I% %E% SMI"
-
- NOTE: This service profile is not editable; its contents will be
- overwritten by package or patch operations, including operating
- system upgrade.
-
- SunFire 15000 platform service profile.
--->
-<service_bundle type='profile' name='default'>
- <service name='system/cvc' version='1' type='service'>
- <instance name='default' enabled='true'/>
- </service>
- <service name='platform/sun4u/dcs' version='1' type='service'>
- <instance name='default' enabled='true'/>
- </service>
- <service name='platform/sun4u/efdaemon' version='1' type='service'>
- <instance name='default' enabled='true'/>
- </service>
- <service name='platform/sun4u/sckmd' version='1' type='service'>
- <instance name='default' enabled='true'/>
- </service>
-</service_bundle>
diff --git a/usr/src/lib/cfgadm_plugins/Makefile.com b/usr/src/lib/cfgadm_plugins/Makefile.com
index 5fcc3e50e6..7cfd1df65c 100644
--- a/usr/src/lib/cfgadm_plugins/Makefile.com
+++ b/usr/src/lib/cfgadm_plugins/Makefile.com
@@ -53,7 +53,6 @@ LINKED_PLATFORMS += SUNW,Sun-Fire-V240
LINKED_PLATFORMS += SUNW,Sun-Fire-V250
LINKED_PLATFORMS += SUNW,Sun-Fire-V440
LINKED_PLATFORMS += SUNW,Sun-Fire-280R
-LINKED_PLATFORMS += SUNW,Sun-Fire-15000
LINKED_PLATFORMS += SUNW,Sun-Fire-880
LINKED_PLATFORMS += SUNW,Sun-Fire-480R
LINKED_PLATFORMS += SUNW,Sun-Fire-V890
diff --git a/usr/src/lib/fm/topo/maps/Makefile b/usr/src/lib/fm/topo/maps/Makefile
index a35419192f..04fc0d4b7d 100644
--- a/usr/src/lib/fm/topo/maps/Makefile
+++ b/usr/src/lib/fm/topo/maps/Makefile
@@ -23,6 +23,7 @@
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
# Copyright (c) 2018, Joyent, Inc.
+# Copyright 2019 Peter Tribble.
#
sparc_SUBDIRS = sun4u \
@@ -30,7 +31,6 @@ sparc_SUBDIRS = sun4u \
sparc \
SUNW,Sun-Fire \
SUNW,Sun-Fire-T200 \
- SUNW,Sun-Fire-15000 \
SUNW,SPARC-Enterprise \
SUNW,Sun-Blade-T6300 \
SUNW,Sun-Blade-T6320 \
diff --git a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Makefile b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Makefile
deleted file mode 100644
index a9b7e40152..0000000000
--- a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-PLATFORMS = SUNW,Sun-Fire-15000
-CLASS = platform
-DTDFILE = topology.dtd.1
-TOPOFILE = Sun-Fire-15000-hc-topology.xml
-SRCDIR = ../SUNW,Sun-Fire-15000
-
-include ../Makefile.map
diff --git a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Sun-Fire-15000-hc-topology.xml b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Sun-Fire-15000-hc-topology.xml
deleted file mode 100644
index abf4e4dbeb..0000000000
--- a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Sun-Fire-15000-hc-topology.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1">
-<!--
- Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- Use is subject to license terms.
-
- CDDL HEADER START
-
- The contents of this file are subject to the terms of the
- Common Development and Distribution License (the "License").
- You may not use this file except in compliance with the License.
-
- You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- or http://www.opensolaris.org/os/licensing.
- See the License for the specific language governing permissions
- and limitations under the License.
-
- When distributing Covered Code, include this CDDL HEADER in each
- file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- If applicable, add the following below this CDDL HEADER, with the
- fields enclosed by brackets "[]" replaced with your own identifying
- information: Portions Copyright [yyyy] [name of copyright owner]
-
- CDDL HEADER END
-
- ident "%Z%%M% %I% %E% SMI"
--->
-
-<topology name='SUNW,Sun-Fire-15000' scheme='hc'>
- <range name='interconnect' min='0' max='0'>
- <node instance='0'>
- <propgroup name='protocol' version='1'
- name-stability='Private' data-stability='Private' >
- <propval name='FRU' type='fmri'
- value='hc:///component=interconnect' />
- <propval name='label' type='string'
- value='interconnect' />
- </propgroup>
- </node>
- <dependents grouping='children'>
- <range name='ioboard' min='0' max='17'>
- <enum-method name='ioboard' version='1' />
- </range>
- <range name='cpu' min='0' max='100'>
- <enum-method name='chip' version='1' />
- </range>
- </dependents>
- </range>
- <range name='ses-enclosure' min='0' max='1024'>
- <enum-method name='ses' version='1' />
- </range>
-</topology>
diff --git a/usr/src/lib/fm/topo/modules/Makefile b/usr/src/lib/fm/topo/modules/Makefile
index afd38c1699..c079a37976 100644
--- a/usr/src/lib/fm/topo/modules/Makefile
+++ b/usr/src/lib/fm/topo/modules/Makefile
@@ -22,13 +22,12 @@
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2019 Peter Tribble.
#
-# ident "%Z%%M% %I% %E% SMI"
sparc_SUBDIRS = sun4u \
sun4v \
SUNW,Sun-Fire \
- SUNW,Sun-Fire-15000 \
SUNW,SPARC-Enterprise
i386_SUBDIRS = i86pc
diff --git a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/Makefile b/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/Makefile
deleted file mode 100644
index 122db7a134..0000000000
--- a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-SUBDIRS = ioboard
-
-.PARALLEL: $(SUBDIRS)
-
-include ../../../Makefile.subdirs
diff --git a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/Makefile b/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/Makefile
deleted file mode 100644
index 1eeb70f998..0000000000
--- a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-
-CLASS = plat
-PLATFORMS = SUNW,Sun-Fire-15000
-
-include ../../sun4/ioboard/Makefile.iob
diff --git a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/iob_platform.c b/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/iob_platform.c
deleted file mode 100644
index c62169f49c..0000000000
--- a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/iob_platform.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * SUNW,Sun-Fire platform ioboard topology enumerator
- */
-
-#include <string.h>
-#include <libdevinfo.h>
-#include <fm/topo_mod.h>
-#include <fm/topo_hc.h>
-
-#include <did.h>
-#include <hostbridge.h>
-#include <ioboard.h>
-#include <util.h>
-
-/*ARGSUSED*/
-int
-platform_iob_label(topo_mod_t *mod, tnode_t *node, nvlist_t *ignored,
- nvlist_t **out)
-{
- /*
- * For E15K, the label is simply IOXX where XX is the
- * instance number of the ioboard.
- */
- char buf[10]; /* up to a million I/O boards :-) */
-
- *out = NULL;
- (void) snprintf(buf, 10, "IO%d", topo_node_instance(node));
- if (topo_mod_nvalloc(mod, out, NV_UNIQUE_NAME) == 0 &&
- nvlist_add_string(*out, TOPO_METH_LABEL_RET_STR, buf) == 0)
- return (0);
- nvlist_free(*out);
- *out = NULL;
- return (-1);
-}
-
-#define IOB_BASEADDR 0x1c
-#define BUS_ADDRDIST 0x20
-
-/*ARGSUSED*/
-int
-platform_iob_enum(topo_mod_t *mod, tnode_t *parent, topo_instance_t imin,
- topo_instance_t imax)
-{
- /*
- * An E15K and its successors may have up to 18 I/O boards,
- * numbered 0 through 17. Each board has two hostbridges, and
- * there are a pair of PCI buses under each hostbridge. We can
- * discover the existence of a board by the presence of
- * devinfo nodes for those hostbridges. We let the hostbridge
- * enumerator actually create nodes for the hostbridges,
- * passing them the did_t's for all the hostbridge nodes we
- * know indicate that the ioboard exists.
- */
- di_node_t devtree;
- di_node_t pnode;
- did_t *iobs[18][2][2];
- int brd, br, bus, i;
-
- devtree = topo_mod_devinfo(mod);
- if (devtree == DI_NODE_NIL) {
- topo_mod_dprintf(mod, "devinfo init failed.");
- return (-1);
- }
-
- for (i = 0; i < 18; i++) {
- iobs[i][0][0] = iobs[i][0][1] = NULL;
- iobs[i][1][0] = iobs[i][1][1] = NULL;
- }
-
- pnode = di_drv_first_node(SCHIZO, devtree);
- while (pnode != DI_NODE_NIL) {
- did_t *d;
-
- d = split_bus_address(mod,
- pnode, IOB_BASEADDR, BUS_ADDRDIST, 0, 17, &brd, &br, &bus);
- if (d == NULL) {
- pnode = di_drv_next_node(pnode);
- continue;
- }
- iobs[brd][br][bus] = d;
- pnode = di_drv_next_node(pnode);
- }
-
- for (i = 0; i < 18; i++) {
- tnode_t *ion;
- /*
- * Make sure we found all the buses and bridges
- */
- if (iobs[i][0][0] == NULL || iobs[i][0][1] == NULL ||
- iobs[i][1][0] == NULL || iobs[i][1][1] == NULL)
- continue;
- did_did_link_set(iobs[i][0][0], iobs[i][0][1]);
- did_did_link_set(iobs[i][1][0], iobs[i][1][1]);
- did_did_chain_set(iobs[i][0][0], iobs[i][1][0]);
- if ((ion = ioboard_declare(mod, parent, i, iobs[i][0][0]))
- == NULL) {
- topo_mod_dprintf(mod,
- "Creation of tnode for %s%d failed.\n", IOBOARD, i);
- continue;
- }
- if (topo_mod_enumerate(mod, ion, HOSTBRIDGE, HOSTBRIDGE, 0, 0,
- iobs[i][0][0]) < 0) {
- topo_mod_dprintf(mod,
- "Enumeration of %s%d/%s%d failed.\n",
- IOBOARD, i, HOSTBRIDGE, 0);
- continue;
- }
- if (topo_mod_enumerate(mod, ion, HOSTBRIDGE, HOSTBRIDGE, 1, 1,
- iobs[i][0][0]) < 0) {
- topo_mod_dprintf(mod,
- "Enumeration of %s%d/%s%d failed.\n",
- IOBOARD, i, HOSTBRIDGE, 1);
- continue;
- }
- }
- return (0);
-}
diff --git a/usr/src/lib/libc/capabilities/sun4u-us3/common/mapfile-cap b/usr/src/lib/libc/capabilities/sun4u-us3/common/mapfile-cap
index 987347dd94..789f4c8814 100644
--- a/usr/src/lib/libc/capabilities/sun4u-us3/common/mapfile-cap
+++ b/usr/src/lib/libc/capabilities/sun4u-us3/common/mapfile-cap
@@ -34,7 +34,6 @@ CAPABILITY {
PLATFORM += "SUNW,Sun-Blade-1000";
PLATFORM += "SUNW,Sun-Blade-1500";
PLATFORM += "SUNW,Sun-Blade-2500";
- PLATFORM += "SUNW,Sun-Fire-15000";
PLATFORM += "SUNW,Sun-Fire-280R";
PLATFORM += "SUNW,Sun-Fire-480R";
PLATFORM += "SUNW,Sun-Fire-880";
diff --git a/usr/src/lib/libprtdiag_psr/sparc/Makefile b/usr/src/lib/libprtdiag_psr/sparc/Makefile
index 2649e036df..3961e8fd4d 100644
--- a/usr/src/lib/libprtdiag_psr/sparc/Makefile
+++ b/usr/src/lib/libprtdiag_psr/sparc/Makefile
@@ -26,7 +26,7 @@
# lib/libprtdiag_psr/sparc/Makefile
PRTDIAG_PLATFORMS= desktop tazmo javelin sunfire serengeti \
- montecarlo littleneck starcat daktari cherrystone \
+ montecarlo littleneck daktari cherrystone \
lw8 snowbird ontario schumacher opl montoya monza
all := TARGET= all
diff --git a/usr/src/lib/libprtdiag_psr/sparc/starcat/Makefile b/usr/src/lib/libprtdiag_psr/sparc/starcat/Makefile
deleted file mode 100644
index ab80b392a0..0000000000
--- a/usr/src/lib/libprtdiag_psr/sparc/starcat/Makefile
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# lib/libprtdiag_psr/sparc/starcat/Makefile
-
-UTSBASE = ../../../../uts
-
-PLATFORM_OBJECTS= starcat.o
-
-include ../Makefile.com
-
-IFLAGS = -I$(USR_PLAT_DIR)/sun4u/include -I ../../../libprtdiag/inc
-LINTFLAGS += $(IFLAGS)
-
-PLATFORM=SUNW,Sun-Fire-15000
-
-$(USR_PLAT_DIR)/$(PLATFORM)/lib/libprtdiag_psr.so.1 := FILEMODE= 0755
-
-.KEEP_STATE:
-
-PLATLIBS= $(USR_PLAT_DIR)/$(PLATFORM)/lib/
-
-install: all $(USR_PSM_LIBS)
-
-$(USR_PSM_LIB_DIR):
- cd $(UTSBASE)/sun4u/starcat; $(MAKE) $(USR_PSM_LIB_DIR)
-
-#
-# install rule
-#
-$(USR_PSM_LIB_DIR)/%: % $(USR_PSM_LIB_DIR)
- $(INS.file)
-
-#
-# used for message files
-#
-POFILE= libprtdiag_psr_starcat.po
-POFILES= starcat.po
-
-
-_msg: $(MSGDOMAIN) $(POFILE)
- $(RM) $(MSGDOMAIN)/$(POFILE)
- $(CP) $(POFILE) $(MSGDOMAIN)
-
-$(POFILE): $(POFILES)
- $(RM) $@
- $(CAT) $(POFILES) > $@
-
-$(POFILES):
- $(RM) messages.po
- $(XGETTEXT) $(XGETFLAGS) `$(GREP) -l gettext common/starcat.c`
- $(SED) -e '/^# msg/d' -e '/^domain/d' messages.po > $@
- $(RM) messages.po
diff --git a/usr/src/lib/libprtdiag_psr/sparc/starcat/common/starcat.c b/usr/src/lib/libprtdiag_psr/sparc/starcat/common/starcat.c
deleted file mode 100644
index 0a053ccfd0..0000000000
--- a/usr/src/lib/libprtdiag_psr/sparc/starcat/common/starcat.c
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Starcat Platform specific functions.
- *
- * called when :
- * machine_type == MTYPE_STARCAT
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <string.h>
-#include <kvm.h>
-#include <varargs.h>
-#include <time.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/openpromio.h>
-#include <libintl.h>
-#include <syslog.h>
-#include <sys/dkio.h>
-#include <pdevinfo.h>
-#include <display.h>
-#include <pdevinfo_sun4u.h>
-#include <display_sun4u.h>
-#include <libprtdiag.h>
-
-#define HZ_TO_MHZ(x) (((x) + 500000) / 1000000)
-#define PORTID_TO_EXPANDER(p) (((p) >> 5) & 0x1f)
-#define PORTID_TO_SLOT(p) (((p) >> 3) & 0x1)
-#define PORTID_TO_INSTANCE(p) ((p) & 0x3)
-#define SCHIZO_COMPATIBLE "pci108e,8001"
-#define XMITS_COMPATIBLE "pci108e,8002"
-#define SC_BOARD_TYPE(id) (PORTID_TO_SLOT(id) ? "IO" : "SB")
-
-#ifndef TEXT_DOMAIN
-#define TEXT_DOMAIN "SYS_TEST"
-#endif /* TEXT_DOMAIN */
-
-#define DEFAULT_MAX_FREQ 66 /* 66 MHz */
-#define PCIX_MAX_FREQ 90 /* 90 MHz */
-
-/*
- * these functions will overlay the symbol table of libprtdiag
- * at runtime (Starcat systems only)
- */
-
-int do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag);
-void *get_prop_val(Prop *prop);
-Prop *find_prop(Prom_node *pnode, char *name);
-char *get_node_name(Prom_node *pnode);
-char *get_node_type(Prom_node *pnode);
-void add_node(Sys_tree *, Prom_node *);
-void display_pci(Board_node *);
-void display_ffb(Board_node *, int);
-void display_io_cards(struct io_card *list);
-void display_cpu_devices(Sys_tree *tree);
-void display_cpus(Board_node *board);
-void display_memoryconf(Sys_tree *tree, struct grp_info *grps);
-void print_us3_memory_line(int portid, int bank_id, uint64_t bank_size,
- char *bank_status, uint64_t dimm_size, uint32_t intlv, int seg_id);
-void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree,
- struct system_kstat_data *kstats);
-
-/* Local Functions */
-static void starcat_disp_hw_revisions(Prom_node *root);
-static void display_io_max_bus_speed(struct io_card *p);
-static void display_io_slot_info(struct io_card *p);
-
-/* The bus max freq is determined based on board level in use */
-int board_bus_max_freq = DEFAULT_MAX_FREQ; /* 66MHz default */
-
-/*
- * display_pci
- * Display all the PCI IO cards on this board.
- */
-void
-display_pci(Board_node *board)
-{
- struct io_card *card_list = NULL;
- struct io_card card;
- void *value;
- Prom_node *pci;
- Prom_node *card_node;
- Prom_node *pci_bridge_node = NULL;
- char *slot_name_arr[MAX_SLOTS_PER_IO_BD] = {NULL};
- char *slot_name = NULL;
- int slot_name_bits;
- int slot_name_offset = 0;
- char *child_name;
- char *name, *type;
- char buf[MAXSTRLEN];
- int *int_val;
- int pci_bus;
- int pci_bridge = 0;
- int pci_bridge_dev_no;
- int child_dev_no;
- int i;
- int portid;
- int version, *pversion;
-
- if (board == NULL)
- return;
-
- /* Initialize all the common information */
- card.display = TRUE;
- card.board = board->board_num;
- card.node_id = board->node_id;
-
- /*
- * Search for each schizo, then find/display all nodes under
- * each schizo node found. Since the model property "SUNW,schizo"
- * is not supported on Starcat, we must match on the compatible
- * property "pci108e,8001".
- */
- for (pci = dev_find_node_by_compatible(board->nodes, SCHIZO_COMPATIBLE);
- pci != NULL;
- pci = dev_next_node_by_compatible(pci, SCHIZO_COMPATIBLE)) {
-
- /* set max freq for this board */
- board_bus_max_freq = DEFAULT_MAX_FREQ;
- /*
- * Find out if this is a PCI or cPCI IO Board.
- * If "enum-impl" property exists in pci node => cPCI.
- */
- value = get_prop_val(find_prop(pci, "enum-impl"));
- if (value == NULL) {
- (void) sprintf(card.bus_type, "PCI");
- } else {
- (void) sprintf(card.bus_type, "cPCI");
- }
-
- if (strstr((char *)get_prop_val(
- find_prop(pci, "compatible")), XMITS_COMPATIBLE)) {
- sprintf(card.notes, "%s", XMITS_COMPATIBLE);
- /*
- * With XMITS 3.X and PCI-X mode, the bus speed
- * can be higher than 66MHZ.
- */
- value = (int *)get_prop_val
- (find_prop(pci, "module-revision#"));
- if (value) {
- pversion = (int *)value;
- version = *pversion;
- if (version >= 4)
- board_bus_max_freq = PCIX_MAX_FREQ;
- }
- } else if (strstr((char *)get_prop_val(
- find_prop(pci, "compatible")), SCHIZO_COMPATIBLE))
- sprintf(card.notes, "%s", SCHIZO_COMPATIBLE);
- else
- sprintf(card.notes, " ");
-
- /*
- * Get slot-names property from parent node and
- * store the individual slot names in an array.
- * This is more general than Starcat requires, but
- * it is correct, according to the slot-names property.
- */
- value = (char *)get_prop_val(find_prop(pci, "slot-names"));
- if (value == NULL) {
- /*
- * No slot_names property. This could be an Xmits
- * card, so check the child node for slot-names property
- */
- value = (char *)get_prop_val(
- find_prop(pci->child, "slot-names"));
- }
-
- if (value != NULL) {
- /* Get the 4 byte bitmask and pointer to first name */
- slot_name_bits = *(int *)value;
- if (slot_name_bits > 0)
- slot_name_offset = slot_name_bits - 1;
- slot_name = (char *)value + sizeof (int);
-
- for (i = 0; i < MAX_SLOTS_PER_IO_BD; i++) {
- if (! (slot_name_bits & (1 << i))) {
- slot_name_arr[i] = (char *)NULL;
- continue;
- }
-
- /*
- * Save the name pointer into the array
- * and advance it past the end of this
- * slot name
- */
- slot_name_arr[i] = slot_name;
- slot_name += strlen(slot_name) + 1;
- }
- slot_name = (char *)NULL;
- }
-
- /*
- * Search for Children of this node ie. Cards.
- * Note: any of these cards can be a pci-bridge
- * that itself has children. If we find a
- * pci-bridge we need to handle it specially.
- */
- card_node = pci->child;
- while (card_node != NULL) {
- pci_bridge = 0;
-
- /* If it doesn't have a name, skip it */
- name = (char *)get_prop_val(
- find_prop(card_node, "name"));
- if (name == NULL) {
- card_node = card_node->sibling;
- continue;
- }
-
- /*
- * get dev# and func# for this card from the
- * 'reg' property.
- */
- int_val = (int *)get_prop_val(
- find_prop(card_node, "reg"));
- if (int_val != NULL) {
- card.dev_no = (((*int_val) & 0xF800) >> 11);
- card.func_no = (((*int_val) & 0x700) >> 8);
- } else {
- card.dev_no = -1;
- card.func_no = -1;
- }
-
- /*
- * If this is a pci-bridge, then store it's dev#
- * as its children nodes need this to get their slot#.
- * We set the pci_bridge flag so that we know we are
- * looking at a pci-bridge node. This flag gets reset
- * every time we enter this while loop.
- */
-
- /*
- * Check for a PCI-PCI Bridge for PCI and cPCI
- * IO Boards using the name and type properties.
- */
- type = (char *)get_prop_val(
- find_prop(card_node, "device_type"));
- if ((type != NULL) &&
- (strncmp(name, "pci", 3) == 0) &&
- (strcmp(type, "pci") == 0)) {
- pci_bridge_dev_no = card.dev_no;
- pci_bridge_node = card_node;
- pci_bridge = TRUE;
- }
-
- /*
- * Get slot-names property from slot_names_arr.
- * If we are the child of a pci_bridge we use the
- * dev# of the pci_bridge as an index to get
- * the slot number. We know that we are a child of
- * a pci-bridge if our parent is the same as the last
- * pci_bridge node found above.
- */
- if (card.dev_no != -1) {
- /*
- * We compare this card's parent node with the
- * pci_bridge_node to see if it's a child.
- */
- if (card_node->parent == pci_bridge_node) {
- /* use dev_no of pci_bridge */
- child_dev_no = pci_bridge_dev_no - 1;
- } else {
- /* use card's own dev_no */
- child_dev_no = card.dev_no - 1;
- }
-
- if (child_dev_no < MAX_SLOTS_PER_IO_BD &&
- child_dev_no >= 0 &&
- slot_name_arr
- [child_dev_no + slot_name_offset] != NULL) {
-
- slot_name = slot_name_arr[
- child_dev_no + slot_name_offset];
- } else
- slot_name = (char *)NULL;
-
- if (slot_name != NULL && slot_name[0] != '\0') {
- (void) sprintf(card.slot_str, "%s",
- slot_name);
- } else {
- (void) sprintf(card.slot_str, "-");
- }
- } else {
- (void) sprintf(card.slot_str, "%c", '-');
- }
-
- /*
- * Get the portid of the schizo that this card
- * lives under.
- */
- portid = -1;
- value = get_prop_val(find_prop(pci, "portid"));
- if (value != NULL) {
- portid = *(int *)value;
- }
- card.schizo_portid = portid;
-
-#ifdef DEBUG
- (void) sprintf(card.notes, "%s portid [%d]"
- " dev_no [%d] slot_name[%s] name_bits[%#x]",
- card.notes, portid, card.dev_no,
- ((slot_name != NULL) ? slot_name : "NULL"),
- slot_name_bits);
-#endif /* DEBUG */
-
- /*
- * Find out whether this is PCI bus A or B
- * using the 'reg' property.
- */
- int_val = (int *)get_prop_val
- (find_prop(pci, "reg"));
-
- if (int_val != NULL) {
- int_val ++; /* skip over first integer */
- pci_bus = ((*int_val) & 0x7f0000);
- if (pci_bus == 0x600000)
- card.pci_bus = 'A';
- else if (pci_bus == 0x700000)
- card.pci_bus = 'B';
- else
- card.pci_bus = '-';
- } else {
- card.pci_bus = '-';
- }
-
-
- /*
- * Check for failed status.
- */
- if (node_failed(card_node))
- strcpy(card.status, "fail");
- else
- strcpy(card.status, "ok");
-
- /* Get the model of this card */
- value = get_prop_val(find_prop(card_node, "model"));
- if (value == NULL)
- card.model[0] = '\0';
- else {
- (void) sprintf(card.model, "%s", (char *)value);
- /*
- * If we wish to exclude onboard devices
- * (such as SBBC) then this is the place
- * and here is how to do it:
- *
- * if (strcmp(card.model, "SUNW,sbbc") == 0) {
- * card_node = card_node->sibling;
- * continue;
- * }
- */
- }
-
- /*
- * The card may have a "clock-frequency" but we
- * are not interested in that. Instead we get the
- * "clock-frequency" of the PCI Bus that the card
- * resides on. PCI-A can operate at 33Mhz or 66Mhz
- * depending on what card is plugged into the Bus.
- * PCI-B always operates at 33Mhz.
- *
- */
- int_val = get_prop_val(find_prop(pci,
- "clock-frequency"));
- if (int_val != NULL) {
- card.freq = HZ_TO_MHZ(*int_val);
- } else {
- card.freq = -1;
- }
-
- /*
- * Figure out how we want to display the name
- */
- value = get_prop_val(find_prop(card_node,
- "compatible"));
- if (value != NULL) {
- /* use 'name'-'compatible' */
- (void) sprintf(buf, "%s-%s", name,
- (char *)value);
- } else {
- /* just use 'name' */
- (void) sprintf(buf, "%s", name);
- }
- name = buf;
-
- /*
- * If this node has children, add the device_type
- * of the child to the name value of this card.
- */
- child_name = (char *)get_node_name(card_node->child);
- if ((card_node->child != NULL) &&
- (child_name != NULL)) {
- value = get_prop_val(find_prop(card_node->child,
- "device_type"));
- if (value != NULL) {
- /* add device_type of child to name */
- (void) sprintf(card.name, "%s/%s (%s)",
- name, child_name,
- (char *)value);
- } else {
- /* just add child's name */
- (void) sprintf(card.name, "%s/%s",
- name, child_name);
- }
- } else {
- /* childless, just the card's name */
- (void) sprintf(card.name, "%s", (char *)name);
- }
-
- /*
- * If this is a pci-bridge, then add the word
- * 'pci-bridge' to its model.
- */
- if (pci_bridge) {
- if (card.model[0] == '\0')
- (void) sprintf(card.model,
- "%s", "pci-bridge");
- else
- (void) strcat(card.model,
- "/pci-bridge");
- }
-
- /* insert this card in the list to be displayed later */
- card_list = insert_io_card(card_list, &card);
-
- /*
- * If we are dealing with a pci-bridge, we need to move
- * down to the children of this bridge, if there are
- * any, otherwise its siblings.
- *
- * If not a bridge, we are either dealing with a regular
- * card (in which case we move onto the sibling of this
- * card) or we are dealing with a child of a pci-bridge
- * (in which case we move onto the child's siblings or
- * if there are no more siblings for this child, we
- * move onto the parent's siblings). I hope you're
- * getting all this, there will be an exam later.
- */
- if (pci_bridge) {
- if (card_node->child != NULL)
- card_node = card_node->child;
- else
- card_node = card_node->sibling;
- } else {
- /*
- * If our parent is a pci-bridge but there
- * are no more of its children to process we
- * move back up to our parent's sibling,
- * otherwise we move onto our own sibling.
- */
- if ((card_node->parent == pci_bridge_node) &&
- (card_node->sibling == NULL))
- card_node =
- pci_bridge_node->sibling;
- else
- card_node = card_node->sibling;
- }
-
- } /* end while (card_node ...) loop */
-
- } /* end for (pci ...) loop */
-
- display_io_cards(card_list);
- free_io_cards(card_list);
-}
-
-/*
- * display_ffb
- *
- * There are no FFB's on a Starcat, however in the generic library,
- * the display_ffb() function is implemented so we have to define an
- * empty function here.
- */
-/*ARGSUSED0*/
-void
-display_ffb(Board_node *board, int table)
-{
-}
-
-/*
- * add_node
- *
- * This function adds a board node to the board structure where that
- * that node's physical component lives.
- */
-void
-add_node(Sys_tree *root, Prom_node *pnode)
-{
- int portid = -1;
- int nodeid = -1;
- void *value;
- Board_node *bnode;
- Prom_node *p;
- char *type;
-
- /* Get the board number of this board from the portid prop */
- if ((value = get_prop_val(find_prop(pnode, "portid"))) == NULL) {
- if (type = get_node_type(pnode))
- if (strcmp(type, "cpu") == 0)
- value = get_prop_val(find_prop(pnode->parent,
- "portid"));
- }
- if (value != NULL) {
- portid = *(int *)value;
- nodeid = PORTID_TO_EXPANDER(portid);
- }
-
- /* find the board node with the same board number */
- if ((bnode = find_board(root, portid)) == NULL) {
- bnode = insert_board(root, portid);
- bnode->board_type = UNKNOWN_BOARD;
- bnode->node_id = nodeid;
- }
-
- /* now attach this prom node to the board list */
- /* Insert this node at the end of the list */
- pnode->sibling = NULL;
- if (bnode->nodes == NULL)
- bnode->nodes = pnode;
- else {
- p = bnode->nodes;
- while (p->sibling != NULL)
- p = p->sibling;
- p->sibling = pnode;
- }
-}
-
-
-
-/*
- * Print out all the io cards in the list. Also print the column
- * headers if told to do so.
- */
-void
-display_io_cards(struct io_card *list)
-{
- char *hdrfmt = "%-10.10s %-4.4s %-4.4s %-4.4s %-4.4s %-4.4s"
- " %-4.4s %-5.5s %-32.32s %-22.22s"
-#ifdef DEBUG
- " %-22.22s"
-#endif /* DEBUG */
- "\n";
-
- static int banner = FALSE; /* Have we printed the column headings? */
- struct io_card *p;
-
- if (list == NULL)
- return;
-
- (void) textdomain(TEXT_DOMAIN);
-
- if (banner == FALSE) {
- log_printf(hdrfmt,
- "", "", "", "",
- gettext("Bus"),
- gettext("Max"),
- "", "", "", "",
-#ifdef DEBUG
- "",
-#endif /* DEBUG */
- 0);
-
- log_printf(hdrfmt,
- "",
- gettext("IO"),
- gettext("Port"),
- gettext("Bus"),
- gettext("Freq"),
- gettext("Bus"),
- gettext("Dev,"),
- "", "", "",
-#ifdef DEBUG
- "",
-#endif /* DEBUG */
- 0);
-
- log_printf(hdrfmt,
- gettext("Slot ID"),
- gettext("Type"),
- gettext(" ID"),
- gettext("Side"),
- gettext("MHz"),
- gettext("Freq"),
- gettext("Func"),
- gettext("State"),
- gettext("Name"),
- gettext("Model"),
-#ifdef DEBUG
- gettext("Notes"),
-#endif /* DEBUG */
- 0);
-
- log_printf(hdrfmt,
- "----------", "----", "----", "----", "----", "----",
- "----", "-----", "--------------------------------",
- "----------------------",
-#ifdef DEBUG
- "----------------------",
-#endif /* DEBUG */
- 0);
-
- banner = TRUE;
- }
-
- for (p = list; p != NULL; p = p -> next) {
-
- display_io_slot_info(p);
-
- display_io_max_bus_speed(p);
-
- log_printf("\n", 0);
- }
-}
-
-
-static void
-display_io_slot_info(struct io_card *p)
-{
- /*
- * Onboard devices are distinguished by Slot IDs that
- * indicate only the I/O board. Plug-in cards indicate
- * their leaf and Schizo.
- */
-
- if (p->slot_str[0] == '-') {
- log_printf("/%-2s%02d ",
- SC_BOARD_TYPE(p->board),
- PORTID_TO_EXPANDER(p->board), 0);
- } else {
- char c;
- if (strcmp(p->notes, XMITS_COMPATIBLE) == 0) {
- log_printf("/%-2s%02d/%s ",
- SC_BOARD_TYPE(p->board),
- PORTID_TO_EXPANDER(p->board),
- p->slot_str, 0);
- } else {
- if (p->pci_bus == 'A')
- c = '3';
- else if (p->pci_bus == 'B') {
- c = '5';
- } else
- c = '-';
- log_printf("/%-2s%02d/C%cV%1d ",
- SC_BOARD_TYPE(p->board),
- PORTID_TO_EXPANDER(p->board), c,
- PORTID_TO_INSTANCE(p->schizo_portid),
- 0);
- }
- }
- log_printf("%-4.4s ", gettext(p->bus_type), 0);
- log_printf("%3d ", p->schizo_portid, 0);
- log_printf(" %c ", p->pci_bus, 0);
- log_printf(" %3d ", p->freq, 0);
-}
-
-#define BUS_SPEED_PRINT(speed) log_printf(" %d ", speed, 0)
-
-static void
-display_io_max_bus_speed(struct io_card *p)
-{
- int speed = board_bus_max_freq;
-
- switch (p->pci_bus) {
- case 'A':
- BUS_SPEED_PRINT(speed);
- break;
- case 'B':
- if (strcmp(p->notes, XMITS_COMPATIBLE) == 0) {
- if (PORTID_TO_INSTANCE(p->schizo_portid) == 0)
- BUS_SPEED_PRINT(33);
- else
- BUS_SPEED_PRINT(speed);
- } else
- BUS_SPEED_PRINT(33);
- break;
- default:
- log_printf(" - ", 0);
- break;
- }
-
- log_printf("%-1d,%-1d ", p->dev_no, p->func_no, 0);
- log_printf("%-5.5s ", gettext(p->status), 0);
- log_printf("%-32.32s%c ", p->name,
- ((strlen(p->name) > 32) ? '+' : ' '), 0);
- log_printf("%-22.22s%c", p->model,
- ((strlen(p->model) > 22) ? '+' : ' '), 0);
-#ifdef DEBUG
- log_printf(" %s", p->notes, 0);
-#endif /* DEBUG */
-}
-
-void
-display_cpu_devices(Sys_tree *tree)
-{
- Board_node *bnode;
- char *hdrfmt = "%-8.8s %-7.7s %-4.4s %-4.4s %-7.7s %-4.4s\n";
-
- (void) textdomain(TEXT_DOMAIN);
-
- /*
- * Display the table header for CPUs . Then display the CPU
- * frequency, cache size, and processor revision of all cpus.
- */
- log_printf("\n", 0);
- log_printf("=========================", 0);
- log_printf(gettext(" CPUs "), 0);
- log_printf("=========================", 0);
- log_printf("\n\n", 0);
-
- log_printf(hdrfmt,
- "",
- gettext("CPU "),
- gettext("Run"),
- gettext(" E$"),
- gettext(" CPU"),
- gettext("CPU"), 0);
-
- log_printf(hdrfmt,
- gettext("Slot ID"),
- gettext("ID "),
- gettext("MHz"),
- gettext(" MB"),
- gettext("Impl."),
- gettext("Mask"), 0);
-
- log_printf(hdrfmt,
- "--------", "-------", "----", "----", "-------", "----", 0);
-
- /* Now display all of the cpus on each board */
- bnode = tree->bd_list;
- while (bnode != NULL) {
- display_cpus(bnode);
- bnode = bnode->next;
- }
-
- log_printf("\n", 0);
-}
-
-/*
- * Display the CPUs present on this board.
- */
-void
-display_cpus(Board_node *board)
-{
- Prom_node *cpu;
- uint_t freq; /* CPU clock frequency */
- int ecache_size; /* External cache size */
- int *impl;
- int *mask;
- int decoded_mask;
- int *cpuid;
- int *coreid;
- int cpuid_prev = -1;
- int ecache_size_prev = 0;
-
- (void) textdomain(TEXT_DOMAIN);
- /*
- * display the CPUs' operating frequency, cache size, impl. field
- * and mask revision.
- */
- for (cpu = dev_find_type(board->nodes, "cpu"); cpu != NULL;
- cpu = dev_next_type(cpu, "cpu")) {
-
- freq = HZ_TO_MHZ(get_cpu_freq(cpu));
- ecache_size = get_ecache_size(cpu);
- impl = (int *)get_prop_val(find_prop(cpu, "implementation#"));
- mask = (int *)get_prop_val(find_prop(cpu, "mask#"));
- cpuid = (int *)get_prop_val(find_prop(cpu, "cpuid"));
- if (cpuid == NULL)
- cpuid = &board->board_num;
-
- /* Do not display a failed CPU node */
- if ((freq == 0) || (impl == 0) || (node_failed(cpu)))
- continue;
-
- if (CPU_IMPL_IS_CMP(*impl)) {
- coreid = (int *)get_prop_val(find_prop(cpu,
- "reg"));
- if (coreid == NULL) {
- continue;
- }
-
- /*
- * The assumption is made that 2 cores will always be
- * listed together in the device tree. If either core
- * is "bad" then the FRU will not be listed.
- */
- if (cpuid_prev == -1) {
- cpuid_prev = *cpuid;
- ecache_size_prev = ecache_size;
- continue;
- } else {
- /*
- * Jaguar has a split E$, so the size for both
- * cores must be added together to get the total
- * size for the entire chip.
- *
- * Panther E$ (L3) is logically shared, so the
- * total size is equal to the core size.
- */
- if (IS_JAGUAR(*impl)) {
- ecache_size += ecache_size_prev;
- }
-
- ecache_size_prev = 0;
- }
- }
-
- /*
- * Print out cpu data.
- *
- * Slot ID
- */
- log_printf("/%-2s%02d/P%1d ",
- SC_BOARD_TYPE(*cpuid),
- PORTID_TO_EXPANDER(*cpuid),
- PORTID_TO_INSTANCE(*cpuid), 0);
-
- /* CPU ID */
- if (CPU_IMPL_IS_CMP(*impl)) {
- log_printf("%3d,%3d ", cpuid_prev,
- *cpuid, 0);
- cpuid_prev = -1;
- } else
- log_printf("%3d ", *cpuid, 0);
-
- /* Running frequency */
- log_printf("%4u ", freq, 0);
-
- /* Ecache size */
- if (ecache_size == 0)
- log_printf("%-4.4s ", gettext("N/A"), 0);
- else
- log_printf("%4.1f ",
- (float)ecache_size / (float)(1<<20),
- 0);
-
- /* Implementation */
- switch (*impl) {
- case CHEETAH_IMPL:
- log_printf("%-7.7s ",
- gettext("US-III"), 0);
- break;
- case CHEETAH_PLUS_IMPL:
- log_printf("%-7.7s ",
- gettext("US-III+"), 0);
- break;
- case JAGUAR_IMPL:
- log_printf("%-7.7s ",
- gettext("US-IV"), 0);
- break;
- case PANTHER_IMPL:
- log_printf("%-7.7s ",
- gettext("US-IV+"), 0);
- break;
- default:
- log_printf("%-7x ", *impl, 0);
- break;
- }
-
- /* CPU Mask */
- if (mask == NULL) {
- log_printf("%-4.4s", gettext("N/A"), 0);
- } else {
- if (IS_CHEETAH(*impl))
- decoded_mask = REMAP_CHEETAH_MASK(*mask);
- else
- decoded_mask = *mask;
-
- log_printf("%d.%d",
- (decoded_mask >> 4) & 0xf,
- decoded_mask & 0xf, 0);
- }
-
- log_printf("\n", 0);
- }
-}
-
-
-/*ARGSUSED1*/
-void
-display_memoryconf(Sys_tree *tree, struct grp_info *grps)
-{
- Board_node *bnode = tree->bd_list;
- char *hdrfmt = "\n%-11.11s %-4.4s %-7.7s %-7.7s %-8.8s %-6.6s"
- " %-10.10s %-10.10s";
-
- (void) textdomain(TEXT_DOMAIN);
-
- log_printf("=========================", 0);
- log_printf(gettext(" Memory Configuration "), 0);
- log_printf("=========================", 0);
- log_printf("\n", 0);
-
- log_printf(hdrfmt,
- "", "",
- gettext("Logical"),
- gettext("Logical"),
- gettext("Logical"),
- "", "", "", 0);
-
- log_printf(hdrfmt,
- "",
- gettext("Port"),
- gettext("Bank"),
- gettext("Bank"),
- gettext("Bank"),
- gettext(" DIMM"),
- gettext("Interleave"),
- gettext("Interleave"), 0);
-
- log_printf(hdrfmt,
- gettext("Slot ID"),
- gettext(" ID"),
- gettext("Number"),
- gettext("Size"),
- gettext("Status"),
- gettext(" Size"),
- gettext("Factor"),
- gettext("Segment"), 0);
-
- log_printf(hdrfmt,
- "-----------", "----", "-------", "-------", "--------",
- "------", "----------", "----------", 0);
-
- while (bnode != NULL) {
- if (get_us3_mem_regs(bnode)) {
- log_printf(
- gettext(
- "\nFailed to get memory information.\n"),
- 0);
- return;
- }
- bnode = bnode->next;
- }
-
- /* Display what we have found */
- display_us3_banks();
-}
-
-
-/*
- * This function provides Starcat's formatting of the memory config
- * information that get_us3_mem_regs() and display_us3_banks() code has
- * gathered. It overrides the generic print_us3_memory_line() code
- * which prints an error message.
- */
-void
-print_us3_memory_line(int portid, int bank_id, uint64_t bank_size,
- char *bank_status, uint64_t dimm_size, uint32_t intlv, int seg_id)
-{
- (void) textdomain(TEXT_DOMAIN);
-
- /* Slot ID */
- log_printf("\n/%-2s%02d/P%1d/B%1d ",
- SC_BOARD_TYPE(portid), PORTID_TO_EXPANDER(portid),
- PORTID_TO_INSTANCE(portid), (bank_id & 0x1), 0);
-
- /* Port ID */
- log_printf("%3d ", portid, 0);
-
- /* Logical Bank Number */
- log_printf(" %1d ", (bank_id & 0x3), 0);
-
- /* Logical Bank Size */
- log_printf("%4lldMB ", bank_size, 0);
-
- /* Logical Bank Status */
- log_printf("%-8.8s ", gettext(bank_status), 0);
-
- /* DIMM Size */
- log_printf("%4lldMB ", dimm_size, 0);
-
- /* Interleave Factor */
- log_printf(" %2d-%-3.3s ", intlv, gettext("way"), 0);
-
- /* Interleave Segment */
- log_printf(" %3d", seg_id, 0);
-}
-
-/*ARGSUSED2*/
-void
-display_diaginfo(int flag, Prom_node *root, Sys_tree *tree,
- struct system_kstat_data *kstats)
-{
- if (flag) {
- /*
- * display time of latest powerfail. Not all systems
- * have this capability. For those that do not, this
- * is just a no-op.
- */
- disp_powerfail(root);
-
- (void) textdomain(TEXT_DOMAIN);
-
- /* Print the header */
- log_printf("\n", 0);
- log_printf("=========================", 0);
- log_printf(gettext(" Diagnostic Information "), 0);
- log_printf("=========================", 0);
- log_printf("\n\n", 0);
- log_printf(gettext("For diagnostic information,"), 0);
- log_printf("\n", 0);
- log_printf(gettext(
- "see /var/opt/SUNWSMS/adm/[A-R]/messages on the SC."),
- 0);
- log_printf("\n", 0);
-
- /* Print the PROM revisions here */
- starcat_disp_hw_revisions(root);
- }
-}
-
-/*
- * local functions - functions that are only needed inside this library
- */
-
-static void
-starcat_disp_hw_revisions(Prom_node *root)
-{
- Prom_node *pnode;
- char *version;
-
- (void) textdomain(TEXT_DOMAIN);
-
- /* Print the header */
- log_printf("\n", 0);
- log_printf("=========================", 0);
- log_printf(gettext(" Hardware Revisions "), 0);
- log_printf("=========================", 0);
- log_printf("\n\n", 0);
-
- /* Display Prom revision header */
- log_printf(gettext("OpenBoot firmware revision:"), 0);
- log_printf("\n---------------------------\n", 0);
-
- /*
- * Display OBP version info
- */
- pnode = dev_find_node(root, "openprom");
- if (pnode != NULL) {
- version = (char *)get_prop_val(find_prop(pnode, "version"));
- log_printf("%s\n\n", version, 0);
- }
-}
-
-/*
- * We call do_devinfo() in order to use the libdevinfo device tree
- * instead of OBP's device tree.
- */
-int
-do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag)
-{
-
- return (do_devinfo(syserrlog, pgname, log_flag, prt_flag));
-
-}
-
-/*
- * return the property value for the Prop
- * passed in. (When using libdevinfo)
- */
-void *
-get_prop_val(Prop *prop)
-{
- if (prop == NULL)
- return (NULL);
-
- return ((void *)(prop->value.val_ptr));
-}
-
-/*
- * Search a Prom node and retrieve the property with the correct
- * name. (When using libdevinfo)
- */
-Prop *
-find_prop(Prom_node *pnode, char *name)
-{
- Prop *prop;
-
- if (pnode == NULL)
- return (NULL);
-
- for (prop = pnode->props; prop != NULL; prop = prop->next) {
- if (prop->name.val_ptr != NULL &&
- strcmp((char *)(prop->name.val_ptr), name) == 0)
- break;
- }
-
- return (prop);
-}
-
-/*
- * This function searches through the properties of the node passed in
- * and returns a pointer to the value of the name property.
- * (When using libdevinfo)
- */
-char *
-get_node_name(Prom_node *pnode)
-{
- Prop *prop;
-
- if (pnode == NULL) {
- return (NULL);
- }
-
- prop = pnode->props;
- while (prop != NULL) {
- if (strcmp("name", (char *)prop->name.val_ptr) == 0)
- return (prop->value.val_ptr);
- prop = prop->next;
- }
- return (NULL);
-}
-
-/*
- * This function searches through the properties of the node passed in
- * and returns a pointer to the value of the device_type property.
- * (When using libdevinfo)
- */
-char *
-get_node_type(Prom_node *pnode)
-{
- Prop *prop;
-
- if (pnode == NULL) {
- return (NULL);
- }
-
- prop = pnode->props;
- while (prop != NULL) {
- if (strcmp("device_type", (char *)prop->name.val_ptr) == 0)
- return (prop->value.val_ptr);
- prop = prop->next;
- }
- return (NULL);
-}
diff --git a/usr/src/man/man1m/Makefile b/usr/src/man/man1m/Makefile
index dafffb9739..eda366a82d 100644
--- a/usr/src/man/man1m/Makefile
+++ b/usr/src/man/man1m/Makefile
@@ -17,9 +17,10 @@
# Copyright 2016 Toomas Soome <tsoome@me.com>
# Copyright 2018 Nexenta Systems, Inc.
# Copyright (c) 2017, Chris Fraire <cfraire@me.com>.
+# Copyright 2019 Peter Tribble
#
-include $(SRC)//Makefile.master
+include $(SRC)/Makefile.master
MANSECT= 1m
@@ -543,8 +544,7 @@ i386_MANFILES= \
acpixtract.1m \
nvmeadm.1m
-sparc_MANFILES= cvcd.1m \
- dcs.1m \
+sparc_MANFILES= dcs.1m \
drd.1m \
efdaemon.1m \
ldmad.1m \
diff --git a/usr/src/man/man1m/cvcd.1m b/usr/src/man/man1m/cvcd.1m
deleted file mode 100644
index 56d349478c..0000000000
--- a/usr/src/man/man1m/cvcd.1m
+++ /dev/null
@@ -1,162 +0,0 @@
-'\" te
-.\" Copyright (c) 2006, Sun Microsystems, Inc. All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH CVCD 1M "Mar 9, 2006"
-.SH NAME
-cvcd \- virtual console daemon
-.SH SYNOPSIS
-.LP
-.nf
-\fB/platform\fI\fR/\fIplatform_name\fR/cvcd\fR [\fB-a\fR \fIauth\fR] [\fB-e\fR \fIencr\fR]
- [\fB-u\fR \fIesp_auth\fR]
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The virtual console daemon, \fBcvcd\fR, is a server process that supports the
-network console provided on some platforms. The \fBcvcd\fR daemon accepts
-network console connections from a remote host (only one host at any given
-time). Console input is read from this connection and forwarded to
-\fBcvc\fR(7D) by way of \fBcvcredir\fR(7D).
-.sp
-.LP
-Similarly, console output is read from \fBcvcredir\fR(7D) and forwarded across
-the network console connection. If \fBcvcd\fR dies, console traffic is
-automatically rerouted through an internal hardware interface.
-.sp
-.LP
-The \fBcvcd\fR daemon normally starts at system boot time. Each domain supports
-only one \fBcvcd\fR process at a time.
-.LP
-Caution -
-.sp
-.RS 2
-On Sun Enterprise 10000 domains, \fBcvcd\fR uses a configuration file
-(\fB/etc/ssphostname\fR) to determine the name of the host from which network
-console connections are allowed. If the remote console host is renamed, you
-must edit the configuration file to reflect that change.
-.RE
-.sp
-.LP
-The \fBcvcd\fR daemon supports per-socket IP Security Architecture (IPsec)
-through the options described below. See \fBipsec\fR(7P).
-.SH OPTIONS
-.sp
-.LP
-The \fBcvcd\fR daemon supports the options listed below.
-.sp
-.ne 2
-.na
-\fB\fB-a\fR \fIauth\fR\fR
-.ad
-.RS 15n
-Controls the IPsec Authentication Header (AH) algorithm. \fIauth\fR can be one
-of \fBnone\fR, \fBmd5\fR, or \fBsha1\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-e\fR \fIencr\fR\fR
-.ad
-.RS 15n
-Controls the IPsec Encapsulating Security Payload (ESP) encryption algorithm.
-\fIencr\fR can be one of \fBnone\fR, \fBdes\fR, or \fB3des\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-u\fR \fIesp_auth\fR\fR
-.ad
-.RS 15n
-Controls the IPsec Encapsulating Security Payload (ESP) authentication
-algorithm. \fIesp_auth\fR can be one of \fBnone\fR, \fBmd5\fR, or \fBsha1\fR.
-.RE
-
-.SH OPERANDS
-.sp
-.LP
-The following operands are supported:
-.sp
-.ne 2
-.na
-\fB\fIplatform_name\fR\fR
-.ad
-.RS 17n
-The official Sun platform name used in packaging and code. For example, for Sun
-Fire 15K servers, the \fIplatform_name\fR would be \fBSUNW,Sun-Fire-15000\fR.
-.RE
-
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRSetting an IPSec Option
-.sp
-.LP
-The command below sets the value of the IPsec Authentication Header algorithm
-to \fBmd5\fR. As a result of this command, \fBcvcd\fR will use the HMAC-MD5
-authentication algorithm.
-
-.sp
-.in +2
-.nf
-# \fBsvccfg -s svc:/system/cvc setprop cvc/ah_auth = "md5"\fR
-# \fBsvccfg -s svc:/system/cvc setprop cvc/esp_encr = "none"\fR
-# \fBsvccfg -s svc:/system/cvc setprop cvc/esp_auth = "none"\fR
-# \fBsvcadm refresh svc:/system/cvc\fR
-.fi
-.in -2
-.sp
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Architecture T{
-Sun Enterprise 10000 servers, Sun Fire High-End Systems
-T}
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBsvcs\fR(1), \fBsvcadm\fR(1M), \fBsvccfg\fR(1M), \fBservices\fR(4),
-\fBattributes\fR(5), \fBsmf\fR(5), \fBcvc\fR(7D), \fBcvcredir\fR(7D),
-\fBipsec\fR(7P)
-.sp
-.LP
-\fISun Enterprise 10000 SSP Reference Manual\fR
-.sp
-.LP
-\fISystem Management Services (SMS) Reference Manual\fR
-.SH NOTES
-.sp
-.LP
-The \fBcvcd\fR service is managed by the service management facility,
-\fBsmf\fR(5), under the fault management resource identifier (FMRI):
-.sp
-.in +2
-.nf
-svc:/system/cvc
-.fi
-.in -2
-.sp
-
-.sp
-.LP
-Administrative actions on this service, such as enabling, disabling, or
-requesting restart, can be performed using \fBsvcadm\fR(1M) or
-\fBsvccfg\fR(1M). The service's status can be queried using the \fBsvcs\fR(1)
-command.
diff --git a/usr/src/man/man1m/dcs.1m b/usr/src/man/man1m/dcs.1m
index e257bb081d..36c9cd7f70 100644
--- a/usr/src/man/man1m/dcs.1m
+++ b/usr/src/man/man1m/dcs.1m
@@ -1,20 +1,19 @@
'\" te
.\" Copyright 2005 (c), Sun Microsystems, Inc. All Rights Reserved
+.\" Copyright 2019 Peter Tribble.
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH DCS 1M "Apr 25, 2006"
+.TH DCS 1M "Apr 3, 2019"
.SH NAME
dcs \- domain configuration server
.SH SYNOPSIS
.LP
.nf
-\fB/usr/lib/dcs\fR [\fB-s\fR \fIsessions\fR]
- [ [\fB-a\fR \fIauth\fR] [\fB-e\fR \fIencr\fR] [\fB-u\fR \fIesp_auth\fR] ] [\fB-l\fR]
+\fB/usr/lib/dcs\fR [\fB-s\fR \fIsessions\fR] [\fB-l\fR]
.fi
.SH DESCRIPTION
-.sp
.LP
The Domain Configuration Server (DCS) is a daemon process that runs on Sun
servers that support remote Dynamic Reconfiguration (DR) clients. It is started
@@ -26,7 +25,7 @@ returned to the client.
.sp
.LP
The DCS listens on the network service labeled \fBsun-dr\fR. Its underlying
-protocol is TCP. It is invoked as a server program by the SMF using the TCP
+protocol is TCP. It is invoked as a server program by SMF using the TCP
transport. The fault management resource identifier (FMRI) for DCS is:
.sp
.in +2
@@ -42,58 +41,17 @@ If you disable this service, DR operations initiated from a remote host fail.
There is no negative impact on the server.
.sp
.LP
-Security for the DCS connection is provided differently based upon the
-architecture of the system. The SMF specifies the correct options when invoking
-the DCS daemon, based upon the current architecture. For all architectures,
-security is provided on a per-connection basis.
-.sp
-.LP
-The DCS daemon has no security options that are applicable when used on a Sun
-Enterprise 10000 system. So there are no options applicable to that
-architecture.
-.sp
-.LP
-The security options for Sun Fire high-end systems are based on IPsec options
-defined as SMF properties. These options include the \fB-a\fR \fIauth\fR,
-\fB-e\fR \fIencr\fR, and \fB-u\fR \fIesp_auth\fR options, and can be set using
-the \fBsvccfg\fR(1M) command. These options must match the IPsec policies
-defined for DCS on the system controller. Refer to the \fBkmd(1M)\fR man page
-in the \fISystem Management Services (SMS) Reference Manual\fR. The
-\fBkmd(1M)\fR man page is not part of the SunOS man page collection.
-.sp
-.LP
Security on SPARC Enterprise Servers is not configurable. The DCS daemon uses a
platform-specific library to configure its security options when running on
-such systems. The \fB-l\fR option is provided by the SMF when invoking the DCS
+such systems. The \fB-l\fR option is provided by SMF when invoking the DCS
daemon on SPARC Enterprise Servers. No other security options to the DCS daemon
should be used on SPARC Enterprise Servers.
.SH OPTIONS
-.sp
.LP
The following options are supported:
.sp
.ne 2
.na
-\fB\fB-a\fR \fIauth\fR\fR
-.ad
-.RS 15n
-Controls the IPsec Authentication Header (AH) algorithm. \fIauth\fR can be one
-of \fBnone\fR, \fBmd5\fR, or \fBsha1\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-e\fR \fIencr\fR\fR
-.ad
-.RS 15n
-Controls the IPsec Encapsulating Security Payload (ESP) encryption algorithm.
-\fIencr\fR can be one of \fBnone\fR, \fBdes\fR, or \fB3des\fR.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fB-l\fR\fR
.ad
.RS 15n
@@ -113,38 +71,7 @@ complete the execution of their DR operation. If this option is not specified,
a default value of 128 is used.
.RE
-.sp
-.ne 2
-.na
-\fB\fB-u\fR \fIesp_auth\fR\fR
-.ad
-.RS 15n
-Controls the IPsec Encapsulating Security Payload (ESP) authentication
-algorithm. \fIesp_auth\fR can be one of \fBnone\fR, \fBmd5\fR, or \fBsha1\fR.
-.RE
-
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRSetting an IPSec Option
-.sp
-.LP
-The following command sets the Authentication Header algorithm for the DCS
-daemon to use the HMAC-MD5 authentication algorithm. These settings are only
-applicable for using the DCS daemon on a Sun Fire high-end system.
-
-.sp
-.in +2
-.nf
-# \fBsvccfg -s svc:/platform/sun4u/dcs setprop dcs/ah_auth = "md5"\fR
-# \fBsvccfg -s svc:/platform/sun4u/dcs setprop dcs/esp_encr = "none"\fR
-# \fBsvccfg -s svc:/platform/sun4u/dcs setprop dcs/esp_auth = "none"\fR
-# \fBsvcadm refresh svc:/platform/sun4u/dcs\fR
-.fi
-.in -2
-.sp
-
.SH ERRORS
-.sp
.LP
The DCS uses \fBsyslog\fR(3C) to report status and error messages. All of the
messages are logged with the \fBLOG_DAEMON\fR facility. Error messages are
@@ -153,7 +80,6 @@ informational messages are logged with the \fBLOG_INFO\fR priority. The default
entries in the \fB/etc/syslog.conf\fR file log all of the DCS error messages to
the \fB/var/adm/messages\fR log.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -169,13 +95,11 @@ Interface Stability Evolving
.TE
.SH SEE ALSO
-.sp
.LP
-\fBsvcs\fR(1), \fBcfgadm_sbd\fR(1M), \fBsvcadm\fR(1M), \fBsvccfg\fR(1M),
+\fBsvcs\fR(1), \fBcfgadm_sbd\fR(1M), \fBsvcadm\fR(1M),
\fBsyslog\fR(3C), \fBconfig_admin\fR(3CFGADM), \fBlibcfgadm\fR(3LIB),
\fBsyslog.conf\fR(4), \fBattributes\fR(5), \fBsmf\fR(5), \fBdr\fR(7D)
.SH NOTES
-.sp
.LP
The \fBdcs\fR service is managed by the service management facility,
\fBsmf\fR(5), under the fault management resource identifier (FMRI):
diff --git a/usr/src/man/man1m/sckmd.1m b/usr/src/man/man1m/sckmd.1m
index 2cf70a5a04..547a6f982d 100644
--- a/usr/src/man/man1m/sckmd.1m
+++ b/usr/src/man/man1m/sckmd.1m
@@ -1,9 +1,10 @@
'\" te
.\" Copyright (c) 2005, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2019 Peter Tribble.
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SCKMD 1M "Apr 25, 2006"
+.TH SCKMD 1M "Apr 3, 2019"
.SH NAME
sckmd \- Sun cryptographic key management daemon
.SH SYNOPSIS
@@ -13,13 +14,12 @@ sckmd \- Sun cryptographic key management daemon
.fi
.SH DESCRIPTION
-.sp
.LP
\fBsckmd\fR is a server process that resides on a high-end system domain to
maintain the Internet Protocol Security (\fBIPsec\fR) Security Associations
(\fBSAs\fR) needed to secure communications between a Service Processor or
System Controller (SC) and platform management software running within a
-domain. The \fBcvcd\fR(1M) and \fBdcs\fR(1M) daemons use these Security
+domain. The \fBdcs\fR(1M) daemon uses these Security
Associations. See \fBipsec\fR(7P) for a description of Security Associations.
.sp
.LP
@@ -42,7 +42,6 @@ svc:/platform/sun4u/sckmd:default
.LP
A domain supports only one running \fBsckmd\fR process at a time.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -58,20 +57,18 @@ Interface Stability Evolving
.TE
.SH SEE ALSO
-.sp
.LP
-\fBcvcd\fR(1M), \fBdcs\fR(1M), \fBipsecconf\fR(1M), \fBipsecalgs\fR(1M),
+\fBdcs\fR(1M), \fBipsecconf\fR(1M), \fBipsecalgs\fR(1M),
\fBattributes\fR(5), \fBipsec\fR(7P), \fBipsecah\fR(7P), \fBipsecesp\fR(7P),
\fBpf_key\fR(7P)
.SH NOTES
-.sp
.LP
-The \fBsckmd\fR service is used only on Sun Fire high-end systems and the
-\fBSPARC\fR Enterprise Server family. It provides a mechanism for exchanging
+The \fBsckmd\fR service is used only on Sun Fire high-end systems.
+It provides a mechanism for exchanging
\fBIPsec\fR keys between a domain and its System Controller (\fBSC\fR) or
Service Processor. These platforms use \fBIPsec\fR to secure the communications
-between the \fBSC\fR or Service Processor and certain platform-specific daemons
-in the domain. Such daemons currently include \fBcvcd\fR(1M) and \fBdcs\fR(1M).
+between the \fBSC\fR or Service Processor and a platform-specific daemon
+in the domain, such as \fBdcs\fR(1M).
.sp
.LP
The documentation for each platform that supports \fBsckmd\fR describes how to
diff --git a/usr/src/man/man7d/Makefile b/usr/src/man/man7d/Makefile
index bd452ccabb..d48c6dc0be 100644
--- a/usr/src/man/man7d/Makefile
+++ b/usr/src/man/man7d/Makefile
@@ -20,7 +20,7 @@
include $(SRC)/Makefile.master
-MANSECT= 7d
+MANSECT= 7d
_MANFILES= aac.7d \
afe.7d \
@@ -151,8 +151,6 @@ _MANFILES= aac.7d \
sparc_MANFILES= audiocs.7d \
bbc_beep.7d \
ctsmc.7d \
- cvc.7d \
- cvcredir.7d \
dad.7d \
dm2s.7d \
dr.7d \
@@ -170,7 +168,6 @@ sparc_MANFILES= audiocs.7d \
pcicmu.7d \
pcipsy.7d \
pcisch.7d \
- schpc.7d \
sf.7d \
smbus.7d \
socal.7d \
diff --git a/usr/src/man/man7d/cvc.7d b/usr/src/man/man7d/cvc.7d
deleted file mode 100644
index 3cb73a0c73..0000000000
--- a/usr/src/man/man7d/cvc.7d
+++ /dev/null
@@ -1,61 +0,0 @@
-'\" te
-.\" Copyright (c) 2000, Sun Microsystems, Inc. All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH CVC 7D "Sep 15, 2000"
-.SH NAME
-cvc \- virtual console driver
-.SH DESCRIPTION
-.sp
-.LP
-The \fBcvc\fR virtual console driver is a STREAMS-based pseudo driver that
-supports the network console. The \fBcvc\fR driver interfaces with
-\fBconsole\fR(7D).
-.sp
-.LP
-Logically, the \fBcvc\fR driver sits below the \fBconsole\fR driver. It
-redirects console output to the \fBcvcredir\fR(7D) driver if a network console
-connection is active. If a network console connection is not active, it
-redirects console output to an internal hardware interface.
-.sp
-.LP
-The \fBcvc\fR driver receives console input from \fBcvcredir\fR and internal
-hardware and passes it to the process associated with \fB/dev/console\fR.
-.SH NOTES
-.sp
-.LP
-The \fBcvc\fR facility supersedes the SunOS \fBwscons\fR(7D) facility, which
-should \fInot\fR be used in conjunction with \fBcvc\fR. The \fBwscons\fR
-driver is useful for systems with directly attached consoles (frame buffers and
-keyboards), but is not useful with platforms using \fBcvc\fR, which have no
-local keyboard or frame buffer.
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Architecture T{
-Sun Enterprise 10000 servers, Sun Fire 15000 servers
-T}
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcvcd\fR(1M), \fBattributes\fR(5), \fBconsole\fR(7D), \fBcvcredir\fR(7D),
-\fBwscons\fR(7D)
-.sp
-.LP
-\fISun Enterprise 10000 SSP Reference Manual\fR
-.sp
-.LP
-\fISun System Management Services (SMS) Reference Manual\fR
diff --git a/usr/src/man/man7d/cvcredir.7d b/usr/src/man/man7d/cvcredir.7d
deleted file mode 100644
index aef2b8a73b..0000000000
--- a/usr/src/man/man7d/cvcredir.7d
+++ /dev/null
@@ -1,48 +0,0 @@
-'\" te
-.\" Copyright (c) 2000, Sun Microsystems, Inc. All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH CVCREDIR 7D "Sep 15, 2000"
-.SH NAME
-cvcredir \- virtual console redirection driver
-.SH DESCRIPTION
-.sp
-.LP
-The \fBcvcredir\fR virtual console redirection driver is a STREAMS-based pseudo
-driver that supports the network console provided on some platforms. The
-\fBcvcredir\fR driver interfaces with the virtual console driver \fBcvc\fR(7D),
-and the virtual console daemon, \fBcvcd\fR(1M).
-.sp
-.LP
-The \fBcvcredir\fR driver receives console output from \fBcvc\fR and passes it
-to \fBcvcd\fR. It receives console input from \fBcvcd\fR and passes it to
-\fBcvc\fR.
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Architecture T{
-Sun Enterprise 10000 servers, Sun Fire 15K servers
-T}
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcvcd\fR(1M), \fBattributes\fR(5), \fBconsole\fR(7D), \fBcvc\fR(7D)
-.sp
-.LP
-\fISun Enterprise 10000 SSP Reference Manual \fR
-.sp
-.LP
-\fISun System Management Services (SMS) Reference Manual\fR
diff --git a/usr/src/man/man7d/schpc.7d b/usr/src/man/man7d/schpc.7d
deleted file mode 100644
index bba34fc340..0000000000
--- a/usr/src/man/man7d/schpc.7d
+++ /dev/null
@@ -1,38 +0,0 @@
-'\" te
-.\" Copyright (c) 2005, Sun Microsystems, Inc. All Rights Reserved
-.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
-.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
-.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH SCHPC 7D "May 26, 2005"
-.SH NAME
-schpc \- StarCat Hot Plug Controller Driver
-.SH DESCRIPTION
-.sp
-.LP
-The \fBschpc\fR driver controls all hot-plug operations on high-end Sun Fire
-E15K and E25K enterprise servers.
-.SH FILES
-.sp
-.ne 2
-.na
-\fB\fB/platform/SUNW,Sun-Fire-15000/kernel/drv/sparcv9/schpc\fR\fR
-.ad
-.sp .6
-.RS 4n
-64-bit ELF kernel module.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB/platform/SUNW,Sun-Fire-15000/kernel/drv/schpc.conf\fR\fR
-.ad
-.sp .6
-.RS 4n
-Driver configuration file.
-.RE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcfgadm\fR(1M)
diff --git a/usr/src/man/man7d/wscons.7d b/usr/src/man/man7d/wscons.7d
index f01075e356..a39c3e9825 100644
--- a/usr/src/man/man7d/wscons.7d
+++ b/usr/src/man/man7d/wscons.7d
@@ -1,9 +1,10 @@
'\" te
.\" Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2019 Peter Tribble.
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH WSCONS 7D "May 26, 2006"
+.TH WSCONS 7D "Apr 3, 2019"
.SH NAME
wscons \- workstation console
.SH SYNOPSIS
@@ -23,7 +24,6 @@ wscons \- workstation console
.fi
.SH DESCRIPTION
-.sp
.LP
The \fBwscons\fR workstation console consists of a workstation keyboard and
frame buffer that act together to emulate an \fBASCII\fR terminal. It includes
@@ -31,7 +31,6 @@ a redirection facility that allows I/O issued to the workstation console to be
diverted to a STREAMS device, enabling window systems to redirect output that
would otherwise appear directly on the frame buffer in corrupted form.
.SS "Redirection"
-.sp
.LP
The \fBwscons\fR redirection facility maintains a list of devices that are
designated as redirection targets through the \fBSRIOCSREDIR\fR ioctl described
@@ -65,7 +64,6 @@ device denoted by \fIfd\fR, and 0 if it is not.
.RE
.SS "ANSI Standard Terminal Emulation"
-.sp
.LP
The Solaris kernel terminal emulator provides ANSI X3.64 emulation both on
SPARC and x86 systems.
@@ -111,7 +109,6 @@ right-bottom edge, the line-feed function is performed (see \fBCTRL-J\fR
below). The line-feed function scrolls the screen up by one or more lines
before moving the cursor to the first character position on the next line.
.SS "Control Sequence Syntax"
-.sp
.LP
The \fBwscons\fR console defines a number of control sequences that may occur
during input. When a control sequence is written to the console, it affects
@@ -246,7 +243,6 @@ parameter value of 1. Note that \fBESC[;5M\fR (interpreted as \fB`ESC[5M\fR')
is \fInot\fR equivalent to \fBESC[5;M\fR (interpreted as `\fBESC[5;1M\fR')
which is ultimately interpreted as `\fBESC[1M\fR').
.SS "ANSI Control Functions"
-.sp
.LP
The following paragraphs specify the \fBANSI\fR control functions implemented
by the console. Each description provides:
@@ -288,7 +284,6 @@ Initial setting of the mode for functions that set a mode. To restore the
initial settings, use the \fBSUNRESET\fR escape sequence.
.RE
.SS "Control Character Functions"
-.sp
.LP
The \fBwscons \fRcontrol character functions are:
.sp
@@ -449,7 +444,6 @@ The cursor moves to the leftmost character position on the current line.
.RE
.SS "Escape Sequence Functions"
-.sp
.LP
The \fBwscons \fRescape sequence functions are:
.sp
@@ -966,7 +960,6 @@ Takes no parameters. Resets all modes to default, restores current font from
.RE
.SH RETURN VALUES
-.sp
.LP
When there are no errors, the redirection ioctls have return values as
described above. Otherwise, they return \fB\(mi1\fR and set \fBerrno\fR to
@@ -977,7 +970,6 @@ set accordingly.
If the \fItarget\fR stream is in an error state, \fBerrno\fR is set
accordingly.
.SH ERRORS
-.sp
.ne 2
.na
\fB\fBEBADF\fR\fR
@@ -996,7 +988,6 @@ accordingly.
.RE
.SH FILES
-.sp
.ne 2
.na
\fB\fB/dev/wscons\fR\fR
@@ -1034,7 +1025,6 @@ Access system console
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -1050,19 +1040,12 @@ Interface Stability Stable
.TE
.SH SEE ALSO
-.sp
.LP
-\fBcvcd\fR(1M), \fBeeprom\fR(1M), \fBioctl\fR(2), \fBpoll\fR(2), \fBread\fR(2),
-\fBwrite\fR(2), \fBcvc\fR(7D), \fBconsole\fR(7D), \fBvisual_io\fR(7I)
+\fBeeprom\fR(1M), \fBioctl\fR(2), \fBpoll\fR(2), \fBread\fR(2),
+\fBwrite\fR(2), \fBconsole\fR(7D), \fBvisual_io\fR(7I)
.SH WARNINGS
-.sp
.LP
The redirection ioctls block while there is I/O outstanding on the device
instance being redirected. If you try to redirect the workstation console while
there is a outstanding read, the workstation console will hang until the read
completes.
-.SH NOTES
-.sp
-.LP
-The \fBcvc \fRfacility supersedes the SunOS \fBwscons \fRfacility and should
-not be used with \fBwscons\fR.
diff --git a/usr/src/pkg/manifests/SUNWcs.mf b/usr/src/pkg/manifests/SUNWcs.mf
index a2db071aef..3492b64e22 100644
--- a/usr/src/pkg/manifests/SUNWcs.mf
+++ b/usr/src/pkg/manifests/SUNWcs.mf
@@ -449,8 +449,6 @@ file path=etc/svc/profile/ns_nis.xml group=sys mode=0444
file path=etc/svc/profile/ns_none.xml group=sys mode=0444
$(sparc_ONLY)file path=etc/svc/profile/platform_SUNW,SPARC-Enterprise.xml \
group=sys mode=0444
-$(sparc_ONLY)file path=etc/svc/profile/platform_SUNW,Sun-Fire-15000.xml \
- group=sys mode=0444
$(sparc_ONLY)file path=etc/svc/profile/platform_SUNW,Sun-Fire-880.xml \
group=sys mode=0444
$(sparc_ONLY)file path=etc/svc/profile/platform_SUNW,Sun-Fire.xml group=sys \
diff --git a/usr/src/pkg/manifests/SUNWcvc.mf b/usr/src/pkg/manifests/SUNWcvc.mf
deleted file mode 100644
index e8622664b7..0000000000
--- a/usr/src/pkg/manifests/SUNWcvc.mf
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-set name=pkg.fmri value=pkg:/SUNWcvc@0.5.11,5.11-0.133
-set name=pkg.renamed value=true
-set name=variant.arch value=sparc
-depend fmri=pkg:/system/network-console@0.5.11,5.11-0.133 type=require
diff --git a/usr/src/pkg/manifests/SUNWdrcr.mf b/usr/src/pkg/manifests/SUNWdrcr.mf
deleted file mode 100644
index ee1b911f8b..0000000000
--- a/usr/src/pkg/manifests/SUNWdrcr.mf
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-set name=pkg.fmri value=pkg:/SUNWdrcr@0.5.11,5.11-0.133
-set name=pkg.renamed value=true
-set name=variant.arch value=sparc
-depend \
- fmri=pkg:/system/kernel/dynamic-reconfiguration/sun-fire-15000@0.5.11,5.11-0.133 \
- type=require
diff --git a/usr/src/pkg/manifests/developer-apptrace-platform.mf b/usr/src/pkg/manifests/developer-apptrace-platform.mf
index 1552f3a7a7..7b5d068301 100644
--- a/usr/src/pkg/manifests/developer-apptrace-platform.mf
+++ b/usr/src/pkg/manifests/developer-apptrace-platform.mf
@@ -53,8 +53,6 @@ dir path=usr/platform/SUNW,Sun-Blade-1500/lib
dir path=usr/platform/SUNW,Sun-Blade-2500 group=sys
dir path=usr/platform/SUNW,Sun-Blade-2500/lib
dir path=usr/platform/SUNW,Sun-Fire group=sys
-dir path=usr/platform/SUNW,Sun-Fire-15000 group=sys
-dir path=usr/platform/SUNW,Sun-Fire-15000/lib
dir path=usr/platform/SUNW,Sun-Fire-280R group=sys
dir path=usr/platform/SUNW,Sun-Fire-280R/lib
dir path=usr/platform/SUNW,Sun-Fire-480R group=sys
diff --git a/usr/src/pkg/manifests/service-fault-management.mf b/usr/src/pkg/manifests/service-fault-management.mf
index 59709ed5f1..8e97ddca9e 100644
--- a/usr/src/pkg/manifests/service-fault-management.mf
+++ b/usr/src/pkg/manifests/service-fault-management.mf
@@ -23,6 +23,7 @@
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2019, Joyent, Inc.
# Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
+# Copyright 2019 Peter Tribble.
#
#
@@ -166,13 +167,6 @@ $(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Blade-T6320/lib/fm/fmd/plugins
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Blade-T6320/lib/fm/topo
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Blade-T6320/lib/fm/topo/maps
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire group=sys
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000 group=sys
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000/lib
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000/lib/fm
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000/lib/fm/eft
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/maps
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/plugins
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-T200 group=sys
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-T200/lib
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-T200/lib/fm
@@ -625,15 +619,6 @@ $(sparc_ONLY)file \
path=usr/platform/SUNW,Sun-Blade-T6320/lib/fm/topo/maps/Sun-Blade-T6320-hc-topology.xml \
mode=0444
$(sparc_ONLY)file \
- path=usr/platform/SUNW,Sun-Fire-15000/lib/fm/eft/SUNW,Sun-Fire-15000.eft \
- mode=0444
-$(sparc_ONLY)file \
- path=usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/maps/Sun-Fire-15000-hc-topology.xml \
- mode=0444
-$(sparc_ONLY)file \
- path=usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/plugins/ioboard.so \
- mode=0555
-$(sparc_ONLY)file \
path=usr/platform/SUNW,Sun-Fire-T200/lib/fm/fmd/plugins/etm.conf
$(sparc_ONLY)file \
path=usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/Netra-T2000-hc-topology.xml \
diff --git a/usr/src/pkg/manifests/service-key-management-sun-fire-15000.mf b/usr/src/pkg/manifests/service-key-management-sun-fire-15000.mf
index 0c0dba2bc6..92681985ec 100644
--- a/usr/src/pkg/manifests/service-key-management-sun-fire-15000.mf
+++ b/usr/src/pkg/manifests/service-key-management-sun-fire-15000.mf
@@ -21,6 +21,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2019 Peter Tribble.
#
#
@@ -30,41 +31,6 @@
#
<include global_zone_only_component>
set name=pkg.fmri value=pkg:/service/key-management/sun-fire-15000@$(PKGVERS)
-set name=pkg.description value="Key Management Modules for Sun Fire 15000"
-set name=pkg.summary value="Key Management Modules for Sun Fire 15000"
-set name=info.classification \
- value="org.opensolaris.category.2008:System/Enterprise Management"
+set name=pkg.obsolete value=true
+set name=org.opensolaris.noincorp value=true
set name=variant.arch value=sparc
-dir path=lib
-dir path=lib/svc
-dir path=lib/svc/manifest group=sys
-dir path=lib/svc/manifest/platform group=sys
-dir path=lib/svc/manifest/platform/sun4u group=sys
-dir path=lib/svc/method
-dir path=platform group=sys
-dir path=platform/SUNW,Sun-Fire-15000 group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel/drv group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64) group=sys
-dir path=usr group=sys
-dir path=usr/platform group=sys
-dir path=usr/platform/sun4u group=sys
-dir path=usr/platform/sun4u/lib
-dir path=usr/share/man/man1m
-driver name=sckmdrv perms="* 0600 root sys"
-file path=lib/svc/manifest/platform/sun4u/sckmd.xml group=sys mode=0444
-file path=lib/svc/method/svc-sckmd mode=0555
-file path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64)/sckmdrv group=sys
-file path=platform/SUNW,Sun-Fire-15000/kernel/drv/sckmdrv.conf group=sys
-file path=usr/platform/sun4u/lib/sckmd group=sys mode=0755
-file path=usr/share/man/man1m/sckmd.1m
-legacy pkg=SUNWsckm.u arch=$(ARCH).sun4u \
- desc="Key Management Modules for Sun Fire 15000" \
- name="Key Management Modules for Sun Fire 15000"
-legacy pkg=SUNWsckmr desc="SMF service for the Key Management daemon" \
- name="SMF service for the Key Management daemon"
-legacy pkg=SUNWsckmu.u arch=$(ARCH).sun4u \
- desc="Key Management daemon for exchanging security keys from the Service Processor" \
- name="Key Management daemon"
-license cr_Sun license=cr_Sun
-license lic_CDDL license=lic_CDDL
diff --git a/usr/src/pkg/manifests/system-domain-service-processor-protocol-sparc-enterprise.mf b/usr/src/pkg/manifests/system-domain-service-processor-protocol-sparc-enterprise.mf
index d48e4a4355..67c5f874e4 100644
--- a/usr/src/pkg/manifests/system-domain-service-processor-protocol-sparc-enterprise.mf
+++ b/usr/src/pkg/manifests/system-domain-service-processor-protocol-sparc-enterprise.mf
@@ -22,6 +22,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
+# Copyright 2019 Peter Tribble.
#
#
@@ -54,13 +55,17 @@ dir path=usr/platform group=sys
dir path=usr/platform/SUNW,SPARC-Enterprise group=sys
dir path=usr/platform/SUNW,SPARC-Enterprise/lib
dir path=usr/platform/SUNW,SPARC-Enterprise/sbin
+dir path=usr/platform/sun4u group=sys
+dir path=usr/platform/sun4u/lib
dir path=usr/share/man
dir path=usr/share/man/man1m
dir path=usr/share/man/man7d
driver name=dm2s
driver name=oplkmdrv
file path=lib/svc/manifest/platform/sun4u/dscp.xml group=sys mode=0444
+file path=lib/svc/manifest/platform/sun4u/sckmd.xml group=sys mode=0444
file path=lib/svc/method/svc-dscp mode=0555
+file path=lib/svc/method/svc-sckmd mode=0555
file path=platform/SUNW,SPARC-Enterprise/kernel/drv/$(ARCH64)/dm2s group=sys
file path=platform/SUNW,SPARC-Enterprise/kernel/drv/$(ARCH64)/oplkmdrv \
group=sys
@@ -70,7 +75,9 @@ file path=usr/platform/SUNW,SPARC-Enterprise/lib/dscp.ppp.options group=sys \
mode=0555
file path=usr/platform/SUNW,SPARC-Enterprise/lib/libdscp.so.1
file path=usr/platform/SUNW,SPARC-Enterprise/sbin/prtdscp mode=0755
+file path=usr/platform/sun4u/lib/sckmd group=sys mode=0755
file path=usr/share/man/man1m/prtdscp.1m
+file path=usr/share/man/man1m/sckmd.1m
file path=usr/share/man/man7d/dm2s.7d
file path=usr/share/man/man7d/oplkmdrv.7d
legacy pkg=SUNWdscpr.u arch=$(ARCH).sun4u \
diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf
index b06bc6c0b6..d41dd616d4 100644
--- a/usr/src/pkg/manifests/system-header.mf
+++ b/usr/src/pkg/manifests/system-header.mf
@@ -140,7 +140,6 @@ $(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Blade-1000 group=sys
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Blade-1500 group=sys
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Blade-2500 group=sys
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire group=sys
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000 group=sys
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-280R group=sys
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-480R group=sys
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-880 group=sys
@@ -1980,8 +1979,6 @@ $(sparc_ONLY)link path=usr/platform/SUNW,Sun-Blade-1500/include \
target=../sun4u/include
$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Blade-2500/include \
target=../sun4u/include
-$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Fire-15000/include \
- target=../sun4u/include
$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Fire-280R/include \
target=../sun4u/include
$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Fire-480R/include \
diff --git a/usr/src/pkg/manifests/system-kernel-dynamic-reconfiguration-sun-fire-15000.mf b/usr/src/pkg/manifests/system-kernel-dynamic-reconfiguration-sun-fire-15000.mf
index 36bd1927d1..3cd4fda628 100644
--- a/usr/src/pkg/manifests/system-kernel-dynamic-reconfiguration-sun-fire-15000.mf
+++ b/usr/src/pkg/manifests/system-kernel-dynamic-reconfiguration-sun-fire-15000.mf
@@ -21,6 +21,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2019 Peter Tribble.
#
#
@@ -31,32 +32,6 @@
<include global_zone_only_component>
set name=pkg.fmri \
value=pkg:/system/kernel/dynamic-reconfiguration/sun-fire-15000@$(PKGVERS)
-set name=pkg.description \
- value="Dynamic Reconfiguration Modules for Sun Fire 15000"
-set name=pkg.summary \
- value="Dynamic Reconfiguration Modules for Sun Fire 15000"
-set name=info.classification \
- value="org.opensolaris.category.2008:System/Enterprise Management"
+set name=pkg.obsolete value=true
+set name=org.opensolaris.noincorp value=true
set name=variant.arch value=sparc
-dir path=platform group=sys
-dir path=platform/SUNW,Sun-Fire-15000 group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel/drv group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64) group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel/misc group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel/misc/$(ARCH64) group=sys
-file path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64)/dr group=sys
-file path=platform/SUNW,Sun-Fire-15000/kernel/drv/dr.conf group=sys
-file path=platform/SUNW,Sun-Fire-15000/kernel/misc/$(ARCH64)/drmach group=sys \
- mode=0755
-file path=platform/SUNW,Sun-Fire-15000/kernel/misc/$(ARCH64)/fcgp2 group=sys \
- mode=0755
-file path=platform/SUNW,Sun-Fire-15000/kernel/misc/$(ARCH64)/gptwo_pci \
- group=sys mode=0755
-file path=platform/SUNW,Sun-Fire-15000/kernel/misc/$(ARCH64)/sc_gptwocfg \
- group=sys mode=0755
-legacy pkg=SUNWdrcr.u arch=$(ARCH).sun4u \
- desc="Dynamic Reconfiguration Modules for Sun Fire 15000" \
- name="Dynamic Reconfiguration Modules for Sun Fire 15000"
-license cr_Sun license=cr_Sun
-license lic_CDDL license=lic_CDDL
diff --git a/usr/src/pkg/manifests/system-kernel-platform.mf b/usr/src/pkg/manifests/system-kernel-platform.mf
index ade33deeb3..57fad265fe 100644
--- a/usr/src/pkg/manifests/system-kernel-platform.mf
+++ b/usr/src/pkg/manifests/system-kernel-platform.mf
@@ -141,21 +141,6 @@ $(sparc_ONLY)dir path=platform/SUNW,Sun-Blade-2500/kernel/misc group=sys
$(sparc_ONLY)dir path=platform/SUNW,Sun-Blade-2500/kernel/misc/$(ARCH64) \
group=sys
$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000 group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel/$(ARCH64) group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel/cpu group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel/cpu/$(ARCH64) \
- group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel/crypto group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel/crypto/$(ARCH64) \
- group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel/drv group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64) \
- group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel/misc group=sys
-$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-15000/kernel/misc/$(ARCH64) \
- group=sys
$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-280R group=sys
$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-280R/kernel group=sys
$(sparc_ONLY)dir path=platform/SUNW,Sun-Fire-280R/kernel/crypto group=sys
@@ -352,7 +337,6 @@ $(sparc_ONLY)driver name=adm1031 alias=i2c-adm1031
$(i386_ONLY)driver name=amd_iommu perms="* 0644 root sys" \
alias=pci1002,5a23 \
alias=pci1022,11ff
-$(sparc_ONLY)driver name=axq alias=SUNW,axq
$(i386_ONLY)driver name=balloon perms="* 0444 root sys"
$(sparc_ONLY)driver name=bbc_beep alias=SUNW,bbc-beep
$(sparc_ONLY)driver name=central
@@ -380,7 +364,6 @@ $(sparc_ONLY)driver name=db21554 \
alias=pci108e,6722 \
alias=pciclass,060940 \
alias=pciclass,060980
-$(sparc_ONLY)driver name=dman perms="* 0600 root sys"
$(i386_ONLY)driver name=domcaps perms="* 0444 root sys"
$(sparc_ONLY)driver name=dr
$(sparc_ONLY)driver name=ebus class=ebus \
@@ -410,7 +393,6 @@ $(sparc_ONLY)driver name=hpc3130 perms="* 0644 root sys" \
alias=i2c-hpc3130
$(sparc_ONLY)driver name=i2bsc alias=SUNW,i2bsc
$(sparc_ONLY)driver name=ics951601 alias=i2c-ics951601
-$(sparc_ONLY)driver name=iosram
$(i386_ONLY)driver name=isa alias=pciclass,060100 class=sysbus
$(sparc_ONLY)driver name=isadma
$(sparc_ONLY)driver name=jbusppm alias=jbus-ppm
@@ -487,7 +469,6 @@ $(sparc_ONLY)driver name=sbbc alias=pci108e,c416
$(sparc_ONLY)driver name=sbus class=sbus
$(sparc_ONLY)driver name=sbusmem
$(sparc_ONLY)driver name=scfd alias=FJSV,scfc
-$(sparc_ONLY)driver name=schpc
$(sparc_ONLY)driver name=schppm alias=gp2-ppm
$(sparc_ONLY)driver name=seeprom \
alias=i2c-at24c64 \
@@ -645,35 +626,6 @@ $(sparc_ONLY)file path=platform/SUNW,Sun-Blade-2500/kernel/drv/ppm.conf \
$(sparc_ONLY)file \
path=platform/SUNW,Sun-Blade-2500/kernel/misc/$(ARCH64)/platmod group=sys \
mode=0755
-$(sparc_ONLY)file path=platform/SUNW,Sun-Fire-15000/kernel/$(ARCH64)/unix \
- group=sys mode=0755
-$(sparc_ONLY)file \
- path=platform/SUNW,Sun-Fire-15000/kernel/cpu/$(ARCH64)/SUNW,UltraSPARC-III \
- group=sys mode=0755
-$(sparc_ONLY)file \
- path=platform/SUNW,Sun-Fire-15000/kernel/cpu/$(ARCH64)/SUNW,UltraSPARC-III+ \
- group=sys mode=0755
-$(sparc_ONLY)file path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64)/axq \
- group=sys
-$(sparc_ONLY)file path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64)/dman \
- group=sys
-$(sparc_ONLY)file \
- path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64)/iosram group=sys
-$(sparc_ONLY)file path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64)/schpc \
- group=sys
-$(sparc_ONLY)file path=platform/SUNW,Sun-Fire-15000/kernel/drv/dman.conf \
- group=sys
-$(sparc_ONLY)file path=platform/SUNW,Sun-Fire-15000/kernel/drv/schpc.conf \
- group=sys
-$(sparc_ONLY)file \
- path=platform/SUNW,Sun-Fire-15000/kernel/misc/$(ARCH64)/mboxsc group=sys \
- mode=0755
-$(sparc_ONLY)file \
- path=platform/SUNW,Sun-Fire-15000/kernel/misc/$(ARCH64)/platmod group=sys \
- mode=0755
-$(sparc_ONLY)file \
- path=platform/SUNW,Sun-Fire-15000/kernel/misc/$(ARCH64)/scosmb group=sys \
- mode=0755
$(sparc_ONLY)file \
path=platform/SUNW,Sun-Fire-280R/kernel/drv/$(ARCH64)/pcf8574 group=sys
$(sparc_ONLY)file \
@@ -1003,8 +955,6 @@ $(sparc_ONLY)file path=platform/sun4u/kernel/tod/$(ARCH64)/todopl group=sys \
mode=0755
$(sparc_ONLY)file path=platform/sun4u/kernel/tod/$(ARCH64)/todsg group=sys \
mode=0755
-$(sparc_ONLY)file path=platform/sun4u/kernel/tod/$(ARCH64)/todstarcat \
- group=sys mode=0755
$(sparc_ONLY)file path=platform/sun4v/bootlst group=sys reboot-needed=true
$(sparc_ONLY)file path=platform/sun4v/kernel/$(ARCH64)/genunix group=sys \
mode=0755
@@ -1067,7 +1017,6 @@ $(sparc_ONLY)file path=usr/share/man/man7d/oplpanel.7d
$(sparc_ONLY)file path=usr/share/man/man7d/pcicmu.7d
$(sparc_ONLY)file path=usr/share/man/man7d/pcipsy.7d
$(sparc_ONLY)file path=usr/share/man/man7d/pcisch.7d
-$(sparc_ONLY)file path=usr/share/man/man7d/schpc.7d
$(sparc_ONLY)file path=usr/share/man/man7d/smbus.7d
$(sparc_ONLY)file path=usr/share/man/man7d/su.7d
$(sparc_ONLY)file path=usr/share/man/man7d/todopl.7d
@@ -1150,15 +1099,6 @@ $(sparc_ONLY)link \
$(sparc_ONLY)link \
path=platform/SUNW,Sun-Blade-2500/kernel/crypto/$(ARCH64)/aes \
target=../../../../sun4u-us3/kernel/crypto/$(ARCH64)/aes
-$(sparc_ONLY)link \
- path=platform/SUNW,Sun-Fire-15000/kernel/cpu/$(ARCH64)/SUNW,UltraSPARC-IV \
- target=SUNW,UltraSPARC-III+
-$(sparc_ONLY)link \
- path=platform/SUNW,Sun-Fire-15000/kernel/cpu/$(ARCH64)/SUNW,UltraSPARC-IV+ \
- target=SUNW,UltraSPARC-III+
-$(sparc_ONLY)link \
- path=platform/SUNW,Sun-Fire-15000/kernel/crypto/$(ARCH64)/aes \
- target=../../../../sun4u-us3/kernel/crypto/$(ARCH64)/aes
$(sparc_ONLY)link path=platform/SUNW,Sun-Fire-280R/kernel/crypto/$(ARCH64)/aes \
target=../../../../sun4u-us3/kernel/crypto/$(ARCH64)/aes
$(sparc_ONLY)link path=platform/SUNW,Sun-Fire-480R/kernel/crypto/$(ARCH64)/aes \
diff --git a/usr/src/pkg/manifests/system-library-platform.mf b/usr/src/pkg/manifests/system-library-platform.mf
index a68cd5d59f..e68878430c 100644
--- a/usr/src/pkg/manifests/system-library-platform.mf
+++ b/usr/src/pkg/manifests/system-library-platform.mf
@@ -77,8 +77,6 @@ $(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Blade-T6300/lib
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Blade-T6320 group=sys
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Blade-T6320/lib
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire group=sys
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000 group=sys
-$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-15000/lib
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-280R group=sys
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-280R/lib
$(sparc_ONLY)dir path=usr/platform/SUNW,Sun-Fire-480R group=sys
@@ -159,8 +157,6 @@ $(sparc_ONLY)file \
$(sparc_ONLY)file path=usr/platform/SUNW,SPARC-Enterprise/lib/cfgadm/scsi.so.1
$(sparc_ONLY)file \
path=usr/platform/SUNW,SPARC-Enterprise/lib/libprtdiag_psr.so.1
-$(sparc_ONLY)file \
- path=usr/platform/SUNW,Sun-Fire-15000/lib/libprtdiag_psr.so.1
$(sparc_ONLY)file path=usr/platform/SUNW,Sun-Fire-280R/lib/libprtdiag_psr.so.1
$(sparc_ONLY)file path=usr/platform/SUNW,Sun-Fire-480R/lib/libprtdiag_psr.so.1
$(sparc_ONLY)file path=usr/platform/SUNW,Sun-Fire-880/lib/libprtdiag_psr.so.1
@@ -355,12 +351,6 @@ $(sparc_ONLY)link path=usr/platform/SUNW,Sun-Blade-T6320/lib/libpcp.so.1 \
$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Blade-T6320/sbin \
target=../sun4v/sbin
$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Blade-T6340 target=SUNW,T5140
-$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Fire-15000/lib/cfgadm \
- target=../../sun4u/lib/cfgadm
-$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Fire-15000/lib/fs \
- target=../../sun4u/lib/fs
-$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Fire-15000/sbin \
- target=../sun4u/sbin
$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Fire-280R/lib/cfgadm \
target=../../sun4u/lib/cfgadm
$(sparc_ONLY)link path=usr/platform/SUNW,Sun-Fire-280R/lib/fs \
diff --git a/usr/src/pkg/manifests/system-network-console.mf b/usr/src/pkg/manifests/system-network-console.mf
index ae675b5ffb..87f4ec95cb 100644
--- a/usr/src/pkg/manifests/system-network-console.mf
+++ b/usr/src/pkg/manifests/system-network-console.mf
@@ -31,39 +31,6 @@
#
<include global_zone_only_component>
set name=pkg.fmri value=pkg:/system/network-console@$(PKGVERS)
-set name=pkg.description value="Network Console"
-set name=pkg.summary value="Network Console"
-set name=info.classification value=org.opensolaris.category.2008:System/Core
+set name=pkg.obsolete value=true
+set name=org.opensolaris.noincorp value=true
set name=variant.arch value=sparc
-dir path=lib
-dir path=lib/svc
-dir path=lib/svc/manifest group=sys
-dir path=lib/svc/manifest/system group=sys
-dir path=lib/svc/method
-dir path=platform group=sys
-dir path=platform/SUNW,Sun-Fire-15000 group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel/drv group=sys
-dir path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64) group=sys
-dir path=platform/SUNW,Sun-Fire-15000/lib
-dir path=usr/share/man
-dir path=usr/share/man/man1m
-dir path=usr/share/man/man7d
-driver name=cvc perms="* 0600 root sys"
-driver name=cvcredir perms="* 0600 root sys"
-file path=lib/svc/manifest/system/cvc.xml group=sys mode=0444
-file path=lib/svc/method/svc-cvcd mode=0555
-file path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64)/cvc group=sys
-file path=platform/SUNW,Sun-Fire-15000/kernel/drv/$(ARCH64)/cvcredir group=sys
-file path=platform/SUNW,Sun-Fire-15000/kernel/drv/cvc.conf group=sys
-file path=platform/SUNW,Sun-Fire-15000/kernel/drv/cvcredir.conf group=sys
-file path=platform/SUNW,Sun-Fire-15000/lib/cvcd group=sys mode=0755
-file path=usr/share/man/man1m/cvcd.1m
-file path=usr/share/man/man7d/cvc.7d
-file path=usr/share/man/man7d/cvcredir.7d
-legacy pkg=SUNWcvc.u arch=$(ARCH).sun4u desc="Network Console" \
- name="Network Console"
-legacy pkg=SUNWcvcr.u arch=$(ARCH).sun4u desc="Network Console daemon" \
- name="Network Console daemon"
-license cr_Sun license=cr_Sun
-license lic_CDDL license=lic_CDDL
diff --git a/usr/src/psm/promif/ieee1275/sun4u/Makefile.files b/usr/src/psm/promif/ieee1275/sun4u/Makefile.files
index ff9ac4f72f..5fa8bbe84e 100644
--- a/usr/src/psm/promif/ieee1275/sun4u/Makefile.files
+++ b/usr/src/psm/promif/ieee1275/sun4u/Makefile.files
@@ -25,7 +25,7 @@
#
# psm/promif/ieee1275/sun4u/Makefile.files
#
-# This Makefile defines all the promif file modules for the
+# This Makefile defines all the promif file modules for the
# directory psm/promif/ieee1275/sun4u.
#
@@ -53,7 +53,6 @@ CORE_OBJS += \
prom_serengeti.o \
prom_set_traptable.o \
prom_sparc.o \
- prom_starcat.o \
prom_sunfire.o \
prom_tlb.o \
prom_vercheck.o \
diff --git a/usr/src/psm/promif/ieee1275/sun4u/prom_starcat.c b/usr/src/psm/promif/ieee1275/sun4u/prom_starcat.c
deleted file mode 100644
index bd77b7c8f3..0000000000
--- a/usr/src/psm/promif/ieee1275/sun4u/prom_starcat.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 2000 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/promif.h>
-#include <sys/promimpl.h>
-
-/*
- * This file contains the implementations of all Starcat-specific promif
- * routines. Refer to FWARC case 2000/420 for the definitions of the
- * platform-specific interfaces provided by Starcat OBP.
- */
-
-static char *switch_tunnel_cmd = "SUNW,Starcat,switch-tunnel";
-static char *iosram_read_cmd = "SUNW,Starcat,iosram-read";
-static char *iosram_write_cmd = "SUNW,Starcat,iosram-write";
-
-/*
- * Given the portid of the IOB to which the tunnel should be moved and the type
- * of move that should be performed, ask OBP to switch the IOSRAM tunnel from
- * its current host IOB to a new location. If the move type is 0, OBP will
- * coordinate the change with SMS and will copy data from the current location
- * to the new location. If the move type is 1, OBP will simply mark the new
- * location valid and start using it, without doing any data copying and without
- * communicating with SMS. Return 0 on success, non-zero on failure.
- */
-int
-prom_starcat_switch_tunnel(uint_t portid, uint_t msgtype)
-{
- static uint8_t warned = 0;
- cell_t ci[6];
- int rv;
-
- /*
- * Make sure we have the necessary support in OBP.
- */
- if (prom_test(switch_tunnel_cmd) == 0) {
- ci[0] = p1275_ptr2cell(switch_tunnel_cmd); /* name */
- } else {
- if (!warned) {
- warned = 1;
- prom_printf(
- "Warning: No prom support for switch-tunnel!\n");
- }
- return (-1);
- }
-
- /*
- * Set up the arguments and call into OBP.
- */
- ci[1] = (cell_t)2; /* #argument cells */
- ci[2] = (cell_t)1; /* #result cells */
- ci[3] = p1275_uint2cell(portid);
- ci[4] = p1275_uint2cell(msgtype);
-
- promif_preprom();
- rv = p1275_cif_handler(&ci);
- promif_postprom();
-
- /*
- * p1275_cif_handler will return 0 on success, non-zero on failure. If
- * it fails, the return cell from OBP is meaningless, because the OBP
- * client interface probably wasn't even invoked. OBP will return 0 on
- * failure and non-zero on success for this interface.
- */
- if (rv != 0) {
- return (rv);
- } else if (p1275_cell2int(ci[5]) == 0) {
- return (-1);
- } else {
- return (0);
- }
-}
-
-/*
- * Request that OBP read 'len' bytes, starting at 'offset' in the IOSRAM chunk
- * associated with 'key', into the memory indicated by 'buf'. Although there is
- * a driver that provides this functionality, there are certain cases where the
- * OS requires access to IOSRAM before the driver is loaded. Return 0 on
- * success, non-zero on failure.
- */
-int
-prom_starcat_iosram_read(uint32_t key, uint32_t offset, uint32_t len,
- caddr_t buf)
-{
- static uint8_t warned = 0;
- cell_t ci[8];
- int rv;
-
- /*
- * Make sure we have the necessary support in OBP.
- */
- if (prom_test(iosram_read_cmd) == 0) {
- ci[0] = p1275_ptr2cell(iosram_read_cmd); /* name */
- } else {
- if (!warned) {
- warned = 1;
- prom_printf(
- "Warning: No prom support for iosram-read!\n");
- }
- return (-1);
- }
-
- /*
- * Set up the arguments and call into OBP. Note that the argument order
- * needs to be reversed to accomodate OBP. The order must remain as it
- * is in the function prototype to maintain intercompatibility with the
- * IOSRAM driver's equivalent routine.
- */
- ci[1] = (cell_t)4; /* #argument cells */
- ci[2] = (cell_t)1; /* #result cells */
- ci[3] = p1275_ptr2cell(buf);
- ci[4] = p1275_uint2cell(len);
- ci[5] = p1275_uint2cell(offset);
- ci[6] = p1275_uint2cell(key);
-
- promif_preprom();
- rv = p1275_cif_handler(&ci);
- promif_postprom();
-
- /*
- * p1275_cif_handler will return 0 on success, non-zero on failure. If
- * it fails, the return cell from OBP is meaningless, because the OBP
- * client interface probably wasn't even invoked. OBP will return 0 on
- * success and non-zero on failure for this interface.
- */
- if (rv != 0) {
- return (rv);
- } else if (p1275_cell2int(ci[7]) == 0) {
- return (0);
- } else {
- return (-1);
- }
-}
-
-/*
- * Request that OBP write 'len' bytes from the memory indicated by 'buf' into
- * the IOSRAM chunk associated with 'key', starting at 'offset'. Although there
- * is a driver that provides this functionality, there are certain cases where
- * the OS requires access to IOSRAM before the driver is loaded. Return 0 on
- * success, non-zero on failure.
- */
-int
-prom_starcat_iosram_write(uint32_t key, uint32_t offset, uint32_t len,
- caddr_t buf)
-{
- static uint8_t warned = 0;
- cell_t ci[8];
- int rv;
-
- /*
- * Make sure we have the necessary support in OBP.
- */
- if (prom_test(iosram_write_cmd) == 0) {
- ci[0] = p1275_ptr2cell(iosram_write_cmd); /* name */
- } else {
- if (!warned) {
- warned = 1;
- prom_printf(
- "Warning: No prom support for iosram-write!\n");
- }
- return (-1);
- }
-
- /*
- * Set up the arguments and call into OBP. Note that the argument order
- * needs to be reversed to accomodate OBP. The order must remain as it
- * is in the function prototype to maintain intercompatibility with the
- * IOSRAM driver's equivalent routine.
- */
- ci[1] = (cell_t)4; /* #argument cells */
- ci[2] = (cell_t)1; /* #result cells */
- ci[3] = p1275_ptr2cell(buf);
- ci[4] = p1275_uint2cell(len);
- ci[5] = p1275_uint2cell(offset);
- ci[6] = p1275_uint2cell(key);
-
- promif_preprom();
- rv = p1275_cif_handler(&ci);
- promif_postprom();
-
- /*
- * p1275_cif_handler will return 0 on success, non-zero on failure. If
- * it fails, the return cell from OBP is meaningless, because the OBP
- * client interface probably wasn't even invoked. OBP will return 0 on
- * success and non-zero on failure for this interface.
- */
- if (rv != 0) {
- return (rv);
- } else if (p1275_cell2int(ci[7]) == 0) {
- return (0);
- } else {
- return (-1);
- }
-}
diff --git a/usr/src/psm/stand/boot/sparcv9/sun4u/Makefile b/usr/src/psm/stand/boot/sparcv9/sun4u/Makefile
index cdd5a93b4b..fffd4a6789 100644
--- a/usr/src/psm/stand/boot/sparcv9/sun4u/Makefile
+++ b/usr/src/psm/stand/boot/sparcv9/sun4u/Makefile
@@ -49,7 +49,6 @@ PLATLINKS += SUNW,Sun-Fire-V240
PLATLINKS += SUNW,Sun-Fire-V250
PLATLINKS += SUNW,Sun-Fire-V440
PLATLINKS += SUNW,Sun-Fire-280R
-PLATLINKS += SUNW,Sun-Fire-15000
PLATLINKS += SUNW,Sun-Fire-880
PLATLINKS += SUNW,Sun-Fire-480R
PLATLINKS += SUNW,Sun-Fire-V890
@@ -86,7 +85,7 @@ FRC:
.KEEP_STATE:
-all:
+all:
install: all $(LINKED_DIRS) $(LINKED_LIB_DIRS) $(LINKED_LIB_FS_DIRS)
diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/sun4u/Makefile b/usr/src/psm/stand/bootblks/ufs/sparc/sun4u/Makefile
index 7fb47eeffc..058b6367d0 100644
--- a/usr/src/psm/stand/bootblks/ufs/sparc/sun4u/Makefile
+++ b/usr/src/psm/stand/bootblks/ufs/sparc/sun4u/Makefile
@@ -50,7 +50,6 @@ PLATLINKS += SUNW,Sun-Fire-V240
PLATLINKS += SUNW,Sun-Fire-V250
PLATLINKS += SUNW,Sun-Fire-V440
PLATLINKS += SUNW,Sun-Fire-280R
-PLATLINKS += SUNW,Sun-Fire-15000
PLATLINKS += SUNW,Sun-Fire-880
PLATLINKS += SUNW,Sun-Fire-480R
PLATLINKS += SUNW,Sun-Fire-V890
diff --git a/usr/src/tools/chk4ubin/chk4ubin.c b/usr/src/tools/chk4ubin/chk4ubin.c
index aa2e38d6bc..51d372939a 100644
--- a/usr/src/tools/chk4ubin/chk4ubin.c
+++ b/usr/src/tools/chk4ubin/chk4ubin.c
@@ -99,7 +99,6 @@ static uint_t pagemask = 0x1fff;
static char *sun4u_bootables[] = {
"platform/sun4u/kernel/sparcv9/unix",
- "platform/SUNW,Sun-Fire-15000/kernel/sparcv9/unix",
"platform/sun4u/cprboot",
"platform/sun4u/bootlst"
};
@@ -126,7 +125,7 @@ static char *detailed_error_msg =
static int
chk4ubin(char *root, char *binary)
{
- int fd;
+ int fd;
Elf *elf;
Elf_Scn *symscn;
Elf_Scn *strscn;
diff --git a/usr/src/uts/sun4/sys/platform_module.h b/usr/src/uts/sun4/sys/platform_module.h
index 1475816e52..ad1c95ff0d 100644
--- a/usr/src/uts/sun4/sys/platform_module.h
+++ b/usr/src/uts/sun4/sys/platform_module.h
@@ -23,11 +23,13 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright 2019 Peter Tribble.
+ */
+
#ifndef _SYS_PLATFORM_MODULE_H
#define _SYS_PLATFORM_MODULE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/async.h>
#include <sys/sunddi.h>
#include <sys/memlist_plat.h>
@@ -109,7 +111,6 @@ extern int plat_blacklist(int cmd, const char *scheme, nvlist_t *fmri,
const char *class);
extern caddr_t plat_startup_memlist(caddr_t alloc_base);
-extern int starcat_dr_name(char *name);
#pragma weak plat_setprop_enter
#pragma weak plat_setprop_exit
diff --git a/usr/src/uts/sun4u/Makefile.files b/usr/src/uts/sun4u/Makefile.files
index a2b45242cb..5e6e640a1f 100644
--- a/usr/src/uts/sun4u/Makefile.files
+++ b/usr/src/uts/sun4u/Makefile.files
@@ -89,7 +89,7 @@ PX_OBJS += px_asm_4u.o px_err.o px_hlib.o px_lib4u.o px_tools_4u.o
PCI_COMMON_OBJS += pci.o pci_util.o pci_dma.o pci_devctl.o \
pci_fdvma.o pci_iommu.o pci_sc.o pci_debug.o \
pci_cb.o pci_ib.o pci_ecc.o pci_pbm.o pci_intr.o \
- pci_space.o pci_counters.o pci_axq.o \
+ pci_space.o pci_counters.o \
pci_fm.o pci_reloc.o pci_tools.o pci_asm.o
RMCLOMV_OBJS += rmclomv.o
@@ -97,7 +97,7 @@ PSYCHO_PCI_OBJS += $(PCI_COMMON_OBJS) pcipsy.o
SCHIZO_PCI_OBJS += $(PCI_COMMON_OBJS) pcisch_asm.o pcisch.o pcix.o
SIMBA_PCI_OBJS += simba.o
DB21554_OBJS += db21554.o
-US_OBJS += cpudrv.o cpudrv_mach.o
+US_OBJS += cpudrv.o cpudrv_mach.o
POWER_OBJS += power.o
EPIC_OBJS += epic.o
GRBEEP_OBJS += grbeep.o
@@ -136,7 +136,7 @@ I2BSC_OBJS += i2bsc.o
GPTWOCFG_OBJS += gptwocfg.o
GPTWO_CPU_OBJS += gptwo_cpu.o
-JBUSPPM_OBJS += jbusppm.o
+JBUSPPM_OBJS += jbusppm.o
RMC_COMM_OBJS += rmc_comm.o rmc_comm_crctab.o rmc_comm_dp.o rmc_comm_drvintf.o
RMCADM_OBJS += rmcadm.o
MEM_CACHE_OBJS += mem_cache.o panther_asm.o
@@ -161,7 +161,6 @@ SHA1_OBJS += sha1_asm.o
TODMOSTEK_OBJS += todmostek.o
TODDS1287_OBJS += todds1287.o
TODDS1337_OBJS += todds1337.o
-TODSTARCAT_OBJS += todstarcat.o
TODBLADE_OBJS += todblade.o
TODM5819_OBJS += todm5819.o
TODM5819P_RMC_OBJS += todm5819p_rmc.o
@@ -198,10 +197,10 @@ OPL_PCBE_OBJS = opl_pcbe.o
# cpu modules
#
CPU_OBJ += $(OBJS_DIR)/mach_cpu_module.o
-SPITFIRE_OBJS = spitfire.o spitfire_asm.o spitfire_copy.o spitfire_kdi.o common_asm.o
+SPITFIRE_OBJS = spitfire.o spitfire_asm.o spitfire_copy.o spitfire_kdi.o common_asm.o
HUMMINGBIRD_OBJS= $(SPITFIRE_OBJS)
US3_CMN_OBJS = us3_common.o us3_common_mmu.o us3_common_asm.o us3_kdi.o cheetah_copy.o common_asm.o
-CHEETAH_OBJS = $(US3_CMN_OBJS) us3_cheetah.o us3_cheetah_asm.o
+CHEETAH_OBJS = $(US3_CMN_OBJS) us3_cheetah.o us3_cheetah_asm.o
CHEETAHPLUS_OBJS= $(US3_CMN_OBJS) us3_cheetahplus.o us3_cheetahplus_asm.o
JALAPENO_OBJS = $(US3_CMN_OBJS) us3_jalapeno.o us3_jalapeno_asm.o
OLYMPUS_OBJS = opl_olympus.o opl_olympus_asm.o opl_olympus_copy.o \
diff --git a/usr/src/uts/sun4u/Makefile.sun4u b/usr/src/uts/sun4u/Makefile.sun4u
index f5e29d2a13..98b8ef8832 100644
--- a/usr/src/uts/sun4u/Makefile.sun4u
+++ b/usr/src/uts/sun4u/Makefile.sun4u
@@ -104,13 +104,13 @@ MODSTUBS_DIR = $(UNIX_DIR)
DSF_DIR = $(UTSBASE)/$(PLATFORM)/genassym
LINTS_DIR = $(OBJS_DIR)
LINT_LIB_DIR = $(UTSBASE)/$(PLATFORM)/lint-libs/$(OBJS_DIR)
-
+
DTRACESTUBS_O = $(OBJS_DIR)/dtracestubs.o
DTRACESTUBS = $(OBJS_DIR)/libdtracestubs.so
UNIX_O = $(UNIX_DIR)/$(OBJS_DIR)/unix.o
MODSTUBS_O = $(MODSTUBS_DIR)/$(OBJS_DIR)/modstubs.o
-GENLIB = $(GENLIB_DIR)/$(OBJS_DIR)/libgenunix.so
+GENLIB = $(GENLIB_DIR)/$(OBJS_DIR)/libgenunix.so
LINT_LIB = $(LINT_LIB_DIR)/llib-lunix.ln
GEN_LINT_LIB = $(LINT_LIB_DIR)/llib-lgenunix.ln
@@ -158,33 +158,32 @@ include $(UTSBASE)/common/Makefile.files
include $(UTSBASE)/Makefile.uts
# These come after Makefile.uts.
-IMPLEMENTATIONS = tazmo
-IMPLEMENTATIONS += javelin
-IMPLEMENTATIONS += darwin
-IMPLEMENTATIONS += quasar
-IMPLEMENTATIONS += grover
-IMPLEMENTATIONS += enchilada
-IMPLEMENTATIONS += taco
-IMPLEMENTATIONS += mpxu
-IMPLEMENTATIONS += excalibur
-IMPLEMENTATIONS += montecarlo
-IMPLEMENTATIONS += serengeti
-IMPLEMENTATIONS += littleneck
-IMPLEMENTATIONS += starcat
-IMPLEMENTATIONS += daktari
-IMPLEMENTATIONS += cherrystone
-IMPLEMENTATIONS += fjlite
-IMPLEMENTATIONS += snowbird
-IMPLEMENTATIONS += schumacher
-IMPLEMENTATIONS += blade
-IMPLEMENTATIONS += boston
-IMPLEMENTATIONS += seattle
-IMPLEMENTATIONS += chicago
-IMPLEMENTATIONS += sunfire
-IMPLEMENTATIONS += lw8
-IMPLEMENTATIONS += makaha
-IMPLEMENTATIONS += opl
-IMPLEMENTATIONS += lw2plus
+IMPLEMENTATIONS = tazmo
+IMPLEMENTATIONS += javelin
+IMPLEMENTATIONS += darwin
+IMPLEMENTATIONS += quasar
+IMPLEMENTATIONS += grover
+IMPLEMENTATIONS += enchilada
+IMPLEMENTATIONS += taco
+IMPLEMENTATIONS += mpxu
+IMPLEMENTATIONS += excalibur
+IMPLEMENTATIONS += montecarlo
+IMPLEMENTATIONS += serengeti
+IMPLEMENTATIONS += littleneck
+IMPLEMENTATIONS += daktari
+IMPLEMENTATIONS += cherrystone
+IMPLEMENTATIONS += fjlite
+IMPLEMENTATIONS += snowbird
+IMPLEMENTATIONS += schumacher
+IMPLEMENTATIONS += blade
+IMPLEMENTATIONS += boston
+IMPLEMENTATIONS += seattle
+IMPLEMENTATIONS += chicago
+IMPLEMENTATIONS += sunfire
+IMPLEMENTATIONS += lw8
+IMPLEMENTATIONS += makaha
+IMPLEMENTATIONS += opl
+IMPLEMENTATIONS += lw2plus
#
# machine specific optimization, override default in Makefile.master
@@ -239,7 +238,7 @@ MODSTUBS = $(UTSBASE)/sparc/ml/modstubs.s
GENCONST_SRC = $(UTSBASE)/sun4/ml/genconst.c
OFFSETS = $(UTSBASE)/sun4/ml/offsets.in
PLATFORM_OFFSETS = $(UTSBASE)/sun4u/ml/mach_offsets.in
-FDOFFSETS = $(UTSBASE)/sun/io/fd_offsets.in
+FDOFFSETS = $(UTSBASE)/sun/io/fd_offsets.in
#
# Define the actual specific platforms
@@ -272,7 +271,7 @@ DEBUG_DEFS_DBG64 = -DDEBUG
DEBUG_DEFS = $(DEBUG_DEFS_$(BUILD_TYPE))
DEBUG_COND_OBJ64 = $(POUND_SIGN)
-DEBUG_COND_DBG64 =
+DEBUG_COND_DBG64 =
IF_DEBUG_OBJ = $(DEBUG_COND_$(BUILD_TYPE))$(OBJS_DIR)/
$(IF_DEBUG_OBJ)trap.o := DEBUG_DEFS += -DTRAPDEBUG
@@ -286,7 +285,7 @@ IF_TRAPTRACE_OBJ = $(IF_DEBUG_OBJ)
$(IF_TRAPTRACE_OBJ)mach_locore.o := DEBUG_DEFS += -DTRAPTRACE
$(IF_TRAPTRACE_OBJ)mlsetup.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_TRAPTRACE_OBJ)syscall_trap.o := DEBUG_DEFS += -DTRAPTRACE
+$(IF_TRAPTRACE_OBJ)syscall_trap.o := DEBUG_DEFS += -DTRAPTRACE
$(IF_TRAPTRACE_OBJ)startup.o := DEBUG_DEFS += -DTRAPTRACE
$(IF_TRAPTRACE_OBJ)mach_startup.o := DEBUG_DEFS += -DTRAPTRACE
$(IF_TRAPTRACE_OBJ)mp_startup.o := DEBUG_DEFS += -DTRAPTRACE
@@ -314,7 +313,7 @@ $(IF_TRAPTRACE_OBJ)opl_olympus_asm.o := DEBUG_DEFS += -DTRAPTRACE
#$(IF_DEBUG_OBJ)lock_prim.o := DEBUG_DEFS += -DDISP_LOCK_STATS
#$(IF_DEBUG_OBJ)disp.o := DEBUG_DEFS += -DDISP_LOCK_STATS
-# Comment these out if you don't want dispatcher debugging
+# Comment these out if you don't want dispatcher debugging
#$(IF_DEBUG_OBJ)lock_prim.o := DEBUG_DEFS += -DDISP_DEBUG
@@ -392,7 +391,7 @@ DRV_KMODS += rmcadm
DRV_KMODS += rmclomv
DRV_KMODS += sf
DRV_KMODS += nxge
-DRV_KMODS += i2bsc
+DRV_KMODS += i2bsc
DRV_KMODS += mem_cache
#
@@ -459,9 +458,9 @@ CPU_KMODS += cheetah cheetahplus jalapeno serrano spitfire hummingbird
#
# sun4u 'TOD' Modules (/platform/.../kernel/tod):
#
-TOD_KMODS += todds1287 todds1337 todmostek
+TOD_KMODS += todds1287 todds1337 todmostek
TOD_KMODS += todm5819 todblade todbq4802 todsg todopl
-TOD_KMODS += todm5819p_rmc todstarcat
+TOD_KMODS += todm5819p_rmc
#
# Performance Counter BackEnd Modules (/usr/kernel/pcbe):
diff --git a/usr/src/uts/sun4u/io/gptwocfg.c b/usr/src/uts/sun4u/io/gptwocfg.c
index b48a491fa1..b00af4a99d 100644
--- a/usr/src/uts/sun4u/io/gptwocfg.c
+++ b/usr/src/uts/sun4u/io/gptwocfg.c
@@ -24,6 +24,10 @@
*/
/*
+ * Copyright 2019 Peter Tribble.
+ */
+
+/*
* Safari Configurator (gptwocfg)
*
*/
@@ -48,7 +52,6 @@
#include <sys/gp2cfg.h>
#include <sys/machsystm.h>
#include <sys/platform_module.h>
-#pragma weak starcat_dr_name
#ifdef DEBUG
int gptwocfg_debug = 0;
@@ -144,8 +147,7 @@ _fini(void)
}
int
-_info(modinfop)
-struct modinfo *modinfop;
+_info(struct modinfo *modinfop)
{
return (mod_info(&modlinkage, modinfop));
}
@@ -239,12 +241,6 @@ gptwocfg_configure(dev_info_t *ap, spcd_t *pcd, gptwo_aid_t id)
mutex_enter(&gptwo_config_list_lock);
config = gptwo_config_list;
while (config != NULL) {
- if (&starcat_dr_name) {
- if (starcat_dr_name(ddi_node_name(ap)) < 0) {
- config = config->gptwo_next;
- continue;
- }
- }
if (config->gptwo_portid == id) {
cmn_err(CE_WARN, "gptwocfg: gptwocfg_configure: "
"0x%x Port already configured\n", id);
@@ -556,13 +552,6 @@ gptwocfg_get_obp_created_nodes(dev_info_t *ap, uint_t id)
while (saf_dev != NULL) {
if (ddi_getprop(DDI_DEV_T_ANY, saf_dev, DDI_PROP_DONTPASS,
"portid", -1) == id) {
- if (&starcat_dr_name) {
- if (starcat_dr_name(ddi_node_name(saf_dev))
- < 0) {
- saf_dev = ddi_get_next_sibling(saf_dev);
- continue;
- }
- }
nodes++;
}
saf_dev = ddi_get_next_sibling(saf_dev);
@@ -580,13 +569,6 @@ gptwocfg_get_obp_created_nodes(dev_info_t *ap, uint_t id)
while ((saf_dev != NULL) && (i < nodes)) {
if (ddi_getprop(DDI_DEV_T_ANY, saf_dev, DDI_PROP_DONTPASS,
"portid", -1) == id) {
- if (&starcat_dr_name) {
- if (starcat_dr_name(ddi_node_name(saf_dev))
- < 0) {
- saf_dev = ddi_get_next_sibling(saf_dev);
- continue;
- }
- }
/*
* Branch rooted at this dip must have been
* held by the DR driver.
diff --git a/usr/src/uts/sun4u/io/pci/pci.c b/usr/src/uts/sun4u/io/pci/pci.c
index 0b50bd0c47..15cb498378 100644
--- a/usr/src/uts/sun4u/io/pci/pci.c
+++ b/usr/src/uts/sun4u/io/pci/pci.c
@@ -27,6 +27,10 @@
* PCI nexus driver interface
*/
+/*
+ * Copyright 2019 Peter Tribble.
+ */
+
#include <sys/types.h>
#include <sys/conf.h> /* nulldev */
#include <sys/stat.h> /* devctl */
@@ -123,7 +127,7 @@ static struct dev_ops pci_ops = {
extern struct mod_ops mod_driverops;
static struct modldrv modldrv = {
- &mod_driverops, /* Type of module - driver */
+ &mod_driverops, /* Type of module - driver */
"Sun4u Host to PCI nexus driver", /* Name of module. */
&pci_ops, /* driver ops */
};
@@ -471,15 +475,15 @@ pci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
/*
* bus map entry point:
*
- * if map request is for an rnumber
+ * if map request is for an rnumber
* get the corresponding regspec from device node
- * build a new regspec in our parent's format
+ * build a new regspec in our parent's format
* build a new map_req with the new regspec
* call up the tree to complete the mapping
*/
int
pci_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
- off_t off, off_t len, caddr_t *addrp)
+ off_t off, off_t len, caddr_t *addrp)
{
pci_t *pci_p = get_pci_soft_state(ddi_get_instance(dip));
struct regspec p_regspec;
@@ -538,14 +542,12 @@ pci_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
if (rval == DDI_SUCCESS) {
/*
* Set-up access functions for FM access error capable drivers.
- * The axq workaround prevents fault management support
*/
if (DDI_FM_ACC_ERR_CAP(pci_p->pci_fm_cap) &&
DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) &&
mp->map_handlep->ah_acc.devacc_attr_access !=
DDI_DEFAULT_ACC)
pci_fm_acc_setup(mp, rdip);
- pci_axq_setup(mp, pci_p->pci_pbm_p);
}
done:
@@ -567,7 +569,7 @@ done:
*/
int
pci_dma_setup(dev_info_t *dip, dev_info_t *rdip, ddi_dma_req_t *dmareq,
- ddi_dma_handle_t *handlep)
+ ddi_dma_handle_t *handlep)
{
pci_t *pci_p = get_pci_soft_state(ddi_get_instance(dip));
iommu_t *iommu_p = pci_p->pci_iommu_p;
@@ -633,7 +635,7 @@ freehandle:
*/
int
pci_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attrp,
- int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
+ int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
{
pci_t *pci_p = get_pci_soft_state(ddi_get_instance(dip));
ddi_dma_impl_t *mp;
@@ -690,8 +692,8 @@ pci_dma_freehdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handle)
*/
int
pci_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
- ddi_dma_handle_t handle, ddi_dma_req_t *dmareq,
- ddi_dma_cookie_t *cookiep, uint_t *ccountp)
+ ddi_dma_handle_t handle, ddi_dma_req_t *dmareq,
+ ddi_dma_cookie_t *cookiep, uint_t *ccountp)
{
pci_t *pci_p = get_pci_soft_state(ddi_get_instance(dip));
iommu_t *iommu_p = pci_p->pci_iommu_p;
@@ -817,8 +819,8 @@ pci_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handle)
*/
int
pci_dma_win(dev_info_t *dip, dev_info_t *rdip,
- ddi_dma_handle_t handle, uint_t win, off_t *offp,
- size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp)
+ ddi_dma_handle_t handle, uint_t win, off_t *offp,
+ size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp)
{
ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle;
DEBUG2(DBG_DMA_WIN, dip, "rdip=%s%d\n",
@@ -911,8 +913,8 @@ static char *pci_dmactl_str[] = {
*/
int
pci_dma_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handle,
- enum ddi_dma_ctlops cmd, off_t *offp, size_t *lenp, caddr_t *objp,
- uint_t cache_flags)
+ enum ddi_dma_ctlops cmd, off_t *offp, size_t *lenp, caddr_t *objp,
+ uint_t cache_flags)
{
ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle;
DEBUG3(DBG_DMA_CTL, dip, "%s: rdip=%s%d\n", pci_dmactl_str[cmd],
@@ -1205,7 +1207,7 @@ get_reg_set_size(dev_info_t *child, int rnumber)
*/
int
pci_ctlops(dev_info_t *dip, dev_info_t *rdip,
- ddi_ctl_enum_t op, void *arg, void *result)
+ ddi_ctl_enum_t op, void *arg, void *result)
{
pci_t *pci_p = get_pci_soft_state(ddi_get_instance(dip));
diff --git a/usr/src/uts/sun4u/io/pci/pci_axq.c b/usr/src/uts/sun4u/io/pci/pci_axq.c
deleted file mode 100644
index 54131c059b..0000000000
--- a/usr/src/uts/sun4u/io/pci/pci_axq.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * PCI nexus driver interface
- */
-#include <sys/types.h>
-#include <sys/conf.h> /* nulldev */
-#include <sys/stat.h> /* devctl */
-#include <sys/kmem.h>
-#include <sys/async.h> /* ecc_flt for pci_ecc.h */
-#include <sys/sunddi.h>
-#include <sys/sunndi.h>
-#include <sys/ontrap.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/ddi_subrdefs.h>
-#include <sys/epm.h>
-#include <sys/membar.h>
-#include <sys/modctl.h>
-#include <sys/hotplug/pci/pcihp.h>
-#include <sys/pci/pci_obj.h>
-
-/*LINTLIBRARY*/
-
-static uint8_t pci_axq_hack_get8(ddi_acc_impl_t *handle, uint8_t *addr);
-static uint16_t pci_axq_hack_get16(ddi_acc_impl_t *handle, uint16_t *addr);
-static uint32_t pci_axq_hack_get32(ddi_acc_impl_t *handle, uint32_t *addr);
-static uint64_t pci_axq_hack_get64(ddi_acc_impl_t *handle, uint64_t *addr);
-static void pci_axq_hack_put8(ddi_acc_impl_t *handle, uint8_t *addr,
- uint8_t data);
-static void pci_axq_hack_put16(ddi_acc_impl_t *handle, uint16_t *addr,
- uint16_t data);
-static void pci_axq_hack_put32(ddi_acc_impl_t *handle, uint32_t *addr,
- uint32_t data);
-static void pci_axq_hack_put64(ddi_acc_impl_t *handle, uint64_t *addr,
- uint64_t data);
-static void pci_axq_hack_rep_get8(ddi_acc_impl_t *handle,
- uint8_t *host_addr, uint8_t *dev_addr,
- size_t repcount, uint_t flags);
-static void pci_axq_hack_rep_get16(ddi_acc_impl_t *handle,
- uint16_t *host_addr, uint16_t *dev_addr,
- size_t repcount, uint_t flags);
-static void pci_axq_hack_rep_get32(ddi_acc_impl_t *handle,
- uint32_t *host_addr, uint32_t *dev_addr,
- size_t repcount, uint_t flags);
-static void pci_axq_hack_rep_get64(ddi_acc_impl_t *handle,
- uint64_t *host_addr, uint64_t *dev_addr,
- size_t repcount, uint_t flags);
-static void pci_axq_hack_rep_put8(ddi_acc_impl_t *handle,
- uint8_t *host_addr, uint8_t *dev_addr,
- size_t repcount, uint_t flags);
-static void pci_axq_hack_rep_put16(ddi_acc_impl_t *handle,
- uint16_t *host_addr, uint16_t *dev_addr,
- size_t repcount, uint_t flags);
-static void pci_axq_hack_rep_put32(ddi_acc_impl_t *handle,
- uint32_t *host_addr, uint32_t *dev_addr,
- size_t repcount, uint_t flags);
-static void pci_axq_hack_rep_put64(ddi_acc_impl_t *handle,
- uint64_t *host_addr, uint64_t *dev_addr,
- size_t repcount, uint_t flags);
-
-/*
- * On Sunfire 15k systems with AXQs less than 6.1
- * we have to use special PIO routines that limit
- * the number of outstanding PIOs. We setup the
- * handle with pointers to our special functions
- * after it has been succesfully mapped by our
- * parent.
- */
-
-void
-pci_axq_pio_limit(pbm_t *pbm_p)
-{
- pci_t *pci_p = pbm_p->pbm_pci_p;
- dev_info_t *dip = pci_p->pci_dip;
- int (*axq_pio_workaround)(dev_info_t *) = NULL;
-
- axq_pio_workaround =
- (int (*)(dev_info_t *)) modgetsymvalue(
- "starcat_axq_pio_workaround", 0);
-
- if (axq_pio_workaround) {
- pbm_p->pbm_pio_limit = (axq_pio_workaround)(dip);
- pbm_p->pbm_pio_counter = pbm_p->pbm_pio_limit;
- } else
- pbm_p->pbm_pio_limit = 0;
-}
-
-void
-pci_axq_setup(ddi_map_req_t *mp, pbm_t *pbm_p)
-{
- ddi_acc_hdl_t *hp;
- ddi_acc_impl_t *ap;
-
- if (mp->map_op != DDI_MO_MAP_LOCKED)
- return;
- if (!pbm_p->pbm_pio_limit)
- return;
-
- hp = (ddi_acc_hdl_t *)mp->map_handlep;
- ap = (ddi_acc_impl_t *)hp->ah_platform_private;
-
- ap->ahi_get8 = pci_axq_hack_get8;
- ap->ahi_get16 = pci_axq_hack_get16;
- ap->ahi_get32 = pci_axq_hack_get32;
- ap->ahi_get64 = pci_axq_hack_get64;
- ap->ahi_put8 = pci_axq_hack_put8;
- ap->ahi_put16 = pci_axq_hack_put16;
- ap->ahi_put32 = pci_axq_hack_put32;
- ap->ahi_put64 = pci_axq_hack_put64;
- ap->ahi_rep_get8 = pci_axq_hack_rep_get8;
- ap->ahi_rep_get16 = pci_axq_hack_rep_get16;
- ap->ahi_rep_get32 = pci_axq_hack_rep_get32;
- ap->ahi_rep_get64 = pci_axq_hack_rep_get64;
- ap->ahi_rep_put8 = pci_axq_hack_rep_put8;
- ap->ahi_rep_put16 = pci_axq_hack_rep_put16;
- ap->ahi_rep_put32 = pci_axq_hack_rep_put32;
- ap->ahi_rep_put64 = pci_axq_hack_rep_put64;
-
- hp->ah_bus_private = (void *)pbm_p;
-}
-
-/*
- * get/put routines for SunFire 15K systems that have AXQ versions
- * less than 6.1. These routines limit the number of outsanding
- * PIOs issues across a PCI Bus.
- */
-static uint8_t
-pci_axq_hack_get8(ddi_acc_impl_t *handle, uint8_t *addr)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint8_t data;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- data = i_ddi_get8(handle, addr);
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-
- return (data);
-}
-
-static uint16_t
-pci_axq_hack_get16(ddi_acc_impl_t *handle, uint16_t *addr)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint16_t data;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- data = i_ddi_swap_get16(handle, addr);
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-
- return (data);
-}
-
-static uint32_t
-pci_axq_hack_get32(ddi_acc_impl_t *handle, uint32_t *addr)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t data;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- data = i_ddi_swap_get32(handle, addr);
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-
- return (data);
-}
-
-static uint64_t
-pci_axq_hack_get64(ddi_acc_impl_t *handle, uint64_t *addr)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint64_t data;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- data = i_ddi_swap_get64(handle, addr);
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-
- return (data);
-}
-
-static void
-pci_axq_hack_put8(ddi_acc_impl_t *handle, uint8_t *addr, uint8_t data)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- i_ddi_put8(handle, addr, data);
- membar_sync();
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_put16(ddi_acc_impl_t *handle, uint16_t *addr, uint16_t data)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- i_ddi_swap_put16(handle, addr, data);
- membar_sync();
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_put32(ddi_acc_impl_t *handle, uint32_t *addr, uint32_t data)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- i_ddi_swap_put32(handle, addr, data);
- membar_sync();
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_put64(ddi_acc_impl_t *handle, uint64_t *addr, uint64_t data)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- i_ddi_swap_put64(handle, addr, data);
- membar_sync();
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_rep_get8(ddi_acc_impl_t *handle, uint8_t *host_addr,
- uint8_t *dev_addr, size_t repcount, uint_t flags)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- i_ddi_rep_get8(handle, host_addr, dev_addr, repcount, flags);
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_rep_get16(ddi_acc_impl_t *handle, uint16_t *host_addr,
- uint16_t *dev_addr, size_t repcount, uint_t flags)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- i_ddi_swap_rep_get16(handle, host_addr, dev_addr, repcount, flags);
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_rep_get32(ddi_acc_impl_t *handle, uint32_t *host_addr,
- uint32_t *dev_addr, size_t repcount, uint_t flags)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- i_ddi_swap_rep_get32(handle, host_addr, dev_addr, repcount, flags);
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_rep_get64(ddi_acc_impl_t *handle, uint64_t *host_addr,
- uint64_t *dev_addr, size_t repcount, uint_t flags)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- i_ddi_swap_rep_get64(handle, host_addr, dev_addr, repcount, flags);
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_rep_put8(ddi_acc_impl_t *handle, uint8_t *host_addr,
- uint8_t *dev_addr, size_t repcount, uint_t flags)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- while (repcount--) {
- i_ddi_put8(handle, dev_addr, *host_addr);
- membar_sync();
- if (flags == DDI_DEV_AUTOINCR)
- dev_addr++;
- host_addr++;
- }
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_rep_put16(ddi_acc_impl_t *handle, uint16_t *host_addr,
- uint16_t *dev_addr, size_t repcount, uint_t flags)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- while (repcount--) {
- i_ddi_put16(handle, dev_addr, *host_addr);
- membar_sync();
- if (flags == DDI_DEV_AUTOINCR)
- dev_addr++;
- host_addr++;
- }
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-
-static void
-pci_axq_hack_rep_put32(ddi_acc_impl_t *handle, uint32_t *host_addr,
- uint32_t *dev_addr, size_t repcount, uint_t flags)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- while (repcount--) {
- i_ddi_put32(handle, dev_addr, *host_addr);
- membar_sync();
- if (flags == DDI_DEV_AUTOINCR)
- dev_addr++;
- host_addr++;
- }
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
-static void
-pci_axq_hack_rep_put64(ddi_acc_impl_t *handle, uint64_t *host_addr,
- uint64_t *dev_addr, size_t repcount, uint_t flags)
-{
- pbm_t *pbm_p = (pbm_t *)handle->ahi_common.ah_bus_private;
- uint32_t spl;
-
- spl = ddi_enter_critical();
- PIO_LIMIT_ENTER(pbm_p);
- while (repcount--) {
- i_ddi_put64(handle, dev_addr, *host_addr);
- membar_sync();
- if (flags == DDI_DEV_AUTOINCR)
- dev_addr++;
- host_addr++;
- }
- PIO_LIMIT_EXIT(pbm_p);
- ddi_exit_critical(spl);
-}
diff --git a/usr/src/uts/sun4u/io/pci/pci_fm.c b/usr/src/uts/sun4u/io/pci/pci_fm.c
index 47c714562c..500e035607 100644
--- a/usr/src/uts/sun4u/io/pci/pci_fm.c
+++ b/usr/src/uts/sun4u/io/pci/pci_fm.c
@@ -23,7 +23,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2019 Peter Tribble.
+ */
#include <sys/types.h>
#include <sys/sunddi.h>
@@ -180,7 +182,7 @@ pci_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle)
if (derr.fme_status == DDI_FM_OK) {
if (pci_check_error(pci_p) != 0) {
(void) pci_pbm_err_handler(pci_p->pci_dip, &derr,
- (const void *)pci_p, PCI_BUS_EXIT_CALL);
+ (const void *)pci_p, PCI_BUS_EXIT_CALL);
}
}
mutex_exit(&pci_p->pci_common_p->pci_fm_mutex);
@@ -224,7 +226,7 @@ pci_err_callback(dev_info_t *dip, ddi_fm_error_t *derr,
if (pci_check_error(pci_p) != 0) {
int err = pci_pbm_err_handler(pci_p->pci_dip, derr,
- (const void *)pci_p, PCI_TRAP_CALL);
+ (const void *)pci_p, PCI_TRAP_CALL);
if (err == DDI_FM_FATAL)
fatal++;
else if (err == DDI_FM_NONFATAL)
@@ -258,10 +260,10 @@ pci_fm_create(pci_t *pci_p)
*/
if (pci_ecc_queue == NULL) {
pci_ecc_queue = errorq_create("pci_ecc_queue",
- (errorq_func_t)ecc_err_drain,
- (void *)pci_p->pci_ecc_p,
- ECC_MAX_ERRS, sizeof (ecc_errstate_t),
- PIL_2, ERRORQ_VITAL);
+ (errorq_func_t)ecc_err_drain,
+ (void *)pci_p->pci_ecc_p,
+ ECC_MAX_ERRS, sizeof (ecc_errstate_t),
+ PIL_2, ERRORQ_VITAL);
if (pci_ecc_queue == NULL)
panic("failed to create required system error queue");
}
@@ -273,20 +275,15 @@ pci_fm_create(pci_t *pci_p)
/*
* Initialize FMA support
- * The axq workaround prevents fault management of access errors
*/
- if (pci_p->pci_pbm_p->pbm_pio_limit == 0)
- pci_p->pci_fm_cap = DDI_FM_EREPORT_CAPABLE |
- DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE |
- DDI_FM_ERRCB_CAPABLE;
- else
- pci_p->pci_fm_cap = DDI_FM_EREPORT_CAPABLE |
- DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE;
+ pci_p->pci_fm_cap = DDI_FM_EREPORT_CAPABLE |
+ DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE |
+ DDI_FM_ERRCB_CAPABLE;
/*
* Call parent to get it's capablity
*/
ddi_fm_init(pci_p->pci_dip, &pci_p->pci_fm_cap,
- &pci_p->pci_fm_ibc);
+ &pci_p->pci_fm_ibc);
/*
* Need to be ereport and error handler cabable
*/
@@ -297,14 +294,13 @@ pci_fm_create(pci_t *pci_p)
*/
if (cmn_p->pci_common_refcnt == 0) {
mutex_init(&cmn_p->pci_fm_mutex, NULL, MUTEX_DRIVER,
- (void *)pci_p->pci_fm_ibc);
+ (void *)pci_p->pci_fm_ibc);
}
/*
* Register error callback with our parent.
*/
- ddi_fm_handler_register(pci_p->pci_dip, pci_err_callback,
- pci_p);
+ ddi_fm_handler_register(pci_p->pci_dip, pci_err_callback, pci_p);
}
diff --git a/usr/src/uts/sun4u/io/pci/pci_pbm.c b/usr/src/uts/sun4u/io/pci/pci_pbm.c
index b6fcb36431..e0ae8344dd 100644
--- a/usr/src/uts/sun4u/io/pci/pci_pbm.c
+++ b/usr/src/uts/sun4u/io/pci/pci_pbm.c
@@ -23,7 +23,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2019 Peter Tribble.
+ */
/*
* PCI PBM implementation:
@@ -75,12 +77,12 @@ pbm_create(pci_t *pci_p)
pbm_p->pbm_pci_p = pci_p;
len = snprintf(pbm_p->pbm_nameinst_str,
- sizeof (pbm_p->pbm_nameinst_str),
- "%s%d", NAMEINST(dip));
+ sizeof (pbm_p->pbm_nameinst_str),
+ "%s%d", NAMEINST(dip));
pbm_p->pbm_nameaddr_str = pbm_p->pbm_nameinst_str + ++len;
(void) snprintf(pbm_p->pbm_nameaddr_str,
- sizeof (pbm_p->pbm_nameinst_str) - len,
- "%s@%s", NAMEADDR(dip));
+ sizeof (pbm_p->pbm_nameinst_str) - len,
+ "%s@%s", NAMEADDR(dip));
pci_pbm_setup(pbm_p);
@@ -109,11 +111,11 @@ pbm_create(pci_t *pci_p)
pbm_p->pbm_last_pfn = mmu_btop(last_addr);
DEBUG4(DBG_ATTACH, dip,
- "pbm_create: ctrl=%x, afsr=%x, afar=%x, diag=%x\n",
- pbm_p->pbm_ctrl_reg, pbm_p->pbm_async_flt_status_reg,
- pbm_p->pbm_async_flt_addr_reg, pbm_p->pbm_diag_reg);
+ "pbm_create: ctrl=%x, afsr=%x, afar=%x, diag=%x\n",
+ pbm_p->pbm_ctrl_reg, pbm_p->pbm_async_flt_status_reg,
+ pbm_p->pbm_async_flt_addr_reg, pbm_p->pbm_diag_reg);
DEBUG1(DBG_ATTACH, dip, "pbm_create: conf=%x\n",
- pbm_p->pbm_config_header);
+ pbm_p->pbm_config_header);
/*
* Register a function to disable pbm error interrupts during a panic.
@@ -136,12 +138,6 @@ pbm_create(pci_t *pci_p)
}
pbm_configure(pbm_p);
-
- /*
- * Determine if we need to apply the Sun Fire 15k AXQ/PIO
- * workaround.
- */
- pci_axq_pio_limit(pbm_p);
}
int
@@ -234,7 +230,7 @@ pbm_error_intr(caddr_t a)
*/
ASSERT(MUTEX_HELD(&pbm_p->pbm_pokefault_mutex));
ddi_fm_acc_err_get(pbm_p->pbm_excl_handle, &derr,
- DDI_FME_VERSION);
+ DDI_FME_VERSION);
ASSERT(derr.fme_flag == DDI_FM_ERR_EXPECTED);
derr.fme_acc_handle = pbm_p->pbm_excl_handle;
err = pci_pbm_err_handler(pci_p->pci_dip, &derr, (void *)pci_p,
@@ -248,7 +244,7 @@ pbm_error_intr(caddr_t a)
membar_sync();
derr.fme_flag = DDI_FM_ERR_POKE;
err = pci_pbm_err_handler(pci_p->pci_dip, &derr, (void *)pci_p,
- PCI_INTR_CALL);
+ PCI_INTR_CALL);
} else if (pci_check_error(pci_p) != 0) {
/*
* unprotected error, check for all errors.
@@ -257,15 +253,15 @@ pbm_error_intr(caddr_t a)
(void) ldphysio(pci_errtrig_pa);
derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
err = pci_pbm_err_handler(pci_p->pci_dip, &derr, (void *)pci_p,
- PCI_INTR_CALL);
+ PCI_INTR_CALL);
}
if (err == DDI_FM_FATAL) {
if (pci_panic_on_fatal_errors) {
mutex_exit(&pci_p->pci_common_p->pci_fm_mutex);
fm_panic("%s-%d: Fatal PCI bus error(s)\n",
- ddi_driver_name(pci_p->pci_dip),
- ddi_get_instance(pci_p->pci_dip));
+ ddi_driver_name(pci_p->pci_dip),
+ ddi_get_instance(pci_p->pci_dip));
}
}
diff --git a/usr/src/uts/sun4u/io/todstarcat.c b/usr/src/uts/sun4u/io/todstarcat.c
deleted file mode 100644
index a203ee27e6..0000000000
--- a/usr/src/uts/sun4u/io/todstarcat.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * tod driver module for Starcat
- * This module implements a soft tod since
- * starcat has no tod part.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/sysmacros.h>
-#include <sys/systm.h>
-#include <sys/errno.h>
-#include <sys/modctl.h>
-#include <sys/autoconf.h>
-#include <sys/debug.h>
-#include <sys/clock.h>
-#include <sys/cmn_err.h>
-#include <sys/promif.h>
-#include <sys/cpuvar.h>
-#include <sys/sunddi.h>
-#include <sys/iosramio.h>
-#include <sys/domaind.h>
-
-#define abs(x) ((x) < 0 ? -(x) : (x))
-
-#define TODSC_SET_THRESHOLD 30
-
-static timestruc_t todsc_get(void);
-static void todsc_set(timestruc_t);
-static uint_t todsc_set_watchdog_timer(uint_t);
-static uint_t todsc_clear_watchdog_timer(void);
-static void todsc_set_power_alarm(timestruc_t);
-static void todsc_clear_power_alarm(void);
-static uint64_t todsc_get_cpufrequency(void);
-
-/*
- * Module linkage information for the kernel.
- */
-static struct modlmisc modlmisc = {
- &mod_miscops, "Soft tod module for Sun Fire 15000"
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1, (void *)&modlmisc, NULL
-};
-
-static uint32_t heartbeat = 0;
-
-int
-_init(void)
-{
- if (strcmp(tod_module_name, "todstarcat") == 0) {
- uint32_t ssc_time32 = 0;
- char obp_string[40];
-
- /*
- * To obtain the initial start of day time, we use an
- * OBP callback; this is because the iosram is not yet
- * accessible from the OS at this early stage of startup.
- */
-
- /*
- * Set the string to pass to OBP
- * for now, we assume we always get a 32bit value
- */
- (void) sprintf(obp_string, "h# %p unix-gettod",
- (void *) &ssc_time32);
-
- prom_interpret(obp_string, 0, 0, 0, 0, 0);
-
- hrestime.tv_sec = (time_t)ssc_time32;
-
- /*
- * A date of zero causes the root filesystem driver
- * to try to set the date from the last shutdown.
- */
-
- /*
- * Check for a zero date.
- */
- if (ssc_time32 == 0) {
- cmn_err(CE_WARN, "Initial date is invalid.");
- cmn_err(CE_CONT, "Attempting to set the date and time "
- "based on the last shutdown.\n");
- cmn_err(CE_CONT, "Please inspect the date and time and "
- "correct if necessary.\n");
- }
-
- /*
- * Check that the date has not overflowed a 32-bit integer.
- */
- if (TIMESPEC_OVERFLOW(&hrestime)) {
- cmn_err(CE_WARN, "Date overflow detected.");
- cmn_err(CE_CONT, "Attempting to set the date and time "
- "based on the last shutdown.\n");
- cmn_err(CE_CONT, "Please inspect the date and time and "
- "correct if necessary.\n");
-
- hrestime.tv_sec = (time_t)0;
- }
-
- tod_ops.tod_get = todsc_get;
- tod_ops.tod_set = todsc_set;
- tod_ops.tod_set_watchdog_timer = todsc_set_watchdog_timer;
- tod_ops.tod_clear_watchdog_timer = todsc_clear_watchdog_timer;
- tod_ops.tod_set_power_alarm = todsc_set_power_alarm;
- tod_ops.tod_clear_power_alarm = todsc_clear_power_alarm;
- tod_ops.tod_get_cpufrequency = todsc_get_cpufrequency;
-
- /*
- * Flag warning if user tried to use hardware watchdog
- */
- if (watchdog_enable) {
- cmn_err(CE_WARN, "Hardware watchdog unavailable");
- }
- }
-
- return (mod_install(&modlinkage));
-}
-
-int
-_fini(void)
-{
- if (strcmp(tod_module_name, "todstarcat") == 0)
- return (EBUSY);
- else
- return (mod_remove(&modlinkage));
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-
-/*
- * Starcat tod_get is simplified to return hrestime and to
- * update the domain heartbeat.
- * Must be called with tod_lock held.
- */
-static timestruc_t
-todsc_get(void)
-{
- ASSERT(MUTEX_HELD(&tod_lock));
-
- heartbeat++;
- (void) iosram_wr(DOMD_MAGIC, DOMD_HEARTBEAT_OFFSET,
- sizeof (uint32_t), (caddr_t)&heartbeat);
- return (hrestime);
-}
-
-/*
- * Must be called with tod_lock held.
- *
- * When running NTP, tod_set is called at least once per second in order
- * to update the hardware clock - for Starcat, we don't want to sync
- * the non-existent hardware clock, and only want to record significant
- * time changes on the SC (i.e. when date(1M) is run). So, we have a
- * threshold requirement before recording the time change.
- */
-/* ARGSUSED */
-static void
-todsc_set(timestruc_t ts)
-{
- char obp_string[40];
-
- ASSERT(MUTEX_HELD(&tod_lock));
-
- heartbeat++;
- (void) iosram_wr(DOMD_MAGIC, DOMD_HEARTBEAT_OFFSET,
- sizeof (uint32_t), (caddr_t)&heartbeat);
-
- if (abs(hrestime.tv_sec - ts.tv_sec) > TODSC_SET_THRESHOLD) {
- /*
- * Update the SSC with the new UTC domain time
- */
- (void) sprintf(obp_string, "h# %x unix-settod",
- (int)ts.tv_sec);
-
- prom_interpret(obp_string, 0, 0, 0, 0, 0);
-#ifdef DEBUG
- cmn_err(CE_NOTE, "todsc_set: new domain time 0x%lx\n",
- ts.tv_sec);
-#endif
- }
-}
-
-/*
- * No watchdog function.
- */
-/* ARGSUSED */
-static uint_t
-todsc_set_watchdog_timer(uint_t timeoutval)
-{
- ASSERT(MUTEX_HELD(&tod_lock));
- return (0);
-}
-
-/*
- * No watchdog function
- */
-static uint_t
-todsc_clear_watchdog_timer(void)
-{
- ASSERT(MUTEX_HELD(&tod_lock));
- return (0);
-}
-
-/*
- * Null function.
- */
-/* ARGSUSED */
-static void
-todsc_set_power_alarm(timestruc_t ts)
-{
- ASSERT(MUTEX_HELD(&tod_lock));
-}
-
-/*
- * Null function
- */
-static void
-todsc_clear_power_alarm()
-{
- ASSERT(MUTEX_HELD(&tod_lock));
-}
-
-/*
- * Get clock freq from the cpunode. This function is only called
- * when use_stick = 0, otherwise, system_clock_freq gets used instead.
- */
-uint64_t
-todsc_get_cpufrequency(void)
-{
- return (cpunodes[CPU->cpu_id].clock_freq);
-}
diff --git a/usr/src/uts/sun4u/opl/oplkmdrv/Makefile b/usr/src/uts/sun4u/opl/oplkmdrv/Makefile
index 6645855b82..98a28fc104 100644
--- a/usr/src/uts/sun4u/opl/oplkmdrv/Makefile
+++ b/usr/src/uts/sun4u/opl/oplkmdrv/Makefile
@@ -21,8 +21,7 @@
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
+# Copyright 2019 Peter Tribble.
#
# This makefile drives the production of the oplkmdrv driver
# kernel module.
@@ -34,7 +33,7 @@
# Path to the base of the uts directory tree (usually /usr/src/uts).
#
UTSBASE = ../../..
-INC_PATH += -I$(UTSBASE)/sun4u/starcat/
+INC_PATH += -I$(UTSBASE)/sun4u/opl/
#
# Define the module and object file sets.
diff --git a/usr/src/uts/sun4u/opl/sys/Makefile b/usr/src/uts/sun4u/opl/sys/Makefile
index 2d07ddff17..2a643c3b28 100644
--- a/usr/src/uts/sun4u/opl/sys/Makefile
+++ b/usr/src/uts/sun4u/opl/sys/Makefile
@@ -21,6 +21,7 @@
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2019 Peter Tribble.
#
# uts/sun4u/opl/sys/Makefile
#
@@ -45,7 +46,8 @@ CHKHDRS= dm2s.h \
fiomp.h \
mc-opl.h \
oplkm.h \
- oplkm_msg.h
+ oplkm_msg.h \
+ sckm_io.h
OPLMSUHDRS= oplmsu.h \
oplmsu_proto.h
diff --git a/usr/src/uts/sun4u/starcat/sys/sckm_io.h b/usr/src/uts/sun4u/opl/sys/sckm_io.h
index 9d4a5952ef..3ad6389e00 100644
--- a/usr/src/uts/sun4u/starcat/sys/sckm_io.h
+++ b/usr/src/uts/sun4u/opl/sys/sckm_io.h
@@ -24,11 +24,13 @@
* All rights reserved.
*/
+/*
+ * Copyright 2019 Peter Tribble.
+ */
+
#ifndef _SYS_SCKM_IO_H
#define _SYS_SCKM_IO_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/usr/src/uts/sun4u/starcat/Makefile b/usr/src/uts/sun4u/starcat/Makefile
deleted file mode 100644
index d3793ce364..0000000000
--- a/usr/src/uts/sun4u/starcat/Makefile
+++ /dev/null
@@ -1,118 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-#
-# This makefile drives the production of the sun4u starcat platform
-# module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../..
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-def := TARGET= def
-all := TARGET= all
-install := TARGET= install
-install_h := TARGET= install_h
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-lintlib := TARGET= lintlib
-modlintlib := TARGET= modlintlib
-modlist := TARGET= modlist
-modlist := NO_STATE= -K $$MODSTATE$$$$
-clean.lint := TARGET= clean.lint
-check := TARGET= check
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def all clean clobber clean.lint: genassym unix .WAIT \
- $(STARCAT_CPU_KMODS) $(STARCAT_KMODS)
-
-modlist: unix \
- $(STARCAT_CPU_KMODS) $(STARCAT_KMODS)
-
-lintlib: unix
-
-modlintlib: $(STARCAT_KMODS)
-
-IMPLEMENTED_PLATFORM = SUNW,Sun-Fire-15000
-
-install: $(ROOT_STARCAT_DIR) $(USR_STARCAT_DIR) \
- $(USR_STARCAT_INC_DIR) \
- $(USR_STARCAT_SBIN_DIR) \
- $(USR_STARCAT_LIB_DIR) \
- $(STARCAT_CRYPTO_LINKS) \
- genassym unix .WAIT $(STARCAT_CPU_KMODS) \
- $(STARCAT_KMODS)
-
-genassym unix $(STARCAT_KMODS) $(STARCAT_CPU_KMODS): FRC
- @cd $@; pwd; $(MAKE) $(NO_STATE) $(TARGET)
-
-$(STARCAT_CRYPTO_LINKS): $(ROOT_STARCAT_CRYPTO_DIR_64)
- -$(RM) $(ROOT_STARCAT_CRYPTO_DIR_64)/$@;
- $(SYMLINK) $(ROOT_US3_CRYPTO_LINK)/$@ $(ROOT_STARCAT_CRYPTO_DIR_64)/$@
-
-install_h check: FRC
- @cd sys; pwd; $(MAKE) $(TARGET)
-
-lint: modlintlib
-
-
-#
-# The 'lint.platmod' target lints the starcat platform module against
-# the sun4u kernel. This ends up doing all the kernel cross-checks,
-# so it takes a couple of minutes.
-# Due to the low ROI, it's not run by default, but it's a good
-# idea to run this if you change os/starcat.c.
-#
-
-LINT_LIBS = $(LINT_LIB) \
- -L$(STARCAT_LINT_LIB_DIR) \
- -L$(LINT_LIB_DIR) $(LINT_KMODS:%=-l%) \
- $(CLOSED_LINT_KMODS:%=-l%) \
- -L$(SPARC_LIB_DIR) $(SPARC_LINTS:%=-l%)
-
-lint.platmod: modlintlib
- @-$(ECHO) "\nStarcat Platform-dependent module: global crosschecks:"
- @-$(LINT) $(LINTFLAGS) $(LINT_LIBS) 2>&1 | $(LGREP.2)
-
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/Makefile.files b/usr/src/uts/sun4u/starcat/Makefile.files
deleted file mode 100644
index 81f1501aee..0000000000
--- a/usr/src/uts/sun4u/starcat/Makefile.files
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# This Makefile defines all file modules for the directory
-# uts/sun4u/starcat and its children. These are the source files which
-# are starcat "implementation architecture" dependent.
-#
-
-#
-# Object lists
-#
-
-STARCAT_OBJS = starcat.o starcat_asm.o plat_ecc_unum.o plat_ecc_dimm.o
-
-#
-# Starcat specific driver related modules
-#
-
-AXQ_OBJS += axq.o
-CVC_OBJS += cvc.o
-CVCREDIR_OBJS += cvcredir.o
-DMAN_OBJS += dman.o dman_domain.o
-DRMACH_OBJS += drmach.o drmach_asm.o dr_util.o drmach_err.o
-FCGP2_OBJS += fcgp2.o
-GPTWO_PCI_OBJS += gptwo_pci.o
-IOSRAM_OBJS += iosram.o
-MBOXSC_OBJS += mboxsc.o
-SC_GPTWO_OBJS += sc_gptwocfg.o
-SC_PCICFG_OBJS += sc_pcicfg.o
-SCHPC_OBJS += schpc.o
-SCKMDRV_OBJS += sckmdrv.o
-SCOSMB_OBJS += scosmb.o
-
-#
-# Miscellaneous
-#
-INC_PATH += -I$(UTSBASE)/sun4u/starcat
-INC_PATH += -I$(UTSBASE)/sun4u/starcat/sys
-
-#
-# Since assym.h is a derived file, the dependency must be explicit for
-# all files including this file. (This is only actually required in the
-# instance when the .nse_depinfo file does not exist.) It may seem that
-# the lint targets should also have a similar dependency, but they don't
-# since only C headers are included when #defined(lint) is true.
-#
-ASSYM_DEPS += drmach_asm.o
diff --git a/usr/src/uts/sun4u/starcat/Makefile.rules b/usr/src/uts/sun4u/starcat/Makefile.rules
deleted file mode 100644
index a5acd4fa22..0000000000
--- a/usr/src/uts/sun4u/starcat/Makefile.rules
+++ /dev/null
@@ -1,85 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# This Makefile defines the build rules for the directory
-# uts/sun4u/starcat and its children.
-#
-
-#
-# inline support for DR.
-#
-
-IL_CPP=$(CPP) -P -DINLINE -D_ASM $(AS_INC_PATH) \
- $(CPP_DEFS) $(ALWAYS_DEFS) $(ALL_DEFS) $(CONFIG_DEFS)
-
-#
-# Section 1a: C object build rules
-#
-
-DRMACH_IL=$(OBJS_DIR)/drmach.il
-
-$(OBJS_DIR)/drmach.o := CC_XARCH_32 = -xarch=v8plusa
-$(OBJS_DIR)/%.o: $(UTSBASE)/sun4u/starcat/io/%.c $(DRMACH_IL)
- $(COMPILE.c) $(DRMACH_IL) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/sun4u/starcat/os/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
-$(OBJS_DIR)/%.o: $(UTSBASE)/sun4u/starcat/ml/%.s
- $(COMPILE.s) -o $@ $<
-
-STARCAT_IO=$(UTSBASE)/sun4u/starcat/io
-
-CLEANFILES += $(STARCAT_IO)/drmach_err.c
-
-$(STARCAT_IO)/drmach_err.c: $(SBDGENERR) $(SBD_IOCTL)
- $(RM) $@
- $(SBDGENERRCMD) ESTC <$(SBD_IOCTL) >$@
-
-# inline stuff
-
-CLEANFILES += $(DRMACH_IL)
-
-$(DRMACH_IL): $(UTSBASE)/sun4u/starcat/ml/drmach.il.cpp
- $(IL_CPP) $(UTSBASE)/sun4u/starcat/ml/drmach.il.cpp > $@
-
-#
-# Section 1b: Lint object build rules
-#
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/sun4u/starcat/os/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/drmach.ln := LINTFLAGS += -I../sys
-$(LINTS_DIR)/sc_gptwoctfg.ln := LINTFLAGS += -I../sys
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/sun4u/starcat/io/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
-$(LINTS_DIR)/%.ln: $(UTSBASE)/sun4u/starcat/ml/%.s
- @($(LHEAD) $(LINT.s) $< $(LTAIL))
diff --git a/usr/src/uts/sun4u/starcat/Makefile.starcat b/usr/src/uts/sun4u/starcat/Makefile.starcat
deleted file mode 100644
index 4205d221a5..0000000000
--- a/usr/src/uts/sun4u/starcat/Makefile.starcat
+++ /dev/null
@@ -1,155 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Global definitions for sun4u starcat implementation specific modules.
-#
-
-#
-# Define directories.
-#
-ROOT_STARCAT_DIR = $(ROOT_PLAT_DIR)/SUNW,Sun-Fire-15000
-ROOT_STARCAT_MOD_DIR = $(ROOT_STARCAT_DIR)/kernel
-ROOT_STARCAT_KERN_DIR_32 = $(ROOT_STARCAT_MOD_DIR)
-ROOT_STARCAT_KERN_DIR_64 = $(ROOT_STARCAT_MOD_DIR)/$(SUBDIR64)
-ROOT_STARCAT_MISC_DIR_32 = $(ROOT_STARCAT_MOD_DIR)/misc
-ROOT_STARCAT_MISC_DIR_64 = $(ROOT_STARCAT_MOD_DIR)/misc/$(SUBDIR64)
-ROOT_STARCAT_DRV_DIR_32 = $(ROOT_STARCAT_MOD_DIR)/drv
-ROOT_STARCAT_DRV_DIR_64 = $(ROOT_STARCAT_MOD_DIR)/drv/$(SUBDIR64)
-ROOT_STARCAT_CPU_DIR_32 = $(ROOT_STARCAT_MOD_DIR)/cpu
-ROOT_STARCAT_CPU_DIR_64 = $(ROOT_STARCAT_MOD_DIR)/cpu/$(SUBDIR64)
-ROOT_STARCAT_CRYPTO_DIR_32 = $(ROOT_STARCAT_MOD_DIR)/crypto
-ROOT_STARCAT_CRYPTO_DIR_64 = $(ROOT_STARCAT_MOD_DIR)/crypto/$(SUBDIR64)
-
-ROOT_STARCAT_KERN_DIR = $(ROOT_STARCAT_KERN_DIR_$(CLASS))
-ROOT_STARCAT_MISC_DIR = $(ROOT_STARCAT_MISC_DIR_$(CLASS))
-ROOT_STARCAT_DRV_DIR = $(ROOT_STARCAT_DRV_DIR_$(CLASS))
-ROOT_STARCAT_CPU_DIR = $(ROOT_STARCAT_CPU_DIR_$(CLASS))
-ROOT_STARCAT_CRYPTO_DIR = $(ROOT_STARCAT_CRYPTO_DIR_$(CLASS))
-
-ROOT_PLAT_MOD_DIRS += $(ROOT_STARCAT_MOD_DIR)
-ROOT_PLAT_MISC_DIRS_32 += $(ROOT_STARCAT_MISC_DIR_32)
-
-USR_STARCAT_DIR = $(USR_PLAT_DIR)/SUNW,Sun-Fire-15000
-USR_STARCAT_LIB_DIR = $(USR_STARCAT_DIR)/lib
-USR_STARCAT_SBIN_DIR = $(USR_STARCAT_DIR)/sbin
-USR_STARCAT_INC_DIR = $(USR_STARCAT_DIR)/include
-USR_STARCAT_ISYS_DIR = $(USR_STARCAT_INC_DIR)/sys
-
-STARCAT_LINT_LIB_DIR = $(UTSBASE)/$(PLATFORM)/starcat/lint-libs/$(OBJS_DIR)
-
-#
-# Include the makefiles which define build rule templates, the
-# collection of files per module, and a few specific flags. Note
-# that order is significant, just as with an include path. The
-# first build rule template which matches the files name will be
-# used. By including these in order from most machine dependent
-# to most machine independent, we allow a machine dependent file
-# to be used in preference over a machine independent version
-# (Such as a machine specific optimization, which preserves the
-# interfaces.)
-#
-include $(UTSBASE)/sun4u/ngdr/Makefile.files
-include $(UTSBASE)/sun4u/starcat/Makefile.files
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/Makefile.sun4u
-
-#
-# Define modules
-#
-STARCAT_KMODS += axq
-STARCAT_KMODS += cvc
-STARCAT_KMODS += cvcredir
-STARCAT_KMODS += dman
-STARCAT_KMODS += dr
-STARCAT_KMODS += drmach
-STARCAT_KMODS += fcgp2
-STARCAT_KMODS += gptwo_pci
-STARCAT_KMODS += iosram
-STARCAT_KMODS += mboxsc
-STARCAT_KMODS += platmod
-STARCAT_KMODS += sc_gptwocfg
-STARCAT_KMODS += schpc
-STARCAT_KMODS += sckmdrv
-STARCAT_KMODS += scosmb
-
-#
-# Define CPU modules.
-#
-STARCAT_CPU_KMODS += cheetah cheetahplus
-
-#
-# Links to UltraSparc III crypto modules
-#
-STARCAT_CRYPTO_LINKS = aes
-
-#
-# Everybody needs to know how to build modstubs.o and to locate unix.o
-#
-UNIX_DIR = $(UTSBASE)/$(PLATFORM)/starcat/unix
-MODSTUBS_DIR = $(UNIX_DIR)
-DSF_DIR = $(UTSBASE)/$(PLATFORM)/starcat/genassym
-LINTS_DIR = $(OBJS_DIR)
-LINT_LIB_DIR = $(UTSBASE)/$(PLATFORM)/starcat/lint-libs/$(OBJS_DIR)
-
-UNIX_O = $(UNIX_DIR)/$(OBJS_DIR)/unix.o
-
-LINT_LIB = $(LINT_LIB_DIR)/llib-lunix.ln
-
-#
-# Define the actual specific platforms
-#
-MACHINE_DEFS = -D$(PLATFORM) -D_MACHDEP -DSFMMU -DMP -DMIXEDCPU_DR_SUPPORTED
-MACHINE_DEFS += -D_CPU_SIGNATURE
-
-#
-# Define platform specific value
-#
-MACHINE_DEFS += -DNCPU=558
-MACHINE_DEFS += -DMAX_CPU_CHIPID=554
-MACHINE_DEFS += -DMAX_UPA=1024
-MACHINE_DEFS += -DIGN_SIZE=10
-MACHINE_DEFS += -DMAX_MEM_NODES=18
-
-#
-# Define for inline pre-processing since
-# cpp not smart about v9 yet.
-# It's not smart about __sparc either since it only predefines sparc.
-CPP_DEFS_32 = -D__sparc
-CPP_DEFS_64 = -D__sparc -D__sparcv9
-CPP_DEFS = $(CPP_DEFS_$(CLASS))
-
-#
-# For now, disable these lint checks; maintainers should endeavor
-# to investigate and remove these for maximum lint coverage.
-# Please do not carry these forward to new Makefiles.
-#
-LINTTAGS += -erroff=E_SUSPICIOUS_COMPARISON
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-LINTTAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED
-LINTTAGS += -erroff=E_STATIC_UNUSED
-LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
diff --git a/usr/src/uts/sun4u/starcat/Makefile.targ b/usr/src/uts/sun4u/starcat/Makefile.targ
deleted file mode 100644
index 16e7b1456d..0000000000
--- a/usr/src/uts/sun4u/starcat/Makefile.targ
+++ /dev/null
@@ -1,96 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Common targets for sun4u starcat implementation specific modules.
-#
-
-.KEEP_STATE:
-
-#
-# Rules for implementation subdirectories.
-#
-$(ROOT_STARCAT_DIR): $(ROOT_PLAT_DIR)
- -$(INS.dir)
-
-$(ROOT_STARCAT_MOD_DIR): $(ROOT_STARCAT_DIR)
- -$(INS.dir)
-
-$(ROOT_STARCAT_CPU_DIR_32): $(ROOT_STARCAT_MOD_DIR)
- -$(INS.dir)
-
-$(ROOT_STARCAT_CPU_DIR_64): $(ROOT_STARCAT_CPU_DIR_32)
- -$(INS.dir)
-
-$(ROOT_STARCAT_DRV_DIR_32): $(ROOT_STARCAT_MOD_DIR)
- -$(INS.dir)
-
-$(ROOT_STARCAT_DRV_DIR_64): $(ROOT_STARCAT_DRV_DIR_32)
- -$(INS.dir)
-
-$(ROOT_STARCAT_MISC_DIR_32): $(ROOT_STARCAT_MOD_DIR)
- -$(INS.dir)
-
-$(ROOT_STARCAT_MISC_DIR_64): $(ROOT_STARCAT_MISC_DIR_32)
- -$(INS.dir)
-
-$(ROOT_STARCAT_CRYPTO_DIR_32): $(ROOT_STARCAT_MOD_DIR)
- -$(INS.dir)
-
-$(ROOT_STARCAT_CRYPTO_DIR_64): $(ROOT_STARCAT_CRYPTO_DIR_32)
- -$(INS.dir)
-
-$(USR_STARCAT_DIR): $(USR_PLAT_DIR)
- -$(INS.dir)
-
-$(USR_STARCAT_INC_DIR): $(USR_STARCAT_DIR)
- $(INS.slink4)
-
-$(USR_STARCAT_SBIN_DIR): $(USR_STARCAT_DIR)
- -$(INS.slink5)
-
-$(USR_STARCAT_LIB_DIR): $(USR_STARCAT_DIR)
- -$(INS.dir)
-
-$(USR_STARCAT_ISYS_DIR): $(USR_STARCAT_INC_DIR)
- $(INS.dir)
-
-$(ROOT_STARCAT_KERN_DIR)/%: $(OBJS_DIR)/% $(ROOT_STARCAT_KERN_DIR) FRC
- $(INS.file)
-
-$(ROOT_STARCAT_DRV_DIR)/%: $(OBJS_DIR)/% $(ROOT_STARCAT_DRV_DIR) FRC
- $(INS.file)
-
-$(ROOT_STARCAT_CPU_DIR)/%: $(OBJS_DIR)/% $(ROOT_STARCAT_CPU_DIR) FRC
- $(INS.file)
-
-$(ROOT_STARCAT_MISC_DIR)/%: $(OBJS_DIR)/% $(ROOT_STARCAT_MISC_DIR) FRC
- $(INS.file)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/ngdr/Makefile.rules
-include $(UTSBASE)/sun4u/starcat/Makefile.rules
-include $(UTSBASE)/sun4u/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/axq/Makefile b/usr/src/uts/sun4u/starcat/axq/Makefile
deleted file mode 100644
index 0a223a4910..0000000000
--- a/usr/src/uts/sun4u/starcat/axq/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# This makefile drives the production of the Starcat AXQ
-# module.
-#
-# sun4u implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = axq
-OBJECTS = $(AXQ_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(AXQ_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_DRV_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
-#
-# Turn on doubleword alignment for 64 bit registers
-#
-CFLAGS += -dalign
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/cheetah/Makefile b/usr/src/uts/sun4u/starcat/cheetah/Makefile
deleted file mode 100644
index a5df75acd3..0000000000
--- a/usr/src/uts/sun4u/starcat/cheetah/Makefile
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of the Starcat specific
-# UltraSPARC-III driver module.
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = SUNW,UltraSPARC-III
-OBJECTS = $(CHEETAH_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(CHEETAH_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_CPU_DIR)/$(MODULE)
-ROOTSOFTLINKS = $(SOFTLINKS:%=$(ROOT_STARCAT_CPU_DIR)/%)
-
-CPU_DIR = .
-HERE = ../cheetah
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Override defaults
-#
-CLEANFILES += $(CPULIB) $(SYM_MOD)
-
-#
-# Define targets
-#
-ALL_TARGET = $(SYM_MOD)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = def $(BINARY) $(ROOTMODULE) $(ROOTSOFTLINKS)
-
-#
-# Overrides
-#
-ALL_BUILDS = $(ALL_BUILDSONLY64)
-DEF_BUILDS = $(DEF_BUILDSONLY64)
-CLEANLINTFILES += $(LINT32_FILES)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-type-limits
-CERRWARN += -_gcc=-Wno-clobbered
-
-#
-# cpu-module-specific flags
-#
-CPPFLAGS += -DCPU_MODULE -DCHEETAH
-AS_CPPFLAGS += -DCPU_MODULE -DCHEETAH
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS) lint32
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(CPULIB): $(OBJECTS)
- $(BUILD.SO) $(OBJECTS)
-
-$(SYM_MOD): $(UNIX_O) $(CPULIB)
- @echo "resolving symbols against unix.o"
- @(cd $(UNIX_DIR); pwd; \
- CPU_DIR=$(HERE) SYM_MOD=$(HERE)/$(SYM_MOD) $(MAKE) symcheck)
-
-$(ROOTSOFTLINKS): $(ROOTMODULE)
- $(RM) $@; $(SYMLINK) $(MODULE) $@
-
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/cheetahplus/Makefile b/usr/src/uts/sun4u/starcat/cheetahplus/Makefile
deleted file mode 100644
index 37d8deb62b..0000000000
--- a/usr/src/uts/sun4u/starcat/cheetahplus/Makefile
+++ /dev/null
@@ -1,130 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of the Starcat specific
-# UltraSPARC-III+ driver module.
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = SUNW,UltraSPARC-III+
-OBJECTS = $(CHEETAHPLUS_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(CHEETAHPLUS_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_CPU_DIR)/$(MODULE)
-SOFTLINKS = SUNW,UltraSPARC-IV SUNW,UltraSPARC-IV+
-ROOTSOFTLINKS = $(SOFTLINKS:%=$(ROOT_STARCAT_CPU_DIR)/%)
-
-CPU_DIR = .
-HERE = ../cheetahplus
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Override defaults
-#
-CLEANFILES += $(CPULIB) $(SYM_MOD)
-
-#
-# Define targets
-#
-ALL_TARGET = $(SYM_MOD)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = def $(BINARY) $(ROOTMODULE) $(ROOTSOFTLINKS)
-
-#
-# Overrides
-#
-ALL_BUILDS = $(ALL_BUILDSONLY64)
-DEF_BUILDS = $(DEF_BUILDSONLY64)
-CLEANLINTFILES += $(LINT32_FILES)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -DCHEETAH -DCHEETAH_PLUS -DCPU_IMP_L1_CACHE_PARITY \
- -DCPU_IMP_ECACHE_ASSOC -DCPU_IMP_DUAL_PAGESIZE -DCPU_IMP_AFSR_EXT
-ASFLAGS += -DCHEETAH -DCHEETAH_PLUS -DCPU_IMP_L1_CACHE_PARITY \
- -DCPU_IMP_ECACHE_ASSOC -DCPU_IMP_DUAL_PAGESIZE -DCPU_IMP_AFSR_EXT
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-type-limits
-CERRWARN += -_gcc=-Wno-clobbered
-
-#
-# cpu-module-specific flags
-#
-CPPFLAGS += -DCPU_MODULE -DCHEETAH -DCHEETAH_PLUS -DCPU_IMP_L1_CACHE_PARITY \
- -DCPU_IMP_ECACHE_ASSOC -DCPU_IMP_DUAL_PAGESIZE -DCPU_IMP_AFSR_EXT
-AS_CPPFLAGS += -DCPU_MODULE -DCHEETAH -DCHEETAH_PLUS -DCPU_IMP_L1_CACHE_PARITY \
- -DCPU_IMP_ECACHE_ASSOC -DCPU_IMP_DUAL_PAGESIZE -DCPU_IMP_AFSR_EXT
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS) lint32
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(CPULIB): $(OBJECTS)
- $(BUILD.SO) $(OBJECTS)
-
-$(SYM_MOD): $(UNIX_O) $(CPULIB)
- @echo "resolving symbols against unix.o"
- @(cd $(UNIX_DIR); pwd; \
- CPU_DIR=$(HERE) SYM_MOD=$(HERE)/$(SYM_MOD) $(MAKE) symcheck)
-
-$(ROOTSOFTLINKS): $(ROOTMODULE)
- $(RM) $@; $(SYMLINK) $(MODULE) $@
-
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/cvc/Makefile b/usr/src/uts/sun4u/starcat/cvc/Makefile
deleted file mode 100644
index 6efbe00620..0000000000
--- a/usr/src/uts/sun4u/starcat/cvc/Makefile
+++ /dev/null
@@ -1,99 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# This makefile drives the production of the cvc driver module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = cvc
-OBJECTS = $(CVC_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(CVC_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/sun4u/starcat/io
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) .WAIT $(ROOT_CONFFILE)
-
-#
-# Overrides
-#
-ALL_BUILDS = $(ALL_BUILDSONLY64)
-DEF_BUILDS = $(DEF_BUILDSONLY64)
-CLEANLINTFILES += $(LINT32_FILES)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Ndrv/iosram -Ndrv/sbbc
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/cvcredir/Makefile b/usr/src/uts/sun4u/starcat/cvcredir/Makefile
deleted file mode 100644
index 461c10fad1..0000000000
--- a/usr/src/uts/sun4u/starcat/cvcredir/Makefile
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# This makefile drives the production of the cvcredir driver module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = cvcredir
-OBJECTS = $(CVCREDIR_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(CVCREDIR_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/sun4u/starcat/io
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) .WAIT $(ROOT_CONFFILE)
-
-#
-# Overrides
-#
-ALL_BUILDS = $(ALL_BUILDSONLY64)
-DEF_BUILDS = $(DEF_BUILDSONLY64)
-CLEANLINTFILES += $(LINT32_FILES)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Ndrv/cvc
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/dman/Makefile b/usr/src/uts/sun4u/starcat/dman/Makefile
deleted file mode 100644
index 8978ae20bf..0000000000
--- a/usr/src/uts/sun4u/starcat/dman/Makefile
+++ /dev/null
@@ -1,92 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the pruction of the Management Network
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = dman
-OBJECTS = $(DMAN_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(DMAN_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/sun4u/starcat/io
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-LDFLAGS += -dy -Ndrv/ip -Ndrv/eri -Ndrv/iosram -Nmisc/mboxsc
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-unused-label
-CERRWARN += -_gcc=-Wno-type-limits
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/dr/Makefile b/usr/src/uts/sun4u/starcat/dr/Makefile
deleted file mode 100644
index 3a7409fc70..0000000000
--- a/usr/src/uts/sun4u/starcat/dr/Makefile
+++ /dev/null
@@ -1,95 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of the dr driver module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = dr
-OBJECTS = $(DR_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(DR_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/sun4u/starcat/io
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -I../sys
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Nmisc/drmach
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/drmach/Makefile b/usr/src/uts/sun4u/starcat/drmach/Makefile
deleted file mode 100644
index 2cc0ef1aa9..0000000000
--- a/usr/src/uts/sun4u/starcat/drmach/Makefile
+++ /dev/null
@@ -1,98 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of the drmach loadable module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = drmach
-OBJECTS = $(DRMACH_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(DRMACH_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-MACHINE_DEFS += -DCHEETAH_PLUS
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -I../sys -I$(UTSBASE)/sun4u/starcat/sys
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-type-limits
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Nmisc/mboxsc -Ndrv/iosram -Ndrv/axq -Nmisc/fcpci \
- -Nmisc/fcodem -Nmisc/sc_gptwocfg -Ndrv/schpc
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/fcgp2/Makefile b/usr/src/uts/sun4u/starcat/fcgp2/Makefile
deleted file mode 100644
index 83e576953e..0000000000
--- a/usr/src/uts/sun4u/starcat/fcgp2/Makefile
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of the fcgp2
-# miscellaneous module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = fcgp2
-OBJECTS = $(FCGP2_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(FCGP2_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-uninitialized
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Nmisc/fcodem -Nmisc/busra
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/genassym/Makefile b/usr/src/uts/sun4u/starcat/genassym/Makefile
deleted file mode 100644
index fcaa2e5105..0000000000
--- a/usr/src/uts/sun4u/starcat/genassym/Makefile
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# This makefile drives the production of assym.h through genconst/stabs.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-ASSYM_H = $(DSF_DIR)/$(OBJS_DIR)/assym.h
-GENCONST = $(DSF_DIR)/$(OBJS_DIR)/genconst
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(ASSYM_H)
-
-#
-# This is DSF_DIR. Use a short path.
-#
-DSF_DIR = .
-
-#
-# Overrides
-#
-CLEANFILES = $(GENCONST) Nothing_to_remove
-CLOBBERFILES = $(ASSYM_H) $(CLEANFILES) Nothing_to_remove
-ALL_BUILDS = $(ALL_BUILDSONLY64)
-DEF_BUILDS = $(DEF_BUILDSONLY64)
-CLEANLINTFILES += $(LINT32_FILES)
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-clean.lint:
-
-install: def
-
-#
-# create assym.h
-#
-$(GENCONST): $(GENCONST_SRC)
- $(NATIVECC) -w $(ALWAYS_DEFS) $(GENCONST_DEFS) $(NATIVE_INC_PATH) \
- -o $(GENCONST) $(GENCONST_SRC)
-
-$(ASSYM_H): $(GENCONST) $(OFFSETS) $(PLATFORM_OFFSETS)
- $(OFFSETS_CREATE) <$(OFFSETS) >$@
- $(OFFSETS_CREATE) <$(PLATFORM_OFFSETS) >>$@
- $(GENCONST) >>$@
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/gptwo_pci/Makefile b/usr/src/uts/sun4u/starcat/gptwo_pci/Makefile
deleted file mode 100644
index f71c0562a0..0000000000
--- a/usr/src/uts/sun4u/starcat/gptwo_pci/Makefile
+++ /dev/null
@@ -1,101 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# This makefile drives the production of the pci/schizo portion of
-# of the Safari Configurator.
-#
-# sun4u implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = gptwo_pci
-OBJECTS = $(GPTWO_PCI_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(GPTWO_PCI_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-# Turn this on once compiler understands v9 in it's backend
-#INLINES += $(UTSBASE)/sun4u/starcat/io/gptwo_pci.il
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Nmisc/gptwocfg -Nmisc/fcgp2 -Nmisc/fcodem -Nmisc/busra
-
-#
-# Turn on doubleword alignment for 64 bit registers
-#
-CFLAGS += -dalign
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/io/axq.c b/usr/src/uts/sun4u/starcat/io/axq.c
deleted file mode 100644
index 3984d860e0..0000000000
--- a/usr/src/uts/sun4u/starcat/io/axq.c
+++ /dev/null
@@ -1,1746 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-
-#include <sys/types.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/obpdefs.h>
-#include <sys/cmn_err.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/debug.h>
-#include <sys/sysmacros.h>
-#include <sys/autoconf.h>
-#include <sys/modctl.h>
-#include <sys/sunndi.h>
-
-#include <sys/axq.h>
-#include <sys/promif.h>
-#include <sys/cpuvar.h>
-#include <sys/starcat.h>
-#include <sys/callb.h>
-
-#define REG_ADDR(b, o) (uint32_t *)((caddr_t)(b) + (o))
-
-/*
- * Function prototypes
- */
-
-/* autoconfig entry point function definitions */
-static int axq_attach(dev_info_t *, ddi_attach_cmd_t);
-static int axq_detach(dev_info_t *, ddi_detach_cmd_t);
-static int axq_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
-
-/* internal axq definitions */
-static void axq_init(struct axq_soft_state *);
-static void axq_init_local(struct axq_local_regs *);
-
-/* axq kstats */
-static void axq_add_picN_kstats(dev_info_t *dip);
-static void axq_add_kstats(struct axq_soft_state *);
-static int axq_counters_kstat_update(kstat_t *, int);
-
-/*
- * Configuration data structures
- */
-static struct cb_ops axq_cb_ops = {
- nulldev, /* open */
- nulldev, /* close */
- nulldev, /* strategy */
- nulldev, /* print */
- nodev, /* dump */
- nulldev, /* read */
- nulldev, /* write */
- nulldev, /* ioctl */
- nodev, /* devmap */
- nodev, /* mmap */
- nodev, /* segmap */
- nochpoll, /* poll */
- ddi_prop_op, /* cb_prop_op */
- 0, /* streamtab */
- D_MP | D_NEW, /* Driver compatibility flag */
- CB_REV, /* rev */
- nodev, /* cb_aread */
- nodev /* cb_awrite */
-};
-
-static struct dev_ops axq_ops = {
- DEVO_REV, /* rev */
- 0, /* refcnt */
- axq_getinfo, /* getinfo */
- nulldev, /* identify */
- nulldev, /* probe */
- axq_attach, /* attach */
- axq_detach, /* detach */
- nulldev, /* reset */
- &axq_cb_ops, /* cb_ops */
- (struct bus_ops *)0, /* bus_ops */
- nulldev, /* power */
- ddi_quiesce_not_supported, /* devo_quiesce */
-};
-
-
-/*
- * AXQ globals
- */
-struct axq_soft_state *axq_array[AXQ_MAX_EXP][AXQ_MAX_SLOT_PER_EXP];
-krwlock_t axq_array_lock;
-struct axq_local_regs axq_local;
-int use_axq_iopause = 1; /* enable flag axq iopause by default */
-/*
- * If non-zero, iopause will be asserted during DDI_SUSPEND.
- * Clients using the axq_iopause_*_all interfaces should set this to zero.
- */
-int axq_suspend_iopause = 1;
-
-/*
- * loadable module support
- */
-extern struct mod_ops mod_driverops;
-
-static struct modldrv modldrv = {
- &mod_driverops, /* Type of module. This one is a driver */
- "AXQ driver", /* name of module */
- &axq_ops, /* driver ops */
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- (void *)&modldrv,
- NULL
-};
-
-static void *axq_softp;
-
-/*
- * AXQ Performance counters
- * We statically declare a array of the known
- * AXQ event-names and event masks. The number
- * of events in this array is AXQ_NUM_EVENTS.
- */
-static axq_event_mask_t axq_events[AXQ_NUM_EVENTS] = {
- {"count_clk", COUNT_CLK}, {"freeze_cnt", FREEZE_CNT},
- {"ha_input_fifo", HA_INPUT_FIFO}, {"ha_intr_info", HA_INTR_INFO},
- {"ha_pio_fifo", HA_PIO_FIFO}, {"ha_adr_fifo_lk3", HA_ADR_FIFO_LK3},
- {"ha_adr_fifo_lk2", HA_ADR_FIFO_LK2},
- {"ha_adr_fifo_lk1", HA_ADR_FIFO_LK1},
- {"ha_adr_fifo_lk0", HA_ADR_FIFO_LK0},
- {"ha_dump_q", HA_DUMP_Q},
- {"ha_rd_f_stb_q", HA_RD_F_STB_Q},
- {"ha_dp_wr_q", HA_DP_WR_Q},
- {"ha_int_q", HA_INT_Q},
- {"ha_wrb_q", HA_WRB_Q},
- {"ha_wr_mp_q", HA_WR_MP_Q},
- {"ha_wrtag_q", HA_WRTAG_Q},
- {"ha_wt_wait_fifo", HA_WT_WAIT_FIFO},
- {"ha_wrb_stb_fifo", HA_WRB_STB_FIFO},
- {"ha_ap0_q", HA_AP0_Q},
- {"ha_ap1_q", HA_AP1_Q},
- {"ha_new_wr_q", HA_NEW_WR_Q},
- {"ha_dp_rd_q", HA_DP_RD_Q},
- {"ha_unlock_q", HA_UNLOCK_Q},
- {"ha_cdc_upd_q", HA_CDC_UPD_Q},
- {"ha_ds_q", HA_DS_Q},
- {"ha_unlk_wait_q", HA_UNLK_WAIT_Q},
- {"ha_rd_mp_q", HA_RD_MP_Q},
- {"l2_io_q", L2_IO_Q},
- {"l2_sb_q", L2_SB_Q},
- {"l2_ra_q", L2_RA_Q},
- {"l2_ha_q", L2_HA_Q},
- {"l2_sa_q", L2_SA_Q},
- {"ra_wait_fifo", RA_WAIT_FIFO},
- {"ra_wrb_inv_fifo", RA_WRB_INV_FIFO},
- {"ra_wrb_fifo", RA_WRB_FIFO},
- {"ra_cc_ptr_fifo", RA_CC_PTR_FIFO},
- {"ra_io_ptr_fifo", RA_IO_PTR_FIFO},
- {"ra_int_ptr_fifo", RA_INT_PTR_FIFO},
- {"ra_rp_q", RA_RP_Q},
- {"ra_wrb_rp_q", RA_WRB_RP_Q},
- {"ra_dp_q", RA_DP_Q},
- {"ra_dp_stb_q", RA_DP_STB_Q},
- {"ra_gtarg_q", RA_GTARG_Q},
- {"sdc_recv_q", SDC_RECV_Q},
- {"sdc_redir_io_q", SDC_REDIR_IO_Q},
- {"sdc_redir_sb_q", SDC_REDIR_SB_Q},
- {"sdc_outb_io_q", SDC_OUTB_IO_Q},
- {"sdc_outb_sb_q", SDC_OUTB_SB_Q},
- {"sa_add1_input_q", SA_ADD1_INPUT_Q},
- {"sa_add2_input_q", SA_ADD2_INPUT_Q},
- {"sa_inv_q", SA_INV_Q},
- {"sa_no_inv_q", SA_NO_INV_Q},
- {"sa_int_dp_q", SA_INT_DP_Q},
- {"sa_dp_q", SA_DP_Q},
- {"sl_wrtag_q", SL_WRTAG_Q},
- {"sl_rto_dp_q", SL_RTO_DP_Q},
- {"syreg_input_q", SYSREG_INPUT_Q},
- {"sdi_sys_status1", SDI_SYS_STATUS1},
- {"sdi_sys_status0", SDI_SYS_STATUS0},
- {"cdc_hits", CDC_HITS},
- {"total_cdc_read", TOTAL_CDC_READ},
- {"ha_watranid_sd", HA_WATRANID_SD},
- {"ha_stb_sd", HA_STB_SD},
- {"ha_l2_irq_sd", HA_L2_IRQ_SD},
- {"ha_sl_wrtag_sd", HA_SL_WRTAG_SD},
- {"aa_home_cc_full", AA_HOME_CC_FULL},
- {"aa_home_io_full", AA_HOME_IO_FULL},
- {"aa_slave_full", AA_SLAVE_FULL},
- {"aa_rp_full", AA_RP_FULL}
-};
-
-static kstat_t *axq_picN_ksp[AXQ_NUM_PICS]; /* picN kstats */
-static int axq_attachcnt = 0; /* # of instances attached */
-static kmutex_t axq_attachcnt_lock; /* lock for attachcnt */
-
-static int axq_map_phys(dev_info_t *, struct regspec *, caddr_t *,
- ddi_device_acc_attr_t *, ddi_acc_handle_t *);
-static void axq_unmap_phys(ddi_acc_handle_t *);
-
-int starcat_axq_pio_workaround(dev_info_t *);
-static int axq_slot1_idle(struct axq_soft_state *);
-
-static boolean_t axq_panic_callb(void *, int);
-static callb_id_t axq_panic_cb_id;
-
-/*
- * These are the module initialization routines.
- */
-
-int
-_init(void)
-{
- int error;
-
- if ((error = ddi_soft_state_init(&axq_softp,
- sizeof (struct axq_soft_state), 1)) != 0)
- return (error);
-
- rw_init(&axq_array_lock, NULL, RW_DEFAULT, NULL);
-
- mutex_init(&axq_local.axq_local_lock, NULL, MUTEX_DRIVER, NULL);
-
- mutex_init(&axq_attachcnt_lock, NULL, MUTEX_DRIVER, NULL);
-
- axq_local.initflag = 0;
-
- if ((error = mod_install(&modlinkage)) != 0) {
- ddi_soft_state_fini(&axq_softp);
- mutex_destroy(&axq_attachcnt_lock);
- mutex_destroy(&axq_local.axq_local_lock);
- rw_destroy(&axq_array_lock);
- return (error);
- }
-
- axq_panic_cb_id = callb_add(axq_panic_callb, (void *)NULL,
- CB_CL_PANIC, "axq_panic");
-
- return (0);
-}
-
-int
-_fini(void)
-{
- int error;
-
- if ((error = mod_remove(&modlinkage)) != 0)
- return (error);
-
- ddi_soft_state_fini(&axq_softp);
- mutex_destroy(&axq_attachcnt_lock);
- mutex_destroy(&axq_local.axq_local_lock);
- rw_destroy(&axq_array_lock);
-
- (void) callb_delete(axq_panic_cb_id);
-
- return (0);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-static int
-axq_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
-{
- int instance;
- struct axq_soft_state *softsp;
- ddi_device_acc_attr_t attr;
- extern uint64_t va_to_pa(void *);
-
- instance = ddi_get_instance(devi);
-
- switch (cmd) {
- case DDI_ATTACH:
- break;
-
- case DDI_RESUME:
- /*
- * Reenable the axq io pause if it is
- * employed. See the DDI_SUSPEND comments
- */
- softsp = ddi_get_soft_state(axq_softp, instance);
- if (softsp->slotnum && softsp->paused && use_axq_iopause &&
- axq_suspend_iopause) {
- *softsp->axq_domain_ctrl &= ~AXQ_DOMCTRL_PAUSE;
- softsp->paused = 0;
- }
- return (DDI_SUCCESS);
-
- default:
- return (DDI_FAILURE);
- }
-
- if (ddi_soft_state_zalloc(axq_softp, instance) != DDI_SUCCESS)
- return (DDI_FAILURE);
-
- softsp = ddi_get_soft_state(axq_softp, instance);
-
- /* Set the dip in the soft state */
- softsp->dip = devi;
-
- /* Get the "portid" property */
- if ((softsp->portid = (int)ddi_getprop(DDI_DEV_T_ANY, softsp->dip,
- DDI_PROP_DONTPASS, "portid", -1)) == -1) {
- cmn_err(CE_WARN, "Unable to retrieve safari portid"
- "property.");
- goto bad;
- }
-
- softsp->expid = softsp->portid >> 5;
-
- /*
- * derive the slot # from the portid - for starcat, it is
- * either 0 or 1 based on the lsb of the axq portid.
- */
- softsp->slotnum = softsp->portid & 0x1;
-
- /*
- * map in the regs. There are two regspecs - one
- * in safari config space and the other in local space.
- */
- attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
- attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
- attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
- if (ddi_regs_map_setup(softsp->dip, 0, &softsp->address, 0, 0,
- &attr, &softsp->ac0) != DDI_SUCCESS) {
- cmn_err(CE_WARN, "%s%d: unable to map reg set 0\n",
- ddi_get_name(softsp->dip),
- ddi_get_instance(softsp->dip));
- goto bad;
- }
-
- /*
- * This is a hack for support DR copy rename scripting
- * Get the physical address of the start of the
- * AXQ config space and save it.
- */
- softsp->axq_phyaddr = va_to_pa((caddr_t)softsp->address);
-
- axq_init(softsp);
-
- /*
- * Map in the regs for local space access
- * This is global for all axq instances.
- * Make sure that some axq instance does
- * it for the rest of the gang..
- * Note that this mapping is never removed.
- */
- mutex_enter(&axq_local.axq_local_lock);
- if (!axq_local.initflag) {
- /* initialize and map in the local space */
- if (ddi_regs_map_setup(softsp->dip, 1,
- &axq_local.laddress, 0, 0,
- &attr, &axq_local.ac) != DDI_SUCCESS) {
- cmn_err(CE_WARN, "%s%d: unable to map reg set 1\n",
- ddi_get_name(softsp->dip),
- ddi_get_instance(softsp->dip));
- ddi_regs_map_free(&softsp->ac0);
- mutex_exit(&axq_local.axq_local_lock);
- goto bad;
- }
- axq_init_local(&axq_local);
- axq_local.initflag = 1;
- }
- mutex_exit(&axq_local.axq_local_lock);
-
- mutex_init(&softsp->axq_lock, NULL, MUTEX_DRIVER, NULL);
-
- /* update the axq array for this new instance */
- rw_enter(&axq_array_lock, RW_WRITER);
- ASSERT(axq_array[softsp->expid][softsp->slotnum] == NULL);
- axq_array[softsp->expid][softsp->slotnum] = softsp;
- rw_exit(&axq_array_lock);
-
- axq_add_kstats(softsp);
-
- ddi_report_dev(devi);
-
- return (DDI_SUCCESS);
-
-bad:
- ddi_soft_state_free(axq_softp, instance);
- return (DDI_FAILURE);
-}
-
-
-static void
-axq_init(struct axq_soft_state *softsp)
-{
- int i;
-
- /*
- * Setup the AXQ registers
- * Some offsets and availability are dependent on the slot type
- */
- if (softsp->slotnum == 0) {
- /* This is a slot type 0 AXQ */
- softsp->axq_domain_ctrl = REG_ADDR(softsp->address,
- AXQ_SLOT0_DOMCTRL);
- softsp->axq_cdc_addrtest = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_ADR_TEST);
- softsp->axq_cdc_ctrltest = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_CTL_TEST);
- softsp->axq_cdc_datawrite0 = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_DATA_WR0);
- softsp->axq_cdc_datawrite1 = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_DATA_WR1);
- softsp->axq_cdc_datawrite2 = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_DATA_WR2);
- softsp->axq_cdc_datawrite3 = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_DATA_WR3);
- softsp->axq_cdc_counter = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_CNT_TEST);
- softsp->axq_cdc_readdata0 = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_RD_DATA0);
- softsp->axq_cdc_readdata1 = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_RD_DATA1);
- softsp->axq_cdc_readdata2 = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_RD_DATA2);
- softsp->axq_cdc_readdata3 = REG_ADDR(softsp->address,
- AXQ_SLOT0_CDC_RD_DATA3);
- softsp->axq_pcr = REG_ADDR(softsp->address,
- AXQ_SLOT0_PERFCNT_SEL);
- softsp->axq_pic0 = REG_ADDR(softsp->address,
- AXQ_SLOT0_PERFCNT0);
- softsp->axq_pic1 = REG_ADDR(softsp->address,
- AXQ_SLOT0_PERFCNT1);
- softsp->axq_pic2 = REG_ADDR(softsp->address,
- AXQ_SLOT0_PERFCNT2);
- softsp->axq_nasm = REG_ADDR(softsp->address, AXQ_SLOT0_NASM);
- } else {
- /* slot type 1 AXQ */
- softsp->axq_domain_ctrl = REG_ADDR(softsp->address,
- AXQ_SLOT1_DOMCTRL);
- softsp->axq_pcr = REG_ADDR(softsp->address,
- AXQ_SLOT1_PERFCNT_SEL);
- softsp->axq_pic0 = REG_ADDR(softsp->address,
- AXQ_SLOT1_PERFCNT0);
- softsp->axq_pic1 = REG_ADDR(softsp->address,
- AXQ_SLOT1_PERFCNT1);
- softsp->axq_pic2 = REG_ADDR(softsp->address,
- AXQ_SLOT1_PERFCNT2);
- softsp->axq_nasm = REG_ADDR(softsp->address, AXQ_SLOT1_NASM);
- }
-
- /* setup CASM slots */
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- softsp->axq_casm_slot[i] = REG_ADDR(softsp->address,
- (AXQ_CASM_SLOT_START + AXQ_REGOFF(i)));
- }
-
- /* setup SDI timeout register accesses */
- softsp->axq_sdi_timeout_rd = REG_ADDR(softsp->address,
- AXQ_SLOT_SDI_TIMEOUT_RD);
- softsp->axq_sdi_timeout_rdclr = REG_ADDR(softsp->address,
- AXQ_SLOT_SDI_TIMEOUT_RDCLR);
-
- /*
- * Save the CDC state (enabled or disabled)
- * as originally setup by Post.
- */
- if (softsp->slotnum == 0) {
- softsp->axq_cdc_state = *softsp->axq_cdc_ctrltest &
- AXQ_CDC_DIS;
- }
-
-#ifndef _AXQ_LOCAL_ACCESS_SUPPORTED
- /*
- * Setup cpu2ssc intr register in explicit expander
- * space. Local space addressing for this is broken,
- * we'll use explicit addressing for now.
- */
- softsp->axq_cpu2ssc_intr = REG_ADDR(softsp->address,
- AXQ_SLOT_CPU2SSC_INTR);
-#endif /* _AXQ_LOCAL_ACCESS_SUPPORTED */
-}
-
-
-static void
-axq_init_local(struct axq_local_regs *localregs)
-{
- /*
- * local access to cpu2ssc intr register will
- * be the only one that may work properly in the
- * next revision of the AXQ asics.
- * Set it up here for now.
- */
- localregs->axq_cpu2ssc_intr = REG_ADDR(localregs->laddress,
- AXQ_SLOT_CPU2SSC_INTR);
-}
-
-/* ARGSUSED */
-static int
-axq_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
-{
- int instance;
- int i;
- struct axq_soft_state *softsp;
- processorid_t cpuid;
-
- /* get the instance of this devi */
- instance = ddi_get_instance(devi);
-
- /* get the soft state pointer for this device node */
- softsp = ddi_get_soft_state(axq_softp, instance);
-
- switch (cmd) {
- case DDI_SUSPEND:
- /*
- * Depending on the variable "use_axq_iopause"
- * we set the axq iopause bit as a paranoid
- * safety net. This is assuming all the devices
- * associated with the slot are already suspended.
- * Care must be taken to not set iopause when CPUs
- * are known to be present on the slot 1 board,
- * i.e. MCPU board type.
- * This io pause bit only applies to slot 1 axq,
- */
- if (softsp->slotnum && use_axq_iopause && axq_suspend_iopause) {
- /*
- * Do not enable AXQ_DOMCTRL_PAUSE if CPUs are
- * known to be present in slot 1.
- */
- mutex_enter(&cpu_lock);
- for (i = 0; i < STARCAT_SLOT1_CPU_MAX; i++) {
- cpuid = MAKE_CPUID(softsp->expid,
- softsp->slotnum, i);
- if (cpu[cpuid]) {
- mutex_exit(&cpu_lock);
- return (DDI_SUCCESS);
- }
- }
- mutex_exit(&cpu_lock);
-
- /*
- * Make sure that there is no outstanding
- * I/O activity by reading the domain ctrl reg.
- * A non-zero lsb indicates no I/O activity.
- */
- if (axq_slot1_idle(softsp) == DDI_FAILURE) {
- cmn_err(CE_WARN, "%s%d: busy! suspend failed",
- ddi_get_name(softsp->dip),
- ddi_get_instance(softsp->dip));
- return (DDI_FAILURE);
- }
-
- *softsp->axq_domain_ctrl |= AXQ_DOMCTRL_PAUSE;
- softsp->paused = 1;
- }
- return (DDI_SUCCESS);
-
- case DDI_DETACH:
- rw_enter(&axq_array_lock, RW_WRITER);
- ASSERT(axq_array[softsp->expid][softsp->slotnum]
- != NULL);
- axq_array[softsp->expid][softsp->slotnum] = NULL;
- rw_exit(&axq_array_lock);
-
- ddi_regs_map_free(&softsp->ac0);
-
- /*
- * remove counter kstats for this device
- */
- if (softsp->axq_counters_ksp != (kstat_t *)NULL) {
- kstat_delete(softsp->axq_counters_ksp);
- }
-
- /*
- * See if we are the last instance to detach.
- * If so, we need to remove the picN kstats
- */
- mutex_enter(&axq_attachcnt_lock);
- if (--axq_attachcnt == 0) {
- for (i = 0; i < AXQ_NUM_PICS; i++) {
- if (axq_picN_ksp[i] != (kstat_t *)NULL) {
- kstat_delete(axq_picN_ksp[i]);
- axq_picN_ksp[i] = NULL;
- }
- }
- }
- mutex_exit(&axq_attachcnt_lock);
-
- ddi_soft_state_free(axq_softp, instance);
-
- return (DDI_SUCCESS);
- default:
- return (DDI_FAILURE);
- }
-}
-
-
-/* ARGSUSED0 */
-static int
-axq_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
-{
- dev_t dev = (dev_t)arg;
- struct axq_soft_state *softsp;
- int instance, ret;
-
- instance = getminor(dev);
-
- switch (infocmd) {
- case DDI_INFO_DEVT2DEVINFO:
- softsp = (struct axq_soft_state *)
- ddi_get_soft_state(axq_softp, instance);
- if (softsp == NULL) {
- ret = DDI_FAILURE;
- } else {
- *result = softsp->dip;
- ret = DDI_SUCCESS;
- }
- break;
- case DDI_INFO_DEVT2INSTANCE:
- *result = (void *)(uintptr_t)instance;
- ret = DDI_SUCCESS;
- break;
- default:
- ret = DDI_FAILURE;
- break;
- }
- return (ret);
-}
-
-/*
- * Flush the CDC Sram of the slot0 axq
- * indicated by the expid argument
- */
-int
-axq_cdc_flush(uint32_t expid, int held, int disabled)
-{
- struct axq_soft_state *softsp;
- uint32_t axq_ctrl_test_save0;
- uint32_t tmpval;
- int retval = 0;
- int i;
-
- if (!held)
- rw_enter(&axq_array_lock, RW_READER);
-
- ASSERT(axq_array[expid][SLOT0_AXQ] != NULL);
-
- softsp = axq_array[expid][SLOT0_AXQ];
-
- mutex_enter(&softsp->axq_lock);
-
- /* save the value of the ctrl test reg */
- axq_ctrl_test_save0 = *softsp->axq_cdc_ctrltest;
-
- /* disable sram and setup the ctrl test reg for flushing */
- tmpval = axq_ctrl_test_save0 & (AXQ_CDC_DATA_ECC_CHK_EN |
- AXQ_CDC_ADR_PAR_CHK_EN |
- AXQ_CDC_DATA_ECC_GEN_EN |
- AXQ_CDC_ADR_PAR_GEN_EN);
- *softsp->axq_cdc_ctrltest = tmpval | AXQ_CDC_TMODE_WR
- | AXQ_CDC_DATA2PAR_MUX_SEL_DATA
- | AXQ_CDC_ADR2SRAM_MUX_SEL_TEST
- | AXQ_CDC_ADR_INCR_XOR_CTRL
- | AXQ_CDC_DIS;
-
- /* Enable CDC test in the CDC Address test reg */
- *softsp->axq_cdc_addrtest = AXQ_CDC_ADR_TEST_EN;
-
- /* clear the CDC Data write regs */
- *softsp->axq_cdc_datawrite0 = *softsp->axq_cdc_datawrite1 = 0;
- *softsp->axq_cdc_datawrite2 = *softsp->axq_cdc_datawrite3 = 0;
-
- /*
- * write in the size of the sram to clear
- * into the CDC Counter test reg
- */
- *softsp->axq_cdc_counter = AXQ_CDC_SRAM_SIZE;
-
- /* wait for flush to complete */
- for (i = 0; i < AXQ_CDC_FLUSH_WAIT; i++) {
- DELAY(3000); /* should take only 1750 usecs */
- if (((*softsp->axq_cdc_counter) &
- AXQ_CDC_CNT_TEST_DONE) != 0) {
- break;
- }
- }
- if (i >= AXQ_CDC_FLUSH_WAIT) {
- retval = DDI_FAILURE;
- cmn_err(CE_WARN, "axq_cdc_flush failed on expander %d",
- expid);
- }
-
- /*
- * Disable test mode in CDC address test reg
- */
- *softsp->axq_cdc_addrtest = 0;
-
- /*
- * If "disabled" option is requested, leave
- * the CDC disabled.
- */
- if (disabled) {
- axq_ctrl_test_save0 |= AXQ_CDC_DIS;
- *softsp->axq_cdc_ctrltest = axq_ctrl_test_save0;
- } else {
- *softsp->axq_cdc_ctrltest = axq_ctrl_test_save0;
- }
-
- mutex_exit(&softsp->axq_lock);
-
- if (!held)
- rw_exit(&axq_array_lock);
-
- return (retval);
-}
-
-
-/*
- * Flush all the CDC srams for all the AXQs in
- * the local domain.
- */
-int
-axq_cdc_flush_all()
-{
- int retval;
- int i;
-
- rw_enter(&axq_array_lock, RW_READER);
-
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- if (axq_array[i][SLOT0_AXQ] != NULL) {
- retval = axq_cdc_flush(i, 1, 0);
- if (retval != DDI_SUCCESS) break;
- }
- }
- rw_exit(&axq_array_lock);
- return (retval);
-}
-
-/*
- * Disable and flush all CDC srams for all the AXQs
- * in the local domain.
- */
-int
-axq_cdc_disable_flush_all()
-{
- int retval;
- int i;
-
- rw_enter(&axq_array_lock, RW_READER);
-
- /*
- * Disable and flush all the CDC srams
- */
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- if (axq_array[i][SLOT0_AXQ] != NULL) {
- retval = axq_cdc_flush(i, 1, 1);
- if (retval != DDI_SUCCESS) break;
- }
- }
- rw_exit(&axq_array_lock);
-
- if (retval != DDI_SUCCESS) {
- axq_cdc_enable_all();
- }
- return (retval);
-}
-
-
-/*
- * Enable the CDC srams for all the AXQs in the
- * the local domain. This routine is used in
- * conjunction with axq_cdc_disable_flush_all().
- */
-void
-axq_cdc_enable_all()
-{
- struct axq_soft_state *softsp;
- int i;
-
- rw_enter(&axq_array_lock, RW_READER);
-
- /*
- * Enable all the CDC sram
- */
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- if ((softsp = axq_array[i][SLOT0_AXQ]) != NULL) {
- mutex_enter(&softsp->axq_lock);
- if (softsp->axq_cdc_state != AXQ_CDC_DIS) {
- *softsp->axq_cdc_ctrltest &= ~AXQ_CDC_DIS;
- }
- mutex_exit(&softsp->axq_lock);
- }
- }
- rw_exit(&axq_array_lock);
-}
-
-/*
- * Interface for DR to enable slot1 iopause after cpus have been idled.
- * Precondition is for all devices to have been suspended (including axq).
- * This routine avoids locks as it is called by DR with cpus paused.
- */
-int
-axq_iopause_enable_all(uint32_t *errexp)
-{
- int i, j;
- int retval = DDI_SUCCESS;
- processorid_t cpuid;
- struct axq_soft_state *softsp;
-
- DELAY(1000);
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- if ((softsp = axq_array[i][SLOT1_AXQ]) != NULL &&
- use_axq_iopause) {
- /*
- * Do not enable if cpus configured in slot1.
- * Unconfigured cpus should be idle in nc space.
- */
- for (j = 0; j < STARCAT_SLOT1_CPU_MAX; j++) {
- cpuid = MAKE_CPUID(softsp->expid,
- softsp->slotnum, j);
- if (cpu[cpuid]) {
- break;
- }
- }
- if (j < STARCAT_SLOT1_CPU_MAX) {
- continue;
- }
-
- retval = axq_slot1_idle(softsp);
- if (retval == DDI_FAILURE) {
- break;
- }
-
- *softsp->axq_domain_ctrl |= AXQ_DOMCTRL_PAUSE;
- softsp->paused = 1;
- }
- }
-
- if (retval != DDI_SUCCESS) {
- ASSERT(errexp);
- *errexp = i;
- axq_iopause_disable_all();
- }
- return (retval);
-}
-
-/*
- * De-assert axq iopause on all slot1 boards. This routine avoids locks
- * as it is called by DR with cpus paused.
- */
-void
-axq_iopause_disable_all()
-{
- int i;
- struct axq_soft_state *softsp;
-
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- if ((softsp = axq_array[i][SLOT1_AXQ]) != NULL &&
- softsp->paused) {
- *softsp->axq_domain_ctrl &= ~AXQ_DOMCTRL_PAUSE;
- softsp->paused = 0;
- }
- }
-}
-
-/*
- * Attempt to wait for slot1 activity to go idle.
- */
-static int
-axq_slot1_idle(struct axq_soft_state *softsp)
-{
- int i;
-
- ASSERT(softsp->slotnum == SLOT1_AXQ);
- for (i = 0; i < 10; i++) {
- if ((*(softsp->axq_domain_ctrl) & AXQ_DOMCTRL_BUSY) != 0) {
- return (DDI_SUCCESS);
- }
- DELAY(50);
- }
- return (DDI_FAILURE);
-}
-
-/*
- * Read a particular NASM entry
- */
-int
-axq_nasm_read(uint32_t expid, uint32_t slot, uint32_t nasm_entry,
- uint32_t *data)
-{
- axq_nasm_read_u aread;
- axq_nasm_write_u awrite;
- struct axq_soft_state *softsp;
-
- if (slot > AXQ_MAX_SLOT_PER_EXP ||
- expid > AXQ_MAX_EXP ||
- nasm_entry > AXQ_NASM_SIZE) {
- return (DDI_FAILURE);
- }
-
- awrite.bit.rw = 0; /* read operation */
- awrite.bit.addr = nasm_entry;
- awrite.bit.data = 0;
-
- rw_enter(&axq_array_lock, RW_READER);
-
- softsp = axq_array[expid][slot];
- if (softsp == NULL) {
- rw_exit(&axq_array_lock);
- return (DDI_FAILURE);
- }
-
- mutex_enter(&softsp->axq_lock);
-
- *(softsp->axq_nasm) = awrite.val;
- aread.val = *(softsp->axq_nasm);
-
- mutex_exit(&softsp->axq_lock);
- rw_exit(&axq_array_lock);
-
- if (aread.bit.valid) {
- *data = aread.bit.data;
- return (DDI_SUCCESS);
- }
- return (DDI_FAILURE);
-}
-
-/*
- * Write a particular NASM entry
- */
-static int
-axq_nasm_write_one(uint32_t expid, uint32_t slot, uint32_t nasm_entry,
- uint32_t data)
-{
- axq_nasm_write_u awrite;
- struct axq_soft_state *softsp;
-
- /*
- * Note: need to make sure axq_array_lock held first, so that a
- * paused thread is not holding softsp->axq_lock, which could
- * result in deadlock.
- */
- ASSERT(RW_LOCK_HELD(&axq_array_lock));
-
- if (slot > AXQ_MAX_SLOT_PER_EXP ||
- expid > AXQ_MAX_EXP ||
- nasm_entry > AXQ_NASM_SIZE) {
- return (DDI_FAILURE);
- }
-
- awrite.bit.rw = 1; /* write operation */
- awrite.bit.addr = nasm_entry;
- awrite.bit.data = data;
-
- softsp = axq_array[expid][slot];
- if (softsp == NULL) {
- return (DDI_FAILURE);
- }
-
- mutex_enter(&softsp->axq_lock);
-
- *(softsp->axq_nasm) = awrite.val;
-
- mutex_exit(&softsp->axq_lock);
-
- return (DDI_SUCCESS);
-}
-
-int
-axq_nasm_write(uint32_t expid, uint32_t slot, uint32_t nasm_entry,
- uint32_t data)
-{
- int rc;
-
- rw_enter(&axq_array_lock, RW_READER);
- rc = axq_nasm_write_one(expid, slot, nasm_entry, data);
- rw_exit(&axq_array_lock);
- return (rc);
-}
-
-/*
- * Write a particular NASM entry for all the
- * axqs in the domain
- * Note: other CPUs are paused when this function called.
- */
-int
-axq_nasm_write_all(uint32_t nasm_entry, uint32_t data)
-{
- int i;
- int rc;
-
- ASSERT(RW_WRITE_HELD(&axq_array_lock));
-
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- if (axq_array[i][SLOT0_AXQ] != NULL) {
- rc = axq_nasm_write_one(i, SLOT0_AXQ, nasm_entry,
- data);
- if (rc != DDI_SUCCESS) {
- return (DDI_FAILURE);
- }
- }
- if (axq_array[i][SLOT1_AXQ] != NULL) {
- rc = axq_nasm_write_one(i, SLOT1_AXQ, nasm_entry,
- data);
- if (rc != DDI_SUCCESS) {
- return (DDI_FAILURE);
- }
- }
- }
-
- return (DDI_SUCCESS);
-}
-
-/*
- * Take write lock for axq_nasm_write_all() outside
- * critical section where other CPUs are paused.
- */
-void
-axq_array_rw_enter(void)
-{
- rw_enter(&axq_array_lock, RW_WRITER);
-}
-
-/*
- * Release write lock for axq_nasm_write_all() outside
- * critical section where other CPUs are paused.
- */
-void
-axq_array_rw_exit(void)
-{
- rw_exit(&axq_array_lock);
-}
-
-/*
- * Read a particular CASM entry
- */
-uint32_t
-axq_casm_read(uint32_t expid, uint32_t slot, int casmslot)
-{
- struct axq_soft_state *softsp;
- uint32_t retval;
-
- rw_enter(&axq_array_lock, RW_READER);
-
- ASSERT(axq_array[expid][slot] != NULL);
- ASSERT(casmslot >= 0 && casmslot < AXQ_MAX_EXP);
-
- softsp = axq_array[expid][slot];
-
- mutex_enter(&softsp->axq_lock);
-
- retval = *(softsp->axq_casm_slot[casmslot]);
-
- mutex_exit(&softsp->axq_lock);
- rw_exit(&axq_array_lock);
-
- return (retval);
-}
-
-
-/*
- * Write a particular CASM entry
- */
-
-int
-axq_casm_write(uint32_t expid, uint32_t slot, int casmslot,
- uint32_t value)
-{
- struct axq_soft_state *softsp;
- int retval;
-
- rw_enter(&axq_array_lock, RW_READER);
-
- ASSERT(axq_array[expid][slot] != NULL);
- ASSERT(casmslot >= 0 && casmslot < AXQ_MAX_EXP);
-
- softsp = axq_array[expid][slot];
-
- mutex_enter(&softsp->axq_lock);
-
- /*
- * first read the casm slot in question
- * it should be non-zero to indicate that
- * we have write permission to update it.
- * Note that if we write it without valid
- * permission, we can get an exception.
- */
- if (*(softsp->axq_casm_slot[casmslot])) {
- *(softsp->axq_casm_slot[casmslot]) = value;
- retval = DDI_SUCCESS;
- } else {
- retval = DDI_FAILURE;
- }
-
- mutex_exit(&softsp->axq_lock);
- rw_exit(&axq_array_lock);
- return (retval);
-}
-
-/*
- * Write a particular CASM entry for all the
- * axqs in the domain
- */
-
-int
-axq_casm_write_all(int casmslot, uint32_t value)
-{
- int i;
- struct axq_soft_state *softsp;
-
- /*
- * Since we are updating all the AXQs,
- * it will be easier to simply grab
- * exclusive access to the AXQs by obtaining
- * the RW_WRITER access to the axq_array.
- */
- rw_enter(&axq_array_lock, RW_WRITER);
-
- /*
- * Paranoid check: run thru all the avail AXQs
- * and make sure we can write into that slot in question
- * We check it by reading the slot and it should be
- * non-zero.
- */
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- if ((softsp = axq_array[i][SLOT0_AXQ]) != NULL) {
- if (*(softsp->axq_casm_slot[casmslot])
- == 0) {
- break;
- }
- }
- if ((softsp = axq_array[i][SLOT1_AXQ]) != NULL) {
- if (*(softsp->axq_casm_slot[casmslot])
- == 0) {
- break;
- }
- }
- }
-
- if (i < AXQ_MAX_EXP) {
- /*
- * We have no write permission for some AXQ
- * for the CASM slot in question. Flag it
- * as an error
- */
- rw_exit(&axq_array_lock);
- return (DDI_FAILURE);
- }
-
- /*
- * everything looks good - do the update
- */
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- if ((softsp = axq_array[i][SLOT0_AXQ]) != NULL) {
- *softsp->axq_casm_slot[casmslot] = value;
- }
- if ((softsp = axq_array[i][SLOT1_AXQ]) != NULL) {
- *softsp->axq_casm_slot[casmslot] = value;
- }
- }
-
- rw_exit(&axq_array_lock);
- return (DDI_SUCCESS);
-}
-
-
-/*
- * Construct a script of <physicaladdr, data> tuple pairs that
- * reprogram the all the AXQs in the local domain to swap the
- * contents of casmslot0 with casmslot1.
- */
-int
-axq_do_casm_rename_script(uint64_t **script_elm, int casmslot0,
- int casmslot1)
-{
- struct axq_soft_state *softsp;
- int i, slot;
- uint32_t val0, val1;
- uint64_t *s_elm = *script_elm;
- uint64_t paddr;
-
- /*
- * There should be some global locking at the
- * DR level to do this - since this is one of
- * the sequence of steps in copyrename.
- * For now, we grab the RW_WRITER lock for
- * script construction.
- */
- rw_enter(&axq_array_lock, RW_WRITER);
-
- /*
- * Construct the <physicaladdr, data> tuple pairs
- * for reprogramming the AXQs so that the value in
- * casmslot0 is swapped with the content in casmslot1.
- * Paranoid check: We make sure that we can write to
- * both slots in all the AXQs by reading the slots and
- * they should be non-zero.
- */
- for (slot = SLOT0_AXQ; slot <= SLOT1_AXQ; slot++) {
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- if ((softsp = axq_array[i][slot]) != NULL) {
- paddr = softsp->axq_phyaddr;
- val0 = *(softsp->axq_casm_slot[casmslot0]);
- val1 = *(softsp->axq_casm_slot[casmslot1]);
- if (val0 != 0 && val1 != 0) {
- *s_elm++ = paddr + AXQ_CASM_SLOT_START +
- AXQ_REGOFF(casmslot0);
- *s_elm++ = val1;
- *s_elm++ = paddr + AXQ_CASM_SLOT_START +
- AXQ_REGOFF(casmslot1);
- *s_elm++ = val0;
- } else {
- /*
- * Somehow we can't access one of
- * the casm slot - quit.
- */
- break;
- }
- }
- }
- if (i < AXQ_MAX_EXP) break;
- }
-
- rw_exit(&axq_array_lock);
-
- if (slot > SLOT1_AXQ) {
- /* successful */
- *script_elm = s_elm;
- return (DDI_SUCCESS);
- } else {
- return (DDI_FAILURE);
- }
-}
-
-
-/*
- * Send an interrupt to the SSC passing
- * a 8 bit cookie value
- */
-int
-axq_cpu2ssc_intr(uint8_t cookie)
-{
- int retval, i;
- volatile uint32_t *intr_reg;
-
-#ifndef _AXQ_LOCAL_SPACE_SUPPORTED
- /* Local space access not available */
-
- int exp, slot;
-
- rw_enter(&axq_array_lock, RW_READER);
-
- /* Make sure the current cpu is not switched out */
- kpreempt_disable();
-
- /*
- * Compute the exp# and slot# of the current cpu
- * so that we know which AXQ cpu2ssc intr reg to
- * use.
- */
- exp = CPU->cpu_id >> 5;
- slot = (CPU->cpu_id >> 3) & 0x1;
-
- intr_reg = axq_array[exp][slot]->axq_cpu2ssc_intr;
-#else
- /* use local space */
- intr_reg = axq_local.axq_cpu2ssc_intr;
-#endif /* _AXQ_LOCAL_SPACE_SUPPORTED */
-
- ASSERT(intr_reg != 0);
-
- retval = DDI_FAILURE;
- for (i = 0; i < AXQ_INTR_PEND_WAIT; i++) {
- if (!(*intr_reg & AXQ_CPU2SSC_INTR_PEND)) {
- *intr_reg = cookie;
- retval = DDI_SUCCESS;
- break;
- }
- DELAY(200);
- }
-
-#ifndef _AXQ_LOCAL_SPACE_SUPPORTED
- kpreempt_enable();
- rw_exit(&axq_array_lock);
-#endif
- return (retval);
-}
-
-
-/*
- * Read the SDI timeout register (SRD use)
- * This routine accepts a clear flag to indicate
- * whether the register should be cleared after
- * the read.
- */
-uint32_t
-axq_read_sdi_timeout_reg(uint32_t expid, uint32_t slot, int clearflag)
-{
- struct axq_soft_state *softsp;
- uint32_t retval;
-
- rw_enter(&axq_array_lock, RW_READER);
-
- ASSERT(axq_array[expid][slot] != NULL);
-
- softsp = axq_array[expid][slot];
-
- mutex_enter(&softsp->axq_lock);
-
- if (clearflag) {
- /* read and then clear register */
- retval = *softsp->axq_sdi_timeout_rdclr;
- } else {
- retval = *softsp->axq_sdi_timeout_rd;
- }
-
- mutex_exit(&softsp->axq_lock);
- rw_exit(&axq_array_lock);
-
- return (retval);
-}
-
-
-/*
- * Routine to create a kstat for each %pic that
- * the AXQ has (there are 3 of them). These read-only
- * kstats export event names that the respective %pic
- * supports. Pic0 and Pic1 are similar and they both have
- * a 128-input mux. Pic2 counts the clock and can set up
- * to count or freeze.
- * Note that all AXQ instances use the same events, we only
- * need to create one set of the picN kstats.
- */
-static void
-axq_add_picN_kstats(dev_info_t *dip)
-{
- struct kstat_named *axq_pic_named_data;
- int event, pic;
- int instance = ddi_get_instance(dip);
- int pic_shift = 0;
-
- /*
- * Create the picN kstat for Pic0 and Pic1
- * Both have similar set of events. Add one
- * extra event for the clear_event mask.
- */
- for (pic = 0; pic < AXQ_NUM_PICS; pic++) {
- char pic_name[20];
- int num_events, i;
-
- (void) sprintf(pic_name, "pic%d", pic);
-
- num_events = (pic <= 1) ? AXQ_PIC0_1_NUM_EVENTS :
- AXQ_PIC2_NUM_EVENTS;
-
- if ((axq_picN_ksp[pic] = kstat_create("axq",
- instance, pic_name, "bus", KSTAT_TYPE_NAMED,
- num_events + 1, NULL)) == NULL) {
- cmn_err(CE_WARN, "axq %s: kstat_create failed",
- pic_name);
-
- /* remove pic kstats that was created earlier */
- for (i = 0; i < pic; i++) {
- kstat_delete(axq_picN_ksp[i]);
- axq_picN_ksp[i] = NULL;
- }
- return;
- }
-
- axq_pic_named_data =
- (struct kstat_named *)(axq_picN_ksp[pic]->ks_data);
-
- pic_shift = pic * AXQ_PIC_SHIFT;
-
- /*
- * for each picN event, write a kstat record of
- * name = EVENT & value.ui64 = PCR_MASK.
- */
- for (event = 0; event < num_events; event++) {
- /* pcr_mask */
- axq_pic_named_data[event].value.ui64 =
- axq_events[event].pcr_mask << pic_shift;
-
- /* event name */
- kstat_named_init(&axq_pic_named_data[event],
- axq_events[event].event_name,
- KSTAT_DATA_UINT64);
- }
-
- /*
- * Add the clear pic event and mask as the last
- * record in the kstat.
- */
- axq_pic_named_data[num_events].value.ui64 =
- (uint32_t)~(AXQ_PIC_CLEAR_MASK << pic_shift);
-
- kstat_named_init(&axq_pic_named_data[num_events],
- "clear_pic", KSTAT_DATA_UINT64);
-
- kstat_install(axq_picN_ksp[pic]);
- }
-}
-
-
-static void
-axq_add_kstats(struct axq_soft_state *softsp)
-{
- struct kstat *axq_counters_ksp;
- struct kstat_named *axq_counters_named_data;
-
- /*
- * Create the picN kstats if we are the first instance
- * to attach. We use axq_attachcnt as a count of how
- * many instances have attached. This is protected by
- * a lock.
- */
- mutex_enter(&axq_attachcnt_lock);
- if (axq_attachcnt++ == 0)
- axq_add_picN_kstats(softsp->dip);
-
- mutex_exit(&axq_attachcnt_lock);
-
- /*
- * A "counter" kstat is created for each axq
- * instance that provides access to the %pcr and %pic
- * registers for that instance.
- *
- * The size of this kstat is AXQ_NUM_PICS + 1 for %pcr
- */
- if ((axq_counters_ksp = kstat_create("axq",
- ddi_get_instance(softsp->dip), "counters",
- "bus", KSTAT_TYPE_NAMED, AXQ_NUM_PICS + 1,
- KSTAT_FLAG_WRITABLE)) == NULL) {
- cmn_err(CE_WARN, "axq%d counters: kstat_create"
- " failed", ddi_get_instance(softsp->dip));
- return;
- }
-
- axq_counters_named_data =
- (struct kstat_named *)(axq_counters_ksp->ks_data);
-
- /* initialize the named kstats */
- kstat_named_init(&axq_counters_named_data[0],
- "pcr", KSTAT_DATA_UINT32);
-
- kstat_named_init(&axq_counters_named_data[1],
- "pic0", KSTAT_DATA_UINT32);
-
- kstat_named_init(&axq_counters_named_data[2],
- "pic1", KSTAT_DATA_UINT32);
-
- kstat_named_init(&axq_counters_named_data[3],
- "pic2", KSTAT_DATA_UINT32);
-
- axq_counters_ksp->ks_update = axq_counters_kstat_update;
- axq_counters_ksp->ks_private = (void *)softsp;
-
- kstat_install(axq_counters_ksp);
-
- /* update the softstate */
- softsp->axq_counters_ksp = axq_counters_ksp;
-}
-
-
-static int
-axq_counters_kstat_update(kstat_t *ksp, int rw)
-{
- struct kstat_named *axq_counters_data;
- struct axq_soft_state *softsp;
-
- axq_counters_data = (struct kstat_named *)ksp->ks_data;
- softsp = (struct axq_soft_state *)ksp->ks_private;
-
- if (rw == KSTAT_WRITE) {
- /*
- * Write the pcr value to the softsp->axq_pcr.
- * The pic register is read-only so we don't
- * attempt to write to it.
- */
- *softsp->axq_pcr = (uint32_t)axq_counters_data[0].value.ui64;
- } else {
- /*
- * Read %pcr and %pic register values and write them
- * into counters kstat.
- *
- */
-
- /* pcr */
- axq_counters_data[0].value.ui64 = (uint64_t)
- (*softsp->axq_pcr);
-
- /* pic0 */
- axq_counters_data[1].value.ui64 = (uint64_t)
- (*softsp->axq_pic0);
-
- /* pic1 */
- axq_counters_data[2].value.ui64 = (uint64_t)
- *softsp->axq_pic1;
-
- /* pic2 */
- axq_counters_data[3].value.ui64 = (uint64_t)
- *softsp->axq_pic2;
- }
- return (0);
-}
-
-struct gptwo_phys_spec {
- uint_t gptwo_phys_hi; /* child's address, hi word */
- uint_t gptwo_phys_low; /* child's address, low word */
- uint_t gptwo_size_hi; /* high word of size field */
- uint_t gptwo_size_low; /* low word of size field */
-};
-
-int axq_pio_workaround_disable = 0;
-int axq_pio_limit = 3;
-
-int
-starcat_axq_pio_workaround(dev_info_t *dip)
-{
- dev_info_t *axq_dip, *cdip, *pdip;
- int portid, axq_portid;
- char *name;
- int size, circ;
- uint_t *base_addr, *io_domain_control_addr;
- int32_t io_domain_control;
- ddi_device_acc_attr_t acc;
- ddi_acc_handle_t handle;
- struct gptwo_phys_spec *gptwo_spec;
- struct regspec phys_spec;
-
- if (axq_pio_workaround_disable)
- return (0);
-
- /*
- * Get the portid for the PCI (Schizo) device).
- */
- if ((portid = ddi_getprop(DDI_DEV_T_ANY, dip, 0, "portid", -1)) < 0) {
- cmn_err(CE_WARN, "%s: no portid\n", ddi_get_name(dip));
- return (0);
- }
-
- /*
- * Calculate the portid for the Slot 1 AXQ. The portid for
- * Schizo 0 EEEEE11100
- * Schizo 1 EEEEE11101
- * AXQ 0 EEEEE11110
- * AXQ 1 EEEEE11111
- * where EEEEE is the 5 bit expander number. So the portid for
- * AXQ 1 can be easily calculated by oring a 3 to the portid of
- * Schizo 0 or 1.
- */
- axq_portid = portid | 3;
-
- /*
- * Look for AXQ nodes that have the portid we calculated.
- */
- axq_dip = NULL;
- pdip = ddi_root_node();
- ndi_devi_enter(pdip, &circ);
- for (cdip = ddi_get_child(pdip); cdip != NULL;
- cdip = ddi_get_next_sibling(cdip)) {
-
- if (ddi_getlongprop(DDI_DEV_T_ANY, cdip,
- DDI_PROP_DONTPASS, "name", (caddr_t)&name, &size)
- != DDI_PROP_SUCCESS) {
- continue;
- }
-
- if (strcmp(name, "address-extender-queue") != 0) {
- kmem_free(name, size);
- continue;
- }
-
- /*
- * Found an AXQ node.
- */
-
- kmem_free(name, size);
-
- portid = ddi_getprop(DDI_DEV_T_ANY, cdip, 0, "portid", -1);
-
- if (portid == axq_portid) {
-
- /*
- * We found the correct AXQ node.
- */
- ndi_hold_devi(cdip);
- axq_dip = cdip;
- break;
- }
- }
- ndi_devi_exit(pdip, circ);
-
- if (axq_dip == NULL) {
- cmn_err(CE_WARN, "can't find axq node with portid=0x%x\n",
- axq_portid);
- return (0);
- }
-
- if (ddi_getlongprop(DDI_DEV_T_ANY, axq_dip, DDI_PROP_DONTPASS, "reg",
- (caddr_t)&gptwo_spec, &size) != DDI_PROP_SUCCESS) {
- cmn_err(CE_WARN, "%s: no regspec\n", ddi_get_name(axq_dip));
- ndi_rele_devi(axq_dip);
- return (0);
- }
-
- phys_spec.regspec_bustype = gptwo_spec->gptwo_phys_hi;
- phys_spec.regspec_addr = gptwo_spec->gptwo_phys_low;
- phys_spec.regspec_size = gptwo_spec->gptwo_size_low;
-
- acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
- acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
- acc.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
-
- if (axq_map_phys(axq_dip, &phys_spec, (caddr_t *)&base_addr,
- &acc, &handle)) {
- cmn_err(CE_WARN, "%s: map phys failed\n",
- ddi_get_name(axq_dip));
- kmem_free(gptwo_spec, size);
- ndi_rele_devi(axq_dip);
- return (0);
- }
-
- kmem_free(gptwo_spec, size);
-
- io_domain_control_addr = REG_ADDR(base_addr, AXQ_SLOT1_DOMCTRL);
-
- if (ddi_peek32(axq_dip, (int32_t *)io_domain_control_addr,
- (int32_t *)&io_domain_control)) {
- cmn_err(CE_WARN, "%s: peek failed\n", ddi_get_name(axq_dip));
- ndi_rele_devi(axq_dip);
- return (0);
- }
-
- axq_unmap_phys(&handle);
-
- ndi_rele_devi(axq_dip);
-
- /*
- * If bit 6 of the IO Domain Control Register is a one,
- * then this AXQ version does not have the PIO Limit problem.
- */
- if (io_domain_control & AXQ_DOMCTRL_PIOFIX)
- return (0);
-
- return (axq_pio_limit);
-}
-
-static int
-axq_map_phys(dev_info_t *dip, struct regspec *phys_spec,
- caddr_t *addrp, ddi_device_acc_attr_t *accattrp,
- ddi_acc_handle_t *handlep)
-{
- ddi_map_req_t mr;
- ddi_acc_hdl_t *hp;
- int result;
- struct regspec *ph;
-
- *handlep = impl_acc_hdl_alloc(KM_SLEEP, NULL);
- hp = impl_acc_hdl_get(*handlep);
- hp->ah_vers = VERS_ACCHDL;
- hp->ah_dip = dip;
- hp->ah_rnumber = 0;
- hp->ah_offset = 0;
- hp->ah_len = 0;
- hp->ah_acc = *accattrp;
- ph = kmem_zalloc(sizeof (struct regspec), KM_SLEEP);
- *ph = *phys_spec;
- hp->ah_bus_private = ph; /* cache a copy of the reg spec */
-
- mr.map_op = DDI_MO_MAP_LOCKED;
- mr.map_type = DDI_MT_REGSPEC;
- mr.map_obj.rp = phys_spec;
- mr.map_prot = PROT_READ | PROT_WRITE;
- mr.map_flags = DDI_MF_KERNEL_MAPPING;
- mr.map_handlep = hp;
- mr.map_vers = DDI_MAP_VERSION;
-
- result = ddi_map(dip, &mr, 0, 0, addrp);
-
- if (result != DDI_SUCCESS) {
- impl_acc_hdl_free(*handlep);
- *handlep = NULL;
- } else {
- hp->ah_addr = *addrp;
- }
-
- return (result);
-}
-
-static void
-axq_unmap_phys(ddi_acc_handle_t *handlep)
-{
- ddi_map_req_t mr;
- ddi_acc_hdl_t *hp;
- struct regspec *ph;
-
- hp = impl_acc_hdl_get(*handlep);
- ASSERT(hp);
- ph = hp->ah_bus_private;
-
- mr.map_op = DDI_MO_UNMAP;
- mr.map_type = DDI_MT_REGSPEC;
- mr.map_obj.rp = ph;
- mr.map_prot = PROT_READ | PROT_WRITE;
- mr.map_flags = DDI_MF_KERNEL_MAPPING;
- mr.map_handlep = hp;
- mr.map_vers = DDI_MAP_VERSION;
-
- (void) ddi_map(hp->ah_dip, &mr, hp->ah_offset,
- hp->ah_len, &hp->ah_addr);
-
- impl_acc_hdl_free(*handlep);
- kmem_free(ph, sizeof (struct regspec)); /* Free the cached copy */
- *handlep = NULL;
-}
-
-/* ARGSUSED */
-static boolean_t
-axq_panic_callb(void *arg, int code)
-{
- axq_iopause_disable_all();
- return (B_TRUE);
-}
diff --git a/usr/src/uts/sun4u/starcat/io/cvc.c b/usr/src/uts/sun4u/starcat/io/cvc.c
deleted file mode 100644
index a6fe74807e..0000000000
--- a/usr/src/uts/sun4u/starcat/io/cvc.c
+++ /dev/null
@@ -1,1437 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-/*
- * MT STREAMS Virtual Console Device Driver
- */
-
-#include <sys/types.h>
-#include <sys/open.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/signal.h>
-#include <sys/cred.h>
-#include <sys/user.h>
-#include <sys/proc.h>
-#include <sys/disp.h>
-#include <sys/vnode.h>
-#include <sys/uio.h>
-#include <sys/buf.h>
-#include <sys/file.h>
-#include <sys/kmem.h>
-#include <sys/stat.h>
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#include <sys/strsubr.h>
-#include <sys/strsun.h>
-#include <sys/tty.h>
-#include <sys/ptyvar.h>
-#include <sys/poll.h>
-#include <sys/debug.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/errno.h>
-#include <sys/modctl.h>
-
-#include <sys/sc_cvc.h>
-#include <sys/sc_cvcio.h>
-#include <sys/iosramio.h>
-
-static int cvc_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
-static int cvc_attach(dev_info_t *, ddi_attach_cmd_t);
-static int cvc_detach(dev_info_t *, ddi_detach_cmd_t);
-static int cvc_open(register queue_t *, dev_t *, int, int, cred_t *);
-static int cvc_close(queue_t *, int, cred_t *);
-static int cvc_wput(queue_t *, mblk_t *);
-static int cvc_wsrv(queue_t *);
-static void cvc_ioctl(queue_t *, mblk_t *);
-static void cvc_reioctl(void *);
-static void cvc_input_daemon(void);
-static void cvc_send_to_iosram(mblk_t **chainpp);
-static void cvc_flush_queue(void *);
-static void cvc_iosram_ops(uint8_t);
-static void cvc_getstr(char *cp);
-static void cvc_win_resize(int clear_flag);
-
-#define ESUCCESS 0
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
-/*
- * Private copy of devinfo pointer; cvc_info uses it.
- */
-static dev_info_t *cvcdip;
-
-/*
- * This structure reflects the layout of data in CONI and CONO. If you are
- * going to add fields that don't get written into those chunks, be sure to
- * place them _after_ the buffer field.
- */
-typedef struct cvc_buf {
- ushort_t count;
- uchar_t buffer[MAX_XFER_COUTPUT];
-} cvc_buf_t;
-
-typedef struct cvc_s {
- bufcall_id_t cvc_wbufcid;
- tty_common_t cvc_tty;
-} cvc_t;
-
-cvc_t cvc_common_tty;
-
-static struct module_info cvcm_info = {
- 1313, /* mi_idnum Bad luck number ;-) */
- "cvc", /* mi_idname */
- 0, /* mi_minpsz */
- INFPSZ, /* mi_maxpsz */
- 2048, /* mi_hiwat */
- 2048 /* mi_lowat */
-};
-
-static struct qinit cvcrinit = {
- NULL, /* qi_putp */
- NULL, /* qi_srvp */
- cvc_open, /* qi_qopen */
- cvc_close, /* qi_qclose */
- NULL, /* qi_qadmin */
- &cvcm_info, /* qi_minfo */
- NULL /* qi_mstat */
-};
-
-static struct qinit cvcwinit = {
- cvc_wput, /* qi_putp */
- cvc_wsrv, /* qi_srvp */
- cvc_open, /* qi_qopen */
- cvc_close, /* qi_qclose */
- NULL, /* qi_qadmin */
- &cvcm_info, /* qi_minfo */
- NULL /* qi_mstat */
-};
-
-struct streamtab cvcinfo = {
- &cvcrinit, /* st_rdinit */
- &cvcwinit, /* st_wrinit */
- NULL, /* st_muxrinit */
- NULL /* st_muxwrinit */
-};
-
-static krwlock_t cvclock; /* lock protecting everything here */
-static queue_t *cvcinput_q; /* queue for console input */
-static queue_t *cvcoutput_q; /* queue for console output */
-static int cvc_instance = -1;
-static int cvc_stopped = 0;
-static int cvc_suspended = 0;
-
-kthread_id_t cvc_input_daemon_thread; /* just to aid debugging */
-static kmutex_t cvcmutex; /* protects input */
-static kmutex_t cvc_iosram_input_mutex; /* protects IOSRAM inp buff */
-static int input_ok = 0; /* true when stream is valid */
-
-static int via_iosram = 0; /* toggle switch */
-static timeout_id_t cvc_timeout_id = (timeout_id_t)-1;
-static int input_daemon_started = 0;
-
-/* debugging functions */
-#ifdef DEBUG
-uint32_t cvc_dbg_flags = 0x0;
-static void cvc_dbg(uint32_t flag, char *fmt,
- uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5);
-#endif
-
-/*
- * Module linkage information for the kernel.
- */
-
-DDI_DEFINE_STREAM_OPS(cvcops, nulldev, nulldev, cvc_attach, cvc_detach,
- nodev, cvc_info, (D_NEW|D_MTPERQ|D_MP), &cvcinfo,
- ddi_quiesce_not_supported);
-
-extern int nodev(), nulldev();
-extern struct mod_ops mod_driverops;
-
-static struct modldrv modldrv = {
- &mod_driverops, /* Type of module. This one is a pseudo driver */
- "CVC driver 'cvc'",
- &cvcops, /* driver ops */
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- &modldrv,
- NULL
-};
-
-int
-_init()
-{
- int status;
-
- status = mod_install(&modlinkage);
- if (status == 0) {
- mutex_init(&cvcmutex, NULL, MUTEX_DEFAULT, NULL);
- }
- return (status);
-}
-
-int
-_fini()
-{
- return (EBUSY);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-/*
- * DDI glue routines.
- */
-
-/* ARGSUSED */
-static int
-cvc_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
-{
- static char been_here = 0;
-
- if (cmd == DDI_RESUME) {
- cvc_suspended = 0;
- if (cvcinput_q != NULL) {
- qenable(WR(cvcinput_q));
- }
- return (DDI_SUCCESS);
- }
-
- mutex_enter(&cvcmutex);
- if (!been_here) {
- been_here = 1;
- mutex_init(&cvc_iosram_input_mutex, NULL, MUTEX_DEFAULT, NULL);
- rw_init(&cvclock, NULL, RW_DRIVER, NULL);
- cvc_instance = ddi_get_instance(devi);
- } else {
-#if defined(DEBUG)
- cmn_err(CE_NOTE,
- "cvc_attach: called multiple times!! (instance = %d)",
- ddi_get_instance(devi));
-#endif /* DEBUG */
- mutex_exit(&cvcmutex);
- return (DDI_SUCCESS);
- }
- mutex_exit(&cvcmutex);
-
- if (ddi_create_minor_node(devi, "cvc", S_IFCHR,
- 0, NULL, NULL) == DDI_FAILURE) {
- ddi_remove_minor_node(devi, NULL);
- return (-1);
- }
- cvcdip = devi;
- cvcinput_q = NULL;
- cvcoutput_q = NULL;
-
- CVC_DBG0(CVC_DBG_ATTACH, "Attached");
-
- return (DDI_SUCCESS);
-}
-
-static int
-cvc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- if (cmd == DDI_SUSPEND) {
- cvc_suspended = 1;
- } else {
- if (cmd != DDI_DETACH) {
- return (DDI_FAILURE);
- }
- /*
- * XXX this doesn't even begin to address the detach
- * issues - it doesn't terminate the outstanding thread,
- * it doesn't clean up mutexes, kill the timeout routine
- * etc.
- */
- if (cvc_instance == ddi_get_instance(dip)) {
- ddi_remove_minor_node(dip, NULL);
- }
- }
-
- CVC_DBG0(CVC_DBG_DETACH, "Detached");
-
- return (DDI_SUCCESS);
-}
-
-/* ARGSUSED */
-static int
-cvc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
-{
- register int error;
-
- switch (infocmd) {
- case DDI_INFO_DEVT2DEVINFO:
- if (cvcdip == NULL) {
- error = DDI_FAILURE;
- } else {
- *result = (void *)cvcdip;
- error = DDI_SUCCESS;
- }
- break;
- case DDI_INFO_DEVT2INSTANCE:
- *result = (void *)0;
- error = DDI_SUCCESS;
- break;
- default:
- error = DDI_FAILURE;
- }
- return (error);
-}
-
-/* ARGSUSED */
-static int
-cvc_open(register queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp)
-{
- register int unit = getminor(*devp);
- register int err = DDI_SUCCESS;
- tty_common_t *tty;
- cvc_t *cp;
-
- if (unit != 0)
- return (ENXIO);
-
- if (q->q_ptr)
- return (0);
-
- cp = (cvc_t *)&cvc_common_tty;
- bzero((caddr_t)cp, sizeof (cvc_t));
- cp->cvc_wbufcid = 0;
- tty = &cp->cvc_tty;
- tty->t_readq = q;
- tty->t_writeq = WR(q);
- WR(q)->q_ptr = q->q_ptr = (caddr_t)cp;
- cvcinput_q = RD(q); /* save for cvc_redir */
- qprocson(q);
- mutex_enter(&cvcmutex);
- input_ok = 1;
-
- /*
- * Start the thread that handles input polling if it hasn't been started
- * previously.
- */
- if (!input_daemon_started) {
- input_daemon_started = 1;
- mutex_exit(&cvcmutex);
-
- cvc_input_daemon_thread = thread_create(NULL, 0,
- cvc_input_daemon, NULL, 0, &p0, TS_RUN, minclsyspri);
- CVC_DBG0(CVC_DBG_IOSRAM_RD, "Started input daemon");
- } else {
- mutex_exit(&cvcmutex);
- }
-
- /*
- * Set the console window size.
- */
- mutex_enter(&cvc_iosram_input_mutex);
- cvc_win_resize(FALSE);
- mutex_exit(&cvc_iosram_input_mutex);
-
- CVC_DBG0(CVC_DBG_OPEN, "Plumbed successfully");
-
- return (err);
-}
-
-/* ARGSUSED */
-static int
-cvc_close(queue_t *q, int flag, cred_t *crp)
-{
- register int err = DDI_SUCCESS;
- register cvc_t *cp;
-
- mutex_enter(&cvcmutex);
- input_ok = 0;
- mutex_exit(&cvcmutex);
-
- cp = q->q_ptr;
- if (cp->cvc_wbufcid != 0) {
- unbufcall(cp->cvc_wbufcid);
- }
- ttycommon_close(&cp->cvc_tty);
- WR(q)->q_ptr = q->q_ptr = NULL;
- cvcinput_q = NULL;
- bzero((caddr_t)cp, sizeof (cvc_t));
- qprocsoff(q);
-
- CVC_DBG0(CVC_DBG_CLOSE, "Un-plumbed successfully");
-
- return (err);
-}
-
-
-/*
- * cvc_wput()
- * cn driver does a strwrite of console output data to rconsvp which has
- * been set by consconfig. The data enters the cvc stream at the streamhead
- * and flows thru ttycompat and ldterm which have been pushed on the
- * stream. Console output data gets sent out either to cvcredir, if the
- * network path is available and selected, or to IOSRAM otherwise. Data is
- * sent to cvcredir via its read queue (cvcoutput_q, which gets set in
- * cvc_register()). If the IOSRAM path is selected, or if previous mblks
- * are currently queued up for processing, the new mblk will be queued
- * and handled later on by cvc_wsrv.
- */
-static int
-cvc_wput(queue_t *q, mblk_t *mp)
-{
- int error = 0;
-
- rw_enter(&cvclock, RW_READER);
-
- CVC_DBG2(CVC_DBG_WPUT, "mp 0x%x db_type 0x%x",
- mp, mp->b_datap->db_type);
-
- switch (mp->b_datap->db_type) {
-
- case M_IOCTL:
- case M_CTL: {
- struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
-
- switch (iocp->ioc_cmd) {
- /*
- * These ioctls are only supposed to be
- * processed after everything else that is
- * already queued awaiting processing, so throw
- * them on the queue and let cvc_wsrv handle
- * them.
- */
- case TCSETSW:
- case TCSETSF:
- case TCSETAW:
- case TCSETAF:
- case TCSBRK:
- (void) putq(q, mp);
- break;
-
- default:
- cvc_ioctl(q, mp);
- }
- break;
- }
-
- case M_FLUSH:
- if (*mp->b_rptr & FLUSHW) {
- /*
- * Flush our write queue.
- */
- flushq(q, FLUSHDATA);
- *mp->b_rptr &= ~FLUSHW;
- }
- if (*mp->b_rptr & FLUSHR) {
- flushq(RD(q), FLUSHDATA);
- qreply(q, mp);
- } else
- freemsg(mp);
- break;
-
- case M_STOP:
- cvc_stopped = 1;
- freemsg(mp);
- break;
-
- case M_START:
- cvc_stopped = 0;
- freemsg(mp);
- qenable(q); /* Start up delayed messages */
- break;
-
- case M_READ:
- /*
- * ldterm handles this (VMIN/VTIME processing).
- */
- freemsg(mp);
- break;
-
- default:
- cmn_err(CE_WARN, "cvc_wput: unexpected mblk type - mp ="
- " 0x%p, type = 0x%x", (void *)mp,
- mp->b_datap->db_type);
- freemsg(mp);
- break;
-
- case M_DATA:
- /*
- * If there are other mblks queued up for transmission,
- * or we're using IOSRAM either because cvcredir hasn't
- * registered yet or because we were configured that
- * way, or cvc has been stopped or suspended, place this
- * mblk on the input queue for future processing.
- * Otherwise, hand it off to cvcredir for transmission
- * via the network.
- */
- if (q->q_first != NULL || cvcoutput_q == NULL ||
- via_iosram || cvc_stopped == 1 ||
- cvc_suspended == 1) {
- (void) putq(q, mp);
- } else {
- /*
- * XXX - should canputnext be called here?
- * Starfire's cvc doesn't do that, and it
- * appears to work anyway.
- */
- (void) putnext(cvcoutput_q, mp);
- }
- break;
-
- }
- rw_exit(&cvclock);
- return (error);
-}
-
-/*
- * cvc_wsrv()
- * cvc_wsrv handles mblks that have been queued by cvc_wput either because
- * the IOSRAM path was selected or the queue contained preceding mblks. To
- * optimize processing (particularly if the IOSRAM path is selected), all
- * mblks are pulled off of the queue and chained together. Then, if there
- * are any mblks on the chain, they are either forwarded to cvcredir or
- * sent for IOSRAM processing as appropriate given current circumstances.
- * IOSRAM processing may not be able to handle all of the data in the
- * chain, in which case the remaining data is placed back on the queue and
- * a timeout routine is registered to reschedule cvc_wsrv in the future.
- * Automatic scheduling of the queue is disabled (noenable(q)) while
- * cvc_wsrv is running to avoid superfluous calls.
- */
-static int
-cvc_wsrv(queue_t *q)
-{
- mblk_t *total_mp = NULL;
- mblk_t *mp;
-
- if (cvc_stopped == 1 || cvc_suspended == 1) {
- return (0);
- }
-
- rw_enter(&cvclock, RW_READER);
- noenable(q);
-
- /*
- * If there's already a timeout registered for scheduling this routine
- * in the future, it's a safe bet that we don't want to run right now.
- */
- if (cvc_timeout_id != (timeout_id_t)-1) {
- enableok(q);
- rw_exit(&cvclock);
- return (0);
- }
-
- /*
- * Start by linking all of the queued M_DATA mblks into a single chain
- * so we can flush as much as possible to IOSRAM (if we choose that
- * route).
- */
- while ((mp = getq(q)) != NULL) {
- /*
- * Technically, certain IOCTLs are supposed to be processed only
- * after all preceding data has completely "drained". In an
- * attempt to support that, we delay processing of those IOCTLs
- * until this point. It is still possible that an IOCTL will be
- * processed before all preceding data is drained, for instance
- * in the case where not all of the preceding data would fit
- * into IOSRAM and we have to place it back on the queue.
- * However, since none of these IOCTLs really appear to have any
- * relevance for cvc, and we weren't supporting delayed
- * processing at _all_ previously, this partial implementation
- * should suffice. (Fully implementing the delayed IOCTL
- * processing would be unjustifiably difficult given the nature
- * of the underlying IOSRAM console protocol.)
- */
- if (mp->b_datap->db_type == M_IOCTL) {
- cvc_ioctl(q, mp);
- continue;
- }
-
- /*
- * We know that only M_IOCTL and M_DATA blocks are placed on our
- * queue. Since this block isn't an M_IOCTL, it must be M_DATA.
- */
- if (total_mp != NULL) {
- linkb(total_mp, mp);
- } else {
- total_mp = mp;
- }
- }
-
- /*
- * Do we actually have anything to do?
- */
- if (total_mp == NULL) {
- enableok(q);
- rw_exit(&cvclock);
- return (0);
- }
-
- /*
- * Yes, we do, so send the data to either cvcredir or IOSRAM as
- * appropriate. In the latter case, we might not be able to transmit
- * everything right now, so re-queue the remainder.
- */
- if (cvcoutput_q != NULL && !via_iosram) {
- CVC_DBG0(CVC_DBG_NETWORK_WR, "Sending to cvcredir.");
- /*
- * XXX - should canputnext be called here? Starfire's cvc
- * doesn't do that, and it appears to work anyway.
- */
- (void) putnext(cvcoutput_q, total_mp);
- } else {
- CVC_DBG0(CVC_DBG_IOSRAM_WR, "Send to IOSRAM.");
- cvc_send_to_iosram(&total_mp);
- if (total_mp != NULL) {
- (void) putbq(q, total_mp);
- }
- }
-
- /*
- * If there is still data queued at this point, make sure the queue
- * gets scheduled again after an appropriate delay (which has been
- * somewhat arbitrarily selected as half of the SC's input polling
- * frequency).
- */
- enableok(q);
- if (q->q_first != NULL) {
- if (cvc_timeout_id == (timeout_id_t)-1) {
- cvc_timeout_id = timeout(cvc_flush_queue,
- NULL, drv_usectohz(CVC_IOSRAM_POLL_USECS / 2));
- }
- }
- rw_exit(&cvclock);
- return (0);
-}
-
-
-/*
- * cvc_ioctl()
- * handle normal console ioctls.
- */
-static void
-cvc_ioctl(register queue_t *q, register mblk_t *mp)
-{
- register cvc_t *cp = q->q_ptr;
- int datasize;
- int error = 0;
-
- /*
- * Let ttycommon_ioctl take the first shot at processing the ioctl. If
- * it fails because it can't allocate memory, schedule processing of the
- * ioctl later when a proper buffer is available. The mblk that
- * couldn't be processed will have been stored in the tty structure by
- * ttycommon_ioctl.
- */
- datasize = ttycommon_ioctl(&cp->cvc_tty, q, mp, &error);
- if (datasize != 0) {
- if (cp->cvc_wbufcid) {
- unbufcall(cp->cvc_wbufcid);
- }
- cp->cvc_wbufcid = bufcall(datasize, BPRI_HI, cvc_reioctl, cp);
- return;
- }
-
- /*
- * ttycommon_ioctl didn't do anything, but there's nothing we really
- * support either with the exception of TCSBRK, which is supported
- * only to appear a bit more like a serial device for software that
- * expects TCSBRK to work.
- */
- if (error != 0) {
- struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
-
- if (iocp->ioc_cmd == TCSBRK) {
- miocack(q, mp, 0, 0);
- } else {
- miocnak(q, mp, 0, EINVAL);
- }
- } else {
- qreply(q, mp);
- }
-}
-
-
-/*
- * cvc_redir()
- * called from cvcredir:cvcr_wput() to handle console input
- * data. This routine puts the cvcredir write (downstream) data
- * onto the cvc read (upstream) queues.
- */
-int
-cvc_redir(mblk_t *mp)
-{
- register struct iocblk *iocp;
- int rv = 1;
-
- /*
- * This function shouldn't be called if cvcredir hasn't registered yet.
- */
- if (cvcinput_q == NULL) {
- /*
- * Need to let caller know that it may be necessary for them to
- * free the message buffer, so return 0.
- */
- CVC_DBG0(CVC_DBG_REDIR, "redirection not enabled");
- cmn_err(CE_WARN, "cvc_redir: cvcinput_q NULL!");
- return (0);
- }
-
- CVC_DBG1(CVC_DBG_REDIR, "type 0x%x", mp->b_datap->db_type);
- if (mp->b_datap->db_type == M_DATA) {
- /*
- * XXX - should canputnext be called here? Starfire's cvc
- * doesn't do that, and it appears to work anyway.
- */
- CVC_DBG1(CVC_DBG_NETWORK_RD, "Sending mp 0x%x", mp);
- (void) putnext(cvcinput_q, mp);
- } else if (mp->b_datap->db_type == M_IOCTL) {
- /*
- * The cvcredir driver filters out ioctl mblks we wouldn't
- * understand, so we don't have to check for every conceivable
- * ioc_cmd. However, additional ioctls may be supported (again)
- * some day, so the code is structured to check the value even
- * though there's only one that is currently supported.
- */
- iocp = (struct iocblk *)mp->b_rptr;
- if (iocp->ioc_cmd == CVC_DISCONNECT) {
- (void) putnextctl(cvcinput_q, M_HANGUP);
- }
- } else {
- /*
- * Since we don't know what this mblk is, we're not going to
- * process it.
- */
- CVC_DBG1(CVC_DBG_REDIR, "unrecognized mblk type: %d",
- mp->b_datap->db_type);
- rv = 0;
- }
-
- return (rv);
-}
-
-
-/*
- * cvc_register()
- * called from cvcredir to register it's queues. cvc
- * receives data from cn via the streamhead and sends it to cvcredir
- * via pointers to cvcredir's queues.
- */
-int
-cvc_register(queue_t *q)
-{
- int error = -1;
-
- if (cvcinput_q == NULL)
- cmn_err(CE_WARN, "cvc_register: register w/ no console open!");
- rw_enter(&cvclock, RW_WRITER);
- if (cvcoutput_q == NULL) {
- cvcoutput_q = RD(q); /* Make sure its the upstream q */
- qprocson(cvcoutput_q); /* must be done within cvclock */
- error = 0;
- } else {
- /*
- * cmn_err will call us, so release lock.
- */
- rw_exit(&cvclock);
- if (cvcoutput_q == q)
- cmn_err(CE_WARN, "cvc_register: duplicate q!");
- else
- cmn_err(CE_WARN, "cvc_register: nondup q = 0x%p",
- (void *)q);
- return (error);
- }
- rw_exit(&cvclock);
- return (error);
-}
-
-
-/*
- * cvc_unregister()
- * called from cvcredir to clear pointers to its queues.
- * cvcredir no longer wants to send or receive data.
- */
-void
-cvc_unregister(queue_t *q)
-{
- rw_enter(&cvclock, RW_WRITER);
- if (q == cvcoutput_q) {
- qprocsoff(cvcoutput_q); /* must be done within cvclock */
- cvcoutput_q = NULL;
- } else {
- rw_exit(&cvclock);
- cmn_err(CE_WARN, "cvc_unregister: q = 0x%p not registered",
- (void *)q);
- return;
- }
- rw_exit(&cvclock);
-}
-
-
-/*
- * cvc_reioctl()
- * Retry an "ioctl", now that "bufcall" claims we may be able
- * to allocate the buffer we need.
- */
-static void
-cvc_reioctl(void *unit)
-{
- register queue_t *q;
- register mblk_t *mp;
- register cvc_t *cp = (cvc_t *)unit;
-
- /*
- * The bufcall is no longer pending.
- */
- if (!cp->cvc_wbufcid) {
- return;
- }
- cp->cvc_wbufcid = 0;
- if ((q = cp->cvc_tty.t_writeq) == NULL) {
- return;
- }
- if ((mp = cp->cvc_tty.t_iocpending) != NULL) {
- /* not pending any more */
- cp->cvc_tty.t_iocpending = NULL;
- cvc_ioctl(q, mp);
- }
-}
-
-
-/*
- * cvc_iosram_ops()
- * Process commands sent to cvc from netcon_server via IOSRAM
- */
-static void
-cvc_iosram_ops(uint8_t op)
-{
- int rval = ESUCCESS;
- static uint8_t stale_op = 0;
-
- ASSERT(MUTEX_HELD(&cvc_iosram_input_mutex));
-
- CVC_DBG1(CVC_DBG_IOSRAM_CNTL, "cntl msg 0x%x", op);
-
- /*
- * If this is a repeated notice of a command that was previously
- * processed but couldn't be cleared due to EAGAIN (tunnel switch in
- * progress), just clear the data_valid flag and return.
- */
- if (op == stale_op) {
- if (iosram_set_flag(IOSRAM_KEY_CONC, IOSRAM_DATA_INVALID,
- IOSRAM_INT_NONE) == 0) {
- stale_op = 0;
- }
- return;
- }
- stale_op = 0;
-
- switch (op) {
- case CVC_IOSRAM_BREAK: /* A console break (L1-A) */
- abort_sequence_enter((char *)NULL);
- break;
-
- case CVC_IOSRAM_DISCONNECT: /* Break connection, hang up */
- if (cvcinput_q)
- (void) putnextctl(cvcinput_q, M_HANGUP);
- break;
-
- case CVC_IOSRAM_VIA_NET: /* console via network */
- via_iosram = 0;
- break;
-
- case CVC_IOSRAM_VIA_IOSRAM: /* console via iosram */
- via_iosram = 1;
- /*
- * Tell cvcd to close any network connection it has.
- */
- rw_enter(&cvclock, RW_READER);
- if (cvcoutput_q != NULL) {
- (void) putnextctl(cvcoutput_q, M_HANGUP);
- }
- rw_exit(&cvclock);
- break;
-
- case CVC_IOSRAM_WIN_RESIZE: /* console window size data */
- /*
- * In the case of window resizing, we don't want to
- * record a stale_op value because we should always use
- * the most recent winsize info, which could change
- * between the time that we fail to clear the flag and
- * the next time we try to process the command. So,
- * we'll just let cvc_win_resize clear the data_valid
- * flag itself (hence the TRUE parameter) and not worry
- * about whether or not it succeeds.
- */
- cvc_win_resize(TRUE);
- return;
- /* NOTREACHED */
-
- default:
- cmn_err(CE_WARN, "cvc: unknown IOSRAM opcode %d", op);
- break;
- }
-
- /*
- * Clear CONC's data_valid flag to indicate that the chunk is available
- * for further communications. If the flag can't be cleared due to an
- * error, record the op value so we'll know to ignore it when we see it
- * on the next poll.
- */
- rval = iosram_set_flag(IOSRAM_KEY_CONC, IOSRAM_DATA_INVALID,
- IOSRAM_INT_NONE);
- if (rval != 0) {
- stale_op = op;
- if (rval != EAGAIN) {
- cmn_err(CE_WARN,
- "cvc_iosram_ops: set flag for cntlbuf ret %d",
- rval);
- }
- }
-}
-
-
-/*
- * cvc_send_to_iosram()
- * Flush as much data as possible to the CONO chunk. If successful, free
- * any mblks that were completely transmitted, update the b_rptr field in
- * the first remaining mblk if it was partially transmitted, and update the
- * caller's pointer to the new head of the mblk chain. Since the software
- * that will be pulling this data out of IOSRAM (dxs on the SC) is just
- * polling at some frequency, we avoid attempts to flush data to IOSRAM any
- * faster than a large divisor of that polling frequency.
- *
- * Note that "cvc_buf_t out" is only declared "static" to keep it from
- * being allocated on the stack. Allocating 1K+ structures on the stack
- * seems rather antisocial.
- */
-static void
-cvc_send_to_iosram(mblk_t **chainpp)
-{
- int rval;
- uint8_t dvalid;
- uchar_t *cp;
- mblk_t *mp;
- mblk_t *last_empty_mp;
- static clock_t last_flush = (clock_t)-1;
- static cvc_buf_t out; /* see note above about static */
-
- ASSERT(chainpp != NULL);
-
- /*
- * We _do_ have something to do, right?
- */
- if (*chainpp == NULL) {
- return;
- }
-
- /*
- * We can actually increase throughput by throttling back on attempts to
- * flush data to IOSRAM, since trying to write every little bit of data
- * as it shows up will actually generate more delays waiting for the SC
- * to pick up each of those bits. Instead, we'll avoid attempting to
- * write data to IOSRAM any faster than half of the polling frequency we
- * expect the SC to be using.
- */
- if (ddi_get_lbolt() - last_flush <
- drv_usectohz(CVC_IOSRAM_POLL_USECS / 2)) {
- return;
- }
-
- /*
- * If IOSRAM is inaccessible or the CONO chunk still holds data that
- * hasn't been picked up by the SC, there's nothing we can do right now.
- */
- rval = iosram_get_flag(IOSRAM_KEY_CONO, &dvalid, NULL);
- if ((rval != 0) || (dvalid == IOSRAM_DATA_VALID)) {
- if ((rval != 0) && (rval != EAGAIN)) {
- cmn_err(CE_WARN, "cvc_send_to_iosram: get_flag ret %d",
- rval);
- }
- return;
- }
-
- /*
- * Copy up to MAX_XFER_COUTPUT chars from the mblk chain into a buffer.
- * Don't change any of the mblks just yet, since we can't be certain
- * that we'll be successful in writing data to the CONO chunk.
- */
- out.count = 0;
- mp = *chainpp;
- cp = mp->b_rptr;
- last_empty_mp = NULL;
- while ((mp != NULL) && (out.count < MAX_XFER_COUTPUT)) {
- /*
- * Process as many of the characters in the current mblk as
- * possible.
- */
- while ((cp != mp->b_wptr) && (out.count < MAX_XFER_COUTPUT)) {
- out.buffer[out.count++] = *cp++;
- }
-
- /*
- * Did we process that entire mblk? If so, move on to the next
- * one. If not, we're done filling the buffer even if there's
- * space left, because apparently there wasn't room to process
- * the next character.
- */
- if (cp != mp->b_wptr) {
- break;
- }
-
- /*
- * When this loop terminates, last_empty_mp will point to the
- * last mblk that was completely processed, mp will point to the
- * following mblk (or NULL if no more mblks exist), and cp will
- * point to the first untransmitted character in the mblk
- * pointed to by mp. We'll need this data to update the mblk
- * chain if all of the data is successfully transmitted.
- */
- last_empty_mp = mp;
- mp = mp->b_cont;
- cp = (mp != NULL) ? mp->b_rptr : NULL;
- }
-
- /*
- * If we succeeded in preparing some data, try to transmit it through
- * IOSRAM. First write the count and the data, which can be done in a
- * single operation thanks to the buffer structure we use, then set the
- * data_valid flag if the first step succeeded.
- */
- if (out.count != 0) {
- rval = iosram_wr(IOSRAM_KEY_CONO, COUNT_OFFSET,
- CONSBUF_COUNT_SIZE + out.count, (caddr_t)&out);
- if ((rval != 0) && (rval != EAGAIN)) {
- cmn_err(CE_WARN, "cvc_putc: write ret %d", rval);
- }
-
- /* if the data write succeeded, set the data_valid flag */
- if (rval == 0) {
- rval = iosram_set_flag(IOSRAM_KEY_CONO,
- IOSRAM_DATA_VALID, IOSRAM_INT_NONE);
- if ((rval != 0) && (rval != EAGAIN)) {
- cmn_err(CE_WARN,
- "cvc_putc: set flags for outbuf ret %d",
- rval);
- }
- }
-
- /*
- * If we successfully transmitted any data, modify the caller's
- * mblk chain to remove the data that was transmitted, freeing
- * all mblks that were completely processed.
- */
- if (rval == 0) {
- last_flush = ddi_get_lbolt();
-
- /*
- * If any data is left over, update the b_rptr field of
- * the first remaining mblk in case some of its data was
- * processed.
- */
- if (mp != NULL) {
- mp->b_rptr = cp;
- }
-
- /*
- * If any mblks have been emptied, unlink them from the
- * residual chain, free them, and update the caller's
- * mblk pointer.
- */
- if (last_empty_mp != NULL) {
- last_empty_mp->b_cont = NULL;
- freemsg(*chainpp);
- *chainpp = mp;
- }
- }
- }
-}
-
-
-/*
- * cvc_flush_queue()
- * Tell the STREAMS subsystem to schedule cvc_wsrv to process the queue we
- * use to gather console output.
- */
-/* ARGSUSED */
-static void
-cvc_flush_queue(void *notused)
-{
- rw_enter(&cvclock, RW_WRITER);
- if (cvcinput_q != NULL) {
- qenable(WR(cvcinput_q));
- }
-
- cvc_timeout_id = (timeout_id_t)-1;
- rw_exit(&cvclock);
-}
-
-
-/*
- * cvc_getstr()
- * Poll IOSRAM for console input while available.
- */
-static void
-cvc_getstr(char *cp)
-{
- short count;
- uint8_t command = 0;
- int rval = ESUCCESS;
- uint8_t dvalid = IOSRAM_DATA_INVALID;
- uint8_t intrpending = 0;
-
- mutex_enter(&cvc_iosram_input_mutex);
- while (dvalid == IOSRAM_DATA_INVALID) {
- /*
- * Check the CONC data_valid flag to see if a control message is
- * available.
- */
- rval = iosram_get_flag(IOSRAM_KEY_CONC, &dvalid, &intrpending);
- if ((rval != 0) && (rval != EAGAIN)) {
- cmn_err(CE_WARN,
- "cvc_getstr: get flag for cntl ret %d", rval);
- }
-
- /*
- * If a control message is available, try to read and process
- * it.
- */
- if ((dvalid == IOSRAM_DATA_VALID) && (rval == 0)) {
- /* read the control reg offset */
- rval = iosram_rd(IOSRAM_KEY_CONC,
- CVC_CTL_OFFSET(command), CVC_CTL_SIZE(command),
- (caddr_t)&command);
- if ((rval != 0) && (rval != EAGAIN)) {
- cmn_err(CE_WARN,
- "cvc_getstr: read for command ret %d",
- rval);
- }
-
- /* process the cntl msg and clear the data_valid flag */
- if (rval == 0) {
- cvc_iosram_ops(command);
- }
- }
-
- /*
- * Check the CONI data_valid flag to see if console input data
- * is available.
- */
- rval = iosram_get_flag(IOSRAM_KEY_CONI, &dvalid, &intrpending);
- if ((rval != 0) && (rval != EAGAIN)) {
- cmn_err(CE_WARN,
- "cvc_getstr: get flag for inbuf ret %d",
- rval);
- }
- if ((rval != 0) || (dvalid != IOSRAM_DATA_VALID)) {
- goto retry;
- }
-
- /*
- * Try to read the count.
- */
- rval = iosram_rd(IOSRAM_KEY_CONI, COUNT_OFFSET,
- CONSBUF_COUNT_SIZE, (caddr_t)&count);
- if (rval != 0) {
- if (rval != EAGAIN) {
- cmn_err(CE_WARN,
- "cvc_getstr: read for count ret %d", rval);
- }
- goto retry;
- }
-
- /*
- * If there is data to be read, try to read it.
- */
- if (count != 0) {
- rval = iosram_rd(IOSRAM_KEY_CONI, DATA_OFFSET, count,
- (caddr_t)cp);
- if (rval != 0) {
- if (rval != EAGAIN) {
- cmn_err(CE_WARN,
- "cvc_getstr: read for count ret %d",
- rval);
- }
- goto retry;
- }
- cp[count] = '\0';
- }
-
- /*
- * Try to clear the data_valid flag to indicate that whatever
- * was in CONI was read successfully. If successful, and some
- * data was read, break out of the loop to return to the caller.
- */
- rval = iosram_set_flag(IOSRAM_KEY_CONI, IOSRAM_DATA_INVALID,
- IOSRAM_INT_NONE);
- if (rval != 0) {
- if (rval != EAGAIN) {
- cmn_err(CE_WARN,
- "cvc_getstr: set flag for inbuf ret %d",
- rval);
- }
- } else if (count != 0) {
- CVC_DBG1(CVC_DBG_IOSRAM_RD, "Read 0x%x", count);
- break;
- }
-
- /*
- * Use a smaller delay between checks of IOSRAM for input
- * when cvcd/cvcredir are not running or "via_iosram" has
- * been set.
- * We don't go away completely when i/o is going through the
- * network via cvcd since a command may be sent via IOSRAM
- * to switch if the network is down or hung.
- */
-retry:
- if ((cvcoutput_q == NULL) || (via_iosram))
- delay(drv_usectohz(CVC_IOSRAM_POLL_USECS));
- else
- delay(drv_usectohz(CVC_IOSRAM_POLL_USECS * 10));
-
- }
-
- mutex_exit(&cvc_iosram_input_mutex);
-}
-
-
-/*
- * cvc_input_daemon()
- * this function runs as a separate kernel thread and polls IOSRAM for
- * input, and possibly put it on read stream for the console.
- * There are two poll rates (implemented in cvc_getstr):
- * 100 000 uS (10 Hz) - no cvcd communications || via_iosram
- * 1000 000 uS ( 1 Hz) - cvcd communications
- * This continues to run even if there are network console communications
- * in order to handle out-of-band signaling.
- */
-/* ARGSUSED */
-static void
-cvc_input_daemon(void)
-{
- char linebuf[MAX_XFER_CINPUT + 1];
- char *cp;
- mblk_t *mbp;
- int c;
- int dropped_read = 0;
-
- for (;;) {
- cvc_getstr(linebuf);
-
- mbp = allocb(strlen(linebuf), BPRI_MED);
- if (mbp == NULL) { /* drop it & go on if no buffer */
- if (!dropped_read) {
- cmn_err(CE_WARN, "cvc_input_daemon: "
- "dropping IOSRAM reads");
- }
- dropped_read++;
- continue;
- }
-
- if (dropped_read) {
- cmn_err(CE_WARN,
- "cvc_input_daemon: dropped %d IOSRAM reads",
- dropped_read);
- dropped_read = 0;
- }
-
- for (cp = linebuf; *cp != '\0'; cp++) {
- c = (int)*cp;
- if (c == '\r')
- c = '\n';
- c &= 0177;
- *mbp->b_wptr = (char)c;
- mbp->b_wptr++;
- }
- mutex_enter(&cvcmutex);
- if (input_ok) {
- if (cvcinput_q == NULL) {
- cmn_err(CE_WARN,
- "cvc_input_daemon: cvcinput_q is NULL!");
- } else {
- /*
- * XXX - should canputnext be called here?
- * Starfire's cvc doesn't do that, and it
- * appears to work anyway.
- */
- (void) putnext(cvcinput_q, mbp);
- }
- } else {
- freemsg(mbp);
- }
- mutex_exit(&cvcmutex);
- }
-
- /* NOTREACHED */
-}
-
-/*
- * cvc_win_resize()
- * cvc_win_resize will read winsize data from the CONC IOSRAM chunk and set
- * the console window size accordingly. If indicated by the caller, CONC's
- * data_valid flag will also be cleared. The flag isn't cleared in all
- * cases because we need to process winsize data at startup without waiting
- * for a command.
- */
-static void
-cvc_win_resize(int clear_flag)
-{
- int rval;
- uint16_t rows;
- uint16_t cols;
- uint16_t xpixels;
- uint16_t ypixels;
- tty_common_t *tty;
- cvc_t *cp;
- struct winsize ws;
-
- /*
- * Start by reading the new window size out of the CONC chunk and, if
- * requested, clearing CONC's data_valid flag. If any of that fails,
- * return immediately. (Note that the rather bulky condition in the
- * two "if" statements takes advantage of C's short-circuit logic
- * evaluation)
- */
- if (((rval = iosram_rd(IOSRAM_KEY_CONC, CVC_CTL_OFFSET(winsize_rows),
- CVC_CTL_SIZE(winsize_rows), (caddr_t)&rows)) != 0) ||
- ((rval = iosram_rd(IOSRAM_KEY_CONC, CVC_CTL_OFFSET(winsize_cols),
- CVC_CTL_SIZE(winsize_cols), (caddr_t)&cols)) != 0) ||
- ((rval = iosram_rd(IOSRAM_KEY_CONC,
- CVC_CTL_OFFSET(winsize_xpixels), CVC_CTL_SIZE(winsize_xpixels),
- (caddr_t)&xpixels)) != 0) || ((rval = iosram_rd(IOSRAM_KEY_CONC,
- CVC_CTL_OFFSET(winsize_ypixels), CVC_CTL_SIZE(winsize_ypixels),
- (caddr_t)&ypixels)) != 0)) {
- if (rval != EAGAIN) {
- cmn_err(CE_WARN,
- "cvc_win_resize: read for ctlbuf ret %d", rval);
- }
- return;
- }
-
- if (clear_flag && ((rval = iosram_set_flag(IOSRAM_KEY_CONC,
- IOSRAM_DATA_INVALID, IOSRAM_INT_NONE)) != 0)) {
- if (rval != EAGAIN) {
- cmn_err(CE_WARN,
- "cvc_win_resize: set_flag for ctlbuf ret %d", rval);
- }
- return;
- }
-
- /*
- * Copy the parameters from IOSRAM to a winsize struct.
- */
- ws.ws_row = rows;
- ws.ws_col = cols;
- ws.ws_xpixel = xpixels;
- ws.ws_ypixel = ypixels;
-
- /*
- * This code was taken from Starfire, and it appears to work correctly.
- * However, since the original developer felt it necessary to add the
- * following comment, it's probably worth preserving:
- *
- * XXX I hope this is safe...
- */
- cp = cvcinput_q->q_ptr;
- tty = &cp->cvc_tty;
- mutex_enter(&tty->t_excl);
- if (bcmp((caddr_t)&tty->t_size, (caddr_t)&ws,
- sizeof (struct winsize))) {
- tty->t_size = ws;
- mutex_exit(&tty->t_excl);
- (void) putnextctl1(cvcinput_q, M_PCSIG,
- SIGWINCH);
- } else {
- mutex_exit(&tty->t_excl);
- }
-}
-
-#ifdef DEBUG
-
-void
-cvc_dbg(uint32_t flag, char *fmt,
- uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5)
-{
- char *s = NULL;
- char buf[256];
-
- if (cvc_dbg_flags && ((cvc_dbg_flags & flag) == flag)) {
- switch (flag) {
- case CVC_DBG_ATTACH:
- s = "attach";
- break;
- case CVC_DBG_DETACH:
- s = "detach";
- break;
- case CVC_DBG_OPEN:
- s = "open";
- break;
- case CVC_DBG_CLOSE:
- s = "close";
- break;
- case CVC_DBG_IOCTL:
- s = "ioctl";
- break;
- case CVC_DBG_REDIR:
- s = "redir";
- break;
- case CVC_DBG_WPUT:
- s = "wput";
- break;
- case CVC_DBG_WSRV:
- s = "wsrv";
- break;
- case CVC_DBG_IOSRAM_WR:
- s = "iosram_wr";
- break;
- case CVC_DBG_IOSRAM_RD:
- s = "iosram_rd";
- break;
- case CVC_DBG_NETWORK_WR:
- s = "network_wr";
- break;
- case CVC_DBG_NETWORK_RD:
- s = "network_rd";
- break;
- case CVC_DBG_IOSRAM_CNTL:
- s = "iosram_cntlmsg";
- break;
- default:
- s = "Unknown debug flag";
- break;
- }
-
- (void) sprintf(buf, "!%s_%s(%d): %s", ddi_driver_name(cvcdip),
- s, cvc_instance, fmt);
- cmn_err(CE_NOTE, buf, a1, a2, a3, a4, a5);
- }
-}
-
-#endif /* DEBUG */
diff --git a/usr/src/uts/sun4u/starcat/io/cvc.conf b/usr/src/uts/sun4u/starcat/io/cvc.conf
deleted file mode 100644
index 54779c96be..0000000000
--- a/usr/src/uts/sun4u/starcat/io/cvc.conf
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 2000 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-name="cvc" parent="pseudo" instance=0;
diff --git a/usr/src/uts/sun4u/starcat/io/cvcredir.c b/usr/src/uts/sun4u/starcat/io/cvcredir.c
deleted file mode 100644
index 245634cdce..0000000000
--- a/usr/src/uts/sun4u/starcat/io/cvcredir.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-/*
- * MT STREAMS Virtual Console Redirection Device Driver
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/stat.h>
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#include <sys/strsun.h>
-#include <sys/debug.h>
-#include <sys/thread.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/tty.h>
-#include <sys/sc_cvcio.h>
-#include <sys/conf.h>
-#include <sys/modctl.h>
-
-
-/*
- * Routine to to register/unregister our queue for console output and pass
- * redirected data to the console. The cvc driver will do a putnext using
- * our queue, so we will not see the redirected console data.
- */
-extern int cvc_redir(mblk_t *);
-extern int cvc_register(queue_t *);
-extern int cvc_unregister(queue_t *);
-
-static int cvcr_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
-static int cvcr_attach(dev_info_t *, ddi_attach_cmd_t);
-static int cvcr_detach(dev_info_t *, ddi_detach_cmd_t);
-static int cvcr_wput(queue_t *, mblk_t *);
-static int cvcr_open(queue_t *, dev_t *, int, int, cred_t *);
-static int cvcr_close(queue_t *, int, cred_t *);
-static void cvcr_ioctl(queue_t *, mblk_t *);
-
-static dev_info_t *cvcr_dip;
-static int cvcr_suspend = 0;
-
-static struct module_info minfo = {
- 1314, /* mi_idnum Bad luck number +1 ;-) */
- "cvcredir", /* mi_idname */
- 0, /* mi_minpsz */
- INFPSZ, /* mi_maxpsz */
- 2048, /* mi_hiwat */
- 2048 /* mi_lowat */
-};
-
-static struct qinit cvcr_rinit = {
- NULL, /* qi_putp */
- NULL, /* qi_srvp */
- cvcr_open, /* qi_qopen */
- cvcr_close, /* qi_qclose */
- NULL, /* qi_qadmin */
- &minfo, /* qi_minfo */
- NULL /* qi_mstat */
-};
-
-static struct qinit cvcr_winit = {
- cvcr_wput, /* qi_putp */
- NULL, /* qi_srvp */
- cvcr_open, /* qi_qopen */
- cvcr_close, /* qi_qclose */
- NULL, /* qi_qadmin */
- &minfo, /* qi_minfo */
- NULL /* qi_mstat */
-};
-
-struct streamtab cvcrinfo = {
- &cvcr_rinit, /* st_rdinit */
- &cvcr_winit, /* st_wrinit */
- NULL, /* st_muxrinit */
- NULL /* st_muxwrinit */
-};
-
-DDI_DEFINE_STREAM_OPS(cvcrops, nulldev, nulldev, cvcr_attach,
- cvcr_detach, nodev, cvcr_info, (D_MTPERQ|D_MP), &cvcrinfo,
- ddi_quiesce_not_supported);
-
-extern struct mod_ops mod_driverops;
-
-static struct modldrv modldrv = {
- &mod_driverops, /* Type of module. This one is a pseudo driver */
- "CVC redirect driver 'cvcredir'",
- &cvcrops, /* driver ops */
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- &modldrv,
- NULL
-};
-
-
-int
-_init()
-{
- return (mod_install(&modlinkage));
-}
-
-int
-_fini()
-{
- return (mod_remove(&modlinkage));
-}
-
-int
-_info(modinfop)
- struct modinfo *modinfop;
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-/*ARGSUSED*/
-static int
-cvcr_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
-{
- if (cmd == DDI_RESUME) {
- if (cvcr_suspend) {
- cvcr_suspend = 0;
- }
- } else {
- if (ddi_create_minor_node(devi, "cvcredir", S_IFCHR,
- 0, NULL, NULL) == DDI_FAILURE) {
- ddi_remove_minor_node(devi, NULL);
- return (-1);
- }
- cvcr_dip = devi;
- }
- return (DDI_SUCCESS);
-}
-
-static int
-cvcr_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- if (cmd == DDI_SUSPEND) {
- if (!cvcr_suspend) {
- cvcr_suspend = 1;
- }
- } else {
- if (cmd != DDI_DETACH) {
- return (DDI_FAILURE);
- }
- ddi_remove_minor_node(dip, NULL);
- }
- return (DDI_SUCCESS);
-}
-
-/* ARGSUSED */
-static int
-cvcr_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
-{
- register int error;
-
- switch (infocmd) {
- case DDI_INFO_DEVT2DEVINFO:
- if (cvcr_dip == NULL) {
- error = DDI_FAILURE;
- } else {
- *result = (void *)cvcr_dip;
- error = DDI_SUCCESS;
- }
- break;
- case DDI_INFO_DEVT2INSTANCE:
- *result = (void *)0;
- error = DDI_SUCCESS;
- break;
- default:
- error = DDI_FAILURE;
- }
- return (error);
-}
-
-/* ARGSUSED */
-static int
-cvcr_open(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *cred)
-{
- WR(q)->q_ptr = q->q_ptr = (char *)2;
- /*
- * call into the cvc driver to register our queue. cvc will use
- * our queue to send console output data upstream (our stream)to
- * cvcd which has us open and is reading console data.
- */
- if (cvc_register(RD(q)) == -1) {
- cmn_err(CE_WARN, "cvcr_open: cvc_register failed for q = 0x%p",
- (void *)q);
- }
- return (0);
-}
-
-/* ARGSUSED */
-static int
-cvcr_close(queue_t *q, int flag, cred_t *cred)
-{
- /*
- * call into the cvc driver to un-register our queue. cvc will
- * no longer use our queue to send console output data upstream.
- */
- (void) cvc_unregister(RD(q));
- WR(q)->q_ptr = q->q_ptr = NULL;
- return (0);
-}
-
-static int
-cvcr_wput(queue_t *q, mblk_t *mp)
-{
- /*
- * Handle network-transmitted control messages
- */
- if (mp->b_datap->db_type == M_IOCTL) {
- cvcr_ioctl(q, mp);
- return (0);
- }
- /*
- * Call into the cvc driver to put console input data on
- * its upstream queue to be picked up by the console driver.
- */
- if (!cvc_redir(mp))
- freemsg(mp);
- return (0);
-}
-
-static void
-cvcr_ioctl(queue_t *q, mblk_t *mp)
-{
- struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
-
- /*
- * If this is a CVC_BREAK, drop to OBP/kmdb from here rather than
- * passing the mblk on to cvc. If it is a disconnect, pass it on to
- * cvc. Nothing else is currently supported, so NAK all others.
- * Note that cvc_redir doesn't free the mblk passed in, so we can
- * reuse it for ACKing.
- */
- if (iocp->ioc_cmd == CVC_BREAK) {
- abort_sequence_enter((char *)NULL);
- miocack(q, mp, 0, 0);
- } else if (iocp->ioc_cmd == CVC_DISCONNECT) {
- (void) cvc_redir(mp);
- miocack(q, mp, 0, 0);
- } else {
- miocnak(q, mp, 0, EINVAL);
- }
-}
diff --git a/usr/src/uts/sun4u/starcat/io/cvcredir.conf b/usr/src/uts/sun4u/starcat/io/cvcredir.conf
deleted file mode 100644
index fab5da03ec..0000000000
--- a/usr/src/uts/sun4u/starcat/io/cvcredir.conf
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 2000 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-name="cvcredir" parent="pseudo" instance=0;
diff --git a/usr/src/uts/sun4u/starcat/io/dman.c b/usr/src/uts/sun4u/starcat/io/dman.c
deleted file mode 100644
index ca01477ef1..0000000000
--- a/usr/src/uts/sun4u/starcat/io/dman.c
+++ /dev/null
@@ -1,8327 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- * Copyright (c) 2016 by Delphix. All rights reserved.
- * Copyright (c) 2019 Peter Tribble.
- */
-
-
-/*
- * Starcat Management Network Driver
- *
- * ****** NOTICE **** This file also resides in the SSC gate as
- * ****** NOTICE **** usr/src/uts/sun4u/scman/scman.c. Any changes
- * ****** NOTICE **** made here must be propogated there as well.
- *
- */
-
-#include <sys/types.h>
-#include <sys/proc.h>
-#include <sys/disp.h>
-#include <sys/kmem.h>
-#include <sys/stat.h>
-#include <sys/kstat.h>
-#include <sys/ksynch.h>
-#include <sys/stream.h>
-#include <sys/dlpi.h>
-#include <sys/stropts.h>
-#include <sys/strsubr.h>
-#include <sys/debug.h>
-#include <sys/conf.h>
-#include <sys/kstr.h>
-#include <sys/errno.h>
-#include <sys/ethernet.h>
-#include <sys/byteorder.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/sunldi.h>
-#include <sys/modctl.h>
-#include <sys/strsun.h>
-#include <sys/callb.h>
-#include <sys/pci.h>
-#include <netinet/in.h>
-#include <inet/common.h>
-#include <inet/mi.h>
-#include <inet/nd.h>
-#include <sys/socket.h>
-#include <netinet/igmp_var.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <inet/ip.h>
-#include <inet/ip6.h>
-#include <sys/file.h>
-#include <sys/dman.h>
-#include <sys/autoconf.h>
-#include <sys/zone.h>
-
-extern int ddi_create_internal_pathname(dev_info_t *, char *, int, minor_t);
-
-#define MAN_IDNAME "dman"
-#define DMAN_INT_PATH "/devices/pseudo/dman@0:dman"
-#define DMAN_PATH "/devices/pseudo/clone@0:dman"
-#define ERI_IDNAME "eri"
-#define ERI_PATH "/devices/pseudo/clone@0:eri"
-
-#if defined(DEBUG)
-
-static void man_print_msp(manstr_t *);
-static void man_print_man(man_t *);
-static void man_print_mdp(man_dest_t *);
-static void man_print_dev(man_dev_t *);
-static void man_print_mip(mi_path_t *);
-static void man_print_mtp(mi_time_t *);
-static void man_print_mpg(man_pg_t *);
-static void man_print_path(man_path_t *);
-static void man_print_work(man_work_t *);
-
-/*
- * Set manstr_t dlpistate (upper half of multiplexor)
- */
-#define SETSTATE(msp, state) \
- MAN_DBG(MAN_DLPI, ("msp=0x%p @ %d state %s=>%s\n", \
- (void *)msp, __LINE__, dss[msp->ms_dlpistate], \
- dss[(state)])); \
- msp->ms_dlpistate = (state);
-/*
- * Set man_dest_t dlpistate (lower half of multiplexor)
- */
-#define D_SETSTATE(mdp, state) \
- MAN_DBG(MAN_DLPI, ("dst=0x%p @ %d state %s=>%s\n", \
- (void *)mdp, __LINE__, dss[mdp->md_dlpistate], \
- dss[(state)])); \
- mdp->md_dlpistate = (state);
-
-static char *promisc[] = { /* DLPI promisc Strings */
- "not used", /* 0x00 */
- "DL_PROMISC_PHYS", /* 0x01 */
- "DL_PROMISC_SAP", /* 0x02 */
- "DL_PROMISC_MULTI" /* 0x03 */
-};
-
-static char *dps[] = { /* DLPI Primitive Strings */
- "DL_INFO_REQ", /* 0x00 */
- "DL_BIND_REQ", /* 0x01 */
- "DL_UNBIND_REQ", /* 0x02 */
- "DL_INFO_ACK", /* 0x03 */
- "DL_BIND_ACK", /* 0x04 */
- "DL_ERROR_ACK", /* 0x05 */
- "DL_OK_ACK", /* 0x06 */
- "DL_UNITDATA_REQ", /* 0x07 */
- "DL_UNITDATA_IND", /* 0x08 */
- "DL_UDERROR_IND", /* 0x09 */
- "DL_UDQOS_REQ", /* 0x0a */
- "DL_ATTACH_REQ", /* 0x0b */
- "DL_DETACH_REQ", /* 0x0c */
- "DL_CONNECT_REQ", /* 0x0d */
- "DL_CONNECT_IND", /* 0x0e */
- "DL_CONNECT_RES", /* 0x0f */
- "DL_CONNECT_CON", /* 0x10 */
- "DL_TOKEN_REQ", /* 0x11 */
- "DL_TOKEN_ACK", /* 0x12 */
- "DL_DISCONNECT_REQ", /* 0x13 */
- "DL_DISCONNECT_IND", /* 0x14 */
- "DL_SUBS_UNBIND_REQ", /* 0x15 */
- "DL_LIARLIARPANTSONFIRE", /* 0x16 */
- "DL_RESET_REQ", /* 0x17 */
- "DL_RESET_IND", /* 0x18 */
- "DL_RESET_RES", /* 0x19 */
- "DL_RESET_CON", /* 0x1a */
- "DL_SUBS_BIND_REQ", /* 0x1b */
- "DL_SUBS_BIND_ACK", /* 0x1c */
- "DL_ENABMULTI_REQ", /* 0x1d */
- "DL_DISABMULTI_REQ", /* 0x1e */
- "DL_PROMISCON_REQ", /* 0x1f */
- "DL_PROMISCOFF_REQ", /* 0x20 */
- "DL_DATA_ACK_REQ", /* 0x21 */
- "DL_DATA_ACK_IND", /* 0x22 */
- "DL_DATA_ACK_STATUS_IND", /* 0x23 */
- "DL_REPLY_REQ", /* 0x24 */
- "DL_REPLY_IND", /* 0x25 */
- "DL_REPLY_STATUS_IND", /* 0x26 */
- "DL_REPLY_UPDATE_REQ", /* 0x27 */
- "DL_REPLY_UPDATE_STATUS_IND", /* 0x28 */
- "DL_XID_REQ", /* 0x29 */
- "DL_XID_IND", /* 0x2a */
- "DL_XID_RES", /* 0x2b */
- "DL_XID_CON", /* 0x2c */
- "DL_TEST_REQ", /* 0x2d */
- "DL_TEST_IND", /* 0x2e */
- "DL_TEST_RES", /* 0x2f */
- "DL_TEST_CON", /* 0x30 */
- "DL_PHYS_ADDR_REQ", /* 0x31 */
- "DL_PHYS_ADDR_ACK", /* 0x32 */
- "DL_SET_PHYS_ADDR_REQ", /* 0x33 */
- "DL_GET_STATISTICS_REQ", /* 0x34 */
- "DL_GET_STATISTICS_ACK", /* 0x35 */
-};
-
-#define MAN_DLPI_MAX_PRIM 0x35
-
-static char *dss[] = { /* DLPI State Strings */
- "DL_UNBOUND", /* 0x00 */
- "DL_BIND_PENDING", /* 0x01 */
- "DL_UNBIND_PENDING", /* 0x02 */
- "DL_IDLE", /* 0x03 */
- "DL_UNATTACHED", /* 0x04 */
- "DL_ATTACH_PENDING", /* 0x05 */
- "DL_DETACH_PENDING", /* 0x06 */
- "DL_UDQOS_PENDING", /* 0x07 */
- "DL_OUTCON_PENDING", /* 0x08 */
- "DL_INCON_PENDING", /* 0x09 */
- "DL_CONN_RES_PENDING", /* 0x0a */
- "DL_DATAXFER", /* 0x0b */
- "DL_USER_RESET_PENDING", /* 0x0c */
- "DL_PROV_RESET_PENDING", /* 0x0d */
- "DL_RESET_RES_PENDING", /* 0x0e */
- "DL_DISCON8_PENDING", /* 0x0f */
- "DL_DISCON9_PENDING", /* 0x10 */
- "DL_DISCON11_PENDING", /* 0x11 */
- "DL_DISCON12_PENDING", /* 0x12 */
- "DL_DISCON13_PENDING", /* 0x13 */
- "DL_SUBS_BIND_PND", /* 0x14 */
- "DL_SUBS_UNBIND_PND", /* 0x15 */
-};
-
-static const char *lss[] = {
- "UNKNOWN", /* 0x0 */
- "INIT", /* 0x1 */
- "GOOD", /* 0x2 */
- "STALE", /* 0x3 */
- "FAIL", /* 0x4 */
-};
-
-static char *_mw_type[] = {
- "OPEN_CTL", /* 0x0 */
- "CLOSE_CTL", /* 0x1 */
- "SWITCH", /* 0x2 */
- "PATH_UPDATE", /* 0x3 */
- "CLOSE", /* 0x4 */
- "CLOSE_STREAM", /* 0x5 */
- "DRATTACH", /* 0x6 */
- "DRDETACH", /* 0x7 */
- "STOP", /* 0x8 */
- "DRSWITCH", /* 0x9 */
- "KSTAT_UPDATE" /* 0xA */
-};
-
-uint32_t man_debug = MAN_WARN;
-
-#define man_kzalloc(a, b) man_dbg_kzalloc(__LINE__, a, b)
-#define man_kfree(a, b) man_dbg_kfree(__LINE__, a, b)
-void *man_dbg_kzalloc(int line, size_t size, int kmflags);
-void man_dbg_kfree(int line, void *buf, size_t size);
-
-#else /* DEBUG */
-
-uint32_t man_debug = 0;
-/*
- * Set manstr_t dlpistate (upper half of multiplexor)
- */
-#define SETSTATE(msp, state) msp->ms_dlpistate = (state);
-/*
- * Set man_dest_t dlpistate (lower half of multiplexor)
- */
-#define D_SETSTATE(mdp, state) mdp->md_dlpistate = (state);
-
-#define man_kzalloc(a, b) kmem_zalloc(a, b)
-#define man_kfree(a, b) kmem_free(a, b)
-
-#endif /* DEBUG */
-
-#define DL_PRIM(mp) (((union DL_primitives *)(mp)->b_rptr)->dl_primitive)
-#define DL_PROMISCON_TYPE(mp) \
- (((union DL_primitives *)(mp)->b_rptr)->promiscon_req.dl_level)
-#define IOC_CMD(mp) (((struct iocblk *)(mp)->b_rptr)->ioc_cmd)
-
-/*
- * Start of kstat-related declarations
- */
-#define MK_NOT_COUNTER (1<<0) /* is it a counter? */
-#define MK_ERROR (1<<2) /* for error statistics */
-#define MK_NOT_PHYSICAL (1<<3) /* no matching physical stat */
-
-typedef struct man_kstat_info_s {
- char *mk_name; /* e.g. align_errors */
- char *mk_physname; /* e.g. framing (NULL for same) */
- char *mk_physalias; /* e.g. framing (NULL for same) */
- uchar_t mk_type; /* e.g. KSTAT_DATA_UINT32 */
- int mk_flags;
-} man_kstat_info_t;
-
-/*
- * Master declaration macro, note that it uses token pasting
- */
-#define MK_DECLARE(name, pname, palias, bits, flags) \
- { name, pname, palias, KSTAT_DATA_UINT ## bits, flags }
-
-/*
- * Obsolete forms don't have the _sinceswitch forms, they are all errors
- */
-#define MK_OBSOLETE32(name, alias) MK_DECLARE(alias, name, alias, 32, MK_ERROR)
-#define MK_OBSOLETE64(name, alias) MK_DECLARE(alias, name, alias, 64, MK_ERROR)
-
-/*
- * The only non-counters don't have any other aliases
- */
-#define MK_NOTCOUNTER32(name) MK_DECLARE(name, name, NULL, 32, MK_NOT_COUNTER)
-#define MK_NOTCOUNTER64(name) MK_DECLARE(name, name, NULL, 64, MK_NOT_COUNTER)
-
-/*
- * Normal counter forms
- */
-#define MK_DECLARE32(name, alias) \
- MK_DECLARE(name, name, alias, 32, 0)
-#define MK_DECLARE64(name, alias) \
- MK_DECLARE(name, name, alias, 64, 0)
-
-/*
- * Error counters need special MK_ERROR flag only for the non-AP form
- */
-#define MK_ERROR32(name, alias) \
- MK_DECLARE(name, name, alias, 32, MK_ERROR)
-#define MK_ERROR64(name, alias) \
- MK_DECLARE(name, name, alias, 64, MK_ERROR)
-
-/*
- * These AP-specific stats are not backed by physical statistics
- */
-#define MK_NOTPHYS32(name) MK_DECLARE(name, NULL, NULL, 32, MK_NOT_PHYSICAL)
-#define MK_NOTPHYS64(name) MK_DECLARE(name, NULL, NULL, 64, MK_NOT_PHYSICAL)
-
-/*
- * START of the actual man_kstat_info declaration using above macros
- */
-static man_kstat_info_t man_kstat_info[] = {
- /*
- * Link Input/Output stats
- */
- MK_DECLARE32("ipackets", NULL),
- MK_ERROR32("ierrors", NULL),
- MK_DECLARE32("opackets", NULL),
- MK_ERROR32("oerrors", NULL),
- MK_ERROR32("collisions", NULL),
- MK_NOTCOUNTER64("ifspeed"),
- /*
- * These are new MIB-II stats, per PSARC 1997/198
- */
- MK_DECLARE32("rbytes", NULL),
- MK_DECLARE32("obytes", NULL),
- MK_DECLARE32("multircv", NULL),
- MK_DECLARE32("multixmt", NULL),
- MK_DECLARE32("brdcstrcv", NULL),
- MK_DECLARE32("brdcstxmt", NULL),
- /*
- * Error values
- */
- MK_ERROR32("norcvbuf", NULL),
- MK_ERROR32("noxmtbuf", NULL),
- MK_ERROR32("unknowns", NULL),
- /*
- * These are the 64-bit values, they fallback to 32-bit values
- */
- MK_DECLARE64("ipackets64", "ipackets"),
- MK_DECLARE64("opackets64", "opackets"),
- MK_DECLARE64("rbytes64", "rbytes"),
- MK_DECLARE64("obytes64", "obytes"),
-
- /* New AP switching statistics */
- MK_NOTPHYS64("man_switches"),
- MK_NOTPHYS64("man_link_fails"),
- MK_NOTPHYS64("man_link_stales"),
- MK_NOTPHYS64("man_icmpv4_probes"),
- MK_NOTPHYS64("man_icmpv6_probes"),
-
- MK_ERROR32("align_errors", "framing"),
- MK_ERROR32("fcs_errors", "crc"),
- MK_ERROR32("first_collisions", NULL),
- MK_ERROR32("multi_collisions", NULL),
- MK_ERROR32("sqe_errors", "sqe"),
-
- MK_ERROR32("tx_late_collisions", NULL),
- MK_ERROR32("ex_collisions", "excollisions"),
- MK_ERROR32("macxmt_errors", NULL),
- MK_ERROR32("carrier_errors", "nocarrier"),
- MK_ERROR32("toolong_errors", "buff"),
- MK_ERROR32("macrcv_errors", NULL),
-
- MK_OBSOLETE32("framing", "align_errors"),
- MK_OBSOLETE32("crc", "fcs_errors"),
- MK_OBSOLETE32("sqe", "sqe_errors"),
- MK_OBSOLETE32("excollisions", "ex_collisions"),
- MK_OBSOLETE32("nocarrier", "carrier_errors"),
- MK_OBSOLETE32("buff", "toolong_errors"),
-};
-
-#define MAN_NUMSTATS (sizeof (man_kstat_info) / sizeof (man_kstat_info_t))
-
-/*
- * Miscellaneous ethernet stuff.
- *
- * MANs DL_INFO_ACK template.
- */
-static dl_info_ack_t man_infoack = {
- DL_INFO_ACK, /* dl_primitive */
- ETHERMTU, /* dl_max_sdu */
- 0, /* dl_min_sdu */
- MAN_ADDRL, /* dl_addr_length */
- DL_ETHER, /* dl_mac_type */
- 0, /* dl_reserved */
- 0, /* dl_current_state */
- -2, /* dl_sap_length */
- DL_CLDLS, /* dl_service_mode */
- 0, /* dl_qos_length */
- 0, /* dl_qos_offset */
- 0, /* dl_range_length */
- 0, /* dl_range_offset */
- DL_STYLE2, /* dl_provider_style */
- sizeof (dl_info_ack_t), /* dl_addr_offset */
- DL_VERSION_2, /* dl_version */
- ETHERADDRL, /* dl_brdcst_addr_length */
- sizeof (dl_info_ack_t) + MAN_ADDRL, /* dl_brdcst_addr_offset */
- 0 /* dl_growth */
-};
-
-/*
- * Ethernet broadcast address definition.
- */
-static struct ether_addr etherbroadcast = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
-
-static struct ether_addr zero_ether_addr = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/*
- * Set via MAN_SET_SC_IPADDRS ioctl.
- */
-man_sc_ipaddrs_t man_sc_ipaddrs = { 0xffffffffU, 0xffffffffU };
-
-/*
- * Set via MAN_SET_SC_IP6ADDRS ioctl.
- */
-man_sc_ip6addrs_t man_sc_ip6addrs = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-/*
- * IP & ICMP constants
- */
-#ifndef ETHERTYPE_IPV6
-#define ETHERTYPE_IPV6 0x86DD
-#endif
-
-/*
- * Function prototypes.
- *
- * Upper multiplexor functions.
- */
-static int man_attach(dev_info_t *, ddi_attach_cmd_t);
-static int man_detach(dev_info_t *, ddi_detach_cmd_t);
-static int man_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
-static int man_open(register queue_t *, dev_t *, int, int, cred_t *);
-static int man_configure(queue_t *);
-static int man_deconfigure(void);
-static int man_init_dests(man_t *, manstr_t *);
-static void man_start_dest(man_dest_t *, manstr_t *, man_pg_t *);
-static void man_set_optimized_dest(manstr_t *);
-static int man_close(queue_t *, int, cred_t *);
-static void man_cancel_timers(man_adest_t *);
-static int man_uwput(queue_t *, mblk_t *);
-static int man_start(queue_t *, mblk_t *, eaddr_t *);
-static void man_ioctl(queue_t *, mblk_t *);
-static void man_set_linkcheck_time(queue_t *, mblk_t *);
-static void man_setpath(queue_t *, mblk_t *);
-static void man_geteaddr(queue_t *, mblk_t *);
-static void man_set_sc_ipaddrs(queue_t *, mblk_t *);
-static void man_set_sc_ip6addrs(queue_t *, mblk_t *);
-static int man_get_our_etheraddr(eaddr_t *eap);
-static void man_nd_getset(queue_t *, mblk_t *);
-static void man_dl_ioc_hdr_info(queue_t *, mblk_t *);
-static int man_uwsrv(queue_t *);
-static int man_proto(queue_t *, mblk_t *);
-static int man_udreq(queue_t *, mblk_t *);
-static void man_areq(queue_t *, mblk_t *);
-static mblk_t *man_alloc_physreq_mp(eaddr_t *);
-static void man_dreq(queue_t *, mblk_t *);
-static void man_dodetach(manstr_t *, man_work_t *);
-static void man_dl_clean(mblk_t **);
-static void man_breq(queue_t *, mblk_t *);
-static void man_ubreq(queue_t *, mblk_t *);
-static void man_ireq(queue_t *, mblk_t *);
-static void man_ponreq(queue_t *, mblk_t *);
-static void man_poffreq(queue_t *, mblk_t *);
-static void man_emreq(queue_t *, mblk_t *);
-static void man_dmreq(queue_t *, mblk_t *);
-static void man_pareq(queue_t *, mblk_t *);
-static void man_spareq(queue_t *, mblk_t *);
-static int man_dlpi(manstr_t *, mblk_t *);
-static int man_dlioc(manstr_t *, mblk_t *);
-static int man_dl_catch(mblk_t **, mblk_t *);
-static void man_dl_release(mblk_t **, mblk_t *);
-static int man_match_proto(mblk_t *, mblk_t *);
-static int man_open_ctl();
-static void man_close_ctl();
-/*
- * upper/lower multiplexor functions.
- */
-static int man_dlpi_senddown(manstr_t *, mblk_t *);
-static int man_start_lower(man_dest_t *, mblk_t *, queue_t *, int caller);
-static int man_lrput(queue_t *, mblk_t *);
-/*
- * Lower multiplexor functions.
- */
-static int man_lwsrv(queue_t *);
-static int man_lrsrv(queue_t *);
-static void man_dlpi_replay(man_dest_t *, mblk_t *);
-static int man_dlioc_replay(man_dest_t *);
-/*
- * Link failover routines.
- */
-static int man_gettimer(int, man_dest_t *);
-static void man_linkcheck_timer(void *);
-static int man_needs_linkcheck(man_dest_t *);
-static int man_do_autoswitch(man_dest_t *);
-static int man_autoswitch(man_pg_t *, man_dev_t *, man_work_t *);
-static int man_prep_dests_for_switch(man_pg_t *, man_dest_t **, int *);
-static int man_str_uses_pg(manstr_t *, man_pg_t *);
-static void man_do_icmp_bcast(man_dest_t *, t_uscalar_t);
-static mblk_t *man_alloc_udreq(int, man_dladdr_t *);
-static mblk_t *man_pinger(t_uscalar_t);
-/*
- * Functions normally executing outside of the STREAMs perimeter.
- */
-/*
- * Functions supporting/processing work requests.
- */
-static void man_bwork(void);
-static void man_iwork(void); /* inside perimeter */
-void man_work_add(man_workq_t *, man_work_t *);
-man_work_t *man_work_alloc(int, int);
-void man_work_free(man_work_t *);
-/*
- * Functions implementing/supporting failover.
- *
- * Executed inside perimeter.
- */
-static int man_do_dr_attach(man_work_t *);
-static int man_do_dr_switch(man_work_t *);
-static void man_do_dr_detach(man_work_t *);
-static int man_iswitch(man_work_t *);
-static void man_ifail_dest(man_dest_t *);
-static man_dest_t *man_switch_match(man_dest_t *, int, void *);
-static void man_add_dests(man_pg_t *);
-static void man_reset_dlpi(void *);
-static mblk_t *man_dup_mplist(mblk_t *);
-static mblk_t *man_alloc_ubreq_dreq();
-/*
- * Executed outside perimeter (us man_lock for synchronization).
- */
-static void man_bclose(man_adest_t *);
-static void man_bswitch(man_adest_t *, man_work_t *);
-static int man_plumb(man_dest_t *);
-static void man_unplumb(man_dest_t *);
-static void man_plink(queue_t *, mblk_t *);
-static void man_unplink(queue_t *, mblk_t *);
-static void man_linkrec_insert(man_linkrec_t *);
-static queue_t *man_linkrec_find(int);
-/*
- * Functions supporting pathgroups
- */
-int man_pg_cmd(mi_path_t *, man_work_t *);
-static int man_pg_assign(man_pg_t **, mi_path_t *, int);
-static int man_pg_create(man_pg_t **, man_pg_t **, mi_path_t *);
-static int man_pg_unassign(man_pg_t **, mi_path_t *);
-static int man_pg_activate(man_t *, mi_path_t *, man_work_t *);
-static int man_pg_read(man_pg_t *, mi_path_t *);
-static man_pg_t *man_find_path_by_dev(man_pg_t *, man_dev_t *, man_path_t **);
-static man_pg_t *man_find_pg_by_id(man_pg_t *, int);
-static man_path_t *man_find_path_by_ppa(man_path_t *, int);
-static man_path_t *man_find_active_path(man_path_t *);
-static man_path_t *man_find_alternate_path(man_path_t *);
-static void man_path_remove(man_path_t **, man_path_t *);
-static void man_path_insert(man_path_t **, man_path_t *);
-static void man_path_merge(man_path_t **, man_path_t *);
-static int man_path_kstat_init(man_path_t *);
-static void man_path_kstat_uninit(man_path_t *);
-/*
- * Functions supporting kstat reporting.
- */
-static int man_kstat_update(kstat_t *, int);
-static void man_do_kstats(man_work_t *);
-static void man_update_path_kstats(man_t *);
-static void man_update_dev_kstats(kstat_named_t *, man_path_t *);
-static void man_sum_dests_kstats(kstat_named_t *, man_pg_t *);
-static void man_kstat_named_init(kstat_named_t *, int);
-static int man_kstat_byname(kstat_t *, char *, kstat_named_t *);
-static void man_sum_kstats(kstat_named_t *, kstat_t *, kstat_named_t *);
-/*
- * Functions supporting ndd.
- */
-static int man_param_register(param_t *, int);
-static int man_pathgroups_report(queue_t *, mblk_t *, caddr_t, cred_t *);
-static void man_preport(man_path_t *, mblk_t *);
-static int man_set_active_path(queue_t *, mblk_t *, char *, caddr_t,
- cred_t *);
-static int man_get_hostinfo(queue_t *, mblk_t *, caddr_t, cred_t *);
-static char *man_inet_ntoa(in_addr_t);
-static int man_param_get(queue_t *, mblk_t *, caddr_t, cred_t *);
-static int man_param_set(queue_t *, mblk_t *, char *, caddr_t, cred_t *);
-static void man_param_cleanup(void);
-static void man_nd_free(caddr_t *nd_pparam);
-/*
- * MAN SSC/Domain specific externs.
- */
-extern int man_get_iosram(manc_t *);
-extern int man_domain_configure(void);
-extern int man_domain_deconfigure(void);
-extern int man_dossc_switch(uint32_t);
-extern int man_is_on_domain;
-
-/*
- * Driver Globals protected by inner perimeter.
- */
-static manstr_t *man_strup = NULL; /* list of MAN STREAMS */
-static caddr_t man_ndlist = NULL; /* head of ndd var list */
-void *man_softstate = NULL;
-
-/*
- * Driver globals protected by man_lock.
- */
-kmutex_t man_lock; /* lock protecting vars below */
-static kthread_id_t man_bwork_id = NULL; /* background thread ID */
-man_workq_t *man_bwork_q; /* bgthread work q */
-man_workq_t *man_iwork_q; /* inner perim (uwsrv) work q */
-static man_linkrec_t *man_linkrec_head = NULL; /* list of linkblks */
-ldi_handle_t man_ctl_lh = NULL; /* MAN control handle */
-queue_t *man_ctl_wq = NULL; /* MAN control rq */
-static int man_config_state = MAN_UNCONFIGURED;
-static int man_config_error = ENODEV;
-
-/*
- * These parameters are accessed via ndd to report the link configuration
- * for the MAN driver. They can also be used to force configuration changes.
- */
-#define MAN_NOTUSR 0x0f000000
-
-/* ------------------------------------------------------------------------- */
-
-static param_t man_param_arr[] = {
- /* min max value name */
- { 0, 0xFFFF, 0, "man_debug_level"},
-};
-
-#define MAN_NDD_GETABLE 1
-#define MAN_NDD_SETABLE 2
-
-static uint32_t man_param_display[] = {
-/* DISPLAY */
-MAN_NDD_SETABLE, /* man_debug_level */
-};
-
-/*
- * STREAMs information.
- */
-static struct module_info man_m_info = {
- MAN_IDNUM, /* mi_idnum */
- MAN_IDNAME, /* mi_idname */
- MAN_MINPSZ, /* mi_minpsz */
- MAN_MAXPSZ, /* mi_maxpsz */
- MAN_HIWAT, /* mi_hiwat */
- MAN_LOWAT /* mi_lowat */
-};
-
-/*
- * Upper read queue does not do anything.
- */
-static struct qinit man_urinit = {
- NULL, /* qi_putp */
- NULL, /* qi_srvp */
- man_open, /* qi_qopen */
- man_close, /* qi_qclose */
- NULL, /* qi_qadmin */
- &man_m_info, /* qi_minfo */
- NULL /* qi_mstat */
-};
-
-static struct qinit man_lrinit = {
- man_lrput, /* qi_putp */
- man_lrsrv, /* qi_srvp */
- man_open, /* qi_qopen */
- man_close, /* qi_qclose */
- NULL, /* qi_qadmin */
- &man_m_info, /* qi_minfo */
- NULL /* qi_mstat */
-};
-
-static struct qinit man_uwinit = {
- man_uwput, /* qi_putp */
- man_uwsrv, /* qi_srvp */
- man_open, /* qi_qopen */
- man_close, /* qi_qclose */
- NULL, /* qi_qadmin */
- &man_m_info, /* qi_minfo */
- NULL /* qi_mstat */
-};
-
-static struct qinit man_lwinit = {
- NULL, /* qi_putp */
- man_lwsrv, /* qi_srvp */
- man_open, /* qi_qopen */
- man_close, /* qi_qclose */
- NULL, /* qi_qadmin */
- &man_m_info, /* qi_minfo */
- NULL /* qi_mstat */
-};
-
-static struct streamtab man_maninfo = {
- &man_urinit, /* st_rdinit */
- &man_uwinit, /* st_wrinit */
- &man_lrinit, /* st_muxrinit */
- &man_lwinit /* st_muxwrinit */
-};
-
-
-/*
- * Module linkage information for the kernel.
- *
- * Locking Theory:
- * D_MTPERMOD - Only an inner perimeter: All routines single
- * threaded (except put, see below).
- * D_MTPUTSHARED - Put routines enter inner perimeter shared (not
- * exclusive) for concurrency/performance reasons.
- *
- * Anyone who needs exclusive outer perimeter permission (changing
- * global data structures) does so via qwriter() calls. The
- * background thread does all its work outside of perimeter and
- * submits work via qtimeout() when data structures need to be
- * modified.
- */
-
-#define MAN_MDEV_FLAGS (D_MP|D_MTPERMOD|D_MTPUTSHARED)
-
-DDI_DEFINE_STREAM_OPS(man_ops, nulldev, nulldev, man_attach,
- man_detach, nodev, man_info, MAN_MDEV_FLAGS, &man_maninfo,
- ddi_quiesce_not_supported);
-
-extern int nodev(), nulldev();
-
-static struct modldrv modldrv = {
- &mod_driverops, /* Module type. This one is a pseudo driver */
- "MAN MetaDriver",
- &man_ops, /* driver ops */
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- (void *) &modldrv,
- NULL
-};
-
-
-/* Virtual Driver loader entry points */
-
-int
-_init(void)
-{
- int status = DDI_FAILURE;
-
- MAN_DBG(MAN_INIT, ("_init:"));
-
- status = mod_install(&modlinkage);
- if (status != 0) {
- cmn_err(CE_WARN, "man_init: mod_install failed"
- " error = %d", status);
- return (status);
- }
-
- status = ddi_soft_state_init(&man_softstate, sizeof (man_t), 4);
- if (status != 0) {
- cmn_err(CE_WARN, "man_init: ddi_soft_state_init failed"
- " error = %d", status);
- (void) mod_remove(&modlinkage);
- return (status);
- }
-
- man_bwork_q = man_kzalloc(sizeof (man_workq_t), KM_SLEEP);
- man_iwork_q = man_kzalloc(sizeof (man_workq_t), KM_SLEEP);
-
- mutex_init(&man_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&man_bwork_q->q_cv, NULL, CV_DRIVER, NULL);
- cv_init(&man_iwork_q->q_cv, NULL, CV_DRIVER, NULL);
-
- return (0);
-}
-
-/*
- * _info is called by modinfo().
- */
-int
-_info(struct modinfo *modinfop)
-{
- int status;
-
- MAN_DBG(MAN_INIT, ("_info:"));
-
- status = mod_info(&modlinkage, modinfop);
-
- MAN_DBG(MAN_INIT, ("_info: returns %d", status));
-
- return (status);
-}
-
-/*
- * _fini called by modunload() just before driver is unloaded from memory.
- */
-int
-_fini(void)
-{
- int status = 0;
-
- MAN_DBG(MAN_INIT, ("_fini:"));
-
-
- /*
- * The only upper stream left should be man_ctl_lh. Note that
- * man_close (upper stream) is synchronous (i.e. it waits for
- * all STREAMS framework associated with the upper stream to be
- * torn down). This guarantees that man_ctl_lh will never become
- * NULL until noone is around to notice. This assumption is made
- * in a few places like man_plumb, man_unplumb, etc.
- */
- if (man_strup && (man_strup->ms_next != NULL))
- return (EBUSY);
-
- /*
- * Deconfigure the driver.
- */
- status = man_deconfigure();
- if (status)
- goto exit;
-
- /*
- * need to detach every instance of the driver
- */
- status = mod_remove(&modlinkage);
- if (status != 0)
- goto exit;
-
- ddi_soft_state_fini(&man_softstate);
-
- /*
- * Free up locks.
- */
- mutex_destroy(&man_lock);
- cv_destroy(&man_bwork_q->q_cv);
- cv_destroy(&man_iwork_q->q_cv);
-
- man_kfree(man_bwork_q, sizeof (man_workq_t));
- man_kfree(man_iwork_q, sizeof (man_workq_t));
-
-exit:
-
- MAN_DBG(MAN_INIT, ("_fini: returns %d", status));
-
- return (status);
-}
-
-/*
- * Deconfigure the MAN driver.
- */
-static int
-man_deconfigure()
-{
- man_work_t *wp;
- int status = 0;
-
- MAN_DBG(MAN_CONFIG, ("man_deconfigure:\n"));
-
- mutex_enter(&man_lock);
-
- if (man_is_on_domain) {
- status = man_domain_deconfigure();
- if (status != 0)
- goto exit;
- }
-
- man_param_cleanup(); /* Free up NDD resources */
-
- /*
- * I may have to handle straggling work requests. Just qwait?
- * or cvwait? Called from _fini - TBD
- */
- ASSERT(man_bwork_q->q_work == NULL);
- ASSERT(man_iwork_q->q_work == NULL);
-
- MAN_DBG(MAN_CONFIG, ("man_deconfigure: submitting CLOSE_CTL\n"));
-
- if (man_ctl_lh != NULL) {
- wp = man_work_alloc(MAN_WORK_CLOSE_CTL, KM_SLEEP);
- wp->mw_flags = MAN_WFLAGS_CVWAITER;
- man_work_add(man_bwork_q, wp);
-
- while (!(wp->mw_flags & MAN_WFLAGS_DONE)) {
- cv_wait(&wp->mw_cv, &man_lock);
- }
- man_work_free(wp);
- }
-
- MAN_DBG(MAN_CONFIG, ("man_deconfigure: submitting STOP\n"));
- if (man_bwork_id != NULL) {
-
- wp = man_work_alloc(MAN_WORK_STOP, KM_SLEEP);
- wp->mw_flags = MAN_WFLAGS_CVWAITER;
- man_work_add(man_bwork_q, wp);
-
- while (!(wp->mw_flags & MAN_WFLAGS_DONE)) {
- cv_wait(&wp->mw_cv, &man_lock);
- }
- man_work_free(wp);
- }
- man_config_state = MAN_UNCONFIGURED;
-
-exit:
- mutex_exit(&man_lock);
-
- MAN_DBG(MAN_CONFIG, ("man_deconfigure: returns %d\n", status));
-
- return (status);
-}
-
-/*
- * man_attach - allocate resources and attach an instance of the MAN driver
- * The <man>.conf file controls how many instances of the MAN driver are
- * available.
- *
- * dip - devinfo of node
- * cmd - one of DDI_ATTACH | DDI_RESUME
- *
- * returns - success - DDI_SUCCESS
- * - failure - DDI_FAILURE
- */
-static int
-man_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
-{
- man_t *manp; /* per instance data */
- uchar_t flag = KSTAT_FLAG_WRITABLE; /* support netstat -kc */
- kstat_t *ksp;
- int minor_node_created = 0;
- int instance;
- eaddr_t man_eaddr;
-
- MAN_DBG(MAN_INIT, ("man_attach: \n"));
-
- if (cmd != DDI_ATTACH) {
- MAN_DBG(MAN_INIT, ("man_attach: bad command %d\n", cmd));
- return (DDI_FAILURE);
- }
-
- if (man_get_our_etheraddr(&man_eaddr))
- return (DDI_FAILURE);
-
- instance = ddi_get_instance(dip);
-
- /*
- * we assume that instance is always equal to zero.
- * and there will always only be one instance.
- * this is done because when dman opens itself via DMAN_INT_PATH,
- * the path assumes that the instance number is zero.
- * if we ever need to support multiple instances of the dman
- * driver or non-zero instances, this will have to change.
- */
- ASSERT(instance == 0);
-
- /*
- * Allocate per device info pointer and link in to global list of
- * MAN devices.
- */
- if ((ddi_soft_state_zalloc(man_softstate, instance) != DDI_SUCCESS) ||
- ((manp = ddi_get_soft_state(man_softstate, instance)) == NULL)) {
- cmn_err(CE_WARN, "man_attach: cannot zalloc soft state!");
- return (DDI_FAILURE);
- }
-
- ddi_set_driver_private(dip, manp);
- manp->man_dip = dip;
- manp->man_meta_major = ddi_driver_major(dip);
- manp->man_meta_ppa = instance;
-
- /*
- * Set ethernet address. Note that this address is duplicated
- * at md_src_eaddr.
- */
- ether_copy(&man_eaddr, &manp->man_eaddr);
- manp->man_eaddr_v = 1;
-
- MAN_DBG(MAN_INIT, ("man_attach: set ether to %s",
- ether_sprintf(&manp->man_eaddr)));
-
- /*
- * Initialize failover-related fields (timers and such),
- * taking values from properties if present.
- */
- manp->man_init_time = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
- "init_time", MAN_INIT_TIME);
-
- manp->man_linkcheck_time = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
- "linkcheck_time", MAN_LINKCHECK_TIME);
-
- manp->man_linkstale_time = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
- "man_linkstale_time", MAN_LINKSTALE_TIME);
-
- manp->man_linkstale_retries = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
- "man_linkstale_retries", MAN_LINKSTALE_RETRIES);
-
- manp->man_dr_delay = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
- "man_dr_delay", MAN_DR_DELAY);
-
- manp->man_dr_retries = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
- "man_dr_retries", MAN_DR_RETRIES);
-
- manp->man_kstat_waittime = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
- "man_kstat_waittime", MAN_KSTAT_WAITTIME);
-
- manp->man_dlpireset_time = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
- "man_dlpireset_time", MAN_DLPIRESET_TIME);
-
- if (ddi_create_internal_pathname(dip, MAN_IDNAME, S_IFCHR,
- ddi_get_instance(dip)) == DDI_SUCCESS) {
- minor_node_created = 1;
- } else {
- cmn_err(CE_WARN, "man_attach: failed for instance %d",
- ddi_get_instance(dip));
- goto exit;
- }
-
- if (ddi_create_minor_node(dip, MAN_IDNAME, S_IFCHR,
- ddi_get_instance(dip), DDI_NT_NET, CLONE_DEV) == DDI_SUCCESS) {
- minor_node_created = 1;
- } else {
- cmn_err(CE_WARN, "man_attach: failed for instance %d",
- ddi_get_instance(dip));
- goto exit;
- }
-
- /*
- * Allocate meta kstat_t for this instance of the driver.
- * Note that each of man_path_t keeps track of the kstats
- * for the real devices via mp_last_knp.
- */
-#ifdef kstat
- flag |= KSTAT_FLAG_PERSISTENT;
-#endif
- ksp = kstat_create(MAN_IDNAME, ddi_get_instance(dip), NULL, "net",
- KSTAT_TYPE_NAMED, MAN_NUMSTATS, flag);
-
- if (ksp == NULL) {
- cmn_err(CE_WARN, "man_attach(%d): kstat_create failed"
- " - manp(0x%p)", manp->man_meta_ppa,
- (void *)manp);
- goto exit;
- }
-
- man_kstat_named_init(ksp->ks_data, MAN_NUMSTATS);
- ksp->ks_update = man_kstat_update;
- ksp->ks_private = (void *) manp;
- manp->man_ksp = ksp;
- kstat_install(manp->man_ksp);
-
- ddi_report_dev(dip);
-
- MAN_DBG(MAN_INIT, ("man_attach(%d) returns DDI_SUCCESS",
- ddi_get_instance(dip)));
-
- return (DDI_SUCCESS);
-
-exit:
- if (minor_node_created)
- ddi_remove_minor_node(dip, NULL);
- ddi_set_driver_private(dip, NULL);
- ddi_soft_state_free(man_softstate, instance);
-
- MAN_DBG(MAN_INIT, ("man_attach(%d) eaddr returns DDI_FAILIRE",
- ddi_get_instance(dip)));
-
- return (DDI_FAILURE);
-
-}
-
-static int
-man_get_our_etheraddr(eaddr_t *eap)
-{
- manc_t manc;
- int status = 0;
-
- if (man_is_on_domain) {
- if (status = man_get_iosram(&manc))
- return (status);
- ether_copy(&manc.manc_dom_eaddr, eap);
- } else {
- (void) localetheraddr((struct ether_addr *)NULL, eap);
- }
-
- return (status);
-}
-
-/*
- * man_detach - detach an instance of a driver
- *
- * dip - devinfo of node
- * cmd - one of DDI_DETACH | DDI_SUSPEND
- *
- * returns - success - DDI_SUCCESS
- * - failure - DDI_FAILURE
- */
-static int
-man_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- register man_t *manp; /* per instance data */
- int instance;
-
- MAN_DBG(MAN_INIT, ("man_detach(%d):\n", ddi_get_instance(dip)));
-
- if (cmd != DDI_DETACH) {
- MAN_DBG(MAN_INIT, ("man_detach: bad command %d\n", cmd));
- return (DDI_FAILURE);
- }
-
- if (dip == NULL) {
- MAN_DBG(MAN_INIT, ("man_detach: dip == NULL\n"));
- return (DDI_FAILURE);
- }
-
- instance = ddi_get_instance(dip);
-
- mutex_enter(&man_lock);
-
- manp = (man_t *)ddi_get_soft_state(man_softstate, instance);
- if (manp == NULL) {
- mutex_exit(&man_lock);
-
- cmn_err(CE_WARN, "man_detach: unable to get softstate"
- " for instance = %d, dip = 0x%p!\n", instance,
- (void *)dip);
- return (DDI_FAILURE);
- }
-
- if (manp->man_refcnt != 0) {
- mutex_exit(&man_lock);
-
- cmn_err(CE_WARN, "man_detach: %s%d refcnt %d", MAN_IDNAME,
- instance, manp->man_refcnt);
- MAN_DBGCALL(MAN_INIT, man_print_man(manp));
-
- return (DDI_FAILURE);
- }
-
- ddi_remove_minor_node(dip, NULL);
-
- mutex_exit(&man_lock);
-
- kstat_delete(manp->man_ksp);
- ddi_soft_state_free(man_softstate, instance);
- ddi_set_driver_private(dip, NULL);
-
- MAN_DBG(MAN_INIT, ("man_detach returns DDI_SUCCESS"));
-
- return (DDI_SUCCESS);
-}
-
-/*
- * man_info:
- * As a standard DLPI style-2, man_info() should always return
- * DDI_FAILURE.
- *
- * However, man_open() has special treatment for a direct open
- * via kstr_open() without going through the CLONE driver.
- * To make this special kstr_open() work, we need to map
- * minor of 0 to instance 0.
- */
-/*ARGSUSED*/
-static int
-man_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
-{
- minor_t minor;
-
- switch (infocmd) {
- case DDI_INFO_DEVT2DEVINFO:
- break;
-
- case DDI_INFO_DEVT2INSTANCE:
- minor = getminor((dev_t)arg);
- if (minor == 0) {
- *result = (void *)(uintptr_t)minor;
- return (DDI_SUCCESS);
- }
- break;
- default:
- break;
- }
- return (DDI_FAILURE);
-}
-
-/* Standard Device Driver entry points */
-
-/*
- * man_open - open the device
- *
- * rq - upper read queue of the stream
- * devp - pointer to a device number
- * flag - information passed from the user program open(2) system call
- * sflag - stream flags
- * credp - pointer to the cred(9S) user credential structure
- *
- * returns - success - 0
- * - failure - errno value for failure
- */
-/*ARGSUSED*/
-static int
-man_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp)
-{
- int minordev = -1;
- manstr_t *msp;
- manstr_t *tsp;
- manstr_t **prevmsp;
- int status = 0;
-
- MAN_DBG(MAN_OCLOSE, ("man_open: rq(0x%p) sflag(0x%x)\n",
- (void *)rq, sflag));
-
- ASSERT(rq);
- ASSERT(sflag != MODOPEN);
-
- /*
- * reopen; q_ptr set to msp at open completion.
- */
- if (rq->q_ptr) {
- return (0);
- }
-
- /*
- * Allocate and initialize manstr_t for this device.
- */
- msp = man_kzalloc(sizeof (manstr_t), KM_SLEEP);
- SETSTATE(msp, DL_UNATTACHED);
- msp->ms_meta_ppa = -1;
- msp->ms_rq = rq;
- rq->q_ptr = WR(rq)->q_ptr = msp;
-
- /*
- * Get the MAN driver configured on 1st open. Note that the only way
- * we get sflag != CLONEOPEN is via the call in man_plumbctl(). All
- * CLONEOPEN calls to man_open will be via the file system
- * device node /dev/man, a pseudo clone device.
- */
-
- qprocson(rq);
-
- if (sflag == CLONEOPEN && man_config_state != MAN_CONFIGURED) {
- /*
- * First open calls man_configure. Everyone qwaits until
- * we get it open. See man_open_ctl() comments for mutex
- * lock/synchronization info.
- */
-
- mutex_enter(&man_lock);
-
- if (man_config_state == MAN_UNCONFIGURED) {
- man_config_state = MAN_CONFIGURING;
- mutex_exit(&man_lock);
- status = man_configure(rq);
- if (status != 0)
- goto exit;
- } else {
- while (man_config_state == MAN_CONFIGURING) {
-
- mutex_exit(&man_lock);
- status = qwait_sig(rq);
-
- if (status == 0) {
- status = EINTR;
- goto exit;
- }
-
- mutex_enter(&man_lock);
- }
- mutex_exit(&man_lock);
-
- if (man_config_error) {
- status = man_config_error;
- goto exit;
- }
- }
- }
-
- /*
- * Determine minor device number. man_open serialized by
- * D_MTPERMOD.
- */
- prevmsp = &man_strup;
- if (sflag == CLONEOPEN) {
-
- minordev = 0;
- for (; (tsp = *prevmsp) != NULL; prevmsp = &tsp->ms_next) {
- if (minordev < tsp->ms_minor)
- break;
- minordev++;
- }
- *devp = makedevice(getmajor(*devp), minordev);
-
- } else {
- /*
- * Should only get here from man_plumbctl().
- */
- /*LINTED E_ASSIGN_UINT_TO_SIGNED_INT*/
- minordev = getminor(*devp);
-
- /*
- * No need to protect this here as all opens are
- * qwaiting, and the bgthread (who is doing this open)
- * is the only one who mucks with this variable.
- */
- man_ctl_wq = WR(rq);
-
- ASSERT(minordev == 0); /* TBD delete this */
- }
-
- msp->ms_meta_maj = getmajor(*devp);
- msp->ms_minor = minordev;
- if (minordev == 0)
- msp->ms_flags = MAN_SFLAG_CONTROL;
-
- /*
- * Link new entry into global list of active entries.
- */
- msp->ms_next = *prevmsp;
- *prevmsp = msp;
-
-
- /*
- * Disable automatic enabling of our write service procedure.
- * We control this explicitly.
- */
- noenable(WR(rq));
-
-exit:
- MAN_DBG(MAN_OCLOSE, ("man_open: exit rq(0x%p) minor %d errno %d\n",
- (void *)rq, minordev, status));
-
- /*
- * Clean up on error.
- */
- if (status) {
- qprocsoff(rq);
- rq->q_ptr = WR(rq)->q_ptr = NULL;
- man_kfree((char *)msp, sizeof (manstr_t));
- } else
- (void) qassociate(rq, -1);
-
- return (status);
-}
-
-/*
- * Get the driver configured. Called from first man_open with exclusive
- * inner perimeter.
- */
-static int
-man_configure(queue_t *rq)
-{
- man_work_t *wp;
- int status = 0;
-
- MAN_DBG(MAN_CONFIG, ("man_configure:"));
-
- /*
- * Initialize NDD parameters.
- */
- if (!man_ndlist &&
- !man_param_register(man_param_arr, A_CNT(man_param_arr))) {
- cmn_err(CE_WARN, "man_configure: man_param_register failed!");
- man_config_error = ENOMEM;
- goto exit;
- }
-
- mutex_enter(&man_lock);
-
- /*
- * Start up background thread.
- */
- if (man_bwork_id == NULL)
- man_bwork_id = thread_create(NULL, 2 * DEFAULTSTKSZ,
- man_bwork, NULL, 0, &p0, TS_RUN, minclsyspri);
-
- /*
- * Submit work to get control stream opened. Qwait until its
- * done. See man_open_ctl for mutex lock/synchronization info.
- */
-
- if (man_ctl_lh == NULL) {
- wp = man_work_alloc(MAN_WORK_OPEN_CTL, KM_SLEEP);
- wp->mw_flags |= MAN_WFLAGS_QWAITER;
- wp->mw_q = WR(rq);
-
- /*
- * Submit work and wait. When man_open_ctl exits
- * man_open, it will cause qwait below to return.
- */
- man_work_add(man_bwork_q, wp);
- while (!(wp->mw_flags & MAN_WFLAGS_DONE)) {
- mutex_exit(&man_lock);
- qwait(rq);
- mutex_enter(&man_lock);
- }
- status = wp->mw_status;
- man_work_free(wp);
-
- }
- mutex_exit(&man_lock);
-
- /*
- * If on domain, setup IOSRAM and build the pathgroups
- * automatically.
- */
- if ((status == 0) && man_is_on_domain)
- status = man_domain_configure();
-
-exit:
- mutex_enter(&man_lock);
-
- man_config_error = status;
- if (status != 0)
- man_config_state = MAN_UNCONFIGURED;
- else
- man_config_state = MAN_CONFIGURED;
-
- mutex_exit(&man_lock);
-
- MAN_DBG(MAN_CONFIG, ("man_configure: returns %d\n", status));
-
- return (status);
-}
-
-/*
- * man_close - close the device
- *
- * rq - upper read queue of the stream
- *
- * returns - success - 0
- * - failure - errno value for failure
- */
-static int
-man_close(queue_t *rq, int flag __unused, cred_t *cr __unused)
-{
- manstr_t *close_msp;
- manstr_t *msp;
-
- MAN_DBG(MAN_OCLOSE, ("man_close: rq(0x%p)\n", (void *)rq));
-
- qprocsoff(rq);
- close_msp = (manstr_t *)rq->q_ptr;
-
- /*
- * Unlink the per-Stream entry from the active list and free it.
- */
- if (close_msp == man_strup)
- man_strup = close_msp->ms_next;
- else {
- for (msp = man_strup; msp && msp->ms_next != close_msp; )
- msp = msp->ms_next;
-
- if (msp == NULL) {
- cmn_err(CE_WARN, "man_close: no stream!");
- return (ENODEV);
- }
-
- msp->ms_next = close_msp->ms_next;
- }
-
- if (close_msp->ms_dests != NULL) {
- /*
- * Still DL_ATTACHED
- */
- man_work_t *wp;
-
- wp = man_work_alloc(MAN_WORK_CLOSE_STREAM, KM_SLEEP);
- man_dodetach(close_msp, wp);
- }
-
- if (close_msp->ms_flags & MAN_SFLAG_CONTROL) {
- /*
- * Driver about to unload.
- */
- man_ctl_wq = NULL;
- }
-
- rq->q_ptr = WR(rq)->q_ptr = NULL;
- man_kfree((char *)close_msp, sizeof (manstr_t));
- (void) qassociate(rq, -1);
-
- MAN_DBG(MAN_OCLOSE, ("man_close: exit\n"));
-
- return (0);
-}
-
-/*
- * Ask bgthread to tear down lower stream and qwait
- * until its done.
- */
-static void
-man_dodetach(manstr_t *msp, man_work_t *wp)
-{
- man_dest_t *mdp;
- int i;
- mblk_t *mp;
-
- mdp = msp->ms_dests;
- msp->ms_dests = NULL;
- msp->ms_destp = NULL;
-
- /*
- * Excise lower dests array, set it closing and hand it to
- * background thread to dispose of.
- */
- for (i = 0; i < MAN_MAX_DESTS; i++) {
-
- mdp[i].md_state |= MAN_DSTATE_CLOSING;
- mdp[i].md_msp = NULL;
- mdp[i].md_rq = NULL;
-
- if (mdp[i].md_lc_timer_id != 0) {
- (void) quntimeout(man_ctl_wq, mdp[i].md_lc_timer_id);
- mdp[i].md_lc_timer_id = 0;
- }
- if (mdp[i].md_bc_id != 0) {
- qunbufcall(man_ctl_wq, mdp[i].md_bc_id);
- mdp[i].md_bc_id = 0;
- }
-
- mutex_enter(&mdp[i].md_lock);
- while ((mp = mdp[i].md_dmp_head) != NULL) {
- mdp[i].md_dmp_head = mp->b_next;
- mp->b_next = NULL;
- freemsg(mp);
- }
- mdp[i].md_dmp_count = 0;
- mdp[i].md_dmp_tail = NULL;
- mutex_exit(&mdp[i].md_lock);
- }
-
- /*
- * Dump any DL type messages previously caught.
- */
- man_dl_clean(&msp->ms_dl_mp);
- man_dl_clean(&msp->ms_dlioc_mp);
-
- /*
- * We need to clear fast path flag when dlioc messages are cleaned.
- */
- msp->ms_flags &= ~MAN_SFLAG_FAST;
-
- /*
- * MAN_WORK_CLOSE_STREAM work request preallocated by caller.
- */
- ASSERT(wp->mw_type == MAN_WORK_CLOSE_STREAM);
- ASSERT(mdp != NULL);
- wp->mw_arg.a_mdp = mdp;
- wp->mw_arg.a_ndests = MAN_MAX_DESTS;
- wp->mw_arg.a_pg_id = -1; /* Don't care */
-
- mutex_enter(&man_lock);
- man_work_add(man_bwork_q, wp);
- msp->ms_manp->man_refcnt--;
- mutex_exit(&man_lock);
-
- msp->ms_manp = NULL;
-
-}
-
-
-/*
- * man_uwput - handle DLPI messages issued from upstream, the write
- * side of the upper half of multiplexor. Called with shared access to
- * the inner perimeter.
- *
- * wq - upper write queue of mxx
- * mp - mblk ptr to DLPI request
- */
-static int
-man_uwput(register queue_t *wq, register mblk_t *mp)
-{
- register manstr_t *msp; /* per stream data */
- register man_t *manp; /* per instance data */
-
- msp = (manstr_t *)wq->q_ptr;
-
- MAN_DBG(MAN_UWPUT, ("man_uwput: wq(0x%p) mp(0x%p) db_type(0x%x)"
- " msp(0x%p)\n",
- (void *)wq, (void *)mp, DB_TYPE(mp), (void *)msp));
-#if DEBUG
- if (man_debug & MAN_UWPUT) {
- if (DB_TYPE(mp) == M_IOCTL) {
- struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
- MAN_DBG(MAN_UWPUT,
- ("man_uwput: M_IOCTL ioc_cmd(0x%x)\n",
- iocp->ioc_cmd));
- } else if (DB_TYPE(mp) == M_CTL) {
- struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
- MAN_DBG(MAN_UWPUT,
- ("man_uwput: M_CTL ioc_cmd(0x%x)\n",
- iocp->ioc_cmd));
- }
- }
-#endif /* DEBUG */
-
-
- switch (DB_TYPE(mp)) {
- case M_DATA:
- manp = msp->ms_manp;
-
- if (((msp->ms_flags & (MAN_SFLAG_FAST | MAN_SFLAG_RAW)) == 0) ||
- (msp->ms_dlpistate != DL_IDLE) ||
- (manp == NULL)) {
-
- merror(wq, mp, EPROTO);
- break;
- }
-
- if (wq->q_first) {
- (void) putq(wq, mp);
- qenable(wq);
- } else {
- ehdr_t *ep = (ehdr_t *)mp->b_rptr;
-
- (void) man_start(wq, mp, &ep->ether_dhost);
- }
- break;
-
- case M_PROTO:
- case M_PCPROTO:
- if ((DL_PRIM(mp) == DL_UNITDATA_IND) && !wq->q_first) {
- (void) man_udreq(wq, mp);
- } else {
- (void) putq(wq, mp);
- qenable(wq);
- }
- break;
-
- case M_IOCTL:
- case M_IOCDATA:
- qwriter(wq, mp, man_ioctl, PERIM_INNER);
- break;
-
- case M_CTL:
- freemsg(mp);
- break;
-
- case M_FLUSH:
- MAN_DBG(MAN_UWPUT, ("man_wput: M_FLUSH\n"));
- if (*mp->b_rptr & FLUSHW)
- flushq(wq, FLUSHDATA);
- if (*mp->b_rptr & FLUSHR) {
- flushq(RD(wq), FLUSHDATA);
- *mp->b_rptr &= ~FLUSHW;
- qreply(wq, mp);
- } else {
- freemsg(mp);
- }
- break;
-
- default:
- MAN_DBG(MAN_WARN,
- ("man_uwput: illegal mblk(0x%p) type(0x%x)\n",
- (void *)mp, DB_TYPE(mp)));
- freemsg(mp);
- break;
- } /* End switch */
-
- MAN_DBG(MAN_UWPUT, ("man_uwput: exit wq(0x%p) mp(0x%p)\n",
- (void *)wq, (void *)mp));
-
- return (0);
-}
-
-/*
- * man_start - handle data messages issued from upstream. Send down
- * to particular man_dest based on ether_addr, otherwise send out to all
- * valid man_dests.
- *
- * wq - upper write queue of mxx
- * mp - mblk ptr to DLPI request
- * caller - Caller ID for decision making on canput failure
- *
- * Returns:
- * 0 - Data xmitted or No flow control situation detected.
- * 1 - Flow control situation detected.
- *
- * STREAMS Flow Control: can be used if there is only one destination
- * for a stream (1 to 1 multiplexor). In this case, we will use the upper
- * write queue to store mblks when in flow control. If there are multiple
- * destinations, we cannot use the STREAMs based flow control (1 to many
- * multiplexor). In this case, we will use the lower write queue to store
- * mblks when in flow control. Since destinations come and go, we may
- * transition between 1-to-1 and 1-to-m. So it may be the case that we have
- * some mblks stored on the upper queue, and some on the lower queue. However,
- * we will never send mblks out of order. See man_uwput and man_start_lower().
- *
- * A simple flow control mechanism is implemented for the deferred mblk list,
- * as this list is expected to be used temporarily for a very short
- * period required for switching paths. This flow control mechanism is
- * used only as a defensive approach to avoid infinite growth of this list.
- */
-static int
-man_start(register queue_t *wq, register mblk_t *mp, eaddr_t *eap)
-{
- register manstr_t *msp; /* per stream data */
- register man_dest_t *mdp = NULL; /* destination */
- mblk_t *tmp;
- int i;
- int status = 0;
-
- msp = (manstr_t *)wq->q_ptr;
-
- MAN_DBG(MAN_DATA, ("man_start: msp(0x%p) ether_addr(%s)\n",
- (void *)msp, ether_sprintf(eap)));
-
- if (msp->ms_dests == NULL) {
- cmn_err(CE_WARN, "man_start: no destinations");
- freemsg(mp);
- return (0);
- }
-
- /*
- * Optimization if only one valid destination.
- */
- mdp = msp->ms_destp;
-
- if (IS_UNICAST(eap)) {
- queue_t *flow_wq = NULL;
-
- if (mdp == NULL) {
- /*
- * TDB - This needs to be optimized (some bits in
- * ehp->dhost will act as an index.
- */
- for (i = 0; i < MAN_MAX_DESTS; i++) {
-
- mdp = &msp->ms_dests[i];
-
- if ((mdp->md_state == MAN_DSTATE_READY) &&
- (ether_cmp(eap, &mdp->md_dst_eaddr) == 0))
- break;
- mdp = NULL;
- }
- } else {
- /*
- * 1 to 1 multiplexing, use upper wq for flow control.
- */
- flow_wq = wq;
- }
-
- if (mdp != NULL) {
- /*
- * Its going somewhere specific
- */
- status = man_start_lower(mdp, mp, flow_wq, MAN_UPPER);
-
- } else {
- MAN_DBG(MAN_DATA, ("man_start: no destination"
- " for eaddr %s\n", ether_sprintf(eap)));
- freemsg(mp);
- }
- } else {
- /*
- * Broadcast or multicast - send everone a copy.
- */
- if (mdp == NULL) {
- for (i = 0; i < MAN_MAX_DESTS; i++) {
- mdp = &msp->ms_dests[i];
-
- if (mdp->md_state != MAN_DSTATE_READY)
- continue;
-
- if ((tmp = copymsg(mp)) != NULL) {
- (void) man_start_lower(mdp, tmp,
- NULL, MAN_UPPER);
- } else {
- MAN_DBG(MAN_DATA, ("man_start: copymsg"
- " failed!"));
- }
- }
- freemsg(mp);
- } else {
- if (mdp->md_state == MAN_DSTATE_READY)
- status = man_start_lower(mdp, mp, wq,
- MAN_UPPER);
- else
- freemsg(mp);
- }
- }
- return (status);
-}
-
-/*
- * Send a DL_UNITDATA or M_DATA fastpath data mblk to a particular
- * destination. Others mblk types sent down via * man_dlpi_senddown().
- *
- * Returns:
- * 0 - Data xmitted
- * 1 - Data not xmitted due to flow control.
- */
-static int
-man_start_lower(man_dest_t *mdp, mblk_t *mp, queue_t *flow_wq, int caller)
-{
- queue_t *wq = mdp->md_wq;
- int status = 0;
-
- /*
- * Lower stream ready for data transmit.
- */
- if (mdp->md_state == MAN_DSTATE_READY &&
- mdp->md_dlpistate == DL_IDLE) {
-
- ASSERT(mdp->md_wq != NULL);
-
- if (caller == MAN_UPPER) {
- /*
- * Check for flow control conditions for lower
- * stream.
- */
- if (mdp->md_dmp_head == NULL &&
- wq->q_first == NULL && canputnext(wq)) {
-
- (void) putnext(wq, mp);
-
- } else {
- mutex_enter(&mdp->md_lock);
- if (mdp->md_dmp_head != NULL) {
- /*
- * A simple flow control mechanism.
- */
- if (mdp->md_dmp_count >= MAN_HIWAT) {
- freemsg(mp);
- } else {
- /*
- * Add 'mp' to the deferred
- * msg list.
- */
- mdp->md_dmp_tail->b_next = mp;
- mdp->md_dmp_tail = mp;
- mdp->md_dmp_count +=
- msgsize(mp);
- }
- mutex_exit(&mdp->md_lock);
- /*
- * Inform flow control situation
- * to the caller.
- */
- status = 1;
- qenable(wq);
- goto exit;
- }
- mutex_exit(&mdp->md_lock);
- /*
- * If 1 to 1 mux, use upper write queue for
- * flow control.
- */
- if (flow_wq != NULL) {
- /*
- * putbq() message and indicate
- * flow control situation to the
- * caller.
- */
- (void) putbq(flow_wq, mp);
- qenable(flow_wq);
- status = 1;
- goto exit;
- }
- /*
- * 1 to many mux, use lower write queue for
- * flow control. Be mindful not to overflow
- * the lower MAN STREAM q.
- */
- if (canput(wq)) {
- (void) putq(wq, mp);
- qenable(wq);
- } else {
- MAN_DBG(MAN_DATA, ("man_start_lower:"
- " lower q flow controlled -"
- " discarding packet"));
- freemsg(mp);
- goto exit;
- }
- }
-
- } else {
- /*
- * man_lwsrv is draining flow controlled mblks.
- */
- if (canputnext(wq))
- (void) putnext(wq, mp);
- else
- status = 1;
- }
- goto exit;
- }
-
- /*
- * Lower stream in transition, do flow control.
- */
- status = 1;
-
- if (mdp->md_state == MAN_DSTATE_NOTPRESENT) {
-nodest:
- cmn_err(CE_WARN,
- "man_start_lower: no dest for mdp(0x%p), caller(%d)!",
- (void *)mdp, caller);
- if (caller == MAN_UPPER)
- freemsg(mp);
- goto exit;
- }
-
- if (mdp->md_state & MAN_DSTATE_CLOSING) {
- MAN_DBG(MAN_DATA, ("man_start_lower: mdp(0x%p) closing",
- (void *)mdp));
- if (caller == MAN_UPPER)
- freemsg(mp);
- goto exit;
- }
-
- if ((mdp->md_state & MAN_DSTATE_PLUMBING) ||
- (mdp->md_state == MAN_DSTATE_INITIALIZING) ||
- (mdp->md_dlpistate != DL_IDLE)) {
- /*
- * Defer until PLUMBED and DL_IDLE. See man_lwsrv().
- */
- if (caller == MAN_UPPER) {
- /*
- * Upper stream sending data down, add to defered mblk
- * list for stream.
- */
- mutex_enter(&mdp->md_lock);
- if (mdp->md_dmp_count >= MAN_HIWAT) {
- freemsg(mp);
- } else {
- if (mdp->md_dmp_head == NULL) {
- ASSERT(mdp->md_dmp_tail == NULL);
- mdp->md_dmp_head = mp;
- mdp->md_dmp_tail = mp;
- } else {
- mdp->md_dmp_tail->b_next = mp;
- mdp->md_dmp_tail = mp;
- }
- mdp->md_dmp_count += msgsize(mp);
- }
- mutex_exit(&mdp->md_lock);
- }
-
- goto exit;
- }
-
-exit:
- return (status);
-}
-
-/*
- * man_ioctl - handle ioctl requests for this driver (I_PLINK/I_PUNLINK)
- * or pass thru to the physical driver below. Note that most M_IOCTLs we
- * care about come down the control msp, but the IOC ones come down the IP.
- * Called with exclusive inner perimeter.
- *
- * wq - upper write queue of mxx
- * mp - mblk ptr to DLPI ioctl request
- */
-static void
-man_ioctl(register queue_t *wq, register mblk_t *mp)
-{
- manstr_t *msp;
- struct iocblk *iocp;
-
- iocp = (struct iocblk *)mp->b_rptr;
- msp = (manstr_t *)wq->q_ptr;
-
-#ifdef DEBUG
- {
- char ioc_cmd[30];
-
- (void) sprintf(ioc_cmd, "not handled IOCTL 0x%x",
- iocp->ioc_cmd);
- MAN_DBG((MAN_SWITCH | MAN_PATH | MAN_DLPI),
- ("man_ioctl: wq(0x%p) mp(0x%p) cmd(%s)\n",
- (void *)wq, (void *)mp,
- (iocp->ioc_cmd == I_PLINK) ? "I_PLINK" :
- (iocp->ioc_cmd == I_PUNLINK) ? "I_PUNLINK" :
- (iocp->ioc_cmd == MAN_SETPATH) ? "MAN_SETPATH" :
- (iocp->ioc_cmd == DL_IOC_HDR_INFO) ? "DL_IOC_HDR_INFO" :
- (iocp->ioc_cmd == DLIOCRAW) ? "DLIOCRAW" : ioc_cmd));
- }
-#endif /* DEBUG */
-
-
- /*
- * Handle the requests...
- */
- switch ((unsigned int)iocp->ioc_cmd) {
-
- case I_PLINK:
- man_plink(wq, mp);
- break;
-
- case I_PUNLINK:
- man_unplink(wq, mp);
- break;
-
- case MAN_SETPATH:
- man_setpath(wq, mp);
- break;
-
- case MAN_GETEADDR:
- man_geteaddr(wq, mp);
- break;
-
- case MAN_SET_LINKCHECK_TIME:
- man_set_linkcheck_time(wq, mp);
- break;
-
- case MAN_SET_SC_IPADDRS:
- man_set_sc_ipaddrs(wq, mp);
- break;
-
- case MAN_SET_SC_IP6ADDRS:
- man_set_sc_ip6addrs(wq, mp);
- break;
-
- case DLIOCRAW:
- if (man_dlioc(msp, mp))
- miocnak(wq, mp, 0, ENOMEM);
- else {
- msp->ms_flags |= MAN_SFLAG_RAW;
- miocack(wq, mp, 0, 0);
- }
- break;
-
- case DL_IOC_HDR_INFO:
- man_dl_ioc_hdr_info(wq, mp);
- break;
-
- case MAN_ND_GET:
- case MAN_ND_SET:
- man_nd_getset(wq, mp);
- break;
-
- default:
- MAN_DBG(MAN_DDI, ("man_ioctl: unknown ioc_cmd %d\n",
- (unsigned int)iocp->ioc_cmd));
- miocnak(wq, mp, 0, EINVAL);
- break;
- }
-exit:
- MAN_DBG((MAN_SWITCH | MAN_PATH | MAN_DLPI), ("man_ioctl: exit\n"));
-
-}
-
-/*
- * man_plink: handle I_PLINK requests on the control stream
- */
-void
-man_plink(queue_t *wq, mblk_t *mp)
-{
- struct linkblk *linkp;
- man_linkrec_t *lrp;
- int status = 0;
-
- linkp = (struct linkblk *)mp->b_cont->b_rptr;
-
- /*
- * Create a record to hold lower stream info. man_plumb will
- * retrieve it after calling ldi_ioctl(I_PLINK)
- */
- lrp = man_kzalloc(sizeof (man_linkrec_t), KM_NOSLEEP);
- if (lrp == NULL) {
- status = ENOMEM;
- goto exit;
- }
-
- lrp->l_muxid = linkp->l_index;
- lrp->l_wq = linkp->l_qbot;
- lrp->l_rq = RD(linkp->l_qbot);
-
- man_linkrec_insert(lrp);
-
-exit:
- if (status)
- miocnak(wq, mp, 0, status);
- else
- miocack(wq, mp, 0, 0);
-
-}
-
-/*
- * man_unplink - handle I_PUNLINK requests on the control stream
- */
-void
-man_unplink(queue_t *wq, mblk_t *mp)
-{
- struct linkblk *linkp;
-
- linkp = (struct linkblk *)mp->b_cont->b_rptr;
- RD(linkp->l_qbot)->q_ptr = NULL;
- WR(linkp->l_qbot)->q_ptr = NULL;
- miocack(wq, mp, 0, 0);
-}
-
-void
-man_linkrec_insert(man_linkrec_t *lrp)
-{
- mutex_enter(&man_lock);
-
- lrp->l_next = man_linkrec_head;
- man_linkrec_head = lrp;
-
- mutex_exit(&man_lock);
-
-}
-
-static queue_t *
-man_linkrec_find(int muxid)
-{
- man_linkrec_t *lpp;
- man_linkrec_t *lp;
- queue_t *wq = NULL;
-
- mutex_enter(&man_lock);
-
- if (man_linkrec_head == NULL)
- goto exit;
-
- lp = lpp = man_linkrec_head;
- if (lpp->l_muxid == muxid) {
- man_linkrec_head = lpp->l_next;
- } else {
- for (lp = lpp->l_next; lp; lp = lp->l_next) {
- if (lp->l_muxid == muxid)
- break;
- lpp = lp;
- }
- }
-
- if (lp == NULL)
- goto exit;
-
- wq = lp->l_wq;
- ASSERT(wq != NULL);
-
- lpp->l_next = lp->l_next;
- man_kfree(lp, sizeof (man_linkrec_t));
-
-exit:
- mutex_exit(&man_lock);
-
- return (wq);
-}
-
-/*
- * Set instance linkcheck timer value.
- */
-static void
-man_set_linkcheck_time(queue_t *wq, mblk_t *mp)
-{
- mi_time_t *mtp;
- int error;
- man_t *manp;
-
- MAN_DBG(MAN_LINK, ("man_set_linkcheck_time: enter"));
-
- error = miocpullup(mp, sizeof (mi_time_t));
- if (error != 0)
- goto exit;
-
- mtp = (mi_time_t *)mp->b_cont->b_rptr;
-
- MAN_DBG(MAN_LINK, ("man_set_linkcheck_time: mtp"));
- MAN_DBGCALL(MAN_LINK, man_print_mtp(mtp));
-
- manp = ddi_get_soft_state(man_softstate, mtp->mtp_man_ppa);
- if (manp == NULL) {
- error = ENODEV;
- goto exit;
- }
-
- manp->man_linkcheck_time = mtp->mtp_time;
-exit:
- if (error)
- miocnak(wq, mp, 0, error);
- else
- miocack(wq, mp, sizeof (mi_time_t), 0);
-}
-
-/*
- * Man path ioctl processing. Should only happen on the SSC. Called
- * with exclusive inner perimeter.
- */
-static void
-man_setpath(queue_t *wq, mblk_t *mp)
-{
- mi_path_t *mip;
- int error;
-
- error = miocpullup(mp, sizeof (mi_path_t));
- if (error != 0)
- goto exit;
-
- mip = (mi_path_t *)mp->b_cont->b_rptr;
- mutex_enter(&man_lock);
- error = man_pg_cmd(mip, NULL);
- mutex_exit(&man_lock);
-
-exit:
- if (error)
- miocnak(wq, mp, 0, error);
- else
- miocack(wq, mp, sizeof (mi_path_t), 0);
-}
-
-/*
- * Get the local ethernet address of this machine.
- */
-static void
-man_geteaddr(queue_t *wq, mblk_t *mp)
-{
- eaddr_t *eap;
- int error;
-
- error = miocpullup(mp, sizeof (eaddr_t));
- if (error != 0) {
- miocnak(wq, mp, 0, error);
- return;
- }
-
- eap = (eaddr_t *)mp->b_cont->b_rptr;
- (void) localetheraddr(NULL, eap);
- miocack(wq, mp, sizeof (eaddr_t), 0);
-}
-
-/*
- * Set my SC and other SC IPv4 addresses for use in man_pinger routine.
- */
-static void
-man_set_sc_ipaddrs(queue_t *wq, mblk_t *mp)
-{
- int error;
-
- error = miocpullup(mp, sizeof (man_sc_ipaddrs_t));
- if (error != 0)
- goto exit;
-
- man_sc_ipaddrs = *(man_sc_ipaddrs_t *)mp->b_cont->b_rptr;
-
-#ifdef DEBUG
- {
- char buf[INET_ADDRSTRLEN];
-
- (void) inet_ntop(AF_INET,
- (void *) &man_sc_ipaddrs.ip_other_sc_ipaddr,
- buf, INET_ADDRSTRLEN);
- MAN_DBG(MAN_CONFIG, ("ip_other_sc_ipaddr = %s", buf));
- (void) inet_ntop(AF_INET,
- (void *) &man_sc_ipaddrs.ip_my_sc_ipaddr,
- buf, INET_ADDRSTRLEN);
- MAN_DBG(MAN_CONFIG, ("ip_my_sc_ipaddr = %s", buf));
- }
-#endif /* DEBUG */
-exit:
- if (error)
- miocnak(wq, mp, 0, error);
- else
- miocack(wq, mp, sizeof (man_sc_ipaddrs_t), 0);
-}
-
-/*
- * Set my SC and other SC IPv6 addresses for use in man_pinger routine.
- */
-static void
-man_set_sc_ip6addrs(queue_t *wq, mblk_t *mp)
-{
- int error;
-
- error = miocpullup(mp, sizeof (man_sc_ip6addrs_t));
- if (error != 0)
- goto exit;
-
- man_sc_ip6addrs = *(man_sc_ip6addrs_t *)mp->b_cont->b_rptr;
-
-#ifdef DEBUG
- {
- char buf[INET6_ADDRSTRLEN];
-
- (void) inet_ntop(AF_INET6,
- (void *) &man_sc_ip6addrs.ip6_other_sc_ipaddr,
- buf, INET6_ADDRSTRLEN);
- MAN_DBG(MAN_CONFIG, ("ip6_other_sc_ipaddr = %s", buf));
- (void) inet_ntop(AF_INET6,
- (void *) &man_sc_ip6addrs.ip6_my_sc_ipaddr,
- buf, INET6_ADDRSTRLEN);
- MAN_DBG(MAN_CONFIG, ("ip6_my_sc_ipaddr = %s", buf));
- }
-#endif /* DEBUG */
-exit:
- if (error)
- miocnak(wq, mp, 0, error);
- else
- miocack(wq, mp, sizeof (man_sc_ip6addrs_t), 0);
-}
-
-/*
- * M_DATA fastpath info request.
- */
-static void
-man_dl_ioc_hdr_info(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp;
- man_t *manp;
- mblk_t *nmp;
- man_dladdr_t *dlap;
- dl_unitdata_req_t *dludp;
- struct ether_header *headerp;
- t_uscalar_t off, len;
- int status = 0;
-
- MAN_DBG(MAN_DLPI, ("man_dl_ioc_hdr_info: enter"));
-
- msp = (manstr_t *)wq->q_ptr;
- manp = msp->ms_manp;
- if (manp == NULL) {
- status = EINVAL;
- goto exit;
- }
-
- status = miocpullup(mp, sizeof (dl_unitdata_req_t) + MAN_ADDRL);
- if (status != 0)
- goto exit;
-
- /*
- * Sanity check the DL_UNITDATA_REQ destination address
- * offset and length values.
- */
- dludp = (dl_unitdata_req_t *)mp->b_cont->b_rptr;
- off = dludp->dl_dest_addr_offset;
- len = dludp->dl_dest_addr_length;
- if (dludp->dl_primitive != DL_UNITDATA_REQ ||
- !MBLKIN(mp->b_cont, off, len) || len != MAN_ADDRL) {
- status = EINVAL;
- goto exit;
- }
-
- dlap = (man_dladdr_t *)(mp->b_cont->b_rptr + off);
-
- /*
- * Allocate a new mblk to hold the ether header.
- */
- if ((nmp = allocb(ETHERHEADER_SIZE, BPRI_MED)) == NULL) {
- status = ENOMEM;
- goto exit;
- }
-
- /* We only need one dl_ioc_hdr mblk for replay */
- if (!(msp->ms_flags & MAN_SFLAG_FAST))
- status = man_dl_catch(&msp->ms_dlioc_mp, mp);
-
- /* Forward the packet to all lower destinations. */
- if ((status != 0) || ((status = man_dlpi_senddown(msp, mp)) != 0)) {
- freemsg(nmp);
- goto exit;
- }
-
- nmp->b_wptr += ETHERHEADER_SIZE;
-
- /*
- * Fill in the ether header.
- */
- headerp = (struct ether_header *)nmp->b_rptr;
- ether_copy(&dlap->dl_phys, &headerp->ether_dhost);
- ether_copy(&manp->man_eaddr, &headerp->ether_shost);
- put_ether_type(headerp, dlap->dl_sap);
-
- /*
- * Link new mblk in after the "request" mblks.
- */
- linkb(mp, nmp);
-
-exit:
- MAN_DBG(MAN_DLPI, ("man_dl_ioc_hdr_info: returns, status = %d",
- status));
-
- if (status) {
- miocnak(wq, mp, 0, status);
- } else {
- msp = (manstr_t *)wq->q_ptr;
- msp->ms_flags |= MAN_SFLAG_FAST;
- miocack(wq, mp, msgsize(mp->b_cont), 0);
- }
-
-}
-
-/*
- * man_uwsrv - Upper write queue service routine to handle deferred
- * DLPI messages issued from upstream, the write side of the upper half
- * of multiplexor. It is also used by man_bwork to switch the lower
- * multiplexor.
- *
- * wq - upper write queue of mxx
- */
-static int
-man_uwsrv(queue_t *wq)
-{
- register mblk_t *mp;
- manstr_t *msp; /* per stream data */
- man_t *manp; /* per instance data */
- ehdr_t *ep;
- int status;
-
- msp = (manstr_t *)wq->q_ptr;
-
- MAN_DBG(MAN_UWSRV, ("man_uwsrv: wq(0x%p) msp", (void *)wq));
- MAN_DBGCALL(MAN_UWSRV, man_print_msp(msp));
-
- if (msp == NULL)
- goto done;
-
- manp = msp->ms_manp;
-
- while (mp = getq(wq)) {
-
- switch (DB_TYPE(mp)) {
- /*
- * Can probably remove this as I never put data messages
- * here.
- */
- case M_DATA:
- if (manp) {
- ep = (ehdr_t *)mp->b_rptr;
- status = man_start(wq, mp, &ep->ether_dhost);
- if (status) {
- /*
- * man_start() indicated flow control
- * situation, stop processing now.
- */
- goto break_loop;
- }
- } else
- freemsg(mp);
- break;
-
- case M_PROTO:
- case M_PCPROTO:
- status = man_proto(wq, mp);
- if (status) {
- /*
- * man_proto() indicated flow control
- * situation detected by man_start(),
- * stop processing now.
- */
- goto break_loop;
- }
- break;
-
- default:
- MAN_DBG(MAN_UWSRV, ("man_uwsrv: discarding mp(0x%p)",
- (void *)mp));
- freemsg(mp);
- break;
- }
- }
-
-break_loop:
- /*
- * Check to see if bgthread wants us to do something inside the
- * perimeter.
- */
- if ((msp->ms_flags & MAN_SFLAG_CONTROL) &&
- man_iwork_q->q_work != NULL) {
-
- man_iwork();
- }
-
-done:
-
- MAN_DBG(MAN_UWSRV, ("man_uwsrv: returns"));
-
- return (0);
-}
-
-
-/*
- * man_proto - handle DLPI protocol requests issued from upstream.
- * Called by man_uwsrv(). We disassociate upper and lower multiplexor
- * DLPI state transitions. The upper stream here (manstr_t) transitions
- * appropriately, saves the DLPI requests via man_dlpi(), and then
- * arranges for the DLPI request to be sent down via man_dlpi_senddown() if
- * appropriate.
- *
- * wq - upper write queue of mxx
- * mp - mbl ptr to protocol request
- */
-static int
-man_proto(queue_t *wq, mblk_t *mp)
-{
- union DL_primitives *dlp;
- int flow_status = 0;
-
- dlp = (union DL_primitives *)mp->b_rptr;
-
- MAN_DBG((MAN_UWSRV | MAN_DLPI),
- ("man_proto: mp(0x%p) prim(%s)\n", (void *)mp,
- dps[dlp->dl_primitive]));
-
- switch (dlp->dl_primitive) {
- case DL_UNITDATA_REQ:
- flow_status = man_udreq(wq, mp);
- break;
-
- case DL_ATTACH_REQ:
- man_areq(wq, mp);
- break;
-
- case DL_DETACH_REQ:
- man_dreq(wq, mp);
- break;
-
- case DL_BIND_REQ:
- man_breq(wq, mp);
- break;
-
- case DL_UNBIND_REQ:
- man_ubreq(wq, mp);
- break;
-
- case DL_INFO_REQ:
- man_ireq(wq, mp);
- break;
-
- case DL_PROMISCON_REQ:
- man_ponreq(wq, mp);
- break;
-
- case DL_PROMISCOFF_REQ:
- man_poffreq(wq, mp);
- break;
-
- case DL_ENABMULTI_REQ:
- man_emreq(wq, mp);
- break;
-
- case DL_DISABMULTI_REQ:
- man_dmreq(wq, mp);
- break;
-
- case DL_PHYS_ADDR_REQ:
- man_pareq(wq, mp);
- break;
-
- case DL_SET_PHYS_ADDR_REQ:
- man_spareq(wq, mp);
- break;
-
- default:
- MAN_DBG((MAN_UWSRV | MAN_DLPI), ("man_proto: prim(%d)\n",
- dlp->dl_primitive));
- dlerrorack(wq, mp, dlp->dl_primitive, DL_UNSUPPORTED, 0);
- break;
-
- } /* End switch */
-
- MAN_DBG((MAN_UWSRV | MAN_DLPI), ("man_proto: exit\n"));
- return (flow_status);
-
-}
-
-static int
-man_udreq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp;
- dl_unitdata_req_t *dludp;
- mblk_t *nmp;
- man_dladdr_t *dlap;
- t_uscalar_t off, len;
- int flow_status = 0;
-
- msp = (manstr_t *)wq->q_ptr;
-
-
- if (msp->ms_dlpistate != DL_IDLE) {
- dlerrorack(wq, mp, DL_UNITDATA_REQ, DL_OUTSTATE, 0);
- return (flow_status);
- }
- dludp = (dl_unitdata_req_t *)mp->b_rptr;
- off = dludp->dl_dest_addr_offset;
- len = dludp->dl_dest_addr_length;
-
- /*
- * Validate destination address format.
- */
- if (!MBLKIN(mp, off, len) || (len != MAN_ADDRL)) {
- dluderrorind(wq, mp, mp->b_rptr + off, len, DL_BADADDR, 0);
- return (flow_status);
- }
-
- /*
- * Error if no M_DATA follows.
- */
- nmp = mp->b_cont;
- if (nmp == NULL) {
- dluderrorind(wq, mp, mp->b_rptr + off, len, DL_BADDATA, 0);
- return (flow_status);
- }
-
- dlap = (man_dladdr_t *)(mp->b_rptr + off);
-
- flow_status = man_start(wq, mp, &dlap->dl_phys);
- return (flow_status);
-}
-
-/*
- * Handle DL_ATTACH_REQ.
- */
-static void
-man_areq(queue_t *wq, mblk_t *mp)
-{
- man_t *manp; /* per instance data */
- manstr_t *msp; /* per stream data */
- short ppa;
- union DL_primitives *dlp;
- mblk_t *preq = NULL;
- int did_refcnt = FALSE;
- int dlerror = 0;
- int status = 0;
-
- msp = (manstr_t *)wq->q_ptr;
- dlp = (union DL_primitives *)mp->b_rptr;
-
- /*
- * Attach us to MAN PPA (device instance).
- */
- if (MBLKL(mp) < DL_ATTACH_REQ_SIZE) {
- dlerror = DL_BADPRIM;
- goto exit;
- }
-
- if (msp->ms_dlpistate != DL_UNATTACHED) {
- dlerror = DL_OUTSTATE;
- goto exit;
- }
-
- ppa = dlp->attach_req.dl_ppa;
- if (ppa == -1 || qassociate(wq, ppa) != 0) {
- dlerror = DL_BADPPA;
- MAN_DBG(MAN_WARN, ("man_areq: bad PPA %d", ppa));
- goto exit;
- }
-
- mutex_enter(&man_lock);
- manp = ddi_get_soft_state(man_softstate, ppa);
- ASSERT(manp != NULL); /* qassociate() succeeded */
-
- manp->man_refcnt++;
- did_refcnt = TRUE;
- mutex_exit(&man_lock);
-
- /*
- * Create a DL replay list for the lower stream. These wont
- * actually be sent down until the lower streams are made active
- * (sometime after the call to man_init_dests below).
- */
- preq = man_alloc_physreq_mp(&manp->man_eaddr);
- if (preq == NULL) {
- dlerror = DL_SYSERR;
- status = ENOMEM;
- goto exit;
- }
-
- /*
- * Make copy for dlpi resync of upper and lower streams.
- */
- if (man_dlpi(msp, mp)) {
- dlerror = DL_SYSERR;
- status = ENOMEM;
- goto exit;
- }
-
- /* TBD - need to clean off ATTACH req on failure here. */
- if (man_dlpi(msp, preq)) {
- dlerror = DL_SYSERR;
- status = ENOMEM;
- goto exit;
- }
-
- /*
- * man_init_dests/man_start_dest needs these set before call.
- */
- msp->ms_manp = manp;
- msp->ms_meta_ppa = ppa;
-
- /*
- * Allocate and init lower destination structures.
- */
- ASSERT(msp->ms_dests == NULL);
- if (man_init_dests(manp, msp)) {
- mblk_t *tmp;
-
- /*
- * If we cant get the lower streams ready, then
- * remove the messages from the DL replay list and
- * fail attach.
- */
- while ((tmp = msp->ms_dl_mp) != NULL) {
- msp->ms_dl_mp = msp->ms_dl_mp->b_next;
- tmp->b_next = tmp->b_prev = NULL;
- freemsg(tmp);
- }
-
- msp->ms_manp = NULL;
- msp->ms_meta_ppa = -1;
-
- dlerror = DL_SYSERR;
- status = ENOMEM;
- goto exit;
- }
-
- MAN_DBG(MAN_DLPI, ("man_areq: ppa 0x%x man_refcnt: %d\n",
- ppa, manp->man_refcnt));
-
- SETSTATE(msp, DL_UNBOUND);
-
-exit:
- if (dlerror == 0) {
- dlokack(wq, mp, DL_ATTACH_REQ);
- } else {
- if (did_refcnt) {
- mutex_enter(&man_lock);
- manp->man_refcnt--;
- mutex_exit(&man_lock);
- }
- dlerrorack(wq, mp, DL_ATTACH_REQ, dlerror, status);
- (void) qassociate(wq, -1);
- }
- if (preq != NULL)
- freemsg(preq);
-
-}
-
-/*
- * Called at DL_ATTACH time.
- * Man_lock is held to protect pathgroup list(man_pg).
- */
-static int
-man_init_dests(man_t *manp, manstr_t *msp)
-{
- man_dest_t *mdp;
- man_pg_t *mpg;
- int i;
-
- mdp = man_kzalloc(MAN_DEST_ARRAY_SIZE, KM_NOSLEEP);
- if (mdp == NULL)
- return (ENOMEM);
-
- msp->ms_dests = mdp;
-
- mutex_enter(&man_lock);
- for (i = 0; i < MAN_MAX_DESTS; i++) {
-
- mdp[i].md_muxid = -1; /* muxid 0 is valid */
- mutex_init(&mdp->md_lock, NULL, MUTEX_DRIVER, NULL);
-
- mpg = man_find_pg_by_id(manp->man_pg, i);
-
- if (mpg && man_find_active_path(mpg->mpg_pathp))
- man_start_dest(&mdp[i], msp, mpg);
- }
- mutex_exit(&man_lock);
-
- return (0);
-}
-
-/*
- * Get a destination ready for use.
- */
-static void
-man_start_dest(man_dest_t *mdp, manstr_t *msp, man_pg_t *mpg)
-{
- man_path_t *ap;
-
- mdp->md_muxid = -1;
- mdp->md_dlpistate = DL_UNATTACHED;
- mdp->md_msp = msp;
- mdp->md_rq = msp->ms_rq;
- mdp->md_pg_id = mpg->mpg_pg_id;
-
- ASSERT(msp->ms_manp);
-
- ether_copy(&msp->ms_manp->man_eaddr, &mdp->md_src_eaddr);
- ether_copy(&mpg->mpg_dst_eaddr, &mdp->md_dst_eaddr);
-
- ap = man_find_active_path(mpg->mpg_pathp);
- ASSERT(ap);
- mdp->md_device = ap->mp_device;
-
- /*
- * Set up linktimers so that first time through, we will do
- * a failover.
- */
- mdp->md_linkstate = MAN_LINKFAIL;
- mdp->md_state = MAN_DSTATE_INITIALIZING;
- mdp->md_lc_timer_id = qtimeout(man_ctl_wq, man_linkcheck_timer,
- (void *)mdp, man_gettimer(MAN_TIMER_INIT, mdp));
-
- /*
- * As an optimization, if there is only one destination,
- * remember the destination pointer. Used by man_start().
- */
- man_set_optimized_dest(msp);
-
- MAN_DBG(MAN_DEST, ("man_start_dest: mdp"));
- MAN_DBGCALL(MAN_DEST, man_print_mdp(mdp));
-}
-
-static void
-man_set_optimized_dest(manstr_t *msp)
-{
- int count = 0;
- int i;
- man_dest_t *mdp = NULL;
-
- for (i = 0; i < MAN_MAX_DESTS; i++) {
- if (msp->ms_dests[i].md_msp != NULL) {
- count++;
- mdp = &msp->ms_dests[i];
- }
- }
-
- if (count == 1)
- msp->ms_destp = mdp;
- else
- msp->ms_destp = NULL;
-
-}
-
-/*
- * Catch dlpi message for replaying, and arrange to send it down
- * to any destinations not PLUMBING. See man_dlpi_replay().
- */
-static int
-man_dlpi(manstr_t *msp, mblk_t *mp)
-{
- int status;
-
- status = man_dl_catch(&msp->ms_dl_mp, mp);
- if (status == 0)
- status = man_dlpi_senddown(msp, mp);
-
- return (status);
-}
-
-/*
- * Catch IOCTL type DL_ messages.
- */
-static int
-man_dlioc(manstr_t *msp, mblk_t *mp)
-{
- int status;
-
- status = man_dl_catch(&msp->ms_dlioc_mp, mp);
- if (status == 0)
- status = man_dlpi_senddown(msp, mp);
-
- return (status);
-}
-
-/*
- * We catch all DLPI messages that we have to resend to a new AP'ed
- * device to put it in the right state. We link these messages together
- * w/ their b_next fields and hang it off of msp->ms_dl_mp. We
- * must be careful to restore b_next fields before doing dupmsg/freemsg!
- *
- * msp - pointer of stream struct to process
- * mblk - pointer to DLPI request to catch
- */
-static int
-man_dl_catch(mblk_t **mplist, mblk_t *mp)
-{
- mblk_t *dupmp;
- mblk_t *tmp;
- unsigned prim;
- int status = 0;
-
- dupmp = copymsg(mp);
- if (dupmp == NULL) {
- status = ENOMEM;
- goto exit;
- }
-
-
- if (*mplist == NULL)
- *mplist = dupmp;
- else {
- for (tmp = *mplist; tmp->b_next; )
- tmp = tmp->b_next;
-
- tmp->b_next = dupmp;
- }
-
- prim = DL_PRIM(mp);
- MAN_DBG(MAN_DLPI,
- ("man_dl_catch: adding %s\n",
- (prim == DL_IOC_HDR_INFO) ? "DL_IOC_HDR_INFO" :
- (prim == DLIOCRAW) ? "DLIOCRAW" :
- (prim == DL_PROMISCON_REQ) ? promisc[DL_PROMISCON_TYPE(mp)] :
- dps[prim]));
-
-exit:
-
- return (status);
-}
-
-/*
- * Send down a single DLPI M_[PC]PROTO to all currently valid dests.
- *
- * msp - ptr to NDM stream structure DL_ messages was received on.
- * mp - ptr to mblk containing DL_ request.
- */
-static int
-man_dlpi_senddown(manstr_t *msp, mblk_t *mp)
-{
- man_dest_t *mdp;
- int i;
- mblk_t *rmp[MAN_MAX_DESTS]; /* Copy to replay */
- int dstate[MAN_MAX_DESTS];
- int no_dests = TRUE;
- int status = 0;
-
- if (msp->ms_dests == NULL)
- goto exit;
-
- for (i = 0; i < MAN_MAX_DESTS; i++) {
- mdp = &msp->ms_dests[i];
- if (mdp->md_state == MAN_DSTATE_READY) {
- dstate[i] = TRUE;
- no_dests = FALSE;
- } else {
- dstate[i] = FALSE;
- }
- rmp[i] = NULL;
- }
-
- if (no_dests)
- goto exit;
-
- /*
- * Build replay and duplicate list for all possible destinations.
- */
- for (i = 0; i < MAN_MAX_DESTS; i++) {
- if (dstate[i]) {
- rmp[i] = copymsg(mp);
- if (rmp[i] == NULL) {
- status = ENOMEM;
- break;
- }
- }
- }
-
- if (status == 0) {
- for (i = 0; i < MAN_MAX_DESTS; i++)
- if (dstate[i]) {
- mdp = &msp->ms_dests[i];
-
- ASSERT(mdp->md_wq != NULL);
- ASSERT(mp->b_next == NULL);
- ASSERT(mp->b_prev == NULL);
-
- man_dlpi_replay(mdp, rmp[i]);
- }
- } else {
- for (; i >= 0; i--)
- if (dstate[i] && rmp[i])
- freemsg(rmp[i]);
- }
-
-exit:
- return (status);
-}
-
-/*
- * man_dlpi_replay - traverse the list of DLPI requests and reapply them to
- * get the upper and lower streams into the same state. Called holding inner
- * perimeter lock exclusive. Note thet we defer M_IOCTL type dlpi messages
- * until we get an OK_ACK to our ATTACH (see man_lrsrv and
- * man_dlioc_replay).
- *
- * mdp - pointer to lower queue (destination)
- * rmp - list of mblks to send down stream.
- */
-static void
-man_dlpi_replay(man_dest_t *mdp, mblk_t *rmp)
-{
- mblk_t *mp;
- union DL_primitives *dlp = NULL;
-
- MAN_DBG(MAN_DLPI, ("man_dlpi_replay: mdp(0x%p)", (void *)mdp));
-
- while (rmp) {
- mp = rmp;
- rmp = rmp->b_next;
- mp->b_prev = mp->b_next = NULL;
-
- dlp = (union DL_primitives *)mp->b_rptr;
- MAN_DBG(MAN_DLPI,
- ("man_dlpi_replay: mdp(0x%p) sending %s\n",
- (void *)mdp,
- (dlp->dl_primitive == DL_IOC_HDR_INFO) ?
- "DL_IOC_HDR_INFO" : (dlp->dl_primitive == DLIOCRAW) ?
- "DLIOCRAW" : dps[(unsigned)(dlp->dl_primitive)]));
-
- if (dlp->dl_primitive == DL_ATTACH_REQ) {
- /*
- * insert the lower devices ppa.
- */
- dlp->attach_req.dl_ppa = mdp->md_device.mdev_ppa;
- }
-
- (void) putnext(mdp->md_wq, mp);
- }
-
-}
-
-static void
-man_dreq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp; /* per stream data */
- man_work_t *wp;
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_DETACH_REQ_SIZE) {
- dlerrorack(wq, mp, DL_DETACH_REQ, DL_BADPRIM, 0);
- return;
- }
-
- if (msp->ms_dlpistate != DL_UNBOUND) {
- dlerrorack(wq, mp, DL_DETACH_REQ, DL_OUTSTATE, 0);
- return;
- }
-
- ASSERT(msp->ms_dests != NULL);
-
- wp = man_work_alloc(MAN_WORK_CLOSE_STREAM, KM_NOSLEEP);
- if (wp == NULL) {
- dlerrorack(wq, mp, DL_DETACH_REQ, DL_SYSERR, ENOMEM);
- return;
- }
- man_dodetach(msp, wp);
- (void) qassociate(wq, -1);
-
- SETSTATE(msp, DL_UNATTACHED);
-
- dlokack(wq, mp, DL_DETACH_REQ);
-}
-
-static void
-man_dl_clean(mblk_t **mplist)
-{
- mblk_t *tmp;
-
- /*
- * Toss everything.
- */
- while ((tmp = *mplist) != NULL) {
- *mplist = (*mplist)->b_next;
- tmp->b_next = tmp->b_prev = NULL;
- freemsg(tmp);
- }
-
-}
-
-/*
- * man_dl_release - Remove the corresponding DLPI request from the
- * catch list. Walk thru the catch list looking for the other half of
- * the pair and delete it. If we are detaching, delete the entire list.
- *
- * msp - pointer of stream struct to process
- * mp - pointer to mblk to first half of pair. We will delete other
- * half of pair based on this.
- */
-static void
-man_dl_release(mblk_t **mplist, mblk_t *mp)
-{
- uchar_t match_dbtype;
- mblk_t *tmp;
- mblk_t *tmpp;
- int matched = FALSE;
-
- if (*mplist == NULL)
- goto exit;
-
- match_dbtype = DB_TYPE(mp);
-
- /*
- * Currently we only clean DL_ PROTO type messages. There is
- * no way to turn off M_CTL or DL_IOC stuff other than sending
- * down a DL_DETACH, which resets everything.
- */
- if (match_dbtype != M_PROTO && match_dbtype != M_PCPROTO) {
- goto exit;
- }
-
- /*
- * Selectively find a caught mblk that matches this one and
- * remove it from the list
- */
- tmp = tmpp = *mplist;
- matched = man_match_proto(mp, tmp);
- if (matched) {
- *mplist = tmp->b_next;
- tmp->b_next = tmp->b_prev = NULL;
- } else {
- for (tmp = tmp->b_next; tmp != NULL; tmp = tmp->b_next) {
- if (matched = man_match_proto(mp, tmp))
- break;
- tmpp = tmp;
- }
-
- if (matched) {
- tmpp->b_next = tmp->b_next;
- tmp->b_next = tmp->b_prev = NULL;
- }
- }
-
-exit:
- if (matched) {
-
- MAN_DBG(MAN_DLPI, ("man_dl_release: release %s",
- (DL_PRIM(mp) == DL_IOC_HDR_INFO) ? "DL_IOC_HDR_INFO" :
- (DL_PRIM(mp) == DLIOCRAW) ? "DLIOCRAW" :
- dps[(int)DL_PRIM(mp)]));
-
- freemsg(tmp);
- }
- MAN_DBG(MAN_DLPI, ("man_dl_release: returns"));
-
-}
-
-/*
- * Compare two DL_ messages. If they are complimentary (e.g. DL_UNBIND
- * compliments DL_BIND), return true.
- */
-static int
-man_match_proto(mblk_t *mp1, mblk_t *mp2)
-{
- t_uscalar_t prim1;
- t_uscalar_t prim2;
- int matched = FALSE;
-
- /*
- * Primitive to clean off list.
- */
- prim1 = DL_PRIM(mp1);
- prim2 = DL_PRIM(mp2);
-
- switch (prim1) {
- case DL_UNBIND_REQ:
- if (prim2 == DL_BIND_REQ)
- matched = TRUE;
- break;
-
- case DL_PROMISCOFF_REQ:
- if (prim2 == DL_PROMISCON_REQ) {
- dl_promiscoff_req_t *poff1;
- dl_promiscoff_req_t *poff2;
-
- poff1 = (dl_promiscoff_req_t *)mp1->b_rptr;
- poff2 = (dl_promiscoff_req_t *)mp2->b_rptr;
-
- if (poff1->dl_level == poff2->dl_level)
- matched = TRUE;
- }
- break;
-
- case DL_DISABMULTI_REQ:
- if (prim2 == DL_ENABMULTI_REQ) {
- union DL_primitives *dlp;
- t_uscalar_t off;
- eaddr_t *addrp1;
- eaddr_t *addrp2;
-
- dlp = (union DL_primitives *)mp1->b_rptr;
- off = dlp->disabmulti_req.dl_addr_offset;
- addrp1 = (eaddr_t *)(mp1->b_rptr + off);
-
- dlp = (union DL_primitives *)mp2->b_rptr;
- off = dlp->disabmulti_req.dl_addr_offset;
- addrp2 = (eaddr_t *)(mp2->b_rptr + off);
-
- if (ether_cmp(addrp1, addrp2) == 0)
- matched = 1;
- }
- break;
-
- default:
- break;
- }
-
- MAN_DBG(MAN_DLPI, ("man_match_proto returns %d", matched));
-
- return (matched);
-}
-
-/*
- * Bind upper stream to a particular SAP. Called with exclusive innerperim
- * QPAIR, shared outerperim.
- */
-static void
-man_breq(queue_t *wq, mblk_t *mp)
-{
- man_t *manp; /* per instance data */
- manstr_t *msp; /* per stream data */
- union DL_primitives *dlp;
- man_dladdr_t man_addr;
- t_uscalar_t sap;
- t_uscalar_t xidtest;
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_BIND_REQ_SIZE) {
- dlerrorack(wq, mp, DL_BIND_REQ, DL_BADPRIM, 0);
- return;
- }
-
- if (msp->ms_dlpistate != DL_UNBOUND) {
- dlerrorack(wq, mp, DL_BIND_REQ, DL_OUTSTATE, 0);
- return;
- }
-
- dlp = (union DL_primitives *)mp->b_rptr;
- manp = msp->ms_manp; /* valid after attach */
- sap = dlp->bind_req.dl_sap;
- xidtest = dlp->bind_req.dl_xidtest_flg;
-
- ASSERT(manp);
-
- if (xidtest) {
- dlerrorack(wq, mp, DL_BIND_REQ, DL_NOAUTO, 0);
- return;
- }
-
- if (sap > ETHERTYPE_MAX) {
- dlerrorack(wq, mp, DL_BIND_REQ, DL_BADSAP, 0);
- return;
- }
-
- if (man_dlpi(msp, mp)) {
- dlerrorack(wq, mp, DL_BIND_REQ, DL_SYSERR, ENOMEM);
- return;
- }
-
- msp->ms_sap = sap;
-
- SETSTATE(msp, DL_IDLE);
-
- man_addr.dl_sap = msp->ms_sap;
- ether_copy(&msp->ms_manp->man_eaddr, &man_addr.dl_phys);
-
- dlbindack(wq, mp, msp->ms_sap, &man_addr, MAN_ADDRL, 0, 0);
-
-}
-
-static void
-man_ubreq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp; /* per stream data */
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_UNBIND_REQ_SIZE) {
- dlerrorack(wq, mp, DL_UNBIND_REQ, DL_BADPRIM, 0);
- return;
- }
-
- if (msp->ms_dlpistate != DL_IDLE) {
- dlerrorack(wq, mp, DL_UNBIND_REQ, DL_OUTSTATE, 0);
- return;
- }
-
- if (man_dlpi_senddown(msp, mp)) {
- dlerrorack(wq, mp, DL_UNBIND_REQ, DL_SYSERR, ENOMEM);
- return;
- }
-
- man_dl_release(&msp->ms_dl_mp, mp);
-
- SETSTATE(msp, DL_UNBOUND);
-
- dlokack(wq, mp, DL_UNBIND_REQ);
-
-}
-
-static void
-man_ireq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp;
- dl_info_ack_t *dlip;
- man_dladdr_t *dlap;
- eaddr_t *ep;
- size_t size;
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_INFO_REQ_SIZE) {
- dlerrorack(wq, mp, DL_INFO_REQ, DL_BADPRIM, 0);
- return;
- }
-
- /* Exchange current msg for a DL_INFO_ACK. */
- size = sizeof (dl_info_ack_t) + MAN_ADDRL + ETHERADDRL;
- mp = mexchange(wq, mp, size, M_PCPROTO, DL_INFO_ACK);
- if (mp == NULL) {
- MAN_DBG(MAN_DLPI, ("man_ireq: man_ireq: mp == NULL."));
- return;
- }
-
- /* Fill in the DL_INFO_ACK fields and reply. */
- dlip = (dl_info_ack_t *)mp->b_rptr;
- *dlip = man_infoack;
- dlip->dl_current_state = msp->ms_dlpistate;
- dlap = (man_dladdr_t *)(mp->b_rptr + dlip->dl_addr_offset);
- dlap->dl_sap = msp->ms_sap;
-
- /*
- * If attached, return physical address.
- */
- if (msp->ms_manp != NULL) {
- ether_copy(&msp->ms_manp->man_eaddr, &dlap->dl_phys);
- } else {
- bzero((caddr_t)&dlap->dl_phys, ETHERADDRL);
- }
-
- ep = (struct ether_addr *)(mp->b_rptr + dlip->dl_brdcst_addr_offset);
- ether_copy(&etherbroadcast, ep);
-
- qreply(wq, mp);
-
-}
-
-
-static void
-man_ponreq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp;
- int flag;
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_PROMISCON_REQ_SIZE) {
- dlerrorack(wq, mp, DL_PROMISCON_REQ, DL_BADPRIM, 0);
- return;
- }
-
- switch (((dl_promiscon_req_t *)mp->b_rptr)->dl_level) {
- case DL_PROMISC_PHYS:
- flag = MAN_SFLAG_ALLPHYS;
- break;
-
- case DL_PROMISC_SAP:
- flag = MAN_SFLAG_ALLSAP;
- break;
-
- case DL_PROMISC_MULTI:
- flag = MAN_SFLAG_ALLMULTI;
- break;
-
- default:
- dlerrorack(wq, mp, DL_PROMISCON_REQ, DL_NOTSUPPORTED, 0);
- return;
- }
-
- /*
- * Catch request for replay, and forward down to any lower
- * lower stream.
- */
- if (man_dlpi(msp, mp)) {
- dlerrorack(wq, mp, DL_PROMISCON_REQ, DL_SYSERR, ENOMEM);
- return;
- }
-
- msp->ms_flags |= flag;
-
- dlokack(wq, mp, DL_PROMISCON_REQ);
-
-}
-
-static void
-man_poffreq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp;
- int flag;
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_PROMISCOFF_REQ_SIZE) {
- dlerrorack(wq, mp, DL_PROMISCOFF_REQ, DL_BADPRIM, 0);
- return;
- }
-
- switch (((dl_promiscoff_req_t *)mp->b_rptr)->dl_level) {
- case DL_PROMISC_PHYS:
- flag = MAN_SFLAG_ALLPHYS;
- break;
-
- case DL_PROMISC_SAP:
- flag = MAN_SFLAG_ALLSAP;
- break;
-
- case DL_PROMISC_MULTI:
- flag = MAN_SFLAG_ALLMULTI;
- break;
-
- default:
- dlerrorack(wq, mp, DL_PROMISCOFF_REQ, DL_NOTSUPPORTED, 0);
- return;
- }
-
- if ((msp->ms_flags & flag) == 0) {
- dlerrorack(wq, mp, DL_PROMISCOFF_REQ, DL_NOTENAB, 0);
- return;
- }
-
- if (man_dlpi_senddown(msp, mp)) {
- dlerrorack(wq, mp, DL_PROMISCOFF_REQ, DL_SYSERR, ENOMEM);
- return;
- }
-
- man_dl_release(&msp->ms_dl_mp, mp);
-
- msp->ms_flags &= ~flag;
-
- dlokack(wq, mp, DL_PROMISCOFF_REQ);
-
-}
-
-/*
- * Enable multicast requests. We might need to track addresses instead of
- * just passing things through (see eri_dmreq) - TBD.
- */
-static void
-man_emreq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp;
- union DL_primitives *dlp;
- eaddr_t *addrp;
- t_uscalar_t off;
- t_uscalar_t len;
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_ENABMULTI_REQ_SIZE) {
- dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_BADPRIM, 0);
- return;
- }
-
- if (msp->ms_dlpistate == DL_UNATTACHED) {
- dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_OUTSTATE, 0);
- return;
- }
-
- dlp = (union DL_primitives *)mp->b_rptr;
- len = dlp->enabmulti_req.dl_addr_length;
- off = dlp->enabmulti_req.dl_addr_offset;
- addrp = (struct ether_addr *)(mp->b_rptr + off);
-
- if ((len != ETHERADDRL) ||
- !MBLKIN(mp, off, len) ||
- ((addrp->ether_addr_octet[0] & 01) == 0)) {
- dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_BADADDR, 0);
- return;
- }
-
- /*
- * Catch request for replay, and forward down to any lower
- * lower stream.
- */
- if (man_dlpi(msp, mp)) {
- dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_SYSERR, ENOMEM);
- return;
- }
-
- dlokack(wq, mp, DL_ENABMULTI_REQ);
-
-}
-
-static void
-man_dmreq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp;
- union DL_primitives *dlp;
- eaddr_t *addrp;
- t_uscalar_t off;
- t_uscalar_t len;
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_DISABMULTI_REQ_SIZE) {
- dlerrorack(wq, mp, DL_DISABMULTI_REQ, DL_BADPRIM, 0);
- return;
- }
-
- if (msp->ms_dlpistate == DL_UNATTACHED) {
- dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_OUTSTATE, 0);
- return;
- }
-
- dlp = (union DL_primitives *)mp->b_rptr;
- len = dlp->enabmulti_req.dl_addr_length;
- off = dlp->enabmulti_req.dl_addr_offset;
- addrp = (struct ether_addr *)(mp->b_rptr + off);
-
- if ((len != ETHERADDRL) ||
- !MBLKIN(mp, off, len) ||
- ((addrp->ether_addr_octet[0] & 01) == 0)) {
- dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_BADADDR, 0);
- return;
- }
-
- if (man_dlpi_senddown(msp, mp)) {
- dlerrorack(wq, mp, DL_ENABMULTI_REQ, DL_SYSERR, ENOMEM);
- return;
- }
-
- man_dl_release(&msp->ms_dl_mp, mp);
-
- dlokack(wq, mp, DL_DISABMULTI_REQ);
-
-}
-
-static void
-man_pareq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp;
- union DL_primitives *dlp;
- uint32_t type;
- struct ether_addr addr;
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_PHYS_ADDR_REQ_SIZE) {
- dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_BADPRIM, 0);
- return;
- }
-
- dlp = (union DL_primitives *)mp->b_rptr;
- type = dlp->physaddr_req.dl_addr_type;
- if (msp->ms_manp == NULL) {
- dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_OUTSTATE, 0);
- return;
- }
-
- switch (type) {
- case DL_FACT_PHYS_ADDR:
- (void) localetheraddr((struct ether_addr *)NULL, &addr);
- break;
-
- case DL_CURR_PHYS_ADDR:
- ether_bcopy(&msp->ms_manp->man_eaddr, &addr);
- break;
-
- default:
- dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_NOTSUPPORTED, 0);
- return;
- }
-
- dlphysaddrack(wq, mp, &addr, ETHERADDRL);
-}
-
-/*
- * TBD - this routine probably should be protected w/ an ndd
- * tuneable, or a man.conf parameter.
- */
-static void
-man_spareq(queue_t *wq, mblk_t *mp)
-{
- manstr_t *msp;
- union DL_primitives *dlp;
- t_uscalar_t off;
- t_uscalar_t len;
- eaddr_t *addrp;
-
- msp = (manstr_t *)wq->q_ptr;
-
- if (MBLKL(mp) < DL_SET_PHYS_ADDR_REQ_SIZE) {
- dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0);
- return;
- }
-
- dlp = (union DL_primitives *)mp->b_rptr;
- len = dlp->set_physaddr_req.dl_addr_length;
- off = dlp->set_physaddr_req.dl_addr_offset;
-
- if (!MBLKIN(mp, off, len)) {
- dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0);
- return;
- }
-
- addrp = (struct ether_addr *)(mp->b_rptr + off);
-
- /*
- * Error if length of address isn't right or the address
- * specified is a multicast or broadcast address.
- */
- if ((len != ETHERADDRL) ||
- ((addrp->ether_addr_octet[0] & 01) == 1) ||
- (ether_cmp(addrp, &etherbroadcast) == 0)) {
- dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADADDR, 0);
- return;
- }
- /*
- * Error if this stream is not attached to a device.
- */
- if (msp->ms_manp == NULL) {
- dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_OUTSTATE, 0);
- return;
- }
-
- /*
- * We will also resend DL_SET_PHYS_ADDR_REQ for each dest
- * when it is linked under us.
- */
- if (man_dlpi_senddown(msp, mp)) {
- dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_SYSERR, ENOMEM);
- return;
- }
-
- ether_copy(addrp, msp->ms_manp->man_eaddr.ether_addr_octet);
-
- MAN_DBG(MAN_DLPI, ("man_sareq: snagged %s\n",
- ether_sprintf(&msp->ms_manp->man_eaddr)));
-
- dlokack(wq, mp, DL_SET_PHYS_ADDR_REQ);
-
-}
-
-/*
- * These routines make up the lower part of the MAN streams framework.
- */
-
-/*
- * man_lwsrv - Deferred mblks for down stream. We end up here when
- * the destination is not DL_IDLE when traffic comes downstream.
- *
- * wq - lower write queue of mxx
- */
-static int
-man_lwsrv(queue_t *wq)
-{
- mblk_t *mp;
- mblk_t *mlistp;
- man_dest_t *mdp;
- size_t count;
-
- mdp = (man_dest_t *)wq->q_ptr;
-
- MAN_DBG(MAN_LWSRV, ("man_lwsrv: wq(0x%p) mdp(0x%p)"
- " md_rq(0x%p)\n", (void *)wq, (void *)mdp,
- mdp ? (void *)mdp->md_rq : NULL));
-
- if (mdp == NULL)
- goto exit;
-
- if (mdp->md_state & MAN_DSTATE_CLOSING) {
- flushq(wq, FLUSHDATA);
- flushq(RD(wq), FLUSHDATA);
- goto exit;
- }
-
- /*
- * Arrange to send deferred mp's first, then mblks on the
- * service queue. Since we are exclusive in the inner perimeter,
- * we dont have to worry about md_lock, like the put procedures,
- * which are MTPUTSHARED.
- */
- mutex_enter(&mdp->md_lock);
- mlistp = mdp->md_dmp_head;
- mdp->md_dmp_head = NULL;
- count = mdp->md_dmp_count;
- mdp->md_dmp_count = 0;
- mutex_exit(&mdp->md_lock);
-
- while (mlistp != NULL) {
- mp = mlistp;
- mlistp = mp->b_next;
- mp->b_next = NULL;
- count -= msgsize(mp);
- if (man_start_lower(mdp, mp, NULL, MAN_LOWER)) {
-
- mutex_enter(&mdp->md_lock);
- mdp->md_dmp_count += count + msgsize(mp);
- mp->b_next = mlistp;
- mdp->md_dmp_head = mp;
- mutex_exit(&mdp->md_lock);
- goto exit;
- }
- }
- mdp->md_dmp_tail = NULL;
-
- while (mp = getq(wq)) {
- if (man_start_lower(mdp, mp, NULL, MAN_LOWER)) {
- /*
- * Put it back on queue, making sure to avoid
- * infinite loop mentioned in putbq(9F)
- */
- noenable(wq);
- (void) putbq(wq, mp);
- enableok(wq);
-
- break;
- }
- }
-
-exit:
-
- return (0);
-}
-
-/*
- * man_lrput - handle DLPI messages issued from downstream.
- *
- * rq - lower read queue of mxx
- * mp - mblk ptr to DLPI request
- *
- * returns 0
- */
-static int
-man_lrput(queue_t *rq, mblk_t *mp)
-{
- man_dest_t *mdp;
- manstr_t *msp;
-
-#if defined(DEBUG)
- union DL_primitives *dlp;
- t_uscalar_t prim = MAN_DLPI_MAX_PRIM + 1;
- char *prim_str;
-#endif /* DEBUG */
-
- mdp = (man_dest_t *)rq->q_ptr;
-
-#if defined(DEBUG)
- if (DB_TYPE(mp) == M_PROTO) {
- dlp = (union DL_primitives *)mp->b_rptr;
- prim = dlp->dl_primitive;
- }
-
- prim_str = (prim > MAN_DLPI_MAX_PRIM) ? "NON DLPI" :
- (prim == DL_IOC_HDR_INFO) ? "DL_IOC_HDR_INFO" :
- (prim == DLIOCRAW) ? "DLIOCRAW" :
- dps[(unsigned int)prim];
- MAN_DBG(MAN_LRPUT, ("man_lrput: rq(0x%p) mp(0x%p) mdp(0x%p)"
- " db_type(0x%x) dl_prim %s", (void *)rq,
- (void *)mp, (void *)mdp, DB_TYPE(mp), prim_str));
- MAN_DBGCALL(MAN_LRPUT2, man_print_mdp(mdp));
-#endif /* DEBUG */
-
- if (DB_TYPE(mp) == M_FLUSH) {
- /* Turn around */
- if (*mp->b_rptr & FLUSHW) {
- *mp->b_rptr &= ~FLUSHR;
- qreply(rq, mp);
- } else
- freemsg(mp);
- return (0);
- }
-
- if (mdp == NULL || mdp->md_state != MAN_DSTATE_READY) {
-
- MAN_DBG(MAN_LRPUT, ("man_lrput: not ready mdp(0x%p),"
- " state(%d)", (void *)mdp, mdp ? mdp->md_state : -1));
- freemsg(mp);
- return (0);
- }
-
- /*
- * If we have a destination in the right state, forward on datagrams.
- */
- if (MAN_IS_DATA(mp)) {
- if (mdp->md_dlpistate == DL_IDLE && canputnext(mdp->md_rq)) {
-
- msp = mdp->md_msp;
- if (!(msp->ms_flags & MAN_SFLAG_PROMISC))
- mdp->md_rcvcnt++; /* Count for failover */
- /*
- * go put mblk_t directly up to next queue.
- */
- MAN_DBG(MAN_LRPUT, ("man_lrput: putnext to rq(0x%p)",
- (void *)mdp->md_rq));
- (void) putnext(mdp->md_rq, mp);
- } else {
- freemsg(mp);
- }
- } else {
- /*
- * Handle in man_lrsrv with exclusive inner perimeter lock.
- */
- (void) putq(rq, mp);
- }
-
- return (0);
-}
-
-/*
- * Either this is a response from our attempt to sync the upper and lower
- * stream states, or its data. If its not data. Do DL_* response processing
- * and transition md_dlpistate accordingly. If its data, toss it.
- */
-static int
-man_lrsrv(queue_t *rq)
-{
- man_dest_t *mdp;
- mblk_t *mp;
- union DL_primitives *dlp;
- ulong_t prim;
- ulong_t cprim;
- int need_dl_reset = FALSE;
-
-#if defined(DEBUG)
- struct iocblk *iocp;
- char ioc_cmd[256];
-#endif /* DEBUG */
-
- MAN_DBG(MAN_LRSRV, ("man_lrsrv: rq(0x%p)", (void *)rq));
-
- mdp = (man_dest_t *)rq->q_ptr;
-
- if ((mdp == NULL) || (mdp->md_state & MAN_DSTATE_CLOSING)) {
- flushq(rq, FLUSHDATA);
- flushq(WR(rq), FLUSHDATA);
- goto exit;
- }
-
- while (mp = getq(rq)) {
-
-
- /*
- * If we're not connected, or its a datagram, toss it.
- */
- if (MAN_IS_DATA(mp) || mdp->md_state != MAN_DSTATE_READY) {
-
- MAN_DBG(MAN_LRSRV, ("man_lrsrv: dropping mblk mdp(0x%p)"
- " is_data(%d)", (void *)mdp, MAN_IS_DATA(mp)));
- freemsg(mp);
- continue;
- }
-
- /*
- * Should be response to man_dlpi_replay. Discard unless there
- * is a failure we care about.
- */
-
- switch (DB_TYPE(mp)) {
- case M_PROTO:
- case M_PCPROTO:
- /* Do proto processing below. */
- break;
-
- case M_IOCNAK:
- /*
- * DL_IOC* failed for some reason.
- */
- need_dl_reset = TRUE;
-
-#if defined(DEBUG)
- iocp = (struct iocblk *)mp->b_rptr;
-
- (void) sprintf(ioc_cmd, "0x%x", iocp->ioc_cmd);
- MAN_DBG(MAN_LRSRV, ("man_lrsrv: M_IOCNAK err %d for cmd(%s)\n",
- iocp->ioc_error,
- (iocp->ioc_cmd == DL_IOC_HDR_INFO) ? "DL_IOC_HDR_INFO" :
- (iocp->ioc_cmd == DLIOCRAW) ? "DLIOCRAW" : ioc_cmd));
-#endif /* DEBUG */
-
- /* FALLTHRU */
-
- case M_IOCACK:
- case M_CTL:
- /*
- * OK response from DL_IOC*, ignore.
- */
- goto dl_reset;
- }
-
- dlp = (union DL_primitives *)mp->b_rptr;
- prim = dlp->dl_primitive;
-
- MAN_DBG(MAN_LRSRV, ("man_lrsrv: prim %s", dps[(int)prim]));
-
- /*
- * DLPI state processing big theory: We do not rigorously check
- * DLPI states (e.g. PENDING stuff). Simple rules:
- *
- * 1) If we see an OK_ACK to an ATTACH_REQ, dlpistate = DL_UNBOUND.
- * 2) If we see an BIND_ACK to a BIND_REQ, dlpistate = DL_IDLE.
- * 3) If we see a OK_ACK response to an UNBIND_REQ
- * dlpistate = DL_UNBOUND.
- * 4) If we see a OK_ACK response to a DETACH_REQ,
- * dlpistate = DL_UNATTACHED.
- *
- * Everything that isn't handle by 1-4 above is handled by 5)
- *
- * 5) A NAK to any DL_* messages we care about causes
- * dlpistate = DL_UNATTACHED and man_reset_dlpi to run
- *
- * TBD - need a reset counter so we can try a switch if it gets
- * too high.
- */
-
- switch (prim) {
- case DL_OK_ACK:
- cprim = dlp->ok_ack.dl_correct_primitive;
-
- switch (cprim) {
- case DL_ATTACH_REQ:
- if (man_dlioc_replay(mdp)) {
- D_SETSTATE(mdp, DL_UNBOUND);
- } else {
- need_dl_reset = TRUE;
- break;
- }
- break;
-
- case DL_DETACH_REQ:
- D_SETSTATE(mdp, DL_UNATTACHED);
- break;
-
- case DL_UNBIND_REQ:
- /*
- * Cancel timer and set md_dlpistate.
- */
- D_SETSTATE(mdp, DL_UNBOUND);
-
- ASSERT(mdp->md_bc_id == 0);
- if (mdp->md_lc_timer_id != 0) {
- (void) quntimeout(man_ctl_wq,
- mdp->md_lc_timer_id);
- mdp->md_lc_timer_id = 0;
- }
- }
- MAN_DBG(MAN_DLPI,
- (" cprim %s", dps[(int)cprim]));
- break;
-
- case DL_BIND_ACK:
- /*
- * We're ready for data. Get man_lwsrv to run to
- * process any defered data and start linkcheck timer.
- */
- D_SETSTATE(mdp, DL_IDLE);
- qenable(mdp->md_wq);
- mdp->md_linkstate = MAN_LINKGOOD;
- if (man_needs_linkcheck(mdp)) {
- mdp->md_lc_timer_id = qtimeout(man_ctl_wq,
- man_linkcheck_timer, (void *)mdp,
- man_gettimer(MAN_TIMER_LINKCHECK, mdp));
- }
-
- break;
-
- case DL_ERROR_ACK:
- cprim = dlp->error_ack.dl_error_primitive;
- switch (cprim) {
- case DL_ATTACH_REQ:
- case DL_BIND_REQ:
- case DL_DISABMULTI_REQ:
- case DL_ENABMULTI_REQ:
- case DL_PROMISCON_REQ:
- case DL_PROMISCOFF_REQ:
- case DL_SET_PHYS_ADDR_REQ:
- need_dl_reset = TRUE;
- break;
-
- /*
- * ignore error TBD (better comment)
- */
- case DL_UNBIND_REQ:
- case DL_DETACH_REQ:
- break;
- }
-
- MAN_DBG(MAN_DLPI,
- ("\tdl_errno %d dl_unix_errno %d cprim %s",
- dlp->error_ack.dl_errno, dlp->error_ack.dl_unix_errno,
- dps[(int)cprim]));
- break;
-
- case DL_UDERROR_IND:
- MAN_DBG(MAN_DLPI,
- ("\tdl_errno %d unix_errno %d",
- dlp->uderror_ind.dl_errno,
- dlp->uderror_ind.dl_unix_errno));
- break;
-
- case DL_INFO_ACK:
- break;
-
- default:
- /*
- * We should not get here.
- */
- cmn_err(CE_WARN, "man_lrsrv: unexpected DL prim 0x%lx!",
- prim);
- need_dl_reset = TRUE;
- break;
- }
-
-dl_reset:
- freemsg(mp);
-
- if (need_dl_reset) {
- man_pg_t *mpg;
- man_path_t *mp;
-
- if (qsize(rq)) { /* Dump all messages. */
- flushq(rq, FLUSHDATA);
- flushq(WR(rq), FLUSHDATA);
- }
-
- mdp->md_dlpierrors++;
- D_SETSTATE(mdp, DL_UNATTACHED);
- if (mdp->md_lc_timer_id != 0) {
- (void) quntimeout(man_ctl_wq, mdp->md_lc_timer_id);
- mdp->md_lc_timer_id = 0;
- }
-
- mutex_enter(&man_lock);
- ASSERT(mdp->md_msp != NULL);
- ASSERT(mdp->md_msp->ms_manp != NULL);
- mpg = man_find_pg_by_id(mdp->md_msp->ms_manp->man_pg,
- mdp->md_pg_id);
- ASSERT(mpg != NULL);
- mp = man_find_path_by_ppa(mpg->mpg_pathp,
- mdp->md_device.mdev_ppa);
- ASSERT(mp != NULL);
- mp->mp_device.mdev_state |= MDEV_FAILED;
- if ((mdp->md_dlpierrors >= MAN_MAX_DLPIERRORS) &&
- (man_is_on_domain ||
- mdp->md_msp->ms_manp->man_meta_ppa == 1)) {
- /*
- * Autoswitching is disabled for instance 0
- * on the SC as we expect the domain to
- * initiate the path switching.
- */
- (void) man_do_autoswitch((man_dest_t *)mdp);
- MAN_DBG(MAN_WARN, ("man_lrsrv: dlpi failure(%d,%d),"
- " switching path", mdp->md_device.mdev_major,
- mdp->md_device.mdev_ppa));
- } else {
- mdp->md_lc_timer_id = qtimeout(man_ctl_wq,
- man_reset_dlpi, (void *)mdp,
- man_gettimer(MAN_TIMER_DLPIRESET, mdp));
- }
- mutex_exit(&man_lock);
- }
-
-
- } /* End while (getq()) */
-
-exit:
- MAN_DBG(MAN_DLPI, ("man_lrsrv: returns"));
-
- return (0);
-}
-
-static int
-man_needs_linkcheck(man_dest_t *mdp)
-{
- /*
- * Not ready for linkcheck.
- */
- if (mdp->md_msp == NULL || mdp->md_msp->ms_manp == NULL)
- return (0);
-
- /*
- * Linkchecking needs to be done on IP streams. For domain, all
- * driver instances need checking, for SC only instance 1 needs it.
- */
- if ((man_is_on_domain || mdp->md_msp->ms_manp->man_meta_ppa == 1) &&
- (mdp->md_msp->ms_sap == ETHERTYPE_IP ||
- mdp->md_msp->ms_sap == ETHERTYPE_IPV6))
-
- return (1);
-
- /*
- * Linkcheck not need on this link.
- */
- return (0);
-}
-
-/*
- * The following routines process work requests posted to man_iwork_q
- * from the non-STREAMS half of the driver (see man_bwork.c). The work
- * requires access to the inner perimeter lock of the driver. This
- * lock is acquired by man_uwsrv, who calls man_iwork to process the
- * man_iwork_q->
- */
-
-/*
- * The man_bwork has posted some work for us to do inside the
- * perimeter. This mainly involves updating lower multiplexor data
- * structures (non-blocking type stuff). So, we can hold the man_lock
- * until we are done processing all work items. Note that some of these
- * routines in turn submit work back to the bgthread, which they can do
- * since we hold the man_lock.
- */
-static void
-man_iwork()
-{
- man_work_t *wp;
- int wp_finished;
-
- MAN_DBG(MAN_SWITCH, ("man_iwork: q_work(0x%p)",
- (void *)man_iwork_q->q_work));
-
- mutex_enter(&man_lock);
-
- while (man_iwork_q->q_work) {
-
- wp = man_iwork_q->q_work;
- man_iwork_q->q_work = wp->mw_next;
- wp->mw_next = NULL;
-
- mutex_exit(&man_lock);
-
- MAN_DBG(MAN_SWITCH, ("man_iwork: type %s",
- _mw_type[wp->mw_type]));
-
- wp_finished = TRUE;
-
- switch (wp->mw_type) {
- case MAN_WORK_DRATTACH:
- (void) man_do_dr_attach(wp);
- break;
-
- case MAN_WORK_DRSWITCH:
- /*
- * Return status to man_dr_detach immediately. If
- * no error submitting SWITCH request, man_iswitch
- * or man_bclose will cv_signal man_dr_detach on
- * completion of SWITCH work request.
- */
- if (man_do_dr_switch(wp) == 0)
- wp_finished = FALSE;
- break;
-
- case MAN_WORK_DRDETACH:
- man_do_dr_detach(wp);
- break;
-
- case MAN_WORK_SWITCH:
- if (man_iswitch(wp))
- wp_finished = FALSE;
- break;
-
- case MAN_WORK_KSTAT_UPDATE:
- man_do_kstats(wp);
- break;
-
- default:
- cmn_err(CE_WARN, "man_iwork: "
- "illegal work type(%d)", wp->mw_type);
- break;
- }
-
- mutex_enter(&man_lock);
-
- /*
- * If we've completed the work request, delete, or
- * cv_signal waiter.
- */
- if (wp_finished) {
- wp->mw_flags |= MAN_WFLAGS_DONE;
-
- if (wp->mw_flags & MAN_WFLAGS_CVWAITER)
- cv_signal(&wp->mw_cv);
- else
- man_work_free(wp);
- }
- }
-
- mutex_exit(&man_lock);
-}
-
-/*
- * man_dr_detach has submitted a request to DRSWITCH a path.
- * It is in cv_wait_sig(wp->mw_cv). We forward the work request on to
- * man_bwork as a switch request. It should end up back at
- * man_iwork, who will cv_signal(wp->mw_cv) man_dr_detach.
- *
- * Called holding inner perimeter lock.
- * man_lock is held to synchronize access to pathgroup list(man_pg).
- */
-static int
-man_do_dr_switch(man_work_t *wp)
-{
- man_t *manp;
- man_pg_t *mpg;
- man_path_t *mp;
- man_path_t *ap;
- man_adest_t *adp;
- mi_path_t mpath;
- int status = 0;
-
- adp = &wp->mw_arg;
-
- MAN_DBG(MAN_SWITCH, ("man_do_dr_switch: pg_id %d work:", adp->a_pg_id));
- MAN_DBGCALL(MAN_SWITCH, man_print_work(wp));
-
- mutex_enter(&man_lock);
- manp = ddi_get_soft_state(man_softstate, adp->a_man_ppa);
- if (manp == NULL || manp->man_pg == NULL) {
- status = ENODEV;
- goto exit;
- }
-
- mpg = man_find_pg_by_id(manp->man_pg, adp->a_pg_id);
- if (mpg == NULL) {
- status = ENODEV;
- goto exit;
- }
-
- if (mpg->mpg_flags & MAN_PG_SWITCHING) {
- status = EAGAIN;
- goto exit;
- }
-
- /*
- * Check to see if detaching device is active. If so, activate
- * an alternate.
- */
- mp = man_find_active_path(mpg->mpg_pathp);
- if (mp && mp->mp_device.mdev_ppa == adp->a_sf_dev.mdev_ppa) {
-
- ap = man_find_alternate_path(mpg->mpg_pathp);
- if (ap == NULL) {
- status = EBUSY;
- goto exit;
- }
-
- bzero((char *)&mpath, sizeof (mi_path_t));
-
- mpath.mip_cmd = MI_PATH_ACTIVATE;
- mpath.mip_man_ppa = 0;
- mpath.mip_pg_id = 0;
- mpath.mip_devs[0] = ap->mp_device;
- mpath.mip_ndevs = 1;
- ether_copy(&manp->man_eaddr, &mpath.mip_eaddr);
-
- /*
- * DR thread is sleeping on wp->mw_cv. We change the work
- * request from DRSWITCH to SWITCH and submit it to
- * for processing by man_bwork (via man_pg_cmd). At
- * completion the SWITCH work request is processed by
- * man_iswitch() or man_bclose and the DR thread will
- * be cv_signal'd.
- */
- wp->mw_type = MAN_WORK_SWITCH;
- if (status = man_pg_cmd(&mpath, wp))
- goto exit;
-
- } else {
- /*
- * Tell man_dr_detach that detaching device is not currently
- * in use.
- */
- status = ENODEV;
- }
-
-exit:
- if (status) {
- /*
- * ENODEV is a noop, not really an error.
- */
- if (status != ENODEV)
- wp->mw_status = status;
- }
- mutex_exit(&man_lock);
-
- return (status);
-}
-
-/*
- * man_dr_attach has submitted a request to DRATTACH a path,
- * add that path to the path list.
- *
- * Called holding perimeter lock.
- */
-static int
-man_do_dr_attach(man_work_t *wp)
-{
- man_t *manp;
- man_adest_t *adp;
- mi_path_t mpath;
- manc_t manc;
- int status = 0;
-
- adp = &wp->mw_arg;
-
- MAN_DBG(MAN_SWITCH, ("man_do_dr_attach: pg_id %d work:", adp->a_pg_id));
- MAN_DBGCALL(MAN_SWITCH, man_print_work(wp));
-
- mutex_enter(&man_lock);
- manp = ddi_get_soft_state(man_softstate, adp->a_man_ppa);
- if (manp == NULL || manp->man_pg == NULL) {
- status = ENODEV;
- goto exit;
- }
-
- if (status = man_get_iosram(&manc)) {
- goto exit;
- }
- /*
- * Extract SC ethernet address from IOSRAM.
- */
- ether_copy(&manc.manc_sc_eaddr, &mpath.mip_eaddr);
-
- mpath.mip_pg_id = adp->a_pg_id;
- mpath.mip_man_ppa = adp->a_man_ppa;
- /*
- * man_dr_attach passes the new device info in a_sf_dev.
- */
- MAN_DBG(MAN_DR, ("man_do_dr_attach: "));
- MAN_DBGCALL(MAN_DR, man_print_dev(&adp->a_sf_dev));
- mpath.mip_devs[0] = adp->a_sf_dev;
- mpath.mip_ndevs = 1;
- mpath.mip_cmd = MI_PATH_ADD;
- status = man_pg_cmd(&mpath, NULL);
-
-exit:
- mutex_exit(&man_lock);
- return (status);
-}
-
-/*
- * man_dr_detach has submitted a request to DRDETACH a path.
- * It is in cv_wait_sig(wp->mw_cv). We remove the path and
- * cv_signal(wp->mw_cv) man_dr_detach.
- *
- * Called holding perimeter lock.
- */
-static void
-man_do_dr_detach(man_work_t *wp)
-{
- man_t *manp;
- man_pg_t *mpg;
- man_path_t *mp;
- man_adest_t *adp;
- manc_t manc;
- mi_path_t mpath;
- int i;
- int found;
- int status = 0;
-
- adp = &wp->mw_arg;
-
- MAN_DBG(MAN_SWITCH, ("man_do_dr_detach: pg_id %d work:", adp->a_pg_id));
- MAN_DBGCALL(MAN_SWITCH, man_print_work(wp));
-
- mutex_enter(&man_lock);
- manp = ddi_get_soft_state(man_softstate, adp->a_man_ppa);
- if (manp == NULL || manp->man_pg == NULL) {
- status = ENODEV;
- goto exit;
- }
-
- mpg = man_find_pg_by_id(manp->man_pg, adp->a_pg_id);
- if (mpg == NULL) {
- status = ENODEV;
- goto exit;
- }
-
- if (mpg->mpg_flags & MAN_PG_SWITCHING) {
- status = EAGAIN;
- goto exit;
- }
-
- /*
- * We should have switched detaching path if it was active.
- */
- mp = man_find_active_path(mpg->mpg_pathp);
- if (mp && mp->mp_device.mdev_ppa == adp->a_sf_dev.mdev_ppa) {
- status = EAGAIN;
- goto exit;
- }
-
- /*
- * Submit an ASSIGN command, minus the detaching device.
- */
- bzero((char *)&mpath, sizeof (mi_path_t));
-
- if (status = man_get_iosram(&manc)) {
- goto exit;
- }
-
- mpath.mip_cmd = MI_PATH_ASSIGN;
- mpath.mip_man_ppa = 0;
- mpath.mip_pg_id = 0;
-
- mp = mpg->mpg_pathp;
- i = 0;
- found = FALSE;
- while (mp != NULL) {
- if (mp->mp_device.mdev_ppa != adp->a_sf_dev.mdev_ppa) {
- mpath.mip_devs[i] = mp->mp_device;
- i++;
- } else {
- found = TRUE;
- }
- mp = mp->mp_next;
- }
-
- if (found) {
- /*
- * Need to include SCs ethernet address in command.
- */
- mpath.mip_ndevs = i;
- ether_copy(&manc.manc_sc_eaddr, &mpath.mip_eaddr);
-
- status = man_pg_cmd(&mpath, NULL);
- }
-
- /*
- * Hand back status to man_dr_detach request.
- */
-exit:
- if (status != ENODEV)
- wp->mw_status = status;
-
- mutex_exit(&man_lock);
-
-}
-
-
-/*
- * The background thread has configured new lower multiplexor streams for
- * the given destinations. Update the appropriate destination data structures
- * inside the inner perimeter. We must take care to deal with destinations
- * whose upper stream has closed or detached from lower streams.
- *
- * Returns
- * 0 Done with work request.
- * 1 Reused work request.
- */
-static int
-man_iswitch(man_work_t *wp)
-{
- man_adest_t *adp;
- man_t *manp;
- man_pg_t *mpg;
- man_path_t *mp = NULL;
- man_dest_t *mdp;
- man_dest_t *tdp;
- int i;
- int switch_ok = TRUE;
-
- adp = &wp->mw_arg;
-
- if (wp->mw_status != 0) {
- switch_ok = FALSE; /* Never got things opened */
- }
-
- /*
- * Update destination structures as appropriate.
- */
- for (i = 0; i < adp->a_ndests; i++) {
- man_dest_t tmp;
-
- /*
- * Check to see if lower stream we just switch is still
- * around.
- */
- tdp = &adp->a_mdp[i];
- mdp = man_switch_match(tdp, adp->a_pg_id, tdp->md_switch_id);
-
- if (mdp == NULL)
- continue;
-
- if (switch_ok == FALSE) {
- /*
- * Switch failed for some reason. Clear
- * PLUMBING flag and retry switch again later.
- */
- man_ifail_dest(mdp);
- continue;
- }
-
- /*
- * Swap new info, for old. We return the old info to
- * man_bwork to close things up below.
- */
- bcopy((char *)mdp, (char *)&tmp, sizeof (man_dest_t));
-
- ASSERT(mdp->md_state & MAN_DSTATE_PLUMBING);
- ASSERT(mdp->md_state == tdp->md_state);
-
- mdp->md_state = tdp->md_state;
-
- /*
- * save the wq from the destination passed(tdp).
- */
- mdp->md_wq = tdp->md_wq;
- RD(mdp->md_wq)->q_ptr = (void *)(mdp);
- WR(mdp->md_wq)->q_ptr = (void *)(mdp);
-
- mdp->md_state &= ~MAN_DSTATE_INITIALIZING;
- mdp->md_state |= MAN_DSTATE_READY;
-
- ASSERT(mdp->md_device.mdev_major == adp->a_sf_dev.mdev_major);
-
- ASSERT(tdp->md_device.mdev_ppa == adp->a_st_dev.mdev_ppa);
- ASSERT(tdp->md_device.mdev_major == adp->a_st_dev.mdev_major);
-
- mdp->md_device = tdp->md_device;
- mdp->md_muxid = tdp->md_muxid;
- mdp->md_linkstate = MAN_LINKUNKNOWN;
- (void) drv_getparm(TIME, &mdp->md_lastswitch);
- mdp->md_state &= ~MAN_DSTATE_PLUMBING;
- mdp->md_switch_id = 0;
- mdp->md_switches++;
- mdp->md_dlpierrors = 0;
- D_SETSTATE(mdp, DL_UNATTACHED);
-
- /*
- * Resync lower w/ upper dlpi state. This will start link
- * timer if/when lower stream goes to DL_IDLE (see man_lrsrv).
- */
- man_reset_dlpi((void *)mdp);
-
- bcopy((char *)&tmp, (char *)tdp, sizeof (man_dest_t));
- }
-
- if (switch_ok) {
- for (i = 0; i < adp->a_ndests; i++) {
- tdp = &adp->a_mdp[i];
-
- tdp->md_state &= ~MAN_DSTATE_PLUMBING;
- tdp->md_state &= ~MAN_DSTATE_INITIALIZING;
- tdp->md_state |= MAN_DSTATE_READY;
- }
- } else {
- /*
- * Never got switch-to destinations open, free them.
- */
- man_kfree(adp->a_mdp,
- sizeof (man_dest_t) * adp->a_ndests);
- }
-
- /*
- * Clear pathgroup switching flag and update path flags.
- */
- mutex_enter(&man_lock);
- manp = ddi_get_soft_state(man_softstate, adp->a_man_ppa);
-
- ASSERT(manp != NULL);
- ASSERT(manp->man_pg != NULL);
-
- mpg = man_find_pg_by_id(manp->man_pg, adp->a_pg_id);
- ASSERT(mpg != NULL);
- ASSERT(mpg->mpg_flags & MAN_PG_SWITCHING);
- mpg->mpg_flags &= ~MAN_PG_SWITCHING;
-
- /*
- * Switch succeeded, mark path we switched from as failed, and
- * device we switch to as active and clear its failed flag (if set).
- * Sync up kstats.
- */
- if (switch_ok) {
- mp = man_find_active_path(mpg->mpg_pathp);
- if (mp != NULL) {
-
- ASSERT(adp->a_sf_dev.mdev_major != 0);
-
- MAN_DBG(MAN_SWITCH, ("man_iswitch: switch from dev:"));
- MAN_DBGCALL(MAN_SWITCH, man_print_dev(&adp->a_sf_dev));
-
- mp->mp_device.mdev_state &= ~MDEV_ACTIVE;
- } else
- ASSERT(adp->a_sf_dev.mdev_major == 0);
-
- MAN_DBG(MAN_SWITCH, ("man_iswitch: switch to dev:"));
- MAN_DBGCALL(MAN_SWITCH, man_print_dev(&adp->a_st_dev));
-
- ASSERT(adp->a_st_dev.mdev_major != 0);
-
- mp = man_find_path_by_ppa(mpg->mpg_pathp,
- adp->a_st_dev.mdev_ppa);
-
- ASSERT(mp != NULL);
-
- mp->mp_device.mdev_state |= MDEV_ACTIVE;
- }
-
- /*
- * Decrement manp reference count and hand back work request if
- * needed.
- */
- manp->man_refcnt--;
-
- if (switch_ok) {
- wp->mw_type = MAN_WORK_CLOSE;
- man_work_add(man_bwork_q, wp);
- }
-
- mutex_exit(&man_lock);
-
- return (switch_ok);
-}
-
-/*
- * Find the destination in the upper stream that we just switched.
- */
-man_dest_t *
-man_switch_match(man_dest_t *sdp, int pg_id, void *sid)
-{
- man_dest_t *mdp = NULL;
- manstr_t *msp;
-
- for (msp = man_strup; msp != NULL; msp = msp->ms_next) {
- /*
- * Check if upper stream closed, or detached.
- */
- if (msp != sdp->md_msp)
- continue;
-
- if (msp->ms_dests == NULL)
- break;
-
- mdp = &msp->ms_dests[pg_id];
-
- /*
- * Upper stream detached and reattached while we were
- * switching.
- */
- if (mdp->md_switch_id != sid) {
- mdp = NULL;
- break;
- }
- }
-
- return (mdp);
-}
-
-/*
- * bg_thread cant complete the switch for some reason. (Re)start the
- * linkcheck timer again.
- */
-static void
-man_ifail_dest(man_dest_t *mdp)
-{
- ASSERT(mdp->md_lc_timer_id == 0);
- ASSERT(mdp->md_bc_id == 0);
- ASSERT(mdp->md_state & MAN_DSTATE_PLUMBING);
-
- MAN_DBG(MAN_SWITCH, ("man_ifail_dest"));
- MAN_DBGCALL(MAN_SWITCH, man_print_mdp(mdp));
-
- mdp->md_state &= ~MAN_DSTATE_PLUMBING;
- mdp->md_linkstate = MAN_LINKFAIL;
-
- /*
- * If we have not yet initialized link, or the upper stream is
- * DL_IDLE, restart the linktimer.
- */
- if ((mdp->md_state & MAN_DSTATE_INITIALIZING) ||
- ((mdp->md_msp->ms_sap == ETHERTYPE_IPV6 ||
- mdp->md_msp->ms_sap == ETHERTYPE_IP) &&
- mdp->md_msp->ms_dlpistate == DL_IDLE)) {
-
- mdp->md_lc_timer_id = qtimeout(man_ctl_wq, man_linkcheck_timer,
- (void *)mdp, man_gettimer(MAN_TIMER_LINKCHECK, mdp));
- }
-
-}
-
-/*
- * Arrange to replay all of ms_dl_mp on the new lower stream to get it
- * in sync with the upper stream. Note that this includes setting the
- * physical address.
- *
- * Called from qtimeout with inner perimeter lock.
- */
-static void
-man_reset_dlpi(void *argp)
-{
- man_dest_t *mdp = (man_dest_t *)argp;
- manstr_t *msp;
- mblk_t *mp;
- mblk_t *rmp = NULL;
- mblk_t *tmp;
-
- mdp->md_lc_timer_id = 0;
-
- if (mdp->md_state != MAN_DSTATE_READY) {
- MAN_DBG(MAN_DLPI, ("man_reset_dlpi: not ready!"));
- return;
- }
-
- msp = mdp->md_msp;
-
- rmp = man_dup_mplist(msp->ms_dl_mp);
- if (rmp == NULL)
- goto fail;
-
- /*
- * Send down an unbind and detach request, just to clean things
- * out, we ignore ERROR_ACKs for unbind and detach in man_lrsrv.
- */
- tmp = man_alloc_ubreq_dreq();
- if (tmp == NULL) {
- goto fail;
- }
- mp = tmp;
- while (mp->b_next != NULL)
- mp = mp->b_next;
- mp->b_next = rmp;
- rmp = tmp;
-
- man_dlpi_replay(mdp, rmp);
-
- return;
-
-fail:
-
- while (rmp) {
- mp = rmp;
- rmp = rmp->b_next;
- mp->b_next = mp->b_prev = NULL;
- freemsg(mp);
- }
-
- ASSERT(mdp->md_lc_timer_id == 0);
- ASSERT(mdp->md_bc_id == 0);
-
- /*
- * If low on memory, try again later. I Could use qbufcall, but that
- * could fail and I would have to try and recover from that w/
- * qtimeout anyway.
- */
- mdp->md_lc_timer_id = qtimeout(man_ctl_wq, man_reset_dlpi,
- (void *)mdp, man_gettimer(MAN_TIMER_LINKCHECK, mdp));
-}
-
-/*
- * Once we receive acknowledgement that DL_ATTACH_REQ was successful,
- * we can send down the DL_* related IOCTLs (e.g. DL_IOC_HDR). If we
- * try and send them downsteam w/o waiting, the ioctl's get processed before
- * the ATTACH_REQ and they are rejected. TBD - could just do the lower
- * dlpi state change in lock step. TBD
- */
-static int
-man_dlioc_replay(man_dest_t *mdp)
-{
- mblk_t *rmp;
- int status = 1;
-
- if (mdp->md_msp->ms_dlioc_mp == NULL)
- goto exit;
-
- rmp = man_dup_mplist(mdp->md_msp->ms_dlioc_mp);
- if (rmp == NULL) {
- status = 0;
- goto exit;
- }
-
- man_dlpi_replay(mdp, rmp);
-exit:
- return (status);
-}
-
-static mblk_t *
-man_alloc_ubreq_dreq()
-{
- mblk_t *dreq;
- mblk_t *ubreq = NULL;
- union DL_primitives *dlp;
-
- dreq = allocb(DL_DETACH_REQ_SIZE, BPRI_MED);
- if (dreq == NULL)
- goto exit;
-
- dreq->b_datap->db_type = M_PROTO;
- dlp = (union DL_primitives *)dreq->b_rptr;
- dlp->dl_primitive = DL_DETACH_REQ;
- dreq->b_wptr += DL_DETACH_REQ_SIZE;
-
- ubreq = allocb(DL_UNBIND_REQ_SIZE, BPRI_MED);
- if (ubreq == NULL) {
- freemsg(dreq);
- goto exit;
- }
-
- ubreq->b_datap->db_type = M_PROTO;
- dlp = (union DL_primitives *)ubreq->b_rptr;
- dlp->dl_primitive = DL_UNBIND_REQ;
- ubreq->b_wptr += DL_UNBIND_REQ_SIZE;
-
- ubreq->b_next = dreq;
-
-exit:
-
- return (ubreq);
-}
-
-static mblk_t *
-man_dup_mplist(mblk_t *mp)
-{
- mblk_t *listp = NULL;
- mblk_t *tailp = NULL;
-
- for (; mp != NULL; mp = mp->b_next) {
-
- mblk_t *nmp;
- mblk_t *prev;
- mblk_t *next;
-
- prev = mp->b_prev;
- next = mp->b_next;
- mp->b_prev = mp->b_next = NULL;
-
- nmp = copymsg(mp);
-
- mp->b_prev = prev;
- mp->b_next = next;
-
- if (nmp == NULL)
- goto nomem;
-
- if (listp == NULL) {
- listp = tailp = nmp;
- } else {
- tailp->b_next = nmp;
- tailp = nmp;
- }
- }
-
- return (listp);
-nomem:
-
- while (listp) {
- mp = listp;
- listp = mp->b_next;
- mp->b_next = mp->b_prev = NULL;
- freemsg(mp);
- }
-
- return (NULL);
-
-}
-
-static mblk_t *
-man_alloc_physreq_mp(eaddr_t *man_eap)
-{
-
- mblk_t *mp;
- union DL_primitives *dlp;
- t_uscalar_t off;
- eaddr_t *eap;
-
- mp = allocb(DL_SET_PHYS_ADDR_REQ_SIZE + ETHERADDRL, BPRI_MED);
- if (mp == NULL)
- goto exit;
-
- mp->b_datap->db_type = M_PROTO;
- dlp = (union DL_primitives *)mp->b_wptr;
- dlp->set_physaddr_req.dl_primitive = DL_SET_PHYS_ADDR_REQ;
- dlp->set_physaddr_req.dl_addr_length = ETHERADDRL;
- off = DL_SET_PHYS_ADDR_REQ_SIZE;
- dlp->set_physaddr_req.dl_addr_offset = off;
- mp->b_wptr += DL_SET_PHYS_ADDR_REQ_SIZE + ETHERADDRL;
-
- eap = (eaddr_t *)(mp->b_rptr + off);
- ether_copy(man_eap, eap);
-
-exit:
- MAN_DBG(MAN_DLPI, ("man_alloc_physreq: physaddr %s\n",
- ether_sprintf(eap)));
-
- return (mp);
-}
-
-/*
- * A new path in a pathgroup has become active for the first time. Setup
- * the lower destinations in prepartion for man_pg_activate to call
- * man_autoswitch.
- */
-static void
-man_add_dests(man_pg_t *mpg)
-{
- manstr_t *msp;
- man_dest_t *mdp;
-
- for (msp = man_strup; msp != NULL; msp = msp->ms_next) {
-
- if (!man_str_uses_pg(msp, mpg))
- continue;
-
- mdp = &msp->ms_dests[mpg->mpg_pg_id];
-
-/*
- * TBD - Take out
- * ASSERT(mdp->md_device.mdev_state == MDEV_UNASSIGNED);
- * ASSERT(mdp->md_state == MAN_DSTATE_NOTPRESENT);
- */
- if (mdp->md_device.mdev_state != MDEV_UNASSIGNED) {
- cmn_err(CE_NOTE, "man_add_dests mdev !unassigned");
- MAN_DBGCALL(MAN_PATH, man_print_mdp(mdp));
- }
-
- man_start_dest(mdp, msp, mpg);
- }
-
-}
-
-static int
-man_remove_dests(man_pg_t *mpg)
-{
- manstr_t *msp;
- int close_cnt = 0;
- man_dest_t *cdp;
- man_dest_t *mdp;
- man_dest_t *tdp;
- man_work_t *wp;
- mblk_t *mp;
- int status = 0;
-
- wp = man_work_alloc(MAN_WORK_CLOSE, KM_NOSLEEP);
- if (wp == NULL) {
- status = ENOMEM;
- goto exit;
- }
-
- /*
- * Count up number of destinations we need to close.
- */
- for (msp = man_strup; msp != NULL; msp = msp->ms_next) {
- if (!man_str_uses_pg(msp, mpg))
- continue;
-
- close_cnt++;
- }
-
- if (close_cnt == 0)
- goto exit;
-
- cdp = man_kzalloc(sizeof (man_dest_t) * close_cnt, KM_NOSLEEP);
- if (cdp == NULL) {
- status = ENOMEM;
- man_work_free(wp);
- goto exit;
- }
-
- tdp = cdp;
- for (msp = man_strup; msp != NULL; msp = msp->ms_next) {
- if (!man_str_uses_pg(msp, mpg))
- continue;
-
- mdp = &msp->ms_dests[mpg->mpg_pg_id];
-
- mdp->md_state |= MAN_DSTATE_CLOSING;
- mdp->md_device.mdev_state = MDEV_UNASSIGNED;
- mdp->md_msp = NULL;
- mdp->md_rq = NULL;
-
- /*
- * Clean up optimized destination pointer if we are
- * closing it.
- */
- man_set_optimized_dest(msp);
-
- if (mdp->md_lc_timer_id != 0) {
- (void) quntimeout(man_ctl_wq, mdp->md_lc_timer_id);
- mdp->md_lc_timer_id = 0;
- }
- if (mdp->md_bc_id != 0) {
- qunbufcall(man_ctl_wq, mdp->md_bc_id);
- mdp->md_bc_id = 0;
- }
-
- mutex_enter(&mdp->md_lock);
- while ((mp = mdp->md_dmp_head) != NULL) {
- mdp->md_dmp_head = mp->b_next;
- mp->b_next = NULL;
- freemsg(mp);
- }
- mdp->md_dmp_count = 0;
- mdp->md_dmp_tail = NULL;
- mutex_exit(&mdp->md_lock);
-
- *tdp++ = *mdp;
-
- mdp->md_state = MAN_DSTATE_NOTPRESENT;
- mdp->md_muxid = -1;
- }
-
- wp->mw_arg.a_mdp = cdp;
- wp->mw_arg.a_ndests = close_cnt;
- man_work_add(man_bwork_q, wp);
-
-exit:
- return (status);
-
-}
-
-/*
- * Returns TRUE if stream uses pathgroup, FALSE otherwise.
- */
-static int
-man_str_uses_pg(manstr_t *msp, man_pg_t *mpg)
-{
- int status;
-
- status = ((msp->ms_flags & MAN_SFLAG_CONTROL) ||
- (msp->ms_dests == NULL) ||
- (msp->ms_manp == NULL) ||
- (msp->ms_manp->man_meta_ppa != mpg->mpg_man_ppa));
-
- return (!status);
-}
-
-static int
-man_gettimer(int timer, man_dest_t *mdp)
-{
-
- int attached = TRUE;
- int time = 0;
-
- if (mdp == NULL || mdp->md_msp == NULL || mdp->md_msp->ms_manp == NULL)
- attached = FALSE;
-
- switch (timer) {
- case MAN_TIMER_INIT:
- if (attached)
- time = mdp->md_msp->ms_manp->man_init_time;
- else
- time = MAN_INIT_TIME;
- break;
-
- case MAN_TIMER_LINKCHECK:
- if (attached) {
- if (mdp->md_linkstate == MAN_LINKSTALE)
- time = mdp->md_msp->ms_manp->man_linkstale_time;
- else
- time = mdp->md_msp->ms_manp->man_linkcheck_time;
- } else
- time = MAN_LINKCHECK_TIME;
- break;
-
- case MAN_TIMER_DLPIRESET:
- if (attached)
- time = mdp->md_msp->ms_manp->man_dlpireset_time;
- else
- time = MAN_DLPIRESET_TIME;
- break;
-
- default:
- MAN_DBG(MAN_LINK, ("man_gettimer: unknown timer %d", timer));
- time = MAN_LINKCHECK_TIME;
- break;
- }
-
- return (drv_usectohz(time));
-}
-
-/*
- * Check the links for each active destination. Called inside inner
- * perimeter via qtimeout. This timer only runs on the domain side of the
- * driver. It should never run on the SC side.
- *
- * On a MAN_LINKGOOD link, we check/probe the link health every
- * MAN_LINKCHECK_TIME seconds. If the link goes MAN_LINKSTALE, the we probe
- * the link every MAN_LINKSTALE_TIME seconds, and fail the link after probing
- * the link MAN_LINKSTALE_RETRIES times.
- * The man_lock is held to synchronize access pathgroup list(man_pg).
- */
-void
-man_linkcheck_timer(void *argp)
-{
- man_dest_t *mdp = (man_dest_t *)argp;
- int restart_timer = TRUE;
- int send_ping = TRUE;
- int newstate;
- int oldstate;
- man_pg_t *mpg;
- man_path_t *mp;
-
- MAN_DBG(MAN_LINK, ("man_linkcheck_timer: mdp"));
- MAN_DBGCALL(MAN_LINK, man_print_mdp(mdp));
-
- /*
- * Clear timeout id and check if someones waiting on us to
- * complete a close.
- */
- mdp->md_lc_timer_id = 0;
-
- if (mdp->md_state == MAN_DSTATE_NOTPRESENT ||
- mdp->md_state & MAN_DSTATE_BUSY) {
-
- MAN_DBG(MAN_LINK, ("man_linkcheck_timer: not ready mdp"));
- MAN_DBGCALL(MAN_LINK, man_print_mdp(mdp));
- goto exit;
- }
-
- mutex_enter(&man_lock);
- /*
- * If the lower stream needs initializing, just go straight to
- * switch code. As the linkcheck timer is started for all
- * SAPs, do not send ping packets during the initialization.
- */
- if (mdp->md_state == MAN_DSTATE_INITIALIZING) {
- send_ping = FALSE;
- goto do_switch;
- }
-
- newstate = oldstate = mdp->md_linkstate;
-
- if (!man_needs_linkcheck(mdp)) {
- cmn_err(CE_NOTE,
- "man_linkcheck_timer: unneeded linkcheck on mdp(0x%p)",
- (void *)mdp);
- mutex_exit(&man_lock);
- return;
- }
-
- /*
- * The above call to man_needs_linkcheck() validates
- * mdp->md_msp and mdp->md_msp->ms_manp pointers.
- */
- mpg = man_find_pg_by_id(mdp->md_msp->ms_manp->man_pg, mdp->md_pg_id);
- ASSERT(mpg != NULL);
- mp = man_find_path_by_ppa(mpg->mpg_pathp, mdp->md_device.mdev_ppa);
- ASSERT(mp != NULL);
-
- /*
- * This is the most common case, when traffic is flowing.
- */
- if (mdp->md_rcvcnt != mdp->md_lastrcvcnt) {
-
- newstate = MAN_LINKGOOD;
- mdp->md_lastrcvcnt = mdp->md_rcvcnt;
- send_ping = FALSE;
-
- /*
- * Clear the FAILED flag and update lru.
- */
- mp->mp_device.mdev_state &= ~MDEV_FAILED;
- (void) drv_getparm(TIME, &mp->mp_lru);
-
- if (mdp->md_link_updown_msg == MAN_LINK_DOWN_MSG) {
- man_t *manp = mdp->md_msp->ms_manp;
-
- cmn_err(CE_NOTE, "%s%d Link up",
- ddi_major_to_name(manp->man_meta_major),
- manp->man_meta_ppa);
-
- mdp->md_link_updown_msg = MAN_LINK_UP_MSG;
- }
-
- goto done;
- }
-
- /*
- * If we're here, it means we have not seen any traffic
- */
- switch (oldstate) {
- case MAN_LINKINIT:
- case MAN_LINKGOOD:
- newstate = MAN_LINKSTALE;
- mdp->md_linkstales++;
- mdp->md_linkstale_retries =
- mdp->md_msp->ms_manp->man_linkstale_retries;
- break;
-
- case MAN_LINKSTALE:
- case MAN_LINKFAIL:
- mdp->md_linkstales++;
- mdp->md_linkstale_retries--;
- if (mdp->md_linkstale_retries < 0) {
- newstate = MAN_LINKFAIL;
- mdp->md_linkfails++;
- mdp->md_linkstale_retries =
- mdp->md_msp->ms_manp->man_linkstale_retries;
- /*
- * Mark the destination as FAILED and
- * update lru.
- */
- if (oldstate != MAN_LINKFAIL) {
- mp->mp_device.mdev_state |= MDEV_FAILED;
- (void) drv_getparm(TIME, &mp->mp_lru);
- }
- }
- break;
-
- default:
- cmn_err(CE_WARN, "man_linkcheck_timer: illegal link"
- " state %d", oldstate);
- break;
- }
-done:
-
- if (oldstate != newstate) {
-
- MAN_DBG(MAN_LINK, ("man_linkcheck_timer"
- " link state %s -> %s", lss[oldstate],
- lss[newstate]));
-
- mdp->md_linkstate = newstate;
- }
-
- /*
- * Do any work required from state transitions above.
- */
- if (newstate == MAN_LINKFAIL) {
-do_switch:
- if (!man_do_autoswitch(mdp)) {
- /*
- * Stop linkcheck timer until switch completes.
- */
- restart_timer = FALSE;
- send_ping = FALSE;
- }
- }
-
- mutex_exit(&man_lock);
- if (send_ping)
- man_do_icmp_bcast(mdp, mdp->md_msp->ms_sap);
-
- if (restart_timer)
- mdp->md_lc_timer_id = qtimeout(man_ctl_wq, man_linkcheck_timer,
- (void *)mdp, man_gettimer(MAN_TIMER_LINKCHECK, mdp));
-
-exit:
- MAN_DBG(MAN_LINK, ("man_linkcheck_timer: returns"));
-
-}
-
-/*
- * Handle linkcheck initiated autoswitching.
- * Called with man_lock held.
- */
-static int
-man_do_autoswitch(man_dest_t *mdp)
-{
- man_pg_t *mpg;
- man_path_t *ap;
- int status = 0;
-
- ASSERT(MUTEX_HELD(&man_lock));
- /*
- * Set flags and refcnt. Cleared in man_iswitch when SWITCH completes.
- */
- mdp->md_msp->ms_manp->man_refcnt++;
-
- mpg = man_find_pg_by_id(mdp->md_msp->ms_manp->man_pg, mdp->md_pg_id);
- ASSERT(mpg);
-
- if (mpg->mpg_flags & MAN_PG_SWITCHING)
- return (EBUSY);
-
- mpg->mpg_flags |= MAN_PG_SWITCHING;
-
- if (mdp->md_state == MAN_DSTATE_INITIALIZING) {
- /*
- * We're initializing, ask for a switch to our currently
- * active device.
- */
- status = man_autoswitch(mpg, &mdp->md_device, NULL);
- } else {
-
- if (mdp->md_msp != NULL && mdp->md_msp->ms_manp != NULL &&
- mdp->md_link_updown_msg == MAN_LINK_UP_MSG) {
-
- man_t *manp = mdp->md_msp->ms_manp;
-
- cmn_err(CE_NOTE, "%s%d Link down",
- ddi_major_to_name(manp->man_meta_major),
- manp->man_meta_ppa);
- }
- mdp->md_link_updown_msg = MAN_LINK_DOWN_MSG;
-
- MAN_DBG(MAN_LINK, ("man_linkcheck_timer: link failure on %s%d",
- ddi_major_to_name(mdp->md_device.mdev_major),
- mdp->md_device.mdev_ppa));
-
- ap = man_find_alternate_path(mpg->mpg_pathp);
-
- if (ap == NULL) {
- status = ENODEV;
- goto exit;
- }
- status = man_autoswitch(mpg, &ap->mp_device, NULL);
- }
-exit:
- if (status != 0) {
- /*
- * man_iswitch not going to run, clean up.
- */
- mpg->mpg_flags &= ~MAN_PG_SWITCHING;
- mdp->md_msp->ms_manp->man_refcnt--;
- }
-
- return (status);
-}
-
-/*
- * Gather up all lower multiplexor streams that have this link open and
- * try to switch them. Called from inner perimeter and holding man_lock.
- *
- * pg_id - Pathgroup to do switch for.
- * st_devp - New device to switch to.
- * wait_for_switch - whether or not to qwait for completion.
- */
-static int
-man_autoswitch(man_pg_t *mpg, man_dev_t *st_devp, man_work_t *waiter_wp)
-{
- man_work_t *wp;
- int sdp_cnt = 0;
- man_dest_t *sdp;
- int status = 0;
-
- ASSERT(MUTEX_HELD(&man_lock));
- if (waiter_wp == NULL) {
- wp = man_work_alloc(MAN_WORK_SWITCH, KM_NOSLEEP);
- if (wp == NULL) {
- status = ENOMEM;
- goto exit;
- }
- } else {
- ASSERT(waiter_wp->mw_type == MAN_WORK_SWITCH);
- wp = waiter_wp;
- }
-
- /*
- * Set dests as PLUMBING, cancel timers and return array of dests
- * that need a switch.
- */
- status = man_prep_dests_for_switch(mpg, &sdp, &sdp_cnt);
- if (status) {
- if (waiter_wp == NULL)
- man_work_free(wp);
- goto exit;
- }
-
- /*
- * If no streams are active, there are no streams to switch.
- * Return ENODEV (see man_pg_activate).
- */
- if (sdp_cnt == 0) {
- if (waiter_wp == NULL)
- man_work_free(wp);
- status = ENODEV;
- goto exit;
- }
-
- /*
- * Ask the bgthread to switch. See man_bwork.
- */
- wp->mw_arg.a_sf_dev = sdp->md_device;
- wp->mw_arg.a_st_dev = *st_devp;
- wp->mw_arg.a_pg_id = mpg->mpg_pg_id;
- wp->mw_arg.a_man_ppa = mpg->mpg_man_ppa;
-
- wp->mw_arg.a_mdp = sdp;
- wp->mw_arg.a_ndests = sdp_cnt;
- man_work_add(man_bwork_q, wp);
-
-exit:
-
- return (status);
-}
-
-/*
- * If an alternate path exists for pathgroup, arrange for switch to
- * happen. Note that we need to switch each of msp->dests[pg_id], for
- * all on man_strup. We must:
- *
- * Cancel any timers
- * Mark dests as PLUMBING
- * Submit switch request to man_bwork_q->
- */
-static int
-man_prep_dests_for_switch(man_pg_t *mpg, man_dest_t **mdpp, int *cntp)
-{
- manstr_t *msp;
- man_dest_t *mdp;
- int sdp_cnt = 0;
- man_dest_t *sdp = NULL;
- man_dest_t *tdp;
- int status = 0;
-
- MAN_DBG(MAN_SWITCH, ("man_prep_dests_for_switch: pg_id %d",
- mpg->mpg_pg_id));
-
- /*
- * Count up number of streams, there is one destination that needs
- * switching per stream.
- */
- for (msp = man_strup; msp != NULL; msp = msp->ms_next) {
- if (man_str_uses_pg(msp, mpg))
- sdp_cnt++;
- }
-
- if (sdp_cnt == 0)
- goto exit;
-
- sdp = man_kzalloc(sizeof (man_dest_t) * sdp_cnt, KM_NOSLEEP);
- if (sdp == NULL) {
- status = ENOMEM;
- goto exit;
- }
- tdp = sdp;
- /*
- * Mark each destination as unusable.
- */
- for (msp = man_strup; msp != NULL; msp = msp->ms_next) {
- if (man_str_uses_pg(msp, mpg)) {
-
- /*
- * Mark destination as plumbing and store the
- * address of sdp as a way to identify the
- * SWITCH request when it comes back (see man_iswitch).
- */
- mdp = &msp->ms_dests[mpg->mpg_pg_id];
- mdp->md_state |= MAN_DSTATE_PLUMBING;
- mdp->md_switch_id = sdp;
-
- /*
- * Copy destination info.
- */
- bcopy(mdp, tdp, sizeof (man_dest_t));
- tdp++;
-
- /*
- * Cancel timers.
- */
- if (mdp->md_lc_timer_id) {
- (void) quntimeout(man_ctl_wq,
- mdp->md_lc_timer_id);
- mdp->md_lc_timer_id = 0;
- }
- if (mdp->md_bc_id) {
- qunbufcall(man_ctl_wq, mdp->md_bc_id);
- mdp->md_bc_id = 0;
- }
- }
- }
-
- *mdpp = sdp;
- *cntp = sdp_cnt;
- status = 0;
-exit:
-
- MAN_DBG(MAN_SWITCH, ("man_prep_dests_for_switch: returns %d"
- " sdp(0x%p) sdp_cnt(%d)", status, (void *)sdp, sdp_cnt));
-
- return (status);
-
-}
-
-/*
- * The code below generates an ICMP echo packet and sends it to the
- * broadcast address in the hopes that the other end will respond
- * and the man_linkcheck_timer logic will see the traffic.
- *
- * This assumes ethernet-like media.
- */
-/*
- * Generate an ICMP packet. Called exclusive inner perimeter.
- *
- * mdp - destination to send packet to.
- * sap - either ETHERTYPE_ARP or ETHERTYPE_IPV6
- */
-static void
-man_do_icmp_bcast(man_dest_t *mdp, t_uscalar_t sap)
-{
- mblk_t *mp = NULL;
-
- /* TBD - merge pinger and this routine. */
-
- ASSERT(sap == ETHERTYPE_IPV6 || sap == ETHERTYPE_IP);
-
- if (sap == ETHERTYPE_IPV6) {
- mdp->md_icmpv6probes++;
- } else {
- mdp->md_icmpv4probes++;
- }
- /*
- * Send the ICMP message
- */
- mp = man_pinger(sap);
-
- MAN_DBG(MAN_LINK, ("man_do_icmp_bcast: sap=0x%x mp=0x%p",
- sap, (void *)mp));
- if (mp == NULL)
- return;
-
- /*
- * Send it out.
- */
- if (man_start_lower(mdp, mp, NULL, MAN_LOWER)) {
-
- MAN_DBG(MAN_LINK, ("man_do_icmp_broadcast: xmit failed"));
-
- freemsg(mp);
- }
-
-}
-
-static mblk_t *
-man_pinger(t_uscalar_t sap)
-{
- mblk_t *mp = NULL;
- man_dladdr_t dlsap;
- icmph_t *icmph;
- int ipver;
- ipha_t *ipha;
- ip6_t *ip6h;
- int iph_hdr_len;
- int datalen = 64;
- uchar_t *datap;
- uint16_t size;
- uchar_t i;
-
- dlsap.dl_sap = htons(sap);
- bcopy(&etherbroadcast, &dlsap.dl_phys, sizeof (dlsap.dl_phys));
-
- if (sap == ETHERTYPE_IPV6) {
- ipver = IPV6_VERSION;
- iph_hdr_len = sizeof (ip6_t);
- size = ICMP6_MINLEN;
- } else {
- ipver = IPV4_VERSION;
- iph_hdr_len = sizeof (ipha_t);
- size = ICMPH_SIZE;
- }
- size += (uint16_t)iph_hdr_len;
- size += datalen;
-
- mp = man_alloc_udreq(size, &dlsap);
- if (mp == NULL)
- goto exit;
-
- /*
- * fill out the ICMP echo packet headers
- */
- mp->b_cont->b_wptr += iph_hdr_len;
- if (ipver == IPV4_VERSION) {
- ipha = (ipha_t *)mp->b_cont->b_rptr;
- ipha->ipha_version_and_hdr_length = (IP_VERSION << 4)
- | IP_SIMPLE_HDR_LENGTH_IN_WORDS;
- ipha->ipha_type_of_service = 0;
- ipha->ipha_length = size;
- ipha->ipha_fragment_offset_and_flags = IPH_DF;
- ipha->ipha_ttl = 1;
- ipha->ipha_protocol = IPPROTO_ICMP;
- if (man_is_on_domain) {
- manc_t manc;
-
- if (man_get_iosram(&manc)) {
- freemsg(mp);
- mp = NULL;
- goto exit;
- }
-
- /*
- * Domain generates ping packets for domain to
- * SC network (dman0 <--> scman0).
- */
- ipha->ipha_dst = manc.manc_sc_ipaddr;
- ipha->ipha_src = manc.manc_dom_ipaddr;
- } else {
- /*
- * Note that ping packets are only generated
- * by the SC across scman1 (SC to SC network).
- */
- ipha->ipha_dst = man_sc_ipaddrs.ip_other_sc_ipaddr;
- ipha->ipha_src = man_sc_ipaddrs.ip_my_sc_ipaddr;
- }
-
- ipha->ipha_ident = 0;
-
- ipha->ipha_hdr_checksum = 0;
- ipha->ipha_hdr_checksum = IP_CSUM(mp->b_cont, 0, 0);
-
- } else {
- ip6h = (ip6_t *)mp->b_cont->b_rptr;
- /*
- * IP version = 6, priority = 0, flow = 0
- */
- ip6h->ip6_flow = (IPV6_VERSION << 28);
- ip6h->ip6_plen =
- htons((short)(size - iph_hdr_len));
- ip6h->ip6_nxt = IPPROTO_ICMPV6;
- ip6h->ip6_hlim = 1; /* stay on link */
-
- if (man_is_on_domain) {
- manc_t manc;
-
- if (man_get_iosram(&manc)) {
- freemsg(mp);
- mp = NULL;
- goto exit;
- }
-
- /*
- * Domain generates ping packets for domain to
- * SC network (dman0 <--> scman0).
- */
- ip6h->ip6_src = manc.manc_dom_ipv6addr;
- ip6h->ip6_dst = manc.manc_sc_ipv6addr;
- } else {
- /*
- * Note that ping packets are only generated
- * by the SC across scman1 (SC to SC network).
- */
- ip6h->ip6_src = man_sc_ip6addrs.ip6_my_sc_ipaddr;
- ip6h->ip6_dst = man_sc_ip6addrs.ip6_other_sc_ipaddr;
- }
- }
-
- /*
- * IPv6 and IP are the same for ICMP as far as I'm concerned.
- */
- icmph = (icmph_t *)mp->b_cont->b_wptr;
- if (ipver == IPV4_VERSION) {
- mp->b_cont->b_wptr += ICMPH_SIZE;
- icmph->icmph_type = ICMP_ECHO_REQUEST;
- icmph->icmph_code = 0;
- } else {
- mp->b_cont->b_wptr += ICMP6_MINLEN;
- icmph->icmph_type = ICMP6_ECHO_REQUEST;
- icmph->icmph_code = 0;
- }
-
- datap = mp->b_cont->b_wptr;
- mp->b_cont->b_wptr += datalen;
-
- for (i = 0; i < datalen; i++)
- *datap++ = i;
-
- if (ipver == IPV4_VERSION) {
- icmph->icmph_checksum = IP_CSUM(mp->b_cont, iph_hdr_len, 0);
- } else {
- uint32_t sum;
-
- sum = htons(IPPROTO_ICMPV6) + ip6h->ip6_plen;
- icmph->icmph_checksum = IP_CSUM(mp->b_cont, iph_hdr_len - 32,
- (sum & 0xffff) + (sum >> 16));
- }
-
-/*
- * TBD
- * icp->icmp_time = ???;
- */
-
-exit:
- return (mp);
-}
-
-static mblk_t *
-man_alloc_udreq(int size, man_dladdr_t *dlsap)
-{
- dl_unitdata_req_t *udreq;
- mblk_t *bp;
- mblk_t *mp;
-
- mp = allocb(sizeof (dl_unitdata_req_t) + sizeof (*dlsap), BPRI_MED);
-
- if (mp == NULL) {
- cmn_err(CE_NOTE, "man_preparepkt: allocb failed");
- return (NULL);
- }
-
- if ((bp = allocb(size, BPRI_MED)) == NULL) {
- freemsg(mp);
- cmn_err(CE_NOTE, "man_preparepkts: allocb failed");
- return (NULL);
- }
- bzero(bp->b_rptr, size);
-
- mp->b_cont = bp;
- mp->b_datap->db_type = M_PROTO;
- udreq = (dl_unitdata_req_t *)mp->b_wptr;
- mp->b_wptr += sizeof (dl_unitdata_req_t);
-
- /*
- * phys addr first - TBD
- */
- bcopy((char *)dlsap, mp->b_wptr, sizeof (*dlsap));
- mp->b_wptr += sizeof (*dlsap);
-
- udreq->dl_primitive = DL_UNITDATA_REQ;
- udreq->dl_dest_addr_length = sizeof (*dlsap);
- udreq->dl_dest_addr_offset = sizeof (*udreq);
- udreq->dl_priority.dl_min = 0;
- udreq->dl_priority.dl_max = 0;
-
- return (mp);
-}
-
-
-/*
- * The routines in this file are executed by the MAN background thread,
- * which executes outside of the STREAMS framework (see man_str.c). It is
- * allowed to do the things required to modify the STREAMS driver (things
- * that are normally done from a user process). These routines do things like
- * open and close drivers, PLINK and PUNLINK streams to/from the multiplexor,
- * etc.
- *
- * The mechanism of communication between the STREAMS portion of the driver
- * and the background thread portion are two work queues, man_bwork_q
- * and man_iwork_q (background work q and streams work q). Work
- * requests are placed on those queues when one half of the driver wants
- * the other half to do some work for it.
- *
- * The MAN background thread executes the man_bwork routine. Its sole
- * job is to process work requests placed on this work q. The MAN upper
- * write service routine is responsible for processing work requests posted
- * to the man_iwork_q->
- *
- * Both work queues are protected by the global mutex man_lock. The
- * man_bwork is signalged via the condvarman_bwork_q->q_cv. The man_uwsrv
- * routine is signaled by calling qenable (forcing man_uwsrv to run).
- */
-
-/*
- * man_bwork - Work thread for this device. It is responsible for
- * performing operations which can't occur within the STREAMS framework.
- *
- * Locking:
- * - Called holding no locks
- * - Obtains the global mutex man_lock to remove work from
- * man_bwork_q, and post work to man_iwork_q->
- * - Note that we do not want to hold any locks when making
- * any ldi_ calls.
- */
-void
-man_bwork()
-{
- man_work_t *wp;
- int done = 0;
- callb_cpr_t cprinfo;
- int wp_finished;
-
- CALLB_CPR_INIT(&cprinfo, &man_lock, callb_generic_cpr,
- "mn_work_thrd");
-
- MAN_DBG(MAN_CONFIG, ("man_bwork: enter"));
-
- while (done == 0) {
-
- mutex_enter(&man_lock);
- /*
- * While there is nothing to do, sit in cv_wait. If work
- * request is made, requester will signal.
- */
- while (man_bwork_q->q_work == NULL) {
-
- CALLB_CPR_SAFE_BEGIN(&cprinfo);
-
- cv_wait(&man_bwork_q->q_cv, &man_lock);
-
- CALLB_CPR_SAFE_END(&cprinfo, &man_lock);
- }
-
- wp = man_bwork_q->q_work;
- man_bwork_q->q_work = wp->mw_next;
- wp->mw_next = NULL;
- mutex_exit(&man_lock);
-
- wp_finished = TRUE;
-
- MAN_DBG(MAN_SWITCH, ("man_bwork: type %s",
- _mw_type[wp->mw_type]));
-
- switch (wp->mw_type) {
- case MAN_WORK_OPEN_CTL:
- wp->mw_status = man_open_ctl();
- break;
-
- case MAN_WORK_CLOSE_CTL:
- man_close_ctl();
- break;
-
- case MAN_WORK_CLOSE:
- case MAN_WORK_CLOSE_STREAM:
- man_bclose(&wp->mw_arg);
- break;
-
- case MAN_WORK_SWITCH:
- man_bswitch(&wp->mw_arg, wp);
- wp_finished = FALSE;
- break;
-
- case MAN_WORK_STOP: /* man_bwork_stop() */
- done = 1;
- mutex_enter(&man_lock);
- CALLB_CPR_EXIT(&cprinfo); /* Unlocks man_lock */
- break;
-
- default:
- cmn_err(CE_WARN, "man_bwork: "
- "illegal work type(%d)", wp->mw_type);
- break;
- }
-
- mutex_enter(&man_lock);
-
- if (wp_finished) {
- wp->mw_flags |= MAN_WFLAGS_DONE;
- if (wp->mw_flags & MAN_WFLAGS_CVWAITER)
- cv_signal(&wp->mw_cv);
- else if (wp->mw_flags & MAN_WFLAGS_QWAITER)
- qenable(wp->mw_q);
- else
- man_work_free(wp);
- }
-
- mutex_exit(&man_lock);
- }
-
- MAN_DBG(MAN_CONFIG, ("man_bwork: thread_exit"));
-
- mutex_enter(&man_lock);
- man_bwork_id = NULL;
- mutex_exit(&man_lock);
-
- thread_exit();
-}
-
-/*
- * man_open_ctl - Open the control stream.
- *
- * returns - success - 0
- * - failure - errno code
- *
- * Mutex Locking Notes:
- * We need a way to keep the CLONE_OPEN qwaiters in man_open from
- * checking the man_config variables after the ldi_open call below
- * returns from man_open, leaving the inner perimeter. So, we use the
- * man_lock to synchronize the threads in man_open_ctl and man_open. We
- * hold man_lock across this call into man_open, which in general is a
- * no-no. But, the STREAMs portion of the driver (other than open)
- * doesn't use it. So, if ldi_open gets hijacked to run any part of
- * the MAN streams driver, it wont end up recursively trying to acquire
- * man_lock. Note that the non-CLONE_OPEN portion of man_open doesnt
- * acquire it either, so again no recursive mutex.
- */
-static int
-man_open_ctl()
-{
- int status = 0;
- ldi_handle_t ctl_lh = NULL;
- ldi_ident_t li = NULL;
-
- MAN_DBG(MAN_CONFIG, ("man_open_ctl: plumbing control stream\n"));
-
- /*
- * Get eri driver loaded and kstats initialized. Is there a better
- * way to do this? - TBD.
- */
- status = ldi_ident_from_mod(&modlinkage, &li);
- if (status) {
- cmn_err(CE_WARN,
- "man_open_ctl: ident alloc failed, error %d", status);
- goto exit;
- }
-
- status = ldi_open_by_name(ERI_PATH, FREAD | FWRITE | FNOCTTY,
- kcred, &ctl_lh, li);
- if (status) {
- cmn_err(CE_WARN,
- "man_open_ctl: eri open failed, error %d", status);
- ctl_lh = NULL;
- goto exit;
- }
- (void) ldi_close(ctl_lh, NULL, kcred);
- ctl_lh = NULL;
-
- mutex_enter(&man_lock);
-
- if (man_ctl_lh != NULL) {
- mutex_exit(&man_lock);
- goto exit;
- }
-
- ASSERT(man_ctl_wq == NULL);
- mutex_exit(&man_lock);
-
- status = ldi_open_by_name(DMAN_INT_PATH, FREAD | FWRITE | FNOCTTY,
- kcred, &ctl_lh, li);
- if (status) {
- cmn_err(CE_WARN,
- "man_open_ctl: man control dev open failed, "
- "error %d", status);
- goto exit;
- }
-
- /*
- * Update global config state. TBD - dont need lock here, since
- * everyone is stuck in open until we finish. Only other modifier
- * is man_deconfigure via _fini, which returns EBUSY if there is
- * any open streams (other than control). Do need to signal qwaiters
- * on error.
- */
- mutex_enter(&man_lock);
- ASSERT(man_config_state == MAN_CONFIGURING);
- ASSERT(man_ctl_lh == NULL);
- man_ctl_lh = ctl_lh;
- mutex_exit(&man_lock);
-
-exit:
- if (li)
- ldi_ident_release(li);
-
- MAN_DBG(MAN_CONFIG, ("man_open_ctl: man_ctl_lh(0x%p) errno = %d\n",
- (void *)man_ctl_lh, status));
-
- return (status);
-}
-
-/*
- * man_close_ctl - Close control stream, we are about to unload driver.
- *
- * Locking:
- * - Called holding no locks.
- */
-static void
-man_close_ctl()
-{
- ldi_handle_t tlh;
-
- MAN_DBG(MAN_CONFIG, ("man_close_ctl: unplumbing control stream\n"));
-
- mutex_enter(&man_lock);
- if ((tlh = man_ctl_lh) != NULL)
- man_ctl_lh = NULL;
- mutex_exit(&man_lock);
-
- if (tlh != NULL) {
- (void) ldi_close(tlh, NULL, kcred);
- }
-
-}
-
-/*
- * Close the lower streams. Get all the timers canceled, close the lower
- * stream and delete the dest array.
- *
- * Returns:
- * 0 Closed all streams.
- * 1 Couldn't close one or more streams, timers still running.
- *
- * Locking:
- * - Called holding no locks.
- */
-static void
-man_bclose(man_adest_t *adp)
-{
- int i;
- man_dest_t *mdp;
-
- man_cancel_timers(adp);
-
- for (i = 0; i < adp->a_ndests; i++) {
- mdp = &adp->a_mdp[i];
-
- if (mdp->md_muxid != -1)
- man_unplumb(mdp);
- }
-
- mutex_destroy(&mdp->md_lock);
- man_kfree(adp->a_mdp, sizeof (man_dest_t) * adp->a_ndests);
- adp->a_mdp = NULL;
-}
-
-/*
- * We want to close down all lower streams. Need to wait until all
- * timers and work related to these lower streams is quiesced.
- *
- * Returns 1 if lower streams are quiesced, 0 if we need to wait
- * a bit longer.
- */
-static void
-man_cancel_timers(man_adest_t *adp)
-{
- man_dest_t *mdp;
- int cnt;
- int i;
-
- mdp = adp->a_mdp;
- cnt = adp->a_ndests;
-
- MAN_DBG(MAN_SWITCH, ("man_cancel_timers: mdp(0x%p) cnt %d",
- (void *)mdp, cnt));
-
- for (i = 0; i < cnt; i++) {
-
- if (mdp[i].md_lc_timer_id != 0) {
- (void) quntimeout(man_ctl_wq, mdp[i].md_lc_timer_id);
- mdp[i].md_lc_timer_id = 0;
- }
-
- if (mdp[i].md_bc_id != 0) {
- qunbufcall(man_ctl_wq, mdp[i].md_bc_id);
- mdp[i].md_bc_id = 0;
- }
- }
-
- MAN_DBG(MAN_SWITCH, ("man_cancel_timers: returns"));
-}
-
-/*
- * A failover is started at start of day, when the driver detects a
- * link failure (see man_linkcheck_timer), or when DR detaches
- * the IO board containing the current active link between SC and
- * domain (see man_dr_detach, man_iwork, and man_do_dr_detach). A
- * MAN_WORK_SWITCH work request containing all the lower streams that
- * should be switched is posted on the man_bwork_q-> This work request is
- * processed here. Once all lower streams have been switched to an
- * alternate path, the MAN_WORK_SWITCH work request is passed back to
- * man_iwork_q where it is processed within the inner perimeter of the
- * STREAMS framework (see man_iswitch).
- *
- * Note that when the switch fails for whatever reason, we just hand
- * back the lower streams untouched and let another failover happen.
- * Hopefully we will sooner or later succeed at the failover.
- */
-static void
-man_bswitch(man_adest_t *adp, man_work_t *wp)
-{
- man_dest_t *tdp;
- man_t *manp;
- int i;
- int status = 0;
-
- /*
- * Make a temporary copy of dest array, updating device to the
- * alternate and try to open all lower streams. bgthread can sleep.
- */
-
- tdp = man_kzalloc(sizeof (man_dest_t) * adp->a_ndests,
- KM_SLEEP);
- bcopy(adp->a_mdp, tdp, sizeof (man_dest_t) * adp->a_ndests);
-
- /*
- * Before we switch to the new path, lets sync the kstats.
- */
- mutex_enter(&man_lock);
-
- manp = ddi_get_soft_state(man_softstate, adp->a_man_ppa);
- if (manp != NULL) {
- man_update_path_kstats(manp);
- } else
- status = ENODEV;
-
- mutex_exit(&man_lock);
-
- if (status != 0)
- goto exit;
-
- for (i = 0; i < adp->a_ndests; i++) {
-
- tdp[i].md_device = adp->a_st_dev;
- tdp[i].md_muxid = -1;
-
- if (man_plumb(&tdp[i]))
- break;
- }
-
- /*
- * Didn't plumb everyone, unplumb new lower stuff and return.
- */
- if (i < adp->a_ndests) {
- int j;
-
- for (j = 0; j <= i; j++)
- man_unplumb(&tdp[j]);
- status = EAGAIN;
- goto exit;
- }
-
- if (man_is_on_domain && man_dossc_switch(adp->a_st_dev.mdev_exp_id)) {
- /*
- * If we cant set new path on the SSC, then fail the
- * failover.
- */
- for (i = 0; i < adp->a_ndests; i++)
- man_unplumb(&tdp[i]);
- status = EAGAIN;
- goto exit;
- }
-
- man_kfree(adp->a_mdp, sizeof (man_dest_t) * adp->a_ndests);
- adp->a_mdp = tdp;
-
-exit:
- if (status)
- man_kfree(tdp, sizeof (man_dest_t) * adp->a_ndests);
-
-
- MAN_DBG(MAN_SWITCH, ("man_bswitch: returns %d", status));
-
- /*
- * Hand processed switch request back to man_iwork for
- * processing in man_iswitch.
- */
- wp->mw_status = status;
-
- mutex_enter(&man_lock);
- man_work_add(man_iwork_q, wp);
- mutex_exit(&man_lock);
-
-}
-
-/*
- * man_plumb - Configure a lower stream for this destination.
- *
- * Locking:
- * - Called holding no locks.
- *
- * Returns:
- * - success - 0
- * - failure - error code of failure
- */
-static int
-man_plumb(man_dest_t *mdp)
-{
- int status;
- int muxid;
- ldi_handle_t lh;
- ldi_ident_t li = NULL;
-
- MAN_DBG(MAN_SWITCH, ("man_plumb: mdp(0x%p) %s%d exp(%d)",
- (void *)mdp, ddi_major_to_name(mdp->md_device.mdev_major),
- mdp->md_device.mdev_ppa, mdp->md_device.mdev_exp_id));
-
- /*
- * Control stream should already be open.
- */
- if (man_ctl_lh == NULL) {
- status = EAGAIN;
- goto exit;
- }
-
- mutex_enter(&man_lock);
- ASSERT(man_ctl_wq != NULL);
- status = ldi_ident_from_stream(man_ctl_wq, &li);
- if (status != 0) {
- cmn_err(CE_WARN,
- "man_plumb: ident alloc failed, error %d", status);
- goto exit;
- }
- mutex_exit(&man_lock);
-
- /*
- * previously opens were done by a dev_t of makedev(clone_major,
- * mdev_major) which should always map to /devices/pseudo/clone@0:eri
- */
- ASSERT(strcmp(ERI_IDNAME,
- ddi_major_to_name(mdp->md_device.mdev_major)) == 0);
-
- status = ldi_open_by_name(ERI_PATH, FREAD | FWRITE | FNOCTTY,
- kcred, &lh, li);
- if (status) {
- cmn_err(CE_WARN,
- "man_plumb: eri open failed, error %d", status);
- goto exit;
- }
-
- /*
- * Link netdev under MAN.
- */
- ASSERT(mdp->md_muxid == -1);
-
- status = ldi_ioctl(man_ctl_lh, I_PLINK, (intptr_t)lh,
- FREAD+FWRITE+FNOCTTY+FKIOCTL, kcred, &muxid);
- if (status) {
- cmn_err(CE_WARN,
- "man_plumb: ldi_ioctl(I_PLINK) failed, error %d", status);
- (void) ldi_close(lh, NULL, kcred);
- goto exit;
-
- }
- mdp->md_muxid = muxid;
- mdp->md_wq = man_linkrec_find(muxid);
- /*
- * If we can't find the linkrec then return an
- * error. It will be automatically unplumbed on failure.
- */
- if (mdp->md_wq == NULL)
- status = EAGAIN;
-
- (void) ldi_close(lh, NULL, kcred);
-exit:
- if (li)
- ldi_ident_release(li);
-
- MAN_DBG(MAN_SWITCH, ("man_plumb: exit\n"));
-
- return (status);
-}
-
-/*
- * man_unplumb - tear down the STREAMs framework for the lower multiplexor.
- *
- * mdp - destination struct of interest
- *
- * returns - success - 0
- * - failure - return error from ldi_ioctl
- */
-static void
-man_unplumb(man_dest_t *mdp)
-{
- int status, rval;
-
- MAN_DBG(MAN_SWITCH, ("man_unplumb: mdp"));
- MAN_DBGCALL(MAN_SWITCH, man_print_mdp(mdp));
-
- if (mdp->md_muxid == -1)
- return;
-
- ASSERT(man_ctl_lh != NULL);
-
- /*
- * I_PUNLINK causes the multiplexor resources to be freed.
- */
- status = ldi_ioctl(man_ctl_lh, I_PUNLINK, (intptr_t)mdp->md_muxid,
- FREAD+FWRITE+FNOCTTY+FKIOCTL, kcred, &rval);
- if (status) {
- cmn_err(CE_WARN, "man_unplumb: ldi_ioctl(I_PUNLINK) failed"
- " errno %d\n", status);
- }
- /*
- * Delete linkrec if it exists.
- */
- (void) man_linkrec_find(mdp->md_muxid);
- mdp->md_muxid = -1;
-
-}
-
-/*
- * The routines below deal with paths and pathgroups. These data structures
- * are used to track the physical devices connecting the domain and SSC.
- * These devices make up the lower streams of the MAN multiplexor. The
- * routines all expect the man_lock to be held.
- *
- * A pathgroup consists of all paths that connect a particular domain and the
- * SSC. The concept of a pathgroup id (pg_id) is used to uniquely identify
- * a pathgroup. For Domains, there is just one pathgroup, that connecting
- * the domain to the SSC (pg_id == 0). On the SSC, there is one pathgroup per
- * domain. The pg_id field corresponds to the domain tags A-R. A pg_id of
- * 0 means domain tag A, a pg_id of 1 means domain B, etc.
- *
- * The path data structure identifies one path between the SSC and a domain.
- * It describes the information for the path: the major and minor number of
- * the physical device; kstat pointers; and ethernet address of the
- * other end of the path.
- *
- * The pathgroups are anchored at man_pg_head and are protected by the
- * by the inner perimeter. The routines are only called by the STREAMs
- * portion of the driver.
- */
-
-/*
- * Update man instance pathgroup info. Exclusive inner perimeter assures
- * this code is single threaded. man_refcnt assures man_t wont detach
- * while we are playing with man_pg stuff.
- *
- * Returns 0 on success, errno on failure.
- */
-int
-man_pg_cmd(mi_path_t *mip, man_work_t *waiter_wp)
-{
- int status = 0;
- man_t *manp;
-
- if (mip->mip_ndevs < 0) {
- status = EINVAL;
- cmn_err(CE_WARN, "man_pg_cmd: EINVAL: mip_ndevs %d",
- mip->mip_ndevs);
- goto exit;
- }
-
- ASSERT(MUTEX_HELD(&man_lock));
- manp = ddi_get_soft_state(man_softstate, mip->mip_man_ppa);
- if (manp == NULL) {
- status = ENODEV;
- goto exit;
- }
-
- MAN_DBG(MAN_PATH, ("man_pg_cmd: mip"));
- MAN_DBGCALL(MAN_PATH, man_print_mip(mip));
-
- MAN_DBG(MAN_PATH, ("\tman_t"));
- MAN_DBGCALL(MAN_PATH, man_print_man(manp));
-
- switch (mip->mip_cmd) {
- case MI_PATH_ASSIGN:
- status = man_pg_assign(&manp->man_pg, mip, FALSE);
- break;
-
- case MI_PATH_ADD:
- status = man_pg_assign(&manp->man_pg, mip, TRUE);
- break;
-
- case MI_PATH_UNASSIGN:
- status = man_pg_unassign(&manp->man_pg, mip);
- break;
-
- case MI_PATH_ACTIVATE:
- status = man_pg_activate(manp, mip, waiter_wp);
- break;
-
- case MI_PATH_READ:
- status = man_pg_read(manp->man_pg, mip);
- break;
-
- default:
- status = EINVAL;
- cmn_err(CE_NOTE, "man_pg_cmd: invalid command");
- break;
- }
-
-exit:
- MAN_DBG(MAN_PATH, ("man_pg_cmd: returns %d", status));
-
- return (status);
-}
-
-/*
- * Assign paths to a pathgroup. If pathgroup doesnt exists, create it.
- * If path doesnt exist, create it. If ethernet address of existing
- * pathgroup different, change it. If an existing path is not in the new
- * list, remove it. If anything changed, send PATH_UPDATE request to
- * man_iwork to update all man_dest_t's.
- *
- * mplpp - man pathgroup list point to point.
- * mip - new/updated pathgroup info to assign.
- */
-static int
-man_pg_assign(man_pg_t **mplpp, mi_path_t *mip, int add_only)
-{
- man_pg_t *mpg;
- man_path_t *mp;
- man_path_t *add_paths = NULL;
- int cnt;
- int i;
- int first_pass = TRUE;
- int status = 0;
-
- ASSERT(MUTEX_HELD(&man_lock));
-
- cnt = mip->mip_ndevs;
- if (cnt == 0) {
- status = EINVAL;
- cmn_err(CE_NOTE, "man_pg_assign: mip_ndevs == 0");
- goto exit;
- }
-
- /*
- * Assure the devices to be assigned are not assigned to some other
- * pathgroup.
- */
- for (i = 0; i < cnt; i++) {
- mpg = man_find_path_by_dev(*mplpp, &mip->mip_devs[i], NULL);
-
- if (mpg == NULL)
- continue;
-
- if ((mpg->mpg_man_ppa != mip->mip_man_ppa) ||
- (mpg->mpg_pg_id != mip->mip_pg_id)) {
- /*
- * Already assigned to some other man instance
- * or pathgroup.
- */
- status = EEXIST;
- goto exit;
- }
- }
-
- /*
- * Find pathgroup, or allocate new one if it doesnt exist and
- * add it to list at mplpp. Result is that mpg points to
- * pathgroup to modify.
- */
- mpg = man_find_pg_by_id(*mplpp, mip->mip_pg_id);
- if (mpg == NULL) {
-
- status = man_pg_create(mplpp, &mpg, mip);
- if (status)
- goto exit;
-
- } else if (ether_cmp(&mip->mip_eaddr, &mpg->mpg_dst_eaddr) != 0) {
-
- cmn_err(CE_WARN, "man_pg_assign: ethernet address mismatch");
- cmn_err(CE_CONT, "existing %s",
- ether_sprintf(&mpg->mpg_dst_eaddr));
- cmn_err(CE_CONT, "new %s",
- ether_sprintf(&mip->mip_eaddr));
-
- status = EINVAL;
- goto exit;
- }
-
- /*
- * Create list of new paths to add to pathgroup.
- */
- for (i = 0; i < cnt; i++) {
-
- if (man_find_path_by_dev(*mplpp, &mip->mip_devs[i], NULL))
- continue; /* Already exists in this pathgroup */
-
- mp = man_kzalloc(sizeof (man_path_t), KM_NOSLEEP);
- if (mp == NULL) {
- status = ENOMEM;
- goto exit;
- }
-
- mp->mp_device = mip->mip_devs[i];
- mp->mp_device.mdev_state = MDEV_ASSIGNED;
-
- MAN_DBG(MAN_PATH, ("man_pg_assign: assigning mdp"));
- MAN_DBGCALL(MAN_PATH, man_print_dev(&mp->mp_device));
-
- status = man_path_kstat_init(mp);
- if (status) {
- man_kfree(mp, sizeof (man_path_t));
- goto exit;
- }
-
- man_path_insert(&add_paths, mp);
- }
-
- /*
- * man_dr_attach passes only the path which is being DRd in.
- * So just add the path and don't worry about removing paths.
- */
- if (add_only == TRUE)
- goto exit;
-
-
- /*
- * Check if any paths we want to remove are ACTIVE. If not,
- * do a second pass and remove them.
- */
-again:
- mp = mpg->mpg_pathp;
- while (mp != NULL) {
- int in_new_list;
- man_path_t *rp;
-
- rp = NULL;
- in_new_list = FALSE;
-
- for (i = 0; i < cnt; i++) {
- if (mp->mp_device.mdev_ppa ==
- mip->mip_devs[i].mdev_ppa) {
-
- in_new_list = TRUE;
- break;
- }
- }
-
- if (!in_new_list) {
- if (first_pass) {
- if (mp->mp_device.mdev_state & MDEV_ACTIVE) {
- status = EBUSY;
- goto exit;
- }
- } else {
- rp = mp;
- }
- }
- mp = mp->mp_next;
-
- if (rp != NULL)
- man_path_remove(&mpg->mpg_pathp, rp);
- }
-
- if (first_pass == TRUE) {
- first_pass = FALSE;
- goto again;
- }
-
-exit:
- if (status == 0) {
- if (add_paths)
- man_path_merge(&mpg->mpg_pathp, add_paths);
- } else {
- while (add_paths != NULL) {
- mp = add_paths;
- add_paths = mp->mp_next;
- mp->mp_next = NULL;
-
- man_path_kstat_uninit(mp);
- man_kfree(mp, sizeof (man_path_t));
- }
- }
-
- return (status);
-}
-
-/*
- * Remove all paths from a pathgroup (domain shutdown). If there is an
- * active path in the group, shut down all destinations referencing it
- * first.
- */
-static int
-man_pg_unassign(man_pg_t **plpp, mi_path_t *mip)
-{
- man_pg_t *mpg;
- man_pg_t *tpg;
- man_pg_t *tppg;
- man_path_t *mp = NULL;
- int status = 0;
-
- ASSERT(MUTEX_HELD(&man_lock));
-
- /*
- * Check for existence of pathgroup.
- */
- if ((mpg = man_find_pg_by_id(*plpp, mip->mip_pg_id)) == NULL)
- goto exit;
-
- if (man_find_active_path(mpg->mpg_pathp) != NULL) {
- status = man_remove_dests(mpg);
- if (status)
- goto exit;
- }
-
- /*
- * Free all the paths for this pathgroup.
- */
- while (mpg->mpg_pathp) {
- mp = mpg->mpg_pathp;
- mpg->mpg_pathp = mp->mp_next;
- mp->mp_next = NULL;
-
- man_path_kstat_uninit(mp);
- man_kfree(mp, sizeof (man_path_t));
- }
-
- /*
- * Remove this pathgroup from the list, and free it.
- */
- tpg = tppg = *plpp;
- if (tpg == mpg) {
- *plpp = tpg->mpg_next;
- goto free_pg;
- }
-
- for (tpg = tpg->mpg_next; tpg != NULL; tpg = tpg->mpg_next) {
- if (tpg == mpg)
- break;
- tppg = tpg;
- }
-
- ASSERT(tpg != NULL);
-
- tppg->mpg_next = tpg->mpg_next;
- tpg->mpg_next = NULL;
-
-free_pg:
- man_kfree(tpg, sizeof (man_pg_t));
-
-exit:
- return (status);
-
-}
-
-/*
- * Set a new active path. This is done via man_ioctl so we are
- * exclusive in the inner perimeter.
- */
-static int
-man_pg_activate(man_t *manp, mi_path_t *mip, man_work_t *waiter_wp)
-{
- man_pg_t *mpg1;
- man_pg_t *mpg2;
- man_pg_t *plp;
- man_path_t *mp;
- man_path_t *ap;
- int status = 0;
-
- ASSERT(MUTEX_HELD(&man_lock));
- MAN_DBG(MAN_PATH, ("man_pg_activate: dev"));
- MAN_DBGCALL(MAN_PATH, man_print_dev(mip->mip_devs));
-
- if (mip->mip_ndevs != 1) {
- status = EINVAL;
- goto exit;
- }
-
- plp = manp->man_pg;
- mpg1 = man_find_pg_by_id(plp, mip->mip_pg_id);
- if (mpg1 == NULL) {
- status = EINVAL;
- goto exit;
- }
-
- mpg2 = man_find_path_by_dev(plp, mip->mip_devs, &mp);
- if (mpg2 == NULL) {
- status = ENODEV;
- goto exit;
- }
-
- if (mpg1 != mpg2) {
- status = EINVAL;
- goto exit;
- }
-
- ASSERT(mp->mp_device.mdev_ppa == mip->mip_devs->mdev_ppa);
-
- if (mpg1->mpg_flags & MAN_PG_SWITCHING) {
- status = EAGAIN;
- goto exit;
- }
-
- ap = man_find_active_path(mpg1->mpg_pathp);
- if (ap == NULL) {
- /*
- * This is the first time a path has been activated for
- * this pathgroup. Initialize all upper streams dest
- * structure for this pathgroup so autoswitch will find
- * them.
- */
- mp->mp_device.mdev_state |= MDEV_ACTIVE;
- man_add_dests(mpg1);
- goto exit;
- }
-
- /*
- * Path already active, nothing to do.
- */
- if (ap == mp)
- goto exit;
-
- /*
- * Try to autoswitch to requested device. Set flags and refcnt.
- * Cleared in man_iswitch when SWITCH completes.
- */
- manp->man_refcnt++;
- mpg1->mpg_flags |= MAN_PG_SWITCHING;
-
- /*
- * Switch to path specified.
- */
- status = man_autoswitch(mpg1, mip->mip_devs, waiter_wp);
-
- if (status != 0) {
- /*
- * man_iswitch not going to run, clean up.
- */
- manp->man_refcnt--;
- mpg1->mpg_flags &= ~MAN_PG_SWITCHING;
-
- if (status == ENODEV) {
- /*
- * Device not plumbed isn't really an error. Change
- * active device setting here, since man_iswitch isn't
- * going to be run to do it.
- */
- status = 0;
- ap->mp_device.mdev_state &= ~MDEV_ACTIVE;
- mp->mp_device.mdev_state |= MDEV_ACTIVE;
- }
- }
-
-exit:
- MAN_DBG(MAN_PATH, ("man_pg_activate: returns %d", status));
-
- return (status);
-}
-
-static int
-man_pg_read(man_pg_t *plp, mi_path_t *mip)
-{
- man_pg_t *mpg;
- man_path_t *mp;
- int cnt;
- int status = 0;
-
- ASSERT(MUTEX_HELD(&man_lock));
-
- if ((mpg = man_find_pg_by_id(plp, mip->mip_pg_id)) == NULL) {
- status = ENODEV;
- goto exit;
- }
-
- cnt = 0;
- for (mp = mpg->mpg_pathp; mp != NULL; mp = mp->mp_next) {
- bcopy(&mp->mp_device, &mip->mip_devs[cnt], sizeof (man_dev_t));
- if (cnt == mip->mip_ndevs)
- break;
- cnt++;
- }
-
- MAN_DBG(MAN_PATH, ("man_pg_read: pg(0x%p) id(%d) found %d paths",
- (void *)mpg, mpg->mpg_pg_id, cnt));
-
- mip->mip_ndevs = cnt;
-
- /*
- * TBD - What should errno be if user buffer too small ?
- */
- if (mp != NULL) {
- status = ENOMEM;
- }
-
-exit:
-
- return (status);
-}
-
-/*
- * return existing pathgroup, or create it. TBD - Need to update
- * all of destinations if we added a pathgroup. Also, need to update
- * all of man_strup if we add a path.
- *
- * mplpp - man pathgroup list point to pointer.
- * mpgp - returns newly created man pathgroup.
- * mip - info to fill in mpgp.
- */
-static int
-man_pg_create(man_pg_t **mplpp, man_pg_t **mpgp, mi_path_t *mip)
-{
- man_pg_t *mpg;
- man_pg_t *tpg;
- int status = 0;
-
- ASSERT(MUTEX_HELD(&man_lock));
-
- if (ether_cmp(&mip->mip_eaddr, &zero_ether_addr) == 0) {
- cmn_err(CE_NOTE, "man_ioctl: man_pg_create: ether"
- " addresss not set!");
- status = EINVAL;
- goto exit;
- }
-
- mpg = man_kzalloc(sizeof (man_pg_t), KM_NOSLEEP);
- if (mpg == NULL) {
- status = ENOMEM;
- goto exit;
- }
-
- mpg->mpg_flags = MAN_PG_IDLE;
- mpg->mpg_pg_id = mip->mip_pg_id;
- mpg->mpg_man_ppa = mip->mip_man_ppa;
- ether_copy(&mip->mip_eaddr, &mpg->mpg_dst_eaddr);
-
- MAN_DBG(MAN_PATH, ("man_pg_create: new mpg"));
- MAN_DBGCALL(MAN_PATH, man_print_mpg(mpg));
-
- tpg = *mplpp;
- if (tpg == NULL) {
- *mplpp = mpg;
- } else {
- while (tpg->mpg_next != NULL)
- tpg = tpg->mpg_next;
- tpg->mpg_next = mpg;
- }
-
-exit:
- *mpgp = mpg;
-
- return (status);
-}
-
-/*
- * Return pointer to pathgroup containing mdevp, null otherwise. Also,
- * if a path pointer is passed in, set it to matching path in pathgroup.
- *
- * Called holding man_lock.
- */
-static man_pg_t *
-man_find_path_by_dev(man_pg_t *plp, man_dev_t *mdevp, man_path_t **mpp)
-{
- man_pg_t *mpg;
- man_path_t *mp;
-
- ASSERT(MUTEX_HELD(&man_lock));
- for (mpg = plp; mpg != NULL; mpg = mpg->mpg_next) {
- for (mp = mpg->mpg_pathp; mp != NULL; mp = mp->mp_next) {
- if (mp->mp_device.mdev_major == mdevp->mdev_major &&
- mp->mp_device.mdev_ppa == mdevp->mdev_ppa) {
-
- if (mpp != NULL)
- *mpp = mp;
- return (mpg);
- }
- }
- }
-
- return (NULL);
-}
-
-/*
- * Return pointer to pathgroup assigned to destination, null if not found.
- *
- * Called holding man_lock.
- */
-static man_pg_t *
-man_find_pg_by_id(man_pg_t *mpg, int pg_id)
-{
- ASSERT(MUTEX_HELD(&man_lock));
- for (; mpg != NULL; mpg = mpg->mpg_next) {
- if (mpg->mpg_pg_id == pg_id)
- return (mpg);
- }
-
- return (NULL);
-}
-
-static man_path_t *
-man_find_path_by_ppa(man_path_t *mplist, int ppa)
-{
- man_path_t *mp;
-
- ASSERT(MUTEX_HELD(&man_lock));
- for (mp = mplist; mp != NULL; mp = mp->mp_next) {
- if (mp->mp_device.mdev_ppa == ppa)
- return (mp);
- }
-
- return (NULL);
-}
-
-static man_path_t *
-man_find_active_path(man_path_t *mplist)
-{
- man_path_t *mp;
-
- ASSERT(MUTEX_HELD(&man_lock));
- for (mp = mplist; mp != NULL; mp = mp->mp_next)
- if (mp->mp_device.mdev_state & MDEV_ACTIVE)
- return (mp);
-
- return (NULL);
-}
-
-/*
- * Try and find an alternate path.
- */
-static man_path_t *
-man_find_alternate_path(man_path_t *mlp)
-{
- man_path_t *ap; /* Active path */
- man_path_t *np; /* New alternate path */
- man_path_t *fp = NULL; /* LRU failed path */
-
- ASSERT(MUTEX_HELD(&man_lock));
- ap = man_find_active_path(mlp);
-
- /*
- * Find a non-failed path, or the lru failed path and switch to it.
- */
- for (np = mlp; np != NULL; np = np->mp_next) {
- if (np == ap)
- continue;
-
- if (np->mp_device.mdev_state == MDEV_ASSIGNED)
- goto exit;
-
- if (np->mp_device.mdev_state & MDEV_FAILED) {
- if (fp == NULL)
- fp = np;
- else
- if (fp->mp_lru > np->mp_lru)
- fp = np;
- }
- }
-
- /*
- * Nowhere to switch to.
- */
- if (np == NULL && (np = fp) == NULL)
- goto exit;
-
-exit:
- return (np);
-}
-
-/*
- * Assumes caller has verified existence.
- */
-static void
-man_path_remove(man_path_t **lpp, man_path_t *mp)
-{
- man_path_t *tp;
- man_path_t *tpp;
-
- ASSERT(MUTEX_HELD(&man_lock));
- MAN_DBG(MAN_PATH, ("man_path_remove: removing path"));
- MAN_DBGCALL(MAN_PATH, man_print_path(mp));
-
- tp = tpp = *lpp;
- if (tp == mp) {
- *lpp = tp->mp_next;
- goto exit;
- }
-
- for (tp = tp->mp_next; tp != NULL; tp = tp->mp_next) {
- if (tp == mp)
- break;
- tpp = tp;
- }
-
- ASSERT(tp != NULL);
-
- tpp->mp_next = tp->mp_next;
- tp->mp_next = NULL;
-
-exit:
- man_path_kstat_uninit(tp);
- man_kfree(tp, sizeof (man_path_t));
-
-}
-
-/*
- * Insert path into list, ascending order by ppa.
- */
-static void
-man_path_insert(man_path_t **lpp, man_path_t *mp)
-{
- man_path_t *tp;
- man_path_t *tpp;
-
- ASSERT(MUTEX_HELD(&man_lock));
- if (*lpp == NULL) {
- *lpp = mp;
- return;
- }
-
- tp = tpp = *lpp;
- if (tp->mp_device.mdev_ppa > mp->mp_device.mdev_ppa) {
- mp->mp_next = tp;
- *lpp = mp;
- return;
- }
-
- for (tp = tp->mp_next; tp != NULL; tp = tp->mp_next) {
- if (tp->mp_device.mdev_ppa > mp->mp_device.mdev_ppa)
- break;
- tpp = tp;
- }
-
- if (tp == NULL) {
- tpp->mp_next = mp;
- } else {
- tpp->mp_next = mp;
- mp->mp_next = tp;
- }
-}
-
-/*
- * Merge npp into lpp, ascending order by ppa. Assumes no
- * duplicates in either list.
- */
-static void
-man_path_merge(man_path_t **lpp, man_path_t *np)
-{
- man_path_t *tmp;
-
- ASSERT(MUTEX_HELD(&man_lock));
- while (np != NULL) {
- tmp = np;
- np = np->mp_next;
- tmp->mp_next = NULL;
-
- man_path_insert(lpp, tmp);
- }
-
-}
-
-static int
-man_path_kstat_init(man_path_t *mpp)
-{
-
- kstat_named_t *dev_knp;
- int status = 0;
-
- ASSERT(MUTEX_HELD(&man_lock));
- MAN_DBG(MAN_PATH, ("man_path_kstat_init: mpp(0x%p)\n", (void *)mpp));
-
- /*
- * Create named kstats for accounting purposes.
- */
- dev_knp = man_kzalloc(MAN_NUMSTATS * sizeof (kstat_named_t),
- KM_NOSLEEP);
- if (dev_knp == NULL) {
- status = ENOMEM;
- goto exit;
- }
- man_kstat_named_init(dev_knp, MAN_NUMSTATS);
- mpp->mp_last_knp = dev_knp;
-
-exit:
-
- MAN_DBG(MAN_PATH, ("man_path_kstat_init: returns %d\n", status));
-
- return (status);
-}
-
-static void
-man_path_kstat_uninit(man_path_t *mp)
-{
- ASSERT(MUTEX_HELD(&man_lock));
- man_kfree(mp->mp_last_knp, MAN_NUMSTATS * sizeof (kstat_named_t));
-}
-
-/*
- * man_work_alloc - allocate and initiate a work request structure
- *
- * type - type of request to allocate
- * returns - success - ptr to an initialized work structure
- * - failure - NULL
- */
-man_work_t *
-man_work_alloc(int type, int kmflag)
-{
- man_work_t *wp;
-
- wp = man_kzalloc(sizeof (man_work_t), kmflag);
- if (wp == NULL)
- goto exit;
-
- cv_init(&wp->mw_cv, NULL, CV_DRIVER, NULL); \
- wp->mw_type = type;
-
-exit:
- return (wp);
-}
-
-/*
- * man_work_free - deallocate a work request structure
- *
- * wp - ptr to work structure to be freed
- */
-void
-man_work_free(man_work_t *wp)
-{
- cv_destroy(&wp->mw_cv);
- man_kfree((void *)wp, sizeof (man_work_t));
-}
-
-/*
- * Post work to a work queue. The man_bwork sleeps on
- * man_bwork_q->q_cv, and work requesters may sleep on mw_cv.
- * The man_lock is used to protect both cv's.
- */
-void
-man_work_add(man_workq_t *q, man_work_t *wp)
-{
- man_work_t *lp = q->q_work;
-
- if (lp) {
- while (lp->mw_next != NULL)
- lp = lp->mw_next;
-
- lp->mw_next = wp;
-
- } else {
- q->q_work = wp;
- }
-
- /*
- * cv_signal for man_bwork_q, qenable for man_iwork_q
- */
- if (q == man_bwork_q) {
- cv_signal(&q->q_cv);
-
- } else { /* q == man_iwork_q */
-
- if (man_ctl_wq != NULL)
- qenable(man_ctl_wq);
- }
-
-}
-
-/* <<<<<<<<<<<<<<<<<<<<<<< NDD SUPPORT FUNCTIONS >>>>>>>>>>>>>>>>>>> */
-/*
- * ndd support functions to get/set parameters
- */
-
-/*
- * Register each element of the parameter array with the
- * named dispatch handler. Each element is loaded using
- * nd_load()
- *
- * cnt - the number of elements present in the parameter array
- */
-static int
-man_param_register(param_t *manpa, int cnt)
-{
- int i;
- ndgetf_t getp;
- ndsetf_t setp;
- int status = B_TRUE;
-
- MAN_DBG(MAN_CONFIG, ("man_param_register: manpa(0x%p) cnt %d\n",
- (void *)manpa, cnt));
-
- getp = man_param_get;
-
- for (i = 0; i < cnt; i++, manpa++) {
- switch (man_param_display[i]) {
- case MAN_NDD_GETABLE:
- setp = NULL;
- break;
-
- case MAN_NDD_SETABLE:
- setp = man_param_set;
- break;
-
- default:
- continue;
- }
-
- if (!nd_load(&man_ndlist, manpa->param_name, getp,
- setp, (caddr_t)manpa)) {
-
- (void) man_nd_free(&man_ndlist);
- status = B_FALSE;
- goto exit;
- }
- }
-
- if (!nd_load(&man_ndlist, "man_pathgroups_report",
- man_pathgroups_report, NULL, NULL)) {
-
- (void) man_nd_free(&man_ndlist);
- status = B_FALSE;
- goto exit;
- }
-
- if (!nd_load(&man_ndlist, "man_set_active_path",
- NULL, man_set_active_path, NULL)) {
-
- (void) man_nd_free(&man_ndlist);
- status = B_FALSE;
- goto exit;
- }
-
- if (!nd_load(&man_ndlist, "man_get_hostinfo",
- man_get_hostinfo, NULL, NULL)) {
-
- (void) man_nd_free(&man_ndlist);
- status = B_FALSE;
- goto exit;
- }
-
-exit:
-
- MAN_DBG(MAN_CONFIG, ("man_param_register: returns %d\n", status));
-
- return (status);
-}
-
-static void
-man_nd_getset(queue_t *wq, mblk_t *mp)
-{
-
- if (!nd_getset(wq, man_ndlist, mp))
- miocnak(wq, mp, 0, ENOENT);
- else
- qreply(wq, mp);
-}
-
-/*ARGSUSED*/
-static int
-man_pathgroups_report(queue_t *wq, mblk_t *mp, caddr_t cp, cred_t *cr)
-{
-
- man_t *manp;
- man_pg_t *mpg;
- int i;
- char pad[] = " "; /* 17 spaces */
- int pad_end;
-
-
- MAN_DBG(MAN_PATH, ("man_pathgroups_report: wq(0x%p) mp(0x%p)"
- " caddr 0x%p", (void *)wq, (void *)mp, (void *)cp));
-
- (void) mi_mpprintf(mp, "MAN Pathgroup report: (* == failed)");
- (void) mi_mpprintf(mp, "====================================="
- "==========================================");
-
- mutex_enter(&man_lock);
-
- for (i = 0; i < 2; i++) {
- manp = ddi_get_soft_state(man_softstate, i);
- if (manp == NULL)
- continue;
-
- (void) mi_mpprintf(mp,
- "Interface\tDestination\t\tActive Path\tAlternate Paths");
- (void) mi_mpprintf(mp, "---------------------------------------"
- "----------------------------------------");
-
- for (mpg = manp->man_pg; mpg != NULL; mpg = mpg->mpg_next) {
-
- (void) mi_mpprintf(mp, "%s%d\t\t",
- ddi_major_to_name(manp->man_meta_major),
- manp->man_meta_ppa);
-
- if (man_is_on_domain) {
- (void) mi_mpprintf_nr(mp, "Master SSC\t");
- man_preport(mpg->mpg_pathp, mp);
- } else {
- if (i == 0) {
- pad_end = 17 - strlen(ether_sprintf(
- &mpg->mpg_dst_eaddr));
- if (pad_end < 0 || pad_end > 16)
- pad_end = 0;
- pad[pad_end] = '\0';
-
- (void) mi_mpprintf_nr(mp, "%c %s%s",
- mpg->mpg_pg_id + 'A',
- ether_sprintf(&mpg->mpg_dst_eaddr),
- pad);
-
- pad[pad_end] = ' ';
- } else {
- (void) mi_mpprintf_nr(mp,
- "Other SSC\t");
- }
- man_preport(mpg->mpg_pathp, mp);
- }
- (void) mi_mpprintf_nr(mp, "\n");
- }
- }
-
- mutex_exit(&man_lock);
- MAN_DBG(MAN_PATH, ("man_pathgroups_report: returns"));
-
- return (0);
-}
-
-static void
-man_preport(man_path_t *plist, mblk_t *mp)
-{
- man_path_t *ap;
-
- ap = man_find_active_path(plist);
- /*
- * Active path
- */
- if (ap != NULL) {
- (void) mi_mpprintf_nr(mp, "\t%s%d\t\t",
- ddi_major_to_name(ap->mp_device.mdev_major),
- ap->mp_device.mdev_ppa);
- } else {
- (void) mi_mpprintf_nr(mp, "None \t");
- }
-
- /*
- * Alternate Paths.
- */
- while (plist != NULL) {
- (void) mi_mpprintf_nr(mp, "%s%d exp %d",
- ddi_major_to_name(plist->mp_device.mdev_major),
- plist->mp_device.mdev_ppa,
- plist->mp_device.mdev_exp_id);
- if (plist->mp_device.mdev_state & MDEV_FAILED)
- (void) mi_mpprintf_nr(mp, "*");
- plist = plist->mp_next;
- if (plist)
- (void) mi_mpprintf_nr(mp, ", ");
- }
-}
-
-/*
- * NDD request to set active path. Calling context is man_ioctl, so we are
- * exclusive in the inner perimeter.
- *
- * Syntax is "ndd -set /dev/dman <man ppa> <pg_id> <phys ppa>"
- */
-/* ARGSUSED3 */
-static int
-man_set_active_path(queue_t *wq, mblk_t *mp, char *value, caddr_t cp,
- cred_t *cr)
-{
- char *end, *meta_ppap, *phys_ppap, *pg_idp;
- int meta_ppa;
- int phys_ppa;
- int pg_id;
- man_t *manp;
- man_pg_t *mpg;
- man_path_t *np;
- mi_path_t mpath;
- int status = 0;
-
- MAN_DBG(MAN_PATH, ("man_set_active_path: wq(0x%p) mp(0x%p)"
- " args %s", (void *)wq, (void *)mp, value));
-
- meta_ppap = value;
-
- if ((pg_idp = strchr(value, ' ')) == NULL) {
- status = EINVAL;
- goto exit;
- }
-
- *pg_idp++ = '\0';
-
- if ((phys_ppap = strchr(pg_idp, ' ')) == NULL) {
- status = EINVAL;
- goto exit;
- }
-
- *phys_ppap++ = '\0';
-
- meta_ppa = (int)mi_strtol(meta_ppap, &end, 10);
- pg_id = (int)mi_strtol(pg_idp, &end, 10);
- phys_ppa = (int)mi_strtol(phys_ppap, &end, 10);
-
- mutex_enter(&man_lock);
- manp = ddi_get_soft_state(man_softstate, meta_ppa);
- if (manp == NULL || manp->man_pg == NULL) {
- status = EINVAL;
- mutex_exit(&man_lock);
- goto exit;
- }
-
- mpg = man_find_pg_by_id(manp->man_pg, pg_id);
- if (mpg == NULL) {
- status = EINVAL;
- mutex_exit(&man_lock);
- goto exit;
- }
-
- np = man_find_path_by_ppa(mpg->mpg_pathp, phys_ppa);
-
- if (np == NULL) {
- status = EINVAL;
- mutex_exit(&man_lock);
- goto exit;
- }
-
- mpath.mip_cmd = MI_PATH_ACTIVATE;
- mpath.mip_pg_id = pg_id;
- mpath.mip_man_ppa = meta_ppa;
- mpath.mip_devs[0] = np->mp_device;
- mpath.mip_ndevs = 1;
-
- status = man_pg_cmd(&mpath, NULL);
- mutex_exit(&man_lock);
-
-exit:
-
- MAN_DBG(MAN_PATH, ("man_set_active_path: returns %d", status));
-
- return (status);
-}
-
-/*
- * Dump out the contents of the IOSRAM handoff structure. Note that if
- * anything changes here, you must make sure that the sysinit script
- * stays in sync with this output.
- */
-/* ARGSUSED */
-static int
-man_get_hostinfo(queue_t *wq, mblk_t *mp, caddr_t cp, cred_t *cr)
-{
- manc_t manc;
- char *ipaddr;
- char ipv6addr[INET6_ADDRSTRLEN];
- int i;
- int status;
-
- if (!man_is_on_domain)
- return (0);
-
- if (status = man_get_iosram(&manc)) {
- return (status);
- }
-
- (void) mi_mpprintf(mp, "manc_magic = 0x%x", manc.manc_magic);
- (void) mi_mpprintf(mp, "manc_version = 0%d", manc.manc_version);
- (void) mi_mpprintf(mp, "manc_csum = 0x%x", manc.manc_csum);
-
- if (manc.manc_ip_type == AF_INET) {
- in_addr_t netnum;
-
- (void) mi_mpprintf(mp, "manc_ip_type = AF_INET");
-
- ipaddr = man_inet_ntoa(manc.manc_dom_ipaddr);
- (void) mi_mpprintf(mp, "manc_dom_ipaddr = %s", ipaddr);
-
- ipaddr = man_inet_ntoa(manc.manc_dom_ip_netmask);
- (void) mi_mpprintf(mp, "manc_dom_ip_netmask = %s", ipaddr);
-
- netnum = manc.manc_dom_ipaddr & manc.manc_dom_ip_netmask;
- ipaddr = man_inet_ntoa(netnum);
- (void) mi_mpprintf(mp, "manc_dom_ip_netnum = %s", ipaddr);
-
- ipaddr = man_inet_ntoa(manc.manc_sc_ipaddr);
- (void) mi_mpprintf(mp, "manc_sc_ipaddr = %s", ipaddr);
-
- } else if (manc.manc_ip_type == AF_INET6) {
-
- (void) mi_mpprintf(mp, "manc_ip_type = AF_INET6");
-
- (void) inet_ntop(AF_INET6, (void *)&manc.manc_dom_ipv6addr,
- ipv6addr, INET6_ADDRSTRLEN);
- (void) mi_mpprintf(mp, "manc_dom_ipv6addr = %s", ipv6addr);
-
- (void) mi_mpprintf(mp, "manc_dom_ipv6_netmask = %d",
- manc.manc_dom_ipv6_netmask.s6_addr[0]);
-
- (void) inet_ntop(AF_INET6, (void *)&manc.manc_sc_ipv6addr,
- ipv6addr, INET6_ADDRSTRLEN);
- (void) mi_mpprintf(mp, "manc_sc_ipv6addr = %s", ipv6addr);
-
- } else {
-
- (void) mi_mpprintf(mp, "manc_ip_type = NONE");
- }
-
- (void) mi_mpprintf(mp, "manc_dom_eaddr = %s",
- ether_sprintf(&manc.manc_dom_eaddr));
- (void) mi_mpprintf(mp, "manc_sc_eaddr = %s",
- ether_sprintf(&manc.manc_sc_eaddr));
-
- (void) mi_mpprintf(mp, "manc_iob_bitmap = 0x%x\tio boards = ",
- manc.manc_iob_bitmap);
- for (i = 0; i < MAN_MAX_EXPANDERS; i++) {
- if ((manc.manc_iob_bitmap >> i) & 0x1) {
- (void) mi_mpprintf_nr(mp, "%d.1, ", i);
- }
- }
- (void) mi_mpprintf(mp, "manc_golden_iob = %d", manc.manc_golden_iob);
-
- return (0);
-}
-
-static char *
-man_inet_ntoa(in_addr_t in)
-{
- static char b[18];
- unsigned char *p;
-
- p = (unsigned char *)&in;
- (void) sprintf(b, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- return (b);
-}
-
-/*
- * parameter value. cp points to the required parameter.
- */
-/* ARGSUSED */
-static int
-man_param_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *cr)
-{
- param_t *manpa = (param_t *)cp;
-
- (void) mi_mpprintf(mp, "%u", manpa->param_val);
- return (0);
-}
-
-/*
- * Sets the man parameter to the value in the param_register using
- * nd_load().
- */
-/* ARGSUSED */
-static int
-man_param_set(queue_t *q, mblk_t *mp, char *value, caddr_t cp, cred_t *cr)
-{
- char *end;
- size_t new_value;
- param_t *manpa = (param_t *)cp;
-
- new_value = mi_strtol(value, &end, 10);
-
- if (end == value || new_value < manpa->param_min ||
- new_value > manpa->param_max) {
- return (EINVAL);
- }
-
- manpa->param_val = new_value;
-
- return (0);
-
-}
-
-/*
- * Free the Named Dispatch Table by calling man_nd_free
- */
-static void
-man_param_cleanup()
-{
- if (man_ndlist != NULL)
- nd_free(&man_ndlist);
-}
-
-/*
- * Free the table pointed to by 'ndp'
- */
-static void
-man_nd_free(caddr_t *nd_pparam)
-{
- ND *nd;
-
- if ((nd = (ND *)(*nd_pparam)) != NULL) {
- if (nd->nd_tbl)
- mi_free((char *)nd->nd_tbl);
- mi_free((char *)nd);
- *nd_pparam = NULL;
- }
-}
-
-
-/*
- * man_kstat_update - update the statistics for a meta-interface.
- *
- * ksp - kstats struct
- * rw - flag indicating whether stats are to be read or written.
- *
- * returns 0
- *
- * The destination specific kstat information is protected by the
- * perimeter lock, so we submit a work request to get the stats
- * updated (see man_do_kstats()), and then collect the results
- * when cv_signal'd. Note that we are doing cv_timedwait_sig()
- * as a precautionary measure only.
- */
-static int
-man_kstat_update(kstat_t *ksp, int rw)
-{
- man_t *manp; /* per instance data */
- man_work_t *wp;
- int status = 0;
- kstat_named_t *knp;
- kstat_named_t *man_knp;
- int i;
-
- MAN_DBG(MAN_KSTAT, ("man_kstat_update: %s\n", rw ? "KSTAT_WRITE" :
- "KSTAT_READ"));
-
- mutex_enter(&man_lock);
- manp = (man_t *)ksp->ks_private;
- manp->man_refcnt++;
-
- /*
- * If the driver has been configured, get kstats updated by inner
- * perimeter prior to retrieving.
- */
- if (man_config_state == MAN_CONFIGURED) {
- clock_t wait_status;
-
- man_update_path_kstats(manp);
- wp = man_work_alloc(MAN_WORK_KSTAT_UPDATE, KM_SLEEP);
- wp->mw_arg.a_man_ppa = manp->man_meta_ppa;
- wp->mw_flags = MAN_WFLAGS_CVWAITER;
- man_work_add(man_iwork_q, wp);
-
- wait_status = cv_reltimedwait_sig(&wp->mw_cv, &man_lock,
- drv_usectohz(manp->man_kstat_waittime), TR_CLOCK_TICK);
-
- if (wp->mw_flags & MAN_WFLAGS_DONE) {
- status = wp->mw_status;
- man_work_free(wp);
- } else {
- ASSERT(wait_status <= 0);
- wp->mw_flags &= ~MAN_WFLAGS_CVWAITER;
- if (wait_status == 0)
- status = EINTR;
- else {
- MAN_DBG(MAN_KSTAT, ("man_kstat_update: "
- "timedout, returning stale stats."));
- status = 0;
- }
- }
- if (status)
- goto exit;
- }
-
- knp = (kstat_named_t *)ksp->ks_data;
- man_knp = (kstat_named_t *)manp->man_ksp->ks_data;
-
- if (rw == KSTAT_READ) {
- for (i = 0; i < MAN_NUMSTATS; i++) {
- knp[i].value.ui64 = man_knp[i].value.ui64;
- }
- } else {
- for (i = 0; i < MAN_NUMSTATS; i++) {
- man_knp[i].value.ui64 = knp[i].value.ui64;
- }
- }
-
-exit:
- manp->man_refcnt--;
- mutex_exit(&man_lock);
-
- MAN_DBG(MAN_KSTAT, ("man_kstat_update: returns %d", status));
-
- return (status);
-}
-
-/*
- * Sum destination kstats for all active paths for a given instance of the
- * MAN driver. Called with perimeter lock.
- */
-static void
-man_do_kstats(man_work_t *wp)
-{
- man_t *manp;
- man_pg_t *mpg;
- man_path_t *mp;
-
- MAN_DBG(MAN_KSTAT, ("man_do_kstats:"));
-
- mutex_enter(&man_lock);
- /*
- * Sync mp_last_knp for each path associated with the MAN instance.
- */
- manp = (man_t *)ddi_get_soft_state(man_softstate,
- wp->mw_arg.a_man_ppa);
- for (mpg = manp->man_pg; mpg != NULL; mpg = mpg->mpg_next) {
-
- ASSERT(mpg->mpg_man_ppa == manp->man_meta_ppa);
-
- if ((mp = man_find_active_path(mpg->mpg_pathp)) != NULL) {
-
- MAN_DBG(MAN_KSTAT, ("\tkstat: path"));
- MAN_DBGCALL(MAN_KSTAT, man_print_path(mp));
-
- /*
- * We just to update the destination statistics here.
- */
- man_sum_dests_kstats(mp->mp_last_knp, mpg);
- }
- }
- mutex_exit(&man_lock);
- MAN_DBG(MAN_KSTAT, ("man_do_kstats: returns"));
-}
-
-/*
- * Sum device kstats for all active paths for a given instance of the
- * MAN driver. Called with man_lock.
- */
-static void
-man_update_path_kstats(man_t *manp)
-{
- kstat_named_t *man_knp;
- man_pg_t *mpg;
- man_path_t *mp;
-
- ASSERT(MUTEX_HELD(&man_lock));
- MAN_DBG(MAN_KSTAT, ("man_update_path_kstats:"));
-
- man_knp = (kstat_named_t *)manp->man_ksp->ks_data;
-
- for (mpg = manp->man_pg; mpg != NULL; mpg = mpg->mpg_next) {
-
- ASSERT(mpg->mpg_man_ppa == manp->man_meta_ppa);
-
- if ((mp = man_find_active_path(mpg->mpg_pathp)) != NULL) {
-
- man_update_dev_kstats(man_knp, mp);
-
- }
- }
- MAN_DBG(MAN_KSTAT, ("man_update_path_kstats: returns"));
-}
-
-/*
- * Update the device kstats.
- * As man_kstat_update() is called with kstat_chain_lock held,
- * we can safely update the statistics from the underlying driver here.
- */
-static void
-man_update_dev_kstats(kstat_named_t *man_knp, man_path_t *mp)
-{
- kstat_t *dev_ksp;
- major_t major;
- int instance;
- char buf[KSTAT_STRLEN];
-
-
- major = mp->mp_device.mdev_major;
- instance = mp->mp_device.mdev_ppa;
- (void) sprintf(buf, "%s%d", ddi_major_to_name(major), instance);
-
- dev_ksp = kstat_hold_byname(ddi_major_to_name(major), instance, buf,
- ALL_ZONES);
- if (dev_ksp != NULL) {
-
- KSTAT_ENTER(dev_ksp);
- KSTAT_UPDATE(dev_ksp, KSTAT_READ);
- man_sum_kstats(man_knp, dev_ksp, mp->mp_last_knp);
- KSTAT_EXIT(dev_ksp);
- kstat_rele(dev_ksp);
-
- } else {
- MAN_DBG(MAN_KSTAT,
- ("man_update_dev_kstats: no kstat data found for %s(%d,%d)",
- buf, major, instance));
- }
-}
-
-static void
-man_sum_dests_kstats(kstat_named_t *knp, man_pg_t *mpg)
-{
- int i;
- int flags;
- char *statname;
- manstr_t *msp;
- man_dest_t *mdp;
- uint64_t switches = 0;
- uint64_t linkfails = 0;
- uint64_t linkstales = 0;
- uint64_t icmpv4probes = 0;
- uint64_t icmpv6probes = 0;
-
- MAN_DBG(MAN_KSTAT, ("man_sum_dests_kstats: mpg 0x%p", (void *)mpg));
-
- for (msp = man_strup; msp != NULL; msp = msp->ms_next) {
-
- if (!man_str_uses_pg(msp, mpg))
- continue;
-
- mdp = &msp->ms_dests[mpg->mpg_pg_id];
-
- switches += mdp->md_switches;
- linkfails += mdp->md_linkfails;
- linkstales += mdp->md_linkstales;
- icmpv4probes += mdp->md_icmpv4probes;
- icmpv6probes += mdp->md_icmpv6probes;
- }
-
- for (i = 0; i < MAN_NUMSTATS; i++) {
-
- statname = man_kstat_info[i].mk_name;
- flags = man_kstat_info[i].mk_flags;
-
- if (!(flags & MK_NOT_PHYSICAL))
- continue;
-
- if (strcmp(statname, "man_switches") == 0) {
- knp[i].value.ui64 = switches;
- } else if (strcmp(statname, "man_link_fails") == 0) {
- knp[i].value.ui64 = linkfails;
- } else if (strcmp(statname, "man_link_stales") == 0) {
- knp[i].value.ui64 = linkstales;
- } else if (strcmp(statname, "man_icmpv4_probes") == 0) {
- knp[i].value.ui64 = icmpv4probes;
- } else if (strcmp(statname, "man_icmpv6_probes") == 0) {
- knp[i].value.ui64 = icmpv6probes;
- }
- }
-
- MAN_DBG(MAN_KSTAT, ("man_sum_dests_kstats: returns"));
-}
-
-/*
- * Initialize MAN named kstats in the space provided.
- */
-static void
-man_kstat_named_init(kstat_named_t *knp, int num_stats)
-{
- int i;
-
- MAN_DBG(MAN_KSTAT, ("man_kstat_named_init: knp(0x%p) num_stats = %d",
- (void *)knp, num_stats));
-
- for (i = 0; i < num_stats; i++) {
- kstat_named_init(&knp[i], man_kstat_info[i].mk_name,
- man_kstat_info[i].mk_type);
- }
-
- MAN_DBG(MAN_KSTAT, ("man_kstat_named_init: returns"));
-
-}
-
-/*
- * man_kstat_byname - get a kernel stat value from its structure
- *
- * ksp - kstat_t structure to play with
- * s - string to match names with
- * res - in/out result data pointer
- *
- * returns - success - 1 (found)
- * - failure - 0 (not found)
- */
-static int
-man_kstat_byname(kstat_t *ksp, char *s, kstat_named_t *res)
-{
- int found = 0;
-
- MAN_DBG(MAN_KSTAT2, ("man_kstat_byname: GETTING %s\n", s));
-
- if (ksp->ks_type == KSTAT_TYPE_NAMED) {
- kstat_named_t *knp;
-
- for (knp = KSTAT_NAMED_PTR(ksp);
- (caddr_t)knp < ((caddr_t)ksp->ks_data+ksp->ks_data_size);
- knp++) {
-
- if (strcmp(s, knp->name) == NULL) {
-
- res->data_type = knp->data_type;
- res->value = knp->value;
- found++;
-
- MAN_DBG(MAN_KSTAT2, ("\t%s: %d\n", knp->name,
- (int)knp->value.ul));
- }
- }
- } else {
- MAN_DBG(MAN_KSTAT2, ("\tbad kstats type %d\n", ksp->ks_type));
- }
-
- /*
- * if getting a value but couldn't find the namestring, result = 0.
- */
- if (!found) {
- /*
- * a reasonable default
- */
- res->data_type = KSTAT_DATA_ULONG;
- res->value.l = 0;
- MAN_DBG(MAN_KSTAT2, ("\tcouldn't find, using defaults\n"));
- }
-
- MAN_DBG(MAN_KSTAT2, ("man_kstat_byname: returns\n"));
-
- return (found);
-}
-
-
-/*
- *
- * Accumulate MAN driver kstats from the incremental values of the underlying
- * physical interfaces.
- *
- * Parameters:
- * sum_knp - The named kstat area to put cumulative value,
- * NULL if we just want to sync next two params.
- * phys_ksp - Physical interface kstat_t pointer. Contains
- * more current counts.
- * phys_last_knp - counts from the last time we were called for this
- * physical interface. Note that the name kstats
- * pointed to are actually in MAN format, but they
- * hold the mirrored physical devices last read
- * kstats.
- * Basic algorithm is:
- *
- * for each named kstat variable {
- * sum_knp[i] += (phys_ksp->ksp_data[i] - phys_last_knp[i]);
- * phys_last_knp[i] = phys_ksp->ksp_data[i];
- * }
- *
- */
-static void
-man_sum_kstats(kstat_named_t *sum_knp, kstat_t *phys_ksp,
- kstat_named_t *phys_last_knp)
-{
- char *physname;
- char *physalias;
- char *statname;
- kstat_named_t phys_kn_entry;
- uint64_t delta64;
- int i;
-
- MAN_DBG(MAN_KSTAT, ("man_sum_kstats: sum_knp(0x%p) phys_ksp(0x%p)"
- " phys_last_knp(0x%p)\n", (void *)sum_knp, (void *)phys_ksp,
- (void *)phys_last_knp));
-
- /*
- * Now for each entry in man_kstat_info, sum the named kstat.
- * Not that all MAN specific kstats will end up !found.
- */
- for (i = 0; i < MAN_NUMSTATS; i++) {
- int found = 0;
- int flags = 0;
-
- delta64 = 0;
-
- statname = man_kstat_info[i].mk_name;
- physname = man_kstat_info[i].mk_physname;
- physalias = man_kstat_info[i].mk_physalias;
- flags = man_kstat_info[i].mk_flags;
-
- /*
- * Update MAN private kstats.
- */
- if (flags & MK_NOT_PHYSICAL) {
-
- kstat_named_t *knp = phys_last_knp;
-
- if (sum_knp == NULL)
- continue;
-
- if (strcmp(statname, "man_switches") == 0) {
- sum_knp[i].value.ui64 = knp[i].value.ui64;
- } else if (strcmp(statname, "man_link_fails") == 0) {
- sum_knp[i].value.ui64 = knp[i].value.ui64;
- } else if (strcmp(statname, "man_link_stales") == 0) {
- sum_knp[i].value.ui64 = knp[i].value.ui64;
- } else if (strcmp(statname, "man_icmpv4_probes") == 0) {
- sum_knp[i].value.ui64 = knp[i].value.ui64;
- } else if (strcmp(statname, "man_icmpv6_probes") == 0) {
- sum_knp[i].value.ui64 = knp[i].value.ui64;
- }
-
- continue; /* phys_ksp doesnt have this stat */
- }
-
- /*
- * first try it by the "official" name
- */
- if (phys_ksp) {
- if (man_kstat_byname(phys_ksp, physname,
- &phys_kn_entry)) {
-
- found = 1;
-
- } else if ((physalias) && (man_kstat_byname(phys_ksp,
- physalias, &phys_kn_entry))) {
-
- found = 1;
- }
- }
-
- if (!found) {
- /*
- * clear up the "last" value, no change to the sum
- */
- phys_last_knp[i].value.ui64 = 0;
- continue;
- }
-
- /*
- * at this point, we should have the good underlying
- * kstat value stored in phys_kn_entry
- */
- if (flags & MK_NOT_COUNTER) {
- /*
- * it isn't a counter, so store the value and
- * move on (e.g. ifspeed)
- */
- phys_last_knp[i].value = phys_kn_entry.value;
- continue;
- }
-
- switch (phys_kn_entry.data_type) {
- case KSTAT_DATA_UINT32:
-
- /*
- * this handles 32-bit wrapping
- */
- if (phys_kn_entry.value.ui32 <
- phys_last_knp[i].value.ui32) {
-
- /*
- * we've wrapped!
- */
- delta64 += (UINT_MAX -
- phys_last_knp[i].value.ui32);
- phys_last_knp[i].value.ui32 = 0;
- }
-
- delta64 += phys_kn_entry.value.ui32 -
- phys_last_knp[i].value.ui32;
- phys_last_knp[i].value.ui32 = phys_kn_entry.value.ui32;
- break;
-
- default:
- /*
- * must be a 64-bit value, we ignore 64-bit
- * wraps, since they shouldn't ever happen
- * within the life of a machine (if we assume
- * machines don't stay up for more than a few
- * hundred years without a reboot...)
- */
- delta64 = phys_kn_entry.value.ui64 -
- phys_last_knp[i].value.ui64;
- phys_last_knp[i].value.ui64 = phys_kn_entry.value.ui64;
- }
-
- if (sum_knp != NULL) {
- /*
- * now we need to save the value
- */
- switch (sum_knp[i].data_type) {
- case KSTAT_DATA_UINT32:
- /* trunk down to 32 bits, possibly lossy */
- sum_knp[i].value.ui32 += (uint32_t)delta64;
- break;
-
- default:
- sum_knp[i].value.ui64 += delta64;
- break;
- }
- }
- }
-
- MAN_DBG(MAN_KSTAT, ("man_sum_kstats: returns\n"));
-}
-
-
-#if defined(DEBUG)
-
-
-static char *_ms_flags[] = {
- "NONE",
- "FAST", /* 0x1 */
- "RAW", /* 0x2 */
- "ALLPHYS", /* 0x4 */
- "ALLMULTI", /* 0x8 */
- "ALLSAP", /* 0x10 */
- "CKSUM", /* 0x20 */
- "MULTI", /* 0x40 */
- "SERLPBK", /* 0x80 */
- "MACLPBK", /* 0x100 */
- "CLOSING", /* 0x200 */
- "CLOSE_DONE", /* 0x400 */
- "CONTROL" /* 0x800 */
-};
-
-static void
-man_print_msp(manstr_t *msp)
-{
- char buf[512];
- char prbuf[512];
- uint_t flags;
- int i;
-
- cmn_err(CE_CONT, "\tmsp(0x%p)\n", (void *)msp);
-
- if (msp == NULL)
- return;
-
- cmn_err(CE_CONT, "\t%s%d SAP(0x%x):\n",
- ddi_major_to_name(msp->ms_meta_maj), msp->ms_meta_ppa,
- msp->ms_sap);
-
- buf[0] = '\0';
- prbuf[0] = '\0';
- flags = msp->ms_flags;
- for (i = 0; i < A_CNT(_ms_flags); i++) {
- if ((flags >> i) & 0x1) {
- (void) sprintf(buf, " %s |", _ms_flags[i+1]);
- (void) strcat(prbuf, buf);
- }
- }
- prbuf[strlen(prbuf) - 1] = '\0';
- cmn_err(CE_CONT, "\tms_flags: %s\n", prbuf);
-
- cmn_err(CE_CONT, "\tms_dlpistate: %s\n", dss[msp->ms_dlpistate]);
-
- cmn_err(CE_CONT, "\tms_dl_mp: 0x%p\n", (void *)msp->ms_dl_mp);
-
- cmn_err(CE_CONT, "\tms_manp: 0x%p\n", (void *)msp->ms_manp);
-
- cmn_err(CE_CONT, "\tms_dests: 0x%p\n", (void *)msp->ms_dests);
-
-}
-
-static char *_md_state[] = {
- "NOTPRESENT", /* 0x0 */
- "INITIALIZING", /* 0x1 */
- "READY", /* 0x2 */
- "PLUMBING", /* 0x4 */
- "CLOSING" /* 0x8 */
-};
-
-static void
-man_print_mdp(man_dest_t *mdp)
-{
- uint_t state;
- int i;
- char buf[64];
- char prbuf[512];
-
- buf[0] = '\0';
- prbuf[0] = '\0';
-
- cmn_err(CE_CONT, "\tmdp(0x%p)\n", (void *)mdp);
-
- if (mdp == NULL)
- return;
-
- cmn_err(CE_CONT, "\tmd_pg_id: %d\n", mdp->md_pg_id);
- cmn_err(CE_CONT, "\tmd_dst_eaddr: %s\n",
- ether_sprintf(&mdp->md_dst_eaddr));
- cmn_err(CE_CONT, "\tmd_src_eaddr: %s\n",
- ether_sprintf(&mdp->md_src_eaddr));
- cmn_err(CE_CONT, "\tmd_dlpistate: %s", dss[mdp->md_dlpistate]);
- cmn_err(CE_CONT, "\tmd_muxid: 0x%u", mdp->md_muxid);
- cmn_err(CE_CONT, "\tmd_rcvcnt %lu md_lastrcvcnt %lu", mdp->md_rcvcnt,
- mdp->md_lastrcvcnt);
-
- /*
- * Print out state as text.
- */
- state = mdp->md_state;
-
- if (state == 0) {
- (void) strcat(prbuf, _md_state[0]);
- } else {
-
- for (i = 0; i < A_CNT(_md_state); i++) {
- if ((state >> i) & 0x1) {
- (void) sprintf(buf, " %s |", _md_state[i+1]);
- (void) strcat(prbuf, buf);
- }
- }
- prbuf[strlen(prbuf) -1] = '\0';
- }
- cmn_err(CE_CONT, "\tmd_state: %s", prbuf);
-
- cmn_err(CE_CONT, "\tmd_device:\n");
- man_print_dev(&mdp->md_device);
-
-}
-
-static void
-man_print_man(man_t *manp)
-{
- char buf[512];
- char prbuf[512];
-
- buf[0] = '\0';
- prbuf[0] = '\0';
-
- if (manp == NULL)
- return;
-
- if (ddi_major_to_name(manp->man_meta_major)) {
- (void) sprintf(buf, "\t man_device: %s%d\n",
- ddi_major_to_name(manp->man_meta_major),
- manp->man_meta_ppa);
- } else {
- (void) sprintf(buf, "\t major: %d", manp->man_meta_major);
- (void) sprintf(buf, "\t ppa: %d", manp->man_meta_ppa);
- }
-
- cmn_err(CE_CONT, "%s", buf);
-
-}
-
-static char *_mdev_state[] = {
- "UNASSIGNED ",
- "ASSIGNED",
- "ACTIVE",
- "FAILED"
-};
-
-static void
-man_print_dev(man_dev_t *mdevp)
-{
- char buf[512];
- char prbuf[512];
- int i;
- uint_t state;
-
- buf[0] = '\0';
- prbuf[0] = '\0';
-
- if (mdevp == NULL)
- return;
-
- if (mdevp->mdev_major == 0) {
-number:
- (void) sprintf(buf, "\t mdev_major: %d\n", mdevp->mdev_major);
- } else if (ddi_major_to_name(mdevp->mdev_major)) {
- (void) sprintf(buf, "\t mdev_device: %s%d\n",
- ddi_major_to_name(mdevp->mdev_major),
- mdevp->mdev_ppa);
- } else
- goto number;
-
- cmn_err(CE_CONT, "%s", buf);
-
- cmn_err(CE_CONT, "\t mdev_exp_id: %d\n", mdevp->mdev_exp_id);
-
- buf[0] = '\0';
- prbuf[0] = '\0';
- state = mdevp->mdev_state;
-
- if (state == 0) {
- (void) strcat(prbuf, _mdev_state[0]);
- } else {
- for (i = 0; i < A_CNT(_mdev_state); i++) {
- if ((state >> i) & 0x1) {
- (void) sprintf(buf, " %s |", _mdev_state[i+1]);
- (void) strcat(prbuf, buf);
- }
- }
- }
-
- prbuf[strlen(prbuf) - 2] = '\0';
-
- cmn_err(CE_CONT, "\t mdev_state: %s\n", prbuf);
-
-}
-
-static char *_mip_cmd[] = {
- "MI_PATH_READ",
- "MI_PATH_ASSIGN",
- "MI_PATH_ACTIVATE",
- "MI_PATH_DEACTIVATE",
- "MI_PATH_UNASSIGN"
-};
-
-static void
-man_print_mtp(mi_time_t *mtp)
-{
- cmn_err(CE_CONT, "\tmtp(0x%p)\n", (void *)mtp);
-
- if (mtp == NULL)
- return;
-
- cmn_err(CE_CONT, "\tmtp_instance: %d\n", mtp->mtp_man_ppa);
-
- cmn_err(CE_CONT, "\tmtp_time: %d\n", mtp->mtp_time);
-
-}
-
-static void
-man_print_mip(mi_path_t *mip)
-{
- cmn_err(CE_CONT, "\tmip(0x%p)\n", (void *)mip);
-
- if (mip == NULL)
- return;
-
- cmn_err(CE_CONT, "\tmip_pg_id: %d\n", mip->mip_pg_id);
-
- cmn_err(CE_CONT, "\tmip_cmd: %s\n", _mip_cmd[mip->mip_cmd]);
-
- cmn_err(CE_CONT, "\tmip_eaddr: %s\n", ether_sprintf(&mip->mip_eaddr));
-
- cmn_err(CE_CONT, "\tmip_devs: 0x%p\n", (void *)mip->mip_devs);
-
- cmn_err(CE_CONT, "\tmip_ndevs: %d\n", mip->mip_ndevs);
-
-}
-
-static void
-man_print_mpg(man_pg_t *mpg)
-{
- cmn_err(CE_CONT, "\tmpg(0x%p)\n", (void *)mpg);
-
- if (mpg == NULL)
- return;
-
- cmn_err(CE_CONT, "\tmpg_next: 0x%p\n", (void *)mpg->mpg_next);
-
- cmn_err(CE_CONT, "\tmpg_pg_id: %d\n", mpg->mpg_pg_id);
-
- cmn_err(CE_CONT, "\tmpg_man_ppa: %d\n", mpg->mpg_man_ppa);
-
- cmn_err(CE_CONT, "\tmpg_dst_eaddr: %s\n",
- ether_sprintf(&mpg->mpg_dst_eaddr));
-
- cmn_err(CE_CONT, "\tmpg_pathp: 0x%p\n", (void *)mpg->mpg_pathp);
-
-}
-
-static char *_mw_flags[] = {
- "NOWAITER", /* 0x0 */
- "CVWAITER", /* 0x1 */
- "QWAITER", /* 0x2 */
- "DONE" /* 0x3 */
-};
-
-static void
-man_print_work(man_work_t *wp)
-{
- int i;
-
- cmn_err(CE_CONT, "\twp(0x%p)\n\n", (void *)wp);
-
- if (wp == NULL)
- return;
-
- cmn_err(CE_CONT, "\tmw_type: %s\n", _mw_type[wp->mw_type]);
-
- cmn_err(CE_CONT, "\tmw_flags: ");
- for (i = 0; i < A_CNT(_mw_flags); i++) {
- if ((wp->mw_flags >> i) & 0x1)
- cmn_err(CE_CONT, "%s", _mw_flags[i]);
- }
- cmn_err(CE_CONT, "\n");
-
- cmn_err(CE_CONT, "\twp_status: %d\n", wp->mw_status);
-
- cmn_err(CE_CONT, "\twp_arg: 0x%p\n", (void *)&wp->mw_arg);
-
- cmn_err(CE_CONT, "\tmw_next: 0x%p\n", (void *)wp->mw_next);
-
- cmn_err(CE_CONT, "\twp_q: 0x%p", (void *)wp->mw_q);
-
-}
-
-static void
-man_print_path(man_path_t *mp)
-{
- cmn_err(CE_CONT, "\tmp(0x%p)\n\n", (void *)mp);
-
- if (mp == NULL)
- return;
-
- cmn_err(CE_CONT, "\tmp_device:");
- man_print_dev(&mp->mp_device);
-
- cmn_err(CE_CONT, "\tmp_next: 0x%p\n", (void *)mp->mp_next);
-
- cmn_err(CE_CONT, "\tmp_last_knp: 0x%p\n", (void *)mp->mp_last_knp);
-
- cmn_err(CE_CONT, "\tmp_lru: 0x%lx", mp->mp_lru);
-
-}
-
-void *
-man_dbg_kzalloc(int line, size_t size, int kmflags)
-{
- void *tmp;
-
- tmp = kmem_zalloc(size, kmflags);
- MAN_DBG(MAN_KMEM, ("0x%p %lu\tzalloc'd @ %d\n", (void *)tmp,
- size, line));
-
- return (tmp);
-
-}
-
-void
-man_dbg_kfree(int line, void *buf, size_t size)
-{
-
- MAN_DBG(MAN_KMEM, ("0x%p %lu\tfree'd @ %d\n", (void *)buf, size, line));
-
- kmem_free(buf, size);
-
-}
-
-#endif /* DEBUG */
diff --git a/usr/src/uts/sun4u/starcat/io/dman.conf b/usr/src/uts/sun4u/starcat/io/dman.conf
deleted file mode 100644
index 45738cfc8a..0000000000
--- a/usr/src/uts/sun4u/starcat/io/dman.conf
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2000 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-name="dman" parent="pseudo" instance=0;
diff --git a/usr/src/uts/sun4u/starcat/io/dman_domain.c b/usr/src/uts/sun4u/starcat/io/dman_domain.c
deleted file mode 100644
index 36ed6c4049..0000000000
--- a/usr/src/uts/sun4u/starcat/io/dman_domain.c
+++ /dev/null
@@ -1,870 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Domain specific portion of the Starcat Management Network Driver
- */
-
-#include <sys/types.h>
-#include <sys/proc.h>
-#include <sys/kmem.h>
-#include <sys/stat.h>
-#include <sys/kstat.h>
-#include <sys/ksynch.h>
-#include <sys/stream.h>
-#include <sys/dlpi.h>
-#include <sys/stropts.h>
-#include <sys/strsubr.h>
-#include <sys/debug.h>
-#include <sys/conf.h>
-#include <sys/kstr.h>
-#include <sys/errno.h>
-#include <sys/ethernet.h>
-#include <sys/byteorder.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/modctl.h>
-#include <sys/strsun.h>
-#include <sys/pci.h>
-#include <sys/callb.h>
-#include <sys/pci.h>
-#include <sys/iosramio.h>
-#include <sys/mboxsc.h>
-#include <netinet/in.h>
-#include <inet/common.h>
-#include <inet/mi.h>
-#include <inet/nd.h>
-#include <sys/socket.h>
-#include <netinet/igmp_var.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <inet/ip.h>
-#include <inet/ip6.h>
-#include <sys/dman.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/sunndi.h>
-
-#define MAN_SCHIZO_BINDING_NAME "pci108e,8001"
-#define MAN_XMITS_BINDING_NAME "pci108e,8002"
-
-int man_is_on_domain = TRUE;
-
-/*
- * Domain side function prototypes.
- */
-int man_get_iosram(manc_t *);
-int man_domain_configure(void);
-int man_domain_deconfigure(void);
-int man_path_discovery(void);
-int man_dossc_switch(uint32_t);
-int man_dr_attach(dev_info_t *);
-int man_dr_detach(dev_info_t *);
-static int man_dr_submit_work_wait(dev_info_t *, int);
-static int man_find_devs(mi_path_t *, uchar_t);
-static int man_dip_is_schizoxmits0_pcib(dev_info_t *, int *, int *);
-static int man_dip_is_eri(dev_info_t *, man_dev_t *);
-static int man_dip_is_attached(dev_info_t *);
-static int man_get_eri_dev_info(dev_info_t *, man_dev_t *);
-static int man_mbox_initialized = FALSE;
-
-/*
- * Externs
- */
-extern int man_pg_cmd(mi_path_t *, man_work_t *);
-extern kmutex_t man_lock;
-extern void *man_softstate;
-extern man_work_t *man_work_alloc(int, int);
-extern void man_work_free(man_work_t *);
-extern void man_work_add(man_workq_t *, man_work_t *);
-extern man_workq_t *man_bwork_q;
-extern man_workq_t *man_iwork_q;
-extern queue_t *man_ctl_wq;
-
-#if defined(DEBUG)
-static void man_print_manc(manc_t *);
-extern uint32_t man_debug;
-#endif /* DEBUG */
-
-int
-man_domain_configure(void)
-{
- int status = 0;
-
- /*
- * man_mbox_initialized is protected by inner perimiter lock.
- */
- if (man_mbox_initialized == TRUE)
- goto exit;
-
- status = mboxsc_init(IOSRAM_KEY_SCMD, MBOXSC_MBOX_IN, NULL);
-
- if (status != 0) {
- cmn_err(CE_WARN, "man_domain_configure: failed to initialize"
- " MBOXSC_MBOX_IN, errno = %d", status);
- goto exit;
- }
-
- status = mboxsc_init(IOSRAM_KEY_MDSC, MBOXSC_MBOX_OUT, NULL);
- if (status != 0) {
- (void) mboxsc_fini(IOSRAM_KEY_SCMD);
- cmn_err(CE_WARN, "man_domain_configure: failed to initialize"
- " MBOXSC_MBOX_OUT, errno = %d", status);
- goto exit;
- }
-
- man_mbox_initialized = TRUE;
-
- status = man_path_discovery();
- if (status != 0) {
- (void) mboxsc_fini(IOSRAM_KEY_SCMD);
- (void) mboxsc_fini(IOSRAM_KEY_MDSC);
- man_mbox_initialized = FALSE;
- }
-
-exit:
- return (status);
-}
-
-/*
- * Build pathgroup connecting a domain to the SSC. Only called on domains
- * at first man_open. On the SSC, pathgroups are built by IOCTL requests
- * from the MAN daemon (see man_ioctl and mand(1M)).
- *
- * Locks held
- * - exclusive innerperim.
- */
-int
-man_path_discovery(void)
-{
- manc_t manc;
- mi_path_t mpath;
- int num_devs;
- int status = 0;
- int i;
-
- MAN_DBG(MAN_CONFIG, ("man_path_discovery:"));
-
- if (status = man_get_iosram(&manc)) {
- goto exit;
- }
-
- /*
- * If manc_ip_type indicates MAN network is not enabled
- * for this domain, then lets just bailout from here as if no
- * devices were found.
- */
- if ((manc.manc_ip_type != AF_INET) &&
- (manc.manc_ip_type != AF_INET6)) {
- goto exit;
- }
-
- MAN_DBGCALL(MAN_CONFIG, man_print_manc(&manc));
-
- /*
- * Extract SC ethernet address from IOSRAM.
- */
- ether_copy(&manc.manc_sc_eaddr, &mpath.mip_eaddr);
-
- mpath.mip_pg_id = 0; /* SC is always pathgroup ID 0 */
- mpath.mip_man_ppa = 0; /* Domain only has one ppa, 0 */
-
- /*
- * Get list of present devices, and update man_paths[] as needed.
- */
- num_devs = man_find_devs(&mpath, MAN_MAX_EXPANDERS);
- if (num_devs <= 0) {
- status = ENODEV;
- goto exit;
- }
-
- mpath.mip_cmd = MI_PATH_ASSIGN;
-
- mutex_enter(&man_lock);
- status = man_pg_cmd(&mpath, NULL);
- if (status) {
- mutex_exit(&man_lock);
- goto exit;
- }
-
- /*
- * Now activate the ethernet on the golden io board.
- */
- for (i = 0; i < num_devs; i++) {
- if (mpath.mip_devs[i].mdev_exp_id == manc.manc_golden_iob)
- mpath.mip_devs[0] = mpath.mip_devs[i];
- }
- mpath.mip_ndevs = 1;
- mpath.mip_cmd = MI_PATH_ACTIVATE;
- status = man_pg_cmd(&mpath, NULL);
- mutex_exit(&man_lock);
-
-exit:
- MAN_DBG(MAN_CONFIG, ("man_path_discovery: returns %d\n", status));
-
- return (status);
-}
-
-int
-man_domain_deconfigure(void)
-{
-
- (void) mboxsc_fini(IOSRAM_KEY_SCMD);
- (void) mboxsc_fini(IOSRAM_KEY_MDSC);
- /*
- * We are about to unload and know that there are no open
- * streams, so this change outside of the perimiter is ok.
- */
- man_mbox_initialized = FALSE;
-
- return (0);
-}
-
-/*
- * Add a work request to the inner perimeter with the new eri device info.
- */
-/* ARGSUSED */
-int
-man_dr_attach(dev_info_t *dip)
-{
- man_t *manp;
- man_work_t *wp;
- int status = 0;
- man_dev_t mdev;
-
-
- mutex_enter(&man_lock);
- manp = ddi_get_soft_state(man_softstate, 0);
- if (manp == NULL || manp->man_pg == NULL) {
- goto exit;
- }
-
- if (man_get_eri_dev_info(dip, &mdev) == FALSE) {
- status = ENODEV;
- goto exit;
- }
- MAN_DBG(MAN_DR, ("man_dr_attach: dip major = %d instance =%d",
- mdev.mdev_major, mdev.mdev_ppa));
- wp = man_work_alloc(MAN_WORK_DRATTACH, KM_NOSLEEP);
- if (wp == NULL) {
- status = ENOMEM;
- goto exit;
- }
-
- wp->mw_arg.a_man_ppa = 0; /* Domain only has one ppa, 0 */
- wp->mw_arg.a_pg_id = 0; /* SC is always pathgroup ID 0 */
- wp->mw_arg.a_sf_dev = mdev;
- wp->mw_flags = MAN_WFLAGS_NOWAITER;
-
- man_work_add(man_iwork_q, wp);
-
- if (man_ctl_wq)
- qenable(man_ctl_wq);
-
-exit:
- mutex_exit(&man_lock);
-
- return (status);
-}
-
-int
-man_dr_detach(dev_info_t *dip)
-{
- man_t *manp;
- int status = 0;
- int retries = 0;
-
-
- mutex_enter(&man_lock);
- manp = ddi_get_soft_state(man_softstate, 0);
- if (manp == NULL || manp->man_pg == NULL) {
- mutex_exit(&man_lock);
- goto exit;
- }
- mutex_exit(&man_lock);
-
- /*
- * Arrange to have the detaching path switched if it is active.
- * We will cv_wait_sig for the switch to complete if it is needed.
- */
-again:
- status = man_dr_submit_work_wait(dip, MAN_WORK_DRSWITCH);
- if (status == EAGAIN && retries < manp->man_dr_retries) {
- /*
- * Delay a bit and retry.
- */
- MAN_DBG(MAN_DR,
- ("man_dr_detach(switch): EAGAIN - retrying..."));
- retries++;
- delay(drv_usectohz(manp->man_dr_delay));
- goto again;
- }
-
- if (status)
- goto exit;
-
- retries = 0;
-
- /*
- * Detaching device no longer in use, remove it from our
- * pathgroup.
- */
- status = man_dr_submit_work_wait(dip, MAN_WORK_DRDETACH);
- if (status == EAGAIN && retries < manp->man_dr_retries) {
- MAN_DBG(MAN_DR,
- ("man_dr_detach(detach): EAGAIN - retrying..."));
- retries++;
- goto again;
- }
-
-exit:
- MAN_DBG(MAN_DR, ("man_dr_detach: returns %d", status));
- return (status);
-}
-
-static int
-man_dr_submit_work_wait(dev_info_t *dip, int work_type)
-{
- man_work_t *wp;
- int status = 0;
-
- wp = man_work_alloc(work_type, KM_NOSLEEP);
- if (wp == NULL) {
- status = ENOMEM;
- goto exit;
- }
-
- wp->mw_arg.a_man_ppa = 0;
- wp->mw_arg.a_pg_id = 0;
- wp->mw_arg.a_sf_dev.mdev_major = ddi_driver_major(dip);
- wp->mw_arg.a_sf_dev.mdev_ppa = ddi_get_instance(dip);
-
- mutex_enter(&man_lock);
- wp->mw_flags = MAN_WFLAGS_CVWAITER;
- man_work_add(man_iwork_q, wp);
-
- /* TBD - change to ASSERT ? */
- if (man_ctl_wq)
- qenable(man_ctl_wq);
-
- while (!(wp->mw_flags & MAN_WFLAGS_DONE)) {
- if (!cv_wait_sig(&wp->mw_cv, &man_lock)) {
- wp->mw_flags &= ~MAN_WFLAGS_CVWAITER;
- status = EINTR;
- break;
- }
- }
-
- /*
- * Note that if cv_wait_sig() returns zero because a signal
- * was received, MAN_WFLAGS_DONE may not be set.
- * This will happen if man_dr_submit_work_wait() reacquires
- * man_lock before man_iwork() can acquire man_lock just before
- * signalling its work is complete.
- * In this case, it is not necessary to call man_work_free()
- * here because it will be called by man_iwork() because
- * MAN_WFLAGS_CVWAITER was cleared.
- * Should man_iwork() obtain man_lock to signal completion,
- * MAN_WFLAGS_DONE will be set which will ensure man_work_free()
- * is called here.
- */
- if (wp->mw_flags & MAN_WFLAGS_DONE) {
- status = wp->mw_status;
- man_work_free(wp);
- }
-
- mutex_exit(&man_lock);
-
-exit:
- return (status);
-}
-
-/*
- * Notify SSC of switch request and wait for response.
- */
-int
-man_dossc_switch(uint32_t exp_id)
-{
- uint64_t req_tid;
- uint32_t req_cmd;
- uint64_t resp_tid;
- uint32_t resp_cmd;
- uint32_t type;
- man_mbox_msg_t req;
- man_mbox_msg_t resp;
- uint32_t length;
- int status = 0;
-
- /*
- * There should be nothing in inbound mailbox.
- */
- resp_tid = resp_cmd = type = 0;
- length = sizeof (man_mbox_msg_t);
- bzero((char *)&resp, sizeof (man_mbox_msg_t));
- while (mboxsc_getmsg(IOSRAM_KEY_SCMD, &type, &resp_cmd, &resp_tid,
- &length, &resp, 0) == 0) {
-
- resp_tid = resp_cmd = type = 0;
- length = sizeof (man_mbox_msg_t);
- bzero((char *)&resp, sizeof (man_mbox_msg_t));
-
- MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: dumping message"));
- MAN_DBG(MAN_IOSRAM, ("\tcommand = 0x%x", resp_cmd));
- }
-
- MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: sending message"));
-
- bzero((char *)&req, sizeof (man_mbox_msg_t));
- req.mb_status = 0;
- req.mb_exp_id = exp_id;
- req_tid = 0;
- req_cmd = MAN_WORK_SWITCH;
-
- status = mboxsc_putmsg(IOSRAM_KEY_MDSC, MBOXSC_MSG_REQUEST,
- req_cmd, &req_tid, sizeof (man_mbox_msg_t), &req,
- MAN_IOSRAM_TIMEOUT);
-
- if (status != 0) {
- cmn_err(CE_WARN, "man_dossc_switch: mboxsc_putmsg failed,"
- " errno = %d", status);
- goto exit;
- }
-
- bzero((char *)&resp, sizeof (man_mbox_msg_t));
-
- resp_tid = type = resp_cmd = 0;
- length = sizeof (man_mbox_msg_t);
- status = mboxsc_getmsg(IOSRAM_KEY_SCMD, &type, &resp_cmd, &resp_tid,
- &length, (void *)&resp, MAN_IOSRAM_TIMEOUT);
- if (status != 0) {
- cmn_err(CE_WARN, "man_dossc_switch: mboxsc_getmsg failed,"
- " errno = %d", status);
- goto exit;
- }
-
- MAN_DBG(MAN_IOSRAM, ("man_dossc_switch: received message"));
-
- if (req_cmd != resp_cmd || req_tid != resp_tid) {
- cmn_err(CE_WARN, "man_dossc_switch: failed,"
- " cmd/transid mismatch (%d, %d)/(%d, %d)",
- req_cmd, resp_cmd, (int)req_tid, (int)resp_tid);
- status = EINVAL;
- goto exit;
- }
-
- status = resp.mb_status;
- if (status != 0) {
- cmn_err(CE_WARN, "man_dossc_switch: failed errno == %d",
- status);
- }
-exit:
- return (status);
-}
-
-
-/*
- * Read IOSRAM info.
- */
-int
-man_get_iosram(manc_t *mcp)
-{
- int status;
-
- if (mcp == NULL)
- return (EINVAL);
-
- status = iosram_rd(IOSRAM_KEY_MANC, 0, sizeof (manc_t), (caddr_t)mcp);
- if (status) {
- cmn_err(CE_WARN, "man_get_iosram: iosram_rd failed"
- " errno = %d\n", status);
- return (status);
- }
-
- MAN_DBG(MAN_PATH, ("man_get_iosram:"));
- MAN_DBGCALL(MAN_PATH, man_print_manc(mcp));
-
- if (mcp->manc_magic != IOSRAM_KEY_MANC) {
- cmn_err(CE_WARN, "man_get_iosram: bad magic - got(0x%x)"
- " expected(0x%x)\n", mcp->manc_magic, IOSRAM_KEY_MANC);
- status = EIO;
- } else if (mcp->manc_version != MANC_VERSION) {
- cmn_err(CE_WARN, "man_get_iosram: version mismatch -"
- " got(0x%x) expected(0x%x)\n", mcp->manc_version,
- MANC_VERSION);
- status = EIO;
- }
-
- return (status);
-}
-
-#if defined(MAN_NO_IOSRAM)
-
-static manc_t manc = {
- IOSRAM_KEY_MANC,
- MANC_VERSION,
- 0,
- AF_INET,
-/* 0x10010102, Two */
- 0x10010103, /* Scot */
- 0xFF000000, /* Scot netmask */
- 0x10010101, /* SC 10.1.1.1 */
- {0}, /* AF_INET6 addrs */
- {0}, /* AF_INET6 addrs */
- {0},
-/* {0x8, 0x0, 0x20, 0x21, 0x44, 0x83}, Domain eaddr "two" */
- {0x8, 0x0, 0x20, 0x8f, 0x84, 0x63}, /* Domain eaddr "scot" */
- {0x8, 0x0, 0x20, 0x1f, 0xe3, 0x46}, /* SC eaddr "one" */
- 0x1,
- 0x1
-};
-
-
-/*
- * Get IOSRAM info or release it.
- */
-int
-man_get_iosram(manc_t *mcp)
-{
- int status = 0;
-
- if (mcp == NULL)
- return (EINVAL);
-
- *mcp = manc;
-
- if (mcp->manc_magic != IOSRAM_KEY_MANC) {
- cmn_err(CE_WARN, "man_get_iosram: bad magic - got(0x%x)"
- " expected(0x%x)\n", mcp->manc_magic, IOSRAM_KEY_MANC);
- status = EIO;
- } else if (mcp->manc_version != MANC_VERSION) {
- cmn_err(CE_WARN, "man_get_iosram: version mismatch -"
- " got(0x%x) expected(0x%x)\n", mcp->manc_version,
- MANC_VERSION);
- status = EIO;
- }
-
- return (status);
-}
-#endif /* MAN_NO_IOSRAM */
-
-/*
- * Find all RIOs on the IO boards for the domain. We walk all the children
- * of the root node looking for a PCI devinfo with a safari port ID of
- * 0xDC that has a child with device ID of 3. This is gauranteed to be
- * the network portion of the RIO by virtue of the way Starcats are
- * physically built.
- */
-static int
-man_find_devs(mi_path_t *mipathp, uchar_t golden_iob)
-{
- dev_info_t *bus_dip;
- dev_info_t *eri_dip;
- dev_info_t *rdip, *pdip;
- int exp_id;
- int found = 0;
- int circ;
- int circ2;
- man_dev_t ndev;
- int xmits;
-
- MAN_DBG(MAN_PATH, ("man_find_devs: mdevpp(0x%p) golden_iob(%d)\n",
- (void *)(mipathp), golden_iob));
-
- /*
- * Hold parent busy while walking its child list.
- */
- rdip = ddi_root_node();
- ndi_devi_enter(rdip, &circ);
- bus_dip = ddi_get_child(rdip);
-
- while (bus_dip != NULL) {
- exp_id = -1;
- xmits = 0;
- if (man_dip_is_schizoxmits0_pcib(bus_dip, &exp_id, &xmits)) {
- eri_dip = NULL;
- pdip = bus_dip;
- if (xmits) {
- /*
- * If this is XMITS0 PCI_B leaf, then the
- * pci_pci bridge which is the only child,
- * is the parent to MAN RIO.
- */
- pdip = ddi_get_child(bus_dip);
- if (pdip == NULL) {
- bus_dip = ddi_get_next_sibling(bus_dip);
- continue;
- }
- }
- ndi_devi_enter(pdip, &circ2);
- eri_dip = ddi_get_child(pdip);
- while (eri_dip != NULL) {
- MAN_DBG(MAN_PATH, ("man_find_devs: "
- "eri_dip %s\n",
- ddi_binding_name(eri_dip)));
- if (man_dip_is_eri(eri_dip, &ndev) &&
- man_dip_is_attached(eri_dip)) {
-
- ASSERT(exp_id != -1);
- ndev.mdev_exp_id = exp_id;
- ndev.mdev_state = MDEV_ASSIGNED;
- mipathp->mip_devs[found] = ndev;
- found++;
-
- MAN_DBG(MAN_PATH,
- ("man_find_devs: found eri maj(%d) "
- "ppa(%d) on expander(%d)\n",
- ndev.mdev_major,
- ndev.mdev_ppa, exp_id));
- }
- eri_dip = ddi_get_next_sibling(eri_dip);
- }
- ndi_devi_exit(pdip, circ2);
- }
- bus_dip = ddi_get_next_sibling(bus_dip);
- }
- ndi_devi_exit(rdip, circ);
-
- MAN_DBG(MAN_PATH, ("man_find_devs returns found = %d\n", found));
-
- mipathp->mip_ndevs = found;
- return (found);
-}
-
-/*
- * Verify if the dip passed is an instance of 'eri' and set
- * the device info in mdevp.
- */
-static int
-man_get_eri_dev_info(dev_info_t *dip, man_dev_t *mdevp)
-{
- dev_info_t *parent_dip;
- int exp_id;
- int xmits;
- char *name;
-
- ASSERT(dip != NULL);
- /*
- * Verify if the parent is schizo(xmits)0 and pci B leaf.
- */
- if (((parent_dip = ddi_get_parent(dip)) == NULL) ||
- ((name = ddi_binding_name(parent_dip)) == NULL))
- return (FALSE);
- if (strcmp(name, MAN_SCHIZO_BINDING_NAME) != 0) {
- /*
- * This RIO could be on XMITS, so get the dip to
- * XMITS PCI Leaf.
- */
- if ((parent_dip = ddi_get_parent(parent_dip)) == NULL)
- return (FALSE);
- if (((name = ddi_binding_name(parent_dip)) == NULL) ||
- (strcmp(name, MAN_XMITS_BINDING_NAME) != 0)) {
- return (FALSE);
- }
- }
- if (man_dip_is_schizoxmits0_pcib(parent_dip, &exp_id, &xmits) == FALSE)
- return (FALSE);
-
- /*
- * Make sure it is attached.
- */
- if (man_dip_is_attached(dip) == FALSE) {
- MAN_DBG(MAN_DR, ("man_get_eri_dev_info: "
- "dip 0x%p not attached\n", (void *)dip));
- return (FALSE);
- }
- mdevp->mdev_exp_id = exp_id;
- mdevp->mdev_ppa = ddi_get_instance(dip);
- mdevp->mdev_major = ddi_driver_major(dip);
- mdevp->mdev_state = MDEV_ASSIGNED;
- return (TRUE);
-}
-
-/*
- * MAN RIO is connected to SCHIZO/XMITS 0 and PCI_B Leaf.
- * Incase of XMITS, it is actually connected to a PCI Bridge(21154)
- * which is directly connected to the PCI_B leaf of XMITS0.
- *
- * This function verifies if the given dip is SCHIZO/XMITS 0 and
- * PCI_B Leaf. This is done as follows:
- *
- * - Check the binding name to verify SCHIZO/XMITS.
- * - Verify the Device type to be "pci".
- * - Verify the PortID to be ending with 0x1C
- * - Verify the the CSR base to be 0x70.0000.
- */
-static int
-man_dip_is_schizoxmits0_pcib(dev_info_t *dip, int *exp_id, int *xmits)
-{
- char dtype[MAN_DDI_BUFLEN];
- int portid;
- uint_t pci_csr_base;
- struct pci_phys_spec *regbuf = NULL;
- int length = MAN_DDI_BUFLEN;
- char *name;
-
- ASSERT(dip != NULL);
- *exp_id = -1;
- if ((name = ddi_binding_name(dip)) == NULL)
- return (FALSE);
- if (strcmp(name, MAN_SCHIZO_BINDING_NAME) == 0) {
- MAN_DBG(MAN_PATH, ("man_dip_is_schizoxmits0_pcib: "
- "SCHIZO found 0x%p\n", (void *)dip));
- } else if (strcmp(name, MAN_XMITS_BINDING_NAME) == 0) {
- *xmits = TRUE;
- MAN_DBG(MAN_PATH, ("man_dip_is_schizoxmits0_pcib: "
- "XMITS found 0x%p\n", (void *)dip));
- } else
- return (FALSE);
- if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, MAN_DEVTYPE_PROP,
- (caddr_t)dtype, &length) == DDI_PROP_SUCCESS) {
-
- MAN_DBG(MAN_PATH, ("dtype: %s\n", dtype));
- if (strncmp(dtype, MAN_DEVTYPE_PCI, 3) != 0)
- goto notfound;
-
- /*
- * Get safari ID (DDI port ID).
- */
- if ((portid = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 0,
- MAN_PORTID_PROP, -1)) == -1) {
-
- MAN_DBG(MAN_PATH, ("ddi_getpropp: failed\n"));
- goto notfound;
- }
-
- /*
- * All schizo 0 safari IDs end in 0x1C.
- */
- if ((portid & MAN_SCHIZO_MASK) != MAN_SCHIZO_0_ID)
- goto notfound;
-
- /*
- * All PCI nodes "B" are at configspace 0x70.0000
- */
- if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- MAN_REG_PROP, (caddr_t)&regbuf,
- &length) != DDI_PROP_SUCCESS) {
-
- MAN_DBG(MAN_PATH, ("ddi_getlongprop_buf: failed"));
- goto notfound;
- }
-
- pci_csr_base = regbuf[0].pci_phys_mid & PCI_CONF_ADDR_MASK;
- kmem_free(regbuf, length);
- if (pci_csr_base == MAN_PCI_B_CSR_BASE) {
-
- MAN_DBG(MAN_PATH, ("man_dip_is_schizoxmits0_pcib:"
- " found PCI B at dip(0x%p)\n", (void *)dip));
-
- *exp_id = portid >> 5;
- return (TRUE);
- }
- }
-
-notfound:
- return (FALSE);
-}
-
-static int
-man_dip_is_eri(dev_info_t *dip, man_dev_t *ndevp)
-{
- struct pci_phys_spec *regbuf = NULL;
- int length = 0;
- uint_t pci_device;
- uint_t pci_function;
-
- MAN_DBG(MAN_PATH, ("man_dip_is_eri: dip(0x%p) ndevp(0x%p)\n",
- (void *)dip, (void *)ndevp));
- if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- MAN_REG_PROP, (caddr_t)&regbuf,
- &length) == DDI_PROP_SUCCESS) {
-
- pci_device = PCI_REG_DEV_G(regbuf->pci_phys_hi);
- pci_function = PCI_REG_FUNC_G(regbuf->pci_phys_hi);
- kmem_free(regbuf, length);
-
- /*
- * The network function of the RIO ASIC will always
- * be device 3 and function 1 ("network@3,1").
- */
- if (pci_device == 3 && pci_function == 1) {
- ndevp->mdev_ppa = ddi_get_instance(dip);
- ndevp->mdev_major = ddi_driver_major(dip);
-
- MAN_DBG(MAN_PATH, ("man_dip_is_eri: found eri maj(%d)"
- " ppa(%d)\n", ndevp->mdev_major, ndevp->mdev_ppa));
-
- return (TRUE);
- }
- }
-
- MAN_DBG(MAN_PATH, ("man_dip_is_eri: returns FALSE\n"));
-
- return (FALSE);
-}
-
-static int
-man_dip_is_attached(dev_info_t *dip)
-{
- int state;
-
- state = ddi_get_devstate(dip);
- if (i_ddi_devi_attached(dip) || (state == DDI_DEVSTATE_UP)) {
- /*
- * The instance info is more important for us,
- * so verify.
- */
- if (ddi_get_instance(dip) >= 0) {
- return (TRUE);
- }
- cmn_err(CE_WARN, "man_dip_is_attached: "
- "eri 0x%p instance is not set yet", (void *)dip);
-
- }
- return (FALSE);
-}
-
-#if defined(DEBUG)
-static void
-man_print_manc(manc_t *mcp)
-{
- cmn_err(CE_CONT, "\tmcp(0x%p)\n\n", (void *)mcp);
-
- if (mcp == NULL)
- return;
-
- cmn_err(CE_CONT, "\tmagic: 0x%x\n", mcp->manc_magic);
- cmn_err(CE_CONT, "\tversion: 0x%x\n", mcp->manc_version);
- cmn_err(CE_CONT, "\tcsum: %d\n", mcp->manc_csum);
- cmn_err(CE_CONT, "\tdom_eaddr: %s\n",
- ether_sprintf(&mcp->manc_dom_eaddr));
- cmn_err(CE_CONT, "\tsc_eaddr: %s\n",
- ether_sprintf(&mcp->manc_sc_eaddr));
- cmn_err(CE_CONT, "\tiob_bitmap: 0x%x\n", mcp->manc_iob_bitmap);
- cmn_err(CE_CONT, "\tgolden_iob: %d\n", mcp->manc_golden_iob);
-
-}
-
-#endif /* DEBUG */
diff --git a/usr/src/uts/sun4u/starcat/io/dr.conf b/usr/src/uts/sun4u/starcat/io/dr.conf
deleted file mode 100644
index c083d9b30d..0000000000
--- a/usr/src/uts/sun4u/starcat/io/dr.conf
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright (c) 2000 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-name="dr" parent="pseudo" instance=0;
diff --git a/usr/src/uts/sun4u/starcat/io/drmach.c b/usr/src/uts/sun4u/starcat/io/drmach.c
deleted file mode 100644
index c65c930644..0000000000
--- a/usr/src/uts/sun4u/starcat/io/drmach.c
+++ /dev/null
@@ -1,8878 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- * Copyright (c) 2016 by Delphix. All rights reserved.
- * Copyright 2019 Joyent, Inc.
- */
-
-#include <sys/note.h>
-#include <sys/debug.h>
-#include <sys/types.h>
-#include <sys/varargs.h>
-#include <sys/errno.h>
-#include <sys/cred.h>
-#include <sys/dditypes.h>
-#include <sys/devops.h>
-#include <sys/modctl.h>
-#include <sys/poll.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/sunndi.h>
-#include <sys/ndi_impldefs.h>
-#include <sys/stat.h>
-#include <sys/kmem.h>
-#include <sys/vmem.h>
-#include <sys/disp.h>
-#include <sys/processor.h>
-#include <sys/cheetahregs.h>
-#include <sys/cpuvar.h>
-#include <sys/mem_config.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/systm.h>
-#include <sys/machsystm.h>
-#include <sys/autoconf.h>
-#include <sys/cmn_err.h>
-#include <sys/sysmacros.h>
-#include <sys/x_call.h>
-#include <sys/promif.h>
-#include <sys/prom_plat.h>
-#include <sys/membar.h>
-#include <vm/seg_kmem.h>
-#include <sys/mem_cage.h>
-#include <sys/stack.h>
-#include <sys/archsystm.h>
-#include <vm/hat_sfmmu.h>
-#include <sys/pte.h>
-#include <sys/mmu.h>
-#include <sys/cpu_module.h>
-#include <sys/obpdefs.h>
-#include <sys/mboxsc.h>
-#include <sys/plat_ecc_dimm.h>
-
-#include <sys/hotplug/hpctrl.h> /* XXX should be included by schpc.h */
-#include <sys/schpc.h>
-#include <sys/pci.h>
-
-#include <sys/starcat.h>
-#include <sys/cpu_sgnblk_defs.h>
-#include <sys/drmach.h>
-#include <sys/dr_util.h>
-#include <sys/dr_mbx.h>
-#include <sys/sc_gptwocfg.h>
-#include <sys/iosramreg.h>
-#include <sys/iosramio.h>
-#include <sys/iosramvar.h>
-#include <sys/axq.h>
-#include <sys/post/scat_dcd.h>
-#include <sys/kobj.h>
-#include <sys/taskq.h>
-#include <sys/cmp.h>
-#include <sys/sbd_ioctl.h>
-
-#include <sys/sysevent.h>
-#include <sys/sysevent/dr.h>
-#include <sys/sysevent/eventdefs.h>
-
-#include <sys/pci/pcisch.h>
-#include <sys/pci/pci_regs.h>
-
-#include <sys/ontrap.h>
-
-/* defined in ../ml/drmach.il.cpp */
-extern void bcopy32_il(uint64_t, uint64_t);
-extern void flush_ecache_il(int64_t physaddr, int size, int linesz);
-extern void flush_dcache_il(void);
-extern void flush_icache_il(void);
-extern void flush_pcache_il(void);
-
-/* defined in ../ml/drmach_asm.s */
-extern uint64_t lddmcdecode(uint64_t physaddr);
-extern uint64_t lddsafconfig(void);
-
-/* XXX here until provided by sys/dman.h */
-extern int man_dr_attach(dev_info_t *);
-extern int man_dr_detach(dev_info_t *);
-
-#define DRMACH_BNUM2EXP(bnum) ((bnum) >> 1)
-#define DRMACH_BNUM2SLOT(bnum) ((bnum) & 1)
-#define DRMACH_EXPSLOT2BNUM(exp, slot) (((exp) << 1) + (slot))
-
-#define DRMACH_SLICE_MASK 0x1Full
-#define DRMACH_SLICE_TO_PA(s) (((s) & DRMACH_SLICE_MASK) << 37)
-#define DRMACH_PA_TO_SLICE(a) (((a) >> 37) & DRMACH_SLICE_MASK)
-
-/*
- * DRMACH_MEM_SLICE_SIZE and DRMACH_MEM_USABLE_SLICE_SIZE define the
- * available address space and the usable address space for every slice.
- * There must be a distinction between the available and usable do to a
- * restriction imposed by CDC memory size.
- */
-
-#define DRMACH_MEM_SLICE_SIZE (1ull << 37) /* 128GB */
-#define DRMACH_MEM_USABLE_SLICE_SIZE (1ull << 36) /* 64GB */
-
-#define DRMACH_MC_NBANKS 4
-
-#define DRMACH_MC_ADDR(mp, bank) ((mp)->madr_pa + 16 + 8 * (bank))
-#define DRMACH_MC_ASI_ADDR(mp, bank) (DRMACH_MC_ADDR(mp, bank) & 0xFF)
-
-#define DRMACH_EMU_ACT_STATUS_OFFSET 0x50
-#define DRMACH_EMU_ACT_STATUS_ADDR(mp) \
- ((mp)->madr_pa + DRMACH_EMU_ACT_STATUS_OFFSET)
-
-/*
- * The Cheetah's Safari Configuration Register and the Schizo's
- * Safari Control/Status Register place the LPA base and bound fields in
- * same bit locations with in their register word. This source code takes
- * advantage of this by defining only one set of LPA encoding/decoding macros
- * which are shared by various Cheetah and Schizo drmach routines.
- */
-#define DRMACH_LPA_BASE_MASK (0x3Full << 3)
-#define DRMACH_LPA_BND_MASK (0x3Full << 9)
-
-#define DRMACH_LPA_BASE_TO_PA(scr) (((scr) & DRMACH_LPA_BASE_MASK) << 34)
-#define DRMACH_LPA_BND_TO_PA(scr) (((scr) & DRMACH_LPA_BND_MASK) << 28)
-#define DRMACH_PA_TO_LPA_BASE(pa) (((pa) >> 34) & DRMACH_LPA_BASE_MASK)
-#define DRMACH_PA_TO_LPA_BND(pa) (((pa) >> 28) & DRMACH_LPA_BND_MASK)
-
-#define DRMACH_L1_SET_LPA(b) \
- (((b)->flags & DRMACH_NULL_PROC_LPA) == 0)
-
-#define DRMACH_CPU_SRAM_ADDR 0x7fff0900000ull
-#define DRMACH_CPU_SRAM_SIZE 0x20000ull
-
-/*
- * Name properties for frequently accessed device nodes.
- */
-#define DRMACH_CPU_NAMEPROP "cpu"
-#define DRMACH_CMP_NAMEPROP "cmp"
-#define DRMACH_AXQ_NAMEPROP "address-extender-queue"
-#define DRMACH_PCI_NAMEPROP "pci"
-
-/*
- * Maximum value of processor Safari Timeout Log (TOL) field of
- * Safari Config reg (7 secs).
- */
-#define DRMACH_SAF_TOL_MAX 7 * 1000000
-
-/*
- * drmach_board_t flag definitions
- */
-#define DRMACH_NULL_PROC_LPA 0x1
-
-typedef struct {
- uint32_t reg_addr_hi;
- uint32_t reg_addr_lo;
- uint32_t reg_size_hi;
- uint32_t reg_size_lo;
-} drmach_reg_t;
-
-typedef struct {
- struct drmach_node *node;
- void *data;
-} drmach_node_walk_args_t;
-
-typedef struct drmach_node {
- void *here;
-
- pnode_t (*get_dnode)(struct drmach_node *node);
- int (*walk)(struct drmach_node *node, void *data,
- int (*cb)(drmach_node_walk_args_t *args));
- dev_info_t *(*n_getdip)(struct drmach_node *node);
- int (*n_getproplen)(struct drmach_node *node, char *name,
- int *len);
- int (*n_getprop)(struct drmach_node *node, char *name,
- void *buf, int len);
- int (*get_parent)(struct drmach_node *node,
- struct drmach_node *pnode);
-} drmach_node_t;
-
-typedef struct {
- int min_index;
- int max_index;
- int arr_sz;
- drmachid_t *arr;
-} drmach_array_t;
-
-typedef struct {
- void *isa;
-
- void (*dispose)(drmachid_t);
- sbd_error_t *(*release)(drmachid_t);
- sbd_error_t *(*status)(drmachid_t, drmach_status_t *);
-
- char name[MAXNAMELEN];
-} drmach_common_t;
-
-struct drmach_board;
-typedef struct drmach_board drmach_board_t;
-
-typedef struct {
- drmach_common_t cm;
- const char *type;
- drmach_board_t *bp;
- drmach_node_t *node;
- int portid;
- int unum;
- int busy;
- int powered;
-} drmach_device_t;
-
-typedef struct drmach_cpu {
- drmach_device_t dev;
- uint64_t scr_pa;
- processorid_t cpuid;
- int coreid;
-} drmach_cpu_t;
-
-typedef struct drmach_mem {
- drmach_device_t dev;
- struct drmach_mem *next;
- uint64_t nbytes;
- uint64_t madr_pa;
-} drmach_mem_t;
-
-typedef struct drmach_io {
- drmach_device_t dev;
- uint64_t scsr_pa; /* PA of Schizo Control/Status Register */
-} drmach_io_t;
-
-struct drmach_board {
- drmach_common_t cm;
- int bnum;
- int assigned;
- int powered;
- int connected;
- int empty;
- int cond;
- uint_t cpu_impl;
- uint_t flags;
- drmach_node_t *tree;
- drmach_array_t *devices;
- drmach_mem_t *mem;
- uint64_t stardrb_offset;
- char type[BD_TYPELEN];
-};
-
-typedef struct {
- int flags;
- drmach_device_t *dp;
- sbd_error_t *err;
- dev_info_t *fdip;
-} drmach_config_args_t;
-
-typedef struct {
- drmach_board_t *obj;
- int ndevs;
- void *a;
- sbd_error_t *(*found)(void *a, const char *, int, drmachid_t);
- sbd_error_t *err;
-} drmach_board_cb_data_t;
-
-typedef struct drmach_casmslot {
- int valid;
- int slice;
-} drmach_casmslot_t;
-
-typedef enum {
- DRMACH_CR_OK,
- DRMACH_CR_MC_IDLE_ERR,
- DRMACH_CR_IOPAUSE_ERR,
- DRMACH_CR_ONTRAP_ERR
-} drmach_cr_err_t;
-
-typedef struct {
- void *isa;
- caddr_t data;
- drmach_mem_t *s_mp;
- drmach_mem_t *t_mp;
- struct memlist *c_ml;
- uint64_t s_copybasepa;
- uint64_t t_copybasepa;
- drmach_cr_err_t ecode;
- void *earg;
-} drmach_copy_rename_t;
-
-/*
- * The following global is read as a boolean value, non-zero is true.
- * If zero, DR copy-rename and cpu poweron will not set the processor
- * LPA settings (CBASE, CBND of Safari config register) to correspond
- * to the current memory slice map. LPAs of processors present at boot
- * will remain as programmed by POST. LPAs of processors on boards added
- * by DR will remain NULL, as programmed by POST. This can be used to
- * to override the per-board L1SSFLG_THIS_L1_NULL_PROC_LPA flag set by
- * POST in the LDCD (and copied to the GDCD by SMS).
- *
- * drmach_reprogram_lpa and L1SSFLG_THIS_L1_NULL_PROC_LPA do not apply
- * to Schizo device LPAs. These are always set by DR.
- */
-static int drmach_reprogram_lpa = 1;
-
-/*
- * There is a known HW bug where a Jaguar CPU in Safari port 0 (SBX/P0)
- * can fail to receive an XIR. To workaround this issue until a hardware
- * fix is implemented, we will exclude the selection of these CPUs.
- * Setting this to 0 will allow their selection again.
- */
-static int drmach_iocage_exclude_jaguar_port_zero = 1;
-
-static int drmach_initialized;
-static drmach_array_t *drmach_boards;
-
-static int drmach_cpu_delay = 1000;
-static int drmach_cpu_ntries = 50000;
-
-static uint32_t drmach_slice_table[AXQ_MAX_EXP];
-static kmutex_t drmach_slice_table_lock;
-
-tte_t drmach_cpu_sram_tte[NCPU];
-caddr_t drmach_cpu_sram_va;
-
-/*
- * Setting to non-zero will enable delay before all disconnect ops.
- */
-static int drmach_unclaim_delay_all;
-/*
- * Default delay is slightly greater than the max processor Safari timeout.
- * This delay is intended to ensure the outstanding Safari activity has
- * retired on this board prior to a board disconnect.
- */
-static clock_t drmach_unclaim_usec_delay = DRMACH_SAF_TOL_MAX + 10;
-
-/*
- * By default, DR of non-Panther procs is not allowed into a Panther
- * domain with large page sizes enabled. Setting this to 0 will remove
- * the restriction.
- */
-static int drmach_large_page_restriction = 1;
-
-/*
- * Used to pass updated LPA values to procs.
- * Protocol is to clear the array before use.
- */
-volatile uchar_t *drmach_xt_mb;
-volatile uint64_t drmach_xt_ready;
-static kmutex_t drmach_xt_mb_lock;
-static int drmach_xt_mb_size;
-
-uint64_t drmach_bus_sync_list[18 * 4 * 4 + 1];
-static kmutex_t drmach_bus_sync_lock;
-
-static void drmach_fini(void);
-
-static sbd_error_t *drmach_device_new(drmach_node_t *,
- drmach_board_t *, int, drmachid_t *);
-static sbd_error_t *drmach_cpu_new(drmach_device_t *, drmachid_t *);
-static sbd_error_t *drmach_mem_new(drmach_device_t *, drmachid_t *);
-static sbd_error_t *drmach_pci_new(drmach_device_t *, drmachid_t *);
-static sbd_error_t *drmach_io_new(drmach_device_t *, drmachid_t *);
-
-static sbd_error_t *drmach_board_release(drmachid_t);
-static sbd_error_t *drmach_board_status(drmachid_t, drmach_status_t *);
-
-static void drmach_cpu_dispose(drmachid_t);
-static sbd_error_t *drmach_cpu_release(drmachid_t);
-static sbd_error_t *drmach_cpu_status(drmachid_t, drmach_status_t *);
-
-static void drmach_mem_dispose(drmachid_t);
-static sbd_error_t *drmach_mem_release(drmachid_t);
-static sbd_error_t *drmach_mem_status(drmachid_t, drmach_status_t *);
-
-static dev_info_t *drmach_node_ddi_get_dip(drmach_node_t *np);
-static int drmach_node_ddi_get_prop(drmach_node_t *np,
- char *name, void *buf, int len);
-static int drmach_node_ddi_get_proplen(drmach_node_t *np,
- char *name, int *len);
-
-static dev_info_t *drmach_node_obp_get_dip(drmach_node_t *np);
-static int drmach_node_obp_get_prop(drmach_node_t *np,
- char *name, void *buf, int len);
-static int drmach_node_obp_get_proplen(drmach_node_t *np,
- char *name, int *len);
-
-static sbd_error_t *drmach_mbox_trans(uint8_t msgtype, int bnum,
- caddr_t obufp, int olen,
- caddr_t ibufp, int ilen);
-
-sbd_error_t *drmach_io_post_attach(drmachid_t id);
-sbd_error_t *drmach_io_post_release(drmachid_t id);
-
-static sbd_error_t *drmach_iocage_setup(dr_testboard_req_t *,
- drmach_device_t **dpp, cpu_flag_t *oflags);
-static int drmach_iocage_cpu_return(drmach_device_t *dp,
- cpu_flag_t oflags);
-static sbd_error_t *drmach_iocage_mem_return(dr_testboard_reply_t *tbr);
-void drmach_iocage_mem_scrub(uint64_t nbytes);
-
-static sbd_error_t *drmach_i_status(drmachid_t id, drmach_status_t *stat);
-
-static void drmach_slot1_lpa_set(drmach_board_t *bp);
-
-static void drmach_cpu_read(uint64_t arg1, uint64_t arg2);
-static int drmach_cpu_read_scr(drmach_cpu_t *cp, uint64_t *scr);
-
-static void drmach_bus_sync_list_update(void);
-static void drmach_slice_table_update(drmach_board_t *, int);
-static int drmach_portid2bnum(int);
-
-static void drmach_msg_memslice_init(dr_memslice_t slice_arr[]);
-static void drmach_msg_memregs_init(dr_memregs_t regs_arr[]);
-
-static int drmach_panther_boards(void);
-
-static int drmach_name2type_idx(char *);
-
-#ifdef DEBUG
-
-#define DRMACH_PR if (drmach_debug) printf
-#define DRMACH_MEMLIST_DUMP if (drmach_debug) MEMLIST_DUMP
-int drmach_debug = 0; /* set to non-zero to enable debug messages */
-#else
-
-#define DRMACH_PR _NOTE(CONSTANTCONDITION) if (0) printf
-#define DRMACH_MEMLIST_DUMP _NOTE(CONSTANTCONDITION) if (0) MEMLIST_DUMP
-#endif /* DEBUG */
-
-#define DRMACH_OBJ(id) ((drmach_common_t *)id)
-
-#define DRMACH_IS_BOARD_ID(id) \
- ((id != 0) && \
- (DRMACH_OBJ(id)->isa == (void *)drmach_board_new))
-
-#define DRMACH_IS_CPU_ID(id) \
- ((id != 0) && \
- (DRMACH_OBJ(id)->isa == (void *)drmach_cpu_new))
-
-#define DRMACH_IS_MEM_ID(id) \
- ((id != 0) && \
- (DRMACH_OBJ(id)->isa == (void *)drmach_mem_new))
-
-#define DRMACH_IS_IO_ID(id) \
- ((id != 0) && \
- (DRMACH_OBJ(id)->isa == (void *)drmach_io_new))
-
-#define DRMACH_IS_DEVICE_ID(id) \
- ((id != 0) && \
- (DRMACH_OBJ(id)->isa == (void *)drmach_cpu_new || \
- DRMACH_OBJ(id)->isa == (void *)drmach_mem_new || \
- DRMACH_OBJ(id)->isa == (void *)drmach_io_new))
-
-#define DRMACH_IS_ID(id) \
- ((id != 0) && \
- (DRMACH_OBJ(id)->isa == (void *)drmach_board_new || \
- DRMACH_OBJ(id)->isa == (void *)drmach_cpu_new || \
- DRMACH_OBJ(id)->isa == (void *)drmach_mem_new || \
- DRMACH_OBJ(id)->isa == (void *)drmach_io_new))
-
-#define DRMACH_INTERNAL_ERROR() \
- drerr_new(1, ESTC_INTERNAL, drmach_ie_fmt, __LINE__)
-static char *drmach_ie_fmt = "drmach.c %d";
-
-static struct {
- const char *name;
- const char *type;
- sbd_error_t *(*new)(drmach_device_t *, drmachid_t *);
-} drmach_name2type[] = {
- {"cmp", DRMACH_DEVTYPE_CMP, NULL },
- {"cpu", DRMACH_DEVTYPE_CPU, drmach_cpu_new },
- {"SUNW,UltraSPARC-III", DRMACH_DEVTYPE_CPU, drmach_cpu_new },
- {"SUNW,UltraSPARC-III+", DRMACH_DEVTYPE_CPU, drmach_cpu_new },
- {"memory-controller", DRMACH_DEVTYPE_MEM, drmach_mem_new },
- {"pci", DRMACH_DEVTYPE_PCI, drmach_pci_new },
- {"SUNW,wci", DRMACH_DEVTYPE_WCI, drmach_io_new },
-};
-
-/*
- * drmach autoconfiguration data structures and interfaces
- */
-
-extern struct mod_ops mod_miscops;
-
-static struct modlmisc modlmisc = {
- &mod_miscops,
- "Sun Fire 15000 DR"
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- (void *)&modlmisc,
- NULL
-};
-
-/*
- * drmach_boards_rwlock is used to synchronize read/write
- * access to drmach_boards array between status and board lookup
- * as READERS, and assign, and unassign threads as WRITERS.
- */
-static krwlock_t drmach_boards_rwlock;
-
-static kmutex_t drmach_i_lock;
-static kmutex_t drmach_iocage_lock;
-static kcondvar_t drmach_iocage_cv;
-static int drmach_iocage_is_busy = 0;
-uint64_t drmach_iocage_paddr;
-static caddr_t drmach_iocage_vaddr;
-static int drmach_iocage_size = 0;
-static int drmach_is_cheetah = -1;
-
-int
-_init(void)
-{
- int err;
-
- mutex_init(&drmach_i_lock, NULL, MUTEX_DRIVER, NULL);
- rw_init(&drmach_boards_rwlock, NULL, RW_DEFAULT, NULL);
- drmach_xt_mb_size = NCPU * sizeof (uchar_t);
- drmach_xt_mb = (uchar_t *)vmem_alloc(static_alloc_arena,
- drmach_xt_mb_size, VM_SLEEP);
- bzero((void *)drmach_xt_mb, drmach_xt_mb_size);
- if ((err = mod_install(&modlinkage)) != 0) {
- mutex_destroy(&drmach_i_lock);
- rw_destroy(&drmach_boards_rwlock);
- vmem_free(static_alloc_arena, (void *)drmach_xt_mb,
- drmach_xt_mb_size);
- }
-
- return (err);
-}
-
-int
-_fini(void)
-{
- int err;
-
- if ((err = mod_remove(&modlinkage)) == 0)
- drmach_fini();
-
- return (err);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-/*
- * drmach_node_* routines serve the purpose of separating the
- * rest of the code from the device tree and OBP. This is necessary
- * because of In-Kernel-Probing. Devices probed after stod, are probed
- * by the in-kernel-prober, not OBP. These devices, therefore, do not
- * have dnode ids.
- */
-
-static int
-drmach_node_obp_get_parent(drmach_node_t *np, drmach_node_t *pp)
-{
- pnode_t nodeid;
- static char *fn = "drmach_node_obp_get_parent";
-
- nodeid = np->get_dnode(np);
- if (nodeid == OBP_NONODE) {
- cmn_err(CE_WARN, "%s: invalid dnode", fn);
- return (-1);
- }
-
- bcopy(np, pp, sizeof (drmach_node_t));
-
- pp->here = (void *)(uintptr_t)prom_parentnode(nodeid);
- if (pp->here == OBP_NONODE) {
- cmn_err(CE_WARN, "%s: invalid parent dnode", fn);
- return (-1);
- }
-
- return (0);
-}
-
-static pnode_t
-drmach_node_obp_get_dnode(drmach_node_t *np)
-{
- return ((pnode_t)(uintptr_t)np->here);
-}
-
-typedef struct {
- drmach_node_walk_args_t *nwargs;
- int (*cb)(drmach_node_walk_args_t *args);
- int err;
-} drmach_node_ddi_walk_args_t;
-
-int
-drmach_node_ddi_walk_cb(dev_info_t *dip, void *arg)
-{
- drmach_node_ddi_walk_args_t *nargs;
-
- nargs = (drmach_node_ddi_walk_args_t *)arg;
-
- /*
- * dip doesn't have to be held here as we are called
- * from ddi_walk_devs() which holds the dip.
- */
- nargs->nwargs->node->here = (void *)dip;
-
- nargs->err = nargs->cb(nargs->nwargs);
-
- /*
- * Set "here" to NULL so that unheld dip is not accessible
- * outside ddi_walk_devs()
- */
- nargs->nwargs->node->here = NULL;
-
- if (nargs->err)
- return (DDI_WALK_TERMINATE);
- else
- return (DDI_WALK_CONTINUE);
-}
-
-static int
-drmach_node_ddi_walk(drmach_node_t *np, void *data,
- int (*cb)(drmach_node_walk_args_t *args))
-{
- drmach_node_walk_args_t args;
- drmach_node_ddi_walk_args_t nargs;
-
- /* initialized args structure for callback */
- args.node = np;
- args.data = data;
-
- nargs.nwargs = &args;
- nargs.cb = cb;
- nargs.err = 0;
-
- /*
- * Root node doesn't have to be held in any way.
- */
- ddi_walk_devs(ddi_root_node(), drmach_node_ddi_walk_cb, (void *)&nargs);
-
- return (nargs.err);
-}
-
-static int
-drmach_node_obp_walk(drmach_node_t *np, void *data,
- int (*cb)(drmach_node_walk_args_t *args))
-{
- pnode_t nodeid;
- int rv;
- drmach_node_walk_args_t args;
-
- /* initialized args structure for callback */
- args.node = np;
- args.data = data;
-
- nodeid = prom_childnode(prom_rootnode());
-
- /* save our new position within the tree */
- np->here = (void *)(uintptr_t)nodeid;
-
- rv = 0;
- while (nodeid != OBP_NONODE) {
-
- pnode_t child;
-
- rv = (*cb)(&args);
- if (rv)
- break;
-
- child = prom_childnode(nodeid);
- np->here = (void *)(uintptr_t)child;
-
- while (child != OBP_NONODE) {
- rv = (*cb)(&args);
- if (rv)
- break;
-
- child = prom_nextnode(child);
- np->here = (void *)(uintptr_t)child;
- }
-
- nodeid = prom_nextnode(nodeid);
-
- /* save our new position within the tree */
- np->here = (void *)(uintptr_t)nodeid;
- }
-
- return (rv);
-}
-
-static int
-drmach_node_ddi_get_parent(drmach_node_t *np, drmach_node_t *pp)
-{
- dev_info_t *ndip;
- static char *fn = "drmach_node_ddi_get_parent";
-
- ndip = np->n_getdip(np);
- if (ndip == NULL) {
- cmn_err(CE_WARN, "%s: NULL dip", fn);
- return (-1);
- }
-
- bcopy(np, pp, sizeof (drmach_node_t));
-
- pp->here = (void *)ddi_get_parent(ndip);
- if (pp->here == NULL) {
- cmn_err(CE_WARN, "%s: NULL parent dip", fn);
- return (-1);
- }
-
- return (0);
-}
-
-/*ARGSUSED*/
-static pnode_t
-drmach_node_ddi_get_dnode(drmach_node_t *np)
-{
- return ((pnode_t)NULL);
-}
-
-static drmach_node_t *
-drmach_node_new(void)
-{
- drmach_node_t *np;
-
- np = kmem_zalloc(sizeof (drmach_node_t), KM_SLEEP);
-
- if (drmach_initialized) {
- np->get_dnode = drmach_node_ddi_get_dnode;
- np->walk = drmach_node_ddi_walk;
- np->n_getdip = drmach_node_ddi_get_dip;
- np->n_getproplen = drmach_node_ddi_get_proplen;
- np->n_getprop = drmach_node_ddi_get_prop;
- np->get_parent = drmach_node_ddi_get_parent;
- } else {
- np->get_dnode = drmach_node_obp_get_dnode;
- np->walk = drmach_node_obp_walk;
- np->n_getdip = drmach_node_obp_get_dip;
- np->n_getproplen = drmach_node_obp_get_proplen;
- np->n_getprop = drmach_node_obp_get_prop;
- np->get_parent = drmach_node_obp_get_parent;
- }
-
- return (np);
-}
-
-static void
-drmach_node_dispose(drmach_node_t *np)
-{
- kmem_free(np, sizeof (*np));
-}
-
-/*
- * Check if a CPU node is part of a CMP.
- */
-static int
-drmach_is_cmp_child(dev_info_t *dip)
-{
- dev_info_t *pdip;
-
- if (strcmp(ddi_node_name(dip), DRMACH_CPU_NAMEPROP) != 0) {
- return (0);
- }
-
- pdip = ddi_get_parent(dip);
-
- ASSERT(pdip);
-
- if (strcmp(ddi_node_name(pdip), DRMACH_CMP_NAMEPROP) == 0) {
- return (1);
- }
-
- return (0);
-}
-
-static dev_info_t *
-drmach_node_obp_get_dip(drmach_node_t *np)
-{
- pnode_t nodeid;
- dev_info_t *dip;
-
- nodeid = np->get_dnode(np);
- if (nodeid == OBP_NONODE)
- return (NULL);
-
- dip = e_ddi_nodeid_to_dip(nodeid);
- if (dip) {
- /*
- * The branch rooted at dip will have been previously
- * held, or it will be the child of a CMP. In either
- * case, the hold acquired in e_ddi_nodeid_to_dip()
- * is not needed.
- */
- ddi_release_devi(dip);
- ASSERT(drmach_is_cmp_child(dip) || e_ddi_branch_held(dip));
- }
-
- return (dip);
-}
-
-static dev_info_t *
-drmach_node_ddi_get_dip(drmach_node_t *np)
-{
- return ((dev_info_t *)np->here);
-}
-
-static int
-drmach_node_walk(drmach_node_t *np, void *param,
- int (*cb)(drmach_node_walk_args_t *args))
-{
- return (np->walk(np, param, cb));
-}
-
-static int
-drmach_node_ddi_get_prop(drmach_node_t *np, char *name, void *buf, int len)
-{
- int rv = 0;
- dev_info_t *ndip;
- static char *fn = "drmach_node_ddi_get_prop";
-
- ndip = np->n_getdip(np);
- if (ndip == NULL) {
- cmn_err(CE_WARN, "%s: NULL dip", fn);
- rv = -1;
- } else if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ndip,
- DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, name,
- (caddr_t)buf, &len) != DDI_PROP_SUCCESS) {
- rv = -1;
- }
-
- return (rv);
-}
-
-/* ARGSUSED */
-static int
-drmach_node_obp_get_prop(drmach_node_t *np, char *name, void *buf, int len)
-{
- int rv = 0;
- pnode_t nodeid;
- static char *fn = "drmach_node_obp_get_prop";
-
- nodeid = np->get_dnode(np);
- if (nodeid == OBP_NONODE) {
- cmn_err(CE_WARN, "%s: invalid dnode", fn);
- rv = -1;
- } else if (prom_getproplen(nodeid, (caddr_t)name) < 0) {
- rv = -1;
- } else {
- (void) prom_getprop(nodeid, (caddr_t)name, (caddr_t)buf);
- }
-
- return (rv);
-}
-
-static int
-drmach_node_ddi_get_proplen(drmach_node_t *np, char *name, int *len)
-{
- int rv = 0;
- dev_info_t *ndip;
-
- ndip = np->n_getdip(np);
- if (ndip == NULL) {
- rv = -1;
- } else if (ddi_getproplen(DDI_DEV_T_ANY, ndip, DDI_PROP_DONTPASS,
- name, len) != DDI_PROP_SUCCESS) {
- rv = -1;
- }
-
- return (rv);
-}
-
-static int
-drmach_node_obp_get_proplen(drmach_node_t *np, char *name, int *len)
-{
- pnode_t nodeid;
- int rv;
-
- nodeid = np->get_dnode(np);
- if (nodeid == OBP_NONODE)
- rv = -1;
- else {
- *len = prom_getproplen(nodeid, (caddr_t)name);
- rv = (*len < 0 ? -1 : 0);
- }
-
- return (rv);
-}
-
-static drmachid_t
-drmach_node_dup(drmach_node_t *np)
-{
- drmach_node_t *dup;
-
- dup = drmach_node_new();
- dup->here = np->here;
- dup->get_dnode = np->get_dnode;
- dup->walk = np->walk;
- dup->n_getdip = np->n_getdip;
- dup->n_getproplen = np->n_getproplen;
- dup->n_getprop = np->n_getprop;
- dup->get_parent = np->get_parent;
-
- return (dup);
-}
-
-/*
- * drmach_array provides convenient array construction, access,
- * bounds checking and array destruction logic.
- */
-
-static drmach_array_t *
-drmach_array_new(int min_index, int max_index)
-{
- drmach_array_t *arr;
-
- arr = kmem_zalloc(sizeof (drmach_array_t), KM_SLEEP);
-
- arr->arr_sz = (max_index - min_index + 1) * sizeof (void *);
- if (arr->arr_sz > 0) {
- arr->min_index = min_index;
- arr->max_index = max_index;
-
- arr->arr = kmem_zalloc(arr->arr_sz, KM_SLEEP);
- return (arr);
- } else {
- kmem_free(arr, sizeof (*arr));
- return (0);
- }
-}
-
-static int
-drmach_array_set(drmach_array_t *arr, int idx, drmachid_t val)
-{
- if (idx < arr->min_index || idx > arr->max_index)
- return (-1);
- else {
- arr->arr[idx - arr->min_index] = val;
- return (0);
- }
- /*NOTREACHED*/
-}
-
-static int
-drmach_array_get(drmach_array_t *arr, int idx, drmachid_t *val)
-{
- if (idx < arr->min_index || idx > arr->max_index)
- return (-1);
- else {
- *val = arr->arr[idx - arr->min_index];
- return (0);
- }
- /*NOTREACHED*/
-}
-
-static int
-drmach_array_first(drmach_array_t *arr, int *idx, drmachid_t *val)
-{
- int rv;
-
- *idx = arr->min_index;
- while ((rv = drmach_array_get(arr, *idx, val)) == 0 && *val == NULL)
- *idx += 1;
-
- return (rv);
-}
-
-static int
-drmach_array_next(drmach_array_t *arr, int *idx, drmachid_t *val)
-{
- int rv;
-
- *idx += 1;
- while ((rv = drmach_array_get(arr, *idx, val)) == 0 && *val == NULL)
- *idx += 1;
-
- return (rv);
-}
-
-static void
-drmach_array_dispose(drmach_array_t *arr, void (*disposer)(drmachid_t))
-{
- drmachid_t val;
- int idx;
- int rv;
-
- rv = drmach_array_first(arr, &idx, &val);
- while (rv == 0) {
- (*disposer)(val);
-
- /* clear the array entry */
- rv = drmach_array_set(arr, idx, NULL);
- ASSERT(rv == 0);
-
- rv = drmach_array_next(arr, &idx, &val);
- }
-
- kmem_free(arr->arr, arr->arr_sz);
- kmem_free(arr, sizeof (*arr));
-}
-
-
-static gdcd_t *
-drmach_gdcd_new()
-{
- gdcd_t *gdcd;
-
- gdcd = kmem_zalloc(sizeof (gdcd_t), KM_SLEEP);
-
- /* read the gdcd, bail if magic or ver #s are not what is expected */
- if (iosram_rd(GDCD_MAGIC, 0, sizeof (gdcd_t), (caddr_t)gdcd)) {
-bail:
- kmem_free(gdcd, sizeof (gdcd_t));
- return (NULL);
- } else if (gdcd->h.dcd_magic != GDCD_MAGIC) {
- goto bail;
- } else if (gdcd->h.dcd_version != DCD_VERSION) {
- goto bail;
- }
-
- return (gdcd);
-}
-
-static void
-drmach_gdcd_dispose(gdcd_t *gdcd)
-{
- kmem_free(gdcd, sizeof (gdcd_t));
-}
-
-/*ARGSUSED*/
-sbd_error_t *
-drmach_configure(drmachid_t id, int flags)
-{
- drmach_device_t *dp;
- dev_info_t *rdip;
- sbd_error_t *err = NULL;
-
- /*
- * On Starcat, there is no CPU driver, so it is
- * not necessary to configure any CPU nodes.
- */
- if (DRMACH_IS_CPU_ID(id)) {
- return (NULL);
- }
-
- for (; id; ) {
- dev_info_t *fdip = NULL;
-
- if (!DRMACH_IS_DEVICE_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- dp = id;
-
- rdip = dp->node->n_getdip(dp->node);
-
- /*
- * We held this branch earlier, so at a minimum its
- * root should still be present in the device tree.
- */
- ASSERT(rdip);
-
- DRMACH_PR("drmach_configure: configuring DDI branch");
-
- ASSERT(e_ddi_branch_held(rdip));
- if (e_ddi_branch_configure(rdip, &fdip, 0) != 0) {
- if (err == NULL) {
- /*
- * Record first failure but don't stop
- */
- char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
- dev_info_t *dip = (fdip != NULL) ? fdip : rdip;
-
- (void) ddi_pathname(dip, path);
- err = drerr_new(1, ESTC_DRVFAIL, path);
-
- kmem_free(path, MAXPATHLEN);
- }
-
- /*
- * If non-NULL, fdip is returned held and must be
- * released.
- */
- if (fdip != NULL) {
- ddi_release_devi(fdip);
- }
- }
-
- if (DRMACH_IS_MEM_ID(id)) {
- drmach_mem_t *mp = id;
- id = mp->next;
- } else {
- id = NULL;
- }
- }
-
- return (err);
-}
-
-static sbd_error_t *
-drmach_device_new(drmach_node_t *node,
- drmach_board_t *bp, int portid, drmachid_t *idp)
-{
- int i, rv, device_id, unum;
- char name[OBP_MAXDRVNAME];
- drmach_device_t proto;
-
- rv = node->n_getprop(node, "name", name, OBP_MAXDRVNAME);
- if (rv) {
- sbd_error_t *err;
-
- /* every node is expected to have a name */
- err = drerr_new(1, ESTC_GETPROP,
- "dip: 0x%p: property %s",
- node->n_getdip(node), OBP_NAME);
-
- return (err);
- }
-
- i = drmach_name2type_idx(name);
-
- if (i < 0 || strcmp(name, "cmp") == 0) {
- /*
- * Not a node of interest to dr - including "cmp",
- * but it is in drmach_name2type[], which lets gptwocfg
- * driver to check if node is OBP created.
- */
- *idp = (drmachid_t)0;
- return (NULL);
- }
-
- /*
- * Derive a best-guess unit number from the portid value.
- * Some drmach_*_new constructors (drmach_pci_new, for example)
- * will overwrite the prototype unum value with one that is more
- * appropriate for the device.
- */
- device_id = portid & 0x1f;
- if (device_id < 4)
- unum = device_id;
- else if (device_id == 8) {
- unum = 0;
- } else if (device_id == 9) {
- unum = 1;
- } else if (device_id == 0x1c) {
- unum = 0;
- } else if (device_id == 0x1d) {
- unum = 1;
- } else {
- return (DRMACH_INTERNAL_ERROR());
- }
-
- bzero(&proto, sizeof (proto));
- proto.type = drmach_name2type[i].type;
- proto.bp = bp;
- proto.node = node;
- proto.portid = portid;
- proto.unum = unum;
-
- return (drmach_name2type[i].new(&proto, idp));
-}
-
-static void
-drmach_device_dispose(drmachid_t id)
-{
- drmach_device_t *self = id;
-
- self->cm.dispose(id);
-}
-
-static drmach_board_t *
-drmach_board_new(int bnum)
-{
- drmach_board_t *bp;
-
- bp = kmem_zalloc(sizeof (drmach_board_t), KM_SLEEP);
-
- bp->cm.isa = (void *)drmach_board_new;
- bp->cm.release = drmach_board_release;
- bp->cm.status = drmach_board_status;
-
- (void) drmach_board_name(bnum, bp->cm.name, sizeof (bp->cm.name));
-
- bp->bnum = bnum;
- bp->devices = NULL;
- bp->tree = drmach_node_new();
-
- (void) drmach_array_set(drmach_boards, bnum, bp);
- return (bp);
-}
-
-static void
-drmach_board_dispose(drmachid_t id)
-{
- drmach_board_t *bp;
-
- ASSERT(DRMACH_IS_BOARD_ID(id));
- bp = id;
-
- if (bp->tree)
- drmach_node_dispose(bp->tree);
-
- if (bp->devices)
- drmach_array_dispose(bp->devices, drmach_device_dispose);
-
- kmem_free(bp, sizeof (*bp));
-}
-
-static sbd_error_t *
-drmach_board_status(drmachid_t id, drmach_status_t *stat)
-{
- sbd_error_t *err = NULL;
- drmach_board_t *bp;
- caddr_t obufp;
- dr_showboard_t shb;
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- bp = id;
-
- /*
- * we need to know if the board's connected before
- * issuing a showboard message. If it's connected, we just
- * reply with status composed of cached info
- */
-
- if (!bp->connected) {
- obufp = kmem_zalloc(sizeof (dr_proto_hdr_t), KM_SLEEP);
- err = drmach_mbox_trans(DRMSG_SHOWBOARD, bp->bnum, obufp,
- sizeof (dr_proto_hdr_t), (caddr_t)&shb,
- sizeof (dr_showboard_t));
-
- kmem_free(obufp, sizeof (dr_proto_hdr_t));
- if (err)
- return (err);
-
- bp->connected = (shb.bd_assigned && shb.bd_active);
- (void) strncpy(bp->type, shb.board_type, sizeof (bp->type));
- stat->assigned = bp->assigned = shb.bd_assigned;
- stat->powered = bp->powered = shb.power_on;
- stat->empty = bp->empty = shb.slot_empty;
-
- switch (shb.test_status) {
- case DR_TEST_STATUS_UNKNOWN:
- case DR_TEST_STATUS_IPOST:
- case DR_TEST_STATUS_ABORTED:
- stat->cond = bp->cond = SBD_COND_UNKNOWN;
- break;
- case DR_TEST_STATUS_PASSED:
- stat->cond = bp->cond = SBD_COND_OK;
- break;
- case DR_TEST_STATUS_FAILED:
- stat->cond = bp->cond = SBD_COND_FAILED;
- break;
- default:
- stat->cond = bp->cond = SBD_COND_UNKNOWN;
- DRMACH_PR("Unknown test status=0x%x from SC\n",
- shb.test_status);
- break;
-
- }
-
- (void) strncpy(stat->type, shb.board_type, sizeof (stat->type));
- (void) snprintf(stat->info, sizeof (stat->info),
- "Test Level=%d", shb.test_level);
- } else {
- stat->assigned = bp->assigned;
- stat->powered = bp->powered;
- stat->empty = bp->empty;
- stat->cond = bp->cond;
- (void) strncpy(stat->type, bp->type, sizeof (stat->type));
- }
-
- stat->busy = 0; /* assume not busy */
- stat->configured = 0; /* assume not configured */
- if (bp->devices) {
- int rv;
- int d_idx;
- drmachid_t d_id;
-
- rv = drmach_array_first(bp->devices, &d_idx, &d_id);
- while (rv == 0) {
- drmach_status_t d_stat;
-
- err = drmach_i_status(d_id, &d_stat);
- if (err)
- break;
-
- stat->busy |= d_stat.busy;
- stat->configured |= d_stat.configured;
-
- rv = drmach_array_next(bp->devices, &d_idx, &d_id);
- }
- }
-
- return (err);
-}
-
-typedef struct drmach_msglist {
- kcondvar_t s_cv; /* condvar for sending msg */
- kmutex_t s_lock; /* mutex for sending */
- kcondvar_t g_cv; /* condvar for getting reply */
- kmutex_t g_lock; /* mutex for getting reply */
- struct drmach_msglist *prev; /* link to previous entry */
- struct drmach_msglist *next; /* link to next entry */
- struct drmach_msglist *link; /* link to related entry */
- caddr_t o_buf; /* address of output buffer */
- caddr_t i_buf; /* address of input buffer */
- uint32_t o_buflen; /* output buffer length */
- uint32_t i_buflen; /* input buffer length */
- uint32_t msgid; /* message identifier */
- int o_nretry; /* number of sending retries */
- int f_error; /* mailbox framework error */
- uint8_t e_code; /* error code returned by SC */
- uint8_t p_flag :1, /* successfully putmsg */
- m_reply :1, /* msg reply received */
- unused :6;
-} drmach_msglist_t;
-
-kmutex_t drmach_g_mbox_mutex; /* mutex for mailbox globals */
-kmutex_t drmach_ri_mbox_mutex; /* mutex for mailbox reinit */
-kmutex_t drmach_msglist_mutex; /* mutex for message list */
-drmach_msglist_t *drmach_msglist_first; /* first entry in msg list */
-drmach_msglist_t *drmach_msglist_last; /* last entry in msg list */
-uint32_t drmach_msgid; /* current message id */
-kthread_t *drmach_getmsg_thread; /* ptr to getmsg thread */
-volatile int drmach_getmsg_thread_run; /* run flag for getmsg thr */
-kmutex_t drmach_sendmsg_mutex; /* mutex for sendmsg cv */
-kcondvar_t drmach_sendmsg_cv; /* signaled to send new msg */
-kthread_t *drmach_sendmsg_thread; /* ptr to sendmsg thread */
-volatile int drmach_sendmsg_thread_run; /* run flag for sendmsg */
-int drmach_mbox_istate; /* mailbox init state */
-int drmach_mbox_iflag; /* set if init'd with SC */
-int drmach_mbox_ipending; /* set if reinit scheduled */
-
-/*
- * Timeout values (in seconds) used when waiting for replies (from the SC) to
- * requests that we sent. Since we only receive boardevent messages, and they
- * are events rather than replies, there is no boardevent timeout.
- */
-int drmach_to_mbxinit = 60; /* 1 minute */
-int drmach_to_assign = 60; /* 1 minute */
-int drmach_to_unassign = 60; /* 1 minute */
-int drmach_to_claim = 3600; /* 1 hour */
-int drmach_to_unclaim = 3600; /* 1 hour */
-int drmach_to_poweron = 480; /* 8 minutes */
-int drmach_to_poweroff = 480; /* 8 minutes */
-int drmach_to_testboard = 43200; /* 12 hours */
-int drmach_to_aborttest = 180; /* 3 minutes */
-int drmach_to_showboard = 180; /* 3 minutes */
-int drmach_to_unconfig = 180; /* 3 minutes */
-
-/*
- * Delay (in seconds) used after receiving a non-transient error indication from
- * an mboxsc_getmsg call in the thread that loops waiting for incoming messages.
- */
-int drmach_mbxerr_delay = 15; /* 15 seconds */
-
-/*
- * Timeout values (in milliseconds) for mboxsc_putmsg and mboxsc_getmsg calls.
- */
-clock_t drmach_to_putmsg; /* set in drmach_mbox_init */
-clock_t drmach_to_getmsg = 31000; /* 31 seconds */
-
-/*
- * Normally, drmach_to_putmsg is set dynamically during initialization in
- * drmach_mbox_init. This has the potentially undesirable side effect of
- * clobbering any value that might have been set in /etc/system. To prevent
- * dynamic setting of drmach_to_putmsg (thereby allowing it to be tuned in
- * /etc/system), set drmach_use_tuned_putmsg_to to 1.
- */
-int drmach_use_tuned_putmsg_to = 0;
-
-
-/* maximum conceivable message size for future mailbox protocol versions */
-#define DRMACH_MAX_MBOX_MSG_SIZE 4096
-
-/*ARGSUSED*/
-void
-drmach_mbox_prmsg(dr_mbox_msg_t *mbp, int dir)
-{
- int i, j;
- dr_memregs_t *memregs;
- dr_proto_hdr_t *php = &mbp->p_hdr;
- dr_msg_t *mp = &mbp->msgdata;
-
-#ifdef DEBUG
- switch (php->command) {
- case DRMSG_BOARDEVENT:
- if (dir) {
- DRMACH_PR("ERROR!! outgoing BOARDEVENT\n");
- } else {
- DRMACH_PR("BOARDEVENT received:\n");
- DRMACH_PR("init=%d ins=%d rem=%d asgn=%d\n",
- mp->dm_be.initialized,
- mp->dm_be.board_insertion,
- mp->dm_be.board_removal,
- mp->dm_be.slot_assign);
- DRMACH_PR("unasgn=%d avail=%d unavail=%d\n",
- mp->dm_be.slot_unassign,
- mp->dm_be.slot_avail,
- mp->dm_be.slot_unavail);
- }
- break;
- case DRMSG_MBOX_INIT:
- if (dir) {
- DRMACH_PR("MBOX_INIT Request:\n");
- } else {
- DRMACH_PR("MBOX_INIT Reply:\n");
- }
- break;
- case DRMSG_ASSIGN:
- if (dir) {
- DRMACH_PR("ASSIGN Request:\n");
- } else {
- DRMACH_PR("ASSIGN Reply:\n");
- }
- break;
- case DRMSG_UNASSIGN:
- if (dir) {
- DRMACH_PR("UNASSIGN Request:\n");
- } else {
- DRMACH_PR("UNASSIGN Reply:\n");
- }
- break;
- case DRMSG_CLAIM:
- if (!dir) {
- DRMACH_PR("CLAIM Reply:\n");
- break;
- }
-
- DRMACH_PR("CLAIM Request:\n");
- for (i = 0; i < 18; ++i) {
- DRMACH_PR("exp%d: val=%d slice=0x%x\n", i,
- mp->dm_cr.mem_slice[i].valid,
- mp->dm_cr.mem_slice[i].slice);
- memregs = &(mp->dm_cr.mem_regs[i]);
- for (j = 0; j < S0_LPORT_COUNT; j++) {
- DRMACH_PR(" MC %2d: "
- "MADR[%d] = 0x%lx, "
- "MADR[%d] = 0x%lx\n", j,
- 0, DRMACH_MCREG_TO_U64(
- memregs->madr[j][0]),
- 1, DRMACH_MCREG_TO_U64(
- memregs->madr[j][1]));
- DRMACH_PR(" : "
- "MADR[%d] = 0x%lx, "
- "MADR[%d] = 0x%lx\n",
- 2, DRMACH_MCREG_TO_U64(
- memregs->madr[j][2]),
- 3, DRMACH_MCREG_TO_U64(
- memregs->madr[j][3]));
- }
- }
- break;
- case DRMSG_UNCLAIM:
- if (!dir) {
- DRMACH_PR("UNCLAIM Reply:\n");
- break;
- }
-
- DRMACH_PR("UNCLAIM Request:\n");
- for (i = 0; i < 18; ++i) {
- DRMACH_PR("exp%d: val=%d slice=0x%x\n", i,
- mp->dm_ur.mem_slice[i].valid,
- mp->dm_ur.mem_slice[i].slice);
- memregs = &(mp->dm_ur.mem_regs[i]);
- for (j = 0; j < S0_LPORT_COUNT; j++) {
- DRMACH_PR(" MC %2d: "
- "MADR[%d] = 0x%lx, "
- "MADR[%d] = 0x%lx\n", j,
- 0, DRMACH_MCREG_TO_U64(
- memregs->madr[j][0]),
- 1, DRMACH_MCREG_TO_U64(
- memregs->madr[j][1]));
- DRMACH_PR(" : "
- "MADR[%d] = 0x%lx, "
- "MADR[%d] = 0x%lx\n",
- 2, DRMACH_MCREG_TO_U64(
- memregs->madr[j][2]),
- 3, DRMACH_MCREG_TO_U64(
- memregs->madr[j][3]));
- }
- }
- DRMACH_PR(" mem_clear=%d\n", mp->dm_ur.mem_clear);
- break;
- case DRMSG_UNCONFIG:
- if (!dir) {
- DRMACH_PR("UNCONFIG Reply:\n");
- break;
- }
-
- DRMACH_PR("UNCONFIG Request:\n");
- for (i = 0; i < 18; ++i) {
- DRMACH_PR("exp%d: val=%d slice=0x%x\n", i,
- mp->dm_uc.mem_slice[i].valid,
- mp->dm_uc.mem_slice[i].slice);
- memregs = &(mp->dm_uc.mem_regs[i]);
- for (j = 0; j < S0_LPORT_COUNT; j++) {
- DRMACH_PR(" MC %2d: "
- "MADR[%d] = 0x%lx, "
- "MADR[%d] = 0x%lx\n", j,
- 0, DRMACH_MCREG_TO_U64(
- memregs->madr[j][0]),
- 1, DRMACH_MCREG_TO_U64(
- memregs->madr[j][1]));
- DRMACH_PR(" : "
- "MADR[%d] = 0x%lx, "
- "MADR[%d] = 0x%lx\n",
- 2, DRMACH_MCREG_TO_U64(
- memregs->madr[j][2]),
- 3, DRMACH_MCREG_TO_U64(
- memregs->madr[j][3]));
- }
- }
- break;
- case DRMSG_POWERON:
- if (dir) {
- DRMACH_PR("POWERON Request:\n");
- } else {
- DRMACH_PR("POWERON Reply:\n");
- }
- break;
- case DRMSG_POWEROFF:
- if (dir) {
- DRMACH_PR("POWEROFF Request:\n");
- } else {
- DRMACH_PR("POWEROFF Reply:\n");
- }
- break;
- case DRMSG_TESTBOARD:
- if (dir) {
- DRMACH_PR("TESTBOARD Request:\n");
- DRMACH_PR("\tmemaddrhi=0x%x memaddrlo=0x%x ",
- mp->dm_tb.memaddrhi,
- mp->dm_tb.memaddrlo);
- DRMACH_PR("memlen=0x%x cpu_portid=0x%x\n",
- mp->dm_tb.memlen, mp->dm_tb.cpu_portid);
- DRMACH_PR("\tforce=0x%x imm=0x%x\n",
- mp->dm_tb.force, mp->dm_tb.immediate);
- } else {
- DRMACH_PR("TESTBOARD Reply:\n");
- DRMACH_PR("\tmemaddrhi=0x%x memaddrlo=0x%x ",
- mp->dm_tr.memaddrhi,
- mp->dm_tr.memaddrlo);
- DRMACH_PR("memlen=0x%x cpu_portid=0x%x\n",
- mp->dm_tr.memlen, mp->dm_tr.cpu_portid);
- DRMACH_PR("\trecovered=0x%x test status=0x%x\n",
- mp->dm_tr.cpu_recovered,
- mp->dm_tr.test_status);
-
- }
- break;
- case DRMSG_ABORT_TEST:
- if (dir) {
- DRMACH_PR("ABORT_TEST Request:\n");
- } else {
- DRMACH_PR("ABORT_TEST Reply:\n");
- }
-
- DRMACH_PR("\tmemaddrhi=0x%x memaddrlo=0x%x ",
- mp->dm_ta.memaddrhi,
- mp->dm_ta.memaddrlo);
- DRMACH_PR("memlen=0x%x cpu_portid=0x%x\n",
- mp->dm_ta.memlen, mp->dm_ta.cpu_portid);
- break;
- case DRMSG_SHOWBOARD:
- if (dir) {
- DRMACH_PR("SHOWBOARD Request:\n");
- } else {
- DRMACH_PR("SHOWBOARD Reply:\n");
-
- DRMACH_PR(": empty=%d power=%d assigned=%d",
- mp->dm_sb.slot_empty,
- mp->dm_sb.power_on,
- mp->dm_sb.bd_assigned);
- DRMACH_PR(": active=%d t_status=%d t_level=%d ",
- mp->dm_sb.bd_active,
- mp->dm_sb.test_status,
- mp->dm_sb.test_level);
- DRMACH_PR(": type=%s ", mp->dm_sb.board_type);
- }
- break;
- default:
- DRMACH_PR("Unknown message type\n");
- break;
- }
-
- DRMACH_PR("dr hdr:\n\tid=0x%x vers=0x%x cmd=0x%x exp=0x%x slot=0x%x\n",
- php->message_id, php->drproto_version, php->command,
- php->expbrd, php->slot);
-#endif
- DRMACH_PR("\treply_status=0x%x error_code=0x%x\n", php->reply_status,
- php->error_code);
-}
-
-/*
- * Callback function passed to taskq_dispatch when a mailbox reinitialization
- * handshake needs to be scheduled. The handshake can't be performed by the
- * thread that determines it is needed, in most cases, so this function is
- * dispatched on the system-wide taskq pool of threads. Failure is reported but
- * otherwise ignored, since any situation that requires a mailbox initialization
- * handshake will continue to request the handshake until it succeeds.
- */
-static void
-drmach_mbox_reinit(void *unused)
-{
- _NOTE(ARGUNUSED(unused))
-
- caddr_t obufp = NULL;
- sbd_error_t *serr = NULL;
-
- DRMACH_PR("scheduled mailbox reinit running\n");
-
- mutex_enter(&drmach_ri_mbox_mutex);
- mutex_enter(&drmach_g_mbox_mutex);
- if (drmach_mbox_iflag == 0) {
- /* need to initialize the mailbox */
- mutex_exit(&drmach_g_mbox_mutex);
-
- cmn_err(CE_NOTE, "!reinitializing DR mailbox");
- obufp = kmem_zalloc(sizeof (dr_proto_hdr_t), KM_SLEEP);
- serr = drmach_mbox_trans(DRMSG_MBOX_INIT, 0, obufp,
- sizeof (dr_proto_hdr_t), (caddr_t)NULL, 0);
- kmem_free(obufp, sizeof (dr_proto_hdr_t));
-
- if (serr) {
- cmn_err(CE_WARN,
- "mbox_init: MBOX_INIT failed ecode=0x%x",
- serr->e_code);
- sbd_err_clear(&serr);
- }
- mutex_enter(&drmach_g_mbox_mutex);
- if (!serr) {
- drmach_mbox_iflag = 1;
- }
- }
- drmach_mbox_ipending = 0;
- mutex_exit(&drmach_g_mbox_mutex);
- mutex_exit(&drmach_ri_mbox_mutex);
-}
-
-/*
- * To ensure sufficient compatibility with future versions of the DR mailbox
- * protocol, we use a buffer that is large enough to receive the largest message
- * that could possibly be sent to us. However, since that ends up being fairly
- * large, allocating it on the stack is a bad idea. Fortunately, this function
- * does not need to be MT-safe since it is only invoked by the mailbox
- * framework, which will never invoke it multiple times concurrently. Since
- * that is the case, we can use a static buffer.
- */
-void
-drmach_mbox_event(void)
-{
- static uint8_t buf[DRMACH_MAX_MBOX_MSG_SIZE];
- dr_mbox_msg_t *msg = (dr_mbox_msg_t *)buf;
- int err;
- uint32_t type = MBOXSC_MSG_EVENT;
- uint32_t command = DRMSG_BOARDEVENT;
- uint64_t transid = 0;
- uint32_t length = DRMACH_MAX_MBOX_MSG_SIZE;
- char *hint = "";
- int logsys = 0;
-
- do {
- err = mboxsc_getmsg(KEY_SCDR, &type, &command, &transid,
- &length, (void *)msg, 0);
- } while (err == EAGAIN);
-
- /* don't try to interpret anything with the wrong version number */
- if ((err == 0) && (msg->p_hdr.drproto_version != DRMBX_VERSION)) {
- cmn_err(CE_WARN, "mailbox version mismatch 0x%x vs 0x%x",
- msg->p_hdr.drproto_version, DRMBX_VERSION);
- mutex_enter(&drmach_g_mbox_mutex);
- drmach_mbox_iflag = 0;
- /* schedule a reinit handshake if one isn't pending */
- if (!drmach_mbox_ipending) {
- if (taskq_dispatch(system_taskq, drmach_mbox_reinit,
- NULL, TQ_NOSLEEP) != TASKQID_INVALID) {
- drmach_mbox_ipending = 1;
- } else {
- cmn_err(CE_WARN,
- "failed to schedule mailbox reinit");
- }
- }
- mutex_exit(&drmach_g_mbox_mutex);
- return;
- }
-
- if ((err != 0) || (msg->p_hdr.reply_status != DRMSG_REPLY_OK)) {
- cmn_err(CE_WARN,
- "Unsolicited mboxsc_getmsg failed: err=0x%x code=0x%x",
- err, msg->p_hdr.error_code);
- } else {
- dr_boardevent_t *be;
- be = (dr_boardevent_t *)&msg->msgdata;
-
- /* check for initialization event */
- if (be->initialized) {
- mutex_enter(&drmach_g_mbox_mutex);
- drmach_mbox_iflag = 0;
- /* schedule a reinit handshake if one isn't pending */
- if (!drmach_mbox_ipending) {
- if (taskq_dispatch(system_taskq,
- drmach_mbox_reinit, NULL, TQ_NOSLEEP)
- != TASKQID_INVALID) {
- drmach_mbox_ipending = 1;
- } else {
- cmn_err(CE_WARN, "failed to schedule "
- "mailbox reinit");
- }
- }
- mutex_exit(&drmach_g_mbox_mutex);
- cmn_err(CE_NOTE, "!Mailbox Init event received");
- }
-
- /* anything else will be a log_sysevent call */
-
- if (be->board_insertion) {
- DRMACH_PR("Board Insertion event received");
- hint = DR_HINT_INSERT;
- logsys++;
- }
- if (be->board_removal) {
- DRMACH_PR("Board Removal event received");
- hint = DR_HINT_REMOVE;
- logsys++;
- }
- if (be->slot_assign) {
- DRMACH_PR("Slot Assign event received");
- logsys++;
- }
- if (be->slot_unassign) {
- DRMACH_PR("Slot Unassign event received");
- logsys++;
- }
- if (be->slot_avail) {
- DRMACH_PR("Slot Available event received");
- logsys++;
- }
- if (be->slot_unavail) {
- DRMACH_PR("Slot Unavailable event received");
- logsys++;
- }
- if (be->power_on) {
- DRMACH_PR("Power ON event received");
- logsys++;
- }
- if (be->power_off) {
- DRMACH_PR("Power OFF event received");
- logsys++;
- }
-
- if (logsys)
- (void) drmach_log_sysevent(
- DRMACH_EXPSLOT2BNUM(msg->p_hdr.expbrd,
- msg->p_hdr.slot), hint, SE_NOSLEEP, 1);
- }
-}
-
-static uint32_t
-drmach_get_msgid()
-{
- uint32_t rv;
- mutex_enter(&drmach_msglist_mutex);
- if (!(++drmach_msgid))
- ++drmach_msgid;
- rv = drmach_msgid;
- mutex_exit(&drmach_msglist_mutex);
- return (rv);
-}
-
-/*
- * unlink an entry from the message transaction list
- *
- * caller must hold drmach_msglist_mutex
- */
-void
-drmach_msglist_unlink(drmach_msglist_t *entry)
-{
- ASSERT(mutex_owned(&drmach_msglist_mutex));
- if (entry->prev) {
- entry->prev->next = entry->next;
- if (entry->next)
- entry->next->prev = entry->prev;
- } else {
- drmach_msglist_first = entry->next;
- if (entry->next)
- entry->next->prev = NULL;
- }
- if (entry == drmach_msglist_last) {
- drmach_msglist_last = entry->prev;
- }
-}
-
-void
-drmach_msglist_link(drmach_msglist_t *entry)
-{
- mutex_enter(&drmach_msglist_mutex);
- if (drmach_msglist_last) {
- entry->prev = drmach_msglist_last;
- drmach_msglist_last->next = entry;
- drmach_msglist_last = entry;
- } else {
- drmach_msglist_last = drmach_msglist_first = entry;
- }
- mutex_exit(&drmach_msglist_mutex);
-}
-
-void
-drmach_mbox_getmsg()
-{
- int err;
- register int msgid;
- static uint8_t buf[DRMACH_MAX_MBOX_MSG_SIZE];
- dr_mbox_msg_t *msg = (dr_mbox_msg_t *)buf;
- dr_proto_hdr_t *php;
- drmach_msglist_t *found, *entry;
- uint32_t type = MBOXSC_MSG_REPLY;
- uint32_t command;
- uint64_t transid;
- uint32_t length;
-
- php = &msg->p_hdr;
-
- while (drmach_getmsg_thread_run != 0) {
- /* get a reply message */
- command = 0;
- transid = 0;
- length = DRMACH_MAX_MBOX_MSG_SIZE;
- err = mboxsc_getmsg(KEY_SCDR, &type, &command, &transid,
- &length, (void *)msg, drmach_to_getmsg);
-
- if (err) {
- /*
- * If mboxsc_getmsg returns ETIMEDOUT or EAGAIN, then
- * the "error" is really just a normal, transient
- * condition and we can retry the operation right away.
- * Any other error suggests a more serious problem,
- * ranging from a message being too big for our buffer
- * (EMSGSIZE) to total failure of the mailbox layer.
- * This second class of errors is much less "transient",
- * so rather than retrying over and over (and getting
- * the same error over and over) as fast as we can,
- * we'll sleep for a while before retrying.
- */
- if ((err != ETIMEDOUT) && (err != EAGAIN)) {
- cmn_err(CE_WARN,
- "mboxsc_getmsg failed, err=0x%x", err);
- delay(drmach_mbxerr_delay * hz);
- }
- continue;
- }
-
- drmach_mbox_prmsg(msg, 0);
-
- if (php->drproto_version != DRMBX_VERSION) {
- cmn_err(CE_WARN,
- "mailbox version mismatch 0x%x vs 0x%x",
- php->drproto_version, DRMBX_VERSION);
-
- mutex_enter(&drmach_g_mbox_mutex);
- drmach_mbox_iflag = 0;
- /* schedule a reinit handshake if one isn't pending */
- if (!drmach_mbox_ipending) {
- if (taskq_dispatch(system_taskq,
- drmach_mbox_reinit, NULL, TQ_NOSLEEP)
- != TASKQID_INVALID) {
- drmach_mbox_ipending = 1;
- } else {
- cmn_err(CE_WARN, "failed to schedule "
- "mailbox reinit");
- }
- }
- mutex_exit(&drmach_g_mbox_mutex);
-
- continue;
- }
-
- msgid = php->message_id;
- found = NULL;
- mutex_enter(&drmach_msglist_mutex);
- entry = drmach_msglist_first;
- while (entry != NULL) {
- if (entry->msgid == msgid) {
- found = entry;
- drmach_msglist_unlink(entry);
- entry = NULL;
- } else
- entry = entry->next;
- }
-
- if (found) {
- mutex_enter(&found->g_lock);
-
- found->e_code = php->error_code;
- if (found->i_buflen > 0)
- bcopy((caddr_t)&msg->msgdata, found->i_buf,
- found->i_buflen);
- found->m_reply = 1;
-
- cv_signal(&found->g_cv);
- mutex_exit(&found->g_lock);
- } else {
- cmn_err(CE_WARN, "!mbox_getmsg: no match for id 0x%x",
- msgid);
- cmn_err(CE_WARN, "! cmd = 0x%x, exb = %d, slot = %d",
- php->command, php->expbrd, php->slot);
- }
-
- mutex_exit(&drmach_msglist_mutex);
- }
- cmn_err(CE_WARN, "mbox_getmsg: exiting");
- mutex_enter(&drmach_msglist_mutex);
- entry = drmach_msglist_first;
- while (entry != NULL) {
- if (entry->p_flag == 1) {
- entry->f_error = -1;
- mutex_enter(&entry->g_lock);
- cv_signal(&entry->g_cv);
- mutex_exit(&entry->g_lock);
- drmach_msglist_unlink(entry);
- }
- entry = entry->next;
- }
- mutex_exit(&drmach_msglist_mutex);
- drmach_getmsg_thread_run = -1;
- thread_exit();
-}
-
-void
-drmach_mbox_sendmsg()
-{
- int err, retry;
- drmach_msglist_t *entry;
- dr_mbox_msg_t *mp;
- dr_proto_hdr_t *php;
-
- while (drmach_sendmsg_thread_run != 0) {
- /*
- * Search through the list to find entries awaiting
- * transmission to the SC
- */
- mutex_enter(&drmach_msglist_mutex);
- entry = drmach_msglist_first;
- retry = 0;
- while (entry != NULL) {
- if (entry->p_flag == 1) {
- entry = entry->next;
- continue;
- }
-
- mutex_exit(&drmach_msglist_mutex);
-
- if (!retry)
- mutex_enter(&entry->s_lock);
- mp = (dr_mbox_msg_t *)entry->o_buf;
- php = &mp->p_hdr;
-
- drmach_mbox_prmsg(mp, 1);
-
- err = mboxsc_putmsg(KEY_DRSC, MBOXSC_MSG_REQUEST,
- php->command, NULL, entry->o_buflen, (void *)mp,
- drmach_to_putmsg);
-
- if (err) {
- switch (err) {
-
- case EAGAIN:
- case EBUSY:
- ++retry;
- mutex_enter(&drmach_msglist_mutex);
- continue;
-
- case ETIMEDOUT:
- if (--entry->o_nretry <= 0) {
- mutex_enter(
- &drmach_msglist_mutex);
- drmach_msglist_unlink(entry);
- mutex_exit(
- &drmach_msglist_mutex);
- entry->f_error = err;
- entry->p_flag = 1;
- cv_signal(&entry->s_cv);
- } else {
- ++retry;
- mutex_enter(
- &drmach_msglist_mutex);
- continue;
- }
- break;
- default:
- mutex_enter(&drmach_msglist_mutex);
- drmach_msglist_unlink(entry);
- mutex_exit(&drmach_msglist_mutex);
- entry->f_error = err;
- entry->p_flag = 1;
- cv_signal(&entry->s_cv);
- break;
- }
- } else {
- entry->p_flag = 1;
- cv_signal(&entry->s_cv);
- }
-
- mutex_exit(&entry->s_lock);
- retry = 0;
- mutex_enter(&drmach_msglist_mutex);
- entry = drmach_msglist_first;
- }
- mutex_exit(&drmach_msglist_mutex);
-
- mutex_enter(&drmach_sendmsg_mutex);
- (void) cv_reltimedwait(&drmach_sendmsg_cv,
- &drmach_sendmsg_mutex, (5 * hz), TR_CLOCK_TICK);
- mutex_exit(&drmach_sendmsg_mutex);
- }
- cmn_err(CE_WARN, "mbox_sendmsg: exiting");
- mutex_enter(&drmach_msglist_mutex);
- entry = drmach_msglist_first;
- while (entry != NULL) {
- if (entry->p_flag == 0) {
- entry->f_error = -1;
- mutex_enter(&entry->s_lock);
- cv_signal(&entry->s_cv);
- mutex_exit(&entry->s_lock);
- drmach_msglist_unlink(entry);
- }
- entry = entry->next;
- }
- mutex_exit(&drmach_msglist_mutex);
- cv_destroy(&drmach_sendmsg_cv);
- mutex_destroy(&drmach_sendmsg_mutex);
-
- drmach_sendmsg_thread_run = -1;
- thread_exit();
-}
-
-void
-drmach_msglist_destroy(drmach_msglist_t *listp)
-{
- if (listp != NULL) {
- drmach_msglist_t *entry;
-
- mutex_enter(&drmach_msglist_mutex);
- entry = drmach_msglist_first;
- while (entry) {
- if (listp == entry) {
- drmach_msglist_unlink(listp);
- entry = NULL;
- } else
- entry = entry->next;
- }
-
- mutex_destroy(&listp->s_lock);
- cv_destroy(&listp->s_cv);
- mutex_destroy(&listp->g_lock);
- cv_destroy(&listp->g_cv);
- kmem_free(listp, sizeof (drmach_msglist_t));
-
- mutex_exit(&drmach_msglist_mutex);
- }
-}
-
-static drmach_msglist_t *
-drmach_msglist_new(caddr_t ibufp, uint32_t ilen, dr_proto_hdr_t *hdrp,
- uint32_t olen, int nrtry)
-{
- drmach_msglist_t *listp;
-
- listp = kmem_zalloc(sizeof (drmach_msglist_t), KM_SLEEP);
- mutex_init(&listp->s_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&listp->s_cv, NULL, CV_DRIVER, NULL);
- mutex_init(&listp->g_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&listp->g_cv, NULL, CV_DRIVER, NULL);
- listp->o_buf = (caddr_t)hdrp;
- listp->o_buflen = olen;
- listp->i_buf = ibufp;
- listp->i_buflen = ilen;
- listp->o_nretry = nrtry;
- listp->msgid = hdrp->message_id;
-
- return (listp);
-}
-
-static drmach_msglist_t *
-drmach_mbox_req_rply(dr_proto_hdr_t *hdrp, uint32_t olen, caddr_t ibufp,
- uint32_t ilen, int timeout, int nrtry, int nosig,
- drmach_msglist_t *link)
-{
- int crv;
- drmach_msglist_t *listp;
- clock_t to_val;
- dr_proto_hdr_t *php;
-
- /* setup transaction list entry */
- listp = drmach_msglist_new(ibufp, ilen, hdrp, olen, nrtry);
-
- /* send mailbox message, await reply */
- mutex_enter(&listp->s_lock);
- mutex_enter(&listp->g_lock);
-
- listp->link = link;
- drmach_msglist_link(listp);
-
- mutex_enter(&drmach_sendmsg_mutex);
- cv_signal(&drmach_sendmsg_cv);
- mutex_exit(&drmach_sendmsg_mutex);
-
- while (listp->p_flag == 0) {
- cv_wait(&listp->s_cv, &listp->s_lock);
- }
-
- to_val = ddi_get_lbolt() + (timeout * hz);
-
- if (listp->f_error) {
- listp->p_flag = 0;
- cmn_err(CE_WARN, "!mboxsc_putmsg failed: 0x%x", listp->f_error);
- php = (dr_proto_hdr_t *)listp->o_buf;
- cmn_err(CE_WARN, "! cmd = 0x%x, exb = %d, slot = %d",
- php->command, php->expbrd, php->slot);
- } else {
- while (listp->m_reply == 0 && listp->f_error == 0) {
- if (nosig)
- crv = cv_timedwait(&listp->g_cv, &listp->g_lock,
- to_val);
- else
- crv = cv_timedwait_sig(&listp->g_cv,
- &listp->g_lock, to_val);
- switch (crv) {
- case -1: /* timed out */
- cmn_err(CE_WARN,
- "!msgid=0x%x reply timed out",
- hdrp->message_id);
- php = (dr_proto_hdr_t *)listp->o_buf;
- cmn_err(CE_WARN, "! cmd = 0x%x, "
- "exb = %d, slot = %d", php->command,
- php->expbrd, php->slot);
- listp->f_error = ETIMEDOUT;
- break;
- case 0: /* signal received */
- cmn_err(CE_WARN,
- "operation interrupted by signal");
- listp->f_error = EINTR;
- break;
- default:
- break;
- }
- }
-
- /*
- * If link is set for this entry, check to see if
- * the linked entry has been replied to. If not,
- * wait for the response.
- * Currently, this is only used for ABORT_TEST functionality,
- * wherein a check is made for the TESTBOARD reply when
- * the ABORT_TEST reply is received.
- */
-
- if (link) {
- mutex_enter(&link->g_lock);
- /*
- * If the reply to the linked entry hasn't been
- * received, clear the existing link->f_error,
- * and await the reply.
- */
- if (link->m_reply == 0) {
- link->f_error = 0;
- }
- to_val = ddi_get_lbolt() + (timeout * hz);
- while (link->m_reply == 0 && link->f_error == 0) {
- crv = cv_timedwait(&link->g_cv, &link->g_lock,
- to_val);
- switch (crv) {
- case -1: /* timed out */
- cmn_err(CE_NOTE,
- "!link msgid=0x%x reply timed out",
- link->msgid);
- link->f_error = ETIMEDOUT;
- break;
- default:
- break;
- }
- }
- mutex_exit(&link->g_lock);
- }
- }
- mutex_exit(&listp->g_lock);
- mutex_exit(&listp->s_lock);
- return (listp);
-}
-
-static sbd_error_t *
-drmach_mbx2sbderr(drmach_msglist_t *mlp)
-{
- char a_pnt[MAXNAMELEN];
- dr_proto_hdr_t *php;
- int bnum;
-
- if (mlp->f_error) {
- /*
- * If framework failure is due to signal, return "no error"
- * error.
- */
- if (mlp->f_error == EINTR)
- return (drerr_new(0, ESTC_NONE, NULL));
-
- mutex_enter(&drmach_g_mbox_mutex);
- drmach_mbox_iflag = 0;
- mutex_exit(&drmach_g_mbox_mutex);
- if (!mlp->p_flag)
- return (drerr_new(1, ESTC_MBXRQST, NULL));
- else
- return (drerr_new(1, ESTC_MBXRPLY, NULL));
- }
- php = (dr_proto_hdr_t *)mlp->o_buf;
- bnum = 2 * php->expbrd + php->slot;
- a_pnt[0] = '\0';
- (void) drmach_board_name(bnum, a_pnt, MAXNAMELEN);
-
- switch (mlp->e_code) {
- case 0:
- return (NULL);
- case DRERR_NOACL:
- return (drerr_new(0, ESTC_NOACL, "%s", a_pnt));
- case DRERR_NOT_ASSIGNED:
- return (drerr_new(0, ESTC_NOT_ASSIGNED, "%s", a_pnt));
- case DRERR_NOT_ACTIVE:
- return (drerr_new(0, ESTC_NOT_ACTIVE, "%s", a_pnt));
- case DRERR_EMPTY_SLOT:
- return (drerr_new(0, ESTC_EMPTY_SLOT, "%s", a_pnt));
- case DRERR_POWER_OFF:
- return (drerr_new(0, ESTC_POWER_OFF, "%s", a_pnt));
- case DRERR_TEST_IN_PROGRESS:
- return (drerr_new(0, ESTC_TEST_IN_PROGRESS, "%s",
- a_pnt));
- case DRERR_TESTING_BUSY:
- return (drerr_new(0, ESTC_TESTING_BUSY, "%s", a_pnt));
- case DRERR_TEST_REQUIRED:
- return (drerr_new(0, ESTC_TEST_REQUIRED, "%s", a_pnt));
- case DRERR_UNAVAILABLE:
- return (drerr_new(0, ESTC_UNAVAILABLE, "%s", a_pnt));
- case DRERR_RECOVERABLE:
- return (drerr_new(0, ESTC_SMS_ERR_RECOVERABLE, "%s",
- a_pnt));
- case DRERR_UNRECOVERABLE:
- return (drerr_new(1, ESTC_SMS_ERR_UNRECOVERABLE, "%s",
- a_pnt));
- default:
- return (drerr_new(1, ESTC_MBOX_UNKNOWN, NULL));
- }
-}
-
-static sbd_error_t *
-drmach_mbox_trans(uint8_t msgtype, int bnum, caddr_t obufp, int olen,
- caddr_t ibufp, int ilen)
-{
- int timeout = 0;
- int ntries = 0;
- int nosignals = 0;
- dr_proto_hdr_t *hdrp;
- drmach_msglist_t *mlp;
- sbd_error_t *err = NULL;
-
- if (msgtype != DRMSG_MBOX_INIT) {
- mutex_enter(&drmach_ri_mbox_mutex);
- mutex_enter(&drmach_g_mbox_mutex);
- if (drmach_mbox_iflag == 0) {
- /* need to initialize the mailbox */
- dr_proto_hdr_t imsg;
-
- mutex_exit(&drmach_g_mbox_mutex);
-
- imsg.command = DRMSG_MBOX_INIT;
-
- imsg.message_id = drmach_get_msgid();
- imsg.drproto_version = DRMBX_VERSION;
- imsg.expbrd = 0;
- imsg.slot = 0;
-
- cmn_err(CE_WARN, "!reinitializing DR mailbox");
- mlp = drmach_mbox_req_rply(&imsg, sizeof (imsg), 0, 0,
- 10, 5, 0, NULL);
- err = drmach_mbx2sbderr(mlp);
- /*
- * If framework failure incoming is encountered on
- * the MBOX_INIT [timeout on SMS reply], the error
- * type must be changed before returning to caller.
- * This is to prevent drmach_board_connect() and
- * drmach_board_disconnect() from marking boards
- * UNUSABLE based on MBOX_INIT failures.
- */
- if ((err != NULL) && (err->e_code == ESTC_MBXRPLY)) {
- cmn_err(CE_WARN,
- "!Changed mbox incoming to outgoing"
- " failure on reinit");
- sbd_err_clear(&err);
- err = drerr_new(0, ESTC_MBXRQST, NULL);
- }
- drmach_msglist_destroy(mlp);
- if (err) {
- mutex_exit(&drmach_ri_mbox_mutex);
- return (err);
- }
- mutex_enter(&drmach_g_mbox_mutex);
- drmach_mbox_iflag = 1;
- }
- mutex_exit(&drmach_g_mbox_mutex);
- mutex_exit(&drmach_ri_mbox_mutex);
- }
-
- hdrp = (dr_proto_hdr_t *)obufp;
-
- /* setup outgoing mailbox header */
- hdrp->command = msgtype;
- hdrp->message_id = drmach_get_msgid();
- hdrp->drproto_version = DRMBX_VERSION;
- hdrp->expbrd = DRMACH_BNUM2EXP(bnum);
- hdrp->slot = DRMACH_BNUM2SLOT(bnum);
-
- switch (msgtype) {
-
- case DRMSG_MBOX_INIT:
- timeout = drmach_to_mbxinit;
- ntries = 1;
- nosignals = 0;
- break;
-
- case DRMSG_ASSIGN:
- timeout = drmach_to_assign;
- ntries = 1;
- nosignals = 0;
- break;
-
- case DRMSG_UNASSIGN:
- timeout = drmach_to_unassign;
- ntries = 1;
- nosignals = 0;
- break;
-
- case DRMSG_POWERON:
- timeout = drmach_to_poweron;
- ntries = 1;
- nosignals = 0;
- break;
-
- case DRMSG_POWEROFF:
- timeout = drmach_to_poweroff;
- ntries = 1;
- nosignals = 0;
- break;
-
- case DRMSG_SHOWBOARD:
- timeout = drmach_to_showboard;
- ntries = 1;
- nosignals = 0;
- break;
-
- case DRMSG_CLAIM:
- timeout = drmach_to_claim;
- ntries = 1;
- nosignals = 1;
- break;
-
- case DRMSG_UNCLAIM:
- timeout = drmach_to_unclaim;
- ntries = 1;
- nosignals = 1;
- break;
-
- case DRMSG_UNCONFIG:
- timeout = drmach_to_unconfig;
- ntries = 1;
- nosignals = 0;
- break;
-
- case DRMSG_TESTBOARD:
- timeout = drmach_to_testboard;
- ntries = 1;
- nosignals = 0;
- break;
-
- default:
- cmn_err(CE_WARN, "Unknown outgoing message type 0x%x",
- msgtype);
- err = DRMACH_INTERNAL_ERROR();
- break;
- }
-
- if (err == NULL) {
- mlp = drmach_mbox_req_rply(hdrp, olen, ibufp, ilen, timeout,
- ntries, nosignals, NULL);
- err = drmach_mbx2sbderr(mlp);
-
- /*
- * For DRMSG_TESTBOARD attempts which have timed out, or
- * been aborted due to a signal received after mboxsc_putmsg()
- * has succeeded in sending the message, a DRMSG_ABORT_TEST
- * must be sent.
- */
- if ((msgtype == DRMSG_TESTBOARD) && (err != NULL) &&
- ((mlp->f_error == EINTR) || ((mlp->f_error == ETIMEDOUT) &&
- (mlp->p_flag != 0)))) {
- drmach_msglist_t *abmlp;
- dr_abort_test_t abibuf;
-
- hdrp->command = DRMSG_ABORT_TEST;
- hdrp->message_id = drmach_get_msgid();
- abmlp = drmach_mbox_req_rply(hdrp,
- sizeof (dr_abort_test_t), (caddr_t)&abibuf,
- sizeof (abibuf), drmach_to_aborttest, 5, 1, mlp);
- cmn_err(CE_WARN, "test aborted");
- drmach_msglist_destroy(abmlp);
- }
-
- drmach_msglist_destroy(mlp);
- }
-
- return (err);
-}
-
-static int
-drmach_mbox_init()
-{
- int err;
- caddr_t obufp;
- sbd_error_t *serr = NULL;
- mboxsc_timeout_range_t mbxtoz;
-
- drmach_mbox_istate = 0;
- /* register the outgoing mailbox */
- if ((err = mboxsc_init(KEY_DRSC, MBOXSC_MBOX_OUT,
- NULL)) != 0) {
- cmn_err(CE_WARN, "DR - SC mboxsc_init failed: 0x%x", err);
- return (-1);
- }
- drmach_mbox_istate = 1;
-
- /* setup the mboxsc_putmsg timeout value */
- if (drmach_use_tuned_putmsg_to) {
- cmn_err(CE_NOTE, "!using tuned drmach_to_putmsg = 0x%lx\n",
- drmach_to_putmsg);
- } else {
- if ((err = mboxsc_ctrl(KEY_DRSC,
- MBOXSC_CMD_PUTMSG_TIMEOUT_RANGE, &mbxtoz)) != 0) {
- cmn_err(CE_WARN, "mboxsc_ctrl failed: 0x%x", err);
- drmach_to_putmsg = 60000;
- } else {
- drmach_to_putmsg = mboxsc_putmsg_def_timeout() * 6;
- DRMACH_PR("putmsg range is 0x%lx - 0x%lx value"
- " is 0x%lx\n", mbxtoz.min_timeout,
- mbxtoz.max_timeout, drmach_to_putmsg);
- }
- }
-
- /* register the incoming mailbox */
- if ((err = mboxsc_init(KEY_SCDR, MBOXSC_MBOX_IN,
- drmach_mbox_event)) != 0) {
- cmn_err(CE_WARN, "SC - DR mboxsc_init failed: 0x%x", err);
- return (-1);
- }
- drmach_mbox_istate = 2;
-
- /* initialize mutex for mailbox globals */
- mutex_init(&drmach_g_mbox_mutex, NULL, MUTEX_DRIVER, NULL);
-
- /* initialize mutex for mailbox re-init */
- mutex_init(&drmach_ri_mbox_mutex, NULL, MUTEX_DRIVER, NULL);
-
- /* initialize mailbox message list elements */
- drmach_msglist_first = drmach_msglist_last = NULL;
- mutex_init(&drmach_msglist_mutex, NULL, MUTEX_DRIVER, NULL);
-
- mutex_init(&drmach_sendmsg_mutex, NULL, MUTEX_DRIVER, NULL);
- cv_init(&drmach_sendmsg_cv, NULL, CV_DRIVER, NULL);
-
- drmach_mbox_istate = 3;
-
- /* start mailbox sendmsg thread */
- drmach_sendmsg_thread_run = 1;
- if (drmach_sendmsg_thread == NULL)
- drmach_sendmsg_thread = thread_create(NULL, 0,
- (void (*)())drmach_mbox_sendmsg, NULL, 0, &p0,
- TS_RUN, minclsyspri);
-
- /* start mailbox getmsg thread */
- drmach_getmsg_thread_run = 1;
- if (drmach_getmsg_thread == NULL)
- drmach_getmsg_thread = thread_create(NULL, 0,
- (void (*)())drmach_mbox_getmsg, NULL, 0, &p0,
- TS_RUN, minclsyspri);
-
- obufp = kmem_zalloc(sizeof (dr_proto_hdr_t), KM_SLEEP);
- serr = drmach_mbox_trans(DRMSG_MBOX_INIT, 0, obufp,
- sizeof (dr_proto_hdr_t), (caddr_t)NULL, 0);
- kmem_free(obufp, sizeof (dr_proto_hdr_t));
- if (serr) {
- cmn_err(CE_WARN, "mbox_init: MBOX_INIT failed ecode=0x%x",
- serr->e_code);
- sbd_err_clear(&serr);
- return (-1);
- }
- mutex_enter(&drmach_g_mbox_mutex);
- drmach_mbox_iflag = 1;
- drmach_mbox_ipending = 0;
- mutex_exit(&drmach_g_mbox_mutex);
-
- return (0);
-}
-
-static int
-drmach_mbox_fini()
-{
- int err, rv = 0;
-
- if (drmach_mbox_istate > 2) {
- drmach_getmsg_thread_run = 0;
- drmach_sendmsg_thread_run = 0;
- cmn_err(CE_WARN,
- "drmach_mbox_fini: waiting for mbox threads...");
- while ((drmach_getmsg_thread_run == 0) ||
- (drmach_sendmsg_thread_run == 0)) {
- continue;
- }
- cmn_err(CE_WARN, "drmach_mbox_fini: mbox threads done.");
- mutex_destroy(&drmach_msglist_mutex);
-
- }
- if (drmach_mbox_istate) {
- /* de-register the outgoing mailbox */
- if ((err = mboxsc_fini(KEY_DRSC)) != 0) {
- cmn_err(CE_WARN, "DR - SC mboxsc_fini failed: 0x%x",
- err);
- rv = -1;
- }
- }
- if (drmach_mbox_istate > 1) {
- /* de-register the incoming mailbox */
- if ((err = mboxsc_fini(KEY_SCDR)) != 0) {
- cmn_err(CE_WARN, "SC - DR mboxsc_fini failed: 0x%x",
- err);
- rv = -1;
- }
- }
- mutex_destroy(&drmach_g_mbox_mutex);
- mutex_destroy(&drmach_ri_mbox_mutex);
- return (rv);
-}
-
-static int
-drmach_portid2bnum(int portid)
-{
- int slot;
-
- switch (portid & 0x1f) {
- case 0: case 1: case 2: case 3: /* cpu/wci devices */
- case 0x1e: /* slot 0 axq registers */
- slot = 0;
- break;
-
- case 8: case 9: /* cpu devices */
- case 0x1c: case 0x1d: /* schizo/wci devices */
- case 0x1f: /* slot 1 axq registers */
- slot = 1;
- break;
-
- default:
- ASSERT(0); /* catch in debug kernels */
- }
-
- return (((portid >> 4) & 0x7e) | slot);
-}
-
-extern int axq_suspend_iopause;
-
-static int
-hold_rele_branch(dev_info_t *rdip, void *arg)
-{
- int i;
- int *holdp = (int *)arg;
- char *name = ddi_node_name(rdip);
-
- /*
- * For Starcat, we must be children of the root devinfo node
- */
- ASSERT(ddi_get_parent(rdip) == ddi_root_node());
-
- i = drmach_name2type_idx(name);
-
- /*
- * Only children of the root devinfo node need to be
- * held/released since they are the only valid targets
- * of tree operations. This corresponds to the node types
- * listed in the drmach_name2type array.
- */
- if (i < 0) {
- /* Not of interest to us */
- return (DDI_WALK_PRUNECHILD);
- }
-
- if (*holdp) {
- ASSERT(!e_ddi_branch_held(rdip));
- e_ddi_branch_hold(rdip);
- } else {
- ASSERT(e_ddi_branch_held(rdip));
- e_ddi_branch_rele(rdip);
- }
-
- return (DDI_WALK_PRUNECHILD);
-}
-
-static int
-drmach_init(void)
-{
- pnode_t nodeid;
- gdcd_t *gdcd;
- int bnum;
- dev_info_t *rdip;
- int hold, circ;
-
- mutex_enter(&drmach_i_lock);
- if (drmach_initialized) {
- mutex_exit(&drmach_i_lock);
- return (0);
- }
-
- gdcd = drmach_gdcd_new();
- if (gdcd == NULL) {
- mutex_exit(&drmach_i_lock);
- cmn_err(CE_WARN, "drmach_init: failed to access GDCD\n");
- return (-1);
- }
-
- drmach_boards = drmach_array_new(0, MAX_BOARDS - 1);
-
- nodeid = prom_childnode(prom_rootnode());
- do {
- int len;
- int portid;
- drmachid_t id;
-
- len = prom_getproplen(nodeid, "portid");
- if (len != sizeof (portid))
- continue;
-
- portid = -1;
- (void) prom_getprop(nodeid, "portid", (caddr_t)&portid);
- if (portid == -1)
- continue;
-
- bnum = drmach_portid2bnum(portid);
-
- if (drmach_array_get(drmach_boards, bnum, &id) == -1) {
- /* portid translated to an invalid board number */
- cmn_err(CE_WARN, "OBP node 0x%x has"
- " invalid property value, %s=%u",
- nodeid, "portid", portid);
-
- /* clean up */
- drmach_array_dispose(drmach_boards,
- drmach_board_dispose);
- drmach_gdcd_dispose(gdcd);
- mutex_exit(&drmach_i_lock);
- return (-1);
- } else if (id == NULL) {
- drmach_board_t *bp;
- l1_slot_stat_t *dcd;
- int exp, slot;
-
- bp = drmach_board_new(bnum);
- bp->assigned = !drmach_initialized;
- bp->powered = !drmach_initialized;
-
- exp = DRMACH_BNUM2EXP(bnum);
- slot = DRMACH_BNUM2SLOT(bnum);
- dcd = &gdcd->dcd_slot[exp][slot];
- bp->stardrb_offset =
- dcd->l1ss_cpu_drblock_xwd_offset << 3;
- DRMACH_PR("%s: stardrb_offset=0x%lx\n", bp->cm.name,
- bp->stardrb_offset);
-
- if (gdcd->dcd_slot[exp][slot].l1ss_flags &
- L1SSFLG_THIS_L1_NULL_PROC_LPA) {
- bp->flags |= DRMACH_NULL_PROC_LPA;
- DRMACH_PR("%s: NULL proc LPA\n", bp->cm.name);
- }
- }
- } while ((nodeid = prom_nextnode(nodeid)) != OBP_NONODE);
-
- drmach_cpu_sram_va = vmem_alloc(heap_arena, PAGESIZE, VM_SLEEP);
-
- if (gdcd->dcd_testcage_log2_mbytes_size != DCD_DR_TESTCAGE_DISABLED) {
- ASSERT(gdcd->dcd_testcage_log2_mbytes_size ==
- gdcd->dcd_testcage_log2_mbytes_align);
- drmach_iocage_paddr =
- (uint64_t)gdcd->dcd_testcage_mbyte_PA << 20;
- drmach_iocage_size =
- 1 << (gdcd->dcd_testcage_log2_mbytes_size + 20);
-
- drmach_iocage_vaddr = (caddr_t)vmem_alloc(heap_arena,
- drmach_iocage_size, VM_SLEEP);
- hat_devload(kas.a_hat, drmach_iocage_vaddr, drmach_iocage_size,
- mmu_btop(drmach_iocage_paddr),
- PROT_READ | PROT_WRITE,
- HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST);
-
- DRMACH_PR("gdcd size=0x%x align=0x%x PA=0x%x\n",
- gdcd->dcd_testcage_log2_mbytes_size,
- gdcd->dcd_testcage_log2_mbytes_align,
- gdcd->dcd_testcage_mbyte_PA);
- DRMACH_PR("drmach size=0x%x PA=0x%lx VA=0x%p\n",
- drmach_iocage_size, drmach_iocage_paddr,
- (void *)drmach_iocage_vaddr);
- }
-
- if (drmach_iocage_size == 0) {
- drmach_array_dispose(drmach_boards, drmach_board_dispose);
- drmach_boards = NULL;
- vmem_free(heap_arena, drmach_cpu_sram_va, PAGESIZE);
- drmach_gdcd_dispose(gdcd);
- mutex_exit(&drmach_i_lock);
- cmn_err(CE_WARN, "drmach_init: iocage not available\n");
- return (-1);
- }
-
- drmach_gdcd_dispose(gdcd);
-
- mutex_init(&drmach_iocage_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&drmach_iocage_cv, NULL, CV_DRIVER, NULL);
- mutex_init(&drmach_xt_mb_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&drmach_bus_sync_lock, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&drmach_slice_table_lock, NULL, MUTEX_DRIVER, NULL);
-
- mutex_enter(&cpu_lock);
- mutex_enter(&drmach_iocage_lock);
- ASSERT(drmach_iocage_is_busy == 0);
- drmach_iocage_is_busy = 1;
- drmach_iocage_mem_scrub(drmach_iocage_size);
- drmach_iocage_is_busy = 0;
- cv_signal(&drmach_iocage_cv);
- mutex_exit(&drmach_iocage_lock);
- mutex_exit(&cpu_lock);
-
-
- if (drmach_mbox_init() == -1) {
- cmn_err(CE_WARN, "DR - SC mailbox initialization Failed");
- }
-
- /*
- * Walk immediate children of devinfo root node and hold
- * all devinfo branches of interest.
- */
- hold = 1;
- rdip = ddi_root_node();
-
- ndi_devi_enter(rdip, &circ);
- ddi_walk_devs(ddi_get_child(rdip), hold_rele_branch, &hold);
- ndi_devi_exit(rdip, circ);
-
- drmach_initialized = 1;
-
- /*
- * To avoid a circular patch dependency between DR and AXQ, the AXQ
- * rev introducing the axq_iopause_*_all interfaces should not regress
- * when installed without the DR rev using those interfaces. The default
- * is for iopause to be enabled/disabled during axq suspend/resume. By
- * setting the following axq flag to zero, axq will not enable iopause
- * during suspend/resume, instead DR will call the axq_iopause_*_all
- * interfaces during drmach_copy_rename.
- */
- axq_suspend_iopause = 0;
-
- mutex_exit(&drmach_i_lock);
-
- return (0);
-}
-
-static void
-drmach_fini(void)
-{
- dev_info_t *rdip;
- int hold, circ;
-
- if (drmach_initialized) {
- rw_enter(&drmach_boards_rwlock, RW_WRITER);
- drmach_array_dispose(drmach_boards, drmach_board_dispose);
- drmach_boards = NULL;
- rw_exit(&drmach_boards_rwlock);
-
- mutex_destroy(&drmach_slice_table_lock);
- mutex_destroy(&drmach_xt_mb_lock);
- mutex_destroy(&drmach_bus_sync_lock);
- cv_destroy(&drmach_iocage_cv);
- mutex_destroy(&drmach_iocage_lock);
-
- vmem_free(heap_arena, drmach_cpu_sram_va, PAGESIZE);
-
- /*
- * Walk immediate children of the root devinfo node
- * releasing holds acquired on branches in drmach_init()
- */
- hold = 0;
- rdip = ddi_root_node();
-
- ndi_devi_enter(rdip, &circ);
- ddi_walk_devs(ddi_get_child(rdip), hold_rele_branch, &hold);
- ndi_devi_exit(rdip, circ);
-
- drmach_initialized = 0;
- }
-
- (void) drmach_mbox_fini();
- if (drmach_xt_mb != NULL) {
- vmem_free(static_alloc_arena, (void *)drmach_xt_mb,
- drmach_xt_mb_size);
- }
- rw_destroy(&drmach_boards_rwlock);
- mutex_destroy(&drmach_i_lock);
-}
-
-static void
-drmach_mem_read_madr(drmach_mem_t *mp, int bank, uint64_t *madr)
-{
- kpreempt_disable();
-
- /* get register address, read madr value */
- if (STARCAT_CPUID_TO_PORTID(CPU->cpu_id) == mp->dev.portid) {
- *madr = lddmcdecode(DRMACH_MC_ASI_ADDR(mp, bank));
- } else {
- *madr = lddphysio(DRMACH_MC_ADDR(mp, bank));
- }
-
- kpreempt_enable();
-}
-
-
-static uint64_t *
-drmach_prep_mc_rename(uint64_t *p, int local,
- drmach_mem_t *mp, uint64_t current_basepa, uint64_t new_basepa)
-{
- int bank;
-
- for (bank = 0; bank < DRMACH_MC_NBANKS; bank++) {
- uint64_t madr, bank_offset;
-
- /* fetch mc's bank madr register value */
- drmach_mem_read_madr(mp, bank, &madr);
- if (madr & DRMACH_MC_VALID_MASK) {
- uint64_t bankpa;
-
- bank_offset = (DRMACH_MC_UM_TO_PA(madr) |
- DRMACH_MC_LM_TO_PA(madr)) - current_basepa;
- bankpa = new_basepa + bank_offset;
-
- /* encode new base pa into madr */
- madr &= ~DRMACH_MC_UM_MASK;
- madr |= DRMACH_MC_PA_TO_UM(bankpa);
- madr &= ~DRMACH_MC_LM_MASK;
- madr |= DRMACH_MC_PA_TO_LM(bankpa);
-
- if (local)
- *p++ = DRMACH_MC_ASI_ADDR(mp, bank);
- else
- *p++ = DRMACH_MC_ADDR(mp, bank);
-
- *p++ = madr;
- }
- }
-
- return (p);
-}
-
-static uint64_t *
-drmach_prep_schizo_script(uint64_t *p, drmach_mem_t *mp, uint64_t new_basepa)
-{
- drmach_board_t *bp;
- int rv;
- int idx;
- drmachid_t id;
- uint64_t last_scsr_pa = 0;
-
- /* memory is always in slot 0 */
- ASSERT(DRMACH_BNUM2SLOT(mp->dev.bp->bnum) == 0);
-
- /* look up slot 1 board on same expander */
- idx = DRMACH_EXPSLOT2BNUM(DRMACH_BNUM2EXP(mp->dev.bp->bnum), 1);
- rv = drmach_array_get(drmach_boards, idx, &id);
- bp = id; /* bp will be NULL if board not found */
-
- /* look up should never be out of bounds */
- ASSERT(rv == 0);
-
- /* nothing to do when board is not found or has no devices */
- if (rv == -1 || bp == NULL || bp->devices == NULL)
- return (p);
-
- rv = drmach_array_first(bp->devices, &idx, &id);
- while (rv == 0) {
- if (DRMACH_IS_IO_ID(id)) {
- drmach_io_t *io = id;
-
- /*
- * Skip all non-Schizo IO devices (only IO nodes
- * that are Schizo devices have non-zero scsr_pa).
- * Filter out "other" leaf to avoid writing to the
- * same Schizo Control/Status Register twice.
- */
- if (io->scsr_pa && io->scsr_pa != last_scsr_pa) {
- uint64_t scsr;
-
- scsr = lddphysio(io->scsr_pa);
- scsr &= ~(DRMACH_LPA_BASE_MASK |
- DRMACH_LPA_BND_MASK);
- scsr |= DRMACH_PA_TO_LPA_BASE(new_basepa);
- scsr |= DRMACH_PA_TO_LPA_BND(
- new_basepa + DRMACH_MEM_SLICE_SIZE);
-
- *p++ = io->scsr_pa;
- *p++ = scsr;
-
- last_scsr_pa = io->scsr_pa;
- }
- }
- rv = drmach_array_next(bp->devices, &idx, &id);
- }
-
- return (p);
-}
-
-/*
- * For Panther MCs, append the MC idle reg address and drmach_mem_t pointer.
- * The latter is returned when drmach_rename fails to idle a Panther MC and
- * is used to identify the MC for error reporting.
- */
-static uint64_t *
-drmach_prep_pn_mc_idle(uint64_t *p, drmach_mem_t *mp, int local)
-{
- /* only slot 0 has memory */
- ASSERT(DRMACH_BNUM2SLOT(mp->dev.bp->bnum) == 0);
- ASSERT(IS_PANTHER(mp->dev.bp->cpu_impl));
-
- for (mp = mp->dev.bp->mem; mp != NULL; mp = mp->next) {
- ASSERT(DRMACH_IS_MEM_ID(mp));
-
- if (mp->dev.portid == STARCAT_CPUID_TO_PORTID(CPU->cpu_id)) {
- if (local) {
- *p++ = ASI_EMU_ACT_STATUS_VA; /* local ASI */
- *p++ = (uintptr_t)mp;
- }
- } else if (!local) {
- *p++ = DRMACH_EMU_ACT_STATUS_ADDR(mp); /* PIO */
- *p++ = (uintptr_t)mp;
- }
- }
-
- return (p);
-}
-
-static sbd_error_t *
-drmach_prep_rename_script(drmach_mem_t *s_mp, drmach_mem_t *t_mp,
- uint64_t t_slice_offset, caddr_t buf, int buflen)
-{
- _NOTE(ARGUNUSED(buflen))
-
- uint64_t *p = (uint64_t *)buf, *q;
- sbd_error_t *err;
- int rv;
- drmach_mem_t *mp, *skip_mp;
- uint64_t s_basepa, t_basepa;
- uint64_t s_new_basepa, t_new_basepa;
-
- /* verify supplied buffer space is adequate */
- ASSERT(buflen >=
- /* addr for all possible MC banks */
- (sizeof (uint64_t) * 4 * 4 * 18) +
- /* list section terminator */
- (sizeof (uint64_t) * 1) +
- /* addr/id tuple for local Panther MC idle reg */
- (sizeof (uint64_t) * 2) +
- /* list section terminator */
- (sizeof (uint64_t) * 1) +
- /* addr/id tuple for 2 boards with 4 Panther MC idle regs */
- (sizeof (uint64_t) * 2 * 2 * 4) +
- /* list section terminator */
- (sizeof (uint64_t) * 1) +
- /* addr/val tuple for 1 proc with 4 MC banks */
- (sizeof (uint64_t) * 2 * 4) +
- /* list section terminator */
- (sizeof (uint64_t) * 1) +
- /* addr/val tuple for 2 boards w/ 2 schizos each */
- (sizeof (uint64_t) * 2 * 2 * 2) +
- /* addr/val tuple for 2 boards w/ 16 MC banks each */
- (sizeof (uint64_t) * 2 * 2 * 16) +
- /* list section terminator */
- (sizeof (uint64_t) * 1) +
- /* addr/val tuple for 18 AXQs w/ two slots each */
- (sizeof (uint64_t) * 2 * 2 * 18) +
- /* list section terminator */
- (sizeof (uint64_t) * 1) +
- /* list terminator */
- (sizeof (uint64_t) * 1));
-
- /* copy bank list to rename script */
- mutex_enter(&drmach_bus_sync_lock);
- for (q = drmach_bus_sync_list; *q; q++, p++)
- *p = *q;
- mutex_exit(&drmach_bus_sync_lock);
-
- /* list section terminator */
- *p++ = 0;
-
- /*
- * Write idle script for MC on this processor. A script will be
- * produced only if this is a Panther processor on the source or
- * target board.
- */
- if (IS_PANTHER(s_mp->dev.bp->cpu_impl))
- p = drmach_prep_pn_mc_idle(p, s_mp, 1);
-
- if (IS_PANTHER(t_mp->dev.bp->cpu_impl))
- p = drmach_prep_pn_mc_idle(p, t_mp, 1);
-
- /* list section terminator */
- *p++ = 0;
-
- /*
- * Write idle script for all other MCs on source and target
- * Panther boards.
- */
- if (IS_PANTHER(s_mp->dev.bp->cpu_impl))
- p = drmach_prep_pn_mc_idle(p, s_mp, 0);
-
- if (IS_PANTHER(t_mp->dev.bp->cpu_impl))
- p = drmach_prep_pn_mc_idle(p, t_mp, 0);
-
- /* list section terminator */
- *p++ = 0;
-
- /*
- * Step 1: Write source base address to target MC
- * with present bit off.
- * Step 2: Now rewrite target reg with present bit on.
- */
- err = drmach_mem_get_base_physaddr(s_mp, &s_basepa);
- ASSERT(err == NULL);
- err = drmach_mem_get_base_physaddr(t_mp, &t_basepa);
- ASSERT(err == NULL);
-
- /* exchange base pa. include slice offset in new target base pa */
- s_new_basepa = t_basepa & ~ (DRMACH_MEM_SLICE_SIZE - 1);
- t_new_basepa = (s_basepa & ~ (DRMACH_MEM_SLICE_SIZE - 1)) +
- t_slice_offset;
-
- DRMACH_PR("s_new_basepa 0x%lx\n", s_new_basepa);
- DRMACH_PR("t_new_basepa 0x%lx\n", t_new_basepa);
-
- DRMACH_PR("preparing MC MADR rename script (master is CPU%d):\n",
- CPU->cpu_id);
-
- /*
- * Write rename script for MC on this processor. A script will
- * be produced only if this processor is on the source or target
- * board.
- */
-
- skip_mp = NULL;
- mp = s_mp->dev.bp->mem;
- while (mp != NULL && skip_mp == NULL) {
- if (mp->dev.portid == STARCAT_CPUID_TO_PORTID(CPU->cpu_id)) {
- skip_mp = mp;
- p = drmach_prep_mc_rename(p, 1, mp, s_basepa,
- s_new_basepa);
- }
-
- mp = mp->next;
- }
-
- mp = t_mp->dev.bp->mem;
- while (mp != NULL && skip_mp == NULL) {
- if (mp->dev.portid == STARCAT_CPUID_TO_PORTID(CPU->cpu_id)) {
- skip_mp = mp;
- p = drmach_prep_mc_rename(p, 1, mp, t_basepa,
- t_new_basepa);
- }
-
- mp = mp->next;
- }
-
- /* list section terminator */
- *p++ = 0;
-
- /*
- * Write rename script for all other MCs on source and target
- * boards.
- */
-
- for (mp = s_mp->dev.bp->mem; mp; mp = mp->next) {
- if (mp == skip_mp)
- continue;
- p = drmach_prep_mc_rename(p, 0, mp, s_basepa, s_new_basepa);
- }
-
- for (mp = t_mp->dev.bp->mem; mp; mp = mp->next) {
- if (mp == skip_mp)
- continue;
- p = drmach_prep_mc_rename(p, 0, mp, t_basepa, t_new_basepa);
- }
-
- /* Write rename script for Schizo LPA_BASE/LPA_BND */
- p = drmach_prep_schizo_script(p, s_mp, s_new_basepa);
- p = drmach_prep_schizo_script(p, t_mp, t_new_basepa);
-
- /* list section terminator */
- *p++ = 0;
-
- DRMACH_PR("preparing AXQ CASM rename script (EXP%d <> EXP%d):\n",
- DRMACH_BNUM2EXP(s_mp->dev.bp->bnum),
- DRMACH_BNUM2EXP(t_mp->dev.bp->bnum));
-
- rv = axq_do_casm_rename_script(&p,
- DRMACH_PA_TO_SLICE(s_new_basepa),
- DRMACH_PA_TO_SLICE(t_new_basepa));
- if (rv == DDI_FAILURE)
- return (DRMACH_INTERNAL_ERROR());
-
- /* list section & final terminator */
- *p++ = 0;
- *p++ = 0;
-
-#ifdef DEBUG
- {
- uint64_t *q = (uint64_t *)buf;
-
- /* paranoia */
- ASSERT((caddr_t)p <= buf + buflen);
-
- DRMACH_PR("MC bank base pa list:\n");
- while (*q) {
- uint64_t a = *q++;
-
- DRMACH_PR("0x%lx\n", a);
- }
-
- /* skip terminator */
- q += 1;
-
- DRMACH_PR("local Panther MC idle reg (via ASI 0x4a):\n");
- while (*q) {
- DRMACH_PR("addr=0x%lx, mp=0x%lx\n", *q, *(q + 1));
- q += 2;
- }
-
- /* skip terminator */
- q += 1;
-
- DRMACH_PR("non-local Panther MC idle reg (via ASI 0x15):\n");
- while (*q) {
- DRMACH_PR("addr=0x%lx, mp=0x%lx\n", *q, *(q + 1));
- q += 2;
- }
-
- /* skip terminator */
- q += 1;
-
- DRMACH_PR("MC reprogramming script (via ASI 0x72):\n");
- while (*q) {
- uint64_t r = *q++; /* register address */
- uint64_t v = *q++; /* new register value */
-
- DRMACH_PR("0x%lx = 0x%lx, basepa 0x%lx\n",
- r, v, (long)(DRMACH_MC_UM_TO_PA(v)|
- DRMACH_MC_LM_TO_PA(v)));
- }
-
- /* skip terminator */
- q += 1;
-
- DRMACH_PR("MC/SCHIZO reprogramming script:\n");
- while (*q) {
- DRMACH_PR("0x%lx = 0x%lx\n", *q, *(q + 1));
- q += 2;
- }
-
- /* skip terminator */
- q += 1;
-
- DRMACH_PR("AXQ reprogramming script:\n");
- while (*q) {
- DRMACH_PR("0x%lx = 0x%lx\n", *q, *(q + 1));
- q += 2;
- }
-
- /* verify final terminator is present */
- ASSERT(*(q + 1) == 0);
-
- DRMACH_PR("copy-rename script 0x%p, len %d\n",
- (void *)buf, (int)((intptr_t)p - (intptr_t)buf));
-
- if (drmach_debug)
- DELAY(10000000);
- }
-#endif
-
- return (NULL);
-}
-
-static void
-drmach_prep_xt_mb_for_slice_update(drmach_board_t *bp, uchar_t slice)
-{
- int rv;
-
- ASSERT(MUTEX_HELD(&drmach_xt_mb_lock));
-
- if (bp->devices) {
- int d_idx;
- drmachid_t d_id;
-
- rv = drmach_array_first(bp->devices, &d_idx, &d_id);
- while (rv == 0) {
- if (DRMACH_IS_CPU_ID(d_id)) {
- drmach_cpu_t *cp = d_id;
- processorid_t cpuid = cp->cpuid;
-
- mutex_enter(&cpu_lock);
- if (cpu[cpuid] && cpu[cpuid]->cpu_flags)
- drmach_xt_mb[cpuid] = 0x80 | slice;
- mutex_exit(&cpu_lock);
- }
- rv = drmach_array_next(bp->devices, &d_idx, &d_id);
- }
- }
- if (DRMACH_BNUM2SLOT(bp->bnum) == 0) {
- drmach_board_t *s1bp = NULL;
-
- rv = drmach_array_get(drmach_boards, bp->bnum + 1,
- (void *) &s1bp);
- if (rv == 0 && s1bp != NULL) {
- ASSERT(DRMACH_IS_BOARD_ID(s1bp));
- ASSERT(DRMACH_BNUM2SLOT(s1bp->bnum) == 1);
- drmach_prep_xt_mb_for_slice_update(s1bp, slice);
- }
- }
-}
-
-sbd_error_t *
-drmach_copy_rename_init(drmachid_t t_id, uint64_t t_slice_offset,
- drmachid_t s_id, struct memlist *c_ml, drmachid_t *cr_id)
-{
- extern void drmach_rename(uint64_t *, uint_t *, uint64_t *);
- extern void drmach_rename_end(void);
-
- drmach_mem_t *s_mp, *t_mp;
- struct memlist *x_ml;
- uint64_t off_mask, s_copybasepa, t_copybasepa, t_basepa;
- int len;
- caddr_t bp, wp;
- uint_t *p, *q;
- sbd_error_t *err;
- tte_t *tte;
- drmach_copy_rename_t *cr;
-
- if (!DRMACH_IS_MEM_ID(s_id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- if (!DRMACH_IS_MEM_ID(t_id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- s_mp = s_id;
- t_mp = t_id;
-
- /* get starting physical address of target memory */
- err = drmach_mem_get_base_physaddr(t_id, &t_basepa);
- if (err)
- return (err);
-
- /* calculate slice offset mask from slice size */
- off_mask = DRMACH_MEM_SLICE_SIZE - 1;
-
- /* calculate source and target base pa */
- s_copybasepa = c_ml->ml_address;
- t_copybasepa =
- t_basepa + ((c_ml->ml_address & off_mask) - t_slice_offset);
-
- /* paranoia */
- ASSERT((c_ml->ml_address & off_mask) >= t_slice_offset);
-
- /* adjust copy memlist addresses to be relative to copy base pa */
- x_ml = c_ml;
- while (x_ml != NULL) {
- x_ml->ml_address -= s_copybasepa;
- x_ml = x_ml->ml_next;
- }
-
-#ifdef DEBUG
- {
- uint64_t s_basepa, s_size, t_size;
-
- x_ml = c_ml;
- while (x_ml->ml_next != NULL)
- x_ml = x_ml->ml_next;
-
- DRMACH_PR("source copy span: base pa 0x%lx, end pa 0x%lx\n",
- s_copybasepa,
- s_copybasepa + x_ml->ml_address + x_ml->ml_size);
-
- DRMACH_PR("target copy span: base pa 0x%lx, end pa 0x%lx\n",
- t_copybasepa,
- t_copybasepa + x_ml->ml_address + x_ml->ml_size);
-
- DRMACH_PR("copy memlist (relative to copy base pa):\n");
- DRMACH_MEMLIST_DUMP(c_ml);
-
- err = drmach_mem_get_base_physaddr(s_id, &s_basepa);
- ASSERT(err == NULL);
-
- err = drmach_mem_get_size(s_id, &s_size);
- ASSERT(err == NULL);
-
- err = drmach_mem_get_size(t_id, &t_size);
- ASSERT(err == NULL);
-
- DRMACH_PR("current source base pa 0x%lx, size 0x%lx\n",
- s_basepa, s_size);
- DRMACH_PR("current target base pa 0x%lx, size 0x%lx\n",
- t_basepa, t_size);
- }
-#endif /* DEBUG */
-
- /* Map in appropriate cpu sram page */
- tte = &drmach_cpu_sram_tte[CPU->cpu_id];
- ASSERT(TTE_IS_VALID(tte) && TTE_IS_8K(tte) &&
- TTE_IS_PRIVILEGED(tte) && TTE_IS_LOCKED(tte));
- sfmmu_dtlb_ld_kva(drmach_cpu_sram_va, tte);
- sfmmu_itlb_ld_kva(drmach_cpu_sram_va, tte);
-
- bp = wp = drmach_cpu_sram_va;
-
- /* Make sure the rename routine will fit */
- len = (ptrdiff_t)drmach_rename_end - (ptrdiff_t)drmach_rename;
- ASSERT(wp + len < bp + PAGESIZE);
-
- /* copy text. standard bcopy not designed to work in nc space */
- p = (uint_t *)wp;
- q = (uint_t *)drmach_rename;
- while (q < (uint_t *)drmach_rename_end)
- *p++ = *q++;
-
- /* zero remainder. standard bzero not designed to work in nc space */
- while (p < (uint_t *)(bp + PAGESIZE))
- *p++ = 0;
-
- DRMACH_PR("drmach_rename function 0x%p, len %d\n", (void *)wp, len);
- wp += (len + 15) & ~15;
-
- err = drmach_prep_rename_script(s_mp, t_mp, t_slice_offset, wp,
- PAGESIZE - (wp - bp));
- if (err) {
-cleanup:
- xt_one(CPU->cpu_id, vtag_flushpage_tl1,
- (uint64_t)drmach_cpu_sram_va, (uint64_t)ksfmmup);
- return (err);
- }
-
- /* disable and flush CDC */
- if (axq_cdc_disable_flush_all() != DDI_SUCCESS) {
- axq_cdc_enable_all(); /* paranoia */
- err = DRMACH_INTERNAL_ERROR();
- goto cleanup;
- }
-
- /* mark both memory units busy */
- t_mp->dev.busy++;
- s_mp->dev.busy++;
-
- cr = vmem_alloc(static_alloc_arena, sizeof (drmach_copy_rename_t),
- VM_SLEEP);
- cr->isa = (void *)drmach_copy_rename_init;
- cr->data = wp;
- cr->c_ml = c_ml;
- cr->s_mp = s_mp;
- cr->t_mp = t_mp;
- cr->s_copybasepa = s_copybasepa;
- cr->t_copybasepa = t_copybasepa;
- cr->ecode = DRMACH_CR_OK;
-
- mutex_enter(&drmach_slice_table_lock);
-
- mutex_enter(&drmach_xt_mb_lock);
- bzero((void *)drmach_xt_mb, drmach_xt_mb_size);
-
- if (DRMACH_L1_SET_LPA(s_mp->dev.bp) && drmach_reprogram_lpa) {
- drmach_prep_xt_mb_for_slice_update(s_mp->dev.bp,
- DRMACH_PA_TO_SLICE(t_copybasepa));
- }
- if (DRMACH_L1_SET_LPA(t_mp->dev.bp) && drmach_reprogram_lpa) {
- drmach_prep_xt_mb_for_slice_update(t_mp->dev.bp,
- DRMACH_PA_TO_SLICE(s_copybasepa));
- }
-
- *cr_id = cr;
- return (NULL);
-}
-
-int drmach_rename_count;
-int drmach_rename_ntries;
-
-sbd_error_t *
-drmach_copy_rename_fini(drmachid_t id)
-{
- drmach_copy_rename_t *cr = id;
- sbd_error_t *err = NULL;
- dr_mbox_msg_t *obufp;
-
- ASSERT(cr->isa == (void *)drmach_copy_rename_init);
-
- axq_cdc_enable_all();
-
- xt_one(CPU->cpu_id, vtag_flushpage_tl1,
- (uint64_t)drmach_cpu_sram_va, (uint64_t)ksfmmup);
-
- switch (cr->ecode) {
- case DRMACH_CR_OK:
- break;
- case DRMACH_CR_MC_IDLE_ERR: {
- dev_info_t *dip = NULL;
- drmach_mem_t *mp = (drmach_mem_t *)cr->earg;
- char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
-
- ASSERT(DRMACH_IS_MEM_ID(mp));
-
- err = drmach_get_dip(mp, &dip);
-
- ASSERT(err == NULL);
- ASSERT(dip != NULL);
-
- err = drerr_new(0, ESBD_MEMFAIL, NULL);
- (void) ddi_pathname(dip, path);
- cmn_err(CE_WARN, "failed to idle memory controller %s on %s: "
- "copy-rename aborted", path, mp->dev.bp->cm.name);
- kmem_free(path, MAXPATHLEN);
- break;
- }
- case DRMACH_CR_IOPAUSE_ERR:
- ASSERT((uintptr_t)cr->earg >= 0 &&
- (uintptr_t)cr->earg < AXQ_MAX_EXP);
-
- err = drerr_new(0, ESBD_SUSPEND, "EX%d", (uintptr_t)cr->earg);
- cmn_err(CE_WARN, "failed to idle EX%ld AXQ slot1 activity prior"
- " to copy-rename", (uintptr_t)cr->earg);
- break;
- case DRMACH_CR_ONTRAP_ERR:
- err = drerr_new(0, ESBD_MEMFAIL, NULL);
- cmn_err(CE_WARN, "copy-rename aborted due to uncorrectable "
- "memory error");
- break;
- default:
- err = DRMACH_INTERNAL_ERROR();
- cmn_err(CE_WARN, "unknown copy-rename error code (%d)\n",
- cr->ecode);
- break;
- }
-
-#ifdef DEBUG
- if ((DRMACH_L1_SET_LPA(cr->s_mp->dev.bp) ||
- DRMACH_L1_SET_LPA(cr->t_mp->dev.bp)) && drmach_reprogram_lpa) {
- int i;
- for (i = 0; i < NCPU; i++) {
- if (drmach_xt_mb[i])
- DRMACH_PR("cpu%d ignored drmach_xt_mb", i);
- }
- }
-#endif
- mutex_exit(&drmach_xt_mb_lock);
-
- if (cr->c_ml != NULL)
- memlist_delete(cr->c_ml);
-
- cr->t_mp->dev.busy--;
- cr->s_mp->dev.busy--;
-
- if (err) {
- mutex_exit(&drmach_slice_table_lock);
- goto done;
- }
-
- /* update casm shadow for target and source board */
- drmach_slice_table_update(cr->t_mp->dev.bp, 0);
- drmach_slice_table_update(cr->s_mp->dev.bp, 0);
- mutex_exit(&drmach_slice_table_lock);
-
- mutex_enter(&drmach_bus_sync_lock);
- drmach_bus_sync_list_update();
- mutex_exit(&drmach_bus_sync_lock);
-
- /*
- * Make a good-faith effort to notify the SC about the copy-rename, but
- * don't worry if it fails, since a subsequent claim/unconfig/unclaim
- * will duplicate the update.
- */
- obufp = kmem_zalloc(sizeof (dr_mbox_msg_t), KM_SLEEP);
- mutex_enter(&drmach_slice_table_lock);
- drmach_msg_memslice_init(obufp->msgdata.dm_uc.mem_slice);
- drmach_msg_memregs_init(obufp->msgdata.dm_uc.mem_regs);
- mutex_exit(&drmach_slice_table_lock);
- (void) drmach_mbox_trans(DRMSG_UNCONFIG, cr->s_mp->dev.bp->bnum,
- (caddr_t)obufp, sizeof (dr_mbox_msg_t), (caddr_t)NULL, 0);
- kmem_free(obufp, sizeof (dr_mbox_msg_t));
-
-done:
- vmem_free(static_alloc_arena, cr, sizeof (drmach_copy_rename_t));
-
- DRMACH_PR("waited %d out of %d tries for drmach_rename_wait on %d cpus",
- drmach_rename_ntries, drmach_cpu_ntries, drmach_rename_count);
-
- return (err);
-}
-
-int drmach_slow_copy = 0;
-
-void
-drmach_copy_rename(drmachid_t id)
-{
- extern uint_t getpstate(void);
- extern void setpstate(uint_t);
-
- extern xcfunc_t drmach_rename_wait;
- extern xcfunc_t drmach_rename_done;
- extern xcfunc_t drmach_rename_abort;
-
- drmach_copy_rename_t *cr = id;
- uint64_t neer;
- struct memlist *ml;
- int i, count;
- int csize, lnsize;
- uint64_t caddr;
- cpuset_t cpuset;
- uint_t pstate;
- uint32_t exp = 0;
- on_trap_data_t otd;
- xcfunc_t *drmach_end_wait_xcall = drmach_rename_done;
-
- ASSERT(cr->isa == (void *)drmach_copy_rename_init);
- ASSERT(MUTEX_HELD(&cpu_lock));
- ASSERT(cr->ecode == DRMACH_CR_OK);
-
- /*
- * Prevent slot1 IO from accessing Safari memory bus.
- */
- if (axq_iopause_enable_all(&exp) != DDI_SUCCESS) {
- ASSERT(exp >= 0 && exp < AXQ_MAX_EXP);
- cr->ecode = DRMACH_CR_IOPAUSE_ERR;
- cr->earg = (void *)(uintptr_t)exp;
- return;
- }
-
- cpuset = cpu_ready_set;
- CPUSET_DEL(cpuset, CPU->cpu_id);
- count = ncpus - 1;
- drmach_rename_count = count; /* for debug */
-
- drmach_xt_ready = 0;
- xt_some(cpuset, drmach_rename_wait, NULL, NULL);
-
- for (i = 0; i < drmach_cpu_ntries; i++) {
- if (drmach_xt_ready == count)
- break;
- DELAY(drmach_cpu_delay);
- }
-
- drmach_rename_ntries = i; /* for debug */
-
- drmach_xt_ready = 0; /* steal the line back */
- for (i = 0; i < NCPU; i++) /* steal the line back, preserve data */
- drmach_xt_mb[i] = drmach_xt_mb[i];
-
- caddr = drmach_iocage_paddr;
- csize = cpunodes[CPU->cpu_id].ecache_size;
- lnsize = cpunodes[CPU->cpu_id].ecache_linesize;
-
- /* disable CE reporting */
- neer = get_error_enable();
- set_error_enable(neer & ~EN_REG_CEEN);
-
- /* disable interrupts (paranoia) */
- pstate = getpstate();
- setpstate(pstate & ~PSTATE_IE);
-
- /*
- * Execute copy-rename under on_trap to protect against a panic due
- * to an uncorrectable error. Instead, DR will abort the copy-rename
- * operation and rely on the OS to do the error reporting.
- *
- * In general, trap handling on any cpu once the copy begins
- * can result in an inconsistent memory image on the target.
- */
- if (on_trap(&otd, OT_DATA_EC)) {
- cr->ecode = DRMACH_CR_ONTRAP_ERR;
- goto copy_rename_end;
- }
-
- /*
- * DO COPY.
- */
- for (ml = cr->c_ml; ml; ml = ml->ml_next) {
- uint64_t s_pa, t_pa;
- uint64_t nbytes;
-
- s_pa = cr->s_copybasepa + ml->ml_address;
- t_pa = cr->t_copybasepa + ml->ml_address;
- nbytes = ml->ml_size;
-
- while (nbytes != 0ull) {
- /* copy 32 bytes at src_pa to dst_pa */
- bcopy32_il(s_pa, t_pa);
-
- /* increment by 32 bytes */
- s_pa += (4 * sizeof (uint64_t));
- t_pa += (4 * sizeof (uint64_t));
-
- /* decrement by 32 bytes */
- nbytes -= (4 * sizeof (uint64_t));
-
- if (drmach_slow_copy) { /* for debug */
- uint64_t i = 13 * 50;
- while (i--)
- ;
- }
- }
- }
-
- /*
- * XXX CHEETAH SUPPORT
- * For cheetah, we need to grab the iocage lock since iocage
- * memory is used for e$ flush.
- *
- * NOTE: This code block is dangerous at this point in the
- * copy-rename operation. It modifies memory after the copy
- * has taken place which means that any persistent state will
- * be abandoned after the rename operation. The code is also
- * performing thread synchronization at a time when all but
- * one processors are paused. This is a potential deadlock
- * situation.
- *
- * This code block must be moved to drmach_copy_rename_init.
- */
- if (drmach_is_cheetah) {
- mutex_enter(&drmach_iocage_lock);
- while (drmach_iocage_is_busy)
- cv_wait(&drmach_iocage_cv, &drmach_iocage_lock);
- drmach_iocage_is_busy = 1;
- drmach_iocage_mem_scrub(ecache_size * 2);
- mutex_exit(&drmach_iocage_lock);
- }
-
- /*
- * bcopy32_il is implemented as a series of ldxa/stxa via
- * ASI_MEM instructions. Following the copy loop, the E$
- * of the master (this) processor will have lines in state
- * O that correspond to lines of home memory in state gI.
- * An E$ flush is necessary to commit these lines before
- * proceeding with the rename operation.
- *
- * Flushing the E$ will automatically flush the W$, but
- * the D$ and I$ must be flushed separately and explicitly.
- */
- flush_ecache_il(caddr, csize, lnsize); /* inline version */
-
- /*
- * Each line of home memory is now in state gM, except in
- * the case of a cheetah processor when the E$ flush area
- * is included within the copied region. In such a case,
- * the lines of home memory for the upper half of the
- * flush area are in state gS.
- *
- * Each line of target memory is in state gM.
- *
- * Each line of this processor's E$ is in state I, except
- * those of a cheetah processor. All lines of a cheetah
- * processor's E$ are in state S and correspond to the lines
- * in upper half of the E$ flush area.
- *
- * It is vital at this point that none of the lines in the
- * home or target memories are in state gI and that none
- * of the lines in this processor's E$ are in state O or Os.
- * A single instance of such a condition will cause loss of
- * coherency following the rename operation.
- */
-
- /*
- * Rename
- */
- (*(void(*)())drmach_cpu_sram_va)(cr->data, &cr->ecode, &cr->earg);
-
- /*
- * Rename operation complete. The physical address space
- * of the home and target memories have been swapped, the
- * routing data in the respective CASM entries have been
- * swapped, and LPA settings in the processor and schizo
- * devices have been reprogrammed accordingly.
- *
- * In the case of a cheetah processor, the E$ remains
- * populated with lines in state S that correspond to the
- * lines in the former home memory. Now that the physical
- * addresses have been swapped, these E$ lines correspond
- * to lines in the new home memory which are in state gM.
- * This combination is invalid. An additional E$ flush is
- * necessary to restore coherency. The E$ flush will cause
- * the lines of the new home memory for the flush region
- * to transition from state gM to gS. The former home memory
- * remains unmodified. This additional E$ flush has no effect
- * on a cheetah+ processor.
- */
- flush_ecache_il(caddr, csize, lnsize); /* inline version */
-
- /*
- * The D$ and I$ must be flushed to ensure that coherency is
- * maintained. Any line in a cache that is in the valid
- * state has its corresponding line of the new home memory
- * in the gM state. This is an invalid condition. When the
- * flushes are complete the cache line states will be
- * resynchronized with those in the new home memory.
- */
- flush_icache_il(); /* inline version */
- flush_dcache_il(); /* inline version */
- flush_pcache_il(); /* inline version */
-
-copy_rename_end:
-
- no_trap();
-
- /* enable interrupts */
- setpstate(pstate);
-
- /* enable CE reporting */
- set_error_enable(neer);
-
- if (cr->ecode != DRMACH_CR_OK)
- drmach_end_wait_xcall = drmach_rename_abort;
-
- /*
- * XXX CHEETAH SUPPORT
- */
- if (drmach_is_cheetah) {
- mutex_enter(&drmach_iocage_lock);
- drmach_iocage_mem_scrub(ecache_size * 2);
- drmach_iocage_is_busy = 0;
- cv_signal(&drmach_iocage_cv);
- mutex_exit(&drmach_iocage_lock);
- }
-
- axq_iopause_disable_all();
-
- xt_some(cpuset, drmach_end_wait_xcall, NULL, NULL);
-}
-
-static void drmach_io_dispose(drmachid_t);
-static sbd_error_t *drmach_io_release(drmachid_t);
-static sbd_error_t *drmach_io_status(drmachid_t, drmach_status_t *);
-
-static sbd_error_t *
-drmach_pci_new(drmach_device_t *proto, drmachid_t *idp)
-{
- drmach_node_t *node = proto->node;
- sbd_error_t *err;
- drmach_reg_t regs[3];
- int rv;
- int len = 0;
-
- rv = node->n_getproplen(node, "reg", &len);
- if (rv != 0 || len != sizeof (regs)) {
- sbd_error_t *err;
-
- /* pci nodes are expected to have regs */
- err = drerr_new(1, ESTC_GETPROP,
- "Device Node 0x%x: property %s",
- (uint_t)node->get_dnode(node), "reg");
- return (err);
- }
-
- rv = node->n_getprop(node, "reg", (void *)regs, sizeof (regs));
- if (rv) {
- sbd_error_t *err;
-
- err = drerr_new(1, ESTC_GETPROP,
- "Device Node 0x%x: property %s",
- (uint_t)node->get_dnode(node), "reg");
-
- return (err);
- }
-
- /*
- * Fix up unit number so that Leaf A has a lower unit number
- * than Leaf B.
- */
- if ((proto->portid % 2) != 0) {
- if ((regs[0].reg_addr_lo & 0x700000) == 0x700000)
- proto->unum = 0;
- else
- proto->unum = 1;
- } else {
- if ((regs[0].reg_addr_lo & 0x700000) == 0x700000)
- proto->unum = 2;
- else
- proto->unum = 3;
- }
-
- err = drmach_io_new(proto, idp);
- if (err == NULL) {
- drmach_io_t *self = *idp;
-
- /* reassemble 64-bit base address */
- self->scsr_pa = (uint64_t)regs[1].reg_addr_hi << 32;
- self->scsr_pa |= (uint64_t)regs[1].reg_addr_lo;
- }
-
- return (err);
-}
-
-static sbd_error_t *
-drmach_io_new(drmach_device_t *proto, drmachid_t *idp)
-{
- drmach_io_t *ip;
-
- ip = kmem_zalloc(sizeof (drmach_io_t), KM_SLEEP);
- bcopy(proto, &ip->dev, sizeof (ip->dev));
- ip->dev.node = drmach_node_dup(proto->node);
- ip->dev.cm.isa = (void *)drmach_io_new;
- ip->dev.cm.dispose = drmach_io_dispose;
- ip->dev.cm.release = drmach_io_release;
- ip->dev.cm.status = drmach_io_status;
-
- (void) snprintf(ip->dev.cm.name, sizeof (ip->dev.cm.name), "%s%d",
- ip->dev.type, ip->dev.unum);
-
- *idp = (drmachid_t)ip;
- return (NULL);
-}
-
-static void
-drmach_io_dispose(drmachid_t id)
-{
- drmach_io_t *self;
-
- ASSERT(DRMACH_IS_IO_ID(id));
-
- self = id;
- if (self->dev.node)
- drmach_node_dispose(self->dev.node);
-
- kmem_free(self, sizeof (*self));
-}
-
-/*ARGSUSED*/
-sbd_error_t *
-drmach_pre_op(int cmd, drmachid_t id, drmach_opts_t *opts)
-{
- drmach_board_t *bp = (drmach_board_t *)id;
- sbd_error_t *err = NULL;
-
- if (id && DRMACH_IS_BOARD_ID(id)) {
- switch (cmd) {
- case SBD_CMD_TEST:
- case SBD_CMD_STATUS:
- case SBD_CMD_GETNCM:
- break;
- case SBD_CMD_CONNECT:
- if (bp->connected)
- err = drerr_new(0, ESBD_STATE, NULL);
-
- if (bp->cond == SBD_COND_UNUSABLE)
- err = drerr_new(0,
- ESBD_FATAL_STATE, NULL);
- break;
- case SBD_CMD_DISCONNECT:
- if (!bp->connected)
- err = drerr_new(0, ESBD_STATE, NULL);
-
- if (bp->cond == SBD_COND_UNUSABLE)
- err = drerr_new(0,
- ESBD_FATAL_STATE, NULL);
- break;
- default:
- if (bp->cond == SBD_COND_UNUSABLE)
- err = drerr_new(0,
- ESBD_FATAL_STATE, NULL);
- break;
-
- }
- }
-
- return (err);
-}
-
-/*ARGSUSED*/
-sbd_error_t *
-drmach_post_op(int cmd, drmachid_t id, drmach_opts_t *opts)
-{
- return (NULL);
-}
-
-sbd_error_t *
-drmach_board_assign(int bnum, drmachid_t *id)
-{
- sbd_error_t *err = NULL;
- caddr_t obufp;
-
- if (!drmach_initialized && drmach_init() == -1) {
- err = DRMACH_INTERNAL_ERROR();
- }
-
- rw_enter(&drmach_boards_rwlock, RW_WRITER);
-
- if (!err) {
- if (drmach_array_get(drmach_boards, bnum, id) == -1) {
- err = drerr_new(0, ESTC_BNUM, "%d", bnum);
- } else {
- drmach_board_t *bp;
-
- if (*id)
- rw_downgrade(&drmach_boards_rwlock);
-
- obufp = kmem_zalloc(sizeof (dr_proto_hdr_t), KM_SLEEP);
- err = drmach_mbox_trans(DRMSG_ASSIGN, bnum, obufp,
- sizeof (dr_proto_hdr_t), (caddr_t)NULL, 0);
- kmem_free(obufp, sizeof (dr_proto_hdr_t));
-
- if (!err) {
- bp = *id;
- if (!*id)
- bp = *id =
- (drmachid_t)drmach_board_new(bnum);
- bp->assigned = 1;
- }
- }
- }
- rw_exit(&drmach_boards_rwlock);
- return (err);
-}
-
-static uint_t
-drmach_board_non_panther_cpus(gdcd_t *gdcd, uint_t exp, uint_t slot)
-{
- uint_t port, port_start, port_end;
- uint_t non_panther_cpus = 0;
- uint_t impl;
-
- ASSERT(gdcd != NULL);
-
- /*
- * Determine PRD port indices based on slot location.
- */
- switch (slot) {
- case 0:
- port_start = 0;
- port_end = 3;
- break;
- case 1:
- port_start = 4;
- port_end = 5;
- break;
- default:
- ASSERT(0);
- /* check all */
- port_start = 0;
- port_end = 5;
- break;
- }
-
- for (port = port_start; port <= port_end; port++) {
- if (gdcd->dcd_prd[exp][port].prd_ptype == SAFPTYPE_CPU &&
- RSV_GOOD(gdcd->dcd_prd[exp][port].prd_prsv)) {
- /*
- * This Safari port passed POST and represents a
- * cpu, so check the implementation.
- */
- impl = (gdcd->dcd_prd[exp][port].prd_ver_reg >> 32)
- & 0xffff;
-
- switch (impl) {
- case CHEETAH_IMPL:
- case CHEETAH_PLUS_IMPL:
- case JAGUAR_IMPL:
- non_panther_cpus++;
- break;
- case PANTHER_IMPL:
- break;
- default:
- ASSERT(0);
- non_panther_cpus++;
- break;
- }
- }
- }
-
- DRMACH_PR("drmach_board_non_panther_cpus: exp=%d, slot=%d, "
- "non_panther_cpus=%d", exp, slot, non_panther_cpus);
-
- return (non_panther_cpus);
-}
-
-sbd_error_t *
-drmach_board_connect(drmachid_t id, drmach_opts_t *opts)
-{
- _NOTE(ARGUNUSED(opts))
-
- drmach_board_t *bp = (drmach_board_t *)id;
- sbd_error_t *err;
- dr_mbox_msg_t *obufp;
- gdcd_t *gdcd = NULL;
- uint_t exp, slot;
- sc_gptwocfg_cookie_t scc;
- int panther_pages_enabled;
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- /*
- * Build the casm info portion of the CLAIM message.
- */
- obufp = kmem_zalloc(sizeof (dr_mbox_msg_t), KM_SLEEP);
- mutex_enter(&drmach_slice_table_lock);
- drmach_msg_memslice_init(obufp->msgdata.dm_cr.mem_slice);
- drmach_msg_memregs_init(obufp->msgdata.dm_cr.mem_regs);
- mutex_exit(&drmach_slice_table_lock);
- err = drmach_mbox_trans(DRMSG_CLAIM, bp->bnum, (caddr_t)obufp,
- sizeof (dr_mbox_msg_t), (caddr_t)NULL, 0);
- kmem_free(obufp, sizeof (dr_mbox_msg_t));
-
- if (err) {
- /*
- * if mailbox timeout or unrecoverable error from SC,
- * board cannot be touched. Mark the status as
- * unusable.
- */
- if ((err->e_code == ESTC_SMS_ERR_UNRECOVERABLE) ||
- (err->e_code == ESTC_MBXRPLY))
- bp->cond = SBD_COND_UNUSABLE;
- return (err);
- }
-
- gdcd = drmach_gdcd_new();
- if (gdcd == NULL) {
- cmn_err(CE_WARN, "failed to read GDCD info for %s\n",
- bp->cm.name);
- return (DRMACH_INTERNAL_ERROR());
- }
-
- /*
- * Read CPU SRAM DR buffer offset from GDCD.
- */
- exp = DRMACH_BNUM2EXP(bp->bnum);
- slot = DRMACH_BNUM2SLOT(bp->bnum);
- bp->stardrb_offset =
- gdcd->dcd_slot[exp][slot].l1ss_cpu_drblock_xwd_offset << 3;
- DRMACH_PR("%s: stardrb_offset=0x%lx\n", bp->cm.name,
- bp->stardrb_offset);
-
- /*
- * Read board LPA setting from GDCD.
- */
- bp->flags &= ~DRMACH_NULL_PROC_LPA;
- if (gdcd->dcd_slot[exp][slot].l1ss_flags &
- L1SSFLG_THIS_L1_NULL_PROC_LPA) {
- bp->flags |= DRMACH_NULL_PROC_LPA;
- DRMACH_PR("%s: NULL proc LPA\n", bp->cm.name);
- }
-
- /*
- * XXX Until the Solaris large pages support heterogeneous cpu
- * domains, DR needs to prevent the addition of non-Panther cpus
- * to an all-Panther domain with large pages enabled.
- */
- panther_pages_enabled = (page_num_pagesizes() > DEFAULT_MMU_PAGE_SIZES);
- if (drmach_board_non_panther_cpus(gdcd, exp, slot) > 0 &&
- panther_pages_enabled && drmach_large_page_restriction) {
- cmn_err(CE_WARN, "Domain shutdown is required to add a non-"
- "UltraSPARC-IV+ board into an all UltraSPARC-IV+ domain");
- err = drerr_new(0, ESTC_SUPPORT, NULL);
- }
-
- if (err == NULL) {
- /* do saf configurator stuff */
- DRMACH_PR("calling sc_probe_board for bnum=%d\n", bp->bnum);
- scc = sc_probe_board(bp->bnum);
- if (scc == NULL)
- err = drerr_new(0, ESTC_PROBE, bp->cm.name);
- }
-
- if (err) {
- /* flush CDC srams */
- if (axq_cdc_flush_all() != DDI_SUCCESS) {
- goto out;
- }
-
- /*
- * Build the casm info portion of the UNCLAIM message.
- */
- obufp = kmem_zalloc(sizeof (dr_mbox_msg_t), KM_SLEEP);
- mutex_enter(&drmach_slice_table_lock);
- drmach_msg_memslice_init(obufp->msgdata.dm_ur.mem_slice);
- drmach_msg_memregs_init(obufp->msgdata.dm_ur.mem_regs);
- mutex_exit(&drmach_slice_table_lock);
- (void) drmach_mbox_trans(DRMSG_UNCLAIM, bp->bnum,
- (caddr_t)obufp, sizeof (dr_mbox_msg_t),
- (caddr_t)NULL, 0);
-
- kmem_free(obufp, sizeof (dr_mbox_msg_t));
-
- /*
- * we clear the connected flag just in case it would have
- * been set by a concurrent drmach_board_status() thread
- * before the UNCLAIM completed.
- */
- bp->connected = 0;
- goto out;
- }
-
- /*
- * Now that the board has been successfully attached, obtain
- * platform-specific DIMM serial id information for the board.
- */
- if ((DRMACH_BNUM2SLOT(bp->bnum) == 0) &&
- plat_ecc_capability_sc_get(PLAT_ECC_DIMM_SID_MESSAGE)) {
- (void) plat_request_mem_sids(DRMACH_BNUM2EXP(bp->bnum));
- }
-
-out:
- if (gdcd != NULL)
- drmach_gdcd_dispose(gdcd);
-
- return (err);
-}
-
-static void
-drmach_slice_table_update(drmach_board_t *bp, int invalidate)
-{
- static char *axq_name = "address-extender-queue";
- static dev_info_t *axq_dip = NULL;
- static int axq_exp = -1;
- static int axq_slot;
- int e, s, slice;
-
- ASSERT(MUTEX_HELD(&drmach_slice_table_lock));
-
- e = DRMACH_BNUM2EXP(bp->bnum);
- if (invalidate) {
- ASSERT(DRMACH_BNUM2SLOT(bp->bnum) == 0);
-
- /* invalidate cached casm value */
- drmach_slice_table[e] = 0;
-
- /* invalidate cached axq info if for same exp */
- if (e == axq_exp && axq_dip) {
- ndi_rele_devi(axq_dip);
- axq_dip = NULL;
- }
- }
-
- if (axq_dip == NULL || !i_ddi_devi_attached(axq_dip)) {
- int i, portid;
-
- /* search for an attached slot0 axq instance */
- for (i = 0; i < AXQ_MAX_EXP * AXQ_MAX_SLOT_PER_EXP; i++) {
- if (axq_dip)
- ndi_rele_devi(axq_dip);
- axq_dip = ddi_find_devinfo(axq_name, i, 0);
- if (axq_dip && DDI_CF2(axq_dip)) {
- portid = ddi_getprop(DDI_DEV_T_ANY, axq_dip,
- DDI_PROP_DONTPASS, "portid", -1);
- if (portid == -1) {
- DRMACH_PR("cant get portid of axq "
- "instance %d\n", i);
- continue;
- }
-
- axq_exp = (portid >> 5) & 0x1f;
- axq_slot = portid & 1;
-
- if (invalidate && axq_exp == e)
- continue;
-
- if (axq_slot == 0)
- break; /* found */
- }
- }
-
- if (i == AXQ_MAX_EXP * AXQ_MAX_SLOT_PER_EXP) {
- if (axq_dip) {
- ndi_rele_devi(axq_dip);
- axq_dip = NULL;
- }
- DRMACH_PR("drmach_slice_table_update: failed to "
- "update axq dip\n");
- return;
- }
-
- }
-
- ASSERT(axq_dip);
- ASSERT(axq_slot == 0);
-
- if (invalidate)
- return;
-
- s = DRMACH_BNUM2SLOT(bp->bnum);
- DRMACH_PR("using AXQ casm %d.%d for slot%d.%d\n", axq_exp, axq_slot,
- e, s);
-
- /* invalidate entry */
- drmach_slice_table[e] &= ~0x20;
-
- /*
- * find a slice that routes to expander e. If no match
- * is found, drmach_slice_table[e] will remain invalid.
- *
- * The CASM is a routing table indexed by slice number.
- * Each element in the table contains permission bits,
- * a destination expander number and a valid bit. The
- * valid bit must true for the element to be meaningful.
- *
- * CASM entry structure
- * Bits 15..6 ignored
- * Bit 5 valid
- * Bits 0..4 expander number
- *
- * NOTE: the for loop is really enumerating the range of slices,
- * which is ALWAYS equal to the range of expanders. Hence,
- * AXQ_MAX_EXP is okay to use in this loop.
- */
- for (slice = 0; slice < AXQ_MAX_EXP; slice++) {
- uint32_t casm = axq_casm_read(axq_exp, axq_slot, slice);
-
- if ((casm & 0x20) && (casm & 0x1f) == e)
- drmach_slice_table[e] = 0x20 | slice;
- }
-}
-
-/*
- * Get base and bound PAs for slot 1 board lpa programming
- * If a cpu/mem board is present in the same expander, use slice
- * information corresponding to the CASM. Otherwise, set base and
- * bound PAs to 0.
- */
-static void
-drmach_lpa_bb_get(drmach_board_t *s1bp, uint64_t *basep, uint64_t *boundp)
-{
- drmachid_t s0id;
-
- ASSERT(mutex_owned(&drmach_slice_table_lock));
- ASSERT(DRMACH_BNUM2SLOT(s1bp->bnum) == 1);
-
- *basep = *boundp = 0;
- if (drmach_array_get(drmach_boards, s1bp->bnum - 1, &s0id) == 0 &&
- s0id != 0) {
-
- uint32_t slice;
- if ((slice = drmach_slice_table[DRMACH_BNUM2EXP(s1bp->bnum)])
- & 0x20) {
- *basep = DRMACH_SLICE_TO_PA(slice & DRMACH_SLICE_MASK);
- *boundp = *basep + DRMACH_MEM_SLICE_SIZE;
- }
- }
-}
-
-
-/*
- * Reprogram slot 1 lpa's as required.
- * The purpose of this routine is maintain the LPA settings of the devices
- * in slot 1. To date we know Schizo and Cheetah are the only devices that
- * require this attention. The LPA setting must match the slice field in the
- * CASM element for the local expander. This field is guaranteed to be
- * programmed in accordance with the cacheable address space on the slot 0
- * board of the local expander. If no memory is present on the slot 0 board,
- * there is no cacheable address space and, hence, the CASM slice field will
- * be zero or its valid bit will be false (or both).
- */
-
-static void
-drmach_slot1_lpa_set(drmach_board_t *bp)
-{
- drmachid_t id;
- drmach_board_t *s1bp = NULL;
- int rv, idx, is_maxcat = 1;
- uint64_t last_scsr_pa = 0;
- uint64_t new_basepa, new_boundpa;
-
- if (DRMACH_BNUM2SLOT(bp->bnum)) {
- s1bp = bp;
- if (s1bp->devices == NULL) {
- DRMACH_PR("drmach...lpa_set: slot1=%d not present",
- bp->bnum);
- return;
- }
- } else {
- rv = drmach_array_get(drmach_boards, bp->bnum + 1, &id);
- /* nothing to do when board is not found or has no devices */
- s1bp = id;
- if (rv == -1 || s1bp == NULL || s1bp->devices == NULL) {
- DRMACH_PR("drmach...lpa_set: slot1=%d not present",
- bp->bnum + 1);
- return;
- }
- ASSERT(DRMACH_IS_BOARD_ID(id));
- }
- mutex_enter(&drmach_slice_table_lock);
- drmach_lpa_bb_get(s1bp, &new_basepa, &new_boundpa);
- DRMACH_PR("drmach_...lpa_set: bnum=%d base=0x%lx bound=0x%lx\n",
- s1bp->bnum, new_basepa, new_boundpa);
-
- rv = drmach_array_first(s1bp->devices, &idx, &id);
- while (rv == 0) {
- if (DRMACH_IS_IO_ID(id)) {
- drmach_io_t *io = id;
-
- is_maxcat = 0;
-
- /*
- * Skip all non-Schizo IO devices (only IO nodes
- * that are Schizo devices have non-zero scsr_pa).
- * Filter out "other" leaf to avoid writing to the
- * same Schizo Control/Status Register twice.
- */
- if (io->scsr_pa && io->scsr_pa != last_scsr_pa) {
- uint64_t scsr;
-
- scsr = lddphysio(io->scsr_pa);
- DRMACH_PR("drmach...lpa_set: old scsr=0x%lx\n",
- scsr);
- scsr &= ~(DRMACH_LPA_BASE_MASK |
- DRMACH_LPA_BND_MASK);
- scsr |= DRMACH_PA_TO_LPA_BASE(new_basepa);
- scsr |= DRMACH_PA_TO_LPA_BND(new_boundpa);
-
- stdphysio(io->scsr_pa, scsr);
- DRMACH_PR("drmach...lpa_set: new scsr=0x%lx\n",
- scsr);
-
- last_scsr_pa = io->scsr_pa;
- }
- }
- rv = drmach_array_next(s1bp->devices, &idx, &id);
- }
-
- if (is_maxcat && DRMACH_L1_SET_LPA(s1bp) && drmach_reprogram_lpa) {
- extern xcfunc_t drmach_set_lpa;
-
- DRMACH_PR("reprogramming maxcat lpa's");
-
- mutex_enter(&cpu_lock);
- rv = drmach_array_first(s1bp->devices, &idx, &id);
- while (rv == 0 && id != NULL) {
- if (DRMACH_IS_CPU_ID(id)) {
- int ntries;
- processorid_t cpuid;
-
- cpuid = ((drmach_cpu_t *)id)->cpuid;
-
- /*
- * Check for unconfigured or powered-off
- * MCPUs. If CPU_READY flag is clear, the
- * MCPU cannot be xcalled.
- */
- if ((cpu[cpuid] == NULL) ||
- (cpu[cpuid]->cpu_flags &
- CPU_READY) == 0) {
-
- rv = drmach_array_next(s1bp->devices,
- &idx, &id);
- continue;
- }
-
- /*
- * XXX CHEETAH SUPPORT
- * for cheetah, we need to clear iocage
- * memory since it will be used for e$ flush
- * in drmach_set_lpa.
- */
- if (drmach_is_cheetah) {
- mutex_enter(&drmach_iocage_lock);
- while (drmach_iocage_is_busy)
- cv_wait(&drmach_iocage_cv,
- &drmach_iocage_lock);
- drmach_iocage_is_busy = 1;
- drmach_iocage_mem_scrub(ecache_size *
- 2);
- mutex_exit(&drmach_iocage_lock);
- }
-
- /*
- * drmach_slice_table[*]
- * bit 5 valid
- * bit 0:4 slice number
- *
- * drmach_xt_mb[*] format for drmach_set_lpa
- * bit 7 valid
- * bit 6 set null LPA
- * (overrides bits 0:4)
- * bit 0:4 slice number
- *
- * drmach_set_lpa derives processor CBASE and
- * CBND from bits 6 and 0:4 of drmach_xt_mb.
- * If bit 6 is set, then CBASE = CBND = 0.
- * Otherwise, CBASE = slice number;
- * CBND = slice number + 1.
- * No action is taken if bit 7 is zero.
- */
-
- mutex_enter(&drmach_xt_mb_lock);
- bzero((void *)drmach_xt_mb,
- drmach_xt_mb_size);
-
- if (new_basepa == 0 && new_boundpa == 0)
- drmach_xt_mb[cpuid] = 0x80 | 0x40;
- else
- drmach_xt_mb[cpuid] = 0x80 |
- DRMACH_PA_TO_SLICE(new_basepa);
-
- drmach_xt_ready = 0;
-
- xt_one(cpuid, drmach_set_lpa, NULL, NULL);
-
- ntries = drmach_cpu_ntries;
- while (!drmach_xt_ready && ntries) {
- DELAY(drmach_cpu_delay);
- ntries--;
- }
- mutex_exit(&drmach_xt_mb_lock);
- drmach_xt_ready = 0;
-
- /*
- * XXX CHEETAH SUPPORT
- * for cheetah, we need to clear iocage
- * memory since it was used for e$ flush
- * in performed drmach_set_lpa.
- */
- if (drmach_is_cheetah) {
- mutex_enter(&drmach_iocage_lock);
- drmach_iocage_mem_scrub(ecache_size *
- 2);
- drmach_iocage_is_busy = 0;
- cv_signal(&drmach_iocage_cv);
- mutex_exit(&drmach_iocage_lock);
- }
- }
- rv = drmach_array_next(s1bp->devices, &idx, &id);
- }
- mutex_exit(&cpu_lock);
- }
- mutex_exit(&drmach_slice_table_lock);
-}
-
-/*
- * Return the number of connected Panther boards in the domain.
- */
-static int
-drmach_panther_boards(void)
-{
- int rv;
- int b_idx;
- drmachid_t b_id;
- drmach_board_t *bp;
- int npanther = 0;
-
- rv = drmach_array_first(drmach_boards, &b_idx, &b_id);
- while (rv == 0) {
- ASSERT(DRMACH_IS_BOARD_ID(b_id));
- bp = b_id;
-
- if (IS_PANTHER(bp->cpu_impl))
- npanther++;
-
- rv = drmach_array_next(drmach_boards, &b_idx, &b_id);
- }
-
- return (npanther);
-}
-
-/*ARGSUSED*/
-sbd_error_t *
-drmach_board_disconnect(drmachid_t id, drmach_opts_t *opts)
-{
- drmach_board_t *bp;
- dr_mbox_msg_t *obufp;
- sbd_error_t *err = NULL;
-
- sc_gptwocfg_cookie_t scc;
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- bp = id;
-
- /*
- * Build the casm info portion of the UNCLAIM message.
- * This must be done prior to calling for saf configurator
- * deprobe, to ensure that the associated axq instance
- * is not detached.
- */
- obufp = kmem_zalloc(sizeof (dr_mbox_msg_t), KM_SLEEP);
- mutex_enter(&drmach_slice_table_lock);
- drmach_msg_memslice_init(obufp->msgdata.dm_ur.mem_slice);
-
- /*
- * If disconnecting slot 0 board, update the casm slice table
- * info now, for use by drmach_slot1_lpa_set()
- */
- if (DRMACH_BNUM2SLOT(bp->bnum) == 0)
- drmach_slice_table_update(bp, 1);
-
- drmach_msg_memregs_init(obufp->msgdata.dm_ur.mem_regs);
- mutex_exit(&drmach_slice_table_lock);
-
- /*
- * Update LPA information for slot1 board
- */
- drmach_slot1_lpa_set(bp);
-
- /* disable and flush CDC */
- if (axq_cdc_disable_flush_all() != DDI_SUCCESS) {
- axq_cdc_enable_all(); /* paranoia */
- err = DRMACH_INTERNAL_ERROR();
- }
-
- /*
- * call saf configurator for deprobe
- * It's done now before sending an UNCLAIM message because
- * IKP will probe boards it doesn't know about <present at boot>
- * prior to unprobing them. If this happens after sending the
- * UNCLAIM, it will cause a dstop for domain transgression error.
- */
-
- if (!err) {
- scc = sc_unprobe_board(bp->bnum);
- axq_cdc_enable_all();
- if (scc != NULL) {
- err = drerr_new(0, ESTC_DEPROBE, bp->cm.name);
- }
- }
-
- /*
- * If disconnecting a board from a Panther domain, wait a fixed-
- * time delay for pending Safari transactions to complete on the
- * disconnecting board's processors. The bus sync list read used
- * in drmach_shutdown_asm to synchronize with outstanding Safari
- * transactions assumes no read-bypass-write mode for all memory
- * controllers. Since Panther supports read-bypass-write, a
- * delay is used that is slightly larger than the maximum Safari
- * timeout value in the Safari/Fireplane Config Reg.
- */
- if (drmach_panther_boards() > 0 || drmach_unclaim_delay_all) {
- clock_t stime = ddi_get_lbolt();
-
- delay(drv_usectohz(drmach_unclaim_usec_delay));
-
- stime = ddi_get_lbolt() - stime;
- DRMACH_PR("delayed %ld ticks (%ld secs) before disconnecting "
- "board %s from domain\n", stime, stime / hz, bp->cm.name);
- }
-
- if (!err) {
- obufp->msgdata.dm_ur.mem_clear = 0;
-
- err = drmach_mbox_trans(DRMSG_UNCLAIM, bp->bnum, (caddr_t)obufp,
- sizeof (dr_mbox_msg_t), (caddr_t)NULL, 0);
-
- if (err) {
- /*
- * if mailbox timeout or unrecoverable error from SC,
- * board cannot be touched. Mark the status as
- * unusable.
- */
- if ((err->e_code == ESTC_SMS_ERR_UNRECOVERABLE) ||
- (err->e_code == ESTC_MBXRPLY))
- bp->cond = SBD_COND_UNUSABLE;
- else {
- DRMACH_PR("UNCLAIM failed for bnum=%d\n",
- bp->bnum);
- DRMACH_PR("calling sc_probe_board: bnum=%d\n",
- bp->bnum);
- scc = sc_probe_board(bp->bnum);
- if (scc == NULL) {
- cmn_err(CE_WARN,
- "sc_probe_board failed for bnum=%d",
- bp->bnum);
- } else {
- if (DRMACH_BNUM2SLOT(bp->bnum) == 0) {
- mutex_enter(
- &drmach_slice_table_lock);
- drmach_slice_table_update(bp,
- 0);
- mutex_exit(
- &drmach_slice_table_lock);
- }
- drmach_slot1_lpa_set(bp);
- }
- }
- } else {
- bp->connected = 0;
- /*
- * Now that the board has been successfully detached,
- * discard platform-specific DIMM serial id information
- * for the board.
- */
- if ((DRMACH_BNUM2SLOT(bp->bnum) == 0) &&
- plat_ecc_capability_sc_get(
- PLAT_ECC_DIMM_SID_MESSAGE)) {
- (void) plat_discard_mem_sids(
- DRMACH_BNUM2EXP(bp->bnum));
- }
- }
- }
- kmem_free(obufp, sizeof (dr_mbox_msg_t));
-
- return (err);
-}
-
-static int
-drmach_get_portid(drmach_node_t *np)
-{
- drmach_node_t pp;
- int portid;
- char type[OBP_MAXPROPNAME];
-
- if (np->n_getprop(np, "portid", &portid, sizeof (portid)) == 0)
- return (portid);
-
- /*
- * Get the device_type property to see if we should
- * continue processing this node.
- */
- if (np->n_getprop(np, "device_type", &type, sizeof (type)) != 0)
- return (-1);
-
- /*
- * If the device is a CPU without a 'portid' property,
- * it is a CMP core. For such cases, the parent node
- * has the portid.
- */
- if (strcmp(type, DRMACH_CPU_NAMEPROP) == 0) {
- if (np->get_parent(np, &pp) != 0)
- return (-1);
-
- if (pp.n_getprop(&pp, "portid", &portid, sizeof (portid)) == 0)
- return (portid);
- }
-
- return (-1);
-}
-
-/*
- * This is a helper function to determine if a given
- * node should be considered for a dr operation according
- * to predefined dr type nodes and the node's name.
- * Formal Parameter : The name of a device node.
- * Return Value: -1, name does not map to a valid dr type.
- * A value greater or equal to 0, name is a valid dr type.
- */
-static int
-drmach_name2type_idx(char *name)
-{
- int index, ntypes;
-
- if (name == NULL)
- return (-1);
-
- /*
- * Determine how many possible types are currently supported
- * for dr.
- */
- ntypes = sizeof (drmach_name2type) / sizeof (drmach_name2type[0]);
-
- /* Determine if the node's name correspond to a predefined type. */
- for (index = 0; index < ntypes; index++) {
- if (strcmp(drmach_name2type[index].name, name) == 0)
- /* The node is an allowed type for dr. */
- return (index);
- }
-
- /*
- * If the name of the node does not map to any of the
- * types in the array drmach_name2type then the node is not of
- * interest to dr.
- */
- return (-1);
-}
-
-static int
-drmach_board_find_devices_cb(drmach_node_walk_args_t *args)
-{
- drmach_node_t *node = args->node;
- drmach_board_cb_data_t *data = args->data;
- drmach_board_t *obj = data->obj;
-
- int rv, portid;
- drmachid_t id;
- drmach_device_t *device;
- char name[OBP_MAXDRVNAME];
-
- portid = drmach_get_portid(node);
- if (portid == -1) {
- /*
- * if the node does not have a portid property, then
- * by that information alone it is known that drmach
- * is not interested in it.
- */
- return (0);
- }
- rv = node->n_getprop(node, "name", name, OBP_MAXDRVNAME);
-
- /* The node must have a name */
- if (rv)
- return (0);
-
- /*
- * Ignore devices whose portid do not map to this board,
- * or that their name property is not mapped to a valid
- * dr device name.
- */
- if ((drmach_portid2bnum(portid) != obj->bnum) ||
- (drmach_name2type_idx(name) < 0))
- return (0);
-
- /*
- * Create a device data structure from this node data.
- * The call may yield nothing if the node is not of interest
- * to drmach.
- */
- data->err = drmach_device_new(node, obj, portid, &id);
- if (data->err)
- return (-1);
- else if (!id) {
- /*
- * drmach_device_new examined the node we passed in
- * and determined that it was either one not of
- * interest to drmach or the PIM dr layer.
- * So, it is skipped.
- */
- return (0);
- }
-
- rv = drmach_array_set(obj->devices, data->ndevs++, id);
- if (rv) {
- data->err = DRMACH_INTERNAL_ERROR();
- return (-1);
- }
-
- device = id;
-
-#ifdef DEBUG
- DRMACH_PR("%d %s %d %p\n", portid, device->type, device->unum, id);
- if (DRMACH_IS_IO_ID(id))
- DRMACH_PR("ndevs = %d dip/node = %p", data->ndevs, node->here);
-#endif
-
- data->err = (*data->found)(data->a, device->type, device->unum, id);
- return (data->err == NULL ? 0 : -1);
-}
-
-sbd_error_t *
-drmach_board_find_devices(drmachid_t id, void *a,
- sbd_error_t *(*found)(void *a, const char *, int, drmachid_t))
-{
- drmach_board_t *bp = (drmach_board_t *)id;
- sbd_error_t *err;
- int max_devices;
- int rv;
- drmach_board_cb_data_t data;
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- max_devices = plat_max_cpu_units_per_board();
- max_devices += plat_max_mem_units_per_board();
- max_devices += plat_max_io_units_per_board();
-
- bp->devices = drmach_array_new(0, max_devices);
-
- if (bp->tree == NULL)
- bp->tree = drmach_node_new();
-
- data.obj = bp;
- data.ndevs = 0;
- data.found = found;
- data.a = a;
- data.err = NULL;
-
- mutex_enter(&drmach_slice_table_lock);
- mutex_enter(&drmach_bus_sync_lock);
-
- rv = drmach_node_walk(bp->tree, &data, drmach_board_find_devices_cb);
-
- drmach_slice_table_update(bp, 0);
- drmach_bus_sync_list_update();
-
- mutex_exit(&drmach_bus_sync_lock);
- mutex_exit(&drmach_slice_table_lock);
-
- if (rv == 0) {
- err = NULL;
- drmach_slot1_lpa_set(bp);
- } else {
- drmach_array_dispose(bp->devices, drmach_device_dispose);
- bp->devices = NULL;
-
- if (data.err)
- err = data.err;
- else
- err = DRMACH_INTERNAL_ERROR();
- }
-
- return (err);
-}
-
-int
-drmach_board_lookup(int bnum, drmachid_t *id)
-{
- int rv = 0;
-
- if (!drmach_initialized && drmach_init() == -1) {
- *id = 0;
- return (-1);
- }
- rw_enter(&drmach_boards_rwlock, RW_WRITER);
- if (drmach_array_get(drmach_boards, bnum, id)) {
- *id = 0;
- rv = -1;
- } else {
- caddr_t obufp;
- dr_showboard_t shb;
- sbd_error_t *err = NULL;
- drmach_board_t *bp;
-
- bp = *id;
-
- if (bp)
- rw_downgrade(&drmach_boards_rwlock);
-
- obufp = kmem_zalloc(sizeof (dr_proto_hdr_t), KM_SLEEP);
- err = drmach_mbox_trans(DRMSG_SHOWBOARD, bnum, obufp,
- sizeof (dr_proto_hdr_t), (caddr_t)&shb,
- sizeof (dr_showboard_t));
- kmem_free(obufp, sizeof (dr_proto_hdr_t));
-
- if (err) {
- if (err->e_code == ESTC_UNAVAILABLE) {
- *id = 0;
- rv = -1;
- }
- sbd_err_clear(&err);
- } else {
- if (!bp)
- bp = *id = (drmachid_t)drmach_board_new(bnum);
- bp->connected = (shb.bd_assigned && shb.bd_active);
- bp->empty = shb.slot_empty;
-
- switch (shb.test_status) {
- case DR_TEST_STATUS_UNKNOWN:
- case DR_TEST_STATUS_IPOST:
- case DR_TEST_STATUS_ABORTED:
- bp->cond = SBD_COND_UNKNOWN;
- break;
- case DR_TEST_STATUS_PASSED:
- bp->cond = SBD_COND_OK;
- break;
- case DR_TEST_STATUS_FAILED:
- bp->cond = SBD_COND_FAILED;
- break;
- default:
- bp->cond = SBD_COND_UNKNOWN;
- DRMACH_PR("Unknown test status=0x%x from SC\n",
- shb.test_status);
- break;
- }
- (void) strncpy(bp->type, shb.board_type,
- sizeof (bp->type));
- bp->assigned = shb.bd_assigned;
- bp->powered = shb.power_on;
- }
- }
- rw_exit(&drmach_boards_rwlock);
- return (rv);
-}
-
-sbd_error_t *
-drmach_board_name(int bnum, char *buf, int buflen)
-{
- (void) snprintf(buf, buflen, "%s%d", DRMACH_BNUM2SLOT(bnum) ?
- "IO" : "SB", DRMACH_BNUM2EXP(bnum));
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_board_poweroff(drmachid_t id)
-{
- drmach_board_t *bp;
- sbd_error_t *err;
- drmach_status_t stat;
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- bp = id;
-
- err = drmach_board_status(id, &stat);
- if (!err) {
- if (stat.configured || stat.busy)
- err = drerr_new(0, ESTC_CONFIGBUSY, bp->cm.name);
- else {
- caddr_t obufp;
-
- obufp = kmem_zalloc(sizeof (dr_proto_hdr_t), KM_SLEEP);
- err = drmach_mbox_trans(DRMSG_POWEROFF, bp->bnum, obufp,
- sizeof (dr_proto_hdr_t), (caddr_t)NULL, 0);
- kmem_free(obufp, sizeof (dr_proto_hdr_t));
- if (!err)
- bp->powered = 0;
- }
- }
- return (err);
-}
-
-sbd_error_t *
-drmach_board_poweron(drmachid_t id)
-{
- drmach_board_t *bp;
- caddr_t obufp;
- sbd_error_t *err;
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- bp = id;
-
- obufp = kmem_zalloc(sizeof (dr_proto_hdr_t), KM_SLEEP);
- err = drmach_mbox_trans(DRMSG_POWERON, bp->bnum, obufp,
- sizeof (dr_proto_hdr_t), (caddr_t)NULL, 0);
- if (!err)
- bp->powered = 1;
-
- kmem_free(obufp, sizeof (dr_proto_hdr_t));
-
- return (err);
-}
-
-static sbd_error_t *
-drmach_board_release(drmachid_t id)
-{
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- return (NULL);
-}
-
-sbd_error_t *
-drmach_board_test(drmachid_t id, drmach_opts_t *opts, int force)
-{
- drmach_board_t *bp;
- drmach_device_t *dp[MAX_CORES_PER_CMP];
- dr_mbox_msg_t *obufp;
- sbd_error_t *err;
- dr_testboard_reply_t tbr;
- int cpylen;
- char *copts;
- int is_io;
- cpu_flag_t oflags[MAX_CORES_PER_CMP];
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- bp = id;
-
- /*
- * If the board is an I/O or MAXCAT board, setup I/O cage for
- * testing. Slot 1 indicates I/O or MAXCAT board.
- */
-
- is_io = DRMACH_BNUM2SLOT(bp->bnum);
-
- obufp = kmem_zalloc(sizeof (dr_mbox_msg_t), KM_SLEEP);
-
- if (force)
- obufp->msgdata.dm_tb.force = 1;
-
- obufp->msgdata.dm_tb.immediate = 1;
-
- if ((opts->size > 0) && ((copts = opts->copts) != NULL)) {
- cpylen = (opts->size > DR_HPOPTLEN ? DR_HPOPTLEN : opts->size);
- bcopy(copts, obufp->msgdata.dm_tb.hpost_opts, cpylen);
- }
-
- if (is_io) {
- err = drmach_iocage_setup(&obufp->msgdata.dm_tb, dp, oflags);
-
- if (err) {
- kmem_free(obufp, sizeof (dr_mbox_msg_t));
- return (err);
- }
- }
-
- err = drmach_mbox_trans(DRMSG_TESTBOARD, bp->bnum, (caddr_t)obufp,
- sizeof (dr_mbox_msg_t), (caddr_t)&tbr, sizeof (tbr));
-
- if (!err)
- bp->cond = SBD_COND_OK;
- else
- bp->cond = SBD_COND_UNKNOWN;
-
- if ((!err) && (tbr.test_status != DR_TEST_STATUS_PASSED)) {
- /* examine test status */
- switch (tbr.test_status) {
- case DR_TEST_STATUS_IPOST:
- bp->cond = SBD_COND_UNKNOWN;
- err = drerr_new(0, ESTC_TEST_IN_PROGRESS, NULL);
- break;
- case DR_TEST_STATUS_UNKNOWN:
- bp->cond = SBD_COND_UNKNOWN;
- err = drerr_new(1,
- ESTC_TEST_STATUS_UNKNOWN, NULL);
- break;
- case DR_TEST_STATUS_FAILED:
- bp->cond = SBD_COND_FAILED;
- err = drerr_new(1, ESTC_TEST_FAILED, NULL);
- break;
- case DR_TEST_STATUS_ABORTED:
- bp->cond = SBD_COND_UNKNOWN;
- err = drerr_new(1, ESTC_TEST_ABORTED, NULL);
- break;
- default:
- bp->cond = SBD_COND_UNKNOWN;
- err = drerr_new(1, ESTC_TEST_RESULT_UNKNOWN,
- NULL);
- break;
- }
- }
-
- /*
- * If I/O cage test was performed, check for availability of the
- * cpu used. If cpu has been returned, it's OK to proceed with
- * reconfiguring it for use.
- */
- if (is_io) {
- DRMACH_PR("drmach_board_test: tbr.cpu_recovered: %d",
- tbr.cpu_recovered);
- DRMACH_PR("drmach_board_test: port id: %d",
- tbr.cpu_portid);
-
- /*
- * Check the cpu_recovered flag in the testboard reply, or
- * if the testboard request message was not sent to SMS due
- * to an mboxsc_putmsg() failure, it's OK to recover the
- * cpu since hpost hasn't touched it.
- */
- if ((tbr.cpu_recovered && tbr.cpu_portid ==
- obufp->msgdata.dm_tb.cpu_portid) ||
- ((err) && (err->e_code == ESTC_MBXRQST))) {
-
- int i;
-
- mutex_enter(&cpu_lock);
- for (i = 0; i < MAX_CORES_PER_CMP; i++) {
- if (dp[i] != NULL) {
- (void) drmach_iocage_cpu_return(dp[i],
- oflags[i]);
- }
- }
- mutex_exit(&cpu_lock);
- } else {
- cmn_err(CE_WARN, "Unable to recover port id %d "
- "after I/O cage test: cpu_recovered=%d, "
- "returned portid=%d",
- obufp->msgdata.dm_tb.cpu_portid,
- tbr.cpu_recovered, tbr.cpu_portid);
- }
- (void) drmach_iocage_mem_return(&tbr);
- }
- kmem_free(obufp, sizeof (dr_mbox_msg_t));
-
- return (err);
-}
-
-sbd_error_t *
-drmach_board_unassign(drmachid_t id)
-{
- drmach_board_t *bp;
- sbd_error_t *err;
- drmach_status_t stat;
- caddr_t obufp;
-
- rw_enter(&drmach_boards_rwlock, RW_WRITER);
-
- if (!DRMACH_IS_BOARD_ID(id)) {
- rw_exit(&drmach_boards_rwlock);
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- }
- bp = id;
-
- err = drmach_board_status(id, &stat);
- if (err) {
- rw_exit(&drmach_boards_rwlock);
- return (err);
- }
-
- if (stat.configured || stat.busy) {
- err = drerr_new(0, ESTC_CONFIGBUSY, bp->cm.name);
- } else {
-
- obufp = kmem_zalloc(sizeof (dr_proto_hdr_t), KM_SLEEP);
- err = drmach_mbox_trans(DRMSG_UNASSIGN, bp->bnum, obufp,
- sizeof (dr_proto_hdr_t), (caddr_t)NULL, 0);
- kmem_free(obufp, sizeof (dr_proto_hdr_t));
- if (!err) {
- if (drmach_array_set(drmach_boards, bp->bnum, 0) != 0)
- err = DRMACH_INTERNAL_ERROR();
- else
- drmach_board_dispose(bp);
- }
- }
- rw_exit(&drmach_boards_rwlock);
- return (err);
-}
-
-static sbd_error_t *
-drmach_read_reg_addr(drmach_device_t *dp, uint64_t *p)
-{
- int len;
- drmach_reg_t reg;
- drmach_node_t pp;
- drmach_node_t *np = dp->node;
-
- /*
- * If the node does not have a portid property,
- * it represents a CMP device. For a CMP, the reg
- * property of the parent holds the information of
- * interest.
- */
- if (dp->node->n_getproplen(dp->node, "portid", &len) != 0) {
-
- if (dp->node->get_parent(dp->node, &pp) != 0) {
- return (DRMACH_INTERNAL_ERROR());
- }
- np = &pp;
- }
-
- if (np->n_getproplen(np, "reg", &len) != 0)
- return (DRMACH_INTERNAL_ERROR());
-
- if (len != sizeof (reg))
- return (DRMACH_INTERNAL_ERROR());
-
- if (np->n_getprop(np, "reg", &reg, sizeof (reg)) != 0)
- return (DRMACH_INTERNAL_ERROR());
-
- /* reassemble 64-bit base address */
- *p = ((uint64_t)reg.reg_addr_hi << 32) | reg.reg_addr_lo;
-
- return (NULL);
-}
-
-static void
-drmach_cpu_read(uint64_t arg1, uint64_t arg2)
-{
- uint64_t *saf_config_reg = (uint64_t *)arg1;
- uint_t *reg_read = (uint_t *)arg2;
-
- *saf_config_reg = lddsafconfig();
- *reg_read = 0x1;
-}
-
-/*
- * A return value of 1 indicates success and 0 indicates a failure
- */
-static int
-drmach_cpu_read_scr(drmach_cpu_t *cp, uint64_t *scr)
-{
-
- int rv = 0x0;
-
- *scr = 0x0;
-
- /*
- * Confirm cpu was in ready set when xc was issued.
- * This is done by verifying rv which is
- * set to 0x1 when xc_one is successful.
- */
- xc_one(cp->dev.portid, (xcfunc_t *)drmach_cpu_read,
- (uint64_t)scr, (uint64_t)&rv);
-
- return (rv);
-
-}
-
-static sbd_error_t *
-drmach_cpu_read_cpuid(drmach_cpu_t *cp, processorid_t *cpuid)
-{
- drmach_node_t *np;
-
- np = cp->dev.node;
-
- /*
- * If a CPU does not have a portid property, it must
- * be a CMP device with a cpuid property.
- */
- if (np->n_getprop(np, "portid", cpuid, sizeof (*cpuid)) != 0) {
-
- if (np->n_getprop(np, "cpuid", cpuid, sizeof (*cpuid)) != 0) {
- return (DRMACH_INTERNAL_ERROR());
- }
- }
-
- return (NULL);
-}
-
-/* Starcat CMP core id is bit 2 of the cpuid */
-#define DRMACH_COREID_MASK (1u << 2)
-#define DRMACH_CPUID2SRAM_IDX(id) \
- ((id & DRMACH_COREID_MASK) >> 1 | (id & 0x1))
-
-static sbd_error_t *
-drmach_cpu_new(drmach_device_t *proto, drmachid_t *idp)
-{
- sbd_error_t *err;
- uint64_t scr_pa;
- drmach_cpu_t *cp = NULL;
- pfn_t pfn;
- uint64_t cpu_stardrb_offset, cpu_sram_pa;
- int idx;
- int impl;
- processorid_t cpuid;
-
- err = drmach_read_reg_addr(proto, &scr_pa);
- if (err) {
- goto fail;
- }
-
- cp = kmem_zalloc(sizeof (drmach_cpu_t), KM_SLEEP);
- bcopy(proto, &cp->dev, sizeof (cp->dev));
- cp->dev.node = drmach_node_dup(proto->node);
- cp->dev.cm.isa = (void *)drmach_cpu_new;
- cp->dev.cm.dispose = drmach_cpu_dispose;
- cp->dev.cm.release = drmach_cpu_release;
- cp->dev.cm.status = drmach_cpu_status;
- cp->scr_pa = scr_pa;
-
- err = drmach_cpu_read_cpuid(cp, &cpuid);
- if (err) {
- goto fail;
- }
-
- err = drmach_cpu_get_impl(cp, &impl);
- if (err) {
- goto fail;
- }
-
- cp->cpuid = cpuid;
- cp->coreid = STARCAT_CPUID_TO_COREID(cp->cpuid);
- cp->dev.unum = STARCAT_CPUID_TO_AGENT(cp->cpuid);
-
- /*
- * Init the board cpu type. Assumes all board cpus are the same type.
- */
- if (cp->dev.bp->cpu_impl == 0) {
- cp->dev.bp->cpu_impl = impl;
- }
- ASSERT(cp->dev.bp->cpu_impl == impl);
-
- /*
- * XXX CHEETAH SUPPORT
- * determine if the domain uses Cheetah procs
- */
- if (drmach_is_cheetah < 0) {
- drmach_is_cheetah = IS_CHEETAH(impl);
- }
-
- /*
- * Initialize TTE for mapping CPU SRAM STARDRB buffer.
- * The STARDRB buffer (16KB on Cheetah+ boards, 32KB on
- * Jaguar/Panther boards) is shared by all cpus in a Safari port
- * pair. Each cpu uses 8KB according to the following layout:
- *
- * Page 0: even numbered Cheetah+'s and Panther/Jaguar core 0's
- * Page 1: odd numbered Cheetah+'s and Panther/Jaguar core 0's
- * Page 2: even numbered Panther/Jaguar core 1's
- * Page 3: odd numbered Panther/Jaguar core 1's
- */
- idx = DRMACH_CPUID2SRAM_IDX(cp->cpuid);
- cpu_stardrb_offset = cp->dev.bp->stardrb_offset + (PAGESIZE * idx);
- cpu_sram_pa = DRMACH_CPU_SRAM_ADDR + cpu_stardrb_offset;
- pfn = cpu_sram_pa >> PAGESHIFT;
-
- ASSERT(drmach_cpu_sram_tte[cp->cpuid].tte_inthi == 0 &&
- drmach_cpu_sram_tte[cp->cpuid].tte_intlo == 0);
- drmach_cpu_sram_tte[cp->cpuid].tte_inthi = TTE_PFN_INTHI(pfn) |
- TTE_VALID_INT | TTE_SZ_INT(TTE8K);
- drmach_cpu_sram_tte[cp->cpuid].tte_intlo = TTE_PFN_INTLO(pfn) |
- TTE_HWWR_INT | TTE_PRIV_INT | TTE_LCK_INT;
-
- DRMACH_PR("drmach_cpu_new: cpuid=%d, coreid=%d, stardrb_offset=0x%lx, "
- "cpu_sram_offset=0x%lx, idx=%d\n", cp->cpuid, cp->coreid,
- cp->dev.bp->stardrb_offset, cpu_stardrb_offset, idx);
-
- (void) snprintf(cp->dev.cm.name, sizeof (cp->dev.cm.name), "%s%d",
- cp->dev.type, cp->dev.unum);
-
- *idp = (drmachid_t)cp;
- return (NULL);
-
-fail:
- if (cp) {
- drmach_node_dispose(cp->dev.node);
- kmem_free(cp, sizeof (*cp));
- }
-
- *idp = (drmachid_t)0;
- return (err);
-}
-
-static void
-drmach_cpu_dispose(drmachid_t id)
-{
- drmach_cpu_t *self;
- processorid_t cpuid;
-
- ASSERT(DRMACH_IS_CPU_ID(id));
-
- self = id;
- if (self->dev.node)
- drmach_node_dispose(self->dev.node);
-
- cpuid = self->cpuid;
- ASSERT(TTE_IS_VALID(&drmach_cpu_sram_tte[cpuid]) &&
- TTE_IS_8K(&drmach_cpu_sram_tte[cpuid]) &&
- TTE_IS_PRIVILEGED(&drmach_cpu_sram_tte[cpuid]) &&
- TTE_IS_LOCKED(&drmach_cpu_sram_tte[cpuid]));
- drmach_cpu_sram_tte[cpuid].tte_inthi = 0;
- drmach_cpu_sram_tte[cpuid].tte_intlo = 0;
-
- kmem_free(self, sizeof (*self));
-}
-
-static int
-drmach_cpu_start(struct cpu *cp)
-{
- extern xcfunc_t drmach_set_lpa;
- extern void restart_other_cpu(int);
- int cpuid = cp->cpu_id;
- int rv, bnum;
- drmach_board_t *bp;
-
- ASSERT(MUTEX_HELD(&cpu_lock));
- ASSERT(cpunodes[cpuid].nodeid != (pnode_t)0);
-
- cp->cpu_flags &= ~CPU_POWEROFF;
-
- /*
- * NOTE: restart_other_cpu pauses cpus during the
- * slave cpu start. This helps to quiesce the
- * bus traffic a bit which makes the tick sync
- * routine in the prom more robust.
- */
- DRMACH_PR("COLD START for cpu (%d)\n", cpuid);
-
- if (prom_hotaddcpu(cpuid) != 0) {
- cmn_err(CE_PANIC, "prom_hotaddcpu() for cpuid=%d failed.",
- cpuid);
- }
-
- restart_other_cpu(cpuid);
-
- bnum = drmach_portid2bnum(cpunodes[cpuid].portid);
- rv = drmach_array_get(drmach_boards, bnum, (drmachid_t)&bp);
- if (rv == -1 || bp == NULL) {
- DRMACH_PR("drmach_cpu_start: cannot read board info for "
- "cpuid=%d: rv=%d, bp=%p\n", cpuid, rv, (void *)bp);
- } else if (DRMACH_L1_SET_LPA(bp) && drmach_reprogram_lpa) {
- int exp;
- int ntries;
-
- mutex_enter(&drmach_xt_mb_lock);
- mutex_enter(&drmach_slice_table_lock);
- bzero((void *)drmach_xt_mb, drmach_xt_mb_size);
-
- /*
- * drmach_slice_table[*]
- * bit 5 valid
- * bit 0:4 slice number
- *
- * drmach_xt_mb[*] format for drmach_set_lpa
- * bit 7 valid
- * bit 6 set null LPA (overrides bits 0:4)
- * bit 0:4 slice number
- *
- * drmach_set_lpa derives processor CBASE and CBND
- * from bits 6 and 0:4 of drmach_xt_mb. If bit 6 is
- * set, then CBASE = CBND = 0. Otherwise, CBASE = slice
- * number; CBND = slice number + 1.
- * No action is taken if bit 7 is zero.
- */
- exp = (cpuid >> 5) & 0x1f;
- if (drmach_slice_table[exp] & 0x20) {
- drmach_xt_mb[cpuid] = 0x80 |
- (drmach_slice_table[exp] & 0x1f);
- } else {
- drmach_xt_mb[cpuid] = 0x80 | 0x40;
- }
-
- drmach_xt_ready = 0;
-
- xt_one(cpuid, drmach_set_lpa, NULL, NULL);
-
- ntries = drmach_cpu_ntries;
- while (!drmach_xt_ready && ntries) {
- DELAY(drmach_cpu_delay);
- ntries--;
- }
-
- mutex_exit(&drmach_slice_table_lock);
- mutex_exit(&drmach_xt_mb_lock);
-
- DRMACH_PR(
- "waited %d out of %d tries for drmach_set_lpa on cpu%d",
- drmach_cpu_ntries - ntries, drmach_cpu_ntries,
- cp->cpu_id);
- }
-
- xt_one(cpuid, vtag_flushpage_tl1, (uint64_t)drmach_cpu_sram_va,
- (uint64_t)ksfmmup);
-
- return (0);
-}
-
-/*
- * A detaching CPU is xcalled with an xtrap to drmach_cpu_stop_self() after
- * it has been offlined. The function of this routine is to get the cpu
- * spinning in a safe place. The requirement is that the system will not
- * reference anything on the detaching board (memory and i/o is detached
- * elsewhere) and that the CPU not reference anything on any other board
- * in the system. This isolation is required during and after the writes
- * to the domain masks to remove the board from the domain.
- *
- * To accomplish this isolation the following is done:
- * 1) Create a locked mapping to the STARDRB data buffer located
- * in this cpu's sram. There is one TTE per cpu, initialized in
- * drmach_cpu_new(). The cpuid is used to select which TTE to use.
- * Each Safari port pair shares the CPU SRAM on a Serengeti CPU/MEM
- * board. The STARDRB buffer is 16KB on Cheetah+ boards, 32KB on Jaguar
- * boards. Each STARDRB buffer is logically divided by DR into one
- * 8KB page per cpu (or Jaguar core).
- * 2) Copy the target function (drmach_shutdown_asm) into buffer.
- * 3) Jump to function now in the cpu sram.
- * Function will:
- * 3.1) Flush its Ecache (displacement).
- * 3.2) Flush its Dcache with HW mechanism.
- * 3.3) Flush its Icache with HW mechanism.
- * 3.4) Flush all valid and _unlocked_ D-TLB and I-TLB entries.
- * 3.5) Set LPA to NULL
- * 3.6) Clear xt_mb to signal completion. Note: cache line is
- * recovered by drmach_cpu_poweroff().
- * 4) Jump into an infinite loop.
- */
-
-static void
-drmach_cpu_stop_self(void)
-{
- extern void drmach_shutdown_asm(uint64_t, uint64_t, int, int, uint64_t);
- extern void drmach_shutdown_asm_end(void);
-
- tte_t *tte;
- uint_t *p, *q;
- uint64_t stack_pointer;
-
- ASSERT(((ptrdiff_t)drmach_shutdown_asm_end -
- (ptrdiff_t)drmach_shutdown_asm) < PAGESIZE);
-
- tte = &drmach_cpu_sram_tte[CPU->cpu_id];
- ASSERT(TTE_IS_VALID(tte) && TTE_IS_8K(tte) && TTE_IS_PRIVILEGED(tte) &&
- TTE_IS_LOCKED(tte));
- sfmmu_dtlb_ld_kva(drmach_cpu_sram_va, tte);
- sfmmu_itlb_ld_kva(drmach_cpu_sram_va, tte);
-
- /* copy text. standard bcopy not designed to work in nc space */
- p = (uint_t *)drmach_cpu_sram_va;
- q = (uint_t *)drmach_shutdown_asm;
- while (q < (uint_t *)drmach_shutdown_asm_end)
- *p++ = *q++;
-
- /* zero to assist debug */
- q = (uint_t *)(drmach_cpu_sram_va + PAGESIZE);
- while (p < q)
- *p++ = 0;
-
- /* a parking spot for the stack pointer */
- stack_pointer = (uint64_t)q;
-
- /* call copy of drmach_shutdown_asm */
- (*(void (*)())drmach_cpu_sram_va)(
- stack_pointer,
- drmach_iocage_paddr,
- cpunodes[CPU->cpu_id].ecache_size,
- cpunodes[CPU->cpu_id].ecache_linesize,
- va_to_pa((void *)&drmach_xt_mb[CPU->cpu_id]));
-}
-
-static void
-drmach_cpu_shutdown_self(void)
-{
- cpu_t *cp = CPU;
- int cpuid = cp->cpu_id;
- extern void flush_windows(void);
-
- flush_windows();
-
- (void) spl8();
-
- ASSERT(cp->cpu_intr_actv == 0);
- ASSERT(cp->cpu_thread == cp->cpu_idle_thread ||
- cp->cpu_thread == cp->cpu_startup_thread);
-
- cp->cpu_flags = CPU_OFFLINE | CPU_QUIESCED | CPU_POWEROFF;
-
- drmach_cpu_stop_self();
-
- cmn_err(CE_PANIC, "CPU %d FAILED TO SHUTDOWN", cpuid);
-}
-
-static sbd_error_t *
-drmach_cpu_release(drmachid_t id)
-{
- drmach_cpu_t *cp;
- struct cpu *cpu;
- sbd_error_t *err;
-
- if (!DRMACH_IS_CPU_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- cp = id;
-
- ASSERT(MUTEX_HELD(&cpu_lock));
-
- cpu = cpu_get(cp->cpuid);
- if (cpu == NULL)
- err = DRMACH_INTERNAL_ERROR();
- else
- err = NULL;
-
- return (err);
-}
-
-static sbd_error_t *
-drmach_cpu_status(drmachid_t id, drmach_status_t *stat)
-{
- drmach_cpu_t *cp;
- drmach_device_t *dp;
-
- ASSERT(DRMACH_IS_CPU_ID(id));
- cp = id;
- dp = &cp->dev;
-
- stat->assigned = dp->bp->assigned;
- stat->powered = dp->bp->powered;
- mutex_enter(&cpu_lock);
- stat->configured = (cpu_get(cp->cpuid) != NULL);
- mutex_exit(&cpu_lock);
- stat->busy = dp->busy;
- (void) strncpy(stat->type, dp->type, sizeof (stat->type));
- stat->info[0] = '\0';
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_cpu_disconnect(drmachid_t id)
-{
- if (!DRMACH_IS_CPU_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_cpu_get_id(drmachid_t id, processorid_t *cpuid)
-{
- drmach_cpu_t *cpu;
-
- if (!DRMACH_IS_CPU_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- cpu = id;
-
- *cpuid = cpu->cpuid;
- return (NULL);
-}
-
-sbd_error_t *
-drmach_cpu_get_impl(drmachid_t id, int *ip)
-{
- drmach_node_t *np;
- int impl;
-
- if (!DRMACH_IS_CPU_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- np = ((drmach_device_t *)id)->node;
-
- if (np->n_getprop(np, "implementation#", &impl, sizeof (impl)) == -1) {
- return (DRMACH_INTERNAL_ERROR());
- }
-
- *ip = impl;
-
- return (NULL);
-}
-
-/*
- * Flush this cpu's ecache, then ensure all outstanding safari
- * transactions have retired.
- */
-void
-drmach_cpu_flush_ecache_sync(void)
-{
- uint64_t *p;
-
- ASSERT(curthread->t_bound_cpu == CPU);
-
- cpu_flush_ecache();
-
- mutex_enter(&drmach_bus_sync_lock);
- for (p = drmach_bus_sync_list; *p; p++)
- (void) ldphys(*p);
- mutex_exit(&drmach_bus_sync_lock);
-
- cpu_flush_ecache();
-}
-
-sbd_error_t *
-drmach_get_dip(drmachid_t id, dev_info_t **dip)
-{
- drmach_device_t *dp;
-
- if (!DRMACH_IS_DEVICE_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- dp = id;
-
- *dip = dp->node->n_getdip(dp->node);
- return (NULL);
-}
-
-sbd_error_t *
-drmach_io_is_attached(drmachid_t id, int *yes)
-{
- drmach_device_t *dp;
- dev_info_t *dip;
- int state;
-
- if (!DRMACH_IS_IO_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- dp = id;
-
- dip = dp->node->n_getdip(dp->node);
- if (dip == NULL) {
- *yes = 0;
- return (NULL);
- }
-
- state = ddi_get_devstate(dip);
- *yes = i_ddi_devi_attached(dip) || (state == DDI_DEVSTATE_UP);
-
- return (NULL);
-}
-
-static int
-drmach_dip_is_schizo_xmits_0_pci_b(dev_info_t *dip)
-{
- char dtype[OBP_MAXPROPNAME];
- int portid;
- uint_t pci_csr_base;
- struct pci_phys_spec *regbuf = NULL;
- int rv, len;
-
- ASSERT(dip != NULL);
- rv = ddi_getproplen(DDI_DEV_T_ANY, dip, 0, "device_type", &len);
- if ((rv != DDI_PROP_SUCCESS) || (len > sizeof (dtype)))
- return (0);
-
- if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "device_type",
- (caddr_t)dtype, &len) == DDI_PROP_SUCCESS) {
-
- if (strncmp(dtype, "pci", 3) == 0) {
-
- /*
- * Get safari portid. All schizo/xmits 0
- * safari IDs end in 0x1C.
- */
- rv = ddi_getproplen(DDI_DEV_T_ANY, dip, 0, "portid",
- &len);
-
- if ((rv != DDI_PROP_SUCCESS) ||
- (len > sizeof (portid)))
- return (0);
-
- rv = ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0,
- "portid", (caddr_t)&portid, &len);
-
- if (rv != DDI_PROP_SUCCESS)
- return (0);
-
- if ((portid & 0x1F) != 0x1C)
- return (0);
-
- if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "reg", (caddr_t)&regbuf,
- &len) == DDI_PROP_SUCCESS) {
-
- pci_csr_base = regbuf[0].pci_phys_mid &
- PCI_CONF_ADDR_MASK;
- kmem_free(regbuf, len);
- /*
- * All PCI B-Leafs are at configspace 0x70.0000.
- */
- if (pci_csr_base == 0x700000)
- return (1);
- }
- }
- }
- return (0);
-}
-
-#define SCHIZO_BINDING_NAME "pci108e,8001"
-#define XMITS_BINDING_NAME "pci108e,8002"
-
-/*
- * Verify if the dip is an instance of MAN 'eri'.
- */
-static int
-drmach_dip_is_man_eri(dev_info_t *dip)
-{
- struct pci_phys_spec *regbuf = NULL;
- dev_info_t *parent_dip;
- char *name;
- uint_t pci_device;
- uint_t pci_function;
- int len;
-
- if (dip == NULL)
- return (0);
- /*
- * Verify if the parent is schizo(xmits)0 and pci B leaf.
- */
- if (((parent_dip = ddi_get_parent(dip)) == NULL) ||
- ((name = ddi_binding_name(parent_dip)) == NULL))
- return (0);
- if (strcmp(name, SCHIZO_BINDING_NAME) != 0) {
- /*
- * This RIO could be on XMITS, so get the dip to
- * XMITS PCI Leaf.
- */
- if ((parent_dip = ddi_get_parent(parent_dip)) == NULL)
- return (0);
- if (((name = ddi_binding_name(parent_dip)) == NULL) ||
- (strcmp(name, XMITS_BINDING_NAME) != 0)) {
- return (0);
- }
- }
- if (!drmach_dip_is_schizo_xmits_0_pci_b(parent_dip))
- return (0);
- /*
- * Finally make sure it is the MAN eri.
- */
- if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "reg", (caddr_t)&regbuf, &len) == DDI_PROP_SUCCESS) {
-
- pci_device = PCI_REG_DEV_G(regbuf->pci_phys_hi);
- pci_function = PCI_REG_FUNC_G(regbuf->pci_phys_hi);
- kmem_free(regbuf, len);
-
- /*
- * The network function of the RIO ASIC will always be
- * device 3 and function 1 ("network@3,1").
- */
- if ((pci_device == 3) && (pci_function == 1))
- return (1);
- }
- return (0);
-}
-
-typedef struct {
- int iosram_inst;
- dev_info_t *eri_dip;
- int bnum;
-} drmach_io_inst_t;
-
-int
-drmach_board_find_io_insts(dev_info_t *dip, void *args)
-{
- drmach_io_inst_t *ios = (drmach_io_inst_t *)args;
-
- int rv;
- int len;
- int portid;
- char name[OBP_MAXDRVNAME];
-
- rv = ddi_getproplen(DDI_DEV_T_ANY, dip, 0, "portid", &len);
-
- if ((rv != DDI_PROP_SUCCESS) || (len > sizeof (portid))) {
- return (DDI_WALK_CONTINUE);
- }
-
- rv = ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0,
- "portid", (caddr_t)&portid, &len);
- if (rv != DDI_PROP_SUCCESS)
- return (DDI_WALK_CONTINUE);
-
- /* ignore devices that are not on this board */
- if (drmach_portid2bnum(portid) != ios->bnum)
- return (DDI_WALK_CONTINUE);
-
- if ((ios->iosram_inst < 0) || (ios->eri_dip == NULL)) {
- rv = ddi_getproplen(DDI_DEV_T_ANY, dip, 0, "name", &len);
- if (rv == DDI_PROP_SUCCESS) {
-
- rv = ddi_getlongprop_buf(DDI_DEV_T_ANY, dip,
- 0, "name",
- (caddr_t)name, &len);
- if (rv != DDI_PROP_SUCCESS)
- return (DDI_WALK_CONTINUE);
-
- if (strncmp("iosram", name, 6) == 0) {
- ios->iosram_inst = ddi_get_instance(dip);
- if (ios->eri_dip == NULL)
- return (DDI_WALK_CONTINUE);
- else
- return (DDI_WALK_TERMINATE);
- } else {
- if (drmach_dip_is_man_eri(dip)) {
- ASSERT(ios->eri_dip == NULL);
- ndi_hold_devi(dip);
- ios->eri_dip = dip;
- if (ios->iosram_inst < 0)
- return (DDI_WALK_CONTINUE);
- else
- return (DDI_WALK_TERMINATE);
- }
- }
- }
- }
- return (DDI_WALK_CONTINUE);
-}
-
-sbd_error_t *
-drmach_io_pre_release(drmachid_t id)
-{
- drmach_io_inst_t ios;
- drmach_board_t *bp;
- int rv = 0;
- sbd_error_t *err = NULL;
- drmach_device_t *dp;
- dev_info_t *rdip;
- int circ;
-
- if (!DRMACH_IS_IO_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- dp = id;
- bp = dp->bp;
-
- rdip = dp->node->n_getdip(dp->node);
-
- /* walk device tree to find iosram instance for the board */
- ios.iosram_inst = -1;
- ios.eri_dip = NULL;
- ios.bnum = bp->bnum;
-
- ndi_devi_enter(rdip, &circ);
- ddi_walk_devs(ddi_get_child(rdip), drmach_board_find_io_insts,
- (void *)&ios);
-
- DRMACH_PR("drmach_io_pre_release: bnum=%d iosram=%d eri=0x%p\n",
- ios.bnum, ios.iosram_inst, (void *)ios.eri_dip);
- ndi_devi_exit(rdip, circ);
-
- if (ios.eri_dip) {
- /*
- * Release hold acquired in drmach_board_find_io_insts()
- */
- ndi_rele_devi(ios.eri_dip);
- }
- if (ios.iosram_inst >= 0) {
- /* call for tunnel switch */
- do {
- DRMACH_PR("calling iosram_switchfrom(%d)\n",
- ios.iosram_inst);
- rv = iosram_switchfrom(ios.iosram_inst);
- if (rv)
- DRMACH_PR("iosram_switchfrom returned %d\n",
- rv);
- } while (rv == EAGAIN);
-
- if (rv)
- err = drerr_new(0, ESTC_IOSWITCH, NULL);
- }
- return (err);
-}
-
-sbd_error_t *
-drmach_io_unrelease(drmachid_t id)
-{
- dev_info_t *dip;
- sbd_error_t *err = NULL;
- drmach_device_t *dp;
-
- if (!DRMACH_IS_IO_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- dp = id;
-
- dip = dp->node->n_getdip(dp->node);
-
- if (dip == NULL)
- err = DRMACH_INTERNAL_ERROR();
- else {
- int (*func)(dev_info_t *dip);
-
- func = (int (*)(dev_info_t *))kobj_getsymvalue("man_dr_attach",
- 0);
-
- if (func) {
- drmach_io_inst_t ios;
- dev_info_t *pdip;
- int circ;
-
- /*
- * Walk device tree to find rio dip for the board
- * Since we are not interested in iosram instance here,
- * initialize it to 0, so that the walk terminates as
- * soon as eri dip is found.
- */
- ios.iosram_inst = 0;
- ios.eri_dip = NULL;
- ios.bnum = dp->bp->bnum;
-
- if (pdip = ddi_get_parent(dip)) {
- ndi_hold_devi(pdip);
- ndi_devi_enter(pdip, &circ);
- }
- /*
- * Root node doesn't have to be held in any way.
- */
- ddi_walk_devs(dip, drmach_board_find_io_insts,
- (void *)&ios);
-
- if (pdip) {
- ndi_devi_exit(pdip, circ);
- ndi_rele_devi(pdip);
- }
-
- DRMACH_PR("drmach_io_unrelease: bnum=%d eri=0x%p\n",
- ios.bnum, (void *)ios.eri_dip);
-
- if (ios.eri_dip) {
- DRMACH_PR("calling man_dr_attach\n");
- if ((*func)(ios.eri_dip))
- err = drerr_new(0, ESTC_NWSWITCH, NULL);
- /*
- * Release hold acquired in
- * drmach_board_find_io_insts()
- */
- ndi_rele_devi(ios.eri_dip);
- }
- } else
- DRMACH_PR("man_dr_attach NOT present\n");
- }
- return (err);
-}
-
-static sbd_error_t *
-drmach_io_release(drmachid_t id)
-{
- dev_info_t *dip;
- sbd_error_t *err = NULL;
- drmach_device_t *dp;
-
- if (!DRMACH_IS_IO_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- dp = id;
-
- dip = dp->node->n_getdip(dp->node);
-
- if (dip == NULL)
- err = DRMACH_INTERNAL_ERROR();
- else {
- int (*func)(dev_info_t *dip);
-
- func = (int (*)(dev_info_t *))kobj_getsymvalue("man_dr_detach",
- 0);
-
- if (func) {
- drmach_io_inst_t ios;
- dev_info_t *pdip;
- int circ;
-
- /*
- * Walk device tree to find rio dip for the board
- * Since we are not interested in iosram instance here,
- * initialize it to 0, so that the walk terminates as
- * soon as eri dip is found.
- */
- ios.iosram_inst = 0;
- ios.eri_dip = NULL;
- ios.bnum = dp->bp->bnum;
-
- if (pdip = ddi_get_parent(dip)) {
- ndi_hold_devi(pdip);
- ndi_devi_enter(pdip, &circ);
- }
- /*
- * Root node doesn't have to be held in any way.
- */
- ddi_walk_devs(dip, drmach_board_find_io_insts,
- (void *)&ios);
-
- if (pdip) {
- ndi_devi_exit(pdip, circ);
- ndi_rele_devi(pdip);
- }
-
- DRMACH_PR("drmach_io_release: bnum=%d eri=0x%p\n",
- ios.bnum, (void *)ios.eri_dip);
-
- if (ios.eri_dip) {
- DRMACH_PR("calling man_dr_detach\n");
- if ((*func)(ios.eri_dip))
- err = drerr_new(0, ESTC_NWSWITCH, NULL);
- /*
- * Release hold acquired in
- * drmach_board_find_io_insts()
- */
- ndi_rele_devi(ios.eri_dip);
- }
- } else
- DRMACH_PR("man_dr_detach NOT present\n");
- }
- return (err);
-}
-
-sbd_error_t *
-drmach_io_post_release(drmachid_t id)
-{
- char *path;
- dev_info_t *rdip;
- drmach_device_t *dp;
-
- if (!DRMACH_IS_DEVICE_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- dp = id;
-
- rdip = dp->node->n_getdip(dp->node);
-
- /*
- * Always called after drmach_unconfigure() which on Starcat
- * unconfigures the branch but doesn't remove it so the
- * dip must always exist.
- */
- ASSERT(rdip);
-
- ASSERT(e_ddi_branch_held(rdip));
-#ifdef DEBUG
- path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
- (void) ddi_pathname(rdip, path);
- DRMACH_PR("post_release dip path is: %s\n", path);
- kmem_free(path, MAXPATHLEN);
-#endif
-
- if (strcmp(dp->type, DRMACH_DEVTYPE_PCI) == 0) {
- if (schpc_remove_pci(rdip)) {
- DRMACH_PR("schpc_remove_pci failed\n");
- return (drerr_new(0, ESBD_OFFLINE, NULL));
- } else {
- DRMACH_PR("schpc_remove_pci succeeded\n");
- }
- }
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_io_post_attach(drmachid_t id)
-{
- int circ;
- dev_info_t *dip;
- dev_info_t *pdip;
- drmach_device_t *dp;
- drmach_io_inst_t ios;
-
- if (!DRMACH_IS_DEVICE_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- dp = id;
-
- dip = dp->node->n_getdip(dp->node);
-
- /*
- * We held the branch rooted at dip earlier, so at a minimum the
- * root i.e. dip must be present in the device tree.
- */
- ASSERT(dip);
-
- if (strcmp(dp->type, DRMACH_DEVTYPE_PCI) == 0) {
- if (schpc_add_pci(dip)) {
- DRMACH_PR("schpc_add_pci failed\n");
- } else {
- DRMACH_PR("schpc_add_pci succeeded\n");
- }
- }
-
- /*
- * Walk device tree to find rio dip for the board
- * Since we are not interested in iosram instance here,
- * initialize it to 0, so that the walk terminates as
- * soon as eri dip is found.
- */
- ios.iosram_inst = 0;
- ios.eri_dip = NULL;
- ios.bnum = dp->bp->bnum;
-
- if (pdip = ddi_get_parent(dip)) {
- ndi_hold_devi(pdip);
- ndi_devi_enter(pdip, &circ);
- }
- /*
- * Root node doesn't have to be held in any way.
- */
- ddi_walk_devs(dip, drmach_board_find_io_insts, (void *)&ios);
- if (pdip) {
- ndi_devi_exit(pdip, circ);
- ndi_rele_devi(pdip);
- }
-
- DRMACH_PR("drmach_io_post_attach: bnum=%d eri=0x%p\n",
- ios.bnum, (void *)ios.eri_dip);
-
- if (ios.eri_dip) {
- int (*func)(dev_info_t *dip);
-
- func =
- (int (*)(dev_info_t *))kobj_getsymvalue("man_dr_attach", 0);
-
- if (func) {
- DRMACH_PR("calling man_dr_attach\n");
- (void) (*func)(ios.eri_dip);
- } else {
- DRMACH_PR("man_dr_attach NOT present\n");
- }
-
- /*
- * Release hold acquired in drmach_board_find_io_insts()
- */
- ndi_rele_devi(ios.eri_dip);
-
- }
-
- return (NULL);
-}
-
-static sbd_error_t *
-drmach_io_status(drmachid_t id, drmach_status_t *stat)
-{
- drmach_device_t *dp;
- sbd_error_t *err;
- int configured;
-
- ASSERT(DRMACH_IS_IO_ID(id));
- dp = id;
-
- err = drmach_io_is_attached(id, &configured);
- if (err)
- return (err);
-
- stat->assigned = dp->bp->assigned;
- stat->powered = dp->bp->powered;
- stat->configured = (configured != 0);
- stat->busy = dp->busy;
- (void) strncpy(stat->type, dp->type, sizeof (stat->type));
- stat->info[0] = '\0';
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_mem_init_size(drmachid_t id)
-{
- drmach_mem_t *mp;
- sbd_error_t *err;
- gdcd_t *gdcd;
- mem_chunk_t *chunk;
- uint64_t chunks, pa, mask, sz;
-
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- mp = id;
-
- err = drmach_mem_get_base_physaddr(id, &pa);
- if (err)
- return (err);
-
- mask = ~ (DRMACH_MEM_SLICE_SIZE - 1);
- pa &= mask;
-
- gdcd = drmach_gdcd_new();
- if (gdcd == NULL)
- return (DRMACH_INTERNAL_ERROR());
-
- sz = 0;
- chunk = gdcd->dcd_chunk_list.dcl_chunk;
- chunks = gdcd->dcd_chunk_list.dcl_chunks;
- while (chunks-- != 0) {
- if ((chunk->mc_base_pa & mask) == pa) {
- sz += chunk->mc_mbytes * 1048576;
- }
-
- ++chunk;
- }
- mp->nbytes = sz;
-
- drmach_gdcd_dispose(gdcd);
- return (NULL);
-}
-
-/*
- * Hardware registers are organized into consecutively
- * addressed registers. The reg property's hi and lo fields
- * together describe the base address of the register set for
- * this memory-controller. Register descriptions and offsets
- * (from the base address) are as follows:
- *
- * Description Offset Size (bytes)
- * Memory Timing Control Register I 0x00 8
- * Memory Timing Control Register II 0x08 8
- * Memory Address Decoding Register I 0x10 8
- * Memory Address Decoding Register II 0x18 8
- * Memory Address Decoding Register III 0x20 8
- * Memory Address Decoding Register IV 0x28 8
- * Memory Address Control Register 0x30 8
- * Memory Timing Control Register III 0x38 8
- * Memory Timing Control Register IV 0x40 8
- * Memory Timing Control Register V 0x48 8 (Jaguar, Panther only)
- * EMU Activity Status Register 0x50 8 (Panther only)
- *
- * Only the Memory Address Decoding Register and EMU Activity Status
- * Register addresses are needed for DRMACH.
- */
-static sbd_error_t *
-drmach_mem_new(drmach_device_t *proto, drmachid_t *idp)
-{
- sbd_error_t *err;
- uint64_t madr_pa;
- drmach_mem_t *mp;
- int bank, count;
-
- err = drmach_read_reg_addr(proto, &madr_pa);
- if (err)
- return (err);
-
- mp = kmem_zalloc(sizeof (drmach_mem_t), KM_SLEEP);
- bcopy(proto, &mp->dev, sizeof (mp->dev));
- mp->dev.node = drmach_node_dup(proto->node);
- mp->dev.cm.isa = (void *)drmach_mem_new;
- mp->dev.cm.dispose = drmach_mem_dispose;
- mp->dev.cm.release = drmach_mem_release;
- mp->dev.cm.status = drmach_mem_status;
- mp->madr_pa = madr_pa;
-
- (void) snprintf(mp->dev.cm.name,
- sizeof (mp->dev.cm.name), "%s", mp->dev.type);
-
- for (count = bank = 0; bank < DRMACH_MC_NBANKS; bank++) {
- uint64_t madr;
-
- drmach_mem_read_madr(mp, bank, &madr);
- if (madr & DRMACH_MC_VALID_MASK) {
- count += 1;
- break;
- }
- }
-
- /*
- * If none of the banks had their valid bit set, that means
- * post did not configure this MC to participate in the
- * domain. So, pretend this node does not exist by returning
- * a drmachid of zero.
- */
- if (count == 0) {
- /* drmach_mem_dispose frees board mem list */
- drmach_node_dispose(mp->dev.node);
- kmem_free(mp, sizeof (*mp));
- *idp = (drmachid_t)0;
- return (NULL);
- }
-
- /*
- * Only one mem unit per board is exposed to the
- * PIM layer. The first mem unit encountered during
- * tree walk is used to represent all mem units on
- * the same board.
- */
- if (mp->dev.bp->mem == NULL) {
- /* start list of mem units on this board */
- mp->dev.bp->mem = mp;
-
- /*
- * force unum to zero since this is the only mem unit
- * that will be visible to the PIM layer.
- */
- mp->dev.unum = 0;
-
- /*
- * board memory size kept in this mem unit only
- */
- err = drmach_mem_init_size(mp);
- if (err) {
- mp->dev.bp->mem = NULL;
- /* drmach_mem_dispose frees board mem list */
- drmach_node_dispose(mp->dev.node);
- kmem_free(mp, sizeof (*mp));
- *idp = (drmachid_t)0;
- return (NULL);
- }
-
- /*
- * allow this instance (the first encountered on this board)
- * to be visible to the PIM layer.
- */
- *idp = (drmachid_t)mp;
- } else {
- drmach_mem_t *lp;
-
- /* hide this mem instance behind the first. */
- for (lp = mp->dev.bp->mem; lp->next; lp = lp->next)
- ;
- lp->next = mp;
-
- /*
- * hide this instance from the caller.
- * See drmach_board_find_devices_cb() for details.
- */
- *idp = (drmachid_t)0;
- }
-
- return (NULL);
-}
-
-static void
-drmach_mem_dispose(drmachid_t id)
-{
- drmach_mem_t *mp, *next;
- drmach_board_t *bp;
-
- ASSERT(DRMACH_IS_MEM_ID(id));
-
- mutex_enter(&drmach_bus_sync_lock);
-
- mp = id;
- bp = mp->dev.bp;
-
- do {
- if (mp->dev.node)
- drmach_node_dispose(mp->dev.node);
-
- next = mp->next;
- kmem_free(mp, sizeof (*mp));
- mp = next;
- } while (mp);
-
- bp->mem = NULL;
-
- drmach_bus_sync_list_update();
- mutex_exit(&drmach_bus_sync_lock);
-}
-
-sbd_error_t *
-drmach_mem_add_span(drmachid_t id, uint64_t basepa, uint64_t size)
-{
- pfn_t basepfn = (pfn_t)(basepa >> PAGESHIFT);
- pgcnt_t npages = (pgcnt_t)(size >> PAGESHIFT);
- int rv;
-
- ASSERT(size != 0);
-
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- rv = kcage_range_add(basepfn, npages, KCAGE_DOWN);
- if (rv == ENOMEM) {
- cmn_err(CE_WARN, "%lu megabytes not available"
- " to kernel cage", size >> 20);
- } else if (rv != 0) {
- /* catch this in debug kernels */
- ASSERT(0);
-
- cmn_err(CE_WARN, "unexpected kcage_range_add"
- " return value %d", rv);
- }
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_mem_del_span(drmachid_t id, uint64_t basepa, uint64_t size)
-{
- pfn_t basepfn = (pfn_t)(basepa >> PAGESHIFT);
- pgcnt_t npages = (pgcnt_t)(size >> PAGESHIFT);
- int rv;
-
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- if (size > 0) {
- rv = kcage_range_delete_post_mem_del(basepfn, npages);
- if (rv != 0) {
- cmn_err(CE_WARN,
- "unexpected kcage_range_delete_post_mem_del"
- " return value %d", rv);
- return (DRMACH_INTERNAL_ERROR());
- }
- }
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_mem_disable(drmachid_t id)
-{
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- else
- return (NULL);
-}
-
-sbd_error_t *
-drmach_mem_enable(drmachid_t id)
-{
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- else
- return (NULL);
-}
-
-sbd_error_t *
-drmach_mem_get_alignment(drmachid_t id, uint64_t *mask)
-{
-#define MB(mb) ((mb) * 1048576ull)
-
- static struct {
- uint_t uk;
- uint64_t segsz;
- } uk2segsz[] = {
- { 0x003, MB(256) },
- { 0x007, MB(512) },
- { 0x00f, MB(1024) },
- { 0x01f, MB(2048) },
- { 0x03f, MB(4096) },
- { 0x07f, MB(8192) },
- { 0x0ff, MB(16384) },
- { 0x1ff, MB(32768) },
- { 0x3ff, MB(65536) },
- { 0x7ff, MB(131072) }
- };
- static int len = sizeof (uk2segsz) / sizeof (uk2segsz[0]);
-
-#undef MB
-
- uint64_t largest_sz = 0;
- drmach_mem_t *mp;
-
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- /* prime the result with a default value */
- *mask = (DRMACH_MEM_SLICE_SIZE - 1);
-
- for (mp = id; mp; mp = mp->next) {
- int bank;
-
- for (bank = 0; bank < DRMACH_MC_NBANKS; bank++) {
- int i;
- uint_t uk;
- uint64_t madr;
-
- /* get register value, extract uk and normalize */
- drmach_mem_read_madr(mp, bank, &madr);
-
- if (!(madr & DRMACH_MC_VALID_MASK))
- continue;
-
- uk = DRMACH_MC_UK(madr);
-
- /* match uk value */
- for (i = 0; i < len; i++)
- if (uk == uk2segsz[i].uk)
- break;
-
- if (i < len) {
- uint64_t sz = uk2segsz[i].segsz;
-
- /*
- * remember largest segment size,
- * update mask result
- */
- if (sz > largest_sz) {
- largest_sz = sz;
- *mask = sz - 1;
- }
- } else {
- /*
- * uk not in table, punt using
- * entire slice size. no longer any
- * reason to check other banks.
- */
- *mask = (DRMACH_MEM_SLICE_SIZE - 1);
- return (NULL);
- }
- }
- }
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_mem_get_base_physaddr(drmachid_t id, uint64_t *base_addr)
-{
- drmach_mem_t *mp;
-
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- *base_addr = (uint64_t)-1;
- for (mp = id; mp; mp = mp->next) {
- int bank;
-
- for (bank = 0; bank < DRMACH_MC_NBANKS; bank++) {
- uint64_t addr, madr;
-
- drmach_mem_read_madr(mp, bank, &madr);
- if (madr & DRMACH_MC_VALID_MASK) {
- addr = DRMACH_MC_UM_TO_PA(madr) |
- DRMACH_MC_LM_TO_PA(madr);
-
- if (addr < *base_addr)
- *base_addr = addr;
- }
- }
- }
-
- /* should not happen, but ... */
- if (*base_addr == (uint64_t)-1)
- return (DRMACH_INTERNAL_ERROR());
-
- return (NULL);
-}
-
-void
-drmach_bus_sync_list_update(void)
-{
- int rv, idx, cnt = 0;
- drmachid_t id;
-
- ASSERT(MUTEX_HELD(&drmach_bus_sync_lock));
-
- rv = drmach_array_first(drmach_boards, &idx, &id);
- while (rv == 0) {
- drmach_board_t *bp = id;
- drmach_mem_t *mp = bp->mem;
-
- while (mp) {
- int bank;
-
- for (bank = 0; bank < DRMACH_MC_NBANKS; bank++) {
- uint64_t madr;
-
- drmach_mem_read_madr(mp, bank, &madr);
- if (madr & DRMACH_MC_VALID_MASK) {
- uint64_t pa;
-
- pa = DRMACH_MC_UM_TO_PA(madr);
- pa |= DRMACH_MC_LM_TO_PA(madr);
-
- /*
- * The list is zero terminated.
- * Offset the pa by a doubleword
- * to avoid confusing a pa value of
- * of zero with the terminator.
- */
- pa += sizeof (uint64_t);
-
- drmach_bus_sync_list[cnt++] = pa;
- }
- }
-
- mp = mp->next;
- }
-
- rv = drmach_array_next(drmach_boards, &idx, &id);
- }
-
- drmach_bus_sync_list[cnt] = 0;
-}
-
-sbd_error_t *
-drmach_mem_get_memlist(drmachid_t id, struct memlist **ml)
-{
- sbd_error_t *err;
- struct memlist *mlist;
- gdcd_t *gdcd;
- mem_chunk_t *chunk;
- uint64_t chunks, pa, mask;
-
- err = drmach_mem_get_base_physaddr(id, &pa);
- if (err)
- return (err);
-
- gdcd = drmach_gdcd_new();
- if (gdcd == NULL)
- return (DRMACH_INTERNAL_ERROR());
-
- mask = ~ (DRMACH_MEM_SLICE_SIZE - 1);
- pa &= mask;
-
- mlist = NULL;
- chunk = gdcd->dcd_chunk_list.dcl_chunk;
- chunks = gdcd->dcd_chunk_list.dcl_chunks;
- while (chunks-- != 0) {
- if ((chunk->mc_base_pa & mask) == pa) {
- mlist = memlist_add_span(mlist, chunk->mc_base_pa,
- chunk->mc_mbytes * 1048576);
- }
-
- ++chunk;
- }
-
- drmach_gdcd_dispose(gdcd);
-
-#ifdef DEBUG
- DRMACH_PR("GDCD derived memlist:");
- memlist_dump(mlist);
-#endif
-
- *ml = mlist;
- return (NULL);
-}
-
-sbd_error_t *
-drmach_mem_get_size(drmachid_t id, uint64_t *bytes)
-{
- drmach_mem_t *mp;
-
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- mp = id;
-
- ASSERT(mp->nbytes != 0);
- *bytes = mp->nbytes;
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_mem_get_slice_size(drmachid_t id, uint64_t *bytes)
-{
- sbd_error_t *err;
- drmach_device_t *mp;
-
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- mp = id;
-
- switch (DRMACH_BNUM2SLOT(mp->bp->bnum)) {
- case 0: *bytes = DRMACH_MEM_USABLE_SLICE_SIZE;
- err = NULL;
- break;
-
- case 1: *bytes = 0;
- err = NULL;
- break;
-
- default:
- err = DRMACH_INTERNAL_ERROR();
- break;
- }
-
- return (err);
-}
-
-processorid_t drmach_mem_cpu_affinity_nail;
-
-processorid_t
-drmach_mem_cpu_affinity(drmachid_t id)
-{
- drmach_device_t *mp;
- drmach_board_t *bp;
- processorid_t cpuid;
-
- if (!DRMACH_IS_MEM_ID(id))
- return (CPU_CURRENT);
-
- if (drmach_mem_cpu_affinity_nail) {
- cpuid = drmach_mem_cpu_affinity_nail;
-
- if (cpuid < 0 || cpuid > NCPU)
- return (CPU_CURRENT);
-
- mutex_enter(&cpu_lock);
- if (cpu[cpuid] == NULL || !CPU_ACTIVE(cpu[cpuid]))
- cpuid = CPU_CURRENT;
- mutex_exit(&cpu_lock);
-
- return (cpuid);
- }
-
- /* try to choose a proc on the target board */
- mp = id;
- bp = mp->bp;
- if (bp->devices) {
- int rv;
- int d_idx;
- drmachid_t d_id;
-
- rv = drmach_array_first(bp->devices, &d_idx, &d_id);
- while (rv == 0) {
- if (DRMACH_IS_CPU_ID(d_id)) {
- drmach_cpu_t *cp = d_id;
-
- mutex_enter(&cpu_lock);
- cpuid = cp->cpuid;
- if (cpu[cpuid] && CPU_ACTIVE(cpu[cpuid])) {
- mutex_exit(&cpu_lock);
- return (cpuid);
- } else {
- mutex_exit(&cpu_lock);
- }
- }
-
- rv = drmach_array_next(bp->devices, &d_idx, &d_id);
- }
- }
-
- /* otherwise, this proc, wherever it is */
- return (CPU_CURRENT);
-}
-
-static sbd_error_t *
-drmach_mem_release(drmachid_t id)
-{
- if (!DRMACH_IS_MEM_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- return (NULL);
-}
-
-static sbd_error_t *
-drmach_mem_status(drmachid_t id, drmach_status_t *stat)
-{
- drmach_mem_t *mp;
- sbd_error_t *err;
- uint64_t pa, slice_size;
- struct memlist *ml;
-
- ASSERT(DRMACH_IS_MEM_ID(id));
- mp = id;
-
- /* get starting physical address of target memory */
- err = drmach_mem_get_base_physaddr(id, &pa);
- if (err)
- return (err);
-
- /* round down to slice boundary */
- slice_size = DRMACH_MEM_SLICE_SIZE;
- pa &= ~ (slice_size - 1);
-
- /* stop at first span that is in slice */
- memlist_read_lock();
- for (ml = phys_install; ml; ml = ml->ml_next)
- if (ml->ml_address >= pa && ml->ml_address < pa + slice_size)
- break;
- memlist_read_unlock();
-
- stat->assigned = mp->dev.bp->assigned;
- stat->powered = mp->dev.bp->powered;
- stat->configured = (ml != NULL);
- stat->busy = mp->dev.busy;
- (void) strncpy(stat->type, mp->dev.type, sizeof (stat->type));
- stat->info[0] = '\0';
-
- return (NULL);
-}
-
-sbd_error_t *
-drmach_board_deprobe(drmachid_t id)
-{
- drmach_board_t *bp;
- sbd_error_t *err = NULL;
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- bp = id;
-
- if (bp->tree) {
- drmach_node_dispose(bp->tree);
- bp->tree = NULL;
- }
- if (bp->devices) {
- drmach_array_dispose(bp->devices, drmach_device_dispose);
- bp->devices = NULL;
- bp->mem = NULL; /* TODO: still needed? */
- }
- return (err);
-}
-
-/*ARGSUSED1*/
-static sbd_error_t *
-drmach_pt_showlpa(drmachid_t id, drmach_opts_t *opts)
-{
- drmach_device_t *dp;
- uint64_t val;
- int err = 1;
-
- if (DRMACH_IS_CPU_ID(id)) {
- drmach_cpu_t *cp = id;
- if (drmach_cpu_read_scr(cp, &val))
- err = 0;
- } else if (DRMACH_IS_IO_ID(id) && ((drmach_io_t *)id)->scsr_pa != 0) {
- drmach_io_t *io = id;
- val = lddphysio(io->scsr_pa);
- err = 0;
- }
- if (err)
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- dp = id;
- uprintf("showlpa %s::%s portid %d, base pa %lx, bound pa %lx\n",
- dp->bp->cm.name,
- dp->cm.name,
- dp->portid,
- (long)(DRMACH_LPA_BASE_TO_PA(val)),
- (long)(DRMACH_LPA_BND_TO_PA(val)));
-
- return (NULL);
-}
-
-/*ARGSUSED*/
-static sbd_error_t *
-drmach_pt_ikprobe(drmachid_t id, drmach_opts_t *opts)
-{
- drmach_board_t *bp = (drmach_board_t *)id;
- sbd_error_t *err;
- sc_gptwocfg_cookie_t scc;
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
-
- /* do saf configurator stuff */
- DRMACH_PR("calling sc_probe_board for bnum=%d\n", bp->bnum);
- scc = sc_probe_board(bp->bnum);
- if (scc == NULL) {
- err = drerr_new(0, ESTC_PROBE, bp->cm.name);
- return (err);
- }
-
- return (err);
-}
-
-/*ARGSUSED*/
-static sbd_error_t *
-drmach_pt_ikdeprobe(drmachid_t id, drmach_opts_t *opts)
-{
- drmach_board_t *bp;
- sbd_error_t *err = NULL;
- sc_gptwocfg_cookie_t scc;
-
- if (!DRMACH_IS_BOARD_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- bp = id;
-
- cmn_err(CE_CONT, "DR: in-kernel unprobe board %d\n", bp->bnum);
- scc = sc_unprobe_board(bp->bnum);
- if (scc != NULL) {
- err = drerr_new(0, ESTC_DEPROBE, bp->cm.name);
- }
-
- if (err == NULL)
- err = drmach_board_deprobe(id);
-
- return (err);
-}
-
-static sbd_error_t *
-drmach_pt_readmem(drmachid_t id, drmach_opts_t *opts)
-{
- _NOTE(ARGUNUSED(id))
- _NOTE(ARGUNUSED(opts))
-
- struct memlist *ml;
- uint64_t src_pa;
- uint64_t dst_pa;
- uint64_t dst;
-
- dst_pa = va_to_pa(&dst);
-
- memlist_read_lock();
- for (ml = phys_install; ml; ml = ml->ml_next) {
- uint64_t nbytes;
-
- src_pa = ml->ml_address;
- nbytes = ml->ml_size;
-
- while (nbytes != 0ull) {
-
- /* copy 32 bytes at src_pa to dst_pa */
- bcopy32_il(src_pa, dst_pa);
-
- /* increment by 32 bytes */
- src_pa += (4 * sizeof (uint64_t));
-
- /* decrement by 32 bytes */
- nbytes -= (4 * sizeof (uint64_t));
- }
- }
- memlist_read_unlock();
-
- return (NULL);
-}
-
-static sbd_error_t *
-drmach_pt_recovercpu(drmachid_t id, drmach_opts_t *opts)
-{
- _NOTE(ARGUNUSED(opts))
-
- drmach_cpu_t *cp;
-
- if (!DRMACH_IS_CPU_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- cp = id;
-
- mutex_enter(&cpu_lock);
- (void) drmach_iocage_cpu_return(&(cp->dev),
- CPU_ENABLE | CPU_EXISTS | CPU_READY | CPU_RUNNING);
- mutex_exit(&cpu_lock);
-
- return (NULL);
-}
-
-/*
- * Starcat DR passthrus are for debugging purposes only.
- */
-static struct {
- const char *name;
- sbd_error_t *(*handler)(drmachid_t id, drmach_opts_t *opts);
-} drmach_pt_arr[] = {
- { "showlpa", drmach_pt_showlpa },
- { "ikprobe", drmach_pt_ikprobe },
- { "ikdeprobe", drmach_pt_ikdeprobe },
- { "readmem", drmach_pt_readmem },
- { "recovercpu", drmach_pt_recovercpu },
-
- /* the following line must always be last */
- { NULL, NULL }
-};
-
-/*ARGSUSED*/
-sbd_error_t *
-drmach_passthru(drmachid_t id, drmach_opts_t *opts)
-{
- int i;
- sbd_error_t *err;
-
- i = 0;
- while (drmach_pt_arr[i].name != NULL) {
- int len = strlen(drmach_pt_arr[i].name);
-
- if (strncmp(drmach_pt_arr[i].name, opts->copts, len) == 0)
- break;
-
- i += 1;
- }
-
- if (drmach_pt_arr[i].name == NULL)
- err = drerr_new(0, ESTC_UNKPTCMD, opts->copts);
- else
- err = (*drmach_pt_arr[i].handler)(id, opts);
-
- return (err);
-}
-
-sbd_error_t *
-drmach_release(drmachid_t id)
-{
- drmach_common_t *cp;
-
- if (!DRMACH_IS_DEVICE_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- cp = id;
-
- return (cp->release(id));
-}
-
-sbd_error_t *
-drmach_status(drmachid_t id, drmach_status_t *stat)
-{
- drmach_common_t *cp;
- sbd_error_t *err;
-
- rw_enter(&drmach_boards_rwlock, RW_READER);
-
- if (!DRMACH_IS_ID(id)) {
- rw_exit(&drmach_boards_rwlock);
- return (drerr_new(0, ESTC_NOTID, NULL));
- }
-
- cp = id;
-
- err = cp->status(id, stat);
- rw_exit(&drmach_boards_rwlock);
- return (err);
-}
-
-static sbd_error_t *
-drmach_i_status(drmachid_t id, drmach_status_t *stat)
-{
- drmach_common_t *cp;
-
- if (!DRMACH_IS_ID(id))
- return (drerr_new(0, ESTC_NOTID, NULL));
- cp = id;
-
- return (cp->status(id, stat));
-}
-
-/*ARGSUSED*/
-sbd_error_t *
-drmach_unconfigure(drmachid_t id, int flags)
-{
- drmach_device_t *dp;
- dev_info_t *rdip;
-
- char name[OBP_MAXDRVNAME];
- int rv;
-
- /*
- * Since CPU nodes are not configured, it is
- * necessary to skip the unconfigure step as
- * well.
- */
- if (DRMACH_IS_CPU_ID(id)) {
- return (NULL);
- }
-
- for (; id; ) {
- dev_info_t *fdip = NULL;
-
- if (!DRMACH_IS_DEVICE_ID(id))
- return (drerr_new(0, ESTC_INAPPROP, NULL));
- dp = id;
-
- rdip = dp->node->n_getdip(dp->node);
-
- /*
- * drmach_unconfigure() is always called on a configured branch.
- * So the root of the branch was held earlier and must exist.
- */
- ASSERT(rdip);
-
- DRMACH_PR("drmach_unconfigure: unconfiguring DDI branch");
-
- rv = dp->node->n_getprop(dp->node,
- "name", name, OBP_MAXDRVNAME);
-
- /* The node must have a name */
- if (rv)
- return (0);
-
- if (drmach_name2type_idx(name) < 0) {
- if (DRMACH_IS_MEM_ID(id)) {
- drmach_mem_t *mp = id;
- id = mp->next;
- } else {
- id = NULL;
- }
- continue;
- }
-
- /*
- * NOTE: FORCE flag is no longer needed under devfs
- */
- ASSERT(e_ddi_branch_held(rdip));
- if (e_ddi_branch_unconfigure(rdip, &fdip, 0) != 0) {
- sbd_error_t *err = NULL;
- char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
-
- /*
- * If non-NULL, fdip is returned held and must be
- * released.
- */
- if (fdip != NULL) {
- (void) ddi_pathname(fdip, path);
- ddi_release_devi(fdip);
- } else {
- (void) ddi_pathname(rdip, path);
- }
-
- err = drerr_new(1, ESTC_DRVFAIL, path);
-
- kmem_free(path, MAXPATHLEN);
-
- /*
- * If we were unconfiguring an IO board, a call was
- * made to man_dr_detach. We now need to call
- * man_dr_attach to regain man use of the eri.
- */
- if (DRMACH_IS_IO_ID(id)) {
- int (*func)(dev_info_t *dip);
-
- func = (int (*)(dev_info_t *))kobj_getsymvalue\
- ("man_dr_attach", 0);
-
- if (func) {
- drmach_io_inst_t ios;
- dev_info_t *pdip;
- int circ;
-
- /*
- * Walk device tree to find rio dip for
- * the board
- * Since we are not interested in iosram
- * instance here, initialize it to 0, so
- * that the walk terminates as soon as
- * eri dip is found.
- */
- ios.iosram_inst = 0;
- ios.eri_dip = NULL;
- ios.bnum = dp->bp->bnum;
-
- if (pdip = ddi_get_parent(rdip)) {
- ndi_hold_devi(pdip);
- ndi_devi_enter(pdip, &circ);
- }
- /*
- * Root node doesn't have to be held in
- * any way.
- */
- ASSERT(e_ddi_branch_held(rdip));
- ddi_walk_devs(rdip,
- drmach_board_find_io_insts,
- (void *)&ios);
-
- DRMACH_PR("drmach_unconfigure: bnum=%d"
- " eri=0x%p\n",
- ios.bnum, (void *)ios.eri_dip);
-
- if (pdip) {
- ndi_devi_exit(pdip, circ);
- ndi_rele_devi(pdip);
- }
-
- if (ios.eri_dip) {
- DRMACH_PR("calling"
- " man_dr_attach\n");
- (void) (*func)(ios.eri_dip);
- /*
- * Release hold acquired in
- * drmach_board_find_io_insts()
- */
- ndi_rele_devi(ios.eri_dip);
- }
- }
- }
- return (err);
- }
-
- if (DRMACH_IS_MEM_ID(id)) {
- drmach_mem_t *mp = id;
- id = mp->next;
- } else {
- id = NULL;
- }
- }
-
- return (NULL);
-}
-
-/*
- * drmach interfaces to legacy Starfire platmod logic
- * linkage via runtime symbol look up, called from plat_cpu_power*
- */
-
-/*
- * Start up a cpu. It is possible that we're attempting to restart
- * the cpu after an UNCONFIGURE in which case the cpu will be
- * spinning in its cache. So, all we have to do is wake it up.
- * Under normal circumstances the cpu will be coming from a previous
- * CONNECT and thus will be spinning in OBP. In both cases, the
- * startup sequence is the same.
- */
-int
-drmach_cpu_poweron(struct cpu *cp)
-{
- DRMACH_PR("drmach_cpu_poweron: starting cpuid %d\n", cp->cpu_id);
-
- ASSERT(MUTEX_HELD(&cpu_lock));
-
- if (drmach_cpu_start(cp) != 0)
- return (EBUSY);
- else
- return (0);
-}
-
-int
-drmach_cpu_poweroff(struct cpu *cp)
-{
- int ntries;
- processorid_t cpuid;
- void drmach_cpu_shutdown_self(void);
-
- DRMACH_PR("drmach_cpu_poweroff: stopping cpuid %d\n", cp->cpu_id);
-
- ASSERT(MUTEX_HELD(&cpu_lock));
-
- /*
- * XXX CHEETAH SUPPORT
- * for cheetah, we need to grab the iocage lock since iocage
- * memory is used for e$ flush.
- */
- if (drmach_is_cheetah) {
- mutex_enter(&drmach_iocage_lock);
- while (drmach_iocage_is_busy)
- cv_wait(&drmach_iocage_cv, &drmach_iocage_lock);
- drmach_iocage_is_busy = 1;
- drmach_iocage_mem_scrub(ecache_size * 2);
- mutex_exit(&drmach_iocage_lock);
- }
-
- cpuid = cp->cpu_id;
-
- /*
- * Set affinity to ensure consistent reading and writing of
- * drmach_xt_mb[cpuid] by one "master" CPU directing
- * the shutdown of the target CPU.
- */
- affinity_set(CPU->cpu_id);
-
- /*
- * Capture all CPUs (except for detaching proc) to prevent
- * crosscalls to the detaching proc until it has cleared its
- * bit in cpu_ready_set.
- *
- * The CPUs remain paused and the prom_mutex is known to be free.
- * This prevents blocking when doing prom IEEE-1275 calls at a
- * high PIL level.
- */
- promsafe_pause_cpus();
-
- /*
- * Quiesce interrupts on the target CPU. We do this by setting
- * the CPU 'not ready'- (i.e. removing the CPU from cpu_ready_set) to
- * prevent it from receiving cross calls and cross traps.
- * This prevents the processor from receiving any new soft interrupts.
- */
- mp_cpu_quiesce(cp);
-
- (void) prom_hotremovecpu(cpuid);
-
- start_cpus();
-
- /* setup xt_mb, will be cleared by drmach_shutdown_asm when ready */
- drmach_xt_mb[cpuid] = 0x80;
-
- xt_one_unchecked(cp->cpu_id, (xcfunc_t *)idle_stop_xcall,
- (uint64_t)drmach_cpu_shutdown_self, NULL);
-
- ntries = drmach_cpu_ntries;
- while (drmach_xt_mb[cpuid] && ntries) {
- DELAY(drmach_cpu_delay);
- ntries--;
- }
-
- drmach_xt_mb[cpuid] = 0; /* steal the cache line back */
-
- membar_sync(); /* make sure copy-back retires */
-
- affinity_clear();
-
- /*
- * XXX CHEETAH SUPPORT
- */
- if (drmach_is_cheetah) {
- mutex_enter(&drmach_iocage_lock);
- drmach_iocage_mem_scrub(ecache_size * 2);
- drmach_iocage_is_busy = 0;
- cv_signal(&drmach_iocage_cv);
- mutex_exit(&drmach_iocage_lock);
- }
-
- DRMACH_PR("waited %d out of %d tries for "
- "drmach_cpu_shutdown_self on cpu%d",
- drmach_cpu_ntries - ntries, drmach_cpu_ntries, cp->cpu_id);
-
- /*
- * Do this here instead of drmach_cpu_shutdown_self() to
- * avoid an assertion failure panic in turnstile.c.
- */
- CPU_SIGNATURE(OS_SIG, SIGST_DETACHED, SIGSUBST_NULL, cpuid);
-
- return (0);
-}
-
-void
-drmach_iocage_mem_scrub(uint64_t nbytes)
-{
- extern uint32_t drmach_bc_bzero(void*, size_t);
- uint32_t rv;
-
- ASSERT(MUTEX_HELD(&cpu_lock));
-
- affinity_set(CPU->cpu_id);
-
- rv = drmach_bc_bzero(drmach_iocage_vaddr, nbytes);
- if (rv != 0) {
- DRMACH_PR(
- "iocage scrub failed, drmach_bc_bzero returned %d\n", rv);
- rv = drmach_bc_bzero(drmach_iocage_vaddr, drmach_iocage_size);
- if (rv != 0)
- cmn_err(CE_PANIC,
- "iocage scrub failed, drmach_bc_bzero rv=%d\n",
- rv);
- }
-
- cpu_flush_ecache();
-
- affinity_clear();
-}
-
-#define ALIGN(x, a) ((a) == 0 ? (uintptr_t)(x) : \
- (((uintptr_t)(x) + (uintptr_t)(a) - 1l) & ~((uintptr_t)(a) - 1l)))
-
-static sbd_error_t *
-drmach_iocage_mem_get(dr_testboard_req_t *tbrq)
-{
- pfn_t basepfn;
- pgcnt_t npages;
- extern int memscrub_delete_span(pfn_t, pgcnt_t);
- uint64_t drmach_iocage_paddr_mbytes;
-
- ASSERT(drmach_iocage_paddr != -1);
-
- basepfn = (pfn_t)(drmach_iocage_paddr >> PAGESHIFT);
- npages = (pgcnt_t)(drmach_iocage_size >> PAGESHIFT);
-
- (void) memscrub_delete_span(basepfn, npages);
-
- mutex_enter(&cpu_lock);
- drmach_iocage_mem_scrub(drmach_iocage_size);
- mutex_exit(&cpu_lock);
-
- /*
- * HPOST wants the address of the cage to be 64 megabyte-aligned
- * and in megabyte units.
- * The size of the cage is also in megabyte units.
- */
- ASSERT(drmach_iocage_paddr == ALIGN(drmach_iocage_paddr, 0x4000000));
-
- drmach_iocage_paddr_mbytes = drmach_iocage_paddr / 0x100000;
-
- tbrq->memaddrhi = (uint32_t)(drmach_iocage_paddr_mbytes >> 32);
- tbrq->memaddrlo = (uint32_t)drmach_iocage_paddr_mbytes;
- tbrq->memlen = drmach_iocage_size / 0x100000;
-
- DRMACH_PR("drmach_iocage_mem_get: hi: 0x%x", tbrq->memaddrhi);
- DRMACH_PR("drmach_iocage_mem_get: lo: 0x%x", tbrq->memaddrlo);
- DRMACH_PR("drmach_iocage_mem_get: size: 0x%x", tbrq->memlen);
-
- return (NULL);
-}
-
-static sbd_error_t *
-drmach_iocage_mem_return(dr_testboard_reply_t *tbr)
-{
- _NOTE(ARGUNUSED(tbr))
-
- pfn_t basepfn;
- pgcnt_t npages;
- extern int memscrub_add_span(pfn_t, pgcnt_t);
-
- ASSERT(drmach_iocage_paddr != -1);
-
- basepfn = (pfn_t)(drmach_iocage_paddr >> PAGESHIFT);
- npages = (pgcnt_t)(drmach_iocage_size >> PAGESHIFT);
-
- (void) memscrub_add_span(basepfn, npages);
-
- mutex_enter(&cpu_lock);
- mutex_enter(&drmach_iocage_lock);
- drmach_iocage_mem_scrub(drmach_iocage_size);
- drmach_iocage_is_busy = 0;
- cv_signal(&drmach_iocage_cv);
- mutex_exit(&drmach_iocage_lock);
- mutex_exit(&cpu_lock);
-
- return (NULL);
-}
-
-static int
-drmach_cpu_intr_disable(cpu_t *cp)
-{
- if (cpu_intr_disable(cp) != 0)
- return (-1);
- return (0);
-}
-
-static int
-drmach_iocage_cpu_acquire(drmach_device_t *dp, cpu_flag_t *oflags)
-{
- struct cpu *cp;
- processorid_t cpuid;
- static char *fn = "drmach_iocage_cpu_acquire";
- sbd_error_t *err;
- int impl;
-
- ASSERT(DRMACH_IS_CPU_ID(dp));
- ASSERT(MUTEX_HELD(&cpu_lock));
-
- cpuid = ((drmach_cpu_t *)dp)->cpuid;
-
- DRMACH_PR("%s: attempting to acquire CPU id %d", fn, cpuid);
-
- if (dp->busy)
- return (-1);
-
- if ((cp = cpu_get(cpuid)) == NULL) {
- DRMACH_PR("%s: cpu_get(%d) returned NULL", fn, cpuid);
- return (-1);
- }
-
- if (!CPU_ACTIVE(cp)) {
- DRMACH_PR("%s: skipping offlined CPU id %d", fn, cpuid);
- return (-1);
- }
-
- /*
- * There is a known HW bug where a Jaguar CPU in Safari port 0 (SBX/P0)
- * can fail to receive an XIR. To workaround this issue until a hardware
- * fix is implemented, we will exclude the selection of these CPUs.
- *
- * Once a fix is implemented in hardware, this code should be updated
- * to allow Jaguar CPUs that have the fix to be used. However, support
- * must be retained to skip revisions that do not have this fix.
- */
-
- err = drmach_cpu_get_impl(dp, &impl);
- if (err) {
- DRMACH_PR("%s: error getting impl. of CPU id %d", fn, cpuid);
- sbd_err_clear(&err);
- return (-1);
- }
-
- if (IS_JAGUAR(impl) && (STARCAT_CPUID_TO_LPORT(cpuid) == 0) &&
- drmach_iocage_exclude_jaguar_port_zero) {
- DRMACH_PR("%s: excluding CPU id %d: port 0 on jaguar",
- fn, cpuid);
- return (-1);
- }
-
- ASSERT(oflags);
- *oflags = cp->cpu_flags;
-
- if (cpu_offline(cp, 0)) {
- DRMACH_PR("%s: cpu_offline failed for CPU id %d", fn, cpuid);
- return (-1);
- }
-
- if (cpu_poweroff(cp)) {
- DRMACH_PR("%s: cpu_poweroff failed for CPU id %d", fn, cpuid);
- if (cpu_online(cp, 0)) {
- cmn_err(CE_WARN, "failed to online CPU id %d "
- "during I/O cage test selection", cpuid);
- }
- if (CPU_ACTIVE(cp) && cpu_flagged_nointr(*oflags) &&
- drmach_cpu_intr_disable(cp) != 0) {
- cmn_err(CE_WARN, "failed to restore CPU id %d "
- "no-intr during I/O cage test selection", cpuid);
- }
- return (-1);
- }
-
- if (cpu_unconfigure(cpuid)) {
- DRMACH_PR("%s: cpu_unconfigure failed for CPU id %d", fn,
- cpuid);
- (void) cpu_configure(cpuid);
- if ((cp = cpu_get(cpuid)) == NULL) {
- cmn_err(CE_WARN, "failed to reconfigure CPU id %d "
- "during I/O cage test selection", cpuid);
- dp->busy = 1;
- return (-1);
- }
- if (cpu_poweron(cp) || cpu_online(cp, 0)) {
- cmn_err(CE_WARN, "failed to %s CPU id %d "
- "during I/O cage test selection",
- cpu_is_poweredoff(cp) ?
- "poweron" : "online", cpuid);
- }
- if (CPU_ACTIVE(cp) && cpu_flagged_nointr(*oflags) &&
- drmach_cpu_intr_disable(cp) != 0) {
- cmn_err(CE_WARN, "failed to restore CPU id %d "
- "no-intr during I/O cage test selection", cpuid);
- }
- return (-1);
- }
-
- dp->busy = 1;
-
- DRMACH_PR("%s: acquired CPU id %d", fn, cpuid);
-
- return (0);
-}
-
-/*
- * Attempt to acquire all the CPU devices passed in. It is
- * assumed that all the devices in the list are the cores of
- * a single CMP device. Non CMP devices can be handled as a
- * single core CMP by passing in a one element list.
- *
- * Success is only returned if *all* the devices in the list
- * can be acquired. In the failure case, none of the devices
- * in the list will be held as acquired.
- */
-static int
-drmach_iocage_cmp_acquire(drmach_device_t **dpp, cpu_flag_t *oflags)
-{
- int curr;
- int i;
- int rv = 0;
-
- ASSERT((dpp != NULL) && (*dpp != NULL));
-
- /*
- * Walk the list of CPU devices (cores of a CMP)
- * and attempt to acquire them. Bail out if an
- * error is encountered.
- */
- for (curr = 0; curr < MAX_CORES_PER_CMP; curr++) {
-
- /* check for the end of the list */
- if (dpp[curr] == NULL) {
- break;
- }
-
- ASSERT(DRMACH_IS_CPU_ID(dpp[curr]));
- ASSERT(dpp[curr]->portid == (*dpp)->portid);
-
- rv = drmach_iocage_cpu_acquire(dpp[curr], &oflags[curr]);
- if (rv != 0) {
- break;
- }
- }
-
- /*
- * Check for an error.
- */
- if (rv != 0) {
- /*
- * Make a best effort attempt to return any cores
- * that were already acquired before the error was
- * encountered.
- */
- for (i = 0; i < curr; i++) {
- (void) drmach_iocage_cpu_return(dpp[i], oflags[i]);
- }
- }
-
- return (rv);
-}
-
-static int
-drmach_iocage_cpu_return(drmach_device_t *dp, cpu_flag_t oflags)
-{
- processorid_t cpuid;
- struct cpu *cp;
- int rv = 0;
- static char *fn = "drmach_iocage_cpu_return";
-
- ASSERT(DRMACH_IS_CPU_ID(dp));
- ASSERT(MUTEX_HELD(&cpu_lock));
-
- cpuid = ((drmach_cpu_t *)dp)->cpuid;
-
- DRMACH_PR("%s: attempting to return CPU id: %d", fn, cpuid);
-
- if (cpu_configure(cpuid)) {
- cmn_err(CE_WARN, "failed to reconfigure CPU id %d "
- "after I/O cage test", cpuid);
- /*
- * The component was never set to unconfigured during the IO
- * cage test, so we need to leave marked as busy to prevent
- * further DR operations involving this component.
- */
- return (-1);
- }
-
- if ((cp = cpu_get(cpuid)) == NULL) {
- cmn_err(CE_WARN, "cpu_get failed on CPU id %d after "
- "I/O cage test", cpuid);
- dp->busy = 0;
- return (-1);
- }
-
- if (cpu_poweron(cp) || cpu_online(cp, 0)) {
- cmn_err(CE_WARN, "failed to %s CPU id %d after I/O "
- "cage test", cpu_is_poweredoff(cp) ?
- "poweron" : "online", cpuid);
- rv = -1;
- }
-
- /*
- * drmach_iocage_cpu_acquire will accept cpus in state P_ONLINE or
- * P_NOINTR. Need to return to previous user-visible state.
- */
- if (CPU_ACTIVE(cp) && cpu_flagged_nointr(oflags) &&
- drmach_cpu_intr_disable(cp) != 0) {
- cmn_err(CE_WARN, "failed to restore CPU id %d "
- "no-intr after I/O cage test", cpuid);
- rv = -1;
- }
-
- dp->busy = 0;
-
- DRMACH_PR("%s: returned CPU id: %d", fn, cpuid);
-
- return (rv);
-}
-
-static sbd_error_t *
-drmach_iocage_cpu_get(dr_testboard_req_t *tbrq, drmach_device_t **dpp,
- cpu_flag_t *oflags)
-{
- drmach_board_t *bp;
- int b_rv;
- int b_idx;
- drmachid_t b_id;
- int found;
-
- mutex_enter(&cpu_lock);
-
- ASSERT(drmach_boards != NULL);
-
- found = 0;
-
- /*
- * Walk the board list.
- */
- b_rv = drmach_array_first(drmach_boards, &b_idx, &b_id);
-
- while (b_rv == 0) {
-
- int d_rv;
- int d_idx;
- drmachid_t d_id;
-
- bp = b_id;
-
- if (bp->connected == 0 || bp->devices == NULL) {
- b_rv = drmach_array_next(drmach_boards, &b_idx, &b_id);
- continue;
- }
-
- /* An AXQ restriction disqualifies MCPU's as candidates. */
- if (DRMACH_BNUM2SLOT(bp->bnum) == 1) {
- b_rv = drmach_array_next(drmach_boards, &b_idx, &b_id);
- continue;
- }
-
- /*
- * Walk the device list of this board.
- */
- d_rv = drmach_array_first(bp->devices, &d_idx, &d_id);
-
- while (d_rv == 0) {
-
- drmach_device_t *ndp;
-
- /* only interested in CPU devices */
- if (!DRMACH_IS_CPU_ID(d_id)) {
- d_rv = drmach_array_next(bp->devices, &d_idx,
- &d_id);
- continue;
- }
-
- /*
- * The following code assumes two properties
- * of a CMP device:
- *
- * 1. All cores of a CMP are grouped together
- * in the device list.
- *
- * 2. There will only be a maximum of two cores
- * present in the CMP.
- *
- * If either of these two properties change,
- * this code will have to be revisited.
- */
-
- dpp[0] = d_id;
- dpp[1] = NULL;
-
- /*
- * Get the next device. It may or may not be used.
- */
- d_rv = drmach_array_next(bp->devices, &d_idx, &d_id);
- ndp = d_id;
-
- if ((d_rv == 0) && DRMACH_IS_CPU_ID(d_id)) {
- /*
- * The second device is only interesting for
- * this pass if it has the same portid as the
- * first device. This implies that both are
- * cores of the same CMP.
- */
- if (dpp[0]->portid == ndp->portid) {
- dpp[1] = d_id;
- }
- }
-
- /*
- * Attempt to acquire all cores of the CMP.
- */
- if (drmach_iocage_cmp_acquire(dpp, oflags) == 0) {
- found = 1;
- break;
- }
-
- /*
- * Check if the search for the second core was
- * successful. If not, the next iteration should
- * use that device.
- */
- if (dpp[1] == NULL) {
- continue;
- }
-
- d_rv = drmach_array_next(bp->devices, &d_idx, &d_id);
- }
-
- if (found)
- break;
-
- b_rv = drmach_array_next(drmach_boards, &b_idx, &b_id);
- }
-
- mutex_exit(&cpu_lock);
-
- if (!found) {
- return (drerr_new(1, ESTC_IOCAGE_NO_CPU_AVAIL, NULL));
- }
-
- tbrq->cpu_portid = (*dpp)->portid;
-
- return (NULL);
-}
-
-/*
- * Setup an iocage by acquiring a cpu and memory.
- */
-static sbd_error_t *
-drmach_iocage_setup(dr_testboard_req_t *tbrq, drmach_device_t **dpp,
- cpu_flag_t *oflags)
-{
- sbd_error_t *err;
-
- err = drmach_iocage_cpu_get(tbrq, dpp, oflags);
- if (!err) {
- mutex_enter(&drmach_iocage_lock);
- while (drmach_iocage_is_busy)
- cv_wait(&drmach_iocage_cv, &drmach_iocage_lock);
- drmach_iocage_is_busy = 1;
- mutex_exit(&drmach_iocage_lock);
- err = drmach_iocage_mem_get(tbrq);
- if (err) {
- mutex_enter(&drmach_iocage_lock);
- drmach_iocage_is_busy = 0;
- cv_signal(&drmach_iocage_cv);
- mutex_exit(&drmach_iocage_lock);
- }
- }
- return (err);
-}
-
-#define DRMACH_SCHIZO_PCI_LEAF_MAX 2
-#define DRMACH_SCHIZO_PCI_SLOT_MAX 8
-#define DRMACH_S1P_SAMPLE_MAX 2
-
-typedef enum {
- DRMACH_POST_SUSPEND = 0,
- DRMACH_PRE_RESUME
-} drmach_sr_iter_t;
-
-typedef struct {
- dev_info_t *dip;
- uint32_t portid;
- uint32_t pcr_sel_save;
- uint32_t pic_l2_io_q[DRMACH_S1P_SAMPLE_MAX];
- uint64_t reg_basepa;
-} drmach_s1p_axq_t;
-
-typedef struct {
- dev_info_t *dip;
- uint32_t portid;
- uint64_t csr_basepa;
- struct {
- uint64_t slot_intr_state_diag;
- uint64_t obio_intr_state_diag;
- uint_t nmap_regs;
- uint64_t *intr_map_regs;
- } regs[DRMACH_S1P_SAMPLE_MAX];
-} drmach_s1p_pci_t;
-
-typedef struct {
- uint64_t csr_basepa;
- struct {
- uint64_t csr;
- uint64_t errctrl;
- uint64_t errlog;
- } regs[DRMACH_S1P_SAMPLE_MAX];
- drmach_s1p_pci_t pci[DRMACH_SCHIZO_PCI_LEAF_MAX];
-} drmach_s1p_schizo_t;
-
-typedef struct {
- drmach_s1p_axq_t axq;
- drmach_s1p_schizo_t schizo[STARCAT_SLOT1_IO_MAX];
-} drmach_slot1_pause_t;
-
-/*
- * Table of saved state for paused slot1 devices.
- */
-static drmach_slot1_pause_t *drmach_slot1_paused[STARCAT_BDSET_MAX];
-static int drmach_slot1_pause_init = 1;
-
-#ifdef DEBUG
-int drmach_slot1_pause_debug = 1;
-#else
-int drmach_slot1_pause_debug = 0;
-#endif /* DEBUG */
-
-static int
-drmach_is_slot1_pause_axq(dev_info_t *dip, char *name, int *id, uint64_t *reg)
-{
- int portid, exp, slot, i;
- drmach_reg_t regs[2];
- int reglen = sizeof (regs);
-
- if ((portid = ddi_getprop(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "portid", -1)) == -1) {
- return (0);
- }
-
- exp = (portid >> 5) & 0x1f;
- slot = portid & 0x1;
-
- if (slot == 0 || strncmp(name, DRMACH_AXQ_NAMEPROP,
- strlen(DRMACH_AXQ_NAMEPROP))) {
- return (0);
- }
-
- mutex_enter(&cpu_lock);
- for (i = 0; i < STARCAT_SLOT1_CPU_MAX; i++) {
- if (cpu[MAKE_CPUID(exp, slot, i)]) {
- /* maxcat cpu present */
- mutex_exit(&cpu_lock);
- return (0);
- }
- }
- mutex_exit(&cpu_lock);
-
- if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "reg", (caddr_t)regs, &reglen) != DDI_PROP_SUCCESS) {
- DRMACH_PR("drmach_is_slot1_pause_axq: no reg prop for "
- "axq dip=%p\n", (void *)dip);
- return (0);
- }
-
- ASSERT(id && reg);
- *reg = (uint64_t)regs[0].reg_addr_hi << 32;
- *reg |= (uint64_t)regs[0].reg_addr_lo;
- *id = portid;
-
- return (1);
-}
-
-/*
- * Allocate an entry in the slot1_paused state table.
- */
-static void
-drmach_slot1_pause_add_axq(dev_info_t *axq_dip, char *axq_name, int axq_portid,
- uint64_t reg, drmach_slot1_pause_t **slot1_paused)
-{
- int axq_exp;
- drmach_slot1_pause_t *slot1;
-
- axq_exp = (axq_portid >> 5) & 0x1f;
-
- ASSERT(axq_portid & 0x1);
- ASSERT(slot1_paused[axq_exp] == NULL);
- ASSERT(strncmp(axq_name, DRMACH_AXQ_NAMEPROP,
- strlen(DRMACH_AXQ_NAMEPROP)) == 0);
-
- slot1 = kmem_zalloc(sizeof (*slot1), KM_SLEEP);
-
- /*
- * XXX This dip should really be held (via ndi_hold_devi())
- * before saving it in the axq pause structure. However that
- * would prevent DR as the pause data structures persist until
- * the next suspend. drmach code should be modified to free the
- * the slot 1 pause data structures for a boardset when its
- * slot 1 board is DRed out. The dip can then be released via
- * ndi_rele_devi() when the pause data structure is freed
- * allowing DR to proceed. Until this change is made, drmach
- * code should be careful about dereferencing the saved dip
- * as it may no longer exist.
- */
- slot1->axq.dip = axq_dip;
- slot1->axq.portid = axq_portid;
- slot1->axq.reg_basepa = reg;
- slot1_paused[axq_exp] = slot1;
-}
-
-static void
-drmach_s1p_pci_free(drmach_s1p_pci_t *pci)
-{
- int i;
-
- for (i = 0; i < DRMACH_S1P_SAMPLE_MAX; i++) {
- if (pci->regs[i].intr_map_regs != NULL) {
- ASSERT(pci->regs[i].nmap_regs > 0);
- kmem_free(pci->regs[i].intr_map_regs,
- pci->regs[i].nmap_regs * sizeof (uint64_t));
- }
- }
-}
-
-static void
-drmach_slot1_pause_free(drmach_slot1_pause_t **slot1_paused)
-{
- int i, j, k;
- drmach_slot1_pause_t *slot1;
-
- for (i = 0; i < STARCAT_BDSET_MAX; i++) {
- if ((slot1 = slot1_paused[i]) == NULL)
- continue;
-
- for (j = 0; j < STARCAT_SLOT1_IO_MAX; j++)
- for (k = 0; k < DRMACH_SCHIZO_PCI_LEAF_MAX; k++)
- drmach_s1p_pci_free(&slot1->schizo[j].pci[k]);
-
- kmem_free(slot1, sizeof (*slot1));
- slot1_paused[i] = NULL;
- }
-}
-
-/*
- * Tree walk callback routine. If dip represents a Schizo PCI leaf,
- * fill in the appropriate info in the slot1_paused state table.
- */
-static int
-drmach_find_slot1_io(dev_info_t *dip, void *arg)
-{
- int portid, exp, ioc_unum, leaf_unum;
- char buf[OBP_MAXDRVNAME];
- int buflen = sizeof (buf);
- drmach_reg_t regs[3];
- int reglen = sizeof (regs);
- uint32_t leaf_offset;
- uint64_t schizo_csr_pa, pci_csr_pa;
- drmach_s1p_pci_t *pci;
- drmach_slot1_pause_t **slot1_paused = (drmach_slot1_pause_t **)arg;
-
- if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "name", (caddr_t)buf, &buflen) != DDI_PROP_SUCCESS ||
- strncmp(buf, DRMACH_PCI_NAMEPROP, strlen(DRMACH_PCI_NAMEPROP))) {
- return (DDI_WALK_CONTINUE);
- }
-
- if ((portid = ddi_getprop(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "portid", -1)) == -1) {
- return (DDI_WALK_CONTINUE);
- }
-
- if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "reg", (caddr_t)regs, &reglen) != DDI_PROP_SUCCESS) {
- DRMACH_PR("drmach_find_slot1_io: no reg prop for pci "
- "dip=%p\n", (void *)dip);
- return (DDI_WALK_CONTINUE);
- }
-
- exp = portid >> 5;
- ioc_unum = portid & 0x1;
- leaf_offset = regs[0].reg_addr_lo & 0x7fffff;
- pci_csr_pa = (uint64_t)regs[0].reg_addr_hi << 32;
- pci_csr_pa |= (uint64_t)regs[0].reg_addr_lo;
- schizo_csr_pa = (uint64_t)regs[1].reg_addr_hi << 32;
- schizo_csr_pa |= (uint64_t)regs[1].reg_addr_lo;
-
- ASSERT(exp >= 0 && exp < STARCAT_BDSET_MAX);
- ASSERT(slot1_paused[exp] != NULL);
- ASSERT(leaf_offset == 0x600000 || leaf_offset == 0x700000);
- ASSERT(slot1_paused[exp]->schizo[ioc_unum].csr_basepa == 0x0UL ||
- slot1_paused[exp]->schizo[ioc_unum].csr_basepa == schizo_csr_pa);
-
- leaf_unum = (leaf_offset == 0x600000) ? 0 : 1;
- slot1_paused[exp]->schizo[ioc_unum].csr_basepa = schizo_csr_pa;
- pci = &slot1_paused[exp]->schizo[ioc_unum].pci[leaf_unum];
-
- /*
- * XXX This dip should really be held (via ndi_hold_devi())
- * before saving it in the pci pause structure. However that
- * would prevent DR as the pause data structures persist until
- * the next suspend. drmach code should be modified to free the
- * the slot 1 pause data structures for a boardset when its
- * slot 1 board is DRed out. The dip can then be released via
- * ndi_rele_devi() when the pause data structure is freed
- * allowing DR to proceed. Until this change is made, drmach
- * code should be careful about dereferencing the saved dip as
- * it may no longer exist.
- */
- pci->dip = dip;
- pci->portid = portid;
- pci->csr_basepa = pci_csr_pa;
-
- DRMACH_PR("drmach_find_slot1_io: name=%s, portid=0x%x, dip=%p\n",
- buf, portid, (void *)dip);
-
- return (DDI_WALK_PRUNECHILD);
-}
-
-static void
-drmach_slot1_pause_add_io(drmach_slot1_pause_t **slot1_paused)
-{
- /*
- * Root node doesn't have to be held
- */
- ddi_walk_devs(ddi_root_node(), drmach_find_slot1_io,
- (void *)slot1_paused);
-}
-
-/*
- * Save the interrupt mapping registers for each non-idle interrupt
- * represented by the bit pairs in the saved interrupt state
- * diagnostic registers for this PCI leaf.
- */
-static void
-drmach_s1p_intr_map_reg_save(drmach_s1p_pci_t *pci, drmach_sr_iter_t iter)
-{
- int i, cnt, ino;
- uint64_t reg;
- char *dname;
- uchar_t Xmits;
-
- dname = ddi_binding_name(pci->dip);
- Xmits = (strcmp(dname, XMITS_BINDING_NAME) == 0) ? 1 : 0;
-
- /*
- * 1st pass allocates, 2nd pass populates.
- */
- for (i = 0; i < 2; i++) {
- cnt = ino = 0;
-
- /*
- * PCI slot interrupts
- */
- reg = pci->regs[iter].slot_intr_state_diag;
- while (reg) {
- /*
- * Xmits Interrupt Number Offset(ino) Assignments
- * 00-17 PCI Slot Interrupts
- * 18-1f Not Used
- */
- if ((Xmits) && (ino > 0x17))
- break;
- if ((reg & COMMON_CLEAR_INTR_REG_MASK) !=
- COMMON_CLEAR_INTR_REG_IDLE) {
- if (i) {
- pci->regs[iter].intr_map_regs[cnt] =
- lddphysio(pci->csr_basepa +
- SCHIZO_IB_INTR_MAP_REG_OFFSET +
- ino * sizeof (reg));
- }
- ++cnt;
- }
- ++ino;
- reg >>= 2;
- }
-
- /*
- * Xmits Interrupt Number Offset(ino) Assignments
- * 20-2f Not Used
- * 30-37 Internal interrupts
- * 38-3e Not Used
- */
- ino = (Xmits) ? 0x30 : 0x20;
-
- /*
- * OBIO and internal schizo interrupts
- * Each PCI leaf has a set of mapping registers for all
- * possible interrupt sources except the NewLink interrupts.
- */
- reg = pci->regs[iter].obio_intr_state_diag;
- while (reg && ino <= 0x38) {
- if ((reg & COMMON_CLEAR_INTR_REG_MASK) !=
- COMMON_CLEAR_INTR_REG_IDLE) {
- if (i) {
- pci->regs[iter].intr_map_regs[cnt] =
- lddphysio(pci->csr_basepa +
- SCHIZO_IB_INTR_MAP_REG_OFFSET +
- ino * sizeof (reg));
- }
- ++cnt;
- }
- ++ino;
- reg >>= 2;
- }
-
- if (!i) {
- pci->regs[iter].nmap_regs = cnt;
- pci->regs[iter].intr_map_regs =
- kmem_zalloc(cnt * sizeof (reg), KM_SLEEP);
- }
- }
-}
-
-static void
-drmach_s1p_axq_update(drmach_s1p_axq_t *axq, drmach_sr_iter_t iter)
-{
- uint32_t reg;
-
- if (axq->reg_basepa == 0x0UL)
- return;
-
- if (iter == DRMACH_POST_SUSPEND) {
- axq->pcr_sel_save = ldphysio(axq->reg_basepa +
- AXQ_SLOT1_PERFCNT_SEL);
- /*
- * Select l2_io_queue counter by writing L2_IO_Q mux
- * input to bits 0-6 of perf cntr select reg.
- */
- reg = axq->pcr_sel_save;
- reg &= ~AXQ_PIC_CLEAR_MASK;
- reg |= L2_IO_Q;
-
- stphysio(axq->reg_basepa + AXQ_SLOT1_PERFCNT_SEL, reg);
- }
-
- axq->pic_l2_io_q[iter] = ldphysio(axq->reg_basepa + AXQ_SLOT1_PERFCNT0);
-
- if (iter == DRMACH_PRE_RESUME) {
- stphysio(axq->reg_basepa + AXQ_SLOT1_PERFCNT_SEL,
- axq->pcr_sel_save);
- }
-
- DRMACH_PR("drmach_s1p_axq_update: axq #%d pic_l2_io_q[%d]=%d\n",
- ddi_get_instance(axq->dip), iter, axq->pic_l2_io_q[iter]);
-}
-
-static void
-drmach_s1p_schizo_update(drmach_s1p_schizo_t *schizo, drmach_sr_iter_t iter)
-{
- int i;
- drmach_s1p_pci_t *pci;
-
- if (schizo->csr_basepa == 0x0UL)
- return;
-
- schizo->regs[iter].csr =
- lddphysio(schizo->csr_basepa + SCHIZO_CB_CSR_OFFSET);
- schizo->regs[iter].errctrl =
- lddphysio(schizo->csr_basepa + SCHIZO_CB_ERRCTRL_OFFSET);
- schizo->regs[iter].errlog =
- lddphysio(schizo->csr_basepa + SCHIZO_CB_ERRLOG_OFFSET);
-
- for (i = 0; i < DRMACH_SCHIZO_PCI_LEAF_MAX; i++) {
- pci = &schizo->pci[i];
- if (pci->dip != NULL && pci->csr_basepa != 0x0UL) {
- pci->regs[iter].slot_intr_state_diag =
- lddphysio(pci->csr_basepa +
- COMMON_IB_SLOT_INTR_STATE_DIAG_REG);
-
- pci->regs[iter].obio_intr_state_diag =
- lddphysio(pci->csr_basepa +
- COMMON_IB_OBIO_INTR_STATE_DIAG_REG);
-
- drmach_s1p_intr_map_reg_save(pci, iter);
- }
- }
-}
-
-/*
- * Called post-suspend and pre-resume to snapshot the suspend state
- * of slot1 AXQs and Schizos.
- */
-static void
-drmach_slot1_pause_update(drmach_slot1_pause_t **slot1_paused,
- drmach_sr_iter_t iter)
-{
- int i, j;
- drmach_slot1_pause_t *slot1;
-
- for (i = 0; i < STARCAT_BDSET_MAX; i++) {
- if ((slot1 = slot1_paused[i]) == NULL)
- continue;
-
- drmach_s1p_axq_update(&slot1->axq, iter);
- for (j = 0; j < STARCAT_SLOT1_IO_MAX; j++)
- drmach_s1p_schizo_update(&slot1->schizo[j], iter);
- }
-}
-
-/*
- * Starcat hPCI Schizo devices.
- *
- * The name field is overloaded. NULL means the slot (interrupt concentrator
- * bus) is not used. intr_mask is a bit mask representing the 4 possible
- * interrupts per slot, on if valid (rio does not use interrupt lines 0, 1).
- */
-static struct {
- char *name;
- uint8_t intr_mask;
-} drmach_schz_slot_intr[][DRMACH_SCHIZO_PCI_LEAF_MAX] = {
- /* Schizo 0 */ /* Schizo 1 */
- {{"C3V0", 0xf}, {"C3V1", 0xf}}, /* slot 0 */
- {{"C5V0", 0xf}, {"C5V1", 0xf}}, /* slot 1 */
- {{"rio", 0xc}, {NULL, 0x0}}, /* slot 2 */
- {{NULL, 0x0}, {NULL, 0x0}}, /* slot 3 */
- {{"sbbc", 0xf}, {NULL, 0x0}}, /* slot 4 */
- {{NULL, 0x0}, {NULL, 0x0}}, /* slot 5 */
- {{NULL, 0x0}, {NULL, 0x0}}, /* slot 6 */
- {{NULL, 0x0}, {NULL, 0x0}} /* slot 7 */
-};
-
-/*
- * See Schizo Specification, Revision 51 (May 23, 2001), Section 22.4.4
- * "Interrupt Registers", Table 22-69, page 306.
- */
-static char *
-drmach_schz_internal_ino2str(int ino)
-{
- int intr;
-
- ASSERT(ino >= 0x30 && ino <= 0x37);
-
- intr = ino & 0x7;
- switch (intr) {
- case (0x0): return ("Uncorrectable ECC error");
- case (0x1): return ("Correctable ECC error");
- case (0x2): return ("PCI Bus A Error");
- case (0x3): return ("PCI Bus B Error");
- case (0x4): return ("Safari Bus Error");
- default: return ("Reserved");
- }
-}
-
-#define DRMACH_INTR_MASK_SHIFT(ino) ((ino) << 1)
-
-static void
-drmach_s1p_decode_slot_intr(int exp, int unum, drmach_s1p_pci_t *pci,
- int ino, drmach_sr_iter_t iter)
-{
- uint8_t intr_mask;
- char *slot_devname;
- char namebuf[OBP_MAXDRVNAME];
- int slot, intr_line, slot_valid, intr_valid;
-
- ASSERT(ino >= 0 && ino <= 0x1f);
- ASSERT((pci->regs[iter].slot_intr_state_diag &
- (COMMON_CLEAR_INTR_REG_MASK << DRMACH_INTR_MASK_SHIFT(ino))) !=
- COMMON_CLEAR_INTR_REG_IDLE);
-
- slot = (ino >> 2) & 0x7;
- intr_line = ino & 0x3;
-
- slot_devname = drmach_schz_slot_intr[slot][unum].name;
- slot_valid = (slot_devname == NULL) ? 0 : 1;
- if (!slot_valid) {
- (void) snprintf(namebuf, sizeof (namebuf), "slot %d (INVALID)",
- slot);
- slot_devname = namebuf;
- }
-
- intr_mask = drmach_schz_slot_intr[slot][unum].intr_mask;
- intr_valid = (1 << intr_line) & intr_mask;
-
- prom_printf("IO%d/P%d PCI slot interrupt: ino=0x%x, source device=%s, "
- "interrupt line=%d%s\n", exp, unum, ino, slot_devname, intr_line,
- (slot_valid && !intr_valid) ? " (INVALID)" : "");
-}
-
-/*
- * Log interrupt source device info for all valid, pending interrupts
- * on each Schizo PCI leaf. Called if Schizo has logged a Safari bus
- * error in the error ctrl reg.
- */
-static void
-drmach_s1p_schizo_log_intr(drmach_s1p_schizo_t *schizo, int exp,
- int unum, drmach_sr_iter_t iter)
-{
- uint64_t reg;
- int i, n, ino;
- drmach_s1p_pci_t *pci;
-
- ASSERT(exp >= 0 && exp < STARCAT_BDSET_MAX);
- ASSERT(unum < STARCAT_SLOT1_IO_MAX);
-
- /*
- * Check the saved interrupt mapping registers. If interrupt is valid,
- * map the ino to the Schizo source device and check that the pci
- * slot and interrupt line are valid.
- */
- for (i = 0; i < DRMACH_SCHIZO_PCI_LEAF_MAX; i++) {
- pci = &schizo->pci[i];
- for (n = 0; n < pci->regs[iter].nmap_regs; n++) {
- reg = pci->regs[iter].intr_map_regs[n];
- if (reg & COMMON_INTR_MAP_REG_VALID) {
- ino = reg & COMMON_INTR_MAP_REG_INO;
-
- if (ino <= 0x1f) {
- /*
- * PCI slot interrupt
- */
- drmach_s1p_decode_slot_intr(exp, unum,
- pci, ino, iter);
- } else if (ino <= 0x2f) {
- /*
- * OBIO interrupt
- */
- prom_printf("IO%d/P%d OBIO interrupt: "
- "ino=0x%x\n", exp, unum, ino);
- } else if (ino <= 0x37) {
- /*
- * Internal interrupt
- */
- prom_printf("IO%d/P%d Internal "
- "interrupt: ino=0x%x (%s)\n",
- exp, unum, ino,
- drmach_schz_internal_ino2str(ino));
- } else {
- /*
- * NewLink interrupt
- */
- prom_printf("IO%d/P%d NewLink "
- "interrupt: ino=0x%x\n", exp,
- unum, ino);
- }
-
- DRMACH_PR("drmach_s1p_schizo_log_intr: "
- "exp=%d, schizo=%d, pci_leaf=%c, "
- "ino=0x%x, intr_map_reg=0x%lx\n",
- exp, unum, (i == 0) ? 'A' : 'B', ino, reg);
- }
- }
- }
-}
-
-/*
- * See Schizo Specification, Revision 51 (May 23, 2001), Section 22.2.4
- * "Safari Error Control/Log Registers", Table 22-11, page 248.
- */
-#define DRMACH_SCHIZO_SAFARI_UNMAPPED_ERR (0x1ull << 4)
-
-/*
- * Check for possible error indicators prior to resuming the
- * AXQ driver, which will de-assert slot1 AXQ_DOMCTRL_PAUSE.
- */
-static void
-drmach_slot1_pause_verify(drmach_slot1_pause_t **slot1_paused,
- drmach_sr_iter_t iter)
-{
- int i, j;
- int errflag = 0;
- drmach_slot1_pause_t *slot1;
-
- /*
- * Check for logged schizo bus error and pending interrupts.
- */
- for (i = 0; i < STARCAT_BDSET_MAX; i++) {
- if ((slot1 = slot1_paused[i]) == NULL)
- continue;
-
- for (j = 0; j < STARCAT_SLOT1_IO_MAX; j++) {
- if (slot1->schizo[j].csr_basepa == 0x0UL)
- continue;
-
- if (slot1->schizo[j].regs[iter].errlog &
- DRMACH_SCHIZO_SAFARI_UNMAPPED_ERR) {
- if (!errflag) {
- prom_printf("DR WARNING: interrupt "
- "attempt detected during "
- "copy-rename (%s):\n",
- (iter == DRMACH_POST_SUSPEND) ?
- "post suspend" : "pre resume");
- ++errflag;
- }
- drmach_s1p_schizo_log_intr(&slot1->schizo[j],
- i, j, iter);
- }
- }
- }
-
- /*
- * Check for changes in axq l2_io_q performance counters (2nd pass only)
- */
- if (iter == DRMACH_PRE_RESUME) {
- for (i = 0; i < STARCAT_BDSET_MAX; i++) {
- if ((slot1 = slot1_paused[i]) == NULL)
- continue;
-
- if (slot1->axq.pic_l2_io_q[DRMACH_POST_SUSPEND] !=
- slot1->axq.pic_l2_io_q[DRMACH_PRE_RESUME]) {
- prom_printf("DR WARNING: IO transactions "
- "detected on IO%d during copy-rename: "
- "AXQ l2_io_q performance counter "
- "start=%d, end=%d\n", i,
- slot1->axq.pic_l2_io_q[DRMACH_POST_SUSPEND],
- slot1->axq.pic_l2_io_q[DRMACH_PRE_RESUME]);
- }
- }
- }
-}
-
-struct drmach_sr_list {
- dev_info_t *dip;
- struct drmach_sr_list *next;
- struct drmach_sr_list *prev;
-};
-
-static struct drmach_sr_ordered {
- char *name;
- struct drmach_sr_list *ring;
-} drmach_sr_ordered[] = {
- { "iosram", NULL },
- { "address-extender-queue", NULL },
- { NULL, NULL }, /* terminator -- required */
-};
-
-static void
-drmach_sr_insert(struct drmach_sr_list **lp, dev_info_t *dip)
-{
- struct drmach_sr_list *np;
-
- DRMACH_PR("drmach_sr_insert: adding dip %p\n", (void *)dip);
-
- np = (struct drmach_sr_list *)kmem_alloc(
- sizeof (struct drmach_sr_list), KM_SLEEP);
-
- ndi_hold_devi(dip);
- np->dip = dip;
-
- if (*lp == NULL) {
- /* establish list */
- *lp = np->next = np->prev = np;
- } else {
- /* place new node behind head node on ring list */
- np->prev = (*lp)->prev;
- np->next = *lp;
- np->prev->next = np;
- np->next->prev = np;
- }
-}
-
-static void
-drmach_sr_delete(struct drmach_sr_list **lp, dev_info_t *dip)
-{
- DRMACH_PR("drmach_sr_delete: searching for dip %p\n", (void *)dip);
-
- if (*lp) {
- struct drmach_sr_list *xp;
-
- /* start search with mostly likely node */
- xp = (*lp)->prev;
- do {
- if (xp->dip == dip) {
- xp->prev->next = xp->next;
- xp->next->prev = xp->prev;
-
- if (xp == *lp)
- *lp = xp->next;
- if (xp == *lp)
- *lp = NULL;
- xp->dip = NULL;
- ndi_rele_devi(dip);
- kmem_free(xp, sizeof (*xp));
-
- DRMACH_PR("drmach_sr_delete:"
- " disposed sr node for dip %p",
- (void *)dip);
- return;
- }
-
- DRMACH_PR("drmach_sr_delete: still searching\n");
-
- xp = xp->prev;
- } while (xp != (*lp)->prev);
- }
-
- /* every dip should be found during resume */
- DRMACH_PR("ERROR: drmach_sr_delete: can't find dip %p", (void *)dip);
-}
-
-int
-drmach_verify_sr(dev_info_t *dip, int sflag)
-{
- int rv;
- int len;
- char name[OBP_MAXDRVNAME];
-
- if (drmach_slot1_pause_debug) {
- if (sflag && drmach_slot1_pause_init) {
- drmach_slot1_pause_free(drmach_slot1_paused);
- drmach_slot1_pause_init = 0;
- } else if (!sflag && !drmach_slot1_pause_init) {
- /* schedule init for next suspend */
- drmach_slot1_pause_init = 1;
- }
- }
-
- rv = ddi_getproplen(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "name", &len);
- if (rv == DDI_PROP_SUCCESS) {
- int portid;
- uint64_t reg;
- struct drmach_sr_ordered *op;
-
- rv = ddi_getlongprop_buf(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "name", (caddr_t)name, &len);
-
- if (rv != DDI_PROP_SUCCESS)
- return (0);
-
- if (drmach_slot1_pause_debug && sflag &&
- drmach_is_slot1_pause_axq(dip, name, &portid, &reg)) {
- drmach_slot1_pause_add_axq(dip, name, portid, reg,
- drmach_slot1_paused);
- }
-
- for (op = drmach_sr_ordered; op->name; op++) {
- if (strncmp(op->name, name, strlen(op->name)) == 0) {
- if (sflag)
- drmach_sr_insert(&op->ring, dip);
- else
- drmach_sr_delete(&op->ring, dip);
- return (1);
- }
- }
- }
-
- return (0);
-}
-
-static void
-drmach_sr_dip(dev_info_t *dip, int suspend)
-{
- int rv;
- major_t maj;
- char *name, *name_addr, *aka;
-
- if ((name = ddi_get_name(dip)) == NULL)
- name = "<null name>";
- else if ((maj = ddi_name_to_major(name)) != -1)
- aka = ddi_major_to_name(maj);
- else
- aka = "<unknown>";
-
- if ((name_addr = ddi_get_name_addr(dip)) == NULL)
- name_addr = "<null>";
-
- prom_printf("\t%s %s@%s (aka %s)\n",
- suspend ? "suspending" : "resuming",
- name, name_addr, aka);
-
- if (suspend) {
- rv = devi_detach(dip, DDI_SUSPEND);
- } else {
- rv = devi_attach(dip, DDI_RESUME);
- }
-
- if (rv != DDI_SUCCESS) {
- prom_printf("\tFAILED to %s %s@%s\n",
- suspend ? "suspend" : "resume",
- name, name_addr);
- }
-}
-
-void
-drmach_suspend_last()
-{
- struct drmach_sr_ordered *op;
-
- if (drmach_slot1_pause_debug)
- drmach_slot1_pause_add_io(drmach_slot1_paused);
-
- /*
- * The ordering array declares the strict sequence in which
- * the named drivers are to suspended. Each element in
- * the array may have a double-linked ring list of driver
- * instances (dip) in the order in which they were presented
- * to drmach_verify_sr. If present, walk the list in the
- * forward direction to suspend each instance.
- */
- for (op = drmach_sr_ordered; op->name; op++) {
- if (op->ring) {
- struct drmach_sr_list *rp;
-
- rp = op->ring;
- do {
- drmach_sr_dip(rp->dip, 1);
- rp = rp->next;
- } while (rp != op->ring);
- }
- }
-
- if (drmach_slot1_pause_debug) {
- drmach_slot1_pause_update(drmach_slot1_paused,
- DRMACH_POST_SUSPEND);
- drmach_slot1_pause_verify(drmach_slot1_paused,
- DRMACH_POST_SUSPEND);
- }
-}
-
-void
-drmach_resume_first()
-{
- struct drmach_sr_ordered *op = drmach_sr_ordered +
- (sizeof (drmach_sr_ordered) / sizeof (drmach_sr_ordered[0]));
-
- if (drmach_slot1_pause_debug) {
- drmach_slot1_pause_update(drmach_slot1_paused,
- DRMACH_PRE_RESUME);
- drmach_slot1_pause_verify(drmach_slot1_paused,
- DRMACH_PRE_RESUME);
- }
-
- op -= 1; /* point at terminating element */
-
- /*
- * walk ordering array and rings backwards to resume dips
- * in reverse order in which they were suspended
- */
- while (--op >= drmach_sr_ordered) {
- if (op->ring) {
- struct drmach_sr_list *rp;
-
- rp = op->ring->prev;
- do {
- drmach_sr_dip(rp->dip, 0);
- rp = rp->prev;
- } while (rp != op->ring->prev);
- }
- }
-}
-
-/*
- * Log a DR sysevent.
- * Return value: 0 success, non-zero failure.
- */
-int
-drmach_log_sysevent(int board, char *hint, int flag, int verbose)
-{
- sysevent_t *ev;
- sysevent_id_t eid;
- int rv, km_flag;
- sysevent_value_t evnt_val;
- sysevent_attr_list_t *evnt_attr_list = NULL;
- char attach_pnt[MAXNAMELEN];
-
- km_flag = (flag == SE_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
- attach_pnt[0] = '\0';
- if (drmach_board_name(board, attach_pnt, MAXNAMELEN)) {
- rv = -1;
- goto logexit;
- }
- if (verbose)
- DRMACH_PR("drmach_log_sysevent: %s %s, flag: %d, verbose: %d\n",
- attach_pnt, hint, flag, verbose);
-
- if ((ev = sysevent_alloc(EC_DR, ESC_DR_AP_STATE_CHANGE,
- SUNW_KERN_PUB"dr", km_flag)) == NULL) {
- rv = -2;
- goto logexit;
- }
- evnt_val.value_type = SE_DATA_TYPE_STRING;
- evnt_val.value.sv_string = attach_pnt;
- if ((rv = sysevent_add_attr(&evnt_attr_list, DR_AP_ID,
- &evnt_val, km_flag)) != 0)
- goto logexit;
-
- evnt_val.value_type = SE_DATA_TYPE_STRING;
- evnt_val.value.sv_string = hint;
- if ((rv = sysevent_add_attr(&evnt_attr_list, DR_HINT,
- &evnt_val, km_flag)) != 0) {
- sysevent_free_attr(evnt_attr_list);
- goto logexit;
- }
-
- (void) sysevent_attach_attributes(ev, evnt_attr_list);
-
- /*
- * Log the event but do not sleep waiting for its
- * delivery. This provides insulation from syseventd.
- */
- rv = log_sysevent(ev, SE_NOSLEEP, &eid);
-
-logexit:
- if (ev)
- sysevent_free(ev);
- if ((rv != 0) && verbose)
- cmn_err(CE_WARN,
- "drmach_log_sysevent failed (rv %d) for %s %s\n",
- rv, attach_pnt, hint);
-
- return (rv);
-}
-
-/*
- * Initialize the mem_slice portion of a claim/unconfig/unclaim mailbox message.
- * Only the valid entries are modified, so the array should be zeroed out
- * initially.
- */
-static void
-drmach_msg_memslice_init(dr_memslice_t slice_arr[]) {
- int i;
- char c;
-
- ASSERT(mutex_owned(&drmach_slice_table_lock));
-
- for (i = 0; i < AXQ_MAX_EXP; i++) {
- c = drmach_slice_table[i];
-
- if (c & 0x20) {
- slice_arr[i].valid = 1;
- slice_arr[i].slice = c & 0x1f;
- }
- }
-}
-
-/*
- * Initialize the mem_regs portion of a claim/unconfig/unclaim mailbox message.
- * Only the valid entries are modified, so the array should be zeroed out
- * initially.
- */
-static void
-drmach_msg_memregs_init(dr_memregs_t regs_arr[]) {
- int rv, exp, mcnum, bank;
- uint64_t madr;
- drmachid_t id;
- drmach_board_t *bp;
- drmach_mem_t *mp;
- dr_memregs_t *memregs;
-
- /* CONSTCOND */
- ASSERT(DRMACH_MC_NBANKS == (PMBANKS_PER_PORT * LMBANKS_PER_PMBANK));
-
- for (exp = 0; exp < 18; exp++) {
- rv = drmach_array_get(drmach_boards,
- DRMACH_EXPSLOT2BNUM(exp, 0), &id);
- ASSERT(rv == 0); /* should never be out of bounds */
- if (id == NULL) {
- continue;
- }
-
- memregs = &regs_arr[exp];
- bp = (drmach_board_t *)id;
- for (mp = bp->mem; mp != NULL; mp = mp->next) {
- mcnum = mp->dev.portid & 0x3;
- for (bank = 0; bank < DRMACH_MC_NBANKS; bank++) {
- drmach_mem_read_madr(mp, bank, &madr);
- if (madr & DRMACH_MC_VALID_MASK) {
- DRMACH_PR("%d.%d.%d.madr = 0x%lx\n",
- exp, mcnum, bank, madr);
- memregs->madr[mcnum][bank].hi =
- DRMACH_U64_TO_MCREGHI(madr);
- memregs->madr[mcnum][bank].lo =
- DRMACH_U64_TO_MCREGLO(madr);
- }
- }
- }
- }
-}
-
-/*
- * Do not allow physical address range modification if either board on this
- * expander has processors in NULL LPA mode (CBASE=CBND=NULL).
- *
- * A side effect of NULL proc LPA mode in Starcat SSM is that local reads will
- * install the cache line as owned/dirty as a result of the RTSR transaction.
- * See section 5.2.3 of the Safari spec. All processors will read the bus sync
- * list before the rename after flushing local caches. When copy-rename
- * requires changing the physical address ranges (i.e. smaller memory target),
- * the bus sync list contains physical addresses that will not exist after the
- * rename. If these cache lines are owned due to a RTSR, a system error can
- * occur following the rename when these cache lines are evicted and a writeback
- * is attempted.
- *
- * Incoming parameter represents either the copy-rename source or a candidate
- * target memory board. On Starcat, only slot0 boards may have memory.
- */
-int
-drmach_allow_memrange_modify(drmachid_t s0id)
-{
- drmach_board_t *s0bp, *s1bp;
- drmachid_t s1id;
- int rv;
-
- s0bp = s0id;
-
- ASSERT(DRMACH_IS_BOARD_ID(s0id));
- ASSERT(DRMACH_BNUM2SLOT(s0bp->bnum) == 0);
-
- if (s0bp->flags & DRMACH_NULL_PROC_LPA) {
- /*
- * This is reason enough to fail the request, no need
- * to check the device list for cpus.
- */
- return (0);
- }
-
- /*
- * Check for MCPU board on the same expander.
- *
- * The board flag DRMACH_NULL_PROC_LPA can be set for all board
- * types, as it is derived at from the POST gdcd board flag
- * L1SSFLG_THIS_L1_NULL_PROC_LPA, which can be set (and should be
- * ignored) for boards with no processors. Since NULL proc LPA
- * applies only to processors, we walk the devices array to detect
- * MCPUs.
- */
- rv = drmach_array_get(drmach_boards, s0bp->bnum + 1, &s1id);
- s1bp = s1id;
- if (rv == 0 && s1bp != NULL) {
-
- ASSERT(DRMACH_IS_BOARD_ID(s1id));
- ASSERT(DRMACH_BNUM2SLOT(s1bp->bnum) == 1);
- ASSERT(DRMACH_BNUM2EXP(s0bp->bnum) ==
- DRMACH_BNUM2EXP(s1bp->bnum));
-
- if ((s1bp->flags & DRMACH_NULL_PROC_LPA) &&
- s1bp->devices != NULL) {
- int d_idx;
- drmachid_t d_id;
-
- rv = drmach_array_first(s1bp->devices, &d_idx, &d_id);
- while (rv == 0) {
- if (DRMACH_IS_CPU_ID(d_id)) {
- /*
- * Fail MCPU in NULL LPA mode.
- */
- return (0);
- }
-
- rv = drmach_array_next(s1bp->devices, &d_idx,
- &d_id);
- }
- }
- }
-
- return (1);
-}
diff --git a/usr/src/uts/sun4u/starcat/io/fcgp2.c b/usr/src/uts/sun4u/starcat/io/fcgp2.c
deleted file mode 100644
index c7dad76348..0000000000
--- a/usr/src/uts/sun4u/starcat/io/fcgp2.c
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * fcgp2.c: Framework gp2 (Safari) fcode ops
- */
-#include <sys/types.h>
-#include <sys/kmem.h>
-#include <sys/systm.h>
-#include <sys/pci.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/sunndi.h>
-#include <sys/ddidmareq.h>
-#include <sys/modctl.h>
-#include <sys/ndi_impldefs.h>
-#include <sys/fcode.h>
-#include <sys/promif.h>
-#include <sys/promimpl.h>
-
-static int gfc_map_in(dev_info_t *, fco_handle_t, fc_ci_t *);
-static int gfc_map_out(dev_info_t *, fco_handle_t, fc_ci_t *);
-static int gfc_register_fetch(dev_info_t *, fco_handle_t, fc_ci_t *);
-static int gfc_register_store(dev_info_t *, fco_handle_t, fc_ci_t *);
-static int gfc_claim_address(dev_info_t *, fco_handle_t, fc_ci_t *);
-static int gfc_claim_memory(dev_info_t *, fco_handle_t, fc_ci_t *);
-static int gfc_release_memory(dev_info_t *, fco_handle_t, fc_ci_t *);
-static int gfc_vtop(dev_info_t *, fco_handle_t, fc_ci_t *);
-static int gfc_master_intr(dev_info_t *, fco_handle_t, fc_ci_t *);
-
-static int gfc_config_child(dev_info_t *, fco_handle_t, fc_ci_t *);
-
-static int gfc_get_fcode_size(dev_info_t *, fco_handle_t, fc_ci_t *);
-static int gfc_get_fcode(dev_info_t *, fco_handle_t, fc_ci_t *);
-
-int prom_get_fcode_size(char *);
-int prom_get_fcode(char *, char *);
-
-int fcpci_unloadable;
-int no_advisory_dma;
-
-#define HIADDR(n) ((uint32_t)(((uint64_t)(n) & 0xFFFFFFFF00000000)>> 32))
-#define LOADDR(n)((uint32_t)((uint64_t)(n) & 0x00000000FFFFFFFF))
-#define LADDR(lo, hi) (((uint64_t)(hi) << 32) | (uint32_t)(lo))
-#define PCI_4GIG_LIMIT 0xFFFFFFFFUL
-
-
-/*
- * Module linkage information for the kernel.
- */
-static struct modlmisc modlmisc = {
- &mod_miscops, "FCode gp2 (safari) bus functions"
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1, (void *)&modlmisc, NULL
-};
-
-int
-_init(void)
-{
- return (mod_install(&modlinkage));
-}
-
-int
-_fini(void)
-{
- if (fcpci_unloadable)
- return (mod_remove(&modlinkage));
- return (EBUSY);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-
-struct gfc_ops_v {
- char *svc_name;
- fc_ops_t *f;
-};
-
-struct gfc_ops_v gp2_pov[] = {
- { "map-in", gfc_map_in},
- { "map-out", gfc_map_out},
- { "rx@", gfc_register_fetch},
- { "rl@", gfc_register_fetch},
- { "rw@", gfc_register_fetch},
- { "rb@", gfc_register_fetch},
- { "rx!", gfc_register_store},
- { "rl!", gfc_register_store},
- { "rw!", gfc_register_store},
- { "rb!", gfc_register_store},
- { "claim-address", gfc_claim_address},
- { "master-interrupt", gfc_master_intr},
- { "claim-memory", gfc_claim_memory},
- { "release-memory", gfc_release_memory},
- { "vtop", gfc_vtop},
- { FC_CONFIG_CHILD, gfc_config_child},
- { FC_GET_FCODE_SIZE, gfc_get_fcode_size},
- { FC_GET_FCODE, gfc_get_fcode},
- { NULL, NULL}
-};
-
-struct gfc_ops_v gp2_shared_pov[] = {
- { NULL, NULL}
-};
-
-static int gp2_map_phys(dev_info_t *, struct regspec *, caddr_t *,
- ddi_device_acc_attr_t *, ddi_acc_handle_t *);
-static void gp2_unmap_phys(ddi_acc_handle_t *);
-
-fco_handle_t
-gp2_fc_ops_alloc_handle(dev_info_t *ap, dev_info_t *child,
- void *fcode, size_t fcode_size, char *unit_address,
- char *my_args)
-{
- fco_handle_t rp;
- phandle_t h;
-
- rp = kmem_zalloc(sizeof (struct fc_resource_list), KM_SLEEP);
- rp->next_handle = fc_ops_alloc_handle(ap, child, fcode, fcode_size,
- unit_address, NULL);
- rp->ap = ap;
- rp->child = child;
- rp->fcode = fcode;
- rp->fcode_size = fcode_size;
- rp->my_args = my_args;
-
- if (unit_address) {
- char *buf;
-
- buf = kmem_zalloc(strlen(unit_address) + 1, KM_SLEEP);
- (void) strcpy(buf, unit_address);
- rp->unit_address = buf;
- }
-
- /*
- * Add the child's nodeid to our table...
- */
- h = ddi_get_nodeid(rp->child);
- fc_add_dip_to_phandle(fc_handle_to_phandle_head(rp), rp->child, h);
-
- return (rp);
-}
-
-void
-gp2_fc_ops_free_handle(fco_handle_t rp)
-{
- struct fc_resource *ip, *np;
-
- ASSERT(rp);
-
- if (rp->next_handle)
- fc_ops_free_handle(rp->next_handle);
- if (rp->unit_address)
- kmem_free(rp->unit_address, strlen(rp->unit_address) + 1);
- if (rp->my_args != NULL)
- kmem_free(rp->my_args, strlen(rp->my_args) + 1);
-
- /*
- * Release all the resources from the resource list
- */
- for (ip = rp->head; ip != NULL; ip = np) {
- np = ip->next;
- switch (ip->type) {
- case RT_MAP:
- FC_DEBUG1(1, CE_CONT, "gp2_fc_ops_free: "
- " map handle - %p\n", ip->fc_map_handle);
- break;
- case RT_DMA:
- /* DMA has to be freed up at exit time */
- cmn_err(CE_CONT, "gfc_fc_ops_free: DMA seen!\n");
- break;
- case RT_CONTIGIOUS:
- FC_DEBUG2(1, CE_CONT, "gp2_fc_ops_free: "
- "Free claim-memory resource 0x%lx size 0x%x\n",
- ip->fc_contig_virt, ip->fc_contig_len);
-
- (void) ndi_ra_free(ddi_root_node(),
- (uint64_t)ip->fc_contig_virt,
- ip->fc_contig_len, "gptwo-contigousmem",
- NDI_RA_PASS);
-
- break;
- default:
- cmn_err(CE_CONT, "gp2_fc_ops_free: "
- "unknown resource type %d\n", ip->type);
- break;
- }
- fc_rem_resource(rp, ip);
- kmem_free(ip, sizeof (struct fc_resource));
- }
- kmem_free(rp, sizeof (struct fc_resource_list));
-}
-
-int
-gp2_fc_ops(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- struct gfc_ops_v *pv;
- char *name = fc_cell2ptr(cp->svc_name);
-
- ASSERT(rp);
-
- /*
- * First try the generic fc_ops. If the ops is a shared op,
- * also call our local function.
- */
- if (fc_ops(ap, rp->next_handle, cp) == 0) {
- for (pv = gp2_shared_pov; pv->svc_name != NULL; ++pv)
- if (strcmp(pv->svc_name, name) == 0)
- return (pv->f(ap, rp, cp));
- return (0);
- }
-
- for (pv = gp2_pov; pv->svc_name != NULL; ++pv)
- if (strcmp(pv->svc_name, name) == 0)
- return (pv->f(ap, rp, cp));
-
- FC_DEBUG1(9, CE_CONT, "gp2_fc_ops: <%s> not serviced\n", name);
-
- return (-1);
-}
-
-/*
- * map-in (phys.lo phys.hi size -- virt )
- */
-static int
-gfc_map_in(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- size_t len;
- int error;
- caddr_t virt;
- struct fc_resource *ip;
- struct regspec r;
- ddi_device_acc_attr_t acc;
- ddi_acc_handle_t h;
-
- if (fc_cell2int(cp->nargs) != 3)
- return (fc_syntax_error(cp, "nargs must be 3"));
-
- if (fc_cell2int(cp->nresults) < 1)
- return (fc_syntax_error(cp, "nresults must be >= 1"));
-
- r.regspec_size = len = fc_cell2size(fc_arg(cp, 0));
- r.regspec_bustype = fc_cell2uint(fc_arg(cp, 1));
- r.regspec_addr = fc_cell2uint(fc_arg(cp, 2));
-
- acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
- acc.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC;
- acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
-
- FC_DEBUG3(1, CE_CONT, "gfc_map_in: attempting map in "
- "address 0x%08x.%08x length %x\n", r.regspec_bustype,
- r.regspec_addr, r.regspec_size);
-
- error = gp2_map_phys(rp->child, &r, &virt, &acc, &h);
-
- if (error) {
- FC_DEBUG3(1, CE_CONT, "gfc_map_in: map in failed - "
- "address 0x%08x.%08x length %x\n", r.regspec_bustype,
- r.regspec_addr, r.regspec_size);
-
- return (fc_priv_error(cp, "gp2 map-in failed"));
- }
-
- FC_DEBUG1(3, CE_CONT, "gp2_map_in: returning virt %p\n", virt);
-
- cp->nresults = fc_int2cell(1);
- fc_result(cp, 0) = fc_ptr2cell(virt);
-
- /*
- * Log this resource ...
- */
- ip = kmem_zalloc(sizeof (struct fc_resource), KM_SLEEP);
- ip->type = RT_MAP;
- ip->fc_map_virt = virt;
- ip->fc_map_len = len;
- ip->fc_map_handle = h;
- fc_add_resource(rp, ip);
-
- return (fc_success_op(ap, rp, cp));
-}
-
-/*
- * map-out ( virt size -- )
- */
-static int
-gfc_map_out(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- caddr_t virt;
- size_t len;
- struct fc_resource *ip;
-
- if (fc_cell2int(cp->nargs) != 2)
- return (fc_syntax_error(cp, "nargs must be 2"));
-
- virt = fc_cell2ptr(fc_arg(cp, 1));
-
- len = fc_cell2size(fc_arg(cp, 0));
-
- FC_DEBUG2(1, CE_CONT, "gp2_map_out: attempting map out %p %x\n",
- virt, len);
-
- /*
- * Find if this request matches a mapping resource we set up.
- */
- fc_lock_resource_list(rp);
- for (ip = rp->head; ip != NULL; ip = ip->next) {
- if (ip->type != RT_MAP)
- continue;
- if (ip->fc_map_virt != virt)
- continue;
- if (ip->fc_map_len == len)
- break;
- }
- fc_unlock_resource_list(rp);
-
- if (ip == NULL)
- return (fc_priv_error(cp, "request doesn't match a "
- "known mapping"));
-
- gp2_unmap_phys(&ip->fc_map_handle);
-
- /*
- * remove the resource from the list and release it.
- */
- fc_rem_resource(rp, ip);
- kmem_free(ip, sizeof (struct fc_resource));
-
- cp->nresults = fc_int2cell(0);
- return (fc_success_op(ap, rp, cp));
-}
-
-static int
-gfc_register_fetch(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- size_t len;
- caddr_t virt;
- int error = 0;
- uint64_t x;
- uint32_t l;
- uint16_t w;
- uint8_t b;
- char *name = fc_cell2ptr(cp->svc_name);
- struct fc_resource *ip;
-
- if (fc_cell2int(cp->nargs) != 1)
- return (fc_syntax_error(cp, "nargs must be 1"));
-
- if (fc_cell2int(cp->nresults) < 1)
- return (fc_syntax_error(cp, "nresults must be >= 1"));
-
- virt = fc_cell2ptr(fc_arg(cp, 0));
-
- /*
- * Determine the access width .. we can switch on the 2nd
- * character of the name which is "rx@", "rl@", "rb@" or "rw@"
- */
- switch (*(name + 1)) {
- case 'x': len = sizeof (x); break;
- case 'l': len = sizeof (l); break;
- case 'w': len = sizeof (w); break;
- case 'b': len = sizeof (b); break;
- }
-
- /*
- * Check the alignment ...
- */
- if (((intptr_t)virt & (len - 1)) != 0)
- return (fc_priv_error(cp, "unaligned access"));
-
- /*
- * Find if this virt is 'within' a request we know about
- */
- fc_lock_resource_list(rp);
- for (ip = rp->head; ip != NULL; ip = ip->next) {
- if (ip->type == RT_MAP) {
- if ((virt >= (caddr_t)ip->fc_map_virt) && ((virt + len) <=
- ((caddr_t)ip->fc_map_virt + ip->fc_map_len)))
- break;
- } else if (ip->type == RT_CONTIGIOUS) {
- if ((virt >= (caddr_t)ip->fc_contig_virt) && ((virt + len)
- <= ((caddr_t)ip->fc_contig_virt + ip->fc_contig_len)))
- break;
- }
- }
- fc_unlock_resource_list(rp);
-
- if (ip == NULL) {
- return (fc_priv_error(cp, "request not within a "
- "known mapping or contigious adddress"));
- }
-
- switch (len) {
- case sizeof (x):
- if (ip->type == RT_MAP)
- error = ddi_peek64(rp->child,
- (int64_t *)virt, (int64_t *)&x);
- else /* RT_CONTIGIOUS */
- x = *(int64_t *)virt;
- break;
- case sizeof (l):
- if (ip->type == RT_MAP)
- error = ddi_peek32(rp->child,
- (int32_t *)virt, (int32_t *)&l);
- else /* RT_CONTIGIOUS */
- l = *(int32_t *)virt;
- break;
- case sizeof (w):
- if (ip->type == RT_MAP)
- error = ddi_peek16(rp->child,
- (int16_t *)virt, (int16_t *)&w);
- else /* RT_CONTIGIOUS */
- w = *(int16_t *)virt;
- break;
- case sizeof (b):
- if (ip->type == RT_MAP)
- error = ddi_peek8(rp->child,
- (int8_t *)virt, (int8_t *)&b);
- else /* RT_CONTIGIOUS */
- b = *(int8_t *)virt;
- break;
- }
-
- if (error) {
- FC_DEBUG2(1, CE_CONT, "gfc_register_fetch: access error "
- "accessing virt %p len %d\n", virt, len);
- return (fc_priv_error(cp, "access error"));
- }
-
- cp->nresults = fc_int2cell(1);
- switch (len) {
- case sizeof (x): fc_result(cp, 0) = x; break;
- case sizeof (l): fc_result(cp, 0) = fc_uint32_t2cell(l); break;
- case sizeof (w): fc_result(cp, 0) = fc_uint16_t2cell(w); break;
- case sizeof (b): fc_result(cp, 0) = fc_uint8_t2cell(b); break;
- }
- return (fc_success_op(ap, rp, cp));
-}
-
-static int
-gfc_register_store(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- size_t len;
- caddr_t virt;
- uint64_t x;
- uint32_t l;
- uint16_t w;
- uint8_t b;
- char *name = fc_cell2ptr(cp->svc_name);
- struct fc_resource *ip;
- int error = 0;
-
- if (fc_cell2int(cp->nargs) != 2)
- return (fc_syntax_error(cp, "nargs must be 2"));
-
- virt = fc_cell2ptr(fc_arg(cp, 0));
-
- /*
- * Determine the access width .. we can switch on the 2nd
- * character of the name which is "rx!", "rl!", "rb!" or "rw!"
- */
- switch (*(name + 1)) {
- case 'x': len = sizeof (x); x = fc_arg(cp, 1); break;
- case 'l': len = sizeof (l); l = fc_cell2uint32_t(fc_arg(cp, 1)); break;
- case 'w': len = sizeof (w); w = fc_cell2uint16_t(fc_arg(cp, 1)); break;
- case 'b': len = sizeof (b); b = fc_cell2uint8_t(fc_arg(cp, 1)); break;
- }
-
- /*
- * Check the alignment ...
- */
- if (((intptr_t)virt & (len - 1)) != 0)
- return (fc_priv_error(cp, "unaligned access"));
-
- /*
- * Find if this virt is 'within' a request we know about
- */
- fc_lock_resource_list(rp);
- for (ip = rp->head; ip != NULL; ip = ip->next) {
- if (ip->type == RT_MAP) {
- if ((virt >= (caddr_t)ip->fc_map_virt) && ((virt + len) <=
- ((caddr_t)ip->fc_map_virt + ip->fc_map_len)))
- break;
- } else if (ip->type == RT_CONTIGIOUS) {
- if ((virt >= (caddr_t)ip->fc_contig_virt) && ((virt + len)
- <= ((caddr_t)ip->fc_contig_virt + ip->fc_contig_len)))
- break;
- }
- }
- fc_unlock_resource_list(rp);
-
- if (ip == NULL)
- return (fc_priv_error(cp, "request not within a "
- "known mapping or contigious address"));
-
- switch (len) {
- case sizeof (x):
- if (ip->type == RT_MAP)
- error = ddi_poke64(rp->child, (int64_t *)virt, x);
- else if (ip->type == RT_CONTIGIOUS)
- *(uint64_t *)virt = x;
- break;
- case sizeof (l):
- if (ip->type == RT_MAP)
- error = ddi_poke32(rp->child, (int32_t *)virt, l);
- else if (ip->type == RT_CONTIGIOUS)
- *(uint32_t *)virt = l;
- break;
- case sizeof (w):
- if (ip->type == RT_MAP)
- error = ddi_poke16(rp->child, (int16_t *)virt, w);
- else if (ip->type == RT_CONTIGIOUS)
- *(uint16_t *)virt = w;
- break;
- case sizeof (b):
- if (ip->type == RT_MAP)
- error = ddi_poke8(rp->child, (int8_t *)virt, b);
- else if (ip->type == RT_CONTIGIOUS)
- *(uint8_t *)virt = b;
- break;
- }
-
- if (error == DDI_FAILURE) {
- FC_DEBUG2(1, CE_CONT, "gfc_register_store: access error "
- "accessing virt %p len %d\n", virt, len);
- return (fc_priv_error(cp, "access error"));
- }
-
- cp->nresults = fc_int2cell(0);
- return (fc_success_op(ap, rp, cp));
-}
-
-static int
-gfc_master_intr(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- int xt, portid;
-
- if (fc_cell2int(cp->nargs) != 2)
- return (fc_syntax_error(cp, "nargs must be 4"));
-
- if (fc_cell2int(cp->nresults) < 1)
- return (fc_syntax_error(cp, "nresults must be >= 1"));
-
- xt = fc_cell2int(fc_arg(cp, 1));
- portid = fc_cell2int(fc_arg(cp, 0));
-
- FC_DEBUG2(1, CE_CONT, "gfc_master_intr: reset-int-xt=%x portid=%x",
- xt, portid);
-
- cp->nresults = fc_int2cell(1);
- fc_result(cp, 0) = 0;
-
- return (fc_success_op(ap, rp, cp));
-}
-
-/*
- * gfc_claim_address
- *
- * claim-address (size.lo size.hi type align bar portid -- base.lo base.hi )
- */
-static int
-gfc_claim_address(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- int bar, portid;
- uint64_t exp, slot, port, slice;
- uint64_t paddr;
-
- if (fc_cell2int(cp->nargs) != 6)
- return (fc_syntax_error(cp, "nargs must be 6"));
-
- if (fc_cell2int(cp->nresults) < 2)
- return (fc_syntax_error(cp, "nresults must be 2"));
-
- bar = fc_cell2int(fc_arg(cp, 1));
- portid = fc_cell2int(fc_arg(cp, 0));
-
- exp = portid >> 5;
- slot = (0x8 & portid) >> 3;
- port = portid & 0x1;
-
- switch (bar) {
- case 0: /* PCI IO Bus A */
- paddr = (exp << 28) | (port << 26) | (slot << 27) |
- ((uint64_t)0x402 << 32);
-
- break;
- case 1: /* PCI Memory Bus A */
- slice = (exp * 2) + slot + 1;
-
- paddr = ((uint64_t)1 << 42) | ((uint64_t)slice << 34) |
- ((uint64_t)port << 33);
-
- break;
- case 2: /* PCI IO Bus B */
- paddr = (exp << 28) | (port << 26) | (slot << 27) |
- ((uint64_t)0x402 << 32) | (1 << 25);
-
- break;
- case 3: /* PCI Memory Bus B */
- slice = (exp * 2) + slot + 1;
-
- paddr = ((uint64_t)1 << 42) | ((uint64_t)slice << 34) |
- ((uint64_t)port << 33);
-
- paddr |= ((uint64_t)1 << 32);
-
- break;
- default:
- cmn_err(CE_WARN,
- "gfc_claim_address - invalid BAR=0x%x\n", bar);
-
- return (fc_syntax_error(cp, "invalid argument"));
- }
-
- FC_DEBUG1(1, CE_CONT, "gfc_claim_address: returning 0x%lx\n", paddr);
-
- cp->nresults = fc_int2cell(2);
- fc_result(cp, 0) = LOADDR(paddr);
- fc_result(cp, 1) = HIADDR(paddr);
-
- return (fc_success_op(ap, rp, cp));
-}
-
-/*
- * gfc_claim_memory
- *
- * claim-memory ( align size vhint -- vaddr)
- */
-static int
-gfc_claim_memory(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- int align, size, vhint;
- ndi_ra_request_t request;
- uint64_t answer, alen;
- struct fc_resource *ip;
-
- if (fc_cell2int(cp->nargs) != 3)
- return (fc_syntax_error(cp, "nargs must be 3"));
-
- if (fc_cell2int(cp->nresults) < 1)
- return (fc_syntax_error(cp, "nresults must be >= 1"));
-
- vhint = fc_cell2int(fc_arg(cp, 2));
- size = fc_cell2int(fc_arg(cp, 1));
- align = fc_cell2int(fc_arg(cp, 0));
-
- FC_DEBUG3(1, CE_CONT, "gfc_claim_memory: align=0x%x size=0x%x "
- "vhint=0x%x\n", align, size, vhint);
-
- if (size == 0) {
- cmn_err(CE_WARN, " gfc_claim_memory - unable to allocate "
- "contigiuos memory of size zero\n");
- return (fc_priv_error(cp, "allocation error"));
- }
-
- if (vhint) {
- cmn_err(CE_WARN, "gfc_claim_memory - vhint is not zero "
- "vhint=0x%x - Ignoring Argument\n", vhint);
- }
-
- bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
- request.ra_flags = NDI_RA_ALLOC_BOUNDED;
- request.ra_boundbase = 0;
- request.ra_boundlen = 0xffffffff;
- request.ra_len = size;
- request.ra_align_mask = align - 1;
-
- if (ndi_ra_alloc(ddi_root_node(), &request, &answer, &alen,
- "gptwo-contigousmem", NDI_RA_PASS) != NDI_SUCCESS) {
- cmn_err(CE_WARN, " gfc_claim_memory - unable to allocate "
- "contigiuos memory\n");
- return (fc_priv_error(cp, "allocation error"));
-
- }
-
- FC_DEBUG2(1, CE_CONT, "gfc_claim_memory: address allocated=0x%lx "
- "size=0x%x\n", answer, alen);
-
- cp->nresults = fc_int2cell(1);
- fc_result(cp, 0) = answer;
-
- /*
- * Log this resource ...
- */
- ip = kmem_zalloc(sizeof (struct fc_resource), KM_SLEEP);
- ip->type = RT_CONTIGIOUS;
- ip->fc_contig_virt = (void *)answer;
- ip->fc_contig_len = size;
- fc_add_resource(rp, ip);
-
- return (fc_success_op(ap, rp, cp));
-}
-
-/*
- * gfc_release_memory
- *
- * release-memory ( size vaddr -- )
- */
-static int
-gfc_release_memory(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- int32_t vaddr, size;
- struct fc_resource *ip;
-
- if (fc_cell2int(cp->nargs) != 2)
- return (fc_syntax_error(cp, "nargs must be 2"));
-
- if (fc_cell2int(cp->nresults) != 0)
- return (fc_syntax_error(cp, "nresults must be 0"));
-
- vaddr = fc_cell2int(fc_arg(cp, 1));
- size = fc_cell2int(fc_arg(cp, 0));
-
- FC_DEBUG2(1, CE_CONT, "gfc_release_memory: vaddr=0x%x size=0x%x\n",
- vaddr, size);
- /*
- * Find if this request matches a mapping resource we set up.
- */
- fc_lock_resource_list(rp);
- for (ip = rp->head; ip != NULL; ip = ip->next) {
- if (ip->type != RT_CONTIGIOUS)
- continue;
- if (ip->fc_contig_virt != (void *)(uintptr_t)vaddr)
- continue;
- if (ip->fc_contig_len == size)
- break;
- }
- fc_unlock_resource_list(rp);
-
- if (ip == NULL)
- return (fc_priv_error(cp, "request doesn't match a "
- "known mapping"));
-
- (void) ndi_ra_free(ddi_root_node(), vaddr, size,
- "gptwo-contigousmem", NDI_RA_PASS);
-
- /*
- * remove the resource from the list and release it.
- */
- fc_rem_resource(rp, ip);
- kmem_free(ip, sizeof (struct fc_resource));
-
- cp->nresults = fc_int2cell(0);
-
- return (fc_success_op(ap, rp, cp));
-}
-
-/*
- * gfc_vtop
- *
- * vtop ( vaddr -- paddr.lo paddr.hi)
- */
-static int
-gfc_vtop(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- int vaddr;
- uint64_t paddr;
- struct fc_resource *ip;
-
- if (fc_cell2int(cp->nargs) != 1)
- return (fc_syntax_error(cp, "nargs must be 1"));
-
- if (fc_cell2int(cp->nresults) >= 3)
- return (fc_syntax_error(cp, "nresults must be less than 2"));
-
- vaddr = fc_cell2int(fc_arg(cp, 0));
-
- /*
- * Find if this request matches a mapping resource we set up.
- */
- fc_lock_resource_list(rp);
- for (ip = rp->head; ip != NULL; ip = ip->next) {
- if (ip->type != RT_CONTIGIOUS)
- continue;
- if (ip->fc_contig_virt == (void *)(uintptr_t)vaddr)
- break;
- }
- fc_unlock_resource_list(rp);
-
- if (ip == NULL)
- return (fc_priv_error(cp, "request doesn't match a "
- "known mapping"));
-
-
- paddr = va_to_pa((void *)(uintptr_t)vaddr);
-
- FC_DEBUG2(1, CE_CONT, "gfc_vtop: vaddr=0x%x paddr=0x%x\n",
- vaddr, paddr);
-
- cp->nresults = fc_int2cell(2);
-
- fc_result(cp, 0) = paddr;
- fc_result(cp, 1) = 0;
-
- return (fc_success_op(ap, rp, cp));
-}
-
-static int
-gfc_config_child(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- fc_phandle_t h;
-
- if (fc_cell2int(cp->nargs) != 0)
- return (fc_syntax_error(cp, "nargs must be 0"));
-
- if (fc_cell2int(cp->nresults) < 1)
- return (fc_syntax_error(cp, "nresults must be >= 1"));
-
- h = fc_dip_to_phandle(fc_handle_to_phandle_head(rp), rp->child);
-
- cp->nresults = fc_int2cell(1);
- fc_result(cp, 0) = fc_phandle2cell(h);
-
- return (fc_success_op(ap, rp, cp));
-}
-
-static int
-gfc_get_fcode(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- caddr_t name_virt, fcode_virt;
- char *name, *fcode;
- int fcode_len, status;
-
- if (fc_cell2int(cp->nargs) != 3)
- return (fc_syntax_error(cp, "nargs must be 3"));
-
- if (fc_cell2int(cp->nresults) < 1)
- return (fc_syntax_error(cp, "nresults must be >= 1"));
-
- name_virt = fc_cell2ptr(fc_arg(cp, 0));
-
- fcode_virt = fc_cell2ptr(fc_arg(cp, 1));
-
- fcode_len = fc_cell2int(fc_arg(cp, 2));
-
- name = kmem_zalloc(FC_SVC_NAME_LEN, KM_SLEEP);
-
- if (copyinstr(fc_cell2ptr(name_virt), name,
- FC_SVC_NAME_LEN - 1, NULL)) {
- FC_DEBUG1(1, CE_CONT, "gfc_get_fcode: "
- "fault copying in drop in name %p\n", name_virt);
- status = 0;
- } else {
-
- fcode = kmem_zalloc(fcode_len, KM_SLEEP);
-
- if ((status = prom_get_fcode(name, fcode)) != 0) {
-
- if (copyout((void *)fcode, (void *)fcode_virt,
- fcode_len)) {
- cmn_err(CE_WARN, " gfc_get_fcode: Unable "
- "to copy out fcode image\n");
- status = 0;
- }
- }
-
- kmem_free(fcode, fcode_len);
- }
-
- kmem_free(name, FC_SVC_NAME_LEN);
-
- cp->nresults = fc_int2cell(1);
- fc_result(cp, 0) = status;
-
- return (fc_success_op(ap, rp, cp));
-}
-
-static int
-gfc_get_fcode_size(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
-{
- caddr_t virt;
- char *name;
- int len;
-
- if (fc_cell2int(cp->nargs) != 1)
- return (fc_syntax_error(cp, "nargs must be 1"));
-
- if (fc_cell2int(cp->nresults) < 1)
- return (fc_syntax_error(cp, "nresults must be >= 1"));
-
- virt = fc_cell2ptr(fc_arg(cp, 0));
-
- name = kmem_zalloc(FC_SVC_NAME_LEN, KM_SLEEP);
-
- if (copyinstr(fc_cell2ptr(virt), name,
- FC_SVC_NAME_LEN - 1, NULL)) {
- FC_DEBUG1(1, CE_CONT, "gfc_get_fcode_size: "
- "fault copying in drop in name %p\n", virt);
- len = 0;
- } else {
-
- len = prom_get_fcode_size(name);
- }
-
- kmem_free(name, FC_SVC_NAME_LEN);
-
- cp->nresults = fc_int2cell(1);
- fc_result(cp, 0) = len;
-
- return (fc_success_op(ap, rp, cp));
-}
-
-static int
-gp2_map_phys(dev_info_t *dip, struct regspec *phys_spec,
- caddr_t *addrp, ddi_device_acc_attr_t *accattrp,
- ddi_acc_handle_t *handlep)
-{
- ddi_map_req_t mr;
- ddi_acc_hdl_t *hp;
- int result;
- struct regspec *ph;
-
- *handlep = impl_acc_hdl_alloc(KM_SLEEP, NULL);
- hp = impl_acc_hdl_get(*handlep);
- hp->ah_vers = VERS_ACCHDL;
- hp->ah_dip = dip;
- hp->ah_rnumber = 0;
- hp->ah_offset = 0;
- hp->ah_len = 0;
- hp->ah_acc = *accattrp;
- ph = kmem_zalloc(sizeof (struct regspec), KM_SLEEP);
- *ph = *phys_spec;
- hp->ah_bus_private = ph; /* cache a copy of the reg spec */
-
- mr.map_op = DDI_MO_MAP_LOCKED;
- mr.map_type = DDI_MT_REGSPEC;
- mr.map_obj.rp = (struct regspec *)phys_spec;
- mr.map_prot = PROT_READ | PROT_WRITE;
- mr.map_flags = DDI_MF_KERNEL_MAPPING;
- mr.map_handlep = hp;
- mr.map_vers = DDI_MAP_VERSION;
-
- result = ddi_map(dip, &mr, 0, 0, addrp);
-
- if (result != DDI_SUCCESS) {
- impl_acc_hdl_free(*handlep);
- *handlep = (ddi_acc_handle_t)NULL;
- } else {
- hp->ah_addr = *addrp;
- }
-
- return (result);
-}
-
-static void
-gp2_unmap_phys(ddi_acc_handle_t *handlep)
-{
- ddi_map_req_t mr;
- ddi_acc_hdl_t *hp;
- struct regspec_t *ph;
-
- hp = impl_acc_hdl_get(*handlep);
- ASSERT(hp);
- ph = hp->ah_bus_private;
-
- mr.map_op = DDI_MO_UNMAP;
- mr.map_type = DDI_MT_REGSPEC;
- mr.map_obj.rp = (struct regspec *)ph;
- mr.map_prot = PROT_READ | PROT_WRITE;
- mr.map_flags = DDI_MF_KERNEL_MAPPING;
- mr.map_handlep = hp;
- mr.map_vers = DDI_MAP_VERSION;
-
- (void) ddi_map(hp->ah_dip, &mr, hp->ah_offset,
- hp->ah_len, &hp->ah_addr);
-
- impl_acc_hdl_free(*handlep);
- kmem_free(ph, sizeof (struct regspec)); /* Free the cached copy */
- *handlep = (ddi_acc_handle_t)NULL;
-}
diff --git a/usr/src/uts/sun4u/starcat/io/gptwo_pci.c b/usr/src/uts/sun4u/starcat/io/gptwo_pci.c
deleted file mode 100644
index b7e7a84c2e..0000000000
--- a/usr/src/uts/sun4u/starcat/io/gptwo_pci.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Schizo/PCI Functions to the Safari Configurator
- *
- */
-
-#include <sys/types.h>
-#include <sys/cred.h>
-#include <sys/mman.h>
-#include <sys/kmem.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/sunndi.h>
-#include <sys/modctl.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/autoconf.h>
-#include <sys/ksynch.h>
-#include <sys/promif.h>
-#include <sys/ndi_impldefs.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/machsystm.h>
-#include <sys/gp2cfg.h>
-#include <sys/gptwo_pci.h>
-
-#ifdef DEBUG
-int gptwo_pci_debug = 0;
-
-static void debug(char *, uintptr_t, uintptr_t,
- uintptr_t, uintptr_t, uintptr_t);
-
-#define GPTWO_DEBUG0(level, flag, s) if (gptwo_pci_debug >= level) \
- cmn_err(flag, s)
-#define GPTWO_DEBUG1(level, flag, fmt, a1) if (gptwo_pci_debug >= level) \
- debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0);
-#define GPTWO_DEBUG2(level, flag, fmt, a1, a2) if (gptwo_pci_debug >= level) \
- debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
-#define GPTWO_DEBUG3(level, flag, fmt, a1, a2, a3) \
- if (gptwo_pci_debug >= level) \
- debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), (uintptr_t)(a3), 0, 0);
-#else
-#define GPTWO_DEBUG0(level, flag, s)
-#define GPTWO_DEBUG1(level, flag, fmt, a1)
-#define GPTWO_DEBUG2(level, flag, fmt, a1, a2)
-#define GPTWO_DEBUG3(level, flag, fmt, a1, a2, a3)
-#endif
-
-void gptwocfg_devi_attach_to_parent(dev_info_t *);
-static char *gptwo_get_probe_string(spcd_t *, int);
-static void gptwo_find_nodes(dev_info_t *, int, gptwo_new_nodes_t *);
-
-extern caddr_t efcode_vaddr;
-extern int efcode_size;
-
-/*
- * Module linkage information for the kernel.
- */
-
-extern struct mod_ops mod_miscops;
-
-static struct modlmisc modlmisc = {
- &mod_miscops, /* Type of module */
- "gptwo->pci configurator",
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1, (void *)&modlmisc, NULL
-};
-
-int
-_init(void)
-{
- int err = 0;
-
- /*
- * Create a resource map for the contigous memory allocated
- * at start-of-day in startup.c
- */
- if (ndi_ra_map_setup(ddi_root_node(), "gptwo-contigousmem")
- == NDI_FAILURE) {
- GPTWO_DEBUG0(1, CE_WARN,
- "Can not setup resource map - gptwo-contigousmem\n");
- return (1);
- }
-
- /*
- * Put the allocated memory into the pool.
- */
- (void) ndi_ra_free(ddi_root_node(), (uint64_t)efcode_vaddr,
- (uint64_t)efcode_size, "gptwo-contigousmem", 0);
-
- /* register devices with the configurator */
- gptwocfg_register_ops(SAFPTYPE_sPCI, gptwo_configure_pci,
- gptwo_unconfigure_pci);
- gptwocfg_register_ops(SAFPTYPE_cPCI, gptwo_configure_pci,
- gptwo_unconfigure_pci);
- gptwocfg_register_ops(SAFPTYPE_PCIX, gptwo_configure_pci,
- gptwo_unconfigure_pci);
-
- if ((err = mod_install(&modlinkage)) != 0) {
- GPTWO_DEBUG1(1, CE_WARN, "gptwo_pci (PCI Functions) "
- "failed to load, error=%d\n", err);
- gptwocfg_unregister_ops(SAFPTYPE_sPCI);
- gptwocfg_unregister_ops(SAFPTYPE_cPCI);
- gptwocfg_unregister_ops(SAFPTYPE_PCIX);
- } else {
- GPTWO_DEBUG0(1, CE_WARN, "gptwo_pci (PCI Functions) "
- "has been loaded.\n");
- }
- return (err);
-}
-
-int
-_fini(void)
-{
- gptwocfg_unregister_ops(SAFPTYPE_sPCI);
- gptwocfg_unregister_ops(SAFPTYPE_cPCI);
- gptwocfg_unregister_ops(SAFPTYPE_PCIX);
- return (mod_remove(&modlinkage));
-}
-
-int
-_info(modinfop)
-struct modinfo *modinfop;
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-/*ARGSUSED*/
-static int
-set_name_prop(dev_info_t *dip, void *arg, uint_t flags)
-{
- if (ndi_prop_update_string(DDI_DEV_T_NONE, dip,
- "name", "pci") != DDI_SUCCESS) {
- return (DDI_WALK_ERROR);
- }
-
- return (DDI_WALK_TERMINATE);
-}
-
-/*ARGSUSED*/
-static void
-get_new_child(dev_info_t *rdip, void *arg, uint_t flags)
-{
- dev_info_t **dipp = (dev_info_t **)arg;
-
- ASSERT(dipp && (*dipp == NULL));
-
- *dipp = rdip;
-}
-
-gptwo_new_nodes_t *
-gptwo_configure_pci(dev_info_t *ap, spcd_t *pcd, uint_t id)
-{
- fco_handle_t fco_handle;
- int error, i, circ, freq;
- dev_info_t *new_child;
- char unit_address[64];
- gptwo_new_nodes_t *new_nodes;
- char *probe_string;
- devi_branch_t b = {0};
-
- GPTWO_DEBUG2(1, CE_CONT, "gptwo_configure_pci: id=%x pcd=%lx\n",
- id, pcd);
-
- new_nodes = gptwocfg_allocate_node_list(IOBUS_PER_PORT);
-
- i = IOBUS_PER_PORT;
-
- while (i) {
- i--;
-
- if (pcd->spcd_iobus_rsv[i] != SPCD_RSV_PASS) {
-
- cmn_err(CE_WARN, "gptwo_configure_pci: saf id=0x%x "
- "leaf %d - Can not be probed\n", id, i);
-
- continue;
- }
-
- /*
- * Ideally, fcode would be run from the "sid_branch_create"
- * callback (that is the primary purpose of that callback).
- * However, the fcode interpreter was written with the
- * assumption that the "new_child" was linked into the
- * device tree. The callback is invoked with the devinfo node
- * in the DS_PROTO state. More investigation is needed before
- * we can invoke the interpreter from the callback. For now,
- * we create the "new_child" in the BOUND state, invoke the
- * fcode interpreter and then rebind the dip to use any
- * compatible properties created by fcode.
- */
-
- new_child = NULL;
-
- b.arg = &new_child;
- b.type = DEVI_BRANCH_SID;
- b.create.sid_branch_create = set_name_prop;
- b.devi_branch_callback = get_new_child;
-
- /*
- * Prevent any changes to new_child
- * until we have bound it to the correct driver.
- */
- ndi_devi_enter(ap, &circ);
- if (e_ddi_branch_create(ap, &b, NULL, 0)) {
- ASSERT(new_child == NULL);
-
- if (new_nodes->gptwo_nodes[0] == NULL) {
- GPTWO_DEBUG0(1, CE_CONT, "gptwo_configure_pci: "
- "No nodes configured - "
- "removing new_nodes\n");
- gptwocfg_free_node_list(new_nodes);
- new_nodes = NULL;
- }
-
- ndi_devi_exit(ap, circ);
-
- return (new_nodes);
- }
-
- /*
- * The platform DR interfaces created the dip in
- * bound state. Bring devinfo node down to linked
- * state and hold it there until compatible
- * properties are created.
- */
- e_ddi_branch_rele(new_child);
- (void) i_ndi_unconfig_node(new_child, DS_LINKED, 0);
- ASSERT(i_ddi_node_state(new_child) == DS_LINKED);
- e_ddi_branch_hold(new_child);
-
- mutex_enter(&DEVI(new_child)->devi_lock);
- DEVI(new_child)->devi_flags |= DEVI_NO_BIND;
- mutex_exit(&DEVI(new_child)->devi_lock);
-
- /*
- * Drop the busy-hold on parent before calling
- * fcode_interpreter to prevent potential deadlocks
- */
- ndi_devi_exit(ap, circ);
-
- (void) sprintf(unit_address, "%x", id);
-
- /*
- * Build the probe string from the PCD that will be passed
- * in to the interpreter as my-args. This will tell the
- * fcode what pci devices to probe after the pci node has
- * been probed.
- */
- probe_string = gptwo_get_probe_string(pcd, i);
-
- GPTWO_DEBUG3(1, CE_CONT, "gptwo_configure_pci: args to "
- "interpreter ap=%lx new_child=%lx unit_address=%s\n",
- ap, new_child, unit_address);
-
- if (probe_string)
- GPTWO_DEBUG1(1, CE_CONT, "gptwo_configure_pci: "
- "probe string=%s\n", probe_string);
-
- fco_handle = gp2_fc_ops_alloc_handle(ap, new_child, NULL, NULL,
- unit_address, probe_string);
-
- GPTWO_DEBUG0(1, CE_CONT,
- "gptwocfg: Calling Fcode Interpeter...\n");
-
- error = fcode_interpreter(ap, &gp2_fc_ops, fco_handle);
-
- GPTWO_DEBUG1(1, CE_CONT,
- "gptwo_configure_pci: fcode_interpreter "
- " returned %x\n", error);
-
- if (error) {
- cmn_err(CE_WARN, "gptwo_pci: Unable to probe pci leaf "
- "%s\n", unit_address);
-
- gp2_fc_ops_free_handle(fco_handle);
-
- (void) e_ddi_branch_destroy(new_child, NULL, 0);
- } else {
- gptwocfg_save_handle(new_child, fco_handle);
-
- /*
- * Compatible properties (if any) have been created,
- * so bind driver.
- */
- ndi_devi_enter(ap, &circ);
- ASSERT(i_ddi_node_state(new_child) <= DS_LINKED);
-
- mutex_enter(&DEVI(new_child)->devi_lock);
- DEVI(new_child)->devi_flags &= ~DEVI_NO_BIND;
- mutex_exit(&DEVI(new_child)->devi_lock);
-
- ndi_devi_exit(ap, circ);
-
- if (ndi_devi_bind_driver(new_child, 0) !=
- DDI_SUCCESS) {
- cmn_err(CE_WARN, "gptwo_pci: Unable to bind"
- " new pci child at dip=0x%p\n",
- (void *)new_child);
- }
-
- /*
- * If POST provided a frequency, the clock-frequency
- * property needs to be updated.
- */
- if (pcd->spcd_afreq) {
-
- /*
- * The upper byte is for leaf B and the lower
- * byte is for leaf A.
- */
- if (i)
- freq = pcd->spcd_afreq >> 8;
- else
- freq = pcd->spcd_afreq & 0x00ff;
-
- (void) ndi_prop_update_int(DDI_DEV_T_NONE,
- new_child, "clock-frequency",
- (freq * 1000 * 1000));
- }
- }
- }
-
- gptwo_find_nodes(ap, id, new_nodes);
-
- if (new_nodes->gptwo_nodes[0] == NULL) {
- GPTWO_DEBUG0(1, CE_CONT, "gptwo_configure_pci: "
- "No nodes configured - removing new_nodes\n");
- gptwocfg_free_node_list(new_nodes);
- new_nodes = NULL;
- }
-
- GPTWO_DEBUG1(1, CE_CONT, "gptwo_configure_pci: "
- "Returning new_nodes=%p\n", new_nodes);
-
- return (new_nodes);
-}
-
-dev_info_t *
-gptwo_unconfigure_pci(dev_info_t *dip)
-{
- fco_handle_t fco_handle;
-
- fco_handle = gptwocfg_get_handle(dip);
-
- if (fco_handle != NULL) {
- /*
- * If there is a handle, there may be resources
- * that need to be freed from when the
- * devices's fcode ran.
- */
- GPTWO_DEBUG1(1, CE_CONT, "fco_handle=%lx\n", fco_handle);
- gp2_fc_ops_free_handle(fco_handle);
- }
- return (NULL);
-}
-
-static void
-gptwo_find_nodes(dev_info_t *ap, int id, gptwo_new_nodes_t *new_nodes)
-{
- dev_info_t *saf_dev;
- int found, j, circ;
- int i = 0;
-
- GPTWO_DEBUG1(1, CE_CONT, "gptwo_find_nodes - id=%x\n", id);
-
- /*
- * We are walking child list of ap, so hold it busy
- */
- ndi_devi_enter(ap, &circ);
-
- saf_dev = ddi_get_child(ap);
- while (saf_dev != NULL) {
- if (ddi_getprop(DDI_DEV_T_ANY, saf_dev,
- DDI_PROP_DONTPASS, "portid", -1) == id) {
- if (i < IOBUS_PER_PORT) {
-
- GPTWO_DEBUG2(1, CE_CONT,
- "gptwo_find_nodes - "
- "Found %d %p\n", i, saf_dev);
-
- found = 0;
- for (j = 0; j < IOBUS_PER_PORT; j++) {
- if (new_nodes->gptwo_nodes[j] ==
- saf_dev) {
- found = 1;
- }
- }
- if (!found) {
- /*
- * Branch rooted at saf-dev was
- * held earlier.
- */
- ASSERT(e_ddi_branch_held(saf_dev));
- new_nodes->gptwo_nodes[i] = saf_dev;
- i++;
- }
- } else {
- GPTWO_DEBUG0(1, CE_CONT,
- "gptwo_find_nodes - "
- "No room in new_nodes\n");
- }
- }
- saf_dev = ddi_get_next_sibling(saf_dev);
- }
-
- ndi_devi_exit(ap, circ);
-}
-
-static char *
-gptwo_get_probe_string(spcd_t *pcd, int bus_number)
-{
- int i, str_size;
- char temp[64];
- char num[8];
- char *probe;
-
- GPTWO_DEBUG2(1, CE_CONT, "gptwo_get_probe_string - %p %x\n", pcd,
- bus_number);
-
- temp[0] = NULL;
-
- for (i = 0; i < IOCARD_PER_BUS; i++) {
-
- GPTWO_DEBUG2(1, CE_CONT, "gptwo_get_probe_string - "
- "card status %x %x\n",
- i, pcd->spcd_iocard_rsv[bus_number][i]);
-
- if (pcd->spcd_iocard_rsv[bus_number][i] == SPCD_RSV_PASS) {
- numtos(i, num);
- if (temp[0] == NULL)
- (void) sprintf(temp, "%s", num);
- else
- (void) sprintf(temp, "%s,%s", temp, num);
- }
- }
-
- if (bus_number == 0)
- (void) sprintf(temp, "%sa", temp); /* Append a 'a' for leaf A */
- else
- (void) sprintf(temp, "%sb", temp); /* Append a 'b' for leaf B */
-
- str_size = strlen(temp);
-
- if (str_size == 0)
- return (NULL);
-
- probe = kmem_zalloc(str_size + 1, KM_SLEEP);
-
- (void) strcpy(probe, temp);
-
- GPTWO_DEBUG1(1, CE_CONT, "gptwo_get_probe_string - Returning %s\n",
- probe);
-
- return (probe);
-}
-
-#ifdef DEBUG
-static void
-debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3,
- uintptr_t a4, uintptr_t a5)
-{
- cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5);
-}
-#endif
diff --git a/usr/src/uts/sun4u/starcat/io/iosram.c b/usr/src/uts/sun4u/starcat/io/iosram.c
deleted file mode 100644
index 3ee1c71165..0000000000
--- a/usr/src/uts/sun4u/starcat/io/iosram.c
+++ /dev/null
@@ -1,3532 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * IOSRAM leaf driver to SBBC nexus driver. This driver is used
- * by Starcat Domain SW to read/write from/to the IO sram.
- */
-
-#include <sys/types.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/obpdefs.h>
-#include <sys/promif.h>
-#include <sys/prom_plat.h>
-#include <sys/cmn_err.h>
-#include <sys/conf.h> /* req. by dev_ops flags MTSAFE etc. */
-#include <sys/modctl.h> /* for modldrv */
-#include <sys/stat.h> /* ddi_create_minor_node S_IFCHR */
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/kstat.h>
-#include <sys/debug.h>
-
-#include <sys/axq.h>
-#include <sys/iosramreg.h>
-#include <sys/iosramio.h>
-#include <sys/iosramvar.h>
-
-
-#if defined(DEBUG)
-int iosram_debug = 0;
-static void iosram_dprintf(const char *fmt, ...);
-#define DPRINTF(level, arg) \
- { if (iosram_debug >= level) iosram_dprintf arg; }
-#else /* !DEBUG */
-#define DPRINTF(level, arg)
-#endif /* !DEBUG */
-
-
-/*
- * IOSRAM module global state
- */
-static void *iosramsoft_statep; /* IOSRAM state pointer */
-static kmutex_t iosram_mutex; /* mutex lock */
-
-static iosram_chunk_t *chunks = NULL; /* array of TOC entries */
-static int nchunks = 0; /* # of TOC entries */
-static iosram_chunk_t *iosram_hashtab[IOSRAM_HASHSZ]; /* key hash table */
-
-static kcondvar_t iosram_tswitch_wait; /* tunnel switch wait cv */
-static int iosram_tswitch_wakeup = 0; /* flag indicationg one or */
- /* more threads waiting on */
- /* iosram_tswitch_wait cv */
-static int iosram_tswitch_active = 0; /* tunnel switch active flag */
-static int iosram_tswitch_aborted = 0; /* tunnel switch abort flag */
-static clock_t iosram_tswitch_tstamp = 0; /* lbolt of last tswitch end */
-static kcondvar_t iosram_rw_wait; /* read/write wait cv */
-static int iosram_rw_wakeup = 0; /* flag indicationg one or */
- /* more threads waiting on */
- /* iosram_rw_wait cv */
-static int iosram_rw_active = 0; /* # threads accessing IOSRAM */
-#if defined(DEBUG)
-static int iosram_rw_active_max = 0;
-#endif
-
-static struct iosramsoft *iosram_new_master = NULL; /* new tunnel target */
-static struct iosramsoft *iosram_master = NULL; /* master tunnel */
-static struct iosramsoft *iosram_instances = NULL; /* list of softstates */
-
-static ddi_acc_handle_t iosram_handle = NULL; /* master IOSRAM map handle */
-
-static void (*iosram_hdrchange_handler)() = NULL;
-
-#if IOSRAM_STATS
-static struct iosram_stat iosram_stats; /* IOSRAM statistics */
-static void iosram_print_stats(); /* forward declaration */
-#endif /* IOSRAM_STATS */
-
-
-#if IOSRAM_LOG
-kmutex_t iosram_log_mutex;
-int iosram_log_level = 1;
-int iosram_log_print = 0; /* print log when recorded */
-uint32_t iosram_logseq;
-iosram_log_t iosram_logbuf[IOSRAM_MAXLOG];
-static void iosram_print_log(int cnt); /* forward declaration */
-#endif /* IOSRAM_LOG */
-
-
-/* driver entry point fn definitions */
-static int iosram_open(dev_t *, int, int, cred_t *);
-static int iosram_close(dev_t, int, int, cred_t *);
-static int iosram_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
-
-/* configuration entry point fn definitions */
-static int iosram_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
-static int iosram_attach(dev_info_t *, ddi_attach_cmd_t);
-static int iosram_detach(dev_info_t *, ddi_detach_cmd_t);
-
-
-/* forward declaractions */
-static iosram_chunk_t *iosram_find_chunk(uint32_t key);
-static void iosram_set_master(struct iosramsoft *softp);
-static int iosram_is_chosen(struct iosramsoft *softp);
-static int iosram_tunnel_capable(struct iosramsoft *softp);
-static int iosram_read_toc(struct iosramsoft *softp);
-static void iosram_init_hashtab(void);
-static void iosram_update_addrs(struct iosramsoft *softp);
-
-static int iosram_setup_map(struct iosramsoft *softp);
-static void iosram_remove_map(struct iosramsoft *softp);
-static int iosram_add_intr(iosramsoft_t *);
-static int iosram_remove_intr(iosramsoft_t *);
-
-static void iosram_add_instance(struct iosramsoft *softp);
-static void iosram_remove_instance(int instance);
-static int iosram_switch_tunnel(iosramsoft_t *softp);
-static void iosram_abort_tswitch();
-
-#if defined(DEBUG)
-/* forward declaractions for debugging */
-static int iosram_get_keys(iosram_toc_entry_t *buf, uint32_t *len);
-static void iosram_print_cback();
-static void iosram_print_state(int);
-static void iosram_print_flags();
-#endif
-
-
-
-/*
- * cb_ops
- */
-static struct cb_ops iosram_cb_ops = {
- iosram_open, /* cb_open */
- iosram_close, /* cb_close */
- nodev, /* cb_strategy */
- nodev, /* cb_print */
- nodev, /* cb_dump */
- nodev, /* cb_read */
- nodev, /* cb_write */
- iosram_ioctl, /* cb_ioctl */
- nodev, /* cb_devmap */
- nodev, /* cb_mmap */
- nodev, /* cb_segmap */
- nochpoll, /* cb_chpoll */
- ddi_prop_op, /* cb_prop_op */
- NULL, /* cb_stream */
- (int)(D_NEW | D_MP | D_HOTPLUG) /* cb_flag */
-};
-
-/*
- * Declare ops vectors for auto configuration.
- */
-struct dev_ops iosram_ops = {
- DEVO_REV, /* devo_rev */
- 0, /* devo_refcnt */
- iosram_getinfo, /* devo_getinfo */
- nulldev, /* devo_identify */
- nulldev, /* devo_probe */
- iosram_attach, /* devo_attach */
- iosram_detach, /* devo_detach */
- nodev, /* devo_reset */
- &iosram_cb_ops, /* devo_cb_ops */
- (struct bus_ops *)NULL, /* devo_bus_ops */
- nulldev, /* devo_power */
- ddi_quiesce_not_supported, /* devo_quiesce */
-};
-
-/*
- * Loadable module support.
- */
-extern struct mod_ops mod_driverops;
-
-static struct modldrv iosrammodldrv = {
- &mod_driverops, /* type of module - driver */
- "IOSRAM Leaf driver",
- &iosram_ops,
-};
-
-static struct modlinkage iosrammodlinkage = {
- MODREV_1,
- &iosrammodldrv,
- NULL
-};
-
-
-int
-_init(void)
-{
- int error;
- int i;
-
- mutex_init(&iosram_mutex, NULL, MUTEX_DRIVER, (void *)NULL);
- cv_init(&iosram_tswitch_wait, NULL, CV_DRIVER, NULL);
- cv_init(&iosram_rw_wait, NULL, CV_DRIVER, NULL);
-#if defined(IOSRAM_LOG)
- mutex_init(&iosram_log_mutex, NULL, MUTEX_DRIVER, (void *)NULL);
-#endif
-
- DPRINTF(1, ("_init:IOSRAM\n"));
-
- for (i = 0; i < IOSRAM_HASHSZ; i++) {
- iosram_hashtab[i] = NULL;
- }
-
- if ((error = ddi_soft_state_init(&iosramsoft_statep,
- sizeof (struct iosramsoft), 1)) != 0) {
- goto failed;
- }
- if ((error = mod_install(&iosrammodlinkage)) != 0) {
- ddi_soft_state_fini(&iosramsoft_statep);
- goto failed;
- }
-
- IOSRAMLOG(0, "_init:IOSRAM ... error:%d statep:%p\n",
- error, iosramsoft_statep, NULL, NULL);
-
- return (error);
-
-failed:
- cv_destroy(&iosram_tswitch_wait);
- cv_destroy(&iosram_rw_wait);
- mutex_destroy(&iosram_mutex);
-#if defined(IOSRAM_LOG)
- mutex_destroy(&iosram_log_mutex);
-#endif
- IOSRAMLOG(0, "_init:IOSRAM ... error:%d statep:%p\n",
- error, iosramsoft_statep, NULL, NULL);
-
- return (error);
-}
-
-
-int
-_fini(void)
-{
-#ifndef DEBUG
- return (EBUSY);
-#else /* !DEBUG */
- int error;
-
- if ((error = mod_remove(&iosrammodlinkage)) == 0) {
- ddi_soft_state_fini(&iosramsoft_statep);
-
- cv_destroy(&iosram_tswitch_wait);
- cv_destroy(&iosram_rw_wait);
- mutex_destroy(&iosram_mutex);
-#if defined(IOSRAM_LOG)
- mutex_destroy(&iosram_log_mutex);
-#endif
- }
- DPRINTF(1, ("_fini:IOSRAM error:%d\n", error));
-
- return (error);
-#endif /* !DEBUG */
-}
-
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&iosrammodlinkage, modinfop));
-}
-
-
-static int
-iosram_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
-{
- int instance;
- int propval;
- int length;
- char name[32];
- struct iosramsoft *softp;
-
- instance = ddi_get_instance(dip);
-
- DPRINTF(1, ("iosram(%d): attach dip:%p\n", instance, (void *)dip));
-
- IOSRAMLOG(1, "ATTACH: dip:%p instance %d ... start\n",
- dip, instance, NULL, NULL);
- switch (cmd) {
- case DDI_ATTACH:
- break;
- case DDI_RESUME:
- if (!(softp = ddi_get_soft_state(iosramsoft_statep,
- instance))) {
- return (DDI_FAILURE);
- }
- mutex_enter(&iosram_mutex);
- mutex_enter(&softp->intr_mutex);
- if (!softp->suspended) {
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- return (DDI_FAILURE);
- }
- softp->suspended = 0;
-
- /*
- * enable SBBC interrupts if SBBC is mapped in
- * restore the value saved during detach
- */
- if (softp->sbbc_region) {
- ddi_put32(softp->sbbc_handle,
- &(softp->sbbc_region->int_enable.reg),
- softp->int_enable_sav);
- }
-
- /*
- * Trigger soft interrupt handler to process any pending
- * interrupts.
- */
- if (softp->intr_pending && !softp->intr_busy &&
- (softp->softintr_id != NULL)) {
- ddi_trigger_softintr(softp->softintr_id);
- }
-
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
-
- return (DDI_SUCCESS);
-
- default:
- return (DDI_FAILURE);
- }
-
- if (ddi_soft_state_zalloc(iosramsoft_statep, instance) != 0) {
- return (DDI_FAILURE);
- }
-
- if ((softp = ddi_get_soft_state(iosramsoft_statep, instance)) == NULL) {
- return (DDI_FAILURE);
- }
- softp->dip = dip;
- softp->instance = instance;
- softp->sbbc_region = NULL;
-
- /*
- * If this instance is not tunnel capable, we don't attach it.
- */
- if (iosram_tunnel_capable(softp) == 0) {
- DPRINTF(1, ("iosram(%d): not tunnel_capable\n", instance));
- IOSRAMLOG(1, "ATTACH(%d): not tunnel_capable\n", instance, NULL,
- NULL, NULL);
- goto attach_fail;
- }
-
- /*
- * Need to create an "interrupt-priorities" property to define the PIL
- * to be used with the interrupt service routine.
- */
- if (ddi_getproplen(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "interrupt-priorities", &length) == DDI_PROP_NOT_FOUND) {
- DPRINTF(1, ("iosram(%d): creating interrupt priority property",
- instance));
- propval = IOSRAM_PIL;
- if (ddi_prop_create(DDI_DEV_T_NONE, dip, 0,
- "interrupt-priorities", (caddr_t)&propval, sizeof (propval))
- != DDI_PROP_SUCCESS) {
- cmn_err(CE_WARN,
- "iosram_attach: failed to create property");
- goto attach_fail;
- }
- }
-
- /*
- * Get interrupts cookies and initialize per-instance mutexes
- */
- if (ddi_get_iblock_cookie(softp->dip, 0, &softp->real_iblk)
- != DDI_SUCCESS) {
- IOSRAMLOG(1, "ATTACH(%d): cannot get soft intr cookie\n",
- instance, NULL, NULL, NULL);
- goto attach_fail;
- }
- mutex_init(&softp->intr_mutex, NULL, MUTEX_DRIVER,
- (void *)softp->real_iblk);
-
- /*
- * Add this instance to the iosram_instances list so that it can be used
- * for tunnel in future.
- */
- mutex_enter(&iosram_mutex);
- softp->state = IOSRAM_STATE_INIT;
- iosram_add_instance(softp);
-
- /*
- * If this is the chosen IOSRAM and there is no master IOSRAM yet, then
- * let's set this instance as the master.
- */
- if (iosram_master == NULL && iosram_is_chosen(softp)) {
- (void) iosram_switch_tunnel(softp);
-
- /*
- * XXX Do we need to panic if unable to setup master IOSRAM?
- */
- if (iosram_master == NULL) {
- cmn_err(CE_WARN,
- "iosram(%d): can't setup master tunnel\n",
- instance);
- softp->state = 0;
- iosram_remove_instance(softp->instance);
- mutex_exit(&iosram_mutex);
- mutex_destroy(&softp->intr_mutex);
- goto attach_fail;
- }
- }
-
- mutex_exit(&iosram_mutex);
-
- /*
- * Create minor node
- */
- (void) sprintf(name, "iosram%d", instance);
- if (ddi_create_minor_node(dip, name, S_IFCHR, instance, NULL, NULL) ==
- DDI_FAILURE) {
- /*
- * Minor node seems to be needed only for debugging purposes.
- * Therefore, there is no need to fail this attach request.
- * Simply print a message out.
- */
- cmn_err(CE_NOTE, "!iosram(%d): can't create minor node\n",
- instance);
- }
- ddi_report_dev(dip);
-
- DPRINTF(1, ("iosram_attach(%d): success.\n", instance));
- IOSRAMLOG(1, "ATTACH: dip:%p instance:%d ... success softp:%p\n",
- dip, instance, softp, NULL);
-
- return (DDI_SUCCESS);
-
-attach_fail:
- DPRINTF(1, ("iosram_attach(%d):failed.\n", instance));
- IOSRAMLOG(1, "ATTACH: dip:%p instance:%d ... failed.\n",
- dip, instance, NULL, NULL);
-
- ddi_soft_state_free(iosramsoft_statep, instance);
- return (DDI_FAILURE);
-}
-
-
-static int
-iosram_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
-{
- int instance;
- struct iosramsoft *softp;
-
- instance = ddi_get_instance(dip);
- if (!(softp = ddi_get_soft_state(iosramsoft_statep, instance))) {
- return (DDI_FAILURE);
- }
-
- IOSRAMLOG(1, "DETACH: dip:%p instance %d softp:%p\n",
- dip, instance, softp, NULL);
-
- switch (cmd) {
- case DDI_DETACH:
- break;
- case DDI_SUSPEND:
- mutex_enter(&iosram_mutex);
- mutex_enter(&softp->intr_mutex);
- if (softp->suspended) {
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- return (DDI_FAILURE);
- }
- softp->suspended = 1;
- /*
- * Disable SBBC interrupts if SBBC is mapped in
- */
- if (softp->sbbc_region) {
- /* save current interrupt enable register */
- softp->int_enable_sav = ddi_get32(softp->sbbc_handle,
- &(softp->sbbc_region->int_enable.reg));
- ddi_put32(softp->sbbc_handle,
- &(softp->sbbc_region->int_enable.reg), 0x0);
- }
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- return (DDI_SUCCESS);
-
- default:
- return (DDI_FAILURE);
- }
-
-
- /*
- * Indicate that this instance is being detached so that this instance
- * does not become a target for tunnel switch in future.
- */
- mutex_enter(&iosram_mutex);
- softp->state |= IOSRAM_STATE_DETACH;
-
- /*
- * If this instance is currently the master or the target of the tunnel
- * switch, then we need to wait and switch tunnel, if necessary.
- */
- if (iosram_master == softp || (softp->state & IOSRAM_STATE_TSWITCH)) {
- mutex_exit(&iosram_mutex);
- (void) iosram_switchfrom(instance);
- mutex_enter(&iosram_mutex);
- }
-
- /*
- * If the tunnel switch is in progress and we are the master or target
- * of tunnel relocation, then we can't detach this instance right now.
- */
- if (softp->state & IOSRAM_STATE_TSWITCH) {
- softp->state &= ~IOSRAM_STATE_DETACH;
- mutex_exit(&iosram_mutex);
- return (DDI_FAILURE);
- }
-
- /*
- * We can't allow master IOSRAM to be detached as we won't be able to
- * communicate otherwise.
- */
- if (iosram_master == softp) {
- softp->state &= ~IOSRAM_STATE_DETACH;
- mutex_exit(&iosram_mutex);
- return (DDI_FAILURE);
- }
-
- /*
- * Now remove our instance from the iosram_instances list.
- */
- iosram_remove_instance(instance);
- mutex_exit(&iosram_mutex);
-
- /*
- * Instances should only ever be mapped if they are the master and/or
- * participating in a tunnel switch. Neither should be the case here.
- */
- ASSERT((softp->state & IOSRAM_STATE_MAPPED) == 0);
-
- /*
- * Destroy per-instance mutexes
- */
- mutex_destroy(&softp->intr_mutex);
-
- ddi_remove_minor_node(dip, NULL);
-
- /*
- * Finally remove our soft state structure
- */
- ddi_soft_state_free(iosramsoft_statep, instance);
-
- return (DDI_SUCCESS);
-}
-
-
-/* ARGSUSED0 */
-static int
-iosram_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
- void **result)
-{
- dev_t dev = (dev_t)arg;
- struct iosramsoft *softp;
- int instance, ret;
-
- instance = getminor(dev);
-
- IOSRAMLOG(2, "GETINFO: dip:%x instance %d dev:%x infocmd:%x\n",
- dip, instance, dev, infocmd);
-
- switch (infocmd) {
- case DDI_INFO_DEVT2DEVINFO:
- softp = ddi_get_soft_state(iosramsoft_statep, instance);
- if (softp == NULL) {
- *result = NULL;
- ret = DDI_FAILURE;
- } else {
- *result = softp->dip;
- ret = DDI_SUCCESS;
- }
- break;
- case DDI_INFO_DEVT2INSTANCE:
- *result = (void *)(uintptr_t)instance;
- ret = DDI_SUCCESS;
- break;
- default:
- ret = DDI_FAILURE;
- break;
- }
-
- return (ret);
-}
-
-
-/*ARGSUSED1*/
-static int
-iosram_open(dev_t *dev, int flag, int otype, cred_t *credp)
-{
- struct iosramsoft *softp;
- int instance;
-
- instance = getminor(*dev);
- softp = ddi_get_soft_state(iosramsoft_statep, instance);
-
- if (softp == NULL) {
- return (ENXIO);
- }
-
- IOSRAMLOG(1, "OPEN: dev:%p otype:%x ... instance:%d softp:%p\n",
- *dev, otype, softp->instance, softp);
-
- return (0);
-}
-
-
-/*ARGSUSED1*/
-static int
-iosram_close(dev_t dev, int flag, int otype, cred_t *credp)
-{
- struct iosramsoft *softp;
- int instance;
-
- instance = getminor(dev);
- softp = ddi_get_soft_state(iosramsoft_statep, instance);
- if (softp == NULL) {
- return (ENXIO);
- }
-
- IOSRAMLOG(1, "CLOSE: dev:%p otype:%x ... instance:%d softp:%p\n",
- dev, otype, softp->instance, softp);
-
- return (0);
-}
-
-
-int
-iosram_rd(uint32_t key, uint32_t off, uint32_t len, caddr_t dptr)
-{
- iosram_chunk_t *chunkp;
- uint32_t chunk_len;
- uint8_t *iosramp;
- ddi_acc_handle_t handle;
- int boff;
- union {
- uchar_t cbuf[UINT32SZ];
- uint32_t data;
- } word;
-
- int error = 0;
- uint8_t *buf = (uint8_t *)dptr;
-
- /*
- * We try to read from the IOSRAM using double word or word access
- * provided both "off" and "buf" are (or can be) double word or word
- * aligned. Othewise, we try to align the "off" to a word boundary and
- * then try to read data from the IOSRAM using word access, but store it
- * into buf buffer using byte access.
- *
- * If the leading/trailing portion of the IOSRAM data is not word
- * aligned, it will always be copied using byte access.
- */
- IOSRAMLOG(1, "RD: key: 0x%x off:%x len:%x buf:%p\n",
- key, off, len, buf);
-
- /*
- * Acquire lock and look for the requested chunk. If it exists, make
- * sure the requested read is within the chunk's bounds and no tunnel
- * switch is active.
- */
- mutex_enter(&iosram_mutex);
- chunkp = iosram_find_chunk(key);
- chunk_len = (chunkp != NULL) ? chunkp->toc_data.len : 0;
-
- if (iosram_master == NULL) {
- error = EIO;
- } else if (chunkp == NULL) {
- error = EINVAL;
- } else if ((off >= chunk_len) || (len > chunk_len) ||
- ((off + len) > chunk_len)) {
- error = EMSGSIZE;
- } else if (iosram_tswitch_active) {
- error = EAGAIN;
- }
-
- if (error) {
- mutex_exit(&iosram_mutex);
- return (error);
- }
-
- /*
- * Bump reference count to indicate #thread accessing IOSRAM and release
- * the lock.
- */
- iosram_rw_active++;
-#if defined(DEBUG)
- if (iosram_rw_active > iosram_rw_active_max) {
- iosram_rw_active_max = iosram_rw_active;
- }
-#endif
- mutex_exit(&iosram_mutex);
-
- IOSRAM_STAT(read);
- IOSRAM_STAT_ADD(bread, len);
-
- /* Get starting address and map handle */
- iosramp = chunkp->basep + off;
- handle = iosram_handle;
-
- /*
- * Align the off to word boundary and then try reading/writing data
- * using double word or word access.
- */
- if ((boff = ((uintptr_t)iosramp & (UINT32SZ - 1))) != 0) {
- int cnt = UINT32SZ - boff;
-
- if (cnt > len) {
- cnt = len;
- }
- IOSRAMLOG(2,
- "RD: align rep_get8(buf:%p sramp:%p cnt:%x) len:%x\n",
- buf, iosramp, cnt, len);
- ddi_rep_get8(handle, buf, iosramp, cnt, DDI_DEV_AUTOINCR);
- buf += cnt;
- iosramp += cnt;
- len -= cnt;
- }
-
- if ((len >= UINT64SZ) &&
- ((((uintptr_t)iosramp | (uintptr_t)buf) & (UINT64SZ - 1)) == 0)) {
- /*
- * Both source and destination are double word aligned
- */
- int cnt = len/UINT64SZ;
-
- IOSRAMLOG(2,
- "RD: rep_get64(buf:%p sramp:%p cnt:%x) len:%x\n",
- buf, iosramp, cnt, len);
- ddi_rep_get64(handle, (uint64_t *)buf, (uint64_t *)iosramp,
- cnt, DDI_DEV_AUTOINCR);
- iosramp += cnt * UINT64SZ;
- buf += cnt * UINT64SZ;
- len -= cnt * UINT64SZ;
-
- /*
- * read remaining data using word and byte access
- */
- if (len >= UINT32SZ) {
- IOSRAMLOG(2,
- "RD: get32(buf:%p sramp:%p) len:%x\n",
- buf, iosramp, len, NULL);
- *(uint32_t *)buf = ddi_get32(handle,
- (uint32_t *)iosramp);
- iosramp += UINT32SZ;
- buf += UINT32SZ;
- len -= UINT32SZ;
- }
-
- if (len != 0) {
- ddi_rep_get8(handle, buf, iosramp, len,
- DDI_DEV_AUTOINCR);
- }
- } else if ((len >= UINT32SZ) &&
- ((((uintptr_t)iosramp | (uintptr_t)buf) & (UINT32SZ - 1)) == 0)) {
- /*
- * Both source and destination are word aligned
- */
- int cnt = len/UINT32SZ;
-
- IOSRAMLOG(2,
- "RD: rep_get32(buf:%p sramp:%p cnt:%x) len:%x\n",
- buf, iosramp, cnt, len);
- ddi_rep_get32(handle, (uint32_t *)buf, (uint32_t *)iosramp,
- cnt, DDI_DEV_AUTOINCR);
- iosramp += cnt * UINT32SZ;
- buf += cnt * UINT32SZ;
- len -= cnt * UINT32SZ;
-
- /*
- * copy the remainder using byte access
- */
- if (len != 0) {
- ddi_rep_get8(handle, buf, iosramp, len,
- DDI_DEV_AUTOINCR);
- }
- } else if (len != 0) {
- /*
- * We know that the "off" (i.e. iosramp) is at least word
- * aligned. We need to read IOSRAM word at a time and copy it
- * byte at a time.
- */
- ASSERT(((uintptr_t)iosramp & (UINT32SZ - 1)) == 0);
-
- IOSRAMLOG(2,
- "RD: unaligned get32(buf:%p sramp:%p) len:%x\n",
- buf, iosramp, len, NULL);
- for (; len >= UINT32SZ; len -= UINT32SZ, iosramp += UINT32SZ) {
- word.data = ddi_get32(handle, (uint32_t *)iosramp);
- *buf++ = word.cbuf[0];
- *buf++ = word.cbuf[1];
- *buf++ = word.cbuf[2];
- *buf++ = word.cbuf[3];
- }
-
- /*
- * copy the remaining data using byte access
- */
- if (len != 0) {
- ddi_rep_get8(handle, buf, iosramp, len,
- DDI_DEV_AUTOINCR);
- }
- }
-
- /*
- * Reacquire mutex lock, decrement refcnt and if refcnt is 0 and any
- * threads are waiting for r/w activity to complete, wake them up.
- */
- mutex_enter(&iosram_mutex);
- ASSERT(iosram_rw_active > 0);
-
- if ((--iosram_rw_active == 0) && iosram_rw_wakeup) {
- iosram_rw_wakeup = 0;
- cv_broadcast(&iosram_rw_wait);
- }
- mutex_exit(&iosram_mutex);
-
- return (error);
-}
-
-
-/*
- * _iosram_write(key, off, len, dptr, force)
- * Internal common routine to write to the IOSRAM.
- */
-static int
-_iosram_write(uint32_t key, uint32_t off, uint32_t len, caddr_t dptr, int force)
-{
- iosram_chunk_t *chunkp;
- uint32_t chunk_len;
- uint8_t *iosramp;
- ddi_acc_handle_t handle;
- int boff;
- union {
- uint8_t cbuf[UINT32SZ];
- uint32_t data;
- } word;
-
- int error = 0;
- uint8_t *buf = (uint8_t *)dptr;
-
- /*
- * We try to write to the IOSRAM using double word or word access
- * provided both "off" and "buf" are (or can be) double word or word
- * aligned. Othewise, we try to align the "off" to a word boundary and
- * then try to write data to the IOSRAM using word access, but read data
- * from the buf buffer using byte access.
- *
- * If the leading/trailing portion of the IOSRAM data is not word
- * aligned, it will always be written using byte access.
- */
- IOSRAMLOG(1, "WR: key: 0x%x off:%x len:%x buf:%p\n",
- key, off, len, buf);
-
- /*
- * Acquire lock and look for the requested chunk. If it exists, make
- * sure the requested write is within the chunk's bounds and no tunnel
- * switch is active.
- */
- mutex_enter(&iosram_mutex);
- chunkp = iosram_find_chunk(key);
- chunk_len = (chunkp != NULL) ? chunkp->toc_data.len : 0;
-
- if (iosram_master == NULL) {
- error = EIO;
- } else if (chunkp == NULL) {
- error = EINVAL;
- } else if ((off >= chunk_len) || (len > chunk_len) ||
- ((off+len) > chunk_len)) {
- error = EMSGSIZE;
- } else if (iosram_tswitch_active && !force) {
- error = EAGAIN;
- }
-
- if (error) {
- mutex_exit(&iosram_mutex);
- return (error);
- }
-
- /*
- * If this is a forced write and there's a tunnel switch in progress,
- * abort the switch.
- */
- if (iosram_tswitch_active && force) {
- cmn_err(CE_NOTE, "!iosram: Aborting tswitch on force_write");
- iosram_abort_tswitch();
- }
-
- /*
- * Bump reference count to indicate #thread accessing IOSRAM
- * and release the lock.
- */
- iosram_rw_active++;
-#if defined(DEBUG)
- if (iosram_rw_active > iosram_rw_active_max) {
- iosram_rw_active_max = iosram_rw_active;
- }
-#endif
- mutex_exit(&iosram_mutex);
-
-
- IOSRAM_STAT(write);
- IOSRAM_STAT_ADD(bwrite, len);
-
- /* Get starting address and map handle */
- iosramp = chunkp->basep + off;
- handle = iosram_handle;
-
- /*
- * Align the off to word boundary and then try reading/writing
- * data using double word or word access.
- */
- if ((boff = ((uintptr_t)iosramp & (UINT32SZ - 1))) != 0) {
- int cnt = UINT32SZ - boff;
-
- if (cnt > len) {
- cnt = len;
- }
- IOSRAMLOG(2,
- "WR: align rep_put8(buf:%p sramp:%p cnt:%x) len:%x\n",
- buf, iosramp, cnt, len);
- ddi_rep_put8(handle, buf, iosramp, cnt, DDI_DEV_AUTOINCR);
- buf += cnt;
- iosramp += cnt;
- len -= cnt;
- }
-
- if ((len >= UINT64SZ) &&
- ((((uintptr_t)iosramp | (uintptr_t)buf) & (UINT64SZ - 1)) == 0)) {
- /*
- * Both source and destination are double word aligned
- */
- int cnt = len/UINT64SZ;
-
- IOSRAMLOG(2,
- "WR: rep_put64(buf:%p sramp:%p cnt:%x) len:%x\n",
- buf, iosramp, cnt, len);
- ddi_rep_put64(handle, (uint64_t *)buf, (uint64_t *)iosramp,
- cnt, DDI_DEV_AUTOINCR);
- iosramp += cnt * UINT64SZ;
- buf += cnt * UINT64SZ;
- len -= cnt * UINT64SZ;
-
- /*
- * Copy the remaining data using word & byte access
- */
- if (len >= UINT32SZ) {
- IOSRAMLOG(2,
- "WR: put32(buf:%p sramp:%p) len:%x\n", buf, iosramp,
- len, NULL);
- ddi_put32(handle, (uint32_t *)iosramp,
- *(uint32_t *)buf);
- iosramp += UINT32SZ;
- buf += UINT32SZ;
- len -= UINT32SZ;
- }
-
- if (len != 0) {
- ddi_rep_put8(handle, buf, iosramp, len,
- DDI_DEV_AUTOINCR);
- }
- } else if ((len >= UINT32SZ) &&
- ((((uintptr_t)iosramp | (uintptr_t)buf) & (UINT32SZ - 1)) == 0)) {
- /*
- * Both source and destination are word aligned
- */
- int cnt = len/UINT32SZ;
-
- IOSRAMLOG(2,
- "WR: rep_put32(buf:%p sramp:%p cnt:%x) len:%x\n",
- buf, iosramp, cnt, len);
- ddi_rep_put32(handle, (uint32_t *)buf, (uint32_t *)iosramp,
- cnt, DDI_DEV_AUTOINCR);
- iosramp += cnt * UINT32SZ;
- buf += cnt * UINT32SZ;
- len -= cnt * UINT32SZ;
-
- /*
- * copy the remainder using byte access
- */
- if (len != 0) {
- ddi_rep_put8(handle, buf, iosramp, len,
- DDI_DEV_AUTOINCR);
- }
- } else if (len != 0) {
- /*
- * We know that the "off" is at least word aligned. We
- * need to read data from buf buffer byte at a time, and
- * write it to the IOSRAM word at a time.
- */
-
- ASSERT(((uintptr_t)iosramp & (UINT32SZ - 1)) == 0);
-
- IOSRAMLOG(2,
- "WR: unaligned put32(buf:%p sramp:%p) len:%x\n",
- buf, iosramp, len, NULL);
- for (; len >= UINT32SZ; len -= UINT32SZ, iosramp += UINT32SZ) {
- word.cbuf[0] = *buf++;
- word.cbuf[1] = *buf++;
- word.cbuf[2] = *buf++;
- word.cbuf[3] = *buf++;
- ddi_put32(handle, (uint32_t *)iosramp, word.data);
- }
-
- /*
- * copy the remaining data using byte access
- */
- if (len != 0) {
- ddi_rep_put8(handle, buf, iosramp,
- len, DDI_DEV_AUTOINCR);
- }
- }
-
- /*
- * Reacquire mutex lock, decrement refcnt and if refcnt is 0 and
- * any threads are waiting for r/w activity to complete, wake them up.
- */
- mutex_enter(&iosram_mutex);
- ASSERT(iosram_rw_active > 0);
-
- if ((--iosram_rw_active == 0) && iosram_rw_wakeup) {
- iosram_rw_wakeup = 0;
- cv_broadcast(&iosram_rw_wait);
- }
- mutex_exit(&iosram_mutex);
-
- return (error);
-}
-
-
-int
-iosram_force_write(uint32_t key, uint32_t off, uint32_t len, caddr_t dptr)
-{
- return (_iosram_write(key, off, len, dptr, 1 /* force */));
-}
-
-
-int
-iosram_wr(uint32_t key, uint32_t off, uint32_t len, caddr_t dptr)
-{
- return (_iosram_write(key, off, len, dptr, 0));
-}
-
-
-/*
- * iosram_register(key, handler, arg)
- * Register a handler and an arg for the specified chunk. This handler
- * will be invoked when an interrupt is received from the other side and
- * the int_pending flag for the corresponding key is marked
- * IOSRAM_INT_TO_DOM.
- */
-/* ARGSUSED */
-int
-iosram_register(uint32_t key, void (*handler)(), void *arg)
-{
- struct iosram_chunk *chunkp;
- int error = 0;
-
- /*
- * Acquire lock and look for the requested chunk. If it exists, and no
- * other callback is registered, proceed with the registration.
- */
- mutex_enter(&iosram_mutex);
- chunkp = iosram_find_chunk(key);
-
- if (iosram_master == NULL) {
- error = EIO;
- } else if (chunkp == NULL) {
- error = EINVAL;
- } else if (chunkp->cback.handler != NULL) {
- error = EBUSY;
- } else {
- chunkp->cback.busy = 0;
- chunkp->cback.unregister = 0;
- chunkp->cback.handler = handler;
- chunkp->cback.arg = arg;
- }
- mutex_exit(&iosram_mutex);
-
- IOSRAMLOG(1, "REG: key: 0x%x hdlr:%p arg:%p error:%d\n",
- key, handler, arg, error);
-
- return (error);
-}
-
-
-/*
- * iosram_unregister()
- * Unregister handler associated with the specified chunk.
- */
-int
-iosram_unregister(uint32_t key)
-{
- struct iosram_chunk *chunkp;
- int error = 0;
-
- /*
- * Acquire lock and look for the requested chunk. If it exists and has
- * a callback registered, unregister it.
- */
- mutex_enter(&iosram_mutex);
- chunkp = iosram_find_chunk(key);
-
- if (iosram_master == NULL) {
- error = EIO;
- } else if (chunkp == NULL) {
- error = EINVAL;
- } else if (chunkp->cback.busy) {
- /*
- * If the handler is already busy (being invoked), then we flag
- * it so it will be unregistered after the invocation completes.
- */
- DPRINTF(1, ("IOSRAM(%d): unregister: delaying unreg k:0x%08x\n",
- iosram_master->instance, key));
- chunkp->cback.unregister = 1;
- } else if (chunkp->cback.handler != NULL) {
- chunkp->cback.handler = NULL;
- chunkp->cback.arg = NULL;
- }
- mutex_exit(&iosram_mutex);
-
- IOSRAMLOG(1, "UNREG: key:%x error:%d\n", key, error, NULL, NULL);
- return (error);
-}
-
-
-/*
- * iosram_get_flag():
- * Get data_valid and/or int_pending flags associated with the
- * specified key.
- */
-int
-iosram_get_flag(uint32_t key, uint8_t *data_valid, uint8_t *int_pending)
-{
- iosram_chunk_t *chunkp;
- iosram_flags_t flags;
- int error = 0;
-
- /*
- * Acquire lock and look for the requested chunk. If it exists, and no
- * tunnel switch is in progress, read the chunk's flags.
- */
- mutex_enter(&iosram_mutex);
- chunkp = iosram_find_chunk(key);
-
- if (iosram_master == NULL) {
- error = EIO;
- } else if (chunkp == NULL) {
- error = EINVAL;
- } else if (iosram_tswitch_active) {
- error = EAGAIN;
- } else {
- IOSRAM_STAT(getflag);
-
- /*
- * Read the flags
- */
- ddi_rep_get8(iosram_handle, (uint8_t *)&flags,
- (uint8_t *)(chunkp->flagsp), sizeof (iosram_flags_t),
- DDI_DEV_AUTOINCR);
-
- /*
- * Get each flag value that the caller is interested in.
- */
- if (data_valid != NULL) {
- *data_valid = flags.data_valid;
- }
-
- if (int_pending != NULL) {
- *int_pending = flags.int_pending;
- }
- }
- mutex_exit(&iosram_mutex);
-
- IOSRAMLOG(1, "GetFlag key:%x data_valid:%x int_pending:%x error:%d\n",
- key, flags.data_valid, flags.int_pending, error);
- return (error);
-}
-
-
-/*
- * iosram_set_flag():
- * Set data_valid and int_pending flags associated with the specified key.
- */
-int
-iosram_set_flag(uint32_t key, uint8_t data_valid, uint8_t int_pending)
-{
- iosram_chunk_t *chunkp;
- iosram_flags_t flags;
- int error = 0;
-
- /*
- * Acquire lock and look for the requested chunk. If it exists, and no
- * tunnel switch is in progress, write the chunk's flags.
- */
- mutex_enter(&iosram_mutex);
- chunkp = iosram_find_chunk(key);
-
- if (iosram_master == NULL) {
- error = EIO;
- } else if ((chunkp == NULL) ||
- ((data_valid != IOSRAM_DATA_INVALID) &&
- (data_valid != IOSRAM_DATA_VALID)) ||
- ((int_pending != IOSRAM_INT_NONE) &&
- (int_pending != IOSRAM_INT_TO_SSC) &&
- (int_pending != IOSRAM_INT_TO_DOM))) {
- error = EINVAL;
- } else if (iosram_tswitch_active) {
- error = EAGAIN;
- } else {
- IOSRAM_STAT(setflag);
- flags.data_valid = data_valid;
- flags.int_pending = int_pending;
- ddi_rep_put8(iosram_handle, (uint8_t *)&flags,
- (uint8_t *)(chunkp->flagsp), sizeof (iosram_flags_t),
- DDI_DEV_AUTOINCR);
- }
- mutex_exit(&iosram_mutex);
-
- IOSRAMLOG(1, "SetFlag key:%x data_valid:%x int_pending:%x error:%d\n",
- key, flags.data_valid, flags.int_pending, error);
- return (error);
-}
-
-
-/*
- * iosram_ctrl()
- * This function provides access to a variety of services not available
- * through the basic API.
- */
-int
-iosram_ctrl(uint32_t key, uint32_t cmd, void *arg)
-{
- struct iosram_chunk *chunkp;
- int error = 0;
-
- /*
- * Acquire lock and do some argument sanity checking.
- */
- mutex_enter(&iosram_mutex);
- chunkp = iosram_find_chunk(key);
-
- if (iosram_master == NULL) {
- error = EIO;
- } else if (chunkp == NULL) {
- error = EINVAL;
- }
-
- if (error != 0) {
- mutex_exit(&iosram_mutex);
- return (error);
- }
-
- /*
- * Arguments seem okay so far, so process the command.
- */
- switch (cmd) {
- case IOSRAM_CMD_CHUNKLEN:
- /*
- * Return the length of the chunk indicated by the key.
- */
- if (arg == NULL) {
- error = EINVAL;
- break;
- }
-
- *(uint32_t *)arg = chunkp->toc_data.len;
- break;
-
- default:
- error = ENOTSUP;
- break;
- }
-
- mutex_exit(&iosram_mutex);
- return (error);
-}
-
-
-/*
- * iosram_hdr_ctrl()
- * This function provides an interface for the Mailbox Protocol
- * implementation to use when interacting with the IOSRAM header.
- */
-int
-iosram_hdr_ctrl(uint32_t cmd, void *arg)
-{
- int error = 0;
-
- /*
- * Acquire lock and do some argument sanity checking.
- */
- mutex_enter(&iosram_mutex);
-
- if (iosram_master == NULL) {
- error = EIO;
- }
-
- if (error != 0) {
- mutex_exit(&iosram_mutex);
- return (error);
- }
-
- switch (cmd) {
- case IOSRAM_HDRCMD_GET_SMS_MBOX_VER:
- /*
- * Return the value of the sms_mbox_version field.
- */
- if (arg == NULL) {
- error = EINVAL;
- break;
- }
-
- *(uint32_t *)arg = IOSRAM_GET_HDRFIELD32(iosram_master,
- sms_mbox_version);
- break;
-
- case IOSRAM_HDRCMD_SET_OS_MBOX_VER:
- /*
- * Set the value of the os_mbox_version field.
- */
- IOSRAM_SET_HDRFIELD32(iosram_master, os_mbox_version,
- (uint32_t)(uintptr_t)arg);
- IOSRAM_SET_HDRFIELD32(iosram_master, os_change_mask,
- IOSRAM_HDRFIELD_OS_MBOX_VER);
- (void) iosram_send_intr();
- break;
-
- case IOSRAM_HDRCMD_REG_CALLBACK:
- iosram_hdrchange_handler = (void (*)())arg;
- break;
-
- default:
- error = ENOTSUP;
- break;
- }
-
- mutex_exit(&iosram_mutex);
- return (error);
-}
-
-
-/*
- * iosram_softintr()
- * IOSRAM soft interrupt handler
- */
-static uint_t
-iosram_softintr(caddr_t arg)
-{
- uint32_t hdr_changes;
- iosramsoft_t *softp = (iosramsoft_t *)arg;
- iosram_chunk_t *chunkp;
- void (*handler)();
- int i;
- uint8_t flag;
-
- DPRINTF(1, ("iosram(%d): in iosram_softintr\n", softp->instance));
-
- IOSRAMLOG(2, "SINTR arg/softp:%p pending:%d busy:%d\n",
- arg, softp->intr_pending, softp->intr_busy, NULL);
-
- mutex_enter(&iosram_mutex);
- mutex_enter(&softp->intr_mutex);
-
- /*
- * Do not process interrupt if interrupt handler is already running or
- * no interrupts are pending.
- */
- if (softp->intr_busy || !softp->intr_pending) {
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- DPRINTF(1, ("IOSRAM(%d): softintr: busy=%d pending=%d\n",
- softp->instance, softp->intr_busy, softp->intr_pending));
- return (softp->intr_pending ? DDI_INTR_CLAIMED :
- DDI_INTR_UNCLAIMED);
- }
-
- /*
- * It's possible for the SC to send an interrupt on the new master
- * before we are able to set our internal state. If so, we'll retrigger
- * soft interrupt right after tunnel switch completion.
- */
- if (softp->state & IOSRAM_STATE_TSWITCH) {
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- DPRINTF(1, ("IOSRAM(%d): softintr: doing switch "
- "state=0x%x\n", softp->instance, softp->state));
- return (DDI_INTR_CLAIMED);
- }
-
- /*
- * Do not process interrupt if we are not the master.
- */
- if (!(softp->state & IOSRAM_STATE_MASTER)) {
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- DPRINTF(1, ("IOSRAM(%d): softintr: no master state=0x%x\n ",
- softp->instance, softp->state));
- return (DDI_INTR_CLAIMED);
- }
-
- IOSRAM_STAT(sintr_recv);
-
- /*
- * If the driver is suspended, then we should not process any
- * interrupts. Instead, we trigger a soft interrupt when the driver
- * resumes.
- */
- if (softp->suspended) {
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- DPRINTF(1, ("IOSRAM(%d): softintr: suspended\n",
- softp->instance));
- return (DDI_INTR_CLAIMED);
- }
-
- /*
- * Indicate that the IOSRAM interrupt handler is busy. Note that this
- * includes incrementing the reader/writer count, since we don't want
- * any tunnel switches to start up while we're processing callbacks.
- */
- softp->intr_busy = 1;
- iosram_rw_active++;
-#if defined(DEBUG)
- if (iosram_rw_active > iosram_rw_active_max) {
- iosram_rw_active_max = iosram_rw_active;
- }
-#endif
-
- do {
- DPRINTF(1, ("IOSRAM(%d): softintr: processing interrupt\n",
- softp->instance));
-
- softp->intr_pending = 0;
-
- mutex_exit(&softp->intr_mutex);
-
- /*
- * Process changes to the IOSRAM header.
- */
- hdr_changes = IOSRAM_GET_HDRFIELD32(iosram_master,
- sms_change_mask);
- if (hdr_changes != 0) {
- int error;
-
- IOSRAM_SET_HDRFIELD32(iosram_master, sms_change_mask,
- 0);
- if (hdr_changes & IOSRAM_HDRFIELD_TOC_INDEX) {
- /*
- * XXX is it safe to temporarily release the
- * iosram_mutex here?
- */
- mutex_exit(&iosram_mutex);
- error = iosram_read_toc(iosram_master);
- mutex_enter(&iosram_mutex);
- if (error) {
- cmn_err(CE_WARN, "iosram_read_toc: new"
- " TOC invalid; using old TOC.");
- }
- iosram_update_addrs(iosram_master);
- }
-
- if (iosram_hdrchange_handler != NULL) {
- mutex_exit(&iosram_mutex);
- iosram_hdrchange_handler();
- mutex_enter(&iosram_mutex);
- }
- }
-
- /*
- * Get data_valid/int_pending flags and generate a callback if
- * applicable. For now, we read only those flags for which a
- * callback has been registered. We can optimize reading of
- * flags by reading them all at once and then process them
- * later.
- */
- for (i = 0, chunkp = chunks; i < nchunks; i++,
- chunkp++) {
-#if DEBUG
- flag = ddi_get8(iosram_handle,
- &(chunkp->flagsp->int_pending));
- DPRINTF(1, ("IOSRAM(%d): softintr chunk #%d "
- "flag=0x%x handler=%p\n",
- softp->instance, i, (int)flag,
- (void *)chunkp->cback.handler));
-#endif
- if ((handler = chunkp->cback.handler) == NULL) {
- continue;
- }
- flag = ddi_get8(iosram_handle,
- &(chunkp->flagsp->int_pending));
- if (flag == IOSRAM_INT_TO_DOM) {
- DPRINTF(1,
- ("IOSRAM(%d): softintr: invoking handler\n",
- softp->instance));
- IOSRAMLOG(1,
- "SINTR invoking hdlr:%p arg:%p index:%d\n",
- handler, chunkp->cback.arg, i, NULL);
- IOSRAM_STAT(callbacks);
-
- ddi_put8(iosram_handle,
- &(chunkp->flagsp->int_pending),
- IOSRAM_INT_NONE);
- chunkp->cback.busy = 1;
- mutex_exit(&iosram_mutex);
- (*handler)(chunkp->cback.arg);
- mutex_enter(&iosram_mutex);
- chunkp->cback.busy = 0;
-
- /*
- * If iosram_unregister was called while the
- * callback was being invoked, complete the
- * unregistration here.
- */
- if (chunkp->cback.unregister) {
- DPRINTF(1, ("IOSRAM(%d): softintr: "
- "delayed unreg k:0x%08x\n",
- softp->instance,
- chunkp->toc_data.key));
- chunkp->cback.handler = NULL;
- chunkp->cback.arg = NULL;
- chunkp->cback.unregister = 0;
- }
- }
-
- /*
- * If there's a tunnel switch waiting to run, give it
- * higher priority than these callbacks by bailing out.
- * They'll still be invoked on the new master iosram
- * when the tunnel switch is done.
- */
- if (iosram_tswitch_active) {
- break;
- }
- }
-
- mutex_enter(&softp->intr_mutex);
-
- } while (softp->intr_pending && !softp->suspended &&
- !iosram_tswitch_active);
-
- /*
- * Indicate IOSRAM interrupt handler is not BUSY any more
- */
- softp->intr_busy = 0;
-
- ASSERT(iosram_rw_active > 0);
- if ((--iosram_rw_active == 0) && iosram_rw_wakeup) {
- iosram_rw_wakeup = 0;
- cv_broadcast(&iosram_rw_wait);
- }
-
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
-
- DPRINTF(1, ("iosram(%d): softintr exit\n", softp->instance));
-
- return (DDI_INTR_CLAIMED);
-}
-
-
-/*
- * iosram_intr()
- * IOSRAM real interrupt handler
- */
-static uint_t
-iosram_intr(caddr_t arg)
-{
- iosramsoft_t *softp = (iosramsoft_t *)arg;
- int result = DDI_INTR_UNCLAIMED;
- uint32_t int_status;
-
- DPRINTF(2, ("iosram(%d): in iosram_intr\n", softp->instance));
-
- mutex_enter(&softp->intr_mutex);
-
- if (softp->sbbc_handle == NULL) {
- /*
- * The SBBC registers region is not mapped in.
- * Set the interrupt pending flag here, and process the
- * interrupt after the tunnel switch.
- */
- DPRINTF(1, ("IOSRAM(%d): iosram_intr: SBBC not mapped\n",
- softp->instance));
- softp->intr_pending = 1;
- mutex_exit(&softp->intr_mutex);
- return (DDI_INTR_UNCLAIMED);
- }
-
- int_status = ddi_get32(softp->sbbc_handle,
- &(softp->sbbc_region->int_status.reg));
- DPRINTF(1, ("iosram_intr: int_status = 0x%08x\n", int_status));
-
- if (int_status & IOSRAM_SBBC_INT0) {
- result = DDI_INTR_CLAIMED;
- DPRINTF(1, ("iosram_intr: int0 detected!\n"));
- }
-
- if (int_status & IOSRAM_SBBC_INT1) {
- result = DDI_INTR_CLAIMED;
- DPRINTF(1, ("iosram_intr: int1 detected!\n"));
- }
-
- if (result == DDI_INTR_CLAIMED) {
- ddi_put32(softp->sbbc_handle,
- &(softp->sbbc_region->int_status.reg), int_status);
- int_status = ddi_get32(softp->sbbc_handle,
- &(softp->sbbc_region->int_status.reg));
- DPRINTF(1, ("iosram_intr: int_status = 0x%08x\n",
- int_status));
-
- softp->intr_pending = 1;
- /*
- * Trigger soft interrupt if not executing and
- * not suspended.
- */
- if (!softp->intr_busy && !softp->suspended &&
- (softp->softintr_id != NULL)) {
- DPRINTF(1, ("iosram(%d): trigger softint\n",
- softp->instance));
- ddi_trigger_softintr(softp->softintr_id);
- }
- }
-
- IOSRAM_STAT(intr_recv);
-
- mutex_exit(&softp->intr_mutex);
-
- IOSRAMLOG(2, "INTR arg/softp:%p pending:%d busy:%d\n",
- arg, softp->intr_pending, softp->intr_busy, NULL);
- DPRINTF(1, ("iosram(%d): iosram_intr exit\n", softp->instance));
-
- return (result);
-}
-
-
-/*
- * iosram_send_intr()
- * Send an interrupt to the SSP side via AXQ driver
- */
-int
-iosram_send_intr()
-{
- IOSRAMLOG(1, "SendIntr called\n", NULL, NULL, NULL, NULL);
- IOSRAM_STAT(intr_send);
- DPRINTF(1, ("iosram iosram_send_intr invoked\n"));
-
- return (axq_cpu2ssc_intr(0));
-}
-
-
-#if defined(DEBUG)
-static void
-iosram_dummy_cback(void *arg)
-{
- DPRINTF(1, ("iosram_dummy_cback invoked arg:%p\n", arg));
-}
-#endif /* DEBUG */
-
-
-/*ARGSUSED1*/
-static int
-iosram_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
- int *rvalp)
-{
- struct iosramsoft *softp;
- int error = DDI_SUCCESS;
-
- softp = ddi_get_soft_state(iosramsoft_statep, getminor(dev));
- if (softp == NULL) {
- return (ENXIO);
- }
- IOSRAMLOG(1, "IOCTL: dev:%p cmd:%x arg:%p ... instance %d\n",
- dev, cmd, arg, softp->instance);
-
- switch (cmd) {
-#if defined(DEBUG)
- case IOSRAM_GET_FLAG:
- {
- iosram_io_t req;
- uint8_t data_valid, int_pending;
-
- if (ddi_copyin((void *)arg, &req, sizeof (req), mode)) {
- return (EFAULT);
- }
-
- DPRINTF(2, ("IOSRAM_GET_FLAG(key:%x\n", req.key));
-
- req.retval = iosram_get_flag(req.key, &data_valid,
- &int_pending);
- req.data_valid = (uint32_t)data_valid;
- req.int_pending = (uint32_t)int_pending;
-
- if (ddi_copyout(&req, (void *)arg, sizeof (req), mode)) {
- DPRINTF(1,
- ("IOSRAM_GET_FLAG: can't copyout req.retval (%x)",
- req.retval));
- error = EFAULT;
- }
-
- return (error);
- }
-
- case IOSRAM_SET_FLAG:
- {
- iosram_io_t req;
-
- if (ddi_copyin((void *)arg, &req, sizeof (req), mode)) {
- return (EFAULT);
- }
-
- DPRINTF(2, ("IOSRAM_SET_FLAG(key:%x data_valid:%x "
- "int_pending:%x\n", req.key, req.data_valid,
- req.int_pending));
-
- req.retval = iosram_set_flag(req.key, req.data_valid,
- req.int_pending);
-
- if (ddi_copyout(&req, (void *)arg, sizeof (req), mode)) {
- DPRINTF(1, ("IOSRAM_SET_FLAG: can't copyout req.retval"
- " (%x)\n", req.retval));
- error = EFAULT;
- }
-
- return (error);
- }
-
- case IOSRAM_RD:
- {
- caddr_t bufp;
- int len;
- iosram_io_t req;
-
- if (ddi_copyin((void *)arg, &req, sizeof (req), mode)) {
- return (EFAULT);
- }
-
- DPRINTF(2, ("IOSRAM_RD(k:%x o:%x len:%x bufp:%p\n", req.key,
- req.off, req.len, (void *)(uintptr_t)req.bufp));
-
- len = req.len;
- bufp = kmem_alloc(len, KM_SLEEP);
-
- req.retval = iosram_rd(req.key, req.off, req.len, bufp);
-
- if (ddi_copyout(bufp, (void *)(uintptr_t)req.bufp, len, mode)) {
- DPRINTF(1, ("IOSRAM_RD: copyout(%p, %p,%x,%x) failed\n",
- (void *)bufp, (void *)(uintptr_t)req.bufp, len,
- mode));
- error = EFAULT;
- } else if (ddi_copyout(&req, (void *)arg, sizeof (req), mode)) {
- DPRINTF(1, ("IOSRAM_RD: can't copyout retval (%x)\n",
- req.retval));
- error = EFAULT;
- }
-
- kmem_free(bufp, len);
- return (error);
- }
-
- case IOSRAM_WR:
- {
- caddr_t bufp;
- iosram_io_t req;
- int len;
-
- if (ddi_copyin((void *)arg, &req, sizeof (req), mode)) {
- return (EFAULT);
- }
-
- DPRINTF(2, ("IOSRAM_WR(k:%x o:%x len:%x bufp:%p\n",
- req.key, req.off, req.len, (void *)(uintptr_t)req.bufp));
- len = req.len;
- bufp = kmem_alloc(len, KM_SLEEP);
- if (ddi_copyin((void *)(uintptr_t)req.bufp, bufp, len, mode)) {
- error = EFAULT;
- } else {
- req.retval = iosram_wr(req.key, req.off, req.len,
- bufp);
-
- if (ddi_copyout(&req, (void *)arg, sizeof (req),
- mode)) {
- error = EFAULT;
- }
- }
- kmem_free(bufp, len);
- return (error);
- }
-
- case IOSRAM_TOC:
- {
- caddr_t bufp;
- int len;
- iosram_io_t req;
-
- if (ddi_copyin((void *)arg, &req, sizeof (req), mode)) {
- return (EFAULT);
- }
-
- DPRINTF(2, ("IOSRAM_TOC (req.bufp:%x req.len:%x) \n",
- req.bufp, req.len));
-
- len = req.len;
- bufp = kmem_alloc(len, KM_SLEEP);
-
- req.retval = iosram_get_keys((iosram_toc_entry_t *)bufp,
- &req.len);
-
- if (ddi_copyout(bufp, (void *)(uintptr_t)req.bufp, req.len,
- mode)) {
- DPRINTF(1,
- ("IOSRAM_TOC: copyout(%p, %p,%x,%x) failed\n",
- (void *)bufp, (void *)(uintptr_t)req.bufp, req.len,
- mode));
- error = EFAULT;
- } else if (ddi_copyout(&req, (void *)arg, sizeof (req), mode)) {
- DPRINTF(1, ("IOSRAM_TOC: can't copyout retval (%x)\n",
- req.retval));
- error = EFAULT;
- }
- kmem_free(bufp, len);
- return (error);
- }
-
- case IOSRAM_SEND_INTR:
- {
- DPRINTF(2, ("IOSRAM_SEND_INTR\n"));
-
- switch ((int)arg) {
- case 0x11:
- case 0x22:
- case 0x44:
- case 0x88:
- ddi_put32(softp->sbbc_handle,
- &(softp->sbbc_region->int_enable.reg), (int)arg);
- DPRINTF(1, ("Wrote 0x%x to int_enable.reg\n",
- (int)arg));
- break;
- case 0xBB:
- ddi_put32(softp->sbbc_handle,
- &(softp->sbbc_region->p0_int_gen.reg), 1);
- DPRINTF(1, ("Wrote 1 to p0_int_gen.reg\n"));
- break;
- default:
- error = iosram_send_intr();
- }
-
- return (error);
- }
-
- case IOSRAM_PRINT_CBACK:
- iosram_print_cback();
- break;
-
- case IOSRAM_PRINT_STATE:
- iosram_print_state((int)arg);
- break;
-
-#if IOSRAM_STATS
- case IOSRAM_PRINT_STATS:
- iosram_print_stats();
- break;
-#endif
-
-#if IOSRAM_LOG
- case IOSRAM_PRINT_LOG:
- iosram_print_log((int)arg);
- break;
-#endif
-
- case IOSRAM_TUNNEL_SWITCH:
- error = iosram_switchfrom((int)arg);
- break;
-
- case IOSRAM_PRINT_FLAGS:
- iosram_print_flags();
- break;
-
- case IOSRAM_REG_CBACK:
- {
- iosram_io_t req;
-
- if (ddi_copyin((void *)arg, &req, sizeof (req), mode)) {
- return (EFAULT);
- }
-
- DPRINTF(2, ("IOSRAM_REG_CBACK(k:%x)\n", req.key));
-
- req.retval = iosram_register(req.key, iosram_dummy_cback,
- (void *)(uintptr_t)req.key);
- if (ddi_copyout(&req, (void *)arg, sizeof (req), mode)) {
- error = EFAULT;
- }
-
- return (error);
- }
-
- case IOSRAM_UNREG_CBACK:
- {
- iosram_io_t req;
-
- if (ddi_copyin((void *)arg, &req, sizeof (req), mode)) {
- return (EFAULT);
- }
-
- DPRINTF(2, ("IOSRAM_REG_CBACK(k:%x)\n", req.key));
-
- req.retval = iosram_unregister(req.key);
- if (ddi_copyout(&req, (void *)arg, sizeof (req), mode)) {
- error = EFAULT;
- }
-
- return (error);
- }
-
- case IOSRAM_SEMA_ACQUIRE:
- {
- DPRINTF(1, ("IOSRAM_SEMA_ACQUIRE\n"));
- error = iosram_sema_acquire(NULL);
- return (error);
- }
-
- case IOSRAM_SEMA_RELEASE:
- {
- DPRINTF(1, ("IOSRAM_SEMA_RELEASE\n"));
- error = iosram_sema_release();
- return (error);
- }
-
-#endif /* DEBUG */
-
- default:
- DPRINTF(1, ("iosram_ioctl: Illegal command %x\n", cmd));
- error = ENOTTY;
- }
-
- return (error);
-}
-
-
-/*
- * iosram_switch_tunnel(softp)
- * Switch master tunnel to the specified instance
- * Must be called while holding iosram_mutex
- */
-/*ARGSUSED*/
-static int
-iosram_switch_tunnel(iosramsoft_t *softp)
-{
-#ifdef DEBUG
- int instance = softp->instance;
-#endif
- int error = 0;
- iosramsoft_t *prev_master;
-
- ASSERT(mutex_owned(&iosram_mutex));
-
- DPRINTF(1, ("tunnel switch new master:%p (%d) current master:%p (%d)\n",
- (void *)softp, instance, (void *)iosram_master,
- ((iosram_master) ? iosram_master->instance : -1)));
- IOSRAMLOG(1, "TSWTCH: new_master:%p (%p) iosram_master:%p (%d)\n",
- softp, instance, iosram_master,
- ((iosram_master) ? iosram_master->instance : -1));
-
- if (softp == NULL || (softp->state & IOSRAM_STATE_DETACH)) {
- return (ENXIO);
- }
- if (iosram_master == softp) {
- return (0);
- }
-
-
- /*
- * We protect against the softp structure being deallocated by setting
- * the IOSRAM_STATE_TSWITCH state flag. The detach routine will check
- * for this flag and if set, it will wait for this flag to be reset or
- * refuse the detach operation.
- */
- iosram_new_master = softp;
- softp->state |= IOSRAM_STATE_TSWITCH;
- prev_master = iosram_master;
- if (prev_master) {
- prev_master->state |= IOSRAM_STATE_TSWITCH;
- }
- mutex_exit(&iosram_mutex);
-
- /*
- * Map the target IOSRAM, read the TOC, and register interrupts if not
- * already done.
- */
- DPRINTF(1, ("iosram(%d): mapping IOSRAM and SBBC\n",
- softp->instance));
- IOSRAMLOG(1, "TSWTCH: mapping instance:%d softp:%p\n",
- instance, softp, NULL, NULL);
-
- if (iosram_setup_map(softp) != DDI_SUCCESS) {
- error = ENXIO;
- } else if ((chunks == NULL) && (iosram_read_toc(softp) != 0)) {
- iosram_remove_map(softp);
- error = EINVAL;
- } else if (iosram_add_intr(softp) != DDI_SUCCESS) {
- /*
- * If there was no previous master, purge the TOC data that
- * iosram_read_toc() created.
- */
- if ((prev_master == NULL) && (chunks != NULL)) {
- kmem_free(chunks, nchunks * sizeof (iosram_chunk_t));
- chunks = NULL;
- nchunks = 0;
- iosram_init_hashtab();
- }
- iosram_remove_map(softp);
- error = ENXIO;
- }
-
- /*
- * If we are asked to abort tunnel switch, do so now, before invoking
- * the OBP callback.
- */
- if (iosram_tswitch_aborted) {
-
- /*
- * Once the tunnel switch is aborted, this thread should not
- * resume. If it does, we simply log a message. We can't unmap
- * the new master IOSRAM as it may be accessed in
- * iosram_abort_tswitch(). It will be unmapped when it is
- * detached.
- */
- IOSRAMLOG(1,
- "TSWTCH: aborted (pre OBP cback). Thread resumed.\n",
- NULL, NULL, NULL, NULL);
- error = EIO;
- }
-
- if (error) {
- IOSRAMLOG(1,
- "TSWTCH: map failed instance:%d softp:%p error:%x\n",
- instance, softp, error, NULL);
- goto done;
- }
-
- if (prev_master != NULL) {
- int result;
-
- /*
- * Now invoke the OBP interface to do the tunnel switch.
- */
- result = prom_starcat_switch_tunnel(softp->portid,
- OBP_TSWITCH_REQREPLY);
- if (result != 0) {
- error = EIO;
- }
- IOSRAMLOG(1,
- "TSWTCH: OBP tswitch portid:%x result:%x error:%x\n",
- softp->portid, result, error, NULL);
- IOSRAM_STAT(tswitch);
- iosram_tswitch_tstamp = ddi_get_lbolt();
- }
-
- mutex_enter(&iosram_mutex);
- if (iosram_tswitch_aborted) {
- /*
- * Tunnel switch aborted. This thread should not resume.
- * For now, we simply log a message, but don't unmap any
- * IOSRAM at this stage as it may be accessed within the
- * isoram_abort_tswitch(). The IOSRAM will be unmapped
- * when that instance is detached.
- */
- if (iosram_tswitch_aborted) {
- IOSRAMLOG(1,
- "TSWTCH: aborted (post OBP cback). Thread"
- " resumed.\n", NULL, NULL, NULL, NULL);
- error = EIO;
- mutex_exit(&iosram_mutex);
- }
- } else if (error) {
- /*
- * Tunnel switch failed. Continue using previous tunnel.
- * However, unmap new (target) IOSRAM.
- */
- iosram_new_master = NULL;
- mutex_exit(&iosram_mutex);
- (void) iosram_remove_intr(softp);
- iosram_remove_map(softp);
- } else {
- /*
- * Tunnel switch was successful. Set the new master.
- * Also unmap old master IOSRAM and remove any interrupts
- * associated with that.
- *
- * Note that a call to iosram_force_write() allows access
- * to the IOSRAM while tunnel switch is in progress. That
- * means we need to set the new master before unmapping
- * the old master.
- */
- iosram_set_master(softp);
- iosram_new_master = NULL;
- mutex_exit(&iosram_mutex);
-
- if (prev_master) {
- IOSRAMLOG(1, "TSWTCH: unmapping prev_master:%p (%d)\n",
- prev_master, prev_master->instance, NULL, NULL);
- (void) iosram_remove_intr(prev_master);
- iosram_remove_map(prev_master);
- }
- }
-
-done:
- mutex_enter(&iosram_mutex);
-
- /*
- * Clear the tunnel switch flag on the source and destination
- * instances.
- */
- if (prev_master) {
- prev_master->state &= ~IOSRAM_STATE_TSWITCH;
- }
- softp->state &= ~IOSRAM_STATE_TSWITCH;
-
- /*
- * Since incoming interrupts could get lost during a tunnel switch,
- * trigger a soft interrupt just in case. No harm other than a bit
- * of wasted effort will be caused if no interrupts were dropped.
- */
- mutex_enter(&softp->intr_mutex);
- iosram_master->intr_pending = 1;
- if ((iosram_master->softintr_id != NULL) &&
- (iosram_master->intr_busy == 0)) {
- ddi_trigger_softintr(iosram_master->softintr_id);
- }
- mutex_exit(&softp->intr_mutex);
-
- IOSRAMLOG(1, "TSWTCH: done error:%d iosram_master:%p instance:%d\n",
- error, iosram_master,
- (iosram_master) ? iosram_master->instance : -1, NULL);
-
- return (error);
-}
-
-
-/*
- * iosram_abort_tswitch()
- * Must be called while holding iosram_mutex.
- */
-static void
-iosram_abort_tswitch()
-{
- uint32_t master_valid, new_master_valid;
-
- ASSERT(mutex_owned(&iosram_mutex));
-
- if ((!iosram_tswitch_active) || iosram_tswitch_aborted) {
- return;
- }
-
- ASSERT(iosram_master != NULL);
-
- IOSRAMLOG(1, "ABORT: iosram_master:%p (%d) iosram_new_master:%p (%d)\n",
- iosram_master, iosram_master->instance, iosram_new_master,
- (iosram_new_master == NULL) ? -1 : iosram_new_master->instance);
-
- /*
- * The first call to iosram_force_write() in the middle of tunnel switch
- * will get here. We lookup IOSRAM VALID location and setup appropriate
- * master, if one is still valid. We also set iosram_tswitch_aborted to
- * prevent reentering this code and to catch if the OBP callback thread
- * somehow resumes.
- */
- iosram_tswitch_aborted = 1;
-
- if ((iosram_new_master == NULL) ||
- (iosram_new_master = iosram_master)) {
- /*
- * New master hasn't been selected yet, or OBP callback
- * succeeded and we already selected new IOSRAM as master, but
- * system crashed in the middle of unmapping previous master or
- * cleaning up state. Use the existing master.
- */
- ASSERT(iosram_master->iosramp != NULL);
- ASSERT(IOSRAM_GET_HDRFIELD32(iosram_master, status) ==
- IOSRAM_VALID);
- IOSRAMLOG(1, "ABORT: master (%d) already determined.\n",
- iosram_master->instance, NULL, NULL, NULL);
-
- return;
- }
-
- /*
- * System crashed in the middle of tunnel switch and we know that the
- * new target has not been marked master yet. That means, the old
- * master should still be mapped. We need to abort the tunnel switch
- * and setup a valid master, if possible, so that we can write to the
- * IOSRAM.
- *
- * We select a new master based upon the IOSRAM header status fields in
- * the previous master IOSRAM and the target IOSRAM as follows:
- *
- * iosram_master iosram-tswitch
- * (Prev Master) (New Target) Decision
- * --------------- --------------- -----------
- * VALID don't care prev master
- * INTRANSIT INVALID prev master
- * INTRANSIT INTRANSIT prev master
- * INTRANSIT VALID new target
- * INVALID INVALID shouldn't ever happen
- * INVALID INTRANSIT shouldn't ever happen
- * INVALID VALID new target
- */
-
- master_valid = (iosram_master->iosramp != NULL) ?
- IOSRAM_GET_HDRFIELD32(iosram_master, status) : IOSRAM_INVALID;
- new_master_valid = (iosram_new_master->iosramp != NULL) ?
- IOSRAM_GET_HDRFIELD32(iosram_new_master, status) : IOSRAM_INVALID;
-
- if (master_valid == IOSRAM_VALID) {
- /* EMPTY */
- /*
- * OBP hasn't been called yet or, if it has, it hasn't started
- * copying yet. Use the existing master. Note that the new
- * master may not be mapped yet.
- */
- IOSRAMLOG(1, "ABORT: prev master(%d) is VALID\n",
- iosram_master->instance, NULL, NULL, NULL);
- } else if (master_valid == IOSRAM_INTRANSIT) {
- /*
- * The system crashed after OBP started processing the tunnel
- * switch but before the iosram driver determined that it was
- * complete. Use the new master if it has been marked valid,
- * meaning that OBP finished copying data to it, or the old
- * master otherwise.
- */
- IOSRAMLOG(1, "ABORT: prev master(%d) is INTRANSIT\n",
- iosram_master->instance, NULL, NULL, NULL);
-
- if (new_master_valid == IOSRAM_VALID) {
- iosram_set_master(iosram_new_master);
- IOSRAMLOG(1, "ABORT: new master(%d) is VALID\n",
- iosram_new_master->instance, NULL, NULL,
- NULL);
- } else {
- (void) prom_starcat_switch_tunnel(iosram_master->portid,
- OBP_TSWITCH_NOREPLY);
-
- IOSRAMLOG(1, "ABORT: new master(%d) is INVALID\n",
- iosram_new_master->instance, NULL, NULL,
- NULL);
- }
- } else {
- /*
- * The system crashed after OBP marked the old master INVALID,
- * which means the new master is the way to go.
- */
- IOSRAMLOG(1, "ABORT: prev master(%d) is INVALID\n",
- iosram_master->instance, NULL, NULL, NULL);
-
- ASSERT(new_master_valid == IOSRAM_VALID);
-
- iosram_set_master(iosram_new_master);
- }
-
- IOSRAMLOG(1, "ABORT: Instance %d selected as master\n",
- iosram_master->instance, NULL, NULL, NULL);
-}
-
-
-/*
- * iosram_switchfrom(instance)
- * Switch master tunnel away from the specified instance
- */
-/*ARGSUSED*/
-int
-iosram_switchfrom(int instance)
-{
- struct iosramsoft *softp;
- int error = 0;
- int count;
- clock_t current_tstamp;
- clock_t tstamp_interval;
- struct iosramsoft *last_master = NULL;
- static int last_master_instance = -1;
-
- IOSRAMLOG(1, "SwtchFrom: instance:%d iosram_master:%p (%d)\n",
- instance, iosram_master,
- ((iosram_master) ? iosram_master->instance : -1), NULL);
-
- mutex_enter(&iosram_mutex);
-
- /*
- * Wait if another tunnel switch is in progress
- */
- for (count = 0; iosram_tswitch_active && count < IOSRAM_TSWITCH_RETRY;
- count++) {
- iosram_tswitch_wakeup = 1;
- cv_wait(&iosram_tswitch_wait, &iosram_mutex);
- }
-
- if (iosram_tswitch_active) {
- mutex_exit(&iosram_mutex);
- return (EAGAIN);
- }
-
- /*
- * Check if the specified instance holds the tunnel. If not,
- * then we are done.
- */
- if ((iosram_master == NULL) || (iosram_master->instance != instance)) {
- mutex_exit(&iosram_mutex);
- return (0);
- }
-
- /*
- * Before beginning the tunnel switch process, wait for any outstanding
- * read/write activity to complete.
- */
- iosram_tswitch_active = 1;
- while (iosram_rw_active) {
- iosram_rw_wakeup = 1;
- cv_wait(&iosram_rw_wait, &iosram_mutex);
- }
-
- /*
- * If a previous tunnel switch just completed, we have to make sure
- * HWAD has enough time to find the new tunnel before we switch
- * away from it. Otherwise, OBP's mailbox message to OSD will never
- * get through. Just to be paranoid about synchronization of lbolt
- * across different CPUs, make sure the current attempt isn't noted
- * as starting _before_ the last tunnel switch completed.
- */
- current_tstamp = ddi_get_lbolt();
- if (current_tstamp > iosram_tswitch_tstamp) {
- tstamp_interval = current_tstamp - iosram_tswitch_tstamp;
- } else {
- tstamp_interval = 0;
- }
- if (drv_hztousec(tstamp_interval) < IOSRAM_TSWITCH_DELAY_US) {
- mutex_exit(&iosram_mutex);
- delay(drv_usectohz(IOSRAM_TSWITCH_DELAY_US) - tstamp_interval);
- mutex_enter(&iosram_mutex);
- }
-
- /*
- * The specified instance holds the tunnel. We need to move it to some
- * other IOSRAM. Try out all possible IOSRAMs listed in
- * iosram_instances. For now, we always search from the first entry.
- * In future, it may be desirable to start where we left off.
- */
- for (softp = iosram_instances; softp != NULL; softp = softp->next) {
- if (iosram_tswitch_aborted) {
- break;
- }
-
- /* we can't switch _to_ the instance we're switching _from_ */
- if (softp->instance == instance) {
- continue;
- }
-
- /* skip over instances being detached */
- if (softp->state & IOSRAM_STATE_DETACH) {
- continue;
- }
-
- /*
- * Try to avoid reverting to the last instance we switched away
- * from, as we expect that one to be detached eventually. Keep
- * track of it, though, so we can go ahead and try switching to
- * it if no other viable candidates are found.
- */
- if (softp->instance == last_master_instance) {
- last_master = softp;
- continue;
- }
-
- /*
- * Do the tunnel switch. If successful, record the instance of
- * the master we just left behind so we can try to avoid
- * reverting to it next time.
- */
- if (iosram_switch_tunnel(softp) == 0) {
- last_master_instance = instance;
- break;
- }
- }
-
- /*
- * If we failed to switch the tunnel, but we skipped over an instance
- * that had previously been switched out of because we expected it to be
- * detached, go ahead and try it anyway (unless the tswitch was aborted
- * or the instance we skipped is finally being detached).
- */
- if ((softp == NULL) && (last_master != NULL) &&
- !iosram_tswitch_aborted &&
- !(last_master->state & IOSRAM_STATE_DETACH)) {
- if (iosram_switch_tunnel(last_master) == 0) {
- softp = last_master;
- last_master_instance = instance;
- }
- }
-
- if ((softp == NULL) || (iosram_tswitch_aborted)) {
- error = EIO;
- }
-
- /*
- * If there are additional tunnel switches queued up waiting for this
- * one to complete, wake them up.
- */
- if (iosram_tswitch_wakeup) {
- iosram_tswitch_wakeup = 0;
- cv_broadcast(&iosram_tswitch_wait);
- }
- iosram_tswitch_active = 0;
- mutex_exit(&iosram_mutex);
- return (error);
-}
-
-
-/*
- * iosram_tunnel_capable(softp)
- * Check if this IOSRAM instance is tunnel-capable by looing at
- * "tunnel-capable" property.
- */
-static int
-iosram_tunnel_capable(struct iosramsoft *softp)
-{
- int proplen;
- int tunnel_capable;
-
- /*
- * Look up IOSRAM_TUNNELOK_PROP property, if any.
- */
- proplen = sizeof (tunnel_capable);
- if (ddi_getlongprop_buf(DDI_DEV_T_ANY, softp->dip,
- DDI_PROP_DONTPASS, IOSRAM_TUNNELOK_PROP, (caddr_t)&tunnel_capable,
- &proplen) != DDI_PROP_SUCCESS) {
- tunnel_capable = 0;
- }
- return (tunnel_capable);
-}
-
-
-static int
-iosram_sbbc_setup_map(struct iosramsoft *softp)
-{
- int rv;
- struct ddi_device_acc_attr attr;
- dev_info_t *dip = softp->dip;
- uint32_t sema_val;
-
- attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
- attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
- attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
-
- mutex_enter(&iosram_mutex);
- mutex_enter(&softp->intr_mutex);
-
- /*
- * Map SBBC region in
- */
- if ((rv = ddi_regs_map_setup(dip, IOSRAM_SBBC_MAP_INDEX,
- (caddr_t *)&softp->sbbc_region,
- IOSRAM_SBBC_MAP_OFFSET, sizeof (iosram_sbbc_region_t),
- &attr, &softp->sbbc_handle)) != DDI_SUCCESS) {
- DPRINTF(1, ("Failed to map SBBC region.\n"));
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- return (rv);
- }
-
- /*
- * Disable SBBC interrupts. SBBC interrupts are enabled
- * once the interrupt handler is registered.
- */
- ddi_put32(softp->sbbc_handle,
- &(softp->sbbc_region->int_enable.reg), 0x0);
-
- /*
- * Clear hardware semaphore value if appropriate.
- * When the first SBBC is mapped in by the IOSRAM driver,
- * the value of the semaphore should be initialized only
- * if it is not held by SMS. For subsequent SBBC's, the
- * semaphore will be always initialized.
- */
- sema_val = IOSRAM_SEMA_RD(softp);
-
- if (!iosram_master) {
- /* the first SBBC is being mapped in */
- if (!(IOSRAM_SEMA_IS_HELD(sema_val) &&
- IOSRAM_SEMA_GET_IDX(sema_val) == IOSRAM_SEMA_SMS_IDX)) {
- /* not held by SMS, we clear the semaphore */
- IOSRAM_SEMA_WR(softp, 0);
- }
- } else {
- /* not the first SBBC, we clear the semaphore */
- IOSRAM_SEMA_WR(softp, 0);
- }
-
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- return (0);
-}
-
-
-static int
-iosram_setup_map(struct iosramsoft *softp)
-{
- int instance = softp->instance;
- dev_info_t *dip = softp->dip;
- int portid;
- int proplen;
- caddr_t propvalue;
- struct ddi_device_acc_attr attr;
-
- attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
- attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
- attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
-
- /*
- * Lookup IOSRAM_REG_PROP property to find out our IOSRAM length
- */
- if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, IOSRAM_REG_PROP, (caddr_t)&propvalue,
- &proplen) != DDI_PROP_SUCCESS) {
- cmn_err(CE_WARN, "iosram(%d): can't find register property.\n",
- instance);
- return (DDI_FAILURE);
- } else {
- iosram_reg_t *regprop = (iosram_reg_t *)propvalue;
-
- DPRINTF(1, ("SetupMap(%d): Got reg prop: %x %x %x\n",
- instance, regprop->addr_hi,
- regprop->addr_lo, regprop->size));
-
- softp->iosramlen = regprop->size;
-
- kmem_free(propvalue, proplen);
- }
- DPRINTF(1, ("SetupMap(%d): IOSRAM length: 0x%x\n", instance,
- softp->iosramlen));
- softp->handle = NULL;
-
- /*
- * To minimize boot time, we map the entire IOSRAM as opposed to
- * mapping individual chunk via ddi_regs_map_setup() call.
- */
- if (ddi_regs_map_setup(dip, 0, (caddr_t *)&softp->iosramp,
- 0x0, softp->iosramlen, &attr, &softp->handle) != DDI_SUCCESS) {
- cmn_err(CE_WARN, "iosram(%d): failed to map IOSRAM len:%x\n",
- instance, softp->iosramlen);
- iosram_remove_map(softp);
- return (DDI_FAILURE);
- }
-
- /*
- * Lookup PORTID property on my parent hierarchy
- */
- proplen = sizeof (portid);
- if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip,
- 0, IOSRAM_PORTID_PROP, (caddr_t)&portid,
- &proplen) != DDI_PROP_SUCCESS) {
- cmn_err(CE_WARN, "iosram(%d): can't find portid property.\n",
- instance);
- iosram_remove_map(softp);
- return (DDI_FAILURE);
- }
- softp->portid = portid;
-
- if (iosram_sbbc_setup_map(softp) != DDI_SUCCESS) {
- cmn_err(CE_WARN, "iosram(%d): can't map SBBC region.\n",
- instance);
- iosram_remove_map(softp);
- return (DDI_FAILURE);
- }
-
- mutex_enter(&iosram_mutex);
- softp->state |= IOSRAM_STATE_MAPPED;
- mutex_exit(&iosram_mutex);
-
- return (DDI_SUCCESS);
-}
-
-
-static void
-iosram_remove_map(struct iosramsoft *softp)
-{
- mutex_enter(&iosram_mutex);
-
- ASSERT((softp->state & IOSRAM_STATE_MASTER) == 0);
-
- if (softp->handle) {
- ddi_regs_map_free(&softp->handle);
- softp->handle = NULL;
- }
- softp->iosramp = NULL;
-
- /*
- * Umap SBBC registers region. Shared with handler for SBBC
- * interrupts, take intr_mutex.
- */
- mutex_enter(&softp->intr_mutex);
- if (softp->sbbc_region) {
- ddi_regs_map_free(&softp->sbbc_handle);
- softp->sbbc_region = NULL;
- }
- mutex_exit(&softp->intr_mutex);
-
- softp->state &= ~IOSRAM_STATE_MAPPED;
-
- mutex_exit(&iosram_mutex);
-}
-
-
-/*
- * iosram_is_chosen(struct iosramsoft *softp)
- *
- * Looks up "chosen" node property to
- * determine if it is the chosen IOSRAM.
- */
-static int
-iosram_is_chosen(struct iosramsoft *softp)
-{
- char chosen_iosram[MAXNAMELEN];
- char pn[MAXNAMELEN];
- int nodeid;
- int chosen;
- pnode_t dnode;
-
- /*
- * Get /chosen node info. prom interface will handle errors.
- */
- dnode = prom_chosennode();
-
- /*
- * Look for the "iosram" property on the chosen node with a prom
- * interface as ddi_find_devinfo() couldn't be used (calls
- * ddi_walk_devs() that creates one extra lock on the device tree).
- */
- if (prom_getprop(dnode, IOSRAM_CHOSEN_PROP, (caddr_t)&nodeid) <= 0) {
- /*
- * Can't find IOSRAM_CHOSEN_PROP property under chosen node
- */
- cmn_err(CE_WARN,
- "iosram(%d): can't find chosen iosram property\n",
- softp->instance);
- return (0);
- }
-
- DPRINTF(1, ("iosram(%d): Got '%x' for chosen '%s' property\n",
- softp->instance, nodeid, IOSRAM_CHOSEN_PROP));
-
- /*
- * get the full OBP pathname of this node
- */
- if (prom_phandle_to_path((phandle_t)nodeid, chosen_iosram,
- sizeof (chosen_iosram)) < 0) {
- cmn_err(CE_NOTE, "prom_phandle_to_path(%x) failed\n", nodeid);
- return (0);
- }
- DPRINTF(1, ("iosram(%d): prom_phandle_to_path(%x) is '%s'\n",
- softp->instance, nodeid, chosen_iosram));
-
- (void) ddi_pathname(softp->dip, pn);
- DPRINTF(1, ("iosram(%d): ddi_pathname(%p) is '%s'\n",
- softp->instance, (void *)softp->dip, pn));
-
- chosen = (strcmp(chosen_iosram, pn) == 0) ? 1 : 0;
- DPRINTF(1, ("iosram(%d): ... %s\n", softp->instance,
- chosen ? "MASTER" : "SLAVE"));
- IOSRAMLOG(1, "iosram(%d): ... %s\n", softp->instance,
- (chosen ? "MASTER" : "SLAVE"), NULL, NULL);
-
- return (chosen);
-}
-
-
-/*
- * iosram_set_master(struct iosramsoft *softp)
- *
- * Set master tunnel to the specified IOSRAM
- * Must be called while holding iosram_mutex.
- */
-static void
-iosram_set_master(struct iosramsoft *softp)
-{
- ASSERT(mutex_owned(&iosram_mutex));
- ASSERT(softp != NULL);
- ASSERT(softp->state & IOSRAM_STATE_MAPPED);
- ASSERT(IOSRAM_GET_HDRFIELD32(softp, status) == IOSRAM_VALID);
-
- /*
- * Clear MASTER flag on any previous IOSRAM master, if any
- */
- if (iosram_master && (iosram_master != softp)) {
- iosram_master->state &= ~IOSRAM_STATE_MASTER;
- }
-
- /*
- * Setup new IOSRAM master
- */
- iosram_update_addrs(softp);
- iosram_handle = softp->handle;
- softp->state |= IOSRAM_STATE_MASTER;
- softp->tswitch_ok++;
- iosram_master = softp;
-
- IOSRAMLOG(1, "SETMASTER: softp:%p instance:%d\n", softp,
- softp->instance, NULL, NULL);
-}
-
-
-/*
- * iosram_read_toc()
- *
- * Read the TOC from an IOSRAM instance that has been mapped in.
- * If the TOC is flawed or the IOSRAM isn't valid, return an error.
- */
-static int
-iosram_read_toc(struct iosramsoft *softp)
-{
- int i;
- int instance = softp->instance;
- uint8_t *toc_entryp;
- iosram_flags_t *flagsp = NULL;
- int new_nchunks;
- iosram_chunk_t *new_chunks;
- iosram_chunk_t *chunkp;
- iosram_chunk_t *old_chunkp;
- iosram_toc_entry_t index;
-
- /*
- * Never try to read the TOC out of an unmapped IOSRAM.
- */
- ASSERT(softp->state & IOSRAM_STATE_MAPPED);
-
- mutex_enter(&iosram_mutex);
-
- /*
- * Check to make sure this IOSRAM is marked valid. Return
- * an error if it isn't.
- */
- if (IOSRAM_GET_HDRFIELD32(softp, status) != IOSRAM_VALID) {
- DPRINTF(1, ("iosram_read_toc(%d): IOSRAM not flagged valid\n",
- instance));
- mutex_exit(&iosram_mutex);
- return (EINVAL);
- }
-
- /*
- * Get the location of the TOC.
- */
- toc_entryp = softp->iosramp + IOSRAM_GET_HDRFIELD32(softp, toc_offset);
-
- /*
- * Read the index entry from the TOC and make sure it looks correct.
- */
- ddi_rep_get8(softp->handle, (uint8_t *)&index, toc_entryp,
- sizeof (iosram_toc_entry_t), DDI_DEV_AUTOINCR);
- if ((index.key != IOSRAM_INDEX_KEY) ||
- (index.off != IOSRAM_INDEX_OFF)) {
- cmn_err(CE_WARN, "iosram(%d): invalid TOC index.\n", instance);
- mutex_exit(&iosram_mutex);
- return (EINVAL);
- }
-
- /*
- * Allocate storage for the new chunks array and initialize it with data
- * from the TOC and callback data from the corresponding old chunk, if
- * it exists.
- */
- new_nchunks = index.len - 1;
- new_chunks = (iosram_chunk_t *)kmem_zalloc(new_nchunks *
- sizeof (iosram_chunk_t), KM_SLEEP);
- for (i = 0, chunkp = new_chunks; i < new_nchunks; i++, chunkp++) {
- toc_entryp += sizeof (iosram_toc_entry_t);
- ddi_rep_get8(softp->handle, (uint8_t *)&(chunkp->toc_data),
- toc_entryp, sizeof (iosram_toc_entry_t), DDI_DEV_AUTOINCR);
- chunkp->hash = NULL;
- if ((chunkp->toc_data.off < softp->iosramlen) &&
- (chunkp->toc_data.len <= softp->iosramlen) &&
- ((chunkp->toc_data.off + chunkp->toc_data.len) <=
- softp->iosramlen)) {
- chunkp->basep = softp->iosramp + chunkp->toc_data.off;
- DPRINTF(1,
- ("iosram_read_toc(%d): k:%x o:%x l:%x p:%p\n",
- instance, chunkp->toc_data.key,
- chunkp->toc_data.off, chunkp->toc_data.len,
- (void *)chunkp->basep));
- } else {
- cmn_err(CE_WARN, "iosram(%d): TOC entry %d"
- "out of range... off:%x len:%x\n",
- instance, i + 1, chunkp->toc_data.off,
- chunkp->toc_data.len);
- kmem_free(new_chunks, new_nchunks *
- sizeof (iosram_chunk_t));
- mutex_exit(&iosram_mutex);
- return (EINVAL);
- }
-
- /*
- * Note the existence of the flags chunk, which is required in
- * a correct TOC.
- */
- if (chunkp->toc_data.key == IOSRAM_FLAGS_KEY) {
- flagsp = (iosram_flags_t *)chunkp->basep;
- }
-
- /*
- * If there was an entry for this chunk in the old list, copy
- * the callback data from old to new storage.
- */
- if ((nchunks > 0) &&
- ((old_chunkp = iosram_find_chunk(chunkp->toc_data.key)) !=
- NULL)) {
- bcopy(&(old_chunkp->cback), &(chunkp->cback),
- sizeof (iosram_cback_t));
- }
- }
- /*
- * The TOC is malformed if there is no entry for the flags chunk.
- */
- if (flagsp == NULL) {
- kmem_free(new_chunks, new_nchunks * sizeof (iosram_chunk_t));
- mutex_exit(&iosram_mutex);
- return (EINVAL);
- }
-
- /*
- * Free any memory that is no longer needed and install the new data
- * as current data.
- */
- if (chunks != NULL) {
- kmem_free(chunks, nchunks * sizeof (iosram_chunk_t));
- }
- chunks = new_chunks;
- nchunks = new_nchunks;
- iosram_init_hashtab();
-
- mutex_exit(&iosram_mutex);
- return (0);
-}
-
-
-/*
- * iosram_init_hashtab()
- *
- * Initialize the hash table and populate it with the IOSRAM
- * chunks previously read from the TOC. The caller must hold the
- * ioram_mutex lock.
- */
-static void
-iosram_init_hashtab(void)
-{
- int i, bucket;
- iosram_chunk_t *chunkp;
-
- ASSERT(mutex_owned(&iosram_mutex));
-
- for (i = 0; i < IOSRAM_HASHSZ; i++) {
- iosram_hashtab[i] = NULL;
- }
-
- if (chunks) {
- for (i = 0, chunkp = chunks; i < nchunks; i++, chunkp++) {
- /*
- * Hide the flags chunk by leaving it out of the hash
- * table.
- */
- if (chunkp->toc_data.key == IOSRAM_FLAGS_KEY) {
- continue;
- }
-
- /*
- * Add the current chunk to the hash table.
- */
- bucket = IOSRAM_HASH(chunkp->toc_data.key);
- chunkp->hash = iosram_hashtab[bucket];
- iosram_hashtab[bucket] = chunkp;
- }
- }
-}
-
-
-/*
- * iosram_update_addrs()
- *
- * Process the chunk list, updating each chunk's basep, which is a pointer
- * to the beginning of the chunk's memory in kvaddr space. Record the
- * basep value of the flags chunk to speed up flag access. The caller
- * must hold the iosram_mutex lock.
- */
-static void
-iosram_update_addrs(struct iosramsoft *softp)
-{
- int i;
- iosram_flags_t *flagsp;
- iosram_chunk_t *chunkp;
-
- ASSERT(mutex_owned(&iosram_mutex));
-
- /*
- * First go through all of the chunks updating their base pointers and
- * looking for the flags chunk.
- */
- for (i = 0, chunkp = chunks; i < nchunks; i++, chunkp++) {
- chunkp->basep = softp->iosramp + chunkp->toc_data.off;
- if (chunkp->toc_data.key == IOSRAM_FLAGS_KEY) {
- flagsp = (iosram_flags_t *)(chunkp->basep);
- DPRINTF(1,
- ("iosram_update_addrs flags: o:0x%08x p:%p",
- chunkp->toc_data.off, (void *)flagsp));
- }
- }
-
- /*
- * Now, go through and update each chunk's flags pointer. This can't be
- * done in the first loop because we don't have the address of the flags
- * chunk yet.
- */
- for (i = 0, chunkp = chunks; i < nchunks; i++, chunkp++) {
- chunkp->flagsp = flagsp++;
- DPRINTF(1, ("iosram_update_addrs: k:0x%x f:%p\n",
- chunkp->toc_data.key, (void *)chunkp->flagsp));
- }
-}
-
-/*
- * iosram_find_chunk(key)
- *
- * Return a pointer to iosram_chunk structure corresponding to the
- * "key" IOSRAM chunk. The caller must hold the iosram_mutex lock.
- */
-static iosram_chunk_t *
-iosram_find_chunk(uint32_t key)
-{
- iosram_chunk_t *chunkp;
- int index = IOSRAM_HASH(key);
-
- ASSERT(mutex_owned(&iosram_mutex));
-
- for (chunkp = iosram_hashtab[index]; chunkp; chunkp = chunkp->hash) {
- if (chunkp->toc_data.key == key) {
- break;
- }
- }
-
- return (chunkp);
-}
-
-
-/*
- * iosram_add_intr(iosramsoft_t *)
- */
-static int
-iosram_add_intr(iosramsoft_t *softp)
-{
- IOSRAMLOG(2, "ADDINTR: softp:%p instance:%d\n",
- softp, softp->instance, NULL, NULL);
-
- if (ddi_add_softintr(softp->dip, DDI_SOFTINT_MED,
- &softp->softintr_id, &softp->soft_iblk, NULL,
- iosram_softintr, (caddr_t)softp) != DDI_SUCCESS) {
- cmn_err(CE_WARN,
- "iosram(%d): Can't register softintr.\n",
- softp->instance);
- return (DDI_FAILURE);
- }
-
- if (ddi_add_intr(softp->dip, 0, &softp->real_iblk, NULL,
- iosram_intr, (caddr_t)softp) != DDI_SUCCESS) {
- cmn_err(CE_WARN,
- "iosram(%d): Can't register intr"
- " handler.\n", softp->instance);
- ddi_remove_softintr(softp->softintr_id);
- return (DDI_FAILURE);
- }
-
- /*
- * Enable SBBC interrupts
- */
- ddi_put32(softp->sbbc_handle, &(softp->sbbc_region->int_enable.reg),
- IOSRAM_SBBC_INT0|IOSRAM_SBBC_INT1);
-
- return (DDI_SUCCESS);
-}
-
-
-/*
- * iosram_remove_intr(iosramsoft_t *)
- */
-static int
-iosram_remove_intr(iosramsoft_t *softp)
-{
- IOSRAMLOG(2, "REMINTR: softp:%p instance:%d\n",
- softp, softp->instance, NULL, NULL);
-
- /*
- * Disable SBBC interrupts if SBBC is mapped in
- */
- if (softp->sbbc_region) {
- ddi_put32(softp->sbbc_handle,
- &(softp->sbbc_region->int_enable.reg), 0);
- }
-
- /*
- * Remove SBBC interrupt handler
- */
- ddi_remove_intr(softp->dip, 0, softp->real_iblk);
-
- /*
- * Remove soft interrupt handler
- */
- mutex_enter(&iosram_mutex);
- if (softp->softintr_id != NULL) {
- ddi_remove_softintr(softp->softintr_id);
- softp->softintr_id = NULL;
- }
- mutex_exit(&iosram_mutex);
-
- return (0);
-}
-
-
-/*
- * iosram_add_instance(iosramsoft_t *)
- * Must be called while holding iosram_mutex
- */
-static void
-iosram_add_instance(iosramsoft_t *new_softp)
-{
-#ifdef DEBUG
- int instance = new_softp->instance;
- iosramsoft_t *softp;
-#endif
-
- ASSERT(mutex_owned(&iosram_mutex));
-
-#if defined(DEBUG)
- /* Verify that this instance is not in the list */
- for (softp = iosram_instances; softp != NULL; softp = softp->next) {
- ASSERT(softp->instance != instance);
- }
-#endif
-
- /*
- * Add this instance to the list
- */
- if (iosram_instances != NULL) {
- iosram_instances->prev = new_softp;
- }
- new_softp->next = iosram_instances;
- new_softp->prev = NULL;
- iosram_instances = new_softp;
-}
-
-
-/*
- * iosram_remove_instance(int instance)
- * Must be called while holding iosram_mutex
- */
-static void
-iosram_remove_instance(int instance)
-{
- iosramsoft_t *softp;
-
- /*
- * Remove specified instance from the iosram_instances list so that
- * it can't be chosen for tunnel in future.
- */
- ASSERT(mutex_owned(&iosram_mutex));
-
- for (softp = iosram_instances; softp != NULL; softp = softp->next) {
- if (softp->instance == instance) {
- if (softp->next != NULL) {
- softp->next->prev = softp->prev;
- }
- if (softp->prev != NULL) {
- softp->prev->next = softp->next;
- }
- if (iosram_instances == softp) {
- iosram_instances = softp->next;
- }
-
- return;
- }
- }
-}
-
-
-/*
- * iosram_sema_acquire: Acquire hardware semaphore.
- * Return 0 if the semaphore could be acquired, or one of the following
- * possible values:
- * EAGAIN: there is a tunnel switch in progress
- * EBUSY: the semaphore was already "held"
- * ENXIO: an IO error occured (e.g. SBBC not mapped)
- * If old_value is not NULL, the location it points to will be updated
- * with the semaphore value read when attempting to acquire it.
- */
-int
-iosram_sema_acquire(uint32_t *old_value)
-{
- struct iosramsoft *softp;
- int rv;
- uint32_t sema_val;
-
- DPRINTF(2, ("IOSRAM: in iosram_sema_acquire\n"));
-
- mutex_enter(&iosram_mutex);
-
- /*
- * Disallow access if there is a tunnel switch in progress.
- */
- if (iosram_tswitch_active) {
- mutex_exit(&iosram_mutex);
- return (EAGAIN);
- }
-
- /*
- * Use current master IOSRAM for operation, fail if none is
- * currently active.
- */
- if ((softp = iosram_master) == NULL) {
- mutex_exit(&iosram_mutex);
- DPRINTF(1, ("IOSRAM: iosram_sema_acquire: no master\n"));
- return (ENXIO);
- }
-
- mutex_enter(&softp->intr_mutex);
-
- /*
- * Fail if SBBC region has not been mapped. This shouldn't
- * happen if we have a master IOSRAM, but we double-check.
- */
- if (softp->sbbc_region == NULL) {
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- DPRINTF(1, ("IOSRAM(%d): iosram_sema_acquire: "
- "SBBC not mapped\n", softp->instance));
- return (ENXIO);
- }
-
- /* read semaphore value */
- sema_val = IOSRAM_SEMA_RD(softp);
- if (old_value != NULL)
- *old_value = sema_val;
-
- if (IOSRAM_SEMA_IS_HELD(sema_val)) {
- /* semaphore was held by someone else */
- rv = EBUSY;
- } else {
- /* semaphore was not held, we just acquired it */
- rv = 0;
- }
-
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
-
- DPRINTF(1, ("IOSRAM(%d): iosram_sema_acquire: "
- "old value=0x%x rv=%d\n", softp->instance, sema_val, rv));
-
- return (rv);
-}
-
-
-/*
- * iosram_sema_release: Release hardware semaphore.
- * This function will "release" the hardware semaphore, and return 0 on
- * success. If an error occured, one of the following values will be
- * returned:
- * EAGAIN: there is a tunnel switch in progress
- * ENXIO: an IO error occured (e.g. SBBC not mapped)
- */
-int
-iosram_sema_release(void)
-{
- struct iosramsoft *softp;
-
- DPRINTF(2, ("IOSRAM: in iosram_sema_release\n"));
-
- mutex_enter(&iosram_mutex);
-
- /*
- * Disallow access if there is a tunnel switch in progress.
- */
- if (iosram_tswitch_active) {
- mutex_exit(&iosram_mutex);
- return (EAGAIN);
- }
-
- /*
- * Use current master IOSRAM for operation, fail if none is
- * currently active.
- */
- if ((softp = iosram_master) == NULL) {
- mutex_exit(&iosram_mutex);
- DPRINTF(1, ("IOSRAM: iosram_sema_release: no master\n"));
- return (ENXIO);
- }
-
- mutex_enter(&softp->intr_mutex);
-
- /*
- * Fail if SBBC region has not been mapped in. This shouldn't
- * happen if we have a master IOSRAM, but we double-check.
- */
- if (softp->sbbc_region == NULL) {
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
- DPRINTF(1, ("IOSRAM(%d): iosram_sema_release: "
- "SBBC not mapped\n", softp->instance));
- return (ENXIO);
- }
-
- /* Release semaphore by clearing our semaphore register */
- IOSRAM_SEMA_WR(softp, 0);
-
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
-
- DPRINTF(1, ("IOSRAM(%d): iosram_sema_release: success\n",
- softp->instance));
-
- return (0);
-}
-
-
-#if defined(IOSRAM_LOG)
-void
-iosram_log(caddr_t fmt, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4)
-{
- uint32_t seq;
- iosram_log_t *logp;
-
- mutex_enter(&iosram_log_mutex);
-
- seq = iosram_logseq++;
- logp = &iosram_logbuf[seq % IOSRAM_MAXLOG];
- logp->seq = seq;
- logp->tstamp = ddi_get_lbolt();
- logp->fmt = fmt;
- logp->arg1 = a1;
- logp->arg2 = a2;
- logp->arg3 = a3;
- logp->arg4 = a4;
-
- mutex_exit(&iosram_log_mutex);
-
- if (iosram_log_print) {
- cmn_err(CE_CONT, "#%x @%lx ", logp->seq, logp->tstamp);
- if (logp->fmt) {
- cmn_err(CE_CONT, logp->fmt, logp->arg1, logp->arg2,
- logp->arg3, logp->arg4);
- if (logp->fmt[strlen(logp->fmt)-1] != '\n') {
- cmn_err(CE_CONT, "\n");
- }
- } else {
- cmn_err(CE_CONT, "fmt:%p args: %lx %lx %lx %lx\n",
- (void *)logp->fmt, logp->arg1, logp->arg2,
- logp->arg3, logp->arg4);
- }
- }
-}
-#endif /* IOSRAM_LOG */
-
-
-#if defined(DEBUG)
-/*
- * iosram_get_keys(buf, len)
- * Return IOSRAM TOC in the specified buffer
- */
-static int
-iosram_get_keys(iosram_toc_entry_t *bufp, uint32_t *len)
-{
- struct iosram_chunk *chunkp;
- int error = 0;
- int i;
- int cnt = (*len) / sizeof (iosram_toc_entry_t);
-
- IOSRAMLOG(2, "iosram_get_keys(bufp:%p *len:%x)\n", bufp, *len, NULL,
- NULL);
-
- /*
- * Copy data while holding the lock to prevent any data
- * corruption or invalid pointer dereferencing.
- */
- mutex_enter(&iosram_mutex);
-
- if (iosram_master == NULL) {
- error = EIO;
- } else {
- for (i = 0, chunkp = chunks; i < nchunks && i < cnt;
- i++, chunkp++) {
- bufp[i].key = chunkp->toc_data.key;
- bufp[i].off = chunkp->toc_data.off;
- bufp[i].len = chunkp->toc_data.len;
- bufp[i].unused = chunkp->toc_data.unused;
- }
- *len = i * sizeof (iosram_toc_entry_t);
- }
-
- mutex_exit(&iosram_mutex);
- return (error);
-}
-
-
-/*
- * iosram_print_state(instance)
- */
-static void
-iosram_print_state(int instance)
-{
- struct iosramsoft *softp;
- char pn[MAXNAMELEN];
-
- if (instance < 0) {
- softp = iosram_master;
- } else {
- softp = ddi_get_soft_state(iosramsoft_statep, instance);
- }
-
- if (softp == NULL) {
- cmn_err(CE_CONT, "iosram_print_state: Can't find instance %d\n",
- instance);
- return;
- }
- instance = softp->instance;
-
- mutex_enter(&iosram_mutex);
- mutex_enter(&softp->intr_mutex);
-
- cmn_err(CE_CONT, "iosram_print_state(%d): ... %s\n", instance,
- ((softp == iosram_master) ? "MASTER" : "SLAVE"));
-
- (void) ddi_pathname(softp->dip, pn);
- cmn_err(CE_CONT, " pathname:%s\n", pn);
- cmn_err(CE_CONT, " instance:%d portid:%d iosramlen:0x%x\n",
- softp->instance, softp->portid, softp->iosramlen);
- cmn_err(CE_CONT, " softp:%p handle:%p iosramp:%p\n", (void *)softp,
- (void *)softp->handle, (void *)softp->iosramp);
- cmn_err(CE_CONT, " state:0x%x tswitch_ok:%x tswitch_fail:%x\n",
- softp->state, softp->tswitch_ok, softp->tswitch_fail);
- cmn_err(CE_CONT, " softintr_id:%p intr_busy:%x intr_pending:%x\n",
- (void *)softp->softintr_id, softp->intr_busy, softp->intr_pending);
-
- mutex_exit(&softp->intr_mutex);
- mutex_exit(&iosram_mutex);
-}
-
-
-/*
- * iosram_print_stats()
- */
-static void
-iosram_print_stats()
-{
- uint32_t calls;
-
- cmn_err(CE_CONT, "iosram_stats:\n");
- calls = iosram_stats.read;
- cmn_err(CE_CONT, " read ... calls:%x bytes:%lx avg_sz:%x\n",
- calls, iosram_stats.bread,
- (uint32_t)((calls != 0) ? (iosram_stats.bread/calls) : 0));
-
- calls = iosram_stats.write;
- cmn_err(CE_CONT, " write ... calls:%x bytes:%lx avg_sz:%x\n",
- calls, iosram_stats.bwrite,
- (uint32_t)((calls != 0) ? (iosram_stats.bwrite/calls) : 0));
-
- cmn_err(CE_CONT, " intr recv (real:%x soft:%x) sent:%x cback:%x\n",
- iosram_stats.intr_recv, iosram_stats.sintr_recv,
- iosram_stats.intr_send, iosram_stats.callbacks);
-
- cmn_err(CE_CONT, " tswitch: %x getflag:%x setflag:%x\n",
- iosram_stats.tswitch, iosram_stats.getflag,
- iosram_stats.setflag);
-
- cmn_err(CE_CONT, " iosram_rw_active_max: %x\n", iosram_rw_active_max);
-}
-
-
-static void
-iosram_print_cback()
-{
- iosram_chunk_t *chunkp;
- int i;
-
- /*
- * Print callback handlers
- */
- mutex_enter(&iosram_mutex);
-
- cmn_err(CE_CONT, "IOSRAM callbacks:\n");
- for (i = 0, chunkp = chunks; i < nchunks; i++, chunkp++) {
- if (chunkp->cback.handler) {
- cmn_err(CE_CONT, " %2d: key:0x%x hdlr:%p arg:%p "
- "busy:%d unreg:%d\n", i, chunkp->toc_data.key,
- (void *)chunkp->cback.handler,
- (void *)chunkp->cback.arg,
- chunkp->cback.busy, chunkp->cback.unregister);
- }
- }
- mutex_exit(&iosram_mutex);
-}
-
-
-static void
-iosram_print_flags()
-{
- int i;
- uint32_t *keys;
- iosram_flags_t *flags;
-
- mutex_enter(&iosram_mutex);
-
- if (iosram_master == NULL) {
- mutex_exit(&iosram_mutex);
- cmn_err(CE_CONT, "IOSRAM Flags: not accessible\n");
- return;
- }
-
- keys = kmem_alloc(nchunks * sizeof (uint32_t), KM_SLEEP);
- flags = kmem_alloc(nchunks * sizeof (iosram_flags_t), KM_SLEEP);
-
- for (i = 0; i < nchunks; i++) {
- keys[i] = chunks[i].toc_data.key;
- ddi_rep_get8(iosram_handle, (uint8_t *)&(flags[i]),
- (uint8_t *)(chunks[i].flagsp), sizeof (iosram_flags_t),
- DDI_DEV_AUTOINCR);
- }
-
- mutex_exit(&iosram_mutex);
-
- cmn_err(CE_CONT, "IOSRAM Flags:\n");
- for (i = 0; i < nchunks; i++) {
- cmn_err(CE_CONT,
- " %2d: key: 0x%x data_valid:%x int_pending:%x\n",
- i, keys[i], flags[i].data_valid, flags[i].int_pending);
- }
-
- kmem_free(keys, nchunks * sizeof (uint32_t));
- kmem_free(flags, nchunks * sizeof (iosram_flags_t));
-}
-
-
-/*PRINTFLIKE1*/
-static void
-iosram_dprintf(const char *fmt, ...)
-{
- char msg_buf[256];
- va_list adx;
-
- va_start(adx, fmt);
- (void) vsprintf(msg_buf, fmt, adx);
- va_end(adx);
-
- cmn_err(CE_CONT, "%s", msg_buf);
-}
-#endif /* DEBUG */
-
-
-#if IOSRAM_LOG
-/*
- * iosram_print_log(int cnt)
- * Print last few entries of the IOSRAM log in reverse order
- */
-static void
-iosram_print_log(int cnt)
-{
- int i;
-
- if (cnt <= 0) {
- cnt = 20;
- } else if (cnt > IOSRAM_MAXLOG) {
- cnt = IOSRAM_MAXLOG;
- }
-
-
- cmn_err(CE_CONT,
- "\niosram_logseq: 0x%x lbolt: %lx iosram_log_level:%x\n",
- iosram_logseq, ddi_get_lbolt(), iosram_log_level);
- cmn_err(CE_CONT, "iosram_logbuf: %p max entries:0x%x\n",
- (void *)iosram_logbuf, IOSRAM_MAXLOG);
- for (i = iosram_logseq; --i >= 0 && --cnt >= 0; ) {
- iosram_log_t *logp;
-
- mutex_enter(&iosram_log_mutex);
-
- logp = &iosram_logbuf[i %IOSRAM_MAXLOG];
- cmn_err(CE_CONT, "#%x @%lx ", logp->seq, logp->tstamp);
-
- if (logp->fmt) {
- cmn_err(CE_CONT, logp->fmt, logp->arg1, logp->arg2,
- logp->arg3, logp->arg4);
- if (logp->fmt[strlen(logp->fmt)-1] != '\n') {
- cmn_err(CE_CONT, "\n");
- }
- } else {
- cmn_err(CE_CONT, "fmt:%p args: %lx %lx %lx %lx\n",
- (void *)logp->fmt, logp->arg1, logp->arg2,
- logp->arg3, logp->arg4);
- }
-
- mutex_exit(&iosram_log_mutex);
- }
-}
-#endif /* IOSRAM_LOG */
diff --git a/usr/src/uts/sun4u/starcat/io/mboxsc.c b/usr/src/uts/sun4u/starcat/io/mboxsc.c
deleted file mode 100644
index df22464f91..0000000000
--- a/usr/src/uts/sun4u/starcat/io/mboxsc.c
+++ /dev/null
@@ -1,2460 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * This file contains the implementation of the mboxsc module, a mailbox layer
- * built upon the Starcat IOSRAM driver.
- */
-
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/modctl.h>
-#include <sys/errno.h>
-#include <sys/ksynch.h>
-#include <sys/kmem.h>
-#include <sys/varargs.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/cmn_err.h>
-#include <sys/debug.h>
-#include <sys/sysmacros.h>
-
-#include <sys/iosramreg.h>
-#include <sys/iosramio.h>
-#include <sys/mboxsc.h>
-#include <sys/mboxsc_impl.h>
-
-/*
- * Debugging facility
- */
-#define DBGACT_NONE (0x00000000)
-#define DBGACT_BREAK (0x00000001)
-#define DBGACT_SHOWPOS (0x00000002)
-#define DBGACT_DEFAULT DBGACT_NONE
-
-#define DBG_DEV (0x00000001)
-#define DBG_CALLS (0x00000002)
-#define DBG_RETS (0x00000004)
-#define DBG_ARGS (0x00000008)
-#define DBG_KMEM (0x00000010)
-#define DBG_ALL (0xFFFFFFFF)
-
-#ifdef DEBUG
-static uint32_t mboxsc_debug_mask = 0x00000000;
-#define DPRINTF0(class, action, fmt) \
- mboxsc_dprintf(__FILE__, __LINE__, (class), (action), (fmt))
-#define DPRINTF1(class, action, fmt, arg1) \
- mboxsc_dprintf(__FILE__, __LINE__, (class), (action), (fmt),\
- (arg1))
-#define DPRINTF2(class, action, fmt, arg1, arg2) \
- mboxsc_dprintf(__FILE__, __LINE__, (class), (action), (fmt),\
- (arg1), (arg2))
-#define DPRINTF3(class, action, fmt, arg1, arg2, arg3) \
- mboxsc_dprintf(__FILE__, __LINE__, (class), (action), (fmt),\
- (arg1), (arg2), (arg3))
-#define DPRINTF4(class, action, fmt, arg1, arg2, arg3, arg4) \
- mboxsc_dprintf(__FILE__, __LINE__, (class), (action), (fmt),\
- (arg1), (arg2), (arg3), (arg4))
-#define DPRINTF5(class, action, fmt, arg1, arg2, arg3, arg4, arg5) \
- mboxsc_dprintf(__FILE__, __LINE__, (class), (action), (fmt),\
- (arg1), (arg2), (arg3), (arg4), (arg5))
-#else /* DEBUG */
-#define DPRINTF0(class, action, fmt)
-#define DPRINTF1(class, action, fmt, arg1)
-#define DPRINTF2(class, action, fmt, arg1, arg2)
-#define DPRINTF3(class, action, fmt, arg1, arg2, arg3)
-#define DPRINTF4(class, action, fmt, arg1, arg2, arg3, arg4)
-#define DPRINTF5(class, action, fmt, arg1, arg2, arg3, arg4, arg5)
-#endif /* DEBUG */
-
-/*
- * Basic constants
- */
-#ifndef TRUE
-#define TRUE (1)
-#endif /* TRUE */
-#ifndef FALSE
-#define FALSE (0)
-#endif /* FALSE */
-
-
-/*
- * Whenever mboxsc_init is called to create a new mailbox, an instance of
- * mboxsc_mbox_t is created and inserted into a hash table to maintain
- * various information about the mailbox. The mbox_state, mbox_refcount, and
- * mbox_wait fields are all protected by the global mboxsc_lock mutex.
- * If lock contention between mailboxes becomes an issue, each mailbox will
- * need to be given its own mutex to protect the mbox_wait, mbox_state,
- * and mbox_update_wait fields. The mbox_refcount field will probably need to
- * remain under global protection, however, since it is used to keep track of
- * the number of threads sleeping inside the mailbox's various synchronization
- * mechanisms and would consequently be difficult to protect using those same
- * mechanisms.
- */
-typedef struct mboxsc_mbox {
- uint32_t mbox_key;
- int mbox_direction;
- void (*mbox_callback)(void);
- uint32_t mbox_length;
- uint16_t mbox_refcount;
- uint16_t mbox_state;
- kcondvar_t mbox_wait;
- mboxsc_msghdr_t mbox_header;
- struct mboxsc_mbox *mbox_hash_next;
-} mboxsc_mbox_t;
-
-/*
- * Various state flags that can be set on a mailbox. Multiple states may
- * be active at the same time.
- */
-#define STATE_IDLE (0x0000)
-#define STATE_WRITING (0x0001)
-#define STATE_READING (0x0002)
-#define STATE_HDRVALID (0x0004)
-
-/*
- * Timeout periods for mboxsc_putmsg and mboxsc_getmsg, converted to ticks
- * from the microsecond values found in mboxsc_impl.h.
- */
-#define EAGAIN_POLL (drv_usectohz(MBOXSC_EAGAIN_POLL_USECS))
-#define PUTMSG_POLL (drv_usectohz(MBOXSC_PUTMSG_POLL_USECS))
-#define HWLOCK_POLL (drv_usectohz(MBOXSC_HWLOCK_POLL_USECS))
-#define LOOP_WARN_INTERVAL (drv_usectohz(MBOXSC_USECS_PER_SECOND * 15))
-
-/*
- * Various tests that are performed on message header fields.
- */
-#define IS_UNSOLICITED_TYPE(type) ((type) != MBOXSC_MSG_REPLY)
-#define MSG_TYPE_MATCHES(type, msgp) \
- (((type) == 0) || ((type) & (msgp)->msg_type))
-#define MSG_CMD_MATCHES(cmd, msgp) \
- (((cmd) == 0) || ((cmd) == (msgp)->msg_cmd))
-#define MSG_TRANSID_MATCHES(tid, msgp) \
- (((tid) == 0) || ((tid) == (msgp)->msg_transid))
-
-/*
- * This macro can be used to determine the size of any field in the message
- * header (or any other struct, for that matter).
- */
-#define FIELD_SIZE(type, field) (sizeof (((type *)0)->field))
-
-/*
- * Mask used when generating unique transaction ID values.
- * This arbitrarily chosen value will be OR'd together with
- * a counter for each successive internally-generated transaction ID.
- */
-#define TRANSID_GEN_MASK (0xFFC0000000000000)
-
-/*
- * All existing mailboxes are stored in a hash table with HASHTBL_SIZE
- * entries so they can be rapidly accessed by their key values.
- */
-#define HASHTBL_SIZE (32)
-#define HASH_KEY(key) ((((key) >> 24) ^ ((key) >> 16) ^ ((key) >> 9) ^\
- (key)) & (HASHTBL_SIZE - 1));
-
-/*
- * Unfortunately, it is necessary to calculate checksums on data split up
- * amongst different buffers in some cases. Consequently, mboxsc_checksum
- * accepts a "seed" value as one of its parameters. When first starting a
- * checksum calculation, the seed should be 0.
- */
-#define CHKSUM_INIT (0)
-
-/*
- * local variables
- */
-static kmutex_t mboxsc_lock;
-static mboxsc_mbox_t *mboxsc_hash_table[HASHTBL_SIZE];
-static uint32_t mboxsc_flaglock_count;
-static uint32_t mboxsc_active_version = MBOXSC_PROTOCOL_VERSION;
-static kcondvar_t mboxsc_dereference_cv;
-
-/*
- * Structures from modctl.h used for loadable module support.
- * The mboxsc API is a "miscellaneous" module.
- */
-extern struct mod_ops mod_miscops;
-
-static struct modlmisc modlmisc = {
- &mod_miscops,
- "IOSRAM Mailbox API 'mboxsc'",
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- (void *)&modlmisc,
- NULL
-};
-
-/*
- * Prototypes for local functions
- */
-static void mboxsc_iosram_callback(void *arg);
-static void mboxsc_hdrchange_callback(void);
-static int mboxsc_add_mailbox(mboxsc_mbox_t *mailboxp);
-static void mboxsc_close_mailbox(mboxsc_mbox_t *mailboxp);
-static void mboxsc_hashinsert_mailbox(mboxsc_mbox_t *mailboxp);
-static mboxsc_mbox_t *mboxsc_hashfind_mailbox_by_key(uint32_t key);
-static mboxsc_mbox_t *mboxsc_hashremove_mailbox_by_key(uint32_t key);
-static mboxsc_chksum_t mboxsc_checksum(mboxsc_chksum_t seed, uint8_t *buf,
- uint32_t length);
-static int mboxsc_lock_flags(uint8_t mandatory, clock_t deadline);
-static int mboxsc_unlock_flags(uint8_t mandatory);
-static int mboxsc_timed_read(clock_t deadline, uint32_t key,
- uint32_t off, uint32_t len, caddr_t dptr);
-static int mboxsc_timed_write(clock_t deadline, uint32_t key,
- uint32_t off, uint32_t len, caddr_t dptr);
-static int mboxsc_timed_get_flag(clock_t deadline, uint32_t key,
- uint8_t *data_validp, uint8_t *int_pendingp);
-static int mboxsc_timed_set_flag(clock_t deadline, uint32_t key,
- uint8_t data_valid, uint8_t int_pending);
-static int mboxsc_timed_send_intr(clock_t deadline);
-static int mboxsc_expire_message(uint32_t key, int *resultp);
-static uint64_t mboxsc_generate_transid(uint64_t prev_transid);
-static void mboxsc_reference_mailbox(mboxsc_mbox_t *mailboxp);
-static void mboxsc_dereference_mailbox(mboxsc_mbox_t *mailboxp);
-#ifdef DEBUG
-/*PRINTFLIKE5*/
-static void mboxsc_dprintf(const char *file, int line,
- uint32_t class, uint32_t action, const char *fmt, ...);
-int mboxsc_debug(int cmd, void *arg);
-#endif /* DEBUG */
-
-
-/*
- * _init
- *
- * Loadable module support routine. Initializes global lock and hash table.
- */
-int
-_init(void)
-{
- int i;
- uint32_t sms_version;
- int error = 0;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "_init called\n");
-
- /*
- * Initialize all module resources.
- */
- mutex_init(&mboxsc_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&mboxsc_dereference_cv, NULL, CV_DRIVER, NULL);
-
- for (i = 0; i < HASHTBL_SIZE; i++) {
- mboxsc_hash_table[i] = NULL;
- }
- mboxsc_flaglock_count = 0;
-
- if (mod_install(&modlinkage) != 0) {
- goto failed;
- }
-
- /*
- * Set the os_mbox_version field in the IOSRAM header to indicate the
- * highest Mailbox Protocol version we support
- */
- error = iosram_hdr_ctrl(IOSRAM_HDRCMD_SET_OS_MBOX_VER,
- (void *)MBOXSC_PROTOCOL_VERSION);
- if (error != 0) {
- goto failed;
- }
-
- /*
- * Read the sms_mbox_version field in the IOSRAM header to determine
- * what the greatest commonly supported version is.
- */
- error = iosram_hdr_ctrl(IOSRAM_HDRCMD_GET_SMS_MBOX_VER,
- (void *)&sms_version);
- if (error != 0) {
- goto failed;
- }
- mboxsc_active_version = MIN(MBOXSC_PROTOCOL_VERSION, sms_version);
- DPRINTF2(DBG_DEV, DBGACT_DEFAULT,
- "sms version: %d, active version: %d\n", sms_version,
- mboxsc_active_version);
-
- /*
- * Register a callback with the IOSRAM driver to receive notification of
- * changes to the IOSRAM header, in case the sms_mbox_version field
- * changes.
- */
- error = iosram_hdr_ctrl(IOSRAM_HDRCMD_REG_CALLBACK,
- (void *)mboxsc_hdrchange_callback);
- if (error != 0) {
- goto failed;
- }
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "_init ret: 0x%08x\n", error);
- return (0);
-
- /*
- * If initialization fails, uninitialize resources.
- */
-failed:
- mutex_destroy(&mboxsc_lock);
- cv_destroy(&mboxsc_dereference_cv);
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "_init ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * _fini
- *
- * Loadable module support routine. Closes all mailboxes and releases all
- * resources.
- */
-int
-_fini(void)
-{
- int i;
- int error = 0;
- mboxsc_mbox_t *mailboxp;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "_fini called\n");
-
- /*
- * Attempt to remove the module. If successful, close all mailboxes
- * and deallocate the global lock.
- */
- error = mod_remove(&modlinkage);
- if (error == 0) {
- mutex_enter(&mboxsc_lock);
-
- (void) iosram_hdr_ctrl(IOSRAM_HDRCMD_REG_CALLBACK, NULL);
-
- for (i = 0; i < HASHTBL_SIZE; i++) {
- while (mboxsc_hash_table[i] != NULL) {
- mailboxp = mboxsc_hash_table[i];
- mboxsc_close_mailbox(mailboxp);
- }
- }
- mutex_exit(&mboxsc_lock);
- mutex_destroy(&mboxsc_lock);
- cv_destroy(&mboxsc_dereference_cv);
- }
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "_fini ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * _info
- *
- * Loadable module support routine.
- */
-int
-_info(struct modinfo *modinfop)
-{
- int error = 0;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "_info called\n");
-
- error = mod_info(&modlinkage, modinfop);
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "_info ret: 0x%08x\n", error);
-
- return (error);
-}
-
-/*
- * mboxsc_init
- *
- * Attempts to create a new mailbox.
- */
-int
-mboxsc_init(uint32_t key, int direction, void (*event_handler)(void))
-{
- int error = 0;
- mboxsc_mbox_t *mailboxp;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_init called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "direction = %d\n", direction);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "event_handlerp = %p\n",
- (void *)event_handler);
-
- /*
- * Check for valid direction and callback specification.
- */
- if (((direction != MBOXSC_MBOX_IN) && (direction != MBOXSC_MBOX_OUT)) ||
- ((event_handler != NULL) && (direction != MBOXSC_MBOX_IN))) {
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_init ret: 0x%08x\n",
- EINVAL);
- return (EINVAL);
- }
-
- /*
- * Allocate memory for the mailbox structure and initialize all
- * caller-provided fields.
- */
- mailboxp = (mboxsc_mbox_t *)kmem_zalloc(sizeof (mboxsc_mbox_t),
- KM_SLEEP);
- DPRINTF2(DBG_KMEM, DBGACT_DEFAULT, "kmem_zalloc(%lu) = %p\n",
- sizeof (mboxsc_mbox_t), (void *)mailboxp);
- mailboxp->mbox_key = key;
- mailboxp->mbox_direction = direction;
- mailboxp->mbox_callback = event_handler;
-
- /*
- * Attempt to add the mailbox. If unsuccessful, free the allocated
- * memory.
- */
- mutex_enter(&mboxsc_lock);
- error = mboxsc_add_mailbox(mailboxp);
- mutex_exit(&mboxsc_lock);
-
- if (error != 0) {
- DPRINTF2(DBG_KMEM, DBGACT_DEFAULT, "kmem_free(%p, %lu)\n",
- (void *)mailboxp, sizeof (mboxsc_mbox_t));
- kmem_free(mailboxp, sizeof (mboxsc_mbox_t));
- }
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_init ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * mboxsc_fini
- *
- * Closes the mailbox with the indicated key, if it exists.
- */
-int
-mboxsc_fini(uint32_t key)
-{
- int error = 0;
- mboxsc_mbox_t *mailboxp;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_fini called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
-
- /*
- * Attempt to close the mailbox.
- */
- mutex_enter(&mboxsc_lock);
- mailboxp = mboxsc_hashfind_mailbox_by_key(key);
- if (mailboxp == NULL) {
- error = EBADF;
- } else {
- while (mailboxp->mbox_refcount != 0) {
- cv_wait(&mboxsc_dereference_cv, &mboxsc_lock);
- }
- mboxsc_close_mailbox(mailboxp);
- }
- mutex_exit(&mboxsc_lock);
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_fini ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * mboxsc_putmsg
- *
- * Attempt to place a message into an outbound mailbox and signal the
- * recipient. A successful return (0) indicates that the message was
- * successfully delivered.
- */
-int
-mboxsc_putmsg(uint32_t key, uint32_t type, uint32_t cmd, uint64_t *transidp,
- uint32_t length, void *datap, clock_t timeout)
-{
- int i;
- int error = 0;
- int result;
- int lock_held = 0;
- int unlock_err;
- uint8_t data_valid;
- clock_t deadline;
- clock_t remainder;
- mboxsc_chksum_t checksum;
- mboxsc_mbox_t *mailboxp;
- mboxsc_msghdr_t header;
-
-#ifdef DEBUG /* because lint whines about if stmts without consequents */
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_putmsg called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "type = 0x%x\n", type);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "cmd = 0x%x\n", cmd);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "transidp = %p\n", (void *)transidp);
- if (transidp != NULL) {
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "*transidp = 0x%016lx\n",
- *transidp);
- }
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "length = 0x%x\n", length);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "datap = %p\n", datap);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "timeout = %ld\n", timeout);
-#endif /* DEBUG */
-
- /*
- * Perform some basic sanity checks on the message.
- */
- for (i = 0; i < MBOXSC_NUM_MSG_TYPES; i++) {
- if (type == (1 << i)) {
- break;
- }
- }
- if ((i == MBOXSC_NUM_MSG_TYPES) || (cmd == 0) ||
- ((datap == NULL) && (length != 0)) ||
- (timeout < MBOXSC_PUTMSG_MIN_TIMEOUT_MSECS) ||
- (timeout > MBOXSC_PUTMSG_MAX_TIMEOUT_MSECS)) {
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_putmsg ret: 0x%08x\n", EINVAL);
- return (EINVAL);
- }
-
- /*
- * Initialize the header structure with values provided by the caller.
- */
- header.msg_version = mboxsc_active_version;
- header.msg_type = type;
- header.msg_cmd = cmd;
- header.msg_length = MBOXSC_MSGHDR_SIZE + length;
- if (transidp != NULL) {
- header.msg_transid = *transidp;
- } else {
- header.msg_transid = 0;
- }
-
- /*
- * Perform additional sanity checks on the mailbox and message.
- * Make sure that the specified mailbox really exists, that the
- * given message will fit in it, and that the current message's
- * transaction ID isn't the same as the last message's transaction
- * ID unless both messages are replies (it's okay, necessary even,
- * to reuse a transaction ID when resending a failed reply message,
- * but that is the only case in which it is permissible).
- */
- mutex_enter(&mboxsc_lock);
- mailboxp = mboxsc_hashfind_mailbox_by_key(key);
-
- if (mailboxp == NULL) {
- error = EBADF;
- } else if ((mailboxp->mbox_direction != MBOXSC_MBOX_OUT) ||
- (length + MBOXSC_PROTOCOL_SIZE > mailboxp->mbox_length) ||
- ((header.msg_transid == mailboxp->mbox_header.msg_transid) &&
- ((type & mailboxp->mbox_header.msg_type) != MBOXSC_MSG_REPLY) &&
- (header.msg_transid != 0))) {
- error = EINVAL;
- }
-
- if (error != 0) {
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_putmsg ret: 0x%08x\n", error);
- return (error);
- }
-
- /*
- * If the message's transaction ID is set to 0, generate a unique
- * transaction ID and copy it into the message header. If the message
- * is successfully delivered and transidp != NULL, we'll copy this new
- * transid into *transidp later.
- */
- if (header.msg_transid == 0) {
- header.msg_transid =
- mboxsc_generate_transid(mailboxp->mbox_header.msg_transid);
- }
-
- /*
- * Don't allow mboxsc_putmsg to attempt to place a message for
- * longer than the caller's timeout.
- */
- deadline = ddi_get_lbolt() +
- drv_usectohz(timeout * MBOXSC_USECS_PER_MSEC);
-
- /*
- * Increment the reference count on the mailbox to keep it from being
- * closed, and wait for it to become available.
- */
- mboxsc_reference_mailbox(mailboxp);
- remainder = 1;
- while ((mailboxp->mbox_state & STATE_WRITING) &&
- (remainder > 0)) {
- remainder = cv_timedwait_sig(&(mailboxp->mbox_wait),
- &mboxsc_lock, deadline);
- }
-
- /*
- * Check to see whether or not the mailbox became available. If it
- * did not, decrement its reference count and return an error to the
- * caller.
- */
- if (remainder == -1) {
- error = ENOSPC;
- } else if (remainder == 0) {
- error = EINTR;
- }
-
- if (error != 0) {
- mboxsc_dereference_mailbox(mailboxp);
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_putmsg ret: 0x%08x\n", error);
- return (error);
- }
-
- /*
- * Since the message is valid and we're going to try to write it to
- * IOSRAM, record its header for future reference (e.g. to make sure the
- * next message doesn't incorrectly use the same transID).
- */
- bcopy(&header, &(mailboxp->mbox_header), MBOXSC_MSGHDR_SIZE);
-
- /*
- * Flag the mailbox as being in use and release the global lock.
- */
- mailboxp->mbox_state |= STATE_WRITING;
- mutex_exit(&mboxsc_lock);
-
- /*
- * Calculate the message checksum using the header and the data.
- */
- checksum = mboxsc_checksum(CHKSUM_INIT, (uint8_t *)&header,
- MBOXSC_MSGHDR_SIZE);
- checksum = mboxsc_checksum(checksum, (uint8_t *)datap, length);
-
- /*
- * Attempt to write the message and checksum to IOSRAM until successful,
- * or as long as time remains and no errors other than EAGAIN are
- * returned from any call to the IOSRAM driver in case there is a tunnel
- * switch in progress.
- */
- error = mboxsc_timed_write(deadline, key, MBOXSC_MSGHDR_OFFSET,
- MBOXSC_MSGHDR_SIZE, (caddr_t)&header);
-
- if (error == 0) {
- error = mboxsc_timed_write(deadline, key, MBOXSC_DATA_OFFSET,
- length, (caddr_t)datap);
- }
-
- if (error == 0) {
- error = mboxsc_timed_write(deadline, key, header.msg_length,
- MBOXSC_CHKSUM_SIZE, (caddr_t)&checksum);
- }
-
- /*
- * Lock the flags before setting data_valid. This isn't strictly
- * necessary for correct protocol operation, but it gives us a chance to
- * verify that the flags lock is functional before we commit to sending
- * the message.
- */
- if (error == 0) {
- error = mboxsc_lock_flags(FALSE, deadline);
- if (error == 0) {
- lock_held = 1;
- } else if (error == EBUSY) {
- error = EAGAIN;
- }
- }
-
- if (error == 0) {
- error = mboxsc_timed_set_flag(deadline, key, IOSRAM_DATA_VALID,
- IOSRAM_INT_TO_SSC);
- }
-
- /*
- * Unlock the flags. If an error is encountered, only return it if
- * another error hasn't been encountered previously.
- */
- if (lock_held) {
- unlock_err = mboxsc_unlock_flags(TRUE);
- if ((unlock_err != 0) && ((error == 0) || (error == EAGAIN))) {
- error = unlock_err;
- }
- }
-
- /*
- * If time ran out or an IOSRAM call failed, notify other callers that
- * the mailbox is available, decrement its reference count, and return
- * an error.
- */
- if (error != 0) {
- ASSERT((error != EINVAL) && (error != EMSGSIZE));
- mutex_enter(&mboxsc_lock);
- mailboxp->mbox_state &= ~STATE_WRITING;
- cv_broadcast(&(mailboxp->mbox_wait));
- mboxsc_dereference_mailbox(mailboxp);
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_putmsg ret: 0x%08x\n", error);
- return (error);
- }
-
- /*
- * Send an interrupt to the remote mailbox interface to announce the
- * presence of a new, valid message.
- */
- error = mboxsc_timed_send_intr(deadline);
-
- /*
- * Wait until either the data_valid flag is set INVALID by the
- * remote client or time runs out. Since we're calling delay as
- * a part of polling the flag anyway, we don't really need to do
- * the usual continuous retry if iosram_get_flag returns EAGAIN.
- */
- data_valid = IOSRAM_DATA_VALID;
- if (error == DDI_SUCCESS) {
- do {
- delay(MIN(PUTMSG_POLL, deadline - ddi_get_lbolt()));
- error = iosram_get_flag(key, &data_valid, NULL);
- } while ((data_valid == IOSRAM_DATA_VALID) &&
- ((error == EAGAIN) || (error == 0)) &&
- (deadline - ddi_get_lbolt() >= 0));
- }
-
- /*
- * If the data_valid flag was set to INVALID by the other side, the
- * message was successfully transmitted. If it wasn't, but there
- * weren't any IOSRAM errors, the operation timed out. If there was a
- * problem with the IOSRAM, pass that info back to the caller.
- */
- if (data_valid == IOSRAM_DATA_INVALID) {
- result = 0;
- } else if ((error == 0) || (error == DDI_FAILURE)) {
- result = ETIMEDOUT;
- } else {
- ASSERT(error != EINVAL);
- result = error;
- }
-
- /*
- * If the message has not been picked up, expire it. Note that this may
- * actually result in detecting successful message delivery if the SC
- * picks it up at the last moment. If expiration fails due to an error,
- * return an error to the user even if the message appears to have
- * been successfully delivered.
- */
- if (data_valid == IOSRAM_DATA_VALID) {
- error = mboxsc_expire_message(key, &result);
- if ((error != 0) && ((result == 0) || (result == ETIMEDOUT))) {
- result = error;
- }
- }
-
- /*
- * If the message was successfully delivered, and we generated a
- * transaction ID for the caller, and the caller wants to know what it
- * was, give it to them.
- */
- if ((result == 0) && (transidp != NULL) && (*transidp == 0)) {
- *transidp = header.msg_transid;
- }
-
- /*
- * Regardless of whether the message was successfully transmitted or
- * not, notify other callers that the mailbox is available and decrement
- * its reference count.
- */
- mutex_enter(&mboxsc_lock);
- mailboxp->mbox_state &= ~STATE_WRITING;
- cv_broadcast(&(mailboxp->mbox_wait));
- mboxsc_dereference_mailbox(mailboxp);
- mutex_exit(&mboxsc_lock);
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_putmsg ret: 0x%08x\n",
- result);
- return (result);
-}
-
-/*
- * mboxsc_getmsg
- *
- * Attempt to retrieve a message from the mailbox with the given key that
- * matches values provided in msgp. A successful return (0) indicates that
- * a message matching the caller's request was successfully received within
- * timeout milliseconds. If a message matching the caller's request is
- * detected, but can't be successfully read, an error will be returned even
- * if the caller's timeout hasn't expired.
- */
-int
-mboxsc_getmsg(uint32_t key, uint32_t *typep, uint32_t *cmdp, uint64_t *transidp,
- uint32_t *lengthp, void *datap, clock_t timeout)
-{
- int error = 0;
- uint32_t datalen;
- uint8_t data_valid;
- uint8_t lock_held;
- mboxsc_chksum_t read_checksum;
- mboxsc_chksum_t calc_checksum;
- uint64_t read_transid;
- clock_t deadline;
- clock_t remainder;
- mboxsc_mbox_t *mailboxp;
- mboxsc_msghdr_t header;
-
-#ifdef DEBUG /* because lint whines about if stmts without consequents */
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_getmsg called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "typep = %p\n", (void *)typep);
- if (typep != NULL) {
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "*typep = 0x%x\n", *typep);
- }
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "cmdp = %p\n", (void *)cmdp);
- if (cmdp != NULL) {
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "*cmdp = 0x%x\n", *cmdp);
- }
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "transidp = %p\n", (void *)transidp);
- if (transidp != NULL) {
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "*transidp = 0x%lx\n",
- *transidp);
- }
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "lengthp = %p\n", (void *)lengthp);
- if (lengthp != NULL) {
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "*lengthp = 0x%x\n",
- *lengthp);
- }
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "datap = %p\n", datap);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "timeout = %ld\n", timeout);
-#endif /* DEBUG */
-
- /*
- * Perform basic sanity checks on the caller's request.
- */
- if ((typep == NULL) || (*typep >= (1 << MBOXSC_NUM_MSG_TYPES)) ||
- (cmdp == NULL) || (transidp == NULL) || (lengthp == NULL) ||
- ((datap == NULL) && (*lengthp != 0)) ||
- (timeout < MBOXSC_GETMSG_MIN_TIMEOUT_MSECS) ||
- (timeout > MBOXSC_GETMSG_MAX_TIMEOUT_MSECS)) {
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_getmsg ret: 0x%08x\n", EINVAL);
- return (EINVAL);
- }
-
- /*
- * Don't allow mboxsc_getmsg to attempt to receive a message for
- * longer than the caller's timeout.
- */
- deadline = ddi_get_lbolt() +
- drv_usectohz(timeout * MBOXSC_USECS_PER_MSEC);
-
- /*
- * Perform additional sanity checks on the client's request and the
- * associated mailbox.
- */
- mutex_enter(&mboxsc_lock);
- mailboxp = mboxsc_hashfind_mailbox_by_key(key);
- if (mailboxp == NULL) {
- error = EBADF;
- } else if (mailboxp->mbox_direction != MBOXSC_MBOX_IN) {
- error = EINVAL;
- }
-
- if (error != 0) {
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_getmsg ret: 0x%08x\n", error);
- return (error);
- }
-
- /*
- * The request is okay, so reference the mailbox (to keep it from being
- * closed), and proceed with the real work.
- */
- mboxsc_reference_mailbox(mailboxp);
-
- /*
- * Certain failures that may occur late in the process of getting a
- * message (e.g. checksum error, cancellation by the sender) are
- * supposed to leave the recipient waiting for the next message to
- * arrive rather than returning an error. To facilitate restarting
- * the message acquisition process, the following label is provided
- * as a target for a very few judiciously-placed "goto"s.
- *
- * The mboxsc_lock mutex MUST be held when jumping to this point.
- */
-mboxsc_getmsg_retry:
- ;
-
- /*
- * If there is a valid message in the mailbox right now, check to
- * see if it matches the caller's request. If not, or if another
- * caller is already reading it, wait for either the arrival of the
- * next message or the expiration of the caller's specified timeout.
- */
- error = 0;
- while (!(mailboxp->mbox_state & STATE_HDRVALID) ||
- (mailboxp->mbox_state & STATE_READING) ||
- !MSG_TYPE_MATCHES(*typep, &(mailboxp->mbox_header)) ||
- !MSG_CMD_MATCHES(*cmdp, &(mailboxp->mbox_header)) ||
- !MSG_TRANSID_MATCHES(*transidp, &(mailboxp->mbox_header))) {
- remainder = cv_timedwait_sig(&(mailboxp->mbox_wait),
- &mboxsc_lock, deadline);
- if (remainder == -1) {
- error = ETIMEDOUT;
- } else if (remainder == 0) {
- error = EINTR;
- }
-
- if (error != 0) {
- mboxsc_dereference_mailbox(mailboxp);
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_getmsg ret: 0x%08x\n", error);
- return (error);
- }
- }
-
- /*
- * If somebody sends us a message using a Mailbox Protocol version
- * greater than the highest one we understand, invalidate the message,
- * because we can't safely interpret anything beyond the version field.
- */
- if (mailboxp->mbox_header.msg_version > MBOXSC_PROTOCOL_VERSION) {
- DPRINTF1(DBG_DEV, DBGACT_DEFAULT,
- "incoming message with unsupported version %d\n",
- mailboxp->mbox_header.msg_version);
- mailboxp->mbox_state &= ~STATE_HDRVALID;
- goto mboxsc_getmsg_retry;
- }
-
- /*
- * At this point, there is a stored message header that matches the
- * caller's request, but the actual message may no longer be valid
- * in IOSRAM. Check the data_valid flag to see whether or not
- * this is the case. If the message has expired, go start over.
- *
- * The global mutex is held while reading flag data from IOSRAM to
- * avoid certain race conditions. One race condition is still
- * possible (i.e. SC-side has just set the data_valid flag for a
- * new message, but the stored message header hasn't been updated
- * yet), but it won't cause incorrect behavior (just some wasted work).
- */
- error = iosram_get_flag(key, &data_valid, NULL);
-
- ASSERT(error != EINVAL);
- if (error == 0) {
- if (data_valid != IOSRAM_DATA_VALID) {
- mailboxp->mbox_state &= ~STATE_HDRVALID;
- goto mboxsc_getmsg_retry;
- }
- } else if ((error == EAGAIN) && (deadline - ddi_get_lbolt() >= 0)) {
- mutex_exit(&mboxsc_lock);
- delay(MIN(EAGAIN_POLL, deadline - ddi_get_lbolt()));
- mutex_enter(&mboxsc_lock);
- goto mboxsc_getmsg_retry;
- }
-
- /*
- * If the message is larger than the caller's buffer, provide the caller
- * with the length of the message and return an error.
- */
- datalen = mailboxp->mbox_header.msg_length - MBOXSC_MSGHDR_SIZE;
- if ((error == 0) && (datalen > *lengthp)) {
- *lengthp = datalen;
- error = EMSGSIZE;
- }
-
- /*
- * Note that there's no need to check STATE_HDRVALID before broadcasting
- * here because the header is guaranteed to be valid at this point.
- */
- if (error != 0) {
- cv_broadcast(&(mailboxp->mbox_wait));
- mboxsc_dereference_mailbox(mailboxp);
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_getmsg ret: 0x%08x\n", error);
- return (error);
- }
-
- /*
- * Store a copy of the current message header, flag the mailbox to
- * indicate that it is being read and attempt to read the message data
- * and checksum.
- */
- bcopy(&(mailboxp->mbox_header), &header, MBOXSC_MSGHDR_SIZE);
- mailboxp->mbox_state |= STATE_READING;
- mutex_exit(&mboxsc_lock);
-
- if (datalen > 0) {
- error = mboxsc_timed_read(deadline, key, MBOXSC_DATA_OFFSET,
- datalen, (caddr_t)datap);
- }
-
- if (error == 0) {
- error = mboxsc_timed_read(deadline, key, header.msg_length,
- MBOXSC_CHKSUM_SIZE, (caddr_t)&read_checksum);
- }
-
- /*
- * Check for errors that may have occurred while accessing IOSRAM.
- */
- if (error != 0) {
- ASSERT((error != EINVAL) && (error != EMSGSIZE));
- mutex_enter(&mboxsc_lock);
- mailboxp->mbox_state &= ~STATE_READING;
- if (mailboxp->mbox_state & STATE_HDRVALID) {
- cv_broadcast(&(mailboxp->mbox_wait));
- }
- mboxsc_dereference_mailbox(mailboxp);
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_getmsg ret: 0x%08x\n", error);
- return (error);
- }
-
- /*
- * Calculate the checksum for the header and data that was read from
- * IOSRAM.
- */
- calc_checksum = mboxsc_checksum(CHKSUM_INIT, (uint8_t *)&header,
- MBOXSC_MSGHDR_SIZE);
- calc_checksum = mboxsc_checksum(calc_checksum, (uint8_t *)datap,
- datalen);
-
- /*
- * If the message header has been invalidated, note the change.
- * If a the checksum verification fails, invalidate the message
- * header. In either case, go back to the beginning and wait
- * for a new message.
- */
- mutex_enter(&mboxsc_lock);
- if (!(mailboxp->mbox_state & STATE_HDRVALID)) {
- error = -1;
- DPRINTF0(DBG_DEV, DBGACT_DEFAULT,
- "mboxsc_getmsg - message invalidated while reading\n");
- } else if (read_checksum != calc_checksum) {
- error = -1;
- mailboxp->mbox_state &= ~STATE_HDRVALID;
- DPRINTF0(DBG_DEV, DBGACT_DEFAULT,
- "mboxsc_getmsg - message failed checksum\n");
- cmn_err(CE_NOTE,
- "mboxsc_getmsg - message failed checksum\n");
- }
-
- if (error == -1) {
- mailboxp->mbox_state &= ~STATE_READING;
- goto mboxsc_getmsg_retry;
- }
-
- /*
- * Acquire the hardware lock used for synchronization of data_valid flag
- * access to avoid race conditions. If it is acquired, try to check the
- * current data_valid flag and transaction ID to verify that the message
- * is still valid.
- */
- mutex_exit(&mboxsc_lock);
-
- if ((error = mboxsc_lock_flags(FALSE, deadline)) != 0) {
- lock_held = FALSE;
- /*
- * We don't "do" EBUSY here, so treat it as EAGAIN.
- */
- if (error == EBUSY) {
- error = EAGAIN;
- }
- } else {
- lock_held = TRUE;
- }
-
- if (error == 0) {
- error = mboxsc_timed_get_flag(deadline, key, &data_valid, NULL);
- }
-
- if ((error == 0) && (data_valid == IOSRAM_DATA_VALID)) {
- error = mboxsc_timed_read(deadline, key,
- offsetof(mboxsc_msghdr_t, msg_transid),
- FIELD_SIZE(mboxsc_msghdr_t, msg_transid),
- (caddr_t)&read_transid);
- }
-
- /*
- * If something failed along the way, either the error is unrecoverable
- * or we're just plain out of time, so unlock the flags if they were
- * locked, release the mailbox, wake up other potential readers if
- * there's still a message around, and return.
- */
- if (error != 0) {
- ASSERT((error != EINVAL) && (error != EMSGSIZE));
- if (lock_held) {
- (void) mboxsc_unlock_flags(TRUE);
- }
- mutex_enter(&mboxsc_lock);
- mailboxp->mbox_state &= ~STATE_READING;
- if (mailboxp->mbox_state & STATE_HDRVALID) {
- cv_broadcast(&(mailboxp->mbox_wait));
- }
- mboxsc_dereference_mailbox(mailboxp);
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_getmsg ret: 0x%08x\n", error);
- return (error);
- }
-
- /*
- * If the data_valid flag isn't set to IOSRAM_DATA_VALID, or the
- * message transaction ID in IOSRAM has changed, the message being
- * read was timed out by its sender. Since the data_valid flag can't
- * change as long as we have the flags locked, we can safely mark the
- * stored message header invalid if either the data_valid flag isn't set
- * or the stored transaction ID doesn't match the one we read. (If
- * data_valid is set, the transaction ID shouldn't be changing
- * underneath us.) On the other hand, if there may still be a valid
- * message, wake up any pending readers.
- */
- if ((data_valid != IOSRAM_DATA_VALID) ||
- (read_transid != header.msg_transid)) {
- mutex_enter(&mboxsc_lock);
- mailboxp->mbox_state &= ~STATE_READING;
- if ((data_valid != IOSRAM_DATA_VALID) ||
- (mailboxp->mbox_header.msg_transid != read_transid)) {
- mailboxp->mbox_state &= ~STATE_HDRVALID;
- } else if (mailboxp->mbox_state & STATE_HDRVALID) {
- cv_broadcast(&(mailboxp->mbox_wait));
- }
-
- /*
- * Unfortunately, we can't be holding mboxsc_lock when we unlock
- * the flags. However, we have to hold the flags until here to
- * make sure the SC doesn't change the message's state while
- * we're checking to see if we should invalidate our stored
- * header.
- */
- mutex_exit(&mboxsc_lock);
- error = mboxsc_unlock_flags(TRUE);
- mutex_enter(&mboxsc_lock);
-
- DPRINTF0(DBG_DEV, DBGACT_DEFAULT,
- "mboxsc_getmsg() - message invalidated by sender\n");
- goto mboxsc_getmsg_retry;
- }
-
- /*
- * If everything has worked up to this point, all that remains is
- * to set the data_valid flag to IOSRAM_DATA_INVALID, tidy up, and
- * return the message. If the flag can't be set, the message can't
- * be received, so keep trying as long as there is time.
- */
- error = mboxsc_timed_set_flag(deadline, key, IOSRAM_DATA_INVALID,
- IOSRAM_INT_NONE);
-
- (void) mboxsc_unlock_flags(TRUE);
- mutex_enter(&mboxsc_lock);
-
- if (error != 0) {
- ASSERT(error != EINVAL);
- mboxsc_dereference_mailbox(mailboxp);
- mailboxp->mbox_state &= ~STATE_READING;
- if (mailboxp->mbox_state & STATE_HDRVALID) {
- cv_broadcast(&(mailboxp->mbox_wait));
- }
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_getmsg ret: 0x%08x\n", error);
- return (error);
- }
-
- /*
- * If the message was read 100% successfully and the stored message
- * header for the mailbox still matches the message that was read,
- * invalidate it to prevent other readers from trying to read it.
- */
- if (bcmp(&(mailboxp->mbox_header), &header, MBOXSC_MSGHDR_SIZE) == 0) {
- mailboxp->mbox_state &= ~STATE_HDRVALID;
- } else if (mailboxp->mbox_state & STATE_HDRVALID) {
- cv_broadcast(&(mailboxp->mbox_wait));
- }
-
- mboxsc_dereference_mailbox(mailboxp);
- mailboxp->mbox_state &= ~STATE_READING;
- mutex_exit(&mboxsc_lock);
-
- /*
- * Since we're successfully returning a message, we need to provide the
- * caller with all of the interesting header information.
- */
- *typep = header.msg_type;
- *cmdp = header.msg_cmd;
- *transidp = header.msg_transid;
- *lengthp = datalen;
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_getmsg ret: 0x%08x\n", 0);
- return (0);
-}
-
-/*
- * mboxsc_ctrl
- *
- * This routine provides access to a variety of services not available through
- * the basic API.
- */
-int
-mboxsc_ctrl(uint32_t key, uint32_t cmd, void *arg)
-{
- int error = 0;
- mboxsc_mbox_t *mailboxp;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_ctrl called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "cmd = 0x%x\n", cmd);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "arg = %p\n", arg);
-
- mutex_enter(&mboxsc_lock);
- mailboxp = mboxsc_hashfind_mailbox_by_key(key);
- if (mailboxp == NULL) {
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_ctrl ret: 0x%08x\n",
- EBADF);
- return (EBADF);
- }
-
- switch (cmd) {
- case MBOXSC_CMD_VERSION:
- /*
- * Return the Protocol version currently in use. Since
- * there is only one version that exists right now, we
- * can't be using anything else.
- */
- if (arg == NULL) {
- error = EINVAL;
- break;
- }
-
- *(uint32_t *)arg = MBOXSC_PROTOCOL_VERSION;
- break;
-
- case MBOXSC_CMD_MAXVERSION:
- /*
- * Return the highest Protocol version that we support.
- */
- if (arg == NULL) {
- error = EINVAL;
- break;
- }
-
- *(uint32_t *)arg = MBOXSC_PROTOCOL_VERSION;
- break;
-
- case MBOXSC_CMD_MAXDATALEN:
- /*
- * Return the amount of space available for client data
- * in the indicated mailbox.
- */
- if (arg == NULL) {
- error = EINVAL;
- break;
- }
-
- *(uint32_t *)arg = mailboxp->mbox_length -
- MBOXSC_PROTOCOL_SIZE;
- break;
-
- case MBOXSC_CMD_PUTMSG_TIMEOUT_RANGE:
- {
- mboxsc_timeout_range_t *rangep;
-
- /*
- * Return the range of acceptable timeout values for
- * mboxsc_putmsg, expressed in milliseconds.
- */
- if (arg == NULL) {
- error = EINVAL;
- break;
- }
-
- rangep = (mboxsc_timeout_range_t *)arg;
- rangep->min_timeout = MBOXSC_PUTMSG_MIN_TIMEOUT_MSECS;
- rangep->max_timeout = MBOXSC_PUTMSG_MAX_TIMEOUT_MSECS;
- break;
- }
-
- case MBOXSC_CMD_GETMSG_TIMEOUT_RANGE:
- {
- mboxsc_timeout_range_t *rangep;
-
- /*
- * Return the range of acceptable timeout values for
- * mboxsc_getmsg, expressed in milliseconds.
- */
- if (arg == NULL) {
- error = EINVAL;
- break;
- }
-
- rangep = (mboxsc_timeout_range_t *)arg;
- rangep->min_timeout = MBOXSC_GETMSG_MIN_TIMEOUT_MSECS;
- rangep->max_timeout = MBOXSC_GETMSG_MAX_TIMEOUT_MSECS;
- break;
- }
-
- default:
- error = ENOTSUP;
- break;
- }
-
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_ctrl ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * mboxsc_putmsg_def_timeout
- *
- * This routine returns the default mboxsc_putmsg timeout provided for the
- * convenience of clients.
- */
-clock_t
-mboxsc_putmsg_def_timeout(void)
-{
- return (MBOXSC_PUTMSG_DEF_TIMEOUT_MSECS);
-}
-
-/*
- * mboxsc_iosram_callback
- *
- * This routine is registered with the IOSRAM driver for all inbound mailboxes,
- * and performs preliminary processing of all new messages.
- */
-static void
-mboxsc_iosram_callback(void *arg)
-{
- int error = 0;
- uint8_t data_valid;
- uint32_t key = (uint32_t)(uintptr_t)arg;
- mboxsc_mbox_t *mailboxp;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_iosram_callback called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "arg = 0x%x\n", key);
-
- mutex_enter(&mboxsc_lock);
- mailboxp = mboxsc_hashfind_mailbox_by_key(key);
-
- /*
- * We shouldn't ever receive a callback for a mailbox that doesn't
- * exist or for an output mailbox.
- */
- ASSERT(mailboxp != NULL);
- ASSERT(mailboxp->mbox_direction == MBOXSC_MBOX_IN);
-
- /*
- * Attempt to read the header of the mailbox. If the IOSRAM returns
- * EAGAIN, indicating a tunnel switch is in progress, do not retry
- * the operation.
- */
- mailboxp->mbox_state &= ~STATE_HDRVALID;
- error = iosram_rd(key, MBOXSC_MSGHDR_OFFSET, MBOXSC_MSGHDR_SIZE,
- (caddr_t)&(mailboxp->mbox_header));
-
- /*
- * If somebody sends us a message using a Mailbox Protocol version
- * greater than the highest one we understand, ignore the message,
- * because we can't safely interpret anything beyond the version field.
- */
- if (mailboxp->mbox_header.msg_version > MBOXSC_PROTOCOL_VERSION) {
- error = -1;
- DPRINTF1(DBG_DEV, DBGACT_DEFAULT,
- "incoming message with unsupported version %d\n",
- mailboxp->mbox_header.msg_version);
- }
-
- /*
- * If this message is a repeat of a previous message (which should
- * only happen with reply messages), it is conceivable that a client
- * already executing in mboxsc_getmsg for the previous message could
- * end up receiving the new message before this callback gets a chance
- * to execute. If that happens, the data_valid flag will already have
- * been cleared. Call iosram_get_flag to see if that is the case, and
- * do not process the message if it is.
- */
- if (error == 0) {
- error = iosram_get_flag(key, &data_valid, NULL);
- if ((error == 0) && (data_valid != IOSRAM_DATA_VALID)) {
- error = -1;
- }
- }
-
- /*
- * If the iosram_rd call failed, return.
- */
- if (error != 0) {
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_iosram_callback ret (0x%08x)\n", error);
- return;
- }
-
- /*
- * If the message read from IOSRAM was unsolicited, invoke
- * its callback. Otherwise, wake all threads that are waiting
- * in mboxsc_getmsg.
- */
- mailboxp->mbox_state |= STATE_HDRVALID;
- if (IS_UNSOLICITED_TYPE(mailboxp->mbox_header.msg_type) &&
- (mailboxp->mbox_callback != NULL)) {
- mboxsc_reference_mailbox(mailboxp);
- mutex_exit(&mboxsc_lock);
- (*(mailboxp->mbox_callback))();
- mutex_enter(&mboxsc_lock);
- mboxsc_dereference_mailbox(mailboxp);
- } else {
- cv_broadcast(&(mailboxp->mbox_wait));
- }
-
- mutex_exit(&mboxsc_lock);
-
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT, "mboxsc_iosram_callback ret\n");
-}
-
-/*
- * mboxsc_hdrchange_callback
- *
- * This routine is registered with the IOSRAM driver to react to any changes SMS
- * makes to the IOSRAM header.
- */
-static void
-mboxsc_hdrchange_callback(void)
-{
- int error;
- uint32_t sms_version;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT,
- "mboxsc_hdrchange_callback called\n");
-
- error = iosram_hdr_ctrl(IOSRAM_HDRCMD_GET_SMS_MBOX_VER,
- (void *)&sms_version);
- if (error == 0) {
- DPRINTF1(DBG_DEV, DBGACT_DEFAULT,
- "sms mailbox version = %d\n", sms_version);
- mboxsc_active_version = MIN(MBOXSC_PROTOCOL_VERSION,
- sms_version);
- }
-
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT, "mboxsc_hdrchange_callback ret\n");
-}
-
-
-/*
- * mboxsc_add_mailbox
- *
- * If no other mailbox exists with the same key as this mailbox, attempt to
- * retrieve its length from the IOSRAM driver and register the mboxsc callback
- * for the associated IOSRAM chunk. If successful, initialize the
- * non-client-supplied mailbox fields and insert it into the hash table.
- * NOTE: The caller MUST hold mboxsc_lock to avoid corrupting the hash table.
- */
-static int
-mboxsc_add_mailbox(mboxsc_mbox_t *mailboxp)
-{
- int error = 0;
- uint32_t key = mailboxp->mbox_key;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_add_mailbox called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "mailboxp = %p\n", (void *)mailboxp);
-
- /*
- * The global lock must be held by the caller.
- */
- ASSERT(mutex_owned(&mboxsc_lock));
-
- /*
- * Don't create the mailbox if it already exists.
- */
- if (mboxsc_hashfind_mailbox_by_key(key) != NULL) {
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_add_mailbox ret: 0x%08x\n", EEXIST);
- return (EEXIST);
- }
-
- /*
- * Obtain the mailbox length and register the mboxsc callback with the
- * IOSRAM driver. If either call to the IOSRAM driver fails, or the
- * chunk is too small to be used as a mailbox, return an error to the
- * caller.
- */
- error = iosram_ctrl(key, IOSRAM_CMD_CHUNKLEN, &(mailboxp->mbox_length));
-
- if ((error == 0) && (mailboxp->mbox_length < MBOXSC_PROTOCOL_SIZE)) {
- error = EFAULT;
- }
-
- if ((error == 0) && (mailboxp->mbox_direction == MBOXSC_MBOX_IN)) {
- error = iosram_register(key, mboxsc_iosram_callback,
- (void *)(uintptr_t)(key));
- if (error == EBUSY) {
- error = EFAULT;
- }
- }
-
- if (error != 0) {
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_add_mailbox ret: 0x%08x\n", error);
- return (error);
- }
-
- /*
- * Initialize remaining mailbox fields and insert mailbox into
- * hash table.
- */
- mailboxp->mbox_state = STATE_IDLE;
- mailboxp->mbox_refcount = 0;
- cv_init(&(mailboxp->mbox_wait), NULL, CV_DRIVER, NULL);
- mboxsc_hashinsert_mailbox(mailboxp);
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_add_mailbox ret: 0x%08x\n",
- 0);
- return (0);
-}
-
-/*
- * mboxsc_close_mailbox
- *
- * Remove a mailbox from the hash table, unregister its IOSRAM callback, and
- * deallocate its resources.
- * NOTE: The caller MUST hold mboxsc_lock to avoid corrupting the hash table.
- */
-static void
-mboxsc_close_mailbox(mboxsc_mbox_t *mailboxp)
-{
- int error = 0;
- uint32_t key = mailboxp->mbox_key;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_close_mailbox called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "mailboxp = %p\n", (void *)mailboxp);
-
- /*
- * The global lock must be held by the caller.
- */
- ASSERT(mutex_owned(&mboxsc_lock));
-
- /*
- * Unregister the mboxsc callback for this particular mailbox.
- */
- if (mailboxp->mbox_direction == MBOXSC_MBOX_IN) {
- error = iosram_unregister(key);
- if (error == EINVAL) {
- DPRINTF1(DBG_DEV, DBGACT_DEFAULT, "invalid key (0x%08x)"
- " reported in mboxsc_close_mailbox.\n", key);
- error = 0;
- }
- }
-
- /*
- * Remove the mailbox from the hash table and deallocate its resources.
- */
- (void) mboxsc_hashremove_mailbox_by_key(key);
- cv_destroy(&(mailboxp->mbox_wait));
- DPRINTF2(DBG_KMEM, DBGACT_DEFAULT, "kmem_free(%p, %lu)\n",
- (void *)mailboxp, sizeof (mboxsc_mbox_t));
- kmem_free(mailboxp, sizeof (mboxsc_mbox_t));
-
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT, "mboxsc_close_mailbox ret\n");
-}
-
-/*
- * mboxsc_hashinsert_mailbox
- *
- * Insert a fully initialized mailbox into the hash table. No duplicate
- * checking is performed at this point, so the caller is responsible for
- * duplicate prevention if it is desired.
- * NOTE: The caller MUST hold mboxsc_lock to avoid corrupting the hash table.
- */
-static void
-mboxsc_hashinsert_mailbox(mboxsc_mbox_t *mailboxp)
-{
- uint32_t hash;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT,
- "mboxsc_hashinsert_mailbox called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "mailboxp = %p\n", (void *)mailboxp);
-
- /*
- * The global lock must be held by the caller.
- */
- ASSERT(mutex_owned(&mboxsc_lock));
-
- hash = HASH_KEY(mailboxp->mbox_key);
- mailboxp->mbox_hash_next = mboxsc_hash_table[hash];
- mboxsc_hash_table[hash] = mailboxp;
-
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_hashinsert_mailbox ret\n");
-}
-
-/*
- * mboxsc_hashfind_mailbox_by_key
- *
- * Locate a mailbox with the given key in the hash table. Return a pointer
- * to the mailbox if it exists, or NULL if no matching mailbox is found.
- * NOTE: The caller MUST hold mboxsc_lock to avoid corrupting the hash table.
- */
-static mboxsc_mbox_t *
-mboxsc_hashfind_mailbox_by_key(uint32_t key)
-{
- uint32_t hash;
- mboxsc_mbox_t *mailboxp;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT,
- "mboxsc_hashfind_mailbox_by_key called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
-
- /*
- * The global lock must be held by the caller.
- */
- ASSERT(mutex_owned(&mboxsc_lock));
-
- hash = HASH_KEY(key);
- mailboxp = mboxsc_hash_table[hash];
- while (mailboxp != NULL) {
- if (mailboxp->mbox_key == key) {
- break;
- }
- mailboxp = mailboxp->mbox_hash_next;
- }
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_hashfind_mailbox_by_key ret: %p\n", (void *)mailboxp);
- return (mailboxp);
-}
-
-/*
- * mboxsc_hashremove_mailbox_by_key
- *
- * Locate a mailbox with the given key in the hash table. If it exists,
- * remove it from the hash table and return a pointer to it. Otherwise,
- * return NULL.
- * NOTE: The caller MUST hold mboxsc_lock to avoid corrupting the hash table.
- */
-static mboxsc_mbox_t *
-mboxsc_hashremove_mailbox_by_key(uint32_t key)
-{
- uint32_t hash;
- mboxsc_mbox_t *mailboxp;
- mboxsc_mbox_t *last;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT,
- "mboxsc_hashremove_mailbox_by_key called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
-
- /*
- * The global lock must be held by the caller.
- */
- ASSERT(mutex_owned(&mboxsc_lock));
-
- hash = HASH_KEY(key);
- mailboxp = mboxsc_hash_table[hash];
- last = NULL;
- while (mailboxp != NULL) {
- if (mailboxp->mbox_key == key) {
- break;
- }
- last = mailboxp;
- mailboxp = mailboxp->mbox_hash_next;
- }
-
- /*
- * If a mailbox was found, remove it from the hash table.
- */
- if (mailboxp != NULL) {
- if (last == NULL) {
- mboxsc_hash_table[hash] = mailboxp->mbox_hash_next;
- } else {
- last->mbox_hash_next = mailboxp->mbox_hash_next;
- }
-
- mailboxp->mbox_hash_next = NULL;
- }
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_hashremove_mailbox_by_key ret: %p\n", (void *)mailboxp);
- return (mailboxp);
-}
-
-/*
- * mboxsc_checksum
- *
- * Given a pointer to a data buffer and its length, calculate the checksum of
- * the data contained therein.
- */
-static mboxsc_chksum_t
-mboxsc_checksum(mboxsc_chksum_t seed, uint8_t *buf, uint32_t length)
-{
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_checksum called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "seed = 0x%x\n", seed);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "buf = %p\n", (void *)buf);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "length = 0x%x\n", length);
-
- while (length-- > 0) {
- seed += *(buf++);
- }
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_checksum ret: 0x%08x\n",
- seed);
- return (seed);
-}
-
-/*
- * mboxsc_lock_flags
- *
- * Acquire the hardware lock used for data_valid flag synchronization. If the
- * lock is currently held by SMS and acquisition is mandatory, just keep on
- * trying until it is acquired. If acquisition is not mandatory, keep trying
- * until the given deadline has been reached. To avoid loading the system
- * unreasonably on EBUSY or EAGAIN, sleep for an appropriate amount of time
- * before retrying. If a hardware error is encountered return it to the caller.
- *
- * If the lock is held, but not by SMS, clear it and acquire it. Nobody
- * else should be grabbing that lock.
- */
-static int
-mboxsc_lock_flags(uint8_t mandatory, clock_t deadline)
-{
- int error;
- int warned = 0;
- uint32_t sema;
- clock_t pause;
- clock_t warning_time = ddi_get_lbolt() + LOOP_WARN_INTERVAL;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_lock_flags called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "mandatory = 0x%x\n", mandatory);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "deadline = 0x%lx\n", deadline);
-
- /*
- * Keep trying to acquire the lock until successful or (if acquisition
- * is not mandatory) time runs out. If EBUSY (lock is already held) or
- * EAGAIN (tunnel switch in progress) is encountered, sleep for an
- * appropriate amount of time before retrying. Any other error is
- * unrecoverable.
- */
- do {
- pause = 0;
-
- /*
- * Since multiple threads could conceivably want the flag lock
- * at the same time, we place the lock under a mutex and keep a
- * counter indicating how many threads have the flags locked at
- * the moment.
- */
- mutex_enter(&mboxsc_lock);
- if ((mboxsc_flaglock_count > 0) ||
- ((error = iosram_sema_acquire(&sema)) == 0)) {
- mboxsc_flaglock_count++;
- mutex_exit(&mboxsc_lock);
-
- if (warned) {
- cmn_err(CE_WARN, "Flags locked");
- }
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_lock_flags ret: 0\n");
- return (0);
- }
-
- /*
- * If iosram_sema_acquire returned EBUSY (lock already held),
- * make sure the lock is held by SMS, since nobody else should
- * ever be holding it. If EBUSY or EAGAIN (tunnel switch in
- * progress) was returned, determine the appropriate amount of
- * time to sleep before trying again.
- */
- if (error == EBUSY) {
- if (IOSRAM_SEMA_GET_IDX(sema) != IOSRAM_SEMA_SMS_IDX) {
- (void) iosram_sema_release();
- cmn_err(CE_WARN,
- "Incorrect flag lock value read (0x%08x)",
- sema);
- } else {
- pause = (mandatory ? HWLOCK_POLL :
- MIN(HWLOCK_POLL, deadline -
- ddi_get_lbolt()));
- }
- } else if (error == EAGAIN) {
- pause = (mandatory ? EAGAIN_POLL : MIN(EAGAIN_POLL,
- deadline - ddi_get_lbolt()));
- }
-
- /*
- * We had to hold the lock until now to protect the potential
- * iosram_sema_release call above.
- */
- mutex_exit(&mboxsc_lock);
-
- /*
- * If EAGAIN or EBUSY was encountered, we're looping.
- */
- if ((error == EAGAIN) || (error == EBUSY)) {
- /*
- * If we've been looping here for a while, something is
- * probably wrong, so we should generated a warning.
- */
- if (warning_time - ddi_get_lbolt() <= 0) {
- if (!warned) {
- warned = 1;
- cmn_err(CE_WARN,
- "Unable to lock flags (0x%08x)",
- error);
- } else {
- cmn_err(CE_WARN,
- "Still unable to lock flags");
- }
- warning_time = ddi_get_lbolt() +
- LOOP_WARN_INTERVAL;
- }
-
- /*
- * Sleep a while before trying again.
- */
- delay(pause);
- }
- } while (((error == EAGAIN) || (error == EBUSY)) &&
- (mandatory || (deadline - ddi_get_lbolt() >= 0)));
-
- /*
- * If something really bad has happened, generate a warning.
- */
- if ((error != EAGAIN) && (error != EBUSY)) {
- cmn_err(CE_WARN, "Flag locking failed! (%d)", error);
- }
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_lock_flags ret: 0x%08x\n",
- error);
- return (error);
-}
-
-/*
- * mboxsc_unlock_flags
- *
- * Release the hardware lock used for data_valid flag synchronization.
- * If a hardware error is encountered, return it to the caller. If the
- * mandatory flag is set, loop and retry if EAGAIN is encountered.
- */
-static int
-mboxsc_unlock_flags(uint8_t mandatory)
-{
- int error;
- int warned = 0;
- clock_t warning_time = ddi_get_lbolt() + LOOP_WARN_INTERVAL;
-
- ASSERT(mboxsc_flaglock_count != 0);
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_unlock_flags called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "mandatory = 0x%x\n", mandatory);
-
- do {
- /*
- * Since multiple threads could conceivably want the flag lock
- * at the same time, we place the lock under a mutex and keep a
- * counter indicating how many threads have the flags locked at
- * the moment.
- */
- mutex_enter(&mboxsc_lock);
- if ((mboxsc_flaglock_count > 1) ||
- ((error = iosram_sema_release()) == 0)) {
- mboxsc_flaglock_count--;
- mutex_exit(&mboxsc_lock);
-
- if (warned) {
- cmn_err(CE_WARN, "Flags unlocked");
- }
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_unlock_flags ret: 0\n");
- return (0);
- }
- mutex_exit(&mboxsc_lock);
-
- /*
- * If iosram_sema_release returned EAGAIN (tunnel switch in
- * progress) and unlocking the flags is mandatory, sleep before
- * trying again. If we've been trying for a while, display a
- * warning message too.
- */
- if ((error == EAGAIN) && mandatory) {
- if (warning_time - ddi_get_lbolt() <= 0) {
- if (!warned) {
- warned = 1;
- cmn_err(CE_WARN, "Unable to unlock "
- "flags (iosram EAGAIN)");
- } else {
- cmn_err(CE_WARN,
- "Still unable to unlock flags");
- }
- warning_time = ddi_get_lbolt() +
- LOOP_WARN_INTERVAL;
- }
-
- delay(EAGAIN_POLL);
- }
- } while ((error == EAGAIN) && mandatory);
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_unlock_flags ret: 0x%08x\n",
- error);
- return (error);
-}
-
-/*
- * mboxsc_timed_read
- *
- * This function is just a wrapper around iosram_rd that will keep sleeping
- * and retrying, up to a given deadline, if iosram_rd returns EAGAIN
- * (presumably due to a tunnel switch).
- */
-static int
-mboxsc_timed_read(clock_t deadline, uint32_t key, uint32_t off, uint32_t len,
- caddr_t dptr)
-{
- int error;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_timed_read called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "deadline = 0x%lx\n", deadline);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "off = 0x%x\n", off);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "len = 0x%x\n", len);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "dptr = %p\n", (void *)dptr);
-
- do {
- error = iosram_rd(key, off, len, dptr);
- if (error == EAGAIN) {
- delay(MIN(EAGAIN_POLL, deadline - ddi_get_lbolt()));
- }
- } while ((error == EAGAIN) && (deadline - ddi_get_lbolt() >= 0));
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_timed_read ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * mboxsc_timed_write
- *
- * This function is just a wrapper around iosram_wr that will keep sleeping
- * and retrying, up to a given deadline, if iosram_wr returns EAGAIN
- * (presumably due to a tunnel switch).
- */
-static int
-mboxsc_timed_write(clock_t deadline, uint32_t key, uint32_t off, uint32_t len,
- caddr_t dptr)
-{
- int error;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_timed_write called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "deadline = 0x%lx\n", deadline);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "off = 0x%x\n", off);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "len = 0x%x\n", len);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "dptr = %p\n", (void *)dptr);
-
- do {
- error = iosram_wr(key, off, len, dptr);
- if (error == EAGAIN) {
- delay(MIN(EAGAIN_POLL, deadline - ddi_get_lbolt()));
- }
- } while ((error == EAGAIN) && (deadline - ddi_get_lbolt() >= 0));
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_timed_write ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * mboxsc_timed_get_flag
- *
- * This function is just a wrapper around iosram_get_flag that will keep
- * sleeping and retrying, up to a given deadline, if iosram_get_flag returns
- * EAGAIN (presumably due to a tunnel switch).
- */
-static int
-mboxsc_timed_get_flag(clock_t deadline, uint32_t key, uint8_t *data_validp,
- uint8_t *int_pendingp)
-{
- int error;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_timed_get_flag called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "deadline = 0x%lx\n", deadline);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "data_validp = %p\n",
- (void *)data_validp);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "int_pendingp = %p\n",
- (void *)int_pendingp);
-
- do {
- error = iosram_get_flag(key, data_validp, int_pendingp);
- if (error == EAGAIN) {
- delay(MIN(EAGAIN_POLL, deadline - ddi_get_lbolt()));
- }
- } while ((error == EAGAIN) && (deadline - ddi_get_lbolt() >= 0));
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_timed_get_flag ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * mboxsc_timed_set_flag
- *
- * This function is just a wrapper around iosram_set_flag that will keep
- * sleeping and retrying, up to a given deadline, if iosram_set_flag returns
- * EAGAIN (presumably due to a tunnel switch).
- */
-static int
-mboxsc_timed_set_flag(clock_t deadline, uint32_t key, uint8_t data_valid,
- uint8_t int_pending)
-{
- int error;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_timed_set_flag called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "deadline = 0x%lx\n", deadline);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "data_valid = %d\n", data_valid);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "int_pending = %d\n", int_pending);
-
- do {
- error = iosram_set_flag(key, data_valid, int_pending);
- if (error == EAGAIN) {
- delay(MIN(EAGAIN_POLL, deadline - ddi_get_lbolt()));
- }
- } while ((error == EAGAIN) && (deadline - ddi_get_lbolt() >= 0));
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_timed_set_flag ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * mboxsc_timed_send_intr
- *
- * This function is just a wrapper around iosram_send_intr that will keep
- * sleeping and retrying, up to a given deadline, if iosram_send_intr returns
- * EAGAIN (presumably due to a tunnel switch).
- */
-static int
-mboxsc_timed_send_intr(clock_t deadline)
-{
- int error;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_timed_send_intr called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "deadline = 0x%lx\n", deadline);
-
- do {
- error = iosram_send_intr();
- if (error == DDI_FAILURE) {
- delay(MIN(EAGAIN_POLL, deadline - ddi_get_lbolt()));
- }
- } while ((error == DDI_FAILURE) && (deadline - ddi_get_lbolt() >= 0));
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_timed_send_intr ret: 0x%08x\n", error);
- return (error);
-}
-
-/*
- * mboxsc_expire_message
- *
- * This function is called by mboxsc_putmsg to handle expiration of messages
- * that weren't picked up before they timed out. It will not return until the
- * message has been picked up (which isn't expected), the message has been
- * successfully expired, or a serious error has been encountered. If the
- * message is finally picked up, it will set the value pointed to by "resultp"
- * to 0. Unlike other sections of code, this function will never time out on
- * EAGAIN from the iosram driver, since it is important that both sides of the
- * IOSRAM agree on whether or not a message was delivered successfully.
- */
-static int
-mboxsc_expire_message(uint32_t key, int *resultp)
-{
- int error = 0;
- int lock_held = 0;
- int warned = 0;
- uint8_t data_valid;
- clock_t warning_time = ddi_get_lbolt() + LOOP_WARN_INTERVAL;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_expire_message called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%x\n", key);
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "resultp = %p\n", (void *)resultp);
-
- do {
- error = 0;
-
- /*
- * Lock the flags if they aren't locked already.
- */
- if (!lock_held) {
- error = mboxsc_lock_flags(TRUE, 0);
- if (error == 0) {
- lock_held = 1;
- }
- }
-
- /*
- * If the flags were locked successfully, reread the data-valid
- * flag.
- */
- if (error == 0) {
- error = iosram_get_flag(key, &data_valid, NULL);
- }
-
- /*
- * If the data-valid flag was read successfully, see if it has
- * been cleared or not, as the other side may have finally read
- * the message.
- */
- if (error == 0) {
- if (data_valid == IOSRAM_DATA_INVALID) {
- /*
- * Surprise! The SC finally picked up the
- * message, so delivery succeeded after all.
- */
- if (*resultp == ETIMEDOUT) {
- *resultp = 0;
- }
- } else {
- /*
- * The message still hasn't been read, so try to
- * clear the data-valid flag.
- */
- error = iosram_set_flag(key,
- IOSRAM_DATA_INVALID, IOSRAM_INT_NONE);
- }
- }
-
- /*
- * If the flags were locked, unlock them, no matter what else
- * has or has not succeeded. Don't overwrite the existing value
- * of "error" unless no errors other than EAGAIN have been
- * encountered previously. If we hit EAGAIN at some point,
- * unlocking the flags here is optional. In all other cases, it
- * is mandatory.
- */
- if (lock_held) {
- int unlock_err;
-
- if (error == EAGAIN) {
- unlock_err = mboxsc_unlock_flags(FALSE);
- } else {
- unlock_err = mboxsc_unlock_flags(TRUE);
- }
-
- if (unlock_err == 0) {
- lock_held = 0;
- } else if ((error == 0) || (error == EAGAIN)) {
- error = unlock_err;
- }
- }
-
- /*
- * Did we hit a tunnel switch? (iosram driver returns EAGAIN)
- * If so, sleep for a while before trying the whole process
- * again.
- */
- if (error == EAGAIN) {
- /*
- * If we've been stuck in this loop for a while,
- * something is probably wrong, and we should display a
- * warning.
- */
- if (warning_time - ddi_get_lbolt() <= 0) {
- if (!warned) {
- warned = 1;
- cmn_err(CE_WARN, "Unable to clear flag "
- "(iosram EAGAIN)");
- } else {
- cmn_err(CE_WARN,
- "Still unable to clear flag");
- }
- warning_time = ddi_get_lbolt() +
- LOOP_WARN_INTERVAL;
- }
-
- delay(EAGAIN_POLL);
- }
- } while (error == EAGAIN);
-
- /*
- * If the data-valid flag was not successfully cleared due to some sort
- * of problem, report it. Otherwise, if we looped for a while on EAGAIN
- * and generated a warning about it, indicate that everything is okay
- * now.
- */
- if (error != 0) {
- cmn_err(CE_WARN, "Message expiration failure! (%d)", error);
- } else if (warned) {
- cmn_err(CE_WARN, "Flag cleared");
- }
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_expire_message ret: 0x%08x\n", error);
- return (error);
-}
-
-
-/*
- * mboxsc_generate_transid
- *
- * This function generates unique transaction IDs using an incrementing counter.
- * The value generated is guaranteed not to be the same as the prev_transid
- * value passed in by the caller.
- */
-static uint64_t
-mboxsc_generate_transid(uint64_t prev_transid)
-{
- uint64_t new_transid;
- static uint64_t transid_counter = 0;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_generate_transid called");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "prev_transid = 0x%016lx\n",
- prev_transid);
-
- do {
- new_transid = TRANSID_GEN_MASK | transid_counter++;
- if (transid_counter & TRANSID_GEN_MASK) {
- transid_counter = 0;
- }
- } while (new_transid == prev_transid);
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "mboxsc_generate_transid ret: 0x%016lx", new_transid);
- return (new_transid);
-}
-
-
-/*
- * mboxsc_reference_mailbox
- *
- * Increment the mailbox's reference count to prevent it from being closed.
- * This really doesn't deserve to be a function, but since a dereference
- * function is needed, having a corresponding reference function makes the code
- * clearer.
- */
-static void
-mboxsc_reference_mailbox(mboxsc_mbox_t *mailboxp)
-{
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_reference_mailbox called");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "mailboxp = 0x%p\n",
- (void *)mailboxp);
-
- ASSERT(mutex_owned(&mboxsc_lock));
-
- mailboxp->mbox_refcount++;
-
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT, "mboxsc_reference_mailbox ret");
-}
-
-
-/*
- * mboxsc_dereference_mailbox
- *
- * Decrement the mailbox's reference count, and if the count has gone to zero,
- * signal any threads waiting for mailboxes to be completely dereferenced.
- */
-static void
-mboxsc_dereference_mailbox(mboxsc_mbox_t *mailboxp)
-{
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT,
- "mboxsc_dereference_mailbox called");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "mailboxp = 0x%p\n",
- (void *)mailboxp);
-
- ASSERT(mutex_owned(&mboxsc_lock));
-
- mailboxp->mbox_refcount--;
- if (mailboxp->mbox_refcount == 0) {
- cv_broadcast(&mboxsc_dereference_cv);
- }
-
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT, "mboxsc_dereference_mailbox ret");
-}
-
-
-#ifndef DEBUG
-/* ARGSUSED */
-int
-mboxsc_debug(int cmd, void *arg)
-{
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_debug called");
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT, "mboxsc_debug ret");
- return (ENOTSUP);
-}
-#else /* DEBUG */
-
-static void print_hash_table(void);
-static int print_mailbox_by_key(uint32_t key);
-static void print_mailbox(mboxsc_mbox_t *mailboxp);
-
-int
-mboxsc_debug(int cmd, void *arg)
-{
- int error = 0;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "mboxsc_debug called\n");
-
- switch (cmd) {
- case MBOXSC_PRNMBOX:
- error = print_mailbox_by_key((uint32_t)(uintptr_t)arg);
- break;
-
- case MBOXSC_PRNHASHTBL:
- print_hash_table();
- break;
-
- case MBOXSC_SETDBGMASK:
- mboxsc_debug_mask = (uint32_t)(uintptr_t)arg;
- break;
-
- default:
- DPRINTF1(DBG_DEV, DBGACT_DEFAULT,
- "Error: unknown mboxsc debug cmd (%d)\n", cmd);
- error = ENOTTY;
- break;
- }
-
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT, "mboxsc_debug ret: 0x%08x\n", error);
-
- return (error);
-}
-
-/*PRINTFLIKE5*/
-static void
-mboxsc_dprintf(
- const char *file,
- int line,
- uint32_t class,
- uint32_t action,
- const char *fmt,
- ...)
-{
- int i;
- char indent_buf[64];
- char msg_buf[256];
- va_list adx;
- static uint32_t indent = 0;
-
- if (action & DBGACT_SHOWPOS) {
- cmn_err(CE_CONT, "%s at line %d:\n", file, line);
- }
-
- if (class & DBG_RETS) {
- indent--;
- }
-
- if (class & mboxsc_debug_mask) {
- indent_buf[0] = '\0';
- for (i = 0; i < indent; i++) {
- (void) strcat(indent_buf, " ");
- }
-
- va_start(adx, fmt);
- (void) vsprintf(msg_buf, fmt, adx);
- va_end(adx);
-
- cmn_err(CE_CONT, "%s%s", indent_buf, msg_buf);
- }
-
- if (class & DBG_CALLS) {
- indent++;
- }
-
- if (action & DBGACT_BREAK) {
- debug_enter("");
- }
-}
-
-static void
-print_hash_table(void)
-{
- int i;
- mboxsc_mbox_t *mailboxp;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "print_hash_table called\n");
-
- mutex_enter(&mboxsc_lock);
-
- for (i = 0; i < HASHTBL_SIZE; i++) {
- DPRINTF1(DBG_DEV, DBGACT_DEFAULT, "hash[%02d]:\n", i);
-
- for (mailboxp = mboxsc_hash_table[i]; mailboxp != NULL;
- mailboxp = mailboxp->mbox_hash_next) {
- DPRINTF2(DBG_DEV, DBGACT_DEFAULT,
- " key: 0x%08x, dir: %d\n", mailboxp->mbox_key,
- mailboxp->mbox_direction);
- }
- }
-
- mutex_exit(&mboxsc_lock);
-
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT, "print_hash_table ret\n");
-}
-
-static int
-print_mailbox_by_key(uint32_t key)
-{
- int error = 0;
- mboxsc_mbox_t *mailboxp;
-
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "print_mailbox_by_key called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "key = 0x%08x\n", key);
-
- mutex_enter(&mboxsc_lock);
-
- mailboxp = mboxsc_hashfind_mailbox_by_key(key);
- if (mailboxp != NULL) {
- print_mailbox(mailboxp);
- error = 0;
- } else {
- DPRINTF1(DBG_DEV, DBGACT_DEFAULT,
- "print_mailbox_by_key: no such mbox 0x%08x\n", key);
- error = EBADF;
- }
-
- mutex_exit(&mboxsc_lock);
- DPRINTF1(DBG_RETS, DBGACT_DEFAULT,
- "print_mailbox_by_key ret: 0x%08x\n", error);
-
- return (error);
-}
-
-/* ARGSUSED */
-static void
-print_mailbox(mboxsc_mbox_t *mailboxp)
-{
- DPRINTF0(DBG_CALLS, DBGACT_DEFAULT, "print_mailbox called\n");
- DPRINTF1(DBG_ARGS, DBGACT_DEFAULT, "mailboxp = %p\n",
- (void *)mailboxp);
- if (mailboxp->mbox_direction == MBOXSC_MBOX_IN) {
- DPRINTF3(DBG_DEV, DBGACT_DEFAULT,
- "key = 0x%08x, dir = %d, callback = %p\n",
- mailboxp->mbox_key, mailboxp->mbox_direction,
- (void *)mailboxp->mbox_callback);
- } else {
- DPRINTF2(DBG_DEV, DBGACT_DEFAULT, "key = 0x%08x, dir = %d\n",
- (int)mailboxp->mbox_key, mailboxp->mbox_direction);
- }
- DPRINTF3(DBG_DEV, DBGACT_DEFAULT,
- "length = %d, refcount = %d, state = %d\n",
- mailboxp->mbox_length, mailboxp->mbox_refcount,
- mailboxp->mbox_state);
- /* LINTED E_BAD_FORMAT_ARG_TYPE2 */
- DPRINTF2(DBG_DEV, DBGACT_DEFAULT, "waitcv = %p, hashnext = %p\n",
- (void *)&mailboxp->mbox_wait, (void *)mailboxp->mbox_hash_next);
- if (mailboxp->mbox_direction == MBOXSC_MBOX_IN) {
- DPRINTF3(DBG_DEV, DBGACT_DEFAULT,
- "hdr.type = 0x%x, hdr.cmd = 0x%x, hdr.len = 0x%x\n",
- mailboxp->mbox_header.msg_type,
- mailboxp->mbox_header.msg_cmd,
- mailboxp->mbox_header.msg_length);
- DPRINTF1(DBG_DEV, DBGACT_DEFAULT, "hdr.tid = 0x%016lx\n",
- mailboxp->mbox_header.msg_transid);
- }
- DPRINTF0(DBG_RETS, DBGACT_DEFAULT, "print_mailbox ret\n");
-}
-#endif /* DEBUG */
diff --git a/usr/src/uts/sun4u/starcat/io/sc_gptwocfg.c b/usr/src/uts/sun4u/starcat/io/sc_gptwocfg.c
deleted file mode 100644
index 23ea68c5c2..0000000000
--- a/usr/src/uts/sun4u/starcat/io/sc_gptwocfg.c
+++ /dev/null
@@ -1,1547 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Starcat Specific Glue for Safari Configurator
- */
-
-#include <sys/isa_defs.h>
-#include <sys/conf.h>
-#include <sys/kmem.h>
-#include <sys/debug.h>
-#include <sys/modctl.h>
-#include <sys/autoconf.h>
-#include <sys/hwconf.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/sunndi.h>
-#include <sys/ndi_impldefs.h>
-#include <sys/safari_pcd.h>
-#include <sys/gp2cfg.h>
-#include <sys/gptwo_cpu.h>
-#include <sys/gptwo_pci.h>
-#include <sys/sc_gptwocfg.h>
-#include <post/scat_dcd.h>
-#include <sys/machsystm.h>
-
-int sc_gptwocfg_debug = 0;
-
-#define SC_DEBUG(level, args) if (sc_gptwocfg_debug >= level) cmn_err args
-
-typedef struct sc_gptwocfg_config {
- int board;
- struct gptwocfg_config *port_cookie;
- gptwo_aid_t portid;
- struct sc_gptwocfg_config *link;
- struct sc_gptwocfg_config *next;
-} sc_gptwocfg_config_t;
-
-static kmutex_t sc_gptwo_config_list_lock;
-static sc_gptwocfg_config_t *sc_gptwo_config_list;
-static dev_info_t *sc_find_axq_node(uint_t);
-static sc_gptwocfg_cookie_t sc_configure(uint_t, int);
-static spcd_t *sc_get_common_pcd(uint_t, uint_t);
-static void sc_free_common_pcd(spcd_t *);
-static gptwo_new_nodes_t *sc_gptwocfg_configure_axq(dev_info_t *, uint_t, int);
-static gptwocfg_config_t *sc_gptwocfg_unconfigure_axq(gptwocfg_config_t *);
-static void dump_config(sc_gptwocfg_config_t *);
-static void dump_pcd(spcd_t *);
-static uint_t sc_get_agent_id(spcd_t *, uint_t, uint_t, uint_t);
-static char *rsv_string(prdrsv_t);
-
-extern gptwo_new_nodes_t *gptwocfg_allocate_node_list(int);
-extern void gptwocfg_free_node_list(gptwo_new_nodes_t *);
-
-static uint8_t *get_memlayout(uint32_t, uint32_t *);
-
-#ifdef NO_IOSRAM
-int iosram_rd(uint32_t, uint32_t, uint32_t, caddr_t);
-#else
-extern int iosram_rd(uint32_t, uint32_t, uint32_t, caddr_t);
-#endif
-extern void gptwocfg_devi_attach_to_parent(dev_info_t *);
-
-/*
- * Module control operations
- */
-
-extern struct mod_ops mod_miscops;
-
-static struct modlmisc modlmisc = {
- &mod_miscops, /* Type of module */
- "Sun Fire 15000 gptwocfg"
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1, (void *)&modlmisc, NULL
-};
-
-int
-_init()
-{
- int err = 0;
-
- mutex_init(&sc_gptwo_config_list_lock, NULL, MUTEX_DRIVER, NULL);
- sc_gptwo_config_list = NULL;
-
- /*
- * CPU/PCI devices are already registered by their respective modules,
- * so all we need to do now is install.
- */
- if ((err = mod_install(&modlinkage)) != 0) {
- SC_DEBUG(1, (CE_WARN, "sc_gptwocfg failed to load, error=%d\n",
- err));
- mutex_destroy(&sc_gptwo_config_list_lock);
- } else {
- SC_DEBUG(1, (CE_WARN, "sc_gptwocfg has been loaded.\n"));
- }
- return (err);
-}
-
-int
-_fini(void)
-{
- mutex_destroy(&sc_gptwo_config_list_lock);
- return (mod_remove(&modlinkage));
-}
-
-int
-_info(modinfop)
-struct modinfo *modinfop;
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-static spcd_t *
-sc_get_common_pcd(uint_t expander, uint_t prd_slot)
-{
- spcd_t *pcd;
- gdcd_t *gdcd;
- int portid;
- int i, j, slot;
- int dimm;
- char *label1, *label2;
-
- SC_DEBUG(1, (CE_WARN, "sc_get_common_pcd() expander=%d prd_slot=%d\n",
- expander, prd_slot));
-
- gdcd = (gdcd_t *)kmem_zalloc(sizeof (gdcd_t), KM_SLEEP);
-
- /*
- * Get the Starcat Specific Global DCD Structure from the golden
- * IOSRAM.
- */
- if (iosram_rd(GDCD_MAGIC, 0, sizeof (gdcd_t), (caddr_t)gdcd)) {
- cmn_err(CE_WARN, "sc_gptwocfg: Unable To Read GDCD "
- "From IOSRAM\n");
- kmem_free(gdcd, sizeof (gdcd_t));
- return (NULL);
- }
-
- if (gdcd->h.dcd_magic != GDCD_MAGIC) {
-
- cmn_err(CE_WARN, "sc_gptwocfg: GDCD Bad Magic 0x%x\n",
- gdcd->h.dcd_magic);
-
- kmem_free(gdcd, sizeof (gdcd_t));
- return (NULL);
- }
-
- if (gdcd->h.dcd_version != DCD_VERSION) {
- cmn_err(CE_WARN, "sc_gptwocfg: GDCD Bad Version: "
- "GDCD Version 0x%x Expecting 0x%x\n",
- gdcd->h.dcd_version, DCD_VERSION);
-
- kmem_free(gdcd, sizeof (gdcd_t));
- return (NULL);
- }
-
- pcd = (spcd_t *)kmem_zalloc(sizeof (spcd_t), KM_SLEEP);
-
- /*
- * Copy various information from the platform specific Port
- * Resource Descriptor (PRD) To the platform independent
- * Port Configuration Descriptor.
- */
- pcd->spcd_magic = PCD_MAGIC;
- pcd->spcd_version = PCD_VERSION;
- pcd->spcd_ptype = gdcd->dcd_prd[expander][prd_slot].prd_ptype;
- pcd->spcd_ver_reg = gdcd->dcd_prd[expander][prd_slot].prd_ver_reg;
-
- if (pcd->spcd_ptype == SAFPTYPE_CPU) {
- /*
- * This will calculate the cpu speed based on the
- * the actual frequency ratio * interconnect frequency
- * converted to Mhz.
- */
- pcd->spcd_afreq = gdcd->dcd_prd[expander][prd_slot].
- prd_afreq_ratio *
- (uint16_t)((gdcd->dcd_intercon_freq + 500000) / 1000000);
- } else {
- /*
- * For non-cpu devices, just pass through the frequency
- * unchanged.
- */
- pcd->spcd_afreq =
- gdcd->dcd_prd[expander][prd_slot].prd_afreq_ratio;
- }
-
- pcd->spcd_cache = gdcd->dcd_prd[expander][prd_slot].prd_cache;
-
- SC_DEBUG(1, (CE_WARN, "Safari Device Status status=0x%x\n",
- gdcd->dcd_prd[expander][prd_slot].prd_prsv));
-
- /*
- * Fill in the entire port status.
- */
- if (RSV_GOOD(gdcd->dcd_prd[expander][prd_slot].prd_prsv)) {
- pcd->spcd_prsv = SPCD_RSV_PASS;
- } else {
- pcd->spcd_prsv = SPCD_RSV_FAIL;
- }
-
- /*
- * Fill in the per agent status.
- */
- if (gdcd->dcd_prd[expander][prd_slot].prd_agent[1] == RSV_UNKNOWN) {
- pcd->spcd_agent[0] = pcd->spcd_prsv;
- pcd->spcd_agent[1] = SPCD_RSV_FAIL;
- } else {
- for (i = 0; i < AGENTS_PER_PORT; i++) {
-
- if (RSV_GOOD(
- gdcd->dcd_prd[expander][prd_slot].prd_agent[i]))
- pcd->spcd_agent[i] = SPCD_RSV_PASS;
- else
- pcd->spcd_agent[i] = SPCD_RSV_FAIL;
- }
- }
-
- /*
- * If this is a CPU device calculate the cpuid for it. For Starcat
- * the cpuid is in the following format.
- *
- * EEEEEPPAPP
- *
- * where: EEEEE is the expander
- * PP_PP is the portid
- * __A__ is the sub-agent identifier.
- */
- if (pcd->spcd_ptype == SAFPTYPE_CPU) {
- for (i = 0; i < AGENTS_PER_PORT; i++) {
- switch (prd_slot) {
- case 0:
- case 1:
- case 2:
- case 3:
- portid = (expander << 5) | prd_slot;
- break;
- case 4: /* Maxcat */
- portid = (expander << 5) | 8;
- break;
- case 5: /* Maxcat */
- portid = (expander << 5) | 9;
- break;
- default:
- cmn_err(CE_WARN, "sc_gptwocfg: invalid "
- "prd_slot=%d\n", prd_slot);
- }
- pcd->spcd_cpuid[i] = (i << 2) | portid;
- }
- }
-
- /*
- * Starcat does not have ports with UPA devices so
- * spcd_upadev structure will not be filled in.
- */
-
- /*
- * Fill in IO Bus Status
- */
- for (i = 0; i < IOBUS_PER_PORT; i++) {
-
- SC_DEBUG(1, (CE_WARN, " IO Bus Status "
- "bus=%d status=0x%x\n", i,
- gdcd->dcd_prd[expander][prd_slot].prd_iobus_rsv[i]));
-
- if (RSV_GOOD(
- gdcd->dcd_prd[expander][prd_slot].prd_iobus_rsv[i])) {
- pcd->spcd_iobus_rsv[i] = SPCD_RSV_PASS;
- } else {
- pcd->spcd_iobus_rsv[i] = SPCD_RSV_FAIL;
- }
-
- for (j = 0; j < IOCARD_PER_BUS; j++)
- pcd->spcd_iocard_rsv[i][j] = SPCD_RSV_FAIL;
-
- /*
- * Fill in IO Card Status
- */
- for (j = 0; j < IOCARD_PER_BUS; j++) {
-
- SC_DEBUG(1, (CE_WARN, " Card Status bus=%d "
- "slot=%d status=0x%x\n", i, j,
- gdcd->dcd_prd[expander][prd_slot].
- prd_iocard_rsv[i][j]));
-
- if (j == 1)
- continue;
-
- if (j == 0)
- slot = 1;
- else
- slot = j;
-
- /*
- * If POST marked the card as GOOD or if the slot
- * is empty, we want to probe for the device.
- */
- if (RSV_GOOD(gdcd->dcd_prd[expander][prd_slot].
- prd_iocard_rsv[i][j]) ||
- (gdcd->dcd_prd[expander][prd_slot].
- prd_iocard_rsv[i][j] == RSV_MISS) ||
- (gdcd->dcd_prd[expander][prd_slot].
- prd_iocard_rsv[i][j] == RSV_EMPTY_CASSETTE))
- pcd->spcd_iocard_rsv[i][slot] = SPCD_RSV_PASS;
- else
- pcd->spcd_iocard_rsv[i][slot] = SPCD_RSV_FAIL;
- }
- }
-
- /*
- * Fill in WIC Link Status
- */
- for (i = 0; i < LINKS_PER_PORT; i++) {
- if (RSV_GOOD(
- gdcd->dcd_prd[expander][prd_slot].prd_wic_links[i])) {
- pcd->spcd_wic_links[i] = SPCD_RSV_PASS;
-
- } else {
- pcd->spcd_wic_links[i] = SPCD_RSV_FAIL;
- }
- }
-
- /*
- * Get data for the "bank-status" property.
- */
- pcd->sprd_bank_rsv[0] =
- rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[0][0]);
- pcd->sprd_bank_rsv[1] =
- rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[1][0]);
- pcd->sprd_bank_rsv[2] =
- rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[0][1]);
- pcd->sprd_bank_rsv[3] =
- rsv_string(gdcd->dcd_prd[expander][prd_slot].prd_bank_rsv[1][1]);
-
- dimm = 0;
- for (i = 0; i < PMBANKS_PER_PORT; i++) {
- for (j = 0; j < DIMMS_PER_PMBANK; j++) {
- if (dimm < MAX_DIMMS_PER_PORT) {
- pcd->sprd_dimm[dimm] = rsv_string(
- gdcd->dcd_prd[expander][prd_slot].
- prd_dimm[i][j]);
- dimm++;
- }
- }
- }
-
- /*
- * Get data for the "ecache-dimm-label" property.
- *
- * Right now it is hardcoded, but we should eventually get this
- * from the SC.
- */
- label1 = NULL;
- label2 = NULL;
-
- switch (prd_slot) {
- case 0:
- label1 = "4400";
- label2 = "4300";
- break;
- case 1:
- label1 = "5400";
- label2 = "5300";
- break;
- case 2:
- label1 = "6400";
- label2 = "6300";
- break;
- case 3:
- label1 = "7400";
- label2 = "7300";
- break;
-
- /*
- * Maxcat labels.
- */
- case 4:
- label1 = "6400";
- label2 = "6300";
- break;
- case 5:
- label1 = "7400";
- label2 = "7300";
- break;
- }
-
- i = 0;
- if (label1) {
- pcd->sprd_ecache_dimm_label[i] =
- kmem_alloc(strlen(label1) + 1, KM_SLEEP);
-
- (void) strcpy(pcd->sprd_ecache_dimm_label[i], label1);
-
- i++;
- }
- if (label2) {
- pcd->sprd_ecache_dimm_label[i] =
- kmem_alloc(strlen(label2) + 1, KM_SLEEP);
-
- (void) strcpy(pcd->sprd_ecache_dimm_label[i], label2);
-
- i++;
-
- }
-
- kmem_free(gdcd, sizeof (gdcd_t));
-
-#ifdef DEBUG
- dump_pcd(pcd);
-#endif
-
- return (pcd);
-}
-
-void
-sc_free_common_pcd(spcd_t *pcd)
-{
- int i;
-
- SC_DEBUG(1, (CE_WARN, "sc_free_common_pcd pcd=%p\n", (void *)pcd));
-
- if (pcd->memory_layout && pcd->memory_layout_size) {
- SC_DEBUG(1, (CE_WARN, "sc_free_common_pcd: memory_layout %p "
- "size=%x", (void *)pcd->memory_layout,
- pcd->memory_layout_size));
- kmem_free(pcd->memory_layout, pcd->memory_layout_size);
- }
-
- for (i = 0; i < MAX_BANKS_PER_PORT; i++) {
- if (pcd->sprd_bank_rsv[i]) {
- kmem_free(pcd->sprd_bank_rsv[i],
- strlen(pcd->sprd_bank_rsv[i]) + 1);
-
- pcd->sprd_bank_rsv[i] = NULL;
- }
- }
-
- for (i = 0; i < MAX_DIMMS_PER_PORT; i++) {
- if (pcd->sprd_dimm[i]) {
- kmem_free(pcd->sprd_dimm[i],
- strlen(pcd->sprd_dimm[i]) + 1);
-
- pcd->sprd_dimm[i] = NULL;
- }
- if (pcd->sprd_ecache_dimm_label[i]) {
- kmem_free(pcd->sprd_ecache_dimm_label[i],
- strlen(pcd->sprd_ecache_dimm_label[i]) + 1);
-
- pcd->sprd_ecache_dimm_label[i] = NULL;
- }
- }
-
- kmem_free(pcd, sizeof (spcd_t));
-}
-
-sc_gptwocfg_cookie_t
-sc_probe_board(uint_t board)
-{
- return (sc_configure(board, 1));
-}
-
-static sc_gptwocfg_cookie_t
-sc_configure(uint_t board, int create_nodes)
-{
- spcd_t *pcd;
- dev_info_t *ap, *axq_dip;
- uint_t agent_id;
- uint_t prd_slot, prd_slot_start, prd_slot_end;
- uint_t expander, slot;
- gptwo_new_nodes_t *new_nodes;
- gptwocfg_config_t *port_cookie;
- struct sc_gptwocfg_config *board_config, *last, *new;
- int created_node = 0;
- uint32_t size;
-
- SC_DEBUG(1, (CE_WARN, "sc_configure: board=%d, create_nodes=%d\n",
- board, create_nodes));
-
- if (board > 35) {
- SC_DEBUG(1, (CE_WARN, "sc_gptwocfg - probe_board - "
- "invalid board 0x%x\n", board));
- return (NULL);
- }
-
- slot = board & 1; /* Extract Slot Number */
- expander = board >> 1; /* Extract Expander Number */
-
- SC_DEBUG(1, (CE_WARN, "sc_configure: exp=0x%x slot=0x%x\n",
- expander, slot));
-
- /*
- * Get the Attachment Point. For Starcat the parent of all
- * Safari children is root node.
- */
- ap = ddi_root_node();
-
- /*
- * Get the agent id of the AXQ.
- */
- agent_id = (expander << 5) | 0x1e | slot;
-
- /*
- * Look to see if the board is already configured by searching for
- * its AXQ.
- */
- if (create_nodes && (axq_dip = sc_find_axq_node(agent_id))) {
- ddi_release_devi(axq_dip);
- cmn_err(CE_WARN, "Board %d AXQ is already configured\n",
- board);
- return (NULL);
- }
-
- /*
- * Probe AXQ first
- */
- SC_DEBUG(1, (CE_WARN, "sc_configure: Probing AXQ exp=0x%x brd=0x%x\n",
- expander, slot));
-
- /*
- * The generic gptwocfg does not support the AXQ, so we need
- * to configure it. The AXQ branch is returned held.
- */
- new_nodes = sc_gptwocfg_configure_axq(ap, agent_id, create_nodes);
-
- if (new_nodes == NULL) {
- SC_DEBUG(1, (CE_WARN, "sc_configure: Can not probe AXQ\n"));
- return (NULL);
- }
-
- port_cookie = kmem_zalloc(sizeof (gptwocfg_config_t), KM_SLEEP);
-
- /*
- * Build a cookie for the AXQ.
- */
- port_cookie->gptwo_ap = ap;
- port_cookie->gptwo_portid = agent_id;
- port_cookie->gptwo_nodes = new_nodes;
-
- board_config = kmem_zalloc(sizeof (sc_gptwocfg_config_t), KM_SLEEP);
-
- board_config->port_cookie = port_cookie;
- board_config->board = board;
- board_config->portid = agent_id;
- board_config->link = NULL;
- last = board_config;
-
- mutex_enter(&sc_gptwo_config_list_lock);
- board_config->next = sc_gptwo_config_list;
- sc_gptwo_config_list = board_config;
- mutex_exit(&sc_gptwo_config_list_lock);
-
- SC_DEBUG(1, (CE_WARN, "sc_configure: AXQ Probing Complete. "
- "%d nodes added\n", new_nodes->gptwo_number_of_nodes));
-
- /*
- * Determine the starting ending slots of the PRD array.
- */
- switch (slot) {
- case 0: /* Full Bandwidth Slot */
- prd_slot_start = 0;
- prd_slot_end = 3;
- break;
- case 1: /* Half Bandwidth Slot */
- prd_slot_start = 4;
- prd_slot_end = 5;
- break;
- default:
- SC_DEBUG(1, (CE_WARN, "Unknown Board Address - "
- "Can not probe\n"));
- return (board_config);
- }
-
- /*
- * For each valid PRD entry, determine the agent id which is based
- * on what type of device is described by the slot, and then
- * call the safari configurator.
- */
- for (prd_slot = prd_slot_start; prd_slot <= prd_slot_end; prd_slot++) {
-
- pcd = sc_get_common_pcd(expander, prd_slot);
-
- if (pcd == NULL) {
-
- /*
- * We can not get a PCD for this port so skip it.
- */
- cmn_err(CE_WARN, "sc_gptwocfg: Can not get PCD "
- "expander 0x%x prd slot 0x%x\n",
- expander, prd_slot);
-
- return (board_config);
- }
-
- /*
- * Only configure good devices.
- */
- if (pcd->spcd_prsv == SPCD_RSV_PASS) {
- /*
- * Determine the agent id.
- */
- agent_id = sc_get_agent_id(
- pcd, expander, slot, prd_slot);
-
- pcd->memory_layout = get_memlayout(agent_id, &size);
- pcd->memory_layout_size = size;
-
- /*
- * Call Platform Independent gptwo configurator to
- * create node and properties.
- */
- if (create_nodes) {
- port_cookie =
- gptwocfg_configure(ap, pcd, agent_id);
- if (port_cookie)
- created_node++;
- }
-
- new = kmem_zalloc
- (sizeof (sc_gptwocfg_config_t), KM_SLEEP);
-
- /*
- * XXX Shouldn't port_cookie be NULL if
- * !create_nodes ?
- */
- new->port_cookie = port_cookie;
- new->portid = agent_id;
- new->link = NULL;
- last->link = new;
- last = new;
- } else {
- SC_DEBUG(1, (CE_WARN, "sc_configure: Bad Agent "
- "Exp=0x%x PRD Slot=0x%x prsv Status=0x%x\n",
- expander, prd_slot, pcd->spcd_prsv));
- }
-
- sc_free_common_pcd(pcd);
-
- } /* for loop */
-
- dump_config(board_config);
-
- if (create_nodes && !created_node) {
- SC_DEBUG(1, (CE_WARN, "sc_configure: GPTWO Devices failed "
- "to configure - unprobing board %d\n", board));
- board_config = sc_unprobe_board(board);
- }
-
- SC_DEBUG(1, (CE_WARN, "sc_configure: Returning 0x%p\n",
- (void *)board_config));
-
- return (board_config);
-}
-
-sc_gptwocfg_cookie_t
-sc_unprobe_board(uint_t board)
-{
- sc_gptwocfg_config_t *board_config, *axq_config, *prior_config;
- gptwocfg_cookie_t port_cookie;
-
- SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: board=%d\n", board));
-
- if (board > 35) {
- SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: "
- "invalid board 0x%x\n", board));
- return (NULL);
- }
- mutex_enter(&sc_gptwo_config_list_lock);
- board_config = sc_gptwo_config_list;
- while (board_config != NULL) {
- if (board_config->board == board) {
- break;
- }
- board_config = board_config->next;
- }
- mutex_exit(&sc_gptwo_config_list_lock);
-
- if (board_config == NULL) {
-
- SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: No "
- "config structure board=0x%x\n", board));
-
- /*
- * Configure the board without creating nodes.
- */
- board_config = sc_configure(board, 0);
-
- if (board_config == NULL) {
-
- cmn_err(CE_WARN, "sc_gptwocfg: sc_unprobe_board: "
- "Unable to unconfigure board %d - board is not "
- "configured\n", board);
-
- return (NULL);
- }
- }
-
- axq_config = board_config;
-
- /*
- * Walk the link of ports on this board and unconfigure them.
- * Save the AXQ for last.
- */
- while (board_config->link != NULL) {
- prior_config = board_config;
- board_config = board_config->link;
-
- SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: "
- "calling gptwocfg_unconfigure(ap=0x%p portid=0x%x)\n",
- (void *)ddi_root_node(), board_config->portid));
-
- port_cookie = gptwocfg_unconfigure(ddi_root_node(),
- board_config->portid);
-
- SC_DEBUG(1, (CE_WARN, "sc_unprobe_board: "
- "gptwocfg_unconfigure returned cookie=0x%p\n",
- port_cookie));
-
- if (port_cookie == NULL) {
- /*
- * Can be removed from list.
- */
- prior_config->link = board_config->link;
- kmem_free(board_config, sizeof (sc_gptwocfg_config_t));
- board_config = prior_config;
- } else {
- board_config->port_cookie = port_cookie;
- }
- }
-
- if (axq_config->link == NULL) {
-
- /*
- * If all the other Safari devices have been successfully
- * unconfigured, then the AXQ can be unconfigured.
- */
- axq_config->port_cookie =
- sc_gptwocfg_unconfigure_axq(axq_config->port_cookie);
-
- if (axq_config->port_cookie == NULL) {
-
- /*
- * If the AXQ was successfully unconfigured, then
- * the board is removed from the configured list.
- */
- mutex_enter(&sc_gptwo_config_list_lock);
- if (sc_gptwo_config_list == axq_config) {
- sc_gptwo_config_list = axq_config->next;
- } else {
- board_config = sc_gptwo_config_list;
- while (board_config->next != axq_config) {
- board_config = board_config->next;
- }
- board_config->next = axq_config->next;
- }
- mutex_exit(&sc_gptwo_config_list_lock);
- kmem_free(axq_config, sizeof (sc_gptwocfg_config_t));
- axq_config = NULL;
- }
- }
- dump_config(axq_config);
- return (axq_config);
-}
-
-int
-sc_next_node(sc_gptwocfg_cookie_t c, dev_info_t *previous, dev_info_t **next)
-{
- dev_info_t *dip;
- sc_gptwocfg_config_t *cookie;
-
- SC_DEBUG(1, (CE_WARN, "sccfg: sccfg_next_node"
- "(c=0x%p, previous=0x%p, next=0x%p)\n", (void *)c,
- (void *)previous, (void *)next));
-
- cookie = (sc_gptwocfg_config_t *)c;
-
- if (cookie == NULL) {
- cmn_err(CE_WARN, "sccfg: sccfg_next_node - "
- "Invalid Cookie\n");
- return (0);
- }
- if (previous == NULL) {
- /*
- * Start with the AXQ node.
- */
- if (gptwocfg_next_node(cookie->port_cookie, NULL, &dip)) {
- *next = dip;
- return (1);
- } else {
- return (0);
- }
- }
-
- while (cookie != NULL) {
- if (gptwocfg_next_node(cookie->port_cookie, previous, &dip)) {
- if ((dip == NULL) && (cookie->link == NULL)) {
- *next = NULL;
- return (1);
- }
- if (dip != NULL) {
- *next = dip;
- return (1);
- }
-
- /* dip == NULL */
-
- previous = NULL;
- }
- cookie = cookie->link;
- }
-
- return (0);
-}
-
-static dev_info_t *
-sc_find_axq_node(uint_t axq_id)
-{
- char *name;
- int size;
- gptwo_regspec_t *reg;
- dev_info_t *dip;
- uint_t id;
- int circ;
-
- SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: id=0x%x\n", axq_id));
-
- /*
- * Hold root node busy to walk its child list
- */
- ndi_devi_enter(ddi_root_node(), &circ);
-
- dip = ddi_get_child(ddi_root_node());
-
- while (dip != NULL) {
-
- SC_DEBUG(1, (CE_CONT, "Searching dip=0x%p for our AXQ\n",
- (void *)dip));
-
- if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "name", (caddr_t)&name, &size)
- != DDI_PROP_SUCCESS) {
-
- /*
- * This node does not have a name property.
- */
- SC_DEBUG(1, (CE_CONT, "dip=0x%p does not have a "
- "'name' property\n", (void *)dip));
-
- dip = ddi_get_next_sibling(dip);
- continue;
- }
-
- SC_DEBUG(1, (CE_CONT, "dip=0x%p name=%s\n", (void *)dip, name));
-
- if (strcmp(name, "address-extender-queue")) {
-
- /*
- * This node is not a AXQ node.
- */
- SC_DEBUG(1, (CE_CONT, "dip=0x%p is not an AXQ "
- "node\n", (void *)dip));
- kmem_free(name, size);
- dip = ddi_get_next_sibling(dip);
- continue;
- }
- kmem_free(name, size);
-
- if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "reg", (caddr_t)&reg, &size)
- != DDI_PROP_SUCCESS) {
-
- /*
- * This AXQ node does not have a reg property.
- */
- SC_DEBUG(1, (CE_CONT, "dip=0x%p (AXQ Node) does "
- "have a 'reg' property\n", (void *)dip));
- dip = ddi_get_next_sibling(dip);
- continue;
- }
-
- id = ((reg[0].gptwo_phys_hi & 1) << 9) |
- ((reg[0].gptwo_phys_low & 0xff800000) >> 23);
-
- kmem_free(reg, size);
-
- if (axq_id != id) {
-
- /*
- * This is the wrong AXQ node.
- */
- SC_DEBUG(1, (CE_CONT, "dip=0x%p Wrong node id=0x%x\n",
- (void *)dip, id));
-
- dip = ddi_get_next_sibling(dip);
- continue;
-
- }
-
- /*
- * The correct AXQ node was found.
- */
- SC_DEBUG(1, (CE_CONT, "dip=0x%p Found AXQ Node\n",
- (void *)dip));
- ndi_hold_devi(dip);
- break;
- }
- ndi_devi_exit(ddi_root_node(), circ);
-
- SC_DEBUG(1, (CE_CONT, "sc_find_axq_node: Returning 0x%p\n",
- (void *)dip));
-
- return (dip);
-}
-
-struct axq_arg {
- uint_t id;
- dev_info_t *axq_dip;
-};
-
-/*ARGSUSED*/
-static int
-axq_set_prop(dev_info_t *axq_dip, void *arg, uint_t flags)
-{
- struct axq_arg *aqp = (struct axq_arg *)arg;
- gptwo_regspec_t reg[2];
- uint_t id;
-
- ASSERT(aqp);
-
- id = aqp->id;
-
- if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip,
- "name", "address-extender-queue") != DDI_SUCCESS) {
- SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed "
- "to create name property\n"));
- return (DDI_WALK_ERROR);
- }
-
- if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip,
- "device_type", "address-extender-queue") != DDI_SUCCESS) {
- SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed "
- "to create device_type property\n"));
- return (DDI_WALK_ERROR);
- }
-
- if (ndi_prop_update_string(DDI_DEV_T_NONE, axq_dip,
- "compatible", "SUNW,axq") != DDI_SUCCESS) {
- SC_DEBUG(1, (CE_CONT, "sc_gptwocfg: failed "
- "to create compatible property\n"));
- return (DDI_WALK_ERROR);
- }
-
- if (ndi_prop_update_int(DDI_DEV_T_NONE, axq_dip,
- "portid", id) != DDI_SUCCESS) {
- SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed "
- "to create portid property\n"));
- return (DDI_WALK_ERROR);
- }
-
- reg[0].gptwo_phys_hi = 0x400 | (id >> 9);
- reg[0].gptwo_phys_low = (id << 23);
- reg[0].gptwo_size_hi = 0;
- reg[0].gptwo_size_low = 0x520;
-
- reg[1].gptwo_phys_hi = 0x401;
- reg[1].gptwo_phys_low = 0xf0000000;
- reg[1].gptwo_size_hi = 0;
- reg[1].gptwo_size_low = 0x520;
-
- if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
- axq_dip, "reg", (int *)&reg,
- (sizeof (gptwo_regspec_t) * 2)/sizeof (int)) != DDI_SUCCESS) {
- SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_pci: failed "
- "to create reg property\n"));
- return (DDI_WALK_ERROR);
- }
-
- return (DDI_WALK_TERMINATE);
-}
-
-/*ARGSUSED*/
-static void
-get_axq_dip(dev_info_t *rdip, void *arg, uint_t flags)
-{
- struct axq_arg *aqp = (struct axq_arg *)arg;
-
- ASSERT(aqp);
-
- aqp->axq_dip = rdip;
-}
-
-static gptwo_new_nodes_t *
-sc_gptwocfg_configure_axq(dev_info_t *ap, uint_t id, int create_nodes)
-{
- struct axq_arg arg = {0};
- devi_branch_t b = {0};
- dev_info_t *axq_dip, *fdip = NULL;
- gptwo_new_nodes_t *new_nodes = NULL;
- int rv;
-
- SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: id=0x%x "
- "create_nodes=%d\n", id, create_nodes));
-
- if (!create_nodes) {
- axq_dip = sc_find_axq_node(id);
-
- if (axq_dip) {
- new_nodes = gptwocfg_allocate_node_list(1);
- new_nodes->gptwo_nodes[0] = axq_dip;
- ASSERT(!e_ddi_branch_held(axq_dip));
- e_ddi_branch_hold(axq_dip);
- /*
- * Release hold from sc_find_axq_node()
- */
- ddi_release_devi(axq_dip);
- }
-
- SC_DEBUG(1, (CE_CONT, "gptwocfg_configure_axq: "
- "Returning 0x%p\n", (void *)new_nodes));
-
- return (new_nodes);
- }
-
- arg.id = id;
- arg.axq_dip = NULL;
-
- b.arg = &arg;
- b.type = DEVI_BRANCH_SID;
- b.create.sid_branch_create = axq_set_prop;
- b.devi_branch_callback = get_axq_dip;
-
- rv = e_ddi_branch_create(ap, &b, &fdip, DEVI_BRANCH_CONFIGURE);
- if (rv != 0) {
- char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
-
- /*
- * If non-NULL, fdip is held and must be released.
- */
- if (fdip != NULL) {
- (void) ddi_pathname(fdip, path);
- ddi_release_devi(fdip);
- } else {
- (void) ddi_pathname(ap, path);
- }
-
- SC_DEBUG(1, (CE_WARN, "e_ddi_branch_create failed: "
- "path=%s, dip=%p, rv=%d", path, fdip ? (void *)fdip :
- (void *)ap, rv));
-
- kmem_free(path, MAXPATHLEN);
-
- return (NULL);
- }
-
- axq_dip = arg.axq_dip;
-
- new_nodes = gptwocfg_allocate_node_list(1);
- new_nodes->gptwo_nodes[0] = axq_dip;
-
- return (new_nodes);
-}
-
-static gptwocfg_config_t *
-sc_gptwocfg_unconfigure_axq(gptwocfg_config_t *config)
-{
- int i;
- int failure = 0;
- dev_info_t *saf_dip;
-
- if (config == NULL) {
- cmn_err(CE_WARN, "sc_gptwocfg: sc_gptwocfg_unconfigure_axq: "
- "Invalid AXQ\n");
- return (NULL);
- }
- for (i = 0; i < config->gptwo_nodes->gptwo_number_of_nodes; i++) {
- int rv;
- dev_info_t *fdip = NULL;
-
- saf_dip = config->gptwo_nodes->gptwo_nodes[i];
- ASSERT(e_ddi_branch_held(saf_dip));
- rv = e_ddi_branch_destroy(saf_dip, &fdip, 0);
- if (rv != 0) {
- char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
-
- /*
- * If non-NULL, fdip is held and must be released.
- */
- if (fdip != NULL) {
- (void) ddi_pathname(fdip, path);
- ddi_release_devi(fdip);
- } else {
- (void) ddi_pathname(saf_dip, path);
- }
-
- cmn_err(CE_CONT, "AXQ node removal failed: "
- "path=%s, dip=%p, rv=%d\n", path,
- fdip ? (void *)fdip : (void *)saf_dip, rv);
-
- kmem_free(path, MAXPATHLEN);
- failure = 1;
- } else {
- config->gptwo_nodes->gptwo_nodes[i] = NULL;
- }
- }
- if (!failure) {
- gptwocfg_free_node_list(config->gptwo_nodes);
-
- kmem_free(config, sizeof (gptwocfg_config_t));
- config = NULL;
- }
- return (config);
-}
-
-static uint_t
-sc_get_agent_id(spcd_t *pcd, uint_t expander, uint_t slot, uint_t prd_slot)
-{
- uint_t agent_id;
-
- switch (pcd->spcd_ptype) {
- case SAFPTYPE_CPU:
- if (slot == 0) {
- agent_id = prd_slot;
- } else {
- if (prd_slot == 4) {
- agent_id = 8;
- } else {
- agent_id = 9;
- }
- }
- break;
-
- case SAFPTYPE_sPCI:
- case SAFPTYPE_cPCI:
- case SAFPTYPE_PCIX:
- if (prd_slot == 4) {
- agent_id = 0x1c;
- } else {
- agent_id = 0x1d;
- }
- break;
- case SAFPTYPE_WCI:
- agent_id = 0x1d;
- break;
- default:
- cmn_err(CE_WARN, "sc_gptwocfg: Invalid Safari Port "
- "Type 0x%x Slot 0x%x\n",
- pcd->spcd_ptype, prd_slot);
- } /* switch */
-
- agent_id |= (expander << 5);
-
- SC_DEBUG(1, (CE_CONT, "sc_get_agent_id(pcd=0x%p, expander=0x%x, "
- "prd_slot=0x%x) Returning agent_id=0x%x\n", (void *)pcd, expander,
- prd_slot, agent_id));
-
- return (agent_id);
-}
-
-static void
-dump_config(sc_gptwocfg_config_t *board_config)
-{
- gptwocfg_config_t *port;
-
- SC_DEBUG(1, (CE_CONT, "dump_config 0x%p", (void *)board_config));
- while (board_config != NULL) {
- SC_DEBUG(1, (CE_CONT, "************* 0x%p ************\n",
- (void *)board_config));
- SC_DEBUG(1, (CE_CONT, "port_cookie - 0x%p\n",
- (void *)board_config->port_cookie));
-
- port = board_config->port_cookie;
- if (port) {
- SC_DEBUG(1, (CE_CONT, " ap - 0x%p\n",
- (void *)port->gptwo_ap));
- SC_DEBUG(1, (CE_CONT, " portid - 0x%x\n",
- port->gptwo_portid));
- }
- SC_DEBUG(1, (CE_CONT, "portid - 0x%x\n",
- board_config->portid));
- SC_DEBUG(1, (CE_CONT, "board - 0x%x\n",
- board_config->board));
- SC_DEBUG(1, (CE_CONT, "link - 0x%p\n",
- (void *)board_config->link));
- SC_DEBUG(1, (CE_CONT, "next - 0x%p\n",
- (void *)board_config->next));
- board_config = board_config->link;
- }
-}
-
-static void
-dump_pcd(spcd_t *pcd)
-{
- int i;
-
- SC_DEBUG(1, (CE_CONT, "dump_pcd 0x%p", (void *)pcd));
- SC_DEBUG(1, (CE_CONT, " magic - 0x%x\n", pcd->spcd_magic));
- SC_DEBUG(1, (CE_CONT, " version - 0x%x\n", pcd->spcd_version));
- SC_DEBUG(1, (CE_CONT, " ver.reg - 0x%lx\n", pcd->spcd_ver_reg));
- SC_DEBUG(1, (CE_CONT, " afreq - %d\n", pcd->spcd_afreq));
- switch (pcd->spcd_ptype) {
- case SAFPTYPE_CPU:
- SC_DEBUG(1, (CE_CONT, " ptype - CPU\n"));
- break;
- case SAFPTYPE_sPCI:
- SC_DEBUG(1, (CE_CONT, " ptype - sPCI\n"));
- break;
- case SAFPTYPE_cPCI:
- SC_DEBUG(1, (CE_CONT, " ptype - cPCI\n"));
- break;
- case SAFPTYPE_PCIX:
- SC_DEBUG(1, (CE_CONT, " ptype - sPCI+\n"));
- break;
- case SAFPTYPE_WCI:
- SC_DEBUG(1, (CE_CONT, " ptype - WIC\n"));
- break;
- default:
- SC_DEBUG(1, (CE_CONT, " ptype - 0x%x\n",
- pcd->spcd_ptype));
- break;
- }
- SC_DEBUG(1, (CE_CONT, " cache - %d\n", pcd->spcd_cache));
-
- if (pcd->spcd_prsv == SPCD_RSV_PASS) {
- SC_DEBUG(1, (CE_CONT, " prsv - SPCD_RSV_PASS\n"));
- } else {
- SC_DEBUG(1, (CE_CONT, " prsv - 0x%x (FAIL)\n",
- pcd->spcd_prsv));
- }
-
- for (i = 0; i < AGENTS_PER_PORT; i++) {
- if (pcd->spcd_agent[i] == SPCD_RSV_PASS) {
- SC_DEBUG(1, (CE_CONT, " agent[%d] "
- "- SPCD_RSV_PASS\n", i));
- } else {
- SC_DEBUG(1, (CE_CONT, " agent[%d] "
- "- 0x%x (FAIL)\n", i, pcd->spcd_agent[i]));
- }
- }
-
- if (pcd->spcd_ptype == SAFPTYPE_CPU) {
- for (i = 0; i < AGENTS_PER_PORT; i++) {
- SC_DEBUG(1, (CE_CONT, " cpuid[%d] - 0x%x\n",
- i, pcd->spcd_cpuid[i]));
- }
- }
-
- SC_DEBUG(1, (CE_CONT, " Banks\n"));
- for (i = 0; i < MAX_BANKS_PER_PORT; i++) {
- if (pcd->sprd_bank_rsv[i]) {
- SC_DEBUG(1, (CE_CONT, " %d %s\n", i,
- pcd->sprd_bank_rsv[i]));
- }
- }
-
- SC_DEBUG(1, (CE_CONT, " Dimms\n"));
- for (i = 0; i < MAX_DIMMS_PER_PORT; i++) {
- if (pcd->sprd_dimm[i]) {
- SC_DEBUG(1, (CE_CONT, " %d %s\n", i,
- pcd->sprd_dimm[i]));
- }
- }
- SC_DEBUG(1, (CE_CONT, " Ecache Dimm Labels\n"));
- for (i = 0; i < MAX_DIMMS_PER_PORT; i++) {
- if (pcd->sprd_ecache_dimm_label[i]) {
- SC_DEBUG(1, (CE_CONT, " %d %s\n", i,
- pcd->sprd_ecache_dimm_label[i]));
- }
- }
-}
-
-
-typedef struct {
- char Jnumber[8][8];
- uint8_t sym_flag;
- uint8_t d_dimmtable[144];
- uint8_t d_pintable[576];
-}m_layout;
-
-/*
- * Use 2 bits to represent each bit at a cache line. The table
- * is in big endian order, i.e.
- * dimmtable[0], ... , dimmtable[143]
- * Q0:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0]
- * .
- * .
- * Q3:data-bits[127 126 125 124], ... , MtagEcc[3 2 1 0]
- */
-uint8_t J_dimm_pinTable[] = {
-/* Jnumber */
-/* 0 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x30, 0x00, 0x00,
-/* 1 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x30, 0x00, 0x00,
-/* 2 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x30, 0x00, 0x00,
-/* 3 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x30, 0x00, 0x00,
-/* 4 */ 0x4a, 0x31, 0x33, 0x33, 0x30, 0x31, 0x00, 0x00,
-/* 5 */ 0x4a, 0x31, 0x33, 0x34, 0x30, 0x31, 0x00, 0x00,
-/* 6 */ 0x4a, 0x31, 0x33, 0x35, 0x30, 0x31, 0x00, 0x00,
-/* 7 */ 0x4a, 0x31, 0x33, 0x36, 0x30, 0x31, 0x00, 0x00,
-/* flag */ 0x01,
-/* -- Q0 -- */
-/* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff,
-/* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55,
-/* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00,
-/* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80,
-/* 4 */ 0xe7, 0xe3, 0x9b, 0x1b,
-/* -- Q1 -- */
-/* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff,
-/* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55,
-/* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00,
-/* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80,
-/* 4 */ 0xe7, 0xe3, 0x9b, 0x1b,
-/* -- Q2 -- */
-/* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff,
-/* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55,
-/* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00,
-/* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80,
-/* 4 */ 0xe7, 0xe3, 0x9b, 0x1b,
-/* -- Q3 -- */
-/* 0 */ 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa, 0xff,
-/* 1 */ 0x00, 0xaa, 0xff, 0x00, 0x56, 0xaf, 0x00, 0x55,
-/* 2 */ 0xaa, 0x55, 0xaf, 0xc0, 0x55, 0xaa, 0xff, 0x00,
-/* 3 */ 0x55, 0xff, 0x00, 0x55, 0xaa, 0xff, 0x6d, 0x80,
-/* 4 */ 0xe7, 0xe3, 0x9b, 0x1b,
-/*
- * In the following order
- * pintable[0], ..., pintable[575]
- * Quadword3, Quadword2, Quadword1, Quadword0
- * MtagEcc, Mtag, Ecc, Data
- */
-/* -- Q3 -- */
-/* 0 */ 227, 227, 227, 227, 111, 111, 111, 22,
-/* 1 */ 22, 32, 138, 222, 81, 117, 117, 117,
-/* 2 */ 111, 222, 106, 222, 222, 106, 106, 106,
-/* 3 */ 217, 101, 212, 96, 217, 101, 212, 96,
-/* 4 */ 217, 101, 212, 96, 217, 101, 212, 96,
-/* 5 */ 207, 91, 202, 86, 187, 71, 158, 42,
-/* 6 */ 187, 71, 158, 42, 153, 37, 148, 32,
-/* 7 */ 153, 37, 148, 32, 153, 37, 148, 32,
-/* 8 */ 153, 37, 148, 143, 27, 138, 143, 27,
-/* 9 */ 143, 27, 138, 22, 207, 91, 202, 86,
-/* 10 */ 207, 91, 202, 86, 207, 91, 202, 86,
-/* 11 */ 192, 76, 81, 192, 76, 81, 192, 76,
-/* 12 */ 197, 81, 192, 76, 187, 71, 158, 42,
-/* 13 */ 187, 71, 158, 42, 143, 27, 138, 22,
-/* 14 */ 133, 17, 128, 12, 133, 17, 128, 12,
-/* 15 */ 133, 17, 128, 12, 133, 17, 128, 12,
-/* 16 */ 123, 07, 118, 2, 123, 07, 118, 2,
-/* 17 */ 123, 07, 118, 2, 123, 07, 118, 2,
-/* -- Q2 -- */
-/* 0 */ 228, 228, 228, 228, 112, 112, 112, 23,
-/* 1 */ 23, 33, 139, 223, 82, 118, 118, 118,
-/* 2 */ 112, 223, 107, 223, 223, 107, 107, 107,
-/* 3 */ 218, 102, 213, 97, 218, 102, 213, 97,
-/* 4 */ 218, 102, 213, 97, 218, 102, 213, 97,
-/* 5 */ 208, 92, 203, 87, 188, 72, 159, 43,
-/* 6 */ 188, 72, 159, 43, 154, 38, 149, 33,
-/* 7 */ 154, 38, 149, 33, 154, 38, 149, 33,
-/* 8 */ 154, 38, 149, 144, 28, 139, 144, 28,
-/* 9 */ 144, 28, 139, 23, 208, 92, 203, 87,
-/* 10 */ 208, 92, 203, 87, 208, 92, 203, 87,
-/* 11 */ 193, 77, 82, 193, 77, 82, 193, 77,
-/* 12 */ 198, 82, 193, 77, 188, 72, 159, 43,
-/* 13 */ 188, 72, 159, 43, 144, 28, 139, 23,
-/* 14 */ 134, 18, 129, 13, 134, 18, 129, 13,
-/* 15 */ 134, 18, 129, 13, 134, 18, 129, 13,
-/* 16 */ 124, 8, 119, 3, 124, 8, 119, 3,
-/* 17 */ 124, 8, 119, 3, 124, 8, 119, 3,
-/* -- Q1 -- */
-/* 0 */ 229, 229, 229, 229, 113, 113, 113, 24,
-/* 1 */ 24, 34, 140, 224, 83, 119, 119, 119,
-/* 2 */ 113, 224, 108, 224, 224, 108, 108, 108,
-/* 3 */ 219, 103, 214, 98, 219, 103, 214, 98,
-/* 4 */ 219, 103, 214, 98, 219, 103, 214, 98,
-/* 5 */ 209, 93, 204, 88, 189, 73, 160, 44,
-/* 6 */ 189, 73, 160, 44, 155, 39, 150, 34,
-/* 7 */ 155, 39, 150, 34, 155, 39, 150, 34,
-/* 8 */ 155, 39, 150, 145, 29, 140, 145, 29,
-/* 9 */ 145, 29, 140, 24, 209, 93, 204, 88,
-/* 10 */ 209, 93, 204, 88, 209, 93, 204, 88,
-/* 11 */ 194, 78, 83, 194, 78, 83, 194, 78,
-/* 12 */ 199, 83, 194, 78, 189, 73, 160, 44,
-/* 13 */ 189, 73, 160, 44, 145, 29, 140, 24,
-/* 14 */ 135, 19, 130, 14, 135, 19, 130, 14,
-/* 15 */ 135, 19, 130, 14, 135, 19, 130, 14,
-/* 16 */ 125, 9, 120, 4, 125, 9, 120, 4,
-/* 17 */ 125, 9, 120, 4, 125, 9, 120, 4,
-/* -- Q0 -- */
-/* 0 */ 230, 230, 230, 230, 114, 114, 114, 25,
-/* 1 */ 25, 35, 141, 225, 84, 200, 200, 200,
-/* 2 */ 114, 225, 109, 225, 225, 109, 109, 109,
-/* 3 */ 220, 104, 215, 99, 220, 104, 215, 99,
-/* 4 */ 220, 104, 215, 99, 220, 104, 215, 99,
-/* 5 */ 210, 94, 205, 89, 190, 74, 161, 45,
-/* 6 */ 190, 74, 161, 45, 156, 40, 151, 35,
-/* 7 */ 156, 40, 151, 35, 156, 40, 151, 35,
-/* 8 */ 156, 40, 151, 146, 30, 141, 146, 30,
-/* 9 */ 146, 30, 141, 25, 210, 94, 205, 89,
-/* 10 */ 210, 94, 205, 89, 210, 94, 205, 89,
-/* 11 */ 195, 79, 84, 195, 79, 84, 195, 79,
-/* 12 */ 200, 84, 195, 79, 190, 74, 161, 45,
-/* 13 */ 190, 74, 161, 45, 146, 30, 141, 25,
-/* 14 */ 136, 20, 131, 15, 136, 20, 131, 15,
-/* 15 */ 136, 20, 131, 15, 136, 20, 131, 15,
-/* 16 */ 126, 10, 121, 5, 126, 10, 121, 5,
-/* 17 */ 126, 10, 121, 5, 126, 10, 121, 5
-};
-
-/*
- * This table is for internal reference
- *
- * pintable_internal[]= {
- * -- Q0 --
- * 0 143,143,143,143,139,139,139,35
- * 1 35,51,39,135,91,95,95,95
- * 2 139,135,131,135,135,131,131,131
- * 3 127,123,119,115,127,123,119,115
- * 4 127,123,119,115,127,123,119,115
- * 5 111,107,103,99,79,75,71,67
- * 6 79,75,71,67,63,59,55,51
- * 7 63,59,55,51,63,59,55,51
- * 8 63,59,55,47,43,39,47,43
- * 9 47,43,39,35,111,107,103,99
- * 10 111,107,103,99,111,107,103,99
- * 11 87,83,91,87,83,91,87,83
- * 12 95,91,87,83,79,75,71,67
- * 13 79,75,71,67,47,43,39,35
- * 14 31,27,23,19,31,27,23,19
- * 15 31,27,23,19,31,27,23,19
- * 16 15,11,7,3,15,11,7,3
- * 17 15,11,7,3,15,11,7,3
- * }
- */
-
-char *dimm_Jno[] = {
-/* P0 */ "J13300", "J13400", "J13500", "J13600",
- "J13301", "J13401", "J13501", "J13601",
-/* P1 */ "J14300", "J14400", "J14500", "J14600",
- "J14301", "J14401", "J14501", "J14601",
-/* P2 */ "J15300", "J15400", "J15500", "J15600",
- "J15301", "J15401", "J15501", "J15601",
-/* P3 */ "J16300", "J16400", "J16500", "J16600",
- "J16301", "J16401", "J16501", "J16601",
- NULL
- };
-
-
-static uint8_t *
-get_memlayout(uint32_t cpuid, uint32_t *len)
-{
- m_layout *LayoutBuf;
-
- if ((LayoutBuf = (m_layout *)kmem_zalloc(sizeof (m_layout),
- KM_SLEEP)) == NULL) {
- *len = 0;
- return (NULL);
- }
-
- bcopy(J_dimm_pinTable, LayoutBuf, sizeof (m_layout));
-
- *len = sizeof (m_layout);
- cpuid &= 0x03; /* last 2 bits of a 10 bit number */
-
- bcopy(dimm_Jno[cpuid << 3], LayoutBuf->Jnumber[0], 64);
-
- return ((uint8_t *)LayoutBuf);
-}
-
-static char *
-rsv_string(prdrsv_t rsv)
-{
- char *buffer;
- char *status;
-
- switch (rsv) {
- case RSV_UNKNOWN:
- buffer = "unknown";
- break;
- case RSV_PRESENT:
- buffer = "okay";
- break;
- case RSV_CRUNCH:
- buffer = "disabled";
- break;
- case RSV_UNDEFINED:
- buffer = "undefined";
- break;
- case RSV_MISS:
- buffer = "missing";
- break;
- case RSV_EMPTY_CASSETTE:
- buffer = "disabled";
- break;
- case RSV_MISCONFIG:
- buffer = "misconfigured";
- break;
- case RSV_FAIL_OBP:
- buffer = "fail-obp";
- break;
- case RSV_BLACK:
- buffer = "blacklisted";
- break;
- case RSV_RED:
- buffer = "redlisted";
- break;
- case RSV_EXCLUDED:
- buffer = "disabled";
- break;
- case RSV_UNCONFIG:
- buffer = "disabled";
- break;
- case RSV_PASS:
- buffer = "okay";
- break;
- case RSV_FAIL:
- default:
- buffer = "fail";
- break;
- }
-
- status = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
- (void) strcpy(status, buffer);
-
- return (status);
-}
diff --git a/usr/src/uts/sun4u/starcat/io/schpc.c b/usr/src/uts/sun4u/starcat/io/schpc.c
deleted file mode 100644
index 6b22e06a71..0000000000
--- a/usr/src/uts/sun4u/starcat/io/schpc.c
+++ /dev/null
@@ -1,4509 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-/*
- * Starcat IOSRAM/Tunnel PCI Hot Plug Controller Driver
- */
-
-#define CPCI_ENUM
-
-#include <sys/note.h>
-#include <sys/types.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/open.h>
-#include <sys/stat.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-#include <sys/cmn_err.h>
-#include <sys/sunddi.h>
-#include <sys/sunndi.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/ndi_impldefs.h>
-#include <sys/modctl.h>
-#include <sys/disp.h>
-#include <sys/async.h>
-#include <sys/hotplug/hpcsvc.h>
-#include <sys/mboxsc.h>
-#include <sys/schpc_msg.h>
-#include <sys/schpc.h>
-#include <post/scat_dcd.h>
-#include <sys/taskq.h>
-
-#ifdef DEBUG
-int schpc_dump_save_regs = 0;
-static uint_t schpc_debug_flags = 0;
-#define SCHPC_DEBUG0(f, s) if ((f)& schpc_debug_flags) \
- cmn_err(CE_CONT, "schpc: " s "\n")
-#define SCHPC_DEBUG1(f, s, a) if ((f)& schpc_debug_flags) \
- cmn_err(CE_CONT, "schpc: " s "\n", a)
-#define SCHPC_DEBUG2(f, s, a, b) if ((f)& schpc_debug_flags) \
- cmn_err(CE_CONT, "schpc: " s "\n", a, b)
-#define SCHPC_DEBUG3(f, s, a, b, c) if ((f)& schpc_debug_flags) \
- cmn_err(CE_CONT, "schpc: " s "\n", a, b, c)
-#define SCHPC_DEBUG4(f, s, a, b, c, d) if ((f)& schpc_debug_flags) \
- cmn_err(CE_CONT, "schpc: " s "\n", a, b, c, d)
-#define SCHPC_DEBUG5(f, s, a, b, c, d, e) if ((f)& schpc_debug_flags) \
- cmn_err(CE_CONT, "schpc: " s "\n", a, b, c, d, e)
-#define SCHPC_DEBUG6(f, s, a, b, c, d, e, ff) if ((f)& schpc_debug_flags) \
- cmn_err(CE_CONT, "schpc: " s "\n", a, b, c, d, e, ff)
-#else
-
-#define SCHPC_DEBUG0(f, s)
-#define SCHPC_DEBUG1(f, s, a)
-#define SCHPC_DEBUG2(f, s, a, b)
-#define SCHPC_DEBUG3(f, s, a, b, c)
-#define SCHPC_DEBUG4(f, s, a, b, c, d)
-#define SCHPC_DEBUG5(f, s, a, b, c, d, e)
-#define SCHPC_DEBUG6(f, s, a, b, c, d, e, ff)
-
-#endif
-
-#define D_IDENTIFY 0x00000001
-#define D_ATTACH 0x00000002
-#define D_DETACH 0x00000004
-#define D_OPEN 0x00000008
-#define D_GETSLOTSTATUS 0x00000010
-#define D_SETSLOTSTATUS 0x00000020
-#define D_IOCTL 0x00010000
-#define D_IOC_CONNECT 0x00020000
-#define D_IOC_CONTROL 0x00040000
-#define D_IOC_CONFIG 0x00080000
-#define D_IOC_STATUS 0x00100000
-#define D_IOC_MSG 0x00200000
-#define D_IOC_TEST 0x00400000
-#define D_IOC_LED 0x00800000
-#define D_EVENT 0x01000000
-#define D_THREAD 0x02000000
-#define D_TRANSID 0x04000000
-#define D_SLOTTABLE 0x08000000
-#define D_FREQCHG 0x10000000
-#define D_APID 0x20000000
-
-/*
- * driver global data:
- */
-static void *per_schpc_state; /* soft state head */
-dev_info_t *schpc_devi;
-static schpc_t *schpc_p;
-
-clock_t schpc_timeout_putmsg = 60 * 1000; /* 60 seconds */
-clock_t schpc_timeout_getmsg = 60 * 1000; /* 60 seconds */
-clock_t schpc_timeout_event = 60 * 5 * 1000; /* 5 minutes */
-
-int schpc_use_legacy_apid = 0;
-
-static mboxsc_timeout_range_t schpc_putmsg_timeout_range;
-static mboxsc_timeout_range_t schpc_getmsg_timeout_range;
-
-static taskq_t *schpc_event_taskq = NULL;
-
-/*
- * replies to mboxsc_getmsg() are handled asynchronously by the
- * schpc_msg_thread using a linked list of schpc_replylist_t
- * elements
- */
-typedef struct schpc_replylist {
- struct schpc_replylist *prev; /* link to previous entry */
- struct schpc_replylist *next; /* link to next entry */
- kcondvar_t reply_cv; /* condvar for getting reply */
- kmutex_t reply_lock; /* mutex for getting reply */
- uint32_t type; /* mboxsc_xxxmsg() msg type */
- uint32_t cmd; /* mboxsc_xxxmsg() cmd */
- uint64_t transid; /* mboxsc_xxxmsg() trans id */
- uint32_t length; /* mboxsc_xxxmsg() length */
- pcimsg_t reply; /* mboxsc_xxxmsg() reply msg */
- boolean_t reply_recvd; /* msg reply received */
- boolean_t reply_cexit; /* client early exit */
-} schpc_replylist_t;
-
-static kmutex_t schpc_replylist_mutex; /* replylist mutex */
-static uint32_t schpc_replylist_count; /* replylist size */
-static schpc_replylist_t *schpc_replylist_first; /* replylist 1st elem */
-static schpc_replylist_t *schpc_replylist_last; /* replylist last elem */
-static boolean_t slots_registered = B_FALSE; /* slots registered? */
-
-typedef struct {
- char *cname;
- char *caddr;
- char schizo;
- char leaf;
- dev_info_t *dip;
-} find_dev_t;
-
-/*
- * Function prototypes for local functions
- */
-static int schpc_getexpander(dev_info_t *);
-static int schpc_getboard(dev_info_t *);
-static void schpc_event_handler(void *);
-static void schpc_event_filter(pcimsg_t *msg);
-static void schpc_reply_handler(pcimsg_t *pmsg, uint32_t type, uint32_t cmd,
- uint64_t transid, uint32_t length);
-static uint64_t schpc_gettransid(schpc_t *, int);
-static int schpc_slot_get_index(schpc_t *, hpc_slot_t);
-static void schpc_register_all_slots(schpc_t *);
-static void schpc_setslotled(int, int, int, uint32_t);
-static void schpc_init_setslot_message(pci_setslot_t *);
-static void schpc_test(caddr_t, int, void *, uint_t);
-static int schpc_getslotstatus(uint32_t, uint32_t, uint32_t, pci_getslot_t *);
-static int schpc_setslotstatus(uint32_t, uint32_t, uint32_t, pci_setslot_t *);
-static int schpc_match_dip(dev_info_t *, void *);
-static void schpc_buildapid(dev_info_t *, int, char *);
-static int schpc_get_slot_status(uint_t, uint_t, uint_t);
-static void schpc_replylist_unlink(schpc_replylist_t *entry);
-static schpc_replylist_t *schpc_replylist_link(uint32_t cmd, uint64_t transid,
- uint32_t length);
-static void schpc_msg_thread(void);
-static int schpc_putrequest(uint32_t key, uint32_t type, uint32_t cmd,
- uint64_t *transidp, uint32_t length,
- void *datap, clock_t timeout,
- schpc_replylist_t **entryp);
-static int schpc_getreply(uint32_t key, uint32_t *typep, uint32_t *cmdp,
- uint64_t *transidp, uint32_t *lengthp, void *datap,
- clock_t timeout, schpc_replylist_t *listp);
-
-static int schpc_slot_freq(pci_getslot_t *);
-static int schpc_find_dip(dev_info_t *, void *);
-
-static int schpc_save_leaf(int slot);
-static void schpc_restore_leaf(int slot);
-static int schpc_is_leaf_reset_required(int slot);
-static int schpc_is_freq_switchable(int slot);
-static void schpc_save_entry(int slot, int list_entry, int save_entry);
-static void schpc_restore_entry(int slot, int list_entry, int save_entry);
-
-/*
- * Function prototype for Hot Plug Services
- */
-static int schpc_connect(caddr_t, hpc_slot_t, void *, uint_t);
-static int schpc_disconnect(caddr_t, hpc_slot_t, void *, uint_t);
-static int schpc_cpci_control(caddr_t, hpc_slot_t, int, caddr_t);
-static int schpc_pci_control(caddr_t, hpc_slot_t, int, caddr_t);
-
-extern int iosram_rd(uint32_t, uint32_t, uint32_t, caddr_t);
-
-/*
- * cb_ops and dev_ops:
- */
-static struct cb_ops schpc_cb_ops = {
- nodev, /* open */
- nodev, /* close */
- nodev, /* strategy */
- nodev, /* print */
- nodev, /* dump */
- nodev, /* read */
- nodev, /* write */
- nodev, /* ioctl */
- nodev, /* devmap */
- nodev, /* mmap */
- nodev, /* segmap */
- nochpoll, /* poll */
- ddi_prop_op, /* prop_op */
- 0, /* streamtab */
- D_NEW | D_MP | D_HOTPLUG /* Driver compatibility flag */
-};
-
-/*
- * Function prototype for dev_ops
- */
-static int schpc_attach(dev_info_t *, ddi_attach_cmd_t);
-static int schpc_detach(dev_info_t *, ddi_detach_cmd_t);
-static int schpc_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
-
-static struct dev_ops schpc_dev_ops = {
- DEVO_REV, /* devo_rev, */
- 0, /* refcnt */
- schpc_info, /* get_dev_info */
- nulldev, /* identify */
- nulldev, /* probe */
- schpc_attach, /* attach */
- schpc_detach, /* detach */
- nodev, /* reset */
- &schpc_cb_ops, /* driver operations */
- (struct bus_ops *)0, /* no bus operations */
- NULL, /* power */
- ddi_quiesce_not_supported, /* devo_quiesce */
-};
-
-/*
- * loadable module declarations:
- */
-static struct modldrv modldrv = {
- &mod_driverops,
- "PCI Hot Plug Controller Driver (schpc)",
- &schpc_dev_ops,
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- (void *)&modldrv,
- NULL
-};
-
-int
-_init(void)
-{
- int ret;
- int rv;
-
- SCHPC_DEBUG0(D_ATTACH, "_init() installing module");
-
- ret = ddi_soft_state_init(&per_schpc_state, sizeof (schpc_t), 1);
- if (ret != 0) {
- return (ret);
- }
-
- /*
- * Initialize Outgoing Mailbox.
- */
- ret = mboxsc_init(KEY_PCSC, MBOXSC_MBOX_OUT, NULL);
-
- if (ret != 0) {
- ddi_soft_state_fini(&per_schpc_state);
- return (ret);
- }
-
- ret = mboxsc_ctrl(KEY_PCSC, MBOXSC_CMD_PUTMSG_TIMEOUT_RANGE,
- (void *) &schpc_putmsg_timeout_range);
-
- if (ret != 0) {
- ddi_soft_state_fini(&per_schpc_state);
- return (ret);
- }
-
- if (schpc_timeout_putmsg < schpc_putmsg_timeout_range.min_timeout) {
- schpc_timeout_putmsg = schpc_putmsg_timeout_range.min_timeout;
- cmn_err(CE_WARN, " schpc: resetting putmsg timeout to %ld\n",
- schpc_timeout_putmsg);
- }
-
- if (schpc_timeout_putmsg > schpc_putmsg_timeout_range.max_timeout) {
- schpc_timeout_putmsg = schpc_putmsg_timeout_range.max_timeout;
- cmn_err(CE_WARN, " schpc: resetting putmsg timeout to %ld\n",
- schpc_timeout_putmsg);
- }
-
- /*
- * Create the schpc_event_taskq for MBOXSC_MSG_EVENT processing.
- */
- schpc_event_taskq = taskq_create("schpc_event_taskq", 2,
- minclsyspri, 4, 4, TASKQ_PREPOPULATE);
-
- /*
- * Initialize Incoming Mailbox.
- * NOTE: the callback is null because the schpc_msg_thread will
- * handle all incoming MBOXSC_MSG_EVENT and MBOXSC_MSG_REPLY
- * messages.
- */
- ret = mboxsc_init(KEY_SCPC, MBOXSC_MBOX_IN, NULL);
-
- if (ret != 0) {
- cmn_err(CE_WARN, "schpc: can not initialize KEY_SCPC as "
- "MBOXSC_MBOX_IN");
- ddi_soft_state_fini(&per_schpc_state);
- return (ret);
- }
-
- ret = mboxsc_ctrl(KEY_SCPC, MBOXSC_CMD_GETMSG_TIMEOUT_RANGE,
- (void *) &schpc_getmsg_timeout_range);
-
- if (ret != 0) {
- ddi_soft_state_fini(&per_schpc_state);
- return (ret);
- }
-
- if (schpc_timeout_getmsg < schpc_getmsg_timeout_range.min_timeout) {
- schpc_timeout_getmsg = schpc_getmsg_timeout_range.min_timeout;
- cmn_err(CE_WARN, " schpc: resetting getmsg timeout to %ld\n",
- schpc_timeout_getmsg);
- }
-
- if (schpc_timeout_getmsg > schpc_getmsg_timeout_range.max_timeout) {
- schpc_timeout_getmsg = schpc_getmsg_timeout_range.max_timeout;
- cmn_err(CE_WARN, " schpc: resetting putmsg timeout to %ld\n",
- schpc_timeout_putmsg);
- }
-
- if (schpc_timeout_event < schpc_getmsg_timeout_range.min_timeout) {
- schpc_timeout_event = schpc_getmsg_timeout_range.min_timeout;
- cmn_err(CE_WARN, " schpc: resetting event timeout to %ld\n",
- schpc_timeout_event);
- }
-
- if (schpc_timeout_event > schpc_getmsg_timeout_range.max_timeout) {
- schpc_timeout_event = schpc_getmsg_timeout_range.max_timeout;
- cmn_err(CE_WARN, " schpc: resetting event timeout to %ld\n",
- schpc_timeout_event);
- }
-
- ret = mod_install(&modlinkage);
- if (ret != 0) {
- if ((rv = mboxsc_fini(KEY_PCSC)) != 0) {
- cmn_err(CE_WARN, "schpc: _init() - "
- "mboxsc_fini(KEY_PCSC) failed: 0x%x", rv);
- }
- if ((rv = mboxsc_fini(KEY_SCPC)) != 0) {
- cmn_err(CE_WARN, "schpc: _init() - "
- "mboxsc_fini(KEY_SCPC) failed: 0x%x", rv);
- }
- taskq_destroy(schpc_event_taskq);
- ddi_soft_state_fini(&per_schpc_state);
- return (ret);
- }
-
- SCHPC_DEBUG0(D_ATTACH, "_init() module installed");
-
- /*
- * Start the schpc_msg_thread to continuously monitor the
- * MBOXSC_MBOX_IN mailbox for incoming MBOXSC_MSG_EVENTs and
- * MBOXSC_MSG_REPLYs.
- */
- mutex_init(&schpc_replylist_mutex, NULL, MUTEX_DRIVER, NULL);
- (void) thread_create(NULL, 0, schpc_msg_thread,
- NULL, 0, &p0, TS_RUN, minclsyspri);
-
- SCHPC_DEBUG0(D_ATTACH, "_init() started schpc_msg_thread");
-
- return (ret);
-}
-
-int
-_fini(void)
-{
- SCHPC_DEBUG0(D_ATTACH, "_fini()");
-
- return (DDI_FAILURE);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- SCHPC_DEBUG0(D_ATTACH, "_info() called.");
-
- return (mod_info(&modlinkage, modinfop));
-}
-
-static int
-schpc_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
-{
- int instance = ddi_get_instance(devi);
- int rval;
-
- SCHPC_DEBUG1(D_ATTACH, "attach(%x) ATTACH", instance);
-
- switch (cmd) {
- case DDI_ATTACH:
-
- /*
- * Allocate the soft state structure for this instance.
- */
- rval = ddi_soft_state_zalloc(per_schpc_state, instance);
-
- if (rval != DDI_SUCCESS) {
- SCHPC_DEBUG1(D_ATTACH,
- "schpc_attach(%x) Can not allocate "
- "soft state structure", instance);
- return (DDI_FAILURE);
- }
-
- schpc_p = (schpc_t *)ddi_get_soft_state(per_schpc_state,
- instance);
-
- if (schpc_p == NULL) {
- return (DDI_FAILURE);
- }
-
- mutex_init(&schpc_p->schpc_mutex, NULL, MUTEX_DRIVER, NULL);
- cv_init(&schpc_p->schpc_cv, NULL, CV_DRIVER, NULL);
-
- /*
- * Put schpc structure on global linked list.
- */
-
- /*
- * Initialize starting transaction ID.
- */
- schpc_p->schpc_transid = 0;
-
- schpc_p->schpc_number_of_slots = STARCAT_MAX_SLOTS;
-
- SCHPC_DEBUG2(D_ATTACH, "schpc_attach(%x) slot-table property "
- "describes %d slots", instance,
- schpc_p->schpc_number_of_slots);
-
- schpc_p->schpc_hotplugmodel = ddi_getprop(DDI_DEV_T_ANY,
- devi, 0, "hot-plug-model", SCHPC_HOTPLUGTYPE_CPCIHOTPLUG);
-
- SCHPC_DEBUG2(D_ATTACH, "attach(%x) ATTACH - Hot Plug Model=%x",
- instance, schpc_p->schpc_hotplugmodel);
-
- /*
- * What type of hot plug do these slots support? The only
- * types of slots we support is the cPCI Hot Plug Model
- * and Not Hot Pluggable.
- */
- if (schpc_p->schpc_hotplugmodel !=
- SCHPC_HOTPLUGTYPE_CPCIHOTPLUG) {
- schpc_p->schpc_hotplugmodel =
- SCHPC_HOTPLUGTYPE_NOTHOTPLUGGABLE;
- }
-
- schpc_p->schpc_slot = (schpc_slot_t *)kmem_zalloc((size_t)
- (schpc_p->schpc_number_of_slots * sizeof (schpc_slot_t)),
- KM_SLEEP);
-
- schpc_p->schpc_devi = devi;
- schpc_p->schpc_instance = instance;
-
- /*
- * Start thread to search the device tree and register
- * all found pci slots.
- */
- (void) thread_create(NULL, 0, schpc_register_all_slots,
- (void *)schpc_p, 0, &p0, TS_RUN, minclsyspri);
-
- break;
-
- case DDI_PM_RESUME:
- case DDI_RESUME:
- return (DDI_SUCCESS);
- default:
- cmn_err(CE_WARN, "schpc%d: Cmd != DDI_ATTACH/DDI_RESUME",
- instance);
-
- return (DDI_FAILURE);
- }
-
- SCHPC_DEBUG1(D_ATTACH,
- "schpc_attach(%x) Attach - DDI_SUCCESS", instance);
-
- return (DDI_SUCCESS);
-}
-
-/*ARGSUSED*/
-static int
-schpc_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
-{
- int instance = ddi_get_instance(devi);
-
- SCHPC_DEBUG1(D_DETACH, "detach(%x) DETACH", instance);
-
- return (DDI_FAILURE);
-}
-
-/*ARGSUSED*/
-static int
-schpc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
- void **result)
-{
- int error;
-
- switch (infocmd) {
- case DDI_INFO_DEVT2DEVINFO:
- *result = (void *)schpc_devi;
- error = DDI_SUCCESS;
- break;
- case DDI_INFO_DEVT2INSTANCE:
- *result = (void *)0;
- error = DDI_SUCCESS;
- break;
- default:
- error = DDI_FAILURE;
- }
- return (error);
-}
-
-/*
- * schpc_connect()
- *
- * Called by Hot Plug Services to connect a slot to the bus.
- */
-
-/*ARGSUSED*/
-static int
-schpc_connect(caddr_t ops_arg, hpc_slot_t slot_hdl, void *data, uint_t flags)
-{
- int rval;
- int expander, board;
- pci_setslot_t setslot;
- pci_getslot_t getslot;
- int slot;
-
- SCHPC_DEBUG2(D_IOC_CONNECT, "schpc_connect( ops_arg=%p slot_hdl=%p)",
- (void *)ops_arg, (void *)slot_hdl);
-
- mutex_enter(&schpc_p->schpc_mutex);
-
- slot = schpc_slot_get_index(schpc_p, slot_hdl);
-
- if (!(schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_HPCINITED)) {
- SCHPC_DEBUG0(D_IOC_CONNECT, "schpc_connect - HPC Not Inited");
- mutex_exit(&schpc_p->schpc_mutex);
- return (HPC_ERR_FAILED);
- }
-
- /*
- * Check to see if the slot is already connected.
- */
- if (schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_CONNECTED) {
- mutex_exit(&schpc_p->schpc_mutex);
- return (0);
- }
-
- /*
- * Block if another thread is executing a HPC command.
- */
- while (schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_EXECUTING) {
- cv_wait(&schpc_p->schpc_cv, &schpc_p->schpc_mutex);
- }
-
- schpc_p->schpc_slot[slot].state |= SCHPC_SLOTSTATE_EXECUTING;
-
- mutex_exit(&schpc_p->schpc_mutex);
-
- expander = schpc_p->schpc_slot[slot].expander; /* get expander */
- board = schpc_p->schpc_slot[slot].board; /* get board */
-
- SCHPC_DEBUG3(D_IOC_CONNECT,
- "schpc_connect Expander=%x Board=%x Slot=%x",
- expander, board, SCHPC_SLOT_NUM(slot));
-
-
- if (!(schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_OCC_GOOD)) {
- cmn_err(CE_WARN, "schpc: Hot Plug - Unable to complete "
- "connection on Expander %d Board %d Slot %d - "
- "Ap_Id=%s : Occupant is in failed state",
- expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- /* Fault LED should already be illuminated */
-
- goto failed;
- }
-
- if (!(schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_REC_GOOD)) {
- cmn_err(CE_WARN, "schpc: Hot Plug - Unable to complete "
- "connection on Expander %d Board %d Slot %d - "
- "Ap_Id=%s : Receptacle is in failed state",
- expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- /* Fault LED should already be illuminated */
-
- goto failed;
- }
-
- rval = schpc_getslotstatus(expander, board, slot, &getslot);
-
- if (rval) {
- /*
- * System Controller/Mailbox failure.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : Unable to "
- "Communicate with System Controller", expander, board,
- SCHPC_SLOT_NUM(slot), schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
-
- if (getslot.slot_replystatus != PCIMSG_REPLY_GOOD) {
-
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : Unable to "
- "Read Slot Status", expander, board,
- SCHPC_SLOT_NUM(slot), schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
-
- if (getslot.slot_empty) {
- /*
- * If the slot is empty - fail the connection request.
- */
- goto failed;
- }
-
- SCHPC_DEBUG3(D_FREQCHG, "Slot %d - slot_freq_setting %d "
- "slot_freq_cap %d", slot, getslot.slot_freq_setting,
- getslot.slot_freq_cap);
-
- if (!schpc_is_freq_switchable(slot) &&
- (getslot.slot_freq_setting > getslot.slot_freq_cap)) {
-
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed "
- "on Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "Bus Speed Mismatch", expander,
- board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
-
- if (schpc_is_leaf_reset_required(slot) &&
- (schpc_p->schpc_slot[slot].saved_regs == NULL)) {
-
- SCHPC_DEBUG1(D_FREQCHG, "Slot %d - Save Regs before connect",
- slot);
-
- /*
- * A prior disconnect had not saved off the leaf so lets
- * save it now. This is probably due to the domain being
- * booted with a slot with no cassette.
- */
- if (schpc_save_leaf(slot) != 0) {
- cmn_err(CE_WARN, "schpc - Unable to save leaf regs on "
-
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : ",
- expander, board, slot & 3,
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
- }
-
- /*
- * Initialize Set Slot Command.
- */
- schpc_init_setslot_message(&setslot);
-
- setslot.slot_power_on = PCIMSG_ON; /* Turn slot power on */
-
- setslot.slot_led_fault = PCIMSG_LED_FLASH; /* Flash Fault LED */
-
- rval = schpc_setslotstatus(expander, board, slot, &setslot);
-
- if (rval != 0) {
- /*
- * System Controller/Mailbox failure.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : Unable to "
- "Communicate with System Controller", expander, board,
- SCHPC_SLOT_NUM(slot), schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
-
- if (setslot.slot_replystatus == PCIMSG_REPLY_GOOD) {
-
- /*
- * The Request was successfully completed.
- */
-
- SCHPC_DEBUG0(D_IOC_CONNECT, "schpc_connect() - setslotstatus "
- "succeeded");
-
- /*
- * Need to check HEALTHY# signal.
- */
- rval = schpc_getslotstatus(expander, board, slot, &getslot);
-
- if (rval) {
- /*
- * System Controller/Mailbox failure.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed "
- "on Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "Unable to Communicate with System Controller",
- expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
-
- if (getslot.slot_replystatus != PCIMSG_REPLY_GOOD) {
-
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed "
- "on Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "Unable to Read Slot Status", expander, board,
- SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
-
- if ((getslot.slot_powergood != PCIMSG_ON) ||
- (getslot.slot_powerfault == PCIMSG_ON)) {
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed "
- "on Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "Power failure detected", expander, board,
- SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- /*
- * Initialize Set Slot Command.
- */
- schpc_init_setslot_message(&setslot);
-
- /*
- * Turn slot power off.
- */
- setslot.slot_power_off = PCIMSG_ON;
-
- (void) schpc_setslotstatus(expander, board,
- slot, &setslot);
-
- schpc_setslotled(expander, board, slot,
- (SERVICE_LED_ON | FAULT_LED_ON));
-
- goto failed;
- }
-
- if (!getslot.slot_HEALTHY) {
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed "
- "on Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "Adapter did not assert HEALTHY#", expander, board,
- SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- /*
- * Initialize Set Slot Command.
- */
- schpc_init_setslot_message(&setslot);
-
- /*
- * Turn slot power off.
- */
- setslot.slot_power_off = PCIMSG_ON;
-
- (void) schpc_setslotstatus(expander, board, slot,
- &setslot);
-
- schpc_setslotled(expander, board, slot,
- (SERVICE_LED_ON | FAULT_LED_ON));
-
- goto failed;
- }
-
- /*
- * Initialize Set Slot Command.
- */
- schpc_init_setslot_message(&setslot);
-
- /*
- * Start monitoring ENUM# and HEALTHY#
- */
- setslot.slot_enable_HEALTHY = PCIMSG_ON;
- setslot.slot_enable_ENUM = PCIMSG_ON;
-
- rval = schpc_setslotstatus(expander, board, slot, &setslot);
-
- if (rval != 0) {
- /*
- * System Controller/Mailbox failure.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed "
- "on Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "Unable to Communicate with System Controller",
- expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
- if (setslot.slot_replystatus == PCIMSG_REPLY_GOOD) {
-
- int freq;
- find_dev_t find_dev;
-
- /*
- * The Request was successfully completed.
- */
-
- SCHPC_DEBUG0(D_IOC_CONNECT,
- "schpc_connect() - setslotstatus succeeded");
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_CONNECTED;
-
- schpc_setslotled(expander, board, slot,
- (POWER_LED_ON | SERVICE_LED_OFF | FAULT_LED_OFF));
-
- find_dev.cname = schpc_p->schpc_slot[slot].nexus_path;
- find_dev.caddr = (char *)kmem_alloc(MAXPATHLEN,
- KM_SLEEP);
- find_dev.dip = NULL;
-
- /* root node doesn't have to be held */
- ddi_walk_devs(ddi_root_node(), schpc_find_dip,
- &find_dev);
- if (find_dev.dip != NULL) {
- /*
- * Update the clock-frequency property to
- * reflect the new slot-frequency.
- */
- freq = schpc_slot_freq(&getslot);
- SCHPC_DEBUG2(D_FREQCHG,
- "schpc_connect: updating dip=%p freq=%dHZ",
- (void *)find_dev.dip, freq);
- if (ndi_prop_update_int(DDI_DEV_T_NONE,
- find_dev.dip, "clock-frequency", freq)
- != DDI_SUCCESS) {
- cmn_err(CE_WARN,
- "schpc: - failed to update "
- "clock-frequency property for %s",
- find_dev.cname);
- }
- ndi_rele_devi(find_dev.dip);
- } else {
- cmn_err(CE_WARN,
- "schpc: couldn't find dip for %s ",
- find_dev.cname);
- }
- kmem_free(find_dev.caddr, MAXPATHLEN);
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
-
- /*
- * If leaf registers were saved off, then they
- * need to be restored.
- */
- schpc_restore_leaf(slot);
-
- /*
- * Since the device saw a PCI Reset, we need to
- * wait 2^25 clock cycles before the first
- * Configuration access. The worst case is 33MHz,
- * which is a 1 second wait.
- */
- drv_usecwait(1000000);
-
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
- } else {
- /*
- * The System Controller Rejected the
- * connection request.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed "
- "on Expander %d Board %d PCI Slot %d - Ap_Id=%s :"
- "System Controller failed connection request",
- expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
- }
-
- /*
- * The System Controller Rejected the connection request.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Connection Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : System Controller "
- "failed connection request", expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
-failed:
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (HPC_ERR_FAILED);
-}
-
-/*
- * schpc_disconnect()
- *
- * Called by Hot Plug Services to disconnect a slot to the bus.
- */
-
-/*ARGSUSED*/
-static int
-schpc_disconnect(caddr_t ops_arg, hpc_slot_t slot_hdl, void *data,
- uint_t flags)
-{
- int rval;
- int expander, board, slot;
- pci_setslot_t setslot;
-
- SCHPC_DEBUG2(D_IOC_CONNECT,
- "schpc_disconnect( ops_arg=%p slot_hdl=%p)", (void *)ops_arg,
- slot_hdl);
-
- mutex_enter(&schpc_p->schpc_mutex);
-
- slot = schpc_slot_get_index(schpc_p, slot_hdl);
-
- if (!(schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_HPCINITED)) {
- SCHPC_DEBUG0(D_IOC_CONNECT,
- "schpc_disconnect - HPC Not Inited");
- mutex_exit(&schpc_p->schpc_mutex);
- return (HPC_ERR_FAILED);
- }
-
- /*
- * Check to see if we are already disconnected.
- */
- if (!(schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_CONNECTED)) {
- mutex_exit(&schpc_p->schpc_mutex);
- return (0);
- }
-
- /*
- * Block if another thread is executing a HPC command.
- */
- while (schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_EXECUTING) {
- cv_wait(&schpc_p->schpc_cv, &schpc_p->schpc_mutex);
- }
-
- schpc_p->schpc_slot[slot].state |= SCHPC_SLOTSTATE_EXECUTING;
-
- mutex_exit(&schpc_p->schpc_mutex);
-
- expander = schpc_p->schpc_slot[slot].expander; /* get expander */
- board = schpc_p->schpc_slot[slot].board; /* get board */
-
- /*
- * If a leaf reset is going to be asserted due to a mode/freq.
- * change, then the leaf registers of the XMITS bridge will need
- * to be saved off prior to the connect.
- */
- if (schpc_is_leaf_reset_required(slot)) {
- if (schpc_save_leaf(slot) != 0) {
-
- cmn_err(CE_WARN, "schpc - Unable to save leaf regs on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : ",
- expander, board, slot & 3,
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
- }
-
- /*
- * Initialize Set Slot Command.
- */
- schpc_init_setslot_message(&setslot);
-
- setslot.slot_power_off = PCIMSG_ON; /* Turn Power Off */
-
- setslot.slot_led_fault = PCIMSG_LED_FLASH; /* Flash the Fault LED */
-
- setslot.slot_disable_ENUM = PCIMSG_ON; /* Mask the ENUM# signal */
- setslot.slot_disable_HEALTHY = PCIMSG_ON; /* Mask the HEALTHY# sig */
-
- rval = schpc_setslotstatus(expander, board, slot, &setslot);
-
- SCHPC_DEBUG1(D_IOC_CONNECT, "schpc_disconnect() - "
- "setslotstatus returned 0x%x", rval);
-
- if (rval != 0) {
- /*
- * System Controller/Mailbox failure.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Disconnection Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : Unable to "
- "Communicate with System Controller", expander, board,
- SCHPC_SLOT_NUM(slot), schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
- goto failed;
- }
-
- SCHPC_DEBUG1(D_IOC_CONNECT, "schpc_disconnect() - "
- "slot_replystatus returned 0x%x", setslot.slot_replystatus);
-
- if (setslot.slot_replystatus == PCIMSG_REPLY_GOOD) {
-
- /*
- * The Request was successfully completed.
- */
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_CONNECTED;
-
- schpc_setslotled(expander, board, slot,
- (POWER_LED_OFF | SERVICE_LED_ON | FAULT_LED_OFF));
-
- SCHPC_DEBUG0(D_IOC_CONNECT,
- "schpc_disconnect() - setslotstatus succeeded");
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
- }
- /*
- * System Controller/Mailbox failure.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Disconnection Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : System Controller "
- "failed disconnection request", expander, board,
- SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
-
-failed:
- schpc_restore_leaf(slot);
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (HPC_ERR_FAILED);
-}
-
-/*
- * schpc_cpci_control
- *
- * Called by Hot Plug Services to perform a attachment point specific
- * on a Hot Pluggable Compact PCI Slot.
- */
-/*ARGSUSED*/
-static int
-schpc_cpci_control(caddr_t ops_arg, hpc_slot_t slot_hdl, int request,
- caddr_t arg)
-{
- int rval;
- int expander, board, slot;
- pci_setslot_t setslot;
- pci_getslot_t slotstatus;
- hpc_led_info_t *hpc_led_info;
-
- SCHPC_DEBUG3(D_IOC_CONTROL,
- "schpc_cpci_control(op_args=%p slot_hdl=%p request=%x)",
- (void *)ops_arg, (void *)slot_hdl, request);
-
- mutex_enter(&schpc_p->schpc_mutex);
-
- slot = schpc_slot_get_index(schpc_p, slot_hdl);
-
- if (!(schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_HPCINITED)) {
- SCHPC_DEBUG0(D_IOC_CONNECT,
- "schpc_disconnect - HPC Not Inited");
- mutex_exit(&schpc_p->schpc_mutex);
- return (HPC_ERR_FAILED);
- }
-
- /*
- * Block if another thread is executing a HPC command.
- */
- while (schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_EXECUTING) {
- cv_wait(&schpc_p->schpc_cv, &schpc_p->schpc_mutex);
- }
-
- schpc_p->schpc_slot[slot].state |= SCHPC_SLOTSTATE_EXECUTING;
-
- mutex_exit(&schpc_p->schpc_mutex);
-
- expander = schpc_p->schpc_slot[slot].expander; /* get expander */
- board = schpc_p->schpc_slot[slot].board; /* get board */
-
- /*
- * Initialize Set Slot Command.
- */
- schpc_init_setslot_message(&setslot);
-
- /*
- * Initialize LED to last know state.
- */
- switch (schpc_p->schpc_slot[slot].led.led_power) {
- case LED_ON:
- setslot.slot_led_power = PCIMSG_LED_ON;
- break;
- case LED_OFF:
- setslot.slot_led_power = PCIMSG_LED_OFF;
- break;
- case LED_FLASH:
- setslot.slot_led_power = PCIMSG_LED_FLASH;
- break;
- }
-
- switch (schpc_p->schpc_slot[slot].led.led_service) {
- case LED_ON:
- setslot.slot_led_service = PCIMSG_LED_ON;
- break;
- case LED_OFF:
- setslot.slot_led_service = PCIMSG_LED_OFF;
- break;
- case LED_FLASH:
- setslot.slot_led_service = PCIMSG_LED_FLASH;
- break;
- }
-
- switch (schpc_p->schpc_slot[slot].led.led_fault) {
- case LED_ON:
- setslot.slot_led_fault = PCIMSG_LED_ON;
- break;
- case LED_OFF:
- setslot.slot_led_fault = PCIMSG_LED_OFF;
- break;
- case LED_FLASH:
- setslot.slot_led_fault = PCIMSG_LED_FLASH;
- break;
- }
-
- switch (request) {
-
- case HPC_CTRL_GET_LED_STATE:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_GET_LED_STATE");
- hpc_led_info = (hpc_led_info_t *)arg;
-
- switch (hpc_led_info->led) {
- case HPC_FAULT_LED:
- switch (schpc_p->schpc_slot[slot].led.led_fault) {
- case LED_OFF:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_ON:
- hpc_led_info->state = HPC_LED_ON;
- break;
- case LED_FLASH:
- hpc_led_info->state = HPC_LED_BLINK;
- break;
- }
- break;
-
- case HPC_POWER_LED:
- switch (schpc_p->schpc_slot[slot].led.led_power) {
- case LED_OFF:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_ON:
- hpc_led_info->state = HPC_LED_ON;
- break;
- case LED_FLASH:
- hpc_led_info->state = HPC_LED_BLINK;
- break;
- }
- break;
- case HPC_ATTN_LED:
- switch (schpc_p->schpc_slot[slot].led.led_fault) {
- case LED_OFF:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_ON:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_FLASH:
- hpc_led_info->state = HPC_LED_ON;
- break;
- }
- break;
- case HPC_ACTIVE_LED:
- switch (schpc_p->schpc_slot[slot].led.led_service) {
- case LED_OFF:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_ON:
- hpc_led_info->state = HPC_LED_ON;
- break;
- case LED_FLASH:
- hpc_led_info->state = HPC_LED_BLINK;
- break;
- }
- break;
- default:
- SCHPC_DEBUG1(D_IOC_CONTROL, "schpc_cpci_control() - "
- "Invalid LED %x", hpc_led_info->led);
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (HPC_ERR_FAILED);
- }
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_SET_LED_STATE:
- hpc_led_info = (hpc_led_info_t *)arg;
-
- SCHPC_DEBUG1(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_SET_LED_STATE hpc_led_info=%p",
- (void *)hpc_led_info);
-
- switch (hpc_led_info->led) {
- case HPC_FAULT_LED:
- switch (hpc_led_info->state) {
- case HPC_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_OFF;
- setslot.slot_led_fault = PCIMSG_LED_OFF;
- break;
- case HPC_LED_ON:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_ON;
- setslot.slot_led_fault = PCIMSG_LED_ON;
- break;
- case HPC_LED_BLINK:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_FLASH;
- setslot.slot_led_fault = PCIMSG_LED_FLASH;
- break;
- }
- break;
- case HPC_POWER_LED:
- switch (hpc_led_info->state) {
- case HPC_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_power =
- LED_OFF;
- setslot.slot_led_power = PCIMSG_LED_OFF;
- break;
- case HPC_LED_ON:
- schpc_p->schpc_slot[slot].led.led_power =
- LED_ON;
- setslot.slot_led_power = PCIMSG_LED_ON;
- break;
- case HPC_LED_BLINK:
- schpc_p->schpc_slot[slot].led.led_power =
- LED_FLASH;
- setslot.slot_led_power = PCIMSG_LED_FLASH;
- break;
- }
- break;
- case HPC_ATTN_LED:
- switch (hpc_led_info->state) {
- case HPC_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_OFF;
- setslot.slot_led_fault = PCIMSG_LED_OFF;
- break;
- case HPC_LED_ON:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_FLASH;
- setslot.slot_led_fault = PCIMSG_LED_FLASH;
- break;
- case HPC_LED_BLINK:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_FLASH;
- setslot.slot_led_fault = PCIMSG_LED_FLASH;
- break;
- }
- break;
- case HPC_ACTIVE_LED:
- switch (hpc_led_info->state) {
- case HPC_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_service =
- LED_OFF;
- setslot.slot_led_service = PCIMSG_LED_OFF;
- break;
- case HPC_LED_ON:
- schpc_p->schpc_slot[slot].led.led_service =
- LED_ON;
- setslot.slot_led_service = PCIMSG_LED_ON;
- break;
- case HPC_LED_BLINK:
- schpc_p->schpc_slot[slot].led.led_service =
- LED_FLASH;
- setslot.slot_led_service = PCIMSG_LED_FLASH;
- break;
- }
- break;
- default:
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
- }
-
- (void) schpc_setslotstatus(expander, board, slot, &setslot);
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_GET_SLOT_STATE: {
- hpc_slot_state_t *hpc_slot_state;
-
- hpc_slot_state = (hpc_slot_state_t *)arg;
-
- SCHPC_DEBUG1(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_GET_SLOT_STATE hpc_slot_state=%p",
- (void *)hpc_slot_state);
-
- rval = schpc_getslotstatus(expander, board, slot, &slotstatus);
-
- if (!rval) {
-
- if (slotstatus.slot_replystatus != PCIMSG_REPLY_GOOD) {
- return (HPC_ERR_FAILED);
- }
-
- if (slotstatus.slot_empty == PCIMSG_ON) {
- *hpc_slot_state = HPC_SLOT_EMPTY;
- SCHPC_DEBUG0(D_IOC_CONTROL, "Slot Empty");
- } else if (slotstatus.slot_power_on == PCIMSG_ON) {
- *hpc_slot_state = HPC_SLOT_CONNECTED;
- SCHPC_DEBUG0(D_IOC_CONTROL, "Slot Connected");
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_CONNECTED;
- } else {
- *hpc_slot_state = HPC_SLOT_DISCONNECTED;
- SCHPC_DEBUG0(D_IOC_CONTROL,
- "Slot Disconnected");
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_CONNECTED;
- }
- } else {
- SCHPC_DEBUG0(D_IOC_CONTROL, "Mailbox Command failed");
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (HPC_ERR_FAILED);
- }
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
- }
- case HPC_CTRL_GET_BOARD_TYPE: {
- hpc_board_type_t *hpc_board_type;
-
- hpc_board_type = (hpc_board_type_t *)arg;
-
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_GET_BOARD_TYPE");
-
- /*
- * The HPC driver does not know what board type
- * is plugged in.
- */
- *hpc_board_type = HPC_BOARD_CPCI_HS;
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- }
- case HPC_CTRL_DEV_CONFIGURED:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_DEV_CONFIGURED");
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_DEV_UNCONFIGURED:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_DEV_UNCONFIGURED");
-
- if (schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_ENUM) {
- /*
- * When the occupant is unconfigured, power
- * down the slot.
- */
- rval = schpc_disconnect((caddr_t)schpc_p,
- schpc_p->schpc_slot[slot].slot_handle,
- 0, 0);
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_ENUM;
- }
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_ENABLE_AUTOCFG:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_ENABLE_AUTOCFG");
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_AUTOCFG_ENABLE;
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_DISABLE_AUTOCFG:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_DISABLE_AUTOCFG");
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_AUTOCFG_ENABLE;
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_DISABLE_ENUM:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_DISABLE_ENUM");
-
- setslot.slot_disable_ENUM = PCIMSG_ON;
-
- rval = schpc_setslotstatus(expander, board, slot, &setslot);
-
- if (rval)
- rval = HPC_ERR_FAILED;
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (rval);
-
- case HPC_CTRL_ENABLE_ENUM:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_cpci_control() - "
- "HPC_CTRL_ENABLE_ENUM");
-
- setslot.slot_enable_ENUM = PCIMSG_ON;
-
- rval = schpc_setslotstatus(expander, board, slot, &setslot);
-
- if (rval)
- rval = HPC_ERR_FAILED;
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (rval);
-
- default:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_cpci_control() - "
- "****NOT SUPPORTED CONTROL CMD");
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (HPC_ERR_NOTSUPPORTED);
- }
-}
-
-/*
- * schpc_pci_control
- *
- * Called by Hot Plug Services to perform a attachment point specific
- * on a Hot Pluggable Standard PCI Slot.
- */
-/*ARGSUSED*/
-static int
-schpc_pci_control(caddr_t ops_arg, hpc_slot_t slot_hdl, int request,
- caddr_t arg)
-{
- int rval;
- int expander, board, slot;
- pci_setslot_t setslot;
- pci_getslot_t slotstatus;
- hpc_led_info_t *hpc_led_info;
-
- SCHPC_DEBUG3(D_IOC_CONTROL,
- "schpc_pci_control(op_args=%p slot_hdl=%p request=%x)",
- (void *)ops_arg, (void *)slot_hdl, request);
-
- mutex_enter(&schpc_p->schpc_mutex);
-
- slot = schpc_slot_get_index(schpc_p, slot_hdl);
-
- if (!(schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_HPCINITED)) {
- SCHPC_DEBUG0(D_IOC_CONNECT,
- "schpc_disconnect - HPC Not Inited");
- mutex_exit(&schpc_p->schpc_mutex);
- return (HPC_ERR_FAILED);
- }
-
- /*
- * Block if another thread is executing a HPC command.
- */
- while (schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_EXECUTING) {
- cv_wait(&schpc_p->schpc_cv, &schpc_p->schpc_mutex);
- }
-
- schpc_p->schpc_slot[slot].state |= SCHPC_SLOTSTATE_EXECUTING;
-
- mutex_exit(&schpc_p->schpc_mutex);
-
- expander = schpc_p->schpc_slot[slot].expander; /* get expander */
- board = schpc_p->schpc_slot[slot].board; /* get board */
-
- /*
- * Initialize Set Slot Command.
- */
- schpc_init_setslot_message(&setslot);
-
- /*
- * Initialize LED to last know state.
- */
- switch (schpc_p->schpc_slot[slot].led.led_power) {
- case LED_ON:
- setslot.slot_led_power = PCIMSG_LED_ON;
- break;
- case LED_OFF:
- setslot.slot_led_power = PCIMSG_LED_OFF;
- break;
- case LED_FLASH:
- setslot.slot_led_power = PCIMSG_LED_FLASH;
- break;
- }
-
- switch (schpc_p->schpc_slot[slot].led.led_service) {
- case LED_ON:
- setslot.slot_led_service = PCIMSG_LED_ON;
- break;
- case LED_OFF:
- setslot.slot_led_service = PCIMSG_LED_OFF;
- break;
- case LED_FLASH:
- setslot.slot_led_service = PCIMSG_LED_FLASH;
- break;
- }
-
- switch (schpc_p->schpc_slot[slot].led.led_fault) {
- case LED_ON:
- setslot.slot_led_fault = PCIMSG_LED_ON;
- break;
- case LED_OFF:
- setslot.slot_led_fault = PCIMSG_LED_OFF;
- break;
- case LED_FLASH:
- setslot.slot_led_fault = PCIMSG_LED_FLASH;
- break;
- }
-
- switch (request) {
-
-
- case HPC_CTRL_GET_SLOT_STATE: {
- hpc_slot_state_t *hpc_slot_state;
-
- hpc_slot_state = (hpc_slot_state_t *)arg;
-
- SCHPC_DEBUG1(D_IOC_CONTROL, "schpc_pci_control() - "
- "HPC_CTRL_GET_SLOT_STATE hpc_slot_state=%p",
- (void *)hpc_slot_state);
-
- rval = schpc_getslotstatus(expander, board, slot, &slotstatus);
-
- if (!rval) {
-
- if (slotstatus.slot_replystatus != PCIMSG_REPLY_GOOD) {
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (HPC_ERR_FAILED);
- }
-
- if (slotstatus.slot_empty == PCIMSG_ON) {
- *hpc_slot_state = HPC_SLOT_EMPTY;
- SCHPC_DEBUG0(D_IOC_CONTROL, "Slot Empty");
- } else if (slotstatus.slot_power_on == PCIMSG_ON) {
- *hpc_slot_state = HPC_SLOT_CONNECTED;
- SCHPC_DEBUG0(D_IOC_CONTROL, "Slot Connected");
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_CONNECTED;
- } else {
- *hpc_slot_state = HPC_SLOT_DISCONNECTED;
- SCHPC_DEBUG0(D_IOC_CONTROL,
- "Slot Disconnected");
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_CONNECTED;
- }
- } else {
- SCHPC_DEBUG0(D_IOC_CONTROL, "Mailbox Command failed");
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (HPC_ERR_FAILED);
- }
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
- }
- case HPC_CTRL_GET_BOARD_TYPE: {
- hpc_board_type_t *hpc_board_type;
-
- hpc_board_type = (hpc_board_type_t *)arg;
-
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_pci_control() - "
- "HPC_CTRL_GET_BOARD_TYPE");
-
-
- /*
- * The HPC driver does not know what board type
- * is plugged in.
- */
- *hpc_board_type = HPC_BOARD_PCI_HOTPLUG;
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- }
- case HPC_CTRL_DEV_UNCONFIG_START:
- case HPC_CTRL_DEV_CONFIG_START:
- case HPC_CTRL_DEV_CONFIGURED:
- case HPC_CTRL_DEV_UNCONFIGURED:
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_GET_LED_STATE:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_pci_control() - "
- "HPC_CTRL_GET_LED_STATE");
- hpc_led_info = (hpc_led_info_t *)arg;
-
- switch (hpc_led_info->led) {
- case HPC_FAULT_LED:
- switch (schpc_p->schpc_slot[slot].led.led_fault) {
- case LED_OFF:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_ON:
- hpc_led_info->state = HPC_LED_ON;
- break;
- case LED_FLASH:
- hpc_led_info->state = HPC_LED_BLINK;
- break;
- }
- break;
-
- case HPC_POWER_LED:
- switch (schpc_p->schpc_slot[slot].led.led_power) {
- case LED_OFF:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_ON:
- hpc_led_info->state = HPC_LED_ON;
- break;
- case LED_FLASH:
- hpc_led_info->state = HPC_LED_BLINK;
- break;
- }
- break;
- case HPC_ATTN_LED:
- switch (schpc_p->schpc_slot[slot].led.led_fault) {
- case LED_OFF:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_ON:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_FLASH:
- hpc_led_info->state = HPC_LED_ON;
- break;
- }
- break;
- case HPC_ACTIVE_LED:
- switch (schpc_p->schpc_slot[slot].led.led_service) {
- case LED_OFF:
- hpc_led_info->state = HPC_LED_OFF;
- break;
- case LED_ON:
- hpc_led_info->state = HPC_LED_ON;
- break;
- case LED_FLASH:
- hpc_led_info->state = HPC_LED_BLINK;
- break;
- }
- break;
- default:
- SCHPC_DEBUG1(D_IOC_CONTROL, "schpc_pci_control() - "
- "Invalid LED %x", hpc_led_info->led);
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (HPC_ERR_FAILED);
- }
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_SET_LED_STATE:
- hpc_led_info = (hpc_led_info_t *)arg;
-
- SCHPC_DEBUG1(D_IOC_CONTROL, "schpc_pci_control() - "
- "HPC_CTRL_SET_LED_STATE hpc_led_info=%p",
- (void *)hpc_led_info);
-
- switch (hpc_led_info->led) {
- case HPC_FAULT_LED:
- switch (hpc_led_info->state) {
- case HPC_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_OFF;
- setslot.slot_led_fault = PCIMSG_LED_OFF;
- break;
- case HPC_LED_ON:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_ON;
- setslot.slot_led_fault = PCIMSG_LED_ON;
- break;
- case HPC_LED_BLINK:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_FLASH;
- setslot.slot_led_fault = PCIMSG_LED_FLASH;
- break;
- }
- break;
- case HPC_POWER_LED:
- switch (hpc_led_info->state) {
- case HPC_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_power =
- LED_OFF;
- setslot.slot_led_power = PCIMSG_LED_OFF;
- break;
- case HPC_LED_ON:
- schpc_p->schpc_slot[slot].led.led_power =
- LED_ON;
- setslot.slot_led_power = PCIMSG_LED_ON;
- break;
- case HPC_LED_BLINK:
- schpc_p->schpc_slot[slot].led.led_power =
- LED_FLASH;
- setslot.slot_led_power = PCIMSG_LED_FLASH;
- break;
- }
- break;
- case HPC_ATTN_LED:
- switch (hpc_led_info->state) {
- case HPC_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_OFF;
- setslot.slot_led_fault = PCIMSG_LED_OFF;
- break;
- case HPC_LED_ON:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_FLASH;
- setslot.slot_led_fault = PCIMSG_LED_FLASH;
- break;
- case HPC_LED_BLINK:
- schpc_p->schpc_slot[slot].led.led_fault =
- LED_FLASH;
- setslot.slot_led_fault = PCIMSG_LED_FLASH;
- break;
- }
- break;
- case HPC_ACTIVE_LED:
- switch (hpc_led_info->state) {
- case HPC_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_service =
- LED_OFF;
- setslot.slot_led_service = PCIMSG_LED_OFF;
- break;
- case HPC_LED_ON:
- schpc_p->schpc_slot[slot].led.led_service =
- LED_ON;
- setslot.slot_led_service = PCIMSG_LED_ON;
- break;
- case HPC_LED_BLINK:
- schpc_p->schpc_slot[slot].led.led_service =
- LED_FLASH;
- setslot.slot_led_service = PCIMSG_LED_FLASH;
- break;
- }
- break;
- default:
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
- }
-
- (void) schpc_setslotstatus(expander, board, slot, &setslot);
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_ENABLE_AUTOCFG:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_pci_control() - "
- "HPC_CTRL_ENABLE_AUTOCFG");
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_AUTOCFG_ENABLE;
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_DISABLE_AUTOCFG:
- SCHPC_DEBUG0(D_IOC_CONTROL, "schpc_pci_control() - "
- "HPC_CTRL_DISABLE_AUTOCFG");
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_AUTOCFG_ENABLE;
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (0);
-
- case HPC_CTRL_DISABLE_ENUM:
- case HPC_CTRL_ENABLE_ENUM:
- default:
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- return (HPC_ERR_NOTSUPPORTED);
- }
-}
-
-/*
- * schpc_test
- *
- * Tests the slot.
- */
-/*ARGSUSED*/
-static void
-schpc_test(caddr_t ops_arg, int slot, void *data, uint_t flags)
-{
- pci_getslot_t slotstatus;
- pci_setslot_t setslot;
- int expander, board;
- int rval;
- int retry = 1;
-
- SCHPC_DEBUG2(D_IOC_TEST, "schpc_test(op_args=%p slot=%x)",
- (void *)ops_arg, SCHPC_SLOT_NUM(slot));
-
- SCHPC_DEBUG3(D_IOC_TEST,
- " schpc_test() Expander=%d Board=%d Slot=%d",
- schpc_p->schpc_slot[slot].expander,
- schpc_p->schpc_slot[slot].board, SCHPC_SLOT_NUM(slot));
-
- expander = schpc_p->schpc_slot[slot].expander;
- board = schpc_p->schpc_slot[slot].board;
-
-restart_test:
- /*
- * Initial the slot with its occupant and receptacle in good condition.
- */
- schpc_p->schpc_slot[slot].state |= SCHPC_SLOTSTATE_REC_GOOD;
- schpc_p->schpc_slot[slot].state |= SCHPC_SLOTSTATE_OCC_GOOD;
-
-
- rval = schpc_getslotstatus(expander, board, slot, &slotstatus);
-
- if (rval) {
- /*
- * System Controller/Mailbox failure.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Slot Test Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : Unable to "
- "Communicate with System Controller", expander, board,
- SCHPC_SLOT_NUM(slot), schpc_p->schpc_slot[slot].ap_id);
-
- schpc_p->schpc_slot[slot].state &= ~SCHPC_SLOTSTATE_REC_GOOD;
- return;
- }
-
- if (slotstatus.slot_replystatus != PCIMSG_REPLY_GOOD) {
-
- cmn_err(CE_WARN, "schpc - Expander %d Board %d PCI Slot %d "
- "is not hot pluggable\n", expander, board,
- SCHPC_SLOT_NUM(slot));
-
- schpc_p->schpc_slot[slot].state &= ~SCHPC_SLOTSTATE_REC_GOOD;
- return;
- }
-
- switch (slotstatus.slot_condition) {
- case PCIMSG_SLOTCOND_OCC_FAIL:
- cmn_err(CE_WARN, "schpc - Hot Plug Slot Test Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "System Controller/Occupant Failed",
- expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot,
- (POWER_LED_OFF | SERVICE_LED_ON | FAULT_LED_ON));
-
- schpc_p->schpc_slot[slot].state &= ~SCHPC_SLOTSTATE_OCC_GOOD;
- return;
- case PCIMSG_SLOTCOND_REC_FAIL:
- cmn_err(CE_WARN, "schpc - Hot Plug Slot Test Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "System Controller/Receptacle Failed",
- expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot,
- (POWER_LED_OFF | SERVICE_LED_OFF | FAULT_LED_ON));
-
- schpc_p->schpc_slot[slot].state &= ~SCHPC_SLOTSTATE_REC_GOOD;
- return;
- }
-
- if (slotstatus.slot_power_on) {
- schpc_p->schpc_slot[slot].led.led_power = PCIMSG_LED_ON;
-
- if (!slotstatus.slot_HEALTHY) {
- /*
- * cPCI Adapter is not asserting HEALTHY#.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Slot Test Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "PCI adapter not HEALTHY", expander, board,
- SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot,
- (POWER_LED_ON | SERVICE_LED_OFF | FAULT_LED_ON));
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_OCC_GOOD;
-
- return;
- }
-
- if (!slotstatus.slot_powergood) {
- /*
- * PCI Power Input is not good.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Slot Test Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "System Controller PCI Power Input Not Good",
- expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot,
- (POWER_LED_ON | SERVICE_LED_OFF | FAULT_LED_ON));
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_OCC_GOOD;
-
- return;
- }
-
- if (slotstatus.slot_powerfault) {
- /*
- * PCI Power Fault.
- */
- cmn_err(CE_WARN, "schpc - Hot Plug Slot Test Failed on "
- "Expander %d Board %d PCI Slot %d - Ap_Id=%s : "
- "System Controller PCI Power Fault",
- expander, board, SCHPC_SLOT_NUM(slot),
- schpc_p->schpc_slot[slot].ap_id);
-
- schpc_setslotled(expander, board, slot,
- (POWER_LED_ON | SERVICE_LED_OFF | FAULT_LED_ON));
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_OCC_GOOD;
-
- return;
- }
- }
-
- SCHPC_DEBUG0(D_IOC_TEST, "schpc_test() Test Successful - ret 0");
-
- /*
- * Is the slot empty?
- */
- if (slotstatus.slot_empty) {
- SCHPC_DEBUG0(D_IOC_TEST, "schpc_test() Slot Empty");
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_PRESENT;
-
- if (slotstatus.slot_power_on) {
-
- SCHPC_DEBUG0(D_IOC_TEST, "schpc_test() Empty Slot "
- "is powered ON");
-
- /*
- * Tests will be retried once after powering off
- * an empty slot.
- */
- if (retry) {
-
- /*
- * Turn off the slot and restart test.
- */
- SCHPC_DEBUG0(D_IOC_TEST, "schpc_test() "
- "Turning Empty Slot OFF");
-
- schpc_init_setslot_message(&setslot);
- setslot.slot_power_off = PCIMSG_ON;
- (void) schpc_setslotstatus(
- expander, board, slot, &setslot);
-
- retry = 0;
-
- goto restart_test;
- }
- }
- } else {
- SCHPC_DEBUG0(D_IOC_TEST, "schpc_test() Adapter Present");
-
- if (!slotstatus.slot_power_on) {
- if (retry) {
- /*
- * If there is a cassette present and the
- * power is off, try turning the power on and
- * restart the test. This allows access to
- * the FRUID when an empty cassette is
- * installed.
- */
- SCHPC_DEBUG0(D_IOC_TEST,
- "schpc_test() Power On Adapter");
- schpc_init_setslot_message(&setslot);
- setslot.slot_power_on = PCIMSG_ON;
- (void) schpc_setslotstatus(
- expander, board, slot, &setslot);
- retry = 0;
- goto restart_test;
- }
- }
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_PRESENT;
- }
-
- /*
- * Is the slot powered up?
- */
- schpc_init_setslot_message(&setslot);
-
- if (slotstatus.slot_power_on) {
- SCHPC_DEBUG0(D_IOC_TEST, "schpc_test() Slot Power On");
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_CONNECTED;
-
- setslot.slot_led_power = PCIMSG_LED_ON;
- setslot.slot_led_service = PCIMSG_LED_OFF;
- setslot.slot_enable_ENUM = PCIMSG_ON;
- setslot.slot_enable_HEALTHY = PCIMSG_ON;
- } else {
- SCHPC_DEBUG0(D_IOC_TEST, "schpc_test() Slot Power Off");
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_CONNECTED;
-
- setslot.slot_led_power = PCIMSG_LED_OFF;
- setslot.slot_led_service = PCIMSG_LED_ON;
- setslot.slot_disable_ENUM = PCIMSG_ON;
- setslot.slot_disable_HEALTHY = PCIMSG_ON;
- }
-
- setslot.slot_led_fault = PCIMSG_LED_OFF;
-
- (void) schpc_setslotstatus(expander, board, slot, &setslot);
-
- /*
- * Save LED State.
- */
- switch (setslot.slot_led_power) {
- case PCIMSG_LED_ON:
- schpc_p->schpc_slot[slot].led.led_power = LED_ON;
- break;
- case PCIMSG_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_power = LED_OFF;
- break;
- case PCIMSG_LED_FLASH:
- schpc_p->schpc_slot[slot].led.led_power = LED_FLASH;
- break;
- }
- switch (setslot.slot_led_service) {
- case PCIMSG_LED_ON:
- schpc_p->schpc_slot[slot].led.led_service = LED_ON;
- break;
- case PCIMSG_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_service = LED_OFF;
- break;
- case PCIMSG_LED_FLASH:
- schpc_p->schpc_slot[slot].led.led_service = LED_FLASH;
- break;
- }
- switch (setslot.slot_led_fault) {
- case PCIMSG_LED_ON:
- schpc_p->schpc_slot[slot].led.led_fault = LED_ON;
- break;
- case PCIMSG_LED_OFF:
- schpc_p->schpc_slot[slot].led.led_fault = LED_OFF;
- break;
- case PCIMSG_LED_FLASH:
- schpc_p->schpc_slot[slot].led.led_fault = LED_FLASH;
- break;
- }
-}
-
-
-/*
- * schpc_event_handler
- *
- * Placed on the schpc_event_taskq by schpc_event_filter when an
- * unsolicited MBOXSC_MSG_EVENT is received from the SC. It handles
- * things like power insertion/removal, ENUM#, etc.
- */
-static void
-schpc_event_handler(void *arg)
-{
- pci_getslot_t slotstatus;
- uint8_t expander, board, slot;
- int rval;
- pcimsg_t *event = (pcimsg_t *)arg;
-
- /*
- * OK, we got an event message. Since the event message only tells
- * us something has changed and not changed to what, we need to get
- * the current slot status to find how WHAT was change to WHAT.
- */
-
- slot = event->pcimsg_slot;
- expander = event->pcimsg_node; /* get expander */
- board = event->pcimsg_board; /* get board */
-
- SCHPC_DEBUG3(D_EVENT,
- "schpc_event_handler() - exp=%d board=%d slot=%d",
- expander, board, slot);
-
- /* create a slot table index */
- slot = SCHPC_MAKE_SLOT_INDEX2(expander, slot);
-
- SCHPC_DEBUG1(D_EVENT,
- "schpc_event_handler() - expanded slot %d", slot);
-
- if (schpc_p == NULL) {
- cmn_err(CE_WARN, "schpc/Event Handler - Can not find schpc");
- kmem_free(event, sizeof (pcimsg_t));
- return;
- }
-
- mutex_enter(&schpc_p->schpc_mutex);
-
- if (!(schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_HPCINITED)) {
- SCHPC_DEBUG0(D_EVENT, "schpc_event_handler - HPC Not Inited");
- mutex_exit(&schpc_p->schpc_mutex);
- kmem_free(event, sizeof (pcimsg_t));
- return;
- }
- /*
- * Block if another thread is executing a HPC command.
- */
- while (schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_EXECUTING) {
- SCHPC_DEBUG0(D_EVENT, "schpc_event_handler - Slot is busy");
- cv_wait(&schpc_p->schpc_cv, &schpc_p->schpc_mutex);
- }
-
- schpc_p->schpc_slot[slot].state |= SCHPC_SLOTSTATE_EXECUTING;
-
- mutex_exit(&schpc_p->schpc_mutex);
-
- rval = schpc_getslotstatus(expander, board, slot, &slotstatus);
-
- if (rval) {
- cmn_err(CE_WARN, "schpc/Event Handler - Can not get status "
- "for expander=%d board=%d slot=%d\n",
- expander, board, SCHPC_SLOT_NUM(slot));
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
- kmem_free(event, sizeof (pcimsg_t));
- return;
- }
-
- if (slotstatus.slot_replystatus != PCIMSG_REPLY_GOOD) {
- cmn_err(CE_WARN, "schpc/Event Handler - Can not get good "
- "status for expander=%d board=%d slot=%d\n",
- expander, board, SCHPC_SLOT_NUM(slot));
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- kmem_free(event, sizeof (pcimsg_t));
- return;
- }
-
- SCHPC_DEBUG3(D_EVENT, "Event Received - Expander %d Board %d Slot %d",
- expander, board, SCHPC_SLOT_NUM(slot));
-
- if (schpc_p->schpc_slot[slot].slot_ops == NULL) {
- SCHPC_DEBUG3(D_EVENT, "schpc/Event Handler - Received event "
- "for unregistered slot for expander=%d board=%d slot=%d",
- expander, board, SCHPC_SLOT_NUM(slot));
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- kmem_free(event, sizeof (pcimsg_t));
- return;
- }
-
- /* Slot Power Event */
-
- if (event->pcimsg_type.pcimsg_slotevent.slot_power) {
- SCHPC_DEBUG0(D_EVENT, "Event Type: Slot Power Event");
- /*
- * The SC may have changed to slot power status.
- */
- if (slotstatus.slot_power_on) {
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_CONNECTED;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_POWER_ON, 0);
- } else {
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_CONNECTED;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_POWER_OFF, 0);
- }
- }
-
- /* Adapter Insertion/Removal Event */
-
- if (event->pcimsg_type.pcimsg_slotevent.slot_presence) {
- if (slotstatus.slot_empty == PCIMSG_ON) {
-
- /* Adapter Removed */
-
- SCHPC_DEBUG0(D_EVENT, "Event Type: Adapter Removed");
-
- if (schpc_p->schpc_slot[slot].state &
- SCHPC_SLOTSTATE_CONNECTED) {
- /*
- * If the adapter has been removed while
- * there the slot is connected, it could be
- * due to a ENUM handling.
- */
- cmn_err(CE_WARN, "Card removed from "
- "powered on slot at "
- "expander=%d board=%d slot=%d\n",
- expander, board, SCHPC_SLOT_NUM(slot));
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- rval = schpc_disconnect((caddr_t)schpc_p,
- schpc_p->schpc_slot[slot].slot_handle,
- 0, 0);
- mutex_enter(&schpc_p->schpc_mutex);
- while (schpc_p->schpc_slot[slot].state &
- SCHPC_SLOTSTATE_EXECUTING) {
- SCHPC_DEBUG0(D_EVENT,
- "schpc_event_handler - "
- "Slot is busy");
- cv_wait(&schpc_p->schpc_cv,
- &schpc_p->schpc_mutex);
- }
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_EXECUTING;
-
- mutex_exit(&schpc_p->schpc_mutex);
- }
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_OCC_GOOD;
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_PRESENT;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_REMOVAL, 0);
- } else {
-
- /* Adapter Inserted */
-
- SCHPC_DEBUG0(D_EVENT, "Event Type: Adapter Inserted");
-
- if (schpc_p->schpc_slot[slot].state &
- SCHPC_SLOTSTATE_PRESENT) {
- /*
- * If the adapter is already present
- * throw the this event away.
- */
-
- SCHPC_DEBUG0(D_EVENT,
- "Adapter is already present");
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- kmem_free(event, sizeof (pcimsg_t));
- return;
- }
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_PRESENT;
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_CONNECTED;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_INSERTION, 0);
-
- if (schpc_p->schpc_slot[slot].state &
- SCHPC_SLOTSTATE_AUTOCFG_ENABLE) {
- SCHPC_DEBUG0(D_EVENT, "Auto Configuration "
- "(Connect/Configure) Started");
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
-
- rval = schpc_connect((caddr_t)schpc_p,
- schpc_p->schpc_slot[slot].slot_handle,
- 0, 0);
-
- if (rval) {
- cmn_err(CE_WARN, "schpc/Event Handler -"
- " Can not connect");
-
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- kmem_free(event, sizeof (pcimsg_t));
- return;
- }
- mutex_enter(&schpc_p->schpc_mutex);
- while (schpc_p->schpc_slot[slot].state &
- SCHPC_SLOTSTATE_EXECUTING) {
- SCHPC_DEBUG0(D_EVENT,
- "schpc_event_handler - "
- "Slot is busy");
- cv_wait(&schpc_p->schpc_cv,
- &schpc_p->schpc_mutex);
- }
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_EXECUTING;
-
- mutex_exit(&schpc_p->schpc_mutex);
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_CONFIGURE, 0);
- } else {
- schpc_setslotled(expander, board, slot,
- SERVICE_LED_ON);
- }
- }
- }
-
- /* ENUM# signal change event */
-
- if (event->pcimsg_type.pcimsg_slotevent.slot_ENUM) {
- /*
- * ENUM should only be received to the adapter remove
- * procedure.
- */
-
- SCHPC_DEBUG0(D_EVENT, "Event Type: ENUM Asserted");
-
- schpc_setslotled(expander, board, slot, FAULT_LED_FLASH);
-
- schpc_p->schpc_slot[slot].state |= SCHPC_SLOTSTATE_ENUM;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_ENUM, 0);
- }
-
- /* HEALTHY# signal change event */
-
- if (event->pcimsg_type.pcimsg_slotevent.slot_HEALTHY) {
-
- if (!slotstatus.slot_HEALTHY) {
-
- SCHPC_DEBUG0(D_EVENT, "Event Type: !HEALTHY ASSERTED");
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_OCC_GOOD;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_NOT_HEALTHY, 0);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
- } else {
- SCHPC_DEBUG0(D_EVENT, "Event Type: HEALTHY OK");
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_OCC_GOOD;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_HEALTHY_OK, 0);
-
- schpc_setslotled(expander, board, slot,
- FAULT_LED_OFF);
- }
- }
-
- /* Good Power change event */
-
- if (event->pcimsg_type.pcimsg_slotevent.slot_powergood) {
- if (slotstatus.slot_powergood == PCIMSG_ON) {
-
- SCHPC_DEBUG0(D_EVENT,
- "Event Type: Slot Power Good Detected");
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_OCC_GOOD;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_HEALTHY_OK, 0);
-
- schpc_setslotled(expander, board, slot,
- FAULT_LED_OFF);
- } else {
- SCHPC_DEBUG0(D_EVENT, "Event Type: Slot Power Not Good "
- "Detected");
-
- if (schpc_p->schpc_slot[slot].state &
- SCHPC_SLOTSTATE_CONNECTED) {
-
- SCHPC_DEBUG0(D_EVENT, "Slot Power Not Good: "
- "power failed");
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_OCC_GOOD;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_NOT_HEALTHY, 0);
-
- schpc_setslotled(expander, board, slot,
- FAULT_LED_ON);
- }
- }
- }
-
- /* Power Fault change event */
-
- if (event->pcimsg_type.pcimsg_slotevent.slot_powerfault) {
- if (slotstatus.slot_powerfault == PCIMSG_ON) {
-
- SCHPC_DEBUG0(D_EVENT, "Event Type: Slot Power Fault "
- "Detected");
-
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_OCC_GOOD;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_NOT_HEALTHY, 0);
-
- schpc_setslotled(expander, board, slot, FAULT_LED_ON);
- } else {
- SCHPC_DEBUG0(D_EVENT, "Event Type: Slot Power Fault "
- "Cleared");
-
- schpc_p->schpc_slot[slot].state |=
- SCHPC_SLOTSTATE_OCC_GOOD;
-
- (void) hpc_slot_event_notify(
- schpc_p->schpc_slot[slot].slot_handle,
- HPC_EVENT_SLOT_HEALTHY_OK, 0);
-
- schpc_setslotled(expander, board, slot,
- FAULT_LED_OFF);
- }
- }
- mutex_enter(&schpc_p->schpc_mutex);
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_EXECUTING;
- cv_signal(&schpc_p->schpc_cv);
- mutex_exit(&schpc_p->schpc_mutex);
-
- kmem_free(event, sizeof (pcimsg_t));
-}
-
-
-/*
- * schpc_event_filter
- *
- * The schpc_event_filter enqueues MBOXSC_MSG_EVENTs into the
- * schpc_event_taskq for processing by the schpc_event_handler _if_
- * hotpluggable pci slots have been registered; otherwise, the
- * MBOXSC_MSG_EVENTs are discarded in order to keep the incoming mailbox
- * open for future messages.
- */
-static void
-schpc_event_filter(pcimsg_t *pmsg)
-{
- if (slots_registered == B_TRUE) {
-
- pcimsg_t *pevent;
-
- /*
- * If hotpluggable pci slots have been registered then enqueue
- * the event onto the schpc_event_taskq for processing.
- */
-
- SCHPC_DEBUG0(D_EVENT, "schpc_event_filter() - "
- "slots_registered = B_TRUE");
-
- pevent = (pcimsg_t *)kmem_zalloc(sizeof (pcimsg_t), KM_SLEEP);
- bcopy(pmsg, pevent, sizeof (pcimsg_t));
-
- SCHPC_DEBUG0(D_EVENT, "schpc_event_filter() - "
- "event alloc'd");
-
- if (taskq_dispatch(schpc_event_taskq, schpc_event_handler,
- (void *)pevent, TQ_SLEEP) == TASKQID_INVALID) {
- cmn_err(CE_WARN, "schpc: schpc_event_filter - "
- "taskq_dispatch failed to enqueue event");
- kmem_free(pevent, sizeof (pcimsg_t));
- return;
- }
-
- SCHPC_DEBUG0(D_EVENT, "schpc_event_filter() - "
- "event was taskq_dispatch'ed to schpc_event_handler");
- } else {
- /*
- * Oops, schpc received an event _before_ the slots have been
- * registered. In that case there is no choice but to toss
- * the event.
- */
- cmn_err(CE_WARN, "schpc: schpc_event_filter - discarding "
- "premature event");
- }
-}
-
-
-/*
- * schpc_msg_thread
- * A stand-alone thread that monitors the incoming mailbox for
- * MBOXSC_MSG_REPLYs and MBOXSC_MSG_EVENTs, and removes them from
- * the mailbox for processing.
- *
- * MBOXSC_MSG_REPLYs are matched against outstanding REPLYs in the
- * schpc_replylist, and the waiting thread is notified that its REPLY
- * message has arrived; otherwise, if no REPLY match is found, then it is
- * discarded.
- *
- * MBOXSC_MSG_EVENTs are enqueued into the schpc_event_taskq and processed
- * by the schpc_event_handler.
- *
- * The schpc_msg_thread is started in _init().
- */
-void
-schpc_msg_thread(void)
-{
- int err;
- uint32_t type;
- uint32_t cmd;
- uint64_t transid;
- uint32_t length;
- pcimsg_t msg;
-
- SCHPC_DEBUG0(D_THREAD, "schpc_msg_thread() running");
-
- /* CONSTCOND */
- while (1) {
-
- /* setup wildcard arguments */
- type = 0;
- cmd = 0;
- transid = 0;
- length = sizeof (pcimsg_t);
- bzero(&msg, sizeof (pcimsg_t));
-
- err = mboxsc_getmsg(KEY_SCPC, &type, &cmd,
- &transid, &length, (void *)&msg,
- schpc_timeout_getmsg);
-
- if (err) {
- switch (err) {
-
- /*FALLTHROUGH*/
- case ETIMEDOUT:
- case EAGAIN:
- continue;
-
- default:
- /*
- * unfortunately, we can't do very much here
- * because we're wildcarding mboxsc_getmsg
- * so if it encounters an error, we can't
- * identify which transid it belongs to.
- */
- cmn_err(CE_WARN,
- "schpc - mboxsc_getmsg failed, err=0x%x", err);
- delay(drv_usectohz(100000));
- continue;
- }
- }
-
- if (msg.pcimsg_revision != PCIMSG_REVISION) {
- /*
- * This version of the schpc driver only understands
- * version 1.0 of the PCI Hot Plug Message format.
- */
- cmn_err(CE_WARN, " schpc: schpc_msg_thread - "
- "discarding event w/ unknown message version %x",
- msg.pcimsg_revision);
- continue;
- }
-
- switch (type) {
-
- case MBOXSC_MSG_EVENT:
- schpc_event_filter(&msg);
- break;
-
- case MBOXSC_MSG_REPLY:
- schpc_reply_handler(&msg, type, cmd, transid, length);
- break;
-
- default:
- cmn_err(CE_WARN,
- "schpc - mboxsc_getmsg unknown msg"
- " type=0x%x", type);
- break;
- }
- }
- /* this thread never exits */
-}
-
-
-void
-schpc_reply_handler(pcimsg_t *pmsg, uint32_t type, uint32_t cmd,
- uint64_t transid, uint32_t length)
-{
- schpc_replylist_t *entry;
-
- mutex_enter(&schpc_replylist_mutex);
- entry = schpc_replylist_first;
- while (entry != NULL) {
- if (entry->transid == transid) {
- break;
- } else
- entry = entry->next;
- }
- if (entry) {
- SCHPC_DEBUG1(D_GETSLOTSTATUS|D_SETSLOTSTATUS,
- "schpc_reply_handler() - 0x%lx transid reply "
- "received", transid);
-
- mutex_enter(&entry->reply_lock);
- if (entry->reply_cexit == B_FALSE) {
- SCHPC_DEBUG1(D_GETSLOTSTATUS|D_SETSLOTSTATUS,
- "schpc_reply_handler() - 0x%lx transid"
- " cv_signal waiting thread", transid);
-
- /*
- * emulate mboxsc_getmsg by copying the reply
- */
- entry->type = type;
- entry->cmd = cmd;
- entry->transid = transid;
- entry->length = length;
- bcopy((caddr_t)pmsg, &entry->reply, length);
-
- /* reply was received */
- entry->reply_recvd = B_TRUE;
-
- /*
- * wake up thread waiting for reply with transid
- */
- cv_signal(&entry->reply_cv);
- }
- mutex_exit(&entry->reply_lock);
- } else {
- cmn_err(CE_WARN, "schpc - no match for transid 0x%lx",
- transid);
- }
- mutex_exit(&schpc_replylist_mutex);
-}
-
-
-/*
- * schpc_putrequest
- *
- * A wrapper around the synchronous call mboxsc_putmsg().
- */
-int
-schpc_putrequest(uint32_t key, uint32_t type, uint32_t cmd, uint64_t *transidp,
- uint32_t length, void *datap, clock_t timeout,
- schpc_replylist_t **entryp)
-{
- int rval;
-
- /* add the request to replylist to keep track of outstanding requests */
- *entryp = schpc_replylist_link(cmd, *transidp, length);
-
- SCHPC_DEBUG1(D_GETSLOTSTATUS|D_SETSLOTSTATUS, "schpc_putrequest() - "
- "0x%lx transid mboxsc_putmsg called", *transidp);
-
- /* wait synchronously for request to be sent */
- rval = mboxsc_putmsg(key, type, cmd, transidp, length,
- (void *)datap, timeout);
-
- SCHPC_DEBUG2(D_GETSLOTSTATUS|D_SETSLOTSTATUS, "schpc_putrequest() - "
- "0x%lx transid mboxsc_putmsg returned 0x%x", *transidp, rval);
-
- /* if problem is encountered then remove the request from replylist */
- if (rval)
- schpc_replylist_unlink(*entryp);
-
- return (rval);
-}
-
-
-/*
- * schpc_getreply
- *
- * Wait for the schpc_msg_thread to respond that a matching reply has
- * arrived; otherwise, timeout and remove the entry from the schpc_replylist.
- */
-/*ARGSUSED*/
-int
-schpc_getreply(uint32_t key, uint32_t *typep, uint32_t *cmdp,
- uint64_t *transidp, uint32_t *lengthp, void *datap,
- clock_t timeout, schpc_replylist_t *listp)
-{
- int rc = 0;
-
- SCHPC_DEBUG1(D_GETSLOTSTATUS|D_SETSLOTSTATUS,
- "schpc_getreply() - 0x%lx transid waiting for reply",
- *transidp);
-
- /*
- * wait here until schpc_msg_thread because it's always
- * looking for reply messages
- */
- mutex_enter(&listp->reply_lock);
-
- while (listp->reply_recvd == B_FALSE) {
- /*
- * wait for reply or timeout
- */
- rc = cv_timedwait(&listp->reply_cv, &listp->reply_lock,
- ddi_get_lbolt() + drv_usectohz(timeout * 1000));
- switch (rc) {
- case -1: /* most likely a timeout, but check anyway */
-
- /* message was received after all */
- if (listp->reply_recvd == B_TRUE)
- break;
-
- /* no, it's really a timeout */
- listp->reply_cexit = B_TRUE;
- mutex_exit(&listp->reply_lock);
- cmn_err(CE_WARN,
- "schpc - 0x%lx transid reply timed out", *transidp);
- schpc_replylist_unlink(listp);
- return (ETIMEDOUT);
-
- default:
- break;
- }
- }
-
- *typep = listp->type;
- *cmdp = listp->cmd;
- *transidp = listp->transid;
- *lengthp = listp->length;
- bcopy((caddr_t)&listp->reply, datap, *lengthp);
- mutex_exit(&listp->reply_lock);
- SCHPC_DEBUG1(D_GETSLOTSTATUS|D_SETSLOTSTATUS,
- "schpc_getreply() - 0x%lx transid received", *transidp);
- schpc_replylist_unlink(listp);
- return (0);
-}
-
-
-/*
- * schpc_replylist_unlink
- *
- * Deallocate a schpc_replylist_t element.
- */
-void
-schpc_replylist_unlink(schpc_replylist_t *entry)
-{
-#if DEBUG
- schpc_replylist_t *dbg_entry;
-#endif /* DEBUG */
-
- SCHPC_DEBUG1(D_GETSLOTSTATUS|D_SETSLOTSTATUS,
- "schpc_replylist_unlink() - 0x%lx transid deleted from replylist",
- entry->transid);
-
- mutex_enter(&schpc_replylist_mutex);
- if (entry->prev) {
- entry->prev->next = entry->next;
- if (entry->next)
- entry->next->prev = entry->prev;
- } else {
- schpc_replylist_first = entry->next;
- if (entry->next)
- entry->next->prev = NULL;
- }
- if (entry == schpc_replylist_last) {
- schpc_replylist_last = entry->prev;
- }
- kmem_free(entry, sizeof (schpc_replylist_t));
- schpc_replylist_count--;
-
-#if DEBUG
- if (schpc_debug_flags & (D_GETSLOTSTATUS|D_SETSLOTSTATUS)) {
- dbg_entry = schpc_replylist_first;
- cmn_err(CE_CONT, "schpc: schpc_replylist_unlink() - replylist "
- "count = %d\n", schpc_replylist_count);
- while (dbg_entry != NULL) {
- cmn_err(CE_CONT, "schpc: schpc_replylist_unlink() - "
- "0x%lx transid\n", dbg_entry->transid);
- dbg_entry = dbg_entry->next;
- }
- }
-#endif /* DEBUG */
-
- mutex_exit(&schpc_replylist_mutex);
-}
-
-
-/*
- * schpc_replylist_link
- *
- * Allocate and initialize a schpc_replylist_t element.
- */
-schpc_replylist_t *
-schpc_replylist_link(uint32_t cmd, uint64_t transid, uint32_t length)
-{
- schpc_replylist_t *entry;
-#if DEBUG
- schpc_replylist_t *dbg_entry;
-#endif /* DEBUG */
-
- SCHPC_DEBUG1(D_GETSLOTSTATUS|D_SETSLOTSTATUS,
- "schpc_replylist_link() - 0x%lx transid inserting into replylist",
- transid);
-
- entry = kmem_zalloc(sizeof (schpc_replylist_t), KM_SLEEP);
- mutex_init(&entry->reply_lock, NULL, MUTEX_DRIVER, NULL);
- cv_init(&entry->reply_cv, NULL, CV_DRIVER, NULL);
- entry->type = MBOXSC_MSG_REPLY;
- entry->cmd = cmd;
- entry->transid = transid;
- entry->length = length;
- entry->reply_recvd = B_FALSE;
- entry->reply_cexit = B_FALSE;
-
- mutex_enter(&schpc_replylist_mutex);
- if (schpc_replylist_last) {
- entry->prev = schpc_replylist_last;
- schpc_replylist_last->next = entry;
- schpc_replylist_last = entry;
- } else {
- schpc_replylist_last = schpc_replylist_first = entry;
- }
-
- schpc_replylist_count++;
-
-#if DEBUG
- if (schpc_debug_flags & (D_GETSLOTSTATUS|D_SETSLOTSTATUS)) {
- dbg_entry = schpc_replylist_first;
- cmn_err(CE_CONT, "schpc: schpc_replylist_link() - replylist "
- "count = %d\n", schpc_replylist_count);
- while (dbg_entry != NULL) {
- cmn_err(CE_CONT, "schpc: schpc_replylist_link() - "
- "0x%lx transid\n", dbg_entry->transid);
- dbg_entry = dbg_entry->next;
- }
- }
-#endif /* DEBUG */
-
- mutex_exit(&schpc_replylist_mutex);
-
- return (entry);
-}
-
-
-/*
- * schpc_getslotstatus
- *
- * Issues a Get Slot Status command to the System Controller
- * for a specific slot.
- */
-static int
-schpc_getslotstatus(uint32_t expander, uint32_t board, uint32_t slot,
- pci_getslot_t *slotstatus)
-{
- pcimsg_t request;
- pcimsg_t reply;
- int rval;
- uint32_t type, cmd, length;
- uint64_t transid;
- schpc_replylist_t *entry;
-
- SCHPC_DEBUG4(D_GETSLOTSTATUS,
- "schpc_getslotstatus(expander=%d board=%d "
- "slot=%d slotstatus=0x%p", expander, board,
- SCHPC_SLOT_NUM(slot), (void *)slotstatus);
-
- if (schpc_p == NULL) {
- return (1);
- }
-
- bzero(&request, sizeof (pcimsg_t));
-
- request.pcimsg_node = expander;
- request.pcimsg_board = board;
- request.pcimsg_slot = SCHPC_SLOT_NUM(slot);
- request.pcimsg_revision = PCIMSG_REVISION;
- request.pcimsg_command = PCIMSG_GETSLOTSTATUS;
-
- type = MBOXSC_MSG_REQUEST;
- cmd = PCIMSG_GETSLOTSTATUS;
- transid = schpc_gettransid(schpc_p, slot);
- length = sizeof (pcimsg_t);
-
- SCHPC_DEBUG1(D_GETSLOTSTATUS, "schpc_getslotstatus() - "
- "0x%lx transid schpc_putrequest called", transid);
-
- rval = schpc_putrequest(KEY_PCSC, type, cmd, &transid, length,
- (void *)&request, schpc_timeout_putmsg, &entry);
-
- SCHPC_DEBUG2(D_GETSLOTSTATUS, "schpc_getslotstatus() - "
- "0x%lx transid schpc_putrequest returned 0x%x", transid, rval);
-
- if (rval) {
- return (rval);
- }
-
- bzero(&reply, sizeof (pcimsg_t));
- type = MBOXSC_MSG_REPLY;
-
- SCHPC_DEBUG1(D_GETSLOTSTATUS, "schpc_getslotstatus() - "
- "0x%lx transid schpc_getreply called", transid);
-
- rval = schpc_getreply(KEY_SCPC, &type, &cmd, &transid, &length,
- (void *)&reply, schpc_timeout_getmsg, entry);
-
- SCHPC_DEBUG2(D_GETSLOTSTATUS, "schpc_getslotstatus() - "
- "0x%lx transid schpc_getreply returned 0x%x", transid, rval);
-
- if (rval == 0) {
- *slotstatus = reply.pcimsg_type.pcimsg_getslot;
-
- SCHPC_DEBUG0(D_GETSLOTSTATUS, "schpc_getslotstatus()");
- SCHPC_DEBUG1(D_GETSLOTSTATUS, " slot_power_on %x",
- reply.pcimsg_type.pcimsg_getslot.slot_power_on);
- SCHPC_DEBUG1(D_GETSLOTSTATUS, " slot_powergood %x",
- reply.pcimsg_type.pcimsg_getslot.slot_powergood);
- SCHPC_DEBUG1(D_GETSLOTSTATUS, " slot_powerfault %x",
- reply.pcimsg_type.pcimsg_getslot.slot_powerfault);
- SCHPC_DEBUG1(D_GETSLOTSTATUS, " slot_empty %x",
- reply.pcimsg_type.pcimsg_getslot.slot_empty);
- SCHPC_DEBUG1(D_GETSLOTSTATUS, " slot_freq_cap %x",
- reply.pcimsg_type.pcimsg_getslot.slot_freq_cap);
- SCHPC_DEBUG1(D_GETSLOTSTATUS, " slot_freq_setting %x",
- reply.pcimsg_type.pcimsg_getslot.slot_freq_setting);
- SCHPC_DEBUG1(D_GETSLOTSTATUS, " slot_condition %x",
- reply.pcimsg_type.pcimsg_getslot.slot_condition);
- SCHPC_DEBUG1(D_GETSLOTSTATUS, " slot_HEALTHY %x",
- reply.pcimsg_type.pcimsg_getslot.slot_HEALTHY);
- SCHPC_DEBUG1(D_GETSLOTSTATUS, " slot_ENUM %x",
- reply.pcimsg_type.pcimsg_getslot.slot_ENUM);
- }
-
- return (rval);
-}
-
-
-/*
- * schpc_setslotstatus
- *
- * Issues a Set Slot Status command to the System Controller
- * for a specific slot.
- */
-static int
-schpc_setslotstatus(uint32_t expander, uint32_t board, uint32_t slot,
- pci_setslot_t *slotstatus)
-{
- pcimsg_t request;
- pcimsg_t reply;
- int rval;
- uint32_t type, cmd, length;
- uint64_t transid;
- schpc_replylist_t *entry;
-
- SCHPC_DEBUG4(D_SETSLOTSTATUS,
- "schpc_setslotstatus(expander=%d board=%d "
- "slot=%d slotstatus=0x%p", expander, board,
- SCHPC_SLOT_NUM(slot), (void *)slotstatus);
-
- bzero(&request, sizeof (pcimsg_t));
-
- if (schpc_p == NULL) {
- return (1);
- }
-
- request.pcimsg_node = expander;
- request.pcimsg_board = board;
- request.pcimsg_slot = SCHPC_SLOT_NUM(slot);
- request.pcimsg_revision = PCIMSG_REVISION;
- request.pcimsg_command = PCIMSG_SETSLOTSTATUS;
-
- request.pcimsg_type.pcimsg_setslot = *slotstatus;
-
- SCHPC_DEBUG0(D_IOC_LED, "schpc_setslotstatus() - LED state change");
- SCHPC_DEBUG3(D_IOC_LED, "LED Power %d Service %d Fault %d",
- slotstatus->slot_led_power,
- slotstatus->slot_led_service,
- slotstatus->slot_led_fault);
-
- type = MBOXSC_MSG_REQUEST;
- cmd = PCIMSG_SETSLOTSTATUS;
- transid = schpc_gettransid(schpc_p, slot);
- length = sizeof (pcimsg_t);
-
- SCHPC_DEBUG1(D_SETSLOTSTATUS, "schpc_setslotstatus() - "
- "0x%lx transid schpc_putrequest called", transid);
-
- rval = schpc_putrequest(KEY_PCSC, type, cmd, &transid, length,
- (void *)&request, schpc_timeout_putmsg, &entry);
-
- SCHPC_DEBUG2(D_SETSLOTSTATUS, "schpc_setslotstatus() - "
- "0x%lx transid schpc_putrequest returned 0x%x", transid, rval);
-
- if (rval) {
- return (rval);
- }
-
- bzero(&reply, sizeof (pcimsg_t));
- type = MBOXSC_MSG_REPLY;
-
- SCHPC_DEBUG1(D_SETSLOTSTATUS, "schpc_setslotstatus() - "
- "0x%lx transid schpc_getreply called", transid);
-
- rval = schpc_getreply(KEY_SCPC, &type, &cmd, &transid, &length,
- (void *)&reply, schpc_timeout_getmsg, entry);
-
- SCHPC_DEBUG2(D_SETSLOTSTATUS, "schpc_setslotstatus() - "
- "0x%lx transid schpc_getreply returned 0x%x", transid, rval);
-
- if (rval == 0) {
- slotstatus->slot_replystatus =
- reply.pcimsg_type.pcimsg_setslot.slot_replystatus;
- }
-
- return (rval);
-}
-
-/*
- * schpc_setslotled
- *
- * Changes the attention indicators for a given slot.
- */
-static void
-schpc_setslotled(int expander, int board, int slot, uint32_t led_state)
-{
-
- pci_setslot_t setslot;
-
- if (schpc_p == NULL) {
- return;
- }
-
- schpc_init_setslot_message(&setslot);
-
- if (led_state & POWER_LED_ON) {
- schpc_p->schpc_slot[slot].led.led_power = PCIMSG_LED_ON;
- }
- if (led_state & POWER_LED_OFF) {
- schpc_p->schpc_slot[slot].led.led_power = PCIMSG_LED_OFF;
- }
- if (led_state & POWER_LED_FLASH) {
- schpc_p->schpc_slot[slot].led.led_power = PCIMSG_LED_FLASH;
- }
- if (led_state & SERVICE_LED_ON) {
- schpc_p->schpc_slot[slot].led.led_service = PCIMSG_LED_ON;
- }
- if (led_state & SERVICE_LED_OFF) {
- schpc_p->schpc_slot[slot].led.led_service = PCIMSG_LED_OFF;
- }
- if (led_state & SERVICE_LED_FLASH) {
- schpc_p->schpc_slot[slot].led.led_service = PCIMSG_LED_FLASH;
- }
- if (led_state & FAULT_LED_ON) {
- schpc_p->schpc_slot[slot].led.led_fault = PCIMSG_LED_ON;
- }
- if (led_state & FAULT_LED_OFF) {
- schpc_p->schpc_slot[slot].led.led_fault = PCIMSG_LED_OFF;
- }
- if (led_state & FAULT_LED_FLASH) {
- schpc_p->schpc_slot[slot].led.led_fault = PCIMSG_LED_FLASH;
- }
-
- switch (schpc_p->schpc_slot[slot].led.led_power) {
- case PCIMSG_LED_ON:
- setslot.slot_led_power = PCIMSG_LED_ON;
- break;
- case PCIMSG_LED_OFF:
- setslot.slot_led_power = PCIMSG_LED_OFF;
- break;
- case PCIMSG_LED_FLASH:
- setslot.slot_led_power = PCIMSG_LED_FLASH;
- break;
- }
- switch (schpc_p->schpc_slot[slot].led.led_service) {
- case PCIMSG_LED_ON:
- setslot.slot_led_service = PCIMSG_LED_ON;
- break;
- case PCIMSG_LED_OFF:
- setslot.slot_led_service = PCIMSG_LED_OFF;
- break;
- case PCIMSG_LED_FLASH:
- setslot.slot_led_service = PCIMSG_LED_FLASH;
- break;
- }
- switch (schpc_p->schpc_slot[slot].led.led_fault) {
- case PCIMSG_LED_ON:
- setslot.slot_led_fault = PCIMSG_LED_ON;
- break;
- case PCIMSG_LED_OFF:
- setslot.slot_led_fault = PCIMSG_LED_OFF;
- break;
- case PCIMSG_LED_FLASH:
- setslot.slot_led_fault = PCIMSG_LED_FLASH;
- break;
- }
-
- (void) schpc_setslotstatus(expander, board, slot, &setslot);
-}
-
-/*
- * schpc_init_setslot_message
- *
- * Initialize Set Slot Message before using it.
- */
-static void
-schpc_init_setslot_message(pci_setslot_t *setslot)
-{
- /*
- * Initialize Set Slot Command.
- */
- setslot->slot_power_on = PCIMSG_OFF;
- setslot->slot_power_off = PCIMSG_OFF;
- setslot->slot_led_power = PCIMSG_LED_OFF;
- setslot->slot_led_service = PCIMSG_LED_OFF;
- setslot->slot_led_fault = PCIMSG_LED_OFF;
- setslot->slot_disable_ENUM = PCIMSG_OFF;
- setslot->slot_enable_ENUM = PCIMSG_OFF;
- setslot->slot_disable_HEALTHY = PCIMSG_OFF;
- setslot->slot_enable_HEALTHY = PCIMSG_OFF;
-}
-
-/*
- * schpc_gettransid
- *
- * Builds a unique transaction ID.
- */
-static uint64_t
-schpc_gettransid(schpc_t *schpc_p, int slot)
-{
- uint64_t trans_id;
-
- mutex_enter(&schpc_p->schpc_mutex);
-
- if (++schpc_p->schpc_transid == 0)
- schpc_p->schpc_transid = 1;
-
- trans_id = (schpc_p->schpc_slot[slot].expander<<24) |
- (schpc_p->schpc_slot[slot].board << 16) | schpc_p->schpc_transid;
-
- mutex_exit(&schpc_p->schpc_mutex);
-
- SCHPC_DEBUG1(D_TRANSID, "schpc_gettransid() - 0x%lx transid returning",
- trans_id);
-
- return (trans_id);
-}
-
-/*
- * schpc_slot_get_index
- *
- * get slot table index from the slot handle
- */
-static int
-schpc_slot_get_index(schpc_t *schpc_p, hpc_slot_t slot)
-{
- int i;
- int rval = -1;
-
- ASSERT(MUTEX_HELD(&schpc_p->schpc_mutex));
-
- for (i = 0; i < schpc_p->schpc_number_of_slots; i++) {
- if (schpc_p->schpc_slot[i].slot_handle == slot)
- return (i);
- }
-
- return (rval);
-}
-
-/*
- * schpc_register_all_slots
- *
- * Search device tree for pci nodes and register attachment points
- * for all hot pluggable slots.
- */
-/*ARGSUSED*/
-static void
-schpc_register_all_slots(schpc_t *schpc_p)
-{
- int slot = 0;
- char caddr[64];
- dev_info_t *pci_dip = NULL;
- find_dev_t find_dev;
- int leaf, schizo, expander, portid, offset;
-
- SCHPC_DEBUG1(D_ATTACH,
- "schpc_register_all_slots(schpc_p=%p)", (void *)schpc_p);
-
- /*
- * Allow the event_handler to start processing unsolicited
- * events now that slots are about to be registered.
- */
- slots_registered = B_TRUE;
-
- for (slot = 0; slot < STARCAT_MAX_SLOTS; slot++) {
-
- leaf = SCHPC_SLOT_LEAF(slot);
- schizo = SCHPC_SLOT_SCHIZO(slot);
- expander = SCHPC_SLOT_EXPANDER(slot);
-
- if (schizo == 0)
- portid = 0x1c;
- else
- portid = 0x1d;
-
- if (leaf == 0)
- offset = 0x600000;
- else
- offset = 0x700000;
-
- portid = (expander << 5) | portid;
-
- (void) sprintf(caddr, "%x,%x", portid, offset);
-
- SCHPC_DEBUG3(D_ATTACH,
- "schpc_register_all_slots: searching for pci@%s"
- " schizo=%d, leaf=%d", caddr, schizo, leaf);
-
- find_dev.cname = "pci";
- find_dev.caddr = caddr;
- find_dev.schizo = schizo;
- find_dev.leaf = leaf;
- find_dev.dip = NULL;
-
- /* root node doesn't have to be held */
- ddi_walk_devs(ddi_root_node(), schpc_match_dip,
- &find_dev);
-
- pci_dip = find_dev.dip;
-
- if (pci_dip == NULL) {
-
- SCHPC_DEBUG1(D_ATTACH,
- "schpc_register_all_slots: pci@%s NOT FOUND",
- caddr);
-
- continue;
- }
-
- SCHPC_DEBUG2(D_ATTACH,
- "schpc_register_all_slots: pci@%s FOUND dip=0x%p",
- caddr, (void *)pci_dip);
-
- (void) schpc_add_pci(pci_dip);
-
- /*
- * Release hold acquired in schpc_match_dip()
- */
- ndi_rele_devi(pci_dip);
- }
-
- SCHPC_DEBUG0(D_ATTACH, "schpc_register_all_slots: Thread Exit");
-
- thread_exit();
-}
-
-/*
- * schpc_add_pci
- *
- * Routine to add attachments points associated with a pci node.
- * Can be call externally by DR when configuring a PCI I/O Board.
- */
-int
-schpc_add_pci(dev_info_t *bdip)
-{
- int portid;
- int expander, board, schizo, leaf, slot, status;
- char ap_id[MAXNAMELEN];
- char caddr[64];
- char *naddr;
- hpc_slot_info_t slot_info;
- hpc_slot_ops_t *slot_ops;
- dev_info_t *sdip = bdip;
-
- SCHPC_DEBUG1(D_ATTACH, "schpc_add_pci(dip=0x%p)", (void *)sdip);
-
- if (schpc_p == NULL) {
- /*
- * The schpc driver has not been attached yet.
- */
- return (DDI_SUCCESS);
- }
-
- if ((portid = ddi_getprop(DDI_DEV_T_ANY, sdip, 0, "portid", -1)) < 0) {
- cmn_err(CE_WARN, "schpc_add_pci(dip=0x%p) - no portid\n",
- (void *)sdip);
- return (DDI_FAILURE);
- }
-
- expander = schpc_getexpander(sdip);
- board = schpc_getboard(sdip);
-
- switch (portid & 0x1f) {
-
- case 0x1c:
- schizo = 0;
- break;
- case 0x1d:
- schizo = 1;
- break;
- default:
- cmn_err(CE_WARN, "schpc_add_pci(dip=0x%p) - "
- "Invalid pci portid 0x%x\n", (void *)sdip, portid);
- return (DDI_FAILURE);
- }
-
- naddr = ddi_get_name_addr(sdip);
- if (naddr == NULL) {
- SCHPC_DEBUG1(D_ATTACH, "schpc_add_pci: ddi_get_name_addr"
- "(0x%p) returns null", (void *)sdip);
- return (DDI_FAILURE);
- }
-
- (void) sprintf(caddr, "%x,600000", portid);
-
- if (strcmp(caddr, naddr) == 0) {
- leaf = 0;
- } else {
- (void) sprintf(caddr, "%x,700000", portid);
- if (strcmp(caddr, naddr) == 0) {
- char *name;
-
- leaf = 1;
- name = ddi_binding_name(sdip);
- if ((strcmp(name, "pci108e,8002") == 0) &&
- (schizo == 0)) {
- int circ;
- dev_info_t *cdip;
- /*
- * XMITS 0 Leaf B will have its hot
- * pluggable slot off a PCI-PCI bridge,
- * which is the only child.
- */
- ndi_devi_enter(sdip, &circ);
- cdip = ddi_get_child(sdip);
- if (cdip == NULL) {
- cmn_err(CE_WARN,
- "schpc_add_pci(dip=0x%p) - "
- "Invalid pci name addr %s\n",
- (void *)sdip, naddr);
- ndi_devi_exit(sdip, circ);
- return (DDI_FAILURE);
- }
- ndi_devi_exit(sdip, circ);
- sdip = cdip;
- }
- } else {
- cmn_err(CE_WARN, "schpc_add_pci(dip=0x%p) - "
- "Invalid pci name addr %s\n", (void *)sdip, naddr);
- return (DDI_FAILURE);
- }
- }
-
- /* create a slot table index */
- slot = SCHPC_MAKE_SLOT_INDEX3(expander, schizo, leaf);
-
- if (schpc_p->schpc_slot[slot].devi) {
- cmn_err(CE_WARN, "schpc_add_pci(dip=0x%p) - "
- "pci node already registered\n", (void *)sdip);
- return (DDI_FAILURE);
- }
-
- /*
- * There is no need to hold the dip while saving it in
- * the devi field below. The dip is never dereferenced.
- * (If that changes, this code should be modified).
- * We want to avoid holding the dip here because it
- * prevents DR.
- *
- * NOTE: Even though the slot on XMITS0 Leaf-B
- * is connected to a pci_pci bridge, we will be saving
- * the busdip in this datastructure. This will make
- * it easier to identify the dip being removed in
- * schpc_remove_pci().
- */
- schpc_p->schpc_slot[slot].devi = bdip;
-
- schpc_p->schpc_slot[slot].expander = expander;
- schpc_p->schpc_slot[slot].board = board;
- schpc_p->schpc_slot[slot].schizo = schizo;
- schpc_p->schpc_slot[slot].leaf = leaf;
-
- /*
- * Starcat PCI slots are always PCI device 1.
- */
- schpc_p->schpc_slot[slot].pci_id = 1;
-
- schpc_buildapid(sdip, slot, (char *)&ap_id);
-
- (void) strcpy(schpc_p->schpc_slot[slot].ap_id, (char *)&ap_id);
-
- /* safe to call ddi_pathname(): bdip is held */
- (void) ddi_pathname(sdip, schpc_p->schpc_slot[slot].nexus_path);
-
- status = schpc_get_slot_status(expander, board, SCHPC_SLOT_NUM(slot));
- switch (status) {
- case RSV_UNKNOWN:
- case RSV_PRESENT:
- case RSV_MISS:
- case RSV_PASS:
- case RSV_EMPTY_CASSETTE:
-
- /*
- * Test the condition of the slot.
- */
- schpc_test((caddr_t)schpc_p, slot, 0, 0);
- break;
- case RSV_BLACK:
- schpc_p->schpc_slot[slot].state = 0;
- cmn_err(CE_WARN, "schpc: PCI card blacklisted: "
- "expander=%d board=%d slot=%d\n", expander,
- board, SCHPC_SLOT_NUM(slot));
- break;
- default:
- schpc_p->schpc_slot[slot].state = 0;
- cmn_err(CE_WARN, "schpc: PCI card failed by POST: "
- "expander=%d board=%d slot=%d failure=0x%x\n",
- expander, board, SCHPC_SLOT_NUM(slot), status);
- break;
- }
-
- if (schpc_p->schpc_slot[slot].state & SCHPC_SLOTSTATE_REC_GOOD) {
-
- /* allocate slot ops */
-
- slot_ops = hpc_alloc_slot_ops(KM_SLEEP);
- schpc_p->schpc_slot[slot].slot_ops = slot_ops;
-
- /*
- * Default to Autoconfiguration disabled.
- */
- schpc_p->schpc_slot[slot].state &=
- ~SCHPC_SLOTSTATE_AUTOCFG_ENABLE;
-
- /*
- * Fill in the slot information structure that
- * describes the slot.
- */
- slot_info.version = HPC_SLOT_OPS_VERSION;
-
- if (schpc_p->schpc_hotplugmodel ==
- SCHPC_HOTPLUGTYPE_CPCIHOTPLUG)
- slot_info.slot_type = HPC_SLOT_TYPE_PCI;
- else
- slot_info.slot_type = HPC_SLOT_TYPE_CPCI;
-
- slot_info.slot.pci.device_number =
- schpc_p->schpc_slot[slot].pci_id;
-
- slot_info.slot.pci.slot_capabilities = HPC_SLOT_64BITS;
-
- if (schpc_use_legacy_apid)
- slot_info.slot_flags = HPC_SLOT_NO_AUTO_ENABLE;
- else
- slot_info.slot_flags = HPC_SLOT_NO_AUTO_ENABLE |
- HPC_SLOT_CREATE_DEVLINK;
-
- (void) strcpy(slot_info.slot.pci.slot_logical_name,
- schpc_p->schpc_slot[slot].ap_id);
-
- /*
- * Fill in the slot ops structure that tells
- * the Hot Plug Services what function we
- * support.
- */
- slot_ops->hpc_version = HPC_SLOT_OPS_VERSION;
- if (schpc_p->schpc_hotplugmodel ==
- SCHPC_HOTPLUGTYPE_CPCIHOTPLUG) {
- slot_ops->hpc_op_connect = schpc_connect;
- slot_ops->hpc_op_disconnect = schpc_disconnect;
- slot_ops->hpc_op_insert = NULL;
- slot_ops->hpc_op_remove = NULL;
- slot_ops->hpc_op_control = schpc_pci_control;
- } else {
- slot_ops->hpc_op_connect = NULL;
- slot_ops->hpc_op_disconnect = NULL;
- slot_ops->hpc_op_insert = NULL;
- slot_ops->hpc_op_remove = NULL;
- slot_ops->hpc_op_control = schpc_cpci_control;
- }
-
- SCHPC_DEBUG5(D_ATTACH, "schpc_add_pci: Registering HPC "
- "- nexus =%s schpc_p=%p slot=%d pci number=%d ap_id=%s",
- schpc_p->schpc_slot[slot].nexus_path,
- (void *)schpc_p, SCHPC_SLOT_NUM(slot),
- slot_info.slot.pci.device_number,
- slot_info.slot.pci.slot_logical_name);
-
- if (hpc_slot_register(schpc_p->schpc_devi,
- schpc_p->schpc_slot[slot].nexus_path, &slot_info,
- &schpc_p->schpc_slot[slot].slot_handle,
- slot_ops, (caddr_t)schpc_p, 0) != 0) {
-
- /*
- * If the slot can not be registered,
- * then the slot_ops need to be freed.
- */
- cmn_err(CE_WARN, "schpc%d Unable to Register "
- "Slot %s", schpc_p->schpc_instance,
- slot_info.slot.pci.slot_logical_name);
-
- hpc_free_slot_ops(schpc_p->schpc_slot[slot].slot_ops);
-
- schpc_p->schpc_slot[slot].slot_ops = NULL;
-
- return (DDI_FAILURE);
- }
-
- /*
- * We are ready to take commands from the HPC Services.
- */
- schpc_p->schpc_slot[slot].state |= SCHPC_SLOTSTATE_HPCINITED;
- }
-
- return (DDI_SUCCESS);
-}
-
-/*
- * schpc_remove_pci
- *
- * Routine to remove attachments points associated with a pci node.
- * Can be call externally by DR when unconfiguring a PCI I/O Board.
- */
-int
-schpc_remove_pci(dev_info_t *dip)
-{
- int slot;
-
- SCHPC_DEBUG1(D_DETACH, "schpc_remove_pci(dip=0x%p)", (void *)dip);
-
- if (schpc_p == NULL) {
- /*
- * The schpc driver has not been attached yet.
- */
- return (DDI_SUCCESS);
- }
-
- for (slot = 0; slot < schpc_p->schpc_number_of_slots; slot++) {
- if (schpc_p->schpc_slot[slot].devi == dip) {
-
- if (schpc_p->schpc_slot[slot].slot_ops) {
- if (hpc_slot_unregister(
- &schpc_p->schpc_slot[slot].slot_handle)) {
- cmn_err(CE_WARN,
- "schpc_remove_pci(dip=0x%p) - "
- "unable to unregister pci slots\n",
- (void *)dip);
- return (DDI_FAILURE);
- } else {
- hpc_free_slot_ops(
- schpc_p->schpc_slot[slot].slot_ops);
-
- schpc_p->schpc_slot[slot].slot_ops =
- NULL;
-
- schpc_p->schpc_slot[slot].devi = NULL;
-
- return (DDI_SUCCESS);
- }
- } else {
- schpc_p->schpc_slot[slot].devi = NULL;
-
- return (DDI_SUCCESS);
- }
- }
- }
-
- cmn_err(CE_WARN, "schpc_remove_pci(dip=0x%p) "
- "dip not found\n", (void *)dip);
-
- return (DDI_SUCCESS);
-}
-
-/*
- * schpc_match_dip
- *
- * Used by ddi_walk_devs to find PCI Nexus nodes associated with
- * Hot Plug Controllers.
- */
-static int
-schpc_match_dip(dev_info_t *dip, void *arg)
-{
- char *naddr;
- find_dev_t *find_dev = (find_dev_t *)arg;
-
- if (strcmp(find_dev->cname, ddi_node_name(dip)) == 0 &&
- ((((naddr = ddi_get_name_addr(dip)) != NULL) &&
- (strcmp(find_dev->caddr, naddr) == 0)) ||
- ((naddr == NULL) && (strlen(find_dev->caddr) == 0)))) {
- /*
- * While ddi_walk_devs() holds dips when invoking this
- * callback, this dip is being saved and will be accessible
- * to the caller outside ddi_walk_devs(). Therefore it must be
- * held.
- */
- ndi_hold_devi(dip);
- find_dev->dip = dip;
-
- SCHPC_DEBUG2(D_ATTACH,
- "schpc_match_dip: pci@%s FOUND dip=0x%p",
- find_dev->caddr, (void *)find_dev->dip);
-
- return (DDI_WALK_TERMINATE);
- }
-
- ASSERT(find_dev->dip == NULL);
- return (DDI_WALK_CONTINUE);
-}
-
-/*
- * schpc_buildapid
- *
- * Takes a component address and translates it into a ap_id prefix.
- */
-static void
-schpc_buildapid(dev_info_t *dip, int slot, char *ap_id)
-{
- int r, pci_id_cnt, pci_id_bit;
- int slots_before, found;
- unsigned char *slot_names_data, *s;
- int slot_names_size;
- int slot_num;
- unsigned int bit_mask;
-
- slot_num = SCHPC_SLOT_NUM(slot);
-
- if (schpc_use_legacy_apid) {
- SCHPC_DEBUG1(D_APID, "Slot %d - Using Legacy ap-id", slot);
-
- (void) sprintf(ap_id, "e%02db%dslot%d", schpc_getexpander(dip),
- schpc_getboard(dip), slot_num);
-
- SCHPC_DEBUG2(D_APID, "Slot %d - ap-id=%s", slot, ap_id);
-
- return;
- }
-
- r = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "slot-names", (caddr_t)&slot_names_data,
- &slot_names_size);
-
- if (r == DDI_PROP_SUCCESS) {
-
- /*
- * We can try to use the slot-names property to
- * build our ap-id.
- */
- bit_mask = slot_names_data[3] | (slot_names_data[2] << 8) |
- (slot_names_data[1] << 16) | (slot_names_data[0] << 24);
-
- pci_id_bit = 1;
- pci_id_cnt = slots_before = found = 0;
-
- SCHPC_DEBUG2(D_APID, "Slot %d - slot-names bitmask=%x",
- slot, bit_mask);
-
- /*
- * Walk the bit mask until we find the bit that corresponds
- * to our slots device number. We count how many bits
- * we find before we find our slot's bit.
- */
- while (!found && (pci_id_cnt < 32)) {
-
- while (schpc_p->schpc_slot[slot].pci_id
- != pci_id_cnt) {
-
- /*
- * Find the next bit set.
- */
- while (!(bit_mask & pci_id_bit) &&
- (pci_id_cnt < 32)) {
- pci_id_bit = pci_id_bit << 1;
- pci_id_cnt++;
- }
-
- if (schpc_p->schpc_slot[slot].pci_id !=
- pci_id_cnt)
- slots_before++;
- else
- found = 1;
- }
- }
-
- if (pci_id_cnt < 32) {
-
- /*
- * Set ptr to first string.
- */
- s = slot_names_data + 4;
-
- /*
- * Increment past all the strings for the slots
- * before ours.
- */
- while (slots_before) {
- while (*s != NULL)
- s++;
- s++;
- slots_before--;
- }
-
- /*
- * We should be at our string.
- */
-
- (void) sprintf(ap_id, "IO%d_%s",
- schpc_getexpander(dip), s);
-
- SCHPC_DEBUG2(D_APID, "Slot %d - ap-id=%s",
- slot, ap_id);
-
- kmem_free(slot_names_data, slot_names_size);
- return;
- }
-
- SCHPC_DEBUG1(D_APID, "Slot %d - slot-names entry not found",
- slot);
-
- kmem_free(slot_names_data, slot_names_size);
- } else
- SCHPC_DEBUG1(D_APID, "Slot %d - No slot-names prop found",
- slot);
-
- /*
- * Build the ap-id using the legacy naming scheme.
- */
- (void) sprintf(ap_id, "e%02db%dslot%d", schpc_getexpander(dip),
- schpc_getboard(dip), slot_num);
-
- SCHPC_DEBUG2(D_APID, "Slot %d - ap-id=%s", slot, ap_id);
-}
-
-/*
- * schpc_getexpander
- *
- * Returns the Expander Number (0-17) for the dip passed in. The Expander
- * Number is extracted from the portid property of the pci node. Portid
- * consists of <Expbrd#><1110x>, where x is the schizo number.
- */
-static int
-schpc_getexpander(dev_info_t *dip)
-{
- int id;
-
- id = ddi_getprop(DDI_DEV_T_ANY, dip, 0, "portid", -1);
-
- if (id != -1)
- return (id >> 5);
- else {
- id = ddi_getprop(DDI_DEV_T_ANY, dip, 0, "expander", -1);
- return (id);
- }
-}
-
-/*
- * schpc_getboard
- *
- * Returns the board number (0 or 1) for the dip passed in.
- */
-static int
-schpc_getboard(dev_info_t *dip)
-{
- _NOTE(ARGUNUSED(dip))
-
- /*
- * Hot Pluggable PCI/cPCI slots are only available on
- * Board 1 (half-bandwidth slot).
- */
- return (1);
-}
-
-/*ARGSUSED*/
-static int
-schpc_get_slot_status(uint_t expander, uint_t board, uint_t slot)
-{
- gdcd_t *gdcd;
- int prd_slot, status, bus;
-
- SCHPC_DEBUG3(D_ATTACH, "schpc_get_slot_status() "
- "exp=%d board=%d slot=%d", expander, board, slot);
-
- if ((gdcd = (gdcd_t *)kmem_zalloc(sizeof (gdcd_t),
- KM_SLEEP)) == NULL) {
- return (RSV_UNDEFINED);
- }
-
- /*
- * Get the Starcat Specific Global DCD Structure from the golden
- * IOSRAM.
- */
- if (iosram_rd(GDCD_MAGIC, 0, sizeof (gdcd_t), (caddr_t)gdcd)) {
- cmn_err(CE_WARN, "sc_gptwocfg: Unable To Read GDCD "
- "From IOSRAM\n");
- kmem_free(gdcd, sizeof (gdcd_t));
- return (RSV_UNDEFINED);
- }
-
- if (gdcd->h.dcd_magic != GDCD_MAGIC) {
-
- cmn_err(CE_WARN, "schpc: GDCD Bad Magic 0x%x\n",
- gdcd->h.dcd_magic);
-
- kmem_free(gdcd, sizeof (gdcd_t));
- return (RSV_UNDEFINED);
- }
-
- if (gdcd->h.dcd_version != DCD_VERSION) {
- cmn_err(CE_WARN, "schpc: GDCD Bad Version: "
- "GDCD Version 0x%x Expecting 0x%x\n",
- gdcd->h.dcd_version, DCD_VERSION);
-
- kmem_free(gdcd, sizeof (gdcd_t));
- return (RSV_UNDEFINED);
- }
-
- if (slot < 2)
- prd_slot = 4;
- else
- prd_slot = 5;
-
- bus = slot & 0x1;
-
- status = gdcd->dcd_prd[expander][prd_slot].prd_iocard_rsv[bus][0];
-
- kmem_free(gdcd, sizeof (gdcd_t));
-
- SCHPC_DEBUG3(D_ATTACH, "schpc_get_slot_status() "
- "prd_slot=%d bus=%d status=%d", prd_slot, bus, status);
-
- return (status);
-}
-
-#define LEAF_SAVE_END 0xff
-
-typedef struct {
- int reg;
- int offset;
- int access_size;
- int number;
-} save_reg_list_t;
-
-/*
- * Save List Array. Describes the leaf registers that need to
- * be restored after a leaf reset.
- *
- * Entry 1 - Reg Entry: 0=PCI Leaf CSRs, 2=PCI Config Space
- * Entry 2 - Offset Start
- * Entry 3 - Access Size: 8=64 bit, 4=32 bit, 2=16 bit, 1=8 bit
- * Entry 4 - # of registers to be saved starting at offset,
- */
-save_reg_list_t save_reg_list[] = { 0, 0x110, 8, 1,
- 0, 0x200, 8, 2,
- 0, 0x1000, 8, 0x18,
- 0, 0x1a00, 8, 1,
- 0, 0x2000, 8, 1,
- 0, 0x2020, 8, 1,
- 0, 0x2040, 8, 1,
- 0, 0x2308, 8, 2,
- 0, 0x2800, 8, 1,
- 2, 0x04, 2, 1, /* Command */
- 2, 0x0d, 1, 1, /* Latency */
- 2, 0x40, 1, 1, /* Bus # */
- 2, 0x41, 1, 1, /* Sub. Bus # */
- LEAF_SAVE_END, 0, 0, 0};
-
-static int
-schpc_save_leaf(int slot)
-{
- int save_entry, list_entry, reg;
- caddr_t leaf_regs;
- ddi_device_acc_attr_t attr;
-
- SCHPC_DEBUG1(D_FREQCHG, "Slot %d - Leaf Registers Saved", slot);
-
- attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
- attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
- attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
-
- /*
- * Map in the 3 addresses spaces defined for XMITS.
- */
- for (reg = 0; reg < 3; reg++) {
- if (ddi_regs_map_setup(schpc_p->schpc_slot[slot].devi, reg,
- &leaf_regs, 0, 0, &attr, &schpc_p->schpc_slot[slot].
- saved_handle[reg]) != DDI_SUCCESS) {
- cmn_err(CE_WARN, "Mapin failed\n");
- schpc_p->schpc_slot[slot].saved_regs_va[reg] = NULL;
- return (1);
- }
-
- schpc_p->schpc_slot[slot].saved_regs_va[reg] = leaf_regs;
- }
-
-
- /*
- * Determine how many entries are in the list so we can
- * allocate the save space.
- */
- list_entry = 0;
- save_entry = 0;
- while (save_reg_list[list_entry].reg != LEAF_SAVE_END) {
- save_entry += save_reg_list[list_entry].number;
- list_entry++;
- }
-
- schpc_p->schpc_slot[slot].saved_size = (save_entry * sizeof (uint64_t));
-
- if (schpc_p->schpc_slot[slot].saved_size == 0)
- return (0);
-
- schpc_p->schpc_slot[slot].saved_regs =
- (uint64_t *)kmem_zalloc(schpc_p->schpc_slot[slot].saved_size,
- KM_SLEEP);
-
- /*
- * Walk through the register list and save contents.
- */
- list_entry = 0;
- save_entry = 0;
- while (save_reg_list[list_entry].reg != LEAF_SAVE_END) {
- schpc_save_entry(slot, list_entry, save_entry);
- save_entry += save_reg_list[list_entry].number;
- list_entry ++;
- }
-
- SCHPC_DEBUG1(D_FREQCHG, "Slot %d - Leaf Registers Saved", slot);
-
- return (0);
-}
-
-static void
-schpc_restore_leaf(int slot)
-{
- int save_entry, list_entry, reg;
-
- if (schpc_p->schpc_slot[slot].saved_regs == NULL)
- return;
-
- /*
- * Walk through the register list and restore contents.
- */
- list_entry = 0;
- save_entry = 0;
- while (save_reg_list[list_entry].reg != LEAF_SAVE_END) {
-
- schpc_restore_entry(slot, list_entry, save_entry);
-
- save_entry += save_reg_list[list_entry].number;
- list_entry ++;
- }
-
- /*
- * Free the mapped in registers.
- */
- for (reg = 0; reg < 3; reg++) {
- if (schpc_p->schpc_slot[slot].saved_regs_va[reg]) {
-
- ddi_regs_map_free(
- &schpc_p->schpc_slot[slot].saved_handle[reg]);
-
- schpc_p->schpc_slot[slot].saved_regs_va[reg] = NULL;
- }
- }
-
- kmem_free(schpc_p->schpc_slot[slot].saved_regs,
- schpc_p->schpc_slot[slot].saved_size);
-
- schpc_p->schpc_slot[slot].saved_size = 0;
- schpc_p->schpc_slot[slot].saved_regs = NULL;
-
- SCHPC_DEBUG1(D_FREQCHG, "Slot %d - Leaf Registers Restored", slot);
-}
-
-static void
-schpc_save_entry(int slot, int list_entry, int save_entry)
-{
- int reg, reads = 0;
-
- reg = save_reg_list[list_entry].reg;
-
- while (reads < save_reg_list[list_entry].number) {
- switch (save_reg_list[list_entry].access_size) {
- case 8:
- schpc_p->schpc_slot[slot].saved_regs[save_entry] =
- ddi_get64(
- schpc_p->schpc_slot[slot].saved_handle[reg],
- (uint64_t *)(schpc_p->schpc_slot[slot].
- saved_regs_va[reg]
- + save_reg_list[list_entry].offset +
- (reads * sizeof (uint64_t))));
-#ifdef DEBUG
- if (schpc_dump_save_regs)
- cmn_err(CE_WARN, "Save 64 %x %lx %lx\n", reg,
- save_reg_list[list_entry].offset +
- (reads * sizeof (uint64_t)),
- schpc_p->schpc_slot[slot].
- saved_regs[save_entry]);
-#endif
-
- break;
- case 4:
- schpc_p->schpc_slot[slot].saved_regs[save_entry] =
- ddi_get32(
- schpc_p->schpc_slot[slot].saved_handle[reg],
- (uint32_t *)(schpc_p->schpc_slot[slot].
- saved_regs_va[reg]
- + save_reg_list[list_entry].offset +
- (reads * sizeof (uint32_t))));
-
-#ifdef DEBUG
- if (schpc_dump_save_regs)
- cmn_err(CE_WARN, "Save 32 %x %lx %lx\n", reg,
- save_reg_list[list_entry].offset +
- (reads * sizeof (uint32_t)),
- schpc_p->schpc_slot[slot].
- saved_regs[save_entry]);
-#endif
-
- break;
- case 2:
- schpc_p->schpc_slot[slot].saved_regs[save_entry] =
- ddi_get16(
- schpc_p->schpc_slot[slot].saved_handle[reg],
- (uint16_t *)(schpc_p->schpc_slot[slot].
- saved_regs_va[reg]
- + save_reg_list[list_entry].offset +
- (reads * sizeof (uint16_t))));
-
-#ifdef DEBUG
- if (schpc_dump_save_regs)
- cmn_err(CE_WARN, "Save 16 %x %lx %lx\n", reg,
- save_reg_list[list_entry].offset +
- (reads * sizeof (uint16_t)),
- schpc_p->schpc_slot[slot].
- saved_regs[save_entry]);
-#endif
-
- break;
- case 1:
- schpc_p->schpc_slot[slot].saved_regs[save_entry] =
- ddi_get8(
- schpc_p->schpc_slot[slot].saved_handle[reg],
- (uint8_t *)(schpc_p->schpc_slot[slot].
- saved_regs_va[reg]
- + save_reg_list[list_entry].offset +
- (reads * sizeof (uint8_t))));
-
-#ifdef DEBUG
- if (schpc_dump_save_regs)
- cmn_err(CE_WARN, "Save 8 %x %lx %lx\n", reg,
- save_reg_list[list_entry].offset +
- (reads * sizeof (uint8_t)),
- schpc_p->schpc_slot[slot].
- saved_regs[save_entry]);
-#endif
-
- break;
- default:
- cmn_err(CE_WARN,
- "schpc: Illegal List Entry\n");
- }
- reads++;
- save_entry++;
- }
-}
-
-static void
-schpc_restore_entry(int slot, int list_entry, int save_entry)
-{
- int reg, writes = 0;
-
- reg = save_reg_list[list_entry].reg;
-
- while (writes < save_reg_list[list_entry].number) {
- switch (save_reg_list[list_entry].access_size) {
- case 8:
-#ifdef DEBUG
- if (schpc_dump_save_regs)
- cmn_err(CE_WARN, "Restore 64 %x %lx %lx\n", reg,
- save_reg_list[list_entry].offset +
- (writes * sizeof (uint64_t)),
- schpc_p->schpc_slot[slot].
- saved_regs[save_entry]);
-#endif
-
- ddi_put64(schpc_p->schpc_slot[slot].saved_handle[reg],
- (uint64_t *)(schpc_p->schpc_slot[slot].
- saved_regs_va[reg]
- + save_reg_list[list_entry].offset +
- (writes * sizeof (uint64_t))),
- schpc_p->schpc_slot[slot].saved_regs[save_entry]);
-
- break;
- case 4:
-#ifdef DEBUG
- if (schpc_dump_save_regs)
- cmn_err(CE_WARN, "Restore 32 %x %lx %lx\n", reg,
- save_reg_list[list_entry].offset +
- (writes * sizeof (uint32_t)),
- schpc_p->schpc_slot[slot].
- saved_regs[save_entry]);
-#endif
-
- ddi_put32(schpc_p->schpc_slot[slot].saved_handle[reg],
- (uint32_t *)(schpc_p->schpc_slot[slot].
- saved_regs_va[reg]
- + save_reg_list[list_entry].offset +
- (writes * sizeof (uint32_t))),
- schpc_p->schpc_slot[slot].saved_regs[save_entry]);
-
- break;
- case 2:
-#ifdef DEBUG
- if (schpc_dump_save_regs)
- cmn_err(CE_WARN, "Restore 16 %x %lx %lx\n", reg,
- save_reg_list[list_entry].offset +
- (writes * sizeof (uint16_t)),
- schpc_p->schpc_slot[slot].
- saved_regs[save_entry]);
-#endif
-
- ddi_put16(schpc_p->schpc_slot[slot].saved_handle[reg],
- (uint16_t *)(schpc_p->schpc_slot[slot].
- saved_regs_va[reg]
- + save_reg_list[list_entry].offset +
- (writes * sizeof (uint16_t))),
- schpc_p->schpc_slot[slot].saved_regs[save_entry]);
-
- break;
- case 1:
-#ifdef DEBUG
- if (schpc_dump_save_regs)
- cmn_err(CE_WARN, "Restore 8 %x %lx %lx\n", reg,
- save_reg_list[list_entry].offset +
- (writes * sizeof (uint8_t)),
- schpc_p->schpc_slot[slot].
- saved_regs[save_entry]);
-#endif
-
- ddi_put8(schpc_p->schpc_slot[slot].saved_handle[reg],
- (uint8_t *)(schpc_p->schpc_slot[slot].
- saved_regs_va[reg]
- + save_reg_list[list_entry].offset +
- (writes * sizeof (uint8_t))),
- schpc_p->schpc_slot[slot].saved_regs[save_entry]);
-
- break;
- default:
- cmn_err(CE_WARN,
- "schpc: Illegal List Entry\n");
- }
- writes++;
- save_entry++;
- }
-}
-
-/*
- * Returns TRUE if a leaf reset is required to change frequencies/mode.
- */
-static int
-schpc_is_leaf_reset_required(int slot)
-{
- char *name;
- int32_t mod_rev;
-
- /*
- * Only XMITS 3.0 and greater connected slots will require a
- * reset to switch frequency and/or mode.
- */
- name = ddi_binding_name(schpc_p->schpc_slot[slot].devi);
-
- if (strcmp(name, "pci108e,8002") == 0) {
- mod_rev = ddi_prop_get_int(DDI_DEV_T_ANY,
- schpc_p->schpc_slot[slot].devi,
- DDI_PROP_DONTPASS, "module-revision#", 0);
-
- SCHPC_DEBUG2(D_FREQCHG, "Slot %d - mod_rev=%x", slot, mod_rev);
-
- /*
- * Check for XMITS 3.0 or greater.
- */
- if (mod_rev >= XMITS_30) {
-
- /*
- * The leaf attached to C5V0 (slot 1) should
- * not be reset.
- */
- if ((slot & 3) == 1) {
-
- SCHPC_DEBUG1(D_FREQCHG, "Slot %d - Leaf Reset "
- "Not Required - C5V0", slot);
-
- return (0);
- }
-
- SCHPC_DEBUG1(D_FREQCHG, "Slot %d - Leaf Reset "
- "Required", slot);
-
- return (1);
- }
- }
- SCHPC_DEBUG1(D_FREQCHG, "Slot %d - Leaf Reset NOT Required", slot);
-
- return (0);
-}
-
-/*
- * Returns TRUE if the bus can change frequencies.
- */
-static int
-schpc_is_freq_switchable(int slot)
-{
- char *name;
- int32_t mod_rev;
-
- name = ddi_binding_name(schpc_p->schpc_slot[slot].devi);
-
- if (strcmp(name, "pci108e,8002") == 0) {
- mod_rev = ddi_prop_get_int(DDI_DEV_T_ANY,
- schpc_p->schpc_slot[slot].devi,
- DDI_PROP_DONTPASS, "module-revision#", 0);
-
- SCHPC_DEBUG2(D_FREQCHG, "Slot %d - mod_rev=%x", slot, mod_rev);
-
- /*
- * We will only report back that XMITS 2.0 (mod_rev = 2)
- * or greater will have the ability to switch frequencies.
- */
- if (mod_rev >= XMITS_20) {
- SCHPC_DEBUG1(D_FREQCHG, "Slot %d - "
- "Frequency is switchable", slot);
- return (1);
- }
- }
-
- SCHPC_DEBUG1(D_FREQCHG, "Slot %d - Frequency is NOT switchable", slot);
- return (0);
-}
-
-/*
- * schpc_slot_freq
- *
- * Convert the slot frequency setting to integer value.
- */
-static int
-schpc_slot_freq(pci_getslot_t *getslotp)
-{
- switch (getslotp->slot_freq_setting) {
- case PCIMSG_FREQ_33MHZ:
- return (SCHPC_33MHZ);
- case PCIMSG_FREQ_66MHZ:
- return (SCHPC_66MHZ);
- case PCIMSG_FREQ_90MHZ:
- return (SCHPC_90MHZ);
- case PCIMSG_FREQ_133MHZ:
- return (SCHPC_133MHZ);
- default:
- return (0);
- }
-}
-
-/*
- * schpc_find_dip
- *
- * Used by ddi_walk_devs to find the dip which belongs
- * to a certain slot.
- *
- * When this function returns, the dip is held. It is the
- * responsibility of the caller to release the dip.
- */
-static int
-schpc_find_dip(dev_info_t *dip, void *arg)
-{
- find_dev_t *find_dev = (find_dev_t *)arg;
- char *pathname = find_dev->caddr;
-
- (void) ddi_pathname(dip, pathname);
- if (strcmp(find_dev->cname, pathname) == 0) {
- ndi_hold_devi(dip);
- find_dev->dip = dip;
- return (DDI_WALK_TERMINATE);
- }
- return (DDI_WALK_CONTINUE);
-}
diff --git a/usr/src/uts/sun4u/starcat/io/schpc.conf b/usr/src/uts/sun4u/starcat/io/schpc.conf
deleted file mode 100644
index ecc0a9132a..0000000000
--- a/usr/src/uts/sun4u/starcat/io/schpc.conf
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2001 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-name="schpc" parent="pseudo" instance=0;
-#
-# force attach driver to support hotplug activity
-#
-ddi-forceattach=1;
diff --git a/usr/src/uts/sun4u/starcat/io/sckmdrv.c b/usr/src/uts/sun4u/starcat/io/sckmdrv.c
deleted file mode 100644
index 4882ece935..0000000000
--- a/usr/src/uts/sun4u/starcat/io/sckmdrv.c
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-/*
- * Starcat IPSec Key Management Driver.
- *
- * This driver runs on a Starcat Domain. It processes requests received
- * from the System Controller (SC) from IOSRAM, passes these requests
- * to the sckmd daemon by means of an open/close/ioctl interface, and
- * sends corresponding status information back to the SC.
- *
- * Requests received from the SC consist of IPsec security associations
- * (SAs) needed to secure the communication between SC and Domain daemons
- * communicating using the Management Network (MAN).
- */
-
-#include <sys/types.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/errno.h>
-#include <sys/file.h>
-#include <sys/open.h>
-#include <sys/stat.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-#include <sys/cmn_err.h>
-#include <sys/sunddi.h>
-#include <sys/sunndi.h>
-#include <sys/ddi_impldefs.h>
-#include <sys/ndi_impldefs.h>
-#include <sys/modctl.h>
-#include <sys/disp.h>
-#include <sys/async.h>
-#include <sys/mboxsc.h>
-#include <sys/sckm_msg.h>
-#include <sys/sckm_io.h>
-#include <sys/taskq.h>
-#include <sys/note.h>
-
-#ifdef DEBUG
-static uint_t sckm_debug_flags = 0x0;
-#define SCKM_DEBUG0(f, s) if ((f)& sckm_debug_flags) \
- cmn_err(CE_CONT, s)
-#define SCKM_DEBUG1(f, s, a) if ((f)& sckm_debug_flags) \
- cmn_err(CE_CONT, s, a)
-#define SCKM_DEBUG2(f, s, a, b) if ((f)& sckm_debug_flags) \
- cmn_err(CE_CONT, s, a, b)
-#define SCKM_DEBUG3(f, s, a, b, c) if ((f)& sckm_debug_flags) \
- cmn_err(CE_CONT, s, a, b, c)
-#define SCKM_DEBUG4(f, s, a, b, c, d) if ((f)& sckm_debug_flags) \
- cmn_err(CE_CONT, s, a, b, c, d)
-#define SCKM_DEBUG5(f, s, a, b, c, d, e) if ((f)& sckm_debug_flags) \
- cmn_err(CE_CONT, s, a, b, c, d, e)
-#define SCKM_DEBUG6(f, s, a, b, c, d, e, ff) if ((f)& sckm_debug_flags) \
- cmn_err(CE_CONT, s, a, b, c, d, e, ff)
-#else
-#define SCKM_DEBUG0(f, s)
-#define SCKM_DEBUG1(f, s, a)
-#define SCKM_DEBUG2(f, s, a, b)
-#define SCKM_DEBUG3(f, s, a, b, c)
-#define SCKM_DEBUG4(f, s, a, b, c, d)
-#define SCKM_DEBUG5(f, s, a, b, c, d, e)
-#define SCKM_DEBUG6(f, s, a, b, c, d, e, ff)
-#endif /* DEBUG */
-
-#define D_INIT 0x00000001 /* _init/_fini/_info */
-#define D_ATTACH 0x00000002 /* attach/detach */
-#define D_OPEN 0x00000008 /* open/close */
-#define D_IOCTL 0x00010000 /* ioctl */
-#define D_TASK 0x00100000 /* mailbox task processing */
-#define D_CALLBACK 0x00200000 /* mailbox callback */
-
-static int sckm_open(dev_t *, int, int, struct cred *);
-static int sckm_close(dev_t, int, int, struct cred *);
-static int sckm_ioctl(dev_t, int, intptr_t, int, struct cred *, int *);
-
-static struct cb_ops sckm_cb_ops = {
- sckm_open, /* open */
- sckm_close, /* close */
- nodev, /* strategy */
- nodev, /* print */
- nodev, /* dump */
- nodev, /* read */
- nodev, /* write */
- sckm_ioctl, /* ioctl */
- nodev, /* devmap */
- nodev, /* mmap */
- nodev, /* segmap */
- nochpoll, /* poll */
- ddi_prop_op, /* prop_op */
- 0, /* streamtab */
- D_NEW | D_MP /* Driver compatibility flag */
-};
-
-static int sckm_attach(dev_info_t *, ddi_attach_cmd_t);
-static int sckm_detach(dev_info_t *, ddi_detach_cmd_t);
-static int sckm_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
-
-static struct dev_ops sckm_ops = {
- DEVO_REV, /* devo_rev, */
- 0, /* refcnt */
- sckm_info, /* get_dev_info */
- nulldev, /* identify */
- nulldev, /* probe */
- sckm_attach, /* attach */
- sckm_detach, /* detach */
- nodev, /* reset */
- &sckm_cb_ops, /* driver operations */
- (struct bus_ops *)0, /* no bus operations */
- NULL, /* power */
- ddi_quiesce_not_needed, /* quiesce */
-};
-
-static struct modldrv modldrv = {
- &mod_driverops,
- "Key Management Driver",
- &sckm_ops,
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- &modldrv,
- NULL
-};
-
-/*
- * Private definitions.
- */
-#define SCKM_DEF_GETMSG_TIMEOUT 60 /* in seconds */
-#define SCKM_DAEMON_TIMEOUT 4000000 /* in microseconds */
-#define SCKM_NUM_TASKQ 2 /* # of task queue entries */
-
-/*
- * For processing mailbox layer events.
- */
-static kmutex_t sckm_task_mutex;
-static kmutex_t sckm_taskq_ptr_mutex;
-static clock_t sckm_getmsg_timeout = SCKM_DEF_GETMSG_TIMEOUT*1000;
-static taskq_t *sckm_taskq = NULL;
-static sckm_mbox_req_hdr_t *req_data = NULL;
-static sckm_mbox_rep_hdr_t *rep_data = NULL;
-
-
-/*
- * For synchronization with key management daemon.
- */
-static kmutex_t sckm_umutex;
-static kcondvar_t sckm_udata_cv; /* daemon waits on data */
-static kcondvar_t sckm_cons_cv; /* wait for daemon to consume data */
-static boolean_t sckm_udata_req = B_FALSE; /* data available for daemon */
-static sckm_ioctl_getreq_t sckm_udata; /* request for daemon */
-static sckm_ioctl_status_t sckm_udata_status; /* status from daemon */
-
-/*
- * Other misc private variables.
- */
-static dev_info_t *sckm_devi = NULL;
-static boolean_t sckm_oflag = B_FALSE;
-
-/*
- * Private functions prototypes.
- */
-static void sckm_mbox_callback(void);
-static void sckm_mbox_task(void *arg);
-static void sckm_process_msg(uint32_t cmd, uint64_t transid,
- uint32_t len, sckm_mbox_req_hdr_t *req_data,
- sckm_mbox_rep_hdr_t *rep_data);
-
-
-int
-_init(void)
-{
- mboxsc_timeout_range_t timeout_range;
- int ret;
-
- SCKM_DEBUG0(D_INIT, "in _init");
-
- /*
- * Initialize outgoing mailbox (KDSC)
- */
- if ((ret = mboxsc_init(KEY_KDSC, MBOXSC_MBOX_OUT, NULL)) != 0) {
- cmn_err(CE_WARN, "failed initializing outgoing mailbox "
- "(%d)", ret);
- return (ret);
- }
-
- /*
- * Initialize incoming mailbox (SCKD)
- */
- if ((ret = mboxsc_init(KEY_SCKD, MBOXSC_MBOX_IN,
- sckm_mbox_callback)) != 0) {
- cmn_err(CE_WARN, "failed initializing incoming mailbox "
- "(%d)\n", ret);
- (void) mboxsc_fini(KEY_KDSC);
- return (ret);
- }
-
- if ((ret = mboxsc_ctrl(KEY_SCKD, MBOXSC_CMD_GETMSG_TIMEOUT_RANGE,
- (void *)&timeout_range)) != 0) {
- (void) mboxsc_fini(KEY_SCKD);
- (void) mboxsc_fini(KEY_KDSC);
- return (ret);
- }
-
- if (sckm_getmsg_timeout < timeout_range.min_timeout) {
- sckm_getmsg_timeout = timeout_range.min_timeout;
- cmn_err(CE_WARN, "resetting getmsg timeout to %lx",
- sckm_getmsg_timeout);
- }
-
- if (sckm_getmsg_timeout > timeout_range.max_timeout) {
- sckm_getmsg_timeout = timeout_range.max_timeout;
- cmn_err(CE_WARN, "resetting getmsg timeout to %lx",
- sckm_getmsg_timeout);
- }
-
- if ((ret = mod_install(&modlinkage)) != 0) {
- (void) mboxsc_fini(KEY_KDSC);
- (void) mboxsc_fini(KEY_SCKD);
- return (ret);
- }
-
- /*
- * Initialize variables needed for synchronization with daemon.
- */
- sckm_udata.buf = kmem_alloc(SCKM_SCKD_MAXDATA, KM_SLEEP);
- req_data = (sckm_mbox_req_hdr_t *)kmem_alloc(SCKM_SCKD_MAXDATA,
- KM_SLEEP);
- rep_data = (sckm_mbox_rep_hdr_t *)kmem_alloc(SCKM_KDSC_MAXDATA,
- KM_SLEEP);
-
- if ((sckm_udata.buf == NULL) || (req_data == NULL) ||
- (rep_data == NULL)) {
- cmn_err(CE_WARN, "not enough memory during _init");
-
- /* free what was successfully allocated */
- if (sckm_udata.buf != NULL)
- kmem_free(sckm_udata.buf, SCKM_SCKD_MAXDATA);
- if (req_data != NULL)
- kmem_free(req_data, SCKM_SCKD_MAXDATA);
- if (rep_data != NULL)
- kmem_free(rep_data, SCKM_KDSC_MAXDATA);
- sckm_udata.buf = NULL;
- req_data = NULL;
- rep_data = NULL;
-
- /* uninitialize mailboxes, remove module, and return error */
- (void) mboxsc_fini(KEY_KDSC);
- (void) mboxsc_fini(KEY_SCKD);
- (void) mod_remove(&modlinkage);
- return (-1);
- }
-
- cv_init(&sckm_udata_cv, NULL, CV_DRIVER, NULL);
- cv_init(&sckm_cons_cv, NULL, CV_DRIVER, NULL);
- mutex_init(&sckm_umutex, NULL, MUTEX_DRIVER, NULL);
-
- /*
- * Create mutex for task processing, protection of taskq
- * pointer, and create taskq.
- */
- mutex_init(&sckm_task_mutex, NULL, MUTEX_DRIVER, NULL);
- mutex_init(&sckm_taskq_ptr_mutex, NULL, MUTEX_DRIVER, NULL);
- sckm_taskq = taskq_create("sckm_taskq", 1, minclsyspri,
- SCKM_NUM_TASKQ, SCKM_NUM_TASKQ, TASKQ_PREPOPULATE);
-
- SCKM_DEBUG1(D_INIT, "out _init ret=%d\n", ret);
- return (ret);
-}
-
-int
-_fini(void)
-{
- int ret;
-
- SCKM_DEBUG0(D_INIT, "in _fini");
-
- if ((ret = mod_remove(&modlinkage)) != 0) {
- return (ret);
- }
-
- /*
- * Wait for scheduled tasks to complete, then destroy task queue.
- */
- mutex_enter(&sckm_taskq_ptr_mutex);
- if (sckm_taskq != NULL) {
- taskq_destroy(sckm_taskq);
- sckm_taskq = NULL;
- }
- mutex_exit(&sckm_taskq_ptr_mutex);
-
- /*
- * Terminate incoming and outgoing IOSRAM mailboxes
- */
- (void) mboxsc_fini(KEY_KDSC);
- (void) mboxsc_fini(KEY_SCKD);
-
- /*
- * Destroy module synchronization objects and free memory
- */
- mutex_destroy(&sckm_task_mutex);
- mutex_destroy(&sckm_taskq_ptr_mutex);
- mutex_destroy(&sckm_umutex);
- cv_destroy(&sckm_cons_cv);
-
- if (sckm_udata.buf != NULL) {
- kmem_free(sckm_udata.buf, SCKM_SCKD_MAXDATA);
- sckm_udata.buf = NULL;
- }
- if (rep_data != NULL) {
- kmem_free(rep_data, SCKM_KDSC_MAXDATA);
- rep_data = NULL;
- }
- if (req_data != NULL) {
- kmem_free(req_data, SCKM_SCKD_MAXDATA);
- req_data = NULL;
- }
-
- return (ret);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- SCKM_DEBUG0(D_INIT, "in _info");
- return (mod_info(&modlinkage, modinfop));
-}
-
-static int
-sckm_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
-{
- SCKM_DEBUG1(D_ATTACH, "in sckm_attach, cmd=%d", cmd);
-
- switch (cmd) {
- case DDI_ATTACH:
- SCKM_DEBUG0(D_ATTACH, "sckm_attach: DDI_ATTACH");
- if (ddi_create_minor_node(devi, "sckmdrv", S_IFCHR,
- 0, NULL, NULL) == DDI_FAILURE) {
- cmn_err(CE_WARN, "ddi_create_minor_node failed");
- ddi_remove_minor_node(devi, NULL);
- return (DDI_FAILURE);
- }
- sckm_devi = devi;
- break;
- case DDI_SUSPEND:
- SCKM_DEBUG0(D_ATTACH, "sckm_attach: DDI_SUSPEND");
- break;
- default:
- cmn_err(CE_WARN, "sckm_attach: bad cmd %d\n", cmd);
- return (DDI_FAILURE);
- }
-
- SCKM_DEBUG0(D_ATTACH, "out sckm_attach (DDI_SUCCESS)");
- return (DDI_SUCCESS);
-}
-
-static int
-sckm_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
-{
- SCKM_DEBUG1(D_ATTACH, "in sckm_detach, cmd=%d", cmd);
-
- switch (cmd) {
- case DDI_DETACH:
- SCKM_DEBUG0(D_ATTACH, "sckm_detach: DDI_DETACH");
- ddi_remove_minor_node(devi, NULL);
- break;
- case DDI_SUSPEND:
- SCKM_DEBUG0(D_ATTACH, "sckm_detach: DDI_DETACH");
- break;
- default:
- cmn_err(CE_WARN, "sckm_detach: bad cmd %d\n", cmd);
- return (DDI_FAILURE);
- }
-
- SCKM_DEBUG0(D_ATTACH, "out sckm_detach (DDI_SUCCESS)");
- return (DDI_SUCCESS);
-}
-
-/* ARGSUSED */
-static int
-sckm_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
- void **result)
-{
- int rv;
-
- SCKM_DEBUG1(D_ATTACH, "in sckm_info, infocmd=%d", infocmd);
-
- switch (infocmd) {
- case DDI_INFO_DEVT2DEVINFO:
- *result = (void *)sckm_devi;
- rv = DDI_SUCCESS;
- break;
- case DDI_INFO_DEVT2INSTANCE:
- *result = (void *)0;
- rv = DDI_SUCCESS;
- break;
- default:
- rv = DDI_FAILURE;
- }
-
- SCKM_DEBUG1(D_ATTACH, "out sckm_info, rv=%d", rv);
- return (rv);
-}
-
-/*ARGSUSED*/
-static int
-sckm_open(dev_t *devp, int flag, int otyp, struct cred *cred)
-{
- SCKM_DEBUG0(D_OPEN, "in sckm_open");
-
- /* check credentials of calling process */
- if (drv_priv(cred)) {
- SCKM_DEBUG0(D_OPEN, "sckm_open: attempt by non-root proc");
- return (EPERM);
- }
-
- /* enforce exclusive access */
- mutex_enter(&sckm_umutex);
- if (sckm_oflag == B_TRUE) {
- SCKM_DEBUG0(D_OPEN, "sckm_open: already open");
- mutex_exit(&sckm_umutex);
- return (EBUSY);
- }
- sckm_oflag = B_TRUE;
- mutex_exit(&sckm_umutex);
-
- SCKM_DEBUG0(D_OPEN, "sckm_open: succcess");
- return (0);
-}
-
-/*ARGSUSED*/
-static int
-sckm_close(dev_t dev, int flag, int otyp, struct cred *cred)
-{
- SCKM_DEBUG0(D_OPEN, "in sckm_close");
-
- mutex_enter(&sckm_umutex);
- sckm_oflag = B_FALSE;
- mutex_exit(&sckm_umutex);
-
- return (0);
-}
-
-
-static int
-sckm_copyin_ioctl_getreq(intptr_t userarg, sckm_ioctl_getreq_t *driverarg,
- int flag)
-{
-#ifdef _MULTI_DATAMODEL
- switch (ddi_model_convert_from(flag & FMODELS)) {
- case DDI_MODEL_ILP32: {
- sckm_ioctl_getreq32_t driverarg32;
- if (ddi_copyin((caddr_t)userarg, &driverarg32,
- sizeof (sckm_ioctl_getreq32_t), flag)) {
- return (EFAULT);
- }
- driverarg->transid = driverarg32.transid;
- driverarg->type = driverarg32.type;
- driverarg->buf = (caddr_t)(uintptr_t)driverarg32.buf;
- driverarg->buf_len = driverarg32.buf_len;
- break;
- }
- case DDI_MODEL_NONE: {
- if (ddi_copyin((caddr_t)userarg, &driverarg,
- sizeof (sckm_ioctl_getreq_t), flag)) {
- return (EFAULT);
- }
- break;
- }
- }
-#else /* ! _MULTI_DATAMODEL */
- if (ddi_copyin((caddr_t)userarg, &driverarg,
- sizeof (sckm_ioctl_getreq_t), flag)) {
- return (EFAULT);
- }
-#endif /* _MULTI_DATAMODEL */
- return (0);
-}
-
-
-static int
-sckm_copyout_ioctl_getreq(sckm_ioctl_getreq_t *driverarg, intptr_t userarg,
- int flag)
-{
-#ifdef _MULTI_DATAMODEL
- switch (ddi_model_convert_from(flag & FMODELS)) {
- case DDI_MODEL_ILP32: {
- sckm_ioctl_getreq32_t driverarg32;
- driverarg32.transid = driverarg->transid;
- driverarg32.type = driverarg->type;
- driverarg32.buf = (caddr32_t)(uintptr_t)driverarg->buf;
- driverarg32.buf_len = driverarg->buf_len;
- if (ddi_copyout(&driverarg32, (caddr_t)userarg,
- sizeof (sckm_ioctl_getreq32_t), flag)) {
- return (EFAULT);
- }
- break;
- }
- case DDI_MODEL_NONE:
- if (ddi_copyout(driverarg, (caddr_t)userarg,
- sizeof (sckm_ioctl_getreq_t), flag)) {
- return (EFAULT);
- }
- break;
- }
-#else /* ! _MULTI_DATAMODEL */
- if (ddi_copyout(driverarg, (caddr_t)userarg,
- sizeof (sckm_ioctl_getreq_t), flag)) {
- return (EFAULT);
- }
-#endif /* _MULTI_DATAMODEL */
- return (0);
-}
-
-
-/*ARGSUSED*/
-static int
-sckm_ioctl(dev_t dev, int cmd, intptr_t data, int flag,
- cred_t *cred, int *rvalp)
-{
- int rval = 0;
-
- SCKM_DEBUG0(D_IOCTL, "in sckm_ioctl");
-
- switch (cmd) {
- case SCKM_IOCTL_GETREQ: {
- sckm_ioctl_getreq_t arg;
-
- SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: got SCKM_IOCTL_GETREQ");
- if (sckm_copyin_ioctl_getreq(data, &arg, flag)) {
- return (EFAULT);
- }
-
- /* sanity check argument */
- if (arg.buf_len < SCKM_SCKD_MAXDATA) {
- SCKM_DEBUG2(D_IOCTL, "sckm_ioctl: usr buffer too "
- "small (%d < %d)", arg.buf_len, SCKM_SCKD_MAXDATA);
- return (ENOSPC);
- }
-
- mutex_enter(&sckm_umutex);
-
- /* wait for request from SC */
- while (!sckm_udata_req) {
- SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: waiting for msg");
- if (cv_wait_sig(&sckm_udata_cv, &sckm_umutex) == 0) {
- mutex_exit(&sckm_umutex);
- return (EINTR);
- }
- }
- SCKM_DEBUG1(D_IOCTL, "sckm_ioctl: msg available "
- "transid = 0x%lx", sckm_udata.transid);
-
- arg.transid = sckm_udata.transid;
- arg.type = sckm_udata.type;
- if (ddi_copyout(sckm_udata.buf, arg.buf,
- sckm_udata.buf_len, flag)) {
- mutex_exit(&sckm_umutex);
- return (EFAULT);
- }
- arg.buf_len = sckm_udata.buf_len;
-
- mutex_exit(&sckm_umutex);
- if (sckm_copyout_ioctl_getreq(&arg, data, flag)) {
- return (EFAULT);
- }
- break;
- }
- case SCKM_IOCTL_STATUS: {
- sckm_ioctl_status_t arg;
- SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: got SCKM_IOCTL_STATUS");
- if (ddi_copyin((caddr_t)data, &arg,
- sizeof (sckm_ioctl_status_t), flag)) {
- cmn_err(CE_WARN, "sckm_ioctl: ddi_copyin failed");
- return (EFAULT);
- }
- SCKM_DEBUG3(D_IOCTL, "sckm_ioctl: arg transid=0x%lx, "
- "status=%d, sadb_msg_errno=%d", arg.transid, arg.status,
- arg.sadb_msg_errno);
-
- mutex_enter(&sckm_umutex);
-
- /* fail if no status is expected, or if it does not match */
- if (!sckm_udata_req || sckm_udata.transid != arg.transid) {
- mutex_exit(&sckm_umutex);
- return (EINVAL);
- }
-
- /* update status information for event handler */
- bcopy(&arg, &sckm_udata_status, sizeof (sckm_ioctl_status_t));
-
- /* signal event handler that request has been processed */
- SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: signaling event handler"
- " that data has been processed");
- cv_signal(&sckm_cons_cv);
- sckm_udata_req = B_FALSE;
-
- mutex_exit(&sckm_umutex);
- break;
- }
- default:
- SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: unknown command");
- rval = EINVAL;
- }
-
- SCKM_DEBUG1(D_IOCTL, "out sckm_ioctl, rval=%d", rval);
- return (rval);
-}
-
-
-/*
- * sckm_mbox_callback
- *
- * Callback routine registered with the IOSRAM mailbox protocol driver.
- * Invoked when a message is received on the mailbox.
- */
-static void
-sckm_mbox_callback(void)
-{
- SCKM_DEBUG0(D_CALLBACK, "in sckm_mbox_callback()");
-
- mutex_enter(&sckm_taskq_ptr_mutex);
-
- if (sckm_taskq == NULL) {
- mutex_exit(&sckm_taskq_ptr_mutex);
- return;
- }
-
- if (taskq_dispatch(sckm_taskq, sckm_mbox_task, NULL, KM_NOSLEEP) ==
- TASKQID_INVALID) {
- /*
- * Too many tasks already pending. Do not queue a new
- * request.
- */
- SCKM_DEBUG0(D_CALLBACK, "failed dispatching task");
- }
-
- mutex_exit(&sckm_taskq_ptr_mutex);
-
- SCKM_DEBUG0(D_CALLBACK, "out sckm_mbox_callback()");
-}
-
-
-/*
- * sckm_mbox_task
- *
- * Dispatched on taskq from the IOSRAM mailbox callback
- * sckm_mbox_callback when a message is received on the incoming
- * mailbox.
- */
-static void
-sckm_mbox_task(void *ignored)
-{
- _NOTE(ARGUNUSED(ignored))
- uint32_t type, cmd, length;
- uint64_t transid;
- int rval;
-
- SCKM_DEBUG0(D_TASK, "in sckm_mbox_task\n");
-
- mutex_enter(&sckm_task_mutex);
-
- if (req_data == NULL || rep_data == NULL) {
- SCKM_DEBUG0(D_TASK, "sckm_mbox_task: no buffers");
- mutex_exit(&sckm_task_mutex);
- return;
- }
-
- /*
- * Get mailbox message.
- */
-
- type = MBOXSC_MSG_REQUEST;
- length = SCKM_SCKD_MAXDATA;
- cmd = 0;
- transid = 0;
-
- SCKM_DEBUG0(D_TASK, "sckm_mbox_task: "
- "calling mboxsc_getmsg()\n");
- rval = mboxsc_getmsg(KEY_SCKD, &type, &cmd, &transid,
- &length, req_data, sckm_getmsg_timeout);
-
- if (rval != 0) {
- SCKM_DEBUG1(D_TASK, "sckm_mbox_task: "
- "mboxsc_getmsg() failed (%d)\n", rval);
- mutex_exit(&sckm_task_mutex);
- return;
- }
-
- SCKM_DEBUG4(D_TASK, "sckm_mbox_task: "
- "type=0x%x cmd=0x%x length=%d transid=0x%lx\n",
- type, cmd, length, transid);
-
- /* check message length */
- if (length < sizeof (sckm_mbox_req_hdr_t)) {
- /* protocol error, drop message */
- SCKM_DEBUG2(D_TASK, "received short "
- "message of length %d, min %lu",
- length, sizeof (sckm_mbox_req_hdr_t));
- mutex_exit(&sckm_task_mutex);
- return;
- }
-
- /* check version of message received */
- if (req_data->sckm_version != SCKM_PROTOCOL_VERSION) {
- SCKM_DEBUG2(D_TASK, "received protocol "
- "version %d, expected %d",
- req_data->sckm_version, SCKM_PROTOCOL_VERSION);
- /*
- * Send reply with SCKM_SADB_ERR_VERSION error
- * so that SC can adopt correct protocol version
- * for this domain.
- */
- rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
- rep_data->status = SCKM_ERR_VERSION;
-
- rval = mboxsc_putmsg(KEY_KDSC, MBOXSC_MSG_REPLY,
- cmd, &transid, sizeof (sckm_mbox_rep_hdr_t),
- rep_data, MBOXSC_PUTMSG_DEF_TIMEOUT);
-
- if (rval != 0) {
- SCKM_DEBUG1(D_TASK, "sckm_mbox_task: "
- "mboxsc_putmsg() failed (%d)\n", rval);
- mutex_exit(&sckm_task_mutex);
- return;
- }
- }
-
- /* process message */
- sckm_process_msg(cmd, transid, length,
- req_data, rep_data);
-
- mutex_exit(&sckm_task_mutex);
-}
-
-/*
- * sckm_process_msg
- *
- * Process a message received from the SC. Invoked by sckm_event_task().
- */
-static void
-sckm_process_msg(uint32_t cmd, uint64_t transid,
- uint32_t len, sckm_mbox_req_hdr_t *req_data,
- sckm_mbox_rep_hdr_t *rep_data)
-{
- int rv;
-
- mutex_enter(&sckm_umutex);
-
- switch (cmd) {
- case SCKM_MSG_SADB: {
- int sadb_msglen;
-
- sadb_msglen = len-sizeof (sckm_mbox_req_hdr_t);
- SCKM_DEBUG1(D_TASK, "received SCKM_MSG_SADB len=%d",
- sadb_msglen);
-
- /* sanity check request */
- if (len-sizeof (sckm_mbox_req_hdr_t) <= 0) {
- SCKM_DEBUG0(D_TASK, "bad SADB message, "
- "zero length");
- /*
- * SADB message is too short, send corresponding
- * error message to SC.
- */
- rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
- rep_data->status = SCKM_ERR_SADB_MSG;
-
- if ((rv = mboxsc_putmsg(KEY_KDSC, MBOXSC_MSG_REPLY,
- cmd, &transid, sizeof (sckm_mbox_rep_hdr_t),
- rep_data, MBOXSC_PUTMSG_DEF_TIMEOUT)) != 0) {
- SCKM_DEBUG1(D_TASK, "sckm_mbox_task: "
- "mboxsc_putmsg() failed (%d)\n", rv);
- }
- mutex_exit(&sckm_umutex);
- return;
- }
-
- /* initialize request for daemon */
- sckm_udata.transid = transid;
- sckm_udata.type = SCKM_IOCTL_REQ_SADB;
- sckm_udata.buf_len = len-sizeof (sckm_mbox_req_hdr_t);
- bcopy(req_data+1, sckm_udata.buf, sckm_udata.buf_len);
-
- break;
- }
- default:
- cmn_err(CE_WARN, "unknown cmd %x received from SC", cmd);
- /*
- * Received unknown command from SC. Send corresponding
- * error message to SC.
- */
- rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
- rep_data->status = SCKM_ERR_BAD_CMD;
-
- if ((rv = mboxsc_putmsg(KEY_KDSC, MBOXSC_MSG_REPLY,
- cmd, &transid, sizeof (sckm_mbox_rep_hdr_t),
- rep_data, MBOXSC_PUTMSG_DEF_TIMEOUT)) != 0) {
- SCKM_DEBUG1(D_TASK, "sckm_mbox_task: "
- "mboxsc_putmsg() failed (%d)\n", rv);
- }
- mutex_exit(&sckm_umutex);
- return;
- }
-
- /*
- * At this point, we know that the request is valid, so pass
- * the request to the daemon.
- */
- SCKM_DEBUG0(D_TASK, "waking up daemon");
- sckm_udata_req = B_TRUE;
- cv_signal(&sckm_udata_cv);
-
- /* wait for daemon to process request */
- if (cv_reltimedwait(&sckm_cons_cv, &sckm_umutex,
- drv_usectohz(SCKM_DAEMON_TIMEOUT), TR_CLOCK_TICK) == -1) {
- /*
- * Daemon did not process the data, report this
- * error to the SC.
- */
- SCKM_DEBUG0(D_TASK, "daemon timeout!!");
- rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
- rep_data->status = SCKM_ERR_DAEMON;
- } else {
- /* Daemon processed data, return status to SC */
- SCKM_DEBUG0(D_TASK, "daemon processed data");
- rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
- switch (sckm_udata_status.status) {
- case SCKM_IOCTL_STAT_SUCCESS:
- SCKM_DEBUG0(D_TASK, "daemon returned success");
- rep_data->status = SCKM_SUCCESS;
- break;
- case SCKM_IOCTL_STAT_ERR_PFKEY:
- SCKM_DEBUG1(D_TASK, "daemon returned PF_KEY "
- "error, errno=%d",
- sckm_udata_status.sadb_msg_errno);
- rep_data->status = SCKM_ERR_SADB_PFKEY;
- rep_data->sadb_msg_errno =
- sckm_udata_status.sadb_msg_errno;
- break;
- case SCKM_IOCTL_STAT_ERR_REQ:
- SCKM_DEBUG0(D_TASK, "daemon returned "
- "bad request");
- rep_data->status = SCKM_ERR_DAEMON;
- break;
- case SCKM_IOCTL_STAT_ERR_VERSION:
- SCKM_DEBUG0(D_TASK, "PF_KEY version not "
- "supported");
- rep_data->status = SCKM_ERR_SADB_VERSION;
- rep_data->sadb_msg_version =
- sckm_udata_status.sadb_msg_version;
- break;
- case SCKM_IOCTL_STAT_ERR_TIMEOUT:
- SCKM_DEBUG0(D_TASK, "no response received "
- "from key engine");
- rep_data->status = SCKM_ERR_SADB_TIMEOUT;
- break;
- case SCKM_IOCTL_STAT_ERR_OTHER:
- SCKM_DEBUG0(D_TASK, "daemon encountered "
- "an error");
- rep_data->status = SCKM_ERR_DAEMON;
- break;
- case SCKM_IOCTL_STAT_ERR_SADB_TYPE:
- SCKM_DEBUG0(D_TASK, "daemon returned bad "
- "SADB message type");
- rep_data->status = SCKM_ERR_SADB_BAD_TYPE;
- break;
- default:
- cmn_err(CE_WARN, "SCKM daemon returned "
- "invalid status %d", sckm_udata_status.status);
- rep_data->status = SCKM_ERR_DAEMON;
- }
- }
-
- /* send reply back to SC */
- if ((rv = mboxsc_putmsg(KEY_KDSC, MBOXSC_MSG_REPLY,
- cmd, &transid, sizeof (sckm_mbox_rep_hdr_t),
- rep_data, MBOXSC_PUTMSG_DEF_TIMEOUT)) != 0) {
- SCKM_DEBUG1(D_TASK, "failed sending reply to SC (%d)", rv);
- } else {
- SCKM_DEBUG0(D_TASK, "reply sent to SC");
- }
-
- sckm_udata_req = B_FALSE;
- mutex_exit(&sckm_umutex);
-}
diff --git a/usr/src/uts/sun4u/starcat/io/sckmdrv.conf b/usr/src/uts/sun4u/starcat/io/sckmdrv.conf
deleted file mode 100644
index c7e4f3bedc..0000000000
--- a/usr/src/uts/sun4u/starcat/io/sckmdrv.conf
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2000 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-name="sckmdrv" parent="pseudo" instance=0;
diff --git a/usr/src/uts/sun4u/starcat/io/scosmb.c b/usr/src/uts/sun4u/starcat/io/scosmb.c
deleted file mode 100644
index 597f3d91e4..0000000000
--- a/usr/src/uts/sun4u/starcat/io/scosmb.c
+++ /dev/null
@@ -1,1258 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * This file contains the Starcat Solaris Mailbox Client module. This module
- * handles mailbox messages from the SC to the OS (as opposed to messages sent
- * to specific drivers) and vice versa. Two task queues are created upon
- * startup; one handles reading and processing of all incoming messages, while
- * the other handles transmission of all outgoing messages.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sysmacros.h>
-#include <sys/sunddi.h>
-#include <sys/errno.h>
-#include <sys/cmn_err.h>
-#include <sys/condvar.h>
-#include <sys/mutex.h>
-#include <sys/disp.h>
-#include <sys/thread.h>
-#include <sys/debug.h>
-#include <sys/cpu_sgnblk_defs.h>
-#include <sys/machsystm.h>
-#include <sys/modctl.h>
-#include <sys/iosramio.h>
-#include <sys/mboxsc.h>
-#include <sys/promif.h>
-#include <sys/uadmin.h>
-#include <sys/cred.h>
-#include <sys/taskq.h>
-#include <sys/utsname.h>
-#include <sys/plat_ecc_unum.h>
-#include <sys/fm/protocol.h>
-#include <sys/fm/util.h>
-#include <sys/starcat.h>
-#include <sys/plat_ecc_dimm.h>
-#include <sys/plat_datapath.h>
-
-/* mailbox keys */
-#define SCDM_KEY 0x5343444d /* 'S', 'C', 'D', 'M' */
-#define DMSC_KEY 0x444d5343 /* 'D', 'M', 'S', 'C' */
-
-/* mailbox commands */
-#define SCDM_CMD ('S' << 8) /* generic SSP */
-#define SCDM_CMD_SUCCESS (SCDM_CMD | 0x1)
-#define SCDM_GOTO_OBP (SCDM_CMD | 0x2)
-#define SCDM_GOTO_PANIC (SCDM_CMD | 0x3)
-#define SCDM_ENVIRON (SCDM_CMD | 0x4) /* environmental intr */
-#define SCDM_SHUTDOWN (SCDM_CMD | 0x5) /* setkeyswitch STANDBY */
-#define SCDM_GET_NODENAME (SCDM_CMD | 0x6) /* get domain nodename */
-#define SCDM_LOG_ECC_ERROR (SCDM_CMD | 0x7) /* ECC error logging */
-#define SCDM_LOG_ECC_INDICTMENT (SCDM_CMD | 0x8) /* ECC indictment logging */
-#define SCDM_LOG_ECC (SCDM_CMD | 0x9) /* ECC info */
-#define SCDM_LOG_ECC_CAP_INIT (SCDM_CMD | 0xa) /* ECC Capability Init */
-#define SCDM_LOG_ECC_CAP_RESP (SCDM_CMD | 0xb) /* ECC Capability Response */
-#define SCDM_DIMM_SERIAL_ID (SCDM_CMD | 0xc) /* DIMM ser# req/resp */
-#define SCDM_DP_ERROR_MSG (SCDM_CMD | 0xd) /* datapath error */
-#define SCDM_DP_FAULT_MSG (SCDM_CMD | 0xe) /* datapath fault */
-
-/* general constants */
-#define GETMSG_TIMEOUT_MS 500
-#define PUTMSG_TIMEOUT_MS 6000
-#define MIN_INPUTQ_TASKS 2
-#define MAX_INPUTQ_TASKS 4
-#define MIN_OUTPUTQ_TASKS 2
-#define MAX_OUTPUTQ_TASKS 512
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-clock_t ecc_message_timeout_ms = PUTMSG_TIMEOUT_MS;
-
-/*
- * When a message needs to be sent to the SC, an scosmb_msgdata_t should be
- * populated with the data to be used for the message, and a call to
- * scosmb_process_output should be dispatched on the scosmb_output_taskq, with
- * the address of the scosmb_msgdata_t structure as its arg. The "length" and
- * "data" fields can be used if the message needs to include data beyond the
- * header fields (type, cmd, and transid) and that information must be recorded
- * when the message is placed on the taskq. If appropriate for the message type
- * (e.g. nodename info that should always be the most recent available), the
- * "data" field can be set to NULL and the additional data can be assembled
- * immediately prior to sending the message in scosmb_process_output().
- *
- * If log_error is set, any errors in delivering the message cause a
- * cmn_err() message to be issued. If it is zero, the error is expressed
- * only through return values.
- */
-typedef struct {
- uint32_t type;
- uint32_t cmd;
- uint64_t transid;
- uint32_t length;
- int log_error;
- void *data;
-} scosmb_msgdata_t;
-
-/*
- * Datapath error and fault messages arrive unsolicited. The message data
- * is contained in a plat_datapath_info_t structure.
- */
-typedef struct {
- uint8_t type; /* CDS, DX, EX, CP */
- uint8_t pad; /* for alignment */
- uint16_t cpuid; /* Safari ID of base CPU */
- uint32_t t_value; /* SERD timeout threshold (seconds) */
-} plat_datapath_info_t;
-
-/* externally visible routines */
-void scosmb_update_nodename(uint64_t transid);
-
-/* local routines */
-static void scosmb_inbox_handler();
-static void scosmb_process_input(void *unused);
-static int scosmb_process_output(scosmb_msgdata_t *arg);
-
-/* local variables */
-static uint8_t scosmb_mboxsc_failed = FALSE;
-static uint8_t scosmb_mboxsc_timedout = FALSE;
-static uint8_t scosmb_nodename_event_pending = FALSE;
-static char scosmb_hdr[] = "SCOSMB:";
-static kmutex_t scosmb_mutex;
-static taskq_t *scosmb_input_taskq = NULL;
-static taskq_t *scosmb_output_taskq = NULL;
-
-static char *dperrtype[] = {
- DP_ERROR_CDS,
- DP_ERROR_DX,
- DP_ERROR_EX,
- DP_ERROR_CP
-};
-
-/*
- * Structures from modctl.h used for loadable module support.
- * SCOSMB is a "miscellaneous" module.
- */
-extern struct mod_ops mod_miscops;
-
-static struct modlmisc modlmisc = {
- &mod_miscops,
- "Sun Fire 15000 OS Mbox Client v1.10",
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1,
- (void *)&modlmisc,
- NULL
-};
-
-
-/*
- * _init
- *
- * Loadable module support routine. Initializes mutex and condition variables
- * and starts thread.
- */
-int
-_init(void)
-{
- int error;
-
- /*
- * Initialize the mailboxes
- */
- if ((error = mboxsc_init(SCDM_KEY, MBOXSC_MBOX_IN,
- scosmb_inbox_handler)) != 0) {
- cmn_err(CE_WARN, "%s mboxsc_init failed (0x%x)\n", scosmb_hdr,
- error);
- return (error);
- }
-
- if ((error = mboxsc_init(DMSC_KEY, MBOXSC_MBOX_OUT, NULL)) != 0) {
- cmn_err(CE_WARN, "%s mboxsc_init failed (0x%x)\n", scosmb_hdr,
- error);
- (void) mboxsc_fini(SCDM_KEY);
- return (error);
- }
-
- /*
- * Initialize the global lock
- */
- mutex_init(&scosmb_mutex, NULL, MUTEX_DEFAULT, NULL);
-
- /*
- * Create the task queues used for processing input and output messages
- */
- scosmb_input_taskq = taskq_create("scosmb_input_taskq", 1,
- minclsyspri, MIN_INPUTQ_TASKS, MAX_INPUTQ_TASKS, TASKQ_PREPOPULATE);
- scosmb_output_taskq = taskq_create("scosmb_output_taskq", 1,
- minclsyspri, MIN_OUTPUTQ_TASKS, MAX_OUTPUTQ_TASKS,
- TASKQ_PREPOPULATE);
-
- /*
- * Attempt to install the module. If unsuccessful, uninitialize
- * everything.
- */
- error = mod_install(&modlinkage);
- if (error != 0) {
- taskq_destroy(scosmb_output_taskq);
- taskq_destroy(scosmb_input_taskq);
- mutex_destroy(&scosmb_mutex);
- (void) mboxsc_fini(DMSC_KEY);
- (void) mboxsc_fini(SCDM_KEY);
- }
-
- return (error);
-}
-
-/*
- * _fini
- *
- * Loadable module support routine. Since this routine shouldn't be unloaded (it
- * provides a critical service, and its symbols may be referenced externally),
- * EBUSY is returned to prevent unloading.
- */
-int
-_fini(void)
-{
- return (EBUSY);
-}
-
-/*
- * _info
- *
- * Loadable module support routine.
- */
-int
-_info(struct modinfo *modinfop)
-{
- int error = 0;
-
- error = mod_info(&modlinkage, modinfop);
- return (error);
-}
-
-/*
- * scosmb_inbox_handler() - mbox API event handler.
- *
- * This routine adds an entry to the scosmb_input_taskq that will cause the
- * scosmb_process_input() routine to be called to service the SCDM mailbox. The
- * possibility that taskq_dispatch may fail when given KM_NOSLEEP is safely
- * ignored because there can only be one message waiting in the mailbox at any
- * given time, so the current message will end up being handled by one of the
- * previously queued jobs (and a previous message presumably timed out before we
- * got around to reading it).
- */
-static void
-scosmb_inbox_handler()
-{
- (void) taskq_dispatch(scosmb_input_taskq, scosmb_process_input, NULL,
- KM_NOSLEEP);
-}
-
-/*
- * dp_get_cores()
- *
- * Checks cpu implementation for the input cpuid and returns
- * the number of cores.
- * If implementation cannot be determined, returns 1
- */
-static int
-dp_get_cores(uint16_t cpuid)
-{
- int exp, ii, impl = 0, nc, slot;
-
- exp = STARCAT_CPUID_TO_EXPANDER(cpuid);
- slot = STARCAT_CPUID_TO_BOARDSLOT(cpuid);
- if (slot == 1)
- nc = STARCAT_SLOT1_CPU_MAX;
- else
- nc = plat_max_cpu_units_per_board();
-
- /* find first with valid implementation */
- for (ii = 0; ii < nc; ii++)
- if (cpu[MAKE_CPUID(exp, slot, ii)]) {
- impl = cpunodes[MAKE_CPUID(exp, slot, ii)].
- implementation;
- break;
- }
-
- if (IS_JAGUAR(impl) || IS_PANTHER(impl))
- return (2);
- else
- return (1);
-
-}
-
-/*
- * dp_payload_add_cpus()
- *
- * From datapath mailbox message, determines the number of and safari IDs
- * for affected cpus, then adds this info to the datapath ereport.
- *
- * Input maxcat (if set) is a count of maxcat cpus actually present - it is
- * a count of cpuids, which takes into account multi-core architecture.
- */
-static int
-dp_payload_add_cpus(plat_datapath_info_t *dpmsg, nvlist_t *erp, int maxcat)
-{
- int jj = 0, numcpus = 0, nummaxcpus = 0;
- int count, exp, ii, num, ncores, ret, slot, port;
- uint16_t *dparray, cpuid;
- uint64_t *snarray;
-
- /* check for multiple core architectures */
- ncores = dp_get_cores(dpmsg->cpuid);
-
- /*
- * Determine the number of cpu cores impacted
- */
- switch (dpmsg->type) {
- case DP_CDS_TYPE:
- if (maxcat)
- nummaxcpus = ncores;
- else
- numcpus = ncores;
- break;
-
- case DP_DX_TYPE:
- if (maxcat)
- nummaxcpus = 2 * ncores;
- else
- numcpus = 2 * ncores;
- break;
-
- case DP_EX_TYPE:
- if (maxcat)
- nummaxcpus = STARCAT_SLOT1_CPU_MAX;
- else
- numcpus = plat_max_cpu_units_per_board();
- break;
-
- case DP_CP_TYPE:
- /*
- * SC-DE supplies the base cpuid affected, if
- * maxcat id was given, there's no slot 0 board
- * present.
- */
-
- if (!maxcat) {
- /* Slot 0 id was given - set numcpus */
- numcpus = plat_max_cpu_units_per_board();
- }
-
- /* there may/may not be maxcats. set a count anyway */
- nummaxcpus = STARCAT_SLOT1_CPU_MAX;
-
- break;
-
- default:
- ASSERT(0);
- return (-1);
- }
-
- /* Allocate space for cores */
- num = numcpus + nummaxcpus;
- dparray = kmem_zalloc(num * sizeof (uint16_t *), KM_SLEEP);
-
- /*
- * populate dparray with impacted cores (only those present)
- */
- exp = STARCAT_CPUID_TO_EXPANDER(dpmsg->cpuid);
- slot = STARCAT_CPUID_TO_BOARDSLOT(dpmsg->cpuid);
- port = STARCAT_CPUID_TO_LPORT(dpmsg->cpuid);
-
- mutex_enter(&cpu_lock);
-
- switch (dpmsg->type) {
- case DP_CDS_TYPE:
- /*
- * For a CDS error, it's the reporting cpuid
- * and it's other core (if present)
- */
- cpuid = dpmsg->cpuid & 0xFFFB; /* core 0 */
- if (cpu[cpuid])
- dparray[jj++] = cpuid;
-
- cpuid = dpmsg->cpuid | 0x4; /* core 1 */
- if (cpu[cpuid])
- dparray[jj++] = cpuid;
- break;
-
- case DP_DX_TYPE:
- /*
- * For a DX error, it's the reporting cpuid (all
- * cores), and the other CPU sharing the same
- * DX<-->DCDS interface (all cores)
- */
-
- /* reporting cpuid */
- cpuid = dpmsg->cpuid & 0xFFFB; /* core 0 */
-
- if (cpu[cpuid])
- dparray[jj++] = cpuid;
-
- cpuid = dpmsg->cpuid | 0x4; /* core 1 */
- if (cpu[cpuid])
- dparray[jj++] = cpuid;
-
- /* find partner cpuid */
- if (port == 0 || port == 2)
- cpuid = dpmsg->cpuid | 0x1;
- else
- cpuid = dpmsg->cpuid & 0xFFFE;
-
- /* add partner cpuid */
- cpuid &= 0xFFFB; /* core 0 */
- if (cpu[cpuid])
- dparray[jj++] = cpuid;
-
- cpuid |= 0x4; /* core 1 */
- if (cpu[cpuid])
- dparray[jj++] = cpuid;
- break;
-
- case DP_EX_TYPE:
- /*
- * For an EX error, it is all cpuids (all cores)
- * on the reporting board
- */
-
- if (slot == 1) /* maxcat */
- count = nummaxcpus;
- else
- count = numcpus;
-
- for (ii = 0; ii < count; ii++) {
- cpuid = MAKE_CPUID(exp, slot, ii);
- if (cpu[cpuid])
- dparray[jj++] = cpuid;
- }
- break;
-
- case DP_CP_TYPE:
- /*
- * For a CP error, it is all cpuids (all cores)
- * on both boards (SB & IO) in the boardset
- */
-
- /* Do slot 0 */
- for (ii = 0; ii < numcpus; ii++) {
- cpuid = MAKE_CPUID(exp, 0, ii);
- if (cpu[cpuid])
- dparray[jj++] = cpuid;
- }
-
- /* Do slot 1 */
- for (ii = 0; ii < nummaxcpus; ii++) {
- cpuid = MAKE_CPUID(exp, 1, ii);
- if (cpu[cpuid])
- dparray[jj++] = cpuid;
- }
- break;
- }
-
- mutex_exit(&cpu_lock);
-
- /*
- * The datapath message could not be associated with any
- * configured CPU.
- */
- if (!jj) {
- kmem_free(dparray, num * sizeof (uint16_t *));
- ret = nvlist_add_uint32(erp, DP_LIST_SIZE, jj);
- ASSERT(ret == 0);
- return (-1);
- }
-
- snarray = kmem_zalloc(jj * sizeof (uint64_t *), KM_SLEEP);
- for (ii = 0; ii < jj; ii++)
- snarray[ii] = cpunodes[dparray[ii]].device_id;
-
- ret = nvlist_add_uint32(erp, DP_LIST_SIZE, jj);
- ret |= nvlist_add_uint16_array(erp, DP_LIST, dparray, jj);
- ret |= nvlist_add_uint64_array(erp, SN_LIST, snarray, jj);
- ASSERT(ret == 0);
-
- kmem_free(dparray, num * sizeof (uint16_t *));
- kmem_free(snarray, jj * sizeof (uint64_t *));
-
- return (0);
-}
-
-/*
- * dp_trans_event() - datapath message handler.
- *
- * Process datapath error and fault messages received from the SC. Checks
- * for, and disregards, messages associated with I/O boards. Otherwise,
- * extracts message info to produce a datapath ereport.
- */
-static void
-dp_trans_event(plat_datapath_info_t *dpmsg, int msgtype)
-{
- nvlist_t *erp, *detector, *hcelem;
- char buf[FM_MAX_CLASS];
- int exp, slot, i, maxcat = 0;
-
- /* check for I/O board message */
- exp = STARCAT_CPUID_TO_EXPANDER(dpmsg->cpuid);
- slot = STARCAT_CPUID_TO_BOARDSLOT(dpmsg->cpuid);
-
- if (slot) {
- mutex_enter(&cpu_lock);
- for (i = 0; i < STARCAT_SLOT1_CPU_MAX; i++) {
- if (cpu[MAKE_CPUID(exp, slot, i)]) {
- /* maxcat cpu present */
- maxcat++;
- }
- }
- mutex_exit(&cpu_lock);
-
- /*
- * Ignore I/O board msg
- */
- if (maxcat == 0)
- return;
- }
-
- /* allocate space for ereport */
- erp = fm_nvlist_create(NULL);
-
- /*
- *
- * Member Name Data Type Comments
- * ----------- --------- -----------
- * version uint8 0
- * class string "asic"
- * ENA uint64 ENA Format 1
- * detector fmri aggregated ID data for SC-DE
- *
- * Datapath ereport subclasses and data payloads:
- * There will be two types of ereports (error and fault) which will be
- * identified by the "type" member.
- *
- * ereport.asic.starcat.cds.cds-dp
- * ereport.asic.starcat.dx.dx-dp
- * ereport.asic.starcat.sdi.sdi-dp
- * ereport.asic.starcat.cp.cp-dp
- *
- * Member Name Data Type Comments
- * ----------- --------- -----------
- * erptype uint16 derived from message type: error or
- * fault
- * t-value uint32 SC's datapath SERD timeout threshold
- * dp-list-sz uint8 number of dp-list array elements
- * dp-list array of uint16 Safari IDs of affected cpus
- * sn-list array of uint64 Serial numbers of affected cpus
- *
- */
-
- /* compose common ereport elements */
- detector = fm_nvlist_create(NULL);
-
- /*
- * Create legacy FMRI for the detector
- */
- switch (dpmsg->type) {
- case DP_CDS_TYPE:
- case DP_DX_TYPE:
- if (slot == 1)
- (void) snprintf(buf, FM_MAX_CLASS, "IO%d", exp);
- else
- (void) snprintf(buf, FM_MAX_CLASS, "SB%d", exp);
- break;
-
- case DP_EX_TYPE:
- (void) snprintf(buf, FM_MAX_CLASS, "EX%d", exp);
- break;
-
- case DP_CP_TYPE:
- (void) snprintf(buf, FM_MAX_CLASS, "CP");
- break;
-
- default:
- (void) snprintf(buf, FM_MAX_CLASS, "UNKNOWN");
- break;
- }
-
- hcelem = fm_nvlist_create(NULL);
-
- (void) nvlist_add_string(hcelem, FM_FMRI_HC_NAME, FM_FMRI_LEGACY_HC);
- (void) nvlist_add_string(hcelem, FM_FMRI_HC_ID, buf);
-
- (void) nvlist_add_uint8(detector, FM_VERSION, FM_HC_SCHEME_VERSION);
- (void) nvlist_add_string(detector, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC);
- (void) nvlist_add_string(detector, FM_FMRI_HC_ROOT, "");
- (void) nvlist_add_uint32(detector, FM_FMRI_HC_LIST_SZ, 1);
- (void) nvlist_add_nvlist_array(detector, FM_FMRI_HC_LIST, &hcelem, 1);
-
- /* build ereport class name */
- (void) snprintf(buf, FM_MAX_CLASS, "asic.starcat.%s.%s-%s",
- dperrtype[dpmsg->type], dperrtype[dpmsg->type],
- FM_ERROR_DATAPATH);
-
- fm_ereport_set(erp, FM_EREPORT_VERSION, buf,
- fm_ena_generate(0, FM_ENA_FMT1), detector, NULL);
-
- /* add payload elements */
- if (msgtype == SCDM_DP_ERROR_MSG) {
- fm_payload_set(erp,
- DP_EREPORT_TYPE, DATA_TYPE_UINT16, DP_ERROR, NULL);
- } else {
- fm_payload_set(erp,
- DP_EREPORT_TYPE, DATA_TYPE_UINT16, DP_FAULT, NULL);
- }
-
- fm_payload_set(erp, DP_TVALUE, DATA_TYPE_UINT32, dpmsg->t_value, NULL);
-
- if (dp_payload_add_cpus(dpmsg, erp, maxcat) == 0) {
- /* post ereport */
- fm_ereport_post(erp, EVCH_SLEEP);
- }
-
- /* free ereport memory */
- fm_nvlist_destroy(erp, FM_NVA_FREE);
- fm_nvlist_destroy(detector, FM_NVA_FREE);
-
-}
-
-/*
- * scosmb_process_input() - incoming message processing routine
- *
- * this routine attempts to read a message from the SCDM mailbox and, if
- * successful, processes the command. if an unrecoverable error is encountered,
- * the scosmb_task thread will be terminated.
- */
-/* ARGSUSED0 */
-static void
-scosmb_process_input(void *unused)
-{
- int error;
- scosmb_msgdata_t msg;
- proc_t *initpp;
- plat_capability_data_t *cap; /* capability msg contents ptr */
- int cap_size;
- int cap_ver_len;
- scosmb_msgdata_t *cap_msgdatap; /* capability msg response */
- int max_size;
-
- /*
- * Attempt to read a message from the SCDM mailbox.
- *
- * Setup a local buffer to read incoming messages from the SC.
- */
- cap_ver_len = strlen(utsname.release) + strlen(utsname.version) + 2;
- cap_size = sizeof (plat_capability_data_t) + cap_ver_len;
- max_size = MAX(cap_size, sizeof (plat_dimm_sid_board_data_t));
-
- msg.type = 0;
- msg.cmd = 0;
- msg.transid = 0;
- msg.length = max_size;
- msg.log_error = 0;
- msg.data = kmem_zalloc(max_size, KM_SLEEP);
-
- error = mboxsc_getmsg(SCDM_KEY, &msg.type, &msg.cmd, &msg.transid,
- &msg.length, msg.data, GETMSG_TIMEOUT_MS);
-
- /*
- * If EAGAIN or ETIMEDOUT was received, give up. The SC can just try
- * again if it was important. If any other non-zero error was
- * encountered, the mailbox service is broken, and there's nothing more
- * we can do.
- */
- mutex_enter(&scosmb_mutex);
- if ((error == EAGAIN) || (error == ETIMEDOUT)) {
- mutex_exit(&scosmb_mutex);
- return;
- } else if (error != 0) {
- /*
- * The mailbox service appears to be badly broken. If it was
- * working previously, generate a warning and set a flag to
- * avoid repeating the warning on subsequent failures.
- */
- if (!scosmb_mboxsc_failed) {
- scosmb_mboxsc_failed = TRUE;
- cmn_err(CE_WARN, "%s mboxsc error (0x%x)\n", scosmb_hdr,
- error);
- }
- mutex_exit(&scosmb_mutex);
- return;
- } else {
- /*
- * If the mailbox module failed previously, it appears to have
- * recovered, so we'll want to generate a warning if it fails
- * again.
- */
- scosmb_mboxsc_failed = FALSE;
- }
- mutex_exit(&scosmb_mutex);
-
- /*
- * A message was successfully received, so go ahead and process it.
- */
- switch (msg.cmd) {
-
- case SCDM_GOTO_OBP: /* jump to OBP */
- debug_enter("SC requested jump to OBP");
- break;
-
- case SCDM_GOTO_PANIC: /* Panic the domain */
- cmn_err(CE_PANIC, "%s SC requested PANIC\n", scosmb_hdr);
- break;
-
- case SCDM_SHUTDOWN: /* graceful shutdown */
- cmn_err(CE_WARN, "%s SC requested a shutdown ", scosmb_hdr);
- (void) kadmin(A_SHUTDOWN, AD_HALT, NULL, kcred);
- /*
- * In the event kadmin does not bring down the
- * domain, environmental shutdown is forced
- */
- /*FALLTHROUGH*/
- case SCDM_ENVIRON: /* environmental shutdown */
- /*
- * Send SIGPWR to init(1) it will run rc0,
- * which will uadmin to power down.
- */
- mutex_enter(&pidlock);
- initpp = prfind(P_INITPID);
- mutex_exit(&pidlock);
-
-
- /*
- * If we're still booting and init(1) isn't set up yet,
- * simply halt.
- */
- if (initpp == NULL) {
- extern void halt(char *);
- cmn_err(CE_WARN, "%s Environmental Interrupt",
- scosmb_hdr);
- power_down((char *)NULL);
- halt("Power off the System!\n");
- }
-
- /*
- * else, graceful shutdown with inittab and all
- * getting involved
- */
- psignal(initpp, SIGPWR);
- break;
-
- case SCDM_GET_NODENAME:
- scosmb_update_nodename(msg.transid);
- break;
-
- case SCDM_LOG_ECC_CAP_RESP:
- /*
- * The SC has responded to our initiator capability message
- * issued during the boot flow via scosmb_update_nodename().
- *
- * Parse the incoming data, and appropriately set SC
- * capabilities...
- */
- cap = (plat_capability_data_t *)msg.data;
- plat_ecc_capability_sc_set(cap->capd_capability);
- break;
-
- case SCDM_LOG_ECC_CAP_INIT:
- /*
- * The SC has initiated a capability messaging exchange with
- * the OS.
- *
- * We start out just as we do for an SC response capability
- * message, a parse of incoming data to appropriately set SC
- * described capabilities...
- */
- cap = (plat_capability_data_t *)msg.data;
- plat_ecc_capability_sc_set(cap->capd_capability);
- /*
- * The next step is setting up our Response to the SC.
- *
- * Allocate memory for message data, initialize appropriately,
- * and place a new job on the scosmb_output_taskq for
- * SCDM_LOG_ECC_CAP_RESP, our OS capability messaging response
- * to the SC initiated sequence detected here.
- */
- cap_msgdatap = kmem_zalloc(sizeof (scosmb_msgdata_t), KM_SLEEP);
- cap_msgdatap->type = MBOXSC_MSG_EVENT;
- cap_msgdatap->cmd = SCDM_LOG_ECC_CAP_RESP;
- cap_msgdatap->transid = 0;
- (void) taskq_dispatch(scosmb_output_taskq,
- (task_func_t *)scosmb_process_output, cap_msgdatap,
- KM_SLEEP);
- break;
-
- case SCDM_DP_ERROR_MSG:
- case SCDM_DP_FAULT_MSG:
- dp_trans_event(msg.data, msg.cmd);
- break;
-
- case SCDM_DIMM_SERIAL_ID:
- (void) plat_store_mem_sids(msg.data);
- break;
-
- default:
- cmn_err(CE_WARN, "%s invalid command (0x%x)\n", scosmb_hdr,
- msg.cmd);
- break;
- }
-
- /*
- * Free up buffer for incoming messasge data that we allocated earlier
- */
- kmem_free(msg.data, max_size);
-}
-
-/*
- * scosmb_process_output() - outgoing message processing routine
- *
- * This routine handles jobs that are queued on the scosmb_output_taskq, or
- * sent directly from scosmb_log_ecc_error. Each job corresponds to a single
- * mailbox message that needs to be sent to the SC via the DMSC mailbox. Some
- * processing of the message may be performed before it is sent to the SC,
- * depending on the value of the command field.
- */
-static int
-scosmb_process_output(scosmb_msgdata_t *msgdatap)
-{
- int error;
- int length;
- char nodename[_SYS_NMLN];
- void *free_data;
- int free_data_len;
- int cap_size;
- int cap_ver_len;
- plat_capability_data_t *cap = NULL;
-
- /*
- * This shouldn't ever happen, but it can't hurt to check anyway.
- */
- if (msgdatap == NULL) {
- return (EINVAL);
- }
-
- /*
- * If data was passed in, we'll need to free it before returning.
- */
- free_data = msgdatap->data;
- free_data_len = msgdatap->length;
-
- /*
- * Some commands may need additional processing prior to transmission.
- */
- switch (msgdatap->cmd) {
- /*
- * Since the SC is only interested in the most recent value of
- * utsname.nodename, we wait until now to collect that data. We
- * also use a global flag to prevent multiple event-type
- * nodename messages from being queued at the same time for the
- * same reason.
- */
- case SCDM_GET_NODENAME:
- mutex_enter(&scosmb_mutex);
- length = strlen(utsname.nodename);
- ASSERT(length < _SYS_NMLN);
- if (length == 0) {
- msgdatap->length = 0;
- msgdatap->data = NULL;
- } else {
- bcopy(utsname.nodename, nodename, length);
- nodename[length++] = '\0';
- msgdatap->data = nodename;
- msgdatap->length = length;
- }
- if (msgdatap->transid == 0) {
- scosmb_nodename_event_pending = FALSE;
- }
- mutex_exit(&scosmb_mutex);
- break;
-
- /*
- * SCDM_LOG_ECC_CAP_INIT
- * Initiator Capability message from OS to SC
- *
- * We construct and send an initiator capability message
- * every time we go through scosmb_update_nodename(), which
- * works out to getting an "initiator" capability message
- * sent from the OS to the SC during the OS boot flow.
- *
- * The SC also issues a request to scosmb_update_nodename()
- * during an SC reboot. Which results in an additional
- * capability message exchange during SC reboot scenarios.
- *
- * SCDM_LOG_ECC_CAP_RESP
- * Response Capability message from SC to OS
- *
- * In certain scenarios, the SC could initiate a capability
- * messaging exchange with the OS. Processing starts in
- * scosmb_process_input(), where we detect an incoming
- * initiator capability message from the SC. We finish
- * processing here, by sending a response capability message
- * back to the SC that reflects OS capabilities.
- */
- case SCDM_LOG_ECC_CAP_INIT:
- /*FALLTHROUGH*/
- case SCDM_LOG_ECC_CAP_RESP:
- mutex_enter(&scosmb_mutex);
-
- cap_ver_len = strlen(utsname.release) +
- strlen(utsname.version) + 2;
-
- cap_size = sizeof (plat_capability_data_t) +
- cap_ver_len;
-
- cap = kmem_zalloc(cap_size, KM_SLEEP);
-
- cap->capd_major_version = PLAT_ECC_CAP_VERSION_MAJOR;
- cap->capd_minor_version = PLAT_ECC_CAP_VERSION_MINOR;
- cap->capd_msg_type = PLAT_ECC_CAPABILITY_MESSAGE;
- cap->capd_msg_length = cap_size;
-
- cap->capd_capability =
- PLAT_ECC_CAPABILITY_DOMAIN_DEFAULT;
-
- /*
- * Build the capability solaris_version string:
- * utsname.release + " " + utsname.version
- */
- (void) snprintf(cap->capd_solaris_version,
- cap_ver_len, "%s %s", utsname.release,
- utsname.version);
-
- /*
- * The capability message is constructed, now plug it
- * into the starcat msgdatap:
- */
- msgdatap->data = (plat_capability_data_t *)cap;
- msgdatap->length = cap_size;
-
- /*
- * Finished with initiator/response capability
- * message set up.
- *
- * Note that after sending an "initiator" capability
- * message, we can expect a subsequent "response"
- * capability message from the SC, which we will
- * pick up and minimally handle later,
- * in scosmb_process_input().
- *
- * If we're sending a "response" capability message
- * to the SC, then we're done once the message is sent.
- */
-
- if (msgdatap->transid == 0) {
- scosmb_nodename_event_pending = FALSE;
- }
- mutex_exit(&scosmb_mutex);
- break;
-
- default:
- break;
- }
-
- /*
- * Attempt to send the message.
- */
- error = mboxsc_putmsg(DMSC_KEY, msgdatap->type, msgdatap->cmd,
- &msgdatap->transid, msgdatap->length, msgdatap->data,
- ecc_message_timeout_ms);
-
- /*
- * Free any allocated memory that was passed in.
- */
- if (free_data != NULL) {
- kmem_free(free_data, free_data_len);
- }
-
- if (cap != NULL) {
- kmem_free(cap, cap_size);
- }
-
- kmem_free(msgdatap, sizeof (scosmb_msgdata_t));
-
- /*
- * If EAGAIN or ETIMEDOUT was received, give up. The sender can try
- * again if it was important. If any other non-zero error was
- * encountered, the mailbox service is broken, and there's nothing more
- * we can do.
- */
- mutex_enter(&scosmb_mutex);
- if ((error == EAGAIN) || (error == ETIMEDOUT)) {
- if (msgdatap->log_error && !scosmb_mboxsc_timedout) {
- /*
- * Indictment mailbox messages use the return value to
- * indicate a problem in the mailbox. For Error
- * mailbox messages, we'll have to use a syslog message.
- */
- scosmb_mboxsc_timedout = TRUE;
- cmn_err(CE_NOTE, "!Solaris failed to send a message "
- "(0x%x/0x%x) to the System Controller. Error: %d",
- msgdatap->type, msgdatap->cmd, error);
- }
- } else if (error != 0) {
- /*
- * The mailbox service appears to be badly broken. If it was
- * working previously, generate a warning and set a flag to
- * avoid repeating the warning on subsequent failures.
- */
- if (msgdatap->log_error && !scosmb_mboxsc_failed) {
- scosmb_mboxsc_failed = TRUE;
- cmn_err(CE_NOTE, "!An internal error (%d) occurred "
- "while processing this message (0x%x/0x%x)",
- error, msgdatap->type, msgdatap->cmd);
- }
- } else {
- /*
- * If the mailbox module failed previously, it appears to have
- * recovered, so we'll want to generate a warning if it fails
- * again.
- */
- scosmb_mboxsc_failed = scosmb_mboxsc_timedout = FALSE;
- }
- mutex_exit(&scosmb_mutex);
- return (error);
-}
-
-/*
- * scosmb_update_nodename() - nodename update routine
- *
- * this routine, which may be invoked from outside of the scosmb module, will
- * cause the current nodename to be sent to the SC. The mailbox message sent to
- * the SC will use the indicated transaction ID, and will either be a reply
- * message if the ID is non-zero or an event message if it is 0.
- *
- * Capability messaging enhancements:
- * Every time we move through this code flow, we put an "initiator
- * capability message" on the message output taskq. This action will
- * get a capability message sent to the SC from the OS during boot
- * scenarios. A capability message exchange will also happen for
- * SC reboot scenarios, as the SC will initiate a nodename update
- * as a matter of course while coming back up.
- *
- * We'll also get an extraneous capability message sent
- * to the SC from time to time, but that won't hurt anything.
- */
-void
-scosmb_update_nodename(uint64_t transid)
-{
- scosmb_msgdata_t *msgdatap, *cap_msgdatap;
-
- /*
- * If we're generating an unsolicited nodename update (presumably having
- * been called from platmod:plat_nodename_set()), there's no need to add
- * a new job to the queue if there is already one on it that will be
- * sending the latest nodename data.
- */
- mutex_enter(&scosmb_mutex);
- if (transid == 0) {
- if (scosmb_nodename_event_pending) {
- mutex_exit(&scosmb_mutex);
- return;
- } else {
- scosmb_nodename_event_pending = TRUE;
- }
- }
- mutex_exit(&scosmb_mutex);
-
- /*
- * Allocate memory for the message data, initialize it, and place a new
- * job on the scosmb_output_taskq for SCDM_GET_NODENAME.
- */
- msgdatap = (scosmb_msgdata_t *)kmem_zalloc(sizeof (scosmb_msgdata_t),
- KM_SLEEP);
-
- msgdatap->type = (transid == 0) ? MBOXSC_MSG_EVENT : MBOXSC_MSG_REPLY;
- msgdatap->cmd = SCDM_GET_NODENAME;
- msgdatap->transid = transid;
- msgdatap->log_error = 1;
-
- (void) taskq_dispatch(scosmb_output_taskq,
- (task_func_t *)scosmb_process_output, msgdatap, KM_SLEEP);
-
- /*
- * Next, allocate memory, initialize, and place a new job on the
- * scosmb_output_taskq for SCDM_LOG_ECC_CAP_INIT. That's a
- * capability message, where we're the initiator.
- */
- cap_msgdatap = kmem_zalloc(sizeof (scosmb_msgdata_t), KM_SLEEP);
-
- cap_msgdatap->type = (transid == 0) ?
- MBOXSC_MSG_EVENT : MBOXSC_MSG_REPLY;
- cap_msgdatap->cmd = SCDM_LOG_ECC_CAP_INIT;
- cap_msgdatap->transid = transid;
- cap_msgdatap->log_error = 1;
-
- (void) taskq_dispatch(scosmb_output_taskq,
- (task_func_t *)scosmb_process_output, cap_msgdatap, KM_SLEEP);
-}
-
-/*
- * scosmb_log_ecc_error() - Record ECC error information to SC
- * For ECC error messages, send the messages through a taskq mechanism
- * to prevent impaired system performance during ECC floods. Indictment
- * messages have already passed through a taskq, so directly call the
- * output function.
- */
-int
-scosmb_log_ecc_error(plat_ecc_message_type_t msg_type, void *datap)
-{
- scosmb_msgdata_t *msg_header_ptr;
- uint32_t msg_cmd, msg_length;
- int sleep_flag, log_error;
- int do_queue; /* Set to 1 if taskq needed */
-
- /*
- * Set header type and length for message
- */
- switch (msg_type) {
- case PLAT_ECC_ERROR_MESSAGE:
- /*
- * We do not want to sleep in an error logging thread. So,
- * we set the NOSLEEP flag and go through a taskq before we
- * send the message.
- */
- msg_cmd = SCDM_LOG_ECC_ERROR;
- msg_length = sizeof (plat_ecc_error_data_t);
- sleep_flag = KM_NOSLEEP;
- log_error = 1;
- do_queue = 1;
- break;
- case PLAT_ECC_ERROR2_MESSAGE:
- msg_cmd = SCDM_LOG_ECC;
- msg_length = sizeof (plat_ecc_error2_data_t);
- sleep_flag = KM_NOSLEEP;
- log_error = 1;
- do_queue = 1;
- break;
- case PLAT_ECC_INDICTMENT_MESSAGE:
- /*
- * For indictment messages, we're allowed to sleep, and we
- * can directly call the output function, since we've already
- * gone through a taskq
- */
- msg_cmd = SCDM_LOG_ECC_INDICTMENT;
- msg_length = sizeof (plat_ecc_indictment_data_t);
- sleep_flag = KM_SLEEP;
- log_error = 0;
- do_queue = 0;
- break;
- case PLAT_ECC_INDICTMENT2_MESSAGE:
- /*
- * For indictment2 messages, we're allowed to sleep, and we
- * can directly call the output function, since we've already
- * gone through a taskq
- */
- msg_cmd = SCDM_LOG_ECC;
- msg_length = sizeof (plat_ecc_indictment2_data_t);
- sleep_flag = KM_SLEEP;
- log_error = 0;
- do_queue = 0;
- break;
-
- case PLAT_ECC_DIMM_SID_MESSAGE:
- /*
- * For DIMM sid request messages, we're allowed to sleep, and we
- * can directly call the output function, since we've already
- * gone through a taskq
- */
- msg_cmd = SCDM_DIMM_SERIAL_ID;
- msg_length = sizeof (plat_dimm_sid_request_data_t);
- sleep_flag = KM_SLEEP;
- log_error = 0;
- do_queue = 0;
- break;
-
- default:
- return (EINVAL);
- }
-
- /*
- * Allocate memory for the mailbox message header.
- */
- msg_header_ptr =
- (scosmb_msgdata_t *)kmem_zalloc(sizeof (scosmb_msgdata_t),
- sleep_flag);
-
- if (msg_header_ptr == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "failed to allocate space for scosmb "
- "message header.");
-#endif /* DEBUG */
- return (ENOMEM);
- }
-
- msg_header_ptr->type = MBOXSC_MSG_EVENT;
- msg_header_ptr->cmd = msg_cmd;
- msg_header_ptr->transid = 0;
- msg_header_ptr->log_error = log_error;
-
- /*
- * Allocate memory for the mailbox message payload.
- */
- msg_header_ptr->length = msg_length;
- msg_header_ptr->data = kmem_zalloc((size_t)msg_length, sleep_flag);
-
- if (msg_header_ptr->data == NULL) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "failed to allocate space for scosmb "
- "message data.");
-#endif /* DEBUG */
- kmem_free(msg_header_ptr, sizeof (scosmb_msgdata_t));
- return (ENOMEM);
- }
-
- bcopy(datap, msg_header_ptr->data, (size_t)msg_length);
-
- /*
- * Based on our earlier look at the message type, we either go through
- * a taskq or directly call the output function.
- */
- if (do_queue != 0) {
- /*
- * Place a new job on the scosmb_output_taskq.
- */
- if (taskq_dispatch(scosmb_output_taskq,
- (task_func_t *)scosmb_process_output,
- (void *)msg_header_ptr, TQ_NOSLEEP) == TASKQID_INVALID) {
-#ifdef DEBUG
- cmn_err(CE_WARN, "failed to dispatch a task to send "
- "ECC mailbox message.");
-#endif /* DEBUG */
- kmem_free(msg_header_ptr->data, msg_header_ptr->length);
- kmem_free(msg_header_ptr, sizeof (scosmb_msgdata_t));
- return (ENOMEM);
- }
- return (0);
- } else {
- return (scosmb_process_output(msg_header_ptr));
- }
-}
diff --git a/usr/src/uts/sun4u/starcat/iosram/Makefile b/usr/src/uts/sun4u/starcat/iosram/Makefile
deleted file mode 100644
index 7337535f08..0000000000
--- a/usr/src/uts/sun4u/starcat/iosram/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of the iosram driver module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = iosram
-OBJECTS = $(IOSRAM_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(IOSRAM_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_DRV_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-uninitialized
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Ndrv/axq
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/mboxsc/Makefile b/usr/src/uts/sun4u/starcat/mboxsc/Makefile
deleted file mode 100644
index b9ed9b0f21..0000000000
--- a/usr/src/uts/sun4u/starcat/mboxsc/Makefile
+++ /dev/null
@@ -1,92 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# This makefile drives the production of the mboxsc miscellaneous module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = mboxsc
-OBJECTS = $(MBOXSC_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(MBOXSC_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Ndrv/iosram
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/ml/drmach.il.cpp b/usr/src/uts/sun4u/starcat/ml/drmach.il.cpp
deleted file mode 100644
index b30e1f9aa2..0000000000
--- a/usr/src/uts/sun4u/starcat/ml/drmach.il.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This file is through cpp before being used as
- * an inline. It contains support routines used
- * only by DR for the copy-rename sequence.
- */
-
-#if defined(lint)
-#include <sys/types.h>
-#endif /* lint */
-
-#include <sys/sun4asi.h>
-#include <sys/privregs.h>
-#include <sys/cheetahregs.h>
-#include <sys/machparam.h>
-#include <sys/machthread.h>
-#include <sys/mmu.h>
-#include <sys/cheetahasm.h>
-
-#if defined(lint)
-
-/*ARGSUSED*/
-void
-bcopy32_il(uint64_t paddr1, uint64_t paddr2)
-{}
-
-void
-flush_dcache_il(void)
-{}
-
-void
-flush_icache_il(void)
-{}
-
-void
-flush_pcache_il(void)
-{}
-
-/*ARGSUSED*/
-void
-flush_ecache_il(uint64_t physaddr, uint_t size, uint_t linesz)
-{}
-
-#else /* lint */
-
- !
- ! bcopy32_il
- !
- ! input:
- ! %o0 source PA
- ! %o1 destination PA
- !
- ! returns:
- ! nothing
- !
- ! A simple copy routine that copies 32 bytes using physical
- ! addresses. Used by drmach_copy_rename() to copy permanent
- ! memory. Assumes domain is quiesced and addresses are
- ! aligned appropriately.
- !
- ! Derived from Starfire DR 2.6 version of bcopy32_il.
- !
- ! NOTE: The rdpr instruction executes as a noop. It has no
- ! runtime value or purpose. It exists here solely for its
- ! magical property that protects bcopy32_il from the
- ! actions of Sun Pro's code generator. The ldxa instructions
- ! used in this inline are not supported by the inline feature
- ! of the Sun Pro 5.0 product. See inline(1) for details.
- ! Without the rdpr, the code generator improperly rewrites
- ! the instructions and emits a misrepresentation of the logic.
- !
- .inline bcopy32_il, 0
- rdpr %pstate, %g0 ! See note.
- ldxa [%o0]ASI_MEM, %o2
- add %o0, 8, %o0
- ldxa [%o0]ASI_MEM, %o3
- add %o0, 8, %o0
- ldxa [%o0]ASI_MEM, %o4
- add %o0, 8, %o0
- ldxa [%o0]ASI_MEM, %o5
- stxa %o2, [%o1]ASI_MEM
- add %o1, 8, %o1
- stxa %o3, [%o1]ASI_MEM
- add %o1, 8, %o1
- stxa %o4, [%o1]ASI_MEM
- add %o1, 8, %o1
- stxa %o5, [%o1]ASI_MEM
- .end
-
- !
- ! flush_dcache_il
- !
- ! input:
- ! nothing
- !
- ! output:
- ! nothing
- !
- ! Flushes data cache. Used by drmach_copy_rename() after
- ! the rename step to ensure the data cache tags and mtags
- ! are properly synchronized. Assumes domain is quiesced.
- !
- .inline flush_dcache_il, 0
- set dcache_size, %o0
- ld [%o0], %o0
- set dcache_linesize, %o1
- ld [%o1], %o1
- CH_DCACHE_FLUSHALL(%o0, %o1, %o2)
- .end
-
- !
- ! flush_icache_il
- !
- ! input:
- ! nothing
- !
- ! output:
- ! nothing
- !
- ! Flushes instruction cache. Used by drmach_copy_rename()
- ! after the rename step to ensure the instruction cache tags
- ! and mtags are properly synchronized. Assumes domain is
- ! quiesced.
- !
- ! Panther has a larger Icache compared to Cheetahplus or Jaguar.
- !
- .inline flush_icache_il, 0
- GET_CPU_IMPL(%o0)
- cmp %o0, PANTHER_IMPL
- bne %xcc, 1f
- nop
- set PN_ICACHE_SIZE, %o0
- set PN_ICACHE_LSIZE, %o1
- ba 2f
- nop
-1:
- set CH_ICACHE_SIZE, %o0
- set CH_ICACHE_LSIZE, %o1
-2:
- CH_ICACHE_FLUSHALL(%o0, %o1, %o2, %o3)
- .end
-
- !
- ! flush_pcache_il
- !
- ! input:
- ! nothing
- !
- ! output:
- ! nothing
- !
- ! Flushes prefetch cache. Used by drmach_copy_rename() after
- ! the rename step to ensure the prefetch cache tags and mtags
- ! are properly synchronized. Assumes domain is quiesced.
- !
- .inline flush_pcache_il, 0
- PCACHE_FLUSHALL(%o1, %o2, %o3)
- .end
-
- !
- ! flush_ecache_il
- !
- ! input:
- ! %o0 PA of flush span
- ! %o1 size of this processor's E$
- ! %o2 line size of this processor's E$
- !
- ! output:
- ! nothing
- !
- ! Flushes external cache. Used by drmach_copy_rename() after
- ! the rename step to ensure the external cache tags and mtags
- ! are properly synchronized. Assumes domain is quiesced.
- !
- ! Panther needs to flush L2 cache before L3 cache.
- !
- .inline flush_ecache_il, 0
- PN_L2_FLUSHALL(%o3, %o4, %o5)
- ECACHE_FLUSHALL(%o1, %o2, %o0, %o3)
- .end
-
-#endif /* lint */
-
diff --git a/usr/src/uts/sun4u/starcat/ml/drmach_asm.s b/usr/src/uts/sun4u/starcat/ml/drmach_asm.s
deleted file mode 100644
index 226a14f7ad..0000000000
--- a/usr/src/uts/sun4u/starcat/ml/drmach_asm.s
+++ /dev/null
@@ -1,975 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * This file is through cpp before being used as
- * an inline. It contains support routines used
- * only by DR.
- */
-
-#if defined(lint)
-#include <sys/types.h>
-#else
-#include "assym.h"
-#endif /* lint */
-
-#include <sys/asm_linkage.h>
-#include <sys/clock.h>
-#include <sys/param.h>
-#include <sys/privregs.h>
-#include <sys/machasi.h>
-#include <sys/mmu.h>
-#include <sys/machthread.h>
-#include <sys/pte.h>
-#include <sys/stack.h>
-#include <sys/vis.h>
-#include <sys/cheetahregs.h>
-#include <sys/cmpregs.h>
-#include <sys/intreg.h>
-#include <sys/cheetahasm.h>
-
-#if defined(lint)
-
-/*ARGSUSED*/
-void
-drmach_shutdown_asm(uint64_t estack, uint64_t flushaddr,
- int size, int lsz, uint64_t physmem)
-{}
-
-/*ARGSUSED*/
-void
-drmach_rename(uint64_t *script, uint_t *err, uint64_t *id)
-{}
-
-void
-drmach_rename_end(void)
-{}
-
-/*ARGSUSED*/
-void
-drmach_rename_wait(uint64_t not_used_0, uint64_t not_used_1)
-{
-}
-
-/*ARGSUSED*/
-void
-drmach_rename_done(uint64_t not_used_0, uint64_t not_used_1)
-{
-}
-
-/*ARGSUSED*/
-void
-drmach_rename_abort(uint64_t not_used_0, uint64_t not_used_1)
-{
-}
-
-/*ARGSUSED*/
-uint64_t
-lddsafconfig(void)
-{
- return (0x0ull);
-}
-
-/* ARGSUSED */
-uint32_t
-drmach_bc_bzero(void *addr, size_t size)
-{
- return (0x0);
-}
-
-#else /* lint */
-
-#define BUS_SYNC(reg1, reg2) \
-1: ;\
- ldx [reg1], reg2 ;\
- brz,pn reg2, 2f ;\
- add reg1, 8, reg1 ;\
- ldxa [reg2]ASI_MEM, %g0 ;\
- ba,a 1b ;\
- nop ;\
-2:
-
-#define LOAD_MB(cpuid, mb_data, reg1) \
- set drmach_xt_mb, reg1 ;\
- ldx [reg1], reg1 ;\
- add reg1, cpuid, reg1 ;\
- ldub [reg1], mb_data ;\
- stub %g0, [reg1]
-
-#define LPA_MASK 0x7ff8
-
-#define SET_LPA(cmd, reg1, reg2) \
- btst 0x80, cmd ;\
- bz 2f ;\
- nop ;\
- btst 0x40, cmd ;\
- bnz,a 1f ;\
- mov %g0, cmd ;\
- and cmd, 0x1f, cmd ;\
- sllx cmd, 3, reg1 ;\
- add cmd, 1, cmd ;\
- sllx cmd, 9, cmd ;\
- or cmd, reg1, cmd ;\
-1: ;\
- set LPA_MASK, reg2 ;\
- ldxa [%g0]ASI_SAFARI_CONFIG, reg1 ;\
- and cmd, reg2, cmd ;\
- andn reg1, reg2, reg1 ;\
- or reg1, cmd, reg1 ;\
- stxa reg1, [%g0]ASI_SAFARI_CONFIG ;\
- membar #Sync ;\
-2: ;\
-
-#define SET_NULL_LPA(reg1, reg2) \
- set LPA_MASK, reg2 ;\
- ldxa [%g0]ASI_SAFARI_CONFIG, reg1 ;\
- andn reg1, reg2, reg1 ;\
- stxa reg1, [%g0]ASI_SAFARI_CONFIG ;\
- membar #Sync ;\
-
- ! ATOMIC_ADD_LONG
- ! This code is run at TL > 0, being exec'd via a cross trap.
- ! While running at trap level > 0, all memory accesses are
- ! performed using NUCLEUS context, which is always 0.
- ! Since the cross trap handler does not force PRIMARY context
- ! to be zero, the following casxa instruction must specify
- ! NUCLEUS ASI.
- ! This ASI must be specified explicitly (via casxa), rather
- ! than using casx. This is because of the fact that the
- ! default casx specifies ASI_PRIMARY, which if non-zero, can
- ! prevent the cpu from translating the address, leading to panic
- ! on bad trap following repetitive dtlb misses. This behavior
- ! was encountered on MCPUs when using casx instruction.
-#define ATOMIC_ADD_LONG(label, simm, reg1, reg2, reg3) \
- set label, reg1 ;\
- ldx [reg1], reg2 ;\
-1: ;\
- add reg2, simm, reg3 ;\
- casxa [reg1]ASI_N, reg2, reg3 ;\
- cmp reg2, reg3 ;\
- bne,a,pn %xcc, 1b ;\
- ldx [reg1], reg2
-
-#define HERE(reg1, simm, reg2) \
- rdpr %tick, reg2 ;\
- stx reg2, [reg1 + simm]
-
- !
- ! Returns processor icache size and linesize in reg1 and
- ! reg2, respectively.
- !
- ! Panther has a larger icache compared to Cheetahplus and
- ! Jaguar.
- !
-#define GET_ICACHE_PARAMS(reg1, reg2) \
- GET_CPU_IMPL(reg1) ;\
- cmp reg1, PANTHER_IMPL ;\
- bne %xcc, 1f ;\
- nop ;\
- set PN_ICACHE_SIZE, reg1 ;\
- set PN_ICACHE_LSIZE, reg2 ;\
- ba 2f ;\
- nop ;\
-1: ;\
- set CH_ICACHE_SIZE, reg1 ;\
- set CH_ICACHE_LSIZE, reg2 ;\
-2:
-
-#define DRMACH_MCU_IDLE_READS 3
-
- ! Macro to check if a Panther MC is idle. The EMU Activity
- ! Status register is first read to clear the MCU status bit.
- ! The MCU status is then checked DRMACH_MCU_IDLE_READS times
- ! to verify the MCU is indeed idle. A single non-idle status
- ! will fail the idle check. This could be made more lenient
- ! by adding a retry loop.
- ! addr: Panther EMU Activity Status register read address.
- ! Assumed to be 0x18 for local ASI access or else
- ! FIREPLANE_ADDRESS_REG + 0x400050 for PIO access.
- ! 0 is returned in this register if MCU is idle and
- ! queues are empty. Otherwise, -1 is returned in this
- ! register.
- ! asi: Immediate asi value. Assumed to be ASI_SAFARI_CONFIG
- ! for local ASI or ASI_IO for PIO access.
- ! scr1: Scratch
- ! scr2: Scratch
- !
-#define CHECK_MCU_IDLE(addr, asi, scr1, scr2) \
- ldxa [addr]asi, %g0 ;\
- ba 1f ;\
- clr scr2 ;\
-0: ;\
- btst MCU_ACT_STATUS, scr1 ;\
- bne,a 2f ;\
- sub %g0, 1, addr ;\
- inc scr2 ;\
-1: ;\
- cmp scr2, DRMACH_MCU_IDLE_READS ;\
- ble,a 0b ;\
- ldxa [addr]asi, scr1 ;\
- clr addr ;\
-2:
-
- ! drmach_shutdown_asm
- !
- ! inputs:
- ! %o0 = stack pointer
- ! %o1 = ecache flush address (ignored if cheetah+ processor)
- ! %o2 = ecache size
- ! %o3 = ecache line size
- ! %o4 = phys addr of byte to clear when finished
- !
- ! output:
- ! Stores a zero at [%o4]ASI_MEM when the processor
- ! is ready to be removed from domain coherency.
- !
- ENTRY_NP(drmach_shutdown_asm)
- membar #LoadStore ! parsley.
-
- ! Calculate pointer to data area. Determine size of
- ! drmach_shutdown_asm, add to base address and align
- ! to next 16 byte boundary. Leave result in %g6.
- set drmach_shutdown_asm_end, %g6
- set drmach_shutdown_asm, %g1
- set drmach_cpu_sram_va, %g2
- ldx [%g2], %g2
- sub %g6, %g1, %g6
- add %g6, %g2, %g6
- add %g6, 15, %g6
- andn %g6, 15, %g6
-
- ! Save parameters
- stx %o0, [%g6 + 0] ! save stack pointer
- stx %o1, [%g6 + 24] ! save E$ flush PA
- st %o2, [%g6 + 32] ! save E$ size
- st %o3, [%g6 + 36] ! save E$ linesize
- stx %o4, [%g6 + 40] ! save phys addr of signal byte
-
- set dcache_size, %g1
- ld [%g1], %g1
- st %g1, [%g6 + 8] ! save dcache_size
- set dcache_linesize, %g1
- ld [%g1], %g1
- st %g1, [%g6 + 12] ! save dcache_linesize
-
- GET_ICACHE_PARAMS(%g1, %g2)
- st %g1, [%g6 + 16] ! save icache_size
- st %g2, [%g6 + 20] ! save icache_linesize
-
- ! Flushes all active windows except the current one.
- ! Can cause spill traps to occur.
- flushw
-
- ! Make sure all asynchronous processing is complete.
- ! Note: has no implications on pending bus transactions.
- membar #Sync
-
- ! Move stack. Algorithm copied from t0stacktop setup of
- ! %sp in sun4u/ml/locore.s
- ! Replaces SWITCH_STACK() macro used in Starfire DR.
- ldx [%g6 + 0], %g1
- sub %g1, SA(KFPUSIZE+GSR_SIZE), %g2
- and %g2, 0x3f, %g3
- sub %g2, %g3, %o2
- sub %o2, SA(MPCBSIZE) + STACK_BIAS, %sp
- stx %sp, [%g6 + 48] ! for debug
-
- HERE(%g6, 128, %g1) ! initialization complete (for debug)
-
- ! Panther needs to flush the L2 cache before the L3
- ! cache is flushed by the ecache flushall macro.
- PN_L2_FLUSHALL(%g1, %g2, %g3)
-
- ! Flush E$. The purpose of this flush is to rid the E$ of
- ! lines in states O or Os. Implicitly flushes W$.
- ldx [%g6 + 24], %g1 ! *ecache_flushaddr
- ld [%g6 + 32], %g2 ! ecache_size
- ld [%g6 + 36], %g3 ! ecache_linesize
- ECACHE_FLUSHALL(%g2, %g3, %g1, %g4)
-
- ! Since the bus sync list read below does not guarantee
- ! transaction completion on Panther domains, as an
- ! optimization Panther skips the read and subsequent
- ! E$ flush.
- GET_CPU_IMPL(%g1)
- cmp %g1, PANTHER_IMPL
- be %xcc, drmach_shutdown_ecache_flushed
- nop
-
- !
- ! Ensure all outstanding writebacks have retired. Following this
- ! sync, all writes must be strictly managed.
- !
- set drmach_bus_sync_list, %g1
- BUS_SYNC(%g1, %g2)
-
- ! Flush E$ again to victimize references to drmach_bus_sync_list.
- ldx [%g6 + 24], %g1 ! *ecache_flushaddr
- ld [%g6 + 32], %g2 ! ecache_size
- ld [%g6 + 36], %g3 ! ecache_linesize
- ECACHE_FLUSHALL(%g2, %g3, %g1, %g4)
-
-drmach_shutdown_ecache_flushed:
-
- ld [%g6 + 8], %g1 ! flush dcache
- ld [%g6 + 12], %g2
- CH_DCACHE_FLUSHALL(%g1, %g2, %g3)
-
- ld [%g6 + 16], %g1 ! flush icache
- ld [%g6 + 20], %g2
- CH_ICACHE_FLUSHALL(%g1, %g2, %g3, %g4)
-
- PCACHE_FLUSHALL(%g1, %g2, %g3) ! flush pcache (no parameters)
-
- !
- ! Flush all unlocked dtlb and itlb entries.
- ! Replaces TLB_FLUSH_UNLOCKED macro used in Starfire DR.
- !
- sethi %hi(FLUSH_ADDR), %g1
- set DEMAP_ALL_TYPE, %g2
- stxa %g0, [%g2]ASI_DTLB_DEMAP
- stxa %g0, [%g2]ASI_ITLB_DEMAP
- flush %g1
-
- !
- ! Zero LPA by clearing CBASE and CBND. Following
- ! this, all transactions to cachable address space
- ! will be of the remote flavor.
- !
- SET_NULL_LPA(%g1, %g2)
-
- HERE(%g6, 136, %g1) ! preparation complete (for debug)
-
- !
- ! Clear byte to signal finished.
- ! NOTE: This store will allocate in the E$. It is
- ! vitally important that this line is demoted to
- ! state I before removing this processor from the
- ! coherency. The demotion is ensured by a synchronous
- ! "steal back" that takes place in drmach_cpu_poweroff.
- ldx [%g6 + 40], %g1
- stba %g0, [%g1]ASI_MEM
-5:
- HERE(%g6, 144, %g1) ! spin indicator (for debug)
- ba 5b
- nop
-
- .asciz "drmach_shutdown_asm" ! for debug
- .align 4
- .global drmach_shutdown_asm_end
-drmach_shutdown_asm_end:
- SET_SIZE(drmach_shutdown_asm)
-
-
- ! lddsafconfig
- !
- ! input:
- ! nothing
- !
- ! output:
- ! %o0 content of this processor's SCR
- !
- ! Returns current value of this processor's Safari
- ! Configuration Register.
- !
- ENTRY(lddsafconfig)
- retl
- ldxa [%g0]ASI_SAFARI_CONFIG, %o0
- SET_SIZE(lddsafconfig)
-
- ! drmach_rename
- !
- ! input:
- ! %o0 pointer to register address/value compound list
- ! %o1 address for setting error code if rename did not
- ! complete. Unmodified if no error.
- ! %o2 address for returning opaque memory controller id
- ! in case of error. Unmodified if no error.
- ! Global drmach_xt_mb[cpuid] is expected to be the new LPA.
- !
- ! output:
- ! [%o1] = 1 if failed to idle memory controller, otherwise unmodified.
- ! [%o2] = id of failed memory controller, otherwise unmodified.
- !
- ! Perform HW register reprogramming. This is the "rename" step for
- ! the copy-rename process. drmach_rename is copied to a cpu's sram
- ! followed by register address/value pairs -- the text and data are
- ! sourced from the sram while drmach_rename is executed.
- !
- ! The parameter is assumed to point to a concatenation of six
- ! zero-terminated lists located in non-cachable storage. The assumed
- ! format (and purpose) of each list is as follows:
- !
- ! 1) a copy of drmach_bus_sync_list. A list of PA for each
- ! active memory bank in the domain. Used to infer the
- ! the completion of all pending coherent transactions
- ! initiated by this processor. Assumes MC work queue
- ! does not implement read bypass. This is true of Cheetah,
- ! Cheetah+, and Jaguar processors. Panther does support
- ! read bypass, so for Panther MCs with read-bypass-write
- ! enabled, the read is issued but it does not guarantee
- ! completion of outstanding writes in the MC queue.
- ! 2) address/id pair for the local Panther EMU Activity Status
- ! Register of this processor. The register address is assumed
- ! to be a VA which is polled via ASI_SAFARI_CONFIG until the
- ! MC queues are empty. The id is an opaque identifier which
- ! must be returned along with an error code if the MCU status
- ! does not go idle. See the parameter description above.
- ! This section will be empty if this processor is not a Panther.
- ! Both the address and id are assumed to be 64 bit values.
- ! 3) address/id pairs for non-local Panther EMU Activity Status
- ! Registers on other source and target processors. The register
- ! address is assumed to be a PIO address which is polled via
- ! ASI_IO to drain/idle the MCs on other Panther procs. The
- ! id is an opaque identifier which must be returned along with
- ! an error code if a MC fails to go idle. This section will
- ! empty if there are no non-local Panther processors on the
- ! source and target expanders. Both the address and id are
- ! assumed to be 64 bit values.
- ! 4) address/value pairs for the Memory Address Decoder
- ! register of this processor. The register address is
- ! assumed to be a VA within ASM_MC_DECODE space. The
- ! address and value elements are assumed to 64 bit values.
- ! 5) address/value pairs for any 64 bit register accessible
- ! via ASI_IO. The address and value fields are assumed to
- ! be 64 bit values.
- ! This list is typically used for reprogramming the Memory
- ! Address Decoder Register of other cpus and for reprogram-
- ! ming the Safari Configuration Register of I/O controllers.
- ! 6) address/value pairs for any 32 bit register accessible
- ! via ASI_IO. The address element is assumed to be a 64 bit
- ! value. The value element is assumed to be a 64 bit word
- ! containing a 32 bit value in the lower half.
- ! This list typically contains address/value pairs for
- ! AXQ CASM tables.
- !
- ENTRY_NP(drmach_rename)
-
- mov %o1, %o4 ! save error code address
- mov %o2, %o5 ! save error id address
-
- BUS_SYNC(%o0, %o1) ! run section 1
-
- SET_NULL_LPA(%o1, %o2) ! prep for cachable transactions
- ! after rename completes.
- ! e.g.: the load_mb that occurs below
-3:
- ldx [%o0], %o1 ! run section 2
- brz,a,pn %o1, 4f
- add %o0, 8, %o0 ! skip section 2 terminator
- CHECK_MCU_IDLE(%o1, ASI_SAFARI_CONFIG, %o2, %o3)
- cmp %o1, 0 ! idled?
- be,a 3b ! ok, advance
- add %o0, 16, %o0
- mov 1, %o1 ! not idle, bailout
- stw %o1, [%o4] ! set MC idle error code
- ldx [%o0 + 8], %o1
- stx %o1, [%o5] ! set MC idle error id
- retl
- nop
-4:
- ldx [%o0], %o1 ! run section 3
- brz,a,pn %o1, 5f
- add %o0, 8, %o0 ! skip section 3 terminator
- CHECK_MCU_IDLE(%o1, ASI_IO, %o2, %o3)
- cmp %o1, 0 ! idled?
- be,a 4b ! ok, advance
- add %o0, 16, %o0
- mov 1, %o1 ! not idle, bailout
- stw %o1, [%o4] ! set MC idle error code
- ldx [%o0 + 8], %o1
- stx %o1, [%o5] ! set MC idle error id
- retl
- nop
-5:
- ldx [%o0], %o1 ! run section 4
- brz,a,pn %o1, 6f
- add %o0, 8, %o0 ! skip section 4 terminator
- ldx [%o0 + 8], %o2
- stxa %o2, [%o1]ASI_MC_DECODE
- membar #Sync
- ldxa [%o1]ASI_MC_DECODE, %g0 ! read back to insure written
- b 5b
- add %o0, 16, %o0
-6:
- ldx [%o0], %o1 ! run section 5
- brz,a,pn %o1, 7f
- add %o0, 8, %o0 ! skip section 5 terminator
- ldx [%o0 + 8], %o2
- stxa %o2, [%o1]ASI_IO
- ldxa [%o1]ASI_IO, %g0 ! read back to insure written
- b 6b
- add %o0, 16, %o0
-7:
- ldx [%o0], %o1 ! run section 6
- brz,a,pn %o1, 8f
- nop
- ldx [%o0 + 8], %o2
- stwa %o2, [%o1]ASI_IO
- lduwa [%o1]ASI_IO, %g0 ! read back to insure written
- b 7b
- add %o0, 16, %o0
-8:
- CPU_INDEX(%o0, %o1)
- LOAD_MB(%o0, %o1, %o2)
- SET_LPA(%o1, %o0, %o2)
-
- retl
- nop
-
- .asciz "drmach_rename" ! for debug
- .align 4
- SET_SIZE(drmach_rename)
-
- .global drmach_rename_end
-drmach_rename_end:
-
-
- ! drmach_rename_wait
- !
- ! input:
- ! nothing
- !
- ! output:
- ! nothing
- !
- ! drmach_rename_wait is a cross-trap function used to move a
- ! cpu's execution out of coherent space while a copy-rename
- ! operation is in progress.
- !
- ! In each CPU SRAM exists an area (16KB on Cheetah+ boards,
- ! 32KB on Jaguar/Panther boards) reserved for DR. This area is
- ! logically divided by DR into 8KB pages, one page per CPU (or
- ! core) in a port pair. (Two Safari ports share HW resources on
- ! a CPU/MEM board. These are referred to as a port pair.)
- !
- ! This routine begins by mapping the appropriate SRAM page,
- ! transferring the machine code (between the labels
- ! drmach_rename_wait_asm and drmach_rename_wait_asm_end), then
- ! jumping to SRAM. After returning from SRAM, the page is
- ! demapped before the cross-call is exited (sic).
- !
- ! The machine code flushes all caches, waits for a special
- ! interrupt vector, then updates the processor's LPA and
- ! resynchronizes caches with the new home memory.
- !
- ! The special interrupt vector is assumed to be a cross-call to
- ! drmach_rename_done sent by the master processor upon completing
- ! the copy-rename operation. The interrupt is received and discarded;
- ! The cross-call to drmach_rename_done is never executed. Instead
- ! the Interrupt Receive Status Register is employed, temporarily,
- ! as a semaphore. This avoids unwanted bus traffic during the critical
- ! rename operation.
- !
- ENTRY_NP(drmach_rename_wait)
-
- CPU_INDEX(%g5, %g1) ! put cpuid in %g5
-
- !
- ! sfmmu_dtlb_ld(drmach_cpu_sram_va,
- ! KCONTEXT, drmach_cpu_sram_tte[cpuid]);
- ! sfmmu_itlb_ld(drmach_cpu_sram_va,
- ! KCONTEXT, drmach_cpu_sram_tte[cpuid]);
- !
- set drmach_cpu_sram_tte, %g1
- sllx %g5, 3, %g2
- ldx [%g1 + %g2], %g3
- set drmach_cpu_sram_va, %g1
- ldx [%g1], %g1
- or %g1, KCONTEXT, %g2 ! preserve %g1
- set MMU_TAG_ACCESS, %g4
- set cpu_impl_dual_pgsz, %g6
- ld [%g6], %g6
- brz %g6, 1f
- nop
-
- sethi %hi(ksfmmup), %g6
- ldx [%g6 + %lo(ksfmmup)], %g6
- ldub [%g6 + SFMMU_CEXT], %g6
- sll %g6, TAGACCEXT_SHIFT, %g6
-
- set MMU_TAG_ACCESS_EXT, %g7
- stxa %g6, [%g7]ASI_DMMU
-1:
- stxa %g2, [%g4]ASI_DMMU
- stxa %g3, [%g0]ASI_DTLB_IN
- membar #Sync
- sethi %hi(FLUSH_ADDR), %g6
- stxa %g2, [%g4]ASI_IMMU
- stxa %g3, [%g0]ASI_ITLB_IN
- flush %g6
-
- !
- ! copy drmach_rename_wait_asm block to SRAM. Preserve entry
- ! point in %g1. After the code has been copied, align %g6
- ! (the destination pointer) to the next highest 16 byte
- ! boundary. This will define the start of the data area.
- !
- mov %g1, %g6
- set drmach_rename_wait_asm, %g2
- set drmach_rename_wait_asm_end, %g3
-0:
- lduw [%g2], %g4 ! do copy
- stw %g4, [%g6]
- add %g2, 4, %g2
- cmp %g2, %g3
- bne 0b
- add %g6, 4, %g6
-
- add %g6, 15, %g6 ! locate data area on next 16 byte
- andn %g6, 15, %g6 ! boundary following text
- ! WARNING: no bounds checking
-
- jmpl %g1, %g7 ! jump to code in cpu sram
- nop
-
- set drmach_cpu_sram_va, %g1 ! vtab_flushpage_tl1(drmach_cpu_sram_va,
- ldx [%g1], %g1 ! KCONTEXT);
- set KCONTEXT, %g2
- set MMU_PCONTEXT, %g4
- or %g1, DEMAP_PRIMARY | DEMAP_PAGE_TYPE, %g1
- ldxa [%g4]ASI_DMMU, %g5 /* rd old ctxnum */
- stxa %g2, [%g4]ASI_DMMU /* wr new ctxum */
- stxa %g0, [%g1]ASI_DTLB_DEMAP
- stxa %g0, [%g1]ASI_ITLB_DEMAP
- stxa %g5, [%g4]ASI_DMMU /* restore old ctxnum */
-
- retry
-
-drmach_rename_wait_asm:
- ! the following code is copied to a cpu's sram and executed
- ! from there.
- ! Input:
- ! %g5 is cpuid
- ! %g6 is data area (follows text)
- ! %g7 is link address back to caller
- !
- st %g5, [%g6 + 4] ! save cpuid (for debug)
-
- set dcache_size, %g1
- ld [%g1], %g1
- st %g1, [%g6 + 8] ! save dcache_size
- set dcache_linesize, %g1
- ld [%g1], %g1
- st %g1, [%g6 + 12] ! save dcache_linesize
-
- GET_ICACHE_PARAMS(%g1, %g2)
- st %g1, [%g6 + 16] ! save icache_size
- st %g2, [%g6 + 20] ! save icache_linesize
-
- set drmach_iocage_paddr, %g1
- ldx [%g1], %g1
- stx %g1, [%g6 + 24] ! save *ecache_flushadr
-
- mulx %g5, CPU_NODE_SIZE, %g1 ! %g4 = &cpunodes[cpuid]
- set cpunodes, %g4
- add %g4, %g1, %g4
- ld [%g4 + ECACHE_SIZE], %g1
- st %g1, [%g6 + 32] ! save ecache_size
- ld [%g4 + ECACHE_LINESIZE], %g1
- st %g1, [%g6 + 36] ! save ecache_linesize
-
- LOAD_MB(%g5, %g1, %g2) ! save mailbox data
- stb %g1, [%g6 + 40]
-
- membar #Sync ! Complete any pending processing.
-
- ! Flush E$. The purpose of this flush is to rid the E$ of
- ! lines in states O or Os. Implicitly flushes W$.
- ! NOTE: Reading the bus sync list and r/w ops on drmach_xt_ready
- ! will disturb the E$. The lines of the bus sync list will be
- ! in state S. The line containing drmach_xt_ready will be in
- ! state O. Before proceeding with the copy-rename, the master
- ! processor will "steal back" the drmach_xt_ready (sic) line.
- ! This will demote the state of the line in E$ to I.
- ! However, the lines containing the bus sync list must be
- ! victimized before returning to the OS. This is vital because
- ! following copy-rename the corresponding lines in the new home
- ! memory will be in state gM. The resulting S,gM state pair is
- ! invalid and does represent a loss of coherency. Flushing the
- ! E$ after the bus sync list is read will be sufficient to
- ! avoid the invalid condition.
- !
- ! For Panther, there is redundancy as both cores flush the shared
- ! L2 and L3 caches. As an optimization, only one core could do the
- ! flush of the shared caches, however care must be taken that the
- ! sibling core does not install owned lines once the flush begins.
- PN_L2_FLUSHALL(%g1, %g2, %g3)
- ldx [%g6 + 24], %g1 ! *ecache_flushaddr
- ld [%g6 + 32], %g2 ! ecache_size
- ld [%g6 + 36], %g3 ! ecache_linesize
- ECACHE_FLUSHALL(%g2, %g3, %g1, %g4)
-
- ! Make sure all outstanding transactions for this processor
- ! have retired. See E$ note above.
- set drmach_bus_sync_list, %g1
- BUS_SYNC(%g1, %g2)
-
- HERE(%g6, 128, %g4) ! preparation complete (for debug)
-
- ! Signal this processor is ready for rename operation to begin.
- ! See E$ note above.
- ATOMIC_ADD_LONG(drmach_xt_ready, 1, %g2, %g3, %g4)
-
- ! Loop on IRSR waiting for interrupt. The expected interrupt
- ! is a cross-trap to drmach_wait_done. It is sent by the master
- ! processor when the copy-rename operation is complete. The
- ! received cross-trap is used only as a signal. It is not executed.
-2:
- HERE(%g6, 136, %g4) ! last poll tick (for debug)
-
- ldxa [%g0]ASI_INTR_RECEIVE_STATUS, %g4 ! wait for xt
- btst IRSR_BUSY, %g4
- bz 2b
- nop
- stx %g4, [%g6 + 64] ! save status and payload
- set IRDR_0, %g2
- ldxa [%g2]ASI_INTR_RECEIVE, %g2
- stx %g2, [%g6 + 72]
- set IRDR_1, %g2
- ldxa [%g2]ASI_INTR_RECEIVE, %g2
- stx %g2, [%g6 + 80]
- set IRDR_2, %g2
- ldxa [%g2]ASI_INTR_RECEIVE, %g2
- stx %g2, [%g6 + 88]
-
- ! clear rcv status
- stxa %g0, [%g0]ASI_INTR_RECEIVE_STATUS
- membar #Sync
-
- HERE(%g6, 144, %g4) ! signal rcvd tick (for debug)
-
- ! Check for copy-rename abort signal. If this signal is received,
- ! the LPA change is skipped since the rename step was not done.
- ! The cache flushes are still done as paranoia.
- set drmach_rename_abort, %g1
- ldx [%g6 + 72], %g2
- cmp %g1, %g2
- be 3f
- nop
-
- ! Resume waiting if this is not drmach_rename_done.
- set drmach_rename_done, %g1
- cmp %g1, %g2
- bne 2b
- nop
-
- ldub [%g6 + 40], %g1 ! get saved mailbox data
- SET_LPA(%g1, %g2, %g3) ! set LPA as indicated by the mb data
-
-3:
- ! Flush all caches (E, D, I and P) to ensure each is resynchronized
- ! with the corresponding states in the new home memory. (W$ is
- ! implicitly flushed when the E$ is flushed.)
- !
- ! Panther needs to flush the L2 cache before the L3
- ! cache is flushed by the ecache flushall macro.
- PN_L2_FLUSHALL(%g1, %g2, %g3)
-
- ldx [%g6 + 24], %g1 ! *ecache_flushaddr
- ld [%g6 + 32], %g2 ! ecache_size
- ld [%g6 + 36], %g3 ! ecache_linesize
- ECACHE_FLUSHALL(%g2, %g3, %g1, %g4)
-
- ld [%g6 + 8], %g1 ! flush dcache
- ld [%g6 + 12], %g2
- CH_DCACHE_FLUSHALL(%g1, %g2, %g3)
-
- ld [%g6 + 16], %g1 ! flush icache
- ld [%g6 + 20], %g2
- CH_ICACHE_FLUSHALL(%g1, %g2, %g3, %g4)
-
- PCACHE_FLUSHALL(%g1, %g2, %g3) ! flush pcache (no parameters)
-
- HERE(%g6, 152, %g4) ! done tick (for debug)
-
- jmpl %g7+8, %g0
- nop
-
- .asciz "drmach_rename_wait" ! for debug
- .align 4
-drmach_rename_wait_asm_end:
- SET_SIZE(drmach_rename_wait)
-
-
- ! drmach_rename_done
- !
- ! input:
- ! nothing
- !
- ! output:
- ! nothing
- !
- ! Used as signal data. See drmach_rename_wait.
- !
- ENTRY_NP(drmach_rename_done)
- retry
- SET_SIZE(drmach_rename_done)
-
- ! drmach_rename_abort
- !
- ! input:
- ! nothing
- !
- ! output:
- ! nothing
- !
- ! Used as signal data. See drmach_rename_wait.
- !
- ENTRY_NP(drmach_rename_abort)
- retry
- SET_SIZE(drmach_rename_abort)
-
-
- ! drmach_set_lpa
- !
- ! input:
- ! Globals: drmach_xt_mb[cpuid] contains new LPA data
- !
- ! output:
- ! nothing
- !
- ! Sets the executing processor's LPA as indicated by the command
- ! stored in drmach_xt_mb, a byte array indexed by cpuid. Assumes
- ! the caller is preventing illegal LPA settings and transistions.
- !
- ENTRY_NP(drmach_set_lpa)
-
- !
- ! Set %g1 to this processor's cpuid.
- !
- CPU_INDEX(%g1, %g2)
-
- !
- ! Get LPA message from mailbox, leave in %g5.
- !
- LOAD_MB(%g1, %g5, %g2)
-
- !
- ! Set LPA, mailbox data in %g5.
- !
- SET_LPA(%g5, %g1, %g2)
-
- !
- ! Signal work is done.
- !
- ATOMIC_ADD_LONG(drmach_xt_ready, 1, %g1, %g2, %g3)
-
- retry
- SET_SIZE(drmach_set_lpa)
-
-!
-! drmach_bc_bzero
-!
-! inputs:
-! %o0 = base vaddr of area to clear (must be 64-byte aligned)
-! %o1 = size of area to clear (must be multiple of 256 bytes)
-!
-! outputs:
-! %o0 =
-! 0 (success)
-! 1 (size too small or not modulo 256)
-! 2 (vaddr not 64-byte aligned)
-!
-! Zero a block of storage using block commit stores.
-! Nonzero return if caller's address or size are not
-! block aligned.
-!
-
-
- ENTRY(drmach_bc_bzero)
-
- ! verify size is >= 256 bytes
- cmp %o1, 256
- blu,a .bz_done
- mov 1, %o0 ! error code 1 for invalid size
-
- ! verify size is a multiple of 256
- btst (256-1), %o1
- bnz,a .bz_done
- mov 1, %o0 ! error code 1 for invalid size
-
- ! verify that vaddr is aligned for block stores
- btst (64-1), %o0
- bnz,a .bz_done
- mov 2, %o0 ! error code 2 for invalid alignment
-
- ! save fprs for restore when finished
- rd %fprs, %g1
-
- ! make sure FPU is enabled
- rdpr %pstate, %g3
- btst PSTATE_PEF, %g3
- bnz .bz_block
- nop
- andn %g3, PSTATE_PEF, %g4
- wrpr %g4, PSTATE_PEF, %pstate
-
-.bz_block:
- membar #StoreStore|#StoreLoad|#LoadStore
- wr %g0, FPRS_FEF, %fprs
-
- ! Clear block
- fzero %d0
- fzero %d2
- fzero %d4
- fzero %d6
- fzero %d8
- fzero %d10
- fzero %d12
- fzero %d14
- wr %g0, ASI_BLK_COMMIT_P, %asi
- mov 256, %o3
- ba .bz_doblock
- nop
-
-.bz_blkstart:
- ! stda %d0, [%o0+192]%asi ! in dly slot of branch that got us here
- stda %d0, [%o0+128]%asi
- stda %d0, [%o0+64]%asi
- stda %d0, [%o0]%asi
- add %o0, %o3, %o0
- sub %o1, %o3, %o1
-.bz_doblock:
- cmp %o1, 256
- bgeu,a %ncc, .bz_blkstart
- stda %d0, [%o0+192]%asi
-
-.bz_finish:
- membar #StoreLoad|#StoreStore
- clr %o0
- wr %g1, %fprs ! restore fprs
- btst PSTATE_PEF, %g3 ! restore pstate if necessary
- bnz .bz_done
- nop
- wrpr %g3, %g0, %pstate
-.bz_done:
- membar #Sync
- retl
- nop
-
- SET_SIZE(drmach_bc_bzero)
-
-#endif /* lint */
diff --git a/usr/src/uts/sun4u/starcat/ml/starcat_asm.s b/usr/src/uts/sun4u/starcat/ml/starcat_asm.s
deleted file mode 100644
index 4ba52e3a15..0000000000
--- a/usr/src/uts/sun4u/starcat/ml/starcat_asm.s
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#if defined(lint)
-#include <sys/types.h>
-#else
-#include "assym.h"
-#endif /* lint */
-
-#include <sys/asm_linkage.h>
-#include <sys/param.h>
-#include <sys/privregs.h>
-#include <sys/machasi.h>
-#include <sys/mmu.h>
-#include <sys/machthread.h>
-#include <sys/pte.h>
-#include <sys/stack.h>
-#include <sys/vis.h>
-#include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/vtrace.h>
-#include <sys/clock.h>
-#include <sys/asi.h>
-#include <sys/fsr.h>
-#include <sys/cmpregs.h>
-#include <sys/cheetahregs.h>
-
-#if defined(lint)
-
-/* ARGSUSED */
-uint64_t
-lddmcdecode(uint64_t physaddr)
-{
- return (0x0ull);
-}
-
-#else /* !lint */
-
-!
-! Load the mc_decode reg for this CPU.
-!
-
- ENTRY(lddmcdecode)
- rdpr %pstate, %o4
- andn %o4, PSTATE_IE | PSTATE_AM, %o5
- wrpr %o5, 0, %pstate ! clear IE, AM bits
- ldxa [%o0]ASI_MC_DECODE, %o0
- retl
- wrpr %g0, %o4, %pstate ! restore pstate value
- SET_SIZE(lddmcdecode)
-
-#endif /* lint */
-
diff --git a/usr/src/uts/sun4u/starcat/os/starcat.c b/usr/src/uts/sun4u/starcat/os/starcat.c
deleted file mode 100644
index 0fdcba26b8..0000000000
--- a/usr/src/uts/sun4u/starcat/os/starcat.c
+++ /dev/null
@@ -1,1329 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sysmacros.h>
-#include <sys/sunddi.h>
-#include <sys/esunddi.h>
-#include <sys/sunndi.h>
-#include <sys/modctl.h>
-#include <sys/promif.h>
-#include <sys/machparam.h>
-#include <sys/kobj.h>
-#include <sys/cpuvar.h>
-#include <sys/mem_cage.h>
-#include <sys/promif.h>
-#include <sys/promimpl.h>
-#include <sys/platform_module.h>
-#include <sys/errno.h>
-#include <sys/cpu_sgnblk_defs.h>
-#include <sys/iosramio.h>
-#include <sys/domaind.h>
-#include <sys/starcat.h>
-#include <sys/machsystm.h>
-#include <sys/bootconf.h>
-#include <sys/memnode.h>
-#include <vm/vm_dep.h>
-#include <vm/page.h>
-#include <sys/cheetahregs.h>
-#include <sys/plat_ecc_unum.h>
-#include <sys/plat_ecc_dimm.h>
-#include <sys/lgrp.h>
-#include <sys/dr.h>
-#include <sys/post/scat_dcd.h>
-#include <sys/kdi_impl.h>
-#include <sys/iosramreg.h>
-#include <sys/iosramvar.h>
-#include <sys/mc-us3.h>
-#include <sys/clock_impl.h>
-
-/* Preallocation of spare tsb's for DR */
-int starcat_tsb_spares = STARCAT_SPARE_TSB_MAX;
-
-/* Set the maximum number of slot0 + slot1 boards. .. for DR */
-int starcat_boards = STARCAT_BDSET_MAX * STARCAT_BDSET_SLOT_MAX;
-
-/* Maximum number of cpus per board... for DR */
-int starcat_cpu_per_board = MAX(STARCAT_SLOT0_CPU_MAX, STARCAT_SLOT1_CPU_MAX);
-
-/* Maximum number of mem-units per board... for DR */
-int starcat_mem_per_board = MAX(STARCAT_SLOT0_MEM_MAX, STARCAT_SLOT1_MEM_MAX);
-
-/* Maximum number of io-units (buses) per board... for DR */
-int starcat_io_per_board = 2 * MAX(STARCAT_SLOT0_IO_MAX, STARCAT_SLOT1_IO_MAX);
-
-/* Preferred minimum cage size (expressed in pages)... for DR */
-pgcnt_t starcat_startup_cage_size = 0;
-
-/* Platform specific function to get unum information */
-int (*p2get_mem_unum)(int, uint64_t, char *, int, int *);
-
-/* Memory for fcode claims. 16k times # maximum possible schizos */
-#define EFCODE_SIZE (STARCAT_BDSET_MAX * 4 * 0x4000)
-int efcode_size = EFCODE_SIZE;
-
-void sgn_update_all_cpus(ushort_t, uchar_t, uchar_t);
-
-/*
- * The IOSRAM driver is loaded in load_platform_drivers() any cpu signature
- * usage prior to that time will have not have a function to call.
- */
-static int (*iosram_rdp)(uint32_t key, uint32_t off, uint32_t len,
- caddr_t dptr) = prom_starcat_iosram_read;
-static int (*iosram_wrp)(uint32_t key, uint32_t off, uint32_t len,
- caddr_t dptr) = prom_starcat_iosram_write;
-
-plat_dimm_sid_board_t domain_dimm_sids[STARCAT_BDSET_MAX];
-
-/*
- * set_platform_max_ncpus should return the maximum number of CPUs that the
- * platform supports. This function is called from check_cpus() to set the
- * value of max_ncpus [see PSARC 1997/165 CPU Dynamic Reconfiguration].
- * Data elements which are allocated based upon max_ncpus are all accessed
- * via cpu_seqid and not physical IDs. Previously, the value of max_ncpus
- * was being set to the largest physical ID, which led to boot problems on
- * systems with less than 1.25GB of memory.
- */
-
-int
-set_platform_max_ncpus(void)
-{
- int n;
-
- /*
- * Convert number of slot0 + slot1 boards to number of expander brds
- * and constrain the value to an architecturally plausible range
- */
- n = MAX(starcat_boards, STARCAT_BDSET_MIN * STARCAT_BDSET_SLOT_MAX);
- n = MIN(n, STARCAT_BDSET_MAX * STARCAT_BDSET_SLOT_MAX);
- n = (n + STARCAT_BDSET_SLOT_MAX - 1) / STARCAT_BDSET_SLOT_MAX;
-
- /* return maximum number of cpus possible on N expander boards */
- return (n * STARCAT_BDSET_CPU_MAX - STARCAT_SLOT1_CPU_MAX);
-}
-
-int
-set_platform_tsb_spares()
-{
- return (MIN(starcat_tsb_spares, MAX_UPA));
-}
-
-#pragma weak mmu_init_large_pages
-
-void
-set_platform_defaults(void)
-{
- extern char *tod_module_name;
- extern int ts_dispatch_extended;
- extern void cpu_sgn_update(ushort_t, uchar_t, uchar_t, int);
- extern int tsb_lgrp_affinity;
- extern int segkmem_reloc;
- extern void mmu_init_large_pages(size_t);
- extern int ncpunode; /* number of CPUs detected by OBP */
-
-#ifdef DEBUG
- ce_verbose_memory = 2;
- ce_verbose_other = 2;
-#endif
-
- /* Set the CPU signature function pointer */
- cpu_sgn_func = cpu_sgn_update;
-
- /* Set appropriate tod module for starcat */
- ASSERT(tod_module_name == NULL);
- tod_module_name = "todstarcat";
-
- /*
- * Use the alternate TS dispatch table, which is better
- * tuned for large servers.
- */
- if (ts_dispatch_extended == -1)
- ts_dispatch_extended = 1;
-
- /*
- * Use lgroup-aware TSB allocations on this platform,
- * since they are a considerable performance win.
- */
- tsb_lgrp_affinity = 1;
-
- if ((mmu_page_sizes == max_mmu_page_sizes) &&
- (mmu_ism_pagesize != DEFAULT_ISM_PAGESIZE)) {
- if (&mmu_init_large_pages)
- mmu_init_large_pages(mmu_ism_pagesize);
- }
-
- /*
- * KPR (kernel page relocation) is supported on this platform.
- */
- if (kernel_cage_enable && ncpunode >= 32) {
- segkmem_reloc = 1;
- cmn_err(CE_NOTE, "!Kernel Page Relocation is ENABLED");
- } else {
- cmn_err(CE_NOTE, "!Kernel Page Relocation is DISABLED");
- }
-}
-
-#ifdef DEBUG
-pgcnt_t starcat_cage_size_limit;
-#endif
-
-void
-set_platform_cage_params(void)
-{
- extern pgcnt_t total_pages;
- extern struct memlist *phys_avail;
-
- if (kernel_cage_enable) {
- pgcnt_t preferred_cage_size;
-
- preferred_cage_size =
- MAX(starcat_startup_cage_size, total_pages / 256);
-
-#ifdef DEBUG
- if (starcat_cage_size_limit)
- preferred_cage_size = starcat_cage_size_limit;
-#endif
- /*
- * Note: we are assuming that post has load the
- * whole show in to the high end of memory. Having
- * taken this leap, we copy the whole of phys_avail
- * the glist and arrange for the cage to grow
- * downward (descending pfns).
- */
- kcage_range_init(phys_avail, KCAGE_DOWN, preferred_cage_size);
- }
-
- if (kcage_on)
- cmn_err(CE_NOTE, "!DR Kernel Cage is ENABLED");
- else
- cmn_err(CE_NOTE, "!DR Kernel Cage is DISABLED");
-}
-
-void
-load_platform_modules(void)
-{
- if (modload("misc", "pcihp") < 0) {
- cmn_err(CE_NOTE, "pcihp driver failed to load");
- }
-}
-
-/*
- * Starcat does not support power control of CPUs from the OS.
- */
-/*ARGSUSED*/
-int
-plat_cpu_poweron(struct cpu *cp)
-{
- int (*starcat_cpu_poweron)(struct cpu *) = NULL;
-
- starcat_cpu_poweron =
- (int (*)(struct cpu *))kobj_getsymvalue("drmach_cpu_poweron", 0);
-
- if (starcat_cpu_poweron == NULL)
- return (ENOTSUP);
- else
- return ((starcat_cpu_poweron)(cp));
-}
-
-/*ARGSUSED*/
-int
-plat_cpu_poweroff(struct cpu *cp)
-{
- int (*starcat_cpu_poweroff)(struct cpu *) = NULL;
-
- starcat_cpu_poweroff =
- (int (*)(struct cpu *))kobj_getsymvalue("drmach_cpu_poweroff", 0);
-
- if (starcat_cpu_poweroff == NULL)
- return (ENOTSUP);
- else
- return ((starcat_cpu_poweroff)(cp));
-}
-
-/*
- * The following are currently private to Starcat DR
- */
-int
-plat_max_boards()
-{
- return (starcat_boards);
-}
-
-int
-plat_max_cpu_units_per_board()
-{
- return (starcat_cpu_per_board);
-}
-
-int
-plat_max_mc_units_per_board()
-{
- return (starcat_mem_per_board); /* each CPU has a memory controller */
-}
-
-int
-plat_max_mem_units_per_board()
-{
- return (starcat_mem_per_board);
-}
-
-int
-plat_max_io_units_per_board()
-{
- return (starcat_io_per_board);
-}
-
-int
-plat_max_cpumem_boards(void)
-{
- return (STARCAT_BDSET_MAX);
-}
-
-int
-plat_pfn_to_mem_node(pfn_t pfn)
-{
- return (pfn >> mem_node_pfn_shift);
-}
-
-#define STARCAT_MC_MEMBOARD_SHIFT 37 /* Boards on 128BG boundary */
-
-/* ARGSUSED */
-void
-plat_build_mem_nodes(prom_memlist_t *list, size_t nelems)
-{
- size_t elem;
- pfn_t basepfn;
- pgcnt_t npgs;
-
- /*
- * Starcat mem slices are always aligned on a 128GB boundary,
- * fixed, and limited to one slice per expander due to design
- * of the centerplane ASICs.
- */
- mem_node_pfn_shift = STARCAT_MC_MEMBOARD_SHIFT - MMU_PAGESHIFT;
- mem_node_physalign = 0;
-
- /*
- * Boot install lists are arranged <addr, len>, <addr, len>, ...
- */
- for (elem = 0; elem < nelems; list++, elem++) {
- basepfn = btop(list->addr);
- npgs = btop(list->size);
- mem_node_add_slice(basepfn, basepfn + npgs - 1);
- }
-}
-
-/*
- * Find the CPU associated with a slice at boot-time.
- */
-void
-plat_fill_mc(pnode_t nodeid)
-{
- int len;
- uint64_t mc_addr, mask;
- uint64_t mc_decode[MAX_BANKS_PER_MC];
- uint32_t regs[4];
- int local_mc;
- int portid;
- int expnum;
- int i;
-
- /*
- * Memory address decoding registers
- * (see Chap 9 of SPARCV9 JSP-1 US-III implementation)
- */
- const uint64_t mc_decode_addr[MAX_BANKS_PER_MC] = {
- 0x400028, 0x400010, 0x400018, 0x400020
- };
-
- /*
- * Starcat memory controller portid == global CPU id
- */
- if ((prom_getprop(nodeid, "portid", (caddr_t)&portid) < 0) ||
- (portid == -1))
- return;
-
- expnum = STARCAT_CPUID_TO_EXPANDER(portid);
-
- /*
- * The "reg" property returns 4 32-bit values. The first two are
- * combined to form a 64-bit address. The second two are for a
- * 64-bit size, but we don't actually need to look at that value.
- */
- len = prom_getproplen(nodeid, "reg");
- if (len != (sizeof (uint32_t) * 4)) {
- prom_printf("Warning: malformed 'reg' property\n");
- return;
- }
- if (prom_getprop(nodeid, "reg", (caddr_t)regs) < 0)
- return;
- mc_addr = ((uint64_t)regs[0]) << 32;
- mc_addr |= (uint64_t)regs[1];
-
- /*
- * Figure out whether the memory controller we are examining
- * belongs to this CPU/CMP or a different one.
- */
- if (portid == cpunodes[CPU->cpu_id].portid)
- local_mc = 1;
- else
- local_mc = 0;
-
- for (i = 0; i < MAX_BANKS_PER_MC; i++) {
-
- mask = mc_decode_addr[i];
-
- /*
- * If the memory controller is local to this CPU, we use
- * the special ASI to read the decode registers.
- * Otherwise, we load the values from a magic address in
- * I/O space.
- */
- if (local_mc)
- mc_decode[i] = lddmcdecode(mask & MC_OFFSET_MASK);
- else
- mc_decode[i] = lddphysio((mc_addr | mask));
-
- if (mc_decode[i] >> MC_VALID_SHIFT) {
- uint64_t base = MC_BASE(mc_decode[i]) << PHYS2UM_SHIFT;
- int sliceid = (base >> STARCAT_MC_MEMBOARD_SHIFT);
-
- if (sliceid < max_mem_nodes) {
- /*
- * Establish start-of-day mappings of
- * lgroup platform handles to memnodes.
- * Handle == Expander Number
- * Memnode == Fixed 128GB Slice
- */
- plat_assign_lgrphand_to_mem_node(expnum,
- sliceid);
- }
- }
- }
-}
-
-/*
- * Starcat support for lgroups.
- *
- * On Starcat, an lgroup platform handle == expander number.
- * For split-slot configurations (e.g. slot 0 and slot 1 boards
- * in different domains) an MCPU board has only remote memory.
- *
- * The centerplane logic provides fixed 128GB memory slices
- * each of which map to a memnode. The initial mapping of
- * memnodes to lgroup handles is determined at boot time.
- * A DR addition of memory adds a new mapping. A DR copy-rename
- * swaps mappings.
- */
-
-/*
- * Convert board number to expander number.
- */
-#define BOARDNUM_2_EXPANDER(b) (b >> 1)
-
-/*
- * Return the number of boards configured with NULL LPA.
- */
-static int
-check_for_null_lpa(void)
-{
- gdcd_t *gdcd;
- uint_t exp, nlpa;
-
- /*
- * Read GDCD from IOSRAM.
- * If this fails indicate a NULL LPA condition.
- */
- if ((gdcd = kmem_zalloc(sizeof (gdcd_t), KM_NOSLEEP)) == NULL)
- return (EXP_COUNT+1);
-
- if ((*iosram_rdp)(GDCD_MAGIC, 0, sizeof (gdcd_t), (caddr_t)gdcd) ||
- (gdcd->h.dcd_magic != GDCD_MAGIC) ||
- (gdcd->h.dcd_version != DCD_VERSION)) {
- kmem_free(gdcd, sizeof (gdcd_t));
- cmn_err(CE_WARN, "check_for_null_lpa: failed to access GDCD\n");
- return (EXP_COUNT+2);
- }
-
- /*
- * Check for NULL LPAs on all slot 0 boards in domain
- * (i.e. in all expanders marked good for this domain).
- */
- nlpa = 0;
- for (exp = 0; exp < EXP_COUNT; exp++) {
- if (RSV_GOOD(gdcd->dcd_slot[exp][0].l1ss_rsv) &&
- (gdcd->dcd_slot[exp][0].l1ss_flags &
- L1SSFLG_THIS_L1_NULL_PROC_LPA))
- nlpa++;
- }
-
- kmem_free(gdcd, sizeof (gdcd_t));
- return (nlpa);
-}
-
-/*
- * Return the platform handle for the lgroup containing the given CPU
- *
- * For Starcat, lgroup platform handle == expander.
- */
-
-extern int mpo_disabled;
-extern lgrp_handle_t lgrp_default_handle;
-int null_lpa_boards = -1;
-
-lgrp_handle_t
-plat_lgrp_cpu_to_hand(processorid_t id)
-{
- lgrp_handle_t plathand;
-
- plathand = STARCAT_CPUID_TO_EXPANDER(id);
-
- /*
- * Return the real platform handle for the CPU until
- * such time as we know that MPO should be disabled.
- * At that point, we set the "mpo_disabled" flag to true,
- * and from that point on, return the default handle.
- *
- * By the time we know that MPO should be disabled, the
- * first CPU will have already been added to a leaf
- * lgroup, but that's ok. The common lgroup code will
- * double check that the boot CPU is in the correct place,
- * and in the case where mpo should be disabled, will move
- * it to the root if necessary.
- */
- if (mpo_disabled) {
- /* If MPO is disabled, return the default (UMA) handle */
- plathand = lgrp_default_handle;
- } else {
- if (null_lpa_boards > 0) {
- /* Determine if MPO should be disabled */
- mpo_disabled = 1;
- plathand = lgrp_default_handle;
- }
- }
- return (plathand);
-}
-
-/*
- * Platform specific lgroup initialization
- */
-void
-plat_lgrp_init(void)
-{
- extern uint32_t lgrp_expand_proc_thresh;
- extern uint32_t lgrp_expand_proc_diff;
-
- /*
- * Set tuneables for Starcat architecture
- *
- * lgrp_expand_proc_thresh is the minimum load on the lgroups
- * this process is currently running on before considering
- * expanding threads to another lgroup.
- *
- * lgrp_expand_proc_diff determines how much less the remote lgroup
- * must be loaded before expanding to it.
- *
- * Since remote latencies can be costly, attempt to keep 3 threads
- * within the same lgroup before expanding to the next lgroup.
- */
- lgrp_expand_proc_thresh = LGRP_LOADAVG_THREAD_MAX * 3;
- lgrp_expand_proc_diff = LGRP_LOADAVG_THREAD_MAX;
-}
-
-/*
- * Platform notification of lgroup (re)configuration changes
- */
-/*ARGSUSED*/
-void
-plat_lgrp_config(lgrp_config_flag_t evt, uintptr_t arg)
-{
- update_membounds_t *umb;
- lgrp_config_mem_rename_t lmr;
- int sbd, tbd;
- lgrp_handle_t hand, shand, thand;
- int mnode, snode, tnode;
-
- if (mpo_disabled)
- return;
-
- switch (evt) {
-
- case LGRP_CONFIG_MEM_ADD:
- /*
- * Establish the lgroup handle to memnode translation.
- */
- umb = (update_membounds_t *)arg;
-
- hand = BOARDNUM_2_EXPANDER(umb->u_board);
- mnode = plat_pfn_to_mem_node(umb->u_base >> MMU_PAGESHIFT);
- plat_assign_lgrphand_to_mem_node(hand, mnode);
-
- break;
-
- case LGRP_CONFIG_MEM_DEL:
- /* We don't have to do anything */
-
- break;
-
- case LGRP_CONFIG_MEM_RENAME:
- /*
- * During a DR copy-rename operation, all of the memory
- * on one board is moved to another board -- but the
- * addresses/pfns and memnodes don't change. This means
- * the memory has changed locations without changing identity.
- *
- * Source is where we are copying from and target is where we
- * are copying to. After source memnode is copied to target
- * memnode, the physical addresses of the target memnode are
- * renamed to match what the source memnode had. Then target
- * memnode can be removed and source memnode can take its
- * place.
- *
- * To do this, swap the lgroup handle to memnode mappings for
- * the boards, so target lgroup will have source memnode and
- * source lgroup will have empty target memnode which is where
- * its memory will go (if any is added to it later).
- *
- * Then source memnode needs to be removed from its lgroup
- * and added to the target lgroup where the memory was living
- * but under a different name/memnode. The memory was in the
- * target memnode and now lives in the source memnode with
- * different physical addresses even though it is the same
- * memory.
- */
- sbd = arg & 0xffff;
- tbd = (arg & 0xffff0000) >> 16;
- shand = BOARDNUM_2_EXPANDER(sbd);
- thand = BOARDNUM_2_EXPANDER(tbd);
- snode = plat_lgrphand_to_mem_node(shand);
- tnode = plat_lgrphand_to_mem_node(thand);
-
- plat_assign_lgrphand_to_mem_node(thand, snode);
- plat_assign_lgrphand_to_mem_node(shand, tnode);
-
- lmr.lmem_rename_from = shand;
- lmr.lmem_rename_to = thand;
-
- /*
- * Remove source memnode of copy rename from its lgroup
- * and add it to its new target lgroup
- */
- lgrp_config(LGRP_CONFIG_MEM_RENAME, (uintptr_t)snode,
- (uintptr_t)&lmr);
-
- break;
-
- default:
- break;
- }
-}
-
-/*
- * Return latency between "from" and "to" lgroups
- *
- * This latency number can only be used for relative comparison
- * between lgroups on the running system, cannot be used across platforms,
- * and may not reflect the actual latency. It is platform and implementation
- * specific, so platform gets to decide its value. It would be nice if the
- * number was at least proportional to make comparisons more meaningful though.
- * NOTE: The numbers below are supposed to be load latencies for uncached
- * memory divided by 10.
- */
-int
-plat_lgrp_latency(lgrp_handle_t from, lgrp_handle_t to)
-{
- /*
- * Return min remote latency when there are more than two lgroups
- * (root and child) and getting latency between two different lgroups
- * or root is involved
- */
- if (lgrp_optimizations() && (from != to ||
- from == LGRP_DEFAULT_HANDLE || to == LGRP_DEFAULT_HANDLE))
- return (48);
- else
- return (28);
-}
-
-/*
- * Return platform handle for root lgroup
- */
-lgrp_handle_t
-plat_lgrp_root_hand(void)
-{
- if (mpo_disabled)
- return (lgrp_default_handle);
-
- return (LGRP_DEFAULT_HANDLE);
-}
-
-/* ARGSUSED */
-void
-plat_freelist_process(int mnode)
-{
-}
-
-void
-load_platform_drivers(void)
-{
- uint_t tunnel;
- pnode_t nodeid;
- dev_info_t *chosen_devi;
- char chosen_iosram[MAXNAMELEN];
-
- /*
- * Get /chosen node - that's where the tunnel property is
- */
- nodeid = prom_chosennode();
-
- /*
- * Get the iosram property from the chosen node.
- */
- if (prom_getprop(nodeid, IOSRAM_CHOSEN_PROP, (caddr_t)&tunnel) <= 0) {
- prom_printf("Unable to get iosram property\n");
- cmn_err(CE_PANIC, "Unable to get iosram property\n");
- }
-
- if (prom_phandle_to_path((phandle_t)tunnel, chosen_iosram,
- sizeof (chosen_iosram)) < 0) {
- (void) prom_printf("prom_phandle_to_path(0x%x) failed\n",
- tunnel);
- cmn_err(CE_PANIC, "prom_phandle_to_path(0x%x) failed\n",
- tunnel);
- }
-
- /*
- * Attach all driver instances along the iosram's device path
- */
- if (i_ddi_attach_hw_nodes("iosram") != DDI_SUCCESS) {
- cmn_err(CE_WARN, "IOSRAM failed to load\n");
- }
-
- if ((chosen_devi = e_ddi_hold_devi_by_path(chosen_iosram, 0)) == NULL) {
- (void) prom_printf("e_ddi_hold_devi_by_path(%s) failed\n",
- chosen_iosram);
- cmn_err(CE_PANIC, "e_ddi_hold_devi_by_path(%s) failed\n",
- chosen_iosram);
- }
- ndi_rele_devi(chosen_devi);
-
- /*
- * iosram driver is now loaded so we need to set our read and
- * write pointers.
- */
- iosram_rdp = (int (*)(uint32_t, uint32_t, uint32_t, caddr_t))
- modgetsymvalue("iosram_rd", 0);
- iosram_wrp = (int (*)(uint32_t, uint32_t, uint32_t, caddr_t))
- modgetsymvalue("iosram_wr", 0);
-
- /*
- * Need to check for null proc LPA after IOSRAM driver is loaded
- * and before multiple lgroups created (when start_other_cpus() called)
- */
- null_lpa_boards = check_for_null_lpa();
-
- /* load and attach the axq driver */
- if (i_ddi_attach_hw_nodes("axq") != DDI_SUCCESS) {
- cmn_err(CE_WARN, "AXQ failed to load\n");
- }
-
- /* load Starcat Solaris Mailbox Client driver */
- if (modload("misc", "scosmb") < 0) {
- cmn_err(CE_WARN, "SCOSMB failed to load\n");
- }
-
- /* load the DR driver */
- if (i_ddi_attach_hw_nodes("dr") != DDI_SUCCESS) {
- cmn_err(CE_WARN, "dr failed to load");
- }
-
- /*
- * Load the mc-us3 memory driver.
- */
- if (i_ddi_attach_hw_nodes("mc-us3") != DDI_SUCCESS)
- cmn_err(CE_WARN, "mc-us3 failed to load");
- else
- (void) ddi_hold_driver(ddi_name_to_major("mc-us3"));
-
- /* Load the schizo pci bus nexus driver. */
- if (i_ddi_attach_hw_nodes("pcisch") != DDI_SUCCESS)
- cmn_err(CE_WARN, "pcisch failed to load");
-
- plat_ecc_init();
-}
-
-
-/*
- * No platform drivers on this platform
- */
-char *platform_module_list[] = {
- (char *)0
-};
-
-
-/*ARGSUSED*/
-void
-plat_tod_fault(enum tod_fault_type tod_bad)
-{
-}
-
-/*
- * Update the signature(s) in the IOSRAM's domain data section.
- */
-void
-cpu_sgn_update(ushort_t sgn, uchar_t state, uchar_t sub_state, int cpuid)
-{
- sig_state_t new_sgn;
- sig_state_t current_sgn;
-
- /*
- * If the substate is REBOOT, then check for panic flow
- */
- if (sub_state == SIGSUBST_REBOOT) {
- (*iosram_rdp)(DOMD_MAGIC, DOMD_DSTATE_OFFSET,
- sizeof (sig_state_t), (caddr_t)&current_sgn);
- if (current_sgn.state_t.state == SIGST_EXIT)
- sub_state = SIGSUBST_PANIC_REBOOT;
- }
-
- /*
- * cpuid == -1 indicates that the operation applies to all cpus.
- */
- if (cpuid < 0) {
- sgn_update_all_cpus(sgn, state, sub_state);
- return;
- }
-
- new_sgn.signature = CPU_SIG_BLD(sgn, state, sub_state);
- (*iosram_wrp)(DOMD_MAGIC,
- DOMD_CPUSIGS_OFFSET + cpuid * sizeof (sig_state_t),
- sizeof (sig_state_t), (caddr_t)&new_sgn);
-
- /*
- * Under certain conditions we don't update the signature
- * of the domain_state.
- */
- if ((sgn == OS_SIG) &&
- ((state == SIGST_OFFLINE) || (state == SIGST_DETACHED)))
- return;
- (*iosram_wrp)(DOMD_MAGIC, DOMD_DSTATE_OFFSET, sizeof (sig_state_t),
- (caddr_t)&new_sgn);
-}
-
-/*
- * Update the signature(s) in the IOSRAM's domain data section for all CPUs.
- */
-void
-sgn_update_all_cpus(ushort_t sgn, uchar_t state, uchar_t sub_state)
-{
- sig_state_t new_sgn;
- int i = 0;
-
- new_sgn.signature = CPU_SIG_BLD(sgn, state, sub_state);
-
- /*
- * First update the domain_state signature
- */
- (*iosram_wrp)(DOMD_MAGIC, DOMD_DSTATE_OFFSET, sizeof (sig_state_t),
- (caddr_t)&new_sgn);
-
- for (i = 0; i < NCPU; i++) {
- if (cpu[i] != NULL && (cpu[i]->cpu_flags &
- (CPU_EXISTS|CPU_QUIESCED))) {
- (*iosram_wrp)(DOMD_MAGIC,
- DOMD_CPUSIGS_OFFSET + i * sizeof (sig_state_t),
- sizeof (sig_state_t), (caddr_t)&new_sgn);
- }
- }
-}
-
-ushort_t
-get_cpu_sgn(int cpuid)
-{
- sig_state_t cpu_sgn;
-
- (*iosram_rdp)(DOMD_MAGIC,
- DOMD_CPUSIGS_OFFSET + cpuid * sizeof (sig_state_t),
- sizeof (sig_state_t), (caddr_t)&cpu_sgn);
-
- return (cpu_sgn.state_t.sig);
-}
-
-uchar_t
-get_cpu_sgn_state(int cpuid)
-{
- sig_state_t cpu_sgn;
-
- (*iosram_rdp)(DOMD_MAGIC,
- DOMD_CPUSIGS_OFFSET + cpuid * sizeof (sig_state_t),
- sizeof (sig_state_t), (caddr_t)&cpu_sgn);
-
- return (cpu_sgn.state_t.state);
-}
-
-
-/*
- * Type of argument passed into plat_get_ecache_cpu via ddi_walk_devs
- * for matching on specific CPU node in device tree
- */
-
-typedef struct {
- char *jnum; /* output, kmem_alloc'd if successful */
- int cpuid; /* input, to match cpuid/portid/upa-portid */
- uint_t dimm; /* input, index into ecache-dimm-label */
-} plat_ecache_cpu_arg_t;
-
-
-/*
- * plat_get_ecache_cpu is called repeatedly by ddi_walk_devs with pointers
- * to device tree nodes (dip) and to a plat_ecache_cpu_arg_t structure (arg).
- * Returning DDI_WALK_CONTINUE tells ddi_walk_devs to keep going, returning
- * DDI_WALK_TERMINATE ends the walk. When the node for the specific CPU
- * being searched for is found, the walk is done. But before returning to
- * ddi_walk_devs and plat_get_ecacheunum, we grab this CPU's ecache-dimm-label
- * property and set the jnum member of the plat_ecache_cpu_arg_t structure to
- * point to the label corresponding to this specific ecache DIMM. It is up
- * to plat_get_ecacheunum to kmem_free this string.
- */
-
-static int
-plat_get_ecache_cpu(dev_info_t *dip, void *arg)
-{
- char *devtype;
- plat_ecache_cpu_arg_t *cpuarg;
- char **dimm_labels;
- uint_t numlabels;
- int portid;
-
- /*
- * Check device_type, must be "cpu"
- */
-
- if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "device_type", &devtype) != DDI_PROP_SUCCESS)
- return (DDI_WALK_CONTINUE);
-
- if (strcmp(devtype, "cpu")) {
- ddi_prop_free((void *)devtype);
- return (DDI_WALK_CONTINUE);
- }
-
- ddi_prop_free((void *)devtype);
-
- /*
- * Check cpuid, portid, upa-portid (in that order), must
- * match the cpuid being sought
- */
-
- portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "cpuid", -1);
-
- if (portid == -1)
- portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "portid", -1);
-
- if (portid == -1)
- portid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "upa-portid", -1);
-
- cpuarg = (plat_ecache_cpu_arg_t *)arg;
-
- if (portid != cpuarg->cpuid)
- return (DDI_WALK_CONTINUE);
-
- /*
- * Found the right CPU, fetch ecache-dimm-label property
- */
-
- if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "ecache-dimm-label", &dimm_labels, &numlabels)
- != DDI_PROP_SUCCESS) {
-#ifdef DEBUG
- cmn_err(CE_NOTE, "cpuid=%d missing ecache-dimm-label property",
- portid);
-#endif /* DEBUG */
- return (DDI_WALK_TERMINATE);
- }
-
- if (cpuarg->dimm < numlabels) {
- cpuarg->jnum = kmem_alloc(strlen(dimm_labels[cpuarg->dimm]) + 1,
- KM_SLEEP);
- if (cpuarg->jnum != (char *)NULL)
- (void) strcpy(cpuarg->jnum, dimm_labels[cpuarg->dimm]);
-#ifdef DEBUG
- else
- cmn_err(CE_WARN,
- "cannot kmem_alloc for ecache dimm label");
-#endif /* DEBUG */
- }
-
- ddi_prop_free((void *)dimm_labels);
- return (DDI_WALK_TERMINATE);
-}
-
-
-/*
- * Bit 4 of physical address indicates ecache 0 or 1
- */
-
-#define ECACHE_DIMM_MASK 0x10
-
-/*
- * plat_get_ecacheunum is called to generate the unum for an ecache error.
- * After some initialization, nearly all of the work is done by ddi_walk_devs
- * and plat_get_ecache_cpu.
- */
-
-int
-plat_get_ecacheunum(int cpuid, unsigned long long physaddr, char *buf,
- int buflen, int *ustrlen)
-{
- plat_ecache_cpu_arg_t findcpu;
- uint_t expander, slot, proc;
-
- findcpu.jnum = (char *)NULL;
- findcpu.cpuid = cpuid;
-
- /*
- * Bit 4 of physaddr equal 0 maps to E0 and 1 maps to E1
- * except for Panther and Jaguar where it indicates the reverse
- */
- if (IS_PANTHER(cpunodes[CPU->cpu_id].implementation) ||
- IS_JAGUAR(cpunodes[CPU->cpu_id].implementation))
- findcpu.dimm = (physaddr & ECACHE_DIMM_MASK) ? 0 : 1;
- else
- findcpu.dimm = (physaddr & ECACHE_DIMM_MASK) ? 1 : 0;
-
- /*
- * Walk the device tree, find this specific CPU, and get the label
- * for this ecache, returned here in findcpu.jnum
- */
-
- ddi_walk_devs(ddi_root_node(), plat_get_ecache_cpu, (void *)&findcpu);
-
- if (findcpu.jnum == (char *)NULL)
- return (-1);
-
- expander = STARCAT_CPUID_TO_EXPANDER(cpuid);
- slot = STARCAT_CPUID_TO_BOARDSLOT(cpuid);
-
- /*
- * STARCAT_CPUID_TO_PORTID clears the CoreID bit so that
- * STARCAT_CPUID_TO_AGENT will return a physical proc (0 - 3).
- */
- proc = STARCAT_CPUID_TO_AGENT(STARCAT_CPUID_TO_PORTID(cpuid));
-
- /*
- * NOTE: Any modifications to the snprintf() call below will require
- * changing plat_log_fruid_error() as well!
- */
- (void) snprintf(buf, buflen, "%s%u/P%u/E%u J%s", (slot ? "IO" : "SB"),
- expander, proc, findcpu.dimm, findcpu.jnum);
-
- *ustrlen = strlen(buf);
-
- kmem_free(findcpu.jnum, strlen(findcpu.jnum) + 1);
-
- return (0);
-}
-
-/*ARGSUSED*/
-int
-plat_get_mem_unum(int synd_code, uint64_t flt_addr, int flt_bus_id,
- int flt_in_memory, ushort_t flt_status, char *buf, int buflen, int *lenp)
-{
- int ret;
-
- /*
- * check if it's a Memory or an Ecache error.
- */
- if (flt_in_memory) {
- if (p2get_mem_unum != NULL) {
- return (p2get_mem_unum(synd_code, P2ALIGN(flt_addr, 8),
- buf, buflen, lenp));
- } else {
- return (ENOTSUP);
- }
- } else if (flt_status & ECC_ECACHE) {
- if ((ret = plat_get_ecacheunum(flt_bus_id,
- P2ALIGN(flt_addr, 8), buf, buflen, lenp)) != 0)
- return (EIO);
- } else {
- return (ENOTSUP);
- }
-
- return (ret);
-}
-
-static int (*ecc_mailbox_msg_func)(plat_ecc_message_type_t, void *) = NULL;
-
-/*
- * To keep OS mailbox handling localized, all we do is forward the call to the
- * scosmb module (if it is available).
- */
-int
-plat_send_ecc_mailbox_msg(plat_ecc_message_type_t msg_type, void *datap)
-{
- /*
- * find the symbol for the mailbox sender routine in the scosmb module
- */
- if (ecc_mailbox_msg_func == NULL)
- ecc_mailbox_msg_func = (int (*)(plat_ecc_message_type_t,
- void *))modgetsymvalue("scosmb_log_ecc_error", 0);
-
- /*
- * If the symbol was found, call it. Otherwise, there is not much
- * else we can do and console messages will have to suffice.
- */
- if (ecc_mailbox_msg_func)
- return ((*ecc_mailbox_msg_func)(msg_type, datap));
- else
- return (ENODEV);
-}
-
-int
-plat_make_fru_cpuid(int sb, int m, int proc)
-{
- return (MAKE_CPUID(sb, m, proc));
-}
-
-/*
- * board number for a given proc
- */
-int
-plat_make_fru_boardnum(int proc)
-{
- return (STARCAT_CPUID_TO_EXPANDER(proc));
-}
-
-/*
- * This platform hook gets called from mc_add_mem_unum_label() in the mc-us3
- * driver giving each platform the opportunity to add platform
- * specific label information to the unum for ECC error logging purposes.
- */
-void
-plat_add_mem_unum_label(char *unum, int mcid, int bank, int dimm)
-{
- char new_unum[UNUM_NAMLEN];
- uint_t expander = STARCAT_CPUID_TO_EXPANDER(mcid);
- uint_t slot = STARCAT_CPUID_TO_BOARDSLOT(mcid);
-
- /*
- * STARCAT_CPUID_TO_PORTID clears the CoreID bit so that
- * STARCAT_CPUID_TO_AGENT will return a physical proc (0 - 3).
- */
- uint_t proc = STARCAT_CPUID_TO_AGENT(STARCAT_CPUID_TO_PORTID(mcid));
-
- /*
- * NOTE: Any modifications to the two sprintf() calls below will
- * require changing plat_log_fruid_error() as well!
- */
- if (dimm == -1)
- (void) snprintf(new_unum, UNUM_NAMLEN, "%s%u/P%u/B%d %s",
- (slot ? "IO" : "SB"), expander, proc, (bank & 0x1), unum);
- else
- (void) snprintf(new_unum, UNUM_NAMLEN, "%s%u/P%u/B%d/D%d %s",
- (slot ? "IO" : "SB"), expander,
- proc, (bank & 0x1), (dimm & 0x3), unum);
-
- (void) strcpy(unum, new_unum);
-}
-
-int
-plat_get_cpu_unum(int cpuid, char *buf, int buflen, int *lenp)
-{
- int expander = STARCAT_CPUID_TO_EXPANDER(cpuid);
- int slot = STARCAT_CPUID_TO_BOARDSLOT(cpuid);
-
- if (snprintf(buf, buflen, "%s%d", (slot ? "IO" : "SB"), expander)
- >= buflen) {
- return (ENOSPC);
- } else {
- *lenp = strlen(buf);
- return (0);
- }
-}
-
-/*
- * This routine is used by the data bearing mondo (DMV) initialization
- * routine to determine the number of hardware and software DMV interrupts
- * that a platform supports.
- */
-void
-plat_dmv_params(uint_t *hwint, uint_t *swint)
-{
- *hwint = STARCAT_DMV_HWINT;
- *swint = 0;
-}
-
-/*
- * If provided, this function will be called whenever the nodename is updated.
- * To keep OS mailbox handling localized, all we do is forward the call to the
- * scosmb module (if it is available).
- */
-void
-plat_nodename_set(void)
-{
- void (*nodename_update_func)(uint64_t) = NULL;
-
- /*
- * find the symbol for the nodename update routine in the scosmb module
- */
- nodename_update_func = (void (*)(uint64_t))
- modgetsymvalue("scosmb_update_nodename", 0);
-
- /*
- * If the symbol was found, call it. Otherwise, log a note (but not to
- * the console).
- */
- if (nodename_update_func != NULL) {
- nodename_update_func(0);
- } else {
- cmn_err(CE_NOTE,
- "!plat_nodename_set: scosmb_update_nodename not found\n");
- }
-}
-
-caddr_t efcode_vaddr = NULL;
-caddr_t efcode_paddr = NULL;
-/*
- * Preallocate enough memory for fcode claims.
- */
-
-caddr_t
-efcode_alloc(caddr_t alloc_base)
-{
- caddr_t efcode_alloc_base = (caddr_t)roundup((uintptr_t)alloc_base,
- MMU_PAGESIZE);
- caddr_t vaddr;
-
- /*
- * allocate the physical memory schizo fcode.
- */
- if ((vaddr = (caddr_t)BOP_ALLOC(bootops, efcode_alloc_base,
- efcode_size, MMU_PAGESIZE)) == NULL)
- cmn_err(CE_PANIC, "Cannot allocate Efcode Memory");
-
- efcode_vaddr = vaddr;
-
- return (efcode_alloc_base + efcode_size);
-}
-
-caddr_t
-plat_startup_memlist(caddr_t alloc_base)
-{
- caddr_t tmp_alloc_base;
-
- tmp_alloc_base = efcode_alloc(alloc_base);
- tmp_alloc_base = (caddr_t)roundup((uintptr_t)tmp_alloc_base,
- ecache_alignsize);
- return (tmp_alloc_base);
-}
-
-/*
- * This is a helper function to determine if a given
- * node should be considered for a dr operation according
- * to predefined dr names. This is accomplished using
- * a function defined in drmach module. The drmach module
- * owns the definition of dr allowable names.
- * Formal Parameter: The name of a device node.
- * Expected Return Value: -1, device node name does not map to a valid dr name.
- * A value greater or equal to 0, name is valid.
- */
-int
-starcat_dr_name(char *name)
-{
- int (*drmach_name2type)(char *) = NULL;
-
- /* Get a pointer to helper function in the dramch module. */
- drmach_name2type =
- (int (*)(char *))kobj_getsymvalue("drmach_name2type_idx", 0);
-
- if (drmach_name2type == NULL)
- return (-1);
-
- return ((*drmach_name2type)(name));
-}
-
-void
-startup_platform(void)
-{
- /* set per platform constants for mutex backoff */
- mutex_backoff_base = 2;
- mutex_cap_factor = 64;
-}
-
-/*
- * KDI functions - used by the in-situ kernel debugger (kmdb) to perform
- * platform-specific operations. These functions execute when the world is
- * stopped, and as such cannot make any blocking calls, hold locks, etc.
- * promif functions are a special case, and may be used.
- */
-
-static void
-starcat_system_claim(void)
-{
- lbolt_debug_entry();
-
- prom_interpret("sigb-sig! my-sigb-sig!", OBP_SIG, OBP_SIG, 0, 0, 0);
-}
-
-static void
-starcat_system_release(void)
-{
- prom_interpret("sigb-sig! my-sigb-sig!", OS_SIG, OS_SIG, 0, 0, 0);
-
- lbolt_debug_return();
-}
-
-void
-plat_kdi_init(kdi_t *kdi)
-{
- kdi->pkdi_system_claim = starcat_system_claim;
- kdi->pkdi_system_release = starcat_system_release;
-}
-
-/*
- * This function returns 1 if large pages for kernel heap are supported
- * and 0 otherwise.
- *
- * Currently we disable lp kmem support if kpr is going to be enabled
- * because in the case of large pages hat_add_callback()/hat_delete_callback()
- * cause network performance degradation
- */
-int
-plat_lpkmem_is_supported(void)
-{
- extern int segkmem_reloc;
-
- if (kernel_cage_enable && (ncpunode >= 32 || segkmem_reloc == 1))
- return (0);
-
- return (1);
-}
diff --git a/usr/src/uts/sun4u/starcat/platmod/Makefile b/usr/src/uts/sun4u/starcat/platmod/Makefile
deleted file mode 100644
index b451e7e09a..0000000000
--- a/usr/src/uts/sun4u/starcat/platmod/Makefile
+++ /dev/null
@@ -1,98 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of the sun4u starcat platform
-# module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = platmod
-OBJECTS = $(STARCAT_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(STARCAT_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_MISC_DIR)/$(MODULE)
-PLAT_DIR = .
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Override defaults
-#
-CLEANFILES += $(PLATLIB)
-
-#
-# Define targets
-#
-ALL_TARGET = $(PLATLIB)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-unused-variable
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-$(PLATLIB): $(OBJECTS)
- $(BUILD.SO) $(OBJECTS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/sc_gptwocfg/Makefile b/usr/src/uts/sun4u/starcat/sc_gptwocfg/Makefile
deleted file mode 100644
index f43cf2136a..0000000000
--- a/usr/src/uts/sun4u/starcat/sc_gptwocfg/Makefile
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of the sc_gptwocfg
-# miscellaneous module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = sc_gptwocfg
-OBJECTS = $(SC_GPTWO_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SC_GPTWO_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE) -I../sys -I$(UTSBASE)/sun4u/starcat/sys
-CERRWARN += -_gcc=-Wno-uninitialized
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Nmisc/gptwocfg -Nmisc/gptwo_cpu -Nmisc/gptwo_pci -Ndrv/iosram
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/schpc/Makefile b/usr/src/uts/sun4u/starcat/schpc/Makefile
deleted file mode 100644
index 4bf42c1438..0000000000
--- a/usr/src/uts/sun4u/starcat/schpc/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# This makefile drives the production of the Starcat domain
-# side Hot Plug Controller Driver.
-#
-# Starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = schpc
-OBJECTS = $(SCHPC_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SCHPC_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/sun4u/starcat/io
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Nmisc/mboxsc -Nmisc/hpcsvc -Ndrv/iosram
-
-#
-# Turn on doubleword alignment for 64 bit registers
-#
-CFLAGS += -dalign
-
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/sckmdrv/Makefile b/usr/src/uts/sun4u/starcat/sckmdrv/Makefile
deleted file mode 100644
index 385b6977be..0000000000
--- a/usr/src/uts/sun4u/starcat/sckmdrv/Makefile
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# This makefile drives the production of the Starcat IPsec
-# Key Management driver.
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = sckmdrv
-OBJECTS = $(SCKMDRV_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SCKMDRV_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_DRV_DIR)/$(MODULE)
-CONF_SRCDIR = $(UTSBASE)/sun4u/starcat/io
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY) $(SRC_CONFFILE)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Nmisc/mboxsc
-
-#
-# Turn on doubleword alignment for 64 bit registers
-#
-CFLAGS += -dalign
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/scosmb/Makefile b/usr/src/uts/sun4u/starcat/scosmb/Makefile
deleted file mode 100644
index 56fb23fa46..0000000000
--- a/usr/src/uts/sun4u/starcat/scosmb/Makefile
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of the scosmb miscellaneous module.
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = scosmb
-OBJECTS = $(SCOSMB_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(SCOSMB_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_STARCAT_MISC_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-uninitialized
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Nmisc/mboxsc
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/sys/Makefile b/usr/src/uts/sun4u/starcat/sys/Makefile
deleted file mode 100644
index a0737ba647..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/Makefile
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-UTSBASE = ../../..
-
-#
-# include global definitions
-#
-include ../Makefile.starcat
-
-#
-# Override defaults.
-#
-FILEMODE = 644
-
-HDRS=
-
-
-CHKHDRS= axq.h dman.h domaind.h drmach.h \
- iosramio.h iosramreg.h iosramvar.h \
- sc_cvc.h sc_cvcio.h \
- sckm_msg.h sckm_io.h
-
-STARHDRS= $(UTSBASE)/sun4u/ngdr/sys/dr.h \
- $(UTSBASE)/sun4u/ngdr/sys/dr_util.h
-
-ROOTHDRS= $(HDRS:%=$(USR_STARCAT_ISYS_DIR)/%)
-
-ROOTDIR= $(ROOT)/usr/share/src
-ROOTDIRS= $(ROOTDIR)/uts $(ROOTDIR)/uts/$(PLATFORM)
-
-CHECKHDRS= $(HDRS:%.h=%.check) \
- $(CHKHDRS:%.h=%.check) \
- $(STARHDRS:%.h=%.check)
-
-.KEEP_STATE:
-
-.PARALLEL: $(CHECKHDRS) $(ROOTHDRS)
-
-install_h: $(ROOTDIRS) .WAIT $(ROOTHDRS) $(ROOTLINK)
-
-check: $(CHECKHDRS)
-
-#
-# install rules
-#
-$(USR_STARCAT_ISYS_DIR)/%: % $(USR_STARCAT_ISYS_DIR)
- $(INS.file)
-
-FRC:
-
-include ../Makefile.targ
diff --git a/usr/src/uts/sun4u/starcat/sys/axq.h b/usr/src/uts/sun4u/starcat/sys/axq.h
deleted file mode 100644
index d91d445839..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/axq.h
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_AXQ_H
-#define _SYS_AXQ_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* AXQ register offset constant */
-#define AXQ_REG_OFFSET 0x20
-#define AXQ_REGOFF(idx) ((idx) * AXQ_REG_OFFSET)
-
-/*
- * AXQ system register offsets
- * Each Starcat AXQ asic instance is logically
- * associated with each slot in the expander board.
- * Slot 0 is the full slot (or full bandwidth slot)
- * and Slot1 is the half slot (or half bandwidth slot).
- * Some system registers are only accessible in certain
- * slot type.
- */
-
-/* domain control register (slot0 & slot1) */
-#define AXQ_SLOT0_DOMCTRL AXQ_REGOFF(0x1)
-#define AXQ_SLOT1_DOMCTRL AXQ_REGOFF(0x2)
-
-/* cpu2ssc intr register */
-#define AXQ_SLOT_CPU2SSC_INTR AXQ_REGOFF(0x3)
-
-/* performance counters (one set per slot) */
-#define AXQ_SLOT0_PERFCNT_SEL AXQ_REGOFF(0x9)
-#define AXQ_SLOT0_PERFCNT0 AXQ_REGOFF(0xA)
-#define AXQ_SLOT0_PERFCNT1 AXQ_REGOFF(0xB)
-#define AXQ_SLOT0_PERFCNT2 AXQ_REGOFF(0xC)
-#define AXQ_SLOT1_PERFCNT_SEL AXQ_REGOFF(0x8)
-#define AXQ_SLOT1_PERFCNT0 AXQ_REGOFF(0xD)
-#define AXQ_SLOT1_PERFCNT1 AXQ_REGOFF(0xE)
-#define AXQ_SLOT1_PERFCNT2 AXQ_REGOFF(0xF)
-
-/* CASM slots (for both slot0 & slot1) */
-#define AXQ_CASM_SLOT_START AXQ_REGOFF(0x10)
-#define AXQ_CASM_SLOT_END AXQ_REGOFF(0x21)
-
-/* CDC registers (only available in slot0) */
-#define AXQ_SLOT0_CDC_ADR_TEST AXQ_REGOFF(0x2C)
-#define AXQ_SLOT0_CDC_CTL_TEST AXQ_REGOFF(0x2D)
-#define AXQ_SLOT0_CDC_DATA_WR3 AXQ_REGOFF(0x2E)
-#define AXQ_SLOT0_CDC_DATA_WR2 AXQ_REGOFF(0x2F)
-#define AXQ_SLOT0_CDC_DATA_WR1 AXQ_REGOFF(0x30)
-#define AXQ_SLOT0_CDC_DATA_WR0 AXQ_REGOFF(0x31)
-#define AXQ_SLOT0_CDC_CNT_TEST AXQ_REGOFF(0x32)
-#define AXQ_SLOT0_CDC_RD_DATA3 AXQ_REGOFF(0x33)
-#define AXQ_SLOT0_CDC_RD_DATA2 AXQ_REGOFF(0x34)
-#define AXQ_SLOT0_CDC_RD_DATA1 AXQ_REGOFF(0x35)
-#define AXQ_SLOT0_CDC_RD_DATA0 AXQ_REGOFF(0x36)
-
-/* NASM registers */
-#define AXQ_SLOT0_NASM AXQ_REGOFF(0x37)
-#define AXQ_SLOT1_NASM AXQ_REGOFF(0x38)
-
-#define AXQ_NASM_TYPE_IO 0
-#define AXQ_NASM_TYPE_SLOT0_CMMU 1
-#define AXQ_NASM_TYPE_WIB 2
-#define AXQ_NASM_TYPE_WIB_STRIPED 3
-#define AXQ_NASM_TYPE_SHIFT 5
-
-/* SDI Timeout register */
-#define AXQ_SLOT_SDI_TIMEOUT_RD AXQ_REGOFF(0x2A)
-#define AXQ_SLOT_SDI_TIMEOUT_RDCLR AXQ_REGOFF(0x2B)
-
-/*
- * Bits for domain control register
- */
-#define AXQ_DOMCTRL_BUSY 0x1
-#define AXQ_DOMCTRL_PAUSE 0x10
-#define AXQ_DOMCTRL_PIOFIX 0x40
-
-/*
- * Bits for CDC registers
- */
-/* CDC control test register */
-#define AXQ_CDC_TMODE_WR 0x20000
-#define AXQ_CDC_TMODE_RDCMP 0x40000
-#define AXQ_CDC_TMODE_WR_RDCMP0 0x60000
-#define AXQ_CDC_TMODE_WR_RDCMP1 0x80000
-#define AXQ_CDC_DATA_ECC_CHK_EN 0x10000
-#define AXQ_CDC_ADR_PAR_CHK_EN 0x08000
-#define AXQ_CDC_DATA_ECC_GEN_EN 0x04000
-#define AXQ_CDC_ADR_PAR_GEN_EN 0x02000
-#define AXQ_CDC_DATA2PAR_MUX_SEL_DATA 0x00800
-#define AXQ_CDC_ADR2SRAM_MUX_SEL_TEST 0x00080
-#define AXQ_CDC_ADR_INCR_XOR_CTRL 0x00010
-#define AXQ_CDC_DIS 0x00001
-
-/* CDC Address Test register */
-#define AXQ_CDC_ADR_TEST_EN 0x80000
-
-/* CDC counter test register */
-#define AXQ_CDC_CNT_TEST_DONE 0x80000000
-
-/*
- * Bits for CPU to SSC interrupt register
- */
-#define AXQ_CPU2SSC_INTR_PEND 0x80000000
-
-/*
- * Each AXQ instance has one pcr (performance control
- * register) controlling 3 pics (performance instru-
- * mentation counter). pic0 and pic1 are similar
- * and have identical inputs to their muxes. pic2
- * only counts the clock.
- */
-
-/* Bit masks for selecting pic mux input */
-#define FREEZE_CNT 0x0
-#define COUNT_CLK 0x1
-#define HA_INPUT_FIFO 0x2
-#define HA_INTR_INFO 0x3
-#define HA_PIO_FIFO 0x4
-#define HA_ADR_FIFO_LK3 0x5
-#define HA_ADR_FIFO_LK2 0x6
-#define HA_ADR_FIFO_LK1 0x7
-#define HA_ADR_FIFO_LK0 0x8
-#define HA_DUMP_Q 0x9
-#define HA_RD_F_STB_Q 0xA
-#define HA_DP_WR_Q 0xB
-#define HA_INT_Q 0xC
-#define HA_WRB_Q 0xD
-#define HA_WR_MP_Q 0xE
-#define HA_WRTAG_Q 0xF
-#define HA_WT_WAIT_FIFO 0x10
-#define HA_WRB_STB_FIFO 0x11
-#define HA_AP0_Q 0x12
-#define HA_AP1_Q 0x13
-#define HA_NEW_WR_Q 0x14
-#define HA_DP_RD_Q 0x15
-#define HA_UNLOCK_Q 0x16
-#define HA_CDC_UPD_Q 0x17
-#define HA_DS_Q 0x18
-#define HA_UNLK_WAIT_Q 0x19
-#define HA_RD_MP_Q 0x1A
-#define L2_IO_Q 0x1B
-#define L2_SB_Q 0x1C
-#define L2_RA_Q 0x1D
-#define L2_HA_Q 0x1E
-#define L2_SA_Q 0x1F
-#define RA_WAIT_FIFO 0x20
-#define RA_WRB_INV_FIFO 0x21
-#define RA_WRB_FIFO 0x22
-#define RA_CC_PTR_FIFO 0x23
-#define RA_IO_PTR_FIFO 0x24
-#define RA_INT_PTR_FIFO 0x25
-#define RA_RP_Q 0x26
-#define RA_WRB_RP_Q 0x27
-#define RA_DP_Q 0x28
-#define RA_DP_STB_Q 0x29
-#define RA_GTARG_Q 0x2A
-#define SDC_RECV_Q 0x2B
-#define SDC_REDIR_IO_Q 0x2C
-#define SDC_REDIR_SB_Q 0x2D
-#define SDC_OUTB_IO_Q 0x2E
-#define SDC_OUTB_SB_Q 0x2F
-#define SA_ADD1_INPUT_Q 0x30
-#define SA_ADD2_INPUT_Q 0x31
-#define SA_INV_Q 0x32
-#define SA_NO_INV_Q 0x33
-#define SA_INT_DP_Q 0x34
-#define SA_DP_Q 0x35
-#define SL_WRTAG_Q 0x36
-#define SL_RTO_DP_Q 0x37
-#define SYSREG_INPUT_Q 0x38
-#define SDI_SYS_STATUS1 0x39
-#define SDI_SYS_STATUS0 0x3A
-#define CDC_HITS 0x3B
-#define TOTAL_CDC_READ 0x3C
-#define HA_WATRANID_SD 0x3D
-#define HA_STB_SD 0x3E
-#define HA_L2_IRQ_SD 0x3F
-#define HA_SL_WRTAG_SD 0x40
-#define AA_HOME_CC_FULL 0x41
-#define AA_HOME_IO_FULL 0x42
-#define AA_SLAVE_FULL 0x43
-#define AA_RP_FULL 0x44
-
-/* Shift definitions into pcr for programming pics */
-#define AXQ_PIC_SHIFT 7
-
-/* event constants */
-#define AXQ_NUM_EVENTS 0x45
-#define AXQ_PIC0_1_NUM_EVENTS 0x45
-#define AXQ_PIC2_NUM_EVENTS 0x2
-#define AXQ_NUM_PICS 3
-#define AXQ_PIC_CLEAR_MASK 0x7F
-
-/* AXQ constants */
-#define SLOT0_AXQ 0
-#define SLOT1_AXQ 1
-#define AXQ_MAX_EXP 18
-#define AXQ_MAX_SLOT_PER_EXP 2
-#define AXQ_CDC_SRAM_SIZE 0x40000
-#define AXQ_CDC_FLUSH_WAIT 4
-#define AXQ_INTR_PEND_WAIT 10
-#define AXQ_NASM_SIZE 256
-
-/*
- * Struct element describing a eventname and
- * its pcr-mask.
- */
-typedef struct axq_event_mask {
- char *event_name;
- uint64_t pcr_mask;
-} axq_event_mask_t;
-
-/*
- * NASM RAM system register for reading
- */
-typedef union {
- struct axq_nasm_read {
- uint32_t pad : 16;
- uint32_t valid : 1;
- uint32_t addr : 8;
- uint32_t data : 7;
- } bit;
- uint32_t val;
-} axq_nasm_read_u;
-
-/*
- * NASM RAM system register for reading
- */
-typedef union {
- struct axq_nasm_write {
- uint32_t pad : 16;
- uint32_t addr : 8;
- uint32_t rw : 1;
- uint32_t data : 7;
- } bit;
- uint32_t val;
-} axq_nasm_write_u;
-
-
-/*
- * Global data structure that is used to
- * export certain axq registers in
- * local space. Right now, the only
- * register we want to access in local space
- * is the cheetah2ssc interrupt reg. There
- * could be more in future.
- */
-struct axq_local_regs {
- kmutex_t axq_local_lock;
- int initflag;
- caddr_t laddress;
- ddi_acc_handle_t ac;
- volatile uint32_t *axq_cpu2ssc_intr;
-};
-
-/*
- * axq soft state data structure.
- */
-struct axq_soft_state {
- dev_info_t *dip; /* devinfo of myself */
- uint32_t portid; /* port id */
- uint32_t expid; /* expander id */
- uchar_t slotnum; /* slot 0 or 1 */
- caddr_t address; /* mapped devnode addr property */
- ddi_acc_handle_t ac0; /* access handle for reg0 mapping */
- uint64_t axq_phyaddr; /* physical address of conf space */
- kmutex_t axq_lock; /* mutex protecting this softstate */
-
- volatile uint32_t *axq_domain_ctrl;
-
- /* CASM register slots */
- volatile uint32_t *axq_casm_slot[18];
-
- /* NASM register */
- volatile uint32_t *axq_nasm;
-
- /* CDC registers (only in slot0) */
- volatile uint32_t *axq_cdc_addrtest;
- volatile uint32_t *axq_cdc_ctrltest;
- volatile uint32_t *axq_cdc_datawrite0;
- volatile uint32_t *axq_cdc_datawrite1;
- volatile uint32_t *axq_cdc_datawrite2;
- volatile uint32_t *axq_cdc_datawrite3;
- volatile uint32_t *axq_cdc_counter;
- volatile uint32_t *axq_cdc_readdata0;
- volatile uint32_t *axq_cdc_readdata1;
- volatile uint32_t *axq_cdc_readdata2;
- volatile uint32_t *axq_cdc_readdata3;
-
- /* performance counters */
- volatile uint32_t *axq_pcr;
- volatile uint32_t *axq_pic0;
- volatile uint32_t *axq_pic1;
- volatile uint32_t *axq_pic2;
- kstat_t *axq_counters_ksp; /* perf counter kstat */
-
- /* SDI timeout register */
- volatile uint32_t *axq_sdi_timeout_rd;
- volatile uint32_t *axq_sdi_timeout_rdclr;
-
- uint32_t axq_cdc_state; /* CDC state - enabled/disabled */
- int paused; /* AXQ_DOMCTRL_PAUSE asserted */
-
-#ifndef _AXQ_LOCAL_ACCESS_SUPPORTED
- /*
- * No local access for cpu2ssc intr
- * Need to provide per instance explicit expander addressing
- */
- volatile uint32_t *axq_cpu2ssc_intr;
-#endif /* _AXQ_LOCAL_ACCESS_SUPPORTED */
-};
-
-/*
- * Public interface
- */
-extern int axq_cdc_flush(uint32_t, int, int);
-extern int axq_cdc_flush_all();
-extern int axq_cdc_disable_flush_all();
-extern void axq_cdc_enable_all();
-extern int axq_iopause_enable_all(uint32_t *);
-extern void axq_iopause_disable_all();
-extern uint32_t axq_casm_read(uint32_t, uint32_t, int);
-extern int axq_casm_write(uint32_t, uint32_t, int, uint32_t);
-extern int axq_casm_write_all(int, uint32_t);
-extern int axq_do_casm_rename_script(uint64_t **, int, int);
-extern int axq_cpu2ssc_intr(uint8_t);
-extern uint32_t axq_read_sdi_timeout_reg(uint32_t, uint32_t, int);
-extern int axq_nasm_read(uint32_t expid, uint32_t slot, uint32_t nasm_entry,
- uint32_t *data);
-extern int axq_nasm_write(uint32_t expid, uint32_t slot, uint32_t nasm_entry,
- uint32_t data);
-extern int axq_nasm_write_all(uint32_t nasm_entry, uint32_t data);
-extern void axq_array_rw_enter(void);
-extern void axq_array_rw_exit(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_AXQ_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/dman.h b/usr/src/uts/sun4u/starcat/sys/dman.h
deleted file mode 100644
index 22dca3c4d0..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/dman.h
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * ****** NOTICE **** This header file is maintained in the SMS gate,
- * ****** NOTICE **** the ON gate, and the ssc driver gate. Any changes
- * ****** NOTICE **** to it must also be made to in all gates.
- */
-
-#ifndef _DMAN_H
-#define _DMAN_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Ethernet stuff
- */
-
-#define ETHERHEADER_SIZE (sizeof (struct ether_header))
-typedef struct ether_header ehdr_t;
-typedef struct ether_addr eaddr_t;
-#define IS_BROADCAST(eap) \
- (ether_cmp(eap, &etherbroadcast) == 0)
-#define IS_MULTICAST(eap) \
- ((eap->ether_addr_octet[0] & 01) == 1)
-#define IS_UNICAST(eap) \
- (!IS_BROADCAST(eap) && !IS_MULTICAST(eap))
-
-#define MAN_IS_DATA(mp) ((DB_TYPE(mp) == M_DATA) || \
- ((DB_TYPE(mp) == M_PROTO) && \
- (DL_PRIM(mp) == DL_UNITDATA_IND)))
-
-#define MAN_ADDRL (sizeof (uint16_t) + ETHERADDRL)
-
-/*
- * Private DLPI full dlsap address format - stolen from eri.h
- */
-typedef struct man_dladdr_s {
- struct ether_addr dl_phys;
- uint16_t dl_sap;
-} man_dladdr_t;
-
-#define put_ether_type(ptr, value) {\
- ((uint8_t *)(&((ehdr_t *)ptr)->ether_type))[0] = \
- ((uint16_t)value & 0xff00) >> 8; \
- ((uint8_t *)(&((ehdr_t *)ptr)->ether_type))[1] = (value & 0xff); }
-#define ether_bcopy(a, b) (bcopy((caddr_t)a, (caddr_t)b, 6))
-
-#define MAN_MAX_EXPANDERS 18
-#define MAN_MAX_DESTS 38 /* (MAN_NUM_EXPANDERS * 2) + 2 */
-#define MAN_DEST_ARRAY_SIZE (MAN_MAX_DESTS * sizeof (man_dest_t))
-#define TRUE 1
-#define FALSE 0
-
-/*
- * Caller IDs for man_sendit processing decision on canput failure.
- */
-#define MAN_UPPER 0x1
-#define MAN_LOWER 0x2
-
-/*
- * MAN device information structure, one per man instance
- *
- * global list pointed to by MAN_XX_head
- */
-typedef struct man_s {
- struct man_s *man_next; /* next in list of devices */
- dev_info_t *man_dip; /* devinfo for this device */
- int man_meta_ppa; /* mxx device minor */
- major_t man_meta_major; /* mxx device major # */
- struct man_pg_s *man_pg; /* Pathgroups for this inst */
- int man_refcnt; /* DL_ATTACHes to us */
- int man_suspended; /* DDI_SUSPEND on device */
- kstat_t *man_ksp; /* meta interface statistics */
- int man_eaddr_v; /* ether addr valid */
- eaddr_t man_eaddr; /* active ether addr */
- /*
- * Failover timers, used by man_dest_t.
- */
- int32_t man_init_time; /* init time in usecs */
- int32_t man_linkcheck_time; /* linkcheck time in usecs */
- int32_t man_linkstale_time; /* linkstale time in usecs */
- int32_t man_linkstale_retries; /* linkstale retries/probes */
- int32_t man_dr_delay; /* DR retry delay in usecs */
- int32_t man_dr_retries; /* DR retries on EAGAIN errs */
- int32_t man_kstat_waittime; /* kstat_wait time in usecs */
- int32_t man_dlpireset_time; /* dlpireset time in usecs */
-} man_t;
-
-/*
- * MAN link state definitions
- */
-#define MAN_LINKUNKNOWN 0x0
-#define MAN_LINKINIT 0x1
-#define MAN_LINKGOOD 0x2
-#define MAN_LINKSTALE 0x3
-#define MAN_LINKFAIL 0x4
-
-/*
- * MAN timer types and times.
- */
-#define MAN_TIMER_INIT 0x1
-#define MAN_TIMER_LINKCHECK 0x2
-#define MAN_TIMER_DLPIRESET 0x4
-#define MAN_INIT_TIME 1000000 /* 1 sec in usecs */
-#define MAN_LINKCHECK_TIME 30000000 /* 30 secs in usecs */
-#define MAN_LINKSTALE_TIME 1000000 /* 1 secs in usecs */
-#define MAN_LINKSTALE_RETRIES 10 /* send 10 probes */
-#define MAN_KSTAT_WAITTIME 300000 /* 0.3 secs in usecs */
-#define MAN_DLPIRESET_TIME 5000000 /* 5 secs in usecs */
-#define MAN_MAX_DLPIERRORS 10 /* 10 dlpi errors */
-
-/*
- * MAN DR variables
- */
-#define MAN_DR_DELAY 200000 /* 1/5th sec in usecs */
-#define MAN_DR_RETRIES 150 /* DR retries on EAGAIN errs */
-
-/*
- * Device info - this must stay 64 bit aligned.
- */
-typedef struct md_s {
- major_t mdev_major; /* Driver major */
- uint32_t mdev_ppa; /* Driver instance */
- uint32_t mdev_exp_id; /* Containing expander in domain */
- uint32_t mdev_state; /* Device state */
-} man_dev_t;
-
-/*
- * mdev_state definitions
- */
-#define MDEV_UNASSIGNED 0x0 /* Path assigned to a destination */
-#define MDEV_ASSIGNED 0x1 /* Path assigned to a destination */
-#define MDEV_ACTIVE 0x2 /* Path actively in use for dest */
-#define MDEV_FAILED 0x4 /* Failure detected in past. */
-
-/*
- * MAN lower multiplexor data structure
- */
-typedef struct man_dest_s {
- uint_t md_state; /* state of this destination */
- struct manstr_s *md_msp; /* containing upper STREAM structure */
- queue_t *md_rq; /* upper read queue */
- queue_t *md_wq; /* lower write queue for active path */
- man_dev_t md_device; /* Device from active path. */
- int md_pg_id; /* pathgroup for destination */
- eaddr_t md_dst_eaddr; /* Destinations ether address */
- eaddr_t md_src_eaddr; /* Our ether address */
- int md_dlpistate; /* DLPI State of netdev below us */
- int md_muxid; /* muxid of netdev linked below us */
- void * md_switch_id; /* ID of switch request */
- kmutex_t md_lock; /* Lock for md_dmp_* */
- mblk_t *md_dmp_head; /* deferred mblk list head */
- mblk_t *md_dmp_tail; /* deferred mblk list tail */
- size_t md_dmp_count; /* bytes in deferred mblk list */
- ulong_t md_switches; /* # of failover switches */
- time_t md_lastswitch; /* time of last switch */
- timeout_id_t md_bc_id; /* qbufcall timeout id */
- /*
- * Failover variables, only valid for active path.
- */
- timeout_id_t md_lc_timer_id; /* qtimeout ID */
- int md_linkstate; /* link state */
- ulong_t md_lastrcvcnt; /* snapshot of packet count */
- ulong_t md_rcvcnt; /* current packet count */
- ulong_t md_linkfails; /* # of AP link failures */
- ulong_t md_linkstales; /* # of AP link stales */
- int32_t md_linkstale_retries; /* # of probes to send */
- ulong_t md_icmpv4probes; /* # of ICMPv4 probes sent */
- ulong_t md_icmpv6probes; /* # of ICMPv6 probes sent */
- int md_link_updown_msg; /* Last up/down message */
- int md_dlpierrors; /* # of DLPI errors */
-} man_dest_t;
-
-/*
- * md_state values
- */
-#define MAN_DSTATE_NOTPRESENT 0x0 /* Destination doesnt exist */
-#define MAN_DSTATE_INITIALIZING 0x1 /* Initialize lower stream for dest */
-#define MAN_DSTATE_READY 0x2 /* Destination lower stream exists */
-#define MAN_DSTATE_PLUMBING 0x4 /* lower stream being switched */
-#define MAN_DSTATE_CLOSING 0x8 /* lower stream closing */
-#define MAN_DSTATE_BUSY (MAN_DSTATE_PLUMBING|MAN_DSTATE_CLOSING)
-
-/*
- * md_link_updwon_msg states.
- */
-#define MAN_LINK_UP_MSG 0x0 /* Last msg emitted was "Link up" */
-#define MAN_LINK_DOWN_MSG 0x1 /* Last msg emitted was "Link down" */
-
-/*
- * Upper per-stream instance state information.
- *
- * Each instance is dynamically allocated at open() and free'd at close().
- * Each per-stream instance points to at most one per-device structure
- * using the ms_manp field. All instances are threaded together into one
- * list of active instances ordered on sequence of opens.
- */
-typedef struct manstr_s {
- struct manstr_s *ms_next; /* next in list of streams */
- man_t *ms_manp; /* MAN device info pointer */
- man_dest_t *ms_destp; /* Optimization if only one ms_dests */
- man_dest_t *ms_dests; /* lower streams */
- int ms_flags; /* State for this MAN upper stream */
- queue_t *ms_rq; /* MAN upper read queue */
- int ms_minor; /* minor number of this stream */
- t_uscalar_t ms_sap; /* SAP bound to (if DL_BOUND) */
- int ms_dlpistate; /* DLPI State of this MAN instance */
- major_t ms_meta_maj; /* mxx device major # */
- int ms_meta_ppa; /* mxx device minor # */
- mblk_t *ms_dl_mp; /* list of DLPI ATTACH/BIND rqsts */
- mblk_t *ms_dlioc_mp; /* list of DL_IOC rqsts */
- uint_t ms_dp; /* # of pending DL_DETACH_REQs */
- ulong_t ms_switches; /* number of switches so far */
-} manstr_t;
-
-/*
- * ms_flags values.
- */
-#define MAN_SFLAG_FAST 0x1 /* M_DATA fastpath mode */
-#define MAN_SFLAG_RAW 0x2 /* M_DATA plain raw mode */
-#define MAN_SFLAG_ALLPHYS 0x4 /* promiscuous mode */
-#define MAN_SFLAG_ALLMULTI 0x8 /* enable all multicast addresses */
-#define MAN_SFLAG_ALLSAP 0x10 /* enable all ether type values */
-#define MAN_SFLAG_CKSUM 0x20 /* enable hardware tcp checksumming */
-#define MAN_SFLAG_MULTI 0x40 /* enable multicast addresses */
-#define MAN_SFLAG_SERLPBK 0x80 /* enable SERDES looopback (DIAG) */
-#define MAN_SFLAG_MACLPBK 0x100 /* enable MAC int loopback (DIAG) */
-
-#define MAN_SFLAG_PROMISC (MAN_SFLAG_ALLPHYS|MAN_SFLAG_ALLMULTI| \
- MAN_SFLAG_ALLSAP)
-#define MAN_SFLAG_CLOSING 0x200 /* Stream in process of closing */
-#define MAN_SFLAG_CLOSE_DONE 0x400 /* Stream in process of closing */
-#define MAN_SFLAG_CONTROL 0x800 /* Stream is control stream */
-
-/*
- * Paths in pathgroup lists.
- */
-typedef struct mpa_s {
- struct mpa_s *mp_next; /* Next in linked list */
- man_dev_t mp_device; /* Device for this path */
- kstat_named_t *mp_last_knp; /* last named kstats from mp_phys_ksp */
- time_t mp_lru; /* Last time used */
-} man_path_t;
-
-/*
- * Pathgroup list, one per destination ID. Each pathgroup connects
- * to one destination. Hence we put that destination ethernet address
- * here. It is read from here and stored in man_dest_t.md_dst_eaddr
- * each time a new path is switched to.
- */
-typedef struct man_pg_s {
- struct man_pg_s *mpg_next;
- int mpg_flags;
- uint_t mpg_pg_id;
- uint_t mpg_man_ppa; /* MAN instance for pathgroup */
- eaddr_t mpg_dst_eaddr;
- man_path_t *mpg_pathp;
-} man_pg_t;
-/*
- * mpg_pg_flags fields.
- */
-#define MAN_PG_IDLE 0x0
-#define MAN_PG_SWITCHING 0x1
-
-/*
- * MAN IOCTL Definitions.
- */
-#define MIOC ('M'<< 16)
-#define MAN_SETPATH (MIOC|0x1)
-#define MAN_GETEADDR (MIOC|0x2)
-#define MAN_SET_LINKCHECK_TIME (MIOC|0x3)
-#define MAN_SET_SC_IPADDRS (MIOC|0x4)
-#define MAN_SET_SC_IP6ADDRS (MIOC|0x8)
-
-/*
- * Pathgroup assignment data structure - this must stay 64 bit aligned.
- */
-typedef struct mi_path_t {
- uchar_t mip_cmd; /* Cmd for this pathgroup */
- uchar_t pad1[3];
- uint32_t mip_man_ppa; /* Man instance to apply cmd to */
- uint32_t mip_pg_id; /* pathgroup ID this path is for */
- eaddr_t mip_eaddr; /* Eaddr for this destination */
- uchar_t pad2[2];
- man_dev_t mip_devs[MAN_MAX_DESTS]; /* Array of devices */
- uint32_t mip_ndevs; /* #devs at mip_devs */
-} mi_path_t;
-
-#define MI_PATH_READ 0x0 /* Fill in devs for destID */
-#define MI_PATH_ASSIGN 0x1 /* Assign devs for destID */
-#define MI_PATH_ACTIVATE 0x2 /* Mark a dev as active for destID */
-#define MI_PATH_DEACTIVATE 0x3 /* Deactivate active dev for destID */
-#define MI_PATH_UNASSIGN 0x4 /* Unassign assigned dev for destID */
-#define MI_PATH_ADD 0x5 /* Just Add devs for destID */
-
-/*
- * Linkcheck time assignment data structure - this must stay 64 bit aligned.
- */
-typedef struct mi_time_t {
- int32_t mtp_man_ppa; /* Man instance to apply cmd to */
- int32_t mtp_time; /* Time in usecs to */
-} mi_time_t;
-
-/*
- * SC IP address assignment data structure. See man_pinger().
- */
-typedef struct man_sc_ipaddrs_s {
- in_addr_t ip_other_sc_ipaddr;
- in_addr_t ip_my_sc_ipaddr;
-} man_sc_ipaddrs_t;
-
-/*
- * SC IPv6 address assignment data structure. See man_pinger().
- */
-typedef struct man_sc_ip6addrs_s {
- in6_addr_t ip6_other_sc_ipaddr;
- in6_addr_t ip6_my_sc_ipaddr;
-} man_sc_ip6addrs_t;
-
-/*
- * Array of dests to apply operation to.
- */
-typedef struct man_adest_s {
- int a_man_ppa; /* man instance */
- int a_pg_id; /* pg_id of dests */
- uint32_t a_exp_id; /* Used for DR requests */
- man_dev_t a_sf_dev; /* Switch from device */
- man_dev_t a_st_dev; /* Switch to device */
- man_dest_t *a_mdp; /* array of dests for mw_type */
- uint_t a_ndests; /* size of array */
-} man_adest_t;
-
-/*
- * work structure for MAN background thread.
- */
-typedef struct man_work_s {
- struct man_work_s *mw_next; /* next request on q */
- queue_t *mw_q; /* For qwait-ers */
- int mw_type; /* work request type */
- int mw_flags; /* asycn/sync flags */
- int mw_status; /* Status of work request */
- man_adest_t mw_arg; /* work argument */
- kcondvar_t mw_cv; /* sender sleeps here */
-} man_work_t;
-
-/*
- * Values for mw_flags
- */
-#define MAN_WFLAGS_NOWAITER 0x0
-#define MAN_WFLAGS_CVWAITER 0x1
-#define MAN_WFLAGS_QWAITER 0x2
-#define MAN_WFLAGS_DONE 0x4
-
-/*
- * Values for mw_type.
- */
-#define MAN_WORK_OPEN_CTL 0x0 /* Open the control stream */
-#define MAN_WORK_CLOSE_CTL 0x1 /* Open the control stream */
-#define MAN_WORK_SWITCH 0x2 /* Dest requests switch to new path */
-#define MAN_WORK_PATH_UPDATE 0x3 /* pathgrp info changed, update dests */
-#define MAN_WORK_CLOSE 0x4 /* Close destinations */
-#define MAN_WORK_CLOSE_STREAM 0x5 /* man_close()-ing upper stream */
-#define MAN_WORK_DRATTACH 0x6 /* DR attached new IO board */
-#define MAN_WORK_DRDETACH 0x7 /* DR detached an IO board */
-#define MAN_WORK_STOP 0x8 /* Stop and exit */
-#define MAN_WORK_DRSWITCH 0x9 /* Switch path prior to DRDETACH */
-#define MAN_WORK_KSTAT_UPDATE 0xA /* Take kstat snapshot */
-
-#define MAN_IDNUM (13138) /* module ID number */
-#define MAN_MINPSZ (0) /* min packet size */
-#define MAN_MAXPSZ (INFPSZ) /* max packet size */
-#define MAN_HIWAT (64 * 1024) /* hi-water mark */
-#define MAN_LOWAT (1) /* lo-water mark */
-#define MAN_MEDIA "Ethernet" /* media type */
-
-/*
- * State definitions for man_config_state
- */
-#define MAN_UNCONFIGURED 0x0 /* Attached but never opened */
-#define MAN_CONFIGURING 0x1 /* First open */
-#define MAN_CONFIGURED 0x2 /* Done configuring */
-#define MAN_FINI 0x3 /* cv_waiting in _fini() */
-
-/*
- * IOSRAM definitions
- */
-#define MANC_VERSION 0x1
-#define IOSRAM_KEY_MANC (('M'<<24)|('A'<<16)|('N'<<8)|'C')
-#define IOSRAM_KEY_SCMD (('S'<<24)|('C'<<16)|('M'<<8)|'D')
-#define IOSRAM_KEY_MDSC (('M'<<24)|('D'<<16)|('S'<<8)|'C')
-#define MAN_IOSRAM_TIMEOUT 10000 /* 10 secs in ms */
-
-typedef struct manc_s {
- uint32_t manc_magic; /* MANC_MAGIC */
- uint32_t manc_version; /* MANC_VERSION */
- uint32_t manc_csum; /* TBD */
- int manc_ip_type; /* AF_INET or AF_INET6 */
- in_addr_t manc_dom_ipaddr; /* Domains IP address */
- in_addr_t manc_dom_ip_netmask; /* Domains IP netmask */
- in_addr_t manc_sc_ipaddr; /* SC's IP address */
- in6_addr_t manc_dom_ipv6addr; /* Domain's IPv6 address */
- in6_addr_t manc_dom_ipv6_netmask; /* Domain's IPv6 netmask */
- in6_addr_t manc_sc_ipv6addr; /* SC's IPv6 address */
- eaddr_t manc_dom_eaddr; /* 48 bit ethernet address */
- eaddr_t manc_sc_eaddr; /* 48 bit ethernet address */
- uint32_t manc_iob_bitmap; /* initial ioboard list */
- uchar_t manc_golden_iob; /* post selected ioboard */
-} manc_t;
-
-
-typedef struct man_mb_s {
- uint32_t mb_status;
- uint32_t mb_exp_id;
-} man_mbox_msg_t;
-
-typedef struct ml_s {
- struct ml_s *l_next;
- int l_muxid;
- queue_t *l_rq;
- queue_t *l_wq;
-} man_linkrec_t;
-
-typedef struct man_workq_s {
- man_work_t *q_work;
- kcondvar_t q_cv;
- bufcall_id_t *q_id;
-} man_workq_t;
-
-/*
- * PCI stuff.
- */
-
-/*
- * Misc defines
- */
-#define MAN_DDI_BUFLEN 128
-#define MAN_DEVTYPE_PROP "device_type"
-#define MAN_REG_PROP "reg"
-#define MAN_PORTID_PROP "portid"
-#define MAN_DEVTYPE_PCI "pci"
-#define MAN_PCI_B_CSR_BASE 0x00700000
-#define MAN_SCHIZO_MASK 0xF
-#define MAN_SCHIZO_0_ID 0xC
-
-/* ------------------------------------------------------------------------- */
-/*
- * Patchable debug flag.
- * Set this to nonzero to enable error messages.
- */
-
-/*
- * The following parameters may be configured by the user. If they are not
- * configured by the user, the values will be based on the capabilities of
- * the transceiver.
- * The value "MAN_NOTUSR" is ORed with the parameter value to indicate values
- * which are NOT configured by the user.
- */
-
-/* command */
-
-#define MAN_ND_GET ND_GET
-#define MAN_ND_SET ND_SET
-#define MAN_NOTUSR 0x0f000000
-#define MAN_MASK_1BIT 0x1
-#define MAN_MASK_2BIT 0x3
-#define MAN_MASK_8BIT 0xff
-
-typedef struct param_s {
- uint32_t param_min;
- uint32_t param_max;
- uint32_t param_val;
- char *param_name;
-} param_t;
-
-#if defined(DEBUG)
-#define MAN_DBG(flag, msg) { if (man_debug&flag) (void) printf msg; }
-#define MAN_DBGCALL(flag, func) { if (man_debug&flag) (void) func; }
-
-#define MAN_INIT 0x00000001
-#define MAN_OCLOSE 0x00000002
-#define MAN_CONFIG 0x00000004
-#define MAN_SWITCH 0x00000008
-#define MAN_IOSRAM 0x00000010
-#define MAN_LINK 0x00000020
-#define MAN_PATH 0x00000040
-#define MAN_DEST 0x00000080
-#define MAN_KSTAT 0x00000100
-#define MAN_KSTAT2 0x00000200
-#define MAN_DDI 0x000001FF
-
-#define MAN_UWPUT 0x00000400
-#define MAN_LWPUT 0x00000800
-#define MAN_LRPUT 0x00001000
-#define MAN_LRPUT2 0x00002000
-#define MAN_PUT (MAN_UWPUT | MAN_LWPUT | MAN_LRPUT)
-#define MAN_UWSRV 0x00004000
-#define MAN_LWSRV 0x00008000
-#define MAN_LRSRV 0x00010000
-#define MAN_DATA 0x00020000
-#define MAN_DLPI 0x00040000
-#define MAN_SRV (MAN_UWSRV | MAN_LWSRV | MAN_LRSRV)
-#define MAN_STREAMS (MAN_PUT | MAN_SRV | MAN_OCLOSE)
-
-#define MAN_CALLS (MAN_DDI | MAN_STREAMS)
-
-#define MAN_STATE 0x00080000
-#define MAN_WARN 0x00100000
-#define MAN_DEBUG (MAN_CALLS | MAN_WARN | MAN_STATE)
-#define MAN_KMEM 0x00200000
-#define MAN_DR 0x00400000
-#define MAN_ALL 0xFFFFFFFF
-
-#else
-
-#define MAN_DBG(flag, msg)
-#define MAN_DBGCALL(flag, func)
-
-#endif /* DEBUG */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DMAN_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/domaind.h b/usr/src/uts/sun4u/starcat/sys/domaind.h
deleted file mode 100644
index f06c41236f..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/domaind.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 2000 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _SYS_DOMAIND_H
-#define _SYS_DOMAIND_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/sysmacros.h>
-#include <sys/cpu_sgnblk_defs.h>
-
-typedef struct domain_data {
- uint32_t magic; /* magic number */
- uint8_t version; /* version number */
- uint8_t keyswitch; /* virtual SC keyswitch */
- uint32_t master_sc_ip; /* IP address of master SC */
- uint32_t leds; /* software LEDs */
- sig_state_t domain_state; /* domain state */
- uint32_t heartbeat; /* domain heartbeat */
- cpuset_t cpus_present; /* CPU's present in this domain */
- sig_state_t cpu_sigs[NCPU]; /* state for present CPUs */
- uint32_t resetinfo_off[NCPU]; /* resetinfo offsets */
- uint8_t _reserved[16]; /* word aligned */
-} domain_data_t;
-
-/*
- * Unique ID for domain data IOSRAM chunk
- */
-#define DOMD_MAGIC 0x444F4D44 /* 'D' 'O' 'M' 'D' */
-
-/*
- * offsets
- */
-#define DOMD_MAGIC_OFFSET offsetof(domain_data_t, magic)
-#define DOMD_VERSION_OFFSET offsetof(domain_data_t, version)
-#define DOMD_KEYSWITCH_OFFSET offsetof(domain_data_t, keyswitch)
-#define DOMD_SCIP_OFFSET offsetof(domain_data_t, master_sc_ip)
-#define DOMD_LEDS_OFFSET offsetof(domain_data_t, leds)
-#define DOMD_DSTATE_OFFSET offsetof(domain_data_t, domain_state)
-#define DOMD_HEARTBEAT_OFFSET offsetof(domain_data_t, heartbeat)
-#define DOMD_CPUSPRESENT_OFFSET offsetof(domain_data_t, cpus_present)
-#define DOMD_CPUSIGS_OFFSET offsetof(domain_data_t, cpu_sigs)
-#define DOMD_RESETINFO_OFFSET offsetof(domain_data_t, resetinfo_off)
-
-/*
- * tod
- */
-#define TODSC_SET_THRESHOLD 30 /* in seconds */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_DOMAIND_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/dr_mbx.h b/usr/src/uts/sun4u/starcat/sys/dr_mbx.h
deleted file mode 100644
index efedb45b78..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/dr_mbx.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_DR_MBX_H
-#define _SYS_DR_MBX_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _KERNEL
-#include <sys/mboxsc.h>
-#endif /* _KERNEL */
-#include <post/scat_const.h>
-
-/* this version of the DR - SC mailbox interface */
-#define DRMBX_VERSION 0x0016
-
-#define DR_KEY(a, b, c, d) \
- (((uint_t)(a) << 24) | ((uint_t)(b) << 16) \
- | ((uint_t)(c) << 8) | ((uint_t)(d)))
-#define KEY_DRSC DR_KEY('D', 'R', 'S', 'C')
-#define KEY_SCDR DR_KEY('S', 'C', 'D', 'R')
-
-#define DRSC_TIMEOUT 30
-#define BD_TYPELEN 16
-#define DR_HPOPTLEN 512 /* maximum length of hpost options */
-
-/* Commands */
-#define DRMSG_BOARDEVENT 0x1 /* must be 0x1 in every vesion */
-#define DRMSG_MBOX_INIT 0x2 /* must be 0x2 in every version */
-#define DRMSG_ASSIGN 0x3
-#define DRMSG_UNASSIGN 0x4
-#define DRMSG_CLAIM 0x5
-#define DRMSG_UNCLAIM 0x6
-#define DRMSG_POWERON 0x7
-#define DRMSG_POWEROFF 0x8
-#define DRMSG_TESTBOARD 0x9
-#define DRMSG_ABORT_TEST 0xa
-#define DRMSG_SHOWBOARD 0xb
-#define DRMSG_UNCONFIG 0xc
-
-
-/* Test status definitions */
-#define DR_TEST_STATUS_UNKNOWN 0x1
-#define DR_TEST_STATUS_IPOST 0x2
-#define DR_TEST_STATUS_PASSED 0x3
-#define DR_TEST_STATUS_FAILED 0x4
-#define DR_TEST_STATUS_ABORTED 0x5
-
-/* Message reply status definitions */
-#define DRMSG_REPLY_OK 0x0
-#define DRMSG_REPLY_FAIL 0x1
-
-/* Error Code definitions */
-#define DRERR_NOACL 0x1 /* Board is not in domain's ACL */
-#define DRERR_NOT_ASSIGNED 0x2 /* Board isn't assigned to domain */
-#define DRERR_NOT_ACTIVE 0x3 /* Board is not active */
-#define DRERR_EMPTY_SLOT 0x4 /* The board (slot) is empty */
-#define DRERR_POWER_OFF 0x5 /* The specified board is powered off */
-#define DRERR_TEST_IN_PROGRESS 0x6 /* The board is being tested */
-#define DRERR_TESTING_BUSY 0x7 /* All SC test resources are in use */
-#define DRERR_TEST_REQUIRED 0x8 /* Board requires test prior to use */
-#define DRERR_UNAVAILABLE 0x9 /* Slot is not available to domain */
-#define DRERR_RECOVERABLE 0xa /* Failed, may safely retry */
-#define DRERR_UNRECOVERABLE 0xb /* Failed, resource unusable */
-
-/*
- * Protocol Header and message structure definitions
- */
-
-/* DR-SC Protocol Header */
-typedef struct {
- uint32_t message_id;
- uint16_t drproto_version;
- uint8_t command;
- uint8_t expbrd;
- uint8_t slot;
- uint8_t reply_status;
- uint8_t error_code;
- uint8_t pad[1]; /* explicit pad to 4 byte alignment */
-} dr_proto_hdr_t;
-
-/* Showboard reply structure (from SC) */
-typedef struct {
- uint8_t slot_empty :1,
- power_on :1,
- bd_assigned :1,
- bd_active :1,
- test_status :4;
- uint8_t test_level;
- char board_type[BD_TYPELEN];
-} dr_showboard_t;
-
-/* CPU Memory Controller constants and macros */
-#define DRMACH_MC_VALID_MASK (0x1ull << 63)
-#define DRMACH_MC_UK_MASK (0xFFFull << 41)
-#define DRMACH_MC_UM_MASK (0x1FFFFFull << 20)
-#define DRMACH_MC_LK_MASK (0xFull << 14)
-#define DRMACH_MC_LM_MASK (0xFull << 8)
-
-#define DRMACH_MC_UK(madr) (((madr) & DRMACH_MC_UK_MASK) >> 41)
-#define DRMACH_MC_UM_TO_PA(madr) (((madr) & DRMACH_MC_UM_MASK) << 6)
-#define DRMACH_MC_LM_TO_PA(madr) (((madr) & DRMACH_MC_LM_MASK) >> 2)
-#define DRMACH_MC_PA_TO_UM(pa) (((pa) >> 6) & DRMACH_MC_UM_MASK)
-#define DRMACH_MC_PA_TO_LM(pa) (((pa) << 2) & DRMACH_MC_LM_MASK)
-
-/* Claim/Unclaim/Unconfig request structures */
-typedef struct {
- uint8_t valid :1,
- unused :2,
- slice :5;
-} dr_memslice_t;
-
-/*
- * Since uint64_t can't be used in DR mailbox messages due to alignment and
- * backwards compatibility issues, the 64 bit MADR and MACR register values must
- * be broken into high and low uint32_t values.
- */
-#define DRMACH_MCREG_TO_U64(mcreg) (((uint64_t)mcreg.hi) << 32 | \
- ((uint64_t)mcreg.lo))
-#define DRMACH_U64_TO_MCREGHI(u64) ((uint32_t)((u64) >> 32))
-#define DRMACH_U64_TO_MCREGLO(u64) ((uint32_t)(u64))
-typedef struct {
- uint32_t hi;
- uint32_t lo;
-} dr_mcreg_t;
-
-/*
- * Each expander can contain S0_LPORT_COUNT memory controllers (each CPU has one
- * memory controller, and slot 1 doesn't support memory), and each controller
- * contains PMBANKS_PER_PORT * LMBANKS_PER_PMBANK (the total number of memory
- * banks supported by each controller) MADR registers
- */
-typedef struct {
- dr_mcreg_t madr[S0_LPORT_COUNT][PMBANKS_PER_PORT *
- LMBANKS_PER_PMBANK];
-} dr_memregs_t;
-
-typedef struct {
- dr_memslice_t mem_slice[18];
- uint8_t mem_clear;
- uint8_t pad[1]; /* explicit pad to 4 byte alignment */
- dr_memregs_t mem_regs[18];
-} dr_unclaim_t;
-
-typedef struct {
- dr_memslice_t mem_slice[18];
- uint8_t pad[2]; /* explicit pad to 4 byte alignment */
- dr_memregs_t mem_regs[18];
-} dr_claim_t;
-
-typedef struct {
- dr_memslice_t mem_slice[18];
- uint8_t pad[2]; /* explicit pad to 4 byte alignment */
- dr_memregs_t mem_regs[18];
-} dr_unconfig_t;
-
-/* CPU Portid macros */
-#define DRMBX_PORTID2EXP(cpu_portid) \
- (((cpu_portid) >> 5) & 0x1F)
-#define DRMBX_PORTID2SLOT(cpu_portid) \
- (((((cpu_portid) >> 4) & 0x7E) | (((cpu_portid) >> 3) & 0x01)) & 1)
-#define DRMBX_PORTID2AGID(cpu_portid) ((cpu_portid) & 0x1F)
-
-/* Test board request structure */
-typedef struct {
- uint32_t memaddrhi;
- uint32_t memaddrlo;
- uint32_t memlen;
- uint16_t cpu_portid;
- uint8_t force :1,
- immediate :1,
- reserved :6;
- char hpost_opts[DR_HPOPTLEN];
-} dr_testboard_req_t;
-
-/* Test board reply structure (from SC) */
-typedef struct {
- uint32_t memaddrhi;
- uint32_t memaddrlo;
- uint32_t memlen;
- uint16_t cpu_portid;
- uint8_t cpu_recovered :1,
- test_status :4,
- reserved :3;
-} dr_testboard_reply_t;
-
-/* Test Abort structure (bi-directional) */
-typedef struct {
- uint32_t memaddrhi;
- uint32_t memaddrlo;
- uint32_t memlen;
- uint16_t cpu_portid;
-} dr_abort_test_t;
-
-
-/* Board event structure (from SC) */
-typedef struct {
- uint16_t initialized :1,
- board_insertion :1,
- board_removal :1,
- slot_assign :1,
- slot_unassign :1,
- slot_avail :1,
- slot_unavail :1,
- power_on :1,
- power_off :1,
- reserved :7;
-} dr_boardevent_t;
-
-/*
- * NOTE: The structures in this union all require 4 byte alignment or less. It
- * is forbidden to add any structure that requires 8 byte alignment, as doing so
- * will alter the dr_mbox_msg_t structure, thereby breaking compatibility with
- * older software. (Since the dr_proto_hdr_t structure is 12 bytes long, it
- * can't be followed immediately by an 8 byte aligned structure, and the
- * compiler will implicitly insert 4 padding bytes.)
- */
-typedef union {
- dr_showboard_t dm_sb;
- dr_unclaim_t dm_ur;
- dr_claim_t dm_cr;
- dr_unconfig_t dm_uc;
- dr_testboard_req_t dm_tb;
- dr_testboard_reply_t dm_tr;
- dr_abort_test_t dm_ta;
- dr_boardevent_t dm_be;
-} dr_msg_t;
-
-typedef struct {
- dr_proto_hdr_t p_hdr;
- dr_msg_t msgdata;
-} dr_mbox_msg_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_DR_MBX_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/drmach.h b/usr/src/uts/sun4u/starcat/sys/drmach.h
deleted file mode 100644
index e1389977f8..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/drmach.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_DRMACH_H_
-#define _SYS_DRMACH_H_
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/types.h>
-#include <sys/memlist.h>
-#include <sys/processor.h>
-#include <sys/sbd_ioctl.h>
-#include <sys/sysevent.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Starcat platform specific routines currently only defined
- * in starcat.c and referenced by DR.
- */
-extern int plat_max_boards();
-extern int plat_max_cpu_units_per_board();
-extern int plat_max_io_units_per_board();
-
-#define MAX_BOARDS plat_max_boards()
-#define MAX_CPU_UNITS_PER_BOARD plat_max_cpu_units_per_board()
-#define MAX_MEM_UNITS_PER_BOARD 1
-#define MAX_IO_UNITS_PER_BOARD plat_max_io_units_per_board()
-#define MAX_CMP_UNITS_PER_BOARD 4
-#define MAX_CORES_PER_CMP 2
-
-/* flags for drmach_configure() and drmach_unconfigure() */
-#define DRMACH_DEVI_FORCE 1
-#define DRMACH_DEVI_REMOVE 2
-
-/* returned with drmach_board_find_devices callback */
-#define DRMACH_DEVTYPE_CMP "cmp"
-#define DRMACH_DEVTYPE_CPU "cpu"
-#define DRMACH_DEVTYPE_MEM "memory"
-#define DRMACH_DEVTYPE_PCI "pci"
-#define DRMACH_DEVTYPE_SBUS "sbus"
-#define DRMACH_DEVTYPE_WCI "wci"
-
-/* number of bytes in smallest coherency unit of this machine */
-#define DRMACH_COHERENCY_UNIT 64
-
-typedef void *drmachid_t;
-
-typedef struct {
- boolean_t assigned;
- boolean_t powered;
- boolean_t configured;
- boolean_t busy;
- boolean_t empty;
- sbd_cond_t cond;
- char type[MAXNAMELEN];
- char info[MAXPATHLEN]; /* TODO: what size? */
-} drmach_status_t;
-
-typedef struct {
- int size;
- char *copts;
-} drmach_opts_t;
-
-extern sbd_error_t *drmach_copy_rename_init(
- drmachid_t dst_id, uint64_t dst_slice_offset,
- drmachid_t src_id, struct memlist *src_copy_ml,
- drmachid_t *pgm_id);
-extern sbd_error_t *drmach_copy_rename_fini(drmachid_t id);
-extern void drmach_copy_rename(drmachid_t id);
-
-extern sbd_error_t *drmach_pre_op(int cmd, drmachid_t id,
- drmach_opts_t *opts);
-extern sbd_error_t *drmach_post_op(int cmd, drmachid_t id,
- drmach_opts_t *opts);
-
-extern sbd_error_t *drmach_board_assign(int bnum, drmachid_t *id);
-extern sbd_error_t *drmach_board_connect(drmachid_t id,
- drmach_opts_t *opts);
-extern sbd_error_t *drmach_board_deprobe(drmachid_t id);
-extern sbd_error_t *drmach_board_disconnect(drmachid_t id,
- drmach_opts_t *opts);
-extern sbd_error_t *drmach_board_find_devices(drmachid_t id, void *a,
- sbd_error_t *(*found)(void *a, const char *, int, drmachid_t));
-extern int drmach_board_lookup(int bnum, drmachid_t *id);
-extern sbd_error_t *drmach_passthru(drmachid_t id,
- drmach_opts_t *opts);
-
-extern sbd_error_t *drmach_board_name(int bnum, char *buf, int buflen);
-
-extern sbd_error_t *drmach_board_poweroff(drmachid_t id);
-extern sbd_error_t *drmach_board_poweron(drmachid_t id);
-extern sbd_error_t *drmach_board_test(drmachid_t id, drmach_opts_t *opts,
- int force);
-
-extern sbd_error_t *drmach_board_unassign(drmachid_t id);
-
-extern sbd_error_t *drmach_configure(drmachid_t id, int flags);
-
-extern sbd_error_t *drmach_cpu_disconnect(drmachid_t id);
-extern sbd_error_t *drmach_cpu_get_id(drmachid_t id, processorid_t *cpuid);
-extern sbd_error_t *drmach_cpu_get_impl(drmachid_t id, int *ip);
-extern void drmach_cpu_flush_ecache_sync(void);
-
-extern sbd_error_t *drmach_get_dip(drmachid_t id, dev_info_t **dip);
-
-extern sbd_error_t *drmach_io_is_attached(drmachid_t id, int *yes);
-extern sbd_error_t *drmach_io_post_attach(drmachid_t id);
-extern sbd_error_t *drmach_io_post_release(drmachid_t id);
-extern sbd_error_t *drmach_io_pre_release(drmachid_t id);
-extern sbd_error_t *drmach_io_unrelease(drmachid_t id);
-
-extern sbd_error_t *drmach_mem_add_span(drmachid_t id,
- uint64_t basepa, uint64_t size);
-extern sbd_error_t *drmach_mem_del_span(drmachid_t id,
- uint64_t basepa, uint64_t size);
-extern sbd_error_t *drmach_mem_disable(drmachid_t id);
-extern sbd_error_t *drmach_mem_enable(drmachid_t id);
-extern sbd_error_t *drmach_mem_get_alignment(drmachid_t id, uint64_t *pa);
-extern sbd_error_t *drmach_mem_get_base_physaddr(drmachid_t id,
- uint64_t *pa);
-extern sbd_error_t *drmach_mem_get_memlist(drmachid_t id,
- struct memlist **ml);
-extern sbd_error_t *drmach_mem_get_size(drmachid_t id, uint64_t *bytes);
-extern sbd_error_t *drmach_mem_get_slice_size(drmachid_t id,
- uint64_t *bytes);
-extern processorid_t drmach_mem_cpu_affinity(drmachid_t id);
-extern int drmach_allow_memrange_modify(drmachid_t id);
-
-extern sbd_error_t *drmach_release(drmachid_t id);
-extern sbd_error_t *drmach_status(drmachid_t id, drmach_status_t *stat);
-extern sbd_error_t *drmach_unconfigure(drmachid_t id, int flags);
-extern int drmach_log_sysevent(int board, char *hint, int flag,
- int verbose);
-
-extern int drmach_verify_sr(dev_info_t *dip, int sflag);
-extern void drmach_suspend_last();
-extern void drmach_resume_first();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_DRMACH_H_ */
diff --git a/usr/src/uts/sun4u/starcat/sys/gptwo_pci.h b/usr/src/uts/sun4u/starcat/sys/gptwo_pci.h
deleted file mode 100644
index a5035f1cda..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/gptwo_pci.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_GPTWO_PCI_H
-#define _SYS_GPTWO_PCI_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Header file for the PCI/Schizo component to the
- * Safari Configurator (gptwo_cpu).
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/safari_pcd.h>
-
-gptwocfg_ops_cookie_t gptwocfg_alloc_pci_ops(int, int);
-gptwo_new_nodes_t *gptwo_configure_pci(dev_info_t *, spcd_t *, uint_t);
-dev_info_t *gptwo_prepare_pci(dev_info_t *);
-dev_info_t *gptwo_unconfigure_pci(dev_info_t *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_GPTWO_PCI_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/iosramio.h b/usr/src/uts/sun4u/starcat/sys/iosramio.h
deleted file mode 100644
index 2c04c7ee67..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/iosramio.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_IOSRAMIO_H
-#define _SYS_IOSRAMIO_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * data_valid flag values
- */
-#define IOSRAM_DATA_INVALID 0
-#define IOSRAM_DATA_VALID 1
-
-/*
- * int_pending flag values
- */
-#define IOSRAM_INT_NONE 0
-#define IOSRAM_INT_TO_SSC 1
-#define IOSRAM_INT_TO_DOM 2
-
-/*
- * IOSRAM control commands, for use in iosram_ctrl().
- */
-#define IOSRAM_CMD_CHUNKLEN 1
-
-/*
- * IOSRAM header control commands, for use in iosram_hdr_ctrl _only_ by the
- * Mailbox Protocol implementation
- */
-#define IOSRAM_HDRCMD_GET_SMS_MBOX_VER 1
-#define IOSRAM_HDRCMD_SET_OS_MBOX_VER 2
-#define IOSRAM_HDRCMD_REG_CALLBACK 3
-
-/*
- * Extern prototypes for kernel drivers/modules
- */
-extern int iosram_rd(uint32_t key, uint32_t off, uint32_t len, caddr_t dptr);
-extern int iosram_wr(uint32_t key, uint32_t off, uint32_t len, caddr_t dptr);
-extern int iosram_force_write(uint32_t key, uint32_t off, uint32_t len,
- caddr_t dptr);
-extern int iosram_get_flag(uint32_t key, uint8_t *data_valid,
- uint8_t *int_pending);
-extern int iosram_set_flag(uint32_t key, uint8_t data_valid,
- uint8_t int_pending);
-extern int iosram_send_intr();
-extern int iosram_register(uint32_t key, void (*handler)(), void *arg);
-extern int iosram_unregister(uint32_t key);
-extern int iosram_ctrl(uint32_t key, uint32_t cmd, void *arg);
-
-/*
- * This function is only intended to be called by DR.
- */
-extern int iosram_switchfrom(int instance);
-
-/*
- * The following functions are only to be used by the Mailbox Protocol
- * implementation.
- */
-extern int iosram_sema_acquire(uint32_t *);
-extern int iosram_sema_release(void);
-extern int iosram_hdr_ctrl(uint32_t cmd, void *arg);
-
-
-#if defined(DEBUG)
-
-/*
- * ioctls for testing purposes only
- */
-
-#define IOSRAM_IOC ('i' << 8)
-
-#define IOSRAM_RD (int)(IOSRAM_IOC|1)
-#define IOSRAM_WR (int)(IOSRAM_IOC|2)
-#define IOSRAM_GET_FLAG (int)(IOSRAM_IOC|3)
-#define IOSRAM_SET_FLAG (int)(IOSRAM_IOC|4)
-#define IOSRAM_TOC (int)(IOSRAM_IOC|5)
-#define IOSRAM_SEND_INTR (int)(IOSRAM_IOC|6)
-#define IOSRAM_REG_CBACK (int)(IOSRAM_IOC|7)
-#define IOSRAM_UNREG_CBACK (int)(IOSRAM_IOC|8)
-#define IOSRAM_PRINT_CBACK (int)(IOSRAM_IOC|9)
-#define IOSRAM_PRINT_STATE (int)(IOSRAM_IOC|10)
-#define IOSRAM_PRINT_LOG (int)(IOSRAM_IOC|11)
-#define IOSRAM_PRINT_FLAGS (int)(IOSRAM_IOC|12)
-#define IOSRAM_TUNNEL_SWITCH (int)(IOSRAM_IOC|13)
-#define IOSRAM_PRINT_STATS (int)(IOSRAM_IOC|14)
-#define IOSRAM_SEMA_ACQUIRE (int)(IOSRAM_IOC|15)
-#define IOSRAM_SEMA_RELEASE (int)(IOSRAM_IOC|16)
-
-
-/*
- * struct iosram_io:
- * Used for testing purposes to invoke IOSRAM internal
- * interface from user level via ioctl() interface.
- */
-typedef struct iosram_io {
- uint32_t cmd; /* read or write */
- uint32_t key; /* IOSRAM chunk key */
- uint32_t off; /* offset within IOSRAM chunk */
- uint32_t len; /* size of read or write */
- uint32_t bufp; /* buffer pointer */
- uint32_t retval; /* provided by driver */
- uint32_t data_valid; /* flag being get/set */
- uint32_t int_pending; /* flag being get/set */
-} iosram_io_t;
-
-#endif /* DEBUG */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_IOSRAMIO_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/iosramreg.h b/usr/src/uts/sun4u/starcat/sys/iosramreg.h
deleted file mode 100644
index 7aca9a1f12..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/iosramreg.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_IOSRAMREG_H
-#define _SYS_IOSRAMREG_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-/*
- * iosram_reg_t property (an array of following tuple/data)
- * address format
- * hi npt000ss bbbbbbbb dddddfff rrrrrrrr
- * mid hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
- * low llllllll llllllll llllllll llllllll
- *
- * size format
- * hi hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
- * low llllllll llllllll llllllll llllllll
- * n=0 if relocatable
- * p=1 if addressable region is prefetchable
- * t=1 if address region is aliased
- * ss=00 Config. space also n,p,t must be 0
- * =01 I/O space p must be 0
- * =10 32 bit address memory space
- * =11 64 bit address memory space
- * bbbbbbbb 8 bit bus number
- * ddddd 5 bit device number
- * fff 3 bit function number
- * rrrrrrrr 8 bit register number
- * hhhhhhhh 32 bit unsigned number
- * llllllll 32 bit unsigned number
- *
- * address: 64 bits memory space
- * hi 00000011 00000000 00000000 00000000
- * 0x03000000
- * mid 00000000 00000000 00000000 00000000
- * 0x00000000
- * low 00000000 00010000 00000000 00000000
- * 0x00100000
- * size
- * hi 00000000 00000000 00000000 00000000
- * low 00000000 00000011 11111111 11111111
- */
-
-typedef struct {
- uint32_t addr_hi;
- uint32_t addr_lo;
- uint32_t size;
-} iosram_reg_t;
-
-
-/*
- * SBBC access structures. Each SBBC register is 32 bits aligned on a 16
- * byte boundary. The iosram_sbbc_region structure should be mapped onto
- * the SBBC register space starting at 0x1000 to achieve correct alignment
- * between structure fields and SBBC registers.
- */
-typedef struct iosram_sbbcr {
- uint32_t reg; /* 32-bit register */
- uint32_t pad[3]; /* padding to fill out 16 bytes */
-} iosram_sbbcr_t;
-
-typedef struct iosram_sbbc_region {
- iosram_sbbcr_t synch[16]; /* 0x1000 - 10ff - semaphore region */
- iosram_sbbcr_t pad0[240]; /* 0x1100 - 1fff - padding */
- iosram_sbbcr_t p0_int_gen; /* 0x2000 - 200f - PCI port 0 */
- /* interrupt generation */
- iosram_sbbcr_t p1_int_gen; /* 0x2010 - 201f - PCI port 1 */
- /* interrupt generation */
- iosram_sbbcr_t pad1[48]; /* 0x2020 - 231f - padding */
- iosram_sbbcr_t int_status; /* 0x2320 - 232f - interrupt status */
- iosram_sbbcr_t int_enable; /* 0x2330 - 233f - interrupt enables */
-} iosram_sbbc_region_t;
-
-#define IOSRAM_SBBC_MAP_OFFSET 0x1000 /* offset of SBBC regs to be mapped */
-#define IOSRAM_SBBC_MAP_INDEX 0x1 /* address space set # for SBBC regs */
-#define IOSRAM_SBBC_INT0 0x01
-#define IOSRAM_SBBC_INT1 0x10
-
-/*
- * SBBC hardware semaphore access
- */
-
-/* indices into sbbc_region->synch array */
-#define IOSRAM_SEMA_SMS_IDX 0x1 /* when accessed by SMS */
-#define IOSRAM_SEMA_DOM_IDX 0x8 /* when accessed by domain */
-#define IOSRAM_SEMA_OBP_IDX 0xf /* when accessed by OBP */
-
-/* mask for bits used to encode how semaphore was acquired (bits 1-4) */
-#define IOSRAM_SEMA_MASK 0x1e
-
-/* read an write semaphore values using domain assigned register */
-#define IOSRAM_SEMA_RD(softp) ddi_get32((softp)->sbbc_handle, \
- &(softp->sbbc_region->synch[IOSRAM_SEMA_DOM_IDX].reg));
-#define IOSRAM_SEMA_WR(softp, v) ddi_put32((softp)->sbbc_handle, \
- &(softp->sbbc_region->synch[IOSRAM_SEMA_DOM_IDX].reg), v);
-
-#define IOSRAM_SEMA_IS_HELD(v) ((v) & 0x1)
-#define IOSRAM_SEMA_GET_IDX(v) (((v) & IOSRAM_SEMA_MASK) >> 1)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_IOSRAMREG_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/iosramvar.h b/usr/src/uts/sun4u/starcat/sys/iosramvar.h
deleted file mode 100644
index bada4f50d7..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/iosramvar.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_IOSRAMVAR_H
-#define _SYS_IOSRAMVAR_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Data sizes used by the original author
- */
-#ifndef UINT32SZ
-#define UINT32SZ sizeof (uint32_t)
-#define UINT64SZ sizeof (uint64_t)
-#endif
-
-/*
- * Values used for tunnel switching
- */
-#define OBP_TSWITCH_REQREPLY 0 /* request reply from SSC */
-#define OBP_TSWITCH_NOREPLY 1 /* don't wait for reply */
-#define IOSRAM_TSWITCH_RETRY 20 /* # of times to wait for */
- /* current tunnel switch to */
- /* end when starting a new */
- /* one */
-/*
- * When performing back-to-back tunnel switches, we have to make sure that
- * HWAD (the SC-side implementation) has time to find the new tunnel from
- * one switch before we invalidate it for the next switch. To ensure that,
- * we make sure that the time between consecutive tunnel switches is at
- * least twice the polling rate HWAD uses to detect the new tunnel.
- */
-#define IOSRAM_TSWITCH_DELAY_US 100000
-
-/*
- * Values used for hash table maintenance
- */
-#define IOSRAM_HASHSZ 0x20 /* # hash entries */
-#define IOSRAM_HASH(key) ((((key) >> 24) ^ ((key) >> 16) ^\
- ((key) >> 9) ^ (key)) & (IOSRAM_HASHSZ - 1))
-
-/*
- * A pair of flags is associated with each IOSRAM chunk in the IOSRAM TOC.
- * These flags are stored sequentially in the "SC Domain Communication Data"
- * ('SDCD') IOSRAM chunk. The data-valid/int-pending flags are one byte each
- * and stored sequentially with data-valid flag being the first. The following
- * macros define the offset of the flags for each IOSRAM chunk based upon its
- * location (index) in the IOSRAM TOC.
- */
-#define IOSRAM_DATAVALID_FLAGOFF(index) (2 * (index))
-#define IOSRAM_INTPENDING_FLAGOFF(index) (2 * (index) + 1)
-
-/*
- * IOSRAM node properties (per IOSRAM node)
- */
-#define IOSRAM_REG_PROP "reg"
-#define IOSRAM_TUNNELOK_PROP "tunnel-capable"
-
-/*
- * Other IOSRAM properties (on chosen node and parent hierarchy)
- */
-#define IOSRAM_CHOSEN_PROP "iosram"
-#define IOSRAM_PORTID_PROP "portid"
-
-/*
- * Interrupt priority (PIL) used for IOSRAM interrupts. The value 5 was
- * chosen somewhat arbitrarily based on the fact that it is higher than
- * disks and lower than networks.
- */
-#define IOSRAM_PIL 5
-
-/*
- * IOSRAM header structure, located at the beginning of IOSRAM.
- *
- * NOTE - New fields may be appended to this structure, but no existing fields
- * may be altered in any way!!!
- */
-typedef struct {
- uint32_t status;
- uint32_t version;
- uint32_t toc_offset;
- uint32_t sms_mbox_version;
- uint32_t os_mbox_version;
- uint32_t obp_mbox_version;
- uint32_t sms_change_mask;
- uint32_t os_change_mask;
-} iosram_hdr_t;
-
-/*
- * Values for the status field
- */
-#define IOSRAM_INVALID 0x494e5644 /* 'INVD' */
-#define IOSRAM_VALID 0x56414c44 /* 'VALD' */
-#define IOSRAM_INTRANSIT 0x494e5452 /* 'INTR' */
-
-/*
- * Maximum IOSRAM Protocol version understood by this implementation
- */
-#define IOSRAM_MAX_PROTOCOL_VERSION 1
-
-/*
- * Bit definitions for *_change_mask fields
- */
-#define IOSRAM_HDRFIELD_SMS_MBOX_VER 0x00000001
-#define IOSRAM_HDRFIELD_OS_MBOX_VER 0x00000002
-#define IOSRAM_HDRFIELD_TOC_INDEX 0x00000004
-
-/*
- * Macros used to access fields in the header
- */
-#define IOSRAM_GET_HDRFIELD32(softp, field) \
- (ddi_get32((softp)->handle, &((iosram_hdr_t *)(softp)->iosramp)->field))
-#define IOSRAM_SET_HDRFIELD32(softp, field, val) \
- (ddi_put32((softp)->handle, &((iosram_hdr_t *)(softp)->iosramp)->field,\
- (val)))
-
-/*
- * IOSRAM contains various data chunks and the key, location and size of
- * each IOSRAM chunk is communicated to the IOSRAM driver in the form of a
- * Table of Contents. This structre contains one entry for each IOSRAM
- * chunk, as well as an initial index entry. Each entry has the following
- * structure.
- *
- * NOTE - Although the unused field may be renamed for some use in the future,
- * no other modification to this structure is allowed!!!
- */
-
-typedef struct {
- uint32_t key; /* IOSRAM chunk key */
- uint32_t off; /* IOSRAM chunk starting offset */
- uint32_t len; /* IOSRAM chunk length */
- uint32_t unused; /* currently unused */
-} iosram_toc_entry_t;
-
-/*
- * Special values used in some TOC entries
- */
-#define IOSRAM_FLAGS_KEY 0x53444344 /* 'SDCD' - flags chunk key */
-#define IOSRAM_INDEX_KEY 0x494e4458 /* 'INDX' - index entry key */
-#define IOSRAM_INDEX_OFF 0xFFFFFFFF /* index entry offset */
-
-
-/*
- * IOSRAM flags structure. An array of these - one for every IOSRAM chunk - is
- * stored in the SDCD chunk.
- */
-typedef struct {
- uint8_t data_valid;
- uint8_t int_pending;
-} iosram_flags_t;
-
-/*
- * IOSRAM callback data structure
- */
-typedef struct {
- uchar_t busy; /* cback handler is active/busy */
- uchar_t unregister; /* delayed callback unregistration */
- void (*handler)(); /* cback handler */
- void *arg; /* cback handler arg */
-} iosram_cback_t;
-
-
-/*
- * IOSRAM per chunk state
- */
-typedef struct iosram_chunk {
- iosram_toc_entry_t toc_data; /* Data from TOC entry */
- iosram_cback_t cback; /* callback info */
- uint8_t *basep; /* kvaddr for this IOSRAM chunk */
- iosram_flags_t *flagsp;
- struct iosram_chunk *hash; /* next entry in the hash list */
-} iosram_chunk_t;
-
-
-/*
- * IOSRAM per instance state
- */
-
-typedef struct iosramsoft {
- struct iosramsoft *prev; /* ptr for linked list */
- struct iosramsoft *next; /* ptr for linked list */
-
- boolean_t suspended; /* TRUE if driver suspended */
- int instance; /* driver instance number */
- dev_info_t *dip; /* device information */
-
- uchar_t *iosramp; /* IOSRAM mapped vaddr */
- int iosramlen; /* IOSRAM length */
- int nchunks; /* # IOSRAM chunks */
- iosram_chunk_t *chunks; /* ptr to iosram_chunk array */
- iosram_chunk_t *flags_chunk; /* ptr to flags chunk */
- ddi_acc_handle_t handle; /* IOSRAM map handle */
-
- ddi_iblock_cookie_t real_iblk; /* real intr iblock cookie */
- ddi_iblock_cookie_t soft_iblk; /* soft intr iblock cookie */
- ddi_softintr_t softintr_id; /* soft interrupt ID */
- ushort_t intr_busy; /* softintr handler busy */
- ushort_t intr_pending; /* interrupt pending */
-
- int state; /* IOSRAM state (see below) */
- int portid; /* Card port ID for tswitch */
- uint32_t tswitch_ok; /* # successful tunnel switch */
- uint32_t tswitch_fail; /* # failed tunnel switch */
-
- ddi_acc_handle_t sbbc_handle; /* SBBC regs map handle */
- iosram_sbbc_region_t *sbbc_region; /* region of SBBC registers */
- uint32_t int_enable_sav; /* save int enable reg. on suspend */
- kmutex_t intr_mutex; /* real interrupt handler mutex */
-} iosramsoft_t;
-
-
-/* IOSRAM state value */
-#define IOSRAM_STATE_INIT 0x0001 /* initialization */
-#define IOSRAM_STATE_SLAVE 0x0002 /* SLAVE IOSRAM */
-#define IOSRAM_STATE_MASTER 0x0004 /* MASTER IOSRAM */
-#define IOSRAM_STATE_MAPPED 0x0008 /* IOSRAM mapped */
-
-#define IOSRAM_STATE_TSWITCH 0x0010 /* tunnel switch source/target */
-#define IOSRAM_STATE_DETACH 0x0020 /* IOSRAM instance being detached */
-
-
-#if DEBUG
-#define IOSRAM_STATS 1 /* enable IOSRAM statistics */
-#define IOSRAM_LOG 1 /* enable IOSRAM logging */
-#endif
-
-#if IOSRAM_STATS
-
-/*
- * IOSRAM statistics
- */
-struct iosram_stat {
- uint32_t read; /* calls to iosram_read */
- uint32_t write; /* calls to iosram_{force_}write */
- uint32_t getflag; /* calls to iosram_getflag */
- uint32_t setflag; /* calls to iosram_getflag */
- uint32_t tswitch; /* # tunnel switch */
- uint32_t callbacks; /* # callbacks invoked */
- uint32_t intr_recv; /* # interrupts received */
- uint32_t sintr_recv; /* # softintr received */
- uint32_t intr_send; /* # interrupts sent */
- uint64_t bread; /* # bytes read */
- uint64_t bwrite; /* # bytes written */
-};
-
-#define IOSRAM_STAT(field) iosram_stats.field++
-#define IOSRAM_STAT_ADD(field, amount) iosram_stats.field += (uint64_t)amount
-#define IOSRAM_STAT_SET(field, count) iosram_stats.field = (uint64_t)count
-
-#else /* !IOSRAM_STATS */
-
-#define IOSRAM_STAT(field)
-#define IOSRAM_STAT_ADD(field, amount)
-#define IOSRAM_STAT_SET(field, count)
-
-#endif /* !IOSRAM_STATS */
-
-
-#if IOSRAM_LOG
-
-/*
- * IOSRAM log related structures and extern declarations
- */
-
-#define IOSRAM_MAXLOG 64
-
-typedef struct {
- uint32_t seq; /* logseg# */
- clock_t tstamp; /* time stamp */
- caddr_t fmt; /* format ptr */
- intptr_t arg1; /* first arg */
- intptr_t arg2; /* second arg */
- intptr_t arg3; /* third arg */
- intptr_t arg4; /* fourth arg */
-} iosram_log_t;
-
-#define IOSRAMLOG(level, fmt, a1, a2, a3, a4) \
- if (iosram_log_level >= level) { \
- iosram_log(fmt, (intptr_t)a1, (intptr_t)a2, \
- (intptr_t)a3, (intptr_t)a4); \
- }
-
-extern int iosram_log_level;
-extern uint32_t iosram_logseq;
-extern iosram_log_t iosram_logbuf[IOSRAM_MAXLOG];
-extern void iosram_log(caddr_t, intptr_t, intptr_t, intptr_t, intptr_t);
-
-#else /* !IOSRAM_LOG */
-
-#define IOSRAMLOG(level, fmt, a1, a2, a3, a4)
-
-#endif /* !IOSRAM_LOG */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_IOSRAMVAR_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/mboxsc.h b/usr/src/uts/sun4u/starcat/sys/mboxsc.h
deleted file mode 100644
index 0f5f2eea3e..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/mboxsc.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _MBOXSC_H
-#define _MBOXSC_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This file defines the Starcat Domain Mailbox Interface, as implemented in
- * the mboxsc module.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-
-/*
- * Mailbox message types, for use in mboxsc_putmsg() and mboxsc_getmsg() calls.
- * NOTE: Clients should not use the MBOXSC_NUM_MSG_TYPES value, which
- * is used internally to simplify future code maintenance.
- */
-
-#define MBOXSC_MSG_REQUEST 0x01
-#define MBOXSC_MSG_REPLY 0x02
-#define MBOXSC_MSG_EVENT 0x04
-#define MBOXSC_NUM_MSG_TYPES 3
-
-/*
- * Mailbox directions, for use in mboxsc_init().
- */
-#define MBOXSC_MBOX_IN 0
-#define MBOXSC_MBOX_OUT 1
-
-
-#ifdef _KERNEL
-/*
- * Mailbox control commands, for use in mboxsc_ctrl().
- */
-#define MBOXSC_CMD_VERSION 1
-#define MBOXSC_CMD_MAXVERSION 2
-#define MBOXSC_CMD_MAXDATALEN 3
-#define MBOXSC_CMD_PUTMSG_TIMEOUT_RANGE 4
-#define MBOXSC_CMD_GETMSG_TIMEOUT_RANGE 5
-
-/*
- * The argument for the TIMEOUT_RANGE control commands is a pointer to one of
- * these.
- */
-typedef struct mboxsc_timeout_range {
- clock_t min_timeout;
- clock_t max_timeout;
-} mboxsc_timeout_range_t;
-
-/*
- * Mailbox interface functions available to in-kernel clients on Starcat
- * Domains.
- * NOTE: The timeout arguments to mboxsc_putmsg() and mboxsc_getmsg() are
- * interpreted as milliseconds.
- */
-extern int mboxsc_init(uint32_t key, int direction, void
- (*event_handler)(void));
-extern int mboxsc_fini(uint32_t key);
-extern int mboxsc_putmsg(uint32_t key, uint32_t type, uint32_t cmd,
- uint64_t *transid, uint32_t length, void *datap, clock_t timeout);
-extern int mboxsc_getmsg(uint32_t key, uint32_t *type, uint32_t *cmd,
- uint64_t *transid, uint32_t *length, void *datap, clock_t timeout);
-extern int mboxsc_ctrl(uint32_t key, uint32_t cmd, void *arg);
-extern clock_t mboxsc_putmsg_def_timeout(void);
-#define MBOXSC_PUTMSG_DEF_TIMEOUT mboxsc_putmsg_def_timeout()
-
-#ifdef DEBUG
-/*
- * The following commands may be passed in to the mboxsc_debug() function to
- * dump data to the console that wouldn't be available through normal
- * (non-debug) functions.
- */
-#define MBOXSC_PRNMBOX 1 /* display a particular mailbox */
-#define MBOXSC_PRNHASHTBL 2 /* display the whole hash table */
-#define MBOXSC_SETDBGMASK 3 /* set the debug mask */
-
-/*
- * Debugging interface routine.
- */
-extern int mboxsc_debug(int cmd, void *arg);
-
-#endif /* DEBUG */
-#endif /* _KERNEL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MBOXSC_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/mboxsc_impl.h b/usr/src/uts/sun4u/starcat/sys/mboxsc_impl.h
deleted file mode 100644
index 6b502d9c05..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/mboxsc_impl.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _MBOXSC_IMPL_H
-#define _MBOXSC_IMPL_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This file contains implementation details for the mboxsc API that need to
- * be shared amongst all implementations, but should be hidden from clients.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Version number of the current Mailbox Protocol implementation. This must
- * be updated whenever a new version of the Protocol is implemented.
- */
-#define MBOXSC_PROTOCOL_VERSION 1
-
-/*
- * Mailbox message header and checksum.
- */
-typedef struct {
- uint32_t msg_version;
- uint32_t msg_type;
- uint32_t msg_cmd;
- uint32_t msg_length;
- uint64_t msg_transid;
-} mboxsc_msghdr_t;
-
-typedef uint32_t mboxsc_chksum_t;
-
-/*
- * Constants for various aspects of the protocol.
- */
-#define MBOXSC_MSGHDR_SIZE (sizeof (mboxsc_msghdr_t))
-#define MBOXSC_CHKSUM_SIZE (sizeof (mboxsc_chksum_t))
-#define MBOXSC_PROTOCOL_SIZE (MBOXSC_MSGHDR_SIZE + MBOXSC_CHKSUM_SIZE)
-#define MBOXSC_MSGHDR_OFFSET (0)
-#define MBOXSC_DATA_OFFSET MBOXSC_MSGHDR_SIZE
-
-/*
- * Timeouts used for various mboxsc operations. All timeouts are provided
- * in microseconds.
- * XXX - Aside from the conversion factors, these values are currently
- * somewhat arbitrary, and may need significant modification.
- */
-#define MBOXSC_USECS_PER_SECOND (1000000L)
-#define MBOXSC_USECS_PER_MSEC (1000L)
-
-/*
- * The amount of time to sleep before retrying an IOSRAM operation that failed
- * because a tunnel switch was in progress.
- * Current value: 0.125 seconds
- */
-#define MBOXSC_EAGAIN_POLL_USECS (MBOXSC_USECS_PER_SECOND / 8)
-
-/*
- * The interval at which the data_valid flag should be polled for a change in
- * status after sending a message.
- * Current value: 0.010 seconds
- */
-#define MBOXSC_PUTMSG_POLL_USECS (MBOXSC_USECS_PER_SECOND / 100)
-
-/*
- * The polling rates for acquisition of the hardware lock used to synchronize
- * data_valid flag access.
- * Current values: 0.025 seconds
- */
-#define MBOXSC_HWLOCK_POLL_USECS (MBOXSC_USECS_PER_SECOND / 40)
-
-/*
- * Minimum, default, and maximum times for mboxsc_putmsg to spend trying to send
- * a message before giving up.
- * Current value: 0.050, 10, and 1800 seconds, respectively
- * 1800 seconds (30 minutes) is a few minutes shy of the maximum
- * value of a clock_t in units of microseconds.
- */
-#define MBOXSC_PUTMSG_MIN_TIMEOUT_USECS (MBOXSC_USECS_PER_SECOND / 20)
-#define MBOXSC_PUTMSG_DEF_TIMEOUT_USECS (MBOXSC_USECS_PER_SECOND * 10)
-#define MBOXSC_PUTMSG_MAX_TIMEOUT_USECS (MBOXSC_USECS_PER_SECOND * 60 * 30)
-
-#define MBOXSC_PUTMSG_MIN_TIMEOUT_MSECS \
- (MBOXSC_PUTMSG_MIN_TIMEOUT_USECS / MBOXSC_USECS_PER_MSEC)
-#define MBOXSC_PUTMSG_DEF_TIMEOUT_MSECS \
- (MBOXSC_PUTMSG_DEF_TIMEOUT_USECS / MBOXSC_USECS_PER_MSEC)
-#define MBOXSC_PUTMSG_MAX_TIMEOUT_MSECS \
- (MBOXSC_PUTMSG_MAX_TIMEOUT_USECS / MBOXSC_USECS_PER_MSEC)
-
-/*
- * Minimum and maximum times for mboxsc_getmsg to spend trying to receive a
- * message before giving up.
- * Current value: 0 and 1800 seconds, respectively
- * 1800 seconds (30 minutes) is a few minutes shy of the maximum
- * value of a clock_t in units of microseconds.
- */
-#define MBOXSC_GETMSG_MIN_TIMEOUT_USECS (MBOXSC_USECS_PER_SECOND * 0)
-#define MBOXSC_GETMSG_MAX_TIMEOUT_USECS (MBOXSC_USECS_PER_SECOND * 60 * 30)
-
-#define MBOXSC_GETMSG_MIN_TIMEOUT_MSECS \
- (MBOXSC_GETMSG_MIN_TIMEOUT_USECS / MBOXSC_USECS_PER_MSEC)
-#define MBOXSC_GETMSG_MAX_TIMEOUT_MSECS \
- (MBOXSC_GETMSG_MAX_TIMEOUT_USECS / MBOXSC_USECS_PER_MSEC)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MBOXSC_IMPL_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/post/scat_asicbrd_types.h b/usr/src/uts/sun4u/starcat/sys/post/scat_asicbrd_types.h
deleted file mode 100644
index 4b8f21a38a..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/post/scat_asicbrd_types.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 1998-2000 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _SCAT_ASICBRD_TYPES_H
-#define _SCAT_ASICBRD_TYPES_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This file contains enumerations of the board and asic types used
- * in Starcat.
- */
-
-/*
- * POST DEVELOPERS:
- * This file is copied to the OS workspace, and thus must abide by the OS
- * coding standards. This file must always pass cstyle and hdrchk.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
- /* Enumeration of Starcat positional board types: */
-typedef enum {
- XCBT_SYS0 = 0, /* Full-slot system board, e.g., CPU */
- XCBT_SYS1 = 1, /* Half-slot system board, e,g., I/O */
- XCBT_EXB = 2, /* Expander board */
- XCBT_CSB = 3, /* Centerplane support board */
- XCBT_CP = 4, /* Half-centerplane */
- XCBT_SC = 5, /* System controller */
-
- XCBT_COUNT /* Size of array */
-} xcbrdtype_t;
-#define IS_VALID_XCBT(xcbt) \
- ((((int)(xcbt)) >= 0) && (((int)(xcbt)) < (int)XCBT_COUNT))
-
- /* Enumeration of Starcat L1 system board types */
-typedef enum {
- XCL1BT_CPU, /* Slot 0. Four CPUs, memory */
- XCL1BT_WIB, /* Slot 0. Two CPUs & mem, two WCIs */
- XCL1BT_hPCI, /* Slot 1. Two Schizos. "Hotplug PCI" */
- XCL1BT_cPCI, /* Slot 1. Two Schizos. */
- XCL1BT_MAXCAT, /* Slot 1. Two CPUs, no memory */
- XCL1BT_WIBPCI, /* Slot 1, hybrid hPCI / WCI */
- XCL1BT_sPCI, /* Slot 1. Two Schizos. "Standard PCI" */
-
- XCL1BT_COUNT
-} xcl1bt_t;
-#define IS_VALID_XCL1BT(l1bt) \
- ((((int)(l1bt)) >= 0) && (((int)(l1bt)) < (int)XCL1BT_COUNT))
-
-
- /*
- * Arbitrarily chosen enumeration for the Starcat asics, so we
- * can build some tables & bitmasks. Make sure any changes are
- * reflected in the initialization of xc_asic_name[] in libxcpost.
- */
-typedef enum {
- XCASICT_AXQ,
- XCASICT_SDI,
- XCASICT_AMX,
- XCASICT_RMX,
- XCASICT_DARB,
- XCASICT_DMX,
- XCASICT_CSBCBR, /* Mode of SDI CSB Console Bus Repeater */
- XCASICT_EXBCBR, /* Mode of SDI EXB Console Bus Repeater */
-
- XCASICT_AR,
- XCASICT_DX,
- XCASICT_SDC,
- XCASICT_DCDS,
- XCASICT_L1EPLD,
-
- XCASICT_L1BBC,
- XCASICT_EXBBBC,
- XCASICT_CSBBBC,
-
- XCASICT_CPU,
- XCASICT_RIO,
- XCASICT_SCHIZO,
- XCASICT_WCI,
-
- XCASICT_CBH,
- XCASICT_SCM,
-
- XCASICT_COUNT /* Size of array */
-} xcasictype_t;
-#define IS_VALID_XCASICT(asict) \
- ((((int)(asict)) >= 0) && (((int)(asict)) < (int)XCASICT_COUNT))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_SCAT_ASICBRD_TYPES_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/post/scat_const.h b/usr/src/uts/sun4u/starcat/sys/post/scat_const.h
deleted file mode 100644
index 02a2ca814f..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/post/scat_const.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 1996-2000 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _SCAT_CONST_H
-#define _SCAT_CONST_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This file contains definitions fundamental to the Starcat architecture;
- * how many exps, how many of each asic type, etc.
- */
-
-/*
- * POST DEVELOPERS:
- * This file is copied to the OS workspace, and thus must abide by the OS
- * coding standards. This file must always pass cstyle and hdrchk.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define SSC_COUNT (2)
-#define SSC_MAX (SSC_COUNT - 1)
-#define IS_VALID_SSC(ssc) ((ssc) >= 0 && (ssc) < SSC_COUNT)
-
-#define EXP_COUNT (18)
-#define EXP_MAX (EXP_COUNT - 1)
-#define IS_VALID_EXP(exp) ((exp) >= 0 && (exp) < EXP_COUNT)
-
-#define EXB_COUNT EXP_COUNT
-#define EXB_MAX EXP_MAX
-#define IS_VALID_EXB(exb) IS_VALID_EXP(exb)
-
-#ifdef No_More_No_More
- /* Support this for awhile until we purge everywhere: */
-#define NODE_COUNT EXP_COUNT
-#define NODE_MAX EXP_MAX
-#define IS_VALID_NODE(node) IS_VALID_EXP(node)
-#endif /* No_More_No_More */
-
- /* Slots are L1 boards within an expander */
-#define SLOT_COUNT (2)
-#define SLOT_MAX (SLOT_COUNT - 1)
-#define IS_VALID_SLOT(slot) ((slot) >= 0 && (slot) < SLOT_COUNT)
-
-
-#ifdef REFERENCE
- /* XXX: temporary definitions till Dan decides what he wants */
-#define L1_COUNT (SLOT_COUNT * EXP_COUNT)
-#define L1_MAX (L1_COUNT - 1)
-#define IS_VALID_L1_BOARD(brd) ((brd) >= 0 && (brd) < L1_COUNT)
-
-#define S0_PROC_COUNT (4) /* max procs on slot 0 L1 board */
-#define S1_PROC_COUNT (2) /* max procs on slot 1 L1 board */
-
-#define SPM_COUNT (S0_PROC_COUNT + S1_PROC_COUNT)
-
-#define PROC_COUNT ((S0_PROC_COUNT * EXP_COUNT) + \
- (S1_PROC_COUNT * EXP_COUNT))
-#define PROC_MAX (PROC_COUNT - 1)
-#define IS_VALID_PROC(proc) ((proc) >= 0 && (proc) < PROC_COUNT)
-
-#define EXP2PROC(exp, spm) ((exp) * (spm))
-#define EXPSLTBBC2SRAM(exp, slt, bbc) ((exp * 3) + (slt * 2) + (bbc))
-
-#define PROC2EXP(proc) ((proc) / 6)
-#define PROC2SPM(proc) ((proc) % 6)
-#define PROC2CPU(proc) (PROC2SPM(proc) & 0x3)
-#define PROC2SLT(proc) (PROC2SPM(proc) >> 2)
-#define PROC2BBC(proc) (((PROC2CPU(proc)) & 0x2) >> 1)
-#define PROC2PRT(proc) ((proc) & 0x1)
-#define EXPSLT(proc) PROC2EXP(proc), PROC2SLT(proc)
-#define EXPSLTCPU(proc) PROC2EXP(proc), PROC2SLT(proc), PROC2CPU(proc)
-#endif /* REFERENCE */
-
-
- /*
- * PFP = Packed flat port.
- * For cases where one might need to maintain information
- * (pcd arrays), or write loops, over all 18 X 6 = 108 ports.
- * It is expected that this flat view of the ports is not made
- * visible to the user, they should see only the ordered triple
- * <exp>.<slot>.<lport> or the 10-bit Safari PortId.
- * PWE = Port Within Expander. [0-5]. Comes along with the
- * PFP model, should also not be externally visible.
- */
-#define PORT_PER_EXP 6
-#define PWE_COUNT PORT_PER_EXP
-#define PWE_MAX (PWE_COUNT - 1)
-#define IS_VALID_PWE(pwe) ((pwe) >= 0 && (pwe) < PWE_COUNT)
-
-#define PFP_COUNT (EXP_COUNT * PORT_PER_EXP)
-#define PFP_MAX (PFP_COUNT - 1)
-#define IS_VALID_PFP(pfp) ((pfp) >= 0 && (pfp) < PFP_COUNT)
-
-#define PFP2EXP(pfp) ((pfp) / 6)
-#define PFP2PWE(pfp) ((pfp) % 6)
-#define PWE2SLOT(pwe) ((pwe) >> 2)
-#define PWE2LPORT(pwe) ((pwe) & 0x3)
-#define PFP2SLOT(pfp) (PWE2SLOT(PFP2PWE(pfp)))
-#define PFP2LPORT(pfp) (PWE2LPORT(PFP2PWE(pfp)))
-#define PFP2BBC(pfp) (((PFP2PWE(pfp)) >> 1) & 1)
-#define PFP2BBCPORT(pfp) ((pfp) & 1)
-
-#define SL2PWE(slot, lport) (((slot) << 2) + (lport))
-#define EPWE2PFP(exp, pwe) (((exp) * 6) + (pwe))
-#define ESL2PFP(exp, slot, lport) (EPWE2PFP((exp), SL2PWE((slot), (lport))))
-
-#define S0_LPORT_COUNT 4 /* Ports on slot 0 L1 board */
-#define S0_LPORT_MAX (S0_LPORT_COUNT - 1)
-#define IS_VALID_S0LPORT(lport) ((lport) >= 0 && (lport) < S0_LPORT_COUNT)
-#define S1_LPORT_COUNT 2 /* Ports on slot 1 L1 board */
-#define S1_LPORT_MAX (S1_LPORT_COUNT - 1)
-#define IS_VALID_S1LPORT(lport) ((lport) >= 0 && (lport) < S1_LPORT_COUNT)
-#define LPORT_COUNT(slot) ((slot) ? S1_LPORT_COUNT : S0_LPORT_COUNT)
-#define LPORT_MAX(slot) (LPORT_COUNT(slot) - 1)
-#define IS_VALID_LPORT(slot, lport) \
- ((lport) >= 0 && (lport) < LPORT_COUNT(slot))
-#define XC_IOBUS_PER_PORT 2
-#define XC_IOCARD_PER_PORT 1
-#define IS_VALID_IOBUS(bus) ((bus) >= 0 && (bus) < XC_IOBUS_PER_PORT)
-#define IS_VALID_IOCARD(card) ((card) >= 0 && (card) < XC_IOCARD_PER_PORT)
-
- /* BBC in these macros is local to a slot, either 0 or 1: */
-#define S0_BBC_COUNT 2 /* BBCs on slot 0 L1 board */
-#define S0_BBC_MAX (S0_BBC_COUNT - 1)
-#define IS_VALID_S0BBC(bbc) ((bbc) >= 0 && (bbc) < S0_BBC_COUNT)
-#define S1_BBC_COUNT 1 /* BBCs on slot 1 L1 board */
-#define S1_BBC_MAX (S1_BBC_COUNT - 1)
-#define IS_VALID_S1BBC(bbc) ((bbc) >= 0 && (bbc) < S1_BBC_COUNT)
-#define BBC_COUNT(slot) ((slot) ? S1_BBC_COUNT : S0_BBC_COUNT)
-#define BBC_MAX(slot) (BBC_COUNT(slot) - 1)
-#define IS_VALID_BBC(slot, bbc) \
- ((bbc) >= 0 && (bbc) < BBC_COUNT(slot))
-
-#define LPORT2BBC(lport) ((lport) >> 1)
-#define PWE2BBC(pwe) (((pwe) >> 1) & 1)
-
-
- /* These are for use as printf() arguments for "%2d.%d", etc.: */
-#define EXPSLOT(pfp) PFP2EXP(pfp), PFP2SLOT(pfp)
-#define EXPSLOTLPORT(pfp) PFP2EXP(pfp), PFP2SLOT(pfp), PFP2LPORT(pfp)
-
-
- /* Build a 5-bit Safari Agent ID: */
-#define SAFAGENT(slot, lport, is_ioport) \
- (((slot) ? ((is_ioport) ? 0x1C : 8) : 0) + (lport))
-
- /* Build a 10-bit Safari ID: */
-#define SAFARI_ID(exp, slot, lport, is_ioport) \
- (SAFAGENT(slot, lport, is_ioport) | ((exp) << 5))
-
- /* Given a Safari Agent ID, extract the expander number */
-#define GET_EXP(aid) ((aid & 0x3E0ull) >> 5)
-
- /* Cacheable memory per (CPU) port */
-#define DIMMS_PER_PORT 8
-#define IS_VALID_DIMM(dimm) \
- (((dimm) >= 0) && (dimm < (DIMMS_PER_PORT)))
-#define PMBANKS_PER_PORT 2
-#define LMBANKS_PER_PMBANK 2
-#define IS_VALID_PMBANK(pmbank) \
- (((pmbank) >= 0) && (pmbank < PMBANKS_PER_PORT))
-#define IS_VALID_LMBANK(lmbank) \
- (((lmbank) >= 0) && (lmbank < PMBANKS_PER_PORT))
-
- /* Ecache per (CPU) port */
-#define ECDIMMS_PER_PORT 2
-#define IS_VALID_ECACHE(ecache) \
- (((ecache) >= 0) && (ecache < ECDIMMS_PER_PORT))
-
- /* SCM asics per CSB: */
-#define SCM_COUNT (2)
-#define SCM_MAX (SCM_COUNT - 1)
-#define IS_VALID_SCM(scm) ((scm) >= 0 && (scm) < SCM_COUNT)
-
- /* Master ports in an SCM: */
-#define SCM_MPORT_COUNT 10
-
- /* SDI asics per EXB: */
-#define SDI_COUNT (6)
-#define SDI_MAX (SDI_COUNT - 1)
-#define IS_VALID_SDI(sdi) ((sdi) >= 0 && (sdi) < SDI_COUNT)
-
- /* Half-centerplanes, CSBs, etc. */
-#define CP_COUNT (2)
-#define CP_MAX (CP_COUNT - 1)
-#define IS_VALID_CP(cp) ((cp) >= 0 && (cp) < CP_COUNT)
-
- /* DMX asics on the half-centerplane: */
-#define DMX_COUNT (6)
-#define DMX_MAX (DMX_COUNT - 1)
-#define IS_VALID_DMX(dmx) ((dmx) >= 0 && (dmx) < DMX_COUNT)
-
- /* AMX asics on the half-centerplane: */
-#define AMX_COUNT (2)
-#define AMX_MAX (AMX_COUNT - 1)
-#define IS_VALID_AMX(amx) ((amx) >= 0 && (amx) < AMX_COUNT)
-
- /* Number of CPUs per SBBC on the various boards: */
-#define CPU_COUNT (2)
-
- /* Number of WCI per WIB: */
-#define S0_WCI_COUNT (2)
-#define S0_WCI_MIN (2)
-#define S0_WCI_MAX (S0_WCI_MIN + S0_WCI_COUNT - 1)
-#define S0_IS_VALID_WCI(wci) ((wci) >= S0_WCI_MIN && (wci) <= S0_WCI_MAX)
-#define S1_WCI_COUNT (1)
-#define S1_WCI_MIN (1)
-#define S1_WCI_MAX (S1_WCI_MIN + S1_WCI_COUNT - 1)
-#define WCI_COUNT(slot) ((slot) ? S1_WCI_COUNT : S0_WCI_COUNT)
-#define WCI_MIN(slot) ((slot) ? S1_WCI_MIN : S0_WCI_MIN)
-#define WCI_MAX(slot) ((slot) ? S1_WCI_MAX : S0_WCI_MAX)
-#define S1_IS_VALID_WCI(wci) ((wci) >= S1_WCI_MIN && (wci) <= S1_WCI_MAX)
-#define IS_VALID_WCI(slot, wci) ((slot) ? S1_IS_VALID_WCI((wci)) : \
- S0_IS_VALID_WCI((wci)))
-
- /* Safari reset number (within sbbc) given slot & lport */
-#define WCI_RST_NUM(slot, lport) \
- ((slot) ? 1 : ((lport) & 1 ? 1 : 0))
-
- /* Number of non WCI safari devices per WIB */
-#define S0_WIB_PROC_COUNT (2) /* max procs on slot 0 WIB */
-#define S1_WIB_SCHIZO_COUNT (1) /* max schizos on slot 1 WIB */
-
- /* Number of Schizo per PCI I/O board: */
-#define SCHIZO_COUNT (2)
-
- /*
- * CPU and Maxcat L1 boards have 4 DXs, I/O boards have 2.
- * But it's useful to have this for array dimensions, etc.
- */
-#define DX_COUNT_MAX (4)
-#define IS_VALID_CPU_DX(dx) ((dx) >= 0 && (dx) < DX_COUNT_MAX)
-
- /*
- * DCDS asics for half of a CPU board. The DCDS is a data slice,
- * 8 are required for a full Safari data path.
- */
-#define DCDS_COUNT (8)
-#define DCDS_MAX (DCDS_COUNT - 1)
-#define IS_VALID_DCDS(dcds) ((dcds) >= 0 && (dcds) < DCDS_COUNT)
-
-
- /*
- * Address, Data, or Response Bus.
- * For all three, 0 or 1 is a valid value.
- */
-#define BUS_COUNT (CP_COUNT)
-#define BUS_MAX (BUS_COUNT - 1)
-#define IS_VALID_BUS(bus) ((bus) >= 0 && (bus) < BUS_COUNT)
-
- /*
- * Address, Data, or Response Bus configuration.
- * For all three, 1. 2. or 3 is a valid value.
- */
-#define BCONF_MIN 0x1
-#define BCONF_MAX 0x3
-#define BCONF_COUNT 3
-#define IS_VALID_BCONF(bconf) ((bconf) >= BCONF_MIN && (bconf) <= BCONF_MAX)
-
- /*
- * This might seem a little obscure to be here, but it's needed
- * for some array sizes and function prototypes:
- */
-#define AXQ_NASM_SIZE 256
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_SCAT_CONST_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/post/scat_dcd.h b/usr/src/uts/sun4u/starcat/sys/post/scat_dcd.h
deleted file mode 100644
index ef57df59c1..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/post/scat_dcd.h
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SCAT_DCD_H
-#define _SCAT_DCD_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This file contains definitions of the structures gdcd_t and ldcd_t,
- * Global and Local Domain Configuration Descriptors and the various
- * substructures they contain.
- * The gdcd is the information handed off to OBP and the OS by POST
- * in the "golden" I/O SRAM of a domain in Sun Fire 15000 systems.
- * The ldcd contains information about the two ports local to each
- * sram, kept in that local sram, to support DR operations.
- */
-
-#include <sys/types.h>
-
-#include <post/scat_const.h>
-#include <post/scat_asicbrd_types.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define DCD_VERSION 4
-
-
-#define GDCD_MAGIC (('G'<< 24) | ('D'<< 16) | ('C'<< 8) | 'D')
-#define LDCD_MAGIC (('L'<< 24) | ('D'<< 16) | ('C'<< 8) | 'D')
-
-
-#define PMBANKS_PER_PORT 2
-#define LMBANKS_PER_PMBANK 2
-#define IOBUS_PER_PORT 2
-#define IOCARD_PER_BUS 4 /* 1 currently, but could change */
-#define LINKS_PER_PORT 5 /* 3 in current hardware */
-#define DIMMS_PER_PORT 8
-#define DIMMS_PER_PMBANK 4
-#define ECDIMMS_PER_PORT 2
-
- /*
- * This is intended to handle Jubatus8X - up to 8 CPU cores
- * within one Safari port.
- */
-#define SAF_AGENT_PER_PORT 8
-
- /*
- * The most significant element of the otherwise unused
- * prd_t.prd_wic_links[LINKS_PER_PORT] in processor ports is
- * reserved for use by DR to save the prd_prsv of the port
- * while that is temporarily marked RSV_UNCONFIG when the
- * processor is borrowed for I/O cage testing for DR.
- * It is expected that .prd_wic_links[PRD_LINK_IX_HOLD_CPUPORT_PRSV]
- * will be restored to RSV_UNDEFINED when the prd_prsv is
- * restored to its original value. It would be a Good Thing to
- * check that prd_prsv is not ever being set to RSV_UNDEFINED;
- * it's probably wrong to restore it to other than RSV_GOOD().
- */
-#define PRD_LINK_IX_HOLD_CPUPORT_PRSV (LINKS_PER_PORT - 1)
-
- /*
- * There are four Address Decode Registers, 0 - 3, one for each
- * logical bank. ADR 0 and 2 control the logical banks in
- * physical bank 0; ADR 1 and 3 control the logical banks in
- * physical bank 1.
- */
-#define ADR2PBANK(adr) ((adr) & 1)
-#define ADR2LBANK(adr) (((adr) >> 1) & 1)
-#define PLBANK2ADR(pbank, lbank) ((((lbank) & 1) << 1) | ((pbank) & 1))
-
-
- /* ======================================================== */
- /*
- * RSV stands for Resource Status Value.
- * These are the values used in all cases where the status of
- * a resource is maintained in a byte element of a structure.
- * These are ordered in terms of preserving interesting information
- * in POST displays where all configurations are displayed in a
- * single value. The highest value for a resource over all
- * configurations is shown.
- * Of course, this is just for help to engineers/technicians in
- * understanding what happened; for the most part, everything
- * except "GOOD" is just different flavors of "BAD".
- * This is not an enum because they need to fit in a byte.
- */
-
-typedef uint8_t prdrsv_t;
-
-#define RSV_UNKNOWN 0x0 /* No status yet */
-#define RSV_PRESENT 0x1 /* Presence detected */
-#define RSV_CRUNCH 0x2 /* Unusable by implication */
-#define RSV_UNDEFINED 0x3 /* Architecturally Missing */
-#define RSV_MISS 0x4 /* Missing */
-#define RSV_MISCONFIG 0x5 /* Misconfigured, e.g., mixed dimms */
-#define RSV_FAIL_OBP 0x6 /* Failed by OBP */
-#define RSV_FAIL 0x7 /* Tested and failed */
-#define RSV_BLACK 0x8 /* Blacklisted */
-#define RSV_RED 0x9 /* Redlisted */
-#define RSV_EXCLUDED 0xA /* Not in this domain */
-#define RSV_UNCONFIG 0xB /* Good, but not in config. */
-#define RSV_PASS 0xC /* Passed some sort of test; */
- /* Always subject to more... */
- /*
- * Odd proc of a good Lockstep pair. Valid only for prd_prsv for
- * processor ports.
- */
-#define RSV_LOCKSTEP 0xD
-
- /*
- * This will be used instead of RSV_MISS when an hsPCI
- * cassette is present but it contains no PCI adapter.
- * Intended to be used only for prd_t.prd_iocard_rsv[][]
- */
-#define RSV_EMPTY_CASSETTE 0xF /* An hsPCI cassette, no adapter */
-
- /*
- * This definition of Good depends on context.
- * Some customers of this status may want to use only PASS.
- */
-#define RSV_GOOD(rsv) \
- (RSV_PASS == (rsv) || RSV_UNKNOWN == (rsv) || RSV_PRESENT == (rsv))
-
-#define RSV_NOTOUCH(rsv) (RSV_EXCLUDED == (rsv) || RSV_RED == (rsv))
-
- /* ============================================================ */
- /* Port Resource Descriptor - PRD */
-
-typedef struct {
- uint64_t prd_ver_reg; /* port version register */
- /*
- * For ports with memory, the address decode register
- * for each bank, and the address control register.
- */
- uint64_t prd_madr[PMBANKS_PER_PORT][LMBANKS_PER_PMBANK];
- uint64_t prd_macr;
- /* DOUBLEWORD */
-
- uint16_t prd_rfreq; /* rated frequency Mhz */
- uint16_t prd_afreq_ratio; /* ratio of actual frequency */
- /* to interconnect speed */
-
- prdrsv_t prd_prsv; /* status of entire port. */
- uint8_t prd_ptype; /* port type. See SAFPTYPE_ below */
-
- /* memory configuration state */
- uint8_t prd_mem_config_state;
-
- uint8_t prd_fill1;
- /* DOUBLEWORD */
-
- /*
- * This is intended to handle Jubatus2X - 8X.
- * For all other cases, expect that prd_agent[0] = prd_prsv,
- * and prd_agent[7:1] = RSV_UNDEFINED.
- * For JubatusnX, it conveys the status of the
- * n core processors.
- */
- prdrsv_t prd_agent[SAF_AGENT_PER_PORT];
- /* DOUBLEWORD */
-
- /* for ports that have memory */
- prdrsv_t prd_bank_rsv[PMBANKS_PER_PORT][LMBANKS_PER_PMBANK];
- /* bank rsv */
- uint16_t prd_log_bank_size[PMBANKS_PER_PORT]; /* bank size */
- /*
- * If a physical bank has two logical
- * banks, they are always the same size.
- */
- /* DOUBLEWORD */
-
- /* for ports with IO buses */
- prdrsv_t prd_iocard_rsv[IOBUS_PER_PORT][IOCARD_PER_BUS];
- /*
- * Currently, only 1 adapter is on each bus and index
- * zero is used for that. Index 1 is reserved.
- * The remaining 2 are used to support in-kernel-probing,
- * to avoid board specific hooks.
- * They only exist on bus 1 of Schizo 0 on the board.
- */
-#define IOBOARD_BBCRIO_PORT 0
-#define IOBOARD_BBCRIO_BUS 1
-#define IOCARD_RSV_SBBC_INDEX 2
-#define IOCARD_RSV_RIO_INDEX 3
-
- /* DOUBLEWORD */
-
- prdrsv_t prd_iobus_rsv[IOBUS_PER_PORT];
-
- /* For ports with WCI links, status of each link */
- prdrsv_t prd_wic_links[LINKS_PER_PORT];
-
- uint8_t fill2;
- /* DOUBLEWORD */
-
-
- prdrsv_t prd_dimm[PMBANKS_PER_PORT][DIMMS_PER_PMBANK];
- /*
- * Status for dimms [1:0][3:0].
- * This contains at most only probing information.
- * Testing is done on logical banks, so results are
- * not representable at the dimm level, since each
- * dimm contains part of two logical banks.
- *
- * Also, probing is expensive in time, so it is
- * skipped if the results would not affect available
- * resources.
- * Example: if dimm 0 of a pbank is missing, the other
- * three dimms are ignored and will be RSV_UNKNOWN.
- */
-
- /* DOUBLEWORD */
- uint8_t prd_cache; /* external cache size (MByte) */
- prdrsv_t prd_ecdimm[ECDIMMS_PER_PORT];
- /* status for ecache dimms 0..1 */
-
-
- uint8_t prd_sparebyte[5];
- /* DOUBLEWORD */
- uint32_t prd_spare[4];
- /* DOUBLEWORD */
-
-} prd_t;
-
- /* prd_mem_config_state manifest constants */
-#define PRD_MCS_BANKS ((uint8_t)1 << 0)
-#define PRD_MCS_SLICE ((uint8_t)1 << 1)
-#define PRD_MCS_IMODE(mode) (((uint8_t)(mode) & 0x3) << 2)
-#define PRD_MCS_GET_IMODE(mcs) (((uint8_t)(mcs) & 0xC) >> 2)
-#define PRD_MCS_FAILD ((uint8_t)1 << 6)
-#define PRD_MCS_VALID ((uint8_t)1 << 7)
-
-
- /* Types of Safari ports. Not an enum so it fits in a byte. */
-#define SAFPTYPE_NULL 0
-#define SAFPTYPE_CPU 1
-#define SAFPTYPE_sPCI 2
-#define SAFPTYPE_cPCI 3
-#define SAFPTYPE_WCI 4
-#define SAFPTYPE_PCIX 5
-#define SAFPTYPE_MAX SAFPTYPE_PCIX
-
-#define SAFTYPE_PCI(type) \
- ((SAFPTYPE_sPCI == (type)) || (SAFPTYPE_cPCI == (type)))
-
-
- /* ======================================================== */
- /* Local and Global Domain Configuration Descriptors LDCD & GDCD */
-
- /* Enumeration of process types for xdcd.h.dcd_lmod_type */
-typedef enum {
- DCDLMT_OTHER, /* Something not otherwise in this enum */
- DCDLMT_POST_BOOT, /* POST at initial domain creation */
- DCDLMT_POST_DR, /* POST for some sort of DR case */
- DCDLMT_OBP, /* Domain Open Boot */
- DCDLMT_OS, /* Domain Solaris */
- DCDLMT_DR_SMS, /* DR process running on SSC */
- DCDLMT_DR_DOMAIN, /* DR process running on domain */
- DCDLMT_OTHER_SMS, /* Non-DR process running on SSC */
- DCDLMT_COUNT /* Array size for strings, etc. */
-} dcd_lmod_type_t;
-
-
- /* dcd substructure for status of L1 boards in each slot */
-typedef struct {
- xcl1bt_t l1ss_type; /* enum in scat_asicbrd_types.h */
- prdrsv_t l1ss_rsv; /* Status. */
- /*
- * The cdc information is rightfully
- * only relevant to the EXB and the
- * slot 0 board of that EXB. But it
- * needs to stay with that slot 0
- * board over DR operations, so
- * it goes here.
- * It should be ignored for slot 1
- * boards.
- */
- prdrsv_t l1ss_cdc_rsv;
- uint8_t l1ss_cdc_dimm_size; /* MBytes */
- uint8_t l1ss_fill1; /* Explicit alignment */
- /* DOUBLEWORD */
- /*
- * So Starcat software that doesn't
- * have knowledge of the CPU sram
- * TOC format can find the LDCD in
- * CPU srams.
- */
- uint16_t l1ss_cpu_ldcd_xwd_offset; /* Byte offset >> 3 */
- uint16_t l1ss_cpu_drblock_xwd_offset; /* Byte offset >> 3 */
- uint8_t l1ss_flags; /* See below */
- uint8_t l1ss_sparebyte[3];
- uint32_t l1ss_spare[2];
- /* DOUBLEWORD */
-} l1_slot_stat_t;
-
- /*
- * When this flag is set, all CPUs on this L1 board should be
- * configured with a NULL Local Physical Address (LPA) range in
- * their Safari Config Registers.
- * This flag can be ignored for boards with no processors.
- */
-#define L1SSFLG_THIS_L1_NULL_PROC_LPA (1 << 0)
-
-
- /* dcd substructure for memory chunk list. */
-typedef struct {
- uint64_t mc_base_pa; /* Base Physical Address */
- uint64_t mc_mbytes; /* Size of Chunk in MBytes */
-} mem_chunk_t;
-
-#define MAX_DOM_MEM_CHUNKS (EXP_COUNT * S0_LPORT_COUNT * \
- PMBANKS_PER_PORT * LMBANKS_PER_PMBANK)
-typedef struct {
- uint64_t dcl_chunks; /* number of chunks */
- mem_chunk_t dcl_chunk[MAX_DOM_MEM_CHUNKS];
-} domain_chunk_list_t;
-
-#define MAX_EXP_MEM_CHUNKS (S0_LPORT_COUNT * \
- PMBANKS_PER_PORT * LMBANKS_PER_PMBANK)
-typedef struct {
- uint64_t ecl_chunks; /* number of chunks */
- mem_chunk_t ecl_chunk[MAX_EXP_MEM_CHUNKS];
-} exp_chunk_list_t;
-
-typedef struct {
- uint32_t dcd_magic; /* GDCD_MAGIC or LDCD_MAGIC */
- uint32_t dcd_version; /* structure version: DCD_VERSION */
- uint32_t dcd_csum; /* So sum((uint[]) xdcd) == 0. */
- uint32_t dcd_post_pid; /* Process ID of the SSC hpost that */
- /* originally created this domain */
- /* or POSTed this board. */
- /* DOUBLEWORD */
-
- uint64_t dcd_boot_time; /* Time of creation of the domain */
- /* by POST. To be backward compatible */
- /* in ILD32, uint64_t is used instead */
- /* of time_t. */
-
- uint64_t dcd_lmod_time; /* Time of last modification of */
- /* this structure. */
-
- uint32_t dcd_lmod_pid; /* Process ID of the last modifier */
- /* of this structure. If the last */
- /* modifier has no PID, set to 0. */
-
- dcd_lmod_type_t dcd_lmod_type; /* Type of process that last modified */
- /* this structure. See above. */
- /* DOUBLEWORD */
-
- uint32_t dcd_mod_count; /* Count of the number of times */
- /* this structure has been modified. */
- /* Set to 0 by original POST. */
-
- uint32_t dcd_post_level; /* Level at which POST executed */
- /* for most recent boot or test. */
- /* DOUBLEWORD */
-
- uint32_t dcd_post_private; /* Private word for POST */
- uint32_t dcd_flags; /* See DCDFLAG_xxx */
- uint32_t dcd_spare[8]; /* Minimize future problems */
- /* DOUBLEWORD */
-} dcd_header_t;
-
-
- /*
- * This flag is only for use in LDCDs. It is set when this
- * board is part of a domain and the local DCD is considered
- * only a secondary copy of the information in the GDCD.
- * We do not keep the GDCD location here, since that would
- * impose extra work on DR when the golden IOSRAM board detaches.
- * POST will set this in all LDCDs in a newly booted domain.
- */
-#define DCDFLAG_IN_DOMAIN (1u << 0)
-
- /*
- * This flag is only for use in LDCDs. It is set when this
- * board was called for hpost -H (h.dcd_lmod_type is DCDLMT_POST_DR)
- * and no testing was required. All that was done was clearing.
- */
-#define DCDFLAG_CLEARED_ONLY (1u << 1)
-
- /* POST inititalizes dcd_testcage_mbyte_PA to this value */
-#define DCD_TESTCAGE_MBYTE_PA_INIT ((uint32_t)-1)
- /*
- * zero (0) in dcd_testcage_log2_mbytes has the special meaning
- * that no testcage memory is to be allocated.
- * zero (0) in dcd_testcage_log2_mbytes_align is a real
- * alignment of 1MB.
- */
-#define DCD_DR_TESTCAGE_DISABLED (0) /* zero size cage */
-#define DCD_DR_TESTCAGE_LOG2_1MB_ALIGN (0) /* 2^0 = 1 for */
- /*
- * The remainder of these constants can be used for
- * either dcd_testcage_* variable and indicate the
- * value shown.
- */
-#define DCD_DR_TESTCAGE_LOG2_2MB (1) /* 2^1 = 2 */
-#define DCD_DR_TESTCAGE_LOG2_4MB (2) /* 2^2 = 4 */
-#define DCD_DR_TESTCAGE_LOG2_8MB (3) /* 2^3 = 8 */
-#define DCD_DR_TESTCAGE_LOG2_16MB (4) /* 2^4 = 16 */
-#define DCD_DR_TESTCAGE_LOG2_32MB (5) /* 2^5 = 32 */
-#define DCD_DR_TESTCAGE_LOG2_64MB (6) /* 2^6 = 64 */
-#define DCD_DR_TESTCAGE_LOG2_128MB (7) /* 2^7 = 128 */
-#define DCD_DR_TESTCAGE_LOG2_256MB (8) /* 2^8 = 256 */
-#define DCD_DR_TESTCAGE_LOG2_512MB (9) /* 2^9 = 512 */
-#define DCD_DR_TESTCAGE_LOG2_1024MB (10) /* 2^10 = 1024 */
-
- /* Global DCD - exists only in golden I/O sram */
-typedef struct {
- dcd_header_t h;
- /* DOUBLEWORD */
-
- uint32_t dcd_intercon_freq; /* In Hertz */
- uint8_t dcd_abus_mask; /* Address bus config [1:0] */
- uint8_t dcd_dbus_mask; /* Data bus config [1:0] */
- uint8_t dcd_rbus_mask; /* Response bus config [1:0] */
- uint8_t dcd_stick_ratio; /* Ratio of intercon:STICK */
- /* DOUBLEWORD */
-
- uint8_t dcd_domain; /* 0-17 or other if unknown */
- /*
- * Specification of the required size and alignment of
- * the DR testcage memory used during POST -H testcage runs.
- * The formula is bytes = (1 << (log2_value + 20)).
- */
- uint8_t dcd_testcage_log2_mbytes_size;
- uint8_t dcd_testcage_log2_mbytes_align;
- uint8_t dcd_fill[5];
- /* DOUBLEWORD */
- /*
- * Specification of the DR testcage memory base physical addr.
- * This is initialized to DCD_TESTCAGE_PA_INIT by POST
- * and set by setkeyswitch when it determines the location of
- * the testcage. The formula is PA = (mbyte_PA << 20).
- */
- uint32_t dcd_testcage_mbyte_PA;
- uint32_t dcd_spare[3]; /* Avoid future problems */
- /* DOUBLEWORD */
-
- /* Information on the L1 boards in each slot: */
- l1_slot_stat_t dcd_slot[EXP_COUNT][SLOT_COUNT];
- /* DOUBLEWORD */
-
- /*
- * Information on 108 Safari ports.
- * See scat_const.h for macros that will help in computing
- * indexes into this array, particularly "PWE" and "PFP".
- */
- prd_t dcd_prd[EXP_COUNT][PORT_PER_EXP];
- /* DOUBLEWORD */
-
- /*
- * memory chunk list for the domain; max 288 chunks.
- * This is the worst case scenario where there is no
- * interleaving and no re-configuration of the memory address
- * decode registers to make board memory contiguous.
- * This uses 288 * 16bytes = 4608KB.
- */
- domain_chunk_list_t dcd_chunk_list;
-} gdcd_t;
-
- /* Local DCD - exists in every I/O, CPU, and WCI sram */
-typedef struct {
- dcd_header_t h;
- /* DOUBLEWORD */
-
- /* Information on the L1 board in this slot: */
- l1_slot_stat_t dcd_slot;
- /* DOUBLEWORD */
-
- /* Information on 2 Safari ports: */
- prd_t dcd_prd[2];
- /* DOUBLEWORD */
-
- /* memory chunk list for this exp; max 16 chunks */
- exp_chunk_list_t dcd_chunk_list;
-} ldcd_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_SCAT_DCD_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/post/scat_pa_space.h b/usr/src/uts/sun4u/starcat/sys/post/scat_pa_space.h
deleted file mode 100644
index 3219f68b36..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/post/scat_pa_space.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _SCAT_PA_SPACE_H
-#define _SCAT_PA_SPACE_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This file contains definitions related to the Starcat
- * physical address space.
- */
-
-/*
- * POST DEVELOPERS:
- * This file is copied to the OS workspace, and thus must abide by the OS
- * coding standards. This file must always pass cstyle and hdrchk.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define STARCAT_DEVICE_CONFIG (0x40000000000ull)
-
-#define EXP_PA_ADDR(exp) (exp << 28)
-
- /*
- * Useful to translate an sram or fprom offset to an address
- * that a host processor would use to reach it.
- */
-#define BOOTBUS_PA_BASE 0x7FFF0000000ull
-
- /* See bbc.h for sizes */
-#define BOOTBUS_FPROM_PA_BASE (BOOTBUS_PA_BASE + 0)
-#define BOOTBUS_SRAM_PA_BASE (BOOTBUS_PA_BASE + 0x900000u)
-
- /*
- * Cacheable Physical Memory Addresses in Starcat are assigned
- * to expanders in 128 GByte slices, based on PA[41:37].
- * The slice to exp mapping is not always 1-1, swaps may occur
- * as a result of some DR or POST operations.
- * The map is maintained in the PCD.
- * The slice number will always be a valid expander board
- * number in [0,17], but it may not reside on that expander.
- * The PA in these macros is 64-bit, the slice is 8 bit, unsigned.
- */
-#define PA_2_SLICE128G(pa) (((uint8_t)((pa) >> 37)) & 0x1Fu)
-#define SLICE128G_2_PA_BASE(slice) (((uint64_t)((slice) & 0x1F)) << 37)
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_SCAT_PA_SPACE_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/sc_cvc.h b/usr/src/uts/sun4u/starcat/sys/sc_cvc.h
deleted file mode 100644
index 1d7db9b5df..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/sc_cvc.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_SC_CVC_H
-#define _SYS_SC_CVC_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define CVC_IOSRAM_POLL_USECS 100000
-
-#if defined(DEBUG)
-
-#define CVC_DBG_ATTACH 0x0001
-#define CVC_DBG_DETACH 0x0002
-#define CVC_DBG_OPEN 0x0004
-#define CVC_DBG_CLOSE 0x0008
-#define CVC_DBG_IOCTL 0x0010
-#define CVC_DBG_REDIR 0x0020
-#define CVC_DBG_WPUT 0x0040
-#define CVC_DBG_WSRV 0x0080
-#define CVC_DBG_IOSRAM_WR 0x0100
-#define CVC_DBG_IOSRAM_RD 0x0200
-#define CVC_DBG_NETWORK_WR 0x0400
-#define CVC_DBG_NETWORK_RD 0x0800
-#define CVC_DBG_IOSRAM_CNTL 0x1000
-
-
-#define CVC_DBG0(flag, fmt) \
- cvc_dbg(flag, fmt, 0, 0, 0, 0, 0);
-#define CVC_DBG1(flag, fmt, a1) \
- cvc_dbg(flag, fmt, (uintptr_t)(a1), 0, 0, 0, 0);
-#define CVC_DBG2(flag, fmt, a1, a2) \
- cvc_dbg(flag, fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
-#define CVC_DBG3(flag, fmt, a1, a2, a3) \
- cvc_dbg(flag, fmt, (uintptr_t)(a1), (uintptr_t)(a2), \
- (uintptr_t)(a3), 0, 0);
-#define CVC_DBG4(flag, fmt, a1, a2, a3, a4) \
- cvc_dbg(flag, fmt, (uintptr_t)(a1), (uintptr_t)(a2), \
- (uintptr_t)(a3), (uintptr_t)(a4), 0);
-#define CVC_DBG5(flag, fmt, a1, a2, a3, a4, a5) \
- cvc_dbg(flag, fmt, (uintptr_t)(a1), (uintptr_t)(a2), \
- (uintptr_t)(a3), (uintptr_t)(a4), (uintptr_t)(a5));
-
-#else /* DEBUG */
-
-#define CVC_DBG0(flag, fmt)
-#define CVC_DBG1(flag, fmt, a1)
-#define CVC_DBG2(flag, fmt, a1, a2)
-#define CVC_DBG3(flag, fmt, a1, a2, a3)
-#define CVC_DBG4(flag, fmt, a1, a2, a3, a4)
-#define CVC_DBG5(flag, fmt, a1, a2, a3, a4, a5)
-
-#endif /* DEBUG */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_SC_CVC_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/sc_cvcio.h b/usr/src/uts/sun4u/starcat/sys/sc_cvcio.h
deleted file mode 100644
index 5c56a0c1fd..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/sc_cvcio.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_SC_CVCIO_H
-#define _SYS_SC_CVCIO_H
-
-#include <sys/sysmacros.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Layout of console IOSRAM chunks
- * |---------------|
- * CONC | cvc_ctl_t |
- * | 128 bytes |
- * |---------------|
- *
- * |---------------|
- * CONI | input count |
- * | 2 bytes |
- * |---------------|
- * | receive buffer|
- * | 1022 bytes |
- * |---------------|
- *
- * |---------------|
- * CONO | output count |
- * | 2 bytes |
- * |---------------|
- * | send buffer |
- * | 1022 bytes |
- * |---------------|
- */
-
-#define IOSRAM_KEY_CONC 0x434F4E43
-#define IOSRAM_KEY_CONI 0x434F4E49
-#define IOSRAM_KEY_CONO 0x434F4E4F
-
-#define CONSBUF_IN_SIZE 1024
-#define CONSBUF_OUT_SIZE 1024
-#define CONSBUF_COUNT_SIZE (sizeof (short))
-
-#define MAX_XFER_CINPUT (CONSBUF_IN_SIZE - CONSBUF_COUNT_SIZE)
-#define MAX_XFER_COUTPUT (CONSBUF_OUT_SIZE - CONSBUF_COUNT_SIZE)
-#define COUNT_OFFSET 0
-#define DATA_OFFSET (CONSBUF_COUNT_SIZE)
-
-#define cvc_username "sms"
-#define CVCD_SERVICE "cvc_hostd"
-#define MAX_CONS_CONN 100
-#define MAXPKTSZ 4096
-
-#define TCP_DEV "/dev/tcp"
-#define CVCREDIR_DEV "/devices/pseudo/cvcredir@0:cvcredir"
-
-
-/*
- * ioctl commands passed to cvcredir (and possibly on to cvc from there) by cvcd
- */
-#define CVC 'N'
-#define CVC_BREAK ((CVC<<8) | 0x00)
-#define CVC_DISCONNECT ((CVC<<8) | 0x01)
-
-/*
- * DXS (the SC-side console traffic application) may send a few of these codes
- * to cvcd as expedited TLI traffic. The rest are not used in domain-side
- * software, but SC-side software may use them.
- */
-#define CVC_CONN_BREAK 0x1 /* Break to OBP or kmdb */
-#define CVC_CONN_DIS 0x2 /* disconnect */
-#define CVC_CONN_STAT 0x4 /* status of CVC connects */
-#define CVC_CONN_WRITE 0x8 /* ask write permission */
-#define CVC_CONN_RELW 0x10 /* release write permission */
-#define CVC_CONN_WRLK 0x20 /* Lock the Write */
-#define CVC_CONN_PRIVATE 0x40 /* Only one session is allowed */
-#define CVC_CONN_SWITCH 0x41 /* Switch communication path */
-
-/*
- * This structure represents the layout of control data in the CONC chunk.
- * It should NOT grow beyond 128 bytes, as that is the max size that was
- * identified for the CONC chunk.
- */
-typedef struct cvc_ctl {
- uint8_t command; /* CVC_IOSRAM_BREAK, etc */
- uint8_t version; /* currently unused */
- uint8_t unused1[2]; /* currently unused */
- uint16_t winsize_rows;
- uint16_t winsize_cols;
- uint16_t winsize_xpixels;
- uint16_t winsize_ypixels;
- uint8_t unused2[116]; /* currently unused */
-} cvc_ctl_t;
-
-/*
- * These macros can be used to determine the offset or size of any field in the
- * CONC chunk.
- */
-#define CVC_CTL_OFFSET(field) offsetof(cvc_ctl_t, field)
-#define CVC_CTL_SIZE(field) (sizeof (((cvc_ctl_t *)0)->field))
-
-/*
- * Commands sent across IOSRAM from domain_server to cvc driver
- */
-#define CVC_IOSRAM_BREAK 1
-#define CVC_IOSRAM_DISCONNECT 2
-#define CVC_IOSRAM_VIA_NET 3
-#define CVC_IOSRAM_VIA_IOSRAM 4
-#define CVC_IOSRAM_WIN_RESIZE 5
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_SC_CVCIO_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/sc_gptwocfg.h b/usr/src/uts/sun4u/starcat/sys/sc_gptwocfg.h
deleted file mode 100644
index a16d28d8e0..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/sc_gptwocfg.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_SC_GPTWOCFG_H
-#define _SYS_SC_GPTWOCFG_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Interfaces exported by Starcat Interface, kernel/misc/sc_gptwocfg
- */
-
-typedef void *sc_gptwocfg_cookie_t;
-
-sc_gptwocfg_cookie_t sc_probe_board(uint_t);
-sc_gptwocfg_cookie_t sc_unprobe_board(uint_t);
-int sc_next_node(sc_gptwocfg_cookie_t, dev_info_t *, dev_info_t **);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_SC_GPTWOCFG_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/schpc.h b/usr/src/uts/sun4u/starcat/sys/schpc.h
deleted file mode 100644
index e9a26cea79..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/schpc.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_SCHPC_H
-#define _SYS_SCHPC_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define STARCAT_MAX_SLOTS (18 * 4)
-
-/*
- * Slot LED Descriptor
- *
- * Each hot pluggable PCI/cPCI slot has three leds. Each LED can
- * be on, off, or flashing.
- */
-typedef struct slot_led {
- char led_power;
- char led_service;
- char led_fault;
- char reserved;
-} slot_led_t;
-
-#define LED_OFF 0x00
-#define LED_ON 0x01
-#define LED_FLASH 0x02
-
-/*
- * LED Commands
- */
-#define POWER_LED_ON 0x00000001
-#define POWER_LED_OFF 0x00000002
-#define POWER_LED_FLASH 0x00000004
-#define SERVICE_LED_ON 0x00000010
-#define SERVICE_LED_OFF 0x00000020
-#define SERVICE_LED_FLASH 0x00000040
-#define FAULT_LED_ON 0x00000100
-#define FAULT_LED_OFF 0x00000200
-#define FAULT_LED_FLASH 0x00000400
-
-
-/*
- * Hot Plug Slot Descriptor. Each hot pluggable slot will have
- * a schpc_slot_t structure allocated for it.
- */
-typedef struct {
- dev_info_t *devi; /* Ptr to PCI dev_info */
- uint32_t state; /* Slot's Hot Plug State */
- uint16_t pci_id; /* PCI ID for slot */
- uint8_t expander; /* Centerplane Expander */
- uint8_t board; /* Number of IO Board 0/1 */
- uint8_t schizo; /* Number of Schizo 0/1 */
- uint8_t leaf; /* A or B (0 or 1) */
- uint8_t slot; /* Slot Number */
- slot_led_t led; /* Current LED state */
- hpc_slot_ops_t *slot_ops; /* Ptr HPC entry points */
- hpc_slot_info_t slot_info; /* Bus Specific SlotInfo */
- hpc_slot_t slot_handle; /* Handle used by HPS */
- char nexus_path[MAXNAMELEN]; /* Pathname of Nexus */
- char ap_id[MAXNAMELEN]; /* Attachment point name */
- caddr_t saved_regs_va[3]; /* Reg set virtual addresses */
- ddi_acc_handle_t saved_handle[3]; /* Handle from map in */
- uint64_t *saved_regs; /* Ptr to saved off regs */
- int saved_size; /* Size of saved off regs */
-} schpc_slot_t;
-
-/*
- * PCI/cPCI Hot Plug states for an attachment point
- */
-#define SCHPC_SLOTSTATE_REC_GOOD 0x01 /* Receptacle is Good */
-#define SCHPC_SLOTSTATE_OCC_GOOD 0x02 /* Occupant is Good */
-#define SCHPC_SLOTSTATE_BAD_NEXUS 0x04 /* Invalid PCI Nexus */
-#define SCHPC_SLOTSTATE_PRESENT 0x10 /* Occupant Present */
-#define SCHPC_SLOTSTATE_CONNECTED 0x100 /* Receptacle Connected */
-#define SCHPC_SLOTSTATE_CONFIGURED 0x1000 /* Occupant Configured */
-#define SCHPC_SLOTSTATE_AUTOCFG_ENABLE 0x10000 /* Auto Configuration Enabled */
-#define SCHPC_SLOTSTATE_ENUM 0x100000 /* ENUM Handling in progress */
-#define SCHPC_SLOTSTATE_EXECUTING 0x200000 /* Executing a mailbox cmd */
-#define SCHPC_SLOTSTATE_HPCINITED 0x400000 /* Ready to accept commands */
-
-/*
- * Soft state structure definition for each schpc instance.
- * There will be a single soft state stucture for each IO Board.
- */
-typedef struct schpc {
- uint32_t schpc_instance; /* Instance # */
- dev_info_t *schpc_devi; /* Ptr to dev_info */
- kmutex_t schpc_mutex; /* Mutex to protect struct */
- kcondvar_t schpc_cv; /* Conditional Variable */
- char *schpc_property; /* Ptr to slot-table */
- uint32_t schpc_property_size; /* Size of slot-table */
- uint32_t schpc_hotplugmodel; /* Type of Hot Plug */
- uint16_t schpc_transid; /* Current transaction ID */
- uint16_t schpc_number_of_slots; /* Slot on IO Board */
- struct schpc *schpc_next; /* Ptr to next schpc */
- schpc_slot_t *schpc_slot; /* Slot Specific stuff */
-} schpc_t;
-
-/*
- * Types of Hot Plug/Hot Swap Models
- */
-#define SCHPC_HOTPLUGTYPE_NOTHOTPLUGGABLE 0
-#define SCHPC_HOTPLUGTYPE_CPCIHOTPLUG 1
-#define SCHPC_HOTPLUGTYPE_CPCIHOTSWAPBASIC 2
-#define SCHPC_HOTPLUGTYPE_CPCIHOTSWAPFULL 3
-#define SCHPC_HOTPLUGTYPE_PCIHOTPLUG 4
-
-/*
- * schpc_t's slot table, schpc_slot[], is indexed by
- * a value in the range [0,STARCAT_MAX_SLOTS).
- *
- * That index is composed of these bit-fields:
- *
- * <-- slot num -->
- * |----------------------------|
- * | expander | schizo | leaf |
- * |------------|--------|------|
- * 7 2 1 0
- *
- */
-/* Extract various bit-fields from a slot table index: */
-#define SCHPC_SLOT_EXPANDER(idx) (((idx) & 0xfc) >> 2)
-#define SCHPC_SLOT_SCHIZO(idx) (((idx) & 0x2) >> 1)
-#define SCHPC_SLOT_LEAF(idx) ((idx) & 0x1)
-#define SCHPC_SLOT_NUM(idx) ((idx) & (0x1 | 0x2))
-
-/* Build a slot index from component bit-fields: */
-#define SCHPC_MAKE_SLOT_INDEX2(expander, slot_num)\
- (((expander) << 2) | (slot_num))
-#define SCHPC_MAKE_SLOT_INDEX3(expander, schizo, leaf)\
- (((expander) << 2) | ((schizo) << 1) | (leaf))
-
-/*
- * Integer values for the clock-frequency property.
- */
-#define SCHPC_33MHZ (33 * 1000 * 1000)
-#define SCHPC_66MHZ (66 * 1000 * 1000)
-#define SCHPC_90MHZ (90 * 1000 * 1000)
-#define SCHPC_133MHZ (133 * 1000 * 1000)
-
-/*
- * module-revision# for the XMITS versions
- */
-#define XMITS_10 1
-#define XMITS_20 2
-#define XMITS_21 3
-#define XMITS_30 4
-#define XMITS_31 5
-
-extern int schpc_add_pci(dev_info_t *);
-extern int schpc_remove_pci(dev_info_t *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_SCHPC_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/schpc_msg.h b/usr/src/uts/sun4u/starcat/sys/schpc_msg.h
deleted file mode 100644
index 64098b01e4..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/schpc_msg.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_SCHPC_MSG_H
-#define _SYS_SCHPC_MSG_H
-
-/*
- * This header file describes the messages that are sent between the
- * schpc Hot Plug Controller Driver running on the domain and the System
- * Controller.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Format of the Get Slot Status specific part of
- * PCI Hot Plug message.
- */
-typedef struct {
- uint16_t slot_power_on :1, /* Slot Power is on */
- slot_powergood :1, /* Slot Power is good */
- slot_powerfault :1, /* Slot Power has faulted */
- slot_empty :1, /* No occupant in slot */
- slot_freq_cap :2, /* Slot's Freq Capability */
- slot_freq_setting :2, /* Slot Freq setting */
- slot_condition :2, /* Condition of slot */
- slot_HEALTHY :1, /* Value of HEALTHY# sig */
- slot_ENUM :1, /* Value of ENUM# sig */
- slot_mode_cap :1, /* Conven or PCI-X */
- slot_mode_setting :1, /* Conven or PCI-X */
- reserved :2;
- uint8_t slot_replystatus;
-} pci_getslot_t;
-
-/*
- * Format of the Set Slot Status specific part of
- * PCI Hot Plug message.
- */
-typedef struct {
- uint16_t slot_power_on :1, /* Connect Slot to bus */
- slot_power_off :1, /* Disconnect from bus */
- slot_led_power :2, /* Slot Power LED */
- slot_led_service :2, /* OK To Remove LED */
- slot_led_fault :2, /* Fault LED */
- slot_disable_ENUM :1, /* Disable ENUM Event */
- slot_enable_ENUM :1, /* Enable ENUM Event */
- slot_disable_HEALTHY :1, /* Disable HEALTHY EVENT */
- slot_enable_HEALTHY :1, /* Enable HEALTHY EVENT */
- reserved :4;
- uint8_t slot_replystatus;
-} pci_setslot_t;
-
-/*
- * Format of the Slot Event specific part of
- * the PCI Hot Plug message.
- */
-typedef struct {
- uint16_t slot_power :1, /* Slot Power has changed */
- slot_presence :1, /* occupant has been */
- /* inserted or removed */
- slot_ENUM :1, /* ENUM# has changed */
- slot_HEALTHY :1, /* HEALTHY# has changed */
- slot_powergood :1, /* Power is good */
- slot_powerfault :1, /* Power has faulted */
- reserved :10;
-} pci_slotevent_t;
-
-/*
- * PCI Hot Plug message
- */
-typedef struct {
- uint8_t pcimsg_node;
- uint8_t pcimsg_board;
- uint8_t pcimsg_slot;
- uint8_t pcimsg_revision;
- uint8_t pcimsg_command;
- union {
- pci_setslot_t pcimsg_setslot;
- pci_getslot_t pcimsg_getslot;
- pci_slotevent_t pcimsg_slotevent;
- } pcimsg_type;
-} pcimsg_t;
-
-/*
- * Keys for the outgoing and incoming mailboxes
- */
-#define KEY_PCSC 0x50435343 /* Outgoing Mailbox 'PCSC' */
-#define KEY_SCPC 0x53435043 /* Incoming Mailbox 'SCPC' */
-
-/*
- * default timeout in seconds for mboxsc_getmsg calls
- */
-#define PCSC_TIMEOUT 30
-
-/* Commands */
-#define PCIMSG_GETSLOTSTATUS 0x1
-#define PCIMSG_SETSLOTSTATUS 0x2
-#define PCIMSG_SLOTEVENT 0x3
-
-/* Message Revisions */
-#define PCIMSG_REVISION 0x10
-#define PCIMSG_REVISION_1_0 0x10
-
-/*
- * Values for the slot_condition field of the get slot status command.
- */
-#define PCIMSG_SLOTCOND_UNKNOWN 0x0
-#define PCIMSG_SLOTCOND_GOOD 0x1
-#define PCIMSG_SLOTCOND_REC_FAIL 0x2
-#define PCIMSG_SLOTCOND_OCC_FAIL 0x3
-
-/*
- * Values for the slot_freq_cap and slot_freq_setting fields of the get
- * slot status command.
- */
-#define PCIMSG_FREQ_33MHZ 0x0
-#define PCIMSG_FREQ_66MHZ 0x1
-#define PCIMSG_FREQ_90MHZ 0x2
-#define PCIMSG_FREQ_133MHZ 0x3
-
-/*
- * Values for the slot_mode_cap and slot_mode_setting of the get
- * slot status command.
- */
-#define PCIMSG_MODE_CONVEN 0x0
-#define PCIMSG_MODE_PCIX 0x1
-
-/*
- * Values for the PRSNT signals.
- */
-#define PCIMSG_PRSNT_NOADAPTER 0x0
-#define PCIMSG_PRSNT_25W 0x1
-#define PCIMSG_PRSNT_15W 0x2
-#define PCIMSG_PRSNT_7_5W 0x3
-
-/*
- * Values to turn on and off slot characteristics.
- */
-#define PCIMSG_ON 0x1
-#define PCIMSG_OFF 0x0
-
-/*
- * Values to set the power, service and fault LEDs
- */
-#define PCIMSG_LED_OFF 0x00
-#define PCIMSG_LED_ON 0x01
-#define PCIMSG_LED_FLASH 0x02
-
-/*
- * Return values for the slot_replystatus field for the get/set slot status
- * commands.
- */
-#define PCIMSG_REPLY_GOOD 0x0
-#define PCIMSG_REPLY_FAIL 0x1
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_SCHPC_MSG_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/sckm_msg.h b/usr/src/uts/sun4u/starcat/sys/sckm_msg.h
deleted file mode 100644
index fc2727a047..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/sckm_msg.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_SCKM_MSG_H
-#define _SYS_SCKM_MSG_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * This header file describes the format of the IOSRAM mailbox messages
- * exchanged between the sckmr driver on a Starcat Domain and the
- * Starcat System Controller.
- */
-
-#include <sys/types.h>
-
-/*
- * MBOXSC_MSG_EVENT or MBOXSC_MSG_REQUEST message header.
- */
-typedef struct sckm_mbox_req_hdr {
- uint32_t sckm_version; /* protocol version */
- uint32_t reserved;
-} sckm_mbox_req_hdr_t;
-
-/*
- * MBOXSC_MSG_REPLY message header
- */
-typedef struct sckm_mbox_rep_hdr {
- uint32_t sckm_version; /* protocol version */
- uint32_t status; /* error code */
- uint32_t sadb_msg_errno; /* PF_KEY errno, if applicable */
- uint32_t sadb_msg_version; /* PF_KEY version, if applicable */
-} sckm_mbox_rep_hdr_t;
-
-/*
- * Version of this current protocol.
- */
-#define SCKM_PROTOCOL_VERSION 1
-
-/*
- * Keys for SC to Domain and Domain to SC mailboxes
- */
-#define KEY_SCKD 0x53434b44 /* SC to Domain mailbox */
-#define KEY_KDSC 0x4b445343 /* Domain to SC mailbox */
-
-/*
- * Max data size, in bytes, for IOSRAM mailboxes
- */
-#define SCKM_SCKD_MAXDATA 1024
-#define SCKM_KDSC_MAXDATA 1024
-
-/*
- * Message types.
- */
-#define SCKM_MSG_SADB 0x1 /* SADB message SC<->D */
-
-/*
- * Values for sckm_msg_rep_hdr status field.
- */
-#define SCKM_SUCCESS 0x0 /* Operation succeeded */
-#define SCKM_ERR_VERSION 0x1 /* Unexpected version */
-#define SCKM_ERR_SADB_PFKEY 0x2 /* PF_KEY returned an error */
-#define SCKM_ERR_SADB_MSG 0x3 /* bad SADB msg detect by driver */
-#define SCKM_ERR_DAEMON 0x4 /* Error communicating with daemon */
-#define SCKM_ERR_BAD_CMD 0x5 /* unknown command */
-#define SCKM_ERR_SADB_VERSION 0x6 /* bad SADB version */
-#define SCKM_ERR_SADB_TIMEOUT 0x7 /* no response from key engine */
-#define SCKM_ERR_SADB_BAD_TYPE 0x8 /* bad SADB msg type */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_SCKM_MSG_H */
diff --git a/usr/src/uts/sun4u/starcat/sys/starcat.h b/usr/src/uts/sun4u/starcat/sys/starcat.h
deleted file mode 100644
index b5af261bf2..0000000000
--- a/usr/src/uts/sun4u/starcat/sys/starcat.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_STARCAT_H
-#define _SYS_STARCAT_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Manifest constants of Starcat configuration
- */
-
-#define STARCAT_BDSET_MAX 18 /* maximum number of boardsets */
-
-#define STARCAT_BDSET_MIN 1 /* minimum number of boardsets */
-
-#define STARCAT_BDSET_SLOT_MAX 2 /* maximum slots per boardset */
-
-#define STARCAT_SLOT0_CPU_MAX 8 /* max CPUs per slot 0 board */
-
-#define STARCAT_SLOT1_CPU_MAX 4 /* max CPUs per slot 1 board */
-
-#define STARCAT_BDSET_CPU_MAX 12 /* maximum CPUs per boardset */
-
-#define STARCAT_SLOT0_MEM_MAX 4 /* max mem units per slot 0 bd */
-
-#define STARCAT_SLOT1_MEM_MAX 0 /* max mem units per slot 1 bd */
-
-#define STARCAT_BDSET_MEM_MAX 4 /* max mem units per boardset */
-
-#define STARCAT_SLOT0_IO_MAX 0 /* max I/O ctrlrs per slot 0 bd */
-
-#define STARCAT_SLOT1_IO_MAX 2 /* max I/O ctrlrs per slot 1 bd */
-
-#define STARCAT_BDSET_IO_MAX 2 /* max I/O ctrlrs per boardset */
-
-#define STARCAT_TSB_PER_IO 2 /* each IO has two leaves */
-
- /* max prealloc spare tsb's */
-#define STARCAT_SPARE_TSB_MAX \
- (STARCAT_BDSET_MAX * STARCAT_BDSET_IO_MAX * STARCAT_TSB_PER_IO)
-
-/*
- * Data bearing mondo vector (DMV) support
- *
- * For Starcat, we need to add a few extra "hardware" dmv interrupts.
- * These actually do not correspond to physical hardware but are used
- * by Starcat IDN.
- */
-#define STARCAT_DMV_EXTRA 4
-#define STARCAT_DMV_HWINT (MAX_UPA + STARCAT_DMV_EXTRA)
-#define STARCAT_DMV_IDN_BASE (MAX_UPA)
-
-/*
- * The CPU ID on starcat looks like this:
- *
- * 9 5 4 3 2 1 0
- * --------------------------------------
- * | Expander | | Slot | Core | LPORT |
- * --------------------------------------
- *
- * Expander Starcat has STARCAT_BDSET_MAX (18) expanders.
- * Slot Starcat has STARCAT_BDSET_SLOT_MAX (2) slots per expander.
- * Slot 0 carries a CPU-MEM board which has 4 processor chips.
- * Slot 1 carries an I/O board typically. But it can be
- * configured to carry a MAXCAT board which has 2 processor
- * chips on board.
- * LPORT Port number within the slot for a chip. This is also the
- * chip number within the slot. Note that Slot 1 can have only
- * 2 chips, but this representation allows for 4. This is just
- * the theoretical max.
- * Core Core number within the chip.
- *
- * Currently, the maximum number of cores supported is 2 per chip (on
- * Panther and Jaguar).
- *
- */
-/*
- * Macros for manipulating CPU IDs
- */
-#define STARCAT_CPUID_TO_EXPANDER(p) (((p) >> 5) & 0x1f)
-#define STARCAT_CPUID_TO_BOARDSLOT(p) (((p) >> 3) & 0x1)
-#define STARCAT_CPUID_TO_PORTID(p) ((p) & ~0x4)
-#define STARCAT_CPUID_TO_COREID(p) (((p) >> 2) & 0x1)
-#define STARCAT_CPUID_TO_CORE_BIT(p) ((p) & (0x1 << 2))
-#define STARCAT_CPUID_TO_AGENT(p) ((p) & 0x7)
-#define STARCAT_CPUID_TO_LPORT(p) ((p) & 0x3)
-
-#define MAKE_CPUID(e, s, a) \
- ((((e) & 0x1f) << 5) | (((s) & 0x1) << 3) | ((a) & 0x7))
-
-/*
- * Definitions for decoding memory controller registers. These values
- * are taken from Chapter 9 of the SPARCV9 JSP-1 US-III implementation
- * supplement.
- */
-
-/* Starcat has four banks of memory per MC */
-#define MAX_BANKS_PER_MC (4)
-
-/* Use only low bits for local CPU MC ASI */
-#define MC_OFFSET_MASK (0xffu)
-
-/* Shifts to access specific fields of the memdecode register */
-#define MC_VALID_SHIFT (63) /* Shift for valid bit */
-#define MC_UK_SHIFT (41) /* Shift for upper mask field */
-#define MC_UM_SHIFT (20) /* Shift for upper match field */
-#define PHYS2UM_SHIFT (26) /* UM field matches bits 42-26 of PA */
-
-/* Extract upper mask field from the decode register */
-#define MC_UK(memdec) (((memdec) >> MC_UK_SHIFT) & 0xfffu)
-
-/* Extract upper match field from memdecode register */
-#define MC_UM(memdec) (((memdec) >> MC_UM_SHIFT) & 0x1fffffu)
-
-/* Size of the range covered by the address mask field */
-#define MC_UK2SPAN(memdec) ((MC_UK(memdec) + 1) << PHYS2UM_SHIFT)
-
-/* The base PA the memdecode register will respond to */
-#define MC_BASE(memdec) (MC_UM(memdec) & ~(MC_UK(memdec)))
-
-
-/*
- * Prototypes for functions
- */
-
-extern int set_platform_max_ncpus(void);
-extern int plat_max_boards(void);
-extern int plat_max_cpu_units_per_board(void);
-extern int plat_max_mem_units_per_board(void);
-extern int plat_max_io_units_per_board(void);
-extern uint64_t lddmcdecode(uint64_t);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_STARCAT_H */
diff --git a/usr/src/uts/sun4u/starcat/unix/Makefile b/usr/src/uts/sun4u/starcat/unix/Makefile
deleted file mode 100644
index 7881e5b2c4..0000000000
--- a/usr/src/uts/sun4u/starcat/unix/Makefile
+++ /dev/null
@@ -1,195 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# This makefile drives the production of unix (and unix.o).
-#
-# sun4u starcat implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../../..
-
-#
-# Define the module and object file sets.
-#
-UNIX = unix
-OBJECTS = $(SPECIAL_OBJS:%=$(OBJS_DIR)/%) \
- $(CORE_OBJS:%=$(OBJS_DIR)/%) \
- $(MACH_NOT_YET_KMODS:%=$(OBJS_DIR)/%)
-LINTS = $(SPECIAL_OBJS:%.o=$(LINTS_DIR)/%.ln) \
- $(CORE_OBJS:%.o=$(LINTS_DIR)/%.ln) \
- $(MACH_NOT_YET_KMODS:%.o=$(LINTS_DIR)/%.ln) \
- $(LINTS_DIR)/vers.ln \
- $(LINTS_DIR)/modstubs.ln
-
-KRTLD_MAPFILE = $(UTSBASE)/sparc/krtld/mapfile
-KRTLD_OBJECTS = $(KRTLD_OBJS:%=$(OBJS_DIR)/%)
-KRTLD_O = $(OBJS_DIR)/krtld.o
-
-ROOTMODULE = $(ROOT_STARCAT_KERN_DIR)/$(UNIX)
-UNIX_BIN = $(OBJS_DIR)/$(UNIX)
-
-LIBS = $(GENLIB) $(PLATLIB) $(CPULIB)
-
-GENUNIX = genunix
-GENUNIX_DIR = ../../$(GENUNIX)
-GENOPTS = -L $(GENUNIX_DIR)/$(OBJS_DIR) -l $(GENUNIX)
-
-CPU_DIR = .
-CPUOPTS = -L $(CPU_DIR)/$(OBJS_DIR) -l $(CPUNAME)
-
-PLAT_DIR = ../../platmod
-PLATOPTS = -L $(PLAT_DIR)/$(OBJS_DIR) -l $(PLATMOD)
-
-LIBOPTS = $(GENOPTS) $(PLATOPTS) $(CPUOPTS)
-
-CTFEXTRAOBJS = $(OBJS_DIR)/vers.o
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(UNIX_BIN)
-LINT_TARGET = $(LINT_LIB)
-INSTALL_TARGET = $(UNIX_BIN) $(ROOTMODULE)
-
-#
-# Overrides
-#
-ALL_BUILDS = $(ALL_BUILDSONLY64)
-DEF_BUILDS = $(DEF_BUILDSONLY64)
-SYM_BUILDS = $(DEF_BUILDSONLY64)
-CLEANLINTFILES += $(LINT32_FILES)
-
-#
-# This is UNIX_DIR. Use a short path.
-#
-UNIX_DIR = .
-
-#
-# Overrides
-#
-CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(KRTLD_O) $(KRTLD_OBJECTS) \
- $(OBJS_DIR)/vers.c $(OBJS_DIR)/vers.o \
- $(CPU_OBJ) $(CPULIB) \
- $(DTRACESTUBS_O) $(DTRACESTUBS)
-
-CLOBBERFILES = $(CLEANFILES) $(UNIX_BIN)
-CLEANLINTFILES += $(LINT_LIB)
-
-#
-# lint pass one enforcement
-# Turn on doubleword alignment for 64 bit counter timer registers
-#
-CFLAGS += $(CCVERBOSE) -dalign
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-char-subscripts
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-unused-function
-CERRWARN += -_gcc=-Wno-unused-label
-CERRWARN += -_gcc=-Wno-type-limits
-CERRWARN += -_gcc=-Wno-clobbered
-CERRWARN += -_gcc=-Wno-empty-body
-CERRWARN += -_gcc=-Wno-unused-value
-CERRWARN += -_gcc=-Wno-switch
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-symcheck: $(SYM_DEPS)
-
-$(UNIX_BIN): $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) \
- $(DTRACESTUBS)
- $(LD) -dy -b -o $@ -e _start -M $(MAPFILE) \
- $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
- $(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
- $(POST_PROCESS)
- $(CHK4UBINARY)
-
-symcheck.targ: $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBS) $(DTRACESTUBS)
- $(LD) -dy -b -o $(SYM_MOD) -M $(MAPFILE) \
- $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
-
-$(UNIX_O): $(OBJECTS) $(OBJS_DIR)/vers.o
- $(LD) -r -o $@ $(OBJECTS) $(OBJS_DIR)/vers.o
-
-$(KRTLD_O): $(KRTLD_OBJECTS)
- $(LD) -r -o $@ -M$(KRTLD_MAPFILE) $(KRTLD_OBJECTS)
-
-#
-# CPU_OBJ now comprises of 2 object files which come from sun4 common
-# and from architecture dependent code. OBJS_DIR is prepended where
-# CPU_DIR is defined to allow for building multiple CPU_OBJ's
-#
-$(CPULIB): $(CPU_OBJ)
- $(BUILD.SO) $(CPU_OBJ)
-
-#
-# The global lint target builds the kernel lint library (llib-lunix.ln)
-# which is equivalent to a lint of /unix.o. Then all kernel modules for
-# this architecture are linted against the kernel lint library.
-#
-# Note: lint errors in the kernel lint library will be repeated for
-# each module. It is important that the kernel lint library
-# be clean to keep the textual output to a reasonable level.
-#
-
-$(LINT_LIB): $(LINT_LIB_DIR) $(LINTS)
- @-$(ECHO) "\n$(UNIX): (library construction):"
- @$(LINT) -o $(UNIX) $(LINTFLAGS) $(LINTS)
- @$(MV) $(@F) $@
-
-lintlib: $(LINT_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/starcat/Makefile.targ
diff --git a/usr/src/uts/sun4u/sys/pci/pci_axq.h b/usr/src/uts/sun4u/sys/pci/pci_axq.h
deleted file mode 100644
index 7cb0e14ba4..0000000000
--- a/usr/src/uts/sun4u/sys/pci/pci_axq.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _SYS_PCI_AXQ_H
-#define _SYS_PCI_AXQ_H
-
-#include <sys/types.h>
-#include <sys/atomic.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PIO_LIMIT_ENTER(p) { \
- int n;\
- for (;;) {\
- do {\
- n = p->pbm_pio_counter;\
- } while (n <= 0);\
- if (atomic_dec_32_nv(\
- (uint_t *)&p->pbm_pio_counter)\
- == (n - 1))\
- break;\
- atomic_inc_32(\
- (uint_t *)&p->pbm_pio_counter);\
- }\
- }
-
-
-
-#define PIO_LIMIT_EXIT(p) atomic_inc_32((uint_t *)&p->pbm_pio_counter);
-
-extern void pci_axq_setup(ddi_map_req_t *mp, pbm_t *pbm_p);
-extern void pci_axq_pio_limit(pbm_t *pbm_p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_PCI_AXQ_H */
diff --git a/usr/src/uts/sun4u/sys/pci/pci_obj.h b/usr/src/uts/sun4u/sys/pci/pci_obj.h
index d71c4942ab..02f3e0e373 100644
--- a/usr/src/uts/sun4u/sys/pci/pci_obj.h
+++ b/usr/src/uts/sun4u/sys/pci/pci_obj.h
@@ -23,6 +23,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright 2019 Peter Tribble.
+ */
+
#ifndef _SYS_PCI_OBJ_H
#define _SYS_PCI_OBJ_H
@@ -56,7 +60,6 @@ extern "C" {
#ifdef PCI_DMA_TEST
#include <sys/pci/pci_test.h>
#endif
-#include <sys/pci/pci_axq.h>
#ifdef __cplusplus
}
diff --git a/usr/src/uts/sun4u/sys/prom_plat.h b/usr/src/uts/sun4u/sys/prom_plat.h
index 39616187ca..35a5ef590a 100644
--- a/usr/src/uts/sun4u/sys/prom_plat.h
+++ b/usr/src/uts/sun4u/sys/prom_plat.h
@@ -253,16 +253,6 @@ extern int prom_serengeti_detach_board(uint_t node, uint_t board);
extern int prom_serengeti_tunnel_switch(uint_t node, uint_t board);
/*
- * Starcat-specific routines
- */
-extern int prom_starcat_switch_tunnel(uint_t portid,
- uint_t msgtype);
-extern int prom_starcat_iosram_read(uint32_t key, uint32_t offset,
- uint32_t len, caddr_t buf);
-extern int prom_starcat_iosram_write(uint32_t key, uint32_t offset,
- uint32_t len, caddr_t buf);
-
-/*
* OPL-specific routines
*/
extern void prom_opl_get_tod(time_t *time, int64_t *stickval);
diff --git a/usr/src/uts/sun4u/todstarcat/Makefile b/usr/src/uts/sun4u/todstarcat/Makefile
deleted file mode 100644
index f7fd26cc89..0000000000
--- a/usr/src/uts/sun4u/todstarcat/Makefile
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# uts/sun4u/todstarcat/Makefile
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# This makefile drives the production of the todstarcat
-# kernel module.
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = todstarcat
-OBJECTS = $(TODSTARCAT_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(TODSTARCAT_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_PSM_TOD_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sun4u/Makefile.sun4u
-
-INC_PATH += -I$(UTSBASE)/sun4u/starcat
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# module dependencies
-#
-LDFLAGS += -dy -Ndrv/sbbc -Ndrv/iosram
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sun4u/Makefile.targ