diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-24 08:41:41 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-24 13:07:53 -0400 |
commit | 816724e65c72a90a44fbad0ef0b59b186c85fa90 (patch) | |
tree | 421fa29aedff988e392f92780637553e275d37a0 /drivers/usb/mon | |
parent | 70ac4385a13f78bc478f26d317511893741b05bd (diff) | |
parent | d384ea691fe4ea8c2dd5b9b8d9042eb181776f18 (diff) |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Conflicts:
fs/nfs/inode.c
fs/super.c
Fix conflicts between patch 'NFS: Split fs/nfs/inode.c' and patch
'VFS: Permit filesystem to override root dentry on mount'
Diffstat (limited to 'drivers/usb/mon')
-rw-r--r-- | drivers/usb/mon/mon_dma.c | 5 | ||||
-rw-r--r-- | drivers/usb/mon/mon_main.c | 23 | ||||
-rw-r--r-- | drivers/usb/mon/mon_stat.c | 4 | ||||
-rw-r--r-- | drivers/usb/mon/mon_text.c | 36 | ||||
-rw-r--r-- | drivers/usb/mon/usb_mon.h | 2 |
5 files changed, 59 insertions, 11 deletions
diff --git a/drivers/usb/mon/mon_dma.c b/drivers/usb/mon/mon_dma.c index 0a1367b760a0..ddcfc01e77a0 100644 --- a/drivers/usb/mon/mon_dma.c +++ b/drivers/usb/mon/mon_dma.c | |||
@@ -13,7 +13,10 @@ | |||
13 | #include <linux/usb.h> /* Only needed for declarations in usb_mon.h */ | 13 | #include <linux/usb.h> /* Only needed for declarations in usb_mon.h */ |
14 | #include "usb_mon.h" | 14 | #include "usb_mon.h" |
15 | 15 | ||
16 | #ifdef __i386__ /* CONFIG_ARCH_I386 does not exit */ | 16 | /* |
17 | * PC-compatibles, are, fortunately, sufficiently cache-coherent for this. | ||
18 | */ | ||
19 | #if defined(__i386__) || defined(__x86_64__) /* CONFIG_ARCH_I386 doesn't exit */ | ||
17 | #define MON_HAS_UNMAP 1 | 20 | #define MON_HAS_UNMAP 1 |
18 | 21 | ||
19 | #define phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT) | 22 | #define phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT) |
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 6ecc27302211..275a66f83058 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -97,6 +97,7 @@ static void mon_submit(struct usb_bus *ubus, struct urb *urb) | |||
97 | if (mbus->nreaders == 0) | 97 | if (mbus->nreaders == 0) |
98 | goto out_locked; | 98 | goto out_locked; |
99 | 99 | ||
100 | mbus->cnt_events++; | ||
100 | list_for_each (pos, &mbus->r_list) { | 101 | list_for_each (pos, &mbus->r_list) { |
101 | r = list_entry(pos, struct mon_reader, r_link); | 102 | r = list_entry(pos, struct mon_reader, r_link); |
102 | r->rnf_submit(r->r_data, urb); | 103 | r->rnf_submit(r->r_data, urb); |
@@ -113,20 +114,32 @@ out_unlocked: | |||
113 | 114 | ||
114 | /* | 115 | /* |
115 | */ | 116 | */ |
116 | static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int err) | 117 | static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) |
117 | { | 118 | { |
118 | struct mon_bus *mbus; | 119 | struct mon_bus *mbus; |
120 | unsigned long flags; | ||
121 | struct list_head *pos; | ||
122 | struct mon_reader *r; | ||
119 | 123 | ||
120 | mbus = ubus->mon_bus; | 124 | mbus = ubus->mon_bus; |
121 | if (mbus == NULL) | 125 | if (mbus == NULL) |
122 | goto out_unlocked; | 126 | goto out_unlocked; |
123 | 127 | ||
124 | /* | 128 | spin_lock_irqsave(&mbus->lock, flags); |
125 | * XXX Capture the error code and the 'E' event. | 129 | if (mbus->nreaders == 0) |
126 | */ | 130 | goto out_locked; |
127 | 131 | ||
132 | mbus->cnt_events++; | ||
133 | list_for_each (pos, &mbus->r_list) { | ||
134 | r = list_entry(pos, struct mon_reader, r_link); | ||
135 | r->rnf_error(r->r_data, urb, error); | ||
136 | } | ||
137 | |||
138 | spin_unlock_irqrestore(&mbus->lock, flags); | ||
128 | return; | 139 | return; |
129 | 140 | ||
141 | out_locked: | ||
142 | spin_unlock_irqrestore(&mbus->lock, flags); | ||
130 | out_unlocked: | 143 | out_unlocked: |
131 | return; | 144 | return; |
132 | } | 145 | } |
@@ -152,6 +165,7 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) | |||
152 | } | 165 | } |
153 | 166 | ||
154 | spin_lock_irqsave(&mbus->lock, flags); | 167 | spin_lock_irqsave(&mbus->lock, flags); |
168 | mbus->cnt_events++; | ||
155 | list_for_each (pos, &mbus->r_list) { | 169 | list_for_each (pos, &mbus->r_list) { |
156 | r = list_entry(pos, struct mon_reader, r_link); | 170 | r = list_entry(pos, struct mon_reader, r_link); |
157 | r->rnf_complete(r->r_data, urb); | 171 | r->rnf_complete(r->r_data, urb); |
@@ -163,7 +177,6 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) | |||
163 | 177 | ||
164 | /* | 178 | /* |
165 | * Stop monitoring. | 179 | * Stop monitoring. |
166 | * Obviously this must be well locked, so no need to play with mb's. | ||
167 | */ | 180 | */ |
168 | static void mon_stop(struct mon_bus *mbus) | 181 | static void mon_stop(struct mon_bus *mbus) |
169 | { | 182 | { |
diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index 6e4b165d070a..1fe01d994a79 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c | |||
@@ -31,8 +31,8 @@ static int mon_stat_open(struct inode *inode, struct file *file) | |||
31 | mbus = inode->u.generic_ip; | 31 | mbus = inode->u.generic_ip; |
32 | 32 | ||
33 | sp->slen = snprintf(sp->str, STAT_BUF_SIZE, | 33 | sp->slen = snprintf(sp->str, STAT_BUF_SIZE, |
34 | "nreaders %d text_lost %u\n", | 34 | "nreaders %d events %u text_lost %u\n", |
35 | mbus->nreaders, mbus->cnt_text_lost); | 35 | mbus->nreaders, mbus->cnt_events, mbus->cnt_text_lost); |
36 | 36 | ||
37 | file->private_data = sp; | 37 | file->private_data = sp; |
38 | return 0; | 38 | return 0; |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index ac043ec2b8dc..e02c1a30c4cd 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -26,10 +26,13 @@ | |||
26 | 26 | ||
27 | /* | 27 | /* |
28 | * This limit exists to prevent OOMs when the user process stops reading. | 28 | * This limit exists to prevent OOMs when the user process stops reading. |
29 | * If usbmon were available to unprivileged processes, it might be open | ||
30 | * to a local DoS. But we have to keep to root in order to prevent | ||
31 | * password sniffing from HID devices. | ||
29 | */ | 32 | */ |
30 | #define EVENT_MAX 25 | 33 | #define EVENT_MAX (2*PAGE_SIZE / sizeof(struct mon_event_text)) |
31 | 34 | ||
32 | #define PRINTF_DFL 130 | 35 | #define PRINTF_DFL 160 |
33 | 36 | ||
34 | struct mon_event_text { | 37 | struct mon_event_text { |
35 | struct list_head e_link; | 38 | struct list_head e_link; |
@@ -111,7 +114,7 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | |||
111 | * number of corner cases, but it seems that the following is | 114 | * number of corner cases, but it seems that the following is |
112 | * more or less safe. | 115 | * more or less safe. |
113 | * | 116 | * |
114 | * We do not even try to look transfer_buffer, because it can | 117 | * We do not even try to look at transfer_buffer, because it can |
115 | * contain non-NULL garbage in case the upper level promised to | 118 | * contain non-NULL garbage in case the upper level promised to |
116 | * set DMA for the HCD. | 119 | * set DMA for the HCD. |
117 | */ | 120 | */ |
@@ -179,6 +182,32 @@ static void mon_text_complete(void *data, struct urb *urb) | |||
179 | mon_text_event(rp, urb, 'C'); | 182 | mon_text_event(rp, urb, 'C'); |
180 | } | 183 | } |
181 | 184 | ||
185 | static void mon_text_error(void *data, struct urb *urb, int error) | ||
186 | { | ||
187 | struct mon_reader_text *rp = data; | ||
188 | struct mon_event_text *ep; | ||
189 | |||
190 | if (rp->nevents >= EVENT_MAX || | ||
191 | (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) { | ||
192 | rp->r.m_bus->cnt_text_lost++; | ||
193 | return; | ||
194 | } | ||
195 | |||
196 | ep->type = 'E'; | ||
197 | ep->pipe = urb->pipe; | ||
198 | ep->id = (unsigned long) urb; | ||
199 | ep->tstamp = 0; | ||
200 | ep->length = 0; | ||
201 | ep->status = error; | ||
202 | |||
203 | ep->setup_flag = '-'; | ||
204 | ep->data_flag = 'E'; | ||
205 | |||
206 | rp->nevents++; | ||
207 | list_add_tail(&ep->e_link, &rp->e_list); | ||
208 | wake_up(&rp->wait); | ||
209 | } | ||
210 | |||
182 | /* | 211 | /* |
183 | * Fetch next event from the circular buffer. | 212 | * Fetch next event from the circular buffer. |
184 | */ | 213 | */ |
@@ -232,6 +261,7 @@ static int mon_text_open(struct inode *inode, struct file *file) | |||
232 | rp->r.m_bus = mbus; | 261 | rp->r.m_bus = mbus; |
233 | rp->r.r_data = rp; | 262 | rp->r.r_data = rp; |
234 | rp->r.rnf_submit = mon_text_submit; | 263 | rp->r.rnf_submit = mon_text_submit; |
264 | rp->r.rnf_error = mon_text_error; | ||
235 | rp->r.rnf_complete = mon_text_complete; | 265 | rp->r.rnf_complete = mon_text_complete; |
236 | 266 | ||
237 | snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum, | 267 | snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum, |
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index 8e0613c350cc..33678c24ebee 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h | |||
@@ -27,6 +27,7 @@ struct mon_bus { | |||
27 | struct kref ref; /* Under mon_lock */ | 27 | struct kref ref; /* Under mon_lock */ |
28 | 28 | ||
29 | /* Stats */ | 29 | /* Stats */ |
30 | unsigned int cnt_events; | ||
30 | unsigned int cnt_text_lost; | 31 | unsigned int cnt_text_lost; |
31 | }; | 32 | }; |
32 | 33 | ||
@@ -39,6 +40,7 @@ struct mon_reader { | |||
39 | void *r_data; /* Use container_of instead? */ | 40 | void *r_data; /* Use container_of instead? */ |
40 | 41 | ||
41 | void (*rnf_submit)(void *data, struct urb *urb); | 42 | void (*rnf_submit)(void *data, struct urb *urb); |
43 | void (*rnf_error)(void *data, struct urb *urb, int error); | ||
42 | void (*rnf_complete)(void *data, struct urb *urb); | 44 | void (*rnf_complete)(void *data, struct urb *urb); |
43 | }; | 45 | }; |
44 | 46 | ||