This commit is contained in:
Attilio Rao 2011-06-26 17:30:46 +00:00
commit cfdfd32d34
82 changed files with 6094 additions and 762 deletions

View File

@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
.Dd June 18, 2011
.Dd June 24, 2011
.Dt SH 1
.Os
.Sh NAME
@ -994,11 +994,22 @@ described later),
separated by
.Ql \&|
characters.
Tilde expansion, parameter expansion, command substitution,
arithmetic expansion and quote removal are applied to the word.
Then, each pattern is expanded in turn using tilde expansion,
parameter expansion, command substitution and arithmetic expansion and
the expanded form of the word is checked against it.
If a match is found, the corresponding list is executed.
If the selected list is terminated by the control operator
.Ql ;&
instead of
.Ql ;; ,
execution continues with the next list.
execution continues with the next list,
continuing until a list terminated with
.Ql ;;
or the end of the
.Ic case
command.
The exit code of the
.Ic case
command is the exit code of the last command executed in the list or
@ -1618,15 +1629,15 @@ There are two restrictions on this: first, a pattern cannot match
a string containing a slash, and second,
a pattern cannot match a string starting with a period
unless the first character of the pattern is a period.
The next section describes the patterns used for both
Pathname Expansion and the
The next section describes the patterns used for
Pathname Expansion,
the four varieties of parameter expansion for substring processing and the
.Ic case
command.
.Ss Shell Patterns
A pattern consists of normal characters, which match themselves,
and meta-characters.
The meta-characters are
.Ql \&! ,
.Ql * ,
.Ql \&? ,
and
@ -1656,7 +1667,7 @@ matches a
.Ql \&[
rather than introducing a character class.
A character class matches any of the characters between the square brackets.
A range of characters may be specified using a minus sign.
A locale-dependent range of characters may be specified using a minus sign.
A named class of characters (see
.Xr wctype 3 )
may be specified by surrounding the name with
@ -1669,12 +1680,17 @@ is a shell pattern that matches a single letter.
The character class may be complemented by making an exclamation point
.Pq Ql !\&
the first character of the character class.
A caret
.Pq Ql ^
has the same effect but is non-standard.
.Pp
To include a
.Ql \&]
in a character class, make it the first character listed
(after the
.Ql \&! ,
.Ql \&!
or
.Ql ^ ,
if any).
To include a
.Ql - ,

View File

@ -1,6 +1,6 @@
# $FreeBSD$
FILES= asus.conf uath.conf
FILES= asus.conf uath.conf usb.conf
NO_OBJ=
FILESDIR= /etc/devd

View File

@ -3,13 +3,13 @@
# Atheros USB wireless network device specific devd events
# Accton
# SMCWUSB-G and SMCWUSBT-G2
# SMCWUSBT-G2
notify 100 {
match "system" "USB";
match "subsystem" "DEVICE";
match "type" "ATTACH";
match "vendor" "0x083a";
match "product" "(0x4505|0x4507)";
match "product" "0x4507";
action "/usr/sbin/uathload -d /dev/$cdev";
};

4275
etc/devd/usb.conf Normal file

File diff suppressed because it is too large Load Diff

View File

@ -139,7 +139,19 @@
</band>
<band>
<freqband ref="F1_5260_5320"/>
<maxpower>20</maxpower>
<maxpower>23</maxpower>
<flags>IEEE80211_CHAN_PASSIVE</flags>
<flags>IEEE80211_CHAN_DFS</flags>
</band>
<band>
<freqband ref="F1_5500_5580"/>
<maxpower>23</maxpower>
<flags>IEEE80211_CHAN_PASSIVE</flags>
<flags>IEEE80211_CHAN_DFS</flags>
</band>
<band>
<freqband ref="F1_5660_5700"/>
<maxpower>23</maxpower>
<flags>IEEE80211_CHAN_PASSIVE</flags>
<flags>IEEE80211_CHAN_DFS</flags>
</band>
@ -183,14 +195,42 @@
</band>
<band>
<freqband ref="F1_5260_5320"/>
<maxpower>20</maxpower>
<maxpower>23</maxpower>
<flags>IEEE80211_CHAN_HT20</flags>
<flags>IEEE80211_CHAN_PASSIVE</flags>
<flags>IEEE80211_CHAN_DFS</flags>
</band>
<band>
<freqband ref="H4_5260_5320"/>
<maxpower>20</maxpower>
<maxpower>23</maxpower>
<flags>IEEE80211_CHAN_HT40</flags>
<flags>IEEE80211_CHAN_PASSIVE</flags>
<flags>IEEE80211_CHAN_DFS</flags>
</band>
<band>
<freqband ref="F1_5500_5580"/>
<maxpower>23</maxpower>
<flags>IEEE80211_CHAN_HT20</flags>
<flags>IEEE80211_CHAN_PASSIVE</flags>
<flags>IEEE80211_CHAN_DFS</flags>
</band>
<band>
<freqband ref="H4_5500_5580"/>
<maxpower>23</maxpower>
<flags>IEEE80211_CHAN_HT40</flags>
<flags>IEEE80211_CHAN_PASSIVE</flags>
<flags>IEEE80211_CHAN_DFS</flags>
</band>
<band>
<freqband ref="F1_5660_5700"/>
<maxpower>23</maxpower>
<flags>IEEE80211_CHAN_HT20</flags>
<flags>IEEE80211_CHAN_PASSIVE</flags>
<flags>IEEE80211_CHAN_DFS</flags>
</band>
<band>
<freqband ref="H4_5660_5700"/>
<maxpower>23</maxpower>
<flags>IEEE80211_CHAN_HT40</flags>
<flags>IEEE80211_CHAN_PASSIVE</flags>
<flags>IEEE80211_CHAN_DFS</flags>
@ -341,9 +381,9 @@
<sku>0x30</sku>
<netband mode="11b">
<band>
<freqband ref="F1_2412_2472"/>
<maxpower>30</maxpower>
<flags>IEEE80211_CHAN_B</flags>
<freqband ref="F1_2412_2472"/>
<maxpower>30</maxpower>
<flags>IEEE80211_CHAN_B</flags>
</band>
</netband>
<netband mode="11g">
@ -1644,6 +1684,16 @@
<chanwidth>40</chanwidth> <chansep>20</chansep>
<flags>IEEE80211_CHAN_A</flags>
</freqband>
<freqband id="F1_5500_5580">
<freqstart>5500</freqstart> <freqend>5580</freqend>
<chanwidth>20</chanwidth> <chansep>20</chansep>
<flags>IEEE80211_CHAN_A</flags>
</freqband>
<freqband id="H4_5500_5580">
<freqstart>5500</freqstart> <freqend>5580</freqend>
<chanwidth>40</chanwidth> <chansep>20</chansep>
<flags>IEEE80211_CHAN_A</flags>
</freqband>
<freqband id="F1_5500_5620">
<freqstart>5500</freqstart> <freqend>5620</freqend>
<chanwidth>20</chanwidth> <chansep>20</chansep>
@ -1664,6 +1714,16 @@
<chanwidth>20</chanwidth> <chansep>20</chansep>
<flags>IEEE80211_CHAN_A</flags>
</freqband>
<freqband id="F1_5660_5700">
<freqstart>5660</freqstart> <freqend>5700</freqend>
<chanwidth>20</chanwidth> <chansep>20</chansep>
<flags>IEEE80211_CHAN_A</flags>
</freqband>
<freqband id="H4_5660_5700">
<freqstart>5660</freqstart> <freqend>5700</freqend>
<chanwidth>40</chanwidth> <chansep>20</chansep>
<flags>IEEE80211_CHAN_A</flags>
</freqband>
<freqband id="H4_5725_5825">
<freqstart>5725</freqstart> <freqend>5825</freqend>
<chanwidth>40</chanwidth> <chansep>20</chansep>

View File

@ -1,6 +1,6 @@
# $FreeBSD$
SUBDIR= doc tools lib libexec usr.bin usr.sbin
SUBDIR= doc lib libexec usr.bin usr.sbin
# These are the programs which depend on Kerberos.
KPROGS= lib/libpam \

View File

@ -19,6 +19,8 @@ INCS= libprocstat.h
CFLAGS+= -I. -I${.CURDIR} -D_KVM_VNODE
SHLIB_MAJOR= 1
WITHOUT_MAN= yes
DPADD= ${LIBKVM} ${LIBUTIL}
LDADD= -lkvm -lutil
.if ${MK_NCP} != "no"
CFLAGS+= -DLIBPROCSTAT_NWFS

View File

@ -91,7 +91,6 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/at91var.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91sam9g20reg.h>
#include <arm/at91/at91board.h>
#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
#define KERNEL_PT_KERN 1

View File

@ -130,7 +130,7 @@ options ATH_DIAGAPI
#options ATH_TX99_DIAG
device ath_rate_sample # SampleRate tx rate control for ath
options AH_DEBUG
#options AH_DEBUG
#options AH_ASSERT
options AH_PRIVATE_DIAG
#device ath_ar5210

View File

@ -77,7 +77,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>

View File

@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/reboot.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/module.h>
#include <sys/rman.h>
@ -74,7 +73,6 @@ __FBSDID("$FreeBSD$");
#include <arm/sa11x0/sa11x0_dmacreg.h>
#include <arm/sa11x0/sa11x0_ppcreg.h>
#include <arm/sa11x0/sa11x0_gpioreg.h>
#include <machine/bus.h>
extern void sa11x0_activateirqs(void);

View File

@ -8,10 +8,6 @@
SUBDIR+= ficl
.endif
.if ${MK_FDT} != "no"
SUBDIR+= fdt
.endif
# Pick the machine-dependent subdir based on the target architecture.
ADIR= ${MACHINE:S/amd64/i386/:S/powerpc64/powerpc/}
.if exists(${.CURDIR}/${ADIR}/.)

View File

@ -1,3 +1,7 @@
# $FreeBSD$
.if ${MK_FDT} != "no"
SUBDIR+= fdt
.endif
SUBDIR+= uboot

View File

@ -1,4 +1,8 @@
# $FreeBSD$
.if ${MK_FDT} != "no"
SUBDIR+= fdt
.endif
SUBDIR+= ofw
SUBDIR+= uboot

View File

@ -4894,8 +4894,8 @@ camisr_runqueue(void *V_queue)
&& (--dev->tag_delay_count == 0))
xpt_start_tags(ccb_h->path);
if (!device_is_send_queued(dev)) {
runq = xpt_schedule_dev_sendq(ccb_h->path->bus,
dev);
(void)xpt_schedule_dev_sendq(ccb_h->path->bus,
dev);
}
}

View File

@ -687,6 +687,10 @@ cdregister(struct cam_periph *periph, void *arg)
else
softc->minimum_command_size = 6;
/*
* Refcount and block open attempts until we are setup
* Can't block
*/
(void)cam_periph_hold(periph, PRIBIO);
cam_periph_unlock(periph);
/*
@ -747,7 +751,6 @@ cdregister(struct cam_periph *periph, void *arg)
softc->disk->d_hba_subdevice = cpi.hba_subdevice;
disk_create(softc->disk, DISK_VERSION);
cam_periph_lock(periph);
cam_periph_unhold(periph);
/*
* Add an async callback so that we get
@ -972,12 +975,6 @@ cdregister(struct cam_periph *periph, void *arg)
cdregisterexit:
/*
* Refcount and block open attempts until we are setup
* Can't block
*/
(void)cam_periph_hold(periph, PRIBIO);
if ((softc->flags & CD_FLAG_CHANGER) == 0)
xpt_schedule(periph, CAM_PRIORITY_DEV);
else

