|
@@ -40,27 +40,14 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
40
|
40
|
* @v hubdev Hub device
|
41
|
41
|
*/
|
42
|
42
|
static void hub_refill ( struct usb_hub_device *hubdev ) {
|
43
|
|
- struct io_buffer *iobuf;
|
44
|
|
- size_t mtu = hubdev->intr.mtu;
|
45
|
43
|
int rc;
|
46
|
44
|
|
47
|
|
- /* Enqueue any available I/O buffers */
|
48
|
|
- while ( ( iobuf = list_first_entry ( &hubdev->intrs, struct io_buffer,
|
49
|
|
- list ) ) ) {
|
50
|
|
-
|
51
|
|
- /* Reset size */
|
52
|
|
- iob_put ( iobuf, ( mtu - iob_len ( iobuf ) ) );
|
53
|
|
-
|
54
|
|
- /* Enqueue I/O buffer */
|
55
|
|
- if ( ( rc = usb_stream ( &hubdev->intr, iobuf, 0 ) ) != 0 ) {
|
56
|
|
- DBGC ( hubdev, "HUB %s could not enqueue interrupt: "
|
57
|
|
- "%s\n", hubdev->name, strerror ( rc ) );
|
58
|
|
- /* Leave in available list and wait for next refill */
|
59
|
|
- return;
|
60
|
|
- }
|
61
|
|
-
|
62
|
|
- /* Remove from available list */
|
63
|
|
- list_del ( &iobuf->list );
|
|
45
|
+ /* Refill interrupt endpoint */
|
|
46
|
+ if ( ( rc = usb_refill ( &hubdev->intr ) ) != 0 ) {
|
|
47
|
+ DBGC ( hubdev, "HUB %s could not refill interrupt: %s\n",
|
|
48
|
+ hubdev->name, strerror ( rc ) );
|
|
49
|
+ /* Continue attempting to refill */
|
|
50
|
+ return;
|
64
|
51
|
}
|
65
|
52
|
|
66
|
53
|
/* Stop refill process */
|
|
@@ -119,9 +106,6 @@ static void hub_complete ( struct usb_endpoint *ep,
|
119
|
106
|
}
|
120
|
107
|
|
121
|
108
|
done:
|
122
|
|
- /* Return I/O buffer to available list */
|
123
|
|
- list_add_tail ( &iobuf->list, &hubdev->intrs );
|
124
|
|
-
|
125
|
109
|
/* Start refill process */
|
126
|
110
|
process_add ( &hubdev->refill );
|
127
|
111
|
}
|
|
@@ -140,8 +124,6 @@ static struct usb_endpoint_driver_operations usb_hub_intr_operations = {
|
140
|
124
|
static int hub_open ( struct usb_hub *hub ) {
|
141
|
125
|
struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
|
142
|
126
|
struct usb_device *usb = hubdev->usb;
|
143
|
|
- struct io_buffer *iobuf;
|
144
|
|
- struct io_buffer *tmp;
|
145
|
127
|
unsigned int i;
|
146
|
128
|
int rc;
|
147
|
129
|
|
|
@@ -156,16 +138,6 @@ static int hub_open ( struct usb_hub *hub ) {
|
156
|
138
|
}
|
157
|
139
|
}
|
158
|
140
|
|
159
|
|
- /* Allocate I/O buffers */
|
160
|
|
- for ( i = 0 ; i < USB_HUB_INTR_FILL ; i++ ) {
|
161
|
|
- iobuf = alloc_iob ( hubdev->intr.mtu );
|
162
|
|
- if ( ! iobuf ) {
|
163
|
|
- rc = -ENOMEM;
|
164
|
|
- goto err_alloc_iob;
|
165
|
|
- }
|
166
|
|
- list_add ( &iobuf->list, &hubdev->intrs );
|
167
|
|
- }
|
168
|
|
-
|
169
|
141
|
/* Open interrupt endpoint */
|
170
|
142
|
if ( ( rc = usb_endpoint_open ( &hubdev->intr ) ) != 0 ) {
|
171
|
143
|
DBGC ( hubdev, "HUB %s could not register interrupt: %s\n",
|
|
@@ -183,11 +155,6 @@ static int hub_open ( struct usb_hub *hub ) {
|
183
|
155
|
|
184
|
156
|
usb_endpoint_close ( &hubdev->intr );
|
185
|
157
|
err_open:
|
186
|
|
- err_alloc_iob:
|
187
|
|
- list_for_each_entry_safe ( iobuf, tmp, &hubdev->intrs, list ) {
|
188
|
|
- list_del ( &iobuf->list );
|
189
|
|
- free_iob ( iobuf );
|
190
|
|
- }
|
191
|
158
|
err_power:
|
192
|
159
|
return rc;
|
193
|
160
|
}
|
|
@@ -199,20 +166,12 @@ static int hub_open ( struct usb_hub *hub ) {
|
199
|
166
|
*/
|
200
|
167
|
static void hub_close ( struct usb_hub *hub ) {
|
201
|
168
|
struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
|
202
|
|
- struct io_buffer *iobuf;
|
203
|
|
- struct io_buffer *tmp;
|
204
|
169
|
|
205
|
170
|
/* Close interrupt endpoint */
|
206
|
171
|
usb_endpoint_close ( &hubdev->intr );
|
207
|
172
|
|
208
|
173
|
/* Stop refill process */
|
209
|
174
|
process_del ( &hubdev->refill );
|
210
|
|
-
|
211
|
|
- /* Free I/O buffers */
|
212
|
|
- list_for_each_entry_safe ( iobuf, tmp, &hubdev->intrs, list ) {
|
213
|
|
- list_del ( &iobuf->list );
|
214
|
|
- free_iob ( iobuf );
|
215
|
|
- }
|
216
|
175
|
}
|
217
|
176
|
|
218
|
177
|
/**
|
|
@@ -415,7 +374,7 @@ static int hub_probe ( struct usb_function *func,
|
415
|
374
|
hubdev->features =
|
416
|
375
|
( enhanced ? USB_HUB_FEATURES_ENHANCED : USB_HUB_FEATURES );
|
417
|
376
|
usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
|
418
|
|
- INIT_LIST_HEAD ( &hubdev->intrs );
|
|
377
|
+ usb_refill_init ( &hubdev->intr, 0, USB_HUB_INTR_FILL );
|
419
|
378
|
process_init_stopped ( &hubdev->refill, &hub_refill_desc, NULL );
|
420
|
379
|
|
421
|
380
|
/* Locate hub interface descriptor */
|
|
@@ -510,7 +469,6 @@ static void hub_remove ( struct usb_function *func ) {
|
510
|
469
|
/* Unregister hub */
|
511
|
470
|
unregister_usb_hub ( hubdev->hub );
|
512
|
471
|
assert ( ! process_running ( &hubdev->refill ) );
|
513
|
|
- assert ( list_empty ( &hubdev->intrs ) );
|
514
|
472
|
|
515
|
473
|
/* Free hub */
|
516
|
474
|
free_usb_hub ( hubdev->hub );
|