programs that expect RGB data (e.g. gqcam) to work with this driver. If
your colors look VERY wrong, you may want to change this.
- NAME: buf_timeout
- TYPE: integer
- DEFAULT: 5 (seconds)
- DESC: Number of seconds before unused frame buffers are deallocated.
- Previously, memory was allocated upon open() and deallocated upon
- close(). Deallocation now occurs only if the driver is closed and this
- timeout is reached. If you are capturing frames less frequently than
- the default timeout, increase this. This will not make any difference
- with programs that capture multiple frames during an open/close cycle.
-
NAME: cams
TYPE: integer (1-4 for OV511, 1-31 for OV511+)
DEFAULT: 1
HOW TO CONTACT ME:
-You can email me at mwm@i.am . Please prefix the subject line
+You can email me at mark@alpha.dyndns.org . Please prefix the subject line
with "OV511: " so that I am certain to notice your message.
CREDITS:
W: http://cvs.conectiva.com.br/drivers/ZFL-watchdog/
S: Maintained
+LINUX 2.2 FIXES
+P: Alan Cox
+M: alan@lxorguk.ukuu.org.uk
+S: Maintained
+
THE REST
P: Linus Torvalds
S: Buried alive in reporters
VERSION = 2
PATCHLEVEL = 2
SUBLEVEL = 22
-EXTRAVERSION = rc1
+EXTRAVERSION = rc2
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+++ /dev/null
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-ENTRY(_start)
-SECTIONS
-{
- . = 0xC0000000 + 0x100000;
- _text = .; /* Text and read-only data */
- .text : {
- *(.text)
- *(.fixup)
- *(.gnu.warning)
- } = 0x9090
- .text.lock : { *(.text.lock) } /* out-of-line lock text */
- .rodata : { *(.rodata) }
- .kstrtab : { *(.kstrtab) }
-
- . = ALIGN(16); /* Exception table */
- __start___ex_table = .;
- __ex_table : { *(__ex_table) }
- __stop___ex_table = .;
-
- __start___ksymtab = .; /* Kernel symbol table */
- __ksymtab : { *(__ksymtab) }
- __stop___ksymtab = .;
-
- _etext = .; /* End of text section */
-
- .data : { /* Data */
- *(.data)
- CONSTRUCTORS
- }
-
- _edata = .; /* End of data section */
-
- . = ALIGN(8192); /* init_task */
- .data.init_task : { *(.data.init_task) }
-
- . = ALIGN(4096); /* Init code and data */
- __init_begin = .;
- .text.init : { *(.text.init) }
- .data.init : { *(.data.init) }
- . = ALIGN(16); /* __setup() commandline parameters */
- __setup_start = .;
- .setup.init : { *(.setup.init) }
- __setup_end = .;
- __initcall_start = .; /* the init functions to be called */
- .initcall.init : { *(.initcall.init) }
- __initcall_end = .;
- . = ALIGN(4096);
- __init_end = .;
-
-
- . = ALIGN(32);
- .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
- . = ALIGN(4096);
- .data.page_aligned : { *(.data.idt) }
-
-
- __bss_start = .; /* BSS */
- .bss : {
- *(.bss)
- }
- _end = . ;
-
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
-}
tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5
fi
+if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_STRIPED" = "y" ]; then
+ bool ' Boot support (linear, striped)' CONFIG_MD_BOOT
+fi
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
return 0;
}
+ if (ra.nframes > INT_MAX / CD_FRAMESIZE_RAW)
+ return -EINVAL;
i=verify_area(VERIFY_WRITE, ra.buf, CD_FRAMESIZE_RAW * ra.nframes);
if(i<0)
return i;
struct bttv *btv= (struct bttv *)v;
int q,todo;
/* BROKEN: RETURNS VBI WHEN IT SHOULD RETURN GRABBED VIDEO FRAME */
+ if (count > INT_MAX)
+ return -EINVAL;
todo=count;
while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
{
}
}
}
- if (todo)
+ if (todo > 0 && todo <= VBIBUF_SIZE-btv->vbip)
{
if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, todo))
return -EFAULT;
struct bttv *btv=(struct bttv *)(v-2);
int q,todo;
+ if (count > INT_MAX)
+ return -EINVAL;
todo=count;
while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
{
}
}
}
- if (todo)
+ if (todo > 0 && todo <= VBIBUF_SIZE-btv->vbip)
{
if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, todo))
return -EFAULT;
return -EINVAL;
if (current->tty != tty && !suser())
return -EPERM;
+ /* Further code uses __put_user() relying on this get_user() having
+ * done the address range checking. */
if (get_user(type, (char *)arg))
return -EFAULT;
switch (type)
if ((p2 = *(p1++)))
for (k = 0; k < 64; k++) {
if (*p2 < MAX_GLYPH && ect++ < ct) {
- __put_user((u_short)((i<<11)+(j<<6)+k),
- &list->unicode);
- __put_user((u_short) *p2,
- &list->fontpos);
+ put_user_ret((u_short)((i<<11)+(j<<6)+k),
+ &list->unicode,
+ -EFAULT);
+ put_user_ret((u_short) *p2,
+ &list->fontpos,
+ -EFAULT);
list++;
}
p2++;
}
}
- __put_user(ect, uct);
+ put_user_ret(ect, uct, -EFAULT);
return ((ect <= ct) ? 0 : -ENOMEM);
}
+++ /dev/null
-/*
- * This file is automatically generated by ./gentbl, DO NOT EDIT!
-*/
-
-#define SINTABBITS 9
-#define SINTABSIZE (1<<SINTABBITS)
-
-static short isintab[SINTABSIZE+SINTABSIZE/4] = {
- 0, 402, 804, 1206, 1607, 2009, 2410, 2811,
- 3211, 3611, 4011, 4409, 4807, 5205, 5601, 5997,
- 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
- 9511, 9895, 10278, 10659, 11038, 11416, 11792, 12166,
- 12539, 12909, 13278, 13645, 14009, 14372, 14732, 15090,
- 15446, 15799, 16150, 16499, 16845, 17189, 17530, 17868,
- 18204, 18537, 18867, 19194, 19519, 19840, 20159, 20474,
- 20787, 21096, 21402, 21705, 22004, 22301, 22594, 22883,
- 23169, 23452, 23731, 24006, 24278, 24546, 24811, 25072,
- 25329, 25582, 25831, 26077, 26318, 26556, 26789, 27019,
- 27244, 27466, 27683, 27896, 28105, 28309, 28510, 28706,
- 28897, 29085, 29268, 29446, 29621, 29790, 29955, 30116,
- 30272, 30424, 30571, 30713, 30851, 30984, 31113, 31236,
- 31356, 31470, 31580, 31684, 31785, 31880, 31970, 32056,
- 32137, 32213, 32284, 32350, 32412, 32468, 32520, 32567,
- 32609, 32646, 32678, 32705, 32727, 32744, 32757, 32764,
- 32767, 32764, 32757, 32744, 32727, 32705, 32678, 32646,
- 32609, 32567, 32520, 32468, 32412, 32350, 32284, 32213,
- 32137, 32056, 31970, 31880, 31785, 31684, 31580, 31470,
- 31356, 31236, 31113, 30984, 30851, 30713, 30571, 30424,
- 30272, 30116, 29955, 29790, 29621, 29446, 29268, 29085,
- 28897, 28706, 28510, 28309, 28105, 27896, 27683, 27466,
- 27244, 27019, 26789, 26556, 26318, 26077, 25831, 25582,
- 25329, 25072, 24811, 24546, 24278, 24006, 23731, 23452,
- 23169, 22883, 22594, 22301, 22004, 21705, 21402, 21096,
- 20787, 20474, 20159, 19840, 19519, 19194, 18867, 18537,
- 18204, 17868, 17530, 17189, 16845, 16499, 16150, 15799,
- 15446, 15090, 14732, 14372, 14009, 13645, 13278, 12909,
- 12539, 12166, 11792, 11416, 11038, 10659, 10278, 9895,
- 9511, 9126, 8739, 8351, 7961, 7571, 7179, 6786,
- 6392, 5997, 5601, 5205, 4807, 4409, 4011, 3611,
- 3211, 2811, 2410, 2009, 1607, 1206, 804, 402,
- 0, -402, -804, -1206, -1607, -2009, -2410, -2811,
- -3211, -3611, -4011, -4409, -4807, -5205, -5601, -5997,
- -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126,
- -9511, -9895,-10278,-10659,-11038,-11416,-11792,-12166,
- -12539,-12909,-13278,-13645,-14009,-14372,-14732,-15090,
- -15446,-15799,-16150,-16499,-16845,-17189,-17530,-17868,
- -18204,-18537,-18867,-19194,-19519,-19840,-20159,-20474,
- -20787,-21096,-21402,-21705,-22004,-22301,-22594,-22883,
- -23169,-23452,-23731,-24006,-24278,-24546,-24811,-25072,
- -25329,-25582,-25831,-26077,-26318,-26556,-26789,-27019,
- -27244,-27466,-27683,-27896,-28105,-28309,-28510,-28706,
- -28897,-29085,-29268,-29446,-29621,-29790,-29955,-30116,
- -30272,-30424,-30571,-30713,-30851,-30984,-31113,-31236,
- -31356,-31470,-31580,-31684,-31785,-31880,-31970,-32056,
- -32137,-32213,-32284,-32350,-32412,-32468,-32520,-32567,
- -32609,-32646,-32678,-32705,-32727,-32744,-32757,-32764,
- -32767,-32764,-32757,-32744,-32727,-32705,-32678,-32646,
- -32609,-32567,-32520,-32468,-32412,-32350,-32284,-32213,
- -32137,-32056,-31970,-31880,-31785,-31684,-31580,-31470,
- -31356,-31236,-31113,-30984,-30851,-30713,-30571,-30424,
- -30272,-30116,-29955,-29790,-29621,-29446,-29268,-29085,
- -28897,-28706,-28510,-28309,-28105,-27896,-27683,-27466,
- -27244,-27019,-26789,-26556,-26318,-26077,-25831,-25582,
- -25329,-25072,-24811,-24546,-24278,-24006,-23731,-23452,
- -23169,-22883,-22594,-22301,-22004,-21705,-21402,-21096,
- -20787,-20474,-20159,-19840,-19519,-19194,-18867,-18537,
- -18204,-17868,-17530,-17189,-16845,-16499,-16150,-15799,
- -15446,-15090,-14732,-14372,-14009,-13645,-13278,-12909,
- -12539,-12166,-11792,-11416,-11038,-10659,-10278, -9895,
- -9511, -9126, -8739, -8351, -7961, -7571, -7179, -6786,
- -6392, -5997, -5601, -5205, -4807, -4409, -4011, -3611,
- -3211, -2811, -2410, -2009, -1607, -1206, -804, -402,
- 0, 402, 804, 1206, 1607, 2009, 2410, 2811,
- 3211, 3611, 4011, 4409, 4807, 5205, 5601, 5997,
- 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
- 9511, 9895, 10278, 10659, 11038, 11416, 11792, 12166,
- 12539, 12909, 13278, 13645, 14009, 14372, 14732, 15090,
- 15446, 15799, 16150, 16499, 16845, 17189, 17530, 17868,
- 18204, 18537, 18867, 19194, 19519, 19840, 20159, 20474,
- 20787, 21096, 21402, 21705, 22004, 22301, 22594, 22883,
- 23169, 23452, 23731, 24006, 24278, 24546, 24811, 25072,
- 25329, 25582, 25831, 26077, 26318, 26556, 26789, 27019,
- 27244, 27466, 27683, 27896, 28105, 28309, 28510, 28706,
- 28897, 29085, 29268, 29446, 29621, 29790, 29955, 30116,
- 30272, 30424, 30571, 30713, 30851, 30984, 31113, 31236,
- 31356, 31470, 31580, 31684, 31785, 31880, 31970, 32056,
- 32137, 32213, 32284, 32350, 32412, 32468, 32520, 32567,
- 32609, 32646, 32678, 32705, 32727, 32744, 32757, 32764
-};
-
}
if ((i & 1) != 0) {
Byte |= (z<<4);
- if (__put_user (Byte, temp))
+ if (put_user (Byte, temp))
{
count = -EFAULT;
break;
if (copy_from_user(&tmp, user_ud, sizeof tmp))
return -EFAULT;
if (tmp.entries) {
- i = verify_area(VERIFY_WRITE, tmp.entries,
- tmp.entry_ct*sizeof(struct unipair));
+ /* tmp.entry_ct is an unsigned short */
+ i = verify_area(VERIFY_WRITE, tmp.entries,
+ (size_t)tmp.entry_ct * sizeof(struct unipair));
if (i) return i;
}
switch (cmd) {
#endif /* CONFIG_ISDN_DIVERSION */
-static int isdn_writebuf_stub(int, int, const u_char *, int, int);
+static ssize_t isdn_writebuf_stub(int, int, const u_char *, size_t, int);
static void set_global_features(void);
static int isdn_wildmat(char *s, char *p);
goto out;
}
chidx = isdn_minor2chan(minor);
- while (isdn_writebuf_stub(drvidx, chidx, buf, count, 1) != count)
+ do {
+ retval = isdn_writebuf_stub(drvidx, chidx, buf, count, 1);
+ if (retval == count || retval < 0) break;
interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]);
- retval = count;
+ } while (1);
goto out;
}
if (minor <= ISDN_MINOR_CTRLMAX) {
/*
* writebuf replacement for SKB_ABLE drivers
*/
-static int
-isdn_writebuf_stub(int drvidx, int chan, const u_char * buf, int len,
+static ssize_t
+isdn_writebuf_stub(int drvidx, int chan, const u_char * buf, size_t len,
int user)
{
- int ret;
- int hl = dev->drv[drvidx]->interface->hl_hdrlen;
- struct sk_buff *skb = alloc_skb(hl + len, GFP_ATOMIC);
+ int ret = 0;
+ unsigned int hl;
+ struct sk_buff *skb;
+
+ hl = dev->drv[drvidx]->interface->hl_hdrlen;
+ if (len > INT_MAX / 2 || hl > INT_MAX / 2)
+ return -EINVAL;
+ skb = alloc_skb(hl + len, GFP_ATOMIC);
if (!skb)
- return 0;
+ return -ENOMEM;
skb_reserve(skb, hl);
if (user)
- copy_from_user(skb_put(skb, len), buf, len);
+ ret = copy_from_user(skb_put(skb, len), buf, len) ? -EFAULT : 0;
else
memcpy(skb_put(skb, len), buf, len);
- ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, 1, skb);
+ if (!ret)
+ ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx,
+ chan, 1, skb);
if (ret <= 0)
dev_kfree_skb(skb);
if (ret > 0)
* reports, that there is data
*/
-int
-isdn_ppp_read(int min, struct file *file, char *buf, int count)
+ssize_t
+isdn_ppp_read(int min, struct file *file, char *buf, size_t count)
{
struct ippp_struct *is;
struct ippp_buf_queue *b;
* ipppd wanna write a packet to the card .. non-blocking
*/
-int
-isdn_ppp_write(int min, struct file *file, const char *buf, int count)
+ssize_t
+isdn_ppp_write(int min, struct file *file, const char *buf, size_t count)
{
isdn_net_local *lp;
struct ippp_struct *is;
if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) &&
lp->dialstate == 0 &&
(lp->flags & ISDN_NET_CONNECTED)) {
- unsigned short hl;
+ unsigned int hl;
struct sk_buff *skb;
/*
* we need to reserve enought space in front of
* 16 bytes, now we are looking what the driver want
*/
hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
+ if (hl > INT_MAX / 2 || count > INT_MAX / 2)
+ return -EINVAL;
skb = alloc_skb(hl+count, GFP_ATOMIC);
- if (!skb) {
- printk(KERN_WARNING "isdn_ppp_write: out of memory!\n");
- return count;
- }
+ if (!skb)
+ return -ENOMEM;
skb_reserve(skb, hl);
if (copy_from_user(skb_put(skb, count), buf, count))
{
#ifdef CONFIG_ISDN_PPP_VJ
if (proto == PPP_IP && ipts->pppcfg & SC_COMP_TCP) { /* ipts here? probably yes, but check this again */
struct sk_buff *new_skb;
- unsigned short hl;
+ unsigned int hl;
/*
* we need to reserve enought space in front of
* sk_buff. old call to dev_alloc_skb only reserved
#include <linux/ppp_defs.h> /* for PPP_PROTOCOL */
#include <linux/isdn_ppp.h> /* for isdn_ppp info */
-extern int isdn_ppp_read(int, struct file *, char *, int);
-extern int isdn_ppp_write(int, struct file *, const char *, int);
+extern ssize_t isdn_ppp_read(int, struct file *, char *, size_t);
+extern ssize_t isdn_ppp_write(int, struct file *, const char *, size_t);
extern int isdn_ppp_open(int, struct file *);
extern int isdn_ppp_init(void);
extern void isdn_ppp_cleanup(void);
#ifdef DEBUG
printk(KERN_DEBUG "CPN: Octect 3 %02x\n", skb->data[1]);
#endif
- if ((skb->data[1] & 0x80) == 0)
+ if (len >= 2 && (skb->data[1] & 0x80) == 0)
count = 2;
if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC)))
if (len > 0) {
int count = 1;
- if ((skb->data[1] & 0x80) == 0)
+ if (len >= 2 && (skb->data[1] & 0x80) == 0)
count = 2;
if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC)))
/* --------------------------------------------------------------------- */
-/*
- * currently this module is supposed to support both module styles, i.e.
- * the old one present up to about 2.1.9, and the new one functioning
- * starting with 2.1.21. The reason is I have a kit allowing to compile
- * this module also under 2.0.x which was requested by several people.
- * This will go in 2.2
- */
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE >= 0x20100
#include <asm/uaccess.h>
-#else
-#include <asm/segment.h>
-#include <linux/mm.h>
-
-#undef put_user
-#undef get_user
-
-#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
-#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
-
-extern __inline__ int copy_from_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_READ, from, n);
- if (i)
- return i;
- memcpy_fromfs(to, from, n);
- return 0;
-}
-
-extern __inline__ int copy_to_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_WRITE, to, n);
- if (i)
- return i;
- memcpy_tofs(to, from, n);
- return 0;
-}
-#endif
-
-#if LINUX_VERSION_CODE >= 0x20123
#include <linux/init.h>
-#else
-#define __init
-#define __initdata
-#define __initfunc(x) x
-#endif
/* --------------------------------------------------------------------- */
static const char *mode[NR_PORTS] = { "picpar", };
static int iobase[NR_PORTS] = { 0x378, };
-#if LINUX_VERSION_CODE >= 0x20115
-
MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s");
MODULE_PARM_DESC(mode, "baycom operating mode; eg. par96 or picpar");
MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i");
MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
MODULE_DESCRIPTION("Baycom par96 and picpar amateur radio modem driver");
-#endif
-
__initfunc(int init_module(void))
{
int i;
/* --------------------------------------------------------------------- */
-/*
- * currently this module is supposed to support both module styles, i.e.
- * the old one present up to about 2.1.9, and the new one functioning
- * starting with 2.1.21. The reason is I have a kit allowing to compile
- * this module also under 2.0.x which was requested by several people.
- * This will go in 2.2
- */
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE >= 0x20100
#include <asm/uaccess.h>
-#else
-#include <asm/segment.h>
-#include <linux/mm.h>
-
-#undef put_user
-#undef get_user
-
-#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
-#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
-
-extern inline int copy_from_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_READ, from, n);
- if (i)
- return i;
- memcpy_fromfs(to, from, n);
- return 0;
-}
-
-extern inline int copy_to_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_WRITE, to, n);
- if (i)
- return i;
- memcpy_tofs(to, from, n);
- return 0;
-}
-#endif
/* --------------------------------------------------------------------- */
#include <asm/segment.h>
#include <linux/mm.h>
-#undef put_user
-#undef get_user
-
-#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
-#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
-
extern inline int copy_from_user(void *to, const void *from, unsigned long n)
{
int i = verify_area(VERIFY_READ, from, n);
/* --------------------------------------------------------------------- */
-/*
- * currently this module is supposed to support both module styles, i.e.
- * the old one present up to about 2.1.9, and the new one functioning
- * starting with 2.1.21. The reason is I have a kit allowing to compile
- * this module also under 2.0.x which was requested by several people.
- * This will go in 2.2
- */
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE >= 0x20100
#include <asm/uaccess.h>
-#else
-#include <asm/segment.h>
-#include <linux/mm.h>
-
-#undef put_user
-#undef get_user
-
-#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
-#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
-
-extern inline int copy_from_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_READ, from, n);
- if (i)
- return i;
- memcpy_fromfs(to, from, n);
- return 0;
-}
-
-extern inline int copy_to_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_WRITE, to, n);
- if (i)
- return i;
- memcpy_tofs(to, from, n);
- return 0;
-}
-#endif
-
-#if LINUX_VERSION_CODE < 0x20115
-extern __inline__ void dev_init_buffers(struct device *dev)
-{
- int i;
- for (i = 0; i < DEV_NUMBUFFS; i++) {
- skb_queue_head_init(&dev->buffs[i]);
- }
-}
-#endif
-
-#if LINUX_VERSION_CODE >= 0x20123
#include <linux/init.h>
-#else
-#define __init
-#define __initdata
-#define __initfunc(x) x
-#endif
/* --------------------------------------------------------------------- */
/* Stats section */
-#if LINUX_VERSION_CODE < 0x20119
- struct enet_statistics stats;
-#else
struct net_device_stats stats;
-#endif
int nb_rxint;
int nb_mdint;
/* --------------------------------------------------------------------- */
-#if LINUX_VERSION_CODE >= 0x20119
static struct net_device_stats *
yam_get_stats(struct device *dev)
-#else
-static struct enet_statistics *
- yam_get_stats(struct device *dev)
-#endif
{
struct yam_port *yp;
* command line settable parameters
*/
-#if LINUX_VERSION_CODE >= 0x20115
-
MODULE_AUTHOR("Frederic Rible F1OAT frible@teaser.fr");
MODULE_DESCRIPTION("Yam amateur radio modem driver");
-#endif
-
__initfunc(int init_module(void))
{
int ret = yam_init(NULL);
*/
static int copyin(struct openpromio *info, struct openpromio **opp_p)
{
- int bufsize;
+ unsigned int bufsize;
if (!info || !opp_p)
return -EFAULT;
copy_to_user_ret((Firm_event *)p, &kbd_queue [kbd_tail],
sizeof(Firm_event)-sizeof(struct timeval), -EFAULT);
p += sizeof(Firm_event)-sizeof(struct timeval);
- __put_user_ret(kbd_queue[kbd_tail].time.tv_sec, (u32 *)p, -EFAULT);
+ put_user_ret(kbd_queue[kbd_tail].time.tv_sec, (u32 *)p, -EFAULT);
p += sizeof(u32);
- __put_user_ret(kbd_queue[kbd_tail].time.tv_usec, (u32 *)p, -EFAULT);
+ put_user_ret(kbd_queue[kbd_tail].time.tv_usec, (u32 *)p, -EFAULT);
p += sizeof(u32);
} else
#endif
sizeof(Firm_event)-sizeof(struct timeval),
-EFAULT);
p += sizeof(Firm_event)-sizeof(struct timeval);
- __put_user_ret(q->time.tv_sec, (u32 *)p, -EFAULT);
+ put_user_ret(q->time.tv_sec, (u32 *)p, -EFAULT);
p += sizeof(u32);
- __put_user_ret(q->time.tv_usec, (u32 *)p, -EFAULT);
+ put_user_ret(q->time.tv_usec, (u32 *)p, -EFAULT);
p += sizeof(u32);
} else
#endif
#define PUT_USER put_user
#endif
- #ifndef __PUT_USER
- #define __PUT_USER __put_user
- #endif
-
#ifndef PUT_USER_RET
#define PUT_USER_RET put_user_ret
#endif
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.28"
-#define DRIVER_AUTHOR "Mark McClelland <mwm@i.am> & Bret Wallach & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha <cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
+#define DRIVER_VERSION "v1.28a for Linux 2.2"
+#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha <cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
#define DRIVER_DESC "OV511 USB Camera Driver"
#define OV511_I2C_RETRIES 3
* programs that expect RGB data (e.g. gqcam) to work with this driver. */
static int force_rgb = 0;
-/* Number of seconds before inactive buffers are deallocated */
-static int buf_timeout = 5;
-
/* Number of cameras to stream from simultaneously */
static int cams = 1;
MODULE_PARM_DESC(aperture, "Read the OV7610/7620 specs");
MODULE_PARM(force_rgb, "i");
MODULE_PARM_DESC(force_rgb, "Read RGB instead of BGR");
-MODULE_PARM(buf_timeout, "i");
-MODULE_PARM_DESC(buf_timeout, "Number of seconds before buffer deallocation");
MODULE_PARM(cams, "i");
MODULE_PARM_DESC(cams, "Number of simultaneous cameras");
MODULE_PARM(retry_sync, "i");
PDEBUG(4, "entered");
down(&ov511->buf_lock);
- if (ov511->buf_state == BUF_PEND_DEALLOC) {
- ov511->buf_state = BUF_ALLOCATED;
- del_timer(&ov511->buf_timer);
- }
-
if (ov511->buf_state == BUF_ALLOCATED)
goto out;
PDEBUG(4, "leaving");
}
-static void ov511_buf_callback(unsigned long data)
-{
- struct usb_ov511 *ov511 = (struct usb_ov511 *)data;
- PDEBUG(4, "entered");
- down(&ov511->buf_lock);
-
- if (ov511->buf_state == BUF_PEND_DEALLOC)
- ov511_do_dealloc(ov511);
-
- up(&ov511->buf_lock);
- PDEBUG(4, "leaving");
-}
-
-static void ov511_dealloc(struct usb_ov511 *ov511, int now)
+static void ov511_dealloc(struct usb_ov511 *ov511)
{
- struct timer_list *bt = &(ov511->buf_timer);
PDEBUG(4, "entered");
down(&ov511->buf_lock);
-
- PDEBUG(4, "deallocating buffer memory %s", now ? "now" : "later");
-
- if (ov511->buf_state == BUF_PEND_DEALLOC) {
- ov511->buf_state = BUF_ALLOCATED;
- del_timer(bt);
- }
-
- if (now)
- ov511_do_dealloc(ov511);
- else {
- ov511->buf_state = BUF_PEND_DEALLOC;
- init_timer(bt);
- bt->function = ov511_buf_callback;
- bt->data = (unsigned long)ov511;
- bt->expires = jiffies + buf_timeout * HZ;
- add_timer(bt);
- }
+ ov511_do_dealloc(ov511);
up(&ov511->buf_lock);
PDEBUG(4, "leaving");
}
err = ov511_init_isoc(ov511);
if (err) {
- ov511_dealloc(ov511, 0);
+ ov511_dealloc(ov511);
goto out;
}
ov511_stop_isoc(ov511);
if (ov511->dev)
- ov511_dealloc(ov511, 0);
+ ov511_dealloc(ov511);
up(&ov511->lock);
if (!ov511->dev) {
- ov511_dealloc(ov511, 1);
+ ov511_dealloc(ov511);
video_unregister_device(&ov511->vdev);
kfree(ov511);
ov511 = NULL;
/* Free the memory */
if (ov511 && !ov511->user) {
- ov511_dealloc(ov511, 1);
+ ov511_dealloc(ov511);
kfree(ov511);
ov511 = NULL;
}
enum {
BUF_NOT_ALLOCATED,
BUF_ALLOCATED,
- BUF_PEND_DEALLOC, /* ov511->buf_timer is set */
};
struct usb_device;
/* Framebuffer/sbuf management */
int buf_state;
struct semaphore buf_lock;
- struct timer_list buf_timer;
};
struct cam_list {
case MDI_GET_CFGINFO:
mdii = (struct mdi_cfginfo *)arg;
put_user_ret(FBTYPE_MDICOLOR, &mdii->mdi_type, -EFAULT);
- __put_user_ret(fb->type.fb_height, &mdii->mdi_height, -EFAULT);
- __put_user_ret(fb->type.fb_width, &mdii->mdi_width, -EFAULT);
- __put_user_ret(fb->s.cg14.mode, &mdii->mdi_mode, -EFAULT);
- __put_user_ret(72, &mdii->mdi_pixfreq, -EFAULT); /* FIXME */
- __put_user_ret(fb->s.cg14.ramsize, &mdii->mdi_size, -EFAULT);
+ put_user_ret(fb->type.fb_height, &mdii->mdi_height, -EFAULT);
+ put_user_ret(fb->type.fb_width, &mdii->mdi_width, -EFAULT);
+ put_user_ret(fb->s.cg14.mode, &mdii->mdi_mode, -EFAULT);
+ put_user_ret(72, &mdii->mdi_pixfreq, -EFAULT); /* FIXME */
+ put_user_ret(fb->s.cg14.ramsize, &mdii->mdi_size, -EFAULT);
break;
case MDI_SET_PIXELMODE:
get_user_ret(mode, (int *)arg, -EFAULT);
/*
* "buflen" should be PAGE_SIZE or more.
*/
-char * d_path(struct dentry *dentry, char *buffer, int buflen)
+static char * d_path_error(struct dentry *dentry,
+ char *buffer, int buflen, int *error)
{
char * end = buffer+buflen;
char * retval;
struct dentry * root = current->fs->root;
+ *error = 0;
+
*--end = '\0';
buflen--;
if (dentry->d_parent != dentry && list_empty(&dentry->d_hash)) {
break;
namelen = dentry->d_name.len;
buflen -= namelen + 1;
- if (buflen < 0)
+ if (buflen < 0) {
+ *error = -ENAMETOOLONG;
break;
+ }
end -= namelen;
memcpy(end, dentry->d_name.name, namelen);
*--end = '/';
return retval;
}
+char * d_path(struct dentry *dentry, char *buffer, int buflen)
+{
+ int error;
+
+ return d_path_error(dentry, buffer, buflen, &error);
+}
+
/*
* NOTE! The user-level library version returns a
* character pointer. The kernel system call just
error = -ENOMEM;
if (page) {
unsigned long len;
- char * cwd = d_path(pwd, page, PAGE_SIZE);
-
- error = -ERANGE;
- len = PAGE_SIZE + page - cwd;
- if (len <= size) {
- error = len;
- if (copy_to_user(buf, cwd, len))
- error = -EFAULT;
+ char * cwd;
+
+ cwd = d_path_error(pwd, page, PAGE_SIZE, &error);
+ if (!error) {
+ error = -ERANGE;
+ len = PAGE_SIZE + page - cwd;
+ if (len <= size) {
+ error = len;
+ if (copy_to_user(buf, cwd, len))
+ error = -EFAULT;
+ }
}
free_page((unsigned long) page);
}
int fat_parent_ino(struct inode *dir,int locked)
{
static int zero = 0;
- int error,curr,prev,nr;
+ int error,curr,prev;
+ loff_t nr;
PRINTK(("fat_parent_ino: Debug 0\n"));
if (!S_ISDIR(dir->i_mode)) panic("Non-directory fed to m_p_i");
if (!locked) fat_unlock_creation();
return error;
}
- PRINTK(("fat_parent_ino: Debug 6 nr=%d\n", nr));
+ PRINTK(("fat_parent_ino: Debug 6 nr=%ld\n", (long)nr));
}
if (!locked) fat_unlock_creation();
return nr;
/* If a minor device was explicitly opened, set session to the
* minor number. For instance, if /dev/hdc1 is mounted, session
* 1 on the CD-ROM is selected. CD_PART_MAX gives access to
- * a max of 64 sessions on IDE. SCSI drives must still use
- * the session option to mount.
+ * a max of 64 sessions on IDE. For SCSI drives or loop devices
+ * you must still use the session option to mount.
*/
- if ((MINOR(dev) % CD_PART_MAX) && (MAJOR(dev) != SCSI_CDROM_MAJOR))
+ if ((MINOR(dev) % CD_PART_MAX) && (MAJOR(dev) != SCSI_CDROM_MAJOR)
+ && (MAJOR(dev) != LOOP_MAJOR))
session = MINOR(dev) % CD_PART_MAX;
if (session > 0 && session <= CD_PART_MAX) {
struct cdrom_tocentry entry;
{
struct inode *inode = file->f_dentry->d_inode;
char buffer[10];
-
+
if (count < 0 || !inode->u.generic_ip)
return -EINVAL;
sprintf (buffer, "%8.8x\n", (u32)(long)(inode->u.generic_ip));
return 0;
if (count > 9 - file->f_pos)
count = 9 - file->f_pos;
- copy_to_user(buf, buffer + file->f_pos, count);
+ copy_to_user_ret(buf, buffer + file->f_pos, count, -EFAULT);
file->f_pos += count;
return count;
}
u32 *q;
openprom_property *op;
char buffer[64];
-
- if (filp->f_pos >= 0xffffff)
+
+ if (filp->f_pos >= 0xffffff || count >= 0xffffff)
return -EINVAL;
if (!filp->private_data) {
node = nodes[(u16)((long)inode->u.generic_ip)].node;
if (count > i - k) count = i - k;
if (op->flag & OPP_STRING) {
if (!k) {
- __put_user('\'', buf);
+ put_user_ret('\'', buf, -EFAULT);
k++;
count--;
}
j = count;
if (j >= 0) {
- copy_to_user(buf + k - filp->f_pos,
- op->value + k - 1, j);
+ copy_to_user_ret(buf + k - filp->f_pos,
+ op->value + k - 1, j, -EFAULT);
count -= j;
k += j;
}
if (count)
- __put_user('\'', &buf [k++ - filp->f_pos]);
+ put_user_ret('\'', &buf [k++ - filp->f_pos], -EFAULT);
if (count > 1)
- __put_user('\n', &buf [k++ - filp->f_pos]);
+ put_user_ret('\n', &buf [k++ - filp->f_pos], -EFAULT);
} else if (op->flag & OPP_STRINGLIST) {
char *tmp;
}
strcpy(s, "'\n");
- copy_to_user(buf, tmp + k, count);
+ copy_to_user_ret(buf, tmp + k, count, -EFAULT);
kfree(tmp);
k += count;
if (first == last) {
sprintf (buffer, "%08x.", *first);
- copy_to_user (buf, buffer + first_off, last_cnt - first_off);
+ copy_to_user_ret (buf, buffer + first_off,
+ last_cnt - first_off, -EFAULT);
buf += last_cnt - first_off;
} else {
for (q = first; q <= last; q++) {
sprintf (buffer, "%08x.", *q);
if (q == first) {
- copy_to_user (buf, buffer + first_off,
- 9 - first_off);
+ copy_to_user_ret (buf,
+ buffer + first_off,
+ 9 - first_off, -EFAULT);
buf += 9 - first_off;
} else if (q == last) {
- copy_to_user (buf, buffer, last_cnt);
+ copy_to_user_ret (buf, buffer,
+ last_cnt, -EFAULT);
buf += last_cnt;
} else {
- copy_to_user (buf, buffer, 9);
+ copy_to_user_ret (buf, buffer,
+ 9, -EFAULT);
buf += 9;
}
}
}
if (last == (u32 *)(op->value + op->len - 4) && last_cnt == 9)
- __put_user('\n', (buf - 1));
+ put_user_ret('\n', (buf - 1), -EFAULT);
k += count;
} else if (op->flag & OPP_HEXSTRING) {
- char buffer[2];
+ char buffer[3];
if ((k < i - 1) && (k & 1)) {
- sprintf (buffer, "%02x", *(op->value + (k >> 1)));
- __put_user(buffer[1], &buf[k++ - filp->f_pos]);
+ sprintf (buffer, "%02x",
+ (unsigned char)*(op->value + (k >> 1)) & 0xff);
+ put_user_ret(buffer[1], &buf[k++ - filp->f_pos],
+ -EFAULT);
count--;
}
for (; (count > 1) && (k < i - 1); k += 2) {
- sprintf (buffer, "%02x", *(op->value + (k >> 1)));
- copy_to_user (buf + k - filp->f_pos, buffer, 2);
+ sprintf (buffer, "%02x",
+ (unsigned char)*(op->value + (k >> 1)) & 0xff);
+ copy_to_user_ret (buf + k - filp->f_pos, buffer, 2,
+ -EFAULT);
count -= 2;
}
if (count && (k < i - 1)) {
- sprintf (buffer, "%02x", *(op->value + (k >> 1)));
- __put_user(buffer[0], &buf[k++ - filp->f_pos]);
+ sprintf (buffer, "%02x",
+ (unsigned char)*(op->value + (k >> 1)) & 0xff);
+ put_user_ret(buffer[0], &buf[k++ - filp->f_pos],
+ -EFAULT);
count--;
}
if (count)
- __put_user('\n', &buf [k++ - filp->f_pos]);
+ put_user_ret('\n', &buf [k++ - filp->f_pos], -EFAULT);
}
count = k - filp->f_pos;
filp->f_pos = k;
u32 *q;
void *b;
openprom_property *op;
-
- if (filp->f_pos >= 0xffffff)
+
+ if (filp->f_pos >= 0xffffff || count >= 0xffffff)
return -EINVAL;
if (!filp->private_data) {
i = property_read (filp, NULL, 0, 0);
if (j == 9) j = 0;
if (!j) {
char ctmp;
- __get_user(ctmp, &buf[i]);
+ get_user_ret(ctmp, &buf[i], -EFAULT);
if (ctmp != '.') {
if (ctmp != '\n') {
if (op->flag & OPP_BINARY)
}
} else {
char ctmp;
- __get_user(ctmp, &buf[i]);
+ get_user_ret(ctmp, &buf[i], -EFAULT);
if (ctmp < '0' ||
(ctmp > '9' && ctmp < 'A') ||
(ctmp > 'F' && ctmp < 'a') ||
last_cnt = (k + count) % 9;
if (first + 1 == last) {
memset (tmp, '0', 8);
- copy_from_user (tmp + first_off, buf,
- (count + first_off > 8) ? 8 - first_off : count);
+ copy_from_user_ret (tmp + first_off, buf,
+ (count + first_off > 8) ? 8 - first_off : count,
+ -EFAULT);
mask = 0xffffffff;
mask2 = 0xffffffff;
for (j = 0; j < first_off; j++)
if (q == first) {
if (first_off < 8) {
memset (tmp, '0', 8);
- copy_from_user (tmp + first_off, buf,
- 8 - first_off);
+ copy_from_user_ret (
+ tmp + first_off, buf,
+ 8 - first_off, -EFAULT);
mask = 0xffffffff;
for (j = 0; j < first_off; j++)
mask >>= 1;
} else if ((q == last - 1) && last_cnt
&& (last_cnt < 8)) {
memset (tmp, '0', 8);
- copy_from_user (tmp, buf, last_cnt);
+ copy_from_user_ret (tmp, buf, last_cnt,
+ -EFAULT);
mask = 0xffffffff;
for (j = 0; j < 8 - last_cnt; j++)
mask <<= 1;
} else {
char tchars[17]; /* XXX yuck... */
- copy_from_user(tchars, buf, 16);
+ copy_from_user_ret(tchars, buf, 16,
+ -EFAULT);
*q = simple_strtoul (tchars, 0, 16);
buf += 9;
}
*/
if (k > 0)
return -EINVAL;
- __get_user(ctmp, buf);
+ get_user_ret(ctmp, buf, -EFAULT);
if (ctmp == '\'') {
op->flag |= OPP_QUOTED;
buf++;
kfree (b);
}
p = op->value + filp->f_pos - ((op->flag & OPP_QUOTED) ? 1 : 0);
- copy_from_user (p, buf, count);
+ copy_from_user_ret (p, buf, count, -EFAULT);
op->flag |= OPP_DIRTY;
for (i = 0; i < count; i++, p++)
if (*p == '\n') {
goto nohead;
/* Get the DATA. Size must match skb_add_mtu(). */
+ if (size > 131072 - 32)
+ goto nodata;
size = ((size + 15) & ~15);
data = kmalloc(size + sizeof(atomic_t), gfp_mask);
if (data == NULL)
struct ip_masq_ctl masq_ctl;
int ret = -EINVAL;
- if(optlen>sizeof(masq_ctl))
+ if(optlen < 0 || optlen > sizeof(masq_ctl))
return -EINVAL;
if(copy_from_user(&masq_ctl,optval,optlen))
static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
int length, int *eof, void *data)
{
- *start=buffer;
+ *start = buffer;
- if (offset + length > sizeof(ip_rt_acct)) {
+ if (offset < 0 || length < 0)
+ return 0;
+
+ if (offset >= sizeof(ip_rt_acct) || length >= sizeof(ip_rt_acct)) {
+ *eof = 1;
+ return 0;
+ }
+
+ if (offset + length >= sizeof(ip_rt_acct)) {
length = sizeof(ip_rt_acct) - offset;
*eof = 1;
}
if (length > 0) {
start_bh_atomic();
- memcpy(buffer, ((u8*)&ip_rt_acct)+offset, length);
+ memcpy(buffer, ((u8*)&ip_rt_acct) + offset, length);
end_bh_atomic();
return length;
}
if (!err)
tcp_push_pending_frames(sk, tp);
wait_for_tcp_memory(sk, err);
+ err = 0;
/* If SACK's were formed or PMTU events happened,
* we must find out about it.
}
sk->shutdown = SHUTDOWN_MASK;
if (!sk->dead)
- sk->state_change(sk);
+ sk->error_report(sk);
}
/* This tags the retransmission queue when SACKs arrive. */
asmlinkage int sys_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
{
int err;
+ int len;
struct socket *sock;
lock_kernel();
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
+ /* XXX: insufficient for SMP, but should be redundant anyway */
+ if (get_user(len, optlen))
+ err = -EFAULT;
+ else
+ if (len < 0)
+ err = -EINVAL;
+ else
if (level == SOL_SOCKET)
err=sock_getsockopt(sock,level,optname,optval,optlen);
else
return NULL;
}
u=unix_find_socket_byinode(dentry->d_inode);
+ if (u && u->type == type)
+ UPDATE_ATIME(dentry->d_inode);
dput(dentry);
if (u && u->type != type)
{
}
}
else
+ {
u=unix_find_socket_byname(sunname, len, type, hash);
+ if (u)
+ {
+ struct dentry *dentry;
+ dentry = u->protinfo.af_unix.dentry;
+ if (dentry)
+ UPDATE_ATIME(dentry->d_inode);
+ }
+ }
if (u==NULL)
{