View File

@ -1552,6 +1552,7 @@ dev/pci/isa_pci.c optional pci isa
dev/pci/pci.c optional pci
dev/pci/pci_if.m standard
dev/pci/pci_pci.c optional pci
dev/pci/pci_subr.c optional pci
dev/pci/pci_user.c optional pci
dev/pci/pcib_if.m standard
dev/pci/vga_pci.c optional pci

View File

@ -120,6 +120,7 @@ ia64/pci/pci_cfgreg.c optional pci
isa/syscons_isa.c optional sc
isa/vga_isa.c optional vga
kern/imgact_elf32.c optional compat_freebsd32
kern/kern_clocksource.c standard
libkern/bcmp.c standard
libkern/ffsl.c standard
libkern/fls.c standard

View File

@ -773,7 +773,8 @@ ATH_TXBUF opt_ath.h
ATH_RXBUF opt_ath.h
ATH_DIAGAPI opt_ath.h
ATH_TX99_DIAG opt_ath.h
ATH_ENABLE_11N opt_ah.h
ATH_ENABLE_11N opt_ath.h
ATH_ENABLE_DFS opt_ath.h
# options for the Atheros hal
AH_SUPPORT_AR5416 opt_ah.h

View File

@ -856,10 +856,8 @@ 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);
@ -929,11 +927,9 @@ acpi_cpu_idle()
/* Find the lowest state that has small enough latency. */
cx_next_idx = 0;
#ifndef __ia64__
if (cpu_disable_deep_sleep)
i = min(sc->cpu_cx_lowest, sc->cpu_non_c3);
else
#endif
i = sc->cpu_cx_lowest;
for (; i >= 0; i--) {
if (sc->cpu_cx_states[i].trans_lat * 3 <= sc->cpu_prev_sleep) {

View File

@ -76,6 +76,14 @@ 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 */
MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data");
@ -147,8 +155,6 @@ DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
#include <sys/pcpu.h>
#include <dev/ath/ath_hal/ah_decode.h>
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 */

View File

@ -528,8 +528,8 @@ extern int ath_hal_debug; /* Global debug flags */
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, ...)
#define HALDEBUG(_ah, __m, ...)
#define HALDEBUG_G(_ah, __m, ...)
#endif /* AH_DEBUG */
/*

View File

@ -528,6 +528,9 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
| IEEE80211_C_WPA /* capable of WPA1+WPA2 */
| IEEE80211_C_BGSCAN /* capable of bg scanning */
| IEEE80211_C_TXFRAG /* handle tx frags */
#ifdef ATH_ENABLE_DFS
| IEEE80211_C_DFS /* Enable DFS radar detection */
#endif
;
/*
* Query the hal to figure out h/w crypto support.
@ -1287,6 +1290,8 @@ ath_resume(struct ath_softc *sc)
HAL_GPIO_MUX_MAC_NETWORK_LED);
ath_hal_gpioset(ah, sc->sc_ledpin, !sc->sc_ledon);
}
/* XXX beacons ? */
}
void
@ -1589,6 +1594,12 @@ ath_init(void *arg)
sc->sc_lastani = 0;
sc->sc_lastshortcal = 0;
sc->sc_doresetcal = AH_FALSE;
/*
* Beacon timers were cleared here; give ath_newstate()
* a hint that the beacon timers should be poked when
* things transition to the RUN state.
*/
sc->sc_beacons = 0;
/*
* Setup the hardware after reset: the key cache
@ -4464,6 +4475,19 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
*/
ath_chan_change(sc, chan);
/*
* Reset clears the beacon timers; reset them
* here if needed.
*/
if (sc->sc_beacons) { /* restart beacons */
#ifdef IEEE80211_SUPPORT_TDMA
if (sc->sc_tdma)
ath_tdma_config(sc, NULL);
else
#endif
ath_beacon_config(sc, NULL);
}
/*
* Re-enable interrupts.
*/

View File

@ -38,16 +38,12 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/libkern.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pci_private.h>
@ -1432,91 +1428,3 @@ pcib_power_for_sleep(device_t pcib, device_t dev, int *pstate)
bus = device_get_parent(pcib);
return (PCIB_POWER_FOR_SLEEP(bus, dev, pstate));
}
/*
* Try to read the bus number of a host-PCI bridge using appropriate config
* registers.
*/
int
host_pcib_get_busno(pci_read_config_fn read_config, int bus, int slot, int func,
uint8_t *busnum)
{
uint32_t id;
id = read_config(bus, slot, func, PCIR_DEVVENDOR, 4);
if (id == 0xffffffff)
return (0);
switch (id) {
case 0x12258086:
/* Intel 824?? */
/* XXX This is a guess */
/* *busnum = read_config(bus, slot, func, 0x41, 1); */
*busnum = bus;
break;
case 0x84c48086:
/* Intel 82454KX/GX (Orion) */
*busnum = read_config(bus, slot, func, 0x4a, 1);
break;
case 0x84ca8086:
/*
* For the 450nx chipset, there is a whole bundle of
* things pretending to be host bridges. The MIOC will
* be seen first and isn't really a pci bridge (the
* actual busses are attached to the PXB's). We need to
* read the registers of the MIOC to figure out the
* bus numbers for the PXB channels.
*
* Since the MIOC doesn't have a pci bus attached, we
* pretend it wasn't there.
*/
return (0);
case 0x84cb8086:
switch (slot) {
case 0x12:
/* Intel 82454NX PXB#0, Bus#A */
*busnum = read_config(bus, 0x10, func, 0xd0, 1);
break;
case 0x13:
/* Intel 82454NX PXB#0, Bus#B */
*busnum = read_config(bus, 0x10, func, 0xd1, 1) + 1;
break;
case 0x14:
/* Intel 82454NX PXB#1, Bus#A */
*busnum = read_config(bus, 0x10, func, 0xd3, 1);
break;
case 0x15:
/* Intel 82454NX PXB#1, Bus#B */
*busnum = read_config(bus, 0x10, func, 0xd4, 1) + 1;
break;
}
break;
/* ServerWorks -- vendor 0x1166 */
case 0x00051166:
case 0x00061166:
case 0x00081166:
case 0x00091166:
case 0x00101166:
case 0x00111166:
case 0x00171166:
case 0x01011166:
case 0x010f1014:
case 0x01101166:
case 0x02011166:
case 0x02251166:
case 0x03021014:
*busnum = read_config(bus, slot, func, 0x44, 1);
break;
/* Compaq/HP -- vendor 0x0e11 */
case 0x60100e11:
*busnum = read_config(bus, slot, func, 0xc8, 1);
break;
default:
/* Don't know how to read bus number. */
return 0;
}
return 1;
}

130
sys/dev/pci/pci_subr.c Normal file
View File

@ -0,0 +1,130 @@
/*-
* Copyright (c) 2011 Advanced Computing Technologies LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* Support APIs for Host to PCI bridge drivers and drivers that
* provide PCI domains.
*/
#include <sys/types.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcib_private.h>
/*
* Try to read the bus number of a host-PCI bridge using appropriate config
* registers.
*/
int
host_pcib_get_busno(pci_read_config_fn read_config, int bus, int slot, int func,
uint8_t *busnum)
{
uint32_t id;
id = read_config(bus, slot, func, PCIR_DEVVENDOR, 4);
if (id == 0xffffffff)
return (0);
switch (id) {
case 0x12258086:
/* Intel 824?? */
/* XXX This is a guess */
/* *busnum = read_config(bus, slot, func, 0x41, 1); */
*busnum = bus;
break;
case 0x84c48086:
/* Intel 82454KX/GX (Orion) */
*busnum = read_config(bus, slot, func, 0x4a, 1);
break;
case 0x84ca8086:
/*
* For the 450nx chipset, there is a whole bundle of
* things pretending to be host bridges. The MIOC will
* be seen first and isn't really a pci bridge (the
* actual busses are attached to the PXB's). We need to
* read the registers of the MIOC to figure out the
* bus numbers for the PXB channels.
*
* Since the MIOC doesn't have a pci bus attached, we
* pretend it wasn't there.
*/
return (0);
case 0x84cb8086:
switch (slot) {
case 0x12:
/* Intel 82454NX PXB#0, Bus#A */
*busnum = read_config(bus, 0x10, func, 0xd0, 1);
break;
case 0x13:
/* Intel 82454NX PXB#0, Bus#B */
*busnum = read_config(bus, 0x10, func, 0xd1, 1) + 1;
break;
case 0x14:
/* Intel 82454NX PXB#1, Bus#A */
*busnum = read_config(bus, 0x10, func, 0xd3, 1);
break;
case 0x15:
/* Intel 82454NX PXB#1, Bus#B */
*busnum = read_config(bus, 0x10, func, 0xd4, 1) + 1;
break;
}
break;
/* ServerWorks -- vendor 0x1166 */
case 0x00051166:
case 0x00061166:
case 0x00081166:
case 0x00091166:
case 0x00101166:
case 0x00111166:
case 0x00171166:
case 0x01011166:
case 0x010f1014:
case 0x01101166:
case 0x02011166:
case 0x02251166:
case 0x03021014:
*busnum = read_config(bus, slot, func, 0x44, 1);
break;
/* Compaq/HP -- vendor 0x0e11 */
case 0x60100e11:
*busnum = read_config(bus, slot, func, 0xc8, 1);
break;
default:
/* Don't know how to read bus number. */
return 0;
}
return 1;
}

View File

@ -158,6 +158,8 @@ static int
i2s_probe(device_t self)
{
const char *name;
phandle_t subchild;
char subchildname[255];
name = ofw_bus_get_name(self);
if (!name)
@ -165,6 +167,16 @@ i2s_probe(device_t self)
if (strcmp(name, "i2s") != 0)
return (ENXIO);
/*
* Do not attach to "lightshow" I2S devices on Xserves. This controller
* is used there to control the LEDs on the front panel, and this
* driver can't handle it.
*/
subchild = OF_child(OF_child(ofw_bus_get_node(self)));
if (subchild != 0 && OF_getprop(subchild, "name", subchildname,
sizeof(subchildname)) > 0 && strcmp(subchildname, "lightshow") == 0)
return (ENXIO);
device_set_desc(self, "Apple I2S Audio Controller");

View File

@ -288,6 +288,12 @@ static const struct usb_config uep_config[UEP_N_TRANSFER] = {
},
};
static const STRUCT_USB_HOST_ID uep_devs[] = {
{USB_VPI(USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL, 0)},
{USB_VPI(USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL2, 0)},
{USB_VPI(USB_VENDOR_EGALAX2, USB_PRODUCT_EGALAX2_TPANEL, 0)},
};
static int
uep_probe(device_t dev)
{
@ -295,17 +301,12 @@ uep_probe(device_t dev)
if (uaa->usb_mode != USB_MODE_HOST)
return (ENXIO);
if (uaa->info.bConfigIndex != 0)
return (ENXIO);
if (uaa->info.bIfaceIndex != 0)
return (ENXIO);
if ((uaa->info.idVendor == USB_VENDOR_EGALAX) &&
((uaa->info.idProduct == USB_PRODUCT_EGALAX_TPANEL) ||
(uaa->info.idProduct == USB_PRODUCT_EGALAX_TPANEL2)))
return (BUS_PROBE_SPECIFIC);
if ((uaa->info.idVendor == USB_VENDOR_EGALAX2) &&
(uaa->info.idProduct == USB_PRODUCT_EGALAX2_TPANEL))
return (BUS_PROBE_SPECIFIC);
return (ENXIO);
return (usbd_lookup_id_by_uaa(uep_devs, sizeof(uep_devs), uaa));
}
static int

