This source file includes following definitions.
- wa_nep_arm
- wa_nep_disarm
- wa_rpipe_init
- wa_init
- __rpipe_get
- rpipe_put
- rpipe_avail_dec
- rpipe_avail_inc
- wa_get
- wa_put
- __wa_feature
- __wa_set_feature
- __wa_clear_feature
- __wa_get_status
- __wa_wait_status
- __wa_stop
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66 #ifndef __HWAHC_INTERNAL_H__
67 #define __HWAHC_INTERNAL_H__
68
69 #include <linux/completion.h>
70 #include <linux/usb.h>
71 #include <linux/mutex.h>
72 #include <linux/spinlock.h>
73 #include "../uwb/uwb.h"
74 #include "include/wusb.h"
75 #include "include/wusb-wa.h"
76
77 struct wusbhc;
78 struct wahc;
79 extern void wa_urb_enqueue_run(struct work_struct *ws);
80 extern void wa_process_errored_transfers_run(struct work_struct *ws);
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 struct wa_rpipe {
100 struct kref refcnt;
101 struct usb_rpipe_descriptor descr;
102 struct usb_host_endpoint *ep;
103 struct wahc *wa;
104 spinlock_t seg_lock;
105 struct list_head seg_list;
106 struct list_head list_node;
107 atomic_t segs_available;
108 u8 buffer[1];
109 };
110
111
112 enum wa_dti_state {
113 WA_DTI_TRANSFER_RESULT_PENDING,
114 WA_DTI_ISOC_PACKET_STATUS_PENDING,
115 WA_DTI_BUF_IN_DATA_PENDING
116 };
117
118 enum wa_quirks {
119
120
121
122
123 WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC = 0x01,
124
125
126
127
128 WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS = 0x02,
129 };
130
131 enum wa_vendor_specific_requests {
132 WA_REQ_ALEREON_DISABLE_XFER_NOTIFICATIONS = 0x4C,
133 WA_REQ_ALEREON_FEATURE_SET = 0x01,
134 WA_REQ_ALEREON_FEATURE_CLEAR = 0x00,
135 };
136
137 #define WA_MAX_BUF_IN_URBS 4
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 struct wahc {
173 struct usb_device *usb_dev;
174 struct usb_interface *usb_iface;
175
176
177 union {
178 struct wusbhc *wusb;
179 struct dwahc *dwa;
180 };
181
182 const struct usb_endpoint_descriptor *dto_epd, *dti_epd;
183 const struct usb_wa_descriptor *wa_descr;
184
185 struct urb *nep_urb;
186 struct edc nep_edc;
187 void *nep_buffer;
188 size_t nep_buffer_size;
189
190 atomic_t notifs_queued;
191
192 u16 rpipes;
193 unsigned long *rpipe_bm;
194 struct list_head rpipe_delayed_list;
195 spinlock_t rpipe_lock;
196 struct mutex rpipe_mutex;
197
198
199
200
201
202
203
204 enum wa_dti_state dti_state;
205 u32 dti_isoc_xfer_in_progress;
206 u8 dti_isoc_xfer_seg;
207 struct urb *dti_urb;
208
209 struct urb buf_in_urbs[WA_MAX_BUF_IN_URBS];
210 int active_buf_in_urbs;
211 struct edc dti_edc;
212 void *dti_buf;
213 size_t dti_buf_size;
214
215 unsigned long dto_in_use;
216
217 s32 status;
218
219 struct list_head xfer_list;
220 struct list_head xfer_delayed_list;
221 struct list_head xfer_errored_list;
222
223
224
225
226 spinlock_t xfer_list_lock;
227 struct work_struct xfer_enqueue_work;
228 struct work_struct xfer_error_work;
229 atomic_t xfer_id_count;
230
231 kernel_ulong_t quirks;
232 };
233
234
235 extern int wa_create(struct wahc *wa, struct usb_interface *iface,
236 kernel_ulong_t);
237 extern void __wa_destroy(struct wahc *wa);
238 extern int wa_dti_start(struct wahc *wa);
239 void wa_reset_all(struct wahc *wa);
240
241
242
243 enum {
244
245
246 HWAHC_EPROTO_MAX = 16,
247
248 HWAHC_EPROTO_PERIOD = 4 * HZ,
249 };
250
251
252
253 extern int wa_nep_create(struct wahc *, struct usb_interface *);
254 extern void wa_nep_destroy(struct wahc *);
255
256 static inline int wa_nep_arm(struct wahc *wa, gfp_t gfp_mask)
257 {
258 struct urb *urb = wa->nep_urb;
259 urb->transfer_buffer = wa->nep_buffer;
260 urb->transfer_buffer_length = wa->nep_buffer_size;
261 return usb_submit_urb(urb, gfp_mask);
262 }
263
264 static inline void wa_nep_disarm(struct wahc *wa)
265 {
266 usb_kill_urb(wa->nep_urb);
267 }
268
269
270
271 static inline void wa_rpipe_init(struct wahc *wa)
272 {
273 INIT_LIST_HEAD(&wa->rpipe_delayed_list);
274 spin_lock_init(&wa->rpipe_lock);
275 mutex_init(&wa->rpipe_mutex);
276 }
277
278 static inline void wa_init(struct wahc *wa)
279 {
280 int index;
281
282 edc_init(&wa->nep_edc);
283 atomic_set(&wa->notifs_queued, 0);
284 wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING;
285 wa_rpipe_init(wa);
286 edc_init(&wa->dti_edc);
287 INIT_LIST_HEAD(&wa->xfer_list);
288 INIT_LIST_HEAD(&wa->xfer_delayed_list);
289 INIT_LIST_HEAD(&wa->xfer_errored_list);
290 spin_lock_init(&wa->xfer_list_lock);
291 INIT_WORK(&wa->xfer_enqueue_work, wa_urb_enqueue_run);
292 INIT_WORK(&wa->xfer_error_work, wa_process_errored_transfers_run);
293 wa->dto_in_use = 0;
294 atomic_set(&wa->xfer_id_count, 1);
295
296 for (index = 0; index < WA_MAX_BUF_IN_URBS; ++index)
297 usb_init_urb(&(wa->buf_in_urbs[index]));
298 wa->active_buf_in_urbs = 0;
299 }
300
301
302
303
304
305
306 struct wa_xfer;
307 extern void rpipe_destroy(struct kref *_rpipe);
308 static inline
309 void __rpipe_get(struct wa_rpipe *rpipe)
310 {
311 kref_get(&rpipe->refcnt);
312 }
313 extern int rpipe_get_by_ep(struct wahc *, struct usb_host_endpoint *,
314 struct urb *, gfp_t);
315 static inline void rpipe_put(struct wa_rpipe *rpipe)
316 {
317 kref_put(&rpipe->refcnt, rpipe_destroy);
318
319 }
320 extern void rpipe_ep_disable(struct wahc *, struct usb_host_endpoint *);
321 extern void rpipe_clear_feature_stalled(struct wahc *,
322 struct usb_host_endpoint *);
323 extern int wa_rpipes_create(struct wahc *);
324 extern void wa_rpipes_destroy(struct wahc *);
325 static inline void rpipe_avail_dec(struct wa_rpipe *rpipe)
326 {
327 atomic_dec(&rpipe->segs_available);
328 }
329
330
331
332
333 static inline int rpipe_avail_inc(struct wa_rpipe *rpipe)
334 {
335 return atomic_inc_return(&rpipe->segs_available) > 0
336 && !list_empty(&rpipe->seg_list);
337 }
338
339
340
341 extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *,
342 struct urb *, gfp_t);
343 extern int wa_urb_dequeue(struct wahc *, struct urb *, int);
344 extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *);
345
346
347
348
349
350
351
352
353
354
355
356
357
358 static inline struct wahc *wa_get(struct wahc *wa)
359 {
360 usb_get_intf(wa->usb_iface);
361 return wa;
362 }
363
364 static inline void wa_put(struct wahc *wa)
365 {
366 usb_put_intf(wa->usb_iface);
367 }
368
369
370 static inline int __wa_feature(struct wahc *wa, unsigned op, u16 feature)
371 {
372 return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
373 op ? USB_REQ_SET_FEATURE : USB_REQ_CLEAR_FEATURE,
374 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
375 feature,
376 wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
377 NULL, 0, USB_CTRL_SET_TIMEOUT);
378 }
379
380
381 static inline int __wa_set_feature(struct wahc *wa, u16 feature)
382 {
383 return __wa_feature(wa, 1, feature);
384 }
385
386
387 static inline int __wa_clear_feature(struct wahc *wa, u16 feature)
388 {
389 return __wa_feature(wa, 0, feature);
390 }
391
392
393
394
395
396
397
398
399
400
401
402 static inline
403 s32 __wa_get_status(struct wahc *wa)
404 {
405 s32 result;
406 result = usb_control_msg(
407 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
408 USB_REQ_GET_STATUS,
409 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
410 0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
411 &wa->status, sizeof(wa->status), USB_CTRL_GET_TIMEOUT);
412 if (result >= 0)
413 result = wa->status;
414 return result;
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430 static inline s32 __wa_wait_status(struct wahc *wa, u32 mask, u32 value)
431 {
432 s32 result;
433 unsigned loops = 10;
434 do {
435 msleep(50);
436 result = __wa_get_status(wa);
437 if ((result & mask) == value)
438 break;
439 if (loops-- == 0) {
440 result = -ETIMEDOUT;
441 break;
442 }
443 } while (result >= 0);
444 return result;
445 }
446
447
448
449 static inline int __wa_stop(struct wahc *wa)
450 {
451 int result;
452 struct device *dev = &wa->usb_iface->dev;
453
454 result = __wa_clear_feature(wa, WA_ENABLE);
455 if (result < 0 && result != -ENODEV) {
456 dev_err(dev, "error commanding HC to stop: %d\n", result);
457 goto out;
458 }
459 result = __wa_wait_status(wa, WA_ENABLE, 0);
460 if (result < 0 && result != -ENODEV)
461 dev_err(dev, "error waiting for HC to stop: %d\n", result);
462 out:
463 return 0;
464 }
465
466
467 #endif