summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2015-12-28 07:46:42 -0200
committerRenato Botelho <renato@netgate.com>2015-12-28 07:46:42 -0200
commit0319542cc712df59c57f014b4f925f516bcb5b4b (patch)
treed471c26ca5a9ed2a730a1bbb6781f4e08c79a939
parent3f9b44b7cebbdee8202dd56d8c57ac81b13114e1 (diff)
parent70f106975f9e06a5c50c4dfa06fb3b3d41d1780f (diff)
downloadFreeBSD-src-0319542cc712df59c57f014b4f925f516bcb5b4b.zip
FreeBSD-src-0319542cc712df59c57f014b4f925f516bcb5b4b.tar.gz
Merge remote-tracking branch 'origin/stable/10' into devel
-rw-r--r--bin/ed/main.c10
-rw-r--r--bin/sh/mknodes.c20
-rw-r--r--bin/sh/var.c2
-rw-r--r--contrib/smbfs/README8
-rwxr-xr-xetc/periodic/daily/800.scrub-zfs4
-rwxr-xr-xetc/periodic/security/520.pfdenied2
-rw-r--r--etc/services277
-rw-r--r--gnu/usr.bin/Makefile2
-rw-r--r--include/netdb.h4
-rw-r--r--lib/libc/gen/lockf.c11
-rw-r--r--lib/libc/net/getaddrinfo.360
-rw-r--r--lib/libc/net/getaddrinfo.c172
-rw-r--r--lib/libc/net/name6.c7
-rw-r--r--lib/libc/sys/clock_gettime.26
-rw-r--r--lib/libc/sys/gettimeofday.24
-rw-r--r--lib/liblzma/Makefile6
-rw-r--r--share/examples/tests/tests/atf/printf_test.c2
-rw-r--r--share/man/man4/isp.414
-rw-r--r--share/mk/bsd.README4
-rw-r--r--share/mk/bsd.test.mk3
-rw-r--r--share/mk/suite.test.mk34
-rw-r--r--share/mk/tap.test.mk2
-rw-r--r--sys/conf/files3
-rw-r--r--sys/conf/files.sparc641
-rw-r--r--sys/conf/options2
-rw-r--r--sys/contrib/ipfilter/netinet/ip_nat.c4
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel_mgmt.c2
-rw-r--r--sys/dev/if_ndis/if_ndis_pci.c3
-rw-r--r--sys/dev/isp/isp.c69
-rw-r--r--sys/dev/isp/isp_freebsd.c95
-rw-r--r--sys/dev/isp/isp_freebsd.h15
-rw-r--r--sys/dev/isp/isp_library.c13
-rw-r--r--sys/dev/isp/isp_pci.c294
-rw-r--r--sys/dev/isp/isp_sbus.c16
-rw-r--r--sys/dev/isp/ispmbox.h17
-rw-r--r--sys/dev/isp/ispvar.h12
-rw-r--r--sys/dev/md/md.c40
-rw-r--r--sys/dev/mii/rgephy.c2
-rw-r--r--sys/dev/mii/rlphy.c2
-rw-r--r--sys/dev/mii/rlswitch.c2
-rw-r--r--sys/dev/mpt/mpt.c11
-rw-r--r--sys/dev/mpt/mpt.h12
-rw-r--r--sys/dev/qlxgbe/ql_hw.c3
-rw-r--r--sys/dev/qlxgbe/ql_os.c2
-rw-r--r--sys/dev/qlxgbe/ql_ver.h2
-rw-r--r--sys/dev/re/if_re.c60
-rw-r--r--sys/dev/rl/if_rl.c (renamed from sys/pci/if_rl.c)2
-rw-r--r--sys/dev/rl/if_rlreg.h (renamed from sys/pci/if_rlreg.h)4
-rw-r--r--sys/dev/usb/net/if_urndis.c178
-rw-r--r--sys/dev/vt/colors/vt_termcolors.c11
-rw-r--r--sys/modules/hyperv/netvsc/Makefile2
-rw-r--r--sys/modules/rl/Makefile2
-rw-r--r--sys/netgraph/ng_base.c2
-rw-r--r--sys/netinet/tcp.h5
-rw-r--r--sys/netinet/tcp_fastopen.c442
-rw-r--r--sys/netinet/tcp_fastopen.h47
-rw-r--r--sys/netinet/tcp_input.c92
-rw-r--r--sys/netinet/tcp_output.c71
-rw-r--r--sys/netinet/tcp_subr.c21
-rw-r--r--sys/netinet/tcp_syncache.c137
-rw-r--r--sys/netinet/tcp_syncache.h6
-rw-r--r--sys/netinet/tcp_timer.c3
-rw-r--r--sys/netinet/tcp_usrreq.c57
-rw-r--r--sys/netinet/tcp_var.h16
-rw-r--r--sys/sparc64/ebus/ebus.c35
-rw-r--r--sys/sparc64/include/md_var.h2
-rw-r--r--sys/sparc64/include/smp.h20
-rw-r--r--sys/sparc64/pci/fire.c335
-rw-r--r--sys/sparc64/pci/firereg.h1
-rw-r--r--sys/sparc64/pci/firevar.h20
-rw-r--r--sys/sparc64/pci/ofw_pci.c412
-rw-r--r--sys/sparc64/pci/ofw_pci.h43
-rw-r--r--sys/sparc64/pci/psycho.c340
-rw-r--r--sys/sparc64/pci/psychoreg.h6
-rw-r--r--sys/sparc64/pci/psychovar.h47
-rw-r--r--sys/sparc64/pci/schizo.c349
-rw-r--r--sys/sparc64/pci/schizoreg.h5
-rw-r--r--sys/sparc64/pci/schizovar.h37
-rw-r--r--sys/sparc64/sparc64/machdep.c10
-rw-r--r--sys/sparc64/sparc64/mp_machdep.c52
-rw-r--r--sys/ufs/ffs/ffs_softdep.c64
-rw-r--r--sys/x86/x86/busdma_bounce.c73
-rw-r--r--tests/freebsd_test_suite/macros.h15
-rw-r--r--tools/debugscripts/README6
-rw-r--r--tools/regression/lib/libc/nss/mach47
-rw-r--r--tools/regression/lib/libc/resolv/mach47
-rw-r--r--tools/regression/lib/msun/test-ctrig.c2
-rw-r--r--tools/regression/lib/msun/test-exponential.c13
-rw-r--r--tools/regression/lib/msun/test-fma.c40
-rw-r--r--tools/regression/lib/msun/test-invctrig.c8
-rw-r--r--tools/regression/lib/msun/test-invtrig.c27
-rw-r--r--usr.bin/bc/bc.19
-rw-r--r--usr.bin/bc/bc.y2
-rw-r--r--usr.bin/bc/extern.h10
-rw-r--r--usr.bin/bc/tty.c6
-rw-r--r--usr.sbin/ypserv/Makefile.yp32
96 files changed, 2700 insertions, 1849 deletions
diff --git a/bin/ed/main.c b/bin/ed/main.c
index 98bb300..1749314 100644
--- a/bin/ed/main.c
+++ b/bin/ed/main.c
@@ -505,7 +505,8 @@ exec_command(void)
return ERR;
else if (open_sbuf() < 0)
return FATAL;
- if (*fnp && *fnp != '!') strcpy(old_filename, fnp);
+ if (*fnp && *fnp != '!')
+ strlcpy(old_filename, fnp, PATH_MAX);
#ifdef BACKWARDS
if (*fnp == '\0' && *old_filename == '\0') {
errmsg = "no current filename";
@@ -532,7 +533,8 @@ exec_command(void)
return ERR;
}
GET_COMMAND_SUFFIX();
- if (*fnp) strcpy(old_filename, fnp);
+ if (*fnp)
+ strlcpy(old_filename, fnp, PATH_MAX);
printf("%s\n", strip_escapes(old_filename));
break;
case 'g':
@@ -663,7 +665,7 @@ exec_command(void)
GET_COMMAND_SUFFIX();
if (!isglobal) clear_undo_stack();
if (*old_filename == '\0' && *fnp != '!')
- strcpy(old_filename, fnp);
+ strlcpy(old_filename, fnp, PATH_MAX);
#ifdef BACKWARDS
if (*fnp == '\0' && *old_filename == '\0') {
errmsg = "no current filename";
@@ -797,7 +799,7 @@ exec_command(void)
return ERR;
GET_COMMAND_SUFFIX();
if (*old_filename == '\0' && *fnp != '!')
- strcpy(old_filename, fnp);
+ strlcpy(old_filename, fnp, PATH_MAX);
#ifdef BACKWARDS
if (*fnp == '\0' && *old_filename == '\0') {
errmsg = "no current filename";
diff --git a/bin/sh/mknodes.c b/bin/sh/mknodes.c
index 1a177f8..1fe8bba 100644
--- a/bin/sh/mknodes.c
+++ b/bin/sh/mknodes.c
@@ -89,7 +89,6 @@ static struct str *nodestr[MAXTYPES]; /* type of structure used by the node */
static int nstr; /* number of structures */
static struct str str[MAXTYPES]; /* the structures */
static struct str *curstr; /* current structure */
-static FILE *infp;
static char line[1024];
static int linno;
static char *linep;
@@ -102,7 +101,7 @@ static void outfunc(FILE *, int);
static void indent(int, FILE *);
static int nextfield(char *);
static void skipbl(void);
-static int readline(void);
+static int readline(FILE *);
static void error(const char *, ...) __printf0like(1, 2) __dead2;
static char *savestr(const char *);
@@ -110,17 +109,19 @@ static char *savestr(const char *);
int
main(int argc, char *argv[])
{
+ FILE *infp;
+
if (argc != 3)
error("usage: mknodes file");
- infp = stdin;
if ((infp = fopen(argv[1], "r")) == NULL)
error("Can't open %s: %s", argv[1], strerror(errno));
- while (readline()) {
+ while (readline(infp)) {
if (line[0] == ' ' || line[0] == '\t')
parsefield();
else if (line[0] != '\0')
parsenode();
}
+ fclose(infp);
output(argv[2]);
exit(0);
}
@@ -253,6 +254,10 @@ output(char *file)
fputs("union node *getfuncnode(struct funcdef *);\n", hfile);
fputs("void reffunc(struct funcdef *);\n", hfile);
fputs("void unreffunc(struct funcdef *);\n", hfile);
+ if (ferror(hfile))
+ error("Can't write to nodes.h");
+ if (fclose(hfile))
+ error("Can't close nodes.h");
fputs(writer, cfile);
while (fgets(line, sizeof line, patfile) != NULL) {
@@ -266,6 +271,11 @@ output(char *file)
else
fputs(line, cfile);
}
+ fclose(patfile);
+ if (ferror(cfile))
+ error("Can't write to nodes.c");
+ if (fclose(cfile))
+ error("Can't close nodes.c");
}
@@ -401,7 +411,7 @@ skipbl(void)
static int
-readline(void)
+readline(FILE *infp)
{
char *p;
diff --git a/bin/sh/var.c b/bin/sh/var.c
index ebeff16..d083523 100644
--- a/bin/sh/var.c
+++ b/bin/sh/var.c
@@ -328,7 +328,7 @@ setvareq(char *s, int flags)
if (vp->flags & VREADONLY) {
if ((flags & (VTEXTFIXED|VSTACK)) == 0)
ckfree(s);
- error("%.*s: is read only", vp->name_len, s);
+ error("%.*s: is read only", vp->name_len, vp->text);
}
if (flags & VNOSET) {
if ((flags & (VTEXTFIXED|VSTACK)) == 0)
diff --git a/contrib/smbfs/README b/contrib/smbfs/README
index b63e16c..f0a61b1 100644
--- a/contrib/smbfs/README
+++ b/contrib/smbfs/README
@@ -15,7 +15,7 @@ It is a complete, kernel side implementation of SMB requester and filesystem.
Darwin maintained in the Darwin's tree.
- I'm would be very grateful for any feedback, bug reports etc.
+ I would be very grateful for any feedback, bug reports etc.
Supported SMB servers:
Samba
@@ -23,14 +23,14 @@ It is a complete, kernel side implementation of SMB requester and filesystem.
IBM LanManager
NetApp
- An updated versions of this package can be retrieved from ftp server:
+ An updated version of this package can be retrieved from ftp server:
ftp://ftp.butya.kz/pub/smbfs/smbfs.tar.gz
- Perfomance
+ Performance
==========
- There is some perfomance benchmarks over 10Mbit network:
+ These are some performance benchmarks over a 10Mbit network:
Win95 machine as server:
IOZONE: auto-test mode
diff --git a/etc/periodic/daily/800.scrub-zfs b/etc/periodic/daily/800.scrub-zfs
index ee0e52a..359be13 100755
--- a/etc/periodic/daily/800.scrub-zfs
+++ b/etc/periodic/daily/800.scrub-zfs
@@ -43,6 +43,10 @@ case "$daily_scrub_zfs_enable" in
rc=3
echo "Skipping faulted pool: ${pool}"
continue ;;
+ *UNAVAIL*)
+ rc=4
+ echo "Skipping unavailable pool: ${pool}"
+ continue ;;
esac
# determine how many days shall be between scrubs
diff --git a/etc/periodic/security/520.pfdenied b/etc/periodic/security/520.pfdenied
index 7a32bf2..3fea360 100755
--- a/etc/periodic/security/520.pfdenied
+++ b/etc/periodic/security/520.pfdenied
@@ -44,7 +44,7 @@ rc=0
if check_yesno_period security_status_pfdenied_enable
then
TMP=`mktemp -t security`
- if pfctl -sr -v 2>/dev/null | nawk '{if (/^block/) {buf=$0; getline; gsub(" +"," ",$0); print buf$0;} }' > ${TMP}; then
+ if pfctl -sr -v 2>/dev/null | nawk '{if (/^block/) {buf=$0; getline; gsub(" +"," ",$0); if ($5 > 0) print buf$0;} }' > ${TMP}; then
check_diff new_only pf ${TMP} "${host} pf denied packets:"
fi
rc=$?
diff --git a/etc/services b/etc/services
index d2f9dde..b36e5a0 100644
--- a/etc/services
+++ b/etc/services
@@ -1029,7 +1029,7 @@ nntps 563/udp snntp #nntp protocol over TLS/SSL
whoami 565/tcp
whoami 565/udp
streettalk 566/tcp
-streettalk 566/udp
+streettalk 566/udp
banyan-rpc 567/tcp
banyan-rpc 567/udp
ms-shuttle 568/tcp #Microsoft shuttle
@@ -1099,16 +1099,16 @@ acp 599/tcp #Aeolon Core Protocol
acp 599/udp #Aeolon Core Protocol
ipcserver 600/tcp #Sun IPC server
ipcserver 600/udp #Sun IPC server
-syslog-conn 601/tcp #Reliable Syslog Service
-syslog-conn 601/udp #Reliable Syslog Service
-xmlrpc-beep 602/tcp #XML-RPC over BEEP
-xmlrpc-beep 602/udp #XML-RPC over BEEP
-idxp 603/tcp
-idxp 603/udp
-tunnel 604/tcp
-tunnel 604/udp
-soap-beep 605/tcp #SOAP over BEEP
-soap-beep 605/udp #SOAP over BEEP
+syslog-conn 601/tcp #Reliable Syslog Service
+syslog-conn 601/udp #Reliable Syslog Service
+xmlrpc-beep 602/tcp #XML-RPC over BEEP
+xmlrpc-beep 602/udp #XML-RPC over BEEP
+idxp 603/tcp
+idxp 603/udp
+tunnel 604/tcp
+tunnel 604/udp
+soap-beep 605/tcp #SOAP over BEEP
+soap-beep 605/udp #SOAP over BEEP
urm 606/tcp #Cray Unified Resource Manager
urm 606/udp #Cray Unified Resource Manager
nqs 607/tcp
@@ -1137,14 +1137,14 @@ dei-icda 618/tcp
dei-icda 618/udp
compaq-evm 619/tcp #Compaq EVM
compaq-evm 619/udp #Compaq EVM
-sco-websrvrmgr 620/tcp #SCO WebServer Manager
-sco-websrvrmgr 620/udp #SCO WebServer Manager
+sco-websrvrmgr 620/tcp #SCO WebServer Manager
+sco-websrvrmgr 620/udp #SCO WebServer Manager
escp-ip 621/tcp #ESCP
escp-ip 621/udp #ESCP
collaborator 622/tcp
collaborator 622/udp
-asf-rmcp 623/tcp #ASF Remote Management and Control Protocol
-asf-rmcp 623/udp #ASF Remote Management and Control Protocol
+asf-rmcp 623/tcp #ASF Remote Management and Control Protocol
+asf-rmcp 623/udp #ASF Remote Management and Control Protocol
cryptoadmin 624/tcp #Crypto Admin
cryptoadmin 624/udp #Crypto Admin
dec_dlm 625/tcp #DEC DLM
@@ -1167,12 +1167,12 @@ servstat 633/tcp #Service Status update (Sterling Software)
servstat 633/udp #Service Status update (Sterling Software)
ginad 634/tcp
ginad 634/udp
-rlzdbase 635/tcp #RLZ DBase
-rlzdbase 635/udp #RLZ DBase
+rlzdbase 635/tcp #RLZ DBase
+rlzdbase 635/udp #RLZ DBase
ldaps 636/tcp sldap #ldap protocol over TLS/SSL
ldaps 636/udp sldap
-lanserver 637/tcp
-lanserver 637/udp
+lanserver 637/tcp
+lanserver 637/udp
mcns-sec 638/tcp
mcns-sec 638/udp
msdp 639/tcp
@@ -1191,12 +1191,12 @@ pssc 645/tcp
pssc 645/udp
ldp 646/tcp
ldp 646/udp
-dhcp-failover 647/tcp #DHCP Failover
-dhcp-failover 647/udp #DHCP Failover
-rrp 648/tcp #Registry Registrar Protocol (RRP)
-rrp 648/udp #Registry Registrar Protocol (RRP)
-cadview-3d 649/tcp #Cadview-3d - streaming 3d models over the internet
-cadview-3d 649/udp #Cadview-3d - streaming 3d models over the internet
+dhcp-failover 647/tcp #DHCP Failover
+dhcp-failover 647/udp #DHCP Failover
+rrp 648/tcp #Registry Registrar Protocol (RRP)
+rrp 648/udp #Registry Registrar Protocol (RRP)
+cadview-3d 649/tcp #Cadview-3d - streaming 3d models over the internet
+cadview-3d 649/udp #Cadview-3d - streaming 3d models over the internet
obex 650/tcp
obex 650/udp
ieee-mms 651/tcp #IEEE MMS
@@ -1215,38 +1215,38 @@ rmc 657/tcp
rmc 657/udp
tenfold 658/tcp
tenfold 658/udp
-mac-srvr-admin 660/tcp #MacOS Server Admin
-mac-srvr-admin 660/udp #MacOS Server Admin
-hap 661/tcp
-hap 661/udp
-pftp 662/tcp
-pftp 662/udp
-purenoise 663/tcp #PureNoise
-purenoise 663/udp #PureNoise
-asf-secure-rmcp 664/tcp #ASF Secure Remote Management and Control Protocol
-asf-secure-rmcp 664/udp #ASF Secure Remote Management and Control Protocol
-sun-dr 665/tcp #Sun DR
-sun-dr 665/udp #Sun DR
+mac-srvr-admin 660/tcp #MacOS Server Admin
+mac-srvr-admin 660/udp #MacOS Server Admin
+hap 661/tcp
+hap 661/udp
+pftp 662/tcp
+pftp 662/udp
+purenoise 663/tcp #PureNoise
+purenoise 663/udp #PureNoise
+asf-secure-rmcp 664/tcp #ASF Secure Remote Management and Control Protocol
+asf-secure-rmcp 664/udp #ASF Secure Remote Management and Control Protocol
+sun-dr 665/tcp #Sun DR
+sun-dr 665/udp #Sun DR
mdqs 666/tcp
mdqs 666/udp
#PROBLEMS!===============================================
doom 666/tcp #doom Id Software
doom 666/udp #doom Id Software
#PROBLEMS!===============================================
-disclose 667/tcp #campaign contribution disclosures - SDR Technologies
-disclose 667/udp #campaign contribution disclosures - SDR Technologies
-mecomm 668/tcp
-mecomm 668/udp
-meregister 669/tcp
-meregister 669/udp
-vacdsm-sws 670/tcp
-vacdsm-sws 670/udp
-vacdsm-app 671/tcp
-vacdsm-app 671/udp
-vpps-qua 672/tcp
-vpps-qua 672/udp
-cimplex 673/tcp
-cimplex 673/udp
+disclose 667/tcp #campaign contribution disclosures - SDR Technologies
+disclose 667/udp #campaign contribution disclosures - SDR Technologies
+mecomm 668/tcp
+mecomm 668/udp
+meregister 669/tcp
+meregister 669/udp
+vacdsm-sws 670/tcp
+vacdsm-sws 670/udp
+vacdsm-app 671/tcp
+vacdsm-app 671/udp
+vpps-qua 672/tcp
+vpps-qua 672/udp
+cimplex 673/tcp
+cimplex 673/udp
acap 674/tcp #Application Configuration Access Protocol
acap 674/udp #Application Configuration Access Protocol
dctp 675/tcp
@@ -1257,70 +1257,70 @@ vpp 677/tcp #Virtual Presence Protocol
vpp 677/udp #Virtual Presence Protocol
ggf-ncp 678/tcp #GNU Generation Foundation NCP
ggf-ncp 678/udp #GNU Generation Foundation NCP
-mrm 679/tcp
-mrm 679/udp
+mrm 679/tcp
+mrm 679/udp
entrust-aaas 680/tcp
entrust-aaas 680/udp
entrust-aams 681/tcp
entrust-aams 681/udp
-xfr 682/tcp
-xfr 682/udp
-corba-iiop 683/tcp #CORBA IIOP
-corba-iiop 683/udp #CORBA IIOP
+xfr 682/tcp
+xfr 682/udp
+corba-iiop 683/tcp #CORBA IIOP
+corba-iiop 683/udp #CORBA IIOP
corba-iiop-ssl 684/tcp #CORBA IIOP SSL
corba-iiop-ssl 684/udp #CORBA IIOP SSL
mdc-portmapper 685/tcp #MDC Port Mapper
mdc-portmapper 685/udp #MDC Port Mapper
-hcp-wismar 686/tcp #Hardware Control Protocol Wismar
-hcp-wismar 686/udp #Hardware Control Protocol Wismar
+hcp-wismar 686/tcp #Hardware Control Protocol Wismar
+hcp-wismar 686/udp #Hardware Control Protocol Wismar
asipregistry 687/tcp
asipregistry 687/udp
-realm-rusd 688/tcp #ApplianceWare management protocol
-realm-rusd 688/udp #ApplianceWare management protocol
-nmap 689/tcp
-nmap 689/udp
-vatp 690/tcp #Velazquez Application Transfer Protocol
-vatp 690/udp #Velazquez Application Transfer Protocol
+realm-rusd 688/tcp #ApplianceWare management protocol
+realm-rusd 688/udp #ApplianceWare management protocol
+nmap 689/tcp
+nmap 689/udp
+vatp 690/tcp #Velazquez Application Transfer Protocol
+vatp 690/udp #Velazquez Application Transfer Protocol
msexch-routing 691/tcp #MS Exchange Routing
msexch-routing 691/udp #MS Exchange Routing
hyperwave-isp 692/tcp #Hyperwave-ISP
hyperwave-isp 692/udp #Hyperwave-ISP
-connendp 693/tcp
-connendp 693/udp
-ha-cluster 694/tcp
-ha-cluster 694/udp
-ieee-mms-ssl 695/tcp
-ieee-mms-ssl 695/udp
-rushd 696/tcp
-rushd 696/udp
-uuidgen 697/tcp
-uuidgen 697/udp
-olsr 698/tcp
-olsr 698/udp
-accessnetwork 699/tcp #Access Network
-accessnetwork 699/udp #Access Network
-epp 700/tcp #Extensible Provisioning Protocol
-epp 700/udp #Extensible Provisioning Protocol
-lmp 701/tcp #Link Management Protocol (LMP)
-lmp 701/udp #Link Management Protocol (LMP)
-iris-beep 702/tcp #IRIS over BEEP
-iris-beep 702/udp #IRIS over BEEP
+connendp 693/tcp
+connendp 693/udp
+ha-cluster 694/tcp
+ha-cluster 694/udp
+ieee-mms-ssl 695/tcp
+ieee-mms-ssl 695/udp
+rushd 696/tcp
+rushd 696/udp
+uuidgen 697/tcp
+uuidgen 697/udp
+olsr 698/tcp
+olsr 698/udp
+accessnetwork 699/tcp #Access Network
+accessnetwork 699/udp #Access Network
+epp 700/tcp #Extensible Provisioning Protocol
+epp 700/udp #Extensible Provisioning Protocol
+lmp 701/tcp #Link Management Protocol (LMP)
+lmp 701/udp #Link Management Protocol (LMP)
+iris-beep 702/tcp #IRIS over BEEP
+iris-beep 702/udp #IRIS over BEEP
elcsd 704/tcp #errlog copy/server daemon
elcsd 704/udp #errlog copy/server daemon
-agentx 705/tcp #AgentX
-agentx 705/udp #AgentX
-silc 706/tcp
-silc 706/udp
-borland-dsj 707/tcp #Borland DSJ
-borland-dsj 707/udp #Borland DSJ
+agentx 705/tcp #AgentX
+agentx 705/udp #AgentX
+silc 706/tcp
+silc 706/udp
+borland-dsj 707/tcp #Borland DSJ
+borland-dsj 707/udp #Borland DSJ
entrustmanager 709/tcp #EntrustManager
entrustmanager 709/udp #EntrustManager
-entrust-ash 710/tcp #Entrust Administration Service Handler
-entrust-ash 710/udp #Entrust Administration Service Handler
-cisco-tdp 711/tcp #Cisco TDP
-cisco-tdp 711/udp #Cisco TDP
-tbrpf 712/tcp
-tbrpf 712/udp
+entrust-ash 710/tcp #Entrust Administration Service Handler
+entrust-ash 710/udp #Entrust Administration Service Handler
+cisco-tdp 711/tcp #Cisco TDP
+cisco-tdp 711/udp #Cisco TDP
+tbrpf 712/tcp
+tbrpf 712/udp
iris-xpc 713/tcp #IRIS over XPC
iris-xpc 713/udp #IRIS over XPC
iris-xpcs 714/tcp #IRIS over XPCS
@@ -1419,49 +1419,49 @@ fcp-udp 810/udp #FCP Datagram
itm-mcell-s 828/tcp
itm-mcell-s 828/udp
pkix-3-ca-ra 829/tcp #PKIX-3 CA/RA
-pkix-3-ca-ra 829/udp #PKIX-3 CA/RA
-netconf-ssh 830/tcp #NETCONF over SSH
-netconf-ssh 830/udp #NETCONF over SSH
-netconf-beep 831/tcp #NETCONF over BEEP
-netconf-beep 831/udp #NETCONF over BEEP
-netconfsoaphttp 832/tcp #NETCONF for SOAP over HTTPS
-netconfsoaphttp 832/udp #NETCONF for SOAP over HTTPS
-netconfsoapbeep 833/tcp #NETCONF for SOAP over BEEP
-netconfsoapbeep 833/udp #NETCONF for SOAP over BEEP
-dhcp-failover2 847/tcp #dhcp-failover 2
-dhcp-failover2 847/udp #dhcp-failover 2
-gdoi 848/tcp
-gdoi 848/udp
-iscsi 860/tcp
-iscsi 860/udp
-owamp-control 861/tcp
-owamp-control 861/udp
+pkix-3-ca-ra 829/udp #PKIX-3 CA/RA
+netconf-ssh 830/tcp #NETCONF over SSH
+netconf-ssh 830/udp #NETCONF over SSH
+netconf-beep 831/tcp #NETCONF over BEEP
+netconf-beep 831/udp #NETCONF over BEEP
+netconfsoaphttp 832/tcp #NETCONF for SOAP over HTTPS
+netconfsoaphttp 832/udp #NETCONF for SOAP over HTTPS
+netconfsoapbeep 833/tcp #NETCONF for SOAP over BEEP
+netconfsoapbeep 833/udp #NETCONF for SOAP over BEEP
+dhcp-failover2 847/tcp #dhcp-failover 2
+dhcp-failover2 847/udp #dhcp-failover 2
+gdoi 848/tcp
+gdoi 848/udp
+iscsi 860/tcp
+iscsi 860/udp
+owamp-control 861/tcp
+owamp-control 861/udp
supfilesrv 871/tcp # for SUP
rsync 873/tcp
rsync 873/udp
-iclcnet-locate 886/tcp #ICL coNETion locate server
-iclcnet-locate 886/udp #ICL coNETion locate server
-iclcnet_svinfo 887/tcp #ICL coNETion server info
-iclcnet_svinfo 887/udp #ICL coNETion server info
+iclcnet-locate 886/tcp #ICL coNETion locate server
+iclcnet-locate 886/udp #ICL coNETion locate server
+iclcnet_svinfo 887/tcp #ICL coNETion server info
+iclcnet_svinfo 887/udp #ICL coNETion server info
accessbuilder 888/tcp
accessbuilder 888/udp
-omginitialrefs 900/tcp #OMG Initial Refs
-omginitialrefs 900/udp #OMG Initial Refs
+omginitialrefs 900/tcp #OMG Initial Refs
+omginitialrefs 900/udp #OMG Initial Refs
swat 901/tcp # samba web configuration tool
-smpnameres 901/tcp
-smpnameres 901/udp
-ideafarm-chat 902/tcp
-ideafarm-chat 902/udp
-ideafarm-catch 903/tcp
-ideafarm-catch 903/udp
-kink 910/tcp #Kerberized Internet Negotiation of Keys (KINK)
-kink 910/udp #Kerberized Internet Negotiation of Keys (KINK)
-xact-backup 911/tcp
-xact-backup 911/udp
-apex-mesh 912/tcp #APEX relay-relay service
-apex-mesh 912/udp #APEX relay-relay service
-apex-edge 913/tcp #APEX endpoint-relay service
-apex-edge 913/udp #APEX endpoint-relay service
+smpnameres 901/tcp
+smpnameres 901/udp
+ideafarm-chat 902/tcp
+ideafarm-chat 902/udp
+ideafarm-catch 903/tcp
+ideafarm-catch 903/udp
+kink 910/tcp #Kerberized Internet Negotiation of Keys (KINK)
+kink 910/udp #Kerberized Internet Negotiation of Keys (KINK)
+xact-backup 911/tcp
+xact-backup 911/udp
+apex-mesh 912/tcp #APEX relay-relay service
+apex-mesh 912/udp #APEX relay-relay service
+apex-edge 913/tcp #APEX endpoint-relay service
+apex-edge 913/udp #APEX endpoint-relay service
rndc 953/tcp # named's rndc control socket
ftps-data 989/tcp # ftp protocol, data, over TLS/SSL
ftps-data 989/udp
@@ -1491,10 +1491,10 @@ cadlock2 1000/tcp
cadlock2 1000/udp
surf 1010/tcp
surf 1010/udp
-exp1 1021/tcp #RFC3692-style Experiment 1 (*) [RFC4727]
-exp1 1021/udp #RFC3692-style Experiment 1 (*) [RFC4727]
-exp2 1022/tcp #RFC3692-style Experiment 2 (*) [RFC4727]
-exp2 1022/udp #RFC3692-style Experiment 2 (*) [RFC4727]
+exp1 1021/tcp #RFC3692-style Experiment 1 (*) [RFC4727]
+exp1 1021/udp #RFC3692-style Experiment 1 (*) [RFC4727]
+exp2 1022/tcp #RFC3692-style Experiment 2 (*) [RFC4727]
+exp2 1022/udp #RFC3692-style Experiment 2 (*) [RFC4727]
#
# REGISTERED PORT NUMBERS
#
@@ -2399,6 +2399,7 @@ xdsxdm 6558/udp
sane-port 6566/tcp #Scanner Access Now Easy (SANE) Control Port
sane-port 6566/udp #Scanner Access Now Easy (SANE) Control Port
ircd 6667/tcp #Internet Relay Chat (unofficial)
+ircs-u 6697/tcp #Internet Relay Chat over TLS/SSL
frc-hp 6704/sctp #ForCES HP (High Priority) channel
frc-mp 6705/sctp #ForCES MP (Medium Priority) channel
frc-lp 6706/sctp #ForCES LP (Low priority) channel
diff --git a/gnu/usr.bin/Makefile b/gnu/usr.bin/Makefile
index e12a540..1eb57aa 100644
--- a/gnu/usr.bin/Makefile
+++ b/gnu/usr.bin/Makefile
@@ -17,6 +17,8 @@ SUBDIR= ${_binutils} \
${_tests} \
${_texinfo}
+SUBDIR_DEPEND_gdb= ${_binutils}
+
.if ${MK_CXX} != "no"
_gperf= gperf
.if ${MK_GROFF} != "no"
diff --git a/include/netdb.h b/include/netdb.h
index 9ed6e61..a73d2af 100644
--- a/include/netdb.h
+++ b/include/netdb.h
@@ -122,7 +122,7 @@ struct protoent {
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
- int ai_family; /* PF_xxx */
+ int ai_family; /* AF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
socklen_t ai_addrlen; /* length of ai_addr */
@@ -179,7 +179,7 @@ struct addrinfo {
/* valid flags for addrinfo (not a standard def, apps should not use it) */
#define AI_MASK \
(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | \
- AI_ADDRCONFIG)
+ AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED)
#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
diff --git a/lib/libc/gen/lockf.c b/lib/libc/gen/lockf.c
index 2c567ba..c64a347 100644
--- a/lib/libc/gen/lockf.c
+++ b/lib/libc/gen/lockf.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <fcntl.h>
#include <unistd.h>
#include "un-namespace.h"
+#include "libc_private.h"
int
lockf(int filedes, int function, off_t size)
@@ -62,9 +63,12 @@ lockf(int filedes, int function, off_t size)
break;
case F_TEST:
fl.l_type = F_WRLCK;
- if (_fcntl(filedes, F_GETLK, &fl) == -1)
+ if (((int (*)(int, int, ...))
+ __libc_interposing[INTERPOS_fcntl])(filedes, F_GETLK, &fl)
+ == -1)
return (-1);
- if (fl.l_type == F_UNLCK || (fl.l_sysid == 0 && fl.l_pid == getpid()))
+ if (fl.l_type == F_UNLCK || (fl.l_sysid == 0 &&
+ fl.l_pid == getpid()))
return (0);
errno = EAGAIN;
return (-1);
@@ -75,5 +79,6 @@ lockf(int filedes, int function, off_t size)
/* NOTREACHED */
}
- return (_fcntl(filedes, cmd, &fl));
+ return (((int (*)(int, int, ...))
+ __libc_interposing[INTERPOS_fcntl])(filedes, cmd, &fl));
}
diff --git a/lib/libc/net/getaddrinfo.3 b/lib/libc/net/getaddrinfo.3
index 07fefc0..a8f8c25 100644
--- a/lib/libc/net/getaddrinfo.3
+++ b/lib/libc/net/getaddrinfo.3
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 5, 2015
+.Dd December 21, 2015
.Dt GETADDRINFO 3
.Os
.Sh NAME
@@ -78,7 +78,7 @@ as defined by
.Bd -literal
struct addrinfo {
int ai_flags; /* input flags */
- int ai_family; /* protocol family for socket */
+ int ai_family; /* address family for socket */
int ai_socktype; /* socket type */
int ai_protocol; /* protocol for socket */
socklen_t ai_addrlen; /* length of socket-address */
@@ -94,12 +94,12 @@ The caller can supply the following structure elements in
.Fa hints :
.Bl -tag -width "ai_socktypeXX"
.It Fa ai_family
-The protocol family that should be used.
+The address family that should be used.
When
.Fa ai_family
is set to
-.Dv PF_UNSPEC ,
-it means the caller will accept any protocol family supported by the
+.Dv AF_UNSPEC ,
+it means the caller will accept any address family supported by the
operating system.
.It Fa ai_socktype
Denotes the type of socket that is wanted:
@@ -126,11 +126,13 @@ field to which the
parameter points shall be set to zero
or be the bitwise-inclusive OR of one or more of the values
.Dv AI_ADDRCONFIG ,
+.Dv AI_ALL ,
.Dv AI_CANONNAME ,
.Dv AI_NUMERICHOST ,
-.Dv AI_NUMERICSERV
+.Dv AI_NUMERICSERV ,
+.Dv AI_PASSIVE
and
-.Dv AI_PASSIVE .
+.Dv AI_V4MAPPED .
.Bl -tag -width "AI_CANONNAMEXX"
.It Dv AI_ADDRCONFIG
If the
@@ -139,6 +141,25 @@ bit is set, IPv4 addresses shall be returned only if
an IPv4 address is configured on the local system,
and IPv6 addresses shall be returned only if
an IPv6 address is configured on the local system.
+.It Dv AI_ALL
+If the
+.Dv AI_ALL
+flag is used with the
+.Dv AI_V4MAPPED
+flag, then
+.Fn getaddrinfo
+shall return all matching IPv6 and IPv4 addresses.
+.Pp
+For example, when using the DNS, queries are made for both AAAA records and A records, and
+.Fn getaddrinfo
+returns the combined results of both queries.
+Any IPv4 addresses found are returned as IPv4-mapped IPv6 addresses.
+.Pp
+The
+.Dv AI_ALL
+flag without the
+.Dv AI_V4MAPPED
+flag is ignored.
.It Dv AI_CANONNAME
If the
.Dv AI_CANONNAME
@@ -203,6 +224,25 @@ loopback address if
is the null pointer and
.Dv AI_PASSIVE
is not set.
+.It Dv AI_V4MAPPED
+If the
+.Dv AI_V4MAPPED
+flag is specified along with an ai_family of
+.Dv AF_INET6 ,
+then
+.Fn getaddrinfo
+shall return IPv4-mapped IPv6 addresses on finding no matching IPv6 addresses (
+.Fa ai_addrlen
+shall be 16).
+.Pp
+For example, when using the DNS, if no AAAA records are found then a query is made for A records and any found are returned as IPv4-mapped IPv6 addresses.
+.Pp
+The
+.Dv AI_V4MAPPED
+flag shall be ignored unless
+.Fa ai_family
+equals
+.Dv AF_INET6 .
.El
.El
.Pp
@@ -221,7 +261,7 @@ behaves as if the caller provided a
with
.Fa ai_family
set to
-.Dv PF_UNSPEC
+.Dv AF_UNSPEC
and all other elements set to zero or
.Dv NULL .
.Pp
@@ -333,7 +373,7 @@ int s;
const char *cause = NULL;
memset(&hints, 0, sizeof(hints));
-hints.ai_family = PF_UNSPEC;
+hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("www.kame.net", "http", &hints, &res0);
if (error) {
@@ -376,7 +416,7 @@ int nsock;
const char *cause = NULL;
memset(&hints, 0, sizeof(hints));
-hints.ai_family = PF_UNSPEC;
+hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
error = getaddrinfo(NULL, "http", &hints, &res0);
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c
index 9bc2c9b..54ac329 100644
--- a/lib/libc/net/getaddrinfo.c
+++ b/lib/libc/net/getaddrinfo.c
@@ -96,6 +96,7 @@ __FBSDID("$FreeBSD$");
#include <stdarg.h>
#include <nsswitch.h>
#include "un-namespace.h"
+#include "netdb_private.h"
#include "libc_private.h"
#ifdef NS_CACHING
#include "nscache.h"
@@ -451,6 +452,24 @@ getaddrinfo(const char *hostname, const char *servname,
}
/*
+ * RFC 3493: AI_ALL and AI_V4MAPPED are effective only against
+ * AF_INET6 query. They need to be ignored if specified in other
+ * occassions.
+ */
+ switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) {
+ case AI_V4MAPPED:
+ case AI_ALL | AI_V4MAPPED:
+#ifdef INET6
+ if (pai->ai_family != AF_INET6)
+ pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
+ break;
+#endif
+ case AI_ALL:
+ pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
+ break;
+ }
+
+ /*
* check for special cases. (1) numeric servname is disallowed if
* socktype/protocol are left unspecified. (2) servname is disallowed
* for raw and other inet{,6} sockets.
@@ -759,10 +778,9 @@ match_addrselectpolicy(struct sockaddr *addr, struct policyhead *head)
memset(&key, 0, sizeof(key));
key.sin6_family = AF_INET6;
key.sin6_len = sizeof(key);
- key.sin6_addr.s6_addr[10] = 0xff;
- key.sin6_addr.s6_addr[11] = 0xff;
- memcpy(&key.sin6_addr.s6_addr[12],
- &((struct sockaddr_in *)addr)->sin_addr, 4);
+ _map_v4v6_address(
+ (char *)&((struct sockaddr_in *)addr)->sin_addr,
+ (char *)&key.sin6_addr);
break;
default:
return(NULL);
@@ -842,6 +860,16 @@ set_source(struct ai_order *aio, struct policyhead *ph)
if ((s = _socket(ai.ai_family, ai.ai_socktype | SOCK_CLOEXEC,
ai.ai_protocol)) < 0)
return; /* give up */
+#ifdef INET6
+ if (ai.ai_family == AF_INET6) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai.ai_addr;
+ int off = 0;
+
+ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
+ (void)_setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
+ (char *)&off, sizeof(off));
+ }
+#endif
if (_connect(s, ai.ai_addr, ai.ai_addrlen) < 0)
goto cleanup;
srclen = ai.ai_addrlen;
@@ -1177,7 +1205,7 @@ explore_numeric(const struct addrinfo *pai, const char *hostname,
const char *servname, struct addrinfo **res, const char *canonname)
{
const struct afd *afd;
- struct addrinfo *ai;
+ struct addrinfo *ai, ai0;
int error;
char pton[PTON_MAX];
@@ -1201,8 +1229,17 @@ explore_numeric(const struct addrinfo *pai, const char *hostname,
return 0;
break;
default:
- if (inet_pton(afd->a_af, hostname, pton) != 1)
- return 0;
+ if (inet_pton(afd->a_af, hostname, pton) != 1) {
+ if (pai->ai_family != AF_INET6 ||
+ (pai->ai_flags & AI_V4MAPPED) != AI_V4MAPPED)
+ return 0;
+ if (inet_aton(hostname, (struct in_addr *)pton) != 1)
+ return 0;
+ afd = &afdl[N_INET];
+ ai0 = *pai;
+ ai0.ai_family = AF_INET;
+ pai = &ai0;
+ }
break;
}
@@ -1321,6 +1358,9 @@ get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
char *fp_str;
int translate = 0;
#endif
+#ifdef INET6
+ struct in6_addr mapaddr;
+#endif
#ifdef FAITH
/*
@@ -1358,6 +1398,14 @@ get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
}
#endif
+#ifdef INET6
+ if (afd->a_af == AF_INET && (pai->ai_flags & AI_V4MAPPED) != 0) {
+ afd = &afdl[N_INET6];
+ _map_v4v6_address(addr, (char *)&mapaddr);
+ addr = (char *)&mapaddr;
+ }
+#endif
+
ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
+ (afd->a_socklen));
if (ai == NULL)
@@ -2117,7 +2165,11 @@ getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
return sentinel.ai_next;
}
- RES_SET_H_ERRNO(res, NO_RECOVERY);
+ /*
+ * We could have walked a CNAME chain, but the ultimate target
+ * may not have what we looked for.
+ */
+ RES_SET_H_ERRNO(res, ntohs(hp->ancount) > 0 ? NO_DATA : NO_RECOVERY);
return NULL;
}
@@ -2191,7 +2243,7 @@ addr4sort(struct addrinfo *sentinel, res_state res)
static int
_dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
{
- struct addrinfo *ai;
+ struct addrinfo *ai, ai0;
querybuf *buf, *buf2;
const char *hostname;
const struct addrinfo *pai;
@@ -2221,6 +2273,13 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
return NS_NOTFOUND;
}
+ if (pai->ai_family == AF_INET6 &&
+ (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED) {
+ ai0 = *pai;
+ ai0.ai_family = AF_UNSPEC;
+ pai = &ai0;
+ }
+
switch (pai->ai_family) {
case AF_UNSPEC:
q.name = hostname;
@@ -2276,14 +2335,18 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
cur = cur->ai_next;
}
}
- ai = getanswer(buf, q.n, q.name, q.qtype, pai, res);
- if (ai)
- cur->ai_next = ai;
+ if (!ai || pai->ai_family != AF_UNSPEC ||
+ (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) != AI_V4MAPPED) {
+ ai = getanswer(buf, q.n, q.name, q.qtype, pai, res);
+ if (ai)
+ cur->ai_next = ai;
+ }
free(buf);
free(buf2);
if (sentinel.ai_next == NULL)
switch (res->res_h_errno) {
case HOST_NOT_FOUND:
+ case NO_DATA:
return NS_NOTFOUND;
case TRY_AGAIN:
return NS_TRYAGAIN;
@@ -2360,6 +2423,9 @@ found:
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_NUMERICHOST;
+ if (pai->ai_family == AF_INET6 &&
+ (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED)
+ hints.ai_flags |= AI_V4MAPPED;
error = getaddrinfo(addr, "0", &hints, &res0);
if (error)
goto again;
@@ -2387,6 +2453,20 @@ found:
return res0;
}
+static struct addrinfo *
+_getht(FILE **hostf, const char *name, const struct addrinfo *pai,
+ struct addrinfo *cur)
+{
+ struct addrinfo *p;
+
+ while ((p = _gethtent(hostf, name, pai)) != NULL) {
+ cur->ai_next = p;
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ }
+ return (cur);
+}
+
/*ARGSUSED*/
static int
_files_getaddrinfo(void *rv, void *cb_data, va_list ap)
@@ -2394,7 +2474,6 @@ _files_getaddrinfo(void *rv, void *cb_data, va_list ap)
const char *name;
const struct addrinfo *pai;
struct addrinfo sentinel, *cur;
- struct addrinfo *p;
FILE *hostf = NULL;
name = va_arg(ap, char *);
@@ -2404,11 +2483,19 @@ _files_getaddrinfo(void *rv, void *cb_data, va_list ap)
cur = &sentinel;
_sethtent(&hostf);
- while ((p = _gethtent(&hostf, name, pai)) != NULL) {
- cur->ai_next = p;
- while (cur && cur->ai_next)
- cur = cur->ai_next;
- }
+ if (pai->ai_family == AF_INET6 &&
+ (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) == AI_V4MAPPED) {
+ struct addrinfo ai0 = *pai;
+
+ ai0.ai_flags &= ~AI_V4MAPPED;
+ cur = _getht(&hostf, name, &ai0, cur);
+ if (sentinel.ai_next == NULL) {
+ _sethtent(&hostf);
+ ai0.ai_flags |= AI_V4MAPPED;
+ cur = _getht(&hostf, name, &ai0, cur);
+ }
+ } else
+ cur = _getht(&hostf, name, pai, cur);
_endhtent(&hostf);
*((struct addrinfo **)rv) = sentinel.ai_next;
@@ -2468,6 +2555,9 @@ nextline:
hints = *pai;
hints.ai_flags = AI_NUMERICHOST;
+ if (pai->ai_family == AF_INET6 &&
+ (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED)
+ hints.ai_flags |= AI_V4MAPPED;
error = getaddrinfo(addr, NULL, &hints, &res0);
if (error == 0) {
for (res = res0; res; res = res->ai_next) {
@@ -2515,15 +2605,46 @@ _yp_getaddrinfo(void *rv, void *cb_data, va_list ap)
memset(&sentinel, 0, sizeof(sentinel));
cur = &sentinel;
+ /* ipnodes.byname can hold both IPv4/v6 */
+ r = yp_match(ypdomain, "ipnodes.byname", name,
+ (int)strlen(name), &ypbuf, &ypbuflen);
+ if (r == 0) {
+ ai = _yphostent(ypbuf, pai);
+ if (ai) {
+ cur->ai_next = ai;
+ while (cur && cur->ai_next)
+ cur = cur->ai_next;
+ }
+ free(ypbuf);
+ }
+
+ if (ai != NULL) {
+ struct sockaddr_in6 *sin6;
+
+ switch (ai->ai_family) {
+ case AF_INET:
+ goto done;
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)ai->ai_addr;
+ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
+ goto done;
+ break;
+ }
+ }
+
/* hosts.byname is only for IPv4 (Solaris8) */
- if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) {
+ if (pai->ai_family == AF_UNSPEC || pai->ai_family == AF_INET ||
+ ((pai->ai_family == AF_INET6 &&
+ (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED) &&
+ (ai == NULL || (pai->ai_flags & AI_ALL) == AI_ALL))) {
r = yp_match(ypdomain, "hosts.byname", name,
(int)strlen(name), &ypbuf, &ypbuflen);
if (r == 0) {
struct addrinfo ai4;
ai4 = *pai;
- ai4.ai_family = AF_INET;
+ if (pai->ai_family == AF_UNSPEC)
+ ai4.ai_family = AF_INET;
ai = _yphostent(ypbuf, &ai4);
if (ai) {
cur->ai_next = ai;
@@ -2534,16 +2655,7 @@ _yp_getaddrinfo(void *rv, void *cb_data, va_list ap)
}
}
- /* ipnodes.byname can hold both IPv4/v6 */
- r = yp_match(ypdomain, "ipnodes.byname", name,
- (int)strlen(name), &ypbuf, &ypbuflen);
- if (r == 0) {
- ai = _yphostent(ypbuf, pai);
- if (ai)
- cur->ai_next = ai;
- free(ypbuf);
- }
-
+done:
if (sentinel.ai_next == NULL) {
RES_SET_H_ERRNO(__res_state(), HOST_NOT_FOUND);
return NS_NOTFOUND;
diff --git a/lib/libc/net/name6.c b/lib/libc/net/name6.c
index 97880a2..74d7380 100644
--- a/lib/libc/net/name6.c
+++ b/lib/libc/net/name6.c
@@ -795,10 +795,9 @@ match_addrselectpolicy(struct sockaddr *addr, struct policyhead *head)
memset(&key, 0, sizeof(key));
key.sin6_family = AF_INET6;
key.sin6_len = sizeof(key);
- key.sin6_addr.s6_addr[10] = 0xff;
- key.sin6_addr.s6_addr[11] = 0xff;
- memcpy(&key.sin6_addr.s6_addr[12],
- &((struct sockaddr_in *)addr)->sin_addr, 4);
+ _map_v4v6_address(
+ (char *)&((struct sockaddr_in *)addr)->sin_addr,
+ (char *)&key.sin6_addr);
break;
default:
return(NULL);
diff --git a/lib/libc/sys/clock_gettime.2 b/lib/libc/sys/clock_gettime.2
index 583cc8f..b42432f 100644
--- a/lib/libc/sys/clock_gettime.2
+++ b/lib/libc/sys/clock_gettime.2
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 29, 2009
+.Dd December 20, 2015
.Dt CLOCK_GETTIME 2
.Os
.Sh NAME
@@ -136,10 +136,6 @@ The
.Fa clock_id
argument
was not a valid value.
-.It Bq Er EFAULT
-The
-.Fa *tp
-argument address referenced invalid memory.
.It Bq Er EPERM
A user other than the super-user attempted to set the time.
.El
diff --git a/lib/libc/sys/gettimeofday.2 b/lib/libc/sys/gettimeofday.2
index 23cc059..888cbcd 100644
--- a/lib/libc/sys/gettimeofday.2
+++ b/lib/libc/sys/gettimeofday.2
@@ -28,7 +28,7 @@
.\" @(#)gettimeofday.2 8.2 (Berkeley) 5/26/95
.\" $FreeBSD$
.\"
-.Dd May 26, 1995
+.Dd December 20, 2015
.Dt GETTIMEOFDAY 2
.Os
.Sh NAME
@@ -110,8 +110,6 @@ system call even when the system is secure.
The following error codes may be set in
.Va errno :
.Bl -tag -width Er
-.It Bq Er EFAULT
-An argument address referenced invalid memory.
.It Bq Er EPERM
A user other than the super-user attempted to set the time.
.El
diff --git a/lib/liblzma/Makefile b/lib/liblzma/Makefile
index c7f2172..c78933a 100644
--- a/lib/liblzma/Makefile
+++ b/lib/liblzma/Makefile
@@ -155,12 +155,13 @@ CFLAGS+= -DSYMBOL_VERSIONING
CLEANFILES+= liblzma.pc
+.if !defined(LIBRARIES_ONLY)
all: liblzma.pc
liblzma.pc: liblzma.pc.in
@sed -e 's,@prefix@,/usr,g ; \
s,@exec_prefix@,/usr,g ; \
- s,@libdir@,${LIBDIR},g ; \
- s,@includedir@,${INCLUDEDIR},g ; \
+ s,@libdir@,/usr/lib,g ; \
+ s,@includedir@,/usr/include,g ; \
s,@PACKAGE_URL@,http://tukaani.org/xz/,g ; \
s,@PACKAGE_VERSION@,${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH},g ; \
s,@PTHREAD_CFLAGS@,,g ; \
@@ -169,5 +170,6 @@ liblzma.pc: liblzma.pc.in
beforeinstall:
@${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
liblzma.pc ${DESTDIR}${LIBDATADIR}/pkgconfig
+.endif
.include <bsd.lib.mk>
diff --git a/share/examples/tests/tests/atf/printf_test.c b/share/examples/tests/tests/atf/printf_test.c
index 04a5665..719927c 100644
--- a/share/examples/tests/tests/atf/printf_test.c
+++ b/share/examples/tests/tests/atf/printf_test.c
@@ -152,4 +152,6 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, snprintf__two_formatters);
ATF_TP_ADD_TC(tp, snprintf__overflow);
ATF_TP_ADD_TC(tp, fprintf__simple_string);
+
+ return (atf_no_error());
}
diff --git a/share/man/man4/isp.4 b/share/man/man4/isp.4
index 71050a2..da6b776 100644
--- a/share/man/man4/isp.4
+++ b/share/man/man4/isp.4
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 22, 2015
+.Dd December 9, 2015
.Dt ISP 4
.Os
.Sh NAME
@@ -107,10 +107,12 @@ Optical 2Gb Fibre Channel PCIe cards.
Dell branded version of the QLogic 2312.
.It Qlogic 2422
Optical 4Gb Fibre Channel PCI cards.
-.It Qlogic 2432
+.It Qlogic 246x (aka 2432)
Optical 4Gb Fibre Channel PCIe cards.
-.It Qlogic 2532
+.It Qlogic 256x (aka 2532)
Optical 8Gb Fibre Channel PCIe cards.
+.It Qlogic 267x/836x (aka 2031/8031)
+Optical 16Gb FC/FCoE PCIe cards.
.El
.Sh CONFIGURATION OPTIONS
Target mode support for Fibre Channel adapters may be enabled with the
@@ -127,12 +129,6 @@ They are:
.It Va hint.isp.0.fwload_disable
A hint value to disable loading of firmware
.Xr ispfw 4 .
-.It Va hint.isp.0.prefer_memmap
-A hint value to use PCI memory space instead of I/O space
-access for.
-.It Va hint.isp.0.prefer_iomap
-A hint value to use PCI I/O space instead of Memory space
-access for.
.It Va hint.isp.0.ignore_nvram
A hint value to ignore board NVRAM settings for.
Otherwise use NVRAM settings.
diff --git a/share/mk/bsd.README b/share/mk/bsd.README
index 179bcba..89f5f7e 100644
--- a/share/mk/bsd.README
+++ b/share/mk/bsd.README
@@ -442,6 +442,10 @@ KYUAFILE If 'auto' (the default), generate a Kyuafile out of the
subdirectories providing helper programs or data files
only).
+LOCALBASE The --prefix for the kyua package.
+
+ The value of LOCALBASE defaults to /usr/local .
+
ATF_TESTS_C The names of the ATF C test programs to build.
ATF_TESTS_CXX The names of the ATF C++ test programs to build.
diff --git a/share/mk/bsd.test.mk b/share/mk/bsd.test.mk
index 6f20d3d..3d57506 100644
--- a/share/mk/bsd.test.mk
+++ b/share/mk/bsd.test.mk
@@ -10,6 +10,9 @@
__<bsd.test.mk>__:
+# Third-party software (kyua, etc) prefix.
+LOCALBASE?= /usr/local
+
# Tests install directory
TESTSDIR?= ${TESTSBASE}/${RELDIR:H}
diff --git a/share/mk/suite.test.mk b/share/mk/suite.test.mk
index 0ec905d..0d48950 100644
--- a/share/mk/suite.test.mk
+++ b/share/mk/suite.test.mk
@@ -38,27 +38,17 @@ KYUAFILE?= auto
# Makefile to rely on the KYUAFILE=auto behavior defined here.
#TEST_METADATA.<test-program>+= key="value"
-# Path to the prefix of the installed Kyua CLI, if any.
-#
-# If kyua is installed from ports, we automatically define a realtest target
-# below to run the tests using this tool. The tools are searched for in the
-# hierarchy specified by this variable.
-KYUA_PREFIX?= /usr/local
-
-.if ${KYUAFILE:tl} == "yes"
+.if ${KYUAFILE:tl} != "no"
FILES+= Kyuafile
FILESDIR_Kyuafile= ${TESTSDIR}
+.endif
-CLEANFILES+= Kyuafile.auto Kyuafile.auto.tmp
-.elif ${KYUAFILE:tl} == "auto"
-FILES+= Kyuafile.auto
-FILESDIR_Kyuafile.auto= ${TESTSDIR}
-FILESNAME_Kyuafile.auto= Kyuafile
-
-CLEANFILES+= Kyuafile.auto Kyuafile.auto.tmp
+.if ${KYUAFILE:tl} == "auto"
+CLEANFILES+= Kyuafile Kyuafile.tmp
+.endif
-.NOPATH: Kyuafile.auto
-Kyuafile.auto: Makefile
+.if ${KYUAFILE:tl} == "auto"
+Kyuafile: Makefile
@{ \
echo '-- Automatically generated by bsd.test.mk.'; \
echo; \
@@ -66,23 +56,23 @@ Kyuafile.auto: Makefile
echo; \
echo 'test_suite("${TESTSUITE}")'; \
echo; \
- } >Kyuafile.auto.tmp
+ } > ${.TARGET}.tmp
.for _T in ${_TESTS}
.if defined(.PARSEDIR)
@echo '${TEST_INTERFACE.${_T}}_test_program{name="${_T}"${TEST_METADATA.${_T}:C/$/,/:tW:C/^/, /W:C/,$//W}}' \
- >>Kyuafile.auto.tmp
+ >>${.TARGET}.tmp
.else
@echo '${TEST_INTERFACE.${_T}}_test_program{name="${_T}"${TEST_METADATA.${_T}:C/^/, /:Q:S/\\ ,/,/g:S,\\,,g}}' \
>>Kyuafile.auto.tmp
.endif
.endfor
.for _T in ${TESTS_SUBDIRS:N.WAIT}
- @echo "include(\"${_T}/Kyuafile\")" >>Kyuafile.auto.tmp
+ @echo "include(\"${_T}/${.TARGET}\")" >>${.TARGET}.tmp
.endfor
- @mv Kyuafile.auto.tmp Kyuafile.auto
+ @mv ${.TARGET}.tmp ${.TARGET}
.endif
-KYUA?= ${KYUA_PREFIX}/bin/kyua
+KYUA= ${LOCALBASE}/bin/kyua
.if exists(${KYUA})
# Definition of the "make test" target and supporting variables.
#
diff --git a/share/mk/tap.test.mk b/share/mk/tap.test.mk
index ec86088..28b52af 100644
--- a/share/mk/tap.test.mk
+++ b/share/mk/tap.test.mk
@@ -26,7 +26,7 @@ TAP_TESTS_PERL?=
TAP_TESTS_SH?=
# Perl interpreter to use for test programs written in this language.
-TAP_PERL_INTERPRETER?= /usr/local/bin/perl
+TAP_PERL_INTERPRETER?= ${LOCALBASE}/bin/perl
.if !empty(TAP_TESTS_C)
PROGS+= ${TAP_TESTS_C}
diff --git a/sys/conf/files b/sys/conf/files
index f6456a7..ec77e97 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2258,6 +2258,7 @@ dev/random/hash.c optional random
dev/random/rwfile.c optional random
dev/rc/rc.c optional rc
dev/re/if_re.c optional re
+dev/rl/if_rl.c optional rl pci
dev/rndtest/rndtest.c optional rndtest
dev/rp/rp.c optional rp
dev/rp/rp_isa.c optional rp isa
@@ -3552,6 +3553,7 @@ netinet/sctp_usrreq.c optional inet sctp | inet6 sctp
netinet/sctputil.c optional inet sctp | inet6 sctp
netinet/siftr.c optional inet siftr alq | inet6 siftr alq
netinet/tcp_debug.c optional tcpdebug
+netinet/tcp_fastopen.c optional inet tcp_rfc7413 | inet6 tcp_rfc7413
netinet/tcp_hostcache.c optional inet | inet6
netinet/tcp_input.c optional inet | inet6
netinet/tcp_lro.c optional inet | inet6
@@ -4046,7 +4048,6 @@ opencrypto/xform.c optional crypto
pci/alpm.c optional alpm pci
pci/amdpm.c optional amdpm pci | nfpm pci
pci/amdsmb.c optional amdsmb pci
-pci/if_rl.c optional rl pci
pci/intpm.c optional intpm pci
pci/ncr.c optional ncr pci \
compile-with "${NORMAL_C} -Wno-unused"
diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64
index 5775d9b..9fbc226 100644
--- a/sys/conf/files.sparc64
+++ b/sys/conf/files.sparc64
@@ -81,6 +81,7 @@ sparc64/isa/isa_dma.c optional isa
sparc64/isa/ofw_isa.c optional ebus | isa
sparc64/pci/apb.c optional pci
sparc64/pci/fire.c optional pci
+sparc64/pci/ofw_pci.c optional pci
sparc64/pci/ofw_pcib.c optional pci
sparc64/pci/ofw_pcib_subr.c optional pci
sparc64/pci/ofw_pcibus.c optional pci
diff --git a/sys/conf/options b/sys/conf/options
index 96253be..d8dffe9 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -444,6 +444,8 @@ SLIP_IFF_OPTS opt_slip.h
TCPDEBUG
SIFTR
TCP_OFFLOAD opt_inet.h # Enable code to dispatch TCP offloading
+TCP_RFC7413 opt_inet.h
+TCP_RFC7413_MAX_KEYS opt_inet.h
TCP_SIGNATURE opt_inet.h
VLAN_ARRAY opt_vlan.h
XBONEHACK
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index 6c93810..6ca938a 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -5123,7 +5123,7 @@ ipf_nat_out(fin, nat, natadd, nflags)
ipf_fix_outcksum(0, &fin->fin_ip->ip_sum, msumd, 0);
}
#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \
- defined(linux) || defined(BRIDGE_IPF)
+ defined(linux) || defined(BRIDGE_IPF) || defined(__FreeBSD__)
else {
/*
* Strictly speaking, this isn't necessary on BSD
@@ -5235,7 +5235,7 @@ ipf_nat_out(fin, nat, natadd, nflags)
uh->uh_ulen += fin->fin_plen;
uh->uh_ulen = htons(uh->uh_ulen);
#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \
- defined(linux) || defined(BRIDGE_IPF)
+ defined(linux) || defined(BRIDGE_IPF) || defined(__FreeBSD)
ipf_fix_outcksum(0, &ip->ip_sum, sumd, 0);
#endif
diff --git a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
index d13ece5..d17d696 100644
--- a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
+++ b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
@@ -53,8 +53,6 @@ static void vmbus_channel_on_gpadl_torndown(hv_vmbus_channel_msg_header* hdr);
static void vmbus_channel_on_offers_delivered(hv_vmbus_channel_msg_header* hdr);
static void vmbus_channel_on_version_response(hv_vmbus_channel_msg_header* hdr);
static void vmbus_channel_process_offer(void *context);
-struct hv_vmbus_channel*
- vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary);
/**
* Channel message dispatch table
diff --git a/sys/dev/if_ndis/if_ndis_pci.c b/sys/dev/if_ndis/if_ndis_pci.c
index 8ed6c5a..326e3de 100644
--- a/sys/dev/if_ndis/if_ndis_pci.c
+++ b/sys/dev/if_ndis/if_ndis_pci.c
@@ -295,8 +295,7 @@ ndis_attach_pci(dev)
BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
- BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
- NDIS_NSEG_NEW, /* nsegments */
+ DFLTPHYS, NDIS_NSEG_NEW,/* maxsize, nsegments */
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
BUS_DMA_ALLOCNOW, /* flags */
NULL, NULL, /* lockfunc, lockarg */
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 18c41e9..d394011 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -277,6 +277,9 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
case ISP_HA_FC_2500:
btype = "2532";
break;
+ case ISP_HA_FC_2600:
+ btype = "2031";
+ break;
default:
break;
}
@@ -655,8 +658,10 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
ISP_WRITE(isp, isp->isp_respinrp, 0);
ISP_WRITE(isp, isp->isp_respoutrp, 0);
if (IS_24XX(isp)) {
- ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
- ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
+ if (!IS_26XX(isp)) {
+ ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
+ ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
+ }
ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
}
@@ -761,6 +766,7 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
code_org = ISP_CODE_ORG;
}
+ isp->isp_loaded_fw = 0;
if (dodnld && IS_24XX(isp)) {
const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
int wordload;
@@ -956,8 +962,17 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
ISP_RESET0(isp);
return;
}
+ } else if (IS_26XX(isp)) {
+ MBSINIT(&mbs, MBOX_LOAD_FLASH_FIRMWARE, MBLOGALL, 5000000);
+ mbs.ibitm = 0x01;
+ mbs.obitm = 0x07;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR, "Flash F/W load failed");
+ ISP_RESET0(isp);
+ return;
+ }
} else {
- isp->isp_loaded_fw = 0;
isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
}
@@ -966,7 +981,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
*/
if (isp->isp_loaded_fw) {
MBSINIT(&mbs, MBOX_VERIFY_CHECKSUM, MBLOGNONE, 0);
- mbs.param[0] = MBOX_VERIFY_CHECKSUM;
if (IS_24XX(isp)) {
mbs.param[1] = code_org >> 16;
mbs.param[2] = code_org;
@@ -998,9 +1012,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
} else {
mbs.param[3] = 1;
}
- if (IS_25XX(isp)) {
- mbs.ibits |= 0x10;
- }
} else if (IS_2322(isp)) {
mbs.param[1] = code_org;
if (isp->isp_loaded_fw) {
@@ -1861,16 +1872,16 @@ isp_fibre_init(ispsoftc_t *isp)
icbp->icb_idelaytimer = 10;
}
icbp->icb_zfwoptions = fcp->isp_zfwoptions;
- if (isp->isp_confopts & ISP_CFG_ONEGB) {
+ if (isp->isp_confopts & ISP_CFG_1GB) {
icbp->icb_zfwoptions &= ~ICBZOPT_RATE_MASK;
- icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
- } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
+ icbp->icb_zfwoptions |= ICBZOPT_RATE_1GB;
+ } else if (isp->isp_confopts & ISP_CFG_2GB) {
icbp->icb_zfwoptions &= ~ICBZOPT_RATE_MASK;
- icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
+ icbp->icb_zfwoptions |= ICBZOPT_RATE_2GB;
} else {
switch (icbp->icb_zfwoptions & ICBZOPT_RATE_MASK) {
- case ICBZOPT_RATE_ONEGB:
- case ICBZOPT_RATE_TWOGB:
+ case ICBZOPT_RATE_1GB:
+ case ICBZOPT_RATE_2GB:
case ICBZOPT_RATE_AUTO:
break;
default:
@@ -2122,18 +2133,26 @@ isp_fibre_init_2400(ispsoftc_t *isp)
break;
}
+ if (IS_26XX(isp)) {
+ /* We don't support MSI-X yet, so set this unconditionally. */
+ icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHR;
+ icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHA;
+ }
+
if ((icbp->icb_fwoptions3 & ICB2400_OPT3_RSPSZ_MASK) == 0) {
icbp->icb_fwoptions3 |= ICB2400_OPT3_RSPSZ_24;
}
icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
- if (isp->isp_confopts & ISP_CFG_ONEGB) {
- icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB;
- } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
- icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB;
- } else if (isp->isp_confopts & ISP_CFG_FOURGB) {
- icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB;
- } else if (IS_25XX(isp) && (isp->isp_confopts & ISP_CFG_EIGHTGB)) {
- icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_EIGHTGB;
+ if (isp->isp_confopts & ISP_CFG_1GB) {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_1GB;
+ } else if (isp->isp_confopts & ISP_CFG_2GB) {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_2GB;
+ } else if (isp->isp_confopts & ISP_CFG_4GB) {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_4GB;
+ } else if (isp->isp_confopts & ISP_CFG_8GB) {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_8GB;
+ } else if (isp->isp_confopts & ISP_CFG_16GB) {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_16GB;
} else {
icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
}
@@ -6828,7 +6847,7 @@ static const char *scsi_mbcmd_names[] = {
static const uint32_t mbpfc[] = {
ISP_FC_OPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
ISP_FC_OPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
- ISP_FC_OPMAP(0x0f, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
+ ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x03), /* 0x02: MBOX_EXEC_FIRMWARE */
ISP_FC_OPMAP(0xdf, 0x01), /* 0x03: MBOX_DUMP_RAM */
ISP_FC_OPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
ISP_FC_OPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
@@ -7602,6 +7621,8 @@ isp_setdfltfcparm(ispsoftc_t *isp, int chan)
fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
fcp->isp_fwoptions = 0;
+ fcp->isp_xfwoptions = 0;
+ fcp->isp_zfwoptions = 0;
fcp->isp_lasthdl = NIL_HANDLE;
if (IS_24XX(isp)) {
@@ -7899,7 +7920,9 @@ isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
uint32_t base = 0x7ffe0000;
uint32_t tmp = 0;
- if (IS_25XX(isp)) {
+ if (IS_26XX(isp)) {
+ base = 0x7fe7c000; /* XXX: Observation, may be wrong. */
+ } else if (IS_25XX(isp)) {
base = 0x7ff00000 | 0x48000;
}
ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 73741eb..c533d69 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -4550,91 +4550,52 @@ isp_uninit(ispsoftc_t *isp)
ISP_DISABLE_INTS(isp);
}
-/*
- * When we want to get the 'default' WWNs (when lacking NVRAM), we pick them
- * up from our platform default (defww{p|n}n) and morph them based upon
- * channel.
- *
- * When we want to get the 'active' WWNs, we get NVRAM WWNs and then morph them
- * based upon channel.
- */
-
uint64_t
isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn)
{
uint64_t seed;
struct isp_fc *fc = ISP_FC_PC(isp, chan);
- /*
- * If we're asking for a active WWN, the default overrides get
- * returned, otherwise the NVRAM value is picked.
- *
- * If we're asking for a default WWN, we just pick the default override.
- */
+ /* First try to use explicitly configured WWNs. */
+ seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
+ if (seed)
+ return (seed);
+
+ /* Otherwise try to use WWNs from NVRAM. */
if (isactive) {
- seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
- if (seed) {
- return (seed);
- }
- seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram : FCPARAM(isp, chan)->isp_wwpn_nvram;
- if (seed) {
+ seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram :
+ FCPARAM(isp, chan)->isp_wwpn_nvram;
+ if (seed)
return (seed);
- }
- return (0x400000007F000009ull);
}
- seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
-
- /*
- * For channel zero just return what we have. For either ACTIVE or
- * DEFAULT cases, we depend on default override of NVRAM values for
- * channel zero.
- */
- if (chan == 0) {
- return (seed);
+ /* If still no WWNs, try to steal them from the first channel. */
+ if (chan > 0) {
+ seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn :
+ ISP_FC_PC(isp, 0)->def_wwpn;
+ if (seed == 0) {
+ seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram :
+ FCPARAM(isp, 0)->isp_wwpn_nvram;
+ }
}
- /*
- * For other channels, we are doing one of three things:
- *
- * 1. If what we have now is non-zero, return it. Otherwise we morph
- * values from channel 0. 2. If we're here for a WWPN we synthesize
- * it if Channel 0's wwpn has a type 2 NAA. 3. If we're here for a
- * WWNN we synthesize it if Channel 0's wwnn has a type 2 NAA.
- */
-
- if (seed) {
- return (seed);
+ /* If still nothing -- improvise. */
+ if (seed == 0) {
+ seed = 0x400000007F000000ull + device_get_unit(isp->isp_dev);
+ if (!iswwnn)
+ seed ^= 0x0100000000000000ULL;
}
- seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn : ISP_FC_PC(isp, 0)->def_wwpn;
- if (seed == 0)
- seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram : FCPARAM(isp, 0)->isp_wwpn_nvram;
- if (((seed >> 60) & 0xf) == 2) {
+ /* For additional channels we have to improvise even more. */
+ if (!iswwnn && chan > 0) {
/*
- * The type 2 NAA fields for QLogic cards appear be laid out
- * thusly:
- *
- * bits 63..60 NAA == 2 bits 59..57 unused/zero bit 56
- * port (1) or node (0) WWN distinguishor bit 48
- * physical port on dual-port chips (23XX/24XX)
- *
- * This is somewhat nutty, particularly since bit 48 is
- * irrelevant as they assign separate serial numbers to
- * different physical ports anyway.
- *
* We'll stick our channel number plus one first into bits
* 57..59 and thence into bits 52..55 which allows for 8 bits
- * of channel which is comfortably more than our maximum
- * (126) now.
+ * of channel which is enough for our maximum of 255 channels.
*/
- seed &= ~0x0FF0000000000000ULL;
- if (iswwnn == 0) {
- seed |= ((uint64_t) (chan + 1) & 0xf) << 56;
- seed |= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52;
- }
- } else {
- seed = 0;
+ seed ^= 0x0100000000000000ULL;
+ seed ^= ((uint64_t) (chan + 1) & 0xf) << 56;
+ seed ^= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52;
}
return (seed);
}
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index ff9a5a3..9a9093a 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -38,6 +38,7 @@
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
+#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
@@ -286,9 +287,9 @@ struct isposinfo {
/*
* DMA related sdtuff
*/
- bus_space_tag_t bus_tag;
+ struct resource * regs;
+ struct resource * regs2;
bus_dma_tag_t dmat;
- bus_space_handle_t bus_handle;
bus_dma_tag_t cdmat;
bus_dmamap_t cdmap;
@@ -361,8 +362,8 @@ struct isposinfo {
#define FCP_NEXT_CRN isp_fcp_next_crn
#define isp_lock isp_osinfo.lock
-#define isp_bus_tag isp_osinfo.bus_tag
-#define isp_bus_handle isp_osinfo.bus_handle
+#define isp_regs isp_osinfo.regs
+#define isp_regs2 isp_osinfo.regs2
/*
* Locking macros...
@@ -430,8 +431,7 @@ case SYNC_RESULT: \
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); \
break; \
case SYNC_REG: \
- bus_space_barrier(isp->isp_osinfo.bus_tag, \
- isp->isp_osinfo.bus_handle, offset, size, \
+ bus_barrier(isp->isp_osinfo.regs, offset, size, \
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); \
break; \
default: \
@@ -463,8 +463,7 @@ case SYNC_RESULT: \
isp->isp_osinfo.cdmap, BUS_DMASYNC_POSTWRITE); \
break; \
case SYNC_REG: \
- bus_space_barrier(isp->isp_osinfo.bus_tag, \
- isp->isp_osinfo.bus_handle, offset, size, \
+ bus_barrier(isp->isp_osinfo.regs, offset, size, \
BUS_SPACE_BARRIER_WRITE); \
break; \
default: \
diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c
index 9e8f3ab..ec99244 100644
--- a/sys/dev/isp/isp_library.c
+++ b/sys/dev/isp/isp_library.c
@@ -1402,7 +1402,9 @@ isp_put_icb_2400(ispsoftc_t *isp, isp_icb_2400_t *src, isp_icb_2400_t *dst)
for (i = 0; i < 4; i++) {
ISP_IOXPUT_16(isp, src->icb_priaddr[i], &dst->icb_priaddr[i]);
}
- for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, src->icb_msixresp, &dst->icb_msixresp);
+ ISP_IOXPUT_16(isp, src->icb_msixatio, &dst->icb_msixatio);
+ for (i = 0; i < 2; i++) {
ISP_IOXPUT_16(isp, src->icb_reserved1[i], &dst->icb_reserved1[i]);
}
ISP_IOXPUT_16(isp, src->icb_atio_in, &dst->icb_atio_in);
@@ -1415,9 +1417,14 @@ isp_put_icb_2400(ispsoftc_t *isp, isp_icb_2400_t *src, isp_icb_2400_t *dst)
ISP_IOXPUT_32(isp, src->icb_fwoptions1, &dst->icb_fwoptions1);
ISP_IOXPUT_32(isp, src->icb_fwoptions2, &dst->icb_fwoptions2);
ISP_IOXPUT_32(isp, src->icb_fwoptions3, &dst->icb_fwoptions3);
- for (i = 0; i < 12; i++) {
+ ISP_IOXPUT_16(isp, src->icb_qos, &dst->icb_qos);
+ for (i = 0; i < 3; i++)
ISP_IOXPUT_16(isp, src->icb_reserved2[i], &dst->icb_reserved2[i]);
- }
+ for (i = 0; i < 3; i++)
+ ISP_IOXPUT_16(isp, src->icb_enodemac[i], &dst->icb_enodemac[i]);
+ ISP_IOXPUT_16(isp, src->icb_disctime, &dst->icb_disctime);
+ for (i = 0; i < 4; i++)
+ ISP_IOXPUT_16(isp, src->icb_reserved3[i], &dst->icb_reserved3[i]);
}
void
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 55cb034..e5ea359 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -59,6 +59,8 @@ static uint32_t isp_pci_rd_reg_1080(ispsoftc_t *, int);
static void isp_pci_wr_reg_1080(ispsoftc_t *, int, uint32_t);
static uint32_t isp_pci_rd_reg_2400(ispsoftc_t *, int);
static void isp_pci_wr_reg_2400(ispsoftc_t *, int, uint32_t);
+static uint32_t isp_pci_rd_reg_2600(ispsoftc_t *, int);
+static void isp_pci_wr_reg_2600(ispsoftc_t *, int, uint32_t);
static int isp_pci_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
static int isp_pci_rd_isr_2300(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
static int isp_pci_rd_isr_2400(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
@@ -172,6 +174,18 @@ static struct ispmdvec mdvec_2500 = {
NULL
};
+static struct ispmdvec mdvec_2600 = {
+ isp_pci_rd_isr_2400,
+ isp_pci_rd_reg_2600,
+ isp_pci_wr_reg_2600,
+ isp_pci_mbxdma,
+ isp_pci_dmasetup,
+ isp_common_dmateardown,
+ isp_pci_reset0,
+ isp_pci_reset1,
+ NULL
+};
+
#ifndef PCIM_CMD_INVEN
#define PCIM_CMD_INVEN 0x10
#endif
@@ -276,6 +290,14 @@ static struct ispmdvec mdvec_2500 = {
#define PCI_PRODUCT_QLOGIC_ISP5432 0x5432
#endif
+#ifndef PCI_PRODUCT_QLOGIC_ISP2031
+#define PCI_PRODUCT_QLOGIC_ISP2031 0x2031
+#endif
+
+#ifndef PCI_PRODUCT_QLOGIC_ISP8031
+#define PCI_PRODUCT_QLOGIC_ISP8031 0x8031
+#endif
+
#define PCI_QLOGIC_ISP5432 \
((PCI_PRODUCT_QLOGIC_ISP5432 << 16) | PCI_VENDOR_QLOGIC)
@@ -327,14 +349,17 @@ static struct ispmdvec mdvec_2500 = {
#define PCI_QLOGIC_ISP6322 \
((PCI_PRODUCT_QLOGIC_ISP6322 << 16) | PCI_VENDOR_QLOGIC)
+#define PCI_QLOGIC_ISP2031 \
+ ((PCI_PRODUCT_QLOGIC_ISP2031 << 16) | PCI_VENDOR_QLOGIC)
+
+#define PCI_QLOGIC_ISP8031 \
+ ((PCI_PRODUCT_QLOGIC_ISP8031 << 16) | PCI_VENDOR_QLOGIC)
+
/*
* Odd case for some AMI raid cards... We need to *not* attach to this.
*/
#define AMI_RAID_SUBVENDOR_ID 0x101e
-#define IO_MAP_REG 0x10
-#define MEM_MAP_REG 0x14
-
#define PCI_DFLT_LTNCY 0x40
#define PCI_DFLT_LNSZ 0x10
@@ -348,10 +373,16 @@ struct isp_pcisoftc {
ispsoftc_t pci_isp;
device_t pci_dev;
struct resource * regs;
+ struct resource * regs1;
+ struct resource * regs2;
void * irq;
int iqd;
int rtp;
int rgd;
+ int rtp1;
+ int rgd1;
+ int rtp2;
+ int rgd2;
void * ih;
int16_t pci_poff[_NREG_BLKS];
bus_dma_tag_t dmat;
@@ -434,6 +465,12 @@ isp_pci_probe(device_t dev)
case PCI_QLOGIC_ISP6322:
device_set_desc(dev, "Qlogic ISP 6322 PCI FC-AL Adapter");
break;
+ case PCI_QLOGIC_ISP2031:
+ device_set_desc(dev, "Qlogic ISP 2031 PCI FC-AL Adapter");
+ break;
+ case PCI_QLOGIC_ISP8031:
+ device_set_desc(dev, "Qlogic ISP 8031 PCI FCoE Adapter");
+ break;
default:
return (ENXIO);
}
@@ -485,31 +522,6 @@ isp_get_generic_options(device_t dev, ispsoftc_t *isp)
}
static void
-isp_get_pci_options(device_t dev, int *m1, int *m2)
-{
- int tval;
- /*
- * Which we should try first - memory mapping or i/o mapping?
- *
- * We used to try memory first followed by i/o on alpha, otherwise
- * the reverse, but we should just try memory first all the time now.
- */
- *m1 = PCIM_CMD_MEMEN;
- *m2 = PCIM_CMD_PORTEN;
-
- tval = 0;
- if (resource_int_value(device_get_name(dev), device_get_unit(dev), "prefer_iomap", &tval) == 0 && tval != 0) {
- *m1 = PCIM_CMD_PORTEN;
- *m2 = PCIM_CMD_MEMEN;
- }
- tval = 0;
- if (resource_int_value(device_get_name(dev), device_get_unit(dev), "prefer_memmap", &tval) == 0 && tval != 0) {
- *m1 = PCIM_CMD_MEMEN;
- *m2 = PCIM_CMD_PORTEN;
- }
-}
-
-static void
isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp)
{
const char *sptr;
@@ -662,7 +674,7 @@ isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp)
static int
isp_pci_attach(device_t dev)
{
- int i, m1, m2, locksetup = 0;
+ int i, locksetup = 0;
uint32_t data, cmd, linesz, did;
struct isp_pcisoftc *pcs;
ispsoftc_t *isp;
@@ -689,33 +701,10 @@ isp_pci_attach(device_t dev)
isp_nvports = 0;
isp_get_generic_options(dev, isp);
- /*
- * Get PCI options- which in this case are just mapping preferences.
- */
- isp_get_pci_options(dev, &m1, &m2);
-
linesz = PCI_DFLT_LNSZ;
- pcs->irq = pcs->regs = NULL;
+ pcs->irq = pcs->regs = pcs->regs2 = NULL;
pcs->rgd = pcs->rtp = pcs->iqd = 0;
- pcs->rtp = (m1 == PCIM_CMD_MEMEN)? SYS_RES_MEMORY : SYS_RES_IOPORT;
- pcs->rgd = (m1 == PCIM_CMD_MEMEN)? MEM_MAP_REG : IO_MAP_REG;
- pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd, RF_ACTIVE);
- if (pcs->regs == NULL) {
- pcs->rtp = (m2 == PCIM_CMD_MEMEN)? SYS_RES_MEMORY : SYS_RES_IOPORT;
- pcs->rgd = (m2 == PCIM_CMD_MEMEN)? MEM_MAP_REG : IO_MAP_REG;
- pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd, RF_ACTIVE);
- }
- if (pcs->regs == NULL) {
- device_printf(dev, "unable to map any ports\n");
- goto bad;
- }
- if (bootverbose) {
- device_printf(dev, "using %s space register mapping\n", (pcs->rgd == IO_MAP_REG)? "I/O" : "Memory");
- }
- isp->isp_bus_tag = rman_get_bustag(pcs->regs);
- isp->isp_bus_handle = rman_get_bushandle(pcs->regs);
-
pcs->pci_dev = dev;
pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
@@ -823,6 +812,14 @@ isp_pci_attach(device_t dev)
isp->isp_type = ISP_HA_FC_2500;
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2400_OFF;
break;
+ case PCI_QLOGIC_ISP2031:
+ case PCI_QLOGIC_ISP8031:
+ did = 0x2600;
+ isp->isp_nchan += isp_nvports;
+ isp->isp_mdvec = &mdvec_2600;
+ isp->isp_type = ISP_HA_FC_2600;
+ pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2400_OFF;
+ break;
default:
device_printf(dev, "unknown device type\n");
goto bad;
@@ -830,6 +827,42 @@ isp_pci_attach(device_t dev)
}
isp->isp_revision = pci_get_revid(dev);
+ if (IS_26XX(isp)) {
+ pcs->rtp = SYS_RES_MEMORY;
+ pcs->rgd = PCIR_BAR(0);
+ pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd,
+ RF_ACTIVE);
+ pcs->rtp1 = SYS_RES_MEMORY;
+ pcs->rgd1 = PCIR_BAR(2);
+ pcs->regs1 = bus_alloc_resource_any(dev, pcs->rtp1, &pcs->rgd1,
+ RF_ACTIVE);
+ pcs->rtp2 = SYS_RES_MEMORY;
+ pcs->rgd2 = PCIR_BAR(4);
+ pcs->regs2 = bus_alloc_resource_any(dev, pcs->rtp2, &pcs->rgd2,
+ RF_ACTIVE);
+ } else {
+ pcs->rtp = SYS_RES_MEMORY;
+ pcs->rgd = PCIR_BAR(1);
+ pcs->regs = bus_alloc_resource_any(dev, pcs->rtp, &pcs->rgd,
+ RF_ACTIVE);
+ if (pcs->regs == NULL) {
+ pcs->rtp = SYS_RES_IOPORT;
+ pcs->rgd = PCIR_BAR(0);
+ pcs->regs = bus_alloc_resource_any(dev, pcs->rtp,
+ &pcs->rgd, RF_ACTIVE);
+ }
+ }
+ if (pcs->regs == NULL) {
+ device_printf(dev, "Unable to map any ports\n");
+ goto bad;
+ }
+ if (bootverbose) {
+ device_printf(dev, "Using %s space register mapping\n",
+ (pcs->rtp == SYS_RES_IOPORT)? "I/O" : "Memory");
+ }
+ isp->isp_regs = pcs->regs;
+ isp->isp_regs2 = pcs->regs2;
+
if (IS_FC(isp)) {
psize = sizeof (fcparam);
xsize = sizeof (struct isp_fc);
@@ -910,20 +943,28 @@ isp_pci_attach(device_t dev)
data &= ~1;
pci_write_config(dev, PCIR_ROMADDR, data, 4);
- /*
- * Do MSI
- *
- * NB: MSI-X needs to be disabled for the 2432 (PCI-Express)
- */
- if (IS_24XX(isp) || IS_2322(isp)) {
- pcs->msicount = pci_msi_count(dev);
- if (pcs->msicount > 1) {
- pcs->msicount = 1;
+ if (IS_26XX(isp)) {
+ /* 26XX chips support only MSI-X, so start from them. */
+ pcs->msicount = imin(pci_msix_count(dev), 1);
+ if (pcs->msicount > 0 &&
+ (i = pci_alloc_msix(dev, &pcs->msicount)) == 0) {
+ pcs->iqd = 1;
+ } else {
+ pcs->msicount = 0;
}
- if (pci_alloc_msi(dev, &pcs->msicount) == 0) {
+ }
+ if (pcs->msicount == 0 && (IS_24XX(isp) || IS_2322(isp))) {
+ /*
+ * Older chips support both MSI and MSI-X, but I have
+ * feeling that older firmware may not support MSI-X,
+ * but we have no way to check the firmware flag here.
+ */
+ pcs->msicount = imin(pci_msi_count(dev), 1);
+ if (pcs->msicount > 0 &&
+ pci_alloc_msi(dev, &pcs->msicount) == 0) {
pcs->iqd = 1;
} else {
- pcs->iqd = 0;
+ pcs->msicount = 0;
}
}
pcs->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &pcs->iqd, RF_ACTIVE | RF_SHAREABLE);
@@ -978,9 +1019,12 @@ bad:
if (pcs->msicount) {
pci_release_msi(dev);
}
- if (pcs->regs) {
+ if (pcs->regs)
(void) bus_release_resource(dev, pcs->rtp, pcs->rgd, pcs->regs);
- }
+ if (pcs->regs1)
+ (void) bus_release_resource(dev, pcs->rtp1, pcs->rgd1, pcs->regs1);
+ if (pcs->regs2)
+ (void) bus_release_resource(dev, pcs->rtp2, pcs->rgd2, pcs->regs2);
if (pcs->pci_isp.isp_param) {
free(pcs->pci_isp.isp_param, M_DEVBUF);
pcs->pci_isp.isp_param = NULL;
@@ -1019,6 +1063,10 @@ isp_pci_detach(device_t dev)
pci_release_msi(dev);
}
(void) bus_release_resource(dev, pcs->rtp, pcs->rgd, pcs->regs);
+ if (pcs->regs1)
+ (void) bus_release_resource(dev, pcs->rtp1, pcs->rgd1, pcs->regs1);
+ if (pcs->regs2)
+ (void) bus_release_resource(dev, pcs->rtp2, pcs->rgd2, pcs->regs2);
/*
* XXX: THERE IS A LOT OF LEAKAGE HERE
*/
@@ -1037,15 +1085,12 @@ isp_pci_detach(device_t dev)
(((struct isp_pcisoftc *)a)->pci_poff[((x) & _BLK_REG_MASK) >> \
_BLK_REG_SHFT] + ((x) & 0xfff))
-#define BXR2(isp, off) \
- bus_space_read_2(isp->isp_bus_tag, isp->isp_bus_handle, off)
-#define BXW2(isp, off, v) \
- bus_space_write_2(isp->isp_bus_tag, isp->isp_bus_handle, off, v)
-#define BXR4(isp, off) \
- bus_space_read_4(isp->isp_bus_tag, isp->isp_bus_handle, off)
-#define BXW4(isp, off, v) \
- bus_space_write_4(isp->isp_bus_tag, isp->isp_bus_handle, off, v)
-
+#define BXR2(isp, off) bus_read_2((isp)->isp_regs, (off))
+#define BXW2(isp, off, v) bus_write_2((isp)->isp_regs, (off), (v))
+#define BXR4(isp, off) bus_read_4((isp)->isp_regs, (off))
+#define BXW4(isp, off, v) bus_write_4((isp)->isp_regs, (off), (v))
+#define B2R4(isp, off) bus_read_4((isp)->isp_regs2, (off))
+#define B2W4(isp, off, v) bus_write_4((isp)->isp_regs2, (off), (v))
static ISP_INLINE int
isp_pci_rd_debounced(ispsoftc_t *isp, int off, uint16_t *rp)
@@ -1308,20 +1353,19 @@ isp_pci_rd_reg_2400(ispsoftc_t *isp, int regoff)
case MBOX_BLOCK:
return (BXR2(isp, IspVirt2Off(isp, regoff)));
case SXP_BLOCK:
- isp_prt(isp, ISP_LOGWARN, "SXP_BLOCK read at 0x%x", regoff);
+ isp_prt(isp, ISP_LOGERR, "SXP_BLOCK read at 0x%x", regoff);
return (0xffffffff);
case RISC_BLOCK:
- isp_prt(isp, ISP_LOGWARN, "RISC_BLOCK read at 0x%x", regoff);
+ isp_prt(isp, ISP_LOGERR, "RISC_BLOCK read at 0x%x", regoff);
return (0xffffffff);
case DMA_BLOCK:
- isp_prt(isp, ISP_LOGWARN, "DMA_BLOCK read at 0x%x", regoff);
+ isp_prt(isp, ISP_LOGERR, "DMA_BLOCK read at 0x%x", regoff);
return (0xffffffff);
default:
- isp_prt(isp, ISP_LOGWARN, "unknown block read at 0x%x", regoff);
+ isp_prt(isp, ISP_LOGERR, "unknown block read at 0x%x", regoff);
return (0xffffffff);
}
-
switch (regoff) {
case BIU2400_FLASH_ADDR:
case BIU2400_FLASH_DATA:
@@ -1349,8 +1393,8 @@ isp_pci_rd_reg_2400(ispsoftc_t *isp, int regoff)
rv = BXR4(isp, IspVirt2Off(isp, regoff)) >> 16;
break;
default:
- isp_prt(isp, ISP_LOGERR,
- "isp_pci_rd_reg_2400: unknown offset %x", regoff);
+ isp_prt(isp, ISP_LOGERR, "unknown register read at 0x%x",
+ regoff);
rv = 0xffffffff;
break;
}
@@ -1370,17 +1414,16 @@ isp_pci_wr_reg_2400(ispsoftc_t *isp, int regoff, uint32_t val)
MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, regoff), 2, -1);
return;
case SXP_BLOCK:
- isp_prt(isp, ISP_LOGWARN, "SXP_BLOCK write at 0x%x", regoff);
+ isp_prt(isp, ISP_LOGERR, "SXP_BLOCK write at 0x%x", regoff);
return;
case RISC_BLOCK:
- isp_prt(isp, ISP_LOGWARN, "RISC_BLOCK write at 0x%x", regoff);
+ isp_prt(isp, ISP_LOGERR, "RISC_BLOCK write at 0x%x", regoff);
return;
case DMA_BLOCK:
- isp_prt(isp, ISP_LOGWARN, "DMA_BLOCK write at 0x%x", regoff);
+ isp_prt(isp, ISP_LOGERR, "DMA_BLOCK write at 0x%x", regoff);
return;
default:
- isp_prt(isp, ISP_LOGWARN, "unknown block write at 0x%x",
- regoff);
+ isp_prt(isp, ISP_LOGERR, "unknown block write at 0x%x", regoff);
break;
}
@@ -1415,10 +1458,83 @@ isp_pci_wr_reg_2400(ispsoftc_t *isp, int regoff, uint32_t val)
MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, regoff), 4, -1);
break;
default:
- isp_prt(isp, ISP_LOGERR,
- "isp_pci_wr_reg_2400: bad offset 0x%x", regoff);
+ isp_prt(isp, ISP_LOGERR, "unknown register write at 0x%x",
+ regoff);
+ break;
+ }
+}
+
+static uint32_t
+isp_pci_rd_reg_2600(ispsoftc_t *isp, int regoff)
+{
+ uint32_t rv;
+
+ switch (regoff) {
+ case BIU2400_PRI_REQINP:
+ case BIU2400_PRI_REQOUTP:
+ isp_prt(isp, ISP_LOGERR, "unknown register read at 0x%x",
+ regoff);
+ rv = 0xffffffff;
+ break;
+ case BIU2400_REQINP:
+ rv = B2R4(isp, 0x00);
+ break;
+ case BIU2400_REQOUTP:
+ rv = B2R4(isp, 0x04);
break;
+ case BIU2400_RSPINP:
+ rv = B2R4(isp, 0x08);
+ break;
+ case BIU2400_RSPOUTP:
+ rv = B2R4(isp, 0x0c);
+ break;
+ case BIU2400_ATIO_RSPINP:
+ rv = B2R4(isp, 0x10);
+ break;
+ case BIU2400_ATIO_RSPOUTP:
+ rv = B2R4(isp, 0x14);
+ break;
+ default:
+ rv = isp_pci_rd_reg_2400(isp, regoff);
+ break;
+ }
+ return (rv);
+}
+
+static void
+isp_pci_wr_reg_2600(ispsoftc_t *isp, int regoff, uint32_t val)
+{
+ int off;
+
+ switch (regoff) {
+ case BIU2400_PRI_REQINP:
+ case BIU2400_PRI_REQOUTP:
+ isp_prt(isp, ISP_LOGERR, "unknown register write at 0x%x",
+ regoff);
+ return;
+ case BIU2400_REQINP:
+ off = 0x00;
+ break;
+ case BIU2400_REQOUTP:
+ off = 0x04;
+ break;
+ case BIU2400_RSPINP:
+ off = 0x08;
+ break;
+ case BIU2400_RSPOUTP:
+ off = 0x0c;
+ break;
+ case BIU2400_ATIO_RSPINP:
+ off = 0x10;
+ break;
+ case BIU2400_ATIO_RSPOUTP:
+ off = 0x14;
+ break;
+ default:
+ isp_pci_wr_reg_2400(isp, regoff, val);
+ return;
}
+ B2W4(isp, off, val);
}
diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
index cb8f169..2abfc64 100644
--- a/sys/dev/isp/isp_sbus.c
+++ b/sys/dev/isp/isp_sbus.c
@@ -180,8 +180,7 @@ isp_sbus_attach(device_t dev)
sbs->sbus_poff[RISC_BLOCK >> _BLK_REG_SHFT] = SBUS_RISC_REGS_OFF;
sbs->sbus_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
isp = &sbs->sbus_isp;
- isp->isp_bus_tag = rman_get_bustag(sbs->regs);
- isp->isp_bus_handle = rman_get_bushandle(sbs->regs);
+ isp->isp_regs = sbs->regs;
isp->isp_mdvec = &sbs->sbus_mdvec;
isp->isp_bustype = ISP_BT_SBUS;
isp->isp_type = ISP_HA_SCSI_UNKNOWN;
@@ -367,16 +366,15 @@ isp_sbus_detach(device_t dev)
(((struct isp_sbussoftc *)a)->sbus_poff[((x) & _BLK_REG_MASK) >> \
_BLK_REG_SHFT] + ((x) & 0xff))
-#define BXR2(sbc, off) \
- bus_space_read_2(isp->isp_bus_tag, isp->isp_bus_handle, off)
+#define BXR2(isp, off) bus_read_2((isp)->isp_regs, (off))
static int
isp_sbus_rd_isr(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info)
{
uint16_t isr, sema;
- isr = BXR2(sbc, IspVirt2Off(isp, BIU_ISR));
- sema = BXR2(sbc, IspVirt2Off(isp, BIU_SEMA));
+ isr = BXR2(isp, IspVirt2Off(isp, BIU_ISR));
+ sema = BXR2(isp, IspVirt2Off(isp, BIU_SEMA));
isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);
isr &= INT_PENDING_MASK(isp);
sema &= BIU_SEMA_LOCK;
@@ -385,7 +383,7 @@ isp_sbus_rd_isr(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *info
}
*isrp = isr;
if ((*semap = sema) != 0)
- *info = BXR2(sbc, IspVirt2Off(isp, OUTMAILBOX0));
+ *info = BXR2(isp, IspVirt2Off(isp, OUTMAILBOX0));
return (1);
}
@@ -396,7 +394,7 @@ isp_sbus_rd_reg(ispsoftc_t *isp, int regoff)
struct isp_sbussoftc *sbs = (struct isp_sbussoftc *) isp;
int offset = sbs->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
offset += (regoff & 0xff);
- rval = bus_space_read_2(isp->isp_bus_tag, isp->isp_bus_handle, offset);
+ rval = BXR2(isp, offset);
isp_prt(isp, ISP_LOGDEBUG3,
"isp_sbus_rd_reg(off %x) = %x", regoff, rval);
return (rval);
@@ -410,7 +408,7 @@ isp_sbus_wr_reg(ispsoftc_t *isp, int regoff, uint32_t val)
offset += (regoff & 0xff);
isp_prt(isp, ISP_LOGDEBUG3,
"isp_sbus_wr_reg(off %x) = %x", regoff, val);
- bus_space_write_2(isp->isp_bus_tag, isp->isp_bus_handle, offset, val);
+ bus_write_2(isp->isp_regs, offset, val);
MEMORYBARRIER(isp, SYNC_REG, offset, 2, -1);
}
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index d724679..a89228b 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -122,6 +122,7 @@
#define MBOX_GET_TARGET_STATUS 0x0056
/* These are for the ISP2X00 FC cards */
+#define MBOX_LOAD_FLASH_FIRMWARE 0x0003
#define MBOX_WRITE_FC_SERDES_REG 0x0003 /* FC only */
#define MBOX_READ_FC_SERDES_REG 0x0004 /* FC only */
#define MBOX_GET_IO_STATUS 0x0012
@@ -1007,9 +1008,9 @@ typedef struct {
#define ICBXOPT_TIMER_MASK 0x7
#define ICBZOPT_RATE_MASK 0xC000
-#define ICBZOPT_RATE_ONEGB 0x0000
+#define ICBZOPT_RATE_1GB 0x0000
#define ICBZOPT_RATE_AUTO 0x8000
-#define ICBZOPT_RATE_TWOGB 0x4000
+#define ICBZOPT_RATE_2GB 0x4000
#define ICBZOPT_50_OHM 0x2000
#define ICBZOPT_NO_LOCAL_PLOGI 0x0080
#define ICBZOPT_ENA_OOF 0x0040 /* out of order frame handling */
@@ -1058,14 +1059,14 @@ typedef struct {
#define ICB2400_OPT3_ENA_ETH_RESP 0x08000000
#define ICB2400_OPT3_ENA_ETH_ATIO 0x04000000
#define ICB2400_OPT3_ENA_MFCF 0x00020000
-#define ICB2400_OPT3_SKIP_FOURGB 0x00010000
+#define ICB2400_OPT3_SKIP_4GB 0x00010000
#define ICB2400_OPT3_RATE_MASK 0x0000E000
-#define ICB2400_OPT3_RATE_ONEGB 0x00000000
-#define ICB2400_OPT3_RATE_TWOGB 0x00002000
+#define ICB2400_OPT3_RATE_1GB 0x00000000
+#define ICB2400_OPT3_RATE_2GB 0x00002000
#define ICB2400_OPT3_RATE_AUTO 0x00004000
-#define ICB2400_OPT3_RATE_FOURGB 0x00006000
-#define ICB2400_OPT3_RATE_EIGHTGB 0x00008000
-#define ICB2400_OPT3_RATE_SIXTEENGB 0x0000A000
+#define ICB2400_OPT3_RATE_4GB 0x00006000
+#define ICB2400_OPT3_RATE_8GB 0x00008000
+#define ICB2400_OPT3_RATE_16GB 0x0000A000
#define ICB2400_OPT3_ENA_OOF_XFRDY 0x00000200
#define ICB2400_OPT3_NO_N2N_LOGI 0x00000100
#define ICB2400_OPT3_NO_LOCAL_PLOGI 0x00000080
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index 10060e1..0c42642 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -653,8 +653,8 @@ struct ispsoftc {
#define ISP_CFG_NPORT 0x04 /* prefer {N/F}-Port connection */
#define ISP_CFG_NPORT_ONLY 0x08 /* insist on {N/F}-Port connection */
#define ISP_CFG_LPORT_ONLY 0x0c /* insist on {N/F}L-Port connection */
-#define ISP_CFG_ONEGB 0x10 /* force 1GB connection (23XX only) */
-#define ISP_CFG_TWOGB 0x20 /* force 2GB connection (23XX only) */
+#define ISP_CFG_1GB 0x10 /* force 1GB connection (23XX only) */
+#define ISP_CFG_2GB 0x20 /* force 2GB connection (23XX only) */
#define ISP_CFG_NORELOAD 0x80 /* don't download f/w */
#define ISP_CFG_NONVRAM 0x40 /* ignore NVRAM */
#define ISP_CFG_NOFCTAPE 0x100 /* disable FC-Tape */
@@ -662,9 +662,9 @@ struct ispsoftc {
#define ISP_CFG_OWNFSZ 0x400 /* override NVRAM frame size */
#define ISP_CFG_OWNLOOPID 0x800 /* override NVRAM loopid */
#define ISP_CFG_OWNEXCTHROTTLE 0x1000 /* override NVRAM execution throttle */
-#define ISP_CFG_FOURGB 0x2000 /* force 4GB connection (24XX only) */
-#define ISP_CFG_EIGHTGB 0x4000 /* force 8GB connection (25XX only) */
-#define ISP_CFG_SIXTEENGB 0x8000 /* force 16GB connection (82XX only) */
+#define ISP_CFG_4GB 0x2000 /* force 4GB connection (24XX only) */
+#define ISP_CFG_8GB 0x4000 /* force 8GB connection (25XX only) */
+#define ISP_CFG_16GB 0x8000 /* force 16GB connection (82XX only) */
/*
* For each channel, the outer layers should know what role that channel
@@ -764,6 +764,7 @@ struct ispsoftc {
#define ISP_HA_FC_2322 0x50
#define ISP_HA_FC_2400 0x60
#define ISP_HA_FC_2500 0x70
+#define ISP_HA_FC_2600 0x80
#define IS_SCSI(isp) (isp->isp_type & ISP_HA_SCSI)
#define IS_1020(isp) (isp->isp_type < ISP_HA_SCSI_1240)
@@ -789,6 +790,7 @@ struct ispsoftc {
#define IS_2322(isp) ((isp)->isp_type == ISP_HA_FC_2322)
#define IS_24XX(isp) ((isp)->isp_type >= ISP_HA_FC_2400)
#define IS_25XX(isp) ((isp)->isp_type >= ISP_HA_FC_2500)
+#define IS_26XX(isp) ((isp)->isp_type >= ISP_HA_FC_2600)
/*
* DMA related macros
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index 27ef8b3..693f000 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -825,8 +825,8 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
struct buf *pb;
bus_dma_segment_t *vlist;
struct thread *td;
- off_t len, zerosize;
- int ma_offs;
+ off_t iolen, len, zerosize;
+ int ma_offs, npages;
switch (bp->bio_cmd) {
case BIO_READ:
@@ -847,6 +847,7 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
pb = NULL;
piov = NULL;
ma_offs = bp->bio_ma_offset;
+ len = bp->bio_length;
/*
* VNODE I/O
@@ -879,7 +880,6 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
auio.uio_iovcnt = howmany(bp->bio_length, zerosize);
piov = malloc(sizeof(*piov) * auio.uio_iovcnt, M_MD, M_WAITOK);
auio.uio_iov = piov;
- len = bp->bio_length;
while (len > 0) {
piov->iov_base = __DECONST(void *, zero_region);
piov->iov_len = len;
@@ -893,7 +893,6 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
piov = malloc(sizeof(*piov) * bp->bio_ma_n, M_MD, M_WAITOK);
auio.uio_iov = piov;
vlist = (bus_dma_segment_t *)bp->bio_data;
- len = bp->bio_length;
while (len > 0) {
piov->iov_base = (void *)(uintptr_t)(vlist->ds_addr +
ma_offs);
@@ -909,11 +908,20 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
piov = auio.uio_iov;
} else if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
pb = getpbuf(&md_vnode_pbuf_freecnt);
- pmap_qenter((vm_offset_t)pb->b_data, bp->bio_ma, bp->bio_ma_n);
- aiov.iov_base = (void *)((vm_offset_t)pb->b_data + ma_offs);
- aiov.iov_len = bp->bio_length;
+ bp->bio_resid = len;
+unmapped_step:
+ npages = atop(min(MAXPHYS, round_page(len + (ma_offs &
+ PAGE_MASK))));
+ iolen = min(ptoa(npages) - (ma_offs & PAGE_MASK), len);
+ KASSERT(iolen > 0, ("zero iolen"));
+ pmap_qenter((vm_offset_t)pb->b_data,
+ &bp->bio_ma[atop(ma_offs)], npages);
+ aiov.iov_base = (void *)((vm_offset_t)pb->b_data +
+ (ma_offs & PAGE_MASK));
+ aiov.iov_len = iolen;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
+ auio.uio_resid = iolen;
} else {
aiov.iov_base = bp->bio_data;
aiov.iov_len = bp->bio_length;
@@ -937,15 +945,21 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
vn_finished_write(mp);
}
- if (pb) {
- pmap_qremove((vm_offset_t)pb->b_data, bp->bio_ma_n);
+ if (pb != NULL) {
+ pmap_qremove((vm_offset_t)pb->b_data, npages);
+ if (error == 0) {
+ len -= iolen;
+ bp->bio_resid -= iolen;
+ ma_offs += iolen;
+ if (len > 0)
+ goto unmapped_step;
+ }
relpbuf(pb, &md_vnode_pbuf_freecnt);
}
- if (piov != NULL)
- free(piov, M_MD);
-
- bp->bio_resid = auio.uio_resid;
+ free(piov, M_MD);
+ if (pb == NULL)
+ bp->bio_resid = auio.uio_resid;
return (error);
}
diff --git a/sys/dev/mii/rgephy.c b/sys/dev/mii/rgephy.c
index 2c28068..ff7c470 100644
--- a/sys/dev/mii/rgephy.c
+++ b/sys/dev/mii/rgephy.c
@@ -57,7 +57,7 @@ __FBSDID("$FreeBSD$");
#include "miibus_if.h"
#include <machine/bus.h>
-#include <pci/if_rlreg.h>
+#include <dev/rl/if_rlreg.h>
static int rgephy_probe(device_t);
static int rgephy_attach(device_t);
diff --git a/sys/dev/mii/rlphy.c b/sys/dev/mii/rlphy.c
index ddf8d73..308ee22 100644
--- a/sys/dev/mii/rlphy.c
+++ b/sys/dev/mii/rlphy.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
#include "miidevs.h"
#include <machine/bus.h>
-#include <pci/if_rlreg.h>
+#include <dev/rl/if_rlreg.h>
#include "miibus_if.h"
diff --git a/sys/dev/mii/rlswitch.c b/sys/dev/mii/rlswitch.c
index b158fd4..2e9188e 100644
--- a/sys/dev/mii/rlswitch.c
+++ b/sys/dev/mii/rlswitch.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include "miidevs.h"
#include <machine/bus.h>
-#include <pci/if_rlreg.h>
+#include <dev/rl/if_rlreg.h>
#include "miibus_if.h"
diff --git a/sys/dev/mpt/mpt.c b/sys/dev/mpt/mpt.c
index d5b2a18..9317965 100644
--- a/sys/dev/mpt/mpt.c
+++ b/sys/dev/mpt/mpt.c
@@ -1423,7 +1423,7 @@ mpt_send_handshake_cmd(struct mpt_softc *mpt, size_t len, void *cmd)
/* Send the command */
for (i = 0; i < len; i++) {
- mpt_write(mpt, MPT_OFFSET_DOORBELL, htole32(*data32++));
+ mpt_write_stream(mpt, MPT_OFFSET_DOORBELL, *data32++);
if (mpt_wait_db_ack(mpt) != MPT_OK) {
mpt_prt(mpt,
"mpt_send_handshake_cmd: timeout @ index %d\n", i);
@@ -1457,7 +1457,7 @@ mpt_recv_handshake_reply(struct mpt_softc *mpt, size_t reply_len, void *reply)
*data16++ = le16toh(data & MPT_DB_DATA_MASK);
mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
- /* Get Second Word */
+ /* Get second word */
if (mpt_wait_db_int(mpt) != MPT_OK) {
mpt_prt(mpt, "mpt_recv_handshake_cmd timeout2\n");
return ETIMEDOUT;
@@ -1481,18 +1481,13 @@ mpt_recv_handshake_reply(struct mpt_softc *mpt, size_t reply_len, void *reply)
left = (hdr->MsgLength << 1) - 2;
reply_left = reply_len - 2;
while (left--) {
- u_int16_t datum;
-
if (mpt_wait_db_int(mpt) != MPT_OK) {
mpt_prt(mpt, "mpt_recv_handshake_cmd timeout3\n");
return ETIMEDOUT;
}
data = mpt_read(mpt, MPT_OFFSET_DOORBELL);
- datum = le16toh(data & MPT_DB_DATA_MASK);
-
if (reply_left-- > 0)
- *data16++ = datum;
-
+ *data16++ = le16toh(data & MPT_DB_DATA_MASK);
mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
}
diff --git a/sys/dev/mpt/mpt.h b/sys/dev/mpt/mpt.h
index 1dcd76f..57dbe7b 100644
--- a/sys/dev/mpt/mpt.h
+++ b/sys/dev/mpt/mpt.h
@@ -329,7 +329,6 @@ typedef struct mpt_config_params {
} cfgparms_t;
/**************************** MPI Target State Info ***************************/
-
typedef struct {
uint32_t reply_desc; /* current reply descriptor */
uint32_t resid; /* current data residual */
@@ -784,6 +783,7 @@ mpt_assign_serno(struct mpt_softc *mpt, request_t *req)
/******************************* Register Access ******************************/
static __inline void mpt_write(struct mpt_softc *, size_t, uint32_t);
+static __inline void mpt_write_stream(struct mpt_softc *, size_t, uint32_t);
static __inline uint32_t mpt_read(struct mpt_softc *, int);
static __inline void mpt_pio_write(struct mpt_softc *, size_t, uint32_t);
static __inline uint32_t mpt_pio_read(struct mpt_softc *, int);
@@ -794,6 +794,12 @@ mpt_write(struct mpt_softc *mpt, size_t offset, uint32_t val)
bus_space_write_4(mpt->pci_st, mpt->pci_sh, offset, val);
}
+static __inline void
+mpt_write_stream(struct mpt_softc *mpt, size_t offset, uint32_t val)
+{
+ bus_space_write_stream_4(mpt->pci_st, mpt->pci_sh, offset, val);
+}
+
static __inline uint32_t
mpt_read(struct mpt_softc *mpt, int offset)
{
@@ -818,6 +824,7 @@ mpt_pio_read(struct mpt_softc *mpt, int offset)
KASSERT(mpt->pci_pio_reg != NULL, ("no PIO resource"));
return (bus_space_read_4(mpt->pci_pio_st, mpt->pci_pio_sh, offset));
}
+
/*********************** Reply Frame/Request Management ***********************/
/* Max MPT Reply we are willing to accept (must be power of 2) */
#define MPT_REPLY_SIZE 256
@@ -958,6 +965,7 @@ mpt_cdblen(uint8_t cdb0, int maxlen)
return (16);
}
}
+
#ifdef INVARIANTS
static __inline request_t * mpt_tag_2_req(struct mpt_softc *, uint32_t);
static __inline request_t *
@@ -1136,6 +1144,7 @@ mpt_write_cur_cfg_page(struct mpt_softc *mpt, uint32_t PageAddress,
PageAddress, hdr, len, sleep_ok,
timeout_ms));
}
+
/* mpt_debug.c functions */
void mpt_print_reply(void *vmsg);
void mpt_print_db(uint32_t mb);
@@ -1145,4 +1154,5 @@ void mpt_req_state(mpt_req_state_t state);
void mpt_print_config_request(void *vmsg);
void mpt_print_request(void *vmsg);
void mpt_dump_sgl(SGE_IO_UNION *se, int offset);
+
#endif /* _MPT_H_ */
diff --git a/sys/dev/qlxgbe/ql_hw.c b/sys/dev/qlxgbe/ql_hw.c
index 0e389d6..3efca30 100644
--- a/sys/dev/qlxgbe/ql_hw.c
+++ b/sys/dev/qlxgbe/ql_hw.c
@@ -387,6 +387,7 @@ ql_hw_add_sysctls(qla_host_t *ha)
"Minidump Utility can start minidump process");
#ifdef QL_DBG
+ ha->err_inject = 0;
SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
OID_AUTO, "err_inject",
@@ -3057,7 +3058,7 @@ ql_hw_check_health(qla_host_t *ha)
val = READ_REG32(ha, Q8_FIRMWARE_HEARTBEAT);
if ((val != ha->hw.hbeat_value) &&
- (!(QL_ERR_INJECT(ha, INJCT_TEMPERATURE_FAILURE)))) {
+ (!(QL_ERR_INJECT(ha, INJCT_HEARTBEAT_FAILURE)))) {
ha->hw.hbeat_value = val;
return 0;
}
diff --git a/sys/dev/qlxgbe/ql_os.c b/sys/dev/qlxgbe/ql_os.c
index ecc6cce..5190ff5 100644
--- a/sys/dev/qlxgbe/ql_os.c
+++ b/sys/dev/qlxgbe/ql_os.c
@@ -289,8 +289,6 @@ qla_pci_attach(device_t dev)
int i;
uint32_t num_rcvq = 0;
- QL_DPRINT2(ha, (dev, "%s: enter\n", __func__));
-
if ((ha = device_get_softc(dev)) == NULL) {
device_printf(dev, "cannot get softc\n");
return (ENOMEM);
diff --git a/sys/dev/qlxgbe/ql_ver.h b/sys/dev/qlxgbe/ql_ver.h
index 061e368..0d86db9 100644
--- a/sys/dev/qlxgbe/ql_ver.h
+++ b/sys/dev/qlxgbe/ql_ver.h
@@ -36,6 +36,6 @@
#define QLA_VERSION_MAJOR 3
#define QLA_VERSION_MINOR 10
-#define QLA_VERSION_BUILD 24
+#define QLA_VERSION_BUILD 25
#endif /* #ifndef _QL_VER_H_ */
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
index 20d47e2..3812962 100644
--- a/sys/dev/re/if_re.c
+++ b/sys/dev/re/if_re.c
@@ -147,7 +147,7 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#include <pci/if_rlreg.h>
+#include <dev/rl/if_rlreg.h>
MODULE_DEPEND(re, pci, 1, 1, 1);
MODULE_DEPEND(re, ether, 1, 1, 1);
@@ -237,6 +237,7 @@ static const struct rl_hwrev re_hwrevs[] = {
{ RL_HWREV_8168F, RL_8169, "8168F/8111F", RL_JUMBO_MTU_9K},
{ RL_HWREV_8168G, RL_8169, "8168G/8111G", RL_JUMBO_MTU_9K},
{ RL_HWREV_8168GU, RL_8169, "8168GU/8111GU", RL_JUMBO_MTU_9K},
+ { RL_HWREV_8168H, RL_8169, "8168H/8111H", RL_JUMBO_MTU_9K},
{ RL_HWREV_8411, RL_8169, "8411", RL_JUMBO_MTU_9K},
{ RL_HWREV_8411B, RL_8169, "8411B", RL_JUMBO_MTU_9K},
{ 0, 0, NULL, 0 }
@@ -633,9 +634,8 @@ re_miibus_statchg(device_t dev)
}
}
/*
- * RealTek controllers does not provide any interface to
- * Tx/Rx MACs for resolved speed, duplex and flow-control
- * parameters.
+ * RealTek controllers do not provide any interface to the RX/TX
+ * MACs for resolved speed, duplex and flow-control parameters.
*/
}
@@ -657,7 +657,7 @@ re_set_rxmode(struct rl_softc *sc)
rxfilt = RL_RXCFG_CONFIG | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_BROAD;
if ((sc->rl_flags & RL_FLAG_EARLYOFF) != 0)
rxfilt |= RL_RXCFG_EARLYOFF;
- else if ((sc->rl_flags & RL_FLAG_EARLYOFFV2) != 0)
+ else if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0)
rxfilt |= RL_RXCFG_EARLYOFFV2;
if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
@@ -1204,11 +1204,10 @@ re_attach(device_t dev)
struct rl_softc *sc;
struct ifnet *ifp;
const struct rl_hwrev *hw_rev;
+ int capmask, error = 0, hwrev, i, msic, msixc,
+ phy, reg, rid;
u_int32_t cap, ctl;
- int hwrev;
u_int16_t devid, re_did = 0;
- int error = 0, i, phy, rid;
- int msic, msixc, reg;
uint8_t cfg;
sc = device_get_softc(dev);
@@ -1488,11 +1487,12 @@ re_attach(device_t dev)
RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 |
RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK |
- RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED;
+ RL_FLAG_8168G_PLUS;
break;
case RL_HWREV_8168GU:
+ case RL_HWREV_8168H:
if (pci_get_device(dev) == RT_DEVICEID_8101E) {
- /* RTL8106EUS */
+ /* RTL8106E(US), RTL8107E */
sc->rl_flags |= RL_FLAG_FASTETHER;
} else
sc->rl_flags |= RL_FLAG_JUMBOV2 | RL_FLAG_WOL_MANLINK;
@@ -1500,7 +1500,7 @@ re_attach(device_t dev)
sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
RL_FLAG_AUTOPAD | RL_FLAG_CMDSTOP_WAIT_TXQ |
- RL_FLAG_EARLYOFFV2 | RL_FLAG_RXDV_GATED;
+ RL_FLAG_8168G_PLUS;
break;
case RL_HWREV_8169_8110SB:
case RL_HWREV_8169_8110SBL:
@@ -1650,8 +1650,11 @@ re_attach(device_t dev)
phy = RE_PHYAD_INTERNAL;
if (sc->rl_type == RL_8169)
phy = 1;
+ capmask = BMSR_DEFCAPMASK;
+ if ((sc->rl_flags & RL_FLAG_FASTETHER) != 0)
+ capmask &= ~BMSR_EXTSTAT;
error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd,
- re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
+ re_ifmedia_sts, capmask, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
if (error != 0) {
device_printf(dev, "attaching PHYs failed\n");
goto fail;
@@ -1691,13 +1694,13 @@ re_attach(device_t dev)
#ifdef DEV_NETMAP
re_netmap_attach(sc);
#endif /* DEV_NETMAP */
+
#ifdef RE_DIAG
/*
* Perform hardware diagnostic on the original RTL8169.
* Some 32-bit cards were incorrectly wired and would
* malfunction if plugged into a 64-bit slot.
*/
-
if (hwrev == RL_HWREV_8169) {
error = re_diag(sc);
if (error) {
@@ -1729,7 +1732,6 @@ re_attach(device_t dev)
}
fail:
-
if (error)
re_detach(dev);
@@ -2935,6 +2937,7 @@ re_start_locked(struct ifnet *ifp)
return;
}
#endif /* DEV_NETMAP */
+
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0)
return;
@@ -3190,9 +3193,18 @@ re_init_locked(struct rl_softc *sc)
CSR_WRITE_4(sc, RL_TXLIST_ADDR_LO,
RL_ADDR_LO(sc->rl_ldata.rl_tx_list_addr));
- if ((sc->rl_flags & RL_FLAG_RXDV_GATED) != 0)
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
+ /* Disable RXDV gate. */
CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) &
~0x00080000);
+ }
+
+ /*
+ * Enable transmit and receive for pre-RTL8168G controllers.
+ * RX/TX MACs should be enabled before RX/TX configuration.
+ */
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) == 0)
+ CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
/*
* Set the initial TX configuration.
@@ -3221,9 +3233,11 @@ re_init_locked(struct rl_softc *sc)
}
/*
- * Enable transmit and receive.
+ * Enable transmit and receive for RTL8168G and later controllers.
+ * RX/TX MACs should be enabled after RX/TX configuration.
*/
- CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0)
+ CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
#ifdef DEVICE_POLLING
/*
@@ -3579,6 +3593,12 @@ re_stop(struct rl_softc *sc)
~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_MULTI |
RL_RXCFG_RX_BROAD));
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
+ /* Enable RXDV gate. */
+ CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) |
+ 0x00080000);
+ }
+
if ((sc->rl_flags & RL_FLAG_WAIT_TXPOLL) != 0) {
for (i = RL_TIMEOUT; i > 0; i--) {
if ((CSR_READ_1(sc, sc->rl_txstart) &
@@ -3830,6 +3850,11 @@ re_setwol(struct rl_softc *sc)
CSR_READ_1(sc, RL_GPIO) & ~0x01);
}
if ((ifp->if_capenable & IFCAP_WOL) != 0) {
+ if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
+ /* Disable RXDV gate. */
+ CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) &
+ ~0x00080000);
+ }
re_set_rxmode(sc);
if ((sc->rl_flags & RL_FLAG_WOL_MANLINK) != 0)
re_set_linkspeed(sc);
@@ -3942,7 +3967,6 @@ re_add_sysctls(struct rl_softc *sc)
sc->rl_int_rx_mod = RL_TIMER_DEFAULT;
}
}
-
}
static int
diff --git a/sys/pci/if_rl.c b/sys/dev/rl/if_rl.c
index 4f91d1f..2ff1310 100644
--- a/sys/pci/if_rl.c
+++ b/sys/dev/rl/if_rl.c
@@ -126,7 +126,7 @@ MODULE_DEPEND(rl, miibus, 1, 1, 1);
/* "device miibus" required. See GENERIC if you get errors here. */
#include "miibus_if.h"
-#include <pci/if_rlreg.h>
+#include <dev/rl/if_rlreg.h>
/*
* Various supported device vendors/types and their names.
diff --git a/sys/pci/if_rlreg.h b/sys/dev/rl/if_rlreg.h
index b0de60f..5a5c5f5 100644
--- a/sys/pci/if_rlreg.h
+++ b/sys/dev/rl/if_rlreg.h
@@ -195,6 +195,7 @@
#define RL_HWREV_8168G 0x4C000000
#define RL_HWREV_8168EP 0x50000000
#define RL_HWREV_8168GU 0x50800000
+#define RL_HWREV_8168H 0x54000000
#define RL_HWREV_8411B 0x5C800000
#define RL_HWREV_8139 0x60000000
#define RL_HWREV_8139A 0x70000000
@@ -930,8 +931,7 @@ struct rl_softc {
#define RL_FLAG_CMDSTOP_WAIT_TXQ 0x00008000
#define RL_FLAG_WOL_MANLINK 0x00010000
#define RL_FLAG_EARLYOFF 0x00020000
-#define RL_FLAG_EARLYOFFV2 0x00040000
-#define RL_FLAG_RXDV_GATED 0x00080000
+#define RL_FLAG_8168G_PLUS 0x00040000
#define RL_FLAG_PCIE 0x40000000
#define RL_FLAG_LINK 0x80000000
};
diff --git a/sys/dev/usb/net/if_urndis.c b/sys/dev/usb/net/if_urndis.c
index 6509e78..5d2a637 100644
--- a/sys/dev/usb/net/if_urndis.c
+++ b/sys/dev/usb/net/if_urndis.c
@@ -78,12 +78,20 @@ static uether_fn_t urndis_start;
static uether_fn_t urndis_setmulti;
static uether_fn_t urndis_setpromisc;
-static uint32_t urndis_ctrl_query(struct urndis_softc *, uint32_t, const void **, uint16_t *);
-static uint32_t urndis_ctrl_set(struct urndis_softc *, uint32_t, struct urndis_set_req *, uint16_t);
-static uint32_t urndis_ctrl_handle_init(struct urndis_softc *, const struct urndis_comp_hdr *);
-static uint32_t urndis_ctrl_handle_query(struct urndis_softc *, const struct urndis_comp_hdr *, const void **, uint16_t *);
-static uint32_t urndis_ctrl_handle_reset(struct urndis_softc *, const struct urndis_comp_hdr *);
-static uint32_t urndis_ctrl_init(struct urndis_softc *);
+static uint32_t urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid,
+ struct urndis_query_req *msg, uint16_t len,
+ const void **rbuf, uint16_t *rbufsz);
+static uint32_t urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid,
+ struct urndis_set_req *msg, uint16_t len);
+static uint32_t urndis_ctrl_handle_init(struct urndis_softc *sc,
+ const struct urndis_comp_hdr *hdr);
+static uint32_t urndis_ctrl_handle_query(struct urndis_softc *sc,
+ const struct urndis_comp_hdr *hdr, const void **buf,
+ uint16_t *bufsz);
+static uint32_t urndis_ctrl_handle_reset(struct urndis_softc *sc,
+ const struct urndis_comp_hdr *hdr);
+static uint32_t urndis_ctrl_init(struct urndis_softc *sc);
+static uint32_t urndis_ctrl_halt(struct urndis_softc *sc);
#ifdef USB_DEBUG
static int urndis_debug = 0;
@@ -93,7 +101,6 @@ SYSCTL_INT(_hw_usb_urndis, OID_AUTO, debug, CTLFLAG_RW, &urndis_debug, 0,
#endif
static const struct usb_config urndis_config[URNDIS_N_TRANSFER] = {
-
[URNDIS_BULK_RX] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
@@ -154,7 +161,7 @@ static driver_t urndis_driver = {
static devclass_t urndis_devclass;
-DRIVER_MODULE(urndis, uhub, urndis_driver, urndis_devclass, NULL, 0);
+DRIVER_MODULE(urndis, uhub, urndis_driver, urndis_devclass, NULL, NULL);
MODULE_VERSION(urndis, 1);
MODULE_DEPEND(urndis, uether, 1, 1, 1);
MODULE_DEPEND(urndis, usb, 1, 1, 1);
@@ -171,6 +178,9 @@ static const struct usb_ether_methods urndis_ue_methods = {
static const STRUCT_USB_HOST_ID urndis_host_devs[] = {
/* Generic RNDIS class match */
+ {USB_IFACE_CLASS(UICLASS_CDC),
+ USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
+ USB_IFACE_PROTOCOL(0xff)},
{USB_IFACE_CLASS(UICLASS_WIRELESS), USB_IFACE_SUBCLASS(UISUBCLASS_RF),
USB_IFACE_PROTOCOL(UIPROTO_RNDIS)},
{USB_IFACE_CLASS(UICLASS_IAD), USB_IFACE_SUBCLASS(UISUBCLASS_SYNC),
@@ -192,21 +202,27 @@ urndis_probe(device_t dev)
static void
urndis_attach_post(struct usb_ether *ue)
{
+
/* no-op */
- return;
}
static int
urndis_attach(device_t dev)
{
+ static struct {
+ union {
+ struct urndis_query_req query;
+ struct urndis_set_req set;
+ } hdr;
+ union {
+ uint8_t eaddr[ETHER_ADDR_LEN];
+ uint32_t filter;
+ } ibuf;
+ } msg;
struct urndis_softc *sc = device_get_softc(dev);
struct usb_ether *ue = &sc->sc_ue;
struct usb_attach_arg *uaa = device_get_ivars(dev);
struct usb_cdc_cm_descriptor *cmd;
- struct {
- struct urndis_set_req hdr;
- uint32_t filter;
- } msg_filter;
const void *buf;
uint16_t bufsz;
uint8_t iface_index[2] = { uaa->info.bIfaceIndex + 1, uaa->info.bIfaceIndex };
@@ -228,9 +244,7 @@ urndis_attach(device_t dev)
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
/* scan the alternate settings looking for a valid one */
-
for (i = 0; i != 32; i++) {
-
error = usbd_set_alt_interface_index(uaa->device,
iface_index[0], i);
@@ -244,16 +258,27 @@ urndis_attach(device_t dev)
if (error == 0)
break;
}
-
if ((error != 0) || (i == 32)) {
- device_printf(dev, "No valid alternate "
- "setting found\n");
+ device_printf(dev, "No valid alternate setting found\n");
goto detach;
}
+
+ /* Initialize device - must be done before even querying it */
URNDIS_LOCK(sc);
- error = urndis_ctrl_query(sc, OID_802_3_PERMANENT_ADDRESS, &buf, &bufsz);
+ error = urndis_ctrl_init(sc);
URNDIS_UNLOCK(sc);
+ if (error != (int)RNDIS_STATUS_SUCCESS) {
+ device_printf(dev, "Unable to initialize hardware\n");
+ goto detach;
+ }
+ /* Determine MAC address */
+ memset(msg.ibuf.eaddr, 0, sizeof(msg.ibuf.eaddr));
+ URNDIS_LOCK(sc);
+ error = urndis_ctrl_query(sc, OID_802_3_PERMANENT_ADDRESS,
+ &msg.hdr.query, sizeof(msg.hdr.query) + sizeof(msg.ibuf.eaddr),
+ &buf, &bufsz);
+ URNDIS_UNLOCK(sc);
if (error != (int)RNDIS_STATUS_SUCCESS) {
device_printf(dev, "Unable to get hardware address\n");
goto detach;
@@ -267,17 +292,16 @@ urndis_attach(device_t dev)
/* Initialize packet filter */
sc->sc_filter = RNDIS_PACKET_TYPE_BROADCAST |
RNDIS_PACKET_TYPE_ALL_MULTICAST;
- msg_filter.filter = htole32(sc->sc_filter);
-
+ msg.ibuf.filter = htole32(sc->sc_filter);
URNDIS_LOCK(sc);
error = urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER,
- &msg_filter.hdr, sizeof(msg_filter));
+ &msg.hdr.set, sizeof(msg.hdr.set) + sizeof(msg.ibuf.filter));
URNDIS_UNLOCK(sc);
-
if (error != (int)RNDIS_STATUS_SUCCESS) {
device_printf(dev, "Unable to set data filters\n");
goto detach;
}
+
ue->ue_sc = sc;
ue->ue_dev = dev;
ue->ue_udev = uaa->device;
@@ -298,7 +322,7 @@ urndis_attach(device_t dev)
return (0); /* success */
detach:
- urndis_detach(dev);
+ (void)urndis_detach(dev);
return (ENXIO); /* failure */
}
@@ -313,6 +337,10 @@ urndis_detach(device_t dev)
uether_ifdetach(ue);
+ URNDIS_LOCK(sc);
+ (void)urndis_ctrl_halt(sc);
+ URNDIS_UNLOCK(sc);
+
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -340,8 +368,6 @@ urndis_init(struct usb_ether *ue)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
- urndis_ctrl_init(sc);
-
/* stall data write direction, which depends on USB mode */
usbd_xfer_set_stall(sc->sc_xfer[URNDIS_BULK_TX]);
@@ -369,20 +395,21 @@ urndis_stop(struct usb_ether *ue)
static void
urndis_setmulti(struct usb_ether *ue)
{
+
/* no-op */
- return;
}
static void
urndis_setpromisc(struct usb_ether *ue)
{
+
/* no-op */
- return;
}
static int
urndis_suspend(device_t dev)
{
+
device_printf(dev, "Suspending\n");
return (0);
}
@@ -390,6 +417,7 @@ urndis_suspend(device_t dev)
static int
urndis_resume(device_t dev)
{
+
device_printf(dev, "Resuming\n");
return (0);
}
@@ -416,8 +444,8 @@ urndis_ctrl_send(struct urndis_softc *sc, void *buf, uint16_t len)
{
usb_error_t err;
- err = urndis_ctrl_msg(sc, UT_WRITE_CLASS_INTERFACE, UR_GET_STATUS,
- sc->sc_ifaceno_ctl, 0, buf, len);
+ err = urndis_ctrl_msg(sc, UT_WRITE_CLASS_INTERFACE,
+ UCDC_SEND_ENCAPSULATED_COMMAND, sc->sc_ifaceno_ctl, 0, buf, len);
DPRINTF("%s\n", usbd_errstr(err));
@@ -430,8 +458,9 @@ urndis_ctrl_recv(struct urndis_softc *sc)
struct urndis_comp_hdr *hdr;
usb_error_t err;
- err = urndis_ctrl_msg(sc, UT_READ_CLASS_INTERFACE, UR_CLEAR_FEATURE,
- sc->sc_ifaceno_ctl, 0, sc->sc_response_buf, RNDIS_RESPONSE_LEN);
+ err = urndis_ctrl_msg(sc, UT_READ_CLASS_INTERFACE,
+ UCDC_GET_ENCAPSULATED_RESPONSE, sc->sc_ifaceno_ctl, 0,
+ sc->sc_response_buf, RNDIS_RESPONSE_LEN);
if (err != USB_ERR_NORMAL_COMPLETION)
return (NULL);
@@ -480,7 +509,8 @@ urndis_ctrl_handle(struct urndis_softc *sc, struct urndis_comp_hdr *hdr,
break;
default:
- DPRINTF("ctrl message error: unknown event 0x%x\n",
+ device_printf(sc->sc_ue.ue_dev,
+ "ctrl message error: unknown event 0x%x\n",
le32toh(hdr->rm_type));
rval = RNDIS_STATUS_FAILURE;
break;
@@ -548,10 +578,8 @@ urndis_ctrl_handle_query(struct urndis_softc *sc,
le32toh(msg->rm_infobuflen),
le32toh(msg->rm_infobufoffset));
- if (buf != NULL && bufsz != NULL) {
- *buf = NULL;
- *bufsz = 0;
- }
+ *buf = NULL;
+ *bufsz = 0;
if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) {
DPRINTF("query failed 0x%x\n", le32toh(msg->rm_status));
return (le32toh(msg->rm_status));
@@ -571,10 +599,10 @@ urndis_ctrl_handle_query(struct urndis_softc *sc,
le32toh(msg->rm_len));
return (RNDIS_STATUS_FAILURE);
}
- if (buf != NULL && bufsz != NULL) {
- *buf = ((const uint8_t *)msg) + RNDIS_HEADER_OFFSET + le32toh(msg->rm_infobufoffset);
- *bufsz = le32toh(msg->rm_infobuflen);
- }
+ *buf = ((const uint8_t *)msg) + RNDIS_HEADER_OFFSET +
+ le32toh(msg->rm_infobufoffset);
+ *bufsz = le32toh(msg->rm_infobuflen);
+
return (le32toh(msg->rm_status));
}
@@ -627,7 +655,7 @@ urndis_ctrl_init(struct urndis_softc *sc)
msg.rm_type = htole32(REMOTE_NDIS_INITIALIZE_MSG);
msg.rm_len = htole32(sizeof(msg));
- msg.rm_rid = htole32(0);
+ msg.rm_rid = 0;
msg.rm_ver_major = htole32(1);
msg.rm_ver_minor = htole32(1);
msg.rm_max_xfersz = htole32(RNDIS_RX_MAXLEN);
@@ -656,7 +684,6 @@ urndis_ctrl_init(struct urndis_softc *sc)
return (rval);
}
-#if 0
static uint32_t
urndis_ctrl_halt(struct urndis_softc *sc)
{
@@ -675,39 +702,48 @@ urndis_ctrl_halt(struct urndis_softc *sc)
rval = urndis_ctrl_send(sc, &msg, sizeof(msg));
if (rval != RNDIS_STATUS_SUCCESS)
- printf("halt failed\n");
+ DPRINTF("halt failed\n");
return (rval);
}
-#endif
-
+/*
+ * NB: Querying a device has the requirment of using an input buffer the size
+ * of the expected reply or larger, except for variably sized replies.
+ */
static uint32_t
-urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid, const void **rbuf, uint16_t *rbufsz)
+urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid,
+ struct urndis_query_req *msg, uint16_t len, const void **rbuf,
+ uint16_t *rbufsz)
{
- struct urndis_query_req msg;
- uint32_t rval;
struct urndis_comp_hdr *hdr;
+ uint32_t datalen, rval;
- msg.rm_type = htole32(REMOTE_NDIS_QUERY_MSG);
- msg.rm_len = htole32(sizeof(msg));
- msg.rm_rid = 0; /* XXX */
- msg.rm_oid = htole32(oid);
- msg.rm_infobuflen = htole32(0);
- msg.rm_infobufoffset = 0;
- msg.rm_devicevchdl = 0;
+ msg->rm_type = htole32(REMOTE_NDIS_QUERY_MSG);
+ msg->rm_len = htole32(len);
+ msg->rm_rid = 0; /* XXX */
+ msg->rm_oid = htole32(oid);
+ datalen = len - sizeof(*msg);
+ msg->rm_infobuflen = htole32(datalen);
+ if (datalen != 0) {
+ msg->rm_infobufoffset = htole32(sizeof(*msg) -
+ RNDIS_HEADER_OFFSET);
+ } else {
+ msg->rm_infobufoffset = 0;
+ }
+ msg->rm_devicevchdl = 0;
DPRINTF("type %u len %u rid %u oid 0x%x "
"infobuflen %u infobufoffset %u devicevchdl %u\n",
- le32toh(msg.rm_type),
- le32toh(msg.rm_len),
- le32toh(msg.rm_rid),
- le32toh(msg.rm_oid),
- le32toh(msg.rm_infobuflen),
- le32toh(msg.rm_infobufoffset),
- le32toh(msg.rm_devicevchdl));
+ le32toh(msg->rm_type),
+ le32toh(msg->rm_len),
+ le32toh(msg->rm_rid),
+ le32toh(msg->rm_oid),
+ le32toh(msg->rm_infobuflen),
+ le32toh(msg->rm_infobufoffset),
+ le32toh(msg->rm_devicevchdl));
- rval = urndis_ctrl_send(sc, &msg, sizeof(msg));
+ rval = urndis_ctrl_send(sc, msg, len);
if (rval != RNDIS_STATUS_SUCCESS) {
DPRINTF("query failed\n");
@@ -723,19 +759,21 @@ urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid, const void **rbuf, uint
}
static uint32_t
-urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid, struct urndis_set_req *msg, uint16_t len)
+urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid,
+ struct urndis_set_req *msg, uint16_t len)
{
struct urndis_comp_hdr *hdr;
- uint32_t rval;
- uint32_t datalen = len - sizeof(*msg);
+ uint32_t datalen, rval;
msg->rm_type = htole32(REMOTE_NDIS_SET_MSG);
msg->rm_len = htole32(len);
msg->rm_rid = 0; /* XXX */
msg->rm_oid = htole32(oid);
+ datalen = len - sizeof(*msg);
msg->rm_infobuflen = htole32(datalen);
if (datalen != 0) {
- msg->rm_infobufoffset = htole32(sizeof(*msg) - RNDIS_HEADER_OFFSET);
+ msg->rm_infobufoffset = htole32(sizeof(*msg) -
+ RNDIS_HEADER_OFFSET);
} else {
msg->rm_infobufoffset = 0;
}
@@ -782,13 +820,11 @@ urndis_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
-
usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL);
DPRINTFN(1, "received %u bytes in %u frames\n", actlen, aframes);
for (offset = 0; actlen >= (uint32_t)sizeof(msg);) {
-
/* copy out header */
usbd_copy_out(pc, offset, &msg, sizeof(msg));
@@ -930,7 +966,7 @@ tr_setup:
usbd_xfer_set_frame_offset(xfer, x * RNDIS_TX_MAXLEN, x);
- next_pkt:
+next_pkt:
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
if (m == NULL)
diff --git a/sys/dev/vt/colors/vt_termcolors.c b/sys/dev/vt/colors/vt_termcolors.c
index d8a5909..5075619 100644
--- a/sys/dev/vt/colors/vt_termcolors.c
+++ b/sys/dev/vt/colors/vt_termcolors.c
@@ -25,15 +25,16 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
#include <dev/vt/colors/vt_termcolors.h>
-static struct {
+static const struct {
unsigned char r; /* Red percentage value. */
unsigned char g; /* Green percentage value. */
unsigned char b; /* Blue percentage value. */
@@ -68,8 +69,8 @@ static const int cons_to_vga_colors[16] = {
};
int
-vt_generate_cons_palette(uint32_t *palette, int format, uint32_t rmax, int roffset,
- uint32_t gmax, int goffset, uint32_t bmax, int boffset)
+vt_generate_cons_palette(uint32_t *palette, int format, uint32_t rmax,
+ int roffset, uint32_t gmax, int goffset, uint32_t bmax, int boffset)
{
int i;
diff --git a/sys/modules/hyperv/netvsc/Makefile b/sys/modules/hyperv/netvsc/Makefile
index 472be16..857df82 100644
--- a/sys/modules/hyperv/netvsc/Makefile
+++ b/sys/modules/hyperv/netvsc/Makefile
@@ -6,7 +6,7 @@ KMOD= hv_netvsc
SRCS= hv_net_vsc.c \
hv_netvsc_drv_freebsd.c \
hv_rndis_filter.c
-SRCS+= bus_if.h device_if.h
+SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h
CFLAGS+= -I${.CURDIR}/../../../dev/hyperv/netvsc
diff --git a/sys/modules/rl/Makefile b/sys/modules/rl/Makefile
index e846579..16046ad 100644
--- a/sys/modules/rl/Makefile
+++ b/sys/modules/rl/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/../../pci
+.PATH: ${.CURDIR}/../../dev/rl
KMOD= if_rl
SRCS= if_rl.c device_if.h bus_if.h pci_if.h
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c
index e681bcd..693b3ac 100644
--- a/sys/netgraph/ng_base.c
+++ b/sys/netgraph/ng_base.c
@@ -2971,7 +2971,7 @@ uma_zone_t ng_qzone;
uma_zone_t ng_qdzone;
static int numthreads = 0; /* number of queue threads */
static int maxalloc = 4096;/* limit the damage of a leak */
-static int maxdata = 512; /* limit the damage of a DoS */
+static int maxdata = 4096; /* limit the damage of a DoS */
TUNABLE_INT("net.graph.threads", &numthreads);
SYSCTL_INT(_net_graph, OID_AUTO, threads, CTLFLAG_RDTUN, &numthreads,
diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h
index fb2f810..7e3a1a3 100644
--- a/sys/netinet/tcp.h
+++ b/sys/netinet/tcp.h
@@ -97,6 +97,10 @@ struct tcphdr {
#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
#define TCPOPT_SIGNATURE 19 /* Keyed MD5: RFC 2385 */
#define TCPOLEN_SIGNATURE 18
+#define TCPOPT_FAST_OPEN 34
+#define TCPOLEN_FAST_OPEN_EMPTY 2
+#define TCPOLEN_FAST_OPEN_MIN 6
+#define TCPOLEN_FAST_OPEN_MAX 18
/* Miscellaneous constants */
#define MAX_SACK_BLKS 6 /* Max # SACK blocks stored at receiver side */
@@ -165,6 +169,7 @@ struct tcphdr {
#define TCP_KEEPIDLE 256 /* L,N,X start keeplives after this period */
#define TCP_KEEPINTVL 512 /* L,N interval between keepalives */
#define TCP_KEEPCNT 1024 /* L,N number of keepalives before close */
+#define TCP_FASTOPEN 1025 /* enable TFO / was created via TFO */
/* Start of reserved space for third-party user-settable options. */
#define TCP_VENDOR SO_VENDOR
diff --git a/sys/netinet/tcp_fastopen.c b/sys/netinet/tcp_fastopen.c
new file mode 100644
index 0000000..482320e
--- /dev/null
+++ b/sys/netinet/tcp_fastopen.c
@@ -0,0 +1,442 @@
+/*-
+ * Copyright (c) 2015 Patrick Kelsey
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This is a server-side implementation of TCP Fast Open (TFO) [RFC7413].
+ *
+ * This implementation is currently considered to be experimental and is not
+ * included in kernel builds by default. To include this code, add the
+ * following line to your kernel config:
+ *
+ * options TCP_RFC7413
+ *
+ * The generated TFO cookies are the 64-bit output of
+ * SipHash24(<16-byte-key><client-ip>). Multiple concurrent valid keys are
+ * supported so that time-based rolling cookie invalidation policies can be
+ * implemented in the system. The default number of concurrent keys is 2.
+ * This can be adjusted in the kernel config as follows:
+ *
+ * options TCP_RFC7413_MAX_KEYS=<num-keys>
+ *
+ *
+ * The following TFO-specific sysctls are defined:
+ *
+ * net.inet.tcp.fastopen.acceptany (RW, default 0)
+ * When non-zero, all client-supplied TFO cookies will be considered to
+ * be valid.
+ *
+ * net.inet.tcp.fastopen.autokey (RW, default 120)
+ * When this and net.inet.tcp.fastopen.enabled are non-zero, a new key
+ * will be automatically generated after this many seconds.
+ *
+ * net.inet.tcp.fastopen.enabled (RW, default 0)
+ * When zero, no new TFO connections can be created. On the transition
+ * from enabled to disabled, all installed keys are removed. On the
+ * transition from disabled to enabled, if net.inet.tcp.fastopen.autokey
+ * is non-zero and there are no keys installed, a new key will be
+ * generated immediately. The transition from enabled to disabled does
+ * not affect any TFO connections in progress; it only prevents new ones
+ * from being made.
+ *
+ * net.inet.tcp.fastopen.keylen (RO)
+ * The key length in bytes.
+ *
+ * net.inet.tcp.fastopen.maxkeys (RO)
+ * The maximum number of keys supported.
+ *
+ * net.inet.tcp.fastopen.numkeys (RO)
+ * The current number of keys installed.
+ *
+ * net.inet.tcp.fastopen.setkey (WO)
+ * Install a new key by writing net.inet.tcp.fastopen.keylen bytes to this
+ * sysctl.
+ *
+ *
+ * In order for TFO connections to be created via a listen socket, that
+ * socket must have the TCP_FASTOPEN socket option set on it. This option
+ * can be set on the socket either before or after the listen() is invoked.
+ * Clearing this option on a listen socket after it has been set has no
+ * effect on existing TFO connections or TFO connections in progress; it
+ * only prevents new TFO connections from being made.
+ *
+ * For passively-created sockets, the TCP_FASTOPEN socket option can be
+ * queried to determine whether the connection was established using TFO.
+ * Note that connections that are established via a TFO SYN, but that fall
+ * back to using a non-TFO SYN|ACK will have the TCP_FASTOPEN socket option
+ * set.
+ *
+ * Per the RFC, this implementation limits the number of TFO connections
+ * that can be in the SYN_RECEIVED state on a per listen-socket basis.
+ * Whenever this limit is exceeded, requests for new TFO connections are
+ * serviced as non-TFO requests. Without such a limit, given a valid TFO
+ * cookie, an attacker could keep the listen queue in an overflow condition
+ * using a TFO SYN flood. This implementation sets the limit at half the
+ * configured listen backlog.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_inet.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/rmlock.h>
+#include <sys/socketvar.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+
+#include <crypto/siphash/siphash.h>
+
+#include <net/vnet.h>
+
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_fastopen.h>
+#include <netinet/tcp_var.h>
+
+
+#define TCP_FASTOPEN_KEY_LEN SIPHASH_KEY_LENGTH
+
+#if !defined(TCP_RFC7413_MAX_KEYS) || (TCP_RFC7413_MAX_KEYS < 1)
+#define TCP_FASTOPEN_MAX_KEYS 2
+#else
+#define TCP_FASTOPEN_MAX_KEYS TCP_RFC7413_MAX_KEYS
+#endif
+
+struct tcp_fastopen_keylist {
+ unsigned int newest;
+ uint8_t key[TCP_FASTOPEN_MAX_KEYS][TCP_FASTOPEN_KEY_LEN];
+};
+
+struct tcp_fastopen_callout {
+ struct callout c;
+ struct vnet *v;
+};
+
+SYSCTL_NODE(_net_inet_tcp, OID_AUTO, fastopen, CTLFLAG_RW, 0, "TCP Fast Open");
+
+static VNET_DEFINE(int, tcp_fastopen_acceptany) = 0;
+#define V_tcp_fastopen_acceptany VNET(tcp_fastopen_acceptany)
+SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, acceptany,
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_fastopen_acceptany), 0,
+ "Accept any non-empty cookie");
+
+static VNET_DEFINE(unsigned int, tcp_fastopen_autokey) = 120;
+#define V_tcp_fastopen_autokey VNET(tcp_fastopen_autokey)
+static int sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, autokey,
+ CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0,
+ &sysctl_net_inet_tcp_fastopen_autokey, "IU",
+ "Number of seconds between auto-generation of a new key; zero disables");
+
+VNET_DEFINE(unsigned int, tcp_fastopen_enabled) = 0;
+static int sysctl_net_inet_tcp_fastopen_enabled(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, enabled,
+ CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0,
+ &sysctl_net_inet_tcp_fastopen_enabled, "IU",
+ "Enable/disable TCP Fast Open processing");
+
+SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, keylen,
+ CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_KEY_LEN,
+ "Key length in bytes");
+
+SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, maxkeys,
+ CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_MAX_KEYS,
+ "Maximum number of keys supported");
+
+static VNET_DEFINE(unsigned int, tcp_fastopen_numkeys) = 0;
+#define V_tcp_fastopen_numkeys VNET(tcp_fastopen_numkeys)
+SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, numkeys,
+ CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcp_fastopen_numkeys), 0,
+ "Number of keys installed");
+
+static int sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, setkey,
+ CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_WR, NULL, 0,
+ &sysctl_net_inet_tcp_fastopen_setkey, "",
+ "Install a new key");
+
+static VNET_DEFINE(struct rmlock, tcp_fastopen_keylock);
+#define V_tcp_fastopen_keylock VNET(tcp_fastopen_keylock)
+
+#define TCP_FASTOPEN_KEYS_RLOCK(t) rm_rlock(&V_tcp_fastopen_keylock, (t))
+#define TCP_FASTOPEN_KEYS_RUNLOCK(t) rm_runlock(&V_tcp_fastopen_keylock, (t))
+#define TCP_FASTOPEN_KEYS_WLOCK() rm_wlock(&V_tcp_fastopen_keylock)
+#define TCP_FASTOPEN_KEYS_WUNLOCK() rm_wunlock(&V_tcp_fastopen_keylock)
+
+static VNET_DEFINE(struct tcp_fastopen_keylist, tcp_fastopen_keys);
+#define V_tcp_fastopen_keys VNET(tcp_fastopen_keys)
+
+static VNET_DEFINE(struct tcp_fastopen_callout, tcp_fastopen_autokey_ctx);
+#define V_tcp_fastopen_autokey_ctx VNET(tcp_fastopen_autokey_ctx)
+
+static VNET_DEFINE(uma_zone_t, counter_zone);
+#define V_counter_zone VNET(counter_zone)
+
+void
+tcp_fastopen_init(void)
+{
+ V_counter_zone = uma_zcreate("tfo", sizeof(unsigned int),
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
+ rm_init(&V_tcp_fastopen_keylock, "tfo_keylock");
+ callout_init_rm(&V_tcp_fastopen_autokey_ctx.c,
+ &V_tcp_fastopen_keylock, 0);
+ V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1;
+}
+
+void
+tcp_fastopen_destroy(void)
+{
+ callout_drain(&V_tcp_fastopen_autokey_ctx.c);
+ rm_destroy(&V_tcp_fastopen_keylock);
+ uma_zdestroy(V_counter_zone);
+}
+
+unsigned int *
+tcp_fastopen_alloc_counter(void)
+{
+ unsigned int *counter;
+ counter = uma_zalloc(V_counter_zone, M_NOWAIT);
+ if (counter)
+ *counter = 1;
+ return (counter);
+}
+
+void
+tcp_fastopen_decrement_counter(unsigned int *counter)
+{
+ if (*counter == 1)
+ uma_zfree(V_counter_zone, counter);
+ else
+ atomic_subtract_int(counter, 1);
+}
+
+static void
+tcp_fastopen_addkey_locked(uint8_t *key)
+{
+
+ V_tcp_fastopen_keys.newest++;
+ if (V_tcp_fastopen_keys.newest == TCP_FASTOPEN_MAX_KEYS)
+ V_tcp_fastopen_keys.newest = 0;
+ memcpy(V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest], key,
+ TCP_FASTOPEN_KEY_LEN);
+ if (V_tcp_fastopen_numkeys < TCP_FASTOPEN_MAX_KEYS)
+ V_tcp_fastopen_numkeys++;
+}
+
+static void
+tcp_fastopen_autokey_locked(void)
+{
+ uint8_t newkey[TCP_FASTOPEN_KEY_LEN];
+
+ arc4rand(newkey, TCP_FASTOPEN_KEY_LEN, 0);
+ tcp_fastopen_addkey_locked(newkey);
+}
+
+static void
+tcp_fastopen_autokey_callout(void *arg)
+{
+ struct tcp_fastopen_callout *ctx = arg;
+
+ CURVNET_SET(ctx->v);
+ tcp_fastopen_autokey_locked();
+ callout_reset(&ctx->c, V_tcp_fastopen_autokey * hz,
+ tcp_fastopen_autokey_callout, ctx);
+ CURVNET_RESTORE();
+}
+
+
+static uint64_t
+tcp_fastopen_make_cookie(uint8_t key[SIPHASH_KEY_LENGTH], struct in_conninfo *inc)
+{
+ SIPHASH_CTX ctx;
+ uint64_t siphash;
+
+ SipHash24_Init(&ctx);
+ SipHash_SetKey(&ctx, key);
+ switch (inc->inc_flags & INC_ISIPV6) {
+#ifdef INET
+ case 0:
+ SipHash_Update(&ctx, &inc->inc_faddr, sizeof(inc->inc_faddr));
+ break;
+#endif
+#ifdef INET6
+ case INC_ISIPV6:
+ SipHash_Update(&ctx, &inc->inc6_faddr, sizeof(inc->inc6_faddr));
+ break;
+#endif
+ }
+ SipHash_Final((u_int8_t *)&siphash, &ctx);
+
+ return (siphash);
+}
+
+
+/*
+ * Return values:
+ * -1 the cookie is invalid and no valid cookie is available
+ * 0 the cookie is invalid and the latest cookie has been returned
+ * 1 the cookie is valid and the latest cookie has been returned
+ */
+int
+tcp_fastopen_check_cookie(struct in_conninfo *inc, uint8_t *cookie,
+ unsigned int len, uint64_t *latest_cookie)
+{
+ struct rm_priotracker tracker;
+ unsigned int i, key_index;
+ uint64_t cur_cookie;
+
+ if (V_tcp_fastopen_acceptany) {
+ *latest_cookie = 0;
+ return (1);
+ }
+
+ if (len != TCP_FASTOPEN_COOKIE_LEN) {
+ if (V_tcp_fastopen_numkeys > 0) {
+ *latest_cookie =
+ tcp_fastopen_make_cookie(
+ V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest],
+ inc);
+ return (0);
+ }
+ return (-1);
+ }
+
+ /*
+ * Check against each available key, from newest to oldest.
+ */
+ TCP_FASTOPEN_KEYS_RLOCK(&tracker);
+ key_index = V_tcp_fastopen_keys.newest;
+ for (i = 0; i < V_tcp_fastopen_numkeys; i++) {
+ cur_cookie =
+ tcp_fastopen_make_cookie(V_tcp_fastopen_keys.key[key_index],
+ inc);
+ if (i == 0)
+ *latest_cookie = cur_cookie;
+ if (memcmp(cookie, &cur_cookie, TCP_FASTOPEN_COOKIE_LEN) == 0) {
+ TCP_FASTOPEN_KEYS_RUNLOCK(&tracker);
+ return (1);
+ }
+ if (key_index == 0)
+ key_index = TCP_FASTOPEN_MAX_KEYS - 1;
+ else
+ key_index--;
+ }
+ TCP_FASTOPEN_KEYS_RUNLOCK(&tracker);
+
+ return (0);
+}
+
+static int
+sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ unsigned int new;
+
+ new = V_tcp_fastopen_autokey;
+ error = sysctl_handle_int(oidp, &new, 0, req);
+ if (error == 0 && req->newptr) {
+ if (new > (INT_MAX / hz))
+ return (EINVAL);
+
+ TCP_FASTOPEN_KEYS_WLOCK();
+ if (V_tcp_fastopen_enabled) {
+ if (V_tcp_fastopen_autokey && !new)
+ callout_stop(&V_tcp_fastopen_autokey_ctx.c);
+ else if (new)
+ callout_reset(&V_tcp_fastopen_autokey_ctx.c,
+ new * hz, tcp_fastopen_autokey_callout,
+ &V_tcp_fastopen_autokey_ctx);
+ }
+ V_tcp_fastopen_autokey = new;
+ TCP_FASTOPEN_KEYS_WUNLOCK();
+ }
+
+ return (error);
+}
+
+static int
+sysctl_net_inet_tcp_fastopen_enabled(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ unsigned int new;
+
+ new = V_tcp_fastopen_enabled;
+ error = sysctl_handle_int(oidp, &new, 0, req);
+ if (error == 0 && req->newptr) {
+ if (V_tcp_fastopen_enabled && !new) {
+ /* enabled -> disabled */
+ TCP_FASTOPEN_KEYS_WLOCK();
+ V_tcp_fastopen_numkeys = 0;
+ V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1;
+ if (V_tcp_fastopen_autokey)
+ callout_stop(&V_tcp_fastopen_autokey_ctx.c);
+ V_tcp_fastopen_enabled = 0;
+ TCP_FASTOPEN_KEYS_WUNLOCK();
+ } else if (!V_tcp_fastopen_enabled && new) {
+ /* disabled -> enabled */
+ TCP_FASTOPEN_KEYS_WLOCK();
+ if (V_tcp_fastopen_autokey &&
+ (V_tcp_fastopen_numkeys == 0)) {
+ tcp_fastopen_autokey_locked();
+ callout_reset(&V_tcp_fastopen_autokey_ctx.c,
+ V_tcp_fastopen_autokey * hz,
+ tcp_fastopen_autokey_callout,
+ &V_tcp_fastopen_autokey_ctx);
+ }
+ V_tcp_fastopen_enabled = 1;
+ TCP_FASTOPEN_KEYS_WUNLOCK();
+ }
+ }
+ return (error);
+}
+
+static int
+sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ uint8_t newkey[TCP_FASTOPEN_KEY_LEN];
+
+ if (req->oldptr != NULL || req->oldlen != 0)
+ return (EINVAL);
+ if (req->newptr == NULL)
+ return (EPERM);
+ if (req->newlen != sizeof(newkey))
+ return (EINVAL);
+ error = SYSCTL_IN(req, newkey, sizeof(newkey));
+ if (error)
+ return (error);
+
+ TCP_FASTOPEN_KEYS_WLOCK();
+ tcp_fastopen_addkey_locked(newkey);
+ TCP_FASTOPEN_KEYS_WUNLOCK();
+
+ return (0);
+}
diff --git a/sys/netinet/tcp_fastopen.h b/sys/netinet/tcp_fastopen.h
new file mode 100644
index 0000000..c64ba2c
--- /dev/null
+++ b/sys/netinet/tcp_fastopen.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2015 Patrick Kelsey
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _TCP_FASTOPEN_H_
+#define _TCP_FASTOPEN_H_
+
+#ifdef _KERNEL
+
+#define TCP_FASTOPEN_COOKIE_LEN 8 /* tied to SipHash24 64-bit output */
+
+VNET_DECLARE(unsigned int, tcp_fastopen_enabled);
+#define V_tcp_fastopen_enabled VNET(tcp_fastopen_enabled)
+
+void tcp_fastopen_init(void);
+void tcp_fastopen_destroy(void);
+unsigned int *tcp_fastopen_alloc_counter(void);
+void tcp_fastopen_decrement_counter(unsigned int *counter);
+int tcp_fastopen_check_cookie(struct in_conninfo *inc, uint8_t *cookie,
+ unsigned int len, uint64_t *latest_cookie);
+#endif /* _KERNEL */
+
+#endif /* _TCP_FASTOPEN_H_ */
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 631cd2e..a59874e 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -98,6 +98,9 @@ __FBSDID("$FreeBSD$");
#include <netinet6/in6_pcb.h>
#include <netinet6/ip6_var.h>
#include <netinet6/nd6.h>
+#ifdef TCP_RFC7413
+#include <netinet/tcp_fastopen.h>
+#endif
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
#include <netinet/tcp_timer.h>
@@ -1070,6 +1073,9 @@ relocked:
rstreason = BANDLIM_RST_OPENPORT;
goto dropwithreset;
}
+#ifdef TCP_RFC7413
+new_tfo_socket:
+#endif
if (so == NULL) {
/*
* We completed the 3-way handshake
@@ -1327,7 +1333,12 @@ relocked:
(void *)tcp_saveipgen, &tcp_savetcp, 0);
#endif
tcp_dooptions(&to, optp, optlen, TO_SYN);
+#ifdef TCP_RFC7413
+ if (syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL))
+ goto new_tfo_socket;
+#else
syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL);
+#endif
/*
* Entry added to syncache and mbuf consumed.
* Everything already unlocked by syncache_add().
@@ -1437,6 +1448,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
struct in_conninfo *inc;
struct mbuf *mfree;
struct tcpopt to;
+ int tfo_syn;
#ifdef TCPDEBUG
/*
@@ -1876,6 +1888,28 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
rstreason = BANDLIM_RST_OPENPORT;
goto dropwithreset;
}
+#ifdef TCP_RFC7413
+ if (tp->t_flags & TF_FASTOPEN) {
+ /*
+ * When a TFO connection is in SYN_RECEIVED, the
+ * only valid packets are the initial SYN, a
+ * retransmit/copy of the initial SYN (possibly with
+ * a subset of the original data), a valid ACK, a
+ * FIN, or a RST.
+ */
+ if ((thflags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) {
+ rstreason = BANDLIM_RST_OPENPORT;
+ goto dropwithreset;
+ } else if (thflags & TH_SYN) {
+ /* non-initial SYN is ignored */
+ if ((tcp_timer_active(tp, TT_DELACK) ||
+ tcp_timer_active(tp, TT_REXMT)))
+ goto drop;
+ } else if (!(thflags & (TH_ACK|TH_FIN|TH_RST))) {
+ goto drop;
+ }
+ }
+#endif
break;
/*
@@ -2316,9 +2350,16 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
if ((thflags & TH_ACK) == 0) {
if (tp->t_state == TCPS_SYN_RECEIVED ||
- (tp->t_flags & TF_NEEDSYN))
+ (tp->t_flags & TF_NEEDSYN)) {
+#ifdef TCP_RFC7413
+ if (tp->t_state == TCPS_SYN_RECEIVED &&
+ tp->t_flags & TF_FASTOPEN) {
+ tp->snd_wnd = tiwin;
+ cc_conn_init(tp);
+ }
+#endif
goto step6;
- else if (tp->t_flags & TF_ACKNOW)
+ } else if (tp->t_flags & TF_ACKNOW)
goto dropafterack;
else
goto drop;
@@ -2357,7 +2398,27 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
tcp_state_change(tp, TCPS_ESTABLISHED);
TCP_PROBE5(accept__established, NULL, tp,
mtod(m, const char *), tp, th);
- cc_conn_init(tp);
+#ifdef TCP_RFC7413
+ if (tp->t_tfo_pending) {
+ tcp_fastopen_decrement_counter(tp->t_tfo_pending);
+ tp->t_tfo_pending = NULL;
+
+ /*
+ * Account for the ACK of our SYN prior to
+ * regular ACK processing below.
+ */
+ tp->snd_una++;
+ }
+ /*
+ * TFO connections call cc_conn_init() during SYN
+ * processing. Calling it again here for such
+ * connections is not harmless as it would undo the
+ * snd_cwnd reduction that occurs when a TFO SYN|ACK
+ * is retransmitted.
+ */
+ if (!(tp->t_flags & TF_FASTOPEN))
+#endif
+ cc_conn_init(tp);
tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp));
}
/*
@@ -2888,9 +2949,12 @@ dodata: /* XXX */
* case PRU_RCVD). If a FIN has already been received on this
* connection then we just ignore the text.
*/
- if ((tlen || (thflags & TH_FIN)) &&
+ tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) &&
+ (tp->t_flags & TF_FASTOPEN));
+ if ((tlen || (thflags & TH_FIN) || tfo_syn) &&
TCPS_HAVERCVDFIN(tp->t_state) == 0) {
tcp_seq save_start = th->th_seq;
+
m_adj(m, drop_hdrlen); /* delayed header drop */
/*
* Insert segment which includes th into TCP reassembly queue
@@ -2906,8 +2970,9 @@ dodata: /* XXX */
*/
if (th->th_seq == tp->rcv_nxt &&
LIST_EMPTY(&tp->t_segq) &&
- TCPS_HAVEESTABLISHED(tp->t_state)) {
- if (DELAY_ACK(tp, tlen))
+ (TCPS_HAVEESTABLISHED(tp->t_state) ||
+ tfo_syn)) {
+ if (DELAY_ACK(tp, tlen) || tfo_syn)
tp->t_flags |= TF_DELACK;
else
tp->t_flags |= TF_ACKNOW;
@@ -3260,6 +3325,21 @@ tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, int flags)
to->to_sacks = cp + 2;
TCPSTAT_INC(tcps_sack_rcv_blocks);
break;
+#ifdef TCP_RFC7413
+ case TCPOPT_FAST_OPEN:
+ if ((optlen != TCPOLEN_FAST_OPEN_EMPTY) &&
+ (optlen < TCPOLEN_FAST_OPEN_MIN) &&
+ (optlen > TCPOLEN_FAST_OPEN_MAX))
+ continue;
+ if (!(flags & TO_SYN))
+ continue;
+ if (!V_tcp_fastopen_enabled)
+ continue;
+ to->to_flags |= TOF_FASTOPEN;
+ to->to_tfo_len = optlen - 2;
+ to->to_tfo_cookie = to->to_tfo_len ? cp + 2 : NULL;
+ break;
+#endif
default:
continue;
}
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index f1196e1..c7dc547 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -69,6 +69,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#endif
+#ifdef TCP_RFC7413
+#include <netinet/tcp_fastopen.h>
+#endif
#define TCPOUTFLAGS
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
@@ -202,6 +205,17 @@ tcp_output(struct tcpcb *tp)
return (tcp_offload_output(tp));
#endif
+#ifdef TCP_RFC7413
+ /*
+ * For TFO connections in SYN_RECEIVED, only allow the initial
+ * SYN|ACK and those sent by the retransmit timer.
+ */
+ if ((tp->t_flags & TF_FASTOPEN) &&
+ (tp->t_state == TCPS_SYN_RECEIVED) &&
+ SEQ_GT(tp->snd_max, tp->snd_una) && /* inital SYN|ACK sent */
+ (tp->snd_nxt != tp->snd_una)) /* not a retransmit */
+ return (0);
+#endif
/*
* Determine length of data that should be transmitted,
* and flags that will be used.
@@ -387,6 +401,15 @@ after_sack_rexmit:
if ((flags & TH_SYN) && SEQ_GT(tp->snd_nxt, tp->snd_una)) {
if (tp->t_state != TCPS_SYN_RECEIVED)
flags &= ~TH_SYN;
+#ifdef TCP_RFC7413
+ /*
+ * When sending additional segments following a TFO SYN|ACK,
+ * do not include the SYN bit.
+ */
+ if ((tp->t_flags & TF_FASTOPEN) &&
+ (tp->t_state == TCPS_SYN_RECEIVED))
+ flags &= ~TH_SYN;
+#endif
off--, len++;
}
@@ -400,6 +423,17 @@ after_sack_rexmit:
flags &= ~TH_FIN;
}
+#ifdef TCP_RFC7413
+ /*
+ * When retransmitting SYN|ACK on a passively-created TFO socket,
+ * don't include data, as the presence of data may have caused the
+ * original SYN|ACK to have been dropped by a middlebox.
+ */
+ if ((tp->t_flags & TF_FASTOPEN) &&
+ (((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_rxtshift > 0)) ||
+ (flags & TH_RST)))
+ len = 0;
+#endif
if (len <= 0) {
/*
* If FIN has been sent but not acked,
@@ -718,6 +752,22 @@ send:
tp->snd_nxt = tp->iss;
to.to_mss = tcp_mssopt(&tp->t_inpcb->inp_inc);
to.to_flags |= TOF_MSS;
+#ifdef TCP_RFC7413
+ /*
+ * Only include the TFO option on the first
+ * transmission of the SYN|ACK on a
+ * passively-created TFO socket, as the presence of
+ * the TFO option may have caused the original
+ * SYN|ACK to have been dropped by a middlebox.
+ */
+ if ((tp->t_flags & TF_FASTOPEN) &&
+ (tp->t_state == TCPS_SYN_RECEIVED) &&
+ (tp->t_rxtshift == 0)) {
+ to.to_tfo_len = TCP_FASTOPEN_COOKIE_LEN;
+ to.to_tfo_cookie = (u_char *)&tp->t_tfo_cookie;
+ to.to_flags |= TOF_FASTOPEN;
+ }
+#endif
}
/* Window scaling. */
if ((flags & TH_SYN) && (tp->t_flags & TF_REQ_SCALE)) {
@@ -997,7 +1047,7 @@ send:
* give data to the user when a buffer fills or
* a PUSH comes in.)
*/
- if (off + len == so->so_snd.sb_cc)
+ if ((off + len == so->so_snd.sb_cc) && !(flags & TH_SYN))
flags |= TH_PUSH;
SOCKBUF_UNLOCK(&so->so_snd);
} else {
@@ -1694,6 +1744,25 @@ tcp_addoptions(struct tcpopt *to, u_char *optp)
TCPSTAT_INC(tcps_sack_send_blocks);
break;
}
+#ifdef TCP_RFC7413
+ case TOF_FASTOPEN:
+ {
+ int total_len;
+
+ /* XXX is there any point to aligning this option? */
+ total_len = TCPOLEN_FAST_OPEN_EMPTY + to->to_tfo_len;
+ if (TCP_MAXOLEN - optlen < total_len)
+ continue;
+ *optp++ = TCPOPT_FAST_OPEN;
+ *optp++ = total_len;
+ if (to->to_tfo_len > 0) {
+ bcopy(to->to_tfo_cookie, optp, to->to_tfo_len);
+ optp += to->to_tfo_len;
+ }
+ optlen += total_len;
+ break;
+ }
+#endif
default:
panic("%s: unknown TCP option type", __func__);
break;
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 7bdd573..3ce21a9 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -83,6 +83,9 @@ __FBSDID("$FreeBSD$");
#include <netinet6/nd6.h>
#endif
+#ifdef TCP_RFC7413
+#include <netinet/tcp_fastopen.h>
+#endif
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
#include <netinet/tcp_timer.h>
@@ -427,6 +430,10 @@ tcp_init(void)
SHUTDOWN_PRI_DEFAULT);
EVENTHANDLER_REGISTER(maxsockets_change, tcp_zone_change, NULL,
EVENTHANDLER_PRI_ANY);
+
+#ifdef TCP_RFC7413
+ tcp_fastopen_init();
+#endif
}
#ifdef VIMAGE
@@ -434,6 +441,9 @@ void
tcp_destroy(void)
{
+#ifdef TCP_RFC7413
+ tcp_fastopen_destroy();
+#endif
tcp_hc_destroy();
syncache_destroy();
tcp_tw_destroy();
@@ -1102,6 +1112,17 @@ tcp_close(struct tcpcb *tp)
if (tp->t_state == TCPS_LISTEN)
tcp_offload_listen_stop(tp);
#endif
+#ifdef TCP_RFC7413
+ /*
+ * This releases the TFO pending counter resource for TFO listen
+ * sockets as well as passively-created TFO sockets that transition
+ * from SYN_RECEIVED to CLOSED.
+ */
+ if (tp->t_tfo_pending) {
+ tcp_fastopen_decrement_counter(tp->t_tfo_pending);
+ tp->t_tfo_pending = NULL;
+ }
+#endif
in_pcbdrop(inp);
TCPSTAT_INC(tcps_closed);
KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL"));
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 9896788..8d2cc98 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -78,6 +78,9 @@ __FBSDID("$FreeBSD$");
#include <netinet6/in6_pcb.h>
#endif
#include <netinet/tcp.h>
+#ifdef TCP_RFC7413
+#include <netinet/tcp_fastopen.h>
+#endif
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
#include <netinet/tcp_timer.h>
@@ -1089,6 +1092,39 @@ failed:
return (0);
}
+#ifdef TCP_RFC7413
+static void
+syncache_tfo_expand(struct syncache *sc, struct socket **lsop, struct mbuf *m,
+ uint64_t response_cookie)
+{
+ struct inpcb *inp;
+ struct tcpcb *tp;
+ unsigned int *pending_counter;
+
+ /*
+ * Global TCP locks are held because we manipulate the PCB lists
+ * and create a new socket.
+ */
+ INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
+
+ pending_counter = intotcpcb(sotoinpcb(*lsop))->t_tfo_pending;
+ *lsop = syncache_socket(sc, *lsop, m);
+ if (*lsop == NULL) {
+ TCPSTAT_INC(tcps_sc_aborted);
+ atomic_subtract_int(pending_counter, 1);
+ } else {
+ inp = sotoinpcb(*lsop);
+ tp = intotcpcb(inp);
+ tp->t_flags |= TF_FASTOPEN;
+ tp->t_tfo_cookie = response_cookie;
+ tp->snd_max = tp->iss;
+ tp->snd_nxt = tp->iss;
+ tp->t_tfo_pending = pending_counter;
+ TCPSTAT_INC(tcps_sc_completed);
+ }
+}
+#endif /* TCP_RFC7413 */
+
/*
* Given a LISTEN socket and an inbound SYN request, add
* this to the syn cache, and send back a segment:
@@ -1101,8 +1137,15 @@ failed:
* DoS attack, an attacker could send data which would eventually
* consume all available buffer space if it were ACKed. By not ACKing
* the data, we avoid this DoS scenario.
+ *
+ * The exception to the above is when a SYN with a valid TCP Fast Open (TFO)
+ * cookie is processed, V_tcp_fastopen_enabled set to true, and the
+ * TCP_FASTOPEN socket option is set. In this case, a new socket is created
+ * and returned via lsop, the mbuf is not freed so that tcp_input() can
+ * queue its data to the socket, and 1 is returned to indicate the
+ * TFO-socket-creation path was taken.
*/
-void
+int
syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
struct inpcb *inp, struct socket **lsop, struct mbuf *m, void *tod,
void *todctx)
@@ -1115,6 +1158,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
u_int ltflags;
int win, sb_hiwat, ip_ttl, ip_tos;
char *s;
+ int rv = 0;
#ifdef INET6
int autoflowlabel = 0;
#endif
@@ -1123,6 +1167,11 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
#endif
struct syncache scs;
struct ucred *cred;
+#ifdef TCP_RFC7413
+ uint64_t tfo_response_cookie;
+ int tfo_cookie_valid = 0;
+ int tfo_response_cookie_valid = 0;
+#endif
INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
INP_WLOCK_ASSERT(inp); /* listen socket */
@@ -1148,6 +1197,29 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
sb_hiwat = so->so_rcv.sb_hiwat;
ltflags = (tp->t_flags & (TF_NOOPT | TF_SIGNATURE));
+#ifdef TCP_RFC7413
+ if (V_tcp_fastopen_enabled && (tp->t_flags & TF_FASTOPEN) &&
+ (tp->t_tfo_pending != NULL) && (to->to_flags & TOF_FASTOPEN)) {
+ /*
+ * Limit the number of pending TFO connections to
+ * approximately half of the queue limit. This prevents TFO
+ * SYN floods from starving the service by filling the
+ * listen queue with bogus TFO connections.
+ */
+ if (atomic_fetchadd_int(tp->t_tfo_pending, 1) <=
+ (so->so_qlimit / 2)) {
+ int result;
+
+ result = tcp_fastopen_check_cookie(inc,
+ to->to_tfo_cookie, to->to_tfo_len,
+ &tfo_response_cookie);
+ tfo_cookie_valid = (result > 0);
+ tfo_response_cookie_valid = (result >= 0);
+ } else
+ atomic_subtract_int(tp->t_tfo_pending, 1);
+ }
+#endif
+
/* By the time we drop the lock these should no longer be used. */
so = NULL;
tp = NULL;
@@ -1160,9 +1232,16 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
} else
mac_syncache_create(maclabel, inp);
#endif
+#ifdef TCP_RFC7413
+ if (!tfo_cookie_valid) {
+ INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&V_tcbinfo);
+ }
+#else
INP_WUNLOCK(inp);
INP_INFO_WUNLOCK(&V_tcbinfo);
-
+#endif
+
/*
* Remember the IP options, if any.
*/
@@ -1190,6 +1269,12 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
sc = syncache_lookup(inc, &sch); /* returns locked entry */
SCH_LOCK_ASSERT(sch);
if (sc != NULL) {
+#ifdef TCP_RFC7413
+ if (tfo_cookie_valid) {
+ INP_WUNLOCK(inp);
+ INP_INFO_WUNLOCK(&V_tcbinfo);
+ }
+#endif
TCPSTAT_INC(tcps_sc_dupsyn);
if (ipopts) {
/*
@@ -1232,6 +1317,14 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
goto done;
}
+#ifdef TCP_RFC7413
+ if (tfo_cookie_valid) {
+ bzero(&scs, sizeof(scs));
+ sc = &scs;
+ goto skip_alloc;
+ }
+#endif
+
sc = uma_zalloc(V_tcp_syncache.zone, M_NOWAIT | M_ZERO);
if (sc == NULL) {
/*
@@ -1255,7 +1348,13 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
}
}
}
-
+
+#ifdef TCP_RFC7413
+skip_alloc:
+ if (!tfo_cookie_valid && tfo_response_cookie_valid)
+ sc->sc_tfo_cookie = &tfo_response_cookie;
+#endif
+
/*
* Fill in the syncache values.
*/
@@ -1365,6 +1464,15 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
#endif
SCH_UNLOCK(sch);
+#ifdef TCP_RFC7413
+ if (tfo_cookie_valid) {
+ syncache_tfo_expand(sc, lsop, m, tfo_response_cookie);
+ /* INP_WUNLOCK(inp) will be performed by the called */
+ rv = 1;
+ goto tfo_done;
+ }
+#endif
+
/*
* Do a standard 3-way handshake.
*/
@@ -1382,17 +1490,20 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
}
done:
+ if (m) {
+ *lsop = NULL;
+ m_freem(m);
+ }
+#ifdef TCP_RFC7413
+tfo_done:
+#endif
if (cred != NULL)
crfree(cred);
#ifdef MAC
if (sc == &scs)
mac_syncache_destroy(&maclabel);
#endif
- if (m) {
-
- *lsop = NULL;
- m_freem(m);
- }
+ return (rv);
}
static int
@@ -1520,6 +1631,16 @@ syncache_respond(struct syncache *sc)
if (sc->sc_flags & SCF_SIGNATURE)
to.to_flags |= TOF_SIGNATURE;
#endif
+
+#ifdef TCP_RFC7413
+ if (sc->sc_tfo_cookie) {
+ to.to_flags |= TOF_FASTOPEN;
+ to.to_tfo_len = TCP_FASTOPEN_COOKIE_LEN;
+ to.to_tfo_cookie = sc->sc_tfo_cookie;
+ /* don't send cookie again when retransmitting response */
+ sc->sc_tfo_cookie = NULL;
+ }
+#endif
optlen = tcp_addoptions(&to, (u_char *)(th + 1));
/* Adjust headers by option size. */
diff --git a/sys/netinet/tcp_syncache.h b/sys/netinet/tcp_syncache.h
index fb9a6c6..d56afb6 100644
--- a/sys/netinet/tcp_syncache.h
+++ b/sys/netinet/tcp_syncache.h
@@ -41,7 +41,7 @@ void syncache_destroy(void);
void syncache_unreach(struct in_conninfo *, struct tcphdr *);
int syncache_expand(struct in_conninfo *, struct tcpopt *,
struct tcphdr *, struct socket **, struct mbuf *);
-void syncache_add(struct in_conninfo *, struct tcpopt *,
+int syncache_add(struct in_conninfo *, struct tcpopt *,
struct tcphdr *, struct inpcb *, struct socket **, struct mbuf *,
void *, void *);
void syncache_chkrst(struct in_conninfo *, struct tcphdr *);
@@ -74,7 +74,9 @@ struct syncache {
#endif
struct label *sc_label; /* MAC label reference */
struct ucred *sc_cred; /* cred cache for jail checks */
-
+#ifdef TCP_RFC7413
+ void *sc_tfo_cookie; /* for TCP Fast Open response */
+#endif
void *sc_pspare; /* TCP_SIGNATURE */
u_int32_t sc_spare[2]; /* UTO */
};
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 3dc3a81..c66cb76 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -596,7 +596,8 @@ tcp_timer_rexmt(void * xtp)
} else
tp->t_flags &= ~TF_PREVVALID;
TCPSTAT_INC(tcps_rexmttimeo);
- if (tp->t_state == TCPS_SYN_SENT)
+ if ((tp->t_state == TCPS_SYN_SENT) ||
+ (tp->t_state == TCPS_SYN_RECEIVED))
rexmt = TCPTV_RTOBASE * tcp_syn_backoff[tp->t_rxtshift];
else
rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index c848306..1ccbf9a 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -79,6 +79,9 @@ __FBSDID("$FreeBSD$");
#include <netinet6/ip6_var.h>
#include <netinet6/scope6_var.h>
#endif
+#ifdef TCP_RFC7413
+#include <netinet/tcp_fastopen.h>
+#endif
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
#include <netinet/tcp_timer.h>
@@ -391,6 +394,10 @@ tcp_usr_listen(struct socket *so, int backlog, struct thread *td)
}
SOCK_UNLOCK(so);
+#ifdef TCP_RFC7413
+ if (tp->t_flags & TF_FASTOPEN)
+ tp->t_tfo_pending = tcp_fastopen_alloc_counter();
+#endif
out:
TCPDEBUG2(PRU_LISTEN);
INP_WUNLOCK(inp);
@@ -436,6 +443,10 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
}
SOCK_UNLOCK(so);
+#ifdef TCP_RFC7413
+ if (tp->t_flags & TF_FASTOPEN)
+ tp->t_tfo_pending = tcp_fastopen_alloc_counter();
+#endif
out:
TCPDEBUG2(PRU_LISTEN);
INP_WUNLOCK(inp);
@@ -791,6 +802,18 @@ tcp_usr_rcvd(struct socket *so, int flags)
}
tp = intotcpcb(inp);
TCPDEBUG1();
+#ifdef TCP_RFC7413
+ /*
+ * For passively-created TFO connections, don't attempt a window
+ * update while still in SYN_RECEIVED as this may trigger an early
+ * SYN|ACK. It is preferable to have the SYN|ACK be sent along with
+ * application response data, or failing that, when the DELACK timer
+ * expires.
+ */
+ if ((tp->t_flags & TF_FASTOPEN) &&
+ (tp->t_state == TCPS_SYN_RECEIVED))
+ goto out;
+#endif
#ifdef TCP_OFFLOAD
if (tp->t_flags & TF_TOE)
tcp_offload_rcvd(tp);
@@ -1558,6 +1581,29 @@ unlock_and_done:
TP_MAXIDLE(tp));
goto unlock_and_done;
+#ifdef TCP_RFC7413
+ case TCP_FASTOPEN:
+ INP_WUNLOCK(inp);
+ if (!V_tcp_fastopen_enabled)
+ return (EPERM);
+
+ error = sooptcopyin(sopt, &optval, sizeof optval,
+ sizeof optval);
+ if (error)
+ return (error);
+
+ INP_WLOCK_RECHECK(inp);
+ if (optval) {
+ tp->t_flags |= TF_FASTOPEN;
+ if ((tp->t_state == TCPS_LISTEN) &&
+ (tp->t_tfo_pending == NULL))
+ tp->t_tfo_pending =
+ tcp_fastopen_alloc_counter();
+ } else
+ tp->t_flags &= ~TF_FASTOPEN;
+ goto unlock_and_done;
+#endif
+
default:
INP_WUNLOCK(inp);
error = ENOPROTOOPT;
@@ -1628,6 +1674,13 @@ unlock_and_done:
INP_WUNLOCK(inp);
error = sooptcopyout(sopt, &ui, sizeof(ui));
break;
+#ifdef TCP_RFC7413
+ case TCP_FASTOPEN:
+ optval = tp->t_flags & TF_FASTOPEN;
+ INP_WUNLOCK(inp);
+ error = sooptcopyout(sopt, &optval, sizeof optval);
+ break;
+#endif
default:
INP_WUNLOCK(inp);
error = ENOPROTOOPT;
@@ -1951,6 +2004,10 @@ db_print_tflags(u_int t_flags)
db_printf("%sTF_ECN_PERMIT", comma ? ", " : "");
comma = 1;
}
+ if (t_flags & TF_FASTOPEN) {
+ db_printf("%sTF_FASTOPEN", comma ? ", " : "");
+ comma = 1;
+ }
}
static void
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 758f2c5..cff81c5 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -213,8 +213,18 @@ struct tcpcb {
u_int t_flags2; /* More tcpcb flags storage */
uint32_t t_ispare[6]; /* 5 UTO, 1 TBD */
+#if defined(_KERNEL) && defined(TCP_RFC7413)
+ void *t_pspare2[3]; /* 1 TCP_SIGNATURE, 2 TBD */
+ unsigned int *t_tfo_pending; /* TCP Fast Open pending counter */
+#else
void *t_pspare2[4]; /* 1 TCP_SIGNATURE, 3 TBD */
+#endif
+#if defined(_KERNEL) && defined(TCP_RFC7413)
+ uint64_t _pad[4]; /* 4 TBD (1-2 CC/RTT?) */
+ uint64_t t_tfo_cookie; /* TCP Fast Open cookie */
+#else
uint64_t _pad[5]; /* 5 TBD (1-2 CC/RTT?) */
+#endif
uint32_t t_tsomaxsegcount; /* TSO maximum segment count */
uint32_t t_tsomaxsegsize; /* TSO maximum segment size in bytes */
};
@@ -251,6 +261,7 @@ struct tcpcb {
#define TF_ECN_SND_ECE 0x10000000 /* ECN ECE in queue */
#define TF_CONGRECOVERY 0x20000000 /* congestion recovery mode */
#define TF_WASCRECOVERY 0x40000000 /* was in congestion recovery */
+#define TF_FASTOPEN 0x80000000 /* TCP Fast Open indication */
#define IN_FASTRECOVERY(t_flags) (t_flags & TF_FASTRECOVERY)
#define ENTER_FASTRECOVERY(t_flags) t_flags |= TF_FASTRECOVERY
@@ -310,14 +321,17 @@ struct tcpopt {
#define TOF_TS 0x0010 /* timestamp */
#define TOF_SIGNATURE 0x0040 /* TCP-MD5 signature option (RFC2385) */
#define TOF_SACK 0x0080 /* Peer sent SACK option */
-#define TOF_MAXOPT 0x0100
+#define TOF_FASTOPEN 0x0100 /* TCP Fast Open (TFO) cookie */
+#define TOF_MAXOPT 0x0200
u_int32_t to_tsval; /* new timestamp */
u_int32_t to_tsecr; /* reflected timestamp */
u_char *to_sacks; /* pointer to the first SACK blocks */
u_char *to_signature; /* pointer to the TCP-MD5 signature */
+ u_char *to_tfo_cookie; /* pointer to the TFO cookie */
u_int16_t to_mss; /* maximum segment size */
u_int8_t to_wscale; /* window scaling */
u_int8_t to_nsacks; /* number of SACK blocks */
+ u_int8_t to_tfo_len; /* TFO cookie length */
u_int32_t to_spare; /* UTO */
};
diff --git a/sys/sparc64/ebus/ebus.c b/sys/sparc64/ebus/ebus.c
index 93ad342..0967c5d 100644
--- a/sys/sparc64/ebus/ebus.c
+++ b/sys/sparc64/ebus/ebus.c
@@ -69,7 +69,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
-
#include <sys/rman.h>
#include <dev/ofw/ofw_bus.h>
@@ -294,7 +293,7 @@ ebus_nexus_attach(device_t dev)
sc->sc_nrange = OF_getprop_alloc(node, "ranges",
sizeof(struct ebus_nexus_ranges), &sc->sc_range);
if (sc->sc_nrange == -1) {
- printf("%s: could not get ranges property\n", __func__);
+ device_printf(dev, "could not get ranges property\n");
return (ENXIO);
}
return (ebus_attach(dev, sc, node));
@@ -306,6 +305,7 @@ ebus_pci_attach(device_t dev)
struct ebus_softc *sc;
struct ebus_rinfo *eri;
struct resource *res;
+ struct isa_ranges *range;
phandle_t node;
int i, rnum, rid;
@@ -322,7 +322,7 @@ ebus_pci_attach(device_t dev)
sc->sc_nrange = OF_getprop_alloc(node, "ranges",
sizeof(struct isa_ranges), &sc->sc_range);
if (sc->sc_nrange == -1) {
- printf("%s: could not get ranges property\n", __func__);
+ device_printf(dev, "could not get ranges property\n");
return (ENXIO);
}
@@ -332,21 +332,34 @@ ebus_pci_attach(device_t dev)
/* For every range, there must be a matching resource. */
for (rnum = 0; rnum < sc->sc_nrange; rnum++) {
eri = &sc->sc_rinfo[rnum];
- eri->eri_rtype = ofw_isa_range_restype(
- &((struct isa_ranges *)sc->sc_range)[rnum]);
+ range = &((struct isa_ranges *)sc->sc_range)[rnum];
+ eri->eri_rtype = ofw_isa_range_restype(range);
rid = PCIR_BAR(rnum);
res = bus_alloc_resource_any(dev, eri->eri_rtype, &rid,
RF_ACTIVE);
if (res == NULL) {
- printf("%s: failed to allocate range resource!\n",
- __func__);
+ device_printf(dev,
+ "could not allocate range resource %d\n", rnum);
+ goto fail;
+ }
+ if (rman_get_start(res) != ISA_RANGE_PHYS(range)) {
+ device_printf(dev,
+ "mismatch in start of range %d (0x%lx/0x%lx)\n",
+ rnum, rman_get_start(res), ISA_RANGE_PHYS(range));
+ goto fail;
+ }
+ if (rman_get_size(res) != range->size) {
+ device_printf(dev,
+ "mismatch in size of range %d (0x%lx/0x%x)\n",
+ rnum, rman_get_size(res), range->size);
goto fail;
}
eri->eri_res = res;
eri->eri_rman.rm_type = RMAN_ARRAY;
eri->eri_rman.rm_descr = "EBus range";
if (rman_init_from_resource(&eri->eri_rman, res) != 0) {
- printf("%s: failed to initialize rman!", __func__);
+ device_printf(dev,
+ "could not initialize rman for range %d", rnum);
goto fail;
}
}
@@ -452,7 +465,7 @@ ebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
* Map EBus ranges to PCI ranges. This may include
* changing the allocation type.
*/
- (void)ofw_isa_range_map(sc->sc_range, sc->sc_nrange,
+ type = ofw_isa_range_map(sc->sc_range, sc->sc_nrange,
&start, &end, &ridx);
eri = &sc->sc_rinfo[ridx];
res = rman_reserve_resource(&eri->eri_rman, start,
@@ -507,7 +520,7 @@ ebus_activate_resource(device_t bus, device_t child, int type, int rid,
int i, rv;
sc = device_get_softc(bus);
- if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) {
+ if ((sc->sc_flags & EBUS_PCI) != 0 && type != SYS_RES_IRQ) {
for (i = 0; i < sc->sc_nrange; i++) {
eri = &sc->sc_rinfo[i];
if (rman_is_region_manager(res, &eri->eri_rman) != 0) {
@@ -550,7 +563,7 @@ ebus_release_resource(device_t bus, device_t child, int type, int rid,
passthrough = (device_get_parent(child) != bus);
rl = BUS_GET_RESOURCE_LIST(bus, child);
sc = device_get_softc(bus);
- if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) {
+ if ((sc->sc_flags & EBUS_PCI) != 0 && type != SYS_RES_IRQ) {
if ((rman_get_flags(res) & RF_ACTIVE) != 0 ){
rv = bus_deactivate_resource(child, type, rid, res);
if (rv != 0)
diff --git a/sys/sparc64/include/md_var.h b/sys/sparc64/include/md_var.h
index 6a0a2f6..d3dbf99 100644
--- a/sys/sparc64/include/md_var.h
+++ b/sys/sparc64/include/md_var.h
@@ -47,9 +47,9 @@ extern vm_paddr_t kstack0_phys;
struct pcpu;
struct md_utrap;
-const char *cpu_cpuid_prop(u_int cpu_impl);
uint32_t cpu_get_mid(u_int cpu_impl);
void cpu_identify(u_long vers, u_int clock, u_int id);
+const char *cpu_portid_prop(u_int cpu_impl);
void cpu_setregs(struct pcpu *pc);
int is_physical_memory(vm_paddr_t addr);
struct md_utrap *utrap_alloc(void);
diff --git a/sys/sparc64/include/smp.h b/sys/sparc64/include/smp.h
index c46c4f8..266187e 100644
--- a/sys/sparc64/include/smp.h
+++ b/sys/sparc64/include/smp.h
@@ -47,6 +47,7 @@
#include <sys/sched.h>
#include <sys/smp.h>
+#include <machine/atomic.h>
#include <machine/intr_machdep.h>
#include <machine/tte.h>
@@ -143,7 +144,7 @@ ipi_all_but_self(u_int ipi)
{
cpuset_t cpus;
- if (__predict_false(smp_started == 0))
+ if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
return;
cpus = all_cpus;
sched_pin();
@@ -158,7 +159,8 @@ static __inline void
ipi_selected(cpuset_t cpus, u_int ipi)
{
- if (__predict_false(smp_started == 0 || CPU_EMPTY(&cpus)))
+ if (__predict_false(atomic_load_acq_int(&smp_started) == 0 ||
+ CPU_EMPTY(&cpus)))
return;
mtx_lock_spin(&ipi_mtx);
cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi);
@@ -169,7 +171,7 @@ static __inline void
ipi_cpu(int cpu, u_int ipi)
{
- if (__predict_false(smp_started == 0))
+ if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
return;
mtx_lock_spin(&ipi_mtx);
cpu_ipi_single(cpu, 0, (u_long)tl_ipi_level, ipi);
@@ -183,7 +185,7 @@ ipi_dcache_page_inval(void *func, vm_paddr_t pa)
{
struct ipi_cache_args *ica;
- if (__predict_false(smp_started == 0))
+ if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
return (NULL);
sched_pin();
ica = &ipi_cache_args;
@@ -200,7 +202,7 @@ ipi_icache_page_inval(void *func, vm_paddr_t pa)
{
struct ipi_cache_args *ica;
- if (__predict_false(smp_started == 0))
+ if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
return (NULL);
sched_pin();
ica = &ipi_cache_args;
@@ -217,7 +219,7 @@ ipi_rd(u_int cpu, void *func, u_long *val)
{
struct ipi_rd_args *ira;
- if (__predict_false(smp_started == 0))
+ if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
return (NULL);
sched_pin();
ira = &ipi_rd_args;
@@ -234,7 +236,7 @@ ipi_tlb_context_demap(struct pmap *pm)
struct ipi_tlb_args *ita;
cpuset_t cpus;
- if (__predict_false(smp_started == 0))
+ if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
return (NULL);
sched_pin();
cpus = pm->pm_active;
@@ -259,7 +261,7 @@ ipi_tlb_page_demap(struct pmap *pm, vm_offset_t va)
struct ipi_tlb_args *ita;
cpuset_t cpus;
- if (__predict_false(smp_started == 0))
+ if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
return (NULL);
sched_pin();
cpus = pm->pm_active;
@@ -284,7 +286,7 @@ ipi_tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
struct ipi_tlb_args *ita;
cpuset_t cpus;
- if (__predict_false(smp_started == 0))
+ if (__predict_false(atomic_load_acq_int(&smp_started) == 0))
return (NULL);
sched_pin();
cpus = pm->pm_active;
diff --git a/sys/sparc64/pci/fire.c b/sys/sparc64/pci/fire.c
index 84526f0..be0c64b 100644
--- a/sys/sparc64/pci/fire.c
+++ b/sys/sparc64/pci/fire.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <sys/timetc.h>
#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_pci.h>
#include <dev/ofw/openfirm.h>
#include <vm/vm.h>
@@ -68,7 +67,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/bus_common.h>
#include <machine/bus_private.h>
-#include <machine/fsr.h>
#include <machine/iommureg.h>
#include <machine/iommuvar.h>
#include <machine/pmap.h>
@@ -111,19 +109,14 @@ static driver_filter_t fire_xcb;
/*
* Methods
*/
-static bus_activate_resource_t fire_activate_resource;
-static bus_adjust_resource_t fire_adjust_resource;
static pcib_alloc_msi_t fire_alloc_msi;
static pcib_alloc_msix_t fire_alloc_msix;
static bus_alloc_resource_t fire_alloc_resource;
static device_attach_t fire_attach;
-static bus_get_dma_tag_t fire_get_dma_tag;
-static ofw_bus_get_node_t fire_get_node;
static pcib_map_msi_t fire_map_msi;
static pcib_maxslots_t fire_maxslots;
static device_probe_t fire_probe;
static pcib_read_config_t fire_read_config;
-static bus_read_ivar_t fire_read_ivar;
static pcib_release_msi_t fire_release_msi;
static pcib_release_msix_t fire_release_msix;
static pcib_route_interrupt_t fire_route_interrupt;
@@ -140,15 +133,15 @@ static device_method_t fire_methods[] = {
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
- DEVMETHOD(bus_read_ivar, fire_read_ivar),
+ DEVMETHOD(bus_read_ivar, ofw_pci_read_ivar),
DEVMETHOD(bus_setup_intr, fire_setup_intr),
DEVMETHOD(bus_teardown_intr, fire_teardown_intr),
DEVMETHOD(bus_alloc_resource, fire_alloc_resource),
- DEVMETHOD(bus_activate_resource, fire_activate_resource),
+ DEVMETHOD(bus_activate_resource, ofw_pci_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
- DEVMETHOD(bus_adjust_resource, fire_adjust_resource),
+ DEVMETHOD(bus_adjust_resource, ofw_pci_adjust_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
- DEVMETHOD(bus_get_dma_tag, fire_get_dma_tag),
+ DEVMETHOD(bus_get_dma_tag, ofw_pci_get_dma_tag),
/* pcib interface */
DEVMETHOD(pcib_maxslots, fire_maxslots),
@@ -162,7 +155,7 @@ static device_method_t fire_methods[] = {
DEVMETHOD(pcib_map_msi, fire_map_msi),
/* ofw_bus interface */
- DEVMETHOD(ofw_bus_get_node, fire_get_node),
+ DEVMETHOD(ofw_bus_get_node, ofw_pci_get_node),
DEVMETHOD_END
};
@@ -296,7 +289,7 @@ fire_attach(device_t dev)
struct ofw_pci_msi_eq_to_devino msi_eq_to_devino;
struct fire_msiqarg *fmqa;
struct timecounter *tc;
- struct ofw_pci_ranges *range;
+ bus_dma_tag_t dmat;
uint64_t ino_bitmap, val;
phandle_t node;
uint32_t prop, prop_array[2];
@@ -310,7 +303,6 @@ fire_attach(device_t dev)
mode = desc->fd_mode;
sc->sc_dev = dev;
- sc->sc_node = node;
sc->sc_mode = mode;
sc->sc_flags = 0;
@@ -715,81 +707,21 @@ fire_attach(device_t dev)
sc->sc_is.is_bushandle = rman_get_bushandle(sc->sc_mem_res[FIRE_PCI]);
sc->sc_is.is_iommu = FO_PCI_MMU;
val = FIRE_PCI_READ_8(sc, FO_PCI_MMU + IMR_CTL);
- iommu_init(device_get_nameunit(sc->sc_dev), &sc->sc_is, 7, -1, 0);
+ iommu_init(device_get_nameunit(dev), &sc->sc_is, 7, -1, 0);
#ifdef FIRE_DEBUG
device_printf(dev, "FO_PCI_MMU + IMR_CTL 0x%016llx -> 0x%016llx\n",
(long long unsigned)val, (long long unsigned)sc->sc_is.is_cr);
#endif
-
- /* Initialize memory and I/O rmans. */
- sc->sc_pci_io_rman.rm_type = RMAN_ARRAY;
- sc->sc_pci_io_rman.rm_descr = "Fire PCI I/O Ports";
- if (rman_init(&sc->sc_pci_io_rman) != 0 ||
- rman_manage_region(&sc->sc_pci_io_rman, 0, FO_IO_SIZE) != 0)
- panic("%s: failed to set up I/O rman", __func__);
- sc->sc_pci_mem_rman.rm_type = RMAN_ARRAY;
- sc->sc_pci_mem_rman.rm_descr = "Fire PCI Memory";
- if (rman_init(&sc->sc_pci_mem_rman) != 0 ||
- rman_manage_region(&sc->sc_pci_mem_rman, 0, FO_MEM_SIZE) != 0)
- panic("%s: failed to set up memory rman", __func__);
-
- i = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
- /*
- * Make sure that the expected ranges are present. The
- * OFW_PCI_CS_MEM64 one is not currently used though.
- */
- if (i != FIRE_NRANGE)
- panic("%s: unsupported number of ranges", __func__);
- /*
- * Find the addresses of the various bus spaces.
- * There should not be multiple ones of one kind.
- * The physical start addresses of the ranges are the configuration,
- * memory and I/O handles.
- */
- for (i = 0; i < FIRE_NRANGE; i++) {
- j = OFW_PCI_RANGE_CS(&range[i]);
- if (sc->sc_pci_bh[j] != 0)
- panic("%s: duplicate range for space %d",
- __func__, j);
- sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]);
- }
- free(range, M_OFWPROP);
-
- /* Allocate our tags. */
- sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
- sc->sc_mem_res[FIRE_PCI]), PCI_IO_BUS_SPACE, NULL);
- if (sc->sc_pci_iot == NULL)
- panic("%s: could not allocate PCI I/O tag", __func__);
- sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
- sc->sc_mem_res[FIRE_PCI]), PCI_CONFIG_BUS_SPACE, NULL);
- if (sc->sc_pci_cfgt == NULL)
- panic("%s: could not allocate PCI configuration space tag",
- __func__);
+ /* Create our DMA tag. */
if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0x100000000,
sc->sc_is.is_pmaxaddr, ~0, NULL, NULL, sc->sc_is.is_pmaxaddr,
- 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0)
+ 0xff, 0xffffffff, 0, NULL, NULL, &dmat) != 0)
panic("%s: could not create PCI DMA tag", __func__);
- /* Customize the tag. */
- sc->sc_pci_dmat->dt_cookie = &sc->sc_is;
- sc->sc_pci_dmat->dt_mt = &sc->sc_dma_methods;
-
- /*
- * Get the bus range from the firmware.
- * NB: Neither Fire nor Oberon support PCI bus reenumeration.
- */
- i = OF_getprop(node, "bus-range", (void *)prop_array,
- sizeof(prop_array));
- if (i == -1)
- panic("%s: could not get bus-range", __func__);
- if (i != sizeof(prop_array))
- panic("%s: broken bus-range (%d)", __func__, i);
- sc->sc_pci_secbus = prop_array[0];
- sc->sc_pci_subbus = prop_array[1];
- if (bootverbose != 0)
- device_printf(dev, "bus range %u to %u; PCI bus %d\n",
- sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus);
+ dmat->dt_cookie = &sc->sc_is;
+ dmat->dt_mt = &sc->sc_dma_methods;
- ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t));
+ if (ofw_pci_attach_common(dev, dmat, FO_IO_SIZE, FO_MEM_SIZE) != 0)
+ panic("%s: ofw_pci_attach_common() failed", __func__);
#define FIRE_SYSCTL_ADD_UINT(name, arg, desc) \
SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), \
@@ -1392,136 +1324,44 @@ static uint32_t
fire_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
int width)
{
- struct fire_softc *sc;
- bus_space_handle_t bh;
- u_long offset = 0;
- uint32_t r, wrd;
- int i;
- uint16_t shrt;
- uint8_t byte;
-
- sc = device_get_softc(dev);
- if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
- slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCIE_REGMAX)
- return (-1);
-
- offset = FO_CONF_OFF(bus, slot, func, reg);
- bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
- switch (width) {
- case 1:
- i = bus_space_peek_1(sc->sc_pci_cfgt, bh, offset, &byte);
- r = byte;
- break;
- case 2:
- i = bus_space_peek_2(sc->sc_pci_cfgt, bh, offset, &shrt);
- r = shrt;
- break;
- case 4:
- i = bus_space_peek_4(sc->sc_pci_cfgt, bh, offset, &wrd);
- r = wrd;
- break;
- default:
- panic("%s: bad width", __func__);
- /* NOTREACHED */
- }
- if (i) {
-#ifdef FIRE_DEBUG
- printf("%s: read data error reading: %d.%d.%d: 0x%x\n",
- __func__, bus, slot, func, reg);
-#endif
- r = -1;
- }
- return (r);
+ return (ofw_pci_read_config_common(dev, PCIE_REGMAX, FO_CONF_OFF(bus,
+ slot, func, reg), bus, slot, func, reg, width));
}
static void
fire_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
uint32_t val, int width)
{
- struct fire_softc *sc;
- bus_space_handle_t bh;
- u_long offset = 0;
-
- sc = device_get_softc(dev);
- if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
- slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCIE_REGMAX)
- return;
- offset = FO_CONF_OFF(bus, slot, func, reg);
- bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
- switch (width) {
- case 1:
- bus_space_write_1(sc->sc_pci_cfgt, bh, offset, val);
- break;
- case 2:
- bus_space_write_2(sc->sc_pci_cfgt, bh, offset, val);
- break;
- case 4:
- bus_space_write_4(sc->sc_pci_cfgt, bh, offset, val);
- break;
- default:
- panic("%s: bad width", __func__);
- /* NOTREACHED */
- }
+ ofw_pci_write_config_common(dev, PCIE_REGMAX, FO_CONF_OFF(bus, slot,
+ func, reg), bus, slot, func, reg, val, width);
}
static int
fire_route_interrupt(device_t bridge, device_t dev, int pin)
{
- struct fire_softc *sc;
- struct ofw_pci_register reg;
- ofw_pci_intr_t pintr, mintr;
-
- sc = device_get_softc(bridge);
- pintr = pin;
- if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
- &reg, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- NULL) != 0)
- return (mintr);
-
- device_printf(bridge, "could not route pin %d for device %d.%d\n",
- pin, pci_get_slot(dev), pci_get_function(dev));
- return (PCI_INVALID_IRQ);
-}
-
-static int
-fire_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
- struct fire_softc *sc;
-
- sc = device_get_softc(dev);
- switch (which) {
- case PCIB_IVAR_DOMAIN:
- *result = device_get_unit(dev);
- return (0);
- case PCIB_IVAR_BUS:
- *result = sc->sc_pci_secbus;
- return (0);
- }
- return (ENOENT);
+ ofw_pci_intr_t mintr;
+
+ mintr = ofw_pci_route_interrupt_common(bridge, dev, pin);
+ if (!PCI_INTERRUPT_VALID(mintr))
+ device_printf(bridge,
+ "could not route pin %d for device %d.%d\n",
+ pin, pci_get_slot(dev), pci_get_function(dev));
+ return (mintr);
}
static void
fire_dmamap_sync(bus_dma_tag_t dt __unused, bus_dmamap_t map,
bus_dmasync_op_t op)
{
- static u_char buf[VIS_BLOCKSIZE] __aligned(VIS_BLOCKSIZE);
- register_t reg, s;
if ((map->dm_flags & DMF_LOADED) == 0)
return;
- if ((op & BUS_DMASYNC_POSTREAD) != 0) {
- s = intr_disable();
- reg = rd(fprs);
- wr(fprs, reg | FPRS_FEF, 0);
- __asm __volatile("stda %%f0, [%0] %1"
- : : "r" (buf), "n" (ASI_BLK_COMMIT_S));
- membar(Sync);
- wr(fprs, reg, 0);
- intr_restore(s);
- } else if ((op & BUS_DMASYNC_PREWRITE) != 0)
+ if ((op & BUS_DMASYNC_POSTREAD) != 0)
+ ofw_pci_dmamap_sync_stst_order_common();
+ else if ((op & BUS_DMASYNC_PREWRITE) != 0)
membar(Sync);
}
@@ -2015,122 +1855,13 @@ fire_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct fire_softc *sc;
- struct resource *rv;
- struct rman *rm;
-
- sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_IRQ:
- /*
- * XXX: Don't accept blank ranges for now, only single
- * interrupts. The other case should not happen with
- * the MI PCI code...
- * XXX: This may return a resource that is out of the
- * range that was specified. Is this correct...?
- */
- if (start != end)
- panic("%s: XXX: interrupt range", __func__);
- if (*rid == 0)
- start = end = INTMAP_VEC(sc->sc_ign, end);
- return (bus_generic_alloc_resource(bus, child, type, rid,
- start, end, count, flags));
- case SYS_RES_MEMORY:
- rm = &sc->sc_pci_mem_rman;
- break;
- case SYS_RES_IOPORT:
- rm = &sc->sc_pci_io_rman;
- break;
- default:
- return (NULL);
- }
-
- rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
- child);
- if (rv == NULL)
- return (NULL);
- rman_set_rid(rv, *rid);
-
- if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
- *rid, rv) != 0) {
- rman_release_resource(rv);
- return (NULL);
- }
- return (rv);
-}
-
-static int
-fire_activate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- struct fire_softc *sc;
- struct bus_space_tag *tag;
-
- sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_IRQ:
- return (bus_generic_activate_resource(bus, child, type, rid,
- r));
- case SYS_RES_MEMORY:
- tag = sparc64_alloc_bus_tag(r, rman_get_bustag(
- sc->sc_mem_res[FIRE_PCI]), PCI_MEMORY_BUS_SPACE, NULL);
- if (tag == NULL)
- return (ENOMEM);
- rman_set_bustag(r, tag);
- rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] +
- rman_get_start(r));
- break;
- case SYS_RES_IOPORT:
- rman_set_bustag(r, sc->sc_pci_iot);
- rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] +
- rman_get_start(r));
- break;
- }
- return (rman_activate_resource(r));
-}
-static int
-fire_adjust_resource(device_t bus, device_t child, int type,
- struct resource *r, u_long start, u_long end)
-{
- struct fire_softc *sc;
- struct rman *rm;
-
- sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_IRQ:
- return (bus_generic_adjust_resource(bus, child, type, r,
- start, end));
- case SYS_RES_MEMORY:
- rm = &sc->sc_pci_mem_rman;
- break;
- case SYS_RES_IOPORT:
- rm = &sc->sc_pci_io_rman;
- break;
- default:
- return (EINVAL);
+ if (type == SYS_RES_IRQ && *rid == 0) {
+ sc = device_get_softc(bus);
+ start = end = INTMAP_VEC(sc->sc_ign, end);
}
- if (rman_is_region_manager(r, rm) == 0)
- return (EINVAL);
- return (rman_adjust_resource(r, start, end));
-}
-
-static bus_dma_tag_t
-fire_get_dma_tag(device_t bus, device_t child __unused)
-{
- struct fire_softc *sc;
-
- sc = device_get_softc(bus);
- return (sc->sc_pci_dmat);
-}
-
-static phandle_t
-fire_get_node(device_t bus, device_t child __unused)
-{
- struct fire_softc *sc;
-
- sc = device_get_softc(bus);
- /* We only have one child, the PCI bus, which needs our own node. */
- return (sc->sc_node);
+ return (ofw_pci_alloc_resource(bus, child, type, rid, start, end,
+ count, flags));
}
static u_int
diff --git a/sys/sparc64/pci/firereg.h b/sys/sparc64/pci/firereg.h
index 247a3f7..715d3b7 100644
--- a/sys/sparc64/pci/firereg.h
+++ b/sys/sparc64/pci/firereg.h
@@ -30,7 +30,6 @@
#define _SPARC64_PCI_FIREREG_H_
#define FIRE_NINTR 3 /* 2 OFW + 1 MSIq */
-#define FIRE_NRANGE 4
#define FIRE_NREG 2
#define FIRE_PCI 0
diff --git a/sys/sparc64/pci/firevar.h b/sys/sparc64/pci/firevar.h
index d414c1a..36fd8ea 100644
--- a/sys/sparc64/pci/firevar.h
+++ b/sys/sparc64/pci/firevar.h
@@ -32,6 +32,12 @@
#define _SPARC64_PCI_FIREVAR_H_
struct fire_softc {
+ /*
+ * This is here so that we can hook up the common bus interface
+ * methods in ofw_pci.c directly.
+ */
+ struct ofw_pci_softc sc_ops;
+
struct iommu_state sc_is;
struct bus_dma_methods sc_dma_methods;
@@ -42,13 +48,6 @@ struct fire_softc {
struct resource *sc_irq_res[FIRE_NINTR];
void *sc_ihand[FIRE_NINTR];
- struct rman sc_pci_mem_rman;
- struct rman sc_pci_io_rman;
- bus_space_handle_t sc_pci_bh[FIRE_NRANGE];
- bus_space_tag_t sc_pci_cfgt;
- bus_space_tag_t sc_pci_iot;
- bus_dma_tag_t sc_pci_dmat;
-
device_t sc_dev;
uint64_t *sc_msiq;
@@ -66,8 +65,6 @@ struct fire_softc {
uint32_t sc_msiq_first;
uint32_t sc_msiq_ino_first;
- phandle_t sc_node;
-
u_int sc_mode;
#define FIRE_MODE_FIRE 0
#define FIRE_MODE_OBERON 1
@@ -87,11 +84,6 @@ struct fire_softc {
uint32_t sc_stats_tlu_oe_rx_err;
uint32_t sc_stats_tlu_oe_tx_err;
uint32_t sc_stats_ubc_dmardue;
-
- uint8_t sc_pci_secbus;
- uint8_t sc_pci_subbus;
-
- struct ofw_bus_iinfo sc_pci_iinfo;
};
#endif /* !_SPARC64_PCI_FIREVAR_H_ */
diff --git a/sys/sparc64/pci/ofw_pci.c b/sys/sparc64/pci/ofw_pci.c
new file mode 100644
index 0000000..ae03ed3
--- /dev/null
+++ b/sys/sparc64/pci/ofw_pci.c
@@ -0,0 +1,412 @@
+/*-
+ * Copyright (c) 1999, 2000 Matthew R. Green
+ * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org>
+ * Copyright (c) 2005 - 2015 by Marius Strobl <marius@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: NetBSD: psycho.c,v 1.35 2001/09/10 16:17:06 eeh Exp
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ofw_pci.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/openfirm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <machine/asi.h>
+#include <machine/bus.h>
+#include <machine/bus_private.h>
+#include <machine/cpufunc.h>
+#include <machine/fsr.h>
+#include <machine/resource.h>
+
+#include <sparc64/pci/ofw_pci.h>
+
+/* XXX */
+extern struct bus_space_tag nexus_bustag;
+
+int
+ofw_pci_attach_common(device_t dev, bus_dma_tag_t dmat, u_long iosize,
+ u_long memsize)
+{
+ struct ofw_pci_softc *sc;
+ struct ofw_pci_ranges *range;
+ phandle_t node;
+ uint32_t prop_array[2];
+ u_int i, j, nrange;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+ sc->sc_node = node;
+ sc->sc_pci_dmat = dmat;
+
+ /* Initialize memory and I/O rmans. */
+ sc->sc_pci_io_rman.rm_type = RMAN_ARRAY;
+ sc->sc_pci_io_rman.rm_descr = "PCI I/O Ports";
+ if (rman_init(&sc->sc_pci_io_rman) != 0 ||
+ rman_manage_region(&sc->sc_pci_io_rman, 0, iosize) != 0) {
+ device_printf(dev, "failed to set up I/O rman\n");
+ return (ENXIO);
+ }
+ sc->sc_pci_mem_rman.rm_type = RMAN_ARRAY;
+ sc->sc_pci_mem_rman.rm_descr = "PCI Memory";
+ if (rman_init(&sc->sc_pci_mem_rman) != 0 ||
+ rman_manage_region(&sc->sc_pci_mem_rman, 0, memsize) != 0) {
+ device_printf(dev, "failed to set up memory rman\n");
+ return (ENXIO);
+ }
+
+ /*
+ * Find the addresses of the various bus spaces. The physical
+ * start addresses of the ranges are the configuration, I/O and
+ * memory handles. There should not be multiple ones of one kind.
+ */
+ nrange = OF_getprop_alloc(node, "ranges", sizeof(*range),
+ (void **)&range);
+ for (i = 0; i < nrange; i++) {
+ j = OFW_PCI_RANGE_CS(&range[i]);
+ if (sc->sc_pci_bh[j] != 0) {
+ device_printf(dev, "duplicate range for space %d\n",
+ j);
+ free(range, M_OFWPROP);
+ return (EINVAL);
+ }
+ sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]);
+ }
+ free(range, M_OFWPROP);
+
+ /*
+ * Make sure that the expected ranges are actually present.
+ * The OFW_PCI_CS_MEM64 one is not currently used.
+ */
+ if (sc->sc_pci_bh[OFW_PCI_CS_CONFIG] == 0) {
+ device_printf(dev, "missing CONFIG range\n");
+ return (ENXIO);
+ }
+ if (sc->sc_pci_bh[OFW_PCI_CS_IO] == 0) {
+ device_printf(dev, "missing IO range\n");
+ return (ENXIO);
+ }
+ if (sc->sc_pci_bh[OFW_PCI_CS_MEM32] == 0) {
+ device_printf(dev, "missing MEM32 range\n");
+ return (ENXIO);
+ }
+
+ /* Allocate our tags. */
+ sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, &nexus_bustag,
+ PCI_IO_BUS_SPACE, NULL);
+ if (sc->sc_pci_iot == NULL) {
+ device_printf(dev, "could not allocate PCI I/O tag\n");
+ return (ENXIO);
+ }
+ sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, &nexus_bustag,
+ PCI_CONFIG_BUS_SPACE, NULL);
+ if (sc->sc_pci_cfgt == NULL) {
+ device_printf(dev,
+ "could not allocate PCI configuration space tag\n");
+ return (ENXIO);
+ }
+
+ /*
+ * Get the bus range from the firmware.
+ */
+ i = OF_getprop(node, "bus-range", (void *)prop_array,
+ sizeof(prop_array));
+ if (i == -1) {
+ device_printf(dev, "could not get bus-range\n");
+ return (ENXIO);
+ }
+ if (i != sizeof(prop_array)) {
+ device_printf(dev, "broken bus-range (%d)", i);
+ return (EINVAL);
+ }
+ sc->sc_pci_secbus = prop_array[0];
+ sc->sc_pci_subbus = prop_array[1];
+ if (bootverbose != 0)
+ device_printf(dev, "bus range %u to %u; PCI bus %d\n",
+ sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus);
+
+ ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t));
+
+ return (0);
+}
+
+uint32_t
+ofw_pci_read_config_common(device_t dev, u_int regmax, u_long offset,
+ u_int bus, u_int slot, u_int func, u_int reg, int width)
+{
+ struct ofw_pci_softc *sc;
+ bus_space_handle_t bh;
+ uint32_t r, wrd;
+ int i;
+ uint16_t shrt;
+ uint8_t byte;
+
+ sc = device_get_softc(dev);
+ if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+ slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > regmax)
+ return (-1);
+
+ bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
+ switch (width) {
+ case 1:
+ i = bus_space_peek_1(sc->sc_pci_cfgt, bh, offset, &byte);
+ r = byte;
+ break;
+ case 2:
+ i = bus_space_peek_2(sc->sc_pci_cfgt, bh, offset, &shrt);
+ r = shrt;
+ break;
+ case 4:
+ i = bus_space_peek_4(sc->sc_pci_cfgt, bh, offset, &wrd);
+ r = wrd;
+ break;
+ default:
+ panic("%s: bad width %d", __func__, width);
+ /* NOTREACHED */
+ }
+
+ if (i) {
+#ifdef OFW_PCI_DEBUG
+ printf("%s: read data error reading: %d.%d.%d: 0x%x\n",
+ __func__, bus, slot, func, reg);
+#endif
+ r = -1;
+ }
+ return (r);
+}
+
+void
+ofw_pci_write_config_common(device_t dev, u_int regmax, u_long offset,
+ u_int bus, u_int slot, u_int func, u_int reg, uint32_t val, int width)
+{
+ struct ofw_pci_softc *sc;
+ bus_space_handle_t bh;
+
+ sc = device_get_softc(dev);
+ if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
+ slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > regmax)
+ return;
+
+ bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
+ switch (width) {
+ case 1:
+ bus_space_write_1(sc->sc_pci_cfgt, bh, offset, val);
+ break;
+ case 2:
+ bus_space_write_2(sc->sc_pci_cfgt, bh, offset, val);
+ break;
+ case 4:
+ bus_space_write_4(sc->sc_pci_cfgt, bh, offset, val);
+ break;
+ default:
+ panic("%s: bad width %d", __func__, width);
+ /* NOTREACHED */
+ }
+}
+
+ofw_pci_intr_t
+ofw_pci_route_interrupt_common(device_t bridge, device_t dev, int pin)
+{
+ struct ofw_pci_softc *sc;
+ struct ofw_pci_register reg;
+ ofw_pci_intr_t pintr, mintr;
+
+ sc = device_get_softc(bridge);
+ pintr = pin;
+ if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
+ &reg, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
+ NULL) != 0)
+ return (mintr);
+ return (PCI_INVALID_IRQ);
+}
+
+void
+ofw_pci_dmamap_sync_stst_order_common(void)
+{
+ static u_char buf[VIS_BLOCKSIZE] __aligned(VIS_BLOCKSIZE);
+ register_t reg, s;
+
+ s = intr_disable();
+ reg = rd(fprs);
+ wr(fprs, reg | FPRS_FEF, 0);
+ __asm __volatile("stda %%f0, [%0] %1"
+ : : "r" (buf), "n" (ASI_BLK_COMMIT_S));
+ membar(Sync);
+ wr(fprs, reg, 0);
+ intr_restore(s);
+}
+
+int
+ofw_pci_read_ivar(device_t dev, device_t child __unused, int which,
+ uintptr_t *result)
+{
+ struct ofw_pci_softc *sc;
+
+ switch (which) {
+ case PCIB_IVAR_DOMAIN:
+ *result = device_get_unit(dev);
+ return (0);
+ case PCIB_IVAR_BUS:
+ sc = device_get_softc(dev);
+ *result = sc->sc_pci_secbus;
+ return (0);
+ }
+ return (ENOENT);
+}
+
+struct resource *
+ofw_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct ofw_pci_softc *sc;
+ struct resource *rv;
+ struct rman *rm;
+
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ /*
+ * XXX: Don't accept blank ranges for now, only single
+ * interrupts. The other case should not happen with
+ * the MI PCI code ...
+ * XXX: This may return a resource that is out of the
+ * range that was specified. Is this correct ...?
+ */
+ if (start != end)
+ panic("%s: XXX: interrupt range", __func__);
+ return (bus_generic_alloc_resource(bus, child, type, rid,
+ start, end, count, flags));
+ case SYS_RES_MEMORY:
+ rm = &sc->sc_pci_mem_rman;
+ break;
+ case SYS_RES_IOPORT:
+ rm = &sc->sc_pci_io_rman;
+ break;
+ default:
+ return (NULL);
+ }
+
+ rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
+ child);
+ if (rv == NULL)
+ return (NULL);
+ rman_set_rid(rv, *rid);
+
+ if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
+ *rid, rv) != 0) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ return (rv);
+}
+
+int
+ofw_pci_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct ofw_pci_softc *sc;
+ struct bus_space_tag *tag;
+
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (bus_generic_activate_resource(bus, child, type, rid,
+ r));
+ case SYS_RES_MEMORY:
+ tag = sparc64_alloc_bus_tag(r, &nexus_bustag,
+ PCI_MEMORY_BUS_SPACE, NULL);
+ if (tag == NULL)
+ return (ENOMEM);
+ rman_set_bustag(r, tag);
+ rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] +
+ rman_get_start(r));
+ break;
+ case SYS_RES_IOPORT:
+ rman_set_bustag(r, sc->sc_pci_iot);
+ rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] +
+ rman_get_start(r));
+ break;
+ }
+ return (rman_activate_resource(r));
+}
+
+int
+ofw_pci_adjust_resource(device_t bus, device_t child, int type,
+ struct resource *r, u_long start, u_long end)
+{
+ struct ofw_pci_softc *sc;
+ struct rman *rm;
+
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (bus_generic_adjust_resource(bus, child, type, r,
+ start, end));
+ case SYS_RES_MEMORY:
+ rm = &sc->sc_pci_mem_rman;
+ break;
+ case SYS_RES_IOPORT:
+ rm = &sc->sc_pci_io_rman;
+ break;
+ default:
+ return (EINVAL);
+ }
+ if (rman_is_region_manager(r, rm) == 0)
+ return (EINVAL);
+ return (rman_adjust_resource(r, start, end));
+}
+
+bus_dma_tag_t
+ofw_pci_get_dma_tag(device_t bus, device_t child __unused)
+{
+ struct ofw_pci_softc *sc;
+
+ sc = device_get_softc(bus);
+ return (sc->sc_pci_dmat);
+}
+
+phandle_t
+ofw_pci_get_node(device_t bus, device_t child __unused)
+{
+ struct ofw_pci_softc *sc;
+
+ sc = device_get_softc(bus);
+ /* We only have one child, the PCI bus, which needs our own node. */
+ return (sc->sc_node);
+}
diff --git a/sys/sparc64/pci/ofw_pci.h b/sys/sparc64/pci/ofw_pci.h
index 3915fa7..6d1e5d9 100644
--- a/sys/sparc64/pci/ofw_pci.h
+++ b/sys/sparc64/pci/ofw_pci.h
@@ -62,6 +62,8 @@
#ifndef _SPARC64_PCI_OFW_PCI_H_
#define _SPARC64_PCI_OFW_PCI_H_
+#include <sys/rman.h>
+
#include <dev/ofw/ofw_bus_subr.h>
#include "ofw_pci_if.h"
@@ -73,6 +75,7 @@ typedef uint32_t ofw_pci_intr_t;
#define OFW_PCI_CS_IO 0x01
#define OFW_PCI_CS_MEM32 0x02
#define OFW_PCI_CS_MEM64 0x03
+#define OFW_PCI_NUM_CS 4
/* OFW device types */
#define OFW_TYPE_PCI "pci"
@@ -124,4 +127,44 @@ struct ofw_pci_ranges {
/* default values */
#define OFW_PCI_LATENCY 64
+/*
+ * Common and generic parts of host-PCI-bridge support
+ */
+
+struct ofw_pci_softc {
+ struct rman sc_pci_mem_rman;
+ struct rman sc_pci_io_rman;
+
+ bus_space_handle_t sc_pci_bh[OFW_PCI_NUM_CS];
+ bus_space_tag_t sc_pci_cfgt;
+ bus_space_tag_t sc_pci_iot;
+ bus_dma_tag_t sc_pci_dmat;
+
+ struct ofw_bus_iinfo sc_pci_iinfo;
+
+ phandle_t sc_node;
+
+ uint8_t sc_pci_secbus;
+ uint8_t sc_pci_subbus;
+};
+
+int ofw_pci_attach_common(device_t dev, bus_dma_tag_t dmat, u_long iosize,
+ u_long memsize);
+uint32_t ofw_pci_read_config_common(device_t dev, u_int regmax, u_long offset,
+ u_int bus, u_int slot, u_int func, u_int reg, int width);
+void ofw_pci_write_config_common(device_t dev, u_int regmax, u_long offset,
+ u_int bus, u_int slot, u_int func, u_int reg, uint32_t val, int width);
+ofw_pci_intr_t ofw_pci_route_interrupt_common(device_t bridge, device_t dev,
+ int pin);
+
+void ofw_pci_dmamap_sync_stst_order_common(void);
+
+bus_activate_resource_t ofw_pci_activate_resource;
+bus_adjust_resource_t ofw_pci_adjust_resource;
+bus_alloc_resource_t ofw_pci_alloc_resource;
+bus_get_dma_tag_t ofw_pci_get_dma_tag;
+bus_read_ivar_t ofw_pci_read_ivar;
+
+ofw_bus_get_node_t ofw_pci_get_node;
+
#endif /* ! _SPARC64_PCI_OFW_PCI_H_ */
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index 4881d1f..f688df6 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_pci.h>
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
@@ -110,17 +109,12 @@ static void psycho_iommu_init(struct psycho_softc *, int, uint32_t);
*/
static device_probe_t psycho_probe;
static device_attach_t psycho_attach;
-static bus_read_ivar_t psycho_read_ivar;
static bus_setup_intr_t psycho_setup_intr;
static bus_alloc_resource_t psycho_alloc_resource;
-static bus_activate_resource_t psycho_activate_resource;
-static bus_adjust_resource_t psycho_adjust_resource;
-static bus_get_dma_tag_t psycho_get_dma_tag;
static pcib_maxslots_t psycho_maxslots;
static pcib_read_config_t psycho_read_config;
static pcib_write_config_t psycho_write_config;
static pcib_route_interrupt_t psycho_route_interrupt;
-static ofw_bus_get_node_t psycho_get_node;
static ofw_pci_setup_device_t psycho_setup_device;
static device_method_t psycho_methods[] = {
@@ -132,15 +126,15 @@ static device_method_t psycho_methods[] = {
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
- DEVMETHOD(bus_read_ivar, psycho_read_ivar),
+ DEVMETHOD(bus_read_ivar, ofw_pci_read_ivar),
DEVMETHOD(bus_setup_intr, psycho_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_alloc_resource, psycho_alloc_resource),
- DEVMETHOD(bus_activate_resource, psycho_activate_resource),
+ DEVMETHOD(bus_activate_resource, ofw_pci_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
- DEVMETHOD(bus_adjust_resource, psycho_adjust_resource),
+ DEVMETHOD(bus_adjust_resource, ofw_pci_adjust_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
- DEVMETHOD(bus_get_dma_tag, psycho_get_dma_tag),
+ DEVMETHOD(bus_get_dma_tag, ofw_pci_get_dma_tag),
/* pcib interface */
DEVMETHOD(pcib_maxslots, psycho_maxslots),
@@ -149,7 +143,7 @@ static device_method_t psycho_methods[] = {
DEVMETHOD(pcib_route_interrupt, psycho_route_interrupt),
/* ofw_bus interface */
- DEVMETHOD(ofw_bus_get_node, psycho_get_node),
+ DEVMETHOD(ofw_bus_get_node, ofw_pci_get_node),
/* ofw_pci interface */
DEVMETHOD(ofw_pci_setup_device, psycho_setup_device),
@@ -288,12 +282,12 @@ psycho_attach(device_t dev)
{
struct psycho_icarg *pica;
struct psycho_softc *asc, *sc, *osc;
- struct ofw_pci_ranges *range;
const struct psycho_desc *desc;
bus_addr_t intrclr, intrmap;
+ bus_dma_tag_t dmat;
uint64_t csr, dr;
phandle_t node;
- uint32_t dvmabase, prop, prop_array[2];
+ uint32_t dvmabase, prop;
u_int rerun, ver;
int i, j;
@@ -301,7 +295,6 @@ psycho_attach(device_t dev)
sc = device_get_softc(dev);
desc = psycho_get_desc(dev);
- sc->sc_node = node;
sc->sc_dev = dev;
sc->sc_mode = desc->pd_mode;
@@ -367,6 +360,7 @@ psycho_attach(device_t dev)
panic("%s: mutex not initialized", __func__);
sc->sc_mtx = osc->sc_mtx;
}
+ SLIST_INSERT_HEAD(&psycho_softcs, sc, sc_link);
csr = PSYCHO_READ8(sc, PSR_CS);
ver = PSYCHO_GCSR_VERS(csr);
@@ -435,43 +429,6 @@ psycho_attach(device_t dev)
} else
dvmabase = -1;
- /* Initialize memory and I/O rmans. */
- sc->sc_pci_io_rman.rm_type = RMAN_ARRAY;
- sc->sc_pci_io_rman.rm_descr = "Psycho PCI I/O Ports";
- if (rman_init(&sc->sc_pci_io_rman) != 0 ||
- rman_manage_region(&sc->sc_pci_io_rman, 0, PSYCHO_IO_SIZE) != 0)
- panic("%s: failed to set up I/O rman", __func__);
- sc->sc_pci_mem_rman.rm_type = RMAN_ARRAY;
- sc->sc_pci_mem_rman.rm_descr = "Psycho PCI Memory";
- if (rman_init(&sc->sc_pci_mem_rman) != 0 ||
- rman_manage_region(&sc->sc_pci_mem_rman, 0, PSYCHO_MEM_SIZE) != 0)
- panic("%s: failed to set up memory rman", __func__);
-
- i = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
- /*
- * Make sure that the expected ranges are present. The
- * OFW_PCI_CS_MEM64 one is not currently used though.
- */
- if (i != PSYCHO_NRANGE)
- panic("%s: unsupported number of ranges", __func__);
- /*
- * Find the addresses of the various bus spaces.
- * There should not be multiple ones of one kind.
- * The physical start addresses of the ranges are the configuration,
- * memory and I/O handles.
- */
- for (i = 0; i < PSYCHO_NRANGE; i++) {
- j = OFW_PCI_RANGE_CS(&range[i]);
- if (sc->sc_pci_bh[j] != 0)
- panic("%s: duplicate range for space %d",
- __func__, j);
- sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]);
- }
- free(range, M_OFWPROP);
-
- /* Register the softc, this is needed for paired Psychos. */
- SLIST_INSERT_HEAD(&psycho_softcs, sc, sc_link);
-
/*
* If we're a Hummingbird/Sabre or the first of a pair of Psychos
* to arrive here, do the interrupt setup and start up the IOMMU.
@@ -572,39 +529,21 @@ psycho_attach(device_t dev)
iommu_reset(sc->sc_is);
}
- /* Allocate our tags. */
- sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
- sc->sc_mem_res), PCI_IO_BUS_SPACE, NULL);
- if (sc->sc_pci_iot == NULL)
- panic("%s: could not allocate PCI I/O tag", __func__);
- sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
- sc->sc_mem_res), PCI_CONFIG_BUS_SPACE, NULL);
- if (sc->sc_pci_cfgt == NULL)
- panic("%s: could not allocate PCI configuration space tag",
- __func__);
+ /* Create our DMA tag. */
if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
sc->sc_is->is_pmaxaddr, ~0, NULL, NULL, sc->sc_is->is_pmaxaddr,
- 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0)
+ 0xff, 0xffffffff, 0, NULL, NULL, &dmat) != 0)
panic("%s: could not create PCI DMA tag", __func__);
- /* Customize the tag. */
- sc->sc_pci_dmat->dt_cookie = sc->sc_is;
- sc->sc_pci_dmat->dt_mt = sc->sc_dma_methods;
-
- i = OF_getprop(node, "bus-range", (void *)prop_array,
- sizeof(prop_array));
- if (i == -1)
- panic("%s: could not get bus-range", __func__);
- if (i != sizeof(prop_array))
- panic("%s: broken bus-range (%d)", __func__, i);
- sc->sc_pci_secbus = prop_array[0];
- sc->sc_pci_subbus = prop_array[1];
- if (bootverbose)
- device_printf(dev, "bus range %u to %u; PCI bus %d\n",
- sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus);
+ dmat->dt_cookie = sc->sc_is;
+ dmat->dt_mt = sc->sc_dma_methods;
+
+ if (ofw_pci_attach_common(dev, dmat, PSYCHO_IO_SIZE,
+ PSYCHO_MEM_SIZE) != 0)
+ panic("%s: ofw_pci_attach_common() failed", __func__);
/* Clear any pending PCI error bits. */
- PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
- PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_pci_secbus,
+ PCIB_WRITE_CONFIG(dev, sc->sc_ops.sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
+ PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_ops.sc_pci_secbus,
PCS_DEVICE, PCS_FUNC, PCIR_STATUS, 2), 2);
PCICTL_WRITE8(sc, PCR_CS, PCICTL_READ8(sc, PCR_CS));
PCICTL_WRITE8(sc, PCR_AFS, PCICTL_READ8(sc, PCR_AFS));
@@ -667,20 +606,20 @@ psycho_attach(device_t dev)
* Set the latency timer register as this isn't always done by the
* firmware.
*/
- PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
+ PCIB_WRITE_CONFIG(dev, sc->sc_ops.sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
PCIR_LATTIMER, OFW_PCI_LATENCY, 1);
for (i = PCIR_VENDOR; i < PCIR_STATUS; i += sizeof(uint16_t))
- le16enc(&sc->sc_pci_hpbcfg[i], bus_space_read_2(
- sc->sc_pci_cfgt, sc->sc_pci_bh[OFW_PCI_CS_CONFIG],
- PSYCHO_CONF_OFF(sc->sc_pci_secbus, PCS_DEVICE,
+ le16enc(&sc->sc_pci_hpbcfg[i],
+ bus_space_read_2(sc->sc_ops.sc_pci_cfgt,
+ sc->sc_ops.sc_pci_bh[OFW_PCI_CS_CONFIG],
+ PSYCHO_CONF_OFF(sc->sc_ops.sc_pci_secbus, PCS_DEVICE,
PCS_FUNC, i)));
for (i = PCIR_REVID; i <= PCIR_BIST; i += sizeof(uint8_t))
- sc->sc_pci_hpbcfg[i] = bus_space_read_1(sc->sc_pci_cfgt,
- sc->sc_pci_bh[OFW_PCI_CS_CONFIG], PSYCHO_CONF_OFF(
- sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, i));
+ sc->sc_pci_hpbcfg[i] = bus_space_read_1(sc->sc_ops.sc_pci_cfgt,
+ sc->sc_ops.sc_pci_bh[OFW_PCI_CS_CONFIG], PSYCHO_CONF_OFF(
+ sc->sc_ops.sc_pci_secbus, PCS_DEVICE, PCS_FUNC, i));
- ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t));
/*
* On E250 the interrupt map entry for the EBus bridge is wrong,
* causing incorrect interrupts to be assigned to some devices on
@@ -691,9 +630,9 @@ psycho_attach(device_t dev)
* EBus devices will be used directly instead.
*/
if (strcmp(sparc64_model, "SUNW,Ultra-250") == 0 &&
- sc->sc_pci_iinfo.opi_imapmsk != NULL)
- *(ofw_pci_intr_t *)(&sc->sc_pci_iinfo.opi_imapmsk[
- sc->sc_pci_iinfo.opi_addrc]) = INTMAP_INO_MASK;
+ sc->sc_ops.sc_pci_iinfo.opi_imapmsk != NULL)
+ *(ofw_pci_intr_t *)(&sc->sc_ops.sc_pci_iinfo.opi_imapmsk[
+ sc->sc_ops.sc_pci_iinfo.opi_addrc]) = INTMAP_INO_MASK;
device_add_child(dev, "pci", -1);
return (bus_generic_attach(dev));
@@ -927,20 +866,8 @@ psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
int width)
{
struct psycho_softc *sc;
- bus_space_handle_t bh;
- u_long offset = 0;
- uint8_t byte;
- uint16_t shrt;
- uint32_t r, wrd;
- int i;
sc = device_get_softc(dev);
- if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
- slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
- return (-1);
-
- bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
-
/*
* The Hummingbird and Sabre bridges are picky in that they
* only allow their config space to be accessed using the
@@ -956,9 +883,9 @@ psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
* The Psycho bridges contain a dupe of their header at 0x80
* which we nullify that way also.
*/
- if (bus == sc->sc_pci_secbus && slot == PCS_DEVICE &&
+ if (bus == sc->sc_ops.sc_pci_secbus && slot == PCS_DEVICE &&
func == PCS_FUNC) {
- if (offset % width != 0)
+ if (reg % width != 0)
return (-1);
if (reg >= sizeof(sc->sc_pci_hpbcfg))
@@ -967,8 +894,9 @@ psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
if ((reg < PCIR_STATUS && reg + width > PCIR_STATUS) ||
reg == PCIR_STATUS || reg == PCIR_STATUS + 1)
le16enc(&sc->sc_pci_hpbcfg[PCIR_STATUS],
- bus_space_read_2(sc->sc_pci_cfgt, bh,
- PSYCHO_CONF_OFF(sc->sc_pci_secbus,
+ bus_space_read_2(sc->sc_ops.sc_pci_cfgt,
+ sc->sc_ops.sc_pci_bh[OFW_PCI_CS_CONFIG],
+ PSYCHO_CONF_OFF(sc->sc_ops.sc_pci_secbus,
PCS_DEVICE, PCS_FUNC, PCIR_STATUS)));
switch (width) {
@@ -981,79 +909,29 @@ psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
}
}
- offset = PSYCHO_CONF_OFF(bus, slot, func, reg);
- switch (width) {
- case 1:
- i = bus_space_peek_1(sc->sc_pci_cfgt, bh, offset, &byte);
- r = byte;
- break;
- case 2:
- i = bus_space_peek_2(sc->sc_pci_cfgt, bh, offset, &shrt);
- r = shrt;
- break;
- case 4:
- i = bus_space_peek_4(sc->sc_pci_cfgt, bh, offset, &wrd);
- r = wrd;
- break;
- default:
- panic("%s: bad width", __func__);
- /* NOTREACHED */
- }
-
- if (i) {
-#ifdef PSYCHO_DEBUG
- printf("%s: read data error reading: %d.%d.%d: 0x%x\n",
- __func__, bus, slot, func, reg);
-#endif
- r = -1;
- }
- return (r);
+ return (ofw_pci_read_config_common(dev, PCI_REGMAX,
+ PSYCHO_CONF_OFF(bus, slot, func, reg), bus, slot, func, reg,
+ width));
}
static void
psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func,
u_int reg, uint32_t val, int width)
{
- struct psycho_softc *sc;
- bus_space_handle_t bh;
- u_long offset = 0;
- sc = device_get_softc(dev);
- if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
- slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
- return;
-
- offset = PSYCHO_CONF_OFF(bus, slot, func, reg);
- bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
- switch (width) {
- case 1:
- bus_space_write_1(sc->sc_pci_cfgt, bh, offset, val);
- break;
- case 2:
- bus_space_write_2(sc->sc_pci_cfgt, bh, offset, val);
- break;
- case 4:
- bus_space_write_4(sc->sc_pci_cfgt, bh, offset, val);
- break;
- default:
- panic("%s: bad width", __func__);
- /* NOTREACHED */
- }
+ ofw_pci_write_config_common(dev, PCI_REGMAX, PSYCHO_CONF_OFF(bus,
+ slot, func, reg), bus, slot, func, reg, val, width);
}
static int
psycho_route_interrupt(device_t bridge, device_t dev, int pin)
{
struct psycho_softc *sc;
- struct ofw_pci_register reg;
bus_addr_t intrmap;
- ofw_pci_intr_t pintr, mintr;
+ ofw_pci_intr_t mintr;
- sc = device_get_softc(bridge);
- pintr = pin;
- if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
- &reg, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- NULL))
+ mintr = ofw_pci_route_interrupt_common(bridge, dev, pin);
+ if (PCI_INTERRUPT_VALID(mintr))
return (mintr);
/*
* If this is outside of the range for an intpin, it's likely a full
@@ -1072,6 +950,7 @@ psycho_route_interrupt(device_t bridge, device_t dev, int pin)
* for bus A are one-based, while those for bus B seemingly have an
* offset of 2 (hence the factor of 3 below).
*/
+ sc = device_get_softc(dev);
intrmap = PSR_PCIA0_INT_MAP +
8 * (pci_get_slot(dev) - 1 + 3 * sc->sc_half);
mintr = INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1;
@@ -1081,23 +960,6 @@ psycho_route_interrupt(device_t bridge, device_t dev, int pin)
return (mintr);
}
-static int
-psycho_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
- struct psycho_softc *sc;
-
- sc = device_get_softc(dev);
- switch (which) {
- case PCIB_IVAR_DOMAIN:
- *result = device_get_unit(dev);
- return (0);
- case PCIB_IVAR_BUS:
- *result = sc->sc_pci_secbus;
- return (0);
- }
- return (ENOENT);
-}
-
static void
sabre_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
{
@@ -1180,121 +1042,13 @@ psycho_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct psycho_softc *sc;
- struct resource *rv;
- struct rman *rm;
- sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_IRQ:
- /*
- * XXX: Don't accept blank ranges for now, only single
- * interrupts. The other case should not happen with
- * the MI PCI code...
- * XXX: This may return a resource that is out of the
- * range that was specified. Is this correct...?
- */
- if (start != end)
- panic("%s: XXX: interrupt range", __func__);
+ if (type == SYS_RES_IRQ) {
+ sc = device_get_softc(bus);
start = end = INTMAP_VEC(sc->sc_ign, end);
- return (bus_generic_alloc_resource(bus, child, type, rid,
- start, end, count, flags));
- case SYS_RES_MEMORY:
- rm = &sc->sc_pci_mem_rman;
- break;
- case SYS_RES_IOPORT:
- rm = &sc->sc_pci_io_rman;
- break;
- default:
- return (NULL);
- }
-
- rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
- child);
- if (rv == NULL)
- return (NULL);
- rman_set_rid(rv, *rid);
-
- if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
- *rid, rv) != 0) {
- rman_release_resource(rv);
- return (NULL);
- }
- return (rv);
-}
-
-static int
-psycho_activate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- struct psycho_softc *sc;
- struct bus_space_tag *tag;
-
- sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_IRQ:
- return (bus_generic_activate_resource(bus, child, type, rid,
- r));
- case SYS_RES_MEMORY:
- tag = sparc64_alloc_bus_tag(r, rman_get_bustag(
- sc->sc_mem_res), PCI_MEMORY_BUS_SPACE, NULL);
- if (tag == NULL)
- return (ENOMEM);
- rman_set_bustag(r, tag);
- rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] +
- rman_get_start(r));
- break;
- case SYS_RES_IOPORT:
- rman_set_bustag(r, sc->sc_pci_iot);
- rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] +
- rman_get_start(r));
- break;
- }
- return (rman_activate_resource(r));
-}
-
-static int
-psycho_adjust_resource(device_t bus, device_t child, int type,
- struct resource *r, u_long start, u_long end)
-{
- struct psycho_softc *sc;
- struct rman *rm;
-
- sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_IRQ:
- return (bus_generic_adjust_resource(bus, child, type, r,
- start, end));
- case SYS_RES_MEMORY:
- rm = &sc->sc_pci_mem_rman;
- break;
- case SYS_RES_IOPORT:
- rm = &sc->sc_pci_io_rman;
- break;
- default:
- return (EINVAL);
}
- if (rman_is_region_manager(r, rm) == 0)
- return (EINVAL);
- return (rman_adjust_resource(r, start, end));
-}
-
-static bus_dma_tag_t
-psycho_get_dma_tag(device_t bus, device_t child __unused)
-{
- struct psycho_softc *sc;
-
- sc = device_get_softc(bus);
- return (sc->sc_pci_dmat);
-}
-
-static phandle_t
-psycho_get_node(device_t bus, device_t child __unused)
-{
- struct psycho_softc *sc;
-
- sc = device_get_softc(bus);
- /* We only have one child, the PCI bus, which needs our own node. */
- return (sc->sc_node);
+ return (ofw_pci_alloc_resource(bus, child, type, rid, start, end,
+ count, flags));
}
static void
diff --git a/sys/sparc64/pci/psychoreg.h b/sys/sparc64/pci/psychoreg.h
index ede593a..6e4ea39 100644
--- a/sys/sparc64/pci/psychoreg.h
+++ b/sys/sparc64/pci/psychoreg.h
@@ -73,7 +73,6 @@
*/
#define PSYCHO_NINTR 6
-#define PSYCHO_NRANGE 4
/*
* Psycho register offsets
@@ -121,7 +120,7 @@
#define PSR_PWRMGT_INT_MAP 0x1090 /* power mgmt wake interrupt map reg */
#define PSR_FFB0_INT_MAP 0x1098 /* FFB0 graphics interrupt map reg */
#define PSR_FFB1_INT_MAP 0x10a0 /* FFB1 graphics interrupt map reg */
-/* Note: clear interrupt 0 registers are not really used */
+/* Note: Clear interrupt 0 registers are not really used. */
#define PSR_PCIA0_INT_CLR 0x1400 /* PCI a slot 0 clear int regs 0..3 */
#define PSR_PCIA1_INT_CLR 0x1420 /* PCI a slot 1 clear int regs 0..3 */
#define PSR_PCIA2_INT_CLR 0x1440 /* PCI a slot 2 clear int regs 0..3 */
@@ -165,6 +164,7 @@
#define PSR_PCI_INT_DIAG 0xa800 /* PCI int state diag reg */
#define PSR_OBIO_INT_DIAG 0xa808 /* OBIO and misc int state diag reg */
#define PSR_STRBUF_DIAG 0xb000 /* Streaming buffer diag regs */
+
/*
* Here is the rest of the map, which we're not specifying:
*
@@ -176,7 +176,7 @@
* 1ff.0000.0000 - 1ff.7fff.ffff PCI A memory space
* 1ff.8000.0000 - 1ff.ffff.ffff PCI B memory space
*
- * NB: config and I/O space can use 1-4 byte accesses, not 8 byte
+ * NB: Config and I/O space can use 1-4 byte accesses, not 8 byte
* accesses. Memory space can use any sized accesses.
*
* Note that the SUNW,sabre/SUNW,simba combinations found on the
diff --git a/sys/sparc64/pci/psychovar.h b/sys/sparc64/pci/psychovar.h
index 5532d16..0f828ee 100644
--- a/sys/sparc64/pci/psychovar.h
+++ b/sys/sparc64/pci/psychovar.h
@@ -36,49 +36,38 @@
* per pair of psychos.
*/
struct psycho_softc {
- struct bus_dma_methods *sc_dma_methods;
+ /*
+ * This is here so that we can hook up the common bus interface
+ * methods in ofw_pci.c directly.
+ */
+ struct ofw_pci_softc sc_ops;
- device_t sc_dev;
+ struct iommu_state *sc_is;
+ struct bus_dma_methods *sc_dma_methods;
struct mtx *sc_mtx;
- /* Interrupt Group Number for this device */
- uint32_t sc_ign;
-
- bus_addr_t sc_pcictl;
-
- phandle_t sc_node; /* Firmware node */
- u_int sc_mode;
-#define PSYCHO_MODE_SABRE 0
-#define PSYCHO_MODE_PSYCHO 1
-
- /* Bus A or B of a psycho pair? */
- u_int sc_half;
-
- struct iommu_state *sc_is;
-
struct resource *sc_mem_res;
struct resource *sc_irq_res[PSYCHO_NINTR];
void *sc_ihand[PSYCHO_NINTR];
- struct ofw_bus_iinfo sc_pci_iinfo;
+ uint8_t sc_pci_hpbcfg[16];
- /* Tags for PCI access */
- bus_space_tag_t sc_pci_cfgt;
- bus_space_tag_t sc_pci_iot;
- bus_dma_tag_t sc_pci_dmat;
+ SLIST_ENTRY(psycho_softc) sc_link;
- bus_space_handle_t sc_pci_bh[PSYCHO_NRANGE];
+ device_t sc_dev;
- struct rman sc_pci_mem_rman;
- struct rman sc_pci_io_rman;
+ bus_addr_t sc_pcictl;
- uint8_t sc_pci_secbus;
- uint8_t sc_pci_subbus;
+ u_int sc_mode;
+#define PSYCHO_MODE_SABRE 0
+#define PSYCHO_MODE_PSYCHO 1
- uint8_t sc_pci_hpbcfg[16];
+ /* Bus A or B of a psycho pair? */
+ u_int sc_half;
- SLIST_ENTRY(psycho_softc) sc_link;
+ /* Interrupt Group Number for this device */
+ uint32_t sc_ign;
};
#endif /* !_SPARC64_PCI_PSYCHOVAR_H_ */
diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index b89c7c0..ed1cccd 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -57,13 +57,11 @@ __FBSDID("$FreeBSD$");
#include <sys/timetc.h>
#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_pci.h>
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
#include <machine/bus_common.h>
#include <machine/bus_private.h>
-#include <machine/fsr.h>
#include <machine/iommureg.h>
#include <machine/iommuvar.h>
#include <machine/resource.h>
@@ -108,17 +106,12 @@ static void schizo_iommu_init(struct schizo_softc *, int, uint32_t);
*/
static device_probe_t schizo_probe;
static device_attach_t schizo_attach;
-static bus_read_ivar_t schizo_read_ivar;
static bus_setup_intr_t schizo_setup_intr;
static bus_alloc_resource_t schizo_alloc_resource;
-static bus_activate_resource_t schizo_activate_resource;
-static bus_adjust_resource_t schizo_adjust_resource;
-static bus_get_dma_tag_t schizo_get_dma_tag;
static pcib_maxslots_t schizo_maxslots;
static pcib_read_config_t schizo_read_config;
static pcib_write_config_t schizo_write_config;
static pcib_route_interrupt_t schizo_route_interrupt;
-static ofw_bus_get_node_t schizo_get_node;
static ofw_pci_setup_device_t schizo_setup_device;
static device_method_t schizo_methods[] = {
@@ -130,15 +123,15 @@ static device_method_t schizo_methods[] = {
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
- DEVMETHOD(bus_read_ivar, schizo_read_ivar),
+ DEVMETHOD(bus_read_ivar, ofw_pci_read_ivar),
DEVMETHOD(bus_setup_intr, schizo_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_alloc_resource, schizo_alloc_resource),
- DEVMETHOD(bus_activate_resource, schizo_activate_resource),
+ DEVMETHOD(bus_activate_resource, ofw_pci_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
- DEVMETHOD(bus_adjust_resource, schizo_adjust_resource),
+ DEVMETHOD(bus_adjust_resource, ofw_pci_adjust_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
- DEVMETHOD(bus_get_dma_tag, schizo_get_dma_tag),
+ DEVMETHOD(bus_get_dma_tag, ofw_pci_get_dma_tag),
/* pcib interface */
DEVMETHOD(pcib_maxslots, schizo_maxslots),
@@ -147,7 +140,7 @@ static device_method_t schizo_methods[] = {
DEVMETHOD(pcib_route_interrupt, schizo_route_interrupt),
/* ofw_bus interface */
- DEVMETHOD(ofw_bus_get_node, schizo_get_node),
+ DEVMETHOD(ofw_bus_get_node, ofw_pci_get_node),
/* ofw_pci interface */
DEVMETHOD(ofw_pci_setup_device, schizo_setup_device),
@@ -270,10 +263,10 @@ schizo_probe(device_t dev)
static int
schizo_attach(device_t dev)
{
- struct ofw_pci_ranges *range;
const struct schizo_desc *desc;
struct schizo_softc *asc, *sc, *osc;
struct timecounter *tc;
+ bus_dma_tag_t dmat;
uint64_t ino_bitmap, reg;
phandle_t node;
uint32_t prop, prop_array[2];
@@ -285,7 +278,6 @@ schizo_attach(device_t dev)
mode = desc->sd_mode;
sc->sc_dev = dev;
- sc->sc_node = node;
sc->sc_mode = mode;
sc->sc_flags = 0;
@@ -347,6 +339,7 @@ schizo_attach(device_t dev)
panic("%s: mutex not initialized", __func__);
sc->sc_mtx = osc->sc_mtx;
}
+ SLIST_INSERT_HEAD(&schizo_softcs, sc, sc_link);
if (OF_getprop(node, "portid", &sc->sc_ign, sizeof(sc->sc_ign)) == -1)
panic("%s: could not determine IGN", __func__);
@@ -542,82 +535,23 @@ schizo_attach(device_t dev)
#undef TSBCASE
- /* Initialize memory and I/O rmans. */
- sc->sc_pci_io_rman.rm_type = RMAN_ARRAY;
- sc->sc_pci_io_rman.rm_descr = "Schizo PCI I/O Ports";
- if (rman_init(&sc->sc_pci_io_rman) != 0 ||
- rman_manage_region(&sc->sc_pci_io_rman, 0, STX_IO_SIZE) != 0)
- panic("%s: failed to set up I/O rman", __func__);
- sc->sc_pci_mem_rman.rm_type = RMAN_ARRAY;
- sc->sc_pci_mem_rman.rm_descr = "Schizo PCI Memory";
- if (rman_init(&sc->sc_pci_mem_rman) != 0 ||
- rman_manage_region(&sc->sc_pci_mem_rman, 0, STX_MEM_SIZE) != 0)
- panic("%s: failed to set up memory rman", __func__);
-
- i = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
- /*
- * Make sure that the expected ranges are present. The
- * OFW_PCI_CS_MEM64 one is not currently used though.
- */
- if (i != STX_NRANGE)
- panic("%s: unsupported number of ranges", __func__);
- /*
- * Find the addresses of the various bus spaces.
- * There should not be multiple ones of one kind.
- * The physical start addresses of the ranges are the configuration,
- * memory and I/O handles.
- */
- for (i = 0; i < STX_NRANGE; i++) {
- j = OFW_PCI_RANGE_CS(&range[i]);
- if (sc->sc_pci_bh[j] != 0)
- panic("%s: duplicate range for space %d",
- __func__, j);
- sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]);
- }
- free(range, M_OFWPROP);
-
- /* Register the softc, this is needed for paired Schizos. */
- SLIST_INSERT_HEAD(&schizo_softcs, sc, sc_link);
-
- /* Allocate our tags. */
- sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
- sc->sc_mem_res[STX_PCI]), PCI_IO_BUS_SPACE, NULL);
- if (sc->sc_pci_iot == NULL)
- panic("%s: could not allocate PCI I/O tag", __func__);
- sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
- sc->sc_mem_res[STX_PCI]), PCI_CONFIG_BUS_SPACE, NULL);
- if (sc->sc_pci_cfgt == NULL)
- panic("%s: could not allocate PCI configuration space tag",
- __func__);
+ /* Create our DMA tag. */
if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
sc->sc_is.sis_is.is_pmaxaddr, ~0, NULL, NULL,
sc->sc_is.sis_is.is_pmaxaddr, 0xff, 0xffffffff, 0, NULL, NULL,
- &sc->sc_pci_dmat) != 0)
+ &dmat) != 0)
panic("%s: could not create PCI DMA tag", __func__);
- /* Customize the tag. */
- sc->sc_pci_dmat->dt_cookie = &sc->sc_is;
- sc->sc_pci_dmat->dt_mt = &sc->sc_dma_methods;
+ dmat->dt_cookie = &sc->sc_is;
+ dmat->dt_mt = &sc->sc_dma_methods;
- /*
- * Get the bus range from the firmware.
- * NB: Tomatillos don't support PCI bus reenumeration.
- */
- i = OF_getprop(node, "bus-range", (void *)prop_array,
- sizeof(prop_array));
- if (i == -1)
- panic("%s: could not get bus-range", __func__);
- if (i != sizeof(prop_array))
- panic("%s: broken bus-range (%d)", __func__, i);
- sc->sc_pci_secbus = prop_array[0];
- sc->sc_pci_subbus = prop_array[1];
- if (bootverbose)
- device_printf(dev, "bus range %u to %u; PCI bus %d\n",
- sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus);
+ if (ofw_pci_attach_common(dev, dmat, STX_IO_SIZE, STX_MEM_SIZE) != 0)
+ panic("%s: ofw_pci_attach_common() failed", __func__);
/* Clear any pending PCI error bits. */
- PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC,
- PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_pci_secbus,
- STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2), 2);
+ PCIB_WRITE_CONFIG(dev, sc->sc_ops.sc_pci_secbus, STX_CS_DEVICE,
+ STX_CS_FUNC, PCIR_STATUS, PCIB_READ_CONFIG(dev,
+ sc->sc_ops.sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS,
+ 2), 2);
SCHIZO_PCI_SET(sc, STX_PCI_CTRL, SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL));
SCHIZO_PCI_SET(sc, STX_PCI_AFSR, SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR));
@@ -745,10 +679,8 @@ schizo_attach(device_t dev)
* Set the latency timer register as this isn't always done by the
* firmware.
*/
- PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC,
- PCIR_LATTIMER, OFW_PCI_LATENCY, 1);
-
- ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t));
+ PCIB_WRITE_CONFIG(dev, sc->sc_ops.sc_pci_secbus, STX_CS_DEVICE,
+ STX_CS_FUNC, PCIR_LATTIMER, OFW_PCI_LATENCY, 1);
#define SCHIZO_SYSCTL_ADD_UINT(name, arg, desc) \
SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), \
@@ -872,7 +804,7 @@ schizo_pci_bus(void *arg)
xstat = SCHIZO_PCI_READ_8(sc, XMS_PCI_X_ERR_STAT);
else
xstat = 0;
- status = PCIB_READ_CONFIG(sc->sc_dev, sc->sc_pci_secbus,
+ status = PCIB_READ_CONFIG(sc->sc_dev, sc->sc_ops.sc_pci_secbus,
STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2);
/*
@@ -913,7 +845,7 @@ schizo_pci_bus(void *arg)
(unsigned long long)iommu, (unsigned long long)xstat, status);
/* Clear the error bits that we caught. */
- PCIB_WRITE_CONFIG(sc->sc_dev, sc->sc_pci_secbus, STX_CS_DEVICE,
+ PCIB_WRITE_CONFIG(sc->sc_dev, sc->sc_ops.sc_pci_secbus, STX_CS_DEVICE,
STX_CS_FUNC, PCIR_STATUS, status, 2);
SCHIZO_PCI_WRITE_8(sc, STX_PCI_CTRL, csr);
SCHIZO_PCI_WRITE_8(sc, STX_PCI_AFSR, afsr);
@@ -1034,121 +966,40 @@ schizo_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
int width)
{
struct schizo_softc *sc;
- bus_space_handle_t bh;
- u_long offset = 0;
- uint32_t r, wrd;
- int i;
- uint16_t shrt;
- uint8_t byte;
sc = device_get_softc(dev);
- if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
- slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
- return (-1);
-
/*
* The Schizo bridges contain a dupe of their header at 0x80.
*/
- if (sc->sc_mode == SCHIZO_MODE_SCZ && bus == sc->sc_pci_secbus &&
- slot == STX_CS_DEVICE && func == STX_CS_FUNC &&
- reg + width > 0x80)
+ if (sc->sc_mode == SCHIZO_MODE_SCZ &&
+ bus == sc->sc_ops.sc_pci_secbus && slot == STX_CS_DEVICE &&
+ func == STX_CS_FUNC && reg + width > 0x80)
return (0);
- offset = STX_CONF_OFF(bus, slot, func, reg);
- bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
- switch (width) {
- case 1:
- i = bus_space_peek_1(sc->sc_pci_cfgt, bh, offset, &byte);
- r = byte;
- break;
- case 2:
- i = bus_space_peek_2(sc->sc_pci_cfgt, bh, offset, &shrt);
- r = shrt;
- break;
- case 4:
- i = bus_space_peek_4(sc->sc_pci_cfgt, bh, offset, &wrd);
- r = wrd;
- break;
- default:
- panic("%s: bad width", __func__);
- /* NOTREACHED */
- }
-
- if (i) {
-#ifdef SCHIZO_DEBUG
- printf("%s: read data error reading: %d.%d.%d: 0x%x\n",
- __func__, bus, slot, func, reg);
-#endif
- r = -1;
- }
- return (r);
+ return (ofw_pci_read_config_common(dev, PCI_REGMAX, STX_CONF_OFF(bus,
+ slot, func, reg), bus, slot, func, reg, width));
}
static void
schizo_write_config(device_t dev, u_int bus, u_int slot, u_int func,
u_int reg, uint32_t val, int width)
{
- struct schizo_softc *sc;
- bus_space_handle_t bh;
- u_long offset = 0;
-
- sc = device_get_softc(dev);
- if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
- slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
- return;
- offset = STX_CONF_OFF(bus, slot, func, reg);
- bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
- switch (width) {
- case 1:
- bus_space_write_1(sc->sc_pci_cfgt, bh, offset, val);
- break;
- case 2:
- bus_space_write_2(sc->sc_pci_cfgt, bh, offset, val);
- break;
- case 4:
- bus_space_write_4(sc->sc_pci_cfgt, bh, offset, val);
- break;
- default:
- panic("%s: bad width", __func__);
- /* NOTREACHED */
- }
+ ofw_pci_write_config_common(dev, PCI_REGMAX, STX_CONF_OFF(bus, slot,
+ func, reg), bus, slot, func, reg, val, width);
}
static int
schizo_route_interrupt(device_t bridge, device_t dev, int pin)
{
- struct schizo_softc *sc;
- struct ofw_pci_register reg;
- ofw_pci_intr_t pintr, mintr;
-
- sc = device_get_softc(bridge);
- pintr = pin;
- if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
- &reg, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
- NULL))
- return (mintr);
-
- device_printf(bridge, "could not route pin %d for device %d.%d\n",
- pin, pci_get_slot(dev), pci_get_function(dev));
- return (PCI_INVALID_IRQ);
-}
-
-static int
-schizo_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
- struct schizo_softc *sc;
-
- sc = device_get_softc(dev);
- switch (which) {
- case PCIB_IVAR_DOMAIN:
- *result = device_get_unit(dev);
- return (0);
- case PCIB_IVAR_BUS:
- *result = sc->sc_pci_secbus;
- return (0);
- }
- return (ENOENT);
+ ofw_pci_intr_t mintr;
+
+ mintr = ofw_pci_route_interrupt_common(bridge, dev, pin);
+ if (!PCI_INTERRUPT_VALID(mintr))
+ device_printf(bridge,
+ "could not route pin %d for device %d.%d\n",
+ pin, pci_get_slot(dev), pci_get_function(dev));
+ return (mintr);
}
static void
@@ -1216,11 +1067,10 @@ schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
static void
ichip_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
{
- static u_char buf[VIS_BLOCKSIZE] __aligned(VIS_BLOCKSIZE);
struct timeval cur, end;
struct schizo_iommu_state *sis = dt->dt_cookie;
struct schizo_softc *sc = sis->sis_sc;
- register_t reg, s;
+ uint64_t reg;
if ((map->dm_flags & DMF_STREAMED) != 0) {
iommu_dma_methods.dm_dmamap_sync(dt, map, op);
@@ -1248,14 +1098,7 @@ ichip_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
if (sc->sc_mode == SCHIZO_MODE_XMS)
mtx_unlock_spin(&sc->sc_sync_mtx);
else if ((sc->sc_flags & SCHIZO_FLAGS_BSWAR) != 0) {
- s = intr_disable();
- reg = rd(fprs);
- wr(fprs, reg | FPRS_FEF, 0);
- __asm __volatile("stda %%f0, [%0] %1"
- : : "r" (buf), "n" (ASI_BLK_COMMIT_S));
- membar(Sync);
- wr(fprs, reg, 0);
- intr_restore(s);
+ ofw_pci_dmamap_sync_stst_order_common();
return;
}
}
@@ -1356,121 +1199,13 @@ schizo_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct schizo_softc *sc;
- struct resource *rv;
- struct rman *rm;
- sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_IRQ:
- /*
- * XXX: Don't accept blank ranges for now, only single
- * interrupts. The other case should not happen with
- * the MI PCI code...
- * XXX: This may return a resource that is out of the
- * range that was specified. Is this correct...?
- */
- if (start != end)
- panic("%s: XXX: interrupt range", __func__);
+ if (type == SYS_RES_IRQ) {
+ sc = device_get_softc(bus);
start = end = INTMAP_VEC(sc->sc_ign, end);
- return (bus_generic_alloc_resource(bus, child, type, rid,
- start, end, count, flags));
- case SYS_RES_MEMORY:
- rm = &sc->sc_pci_mem_rman;
- break;
- case SYS_RES_IOPORT:
- rm = &sc->sc_pci_io_rman;
- break;
- default:
- return (NULL);
- }
-
- rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
- child);
- if (rv == NULL)
- return (NULL);
- rman_set_rid(rv, *rid);
-
- if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
- *rid, rv) != 0) {
- rman_release_resource(rv);
- return (NULL);
- }
- return (rv);
-}
-
-static int
-schizo_activate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- struct schizo_softc *sc;
- struct bus_space_tag *tag;
-
- sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_IRQ:
- return (bus_generic_activate_resource(bus, child, type, rid,
- r));
- case SYS_RES_MEMORY:
- tag = sparc64_alloc_bus_tag(r, rman_get_bustag(
- sc->sc_mem_res[STX_PCI]), PCI_MEMORY_BUS_SPACE, NULL);
- if (tag == NULL)
- return (ENOMEM);
- rman_set_bustag(r, tag);
- rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] +
- rman_get_start(r));
- break;
- case SYS_RES_IOPORT:
- rman_set_bustag(r, sc->sc_pci_iot);
- rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] +
- rman_get_start(r));
- break;
- }
- return (rman_activate_resource(r));
-}
-
-static int
-schizo_adjust_resource(device_t bus, device_t child, int type,
- struct resource *r, u_long start, u_long end)
-{
- struct schizo_softc *sc;
- struct rman *rm;
-
- sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_IRQ:
- return (bus_generic_adjust_resource(bus, child, type, r,
- start, end));
- case SYS_RES_MEMORY:
- rm = &sc->sc_pci_mem_rman;
- break;
- case SYS_RES_IOPORT:
- rm = &sc->sc_pci_io_rman;
- break;
- default:
- return (EINVAL);
}
- if (rman_is_region_manager(r, rm) == 0)
- return (EINVAL);
- return (rman_adjust_resource(r, start, end));
-}
-
-static bus_dma_tag_t
-schizo_get_dma_tag(device_t bus, device_t child __unused)
-{
- struct schizo_softc *sc;
-
- sc = device_get_softc(bus);
- return (sc->sc_pci_dmat);
-}
-
-static phandle_t
-schizo_get_node(device_t bus, device_t child __unused)
-{
- struct schizo_softc *sc;
-
- sc = device_get_softc(bus);
- /* We only have one child, the PCI bus, which needs our own node. */
- return (sc->sc_node);
+ return (ofw_pci_alloc_resource(bus, child, type, rid, start, end,
+ count, flags));
}
static void
diff --git a/sys/sparc64/pci/schizoreg.h b/sys/sparc64/pci/schizoreg.h
index cd816b5..59c00b6 100644
--- a/sys/sparc64/pci/schizoreg.h
+++ b/sys/sparc64/pci/schizoreg.h
@@ -32,7 +32,6 @@
#define _SPARC64_PCI_SCHIZOREG_H_
#define STX_NINTR 5 /* 4 via OFW + 1 CDMA */
-#define STX_NRANGE 4
#define SCZ_NREG 3
#define TOM_NREG 4
@@ -279,7 +278,7 @@
/*
* Safari/JBus performance control register
- * NB: for Tomatillo only events 0x00 through 0x08 are documented as
+ * NB: For Tomatillo only events 0x00 through 0x08 are documented as
* implemented.
*/
#define SCZ_CTRL_PERF_ZDATA_OUT 0x0000000000000016ULL
@@ -345,7 +344,7 @@
/* Non-Standard registers in the configration space */
/*
- * NB: for Tomatillo the secondary and subordinate bus number registers
+ * NB: For Tomatillo the secondary and subordinate bus number registers
* apparently are read-only although documented otherwise; writing to
* them just triggers a PCI bus error interrupt or has no effect at best.
*/
diff --git a/sys/sparc64/pci/schizovar.h b/sys/sparc64/pci/schizovar.h
index ab339c8..1b58cf4 100644
--- a/sys/sparc64/pci/schizovar.h
+++ b/sys/sparc64/pci/schizovar.h
@@ -39,16 +39,27 @@ struct schizo_iommu_state {
};
struct schizo_softc {
- struct bus_dma_methods sc_dma_methods;
+ /*
+ * This is here so that we can hook up the common bus interface
+ * methods in ofw_pci.c directly.
+ */
+ struct ofw_pci_softc sc_ops;
- device_t sc_dev;
+ struct schizo_iommu_state sc_is;
+ struct bus_dma_methods sc_dma_methods;
struct mtx sc_sync_mtx;
uint64_t sc_sync_val;
struct mtx *sc_mtx;
- phandle_t sc_node;
+ struct resource *sc_mem_res[TOM_NREG];
+ struct resource *sc_irq_res[STX_NINTR];
+ void *sc_ihand[STX_NINTR];
+
+ SLIST_ENTRY(schizo_softc) sc_link;
+
+ device_t sc_dev;
u_int sc_mode;
#define SCHIZO_MODE_SCZ 0
@@ -72,28 +83,8 @@ struct schizo_softc {
uint32_t sc_ver;
uint32_t sc_mrev;
- struct resource *sc_mem_res[TOM_NREG];
- struct resource *sc_irq_res[STX_NINTR];
- void *sc_ihand[STX_NINTR];
-
- struct schizo_iommu_state sc_is;
-
- struct rman sc_pci_mem_rman;
- struct rman sc_pci_io_rman;
- bus_space_handle_t sc_pci_bh[STX_NRANGE];
- bus_space_tag_t sc_pci_cfgt;
- bus_space_tag_t sc_pci_iot;
- bus_dma_tag_t sc_pci_dmat;
-
uint32_t sc_stats_dma_ce;
uint32_t sc_stats_pci_non_fatal;
-
- uint8_t sc_pci_secbus;
- uint8_t sc_pci_subbus;
-
- struct ofw_bus_iinfo sc_pci_iinfo;
-
- SLIST_ENTRY(schizo_softc) sc_link;
};
#endif /* !_SPARC64_PCI_SCHIZOVAR_H_ */
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index f016eaa..07be1c8 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -249,7 +249,7 @@ find_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl)
{
char type[sizeof("cpu")];
phandle_t child;
- uint32_t cpuid;
+ uint32_t portid;
for (; node != 0; node = OF_peer(node)) {
child = OF_child(node);
@@ -263,10 +263,10 @@ find_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl)
continue;
if (strcmp(type, "cpu") != 0)
continue;
- if (OF_getprop(node, cpu_cpuid_prop(cpu_impl), &cpuid,
- sizeof(cpuid)) <= 0)
+ if (OF_getprop(node, cpu_portid_prop(cpu_impl),
+ &portid, sizeof(portid)) <= 0)
continue;
- if (cpuid == bspid)
+ if (portid == bspid)
return (node);
}
}
@@ -274,7 +274,7 @@ find_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl)
}
const char *
-cpu_cpuid_prop(u_int cpu_impl)
+cpu_portid_prop(u_int cpu_impl)
{
switch (cpu_impl) {
diff --git a/sys/sparc64/sparc64/mp_machdep.c b/sys/sparc64/sparc64/mp_machdep.c
index c2c4e3e..52322a2 100644
--- a/sys/sparc64/sparc64/mp_machdep.c
+++ b/sys/sparc64/sparc64/mp_machdep.c
@@ -119,9 +119,11 @@ struct mtx ipi_mtx;
cpu_ipi_selected_t *cpu_ipi_selected;
cpu_ipi_single_t *cpu_ipi_single;
-static vm_offset_t mp_tramp;
static u_int cpuid_to_mid[MAXCPU];
+static u_int cpuids = 1;
static volatile cpuset_t shutdown_cpus;
+static char ipi_pbuf[CPUSETBUFSIZ];
+static vm_offset_t mp_tramp;
static void ap_count(phandle_t node, u_int mid, u_int cpu_impl);
static void ap_start(phandle_t node, u_int mid, u_int cpu_impl);
@@ -165,13 +167,12 @@ static void
foreach_ap(phandle_t node, void (*func)(phandle_t node, u_int mid,
u_int cpu_impl))
{
- char type[sizeof("cpu")];
+ static char type[sizeof("cpu")];
phandle_t child;
- u_int cpuid;
- uint32_t cpu_impl;
+ uint32_t cpu_impl, portid;
/* There's no need to traverse the whole OFW tree twice. */
- if (mp_maxid > 0 && mp_ncpus >= mp_maxid + 1)
+ if (mp_maxid > 0 && cpuids > mp_maxid)
return;
for (; node != 0; node = OF_peer(node)) {
@@ -188,13 +189,13 @@ foreach_ap(phandle_t node, void (*func)(phandle_t node, u_int mid,
sizeof(cpu_impl)) <= 0)
panic("%s: couldn't determine CPU "
"implementation", __func__);
- if (OF_getprop(node, cpu_cpuid_prop(cpu_impl), &cpuid,
- sizeof(cpuid)) <= 0)
- panic("%s: couldn't determine CPU module ID",
+ if (OF_getprop(node, cpu_portid_prop(cpu_impl),
+ &portid, sizeof(portid)) <= 0)
+ panic("%s: couldn't determine CPU port ID",
__func__);
- if (cpuid == PCPU_GET(mid))
+ if (portid == PCPU_GET(mid))
continue;
- (*func)(node, cpuid, cpu_impl);
+ (*func)(node, portid, cpu_impl);
}
}
}
@@ -208,16 +209,17 @@ cpu_mp_setmaxid(void)
CPU_SETOF(curcpu, &all_cpus);
mp_ncpus = 1;
- mp_maxid = 0;
foreach_ap(OF_child(OF_peer(0)), ap_count);
+ mp_ncpus = MIN(mp_ncpus, MAXCPU);
+ mp_maxid = mp_ncpus - 1;
}
static void
ap_count(phandle_t node __unused, u_int mid __unused, u_int cpu_impl __unused)
{
- mp_maxid++;
+ mp_ncpus++;
}
int
@@ -306,7 +308,7 @@ ap_start(phandle_t node, u_int mid, u_int cpu_impl)
u_int cpuid;
uint32_t clock;
- if (mp_ncpus > MAXCPU)
+ if (cpuids > mp_maxid)
return;
if (OF_getprop(node, "clock-frequency", &clock, sizeof(clock)) <= 0)
@@ -334,7 +336,7 @@ ap_start(phandle_t node, u_int mid, u_int cpu_impl)
csa->csa_tick = csa->csa_stick = 0;
intr_restore(s);
- cpuid = mp_ncpus++;
+ cpuid = cpuids++;
cpuid_to_mid[cpuid] = mid;
cpu_identify(csa->csa_ver, clock, cpuid);
@@ -659,7 +661,6 @@ cheetah_ipi_single(u_int cpu, u_long d0, u_long d1, u_long d2)
static void
cheetah_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
{
- char pbuf[CPUSETBUFSIZ];
register_t s;
u_long ids;
u_int bnp;
@@ -675,14 +676,14 @@ cheetah_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
("%s: outstanding dispatch", __func__));
ids = 0;
- for (i = 0; i < IPI_RETRIES * mp_ncpus; i++) {
+ for (i = 0; i < IPI_RETRIES * smp_cpus; i++) {
s = intr_disable();
stxa(AA_SDB_INTR_D0, ASI_SDB_INTR_W, d0);
stxa(AA_SDB_INTR_D1, ASI_SDB_INTR_W, d1);
stxa(AA_SDB_INTR_D2, ASI_SDB_INTR_W, d2);
membar(Sync);
bnp = 0;
- for (cpu = 0; cpu < mp_ncpus; cpu++) {
+ for (cpu = 0; cpu < smp_cpus; cpu++) {
if (CPU_ISSET(cpu, &cpus)) {
stxa(AA_INTR_SEND | (cpuid_to_mid[cpu] <<
IDC_ITID_SHIFT) | bnp << IDC_BN_SHIFT,
@@ -698,7 +699,7 @@ cheetah_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
;
intr_restore(s);
bnp = 0;
- for (cpu = 0; cpu < mp_ncpus; cpu++) {
+ for (cpu = 0; cpu < smp_cpus; cpu++) {
if (CPU_ISSET(cpu, &cpus)) {
if ((ids & (IDR_NACK << (2 * bnp))) == 0)
CPU_CLR(cpu, &cpus);
@@ -710,10 +711,10 @@ cheetah_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
}
if (kdb_active != 0 || panicstr != NULL)
printf("%s: couldn't send IPI (cpus=%s ids=0x%lu)\n",
- __func__, cpusetobj_strprint(pbuf, &cpus), ids);
+ __func__, cpusetobj_strprint(ipi_pbuf, &cpus), ids);
else
panic("%s: couldn't send IPI (cpus=%s ids=0x%lu)",
- __func__, cpusetobj_strprint(pbuf, &cpus), ids);
+ __func__, cpusetobj_strprint(ipi_pbuf, &cpus), ids);
}
static void
@@ -760,7 +761,6 @@ jalapeno_ipi_single(u_int cpu, u_long d0, u_long d1, u_long d2)
static void
jalapeno_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
{
- char pbuf[CPUSETBUFSIZ];
register_t s;
u_long ids;
u_int cpu;
@@ -775,13 +775,13 @@ jalapeno_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
("%s: outstanding dispatch", __func__));
ids = 0;
- for (i = 0; i < IPI_RETRIES * mp_ncpus; i++) {
+ for (i = 0; i < IPI_RETRIES * smp_cpus; i++) {
s = intr_disable();
stxa(AA_SDB_INTR_D0, ASI_SDB_INTR_W, d0);
stxa(AA_SDB_INTR_D1, ASI_SDB_INTR_W, d1);
stxa(AA_SDB_INTR_D2, ASI_SDB_INTR_W, d2);
membar(Sync);
- for (cpu = 0; cpu < mp_ncpus; cpu++) {
+ for (cpu = 0; cpu < smp_cpus; cpu++) {
if (CPU_ISSET(cpu, &cpus)) {
stxa(AA_INTR_SEND | (cpuid_to_mid[cpu] <<
IDC_ITID_SHIFT), ASI_SDB_INTR_W, 0);
@@ -795,7 +795,7 @@ jalapeno_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
if ((ids &
(IDR_CHEETAH_ALL_BUSY | IDR_CHEETAH_ALL_NACK)) == 0)
return;
- for (cpu = 0; cpu < mp_ncpus; cpu++)
+ for (cpu = 0; cpu < smp_cpus; cpu++)
if (CPU_ISSET(cpu, &cpus))
if ((ids & (IDR_NACK <<
(2 * cpuid_to_mid[cpu]))) == 0)
@@ -803,8 +803,8 @@ jalapeno_ipi_selected(cpuset_t cpus, u_long d0, u_long d1, u_long d2)
}
if (kdb_active != 0 || panicstr != NULL)
printf("%s: couldn't send IPI (cpus=%s ids=0x%lu)\n",
- __func__, cpusetobj_strprint(pbuf, &cpus), ids);
+ __func__, cpusetobj_strprint(ipi_pbuf, &cpus), ids);
else
panic("%s: couldn't send IPI (cpus=%s ids=0x%lu)",
- __func__, cpusetobj_strprint(pbuf, &cpus), ids);
+ __func__, cpusetobj_strprint(ipi_pbuf, &cpus), ids);
}
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 4e2c9ea..1b5ce2d 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -13300,43 +13300,43 @@ softdep_ast_cleanup_proc(void)
bool req;
td = curthread;
- mp = td->td_su;
- if (mp == NULL)
- return;
- td->td_su = NULL;
- error = vfs_busy(mp, MBF_NOWAIT);
- vfs_rel(mp);
- if (error != 0)
- return;
- if (ffs_own_mount(mp) && MOUNTEDSOFTDEP(mp)) {
- ump = VFSTOUFS(mp);
- for (;;) {
- req = false;
- ACQUIRE_LOCK(ump);
- if (softdep_excess_items(ump, D_INODEDEP)) {
- req = true;
- request_cleanup(mp, FLUSH_INODES);
- }
- if (softdep_excess_items(ump, D_DIRREM)) {
- req = true;
- request_cleanup(mp, FLUSH_BLOCKS);
- }
- FREE_LOCK(ump);
- if (softdep_excess_items(ump, D_NEWBLK) ||
- softdep_excess_items(ump, D_ALLOCDIRECT) ||
- softdep_excess_items(ump, D_ALLOCINDIR)) {
- error = vn_start_write(NULL, &mp, V_WAIT);
- if (error == 0) {
+ while ((mp = td->td_su) != NULL) {
+ td->td_su = NULL;
+ error = vfs_busy(mp, MBF_NOWAIT);
+ vfs_rel(mp);
+ if (error != 0)
+ return;
+ if (ffs_own_mount(mp) && MOUNTEDSOFTDEP(mp)) {
+ ump = VFSTOUFS(mp);
+ for (;;) {
+ req = false;
+ ACQUIRE_LOCK(ump);
+ if (softdep_excess_items(ump, D_INODEDEP)) {
+ req = true;
+ request_cleanup(mp, FLUSH_INODES);
+ }
+ if (softdep_excess_items(ump, D_DIRREM)) {
req = true;
- VFS_SYNC(mp, MNT_WAIT);
- vn_finished_write(mp);
+ request_cleanup(mp, FLUSH_BLOCKS);
}
+ FREE_LOCK(ump);
+ if (softdep_excess_items(ump, D_NEWBLK) ||
+ softdep_excess_items(ump, D_ALLOCDIRECT) ||
+ softdep_excess_items(ump, D_ALLOCINDIR)) {
+ error = vn_start_write(NULL, &mp,
+ V_WAIT);
+ if (error == 0) {
+ req = true;
+ VFS_SYNC(mp, MNT_WAIT);
+ vn_finished_write(mp);
+ }
+ }
+ if ((td->td_pflags & TDP_KTHREAD) != 0 || !req)
+ break;
}
- if ((td->td_pflags & TDP_KTHREAD) != 0 || !req)
- break;
}
+ vfs_unbusy(mp);
}
- vfs_unbusy(mp);
}
/*
diff --git a/sys/x86/x86/busdma_bounce.c b/sys/x86/x86/busdma_bounce.c
index f5c1b92..38c9f1e 100644
--- a/sys/x86/x86/busdma_bounce.c
+++ b/sys/x86/x86/busdma_bounce.c
@@ -751,6 +751,9 @@ bounce_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
{
struct bounce_page *bpage;
+ if (map == NULL)
+ return;
+
while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
STAILQ_REMOVE_HEAD(&map->bpages, links);
free_bounce_page(dmat, bpage);
@@ -763,47 +766,43 @@ bounce_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map,
{
struct bounce_page *bpage;
- if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
- /*
- * Handle data bouncing. We might also
- * want to add support for invalidating
- * the caches on broken hardware
- */
- CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
- "performing bounce", __func__, dmat,
- dmat->common.flags, op);
-
- if ((op & BUS_DMASYNC_PREWRITE) != 0) {
- while (bpage != NULL) {
- if (bpage->datavaddr != 0) {
- bcopy((void *)bpage->datavaddr,
- (void *)bpage->vaddr,
- bpage->datacount);
- } else {
- physcopyout(bpage->dataaddr,
- (void *)bpage->vaddr,
- bpage->datacount);
- }
- bpage = STAILQ_NEXT(bpage, links);
+ if (map == NULL || (bpage = STAILQ_FIRST(&map->bpages)) == NULL)
+ return;
+
+ /*
+ * Handle data bouncing. We might also want to add support for
+ * invalidating the caches on broken hardware.
+ */
+ CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
+ "performing bounce", __func__, dmat, dmat->common.flags, op);
+
+ if ((op & BUS_DMASYNC_PREWRITE) != 0) {
+ while (bpage != NULL) {
+ if (bpage->datavaddr != 0) {
+ bcopy((void *)bpage->datavaddr,
+ (void *)bpage->vaddr, bpage->datacount);
+ } else {
+ physcopyout(bpage->dataaddr,
+ (void *)bpage->vaddr, bpage->datacount);
}
- dmat->bounce_zone->total_bounced++;
+ bpage = STAILQ_NEXT(bpage, links);
}
+ dmat->bounce_zone->total_bounced++;
+ }
- if ((op & BUS_DMASYNC_POSTREAD) != 0) {
- while (bpage != NULL) {
- if (bpage->datavaddr != 0) {
- bcopy((void *)bpage->vaddr,
- (void *)bpage->datavaddr,
- bpage->datacount);
- } else {
- physcopyin((void *)bpage->vaddr,
- bpage->dataaddr,
- bpage->datacount);
- }
- bpage = STAILQ_NEXT(bpage, links);
+ if ((op & BUS_DMASYNC_POSTREAD) != 0) {
+ while (bpage != NULL) {
+ if (bpage->datavaddr != 0) {
+ bcopy((void *)bpage->vaddr,
+ (void *)bpage->datavaddr,
+ bpage->datacount);
+ } else {
+ physcopyin((void *)bpage->vaddr,
+ bpage->dataaddr, bpage->datacount);
}
- dmat->bounce_zone->total_bounced++;
+ bpage = STAILQ_NEXT(bpage, links);
}
+ dmat->bounce_zone->total_bounced++;
}
}
@@ -822,12 +821,14 @@ SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL);
static struct sysctl_ctx_list *
busdma_sysctl_tree(struct bounce_zone *bz)
{
+
return (&bz->sysctl_tree);
}
static struct sysctl_oid *
busdma_sysctl_tree_top(struct bounce_zone *bz)
{
+
return (bz->sysctl_tree_top);
}
diff --git a/tests/freebsd_test_suite/macros.h b/tests/freebsd_test_suite/macros.h
index 8d95f05..98da0ed 100644
--- a/tests/freebsd_test_suite/macros.h
+++ b/tests/freebsd_test_suite/macros.h
@@ -38,6 +38,13 @@
#include <atf-c.h>
+#define ATF_REQUIRE_FEATURE(_feature_name) do { \
+ if (feature_present(_feature_name) == 0) { \
+ atf_tc_skip("kernel feature (%s) not present", \
+ _feature_name); \
+ } \
+} while(0)
+
#define ATF_REQUIRE_KERNEL_MODULE(_mod_name) do { \
if (modfind(_mod_name) == -1) { \
atf_tc_skip("module %s could not be resolved: %s", \
@@ -45,6 +52,14 @@
} \
} while(0)
+#define PLAIN_REQUIRE_FEATURE(_feature_name, _exit_code) do { \
+ if (feature_present(_feature_name) == 0) { \
+ printf("kernel feature (%s) not present\n", \
+ _feature_name); \
+ _exit(_exit_code); \
+ } \
+} while(0)
+
#define PLAIN_REQUIRE_KERNEL_MODULE(_mod_name, _exit_code) do { \
if (modfind(_mod_name) == -1) { \
printf("module %s could not be resolved: %s\n", \
diff --git a/tools/debugscripts/README b/tools/debugscripts/README
index 2081531..a218368 100644
--- a/tools/debugscripts/README
+++ b/tools/debugscripts/README
@@ -14,8 +14,8 @@ perform kernel debugging, you would do:
(kgdb)
-This directory also contains a kgdb script that given a crash dump number
-automatically extract the path to the kernel source, run gdb to extract
-information about kernel modules loaded, and then rerun gdb loading the
+This directory also contains a kgdb script that, given a crash dump number,
+automatically extracts the path to the kernel source, runs gdb to extract
+information about kernel modules loaded, and then reruns gdb loading the
necessary symbols for the modules. You need to make sure you build the
modules w/ debugging symbols separately to get things to work.
diff --git a/tools/regression/lib/libc/nss/mach b/tools/regression/lib/libc/nss/mach
index ab7ce24..4b47ebb 100644
--- a/tools/regression/lib/libc/nss/mach
+++ b/tools/regression/lib/libc/nss/mach
@@ -1,32 +1,17 @@
# $FreeBSD$
localhost
-above.warped.net
anoncvs.cirr.com
-anoncvs.isc.netbsd.org
-anoncvs.leo.org
-anoncvs.netbsd.lt
-anoncvs.netbsd.ro
anoncvs.netbsd.se
antioche.antioche.eu.org
-boulder.tele.dk
centaurus.4web.cz
chur.math.ntnu.no
console.netbsd.org
-cvs.fi.netbsd.org
-cvs.mikrolahti.fi
cvs.netbsd.org
-cvsup-netbsd.leo.org
cvsup.netbsd.se
-cvsup.pasta.cs.uit.no
-ftp.bitcon.no
ftp.chg.ru
-ftp.duth.gr
ftp.estpak.ee
ftp.fsn.hu
ftp.funet.fi
-ftp.grondar.za
-ftp.leo.org
-ftp.netbsd.lt
ftp.netbsd.org
ftp.nluug.nl
ftp.plig.org
@@ -34,60 +19,28 @@ ftp.uni-erlangen.de
ftp.xgate.co.kr
gd.tuwien.ac.at
gort.ludd.luth.se
-grappa.unix-ag.uni-kl.de
-info.wins.uva.nl
irc.warped.net
knug.youn.co.kr
-lala.iri.co.jp
mail.jp.netbsd.org
-mail.kr.netbsd.org
mail.netbsd.org
melanoma.cs.rmit.edu.au
mirror.aarnet.edu.au
-mirror.netbsd.com.br
-mirror03.inet.tele.dk
moon.vub.ac.be
-nbwww.sergei.cc
net.bsd.cz
netbsd.3miasto.net
netbsd.4ka.mipt.ru
-netbsd.apk.od.ua
netbsd.csie.nctu.edu.tw
netbsd.enderunix.org
netbsd.ftp.fu-berlin.de
-netbsd.netlead.com.au
-netbsd.nsysu.edu.tw
netbsd.pair.com
-netbsd.stevens-tech.edu
-netbsd.triada.bg
-netbsd.unix.net.nz
-netbsd.unixtech.be
-netbsd.vejas.lt
-netbsd.wagener-consulting.lu
-netbsd.zarco.org
netbsdiso.interoute.net.uk
-netbsdwww.bitcon.no
-netbsdwww.cordef.com.pl
netbsdwww.cs.rmit.edu.au
netbsdwww.interoute.net.uk
-news.gw.com
ns.netbsd.org
-pigu.iri.co.jp
-pluto.cdpa.nsysu.edu.tw
-projects.slowass.net
-server6.pasta.cs.uit.no
skeleton.phys.spbu.ru
-snoopy.allbsd.org
-spike.allbsd.org
-sundry.netbsd.org
-tanya.sergei.cc
-web-a.fi.gw.com
-web-a.us.gw.com
-web.netbsd.mirror.arhea.net
www.en.netbsd.de
www.netbsd.cl
www.netbsd.nl
www.netbsd.org
www.netbsd.ro
-zathras.netbsd.org
zeppo.rediris.es
diff --git a/tools/regression/lib/libc/resolv/mach b/tools/regression/lib/libc/resolv/mach
index ab7ce24..4b47ebb 100644
--- a/tools/regression/lib/libc/resolv/mach
+++ b/tools/regression/lib/libc/resolv/mach
@@ -1,32 +1,17 @@
# $FreeBSD$
localhost
-above.warped.net
anoncvs.cirr.com
-anoncvs.isc.netbsd.org
-anoncvs.leo.org
-anoncvs.netbsd.lt
-anoncvs.netbsd.ro
anoncvs.netbsd.se
antioche.antioche.eu.org
-boulder.tele.dk
centaurus.4web.cz
chur.math.ntnu.no
console.netbsd.org
-cvs.fi.netbsd.org
-cvs.mikrolahti.fi
cvs.netbsd.org
-cvsup-netbsd.leo.org
cvsup.netbsd.se
-cvsup.pasta.cs.uit.no
-ftp.bitcon.no
ftp.chg.ru
-ftp.duth.gr
ftp.estpak.ee
ftp.fsn.hu
ftp.funet.fi
-ftp.grondar.za
-ftp.leo.org
-ftp.netbsd.lt
ftp.netbsd.org
ftp.nluug.nl
ftp.plig.org
@@ -34,60 +19,28 @@ ftp.uni-erlangen.de
ftp.xgate.co.kr
gd.tuwien.ac.at
gort.ludd.luth.se
-grappa.unix-ag.uni-kl.de
-info.wins.uva.nl
irc.warped.net
knug.youn.co.kr
-lala.iri.co.jp
mail.jp.netbsd.org
-mail.kr.netbsd.org
mail.netbsd.org
melanoma.cs.rmit.edu.au
mirror.aarnet.edu.au
-mirror.netbsd.com.br
-mirror03.inet.tele.dk
moon.vub.ac.be
-nbwww.sergei.cc
net.bsd.cz
netbsd.3miasto.net
netbsd.4ka.mipt.ru
-netbsd.apk.od.ua
netbsd.csie.nctu.edu.tw
netbsd.enderunix.org
netbsd.ftp.fu-berlin.de
-netbsd.netlead.com.au
-netbsd.nsysu.edu.tw
netbsd.pair.com
-netbsd.stevens-tech.edu
-netbsd.triada.bg
-netbsd.unix.net.nz
-netbsd.unixtech.be
-netbsd.vejas.lt
-netbsd.wagener-consulting.lu
-netbsd.zarco.org
netbsdiso.interoute.net.uk
-netbsdwww.bitcon.no
-netbsdwww.cordef.com.pl
netbsdwww.cs.rmit.edu.au
netbsdwww.interoute.net.uk
-news.gw.com
ns.netbsd.org
-pigu.iri.co.jp
-pluto.cdpa.nsysu.edu.tw
-projects.slowass.net
-server6.pasta.cs.uit.no
skeleton.phys.spbu.ru
-snoopy.allbsd.org
-spike.allbsd.org
-sundry.netbsd.org
-tanya.sergei.cc
-web-a.fi.gw.com
-web-a.us.gw.com
-web.netbsd.mirror.arhea.net
www.en.netbsd.de
www.netbsd.cl
www.netbsd.nl
www.netbsd.org
www.netbsd.ro
-zathras.netbsd.org
zeppo.rediris.es
diff --git a/tools/regression/lib/msun/test-ctrig.c b/tools/regression/lib/msun/test-ctrig.c
index 9f9b88d..475b6c5 100644
--- a/tools/regression/lib/msun/test-ctrig.c
+++ b/tools/regression/lib/msun/test-ctrig.c
@@ -427,6 +427,7 @@ test_large(void)
test_odd_tol(ctanh, z,
CMPLXL(1.0, 8.95257245135025991216632140458264468e-309L),
DBL_ULP());
+#if !defined(__i386__)
z = CMPLXL(30, 0x1p1023L);
test_odd_tol(ctanh, z,
CMPLXL(1.0, -1.62994325413993477997492170229268382e-26L),
@@ -436,6 +437,7 @@ test_large(void)
CMPLXL(0.878606311888306869546254022621986509L,
-0.225462792499754505792678258169527424L),
DBL_ULP());
+#endif
z = CMPLXL(710.6, 0.78539816339744830961566084581987572L);
test_odd_tol(csinh, z,
diff --git a/tools/regression/lib/msun/test-exponential.c b/tools/regression/lib/msun/test-exponential.c
index 010e0fd..df552ee 100644
--- a/tools/regression/lib/msun/test-exponential.c
+++ b/tools/regression/lib/msun/test-exponential.c
@@ -66,13 +66,22 @@ __FBSDID("$FreeBSD$");
} while (0)
/* Test all the functions that compute b^x. */
-#define testall0(x, result, exceptmask, excepts) do { \
+#define _testall0(x, result, exceptmask, excepts) do { \
test(exp, x, result, exceptmask, excepts); \
test(expf, x, result, exceptmask, excepts); \
test(exp2, x, result, exceptmask, excepts); \
test(exp2f, x, result, exceptmask, excepts); \
+} while (0)
+
+/* Skip over exp2l on platforms that don't support it. */
+#if LDBL_PREC == 53
+#define testall0 _testall0
+#else
+#define testall0(x, result, exceptmask, excepts) do { \
+ _testall0(x, result, exceptmask, excepts); \
test(exp2l, x, result, exceptmask, excepts); \
} while (0)
+#endif
/* Test all the functions that compute b^x - 1. */
#define testall1(x, result, exceptmask, excepts) do { \
@@ -102,12 +111,14 @@ run_generic_tests(void)
testall0(-INFINITY, 0.0, ALL_STD_EXCEPT, 0);
testall1(-INFINITY, -1.0, ALL_STD_EXCEPT, 0);
+#if !defined(__i386__)
/* exp(big) == Inf, overflow exception */
testall0(50000.0, INFINITY, ALL_STD_EXCEPT & ~FE_INEXACT, FE_OVERFLOW);
testall1(50000.0, INFINITY, ALL_STD_EXCEPT & ~FE_INEXACT, FE_OVERFLOW);
/* exp(small) == 0, underflow and inexact exceptions */
testall0(-50000.0, 0.0, ALL_STD_EXCEPT, FE_UNDERFLOW | FE_INEXACT);
+#endif
testall1(-50000.0, -1.0, ALL_STD_EXCEPT, FE_INEXACT);
}
diff --git a/tools/regression/lib/msun/test-fma.c b/tools/regression/lib/msun/test-fma.c
index 1fcf889..7adbd81 100644
--- a/tools/regression/lib/msun/test-fma.c
+++ b/tools/regression/lib/msun/test-fma.c
@@ -31,11 +31,13 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/param.h>
#include <assert.h>
#include <fenv.h>
#include <float.h>
#include <math.h>
#include <stdio.h>
+#include <stdlib.h>
#include "test-utils.h"
@@ -473,44 +475,58 @@ int
main(int argc, char *argv[])
{
int rmodes[] = { FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };
- int i;
+ int i, j;
+
+#if defined(__i386__)
+ printf("1..0 # SKIP all testcases fail on i386\n");
+ exit(0);
+#endif
+
+ j = 1;
printf("1..19\n");
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < nitems(rmodes); i++, j++) {
+ printf("rmode = %d\n", rmodes[i]);
fesetround(rmodes[i]);
test_zeroes();
- printf("ok %d - fma zeroes\n", i + 1);
+ printf("ok %d - fma zeroes\n", j);
}
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < nitems(rmodes); i++, j++) {
+ printf("rmode = %d\n", rmodes[i]);
fesetround(rmodes[i]);
test_infinities();
- printf("ok %d - fma infinities\n", i + 5);
+ printf("ok %d - fma infinities\n", j);
}
fesetround(FE_TONEAREST);
test_nans();
- printf("ok 9 - fma NaNs\n");
+ printf("ok %d - fma NaNs\n", j);
+ j++;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < nitems(rmodes); i++, j++) {
+ printf("rmode = %d\n", rmodes[i]);
fesetround(rmodes[i]);
test_small_z();
- printf("ok %d - fma small z\n", i + 10);
+ printf("ok %d - fma small z\n", j);
}
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < nitems(rmodes); i++, j++) {
+ printf("rmode = %d\n", rmodes[i]);
fesetround(rmodes[i]);
test_big_z();
- printf("ok %d - fma big z\n", i + 14);
+ printf("ok %d - fma big z\n", j);
}
fesetround(FE_TONEAREST);
test_accuracy();
- printf("ok 18 - fma accuracy\n");
+ printf("ok %d - fma accuracy\n", j);
+ j++;
test_double_rounding();
- printf("ok 19 - fma double rounding\n");
+ printf("ok %d - fma double rounding\n", j);
+ j++;
/*
* TODO:
diff --git a/tools/regression/lib/msun/test-invctrig.c b/tools/regression/lib/msun/test-invctrig.c
index 78b1119..34e78a1 100644
--- a/tools/regression/lib/msun/test-invctrig.c
+++ b/tools/regression/lib/msun/test-invctrig.c
@@ -281,21 +281,21 @@ test_axes(void)
for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) {
/* Real axis */
z = CMPLXL(nums[i], 0.0);
- if (fabs(nums[i]) <= 1) {
+ if (fabsl(nums[i]) <= 1) {
testall_tol(cacosh, z, CMPLXL(0.0, acos(nums[i])), 1);
testall_tol(cacos, z, CMPLXL(acosl(nums[i]), -0.0), 1);
testall_tol(casin, z, CMPLXL(asinl(nums[i]), 0.0), 1);
testall_tol(catanh, z, CMPLXL(atanh(nums[i]), 0.0), 1);
} else {
testall_tol(cacosh, z,
- CMPLXL(acosh(fabs(nums[i])),
+ CMPLXL(acosh(fabsl(nums[i])),
(nums[i] < 0) ? pi : 0), 1);
testall_tol(cacos, z,
CMPLXL((nums[i] < 0) ? pi : 0,
- -acosh(fabs(nums[i]))), 1);
+ -acosh(fabsl(nums[i]))), 1);
testall_tol(casin, z,
CMPLXL(copysign(pi / 2, nums[i]),
- acosh(fabs(nums[i]))), 1);
+ acosh(fabsl(nums[i]))), 1);
testall_tol(catanh, z,
CMPLXL(atanh(1 / nums[i]), pi / 2), 1);
}
diff --git a/tools/regression/lib/msun/test-invtrig.c b/tools/regression/lib/msun/test-invtrig.c
index 2523d59..2110df4 100644
--- a/tools/regression/lib/msun/test-invtrig.c
+++ b/tools/regression/lib/msun/test-invtrig.c
@@ -63,14 +63,23 @@ __FBSDID("$FreeBSD$");
#define test(func, x, result, excepts) \
test_tol(func, (x), (result), 0, (excepts))
-#define testall_tol(prefix, x, result, tol, excepts) do { \
+#define _testall_tol(prefix, x, result, tol, excepts) do { \
test_tol(prefix, (double)(x), (double)(result), \
(tol) * ldexp(1.0, 1 - DBL_MANT_DIG), (excepts)); \
test_tol(prefix##f, (float)(x), (float)(result), \
(tol) * ldexpf(1.0, 1 - FLT_MANT_DIG), (excepts)); \
+} while (0)
+
+#if LDBL_PREC == 53
+#define testall_tol _testall_tol
+#else
+#define testall_tol(prefix, x, result, tol, excepts) do { \
+ _testall_tol(prefix, x, result, tol, excepts); \
test_tol(prefix##l, (x), (result), \
(tol) * ldexpl(1.0, 1 - LDBL_MANT_DIG), (excepts)); \
} while (0)
+#endif
+
#define testall(prefix, x, result, excepts) \
testall_tol(prefix, (x), (result), 0, (excepts))
@@ -83,14 +92,23 @@ __FBSDID("$FreeBSD$");
#define test2(func, y, x, result, excepts) \
test2_tol(func, (y), (x), (result), 0, (excepts))
-#define testall2_tol(prefix, y, x, result, tol, excepts) do { \
+#define _testall2_tol(prefix, y, x, result, tol, excepts) do { \
test2_tol(prefix, (double)(y), (double)(x), (double)(result), \
(tol) * ldexp(1.0, 1 - DBL_MANT_DIG), (excepts)); \
test2_tol(prefix##f, (float)(y), (float)(x), (float)(result), \
(tol) * ldexpf(1.0, 1 - FLT_MANT_DIG), (excepts)); \
+} while (0)
+
+#if LDBL_PREC == 53
+#define testall2_tol _testall2_tol
+#else
+#define testall2_tol(prefix, y, x, result, tol, excepts) do { \
+ _testall2_tol(prefix, y, x, result, tol, excepts); \
test2_tol(prefix##l, (y), (x), (result), \
(tol) * ldexpl(1.0, 1 - LDBL_MANT_DIG), (excepts)); \
} while (0)
+#endif
+
#define testall2(prefix, y, x, result, excepts) \
testall2_tol(prefix, (y), (x), (result), 0, (excepts))
@@ -431,6 +449,11 @@ int
main(int argc, char *argv[])
{
+#if defined(__i386__)
+ printf("1..0 # SKIP fails all assertions on i386\n");
+ return (0);
+#endif
+
printf("1..7\n");
test_special();
diff --git a/usr.bin/bc/bc.1 b/usr.bin/bc/bc.1
index 2d539ee..a762832 100644
--- a/usr.bin/bc/bc.1
+++ b/usr.bin/bc/bc.1
@@ -1,5 +1,5 @@
.\" $FreeBSD$
-.\" $OpenBSD: bc.1,v 1.30 2014/01/14 07:42:42 jmc Exp $
+.\" $OpenBSD: bc.1,v 1.32 2015/11/17 05:45:35 mmcc Exp $
.\"
.\" Copyright (C) Caldera International Inc. 2001-2002.
.\" All rights reserved.
@@ -35,7 +35,7 @@
.\"
.\" @(#)bc.1 6.8 (Berkeley) 8/8/91
.\"
-.Dd April 16, 2014
+.Dd November 21 2015
.Dt BC 1
.Os
.Sh NAME
@@ -407,8 +407,9 @@ The current version of the
utility was written by
.An Otto Moerbeek .
.Sh BUGS
-.Ql Quit
-is interpreted when read, not when executed.
+The
+.Ql quit
+statement is interpreted when read, not when executed.
.Pp
Some non-portable extensions, as found in the GNU version of the
.Nm
diff --git a/usr.bin/bc/bc.y b/usr.bin/bc/bc.y
index 8e7e00c..50454e6 100644
--- a/usr.bin/bc/bc.y
+++ b/usr.bin/bc/bc.y
@@ -1125,7 +1125,7 @@ main(int argc, char *argv[])
int ch, i;
init();
- setlinebuf(stdout);
+ setvbuf(stdout, NULL, _IOLBF, 0);
sargv = malloc(argc * sizeof(char *));
if (sargv == NULL)
diff --git a/usr.bin/bc/extern.h b/usr.bin/bc/extern.h
index 685942a..7909a17 100644
--- a/usr.bin/bc/extern.h
+++ b/usr.bin/bc/extern.h
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $OpenBSD: extern.h,v 1.10 2013/09/19 16:12:01 otto Exp $ */
+/* $OpenBSD: extern.h,v 1.12 2014/04/17 19:07:14 otto Exp $ */
/*
* Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
@@ -39,9 +39,9 @@ extern int fileindex;
extern int sargc;
extern const char **sargv;
extern const char *filename;
-extern bool interactive;
-extern EditLine *el;
-extern History *hist;
-extern HistEvent he;
+extern bool interactive;
+extern EditLine *el;
+extern History *hist;
+extern HistEvent he;
extern char *cmdexpr;
extern struct termios ttysaved;
diff --git a/usr.bin/bc/tty.c b/usr.bin/bc/tty.c
index 05f9d14..f5d72fc 100644
--- a/usr.bin/bc/tty.c
+++ b/usr.bin/bc/tty.c
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $OpenBSD: tty.c,v 1.2 2013/11/12 13:54:51 deraadt Exp $ */
+/* $OpenBSD: tty.c,v 1.3 2015/09/05 09:49:24 jsg Exp $ */
/*
* Copyright (c) 2013, Otto Moerbeek <otto@drijf.net>
@@ -30,7 +30,7 @@ settty(struct termios *t)
{
int ret;
- while ((ret = tcsetattr(0, TCSADRAIN, t) == -1) && errno == EINTR)
+ while ((ret = tcsetattr(0, TCSADRAIN, t)) == -1 && errno == EINTR)
continue;
return ret;
}
@@ -40,7 +40,7 @@ gettty(struct termios *t)
{
int ret;
- while ((ret = tcgetattr(0, t) == -1) && errno == EINTR)
+ while ((ret = tcgetattr(0, t)) == -1 && errno == EINTR)
continue;
return ret;
}
diff --git a/usr.sbin/ypserv/Makefile.yp b/usr.sbin/ypserv/Makefile.yp
index fc207b6..17eabe5 100644
--- a/usr.sbin/ypserv/Makefile.yp
+++ b/usr.sbin/ypserv/Makefile.yp
@@ -141,6 +141,7 @@ target:
# If you want to omit some of them, feel free to comment
# them out from this list.
TARGETS= servers hosts networks protocols rpc services shells group
+TARGETS+= ipnodes
#TARGETS+= aliases
# Sanity checks: filter out targets we can't build
@@ -193,10 +194,8 @@ TARGETS+= amd.map
AMDHOST= /dev/null
.endif
-.if exists($(IPNODES))
-TARGETS+= ipnodes
-.else
-IPNODES= /dev/null
+.if !exists($(IPNODES))
+IPNODES= $(HOSTS)
.endif
all: $(TARGETS)
@@ -387,9 +386,22 @@ netgroup.byuser: $(NETGROUP)
.endif
+# Solaris 8 does the following:
+# - /etc/hosts and hosts.{byname,byaddr} are IPv4 only.
+# - /etc/inet/ipnodes and ipnodes.{byname,byaddr} are used for protocol
+# independent name-to-address mapping.
+#
+# For local name resolution, we made /etc/hosts protocol independent.
+# For NIS name resolution, we obey Solaris 8 practice.
+# - We keep hosts.{byname,byaddr} IPv4 only, to be friendly with Solaris 8
+# clients.
+# - ipnodes.{byname,byaddr} is used for protocol independent mapping.
+# We generate all the mappings from /etc/hosts unless /var/yp/ipnodes
+# exists, for compatibility with FreeBSD local name resolution.
+#
hosts.byname: $(HOSTS)
@echo "Updating $@..."
- @$(AWK) '/^[0-9]/ { for (n=2; n<=NF && $$n !~ "^#.*"; n++) \
+ @$(AWK) '/^[0-9.]+[\t ]/ { for (n=2; n<=NF && $$n !~ "^#.*"; n++) \
print $$n"\t"$$0 }' $(HOSTS) | $(DBLOAD) ${B} -i $(HOSTS) \
-o $(YPMAPDIR)/$@ - $(TMP); $(RMV) $(TMP) $@
@$(DBLOAD) -c
@@ -399,7 +411,7 @@ hosts.byname: $(HOSTS)
hosts.byaddr: $(HOSTS)
@echo "Updating $@..."
- @$(AWK) '$$1 !~ "^#.*" { print $$1"\t"$$0 }' $(HOSTS) \
+ @$(AWK) '/^[0-9.]+[\t ]/ { print $$1"\t"$$0 }' $(HOSTS) \
| $(DBLOAD) ${B} -i $(HOSTS) -o $(YPMAPDIR)/$@ - $(TMP); \
$(RMV) $(TMP) $@
@$(DBLOAD) -c
@@ -409,30 +421,22 @@ hosts.byaddr: $(HOSTS)
ipnodes.byname: $(IPNODES)
@echo "Updating $@..."
-.if ${IPNODES} == "/dev/null"
- @echo "Ipnodes source file not found -- skipping"
-.else
@$(AWK) '/^[0-9a-fA-F:]/ { for (n=2; n<=NF && $$n !~ "^#.*"; n++) \
print $$n"\t"$$0 }' $(IPNODES) | $(DBLOAD) ${B} -i $(IPNODES) \
-o $(YPMAPDIR)/$@ - $(TMP); $(RMV) $(TMP) $@
@$(DBLOAD) -c
@if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
@if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
-.endif
ipnodes.byaddr: $(IPNODES)
@echo "Updating $@..."
-.if ${IPNODES} == "/dev/null"
- @echo "Ipnodes source file not found -- skipping"
-.else
@$(AWK) '$$1 !~ "^#.*" { print $$1"\t"$$0 }' $(IPNODES) \
| $(DBLOAD) ${B} -i $(IPNODES) -o $(YPMAPDIR)/$@ - $(TMP); \
$(RMV) $(TMP) $@
@$(DBLOAD) -c
@if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
@if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
-.endif
networks.byname: $(NETWORKS)
OpenPOWER on IntegriCloud