View File

@ -745,6 +745,13 @@ static const struct usb_config ukbd_config[UKBD_N_TRANSFER] = {
},
};
/* A match on these entries will load ukbd */
static const STRUCT_USB_HOST_ID __used ukbd_devs[] = {
{USB_IFACE_CLASS(UICLASS_HID),
USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
USB_IFACE_PROTOCOL(UIPROTO_BOOT_KEYBOARD),},
};
static int
ukbd_probe(device_t dev)
{

View File

@ -355,6 +355,13 @@ static const struct usb_config ums_config[UMS_N_TRANSFER] = {
},
};
/* A match on these entries will load ums */
static const STRUCT_USB_HOST_ID __used ums_devs[] = {
{USB_IFACE_CLASS(UICLASS_HID),
USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
USB_IFACE_PROTOCOL(UIPROTO_MOUSE),},
};
static int
ums_probe(device_t dev)
{

View File

@ -288,40 +288,27 @@ udbp_modload(module_t mod, int event, void *data)
return (error);
}
static const STRUCT_USB_HOST_ID udbp_devs[] = {
{USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_TURBOCONNECT, 0)},
{USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301, 0)},
{USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302, 0)},
{USB_VPI(USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZLINK, 0)},
{USB_VPI(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL620USB, 0)},
};
static int
udbp_probe(device_t dev)
{
struct usb_attach_arg *uaa = device_get_ivars(dev);
if (uaa->usb_mode != USB_MODE_HOST) {
if (uaa->usb_mode != USB_MODE_HOST)
return (ENXIO);
if (uaa->info.bConfigIndex != 0)
return (ENXIO);
if (uaa->info.bIfaceIndex != 0)
return (ENXIO);
}
/*
* XXX Julian, add the id of the device if you have one to test
* things with. run 'usbdevs -v' and note the 3 ID's that appear.
* The Vendor Id and Product Id are in hex and the Revision Id is in
* bcd. But as usual if the revision is 0x101 then you should
* compare the revision id in the device descriptor with 0x101 Or go
* search the file usbdevs.h. Maybe the device is already in there.
*/
if (((uaa->info.idVendor == USB_VENDOR_NETCHIP) &&
(uaa->info.idProduct == USB_PRODUCT_NETCHIP_TURBOCONNECT)))
return (0);
if (((uaa->info.idVendor == USB_VENDOR_PROLIFIC) &&
((uaa->info.idProduct == USB_PRODUCT_PROLIFIC_PL2301) ||
(uaa->info.idProduct == USB_PRODUCT_PROLIFIC_PL2302))))
return (0);
if ((uaa->info.idVendor == USB_VENDOR_ANCHOR) &&
(uaa->info.idProduct == USB_PRODUCT_ANCHOR_EZLINK))
return (0);
if ((uaa->info.idVendor == USB_VENDOR_GENESYS) &&
(uaa->info.idProduct == USB_PRODUCT_GENESYS_GL620USB))
return (0);
return (ENXIO);
return (usbd_lookup_id_by_uaa(udbp_devs, sizeof(udbp_devs), uaa));
}
static int

View File

@ -118,19 +118,23 @@ DRIVER_MODULE(ufm, uhub, ufm_driver, ufm_devclass, NULL, 0);
MODULE_DEPEND(ufm, usb, 1, 1, 1);
MODULE_VERSION(ufm, 1);
static const STRUCT_USB_HOST_ID ufm_devs[] = {
{USB_VPI(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_FMRADIO, 0)},
};
static int
ufm_probe(device_t dev)
{
struct usb_attach_arg *uaa = device_get_ivars(dev);
if (uaa->usb_mode != USB_MODE_HOST) {
if (uaa->usb_mode != USB_MODE_HOST)
return (ENXIO);
}
if ((uaa->info.idVendor == USB_VENDOR_CYPRESS) &&
(uaa->info.idProduct == USB_PRODUCT_CYPRESS_FMRADIO)) {
return (0);
}
return (ENXIO);
if (uaa->info.bConfigIndex != 0)
return (ENXIO);
if (uaa->info.bIfaceIndex != 0)
return (ENXIO);
return (usbd_lookup_id_by_uaa(ufm_devs, sizeof(ufm_devs), uaa));
}
static int

View File

@ -327,6 +327,11 @@ MODULE_DEPEND(ufoma, ucom, 1, 1, 1);
MODULE_DEPEND(ufoma, usb, 1, 1, 1);
MODULE_VERSION(ufoma, 1);
static const STRUCT_USB_HOST_ID ufoma_devs[] = {
{USB_IFACE_CLASS(UICLASS_CDC),
USB_IFACE_SUBCLASS(UISUBCLASS_MCPC),},
};
static int
ufoma_probe(device_t dev)
{
@ -334,30 +339,31 @@ ufoma_probe(device_t dev)
struct usb_interface_descriptor *id;
struct usb_config_descriptor *cd;
usb_mcpc_acm_descriptor *mad;
int error;
if (uaa->usb_mode != USB_MODE_HOST) {
if (uaa->usb_mode != USB_MODE_HOST)
return (ENXIO);
}
error = usbd_lookup_id_by_uaa(ufoma_devs, sizeof(ufoma_devs), uaa);
if (error)
return (error);
id = usbd_get_interface_descriptor(uaa->iface);
cd = usbd_get_config_descriptor(uaa->device);
if ((id == NULL) ||
(cd == NULL) ||
(id->bInterfaceClass != UICLASS_CDC) ||
(id->bInterfaceSubClass != UISUBCLASS_MCPC)) {
if (id == NULL || cd == NULL)
return (ENXIO);
}
mad = ufoma_get_intconf(cd, id, UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM);
if (mad == NULL) {
if (mad == NULL)
return (ENXIO);
}
#ifndef UFOMA_HANDSFREE
if ((mad->bType == UMCPC_ACM_TYPE_AB5) ||
(mad->bType == UMCPC_ACM_TYPE_AB6)) {
(mad->bType == UMCPC_ACM_TYPE_AB6))
return (ENXIO);
}
#endif
return (0);
return (BUS_PROBE_GENERIC);
}
static int

View File

@ -276,11 +276,14 @@ umodem_probe(device_t dev)
DPRINTFN(11, "\n");
if (uaa->usb_mode != USB_MODE_HOST) {
if (uaa->usb_mode != USB_MODE_HOST)
return (ENXIO);
}
error = usbd_lookup_id_by_uaa(umodem_devs, sizeof(umodem_devs), uaa);
return (error);
if (error)
return (error);
return (BUS_PROBE_GENERIC);
}
static int

View File

@ -198,22 +198,25 @@ DRIVER_MODULE(urio, uhub, urio_driver, urio_devclass, NULL, 0);
MODULE_DEPEND(urio, usb, 1, 1, 1);
MODULE_VERSION(urio, 1);
static const STRUCT_USB_HOST_ID urio_devs[] = {
{USB_VPI(USB_VENDOR_DIAMOND, USB_PRODUCT_DIAMOND_RIO500USB, 0)},
{USB_VPI(USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO600USB, 0)},
{USB_VPI(USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO800USB, 0)},
};
static int
urio_probe(device_t dev)
{
struct usb_attach_arg *uaa = device_get_ivars(dev);
if (uaa->usb_mode != USB_MODE_HOST) {
if (uaa->usb_mode != USB_MODE_HOST)
return (ENXIO);
}
if ((((uaa->info.idVendor == USB_VENDOR_DIAMOND) &&
(uaa->info.idProduct == USB_PRODUCT_DIAMOND_RIO500USB)) ||
((uaa->info.idVendor == USB_VENDOR_DIAMOND2) &&
((uaa->info.idProduct == USB_PRODUCT_DIAMOND2_RIO600USB) ||
(uaa->info.idProduct == USB_PRODUCT_DIAMOND2_RIO800USB)))))
return (0);
else
if (uaa->info.bConfigIndex != 0)
return (ENXIO);
if (uaa->info.bIfaceIndex != 0)
return (ENXIO);
return (usbd_lookup_id_by_uaa(urio_devs, sizeof(urio_devs), uaa));
}
static int

View File

@ -1297,6 +1297,21 @@ usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index)
usb_init_attach_arg(udev, &uaa);
/*
* If the whole USB device is targeted, invoke the USB event
* handler(s):
*/
if (iface_index == USB_IFACE_INDEX_ANY) {
EVENTHANDLER_INVOKE(usb_dev_configured, udev, &uaa);
if (uaa.dev_state != UAA_DEV_READY) {
/* leave device unconfigured */
usb_unconfigure(udev, 0);
goto done;
}
}
/* Check if only one interface should be probed: */
if (iface_index != USB_IFACE_INDEX_ANY) {
i = iface_index;
@ -1343,17 +1358,18 @@ usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index)
uaa.info.bIfaceIndex,
uaa.info.bIfaceNum);
if (usb_probe_and_attach_sub(udev, &uaa)) {
/* ignore */
}
}
usb_probe_and_attach_sub(udev, &uaa);
if (uaa.temp_dev) {
/* remove the last created child; it is unused */
if (device_delete_child(udev->parent_dev, uaa.temp_dev)) {
/*
* Remove the leftover child, if any, to enforce that
* a new nomatch devd event is generated for the next
* interface if no driver is found:
*/
if (uaa.temp_dev == NULL)
continue;
if (device_delete_child(udev->parent_dev, uaa.temp_dev))
DPRINTFN(0, "device delete child failed\n");
}
uaa.temp_dev = NULL;
}
done:
if (do_unlock)
@ -1526,7 +1542,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
/* initialise our SX-lock */
sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK);
sx_init_flags(&udev->sr_sx, "USB suspend and resume SX lock", SX_DUPOK);
sx_init_flags(&udev->sr_sx, "USB suspend and resume SX lock", SX_NOWITNESS);
cv_init(&udev->ctrlreq_cv, "WCTRL");
cv_init(&udev->ref_cv, "UGONE");
@ -1834,11 +1850,6 @@ repeat_set_config:
}
}
}
EVENTHANDLER_INVOKE(usb_dev_configured, udev, &uaa);
if (uaa.dev_state != UAA_DEV_READY) {
/* leave device unconfigured */
usb_unconfigure(udev, 0);
}
config_done:
DPRINTF("new dev (addr %d), udev=%p, parent_hub=%p\n",

View File

@ -42,6 +42,8 @@
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/priv.h>
#include <sys/limits.h>
#include <sys/endian.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@ -144,3 +146,108 @@ usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id,
}
return (ENXIO);
}
/*------------------------------------------------------------------------*
* Export the USB device ID format we use to userspace tools.
*------------------------------------------------------------------------*/
#if BYTE_ORDER == BIG_ENDIAN
#define U16_XOR "8"
#define U32_XOR "12"
#define U64_XOR "56"
#define U8_BITFIELD_XOR "7"
#define U16_BITFIELD_XOR "15"
#define U32_BITFIELD_XOR "31"
#define U64_BITFIELD_XOR "63"
#else
#define U16_XOR "0"
#define U32_XOR "0"
#define U64_XOR "0"
#define U8_BITFIELD_XOR "0"
#define U16_BITFIELD_XOR "0"
#define U32_BITFIELD_XOR "0"
#define U64_BITFIELD_XOR "0"
#endif
#if USB_HAVE_COMPAT_LINUX
#define MFL_SIZE "1"
#else
#define MFL_SIZE "0"
#endif
#ifdef KLD_MODULE
static const char __section("bus_autoconf_format") __used usb_id_format[] = {
/* Declare that three different sections use the same format */
"usb_host_id{256,:}"
"usb_device_id{256,:}"
"usb_dual_id{256,:}"
/* List size of fields in the usb_device_id structure */
#if ULONG_MAX >= 0xFFFFFFFFUL
"unused{0,8}"
"unused{0,8}"
"unused{0,8}"
"unused{0,8}"
#if ULONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
"unused{0,8}"
"unused{0,8}"
"unused{0,8}"
"unused{0,8}"
#endif
#else
#error "Please update code."
#endif
"idVendor[0]{" U16_XOR ",8}"
"idVendor[1]{" U16_XOR ",8}"
"idProduct[0]{" U16_XOR ",8}"
"idProduct[1]{" U16_XOR ",8}"
"bcdDevice_lo[0]{" U16_XOR ",8}"
"bcdDevice_lo[1]{" U16_XOR ",8}"
"bcdDevice_hi[0]{" U16_XOR ",8}"
"bcdDevice_hi[1]{" U16_XOR ",8}"
"bDeviceClass{0,8}"
"bDeviceSubClass{0,8}"
"bDeviceProtocol{0,8}"
"bInterfaceClass{0,8}"
"bInterfaceSubClass{0,8}"
"bInterfaceProtocol{0,8}"
"mf_vendor{" U8_BITFIELD_XOR ",1}"
"mf_product{" U8_BITFIELD_XOR ",1}"
"mf_dev_lo{" U8_BITFIELD_XOR ",1}"
"mf_dev_hi{" U8_BITFIELD_XOR ",1}"
"mf_dev_class{" U8_BITFIELD_XOR ",1}"
"mf_dev_subclass{" U8_BITFIELD_XOR ",1}"
"mf_dev_protocol{" U8_BITFIELD_XOR ",1}"
"mf_int_class{" U8_BITFIELD_XOR ",1}"
"mf_int_subclass{" U8_BITFIELD_XOR ",1}"
"mf_int_protocol{" U8_BITFIELD_XOR ",1}"
"unused{" U8_BITFIELD_XOR ",6}"
"mfl_vendor{" U16_XOR "," MFL_SIZE "}"
"mfl_product{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_lo{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_hi{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_class{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_subclass{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_protocol{" U16_XOR "," MFL_SIZE "}"
"mfl_int_class{" U16_XOR "," MFL_SIZE "}"
"mfl_int_subclass{" U16_XOR "," MFL_SIZE "}"
"mfl_int_protocol{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
};
#endif

