From e81b1c71290acd1feb668a81a57a3cdc88d32bb4 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 22 Jun 2011 19:14:49 +0000 Subject: [PATCH 01/57] Add LOGIN_SETCPUMASK and LOGIN_SETLOGINCLASS to the setusercontext(3) calls in ftpd(8). --- libexec/ftpd/ftpd.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c index 21c218e171fb..5894f3c7c3b7 100644 --- a/libexec/ftpd/ftpd.c +++ b/libexec/ftpd/ftpd.c @@ -1191,9 +1191,9 @@ end_login(void) ftpd_logwtmp(wtmpid, NULL, NULL); pw = NULL; #ifdef LOGIN_CAP - setusercontext(NULL, getpwuid(0), 0, - LOGIN_SETPRIORITY|LOGIN_SETRESOURCES|LOGIN_SETUMASK| - LOGIN_SETMAC); + setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN | + LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH | + LOGIN_SETENV)); #endif #ifdef USE_PAM if (pamh) { @@ -1465,9 +1465,8 @@ skip: return; } } - setusercontext(lc, pw, 0, - LOGIN_SETLOGIN|LOGIN_SETGROUP|LOGIN_SETPRIORITY| - LOGIN_SETRESOURCES|LOGIN_SETUMASK|LOGIN_SETMAC); + setusercontext(lc, pw, 0, LOGIN_SETALL & + ~(LOGIN_SETUSER | LOGIN_SETPATH | LOGIN_SETENV)); #else setlogin(pw->pw_name); (void) initgroups(pw->pw_name, pw->pw_gid); From 72b7c8ddb1fd4ee8e66be7345b5e09ec41b217db Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 22 Jun 2011 19:47:45 +0000 Subject: [PATCH 02/57] Fix the new NFSv4 client so that it uses the same uid as was used for doing a mount when performing system operations on AUTH_SYS mounts. This resolved an issue when mounting a Linux server. Found during testing at the recent NFSv4 interoperability Bakeathon. MFC after: 2 weeks --- sys/fs/nfs/nfs_commonkrpc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index df23e49f8daf..c34ea87a0e36 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -526,6 +526,20 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, else secflavour = RPCSEC_GSS_KRB5; srv_principal = NFSMNT_SRVKRBNAME(nmp); + } else if (nmp != NULL && !NFSHASKERB(nmp) && + nd->nd_procnum != NFSPROC_NULL && + (nd->nd_flag & ND_USEGSSNAME) != 0) { + /* + * Use the uid that did the mount when the RPC is doing + * NFSv4 system operations, as indicated by the + * ND_USEGSSNAME flag, for the AUTH_SYS case. + */ + saved_uid = cred->cr_uid; + if (nmp->nm_uid != (uid_t)-1) + cred->cr_uid = nmp->nm_uid; + else + cred->cr_uid = 0; + set_uid = 1; } if (nmp != NULL) { From 0511675327e630aa81e6c358821feda8790e76a9 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Wed, 22 Jun 2011 20:00:27 +0000 Subject: [PATCH 03/57] Export AddLink() function from libalias. It can be used when custom alias address needs to be specified. Add inbound handler to the alias_ftp module. It helps handle active FTP transfer mode for the case with external clients and FTP server behind NAT. Fix passive FTP transfer case for server behind NAT using redirect with external IP address different from NAT ip address. PR: kern/157957 Submitted by: Alexander V. Chernikov --- sys/netinet/libalias/alias_db.c | 24 ++---- sys/netinet/libalias/alias_ftp.c | 124 ++++++++++++++++++++++++----- sys/netinet/libalias/alias_local.h | 7 ++ sys/netinet/libalias/libalias.3 | 11 +++ 4 files changed, 127 insertions(+), 39 deletions(-) diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c index 9b30793b1a7e..4e0837ff5ef5 100644 --- a/sys/netinet/libalias/alias_db.c +++ b/sys/netinet/libalias/alias_db.c @@ -551,10 +551,6 @@ static void IncrementalCleanup(struct libalias *); static void DeleteLink(struct alias_link *); -static struct alias_link * -AddLink(struct libalias *, struct in_addr, struct in_addr, struct in_addr, - u_short, u_short, int, int); - static struct alias_link * ReLink(struct alias_link *, struct in_addr, struct in_addr, struct in_addr, @@ -572,9 +568,6 @@ static struct alias_link * #define ALIAS_PORT_MASK_EVEN 0x07ffe #define GET_NEW_PORT_MAX_ATTEMPTS 20 -#define GET_ALIAS_PORT -1 -#define GET_ALIAS_ID GET_ALIAS_PORT - #define FIND_EVEN_ALIAS_BASE 1 /* GetNewPort() allocates port numbers. Note that if a port number @@ -937,17 +930,12 @@ DeleteLink(struct alias_link *lnk) } -static struct alias_link * -AddLink(struct libalias *la, struct in_addr src_addr, - struct in_addr dst_addr, - struct in_addr alias_addr, - u_short src_port, - u_short dst_port, - int alias_port_param, /* if less than zero, alias */ - int link_type) -{ /* port will be automatically *//* chosen. - * If greater than */ - u_int start_point; /* zero, equal to alias port */ +struct alias_link * +AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, + struct in_addr alias_addr, u_short src_port, u_short dst_port, + int alias_port_param, int link_type) +{ + u_int start_point; struct alias_link *lnk; LIBALIAS_LOCK_ASSERT(la); diff --git a/sys/netinet/libalias/alias_ftp.c b/sys/netinet/libalias/alias_ftp.c index ef0e52ce695f..8e7d05b4f363 100644 --- a/sys/netinet/libalias/alias_ftp.c +++ b/sys/netinet/libalias/alias_ftp.c @@ -100,38 +100,68 @@ __FBSDID("$FreeBSD$"); #define FTP_CONTROL_PORT_NUMBER 21 static void -AliasHandleFtpOut(struct libalias *, struct ip *, struct alias_link *, - int maxpacketsize); +AliasHandleFtpOut(struct libalias *, struct ip *, struct alias_link *, + int maxpacketsize); +static void +AliasHandleFtpIn(struct libalias *, struct ip *, struct alias_link *); -static int -fingerprint(struct libalias *la, struct alias_data *ah) +static int +fingerprint_out(struct libalias *la, struct alias_data *ah) { - if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL || - ah->maxpktsize == 0) + if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL || + ah->maxpktsize == 0) return (-1); - if (ntohs(*ah->dport) == FTP_CONTROL_PORT_NUMBER - || ntohs(*ah->sport) == FTP_CONTROL_PORT_NUMBER) + if (ntohs(*ah->dport) == FTP_CONTROL_PORT_NUMBER || + ntohs(*ah->sport) == FTP_CONTROL_PORT_NUMBER) return (0); return (-1); } -static int -protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah) +static int +fingerprint_in(struct libalias *la, struct alias_data *ah) { - + + if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL) + return (-1); + if (ntohs(*ah->dport) == FTP_CONTROL_PORT_NUMBER || + ntohs(*ah->sport) == FTP_CONTROL_PORT_NUMBER) + return (0); + return (-1); +} + +static int +protohandler_out(struct libalias *la, struct ip *pip, struct alias_data *ah) +{ + AliasHandleFtpOut(la, pip, ah->lnk, ah->maxpktsize); return (0); } + +static int +protohandler_in(struct libalias *la, struct ip *pip, struct alias_data *ah) +{ + + AliasHandleFtpIn(la, pip, ah->lnk); + return (0); +} + struct proto_handler handlers[] = { - { - .pri = 80, - .dir = OUT, - .proto = TCP, - .fingerprint = &fingerprint, - .protohandler = &protohandler - }, + { + .pri = 80, + .dir = OUT, + .proto = TCP, + .fingerprint = &fingerprint_out, + .protohandler = &protohandler_out + }, + { + .pri = 80, + .dir = IN, + .proto = TCP, + .fingerprint = &fingerprint_in, + .protohandler = &protohandler_in + }, { EOH } }; @@ -256,6 +286,57 @@ AliasHandleFtpOut( } } +static void +AliasHandleFtpIn(struct libalias *la, + struct ip *pip, /* IP packet to examine/patch */ + struct alias_link *lnk) /* The link to go through (aliased port) */ +{ + int hlen, tlen, dlen, pflags; + char *sptr; + struct tcphdr *tc; + + /* Calculate data length of TCP packet */ + tc = (struct tcphdr *)ip_next(pip); + hlen = (pip->ip_hl + tc->th_off) << 2; + tlen = ntohs(pip->ip_len); + dlen = tlen - hlen; + + /* Place string pointer and beginning of data */ + sptr = (char *)pip; + sptr += hlen; + + /* + * Check that data length is not too long and previous message was + * properly terminated with CRLF. + */ + pflags = GetProtocolFlags(lnk); + if (dlen <= MAX_MESSAGE_SIZE && (pflags & WAIT_CRLF) == 0 && + ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER && + (ParseFtpPortCommand(la, sptr, dlen) != 0 || + ParseFtpEprtCommand(la, sptr, dlen) != 0)) { + /* + * Alias active mode client requesting data from server + * behind NAT. We need to alias server->client connection + * to external address client is connecting to. + */ + AddLink(la, GetOriginalAddress(lnk), la->true_addr, + GetAliasAddress(lnk), htons(FTP_CONTROL_PORT_NUMBER - 1), + htons(la->true_port), GET_ALIAS_PORT, IPPROTO_TCP); + } + /* Track the msgs which are CRLF term'd for PORT/PASV FW breach */ + if (dlen) { + sptr = (char *)pip; /* start over at beginning */ + tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may + * have grown. + */ + if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n') + pflags &= ~WAIT_CRLF; + else + pflags |= WAIT_CRLF; + SetProtocolFlags(lnk, pflags); + } +} + static int ParseFtpPortCommand(struct libalias *la, char *sptr, int dlen) { @@ -576,9 +657,10 @@ NewFtpMessage(struct libalias *la, struct ip *pip, if (la->true_port < IPPORT_RESERVED) return; -/* Establish link to address and port found in FTP control message. */ - ftp_lnk = FindUdpTcpOut(la, la->true_addr, GetDestAddress(lnk), - htons(la->true_port), 0, IPPROTO_TCP, 1); + /* Establish link to address and port found in FTP control message. */ + ftp_lnk = AddLink(la, la->true_addr, GetDestAddress(lnk), + GetAliasAddress(lnk), htons(la->true_port), 0, GET_ALIAS_PORT, + IPPROTO_TCP); if (ftp_lnk != NULL) { int slen, hlen, tlen, dlen; diff --git a/sys/netinet/libalias/alias_local.h b/sys/netinet/libalias/alias_local.h index e201394ce6e4..c291a372837b 100644 --- a/sys/netinet/libalias/alias_local.h +++ b/sys/netinet/libalias/alias_local.h @@ -67,6 +67,9 @@ #define LINK_TABLE_OUT_SIZE 4001 #define LINK_TABLE_IN_SIZE 4001 +#define GET_ALIAS_PORT -1 +#define GET_ALIAS_ID GET_ALIAS_PORT + struct proxy_entry; struct libalias { @@ -249,6 +252,10 @@ DifferentialChecksum(u_short * _cksum, void * _new, void * _old, int _n); /* Internal data access */ struct alias_link * +AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, + struct in_addr alias_addr, u_short src_port, u_short dst_port, + int alias_param, int link_type); +struct alias_link * FindIcmpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr, u_short _id_alias, int _create); struct alias_link * diff --git a/sys/netinet/libalias/libalias.3 b/sys/netinet/libalias/libalias.3 index e441402ba670..fb63a4ccee39 100644 --- a/sys/netinet/libalias/libalias.3 +++ b/sys/netinet/libalias/libalias.3 @@ -824,6 +824,17 @@ argument is the pointer to a header fragment used as a template, and is the pointer to the packet to be de-aliased. .Ed .Sh MISCELLANEOUS FUNCTIONS +.Ft struct alias_link * +.Fn AddLink "struct libalias *" "struct in_addr src_addr" "struct in_addr dst_addr" \ +"struct in_addr alias_addr" "u_short src_port" "u_short dst_port" \ +"int alias_param" "int link_type" +.Bd -ragged -offset indent +This function adds new state to instance hash table. +Zero can be specified instead of dst_address and/or dst port. +This makes link partially specified dynamic. +However due to hashing method such links can be resolved on inbound (ext -> int) only. +.Ed +.Pp .Ft void .Fn LibAliasSetTarget "struct libalias *" "struct in_addr addr" .Bd -ragged -offset indent From 1368987ae424617c7c314315a5e1b3c222773868 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 22 Jun 2011 21:04:13 +0000 Subject: [PATCH 04/57] Move {amd64,i386}/pci/pci_bus.c and {amd64,i386}/include/pci_cfgreg.h to the x86 tree. The $PIR code is still only enabled on i386 and not amd64. While here, make the qpi(4) driver on conditional on 'device pci'. --- sys/amd64/include/pci_cfgreg.h | 44 +--- sys/amd64/pci/pci_bus.c | 435 -------------------------------- sys/conf/files.amd64 | 4 +- sys/conf/files.i386 | 4 +- sys/conf/files.pc98 | 2 +- sys/i386/include/param.h | 1 + sys/i386/include/pci_cfgreg.h | 53 +--- sys/x86/include/pci_cfgreg.h | 60 +++++ sys/{i386 => x86}/pci/pci_bus.c | 47 +++- 9 files changed, 105 insertions(+), 545 deletions(-) delete mode 100644 sys/amd64/pci/pci_bus.c create mode 100644 sys/x86/include/pci_cfgreg.h rename sys/{i386 => x86}/pci/pci_bus.c (96%) diff --git a/sys/amd64/include/pci_cfgreg.h b/sys/amd64/include/pci_cfgreg.h index 0358e7919391..717d5cc39fba 100644 --- a/sys/amd64/include/pci_cfgreg.h +++ b/sys/amd64/include/pci_cfgreg.h @@ -1,44 +1,6 @@ /*- - * Copyright (c) 1997, Stefan Esser - * 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 unmodified, 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 ``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. - * - * $FreeBSD$ - * + * This file is in the public domain. */ +/* $FreeBSD$ */ -#define CONF1_ADDR_PORT 0x0cf8 -#define CONF1_DATA_PORT 0x0cfc - -#define CONF1_ENABLE 0x80000000ul -#define CONF1_ENABLE_CHK 0x80000000ul -#define CONF1_ENABLE_MSK 0x7f000000ul -#define CONF1_ENABLE_CHK1 0xff000001ul -#define CONF1_ENABLE_MSK1 0x80000001ul -#define CONF1_ENABLE_RES1 0x80000000ul - -u_long hostb_alloc_start(int type, u_long start, u_long end, u_long count); -int pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus); -int pci_cfgregopen(void); -u_int32_t pci_cfgregread(int bus, int slot, int func, int reg, int bytes); -void pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes); +#include diff --git a/sys/amd64/pci/pci_bus.c b/sys/amd64/pci/pci_bus.c deleted file mode 100644 index 6d58575b1654..000000000000 --- a/sys/amd64/pci/pci_bus.c +++ /dev/null @@ -1,435 +0,0 @@ -/*- - * Copyright (c) 1997, Stefan Esser - * 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 unmodified, 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 ``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. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_cpu.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "pcib_if.h" - -int -legacy_pcib_maxslots(device_t dev) -{ - return 31; -} - -/* read configuration space register */ - -uint32_t -legacy_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, - u_int reg, int bytes) -{ - return(pci_cfgregread(bus, slot, func, reg, bytes)); -} - -/* write configuration space register */ - -void -legacy_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func, - u_int reg, uint32_t data, int bytes) -{ - pci_cfgregwrite(bus, slot, func, reg, data, bytes); -} - -/* route interrupt */ - -static int -legacy_pcib_route_interrupt(device_t pcib, device_t dev, int pin) -{ - - /* No routing possible */ - return (PCI_INVALID_IRQ); -} - -/* Pass MSI requests up to the nexus. */ - -static int -legacy_pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, - int *irqs) -{ - device_t bus; - - bus = device_get_parent(pcib); - return (PCIB_ALLOC_MSI(device_get_parent(bus), dev, count, maxcount, - irqs)); -} - -static int -legacy_pcib_alloc_msix(device_t pcib, device_t dev, int *irq) -{ - device_t bus; - - bus = device_get_parent(pcib); - return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq)); -} - -static int -legacy_pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, - uint32_t *data) -{ - device_t bus; - - bus = device_get_parent(pcib); - return (PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data)); -} - -static const char * -legacy_pcib_is_host_bridge(int bus, int slot, int func, - uint32_t id, uint8_t class, uint8_t subclass, - uint8_t *busnum) -{ - const char *s = NULL; - - *busnum = 0; - if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST) - s = "Host to PCI bridge"; - return s; -} - -/* - * Scan the first pci bus for host-pci bridges and add pcib instances - * to the nexus for each bridge. - */ -static void -legacy_pcib_identify(driver_t *driver, device_t parent) -{ - int bus, slot, func; - uint8_t hdrtype; - int found = 0; - int pcifunchigh; - int found824xx = 0; - int found_orion = 0; - device_t child; - devclass_t pci_devclass; - - if (pci_cfgregopen() == 0) - return; - /* - * Check to see if we haven't already had a PCI bus added - * via some other means. If we have, bail since otherwise - * we're going to end up duplicating it. - */ - if ((pci_devclass = devclass_find("pci")) && - devclass_get_device(pci_devclass, 0)) - return; - - - bus = 0; - retry: - for (slot = 0; slot <= PCI_SLOTMAX; slot++) { - func = 0; - hdrtype = legacy_pcib_read_config(0, bus, slot, func, - PCIR_HDRTYPE, 1); - /* - * When enumerating bus devices, the standard says that - * one should check the header type and ignore the slots whose - * header types that the software doesn't know about. We use - * this to filter out devices. - */ - if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE) - continue; - if ((hdrtype & PCIM_MFDEV) && - (!found_orion || hdrtype != 0xff)) - pcifunchigh = PCI_FUNCMAX; - else - pcifunchigh = 0; - for (func = 0; func <= pcifunchigh; func++) { - /* - * Read the IDs and class from the device. - */ - uint32_t id; - uint8_t class, subclass, busnum; - const char *s; - device_t *devs; - int ndevs, i; - - id = legacy_pcib_read_config(0, bus, slot, func, - PCIR_DEVVENDOR, 4); - if (id == -1) - continue; - class = legacy_pcib_read_config(0, bus, slot, func, - PCIR_CLASS, 1); - subclass = legacy_pcib_read_config(0, bus, slot, func, - PCIR_SUBCLASS, 1); - - s = legacy_pcib_is_host_bridge(bus, slot, func, - id, class, subclass, - &busnum); - if (s == NULL) - continue; - - /* - * Check to see if the physical bus has already - * been seen. Eg: hybrid 32 and 64 bit host - * bridges to the same logical bus. - */ - if (device_get_children(parent, &devs, &ndevs) == 0) { - for (i = 0; s != NULL && i < ndevs; i++) { - if (strcmp(device_get_name(devs[i]), - "pcib") != 0) - continue; - if (legacy_get_pcibus(devs[i]) == busnum) - s = NULL; - } - free(devs, M_TEMP); - } - - if (s == NULL) - continue; - /* - * Add at priority 100 to make sure we - * go after any motherboard resources - */ - child = BUS_ADD_CHILD(parent, 100, - "pcib", busnum); - device_set_desc(child, s); - legacy_set_pcibus(child, busnum); - - found = 1; - if (id == 0x12258086) - found824xx = 1; - if (id == 0x84c48086) - found_orion = 1; - } - } - if (found824xx && bus == 0) { - bus++; - goto retry; - } - - /* - * Make sure we add at least one bridge since some old - * hardware doesn't actually have a host-pci bridge device. - * Note that pci_cfgregopen() thinks we have PCI devices.. - */ - if (!found) { - if (bootverbose) - printf( - "legacy_pcib_identify: no bridge found, adding pcib0 anyway\n"); - child = BUS_ADD_CHILD(parent, 100, "pcib", 0); - legacy_set_pcibus(child, 0); - } -} - -static int -legacy_pcib_probe(device_t dev) -{ - - if (pci_cfgregopen() == 0) - return ENXIO; - return -100; -} - -static int -legacy_pcib_attach(device_t dev) -{ - int bus; - - bus = pcib_get_bus(dev); - device_add_child(dev, "pci", bus); - return bus_generic_attach(dev); -} - -int -legacy_pcib_read_ivar(device_t dev, device_t child, int which, - uintptr_t *result) -{ - - switch (which) { - case PCIB_IVAR_DOMAIN: - *result = 0; - return 0; - case PCIB_IVAR_BUS: - *result = legacy_get_pcibus(dev); - return 0; - } - return ENOENT; -} - -int -legacy_pcib_write_ivar(device_t dev, device_t child, int which, - uintptr_t value) -{ - - switch (which) { - case PCIB_IVAR_DOMAIN: - return EINVAL; - case PCIB_IVAR_BUS: - legacy_set_pcibus(dev, value); - return 0; - } - return ENOENT; -} - -/* - * Helper routine for x86 Host-PCI bridge driver resource allocation. - * This is used to adjust the start address of wildcard allocation - * requests to avoid low addresses that are known to be problematic. - * - * If no memory preference is given, use upper 32MB slot most BIOSes - * use for their memory window. This is typically only used on older - * laptops that don't have PCI busses behind a PCI bridge, so assuming - * > 32MB is likely OK. - * - * However, this can cause problems for other chipsets, so we make - * this tunable by hw.pci.host_mem_start. - */ -SYSCTL_DECL(_hw_pci); - -static unsigned long host_mem_start = 0x80000000; -TUNABLE_ULONG("hw.pci.host_mem_start", &host_mem_start); -SYSCTL_ULONG(_hw_pci, OID_AUTO, host_mem_start, CTLFLAG_RDTUN, &host_mem_start, - 0, "Limit the host bridge memory to being above this address."); - -u_long -hostb_alloc_start(int type, u_long start, u_long end, u_long count) -{ - - if (start + count - 1 != end) { - if (type == SYS_RES_MEMORY && start < host_mem_start) - start = host_mem_start; - if (type == SYS_RES_IOPORT && start < 0x1000) - start = 0x1000; - } - return (start); -} - -struct resource * -legacy_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) -{ - - start = hostb_alloc_start(type, start, end, count); - return (bus_generic_alloc_resource(dev, child, type, rid, start, end, - count, flags)); -} - -static device_method_t legacy_pcib_methods[] = { - /* Device interface */ - DEVMETHOD(device_identify, legacy_pcib_identify), - DEVMETHOD(device_probe, legacy_pcib_probe), - DEVMETHOD(device_attach, legacy_pcib_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_read_ivar, legacy_pcib_read_ivar), - DEVMETHOD(bus_write_ivar, legacy_pcib_write_ivar), - DEVMETHOD(bus_alloc_resource, legacy_pcib_alloc_resource), - DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - - /* pcib interface */ - DEVMETHOD(pcib_maxslots, legacy_pcib_maxslots), - DEVMETHOD(pcib_read_config, legacy_pcib_read_config), - DEVMETHOD(pcib_write_config, legacy_pcib_write_config), - DEVMETHOD(pcib_route_interrupt, legacy_pcib_route_interrupt), - DEVMETHOD(pcib_alloc_msi, legacy_pcib_alloc_msi), - DEVMETHOD(pcib_release_msi, pcib_release_msi), - DEVMETHOD(pcib_alloc_msix, legacy_pcib_alloc_msix), - DEVMETHOD(pcib_release_msix, pcib_release_msix), - DEVMETHOD(pcib_map_msi, legacy_pcib_map_msi), - - { 0, 0 } -}; - -static devclass_t hostb_devclass; - -DEFINE_CLASS_0(pcib, legacy_pcib_driver, legacy_pcib_methods, 1); -DRIVER_MODULE(pcib, legacy, legacy_pcib_driver, hostb_devclass, 0, 0); - - -/* - * Install placeholder to claim the resources owned by the - * PCI bus interface. This could be used to extract the - * config space registers in the extreme case where the PnP - * ID is available and the PCI BIOS isn't, but for now we just - * eat the PnP ID and do nothing else. - * - * XXX we should silence this probe, as it will generally confuse - * people. - */ -static struct isa_pnp_id pcibus_pnp_ids[] = { - { 0x030ad041 /* PNP0A03 */, "PCI Bus" }, - { 0x080ad041 /* PNP0A08 */, "PCIe Bus" }, - { 0 } -}; - -static int -pcibus_pnp_probe(device_t dev) -{ - int result; - - if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, pcibus_pnp_ids)) <= 0) - device_quiet(dev); - return(result); -} - -static int -pcibus_pnp_attach(device_t dev) -{ - return(0); -} - -static device_method_t pcibus_pnp_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pcibus_pnp_probe), - DEVMETHOD(device_attach, pcibus_pnp_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - { 0, 0 } -}; - -static devclass_t pcibus_pnp_devclass; - -DEFINE_CLASS_0(pcibus_pnp, pcibus_pnp_driver, pcibus_pnp_methods, 1); -DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0); diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 79168455e39e..1388d0102228 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -128,7 +128,6 @@ amd64/amd64/trap.c standard amd64/amd64/uio_machdep.c standard amd64/amd64/uma_machdep.c standard amd64/amd64/vm_machdep.c standard -amd64/pci/pci_bus.c optional pci amd64/pci/pci_cfgreg.c optional pci crypto/aesni/aesencdec_amd64.S optional aesni crypto/aesni/aeskeys_amd64.S optional aesni @@ -315,7 +314,8 @@ x86/isa/isa.c standard x86/isa/isa_dma.c standard x86/isa/nmi.c standard x86/isa/orm.c optional isa -x86/pci/qpi.c standard +x86/pci/pci_bus.c optional pci +x86/pci/qpi.c optional pci x86/x86/busdma_machdep.c standard x86/x86/dump_machdep.c standard x86/x86/io_apic.c standard diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 4f0d0d0ffdff..41a17729df2d 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -352,7 +352,6 @@ i386/linux/linux_support.s optional compat_linux \ dependency "linux_assym.h" i386/linux/linux_sysent.c optional compat_linux i386/linux/linux_sysvec.c optional compat_linux -i386/pci/pci_bus.c optional pci i386/pci/pci_cfgreg.c optional pci i386/pci/pci_pir.c optional pci i386/svr4/svr4_locore.s optional compat_svr4 \ @@ -405,7 +404,8 @@ x86/isa/isa.c optional isa x86/isa/isa_dma.c optional isa x86/isa/nmi.c standard x86/isa/orm.c optional isa -x86/pci/qpi.c standard +x86/pci/pci_bus.c optional pci +x86/pci/qpi.c optional pci x86/x86/busdma_machdep.c standard x86/x86/dump_machdep.c standard x86/x86/io_apic.c optional apic diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 5db5421f3c53..e034601b930e 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -199,7 +199,6 @@ i386/linux/linux_support.s optional compat_linux \ dependency "linux_assym.h" i386/linux/linux_sysent.c optional compat_linux i386/linux/linux_sysvec.c optional compat_linux -i386/pci/pci_bus.c optional pci i386/pci/pci_cfgreg.c optional pci i386/pci/pci_pir.c optional pci i386/svr4/svr4_locore.s optional compat_svr4 \ @@ -249,6 +248,7 @@ pc98/pc98/pc98_machdep.c standard x86/isa/atpic.c optional atpic x86/isa/clock.c standard x86/isa/isa.c optional isa +x86/pci/pci_bus.c optional pci x86/x86/busdma_machdep.c standard x86/x86/dump_machdep.c standard x86/x86/io_apic.c optional apic diff --git a/sys/i386/include/param.h b/sys/i386/include/param.h index 11ac12efac70..d95fcf3fd087 100644 --- a/sys/i386/include/param.h +++ b/sys/i386/include/param.h @@ -56,6 +56,7 @@ #define __HAVE_ACPI +#define __HAVE_PIR #define __PCI_REROUTE_INTERRUPT #ifndef MACHINE diff --git a/sys/i386/include/pci_cfgreg.h b/sys/i386/include/pci_cfgreg.h index 6995971c69c7..717d5cc39fba 100644 --- a/sys/i386/include/pci_cfgreg.h +++ b/sys/i386/include/pci_cfgreg.h @@ -1,53 +1,6 @@ /*- - * Copyright (c) 1997, Stefan Esser - * 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 unmodified, 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 ``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. - * - * $FreeBSD$ - * + * This file is in the public domain. */ +/* $FreeBSD$ */ -#define CONF1_ADDR_PORT 0x0cf8 -#define CONF1_DATA_PORT 0x0cfc - -#define CONF1_ENABLE 0x80000000ul -#define CONF1_ENABLE_CHK 0x80000000ul -#define CONF1_ENABLE_MSK 0x7f000000ul -#define CONF1_ENABLE_CHK1 0xff000001ul -#define CONF1_ENABLE_MSK1 0x80000001ul -#define CONF1_ENABLE_RES1 0x80000000ul - -#define CONF2_ENABLE_PORT 0x0cf8 -#define CONF2_FORWARD_PORT 0x0cfa - -#define CONF2_ENABLE_CHK 0x0e -#define CONF2_ENABLE_RES 0x0e - -u_long hostb_alloc_start(int type, u_long start, u_long end, u_long count); -int pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus); -int pci_cfgregopen(void); -u_int32_t pci_cfgregread(int bus, int slot, int func, int reg, int bytes); -void pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes); -void pci_pir_open(void); -int pci_pir_probe(int bus, int require_parse); -int pci_pir_route_interrupt(int bus, int device, int func, int pin); +#include diff --git a/sys/x86/include/pci_cfgreg.h b/sys/x86/include/pci_cfgreg.h new file mode 100644 index 000000000000..ea5e3198265f --- /dev/null +++ b/sys/x86/include/pci_cfgreg.h @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1997, Stefan Esser + * 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 unmodified, 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 ``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. + * + * $FreeBSD$ + * + */ + +#ifndef __X86_PCI_CFGREG_H__ +#define __X86_PCI_CFGREG_H__ + +#define CONF1_ADDR_PORT 0x0cf8 +#define CONF1_DATA_PORT 0x0cfc + +#define CONF1_ENABLE 0x80000000ul +#define CONF1_ENABLE_CHK 0x80000000ul +#define CONF1_ENABLE_MSK 0x7f000000ul +#define CONF1_ENABLE_CHK1 0xff000001ul +#define CONF1_ENABLE_MSK1 0x80000001ul +#define CONF1_ENABLE_RES1 0x80000000ul + +#define CONF2_ENABLE_PORT 0x0cf8 +#define CONF2_FORWARD_PORT 0x0cfa + +#define CONF2_ENABLE_CHK 0x0e +#define CONF2_ENABLE_RES 0x0e + +u_long hostb_alloc_start(int type, u_long start, u_long end, u_long count); +int pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus); +int pci_cfgregopen(void); +u_int32_t pci_cfgregread(int bus, int slot, int func, int reg, int bytes); +void pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes); +#ifdef __HAVE_PIR +void pci_pir_open(void); +int pci_pir_probe(int bus, int require_parse); +int pci_pir_route_interrupt(int bus, int device, int func, int pin); +#endif + +#endif /* !__X86_PCI_CFGREG_H__ */ diff --git a/sys/i386/pci/pci_bus.c b/sys/x86/pci/pci_bus.c similarity index 96% rename from sys/i386/pci/pci_bus.c rename to sys/x86/pci/pci_bus.c index c247180f9577..0efac6e366a6 100644 --- a/sys/i386/pci/pci_bus.c +++ b/sys/x86/pci/pci_bus.c @@ -51,9 +51,6 @@ __FBSDID("$FreeBSD$"); #include "pcib_if.h" -static int pcibios_pcib_route_interrupt(device_t pcib, device_t dev, - int pin); - int legacy_pcib_maxslots(device_t dev) { @@ -78,6 +75,21 @@ legacy_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func, pci_cfgregwrite(bus, slot, func, reg, data, bytes); } +/* route interrupt */ + +static int +legacy_pcib_route_interrupt(device_t pcib, device_t dev, int pin) +{ + +#ifdef __HAVE_PIR + return (pci_pir_route_interrupt(pci_get_bus(dev), pci_get_slot(dev), + pci_get_function(dev), pin)); +#else + /* No routing possible */ + return (PCI_INVALID_IRQ); +#endif +} + /* Pass MSI requests up to the nexus. */ static int @@ -115,6 +127,7 @@ legacy_pcib_is_host_bridge(int bus, int slot, int func, uint32_t id, uint8_t class, uint8_t subclass, uint8_t *busnum) { +#ifdef __i386__ const char *s = NULL; static uint8_t pxb[4]; /* hack for 450nx */ @@ -332,6 +345,14 @@ legacy_pcib_is_host_bridge(int bus, int slot, int func, } return s; +#else + const char *s = NULL; + + *busnum = 0; + if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST) + s = "Host to PCI bridge"; + return s; +#endif } /* @@ -471,19 +492,23 @@ legacy_pcib_probe(device_t dev) static int legacy_pcib_attach(device_t dev) { +#ifdef __HAVE_PIR device_t pir; +#endif int bus; + bus = pcib_get_bus(dev); +#ifdef __HAVE_PIR /* * Look for a PCI BIOS interrupt routing table as that will be * our method of routing interrupts if we have one. */ - bus = pcib_get_bus(dev); if (pci_pir_probe(bus, 0)) { pir = BUS_ADD_CHILD(device_get_parent(dev), 0, "pir", 0); if (pir != NULL) device_probe_and_attach(pir); } +#endif device_add_child(dev, "pci", bus); return bus_generic_attach(dev); } @@ -587,7 +612,7 @@ static device_method_t legacy_pcib_methods[] = { DEVMETHOD(pcib_maxslots, legacy_pcib_maxslots), DEVMETHOD(pcib_read_config, legacy_pcib_read_config), DEVMETHOD(pcib_write_config, legacy_pcib_write_config), - DEVMETHOD(pcib_route_interrupt, pcibios_pcib_route_interrupt), + DEVMETHOD(pcib_route_interrupt, legacy_pcib_route_interrupt), DEVMETHOD(pcib_alloc_msi, legacy_pcib_alloc_msi), DEVMETHOD(pcib_release_msi, pcib_release_msi), DEVMETHOD(pcib_alloc_msix, legacy_pcib_alloc_msix), @@ -651,7 +676,7 @@ static devclass_t pcibus_pnp_devclass; DEFINE_CLASS_0(pcibus_pnp, pcibus_pnp_driver, pcibus_pnp_methods, 1); DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0); - +#ifdef __HAVE_PIR /* * Provide a PCI-PCI bridge driver for PCI busses behind PCI-PCI bridges * that appear in the PCIBIOS Interrupt Routing Table to use the routing @@ -664,7 +689,7 @@ static device_method_t pcibios_pcib_pci_methods[] = { DEVMETHOD(device_probe, pcibios_pcib_probe), /* pcib interface */ - DEVMETHOD(pcib_route_interrupt, pcibios_pcib_route_interrupt), + DEVMETHOD(pcib_route_interrupt, legacy_pcib_route_interrupt), {0, 0} }; @@ -691,10 +716,4 @@ pcibios_pcib_probe(device_t dev) device_set_desc(dev, "PCIBIOS PCI-PCI bridge"); return (-2000); } - -static int -pcibios_pcib_route_interrupt(device_t pcib, device_t dev, int pin) -{ - return (pci_pir_route_interrupt(pci_get_bus(dev), pci_get_slot(dev), - pci_get_function(dev), pin)); -} +#endif From 7bb55def7731dd64585a6677bacca207c2a8c701 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 22 Jun 2011 21:10:12 +0000 Subject: [PATCH 05/57] Plug an mbuf leak in the new NFS client that occurred when a server replied NFS3ERR_JUKEBOX/NFS4ERR_DELAY to an rpc. This affected both NFSv3 and NFSv4. Found during testing at the recent NFSv4 interoperability Bakeathon. MFC after: 2 weeks --- sys/fs/nfs/nfs_commonkrpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index c34ea87a0e36..f658ac8d3cb5 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -733,6 +733,8 @@ tryagain: while (NFSD_MONOSEC < waituntil) (void) nfs_catnap(PZERO, 0, "nfstry"); trylater_delay *= 2; + m_freem(nd->nd_mrep); + nd->nd_mrep = NULL; goto tryagain; } From 14f900e2cd3f569d9b731990485f8e292d0a7035 Mon Sep 17 00:00:00 2001 From: Will Andrews Date: Wed, 22 Jun 2011 21:43:10 +0000 Subject: [PATCH 06/57] Plumb support for the device advanced information CCB in the ATA XPT. This was previously done only for SCSI XPT in r223081, on which the change in r223089 depended in order to respond to serial number requests. As a result of r223089, da(4) and ada(4) devices register a d_getattr for geom to use to obtain the information. Reported by: ache Reviewed by: ken --- sys/cam/ata/ata_xpt.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index d02b36f11485..216805d0c6bb 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -1600,6 +1600,34 @@ ata_device_transport(struct cam_path *path) xpt_action((union ccb *)&cts); } +static void +ata_dev_advinfo(union ccb *start_ccb) +{ + struct cam_ed *device; + struct ccb_dev_advinfo *cdai; + off_t amt; + + start_ccb->ccb_h.status = CAM_REQ_INVALID; + device = start_ccb->ccb_h.path->device; + cdai = &start_ccb->cdai; + switch(cdai->buftype) { + case CDAI_TYPE_SERIAL_NUM: + if (cdai->flags & CDAI_FLAG_STORE) + break; + start_ccb->ccb_h.status = CAM_REQ_CMP; + cdai->provsiz = device->serial_num_len; + if (device->serial_num_len == 0) + break; + amt = device->serial_num_len; + if (cdai->provsiz > cdai->bufsiz) + amt = cdai->bufsiz; + memcpy(cdai->buf, device->serial_num, amt); + break; + default: + break; + } +} + static void ata_action(union ccb *start_ccb) { @@ -1652,6 +1680,11 @@ ata_action(union ccb *start_ccb) } /* FALLTHROUGH */ } + case XPT_DEV_ADVINFO: + { + ata_dev_advinfo(start_ccb); + break; + } default: xpt_action_default(start_ccb); break; From a1aea88a5cae1d315efd2e10a1b7c0dcf20d541e Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Wed, 22 Jun 2011 21:53:45 +0000 Subject: [PATCH 07/57] Clarify tftpd's -d flag in the new TFTP implementation. Bump date. --- libexec/tftpd/tftpd.8 | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8 index 3bac492ffda3..68168e3cc27a 100644 --- a/libexec/tftpd/tftpd.8 +++ b/libexec/tftpd/tftpd.8 @@ -32,7 +32,7 @@ .\" @(#)tftpd.8 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd September 14, 2000 +.Dd June 22, 2011 .Dt TFTPD 8 .Os .Sh NAME @@ -150,9 +150,27 @@ compatible format string for the creation of the suffix if .Fl W is specified. By default the string "%Y%m%d" is used. -.It Fl d +.It Fl d, d Ar [value] Enables debug output. -If specified twice, it will log DATA and ACK packets too. +If +.Ar value +is not specified, then the debug level is increased by one +for each instance of +.Fl d +which is specified. +.Pp +If +.Ar value +is specified, then the debug level is set to +.Ar value . +The debug level is a bitmask implemented in +.Pa src/libexec/tftpd/tftp-utils.h . +Valid values are 0 (DEBUG_NONE), 1 (DEBUG_PACKETS), 2, (DEBUG_SIMPLE), +4 (DEBUG_OPTIONS), and 8 (DEBUG_ACCESS). Multiple debug values can be combined +in the bitmask by logically OR'ing the values. For example, specifying +.Fl d +.Ar 15 +will enable all the debug values. .It Fl l Log all requests using .Xr syslog 3 From 7e321ae384b7c31827315a674814cd2a0c336b03 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Wed, 22 Jun 2011 22:05:37 +0000 Subject: [PATCH 08/57] Fix typo. Reported by: Nick Mann --- libexec/tftpd/tftpd.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8 index 68168e3cc27a..3befa73387dc 100644 --- a/libexec/tftpd/tftpd.8 +++ b/libexec/tftpd/tftpd.8 @@ -273,7 +273,7 @@ was introduced in .Fx 7.4 . .Sh NOTES Files larger than 33488896 octets (65535 blocks) cannot be transferred -without client and server supporting the the TFTP blocksize option (RFC2348), +without client and server supporting the TFTP blocksize option (RFC2348), or the non-standard TFTP rollover option. .Pp Many tftp clients will not transfer files over 16744448 octets (32767 blocks). From 95db0bf79861c79e372d0f92e684fcf947e3e167 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Wed, 22 Jun 2011 22:08:55 +0000 Subject: [PATCH 09/57] Use USB_VENDOR_OVISLINK define rather than the vendor ID. PR: usb/158142 Submitted by: Robert Millan MFC after: 1 week --- sys/dev/usb/wlan/if_urtw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c index 3de2273bcb6e..7805c2d55046 100644 --- a/sys/dev/usb/wlan/if_urtw.c +++ b/sys/dev/usb/wlan/if_urtw.c @@ -115,7 +115,7 @@ static const struct usb_device_id urtw_devs[] = { URTW_DEV_L(REALTEK, RTL8187), URTW_DEV_L(SITECOMEU, WL168V1), URTW_DEV_L(SURECOM, EP9001G2A), - { USB_VPI(0x1b75, 0x8187, URTW_REV_RTL8187L) }, + { USB_VPI(USB_VENDOR_OVISLINK, 0x8187, URTW_REV_RTL8187L) }, { USB_VPI(USB_VENDOR_DICKSMITH, 0x9401, URTW_REV_RTL8187L) }, { USB_VPI(USB_VENDOR_HP, 0xca02, URTW_REV_RTL8187L) }, { USB_VPI(USB_VENDOR_LOGITEC, 0x010c, URTW_REV_RTL8187L) }, From b68628c826cdd0ab32dc2dc5d23982e1a22431a6 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Wed, 22 Jun 2011 22:55:51 +0000 Subject: [PATCH 10/57] Bump date. Document the following commands which were added in the new TFTP implementation: blocksize, blocksize2, packetdrop, options, rollover --- usr.bin/tftp/tftp.1 | 50 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/usr.bin/tftp/tftp.1 b/usr.bin/tftp/tftp.1 index bf8720b87b6b..494054bf1bc0 100644 --- a/usr.bin/tftp/tftp.1 +++ b/usr.bin/tftp/tftp.1 @@ -28,7 +28,7 @@ .\" @(#)tftp.1 8.2 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd October 1, 2003 +.Dd June 22, 2011 .Dt TFTP 1 .Os .Sh NAME @@ -70,6 +70,21 @@ Shorthand for "mode ascii" .It Cm binary Shorthand for "mode binary" .Pp +.It Cm blocksize Ar [size] +Sets the TFTP blksize option in TFTP Read Request or Write Request packets +to +.Ar [size] +as specified in RFC 2348. Valid values are between 8 and 65464. +If no blocksize is specified, then by default a blocksize of 512 bytes +will be used. +.Pp +.It Cm blocksize2 Ar [size] +Sets the TFTP blksize2 option in TFTP Read Request or Write Request packets +to +.Ar [size] . +Values are restricted to powers of 2 between 8 and 32768. This is a +non-standard TFTP option. +.Pp .It Cm connect Ar host Op Ar port Set the .Ar host @@ -93,6 +108,14 @@ or .Cm put commands. .Pp +.It Cm debug Ar level +Enable or disable debugging levels during verbose output. The value of +.Ar level +can be one of +.Cm packet, simple, options, +or +.Cm access. +.Pp .It Cm get Oo Ar host : Oc Ns Ar file Op Ar localname .It Cm get Xo .Oo Ar host1 : Oc Ns Ar file1 @@ -130,6 +153,11 @@ or The default is .Em ascii . .Pp +.It Cm packetdrop [arg] +Randomly drop +.Ar arg +out of 100 packets during a transfer. This is a debugging feature. +.Pp .It Cm put Ar file Op Oo Ar host : Oc Ns Ar remotename .It Cm put Ar file1 file2 ... fileN Op Oo Ar host : Oc Ns Ar remote-directory Put a file or set of files to the remote host. @@ -149,6 +177,17 @@ see the example under the .Cm get command. .Pp +.It Cm options Ar [arg] +Enable or disable support for TFTP options. The valid values of +.Ar arg +are +.Cm on +(enable RFC 2347 options), +.Cm off +(disable RFC 2347 options), and +.Cm extra +(toggle support for non-RFC defined options). +.Pp .It Cm quit Exit .Nm . @@ -157,6 +196,15 @@ An end of file also exits. .It Cm rexmt Ar retransmission-timeout Set the per-packet retransmission timeout, in seconds. .Pp +.It Cm rollover [arg] +Specify the rollover option in TFTP Read Request or Write +Request packets. After 65535 packets have been transmitted, set the block +counter to +.Ar arg . +Valid values of +.Ar arg +are 0 and 1. This is a non-standard TFTP option. +.Pp .It Cm status Show current status. .Pp From 4c42b949e9c43339508d627b12ba3e181aa66a87 Mon Sep 17 00:00:00 2001 From: Will Andrews Date: Wed, 22 Jun 2011 22:55:51 +0000 Subject: [PATCH 11/57] Return CAM_REQ_INVALID if the SCSI XPT receives an unsupported operation via the XPT_DEV_ADVINFO CCB. Reviewed by: ken --- sys/cam/scsi/scsi_xpt.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c index 1b507cae125f..c1f713b57c8b 100644 --- a/sys/cam/scsi/scsi_xpt.c +++ b/sys/cam/scsi/scsi_xpt.c @@ -2440,12 +2440,13 @@ scsi_dev_advinfo(union ccb *start_ccb) struct ccb_dev_advinfo *cdai; off_t amt; + start_ccb->ccb_h.status = CAM_REQ_INVALID; device = start_ccb->ccb_h.path->device; cdai = &start_ccb->cdai; switch(cdai->buftype) { case CDAI_TYPE_SCSI_DEVID: if (cdai->flags & CDAI_FLAG_STORE) - break; + return; cdai->provsiz = device->device_id_len; if (device->device_id_len == 0) break; @@ -2456,7 +2457,7 @@ scsi_dev_advinfo(union ccb *start_ccb) break; case CDAI_TYPE_SERIAL_NUM: if (cdai->flags & CDAI_FLAG_STORE) - break; + return; cdai->provsiz = device->serial_num_len; if (device->serial_num_len == 0) break; @@ -2490,7 +2491,7 @@ scsi_dev_advinfo(union ccb *start_ccb) } break; default: - break; + return; } start_ccb->ccb_h.status = CAM_REQ_CMP; From 624a5cc87e5ce96e97787b0ffefcd838b0b4fb86 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 22 Jun 2011 22:56:42 +0000 Subject: [PATCH 12/57] Fix build on ia64 after r223426. --- sys/dev/acpica/acpi_cpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index 583b548bb992..b0a7210a981a 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -856,8 +856,10 @@ acpi_cpu_cx_list(struct acpi_cpu_softc *sc) sbuf_printf(&sb, "C%d/%d ", i + 1, sc->cpu_cx_states[i].trans_lat); if (sc->cpu_cx_states[i].type < ACPI_STATE_C3) sc->cpu_non_c3 = i; +#ifndef __ia64__ else cpu_can_deep_sleep = 1; +#endif } sbuf_trim(&sb); sbuf_finish(&sb); From 957af43f83f2387e562262546e5642a0bb0f0ea6 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Wed, 22 Jun 2011 23:25:24 +0000 Subject: [PATCH 13/57] Update references to RFC's that the newer TFTP implementation supports. --- libexec/tftpd/tftpd.8 | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8 index 3befa73387dc..c8474d2582e5 100644 --- a/libexec/tftpd/tftpd.8 +++ b/libexec/tftpd/tftpd.8 @@ -235,12 +235,34 @@ option. .Xr services 5 , .Xr syslog.conf 5 , .Xr inetd 8 +.Pp +The following RFC's are supported: .Rs -.%A K. R. Sollins +RFC 1350 .%T The TFTP Protocol (Revision 2) -.%D July 1992 -.%O RFC 1350, STD 33 .Re +.Rs +RFC 2347 +.%T TFTP Option Extension +.Re +.Rs +RFC 2348 +.%T TFTP Blocksize Option +.Re +.Rs +RFC 2349 +.%T TFTP Timeout Interval and Transfer Size Options +.Re +.Pp +The non-standard +.Cm rollover +and +.Cm blksize2 +TFTP options are mentioned here: +.Rs +.%T Extending TFTP +.%U http://www.compuphase.com/tftp.htm +.Re .Sh HISTORY The .Nm From fcaab598e020fa3c78fe30615e2442fe3d0f6525 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Wed, 22 Jun 2011 23:26:04 +0000 Subject: [PATCH 14/57] Update references to RFC's that the newer TFTP implementation supports. --- usr.bin/tftp/tftp.1 | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/usr.bin/tftp/tftp.1 b/usr.bin/tftp/tftp.1 index 494054bf1bc0..8c583525b20a 100644 --- a/usr.bin/tftp/tftp.1 +++ b/usr.bin/tftp/tftp.1 @@ -217,6 +217,40 @@ Toggle packet tracing. .It Cm verbose Toggle verbose mode. .El +.Sh SEE ALSO +.Xr tftp 1 +.Pp +The following RFC's are supported: +.Rs +RFC 1350 +.%T The TFTP Protocol (Revision 2) +.Re +.Rs +RFC 2347 +.%T TFTP Option Extension +.Re +.Rs +RFC 2348 +.%T TFTP Blocksize Option +.Re +.Rs +RFC 2349 +.%T TFTP Timeout Interval and Transfer Size Options +.Re +.Rs +RFC 3617 +.%T Uniform Resource Identifier (URI) Scheme and Applicability Statement for the Trivial File Transfer Protocol (TFTP) +.Re +.Pp +The non-standard +.Cm rollover +and +.Cm blksize2 +TFTP options are mentioned here: +.Rs +.%T Extending TFTP +.%U http://www.compuphase.com/tftp.htm +.Re .Sh HISTORY The .Nm From 97a9e26dd89dec79e7c84b65800ebad980ba4c65 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Thu, 23 Jun 2011 02:35:55 +0000 Subject: [PATCH 15/57] Remove links to mirrorlist.FreeBSD.org. Submitted by: ryusuke Reported by: gavin, brucec --- release/doc/en_US.ISO8859-1/readme/article.sgml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/release/doc/en_US.ISO8859-1/readme/article.sgml b/release/doc/en_US.ISO8859-1/readme/article.sgml index 33ae82c567e9..f8ba3aab8e1c 100644 --- a/release/doc/en_US.ISO8859-1/readme/article.sgml +++ b/release/doc/en_US.ISO8859-1/readme/article.sgml @@ -184,8 +184,7 @@ Lists of locations that mirror &os; can be found in the FTP - Sites section of the Handbook, or on the Web pages. + Sites section of the Handbook. Finding a close (in networking terms) mirror from which to download the distribution is highly recommended. From 7d4c35c817a6f91bc079a7df65c0069c078888d3 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Thu, 23 Jun 2011 02:38:06 +0000 Subject: [PATCH 16/57] Bump &release.manpath.*;. --- release/doc/share/sgml/release.ent | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/doc/share/sgml/release.ent b/release/doc/share/sgml/release.ent index 0a4c1ce1e881..60b71307c364 100644 --- a/release/doc/share/sgml/release.ent +++ b/release/doc/share/sgml/release.ent @@ -36,8 +36,8 @@ - - + + From 37931a35441cec30c949e1bb878f04a1b4de7302 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 23 Jun 2011 02:38:36 +0000 Subject: [PATCH 17/57] Break out most of the HAL related tweaks into a per-HAL instance, rather than global variables. This specifically allows for debugging to be enabled per-NIC, rather than globally. Since the ath driver doesn't know about AH_DEBUG, and to keep the ABI consistent regardless of whether AH_DEBUG is enabled or not, enable the debug parameter always but only conditionally compile in the debug methods if needed. The ALQ support is currently still global pending some brainstorming. Submitted by: ssgriffonuser@gmail.com Reviewed by: adrian, bschmidt --- sys/dev/ath/ah_osdep.c | 31 ++--------------- sys/dev/ath/ath_hal/ah.h | 12 +++++++ sys/dev/ath/ath_hal/ah_internal.h | 9 +---- sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c | 4 +-- sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c | 4 +-- sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c | 5 +-- sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c | 4 +-- sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c | 6 ++-- sys/dev/ath/ath_hal/ar5416/ar2133.c | 2 +- sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c | 4 +-- sys/dev/ath/ath_hal/ar5416/ar5416_misc.c | 2 +- sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c | 6 ++-- sys/dev/ath/if_ath.c | 1 + sys/dev/ath/if_ath_sysctl.c | 40 ++++++++++++++++++++++ sys/dev/ath/if_ath_sysctl.h | 2 +- 15 files changed, 77 insertions(+), 55 deletions(-) diff --git a/sys/dev/ath/ah_osdep.c b/sys/dev/ath/ah_osdep.c index b14bba037e5b..c0f9b8c8e26f 100644 --- a/sys/dev/ath/ah_osdep.c +++ b/sys/dev/ath/ah_osdep.c @@ -76,33 +76,6 @@ extern void DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...); /* NB: put this here instead of the driver to avoid circular references */ SYSCTL_NODE(_hw, OID_AUTO, ath, CTLFLAG_RD, 0, "Atheros driver parameters"); -SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0, "Atheros HAL parameters"); - -#ifdef AH_DEBUG -int ath_hal_debug = 0; -SYSCTL_INT(_hw_ath_hal, OID_AUTO, debug, CTLFLAG_RW, &ath_hal_debug, - 0, "Atheros HAL debugging printfs"); -TUNABLE_INT("hw.ath.hal.debug", &ath_hal_debug); -#endif /* AH_DEBUG */ - -int ath_hal_ar5416_biasadj = 0; -SYSCTL_INT(_hw_ath_hal, OID_AUTO, ar5416_biasadj, CTLFLAG_RW, - &ath_hal_ar5416_biasadj, 0, "Enable 2ghz AR5416 direction sensitivity" - " bias adjust"); - -/* NB: these are deprecated; they exist for now for compatibility */ -int ath_hal_dma_beacon_response_time = 2; /* in TU's */ -SYSCTL_INT(_hw_ath_hal, OID_AUTO, dma_brt, CTLFLAG_RW, - &ath_hal_dma_beacon_response_time, 0, - "Atheros HAL DMA beacon response time"); -int ath_hal_sw_beacon_response_time = 10; /* in TU's */ -SYSCTL_INT(_hw_ath_hal, OID_AUTO, sw_brt, CTLFLAG_RW, - &ath_hal_sw_beacon_response_time, 0, - "Atheros HAL software beacon response time"); -int ath_hal_additional_swba_backoff = 0; /* in TU's */ -SYSCTL_INT(_hw_ath_hal, OID_AUTO, swba_backoff, CTLFLAG_RW, - &ath_hal_additional_swba_backoff, 0, - "Atheros HAL additional SWBA backoff time"); MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data"); @@ -146,7 +119,7 @@ ath_hal_ether_sprintf(const u_int8_t *mac) void DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...) { - if ((mask == HAL_DEBUG_UNMASKABLE) || (ath_hal_debug & mask)) { + if ((mask == HAL_DEBUG_UNMASKABLE) || (ah->ah_config.ah_debug & mask)) { __va_list ap; va_start(ap, fmt); ath_hal_vprintf(ah, fmt, ap); @@ -174,6 +147,8 @@ DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...) #include #include +SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0, "Atheros HAL parameters"); + static struct alq *ath_hal_alq; static int ath_hal_alq_emitdev; /* need to emit DEVICE record */ static u_int ath_hal_alq_lost; /* count of lost records */ diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index 7a01be354436..f81e6aab2736 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -756,6 +756,17 @@ struct dfs_event { }; typedef struct dfs_event HAL_DFS_EVENT; +typedef struct +{ + int ah_debug; /* only used if AH_DEBUG is defined */ + int ah_ar5416_biasadj; /* enable AR2133 radio specific bias fiddling */ + + /* NB: these are deprecated; they exist for now for compatibility */ + int ah_dma_beacon_response_time;/* in TU's */ + int ah_sw_beacon_response_time; /* in TU's */ + int ah_additional_swba_backoff; /* in TU's */ +}HAL_OPS_CONFIG; + /* * Hardware Access Layer (HAL) API. * @@ -784,6 +795,7 @@ struct ath_hal { uint16_t *ah_eepromdata; /* eeprom buffer, if needed */ + HAL_OPS_CONFIG ah_config; const HAL_RATE_TABLE *__ahdecl(*ah_getRateTable)(struct ath_hal *, u_int mode); void __ahdecl(*ah_detach)(struct ath_hal*); diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index d66c9d87144a..91edc34e2978 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -475,12 +475,6 @@ isBigEndian(void) #define OS_A_REG_RMW_FIELD(_a, _r, _f, _v) \ do { OS_REG_WRITE(_a, _r, (OS_REG_READ(_a, _r) &~ (_f)) | (((_v) << _f##_S) & (_f))) ; OS_DELAY(100); } while (0) -/* system-configurable parameters */ -extern int ath_hal_dma_beacon_response_time; /* in TU's */ -extern int ath_hal_sw_beacon_response_time; /* in TU's */ -extern int ath_hal_additional_swba_backoff; /* in TU's */ -extern int ath_hal_ar5416_biasadj; /* 1 or 0 */ - /* wait for the register contents to have the specified value */ extern HAL_BOOL ath_hal_wait(struct ath_hal *, u_int reg, uint32_t mask, uint32_t val); @@ -504,11 +498,10 @@ extern void ath_hal_free(void *); /* common debugging interfaces */ #ifdef AH_DEBUG #include "ah_debug.h" -extern int ath_hal_debug; #define HALDEBUG(_ah, __m, ...) \ do { \ if ((__m) == HAL_DEBUG_UNMASKABLE || \ - (ath_hal_debug & (__m))) { \ + ((_ah != AH_NULL) && (((struct ath_hal*)_ah)->ah_config.ah_debug & (__m)))) { \ DO_HALDEBUG((_ah), (__m), __VA_ARGS__); \ } \ } while(0); diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c b/sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c index dbd059e0e8f3..a613c9ca7d16 100644 --- a/sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c +++ b/sys/dev/ath/ath_hal/ar5210/ar5210_beacon.c @@ -56,9 +56,9 @@ ar5210BeaconInit(struct ath_hal *ah, if (AH_PRIVATE(ah)->ah_opmode != HAL_M_STA) { bt.bt_nextdba = (next_beacon - - ath_hal_dma_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */ bt.bt_nextswba = (next_beacon - - ath_hal_sw_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */ /* * The SWBA interrupt is not used for beacons in ad hoc mode * as we don't yet support ATIMs. So since the beacon never diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c b/sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c index 669b8f65ecb8..31e9c5df8a93 100644 --- a/sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c +++ b/sys/dev/ath/ath_hal/ar5211/ar5211_beacon.c @@ -71,9 +71,9 @@ ar5211BeaconInit(struct ath_hal *ah, case HAL_M_IBSS: case HAL_M_HOSTAP: bt.bt_nextdba = (next_beacon - - ath_hal_dma_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */ bt.bt_nextswba = (next_beacon - - ath_hal_sw_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */ break; } /* diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c b/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c index 3af314f6ca59..e1e7f73bf26d 100644 --- a/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c +++ b/sys/dev/ath/ath_hal/ar5211/ar5211_xmit.c @@ -345,8 +345,9 @@ ar5211ResetTxQueue(struct ath_hal *ah, u_int q) | AR_Q_MISC_CBR_INCR_DIS0 | AR_Q_MISC_RDYTIME_EXP_POLICY); value = (ahp->ah_beaconInterval - - (ath_hal_sw_beacon_response_time - ath_hal_dma_beacon_response_time) - - ath_hal_additional_swba_backoff) * 1024; + - (ah->ah_config.ah_sw_beacon_response_time + - ah->ah_config.ah_dma_beacon_response_time) + - ah->ah_config.ah_additional_swba_backoff) * 1024; OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_EN); /* Configure DCU for CAB */ diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c b/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c index 538f8b8d610f..6c1937aff1cf 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c @@ -84,9 +84,9 @@ ar5212BeaconInit(struct ath_hal *ah, case HAL_M_HOSTAP: case HAL_M_IBSS: bt.bt_nextdba = (next_beacon - - ath_hal_dma_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */ bt.bt_nextswba = (next_beacon - - ath_hal_sw_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */ break; } /* diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c index 4fbce31acade..3c6ddc0035fe 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c @@ -416,9 +416,9 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q) * here solely for backwards compatibility. */ value = (ahp->ah_beaconInterval - - (ath_hal_sw_beacon_response_time - - ath_hal_dma_beacon_response_time) - - ath_hal_additional_swba_backoff) * 1024; + - (ah->ah_config.ah_sw_beacon_response_time - + ah->ah_config.ah_dma_beacon_response_time) + - ah->ah_config.ah_additional_swba_backoff) * 1024; OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_ENA); } dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, diff --git a/sys/dev/ath/ath_hal/ar5416/ar2133.c b/sys/dev/ath/ath_hal/ar5416/ar2133.c index f92ea00ac09b..f25c108267e2 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar2133.c +++ b/sys/dev/ath/ath_hal/ar5416/ar2133.c @@ -185,7 +185,7 @@ ar2133SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan) } /* Workaround for hw bug - AR5416 specific */ - if (AR_SREV_OWL(ah) && ath_hal_ar5416_biasadj) + if (AR_SREV_OWL(ah) && ah->ah_config.ah_ar5416_biasadj) ar2133ForceBias(ah, freq); reg32 = (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c b/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c index 358a0eed245d..ee6c1eb3645a 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c @@ -93,9 +93,9 @@ ar5416BeaconInit(struct ath_hal *ah, /* fall thru... */ case HAL_M_HOSTAP: bt.bt_nextdba = (next_beacon - - ath_hal_dma_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */ bt.bt_nextswba = (next_beacon - - ath_hal_sw_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */ bt.bt_flags |= AR_TIMER_MODE_TBTT | AR_TIMER_MODE_DBA | AR_TIMER_MODE_SWBA; diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c index 2332656e8f54..6266b5813532 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c @@ -288,7 +288,7 @@ ar5416SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration, nextStart_us += OS_REG_READ(ah, AR_TSF_L32); } if (flag & HAL_QUIET_ADD_SWBA_RESP_TIME) { - nextStart_us += ath_hal_sw_beacon_response_time; + nextStart_us += ah->ah_config.ah_sw_beacon_response_time; } OS_REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); OS_REG_WRITE(ah, AR_QUIET2, SM(duration, AR_QUIET2_QUIET_DUR)); diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c index 48956c51cb84..20791e8a5a50 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c @@ -1035,9 +1035,9 @@ ar5416ResetTxQueue(struct ath_hal *ah, u_int q) * here solely for backwards compatibility. */ value = (ahp->ah_beaconInterval - - (ath_hal_sw_beacon_response_time - - ath_hal_dma_beacon_response_time) - - ath_hal_additional_swba_backoff) * 1024; + - (ah->ah_config.ah_sw_beacon_response_time - + ah->ah_config.ah_dma_beacon_response_time) + - ah->ah_config.ah_additional_swba_backoff) * 1024; OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_ENA); } dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 6c7b0e7614b2..f3afc70b201e 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -738,6 +738,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) */ ath_sysctlattach(sc); ath_sysctl_stats_attach(sc); + ath_sysctl_hal_attach(sc); if (bootverbose) ieee80211_announce(ic); diff --git a/sys/dev/ath/if_ath_sysctl.c b/sys/dev/ath/if_ath_sysctl.c index 6c1a6b210425..e3c9966b8f55 100644 --- a/sys/dev/ath/if_ath_sysctl.c +++ b/sys/dev/ath/if_ath_sysctl.c @@ -719,3 +719,43 @@ ath_sysctl_stats_attach(struct ath_softc *sc) /* Attach the RX phy error array */ ath_sysctl_stats_attach_rxphyerr(sc, child); } + +/* + * This doesn't necessarily belong here (because it's HAL related, not + * driver related). + */ +void +ath_sysctl_hal_attach(struct ath_softc *sc) +{ + struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); + struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree); + + tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "hal", CTLFLAG_RD, + NULL, "Atheros HAL parameters"); + child = SYSCTL_CHILDREN(tree); + + sc->sc_ah->ah_config.ah_debug = 0; + SYSCTL_ADD_INT(ctx, child, OID_AUTO, "debug", CTLFLAG_RW, + &sc->sc_ah->ah_config.ah_debug, 0, "Atheros HAL debugging printfs"); + + sc->sc_ah->ah_config.ah_ar5416_biasadj = 0; + SYSCTL_ADD_INT(ctx, child, OID_AUTO, "ar5416_biasadj", CTLFLAG_RW, + &sc->sc_ah->ah_config.ah_ar5416_biasadj, 0, + "Enable 2ghz AR5416 direction sensitivity bias adjust"); + + sc->sc_ah->ah_config.ah_dma_beacon_response_time = 2; + SYSCTL_ADD_INT(ctx, child, OID_AUTO, "dma_brt", CTLFLAG_RW, + &sc->sc_ah->ah_config.ah_dma_beacon_response_time, 0, + "Atheros HAL DMA beacon response time"); + + sc->sc_ah->ah_config.ah_sw_beacon_response_time = 10; + SYSCTL_ADD_INT(ctx, child, OID_AUTO, "sw_brt", CTLFLAG_RW, + &sc->sc_ah->ah_config.ah_sw_beacon_response_time, 0, + "Atheros HAL software beacon response time"); + + sc->sc_ah->ah_config.ah_additional_swba_backoff = 0; + SYSCTL_ADD_INT(ctx, child, OID_AUTO, "swba_backoff", CTLFLAG_RW, + &sc->sc_ah->ah_config.ah_additional_swba_backoff, 0, + "Atheros HAL additional SWBA backoff time"); +} diff --git a/sys/dev/ath/if_ath_sysctl.h b/sys/dev/ath/if_ath_sysctl.h index f96a73e9aac5..1fef2be224a4 100644 --- a/sys/dev/ath/if_ath_sysctl.h +++ b/sys/dev/ath/if_ath_sysctl.h @@ -34,5 +34,5 @@ extern void ath_sysctlattach(struct ath_softc *); extern void ath_sysctl_stats_attach(struct ath_softc *sc); - +extern void ath_sysctl_hal_attach(struct ath_softc *sc); #endif From 67de2cd33040bc06e481ad4ebfc9afea626be3a4 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 23 Jun 2011 03:20:11 +0000 Subject: [PATCH 18/57] Add hypervisor call error codes. --- sys/powerpc/ps3/ps3-hvcall.h | 28 ++++++++++++++++++++++++++++ sys/powerpc/ps3/ps3-hvcall.master | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/sys/powerpc/ps3/ps3-hvcall.h b/sys/powerpc/ps3/ps3-hvcall.h index 912158ba38b1..0875a621015b 100644 --- a/sys/powerpc/ps3/ps3-hvcall.h +++ b/sys/powerpc/ps3/ps3-hvcall.h @@ -11,6 +11,34 @@ enum lpar_id { PS3_LPAR_ID_PME = 0x01, }; +/* Return codes from hypercalls */ +#define LV1_SUCCESS 0 +#define LV1_RESOURCE_SHORTAGE -2 +#define LV1_NO_PRIVILEGE -3 +#define LV1_DENIED_BY_POLICY -4 +#define LV1_ACCESS_VIOLATION -5 +#define LV1_NO_ENTRY -6 +#define LV1_DUPLICATE_ENTRY -7 +#define LV1_TYPE_MISMATCH -8 +#define LV1_BUSY -9 +#define LV1_EMPTY -10 +#define LV1_WRONG_STATE -11 +#define LV1_NO_MATCH -13 +#define LV1_ALREADY_CONNECTED -14 +#define LV1_UNSUPPORTED_PARAMETER_VALUE -15 +#define LV1_CONDITION_NOT_SATISFIED -16 +#define LV1_ILLEGAL_PARAMETER_VALUE -17 +#define LV1_BAD_OPTION -18 +#define LV1_IMPLEMENTATION_LIMITATION -19 +#define LV1_NOT_IMPLEMENTED -20 +#define LV1_INVALID_CLASS_ID -21 +#define LV1_CONSTRAINT_NOT_SATISFIED -22 +#define LV1_ALIGNMENT_ERROR -23 +#define LV1_HARDWARE_ERROR -24 +#define LV1_INVALID_DATA_FORMAT -25 +#define LV1_INVALID_OPERATION -26 +#define LV1_INTERNAL_ERROR -32768 + static inline uint64_t lv1_repository_string(const char *str) { diff --git a/sys/powerpc/ps3/ps3-hvcall.master b/sys/powerpc/ps3/ps3-hvcall.master index d53a32e0524d..a9abe9455a68 100644 --- a/sys/powerpc/ps3/ps3-hvcall.master +++ b/sys/powerpc/ps3/ps3-hvcall.master @@ -11,6 +11,34 @@ enum lpar_id { PS3_LPAR_ID_PME = 0x01, }; +/* Return codes from hypercalls */ +#define LV1_SUCCESS 0 +#define LV1_RESOURCE_SHORTAGE -2 +#define LV1_NO_PRIVILEGE -3 +#define LV1_DENIED_BY_POLICY -4 +#define LV1_ACCESS_VIOLATION -5 +#define LV1_NO_ENTRY -6 +#define LV1_DUPLICATE_ENTRY -7 +#define LV1_TYPE_MISMATCH -8 +#define LV1_BUSY -9 +#define LV1_EMPTY -10 +#define LV1_WRONG_STATE -11 +#define LV1_NO_MATCH -13 +#define LV1_ALREADY_CONNECTED -14 +#define LV1_UNSUPPORTED_PARAMETER_VALUE -15 +#define LV1_CONDITION_NOT_SATISFIED -16 +#define LV1_ILLEGAL_PARAMETER_VALUE -17 +#define LV1_BAD_OPTION -18 +#define LV1_IMPLEMENTATION_LIMITATION -19 +#define LV1_NOT_IMPLEMENTED -20 +#define LV1_INVALID_CLASS_ID -21 +#define LV1_CONSTRAINT_NOT_SATISFIED -22 +#define LV1_ALIGNMENT_ERROR -23 +#define LV1_HARDWARE_ERROR -24 +#define LV1_INVALID_DATA_FORMAT -25 +#define LV1_INVALID_OPERATION -26 +#define LV1_INTERNAL_ERROR -32768 + static inline uint64_t lv1_repository_string(const char *str) { From 98934b1fd5d602a69625278d0730aa1d384bbdf2 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 23 Jun 2011 03:37:25 +0000 Subject: [PATCH 19/57] Rework the PS3 disk driver to support NCQ and do its DMA a little differently. --- sys/powerpc/ps3/ps3disk.c | 585 +++++++++++++------------------------- 1 file changed, 193 insertions(+), 392 deletions(-) diff --git a/sys/powerpc/ps3/ps3disk.c b/sys/powerpc/ps3/ps3disk.c index 5390f50e818b..3bab0f2d6e39 100644 --- a/sys/powerpc/ps3/ps3disk.c +++ b/sys/powerpc/ps3/ps3disk.c @@ -116,39 +116,25 @@ struct ps3disk_softc { struct disk **sc_disk; struct bio_queue_head sc_bioq; + struct bio_queue_head sc_deferredq; + struct proc *sc_task; - struct proc *sc_task; - - int sc_bounce_maxblocks; - bus_dma_tag_t sc_bounce_dmatag; - bus_dmamap_t sc_bounce_dmamap; - bus_addr_t sc_bounce_dmaphys; - char *sc_bounce; - uint64_t sc_bounce_lpar; - int sc_bounce_busy; - uint64_t sc_bounce_tag; - uint64_t sc_bounce_status; + bus_dma_tag_t sc_dmatag; int sc_running; - int sc_debug; }; static int ps3disk_open(struct disk *dp); static int ps3disk_close(struct disk *dp); static void ps3disk_strategy(struct bio *bp); -static void ps3disk_task(void *arg); -static int ps3disk_intr_filter(void *arg); +static void ps3disk_task(void *arg); static void ps3disk_intr(void *arg); -static void ps3disk_getphys(void *arg, bus_dma_segment_t *segs, int nsegs, int error); static int ps3disk_get_disk_geometry(struct ps3disk_softc *sc); static int ps3disk_enum_regions(struct ps3disk_softc *sc); -static int ps3disk_read(struct ps3disk_softc *sc, int regidx, - uint64_t start_sector, uint64_t sector_count, char *data); -static int ps3disk_write(struct ps3disk_softc *sc, int regidx, - uint64_t start_sector, uint64_t sector_count, char *data); -static int ps3disk_flush(struct ps3disk_softc *sc); +static void ps3disk_transfer(void *arg, bus_dma_segment_t *segs, int nsegs, + int error); static void ps3disk_sysctlattach(struct ps3disk_softc *sc); @@ -172,6 +158,7 @@ ps3disk_attach(device_t dev) struct ps3disk_softc *sc; struct disk *d; intmax_t mb; + uint64_t junk; char unit; int i, err; @@ -205,7 +192,6 @@ ps3disk_attach(device_t dev) } /* Setup interrupt handler */ - sc->sc_irqid = 0; sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irqid, RF_ACTIVE); @@ -217,52 +203,24 @@ ps3disk_attach(device_t dev) err = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY, - ps3disk_intr_filter, ps3disk_intr, sc, &sc->sc_irqctx); + NULL, ps3disk_intr, sc, &sc->sc_irqctx); if (err) { device_printf(dev, "Could not setup IRQ\n"); err = ENXIO; goto fail_release_intr; } - /* Setup DMA bounce buffer */ - - sc->sc_bounce_maxblocks = DFLTPHYS / sc->sc_blksize; - + /* Setup DMA */ err = bus_dma_tag_create(bus_get_dma_tag(dev), 4096, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, - sc->sc_bounce_maxblocks * sc->sc_blksize, 1, - sc->sc_bounce_maxblocks * sc->sc_blksize, - 0, NULL, NULL, &sc->sc_bounce_dmatag); + BUS_SPACE_UNRESTRICTED, 1, PAGE_SIZE, 0, + busdma_lock_mutex, &sc->sc_mtx, &sc->sc_dmatag); if (err) { - device_printf(dev, "Could not create DMA tag for bounce buffer\n"); + device_printf(dev, "Could not create DMA tag\n"); err = ENXIO; goto fail_teardown_intr; } - err = bus_dmamem_alloc(sc->sc_bounce_dmatag, (void **) &sc->sc_bounce, - BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, - &sc->sc_bounce_dmamap); - if (err) { - device_printf(dev, "Could not allocate DMA memory for bounce buffer\n"); - err = ENXIO; - goto fail_destroy_dmatag; - } - - err = bus_dmamap_load(sc->sc_bounce_dmatag, sc->sc_bounce_dmamap, - sc->sc_bounce, sc->sc_bounce_maxblocks * sc->sc_blksize, - ps3disk_getphys, &sc->sc_bounce_dmaphys, 0); - if (err) { - device_printf(dev, "Could not load DMA map for bounce buffer\n"); - err = ENXIO; - goto fail_free_dmamem; - } - - sc->sc_bounce_lpar = vtophys(sc->sc_bounce); - - if (bootverbose) - device_printf(dev, "bounce buffer lpar address 0x%016lx\n", - sc->sc_bounce_lpar); - /* Setup disks */ sc->sc_disk = malloc(sc->sc_nregs * sizeof(struct disk *), @@ -270,7 +228,7 @@ ps3disk_attach(device_t dev) if (!sc->sc_disk) { device_printf(dev, "Could not allocate disk(s)\n"); err = ENOMEM; - goto fail_unload_dmamem; + goto fail_teardown_intr; } for (i = 0; i < sc->sc_nregs; i++) { @@ -282,7 +240,7 @@ ps3disk_attach(device_t dev) d->d_strategy = ps3disk_strategy; d->d_name = "ps3disk"; d->d_drv1 = sc; - d->d_maxsize = DFLTPHYS; + d->d_maxsize = PAGE_SIZE; d->d_sectorsize = sc->sc_blksize; d->d_unit = i; d->d_mediasize = sc->sc_reg[i].r_size * sc->sc_blksize; @@ -297,53 +255,32 @@ ps3disk_attach(device_t dev) /* Test to see if we can read this region */ err = lv1_storage_read(ps3bus_get_device(dev), d->d_unit, - 0, 1, rp->r_flags, sc->sc_bounce_lpar, &sc->sc_bounce_tag); + 0, 0, rp->r_flags, 0, &junk); device_printf(dev, "region %d %ju%cB%s\n", i, mb, unit, - (err == 0) ? "" : " (hypervisor protected)"); + (err == LV1_DENIED_BY_POLICY) ? " (hypervisor protected)" + : ""); - if (err == 0) + if (err != LV1_DENIED_BY_POLICY) disk_create(d, DISK_VERSION); } err = 0; bioq_init(&sc->sc_bioq); + bioq_init(&sc->sc_deferredq); + kproc_create(&ps3disk_task, sc, &sc->sc_task, 0, 0, "ps3disk"); ps3disk_sysctlattach(sc); - sc->sc_running = 1; - - kproc_create(&ps3disk_task, sc, &sc->sc_task, 0, 0, "task: ps3disk"); - return (0); -fail_unload_dmamem: - - bus_dmamap_unload(sc->sc_bounce_dmatag, sc->sc_bounce_dmamap); - -fail_free_dmamem: - - bus_dmamem_free(sc->sc_bounce_dmatag, sc->sc_bounce, sc->sc_bounce_dmamap); - -fail_destroy_dmatag: - - bus_dma_tag_destroy(sc->sc_bounce_dmatag); - fail_teardown_intr: - bus_teardown_intr(dev, sc->sc_irq, sc->sc_irqctx); - fail_release_intr: - bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqid, sc->sc_irq); - fail_free_regions: - free(sc->sc_reg, M_PS3DISK); - fail_destroy_lock: - PS3DISK_LOCK_DESTROY(sc); - return (err); } @@ -353,28 +290,15 @@ ps3disk_detach(device_t dev) struct ps3disk_softc *sc = device_get_softc(dev); int i; - PS3DISK_LOCK(sc); - sc->sc_running = 0; - wakeup(sc); - PS3DISK_UNLOCK(sc); - - PS3DISK_LOCK(sc); - while (sc->sc_running != -1) - msleep(sc, &sc->sc_mtx, PRIBIO, "detach", 0); - PS3DISK_UNLOCK(sc); - for (i = 0; i < sc->sc_nregs; i++) disk_destroy(sc->sc_disk[i]); - bus_dmamap_unload(sc->sc_bounce_dmatag, sc->sc_bounce_dmamap); - bus_dmamem_free(sc->sc_bounce_dmatag, sc->sc_bounce, sc->sc_bounce_dmamap); - bus_dma_tag_destroy(sc->sc_bounce_dmatag); + bus_dma_tag_destroy(sc->sc_dmatag); bus_teardown_intr(dev, sc->sc_irq, sc->sc_irqctx); bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqid, sc->sc_irq); free(sc->sc_disk, M_PS3DISK); - free(sc->sc_reg, M_PS3DISK); PS3DISK_LOCK_DESTROY(sc); @@ -394,12 +318,45 @@ ps3disk_close(struct disk *dp) return (0); } +/* Process deferred blocks */ +static void +ps3disk_task(void *arg) +{ + struct ps3disk_softc *sc = (struct ps3disk_softc *) arg; + struct bio *bp; + + + while (1) { + kproc_suspend_check(sc->sc_task); + tsleep(&sc->sc_deferredq, PRIBIO, "ps3disk", 10); + + PS3DISK_LOCK(sc); + bp = bioq_takefirst(&sc->sc_deferredq); + PS3DISK_UNLOCK(sc); + + if (bp == NULL) + continue; + + if (bp->bio_driver1 != NULL) { + bus_dmamap_unload(sc->sc_dmatag, (bus_dmamap_t) + bp->bio_driver1); + bus_dmamap_destroy(sc->sc_dmatag, (bus_dmamap_t) + bp->bio_driver1); + } + + ps3disk_strategy(bp); + } + + kproc_exit(0); +} + static void ps3disk_strategy(struct bio *bp) { - struct ps3disk_softc *sc = (struct ps3disk_softc *) bp->bio_disk->d_drv1; + struct ps3disk_softc *sc = (struct ps3disk_softc *)bp->bio_disk->d_drv1; + int err; - if (!sc) { + if (sc == NULL) { bp->bio_flags |= BIO_ERROR; bp->bio_error = EINVAL; biodone(bp); @@ -407,114 +364,48 @@ ps3disk_strategy(struct bio *bp) } PS3DISK_LOCK(sc); - bioq_disksort(&sc->sc_bioq, bp); - if (!sc->sc_bounce_busy) - wakeup(sc); - PS3DISK_UNLOCK(sc); -} + bp->bio_resid = bp->bio_bcount; + bioq_insert_tail(&sc->sc_bioq, bp); -static void -ps3disk_task(void *arg) -{ - struct ps3disk_softc *sc = (struct ps3disk_softc *) arg; - struct bio *bp; - daddr_t block, end; - u_long nblocks; - char *data; - int err; + DPRINTF(sc, PS3DISK_DEBUG_TASK, "%s: bio_cmd 0x%02x\n", + __func__, bp->bio_cmd); - while (sc->sc_running) { - PS3DISK_LOCK(sc); - do { - bp = bioq_first(&sc->sc_bioq); - if (bp == NULL) - msleep(sc, &sc->sc_mtx, PRIBIO, "jobqueue", 0); - } while (bp == NULL && sc->sc_running); - if (bp) - bioq_remove(&sc->sc_bioq, bp); - PS3DISK_UNLOCK(sc); - - if (!sc->sc_running) - break; - - DPRINTF(sc, PS3DISK_DEBUG_TASK, "%s: bio_cmd 0x%02x\n", - __func__, bp->bio_cmd); - - if (bp->bio_cmd == BIO_FLUSH) { - err = ps3disk_flush(sc); - - if (err) { - bp->bio_error = EIO; - bp->bio_flags |= BIO_ERROR; - } else { - bp->bio_error = 0; - bp->bio_flags |= BIO_DONE; - } - } else if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) { - end = bp->bio_pblkno + (bp->bio_bcount / sc->sc_blksize); - - DPRINTF(sc, PS3DISK_DEBUG_TASK, "%s: bio_pblkno %ld bio_bcount %ld\n", - __func__, bp->bio_pblkno, bp->bio_bcount); - - for (block = bp->bio_pblkno; block < end;) { - data = bp->bio_data + - (block - bp->bio_pblkno) * sc->sc_blksize; - - nblocks = end - block; - if (nblocks > sc->sc_bounce_maxblocks) - nblocks = sc->sc_bounce_maxblocks; - - DPRINTF(sc, PS3DISK_DEBUG_TASK, "%s: nblocks %lu\n", - __func__, nblocks); - - if (bp->bio_cmd == BIO_READ) { - err = ps3disk_read(sc, bp->bio_disk->d_unit, - block, nblocks, data); - } else { - err = ps3disk_write(sc, bp->bio_disk->d_unit, - block, nblocks, data); - } - - if (err) - break; - - block += nblocks; - } - - bp->bio_resid = (end - block) * sc->sc_blksize; - if (bp->bio_resid) { - bp->bio_error = EIO; - bp->bio_flags |= BIO_ERROR; - } else { - bp->bio_error = 0; - bp->bio_flags |= BIO_DONE; - } - - DPRINTF(sc, PS3DISK_DEBUG_TASK, "%s: bio_resid %ld\n", - __func__, bp->bio_resid); + err = 0; + if (bp->bio_cmd == BIO_FLUSH) { + bp->bio_driver1 = 0; + err = lv1_storage_send_device_command( + ps3bus_get_device(sc->sc_dev), LV1_STORAGE_ATA_HDDOUT, + 0, 0, 0, 0, (uint64_t *)&bp->bio_driver2); + if (err == LV1_BUSY) + err = EAGAIN; + } else if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) { + if (bp->bio_bcount % sc->sc_blksize != 0) { + err = EINVAL; } else { - bp->bio_error = EINVAL; - bp->bio_flags |= BIO_ERROR; + bus_dmamap_create(sc->sc_dmatag, BUS_DMA_COHERENT, + (bus_dmamap_t *)(&bp->bio_driver1)); + err = bus_dmamap_load(sc->sc_dmatag, + (bus_dmamap_t)(bp->bio_driver1), bp->bio_data, + bp->bio_bcount, ps3disk_transfer, bp, 0); + if (err == EINPROGRESS) + err = 0; } + } else { + err = EINVAL; + } - if (bp->bio_flags & BIO_ERROR) - disk_err(bp, "hard error", -1, 1); - + if (err == EAGAIN) { + bioq_remove(&sc->sc_bioq, bp); + bioq_insert_tail(&sc->sc_deferredq, bp); + } else if (err != 0) { + bp->bio_error = err; + bp->bio_flags |= BIO_ERROR; + bioq_remove(&sc->sc_bioq, bp); + disk_err(bp, "hard error", -1, 1); biodone(bp); } - PS3DISK_LOCK(sc); - sc->sc_running = -1; - wakeup(sc); PS3DISK_UNLOCK(sc); - - kproc_exit(0); -} - -static int -ps3disk_intr_filter(void *arg) -{ - return (FILTER_SCHEDULE_THREAD); } static void @@ -523,50 +414,55 @@ ps3disk_intr(void *arg) struct ps3disk_softc *sc = (struct ps3disk_softc *) arg; device_t dev = sc->sc_dev; uint64_t devid = ps3bus_get_device(dev); + struct bio *bp; uint64_t tag, status; - int err; + if (lv1_storage_get_async_status(devid, &tag, &status) != 0) + return; + PS3DISK_LOCK(sc); - err = lv1_storage_get_async_status(devid, &tag, &status); + DPRINTF(sc, PS3DISK_DEBUG_INTR, "%s: tag 0x%016lx " + "status 0x%016lx\n", __func__, tag, status); - DPRINTF(sc, PS3DISK_DEBUG_INTR, "%s: err %d tag 0x%016lx status 0x%016lx\n", - __func__, err, tag, status); + /* Locate the matching request */ + TAILQ_FOREACH(bp, &sc->sc_bioq.queue, bio_queue) { + if ((uint64_t)bp->bio_driver2 != tag) + continue; - if (err) - goto out; + if (status != 0) { + device_printf(sc->sc_dev, "%s error (%#lx)\n", + (bp->bio_cmd == BIO_READ) ? "Read" : "Write", + status); + bp->bio_error = EIO; + bp->bio_flags |= BIO_ERROR; + } else { + bp->bio_error = 0; + bp->bio_resid = 0; + bp->bio_flags |= BIO_DONE; + } - if (!sc->sc_bounce_busy) { - device_printf(dev, "Got interrupt while no request pending\n"); - goto out; + if (bp->bio_driver1 != NULL) { + if (bp->bio_cmd == BIO_READ) + bus_dmamap_sync(sc->sc_dmatag, (bus_dmamap_t) + bp->bio_driver1, BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->sc_dmatag, (bus_dmamap_t) + bp->bio_driver1); + bus_dmamap_destroy(sc->sc_dmatag, (bus_dmamap_t) + bp->bio_driver1); + } + + bioq_remove(&sc->sc_bioq, bp); + biodone(bp); + break; } - if (tag != sc->sc_bounce_tag) - device_printf(dev, "Tag mismatch, got 0x%016lx expected 0x%016lx\n", - tag, sc->sc_bounce_tag); - - if (status) - device_printf(dev, "Request completed with status 0x%016lx\n", status); - - sc->sc_bounce_status = status; - sc->sc_bounce_busy = 0; - - wakeup(sc); - -out: + if (bioq_first(&sc->sc_deferredq) != NULL) + wakeup(&sc->sc_deferredq); PS3DISK_UNLOCK(sc); } -static void -ps3disk_getphys(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - if (error != 0) - return; - - *(bus_addr_t *) arg = segs[0].ds_addr; -} - static int ps3disk_get_disk_geometry(struct ps3disk_softc *sc) { @@ -582,8 +478,7 @@ ps3disk_get_disk_geometry(struct ps3disk_softc *sc) lv1_repository_string("blk_size"), 0, &sc->sc_blksize, &junk); if (err) { device_printf(dev, "Could not get block size (0x%08x)\n", err); - err = ENXIO; - goto out; + return (ENXIO); } err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, @@ -591,16 +486,11 @@ ps3disk_get_disk_geometry(struct ps3disk_softc *sc) lv1_repository_string("dev") | dev_index, lv1_repository_string("n_blocks"), 0, &sc->sc_nblocks, &junk); if (err) { - device_printf(dev, "Could not get total number of blocks (0x%08x)\n", - err); + device_printf(dev, "Could not get total number of blocks " + "(0x%08x)\n", err); err = ENXIO; - goto out; } - err = 0; - -out: - return (err); } @@ -655,10 +545,11 @@ ps3disk_enum_regions(struct ps3disk_softc *sc) (lv1_repository_string("bus") >> 32) | bus_index, lv1_repository_string("dev") | dev_index, lv1_repository_string("region") | i, - lv1_repository_string("start"), &sc->sc_reg[i].r_start, &junk); + lv1_repository_string("start"), &sc->sc_reg[i].r_start, + &junk); if (err) { - device_printf(dev, "Could not get region start (0x%08x)\n", - err); + device_printf(dev, "Could not get region start " + "(0x%08x)\n", err); err = ENXIO; goto fail; } @@ -667,16 +558,16 @@ ps3disk_enum_regions(struct ps3disk_softc *sc) (lv1_repository_string("bus") >> 32) | bus_index, lv1_repository_string("dev") | dev_index, lv1_repository_string("region") | i, - lv1_repository_string("size"), &sc->sc_reg[i].r_size, &junk); + lv1_repository_string("size"), &sc->sc_reg[i].r_size, + &junk); if (err) { - device_printf(dev, "Could not get region size (0x%08x)\n", - err); + device_printf(dev, "Could not get region size " + "(0x%08x)\n", err); err = ENXIO; goto fail; } if (i == 0) - /* disables HV access control and grants access to whole disk */ sc->sc_reg[i].r_flags = 0x2; else sc->sc_reg[i].r_flags = 0; @@ -693,160 +584,70 @@ fail: return (err); } -static int -ps3disk_read(struct ps3disk_softc *sc, int regidx, - uint64_t start_sector, uint64_t sector_count, char *data) +static void +ps3disk_transfer(void *arg, bus_dma_segment_t *segs, int nsegs, int error) { - device_t dev = sc->sc_dev; - struct ps3disk_region *rp = &sc->sc_reg[regidx]; - uint64_t devid = ps3bus_get_device(dev); - int err; + struct bio *bp = (struct bio *)(arg); + struct ps3disk_softc *sc = (struct ps3disk_softc *)bp->bio_disk->d_drv1; + struct ps3disk_region *rp = &sc->sc_reg[bp->bio_disk->d_unit]; + uint64_t devid = ps3bus_get_device(sc->sc_dev); + uint64_t block; + int i, err; - PS3DISK_LOCK(sc); + /* Locks already held by busdma */ + PS3DISK_ASSERT_LOCKED(sc); - if (sc->sc_bounce_busy) { - device_printf(dev, "busy\n"); - PS3DISK_UNLOCK(sc); - return EIO; + if (error) { + bp->bio_error = error; + bp->bio_flags |= BIO_ERROR; + bioq_remove(&sc->sc_bioq, bp); + biodone(bp); + return; } - sc->sc_bounce_busy = 1; + block = bp->bio_pblkno; + for (i = 0; i < nsegs; i++) { + KASSERT((segs[i].ds_len % sc->sc_blksize) == 0, + ("DMA fragments not blocksize multiples")); - err = lv1_storage_read(devid, rp->r_id, - start_sector, sector_count, rp->r_flags, - sc->sc_bounce_lpar, &sc->sc_bounce_tag); - if (err) { - device_printf(dev, "Could not read sectors (0x%08x)\n", err); - err = EIO; - goto out; + if (bp->bio_cmd == BIO_READ) { + err = lv1_storage_read(devid, rp->r_id, + block, segs[i].ds_len/sc->sc_blksize, + rp->r_flags, segs[i].ds_addr, + (uint64_t *)&bp->bio_driver2); + } else { + bus_dmamap_sync(sc->sc_dmatag, + (bus_dmamap_t)bp->bio_driver1, + BUS_DMASYNC_PREWRITE); + err = lv1_storage_write(devid, rp->r_id, + block, segs[i].ds_len/sc->sc_blksize, + rp->r_flags, segs[i].ds_addr, + (uint64_t *)&bp->bio_driver2); + } + + if (err) { + if (err == LV1_BUSY) { + bioq_remove(&sc->sc_bioq, bp); + bioq_insert_tail(&sc->sc_deferredq, bp); + } else { + bus_dmamap_unload(sc->sc_dmatag, (bus_dmamap_t) + bp->bio_driver1); + bus_dmamap_destroy(sc->sc_dmatag, (bus_dmamap_t) + bp->bio_driver1); + device_printf(sc->sc_dev, "Could not read " + "sectors (0x%08x)\n", err); + bp->bio_error = EINVAL; + bp->bio_flags |= BIO_ERROR; + bioq_remove(&sc->sc_bioq, bp); + biodone(bp); + } + + break; + } + + DPRINTF(sc, PS3DISK_DEBUG_READ, "%s: tag 0x%016lx\n", + __func__, sc->sc_bounce_tag); } - - DPRINTF(sc, PS3DISK_DEBUG_READ, "%s: tag 0x%016lx\n", - __func__, sc->sc_bounce_tag); - - err = msleep(sc, &sc->sc_mtx, PRIBIO, "read", hz); - if (err) { - device_printf(dev, "Read request timed out\n"); - err = EIO; - goto out; - } - - if (sc->sc_bounce_busy || sc->sc_bounce_status) { - err = EIO; - } else { - bus_dmamap_sync(sc->sc_bounce_dmatag, sc->sc_bounce_dmamap, - BUS_DMASYNC_POSTREAD); - memcpy(data, sc->sc_bounce, sector_count * sc->sc_blksize); - err = 0; - } - -out: - - sc->sc_bounce_busy = 0; - - PS3DISK_UNLOCK(sc); - - return (err); -} - -static int -ps3disk_write(struct ps3disk_softc *sc, int regidx, - uint64_t start_sector, uint64_t sector_count, char *data) -{ - device_t dev = sc->sc_dev; - struct ps3disk_region *rp = &sc->sc_reg[regidx]; - uint64_t devid = ps3bus_get_device(dev); - int err; - - PS3DISK_LOCK(sc); - - if (sc->sc_bounce_busy) { - device_printf(dev, "busy\n"); - PS3DISK_UNLOCK(sc); - return EIO; - } - - memcpy(sc->sc_bounce, data, sector_count * sc->sc_blksize); - - bus_dmamap_sync(sc->sc_bounce_dmatag, sc->sc_bounce_dmamap, - BUS_DMASYNC_PREWRITE); - - sc->sc_bounce_busy = 1; - - err = lv1_storage_write(devid, rp->r_id, - start_sector, sector_count, rp->r_flags, - sc->sc_bounce_lpar, &sc->sc_bounce_tag); - if (err) { - device_printf(dev, "Could not write sectors (0x%08x)\n", err); - err = EIO; - goto out; - } - - DPRINTF(sc, PS3DISK_DEBUG_WRITE, "%s: tag 0x%016lx\n", - __func__, sc->sc_bounce_tag); - - err = msleep(sc, &sc->sc_mtx, PRIBIO, "write", hz); - if (err) { - device_printf(dev, "Write request timed out\n"); - err = EIO; - goto out; - } - - err = (sc->sc_bounce_busy || sc->sc_bounce_status) ? EIO : 0; - -out: - - sc->sc_bounce_busy = 0; - - PS3DISK_UNLOCK(sc); - - return (err); -} - -static int -ps3disk_flush(struct ps3disk_softc *sc) -{ - device_t dev = sc->sc_dev; - uint64_t devid = ps3bus_get_device(dev); - int err; - - PS3DISK_LOCK(sc); - - if (sc->sc_bounce_busy) { - device_printf(dev, "busy\n"); - PS3DISK_UNLOCK(sc); - return EIO; - } - - sc->sc_bounce_busy = 1; - - err = lv1_storage_send_device_command(devid, LV1_STORAGE_ATA_HDDOUT, - 0, 0, 0, 0, &sc->sc_bounce_tag); - if (err) { - device_printf(dev, "Could not flush (0x%08x)\n", err); - err = EIO; - goto out; - } - - DPRINTF(sc, PS3DISK_DEBUG_FLUSH, "%s: tag 0x%016lx\n", - __func__, sc->sc_bounce_tag); - - err = msleep(sc, &sc->sc_mtx, PRIBIO, "flush", hz); - if (err) { - device_printf(dev, "Flush request timed out\n"); - err = EIO; - goto out; - } - - err = (sc->sc_bounce_busy || sc->sc_bounce_status) ? EIO : 0; - -out: - - sc->sc_bounce_busy = 0; - - PS3DISK_UNLOCK(sc); - - return (err); } #ifdef PS3DISK_DEBUG From 1c167648c90c1df206aea016697bb28771c256a1 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 23 Jun 2011 04:06:33 +0000 Subject: [PATCH 20/57] Use 4 KB pages for storage bus devices, which seems to be what the HV uses internally. --- sys/powerpc/ps3/ps3bus.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/powerpc/ps3/ps3bus.c b/sys/powerpc/ps3/ps3bus.c index 88b4be20ef6a..90f0e87cc9f4 100644 --- a/sys/powerpc/ps3/ps3bus.c +++ b/sys/powerpc/ps3/ps3bus.c @@ -629,7 +629,7 @@ ps3bus_get_dma_tag(device_t dev, device_t child) { struct ps3bus_devinfo *dinfo = device_get_ivars(child); struct ps3bus_softc *sc = device_get_softc(dev); - int i, err, flags; + int i, err, flags, pagesize; if (dinfo->bustype != PS3_BUSTYPE_SYSBUS && dinfo->bustype != PS3_BUSTYPE_STORAGE) @@ -646,9 +646,13 @@ ps3bus_get_dma_tag(device_t dev, device_t child) dinfo->devtype == PS3_DEVTYPE_USB) flags = 2; /* 8-bit mode */ + pagesize = 24; /* log_2(16 MB) */ + if (dinfo->bustype == PS3_BUSTYPE_STORAGE) + pagesize = 12; /* 4 KB */ + for (i = 0; i < sc->rcount; i++) { err = lv1_allocate_device_dma_region(dinfo->bus, dinfo->dev, - sc->regions[i].mr_size, 24 /* log_2(16 MB) */, flags, + sc->regions[i].mr_size, pagesize, flags, &dinfo->dma_base[i]); if (err != 0) { device_printf(child, From f574af0d6daa56ee36a4a6248aa871ccd8216ce3 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 23 Jun 2011 04:35:45 +0000 Subject: [PATCH 21/57] Use atomic operations to mask and unmask IRQs. This prevents a problem (obvious in retrospect) in which interrupts on one CPU that are temporarily masked can end up permanently masked when a handler on another CPU clobbers the interrupt mask register with an old copy. --- sys/powerpc/ps3/ps3pic.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/powerpc/ps3/ps3pic.c b/sys/powerpc/ps3/ps3pic.c index c00585bdf6ff..3a62e3c2fbeb 100644 --- a/sys/powerpc/ps3/ps3pic.c +++ b/sys/powerpc/ps3/ps3pic.c @@ -56,10 +56,10 @@ static void ps3pic_mask(device_t, u_int); static void ps3pic_unmask(device_t, u_int); struct ps3pic_softc { - uint64_t *bitmap_thread0; - uint64_t *mask_thread0; - uint64_t *bitmap_thread1; - uint64_t *mask_thread1; + volatile uint64_t *bitmap_thread0; + volatile uint64_t *mask_thread0; + volatile uint64_t *bitmap_thread1; + volatile uint64_t *mask_thread1; uint64_t sc_ipi_outlet[2]; int sc_vector[64]; @@ -219,8 +219,8 @@ ps3pic_mask(device_t dev, u_int irq) if (irq == sc->sc_ipi_outlet[0]) return; - sc->mask_thread0[0] &= ~(1UL << (63 - irq)); - sc->mask_thread1[0] &= ~(1UL << (63 - irq)); + atomic_clear_64(&sc->mask_thread0[0], 1UL << (63 - irq)); + atomic_clear_64(&sc->mask_thread1[0], 1UL << (63 - irq)); lv1_get_logical_ppe_id(&ppe); lv1_did_update_interrupt_mask(ppe, 0); @@ -234,8 +234,8 @@ ps3pic_unmask(device_t dev, u_int irq) uint64_t ppe; sc = device_get_softc(dev); - sc->mask_thread0[0] |= (1UL << (63 - irq)); - sc->mask_thread1[0] |= (1UL << (63 - irq)); + atomic_set_64(&sc->mask_thread0[0], 1UL << (63 - irq)); + atomic_set_64(&sc->mask_thread1[0], 1UL << (63 - irq)); lv1_get_logical_ppe_id(&ppe); lv1_did_update_interrupt_mask(ppe, 0); From 1bfec3dfb638640d7d2e9991f97e1a4e2e4db3a8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 23 Jun 2011 05:23:59 +0000 Subject: [PATCH 22/57] Revert to using the page queues lock in vm_page_clear_dirty_mask() on MIPS. (At present, although atomic_clear_char() is defined by atomic.h on MIPS, it is not actually implemented by support.S.) --- sys/vm/vm_fault.c | 3 +-- sys/vm/vm_page.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 7568f573df56..55abe868ef4f 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -1095,8 +1095,7 @@ vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len, * required in order to call vm_page_dirty(). See * vm_page_clear_dirty_mask(). */ -#if defined(__amd64__) || defined(__i386__) || defined(__ia64__) || \ - defined(__mips__) +#if defined(__amd64__) || defined(__i386__) || defined(__ia64__) vm_page_dirty(*mp); #else vm_page_lock_queues(); diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 033c4c9d1529..8e0c8bbaac30 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -2336,8 +2336,7 @@ vm_page_clear_dirty_mask(vm_page_t m, int pagebits) if ((m->oflags & VPO_BUSY) == 0 && (m->flags & PG_WRITEABLE) == 0) m->dirty &= ~pagebits; else { -#if defined(__amd64__) || defined(__i386__) || defined(__ia64__) || \ - defined(__mips__) +#if defined(__amd64__) || defined(__i386__) || defined(__ia64__) /* * On the aforementioned architectures, the page queues lock * is not required by the following read-modify-write From 4c728c42f584fe72d7d639ebba8af4536044d113 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 23 Jun 2011 06:53:13 +0000 Subject: [PATCH 23/57] Fix indenting issues introduced by the previous commit. --- sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c | 4 ++-- sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c b/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c index 6c1937aff1cf..bf0b38a56db7 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_beacon.c @@ -84,9 +84,9 @@ ar5212BeaconInit(struct ath_hal *ah, case HAL_M_HOSTAP: case HAL_M_IBSS: bt.bt_nextdba = (next_beacon - - ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */ bt.bt_nextswba = (next_beacon - - ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */ break; } /* diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c b/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c index ee6c1eb3645a..66b50537de96 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_beacon.c @@ -93,9 +93,9 @@ ar5416BeaconInit(struct ath_hal *ah, /* fall thru... */ case HAL_M_HOSTAP: bt.bt_nextdba = (next_beacon - - ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */ bt.bt_nextswba = (next_beacon - - ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */ + ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */ bt.bt_flags |= AR_TIMER_MODE_TBTT | AR_TIMER_MODE_DBA | AR_TIMER_MODE_SWBA; From f6f1dfb66b8361d0fc09b50a882b0b7be2ef26b3 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 23 Jun 2011 06:55:29 +0000 Subject: [PATCH 24/57] Re-introduce a global ath_hal_debug again for now, whilst I figure out what to do about the few cases where the HAL state isn't available (regdomain) or isn't yet setup (probe/attach.) The global ath_hal_debug now affects all instances of the HAL. This also restores the ability for probe/attach debugging to work; as the sysctl tree may not be attached at that point. Users can just set the global "hw.ath.hal.debug" to a suitable value to enable probe/attach related debugging. --- sys/dev/ath/ath_hal/ah_internal.h | 21 ++++++++++++++++++++- sys/dev/ath/ath_hal/ah_regdomain.c | 4 ++-- sys/dev/ath/ath_hal/ar5210/ar5210_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar5211/ar5211_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar5212/ar5112.c | 2 +- sys/dev/ath/ath_hal/ar5212/ar5212_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar5312/ar5312_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar5416/ar5416_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar9001/ar9130_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar9001/ar9160_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar9002/ar9280_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar9002/ar9285_attach.c | 4 ++-- sys/dev/ath/ath_hal/ar9002/ar9287_attach.c | 4 ++-- 13 files changed, 43 insertions(+), 24 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index 91edc34e2978..0959218b39da 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -498,10 +498,29 @@ extern void ath_hal_free(void *); /* common debugging interfaces */ #ifdef AH_DEBUG #include "ah_debug.h" +extern int ath_hal_debug; /* Global debug flags */ + +/* + * This is used for global debugging, when ahp doesn't yet have the + * related debugging state. For example, during probe/attach. + */ +#define HALDEBUG_G(_ah, __m, ...) \ + do { \ + if ((__m) == HAL_DEBUG_UNMASKABLE || \ + ath_hal_debug & (__m)) { \ + DO_HALDEBUG((_ah), (__m), __VA_ARGS__); \ + } \ + } while (0); + +/* + * This is used for local debugging, when ahp isn't NULL and + * thus may have debug flags set. + */ #define HALDEBUG(_ah, __m, ...) \ do { \ if ((__m) == HAL_DEBUG_UNMASKABLE || \ - ((_ah != AH_NULL) && (((struct ath_hal*)_ah)->ah_config.ah_debug & (__m)))) { \ + ath_hal_debug & (__m) || \ + (_ah)->ah_config.ah_debug & (__m)) { \ DO_HALDEBUG((_ah), (__m), __VA_ARGS__); \ } \ } while(0); diff --git a/sys/dev/ath/ath_hal/ah_regdomain.c b/sys/dev/ath/ath_hal/ah_regdomain.c index c17d0f6d5834..9aae3324a00d 100644 --- a/sys/dev/ath/ath_hal/ah_regdomain.c +++ b/sys/dev/ath/ath_hal/ah_regdomain.c @@ -167,7 +167,7 @@ isEepromValid(struct ath_hal *ah) if (regDomainPairs[i].regDmnEnum == rd) return AH_TRUE; } - HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, + HALDEBUG_G(ah, HAL_DEBUG_REGDOMAIN, "%s: invalid regulatory domain/country code 0x%x\n", __func__, rd); return AH_FALSE; } @@ -609,7 +609,7 @@ ath_hal_mapgsm(int sku, int freq) return 1544 + freq; if (sku == SKU_SR9) return 3344 - freq; - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot map freq %u unknown gsm sku %u\n", __func__, freq, sku); return freq; diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c index 2068733b2f6a..41d957a614c6 100644 --- a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c +++ b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c @@ -181,14 +181,14 @@ ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS ecode; int i; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: devid 0x%x sc %p st %p sh %p\n", __func__, devid, sc, (void*) st, (void*) sh); /* NB: memory is returned zero'd */ ahp = ath_hal_malloc(sizeof (struct ath_hal_5210)); if (ahp == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: no memory for state block\n", __func__); ecode = HAL_ENOMEM; goto bad; diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c index 308ecc9f6f61..14daa0bffedc 100644 --- a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c +++ b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c @@ -200,13 +200,13 @@ ar5211Attach(uint16_t devid, HAL_SOFTC sc, uint16_t eeval; HAL_STATUS ecode; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", __func__, sc, (void*) st, (void*) sh); /* NB: memory is returned zero'd */ ahp = ath_hal_malloc(sizeof (struct ath_hal_5211)); if (ahp == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot allocate memory for state block\n", __func__); ecode = HAL_ENOMEM; goto bad; diff --git a/sys/dev/ath/ath_hal/ar5212/ar5112.c b/sys/dev/ath/ath_hal/ar5212/ar5112.c index c1920b935fd0..10030682a2e8 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5112.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5112.c @@ -611,7 +611,7 @@ getFullPwrTable(uint16_t numPcdacs, uint16_t *pcdacs, int16_t *power, int16_t ma uint16_t idxR = 1; if (numPcdacs < 2) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: at least 2 pcdac values needed [%d]\n", __func__, numPcdacs); return AH_FALSE; diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c index 8e7f3cbddf04..01c0e2c8ad07 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c @@ -317,13 +317,13 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc, uint16_t eeval; HAL_STATUS ecode; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", __func__, sc, (void*) st, (void*) sh); /* NB: memory is returned zero'd */ ahp = ath_hal_malloc(sizeof (struct ath_hal_5212)); if (ahp == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot allocate memory for state block\n", __func__); *status = HAL_ENOMEM; return AH_NULL; diff --git a/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c b/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c index 4ca1a4d0b7df..d1689d59fc61 100644 --- a/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c +++ b/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c @@ -71,13 +71,13 @@ ar5312Attach(uint16_t devid, HAL_SOFTC sc, uint16_t eeval; HAL_STATUS ecode; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", __func__, sc, st, (void*) sh); /* NB: memory is returned zero'd */ ahp = ath_hal_malloc(sizeof (struct ath_hal_5212)); if (ahp == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot allocate memory for state block\n", __func__); *status = HAL_ENOMEM; return AH_NULL; diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c index e6363251f8a2..607f97ab481d 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c @@ -241,7 +241,7 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc, HAL_STATUS ecode; HAL_BOOL rfStatus; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", __func__, sc, (void*) st, (void*) sh); /* NB: memory is returned zero'd */ @@ -250,7 +250,7 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc, sizeof(ar5416Addac) ); if (ahp5416 == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot allocate memory for state block\n", __func__); *status = HAL_ENOMEM; return AH_NULL; diff --git a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c index 2a3f3f0f02f0..518ed85fe852 100644 --- a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c +++ b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c @@ -78,13 +78,13 @@ ar9130Attach(uint16_t devid, HAL_SOFTC sc, HAL_STATUS ecode; HAL_BOOL rfStatus; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", __func__, sc, (void*) st, (void*) sh); /* NB: memory is returned zero'd */ ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416)); if (ahp5416 == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot allocate memory for state block\n", __func__); *status = HAL_ENOMEM; return AH_NULL; diff --git a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c index 44a549d4b3cd..a87d1adc0e71 100644 --- a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c +++ b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c @@ -101,13 +101,13 @@ ar9160Attach(uint16_t devid, HAL_SOFTC sc, HAL_STATUS ecode; HAL_BOOL rfStatus; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", __func__, sc, (void*) st, (void*) sh); /* NB: memory is returned zero'd */ ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416)); if (ahp5416 == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot allocate memory for state block\n", __func__); *status = HAL_ENOMEM; return AH_NULL; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c index ebe3be1b9f1d..3743c2195111 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c @@ -120,13 +120,13 @@ ar9280Attach(uint16_t devid, HAL_SOFTC sc, int8_t pwr_table_offset; uint8_t pwr; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", __func__, sc, (void*) st, (void*) sh); /* NB: memory is returned zero'd */ ahp9280 = ath_hal_malloc(sizeof (struct ath_hal_9280)); if (ahp9280 == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot allocate memory for state block\n", __func__); *status = HAL_ENOMEM; return AH_NULL; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c index 912031397b57..2547148f838c 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c @@ -118,13 +118,13 @@ ar9285Attach(uint16_t devid, HAL_SOFTC sc, HAL_STATUS ecode; HAL_BOOL rfStatus; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", __func__, sc, (void*) st, (void*) sh); /* NB: memory is returned zero'd */ ahp9285 = ath_hal_malloc(sizeof (struct ath_hal_9285)); if (ahp9285 == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot allocate memory for state block\n", __func__); *status = HAL_ENOMEM; return AH_NULL; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c index 9cbe0a5e5d36..f3b403b8ae80 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c @@ -119,13 +119,13 @@ ar9287Attach(uint16_t devid, HAL_SOFTC sc, HAL_BOOL rfStatus; int8_t pwr_table_offset; - HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", + HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", __func__, sc, (void*) st, (void*) sh); /* NB: memory is returned zero'd */ ahp9287 = ath_hal_malloc(sizeof (struct ath_hal_9287)); if (ahp9287 == AH_NULL) { - HALDEBUG(AH_NULL, HAL_DEBUG_ANY, + HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY, "%s: cannot allocate memory for state block\n", __func__); *status = HAL_ENOMEM; return AH_NULL; From 399e6543b2eea74c22e44cd04d35eb852f744f15 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Thu, 23 Jun 2011 07:54:03 +0000 Subject: [PATCH 25/57] - Add more USB templates for various USB device classes - Add basic template support for USB 3.0 - Export definition of template sysctl numbers through usb_ioctl.h MFC after: 7 days --- sys/conf/files | 6 +- sys/dev/usb/template/usb_template.c | 48 ++- sys/dev/usb/template/usb_template.h | 14 +- sys/dev/usb/template/usb_template_audio.c | 400 ++++++++++++++++++++++ sys/dev/usb/template/usb_template_cdce.c | 2 +- sys/dev/usb/template/usb_template_kbd.c | 222 ++++++++++++ sys/dev/usb/template/usb_template_modem.c | 252 ++++++++++++++ sys/dev/usb/template/usb_template_mouse.c | 220 ++++++++++++ sys/dev/usb/template/usb_template_msc.c | 4 +- sys/dev/usb/template/usb_template_mtp.c | 4 +- sys/dev/usb/usb_ioctl.h | 14 + sys/modules/usb/template/Makefile | 9 +- 12 files changed, 1182 insertions(+), 13 deletions(-) create mode 100644 sys/dev/usb/template/usb_template_audio.c create mode 100644 sys/dev/usb/template/usb_template_kbd.c create mode 100644 sys/dev/usb/template/usb_template_modem.c create mode 100644 sys/dev/usb/template/usb_template_mouse.c diff --git a/sys/conf/files b/sys/conf/files index a62e1a628b49..1a8d5ff1f550 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1991,8 +1991,12 @@ dev/usb/quirk/usb_quirk.c optional usb # # USB templates # -dev/usb/template/usb_template.c optional usb_template +dev/usb/template/usb_template.c optional usb_template +dev/usb/template/usb_template_audio.c optional usb_template dev/usb/template/usb_template_cdce.c optional usb_template +dev/usb/template/usb_template_kbd.c optional usb_template +dev/usb/template/usb_template_modem.c optional usb_template +dev/usb/template/usb_template_mouse.c optional usb_template dev/usb/template/usb_template_msc.c optional usb_template dev/usb/template/usb_template_mtp.c optional usb_template # diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c index 7bf17feb3a0a..cf97482f59b0 100644 --- a/sys/dev/usb/template/usb_template.c +++ b/sys/dev/usb/template/usb_template.c @@ -49,6 +49,7 @@ #include #include +#include #include #include #include "usbdevs.h" @@ -141,6 +142,31 @@ usb_make_raw_desc(struct usb_temp_setup *temp, ud->bSlaveInterface[0] += temp->bInterfaceNumber; } + + /* check if we have got an interface association descriptor */ + + if ((raw[0] >= sizeof(struct usb_interface_assoc_descriptor)) && + (raw[1] == UDESC_IFACE_ASSOC)) { + struct usb_interface_assoc_descriptor *iad = (void *)dst; + + /* update the interface number */ + + iad->bFirstInterface += + temp->bInterfaceNumber; + } + + /* check if we have got a call management descriptor */ + + if ((raw[0] >= sizeof(struct usb_cdc_cm_descriptor)) && + (raw[1] == UDESC_CS_INTERFACE) && + (raw[2] == UDESCSUB_CDC_CM)) { + struct usb_cdc_cm_descriptor *ccd = (void *)dst; + + /* update the interface number */ + + ccd->bDataInterface += + temp->bInterfaceNumber; + } } temp->size += len; } @@ -476,6 +502,10 @@ usb_make_device_desc(struct usb_temp_setup *temp, USETW(utd->udd.bcdUSB, 0x0250); utd->udd.bMaxPacketSize = 255; /* 512 bytes */ break; + case USB_SPEED_SUPER: + USETW(utd->udd.bcdUSB, 0x0300); + utd->udd.bMaxPacketSize = 9; /* 2**9 = 512 bytes */ + break; default: temp->err = USB_ERR_INVAL; break; @@ -1303,15 +1333,27 @@ usb_temp_setup_by_index(struct usb_device *udev, uint16_t index) usb_error_t err; switch (index) { - case 0: + case USB_TEMP_MSC: err = usb_temp_setup(udev, &usb_template_msc); break; - case 1: + case USB_TEMP_CDCE: err = usb_temp_setup(udev, &usb_template_cdce); break; - case 2: + case USB_TEMP_MTP: err = usb_temp_setup(udev, &usb_template_mtp); break; + case USB_TEMP_MODEM: + err = usb_temp_setup(udev, &usb_template_modem); + break; + case USB_TEMP_AUDIO: + err = usb_temp_setup(udev, &usb_template_audio); + break; + case USB_TEMP_KBD: + err = usb_temp_setup(udev, &usb_template_kbd); + break; + case USB_TEMP_MOUSE: + err = usb_temp_setup(udev, &usb_template_mouse); + break; default: return (USB_ERR_INVAL); } diff --git a/sys/dev/usb/template/usb_template.h b/sys/dev/usb/template/usb_template.h index 2473af3b4cee..b05272fb2a71 100644 --- a/sys/dev/usb/template/usb_template.h +++ b/sys/dev/usb/template/usb_template.h @@ -30,6 +30,10 @@ #ifndef _USB_TEMPLATE_H_ #define _USB_TEMPLATE_H_ +#ifndef USB_TEMPLATE_VENDOR +#define USB_TEMPLATE_VENDOR 0x0001 +#endif + typedef const void *(usb_temp_get_string_desc_t)(uint16_t lang_id, uint8_t string_index); typedef const void *(usb_temp_get_vendor_desc_t)(const struct usb_device_request *req, uint16_t *plen); @@ -94,10 +98,14 @@ struct usb_temp_data { /* prototypes */ +extern const struct usb_temp_device_desc usb_template_audio; extern const struct usb_temp_device_desc usb_template_cdce; -extern const struct usb_temp_device_desc usb_template_msc; /* Mass Storage Class */ -extern const struct usb_temp_device_desc usb_template_mtp; /* Message Transfer - * Protocol */ +extern const struct usb_temp_device_desc usb_template_kbd; +extern const struct usb_temp_device_desc usb_template_modem; +extern const struct usb_temp_device_desc usb_template_mouse; +extern const struct usb_temp_device_desc usb_template_msc; +extern const struct usb_temp_device_desc usb_template_mtp; + usb_error_t usb_temp_setup(struct usb_device *, const struct usb_temp_device_desc *); void usb_temp_unsetup(struct usb_device *); diff --git a/sys/dev/usb/template/usb_template_audio.c b/sys/dev/usb/template/usb_template_audio.c new file mode 100644 index 000000000000..1e2e56869dcb --- /dev/null +++ b/sys/dev/usb/template/usb_template_audio.c @@ -0,0 +1,400 @@ +#include +__FBSDID("$FreeBSD$"); + +/*- + * Copyright (c) 2010 Hans Petter Selasky. 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 file contains the USB template for an USB Audio Device. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +enum { + INDEX_AUDIO_LANG, + INDEX_AUDIO_MIXER, + INDEX_AUDIO_RECORD, + INDEX_AUDIO_PLAYBACK, + INDEX_AUDIO_PRODUCT, + INDEX_AUDIO_MAX, +}; + +#define STRING_LANG \ + 0x09, 0x04, /* American English */ + +#define STRING_AUDIO_PRODUCT \ + 'A', 0, 'u', 0, 'd', 0, 'i', 0, 'o', 0, ' ', 0, \ + 'T', 0, 'e', 0, 's', 0, 't', 0, ' ', 0, \ + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, ' ', 0, + +#define STRING_AUDIO_MIXER \ + 'M', 0, 'i', 0, 'x', 0, 'e', 0, 'r', 0, ' ', 0, \ + 'i', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, + +#define STRING_AUDIO_RECORD \ + 'R', 0, 'e', 0, 'c', 0, 'o', 0, 'r', 0, 'd', 0, ' ', 0, \ + 'i', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, + +#define STRING_AUDIO_PLAYBACK \ + 'P', 0, 'l', 0, 'a', 0, 'y', 0, 'b', 0, 'a', 0, 'c', 0, 'k', 0, ' ', 0, \ + 'i', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, + + +/* make the real string descriptors */ + +USB_MAKE_STRING_DESC(STRING_LANG, string_lang); +USB_MAKE_STRING_DESC(STRING_AUDIO_MIXER, string_audio_mixer); +USB_MAKE_STRING_DESC(STRING_AUDIO_RECORD, string_audio_record); +USB_MAKE_STRING_DESC(STRING_AUDIO_PLAYBACK, string_audio_playback); +USB_MAKE_STRING_DESC(STRING_AUDIO_PRODUCT, string_audio_product); + +/* prototypes */ + +/* Audio Mixer description structures */ + +static const uint8_t audio_raw_desc_0[] = { + 0x0a, 0x24, 0x01, 0x00, 0x01, 0xa9, 0x00, 0x02, + 0x01, 0x02 +}; + +static const uint8_t audio_raw_desc_1[] = { + 0x0c, 0x24, 0x02, 0x01, 0x01, 0x01, 0x00, 0x02, + 0x03, 0x00, 0x00, 0x00 +}; + +static const uint8_t audio_raw_desc_2[] = { + 0x0c, 0x24, 0x02, 0x02, 0x01, 0x02, 0x00, 0x02, + 0x03, 0x00, 0x00, 0x00 +}; + +static const uint8_t audio_raw_desc_3[] = { + 0x0c, 0x24, 0x02, 0x03, 0x03, 0x06, 0x00, 0x02, + 0x03, 0x00, 0x00, 0x00 +}; + +static const uint8_t audio_raw_desc_4[] = { + 0x0c, 0x24, 0x02, 0x04, 0x05, 0x06, 0x00, 0x02, + 0x03, 0x00, 0x00, 0x00 +}; + +static const uint8_t audio_raw_desc_5[] = { + 0x09, 0x24, 0x03, 0x05, 0x05, 0x06, 0x00, 0x01, + 0x00 +}; + +static const uint8_t audio_raw_desc_6[] = { + 0x09, 0x24, 0x03, 0x06, 0x01, 0x03, 0x00, 0x09, + 0x00 +}; + +static const uint8_t audio_raw_desc_7[] = { + 0x09, 0x24, 0x03, 0x07, 0x01, 0x01, 0x00, 0x08, + 0x00 +}; + +static const uint8_t audio_raw_desc_8[] = { + 0x09, 0x24, 0x05, 0x08, 0x03, 0x0a, 0x0b, 0x0c, + 0x00 +}; + +static const uint8_t audio_raw_desc_9[] = { + 0x0a, 0x24, 0x06, 0x09, 0x0f, 0x01, 0x01, 0x02, + 0x02, 0x00 +}; + +static const uint8_t audio_raw_desc_10[] = { + 0x0a, 0x24, 0x06, 0x0a, 0x02, 0x01, 0x43, 0x00, + 0x00, 0x00 +}; + +static const uint8_t audio_raw_desc_11[] = { + 0x0a, 0x24, 0x06, 0x0b, 0x03, 0x01, 0x01, 0x02, + 0x02, 0x00 +}; + +static const uint8_t audio_raw_desc_12[] = { + 0x0a, 0x24, 0x06, 0x0c, 0x04, 0x01, 0x01, 0x00, + 0x00, 0x00 +}; + +static const uint8_t audio_raw_desc_13[] = { + 0x0a, 0x24, 0x06, 0x0d, 0x02, 0x01, 0x03, 0x00, + 0x00, 0x00 +}; + +static const uint8_t audio_raw_desc_14[] = { + 0x0a, 0x24, 0x06, 0x0e, 0x03, 0x01, 0x01, 0x02, + 0x02, 0x00 +}; + +static const uint8_t audio_raw_desc_15[] = { + 0x0f, 0x24, 0x04, 0x0f, 0x03, 0x01, 0x0d, 0x0e, + 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const void *audio_raw_iface_0_desc[] = { + audio_raw_desc_0, + audio_raw_desc_1, + audio_raw_desc_2, + audio_raw_desc_3, + audio_raw_desc_4, + audio_raw_desc_5, + audio_raw_desc_6, + audio_raw_desc_7, + audio_raw_desc_8, + audio_raw_desc_9, + audio_raw_desc_10, + audio_raw_desc_11, + audio_raw_desc_12, + audio_raw_desc_13, + audio_raw_desc_14, + audio_raw_desc_15, + NULL, +}; + +static const struct usb_temp_interface_desc audio_iface_0 = { + .ppEndpoints = NULL, /* no endpoints */ + .ppRawDesc = audio_raw_iface_0_desc, + .bInterfaceClass = 1, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .iInterface = INDEX_AUDIO_MIXER, +}; + +static const uint8_t audio_raw_desc_20[] = { + 0x07, 0x24, 0x01, 0x01, 0x03, 0x01, 0x00 + +}; + +static const uint8_t audio_raw_desc_21[] = { + 0x0b, 0x24, 0x02, 0x01, 0x02, 0x02, 0x10, 0x01, + /* 48kHz */ + 0x80, 0xbb, 0x00 +}; + +static const uint8_t audio_raw_desc_22[] = { + 0x07, 0x25, 0x01, 0x00, 0x01, 0x04, 0x00 +}; + +static const void *audio_raw_iface_1_desc[] = { + audio_raw_desc_20, + audio_raw_desc_21, + NULL, +}; + +static const void *audio_raw_ep_1_desc[] = { + audio_raw_desc_22, + NULL, +}; + +static const struct usb_temp_packet_size audio_isoc_mps = { + .mps[USB_SPEED_FULL] = 0xC8, + .mps[USB_SPEED_HIGH] = 0xC8, +}; + +static const struct usb_temp_interval audio_isoc_interval = { + .bInterval[USB_SPEED_FULL] = 1, /* 1:1 */ + .bInterval[USB_SPEED_HIGH] = 4, /* 1:8 */ +}; + +static const struct usb_temp_endpoint_desc audio_isoc_out_ep = { + .ppRawDesc = audio_raw_ep_1_desc, + .pPacketSize = &audio_isoc_mps, + .pIntervals = &audio_isoc_interval, + .bEndpointAddress = UE_DIR_OUT, + .bmAttributes = UE_ISOCHRONOUS | UE_ISO_ADAPT, +}; + +static const struct usb_temp_endpoint_desc *audio_iface_1_ep[] = { + &audio_isoc_out_ep, + NULL, +}; + +static const struct usb_temp_interface_desc audio_iface_1_alt_0 = { + .ppEndpoints = NULL, /* no endpoints */ + .ppRawDesc = NULL, /* no raw descriptors */ + .bInterfaceClass = 1, + .bInterfaceSubClass = 2, + .bInterfaceProtocol = 0, + .iInterface = INDEX_AUDIO_PLAYBACK, +}; + +static const struct usb_temp_interface_desc audio_iface_1_alt_1 = { + .ppEndpoints = audio_iface_1_ep, + .ppRawDesc = audio_raw_iface_1_desc, + .bInterfaceClass = 1, + .bInterfaceSubClass = 2, + .bInterfaceProtocol = 0, + .iInterface = INDEX_AUDIO_PLAYBACK, + .isAltInterface = 1, /* this is an alternate setting */ +}; + +static const uint8_t audio_raw_desc_30[] = { + 0x07, 0x24, 0x01, 0x07, 0x01, 0x01, 0x00 + +}; + +static const uint8_t audio_raw_desc_31[] = { + 0x0b, 0x24, 0x02, 0x01, 0x02, 0x02, 0x10, 0x01, + /* 48kHz */ + 0x80, 0xbb, 0x00 +}; + +static const uint8_t audio_raw_desc_32[] = { + 0x07, 0x25, 0x01, 0x01, 0x00, 0x00, 0x00 +}; + +static const void *audio_raw_iface_2_desc[] = { + audio_raw_desc_30, + audio_raw_desc_31, + NULL, +}; + +static const void *audio_raw_ep_2_desc[] = { + audio_raw_desc_32, + NULL, +}; + +static const struct usb_temp_endpoint_desc audio_isoc_in_ep = { + .ppRawDesc = audio_raw_ep_2_desc, + .pPacketSize = &audio_isoc_mps, + .pIntervals = &audio_isoc_interval, + .bEndpointAddress = UE_DIR_IN, + .bmAttributes = UE_ISOCHRONOUS | UE_ISO_ADAPT, +}; + +static const struct usb_temp_endpoint_desc *audio_iface_2_ep[] = { + &audio_isoc_in_ep, + NULL, +}; + +static const struct usb_temp_interface_desc audio_iface_2_alt_0 = { + .ppEndpoints = NULL, /* no endpoints */ + .ppRawDesc = NULL, /* no raw descriptors */ + .bInterfaceClass = 1, + .bInterfaceSubClass = 2, + .bInterfaceProtocol = 0, + .iInterface = INDEX_AUDIO_RECORD, +}; + +static const struct usb_temp_interface_desc audio_iface_2_alt_1 = { + .ppEndpoints = audio_iface_2_ep, + .ppRawDesc = audio_raw_iface_2_desc, + .bInterfaceClass = 1, + .bInterfaceSubClass = 2, + .bInterfaceProtocol = 0, + .iInterface = INDEX_AUDIO_RECORD, + .isAltInterface = 1, /* this is an alternate setting */ +}; + +static const struct usb_temp_interface_desc *audio_interfaces[] = { + &audio_iface_0, + &audio_iface_1_alt_0, + &audio_iface_1_alt_1, + &audio_iface_2_alt_0, + &audio_iface_2_alt_1, + NULL, +}; + +static const struct usb_temp_config_desc audio_config_desc = { + .ppIfaceDesc = audio_interfaces, + .bmAttributes = UC_BUS_POWERED, + .bMaxPower = 25, /* 50 mA */ + .iConfiguration = INDEX_AUDIO_PRODUCT, +}; + +static const struct usb_temp_config_desc *audio_configs[] = { + &audio_config_desc, + NULL, +}; + +static usb_temp_get_string_desc_t audio_get_string_desc; + +const struct usb_temp_device_desc usb_template_audio = { + .getStringDesc = &audio_get_string_desc, + .ppConfigDesc = audio_configs, + .idVendor = USB_TEMPLATE_VENDOR, + .idProduct = 0x000A, + .bcdDevice = 0x0100, + .bDeviceClass = UDCLASS_COMM, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .iManufacturer = 0, + .iProduct = INDEX_AUDIO_PRODUCT, + .iSerialNumber = 0, +}; + +/*------------------------------------------------------------------------* + * audio_get_string_desc + * + * Return values: + * NULL: Failure. No such string. + * Else: Success. Pointer to string descriptor is returned. + *------------------------------------------------------------------------*/ +static const void * +audio_get_string_desc(uint16_t lang_id, uint8_t string_index) +{ + static const void *ptr[INDEX_AUDIO_MAX] = { + [INDEX_AUDIO_LANG] = &string_lang, + [INDEX_AUDIO_MIXER] = &string_audio_mixer, + [INDEX_AUDIO_RECORD] = &string_audio_record, + [INDEX_AUDIO_PLAYBACK] = &string_audio_playback, + [INDEX_AUDIO_PRODUCT] = &string_audio_product, + }; + + if (string_index == 0) { + return (&string_lang); + } + if (lang_id != 0x0409) { + return (NULL); + } + if (string_index < INDEX_AUDIO_MAX) { + return (ptr[string_index]); + } + return (NULL); +} diff --git a/sys/dev/usb/template/usb_template_cdce.c b/sys/dev/usb/template/usb_template_cdce.c index c8b2c6c831fa..481a69cb957f 100644 --- a/sys/dev/usb/template/usb_template_cdce.c +++ b/sys/dev/usb/template/usb_template_cdce.c @@ -264,7 +264,7 @@ static const struct usb_temp_config_desc *eth_configs[] = { const struct usb_temp_device_desc usb_template_cdce = { .getStringDesc = ð_get_string_desc, .ppConfigDesc = eth_configs, - .idVendor = 0x0001, + .idVendor = USB_TEMPLATE_VENDOR, .idProduct = 0x0001, .bcdDevice = 0x0100, .bDeviceClass = UDCLASS_COMM, diff --git a/sys/dev/usb/template/usb_template_kbd.c b/sys/dev/usb/template/usb_template_kbd.c new file mode 100644 index 000000000000..4a9b9dae11b3 --- /dev/null +++ b/sys/dev/usb/template/usb_template_kbd.c @@ -0,0 +1,222 @@ +#include +__FBSDID("$FreeBSD$"); + +/*- + * Copyright (c) 2010 Hans Petter Selasky. 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 file contains the USB template for an USB Keyboard Device. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +enum { + INDEX_LANG, + INDEX_KEYBOARD, + INDEX_PRODUCT, + INDEX_MAX, +}; + +#define STRING_LANG \ + 0x09, 0x04, /* American English */ + +#define STRING_PRODUCT \ + 'K', 0, 'e', 0, 'y', 0, 'b', 0, 'o', 0, 'a', 0, 'r', 0, 'd', 0, ' ', 0, \ + 'T', 0, 'e', 0, 's', 0, 't', 0, ' ', 0, \ + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, ' ', 0, + +#define STRING_KEYBOARD \ + 'K', 0, 'e', 0, 'y', 0, 'b', 0, 'o', 0, 'a', 0, 'r', 0, 'd', 0, ' ', 0, \ + 'i', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, + +/* make the real string descriptors */ + +USB_MAKE_STRING_DESC(STRING_LANG, string_lang); +USB_MAKE_STRING_DESC(STRING_KEYBOARD, string_keyboard); +USB_MAKE_STRING_DESC(STRING_PRODUCT, string_product); + +/* prototypes */ + +static const struct usb_temp_packet_size keyboard_intr_mps = { + .mps[USB_SPEED_LOW] = 16, + .mps[USB_SPEED_FULL] = 16, + .mps[USB_SPEED_HIGH] = 16, +}; + +static const struct usb_temp_interval keyboard_intr_interval = { + .bInterval[USB_SPEED_LOW] = 2, /* ms */ + .bInterval[USB_SPEED_FULL] = 2, + .bInterval[USB_SPEED_HIGH] = 2 * 8, +}; + +static uint8_t keyboard_hid_descriptor[] = { + 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, + 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25, 0x01, + 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, + 0x75, 0x08, 0x81, 0x01, 0x95, 0x03, 0x75, 0x01, + 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x91, 0x02, + 0x95, 0x05, 0x75, 0x01, 0x91, 0x01, 0x95, 0x06, + 0x75, 0x08, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, + 0x07, 0x19, 0x00, 0x2a, 0xff, 0x00, 0x81, 0x00, + 0xc0 +}; + +static const struct usb_temp_endpoint_desc keyboard_ep_0 = { + .ppRawDesc = NULL, /* no raw descriptors */ + .pPacketSize = &keyboard_intr_mps, + .pIntervals = &keyboard_intr_interval, + .bEndpointAddress = UE_DIR_IN, + .bmAttributes = UE_INTERRUPT, +}; + +static const struct usb_temp_endpoint_desc *keyboard_endpoints[] = { + &keyboard_ep_0, + NULL, +}; + +static const uint8_t keyboard_raw_desc[] = { + 0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, sizeof(keyboard_hid_descriptor), + 0x00 +}; + +static const void *keyboard_iface_0_desc[] = { + keyboard_raw_desc, + NULL, +}; + +static const struct usb_temp_interface_desc keyboard_iface_0 = { + .ppRawDesc = keyboard_iface_0_desc, + .ppEndpoints = keyboard_endpoints, + .bInterfaceClass = 3, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 1, + .iInterface = INDEX_KEYBOARD, +}; + +static const struct usb_temp_interface_desc *keyboard_interfaces[] = { + &keyboard_iface_0, + NULL, +}; + +static const struct usb_temp_config_desc keyboard_config_desc = { + .ppIfaceDesc = keyboard_interfaces, + .bmAttributes = UC_BUS_POWERED, + .bMaxPower = 25, /* 50 mA */ + .iConfiguration = INDEX_PRODUCT, +}; + +static const struct usb_temp_config_desc *keyboard_configs[] = { + &keyboard_config_desc, + NULL, +}; + +static usb_temp_get_string_desc_t keyboard_get_string_desc; +static usb_temp_get_vendor_desc_t keyboard_get_vendor_desc; + +const struct usb_temp_device_desc usb_template_kbd = { + .getStringDesc = &keyboard_get_string_desc, + .getVendorDesc = &keyboard_get_vendor_desc, + .ppConfigDesc = keyboard_configs, + .idVendor = USB_TEMPLATE_VENDOR, + .idProduct = 0x00CB, + .bcdDevice = 0x0100, + .bDeviceClass = UDCLASS_COMM, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .iManufacturer = 0, + .iProduct = INDEX_PRODUCT, + .iSerialNumber = 0, +}; + +/*------------------------------------------------------------------------* + * keyboard_get_vendor_desc + * + * Return values: + * NULL: Failure. No such vendor descriptor. + * Else: Success. Pointer to vendor descriptor is returned. + *------------------------------------------------------------------------*/ +static const void * +keyboard_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen) +{ + if ((req->bmRequestType == 0x81) && (req->bRequest == 0x06) && + (req->wValue[0] == 0x00) && (req->wValue[1] == 0x22) && + (req->wIndex[1] == 0) && (req->wIndex[0] == 0)) { + + *plen = sizeof(keyboard_hid_descriptor); + return (keyboard_hid_descriptor); + } + return (NULL); +} + +/*------------------------------------------------------------------------* + * keyboard_get_string_desc + * + * Return values: + * NULL: Failure. No such string. + * Else: Success. Pointer to string descriptor is returned. + *------------------------------------------------------------------------*/ +static const void * +keyboard_get_string_desc(uint16_t lang_id, uint8_t string_index) +{ + static const void *ptr[INDEX_MAX] = { + [INDEX_LANG] = &string_lang, + [INDEX_KEYBOARD] = &string_keyboard, + [INDEX_PRODUCT] = &string_product, + }; + + if (string_index == 0) { + return (&string_lang); + } + if (lang_id != 0x0409) { + return (NULL); + } + if (string_index < INDEX_MAX) { + return (ptr[string_index]); + } + return (NULL); +} diff --git a/sys/dev/usb/template/usb_template_modem.c b/sys/dev/usb/template/usb_template_modem.c new file mode 100644 index 000000000000..6e0f940ebded --- /dev/null +++ b/sys/dev/usb/template/usb_template_modem.c @@ -0,0 +1,252 @@ +#include +__FBSDID("$FreeBSD$"); + +/*- + * Copyright (c) 2010 Hans Petter Selasky. 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 file contains the USB template for an USB Modem Device. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +enum { + INDEX_LANG, + INDEX_MODEM, + INDEX_PRODUCT, + INDEX_MAX, +}; + +#define STRING_LANG \ + 0x09, 0x04, /* American English */ + +#define STRING_PRODUCT \ + 'M', 0, 'o', 0, 'd', 0, 'e', 0, 'm', 0, ' ', 0, \ + 'T', 0, 'e', 0, 's', 0, 't', 0, ' ', 0, \ + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, ' ', 0, + +#define STRING_MODEM \ + 'M', 0, 'o', 0, 'd', 0, 'e', 0, 'm', 0, ' ', 0, \ + 'i', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, + +/* make the real string descriptors */ + +USB_MAKE_STRING_DESC(STRING_LANG, string_lang); +USB_MAKE_STRING_DESC(STRING_MODEM, string_modem); +USB_MAKE_STRING_DESC(STRING_PRODUCT, string_product); + +#define MODEM_IFACE_0 0 +#define MODEM_IFACE_1 1 + +/* prototypes */ + +static const struct usb_temp_packet_size modem_bulk_mps = { + .mps[USB_SPEED_LOW] = 8, + .mps[USB_SPEED_FULL] = 64, + .mps[USB_SPEED_HIGH] = 512, +}; + +static const struct usb_temp_packet_size modem_intr_mps = { + .mps[USB_SPEED_LOW] = 8, + .mps[USB_SPEED_FULL] = 8, + .mps[USB_SPEED_HIGH] = 8, +}; + +static const struct usb_temp_interval modem_intr_interval = { + .bInterval[USB_SPEED_LOW] = 10, + .bInterval[USB_SPEED_FULL] = 10, + .bInterval[USB_SPEED_HIGH] = 10 * 8, +}; + +static const struct usb_temp_endpoint_desc modem_ep_0 = { + .pPacketSize = &modem_intr_mps, + .pIntervals = &modem_intr_interval, + .bEndpointAddress = UE_DIR_IN, + .bmAttributes = UE_INTERRUPT, +}; + +static const struct usb_temp_endpoint_desc modem_ep_1 = { + .pPacketSize = &modem_bulk_mps, + .bEndpointAddress = UE_DIR_OUT, + .bmAttributes = UE_BULK, +}; + +static const struct usb_temp_endpoint_desc modem_ep_2 = { + .pPacketSize = &modem_bulk_mps, + .bEndpointAddress = UE_DIR_IN, + .bmAttributes = UE_BULK, +}; + +static const struct usb_temp_endpoint_desc *modem_iface_0_ep[] = { + &modem_ep_0, + NULL, +}; + +static const struct usb_temp_endpoint_desc *modem_iface_1_ep[] = { + &modem_ep_1, + &modem_ep_2, + NULL, +}; + +static const uint8_t modem_raw_desc_0[] = { + 0x05, 0x24, 0x00, 0x10, 0x01 +}; + +static const uint8_t modem_raw_desc_1[] = { + 0x05, 0x24, 0x06, MODEM_IFACE_0, MODEM_IFACE_1 +}; + +static const uint8_t modem_raw_desc_2[] = { + 0x05, 0x24, 0x01, 0x03, MODEM_IFACE_1 +}; + +static const uint8_t modem_raw_desc_3[] = { + 0x04, 0x24, 0x02, 0x07 +}; + +static const void *modem_iface_0_desc[] = { + &modem_raw_desc_0, + &modem_raw_desc_1, + &modem_raw_desc_2, + &modem_raw_desc_3, + NULL, +}; + +static const struct usb_temp_interface_desc modem_iface_0 = { + .ppRawDesc = modem_iface_0_desc, + .ppEndpoints = modem_iface_0_ep, + .bInterfaceClass = 2, + .bInterfaceSubClass = 2, + .bInterfaceProtocol = 1, + .iInterface = INDEX_MODEM, +}; + +static const struct usb_temp_interface_desc modem_iface_1 = { + .ppEndpoints = modem_iface_1_ep, + .bInterfaceClass = 10, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = INDEX_MODEM, +}; + +static const struct usb_temp_interface_desc *modem_interfaces[] = { + &modem_iface_0, + &modem_iface_1, + NULL, +}; + +static const struct usb_temp_config_desc modem_config_desc = { + .ppIfaceDesc = modem_interfaces, + .bmAttributes = UC_BUS_POWERED, + .bMaxPower = 25, /* 50 mA */ + .iConfiguration = INDEX_PRODUCT, +}; + +static const struct usb_temp_config_desc *modem_configs[] = { + &modem_config_desc, + NULL, +}; + +static usb_temp_get_string_desc_t modem_get_string_desc; +static usb_temp_get_vendor_desc_t modem_get_vendor_desc; + +const struct usb_temp_device_desc usb_template_modem = { + .getStringDesc = &modem_get_string_desc, + .getVendorDesc = &modem_get_vendor_desc, + .ppConfigDesc = modem_configs, + .idVendor = USB_TEMPLATE_VENDOR, + .idProduct = 0x000E, + .bcdDevice = 0x0100, + .bDeviceClass = UDCLASS_COMM, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .iManufacturer = 0, + .iProduct = INDEX_PRODUCT, + .iSerialNumber = 0, +}; + +/*------------------------------------------------------------------------* + * modem_get_vendor_desc + * + * Return values: + * NULL: Failure. No such vendor descriptor. + * Else: Success. Pointer to vendor descriptor is returned. + *------------------------------------------------------------------------*/ +static const void * +modem_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen) +{ + return (NULL); +} + +/*------------------------------------------------------------------------* + * modem_get_string_desc + * + * Return values: + * NULL: Failure. No such string. + * Else: Success. Pointer to string descriptor is returned. + *------------------------------------------------------------------------*/ +static const void * +modem_get_string_desc(uint16_t lang_id, uint8_t string_index) +{ + static const void *ptr[INDEX_MAX] = { + [INDEX_LANG] = &string_lang, + [INDEX_MODEM] = &string_modem, + [INDEX_PRODUCT] = &string_product, + }; + + if (string_index == 0) { + return (&string_lang); + } + if (lang_id != 0x0409) { + return (NULL); + } + if (string_index < INDEX_MAX) { + return (ptr[string_index]); + } + return (NULL); +} diff --git a/sys/dev/usb/template/usb_template_mouse.c b/sys/dev/usb/template/usb_template_mouse.c new file mode 100644 index 000000000000..b0f5381e5a32 --- /dev/null +++ b/sys/dev/usb/template/usb_template_mouse.c @@ -0,0 +1,220 @@ +#include +__FBSDID("$FreeBSD$"); + +/*- + * Copyright (c) 2010 Hans Petter Selasky. 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 file contains the USB template for an USB Mouse Device. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +enum { + INDEX_LANG, + INDEX_MOUSE, + INDEX_PRODUCT, + INDEX_MAX, +}; + +#define STRING_LANG \ + 0x09, 0x04, /* American English */ + +#define STRING_PRODUCT \ + 'M', 0, 'o', 0, 'u', 0, 's', 0, 'e', 0, ' ', 0, \ + 'T', 0, 'e', 0, 's', 0, 't', 0, ' ', 0, \ + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, + +#define STRING_MOUSE \ + 'M', 0, 'o', 0, 'u', 0, 's', 0, 'e', 0, ' ', 0, \ + 'i', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0, + +/* make the real string descriptors */ + +USB_MAKE_STRING_DESC(STRING_LANG, string_lang); +USB_MAKE_STRING_DESC(STRING_MOUSE, string_mouse); +USB_MAKE_STRING_DESC(STRING_PRODUCT, string_product); + +/* prototypes */ + +static uint8_t mouse_hid_descriptor[] = { + 0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, + 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, + 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, + 0x81, 0x02, 0x95, 0x05, 0x81, 0x03, 0x05, 0x01, + 0x09, 0x30, 0x09, 0x31, 0x09, 0x38, 0x15, 0x81, + 0x25, 0x7f, 0x75, 0x08, 0x95, 0x03, 0x81, 0x06, + 0xc0, 0xc0 +}; + +static const struct usb_temp_packet_size mouse_intr_mps = { + .mps[USB_SPEED_LOW] = 8, + .mps[USB_SPEED_FULL] = 8, + .mps[USB_SPEED_HIGH] = 8, +}; + +static const struct usb_temp_interval mouse_intr_interval = { + .bInterval[USB_SPEED_LOW] = 2, + .bInterval[USB_SPEED_FULL] = 2, + .bInterval[USB_SPEED_HIGH] = 2 * 8, +}; + +static const struct usb_temp_endpoint_desc mouse_ep_0 = { + .ppRawDesc = NULL, /* no raw descriptors */ + .pPacketSize = &mouse_intr_mps, + .pIntervals = &mouse_intr_interval, + .bEndpointAddress = UE_DIR_IN, + .bmAttributes = UE_INTERRUPT, +}; + +static const struct usb_temp_endpoint_desc *mouse_endpoints[] = { + &mouse_ep_0, + NULL, +}; + +static const uint8_t mouse_raw_desc[] = { + 0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, sizeof(mouse_hid_descriptor), + 0x00 +}; + +static const void *mouse_iface_0_desc[] = { + mouse_raw_desc, + NULL, +}; + +static const struct usb_temp_interface_desc mouse_iface_0 = { + .ppRawDesc = mouse_iface_0_desc, + .ppEndpoints = mouse_endpoints, + .bInterfaceClass = 3, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 2, + .iInterface = INDEX_MOUSE, +}; + +static const struct usb_temp_interface_desc *mouse_interfaces[] = { + &mouse_iface_0, + NULL, +}; + +static const struct usb_temp_config_desc mouse_config_desc = { + .ppIfaceDesc = mouse_interfaces, + .bmAttributes = UC_BUS_POWERED, + .bMaxPower = 25, /* 50 mA */ + .iConfiguration = INDEX_PRODUCT, +}; + +static const struct usb_temp_config_desc *mouse_configs[] = { + &mouse_config_desc, + NULL, +}; + +static usb_temp_get_string_desc_t mouse_get_string_desc; +static usb_temp_get_vendor_desc_t mouse_get_vendor_desc; + +const struct usb_temp_device_desc usb_template_mouse = { + .getStringDesc = &mouse_get_string_desc, + .getVendorDesc = &mouse_get_vendor_desc, + .ppConfigDesc = mouse_configs, + .idVendor = USB_TEMPLATE_VENDOR, + .idProduct = 0x00AE, + .bcdDevice = 0x0100, + .bDeviceClass = UDCLASS_COMM, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .iManufacturer = 0, + .iProduct = INDEX_PRODUCT, + .iSerialNumber = 0, +}; + +/*------------------------------------------------------------------------* + * mouse_get_vendor_desc + * + * Return values: + * NULL: Failure. No such vendor descriptor. + * Else: Success. Pointer to vendor descriptor is returned. + *------------------------------------------------------------------------*/ +static const void * +mouse_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen) +{ + if ((req->bmRequestType == 0x81) && (req->bRequest == 0x06) && + (req->wValue[0] == 0x00) && (req->wValue[1] == 0x22) && + (req->wIndex[1] == 0) && (req->wIndex[0] == 0)) { + + *plen = sizeof(mouse_hid_descriptor); + return (mouse_hid_descriptor); + } + return (NULL); +} + +/*------------------------------------------------------------------------* + * mouse_get_string_desc + * + * Return values: + * NULL: Failure. No such string. + * Else: Success. Pointer to string descriptor is returned. + *------------------------------------------------------------------------*/ +static const void * +mouse_get_string_desc(uint16_t lang_id, uint8_t string_index) +{ + static const void *ptr[INDEX_MAX] = { + [INDEX_LANG] = &string_lang, + [INDEX_MOUSE] = &string_mouse, + [INDEX_PRODUCT] = &string_product, + }; + + if (string_index == 0) { + return (&string_lang); + } + if (lang_id != 0x0409) { + return (NULL); + } + if (string_index < INDEX_MAX) { + return (ptr[string_index]); + } + return (NULL); +} diff --git a/sys/dev/usb/template/usb_template_msc.c b/sys/dev/usb/template/usb_template_msc.c index 598c9fde1843..5c05ffe8e289 100644 --- a/sys/dev/usb/template/usb_template_msc.c +++ b/sys/dev/usb/template/usb_template_msc.c @@ -173,8 +173,8 @@ static const struct usb_temp_config_desc *msc_configs[] = { const struct usb_temp_device_desc usb_template_msc = { .getStringDesc = &msc_get_string_desc, .ppConfigDesc = msc_configs, - .idVendor = 0x0001, - .idProduct = 0x0001, + .idVendor = USB_TEMPLATE_VENDOR, + .idProduct = 0x0012, .bcdDevice = 0x0100, .bDeviceClass = UDCLASS_COMM, .bDeviceSubClass = 0, diff --git a/sys/dev/usb/template/usb_template_mtp.c b/sys/dev/usb/template/usb_template_mtp.c index ad09b58551df..f48fbf422b8e 100644 --- a/sys/dev/usb/template/usb_template_mtp.c +++ b/sys/dev/usb/template/usb_template_mtp.c @@ -191,8 +191,8 @@ const struct usb_temp_device_desc usb_template_mtp = { .getStringDesc = &mtp_get_string_desc, .getVendorDesc = &mtp_get_vendor_desc, .ppConfigDesc = mtp_configs, - .idVendor = 0x0001, - .idProduct = 0x0001, + .idVendor = USB_TEMPLATE_VENDOR, + .idProduct = 0x0011, .bcdDevice = 0x0100, .bDeviceClass = 0, .bDeviceSubClass = 0, diff --git a/sys/dev/usb/usb_ioctl.h b/sys/dev/usb/usb_ioctl.h index 452de94a7ab4..d35fa1038e5a 100644 --- a/sys/dev/usb/usb_ioctl.h +++ b/sys/dev/usb/usb_ioctl.h @@ -39,6 +39,20 @@ #define USB_DEVICE_NAME "usbctl" #define USB_DEVICE_DIR "usb" #define USB_GENERIC_NAME "ugen" +#define USB_TEMPLATE_SYSCTL "hw.usb.template" /* integer type */ + +/* Definition of valid template sysctl values */ + +enum { + USB_TEMP_MSC, /* USB Mass Storage */ + USB_TEMP_CDCE, /* USB CDC Ethernet */ + USB_TEMP_MTP, /* Message Transfer Protocol */ + USB_TEMP_MODEM, /* USB CDC Modem */ + USB_TEMP_AUDIO, /* USB Audio */ + USB_TEMP_KBD, /* USB Keyboard */ + USB_TEMP_MOUSE, /* USB Mouse */ + USB_TEMP_MAX, +}; struct usb_read_dir { #ifdef COMPAT_32BIT diff --git a/sys/modules/usb/template/Makefile b/sys/modules/usb/template/Makefile index 362da9d54f43..e67303e75022 100644 --- a/sys/modules/usb/template/Makefile +++ b/sys/modules/usb/template/Makefile @@ -31,6 +31,13 @@ S= ${.CURDIR}/../../.. KMOD= usb_template SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h vnode_if.h usbdevs.h \ - usb_template.c usb_template_cdce.c usb_template_msc.c usb_template_mtp.c + usb_template.c \ + usb_template_audio.c \ + usb_template_cdce.c \ + usb_template_kbd.c \ + usb_template_modem.c \ + usb_template_mouse.c \ + usb_template_msc.c \ + usb_template_mtp.c .include From cd5bdbcb4dd1ffb2db454600eb705601890de711 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Thu, 23 Jun 2011 09:42:41 +0000 Subject: [PATCH 26/57] Be consistent with r160968: keep autoSrcAddr flag untouched when node receives NGM_SHUTDOWN. Submitted by: pluknet --- sys/netgraph/ng_ether.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index 5abc5aaebcba..b51d04825e9a 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -718,7 +718,6 @@ ng_ether_shutdown(node_p node) (void)ifpromisc(priv->ifp, 0); priv->promisc = 0; } - priv->autoSrcAddr = 1; /* reset auto-src-addr flag */ NG_NODE_REVIVE(node); /* Signal ng_rmnode we are persisant */ return (0); From f7688a4194f84b7ca0fd956a86a325b0a2d84784 Mon Sep 17 00:00:00 2001 From: Andreas Tobler Date: Thu, 23 Jun 2011 09:43:53 +0000 Subject: [PATCH 27/57] Add leading zeros when printing the stackframe on __powerpc64__. --- sys/powerpc/powerpc/db_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/powerpc/powerpc/db_trace.c b/sys/powerpc/powerpc/db_trace.c index f78378107bee..20de0ec4b90e 100644 --- a/sys/powerpc/powerpc/db_trace.c +++ b/sys/powerpc/powerpc/db_trace.c @@ -200,7 +200,7 @@ db_backtrace(struct thread *td, db_addr_t fp, int count) } #ifdef __powerpc64__ - db_printf("0x%16lx: ", stackframe); + db_printf("0x%016lx: ", stackframe); #else db_printf("0x%08x: ", stackframe); #endif From dcf496e844a6a5d58fb8685cb2509b996983f94d Mon Sep 17 00:00:00 2001 From: Andreas Tobler Date: Thu, 23 Jun 2011 09:46:12 +0000 Subject: [PATCH 28/57] Fix merge typo. --- sys/powerpc/aim/mmu_oea64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 291d89b3e760..8f4028f82a6b 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -1715,7 +1715,7 @@ moea64_kextract(mmu_t mmu, vm_offset_t va) pvo = moea64_pvo_find_va(kernel_pmap, va); KASSERT(pvo != NULL, ("moea64_kextract: no addr found for %#" PRIxPTR, va)); - pa = (pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) + (va - PVO_VADDR(pvo)); + pa = (pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) | (va - PVO_VADDR(pvo)); PMAP_UNLOCK(kernel_pmap); return (pa); } From df142785d5c32191c735e34b09962642d1ee81ac Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Thu, 23 Jun 2011 10:35:45 +0000 Subject: [PATCH 29/57] - Add some comments about the origin of some USB descriptors. MFC after: 7 days --- sys/dev/usb/template/usb_template_audio.c | 7 ++++++- sys/dev/usb/template/usb_template_kbd.c | 2 ++ sys/dev/usb/template/usb_template_mouse.c | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/template/usb_template_audio.c b/sys/dev/usb/template/usb_template_audio.c index 1e2e56869dcb..8e9e7f066457 100644 --- a/sys/dev/usb/template/usb_template_audio.c +++ b/sys/dev/usb/template/usb_template_audio.c @@ -95,7 +95,12 @@ USB_MAKE_STRING_DESC(STRING_AUDIO_PRODUCT, string_audio_product); /* prototypes */ -/* Audio Mixer description structures */ +/* + * Audio Mixer description structures + * + * Some of the audio descriptors were dumped + * from a Creative Labs USB audio device. + */ static const uint8_t audio_raw_desc_0[] = { 0x0a, 0x24, 0x01, 0x00, 0x01, 0xa9, 0x00, 0x02, diff --git a/sys/dev/usb/template/usb_template_kbd.c b/sys/dev/usb/template/usb_template_kbd.c index 4a9b9dae11b3..8928c0665e22 100644 --- a/sys/dev/usb/template/usb_template_kbd.c +++ b/sys/dev/usb/template/usb_template_kbd.c @@ -94,6 +94,8 @@ static const struct usb_temp_interval keyboard_intr_interval = { .bInterval[USB_SPEED_HIGH] = 2 * 8, }; +/* The following HID descriptor was dumped from a HP keyboard. */ + static uint8_t keyboard_hid_descriptor[] = { 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25, 0x01, diff --git a/sys/dev/usb/template/usb_template_mouse.c b/sys/dev/usb/template/usb_template_mouse.c index b0f5381e5a32..3ff0fb0188b1 100644 --- a/sys/dev/usb/template/usb_template_mouse.c +++ b/sys/dev/usb/template/usb_template_mouse.c @@ -82,6 +82,8 @@ USB_MAKE_STRING_DESC(STRING_PRODUCT, string_product); /* prototypes */ +/* The following HID descriptor was dumped from a HP mouse. */ + static uint8_t mouse_hid_descriptor[] = { 0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, From 79ddde082ac7c0c6882f531df4959123b2242f06 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Thu, 23 Jun 2011 10:43:36 +0000 Subject: [PATCH 30/57] Document that autoSrcAddr isn't re-enabled on NGM_SHUTDOWN. Submitted by: Vadim Goncharov --- share/man/man4/ng_ether.4 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/share/man/man4/ng_ether.4 b/share/man/man4/ng_ether.4 index 9fd409db00ed..6ca5c11bbbf6 100644 --- a/share/man/man4/ng_ether.4 +++ b/share/man/man4/ng_ether.4 @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 4, 2006 +.Dd June 23, 2011 .Dt NG_ETHER 4 .Os .Sh NAME @@ -183,7 +183,6 @@ Detach from underlying Ethernet interface and shut down node. Upon receipt of the .Dv NGM_SHUTDOWN control message, all hooks are disconnected, promiscuous mode is disabled, -and the source address override flag is re-enabled, but the node is not removed. Node can be shut down only using .Dv NGM_ETHER_DETACH From dc6ebb1bca9131a41d288b1356deee82fa772856 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Thu, 23 Jun 2011 12:11:43 +0000 Subject: [PATCH 31/57] add missing #define for the non-debug case. --- sys/dev/ath/ath_hal/ah_internal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index 0959218b39da..2bb163fefe08 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -529,6 +529,7 @@ extern void DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...) __printflike(3,4); #else #define HALDEBUG(_ah, __m, _fmt, ...) +#define HALDEBUG_G(_ah, __m, _fmt, ...) #endif /* AH_DEBUG */ /* From ee2b236b9815852a2cbf247bd484b6a16017dd38 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 23 Jun 2011 15:10:44 +0000 Subject: [PATCH 32/57] Fix ATAPI breakage introduced by r223443. It made SCSI commands to ATAPI device to never complete, that caused probe process (system boot) stuck. --- sys/cam/ata/ata_xpt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index 216805d0c6bb..84ab46b52f1a 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -1678,7 +1678,8 @@ ata_action(union ccb *start_ccb) xpt_done(start_ccb); break; } - /* FALLTHROUGH */ + xpt_action_default(start_ccb); + break; } case XPT_DEV_ADVINFO: { From e1b4a23921b41f8d17abee86381675485498b9f8 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 23 Jun 2011 15:53:17 +0000 Subject: [PATCH 33/57] The recent change to increase the zfsboot size to 64k made a few BIOSes unhappy (probably they don't handle crossing the 64k boundary, etc.). Fix this by changing zfsldr to use a loop reading from the disk one sector at a time. To avoid trashing the saved copy of the MBR which is used for disk I/O, read zfsboot2 at address 0x9000. This has the advantage that BTX no longer needs to be relocated as it is read into the correct location. However, the loop to relocate zfsboot2.bin can now cross a 64k boundary, so change it to use relative segments instead. (This will need further work if zfsboot2.bin ever exceeds 64k.) While here, stop storing a relocated copy of zfsldr at 0x700. This was only used by the xread hack which has recently been removed (and even that use was dubious). Also, include the BIOS error code as hex when reporting read errors to aid in debugging. Much thanks to Henri Hennebert for patiently testing various iterations of the patch as well as fixing the zfsboot2.bin relocation to use relative segments. MFC after: 1 week --- sys/boot/i386/zfsboot/zfsldr.S | 125 +++++++++++++++++---------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/sys/boot/i386/zfsboot/zfsldr.S b/sys/boot/i386/zfsboot/zfsldr.S index 182d88e11e47..471a0429caa7 100644 --- a/sys/boot/i386/zfsboot/zfsldr.S +++ b/sys/boot/i386/zfsboot/zfsldr.S @@ -16,7 +16,6 @@ */ /* Memory Locations */ - .set MEM_REL,0x700 # Relocation address .set MEM_ARG,0x900 # Arguments .set MEM_ORG,0x7c00 # Origin .set MEM_BUF,0x8000 # Load area @@ -90,15 +89,6 @@ main: cld # String ops inc mov %cx,%ds # data mov %cx,%ss # Set up mov $start,%sp # stack -/* - * Relocate ourself to MEM_REL. Since %cx == 0, the inc %ch sets - * %cx == 0x100. - */ - mov %sp,%si # Source - mov $MEM_REL,%di # Destination - incb %ch # Word count - rep # Copy - movsw # code /* * If we are on a hard drive, then load the MBR and look for the first * FreeBSD slice. We use the fake partition entry below that points to @@ -106,11 +96,12 @@ main: cld # String ops inc * FreeBSD slice. The second pass looks for the first non-active FreeBSD * slice if the first one fails. */ - mov $part4,%si # Partition + mov $part4,%si # Dummy partition cmpb $0x80,%dl # Hard drive? jb main.4 # No - movb $0x1,%dh # Block count - callw nread # Read MBR + xor %eax,%eax # Read MBR + movl $MEM_BUF,%ebx # from first + callw nread # sector mov $0x1,%cx # Two passes main.1: mov $MEM_BUF+PRT_OFF,%si # Partition table movb $0x1,%dh # Partition @@ -139,52 +130,51 @@ main.4: xor %dx,%dx # Partition:drive /* * Ok, we have a slice and drive in %dx now, so use that to locate and * load boot2. %si references the start of the slice we are looking - * for, so go ahead and load up the 64 sectors starting at sector 1024 + * for, so go ahead and load up the 128 sectors starting at sector 1024 * (i.e. after the two vdev labels). We don't have do anything fancy * here to allow for an extra copy of boot1 and a partition table * (compare to this section of the UFS bootstrap) so we just load it - * all at 0x8000. The first part of boot2 is BTX, which wants to run + * all at 0x9000. The first part of boot2 is BTX, which wants to run * at 0x9000. The boot2.bin binary starts right after the end of BTX, * so we have to figure out where the start of it is and then move the - * binary to 0xc000. After we have moved the client, we relocate BTX - * itself to 0x9000 - doing it in this order means that none of the - * memcpy regions overlap which would corrupt the copy. Normally, BTX - * clients start at MEM_USR, or 0xa000, but when we use btxld to - * create zfsboot2, we use an entry point of 0x2000. That entry point is - * relative to MEM_USR; thus boot2.bin starts at 0xc000. + * binary to 0xc000. Normally, BTX clients start at MEM_USR, or 0xa000, + * but when we use btxld to create zfsboot2, we use an entry point of + * 0x2000. That entry point is relative to MEM_USR; thus boot2.bin + * starts at 0xc000. * * The load area and the target area for the client overlap so we have * to use a decrementing string move. We also play segment register * games with the destination address for the move so that the client * can be larger than 16k (which would overflow the zero segment since - * the client starts at 0xc000). Relocating BTX is easy since the load - * area and target area do not overlap. + * the client starts at 0xc000). */ main.5: mov %dx,MEM_ARG # Save args - movb $NSECT,%dh # Sector count + mov $NSECT,%cx # Sector count movl $1024,%eax # Offset to boot2 - callw nread.1 # Read disk -main.6: mov $MEM_BUF,%si # BTX (before reloc) - mov 0xa(%si),%bx # Get BTX length and set + mov $MEM_BTX,%ebx # Destination buffer +main.6: pushal # Save params + callw nread # Read disk + popal # Restore + incl %eax # Advance to + add $SIZ_SEC,%ebx # next sector + loop main.6 # If not last, read another + mov MEM_BTX+0xa,%bx # Get BTX length mov $NSECT*SIZ_SEC-1,%di # Size of load area (less one) - mov %di,%si # End of load - add $MEM_BUF,%si # area + mov %di,%si # End of load area, 0x9000 rel sub %bx,%di # End of client, 0xc000 rel mov %di,%cx # Size of inc %cx # client + mov $(MEM_BTX)>>4,%dx # Segment + mov %dx,%ds # addressing 0x9000 mov $(MEM_USR+2*SIZ_PAG)>>4,%dx # Segment mov %dx,%es # addressing 0xc000 std # Move with decrement rep # Relocate movsb # client - mov %ds,%dx # Back to - mov %dx,%es # zero segment - mov $MEM_BUF,%si # BTX (before reloc) - mov $MEM_BTX,%di # BTX - mov %bx,%cx # Get BTX length - cld # Increment this time - rep # Relocate - movsb # BTX + cld # Back to increment + xor %dx,%dx # Back + mov %ds,%dx # to zero + mov %dx,%es # segment /* * Enable A20 so we can access memory above 1 meg. @@ -211,32 +201,35 @@ seta20.3: sti # Enable interrupts /* * Trampoline used to call read from within zfsldr. Sets up an EDD - * packet on the stack and passes it to read. + * packet on the stack and passes it to read. We assume that the + * destination address is always segment-aligned. * * %eax - int - LBA to read in relative to partition start + * %ebx - ptr - destination address * %dl - byte - drive to read from - * %dh - byte - num sectors to read * %si - ptr - MBR partition entry */ -nread: xor %eax,%eax # Sector offset in partition -nread.1: xor %ecx,%ecx # Get +nread: xor %ecx,%ecx # Get addl 0x8(%si),%eax # LBA adc $0,%ecx pushl %ecx # Starting absolute block pushl %eax # block number - push %es # Address of - push $MEM_BUF # transfer buffer - xor %ax,%ax # Number of - movb %dh,%al # blocks to - push %ax # transfer + shr $4,%ebx # Convert to segment + push %bx # Address of + push $0 # transfer buffer + push $0x1 # Read 1 sector push $0x10 # Size of packet mov %sp,%bp # Packet pointer callw read # Read from disk + jc nread.1 # If error, fail lea 0x10(%bp),%sp # Clear stack - jnc return # If success, return - mov $msg_read,%si # Otherwise, set the error - # message and fall through to - # the error routine + ret # If success, return +nread.1: mov %ah,%al # Format + mov $read_err,%di # error + call hex8 # code + mov $msg_read,%si # Set the error message and + # fall through to the error + # routine /* * Print out the error message pointed to by %ds:(%si) followed * by a prompt, wait for a keypress, and then reboot the machine. @@ -258,14 +251,6 @@ putstr: lodsb # Get char testb %al,%al # End of string? jne putstr.0 # No -/* - * Overused return code. ereturn is used to return an error from the - * read function. Since we assume putstr succeeds, we (ab)use the - * same code when we return from putstr. - */ -ereturn: movb $0x1,%ah # Invalid - stc # argument -return: retw # To caller /* * Reads sectors from the disk. If EDD is enabled, then check if it is * installed and use it if it is. If it is not installed or not enabled, then @@ -294,14 +279,30 @@ read: cmpb $0x80,%dl # Hard drive? retw # To caller read.1: mov $msg_chs,%si jmp error -msg_chs: .asciz "CHS not supported" + +/* + * AL to hex, saving the result to [EDI]. + */ +hex8: push %ax # Save + shrb $0x4,%al # Do upper + call hex8.1 # 4 + pop %ax # Restore +hex8.1: andb $0xf,%al # Get lower 4 + cmpb $0xa,%al # Convert + sbbb $0x69,%al # to hex + das # digit + orb $0x20,%al # To lower case + stosb # Save char + ret # (Recursive) /* Messages */ -msg_read: .asciz "Read" -msg_part: .asciz "Boot" +msg_chs: .asciz "CHS not supported" +msg_read: .ascii "Read error: " +read_err: .asciz "XX" +msg_part: .asciz "Boot error" -prompt: .asciz " error\r\n" +prompt: .asciz "\r\n" .org PRT_OFF,0x90 From ded49c2eaeb1bd5e70ea4e1e35899b4937c3d4d5 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 23 Jun 2011 16:21:43 +0000 Subject: [PATCH 34/57] Unblock the outgoing thread after we performed pmap_switch() to switch the region registers. pmap_switch() returns the pmap for which the region register are currently programmed, which needs to be re-programmed on the CPU the ougoing thread gets switched in. This change does not noticibly change anything or fix known bugs, but does give me a warm fuzzy feeling by being more correct. --- sys/ia64/ia64/machdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index f3105fc93f46..185e13c9893b 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -470,12 +470,12 @@ cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx) if (PCPU_GET(fpcurthread) == old) old->td_frame->tf_special.psr |= IA64_PSR_DFH; if (!savectx(oldpcb)) { - atomic_store_rel_ptr(&old->td_lock, mtx); - newpcb = new->td_pcb; oldpcb->pcb_current_pmap = pmap_switch(newpcb->pcb_current_pmap); + atomic_store_rel_ptr(&old->td_lock, mtx); + #if defined(SCHED_ULE) && defined(SMP) while (atomic_load_acq_ptr(&new->td_lock) == &blocked_lock) cpu_spinwait(); From 045aee08f3a68778c09e36d695a55bb344a3414e Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 23 Jun 2011 16:34:41 +0000 Subject: [PATCH 35/57] Clear any outstanding atomic reservations when traps are taken. This fixes some interesting bugs (mostly on SMP systems) with atomic operations silently failing in interrupt heavy situations, especially when using overflow pages. --- sys/powerpc/aim/trap_subr32.S | 2 ++ sys/powerpc/aim/trap_subr64.S | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S index 7c154a8da387..80329cd0ff63 100644 --- a/sys/powerpc/aim/trap_subr32.S +++ b/sys/powerpc/aim/trap_subr32.S @@ -748,6 +748,8 @@ k_trap: /* Call C interrupt dispatcher: */ trapagain: addi %r3,%r1,8 + addi %r4,%r1,-4 /* Clear any existing reservations */ + stwcx. %r3,0,%r4 bl CNAME(powerpc_interrupt) .globl CNAME(trapexit) /* backtrace code sentinel */ CNAME(trapexit): diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S index 5d4148a55d87..66c543f4e2a0 100644 --- a/sys/powerpc/aim/trap_subr64.S +++ b/sys/powerpc/aim/trap_subr64.S @@ -508,6 +508,8 @@ trapagain: lis %r3,tocbase@ha ld %r2,tocbase@l(%r3) addi %r3,%r1,48 + addi %r4,%r1,-8 /* Clear any existing reservations */ + stdcx. %r3,0,%r4 bl CNAME(powerpc_interrupt) nop From 61cf9896b6bbf034e904555eddab5d483cb2925e Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Thu, 23 Jun 2011 17:42:27 +0000 Subject: [PATCH 36/57] Put back the global for rx processing due to popular demand. --- sys/dev/e1000/if_igb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index 08735ac043e4..a1a14b6bc2e1 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -346,6 +346,10 @@ TUNABLE_INT("hw.igb.hdr_split", &igb_header_split); static int igb_num_queues = 0; TUNABLE_INT("hw.igb.num_queues", &igb_num_queues); +/* How many packets rxeof tries to clean at a time */ +static int igb_rx_process_limit = 100; +TUNABLE_INT("hw.igb.rx_process_limit", &igb_rx_process_limit); + /********************************************************************* * Device identification routine * @@ -465,7 +469,7 @@ igb_attach(device_t dev) /* Sysctl for limiting the amount of work done in the taskqueue */ igb_set_sysctl_value(adapter, "rx_processing_limit", "max number of rx packets to process", - &adapter->rx_process_limit, 100); + &adapter->rx_process_limit, igb_rx_process_limit); /* * Validate number of transmit and receive descriptors. It From 898dec78308899c8f395afd64ac175582beaae52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20Sp=C3=B6rlein?= Date: Thu, 23 Jun 2011 20:31:52 +0000 Subject: [PATCH 37/57] Fix make buildworld -DMODULES_WITH_WORLD Sort opt_ srcs --- sys/modules/cxgbe/if_cxgbe/Makefile | 1 + sys/modules/nfscl/Makefile | 9 +++++---- sys/modules/nfscommon/Makefile | 7 ++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sys/modules/cxgbe/if_cxgbe/Makefile b/sys/modules/cxgbe/if_cxgbe/Makefile index ac1d22c1f095..e4e69e6acb96 100644 --- a/sys/modules/cxgbe/if_cxgbe/Makefile +++ b/sys/modules/cxgbe/if_cxgbe/Makefile @@ -10,6 +10,7 @@ SRCS = t4_main.c t4_sge.c t4_l2t.c SRCS+= t4_hw.c SRCS+= device_if.h bus_if.h pci_if.h SRCS+= opt_inet.h +SRCS+= opt_ofed.h CFLAGS+= -I${CXGBE} diff --git a/sys/modules/nfscl/Makefile b/sys/modules/nfscl/Makefile index 46fa3278d8a0..a9b20038cfeb 100644 --- a/sys/modules/nfscl/Makefile +++ b/sys/modules/nfscl/Makefile @@ -14,13 +14,14 @@ SRCS= vnode_if.h \ nfs_clsubs.c \ nfs_clvfsops.c \ nfs_clvnops.c \ + opt_bootp.h \ opt_inet.h \ opt_inet6.h \ - opt_bootp.h \ - opt_nfsroot.h \ + opt_kdtrace.h \ + opt_kgssapi.h \ opt_nfs.h \ - opt_ufs.h \ - opt_kgssapi.h + opt_nfsroot.h \ + opt_ufs.h .if !defined(KERNBUILDDIR) NFS_INET?= 1 # 0/1 - requires INET to be configured in kernel diff --git a/sys/modules/nfscommon/Makefile b/sys/modules/nfscommon/Makefile index a3d75a72cb2c..2a6b8f775933 100644 --- a/sys/modules/nfscommon/Makefile +++ b/sys/modules/nfscommon/Makefile @@ -7,9 +7,10 @@ SRCS= vnode_if.h \ nfs_commonkrpc.c \ nfs_commonport.c \ nfs_commonsubs.c \ - opt_kgssapi.h \ - opt_ufs.h \ opt_inet6.h \ - opt_nfs.h + opt_kdtrace.h \ + opt_kgssapi.h \ + opt_nfs.h \ + opt_ufs.h .include From 6a4ba2279dcc15976a06bbb485e52b66d6f874a3 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Thu, 23 Jun 2011 20:54:44 +0000 Subject: [PATCH 38/57] Make GNU as recognize the ARM 'rrx' mnemonic, which can be generated by clang for certain expressions. Code taken from Apple cctools (GPLv2). Submitted by: damjan.marion@gmail.com --- contrib/binutils/gas/config/tc-arm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contrib/binutils/gas/config/tc-arm.c b/contrib/binutils/gas/config/tc-arm.c index 683e6ee48e2a..c48a75845aa0 100644 --- a/contrib/binutils/gas/config/tc-arm.c +++ b/contrib/binutils/gas/config/tc-arm.c @@ -9973,6 +9973,13 @@ do_t_rbit (void) inst.instruction |= inst.operands[1].reg << 16; } +static void +do_t_rd_rm (void) +{ + inst.instruction |= inst.operands[0].reg << 8; + inst.instruction |= inst.operands[1].reg; +} + static void do_t_rev (void) { @@ -14901,6 +14908,9 @@ static const struct asm_opcode insns[] = TCE(rsb, 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb), TC3(rsbs, 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb), + TCE(rrx, 1a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rd_rm), + TCE(rrxs, 1b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rd_rm), + #undef THUMB_VARIANT #define THUMB_VARIANT &arm_ext_v6 TCE(cpy, 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy), From e69dff491d4faeddb7bde8ba3d88881574a29c93 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 23 Jun 2011 22:21:28 +0000 Subject: [PATCH 39/57] Use the ABI-mandated thread pointer register (r2 for ppc32, r13 for ppc64) instead of a PCPU field for curthread. This averts a race on SMP systems with a high interrupt rate where the thread looking up the value of curthread could be preempted and migrated between obtaining the PCPU pointer and reading the value of pc_curthread, resulting in curthread being observed to be the current thread on the thread's original CPU. This played merry havoc with the system, in particular with mutexes. Many thanks to jhb for helping me work this one out. Note that Book-E is in principle susceptible to the same problem, but has not been modified yet due to lack of Book-E hardware. MFC after: 2 weeks --- sys/powerpc/aim/copyinout.c | 22 +++++++++++----------- sys/powerpc/aim/locore32.S | 3 +-- sys/powerpc/aim/locore64.S | 3 +-- sys/powerpc/aim/machdep.c | 4 ++-- sys/powerpc/aim/mp_cpudep.c | 2 +- sys/powerpc/aim/swtch32.S | 18 ++++++++---------- sys/powerpc/aim/swtch64.S | 18 ++++++++---------- sys/powerpc/aim/trap.c | 6 +++--- sys/powerpc/aim/trap_subr32.S | 14 ++++++++++---- sys/powerpc/aim/trap_subr64.S | 13 +++++++++---- sys/powerpc/booke/copyinout.c | 16 ++++++++-------- sys/powerpc/booke/interrupt.c | 2 +- sys/powerpc/booke/trap.c | 6 +++--- sys/powerpc/include/pcpu.h | 8 ++++++++ sys/powerpc/ofw/ofwcall32.S | 14 ++++++++------ sys/powerpc/powerpc/mp_machdep.c | 4 ---- 16 files changed, 82 insertions(+), 71 deletions(-) diff --git a/sys/powerpc/aim/copyinout.c b/sys/powerpc/aim/copyinout.c index 359269145441..69ba43152e69 100644 --- a/sys/powerpc/aim/copyinout.c +++ b/sys/powerpc/aim/copyinout.c @@ -142,7 +142,7 @@ copyout(const void *kaddr, void *udaddr, size_t len) char *up, *p; size_t l; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; if (setfault(env)) { @@ -183,7 +183,7 @@ copyin(const void *udaddr, void *kaddr, size_t len) char *kp, *p; size_t l; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; if (setfault(env)) { @@ -225,7 +225,7 @@ copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done) size_t l; int rv, c; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; if (setfault(env)) { @@ -267,7 +267,7 @@ subyte(void *addr, int byte) faultbuf env; char *p; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; p = (char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); @@ -293,7 +293,7 @@ suword32(void *addr, int word) faultbuf env; int *p; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; p = (int *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); @@ -319,7 +319,7 @@ suword(void *addr, long word) faultbuf env; long *p; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); @@ -359,7 +359,7 @@ fubyte(const void *addr) u_char *p; int val; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; p = (u_char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); @@ -385,7 +385,7 @@ fuword32(const void *addr) faultbuf env; int32_t *p, val; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; p = (int32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); @@ -411,7 +411,7 @@ fuword(const void *addr) faultbuf env; long *p, val; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); @@ -444,7 +444,7 @@ casuword32(volatile uint32_t *addr, uint32_t old, uint32_t new) faultbuf env; uint32_t *p, val; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; p = (uint32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); @@ -489,7 +489,7 @@ casuword(volatile u_long *addr, u_long old, u_long new) faultbuf env; u_long *p, val; - td = PCPU_GET(curthread); + td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; p = (u_long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); diff --git a/sys/powerpc/aim/locore32.S b/sys/powerpc/aim/locore32.S index 35ea99bc69c5..d0a377816691 100644 --- a/sys/powerpc/aim/locore32.S +++ b/sys/powerpc/aim/locore32.S @@ -181,8 +181,7 @@ setfault: mflr 0 mfcr 12 mfsprg 4,0 - lwz 4,PC_CURTHREAD(4) - lwz 4,TD_PCB(4) + lwz 4,TD_PCB(2) /* curthread = r2 */ stw 3,PCB_ONFAULT(4) stw 0,0(3) stw 1,4(3) diff --git a/sys/powerpc/aim/locore64.S b/sys/powerpc/aim/locore64.S index c200b4c2a159..5af5e3a53ef2 100644 --- a/sys/powerpc/aim/locore64.S +++ b/sys/powerpc/aim/locore64.S @@ -203,8 +203,7 @@ ASENTRY(setfault) mflr 0 mfcr 12 mfsprg 4,0 - ld 4,PC_CURTHREAD(4) - ld 4,TD_PCB(4) + ld 4,TD_PCB(13) /* curthread = r13 */ std 3,PCB_ONFAULT(4) std 0,0(3) std 1,8(3) diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 3ccae91add59..c368c6856f14 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -303,7 +303,7 @@ powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel, */ pc = __pcpu; pcpu_init(pc, 0, sizeof(struct pcpu)); - pc->pc_curthread = &thread0; + curthread_reg = pc->pc_curthread = &thread0; pc->pc_cpuid = 0; __asm __volatile("mtsprg 0, %0" :: "r"(pc)); @@ -745,7 +745,7 @@ kcopy(const void *src, void *dst, size_t len) faultbuf env, *oldfault; int rv; - td = PCPU_GET(curthread); + td = curthread; oldfault = td->td_pcb->pcb_onfault; if ((rv = setfault(env)) != 0) { td->td_pcb->pcb_onfault = oldfault; diff --git a/sys/powerpc/aim/mp_cpudep.c b/sys/powerpc/aim/mp_cpudep.c index d617fdec564c..68fe517817b6 100644 --- a/sys/powerpc/aim/mp_cpudep.c +++ b/sys/powerpc/aim/mp_cpudep.c @@ -88,7 +88,7 @@ cpudep_ap_bootstrap(void) msr = PSL_KERNSET & ~PSL_EE; mtmsr(msr); - pcpup->pc_curthread = pcpup->pc_idlethread; + curthread_reg = pcpup->pc_curthread = pcpup->pc_idlethread; pcpup->pc_curpcb = pcpup->pc_curthread->td_pcb; sp = pcpup->pc_curpcb->pcb_sp; diff --git a/sys/powerpc/aim/swtch32.S b/sys/powerpc/aim/swtch32.S index cd141aacf6c3..a44b861f9c0d 100644 --- a/sys/powerpc/aim/swtch32.S +++ b/sys/powerpc/aim/swtch32.S @@ -69,7 +69,7 @@ * void cpu_throw(struct thread *old, struct thread *new) */ ENTRY(cpu_throw) - mr %r15, %r4 + mr %r2, %r4 b cpu_switchin /* @@ -89,10 +89,9 @@ ENTRY(cpu_switch) mflr %r16 /* Save the link register */ stw %r16,PCB_LR(%r6) stw %r1,PCB_SP(%r6) /* Save the stack pointer */ - stw %r2,PCB_TOC(%r6) /* Save the TOC pointer */ mr %r14,%r3 /* Copy the old thread ptr... */ - mr %r15,%r4 /* and the new thread ptr in scratch */ + mr %r2,%r4 /* and the new thread ptr in curthread */ mr %r16,%r5 /* and the new lock */ mr %r17,%r6 /* and the PCB */ @@ -122,24 +121,24 @@ cpu_switchin: lis %r6,blocked_lock@ha addi %r6,%r6,blocked_lock@l blocked_loop: - lwz %r7,TD_LOCK(%r15) + lwz %r7,TD_LOCK(%r2) cmpw %r6,%r7 beq blocked_loop #endif mfsprg %r7,0 /* Get the pcpu pointer */ - stw %r15,PC_CURTHREAD(%r7) /* Store new current thread */ - lwz %r17,TD_PCB(%r15) /* Store new current PCB */ + stw %r2,PC_CURTHREAD(%r7) /* Store new current thread */ + lwz %r17,TD_PCB(%r2) /* Store new current PCB */ stw %r17,PC_CURPCB(%r7) - mr %r3,%r15 /* Get new thread ptr */ + mr %r3,%r2 /* Get new thread ptr */ bl pmap_activate /* Activate the new address space */ lwz %r6, PCB_FLAGS(%r17) /* Restore FPU context if needed */ andi. %r6, %r6, PCB_FPU beq .L3 - mr %r3,%r15 /* Pass curthread to enable_fpu */ + mr %r3,%r2 /* Pass curthread to enable_fpu */ bl enable_fpu .L3: @@ -147,7 +146,7 @@ blocked_loop: /* Restore Altivec context if needed */ andi. %r6, %r6, PCB_VEC beq .L4 - mr %r3,%r15 /* Pass curthread to enable_vec */ + mr %r3,%r2 /* Pass curthread to enable_vec */ bl enable_vec /* thread to restore is in r3 */ @@ -163,7 +162,6 @@ blocked_loop: mtsr USER_SR,%r5 isync lwz %r1,PCB_SP(%r3) /* Load the stack pointer */ - lwz %r2,PCB_TOC(%r3) /* Load the TOC pointer */ /* * Perform a dummy stwcx. to clear any reservations we may have * inherited from the previous thread. It doesn't matter if the diff --git a/sys/powerpc/aim/swtch64.S b/sys/powerpc/aim/swtch64.S index 1877e8df2aab..c5cdcbcaa7fb 100644 --- a/sys/powerpc/aim/swtch64.S +++ b/sys/powerpc/aim/swtch64.S @@ -69,7 +69,7 @@ * void cpu_throw(struct thread *old, struct thread *new) */ ENTRY(cpu_throw) - mr %r15, %r4 + mr %r13, %r4 b cpu_switchin /* @@ -83,7 +83,6 @@ ENTRY(cpu_switch) ld %r6,TD_PCB(%r3) /* Get the old thread's PCB ptr */ std %r12,PCB_CONTEXT(%r6) /* Save the non-volatile GP regs. These can now be used for scratch */ - std %r13,PCB_CONTEXT+1*8(%r6) std %r14,PCB_CONTEXT+2*8(%r6) std %r15,PCB_CONTEXT+3*8(%r6) std %r16,PCB_CONTEXT+4*8(%r6) @@ -111,7 +110,7 @@ ENTRY(cpu_switch) std %r2,PCB_TOC(%r6) /* Save the TOC pointer */ mr %r14,%r3 /* Copy the old thread ptr... */ - mr %r15,%r4 /* and the new thread ptr in scratch */ + mr %r13,%r4 /* and the new thread ptr in curthread*/ mr %r16,%r5 /* and the new lock */ mr %r17,%r6 /* and the PCB */ @@ -148,19 +147,19 @@ cpu_switchin: lis %r6,blocked_lock@ha addi %r6,%r6,blocked_lock@l blocked_loop: - ld %r7,TD_LOCK(%r15) + ld %r7,TD_LOCK(%r13) cmpd %r6,%r7 beq blocked_loop #endif mfsprg %r7,0 /* Get the pcpu pointer */ - std %r15,PC_CURTHREAD(%r7) /* Store new current thread */ - ld %r17,TD_PCB(%r15) /* Store new current PCB */ + std %r13,PC_CURTHREAD(%r7) /* Store new current thread */ + ld %r17,TD_PCB(%r13) /* Store new current PCB */ std %r17,PC_CURPCB(%r7) stdu %r1,-48(%r1) - mr %r3,%r15 /* Get new thread ptr */ + mr %r3,%r13 /* Get new thread ptr */ bl pmap_activate /* Activate the new address space */ nop @@ -168,7 +167,7 @@ blocked_loop: /* Restore FPU context if needed */ andi. %r6, %r6, PCB_FPU beq .L3 - mr %r3,%r15 /* Pass curthread to enable_fpu */ + mr %r3,%r13 /* Pass curthread to enable_fpu */ bl enable_fpu nop @@ -177,7 +176,7 @@ blocked_loop: /* Restore Altivec context if needed */ andi. %r6, %r6, PCB_VEC beq .L4 - mr %r3,%r15 /* Pass curthread to enable_vec */ + mr %r3,%r13 /* Pass curthread to enable_vec */ bl enable_vec nop @@ -186,7 +185,6 @@ blocked_loop: addi %r1,%r1,48 mr %r3,%r17 /* Recover PCB ptr */ ld %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs. */ - ld %r13,PCB_CONTEXT+1*8(%r3) ld %r14,PCB_CONTEXT+2*8(%r3) ld %r15,PCB_CONTEXT+3*8(%r3) ld %r16,PCB_CONTEXT+4*8(%r3) diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c index 60c0f3bd88d2..51dee0eabdb5 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -149,7 +149,7 @@ trap(struct trapframe *frame) PCPU_INC(cnt.v_trap); - td = PCPU_GET(curthread); + td = curthread; p = td->td_proc; type = ucode = frame->exc; @@ -452,7 +452,7 @@ syscall(struct trapframe *frame) struct syscall_args sa; int error; - td = PCPU_GET(curthread); + td = curthread; td->td_frame = frame; #ifdef __powerpc64__ @@ -600,7 +600,7 @@ badaddr_read(void *addr, size_t size, int *rptr) /* Get rid of any stale machine checks that have been waiting. */ __asm __volatile ("sync; isync"); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = 0; diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S index 80329cd0ff63..f00020b2146c 100644 --- a/sys/powerpc/aim/trap_subr32.S +++ b/sys/powerpc/aim/trap_subr32.S @@ -155,9 +155,15 @@ stw %r28,FRAME_AIM_DAR+8(1); \ stw %r29,FRAME_AIM_DSISR+8(1); /* save dsisr/srr0/srr1 */ \ stw %r30,FRAME_SRR0+8(1); \ - stw %r31,FRAME_SRR1+8(1) + stw %r31,FRAME_SRR1+8(1); \ + lwz %r2,PC_CURTHREAD(%r2) /* set curthread pointer */ #define FRAME_LEAVE(savearea) \ +/* Disable exceptions: */ \ + mfmsr %r2; \ + andi. %r2,%r2,~PSL_EE@l; \ + mtmsr %r2; \ + isync; \ /* Now restore regs: */ \ lwz %r2,FRAME_SRR0+8(%r1); \ lwz %r3,FRAME_SRR1+8(%r1); \ @@ -209,7 +215,7 @@ mtsprg3 %r3; \ /* Disable translation, machine check and recoverability: */ \ mfmsr %r2; \ - andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_EE|PSL_ME|PSL_RI)@l; \ + andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ mtmsr %r2; \ isync; \ /* Decide whether we return to user mode: */ \ @@ -764,8 +770,8 @@ CNAME(trapexit): bf 17,1f /* branch if PSL_PR is false */ GET_CPUINFO(%r3) /* get per-CPU pointer */ - lwz %r4, PC_CURTHREAD(%r3) /* deref to get curthread */ - lwz %r4, TD_FLAGS(%r4) /* get thread flags value */ + lwz %r4, TD_FLAGS(%r2) /* get thread flags value + * (r2 is curthread) */ lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l and. %r4,%r4,%r5 diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S index 66c543f4e2a0..1ec8507aef5c 100644 --- a/sys/powerpc/aim/trap_subr64.S +++ b/sys/powerpc/aim/trap_subr64.S @@ -179,9 +179,15 @@ restore_kernsrs: std %r28,FRAME_AIM_DAR+48(1); \ std %r29,FRAME_AIM_DSISR+48(1); /* save dsisr/srr0/srr1 */ \ std %r30,FRAME_SRR0+48(1); \ - std %r31,FRAME_SRR1+48(1) + std %r31,FRAME_SRR1+48(1); \ + ld %r13,PC_CURTHREAD(%r2) /* set kernel curthread */ #define FRAME_LEAVE(savearea) \ +/* Disable exceptions: */ \ + mfmsr %r2; \ + andi. %r2,%r2,~PSL_EE@l; \ + mtmsr %r2; \ + isync; \ /* Now restore regs: */ \ ld %r2,FRAME_SRR0+48(%r1); \ ld %r3,FRAME_SRR1+48(%r1); \ @@ -233,7 +239,7 @@ restore_kernsrs: mtsprg3 %r3; \ /* Disable translation, machine check and recoverability: */ \ mfmsr %r2; \ - andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_EE|PSL_ME|PSL_RI)@l; \ + andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ mtmsr %r2; \ isync; \ /* Decide whether we return to user mode: */ \ @@ -526,8 +532,7 @@ CNAME(trapexit): bf 17,1f /* branch if PSL_PR is false */ GET_CPUINFO(%r3) /* get per-CPU pointer */ - ld %r4, PC_CURTHREAD(%r3) /* deref to get curthread */ - lwz %r4, TD_FLAGS(%r4) /* get thread flags value */ + lwz %r4, TD_FLAGS(%r13) /* get thread flags value */ lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l and. %r4,%r4,%r5 diff --git a/sys/powerpc/booke/copyinout.c b/sys/powerpc/booke/copyinout.c index 91195dd3eb2c..011b8bdf3cde 100644 --- a/sys/powerpc/booke/copyinout.c +++ b/sys/powerpc/booke/copyinout.c @@ -87,7 +87,7 @@ copyout(const void *kaddr, void *udaddr, size_t len) if (!is_uaddr(udaddr)) return (EFAULT); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; @@ -109,7 +109,7 @@ copyin(const void *udaddr, void *kaddr, size_t len) if (!is_uaddr(udaddr) || is_uaddr(kaddr)) return (EFAULT); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; @@ -135,7 +135,7 @@ copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done) if (!is_uaddr(udaddr) || is_uaddr(kaddr)) return (EFAULT); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; @@ -175,7 +175,7 @@ subyte(void *addr, int byte) if (!is_uaddr(addr)) return (EFAULT); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; @@ -197,7 +197,7 @@ suword(void *addr, long word) if (!is_uaddr(addr)) return (EFAULT); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; @@ -228,7 +228,7 @@ fubyte(const void *addr) if (!is_uaddr(addr)) return (EFAULT); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; @@ -251,7 +251,7 @@ fuword(const void *addr) if (!is_uaddr(addr)) return (EFAULT); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; @@ -288,7 +288,7 @@ casuword(volatile u_long *addr, u_long old, u_long new) if (!((vm_offset_t)addr <= VM_MAXUSER_ADDRESS)) return (EFAULT); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; diff --git a/sys/powerpc/booke/interrupt.c b/sys/powerpc/booke/interrupt.c index c0bdee1e96cf..e268537a6039 100644 --- a/sys/powerpc/booke/interrupt.c +++ b/sys/powerpc/booke/interrupt.c @@ -118,7 +118,7 @@ powerpc_decr_interrupt(struct trapframe *framep) struct thread *td; struct trapframe *oldframe; - td = PCPU_GET(curthread); + td = curthread; critical_enter(); atomic_add_int(&td->td_intr_nesting_level, 1); oldframe = td->td_intr_frame; diff --git a/sys/powerpc/booke/trap.c b/sys/powerpc/booke/trap.c index a2d0d7037b15..fc506bd361ce 100644 --- a/sys/powerpc/booke/trap.c +++ b/sys/powerpc/booke/trap.c @@ -145,7 +145,7 @@ trap(struct trapframe *frame) PCPU_INC(cnt.v_trap); - td = PCPU_GET(curthread); + td = curthread; p = td->td_proc; type = frame->exc; @@ -382,7 +382,7 @@ syscall(struct trapframe *frame) struct syscall_args sa; int error; - td = PCPU_GET(curthread); + td = curthread; td->td_frame = frame; error = syscallenter(td, &sa); @@ -480,7 +480,7 @@ badaddr_read(void *addr, size_t size, int *rptr) /* Get rid of any stale machine checks that have been waiting. */ __asm __volatile ("sync; isync"); - td = PCPU_GET(curthread); + td = curthread; if (setfault(env)) { td->td_pcb->pcb_onfault = 0; diff --git a/sys/powerpc/include/pcpu.h b/sys/powerpc/include/pcpu.h index 949bbf391332..631abd256e48 100644 --- a/sys/powerpc/include/pcpu.h +++ b/sys/powerpc/include/pcpu.h @@ -135,6 +135,14 @@ struct pmap; #ifdef _KERNEL #define pcpup ((struct pcpu *) powerpc_get_pcpup()) +#ifdef __powerpc64__ +register struct thread *curthread_reg __asm("%r13"); +#else +register struct thread *curthread_reg __asm("%r2"); +#endif +#ifdef AIM /* Book-E not yet adapted */ +#define curthread curthread_reg +#endif #define PCPU_GET(member) (pcpup->pc_ ## member) diff --git a/sys/powerpc/ofw/ofwcall32.S b/sys/powerpc/ofw/ofwcall32.S index 06cc1055cd1c..d2ba70f49ae2 100644 --- a/sys/powerpc/ofw/ofwcall32.S +++ b/sys/powerpc/ofw/ofwcall32.S @@ -87,10 +87,11 @@ ASENTRY(ofwcall) * later. */ mr %r5,%r1 - lis %r1,(ofwstk+OFWSTKSZ-16)@ha - addi %r1,%r1,(ofwstk+OFWSTKSZ-16)@l - stw %r5,8(%r1) /* Save real stack pointer */ - stw %r6,12(%r1) /* Save old MSR */ + lis %r1,(ofwstk+OFWSTKSZ-32)@ha + addi %r1,%r1,(ofwstk+OFWSTKSZ-32)@l + stw %r5,20(%r1) /* Save real stack pointer */ + stw %r2,24(%r1) /* Save curthread */ + stw %r6,28(%r1) /* Save old MSR */ li %r5,0 stw %r5,4(%r1) stw %r5,0(%r1) @@ -100,8 +101,9 @@ ASENTRY(ofwcall) bctrl /* Reload stack pointer and MSR from the OFW stack */ - lwz %r6,12(%r1) - lwz %r1,8(%r1) + lwz %r6,28(%r1) + lwz %r2,24(%r1) + lwz %r1,20(%r1) /* Now set the real MSR */ mtmsr %r6 diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index 62a97e925050..35633765c5a8 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -96,10 +96,6 @@ machdep_ap_bootstrap(void) printf("SMP: AP CPU #%d launched\n", PCPU_GET(cpuid)); mtx_unlock_spin(&ap_boot_mtx); - /* Initialize curthread */ - PCPU_SET(curthread, PCPU_GET(idlethread)); - PCPU_SET(curpcb, curthread->td_pcb); - /* Start per-CPU event timers. */ cpu_initclocks_ap(); From f1a16106b6317f4cf5b187daeceda7c1468323c9 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 24 Jun 2011 02:30:02 +0000 Subject: [PATCH 40/57] - Move all USB device ID arrays into so-called sections, sorted according to the mode which they support: host, device or dual mode - Add generic tool to extract these data: tools/bus_autoconf Discussed with: imp Suggested by: Robert Millan PR: misc/157903 MFC after: 14 days --- sys/dev/sound/usb/uaudio.c | 9 + sys/dev/usb/input/atp.c | 2 +- sys/dev/usb/input/uhid.c | 28 +- sys/dev/usb/net/if_aue.c | 2 +- sys/dev/usb/net/if_axe.c | 2 +- sys/dev/usb/net/if_cdce.c | 10 +- sys/dev/usb/net/if_cue.c | 2 +- sys/dev/usb/net/if_ipheth.c | 2 +- sys/dev/usb/net/if_kue.c | 2 +- sys/dev/usb/net/if_mos.c | 2 +- sys/dev/usb/net/if_rue.c | 2 +- sys/dev/usb/net/if_udav.c | 2 +- sys/dev/usb/net/uhso.c | 2 +- sys/dev/usb/serial/u3g.c | 2 +- sys/dev/usb/serial/uark.c | 2 +- sys/dev/usb/serial/ubsa.c | 2 +- sys/dev/usb/serial/uchcom.c | 2 +- sys/dev/usb/serial/ucycom.c | 2 +- sys/dev/usb/serial/uftdi.c | 2 +- sys/dev/usb/serial/ugensa.c | 2 +- sys/dev/usb/serial/uipaq.c | 2 +- sys/dev/usb/serial/ulpt.c | 35 +- sys/dev/usb/serial/umcs.c | 2 +- sys/dev/usb/serial/umct.c | 2 +- sys/dev/usb/serial/umodem.c | 2 +- sys/dev/usb/serial/umoscom.c | 2 +- sys/dev/usb/serial/uplcom.c | 2 +- sys/dev/usb/serial/uslcom.c | 2 +- sys/dev/usb/serial/uvisor.c | 2 +- sys/dev/usb/serial/uvscom.c | 2 +- sys/dev/usb/storage/umass.c | 5 + sys/dev/usb/usbdi.h | 12 + sys/dev/usb/wlan/if_rum.c | 2 +- sys/dev/usb/wlan/if_run.c | 2 +- sys/dev/usb/wlan/if_uath.c | 2 +- sys/dev/usb/wlan/if_upgt.c | 4 +- sys/dev/usb/wlan/if_ural.c | 2 +- sys/dev/usb/wlan/if_urtw.c | 2 +- sys/dev/usb/wlan/if_zyd.c | 2 +- sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c | 4 +- .../bluetooth/drivers/ubtbcmfw/ubtbcmfw.c | 2 +- tools/tools/bus_autoconf/Makefile | 43 +++ tools/tools/bus_autoconf/bus_autoconf.c | 321 ++++++++++++++++++ tools/tools/bus_autoconf/bus_autoconf.h | 83 +++++ tools/tools/bus_autoconf/bus_autoconf.sh | 64 ++++ 45 files changed, 623 insertions(+), 61 deletions(-) create mode 100644 tools/tools/bus_autoconf/Makefile create mode 100644 tools/tools/bus_autoconf/bus_autoconf.c create mode 100644 tools/tools/bus_autoconf/bus_autoconf.h create mode 100644 tools/tools/bus_autoconf/bus_autoconf.sh diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 4f8670a5213e..f40ada78fcfb 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -531,6 +531,15 @@ static driver_t uaudio_driver = { .size = sizeof(struct uaudio_softc), }; +static const STRUCT_USB_HOST_ID __used uaudio_devs[] = { + /* Generic USB audio class match */ + {USB_IFACE_CLASS(UICLASS_AUDIO), + USB_IFACE_SUBCLASS(UISUBCLASS_AUDIOCONTROL),}, + /* Generic USB MIDI class match */ + {USB_IFACE_CLASS(UICLASS_AUDIO), + USB_IFACE_SUBCLASS(UISUBCLASS_MIDISTREAM),}, +}; + static int uaudio_probe(device_t dev) { diff --git a/sys/dev/usb/input/atp.c b/sys/dev/usb/input/atp.c index fab60a2c9693..9a17950a2d35 100644 --- a/sys/dev/usb/input/atp.c +++ b/sys/dev/usb/input/atp.c @@ -240,7 +240,7 @@ struct atp_dev_params { }, }; -static const struct usb_device_id atp_devs[] = { +static const STRUCT_USB_HOST_ID atp_devs[] = { /* Core Duo MacBook & MacBook Pro */ { USB_VPI(USB_VENDOR_APPLE, 0x0217, ATP_DEV_PARAMS_0) }, { USB_VPI(USB_VENDOR_APPLE, 0x0218, ATP_DEV_PARAMS_0) }, diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c index a7fd899c6fe0..1da12039d7c4 100644 --- a/sys/dev/usb/input/uhid.c +++ b/sys/dev/usb/input/uhid.c @@ -607,29 +607,33 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, return (error); } +static const STRUCT_USB_HOST_ID uhid_devs[] = { + /* generic HID class */ + {USB_IFACE_CLASS(UICLASS_HID),}, + /* the Xbox 360 gamepad doesn't use the HID class */ + {USB_IFACE_CLASS(UICLASS_VENDOR), + USB_IFACE_SUBCLASS(UISUBCLASS_XBOX360_CONTROLLER), + USB_IFACE_PROTOCOL(UIPROTO_XBOX360_GAMEPAD),}, +}; + static int uhid_probe(device_t dev) { struct usb_attach_arg *uaa = device_get_ivars(dev); + int error; DPRINTFN(11, "\n"); - if (uaa->usb_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); - } - if (uaa->info.bInterfaceClass != UICLASS_HID) { - /* the Xbox 360 gamepad doesn't use the HID class */ + error = usbd_lookup_id_by_uaa(uhid_devs, sizeof(uhid_devs), uaa); + if (error) + return (error); - if ((uaa->info.bInterfaceClass != UICLASS_VENDOR) || - (uaa->info.bInterfaceSubClass != UISUBCLASS_XBOX360_CONTROLLER) || - (uaa->info.bInterfaceProtocol != UIPROTO_XBOX360_GAMEPAD)) { - return (ENXIO); - } - } - if (usb_test_quirk(uaa, UQ_HID_IGNORE)) { + if (usb_test_quirk(uaa, UQ_HID_IGNORE)) return (ENXIO); - } + return (BUS_PROBE_GENERIC); } diff --git a/sys/dev/usb/net/if_aue.c b/sys/dev/usb/net/if_aue.c index 371684434d7f..71871de5a3d3 100644 --- a/sys/dev/usb/net/if_aue.c +++ b/sys/dev/usb/net/if_aue.c @@ -110,7 +110,7 @@ SYSCTL_INT(_hw_usb_aue, OID_AUTO, debug, CTLFLAG_RW, &aue_debug, 0, /* * Various supported device vendors/products. */ -static const struct usb_device_id aue_devs[] = { +static const STRUCT_USB_HOST_ID aue_devs[] = { #define AUE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } AUE_DEV(3COM, 3C460B, AUE_FLAG_PII), AUE_DEV(ABOCOM, DSB650TX_PNA, 0), diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c index 00d1c0b4b069..5c94e91574e6 100644 --- a/sys/dev/usb/net/if_axe.c +++ b/sys/dev/usb/net/if_axe.c @@ -133,7 +133,7 @@ SYSCTL_INT(_hw_usb_axe, OID_AUTO, debug, CTLFLAG_RW, &axe_debug, 0, /* * Various supported device vendors/products. */ -static const struct usb_device_id axe_devs[] = { +static const STRUCT_USB_HOST_ID axe_devs[] = { #define AXE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } AXE_DEV(ABOCOM, UF200, 0), AXE_DEV(ACERCM, EP1427X2, 0), diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c index b48e79d3bb0d..12e6f676d133 100644 --- a/sys/dev/usb/net/if_cdce.c +++ b/sys/dev/usb/net/if_cdce.c @@ -263,7 +263,7 @@ static const struct usb_ether_methods cdce_ue_methods = { .ue_setpromisc = cdce_setpromisc, }; -static const struct usb_device_id cdce_devs[] = { +static const STRUCT_USB_HOST_ID cdce_host_devs[] = { {USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)}, {USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)}, {USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)}, @@ -277,7 +277,9 @@ static const struct usb_device_id cdce_devs[] = { {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, +}; +static const STRUCT_USB_DUAL_ID cdce_dual_devs[] = { {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)}, {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)}, {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_NETWORK_CONTROL_MODEL, 0)}, @@ -472,8 +474,12 @@ static int cdce_probe(device_t dev) { struct usb_attach_arg *uaa = device_get_ivars(dev); + int error; - return (usbd_lookup_id_by_uaa(cdce_devs, sizeof(cdce_devs), uaa)); + error = usbd_lookup_id_by_uaa(cdce_host_devs, sizeof(cdce_host_devs), uaa); + if (error) + error = usbd_lookup_id_by_uaa(cdce_dual_devs, sizeof(cdce_dual_devs), uaa); + return (error); } static void diff --git a/sys/dev/usb/net/if_cue.c b/sys/dev/usb/net/if_cue.c index fae8f7049872..90a18f3fe6ca 100644 --- a/sys/dev/usb/net/if_cue.c +++ b/sys/dev/usb/net/if_cue.c @@ -88,7 +88,7 @@ __FBSDID("$FreeBSD$"); /* Belkin F5U111 adapter covered by NETMATE entry */ -static const struct usb_device_id cue_devs[] = { +static const STRUCT_USB_HOST_ID cue_devs[] = { #define CUE_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } CUE_DEV(CATC, NETMATE), CUE_DEV(CATC, NETMATE2), diff --git a/sys/dev/usb/net/if_ipheth.c b/sys/dev/usb/net/if_ipheth.c index c8a348ac76b0..d666835e6ae0 100644 --- a/sys/dev/usb/net/if_ipheth.c +++ b/sys/dev/usb/net/if_ipheth.c @@ -148,7 +148,7 @@ static const struct usb_ether_methods ipheth_ue_methods = { USB_IFACE_CLASS(c), USB_IFACE_SUBCLASS(sc), \ USB_IFACE_PROTOCOL(pt) -static const struct usb_device_id ipheth_devs[] = { +static const STRUCT_USB_HOST_ID ipheth_devs[] = { {IPHETH_ID(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO)}, diff --git a/sys/dev/usb/net/if_kue.c b/sys/dev/usb/net/if_kue.c index 6c97d28b5ad4..5480a5d8c289 100644 --- a/sys/dev/usb/net/if_kue.c +++ b/sys/dev/usb/net/if_kue.c @@ -100,7 +100,7 @@ __FBSDID("$FreeBSD$"); /* * Various supported device vendors/products. */ -static const struct usb_device_id kue_devs[] = { +static const STRUCT_USB_HOST_ID kue_devs[] = { #define KUE_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } KUE_DEV(3COM, 3C19250), KUE_DEV(3COM, 3C460), diff --git a/sys/dev/usb/net/if_mos.c b/sys/dev/usb/net/if_mos.c index a0e453c0638c..1e884f91ba47 100644 --- a/sys/dev/usb/net/if_mos.c +++ b/sys/dev/usb/net/if_mos.c @@ -146,7 +146,7 @@ SYSCTL_INT(_hw_usb_mos, OID_AUTO, debug, CTLFLAG_RW, &mos_debug, 0, /* Various supported device vendors/products. */ -static const struct usb_device_id mos_devs[] = { +static const STRUCT_USB_HOST_ID mos_devs[] = { {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7730, MCS7730)}, {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7830, MCS7830)}, {USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN030, MCS7830)}, diff --git a/sys/dev/usb/net/if_rue.c b/sys/dev/usb/net/if_rue.c index 1dadd57394cf..afd2f4d3666b 100644 --- a/sys/dev/usb/net/if_rue.c +++ b/sys/dev/usb/net/if_rue.c @@ -108,7 +108,7 @@ SYSCTL_INT(_hw_usb_rue, OID_AUTO, debug, CTLFLAG_RW, * Various supported device vendors/products. */ -static const struct usb_device_id rue_devs[] = { +static const STRUCT_USB_HOST_ID rue_devs[] = { {USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX, 0)}, {USB_VPI(USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100, 0)}, {USB_VPI(USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01, 0)}, diff --git a/sys/dev/usb/net/if_udav.c b/sys/dev/usb/net/if_udav.c index a6598ef96953..d2cceaa966d8 100644 --- a/sys/dev/usb/net/if_udav.c +++ b/sys/dev/usb/net/if_udav.c @@ -199,7 +199,7 @@ SYSCTL_INT(_hw_usb_udav, OID_AUTO, debug, CTLFLAG_RW, &udav_debug, 0, #define UDAV_CLRBIT(sc, reg, x) \ udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x)) -static const struct usb_device_id udav_devs[] = { +static const STRUCT_USB_HOST_ID udav_devs[] = { /* ShanTou DM9601 USB NIC */ {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, 0)}, /* ShanTou ST268 USB NIC */ diff --git a/sys/dev/usb/net/uhso.c b/sys/dev/usb/net/uhso.c index 06ac416fbe49..ab1309353747 100644 --- a/sys/dev/usb/net/uhso.c +++ b/sys/dev/usb/net/uhso.c @@ -247,7 +247,7 @@ static char *uhso_port_type_sysctl[] = { /* ifnet device unit allocations */ static struct unrhdr *uhso_ifnet_unit = NULL; -static const struct usb_device_id uhso_devs[] = { +static const STRUCT_USB_HOST_ID uhso_devs[] = { #define UHSO_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } /* Option GlobeSurfer iCON 7.2 */ UHSO_DEV(OPTION, GSICON72, UHSO_STATIC_IFACE), diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index c332bfbb8844..31e8e112e190 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -182,7 +182,7 @@ MODULE_DEPEND(u3g, ucom, 1, 1, 1); MODULE_DEPEND(u3g, usb, 1, 1, 1); MODULE_VERSION(u3g, 1); -static const struct usb_device_id u3g_devs[] = { +static const STRUCT_USB_HOST_ID u3g_devs[] = { #define U3G_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } U3G_DEV(ACERP, H10, 0), U3G_DEV(AIRPLUS, MCD650, 0), diff --git a/sys/dev/usb/serial/uark.c b/sys/dev/usb/serial/uark.c index 75100f21e343..2c3943d70dea 100644 --- a/sys/dev/usb/serial/uark.c +++ b/sys/dev/usb/serial/uark.c @@ -170,7 +170,7 @@ MODULE_DEPEND(uark, ucom, 1, 1, 1); MODULE_DEPEND(uark, usb, 1, 1, 1); MODULE_VERSION(uark, 1); -static const struct usb_device_id uark_devs[] = { +static const STRUCT_USB_HOST_ID uark_devs[] = { {USB_VPI(USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116, 0)}, }; diff --git a/sys/dev/usb/serial/ubsa.c b/sys/dev/usb/serial/ubsa.c index 1a5a75af444f..6afe05bdfd07 100644 --- a/sys/dev/usb/serial/ubsa.c +++ b/sys/dev/usb/serial/ubsa.c @@ -239,7 +239,7 @@ static const struct ucom_callback ubsa_callback = { .ucom_poll = &ubsa_poll, }; -static const struct usb_device_id ubsa_devs[] = { +static const STRUCT_USB_HOST_ID ubsa_devs[] = { /* AnyData ADU-500A */ {USB_VPI(USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_500A, 0)}, /* AnyData ADU-E100A/H */ diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c index 60fa9e04b47c..3f69c4d918e8 100644 --- a/sys/dev/usb/serial/uchcom.c +++ b/sys/dev/usb/serial/uchcom.c @@ -204,7 +204,7 @@ static const struct uchcom_divider_record dividers[] = #define NUM_DIVIDERS (sizeof (dividers) / sizeof (dividers[0])) -static const struct usb_device_id uchcom_devs[] = { +static const STRUCT_USB_HOST_ID uchcom_devs[] = { {USB_VPI(USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER, 0)}, {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER, 0)}, }; diff --git a/sys/dev/usb/serial/ucycom.c b/sys/dev/usb/serial/ucycom.c index a58398a4d5c6..8fef219de3f2 100644 --- a/sys/dev/usb/serial/ucycom.c +++ b/sys/dev/usb/serial/ucycom.c @@ -180,7 +180,7 @@ MODULE_VERSION(ucycom, 1); /* * Supported devices */ -static const struct usb_device_id ucycom_devs[] = { +static const STRUCT_USB_HOST_ID ucycom_devs[] = { {USB_VPI(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE, MODEL_CY7C64013)}, }; diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c index b196862041a7..1c880637f322 100644 --- a/sys/dev/usb/serial/uftdi.c +++ b/sys/dev/usb/serial/uftdi.c @@ -206,7 +206,7 @@ MODULE_DEPEND(uftdi, ucom, 1, 1, 1); MODULE_DEPEND(uftdi, usb, 1, 1, 1); MODULE_VERSION(uftdi, 1); -static struct usb_device_id uftdi_devs[] = { +static STRUCT_USB_HOST_ID uftdi_devs[] = { #define UFTDI_DEV(v,p,t) \ { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, UFTDI_TYPE_##t) } UFTDI_DEV(ATMEL, STK541, 8U232AM), diff --git a/sys/dev/usb/serial/ugensa.c b/sys/dev/usb/serial/ugensa.c index 0c2f2c4ac802..6b0955e911e6 100644 --- a/sys/dev/usb/serial/ugensa.c +++ b/sys/dev/usb/serial/ugensa.c @@ -154,7 +154,7 @@ MODULE_DEPEND(ugensa, ucom, 1, 1, 1); MODULE_DEPEND(ugensa, usb, 1, 1, 1); MODULE_VERSION(ugensa, 1); -static const struct usb_device_id ugensa_devs[] = { +static const STRUCT_USB_HOST_ID ugensa_devs[] = { {USB_VPI(USB_VENDOR_AIRPRIME, USB_PRODUCT_AIRPRIME_PC5220, 0)}, {USB_VPI(USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CDMA_MODEM1, 0)}, {USB_VPI(USB_VENDOR_KYOCERA2, USB_PRODUCT_KYOCERA2_CDMA_MSM_K, 0)}, diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c index 6f96164d8a83..d038e17e6531 100644 --- a/sys/dev/usb/serial/uipaq.c +++ b/sys/dev/usb/serial/uipaq.c @@ -153,7 +153,7 @@ static const struct ucom_callback uipaq_callback = { * support the same hardware. Numeric values are used where no usbdevs * entries exist. */ -static const struct usb_device_id uipaq_devs[] = { +static const STRUCT_USB_HOST_ID uipaq_devs[] = { /* Socket USB Sync */ {USB_VPI(0x0104, 0x00be, 0)}, /* USB Sync 0301 */ diff --git a/sys/dev/usb/serial/ulpt.c b/sys/dev/usb/serial/ulpt.c index ec1aa24fa2f1..def2ae560f42 100644 --- a/sys/dev/usb/serial/ulpt.c +++ b/sys/dev/usb/serial/ulpt.c @@ -483,24 +483,39 @@ ulpt_ioctl(struct usb_fifo *fifo, u_long cmd, void *data, return (ENODEV); } +static const STRUCT_USB_HOST_ID ulpt_devs[] = { + /* Uni-directional USB printer */ + {USB_IFACE_CLASS(UICLASS_PRINTER), + USB_IFACE_SUBCLASS(UISUBCLASS_PRINTER), + USB_IFACE_PROTOCOL(UIPROTO_PRINTER_UNI)}, + + /* Bi-directional USB printer */ + {USB_IFACE_CLASS(UICLASS_PRINTER), + USB_IFACE_SUBCLASS(UISUBCLASS_PRINTER), + USB_IFACE_PROTOCOL(UIPROTO_PRINTER_BI)}, + + /* 1284 USB printer */ + {USB_IFACE_CLASS(UICLASS_PRINTER), + USB_IFACE_SUBCLASS(UISUBCLASS_PRINTER), + USB_IFACE_PROTOCOL(UIPROTO_PRINTER_1284)}, +}; + static int ulpt_probe(device_t dev) { struct usb_attach_arg *uaa = device_get_ivars(dev); + int error; DPRINTFN(11, "\n"); - if (uaa->usb_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); - } - if ((uaa->info.bInterfaceClass == UICLASS_PRINTER) && - (uaa->info.bInterfaceSubClass == UISUBCLASS_PRINTER) && - ((uaa->info.bInterfaceProtocol == UIPROTO_PRINTER_UNI) || - (uaa->info.bInterfaceProtocol == UIPROTO_PRINTER_BI) || - (uaa->info.bInterfaceProtocol == UIPROTO_PRINTER_1284))) { - return (0); - } - return (ENXIO); + + error = usbd_lookup_id_by_uaa(ulpt_devs, sizeof(ulpt_devs), uaa); + if (error) + return (error); + + return (BUS_PROBE_GENERIC); } static int diff --git a/sys/dev/usb/serial/umcs.c b/sys/dev/usb/serial/umcs.c index c74044e99715..94ed4d9c92cf 100644 --- a/sys/dev/usb/serial/umcs.c +++ b/sys/dev/usb/serial/umcs.c @@ -253,7 +253,7 @@ static struct ucom_callback umcs7840_callback = { .ucom_poll = &umcs7840_poll, }; -static const struct usb_device_id umcs7840_devs[] = { +static const STRUCT_USB_HOST_ID umcs7840_devs[] = { {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7820, 0)}, {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7840, 0)}, }; diff --git a/sys/dev/usb/serial/umct.c b/sys/dev/usb/serial/umct.c index 39dc9d795890..16dd4a1aba3f 100644 --- a/sys/dev/usb/serial/umct.c +++ b/sys/dev/usb/serial/umct.c @@ -192,7 +192,7 @@ static const struct ucom_callback umct_callback = { .ucom_poll = &umct_poll, }; -static const struct usb_device_id umct_devs[] = { +static const STRUCT_USB_HOST_ID umct_devs[] = { {USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0)}, {USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232, 0)}, {USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232, 0)}, diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c index c6d517b69cad..92bfe930f00f 100644 --- a/sys/dev/usb/serial/umodem.c +++ b/sys/dev/usb/serial/umodem.c @@ -123,7 +123,7 @@ SYSCTL_INT(_hw_usb_umodem, OID_AUTO, debug, CTLFLAG_RW, &umodem_debug, 0, "Debug level"); #endif -static const struct usb_device_id umodem_devs[] = { +static const STRUCT_USB_HOST_ID umodem_devs[] = { /* Generic Modem class match */ {USB_IFACE_CLASS(UICLASS_CDC), USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL), diff --git a/sys/dev/usb/serial/umoscom.c b/sys/dev/usb/serial/umoscom.c index 4ab6cc094728..c346ae692237 100644 --- a/sys/dev/usb/serial/umoscom.c +++ b/sys/dev/usb/serial/umoscom.c @@ -280,7 +280,7 @@ MODULE_DEPEND(umoscom, ucom, 1, 1, 1); MODULE_DEPEND(umoscom, usb, 1, 1, 1); MODULE_VERSION(umoscom, 1); -static const struct usb_device_id umoscom_devs[] = { +static const STRUCT_USB_HOST_ID umoscom_devs[] = { {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7703, 0)} }; diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c index 108ee7b3c61f..4af053795d48 100644 --- a/sys/dev/usb/serial/uplcom.c +++ b/sys/dev/usb/serial/uplcom.c @@ -247,7 +247,7 @@ static struct ucom_callback uplcom_callback = { #define UPLCOM_DEV(v,p) \ { USB_VENDOR(USB_VENDOR_##v), USB_PRODUCT(USB_PRODUCT_##v##_##p) } -static const struct usb_device_id uplcom_devs[] = { +static const STRUCT_USB_HOST_ID uplcom_devs[] = { UPLCOM_DEV(ACERP, S81), /* BenQ S81 phone */ UPLCOM_DEV(ADLINK, ND6530), /* ADLINK ND-6530 USB-Serial */ UPLCOM_DEV(ALCATEL, OT535), /* Alcatel One Touch 535/735 */ diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c index 1357c8dfb09a..6eaec83c3047 100644 --- a/sys/dev/usb/serial/uslcom.c +++ b/sys/dev/usb/serial/uslcom.c @@ -173,7 +173,7 @@ static struct ucom_callback uslcom_callback = { .ucom_poll = &uslcom_poll, }; -static const struct usb_device_id uslcom_devs[] = { +static const STRUCT_USB_HOST_ID uslcom_devs[] = { #define USLCOM_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } USLCOM_DEV(BALTECH, CARDREADER), USLCOM_DEV(CLIPSAL, 5500PCU), diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c index 3efef5dc9fef..976ea1922111 100644 --- a/sys/dev/usb/serial/uvisor.c +++ b/sys/dev/usb/serial/uvisor.c @@ -253,7 +253,7 @@ MODULE_DEPEND(uvisor, ucom, 1, 1, 1); MODULE_DEPEND(uvisor, usb, 1, 1, 1); MODULE_VERSION(uvisor, 1); -static const struct usb_device_id uvisor_devs[] = { +static const STRUCT_USB_HOST_ID uvisor_devs[] = { #define UVISOR_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } UVISOR_DEV(ACEECA, MEZ1000, UVISOR_FLAG_PALM4), UVISOR_DEV(ALPHASMART, DANA_SYNC, UVISOR_FLAG_PALM4), diff --git a/sys/dev/usb/serial/uvscom.c b/sys/dev/usb/serial/uvscom.c index d8831901d136..52e02ad904f9 100644 --- a/sys/dev/usb/serial/uvscom.c +++ b/sys/dev/usb/serial/uvscom.c @@ -233,7 +233,7 @@ static const struct ucom_callback uvscom_callback = { .ucom_poll = &uvscom_poll, }; -static const struct usb_device_id uvscom_devs[] = { +static const STRUCT_USB_HOST_ID uvscom_devs[] = { /* SUNTAC U-Cable type A4 */ {USB_VPI(USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS144L4, 0)}, /* SUNTAC U-Cable type D2 */ diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index 158d8432d7db..9292c842bcb7 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -721,6 +721,11 @@ MODULE_VERSION(umass, 1); * USB device probe/attach/detach */ +static const STRUCT_USB_HOST_ID __used umass_devs[] = { + /* generic mass storage class */ + {USB_IFACE_CLASS(UICLASS_MASS),}, +}; + static uint16_t umass_get_proto(struct usb_interface *iface) { diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 91cd3fae3aaf..a21687901392 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -227,6 +227,18 @@ struct usb_config { uint8_t if_index; /* "ifaces" index to use */ }; +/* + * Use these macro when defining USB device ID arrays if you want to + * have your driver module automatically loaded in host, device or + * both modes respectivly: + */ +#define STRUCT_USB_HOST_ID \ + struct usb_device_id __section("usb_host_id") +#define STRUCT_USB_DEVICE_ID \ + struct usb_device_id __section("usb_device_id") +#define STRUCT_USB_DUAL_ID \ + struct usb_device_id __section("usb_dual_id") + /* * The following structure is used when looking up an USB driver for * an USB device. It is inspired by the Linux structure called diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 63b314de4b19..5a69792aeeaa 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -85,7 +85,7 @@ SYSCTL_INT(_hw_usb_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0, "Debug level"); #endif -static const struct usb_device_id rum_devs[] = { +static const STRUCT_USB_HOST_ID rum_devs[] = { #define RUM_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } RUM_DEV(ABOCOM, HWU54DM), RUM_DEV(ABOCOM, RT2573_2), diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c index 2cd147cbb5a3..47823b9d8ec5 100644 --- a/sys/dev/usb/wlan/if_run.c +++ b/sys/dev/usb/wlan/if_run.c @@ -96,7 +96,7 @@ SYSCTL_INT(_hw_usb_run, OID_AUTO, debug, CTLFLAG_RW, &run_debug, 0, */ #define RUN_CMDQ_GET(c) (atomic_fetchadd_32((c), 1) & RUN_CMDQ_MASQ) -static const struct usb_device_id run_devs[] = { +static const STRUCT_USB_HOST_ID run_devs[] = { #define RUN_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } RUN_DEV(ABOCOM, RT2770), RUN_DEV(ABOCOM, RT2870), diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index 35202a9b50f6..baff5dea5b68 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -167,7 +167,7 @@ enum { (((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24))) /* recognized device vendors/products */ -static const struct usb_device_id uath_devs[] = { +static const STRUCT_USB_HOST_ID uath_devs[] = { #define UATH_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } UATH_DEV(ACCTON, SMCWUSBG), UATH_DEV(ACCTON, SMCWUSBTG2), diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index d704cec1aa99..b9381a2c69cd 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -170,7 +170,7 @@ static int upgt_tx_start(struct upgt_softc *, struct mbuf *, static const char *upgt_fwname = "upgt-gw3887"; -static const struct usb_device_id upgt_devs_2[] = { +static const STRUCT_USB_HOST_ID upgt_devs[] = { #define UPGT_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } /* version 2 devices */ UPGT_DEV(ACCTON, PRISM_GT), @@ -236,7 +236,7 @@ upgt_match(device_t dev) if (uaa->info.bIfaceIndex != UPGT_IFACE_INDEX) return (ENXIO); - return (usbd_lookup_id_by_uaa(upgt_devs_2, sizeof(upgt_devs_2), uaa)); + return (usbd_lookup_id_by_uaa(upgt_devs, sizeof(upgt_devs), uaa)); } static int diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index 65d974acd03e..048392d8c96f 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -91,7 +91,7 @@ SYSCTL_INT(_hw_usb_ural, OID_AUTO, debug, CTLFLAG_RW, &ural_debug, 0, ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0) /* various supported device vendors/products */ -static const struct usb_device_id ural_devs[] = { +static const STRUCT_USB_HOST_ID ural_devs[] = { #define URAL_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } URAL_DEV(ASUS, WL167G), URAL_DEV(ASUS, RT2570), diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c index 7805c2d55046..6ae7e1658025 100644 --- a/sys/dev/usb/wlan/if_urtw.c +++ b/sys/dev/usb/wlan/if_urtw.c @@ -102,7 +102,7 @@ TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode); { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTW_REV_RTL8187L) } #define URTW_REV_RTL8187B 0 #define URTW_REV_RTL8187L 1 -static const struct usb_device_id urtw_devs[] = { +static const STRUCT_USB_HOST_ID urtw_devs[] = { URTW_DEV_B(NETGEAR, WG111V3), URTW_DEV_B(REALTEK, RTL8187B_0), URTW_DEV_B(REALTEK, RTL8187B_1), diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index 43ec6ca0a24f..f8d905ec9842 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -200,7 +200,7 @@ static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB; { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, ZYD_ZD1211) } #define ZYD_ZD1211B_DEV(v,p) \ { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, ZYD_ZD1211B) } -static const struct usb_device_id zyd_devs[] = { +static const STRUCT_USB_HOST_ID zyd_devs[] = { /* ZYD_ZD1211 */ ZYD_ZD1211_DEV(3COM2, 3CRUSB10075), ZYD_ZD1211_DEV(ABOCOM, WL54), diff --git a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c index a13ef4d05f96..d3f8fd3c6798 100644 --- a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c +++ b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c @@ -382,14 +382,14 @@ static const struct usb_config ubt_config[UBT_N_TRANSFER] = * where VENDOR_ID and PRODUCT_ID are hex numbers. */ -static const struct usb_device_id ubt_ignore_devs[] = +static const STRUCT_USB_HOST_ID ubt_ignore_devs[] = { /* AVM USB Bluetooth-Adapter BlueFritz! v1.0 */ { USB_VPI(USB_VENDOR_AVM, 0x2200, 0) }, }; /* List of supported bluetooth devices */ -static const struct usb_device_id ubt_devs[] = +static const STRUCT_USB_HOST_ID ubt_devs[] = { /* Generic Bluetooth class devices */ { USB_IFACE_CLASS(UDCLASS_WIRELESS), diff --git a/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c b/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c index 3d8a05e4e3ba..da00e05c9b35 100644 --- a/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c +++ b/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c @@ -180,7 +180,7 @@ MODULE_DEPEND(ubtbcmfw, usb, 1, 1, 1); static int ubtbcmfw_probe(device_t dev) { - const struct usb_device_id devs[] = { + static const STRUCT_USB_HOST_ID devs[] = { /* Broadcom BCM2033 devices only */ { USB_VPI(USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033, 0) }, }; diff --git a/tools/tools/bus_autoconf/Makefile b/tools/tools/bus_autoconf/Makefile new file mode 100644 index 000000000000..c2f1b138594a --- /dev/null +++ b/tools/tools/bus_autoconf/Makefile @@ -0,0 +1,43 @@ +# $FreeBSD$ +# +# Copyright (c) 2011 Hans Petter Selasky. 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. +# + +# +# Example on how to use: +# +# make clean all install +# +# ./bus_autoconf.sh /boot/kernel/*.ko | less +# + +PROG= bus_autoconf +MAN= +BINDIR?= /usr/local/bin + +SRCS= bus_autoconf.c + +WARNS= 6 + +.include diff --git a/tools/tools/bus_autoconf/bus_autoconf.c b/tools/tools/bus_autoconf/bus_autoconf.c new file mode 100644 index 000000000000..68688afb25a7 --- /dev/null +++ b/tools/tools/bus_autoconf/bus_autoconf.c @@ -0,0 +1,321 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + */ + +/* + * Disclaimer: This utility and format is subject to change and not a + * comitted interface. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bus_autoconf.h" + +static char *type; +static char *file_name; +static char *module; +static const char *mode; + +static int +usb_compare(const void *_a, const void *_b) +{ + const struct usb_device_id *a = _a; + const struct usb_device_id *b = _b; + + if (a->idVendor > b->idVendor) + return (1); + if (a->idVendor < b->idVendor) + return (-1); + if (a->idProduct > b->idProduct) + return (1); + if (a->idProduct < b->idProduct) + return (-1); + if (a->bDeviceClass > b->bDeviceClass) + return (1); + if (a->bDeviceClass < b->bDeviceClass) + return (-1); + if (a->bDeviceSubClass > b->bDeviceSubClass) + return (1); + if (a->bDeviceSubClass < b->bDeviceSubClass) + return (-1); + if (a->bDeviceProtocol > b->bDeviceProtocol) + return (1); + if (a->bDeviceProtocol < b->bDeviceProtocol) + return (-1); + if (a->bInterfaceClass > b->bInterfaceClass) + return (1); + if (a->bInterfaceClass < b->bInterfaceClass) + return (-1); + if (a->bInterfaceSubClass > b->bInterfaceSubClass) + return (1); + if (a->bInterfaceSubClass < b->bInterfaceSubClass) + return (-1); + if (a->bInterfaceProtocol > b->bInterfaceProtocol) + return (1); + if (a->bInterfaceProtocol < b->bInterfaceProtocol) + return (-1); + + return (0); +} + +static void +usb_sort(struct usb_device_id *id, uint32_t nid) +{ + qsort(id, nid, sizeof(*id), &usb_compare); +} + +struct usb_info { + uint8_t is_iface; + uint8_t is_any; + uint8_t is_vp; + uint8_t is_dev; +}; + +static void +usb_dump_sub(struct usb_device_id *id, struct usb_info *pinfo) +{ +#if USB_HAVE_COMPAT_LINUX + if (id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) + id->match_flag_vendor = 1; + if (id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) + id->match_flag_product = 1; + if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) + id->match_flag_dev_lo = 1; + if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) + id->match_flag_dev_hi = 1; + if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) + id->match_flag_dev_class = 1; + if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) + id->match_flag_dev_subclass = 1; + if (id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) + id->match_flag_dev_protocol = 1; + if (id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) + id->match_flag_int_class = 1; + if (id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) + id->match_flag_int_subclass = 1; + if (id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) + id->match_flag_int_protocol = 1; +#endif + + pinfo->is_iface = id->match_flag_int_class | + id->match_flag_int_protocol | + id->match_flag_int_subclass; + + pinfo->is_dev = id->match_flag_dev_class | + id->match_flag_dev_subclass; + + pinfo->is_vp = id->match_flag_vendor | + id->match_flag_product; + + pinfo->is_any = pinfo->is_vp + pinfo->is_dev + pinfo->is_iface; +} + +static uint32_t +usb_dump(struct usb_device_id *id, uint32_t nid) +{ + uint32_t n = 1; + struct usb_info info; + + usb_dump_sub(id, &info); + + if (info.is_iface) { + printf("nomatch 10 {\n" + " match \"system\" \"USB\";\n" + " match \"subsystem\" \"INTERFACE\";\n" + " match \"mode\" \"%s\";\n", mode); + } else if (info.is_any) { + printf("nomatch 10 {\n" + " match \"system\" \"USB\";\n" + " match \"subsystem\" \"DEVICE\";\n" + " match \"mode\" \"%s\";\n", mode); + } else { + return (n); + } + + if (id->match_flag_vendor) { + printf(" match \"vendor\" \"0x%04x\";\n", + id->idVendor); + } + if (id->match_flag_product) { + uint32_t x; + + if (info.is_any == 1 && info.is_vp == 1) { + /* try to join similar entries */ + while (n < nid) { + usb_dump_sub(id + n, &info); + + if (info.is_any != 1 || info.is_vp != 1) + break; + if (id[n].idVendor != id[0].idVendor) + break; + n++; + } + /* restore infos */ + usb_dump_sub(id, &info); + } + if (n == 1) { + printf(" match \"product\" \"0x%04x\";\n", + id->idProduct); + } else { + printf(" match \"product\" \"("); + + for (x = 0; x != n; x++) { + printf("0x%04x%s", id[x].idProduct, + (x == (n - 1)) ? "" : "|"); + } + + printf(")\";\n"); + } + } + if (id->match_flag_dev_class) { + printf(" match \"devclass\" \"0x%02x\";\n", + id->bDeviceClass); + } + if (id->match_flag_dev_subclass) { + printf(" match \"devsubclass\" \"0x%02x\";\n", + id->bDeviceSubClass); + } + if (id->match_flag_int_class) { + printf(" match \"intclass\" \"0x%02x\";\n", + id->bInterfaceClass); + } + if (id->match_flag_int_subclass) { + printf(" match \"intsubclass\" \"0x%02x\";\n", + id->bInterfaceSubClass); + } + if (id->match_flag_int_protocol) { + printf(" match \"intprotocol\" \"0x%02x\";\n", + id->bInterfaceProtocol); + } + printf(" action \"kldload %s\";\n" + "};\n\n", module); + + return (n); +} + +static void +usb_parse_and_dump(int f, off_t size) +{ + struct usb_device_id *id; + uint32_t nid; + uint32_t x; + + if (size % sizeof(struct usb_device_id)) { + errx(EX_NOINPUT, "Size is not divisible by %d", + (int)sizeof(struct usb_device_id)); + } + lseek(f, 0, SEEK_SET); + + id = malloc(size); + if (id == NULL) { + errx(EX_SOFTWARE, "Out of memory"); + } + if (read(f, id, size) != size) { + err(EX_NOINPUT, "Cannot read all data"); + } + nid = size / sizeof(*id); + + usb_sort(id, nid); + + for (x = 0; x != nid;) + x += usb_dump(id + x, nid - x); + + free(id); +} + +static void +usage(void) +{ + fprintf(stderr, + "bus_autoconf - devd config file generator\n" + " -i \n" + " -m \n" + " -t \n" + " -h show usage\n" + ); + exit(EX_USAGE); +} + +int +main(int argc, char **argv) +{ + const char *params = "i:m:ht:"; + int c; + int f; + off_t off; + + while ((c = getopt(argc, argv, params)) != -1) { + switch (c) { + case 'i': + file_name = optarg; + break; + case 't': + type = optarg; + break; + case 'm': + module = optarg; + break; + default: + usage(); + break; + } + } + + if (type == NULL || module == NULL || file_name == NULL) + usage(); + + f = open(file_name, O_RDONLY); + if (f < 0) + err(EX_NOINPUT, "Cannot open file '%s'", file_name); + + off = lseek(f, 0, SEEK_END); + if (off <= 0) + err(EX_NOINPUT, "Cannot seek to end of file"); + + if (strcmp(type, "usb_host") == 0) { + mode = "host"; + usb_parse_and_dump(f, off); + } else if (strcmp(type, "usb_device") == 0) { + mode = "device"; + usb_parse_and_dump(f, off); + } else if (strcmp(type, "usb_dual") == 0) { + mode = "(host|device)"; + usb_parse_and_dump(f, off); + } else { + err(EX_USAGE, "Unsupported structure type: %s", type); + } + + close(f); + + return (0); +} diff --git a/tools/tools/bus_autoconf/bus_autoconf.h b/tools/tools/bus_autoconf/bus_autoconf.h new file mode 100644 index 000000000000..a247109b2f7d --- /dev/null +++ b/tools/tools/bus_autoconf/bus_autoconf.h @@ -0,0 +1,83 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + */ + +#ifndef _BUS_AUTOCONF_H_ +#define _BUS_AUTOCONF_H_ + +/* Make sure we get the have compat linux definition. */ +#include + +struct usb_device_id { + + /* Hook for driver specific information */ + unsigned long driver_info; + + /* Used for product specific matches; the BCD range is inclusive */ + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice_lo; + uint16_t bcdDevice_hi; + + /* Used for device class matches */ + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + + /* Used for interface class matches */ + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + + /* Select which fields to match against */ + uint8_t match_flag_vendor:1; + uint8_t match_flag_product:1; + uint8_t match_flag_dev_lo:1; + uint8_t match_flag_dev_hi:1; + uint8_t match_flag_dev_class:1; + uint8_t match_flag_dev_subclass:1; + uint8_t match_flag_dev_protocol:1; + uint8_t match_flag_int_class:1; + uint8_t match_flag_int_subclass:1; + uint8_t match_flag_int_protocol:1; + +#if USB_HAVE_COMPAT_LINUX + /* which fields to match against */ + uint16_t match_flags; +#define USB_DEVICE_ID_MATCH_VENDOR 0x0001 +#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002 +#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004 +#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008 +#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010 +#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 +#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 +#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 +#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 +#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 +#endif +}; + +#endif /* _BUS_AUTOCONF_H_ */ diff --git a/tools/tools/bus_autoconf/bus_autoconf.sh b/tools/tools/bus_autoconf/bus_autoconf.sh new file mode 100644 index 000000000000..4815572261af --- /dev/null +++ b/tools/tools/bus_autoconf/bus_autoconf.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# +# $FreeBSD$ +# +# Copyright (c) 2011 Hans Petter Selasky. 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. +# + +OS=FreeBSD +DOLLAR=$ + +cat < /dev/null +[ -f ${F}.ids ] && ( +bus_autoconf -i ${F}.ids -t usb_host -m ${H} ; +rm ${F}.ids +) +# USB Device +objcopy -j usb_device_id -O binary ${F} ${F}.ids 2> /dev/null +[ -f ${F}.ids ] && ( +bus_autoconf -i ${F}.ids -t usb_device -m ${H} ; +rm ${F}.ids +) +# USB Dual mode +objcopy -j usb_dual_id -O binary ${F} ${F}.ids 2> /dev/null +[ -f ${F}.ids ] && ( +bus_autoconf -i ${F}.ids -t usb_dual -m ${H} ; +rm ${F}.ids +) +done From 14de21443e89dacc8aed237e74f5bd21e85d2f84 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Fri, 24 Jun 2011 02:56:24 +0000 Subject: [PATCH 41/57] Bring back synchnet() implementation from older tftp implementation. The synchnet() function was converted to a no-op when the new TFTP implementation was committed to FreeBSD. However, this function, as it was in the older code, is needed in order to synchronize between the tftpd server and tftp clients, which may be buggy. Specifically, we had a buggy TFTP client which would send TFTP ACK packets for non-TFTP packets, which would cause the count of packets to get out of whack, causing transfers to fail with the new TFTPD implementation. Obtained from: Juniper Networks Submitted by: Santhanakrishnan Balraj --- libexec/tftpd/tftp-file.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/libexec/tftpd/tftp-file.c b/libexec/tftpd/tftp-file.c index 1ef882014ea6..6b8fb6e83c15 100644 --- a/libexec/tftpd/tftp-file.c +++ b/libexec/tftpd/tftp-file.c @@ -27,6 +27,8 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include #include @@ -249,9 +251,34 @@ read_close(void) } -int -synchnet(int peer __unused) -{ +/* When an error has occurred, it is possible that the two sides + * are out of synch. Ie: that what I think is the other side's + * response to packet N is really their response to packet N-1. + * + * So, to try to prevent that, we flush all the input queued up + * for us on the network connection on our host. + * + * We return the number of packets we flushed (mostly for reporting + * when trace is active). + */ - return 0; +int +synchnet(int peer) /* socket to flush */ +{ + int i, j = 0; + char rbuf[MAXPKTSIZE]; + struct sockaddr_storage from; + socklen_t fromlen; + + while (1) { + (void) ioctl(peer, FIONREAD, &i); + if (i) { + j++; + fromlen = sizeof from; + (void) recvfrom(peer, rbuf, sizeof (rbuf), 0, + (struct sockaddr *)&from, &fromlen); + } else { + return(j); + } + } } From 23a5bce73fbf2db712eff486dcfc17ab4c92c539 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Fri, 24 Jun 2011 03:50:54 +0000 Subject: [PATCH 42/57] Fixes to newer tftp code in libstand: (1) Coding style changes. (2) If the server does not acknowledge any blocksize option, revert to the default blocksize of 512 bytes. (3) Send ACK if the first packet happens to be the last packet. (4) Do not accept blocksize greater than what was requested. (5) Drop any unwanted OACK received if a tftp transfer is already in progress. (6) Terminate incomplete transfers with a special no-error ERROR packet. Otherwise we rely on the tftp server to time out, which it does eventually, after re-sending the last packet several times and spamming the system log about it every time. This idea is borrowed from the PXE client, which does exactly that. Submitted by: Alexander Kabaev Reviewed and Tested by: Santhanakrishnan Balraj --- lib/libstand/tftp.c | 183 ++++++++++++++++++++++++++++++++------------ 1 file changed, 132 insertions(+), 51 deletions(-) diff --git a/lib/libstand/tftp.c b/lib/libstand/tftp.c index 54e184cc27d0..bf92c0467199 100644 --- a/lib/libstand/tftp.c +++ b/lib/libstand/tftp.c @@ -64,13 +64,13 @@ struct tftp_handle; static int tftp_open(const char *path, struct open_file *f); static int tftp_close(struct open_file *f); -static void tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len); +static int tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len); static int tftp_read(struct open_file *f, void *buf, size_t size, size_t *resid); static int tftp_write(struct open_file *f, void *buf, size_t size, size_t *resid); static off_t tftp_seek(struct open_file *f, off_t offset, int where); static int tftp_set_blksize(struct tftp_handle *h, const char *str); static int tftp_stat(struct open_file *f, struct stat *sb); -static ssize_t sendrecv_tftp(struct tftp_handle *h, +static ssize_t sendrecv_tftp(struct tftp_handle *h, ssize_t (*sproc)(struct iodesc *, void *, size_t), void *sbuf, size_t ssize, ssize_t (*rproc)(struct tftp_handle *h, void *, ssize_t, time_t, unsigned short *), @@ -93,7 +93,7 @@ static int tftpport = 2000; static int is_open = 0; /* - * The legacy TFTP_BLKSIZE value was 512. + * The legacy TFTP_BLKSIZE value was SEGSIZE(512). * TFTP_REQUESTED_BLKSIZE of 1428 is (Ethernet MTU, less the TFTP, UDP and * IP header lengths). */ @@ -102,7 +102,7 @@ static int is_open = 0; /* * Choose a blksize big enough so we can test with Ethernet * Jumbo frames in the future. - */ + */ #define TFTP_MAX_BLKSIZE 9008 struct tftp_handle { @@ -113,7 +113,7 @@ struct tftp_handle { int off; char *path; /* saved for re-requests */ unsigned int tftp_blksize; - unsigned long tftp_tsize; + unsigned long tftp_tsize; struct { u_char header[HEADER_SIZE]; struct tftphdr t; @@ -121,7 +121,8 @@ struct tftp_handle { } __packed __aligned(4) lastdata; }; -static const int tftperrors[8] = { +#define TFTP_MAX_ERRCODE EOPTNEG +static const int tftperrors[TFTP_MAX_ERRCODE + 1] = { 0, /* ??? */ ENOENT, EPERM, @@ -129,10 +130,57 @@ static const int tftperrors[8] = { EINVAL, /* ??? */ EINVAL, /* ??? */ EEXIST, - EINVAL /* ??? */ + EINVAL, /* ??? */ + EINVAL, /* Option negotiation failed. */ }; -static ssize_t +static int tftp_getnextblock(struct tftp_handle *h); + +/* send error message back. */ +static void +tftp_senderr(struct tftp_handle *h, u_short errcode, const char *msg) +{ + struct { + u_char header[HEADER_SIZE]; + struct tftphdr t; + u_char space[63]; /* +1 from t */ + } __packed __aligned(4) wbuf; + char *wtail; + int len; + + len = strlen(msg); + if (len > sizeof(wbuf.space)) + len = sizeof(wbuf.space); + + wbuf.t.th_opcode = htons((u_short) ERROR); + wbuf.t.th_code = htons(errcode); + + wtail = wbuf.t.th_msg; + bcopy(msg, wtail, len); + wtail[len] = '\0'; + wtail += len + 1; + + sendudp(h->iodesc, &wbuf.t, wtail - (char *) &wbuf.t); +} + +static void +tftp_sendack(struct tftp_handle *h) +{ + struct { + u_char header[HEADER_SIZE]; + struct tftphdr t; + } __packed __aligned(4) wbuf; + char *wtail; + + wbuf.t.th_opcode = htons((u_short) ACK); + wtail = (char *) &wbuf.t.th_block; + wbuf.t.th_block = htons((u_short) h->currblock); + wtail += 2; + + sendudp(h->iodesc, &wbuf.t, wtail - (char *) &wbuf.t); +} + +static ssize_t recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft, unsigned short *rtype) { @@ -170,7 +218,7 @@ recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft, return got; } case ERROR: - if ((unsigned) ntohs(t->th_code) >= 8) { + if ((unsigned) ntohs(t->th_code) > TFTP_MAX_ERRCODE) { printf("illegal tftp error %d\n", ntohs(t->th_code)); errno = EIO; } else { @@ -182,14 +230,30 @@ recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft, return (-1); case OACK: { struct udphdr *uh; - int tftp_oack_len = len - sizeof(t->th_opcode); - tftp_parse_oack(h, t->th_u.tu_stuff, tftp_oack_len); + int tftp_oack_len; + + /* + * Unexpected OACK. TFTP transfer already in progress. + * Drop the pkt. + */ + if (d->xid != 1) { + return (-1); + } + /* - * Remember which port this OACK came from, - * because we need to send the ACK back to it. + * Remember which port this OACK came from, because we need + * to send the ACK or errors back to it. */ uh = (struct udphdr *) pkt - 1; d->destport = uh->uh_sport; + + /* Parse options ACK-ed by the server. */ + tftp_oack_len = len - sizeof(t->th_opcode); + if (tftp_parse_oack(h, t->th_u.tu_stuff, tftp_oack_len) != 0) { + tftp_senderr(h, EOPTNEG, "Malformed OACK"); + errno = EIO; + return (-1); + } return (0); } default: @@ -201,7 +265,7 @@ recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft, } /* send request, expect first block (or error) */ -static int +static int tftp_makereq(struct tftp_handle *h) { struct { @@ -250,26 +314,28 @@ tftp_makereq(struct tftp_handle *h) h->iodesc->destport = htons(IPPORT_TFTP); h->iodesc->xid = 1; /* expected block */ + h->currblock = 0; + h->islastblock = 0; + h->validsize = 0; + res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype); - if (rtype == OACK) { - wbuf.t.th_opcode = htons((u_short)ACK); - wtail = (char *) &wbuf.t.th_block; - wbuf.t.th_block = htons(0); - wtail += 2; - rtype = 0; - res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t, - &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype); - } + if (rtype == OACK) + return (tftp_getnextblock(h)); + + /* Server ignored our blksize request, revert to TFTP default. */ + h->tftp_blksize = SEGSIZE; switch (rtype) { case DATA: { h->currblock = 1; h->validsize = res; h->islastblock = 0; - if (res < h->tftp_blksize) + if (res < h->tftp_blksize) { h->islastblock = 1; /* very short file */ + tftp_sendack(h); + } return (0); } case ERROR: @@ -320,7 +386,7 @@ tftp_getnextblock(struct tftp_handle *h) return (0); } -static int +static int tftp_open(const char *path, struct open_file *f) { struct tftp_handle *tftpfile; @@ -365,7 +431,7 @@ tftp_open(const char *path, struct open_file *f) return (0); } -static int +static int tftp_read(struct open_file *f, void *addr, size_t size, size_t *resid /* out */) { @@ -381,9 +447,11 @@ tftp_read(struct open_file *f, void *addr, size_t size, needblock = tftpfile->off / tftpfile->tftp_blksize + 1; - if (tftpfile->currblock > needblock) /* seek backwards */ + if (tftpfile->currblock > needblock) { /* seek backwards */ + tftp_senderr(tftpfile, 0, "No error: read aborted"); tftp_makereq(tftpfile); /* no error check, it worked * for open */ + } while (tftpfile->currblock < needblock) { int res; @@ -452,7 +520,7 @@ tftp_close(struct open_file *f) return (0); } -static int +static int tftp_write(struct open_file *f __unused, void *start __unused, size_t size __unused, size_t *resid __unused /* out */) { @@ -473,7 +541,7 @@ tftp_stat(struct open_file *f, struct stat *sb) return (0); } -static off_t +static off_t tftp_seek(struct open_file *f, off_t offset, int where) { struct tftp_handle *tftpfile; @@ -494,7 +562,7 @@ tftp_seek(struct open_file *f, off_t offset, int where) } static ssize_t -sendrecv_tftp(struct tftp_handle *h, +sendrecv_tftp(struct tftp_handle *h, ssize_t (*sproc)(struct iodesc *, void *, size_t), void *sbuf, size_t ssize, ssize_t (*rproc)(struct tftp_handle *, void *, ssize_t, time_t, unsigned short *), @@ -562,9 +630,9 @@ tftp_set_blksize(struct tftp_handle *h, const char *str) /* * Only accept blksize value if it is numeric. - * RFC2348 specifies that acceptable valuesare 8-65464 - * 8-65464 . Let's choose a limit less than MAXRSPACE - */ + * RFC2348 specifies that acceptable values are 8-65464. + * Let's choose a limit less than MAXRSPACE. + */ if (*endptr == '\0' && new_blksize >= 8 && new_blksize <= TFTP_MAX_BLKSIZE) { h->tftp_blksize = new_blksize; @@ -597,13 +665,12 @@ tftp_set_blksize(struct tftp_handle *h, const char *str) * optN, valueN * The final option/value acknowledgment pair. */ -static void +static int tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) { /* * We parse the OACK strings into an array * of name-value pairs. - * */ char *tftp_options[128] = { 0 }; char *val = buf; @@ -612,18 +679,22 @@ tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) int blksize_is_set = 0; int tsize = 0; - - while ( option_idx < 128 && i < len ) { - if (buf[i] == '\0') { - if (&buf[i] > val) { - tftp_options[option_idx] = val; - val = &buf[i] + 1; - ++option_idx; - } - } - ++i; + unsigned int orig_blksize; + + while (option_idx < 128 && i < len) { + if (buf[i] == '\0') { + if (&buf[i] > val) { + tftp_options[option_idx] = val; + val = &buf[i] + 1; + ++option_idx; + } + } + ++i; } + /* Save the block size we requested for sanity check later. */ + orig_blksize = h->tftp_blksize; + /* * Parse individual TFTP options. * * "blksize" is specified in RFC2348. @@ -631,27 +702,37 @@ tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len) */ for (i = 0; i < option_idx; i += 2) { if (strcasecmp(tftp_options[i], "blksize") == 0) { - if (i + 1 < option_idx) { + if (i + 1 < option_idx) blksize_is_set = tftp_set_blksize(h, tftp_options[i + 1]); - } } else if (strcasecmp(tftp_options[i], "tsize") == 0) { - if (i + 1 < option_idx) { + if (i + 1 < option_idx) tsize = strtol(tftp_options[i + 1], (char **)NULL, 10); - } + } else { + /* Do not allow any options we did not expect to be ACKed. */ + printf("unexpected tftp option '%s'\n", tftp_options[i]); + return (-1); } } if (!blksize_is_set) { /* * If TFTP blksize was not set, try defaulting - * to the legacy TFTP blksize of 512 + * to the legacy TFTP blksize of SEGSIZE(512) */ - h->tftp_blksize = 512; + h->tftp_blksize = SEGSIZE; + } else if (h->tftp_blksize > orig_blksize) { + /* + * Server should not be proposing block sizes that + * exceed what we said we can handle. + */ + printf("unexpected blksize %u\n", h->tftp_blksize); + return (-1); } #ifdef TFTP_DEBUG printf("tftp_blksize: %u\n", h->tftp_blksize); printf("tftp_tsize: %lu\n", h->tftp_tsize); #endif + return 0; } From e71c21385e77385f15f967c055b9ec70b90e0f4f Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 24 Jun 2011 04:16:06 +0000 Subject: [PATCH 43/57] - Add additional information to the PnP info of USB HUBs children which is now required by bus_autoconf. - Allow interface class matching even if device class is vendor specific. - Update bus_autoconf tool to not generate system and subsystem match lines for the nomatch event. PR: misc/157903 MFC after: 14 days --- sys/dev/usb/usb_hub.c | 6 +++++- sys/dev/usb/usb_lookup.c | 7 ------- tools/tools/bus_autoconf/bus_autoconf.c | 9 +-------- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 351b1343dae5..12898ec2642c 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -1334,15 +1334,19 @@ uhub_child_pnpinfo_string(device_t parent, device_t child, "devclass=0x%02x devsubclass=0x%02x " "sernum=\"%s\" " "release=0x%04x " - "intclass=0x%02x intsubclass=0x%02x" "%s%s", + "mode=%s " + "intclass=0x%02x intsubclass=0x%02x " + "intprotocol=0x%02x " "%s%s", UGETW(res.udev->ddesc.idVendor), UGETW(res.udev->ddesc.idProduct), res.udev->ddesc.bDeviceClass, res.udev->ddesc.bDeviceSubClass, usb_get_serial(res.udev), UGETW(res.udev->ddesc.bcdDevice), + (res.udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device", iface->idesc->bInterfaceClass, iface->idesc->bInterfaceSubClass, + iface->idesc->bInterfaceProtocol, iface->pnpinfo ? " " : "", iface->pnpinfo ? iface->pnpinfo : ""); } else { diff --git a/sys/dev/usb/usb_lookup.c b/sys/dev/usb/usb_lookup.c index ced925e8fd77..3b2d16d48d51 100644 --- a/sys/dev/usb/usb_lookup.c +++ b/sys/dev/usb/usb_lookup.c @@ -105,13 +105,6 @@ usbd_lookup_id_by_info(const struct usb_device_id *id, usb_size_t sizeof_id, (id->bDeviceProtocol != info->bDeviceProtocol)) { continue; } - if ((info->bDeviceClass == 0xFF) && - (!(id->match_flag_vendor)) && - ((id->match_flag_int_class) || - (id->match_flag_int_subclass) || - (id->match_flag_int_protocol))) { - continue; - } if ((id->match_flag_int_class) && (id->bInterfaceClass != info->bInterfaceClass)) { continue; diff --git a/tools/tools/bus_autoconf/bus_autoconf.c b/tools/tools/bus_autoconf/bus_autoconf.c index 68688afb25a7..0f7dbd594524 100644 --- a/tools/tools/bus_autoconf/bus_autoconf.c +++ b/tools/tools/bus_autoconf/bus_autoconf.c @@ -148,15 +148,8 @@ usb_dump(struct usb_device_id *id, uint32_t nid) usb_dump_sub(id, &info); - if (info.is_iface) { + if (info.is_any) { printf("nomatch 10 {\n" - " match \"system\" \"USB\";\n" - " match \"subsystem\" \"INTERFACE\";\n" - " match \"mode\" \"%s\";\n", mode); - } else if (info.is_any) { - printf("nomatch 10 {\n" - " match \"system\" \"USB\";\n" - " match \"subsystem\" \"DEVICE\";\n" " match \"mode\" \"%s\";\n", mode); } else { return (n); From 160d9dc32be9a80a1ca5b6f842bbe59e7ed9c6da Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 24 Jun 2011 04:35:58 +0000 Subject: [PATCH 44/57] - Make sure we don't match the wrong device by adding a match for the bus the device belongs to. PR: misc/157903 MFC after: 14 days --- tools/tools/bus_autoconf/bus_autoconf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/tools/bus_autoconf/bus_autoconf.c b/tools/tools/bus_autoconf/bus_autoconf.c index 0f7dbd594524..38fbd29760d7 100644 --- a/tools/tools/bus_autoconf/bus_autoconf.c +++ b/tools/tools/bus_autoconf/bus_autoconf.c @@ -150,6 +150,7 @@ usb_dump(struct usb_device_id *id, uint32_t nid) if (info.is_any) { printf("nomatch 10 {\n" + " match \"bus\" \"uhub[0-9]+\";\n" " match \"mode\" \"%s\";\n", mode); } else { return (n); From f6c506d9cf5056e5165edcdfb1cb2078e026d435 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Fri, 24 Jun 2011 05:41:38 +0000 Subject: [PATCH 45/57] Acknowledge Edwin Groothuis for the major rewrite he did of the tftpd and tftp code to support TFTP blocksize. --- libexec/tftpd/tftpd.8 | 6 ++++++ usr.bin/tftp/tftp.1 | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8 index c8474d2582e5..96bd24cbb6d2 100644 --- a/libexec/tftpd/tftpd.8 +++ b/libexec/tftpd/tftpd.8 @@ -293,6 +293,12 @@ was introduced in support for the TFTP Blocksize Option (RFC2348) and the blksize2 option was introduced in .Fx 7.4 . +.Pp +Edwin Groothuis performed a major rewrite of the +.Nm +and +.Xr tftp 1 +code to support RFC2348. .Sh NOTES Files larger than 33488896 octets (65535 blocks) cannot be transferred without client and server supporting the TFTP blocksize option (RFC2348), diff --git a/usr.bin/tftp/tftp.1 b/usr.bin/tftp/tftp.1 index 8c583525b20a..02709c0c09ce 100644 --- a/usr.bin/tftp/tftp.1 +++ b/usr.bin/tftp/tftp.1 @@ -218,7 +218,7 @@ Toggle packet tracing. Toggle verbose mode. .El .Sh SEE ALSO -.Xr tftp 1 +.Xr tftpd 8 .Pp The following RFC's are supported: .Rs @@ -256,6 +256,12 @@ The .Nm command appeared in .Bx 4.3 . +.Pp +Edwin Groothuis performed a major rewrite of the +.Xr tftpd 8 +and +.Nm +code to support RFC2348. .Sh NOTES Because there is no user-login or validation within the From fdb6437f737f493d4a064fb1891bfc78024e06a1 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Fri, 24 Jun 2011 07:05:20 +0000 Subject: [PATCH 46/57] Remove duplicated header files --- usr.sbin/ancontrol/ancontrol.c | 1 - usr.sbin/ifmcstat/ifmcstat.c | 1 - usr.sbin/nfsd/nfsd.c | 1 - usr.sbin/pmcstat/pmcpl_calltree.c | 1 - usr.sbin/ppp/nat_cmd.c | 1 - usr.sbin/rpc.yppasswdd/yppasswdd_main.c | 1 - usr.sbin/rpc.ypupdated/update.c | 1 - usr.sbin/rpc.ypupdated/ypupdated_main.c | 1 - usr.sbin/rpc.ypupdated/ypupdated_server.c | 1 - usr.sbin/sysinstall/modules.c | 1 - usr.sbin/wpa/ndis_events/ndis_events.c | 2 -- usr.sbin/wpa/wpa_supplicant/Packet32.c | 1 - 12 files changed, 13 deletions(-) diff --git a/usr.sbin/ancontrol/ancontrol.c b/usr.sbin/ancontrol/ancontrol.c index 008970d9b08e..4a114538a19f 100644 --- a/usr.sbin/ancontrol/ancontrol.c +++ b/usr.sbin/ancontrol/ancontrol.c @@ -40,7 +40,6 @@ static const char copyright[] = "@(#) Copyright (c) 1997, 1998, 1999\ __FBSDID("$FreeBSD$"); #include -#include #include #include diff --git a/usr.sbin/ifmcstat/ifmcstat.c b/usr.sbin/ifmcstat/ifmcstat.c index e45e36d143c3..5ee432860d40 100644 --- a/usr.sbin/ifmcstat/ifmcstat.c +++ b/usr.sbin/ifmcstat/ifmcstat.c @@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c index 656cb143d179..c5cec5ead4f4 100644 --- a/usr.sbin/nfsd/nfsd.c +++ b/usr.sbin/nfsd/nfsd.c @@ -71,7 +71,6 @@ static const char rcsid[] = #include #include #include -#include /* Global defs */ #ifdef DEBUG diff --git a/usr.sbin/pmcstat/pmcpl_calltree.c b/usr.sbin/pmcstat/pmcpl_calltree.c index c647a325a020..af3317a36def 100644 --- a/usr.sbin/pmcstat/pmcpl_calltree.c +++ b/usr.sbin/pmcstat/pmcpl_calltree.c @@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include diff --git a/usr.sbin/ppp/nat_cmd.c b/usr.sbin/ppp/nat_cmd.c index 48f894aedc47..accb149315ce 100644 --- a/usr.sbin/ppp/nat_cmd.c +++ b/usr.sbin/ppp/nat_cmd.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/usr.sbin/rpc.yppasswdd/yppasswdd_main.c b/usr.sbin/rpc.yppasswdd/yppasswdd_main.c index 8c8969165274..38719c4a5c1a 100644 --- a/usr.sbin/rpc.yppasswdd/yppasswdd_main.c +++ b/usr.sbin/rpc.yppasswdd/yppasswdd_main.c @@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$"); #include #include #include /* getenv, exit */ -#include #include /* strcmp */ #include #include diff --git a/usr.sbin/rpc.ypupdated/update.c b/usr.sbin/rpc.ypupdated/update.c index 72a7128beb21..956b057ac9c3 100644 --- a/usr.sbin/rpc.ypupdated/update.c +++ b/usr.sbin/rpc.ypupdated/update.c @@ -57,7 +57,6 @@ static const char rcsid[] = #include #include #include -#include #include "ypupdated_extern.h" #ifdef YP diff --git a/usr.sbin/rpc.ypupdated/ypupdated_main.c b/usr.sbin/rpc.ypupdated/ypupdated_main.c index c13af7df4340..92d8374a7162 100644 --- a/usr.sbin/rpc.ypupdated/ypupdated_main.c +++ b/usr.sbin/rpc.ypupdated/ypupdated_main.c @@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include "ypupdated_extern.h" #include "yp_extern.h" diff --git a/usr.sbin/rpc.ypupdated/ypupdated_server.c b/usr.sbin/rpc.ypupdated/ypupdated_server.c index c9a50dd36e0c..c4e163a50919 100644 --- a/usr.sbin/rpc.ypupdated/ypupdated_server.c +++ b/usr.sbin/rpc.ypupdated/ypupdated_server.c @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include "ypupdate_prot.h" #include "ypupdated_extern.h" diff --git a/usr.sbin/sysinstall/modules.c b/usr.sbin/sysinstall/modules.c index e9bdb0fe22e9..9c9875fa6b19 100644 --- a/usr.sbin/sysinstall/modules.c +++ b/usr.sbin/sysinstall/modules.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/usr.sbin/wpa/ndis_events/ndis_events.c b/usr.sbin/wpa/ndis_events/ndis_events.c index e3cd9b5bda57..9c6e9def54a9 100644 --- a/usr.sbin/wpa/ndis_events/ndis_events.c +++ b/usr.sbin/wpa/ndis_events/ndis_events.c @@ -42,11 +42,9 @@ __FBSDID("$FreeBSD$"); */ #include -#include #include #include #include -#include #include #include #include diff --git a/usr.sbin/wpa/wpa_supplicant/Packet32.c b/usr.sbin/wpa/wpa_supplicant/Packet32.c index 07da3590308e..876417e6635a 100644 --- a/usr.sbin/wpa/wpa_supplicant/Packet32.c +++ b/usr.sbin/wpa/wpa_supplicant/Packet32.c @@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include From aa7e4bb4663ca1167a0c9de643091ffaffebdc4f Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Fri, 24 Jun 2011 07:18:44 +0000 Subject: [PATCH 47/57] Remove duplicated header files --- usr.bin/ktrace/ktrace.c | 1 - usr.bin/ncplogin/ncplogin.c | 2 -- usr.bin/systat/netstat.c | 1 - usr.bin/tftp/main.c | 1 - usr.bin/vmstat/vmstat.c | 1 - 5 files changed, 6 deletions(-) diff --git a/usr.bin/ktrace/ktrace.c b/usr.bin/ktrace/ktrace.c index fa2fa1a9087a..4490849c6655 100644 --- a/usr.bin/ktrace/ktrace.c +++ b/usr.bin/ktrace/ktrace.c @@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include diff --git a/usr.bin/ncplogin/ncplogin.c b/usr.bin/ncplogin/ncplogin.c index 05b95c14e38e..edb903e70a01 100644 --- a/usr.bin/ncplogin/ncplogin.c +++ b/usr.bin/ncplogin/ncplogin.c @@ -42,8 +42,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include #include #include diff --git a/usr.bin/systat/netstat.c b/usr.bin/systat/netstat.c index 2f8ca0a4b0a7..b1c6dc9e3f14 100644 --- a/usr.bin/systat/netstat.c +++ b/usr.bin/systat/netstat.c @@ -63,7 +63,6 @@ static const char sccsid[] = "@(#)netstat.c 8.1 (Berkeley) 6/6/93"; #define TCPSTATES #include #include -#include #include #include #include diff --git a/usr.bin/tftp/main.c b/usr.bin/tftp/main.c index 2bdcf5fde497..da0e5df1ad5f 100644 --- a/usr.bin/tftp/main.c +++ b/usr.bin/tftp/main.c @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c index cda77adc33de..d31fdb54502e 100644 --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -43,7 +43,6 @@ static char sccsid[] = "@(#)vmstat.c 8.1 (Berkeley) 6/6/93"; __FBSDID("$FreeBSD$"); #include -#include #include #include #include From ecd9e552d0671a9bb49d3193527f04b5e04e9632 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Fri, 24 Jun 2011 07:29:04 +0000 Subject: [PATCH 48/57] Remove duplicated header files --- bin/rcp/rcp.c | 1 - bin/sh/mkinit.c | 1 - sbin/savecore/savecore.c | 1 - 3 files changed, 3 deletions(-) diff --git a/bin/rcp/rcp.c b/bin/rcp/rcp.c index 2c27b639f21f..4577b208f045 100644 --- a/bin/rcp/rcp.c +++ b/bin/rcp/rcp.c @@ -71,7 +71,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include "extern.h" diff --git a/bin/sh/mkinit.c b/bin/sh/mkinit.c index 866b238042f9..1d1d93edaf9d 100644 --- a/bin/sh/mkinit.c +++ b/bin/sh/mkinit.c @@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$"); */ -#include #include #include #include diff --git a/sbin/savecore/savecore.c b/sbin/savecore/savecore.c index d54fcf59ac45..ea715f345c22 100644 --- a/sbin/savecore/savecore.c +++ b/sbin/savecore/savecore.c @@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include From 2485d8a793b882e77fe7be4dc1a034390c96abbb Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 24 Jun 2011 11:14:09 +0000 Subject: [PATCH 49/57] - Add two new API's to libusb20 which can be used to retrive information about the parent USB device: - libusb20_dev_get_parent_address - libusb20_dev_get_parent_port - Rename libusb20_compat01.c into libusb01.c MFC after: 3 days --- lib/libusb/Makefile | 4 +++- .../{libusb20_compat01.c => libusb01.c} | 0 lib/libusb/libusb20.3 | 23 +++++++++++++++++++ lib/libusb/libusb20.c | 12 ++++++++++ lib/libusb/libusb20.h | 2 ++ lib/libusb/libusb20_int.h | 2 ++ lib/libusb/libusb20_ugen20.c | 5 ++++ 7 files changed, 47 insertions(+), 1 deletion(-) rename lib/libusb/{libusb20_compat01.c => libusb01.c} (100%) diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile index debbfa285656..f438cff3dec2 100644 --- a/lib/libusb/Makefile +++ b/lib/libusb/Makefile @@ -22,7 +22,7 @@ MLINKS+= libusb.3 usb.3 # libusb 0.1 compat INCS+= usb.h -SRCS+= libusb20_compat01.c +SRCS+= libusb01.c # libusb 1.0 compat INCS+= libusb.h @@ -184,6 +184,8 @@ MLINKS += libusb20.3 libusb20_dev_get_device_desc.3 MLINKS += libusb20.3 libusb20_dev_alloc_config.3 MLINKS += libusb20.3 libusb20_dev_alloc.3 MLINKS += libusb20.3 libusb20_dev_get_address.3 +MLINKS += libusb20.3 libusb20_dev_get_parent_address.3 +MLINKS += libusb20.3 libusb20_dev_get_parent_port.3 MLINKS += libusb20.3 libusb20_dev_get_bus_number.3 MLINKS += libusb20.3 libusb20_dev_get_mode.3 MLINKS += libusb20.3 libusb20_dev_get_speed.3 diff --git a/lib/libusb/libusb20_compat01.c b/lib/libusb/libusb01.c similarity index 100% rename from lib/libusb/libusb20_compat01.c rename to lib/libusb/libusb01.c diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3 index 93dfe18cf5be..042f8853657f 100644 --- a/lib/libusb/libusb20.3 +++ b/lib/libusb/libusb20.3 @@ -159,6 +159,10 @@ USB access library (libusb -lusb) .Ft uint8_t .Fn libusb20_dev_get_address "struct libusb20_device *pdev" .Ft uint8_t +.Fn libusb20_dev_get_parent_address "struct libusb20_device *pdev" +.Ft uint8_t +.Fn libusb20_dev_get_parent_port "struct libusb20_device *pdev" +.Ft uint8_t .Fn libusb20_dev_get_bus_number "struct libusb20_device *pdev" .Ft uint8_t .Fn libusb20_dev_get_mode "struct libusb20_device *pdev" @@ -756,12 +760,31 @@ is an internal function to allocate a new USB device. .Fn libusb20_dev_get_address returns the internal and not necessarily the real hardware address of the given USB device. +Valid addresses start at one. +. +.Pp +. +.Fn libusb20_dev_get_parent_address +returns the internal and not necessarily the real hardware address of +the given parent USB HUB device. +This value is zero for the root HUB which usually has a device address +equal to one. +Valid addresses start at one. +. +.Pp +. +.Fn libusb20_dev_get_parent_port +returns the port number on the parent USB HUB device. +This value is zero for the root HUB which usually has a device address +equal to one. +Valid port numbers start at one. . .Pp . .Fn libusb20_dev_get_bus_number returns the internal bus number which the given USB device belongs to. +Valid bus numbers start at zero. . .Pp . diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c index bcaa1e47ff13..716f5403529d 100644 --- a/lib/libusb/libusb20.c +++ b/lib/libusb/libusb20.c @@ -1056,6 +1056,18 @@ libusb20_dev_get_address(struct libusb20_device *pdev) return (pdev->device_address); } +uint8_t +libusb20_dev_get_parent_address(struct libusb20_device *pdev) +{ + return (pdev->parent_address); +} + +uint8_t +libusb20_dev_get_parent_port(struct libusb20_device *pdev) +{ + return (pdev->parent_port); +} + uint8_t libusb20_dev_get_bus_number(struct libusb20_device *pdev) { diff --git a/lib/libusb/libusb20.h b/lib/libusb/libusb20.h index 958a379ed254..22a2899bbd80 100644 --- a/lib/libusb/libusb20.h +++ b/lib/libusb/libusb20.h @@ -262,6 +262,8 @@ struct LIBUSB20_DEVICE_DESC_DECODED *libusb20_dev_get_device_desc(struct libusb2 struct libusb20_config *libusb20_dev_alloc_config(struct libusb20_device *pdev, uint8_t config_index); struct libusb20_device *libusb20_dev_alloc(void); uint8_t libusb20_dev_get_address(struct libusb20_device *pdev); +uint8_t libusb20_dev_get_parent_address(struct libusb20_device *pdev); +uint8_t libusb20_dev_get_parent_port(struct libusb20_device *pdev); uint8_t libusb20_dev_get_bus_number(struct libusb20_device *pdev); uint8_t libusb20_dev_get_mode(struct libusb20_device *pdev); uint8_t libusb20_dev_get_speed(struct libusb20_device *pdev); diff --git a/lib/libusb/libusb20_int.h b/lib/libusb/libusb20_int.h index 2ecfb4770a39..bef4d02737c5 100644 --- a/lib/libusb/libusb20_int.h +++ b/lib/libusb/libusb20_int.h @@ -226,6 +226,8 @@ struct libusb20_device { uint8_t usb_mode; uint8_t usb_speed; uint8_t is_opened; + uint8_t parent_address; + uint8_t parent_port; char usb_desc[96]; }; diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c index 933d7286b679..307ed96d2274 100644 --- a/lib/libusb/libusb20_ugen20.c +++ b/lib/libusb/libusb20_ugen20.c @@ -195,6 +195,11 @@ ugen20_enumerate(struct libusb20_device *pdev, const char *id) break; } + /* get parent HUB index and port */ + + pdev->parent_address = devinfo.udi_hubindex; + pdev->parent_port = devinfo.udi_hubport; + /* generate a nice description for printout */ snprintf(pdev->usb_desc, sizeof(pdev->usb_desc), From 796fd09a9074ebe1df82f5e08307b31e28c1cd71 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 24 Jun 2011 12:30:43 +0000 Subject: [PATCH 50/57] Import one of the two missing US FCC DFS bands to FCC3. The FCC opened up this band sometime in 2009 (and ath was updated); but regdomain.xml wasn't updated. --- etc/regdomain.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/etc/regdomain.xml b/etc/regdomain.xml index d95000c5c0a4..ed25056a7bdf 100644 --- a/etc/regdomain.xml +++ b/etc/regdomain.xml @@ -137,6 +137,12 @@ 17 + + + 20 + IEEE80211_CHAN_PASSIVE + IEEE80211_CHAN_DFS + 23 @@ -175,6 +181,20 @@ 17 IEEE80211_CHAN_HT40 + + + 20 + IEEE80211_CHAN_HT20 + IEEE80211_CHAN_PASSIVE + IEEE80211_CHAN_DFS + + + + 20 + IEEE80211_CHAN_HT40 + IEEE80211_CHAN_PASSIVE + IEEE80211_CHAN_DFS + 23 From 74024442b760cd55ce3371117967b587820b317c Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 24 Jun 2011 12:31:36 +0000 Subject: [PATCH 51/57] Fix an incorrect frequency band for HT/40 in the FCC SKU. Noticed by: bschmidt@ --- etc/regdomain.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/regdomain.xml b/etc/regdomain.xml index ed25056a7bdf..5d89846f82f9 100644 --- a/etc/regdomain.xml +++ b/etc/regdomain.xml @@ -83,7 +83,7 @@ IEEE80211_CHAN_HT20 - + 30 IEEE80211_CHAN_G IEEE80211_CHAN_HT40 From 9b9fc082bafa3f29eab4bf420692507c97d08a6d Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 24 Jun 2011 12:50:18 +0000 Subject: [PATCH 52/57] More incorrect HT/40 setups in FCC. Noticed-by: bschmidt@ --- etc/regdomain.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/regdomain.xml b/etc/regdomain.xml index 5d89846f82f9..9f7a7a3fb7e6 100644 --- a/etc/regdomain.xml +++ b/etc/regdomain.xml @@ -96,7 +96,7 @@ IEEE80211_CHAN_HT20 - + 17 IEEE80211_CHAN_HT40 @@ -106,7 +106,7 @@ IEEE80211_CHAN_HT20 - + 23 IEEE80211_CHAN_HT40 From 6ca60beb2592d0075cd23fae8f9bb78120bb2fdd Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 24 Jun 2011 12:55:16 +0000 Subject: [PATCH 53/57] Actually, if code had followed style(9), there would be less stupid errors like the one fixed in r223416. Noticed by: julian --- sbin/ipfw/nat.c | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/sbin/ipfw/nat.c b/sbin/ipfw/nat.c index efadeba3cef3..c95a625d5e9b 100644 --- a/sbin/ipfw/nat.c +++ b/sbin/ipfw/nat.c @@ -738,7 +738,8 @@ ipfw_config_nat(int ac, char **av) char *id, *buf, **av1, *end; size_t len; - av++; ac--; + av++; + ac--; /* Nat id. */ if (ac == 0) errx(EX_DATAERR, "missing nat id"); @@ -746,7 +747,8 @@ ipfw_config_nat(int ac, char **av) i = (int)strtol(id, &end, 0); if (i <= 0 || *end != '\0') errx(EX_DATAERR, "illegal nat id: %s", id); - av++; ac--; + av++; + ac--; if (ac == 0) errx(EX_DATAERR, "missing option"); @@ -755,11 +757,13 @@ ipfw_config_nat(int ac, char **av) av1 = av; while (ac1 > 0) { tok = match_token(nat_params, *av1); - ac1--; av1++; + ac1--; + av1++; switch (tok) { case TOK_IP: case TOK_IF: - ac1--; av1++; + ac1--; + av1++; break; case TOK_ALOG: case TOK_DENY_INC: @@ -775,18 +779,22 @@ ipfw_config_nat(int ac, char **av) errx(EX_DATAERR, "redirect_addr: " "not enough arguments"); len += estimate_redir_addr(&ac1, &av1); - av1 += 2; ac1 -= 2; + av1 += 2; + ac1 -= 2; break; case TOK_REDIR_PORT: if (ac1 < 3) errx(EX_DATAERR, "redirect_port: " "not enough arguments"); - av1++; ac1--; + av1++; + ac1--; len += estimate_redir_port(&ac1, &av1); - av1 += 2; ac1 -= 2; + av1 += 2; + ac1 -= 2; /* Skip optional remoteIP/port */ if (ac1 != 0 && isdigit(**av1)) { - av1++; ac1--; + av1++; + ac1--; } break; case TOK_REDIR_PROTO: @@ -794,13 +802,16 @@ ipfw_config_nat(int ac, char **av) errx(EX_DATAERR, "redirect_proto: " "not enough arguments"); len += sizeof(struct cfg_redir); - av1 += 2; ac1 -= 2; + av1 += 2; + ac1 -= 2; /* Skip optional remoteIP/port */ if (ac1 != 0 && isdigit(**av1)) { - av1++; ac1--; + av1++; + ac1--; } if (ac1 != 0 && isdigit(**av1)) { - av1++; ac1--; + av1++; + ac1--; } break; default: @@ -819,7 +830,8 @@ ipfw_config_nat(int ac, char **av) while (ac > 0) { tok = match_token(nat_params, *av); - ac--; av++; + ac--; + av++; switch (tok) { case TOK_IP: if (ac == 0) @@ -827,13 +839,15 @@ ipfw_config_nat(int ac, char **av) if (!inet_aton(av[0], &(n->ip))) errx(EX_DATAERR, "bad ip address ``%s''", av[0]); - ac--; av++; + ac--; + av++; break; case TOK_IF: if (ac == 0) errx(EX_DATAERR, "missing option"); set_addr_dynamic(av[0], n); - ac--; av++; + ac--; + av++; break; case TOK_ALOG: n->mode |= PKT_ALIAS_LOG; @@ -912,7 +926,8 @@ ipfw_show_nat(int ac, char **av) data = NULL; frule = 0; lrule = IPFW_DEFAULT_RULE; /* max ipfw rule number */ - ac--; av++; + ac--; + av++; if (co.test_only) return; From f6133e7144c5f199313e7d58bd2748c81dbc3a55 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 24 Jun 2011 13:58:56 +0000 Subject: [PATCH 54/57] Typo. --- sys/dev/acpica/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 84f65bd8fde9..9352be9c3377 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -1244,7 +1244,7 @@ acpi_alloc_resource(device_t bus, device_t child, int type, int *rid, /* * First attempt at allocating the resource. For direct children, * use resource_list_alloc() to handle reserved resources. For - * other dveices, pass the request up to our parent. + * other devices, pass the request up to our parent. */ if (bus == device_get_parent(child)) { ad = device_get_ivars(child); From 0b73ba9c979eb22cc9ccb757c52dc03884ccc847 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 24 Jun 2011 14:31:30 +0000 Subject: [PATCH 55/57] Fix another broken HT40 channel band reference. --- etc/regdomain.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/regdomain.xml b/etc/regdomain.xml index 9f7a7a3fb7e6..5e98deab00e0 100644 --- a/etc/regdomain.xml +++ b/etc/regdomain.xml @@ -251,7 +251,7 @@ IEEE80211_CHAN_HT20 - + 30 IEEE80211_CHAN_G IEEE80211_CHAN_HT40 From 5e26234ff1d4a8c996e8cde39f591dbfad89a62f Mon Sep 17 00:00:00 2001 From: Jonathan Anderson Date: Fri, 24 Jun 2011 14:40:22 +0000 Subject: [PATCH 56/57] Tidy up a capabilities-related comment. This comment refers to an #ifdef that hasn't been merged [yet?]; remove it. Approved by: rwatson --- sys/kern/vfs_subr.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 741061d639ef..c5ae83cbf47b 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -3590,9 +3590,6 @@ vn_isdisk(struct vnode *vp, int *errp) * and optional call-by-reference privused argument allowing vaccess() * to indicate to the caller whether privilege was used to satisfy the * request (obsoleted). Returns 0 on success, or an errno on failure. - * - * The ifdef'd CAPABILITIES version is here for reference, but is not - * actually used. */ int vaccess(enum vtype type, mode_t file_mode, uid_t file_uid, gid_t file_gid, From f253603f0cc712ea9d6888a27aba788f1324b176 Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Fri, 24 Jun 2011 14:56:38 +0000 Subject: [PATCH 57/57] Add support for string values with white spaces for ifconfig(8) parameters accepting them (such as description, group). Changes discussed on freebsd-rc. PR: conf/156675 Reported by: "Alexander V. Chernikov" Suggested by: hrs Analyzed with: Alexander V. Chernikov via IRC MFC after: 2 weeks --- etc/network.subr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/network.subr b/etc/network.subr index f9a1f88f4029..44a58925c702 100644 --- a/etc/network.subr +++ b/etc/network.subr @@ -94,7 +94,7 @@ ifconfig_up() # ifconfig_IF ifconfig_args=`ifconfig_getargs $1` if [ -n "${ifconfig_args}" ]; then - ifconfig $1 ${ifconfig_args} + eval ifconfig $1 ${ifconfig_args} _cfg=0 fi