forked from Minki/linux
Merge with rsync://fileserver/linux
This commit is contained in:
commit
2c4eec9802
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "piix4.h"
|
||||
|
||||
void (*pm_power_off)(void);
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
|
||||
void machine_restart(char * __unused)
|
||||
{
|
||||
|
@ -36,12 +36,14 @@ int arch_register_cpu(int num)
|
||||
parent = &sysfs_nodes[cpu_to_node(num)];
|
||||
#endif /* CONFIG_NUMA */
|
||||
|
||||
#ifdef CONFIG_ACPI_BOOT
|
||||
/*
|
||||
* If CPEI cannot be re-targetted, and this is
|
||||
* CPEI target, then dont create the control file
|
||||
*/
|
||||
if (!can_cpei_retarget() && is_cpu_cpei_target(num))
|
||||
sysfs_cpus[num].cpu.no_control = 1;
|
||||
#endif
|
||||
|
||||
return register_cpu(&sysfs_cpus[num].cpu, num, parent);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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…
Reference in New Issue
Block a user