View File

@ -489,6 +489,24 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index)
struct usb_interface_descriptor *id;
struct bbb_transfer *sc;
usb_error_t err;
uint8_t do_unlock;
/* automatic locking */
if (usbd_enum_is_locked(udev)) {
do_unlock = 0;
} else {
do_unlock = 1;
usbd_enum_lock(udev);
}
/*
* Make sure any driver which is hooked up to this interface,
* like umass is gone:
*/
usb_detach_device(udev, iface_index, 0);
if (do_unlock)
usbd_enum_unlock(udev);
iface = usbd_get_iface(udev, iface_index);
if (iface == NULL)

View File

@ -270,12 +270,15 @@ struct usb_device_id {
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;
uint8_t match_flag_unused:6;
#if USB_HAVE_COMPAT_LINUX
/* which fields to match against */
@ -291,7 +294,10 @@ struct usb_device_id {
#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
#endif
};
} __aligned(32);
/* check that the size of the structure above is correct */
extern char usb_device_id_assert[(sizeof(struct usb_device_id) == 32) ? 1 : -1];
#define USB_VENDOR(vend) \
.match_flag_vendor = 1, .idVendor = (vend)

View File

@ -169,7 +169,6 @@ enum {
/* recognized device vendors/products */
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),
UATH_DEV(ATHEROS, AR5523),
UATH_DEV(ATHEROS2, AR5523_1),

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2005 Marcel Moolenaar
* Copyright (c) 2005, 2009-2011 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,9 +32,11 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/priority.h>
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/timeet.h>
#include <sys/timetc.h>
#include <sys/pcpu.h>
@ -45,26 +47,12 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <machine/smp.h>
SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics");
static int adjust_edges = 0;
SYSCTL_INT(_debug_clock, OID_AUTO, adjust_edges, CTLFLAG_RD,
&adjust_edges, 0, "Number of times ITC got more than 12.5% behind");
static int adjust_excess = 0;
SYSCTL_INT(_debug_clock, OID_AUTO, adjust_excess, CTLFLAG_RD,
&adjust_excess, 0, "Total number of ignored ITC interrupts");
static int adjust_lost = 0;
SYSCTL_INT(_debug_clock, OID_AUTO, adjust_lost, CTLFLAG_RD,
&adjust_lost, 0, "Total number of lost ITC interrupts");
static int adjust_ticks = 0;
SYSCTL_INT(_debug_clock, OID_AUTO, adjust_ticks, CTLFLAG_RD,
&adjust_ticks, 0, "Total number of ITC interrupts with adjustment");
#define CLOCK_ET_OFF 0
#define CLOCK_ET_PERIODIC 1
#define CLOCK_ET_ONESHOT 2
static struct eventtimer ia64_clock_et;
static u_int ia64_clock_xiv;
static uint64_t ia64_clock_reload;
#ifndef SMP
static timecounter_get_t ia64_get_timecount;
@ -87,75 +75,100 @@ ia64_get_timecount(struct timecounter* tc)
static u_int
ia64_ih_clock(struct thread *td, u_int xiv, struct trapframe *tf)
{
uint64_t adj, clk, itc;
int64_t delta;
int count;
struct eventtimer *et;
uint64_t itc, load;
uint32_t mode;
PCPU_INC(md.stats.pcs_nclks);
intrcnt[INTRCNT_CLOCK]++;
if (PCPU_GET(cpuid) == 0) {
/*
* Clock processing on the BSP.
*/
intrcnt[INTRCNT_CLOCK]++;
itc = ia64_get_itc();
PCPU_SET(md.clock, itc);
itc = ia64_get_itc();
adj = PCPU_GET(md.clockadj);
clk = PCPU_GET(md.clock);
delta = itc - clk;
count = 0;
while (delta >= ia64_clock_reload) {
#ifdef SMP
ipi_all_but_self(ia64_clock_xiv);
#endif
hardclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
if (profprocs != 0)
profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
statclock(TRAPF_USERMODE(tf));
delta -= ia64_clock_reload;
clk += ia64_clock_reload;
if (adj != 0)
adjust_ticks++;
count++;
}
ia64_set_itm(ia64_get_itc() + ia64_clock_reload - adj);
ia64_srlz_d();
if (count > 0) {
adjust_lost += count - 1;
if (delta > (ia64_clock_reload >> 3)) {
if (adj == 0)
adjust_edges++;
adj = ia64_clock_reload >> 4;
} else
adj = 0;
} else {
adj = 0;
adjust_excess++;
}
PCPU_SET(md.clock, clk);
PCPU_SET(md.clockadj, adj);
} else {
/*
* Clock processing on the BSP.
*/
hardclock_cpu(TRAPF_USERMODE(tf));
if (profprocs != 0)
profclock(TRAPF_USERMODE(tf), TRAPF_PC(tf));
statclock(TRAPF_USERMODE(tf));
}
mode = PCPU_GET(md.clock_mode);
if (mode == CLOCK_ET_PERIODIC) {
load = PCPU_GET(md.clock_load);
ia64_set_itm(itc + load);
} else
ia64_set_itv((1 << 16) | xiv);
ia64_srlz_d();
et = &ia64_clock_et;
if (et->et_active)
et->et_event_cb(et, et->et_arg);
return (0);
}
/*
* Start the real-time and statistics clocks. We use ar.itc and cr.itm
* to implement a 1000hz clock.
* Event timer start method.
*/
static int
ia64_clock_start(struct eventtimer *et, struct bintime *first,
struct bintime *period)
{
u_long itc, load;
register_t is;
if (period != NULL) {
PCPU_SET(md.clock_mode, CLOCK_ET_PERIODIC);
load = (et->et_frequency * (period->frac >> 32)) >> 32;
if (period->sec > 0)
load += et->et_frequency * period->sec;
} else {
PCPU_SET(md.clock_mode, CLOCK_ET_ONESHOT);
load = 0;
}
PCPU_SET(md.clock_load, load);
if (first != NULL) {
load = (et->et_frequency * (first->frac >> 32)) >> 32;
if (first->sec > 0)
load += et->et_frequency * first->sec;
}
is = intr_disable();
itc = ia64_get_itc();
ia64_set_itm(itc + load);
ia64_set_itv(ia64_clock_xiv);
ia64_srlz_d();
intr_restore(is);
return (0);
}
/*
* Event timer stop method.
*/
static int
ia64_clock_stop(struct eventtimer *et)
{
ia64_set_itv((1 << 16) | ia64_clock_xiv);
ia64_srlz_d();
PCPU_SET(md.clock_mode, CLOCK_ET_OFF);
PCPU_SET(md.clock_load, 0);
return (0);
}
/*
* We call cpu_initclocks() on the APs as well. It allows us to
* group common initialization in the same function.
*/
void
cpu_initclocks()
{
ia64_clock_stop(NULL);
if (PCPU_GET(cpuid) == 0)
cpu_initclocks_bsp();
else
cpu_initclocks_ap();
}
static void
clock_configure(void *dummy)
{
struct eventtimer *et;
u_long itc_freq;
ia64_clock_xiv = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IPI,
@ -165,31 +178,23 @@ cpu_initclocks()
itc_freq = (u_long)ia64_itc_freq() * 1000000ul;
stathz = hz;
ia64_clock_reload = (itc_freq + hz/2) / hz;
et = &ia64_clock_et;
et->et_name = "ITC";
et->et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU;
et->et_quality = 1000;
et->et_frequency = itc_freq;
et->et_min_period.sec = 0;
et->et_min_period.frac = (0x8000000000000000ul / (u_long)(10*hz)) << 1;
et->et_max_period.sec = 0xffffffff;
et->et_max_period.frac = ((0xfffffffeul << 32) / itc_freq) << 32;
et->et_start = ia64_clock_start;
et->et_stop = ia64_clock_stop;
et->et_priv = NULL;
et_register(et);
#ifndef SMP
ia64_timecounter.tc_frequency = itc_freq;
tc_init(&ia64_timecounter);
#endif
PCPU_SET(md.clockadj, 0);
PCPU_SET(md.clock, ia64_get_itc());
ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload);
ia64_set_itv(ia64_clock_xiv);
ia64_srlz_d();
}
void
cpu_startprofclock(void)
{
/* nothing to do */
}
void
cpu_stopprofclock(void)
{
/* nothing to do */
}
SYSINIT(clkcfg, SI_SUB_CONFIGURE, SI_ORDER_SECOND, clock_configure, NULL);

View File

