mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
Merge ^/head r274961 through r275684.
This commit is contained in:
commit
377af4f123
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang350-import/; revision=275685
@ -5,8 +5,7 @@ MAN = freebsd-version.1
|
||||
CLEANFILES = freebsd-version.sh
|
||||
NEWVERS = ${.CURDIR}/../../sys/conf/newvers.sh
|
||||
|
||||
freebsd-version.sh.in: ${NEWVERS}
|
||||
freebsd-version.sh: ${.CURDIR}/freebsd-version.sh.in
|
||||
freebsd-version.sh: ${.CURDIR}/freebsd-version.sh.in ${NEWVERS}
|
||||
eval $$(egrep '^(TYPE|REVISION|BRANCH)=' ${NEWVERS}) ; \
|
||||
if ! sed -e "\
|
||||
s/@@TYPE@@/$${TYPE}/g; \
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $File: file.man,v 1.106 2014/03/07 23:11:51 christos Exp $
|
||||
.Dd January 30, 2014
|
||||
.Dd December 3, 2014
|
||||
.Dt FILE __CSECTION__
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -385,6 +385,7 @@ options.
|
||||
.Xr hexdump 1 ,
|
||||
.Xr od 1 ,
|
||||
.Xr strings 1 ,
|
||||
.Xr fstyp 8
|
||||
.Sh STANDARDS CONFORMANCE
|
||||
This program is believed to exceed the System V Interface Definition
|
||||
of FILE(CMD), as near as one can determine from the vague language
|
||||
|
@ -35,10 +35,12 @@
|
||||
switch (type) {
|
||||
#ifdef ELFCORE
|
||||
case ET_CORE:
|
||||
phnum = elf_getu16(swap, elfhdr.e_phnum);
|
||||
if (phnum > MAX_PHNUM)
|
||||
return toomany(ms, "program", phnum);
|
||||
flags |= FLAGS_IS_CORE;
|
||||
if (dophn_core(ms, clazz, swap, fd,
|
||||
(off_t)elf_getu(swap, elfhdr.e_phoff),
|
||||
elf_getu16(swap, elfhdr.e_phnum),
|
||||
(off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
|
||||
(size_t)elf_getu16(swap, elfhdr.e_phentsize),
|
||||
fsize, &flags) == -1)
|
||||
return -1;
|
||||
@ -46,18 +48,24 @@
|
||||
#endif
|
||||
case ET_EXEC:
|
||||
case ET_DYN:
|
||||
phnum = elf_getu16(swap, elfhdr.e_phnum);
|
||||
if (phnum > MAX_PHNUM)
|
||||
return toomany(ms, "program", phnum);
|
||||
shnum = elf_getu16(swap, elfhdr.e_shnum);
|
||||
if (shnum > MAX_SHNUM)
|
||||
return toomany(ms, "section", shnum);
|
||||
if (dophn_exec(ms, clazz, swap, fd,
|
||||
(off_t)elf_getu(swap, elfhdr.e_phoff),
|
||||
elf_getu16(swap, elfhdr.e_phnum),
|
||||
(off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
|
||||
(size_t)elf_getu16(swap, elfhdr.e_phentsize),
|
||||
fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
|
||||
== -1)
|
||||
fsize, &flags, shnum) == -1)
|
||||
return -1;
|
||||
/*FALLTHROUGH*/
|
||||
case ET_REL:
|
||||
shnum = elf_getu16(swap, elfhdr.e_shnum);
|
||||
if (shnum > MAX_SHNUM)
|
||||
return toomany(ms, "section", shnum);
|
||||
if (doshn(ms, clazz, swap, fd,
|
||||
(off_t)elf_getu(swap, elfhdr.e_shoff),
|
||||
elf_getu16(swap, elfhdr.e_shnum),
|
||||
(off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
|
||||
(size_t)elf_getu16(swap, elfhdr.e_shentsize),
|
||||
fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
|
||||
(int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
|
||||
|
@ -482,6 +482,14 @@ protected int file_regexec(file_regex_t *, const char *, size_t, regmatch_t *,
|
||||
protected void file_regfree(file_regex_t *);
|
||||
protected void file_regerror(file_regex_t *, int, struct magic_set *);
|
||||
|
||||
typedef struct {
|
||||
char *buf;
|
||||
uint32_t offset;
|
||||
} file_pushbuf_t;
|
||||
|
||||
protected file_pushbuf_t *file_push_buffer(struct magic_set *);
|
||||
protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
|
||||
|
||||
#ifndef COMPILE_ONLY
|
||||
extern const char *file_names[];
|
||||
extern const size_t file_nnames;
|
||||
|
@ -491,3 +491,43 @@ file_regerror(file_regex_t *rx, int rc, struct magic_set *ms)
|
||||
file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat,
|
||||
errmsg);
|
||||
}
|
||||
|
||||
protected file_pushbuf_t *
|
||||
file_push_buffer(struct magic_set *ms)
|
||||
{
|
||||
file_pushbuf_t *pb;
|
||||
|
||||
if (ms->event_flags & EVENT_HAD_ERR)
|
||||
return NULL;
|
||||
|
||||
if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
|
||||
return NULL;
|
||||
|
||||
pb->buf = ms->o.buf;
|
||||
pb->offset = ms->offset;
|
||||
|
||||
ms->o.buf = NULL;
|
||||
ms->offset = 0;
|
||||
|
||||
return pb;
|
||||
}
|
||||
|
||||
protected char *
|
||||
file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
|
||||
{
|
||||
char *rbuf;
|
||||
|
||||
if (ms->event_flags & EVENT_HAD_ERR) {
|
||||
free(pb->buf);
|
||||
free(pb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rbuf = ms->o.buf;
|
||||
|
||||
ms->o.buf = pb->buf;
|
||||
ms->offset = pb->offset;
|
||||
|
||||
free(pb);
|
||||
return rbuf;
|
||||
}
|
||||
|
@ -60,6 +60,18 @@ private uint16_t getu16(int, uint16_t);
|
||||
private uint32_t getu32(int, uint32_t);
|
||||
private uint64_t getu64(int, uint64_t);
|
||||
|
||||
#define MAX_PHNUM 256
|
||||
#define MAX_SHNUM 1024
|
||||
|
||||
private int
|
||||
toomany(struct magic_set *ms, const char *name, uint16_t num)
|
||||
{
|
||||
if (file_printf(ms, ", too many %s header sections (%u)", name, num
|
||||
) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private uint16_t
|
||||
getu16(int swap, uint16_t value)
|
||||
{
|
||||
@ -477,6 +489,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
|
||||
uint32_t namesz, descsz;
|
||||
unsigned char *nbuf = CAST(unsigned char *, vbuf);
|
||||
|
||||
if (xnh_sizeof + offset > size) {
|
||||
/*
|
||||
* We're out of note headers.
|
||||
*/
|
||||
return xnh_sizeof + offset;
|
||||
}
|
||||
|
||||
(void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
|
||||
offset += xnh_sizeof;
|
||||
|
||||
@ -492,13 +511,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
|
||||
if (namesz & 0x80000000) {
|
||||
(void)file_printf(ms, ", bad note name size 0x%lx",
|
||||
(unsigned long)namesz);
|
||||
return offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (descsz & 0x80000000) {
|
||||
(void)file_printf(ms, ", bad note description size 0x%lx",
|
||||
(unsigned long)descsz);
|
||||
return offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -900,6 +919,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
|
||||
Elf32_Shdr sh32;
|
||||
Elf64_Shdr sh64;
|
||||
int stripped = 1;
|
||||
size_t nbadcap = 0;
|
||||
void *nbuf;
|
||||
off_t noff, coff, name_off;
|
||||
uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
|
||||
@ -988,6 +1008,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (nbadcap > 5)
|
||||
break;
|
||||
if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
|
||||
file_badseek(ms);
|
||||
return -1;
|
||||
@ -1053,6 +1075,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
|
||||
(unsigned long long)xcap_tag,
|
||||
(unsigned long long)xcap_val) == -1)
|
||||
return -1;
|
||||
if (nbadcap++ > 2)
|
||||
coff = xsh_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1233,7 +1257,7 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
|
||||
int flags = 0;
|
||||
Elf32_Ehdr elf32hdr;
|
||||
Elf64_Ehdr elf64hdr;
|
||||
uint16_t type;
|
||||
uint16_t type, phnum, shnum;
|
||||
|
||||
if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
|
||||
return 0;
|
||||
|
@ -67,6 +67,9 @@ private void cvt_32(union VALUETYPE *, const struct magic *);
|
||||
private void cvt_64(union VALUETYPE *, const struct magic *);
|
||||
|
||||
#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
|
||||
|
||||
#define MAX_RECURSION_LEVEL 10
|
||||
|
||||
/*
|
||||
* softmagic - lookup one file in parsed, in-memory copy of database
|
||||
* Passed the name and FILE * of one file to be typed.
|
||||
@ -1193,14 +1196,15 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
||||
int flip, int recursion_level, int *printed_something,
|
||||
int *need_separator, int *returnval)
|
||||
{
|
||||
uint32_t soffset, offset = ms->offset;
|
||||
uint32_t offset = ms->offset;
|
||||
uint32_t lhs;
|
||||
file_pushbuf_t *pb;
|
||||
int rv, oneed_separator, in_type;
|
||||
char *sbuf, *rbuf;
|
||||
char *rbuf;
|
||||
union VALUETYPE *p = &ms->ms_value;
|
||||
struct mlist ml;
|
||||
|
||||
if (recursion_level >= 20) {
|
||||
if (recursion_level >= MAX_RECURSION_LEVEL) {
|
||||
file_error(ms, 0, "recursion nesting exceeded");
|
||||
return -1;
|
||||
}
|
||||
@ -1644,19 +1648,23 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
||||
case FILE_INDIRECT:
|
||||
if (offset == 0)
|
||||
return 0;
|
||||
|
||||
if (nbytes < offset)
|
||||
return 0;
|
||||
sbuf = ms->o.buf;
|
||||
soffset = ms->offset;
|
||||
ms->o.buf = NULL;
|
||||
ms->offset = 0;
|
||||
|
||||
if ((pb = file_push_buffer(ms)) == NULL)
|
||||
return -1;
|
||||
|
||||
rv = file_softmagic(ms, s + offset, nbytes - offset,
|
||||
recursion_level, BINTEST, text);
|
||||
|
||||
if ((ms->flags & MAGIC_DEBUG) != 0)
|
||||
fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
|
||||
rbuf = ms->o.buf;
|
||||
ms->o.buf = sbuf;
|
||||
ms->offset = soffset;
|
||||
|
||||
rbuf = file_pop_buffer(ms, pb);
|
||||
if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR)
|
||||
return -1;
|
||||
|
||||
if (rv == 1) {
|
||||
if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
|
||||
file_printf(ms, F(ms, m, "%u"), offset) == -1) {
|
||||
@ -1674,13 +1682,13 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
|
||||
case FILE_USE:
|
||||
if (nbytes < offset)
|
||||
return 0;
|
||||
sbuf = m->value.s;
|
||||
if (*sbuf == '^') {
|
||||
sbuf++;
|
||||
rbuf = m->value.s;
|
||||
if (*rbuf == '^') {
|
||||
rbuf++;
|
||||
flip = !flip;
|
||||
}
|
||||
if (file_magicfind(ms, sbuf, &ml) == -1) {
|
||||
file_error(ms, 0, "cannot find entry `%s'", sbuf);
|
||||
if (file_magicfind(ms, rbuf, &ml) == -1) {
|
||||
file_error(ms, 0, "cannot find entry `%s'", rbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -3,3 +3,6 @@
|
||||
# Automounter master map, see auto_master(5) for details.
|
||||
#
|
||||
/net -hosts -nobrowse,nosuid
|
||||
# When using the -media special map, make sure to edit devd.conf(5)
|
||||
# to move the call to "automount -c" out of the comments section.
|
||||
#/media -media -nosuid
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
FILES= include_ldap special_hosts special_null
|
||||
FILES= include_ldap special_hosts special_media special_null
|
||||
|
||||
NO_OBJ=
|
||||
FILESDIR= /etc/autofs
|
||||
|
93
etc/autofs/special_media
Executable file
93
etc/autofs/special_media
Executable file
@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# Print newline-separated list of devices available for mounting.
|
||||
# If there is a filesystem label - use it, otherwise use device name.
|
||||
print_available() {
|
||||
local _fstype _fstype_and_label _label _p
|
||||
|
||||
for _p in ${providers}; do
|
||||
_fstype_and_label="$(fstyp -l "/dev/${_p}" 2> /dev/null)"
|
||||
if [ $? -ne 0 ]; then
|
||||
# Ignore devices for which we were unable
|
||||
# to determine filesystem type.
|
||||
continue
|
||||
fi
|
||||
|
||||
_fstype="${_fstype_and_label%% *}"
|
||||
if [ "${_fstype}" != "${_fstype_and_label}" ]; then
|
||||
_label="${_fstype_and_label#* }"
|
||||
echo "${_label}"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "${_p}"
|
||||
done
|
||||
}
|
||||
|
||||
# Print a single map entry.
|
||||
print_one() {
|
||||
local _fstype _fstype_and_label _label _key _p
|
||||
|
||||
_key="$1"
|
||||
|
||||
_fstype="$(fstyp "/dev/${_key}" 2> /dev/null)"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "-fstype=${_fstype},nosuid :/dev/${_key}"
|
||||
return
|
||||
fi
|
||||
|
||||
for _p in ${providers}; do
|
||||
_fstype_and_label="$(fstyp -l "/dev/${_p}" 2> /dev/null)"
|
||||
if [ $? -ne 0 ]; then
|
||||
# Ignore devices for which we were unable
|
||||
# to determine filesystem type.
|
||||
continue
|
||||
fi
|
||||
|
||||
_fstype="${_fstype_and_label%% *}"
|
||||
if [ "${_fstype}" = "${_fstype_and_label}" ]; then
|
||||
# No label, try another device.
|
||||
continue
|
||||
fi
|
||||
|
||||
_label="${_fstype_and_label#* }"
|
||||
if [ "${_label}" != "${_key}" ]; then
|
||||
# Labels don't match, try another device.
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "-fstype=${_fstype},nosuid :/dev/${_p}"
|
||||
done
|
||||
|
||||
# No matching device - don't print anything, autofs will handle it.
|
||||
}
|
||||
|
||||
# Obtain a list of (geom-provider-name, access-count) pairs, turning this:
|
||||
#
|
||||
# z0xfffff80005085d00 [shape=hexagon,label="ada0\nr2w2e3\nerr#0\nsector=512\nstripe=0"];
|
||||
#
|
||||
# Into this:
|
||||
#
|
||||
# ada0 r2w2e3
|
||||
#
|
||||
# XXX: It would be easier to use kern.geom.conftxt instead, but it lacks
|
||||
# access counts.
|
||||
pairs=$(sysctl kern.geom.confdot | sed -n 's/^.*hexagon,label="\([^\]*\)\\n\([^\]*\).*/\1 \2/p')
|
||||
|
||||
# Obtain a list of GEOM providers that are not already open - not mounted,
|
||||
# and without other GEOM class, such as gpart, attached. In other words,
|
||||
# grep for "r0w0e0". Skip providers with names containing slashes; we're
|
||||
# not interested in geom_label(4) creations.
|
||||
providers=$(echo "$pairs" | awk '$2 == "r0w0e0" && $1 !~ /\// { print $1 }')
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
print_available
|
||||
exit 0
|
||||
fi
|
||||
|
||||
print_one "$1"
|
||||
exit 0
|
||||
|
@ -318,4 +318,16 @@ notify 0 {
|
||||
action "/usr/local/etc/rc.d/postgresql restart";
|
||||
};
|
||||
|
||||
# Discard autofs caches, useful for the -media special map. The one
|
||||
# second delay is for GEOM to finish tasting.
|
||||
#
|
||||
# XXX: We should probably have a devctl(4) event that fires after GEOM
|
||||
# tasting.
|
||||
#
|
||||
notify 100 {
|
||||
match "system" "DEVFS";
|
||||
match "cdev" "(da|mmcsd)[0-9]+";
|
||||
action "sleep 1 && /usr/sbin/automount -c";
|
||||
};
|
||||
|
||||
*/
|
||||
|
@ -96,7 +96,7 @@ kgdb_thr_add_procs(uintptr_t paddr)
|
||||
kt->kaddr = addr;
|
||||
if (td.td_tid == dumptid)
|
||||
kt->pcb = dumppcb;
|
||||
else if (td.td_state == TDS_RUNNING &&
|
||||
else if (td.td_oncpu != NOCPU &&
|
||||
CPU_ISSET(td.td_oncpu, &stopped_cpus))
|
||||
kt->pcb = kgdb_trgt_core_pcb(td.td_oncpu);
|
||||
else
|
||||
|
@ -886,7 +886,7 @@ sctp_recvv(int sd,
|
||||
struct sctp_rcvinfo *rcvinfo;
|
||||
struct sctp_nxtinfo *nxtinfo;
|
||||
|
||||
if (((info != NULL) && (infolen == NULL)) |
|
||||
if (((info != NULL) && (infolen == NULL)) ||
|
||||
((info == NULL) && (infolen != NULL) && (*infolen != 0)) ||
|
||||
((info != NULL) && (infotype == NULL))) {
|
||||
errno = EINVAL;
|
||||
|
@ -124,11 +124,13 @@ __sflush(FILE *fp)
|
||||
t = _swrite(fp, (char *)p, n);
|
||||
if (t <= 0) {
|
||||
/* Reset _p and _w. */
|
||||
if (p > fp->_p) /* Some was written. */
|
||||
if (p > fp->_p) {
|
||||
/* Some was written. */
|
||||
memmove(fp->_p, p, n);
|
||||
fp->_p += n;
|
||||
if ((fp->_flags & (__SLBF | __SNBF)) == 0)
|
||||
fp->_w -= n;
|
||||
fp->_p += n;
|
||||
if ((fp->_flags & (__SLBF | __SNBF)) == 0)
|
||||
fp->_w -= n;
|
||||
}
|
||||
fp->_flags |= __SERR;
|
||||
return (EOF);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)mount.8 8.8 (Berkeley) 6/16/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 22, 2014
|
||||
.Dd December 3, 2014
|
||||
.Dt MOUNT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -549,6 +549,7 @@ support for a particular file system might be provided either on a static
|
||||
.Xr fstab 5 ,
|
||||
.Xr procfs 5 ,
|
||||
.Xr automount 8 ,
|
||||
.Xr fstyp 8 ,
|
||||
.Xr kldload 8 ,
|
||||
.Xr mount_cd9660 8 ,
|
||||
.Xr mount_msdosfs 8 ,
|
||||
|
@ -26,5 +26,6 @@ dev/mmc/host/dwmmc.c optional dwmmc
|
||||
# BERI specific
|
||||
dev/beri/beri_ring.c optional beri_ring
|
||||
dev/beri/beri_mem.c optional beri_mem
|
||||
dev/beri/virtio/virtio.c optional beri_vtblk
|
||||
dev/beri/virtio/virtio.c optional beri_vtblk | vtbe
|
||||
dev/beri/virtio/virtio_block.c optional beri_vtblk
|
||||
dev/beri/virtio/network/if_vtbe.c optional vtbe
|
||||
|
@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
|
@ -142,14 +142,13 @@ bcmwd_watchdog_fn(void *private, u_int cmd, int *error)
|
||||
|
||||
if (cmd > 0) {
|
||||
sec = ((uint64_t)1 << (cmd & WD_INTERVAL)) / 1000000000;
|
||||
ticks = (sec << 16) & BCM2835_WDOG_TIME_MASK;
|
||||
if (ticks == 0) {
|
||||
if (sec == 0 || sec > 15) {
|
||||
/*
|
||||
* Can't arm
|
||||
* disable watchdog as watchdog(9) requires
|
||||
*/
|
||||
device_printf(sc->dev,
|
||||
"Can't arm, timeout is less than 1 second\n");
|
||||
"Can't arm, timeout must be between 1-15 seconds\n");
|
||||
WRITE(sc, BCM2835_RSTC_REG,
|
||||
(BCM2835_PASWORD << BCM2835_PASSWORD_SHIFT) |
|
||||
BCM2835_RSTC_RESET);
|
||||
@ -157,6 +156,7 @@ bcmwd_watchdog_fn(void *private, u_int cmd, int *error)
|
||||
return;
|
||||
}
|
||||
|
||||
ticks = (sec << 16) & BCM2835_WDOG_TIME_MASK;
|
||||
reg = (BCM2835_PASWORD << BCM2835_PASSWORD_SHIFT) | ticks;
|
||||
WRITE(sc, BCM2835_WDOG_REG, reg);
|
||||
|
||||
|
@ -123,6 +123,7 @@ device spibus
|
||||
device beri_ring
|
||||
device beri_mem
|
||||
device beri_vtblk
|
||||
device vtbe
|
||||
device altera_pio
|
||||
|
||||
# Ethernet
|
||||
|
@ -39,7 +39,8 @@
|
||||
compatible = "altr,socfpga-cyclone5", "altr,socfpga";
|
||||
|
||||
memreserve = < 0x00000000 0x1000 >, /* SMP trampoline */
|
||||
< 0x00001000 0x1000 >; /* virtio block */
|
||||
< 0x00001000 0x1000 >, /* virtio block */
|
||||
< 0x00002000 0x1000 >; /* virtio net */
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
@ -111,6 +112,15 @@
|
||||
pio-recv = <&pio0>;
|
||||
pio-send = <&pio1>;
|
||||
beri-mem = <&beri_mem0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
beri_vtnet: vtnet@00002000 {
|
||||
compatible = "sri-cambridge,beri-vtnet";
|
||||
reg = <0x00002000 0x1000>;
|
||||
pio-recv = <&pio0>;
|
||||
pio-send = <&pio1>;
|
||||
beri-mem = <&beri_mem0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -2651,6 +2651,7 @@ dev/xen/blkback/blkback.c optional xen | xenhvm
|
||||
dev/xen/console/console.c optional xen | xenhvm
|
||||
dev/xen/console/xencons_ring.c optional xen | xenhvm
|
||||
dev/xen/control/control.c optional xen | xenhvm
|
||||
dev/xen/grant_table/grant_table.c optional xen | xenhvm
|
||||
dev/xen/netback/netback.c optional xen | xenhvm
|
||||
dev/xen/netfront/netfront.c optional xen | xenhvm
|
||||
dev/xen/xenpci/xenpci.c optional xenpci
|
||||
@ -4000,7 +4001,6 @@ vm/vm_reserv.c standard
|
||||
vm/vm_unix.c standard
|
||||
vm/vm_zeroidle.c standard
|
||||
vm/vnode_pager.c standard
|
||||
xen/gnttab.c optional xen | xenhvm
|
||||
xen/features.c optional xen | xenhvm
|
||||
xen/xenbus/xenbus_if.m optional xen | xenhvm
|
||||
xen/xenbus/xenbus.c optional xen | xenhvm
|
||||
|
@ -336,6 +336,8 @@ dev/viawd/viawd.c optional viawd
|
||||
dev/vmware/vmxnet3/if_vmx.c optional vmx
|
||||
dev/wbwd/wbwd.c optional wbwd
|
||||
dev/wpi/if_wpi.c optional wpi
|
||||
dev/xen/pci/xen_acpi_pci.c optional xenhvm
|
||||
dev/xen/pci/xen_pci.c optional xenhvm
|
||||
dev/isci/isci.c optional isci
|
||||
dev/isci/isci_controller.c optional isci
|
||||
dev/isci/isci_domain.c optional isci
|
||||
@ -572,4 +574,4 @@ x86/xen/xen_apic.c optional xenhvm
|
||||
x86/xen/xenpv.c optional xenhvm
|
||||
x86/xen/xen_nexus.c optional xenhvm
|
||||
x86/xen/xen_msi.c optional xenhvm
|
||||
x86/xen/xen_pci.c optional xenhvm
|
||||
x86/xen/xen_pci_bus.c optional xenhvm
|
||||
|
655
sys/dev/beri/virtio/network/if_vtbe.c
Normal file
655
sys/dev/beri/virtio/network/if_vtbe.c
Normal file
@ -0,0 +1,655 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by SRI International and the University of
|
||||
* Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
|
||||
* ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* BERI Virtio Networking Frontend
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/timeet.h>
|
||||
#include <sys/timetc.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/mdioctl.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
#include <net/if.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_vlan_var.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/fdt.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <dev/beri/virtio/virtio.h>
|
||||
#include <dev/beri/virtio/virtio_mmio_platform.h>
|
||||
|
||||
#include <dev/altera/pio/pio.h>
|
||||
|
||||
#include <dev/virtio/mmio/virtio_mmio.h>
|
||||
#include <dev/virtio/network/virtio_net.h>
|
||||
#include <dev/virtio/virtio.h>
|
||||
#include <dev/virtio/virtio_ring.h>
|
||||
|
||||
#include "pio_if.h"
|
||||
|
||||
#define DPRINTF(fmt, args...) printf(fmt, ##args)
|
||||
|
||||
#define READ4(_sc, _reg) \
|
||||
bus_read_4((_sc)->res[0], _reg)
|
||||
#define WRITE4(_sc, _reg, _val) \
|
||||
bus_write_4((_sc)->res[0], _reg, _val)
|
||||
|
||||
#define VTBE_LOCK(sc) mtx_lock(&(sc)->mtx)
|
||||
#define VTBE_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
|
||||
#define VTBE_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED);
|
||||
#define VTBE_ASSERT_UNLOCKED(sc) mtx_assert(&(sc)->mtx, MA_NOTOWNED);
|
||||
|
||||
/*
|
||||
* Driver data and defines.
|
||||
*/
|
||||
#define DESC_COUNT 256
|
||||
|
||||
struct vtbe_softc {
|
||||
struct resource *res[2];
|
||||
bus_space_tag_t bst;
|
||||
bus_space_handle_t bsh;
|
||||
device_t dev;
|
||||
struct ifnet *ifp;
|
||||
int if_flags;
|
||||
struct mtx mtx;
|
||||
boolean_t is_attached;
|
||||
|
||||
int beri_mem_offset;
|
||||
device_t pio_send;
|
||||
device_t pio_recv;
|
||||
int opened;
|
||||
|
||||
struct vqueue_info vs_queues[2];
|
||||
int vs_curq;
|
||||
int hdrsize;
|
||||
};
|
||||
|
||||
static struct resource_spec vtbe_spec[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
static void vtbe_txfinish_locked(struct vtbe_softc *sc);
|
||||
static void vtbe_rxfinish_locked(struct vtbe_softc *sc);
|
||||
static void vtbe_stop_locked(struct vtbe_softc *sc);
|
||||
static int pio_enable_irq(struct vtbe_softc *sc, int enable);
|
||||
|
||||
static void
|
||||
vtbe_txstart_locked(struct vtbe_softc *sc)
|
||||
{
|
||||
struct virtio_net_hdr_mrg_rxbuf *vnh;
|
||||
struct iovec iov[DESC_COUNT];
|
||||
struct vqueue_info *vq;
|
||||
struct iovec *riov;
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *m;
|
||||
struct uio uio;
|
||||
int enqueued;
|
||||
int iolen;
|
||||
int error;
|
||||
int *addr;
|
||||
int reg;
|
||||
int len;
|
||||
int n;
|
||||
|
||||
VTBE_ASSERT_LOCKED(sc);
|
||||
|
||||
/* RX queue */
|
||||
vq = &sc->vs_queues[0];
|
||||
if (!vq_has_descs(vq)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ifp = sc->ifp;
|
||||
if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
enqueued = 0;
|
||||
|
||||
if (!vq_ring_ready(vq))
|
||||
return;
|
||||
|
||||
vq->vq_save_used = be16toh(vq->vq_used->idx);
|
||||
|
||||
for (;;) {
|
||||
if (!vq_has_descs(vq)) {
|
||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
break;
|
||||
}
|
||||
|
||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
n = vq_getchain(sc->beri_mem_offset, vq, iov,
|
||||
DESC_COUNT, NULL);
|
||||
|
||||
KASSERT(n >= 1 && n <= DESC_COUNT,
|
||||
("wrong descriptors num %d", n));
|
||||
|
||||
addr = iov[0].iov_base;
|
||||
len = iov[0].iov_len;
|
||||
|
||||
vnh = iov[0].iov_base;
|
||||
memset(vnh, 0, sc->hdrsize);
|
||||
vnh->num_buffers = htobe16(1);
|
||||
|
||||
iov[0].iov_len -= sc->hdrsize;
|
||||
iov[0].iov_base = (void *)((uintptr_t)iov[0].iov_base +
|
||||
sc->hdrsize);
|
||||
riov = &iov[0];
|
||||
|
||||
uio.uio_resid = iov[0].iov_len;
|
||||
uio.uio_iov = riov;
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_iovcnt = 1;
|
||||
uio.uio_offset = 0;
|
||||
uio.uio_rw = UIO_READ;
|
||||
|
||||
error = m_mbuftouio(&uio, m, 0);
|
||||
if (error)
|
||||
panic("m_mbuftouio failed\n");
|
||||
|
||||
iolen = (len - iov[0].iov_len - sc->hdrsize);
|
||||
vq_relchain(vq, iov, 0, iolen + sc->hdrsize);
|
||||
paddr_unmap((void *)addr, len);
|
||||
|
||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
|
||||
|
||||
BPF_MTAP(ifp, m);
|
||||
m_freem(m);
|
||||
|
||||
++enqueued;
|
||||
}
|
||||
|
||||
if (enqueued != 0) {
|
||||
reg = htobe32(VIRTIO_MMIO_INT_VRING);
|
||||
WRITE4(sc, VIRTIO_MMIO_INTERRUPT_STATUS, reg);
|
||||
|
||||
PIO_SET(sc->pio_send, Q_INTR, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vtbe_txstart(struct ifnet *ifp)
|
||||
{
|
||||
struct vtbe_softc *sc = ifp->if_softc;
|
||||
|
||||
VTBE_LOCK(sc);
|
||||
vtbe_txstart_locked(sc);
|
||||
VTBE_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbe_stop_locked(struct vtbe_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
|
||||
VTBE_ASSERT_LOCKED(sc);
|
||||
|
||||
ifp = sc->ifp;
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbe_init_locked(struct vtbe_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp = sc->ifp;
|
||||
|
||||
VTBE_ASSERT_LOCKED(sc);
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
return;
|
||||
|
||||
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
}
|
||||
|
||||
static void
|
||||
vtbe_init(void *if_softc)
|
||||
{
|
||||
struct vtbe_softc *sc = if_softc;
|
||||
|
||||
VTBE_LOCK(sc);
|
||||
vtbe_init_locked(sc);
|
||||
VTBE_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
vtbe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
struct ifmediareq *ifmr;
|
||||
struct vtbe_softc *sc;
|
||||
struct ifreq *ifr;
|
||||
int mask, error;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
ifr = (struct ifreq *)data;
|
||||
|
||||
error = 0;
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
VTBE_LOCK(sc);
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
pio_enable_irq(sc, 1);
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
|
||||
vtbe_init_locked(sc);
|
||||
}
|
||||
} else {
|
||||
pio_enable_irq(sc, 0);
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
vtbe_stop_locked(sc);
|
||||
}
|
||||
}
|
||||
sc->if_flags = ifp->if_flags;
|
||||
VTBE_UNLOCK(sc);
|
||||
break;
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
break;
|
||||
case SIOCSIFMEDIA:
|
||||
case SIOCGIFMEDIA:
|
||||
ifmr = (struct ifmediareq *)data;
|
||||
ifmr->ifm_count = 1;
|
||||
ifmr->ifm_status = (IFM_AVALID | IFM_ACTIVE);
|
||||
ifmr->ifm_active = (IFM_ETHER | IFM_10G_T | IFM_FDX);
|
||||
ifmr->ifm_current = ifmr->ifm_active;
|
||||
break;
|
||||
case SIOCSIFCAP:
|
||||
mask = ifp->if_capenable ^ ifr->ifr_reqcap;
|
||||
if (mask & IFCAP_VLAN_MTU) {
|
||||
ifp->if_capenable ^= IFCAP_VLAN_MTU;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIOCSIFADDR:
|
||||
pio_enable_irq(sc, 1);
|
||||
default:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbe_txfinish_locked(struct vtbe_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
|
||||
VTBE_ASSERT_LOCKED(sc);
|
||||
|
||||
ifp = sc->ifp;
|
||||
}
|
||||
|
||||
static int
|
||||
vq_init(struct vtbe_softc *sc)
|
||||
{
|
||||
struct vqueue_info *vq;
|
||||
uint8_t *base;
|
||||
int size;
|
||||
int reg;
|
||||
int pfn;
|
||||
|
||||
vq = &sc->vs_queues[sc->vs_curq];
|
||||
vq->vq_qsize = DESC_COUNT;
|
||||
|
||||
reg = READ4(sc, VIRTIO_MMIO_QUEUE_PFN);
|
||||
pfn = be32toh(reg);
|
||||
vq->vq_pfn = pfn;
|
||||
|
||||
size = vring_size(vq->vq_qsize, VRING_ALIGN);
|
||||
base = paddr_map(sc->beri_mem_offset,
|
||||
(pfn << PAGE_SHIFT), size);
|
||||
|
||||
/* First pages are descriptors */
|
||||
vq->vq_desc = (struct vring_desc *)base;
|
||||
base += vq->vq_qsize * sizeof(struct vring_desc);
|
||||
|
||||
/* Then avail ring */
|
||||
vq->vq_avail = (struct vring_avail *)base;
|
||||
base += (2 + vq->vq_qsize + 1) * sizeof(uint16_t);
|
||||
|
||||
/* Then it's rounded up to the next page */
|
||||
base = (uint8_t *)roundup2((uintptr_t)base, VRING_ALIGN);
|
||||
|
||||
/* And the last pages are the used ring */
|
||||
vq->vq_used = (struct vring_used *)base;
|
||||
|
||||
/* Mark queue as allocated, and start at 0 when we use it. */
|
||||
vq->vq_flags = VQ_ALLOC;
|
||||
vq->vq_last_avail = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbe_proc_rx(struct vtbe_softc *sc, struct vqueue_info *vq)
|
||||
{
|
||||
struct iovec iov[DESC_COUNT];
|
||||
struct ifnet *ifp;
|
||||
struct uio uio;
|
||||
struct mbuf *m;
|
||||
int iolen;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
ifp = sc->ifp;
|
||||
|
||||
n = vq_getchain(sc->beri_mem_offset, vq, iov,
|
||||
DESC_COUNT, NULL);
|
||||
|
||||
KASSERT(n >= 1 && n <= DESC_COUNT,
|
||||
("wrong n %d", n));
|
||||
|
||||
iolen = 0;
|
||||
for (i = 1; i < n; i++) {
|
||||
iolen += iov[i].iov_len;
|
||||
}
|
||||
|
||||
uio.uio_resid = iolen;
|
||||
uio.uio_iov = &iov[1];
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_iovcnt = (n - 1);
|
||||
uio.uio_rw = UIO_WRITE;
|
||||
|
||||
if ((m = m_uiotombuf(&uio, M_NOWAIT, 0, ETHER_ALIGN,
|
||||
M_PKTHDR)) == NULL) {
|
||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
|
||||
goto done;
|
||||
}
|
||||
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
|
||||
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
|
||||
|
||||
CURVNET_SET(ifp->if_vnet);
|
||||
VTBE_UNLOCK(sc);
|
||||
(*ifp->if_input)(ifp, m);
|
||||
VTBE_LOCK(sc);
|
||||
CURVNET_RESTORE();
|
||||
|
||||
done:
|
||||
vq_relchain(vq, iov, n, iolen + sc->hdrsize);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbe_rxfinish_locked(struct vtbe_softc *sc)
|
||||
{
|
||||
struct vqueue_info *vq;
|
||||
int reg;
|
||||
|
||||
/* TX queue */
|
||||
vq = &sc->vs_queues[1];
|
||||
if (!vq_ring_ready(vq))
|
||||
return;
|
||||
|
||||
/* Process new descriptors */
|
||||
vq->vq_save_used = be16toh(vq->vq_used->idx);
|
||||
|
||||
while (vq_has_descs(vq)) {
|
||||
vtbe_proc_rx(sc, vq);
|
||||
}
|
||||
|
||||
/* Interrupt the other side */
|
||||
reg = htobe32(VIRTIO_MMIO_INT_VRING);
|
||||
WRITE4(sc, VIRTIO_MMIO_INTERRUPT_STATUS, reg);
|
||||
|
||||
PIO_SET(sc->pio_send, Q_INTR, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbe_intr(void *arg)
|
||||
{
|
||||
struct vtbe_softc *sc;
|
||||
int pending;
|
||||
uint32_t reg;
|
||||
|
||||
sc = arg;
|
||||
|
||||
VTBE_LOCK(sc);
|
||||
|
||||
reg = PIO_READ(sc->pio_recv);
|
||||
|
||||
/* Ack */
|
||||
PIO_SET(sc->pio_recv, reg, 0);
|
||||
|
||||
pending = htobe32(reg);
|
||||
if (pending & Q_SEL) {
|
||||
reg = READ4(sc, VIRTIO_MMIO_QUEUE_SEL);
|
||||
sc->vs_curq = be32toh(reg);
|
||||
}
|
||||
|
||||
if (pending & Q_PFN) {
|
||||
vq_init(sc);
|
||||
}
|
||||
|
||||
if (pending & Q_NOTIFY) {
|
||||
/* beri rx / arm tx notify */
|
||||
vtbe_txfinish_locked(sc);
|
||||
}
|
||||
|
||||
if (pending & Q_NOTIFY1) {
|
||||
vtbe_rxfinish_locked(sc);
|
||||
}
|
||||
|
||||
VTBE_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
vtbe_get_hwaddr(struct vtbe_softc *sc, uint8_t *hwaddr)
|
||||
{
|
||||
int rnd;
|
||||
|
||||
/*
|
||||
* Generate MAC address, use 'bsd' + random 24 low-order bits.
|
||||
*/
|
||||
|
||||
rnd = arc4random() & 0x00ffffff;
|
||||
|
||||
hwaddr[0] = 'b';
|
||||
hwaddr[1] = 's';
|
||||
hwaddr[2] = 'd';
|
||||
hwaddr[3] = rnd >> 16;
|
||||
hwaddr[4] = rnd >> 8;
|
||||
hwaddr[5] = rnd >> 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pio_enable_irq(struct vtbe_softc *sc, int enable)
|
||||
{
|
||||
|
||||
/*
|
||||
* IRQ lines should be disabled while reprogram FPGA core.
|
||||
*/
|
||||
|
||||
if (enable) {
|
||||
if (sc->opened == 0) {
|
||||
sc->opened = 1;
|
||||
PIO_SETUP_IRQ(sc->pio_recv, vtbe_intr, sc);
|
||||
}
|
||||
} else {
|
||||
if (sc->opened == 1) {
|
||||
PIO_TEARDOWN_IRQ(sc->pio_recv);
|
||||
sc->opened = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
vtbe_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "sri-cambridge,beri-vtnet"))
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "Virtio BERI Ethernet Controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
vtbe_attach(device_t dev)
|
||||
{
|
||||
uint8_t macaddr[ETHER_ADDR_LEN];
|
||||
struct vtbe_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
int reg;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
|
||||
sc->hdrsize = sizeof(struct virtio_net_hdr_mrg_rxbuf);
|
||||
|
||||
if (bus_alloc_resources(dev, vtbe_spec, sc->res)) {
|
||||
device_printf(dev, "could not allocate resources\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Memory interface */
|
||||
sc->bst = rman_get_bustag(sc->res[0]);
|
||||
sc->bsh = rman_get_bushandle(sc->res[0]);
|
||||
|
||||
mtx_init(&sc->mtx, device_get_nameunit(sc->dev),
|
||||
MTX_NETWORK_LOCK, MTX_DEF);
|
||||
|
||||
if (setup_offset(dev, &sc->beri_mem_offset) != 0)
|
||||
return (ENXIO);
|
||||
if (setup_pio(dev, "pio-send", &sc->pio_send) != 0)
|
||||
return (ENXIO);
|
||||
if (setup_pio(dev, "pio-recv", &sc->pio_recv) != 0)
|
||||
return (ENXIO);
|
||||
|
||||
/* Setup MMIO */
|
||||
|
||||
/* Specify that we provide network device */
|
||||
reg = htobe32(VIRTIO_ID_NETWORK);
|
||||
WRITE4(sc, VIRTIO_MMIO_DEVICE_ID, reg);
|
||||
|
||||
/* The number of desc we support */
|
||||
reg = htobe32(DESC_COUNT);
|
||||
WRITE4(sc, VIRTIO_MMIO_QUEUE_NUM_MAX, reg);
|
||||
|
||||
/* Our features */
|
||||
reg = htobe32(VIRTIO_NET_F_MAC |
|
||||
VIRTIO_NET_F_MRG_RXBUF |
|
||||
VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
WRITE4(sc, VIRTIO_MMIO_HOST_FEATURES, reg);
|
||||
|
||||
/* Get MAC */
|
||||
if (vtbe_get_hwaddr(sc, macaddr)) {
|
||||
device_printf(sc->dev, "can't get mac\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Set up the ethernet interface. */
|
||||
sc->ifp = ifp = if_alloc(IFT_ETHER);
|
||||
ifp->if_baudrate = IF_Gbps(10);
|
||||
ifp->if_softc = sc;
|
||||
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
|
||||
ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX |
|
||||
IFF_MULTICAST | IFF_PROMISC);
|
||||
ifp->if_capabilities = IFCAP_VLAN_MTU;
|
||||
ifp->if_capenable = ifp->if_capabilities;
|
||||
ifp->if_start = vtbe_txstart;
|
||||
ifp->if_ioctl = vtbe_ioctl;
|
||||
ifp->if_init = vtbe_init;
|
||||
IFQ_SET_MAXLEN(&ifp->if_snd, DESC_COUNT - 1);
|
||||
ifp->if_snd.ifq_drv_maxlen = DESC_COUNT - 1;
|
||||
IFQ_SET_READY(&ifp->if_snd);
|
||||
ifp->if_hdrlen = sizeof(struct ether_vlan_header);
|
||||
|
||||
/* All ready to run, attach the ethernet interface. */
|
||||
ether_ifattach(ifp, macaddr);
|
||||
|
||||
sc->is_attached = true;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t vtbe_methods[] = {
|
||||
DEVMETHOD(device_probe, vtbe_probe),
|
||||
DEVMETHOD(device_attach, vtbe_attach),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t vtbe_driver = {
|
||||
"vtbe",
|
||||
vtbe_methods,
|
||||
sizeof(struct vtbe_softc),
|
||||
};
|
||||
|
||||
static devclass_t vtbe_devclass;
|
||||
|
||||
DRIVER_MODULE(vtbe, simplebus, vtbe_driver, vtbe_devclass, 0, 0);
|
||||
MODULE_DEPEND(vtbe, ether, 1, 1, 1);
|
@ -58,10 +58,18 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <dev/beri/virtio/virtio.h>
|
||||
#include <dev/virtio/virtio.h>
|
||||
#include <dev/virtio/virtqueue.h>
|
||||
#include <dev/virtio/virtio_ring.h>
|
||||
#include <dev/altera/pio/pio.h>
|
||||
|
||||
#include "pio_if.h"
|
||||
|
||||
int
|
||||
vq_ring_ready(struct vqueue_info *vq)
|
||||
@ -167,12 +175,13 @@ vq_relchain(struct vqueue_info *vq, struct iovec *iov, int n, uint32_t iolen)
|
||||
int i;
|
||||
|
||||
mask = vq->vq_qsize - 1;
|
||||
vu = vq->vq_used;
|
||||
head = be16toh(vq->vq_avail->ring[vq->vq_last_avail++ & mask]);
|
||||
|
||||
vu = vq->vq_used;
|
||||
uidx = be16toh(vu->idx);
|
||||
vue = &vu->ring[uidx++ & mask];
|
||||
vue->id = htobe16(head);
|
||||
vue->id = htobe32(head);
|
||||
|
||||
vue->len = htobe32(iolen);
|
||||
vu->idx = htobe16(uidx);
|
||||
|
||||
@ -181,3 +190,59 @@ vq_relchain(struct vqueue_info *vq, struct iovec *iov, int n, uint32_t iolen)
|
||||
paddr_unmap((void *)iov[i].iov_base, iov[i].iov_len);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
setup_pio(device_t dev, char *name, device_t *pio_dev)
|
||||
{
|
||||
phandle_t pio_node;
|
||||
struct fdt_ic *ic;
|
||||
phandle_t xref;
|
||||
phandle_t node;
|
||||
|
||||
if ((node = ofw_bus_get_node(dev)) == -1)
|
||||
return (ENXIO);
|
||||
|
||||
if (OF_searchencprop(node, name, &xref,
|
||||
sizeof(xref)) == -1) {
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
pio_node = OF_node_from_xref(xref);
|
||||
SLIST_FOREACH(ic, &fdt_ic_list_head, fdt_ics) {
|
||||
if (ic->iph == pio_node) {
|
||||
*pio_dev = ic->dev;
|
||||
PIO_CONFIGURE(*pio_dev, PIO_OUT_ALL,
|
||||
PIO_UNMASK_ALL);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
int
|
||||
setup_offset(device_t dev, uint32_t *offset)
|
||||
{
|
||||
pcell_t dts_value[2];
|
||||
phandle_t mem_node;
|
||||
phandle_t xref;
|
||||
phandle_t node;
|
||||
int len;
|
||||
|
||||
if ((node = ofw_bus_get_node(dev)) == -1)
|
||||
return (ENXIO);
|
||||
|
||||
if (OF_searchencprop(node, "beri-mem", &xref,
|
||||
sizeof(xref)) == -1) {
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
mem_node = OF_node_from_xref(xref);
|
||||
if ((len = OF_getproplen(mem_node, "reg")) <= 0)
|
||||
return (ENXIO);
|
||||
OF_getencprop(mem_node, "reg", dts_value, len);
|
||||
*offset = dts_value[0];
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -41,14 +41,10 @@
|
||||
|
||||
#define PAGE_SHIFT 12
|
||||
#define VRING_ALIGN 4096
|
||||
#define NUM_QUEUES 1
|
||||
|
||||
#define VQ_ALLOC 0x01 /* set once we have a pfn */
|
||||
#define VQ_MAX_DESCRIPTORS 512
|
||||
|
||||
#define VTBLK_BLK_ID_BYTES 20
|
||||
#define VTBLK_MAXSEGS 256
|
||||
|
||||
struct vqueue_info {
|
||||
uint16_t vq_qsize; /* size of this queue (a power of 2) */
|
||||
uint16_t vq_num;
|
||||
@ -70,3 +66,5 @@ int vq_getchain(uint32_t beri_mem_offset, struct vqueue_info *vq,
|
||||
struct iovec *iov, int n_iov, uint16_t *flags);
|
||||
void vq_relchain(struct vqueue_info *vq, struct iovec *iov, int n, uint32_t iolen);
|
||||
|
||||
int setup_pio(device_t dev, char *name, device_t *pio_dev);
|
||||
int setup_offset(device_t dev, uint32_t *offset);
|
||||
|
@ -74,6 +74,13 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define DPRINTF(fmt, ...)
|
||||
|
||||
/* We use indirect descriptors */
|
||||
#define NUM_DESCS 1
|
||||
#define NUM_QUEUES 1
|
||||
|
||||
#define VTBLK_BLK_ID_BYTES 20
|
||||
#define VTBLK_MAXSEGS 256
|
||||
|
||||
struct beri_vtblk_softc {
|
||||
struct resource *res[1];
|
||||
bus_space_tag_t bst;
|
||||
@ -286,8 +293,12 @@ vtblk_notify(struct beri_vtblk_softc *sc)
|
||||
while (vq_has_descs(vq))
|
||||
vtblk_proc(sc, vq);
|
||||
|
||||
/* Interrupt other side */
|
||||
PIO_SET(sc->pio_send, Q_INTR, 1);
|
||||
/* Interrupt the other side */
|
||||
if ((be16toh(vq->vq_avail->flags) & VRING_AVAIL_F_NO_INTERRUPT) == 0) {
|
||||
reg = htobe32(VIRTIO_MMIO_INT_VRING);
|
||||
WRITE4(sc, VIRTIO_MMIO_INTERRUPT_STATUS, reg);
|
||||
PIO_SET(sc->pio_send, Q_INTR, 1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -302,7 +313,7 @@ vq_init(struct beri_vtblk_softc *sc)
|
||||
int pfn;
|
||||
|
||||
vq = &sc->vs_queues[0];
|
||||
vq->vq_qsize = NUM_QUEUES;
|
||||
vq->vq_qsize = NUM_DESCS;
|
||||
|
||||
reg = READ4(sc, VIRTIO_MMIO_QUEUE_PFN);
|
||||
pfn = be32toh(reg);
|
||||
@ -352,61 +363,6 @@ vtblk_thread(void *arg)
|
||||
kthread_exit();
|
||||
}
|
||||
|
||||
static int
|
||||
setup_pio(struct beri_vtblk_softc *sc, char *name, device_t *dev)
|
||||
{
|
||||
phandle_t pio_node;
|
||||
struct fdt_ic *ic;
|
||||
phandle_t xref;
|
||||
phandle_t node;
|
||||
|
||||
if ((node = ofw_bus_get_node(sc->dev)) == -1)
|
||||
return (ENXIO);
|
||||
|
||||
if (OF_searchencprop(node, name, &xref,
|
||||
sizeof(xref)) == -1) {
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
pio_node = OF_node_from_xref(xref);
|
||||
SLIST_FOREACH(ic, &fdt_ic_list_head, fdt_ics) {
|
||||
if (ic->iph == pio_node) {
|
||||
*dev = ic->dev;
|
||||
PIO_CONFIGURE(*dev, PIO_OUT_ALL,
|
||||
PIO_UNMASK_ALL);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
setup_offset(struct beri_vtblk_softc *sc)
|
||||
{
|
||||
pcell_t dts_value[2];
|
||||
phandle_t mem_node;
|
||||
phandle_t xref;
|
||||
phandle_t node;
|
||||
int len;
|
||||
|
||||
if ((node = ofw_bus_get_node(sc->dev)) == -1)
|
||||
return (ENXIO);
|
||||
|
||||
if (OF_searchencprop(node, "beri-mem", &xref,
|
||||
sizeof(xref)) == -1) {
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
mem_node = OF_node_from_xref(xref);
|
||||
if ((len = OF_getproplen(mem_node, "reg")) <= 0)
|
||||
return (ENXIO);
|
||||
OF_getencprop(mem_node, "reg", dts_value, len);
|
||||
sc->beri_mem_offset = dts_value[0];
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
backend_info(struct beri_vtblk_softc *sc)
|
||||
{
|
||||
@ -419,9 +375,9 @@ backend_info(struct beri_vtblk_softc *sc)
|
||||
reg = htobe32(VIRTIO_ID_BLOCK);
|
||||
WRITE4(sc, VIRTIO_MMIO_DEVICE_ID, reg);
|
||||
|
||||
/* The number of queues we support */
|
||||
reg = htobe16(NUM_QUEUES);
|
||||
WRITE2(sc, VIRTIO_MMIO_QUEUE_NUM, reg);
|
||||
/* Queue size */
|
||||
reg = htobe32(NUM_DESCS);
|
||||
WRITE4(sc, VIRTIO_MMIO_QUEUE_NUM_MAX, reg);
|
||||
|
||||
/* Our features */
|
||||
reg = htobe32(VIRTIO_RING_F_INDIRECT_DESC
|
||||
@ -566,11 +522,11 @@ beri_vtblk_attach(device_t dev)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
if (setup_offset(sc) != 0)
|
||||
if (setup_offset(dev, &sc->beri_mem_offset) != 0)
|
||||
return (ENXIO);
|
||||
if (setup_pio(sc, "pio-send", &sc->pio_send) != 0)
|
||||
if (setup_pio(dev, "pio-send", &sc->pio_send) != 0)
|
||||
return (ENXIO);
|
||||
if (setup_pio(sc, "pio-recv", &sc->pio_recv) != 0)
|
||||
if (setup_pio(dev, "pio-recv", &sc->pio_recv) != 0)
|
||||
return (ENXIO);
|
||||
|
||||
sc->cdev = make_dev(&beri_cdevsw, 0, UID_ROOT, GID_WHEEL,
|
||||
|
@ -149,20 +149,49 @@ virtio_mmio_platform_attach(device_t dev)
|
||||
}
|
||||
|
||||
static int
|
||||
platform_note(device_t dev, size_t offset)
|
||||
platform_note(device_t dev, size_t offset, int val)
|
||||
{
|
||||
struct virtio_mmio_platform_softc *sc;
|
||||
int note;
|
||||
int i;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if (offset == VIRTIO_MMIO_QUEUE_NOTIFY) {
|
||||
mips_dcache_wbinv_all();
|
||||
PIO_SET(sc->pio_send, Q_NOTIFY, 1);
|
||||
switch (offset) {
|
||||
case (VIRTIO_MMIO_QUEUE_NOTIFY):
|
||||
if (val == 0)
|
||||
note = Q_NOTIFY;
|
||||
else if (val == 1)
|
||||
note = Q_NOTIFY1;
|
||||
break;
|
||||
case (VIRTIO_MMIO_QUEUE_PFN):
|
||||
note = Q_PFN;
|
||||
break;
|
||||
case (VIRTIO_MMIO_QUEUE_SEL):
|
||||
note = Q_SEL;
|
||||
break;
|
||||
default:
|
||||
note = 0;
|
||||
}
|
||||
|
||||
if (offset == VIRTIO_MMIO_QUEUE_PFN) {
|
||||
if (note) {
|
||||
mips_dcache_wbinv_all();
|
||||
PIO_SET(sc->pio_send, Q_PFN, 1);
|
||||
|
||||
PIO_SET(sc->pio_send, note, 1);
|
||||
|
||||
/*
|
||||
* Wait until host ack the request.
|
||||
* Usually done within few cycles.
|
||||
* TODO: bad
|
||||
*/
|
||||
|
||||
for (i = 100; i > 0; i--) {
|
||||
if (PIO_READ(sc->pio_send) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
device_printf(sc->dev, "Warning: host busy\n");
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
@ -30,6 +30,8 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define Q_NOTIFY 0x1
|
||||
#define Q_PFN 0x2
|
||||
#define Q_INTR 0x4
|
||||
#define Q_NOTIFY 0x01
|
||||
#define Q_PFN 0x02
|
||||
#define Q_INTR 0x04
|
||||
#define Q_SEL 0x08
|
||||
#define Q_NOTIFY1 0x10
|
||||
|
@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define MII_KSZPHY_RX_DATA_PAD_SKEW 0x105
|
||||
#define MII_KSZPHY_TX_DATA_PAD_SKEW 0x106
|
||||
|
||||
#define PS_TO_REG(p) (p / 200)
|
||||
#define PS_TO_REG(p) ((p) / 200)
|
||||
|
||||
static int micphy_probe(device_t);
|
||||
static int micphy_attach(device_t);
|
||||
@ -104,7 +104,8 @@ static const struct mii_phy_funcs micphy_funcs = {
|
||||
mii_phy_reset
|
||||
};
|
||||
|
||||
static void micphy_write(struct mii_softc *sc, uint32_t reg, uint32_t val)
|
||||
static void
|
||||
micphy_write(struct mii_softc *sc, uint32_t reg, uint32_t val)
|
||||
{
|
||||
|
||||
PHY_WRITE(sc, MII_KSZPHY_EXTREG, KSZPHY_EXTREG_WRITE | reg);
|
||||
|
@ -3195,7 +3195,7 @@ product NETGEAR EA101X 0x1002 Ethernet
|
||||
product NETGEAR FA101 0x1020 Ethernet 10/100, USB1.1
|
||||
product NETGEAR FA120 0x1040 USB 2.0 Ethernet
|
||||
product NETGEAR M4100 0x1100 M4100/M5300/M7100 series switch
|
||||
product NETGEAR WG111V2_2 0x4240 PrismGT USB 2.0 WLAN
|
||||
product NETGEAR WG111V1_2 0x4240 PrismGT USB 2.0 WLAN
|
||||
product NETGEAR WG111V3 0x4260 WG111v3
|
||||
product NETGEAR WG111U 0x4300 WG111U
|
||||
product NETGEAR WG111U_NF 0x4301 WG111U (no firmware)
|
||||
|
@ -182,7 +182,7 @@ static const STRUCT_USB_HOST_ID upgt_devs[] = {
|
||||
UPGT_DEV(FSC, E5400),
|
||||
UPGT_DEV(GLOBESPAN, PRISM_GT_1),
|
||||
UPGT_DEV(GLOBESPAN, PRISM_GT_2),
|
||||
UPGT_DEV(NETGEAR, WG111V2_2),
|
||||
UPGT_DEV(NETGEAR, WG111V1_2),
|
||||
UPGT_DEV(INTERSIL, PRISM_GT),
|
||||
UPGT_DEV(SMC, 2862WG),
|
||||
UPGT_DEV(USR, USR5422),
|
||||
|
@ -1,11 +1,15 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by SRI International and the University of
|
||||
* Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
|
||||
* ("CTSRD"), as part of the DARPA CRASH research programme.
|
||||
*
|
||||
* Portions of this software were developed by Andrew Turner
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -131,15 +135,24 @@ static void vtmmio_vq_intr(void *);
|
||||
/*
|
||||
* I/O port read/write wrappers.
|
||||
*/
|
||||
#define vtmmio_write_config_1(sc, o, v) \
|
||||
bus_write_1((sc)->res[0], (o), (v)); \
|
||||
VIRTIO_MMIO_NOTE(sc->platform, (o))
|
||||
#define vtmmio_write_config_2(sc, o, v) \
|
||||
bus_write_2((sc)->res[0], (o), (v)); \
|
||||
VIRTIO_MMIO_NOTE(sc->platform, (o))
|
||||
#define vtmmio_write_config_4(sc, o, v) \
|
||||
bus_write_4((sc)->res[0], (o), (v)); \
|
||||
VIRTIO_MMIO_NOTE(sc->platform, (o))
|
||||
#define vtmmio_write_config_1(sc, o, v) \
|
||||
do { \
|
||||
bus_write_1((sc)->res[0], (o), (v)); \
|
||||
if (sc->platform != NULL) \
|
||||
VIRTIO_MMIO_NOTE(sc->platform, (o), (v)); \
|
||||
} while (0)
|
||||
#define vtmmio_write_config_2(sc, o, v) \
|
||||
do { \
|
||||
bus_write_2((sc)->res[0], (o), (v)); \
|
||||
if (sc->platform != NULL) \
|
||||
VIRTIO_MMIO_NOTE(sc->platform, (o), (v)); \
|
||||
} while (0)
|
||||
#define vtmmio_write_config_4(sc, o, v) \
|
||||
do { \
|
||||
bus_write_4((sc)->res[0], (o), (v)); \
|
||||
if (sc->platform != NULL) \
|
||||
VIRTIO_MMIO_NOTE(sc->platform, (o), (v)); \
|
||||
} while (0)
|
||||
|
||||
#define vtmmio_read_config_1(sc, o) \
|
||||
bus_read_1((sc)->res[0], (o))
|
||||
@ -200,11 +213,13 @@ vtmmio_setup_intr(device_t dev, enum intr_type type)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
err = VIRTIO_MMIO_SETUP_INTR(sc->platform, sc->dev,
|
||||
vtmmio_vq_intr, sc);
|
||||
if (err == 0) {
|
||||
/* Okay we have backend-specific interrupts */
|
||||
return (0);
|
||||
if (sc->platform != NULL) {
|
||||
err = VIRTIO_MMIO_SETUP_INTR(sc->platform, sc->dev,
|
||||
vtmmio_vq_intr, sc);
|
||||
if (err == 0) {
|
||||
/* Okay we have backend-specific interrupts */
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
rid = 0;
|
||||
@ -473,8 +488,8 @@ vtmmio_alloc_virtqueues(device_t dev, int flags, int nvqs,
|
||||
struct vq_alloc_info *info;
|
||||
struct vtmmio_softc *sc;
|
||||
struct virtqueue *vq;
|
||||
uint32_t size;
|
||||
int idx, error;
|
||||
uint16_t size;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
@ -492,8 +507,10 @@ vtmmio_alloc_virtqueues(device_t dev, int flags, int nvqs,
|
||||
vqx = &sc->vtmmio_vqs[idx];
|
||||
info = &vq_info[idx];
|
||||
|
||||
vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_SEL, idx);
|
||||
|
||||
vtmmio_select_virtqueue(sc, idx);
|
||||
size = vtmmio_read_config_2(sc, VIRTIO_MMIO_QUEUE_NUM);
|
||||
size = vtmmio_read_config_4(sc, VIRTIO_MMIO_QUEUE_NUM_MAX);
|
||||
|
||||
error = virtqueue_alloc(dev, idx, size,
|
||||
VIRTIO_MMIO_VRING_ALIGN, 0xFFFFFFFFUL, info, &vq);
|
||||
@ -503,6 +520,10 @@ vtmmio_alloc_virtqueues(device_t dev, int flags, int nvqs,
|
||||
idx, error);
|
||||
break;
|
||||
}
|
||||
|
||||
vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_NUM, size);
|
||||
vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_ALIGN,
|
||||
VIRTIO_MMIO_VRING_ALIGN);
|
||||
#if 0
|
||||
device_printf(dev, "virtqueue paddr 0x%08lx\n",
|
||||
(uint64_t)virtqueue_paddr(vq));
|
||||
@ -572,7 +593,7 @@ vtmmio_notify_virtqueue(device_t dev, uint16_t queue)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
vtmmio_write_config_2(sc, VIRTIO_MMIO_QUEUE_NOTIFY, queue);
|
||||
vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_NOTIFY, queue);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@ -582,7 +603,7 @@ vtmmio_get_status(device_t dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
return (vtmmio_read_config_1(sc, VIRTIO_MMIO_STATUS));
|
||||
return (vtmmio_read_config_4(sc, VIRTIO_MMIO_STATUS));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -595,7 +616,7 @@ vtmmio_set_status(device_t dev, uint8_t status)
|
||||
if (status != VIRTIO_CONFIG_STATUS_RESET)
|
||||
status |= vtmmio_get_status(dev);
|
||||
|
||||
vtmmio_write_config_1(sc, VIRTIO_MMIO_STATUS, status);
|
||||
vtmmio_write_config_4(sc, VIRTIO_MMIO_STATUS, status);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -611,13 +632,16 @@ vtmmio_read_dev_config(device_t dev, bus_size_t offset,
|
||||
off = VIRTIO_MMIO_CONFIG + offset;
|
||||
|
||||
for (d = dst; length > 0; d += size, off += size, length -= size) {
|
||||
#ifdef ALLOW_WORD_ALIGNED_ACCESS
|
||||
if (length >= 4) {
|
||||
size = 4;
|
||||
*(uint32_t *)d = vtmmio_read_config_4(sc, off);
|
||||
} else if (length >= 2) {
|
||||
size = 2;
|
||||
*(uint16_t *)d = vtmmio_read_config_2(sc, off);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
size = 1;
|
||||
*d = vtmmio_read_config_1(sc, off);
|
||||
}
|
||||
@ -637,13 +661,16 @@ vtmmio_write_dev_config(device_t dev, bus_size_t offset,
|
||||
off = VIRTIO_MMIO_CONFIG + offset;
|
||||
|
||||
for (s = src; length > 0; s += size, off += size, length -= size) {
|
||||
#ifdef ALLOW_WORD_ALIGNED_ACCESS
|
||||
if (length >= 4) {
|
||||
size = 4;
|
||||
vtmmio_write_config_4(sc, off, *(uint32_t *)s);
|
||||
} else if (length >= 2) {
|
||||
size = 2;
|
||||
vtmmio_write_config_2(sc, off, *(uint16_t *)s);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
size = 1;
|
||||
vtmmio_write_config_1(sc, off, *s);
|
||||
}
|
||||
@ -711,7 +738,7 @@ vtmmio_reinit_virtqueue(struct vtmmio_softc *sc, int idx)
|
||||
KASSERT(vq != NULL, ("%s: vq %d not allocated", __func__, idx));
|
||||
|
||||
vtmmio_select_virtqueue(sc, idx);
|
||||
size = vtmmio_read_config_2(sc, VIRTIO_MMIO_QUEUE_NUM);
|
||||
size = vtmmio_read_config_4(sc, VIRTIO_MMIO_QUEUE_NUM_MAX);
|
||||
|
||||
error = virtqueue_reinit(vq, size);
|
||||
if (error)
|
||||
@ -778,7 +805,7 @@ static void
|
||||
vtmmio_select_virtqueue(struct vtmmio_softc *sc, int idx)
|
||||
{
|
||||
|
||||
vtmmio_write_config_2(sc, VIRTIO_MMIO_QUEUE_SEL, idx);
|
||||
vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_SEL, idx);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -787,14 +814,27 @@ vtmmio_vq_intr(void *arg)
|
||||
struct vtmmio_virtqueue *vqx;
|
||||
struct vtmmio_softc *sc;
|
||||
struct virtqueue *vq;
|
||||
uint32_t status;
|
||||
int idx;
|
||||
|
||||
sc = arg;
|
||||
|
||||
status = vtmmio_read_config_4(sc, VIRTIO_MMIO_INTERRUPT_STATUS);
|
||||
vtmmio_write_config_4(sc, VIRTIO_MMIO_INTERRUPT_ACK, status);
|
||||
|
||||
/* The config changed */
|
||||
if (status & VIRTIO_MMIO_INT_CONFIG)
|
||||
if (sc->vtmmio_child_dev != NULL)
|
||||
VIRTIO_CONFIG_CHANGE(sc->vtmmio_child_dev);
|
||||
|
||||
/* Notify all virtqueues. */
|
||||
for (idx = 0; idx < sc->vtmmio_nvqs; idx++) {
|
||||
vqx = &sc->vtmmio_vqs[idx];
|
||||
vq = vqx->vtv_vq;
|
||||
virtqueue_intr(vq);
|
||||
};
|
||||
if (status & VIRTIO_MMIO_INT_VRING) {
|
||||
for (idx = 0; idx < sc->vtmmio_nvqs; idx++) {
|
||||
vqx = &sc->vtmmio_vqs[idx];
|
||||
if (vqx->vtv_no_intr == 0) {
|
||||
vq = vqx->vtv_vq;
|
||||
virtqueue_intr(vq);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ INTERFACE virtio_mmio;
|
||||
|
||||
CODE {
|
||||
static int
|
||||
virtio_mmio_write(device_t dev, size_t offset)
|
||||
virtio_mmio_note(device_t dev, size_t offset, int val)
|
||||
{
|
||||
|
||||
return (1);
|
||||
@ -63,7 +63,8 @@ CODE {
|
||||
METHOD int note {
|
||||
device_t dev;
|
||||
size_t offset;
|
||||
} DEFAULT virtio_mmio_write;
|
||||
int val;
|
||||
} DEFAULT virtio_mmio_note;
|
||||
|
||||
#
|
||||
# Setup backend-specific interrupts.
|
||||
|
@ -659,16 +659,59 @@ gnttab_expand(unsigned int req_entries)
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
gnttab_init(device_t dev)
|
||||
MTX_SYSINIT(gnttab, &gnttab_list_lock, "GNTTAB LOCK", MTX_DEF);
|
||||
|
||||
/*------------------ Private Device Attachment Functions --------------------*/
|
||||
/**
|
||||
* \brief Identify instances of this device type in the system.
|
||||
*
|
||||
* \param driver The driver performing this identify action.
|
||||
* \param parent The NewBus parent device for any devices this method adds.
|
||||
*/
|
||||
static void
|
||||
granttable_identify(driver_t *driver __unused, device_t parent)
|
||||
{
|
||||
|
||||
KASSERT(xen_domain(),
|
||||
("Trying to attach grant-table device on non Xen domain"));
|
||||
/*
|
||||
* A single device instance for our driver is always present
|
||||
* in a system operating under Xen.
|
||||
*/
|
||||
if (BUS_ADD_CHILD(parent, 0, driver->name, 0) == NULL)
|
||||
panic("unable to attach Xen Grant-table device");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Probe for the existence of the Xen Grant-table device
|
||||
*
|
||||
* \param dev NewBus device_t for this instance.
|
||||
*
|
||||
* \return Always returns 0 indicating success.
|
||||
*/
|
||||
static int
|
||||
granttable_probe(device_t dev)
|
||||
{
|
||||
|
||||
device_set_desc(dev, "Xen Grant-table Device");
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Attach the Xen Grant-table device.
|
||||
*
|
||||
* \param dev NewBus device_t for this instance.
|
||||
*
|
||||
* \return On success, 0. Otherwise an errno value indicating the
|
||||
* type of failure.
|
||||
*/
|
||||
static int
|
||||
granttable_attach(device_t dev)
|
||||
{
|
||||
int i;
|
||||
unsigned int max_nr_glist_frames;
|
||||
unsigned int nr_init_grefs;
|
||||
|
||||
if (!is_running_on_xen())
|
||||
return (ENODEV);
|
||||
|
||||
nr_grant_frames = 1;
|
||||
boot_max_nr_grant_frames = __max_nr_grant_frames();
|
||||
|
||||
@ -714,7 +757,20 @@ gnttab_init(device_t dev)
|
||||
free(gnttab_list[i], M_DEVBUF);
|
||||
free(gnttab_list, M_DEVBUF);
|
||||
return (ENOMEM);
|
||||
|
||||
}
|
||||
|
||||
MTX_SYSINIT(gnttab, &gnttab_list_lock, "GNTTAB LOCK", MTX_DEF);
|
||||
/*-------------------- Private Device Attachment Data -----------------------*/
|
||||
static device_method_t granttable_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_identify, granttable_identify),
|
||||
DEVMETHOD(device_probe, granttable_probe),
|
||||
DEVMETHOD(device_attach, granttable_attach),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_0(granttable, granttable_driver, granttable_methods, 0);
|
||||
devclass_t granttable_devclass;
|
||||
|
||||
DRIVER_MODULE_ORDERED(granttable, xenpv, granttable_driver, granttable_devclass,
|
||||
NULL, NULL, SI_ORDER_FIRST);
|
88
sys/dev/xen/pci/xen_acpi_pci.c
Normal file
88
sys/dev/xen/pci/xen_acpi_pci.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Roger Pau Monné <roger.pau@citrix.com>
|
||||
* 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$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <contrib/dev/acpica/include/acpi.h>
|
||||
#include <contrib/dev/acpica/include/accommon.h>
|
||||
|
||||
#include <dev/acpica/acpivar.h>
|
||||
|
||||
#include <sys/pciio.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pci_private.h>
|
||||
|
||||
#include <xen/xen-os.h>
|
||||
#include <xen/hypervisor.h>
|
||||
#include <xen/xen_pci.h>
|
||||
|
||||
#include "pcib_if.h"
|
||||
#include "pci_if.h"
|
||||
|
||||
static int
|
||||
xen_acpi_pci_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (!xen_pv_domain())
|
||||
return (ENXIO);
|
||||
if (acpi_get_handle(dev) == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "Xen ACPI PCI bus");
|
||||
|
||||
return (BUS_PROBE_SPECIFIC);
|
||||
}
|
||||
|
||||
static device_method_t xen_acpi_pci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, xen_acpi_pci_probe),
|
||||
|
||||
/* PCI interface overwrites */
|
||||
DEVMETHOD(pci_enable_msi, xen_pci_enable_msi_method),
|
||||
DEVMETHOD(pci_disable_msi, xen_pci_disable_msi_method),
|
||||
DEVMETHOD(pci_child_added, xen_pci_child_added_method),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static devclass_t pci_devclass;
|
||||
|
||||
DECLARE_CLASS(acpi_pci_driver);
|
||||
DEFINE_CLASS_1(pci, xen_acpi_pci_driver, xen_acpi_pci_methods,
|
||||
sizeof(struct pci_softc), acpi_pci_driver);
|
||||
DRIVER_MODULE(xen_acpi_pci, pcib, xen_acpi_pci_driver, pci_devclass, 0, 0);
|
||||
MODULE_DEPEND(xen_acpi_pci, pci, 1, 1, 1);
|
||||
MODULE_DEPEND(xen_acpi_pci, acpi, 1, 1, 1);
|
||||
MODULE_VERSION(xen_acpi_pci, 1);
|
80
sys/dev/xen/pci/xen_pci.c
Normal file
80
sys/dev/xen/pci/xen_pci.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Roger Pau Monné <roger.pau@citrix.com>
|
||||
* 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$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <sys/pciio.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pci_private.h>
|
||||
|
||||
#include <xen/xen-os.h>
|
||||
#include <xen/hypervisor.h>
|
||||
#include <xen/xen_pci.h>
|
||||
|
||||
#include "pcib_if.h"
|
||||
#include "pci_if.h"
|
||||
|
||||
static int
|
||||
xen_pci_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (!xen_pv_domain())
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "Xen PCI bus");
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static device_method_t xen_pci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, xen_pci_probe),
|
||||
|
||||
/* PCI interface overwrites */
|
||||
DEVMETHOD(pci_enable_msi, xen_pci_enable_msi_method),
|
||||
DEVMETHOD(pci_disable_msi, xen_pci_disable_msi_method),
|
||||
DEVMETHOD(pci_child_added, xen_pci_child_added_method),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static devclass_t pci_devclass;
|
||||
|
||||
DECLARE_CLASS(pci_driver);
|
||||
DEFINE_CLASS_1(pci, xen_pci_driver, xen_pci_methods, sizeof(struct pci_softc),
|
||||
pci_driver);
|
||||
DRIVER_MODULE(xen_pci, pcib, xen_pci_driver, pci_devclass, 0, 0);
|
||||
MODULE_DEPEND(xen_pci, pci, 1, 1, 1);
|
||||
MODULE_VERSION(xen_pci, 1);
|
@ -224,14 +224,18 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred,
|
||||
* will be returned to the free list. lastiblock values are also
|
||||
* normalized to -1 for calls to ext2_indirtrunc below.
|
||||
*/
|
||||
bcopy((caddr_t)&oip->i_db[0], (caddr_t)oldblks, sizeof(oldblks));
|
||||
for (level = TRIPLE; level >= SINGLE; level--)
|
||||
for (level = TRIPLE; level >= SINGLE; level--) {
|
||||
oldblks[NDADDR + level] = oip->i_ib[level];
|
||||
if (lastiblock[level] < 0) {
|
||||
oip->i_ib[level] = 0;
|
||||
lastiblock[level] = -1;
|
||||
}
|
||||
for (i = NDADDR - 1; i > lastblock; i--)
|
||||
oip->i_db[i] = 0;
|
||||
}
|
||||
for (i = 0; i < NDADDR; i++) {
|
||||
oldblks[i] = oip->i_db[i];
|
||||
if (i > lastblock)
|
||||
oip->i_db[i] = 0;
|
||||
}
|
||||
oip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
allerror = ext2_update(ovp, !DOINGASYNC(ovp));
|
||||
|
||||
@ -241,8 +245,14 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred,
|
||||
* Note that we save the new block configuration so we can check it
|
||||
* when we are done.
|
||||
*/
|
||||
bcopy((caddr_t)&oip->i_db[0], (caddr_t)newblks, sizeof(newblks));
|
||||
bcopy((caddr_t)oldblks, (caddr_t)&oip->i_db[0], sizeof(oldblks));
|
||||
for (i = 0; i < NDADDR; i++) {
|
||||
newblks[i] = oip->i_db[i];
|
||||
oip->i_db[i] = oldblks[i];
|
||||
}
|
||||
for (i = 0; i < NIADDR; i++) {
|
||||
newblks[NDADDR + i] = oip->i_ib[i];
|
||||
oip->i_ib[i] = oldblks[NDADDR + i];
|
||||
}
|
||||
oip->i_size = osize;
|
||||
error = vtruncbuf(ovp, cred, length, (int)fs->e2fs_bsize);
|
||||
if (error && (allerror == 0))
|
||||
|
@ -797,11 +797,15 @@ msdosfs_unmount(struct mount *mp, int mntflags)
|
||||
int error, flags;
|
||||
|
||||
flags = 0;
|
||||
if (mntflags & MNT_FORCE)
|
||||
error = msdosfs_sync(mp, MNT_WAIT);
|
||||
if ((mntflags & MNT_FORCE) != 0) {
|
||||
flags |= FORCECLOSE;
|
||||
} else if (error != 0) {
|
||||
return (error);
|
||||
}
|
||||
error = vflush(mp, 0, flags, curthread);
|
||||
if (error && error != ENXIO)
|
||||
return error;
|
||||
if (error != 0 && error != ENXIO)
|
||||
return (error);
|
||||
pmp = VFSTOMSDOSFS(mp);
|
||||
if ((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0) {
|
||||
error = markvoldirty(pmp, 0);
|
||||
|
@ -1305,8 +1305,8 @@ dounmount(mp, flags, td)
|
||||
}
|
||||
vput(fsrootvp);
|
||||
}
|
||||
if (((mp->mnt_flag & MNT_RDONLY) ||
|
||||
(error = VFS_SYNC(mp, MNT_WAIT)) == 0) || (flags & MNT_FORCE) != 0)
|
||||
if ((mp->mnt_flag & MNT_RDONLY) != 0 || (flags & MNT_FORCE) != 0 ||
|
||||
(error = VFS_SYNC(mp, MNT_WAIT)) == 0)
|
||||
error = VFS_UNMOUNT(mp, flags);
|
||||
vn_finished_write(mp);
|
||||
/*
|
||||
|
@ -1788,7 +1788,6 @@ sched_sync(void)
|
||||
int last_work_seen;
|
||||
int net_worklist_len;
|
||||
int syncer_final_iter;
|
||||
int first_printf;
|
||||
int error;
|
||||
|
||||
last_work_seen = 0;
|
||||
|
@ -49,9 +49,9 @@
|
||||
#define EXPORT_SYMBOL_GPL(name)
|
||||
|
||||
/* OFED pre-module initialization */
|
||||
#define SI_SUB_OFED_PREINIT (SI_SUB_KTHREAD_INIT - 2)
|
||||
#define SI_SUB_OFED_PREINIT (SI_SUB_ROOT_CONF - 2)
|
||||
/* OFED default module initialization */
|
||||
#define SI_SUB_OFED_MODINIT (SI_SUB_KTHREAD_INIT - 1)
|
||||
#define SI_SUB_OFED_MODINIT (SI_SUB_ROOT_CONF - 1)
|
||||
|
||||
#include <sys/linker.h>
|
||||
|
||||
|
@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/vmmeter.h>
|
||||
|
@ -91,6 +91,15 @@ madt_parse_interrupt_override(ACPI_MADT_INTERRUPT_OVERRIDE *intr)
|
||||
|
||||
madt_parse_interrupt_values(intr, &trig, &pol);
|
||||
|
||||
/* Remap the IRQ if it is mapped to a different interrupt vector. */
|
||||
if (intr->SourceIrq != intr->GlobalIrq && intr->GlobalIrq > 15 &&
|
||||
intr->SourceIrq == AcpiGbl_FADT.SciInterrupt)
|
||||
/*
|
||||
* If the SCI is remapped to a non-ISA global interrupt,
|
||||
* then override the vector we use to setup.
|
||||
*/
|
||||
acpi_OverrideInterruptLevel(intr->GlobalIrq);
|
||||
|
||||
/* Register the IRQ with the polarity and trigger mode found. */
|
||||
xen_register_pirq(intr->GlobalIrq, trig, pol);
|
||||
}
|
||||
|
@ -425,6 +425,17 @@ xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
|
||||
/* Assign the opaque handler (the event channel port) */
|
||||
*port_handlep = &isrc->xi_port;
|
||||
|
||||
#ifdef SMP
|
||||
if (type == EVTCHN_TYPE_PORT) {
|
||||
/*
|
||||
* By default all interrupts are assigned to vCPU#0
|
||||
* unless specified otherwise, so shuffle them to balance
|
||||
* the interrupt load.
|
||||
*/
|
||||
xen_intr_assign_cpu(&isrc->xi_intsrc, intr_next_cpu());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (filter == NULL && handler == NULL) {
|
||||
/*
|
||||
* No filter/handler provided, leave the event channel
|
||||
@ -851,7 +862,7 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
|
||||
struct evtchn_bind_vcpu bind_vcpu;
|
||||
struct xenisrc *isrc;
|
||||
u_int to_cpu, vcpu_id;
|
||||
int error;
|
||||
int error, masked;
|
||||
|
||||
#ifdef XENHVM
|
||||
if (xen_vector_callback_enabled == 0)
|
||||
@ -869,6 +880,11 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mask the event channel while binding it to prevent interrupt
|
||||
* delivery with an inconsistent state in isrc->xi_cpu.
|
||||
*/
|
||||
masked = evtchn_test_and_set_mask(isrc->xi_port);
|
||||
if ((isrc->xi_type == EVTCHN_TYPE_VIRQ) ||
|
||||
(isrc->xi_type == EVTCHN_TYPE_IPI)) {
|
||||
/*
|
||||
@ -879,29 +895,25 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
|
||||
evtchn_cpu_mask_port(isrc->xi_cpu, isrc->xi_port);
|
||||
isrc->xi_cpu = to_cpu;
|
||||
evtchn_cpu_unmask_port(isrc->xi_cpu, isrc->xi_port);
|
||||
mtx_unlock(&xen_intr_isrc_lock);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
bind_vcpu.port = isrc->xi_port;
|
||||
bind_vcpu.vcpu = vcpu_id;
|
||||
|
||||
/*
|
||||
* Allow interrupts to be fielded on the new VCPU before
|
||||
* we ask the hypervisor to deliver them there.
|
||||
*/
|
||||
evtchn_cpu_unmask_port(to_cpu, isrc->xi_port);
|
||||
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu);
|
||||
if (isrc->xi_cpu != to_cpu) {
|
||||
if (error == 0) {
|
||||
/* Commit to new binding by removing the old one. */
|
||||
evtchn_cpu_mask_port(isrc->xi_cpu, isrc->xi_port);
|
||||
isrc->xi_cpu = to_cpu;
|
||||
} else {
|
||||
/* Roll-back to previous binding. */
|
||||
evtchn_cpu_mask_port(to_cpu, isrc->xi_port);
|
||||
evtchn_cpu_unmask_port(isrc->xi_cpu, isrc->xi_port);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (masked == 0)
|
||||
evtchn_unmask_port(isrc->xi_port);
|
||||
mtx_unlock(&xen_intr_isrc_lock);
|
||||
return (0);
|
||||
#else
|
||||
|
@ -31,8 +31,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <sys/pciio.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
@ -41,52 +39,12 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <xen/xen-os.h>
|
||||
#include <xen/hypervisor.h>
|
||||
#include <xen/xen_pci.h>
|
||||
|
||||
#include "pcib_if.h"
|
||||
#include "pci_if.h"
|
||||
|
||||
static int xen_pci_probe(device_t dev);
|
||||
|
||||
static void xen_pci_enable_msi_method(device_t dev, device_t child,
|
||||
uint64_t address, uint16_t data);
|
||||
static void xen_pci_disable_msi_method(device_t dev, device_t child);
|
||||
static void xen_pci_child_added_method(device_t dev, device_t child);
|
||||
|
||||
static device_method_t xen_pci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, xen_pci_probe),
|
||||
|
||||
/* PCI interface overwrites */
|
||||
DEVMETHOD(pci_enable_msi, xen_pci_enable_msi_method),
|
||||
DEVMETHOD(pci_disable_msi, xen_pci_disable_msi_method),
|
||||
DEVMETHOD(pci_child_added, xen_pci_child_added_method),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static devclass_t pci_devclass;
|
||||
|
||||
DECLARE_CLASS(acpi_pci_driver);
|
||||
DEFINE_CLASS_1(pci, xen_pci_driver, xen_pci_methods, sizeof(struct pci_softc),
|
||||
acpi_pci_driver);
|
||||
DRIVER_MODULE(xen_pci, pcib, xen_pci_driver, pci_devclass, 0, 0);
|
||||
MODULE_DEPEND(xen_pci, pci, 1, 1, 1);
|
||||
MODULE_DEPEND(xen_pci, acpi, 1, 1, 1);
|
||||
MODULE_VERSION(xen_pci, 1);
|
||||
|
||||
static int
|
||||
xen_pci_probe(device_t dev)
|
||||
{
|
||||
|
||||
device_set_desc(dev, "Xen PCI bus");
|
||||
|
||||
if (!xen_pv_domain())
|
||||
return (ENXIO);
|
||||
|
||||
return (BUS_PROBE_SPECIFIC);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
xen_pci_enable_msi_method(device_t dev, device_t child, uint64_t address,
|
||||
uint16_t data)
|
||||
{
|
||||
@ -99,7 +57,7 @@ xen_pci_enable_msi_method(device_t dev, device_t child, uint64_t address,
|
||||
msi->msi_ctrl, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
xen_pci_disable_msi_method(device_t dev, device_t child)
|
||||
{
|
||||
struct pci_devinfo *dinfo = device_get_ivars(child);
|
||||
@ -110,7 +68,7 @@ xen_pci_disable_msi_method(device_t dev, device_t child)
|
||||
msi->msi_ctrl, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
xen_pci_child_added_method(device_t dev, device_t child)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
@ -66,15 +66,6 @@ static int
|
||||
xenpv_attach(device_t dev)
|
||||
{
|
||||
device_t child;
|
||||
int error;
|
||||
|
||||
/* Initialize grant table before any Xen specific device is attached */
|
||||
error = gnttab_init(dev);
|
||||
if (error != 0) {
|
||||
device_printf(dev, "error initializing grant table: %d\n",
|
||||
error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Let our child drivers identify any child devices that they
|
||||
|
@ -51,8 +51,6 @@ struct gnttab_free_callback {
|
||||
uint16_t count;
|
||||
};
|
||||
|
||||
int gnttab_init(device_t);
|
||||
|
||||
/*
|
||||
* Allocate a grant table reference and return it in *result. Returns
|
||||
* zero on success or errno on error.
|
||||
|
37
sys/xen/xen_pci.h
Normal file
37
sys/xen/xen_pci.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Roger Pau Monné <roger.pau@citrix.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PCI_H__
|
||||
#define __XEN_PCI_H__
|
||||
|
||||
void xen_pci_enable_msi_method(device_t dev, device_t child, uint64_t address,
|
||||
uint16_t data);
|
||||
void xen_pci_disable_msi_method(device_t dev, device_t child);
|
||||
void xen_pci_child_added_method(device_t dev, device_t child);
|
||||
|
||||
#endif /* !__XEN_PCI_H__ */
|
@ -29,6 +29,7 @@ SUBDIR= adduser \
|
||||
extattr \
|
||||
extattrctl \
|
||||
fifolog \
|
||||
fstyp \
|
||||
fwcontrol \
|
||||
getfmac \
|
||||
getpmac \
|
||||
|
@ -27,7 +27,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 21, 2014
|
||||
.Dd November 22, 2014
|
||||
.Dt AUTO_MASTER 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -213,14 +213,17 @@ Supported special maps are:
|
||||
.Pp
|
||||
.Bl -tag -width "-hosts" -compact
|
||||
.It Li -hosts
|
||||
This map queries the remote NFS server and maps exported volumes.
|
||||
It is traditionally mounted on
|
||||
Query the remote NFS server and map exported shares.
|
||||
This map is traditionally mounted on
|
||||
.Pa /net .
|
||||
It enables access to files on a remote NFS server by accessing
|
||||
Access to files on a remote NFS server is provided through the
|
||||
.Pa /net/nfs-server-ip/share-name/
|
||||
directory, without the need for any further configuration.
|
||||
directory without any additional configuration.
|
||||
.It Li -media
|
||||
Query devices that are not yet mounted, but contain valid filesystems.
|
||||
Generally used to access files on removable media.
|
||||
.It Li -null
|
||||
This map prevents the
|
||||
Prevent
|
||||
.Xr automountd 8
|
||||
from mounting anything on the mountpoint.
|
||||
.El
|
||||
|
9
usr.sbin/fstyp/Makefile
Normal file
9
usr.sbin/fstyp/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= fstyp
|
||||
SRCS= fstyp.c ext2fs.c cd9660.c msdosfs.c ntfs.c ufs.c
|
||||
MAN= fstyp.8
|
||||
|
||||
WARNS= 6
|
||||
|
||||
.include <bsd.prog.mk>
|
72
usr.sbin/fstyp/cd9660.c
Normal file
72
usr.sbin/fstyp/cd9660.c
Normal file
@ -0,0 +1,72 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Edward Tomasz Napierala under sponsorship
|
||||
* from the FreeBSD Foundation.
|
||||
*
|
||||
* 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 AUTHORS 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 AUTHORS 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$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fstyp.h"
|
||||
|
||||
#define G_LABEL_ISO9660_DIR "iso9660"
|
||||
|
||||
#define ISO9660_MAGIC "\x01" "CD001" "\x01\x00"
|
||||
#define ISO9660_OFFSET 0x8000
|
||||
#define VOLUME_LEN 32
|
||||
|
||||
int
|
||||
fstyp_cd9660(FILE *fp, char *label, size_t size)
|
||||
{
|
||||
char *sector, *volume;
|
||||
int i;
|
||||
|
||||
sector = read_buf(fp, ISO9660_OFFSET, 512);
|
||||
if (sector == NULL)
|
||||
return (1);
|
||||
if (bcmp(sector, ISO9660_MAGIC, sizeof(ISO9660_MAGIC) - 1) != 0) {
|
||||
free(sector);
|
||||
return (1);
|
||||
}
|
||||
volume = sector + 0x28;
|
||||
bzero(label, size);
|
||||
strlcpy(label, volume, MIN(size, VOLUME_LEN));
|
||||
free(sector);
|
||||
for (i = size - 1; i > 0; i--) {
|
||||
if (label[i] == '\0')
|
||||
continue;
|
||||
else if (label[i] == ' ')
|
||||
label[i] = '\0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
90
usr.sbin/fstyp/ext2fs.c
Normal file
90
usr.sbin/fstyp/ext2fs.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Stanislav Sedov
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Edward Tomasz Napierala under sponsorship
|
||||
* from the FreeBSD Foundation.
|
||||
*
|
||||
* 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$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fstyp.h"
|
||||
|
||||
#define EXT2FS_SB_OFFSET 1024
|
||||
#define EXT2_SUPER_MAGIC 0xef53
|
||||
#define EXT2_DYNAMIC_REV 1
|
||||
|
||||
typedef struct e2sb {
|
||||
uint8_t fake1[56];
|
||||
uint16_t s_magic;
|
||||
uint8_t fake2[18];
|
||||
uint32_t s_rev_level;
|
||||
uint8_t fake3[40];
|
||||
char s_volume_name[16];
|
||||
} e2sb_t;
|
||||
|
||||
int
|
||||
fstyp_ext2fs(FILE *fp, char *label, size_t size)
|
||||
{
|
||||
e2sb_t *fs;
|
||||
char *s_volume_name;
|
||||
|
||||
fs = (e2sb_t *)read_buf(fp, EXT2FS_SB_OFFSET, 512);
|
||||
if (fs == NULL)
|
||||
return (1);
|
||||
|
||||
/* Check for magic and versio n*/
|
||||
if (fs->s_magic == EXT2_SUPER_MAGIC &&
|
||||
fs->s_rev_level == EXT2_DYNAMIC_REV) {
|
||||
//G_LABEL_DEBUG(1, "ext2fs file system detected on %s.",
|
||||
// pp->name);
|
||||
} else {
|
||||
free(fs);
|
||||
return (1);
|
||||
}
|
||||
|
||||
s_volume_name = fs->s_volume_name;
|
||||
/* Terminate label */
|
||||
s_volume_name[sizeof(fs->s_volume_name) - 1] = '\0';
|
||||
|
||||
if (s_volume_name[0] == '/')
|
||||
s_volume_name += 1;
|
||||
|
||||
/* Check for volume label */
|
||||
if (s_volume_name[0] == '\0') {
|
||||
free(fs);
|
||||
return (1);
|
||||
}
|
||||
|
||||
strlcpy(label, s_volume_name, size);
|
||||
|
||||
return (0);
|
||||
}
|
97
usr.sbin/fstyp/fstyp.8
Normal file
97
usr.sbin/fstyp/fstyp.8
Normal file
@ -0,0 +1,97 @@
|
||||
.\" Copyright (c) 2014 The FreeBSD Foundation
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This software was developed by Edward Tomasz Napierala under sponsorship
|
||||
.\" from the FreeBSD Foundation.
|
||||
.\"
|
||||
.\" 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 6, 2014
|
||||
.Dt FSTYP 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm fstyp
|
||||
.Nd determine filesystem type
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl l
|
||||
.Op Fl s
|
||||
.Ar special
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility is used to determine the filesystem type on a given device.
|
||||
It can recognize ISO-9660, Ext2, FAT, NTFS, and UFS filesystems.
|
||||
The filesystem name is printed to the standard output
|
||||
as, respectively,
|
||||
.Li cd9660 ,
|
||||
.Li ext2fs ,
|
||||
.Li msdosfs ,
|
||||
.Li ntfs ,
|
||||
or
|
||||
.Li ufs .
|
||||
.Pp
|
||||
Because
|
||||
.Nm
|
||||
is built specifically to detect filesystem types, it differs from
|
||||
.Xr file 1
|
||||
in several ways.
|
||||
The output is machine-parsable, filesystem labels are supported,
|
||||
and only filesystems are identified.
|
||||
Security is improved with
|
||||
.Xr capsicum 4 .
|
||||
.Pp
|
||||
These options are available:
|
||||
.Bl -tag -width ".Fl l"
|
||||
.It Fl l
|
||||
In addition to filesystem type, print filesystem label if available.
|
||||
.It Fl s
|
||||
Ignore file type.
|
||||
By default,
|
||||
.Nm
|
||||
only works on regular files and disk-like device nodes.
|
||||
Trying to read other file types might have unexpected consequences or hang
|
||||
indefinitely.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
utility exits 0 on success, and >0 if an error occurs or the filesystem
|
||||
type is not recognized.
|
||||
.Sh SEE ALSO
|
||||
.Xr file 1 ,
|
||||
.Xr capsicum 4 ,
|
||||
.Xr glabel 8 ,
|
||||
.Xr mount 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Fx 11.0 .
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was developed by
|
||||
.An Edward Tomasz Napierala Aq Mt trasz@FreeBSD.org
|
||||
under sponsorship from the FreeBSD Foundation.
|
210
usr.sbin/fstyp/fstyp.c
Normal file
210
usr.sbin/fstyp/fstyp.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Edward Tomasz Napierala under sponsorship
|
||||
* from the FreeBSD Foundation.
|
||||
*
|
||||
* 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$");
|
||||
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <vis.h>
|
||||
|
||||
#include "fstyp.h"
|
||||
|
||||
#define LABEL_LEN 256
|
||||
|
||||
typedef int (*fstyp_function)(FILE *, char *, size_t);
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
fstyp_function function;
|
||||
} fstypes[] = {
|
||||
{ "cd9660", &fstyp_cd9660 },
|
||||
{ "ext2fs", &fstyp_ext2fs },
|
||||
{ "msdosfs", &fstyp_msdosfs },
|
||||
{ "ntfs", &fstyp_ntfs },
|
||||
{ "ufs", &fstyp_ufs },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void *
|
||||
read_buf(FILE *fp, off_t off, size_t len)
|
||||
{
|
||||
int error;
|
||||
size_t nread;
|
||||
void *buf;
|
||||
|
||||
error = fseek(fp, off, SEEK_SET);
|
||||
if (error != 0) {
|
||||
warn("cannot seek to %jd", (uintmax_t)off);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
buf = malloc(len);
|
||||
if (buf == 0) {
|
||||
warn("cannot malloc %zd bytes of memory", len);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
nread = fread(buf, len, 1, fp);
|
||||
if (nread != 1) {
|
||||
free(buf);
|
||||
if (feof(fp) == 0)
|
||||
warn("fread");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *
|
||||
checked_strdup(const char *s)
|
||||
{
|
||||
char *c;
|
||||
|
||||
c = strdup(s);
|
||||
if (c == NULL)
|
||||
err(1, "strdup");
|
||||
return (c);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: fstyp [-l][-s] special\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
type_check(const char *path, FILE *fp)
|
||||
{
|
||||
int error, fd;
|
||||
off_t mediasize;
|
||||
struct stat sb;
|
||||
|
||||
fd = fileno(fp);
|
||||
|
||||
error = fstat(fd, &sb);
|
||||
if (error != 0)
|
||||
err(1, "%s: fstat", path);
|
||||
|
||||
if (S_ISREG(sb.st_mode))
|
||||
return;
|
||||
|
||||
error = ioctl(fd, DIOCGMEDIASIZE, &mediasize);
|
||||
if (error != 0)
|
||||
errx(1, "%s: not a disk", path);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch, error, i, nbytes;
|
||||
bool ignore_type = false, show_label = false;
|
||||
char label[LABEL_LEN + 1], strvised[LABEL_LEN * 4 + 1];
|
||||
char *path;
|
||||
FILE *fp;
|
||||
fstyp_function fstyp_f;
|
||||
|
||||
while ((ch = getopt(argc, argv, "ls")) != -1) {
|
||||
switch (ch) {
|
||||
case 'l':
|
||||
show_label = true;
|
||||
break;
|
||||
case 's':
|
||||
ignore_type = true;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc != 1)
|
||||
usage();
|
||||
|
||||
path = argv[0];
|
||||
|
||||
fp = fopen(path, "r");
|
||||
if (fp == NULL)
|
||||
err(1, "%s", path);
|
||||
|
||||
error = cap_enter();
|
||||
if (error != 0 && errno != ENOSYS)
|
||||
err(1, "cap_enter");
|
||||
|
||||
if (ignore_type == false)
|
||||
type_check(path, fp);
|
||||
|
||||
memset(label, '\0', sizeof(label));
|
||||
|
||||
for (i = 0;; i++) {
|
||||
fstyp_f = fstypes[i].function;
|
||||
if (fstyp_f == NULL)
|
||||
break;
|
||||
|
||||
error = fstyp_f(fp, label, sizeof(label));
|
||||
if (error == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (fstypes[i].name == NULL) {
|
||||
warnx("%s: filesystem not recognized", path);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (show_label && label[0] != '\0') {
|
||||
/*
|
||||
* XXX: I'd prefer VIS_HTTPSTYLE, but it unconditionally
|
||||
* encodes spaces.
|
||||
*/
|
||||
nbytes = strsnvis(strvised, sizeof(strvised), label,
|
||||
VIS_GLOB | VIS_NL, "\"'$");
|
||||
if (nbytes == -1)
|
||||
err(1, "strsnvis");
|
||||
|
||||
printf("%s %s\n", fstypes[i].name, strvised);
|
||||
} else {
|
||||
printf("%s\n", fstypes[i].name);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
46
usr.sbin/fstyp/fstyp.h
Normal file
46
usr.sbin/fstyp/fstyp.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Edward Tomasz Napierala under sponsorship
|
||||
* from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef FSTYP_H
|
||||
#define FSTYP_H
|
||||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
void *read_buf(FILE *fp, off_t off, size_t len);
|
||||
char *checked_strdup(const char *s);
|
||||
|
||||
int fstyp_cd9660(FILE *fp, char *label, size_t size);
|
||||
int fstyp_ext2fs(FILE *fp, char *label, size_t size);
|
||||
int fstyp_msdosfs(FILE *fp, char *label, size_t size);
|
||||
int fstyp_ntfs(FILE *fp, char *label, size_t size);
|
||||
int fstyp_ufs(FILE *fp, char *label, size_t size);
|
||||
|
||||
#endif /* !FSTYP_H */
|
183
usr.sbin/fstyp/msdosfs.c
Normal file
183
usr.sbin/fstyp/msdosfs.c
Normal file
@ -0,0 +1,183 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* Copyright (c) 2006 Tobias Reifenberger
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Edward Tomasz Napierala under sponsorship
|
||||
* from the FreeBSD Foundation.
|
||||
*
|
||||
* 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 AUTHORS 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 AUTHORS 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$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fstyp.h"
|
||||
#include "msdosfs.h"
|
||||
|
||||
#define LABEL_NO_NAME "NO NAME "
|
||||
|
||||
int
|
||||
fstyp_msdosfs(FILE *fp, char *label, size_t size)
|
||||
{
|
||||
FAT_BSBPB *pfat_bsbpb;
|
||||
FAT32_BSBPB *pfat32_bsbpb;
|
||||
FAT_DES *pfat_entry;
|
||||
uint8_t *sector0, *sector;
|
||||
uint32_t i;
|
||||
|
||||
sector0 = NULL;
|
||||
sector = NULL;
|
||||
|
||||
/* Load 1st sector with boot sector and boot parameter block. */
|
||||
sector0 = (uint8_t *)read_buf(fp, 0, 512);
|
||||
if (sector0 == NULL)
|
||||
return (1);
|
||||
|
||||
/* Check for the FAT boot sector signature. */
|
||||
if (sector0[510] != 0x55 || sector0[511] != 0xaa) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test if this is really a FAT volume and determine the FAT type.
|
||||
*/
|
||||
|
||||
pfat_bsbpb = (FAT_BSBPB *)sector0;
|
||||
pfat32_bsbpb = (FAT32_BSBPB *)sector0;
|
||||
|
||||
if (UINT16BYTES(pfat_bsbpb->BPB_FATSz16) != 0) {
|
||||
/*
|
||||
* If the BPB_FATSz16 field is not zero and the string "FAT" is
|
||||
* at the right place, this should be a FAT12 or FAT16 volume.
|
||||
*/
|
||||
if (strncmp(pfat_bsbpb->BS_FilSysType, "FAT", 3) != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* A volume with no name should have "NO NAME " as label. */
|
||||
if (strncmp(pfat_bsbpb->BS_VolLab, LABEL_NO_NAME,
|
||||
sizeof(pfat_bsbpb->BS_VolLab)) == 0) {
|
||||
goto endofchecks;
|
||||
}
|
||||
strlcpy(label, pfat_bsbpb->BS_VolLab,
|
||||
MIN(size, sizeof(pfat_bsbpb->BS_VolLab) + 1));
|
||||
} else if (UINT32BYTES(pfat32_bsbpb->BPB_FATSz32) != 0) {
|
||||
uint32_t fat_FirstDataSector, fat_BytesPerSector, offset;
|
||||
|
||||
/*
|
||||
* If the BPB_FATSz32 field is not zero and the string "FAT" is
|
||||
* at the right place, this should be a FAT32 volume.
|
||||
*/
|
||||
if (strncmp(pfat32_bsbpb->BS_FilSysType, "FAT", 3) != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the volume label is not "NO NAME " we're done.
|
||||
*/
|
||||
if (strncmp(pfat32_bsbpb->BS_VolLab, LABEL_NO_NAME,
|
||||
sizeof(pfat32_bsbpb->BS_VolLab)) != 0) {
|
||||
strlcpy(label, pfat32_bsbpb->BS_VolLab,
|
||||
MIN(size, sizeof(pfat32_bsbpb->BS_VolLab) + 1));
|
||||
goto endofchecks;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the volume label "NO NAME " is in the boot sector, the
|
||||
* label of FAT32 volumes may be stored as a special entry in
|
||||
* the root directory.
|
||||
*/
|
||||
fat_FirstDataSector =
|
||||
UINT16BYTES(pfat32_bsbpb->BPB_RsvdSecCnt) +
|
||||
(pfat32_bsbpb->BPB_NumFATs *
|
||||
UINT32BYTES(pfat32_bsbpb->BPB_FATSz32));
|
||||
fat_BytesPerSector = UINT16BYTES(pfat32_bsbpb->BPB_BytsPerSec);
|
||||
|
||||
// fat_FirstDataSector, fat_BytesPerSector);
|
||||
|
||||
for (offset = fat_BytesPerSector * fat_FirstDataSector;;
|
||||
offset += fat_BytesPerSector) {
|
||||
sector = (uint8_t *)read_buf(fp, offset, fat_BytesPerSector);
|
||||
if (sector == NULL)
|
||||
goto error;
|
||||
|
||||
pfat_entry = (FAT_DES *)sector;
|
||||
do {
|
||||
/* No more entries available. */
|
||||
if (pfat_entry->DIR_Name[0] == 0) {
|
||||
goto endofchecks;
|
||||
}
|
||||
|
||||
/* Skip empty or long name entries. */
|
||||
if (pfat_entry->DIR_Name[0] == 0xe5 ||
|
||||
(pfat_entry->DIR_Attr &
|
||||
FAT_DES_ATTR_LONG_NAME) ==
|
||||
FAT_DES_ATTR_LONG_NAME) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* The name of the entry is the volume label if
|
||||
* ATTR_VOLUME_ID is set.
|
||||
*/
|
||||
if (pfat_entry->DIR_Attr &
|
||||
FAT_DES_ATTR_VOLUME_ID) {
|
||||
strlcpy(label, pfat_entry->DIR_Name,
|
||||
MIN(size,
|
||||
sizeof(pfat_entry->DIR_Name) + 1));
|
||||
goto endofchecks;
|
||||
}
|
||||
} while((uint8_t *)(++pfat_entry) <
|
||||
(uint8_t *)(sector + fat_BytesPerSector));
|
||||
free(sector);
|
||||
}
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
|
||||
endofchecks:
|
||||
for (i = size - 1; i > 0; i--) {
|
||||
if (label[i] == '\0')
|
||||
continue;
|
||||
else if (label[i] == ' ')
|
||||
label[i] = '\0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
free(sector0);
|
||||
free(sector);
|
||||
|
||||
return (0);
|
||||
|
||||
error:
|
||||
free(sector0);
|
||||
free(sector);
|
||||
|
||||
return (1);
|
||||
}
|
140
usr.sbin/fstyp/msdosfs.h
Normal file
140
usr.sbin/fstyp/msdosfs.h
Normal file
@ -0,0 +1,140 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Tobias Reifenberger
|
||||
* 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* Conversion macros for little endian encoded unsigned integers
|
||||
* in byte streams to the local unsigned integer format.
|
||||
*/
|
||||
#define UINT16BYTES(p) ((uint32_t)((p)[0] + (256*(p)[1])))
|
||||
#define UINT32BYTES(p) ((uint32_t)((p)[0] + (256*(p)[1]) + \
|
||||
(65536*(p)[2]) + (16777216*(p)[3])))
|
||||
|
||||
/*
|
||||
* All following structures are according to:
|
||||
*
|
||||
* Microsoft Extensible Firmware Initiative FAT32 File System Specification
|
||||
* FAT: General Overview of On-Disk Format
|
||||
* Version 1.03, December 6, 2000
|
||||
* Microsoft Corporation
|
||||
*/
|
||||
|
||||
/*
|
||||
* FAT boot sector and boot parameter block for
|
||||
* FAT12 and FAT16 volumes
|
||||
*/
|
||||
typedef struct fat_bsbpb {
|
||||
/* common fields */
|
||||
uint8_t BS_jmpBoot[3];
|
||||
uint8_t BS_OEMName[8];
|
||||
uint8_t BPB_BytsPerSec[2];
|
||||
uint8_t BPB_SecPerClus;
|
||||
uint8_t BPB_RsvdSecCnt[2];
|
||||
uint8_t BPB_NumFATs;
|
||||
uint8_t BPB_RootEntCnt[2];
|
||||
uint8_t BPB_TotSec16[2];
|
||||
uint8_t BPB_Media;
|
||||
uint8_t BPB_FATSz16[2];
|
||||
uint8_t BPB_SecPerTrack[2];
|
||||
uint8_t BPB_NumHeads[2];
|
||||
uint8_t BPB_HiddSec[4];
|
||||
uint8_t BPB_TotSec32[4];
|
||||
/* FAT12/FAT16 only fields */
|
||||
uint8_t BS_DrvNum;
|
||||
uint8_t BS_Reserved1;
|
||||
uint8_t BS_BootSig;
|
||||
uint8_t BS_VolID[4];
|
||||
uint8_t BS_VolLab[11];
|
||||
uint8_t BS_FilSysType[8];
|
||||
} FAT_BSBPB; /* 62 bytes */
|
||||
|
||||
/*
|
||||
* FAT boot sector and boot parameter block for
|
||||
* FAT32 volumes
|
||||
*/
|
||||
typedef struct fat32_bsbpb {
|
||||
/* common fields */
|
||||
uint8_t BS_jmpBoot[3];
|
||||
uint8_t BS_OEMName[8];
|
||||
uint8_t BPB_BytsPerSec[2];
|
||||
uint8_t BPB_SecPerClus;
|
||||
uint8_t BPB_RsvdSecCnt[2];
|
||||
uint8_t BPB_NumFATs;
|
||||
uint8_t BPB_RootEntCnt[2];
|
||||
uint8_t BPB_TotSec16[2];
|
||||
uint8_t BPB_Media;
|
||||
uint8_t BPB_FATSz16[2];
|
||||
uint8_t BPB_SecPerTrack[2];
|
||||
uint8_t BPB_NumHeads[2];
|
||||
uint8_t BPB_HiddSec[4];
|
||||
uint8_t BPB_TotSec32[4];
|
||||
/* FAT32 only fields */
|
||||
uint8_t BPB_FATSz32[4];
|
||||
uint8_t BPB_ExtFlags[2];
|
||||
uint8_t BPB_FSVer[2];
|
||||
uint8_t BPB_RootClus[4];
|
||||
uint8_t BPB_FSInfo[2];
|
||||
uint8_t BPB_BkBootSec[2];
|
||||
uint8_t BPB_Reserved[12];
|
||||
uint8_t BS_DrvNum;
|
||||
uint8_t BS_Reserved1;
|
||||
uint8_t BS_BootSig;
|
||||
uint8_t BS_VolID[4];
|
||||
uint8_t BS_VolLab[11];
|
||||
uint8_t BS_FilSysType[8];
|
||||
} FAT32_BSBPB; /* 90 bytes */
|
||||
|
||||
/*
|
||||
* FAT directory entry structure
|
||||
*/
|
||||
#define FAT_DES_ATTR_READ_ONLY 0x01
|
||||
#define FAT_DES_ATTR_HIDDEN 0x02
|
||||
#define FAT_DES_ATTR_SYSTEM 0x04
|
||||
#define FAT_DES_ATTR_VOLUME_ID 0x08
|
||||
#define FAT_DES_ATTR_DIRECTORY 0x10
|
||||
#define FAT_DES_ATTR_ARCHIVE 0x20
|
||||
#define FAT_DES_ATTR_LONG_NAME (FAT_DES_ATTR_READ_ONLY | \
|
||||
FAT_DES_ATTR_HIDDEN | \
|
||||
FAT_DES_ATTR_SYSTEM | \
|
||||
FAT_DES_ATTR_VOLUME_ID)
|
||||
|
||||
typedef struct fat_des {
|
||||
uint8_t DIR_Name[11];
|
||||
uint8_t DIR_Attr;
|
||||
uint8_t DIR_NTRes;
|
||||
uint8_t DIR_CrtTimeTenth;
|
||||
uint8_t DIR_CrtTime[2];
|
||||
uint8_t DIR_CrtDate[2];
|
||||
uint8_t DIR_LstAccDate[2];
|
||||
uint8_t DIR_FstClusHI[2];
|
||||
uint8_t DIR_WrtTime[2];
|
||||
uint8_t DIR_WrtDate[2];
|
||||
uint8_t DIR_FstClusLO[2];
|
||||
uint8_t DIR_FileSize[4];
|
||||
} FAT_DES;
|
165
usr.sbin/fstyp/ntfs.c
Normal file
165
usr.sbin/fstyp/ntfs.c
Normal file
@ -0,0 +1,165 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Takanori Watanabe
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Edward Tomasz Napierala under sponsorship
|
||||
* from the FreeBSD Foundation.
|
||||
*
|
||||
* 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$");
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fstyp.h"
|
||||
|
||||
#define NTFS_A_VOLUMENAME 0x60
|
||||
#define NTFS_FILEMAGIC ((uint32_t)(0x454C4946))
|
||||
#define NTFS_VOLUMEINO 3
|
||||
|
||||
#define G_LABEL_NTFS_DIR "ntfs"
|
||||
|
||||
struct ntfs_attr {
|
||||
uint32_t a_type;
|
||||
uint32_t reclen;
|
||||
uint8_t a_flag;
|
||||
uint8_t a_namelen;
|
||||
uint8_t a_nameoff;
|
||||
uint8_t reserved1;
|
||||
uint8_t a_compression;
|
||||
uint8_t reserved2;
|
||||
uint16_t a_index;
|
||||
uint16_t a_datalen;
|
||||
uint16_t reserved3;
|
||||
uint16_t a_dataoff;
|
||||
uint16_t a_indexed;
|
||||
} __packed;
|
||||
|
||||
struct ntfs_filerec {
|
||||
uint32_t fr_hdrmagic;
|
||||
uint16_t fr_hdrfoff;
|
||||
uint16_t fr_hdrfnum;
|
||||
uint8_t reserved[8];
|
||||
uint16_t fr_seqnum;
|
||||
uint16_t fr_nlink;
|
||||
uint16_t fr_attroff;
|
||||
uint16_t fr_flags;
|
||||
uint32_t fr_size;
|
||||
uint32_t fr_allocated;
|
||||
uint64_t fr_mainrec;
|
||||
uint16_t fr_attrnum;
|
||||
} __packed;
|
||||
|
||||
struct ntfs_bootfile {
|
||||
uint8_t reserved1[3];
|
||||
uint8_t bf_sysid[8];
|
||||
uint16_t bf_bps;
|
||||
uint8_t bf_spc;
|
||||
uint8_t reserved2[7];
|
||||
uint8_t bf_media;
|
||||
uint8_t reserved3[2];
|
||||
uint16_t bf_spt;
|
||||
uint16_t bf_heads;
|
||||
uint8_t reserver4[12];
|
||||
uint64_t bf_spv;
|
||||
uint64_t bf_mftcn;
|
||||
uint64_t bf_mftmirrcn;
|
||||
int8_t bf_mftrecsz;
|
||||
uint32_t bf_ibsz;
|
||||
uint32_t bf_volsn;
|
||||
} __packed;
|
||||
|
||||
int
|
||||
fstyp_ntfs(FILE *fp, char *label, size_t size)
|
||||
{
|
||||
struct ntfs_bootfile *bf;
|
||||
struct ntfs_filerec *fr;
|
||||
struct ntfs_attr *atr;
|
||||
off_t voloff;
|
||||
char *filerecp, *ap;
|
||||
int8_t mftrecsz;
|
||||
char vnchar;
|
||||
int recsize, j;
|
||||
|
||||
filerecp = NULL;
|
||||
|
||||
bf = (struct ntfs_bootfile *)read_buf(fp, 0, 512);
|
||||
if (bf == NULL || strncmp(bf->bf_sysid, "NTFS ", 8) != 0)
|
||||
return (1);
|
||||
|
||||
mftrecsz = bf->bf_mftrecsz;
|
||||
recsize = (mftrecsz > 0) ? (mftrecsz * bf->bf_bps * bf->bf_spc) : (1 << -mftrecsz);
|
||||
|
||||
voloff = bf->bf_mftcn * bf->bf_spc * bf->bf_bps +
|
||||
recsize * NTFS_VOLUMEINO;
|
||||
|
||||
filerecp = read_buf(fp, voloff, recsize);
|
||||
if (filerecp == NULL)
|
||||
goto fail;
|
||||
fr = (struct ntfs_filerec *)filerecp;
|
||||
|
||||
if (fr->fr_hdrmagic != NTFS_FILEMAGIC)
|
||||
goto fail;
|
||||
|
||||
for (ap = filerecp + fr->fr_attroff;
|
||||
atr = (struct ntfs_attr *)ap, (int)atr->a_type != -1;
|
||||
ap += atr->reclen) {
|
||||
if (atr->a_type == NTFS_A_VOLUMENAME) {
|
||||
if(atr->a_datalen >= size *2){
|
||||
goto fail;
|
||||
}
|
||||
/*
|
||||
*UNICODE to ASCII.
|
||||
* Should we need to use iconv(9)?
|
||||
*/
|
||||
for (j = 0; j < atr->a_datalen; j++) {
|
||||
vnchar = *(ap + atr->a_dataoff + j);
|
||||
if (j & 1) {
|
||||
if (vnchar) {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
label[j / 2] = vnchar;
|
||||
}
|
||||
}
|
||||
label[j / 2] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(bf);
|
||||
free(filerecp);
|
||||
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
free(bf);
|
||||
free(filerecp);
|
||||
|
||||
return (1);
|
||||
}
|
109
usr.sbin/fstyp/ufs.c
Normal file
109
usr.sbin/fstyp/ufs.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 Gordon Tetlow
|
||||
* Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Edward Tomasz Napierala under sponsorship
|
||||
* from the FreeBSD Foundation.
|
||||
*
|
||||
* 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 AUTHORS 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 AUTHORS 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$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
|
||||
#include "fstyp.h"
|
||||
|
||||
static const int superblocks[] = SBLOCKSEARCH;
|
||||
|
||||
int
|
||||
fstyp_ufs(FILE *fp, char *label, size_t labelsize)
|
||||
{
|
||||
int sb, superblock;
|
||||
struct fs *fs;
|
||||
|
||||
/*
|
||||
* Walk through the standard places that superblocks hide and look
|
||||
* for UFS magic. If we find magic, then check that the size in the
|
||||
* superblock corresponds to the size of the underlying provider.
|
||||
* Finally, look for a volume label and create an appropriate
|
||||
* provider based on that.
|
||||
*/
|
||||
for (sb = 0; (superblock = superblocks[sb]) != -1; sb++) {
|
||||
fs = (struct fs *)read_buf(fp, superblock, SBLOCKSIZE);
|
||||
if (fs == NULL)
|
||||
continue;
|
||||
/*
|
||||
* Check for magic. We also need to check if file system size is equal
|
||||
* to providers size, because sysinstall(8) used to bogusly put first
|
||||
* partition at offset 0 instead of 16, and glabel/ufs would find file
|
||||
* system on slice instead of partition.
|
||||
*/
|
||||
#ifdef notyet
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_fsize > 0 &&
|
||||
((pp->mediasize / fs->fs_fsize == fs->fs_old_size) ||
|
||||
(pp->mediasize / fs->fs_fsize == fs->fs_providersize))) {
|
||||
/* Valid UFS1. */
|
||||
} else if (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_fsize > 0 &&
|
||||
((pp->mediasize / fs->fs_fsize == fs->fs_size) ||
|
||||
(pp->mediasize / fs->fs_fsize == fs->fs_providersize))) {
|
||||
/* Valid UFS2. */
|
||||
} else {
|
||||
g_free(fs);
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_fsize > 0) {
|
||||
/* Valid UFS1. */
|
||||
} else if (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_fsize > 0) {
|
||||
/* Valid UFS2. */
|
||||
} else {
|
||||
free(fs);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fs->fs_sblockloc != superblock || fs->fs_ncg < 1 ||
|
||||
fs->fs_bsize < MINBSIZE ||
|
||||
(size_t)fs->fs_bsize < sizeof(struct fs)) {
|
||||
free(fs);
|
||||
continue;
|
||||
}
|
||||
|
||||
strlcpy(label, fs->fs_volname, labelsize);
|
||||
|
||||
free(fs);
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
@ -233,7 +233,7 @@ miss(NODE *p, char *tail)
|
||||
miss(p->child, tp + 1);
|
||||
*tp = '\0';
|
||||
|
||||
if (!create)
|
||||
if (!create && !uflag)
|
||||
continue;
|
||||
if (chown(path, p->st_uid, p->st_gid) == -1) {
|
||||
serr = errno;
|
||||
|
@ -5,10 +5,17 @@ TESTSRC= ${.CURDIR}/../../../contrib/netbsd-tests/usr.sbin/useradd
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/usr.sbin/pw
|
||||
|
||||
ATF_TESTS_SH= pw_delete pw_lock pw_modify pw_etcdir
|
||||
ATF_TESTS_SH= pw_etcdir \
|
||||
pw_lock \
|
||||
pw_groupdel \
|
||||
pw_groupmod \
|
||||
pw_useradd \
|
||||
pw_userdel \
|
||||
pw_usermod
|
||||
|
||||
TEST_METADATA.pw_delete+= required_user="root"
|
||||
TEST_METADATA.pw_modify+= required_user="root"
|
||||
.for tp in ${ATF_TESTS_SH}
|
||||
TEST_METADATA.${tp}+= required_user="root"
|
||||
.endfor
|
||||
|
||||
FILES= group helper_functions.shin master.passwd
|
||||
FILESDIR= ${TESTSDIR}
|
||||
|
24
usr.sbin/pw/tests/pw_groupdel.sh
Executable file
24
usr.sbin/pw/tests/pw_groupdel.sh
Executable file
@ -0,0 +1,24 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# Import helper functions
|
||||
. $(atf_get_srcdir)/helper_functions.shin
|
||||
|
||||
|
||||
# Test to make sure we do not accidentially delete wheel when trying to delete
|
||||
# an unknown group
|
||||
atf_test_case group_do_not_delete_wheel_if_group_unknown
|
||||
group_do_not_delete_wheel_if_group_unknown_head() {
|
||||
atf_set "descr" "Make sure we do not consider gid 0 an unknown group"
|
||||
}
|
||||
group_do_not_delete_wheel_if_group_unknown_body() {
|
||||
populate_etc_skel
|
||||
atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel
|
||||
atf_check -e inline:"pw: -g expects a number\n" -s exit:64 -x \
|
||||
${PW} groupdel -g I_do_not_exist
|
||||
atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel
|
||||
}
|
||||
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case group_do_not_delete_wheel_if_group_unknown
|
||||
}
|
40
usr.sbin/pw/tests/pw_useradd.sh
Executable file
40
usr.sbin/pw/tests/pw_useradd.sh
Executable file
@ -0,0 +1,40 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# Import helper functions
|
||||
. $(atf_get_srcdir)/helper_functions.shin
|
||||
|
||||
# Test add user
|
||||
atf_test_case user_add
|
||||
user_add_body() {
|
||||
populate_etc_skel
|
||||
|
||||
atf_check -s exit:0 ${PW} useradd test
|
||||
atf_check -s exit:0 -o match:"^test:.*" \
|
||||
grep "^test:.*" $HOME/master.passwd
|
||||
}
|
||||
|
||||
|
||||
atf_test_case user_add_comments
|
||||
user_add_comments_body() {
|
||||
populate_etc_skel
|
||||
|
||||
atf_check -s exit:0 ${PW} useradd test -c "Test User,work,123,456"
|
||||
atf_check -s exit:0 -o match:"^test:.*:Test User,work,123,456:" \
|
||||
grep "^test:.*:Test User,work,123,456:" $HOME/master.passwd
|
||||
}
|
||||
|
||||
atf_test_case user_add_comments_invalid
|
||||
user_add_comments_invalid_body() {
|
||||
populate_etc_skel
|
||||
|
||||
atf_check -s exit:65 -e match:"invalid character" \
|
||||
${PW} useradd test -c "Test User,work,123:456,456"
|
||||
atf_check -s exit:1 -o empty \
|
||||
grep "^test:.*:Test User,work,123:456,456:" $HOME/master.passwd
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case user_add
|
||||
atf_add_test_case user_add_comments
|
||||
atf_add_test_case user_add_comments_invalid
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
# Import helper functions
|
||||
. $(atf_get_srcdir)/helper_functions.shin
|
||||
|
||||
|
||||
# Test that a user can be deleted when another user is part of this
|
||||
# user's default group and does not go into an infinate loop.
|
||||
# PR: 191427
|
||||
@ -18,30 +19,19 @@ rmuser_seperate_group_body() {
|
||||
${PW} userdel test || atf_fail "Delete the test user"
|
||||
}
|
||||
|
||||
atf_test_case group_do_not_delete_wheel_if_group_unknown
|
||||
group_do_not_delete_wheel_if_group_unknown_head() {
|
||||
atf_set "descr" "Make sure we do not consider gid 0 an unknown group"
|
||||
}
|
||||
|
||||
group_do_not_delete_wheel_if_group_unknown_body() {
|
||||
populate_etc_skel
|
||||
atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel
|
||||
atf_check -e inline:"pw: -g expects a number\n" -s exit:64 -x ${PW} groupdel -g I_do_not_exist
|
||||
atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel
|
||||
}
|
||||
|
||||
atf_test_case user_do_not_try_to_delete_root_if_user_unknown
|
||||
user_do_not_try_to_delete_root_if_user_unknown_head() {
|
||||
atf_set "descr" "Make sure not to try to remove root if deleting an unknown user"
|
||||
atf_set "descr" \
|
||||
"Make sure not to try to remove root if deleting an unknown user"
|
||||
}
|
||||
|
||||
user_do_not_try_to_delete_root_if_user_unknown_body() {
|
||||
populate_etc_skel
|
||||
atf_check -e inline:"pw: -u expects a number\n" -s exit:64 -x ${PW} userdel -u plop
|
||||
atf_check -e inline:"pw: -u expects a number\n" -s exit:64 -x \
|
||||
${PW} userdel -u plop
|
||||
}
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case rmuser_seperate_group
|
||||
atf_add_test_case group_do_not_delete_wheel_if_group_unknown
|
||||
atf_add_test_case user_do_not_try_to_delete_root_if_user_unknown
|
||||
}
|
56
usr.sbin/pw/tests/pw_usermod.sh
Executable file
56
usr.sbin/pw/tests/pw_usermod.sh
Executable file
@ -0,0 +1,56 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# Import helper functions
|
||||
. $(atf_get_srcdir)/helper_functions.shin
|
||||
|
||||
# Test modifying a user
|
||||
atf_test_case user_mod
|
||||
user_mod_body() {
|
||||
populate_etc_skel
|
||||
|
||||
atf_check -s exit:67 -e match:"no such user" ${PW} usermod test
|
||||
atf_check -s exit:0 ${PW} useradd test
|
||||
atf_check -s exit:0 ${PW} usermod test
|
||||
atf_check -s exit:0 -o match:"^test:.*" \
|
||||
grep "^test:.*" $HOME/master.passwd
|
||||
}
|
||||
|
||||
# Test modifying a user with comments
|
||||
atf_test_case user_mod_comments
|
||||
user_mod_comments_body() {
|
||||
populate_etc_skel
|
||||
|
||||
atf_check -s exit:0 ${PW} useradd test -c "Test User,home,123,456"
|
||||
atf_check -s exit:0 ${PW} usermod test -c "Test User,work,123,456"
|
||||
atf_check -s exit:0 -o match:"^test:.*:Test User,work,123,456:" \
|
||||
grep "^test:.*:Test User,work,123,456:" $HOME/master.passwd
|
||||
}
|
||||
|
||||
# Test modifying a user with invalid comments
|
||||
atf_test_case user_mod_comments_invalid
|
||||
user_mod_comments_invalid_body() {
|
||||
populate_etc_skel
|
||||
|
||||
atf_check -s exit:0 ${PW} useradd test
|
||||
atf_check -s exit:65 -e match:"invalid character" \
|
||||
${PW} usermod test -c "Test User,work,123:456,456"
|
||||
atf_check -s exit:1 -o empty \
|
||||
grep "^test:.*:Test User,work,123:456,456:" $HOME/master.passwd
|
||||
}
|
||||
|
||||
# Test modifying a user name with -l
|
||||
atf_test_case user_mod_name
|
||||
user_mod_name_body() {
|
||||
populate_etc_skel
|
||||
|
||||
atf_check -s exit:0 ${PW} useradd foo
|
||||
atf_check -s exit:0 ${PW} usermod foo -l "bar"
|
||||
atf_check -s exit:0 -o match:"^bar:.*" \
|
||||
grep "^bar:.*" $HOME/master.passwd
|
||||
}
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case user_mod
|
||||
atf_add_test_case user_mod_comments
|
||||
atf_add_test_case user_mod_comments_invalid
|
||||
atf_add_test_case user_mod_name
|
||||
}
|
Loading…
Reference in New Issue
Block a user