iPXE
usbhub.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <assert.h>
31 #include <byteswap.h>
32 #include <ipxe/usb.h>
33 #include "usbhub.h"
34 
35 /** @file
36  *
37  * USB hub driver
38  *
39  */
40 
41 /**
42  * Refill interrupt ring
43  *
44  * @v hubdev Hub device
45  */
46 static void hub_refill ( struct usb_hub_device *hubdev ) {
47  int rc;
48 
49  /* Refill interrupt endpoint */
50  if ( ( rc = usb_refill ( &hubdev->intr ) ) != 0 ) {
51  DBGC ( hubdev, "HUB %s could not refill interrupt: %s\n",
52  hubdev->name, strerror ( rc ) );
53  /* Continue attempting to refill */
54  return;
55  }
56 
57  /* Stop refill process */
58  process_del ( &hubdev->refill );
59 }
60 
61 /** Refill process descriptor */
63  PROC_DESC ( struct usb_hub_device, refill, hub_refill );
64 
65 /**
66  * Complete interrupt transfer
67  *
68  * @v ep USB endpoint
69  * @v iobuf I/O buffer
70  * @v rc Completion status code
71  */
72 static void hub_complete ( struct usb_endpoint *ep,
73  struct io_buffer *iobuf, int rc ) {
74  struct usb_hub_device *hubdev =
75  container_of ( ep, struct usb_hub_device, intr );
76  struct usb_hub *hub = hubdev->hub;
77  uint8_t *data = iobuf->data;
78  unsigned int bits = ( 8 * iob_len ( iobuf ) );
79  unsigned int i;
80 
81  /* Ignore packets cancelled when the endpoint closes */
82  if ( ! ep->open )
83  goto done;
84 
85  /* Ignore packets with errors */
86  if ( rc != 0 ) {
87  DBGC ( hubdev, "HUB %s interrupt failed: %s\n",
88  hubdev->name, strerror ( rc ) );
89  DBGC_HDA ( hubdev, 0, iobuf->data, iob_len ( iobuf ) );
90  goto done;
91  }
92 
93  /* Report any port status changes */
94  for ( i = 1 ; i <= hub->ports ; i++ ) {
95 
96  /* Sanity check */
97  if ( i > bits ) {
98  DBGC ( hubdev, "HUB %s underlength interrupt:\n",
99  hubdev->name );
100  DBGC_HDA ( hubdev, 0, iobuf->data, iob_len ( iobuf ) );
101  goto done;
102  }
103 
104  /* Report port status change if applicable */
105  if ( data[ i / 8 ] & ( 1 << ( i % 8 ) ) ) {
106  DBGC2 ( hubdev, "HUB %s port %d status changed\n",
107  hubdev->name, i );
108  usb_port_changed ( usb_port ( hub, i ) );
109  }
110  }
111 
112  done:
113  /* Start refill process */
114  process_add ( &hubdev->refill );
115 }
116 
117 /** Interrupt endpoint operations */
120 };
121 
122 /**
123  * Open hub
124  *
125  * @v hub USB hub
126  * @ret rc Return status code
127  */
128 static int hub_open ( struct usb_hub *hub ) {
129  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
130  struct usb_device *usb = hubdev->usb;
131  unsigned int i;
132  int rc;
133 
134  /* Ensure ports are powered */
135  for ( i = 1 ; i <= hub->ports ; i++ ) {
136  if ( ( rc = usb_hub_set_port_feature ( usb, i,
138  0 ) ) != 0 ) {
139  DBGC ( hubdev, "HUB %s port %d could not apply power: "
140  "%s\n", hubdev->name, i, strerror ( rc ) );
141  goto err_power;
142  }
143  }
144 
145  /* Open interrupt endpoint */
146  if ( ( rc = usb_endpoint_open ( &hubdev->intr ) ) != 0 ) {
147  DBGC ( hubdev, "HUB %s could not register interrupt: %s\n",
148  hubdev->name, strerror ( rc ) );
149  goto err_open;
150  }
151 
152  /* Start refill process */
153  process_add ( &hubdev->refill );
154 
155  /* Refill interrupt ring */
156  hub_refill ( hubdev );
157 
158  /* Delay to allow ports to stabilise on out-of-spec hubs */
159  if ( hubdev->flags & USB_HUB_SLOW_START )
161 
162  return 0;
163 
164  usb_endpoint_close ( &hubdev->intr );
165  err_open:
166  err_power:
167  return rc;
168 }
169 
170 /**
171  * Close hub
172  *
173  * @v hub USB hub
174  */
175 static void hub_close ( struct usb_hub *hub ) {
176  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
177 
178  /* Close interrupt endpoint */
179  usb_endpoint_close ( &hubdev->intr );
180 
181  /* Stop refill process */
182  process_del ( &hubdev->refill );
183 }
184 
185 /**
186  * Enable port
187  *
188  * @v hub USB hub
189  * @v port USB port
190  * @ret rc Return status code
191  */
192 static int hub_enable ( struct usb_hub *hub, struct usb_port *port ) {
193  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
194  struct usb_device *usb = hubdev->usb;
196  unsigned int current;
197  unsigned int i;
198  int rc;
199 
200  /* Initiate reset if applicable */
201  if ( ( hub->protocol < USB_PROTO_3_0 ) &&
202  ( ( rc = usb_hub_set_port_feature ( usb, port->address,
203  USB_HUB_PORT_RESET, 0 ) )!=0)){
204  DBGC ( hubdev, "HUB %s port %d could not initiate reset: %s\n",
205  hubdev->name, port->address, strerror ( rc ) );
206  return rc;
207  }
208 
209  /* Wait for port to become enabled */
210  for ( i = 0 ; i < USB_HUB_ENABLE_MAX_WAIT_MS ; i++ ) {
211 
212  /* Check for port being enabled */
213  if ( ( rc = usb_hub_get_port_status ( usb, port->address,
214  &status ) ) != 0 ) {
215  DBGC ( hubdev, "HUB %s port %d could not get status: "
216  "%s\n", hubdev->name, port->address,
217  strerror ( rc ) );
218  return rc;
219  }
220  current = le16_to_cpu ( status.current );
221  if ( current & ( 1 << USB_HUB_PORT_ENABLE ) )
222  return 0;
223 
224  /* Delay */
225  mdelay ( 1 );
226  }
227 
228  DBGC ( hubdev, "HUB %s port %d timed out waiting for enable\n",
229  hubdev->name, port->address );
230  return -ETIMEDOUT;
231 }
232 
233 /**
234  * Disable port
235  *
236  * @v hub USB hub
237  * @v port USB port
238  * @ret rc Return status code
239  */
240 static int hub_disable ( struct usb_hub *hub, struct usb_port *port ) {
241  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
242  struct usb_device *usb = hubdev->usb;
243  int rc;
244 
245  /* Disable port */
246  if ( ( rc = usb_hub_clear_port_feature ( usb, port->address,
247  USB_HUB_PORT_ENABLE, 0 ) )!=0){
248  DBGC ( hubdev, "HUB %s port %d could not disable: %s\n",
249  hubdev->name, port->address, strerror ( rc ) );
250  return rc;
251  }
252 
253  return 0;
254 }
255 
256 /**
257  * Clear port status change bits
258  *
259  * @v hubdev USB hub device
260  * @v port Port number
261  * @v changed Port status change bits
262  * @ret rc Return status code
263  */
264 static int hub_clear_changes ( struct usb_hub_device *hubdev,
265  unsigned int port, uint16_t changed ) {
266  struct usb_device *usb = hubdev->usb;
267  unsigned int bit;
268  unsigned int feature;
269  int rc;
270 
271  /* Clear each set bit */
272  for ( bit = 0 ; bit < 16 ; bit++ ) {
273 
274  /* Skip unset bits */
275  if ( ! ( changed & ( 1 << bit ) ) )
276  continue;
277 
278  /* Skip unused features */
280  if ( ! ( hubdev->features & ( 1 << feature ) ) )
281  continue;
282 
283  /* Clear bit */
284  if ( ( rc = usb_hub_clear_port_feature ( usb, port,
285  feature, 0 ) ) != 0 ) {
286  DBGC ( hubdev, "HUB %s port %d could not clear feature "
287  "%d: %s\n", hubdev->name, port, feature,
288  strerror ( rc ) );
289  return rc;
290  }
291  }
292 
293  return 0;
294 }
295 
296 /**
297  * Update port speed
298  *
299  * @v hub USB hub
300  * @v port USB port
301  * @ret rc Return status code
302  */
303 static int hub_speed ( struct usb_hub *hub, struct usb_port *port ) {
304  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
305  struct usb_device *usb = hubdev->usb;
307  unsigned int current;
308  unsigned int changed;
309  int rc;
310 
311  /* Get port status */
312  if ( ( rc = usb_hub_get_port_status ( usb, port->address,
313  &status ) ) != 0 ) {
314  DBGC ( hubdev, "HUB %s port %d could not get status: %s\n",
315  hubdev->name, port->address, strerror ( rc ) );
316  return rc;
317  }
318  current = le16_to_cpu ( status.current );
319  changed = le16_to_cpu ( status.changed );
320  DBGC2 ( hubdev, "HUB %s port %d status is %04x:%04x\n",
321  hubdev->name, port->address, changed, current );
322 
323  /* Update port speed */
324  if ( current & ( 1 << USB_HUB_PORT_CONNECTION ) ) {
325  if ( hub->protocol >= USB_PROTO_3_0 ) {
326  port->speed = USB_SPEED_SUPER;
327  } else if ( current & ( 1 << USB_HUB_PORT_LOW_SPEED ) ) {
328  port->speed = USB_SPEED_LOW;
329  } else if ( current & ( 1 << USB_HUB_PORT_HIGH_SPEED ) ) {
330  port->speed = USB_SPEED_HIGH;
331  } else {
332  port->speed = USB_SPEED_FULL;
333  }
334  } else {
335  port->speed = USB_SPEED_NONE;
336  }
337 
338  /* Record disconnections */
339  port->disconnected |= ( changed & ( 1 << USB_HUB_PORT_CONNECTION ) );
340 
341  /* Clear port status change bits */
342  if ( ( rc = hub_clear_changes ( hubdev, port->address, changed ) ) != 0)
343  return rc;
344 
345  return 0;
346 }
347 
348 /**
349  * Clear transaction translator buffer
350  *
351  * @v hub USB hub
352  * @v port USB port
353  * @v ep USB endpoint
354  * @ret rc Return status code
355  */
356 static int hub_clear_tt ( struct usb_hub *hub, struct usb_port *port,
357  struct usb_endpoint *ep ) {
358  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
359  struct usb_device *usb = hubdev->usb;
360  int rc;
361 
362  /* Clear transaction translator buffer. All hubs must support
363  * single-TT operation; we simplify our code by supporting
364  * only this configuration.
365  */
366  if ( ( rc = usb_hub_clear_tt_buffer ( usb, ep->usb->address,
367  ep->address, ep->attributes,
368  USB_HUB_TT_SINGLE ) ) != 0 ) {
369  DBGC ( hubdev, "HUB %s port %d could not clear TT buffer: %s\n",
370  hubdev->name, port->address, strerror ( rc ) );
371  return rc;
372  }
373 
374  return 0;
375 }
376 
377 /** USB hub operations */
379  .open = hub_open,
380  .close = hub_close,
381  .enable = hub_enable,
382  .disable = hub_disable,
383  .speed = hub_speed,
384  .clear_tt = hub_clear_tt,
385 };
386 
387 /**
388  * Probe USB hub
389  *
390  * @v func USB function
391  * @v config Configuration descriptor
392  * @ret rc Return status code
393  */
394 static int hub_probe ( struct usb_function *func,
395  struct usb_configuration_descriptor *config ) {
396  struct usb_device *usb = func->usb;
397  struct usb_bus *bus = usb->port->hub->bus;
398  struct usb_hub_device *hubdev;
400  union usb_hub_descriptor desc;
401  unsigned int depth;
402  unsigned int ports;
403  int enhanced;
404  int rc;
405 
406  /* Allocate and initialise structure */
407  hubdev = zalloc ( sizeof ( *hubdev ) );
408  if ( ! hubdev ) {
409  rc = -ENOMEM;
410  goto err_alloc;
411  }
412  enhanced = ( usb->port->protocol >= USB_PROTO_3_0 );
413  hubdev->name = func->name;
414  hubdev->usb = usb;
415  hubdev->features =
417  hubdev->flags = func->id->driver_data;
418  usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
419  usb_refill_init ( &hubdev->intr, 0, 0, USB_HUB_INTR_FILL );
421 
422  /* Locate hub interface descriptor */
423  interface = usb_interface_descriptor ( config, func->interface[0], 0 );
424  if ( ! interface ) {
425  DBGC ( hubdev, "HUB %s has no interface descriptor\n",
426  hubdev->name );
427  rc = -EINVAL;
428  goto err_interface;
429  }
430 
431  /* Locate interrupt endpoint descriptor */
432  if ( ( rc = usb_endpoint_described ( &hubdev->intr, config, interface,
433  USB_INTERRUPT_IN, 0 ) ) != 0 ) {
434  DBGC ( hubdev, "HUB %s could not describe interrupt endpoint: "
435  "%s\n", hubdev->name, strerror ( rc ) );
436  goto err_endpoint;
437  }
438 
439  /* Set hub depth */
440  depth = usb_depth ( usb );
441  if ( enhanced ) {
442  if ( ( rc = usb_hub_set_hub_depth ( usb, depth ) ) != 0 ) {
443  DBGC ( hubdev, "HUB %s could not set hub depth to %d: "
444  "%s\n", hubdev->name, depth, strerror ( rc ) );
445  goto err_set_hub_depth;
446  }
447  }
448 
449  /* Get hub descriptor */
450  if ( ( rc = usb_hub_get_descriptor ( usb, enhanced, &desc ) ) != 0 ) {
451  DBGC ( hubdev, "HUB %s could not get hub descriptor: %s\n",
452  hubdev->name, strerror ( rc ) );
453  goto err_hub_descriptor;
454  }
455  ports = desc.basic.ports;
456  DBGC ( hubdev, "HUB %s has %d ports at depth %d%s\n", hubdev->name,
457  ports, depth, ( enhanced ? " (enhanced)" : "" ) );
458 
459  /* Allocate hub */
460  hubdev->hub = alloc_usb_hub ( bus, usb, ports, &hub_operations );
461  if ( ! hubdev->hub ) {
462  rc = -ENOMEM;
463  goto err_alloc_hub;
464  }
465  usb_hub_set_drvdata ( hubdev->hub, hubdev );
466 
467  /* Register hub */
468  if ( ( rc = register_usb_hub ( hubdev->hub ) ) != 0 ) {
469  DBGC ( hubdev, "HUB %s could not register: %s\n",
470  hubdev->name, strerror ( rc ) );
471  goto err_register_hub;
472  }
473 
474  usb_func_set_drvdata ( func, hubdev );
475  return 0;
476 
477  unregister_usb_hub ( hubdev->hub );
478  err_register_hub:
479  free_usb_hub ( hubdev->hub );
480  err_alloc_hub:
481  err_hub_descriptor:
482  err_set_hub_depth:
483  err_endpoint:
484  err_interface:
485  free ( hubdev );
486  err_alloc:
487  return rc;
488 }
489 
490 /**
491  * Remove USB hub
492  *
493  * @v func USB function
494  * @ret rc Return status code
495  */
496 static void hub_remove ( struct usb_function *func ) {
497  struct usb_hub_device *hubdev = usb_func_get_drvdata ( func );
498  struct usb_hub *hub = hubdev->hub;
499  struct usb_device *usb = hubdev->usb;
500  struct usb_port *port;
501  unsigned int i;
502 
503  /* If hub has been unplugged, mark all ports as unplugged */
504  if ( usb->port->disconnected ) {
505  for ( i = 1 ; i <= hub->ports ; i++ ) {
506  port = usb_port ( hub, i );
507  port->disconnected = 1;
508  port->speed = USB_SPEED_NONE;
509  }
510  }
511 
512  /* Unregister hub */
513  unregister_usb_hub ( hubdev->hub );
514  assert ( ! process_running ( &hubdev->refill ) );
515 
516  /* Free hub */
517  free_usb_hub ( hubdev->hub );
518 
519  /* Free hub device */
520  free ( hubdev );
521 }
522 
523 /** USB hub device IDs */
524 static struct usb_device_id hub_ids[] = {
525  {
526  .name = "avocent-hub",
527  .vendor = 0x0624,
528  .product = 0x0248,
529  .driver_data = USB_HUB_SLOW_START,
530  },
531  {
532  .name = "hub",
533  .vendor = USB_ANY_ID,
534  .product = USB_ANY_ID,
535  },
536 };
537 
538 /** USB hub driver */
539 struct usb_driver usb_hub_driver __usb_driver = {
540  .ids = hub_ids,
541  .id_count = ( sizeof ( hub_ids ) / sizeof ( hub_ids[0] ) ),
542  .class = USB_CLASS_ID ( USB_CLASS_HUB, 0, USB_ANY_ID ),
543  .score = USB_SCORE_NORMAL,
544  .probe = hub_probe,
545  .remove = hub_remove,
546 };
#define USB_HUB_PORT_ENABLE
Port enabled/disabled feature.
Definition: usbhub.h:73
A USB driver.
Definition: usb.h:1363
#define EINVAL
Invalid argument.
Definition: errno.h:428
static void hub_close(struct usb_hub *hub)
Close hub.
Definition: usbhub.c:175
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
A USB device ID.
Definition: usb.h:1317
void(* complete)(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer.
Definition: usb.h:481
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition: usb.h:701
int disconnected
Port disconnection has been detected.
Definition: usb.h:810
const char * name
Name.
Definition: usb.h:659
A USB hub.
Definition: usb.h:824
static int usb_hub_get_descriptor(struct usb_device *usb, int enhanced, union usb_hub_descriptor *data)
Get hub descriptor.
Definition: usbhub.h:146
#define USB_HUB_SLOW_START_DELAY_MS
Additional setting delay for out-of-spec hubs.
Definition: usbhub.h:273
static unsigned int unsigned int bit
Definition: bigint.h:205
const char * name
Name.
Definition: usb.h:1319
unsigned int features
Features.
Definition: usbhub.h:259
void unregister_usb_hub(struct usb_hub *hub)
Unregister USB hub.
Definition: usb.c:1966
static int hub_clear_changes(struct usb_hub_device *hubdev, unsigned int port, uint16_t changed)
Clear port status change bits.
Definition: usbhub.c:264
Error codes.
Low speed (1.5Mbps)
Definition: usb.h:48
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbhub.h:264
#define DBGC(...)
Definition: compiler.h:505
A process descriptor.
Definition: process.h:31
struct usb_device * usb
Currently attached device (if in use)
Definition: usb.h:818
int usb_endpoint_open(struct usb_endpoint *ep)
Open USB endpoint.
Definition: usb.c:293
static int usb_hub_clear_tt_buffer(struct usb_device *usb, unsigned int device, unsigned int endpoint, unsigned int attributes, unsigned int tt_port)
Clear transaction translator buffer.
Definition: usbhub.h:233
#define USB_HUB_PORT_HIGH_SPEED
High-speed device attached.
Definition: usbhub.h:85
unsigned int protocol
Port protocol.
Definition: usb.h:802
#define USB_HUB_INTR_FILL
Interrupt ring fill level.
Definition: usbhub.h:279
struct usb_hub_descriptor_enhanced enhanced
Enhanced hub descriptor.
Definition: usbhub.h:58
#define USB_INTERRUPT_IN
Interrupt IN endpoint (internal) type.
Definition: usb.h:287
uint8_t ports
Number of ports.
Definition: usbhub.h:24
static int usb_hub_get_port_status(struct usb_device *usb, unsigned int port, struct usb_hub_port_status *status)
Get port status.
Definition: usbhub.h:168
Super speed (5Gbps)
Definition: usb.h:54
void usb_endpoint_close(struct usb_endpoint *ep)
Close USB endpoint.
Definition: usb.c:370
int open
Endpoint is open.
Definition: usb.h:404
struct usb_device * usb
USB device.
Definition: usbhub.h:255
int usb_endpoint_described(struct usb_endpoint *ep, struct usb_configuration_descriptor *config, struct usb_interface_descriptor *interface, unsigned int type, unsigned int index)
Describe USB endpoint from device configuration.
Definition: usb.c:241
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
struct process refill
Interrupt endpoint refill process.
Definition: usbhub.h:266
USB hub driver operations.
Definition: usb.h:869
int usb_refill(struct usb_endpoint *ep)
Refill endpoint.
Definition: usb.c:642
unsigned int address
Device address, if assigned.
Definition: usb.h:716
static struct usb_device_id hub_ids[]
USB hub device IDs.
Definition: usbhub.c:524
static int hub_enable(struct usb_hub *hub, struct usb_port *port)
Enable port.
Definition: usbhub.c:192
void usb_port_changed(struct usb_port *port)
Report port status change.
Definition: usb.c:1794
union ena_feature feature
Feature.
Definition: ena.h:14
static int usb_hub_set_hub_depth(struct usb_device *usb, unsigned int depth)
Set hub depth.
Definition: usbhub.h:217
static int hub_clear_tt(struct usb_hub *hub, struct usb_port *port, struct usb_endpoint *ep)
Clear transaction translator buffer.
Definition: usbhub.c:356
struct usb_device_id * id
Driver device ID.
Definition: usb.h:674
uint8_t status
Status.
Definition: ena.h:16
#define USB_HUB_ENABLE_MAX_WAIT_MS
Maximum time to wait for port to become enabled.
Definition: usbhub.h:285
#define USB_HUB_PORT_POWER
Port power feature.
Definition: usbhub.h:79
A USB port.
Definition: usb.h:796
#define ENOMEM
Not enough space.
Definition: errno.h:534
A USB endpoint.
Definition: usb.h:389
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
u8 port
Port number.
Definition: CIB_PRM.h:31
A USB interface descriptor.
Definition: usb.h:230
static int hub_open(struct usb_hub *hub)
Open hub.
Definition: usbhub.c:128
struct usb_port * port
USB port.
Definition: usb.h:710
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
USB 3.0.
Definition: usb.h:24
An object interface.
Definition: interface.h:109
Not connected.
Definition: usb.h:46
uint8_t intr
Interrupts enabled.
Definition: ena.h:14
#define DBGC_HDA(...)
Definition: compiler.h:506
A USB hub device.
Definition: usbhub.h:251
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition: usb.h:601
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
A USB hub descriptor.
Definition: usbhub.h:52
#define USB_HUB_TT_SINGLE
Transaction translator port value for single-TT hubs.
Definition: usbhub.h:248
static int usb_hub_clear_port_feature(struct usb_device *usb, unsigned int port, unsigned int feature, unsigned int index)
Clear port feature.
Definition: usbhub.h:185
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition: usb.h:690
unsigned int ports
Number of ports.
Definition: usb.h:834
#define USB_HUB_C_FEATURE(bit)
Calculate feature from change bit number.
Definition: usbhub.h:109
A USB device.
Definition: usb.h:706
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
static void hub_refill(struct usb_hub_device *hubdev)
Refill interrupt ring.
Definition: usbhub.c:46
unsigned int flags
Flags.
Definition: usbhub.h:261
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
static struct usb_hub_driver_operations hub_operations
USB hub operations.
Definition: usbhub.c:378
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition: usb.h:1345
Normal driver.
Definition: usb.h:1406
unsigned int usb_depth(struct usb_device *usb)
Get USB depth.
Definition: usb.c:2241
unsigned char uint8_t
Definition: stdint.h:10
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:145
struct usb_device * usb
USB device.
Definition: usb.h:661
static void usb_endpoint_init(struct usb_endpoint *ep, struct usb_device *usb, struct usb_endpoint_driver_operations *driver)
Initialise USB endpoint.
Definition: usb.h:525
#define le16_to_cpu(value)
Definition: byteswap.h:112
static struct usb_endpoint_driver_operations usb_hub_intr_operations
Interrupt endpoint operations.
Definition: usbhub.c:118
#define USB_HUB_PORT_CONNECTION
Current connect status feature.
Definition: usbhub.h:70
unsigned long driver_data
Arbitrary driver data.
Definition: usb.h:1325
Port status.
Definition: usbhub.h:62
static int process_running(struct process *process)
Check if process is running.
Definition: process.h:175
#define USB_CLASS_HUB
Class code for USB hubs.
Definition: usb.h:155
static int hub_disable(struct usb_hub *hub, struct usb_port *port)
Disable port.
Definition: usbhub.c:240
void free_usb_hub(struct usb_hub *hub)
Free USB hub.
Definition: usb.c:1999
uint16_t changed
Changed status.
Definition: usbhub.h:66
A named feature.
Definition: features.h:78
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
A USB configuration descriptor.
Definition: usb.h:195
#define USB_HUB_PORT_LOW_SPEED
Low-speed device attached.
Definition: usbhub.h:82
#define USB_HUB_FEATURES
USB features.
Definition: usbhub.h:112
static volatile void * bits
Definition: bitops.h:27
#define DBGC2(...)
Definition: compiler.h:522
#define USB_ANY_ID
Match-anything ID.
Definition: usb.h:1329
Universal Serial Bus (USB)
void * data
Start of data.
Definition: iobuf.h:44
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition: process.h:82
struct usb_hub * hub
USB hub.
Definition: usb.h:798
High speed (480Mbps)
Definition: usb.h:52
struct usb_endpoint * ep[32]
Endpoint list.
Definition: usb.h:728
static void hub_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete interrupt transfer.
Definition: usbhub.c:72
static int usb_hub_set_port_feature(struct usb_device *usb, unsigned int port, unsigned int feature, unsigned int index)
Set port feature.
Definition: usbhub.h:202
#define USB_HUB_PORT_RESET
Port reset feature.
Definition: usbhub.h:76
int register_usb_hub(struct usb_hub *hub)
Register USB hub.
Definition: usb.c:1912
static void usb_hub_set_drvdata(struct usb_hub *hub, void *priv)
Set USB hub driver private data.
Definition: usb.h:920
struct usb_device * usb
USB device.
Definition: usb.h:391
#define USB_HUB_FEATURES_ENHANCED
USB features for enhanced hubs.
Definition: usbhub.h:120
static struct usb_port * usb_port(struct usb_hub *hub, unsigned int address)
Get USB port.
Definition: usb.h:943
#define USB_HUB_SLOW_START
Hub requires additional settling delay.
Definition: usbhub.h:270
static void hub_remove(struct usb_function *func)
Remove USB hub.
Definition: usbhub.c:496
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
unsigned int protocol
Hub protocol.
Definition: usb.h:832
struct usb_hub_descriptor_basic basic
Basic hub descriptor.
Definition: usbhub.h:56
USB endpoint driver operations.
Definition: usb.h:474
A USB function.
Definition: usb.h:657
static int hub_speed(struct usb_hub *hub, struct usb_port *port)
Update port speed.
Definition: usbhub.c:303
struct usb_bus * bus
USB bus.
Definition: usb.h:828
uint16_t current
Current status.
Definition: usbhub.h:64
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
const char * name
Name.
Definition: usbhub.h:253
String functions.
struct usb_driver usb_hub_driver __usb_driver
USB hub driver.
Definition: usbhub.c:539
A USB bus.
Definition: usb.h:949
unsigned int attributes
Attributes.
Definition: usb.h:395
uint8_t interface
Interface number.
Definition: usb.h:234
uint8_t bus
Bus.
Definition: edd.h:14
Full speed (12Mbps)
Definition: usb.h:50
struct bofm_section_header done
Definition: bofm_test.c:46
static struct process_descriptor hub_refill_desc
Refill process descriptor.
Definition: usbhub.c:62
unsigned int address
Endpoint address.
Definition: usb.h:393
static int hub_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe USB hub.
Definition: usbhub.c:394
static void * usb_hub_get_drvdata(struct usb_hub *hub)
Get USB hub driver private data.
Definition: usb.h:931
int(* open)(struct usb_hub *hub)
Open hub.
Definition: usb.h:875
struct usb_device_id * ids
USB ID table.
Definition: usb.h:1365
A persistent I/O buffer.
Definition: iobuf.h:32
USB hubs.
struct usb_hub * alloc_usb_hub(struct usb_bus *bus, struct usb_device *usb, unsigned int ports, struct usb_hub_driver_operations *driver)
Allocate USB hub.
Definition: usb.c:1873