@ -578,11 +578,13 @@ db_show_mdpcpu(struct pcpu *pc)
{
struct pcpu_md *md = &pc->pc_md;
db_printf("MD: vhpt = %#lx\n", md->vhpt);
db_printf("MD: lid = %#lx\n", md->lid);
db_printf("MD: clock = %#lx/%#lx\n", md->clock, md->clockadj);
db_printf("MD: stats = %p\n", &md->stats);
db_printf("MD: pmap = %p\n", md->current_pmap);
db_printf("MD: vhpt = %#lx\n", md->vhpt);
db_printf("MD: lid = %#lx\n", md->lid);
db_printf("MD: clock = %#lx\n", md->clock);
db_printf("MD: clock_mode = %u\n", md->clock_mode);
db_printf("MD: clock_load = %#lx\n", md->clock_load);
db_printf("MD: stats = %p\n", &md->stats);
db_printf("MD: pmap = %p\n", md->current_pmap);
}
void

View File

@ -1,41 +1,33 @@
/* $FreeBSD$ */
/* $NetBSD: interrupt.c,v 1.23 1998/02/24 07:38:01 thorpej Exp $ */
/*-
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
* Copyright (c) 2010-2011 Marcel Moolenaar
* All rights reserved.
*
* Authors: Keith Bostic, Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
* 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.
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/*-
* Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center.
* Redistribute and modify at will, leaving only this additional copyright
* notice.
* 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.
*/
#include "opt_ddb.h"
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
@ -309,6 +301,7 @@ void
ia64_handle_intr(struct trapframe *tf)
{
struct thread *td;
struct trapframe *stf;
u_int xiv;
td = curthread;
@ -323,17 +316,20 @@ ia64_handle_intr(struct trapframe *tf)
}
critical_enter();
stf = td->td_intr_frame;
td->td_intr_frame = tf;
do {
ia64_set_eoi(0);
ia64_srlz_d();
CTR2(KTR_INTR, "INTR: ITC=%u, XIV=%u",
(u_int)tf->tf_special.ifa, xiv);
(ia64_handler[xiv])(td, xiv, tf);
ia64_set_eoi(0);
ia64_srlz_d();
xiv = ia64_get_ivr();
ia64_srlz_d();
} while (xiv != 15);
td->td_intr_frame = stf;
critical_exit();
out:

View File

@ -345,6 +345,11 @@ cpu_startup(void *dummy)
"nextints", CTLFLAG_RD, &pcs->pcs_nextints,
"Number of ExtINT interrupts");
SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
"nhardclocks", CTLFLAG_RD, &pcs->pcs_nhardclocks,
"Number of IPI_HARDCLOCK interrupts");
SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
"nhighfps", CTLFLAG_RD, &pcs->pcs_nhighfps,
@ -416,12 +421,10 @@ cpu_idle(int busy)
{
register_t ie;
#if 0
if (!busy) {
critical_enter();
cpu_idleclock();
}
#endif
ie = intr_disable();
KASSERT(ie != 0, ("%s called with interrupts disabled\n", __func__));
@ -436,12 +439,10 @@ cpu_idle(int busy)
ia64_enable_intr();
}
#if 0
if (!busy) {
cpu_activeclock();
critical_exit();
}
#endif
}
int

View File

@ -77,6 +77,7 @@ void ia64_ap_startup(void);
struct ia64_ap_state ia64_ap_state;
int ia64_ipi_ast;
int ia64_ipi_hardclock;
int ia64_ipi_highfp;
int ia64_ipi_nmi;
int ia64_ipi_preempt;
@ -107,6 +108,16 @@ ia64_ih_ast(struct thread *td, u_int xiv, struct trapframe *tf)
return (0);
}
static u_int
ia64_ih_hardclock(struct thread *td, u_int xiv, struct trapframe *tf)
{
PCPU_INC(md.stats.pcs_nhardclocks);
CTR1(KTR_SMP, "IPI_HARDCLOCK, cpuid=%d", PCPU_GET(cpuid));
hardclockintr();
return (0);
}
static u_int
ia64_ih_highfp(struct thread *td, u_int xiv, struct trapframe *tf)
{
@ -233,10 +244,11 @@ ia64_ap_startup(void)
CTR1(KTR_SMP, "SMP: cpu%d launched", PCPU_GET(cpuid));
/* Mask interval timer interrupts on APs. */
ia64_set_itv(0x10000);
cpu_initclocks();
ia64_set_tpr(0);
ia64_srlz_d();
ia64_enable_intr();
sched_throw(NULL);
@ -411,6 +423,8 @@ cpu_mp_unleash(void *dummy)
/* Allocate XIVs for IPIs */
ia64_ipi_ast = ia64_xiv_alloc(PI_DULL, IA64_XIV_IPI, ia64_ih_ast);
ia64_ipi_hardclock = ia64_xiv_alloc(PI_REALTIME, IA64_XIV_IPI,
ia64_ih_hardclock);
ia64_ipi_highfp = ia64_xiv_alloc(PI_AV, IA64_XIV_IPI, ia64_ih_highfp);
ia64_ipi_preempt = ia64_xiv_alloc(PI_SOFT, IA64_XIV_IPI,
ia64_ih_preempt);

View File

@ -37,6 +37,7 @@ struct pcpu_stats {
u_long pcs_nasts; /* IPI_AST counter. */
u_long pcs_nclks; /* Clock interrupt counter. */
u_long pcs_nextints; /* ExtINT counter. */
u_long pcs_nhardclocks; /* IPI_HARDCLOCK counter. */
u_long pcs_nhighfps; /* IPI_HIGH_FP counter. */
u_long pcs_nhwints; /* Hardware int. counter. */
u_long pcs_npreempts; /* IPI_PREEMPT counter. */
@ -51,7 +52,8 @@ struct pcpu_md {
vm_offset_t vhpt; /* Address of VHPT */
uint64_t lid; /* local CPU ID */
uint64_t clock; /* Clock counter. */
uint64_t clockadj; /* Clock adjust. */
uint64_t clock_load; /* Clock reload value. */
uint32_t clock_mode; /* Clock ET mode */
uint32_t awake:1; /* CPU is awake? */
struct pcpu_stats stats; /* Interrupt stats. */
#ifdef _KERNEL

View File

@ -7,6 +7,7 @@
#ifdef _KERNEL
#define IPI_AST ia64_ipi_ast
#define IPI_HARDCLOCK ia64_ipi_hardclock
#define IPI_PREEMPT ia64_ipi_preempt
#define IPI_RENDEZVOUS ia64_ipi_rndzvs
#define IPI_STOP ia64_ipi_stop
@ -37,6 +38,7 @@ struct ia64_ap_state {
};
extern int ia64_ipi_ast;
extern int ia64_ipi_hardclock;
extern int ia64_ipi_highfp;
extern int ia64_ipi_nmi;
extern int ia64_ipi_preempt;

View File

@ -87,20 +87,6 @@ SYSCTL_PROC(_debug_kdb, OID_AUTO, trap, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
kdb_sysctl_trap_code, "I", "set to cause a page fault via code access");
/*
* Flag indicating whether or not to IPI the other CPUs to stop them on
* entering the debugger. Sometimes, this will result in a deadlock as
* stop_cpus() waits for the other cpus to stop, so we allow it to be
* disabled. In order to maximize the chances of success, use a hard
* stop for that.
*/
#ifdef SMP
static int kdb_stop_cpus = 1;
SYSCTL_INT(_debug_kdb, OID_AUTO, stop_cpus, CTLFLAG_RW | CTLFLAG_TUN,
&kdb_stop_cpus, 0, "stop other CPUs when entering the debugger");
TUNABLE_INT("debug.kdb.stop_cpus", &kdb_stop_cpus);
#endif
/*
* Flag to indicate to debuggers why the debugger was entered.
*/
@ -565,8 +551,7 @@ kdb_trap(int type, int code, struct trapframe *tf)
kdb_active--;
#ifdef SMP
if (did_stop_cpus)
restart_cpus(stopped_cpus);
restart_cpus(stopped_cpus);
#endif
intr_restore(intr);

View File

@ -236,12 +236,10 @@ generic_stop_cpus(cpuset_t map, u_int type)
/* spin */
cpu_spinwait();
i++;
#ifdef DIAGNOSTIC
if (i == 100000) {
if (i == 100000000) {
printf("timeout stopping cpus\n");
break;
}
#endif
}
stopping_cpu = NOCPU;

View File

@ -63,13 +63,6 @@ __FBSDID("$FreeBSD$");
FEATURE(security_capabilities, "Capsicum Capability Mode");
/*
* We don't currently have any MIB entries for sysctls, but we do expose
* security.capabilities so that it's easy to tell if options CAPABILITIES is
* compiled into the kernel.
*/
SYSCTL_NODE(_security, OID_AUTO, capabilities, CTLFLAG_RW, 0, "Capsicum");
/*
* System call to enter capability mode for the process.
*/

View File

@ -27,11 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <machine/cpuregs.h>
#include <mips/sentry5/s5reg.h>
#include "opt_ddb.h"
#include <sys/param.h>
@ -50,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/cpuregs.h>
#include <machine/hwfunc.h>
#include <machine/md_var.h>
#include <machine/trap.h>
@ -61,6 +57,8 @@ __FBSDID("$FreeBSD$");
#include <mips/atheros/ar71xx_cpudef.h>
#include <mips/sentry5/s5reg.h>
/* XXX these should replace the current definitions in ar71xxreg.h */
/* XXX perhaps an ar71xx_chip.h header file? */
#define AR71XX_PLL_REG_CPU_CONFIG AR71XX_PLL_CPU_BASE + 0x00

View File

@ -27,11 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <machine/cpuregs.h>
#include <mips/sentry5/s5reg.h>
#include "opt_ddb.h"
#include <sys/param.h>
@ -50,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/cpuregs.h>
#include <machine/hwfunc.h>
#include <machine/md_var.h>
#include <machine/trap.h>
@ -60,6 +56,8 @@ __FBSDID("$FreeBSD$");
#include <mips/atheros/ar71xx_setup.h>
#include <mips/atheros/ar71xx_cpudef.h>
#include <mips/sentry5/s5reg.h>
extern char edata[], end[];
uint32_t ar711_base_mac[ETHER_ADDR_LEN];

View File

@ -49,8 +49,6 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/controller/ohci.h>
#include <dev/usb/controller/ohcireg.h>
#include <sys/rman.h>
static int ar71xx_ohci_attach(device_t dev);
static int ar71xx_ohci_detach(device_t dev);
static int ar71xx_ohci_probe(device_t dev);

View File

@ -27,11 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <machine/cpuregs.h>
#include <mips/sentry5/s5reg.h>
#include "opt_ddb.h"
#include <sys/param.h>
@ -50,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/cpuregs.h>
#include <machine/hwfunc.h>
#include <machine/md_var.h>
#include <machine/trap.h>
@ -64,6 +60,8 @@ __FBSDID("$FreeBSD$");
#include <mips/atheros/ar724x_chip.h>
#include <mips/atheros/ar91xx_chip.h>
#include <mips/sentry5/s5reg.h>
#define AR71XX_SYS_TYPE_LEN 128
static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN];

View File

@ -27,11 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <machine/cpuregs.h>
#include <mips/sentry5/s5reg.h>
#include "opt_ddb.h"
#include <sys/param.h>
@ -50,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/cpuregs.h>
#include <machine/hwfunc.h>
#include <machine/md_var.h>
#include <machine/trap.h>
@ -62,6 +58,8 @@ __FBSDID("$FreeBSD$");
#include <mips/atheros/ar71xx_setup.h>
#include <mips/atheros/ar724x_chip.h>
#include <mips/sentry5/s5reg.h>
static void
ar724x_chip_detect_mem_size(void)
{

View File

@ -27,11 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <machine/cpuregs.h>
#include <mips/sentry5/s5reg.h>
#include "opt_ddb.h"
#include <sys/param.h>
@ -50,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/cpuregs.h>
#include <machine/hwfunc.h>
#include <machine/md_var.h>
#include <machine/trap.h>
@ -61,6 +57,8 @@ __FBSDID("$FreeBSD$");
#include <mips/atheros/ar71xx_cpudef.h>
#include <mips/atheros/ar91xx_chip.h>
#include <mips/sentry5/s5reg.h>
static void
ar91xx_chip_detect_mem_size(void)
{

View File

@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <sys/proc.h>
#include <machine/cpuregs.h>
#include <machine/pcb.h>
#include <machine/sigframe.h>

View File

@ -91,10 +91,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kdb.h>
#endif
#include <sys/cdefs.h>
#include <sys/syslog.h>
#ifdef TRAP_DEBUG
int trap_debug = 0;
SYSCTL_INT(_machdep, OID_AUTO, trap_debug, CTLFLAG_RW,

View File

@ -78,8 +78,6 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/mips_opcode.h>
#include <machine/asm.h>
#include <mips/rmi/rmi_mips_exts.h>
#include <machine/cpuregs.h>
#include <machine/param.h>
#include <machine/intr_machdep.h>

View File

@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
#include <sys/ktr.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
#include <sys/unistd.h>

View File

@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <sys/types.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/module.h>

View File

@ -27,11 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <machine/cpuregs.h>
#include <mips/sentry5/s5reg.h>
#include "opt_ddb.h"
#include <sys/param.h>
@ -75,6 +70,8 @@ __FBSDID("$FreeBSD$");
#include <machine/trap.h>
#include <machine/vmparam.h>
#include <mips/sentry5/s5reg.h>
#ifdef CFE
#include <dev/cfe/cfe_api.h>
#endif

View File

@ -27,8 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include "opt_ddb.h"
#include "opt_kdb.h"

View File

@ -754,8 +754,6 @@ 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):

View File

@ -514,8 +514,6 @@ 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

View File

@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
@ -39,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/pmap.h>
#include <machine/rtas.h>
#include <machine/stdarg.h>
@ -60,6 +62,8 @@ int rtascall(vm_offset_t callbuffer, uintptr_t rtas_privdat);
extern uintptr_t rtas_entry;
extern register_t rtasmsr;
int setfault(faultbuf); /* defined in locore.S */
/*
* After the VM is up, allocate RTAS memory and instantiate it
*/
@ -188,6 +192,7 @@ int
rtas_call_method(cell_t token, int nargs, int nreturns, ...)
{
vm_offset_t argsptr;
faultbuf env;
va_list ap;
struct {
cell_t token;
@ -213,7 +218,19 @@ rtas_call_method(cell_t token, int nargs, int nreturns, ...)
args.args_n_results[n] = va_arg(ap, cell_t);
argsptr = rtas_real_map(&args, sizeof(args));
result = rtascall(argsptr, rtas_private_data);
/* Get rid of any stale machine checks that have been waiting. */
__asm __volatile ("sync; isync");
if (!setfault(env)) {
__asm __volatile ("sync");
result = rtascall(argsptr, rtas_private_data);
__asm __volatile ("sync; isync");
} else {
result = RTAS_HW_ERROR;
}
curthread->td_pcb->pcb_onfault = 0;
__asm __volatile ("sync");
rtas_real_unmap(argsptr, &args, sizeof(args));
mtx_unlock(&rtas_mtx);

View File

@ -510,7 +510,7 @@ fcu_fill_fan_prop(device_t dev)
sc->sc_fans[j].fan.set =
(int (*)(struct pmac_fan *, int))(fcu_fan_set_rpm);
} else {
sc->sc_fans[j].fan.min_rpm = 40; /* Percent */
sc->sc_fans[j].fan.min_rpm = 30; /* Percent */
sc->sc_fans[j].fan.max_rpm = 100;
sc->sc_fans[j].fan.read = NULL;
sc->sc_fans[j].fan.set =

View File

@ -0,0 +1,16 @@
# $FreeBSD$
case ! in
[\!!]) ;;
*) echo Failed at $LINENO ;;
esac
case ! in
['!'!]) ;;
*) echo Failed at $LINENO ;;
esac
case ! in
["!"!]) ;;
*) echo Failed at $LINENO ;;
esac

