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