MFC
This commit is contained in:
commit
cfdfd32d34
30
bin/sh/sh.1
30
bin/sh/sh.1
@ -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 - ,
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
FILES= asus.conf uath.conf
|
||||
FILES= asus.conf uath.conf usb.conf
|
||||
|
||||
NO_OBJ=
|
||||
FILESDIR= /etc/devd
|
||||
|
@ -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
4275
etc/devd/usb.conf
Normal file
File diff suppressed because it is too large
Load Diff
@ -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>
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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}/.)
|
||||
|
@ -1,3 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if ${MK_FDT} != "no"
|
||||
SUBDIR+= fdt
|
||||
.endif
|
||||
|
||||
SUBDIR+= uboot
|
||||
|
@ -1,4 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if ${MK_FDT} != "no"
|
||||
SUBDIR+= fdt
|
||||
.endif
|
||||
|
||||
SUBDIR+= ofw
|
||||
SUBDIR+= uboot
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
130
sys/dev/pci/pci_subr.c
Normal 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;
|
||||
}
|
@ -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");
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -27,8 +27,6 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_kdb.h"
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 =
|
||||
|
16
tools/regression/bin/sh/builtins/case10.0
Normal file
16
tools/regression/bin/sh/builtins/case10.0
Normal 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
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
111
tools/tools/bus_autoconf/bus_autoconf_format_example.txt
Normal file
111
tools/tools/bus_autoconf/bus_autoconf_format_example.txt
Normal 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 "}"
|
||||
};
|
76
tools/tools/bus_autoconf/bus_load_file.c
Normal file
76
tools/tools/bus_autoconf/bus_load_file.c
Normal 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;
|
||||
}
|
33
tools/tools/bus_autoconf/bus_load_file.h
Normal file
33
tools/tools/bus_autoconf/bus_load_file.h
Normal 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_ */
|
223
tools/tools/bus_autoconf/bus_sections.c
Normal file
223
tools/tools/bus_autoconf/bus_sections.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
35
tools/tools/bus_autoconf/bus_sections.h
Normal file
35
tools/tools/bus_autoconf/bus_sections.h
Normal 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_ */
|
386
tools/tools/bus_autoconf/bus_usb.c
Normal file
386
tools/tools/bus_autoconf/bus_usb.c
Normal 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);
|
||||
}
|
73
tools/tools/bus_autoconf/bus_usb.h
Normal file
73
tools/tools/bus_autoconf/bus_usb.h
Normal 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_ */
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user