View File

@ -36,7 +36,10 @@ PROG= bus_autoconf
MAN=
BINDIR?= /usr/local/bin
SRCS= bus_autoconf.c
SRCS+= bus_autoconf.c
SRCS+= bus_load_file.c
SRCS+= bus_sections.c
SRCS+= bus_usb.c
WARNS= 6

View File

@ -33,228 +33,23 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sysexits.h>
#include <err.h>
#include <fcntl.h>
#include <string.h>
#include <err.h>
#include <sysexits.h>
#include <unistd.h>
#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_any) {
printf("nomatch 10 {\n"
" match \"bus\" \"uhub[0-9]+\";\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);
}
#include "bus_sections.h"
#include "bus_load_file.h"
#include "bus_usb.h"
static void
usage(void)
{
fprintf(stderr,
"bus_autoconf - devd config file generator\n"
" -i <input_binary>\n"
" -m <module_name>\n"
" -t <structure_type>\n"
" -i <structure_type,module.ko>\n"
" -F <format_file>\n"
" -h show usage\n"
);
exit(EX_USAGE);
@ -263,53 +58,68 @@ usage(void)
int
main(int argc, char **argv)
{
const char *params = "i:m:ht:";
const char *params = "i:F:h";
char *fname;
char *section;
char *module;
char *postfix;
uint8_t *ptr;
uint32_t len;
int c;
int f;
off_t off;
int any_opt = 0;
while ((c = getopt(argc, argv, params)) != -1) {
switch (c) {
case 'i':
file_name = optarg;
fname = optarg;
load_file(fname, &ptr, &len);
module = strchr(fname, ',');
if (module == NULL) {
errx(EX_USAGE, "Invalid input "
"file name '%s'", fname);
}
/* split module and section */
*module++ = 0;
/* remove postfix */
postfix = strchr(module, '.');
if (postfix)
*postfix = 0;
/* get section name */
section = fname;
/* check section type */
if (strncmp(section, "usb_", 4) == 0)
usb_import_entries(section, module, ptr, len);
else
errx(EX_USAGE, "Invalid section '%s'", section);
free(ptr);
any_opt = 1;
break;
case 't':
type = optarg;
break;
case 'm':
module = optarg;
case 'F':
fname = optarg;
load_file(fname, &ptr, &len);
format_parse_entries(ptr, len);
free(ptr);
any_opt = 1;
break;
default:
usage();
break;
}
}
if (type == NULL || module == NULL || file_name == NULL)
if (any_opt == 0)
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);
usb_dump_entries();
return (0);
}

View File

@ -28,56 +28,4 @@
#ifndef _BUS_AUTOCONF_H_
#define _BUS_AUTOCONF_H_
/* Make sure we get the have compat linux definition. */
#include <dev/usb/usb.h>
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_ */

View File

@ -28,6 +28,7 @@
OS=FreeBSD
DOLLAR=$
OBJCOPY=objcopy
cat <<EOF
#
@ -39,26 +40,39 @@ cat <<EOF
EOF
for F in $(echo $* | sort)
do
H=$(basename ${F} | sed -e "s/\.ko//g")
rm -f bus_autoconf_format.bin
rm -f bus_autoconf_args.txt
rm -f bus_autoconf.ids
for F in $*
do
G=$(basename ${F})
# Format information
${OBJCOPY} -j bus_autoconf_format -O binary ${F} bus_autoconf.ids 2> /dev/null
[ -f bus_autoconf.ids ] && cat bus_autoconf.ids >> bus_autoconf_format.bin
# USB Host mode
${OBJCOPY} -j usb_host_id -O binary ${F} "usb_host_id,${G}" 2> /dev/null
[ -f "usb_host_id,${G}" ] && (echo -n " -i usb_host_id,${G}" >> bus_autoconf_args.txt)
# USB Device mode
${OBJCOPY} -j usb_device_id -O binary ${F} "usb_device_id,${G}" 2> /dev/null
[ -f "usb_device_id,${G}" ] && (echo -n " -i usb_device_id,${G}" >> bus_autoconf_args.txt)
# USB Host
objcopy -j usb_host_id -O binary ${F} ${F}.ids 2> /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
)
${OBJCOPY} -j usb_dual_id -O binary ${F} "usb_dual_id,${G}" 2> /dev/null
[ -f "usb_dual_id,${G}" ] && (echo -n " -i usb_dual_id,${G}" >> bus_autoconf_args.txt)
done
# Dump all data
bus_autoconf -F bus_autoconf_format.bin $(cat bus_autoconf_args.txt)
# Cleanup
rm -f -- \
$(cat bus_autoconf_args.txt) \
bus_autoconf_args.txt \
bus_autoconf_format.bin \
bus_autoconf.ids

View File

@ -0,0 +1,111 @@
/* $FreeBSD$ */
#if BYTE_ORDER == BIG_ENDIAN
#define U16_XOR "8"
#define U32_XOR "12"
#define U64_XOR "56"
#define U8_BITFIELD_XOR "7"
#define U16_BITFIELD_XOR "15"
#define U32_BITFIELD_XOR "31"
#define U64_BITFIELD_XOR "63"
#else
#define U16_XOR "0"
#define U32_XOR "0"
#define U64_XOR "0"
#define U8_BITFIELD_XOR "0"
#define U16_BITFIELD_XOR "0"
#define U32_BITFIELD_XOR "0"
#define U64_BITFIELD_XOR "0"
#endif
#if USB_HAVE_COMPAT_LINUX
#define MFL_SIZE "1"
#else
#define MFL_SIZE "0"
#endif
static const char __section("bus_autoconf_format") __used usb_id_format[] = {
/*
* Declare three different sections that use the same format.
* All sizes are in bits. Fields cannot be greater than
* 8 bits in size. Bitfields having a size greater than 1
* must fit within the byte in which the bitfield is defined.
*/
"usb_host_id{256,:}"
"usb_device_id{256,:}"
"usb_dual_id{256,:}"
/*
* Describe all fields in the usb_device_id structure
* which is found in sys/dev/usb/usbdi.h.
*/
#if BITS_PER_LONG == 32 || BITS_PER_LONG == 64
"unused{0,8}"
"unused{0,8}"
"unused{0,8}"
"unused{0,8}"
#if BITS_PER_LONG == 64
"unused{0,8}"
"unused{0,8}"
"unused{0,8}"
"unused{0,8}"
#endif
#else
#error "Please update code."
#endif
"idVendor[0]{" U16_XOR ",8}"
"idVendor[1]{" U16_XOR ",8}"
"idProduct[0]{" U16_XOR ",8}"
"idProduct[1]{" U16_XOR ",8}"
"bcdDevice_lo[0]{" U16_XOR ",8}"
"bcdDevice_lo[1]{" U16_XOR ",8}"
"bcdDevice_hi[0]{" U16_XOR ",8}"
"bcdDevice_hi[1]{" U16_XOR ",8}"
"bDeviceClass{0,8}"
"bDeviceSubClass{0,8}"
"bDeviceProtocol{0,8}"
"bInterfaceClass{0,8}"
"bInterfaceSubClass{0,8}"
"bInterfaceProtocol{0,8}"
/* NOTE: On big endian machines bitfields are bitreversed. */
"mf_vendor{" U8_BITFIELD_XOR ",1}"
"mf_product{" U8_BITFIELD_XOR ",1}"
"mf_dev_lo{" U8_BITFIELD_XOR ",1}"
"mf_dev_hi{" U8_BITFIELD_XOR ",1}"
"mf_dev_class{" U8_BITFIELD_XOR ",1}"
"mf_dev_subclass{" U8_BITFIELD_XOR ",1}"
"mf_dev_protocol{" U8_BITFIELD_XOR ",1}"
"mf_int_class{" U8_BITFIELD_XOR ",1}"
"mf_int_subclass{" U8_BITFIELD_XOR ",1}"
"mf_int_protocol{" U8_BITFIELD_XOR ",1}"
"unused{" U8_BITFIELD_XOR ",6}"
"mfl_vendor{" U16_XOR "," MFL_SIZE "}"
"mfl_product{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_lo{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_hi{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_class{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_subclass{" U16_XOR "," MFL_SIZE "}"
"mfl_dev_protocol{" U16_XOR "," MFL_SIZE "}"
"mfl_int_class{" U16_XOR "," MFL_SIZE "}"
"mfl_int_subclass{" U16_XOR "," MFL_SIZE "}"
"mfl_int_protocol{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
"unused{" U16_XOR "," MFL_SIZE "}"
};

