Auto merge with /home/aegl/GIT/linus
This commit is contained in:
commit
08848e446b
35 changed files with 448 additions and 378 deletions
Documentation/filesystems
MAINTAINERSarch
i386/mach-visws
um
drivers
char
ieee1394
md
media
usb/serial
fs
include
init
mm
|
@ -1,18 +1,22 @@
|
|||
inotify
|
||||
a powerful yet simple file change notification system
|
||||
inotify
|
||||
a powerful yet simple file change notification system
|
||||
|
||||
|
||||
|
||||
Document started 15 Mar 2005 by Robert Love <rml@novell.com>
|
||||
|
||||
|
||||
(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 ();
|
||||
|
||||
Each instance is associated with a unique, ordered queue.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
Adding a watch is simple,
|
||||
Adding a watch is simple:
|
||||
|
||||
int wd = inotify_add_watch (fd, path, mask);
|
||||
|
||||
You can add a large number of files via something like
|
||||
|
||||
for each file to watch {
|
||||
int wd = inotify_add_watch (fd, file, mask);
|
||||
}
|
||||
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>).
|
||||
|
||||
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)
|
||||
from a inotify instance fd. The filename is of dynamic length and follows the
|
||||
struct. It is of size len. The filename is padded with null bytes to ensure
|
||||
proper alignment. This padding is reflected in len.
|
||||
from a given inotify instance. The filename is of dynamic length and follows
|
||||
the struct. It is of size len. The filename is padded with null bytes to
|
||||
ensure proper alignment. This padding is reflected in len.
|
||||
|
||||
You can slurp multiple events by passing a large buffer, for example
|
||||
|
||||
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.
|
||||
|
||||
|
||||
(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
|
||||
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.
|
||||
|
||||
|
||||
(iii) Rationale
|
||||
(iv) Rationale
|
||||
|
||||
Q: What is the design decision behind not tying the watch to the open fd of
|
||||
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
|
||||
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
|
||||
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?
|
||||
|
||||
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.
|
||||
A watch consumes less memory than an open file, separating the number
|
||||
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
|
||||
and no twiddling with fd limits. Initializing an inotify instance two
|
||||
want: Users initialize inotify, once, and add n watches, requiring but one
|
||||
fd and no twiddling with fd limits. Initializing an inotify instance two
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
- 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
|
||||
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?
|
||||
|
||||
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
|
||||
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
|
||||
features and it means our user interface requirements.
|
||||
|
||||
Additionally, it _is_ possible to more than one instance and
|
||||
juggle more than one queue and thus more than one associated fd.
|
||||
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.
|
||||
|
||||
|
|
12
MAINTAINERS
12
MAINTAINERS
|
@ -1169,6 +1169,12 @@ L: linux-input@atrey.karlin.mff.cuni.cz
|
|||
L: linux-joystick@atrey.karlin.mff.cuni.cz
|
||||
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
|
||||
P: Antonino Daplas
|
||||
M: adaplas@pol.net
|
||||
|
@ -2420,6 +2426,12 @@ L: linux-usb-users@lists.sourceforge.net
|
|||
L: linux-usb-devel@lists.sourceforge.net
|
||||
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
|
||||
P: Mark McClelland
|
||||
M: mmcclell@bigfoot.com
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "piix4.h"
|
||||
|
||||
void (*pm_power_off)(void);
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
|
||||
void machine_restart(char * __unused)
|
||||
{
|
||||
|
|
|
@ -135,7 +135,7 @@ config UML_NET_MCAST
|
|||
|
||||
config UML_NET_PCAP
|
||||
bool "pcap transport"
|
||||
depends on UML_NET && BROKEN
|
||||
depends on UML_NET && EXPERIMENTAL
|
||||
help
|
||||
The pcap transport makes a pcap packet stream on the host look
|
||||
like an ethernet device inside UML. This is useful for making
|
||||
|
|
|
@ -51,25 +51,26 @@ MRPROPER_DIRS += $(ARCH_DIR)/include2
|
|||
endif
|
||||
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)
|
||||
libs-y += $(SUBARCH_LIBS)
|
||||
CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
|
||||
$(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
|
||||
# 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
|
||||
# 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 += $(call cc-option,-fno-unit-at-a-time,)
|
||||
|
||||
include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
|
||||
|
||||
#This will adjust *FLAGS accordingly to the platform.
|
||||
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)) ] )
|
||||
|
||||
ifndef START
|
||||
START = $$(($(TOP_ADDR) - $(SIZE)))
|
||||
START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] )
|
||||
endif
|
||||
|
||||
CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \
|
||||
CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \
|
||||
-DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
|
||||
-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \
|
||||
-DKERNEL_STACK_SIZE=$(STACK_SIZE) -DSUBARCH=$(SUBARCH))
|
||||
-DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
|
||||
-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.
|
||||
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__
|
||||
$(CC) $(CFLAGS_vmlinux) -o $@ \
|
||||
-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)
|
||||
|
||||
|
@ -8,21 +8,32 @@ ifeq ($(CONFIG_MODE_SKAS),y)
|
|||
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)
|
||||
ARCH_USER_CFLAGS :=
|
||||
|
||||
ifneq ($(CONFIG_GPROF),y)
|
||||
ARCH_CFLAGS += -DUM_FASTCALL
|
||||
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)
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
# Copyright 2003 - 2004 Pathscale, Inc
|
||||
# Released under the GPL
|
||||
|
||||
SUBARCH_LIBS := arch/um/sys-x86_64/
|
||||
libs-y += arch/um/sys-x86_64/
|
||||
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)
|
||||
ARCH_USER_CFLAGS := -D__x86_64__
|
||||
USER_CFLAGS += -fno-builtin
|
||||
|
||||
ELF_ARCH := i386: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
|
||||
daemon-objs := daemon_kern.o daemon_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
|
||||
mconsole-objs := mconsole_kern.o mconsole_user.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
|
||||
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-$(CONFIG_SSL) += ssl.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_DAEMON) += daemon.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_MCONSOLE) += mconsole.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_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
|
||||
|
|
|
@ -16,8 +16,8 @@ SECTIONS
|
|||
__binary_start = .;
|
||||
|
||||
#ifdef MODE_TT
|
||||
.remap_data : { arch/um/sys-SUBARCH/unmap_fin.o (.data .bss) }
|
||||
.remap : { arch/um/sys-SUBARCH/unmap_fin.o (.text) }
|
||||
.remap_data : { UNMAP_PATH (.data .bss) }
|
||||
.remap : { UNMAP_PATH (.text) }
|
||||
|
||||
. = ALIGN(4096); /* Init code and data */
|
||||
#endif
|
||||
|
|
|
@ -12,8 +12,8 @@ $(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS))
|
|||
|
||||
quiet_cmd_wrapld = LD $@
|
||||
define cmd_wrapld
|
||||
$(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a); \
|
||||
$(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo
|
||||
$(LD) $(LDFLAGS) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) $(CFLAGS) -print-file-name=libc.a); \
|
||||
$(OBJCOPY) $(UML_OBJCOPYFLAGS) $(obj)/unmap_tmp.o $@ -G switcheroo
|
||||
endef
|
||||
|
||||
$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE
|
||||
|
|
|
@ -4,96 +4,106 @@
|
|||
*/
|
||||
|
||||
#include "linux/config.h"
|
||||
#include "linux/sched.h"
|
||||
#include "linux/slab.h"
|
||||
#include "linux/types.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "asm/ptrace.h"
|
||||
#include "asm/smp.h"
|
||||
#include "asm/ldt.h"
|
||||
#include "choose-mode.h"
|
||||
#include "kern.h"
|
||||
#include "mode_kern.h"
|
||||
|
||||
#ifdef CONFIG_MODE_TT
|
||||
|
||||
extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
|
||||
|
||||
/* XXX this needs copy_to_user and copy_from_user */
|
||||
|
||||
int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)
|
||||
static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
|
||||
{
|
||||
if (!access_ok(VERIFY_READ, ptr, bytecount))
|
||||
return -EFAULT;
|
||||
|
||||
return modify_ldt(func, ptr, bytecount);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MODE_SKAS
|
||||
extern int userspace_pid[];
|
||||
|
||||
#include "skas.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;
|
||||
void *buf;
|
||||
int res, n;
|
||||
u32 cpu;
|
||||
int res;
|
||||
|
||||
buf = kmalloc(bytecount, GFP_KERNEL);
|
||||
if(buf == NULL)
|
||||
return(-ENOMEM);
|
||||
ldt = ((struct ptrace_ldt) { .func = func,
|
||||
.ptr = ptr,
|
||||
.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){
|
||||
case 1:
|
||||
case 0x11:
|
||||
res = copy_from_user(buf, ptr, bytecount);
|
||||
break;
|
||||
}
|
||||
case 0x11: /* write_ldt */
|
||||
/* Do this check now to avoid overflows. */
|
||||
if (bytecount != sizeof(struct user_desc)) {
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(res != 0){
|
||||
res = -EFAULT;
|
||||
if(copy_from_user(&info, ptr, sizeof(info))) {
|
||||
res = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = &info;
|
||||
break;
|
||||
case 0:
|
||||
case 2: /* read_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;
|
||||
}
|
||||
|
||||
ldt = ((struct ptrace_ldt) { .func = func,
|
||||
.ptr = buf,
|
||||
.bytecount = bytecount });
|
||||
#warning Need to look up userspace_pid by cpu
|
||||
res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
|
||||
res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
|
||||
p, bytecount);
|
||||
if(res < 0)
|
||||
goto out;
|
||||
|
||||
switch(func){
|
||||
case 0:
|
||||
case 2:
|
||||
n = res;
|
||||
res = copy_to_user(ptr, buf, n);
|
||||
if(res != 0)
|
||||
/* Modify_ldt was for reading and returned the number of read
|
||||
* bytes.*/
|
||||
if(copy_to_user(ptr, p, res))
|
||||
res = -EFAULT;
|
||||
else
|
||||
res = n;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
out:
|
||||
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){
|
||||
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);
|
||||
}
|
||||
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 *)
|
||||
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)))
|
||||
goto out;
|
||||
|
|
|
@ -15,7 +15,7 @@ int switcheroo(int fd, int prot, void *from, void *to, int size)
|
|||
if(munmap(to, size) < 0){
|
||||
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);
|
||||
}
|
||||
if(munmap(from, size) < 0){
|
||||
|
|
|
@ -355,7 +355,7 @@ static void rp_do_receive(struct r_port *info,
|
|||
ToRecv = space;
|
||||
|
||||
if (ToRecv <= 0)
|
||||
return;
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
|
||||
done:
|
||||
tty_ldisc_deref(ld);
|
||||
}
|
||||
|
||||
|
|
|
@ -2796,7 +2796,7 @@ void do_blank_screen(int entering_gfx)
|
|||
return;
|
||||
|
||||
if (vesa_off_interval) {
|
||||
blank_state = blank_vesa_wait,
|
||||
blank_state = blank_vesa_wait;
|
||||
mod_timer(&console_timer, jiffies + vesa_off_interval);
|
||||
}
|
||||
|
||||
|
|
|
@ -1084,7 +1084,8 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
|
|||
|
||||
initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
|
||||
|
||||
PRINT(KERN_ERR, "IR legacy activated");
|
||||
if (printk_ratelimit())
|
||||
PRINT(KERN_ERR, "IR legacy activated");
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ohci->IR_channel_lock, flags);
|
||||
|
|
|
@ -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;
|
||||
int rv;
|
||||
|
@ -1362,8 +1363,10 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks)
|
|||
rv = 1;
|
||||
else if (NEEDED(*bmc)) {
|
||||
rv = 1;
|
||||
*bmc |= RESYNC_MASK;
|
||||
*bmc &= ~NEEDED_MASK;
|
||||
if (!degraded) { /* don't set/clear bits if degraded */
|
||||
*bmc |= RESYNC_MASK;
|
||||
*bmc &= ~NEEDED_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(&bitmap->lock);
|
||||
|
|
|
@ -314,16 +314,16 @@ static int raid0_run (mddev_t *mddev)
|
|||
sector_t space = conf->hash_spacing;
|
||||
int round;
|
||||
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 */
|
||||
while (space > (sector_t) (~(unsigned long)0)) {
|
||||
while (space > (sector_t) (~(u32)0)) {
|
||||
s >>= 1;
|
||||
space >>= 1;
|
||||
s += 1; /* force round-up */
|
||||
conf->preshift++;
|
||||
}
|
||||
}
|
||||
round = sector_div(s, (unsigned long)space) ? 1 : 0;
|
||||
round = sector_div(s, (u32)space) ? 1 : 0;
|
||||
nb_zone = s + round;
|
||||
}
|
||||
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
|
||||
#endif
|
||||
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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
* We can find the current addess in mddev->curr_resync
|
||||
*/
|
||||
if (!conf->fullsync) {
|
||||
if (mddev->curr_resync < max_sector)
|
||||
bitmap_end_sync(mddev->bitmap,
|
||||
mddev->curr_resync,
|
||||
if (mddev->curr_resync < max_sector) /* aborted */
|
||||
bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
|
||||
&sync_blocks, 1);
|
||||
bitmap_close_sync(mddev->bitmap);
|
||||
}
|
||||
if (mddev->curr_resync >= max_sector)
|
||||
else /* completed sync */
|
||||
conf->fullsync = 0;
|
||||
|
||||
bitmap_close_sync(mddev->bitmap);
|
||||
close_sync(conf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!conf->fullsync &&
|
||||
!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks)) {
|
||||
if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) &&
|
||||
!conf->fullsync) {
|
||||
/* We can skip this block, and probably several more */
|
||||
*skipped = 1;
|
||||
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;
|
||||
if (len == 0)
|
||||
break;
|
||||
if (!conf->fullsync) {
|
||||
if (sync_blocks == 0) {
|
||||
if (!bitmap_start_sync(mddev->bitmap,
|
||||
sector_nr, &sync_blocks))
|
||||
break;
|
||||
if (sync_blocks < (PAGE_SIZE>>9))
|
||||
BUG();
|
||||
if (len > (sync_blocks<<9)) len = sync_blocks<<9;
|
||||
}
|
||||
if (sync_blocks == 0) {
|
||||
if (!bitmap_start_sync(mddev->bitmap, sector_nr,
|
||||
&sync_blocks, mddev->degraded) &&
|
||||
!conf->fullsync)
|
||||
break;
|
||||
if (sync_blocks < (PAGE_SIZE>>9))
|
||||
BUG();
|
||||
if (len > (sync_blocks<<9))
|
||||
len = sync_blocks<<9;
|
||||
}
|
||||
|
||||
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) {
|
||||
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 */
|
||||
bio->bi_vcnt--;
|
||||
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 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
|
||||
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 };
|
||||
|
||||
/* Change only if we are actually changing the modulation */
|
||||
if (state->current_modulation != param->u.vsb.modulation) {
|
||||
int value;
|
||||
|
||||
switch(param->u.vsb.modulation) {
|
||||
case VSB_8:
|
||||
dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
|
||||
|
@ -276,16 +274,8 @@ static int lgdt3302_set_parameters(struct dvb_frontend* fe,
|
|||
recovery center frequency register */
|
||||
i2c_writebytes(state, state->config->demod_address,
|
||||
vsb_freq_cfg, sizeof(vsb_freq_cfg));
|
||||
/* Set the value of 'INLVTHD' register 0x2a/0x2c
|
||||
to value from 'IFACC' register 0x39/0x3b -1 */
|
||||
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;
|
||||
|
||||
/* Set the value of 'INLVTHD' register 0x2a/0x2c to 0x7fe */
|
||||
i2c_writebytes(state, state->config->demod_address,
|
||||
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
|
||||
* card-specific stuff.
|
||||
|
@ -682,9 +682,9 @@ struct cx88_board cx88_boards[] = {
|
|||
.name = "PixelView PlayTV Ultra Pro (Stereo)",
|
||||
/* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */
|
||||
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
|
||||
.radio_type = TUNER_TEA5767,
|
||||
.tuner_addr = 0xc2>>1,
|
||||
.radio_addr = 0xc0>>1,
|
||||
.radio_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.radio_addr = ADDR_UNSET,
|
||||
.input = {{
|
||||
.type = CX88_VMUX_TELEVISION,
|
||||
.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
|
||||
* MPEG Transport Stream (DVB) routines
|
||||
|
@ -180,12 +180,14 @@ static struct mt352_config dntv_live_dvbt_config = {
|
|||
#if CONFIG_DVB_CX22702
|
||||
static struct cx22702_config connexant_refboard_config = {
|
||||
.demod_address = 0x43,
|
||||
.output_mode = CX22702_SERIAL_OUTPUT,
|
||||
.pll_address = 0x60,
|
||||
.pll_desc = &dvb_pll_thomson_dtt7579,
|
||||
};
|
||||
|
||||
static struct cx22702_config hauppauge_novat_config = {
|
||||
.demod_address = 0x43,
|
||||
.output_mode = CX22702_SERIAL_OUTPUT,
|
||||
.pll_address = 0x61,
|
||||
.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
|
||||
* video4linux video interface
|
||||
|
@ -1346,6 +1346,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
|
|||
dev->freq = f->frequency;
|
||||
cx88_newstation(core);
|
||||
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);
|
||||
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
|
||||
*
|
||||
|
@ -35,8 +35,8 @@
|
|||
#include "btcx-risc.h"
|
||||
#include "cx88-reg.h"
|
||||
|
||||
#include <linux/version.h>
|
||||
#define CX88_VERSION_CODE KERNEL_VERSION(0,0,4)
|
||||
#include <linux/utsname.h>
|
||||
#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5)
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE (1==1)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
|
||||
* 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)
|
||||
* 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) {
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
case TEA5767_HIGH_LO_32768:
|
||||
default:
|
||||
frq = 1000 * (div * 32768 / 1000 - 700 - 225) / 4; /* Freq in KHz */
|
||||
frq = (div * 32768 - 700000 - 225000) / 4; /* Freq in KHz */
|
||||
break;
|
||||
}
|
||||
buffer[0] = (div >> 8) & 0x3f;
|
||||
|
@ -196,7 +196,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
|
|||
unsigned div;
|
||||
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 */
|
||||
/* 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");
|
||||
buffer[2] |= TEA5767_HIGH_LO_INJECT;
|
||||
buffer[4] |= TEA5767_PLLREF_ENABLE;
|
||||
div = (frq * 4 / 16 + 700 + 225 + 25) / 50;
|
||||
div = (frq * 4000 / 16 + 700000 + 225000 + 25000) / 50000;
|
||||
break;
|
||||
case TEA5767_LOW_LO_13MHz:
|
||||
tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
|
||||
|
||||
buffer[4] |= TEA5767_PLLREF_ENABLE;
|
||||
div = (frq * 4 / 16 - 700 - 225 + 25) / 50;
|
||||
div = (frq * 4000 / 16 - 700000 - 225000 + 25000) / 50000;
|
||||
break;
|
||||
case TEA5767_LOW_LO_32768:
|
||||
tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
|
||||
buffer[3] |= TEA5767_XTAL_32768;
|
||||
/* 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;
|
||||
case TEA5767_HIGH_LO_32768:
|
||||
default:
|
||||
|
@ -244,17 +244,21 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
|
|||
|
||||
buffer[2] |= TEA5767_HIGH_LO_INJECT;
|
||||
buffer[3] |= TEA5767_XTAL_32768;
|
||||
div = (1000 * (frq * 4 / 16 + 700 + 225) + 16384) >> 15;
|
||||
div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
|
||||
break;
|
||||
}
|
||||
buffer[0] = (div >> 8) & 0x3f;
|
||||
buffer[1] = div & 0xff;
|
||||
|
||||
if (tuner_debug)
|
||||
tea5767_status_dump(buffer);
|
||||
|
||||
if (5 != (rc = i2c_master_send(c, buffer, 5)))
|
||||
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)
|
||||
|
@ -294,7 +298,7 @@ int tea5767_autodetection(struct i2c_client *c)
|
|||
struct tuner *t = i2c_get_clientdata(c);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -310,11 +314,11 @@ int tea5767_autodetection(struct i2c_client *c)
|
|||
* bit 0 : internally set to 0
|
||||
* Byte 5: bit 7:0 : == 0
|
||||
*/
|
||||
|
||||
if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
|
||||
tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
tuner_warn("TEA5767 detected.\n");
|
||||
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
|
||||
* core core, i.e. kernel interfaces, registering and so on
|
||||
|
@ -39,6 +39,9 @@ I2C_CLIENT_INSMOD;
|
|||
static unsigned int addr = 0;
|
||||
module_param(addr, int, 0444);
|
||||
|
||||
static unsigned int no_autodetect = 0;
|
||||
module_param(no_autodetect, int, 0444);
|
||||
|
||||
/* insmod options used at runtime => read/write */
|
||||
unsigned int tuner_debug = 0;
|
||||
module_param(tuner_debug, int, 0644);
|
||||
|
@ -318,17 +321,19 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
|
|||
tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
|
||||
|
||||
/* TEA5767 autodetection code - only for addr = 0xc0 */
|
||||
if (addr == 0x60) {
|
||||
if (tea5767_autodetection(&t->i2c) != EINVAL) {
|
||||
t->type = TUNER_TEA5767;
|
||||
t->mode_mask = T_RADIO;
|
||||
t->mode = T_STANDBY;
|
||||
t->freq = 87.5 * 16; /* Sets freq to FM range */
|
||||
default_mode_mask &= ~T_RADIO;
|
||||
if (!no_autodetect) {
|
||||
if (addr == 0x60) {
|
||||
if (tea5767_autodetection(&t->i2c) != EINVAL) {
|
||||
t->type = TUNER_TEA5767;
|
||||
t->mode_mask = T_RADIO;
|
||||
t->mode = T_STANDBY;
|
||||
t->freq = 87.5 * 16; /* Sets freq to FM range */
|
||||
default_mode_mask &= ~T_RADIO;
|
||||
|
||||
i2c_attach_client (&t->i2c);
|
||||
set_type(&t->i2c,t->type, t->mode_mask);
|
||||
return 0;
|
||||
i2c_attach_client (&t->i2c);
|
||||
set_type(&t->i2c,t->type, t->mode_mask);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -631,7 +636,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,14 +12,25 @@
|
|||
History:
|
||||
|
||||
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
|
||||
random 64-byte chunks of data
|
||||
2005-05-21 v0.3 implemented chars_in_buffer()
|
||||
turned on low_latency
|
||||
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_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 int option_write (struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count);
|
||||
|
||||
|
@ -60,14 +70,17 @@ static int option_tiocmset (struct usb_serial_port *port, struct file *file,
|
|||
static int option_send_setup (struct usb_serial_port *port);
|
||||
|
||||
/* Vendor and product IDs */
|
||||
#define OPTION_VENDOR_ID 0x0AF0
|
||||
#define OPTION_VENDOR_ID 0x0AF0
|
||||
|
||||
#define OPTION_PRODUCT_OLD 0x5000
|
||||
#define OPTION_PRODUCT_FUSION 0x6000
|
||||
#define OPTION_PRODUCT_FUSION2 0x6300
|
||||
|
||||
#define OPTION_PRODUCT_OLD 0x5000
|
||||
#define OPTION_PRODUCT_WLAN 0x6000
|
||||
|
||||
static struct usb_device_id option_ids[] = {
|
||||
{ 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 */
|
||||
};
|
||||
|
||||
|
@ -85,58 +98,62 @@ static struct usb_driver option_driver = {
|
|||
* recognizes separately, thus num_port=1.
|
||||
*/
|
||||
static struct usb_serial_device_type option_3port_device = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "Option 3-port card",
|
||||
.short_name = "option",
|
||||
.id_table = option_ids,
|
||||
.num_interrupt_in = NUM_DONT_CARE,
|
||||
.num_bulk_in = NUM_DONT_CARE,
|
||||
.num_bulk_out = NUM_DONT_CARE,
|
||||
.num_ports = 1, /* 3 */
|
||||
.open = option_open,
|
||||
.close = option_close,
|
||||
.write = option_write,
|
||||
.write_room = option_write_room,
|
||||
.chars_in_buffer = option_chars_in_buffer,
|
||||
.throttle = option_rx_throttle,
|
||||
.unthrottle = option_rx_unthrottle,
|
||||
.ioctl = option_ioctl,
|
||||
.set_termios = option_set_termios,
|
||||
.break_ctl = option_break_ctl,
|
||||
.tiocmget = option_tiocmget,
|
||||
.tiocmset = option_tiocmset,
|
||||
.attach = option_startup,
|
||||
.shutdown = option_shutdown,
|
||||
.read_int_callback = option_instat_callback,
|
||||
.owner = THIS_MODULE,
|
||||
.name = "Option 3G data card",
|
||||
.short_name = "option",
|
||||
.id_table = option_ids,
|
||||
.num_interrupt_in = NUM_DONT_CARE,
|
||||
.num_bulk_in = NUM_DONT_CARE,
|
||||
.num_bulk_out = NUM_DONT_CARE,
|
||||
.num_ports = 1, /* 3, but the card reports its ports separately */
|
||||
.open = option_open,
|
||||
.close = option_close,
|
||||
.write = option_write,
|
||||
.write_room = option_write_room,
|
||||
.chars_in_buffer = option_chars_in_buffer,
|
||||
.throttle = option_rx_throttle,
|
||||
.unthrottle = option_rx_unthrottle,
|
||||
.ioctl = option_ioctl,
|
||||
.set_termios = option_set_termios,
|
||||
.break_ctl = option_break_ctl,
|
||||
.tiocmget = option_tiocmget,
|
||||
.tiocmset = option_tiocmset,
|
||||
.attach = option_startup,
|
||||
.shutdown = option_shutdown,
|
||||
.read_int_callback = option_instat_callback,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USB_DEBUG
|
||||
static int debug;
|
||||
#else
|
||||
#define debug 0
|
||||
#endif
|
||||
|
||||
|
||||
/* per port private data */
|
||||
|
||||
#define N_IN_URB 4
|
||||
#define N_OUT_URB 1
|
||||
#define IN_BUFLEN 1024
|
||||
#define OUT_BUFLEN 1024
|
||||
#define N_IN_URB 4
|
||||
#define N_OUT_URB 1
|
||||
#define IN_BUFLEN 1024
|
||||
#define OUT_BUFLEN 128
|
||||
|
||||
struct option_port_private {
|
||||
/* Input endpoints and buffer for this port */
|
||||
struct urb *in_urbs[N_IN_URB];
|
||||
char in_buffer[N_IN_URB][IN_BUFLEN];
|
||||
struct urb *in_urbs[N_IN_URB];
|
||||
char in_buffer[N_IN_URB][IN_BUFLEN];
|
||||
/* Output endpoints and buffer for this port */
|
||||
struct urb *out_urbs[N_OUT_URB];
|
||||
char out_buffer[N_OUT_URB][OUT_BUFLEN];
|
||||
struct urb *out_urbs[N_OUT_URB];
|
||||
char out_buffer[N_OUT_URB][OUT_BUFLEN];
|
||||
|
||||
/* Settings for the port */
|
||||
int rts_state; /* Handshaking pins (outputs) */
|
||||
int dtr_state;
|
||||
int cts_state; /* Handshaking pins (inputs) */
|
||||
int dsr_state;
|
||||
int dcd_state;
|
||||
int ri_state;
|
||||
// int break_on;
|
||||
int rts_state; /* Handshaking pins (outputs) */
|
||||
int dtr_state;
|
||||
int cts_state; /* Handshaking pins (inputs) */
|
||||
int dsr_state;
|
||||
int dcd_state;
|
||||
int ri_state;
|
||||
|
||||
unsigned long tx_start_time[N_OUT_URB];
|
||||
unsigned long tx_start_time[N_OUT_URB];
|
||||
};
|
||||
|
||||
|
||||
|
@ -190,13 +207,13 @@ static void
|
|||
option_break_ctl (struct usb_serial_port *port, int break_state)
|
||||
{
|
||||
/* Unfortunately, I don't know how to send a break */
|
||||
dbg("%s", __FUNCTION__);
|
||||
dbg("%s", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
option_set_termios (struct usb_serial_port *port,
|
||||
struct termios *old_termios)
|
||||
struct termios *old_termios)
|
||||
{
|
||||
dbg("%s", __FUNCTION__);
|
||||
|
||||
|
@ -204,10 +221,10 @@ option_set_termios (struct usb_serial_port *port,
|
|||
}
|
||||
|
||||
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;
|
||||
struct option_port_private *portdata;
|
||||
unsigned int value;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
|
@ -225,7 +242,7 @@ static int
|
|||
option_tiocmset (struct usb_serial_port *port, struct file *file,
|
||||
unsigned int set, unsigned int clear)
|
||||
{
|
||||
struct option_port_private *portdata;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
|
@ -250,71 +267,50 @@ option_ioctl (struct usb_serial_port *port, struct file *file,
|
|||
|
||||
/* Write */
|
||||
static int
|
||||
option_write(struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count)
|
||||
option_write (struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count)
|
||||
{
|
||||
struct option_port_private *portdata;
|
||||
int i;
|
||||
int left, todo;
|
||||
struct urb *this_urb = NULL; /* spurious */
|
||||
int err;
|
||||
struct option_port_private *portdata;
|
||||
int i;
|
||||
int left, todo;
|
||||
struct urb *this_urb = NULL; /* spurious */
|
||||
int err;
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
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;
|
||||
left = count;
|
||||
while (left>0) {
|
||||
for (i=0; left > 0 && i < N_OUT_URB; i++) {
|
||||
todo = left;
|
||||
if (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];
|
||||
if (this_urb->status != -EINPROGRESS)
|
||||
break;
|
||||
this_urb = portdata->out_urbs[i];
|
||||
if (this_urb->status == -EINPROGRESS) {
|
||||
if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
|
||||
continue;
|
||||
if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
|
||||
continue;
|
||||
this_urb->transfer_flags |= URB_ASYNC_UNLINK;
|
||||
usb_unlink_urb(this_urb);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == N_OUT_URB) {
|
||||
/* 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;
|
||||
}
|
||||
if (this_urb->status != 0)
|
||||
dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status);
|
||||
|
||||
dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
|
||||
|
||||
/* send the data */
|
||||
memcpy (this_urb->transfer_buffer, buf, todo);
|
||||
|
||||
/* send the data out the bulk port */
|
||||
this_urb->transfer_buffer_length = todo;
|
||||
|
||||
this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
|
||||
this_urb->dev = port->serial->dev;
|
||||
err = usb_submit_urb(this_urb, GFP_ATOMIC);
|
||||
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;
|
||||
}
|
||||
portdata->tx_start_time[i] = jiffies;
|
||||
|
@ -323,9 +319,6 @@ option_write(struct usb_serial_port *port,
|
|||
}
|
||||
|
||||
count -= left;
|
||||
#if 0
|
||||
port->write_urb_busy = 0;
|
||||
#endif
|
||||
dbg("%s: wrote (did %d)", __FUNCTION__, count);
|
||||
return count;
|
||||
}
|
||||
|
@ -333,7 +326,7 @@ option_write(struct usb_serial_port *port,
|
|||
static void
|
||||
option_indat_callback (struct urb *urb, struct pt_regs *regs)
|
||||
{
|
||||
int i, err;
|
||||
int i, err;
|
||||
int endpoint;
|
||||
struct usb_serial_port *port;
|
||||
struct tty_struct *tty;
|
||||
|
@ -444,10 +437,11 @@ option_write_room (struct usb_serial_port *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];
|
||||
if (this_urb && this_urb->status != -EINPROGRESS)
|
||||
data_len += OUT_BUFLEN;
|
||||
}
|
||||
|
||||
dbg("%s: %d", __FUNCTION__, 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);
|
||||
|
||||
for (i=0; i < N_OUT_URB; i++)
|
||||
for (i=0; i < N_OUT_URB; i++) {
|
||||
this_urb = portdata->out_urbs[i];
|
||||
if (this_urb && this_urb->status == -EINPROGRESS)
|
||||
data_len += this_urb->transfer_buffer_length;
|
||||
|
||||
}
|
||||
dbg("%s: %d", __FUNCTION__, data_len);
|
||||
return data_len;
|
||||
}
|
||||
|
@ -477,10 +471,10 @@ option_chars_in_buffer (struct usb_serial_port *port)
|
|||
static int
|
||||
option_open (struct usb_serial_port *port, struct file *filp)
|
||||
{
|
||||
struct option_port_private *portdata;
|
||||
struct usb_serial *serial = port->serial;
|
||||
int i, err;
|
||||
struct urb *urb;
|
||||
struct option_port_private *portdata;
|
||||
struct usb_serial *serial = port->serial;
|
||||
int i, err;
|
||||
struct urb *urb;
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
|
@ -528,7 +522,7 @@ option_open (struct usb_serial_port *port, struct file *filp)
|
|||
}
|
||||
|
||||
static inline void
|
||||
stop_urb(struct urb *urb)
|
||||
stop_urb (struct urb *urb)
|
||||
{
|
||||
if (urb && urb->status == -EINPROGRESS) {
|
||||
urb->transfer_flags &= ~URB_ASYNC_UNLINK;
|
||||
|
@ -537,11 +531,11 @@ stop_urb(struct urb *urb)
|
|||
}
|
||||
|
||||
static void
|
||||
option_close(struct usb_serial_port *port, struct file *filp)
|
||||
option_close (struct usb_serial_port *port, struct file *filp)
|
||||
{
|
||||
int i;
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct option_port_private *portdata;
|
||||
int i;
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
dbg("%s", __FUNCTION__);
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
@ -589,11 +583,11 @@ option_setup_urb (struct usb_serial *serial, int endpoint,
|
|||
|
||||
/* Setup urbs */
|
||||
static void
|
||||
option_setup_urbs(struct usb_serial *serial)
|
||||
option_setup_urbs (struct usb_serial *serial)
|
||||
{
|
||||
int j;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
int j;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
dbg("%s", __FUNCTION__);
|
||||
|
||||
|
@ -617,7 +611,7 @@ option_setup_urbs(struct usb_serial *serial)
|
|||
|
||||
|
||||
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 option_port_private *portdata;
|
||||
|
@ -644,9 +638,9 @@ option_send_setup(struct usb_serial_port *port)
|
|||
static int
|
||||
option_startup (struct usb_serial *serial)
|
||||
{
|
||||
int i, err;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
int i, err;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
dbg("%s", __FUNCTION__);
|
||||
|
||||
|
@ -677,9 +671,9 @@ option_startup (struct usb_serial *serial)
|
|||
static void
|
||||
option_shutdown (struct usb_serial *serial)
|
||||
{
|
||||
int i, j;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
int i, j;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
dbg("%s", __FUNCTION__);
|
||||
|
||||
|
@ -724,6 +718,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
|
|||
MODULE_VERSION(DRIVER_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#ifdef CONFIG_USB_DEBUG
|
||||
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "Debug messages");
|
||||
#endif
|
||||
|
||||
|
|
|
@ -15,66 +15,79 @@
|
|||
#include "xip.h"
|
||||
|
||||
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);
|
||||
return inode->i_sb->s_bdev->bd_disk->fops
|
||||
->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
|
||||
ext2_clear_xip_target(struct inode *inode, int block) {
|
||||
sector_t sector = block*(PAGE_SIZE/512);
|
||||
ext2_clear_xip_target(struct inode *inode, int block)
|
||||
{
|
||||
sector_t sector = block * (PAGE_SIZE/512);
|
||||
unsigned long data;
|
||||
int rc;
|
||||
|
||||
rc = __inode_direct_access(inode, sector, &data);
|
||||
if (rc)
|
||||
return rc;
|
||||
clear_page((void*)data);
|
||||
return 0;
|
||||
if (!rc)
|
||||
clear_page((void*)data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ext2_xip_verify_sb(struct super_block *sb)
|
||||
{
|
||||
struct ext2_sb_info *sbi = EXT2_SB(sb);
|
||||
|
||||
if ((sbi->s_mount_opt & EXT2_MOUNT_XIP)) {
|
||||
if ((sb->s_bdev == NULL) ||
|
||||
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);
|
||||
ext2_warning(sb, __FUNCTION__,
|
||||
"ignoring xip option - not supported by bdev");
|
||||
}
|
||||
if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&
|
||||
!sb->s_bdev->bd_disk->fops->direct_access) {
|
||||
sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
|
||||
ext2_warning(sb, __FUNCTION__,
|
||||
"ignoring xip option - not supported by bdev");
|
||||
}
|
||||
}
|
||||
|
||||
struct page*
|
||||
ext2_get_xip_page(struct address_space *mapping, sector_t blockno,
|
||||
struct page *
|
||||
ext2_get_xip_page(struct address_space *mapping, sector_t offset,
|
||||
int create)
|
||||
{
|
||||
int rc;
|
||||
unsigned long data;
|
||||
struct buffer_head tmp;
|
||||
sector_t sector;
|
||||
|
||||
tmp.b_state = 0;
|
||||
tmp.b_blocknr = 0;
|
||||
rc = ext2_get_block(mapping->host, blockno/(PAGE_SIZE/512) , &tmp,
|
||||
create);
|
||||
/* first, retrieve the sector number */
|
||||
rc = __ext2_get_sector(mapping->host, offset, create, §or);
|
||||
if (rc)
|
||||
return ERR_PTR(rc);
|
||||
if (tmp.b_blocknr == 0) {
|
||||
/* SPARSE block */
|
||||
BUG_ON(create);
|
||||
return ERR_PTR(-ENODATA);
|
||||
}
|
||||
goto error;
|
||||
|
||||
/* retrieve address of the target data */
|
||||
rc = __inode_direct_access
|
||||
(mapping->host,tmp.b_blocknr*(PAGE_SIZE/512) ,&data);
|
||||
if (rc)
|
||||
return ERR_PTR(rc);
|
||||
(mapping->host, sector * (PAGE_SIZE/512), &data);
|
||||
if (!rc)
|
||||
return virt_to_page(data);
|
||||
|
||||
SetPageUptodate(virt_to_page(data));
|
||||
return virt_to_page(data);
|
||||
error:
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <linux/pagemap.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/statfs.h>
|
||||
#include <linux/kdev_t.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_blksize = i_blksize;
|
||||
ino->i_blocks = i_blocks;
|
||||
if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
|
||||
ino->i_uid = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -841,16 +838,10 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
attrs.ia_mode = attr->ia_mode;
|
||||
}
|
||||
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_uid = attr->ia_uid;
|
||||
}
|
||||
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_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);
|
||||
|
||||
if(ppos) *ppos = file->f_pos;
|
||||
return(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
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);
|
||||
if(err < 0){
|
||||
printk("hppfs_read : read failed, errno = %d\n",
|
||||
count);
|
||||
err);
|
||||
n = err;
|
||||
goto out_free;
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
|
|||
out_free:
|
||||
kfree(new_buf);
|
||||
out:
|
||||
return(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
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);
|
||||
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
|
||||
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_close_sync(struct bitmap *bitmap);
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@ static char __initdata saved_root_name[64];
|
|||
/* this is initialized in init/main.c */
|
||||
dev_t ROOT_DEV;
|
||||
|
||||
EXPORT_SYMBOL(ROOT_DEV);
|
||||
|
||||
static int __init load_ramdisk(char *str)
|
||||
{
|
||||
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 (PTR_ERR(page) == -ENODATA) {
|
||||
/* sparse */
|
||||
page = virt_to_page(empty_zero_page);
|
||||
page = ZERO_PAGE(0);
|
||||
} else {
|
||||
desc->error = PTR_ERR(page);
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
BUG_ON(!PageUptodate(page));
|
||||
}
|
||||
|
||||
/* If users can be writing to this page using arbitrary
|
||||
* virtual addresses, take care about potential aliasing
|
||||
|
@ -84,8 +83,7 @@ do_xip_mapping_read(struct address_space *mapping,
|
|||
flush_dcache_page(page);
|
||||
|
||||
/*
|
||||
* Ok, we have the page, and it's up-to-date, so
|
||||
* now we can copy it to user space...
|
||||
* Ok, we have the page, so now we can copy it to user space...
|
||||
*
|
||||
* The actor routine returns how many bytes were actually used..
|
||||
* 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
|
||||
*
|
||||
* 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
|
||||
__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,
|
||||
* munmap, fork, etc...
|
||||
*/
|
||||
pte = page_check_address(virt_to_page(empty_zero_page), mm,
|
||||
pte = page_check_address(ZERO_PAGE(address), mm,
|
||||
address);
|
||||
if (!IS_ERR(pte)) {
|
||||
/* 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);
|
||||
if (!IS_ERR(page)) {
|
||||
BUG_ON(!PageUptodate(page));
|
||||
return page;
|
||||
}
|
||||
if (PTR_ERR(page) != -ENODATA)
|
||||
|
@ -245,12 +242,11 @@ xip_file_nopage(struct vm_area_struct * area,
|
|||
pgoff*(PAGE_SIZE/512), 1);
|
||||
if (IS_ERR(page))
|
||||
return NULL;
|
||||
BUG_ON(!PageUptodate(page));
|
||||
/* unmap page at pgoff from all other vmas */
|
||||
__xip_unmap(mapping, pgoff);
|
||||
} else {
|
||||
/* not shared and writable, use empty_zero_page */
|
||||
page = virt_to_page(empty_zero_page);
|
||||
/* not shared and writable, use ZERO_PAGE() */
|
||||
page = ZERO_PAGE(address);
|
||||
}
|
||||
|
||||
return page;
|
||||
|
@ -319,8 +315,6 @@ __xip_file_write(struct file *filp, const char __user *buf,
|
|||
break;
|
||||
}
|
||||
|
||||
BUG_ON(!PageUptodate(page));
|
||||
|
||||
copied = filemap_copy_from_user(page, offset, buf, bytes);
|
||||
flush_dcache_page(page);
|
||||
if (likely(copied > 0)) {
|
||||
|
@ -435,8 +429,7 @@ xip_truncate_page(struct address_space *mapping, loff_t from)
|
|||
return 0;
|
||||
else
|
||||
return PTR_ERR(page);
|
||||
} else
|
||||
BUG_ON(!PageUptodate(page));
|
||||
}
|
||||
kaddr = kmap_atomic(page, KM_USER0);
|
||||
memset(kaddr + offset, 0, length);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
|
Loading…
Add table
Reference in a new issue