1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52#include <linux/workqueue.h>
53#include <linux/ctype.h>
54
55#include "wa-hc.h"
56#include "wusbhc.h"
57
58
59struct wa_notif_work {
60 struct work_struct work;
61 struct wahc *wa;
62 size_t size;
63 u8 data[];
64};
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91static void wa_notif_dispatch(struct work_struct *ws)
92{
93 void *itr;
94 u8 missing = 0;
95 struct wa_notif_work *nw = container_of(ws, struct wa_notif_work, work);
96 struct wahc *wa = nw->wa;
97 struct wa_notif_hdr *notif_hdr;
98 size_t size;
99
100 struct device *dev = &wa->usb_iface->dev;
101
102#if 0
103
104 if (usb_hcd->state == HC_STATE_QUIESCING)
105 goto out;
106#endif
107 atomic_dec(&wa->notifs_queued);
108 dev = &wa->usb_iface->dev;
109 size = nw->size;
110 itr = nw->data;
111
112 while (size) {
113 if (size < sizeof(*notif_hdr)) {
114 missing = sizeof(*notif_hdr) - size;
115 goto exhausted_buffer;
116 }
117 notif_hdr = itr;
118 if (size < notif_hdr->bLength)
119 goto exhausted_buffer;
120 itr += notif_hdr->bLength;
121 size -= notif_hdr->bLength;
122
123 switch (notif_hdr->bNotifyType) {
124 case HWA_NOTIF_DN: {
125 struct hwa_notif_dn *hwa_dn;
126 hwa_dn = container_of(notif_hdr, struct hwa_notif_dn,
127 hdr);
128 wusbhc_handle_dn(wa->wusb, hwa_dn->bSourceDeviceAddr,
129 hwa_dn->dndata,
130 notif_hdr->bLength - sizeof(*hwa_dn));
131 break;
132 }
133 case WA_NOTIF_TRANSFER:
134 wa_handle_notif_xfer(wa, notif_hdr);
135 break;
136 case DWA_NOTIF_RWAKE:
137 case DWA_NOTIF_PORTSTATUS:
138 case HWA_NOTIF_BPST_ADJ:
139
140
141 default:
142 dev_err(dev, "HWA: unknown notification 0x%x, "
143 "%zu bytes; discarding\n",
144 notif_hdr->bNotifyType,
145 (size_t)notif_hdr->bLength);
146 break;
147 }
148 }
149out:
150 wa_put(wa);
151 kfree(nw);
152 return;
153
154
155
156
157
158
159exhausted_buffer:
160 dev_warn(dev, "HWA: device sent short notification, "
161 "%d bytes missing; discarding %d bytes.\n",
162 missing, (int)size);
163 goto out;
164}
165
166
167
168
169
170
171
172
173
174
175
176
177
178static int wa_nep_queue(struct wahc *wa, size_t size)
179{
180 int result = 0;
181 struct device *dev = &wa->usb_iface->dev;
182 struct wa_notif_work *nw;
183
184
185 BUG_ON(size > wa->nep_buffer_size);
186 if (size == 0)
187 goto out;
188 if (atomic_read(&wa->notifs_queued) > 200) {
189 if (printk_ratelimit())
190 dev_err(dev, "Too many notifications queued, "
191 "throttling back\n");
192 goto out;
193 }
194 nw = kzalloc(sizeof(*nw) + size, GFP_ATOMIC);
195 if (nw == NULL) {
196 if (printk_ratelimit())
197 dev_err(dev, "No memory to queue notification\n");
198 goto out;
199 }
200 INIT_WORK(&nw->work, wa_notif_dispatch);
201 nw->wa = wa_get(wa);
202 nw->size = size;
203 memcpy(nw->data, wa->nep_buffer, size);
204 atomic_inc(&wa->notifs_queued);
205 queue_work(wusbd, &nw->work);
206out:
207
208 return result;
209}
210
211
212
213
214
215
216
217static void wa_nep_cb(struct urb *urb)
218{
219 int result;
220 struct wahc *wa = urb->context;
221 struct device *dev = &wa->usb_iface->dev;
222
223 switch (result = urb->status) {
224 case 0:
225 result = wa_nep_queue(wa, urb->actual_length);
226 if (result < 0)
227 dev_err(dev, "NEP: unable to process notification(s): "
228 "%d\n", result);
229 break;
230 case -ECONNRESET:
231 case -ENOENT:
232 case -ESHUTDOWN:
233 dev_dbg(dev, "NEP: going down %d\n", urb->status);
234 goto out;
235 default:
236 if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
237 EDC_ERROR_TIMEFRAME)) {
238 dev_err(dev, "NEP: URB max acceptable errors "
239 "exceeded, resetting device\n");
240 wa_reset_all(wa);
241 goto out;
242 }
243 dev_err(dev, "NEP: URB error %d\n", urb->status);
244 }
245 result = wa_nep_arm(wa, GFP_ATOMIC);
246 if (result < 0) {
247 dev_err(dev, "NEP: cannot submit URB: %d\n", result);
248 wa_reset_all(wa);
249 }
250out:
251 return;
252}
253
254
255
256
257
258
259
260int wa_nep_create(struct wahc *wa, struct usb_interface *iface)
261{
262 int result;
263 struct usb_endpoint_descriptor *epd;
264 struct usb_device *usb_dev = interface_to_usbdev(iface);
265 struct device *dev = &iface->dev;
266
267 edc_init(&wa->nep_edc);
268 epd = &iface->cur_altsetting->endpoint[0].desc;
269 wa->nep_buffer_size = 1024;
270 wa->nep_buffer = kmalloc(wa->nep_buffer_size, GFP_KERNEL);
271 if (wa->nep_buffer == NULL) {
272 dev_err(dev, "Unable to allocate notification's read buffer\n");
273 goto error_nep_buffer;
274 }
275 wa->nep_urb = usb_alloc_urb(0, GFP_KERNEL);
276 if (wa->nep_urb == NULL) {
277 dev_err(dev, "Unable to allocate notification URB\n");
278 goto error_urb_alloc;
279 }
280 usb_fill_int_urb(wa->nep_urb, usb_dev,
281 usb_rcvintpipe(usb_dev, epd->bEndpointAddress),
282 wa->nep_buffer, wa->nep_buffer_size,
283 wa_nep_cb, wa, epd->bInterval);
284 result = wa_nep_arm(wa, GFP_KERNEL);
285 if (result < 0) {
286 dev_err(dev, "Cannot submit notification URB: %d\n", result);
287 goto error_nep_arm;
288 }
289 return 0;
290
291error_nep_arm:
292 usb_free_urb(wa->nep_urb);
293error_urb_alloc:
294 kfree(wa->nep_buffer);
295error_nep_buffer:
296 return -ENOMEM;
297}
298
299void wa_nep_destroy(struct wahc *wa)
300{
301 wa_nep_disarm(wa);
302 usb_free_urb(wa->nep_urb);
303 kfree(wa->nep_buffer);
304}
305