View File

@ -0,0 +1,76 @@
/* $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.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <err.h>
#include <sysexits.h>
#include <unistd.h>
#include "bus_load_file.h"
void
load_file(const char *fname, uint8_t **pptr, uint32_t *plen)
{
uint8_t *ptr;
uint32_t len;
off_t off;
int f;
f = open(fname, O_RDONLY);
if (f < 0)
err(EX_NOINPUT, "Cannot open file '%s'", fname);
off = lseek(f, 0, SEEK_END);
if (off < 0) {
err(EX_NOINPUT, "Cannot seek to "
"end of file '%s'", fname);
}
if (lseek(f, 0, SEEK_SET) < 0) {
err(EX_NOINPUT, "Cannot seek to "
"beginning of file '%s'", fname);
}
len = off;
if (len != off)
err(EX_NOINPUT, "File '%s' is too big", fname);
ptr = malloc(len);
if (ptr == NULL)
errx(EX_SOFTWARE, "Out of memory");
if (read(f, ptr, len) != len)
err(EX_NOINPUT, "Cannot read all data");
close(f);
*pptr = ptr;
*plen = len;
}

View File

@ -0,0 +1,33 @@
/* $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_LOAD_FILE_H_
#define _BUS_LOAD_FILE_H_
void load_file(const char *, uint8_t **, uint32_t *);
#endif /* _BUS_LOAD_FILE_H_ */

View File

@ -0,0 +1,223 @@
/* $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.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sysexits.h>
#include <err.h>
#include <string.h>
#include <sys/queue.h>
#include "bus_sections.h"
#define MAX_STRING 64
struct format_info;
typedef TAILQ_HEAD(,format_info) format_info_head_t;
typedef TAILQ_ENTRY(format_info) format_info_entry_t;
static format_info_head_t format_head = TAILQ_HEAD_INITIALIZER(format_head);
struct format_info {
format_info_entry_t entry;
format_info_head_t fields;
char name[MAX_STRING];
uint16_t bit_offset;
uint16_t bit_size;
};
static struct format_info *
format_info_new(char *pstr, uint16_t bo, uint16_t bs)
{
struct format_info *pfi;
pfi = malloc(sizeof(*pfi));
if (pfi == NULL)
errx(EX_SOFTWARE, "Out of memory.");
memset(pfi, 0, sizeof(*pfi));
TAILQ_INIT(&pfi->fields);
strlcpy(pfi->name, pstr, sizeof(pfi->name));
pfi->bit_offset = bo;
pfi->bit_size = bs;
return (pfi);
}
static const struct format_info *
format_get_section(const char *section)
{
const struct format_info *psub;
static const struct format_info *psub_last;
static const char *psub_cache;
if (psub_cache && strcmp(psub_cache, section) == 0)
return (psub_last);
TAILQ_FOREACH(psub, &format_head, entry) {
if (strcmp(section, psub->name) == 0) {
psub_cache = section;
psub_last = psub;
return (psub);
}
}
warnx("Section '%s' not found", section);
psub_cache = section;
psub_last = psub;
return (NULL);
}
uint16_t
format_get_section_size(const char *section)
{
const struct format_info *pfi;
pfi = format_get_section(section);
if (pfi == NULL)
return (0);
return ((pfi->bit_offset + 7) / 8);
}
uint8_t
format_get_field(const char *section, const char *field,
const uint8_t *ptr, uint16_t size)
{
const struct format_info *pfi;
const struct format_info *psub;
uint16_t rem;
uint16_t off;
uint16_t sz;
pfi = format_get_section(section);
if (pfi == NULL)
return (0);
/* skip until we find the fields */
while (pfi && TAILQ_FIRST(&pfi->fields) == NULL)
pfi = TAILQ_NEXT(pfi, entry);
if (pfi == NULL)
return (0);
TAILQ_FOREACH(psub, &pfi->fields, entry) {
if (strcmp(field, psub->name) == 0) {
/* range check */
if (((psub->bit_offset + psub->bit_size) / 8) > size)
return (0);
/* compute byte offset */
rem = psub->bit_offset & 7;
off = psub->bit_offset / 8;
sz = psub->bit_size;
/* extract bit-field */
return ((ptr[off] >> rem) & ((1 << sz) - 1));
}
}
warnx("Field '%s' not found in '%s'", field, pfi->name);
return (0);
}
void
format_parse_entries(const uint8_t *ptr, uint32_t len)
{
static const char *command_list = "012345678:";
const char *cmd;
struct format_info *pfi;
struct format_info *pfi_last = NULL;
char linebuf[3][MAX_STRING];
uint32_t off = 0;
uint16_t bit_offset = 0;
uint8_t state = 0;
uint8_t cmd_index;
int c;
/*
* The format we are parsing:
* <string>{string,string}<next_string>{...}
*/
while (len--) {
c = *(ptr++);
/* skip some characters */
if (c == 0 || c == '\n' || c == '\r' || c == ' ' || c == '\t')
continue;
/* accumulate non-field delimiters */
if (strchr("{,}", c) == NULL) {
if (off < (MAX_STRING - 1)) {
linebuf[state][off] = c;
off++;
}
continue;
}
/* parse keyword */
linebuf[state][off] = 0;
off = 0;
state++;
if (state == 3) {
/* check for command in command list */
cmd = strchr(command_list, linebuf[2][0]);
if (cmd != NULL)
cmd_index = cmd - command_list;
else
cmd_index = 255;
/*
* Check for new field, format is:
*
* <field_name>{bit_offset_xor, bit_size}
*/
if (cmd_index < 9 && pfi_last != NULL) {
pfi = format_info_new(linebuf[0], bit_offset ^
atoi(linebuf[1]), cmd_index);
TAILQ_INSERT_TAIL(&pfi_last->fields, pfi, entry);
bit_offset += cmd_index;
}
/*
* Check for new section, format is:
*
* <section_name>{section_bit_size, :}
*/
if (cmd_index == 9) {
pfi_last = format_info_new(linebuf[0],
atoi(linebuf[1]), cmd_index);
TAILQ_INSERT_TAIL(&format_head, pfi_last, entry);
bit_offset = 0;
}
state = 0;
continue;
}
}
}

View File

@ -0,0 +1,35 @@
/* $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_SECTIONS_H_
#define _BUS_SECTIONS_H_
uint16_t format_get_section_size(const char *);
uint8_t format_get_field(const char *, const char *, const uint8_t *, uint16_t);
void format_parse_entries(const uint8_t *, uint32_t);
#endif /* _BUS_SECTIONS_H_ */

View File

