Merge of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/tg3-2.6
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index e4f1615..7329ef1 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -619,7 +619,7 @@
_GLOBAL(flush_icache_range)
BEGIN_FTR_SECTION
blr /* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
li r5,L1_CACHE_LINE_SIZE-1
andc r3,r3,r5
subf r4,r3,r4
@@ -736,7 +736,7 @@
_GLOBAL(__flush_dcache_icache)
BEGIN_FTR_SECTION
blr /* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
rlwinm r3,r3,0,0,19 /* Get page base address */
li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */
mtctr r4
@@ -764,7 +764,7 @@
_GLOBAL(__flush_dcache_icache_phys)
BEGIN_FTR_SECTION
blr /* for 601, do nothing */
-END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE)
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
mfmsr r10
rlwinm r0,r10,0,28,26 /* clear DR */
mtmsr r0
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 7a24506..f022f09 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1995,9 +1995,6 @@
unsigned char ch, gdl;
int ignored = 0;
int cnt = 0;
- unsigned char *cp;
- char *fp;
- int count;
int recv_room;
int max = 256;
unsigned long flags;
@@ -2011,10 +2008,6 @@
//return;
}
- cp = tty->flip.char_buf;
- fp = tty->flip.flag_buf;
- count = 0;
-
// following add by Victor Yu. 09-02-2002
if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {
@@ -2041,12 +2034,10 @@
}
while (gdl--) {
ch = inb(info->base + UART_RX);
- count++;
- *cp++ = ch;
- *fp++ = 0;
+ tty_insert_flip_char(tty, ch, 0);
cnt++;
/*
- if((count>=HI_WATER) && (info->stop_rx==0)){
+ if((cnt>=HI_WATER) && (info->stop_rx==0)){
mxser_stoprx(tty);
info->stop_rx=1;
break;
@@ -2061,7 +2052,7 @@
if (max-- < 0)
break;
/*
- if((count>=HI_WATER) && (info->stop_rx==0)){
+ if((cnt>=HI_WATER) && (info->stop_rx==0)){
mxser_stoprx(tty);
info->stop_rx=1;
break;
@@ -2078,36 +2069,33 @@
if (++ignored > 100)
break;
} else {
- count++;
+ char flag = 0;
if (*status & UART_LSR_SPECIAL) {
if (*status & UART_LSR_BI) {
- *fp++ = TTY_BREAK;
+ flag = TTY_BREAK;
/* added by casper 1/11/2000 */
info->icount.brk++;
-
/* */
if (info->flags & ASYNC_SAK)
do_SAK(tty);
} else if (*status & UART_LSR_PE) {
- *fp++ = TTY_PARITY;
+ flag = TTY_PARITY;
/* added by casper 1/11/2000 */
info->icount.parity++;
/* */
} else if (*status & UART_LSR_FE) {
- *fp++ = TTY_FRAME;
+ flag = TTY_FRAME;
/* added by casper 1/11/2000 */
info->icount.frame++;
/* */
} else if (*status & UART_LSR_OE) {
- *fp++ = TTY_OVERRUN;
+ flag = TTY_OVERRUN;
/* added by casper 1/11/2000 */
info->icount.overrun++;
/* */
- } else
- *fp++ = 0;
- } else
- *fp++ = 0;
- *cp++ = ch;
+ }
+ }
+ tty_insert_flip_char(tty, ch, flag);
cnt++;
if (cnt >= recv_room) {
if (!info->ldisc_stop_rx) {
@@ -2132,13 +2120,13 @@
// above add by Victor Yu. 09-02-2002
} while (*status & UART_LSR_DR);
- end_intr: // add by Victor Yu. 09-02-2002
+end_intr: // add by Victor Yu. 09-02-2002
mxvar_log.rxcnt[info->port] += cnt;
info->mon_data.rxcnt += cnt;
info->mon_data.up_rxcnt += cnt;
spin_unlock_irqrestore(&info->slock, flags);
-
+
tty_flip_buffer_push(tty);
}
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index f0cd67d..c8998dc 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -520,7 +520,7 @@
DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
down_write(¤t->mm->mmap_sem);
- textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0);
+ textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 0);
up_write(¤t->mm->mmap_sem);
if (!textpos || textpos >= (unsigned long) -4096) {
if (!textpos)
@@ -532,7 +532,7 @@
down_write(¤t->mm->mmap_sem);
realdatastart = do_mmap(0, 0, data_len + extra +
MAX_SHARED_LIBS * sizeof(unsigned long),
- PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0);
+ PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
up_write(¤t->mm->mmap_sem);
if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -574,7 +574,7 @@
down_write(¤t->mm->mmap_sem);
textpos = do_mmap(0, 0, text_len + data_len + extra +
MAX_SHARED_LIBS * sizeof(unsigned long),
- PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0);
+ PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
up_write(¤t->mm->mmap_sem);
if (!textpos || textpos >= (unsigned long) -4096) {
if (!textpos)
diff --git a/fs/namei.c b/fs/namei.c
index dd78f01..a7f7f44 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -493,12 +493,21 @@
return PTR_ERR(link);
}
-static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
+struct path {
+ struct vfsmount *mnt;
+ struct dentry *dentry;
+};
+
+static inline int __do_follow_link(struct path *path, struct nameidata *nd)
{
int error;
+ struct dentry *dentry = path->dentry;
- touch_atime(nd->mnt, dentry);
+ touch_atime(path->mnt, dentry);
nd_set_link(nd, NULL);
+
+ if (path->mnt == nd->mnt)
+ mntget(path->mnt);
error = dentry->d_inode->i_op->follow_link(dentry, nd);
if (!error) {
char *s = nd_get_link(nd);
@@ -507,6 +516,8 @@
if (dentry->d_inode->i_op->put_link)
dentry->d_inode->i_op->put_link(dentry, nd);
}
+ dput(dentry);
+ mntput(path->mnt);
return error;
}
@@ -518,7 +529,7 @@
* Without that kind of total limit, nasty chains of consecutive
* symlinks can cause almost arbitrarily long lookups.
*/
-static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
+static inline int do_follow_link(struct path *path, struct nameidata *nd)
{
int err = -ELOOP;
if (current->link_count >= MAX_NESTED_LINKS)
@@ -527,17 +538,20 @@
goto loop;
BUG_ON(nd->depth >= MAX_NESTED_LINKS);
cond_resched();
- err = security_inode_follow_link(dentry, nd);
+ err = security_inode_follow_link(path->dentry, nd);
if (err)
goto loop;
current->link_count++;
current->total_link_count++;
nd->depth++;
- err = __do_follow_link(dentry, nd);
+ err = __do_follow_link(path, nd);
current->link_count--;
nd->depth--;
return err;
loop:
+ dput(path->dentry);
+ if (path->mnt != nd->mnt)
+ mntput(path->mnt);
path_release(nd);
return err;
}
@@ -565,87 +579,91 @@
/* no need for dcache_lock, as serialization is taken care in
* namespace.c
*/
-static int follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+static int __follow_mount(struct path *path)
{
int res = 0;
- while (d_mountpoint(*dentry)) {
- struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
+ while (d_mountpoint(path->dentry)) {
+ struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry);
if (!mounted)
break;
- mntput(*mnt);
- *mnt = mounted;
- dput(*dentry);
- *dentry = dget(mounted->mnt_root);
+ dput(path->dentry);
+ if (res)
+ mntput(path->mnt);
+ path->mnt = mounted;
+ path->dentry = dget(mounted->mnt_root);
res = 1;
}
return res;
}
+static void follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+{
+ while (d_mountpoint(*dentry)) {
+ struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
+ if (!mounted)
+ break;
+ dput(*dentry);
+ mntput(*mnt);
+ *mnt = mounted;
+ *dentry = dget(mounted->mnt_root);
+ }
+}
+
/* no need for dcache_lock, as serialization is taken care in
* namespace.c
*/
-static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
+int follow_down(struct vfsmount **mnt, struct dentry **dentry)
{
struct vfsmount *mounted;
mounted = lookup_mnt(*mnt, *dentry);
if (mounted) {
+ dput(*dentry);
mntput(*mnt);
*mnt = mounted;
- dput(*dentry);
*dentry = dget(mounted->mnt_root);
return 1;
}
return 0;
}
-int follow_down(struct vfsmount **mnt, struct dentry **dentry)
-{
- return __follow_down(mnt,dentry);
-}
-
-static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
+static inline void follow_dotdot(struct nameidata *nd)
{
while(1) {
struct vfsmount *parent;
- struct dentry *old = *dentry;
+ struct dentry *old = nd->dentry;
read_lock(¤t->fs->lock);
- if (*dentry == current->fs->root &&
- *mnt == current->fs->rootmnt) {
+ if (nd->dentry == current->fs->root &&
+ nd->mnt == current->fs->rootmnt) {
read_unlock(¤t->fs->lock);
break;
}
read_unlock(¤t->fs->lock);
spin_lock(&dcache_lock);
- if (*dentry != (*mnt)->mnt_root) {
- *dentry = dget((*dentry)->d_parent);
+ if (nd->dentry != nd->mnt->mnt_root) {
+ nd->dentry = dget(nd->dentry->d_parent);
spin_unlock(&dcache_lock);
dput(old);
break;
}
spin_unlock(&dcache_lock);
spin_lock(&vfsmount_lock);
- parent = (*mnt)->mnt_parent;
- if (parent == *mnt) {
+ parent = nd->mnt->mnt_parent;
+ if (parent == nd->mnt) {
spin_unlock(&vfsmount_lock);
break;
}
mntget(parent);
- *dentry = dget((*mnt)->mnt_mountpoint);
+ nd->dentry = dget(nd->mnt->mnt_mountpoint);
spin_unlock(&vfsmount_lock);
dput(old);
- mntput(*mnt);
- *mnt = parent;
+ mntput(nd->mnt);
+ nd->mnt = parent;
}
- follow_mount(mnt, dentry);
+ follow_mount(&nd->mnt, &nd->dentry);
}
-struct path {
- struct vfsmount *mnt;
- struct dentry *dentry;
-};
-
/*
* It's more convoluted than I'd like it to be, but... it's still fairly
* small and for now I'd prefer to have fast path as straight as possible.
@@ -664,6 +682,7 @@
done:
path->mnt = mnt;
path->dentry = dentry;
+ __follow_mount(path);
return 0;
need_lookup:
@@ -751,7 +770,7 @@
case 2:
if (this.name[1] != '.')
break;
- follow_dotdot(&nd->mnt, &nd->dentry);
+ follow_dotdot(nd);
inode = nd->dentry->d_inode;
/* fallthrough */
case 1:
@@ -771,8 +790,6 @@
err = do_lookup(nd, &this, &next);
if (err)
break;
- /* Check mountpoints.. */
- follow_mount(&next.mnt, &next.dentry);
err = -ENOENT;
inode = next.dentry->d_inode;
@@ -783,10 +800,7 @@
goto out_dput;
if (inode->i_op->follow_link) {
- mntget(next.mnt);
- err = do_follow_link(next.dentry, nd);
- dput(next.dentry);
- mntput(next.mnt);
+ err = do_follow_link(&next, nd);
if (err)
goto return_err;
err = -ENOENT;
@@ -798,6 +812,8 @@
break;
} else {
dput(nd->dentry);
+ if (nd->mnt != next.mnt)
+ mntput(nd->mnt);
nd->mnt = next.mnt;
nd->dentry = next.dentry;
}
@@ -819,7 +835,7 @@
case 2:
if (this.name[1] != '.')
break;
- follow_dotdot(&nd->mnt, &nd->dentry);
+ follow_dotdot(nd);
inode = nd->dentry->d_inode;
/* fallthrough */
case 1:
@@ -833,19 +849,17 @@
err = do_lookup(nd, &this, &next);
if (err)
break;
- follow_mount(&next.mnt, &next.dentry);
inode = next.dentry->d_inode;
if ((lookup_flags & LOOKUP_FOLLOW)
&& inode && inode->i_op && inode->i_op->follow_link) {
- mntget(next.mnt);
- err = do_follow_link(next.dentry, nd);
- dput(next.dentry);
- mntput(next.mnt);
+ err = do_follow_link(&next, nd);
if (err)
goto return_err;
inode = nd->dentry->d_inode;
} else {
dput(nd->dentry);
+ if (nd->mnt != next.mnt)
+ mntput(nd->mnt);
nd->mnt = next.mnt;
nd->dentry = next.dentry;
}
@@ -885,6 +899,8 @@
return 0;
out_dput:
dput(next.dentry);
+ if (nd->mnt != next.mnt)
+ mntput(next.mnt);
break;
}
path_release(nd);
@@ -1398,7 +1414,7 @@
int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
{
int acc_mode, error = 0;
- struct dentry *dentry;
+ struct path path;
struct dentry *dir;
int count = 0;
@@ -1442,23 +1458,24 @@
dir = nd->dentry;
nd->flags &= ~LOOKUP_PARENT;
down(&dir->d_inode->i_sem);
- dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+ path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+ path.mnt = nd->mnt;
do_last:
- error = PTR_ERR(dentry);
- if (IS_ERR(dentry)) {
+ error = PTR_ERR(path.dentry);
+ if (IS_ERR(path.dentry)) {
up(&dir->d_inode->i_sem);
goto exit;
}
/* Negative dentry, just create the file */
- if (!dentry->d_inode) {
+ if (!path.dentry->d_inode) {
if (!IS_POSIXACL(dir->d_inode))
mode &= ~current->fs->umask;
- error = vfs_create(dir->d_inode, dentry, mode, nd);
+ error = vfs_create(dir->d_inode, path.dentry, mode, nd);
up(&dir->d_inode->i_sem);
dput(nd->dentry);
- nd->dentry = dentry;
+ nd->dentry = path.dentry;
if (error)
goto exit;
/* Don't check for write permission, don't truncate */
@@ -1476,22 +1493,24 @@
if (flag & O_EXCL)
goto exit_dput;
- if (d_mountpoint(dentry)) {
+ if (__follow_mount(&path)) {
error = -ELOOP;
if (flag & O_NOFOLLOW)
goto exit_dput;
- while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
}
error = -ENOENT;
- if (!dentry->d_inode)
+ if (!path.dentry->d_inode)
goto exit_dput;
- if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
+ if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link)
goto do_link;
dput(nd->dentry);
- nd->dentry = dentry;
+ nd->dentry = path.dentry;
+ if (nd->mnt != path.mnt)
+ mntput(nd->mnt);
+ nd->mnt = path.mnt;
error = -EISDIR;
- if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
+ if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode))
goto exit;
ok:
error = may_open(nd, acc_mode, flag);
@@ -1500,7 +1519,9 @@
return 0;
exit_dput:
- dput(dentry);
+ dput(path.dentry);
+ if (nd->mnt != path.mnt)
+ mntput(path.mnt);
exit:
path_release(nd);
return error;
@@ -1520,18 +1541,15 @@
* are done. Procfs-like symlinks just set LAST_BIND.
*/
nd->flags |= LOOKUP_PARENT;
- error = security_inode_follow_link(dentry, nd);
+ error = security_inode_follow_link(path.dentry, nd);
if (error)
goto exit_dput;
- error = __do_follow_link(dentry, nd);
- dput(dentry);
+ error = __do_follow_link(&path, nd);
if (error)
return error;
nd->flags &= ~LOOKUP_PARENT;
- if (nd->last_type == LAST_BIND) {
- dentry = nd->dentry;
+ if (nd->last_type == LAST_BIND)
goto ok;
- }
error = -EISDIR;
if (nd->last_type != LAST_NORM)
goto exit;
@@ -1546,7 +1564,8 @@
}
dir = nd->dentry;
down(&dir->d_inode->i_sem);
- dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+ path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
+ path.mnt = nd->mnt;
putname(nd->last.name);
goto do_last;
}
diff --git a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h
index 82431ed..1ec8a34 100644
--- a/include/asm-h8300/kmap_types.h
+++ b/include/asm-h8300/kmap_types.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
+#ifndef _ASM_H8300_KMAP_TYPES_H
+#define _ASM_H8300_KMAP_TYPES_H
enum km_type {
KM_BOUNCE_READ,
@@ -13,6 +13,8 @@
KM_PTE1,
KM_IRQ0,
KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
KM_TYPE_NR
};
diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h
index abe0885..63f727a 100644
--- a/include/asm-h8300/mman.h
+++ b/include/asm-h8300/mman.h
@@ -4,6 +4,7 @@
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
+#define PROT_SEM 0x8 /* page may be used for atomic ops */
#define PROT_NONE 0x0 /* page can not be accessed */
#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */
#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */
@@ -19,6 +20,8 @@
#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
#define MAP_LOCKED 0x2000 /* pages are locked */
#define MAP_NORESERVE 0x4000 /* don't check for reservations */
+#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x10000 /* do not block on IO */
#define MS_ASYNC 1 /* sync memory asynchronously */
#define MS_INVALIDATE 2 /* invalidate the caches */
diff --git a/mm/filemap.c b/mm/filemap.c
index 1d33fec..4a2fee2 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1968,6 +1968,7 @@
do {
unsigned long index;
unsigned long offset;
+ unsigned long maxlen;
size_t copied;
offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
@@ -1982,7 +1983,10 @@
* same page as we're writing to, without it being marked
* up-to-date.
*/
- fault_in_pages_readable(buf, bytes);
+ maxlen = cur_iov->iov_len - iov_base;
+ if (maxlen > bytes)
+ maxlen = bytes;
+ fault_in_pages_readable(buf, maxlen);
page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
if (!page) {
@@ -2024,6 +2028,8 @@
filemap_set_next_iovec(&cur_iov,
&iov_base, status);
buf = cur_iov->iov_base + iov_base;
+ } else {
+ iov_base += status;
}
}
}
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 8ec4848..a3eeb88 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -356,7 +356,7 @@
{
struct ethtool_coalesce coalesce;
- if (!dev->ethtool_ops->get_coalesce)
+ if (!dev->ethtool_ops->set_coalesce)
return -EOPNOTSUPP;
if (copy_from_user(&coalesce, useraddr, sizeof(coalesce)))