Commit c87d0278 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.12

parent 86ae3b2a
...@@ -163,17 +163,15 @@ ssize_t parport_device_id (int devnum, char *buffer, size_t len) ...@@ -163,17 +163,15 @@ ssize_t parport_device_id (int devnum, char *buffer, size_t len)
len = idlen; len = idlen;
retval = parport_read (dev->port, buffer, len); retval = parport_read (dev->port, buffer, len);
if (retval != len) { if (retval != len)
printk (KERN_DEBUG "%s: only read %d of %d ID bytes\n", printk (KERN_DEBUG "%s: only read %d of %d ID bytes\n",
dev->port->name, retval, len); dev->port->name, retval, len);
goto restore_fs;
}
/* Some printer manufacturers mistakenly believe that /* Some printer manufacturers mistakenly believe that
the length field is supposed to be _exclusive_. */ the length field is supposed to be _exclusive_. */
/* In addition, there are broken devices out there /* In addition, there are broken devices out there
that don't even finish off with a semi-colon. */ that don't even finish off with a semi-colon. */
if (idlen == len && buffer[len - 1] != ';') { if (buffer[len - 1] != ';') {
ssize_t diff; ssize_t diff;
diff = parport_read (dev->port, buffer + len, 2); diff = parport_read (dev->port, buffer + len, 2);
retval += diff; retval += diff;
...@@ -186,7 +184,6 @@ ssize_t parport_device_id (int devnum, char *buffer, size_t len) ...@@ -186,7 +184,6 @@ ssize_t parport_device_id (int devnum, char *buffer, size_t len)
else { else {
/* One semi-colon short of a device ID. */ /* One semi-colon short of a device ID. */
buffer[len++] = ';'; buffer[len++] = ';';
buffer[len] = '\0';
printk (KERN_DEBUG "%s: faking semi-colon\n", printk (KERN_DEBUG "%s: faking semi-colon\n",
dev->port->name); dev->port->name);
...@@ -199,12 +196,13 @@ ssize_t parport_device_id (int devnum, char *buffer, size_t len) ...@@ -199,12 +196,13 @@ ssize_t parport_device_id (int devnum, char *buffer, size_t len)
} }
restore_fs: restore_fs:
buffer[len] = '\0';
set_fs (oldfs); set_fs (oldfs);
parport_negotiate (dev->port, IEEE1284_MODE_COMPAT); parport_negotiate (dev->port, IEEE1284_MODE_COMPAT);
} }
parport_release (dev); parport_release (dev);
if (retval > 0) if (retval > 2)
parse_data (dev->port, dev->daisy, buffer); parse_data (dev->port, dev->daisy, buffer);
parport_close (dev); parport_close (dev);
......
...@@ -268,8 +268,8 @@ sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp) ...@@ -268,8 +268,8 @@ sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
if (n < 0) if (n < 0)
goto out_nofds; goto out_nofds;
if (n > current->files->max_fdset + 1) if (n > current->files->max_fdset)
n = current->files->max_fdset + 1; n = current->files->max_fdset;
/* /*
* We need 6 bitmaps (in/out/ex for both incoming and outgoing), * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
...@@ -277,7 +277,7 @@ sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp) ...@@ -277,7 +277,7 @@ sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
* long-words. * long-words.
*/ */
ret = -ENOMEM; ret = -ENOMEM;
size = (n + 8 * sizeof(long) - 1) / (8 * sizeof(long)) * sizeof(long); size = FDS_BYTES(n);
bits = kmalloc(6 * size, GFP_KERNEL); bits = kmalloc(6 * size, GFP_KERNEL);
if (!bits) if (!bits)
goto out_nofds; goto out_nofds;
......
...@@ -180,12 +180,12 @@ typedef struct sigaltstack { ...@@ -180,12 +180,12 @@ typedef struct sigaltstack {
extern __inline__ void sigaddset(sigset_t *set, int _sig) extern __inline__ void sigaddset(sigset_t *set, int _sig)
{ {
__asm__("btsl %1,%0" : "=m"(*set) : "ir"(_sig - 1) : "cc"); __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
} }
extern __inline__ void sigdelset(sigset_t *set, int _sig) extern __inline__ void sigdelset(sigset_t *set, int _sig)
{ {
__asm__("btrl %1,%0" : "=m"(*set) : "ir"(_sig - 1) : "cc"); __asm__("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
} }
extern __inline__ int __const_sigismember(sigset_t *set, int _sig) extern __inline__ int __const_sigismember(sigset_t *set, int _sig)
...@@ -198,7 +198,7 @@ extern __inline__ int __gen_sigismember(sigset_t *set, int _sig) ...@@ -198,7 +198,7 @@ extern __inline__ int __gen_sigismember(sigset_t *set, int _sig)
{ {
int ret; int ret;
__asm__("btl %2,%1\n\tsbbl %0,%0" __asm__("btl %2,%1\n\tsbbl %0,%0"
: "=r"(ret) : "m"(*set), "ir"(_sig-1) : "cc"); : "=r"(ret) : "m"(*set), "Ir"(_sig-1) : "cc");
return ret; return ret;
} }
......
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
* increased. The larger it is, though, the longer it will be between * increased. The larger it is, though, the longer it will be between
* necessary transmits - don't set this too large. * necessary transmits - don't set this too large.
*/ */
#define TX_TIMEOUT 20 #define TX_TIMEOUT (20*HZ/100)
/* Display warnings about the driver being an ALPHA version. /* Display warnings about the driver being an ALPHA version.
......
...@@ -35,6 +35,7 @@ extern unsigned long event; ...@@ -35,6 +35,7 @@ extern unsigned long event;
#define CLONE_PID 0x00001000 /* set if pid shared */ #define CLONE_PID 0x00001000 /* set if pid shared */
#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
/* /*
* These are the constant used to fake the fixed-point load-average * These are the constant used to fake the fixed-point load-average
......
...@@ -637,6 +637,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) ...@@ -637,6 +637,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
p->run_list.next = NULL; p->run_list.next = NULL;
p->run_list.prev = NULL; p->run_list.prev = NULL;
if ((clone_flags & CLONE_VFORK) || !(clone_flags & CLONE_PARENT))
p->p_pptr = p->p_opptr = current; p->p_pptr = p->p_opptr = current;
p->p_cptr = NULL; p->p_cptr = NULL;
init_waitqueue_head(&p->wait_chldexit); init_waitqueue_head(&p->wait_chldexit);
......
...@@ -475,19 +475,23 @@ int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t len) ...@@ -475,19 +475,23 @@ int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t len)
if (!vma) if (!vma)
goto out_unlock; goto out_unlock;
} }
if (!handle_mm_fault(current, vma, ptr, (rw==READ))) if (handle_mm_fault(current, vma, ptr, (rw==READ)) <= 0)
goto out_unlock; goto out_unlock;
spin_lock(&mm->page_table_lock);
page = follow_page(ptr); page = follow_page(ptr);
if (!page) { if (!page) {
printk (KERN_ERR "Missing page in map_user_kiobuf\n"); dprintk (KERN_ERR "Missing page in map_user_kiobuf\n");
goto out_unlock; map = NULL;
goto retry;
} }
map = get_page_map(page); map = get_page_map(page);
if (map) { if (map) {
if (TryLockPage(map)) if (TryLockPage(map)) {
goto retry; goto retry;
}
atomic_inc(&map->count); atomic_inc(&map->count);
} }
spin_unlock(&mm->page_table_lock);
dprintk ("Installing page %p %p: %d\n", (void *)page, map, i); dprintk ("Installing page %p %p: %d\n", (void *)page, map, i);
iobuf->pagelist[i] = page; iobuf->pagelist[i] = page;
iobuf->maplist[i] = map; iobuf->maplist[i] = map;
...@@ -511,17 +515,20 @@ int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t len) ...@@ -511,17 +515,20 @@ int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t len)
/* /*
* Undo the locking so far, wait on the page we got to, and try again. * Undo the locking so far, wait on the page we got to, and try again.
*/ */
spin_unlock(&mm->page_table_lock);
unmap_kiobuf(iobuf); unmap_kiobuf(iobuf);
up(&mm->mmap_sem); up(&mm->mmap_sem);
/* /*
* Did the release also unlock the page we got stuck on? * Did the release also unlock the page we got stuck on?
*/ */
if (map) {
if (!PageLocked(map)) { if (!PageLocked(map)) {
/* If so, we may well have the page mapped twice in the /* If so, we may well have the page mapped twice
* IO address range. Bad news. Of course, it _might_ * in the IO address range. Bad news. Of
* just be a coincidence, but if it happens more than * course, it _might_ * just be a coincidence,
* once, chances are we have a double-mapped page. */ * but if it happens more than * once, chances
* are we have a double-mapped page. */
if (++doublepage >= 3) { if (++doublepage >= 3) {
return -EINVAL; return -EINVAL;
} }
...@@ -531,6 +538,8 @@ int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t len) ...@@ -531,6 +538,8 @@ int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t len)
* Try again... * Try again...
*/ */
wait_on_page(map); wait_on_page(map);
}
if (++repeat < 16) if (++repeat < 16)
goto repeat; goto repeat;
return -EAGAIN; return -EAGAIN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment