Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@osdl.org>2002-07-31 22:24:41 -0700
committerPatrick Mochel <mochel@osdl.org>2002-07-31 22:24:41 -0700
commit9e27f077152b4aa70184166406eed14005a83faa (patch)
tree74d8c57e5efb6ffdefcd5e9766ba56a58d24d6f0
parent137973c1a3ee75e3d28af550a5e33737ac9acc5b (diff)
parent8a24c0b94488c734eddee9d07e61adcbe441919f (diff)
Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin
into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-driverfs-api
-rw-r--r--drivers/usb/host/ohci-q.c29
-rw-r--r--fs/nfs/dir.c9
-rw-r--r--fs/nfs/nfs2xdr.c2
-rw-r--r--fs/nfs/nfs3xdr.c2
-rw-r--r--include/asm-i386/smp.h5
-rw-r--r--mm/rmap.c2
-rw-r--r--net/sunrpc/clnt.c12
-rw-r--r--net/sunrpc/xprt.c34
8 files changed, 61 insertions, 34 deletions
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 0fe88b71cc30..7518b8992b8f 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -534,6 +534,8 @@ td_fill (unsigned int info,
/* aim for only one interrupt per urb. mostly applies to control
* and iso; other urbs rarely need more than one TD per urb.
* this way, only final tds (or ones with an error) cause IRQs.
+ * at least immediately; use DI=6 in case any control request is
+ * tempted to die part way through.
*
* NOTE: could delay interrupts even for the last TD, and get fewer
* interrupts ... increasing per-urb latency by sharing interrupts.
@@ -541,7 +543,7 @@ td_fill (unsigned int info,
*/
if (index != (urb_priv->length - 1)
|| (urb->transfer_flags & URB_NO_INTERRUPT))
- info |= TD_DI_SET (7);
+ info |= TD_DI_SET (6);
/* use this td as the next dummy */
td_pt = urb_priv->td [index];
@@ -809,12 +811,16 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
ohci->hcca->done_head = 0;
while (td_list_hc) {
+ int cc;
+
td_list = dma_to_td (ohci, td_list_hc);
td_list->hwINFO |= cpu_to_le32 (TD_DONE);
- if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) {
+ cc = TD_CC_GET (le32_to_cpup (&td_list->hwINFO));
+ if (cc != TD_CC_NOERROR) {
urb_priv = (urb_priv_t *) td_list->urb->hcpriv;
+
/* Non-iso endpoints can halt on error; un-halt,
* and dequeue any other TDs from this urb.
* No other TD could have caused the halt.
@@ -822,12 +828,21 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
if (td_list->ed->hwHeadP & ED_H) {
if (urb_priv && ((td_list->index + 1)
< urb_priv->length)) {
-#ifdef OHCI_VERBOSE_DEBUG
- dbg ("urb %p TD %p (%d/%d), patch ED",
- td_list->urb, td_list,
+ struct urb *urb = td_list->urb;
+
+ /* help for troubleshooting: */
+ dbg ("urb %p usb-%s-%s ep-%d-%s "
+ "(td %d/%d), "
+ "cc %d --> status %d",
+ td_list->urb,
+ urb->dev->bus->bus_name,
+ urb->dev->devpath,
+ usb_pipeendpoint (urb->pipe),
+ usb_pipein (urb->pipe)
+ ? "IN" : "OUT",
1 + td_list->index,
- urb_priv->length);
-#endif
+ urb_priv->length,
+ cc, cc_to_error [cc]);
td_list->ed->hwHeadP =
(urb_priv->td [urb_priv->length - 1]->hwNextTD
& __constant_cpu_to_le32 (TD_MASK))
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 42f58d5f061a..bba0eb57f54a 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -198,7 +198,7 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc)
dfprintk(VFS, "NFS: find_dirent_page() searching directory page %ld\n", desc->page_index);
- page = read_cache_page(&inode->i_data, desc->page_index,
+ page = read_cache_page(inode->i_mapping, desc->page_index,
(filler_t *)nfs_readdir_filler, desc);
if (IS_ERR(page)) {
status = PTR_ERR(page);
@@ -566,7 +566,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, int flags)
goto out_valid;
shrink_dcache_parent(dentry);
}
- d_drop(dentry);
unlock_kernel();
dput(parent);
return 0;
@@ -639,7 +638,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry)
nfs_renew_times(dentry);
error = 0;
}
- goto out;
+ goto out_unlock;
}
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
@@ -655,8 +654,10 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry)
}
nfs_renew_times(dentry);
}
+out_unlock:
unlock_kernel();
out:
+ BUG_ON(error > 0);
return ERR_PTR(error);
}
@@ -712,7 +713,7 @@ int nfs_cached_lookup(struct inode *dir, struct dentry *dentry,
desc.page_index = 0;
desc.plus = 1;
- for(;(page = find_get_page(&dir->i_data, desc.page_index)); desc.page_index++) {
+ for(;(page = find_get_page(dir->i_mapping, desc.page_index)); desc.page_index++) {
res = -EIO;
if (PageUptodate(page)) {
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 5e083b6b3bca..4883b923d5f1 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -420,9 +420,9 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
kunmap(*page);
return nr;
short_pkt:
- kunmap(*page);
printk(KERN_NOTICE "NFS: short packet in readdir reply!\n");
entry[0] = entry[1] = 0;
+ kunmap(*page);
return nr;
err_unmap:
kunmap(*page);
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 784720607bf8..4ebce82ad8e0 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -574,10 +574,10 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res)
kunmap(*page);
return nr;
short_pkt:
- kunmap(*page);
printk(KERN_NOTICE "NFS: short packet in readdir reply!\n");
/* truncate listing */
entry[0] = entry[1] = 0;
+ kunmap(*page);
return nr;
err_unmap:
kunmap(*page);
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index 6b116b38a4e2..a6d46dec1d09 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -85,7 +85,9 @@ extern volatile int logical_apicid_to_cpu[MAX_APICID];
*/
#define smp_processor_id() (current_thread_info()->cpu)
-#define cpu_possible(cpu) (phys_cpu_present_map & (1<<(cpu)))
+extern volatile unsigned long cpu_callout_map;
+
+#define cpu_possible(cpu) (cpu_callout_map & (1<<(cpu)))
#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
extern inline unsigned int num_online_cpus(void)
@@ -113,7 +115,6 @@ static __inline int logical_smp_processor_id(void)
return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR));
}
-extern volatile unsigned long cpu_callout_map;
/* We don't mark CPUs online until __cpu_up(), so we need another measure */
static inline int num_booting_cpus(void)
{
diff --git a/mm/rmap.c b/mm/rmap.c
index 6287e9cacc2a..891583e3438f 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -208,8 +208,6 @@ void page_remove_rmap(struct page * page, pte_t * ptep)
}
printk("\n");
printk(KERN_ERR "page_remove_rmap: driver cleared PG_reserved ?\n");
-#else
- BUG();
#endif
out:
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 001c2253ec8f..283fac6a3951 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -605,17 +605,17 @@ call_status(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
struct rpc_xprt *xprt = clnt->cl_xprt;
- struct rpc_rqst *req;
- int status = task->tk_status;
+ struct rpc_rqst *req = task->tk_rqstp;
+ int status;
+
+ if (req->rq_received != 0)
+ task->tk_status = req->rq_received;
dprintk("RPC: %4d call_status (status %d)\n",
task->tk_pid, task->tk_status);
- req = task->tk_rqstp;
- if (req->rq_received != 0)
- status = req->rq_received;
+ status = task->tk_status;
if (status >= 0) {
- req->rq_received = 0;
task->tk_action = call_decode;
return;
}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 3d4ba37b48e1..e6ae990b0cc8 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -137,17 +137,14 @@ xprt_from_sock(struct sock *sk)
* Also prevents TCP socket reconnections from colliding with writes.
*/
static int
-xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
+__xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
{
- int retval;
- spin_lock_bh(&xprt->sock_lock);
if (!xprt->snd_task) {
if (xprt->nocong || __xprt_get_cong(xprt, task))
xprt->snd_task = task;
}
if (xprt->snd_task != task) {
- dprintk("RPC: %4d TCP write queue full (task %d)\n",
- task->tk_pid, xprt->snd_task->tk_pid);
+ dprintk("RPC: %4d TCP write queue full\n", task->tk_pid);
task->tk_timeout = 0;
task->tk_status = -EAGAIN;
if (task->tk_rqstp->rq_nresend)
@@ -155,11 +152,21 @@ xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
else
rpc_sleep_on(&xprt->sending, task, NULL, NULL);
}
- retval = xprt->snd_task == task;
+ return xprt->snd_task == task;
+}
+
+static inline int
+xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
+{
+ int retval;
+
+ spin_lock_bh(&xprt->sock_lock);
+ retval = __xprt_lock_write(xprt, task);
spin_unlock_bh(&xprt->sock_lock);
return retval;
}
+
static void
__xprt_lock_write_next(struct rpc_xprt *xprt)
{
@@ -564,8 +571,8 @@ xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied)
#endif
dprintk("RPC: %4d has input (%d bytes)\n", task->tk_pid, copied);
- task->tk_status = copied;
req->rq_received = copied;
+ list_del_init(&req->rq_list);
/* ... and wake up the process. */
rpc_wake_up_task(task);
@@ -1057,8 +1064,16 @@ xprt_transmit(struct rpc_task *task)
*marker = htonl(0x80000000|(req->rq_slen-sizeof(*marker)));
}
- if (!xprt_lock_write(xprt, task))
+ spin_lock_bh(&xprt->sock_lock);
+ if (!__xprt_lock_write(xprt, task)) {
+ spin_unlock_bh(&xprt->sock_lock);
return;
+ }
+ if (list_empty(&req->rq_list)) {
+ list_add_tail(&req->rq_list, &xprt->recv);
+ req->rq_received = 0;
+ }
+ spin_unlock_bh(&xprt->sock_lock);
do_xprt_transmit(task);
}
@@ -1242,9 +1257,6 @@ xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
if (!xid)
xid++;
INIT_LIST_HEAD(&req->rq_list);
- spin_lock_bh(&xprt->sock_lock);
- list_add_tail(&req->rq_list, &xprt->recv);
- spin_unlock_bh(&xprt->sock_lock);
}
/*