Auto merge with /home/aegl/GIT/linus
This commit is contained in:
commit
08848e446b
35 changed files with 448 additions and 378 deletions
|
@ -5,14 +5,18 @@
|
||||||
|
|
||||||
Document started 15 Mar 2005 by Robert Love <rml@novell.com>
|
Document started 15 Mar 2005 by Robert Love <rml@novell.com>
|
||||||
|
|
||||||
|
|
||||||
(i) User Interface
|
(i) User Interface
|
||||||
|
|
||||||
Inotify is controlled by a set of three sys calls
|
Inotify is controlled by a set of three system calls and normal file I/O on a
|
||||||
|
returned file descriptor.
|
||||||
|
|
||||||
First step in using inotify is to initialise an inotify instance
|
First step in using inotify is to initialise an inotify instance:
|
||||||
|
|
||||||
int fd = inotify_init ();
|
int fd = inotify_init ();
|
||||||
|
|
||||||
|
Each instance is associated with a unique, ordered queue.
|
||||||
|
|
||||||
Change events are managed by "watches". A watch is an (object,mask) pair where
|
Change events are managed by "watches". A watch is an (object,mask) pair where
|
||||||
the object is a file or directory and the mask is a bit mask of one or more
|
the object is a file or directory and the mask is a bit mask of one or more
|
||||||
inotify events that the application wishes to receive. See <linux/inotify.h>
|
inotify events that the application wishes to receive. See <linux/inotify.h>
|
||||||
|
@ -22,43 +26,52 @@ Watches are added via a path to the file.
|
||||||
|
|
||||||
Watches on a directory will return events on any files inside of the directory.
|
Watches on a directory will return events on any files inside of the directory.
|
||||||
|
|
||||||
Adding a watch is simple,
|
Adding a watch is simple:
|
||||||
|
|
||||||
int wd = inotify_add_watch (fd, path, mask);
|
int wd = inotify_add_watch (fd, path, mask);
|
||||||
|
|
||||||
You can add a large number of files via something like
|
Where "fd" is the return value from inotify_init(), path is the path to the
|
||||||
|
object to watch, and mask is the watch mask (see <linux/inotify.h>).
|
||||||
for each file to watch {
|
|
||||||
int wd = inotify_add_watch (fd, file, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
You can update an existing watch in the same manner, by passing in a new mask.
|
You can update an existing watch in the same manner, by passing in a new mask.
|
||||||
|
|
||||||
An existing watch is removed via the INOTIFY_IGNORE ioctl, for example
|
An existing watch is removed via
|
||||||
|
|
||||||
inotify_rm_watch (fd, wd);
|
int ret = inotify_rm_watch (fd, wd);
|
||||||
|
|
||||||
Events are provided in the form of an inotify_event structure that is read(2)
|
Events are provided in the form of an inotify_event structure that is read(2)
|
||||||
from a inotify instance fd. The filename is of dynamic length and follows the
|
from a given inotify instance. The filename is of dynamic length and follows
|
||||||
struct. It is of size len. The filename is padded with null bytes to ensure
|
the struct. It is of size len. The filename is padded with null bytes to
|
||||||
proper alignment. This padding is reflected in len.
|
ensure proper alignment. This padding is reflected in len.
|
||||||
|
|
||||||
You can slurp multiple events by passing a large buffer, for example
|
You can slurp multiple events by passing a large buffer, for example
|
||||||
|
|
||||||
size_t len = read (fd, buf, BUF_LEN);
|
size_t len = read (fd, buf, BUF_LEN);
|
||||||
|
|
||||||
Will return as many events as are available and fit in BUF_LEN.
|
Where "buf" is a pointer to an array of "inotify_event" structures at least
|
||||||
|
BUF_LEN bytes in size. The above example will return as many events as are
|
||||||
|
available and fit in BUF_LEN.
|
||||||
|
|
||||||
each inotify instance fd is also select()- and poll()-able.
|
Each inotify instance fd is also select()- and poll()-able.
|
||||||
|
|
||||||
You can find the size of the current event queue via the FIONREAD ioctl.
|
You can find the size of the current event queue via the standard FIONREAD
|
||||||
|
ioctl on the fd returned by inotify_init().
|
||||||
|
|
||||||
All watches are destroyed and cleaned up on close.
|
All watches are destroyed and cleaned up on close.
|
||||||
|
|
||||||
|
|
||||||
(ii) Internal Kernel Implementation
|
(ii)
|
||||||
|
|
||||||
Each open inotify instance is associated with an inotify_device structure.
|
Prototypes:
|
||||||
|
|
||||||
|
int inotify_init (void);
|
||||||
|
int inotify_add_watch (int fd, const char *path, __u32 mask);
|
||||||
|
int inotify_rm_watch (int fd, __u32 mask);
|
||||||
|
|
||||||
|
|
||||||
|
(iii) Internal Kernel Implementation
|
||||||
|
|
||||||
|
Each inotify instance is associated with an inotify_device structure.
|
||||||
|
|
||||||
Each watch is associated with an inotify_watch structure. Watches are chained
|
Each watch is associated with an inotify_watch structure. Watches are chained
|
||||||
off of each associated device and each associated inode.
|
off of each associated device and each associated inode.
|
||||||
|
@ -66,7 +79,7 @@ off of each associated device and each associated inode.
|
||||||
See fs/inotify.c for the locking and lifetime rules.
|
See fs/inotify.c for the locking and lifetime rules.
|
||||||
|
|
||||||
|
|
||||||
(iii) Rationale
|
(iv) Rationale
|
||||||
|
|
||||||
Q: What is the design decision behind not tying the watch to the open fd of
|
Q: What is the design decision behind not tying the watch to the open fd of
|
||||||
the watched object?
|
the watched object?
|
||||||
|
@ -75,9 +88,9 @@ A: Watches are associated with an open inotify device, not an open file.
|
||||||
This solves the primary problem with dnotify: keeping the file open pins
|
This solves the primary problem with dnotify: keeping the file open pins
|
||||||
the file and thus, worse, pins the mount. Dnotify is therefore infeasible
|
the file and thus, worse, pins the mount. Dnotify is therefore infeasible
|
||||||
for use on a desktop system with removable media as the media cannot be
|
for use on a desktop system with removable media as the media cannot be
|
||||||
unmounted.
|
unmounted. Watching a file should not require that it be open.
|
||||||
|
|
||||||
Q: What is the design decision behind using an-fd-per-device as opposed to
|
Q: What is the design decision behind using an-fd-per-instance as opposed to
|
||||||
an fd-per-watch?
|
an fd-per-watch?
|
||||||
|
|
||||||
A: An fd-per-watch quickly consumes more file descriptors than are allowed,
|
A: An fd-per-watch quickly consumes more file descriptors than are allowed,
|
||||||
|
@ -86,8 +99,8 @@ A: An fd-per-watch quickly consumes more file descriptors than are allowed,
|
||||||
can use epoll, but requiring both is a silly and extraneous requirement.
|
can use epoll, but requiring both is a silly and extraneous requirement.
|
||||||
A watch consumes less memory than an open file, separating the number
|
A watch consumes less memory than an open file, separating the number
|
||||||
spaces is thus sensible. The current design is what user-space developers
|
spaces is thus sensible. The current design is what user-space developers
|
||||||
want: Users initialize inotify, once, and add n watches, requiring but one fd
|
want: Users initialize inotify, once, and add n watches, requiring but one
|
||||||
and no twiddling with fd limits. Initializing an inotify instance two
|
fd and no twiddling with fd limits. Initializing an inotify instance two
|
||||||
thousand times is silly. If we can implement user-space's preferences
|
thousand times is silly. If we can implement user-space's preferences
|
||||||
cleanly--and we can, the idr layer makes stuff like this trivial--then we
|
cleanly--and we can, the idr layer makes stuff like this trivial--then we
|
||||||
should.
|
should.
|
||||||
|
@ -111,9 +124,6 @@ A: An fd-per-watch quickly consumes more file descriptors than are allowed,
|
||||||
example, love it. Trust me, I asked. It is not a surprise: Who'd want
|
example, love it. Trust me, I asked. It is not a surprise: Who'd want
|
||||||
to manage and block on 1000 fd's via select?
|
to manage and block on 1000 fd's via select?
|
||||||
|
|
||||||
- You'd have to manage the fd's, as an example: Call close() when you
|
|
||||||
received a delete event.
|
|
||||||
|
|
||||||
- No way to get out of band data.
|
- No way to get out of band data.
|
||||||
|
|
||||||
- 1024 is still too low. ;-)
|
- 1024 is still too low. ;-)
|
||||||
|
@ -122,6 +132,11 @@ A: An fd-per-watch quickly consumes more file descriptors than are allowed,
|
||||||
scales to 1000s of directories, juggling 1000s of fd's just does not seem
|
scales to 1000s of directories, juggling 1000s of fd's just does not seem
|
||||||
the right interface. It is too heavy.
|
the right interface. It is too heavy.
|
||||||
|
|
||||||
|
Additionally, it _is_ possible to more than one instance and
|
||||||
|
juggle more than one queue and thus more than one associated fd. There
|
||||||
|
need not be a one-fd-per-process mapping; it is one-fd-per-queue and a
|
||||||
|
process can easily want more than one queue.
|
||||||
|
|
||||||
Q: Why the system call approach?
|
Q: Why the system call approach?
|
||||||
|
|
||||||
A: The poor user-space interface is the second biggest problem with dnotify.
|
A: The poor user-space interface is the second biggest problem with dnotify.
|
||||||
|
@ -131,8 +146,6 @@ A: The poor user-space interface is the second biggest problem with dnotify.
|
||||||
Obtaining the fd and managing the watches could have been done either via a
|
Obtaining the fd and managing the watches could have been done either via a
|
||||||
device file or a family of new system calls. We decided to implement a
|
device file or a family of new system calls. We decided to implement a
|
||||||
family of system calls because that is the preffered approach for new kernel
|
family of system calls because that is the preffered approach for new kernel
|
||||||
features and it means our user interface requirements.
|
interfaces. The only real difference was whether we wanted to use open(2)
|
||||||
|
and ioctl(2) or a couple of new system calls. System calls beat ioctls.
|
||||||
Additionally, it _is_ possible to more than one instance and
|
|
||||||
juggle more than one queue and thus more than one associated fd.
|
|
||||||
|
|
||||||
|
|
12
MAINTAINERS
12
MAINTAINERS
|
@ -1169,6 +1169,12 @@ L: linux-input@atrey.karlin.mff.cuni.cz
|
||||||
L: linux-joystick@atrey.karlin.mff.cuni.cz
|
L: linux-joystick@atrey.karlin.mff.cuni.cz
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
INOTIFY
|
||||||
|
P: John McCutchan and Robert Love
|
||||||
|
M: ttb@tentacle.dhs.org and rml@novell.com
|
||||||
|
L: linux-kernel@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
INTEL 810/815 FRAMEBUFFER DRIVER
|
INTEL 810/815 FRAMEBUFFER DRIVER
|
||||||
P: Antonino Daplas
|
P: Antonino Daplas
|
||||||
M: adaplas@pol.net
|
M: adaplas@pol.net
|
||||||
|
@ -2420,6 +2426,12 @@ L: linux-usb-users@lists.sourceforge.net
|
||||||
L: linux-usb-devel@lists.sourceforge.net
|
L: linux-usb-devel@lists.sourceforge.net
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
USB OPTION-CARD DRIVER
|
||||||
|
P: Matthias Urlichs
|
||||||
|
M: smurf@smurf.noris.de
|
||||||
|
L: linux-usb-devel@lists.sourceforge.net
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
USB OV511 DRIVER
|
USB OV511 DRIVER
|
||||||
P: Mark McClelland
|
P: Mark McClelland
|
||||||
M: mmcclell@bigfoot.com
|
M: mmcclell@bigfoot.com
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "piix4.h"
|
#include "piix4.h"
|
||||||
|
|
||||||
void (*pm_power_off)(void);
|
void (*pm_power_off)(void);
|
||||||
|
EXPORT_SYMBOL(pm_power_off);
|
||||||
|
|
||||||
void machine_restart(char * __unused)
|
void machine_restart(char * __unused)
|
||||||
{
|
{
|
||||||
|
|
|
@ -135,7 +135,7 @@ config UML_NET_MCAST
|
||||||
|
|
||||||
config UML_NET_PCAP
|
config UML_NET_PCAP
|
||||||
bool "pcap transport"
|
bool "pcap transport"
|
||||||
depends on UML_NET && BROKEN
|
depends on UML_NET && EXPERIMENTAL
|
||||||
help
|
help
|
||||||
The pcap transport makes a pcap packet stream on the host look
|
The pcap transport makes a pcap packet stream on the host look
|
||||||
like an ethernet device inside UML. This is useful for making
|
like an ethernet device inside UML. This is useful for making
|
||||||
|
|
|
@ -51,25 +51,26 @@ MRPROPER_DIRS += $(ARCH_DIR)/include2
|
||||||
endif
|
endif
|
||||||
SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
|
SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
|
||||||
|
|
||||||
include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
|
# -Dvmap=kernel_vmap affects everything, and prevents anything from
|
||||||
|
# referencing the libpcap.o symbol so named.
|
||||||
|
|
||||||
core-y += $(SUBARCH_CORE)
|
CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
|
||||||
libs-y += $(SUBARCH_LIBS)
|
$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap
|
||||||
|
|
||||||
|
USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
|
||||||
|
USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
|
||||||
|
$(MODE_INCLUDE)
|
||||||
|
|
||||||
# -Derrno=kernel_errno - This turns all kernel references to errno into
|
# -Derrno=kernel_errno - This turns all kernel references to errno into
|
||||||
# kernel_errno to separate them from the libc errno. This allows -fno-common
|
# kernel_errno to separate them from the libc errno. This allows -fno-common
|
||||||
# in CFLAGS. Otherwise, it would cause ld to complain about the two different
|
# in CFLAGS. Otherwise, it would cause ld to complain about the two different
|
||||||
# errnos.
|
# errnos.
|
||||||
|
|
||||||
CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
|
|
||||||
$(ARCH_INCLUDE) $(MODE_INCLUDE)
|
|
||||||
|
|
||||||
USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
|
|
||||||
USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
|
|
||||||
$(MODE_INCLUDE) $(ARCH_USER_CFLAGS)
|
|
||||||
CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask
|
CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask
|
||||||
CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
|
CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
|
||||||
|
|
||||||
|
include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
|
||||||
|
|
||||||
#This will adjust *FLAGS accordingly to the platform.
|
#This will adjust *FLAGS accordingly to the platform.
|
||||||
include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
|
include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
|
||||||
|
|
||||||
|
@ -116,18 +117,19 @@ CONFIG_KERNEL_STACK_ORDER ?= 2
|
||||||
STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
|
STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
|
||||||
|
|
||||||
ifndef START
|
ifndef START
|
||||||
START = $$(($(TOP_ADDR) - $(SIZE)))
|
START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] )
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \
|
CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \
|
||||||
-DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
|
-DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
|
||||||
-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \
|
-DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
|
||||||
-DKERNEL_STACK_SIZE=$(STACK_SIZE) -DSUBARCH=$(SUBARCH))
|
-DKERNEL_STACK_SIZE=$(STACK_SIZE) \
|
||||||
|
-DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap_fin.o
|
||||||
|
|
||||||
#The wrappers will select whether using "malloc" or the kernel allocator.
|
#The wrappers will select whether using "malloc" or the kernel allocator.
|
||||||
LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
|
LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
|
||||||
|
|
||||||
CFLAGS_vmlinux = $(LINK-y) $(LINK_WRAPS)
|
CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS)
|
||||||
define cmd_vmlinux__
|
define cmd_vmlinux__
|
||||||
$(CC) $(CFLAGS_vmlinux) -o $@ \
|
$(CC) $(CFLAGS_vmlinux) -o $@ \
|
||||||
-Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
|
-Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/
|
core-y += arch/um/sys-i386/ arch/i386/crypto/
|
||||||
|
|
||||||
TOP_ADDR := $(CONFIG_TOP_ADDR)
|
TOP_ADDR := $(CONFIG_TOP_ADDR)
|
||||||
|
|
||||||
|
@ -8,20 +8,31 @@ ifeq ($(CONFIG_MODE_SKAS),y)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
LDFLAGS += -m elf_i386
|
||||||
|
ELF_ARCH := $(SUBARCH)
|
||||||
|
ELF_FORMAT := elf32-$(SUBARCH)
|
||||||
|
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
|
||||||
|
|
||||||
|
ifeq ("$(origin SUBARCH)", "command line")
|
||||||
|
ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
|
||||||
|
CFLAGS += $(call cc-option,-m32)
|
||||||
|
USER_CFLAGS += $(call cc-option,-m32)
|
||||||
|
HOSTCFLAGS += $(call cc-option,-m32)
|
||||||
|
HOSTLDFLAGS += $(call cc-option,-m32)
|
||||||
|
AFLAGS += $(call cc-option,-m32)
|
||||||
|
LINK-y += $(call cc-option,-m32)
|
||||||
|
UML_OBJCOPYFLAGS += -F $(ELF_FORMAT)
|
||||||
|
|
||||||
|
export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) $(STUB_CFLAGS)
|
CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) $(STUB_CFLAGS)
|
||||||
ARCH_USER_CFLAGS :=
|
|
||||||
|
|
||||||
ifneq ($(CONFIG_GPROF),y)
|
ifneq ($(CONFIG_GPROF),y)
|
||||||
ARCH_CFLAGS += -DUM_FASTCALL
|
ARCH_CFLAGS += -DUM_FASTCALL
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ELF_ARCH := $(SUBARCH)
|
|
||||||
ELF_FORMAT := elf32-$(SUBARCH)
|
|
||||||
|
|
||||||
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
|
|
||||||
|
|
||||||
SYS_UTIL_DIR := $(ARCH_DIR)/sys-i386/util
|
|
||||||
|
|
||||||
SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
|
SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
|
||||||
|
|
||||||
prepare: $(SYS_HEADERS)
|
prepare: $(SYS_HEADERS)
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
# Copyright 2003 - 2004 Pathscale, Inc
|
# Copyright 2003 - 2004 Pathscale, Inc
|
||||||
# Released under the GPL
|
# Released under the GPL
|
||||||
|
|
||||||
SUBARCH_LIBS := arch/um/sys-x86_64/
|
libs-y += arch/um/sys-x86_64/
|
||||||
START := 0x60000000
|
START := 0x60000000
|
||||||
|
|
||||||
|
#We #undef __x86_64__ for kernelspace, not for userspace where
|
||||||
|
#it's needed for headers to work!
|
||||||
CFLAGS += -U__$(SUBARCH)__ -fno-builtin $(STUB_CFLAGS)
|
CFLAGS += -U__$(SUBARCH)__ -fno-builtin $(STUB_CFLAGS)
|
||||||
ARCH_USER_CFLAGS := -D__x86_64__
|
USER_CFLAGS += -fno-builtin
|
||||||
|
|
||||||
ELF_ARCH := i386:x86-64
|
ELF_ARCH := i386:x86-64
|
||||||
ELF_FORMAT := elf64-x86-64
|
ELF_FORMAT := elf64-x86-64
|
||||||
|
|
|
@ -10,7 +10,6 @@ slip-objs := slip_kern.o slip_user.o
|
||||||
slirp-objs := slirp_kern.o slirp_user.o
|
slirp-objs := slirp_kern.o slirp_user.o
|
||||||
daemon-objs := daemon_kern.o daemon_user.o
|
daemon-objs := daemon_kern.o daemon_user.o
|
||||||
mcast-objs := mcast_kern.o mcast_user.o
|
mcast-objs := mcast_kern.o mcast_user.o
|
||||||
#pcap-objs := pcap_kern.o pcap_user.o $(PCAP)
|
|
||||||
net-objs := net_kern.o net_user.o
|
net-objs := net_kern.o net_user.o
|
||||||
mconsole-objs := mconsole_kern.o mconsole_user.o
|
mconsole-objs := mconsole_kern.o mconsole_user.o
|
||||||
hostaudio-objs := hostaudio_kern.o
|
hostaudio-objs := hostaudio_kern.o
|
||||||
|
@ -18,6 +17,17 @@ ubd-objs := ubd_kern.o ubd_user.o
|
||||||
port-objs := port_kern.o port_user.o
|
port-objs := port_kern.o port_user.o
|
||||||
harddog-objs := harddog_kern.o harddog_user.o
|
harddog-objs := harddog_kern.o harddog_user.o
|
||||||
|
|
||||||
|
LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a)
|
||||||
|
|
||||||
|
$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o
|
||||||
|
$(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o)
|
||||||
|
#XXX: The call below does not work because the flags are added before the
|
||||||
|
# object name, so nothing from the library gets linked.
|
||||||
|
#$(call if_changed,ld)
|
||||||
|
|
||||||
|
# When the above is fixed, don't forget to add this too!
|
||||||
|
#targets := $(obj)/pcap.o
|
||||||
|
|
||||||
obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
|
obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
|
||||||
obj-$(CONFIG_SSL) += ssl.o
|
obj-$(CONFIG_SSL) += ssl.o
|
||||||
obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
|
obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
|
||||||
|
@ -26,7 +36,7 @@ obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
|
||||||
obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
|
obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
|
||||||
obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
|
obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
|
||||||
obj-$(CONFIG_UML_NET_MCAST) += mcast.o
|
obj-$(CONFIG_UML_NET_MCAST) += mcast.o
|
||||||
#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP)
|
obj-$(CONFIG_UML_NET_PCAP) += pcap.o
|
||||||
obj-$(CONFIG_UML_NET) += net.o
|
obj-$(CONFIG_UML_NET) += net.o
|
||||||
obj-$(CONFIG_MCONSOLE) += mconsole.o
|
obj-$(CONFIG_MCONSOLE) += mconsole.o
|
||||||
obj-$(CONFIG_MMAPPER) += mmapper_kern.o
|
obj-$(CONFIG_MMAPPER) += mmapper_kern.o
|
||||||
|
@ -41,6 +51,7 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
|
||||||
obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
|
obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
|
||||||
obj-$(CONFIG_UML_RANDOM) += random.o
|
obj-$(CONFIG_UML_RANDOM) += random.o
|
||||||
|
|
||||||
USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o
|
# pcap_user.o must be added explicitly.
|
||||||
|
USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o
|
||||||
|
|
||||||
include arch/um/scripts/Makefile.rules
|
include arch/um/scripts/Makefile.rules
|
||||||
|
|
|
@ -16,8 +16,8 @@ SECTIONS
|
||||||
__binary_start = .;
|
__binary_start = .;
|
||||||
|
|
||||||
#ifdef MODE_TT
|
#ifdef MODE_TT
|
||||||
.remap_data : { arch/um/sys-SUBARCH/unmap_fin.o (.data .bss) }
|
.remap_data : { UNMAP_PATH (.data .bss) }
|
||||||
.remap : { arch/um/sys-SUBARCH/unmap_fin.o (.text) }
|
.remap : { UNMAP_PATH (.text) }
|
||||||
|
|
||||||
. = ALIGN(4096); /* Init code and data */
|
. = ALIGN(4096); /* Init code and data */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,8 +12,8 @@ $(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS))
|
||||||
|
|
||||||
quiet_cmd_wrapld = LD $@
|
quiet_cmd_wrapld = LD $@
|
||||||
define cmd_wrapld
|
define cmd_wrapld
|
||||||
$(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a); \
|
$(LD) $(LDFLAGS) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) $(CFLAGS) -print-file-name=libc.a); \
|
||||||
$(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo
|
$(OBJCOPY) $(UML_OBJCOPYFLAGS) $(obj)/unmap_tmp.o $@ -G switcheroo
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE
|
$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE
|
||||||
|
|
|
@ -4,96 +4,106 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linux/config.h"
|
#include "linux/config.h"
|
||||||
|
#include "linux/sched.h"
|
||||||
#include "linux/slab.h"
|
#include "linux/slab.h"
|
||||||
|
#include "linux/types.h"
|
||||||
#include "asm/uaccess.h"
|
#include "asm/uaccess.h"
|
||||||
#include "asm/ptrace.h"
|
#include "asm/ptrace.h"
|
||||||
|
#include "asm/smp.h"
|
||||||
|
#include "asm/ldt.h"
|
||||||
#include "choose-mode.h"
|
#include "choose-mode.h"
|
||||||
#include "kern.h"
|
#include "kern.h"
|
||||||
|
#include "mode_kern.h"
|
||||||
|
|
||||||
#ifdef CONFIG_MODE_TT
|
#ifdef CONFIG_MODE_TT
|
||||||
|
|
||||||
extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
|
extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
|
||||||
|
|
||||||
/* XXX this needs copy_to_user and copy_from_user */
|
static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
|
||||||
|
|
||||||
int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)
|
|
||||||
{
|
{
|
||||||
if (!access_ok(VERIFY_READ, ptr, bytecount))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return modify_ldt(func, ptr, bytecount);
|
return modify_ldt(func, ptr, bytecount);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_MODE_SKAS
|
#ifdef CONFIG_MODE_SKAS
|
||||||
extern int userspace_pid[];
|
|
||||||
|
|
||||||
|
#include "skas.h"
|
||||||
#include "skas_ptrace.h"
|
#include "skas_ptrace.h"
|
||||||
|
|
||||||
int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)
|
static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
|
||||||
{
|
{
|
||||||
struct ptrace_ldt ldt;
|
struct ptrace_ldt ldt;
|
||||||
void *buf;
|
u32 cpu;
|
||||||
int res, n;
|
int res;
|
||||||
|
|
||||||
buf = kmalloc(bytecount, GFP_KERNEL);
|
ldt = ((struct ptrace_ldt) { .func = func,
|
||||||
if(buf == NULL)
|
.ptr = ptr,
|
||||||
return(-ENOMEM);
|
.bytecount = bytecount });
|
||||||
|
|
||||||
res = 0;
|
cpu = get_cpu();
|
||||||
|
res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);
|
||||||
|
put_cpu();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
|
||||||
|
{
|
||||||
|
struct user_desc info;
|
||||||
|
int res = 0;
|
||||||
|
void *buf = NULL;
|
||||||
|
void *p = NULL; /* What we pass to host. */
|
||||||
|
|
||||||
switch(func){
|
switch(func){
|
||||||
case 1:
|
case 1:
|
||||||
case 0x11:
|
case 0x11: /* write_ldt */
|
||||||
res = copy_from_user(buf, ptr, bytecount);
|
/* Do this check now to avoid overflows. */
|
||||||
break;
|
if (bytecount != sizeof(struct user_desc)) {
|
||||||
|
res = -EINVAL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(res != 0){
|
if(copy_from_user(&info, ptr, sizeof(info))) {
|
||||||
res = -EFAULT;
|
res = -EFAULT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ldt = ((struct ptrace_ldt) { .func = func,
|
p = &info;
|
||||||
.ptr = buf,
|
break;
|
||||||
.bytecount = bytecount });
|
case 0:
|
||||||
#warning Need to look up userspace_pid by cpu
|
case 2: /* read_ldt */
|
||||||
res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
|
|
||||||
|
/* The use of info avoids kmalloc on the write case, not on the
|
||||||
|
* read one. */
|
||||||
|
buf = kmalloc(bytecount, GFP_KERNEL);
|
||||||
|
if (!buf) {
|
||||||
|
res = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
p = buf;
|
||||||
|
default:
|
||||||
|
res = -ENOSYS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
|
||||||
|
p, bytecount);
|
||||||
if(res < 0)
|
if(res < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
switch(func){
|
switch(func){
|
||||||
case 0:
|
case 0:
|
||||||
case 2:
|
case 2:
|
||||||
n = res;
|
/* Modify_ldt was for reading and returned the number of read
|
||||||
res = copy_to_user(ptr, buf, n);
|
* bytes.*/
|
||||||
if(res != 0)
|
if(copy_to_user(ptr, p, res))
|
||||||
res = -EFAULT;
|
res = -EFAULT;
|
||||||
else
|
|
||||||
res = n;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
return(res);
|
return res;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
|
|
||||||
{
|
|
||||||
return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
|
|
||||||
ptr, bytecount));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
|
||||||
* Emacs will notice this stuff at the end of the file and automatically
|
|
||||||
* adjust the settings for this buffer only. This must remain at the end
|
|
||||||
* of the file.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* Local variables:
|
|
||||||
* c-file-style: "linux"
|
|
||||||
* End:
|
|
||||||
*/
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ int switcheroo(int fd, int prot, void *from, void *to, int size)
|
||||||
if(munmap(to, size) < 0){
|
if(munmap(to, size) < 0){
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
|
if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if(munmap(from, size) < 0){
|
if(munmap(from, size) < 0){
|
||||||
|
|
|
@ -168,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
|
||||||
|
|
||||||
frame = (struct rt_sigframe __user *)
|
frame = (struct rt_sigframe __user *)
|
||||||
round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
|
round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
|
||||||
((unsigned char *) frame) -= 128;
|
frame = (struct rt_sigframe *) ((unsigned long) frame - 128);
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
|
if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -15,7 +15,7 @@ int switcheroo(int fd, int prot, void *from, void *to, int size)
|
||||||
if(munmap(to, size) < 0){
|
if(munmap(to, size) < 0){
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
|
if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if(munmap(from, size) < 0){
|
if(munmap(from, size) < 0){
|
||||||
|
|
|
@ -355,7 +355,7 @@ static void rp_do_receive(struct r_port *info,
|
||||||
ToRecv = space;
|
ToRecv = space;
|
||||||
|
|
||||||
if (ToRecv <= 0)
|
if (ToRecv <= 0)
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if status indicates there are errored characters in the
|
* if status indicates there are errored characters in the
|
||||||
|
@ -437,6 +437,7 @@ static void rp_do_receive(struct r_port *info,
|
||||||
}
|
}
|
||||||
/* Push the data up to the tty layer */
|
/* Push the data up to the tty layer */
|
||||||
ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
|
ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
|
||||||
|
done:
|
||||||
tty_ldisc_deref(ld);
|
tty_ldisc_deref(ld);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2796,7 +2796,7 @@ void do_blank_screen(int entering_gfx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (vesa_off_interval) {
|
if (vesa_off_interval) {
|
||||||
blank_state = blank_vesa_wait,
|
blank_state = blank_vesa_wait;
|
||||||
mod_timer(&console_timer, jiffies + vesa_off_interval);
|
mod_timer(&console_timer, jiffies + vesa_off_interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1084,6 +1084,7 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
|
||||||
|
|
||||||
initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
|
initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
|
||||||
|
|
||||||
|
if (printk_ratelimit())
|
||||||
PRINT(KERN_ERR, "IR legacy activated");
|
PRINT(KERN_ERR, "IR legacy activated");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1345,7 +1345,8 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks)
|
int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
|
||||||
|
int degraded)
|
||||||
{
|
{
|
||||||
bitmap_counter_t *bmc;
|
bitmap_counter_t *bmc;
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -1362,10 +1363,12 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks)
|
||||||
rv = 1;
|
rv = 1;
|
||||||
else if (NEEDED(*bmc)) {
|
else if (NEEDED(*bmc)) {
|
||||||
rv = 1;
|
rv = 1;
|
||||||
|
if (!degraded) { /* don't set/clear bits if degraded */
|
||||||
*bmc |= RESYNC_MASK;
|
*bmc |= RESYNC_MASK;
|
||||||
*bmc &= ~NEEDED_MASK;
|
*bmc &= ~NEEDED_MASK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
spin_unlock_irq(&bitmap->lock);
|
spin_unlock_irq(&bitmap->lock);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,16 +314,16 @@ static int raid0_run (mddev_t *mddev)
|
||||||
sector_t space = conf->hash_spacing;
|
sector_t space = conf->hash_spacing;
|
||||||
int round;
|
int round;
|
||||||
conf->preshift = 0;
|
conf->preshift = 0;
|
||||||
if (sizeof(sector_t) > sizeof(unsigned long)) {
|
if (sizeof(sector_t) > sizeof(u32)) {
|
||||||
/*shift down space and s so that sector_div will work */
|
/*shift down space and s so that sector_div will work */
|
||||||
while (space > (sector_t) (~(unsigned long)0)) {
|
while (space > (sector_t) (~(u32)0)) {
|
||||||
s >>= 1;
|
s >>= 1;
|
||||||
space >>= 1;
|
space >>= 1;
|
||||||
s += 1; /* force round-up */
|
s += 1; /* force round-up */
|
||||||
conf->preshift++;
|
conf->preshift++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
round = sector_div(s, (unsigned long)space) ? 1 : 0;
|
round = sector_div(s, (u32)space) ? 1 : 0;
|
||||||
nb_zone = s + round;
|
nb_zone = s + round;
|
||||||
}
|
}
|
||||||
printk("raid0 : nb_zone is %d.\n", nb_zone);
|
printk("raid0 : nb_zone is %d.\n", nb_zone);
|
||||||
|
@ -443,7 +443,7 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
|
||||||
volatile
|
volatile
|
||||||
#endif
|
#endif
|
||||||
sector_t x = block >> conf->preshift;
|
sector_t x = block >> conf->preshift;
|
||||||
sector_div(x, (unsigned long)conf->hash_spacing);
|
sector_div(x, (u32)conf->hash_spacing);
|
||||||
zone = conf->hash_table[x];
|
zone = conf->hash_table[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1126,21 +1126,19 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
|
||||||
* only be one in raid1 resync.
|
* only be one in raid1 resync.
|
||||||
* We can find the current addess in mddev->curr_resync
|
* We can find the current addess in mddev->curr_resync
|
||||||
*/
|
*/
|
||||||
if (!conf->fullsync) {
|
if (mddev->curr_resync < max_sector) /* aborted */
|
||||||
if (mddev->curr_resync < max_sector)
|
bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
|
||||||
bitmap_end_sync(mddev->bitmap,
|
|
||||||
mddev->curr_resync,
|
|
||||||
&sync_blocks, 1);
|
&sync_blocks, 1);
|
||||||
bitmap_close_sync(mddev->bitmap);
|
else /* completed sync */
|
||||||
}
|
|
||||||
if (mddev->curr_resync >= max_sector)
|
|
||||||
conf->fullsync = 0;
|
conf->fullsync = 0;
|
||||||
|
|
||||||
|
bitmap_close_sync(mddev->bitmap);
|
||||||
close_sync(conf);
|
close_sync(conf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conf->fullsync &&
|
if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) &&
|
||||||
!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks)) {
|
!conf->fullsync) {
|
||||||
/* We can skip this block, and probably several more */
|
/* We can skip this block, and probably several more */
|
||||||
*skipped = 1;
|
*skipped = 1;
|
||||||
return sync_blocks;
|
return sync_blocks;
|
||||||
|
@ -1243,15 +1241,15 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
|
||||||
len = (max_sector - sector_nr) << 9;
|
len = (max_sector - sector_nr) << 9;
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
break;
|
break;
|
||||||
if (!conf->fullsync) {
|
|
||||||
if (sync_blocks == 0) {
|
if (sync_blocks == 0) {
|
||||||
if (!bitmap_start_sync(mddev->bitmap,
|
if (!bitmap_start_sync(mddev->bitmap, sector_nr,
|
||||||
sector_nr, &sync_blocks))
|
&sync_blocks, mddev->degraded) &&
|
||||||
|
!conf->fullsync)
|
||||||
break;
|
break;
|
||||||
if (sync_blocks < (PAGE_SIZE>>9))
|
if (sync_blocks < (PAGE_SIZE>>9))
|
||||||
BUG();
|
BUG();
|
||||||
if (len > (sync_blocks<<9)) len = sync_blocks<<9;
|
if (len > (sync_blocks<<9))
|
||||||
}
|
len = sync_blocks<<9;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0 ; i < conf->raid_disks; i++) {
|
for (i=0 ; i < conf->raid_disks; i++) {
|
||||||
|
@ -1264,7 +1262,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
i--;
|
i--;
|
||||||
bio = r1_bio->bios[i];
|
bio = r1_bio->bios[i];
|
||||||
if (bio->bi_end_io==NULL) continue;
|
if (bio->bi_end_io==NULL)
|
||||||
|
continue;
|
||||||
/* remove last page from this bio */
|
/* remove last page from this bio */
|
||||||
bio->bi_vcnt--;
|
bio->bi_vcnt--;
|
||||||
bio->bi_size -= len;
|
bio->bi_size -= len;
|
||||||
|
|
|
@ -217,13 +217,11 @@ static int lgdt3302_set_parameters(struct dvb_frontend* fe,
|
||||||
static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
|
static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
|
||||||
static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
|
static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
|
||||||
static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
|
static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
|
||||||
static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x00, 0x00, 0x00 };
|
static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x07, 0x00, 0xfe };
|
||||||
static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
|
static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
|
||||||
|
|
||||||
/* Change only if we are actually changing the modulation */
|
/* Change only if we are actually changing the modulation */
|
||||||
if (state->current_modulation != param->u.vsb.modulation) {
|
if (state->current_modulation != param->u.vsb.modulation) {
|
||||||
int value;
|
|
||||||
|
|
||||||
switch(param->u.vsb.modulation) {
|
switch(param->u.vsb.modulation) {
|
||||||
case VSB_8:
|
case VSB_8:
|
||||||
dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
|
dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
|
||||||
|
@ -276,16 +274,8 @@ static int lgdt3302_set_parameters(struct dvb_frontend* fe,
|
||||||
recovery center frequency register */
|
recovery center frequency register */
|
||||||
i2c_writebytes(state, state->config->demod_address,
|
i2c_writebytes(state, state->config->demod_address,
|
||||||
vsb_freq_cfg, sizeof(vsb_freq_cfg));
|
vsb_freq_cfg, sizeof(vsb_freq_cfg));
|
||||||
/* Set the value of 'INLVTHD' register 0x2a/0x2c
|
|
||||||
to value from 'IFACC' register 0x39/0x3b -1 */
|
/* Set the value of 'INLVTHD' register 0x2a/0x2c to 0x7fe */
|
||||||
i2c_selectreadbytes(state, AGC_RFIF_ACC0,
|
|
||||||
&agc_delay_cfg[1], 3);
|
|
||||||
value = ((agc_delay_cfg[1] & 0x0f) << 8) | agc_delay_cfg[3];
|
|
||||||
value = value -1;
|
|
||||||
dprintk("%s IFACC -1 = 0x%03x\n", __FUNCTION__, value);
|
|
||||||
agc_delay_cfg[1] = (value >> 8) & 0x0f;
|
|
||||||
agc_delay_cfg[2] = 0x00;
|
|
||||||
agc_delay_cfg[3] = value & 0xff;
|
|
||||||
i2c_writebytes(state, state->config->demod_address,
|
i2c_writebytes(state, state->config->demod_address,
|
||||||
agc_delay_cfg, sizeof(agc_delay_cfg));
|
agc_delay_cfg, sizeof(agc_delay_cfg));
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: cx88-cards.c,v 1.85 2005/07/04 19:35:05 mkrufky Exp $
|
* $Id: cx88-cards.c,v 1.86 2005/07/14 03:06:43 mchehab Exp $
|
||||||
*
|
*
|
||||||
* device driver for Conexant 2388x based TV cards
|
* device driver for Conexant 2388x based TV cards
|
||||||
* card-specific stuff.
|
* card-specific stuff.
|
||||||
|
@ -682,9 +682,9 @@ struct cx88_board cx88_boards[] = {
|
||||||
.name = "PixelView PlayTV Ultra Pro (Stereo)",
|
.name = "PixelView PlayTV Ultra Pro (Stereo)",
|
||||||
/* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */
|
/* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */
|
||||||
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
|
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
|
||||||
.radio_type = TUNER_TEA5767,
|
.radio_type = UNSET,
|
||||||
.tuner_addr = 0xc2>>1,
|
.tuner_addr = ADDR_UNSET,
|
||||||
.radio_addr = 0xc0>>1,
|
.radio_addr = ADDR_UNSET,
|
||||||
.input = {{
|
.input = {{
|
||||||
.type = CX88_VMUX_TELEVISION,
|
.type = CX88_VMUX_TELEVISION,
|
||||||
.vmux = 0,
|
.vmux = 0,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: cx88-dvb.c,v 1.41 2005/07/04 19:35:05 mkrufky Exp $
|
* $Id: cx88-dvb.c,v 1.42 2005/07/12 15:44:55 mkrufky Exp $
|
||||||
*
|
*
|
||||||
* device driver for Conexant 2388x based TV cards
|
* device driver for Conexant 2388x based TV cards
|
||||||
* MPEG Transport Stream (DVB) routines
|
* MPEG Transport Stream (DVB) routines
|
||||||
|
@ -180,12 +180,14 @@ static struct mt352_config dntv_live_dvbt_config = {
|
||||||
#if CONFIG_DVB_CX22702
|
#if CONFIG_DVB_CX22702
|
||||||
static struct cx22702_config connexant_refboard_config = {
|
static struct cx22702_config connexant_refboard_config = {
|
||||||
.demod_address = 0x43,
|
.demod_address = 0x43,
|
||||||
|
.output_mode = CX22702_SERIAL_OUTPUT,
|
||||||
.pll_address = 0x60,
|
.pll_address = 0x60,
|
||||||
.pll_desc = &dvb_pll_thomson_dtt7579,
|
.pll_desc = &dvb_pll_thomson_dtt7579,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cx22702_config hauppauge_novat_config = {
|
static struct cx22702_config hauppauge_novat_config = {
|
||||||
.demod_address = 0x43,
|
.demod_address = 0x43,
|
||||||
|
.output_mode = CX22702_SERIAL_OUTPUT,
|
||||||
.pll_address = 0x61,
|
.pll_address = 0x61,
|
||||||
.pll_desc = &dvb_pll_thomson_dtt759x,
|
.pll_desc = &dvb_pll_thomson_dtt759x,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: cx88-video.c,v 1.79 2005/07/07 14:17:47 mchehab Exp $
|
* $Id: cx88-video.c,v 1.80 2005/07/13 08:49:08 mchehab Exp $
|
||||||
*
|
*
|
||||||
* device driver for Conexant 2388x based TV cards
|
* device driver for Conexant 2388x based TV cards
|
||||||
* video4linux video interface
|
* video4linux video interface
|
||||||
|
@ -1346,6 +1346,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
dev->freq = f->frequency;
|
dev->freq = f->frequency;
|
||||||
cx88_newstation(core);
|
cx88_newstation(core);
|
||||||
cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
|
cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
|
||||||
|
|
||||||
|
/* When changing channels it is required to reset TVAUDIO */
|
||||||
|
msleep (10);
|
||||||
|
cx88_set_tvaudio(core);
|
||||||
|
|
||||||
up(&dev->lock);
|
up(&dev->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: cx88.h,v 1.68 2005/07/07 14:17:47 mchehab Exp $
|
* $Id: cx88.h,v 1.69 2005/07/13 17:25:25 mchehab Exp $
|
||||||
*
|
*
|
||||||
* v4l2 device driver for cx2388x based TV cards
|
* v4l2 device driver for cx2388x based TV cards
|
||||||
*
|
*
|
||||||
|
@ -35,8 +35,8 @@
|
||||||
#include "btcx-risc.h"
|
#include "btcx-risc.h"
|
||||||
#include "cx88-reg.h"
|
#include "cx88-reg.h"
|
||||||
|
|
||||||
#include <linux/version.h>
|
#include <linux/utsname.h>
|
||||||
#define CX88_VERSION_CODE KERNEL_VERSION(0,0,4)
|
#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5)
|
||||||
|
|
||||||
#ifndef TRUE
|
#ifndef TRUE
|
||||||
# define TRUE (1==1)
|
# define TRUE (1==1)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
|
* For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
|
||||||
* I2C address is allways 0xC0.
|
* I2C address is allways 0xC0.
|
||||||
*
|
*
|
||||||
* $Id: tea5767.c,v 1.18 2005/07/07 03:02:55 mchehab Exp $
|
* $Id: tea5767.c,v 1.21 2005/07/14 03:06:43 mchehab Exp $
|
||||||
*
|
*
|
||||||
* Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
|
* Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
|
||||||
* This code is placed under the terms of the GNU General Public License
|
* This code is placed under the terms of the GNU General Public License
|
||||||
|
@ -153,17 +153,17 @@ static void tea5767_status_dump(unsigned char *buffer)
|
||||||
|
|
||||||
switch (TEA5767_HIGH_LO_32768) {
|
switch (TEA5767_HIGH_LO_32768) {
|
||||||
case TEA5767_HIGH_LO_13MHz:
|
case TEA5767_HIGH_LO_13MHz:
|
||||||
frq = 1000 * (div * 50 - 700 - 225) / 4; /* Freq in KHz */
|
frq = (div * 50000 - 700000 - 225000) / 4; /* Freq in KHz */
|
||||||
break;
|
break;
|
||||||
case TEA5767_LOW_LO_13MHz:
|
case TEA5767_LOW_LO_13MHz:
|
||||||
frq = 1000 * (div * 50 + 700 + 225) / 4; /* Freq in KHz */
|
frq = (div * 50000 + 700000 + 225000) / 4; /* Freq in KHz */
|
||||||
break;
|
break;
|
||||||
case TEA5767_LOW_LO_32768:
|
case TEA5767_LOW_LO_32768:
|
||||||
frq = 1000 * (div * 32768 / 1000 + 700 + 225) / 4; /* Freq in KHz */
|
frq = (div * 32768 + 700000 + 225000) / 4; /* Freq in KHz */
|
||||||
break;
|
break;
|
||||||
case TEA5767_HIGH_LO_32768:
|
case TEA5767_HIGH_LO_32768:
|
||||||
default:
|
default:
|
||||||
frq = 1000 * (div * 32768 / 1000 - 700 - 225) / 4; /* Freq in KHz */
|
frq = (div * 32768 - 700000 - 225000) / 4; /* Freq in KHz */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer[0] = (div >> 8) & 0x3f;
|
buffer[0] = (div >> 8) & 0x3f;
|
||||||
|
@ -196,7 +196,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
|
||||||
unsigned div;
|
unsigned div;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
tuner_dbg (PREFIX "radio freq counter %d\n", frq);
|
tuner_dbg (PREFIX "radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
|
||||||
|
|
||||||
/* Rounds freq to next decimal value - for 62.5 KHz step */
|
/* Rounds freq to next decimal value - for 62.5 KHz step */
|
||||||
/* frq = 20*(frq/16)+radio_frq[frq%16]; */
|
/* frq = 20*(frq/16)+radio_frq[frq%16]; */
|
||||||
|
@ -224,19 +224,19 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
|
||||||
tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
|
tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
|
||||||
buffer[2] |= TEA5767_HIGH_LO_INJECT;
|
buffer[2] |= TEA5767_HIGH_LO_INJECT;
|
||||||
buffer[4] |= TEA5767_PLLREF_ENABLE;
|
buffer[4] |= TEA5767_PLLREF_ENABLE;
|
||||||
div = (frq * 4 / 16 + 700 + 225 + 25) / 50;
|
div = (frq * 4000 / 16 + 700000 + 225000 + 25000) / 50000;
|
||||||
break;
|
break;
|
||||||
case TEA5767_LOW_LO_13MHz:
|
case TEA5767_LOW_LO_13MHz:
|
||||||
tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
|
tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
|
||||||
|
|
||||||
buffer[4] |= TEA5767_PLLREF_ENABLE;
|
buffer[4] |= TEA5767_PLLREF_ENABLE;
|
||||||
div = (frq * 4 / 16 - 700 - 225 + 25) / 50;
|
div = (frq * 4000 / 16 - 700000 - 225000 + 25000) / 50000;
|
||||||
break;
|
break;
|
||||||
case TEA5767_LOW_LO_32768:
|
case TEA5767_LOW_LO_32768:
|
||||||
tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
|
tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
|
||||||
buffer[3] |= TEA5767_XTAL_32768;
|
buffer[3] |= TEA5767_XTAL_32768;
|
||||||
/* const 700=4000*175 Khz - to adjust freq to right value */
|
/* const 700=4000*175 Khz - to adjust freq to right value */
|
||||||
div = (1000 * (frq * 4 / 16 - 700 - 225) + 16384) >> 15;
|
div = ((frq * 4000 / 16 - 700000 - 225000) + 16384) >> 15;
|
||||||
break;
|
break;
|
||||||
case TEA5767_HIGH_LO_32768:
|
case TEA5767_HIGH_LO_32768:
|
||||||
default:
|
default:
|
||||||
|
@ -244,17 +244,21 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
|
||||||
|
|
||||||
buffer[2] |= TEA5767_HIGH_LO_INJECT;
|
buffer[2] |= TEA5767_HIGH_LO_INJECT;
|
||||||
buffer[3] |= TEA5767_XTAL_32768;
|
buffer[3] |= TEA5767_XTAL_32768;
|
||||||
div = (1000 * (frq * 4 / 16 + 700 + 225) + 16384) >> 15;
|
div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer[0] = (div >> 8) & 0x3f;
|
buffer[0] = (div >> 8) & 0x3f;
|
||||||
buffer[1] = div & 0xff;
|
buffer[1] = div & 0xff;
|
||||||
|
|
||||||
if (tuner_debug)
|
|
||||||
tea5767_status_dump(buffer);
|
|
||||||
|
|
||||||
if (5 != (rc = i2c_master_send(c, buffer, 5)))
|
if (5 != (rc = i2c_master_send(c, buffer, 5)))
|
||||||
tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
|
tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
|
||||||
|
|
||||||
|
if (tuner_debug) {
|
||||||
|
if (5 != (rc = i2c_master_recv(c, buffer, 5)))
|
||||||
|
tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
|
||||||
|
else
|
||||||
|
tea5767_status_dump(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tea5767_signal(struct i2c_client *c)
|
static int tea5767_signal(struct i2c_client *c)
|
||||||
|
@ -294,7 +298,7 @@ int tea5767_autodetection(struct i2c_client *c)
|
||||||
struct tuner *t = i2c_get_clientdata(c);
|
struct tuner *t = i2c_get_clientdata(c);
|
||||||
|
|
||||||
if (5 != (rc = i2c_master_recv(c, buffer, 5))) {
|
if (5 != (rc = i2c_master_recv(c, buffer, 5))) {
|
||||||
tuner_warn("it is not a TEA5767. Received %i chars.\n", rc);
|
tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,11 +314,11 @@ int tea5767_autodetection(struct i2c_client *c)
|
||||||
* bit 0 : internally set to 0
|
* bit 0 : internally set to 0
|
||||||
* Byte 5: bit 7:0 : == 0
|
* Byte 5: bit 7:0 : == 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
|
if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
|
||||||
tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
|
tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tuner_warn("TEA5767 detected.\n");
|
tuner_warn("TEA5767 detected.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: tuner-core.c,v 1.55 2005/07/08 13:20:33 mchehab Exp $
|
* $Id: tuner-core.c,v 1.58 2005/07/14 03:06:43 mchehab Exp $
|
||||||
*
|
*
|
||||||
* i2c tv tuner chip device driver
|
* i2c tv tuner chip device driver
|
||||||
* core core, i.e. kernel interfaces, registering and so on
|
* core core, i.e. kernel interfaces, registering and so on
|
||||||
|
@ -39,6 +39,9 @@ I2C_CLIENT_INSMOD;
|
||||||
static unsigned int addr = 0;
|
static unsigned int addr = 0;
|
||||||
module_param(addr, int, 0444);
|
module_param(addr, int, 0444);
|
||||||
|
|
||||||
|
static unsigned int no_autodetect = 0;
|
||||||
|
module_param(no_autodetect, int, 0444);
|
||||||
|
|
||||||
/* insmod options used at runtime => read/write */
|
/* insmod options used at runtime => read/write */
|
||||||
unsigned int tuner_debug = 0;
|
unsigned int tuner_debug = 0;
|
||||||
module_param(tuner_debug, int, 0644);
|
module_param(tuner_debug, int, 0644);
|
||||||
|
@ -318,6 +321,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||||
tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
|
tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
|
||||||
|
|
||||||
/* TEA5767 autodetection code - only for addr = 0xc0 */
|
/* TEA5767 autodetection code - only for addr = 0xc0 */
|
||||||
|
if (!no_autodetect) {
|
||||||
if (addr == 0x60) {
|
if (addr == 0x60) {
|
||||||
if (tea5767_autodetection(&t->i2c) != EINVAL) {
|
if (tea5767_autodetection(&t->i2c) != EINVAL) {
|
||||||
t->type = TUNER_TEA5767;
|
t->type = TUNER_TEA5767;
|
||||||
|
@ -331,6 +335,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initializes only the first adapter found */
|
/* Initializes only the first adapter found */
|
||||||
if (default_mode_mask != T_UNINITIALIZED) {
|
if (default_mode_mask != T_UNINITIALIZED) {
|
||||||
|
@ -631,7 +636,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
tuner_dbg("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
|
tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n",
|
||||||
|
cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
|
||||||
|
_IOC_NR(cmd), _IOC_SIZE(cmd));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,25 @@
|
||||||
History:
|
History:
|
||||||
|
|
||||||
2005-05-19 v0.1 Initial version, based on incomplete docs
|
2005-05-19 v0.1 Initial version, based on incomplete docs
|
||||||
and analysis of misbehavior of the standard driver
|
and analysis of misbehavior with the standard driver
|
||||||
2005-05-20 v0.2 Extended the input buffer to avoid losing
|
2005-05-20 v0.2 Extended the input buffer to avoid losing
|
||||||
random 64-byte chunks of data
|
random 64-byte chunks of data
|
||||||
2005-05-21 v0.3 implemented chars_in_buffer()
|
2005-05-21 v0.3 implemented chars_in_buffer()
|
||||||
turned on low_latency
|
turned on low_latency
|
||||||
simplified the code somewhat
|
simplified the code somewhat
|
||||||
|
2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load
|
||||||
|
removed some dead code
|
||||||
|
added sponsor notice
|
||||||
|
coding style clean-up
|
||||||
|
2005-06-20 v0.4.1 add missing braces :-/
|
||||||
|
killed end-of-line whitespace
|
||||||
|
2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2
|
||||||
|
|
||||||
|
Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#define DRIVER_VERSION "v0.3"
|
|
||||||
|
#define DRIVER_VERSION "v0.4"
|
||||||
#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
|
#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
|
||||||
#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver"
|
#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver"
|
||||||
|
|
||||||
|
@ -44,7 +55,6 @@ static int option_write_room (struct usb_serial_port *port);
|
||||||
|
|
||||||
static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
|
static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
|
||||||
|
|
||||||
|
|
||||||
static int option_write (struct usb_serial_port *port,
|
static int option_write (struct usb_serial_port *port,
|
||||||
const unsigned char *buf, int count);
|
const unsigned char *buf, int count);
|
||||||
|
|
||||||
|
@ -63,11 +73,14 @@ static int option_send_setup (struct usb_serial_port *port);
|
||||||
#define OPTION_VENDOR_ID 0x0AF0
|
#define OPTION_VENDOR_ID 0x0AF0
|
||||||
|
|
||||||
#define OPTION_PRODUCT_OLD 0x5000
|
#define OPTION_PRODUCT_OLD 0x5000
|
||||||
#define OPTION_PRODUCT_WLAN 0x6000
|
#define OPTION_PRODUCT_FUSION 0x6000
|
||||||
|
#define OPTION_PRODUCT_FUSION2 0x6300
|
||||||
|
|
||||||
|
|
||||||
static struct usb_device_id option_ids[] = {
|
static struct usb_device_id option_ids[] = {
|
||||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
|
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
|
||||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) },
|
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
|
||||||
|
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,13 +99,13 @@ static struct usb_driver option_driver = {
|
||||||
*/
|
*/
|
||||||
static struct usb_serial_device_type option_3port_device = {
|
static struct usb_serial_device_type option_3port_device = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "Option 3-port card",
|
.name = "Option 3G data card",
|
||||||
.short_name = "option",
|
.short_name = "option",
|
||||||
.id_table = option_ids,
|
.id_table = option_ids,
|
||||||
.num_interrupt_in = NUM_DONT_CARE,
|
.num_interrupt_in = NUM_DONT_CARE,
|
||||||
.num_bulk_in = NUM_DONT_CARE,
|
.num_bulk_in = NUM_DONT_CARE,
|
||||||
.num_bulk_out = NUM_DONT_CARE,
|
.num_bulk_out = NUM_DONT_CARE,
|
||||||
.num_ports = 1, /* 3 */
|
.num_ports = 1, /* 3, but the card reports its ports separately */
|
||||||
.open = option_open,
|
.open = option_open,
|
||||||
.close = option_close,
|
.close = option_close,
|
||||||
.write = option_write,
|
.write = option_write,
|
||||||
|
@ -110,14 +123,19 @@ static struct usb_serial_device_type option_3port_device = {
|
||||||
.read_int_callback = option_instat_callback,
|
.read_int_callback = option_instat_callback,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_DEBUG
|
||||||
static int debug;
|
static int debug;
|
||||||
|
#else
|
||||||
|
#define debug 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* per port private data */
|
/* per port private data */
|
||||||
|
|
||||||
#define N_IN_URB 4
|
#define N_IN_URB 4
|
||||||
#define N_OUT_URB 1
|
#define N_OUT_URB 1
|
||||||
#define IN_BUFLEN 1024
|
#define IN_BUFLEN 1024
|
||||||
#define OUT_BUFLEN 1024
|
#define OUT_BUFLEN 128
|
||||||
|
|
||||||
struct option_port_private {
|
struct option_port_private {
|
||||||
/* Input endpoints and buffer for this port */
|
/* Input endpoints and buffer for this port */
|
||||||
|
@ -134,7 +152,6 @@ struct option_port_private {
|
||||||
int dsr_state;
|
int dsr_state;
|
||||||
int dcd_state;
|
int dcd_state;
|
||||||
int ri_state;
|
int ri_state;
|
||||||
// int break_on;
|
|
||||||
|
|
||||||
unsigned long tx_start_time[N_OUT_URB];
|
unsigned long tx_start_time[N_OUT_URB];
|
||||||
};
|
};
|
||||||
|
@ -204,7 +221,7 @@ option_set_termios (struct usb_serial_port *port,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
option_tiocmget(struct usb_serial_port *port, struct file *file)
|
option_tiocmget (struct usb_serial_port *port, struct file *file)
|
||||||
{
|
{
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
struct option_port_private *portdata;
|
struct option_port_private *portdata;
|
||||||
|
@ -250,7 +267,7 @@ option_ioctl (struct usb_serial_port *port, struct file *file,
|
||||||
|
|
||||||
/* Write */
|
/* Write */
|
||||||
static int
|
static int
|
||||||
option_write(struct usb_serial_port *port,
|
option_write (struct usb_serial_port *port,
|
||||||
const unsigned char *buf, int count)
|
const unsigned char *buf, int count)
|
||||||
{
|
{
|
||||||
struct option_port_private *portdata;
|
struct option_port_private *portdata;
|
||||||
|
@ -263,58 +280,37 @@ option_write(struct usb_serial_port *port,
|
||||||
|
|
||||||
dbg("%s: write (%d chars)", __FUNCTION__, count);
|
dbg("%s: write (%d chars)", __FUNCTION__, count);
|
||||||
|
|
||||||
#if 0
|
|
||||||
spin_lock(&port->lock);
|
|
||||||
if (port->write_urb_busy) {
|
|
||||||
spin_unlock(&port->lock);
|
|
||||||
dbg("%s: already writing", __FUNCTION__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
port->write_urb_busy = 1;
|
|
||||||
spin_unlock(&port->lock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
left = count;
|
left = count;
|
||||||
while (left>0) {
|
for (i=0; left > 0 && i < N_OUT_URB; i++) {
|
||||||
todo = left;
|
todo = left;
|
||||||
if (todo > OUT_BUFLEN)
|
if (todo > OUT_BUFLEN)
|
||||||
todo = OUT_BUFLEN;
|
todo = OUT_BUFLEN;
|
||||||
|
|
||||||
for (;i < N_OUT_URB; i++) {
|
|
||||||
/* Check we have a valid urb/endpoint before we use it... */
|
|
||||||
this_urb = portdata->out_urbs[i];
|
this_urb = portdata->out_urbs[i];
|
||||||
if (this_urb->status != -EINPROGRESS)
|
if (this_urb->status == -EINPROGRESS) {
|
||||||
break;
|
|
||||||
if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
|
if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
|
||||||
continue;
|
continue;
|
||||||
if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
|
if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
|
||||||
continue;
|
continue;
|
||||||
this_urb->transfer_flags |= URB_ASYNC_UNLINK;
|
this_urb->transfer_flags |= URB_ASYNC_UNLINK;
|
||||||
usb_unlink_urb(this_urb);
|
usb_unlink_urb(this_urb);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
if (this_urb->status != 0)
|
||||||
if (i == N_OUT_URB) {
|
dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status);
|
||||||
/* no bulk out free! */
|
|
||||||
dbg("%s: no output urb -- left %d", __FUNCTION__,count-left);
|
|
||||||
#if 0
|
|
||||||
port->write_urb_busy = 0;
|
|
||||||
#endif
|
|
||||||
return count-left;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
|
dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
|
||||||
|
|
||||||
|
/* send the data */
|
||||||
memcpy (this_urb->transfer_buffer, buf, todo);
|
memcpy (this_urb->transfer_buffer, buf, todo);
|
||||||
|
|
||||||
/* send the data out the bulk port */
|
|
||||||
this_urb->transfer_buffer_length = todo;
|
this_urb->transfer_buffer_length = todo;
|
||||||
|
|
||||||
this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
|
this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
|
||||||
this_urb->dev = port->serial->dev;
|
this_urb->dev = port->serial->dev;
|
||||||
err = usb_submit_urb(this_urb, GFP_ATOMIC);
|
err = usb_submit_urb(this_urb, GFP_ATOMIC);
|
||||||
if (err) {
|
if (err) {
|
||||||
dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status);
|
dbg("usb_submit_urb %p (write bulk) failed (%d, has %d)", this_urb, err, this_urb->status);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
portdata->tx_start_time[i] = jiffies;
|
portdata->tx_start_time[i] = jiffies;
|
||||||
|
@ -323,9 +319,6 @@ option_write(struct usb_serial_port *port,
|
||||||
}
|
}
|
||||||
|
|
||||||
count -= left;
|
count -= left;
|
||||||
#if 0
|
|
||||||
port->write_urb_busy = 0;
|
|
||||||
#endif
|
|
||||||
dbg("%s: wrote (did %d)", __FUNCTION__, count);
|
dbg("%s: wrote (did %d)", __FUNCTION__, count);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -444,10 +437,11 @@ option_write_room (struct usb_serial_port *port)
|
||||||
|
|
||||||
portdata = usb_get_serial_port_data(port);
|
portdata = usb_get_serial_port_data(port);
|
||||||
|
|
||||||
for (i=0; i < N_OUT_URB; i++)
|
for (i=0; i < N_OUT_URB; i++) {
|
||||||
this_urb = portdata->out_urbs[i];
|
this_urb = portdata->out_urbs[i];
|
||||||
if (this_urb && this_urb->status != -EINPROGRESS)
|
if (this_urb && this_urb->status != -EINPROGRESS)
|
||||||
data_len += OUT_BUFLEN;
|
data_len += OUT_BUFLEN;
|
||||||
|
}
|
||||||
|
|
||||||
dbg("%s: %d", __FUNCTION__, data_len);
|
dbg("%s: %d", __FUNCTION__, data_len);
|
||||||
return data_len;
|
return data_len;
|
||||||
|
@ -464,11 +458,11 @@ option_chars_in_buffer (struct usb_serial_port *port)
|
||||||
|
|
||||||
portdata = usb_get_serial_port_data(port);
|
portdata = usb_get_serial_port_data(port);
|
||||||
|
|
||||||
for (i=0; i < N_OUT_URB; i++)
|
for (i=0; i < N_OUT_URB; i++) {
|
||||||
this_urb = portdata->out_urbs[i];
|
this_urb = portdata->out_urbs[i];
|
||||||
if (this_urb && this_urb->status == -EINPROGRESS)
|
if (this_urb && this_urb->status == -EINPROGRESS)
|
||||||
data_len += this_urb->transfer_buffer_length;
|
data_len += this_urb->transfer_buffer_length;
|
||||||
|
}
|
||||||
dbg("%s: %d", __FUNCTION__, data_len);
|
dbg("%s: %d", __FUNCTION__, data_len);
|
||||||
return data_len;
|
return data_len;
|
||||||
}
|
}
|
||||||
|
@ -528,7 +522,7 @@ option_open (struct usb_serial_port *port, struct file *filp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
stop_urb(struct urb *urb)
|
stop_urb (struct urb *urb)
|
||||||
{
|
{
|
||||||
if (urb && urb->status == -EINPROGRESS) {
|
if (urb && urb->status == -EINPROGRESS) {
|
||||||
urb->transfer_flags &= ~URB_ASYNC_UNLINK;
|
urb->transfer_flags &= ~URB_ASYNC_UNLINK;
|
||||||
|
@ -537,7 +531,7 @@ stop_urb(struct urb *urb)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
option_close(struct usb_serial_port *port, struct file *filp)
|
option_close (struct usb_serial_port *port, struct file *filp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct usb_serial *serial = port->serial;
|
struct usb_serial *serial = port->serial;
|
||||||
|
@ -589,7 +583,7 @@ option_setup_urb (struct usb_serial *serial, int endpoint,
|
||||||
|
|
||||||
/* Setup urbs */
|
/* Setup urbs */
|
||||||
static void
|
static void
|
||||||
option_setup_urbs(struct usb_serial *serial)
|
option_setup_urbs (struct usb_serial *serial)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
struct usb_serial_port *port;
|
struct usb_serial_port *port;
|
||||||
|
@ -617,7 +611,7 @@ option_setup_urbs(struct usb_serial *serial)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
option_send_setup(struct usb_serial_port *port)
|
option_send_setup (struct usb_serial_port *port)
|
||||||
{
|
{
|
||||||
struct usb_serial *serial = port->serial;
|
struct usb_serial *serial = port->serial;
|
||||||
struct option_port_private *portdata;
|
struct option_port_private *portdata;
|
||||||
|
@ -724,6 +718,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
|
||||||
MODULE_VERSION(DRIVER_VERSION);
|
MODULE_VERSION(DRIVER_VERSION);
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_DEBUG
|
||||||
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||||
MODULE_PARM_DESC(debug, "Debug messages");
|
MODULE_PARM_DESC(debug, "Debug messages");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -15,66 +15,79 @@
|
||||||
#include "xip.h"
|
#include "xip.h"
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
__inode_direct_access(struct inode *inode, sector_t sector, unsigned long *data) {
|
__inode_direct_access(struct inode *inode, sector_t sector,
|
||||||
|
unsigned long *data)
|
||||||
|
{
|
||||||
BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access);
|
BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access);
|
||||||
return inode->i_sb->s_bdev->bd_disk->fops
|
return inode->i_sb->s_bdev->bd_disk->fops
|
||||||
->direct_access(inode->i_sb->s_bdev,sector,data);
|
->direct_access(inode->i_sb->s_bdev,sector,data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__ext2_get_sector(struct inode *inode, sector_t offset, int create,
|
||||||
|
sector_t *result)
|
||||||
|
{
|
||||||
|
struct buffer_head tmp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
memset(&tmp, 0, sizeof(struct buffer_head));
|
||||||
|
rc = ext2_get_block(inode, offset/ (PAGE_SIZE/512), &tmp,
|
||||||
|
create);
|
||||||
|
*result = tmp.b_blocknr;
|
||||||
|
|
||||||
|
/* did we get a sparse block (hole in the file)? */
|
||||||
|
if (!(*result)) {
|
||||||
|
BUG_ON(create);
|
||||||
|
rc = -ENODATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ext2_clear_xip_target(struct inode *inode, int block) {
|
ext2_clear_xip_target(struct inode *inode, int block)
|
||||||
sector_t sector = block*(PAGE_SIZE/512);
|
{
|
||||||
|
sector_t sector = block * (PAGE_SIZE/512);
|
||||||
unsigned long data;
|
unsigned long data;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = __inode_direct_access(inode, sector, &data);
|
rc = __inode_direct_access(inode, sector, &data);
|
||||||
if (rc)
|
if (!rc)
|
||||||
return rc;
|
|
||||||
clear_page((void*)data);
|
clear_page((void*)data);
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ext2_xip_verify_sb(struct super_block *sb)
|
void ext2_xip_verify_sb(struct super_block *sb)
|
||||||
{
|
{
|
||||||
struct ext2_sb_info *sbi = EXT2_SB(sb);
|
struct ext2_sb_info *sbi = EXT2_SB(sb);
|
||||||
|
|
||||||
if ((sbi->s_mount_opt & EXT2_MOUNT_XIP)) {
|
if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&
|
||||||
if ((sb->s_bdev == NULL) ||
|
!sb->s_bdev->bd_disk->fops->direct_access) {
|
||||||
sb->s_bdev->bd_disk == NULL ||
|
|
||||||
sb->s_bdev->bd_disk->fops == NULL ||
|
|
||||||
sb->s_bdev->bd_disk->fops->direct_access == NULL) {
|
|
||||||
sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
|
sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
|
||||||
ext2_warning(sb, __FUNCTION__,
|
ext2_warning(sb, __FUNCTION__,
|
||||||
"ignoring xip option - not supported by bdev");
|
"ignoring xip option - not supported by bdev");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct page*
|
struct page *
|
||||||
ext2_get_xip_page(struct address_space *mapping, sector_t blockno,
|
ext2_get_xip_page(struct address_space *mapping, sector_t offset,
|
||||||
int create)
|
int create)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
unsigned long data;
|
unsigned long data;
|
||||||
struct buffer_head tmp;
|
sector_t sector;
|
||||||
|
|
||||||
tmp.b_state = 0;
|
/* first, retrieve the sector number */
|
||||||
tmp.b_blocknr = 0;
|
rc = __ext2_get_sector(mapping->host, offset, create, §or);
|
||||||
rc = ext2_get_block(mapping->host, blockno/(PAGE_SIZE/512) , &tmp,
|
|
||||||
create);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return ERR_PTR(rc);
|
goto error;
|
||||||
if (tmp.b_blocknr == 0) {
|
|
||||||
/* SPARSE block */
|
|
||||||
BUG_ON(create);
|
|
||||||
return ERR_PTR(-ENODATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* retrieve address of the target data */
|
||||||
rc = __inode_direct_access
|
rc = __inode_direct_access
|
||||||
(mapping->host,tmp.b_blocknr*(PAGE_SIZE/512) ,&data);
|
(mapping->host, sector * (PAGE_SIZE/512), &data);
|
||||||
if (rc)
|
if (!rc)
|
||||||
return ERR_PTR(rc);
|
|
||||||
|
|
||||||
SetPageUptodate(virt_to_page(data));
|
|
||||||
return virt_to_page(data);
|
return virt_to_page(data);
|
||||||
|
|
||||||
|
error:
|
||||||
|
return ERR_PTR(rc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/root_dev.h>
|
|
||||||
#include <linux/statfs.h>
|
#include <linux/statfs.h>
|
||||||
#include <linux/kdev_t.h>
|
#include <linux/kdev_t.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
@ -160,8 +159,6 @@ static int read_name(struct inode *ino, char *name)
|
||||||
ino->i_size = i_size;
|
ino->i_size = i_size;
|
||||||
ino->i_blksize = i_blksize;
|
ino->i_blksize = i_blksize;
|
||||||
ino->i_blocks = i_blocks;
|
ino->i_blocks = i_blocks;
|
||||||
if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
|
|
||||||
ino->i_uid = 0;
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,16 +838,10 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
|
||||||
attrs.ia_mode = attr->ia_mode;
|
attrs.ia_mode = attr->ia_mode;
|
||||||
}
|
}
|
||||||
if(attr->ia_valid & ATTR_UID){
|
if(attr->ia_valid & ATTR_UID){
|
||||||
if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
|
|
||||||
(attr->ia_uid == 0))
|
|
||||||
attr->ia_uid = getuid();
|
|
||||||
attrs.ia_valid |= HOSTFS_ATTR_UID;
|
attrs.ia_valid |= HOSTFS_ATTR_UID;
|
||||||
attrs.ia_uid = attr->ia_uid;
|
attrs.ia_uid = attr->ia_uid;
|
||||||
}
|
}
|
||||||
if(attr->ia_valid & ATTR_GID){
|
if(attr->ia_valid & ATTR_GID){
|
||||||
if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
|
|
||||||
(attr->ia_gid == 0))
|
|
||||||
attr->ia_gid = getgid();
|
|
||||||
attrs.ia_valid |= HOSTFS_ATTR_GID;
|
attrs.ia_valid |= HOSTFS_ATTR_GID;
|
||||||
attrs.ia_gid = attr->ia_gid;
|
attrs.ia_gid = attr->ia_gid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,7 +233,7 @@ static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
|
||||||
set_fs(USER_DS);
|
set_fs(USER_DS);
|
||||||
|
|
||||||
if(ppos) *ppos = file->f_pos;
|
if(ppos) *ppos = file->f_pos;
|
||||||
return(n);
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
|
static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
|
||||||
|
@ -254,7 +254,7 @@ static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
|
||||||
err = os_read_file(fd, new_buf, cur);
|
err = os_read_file(fd, new_buf, cur);
|
||||||
if(err < 0){
|
if(err < 0){
|
||||||
printk("hppfs_read : read failed, errno = %d\n",
|
printk("hppfs_read : read failed, errno = %d\n",
|
||||||
count);
|
err);
|
||||||
n = err;
|
n = err;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
|
||||||
out_free:
|
out_free:
|
||||||
kfree(new_buf);
|
kfree(new_buf);
|
||||||
out:
|
out:
|
||||||
return(n);
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
|
static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
|
||||||
|
|
5
include/asm-um/ldt.h
Normal file
5
include/asm-um/ldt.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef __UM_LDT_H
|
||||||
|
#define __UM_LDT_H
|
||||||
|
|
||||||
|
#include "asm/arch/ldt.h"
|
||||||
|
#endif
|
|
@ -262,7 +262,7 @@ void bitmap_write_all(struct bitmap *bitmap);
|
||||||
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors);
|
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors);
|
||||||
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
|
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
|
||||||
int success);
|
int success);
|
||||||
int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks);
|
int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded);
|
||||||
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
|
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
|
||||||
void bitmap_close_sync(struct bitmap *bitmap);
|
void bitmap_close_sync(struct bitmap *bitmap);
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@ static char __initdata saved_root_name[64];
|
||||||
/* this is initialized in init/main.c */
|
/* this is initialized in init/main.c */
|
||||||
dev_t ROOT_DEV;
|
dev_t ROOT_DEV;
|
||||||
|
|
||||||
EXPORT_SYMBOL(ROOT_DEV);
|
|
||||||
|
|
||||||
static int __init load_ramdisk(char *str)
|
static int __init load_ramdisk(char *str)
|
||||||
{
|
{
|
||||||
rd_doload = simple_strtol(str,NULL,0) & 3;
|
rd_doload = simple_strtol(str,NULL,0) & 3;
|
||||||
|
|
|
@ -68,13 +68,12 @@ do_xip_mapping_read(struct address_space *mapping,
|
||||||
if (unlikely(IS_ERR(page))) {
|
if (unlikely(IS_ERR(page))) {
|
||||||
if (PTR_ERR(page) == -ENODATA) {
|
if (PTR_ERR(page) == -ENODATA) {
|
||||||
/* sparse */
|
/* sparse */
|
||||||
page = virt_to_page(empty_zero_page);
|
page = ZERO_PAGE(0);
|
||||||
} else {
|
} else {
|
||||||
desc->error = PTR_ERR(page);
|
desc->error = PTR_ERR(page);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
BUG_ON(!PageUptodate(page));
|
|
||||||
|
|
||||||
/* If users can be writing to this page using arbitrary
|
/* If users can be writing to this page using arbitrary
|
||||||
* virtual addresses, take care about potential aliasing
|
* virtual addresses, take care about potential aliasing
|
||||||
|
@ -84,8 +83,7 @@ do_xip_mapping_read(struct address_space *mapping,
|
||||||
flush_dcache_page(page);
|
flush_dcache_page(page);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ok, we have the page, and it's up-to-date, so
|
* Ok, we have the page, so now we can copy it to user space...
|
||||||
* now we can copy it to user space...
|
|
||||||
*
|
*
|
||||||
* The actor routine returns how many bytes were actually used..
|
* The actor routine returns how many bytes were actually used..
|
||||||
* NOTE! This may not be the same as how much of a user buffer
|
* NOTE! This may not be the same as how much of a user buffer
|
||||||
|
@ -164,7 +162,7 @@ EXPORT_SYMBOL_GPL(xip_file_sendfile);
|
||||||
* xip_write
|
* xip_write
|
||||||
*
|
*
|
||||||
* This function walks all vmas of the address_space and unmaps the
|
* This function walks all vmas of the address_space and unmaps the
|
||||||
* empty_zero_page when found at pgoff. Should it go in rmap.c?
|
* ZERO_PAGE when found at pgoff. Should it go in rmap.c?
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
__xip_unmap (struct address_space * mapping,
|
__xip_unmap (struct address_space * mapping,
|
||||||
|
@ -187,7 +185,7 @@ __xip_unmap (struct address_space * mapping,
|
||||||
* We need the page_table_lock to protect us from page faults,
|
* We need the page_table_lock to protect us from page faults,
|
||||||
* munmap, fork, etc...
|
* munmap, fork, etc...
|
||||||
*/
|
*/
|
||||||
pte = page_check_address(virt_to_page(empty_zero_page), mm,
|
pte = page_check_address(ZERO_PAGE(address), mm,
|
||||||
address);
|
address);
|
||||||
if (!IS_ERR(pte)) {
|
if (!IS_ERR(pte)) {
|
||||||
/* Nuke the page table entry. */
|
/* Nuke the page table entry. */
|
||||||
|
@ -230,7 +228,6 @@ xip_file_nopage(struct vm_area_struct * area,
|
||||||
|
|
||||||
page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);
|
page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);
|
||||||
if (!IS_ERR(page)) {
|
if (!IS_ERR(page)) {
|
||||||
BUG_ON(!PageUptodate(page));
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
if (PTR_ERR(page) != -ENODATA)
|
if (PTR_ERR(page) != -ENODATA)
|
||||||
|
@ -245,12 +242,11 @@ xip_file_nopage(struct vm_area_struct * area,
|
||||||
pgoff*(PAGE_SIZE/512), 1);
|
pgoff*(PAGE_SIZE/512), 1);
|
||||||
if (IS_ERR(page))
|
if (IS_ERR(page))
|
||||||
return NULL;
|
return NULL;
|
||||||
BUG_ON(!PageUptodate(page));
|
|
||||||
/* unmap page at pgoff from all other vmas */
|
/* unmap page at pgoff from all other vmas */
|
||||||
__xip_unmap(mapping, pgoff);
|
__xip_unmap(mapping, pgoff);
|
||||||
} else {
|
} else {
|
||||||
/* not shared and writable, use empty_zero_page */
|
/* not shared and writable, use ZERO_PAGE() */
|
||||||
page = virt_to_page(empty_zero_page);
|
page = ZERO_PAGE(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
|
@ -319,8 +315,6 @@ __xip_file_write(struct file *filp, const char __user *buf,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
BUG_ON(!PageUptodate(page));
|
|
||||||
|
|
||||||
copied = filemap_copy_from_user(page, offset, buf, bytes);
|
copied = filemap_copy_from_user(page, offset, buf, bytes);
|
||||||
flush_dcache_page(page);
|
flush_dcache_page(page);
|
||||||
if (likely(copied > 0)) {
|
if (likely(copied > 0)) {
|
||||||
|
@ -435,8 +429,7 @@ xip_truncate_page(struct address_space *mapping, loff_t from)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return PTR_ERR(page);
|
return PTR_ERR(page);
|
||||||
} else
|
}
|
||||||
BUG_ON(!PageUptodate(page));
|
|
||||||
kaddr = kmap_atomic(page, KM_USER0);
|
kaddr = kmap_atomic(page, KM_USER0);
|
||||||
memset(kaddr + offset, 0, length);
|
memset(kaddr + offset, 0, length);
|
||||||
kunmap_atomic(kaddr, KM_USER0);
|
kunmap_atomic(kaddr, KM_USER0);
|
||||||
|
|
Loading…
Add table
Reference in a new issue