summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/Makefile.ast3
-rw-r--r--usr/src/cmd/abi/appcert/static_prof/static_prof.c44
-rw-r--r--usr/src/cmd/fs.d/nfs/svc/nfs-server4
-rw-r--r--usr/src/cmd/hal/hald/hald_dbus.c2
-rw-r--r--usr/src/cmd/mdb/common/modules/mac/mac.c2
-rw-r--r--usr/src/cmd/stat/vfsstat/vfsstat.pl27
-rw-r--r--usr/src/cmd/zfs/zfs_main.c8
-rw-r--r--usr/src/grub/grub-0.97/netboot/pcnet32.c2
-rw-r--r--usr/src/lib/brand/joyent/zone/statechange.ksh8
-rwxr-xr-xusr/src/lib/brand/kvm/zone/statechange.ksh8
-rw-r--r--usr/src/lib/libdladm/common/libdladm.c10
-rw-r--r--usr/src/lib/libiscsit/common/libiscsit.c7
-rw-r--r--usr/src/lib/libiscsit/common/libiscsit.h10
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c4
-rw-r--r--usr/src/man/man7d/bge.7d10
-rw-r--r--usr/src/man/man7d/eri.7d2
-rw-r--r--usr/src/man/man7d/hme.7d2
-rw-r--r--usr/src/man/man7d/igb.7d6
-rw-r--r--usr/src/man/man7d/nxge.7d4
-rw-r--r--usr/src/man/man7d/pcn.7d4
-rw-r--r--usr/src/man/man7d/vr.7d8
-rw-r--r--usr/src/tools/ctf/cvt/dwarf.c9
-rw-r--r--usr/src/tools/scripts/hgsetup.sh2
-rw-r--r--usr/src/uts/common/inet/ipf/netinet/ip_compat.h2
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_buf.c5
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_fm.c7
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_gld.c78
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_hw.c79
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_intr.c19
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_main.c76
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_mbx.c44
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_mq.c5
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_queue.c63
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_rx.c9
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_stat.c67
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_tx.c23
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/oce/oce_utils.c5
-rw-r--r--usr/src/uts/common/io/power.c58
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/oce/oce_buf.h7
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw.h80
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw_eth.h5
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/oce/oce_impl.h39
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/oce/oce_io.h30
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/oce/oce_ioctl.h21
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/oce/oce_stat.h22
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/oce/oce_utils.h5
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/oce/oce_version.h9
-rw-r--r--usr/src/uts/i86pc/io/acpi/acpinex/acpinex_event.c7
-rw-r--r--usr/src/uts/i86pc/io/pcplusmp/apic_timer.c42
-rw-r--r--usr/src/uts/i86pc/os/cpr_impl.c11
-rw-r--r--usr/src/uts/intel/io/acpica/acpica.c159
-rw-r--r--usr/src/uts/intel/io/acpica/acpica_ec.c568
-rw-r--r--usr/src/uts/intel/io/acpica/osl.c2
-rw-r--r--usr/src/uts/intel/sys/acpi/platform/acsolaris.h4
54 files changed, 1120 insertions, 617 deletions
diff --git a/usr/src/Makefile.ast b/usr/src/Makefile.ast
index 7b1f5aadbc..4dda28afa2 100644
--- a/usr/src/Makefile.ast
+++ b/usr/src/Makefile.ast
@@ -80,6 +80,3 @@ ASTCFLAGS64 = \
$(CCVERBOSE) \
-_cc=-xcsi \
-xstrconst
-
-# We need this for C99/VLA support
-DEBUGFORMAT=-xdebugformat=dwarf
diff --git a/usr/src/cmd/abi/appcert/static_prof/static_prof.c b/usr/src/cmd/abi/appcert/static_prof/static_prof.c
index b84fe523ed..7d2d71c20f 100644
--- a/usr/src/cmd/abi/appcert/static_prof/static_prof.c
+++ b/usr/src/cmd/abi/appcert/static_prof/static_prof.c
@@ -28,6 +28,9 @@
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
+/* Copyright 2011 Nexenta Systems, Inc. All rights reserved. */
+
+
/* ------------------------------------------------------------------------ */
/* include headers */
/* ------------------------------------------------------------------------ */
@@ -97,42 +100,27 @@ store_binding(binding_bucket * bind)
{
unsigned long bktno;
unsigned long orig_bktno;
- int table_full = FALSE;
- int i;
bktno = my_elf_hash(bind->sym) % DEFBKTS;
orig_bktno = bktno;
- if (!bkts[bktno].sym) {
- bkts[bktno].sym = bind->sym;
- bkts[bktno].obj = bind->obj;
- bkts[bktno].ref_lib = bind->ref_lib;
- bkts[bktno].def_lib = bind->def_lib;
- bkts[bktno].section = bind->section;
- bkts[bktno].stbind = bind->stbind;
- bkts[bktno].sttype = bind->sttype;
- } else {
+ while (bkts[bktno].sym != NULL) {
bktno = (bktno + 1) % DEFBKTS;
- for (i = bktno; i < DEFBKTS; i = (i + 1) % DEFBKTS) {
- if (i == orig_bktno) {
- table_full = TRUE;
- exit(1);
- }
- if (!bkts[i].sym)
- break;
- }
- if ((i < DEFBKTS) && (!bkts[i].sym) && (table_full != TRUE)) {
- bkts[i].sym = bind->sym;
- bkts[i].obj = bind->obj;
- bkts[i].ref_lib = bind->ref_lib;
- bkts[i].def_lib = bind->def_lib;
- bkts[i].section = bind->section;
- bkts[i].stbind = bind->stbind;
- bkts[i].sttype = bind->sttype;
- }
+
+ if (bktno == orig_bktno)
+ exit(1);
}
+
+ bkts[bktno].sym = bind->sym;
+ bkts[bktno].obj = bind->obj;
+ bkts[bktno].ref_lib = bind->ref_lib;
+ bkts[bktno].def_lib = bind->def_lib;
+ bkts[bktno].section = bind->section;
+ bkts[bktno].stbind = bind->stbind;
+ bkts[bktno].sttype = bind->sttype;
}
+
/* ========== check_store_binding ========================================= */
/*
* DESCRIPTION:
diff --git a/usr/src/cmd/fs.d/nfs/svc/nfs-server b/usr/src/cmd/fs.d/nfs/svc/nfs-server
index 09bb057e43..271f79c483 100644
--- a/usr/src/cmd/fs.d/nfs/svc/nfs-server
+++ b/usr/src/cmd/fs.d/nfs/svc/nfs-server
@@ -49,13 +49,13 @@ configure_ipfilter()
#
# Nothing to do if:
+ # - service's policy is 'use_global'
# - ipfilter isn't online
# - global policy is 'custom'
- # - service's policy is 'use_global'
#
+ [ "`get_policy $SMF_FMRI`" = "use_global" ] && return 0
service_check_state $IPF_FMRI $SMF_ONLINE || return 0
[ "`get_global_def_policy`" = "custom" ] && return 0
- [ "`get_policy $SMF_FMRI`" = "use_global" ] && return 0
svcadm restart $IPF_FMRI
}
diff --git a/usr/src/cmd/hal/hald/hald_dbus.c b/usr/src/cmd/hal/hald/hald_dbus.c
index 72ce93b0a6..51fe5206a4 100644
--- a/usr/src/cmd/hal/hald/hald_dbus.c
+++ b/usr/src/cmd/hal/hald/hald_dbus.c
@@ -3295,7 +3295,7 @@ hald_exec_method_cb (HalDevice *d, guint32 exit_type,
* otherwise, dbus will be messed up.
*/
invalid_name = TRUE;
- exp_detail = g_strconcat (exp_name, " \n ", exp_detail, (char *)NULL);
+ exp_detail = g_strconcat (exp_name, " \n ", exp_detail, (void *)NULL);
exp_name = "org.freedesktop.Hal.Device.UnknownError";
}
reply = dbus_message_new_error (message, exp_name, exp_detail);
diff --git a/usr/src/cmd/mdb/common/modules/mac/mac.c b/usr/src/cmd/mdb/common/modules/mac/mac.c
index 268d92ac2d..29fe51870d 100644
--- a/usr/src/cmd/mdb/common/modules/mac/mac.c
+++ b/usr/src/cmd/mdb/common/modules/mac/mac.c
@@ -107,7 +107,7 @@ mac_flow_priority2str(mac_priority_level_t prio)
}
/*
- * Convert bandwidth in bps to a string in mpbs.
+ * Convert bandwidth in bps to a string in Mbps.
*/
static char *
mac_flow_bw2str(uint64_t bw, char *buf, ssize_t len)
diff --git a/usr/src/cmd/stat/vfsstat/vfsstat.pl b/usr/src/cmd/stat/vfsstat/vfsstat.pl
index 7da629a3f5..d9abc2701c 100644
--- a/usr/src/cmd/stat/vfsstat/vfsstat.pl
+++ b/usr/src/cmd/stat/vfsstat/vfsstat.pl
@@ -102,23 +102,23 @@ my @fields = ( 'reads', 'writes', 'nread', 'nwritten', 'rtime', 'wtime',
chomp(my $curzone = (`/sbin/zonename`));
-# Read list of visible zones and their zone IDs
-my @zones = ();
-my %zoneids = ();
-my $zoneadm = `zoneadm list -p | cut -d: -f1,2`;
-@lines = split(/\n/, $zoneadm);
-foreach $line (@lines) {
- @tok = split(/:/, $line);
- $zoneids->{$tok[1]} = $tok[0];
- push(@zones, $tok[1]);
-}
-
my %old = ();
my $rows_printed = 0;
-$Kstat->update();
-
for (my $ii = 0; $ii < $count; $ii++) {
+ # Read list of visible zones and their zone IDs
+ my @zones = ();
+ my %zoneids = ();
+ my $zoneadm = `zoneadm list -p | cut -d: -f1,2`;
+ @lines = split(/\n/, $zoneadm);
+ foreach $line (@lines) {
+ @tok = split(/:/, $line);
+ $zoneids->{$tok[1]} = $tok[0];
+ push(@zones, $tok[1]);
+ }
+
+ $Kstat->update();
+
# Print the column header every 20 rows
if ($rows_printed == 0 || $ALL_ZONES) {
printf($HEADER_FMT, $INTERVAL_SUFFIX, $INTERVAL_SUFFIX,
@@ -151,7 +151,6 @@ for (my $ii = 0; $ii < $count; $ii++) {
}
sleep ($interval);
- $Kstat->update();
}
exit(0);
diff --git a/usr/src/cmd/zfs/zfs_main.c b/usr/src/cmd/zfs/zfs_main.c
index d041c33029..a72e915c17 100644
--- a/usr/src/cmd/zfs/zfs_main.c
+++ b/usr/src/cmd/zfs/zfs_main.c
@@ -4969,9 +4969,9 @@ zfs_do_allow_unallow_impl(int argc, char **argv, boolean_t un)
parse_allow_args(argc, argv, un, &opts);
/* try to open the dataset */
- if ((zhp = zfs_open(g_zfs, opts.dataset, ZFS_TYPE_FILESYSTEM))
- == NULL) {
- (void) fprintf(stderr, "Failed to open Dataset *%s*\n",
+ if ((zhp = zfs_open(g_zfs, opts.dataset, ZFS_TYPE_FILESYSTEM |
+ ZFS_TYPE_VOLUME)) == NULL) {
+ (void) fprintf(stderr, "Failed to open dataset: %s\n",
opts.dataset);
return (-1);
}
@@ -4981,7 +4981,7 @@ zfs_do_allow_unallow_impl(int argc, char **argv, boolean_t un)
fs_perm_set_init(&fs_perm_set);
if (parse_fs_perm_set(&fs_perm_set, perm_nvl) != 0) {
- (void) fprintf(stderr, "Failed to parse fsacl permissionsn");
+ (void) fprintf(stderr, "Failed to parse fsacl permissions\n");
goto cleanup1;
}
diff --git a/usr/src/grub/grub-0.97/netboot/pcnet32.c b/usr/src/grub/grub-0.97/netboot/pcnet32.c
index f7bd1f6d10..c7beb14012 100644
--- a/usr/src/grub/grub-0.97/netboot/pcnet32.c
+++ b/usr/src/grub/grub-0.97/netboot/pcnet32.c
@@ -479,7 +479,7 @@ static void pcnet32_reset(struct nic *nic)
lp->a.write_csr(ioaddr, 124, val);
if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
- val = lp->a.read_bcr(ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */
+ val = lp->a.read_bcr(ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mbps, HD */
if (lp->options & PCNET32_PORT_FD)
val |= 0x10;
if (lp->options & PCNET32_PORT_100)
diff --git a/usr/src/lib/brand/joyent/zone/statechange.ksh b/usr/src/lib/brand/joyent/zone/statechange.ksh
index 7d7d0213a4..ba4df02b99 100644
--- a/usr/src/lib/brand/joyent/zone/statechange.ksh
+++ b/usr/src/lib/brand/joyent/zone/statechange.ksh
@@ -142,6 +142,14 @@ setup_net()
orig_global=$global_nic
global_nic=$(eval echo \$SYSINFO_NIC_${orig_global})
+ # If the global nic is specified as a device or etherstub name
+ # rather than a tag
+ if [[ -z $global_nic ]]; then
+ echo "$(dladm show-phys -p -o LINK) $(dladm show-etherstub -p -o LINK)" \
+ | egrep "(^| )${orig_global}( |$)" > /dev/null
+ (( $? == 0 )) && global_nic=${orig_global}
+ fi
+
# For backwards compatibility with the other parts of the
# system, check if this zone already has this vnic setup.
# If so, move on to the next vnic.
diff --git a/usr/src/lib/brand/kvm/zone/statechange.ksh b/usr/src/lib/brand/kvm/zone/statechange.ksh
index 6efe6f3cb5..7c08ce6ea9 100755
--- a/usr/src/lib/brand/kvm/zone/statechange.ksh
+++ b/usr/src/lib/brand/kvm/zone/statechange.ksh
@@ -115,6 +115,14 @@ setup_net()
orig_global=$global_nic
global_nic=$(eval echo \$SYSINFO_NIC_${orig_global})
+ # If the global nic is specified as a device or etherstub name
+ # rather than a tag
+ if [[ -z $global_nic ]]; then
+ echo "$(dladm show-phys -p -o LINK) $(dladm show-etherstub -p -o LINK)" \
+ | egrep "(^| )${orig_global}( |$)" > /dev/null
+ (( $? == 0 )) && global_nic=${orig_global}
+ fi
+
# For backwards compatibility with the other parts of the
# system, check if this zone already has this vnic setup.
# If so, move on to the next vnic.
diff --git a/usr/src/lib/libdladm/common/libdladm.c b/usr/src/lib/libdladm/common/libdladm.c
index 7ecb54ab54..e0150d6529 100644
--- a/usr/src/lib/libdladm/common/libdladm.c
+++ b/usr/src/lib/libdladm/common/libdladm.c
@@ -535,10 +535,10 @@ dladm_str2bw(char *oarg, uint64_t *bw)
}
/*
- * Convert bandwidth in bps to a string in mpbs. For values greater
- * than 1mbps or 1000000, print a whole mbps value. For values that
- * have fractional Mbps in whole Kbps , print the bandwidth in a manner
- * simlilar to a floating point format.
+ * Convert bandwidth in bps to a string in Mbps. For values greater
+ * than 1Mbps or 1000000, print a whole Mbps value. For values that
+ * have fractional Mbps in whole Kbps, print the bandwidth in a manner
+ * similar to a floating point format.
*
* bps string
* 0 0
@@ -1069,7 +1069,7 @@ fail:
/*
* Convert an array of strings (which can be ranges or individual
* elements) into a single mac_propval_range_t structure which
- * allocated here but should be freed by the caller.
+ * is allocated here but should be freed by the caller.
*/
dladm_status_t
dladm_strs2range(char **prop_val, uint_t val_cnt,
diff --git a/usr/src/lib/libiscsit/common/libiscsit.c b/usr/src/lib/libiscsit/common/libiscsit.c
index 9530419701..c45b9b1c1d 100644
--- a/usr/src/lib/libiscsit/common/libiscsit.c
+++ b/usr/src/lib/libiscsit/common/libiscsit.c
@@ -21,6 +21,9 @@
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
+/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/stat.h>
@@ -1846,10 +1849,10 @@ it_iqn_generate(char *iqn_buf, int iqn_buf_len, char *opt_iqn_suffix)
uuid_unparse(id, id_str);
if (opt_iqn_suffix) {
- ret = snprintf(iqn_buf, iqn_buf_len, "iqn.1986-03.com.sun:"
+ ret = snprintf(iqn_buf, iqn_buf_len, DEFAULT_IQN
"%02d:%s.%s", TARGET_NAME_VERS, id_str, opt_iqn_suffix);
} else {
- ret = snprintf(iqn_buf, iqn_buf_len, "iqn.1986-03.com.sun:"
+ ret = snprintf(iqn_buf, iqn_buf_len, DEFAULT_IQN
"%02d:%s", TARGET_NAME_VERS, id_str);
}
diff --git a/usr/src/lib/libiscsit/common/libiscsit.h b/usr/src/lib/libiscsit/common/libiscsit.h
index 861529e86f..704c790edc 100644
--- a/usr/src/lib/libiscsit/common/libiscsit.h
+++ b/usr/src/lib/libiscsit/common/libiscsit.h
@@ -22,6 +22,9 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ */
#ifndef _LIBISCSIT_H
#define _LIBISCSIT_H
@@ -45,6 +48,13 @@ extern "C" {
#define IS_EUI_NAME(s) (strncmp((s), "eui.", 4) == 0)
/*
+ * We change the default IQN here to org.illumos.
+ * Other distros using it need to change accordingly.
+ */
+
+#define DEFAULT_IQN "iqn.2010-08.org.illumos:"
+
+/*
* Object Hierarchy
*
* _______________________
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
index 706ca9e61e..b938851c78 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
@@ -420,8 +420,8 @@ smb_netbios_cache_status(unsigned char *buf, int bufsize, unsigned char *scope)
(strcasecmp((char *)scope, (char *)name->scope) == 0)) {
bcopy(name->name, scan, NETBIOS_NAME_SZ);
scan += NETBIOS_NAME_SZ;
- *scan++ = (uint8_t)(PUBLIC_BITS(name->attributes) >> 8);
- *scan++ = (uint8_t)PUBLIC_BITS(name->attributes);
+ *scan++ = (PUBLIC_BITS(name->attributes) >> 8) & 0xff;
+ *scan++ = PUBLIC_BITS(name->attributes) & 0xff;
(*numnames)++;
}
diff --git a/usr/src/man/man7d/bge.7d b/usr/src/man/man7d/bge.7d
index 055831aa51..d9be2c667f 100644
--- a/usr/src/man/man7d/bge.7d
+++ b/usr/src/man/man7d/bge.7d
@@ -181,11 +181,11 @@ selected by the first non-zero parameter in priority order as listed below:
.nf
(highest priority/greatest throughput)
en_1000fdx_cap 1000Mbps full duplex
- en_1000hdx_cap 1000Mpbs half duplex
- en_100fdx_cap 100Mpbs full duplex
- en_100hdx_cap 100Mpbs half duplex
- en_10fdx_cap 10Mpbs full duplex
- en_10hdx_cap 10Mpbs half duplex
+ en_1000hdx_cap 1000Mbps half duplex
+ en_100fdx_cap 100Mbps full duplex
+ en_100hdx_cap 100Mbps half duplex
+ en_10fdx_cap 10Mbps full duplex
+ en_10hdx_cap 10Mbps half duplex
(lowest priority/least throughput)
.fi
.in -2
diff --git a/usr/src/man/man7d/eri.7d b/usr/src/man/man7d/eri.7d
index 7ac04e3112..58b5b9aa35 100644
--- a/usr/src/man/man7d/eri.7d
+++ b/usr/src/man/man7d/eri.7d
@@ -298,7 +298,7 @@ mode of the link and the common mode of operation with the link partner.
For users who want to select the speed and mode of the link, the \fBeri\fR
device supports programmable \fBIPG\fR (Inter-Packet Gap) parameters \fBipg1\fR
and \fBipg2\fR. Sometimes, the user may want to alter these values depending
-on whether the driver supports 10 Mbps or 100 Mpbs and accordingly, \fBIPG\fR
+on whether the driver supports 10 Mbps or 100 Mbps and accordingly, \fBIPG\fR
will be set to 9.6 or 0.96 microseconds.
.SS "eri Parameter List"
.sp
diff --git a/usr/src/man/man7d/hme.7d b/usr/src/man/man7d/hme.7d
index 94465348d6..79944244a2 100644
--- a/usr/src/man/man7d/hme.7d
+++ b/usr/src/man/man7d/hme.7d
@@ -337,7 +337,7 @@ Sometimes, the user may want to select the speed and mode of the link. The
parameters \fBipg1\fR and \fBipg2\fR. By default, the driver sets \fBipg1\fR
to 8 \fBbyte-times\fR and \fBipg2\fR to 4 \fBbyte-times\fR (which are the
standard values). Sometimes, the user may want to alter these values depending
-on whether the driver supports 10 Mbps or 100 Mpbs and accordingly, \fBIPG\fR
+on whether the driver supports 10 Mbps or 100 Mbps and accordingly, \fBIPG\fR
will be set to 9.6 or 0.96 microseconds.
.SS "hme Parameter List"
.sp
diff --git a/usr/src/man/man7d/igb.7d b/usr/src/man/man7d/igb.7d
index 9eaab07a06..81a0e0dfac 100644
--- a/usr/src/man/man7d/igb.7d
+++ b/usr/src/man/man7d/igb.7d
@@ -140,10 +140,10 @@ parameter in priority order as shown below:
.nf
(highest priority/greatest throughput)
adv_1000fdx_cap 1000Mbps full duplex
- adv_100fdx_cap 100Mpbs full duplex
+ adv_100fdx_cap 100Mbps full duplex
adv_100hdx_cap 100Mbps half duplex
- adv_10fdx_cap 10Mpbs full duplex
- adv_10hdx_cap 10Mpbs half duplex
+ adv_10fdx_cap 10Mbps full duplex
+ adv_10hdx_cap 10Mbps half duplex
(lowest priority/least throughput)
.fi
.in -2
diff --git a/usr/src/man/man7d/nxge.7d b/usr/src/man/man7d/nxge.7d
index 10f2a26337..b940e85cae 100644
--- a/usr/src/man/man7d/nxge.7d
+++ b/usr/src/man/man7d/nxge.7d
@@ -147,8 +147,8 @@ shown below:
.nf
(highest priority/greatest throughput)
en_1000fdx_cap 1000Mbps full duplex
- en_100fdx_cap 100Mpbs full duplex
- en_10fdx_cap 10Mpbs full duplex
+ en_100fdx_cap 100Mbps full duplex
+ en_10fdx_cap 10Mbps full duplex
(lowest priority/least throughput)
.fi
.in -2
diff --git a/usr/src/man/man7d/pcn.7d b/usr/src/man/man7d/pcn.7d
index a09a1835b8..2ae5d00638 100644
--- a/usr/src/man/man7d/pcn.7d
+++ b/usr/src/man/man7d/pcn.7d
@@ -112,8 +112,8 @@ parameter in priority order as shown below:
.in +2
.nf
(highest priority/greatest throughput)
- en_100fdx_cap 100Mpbs full duplex
- en_10fdx_cap 10Mpbs full duplex
+ en_100fdx_cap 100Mbps full duplex
+ en_10fdx_cap 10Mbps full duplex
(lowest priority/least throughput)
.fi
.in -2
diff --git a/usr/src/man/man7d/vr.7d b/usr/src/man/man7d/vr.7d
index 94fa6228c9..b6f98c46a1 100644
--- a/usr/src/man/man7d/vr.7d
+++ b/usr/src/man/man7d/vr.7d
@@ -46,10 +46,10 @@ combination from the first non-zero parameter from this list:
.sp
.in +2
.nf
-en_100fdx_cap 100Mpbs full duplex
-en_100hdx_cap 100Mpbs half duplex
-en_10fdx_cap 10Mpbs full duplex
-en_10hdx_cap 10Mpbs half duplex
+en_100fdx_cap 100Mbps full duplex
+en_100hdx_cap 100Mbps half duplex
+en_10fdx_cap 10Mbps full duplex
+en_10hdx_cap 10Mbps half duplex
.fi
.in -2
.sp
diff --git a/usr/src/tools/ctf/cvt/dwarf.c b/usr/src/tools/ctf/cvt/dwarf.c
index a7e97dfb23..ce8f6f9601 100644
--- a/usr/src/tools/ctf/cvt/dwarf.c
+++ b/usr/src/tools/ctf/cvt/dwarf.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* DWARF to tdata conversion
*
@@ -1832,8 +1830,11 @@ dw_read(tdata_t *td, Elf *elf, const char *filename)
}
if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff,
- &addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK ||
- (cu = die_sibling(&dw, NULL)) == NULL ||
+ &addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK)
+ terminate("file does not contain valid DWARF data: %s\n",
+ dwarf_errmsg(dw.dw_err));
+
+ if ((cu = die_sibling(&dw, NULL)) == NULL ||
(child = die_child(&dw, cu)) == NULL)
terminate("file does not contain dwarf type data "
"(try compiling with -g)\n");
diff --git a/usr/src/tools/scripts/hgsetup.sh b/usr/src/tools/scripts/hgsetup.sh
index 937b505806..282a748a00 100644
--- a/usr/src/tools/scripts/hgsetup.sh
+++ b/usr/src/tools/scripts/hgsetup.sh
@@ -160,7 +160,7 @@ from=$email
[paths]
onnv-gate=ssh://anon@hg.opensolaris.org//hg/onnv/onnv-gate
-illumos-gate=http://hg.illumos.org/illumos-gate
+illumos-gate=ssh://anonhg@hg.illumos.org/illumos-gate
[merge-tools]
filemerge.gui=True
diff --git a/usr/src/uts/common/inet/ipf/netinet/ip_compat.h b/usr/src/uts/common/inet/ipf/netinet/ip_compat.h
index 94d02abd04..caae45f012 100644
--- a/usr/src/uts/common/inet/ipf/netinet/ip_compat.h
+++ b/usr/src/uts/common/inet/ipf/netinet/ip_compat.h
@@ -1777,7 +1777,7 @@ typedef struct tcpiphdr tcpiphdr_t;
# define IP_HL(x) (x)->ip_hl
#endif
#ifndef IP_HL_A
-# define IP_HL_A(x,y) (x)->ip_hl = (y & 0xf)
+# define IP_HL_A(x,y) (x)->ip_hl = ((y) & 0xf)
#endif
#ifndef TCP_X2
# define TCP_X2(x) (x)->th_x2
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_buf.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_buf.c
index 7ab825865d..af6e7f03de 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_buf.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_buf.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of Driver buffer management
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_fm.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_fm.c
index 6a0b68f323..ae4cd24649 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_fm.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_fm.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of fma support in driver
@@ -53,7 +50,6 @@ oce_fm_init(struct oce_dev *dev)
oce_set_dma_fma_flags(dev->fm_caps);
oce_set_reg_fma_flags(dev->fm_caps);
- oce_set_tx_map_dma_fma_flags(dev->fm_caps);
(void) ddi_fm_init(dev->dip, &dev->fm_caps, &ibc);
if (DDI_FM_EREPORT_CAP(dev->fm_caps) ||
@@ -102,6 +98,7 @@ oce_fm_check_acc_handle(struct oce_dev *dev, ddi_acc_handle_t acc_handle)
{
ddi_fm_error_t fme;
+
if (!DDI_FM_ACC_ERR_CAP(dev->fm_caps)) {
return (DDI_FM_OK);
}
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_gld.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_gld.c
index 1ce4dd791f..19d210d4d1 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_gld.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_gld.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of the driver entry points
@@ -68,25 +65,6 @@ oce_m_start(void *arg)
mutex_exit(&dev->dev_lock);
return (EIO);
}
-
- if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
- ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
- mutex_exit(&dev->dev_lock);
- return (EIO);
- }
-
- if (oce_fm_check_acc_handle(dev, dev->csr_handle) != DDI_FM_OK) {
- ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
- mutex_exit(&dev->dev_lock);
- return (EIO);
- }
-
- if (oce_fm_check_acc_handle(dev, dev->cfg_handle) != DDI_FM_OK) {
- ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
- mutex_exit(&dev->dev_lock);
- return (EIO);
- }
-
ret = oce_start(dev);
if (ret != DDI_SUCCESS) {
mutex_exit(&dev->dev_lock);
@@ -180,7 +158,6 @@ oce_stop(struct oce_dev *dev)
int
oce_m_multicast(void *arg, boolean_t add, const uint8_t *mca)
{
-
struct oce_dev *dev = (struct oce_dev *)arg;
struct ether_addr *mca_drv_list;
struct ether_addr mca_hw_list[OCE_MAX_MCA];
@@ -233,7 +210,9 @@ oce_m_multicast(void *arg, boolean_t add, const uint8_t *mca)
ret = oce_set_multicast_table(dev, dev->if_id,
&mca_hw_list[0], new_mcnt, B_FALSE);
}
- if (ret != 0) {
+ if (ret != 0) {
+ oce_log(dev, CE_WARN, MOD_CONFIG,
+ "mcast %s fails", add ? "ADD" : "DEL");
DEV_UNLOCK(dev);
return (EIO);
}
@@ -248,6 +227,11 @@ finish:
dev->num_mca = (uint16_t)new_mcnt;
}
DEV_UNLOCK(dev);
+ oce_log(dev, CE_NOTE, MOD_CONFIG,
+ "mcast %s, addr=%02x:%02x:%02x:%02x:%02x:%02x, num_mca=%d",
+ add ? "ADD" : "DEL",
+ mca[0], mca[1], mca[2], mca[3], mca[4], mca[5],
+ dev->num_mca);
return (0);
} /* oce_m_multicast */
@@ -260,6 +244,7 @@ oce_m_unicast(void *arg, const uint8_t *uca)
DEV_LOCK(dev);
if (dev->suspended) {
bcopy(uca, dev->unicast_addr, ETHERADDRL);
+ dev->num_smac = 0;
DEV_UNLOCK(dev);
return (DDI_SUCCESS);
}
@@ -270,6 +255,7 @@ oce_m_unicast(void *arg, const uint8_t *uca)
DEV_UNLOCK(dev);
return (EIO);
}
+ dev->num_smac = 0;
bzero(dev->unicast_addr, ETHERADDRL);
/* Set the New MAC addr earlier is no longer valid */
@@ -279,6 +265,7 @@ oce_m_unicast(void *arg, const uint8_t *uca)
return (EIO);
}
bcopy(uca, dev->unicast_addr, ETHERADDRL);
+ dev->num_smac = 1;
DEV_UNLOCK(dev);
return (ret);
} /* oce_m_unicast */
@@ -603,11 +590,46 @@ oce_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
case OCE_ISSUE_MBOX: {
ret = oce_issue_mbox(dev, wq, mp, &payload_length);
- if (ret != 0) {
- miocnak(wq, mp, payload_length, ret);
+ miocack(wq, mp, payload_length, ret);
+ break;
+ }
+ case OCE_QUERY_DRIVER_DATA: {
+ struct oce_driver_query *drv_query =
+ (struct oce_driver_query *)(void *)mp->b_cont->b_rptr;
+
+ /* if the driver version does not match bail */
+ if (drv_query->version != OCN_VERSION_SUPPORTED) {
+ oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
+ "One Connect version mismatch");
+ miocnak(wq, mp, 0, ENOTSUP);
+ break;
+ }
+
+ /* fill the return values */
+ bcopy(OCE_MOD_NAME, drv_query->driver_name,
+ (sizeof (OCE_MOD_NAME) > 32) ?
+ 31 : sizeof (OCE_MOD_NAME));
+ drv_query->driver_name[31] = '\0';
+
+ bcopy(OCE_VERSION, drv_query->driver_version,
+ (sizeof (OCE_VERSION) > 32) ? 31 :
+ sizeof (OCE_VERSION));
+ drv_query->driver_version[31] = '\0';
+
+ if (dev->num_smac == 0) {
+ drv_query->num_smac = 1;
+ bcopy(dev->mac_addr, drv_query->smac_addr[0],
+ ETHERADDRL);
} else {
- miocack(wq, mp, payload_length, 0);
+ drv_query->num_smac = dev->num_smac;
+ bcopy(dev->unicast_addr, drv_query->smac_addr[0],
+ ETHERADDRL);
}
+
+ bcopy(dev->mac_addr, drv_query->pmac_addr, ETHERADDRL);
+
+ payload_length = sizeof (struct oce_driver_query);
+ miocack(wq, mp, payload_length, 0);
break;
}
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_hw.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_hw.c
index 65244c5fcd..8127a9ff29 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_hw.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_hw.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of the Hardware specific
@@ -150,15 +147,9 @@ oce_pci_init(struct oce_dev *dev)
{
int ret = 0;
- ret = pci_config_setup(dev->dip, &dev->pci_cfg_handle);
- if (ret != DDI_SUCCESS) {
- return (DDI_FAILURE);
- }
-
ret = oce_map_regs(dev);
if (ret != DDI_SUCCESS) {
- pci_config_teardown(&dev->pci_cfg_handle);
return (DDI_FAILURE);
}
dev->fn = OCE_PCI_FUNC(dev);
@@ -184,9 +175,75 @@ void
oce_pci_fini(struct oce_dev *dev)
{
oce_unmap_regs(dev);
- pci_config_teardown(&dev->pci_cfg_handle);
} /* oce_pci_fini */
+/*
+ * function to read the PCI Bus, Device, and function numbers for the
+ * device instance.
+ *
+ * dev - handle to device private data
+ */
+int
+oce_get_bdf(struct oce_dev *dev)
+{
+ pci_regspec_t *pci_rp;
+ uint32_t length;
+ int rc;
+
+ /* Get "reg" property */
+ rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dev->dip,
+ 0, "reg", (int **)&pci_rp, (uint_t *)&length);
+
+ if ((rc != DDI_SUCCESS) ||
+ (length < (sizeof (pci_regspec_t) / sizeof (int)))) {
+ oce_log(dev, CE_WARN, MOD_CONFIG,
+ "Failed to read \"reg\" property, Status = 0x%x", rc);
+ return (rc);
+ }
+
+ dev->pci_bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
+ dev->pci_device = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
+ dev->pci_function = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
+
+ oce_log(dev, CE_NOTE, MOD_CONFIG,
+ "\"reg\" property num=%d, Bus=%d, Device=%d, Function=%d",
+ length, dev->pci_bus, dev->pci_device, dev->pci_function);
+
+ /* Free the memory allocated by ddi_prop_lookup_int_array() */
+ ddi_prop_free(pci_rp);
+ return (rc);
+}
+
+int
+oce_identify_hw(struct oce_dev *dev)
+{
+ int ret = DDI_SUCCESS;
+
+ dev->vendor_id = pci_config_get16(dev->pci_cfg_handle,
+ PCI_CONF_VENID);
+ dev->device_id = pci_config_get16(dev->pci_cfg_handle,
+ PCI_CONF_DEVID);
+ dev->subsys_id = pci_config_get16(dev->pci_cfg_handle,
+ PCI_CONF_SUBSYSID);
+ dev->subvendor_id = pci_config_get16(dev->pci_cfg_handle,
+ PCI_CONF_SUBVENID);
+
+ switch (dev->device_id) {
+
+ case DEVID_TIGERSHARK:
+ dev->chip_rev = OC_CNA_GEN2;
+ break;
+ case DEVID_TOMCAT:
+ dev->chip_rev = OC_CNA_GEN3;
+ break;
+ default:
+ dev->chip_rev = 0;
+ ret = DDI_FAILURE;
+ break;
+ }
+ return (ret);
+}
+
/*
* function to check if a reset is required
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_intr.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_intr.c
index 2f22cf10e8..009aa46c58 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_intr.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_intr.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file interrupt registration
@@ -31,6 +28,7 @@
#include <oce_impl.h>
+
static uint_t oce_isr(caddr_t arg1, caddr_t arg2);
/*
@@ -223,14 +221,8 @@ oce_chip_ei(struct oce_dev *dev)
uint32_t reg;
reg = OCE_CFG_READ32(dev, PCICFG_INTR_CTRL);
- if (oce_fm_check_acc_handle(dev, dev->dev_cfg_handle) != DDI_FM_OK) {
- ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
- }
reg |= HOSTINTR_MASK;
OCE_CFG_WRITE32(dev, PCICFG_INTR_CTRL, reg);
- if (oce_fm_check_acc_handle(dev, dev->dev_cfg_handle) != DDI_FM_OK) {
- ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
- }
}
/*
@@ -268,14 +260,8 @@ oce_chip_di(struct oce_dev *dev)
uint32_t reg;
reg = OCE_CFG_READ32(dev, PCICFG_INTR_CTRL);
- if (oce_fm_check_acc_handle(dev, dev->dev_cfg_handle) != DDI_FM_OK) {
- ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
- }
reg &= ~HOSTINTR_MASK;
OCE_CFG_WRITE32(dev, PCICFG_INTR_CTRL, reg);
- if (oce_fm_check_acc_handle(dev, dev->dev_cfg_handle) != DDI_FM_OK) {
- ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
- }
}
/*
@@ -303,6 +289,7 @@ oce_di(struct oce_dev *dev)
}
}
}
+
} /* oce_di */
/*
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_main.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_main.c
index 6301ba9674..39b906f5b2 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_main.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_main.c
@@ -19,10 +19,8 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
+
/*
* Source file containing the implementation of the driver entry points
@@ -35,18 +33,20 @@
#define ATTACH_DEV_INIT 0x1
#define ATTACH_FM_INIT 0x2
-#define ATTACH_LOCK_INIT 0x4
-#define ATTACH_PCI_INIT 0x8
-#define ATTACH_HW_INIT 0x10
-#define ATTACH_SETUP_TXRX 0x20
-#define ATTACH_SETUP_ADAP 0x40
-#define ATTACH_SETUP_INTR 0x80
-#define ATTACH_STAT_INIT 0x100
-#define ATTACH_MAC_REG 0x200
+#define ATTACH_PCI_CFG 0x4
+#define ATTACH_LOCK_INIT 0x8
+#define ATTACH_PCI_INIT 0x10
+#define ATTACH_HW_INIT 0x20
+#define ATTACH_SETUP_TXRX 0x40
+#define ATTACH_SETUP_ADAP 0x80
+#define ATTACH_SETUP_INTR 0x100
+#define ATTACH_STAT_INIT 0x200
+#define ATTACH_MAC_REG 0x400
/* ---[ globals and externs ]-------------------------------------------- */
const char oce_ident_string[] = OCE_IDENT_STRING;
const char oce_mod_name[] = OCE_MOD_NAME;
+struct oce_dev *oce_dev_list[MAX_DEVS + 1]; /* Last entry is invalid */
/* driver properties */
static const char flow_control[] = "flow_control";
@@ -192,6 +192,7 @@ oce_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
int ret = 0;
struct oce_dev *dev = NULL;
mac_register_t *mac;
+ uint8_t dev_index = 0;
switch (cmd) {
case DDI_RESUME:
@@ -211,6 +212,21 @@ oce_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
dev->dev_id = ddi_get_instance(dip);
dev->suspended = B_FALSE;
+ dev->dev_list_index = MAX_DEVS;
+ while (dev_index < MAX_DEVS) {
+ (void) atomic_cas_ptr(&oce_dev_list[dev_index], NULL, dev);
+ if (oce_dev_list[dev_index] == dev) {
+ break;
+ }
+ dev_index++;
+ }
+ if (dev_index == MAX_DEVS) {
+ oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
+ "Too many oce devices on the system. Failed to attach.");
+ goto attach_fail;
+ }
+ dev->dev_list_index = dev_index;
+
/* get the parameters */
oce_get_params(dev);
@@ -225,6 +241,31 @@ oce_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
oce_fm_init(dev);
dev->attach_state |= ATTACH_FM_INIT;
+ ret = pci_config_setup(dev->dip, &dev->pci_cfg_handle);
+ if (ret != DDI_SUCCESS) {
+ oce_log(dev, CE_WARN, MOD_CONFIG,
+ "Map PCI config failed with %d", ret);
+ goto attach_fail;
+ }
+ dev->attach_state |= ATTACH_PCI_CFG;
+
+ ret = oce_identify_hw(dev);
+
+ if (ret != DDI_SUCCESS) {
+ oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
+ "Device Unknown");
+ goto attach_fail;
+ }
+
+ ret = oce_get_bdf(dev);
+ if (ret != DDI_SUCCESS) {
+ oce_log(dev, CE_WARN, MOD_CONFIG,
+ "Failed to read BDF, status = 0x%x", ret);
+ goto attach_fail;
+ }
+ /* Update the dev->rss */
+ oce_dev_rss_ready(dev);
+
/* setup PCI bars */
ret = oce_pci_init(dev);
if (ret != DDI_SUCCESS) {
@@ -301,7 +342,7 @@ oce_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
mac->m_callbacks = &oce_mac_cb;
mac->m_min_sdu = 0;
mac->m_max_sdu = dev->mtu;
- mac->m_margin = VLAN_TAGSZ;
+ mac->m_margin = VTAG_SIZE;
mac->m_priv_props = oce_priv_props;
oce_log(dev, CE_NOTE, MOD_CONFIG,
@@ -491,29 +532,30 @@ oce_unconfigure(struct oce_dev *dev)
if (state & ATTACH_SETUP_ADAP) {
oce_unsetup_adapter(dev);
}
-
if (state & ATTACH_SETUP_TXRX) {
oce_fini_txrx(dev);
}
-
if (state & ATTACH_HW_INIT) {
oce_hw_fini(dev);
}
if (state & ATTACH_LOCK_INIT) {
oce_destroy_locks(dev);
}
-
if (state & ATTACH_SETUP_INTR) {
(void) oce_teardown_intr(dev);
}
if (state & ATTACH_PCI_INIT) {
oce_pci_fini(dev);
}
+ if (state & ATTACH_PCI_CFG) {
+ pci_config_teardown(&dev->pci_cfg_handle);
+ }
if (state & ATTACH_FM_INIT) {
oce_fm_fini(dev);
}
if (state & ATTACH_DEV_INIT) {
ddi_set_driver_private(dev->dip, NULL);
+ oce_dev_list[dev->dev_list_index] = NULL;
kmem_free(dev, sizeof (struct oce_dev));
}
} /* oce_unconfigure */
@@ -587,7 +629,7 @@ oce_get_params(struct oce_dev *dev)
0, dev->rx_ring_size/2, OCE_DEFAULT_RX_PKT_PER_INTR, rx_ppi_values);
dev->rx_rings = oce_get_prop(dev, (char *)rx_rings_name,
- OCE_DEFAULT_RQS, OCE_MAX_RQS, OCE_DEFAULT_RQS, rx_rings_values);
+ OCE_MIN_RQ, OCE_MAX_RQ, OCE_DEFAULT_RQS, rx_rings_values);
dev->tx_rings = oce_get_prop(dev, (char *)tx_rings_name,
OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, tx_rings_values);
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mbx.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mbx.c
index adaffb1e9b..96f7b19e02 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mbx.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mbx.c
@@ -19,10 +19,8 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
+
/*
* Source file containing the implementation of MBOX
@@ -138,6 +136,9 @@ oce_mbox_wait(struct oce_dev *dev, uint32_t tmo_sec)
tmo = (tmo_sec > 0) ? drv_usectohz(tmo_sec * 1000000) :
drv_usectohz(DEFAULT_MQ_MBOX_TIMEOUT);
+ /* Add the default timeout to wait for a mailbox to complete */
+ tmo += drv_usectohz(MBX_READY_TIMEOUT);
+
tstamp = ddi_get_lbolt();
for (;;) {
now = ddi_get_lbolt();
@@ -289,19 +290,19 @@ oce_mbox_post(struct oce_dev *dev, struct oce_mbx *mbx,
mb_cqe = &mb->cqe;
DW_SWAP(u32ptr(&mb_cqe->u0.dw[0]), sizeof (struct oce_mq_cqe));
+ /* copy mbox mbx back */
+ bcopy(mb_mbx, mbx, sizeof (struct oce_mbx));
+
/* check mbox status */
if (mb_cqe->u0.s.completion_status != 0) {
oce_log(dev, CE_WARN, MOD_CONFIG,
- "MBOX Failed with Status: %d %d",
+ "MBOX Command Failed with Status: %d %d",
mb_cqe->u0.s.completion_status,
mb_cqe->u0.s.extended_status);
mutex_exit(&dev->bmbx_lock);
return (EIO);
}
- /* copy mbox mbx back */
- bcopy(mb_mbx, mbx, sizeof (struct oce_mbx));
-
/*
* store the mbx context in the cqe tag section so that
* the upper layer handling the cqe can associate the mbx
@@ -800,6 +801,8 @@ oce_get_hw_stats(struct oce_dev *dev)
DW_SWAP(u32ptr(&mbx), sizeof (struct oce_mq_sge) + OCE_BMBX_RHDR_SZ);
+ bzero(&dev->hw_stats->params, sizeof (dev->hw_stats->params));
+
/* sync for device */
(void) DBUF_SYNC(dev->stats_dbuf, DDI_DMA_SYNC_FORDEV);
@@ -1257,7 +1260,7 @@ oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
is_embedded = (payload_length <= sizeof (struct oce_mbx_payload));
- alloc_len = MBLKL(mp->b_cont);
+ alloc_len = msgdsize(mp->b_cont);
oce_log(dev, CE_NOTE, MOD_CONFIG, "Mailbox: "
"DW[0] 0x%x DW[1] 0x%x DW[2]0x%x DW[3]0x%x,"
@@ -1266,6 +1269,9 @@ oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
hdr.u0.dw[2], hdr.u0.dw[3],
MBLKL(mp->b_cont), alloc_len);
+ /* get the timeout from the command header */
+ mbx.tag[0] = hdr.u0.req.timeout;
+
if (hdr.u0.req.opcode == OPCODE_WRITE_COMMON_FLASHROM) {
struct mbx_common_read_write_flashrom *fwcmd =
(struct mbx_common_read_write_flashrom *)
@@ -1278,9 +1284,6 @@ oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
dev->cookie = hdr.u0.req.rsvd0;
hdr.u0.req.rsvd0 = 0;
- /* get the timeout from the command header */
- mbx.tag[0] = hdr.u0.req.timeout;
-
oce_log(dev, CE_NOTE, MOD_CONFIG, "Mailbox params:"
"OPCODE(%d) OPTYPE = %d SIZE = %d OFFSET = %d",
fwcmd->flash_op_code, fwcmd->flash_op_type,
@@ -1288,9 +1291,10 @@ oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
}
if (!is_embedded) {
- mblk_t *mp_w = mp->b_cont;
+ mblk_t *tmp = NULL;
ddi_dma_cookie_t cookie;
uint32_t count = 0;
+ int offset = 0;
/* allocate dma handle */
ret = ddi_dma_alloc_handle(dev->dip,
@@ -1316,13 +1320,16 @@ oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
goto dma_alloc_fail;
}
- bcopy((caddr_t)mp_w->b_rptr, sg_va, MBLKL(mp->b_cont));
+ for (tmp = mp->b_cont; tmp != NULL; tmp = tmp->b_cont) {
+ bcopy((caddr_t)tmp->b_rptr, sg_va + offset, MBLKL(tmp));
+ offset += MBLKL(tmp);
+ }
/* bind mblk mem to handle */
ret = ddi_dma_addr_bind_handle(
dma_handle,
(struct as *)0, sg_va,
- MBLKL(mp_w),
+ alloc_len,
DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
DDI_DMA_DONTWAIT, NULL, &cookie, &count);
if (ret != DDI_DMA_MAPPED) {
@@ -1408,6 +1415,8 @@ oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
bcopy(&mbx.payload, mp->b_cont->b_rptr,
min(payload_length, MBLKL(mp->b_cont)));
} else {
+ mblk_t *tmp = NULL;
+ int offset = 0;
/* sync */
(void) ddi_dma_sync(dma_handle, 0, 0,
DDI_DMA_SYNC_FORKERNEL);
@@ -1416,7 +1425,10 @@ oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
}
/* copy back from kernel allocated buffer to user buffer */
- bcopy(sg_va, mp->b_cont->b_rptr, MBLKL(mp->b_cont));
+ for (tmp = mp->b_cont; tmp != NULL; tmp = tmp->b_cont) {
+ bcopy(sg_va + offset, tmp->b_rptr, MBLKL(tmp));
+ offset += MBLKL(tmp);
+ }
/* unbind and free dma handles */
(void) ddi_dma_unbind_handle(dma_handle);
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mq.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mq.c
index 9823a3b213..6c8d13a06c 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mq.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mq.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of the MailBox queue handling
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_queue.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_queue.c
index a0c58153dc..91011f7505 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_queue.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_queue.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing Queue handling functions
@@ -30,6 +27,7 @@
*/
#include <oce_impl.h>
+extern struct oce_dev *oce_dev_list[];
int oce_destroy_q(struct oce_dev *oce, struct oce_mbx *mbx, size_t req_size,
enum qtype qtype);
@@ -96,8 +94,7 @@ oce_eq_create(struct oce_dev *dev, uint32_t q_len, uint32_t item_size,
if (eq->ring == NULL) {
oce_log(dev, CE_WARN, MOD_CONFIG,
- "EQ ring alloc failed:0x%p",
- (void *)eq->ring);
+ "EQ ring alloc failed:0x%p", (void *)eq->ring);
kmem_free(eq, sizeof (struct oce_eq));
return (NULL);
}
@@ -135,8 +132,7 @@ oce_eq_create(struct oce_dev *dev, uint32_t q_len, uint32_t item_size,
ret = oce_mbox_post(dev, &mbx, NULL);
if (ret != 0) {
- oce_log(dev, CE_WARN, MOD_CONFIG,
- "EQ create failed: %d", ret);
+ oce_log(dev, CE_WARN, MOD_CONFIG, "EQ create failed: %d", ret);
destroy_ring_buffer(dev, eq->ring);
kmem_free(eq, sizeof (struct oce_eq));
return (NULL);
@@ -635,7 +631,6 @@ oce_wq_create(struct oce_wq *wq, struct oce_eq *eq)
"WQ create failed: %d", ret);
oce_cq_del(dev, cq);
return (ret);
-
}
/* interpret the response */
@@ -650,6 +645,9 @@ oce_wq_create(struct oce_wq *wq, struct oce_eq *eq)
/* reset indicies */
wq->ring->cidx = 0;
wq->ring->pidx = 0;
+ oce_log(dev, CE_NOTE, MOD_CONFIG, "WQ CREATED WQID = %d",
+ wq->wq_id);
+
return (0);
}
@@ -776,14 +774,15 @@ oce_rq_init(struct oce_dev *dev, uint32_t q_len,
rq_ringfail:
oce_rqb_cache_destroy(rq);
rqb_fail:
- kmem_free(rq->shadow_ring,
- (rq->cfg.q_len * sizeof (oce_rq_bdesc_t *)));
-rqb_free_list_fail:
kmem_free(rq->rqb_freelist,
(rq->cfg.nbufs * sizeof (oce_rq_bdesc_t *)));
+rqb_free_list_fail:
+
+ kmem_free(rq->shadow_ring,
+ (rq->cfg.q_len * sizeof (oce_rq_bdesc_t *)));
rq_shdw_fail:
kmem_free(rq->rq_bdesc_array,
- (sizeof (oce_rq_bdesc_t) * rq->cfg.q_len));
+ (sizeof (oce_rq_bdesc_t) * rq->cfg.nbufs));
rqbd_alloc_fail:
kmem_free(rq, sizeof (struct oce_rq));
return (NULL);
@@ -882,6 +881,7 @@ oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq)
rq->ring->cidx = 0;
rq->ring->pidx = 0;
rq->buf_avail = 0;
+ oce_log(dev, CE_NOTE, MOD_CONFIG, "RQ created, RQID : %d", rq->rq_id);
return (0);
}
@@ -1250,3 +1250,40 @@ oce_delete_queues(struct oce_dev *dev)
dev->eq[i] = NULL;
}
}
+
+void
+oce_dev_rss_ready(struct oce_dev *dev)
+{
+ uint8_t dev_index = 0;
+ uint8_t adapter_rss = 0;
+
+ /* Return if rx_rings <= 1 (No RSS) */
+ if (dev->rx_rings <= 1) {
+ oce_log(dev, CE_NOTE, MOD_CONFIG,
+ "Rx rings = %d, Not enabling RSS", dev->rx_rings);
+ return;
+ }
+
+ /*
+ * Count the number of PCI functions enabling RSS on this
+ * adapter
+ */
+ while (dev_index < MAX_DEVS) {
+ if ((oce_dev_list[dev_index] != NULL) &&
+ (dev->pci_bus == oce_dev_list[dev_index]->pci_bus) &&
+ (dev->pci_device == oce_dev_list[dev_index]->pci_device) &&
+ (oce_dev_list[dev_index]->rss_enable)) {
+ adapter_rss++;
+ }
+ dev_index++;
+ }
+
+ /*
+ * If there are already MAX_RSS_PER_ADAPTER PCI functions using
+ * RSS on this adapter, reduce the number of rx rings to 1
+ * (No RSS)
+ */
+ if (adapter_rss >= MAX_RSS_PER_ADAPTER) {
+ dev->rx_rings = 1;
+ }
+}
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_rx.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_rx.c
index fa21f6dbcc..2efb178ff1 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_rx.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_rx.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the Receive Path handling
@@ -463,9 +460,9 @@ oce_rx_insert_tag(mblk_t *mp, uint16_t vtag)
{
struct ether_vlan_header *ehp;
- (void) memmove(mp->b_rptr - VLAN_TAGSZ,
+ (void) memmove(mp->b_rptr - VTAG_SIZE,
mp->b_rptr, 2 * ETHERADDRL);
- mp->b_rptr -= VLAN_TAGSZ;
+ mp->b_rptr -= VTAG_SIZE;
ehp = (struct ether_vlan_header *)voidptr(mp->b_rptr);
ehp->ether_tpid = htons(ETHERTYPE_VLAN);
ehp->ether_tci = LE_16(vtag);
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_stat.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_stat.c
index 76e4bfc971..4090d584f2 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_stat.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_stat.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of the driver statistics
@@ -152,6 +149,37 @@ oce_update_stats(kstat_t *ksp, int rw)
port_stats->tx_pause_frames;
stats->tx_control_frames.value.ul =
port_stats->tx_control_frames;
+
+
+ stats->rx_drops_no_pbuf.value.ul =
+ dev->hw_stats->params.rsp.rx.rx_drops_no_pbuf;
+ stats->rx_drops_no_txpb.value.ul =
+ dev->hw_stats->params.rsp.rx.rx_drops_no_txpb;
+ stats->rx_drops_no_erx_descr.value.ul =
+ dev->hw_stats->params.rsp.rx.rx_drops_no_erx_descr;
+ stats->rx_drops_no_tpre_descr.value.ul =
+ dev->hw_stats->params.rsp.rx.rx_drops_no_tpre_descr;
+ stats->rx_drops_too_many_frags.value.ul =
+ dev->hw_stats->params.rsp.rx.rx_drops_too_many_frags;
+ stats->rx_drops_invalid_ring.value.ul =
+ dev->hw_stats->params.rsp.rx.rx_drops_invalid_ring;
+ stats->rx_drops_mtu.value.ul =
+ dev->hw_stats->params.rsp.rx.rx_drops_mtu;
+
+ stats->rx_dropped_too_small.value.ul =
+ port_stats->rx_dropped_too_small;
+ stats->rx_dropped_too_short.value.ul =
+ port_stats->rx_dropped_too_short;
+ stats->rx_dropped_header_too_small.value.ul =
+ port_stats->rx_dropped_header_too_small;
+ stats->rx_dropped_tcp_length.value.ul =
+ port_stats->rx_dropped_tcp_length;
+ stats->rx_dropped_runt.value.ul =
+ port_stats->rx_dropped_runt;
+
+ stats->rx_drops_no_fragments.value.ul =
+ dev->hw_stats->params.rsp.err_rx.rx_drops_no_fragments[0];
+
mutex_exit(&dev->dev_lock);
return (DDI_SUCCESS);
} /* oce_update_stats */
@@ -255,6 +283,37 @@ oce_stat_init(struct oce_dev *dev)
kstat_named_init(&stats->tx_control_frames,
"tx control frames", KSTAT_DATA_ULONG);
+
+ kstat_named_init(&stats->rx_drops_no_pbuf,
+ "rx_drops_no_pbuf", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_drops_no_txpb,
+ "rx_drops_no_txpb", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_drops_no_erx_descr,
+ "rx_drops_no_erx_descr", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_drops_no_tpre_descr,
+ "rx_drops_no_tpre_descr", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_drops_too_many_frags,
+ "rx_drops_too_many_frags", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_drops_invalid_ring,
+ "rx_drops_invalid_ring", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_drops_mtu,
+ "rx_drops_mtu", KSTAT_DATA_ULONG);
+
+ kstat_named_init(&stats->rx_dropped_too_small,
+ "rx_dropped_too_small", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_dropped_too_short,
+ "rx_dropped_too_short", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_dropped_header_too_small,
+ "rx_dropped_header_too_small", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_dropped_tcp_length,
+ "rx_dropped_tcp_length", KSTAT_DATA_ULONG);
+ kstat_named_init(&stats->rx_dropped_runt,
+ "rx_dropped_runt", KSTAT_DATA_ULONG);
+
+ kstat_named_init(&stats->rx_drops_no_fragments,
+ "rx_drop_no_frag", KSTAT_DATA_ULONG);
+
+
dev->oce_kstats->ks_update = oce_update_stats;
dev->oce_kstats->ks_private = (void *)dev;
kstat_install(dev->oce_kstats);
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_tx.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_tx.c
index fd1abad73f..b74f32c6f0 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_tx.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_tx.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of the Transmit
@@ -643,9 +640,9 @@ static inline void
oce_insert_vtag(mblk_t *mp, uint16_t vlan_tag)
{
struct ether_vlan_header *evh;
- (void) memmove(mp->b_rptr - VLAN_TAGSZ,
+ (void) memmove(mp->b_rptr - VTAG_SIZE,
mp->b_rptr, 2 * ETHERADDRL);
- mp->b_rptr -= VLAN_TAGSZ;
+ mp->b_rptr -= VTAG_SIZE;
evh = (struct ether_vlan_header *)(void *)mp->b_rptr;
evh->ether_tpid = htons(VLAN_TPID);
evh->ether_tci = htons(vlan_tag);
@@ -662,9 +659,9 @@ oce_insert_vtag(mblk_t *mp, uint16_t vlan_tag)
static inline void
oce_remove_vtag(mblk_t *mp)
{
- (void) memmove(mp->b_rptr + VLAN_TAGSZ, mp->b_rptr,
+ (void) memmove(mp->b_rptr + VTAG_SIZE, mp->b_rptr,
ETHERADDRL * 2);
- mp->b_rptr += VLAN_TAGSZ;
+ mp->b_rptr += VTAG_SIZE;
}
/*
@@ -678,7 +675,6 @@ oce_remove_vtag(mblk_t *mp)
mblk_t *
oce_send_packet(struct oce_wq *wq, mblk_t *mp)
{
-
struct oce_nic_hdr_wqe *wqeh;
struct oce_dev *dev;
struct ether_header *eh;
@@ -755,7 +751,7 @@ oce_send_packet(struct oce_wq *wq, mblk_t *mp)
tagged = B_TRUE;
etype = ntohs(evh->ether_type);
ip_offset = sizeof (struct ether_vlan_header);
- pkt_len -= VLAN_TAGSZ;
+ pkt_len -= VTAG_SIZE;
vlan_tag = ntohs(evh->ether_tci);
oce_remove_vtag(mp);
} else {
@@ -859,6 +855,10 @@ oce_send_packet(struct oce_wq *wq, mblk_t *mp)
/* fill the wq for adapter */
oce_fill_ring_descs(wq, wqed);
+ /* Set the mp pointer in the wqe descriptor */
+ if (use_copy == B_FALSE) {
+ wqed->mp = mp;
+ }
/* Add the packet desc to list to be retrieved during cmpl */
OCE_LIST_INSERT_TAIL(&wq->wqe_desc_list, wqed);
(void) ddi_dma_sync(wq->ring->dbuf->dma_handle, 0, 0,
@@ -876,8 +876,7 @@ oce_send_packet(struct oce_wq *wq, mblk_t *mp)
/* free mp if copied or packet chain collapsed */
if (use_copy == B_TRUE) {
freemsg(mp);
- } else
- wqed->mp = mp;
+ }
return (NULL);
wqe_fail:
diff --git a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_utils.c b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_utils.c
index e29e4554bf..ed329b01b7 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/oce/oce_utils.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/oce/oce_utils.c
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Source file containing the implementation of the driver
diff --git a/usr/src/uts/common/io/power.c b/usr/src/uts/common/io/power.c
index 26263a3591..61e675ba77 100644
--- a/usr/src/uts/common/io/power.c
+++ b/usr/src/uts/common/io/power.c
@@ -22,6 +22,7 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2011 Joyent, Inc. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -946,58 +947,6 @@ power_log_message(void)
#ifdef ACPI_POWER_BUTTON
/*
- * Given a handle to a device object, locate a _PRW object
- * if present and fetch the GPE info for this device object
- */
-static ACPI_STATUS
-power_get_prw_gpe(ACPI_HANDLE dev, ACPI_HANDLE *gpe_dev, UINT32 *gpe_num)
-{
- ACPI_BUFFER buf;
- ACPI_STATUS status;
- ACPI_HANDLE prw;
- ACPI_OBJECT *gpe;
-
- /*
- * Evaluate _PRW if present
- */
- status = AcpiGetHandle(dev, "_PRW", &prw);
- if (status != AE_OK)
- return (status);
- buf.Length = ACPI_ALLOCATE_BUFFER;
- status = AcpiEvaluateObjectTyped(prw, NULL, NULL, &buf,
- ACPI_TYPE_PACKAGE);
- if (status != AE_OK)
- return (status);
-
- /*
- * Sanity-check the package; need at least two elements
- */
- status = AE_ERROR;
- if (((ACPI_OBJECT *)buf.Pointer)->Package.Count < 2)
- goto done;
-
- gpe = &((ACPI_OBJECT *)buf.Pointer)->Package.Elements[0];
- if (gpe->Type == ACPI_TYPE_INTEGER) {
- *gpe_dev = NULL;
- *gpe_num = gpe->Integer.Value;
- status = AE_OK;
- } else if (gpe->Type == ACPI_TYPE_PACKAGE) {
- if ((gpe->Package.Count != 2) ||
- (gpe->Package.Elements[0].Type != ACPI_TYPE_DEVICE) ||
- (gpe->Package.Elements[1].Type != ACPI_TYPE_INTEGER))
- goto done;
- *gpe_dev = gpe->Package.Elements[0].Reference.Handle;
- *gpe_num = gpe->Package.Elements[1].Integer.Value;
- status = AE_OK;
- }
-
-done:
- AcpiOsFree(buf.Pointer);
- return (status);
-}
-
-
-/*
*
*/
/*ARGSUSED*/
@@ -1052,15 +1001,10 @@ static int
power_probe_method_button(struct power_soft_state *softsp)
{
ACPI_HANDLE button_obj;
- UINT32 gpe_num;
- ACPI_HANDLE gpe_dev;
button_obj = probe_acpi_pwrbutton();
softsp->button_obj = button_obj; /* remember obj */
if ((button_obj != NULL) &&
- (power_get_prw_gpe(button_obj, &gpe_dev, &gpe_num) == AE_OK) &&
- (AcpiSetupGpeForWake(button_obj, gpe_dev, gpe_num) == AE_OK) &&
- (AcpiEnableGpe(gpe_dev, gpe_num) == AE_OK) &&
(AcpiInstallNotifyHandler(button_obj, ACPI_DEVICE_NOTIFY,
power_acpi_notify_event, (void*)softsp) == AE_OK))
return (1);
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_buf.h b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_buf.h
index cc31af3878..dd435cca82 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_buf.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_buf.h
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Header file defining the driver buffer management interface
@@ -143,7 +140,7 @@ typedef struct _oce_rq_buf_hdr_s {
} oce_rq_buf_hdr_t;
#pragma pack()
-#define OCE_RQE_BUF_HEADROOM sizeof (oce_rq_buf_hdr_t)
+#define OCE_RQE_BUF_HEADROOM 18
#define MAX_POOL_NAME 32
#define RING_NUM_PENDING(ring) ring->num_used
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw.h b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw.h
index 860dde5092..2770847f2b 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw.h
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Header file containing the command structures for Hardware
@@ -39,24 +36,29 @@ extern "C" {
#pragma pack(1)
+#define OC_CNA_GEN2 0x2
+#define OC_CNA_GEN3 0x3
+#define DEVID_TIGERSHARK 0x700
+#define DEVID_TOMCAT 0x710
+
/* PCI CSR offsets */
-#define PCICFG_F1_CSR 0x0 /* F1 for NIC */
-#define PCICFG_SEMAPHORE 0xbc
-#define PCICFG_SOFT_RESET 0x5c
+#define PCICFG_F1_CSR 0x0 /* F1 for NIC */
+#define PCICFG_SEMAPHORE 0xbc
+#define PCICFG_SOFT_RESET 0x5c
#define PCICFG_UE_STATUS_HI_MASK 0xac
#define PCICFG_UE_STATUS_LO_MASK 0xa8
-#define PCICFG_ONLINE0 0xb0
-#define PCICFG_ONLINE1 0xb4
+#define PCICFG_ONLINE0 0xb0
+#define PCICFG_ONLINE1 0xb4
#define INTR_EN 0x20000000
-#define IMAGE_TRANSFER_SIZE (32 * 1024) /* 32K at a time */
+#define IMAGE_TRANSFER_SIZE (32 * 1024) /* 32K at a time */
/* CSR register offsets */
-#define MPU_EP_CONTROL 0
-#define MPU_EP_SEMAPHORE 0xac
-#define PCICFG_INTR_CTRL 0xfc
-#define HOSTINTR_MASK (1 << 29)
-#define HOSTINTR_PFUNC_SHIFT 26
-#define HOSTINTR_PFUNC_MASK 7
+#define MPU_EP_CONTROL 0
+#define MPU_EP_SEMAPHORE 0xac
+#define PCICFG_INTR_CTRL 0xfc
+#define HOSTINTR_MASK (1 << 29)
+#define HOSTINTR_PFUNC_SHIFT 26
+#define HOSTINTR_PFUNC_MASK 7
/* POST status reg struct */
#define POST_STAGE_POWER_ON_RESET 0x00
@@ -67,26 +69,26 @@ extern "C" {
#define POST_STAGE_ARMFW_UE 0xf000
/* DOORBELL registers */
-#define PD_RXULP_DB 0x0100
-#define PD_TXULP_DB 0x0060
-#define DB_RQ_ID_MASK 0x3FF
+#define PD_RXULP_DB 0x0100
+#define PD_TXULP_DB 0x0060
+#define DB_RQ_ID_MASK 0x3FF
-#define PD_CQ_DB 0x0120
-#define PD_EQ_DB PD_CQ_DB
-#define PD_MPU_MBOX_DB 0x0160
-#define PD_MQ_DB 0x0140
+#define PD_CQ_DB 0x0120
+#define PD_EQ_DB PD_CQ_DB
+#define PD_MPU_MBOX_DB 0x0160
+#define PD_MQ_DB 0x0140
/* EQE completion types */
#define EQ_MINOR_CODE_COMPLETION 0x00
-#define EQ_MINOR_CODE_OTHER 0x01
+#define EQ_MINOR_CODE_OTHER 0x01
#define EQ_MAJOR_CODE_COMPLETION 0x00
/* Link Status field values */
-#define PHY_LINK_FAULT_NONE 0x0
+#define PHY_LINK_FAULT_NONE 0x0
#define PHY_LINK_FAULT_LOCAL 0x01
#define PHY_LINK_FAULT_REMOTE 0x02
-#define PHY_LINK_SPEED_ZERO 0x0 /* No link */
+#define PHY_LINK_SPEED_ZERO 0x0 /* No link */
#define PHY_LINK_SPEED_10MBPS 0x1 /* (10 Mbps) */
#define PHY_LINK_SPEED_100MBPS 0x2 /* (100 Mbps) */
#define PHY_LINK_SPEED_1GBPS 0x3 /* (1 Gbps) */
@@ -113,16 +115,16 @@ extern "C" {
#define MAC_ADDRESS_TYPE_FCOE 0x4 /* (FCoE MAC Address) */
/* CREATE_IFACE capability and cap_en flags */
-#define MBX_RX_IFACE_FLAGS_RSS 0x4
-#define MBX_RX_IFACE_FLAGS_PROMISCUOUS 0x8
-#define MBX_RX_IFACE_FLAGS_BROADCAST 0x10
-#define MBX_RX_IFACE_FLAGS_UNTAGGED 0x20
-#define MBX_RX_IFACE_FLAGS_ULP 0x40
-#define MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS 0x80
-#define MBX_RX_IFACE_FLAGS_VLAN 0x100
+#define MBX_RX_IFACE_FLAGS_RSS 0x4
+#define MBX_RX_IFACE_FLAGS_PROMISCUOUS 0x8
+#define MBX_RX_IFACE_FLAGS_BROADCAST 0x10
+#define MBX_RX_IFACE_FLAGS_UNTAGGED 0x20
+#define MBX_RX_IFACE_FLAGS_ULP 0x40
+#define MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS 0x80
+#define MBX_RX_IFACE_FLAGS_VLAN 0x100
#define MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS 0x200
-#define MBX_RX_IFACE_FLAGS_PASS_L2 0x400
-#define MBX_RX_IFACE_FLAGS_PASS_L3L4 0x800
+#define MBX_RX_IFACE_FLAGS_PASS_L2 0x400
+#define MBX_RX_IFACE_FLAGS_PASS_L3L4 0x800
#define MQ_RING_CONTEXT_SIZE_16 0x5 /* (16 entries) */
#define MQ_RING_CONTEXT_SIZE_32 0x6 /* (32 entries) */
@@ -130,10 +132,10 @@ extern "C" {
#define MQ_RING_CONTEXT_SIZE_128 0x8 /* (128 entries) */
-#define MBX_DB_READY_BIT 0x1
-#define MBX_DB_HI_BIT 0x2
+#define MBX_DB_READY_BIT 0x1
+#define MBX_DB_HI_BIT 0x2
#define ASYNC_EVENT_CODE_LINK_STATE 0x1
-#define ASYNC_EVENT_LINK_UP 0x1
+#define ASYNC_EVENT_LINK_UP 0x1
#define ASYNC_EVENT_LINK_DOWN 0x0
/* port link_status */
@@ -150,7 +152,7 @@ extern "C" {
#define NTWK_RX_FILTER_STRIP_CRC 0x8
/* max SGE per mbx */
-#define MAX_MBX_SGE 19
+#define MAX_MBX_SGE 19
/* physical address structure to be used in MBX */
struct phys_addr {
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw_eth.h b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw_eth.h
index 6b802293e5..54010f2d36 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw_eth.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_hw_eth.h
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* header file containing the data structure definitions for the NIC
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_impl.h b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_impl.h
index 1b3e8a8b96..296e46d357 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_impl.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_impl.h
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Driver specific data structures and function prototypes
@@ -43,7 +40,7 @@ extern "C" {
#include <sys/byteorder.h>
#include <sys/mac_provider.h>
#include <sys/mac_ether.h>
-#include <sys/vlan.h>
+#include <sys/gld.h>
#include <sys/bitmap.h>
#include <sys/ddidmareq.h>
#include <sys/kmem.h>
@@ -82,6 +79,9 @@ extern "C" {
#define END 0xdeadface
+#define MAX_DEVS 32
+#define MAX_RSS_PER_ADAPTER 2
+
#define OCE_MAX_ETH_FRAME_SIZE 1500
#define OCE_MAX_JUMBO_FRAME_SIZE 9018
#define OCE_MIN_ETH_FRAME_SIZE 64
@@ -96,6 +96,7 @@ extern "C" {
#define OCE_MAX_CQ 1024
#define OCE_MAX_WQ 8
#define OCE_MAX_RQ 5
+#define OCE_MIN_RQ 1
#define OCE_WQ_NUM_BUFFERS 2048
#define OCE_WQ_BUF_SIZE 2048
@@ -107,8 +108,11 @@ extern "C" {
#define OCE_DEFAULT_TX_RING_SIZE 2048
#define OCE_DEFAULT_RX_RING_SIZE 1024
#define OCE_DEFAULT_WQS 1
-#define OCE_DEFAULT_RQS 1
-#define OCE_MAX_RQS 5
+#if defined(__sparc)
+#define OCE_DEFAULT_RQS OCE_MAX_RQ
+#else
+#define OCE_DEFAULT_RQS OCE_MIN_RQ
+#endif
#define OCE_DEFAULT_RX_PKT_PER_INTR (OCE_DEFAULT_RX_RING_SIZE / 2)
#define OCE_DEFAULT_TX_RECLAIM_THRESHOLD 1024
@@ -133,10 +137,9 @@ extern "C" {
MBX_RX_IFACE_FLAGS_UNTAGGED | \
MBX_RX_IFACE_FLAGS_PASS_L3L4)
-#define OCE_FM_CAPABILITY (DDI_FM_EREPORT_CAPABLE | \
- DDI_FM_ACCCHK_CAPABLE | \
- DDI_FM_DMACHK_CAPABLE)
-
+#define OCE_FM_CAPABILITY (DDI_FM_EREPORT_CAPABLE | \
+ DDI_FM_ACCCHK_CAPABLE | \
+ DDI_FM_DMACHK_CAPABLE)
#define OCE_DEFAULT_RSS_TYPE (RSS_ENABLE_IPV4|RSS_ENABLE_TCP_IPV4)
@@ -273,6 +276,7 @@ struct oce_dev {
uint32_t rx_rings;
uint32_t pmac_id; /* used to add or remove mac */
uint8_t unicast_addr[ETHERADDRL];
+ uint32_t num_smac;
uint32_t mtu;
int32_t fm_caps;
boolean_t rss_enable; /* RSS support */
@@ -291,12 +295,23 @@ struct oce_dev {
uint32_t port_id;
uint32_t function_mode;
uint32_t function_caps;
+ uint32_t chip_rev; /* Chip revision */
uint32_t max_tx_rings; /* Max Rx rings available */
uint32_t max_rx_rings; /* Max rx rings available */
int32_t if_id; /* IF ID */
uint8_t fn; /* function number */
uint8_t fw_version[32]; /* fw version string */
+ /* PCI related */
+ uint16_t vendor_id;
+ uint16_t device_id;
+ uint16_t subsys_id;
+ uint16_t subvendor_id;
+ uint8_t pci_bus;
+ uint8_t pci_device;
+ uint8_t pci_function;
+ uint8_t dev_list_index;
+
/* Logging related */
uint16_t mod_mask; /* Log Mask */
int16_t severity; /* Log level */
@@ -323,6 +338,8 @@ int oce_m_stat(void *arg, uint_t stat, uint64_t *val);
/* Hardware start/stop functions */
int oce_start(struct oce_dev *dev);
void oce_stop(struct oce_dev *dev);
+int oce_identify_hw(struct oce_dev *dev);
+int oce_get_bdf(struct oce_dev *dev);
/* FMA support Functions */
void oce_fm_init(struct oce_dev *dev);
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_io.h b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_io.h
index 15ae0a577b..f3647e5ed8 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_io.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_io.h
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Header file defining the HW IO elements
@@ -45,7 +42,8 @@ extern "C" {
#include <oce_buf.h>
#define DEFAULT_MQ_MBOX_TIMEOUT (5 * 1000 * 1000) /* 5 sec (in usec) */
-#define DEFAULT_DRAIN_TIME 200 /* Default Drain Time */
+#define MBX_READY_TIMEOUT (1 * 1000 * 1000) /* 1 sec (in usec) */
+#define DEFAULT_DRAIN_TIME 200 /* Default Drain Time */
#define MBX_TIMEOUT_SEC 5
#define STAT_TIMEOUT 2000000 /* update stats every 2 sec */
@@ -217,19 +215,18 @@ struct oce_wq {
kmutex_t txc_lock; /* tx compl lock */
void *parent; /* parent of this wq */
oce_ring_buffer_t *ring; /* ring buffer managing the wqes */
- struct oce_cq *cq; /* cq associated with this wq */
- kmem_cache_t *wqed_cache; /* packet desc cache */
+ struct oce_cq *cq; /* cq associated with this wq */
+ kmem_cache_t *wqed_cache; /* packet desc cache */
oce_wq_bdesc_t *wq_bdesc_array; /* buffer desc array */
OCE_LIST_T wq_buf_list; /* buffer list */
OCE_LIST_T wqe_desc_list; /* packet descriptor list */
- OCE_LIST_T wq_mdesc_list; /* free list of memory handles */
- oce_wq_mdesc_t *wq_mdesc_array; /* preallocated memory handles */
- uint32_t wqm_used; /* memory handles uses */
- boolean_t resched; /* used for mac_tx_update */
- uint32_t wq_free; /* Wqe free */
- uint32_t tx_deferd; /* Wqe free */
- uint32_t pkt_drops; /* drops */
-
+ OCE_LIST_T wq_mdesc_list; /* free list of memory handles */
+ oce_wq_mdesc_t *wq_mdesc_array; /* preallocated memory handles */
+ uint32_t wqm_used; /* memory handles uses */
+ boolean_t resched; /* used for mac_tx_update */
+ uint32_t wq_free; /* Wqe free */
+ uint32_t tx_deferd; /* Wqe free */
+ uint32_t pkt_drops; /* drops */
/* Queue state */
qstate_t qstate;
uint16_t wq_id; /* wq ID */
@@ -310,7 +307,7 @@ void oce_arm_eq(struct oce_dev *dev, int16_t qid, int npopped,
void oce_arm_cq(struct oce_dev *dev, int16_t qid, int npopped,
boolean_t rearm);
void oce_drain_eq(struct oce_eq *eq);
-
+void oce_dev_rss_ready(struct oce_dev *dev);
/* Bootstrap */
int oce_mbox_init(struct oce_dev *dev);
@@ -394,7 +391,6 @@ int oce_config_rss(struct oce_dev *dev, uint16_t if_id, char *hkey, char *itbl,
int tbl_sz, uint16_t rss_type, uint8_t flush);
int oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
uint32_t *payload_length);
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_ioctl.h b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_ioctl.h
index e79a416c7b..878da3baa8 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_ioctl.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_ioctl.h
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Driver private ioctls
@@ -41,7 +38,21 @@ extern "C" {
#define OCE_IOC ((((('O' << 8) + 'C') << 8) + 'E') << 8)
-#define OCE_ISSUE_MBOX (OCE_IOC|1)
+#define OCE_ISSUE_MBOX (OCE_IOC | 1)
+#define OCE_QUERY_DRIVER_DATA (OCE_IOC | 0x10)
+
+#define OCN_VERSION_SUPPORTED 0x00
+
+#define MAX_SMAC 32
+struct oce_driver_query {
+ uint8_t version;
+ uint8_t smac_addr[MAX_SMAC][ETHERADDRL];
+ uint8_t pmac_addr[ETHERADDRL];
+ uint8_t driver_name[32];
+ uint8_t driver_version[32];
+ uint32_t num_smac;
+};
+
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_stat.h b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_stat.h
index 1830771c79..96c4944fdb 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_stat.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_stat.h
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Statistic specific data structures and function prototypes
@@ -74,6 +71,23 @@ struct oce_stat {
kstat_named_t tx_broadcast_frames;
kstat_named_t tx_pause_frames;
kstat_named_t tx_control_frames;
+
+
+ kstat_named_t rx_drops_no_pbuf;
+ kstat_named_t rx_drops_no_txpb;
+ kstat_named_t rx_drops_no_erx_descr;
+ kstat_named_t rx_drops_no_tpre_descr;
+ kstat_named_t rx_drops_too_many_frags;
+ kstat_named_t rx_drops_invalid_ring;
+ kstat_named_t rx_drops_mtu;
+
+ kstat_named_t rx_dropped_too_small;
+ kstat_named_t rx_dropped_too_short;
+ kstat_named_t rx_dropped_header_too_small;
+ kstat_named_t rx_dropped_tcp_length;
+ kstat_named_t rx_dropped_runt;
+
+ kstat_named_t rx_drops_no_fragments;
};
int oce_stat_init(struct oce_dev *dev);
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_utils.h b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_utils.h
index 6e3347fa3e..a87cebff15 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_utils.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_utils.h
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2009 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Driver Utility function prototypes
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_version.h b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_version.h
index 2b74e0e752..01826dcc09 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_version.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/oce/oce_version.h
@@ -19,10 +19,7 @@
* CDDL HEADER END
*/
-/*
- * Copyright 2010 Emulex. All rights reserved.
- * Use is subject to license terms.
- */
+/* Copyright © 2003-2011 Emulex. All rights reserved. */
/*
* Driver Version
@@ -36,9 +33,9 @@ extern "C" {
#endif
#define OCE_MAJOR_VERSION "1"
-#define OCE_MINOR_VERSION "1"
+#define OCE_MINOR_VERSION "2"
#define OCE_RELEASE_NUM "0"
-#define OCE_PROTO_LEVEL "s"
+#define OCE_PROTO_LEVEL "e"
#define OCE_VERSION OCE_MAJOR_VERSION "." \
OCE_MINOR_VERSION \
diff --git a/usr/src/uts/i86pc/io/acpi/acpinex/acpinex_event.c b/usr/src/uts/i86pc/io/acpi/acpinex/acpinex_event.c
index 633c99b442..f7979307fe 100644
--- a/usr/src/uts/i86pc/io/acpi/acpinex/acpinex_event.c
+++ b/usr/src/uts/i86pc/io/acpi/acpinex/acpinex_event.c
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2010, Intel Corporation.
* All rights reserved.
*/
@@ -487,6 +488,7 @@ static int
acpinex_event_install_handler(ACPI_HANDLE hdl, void *arg,
ACPI_DEVICE_INFO *infop, acpidev_data_handle_t dhdl)
{
+ ACPI_STATUS status;
int rc = DDI_SUCCESS;
ASSERT(hdl != NULL);
@@ -505,8 +507,9 @@ acpinex_event_install_handler(ACPI_HANDLE hdl, void *arg,
if (acpidev_data_get_flag(dhdl, ACPIDEV_DATA_HANDLER_READY)) {
return (DDI_SUCCESS);
}
- if (ACPI_SUCCESS(AcpiInstallNotifyHandler(hdl, ACPI_SYSTEM_NOTIFY,
- acpinex_event_system_handler, arg))) {
+ status = AcpiInstallNotifyHandler(hdl, ACPI_SYSTEM_NOTIFY,
+ acpinex_event_system_handler, arg);
+ if (status == AE_OK || status == AE_ALREADY_EXISTS) {
acpidev_data_set_flag(dhdl, ACPIDEV_DATA_HANDLER_READY);
} else {
char *objname;
diff --git a/usr/src/uts/i86pc/io/pcplusmp/apic_timer.c b/usr/src/uts/i86pc/io/pcplusmp/apic_timer.c
index ffc1e99f68..348f5034fc 100644
--- a/usr/src/uts/i86pc/io/pcplusmp/apic_timer.c
+++ b/usr/src/uts/i86pc/io/pcplusmp/apic_timer.c
@@ -25,6 +25,9 @@
* Copyright (c) 2010, Intel Corporation.
* All rights reserved.
*/
+/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ */
#include <sys/time.h>
#include <sys/psm.h>
@@ -286,8 +289,28 @@ oneshot_timer_reprogram(hrtime_t time)
static void
deadline_timer_enable(void)
{
+ uint64_t ticks;
+
apic_reg_ops->apic_write(APIC_LOCAL_TIMER,
(apic_clkvect + APIC_BASE_VECT) | AV_DEADLINE);
+ /*
+ * Now we have to serialize this per the SDM. That is to
+ * say, the above enabling can race in the pipeline with
+ * changes to the MSR. We need to make sure the above
+ * operation is complete before we proceed to reprogram
+ * the deadline value in reprogram(). The algorithm
+ * recommended by the Intel SDM 3A in 10.5.1.4 is:
+ *
+ * a) write a big value to the deadline register
+ * b) read the register back
+ * c) if it reads zero, go back to a and try again
+ */
+
+ do {
+ /* write a really big value */
+ wrmsr(IA32_DEADLINE_TSC_MSR, 1ULL << 63);
+ ticks = rdmsr(IA32_DEADLINE_TSC_MSR);
+ } while (ticks == 0);
}
/* deadline timer disable */
@@ -302,17 +325,20 @@ deadline_timer_disable(void)
static void
deadline_timer_reprogram(hrtime_t time)
{
+ int64_t delta;
uint64_t ticks;
- if (time <= 0) {
- /*
- * generate an immediate interrupt
- */
- ticks = (uint64_t)tsc_read();
- } else {
- ticks = unscalehrtime(time);
- }
+ /*
+ * Note that this entire routine is called with
+ * CBE_HIGH_PIL, so we needn't worry about preemption.
+ */
+ delta = time - gethrtime();
+
+ /* The unscalehrtime wants unsigned values. */
+ delta = max(delta, 0);
+ /* Now we shouldn't be interrupted, we can set the deadline */
+ ticks = (uint64_t)tsc_read() + unscalehrtime(delta);
wrmsr(IA32_DEADLINE_TSC_MSR, ticks);
}
diff --git a/usr/src/uts/i86pc/os/cpr_impl.c b/usr/src/uts/i86pc/os/cpr_impl.c
index 643753fa23..acc78eaa14 100644
--- a/usr/src/uts/i86pc/os/cpr_impl.c
+++ b/usr/src/uts/i86pc/os/cpr_impl.c
@@ -357,8 +357,8 @@ i_cpr_pre_resume_cpus()
gdt.limit = cpup->wc_gdt_limit;
#if defined(__amd64)
- code_length = (uintptr_t)wc_long_mode_64 -
- (uintptr_t)wc_rm_start;
+ code_length = (uint32_t)((uintptr_t)wc_long_mode_64 -
+ (uintptr_t)wc_rm_start);
#else
code_length = 0;
#endif
@@ -571,6 +571,7 @@ i_cpr_power_down(int sleeptype)
PMD(PMD_SX, ("real_mode_platter->rm_cr4=%lx, getcr4()=%lx\n",
(ulong_t)real_mode_platter->rm_cr4, (ulong_t)getcr4()))
+
PMD(PMD_SX, ("real_mode_platter->rm_pdbr=%lx, getcr3()=%lx\n",
(ulong_t)real_mode_platter->rm_pdbr, getcr3()))
@@ -584,7 +585,7 @@ i_cpr_power_down(int sleeptype)
* mapped address, we need to calculate it here.
*/
real_mode_platter->rm_longmode64_addr = rm_platter_pa +
- ((uintptr_t)wc_long_mode_64 - (uintptr_t)wc_rm_start);
+ (uint32_t)((uintptr_t)wc_long_mode_64 - (uintptr_t)wc_rm_start);
PMD(PMD_SX, ("real_mode_platter->rm_cr4=%lx, getcr4()=%lx\n",
(ulong_t)real_mode_platter->rm_cr4, getcr4()))
@@ -633,8 +634,8 @@ i_cpr_power_down(int sleeptype)
gdt.limit = cpup->wc_gdt_limit;
#if defined(__amd64)
- code_length = (uintptr_t)wc_long_mode_64 -
- (uintptr_t)wc_rm_start;
+ code_length = (uint32_t)((uintptr_t)wc_long_mode_64 -
+ (uintptr_t)wc_rm_start);
#else
code_length = 0;
#endif
diff --git a/usr/src/uts/intel/io/acpica/acpica.c b/usr/src/uts/intel/io/acpica/acpica.c
index 9c9c73dc03..999002f5c3 100644
--- a/usr/src/uts/intel/io/acpica/acpica.c
+++ b/usr/src/uts/intel/io/acpica/acpica.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Copyright (c) 2009, Intel Corporation.
@@ -65,7 +66,22 @@ static struct modlinkage modlinkage = {
* Local prototypes
*/
+struct parsed_prw {
+ ACPI_HANDLE prw_gpeobj;
+ int prw_gpebit;
+ int prw_level;
+};
+
static void acpica_init_kstats(void);
+static ACPI_STATUS acpica_init_PRW(
+ ACPI_HANDLE hdl,
+ UINT32 lvl,
+ void *ctxp,
+ void **rvpp);
+
+static ACPI_STATUS acpica_parse_PRW(
+ ACPI_BUFFER *prw_buf,
+ struct parsed_prw *prw);
/*
* Local data
@@ -166,7 +182,11 @@ _fini(void)
}
/*
- * Install acpica-provided address-space handlers
+ * Install acpica-provided (default) address-space handlers
+ * that may be needed before AcpiEnableSubsystem() runs.
+ * See the comment in AcpiInstallAddressSpaceHandler().
+ * Default handlers for remaining address spaces are
+ * installed later, in AcpiEnableSubsystem.
*/
static int
acpica_install_handlers()
@@ -200,6 +220,13 @@ acpica_install_handlers()
rv = AE_ERROR;
}
+ if (AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+ ACPI_ADR_SPACE_DATA_TABLE,
+ ACPI_DEFAULT_HANDLER, NULL, NULL) != AE_OK) {
+ cmn_err(CE_WARN, "!acpica: no default handler for"
+ " Data Table");
+ rv = AE_ERROR;
+ }
return (rv);
}
@@ -421,12 +448,23 @@ acpica_init()
/* do after AcpiEnableSubsystem() so GPEs are initialized */
acpica_ec_init(); /* initialize EC if present */
+ /* This runs all device _STA and _INI methods. */
if (ACPI_FAILURE(status = AcpiInitializeObjects(0)))
goto error;
acpica_init_state = ACPICA_INITIALIZED;
/*
+ * [ACPI, sec. 4.4.1.1]
+ * As of ACPICA version 20101217 (December 2010), the _PRW methods
+ * (Power Resources for Wake) are no longer automatically executed
+ * as part of the ACPICA initialization. The OS must do this.
+ */
+ (void) AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ UINT32_MAX, acpica_init_PRW, NULL, NULL, NULL);
+ (void) AcpiUpdateAllGpes();
+
+ /*
* If we are running on the Xen hypervisor as dom0 we need to
* find the ioapics so we can prevent ACPI from trying to
* access them.
@@ -539,6 +577,47 @@ acpica_get_sci(int *sci_irq, iflag_t *sci_flags)
}
/*
+ * Call-back function used for _PRW initialization. For every
+ * device node that has a _PRW method, evaluate, parse, and do
+ * AcpiSetupGpeForWake().
+ */
+static ACPI_STATUS
+acpica_init_PRW(
+ ACPI_HANDLE devhdl,
+ UINT32 depth,
+ void *ctxp,
+ void **rvpp)
+{
+ ACPI_STATUS status;
+ ACPI_BUFFER prw_buf;
+ struct parsed_prw prw;
+
+ prw_buf.Pointer = NULL;
+ prw_buf.Length = ACPI_ALLOCATE_BUFFER;
+
+ /*
+ * Attempt to evaluate _PRW object.
+ * If no valid object is found, return quietly, since not all
+ * devices have _PRW objects.
+ */
+ status = AcpiEvaluateObject(devhdl, "_PRW", NULL, &prw_buf);
+ if (ACPI_FAILURE(status))
+ goto done;
+ status = acpica_parse_PRW(&prw_buf, &prw);
+ if (ACPI_FAILURE(status))
+ goto done;
+
+ (void) AcpiSetupGpeForWake(devhdl,
+ prw.prw_gpeobj, prw.prw_gpebit);
+
+done:
+ if (prw_buf.Pointer != NULL)
+ AcpiOsFree(prw_buf.Pointer);
+
+ return (AE_OK);
+}
+
+/*
* Sets ACPI wake state for device referenced by dip.
* If level is S0 (0), disables wake event; otherwise,
* enables wake event which will wake system from level.
@@ -547,12 +626,12 @@ static int
acpica_ddi_setwake(dev_info_t *dip, int level)
{
ACPI_STATUS status;
- ACPI_HANDLE devobj, gpeobj;
- ACPI_OBJECT *prw, *gpe;
+ ACPI_HANDLE devobj;
ACPI_BUFFER prw_buf;
ACPI_OBJECT_LIST arglist;
ACPI_OBJECT args[3];
- int gpebit, pwr_res_count, prw_level, rv;
+ struct parsed_prw prw;
+ int rv;
/*
* initialize these early so we can use a common
@@ -627,12 +706,49 @@ acpica_ddi_setwake(dev_info_t *dip, int level)
* devices have _PRW objects.
*/
status = AcpiEvaluateObject(devobj, "_PRW", NULL, &prw_buf);
- prw = prw_buf.Pointer;
- if (ACPI_FAILURE(status) || prw_buf.Length == 0 || prw == NULL ||
- prw->Type != ACPI_TYPE_PACKAGE || prw->Package.Count < 2 ||
- prw->Package.Elements[1].Type != ACPI_TYPE_INTEGER) {
+ if (ACPI_FAILURE(status))
+ goto done;
+ status = acpica_parse_PRW(&prw_buf, &prw);
+ if (ACPI_FAILURE(status))
goto done;
+
+ rv = -1;
+ if (level == 0) {
+ status = AcpiDisableGpe(prw.prw_gpeobj, prw.prw_gpebit);
+ if (ACPI_FAILURE(status))
+ goto done;
+ } else if (prw.prw_level >= level) {
+ status = AcpiSetGpeWakeMask(prw.prw_gpeobj, prw.prw_gpebit,
+ ACPI_GPE_ENABLE);
+ if (ACPI_SUCCESS(status)) {
+ status = AcpiEnableGpe(prw.prw_gpeobj, prw.prw_gpebit);
+ if (ACPI_FAILURE(status))
+ goto done;
+ }
}
+ rv = 0;
+done:
+ if (prw_buf.Pointer != NULL)
+ AcpiOsFree(prw_buf.Pointer);
+ return (rv);
+}
+
+static ACPI_STATUS
+acpica_parse_PRW(
+ ACPI_BUFFER *prw_buf,
+ struct parsed_prw *p_prw)
+{
+ ACPI_HANDLE gpeobj;
+ ACPI_OBJECT *prw, *gpe;
+ int gpebit, prw_level;
+
+ if (prw_buf->Length == 0 || prw_buf->Pointer == NULL)
+ return (AE_NULL_OBJECT);
+
+ prw = prw_buf->Pointer;
+ if (prw->Type != ACPI_TYPE_PACKAGE || prw->Package.Count < 2 ||
+ prw->Package.Elements[1].Type != ACPI_TYPE_INTEGER)
+ return (AE_TYPE);
/* fetch the lowest wake level from the _PRW */
prw_level = prw->Package.Elements[1].Integer.Value;
@@ -649,30 +765,21 @@ acpica_ddi_setwake(dev_info_t *dip, int level)
gpe = &prw->Package.Elements[0];
if (gpe->Package.Count != 2 ||
gpe->Package.Elements[1].Type != ACPI_TYPE_INTEGER)
- goto done;
+ return (AE_TYPE);
gpeobj = gpe->Package.Elements[0].Reference.Handle;
gpebit = gpe->Package.Elements[1].Integer.Value;
if (gpeobj == NULL)
- goto done;
+ return (AE_NULL_OBJECT);
+ break;
default:
- goto done;
+ return (AE_TYPE);
}
- rv = -1;
- if (level == 0) {
- if (ACPI_FAILURE(AcpiDisableGpe(gpeobj, gpebit)))
- goto done;
- } else if (prw_level >= level) {
- if (ACPI_SUCCESS(
- AcpiSetGpeWakeMask(gpeobj, gpebit, ACPI_GPE_ENABLE)))
- if (ACPI_FAILURE(AcpiEnableGpe(gpeobj, gpebit)))
- goto done;
- }
- rv = 0;
-done:
- if (prw_buf.Pointer != NULL)
- AcpiOsFree(prw_buf.Pointer);
- return (rv);
+ p_prw->prw_gpeobj = gpeobj;
+ p_prw->prw_gpebit = gpebit;
+ p_prw->prw_level = prw_level;
+
+ return (AE_OK);
}
/*
diff --git a/usr/src/uts/intel/io/acpica/acpica_ec.c b/usr/src/uts/intel/io/acpica/acpica_ec.c
index 2de53b578c..e76c87e273 100644
--- a/usr/src/uts/intel/io/acpica/acpica_ec.c
+++ b/usr/src/uts/intel/io/acpica/acpica_ec.c
@@ -22,6 +22,7 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2011 Joyent, Inc. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Solaris x86 ACPI CA Embedded Controller operation region handler
@@ -42,12 +43,6 @@
#include <sys/acpica.h>
/*
- * Internal prototypes
- */
-static int ec_wait_ibf_clear(int sc_addr);
-static int ec_wait_obf_set(int sc_addr);
-
-/*
* EC status bits
* Low to high
* Output buffer full?
@@ -80,11 +75,13 @@ static int ec_wait_obf_set(int sc_addr);
/*
* EC softstate
*/
-struct ec_softstate {
- uint8_t ec_ok; /* != 0 when EC handler is attached */
+static struct ec_softstate {
+ uint8_t ec_ok; /* != 0 if we have ec_base, ec_sc */
uint16_t ec_base; /* base of EC I/O port - data */
- uint16_t ec_sc; /* EC status/command */
- ACPI_HANDLE ec_obj; /* handle to ACPI object for EC */
+ uint16_t ec_sc; /* EC status/command */
+ ACPI_HANDLE ec_dev_hdl; /* EC device handle */
+ ACPI_HANDLE ec_gpe_hdl; /* GPE info */
+ ACPI_INTEGER ec_gpe_bit;
kmutex_t ec_mutex; /* serialize access to EC */
} ec;
@@ -101,6 +98,12 @@ typedef struct io_port_des {
} io_port_des_t;
/*
+ * Patchable to ignore an ECDT, in case using that
+ * causes problems on someone's system.
+ */
+int ec_ignore_ecdt = 0;
+
+/*
* Patchable timeout values for EC input-buffer-full-clear
* and output-buffer-full-set. These are in 10uS units and
* default to 1 second.
@@ -109,14 +112,43 @@ int ibf_clear_timeout = 100000;
int obf_set_timeout = 100000;
/*
- * ACPI CA address space handler interface functions
+ * ACPI CA EC address space handler support functions
*/
-/*ARGSUSED*/
-static ACPI_STATUS
-ec_setup(ACPI_HANDLE reg, UINT32 func, void *context, void **ret)
+
+/*
+ * Busy-wait for IBF to clear
+ * return < 0 for time out, 0 for no error
+ */
+static int
+ec_wait_ibf_clear(int sc_addr)
{
+ int cnt;
- return (AE_OK);
+ cnt = ibf_clear_timeout;
+ while (inb(sc_addr) & EC_IBF) {
+ if (cnt-- <= 0)
+ return (-1);
+ drv_usecwait(10);
+ }
+ return (0);
+}
+
+/*
+ * Busy-wait for OBF to set
+ * return < 0 for time out, 0 for no error
+ */
+static int
+ec_wait_obf_set(int sc_addr)
+{
+ int cnt;
+
+ cnt = obf_set_timeout;
+ while (!(inb(sc_addr) & EC_OBF)) {
+ if (cnt-- <= 0)
+ return (-1);
+ drv_usecwait(10);
+ }
+ return (0);
}
/*
@@ -172,7 +204,7 @@ ec_rd(int addr)
* Only called from ec_handler(), which validates ec_ok
*/
static int
-ec_wr(int addr, uint8_t *val)
+ec_wr(int addr, uint8_t val)
{
int cnt;
uint8_t sc;
@@ -206,7 +238,7 @@ ec_wr(int addr, uint8_t *val)
return (-1);
}
- outb(ec.ec_base, *val); /* write data */
+ outb(ec.ec_base, val); /* write data */
if (ec_wait_ibf_clear(ec.ec_sc) < 0) {
cmn_err(CE_NOTE, "!ec_wr:3: timed-out waiting "
"for IBF to clear");
@@ -248,12 +280,16 @@ ec_query(void)
return (rv);
}
+/*
+ * ACPI CA EC address space handler
+ * Requires: ec.ec_sc, ec.ec_base
+ */
static ACPI_STATUS
ec_handler(UINT32 func, ACPI_PHYSICAL_ADDRESS addr, UINT32 width,
- ACPI_INTEGER *val, void *context, void *regcontext)
+ UINT64 *val, void *context, void *regcontext)
{
_NOTE(ARGUNUSED(context, regcontext))
- int tmp;
+ int i, tw, tmp;
/* Guard against unexpected invocation */
if (ec.ec_ok == 0)
@@ -263,52 +299,71 @@ ec_handler(UINT32 func, ACPI_PHYSICAL_ADDRESS addr, UINT32 width,
* Add safety checks for BIOSes not strictly compliant
* with ACPI spec
*/
- if (((width % 8) != 0) || (width > 8)) {
+ if ((width % 8) != 0) {
cmn_err(CE_NOTE, "!ec_handler: invalid width %d", width);
- return (AE_ERROR);
+ return (AE_BAD_PARAMETER);
+ }
+ if (val == NULL) {
+ cmn_err(CE_NOTE, "!ec_handler: NULL value pointer");
+ return (AE_BAD_PARAMETER);
}
- switch (func) {
- case ACPI_READ:
- tmp = ec_rd(addr);
- if (tmp < 0)
- return (AE_ERROR);
- *val = tmp;
- break;
- case ACPI_WRITE:
- if (ec_wr(addr, (uint8_t *)val) < 0)
- return (AE_ERROR);
- break;
- default:
- return (AE_ERROR);
+ while (width > 0) {
+
+ /* One UINT64 *val at a time. */
+ tw = min(width, 64);
+
+ if (func == ACPI_READ)
+ *val = 0;
+
+ /* Do I/O of up to 64 bits */
+ for (i = 0; i < tw; i += 8, addr++) {
+ switch (func) {
+ case ACPI_READ:
+ tmp = ec_rd(addr);
+ if (tmp < 0)
+ return (AE_ERROR);
+ *val |= ((UINT64)tmp) << i;
+ break;
+ case ACPI_WRITE:
+ tmp = ((*val) >> i) & 0xFF;
+ if (ec_wr(addr, (uint8_t)tmp) < 0)
+ return (AE_ERROR);
+ break;
+ default:
+ return (AE_ERROR);
+ }
+ }
+ val++;
+ width -= tw;
}
return (AE_OK);
}
-
+/*
+ * Called via taskq entry enqueued by ec_gpe_handler,
+ * which validates ec_ok
+ */
static void
ec_gpe_callback(void *ctx)
{
_NOTE(ARGUNUSED(ctx))
-
char query_str[5];
int query;
if (!(inb(ec.ec_sc) & EC_SCI))
- return;
-
- if (ec.ec_ok == 0) {
- cmn_err(CE_WARN, "!ec_gpe_callback: EC handler unavailable");
- return;
- }
+ goto out;
query = ec_query();
- if (query >= 0) {
- (void) snprintf(query_str, 5, "_Q%02X", (uint8_t)query);
- (void) AcpiEvaluateObject(ec.ec_obj, query_str, NULL, NULL);
- }
+ if (query < 0)
+ goto out;
+
+ (void) snprintf(query_str, 5, "_Q%02X", (uint8_t)query);
+ (void) AcpiEvaluateObject(ec.ec_dev_hdl, query_str, NULL, NULL);
+out:
+ AcpiFinishGpe(ec.ec_gpe_hdl, ec.ec_gpe_bit);
}
static UINT32
@@ -318,75 +373,129 @@ ec_gpe_handler(ACPI_HANDLE GpeDevice, UINT32 GpeNumber, void *ctx)
_NOTE(ARGUNUSED(GpeNumber))
_NOTE(ARGUNUSED(ctx))
+ /*
+ * With ec_ok==0, we will not install a GPE handler,
+ * so this is just paranoia. But if this were to
+ * happen somehow, don't add the taskq entry, and
+ * tell the caller we're done with this GPE call.
+ */
+ if (ec.ec_ok == 0)
+ return (ACPI_REENABLE_GPE);
+
AcpiOsExecute(OSL_GPE_HANDLER, ec_gpe_callback, NULL);
+
+ /*
+ * Returning zero tells the ACPI system that we will
+ * handle this event asynchronously.
+ */
return (0);
}
/*
- * Busy-wait for IBF to clear
- * return < 0 for time out, 0 for no error
+ * Some systems describe the EC using an "ECDT" (table).
+ * If we find one use it (unless ec_ignore_ecdt is set).
+ * Modern systems don't provide an ECDT.
*/
-static int
-ec_wait_ibf_clear(int sc_addr)
+static ACPI_STATUS
+ec_probe_ecdt(void)
{
- int cnt;
+ ACPI_TABLE_HEADER *th;
+ ACPI_TABLE_ECDT *ecdt;
+ ACPI_HANDLE dev_hdl;
+ ACPI_STATUS status;
+
+ status = AcpiGetTable(ACPI_SIG_ECDT, 1, &th);
+#ifndef DEBUG
+ if (status == AE_NOT_FOUND)
+ return (status);
+#endif
+ if (ACPI_FAILURE(status)) {
+ cmn_err(CE_NOTE, "!acpica: ECDT not found");
+ return (status);
+ }
+ if (ec_ignore_ecdt) {
+ /* pretend it was not found */
+ cmn_err(CE_NOTE, "!acpica: ECDT ignored");
+ return (AE_NOT_FOUND);
+ }
- cnt = ibf_clear_timeout;
- while (inb(sc_addr) & EC_IBF) {
- if (cnt-- <= 0)
- return (-1);
- drv_usecwait(10);
+ ecdt = (ACPI_TABLE_ECDT *)th;
+ if (ecdt->Control.BitWidth != 8 ||
+ ecdt->Data.BitWidth != 8) {
+ cmn_err(CE_NOTE, "!acpica: bad ECDT I/O width");
+ return (AE_BAD_VALUE);
}
+ status = AcpiGetHandle(NULL, (char *)ecdt->Id, &dev_hdl);
+ if (ACPI_FAILURE(status)) {
+ cmn_err(CE_NOTE, "!acpica: no ECDT device handle");
+ return (status);
+ }
+
+ /*
+ * Success. Save info for attach.
+ */
+ ec.ec_base = ecdt->Data.Address;
+ ec.ec_sc = ecdt->Control.Address;
+ ec.ec_dev_hdl = dev_hdl;
+ ec.ec_gpe_hdl = NULL;
+ ec.ec_gpe_bit = ecdt->Gpe;
+ ec.ec_ok = 1;
+
+#ifdef DEBUG
+ cmn_err(CE_NOTE, "!acpica:ec_probe_ecdt: success");
+#endif
return (0);
}
/*
- * Busy-wait for OBF to set
- * return < 0 for time out, 0 for no error
+ * Called from AcpiWalkDevices() when an EC device is found
*/
-static int
-ec_wait_obf_set(int sc_addr)
+static ACPI_STATUS
+ec_find(ACPI_HANDLE obj, UINT32 nest, void *context, void **rv)
{
- int cnt;
+ _NOTE(ARGUNUSED(nest, rv))
- cnt = obf_set_timeout;
- while (!(inb(sc_addr) & EC_OBF)) {
- if (cnt-- <= 0)
- return (-1);
- drv_usecwait(10);
- }
- return (0);
+ *((ACPI_HANDLE *)context) = obj;
+ return (AE_OK);
}
-
-
/*
- * Called from AcpiWalkDevices() when an EC device is found
+ * Normal way to get the details about the EC,
+ * by searching the name space.
*/
static ACPI_STATUS
-acpica_install_ec(ACPI_HANDLE obj, UINT32 nest, void *context, void **rv)
+ec_probe_ns(void)
{
- _NOTE(ARGUNUSED(nest, context, rv))
-
- int status, i;
+ ACPI_HANDLE dev_hdl;
ACPI_BUFFER buf, crs;
- ACPI_INTEGER gpe;
- int io_port_cnt;
-
- /*
- * Save the one EC object we have
- */
- ec.ec_obj = obj;
+ ACPI_OBJECT *gpe_obj;
+ ACPI_HANDLE gpe_hdl;
+ ACPI_INTEGER gpe_bit;
+ ACPI_STATUS status;
+ int i, io_port_cnt;
+ uint16_t ec_sc, ec_base;
+
+ dev_hdl = NULL;
+ (void) AcpiGetDevices("PNP0C09", &ec_find, (void *)&dev_hdl, NULL);
+ if (dev_hdl == NULL) {
+#ifdef DEBUG
+ /* Not an error, just no EC on this machine. */
+ cmn_err(CE_WARN, "!acpica:ec_probe_ns: "
+ "PNP0C09 not found");
+#endif
+ return (AE_NOT_FOUND);
+ }
/*
* Find ec_base and ec_sc addresses
*/
crs.Length = ACPI_ALLOCATE_BUFFER;
- if (ACPI_FAILURE(AcpiEvaluateObjectTyped(obj, "_CRS", NULL, &crs,
- ACPI_TYPE_BUFFER))) {
- cmn_err(CE_WARN, "!acpica_install_ec: _CRS object evaluate"
- "failed");
- return (AE_OK);
+ status = AcpiEvaluateObjectTyped(dev_hdl, "_CRS", NULL, &crs,
+ ACPI_TYPE_BUFFER);
+ if (ACPI_FAILURE(status)) {
+ cmn_err(CE_WARN, "!acpica:ec_probe_ns: "
+ "_CRS object evaluate failed");
+ return (status);
}
for (i = 0, io_port_cnt = 0;
@@ -399,13 +508,13 @@ acpica_install_ec(ACPI_HANDLE obj, UINT32 nest, void *context, void **rv)
continue;
io_port = (io_port_des_t *)tmp;
/*
- * Assuming first port is ec_base and second is ec_sc
+ * first port is ec_base and second is ec_sc
*/
- if (io_port_cnt)
- ec.ec_sc = (io_port->min_base_hi << 8) |
+ if (io_port_cnt == 0)
+ ec_base = (io_port->min_base_hi << 8) |
io_port->min_base_lo;
- else
- ec.ec_base = (io_port->min_base_hi << 8) |
+ if (io_port_cnt == 1)
+ ec_sc = (io_port->min_base_hi << 8) |
io_port->min_base_lo;
io_port_cnt++;
@@ -415,152 +524,219 @@ acpica_install_ec(ACPI_HANDLE obj, UINT32 nest, void *context, void **rv)
i += 7;
}
AcpiOsFree(crs.Pointer);
-
- /*
- * Drain the EC data register if something is left over from
- * legacy mode
- */
- if (inb(ec.ec_sc) & EC_OBF) {
-#ifndef DEBUG
- inb(ec.ec_base); /* read and discard value */
-#else
- cmn_err(CE_NOTE, "!EC had something: 0x%x\n", inb(ec.ec_base));
-#endif
+ if (io_port_cnt < 2) {
+ cmn_err(CE_WARN, "!acpica:ec_probe_ns: "
+ "_CRS parse failed");
+ return (AE_BAD_VALUE);
}
/*
- * Get GPE
+ * Get the GPE info.
*/
buf.Length = ACPI_ALLOCATE_BUFFER;
- /*
- * grab contents of GPE object
- */
- if (ACPI_FAILURE(AcpiEvaluateObjectTyped(obj, "_GPE", NULL, &buf,
- ACPI_TYPE_INTEGER))) {
- /* emit a warning but ignore the error */
- cmn_err(CE_WARN, "!acpica_install_ec: _GPE object evaluate"
- "failed");
- gpe = -1;
- } else {
- gpe = ((ACPI_OBJECT *)buf.Pointer)->Integer.Value;
- AcpiOsFree(buf.Pointer);
+ status = AcpiEvaluateObject(dev_hdl, "_GPE", NULL, &buf);
+ if (ACPI_FAILURE(status)) {
+ cmn_err(CE_WARN, "!acpica:ec_probe_ns: "
+ "_GPE object evaluate");
+ return (status);
}
-
+ gpe_obj = (ACPI_OBJECT *)buf.Pointer;
/*
- * Initialize EC mutex here
+ * process the GPE description
*/
- mutex_init(&ec.ec_mutex, NULL, MUTEX_DRIVER, NULL);
+ switch (gpe_obj->Type) {
+ case ACPI_TYPE_INTEGER:
+ gpe_hdl = NULL;
+ gpe_bit = gpe_obj->Integer.Value;
+ break;
+ case ACPI_TYPE_PACKAGE:
+ if (gpe_obj->Package.Count != 2)
+ goto bad_gpe;
+ gpe_obj = gpe_obj->Package.Elements;
+ if (gpe_obj[1].Type != ACPI_TYPE_INTEGER)
+ goto bad_gpe;
+ gpe_hdl = gpe_obj[0].Reference.Handle;
+ gpe_bit = gpe_obj[1].Integer.Value;
+ break;
+ bad_gpe:
+ default:
+ status = AE_BAD_VALUE;
+ break;
+ }
+ AcpiOsFree(buf.Pointer);
+ if (ACPI_FAILURE(status)) {
+ cmn_err(CE_WARN, "!acpica:ec_probe_ns: "
+ "_GPE parse failed");
+ return (status);
+ }
/*
- * Assume the EC handler is available now; the next attempt
- * to install the address space handler may actually need
- * to use the EC handler to install it (chicken/egg)
+ * Success. Save info for attach.
*/
+ ec.ec_base = ec_base;
+ ec.ec_sc = ec_sc;
+ ec.ec_dev_hdl = dev_hdl;
+ ec.ec_gpe_hdl = gpe_hdl;
+ ec.ec_gpe_bit = gpe_bit;
ec.ec_ok = 1;
- if (AcpiInstallAddressSpaceHandler(obj,
- ACPI_ADR_SPACE_EC, &ec_handler, &ec_setup, NULL) != AE_OK) {
- cmn_err(CE_WARN, "!acpica: failed to add EC handler\n");
- ec.ec_ok = 0; /* EC handler failed to install */
- membar_producer(); /* force ec_ok store before mutex_destroy */
- mutex_destroy(&ec.ec_mutex);
- return (AE_ERROR);
- }
+#ifdef DEBUG
+ cmn_err(CE_NOTE, "!acpica:ec_probe_ns: success");
+#endif
+ return (0);
+}
+
+/*
+ * Setup the Embedded Controller (EC) address space handler.
+ * Entered only if one of the EC probe methods found an EC.
+ */
+static void
+ec_init(void)
+{
+ ACPI_STATUS rc;
+ int x;
+
+ /* paranoia */
+ if (ec.ec_ok == 0)
+ return;
/*
- * In case the EC handler was successfully installed but no
- * GPE was found, return sucess; a warning was emitted above
+ * Drain the EC data register if something is left over from
+ * legacy mode
*/
- if (gpe < 0)
- return (AE_OK);
+ if (inb(ec.ec_sc) & EC_OBF) {
+ x = inb(ec.ec_base); /* read and discard value */
+#ifdef DEBUG
+ cmn_err(CE_NOTE, "!EC had something: 0x%x", x);
+#endif
+ }
/*
- * Have a valid EC GPE; enable it
+ * Install an "EC address space" handler.
+ *
+ * This call does a name space walk under the passed
+ * object looking for child objects with an EC space
+ * region for which to install this handler. Using
+ * the ROOT object makes sure we find them all.
+ *
+ * XXX: Some systems return an error from this call
+ * after a partial success, i.e. where the NS walk
+ * installs on some nodes and fails on other nodes.
+ * In such cases, disabling the EC and GPE handlers
+ * makes things worse, so just report the error and
+ * leave the EC handler enabled.
+ *
+ * At one point, it seemed that doing this part of
+ * EC setup earlier may help, which is why this is
+ * now a separate function from ec_attach. Someone
+ * needs to figure our why some systems give us an
+ * error return from this call. (TODO)
*/
- if ((status = AcpiInstallGpeHandler(NULL, gpe, ACPI_GPE_EDGE_TRIGGERED,
- ec_gpe_handler, NULL)) != AE_OK) {
- cmn_err(CE_WARN, "!acpica: failed to install gpe handler status"
- " = %d", status);
- /*
- * don't return an error here - GPE won't work but the EC
- * handler may be OK
- */
+ rc = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+ ACPI_ADR_SPACE_EC, &ec_handler, NULL, NULL);
+ if (rc != AE_OK) {
+ cmn_err(CE_WARN, "!acpica:ec_init: "
+ "install AS handler, rc=0x%x", rc);
+ return;
}
-
- (void) AcpiEnableGpe(NULL, gpe);
-
- return (AE_OK);
+#ifdef DEBUG
+ cmn_err(CE_NOTE, "!acpica:ec_init: success");
+#endif
}
-#ifdef DEBUG
-/*ARGSUSED*/
-static ACPI_STATUS
-acpica_install_smbus_v1(ACPI_HANDLE obj, UINT32 nest, void *context, void **rv)
+/*
+ * Attach the EC General-Purpose Event (GPE) handler.
+ */
+static void
+ec_attach(void)
{
+ ACPI_STATUS rc;
- cmn_err(CE_NOTE, "!acpica: found an SMBC Version 1.0\n");
- return (AE_OK);
-}
+ /*
+ * Guard against call without probe results.
+ */
+ if (ec.ec_ok == 0) {
+ cmn_err(CE_WARN, "!acpica:ec_attach: "
+ "no EC device found");
+ return;
+ }
-/*ARGSUSED*/
-static ACPI_STATUS
-acpica_install_smbus_v2(ACPI_HANDLE obj, UINT32 nest, void *context, void **rv)
-{
+ /*
+ * Install the GPE handler and enable it.
+ */
+ rc = AcpiInstallGpeHandler(ec.ec_gpe_hdl, ec.ec_gpe_bit,
+ ACPI_GPE_EDGE_TRIGGERED, ec_gpe_handler, NULL);
+ if (rc != AE_OK) {
+ cmn_err(CE_WARN, "!acpica:ec_attach: "
+ "install GPE handler, rc=0x%x", rc);
+ goto errout;
+ }
- cmn_err(CE_NOTE, "!acpica: found an SMBC Version 2.0\n");
- return (AE_OK);
-}
-#endif /* DEBUG */
+ rc = AcpiEnableGpe(ec.ec_gpe_hdl, ec.ec_gpe_bit);
+ if (rc != AE_OK) {
+ cmn_err(CE_WARN, "!acpica:ec_attach: "
+ "enable GPE handler, rc=0x%x", rc);
+ goto errout;
+ }
-#ifdef NOTYET
-static void
-prgas(ACPI_GENERIC_ADDRESS *gas)
-{
- cmn_err(CE_CONT, "gas: %d %d %d %d %lx",
- gas->AddressSpaceId, gas->RegisterBitWidth, gas->RegisterBitOffset,
- gas->AccessWidth, (long)gas->Address);
+#ifdef DEBUG
+ cmn_err(CE_NOTE, "!acpica:ec_attach: success");
+#endif
+ return;
+
+errout:
+ AcpiRemoveGpeHandler(ec.ec_gpe_hdl, ec.ec_gpe_bit,
+ ec_gpe_handler);
}
+/*
+ * System Management Bus Controller (SMBC)
+ * These also go through the EC.
+ * (not yet supported)
+ */
static void
-acpica_probe_ecdt()
+smbus_attach(void)
{
- EC_BOOT_RESOURCES *ecdt;
-
+#ifdef DEBUG
+ ACPI_HANDLE obj;
- if (AcpiGetTable("ECDT", 1, (ACPI_TABLE_HEADER **) &ecdt) != AE_OK) {
- cmn_err(CE_NOTE, "!acpica: ECDT not found\n");
- return;
+ obj = NULL;
+ (void) AcpiGetDevices("ACPI0001", &ec_find, (void *)&obj, NULL);
+ if (obj != NULL) {
+ cmn_err(CE_NOTE, "!acpica: found an SMBC Version 1.0");
}
- cmn_err(CE_NOTE, "EcControl: ");
- prgas(&ecdt->EcControl);
-
- cmn_err(CE_NOTE, "EcData: ");
- prgas(&ecdt->EcData);
+ obj = NULL;
+ (void) AcpiGetDevices("ACPI0005", &ec_find, (void *)&obj, NULL);
+ if (obj != NULL) {
+ cmn_err(CE_NOTE, "!acpica: found an SMBC Version 2.0");
+ }
+#endif /* DEBUG */
}
-#endif /* NOTYET */
+/*
+ * Initialize the EC, if present.
+ */
void
acpica_ec_init(void)
{
-#ifdef NOTYET
+ ACPI_STATUS rc;
+
/*
- * Search the ACPI tables for an ECDT; if
- * found, use it to install an EC handler
+ * Initialize EC mutex here
*/
- acpica_probe_ecdt();
-#endif /* NOTYET */
-
- /* EC handler defaults to not available */
- ec.ec_ok = 0;
+ mutex_init(&ec.ec_mutex, NULL, MUTEX_DRIVER, NULL);
/*
- * General model is: use GetDevices callback to install
- * handler(s) when device is present.
+ * First search the ACPI tables for an ECDT, and
+ * if not found, search the name space for it.
*/
- (void) AcpiGetDevices("PNP0C09", &acpica_install_ec, NULL, NULL);
-#ifdef DEBUG
- (void) AcpiGetDevices("ACPI0001", &acpica_install_smbus_v1, NULL, NULL);
- (void) AcpiGetDevices("ACPI0005", &acpica_install_smbus_v2, NULL, NULL);
-#endif /* DEBUG */
+ rc = ec_probe_ecdt();
+ if (ACPI_FAILURE(rc))
+ rc = ec_probe_ns();
+ if (ACPI_SUCCESS(rc)) {
+ ec_init();
+ ec_attach();
+ }
+ smbus_attach();
}
diff --git a/usr/src/uts/intel/io/acpica/osl.c b/usr/src/uts/intel/io/acpica/osl.c
index 783db12211..d5bfab754f 100644
--- a/usr/src/uts/intel/io/acpica/osl.c
+++ b/usr/src/uts/intel/io/acpica/osl.c
@@ -713,7 +713,7 @@ AcpiOsGetThreadId(void)
* ACPI CA assumes that thread ID is castable to a pointer,
* so we use the current thread pointer.
*/
- return (ACPI_CAST_PTHREAD_T ((uintptr_t)curthread));
+ return (ACPI_CAST_PTHREAD_T((uintptr_t)curthread));
}
/*
diff --git a/usr/src/uts/intel/sys/acpi/platform/acsolaris.h b/usr/src/uts/intel/sys/acpi/platform/acsolaris.h
index d48d1a8fed..b0cd8bfcf3 100644
--- a/usr/src/uts/intel/sys/acpi/platform/acsolaris.h
+++ b/usr/src/uts/intel/sys/acpi/platform/acsolaris.h
@@ -19,6 +19,7 @@
* CDDL HEADER END
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,6 +37,9 @@ extern "C" {
#include <sys/cpu.h>
#include <sys/thread.h>
+/* Function name used for debug output. */
+#define ACPI_GET_FUNCTION_NAME __func__
+
uint32_t __acpi_acquire_global_lock(void *);
uint32_t __acpi_release_global_lock(void *);
void __acpi_wbinvd(void);