@ -0,0 +1,386 @@
/* $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.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <sysexits.h>
#include <unistd.h>
#include <sys/queue.h>
#include "bus_autoconf.h"
#include "bus_sections.h"
#include "bus_usb.h"
struct usb_blob;
typedef TAILQ_HEAD(,usb_blob) usb_blob_head_t;
typedef TAILQ_ENTRY(usb_blob) usb_blob_entry_t;
static usb_blob_head_t usb_blob_head = TAILQ_HEAD_INITIALIZER(usb_blob_head);
static uint32_t usb_blob_count;
struct usb_blob {
usb_blob_entry_t entry;
struct usb_device_id temp;
};
/*
* To ensure that the correct USB driver is loaded, the driver having
* the most information about the device must be probed first. Then
* more generic drivers shall be probed.
*/
static int
usb_compare(const void *_a, const void *_b)
{
const struct usb_device_id *a = _a;
const struct usb_device_id *b = _b;
int retval;
/* vendor matches first */
if (a->match_flag_vendor > b->match_flag_vendor)
return (-1);
if (a->match_flag_vendor < b->match_flag_vendor)
return (1);
/* product matches first */
if (a->match_flag_product > b->match_flag_product)
return (-1);
if (a->match_flag_product < b->match_flag_product)
return (1);
/* device class matches first */
if (a->match_flag_dev_class > b->match_flag_dev_class)
return (-1);
if (a->match_flag_dev_class < b->match_flag_dev_class)
return (1);
if (a->match_flag_dev_subclass > b->match_flag_dev_subclass)
return (-1);
if (a->match_flag_dev_subclass < b->match_flag_dev_subclass)
return (1);
/* interface class matches first */
if (a->match_flag_int_class > b->match_flag_int_class)
return (-1);
if (a->match_flag_int_class < b->match_flag_int_class)
return (1);
if (a->match_flag_int_subclass > b->match_flag_int_subclass)
return (-1);
if (a->match_flag_int_subclass < b->match_flag_int_subclass)
return (1);
if (a->match_flag_int_protocol > b->match_flag_int_protocol)
return (-1);
if (a->match_flag_int_protocol < b->match_flag_int_protocol)
return (1);
/* then sort according to value */
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);
/* in the end sort by module name and mode */
retval = strcmp(a->module_name, b->module_name);
if (retval == 0)
retval = strcmp(a->module_mode, b->module_mode);
return (retval);
}
static void
usb_sort_entries(struct usb_device_id *id, uint32_t nid)
{
qsort(id, nid, sizeof(*id), &usb_compare);
}
static void
usb_import_entry(struct usb_device_id *id, const char *type,
const char *module, const uint8_t *ptr, uint16_t size)
{
const char *mode;
if (strstr(type, "_host_"))
mode = "host";
else if (strstr(type, "_device_"))
mode = "device";
else
mode = "(host|device)";
strlcpy(id->module_name, module, sizeof(id->module_name));
strlcpy(id->module_mode, mode, sizeof(id->module_mode));
/* import data from binary object */
if (format_get_field(type, "mfl_vendor", ptr, size))
id->match_flag_vendor = 1;
if (format_get_field(type, "mfl_product", ptr, size))
id->match_flag_product = 1;
if (format_get_field(type, "mfl_dev_lo", ptr, size))
id->match_flag_dev_lo = 1;
if (format_get_field(type, "mfl_dev_hi", ptr, size))
id->match_flag_dev_hi = 1;
if (format_get_field(type, "mfl_dev_class", ptr, size))
id->match_flag_dev_class = 1;
if (format_get_field(type, "mfl_dev_subclass", ptr, size))
id->match_flag_dev_subclass = 1;
if (format_get_field(type, "mfl_dev_protocol", ptr, size))
id->match_flag_dev_protocol = 1;
if (format_get_field(type, "mfl_int_class", ptr, size))
id->match_flag_int_class = 1;
if (format_get_field(type, "mfl_int_subclass", ptr, size))
id->match_flag_int_subclass = 1;
if (format_get_field(type, "mfl_int_protocol", ptr, size))
id->match_flag_int_protocol = 1;
id->idVendor = format_get_field(type, "idVendor[0]", ptr, size) |
(format_get_field(type, "idVendor[1]", ptr, size) << 8);
id->idProduct = format_get_field(type, "idProduct[0]", ptr, size) |
(format_get_field(type, "idProduct[1]", ptr, size) << 8);
id->bcdDevice_lo = format_get_field(type, "bcdDevice_lo[0]", ptr, size) |
(format_get_field(type, "bcdDevice_lo[1]", ptr, size) << 8);
id->bcdDevice_hi = format_get_field(type, "bcdDevice_hi[0]", ptr, size) |
(format_get_field(type, "bcdDevice_hi[1]", ptr, size) << 8);
id->bDeviceClass = format_get_field(type, "bDeviceClass", ptr, size);
id->bDeviceSubClass = format_get_field(type, "bDeviceSubClass", ptr, size);
id->bDeviceProtocol = format_get_field(type, "bDeviceProtocol", ptr, size);
id->bInterfaceClass = format_get_field(type, "bInterfaceClass", ptr, size);
id->bInterfaceSubClass = format_get_field(type, "bInterfaceSubClass", ptr, size);
id->bInterfaceProtocol = format_get_field(type, "bInterfaceProtocol", ptr, size);
if (format_get_field(type, "mf_vendor", ptr, size))
id->match_flag_vendor = 1;
if (format_get_field(type, "mf_product", ptr, size))
id->match_flag_product = 1;
if (format_get_field(type, "mf_dev_lo", ptr, size))
id->match_flag_dev_lo = 1;
if (format_get_field(type, "mf_dev_hi", ptr, size))
id->match_flag_dev_hi = 1;
if (format_get_field(type, "mf_dev_class", ptr, size))
id->match_flag_dev_class = 1;
if (format_get_field(type, "mf_dev_subclass", ptr, size))
id->match_flag_dev_subclass = 1;
if (format_get_field(type, "mf_dev_protocol", ptr, size))
id->match_flag_dev_protocol = 1;
if (format_get_field(type, "mf_int_class", ptr, size))
id->match_flag_int_class = 1;
if (format_get_field(type, "mf_int_subclass", ptr, size))
id->match_flag_int_subclass = 1;
if (format_get_field(type, "mf_int_protocol", ptr, size))
id->match_flag_int_protocol = 1;
/* compute some internal fields */
id->is_iface = id->match_flag_int_class |
id->match_flag_int_protocol |
id->match_flag_int_subclass;
id->is_dev = id->match_flag_dev_class |
id->match_flag_dev_subclass;
id->is_vp = id->match_flag_vendor |
id->match_flag_product;
id->is_any = id->is_vp + id->is_dev + id->is_iface;
}
static uint32_t
usb_dump(struct usb_device_id *id, uint32_t nid)
{
uint32_t n = 1;
if (id->is_any) {
printf("nomatch 32 {\n"
" match \"bus\" \"uhub[0-9]+\";\n"
" match \"mode\" \"%s\";\n", id->module_mode);
} else {
printf("# skipped entry on module %s\n",
id->module_name);
return (n);
}
if (id->match_flag_vendor) {
printf(" match \"vendor\" \"0x%04x\";\n",
id->idVendor);
}
if (id->match_flag_product) {
uint32_t x;
if (id->is_any == 1 && id->is_vp == 1) {
/* try to join similar entries */
while (n < nid) {
if (id[n].is_any != 1 || id[n].is_vp != 1)
break;
if (id[n].idVendor != id[0].idVendor)
break;
if (strcmp(id[n].module_name, id[0].module_name))
break;
if (strcmp(id[n].module_mode, id[0].module_mode))
break;
n++;
}
}
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", id->module_name);
return (n);
}
void
usb_import_entries(const char *section, const char *module,
const uint8_t *ptr, uint32_t len)
{
struct usb_blob *pub;
uint32_t section_size;
uint32_t off;
section_size = format_get_section_size(section);
if (section_size == 0) {
errx(EX_DATAERR, "Invalid or non-existing "
"section format '%s'", section);
}
if (len % section_size) {
errx(EX_DATAERR, "Length %d is not "
"divisible by %d. Section format '%s'",
len, section_size, section);
}
for (off = 0; off != len; off += section_size) {
pub = malloc(sizeof(*pub));
if (pub == NULL)
errx(EX_SOFTWARE, "Out of memory");
memset(pub, 0, sizeof(*pub));
usb_import_entry(&pub->temp, section,
module, ptr + off, section_size);
TAILQ_INSERT_TAIL(&usb_blob_head, pub, entry);
usb_blob_count++;
if (usb_blob_count == 0)
errx(EX_SOFTWARE, "Too many entries");
}
}
void
usb_dump_entries(void)
{
struct usb_blob *pub;
struct usb_device_id *id;
uint32_t x;
id = malloc(usb_blob_count * sizeof(*id));
if (id == NULL)
errx(EX_SOFTWARE, "Out of memory");
/* make linear array of all USB blobs */
x = 0;
TAILQ_FOREACH(pub, &usb_blob_head, entry)
id[x++] = pub->temp;
usb_sort_entries(id, usb_blob_count);
for (x = 0; x != usb_blob_count;)
x += usb_dump(id + x, usb_blob_count - x);
free(id);
printf("# %d USB entries processed\n\n", usb_blob_count);
}

View File

@ -0,0 +1,73 @@
/* $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_USB_H_
#define _BUS_USB_H_
struct usb_device_id {
/* Internal fields */
char module_name[32];
char module_mode[32];
uint8_t is_iface;
uint8_t is_vp;
uint8_t is_dev;
uint8_t is_any;
/* 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;
};
void usb_import_entries(const char *, const char *, const uint8_t *, uint32_t);
void usb_dump_entries(void);
#endif /* _BUS_USB_H_ */

View File

@ -289,7 +289,7 @@
10/18 Sheldon Hearn <sheldonh@FreeBSD.org> born in Cape Town, Western Cape, South Africa, 1974
10/19 Nicholas Souchu <nsouch@FreeBSD.org> born in Suresnes, Hauts-de-Seine, France, 1972
10/19 Nick Barkas <snb@FreeBSD.org> born in Longview, Washington, United States, 1981
10/20 Joel Dahl <joel@FreeBSD.org> born in Lidkoping, Sweden, 1983
10/20 Joel Dahl <joel@FreeBSD.org> born in Bitterna, Skaraborg, Sweden, 1983
10/20 Dmitry Marakasov <amdmi3@FreeBSD.org> born in Moscow, Russian Federation, 1984
10/21 Ben Smithurst <ben@FreeBSD.org> born in Sheffield, South Yorkshire, United Kingdom, 1981
10/22 Jean-Sebastien Pedron <dumbbell@FreeBSD.org> born in Redon, Ille-et-Vilaine, France, 1980

View File

@ -226,7 +226,11 @@ yes(const char *fmt, ...)
fflush(stderr);
l = read(2, buff, sizeof(buff) - 1);
if (l <= 0)
if (l < 0) {
fprintf(stderr, "Keyboard read failed\n");
exit(1);
}
if (l == 0)
return (0);
buff[l] = 0;

View File

@ -919,6 +919,7 @@ write_entry_backend(struct bsdtar *bsdtar, struct archive *a,
const char *pathname = archive_entry_sourcepath(entry);
fd = open(pathname, O_RDONLY | O_BINARY);
if (fd == -1) {
bsdtar->return_value = 1;
if (!bsdtar->verbose)
bsdtar_warnc(errno,
"%s: could not open file", pathname);
@ -1020,6 +1021,12 @@ write_file_data(struct bsdtar *bsdtar, struct archive *a,
progress += bytes_written;
bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN);
}
if (bytes_read < 0) {
bsdtar_warnc(errno,
"%s: Read error",
archive_entry_pathname(entry));
bsdtar->return_value = 1;
}
return 0;
}

View File

@ -204,14 +204,16 @@ main(int argc, char **argv)
s6 = -1;
#ifdef INET
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1)
if (s == -1 && errno != EPROTONOSUPPORT)
err(1, "can't open IPv4 socket");
#endif
#ifdef INET6
s6 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (s6 == -1)
if (s6 == -1 && errno != EPROTONOSUPPORT)
err(1, "can't open IPv6 socket");
#endif
if (s == -1 && s6 == -1)
errc(1, EPROTONOSUPPORT, "can't open socket");
if (argc < 2) {
if (isatty(STDIN_FILENO)) {
@ -371,7 +373,7 @@ af2socklen(const int af)
}
static void
process_cmd(char *cmd, int s, int s6 __unused, FILE *fp __unused)
process_cmd(char *cmd, int s, int s6, FILE *fp __unused)
{
char str1[STR_SIZE];
char str2[STR_SIZE];
@ -457,7 +459,10 @@ process_cmd(char *cmd, int s, int s6 __unused, FILE *fp __unused)
optval = (void *)&mr.mr;
optlen = sizeof(mr.mr);
}
if (setsockopt(s, level, optname, optval,
if (s < 0) {
warnc(EPROTONOSUPPORT, "setsockopt %s",
toptname);
} else if (setsockopt(s, level, optname, optval,
optlen) == 0) {
printf("ok\n");
break;
@ -496,7 +501,10 @@ process_cmd(char *cmd, int s, int s6 __unused, FILE *fp __unused)
optval = (void *)&mr.mr6;
optlen = sizeof(mr.mr6);
}
if (setsockopt(s6, level, optname, optval,
if (s6 < 0) {
warnc(EPROTONOSUPPORT, "setsockopt %s",
toptname);
} else if (setsockopt(s6, level, optname, optval,
optlen) == 0) {
printf("ok\n");
break;
@ -534,6 +542,10 @@ process_cmd(char *cmd, int s, int s6 __unused, FILE *fp __unused)
break;
}
af = su.sa.sa_family;
if (af2sock(af, s, s6) == -1) {
warnc(EPROTONOSUPPORT, "setsourcefilter");
break;
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_flags = AI_NUMERICHOST;
@ -593,6 +605,10 @@ process_cmd(char *cmd, int s, int s6 __unused, FILE *fp __unused)
break;
}
af = su.sa.sa_family;
if (af2sock(af, s, s6) == -1) {
warnc(EPROTONOSUPPORT, "getsourcefilter");
break;
}
/* First determine our current filter mode. */
n = 0;
@ -700,6 +716,10 @@ process_cmd(char *cmd, int s, int s6 __unused, FILE *fp __unused)
}
af = su.sa.sa_family;
if (af2sock(af, s, s6) == -1) {
warnc(EPROTONOSUPPORT, "getsourcefilter");
break;
}
nsrc = nreqsrc;
if (getsourcefilter(af2sock(af, s, s6), ifindex, &su.sa,
su.sa.sa_len, &fmode, &nsrc, &sources[0].ss) != 0) {