iPXE
Functions | Variables
usbhub.c File Reference

USB hub driver. More...

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/usb.h>
#include "usbhub.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static void hub_refill (struct usb_hub_device *hubdev)
 Refill interrupt ring. More...
 
static void hub_complete (struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
 Complete interrupt transfer. More...
 
static int hub_open (struct usb_hub *hub)
 Open hub. More...
 
static void hub_close (struct usb_hub *hub)
 Close hub. More...
 
static int hub_enable (struct usb_hub *hub, struct usb_port *port)
 Enable port. More...
 
static int hub_disable (struct usb_hub *hub, struct usb_port *port)
 Disable port. More...
 
static int hub_clear_changes (struct usb_hub_device *hubdev, unsigned int port, uint16_t changed)
 Clear port status change bits. More...
 
static int hub_speed (struct usb_hub *hub, struct usb_port *port)
 Update port speed. More...
 
static int hub_clear_tt (struct usb_hub *hub, struct usb_port *port, struct usb_endpoint *ep)
 Clear transaction translator buffer. More...
 
static int hub_probe (struct usb_function *func, struct usb_configuration_descriptor *config)
 Probe USB hub. More...
 
static void hub_remove (struct usb_function *func)
 Remove USB hub. More...
 

Variables

static struct process_descriptor hub_refill_desc
 Refill process descriptor. More...
 
static struct usb_endpoint_driver_operations usb_hub_intr_operations
 Interrupt endpoint operations. More...
 
static struct usb_hub_driver_operations hub_operations
 USB hub operations. More...
 
static struct usb_device_id hub_ids []
 USB hub device IDs. More...
 
struct usb_driver usb_hub_driver __usb_driver
 USB hub driver. More...
 

Detailed Description

USB hub driver.

Definition in file usbhub.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ hub_refill()

static void hub_refill ( struct usb_hub_device hubdev)
static

Refill interrupt ring.

Parameters
hubdevHub device

Definition at line 46 of file usbhub.c.

46  {
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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbhub.h:264
#define DBGC(...)
Definition: compiler.h:505
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
int usb_refill(struct usb_endpoint *ep)
Refill endpoint.
Definition: usb.c:710
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
const char * name
Name.
Definition: usbhub.h:253

References DBGC, usb_hub_device::intr, usb_hub_device::name, process_del(), rc, usb_hub_device::refill, strerror(), and usb_refill().

Referenced by hub_open().

◆ hub_complete()

static void hub_complete ( struct usb_endpoint ep,
struct io_buffer iobuf,
int  rc 
)
static

Complete interrupt transfer.

Parameters
epUSB endpoint
iobufI/O buffer
rcCompletion status code

Definition at line 72 of file usbhub.c.

73  {
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 
114  /* Recycle I/O buffer */
115  usb_recycle ( &hubdev->intr, iobuf );
116 
117  /* Start refill process */
118  process_add ( &hubdev->refill );
119 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A USB hub.
Definition: usb.h:826
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbhub.h:264
#define DBGC(...)
Definition: compiler.h:505
int open
Endpoint is open.
Definition: usb.h:404
struct process refill
Interrupt endpoint refill process.
Definition: usbhub.h:266
void usb_port_changed(struct usb_port *port)
Report port status change.
Definition: usb.c:1839
A USB port.
Definition: usb.h:798
static void usb_recycle(struct usb_endpoint *ep, struct io_buffer *iobuf)
Recycle I/O buffer.
Definition: usb.h:618
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
uint8_t intr
Interrupts enabled.
Definition: ena.h:14
#define DBGC_HDA(...)
Definition: compiler.h:506
A USB hub device.
Definition: usbhub.h:251
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
unsigned int ports
Number of ports.
Definition: usb.h:836
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
unsigned char uint8_t
Definition: stdint.h:10
static volatile void * bits
Definition: bitops.h:27
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:48
uint8_t data[48]
Additional event data.
Definition: ena.h:22
const char * name
Name.
Definition: usbhub.h:253
struct bofm_section_header done
Definition: bofm_test.c:46

References bits, container_of, data, io_buffer::data, DBGC, DBGC2, DBGC_HDA, done, usb_hub_device::hub, intr, usb_hub_device::intr, iob_len(), usb_hub_device::name, usb_endpoint::open, usb_hub::ports, process_add(), rc, usb_hub_device::refill, strerror(), usb_port_changed(), and usb_recycle().

◆ hub_open()

static int hub_open ( struct usb_hub hub)
static

Open hub.

Parameters
hubUSB hub
Return values
rcReturn status code

Definition at line 132 of file usbhub.c.

132  {
133  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
134  struct usb_device *usb = hubdev->usb;
135  unsigned int i;
136  int rc;
137 
138  /* Ensure ports are powered */
139  for ( i = 1 ; i <= hub->ports ; i++ ) {
140  if ( ( rc = usb_hub_set_port_feature ( usb, i,
142  0 ) ) != 0 ) {
143  DBGC ( hubdev, "HUB %s port %d could not apply power: "
144  "%s\n", hubdev->name, i, strerror ( rc ) );
145  goto err_power;
146  }
147  }
148 
149  /* Open interrupt endpoint */
150  if ( ( rc = usb_endpoint_open ( &hubdev->intr ) ) != 0 ) {
151  DBGC ( hubdev, "HUB %s could not register interrupt: %s\n",
152  hubdev->name, strerror ( rc ) );
153  goto err_open;
154  }
155 
156  /* Start refill process */
157  process_add ( &hubdev->refill );
158 
159  /* Refill interrupt ring */
160  hub_refill ( hubdev );
161 
162  /* Delay to allow ports to stabilise on out-of-spec hubs */
163  if ( hubdev->flags & USB_HUB_SLOW_START )
165 
166  return 0;
167 
168  usb_endpoint_close ( &hubdev->intr );
169  err_open:
170  err_power:
171  return rc;
172 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define USB_HUB_SLOW_START_DELAY_MS
Additional setting delay for out-of-spec hubs.
Definition: usbhub.h:273
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbhub.h:264
#define DBGC(...)
Definition: compiler.h:505
int usb_endpoint_open(struct usb_endpoint *ep)
Open USB endpoint.
Definition: usb.c:293
void usb_endpoint_close(struct usb_endpoint *ep)
Close USB endpoint.
Definition: usb.c:399
struct usb_device * usb
USB device.
Definition: usbhub.h:255
struct process refill
Interrupt endpoint refill process.
Definition: usbhub.h:266
#define USB_HUB_PORT_POWER
Port power feature.
Definition: usbhub.h:79
A USB hub device.
Definition: usbhub.h:251
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
unsigned int ports
Number of ports.
Definition: usb.h:836
A USB device.
Definition: usb.h:708
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
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
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_SLOW_START
Hub requires additional settling delay.
Definition: usbhub.h:270
const char * name
Name.
Definition: usbhub.h:253
static void * usb_hub_get_drvdata(struct usb_hub *hub)
Get USB hub driver private data.
Definition: usb.h:933

References DBGC, usb_hub_device::flags, usb_hub_device::hub, hub_refill(), usb_hub_device::intr, mdelay(), usb_hub_device::name, usb_hub::ports, process_add(), rc, usb_hub_device::refill, strerror(), usb_hub_device::usb, usb_endpoint_close(), usb_endpoint_open(), usb_hub_get_drvdata(), USB_HUB_PORT_POWER, usb_hub_set_port_feature(), USB_HUB_SLOW_START, and USB_HUB_SLOW_START_DELAY_MS.

◆ hub_close()

static void hub_close ( struct usb_hub hub)
static

Close hub.

Parameters
hubUSB hub

Definition at line 179 of file usbhub.c.

179  {
180  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
181 
182  /* Close interrupt endpoint */
183  usb_endpoint_close ( &hubdev->intr );
184 
185  /* Stop refill process */
186  process_del ( &hubdev->refill );
187 }
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbhub.h:264
void usb_endpoint_close(struct usb_endpoint *ep)
Close USB endpoint.
Definition: usb.c:399
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
A USB hub device.
Definition: usbhub.h:251
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
static void * usb_hub_get_drvdata(struct usb_hub *hub)
Get USB hub driver private data.
Definition: usb.h:933

References usb_hub_device::hub, usb_hub_device::intr, process_del(), usb_hub_device::refill, usb_endpoint_close(), and usb_hub_get_drvdata().

◆ hub_enable()

static int hub_enable ( struct usb_hub hub,
struct usb_port port 
)
static

Enable port.

Parameters
hubUSB hub
portUSB port
Return values
rcReturn status code

Definition at line 196 of file usbhub.c.

196  {
197  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
198  struct usb_device *usb = hubdev->usb;
200  unsigned int current;
201  unsigned int i;
202  int rc;
203 
204  /* Initiate reset if applicable */
205  if ( ( hub->protocol < USB_PROTO_3_0 ) &&
206  ( ( rc = usb_hub_set_port_feature ( usb, port->address,
207  USB_HUB_PORT_RESET, 0 ) )!=0)){
208  DBGC ( hubdev, "HUB %s port %d could not initiate reset: %s\n",
209  hubdev->name, port->address, strerror ( rc ) );
210  return rc;
211  }
212 
213  /* Wait for port to become enabled */
214  for ( i = 0 ; i < USB_HUB_ENABLE_MAX_WAIT_MS ; i++ ) {
215 
216  /* Check for port being enabled */
217  if ( ( rc = usb_hub_get_port_status ( usb, port->address,
218  &status ) ) != 0 ) {
219  DBGC ( hubdev, "HUB %s port %d could not get status: "
220  "%s\n", hubdev->name, port->address,
221  strerror ( rc ) );
222  return rc;
223  }
224  current = le16_to_cpu ( status.current );
225  if ( current & ( 1 << USB_HUB_PORT_ENABLE ) )
226  return 0;
227 
228  /* Delay */
229  mdelay ( 1 );
230  }
231 
232  DBGC ( hubdev, "HUB %s port %d timed out waiting for enable\n",
233  hubdev->name, port->address );
234  return -ETIMEDOUT;
235 }
#define USB_HUB_PORT_ENABLE
Port enabled/disabled feature.
Definition: usbhub.h:73
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
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
struct usb_device * usb
USB device.
Definition: usbhub.h:255
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
u8 port
Port number.
Definition: CIB_PRM.h:31
USB 3.0.
Definition: usb.h:24
A USB hub device.
Definition: usbhub.h:251
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
A USB device.
Definition: usb.h:708
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define le16_to_cpu(value)
Definition: byteswap.h:112
Port status.
Definition: usbhub.h:62
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
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
unsigned int protocol
Hub protocol.
Definition: usb.h:834
uint16_t current
Current status.
Definition: usbhub.h:64
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
const char * name
Name.
Definition: usbhub.h:253
static void * usb_hub_get_drvdata(struct usb_hub *hub)
Get USB hub driver private data.
Definition: usb.h:933

References usb_hub_port_status::current, DBGC, ETIMEDOUT, usb_hub_device::hub, le16_to_cpu, mdelay(), usb_hub_device::name, port, usb_hub::protocol, rc, status, strerror(), usb_hub_device::usb, USB_HUB_ENABLE_MAX_WAIT_MS, usb_hub_get_drvdata(), usb_hub_get_port_status(), USB_HUB_PORT_ENABLE, USB_HUB_PORT_RESET, usb_hub_set_port_feature(), and USB_PROTO_3_0.

◆ hub_disable()

static int hub_disable ( struct usb_hub hub,
struct usb_port port 
)
static

Disable port.

Parameters
hubUSB hub
portUSB port
Return values
rcReturn status code

Definition at line 244 of file usbhub.c.

244  {
245  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
246  struct usb_device *usb = hubdev->usb;
247  int rc;
248 
249  /* Disable port */
250  if ( ( hub->protocol < USB_PROTO_3_0 ) &&
251  ( ( rc = usb_hub_clear_port_feature ( usb, port->address,
253  0 ) ) != 0 ) ) {
254  DBGC ( hubdev, "HUB %s port %d could not disable: %s\n",
255  hubdev->name, port->address, strerror ( rc ) );
256  return rc;
257  }
258 
259  return 0;
260 }
#define USB_HUB_PORT_ENABLE
Port enabled/disabled feature.
Definition: usbhub.h:73
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
struct usb_device * usb
USB device.
Definition: usbhub.h:255
u8 port
Port number.
Definition: CIB_PRM.h:31
USB 3.0.
Definition: usb.h:24
A USB hub device.
Definition: usbhub.h:251
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
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
A USB device.
Definition: usb.h:708
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
unsigned int protocol
Hub protocol.
Definition: usb.h:834
const char * name
Name.
Definition: usbhub.h:253
static void * usb_hub_get_drvdata(struct usb_hub *hub)
Get USB hub driver private data.
Definition: usb.h:933

References DBGC, usb_hub_device::hub, usb_hub_device::name, port, usb_hub::protocol, rc, strerror(), usb_hub_device::usb, usb_hub_clear_port_feature(), usb_hub_get_drvdata(), USB_HUB_PORT_ENABLE, and USB_PROTO_3_0.

◆ hub_clear_changes()

static int hub_clear_changes ( struct usb_hub_device hubdev,
unsigned int  port,
uint16_t  changed 
)
static

Clear port status change bits.

Parameters
hubdevUSB hub device
portPort number
changedPort status change bits
Return values
rcReturn status code

Definition at line 270 of file usbhub.c.

271  {
272  struct usb_device *usb = hubdev->usb;
273  unsigned int bit;
274  unsigned int feature;
275  int rc;
276 
277  /* Clear each set bit */
278  for ( bit = 0 ; bit < 16 ; bit++ ) {
279 
280  /* Skip unset bits */
281  if ( ! ( changed & ( 1 << bit ) ) )
282  continue;
283 
284  /* Skip unused features */
286  if ( ! ( hubdev->features & ( 1 << feature ) ) )
287  continue;
288 
289  /* Clear bit */
290  if ( ( rc = usb_hub_clear_port_feature ( usb, port,
291  feature, 0 ) ) != 0 ) {
292  DBGC ( hubdev, "HUB %s port %d could not clear feature "
293  "%d: %s\n", hubdev->name, port, feature,
294  strerror ( rc ) );
295  return rc;
296  }
297  }
298 
299  return 0;
300 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static unsigned int unsigned int bit
Definition: bigint.h:208
unsigned int features
Features.
Definition: usbhub.h:259
#define DBGC(...)
Definition: compiler.h:505
struct usb_device * usb
USB device.
Definition: usbhub.h:255
union ena_feature feature
Feature.
Definition: ena.h:14
u8 port
Port number.
Definition: CIB_PRM.h:31
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
#define USB_HUB_C_FEATURE(bit)
Calculate feature from change bit number.
Definition: usbhub.h:109
A USB device.
Definition: usb.h:708
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A named feature.
Definition: features.h:78
const char * name
Name.
Definition: usbhub.h:253

References bit, DBGC, feature, usb_hub_device::features, usb_hub_device::name, port, rc, strerror(), usb_hub_device::usb, USB_HUB_C_FEATURE, and usb_hub_clear_port_feature().

Referenced by hub_speed().

◆ hub_speed()

static int hub_speed ( struct usb_hub hub,
struct usb_port port 
)
static

Update port speed.

Parameters
hubUSB hub
portUSB port
Return values
rcReturn status code

Definition at line 309 of file usbhub.c.

309  {
310  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
311  struct usb_device *usb = hubdev->usb;
313  unsigned int current;
314  unsigned int changed;
315  int rc;
316 
317  /* Get port status */
318  if ( ( rc = usb_hub_get_port_status ( usb, port->address,
319  &status ) ) != 0 ) {
320  DBGC ( hubdev, "HUB %s port %d could not get status: %s\n",
321  hubdev->name, port->address, strerror ( rc ) );
322  return rc;
323  }
324  current = le16_to_cpu ( status.current );
325  changed = le16_to_cpu ( status.changed );
326  DBGC2 ( hubdev, "HUB %s port %d status is %04x:%04x\n",
327  hubdev->name, port->address, changed, current );
328 
329  /* Update port speed */
330  if ( current & ( 1 << USB_HUB_PORT_CONNECTION ) ) {
331  if ( hub->protocol >= USB_PROTO_3_0 ) {
332  port->speed = USB_SPEED_SUPER;
333  } else if ( current & ( 1 << USB_HUB_PORT_LOW_SPEED ) ) {
334  port->speed = USB_SPEED_LOW;
335  } else if ( current & ( 1 << USB_HUB_PORT_HIGH_SPEED ) ) {
336  port->speed = USB_SPEED_HIGH;
337  } else {
338  port->speed = USB_SPEED_FULL;
339  }
340  } else {
341  port->speed = USB_SPEED_NONE;
342  }
343 
344  /* Record disconnections */
345  port->disconnected |= ( changed & ( 1 << USB_HUB_PORT_CONNECTION ) );
346 
347  /* Clear port status change bits */
348  if ( ( rc = hub_clear_changes ( hubdev, port->address, changed ) ) != 0)
349  return rc;
350 
351  return 0;
352 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int hub_clear_changes(struct usb_hub_device *hubdev, unsigned int port, uint16_t changed)
Clear port status change bits.
Definition: usbhub.c:270
Low speed (1.5Mbps)
Definition: usb.h:48
#define DBGC(...)
Definition: compiler.h:505
#define USB_HUB_PORT_HIGH_SPEED
High-speed device attached.
Definition: usbhub.h:85
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
struct usb_device * usb
USB device.
Definition: usbhub.h:255
uint8_t status
Status.
Definition: ena.h:16
u8 port
Port number.
Definition: CIB_PRM.h:31
USB 3.0.
Definition: usb.h:24
Not connected.
Definition: usb.h:46
A USB hub device.
Definition: usbhub.h:251
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
A USB device.
Definition: usb.h:708
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define le16_to_cpu(value)
Definition: byteswap.h:112
#define USB_HUB_PORT_CONNECTION
Current connect status feature.
Definition: usbhub.h:70
Port status.
Definition: usbhub.h:62
uint16_t changed
Changed status.
Definition: usbhub.h:66
#define USB_HUB_PORT_LOW_SPEED
Low-speed device attached.
Definition: usbhub.h:82
#define DBGC2(...)
Definition: compiler.h:522
High speed (480Mbps)
Definition: usb.h:52
unsigned int protocol
Hub protocol.
Definition: usb.h:834
uint16_t current
Current status.
Definition: usbhub.h:64
const char * name
Name.
Definition: usbhub.h:253
Full speed (12Mbps)
Definition: usb.h:50
static void * usb_hub_get_drvdata(struct usb_hub *hub)
Get USB hub driver private data.
Definition: usb.h:933

References usb_hub_port_status::changed, usb_hub_port_status::current, DBGC, DBGC2, usb_hub_device::hub, hub_clear_changes(), le16_to_cpu, usb_hub_device::name, port, usb_hub::protocol, rc, status, strerror(), usb_hub_device::usb, usb_hub_get_drvdata(), usb_hub_get_port_status(), USB_HUB_PORT_CONNECTION, USB_HUB_PORT_HIGH_SPEED, USB_HUB_PORT_LOW_SPEED, USB_PROTO_3_0, USB_SPEED_FULL, USB_SPEED_HIGH, USB_SPEED_LOW, USB_SPEED_NONE, and USB_SPEED_SUPER.

◆ hub_clear_tt()

static int hub_clear_tt ( struct usb_hub hub,
struct usb_port port,
struct usb_endpoint ep 
)
static

Clear transaction translator buffer.

Parameters
hubUSB hub
portUSB port
epUSB endpoint
Return values
rcReturn status code

Definition at line 362 of file usbhub.c.

363  {
364  struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
365  struct usb_device *usb = hubdev->usb;
366  int rc;
367 
368  /* Clear transaction translator buffer. All hubs must support
369  * single-TT operation; we simplify our code by supporting
370  * only this configuration.
371  */
372  if ( ( rc = usb_hub_clear_tt_buffer ( usb, ep->usb->address,
373  ep->address, ep->attributes,
374  USB_HUB_TT_SINGLE ) ) != 0 ) {
375  DBGC ( hubdev, "HUB %s port %d could not clear TT buffer: %s\n",
376  hubdev->name, port->address, strerror ( rc ) );
377  return rc;
378  }
379 
380  return 0;
381 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
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
struct usb_device * usb
USB device.
Definition: usbhub.h:255
unsigned int address
Device address, if assigned.
Definition: usb.h:718
u8 port
Port number.
Definition: CIB_PRM.h:31
A USB hub device.
Definition: usbhub.h:251
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
#define USB_HUB_TT_SINGLE
Transaction translator port value for single-TT hubs.
Definition: usbhub.h:248
A USB device.
Definition: usb.h:708
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct usb_endpoint * ep[32]
Endpoint list.
Definition: usb.h:730
struct usb_device * usb
USB device.
Definition: usb.h:391
const char * name
Name.
Definition: usbhub.h:253
unsigned int attributes
Attributes.
Definition: usb.h:395
unsigned int address
Endpoint address.
Definition: usb.h:393
static void * usb_hub_get_drvdata(struct usb_hub *hub)
Get USB hub driver private data.
Definition: usb.h:933

References usb_endpoint::address, usb_device::address, usb_endpoint::attributes, DBGC, usb_device::ep, usb_hub_device::hub, usb_hub_device::name, port, rc, strerror(), usb_hub_device::usb, usb_endpoint::usb, usb_hub_clear_tt_buffer(), usb_hub_get_drvdata(), and USB_HUB_TT_SINGLE.

◆ hub_probe()

static int hub_probe ( struct usb_function func,
struct usb_configuration_descriptor config 
)
static

Probe USB hub.

Parameters
funcUSB function
configConfiguration descriptor
Return values
rcReturn status code

Definition at line 400 of file usbhub.c.

401  {
402  struct usb_device *usb = func->usb;
403  struct usb_bus *bus = usb->port->hub->bus;
404  struct usb_hub_device *hubdev;
406  union usb_hub_descriptor desc;
407  unsigned int depth;
408  unsigned int ports;
409  int enhanced;
410  int rc;
411 
412  /* Allocate and initialise structure */
413  hubdev = zalloc ( sizeof ( *hubdev ) );
414  if ( ! hubdev ) {
415  rc = -ENOMEM;
416  goto err_alloc;
417  }
418  enhanced = ( usb->port->protocol >= USB_PROTO_3_0 );
419  hubdev->name = func->name;
420  hubdev->usb = usb;
421  hubdev->features =
423  hubdev->flags = func->id->driver_data;
424  usb_endpoint_init ( &hubdev->intr, usb, &usb_hub_intr_operations );
425  usb_refill_init ( &hubdev->intr, 0, 0, USB_HUB_INTR_FILL );
427 
428  /* Locate hub interface descriptor */
429  interface = usb_interface_descriptor ( config, func->interface[0], 0 );
430  if ( ! interface ) {
431  DBGC ( hubdev, "HUB %s has no interface descriptor\n",
432  hubdev->name );
433  rc = -EINVAL;
434  goto err_interface;
435  }
436 
437  /* Locate interrupt endpoint descriptor */
438  if ( ( rc = usb_endpoint_described ( &hubdev->intr, config, interface,
439  USB_INTERRUPT_IN, 0 ) ) != 0 ) {
440  DBGC ( hubdev, "HUB %s could not describe interrupt endpoint: "
441  "%s\n", hubdev->name, strerror ( rc ) );
442  goto err_endpoint;
443  }
444 
445  /* Set hub depth */
446  depth = usb_depth ( usb );
447  if ( enhanced ) {
448  if ( ( rc = usb_hub_set_hub_depth ( usb, depth ) ) != 0 ) {
449  DBGC ( hubdev, "HUB %s could not set hub depth to %d: "
450  "%s\n", hubdev->name, depth, strerror ( rc ) );
451  goto err_set_hub_depth;
452  }
453  }
454 
455  /* Get hub descriptor */
456  if ( ( rc = usb_hub_get_descriptor ( usb, enhanced, &desc ) ) != 0 ) {
457  DBGC ( hubdev, "HUB %s could not get hub descriptor: %s\n",
458  hubdev->name, strerror ( rc ) );
459  goto err_hub_descriptor;
460  }
461  ports = desc.basic.ports;
462  DBGC ( hubdev, "HUB %s has %d ports at depth %d%s\n", hubdev->name,
463  ports, depth, ( enhanced ? " (enhanced)" : "" ) );
464 
465  /* Allocate hub */
466  hubdev->hub = alloc_usb_hub ( bus, usb, ports, &hub_operations );
467  if ( ! hubdev->hub ) {
468  rc = -ENOMEM;
469  goto err_alloc_hub;
470  }
471  usb_hub_set_drvdata ( hubdev->hub, hubdev );
472 
473  /* Register hub */
474  if ( ( rc = register_usb_hub ( hubdev->hub ) ) != 0 ) {
475  DBGC ( hubdev, "HUB %s could not register: %s\n",
476  hubdev->name, strerror ( rc ) );
477  goto err_register_hub;
478  }
479 
480  usb_func_set_drvdata ( func, hubdev );
481  return 0;
482 
483  unregister_usb_hub ( hubdev->hub );
484  err_register_hub:
485  free_usb_hub ( hubdev->hub );
486  err_alloc_hub:
487  err_hub_descriptor:
488  err_set_hub_depth:
489  err_endpoint:
490  err_interface:
491  free ( hubdev );
492  err_alloc:
493  return rc;
494 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Name.
Definition: usb.h:661
static int usb_hub_get_descriptor(struct usb_device *usb, int enhanced, union usb_hub_descriptor *data)
Get hub descriptor.
Definition: usbhub.h:146
unsigned int features
Features.
Definition: usbhub.h:259
void unregister_usb_hub(struct usb_hub *hub)
Unregister USB hub.
Definition: usb.c:2011
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbhub.h:264
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define DBGC(...)
Definition: compiler.h:505
unsigned int protocol
Port protocol.
Definition: usb.h:804
#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
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
struct process refill
Interrupt endpoint refill process.
Definition: usbhub.h:266
static int usb_hub_set_hub_depth(struct usb_device *usb, unsigned int depth)
Set hub depth.
Definition: usbhub.h:217
struct usb_device_id * id
Driver device ID.
Definition: usb.h:676
#define ENOMEM
Not enough space.
Definition: errno.h:534
A USB interface descriptor.
Definition: usb.h:230
struct usb_port * port
USB port.
Definition: usb.h:712
USB 3.0.
Definition: usb.h:24
An object interface.
Definition: interface.h:124
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:602
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
A USB hub descriptor.
Definition: usbhub.h:52
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition: usb.h:692
A USB device.
Definition: usb.h:708
static unsigned int usb_depth(struct usb_device *usb)
Get USB depth.
Definition: usb.h:1248
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 struct usb_hub_driver_operations hub_operations
USB hub operations.
Definition: usbhub.c:384
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:663
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
static struct usb_endpoint_driver_operations usb_hub_intr_operations
Interrupt endpoint operations.
Definition: usbhub.c:122
unsigned long driver_data
Arbitrary driver data.
Definition: usb.h:1343
void free_usb_hub(struct usb_hub *hub)
Free USB hub.
Definition: usb.c:2044
#define USB_HUB_FEATURES
USB features.
Definition: usbhub.h:112
struct usb_hub * hub
USB hub.
Definition: usb.h:800
int register_usb_hub(struct usb_hub *hub)
Register USB hub.
Definition: usb.c:1957
static void usb_hub_set_drvdata(struct usb_hub *hub, void *priv)
Set USB hub driver private data.
Definition: usb.h:922
#define USB_HUB_FEATURES_ENHANCED
USB features for enhanced hubs.
Definition: usbhub.h:120
struct usb_bus * bus
USB bus.
Definition: usb.h:830
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
const char * name
Name.
Definition: usbhub.h:253
A USB bus.
Definition: usb.h:951
uint8_t interface
Interface number.
Definition: usb.h:234
uint8_t bus
Bus.
Definition: edd.h:14
static struct process_descriptor hub_refill_desc
Refill process descriptor.
Definition: usbhub.c:62
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:1918

References alloc_usb_hub(), bus, usb_hub::bus, DBGC, desc, usb_device_id::driver_data, EINVAL, usb_hub_descriptor::enhanced, ENOMEM, usb_hub_device::features, usb_hub_device::flags, free, free_usb_hub(), usb_hub_device::hub, usb_port::hub, hub_operations, hub_refill_desc, usb_function::id, usb_interface_descriptor::interface, usb_hub_device::intr, usb_hub_device::name, usb_function::name, NULL, usb_device::port, process_init_stopped(), usb_port::protocol, rc, usb_hub_device::refill, register_usb_hub(), strerror(), unregister_usb_hub(), usb_hub_device::usb, usb_function::usb, usb_depth(), usb_endpoint_described(), usb_endpoint_init(), usb_func_set_drvdata(), USB_HUB_FEATURES, USB_HUB_FEATURES_ENHANCED, usb_hub_get_descriptor(), USB_HUB_INTR_FILL, usb_hub_intr_operations, usb_hub_set_drvdata(), usb_hub_set_hub_depth(), USB_INTERRUPT_IN, USB_PROTO_3_0, usb_refill_init(), and zalloc().

◆ hub_remove()

static void hub_remove ( struct usb_function func)
static

Remove USB hub.

Parameters
funcUSB function
Return values
rcReturn status code

Definition at line 502 of file usbhub.c.

502  {
503  struct usb_hub_device *hubdev = usb_func_get_drvdata ( func );
504  struct usb_hub *hub = hubdev->hub;
505  struct usb_device *usb = hubdev->usb;
506  struct usb_port *port;
507  unsigned int i;
508 
509  /* If hub has been unplugged, mark all ports as unplugged */
510  if ( usb->port->disconnected ) {
511  for ( i = 1 ; i <= hub->ports ; i++ ) {
512  port = usb_port ( hub, i );
513  port->disconnected = 1;
514  port->speed = USB_SPEED_NONE;
515  }
516  }
517 
518  /* Unregister hub */
519  unregister_usb_hub ( hubdev->hub );
520  assert ( ! process_running ( &hubdev->refill ) );
521 
522  /* Free hub */
523  free_usb_hub ( hubdev->hub );
524 
525  /* Free hub device */
526  free ( hubdev );
527 }
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition: usb.h:703
int disconnected
Port disconnection has been detected.
Definition: usb.h:812
A USB hub.
Definition: usb.h:826
void unregister_usb_hub(struct usb_hub *hub)
Unregister USB hub.
Definition: usb.c:2011
struct usb_device * usb
Currently attached device (if in use)
Definition: usb.h:820
struct usb_device * usb
USB device.
Definition: usbhub.h:255
struct process refill
Interrupt endpoint refill process.
Definition: usbhub.h:266
A USB port.
Definition: usb.h:798
u8 port
Port number.
Definition: CIB_PRM.h:31
struct usb_port * port
USB port.
Definition: usb.h:712
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
Not connected.
Definition: usb.h:46
A USB hub device.
Definition: usbhub.h:251
struct usb_hub * hub
USB hub.
Definition: usbhub.h:257
unsigned int ports
Number of ports.
Definition: usb.h:836
A USB device.
Definition: usb.h:708
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static int process_running(struct process *process)
Check if process is running.
Definition: process.h:175
void free_usb_hub(struct usb_hub *hub)
Free USB hub.
Definition: usb.c:2044
struct usb_hub * hub
USB hub.
Definition: usb.h:800
static struct usb_port * usb_port(struct usb_hub *hub, unsigned int address)
Get USB port.
Definition: usb.h:945

References assert(), usb_port::disconnected, free, free_usb_hub(), usb_hub_device::hub, usb_port::hub, port, usb_device::port, usb_hub::ports, process_running(), usb_hub_device::refill, unregister_usb_hub(), usb_hub_device::usb, usb_port::usb, usb_func_get_drvdata(), usb_port(), and USB_SPEED_NONE.

Variable Documentation

◆ hub_refill_desc

struct process_descriptor hub_refill_desc
static
Initial value:
=
PROC_DESC ( struct usb_hub_device, refill, hub_refill )
A USB hub device.
Definition: usbhub.h:251
static void hub_refill(struct usb_hub_device *hubdev)
Refill interrupt ring.
Definition: usbhub.c:46
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition: process.h:82

Refill process descriptor.

Definition at line 62 of file usbhub.c.

Referenced by hub_probe().

◆ usb_hub_intr_operations

struct usb_endpoint_driver_operations usb_hub_intr_operations
static
Initial value:
= {
.complete = hub_complete,
}
static void hub_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete interrupt transfer.
Definition: usbhub.c:72

Interrupt endpoint operations.

Definition at line 122 of file usbhub.c.

Referenced by hub_probe().

◆ hub_operations

struct usb_hub_driver_operations hub_operations
static
Initial value:
= {
.open = hub_open,
.close = hub_close,
.enable = hub_enable,
.disable = hub_disable,
.speed = hub_speed,
.clear_tt = hub_clear_tt,
}
static void hub_close(struct usb_hub *hub)
Close hub.
Definition: usbhub.c:179
static int hub_enable(struct usb_hub *hub, struct usb_port *port)
Enable port.
Definition: usbhub.c:196
static int hub_clear_tt(struct usb_hub *hub, struct usb_port *port, struct usb_endpoint *ep)
Clear transaction translator buffer.
Definition: usbhub.c:362
static int hub_open(struct usb_hub *hub)
Open hub.
Definition: usbhub.c:132
static int hub_disable(struct usb_hub *hub, struct usb_port *port)
Disable port.
Definition: usbhub.c:244
static int hub_speed(struct usb_hub *hub, struct usb_port *port)
Update port speed.
Definition: usbhub.c:309

USB hub operations.

Definition at line 384 of file usbhub.c.

Referenced by hub_probe().

◆ hub_ids

struct usb_device_id hub_ids[]
static
Initial value:
= {
{
.name = "avocent-hub",
.vendor = 0x0624,
.product = 0x0248,
.driver_data = USB_HUB_SLOW_START,
},
{
.name = "hub",
.vendor = USB_ANY_ID,
.product = USB_ANY_ID,
},
}
#define USB_ANY_ID
Match-anything ID.
Definition: usb.h:1347
#define USB_HUB_SLOW_START
Hub requires additional settling delay.
Definition: usbhub.h:270

USB hub device IDs.

Definition at line 530 of file usbhub.c.

◆ __usb_driver

struct usb_driver usb_hub_driver __usb_driver
Initial value:
= {
.ids = hub_ids,
.id_count = ( sizeof ( hub_ids ) / sizeof ( hub_ids[0] ) ),
.score = USB_SCORE_NORMAL,
.probe = hub_probe,
.remove = hub_remove,
}
static struct usb_device_id hub_ids[]
USB hub device IDs.
Definition: usbhub.c:530
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition: usb.h:1363
Normal driver.
Definition: usb.h:1427
#define USB_CLASS_HUB
Class code for USB hubs.
Definition: usb.h:155
#define USB_ANY_ID
Match-anything ID.
Definition: usb.h:1347
static void hub_remove(struct usb_function *func)
Remove USB hub.
Definition: usbhub.c:502
static int hub_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe USB hub.
Definition: usbhub.c:400

USB hub driver.

Definition at line 545 of file usbhub.c.