iPXE
uhci.c File Reference

USB Universal Host Controller Interface (UHCI) driver. More...

#include <strings.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/malloc.h>
#include <ipxe/pci.h>
#include <ipxe/usb.h>
#include "ehci.h"
#include "uhci.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int uhci_reachable (void *addr, size_t len)
 Check that address is reachable.
static void uhci_run (struct uhci_device *uhci)
 Start UHCI device.
static int uhci_stop (struct uhci_device *uhci)
 Stop UHCI device.
static int uhci_reset (struct uhci_device *uhci)
 Reset UHCI device.
static int uhci_ring_alloc (struct uhci_ring *ring)
 Allocate transfer ring.
static void uhci_ring_free (struct uhci_ring *ring)
 Free transfer ring.
static int uhci_enqueue (struct uhci_ring *ring, struct io_buffer *iobuf, unsigned int count)
 Enqueue new transfer.
static void uhci_describe (struct uhci_ring *ring, void *data, size_t len, uint8_t pid)
 Describe transfer.
static struct io_bufferuhci_dequeue (struct uhci_ring *ring)
 Dequeue transfer.
static void uhci_restart (struct uhci_ring *ring, uint32_t toggle)
 Restart ring.
static uint32_t uhci_link_qh (struct uhci_queue_head *queue)
 Get link value for a queue head.
static void uhci_async_schedule (struct uhci_device *uhci)
 (Re)build asynchronous schedule
static void uhci_async_add (struct uhci_endpoint *endpoint)
 Add endpoint to asynchronous schedule.
static void uhci_async_del (struct uhci_endpoint *endpoint)
 Remove endpoint from asynchronous schedule.
static void uhci_periodic_schedule (struct uhci_device *uhci)
 (Re)build periodic schedule
static void uhci_periodic_add (struct uhci_endpoint *endpoint)
 Add endpoint to periodic schedule.
static void uhci_periodic_del (struct uhci_endpoint *endpoint)
 Remove endpoint from periodic schedule.
static void uhci_schedule_add (struct uhci_endpoint *endpoint)
 Add endpoint to appropriate schedule.
static void uhci_schedule_del (struct uhci_endpoint *endpoint)
 Remove endpoint from appropriate schedule.
static int uhci_endpoint_open (struct usb_endpoint *ep)
 Open endpoint.
static void uhci_endpoint_close (struct usb_endpoint *ep)
 Close endpoint.
static int uhci_endpoint_reset (struct usb_endpoint *ep)
 Reset endpoint.
static int uhci_endpoint_mtu (struct usb_endpoint *ep)
 Update MTU.
static int uhci_endpoint_message (struct usb_endpoint *ep, struct io_buffer *iobuf)
 Enqueue message transfer.
static int uhci_endpoint_stream (struct usb_endpoint *ep, struct io_buffer *iobuf, int zlp)
 Enqueue stream transfer.
static int uhci_is_message (struct uhci_transfer *xfer)
 Check if transfer is a message transfer.
static void uhci_endpoint_poll (struct uhci_endpoint *endpoint)
 Poll for completions.
static int uhci_device_open (struct usb_device *usb)
 Open device.
static void uhci_device_close (struct usb_device *usb)
 Close device.
static int uhci_device_address (struct usb_device *usb)
 Assign device address.
static int uhci_hub_open (struct usb_hub *hub __unused)
 Open hub.
static void uhci_hub_close (struct usb_hub *hub __unused)
 Close hub.
static int uhci_root_open (struct usb_hub *hub __unused)
 Open root hub.
static void uhci_root_close (struct usb_hub *hub __unused)
 Close root hub.
static int uhci_root_enable (struct usb_hub *hub, struct usb_port *port)
 Enable port.
static int uhci_root_disable (struct usb_hub *hub, struct usb_port *port)
 Disable port.
static int uhci_root_speed (struct usb_hub *hub, struct usb_port *port)
 Update root hub port speed.
static int uhci_root_clear_tt (struct usb_hub *hub, struct usb_port *port, struct usb_endpoint *ep)
 Clear transaction translator buffer.
static void uhci_root_poll (struct usb_hub *hub, struct usb_port *port)
 Poll for port status changes.
static int uhci_bus_open (struct usb_bus *bus)
 Open USB bus.
static void uhci_bus_close (struct usb_bus *bus)
 Close USB bus.
static void uhci_bus_poll (struct usb_bus *bus)
 Poll USB bus.
__weak unsigned int ehci_companion (struct pci_device *pci __unused)
 Locate EHCI companion controller (when no EHCI support is present).
static int uhci_probe (struct pci_device *pci)
 Probe PCI device.
static void uhci_remove (struct pci_device *pci)
 Remove PCI device.

Variables

static struct usb_host_operations uhci_operations
 USB host controller operations.
static struct pci_device_id uhci_ids []
 UHCI PCI device IDs.
struct pci_driver uhci_driver __pci_driver
 UHCI PCI driver.

Detailed Description

USB Universal Host Controller Interface (UHCI) driver.

Definition in file uhci.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ uhci_reachable()

int uhci_reachable ( void * addr,
size_t len )
inlinestatic

Check that address is reachable.

Parameters
addrAddress
lenLength
Return values
rcReturn status code

Definition at line 58 of file uhci.c.

58 {
59 physaddr_t phys = virt_to_phys ( addr );
60
61 /* Always reachable in a 32-bit build */
62 if ( sizeof ( physaddr_t ) <= sizeof ( uint32_t ) )
63 return 0;
64
65 /* Reachable if below 4GB */
66 if ( ( ( phys + len - 1 ) & ~0xffffffffULL ) == 0 )
67 return 0;
68
69 return -ENOTSUP;
70}
unsigned int uint32_t
Definition stdint.h:12
unsigned long physaddr_t
Definition stdint.h:20
ring len
Length.
Definition dwmac.h:226
uint32_t addr
Buffer address.
Definition dwmac.h:9
static signed char phys[4]
Definition epic100.c:88
#define ENOTSUP
Operation not supported.
Definition errno.h:633

References addr, ENOTSUP, len, and phys.

Referenced by uhci_bus_open(), uhci_enqueue(), and uhci_ring_alloc().

◆ uhci_run()

void uhci_run ( struct uhci_device * uhci)
static

Start UHCI device.

Parameters
uhciUHCI device

Definition at line 84 of file uhci.c.

84 {
85 uint16_t usbcmd;
86
87 /* Set run/stop bit */
88 usbcmd = inw ( uhci->regs + UHCI_USBCMD );
89 usbcmd |= ( UHCI_USBCMD_RUN | UHCI_USBCMD_MAX64 );
90 outw ( usbcmd, uhci->regs + UHCI_USBCMD );
91}
unsigned short uint16_t
Definition stdint.h:11
#define inw(io_addr)
Definition io.h:292
#define outw(data, io_addr)
Definition io.h:320
unsigned long regs
Registers.
Definition uhci.h:310
#define UHCI_USBCMD_MAX64
Max packet is 64 bytes.
Definition uhci.h:37
#define UHCI_USBCMD_RUN
Run/stop.
Definition uhci.h:43
#define UHCI_USBCMD
USB command register.
Definition uhci.h:34

References inw, outw, uhci_device::regs, UHCI_USBCMD, UHCI_USBCMD_MAX64, and UHCI_USBCMD_RUN.

Referenced by uhci_bus_open().

◆ uhci_stop()

int uhci_stop ( struct uhci_device * uhci)
static

Stop UHCI device.

Parameters
uhciUHCI device
Return values
rcReturn status code

Definition at line 99 of file uhci.c.

99 {
100 uint16_t usbcmd;
101 uint16_t usbsts;
102 unsigned int i;
103
104 /* Clear run/stop bit */
105 usbcmd = inw ( uhci->regs + UHCI_USBCMD );
106 usbcmd &= ~UHCI_USBCMD_RUN;
107 outw ( usbcmd, uhci->regs + UHCI_USBCMD );
108
109 /* Wait for device to stop */
110 for ( i = 0 ; i < UHCI_STOP_MAX_WAIT_MS ; i++ ) {
111
112 /* Check if device is stopped */
113 usbsts = inw ( uhci->regs + UHCI_USBSTS );
114 if ( usbsts & UHCI_USBSTS_HCHALTED )
115 return 0;
116
117 /* Delay */
118 mdelay ( 1 );
119 }
120
121 DBGC ( uhci, "UHCI %s timed out waiting for stop\n", uhci->name );
122 return -ETIMEDOUT;
123}
#define DBGC(...)
Definition compiler.h:530
#define ETIMEDOUT
Connection timed out.
Definition errno.h:713
const char * name
Name.
Definition uhci.h:312
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79
#define UHCI_USBSTS_HCHALTED
Host controller halted.
Definition uhci.h:49
#define UHCI_USBSTS
USB status register.
Definition uhci.h:46
#define UHCI_STOP_MAX_WAIT_MS
Maximum time to wait for host controller to stop.
Definition uhci.h:293

References DBGC, ETIMEDOUT, inw, mdelay(), uhci_device::name, outw, uhci_device::regs, UHCI_STOP_MAX_WAIT_MS, UHCI_USBCMD, UHCI_USBCMD_RUN, UHCI_USBSTS, and UHCI_USBSTS_HCHALTED.

Referenced by uhci_bus_close(), uhci_bus_open(), and uhci_reset().

◆ uhci_reset()

int uhci_reset ( struct uhci_device * uhci)
static

Reset UHCI device.

Parameters
uhciUHCI device
Return values
rcReturn status code

Definition at line 131 of file uhci.c.

131 {
132 uint16_t usbcmd;
133 unsigned int i;
134 int rc;
135
136 /* The UHCI specification states that resetting a running
137 * device may result in undefined behaviour, so try stopping
138 * it first.
139 */
140 if ( ( rc = uhci_stop ( uhci ) ) != 0 ) {
141 /* Ignore errors and attempt to reset the device anyway */
142 }
143
144 /* Reset device */
146
147 /* Wait for reset to complete */
148 for ( i = 0 ; i < UHCI_RESET_MAX_WAIT_MS ; i++ ) {
149
150 /* Check if reset is complete */
151 usbcmd = inw ( uhci->regs + UHCI_USBCMD );
152 if ( ! ( usbcmd & UHCI_USBCMD_HCRESET ) )
153 return 0;
154
155 /* Delay */
156 mdelay ( 1 );
157 }
158
159 DBGC ( uhci, "UHCI %s timed out waiting for reset\n", uhci->name );
160 return -ETIMEDOUT;
161}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
static int uhci_stop(struct uhci_device *uhci)
Stop UHCI device.
Definition uhci.c:99
#define UHCI_RESET_MAX_WAIT_MS
Maximum time to wait for reset to complete.
Definition uhci.h:299
#define UHCI_USBCMD_HCRESET
Host controller reset.
Definition uhci.h:40

References DBGC, ETIMEDOUT, inw, mdelay(), uhci_device::name, outw, rc, uhci_device::regs, UHCI_RESET_MAX_WAIT_MS, uhci_stop(), UHCI_USBCMD, and UHCI_USBCMD_HCRESET.

Referenced by uhci_probe(), and uhci_remove().

◆ uhci_ring_alloc()

int uhci_ring_alloc ( struct uhci_ring * ring)
static

Allocate transfer ring.

Parameters
ringTransfer ring
Return values
rcReturn status code

Definition at line 176 of file uhci.c.

176 {
177 int rc;
178
179 /* Initialise structure */
180 memset ( ring, 0, sizeof ( *ring ) );
181
182 /* Allocate queue head */
183 ring->head = malloc_phys ( sizeof ( *ring->head ), UHCI_ALIGN );
184 if ( ! ring->head ) {
185 rc = -ENOMEM;
186 goto err_alloc;
187 }
188 if ( ( rc = uhci_reachable ( ring->head,
189 sizeof ( *ring->head ) ) ) != 0 )
190 goto err_unreachable;
191
192 /* Initialise queue head */
194
195 return 0;
196
197 err_unreachable:
198 free_phys ( ring->head, sizeof ( *ring->head ) );
199 err_alloc:
200 return rc;
201}
#define ENOMEM
Not enough space.
Definition errno.h:578
#define cpu_to_le32(value)
Definition byteswap.h:108
void * memset(void *dest, int character, size_t len) __nonnull
void * malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition malloc.c:789
void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys().
Definition malloc.c:805
uint32_t current
Current transfer descriptor.
Definition uhci.h:197
struct uhci_queue_head * head
Queue head.
Definition uhci.h:258
static int uhci_reachable(void *addr, size_t len)
Check that address is reachable.
Definition uhci.c:58
#define UHCI_ALIGN
Minimum alignment required for data structures.
Definition uhci.h:22
#define UHCI_LINK_TERMINATE
List terminator.
Definition uhci.h:88

References cpu_to_le32, uhci_queue_head::current, ENOMEM, free_phys(), uhci_ring::head, malloc_phys(), memset(), rc, UHCI_ALIGN, UHCI_LINK_TERMINATE, and uhci_reachable().

Referenced by uhci_endpoint_open().

◆ uhci_ring_free()

void uhci_ring_free ( struct uhci_ring * ring)
static

Free transfer ring.

Parameters
ringTransfer ring

Definition at line 208 of file uhci.c.

208 {
209 unsigned int i;
210
211 /* Sanity checks */
212 assert ( uhci_ring_fill ( ring ) == 0 );
213 for ( i = 0 ; i < UHCI_RING_COUNT ; i++ )
214 assert ( ring->xfer[i] == NULL );
215
216 /* Free queue head */
217 free_phys ( ring->head, sizeof ( *ring->head ) );
218}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
struct uhci_transfer * xfer[UHCI_RING_COUNT]
Transfers.
Definition uhci.h:253
#define UHCI_RING_COUNT
Number of transfer descriptors in a ring.
Definition uhci.h:229
static unsigned int uhci_ring_fill(struct uhci_ring *ring)
Calculate space used in transfer ring.
Definition uhci.h:268

References assert, free_phys(), uhci_ring::head, NULL, UHCI_RING_COUNT, uhci_ring_fill(), and uhci_ring::xfer.

Referenced by uhci_endpoint_close(), and uhci_endpoint_open().

◆ uhci_enqueue()

int uhci_enqueue ( struct uhci_ring * ring,
struct io_buffer * iobuf,
unsigned int count )
static

Enqueue new transfer.

Parameters
ringTransfer ring
iobufI/O buffer
countNumber of descriptors
Return values
rcReturn status code

Definition at line 228 of file uhci.c.

229 {
230 struct uhci_transfer *xfer;
231 struct uhci_transfer *end;
233 unsigned int index = ( ring->prod % UHCI_RING_COUNT );
235 size_t len;
236 int rc;
237
238 /* Sanity check */
239 assert ( count > 0 );
240 assert ( iobuf != NULL );
241
242 /* Check for space in ring */
243 if ( ! uhci_ring_remaining ( ring ) ) {
244 rc = -ENOBUFS;
245 goto err_ring_full;
246 }
247
248 /* Check for reachability of I/O buffer */
249 if ( ( rc = uhci_reachable ( iobuf->data, iob_len ( iobuf ) ) ) != 0 )
250 goto err_unreachable_iobuf;
251
252 /* Allocate transfer */
253 xfer = malloc ( sizeof ( *xfer ) );
254 if ( ! xfer ) {
255 rc = -ENOMEM;
256 goto err_alloc_xfer;
257 }
258
259 /* Initialise transfer */
260 xfer->prod = 0;
261 xfer->cons = 0;
262 xfer->len = 0;
263 xfer->iobuf = iobuf;
264
265 /* Allocate transfer descriptors */
266 len = ( count * sizeof ( xfer->desc[0] ) );
267 xfer->desc = malloc_phys ( len, UHCI_ALIGN );
268 if ( ! xfer->desc ) {
269 rc = -ENOMEM;
270 goto err_alloc_desc;
271 }
272 if ( ( rc = uhci_reachable ( xfer->desc, len ) ) != 0 )
273 goto err_unreachable_desc;
274
275 /* Initialise transfer descriptors */
276 memset ( xfer->desc, 0, len );
277 desc = xfer->desc;
278 for ( ; --count ; desc++ ) {
279 link = ( virt_to_phys ( desc + 1 ) | UHCI_LINK_DEPTH_FIRST );
280 desc->link = cpu_to_le32 ( link );
281 desc->flags = ring->flags;
282 }
284 desc->flags = ( ring->flags | UHCI_FL_IOC );
285
286 /* Add to ring */
287 wmb();
288 link = virt_to_phys ( xfer->desc );
289 if ( uhci_ring_fill ( ring ) > 0 ) {
290 end = ring->end;
291 end->desc[ end->prod - 1 ].link = cpu_to_le32 ( link );
292 } else {
293 ring->head->current = cpu_to_le32 ( link );
294 }
295 assert ( ring->xfer[index] == NULL );
296 ring->xfer[index] = xfer;
297 ring->end = xfer;
298 ring->prod++;
299
300 return 0;
301
302 err_unreachable_desc:
303 free_phys ( xfer->desc, len );
304 err_alloc_desc:
305 free ( xfer );
306 err_alloc_xfer:
307 err_unreachable_iobuf:
308 err_ring_full:
309 return rc;
310}
u32 link
Link to next descriptor.
Definition ar9003_mac.h:1
long index
Definition bigint.h:30
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define ENOBUFS
No buffer space available.
Definition errno.h:542
#define wmb()
Definition io.h:546
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:677
uint32_t end
Ending offset.
Definition netvsc.h:7
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
void * data
Start of data.
Definition iobuf.h:113
uint8_t flags
Base flags.
Definition uhci.h:244
unsigned int prod
Producer counter.
Definition uhci.h:234
struct uhci_transfer * end
End of transfer ring (if non-empty).
Definition uhci.h:255
A transfer descriptor.
Definition uhci.h:100
A single UHCI transfer.
Definition uhci.h:210
struct uhci_transfer_descriptor * desc
Transfer descriptors.
Definition uhci.h:219
size_t len
Completed data length.
Definition uhci.h:216
unsigned int prod
Producer counter.
Definition uhci.h:212
unsigned int cons
Consumer counter.
Definition uhci.h:214
struct io_buffer * iobuf
I/O buffer.
Definition uhci.h:222
#define UHCI_LINK_DEPTH_FIRST
Depth-first processing.
Definition uhci.h:82
static unsigned int uhci_ring_remaining(struct uhci_ring *ring)
Calculate space remaining in transfer ring.
Definition uhci.h:283
#define UHCI_FL_IOC
Interrupt on completion.
Definition uhci.h:155

References assert, uhci_transfer::cons, count, cpu_to_le32, uhci_queue_head::current, io_buffer::data, desc, uhci_transfer::desc, end, uhci_ring::end, ENOBUFS, ENOMEM, uhci_ring::flags, free, free_phys(), uhci_ring::head, index, iob_len(), uhci_transfer::iobuf, len, uhci_transfer::len, link, malloc(), malloc_phys(), memset(), NULL, uhci_ring::prod, uhci_transfer::prod, rc, UHCI_ALIGN, UHCI_FL_IOC, UHCI_LINK_DEPTH_FIRST, UHCI_LINK_TERMINATE, uhci_reachable(), UHCI_RING_COUNT, uhci_ring_fill(), uhci_ring_remaining(), wmb, and uhci_ring::xfer.

Referenced by uhci_endpoint_message(), and uhci_endpoint_stream().

◆ uhci_describe()

void uhci_describe ( struct uhci_ring * ring,
void * data,
size_t len,
uint8_t pid )
static

Describe transfer.

Parameters
ringTransfer ring
dataData
lenLength of data
pidPacket ID

Definition at line 320 of file uhci.c.

321 {
322 struct uhci_transfer *xfer = ring->end;
324 size_t frag_len;
326
327 do {
328 /* Calculate fragment length */
329 frag_len = len;
330 if ( frag_len > ring->mtu )
331 frag_len = ring->mtu;
332
333 /* Populate descriptor */
334 desc = &xfer->desc[xfer->prod++];
335 if ( pid == USB_PID_IN )
336 desc->flags |= UHCI_FL_SPD;
337 control = ( ring->control | UHCI_CONTROL_PID ( pid ) |
338 UHCI_CONTROL_LEN ( frag_len ) );
339 desc->control = cpu_to_le32 ( control );
340 if ( data )
341 desc->data = cpu_to_le32 ( virt_to_phys ( data ) );
342 wmb();
343 desc->status = UHCI_STATUS_ACTIVE;
344
345 /* Update data toggle */
347
348 /* Move to next descriptor */
349 data += frag_len;
350 len -= frag_len;
351
352 } while ( len );
353}
uint8_t data[48]
Additional event data.
Definition ena.h:11
@ USB_PID_IN
IN PID.
Definition usb.h:75
uint32_t control
Control.
Definition myson.h:3
size_t mtu
Maximum packet length.
Definition uhci.h:239
uint32_t control
Base control word.
Definition uhci.h:250
#define UHCI_CONTROL_LEN(len)
Data length.
Definition uhci.h:173
#define UHCI_CONTROL_TOGGLE
Data toggle.
Definition uhci.h:170
#define UHCI_FL_SPD
Short packet detect.
Definition uhci.h:143
#define UHCI_CONTROL_PID(pid)
Packet ID.
Definition uhci.h:158
#define UHCI_STATUS_ACTIVE
Active.
Definition uhci.h:122

References control, uhci_ring::control, cpu_to_le32, data, desc, uhci_transfer::desc, uhci_ring::end, len, uhci_ring::mtu, uhci_transfer::prod, UHCI_CONTROL_LEN, UHCI_CONTROL_PID, UHCI_CONTROL_TOGGLE, UHCI_FL_SPD, UHCI_STATUS_ACTIVE, USB_PID_IN, and wmb.

Referenced by uhci_endpoint_message(), and uhci_endpoint_stream().

◆ uhci_dequeue()

struct io_buffer * uhci_dequeue ( struct uhci_ring * ring)
static

Dequeue transfer.

Parameters
ringTransfer ring
Return values
iobufI/O buffer

Definition at line 361 of file uhci.c.

361 {
362 unsigned int index = ( ring->cons % UHCI_RING_COUNT );
363 struct io_buffer *iobuf;
364 struct uhci_transfer *xfer;
365 size_t len;
366
367 /* Sanity checks */
368 assert ( uhci_ring_fill ( ring ) > 0 );
369
370 /* Consume transfer */
371 xfer = ring->xfer[index];
372 assert ( xfer != NULL );
373 assert ( xfer->desc != NULL );
374 iobuf = xfer->iobuf;
375 assert ( iobuf != NULL );
376 ring->xfer[index] = NULL;
377 ring->cons++;
378
379 /* Free transfer descriptors */
380 len = ( xfer->prod * sizeof ( xfer->desc[0] ) );
381 free_phys ( xfer->desc, len );
382
383 /* Free transfer */
384 free ( xfer );
385
386 return iobuf;
387}
A persistent I/O buffer.
Definition iobuf.h:98
unsigned int cons
Consumer counter.
Definition uhci.h:236

References assert, uhci_ring::cons, uhci_transfer::desc, free, free_phys(), index, uhci_transfer::iobuf, len, NULL, uhci_transfer::prod, UHCI_RING_COUNT, uhci_ring_fill(), and uhci_ring::xfer.

Referenced by uhci_endpoint_close(), and uhci_endpoint_poll().

◆ uhci_restart()

void uhci_restart ( struct uhci_ring * ring,
uint32_t toggle )
static

Restart ring.

Parameters
ringTransfer ring
toggleExpected data toggle for next descriptor

Definition at line 395 of file uhci.c.

395 {
396 struct uhci_transfer *xfer;
400 unsigned int i;
401 unsigned int j;
402
403 /* Sanity check */
405
406 /* If ring is empty, then just update the data toggle for the
407 * next descriptor.
408 */
409 if ( uhci_ring_fill ( ring ) == 0 ) {
411 ring->control |= toggle;
412 return;
413 }
414
415 /* If expected toggle does not match the toggle in the first
416 * unconsumed descriptor, then invert all toggles.
417 */
418 xfer = ring->xfer[ ring->cons % UHCI_RING_COUNT ];
419 assert ( xfer != NULL );
420 assert ( xfer->cons == 0 );
421 first = &xfer->desc[0];
422 if ( ( le32_to_cpu ( first->control ) ^ toggle ) & UHCI_CONTROL_TOGGLE){
423
424 /* Invert toggle on all unconsumed transfer descriptors */
425 for ( i = ring->cons ; i != ring->prod ; i++ ) {
426 xfer = ring->xfer[ i % UHCI_RING_COUNT ];
427 assert ( xfer != NULL );
428 assert ( xfer->cons == 0 );
429 for ( j = 0 ; j < xfer->prod ; j++ ) {
430 desc = &xfer->desc[j];
431 desc->control ^=
433 }
434 }
435
436 /* Invert toggle for next descriptor to be enqueued */
438 }
439
440 /* Restart ring at first unconsumed transfer */
441 link = virt_to_phys ( first );
442 wmb();
443 ring->head->current = cpu_to_le32 ( link );
444}
#define le32_to_cpu(value)
Definition byteswap.h:114
uint32_t first
First block in range.
Definition pccrr.h:1

References assert, uhci_ring::cons, uhci_transfer::cons, uhci_ring::control, cpu_to_le32, uhci_queue_head::current, desc, uhci_transfer::desc, first, uhci_ring::head, le32_to_cpu, link, NULL, uhci_ring::prod, uhci_transfer::prod, UHCI_CONTROL_TOGGLE, UHCI_LINK_TERMINATE, UHCI_RING_COUNT, uhci_ring_fill(), wmb, and uhci_ring::xfer.

Referenced by uhci_endpoint_poll(), and uhci_endpoint_reset().

◆ uhci_link_qh()

uint32_t uhci_link_qh ( struct uhci_queue_head * queue)
inlinestatic

Get link value for a queue head.

Parameters
queueQueue head
Return values
linkLink value

Definition at line 459 of file uhci.c.

459 {
460
461 return ( virt_to_phys ( queue ) | UHCI_LINK_TYPE_QH );
462}
uint16_t queue
Queue ID.
Definition ena.h:11
#define UHCI_LINK_TYPE_QH
Queue head type.
Definition uhci.h:85

References queue, and UHCI_LINK_TYPE_QH.

Referenced by uhci_async_schedule(), and uhci_periodic_schedule().

◆ uhci_async_schedule()

void uhci_async_schedule ( struct uhci_device * uhci)
static

(Re)build asynchronous schedule

Parameters
uhciUHCI device

Definition at line 469 of file uhci.c.

469 {
470 struct uhci_endpoint *endpoint;
471 struct uhci_queue_head *queue;
474
475 /* Build schedule in reverse order of execution. Provided
476 * that we only ever add or remove single endpoints, this can
477 * safely run concurrently with hardware execution of the
478 * schedule.
479 */
480 link = end = uhci_link_qh ( uhci->head );
481 list_for_each_entry_reverse ( endpoint, &uhci->async, schedule ) {
482 queue = endpoint->ring.head;
483 queue->link = cpu_to_le32 ( link );
484 wmb();
485 link = uhci_link_qh ( queue );
486 }
487 if ( link == end )
489 uhci->head->link = cpu_to_le32 ( link );
490 wmb();
491}
#define list_for_each_entry_reverse(pos, head, member)
Iterate over entries in a list in reverse order.
Definition list.h:445
struct list_head async
Asynchronous schedule.
Definition uhci.h:325
struct uhci_queue_head * head
Asynchronous queue head.
Definition uhci.h:318
A UHCI endpoint.
Definition uhci.h:337
struct uhci_ring ring
Transfer ring.
Definition uhci.h:348
A queue head.
Definition uhci.h:193
uint32_t link
Horizontal link pointer.
Definition uhci.h:195
static uint32_t uhci_link_qh(struct uhci_queue_head *queue)
Get link value for a queue head.
Definition uhci.c:459

References uhci_device::async, cpu_to_le32, end, uhci_device::head, uhci_ring::head, link, uhci_queue_head::link, list_for_each_entry_reverse, queue, uhci_endpoint::ring, uhci_link_qh(), UHCI_LINK_TERMINATE, and wmb.

Referenced by uhci_async_add(), uhci_async_del(), and uhci_bus_open().

◆ uhci_async_add()

void uhci_async_add ( struct uhci_endpoint * endpoint)
static

Add endpoint to asynchronous schedule.

Parameters
endpointEndpoint

Definition at line 498 of file uhci.c.

498 {
499 struct uhci_device *uhci = endpoint->uhci;
500
501 /* Add to end of schedule */
502 list_add_tail ( &endpoint->schedule, &uhci->async );
503
504 /* Rebuild schedule */
505 uhci_async_schedule ( uhci );
506}
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
A UHCI device.
Definition uhci.h:308
struct uhci_device * uhci
UHCI device.
Definition uhci.h:339
struct list_head schedule
Endpoint schedule.
Definition uhci.h:345
static void uhci_async_schedule(struct uhci_device *uhci)
(Re)build asynchronous schedule
Definition uhci.c:469

References uhci_device::async, list_add_tail, uhci_endpoint::schedule, uhci_endpoint::uhci, and uhci_async_schedule().

Referenced by uhci_schedule_add().

◆ uhci_async_del()

void uhci_async_del ( struct uhci_endpoint * endpoint)
static

Remove endpoint from asynchronous schedule.

Parameters
endpointEndpoint

Definition at line 513 of file uhci.c.

513 {
514 struct uhci_device *uhci = endpoint->uhci;
515
516 /* Remove from schedule */
517 list_check_contains_entry ( endpoint, &uhci->async, schedule );
518 list_del ( &endpoint->schedule );
519
520 /* Rebuild schedule */
521 uhci_async_schedule ( uhci );
522
523 /* Delay for a whole USB frame (with a 100% safety margin) */
524 mdelay ( 2 );
525}
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define list_check_contains_entry(entry, head, member)
Check list contains a specified entry.
Definition list.h:550

References uhci_device::async, list_check_contains_entry, list_del, mdelay(), uhci_endpoint::schedule, uhci_endpoint::uhci, and uhci_async_schedule().

Referenced by uhci_schedule_del().

◆ uhci_periodic_schedule()

void uhci_periodic_schedule ( struct uhci_device * uhci)
static

(Re)build periodic schedule

Parameters
uhciUHCI device

Definition at line 532 of file uhci.c.

532 {
533 struct uhci_endpoint *endpoint;
534 struct uhci_queue_head *queue;
537 unsigned int max_interval;
538 unsigned int i;
539
540 /* Build schedule in reverse order of execution. Provided
541 * that we only ever add or remove single endpoints, this can
542 * safely run concurrently with hardware execution of the
543 * schedule.
544 */
545 DBGCP ( uhci, "UHCI %s periodic schedule: ", uhci->name );
546 link = end = uhci_link_qh ( uhci->head );
547 list_for_each_entry_reverse ( endpoint, &uhci->periodic, schedule ) {
548 queue = endpoint->ring.head;
549 queue->link = cpu_to_le32 ( link );
550 wmb();
551 DBGCP ( uhci, "%s%d", ( ( link == end ) ? "" : "<-" ),
552 endpoint->ep->interval );
553 link = uhci_link_qh ( queue );
554 }
555 DBGCP ( uhci, "\n" );
556
557 /* Populate periodic frame list */
558 DBGCP ( uhci, "UHCI %s periodic frame list:", uhci->name );
559 for ( i = 0 ; i < UHCI_FRAMES ; i++ ) {
560
561 /* Calculate maximum interval (in microframes) which
562 * may appear as part of this frame list.
563 */
564 if ( i == 0 ) {
565 /* Start of list: include all endpoints */
566 max_interval = -1U;
567 } else {
568 /* Calculate highest power-of-two frame interval */
569 max_interval = ( 1 << ( ffs ( i ) - 1 ) );
570 /* Convert to microframes */
571 max_interval <<= 3;
572 /* Round up to nearest 2^n-1 */
573 max_interval = ( ( max_interval << 1 ) - 1 );
574 }
575
576 /* Find first endpoint in schedule satisfying this
577 * maximum interval constraint.
578 */
579 link = uhci_link_qh ( uhci->head );
580 list_for_each_entry ( endpoint, &uhci->periodic, schedule ) {
581 if ( endpoint->ep->interval <= max_interval ) {
582 queue = endpoint->ring.head;
583 link = uhci_link_qh ( queue );
584 DBGCP ( uhci, " %d:%d",
585 i, endpoint->ep->interval );
586 break;
587 }
588 }
589 uhci->frame->link[i] = cpu_to_le32 ( link );
590 }
591 wmb();
592 DBGCP ( uhci, "\n" );
593}
#define DBGCP(...)
Definition compiler.h:564
#define ffs(x)
Find first (i.e.
Definition strings.h:141
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
struct list_head periodic
Periodic schedule.
Definition uhci.h:330
struct uhci_frame_list * frame
Frame list.
Definition uhci.h:320
struct usb_endpoint * ep
USB endpoint.
Definition uhci.h:341
uint32_t link[UHCI_FRAMES]
Link pointer.
Definition uhci.h:96
unsigned int interval
Interval (in microframes).
Definition usb.h:426
#define UHCI_FRAMES
Number of frames in frame list.
Definition uhci.h:91

References cpu_to_le32, DBGCP, end, uhci_endpoint::ep, ffs, uhci_device::frame, uhci_device::head, uhci_ring::head, usb_endpoint::interval, link, uhci_frame_list::link, list_for_each_entry, list_for_each_entry_reverse, uhci_device::name, uhci_device::periodic, queue, uhci_endpoint::ring, UHCI_FRAMES, uhci_link_qh(), and wmb.

Referenced by uhci_bus_open(), uhci_periodic_add(), and uhci_periodic_del().

◆ uhci_periodic_add()

void uhci_periodic_add ( struct uhci_endpoint * endpoint)
static

Add endpoint to periodic schedule.

Parameters
endpointEndpoint

Definition at line 600 of file uhci.c.

600 {
601 struct uhci_device *uhci = endpoint->uhci;
602 struct uhci_endpoint *before;
603 unsigned int interval = endpoint->ep->interval;
604
605 /* Find first endpoint with a smaller interval */
607 if ( before->ep->interval < interval )
608 break;
609 }
610 list_add_tail ( &endpoint->schedule, &before->schedule );
611
612 /* Rebuild schedule */
614}
int32_t before
Initial microcode version.
Definition ucode.h:5
static void uhci_periodic_schedule(struct uhci_device *uhci)
(Re)build periodic schedule
Definition uhci.c:532

References before, uhci_endpoint::ep, usb_endpoint::interval, list_add_tail, list_for_each_entry, uhci_device::periodic, uhci_endpoint::schedule, uhci_endpoint::uhci, and uhci_periodic_schedule().

Referenced by uhci_schedule_add().

◆ uhci_periodic_del()

void uhci_periodic_del ( struct uhci_endpoint * endpoint)
static

Remove endpoint from periodic schedule.

Parameters
endpointEndpoint

Definition at line 621 of file uhci.c.

621 {
622 struct uhci_device *uhci = endpoint->uhci;
623
624 /* Remove from schedule */
625 list_check_contains_entry ( endpoint, &uhci->periodic, schedule );
626 list_del ( &endpoint->schedule );
627
628 /* Rebuild schedule */
629 uhci_periodic_schedule ( uhci );
630
631 /* Delay for a whole USB frame (with a 100% safety margin) */
632 mdelay ( 2 );
633}

References list_check_contains_entry, list_del, mdelay(), uhci_device::periodic, uhci_endpoint::schedule, uhci_endpoint::uhci, and uhci_periodic_schedule().

Referenced by uhci_schedule_del().

◆ uhci_schedule_add()

void uhci_schedule_add ( struct uhci_endpoint * endpoint)
static

Add endpoint to appropriate schedule.

Parameters
endpointEndpoint

Definition at line 640 of file uhci.c.

640 {
641 struct usb_endpoint *ep = endpoint->ep;
642 unsigned int attr = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
643
645 uhci_periodic_add ( endpoint );
646 } else {
647 uhci_async_add ( endpoint );
648 }
649}
#define USB_ENDPOINT_ATTR_INTERRUPT
Interrupt endpoint transfer type.
Definition usb.h:293
#define USB_ENDPOINT_ATTR_TYPE_MASK
Endpoint attribute transfer type mask.
Definition usb.h:281
uint8_t attr
Type and attributes.
Definition librm.h:7
A USB endpoint.
Definition usb.h:414
unsigned int attributes
Attributes.
Definition usb.h:420
static void uhci_periodic_add(struct uhci_endpoint *endpoint)
Add endpoint to periodic schedule.
Definition uhci.c:600
static void uhci_async_add(struct uhci_endpoint *endpoint)
Add endpoint to asynchronous schedule.
Definition uhci.c:498

References attr, usb_endpoint::attributes, uhci_endpoint::ep, uhci_async_add(), uhci_periodic_add(), USB_ENDPOINT_ATTR_INTERRUPT, and USB_ENDPOINT_ATTR_TYPE_MASK.

Referenced by uhci_endpoint_open().

◆ uhci_schedule_del()

void uhci_schedule_del ( struct uhci_endpoint * endpoint)
static

Remove endpoint from appropriate schedule.

Parameters
endpointEndpoint

Definition at line 656 of file uhci.c.

656 {
657 struct usb_endpoint *ep = endpoint->ep;
658 unsigned int attr = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
659
661 uhci_periodic_del ( endpoint );
662 } else {
663 uhci_async_del ( endpoint );
664 }
665}
static void uhci_periodic_del(struct uhci_endpoint *endpoint)
Remove endpoint from periodic schedule.
Definition uhci.c:621
static void uhci_async_del(struct uhci_endpoint *endpoint)
Remove endpoint from asynchronous schedule.
Definition uhci.c:513

References attr, usb_endpoint::attributes, uhci_endpoint::ep, uhci_async_del(), uhci_periodic_del(), USB_ENDPOINT_ATTR_INTERRUPT, and USB_ENDPOINT_ATTR_TYPE_MASK.

Referenced by uhci_endpoint_close().

◆ uhci_endpoint_open()

int uhci_endpoint_open ( struct usb_endpoint * ep)
static

Open endpoint.

Parameters
epUSB endpoint
Return values
rcReturn status code

Definition at line 680 of file uhci.c.

680 {
681 struct usb_device *usb = ep->usb;
682 struct uhci_device *uhci = usb_get_hostdata ( usb );
683 struct uhci_endpoint *endpoint;
684 int rc;
685
686 /* Allocate and initialise structure */
687 endpoint = zalloc ( sizeof ( *endpoint ) );
688 if ( ! endpoint ) {
689 rc = -ENOMEM;
690 goto err_alloc;
691 }
692 endpoint->uhci = uhci;
693 endpoint->ep = ep;
694 usb_endpoint_set_hostdata ( ep, endpoint );
695
696 /* Initialise descriptor ring */
697 if ( ( rc = uhci_ring_alloc ( &endpoint->ring ) ) != 0 )
698 goto err_ring_alloc;
699 endpoint->ring.mtu = ep->mtu;
700 endpoint->ring.flags = UHCI_FL_CERR_MAX;
701 if ( usb->speed < USB_SPEED_FULL )
702 endpoint->ring.flags |= UHCI_FL_LS;
703 endpoint->ring.control = ( UHCI_CONTROL_DEVICE ( usb->address ) |
705
706 /* Add to list of endpoints */
707 list_add_tail ( &endpoint->list, &uhci->endpoints );
708
709 /* Add to schedule */
710 uhci_schedule_add ( endpoint );
711
712 return 0;
713
714 uhci_ring_free ( &endpoint->ring );
715 err_ring_alloc:
716 free ( endpoint );
717 err_alloc:
718 return rc;
719}
static void * usb_get_hostdata(struct usb_device *usb)
Get USB device host controller private data.
Definition usb.h:805
static void usb_endpoint_set_hostdata(struct usb_endpoint *ep, void *priv)
Set USB endpoint host controller private data.
Definition usb.h:586
@ USB_SPEED_FULL
Full speed (12Mbps).
Definition usb.h:51
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
struct list_head endpoints
List of all endpoints.
Definition uhci.h:323
struct list_head list
List of all endpoints.
Definition uhci.h:343
A USB device.
Definition usb.h:733
unsigned int address
Device address, if assigned.
Definition usb.h:743
struct usb_endpoint * ep[32]
Endpoint list.
Definition usb.h:755
unsigned int speed
Device speed.
Definition usb.h:739
size_t mtu
Maximum transfer size.
Definition usb.h:422
struct usb_device * usb
USB device.
Definition usb.h:416
unsigned int address
Endpoint address.
Definition usb.h:418
static int uhci_ring_alloc(struct uhci_ring *ring)
Allocate transfer ring.
Definition uhci.c:176
static void uhci_schedule_add(struct uhci_endpoint *endpoint)
Add endpoint to appropriate schedule.
Definition uhci.c:640
static void uhci_ring_free(struct uhci_ring *ring)
Free transfer ring.
Definition uhci.c:208
#define UHCI_FL_CERR_MAX
Error counter maximum value.
Definition uhci.h:149
#define UHCI_CONTROL_ENDPOINT(address)
Endpoint address.
Definition uhci.h:167
#define UHCI_FL_LS
Low speed device.
Definition uhci.h:152
#define UHCI_CONTROL_DEVICE(address)
Device address.
Definition uhci.h:164

References usb_device::address, usb_endpoint::address, uhci_ring::control, uhci_device::endpoints, ENOMEM, uhci_endpoint::ep, usb_device::ep, uhci_ring::flags, free, uhci_endpoint::list, list_add_tail, uhci_ring::mtu, usb_endpoint::mtu, rc, uhci_endpoint::ring, usb_device::speed, uhci_endpoint::uhci, UHCI_CONTROL_DEVICE, UHCI_CONTROL_ENDPOINT, UHCI_FL_CERR_MAX, UHCI_FL_LS, uhci_ring_alloc(), uhci_ring_free(), uhci_schedule_add(), usb_endpoint::usb, usb_endpoint_set_hostdata(), usb_get_hostdata(), USB_SPEED_FULL, and zalloc().

◆ uhci_endpoint_close()

void uhci_endpoint_close ( struct usb_endpoint * ep)
static

Close endpoint.

Parameters
epUSB endpoint

Definition at line 726 of file uhci.c.

726 {
727 struct uhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
728 struct io_buffer *iobuf;
729
730 /* Remove from schedule */
731 uhci_schedule_del ( endpoint );
732
733 /* Cancel any incomplete transfers */
734 while ( uhci_ring_fill ( &endpoint->ring ) ) {
735 iobuf = uhci_dequeue ( &endpoint->ring );
736 if ( iobuf )
737 usb_complete_err ( ep, iobuf, -ECANCELED );
738 }
739
740 /* Remove from list of endpoints */
741 list_del ( &endpoint->list );
742
743 /* Free descriptor ring */
744 uhci_ring_free ( &endpoint->ring );
745
746 /* Free endpoint */
747 free ( endpoint );
748}
#define ECANCELED
Operation canceled.
Definition errno.h:387
static void * usb_endpoint_get_hostdata(struct usb_endpoint *ep)
Get USB endpoint host controller private data.
Definition usb.h:597
static void uhci_schedule_del(struct uhci_endpoint *endpoint)
Remove endpoint from appropriate schedule.
Definition uhci.c:656
static struct io_buffer * uhci_dequeue(struct uhci_ring *ring)
Dequeue transfer.
Definition uhci.c:361
void usb_complete_err(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer (possibly with error).
Definition usb.c:586

References ECANCELED, uhci_endpoint::ep, free, uhci_endpoint::list, list_del, uhci_endpoint::ring, uhci_dequeue(), uhci_ring_fill(), uhci_ring_free(), uhci_schedule_del(), usb_complete_err(), and usb_endpoint_get_hostdata().

◆ uhci_endpoint_reset()

int uhci_endpoint_reset ( struct usb_endpoint * ep)
static

Reset endpoint.

Parameters
epUSB endpoint
Return values
rcReturn status code

Definition at line 756 of file uhci.c.

756 {
757 struct uhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
758 struct uhci_ring *ring = &endpoint->ring;
759
760 /* Restart ring */
761 uhci_restart ( ring, 0 );
762
763 return 0;
764}
A transfer ring.
Definition uhci.h:232
static void uhci_restart(struct uhci_ring *ring, uint32_t toggle)
Restart ring.
Definition uhci.c:395

References uhci_endpoint::ep, uhci_endpoint::ring, uhci_restart(), and usb_endpoint_get_hostdata().

◆ uhci_endpoint_mtu()

int uhci_endpoint_mtu ( struct usb_endpoint * ep)
static

Update MTU.

Parameters
epUSB endpoint
Return values
rcReturn status code

Definition at line 772 of file uhci.c.

772 {
773 struct uhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
774
775 /* Update endpoint MTU */
776 endpoint->ring.mtu = ep->mtu;
777
778 return 0;
779}

References uhci_endpoint::ep, uhci_ring::mtu, usb_endpoint::mtu, uhci_endpoint::ring, and usb_endpoint_get_hostdata().

◆ uhci_endpoint_message()

int uhci_endpoint_message ( struct usb_endpoint * ep,
struct io_buffer * iobuf )
static

Enqueue message transfer.

Parameters
epUSB endpoint
iobufI/O buffer
Return values
rcReturn status code

Definition at line 788 of file uhci.c.

789 {
790 struct uhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
791 struct uhci_ring *ring = &endpoint->ring;
792 struct usb_setup_packet *packet;
793 unsigned int count;
794 size_t len;
795 int input;
796 int rc;
797
798 /* Calculate number of descriptors */
799 assert ( iob_len ( iobuf ) >= sizeof ( *packet ) );
800 len = ( iob_len ( iobuf ) - sizeof ( *packet ) );
801 count = ( 1 /* setup stage */ +
802 ( ( len + ring->mtu - 1 ) / ring->mtu ) /* data stage */ +
803 1 /* status stage */ );
804
805 /* Enqueue transfer */
806 if ( ( rc = uhci_enqueue ( ring, iobuf, count ) ) != 0 )
807 return rc;
808
809 /* Describe setup stage */
810 packet = iobuf->data;
812 uhci_describe ( ring, packet, sizeof ( *packet ), USB_PID_SETUP );
813 iob_pull ( iobuf, sizeof ( *packet ) );
814
815 /* Describe data stage, if applicable */
817 input = ( packet->request & cpu_to_le16 ( USB_DIR_IN ) );
818 if ( len ) {
819 uhci_describe ( ring, iobuf->data, len,
820 ( input ? USB_PID_IN : USB_PID_OUT ) );
821 }
822
823 /* Describe status stage */
825 uhci_describe ( ring, NULL, 0,
826 ( ( len && input ) ? USB_PID_OUT : USB_PID_IN ) );
827
828 /* Sanity check */
829 assert ( ring->end->prod == count );
830
831 return 0;
832}
#define cpu_to_le16(value)
Definition byteswap.h:107
#define USB_DIR_IN
Data transfer is from device to host.
Definition usb.h:98
@ USB_PID_OUT
OUT PID.
Definition usb.h:77
@ USB_PID_SETUP
SETUP PID.
Definition usb.h:79
#define iob_pull(iobuf, len)
Definition iobuf.h:167
A USB setup data packet.
Definition usb.h:83
uint16_t request
Request.
Definition usb.h:85
static int uhci_enqueue(struct uhci_ring *ring, struct io_buffer *iobuf, unsigned int count)
Enqueue new transfer.
Definition uhci.c:228
static void uhci_describe(struct uhci_ring *ring, void *data, size_t len, uint8_t pid)
Describe transfer.
Definition uhci.c:320

References assert, uhci_ring::control, count, cpu_to_le16, io_buffer::data, uhci_ring::end, uhci_endpoint::ep, iob_len(), iob_pull, len, uhci_ring::mtu, NULL, uhci_transfer::prod, rc, usb_setup_packet::request, uhci_endpoint::ring, UHCI_CONTROL_TOGGLE, uhci_describe(), uhci_enqueue(), USB_DIR_IN, usb_endpoint_get_hostdata(), USB_PID_IN, USB_PID_OUT, and USB_PID_SETUP.

◆ uhci_endpoint_stream()

int uhci_endpoint_stream ( struct usb_endpoint * ep,
struct io_buffer * iobuf,
int zlp )
static

Enqueue stream transfer.

Parameters
epUSB endpoint
iobufI/O buffer
zlpAppend a zero-length packet
Return values
rcReturn status code

Definition at line 842 of file uhci.c.

843 {
844 struct uhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
845 struct uhci_ring *ring = &endpoint->ring;
846 unsigned int count;
847 size_t len;
848 int input;
849 int rc;
850
851 /* Calculate number of descriptors */
852 len = iob_len ( iobuf );
853 count = ( ( len + ring->mtu - 1 ) / ring->mtu );
854 if ( zlp || ( count == 0 ) )
855 count++;
856
857 /* Enqueue transfer */
858 if ( ( rc = uhci_enqueue ( ring, iobuf, count ) ) != 0 )
859 return rc;
860
861 /* Describe data packet */
862 input = ( ep->address & USB_DIR_IN );
863 uhci_describe ( ring, iobuf->data, len,
864 ( input ? USB_PID_IN : USB_PID_OUT ) );
865
866 /* Describe zero-length packet, if applicable */
867 if ( len && zlp )
868 uhci_describe ( ring, NULL, 0, USB_PID_OUT );
869
870 /* Sanity check */
871 assert ( ring->end->prod == count );
872
873 return 0;
874}

References usb_endpoint::address, assert, count, io_buffer::data, uhci_ring::end, uhci_endpoint::ep, iob_len(), len, uhci_ring::mtu, NULL, uhci_transfer::prod, rc, uhci_endpoint::ring, uhci_describe(), uhci_enqueue(), USB_DIR_IN, usb_endpoint_get_hostdata(), USB_PID_IN, and USB_PID_OUT.

◆ uhci_is_message()

int uhci_is_message ( struct uhci_transfer * xfer)
inlinestatic

Check if transfer is a message transfer.

Parameters
xferUHCI transfer
Return values
is_messageTransfer is a message transfer

Definition at line 882 of file uhci.c.

882 {
883 struct uhci_transfer_descriptor *desc = &xfer->desc[0];
884
885 return ( ( desc->control & cpu_to_le32 ( UHCI_CONTROL_PID_MASK ) ) ==
887}
#define UHCI_CONTROL_PID_MASK
Packet ID mask.
Definition uhci.h:161

References cpu_to_le32, desc, uhci_transfer::desc, UHCI_CONTROL_PID, UHCI_CONTROL_PID_MASK, and USB_PID_SETUP.

Referenced by uhci_endpoint_poll().

◆ uhci_endpoint_poll()

void uhci_endpoint_poll ( struct uhci_endpoint * endpoint)
static

Poll for completions.

Parameters
endpointEndpoint

Definition at line 894 of file uhci.c.

894 {
895 struct uhci_ring *ring = &endpoint->ring;
896 struct uhci_device *uhci = endpoint->uhci;
897 struct usb_endpoint *ep = endpoint->ep;
898 struct usb_device *usb = ep->usb;
899 struct uhci_transfer *xfer;
901 struct io_buffer *iobuf;
902 unsigned int index;
904 uint32_t toggle;
906 uint16_t actual;
907 size_t len;
908
909 /* Consume all completed descriptors */
910 while ( uhci_ring_fill ( ring ) ) {
911
912 /* Stop if we reach an uncompleted descriptor */
913 index = ( ring->cons % UHCI_RING_COUNT );
914 xfer = ring->xfer[index];
915 assert ( xfer != NULL );
916 assert ( xfer->cons < xfer->prod );
917 desc = &xfer->desc[xfer->cons];
918 rmb();
919 if ( desc->status & UHCI_STATUS_ACTIVE )
920 break;
921 control = le32_to_cpu ( desc->control );
922 actual = le16_to_cpu ( desc->actual );
923
924 /* Update data length, if applicable */
925 if ( UHCI_DATA_PACKET ( control ) )
926 xfer->len += UHCI_ACTUAL_LEN ( actual );
927
928 /* If we have encountered an error, then deactivate
929 * the queue head (to prevent further hardware
930 * accesses to this transfer), consume the transfer,
931 * and report the error to the USB core.
932 */
933 if ( desc->status & UHCI_STATUS_STALLED ) {
934 DBGC ( uhci, "UHCI %s %s completion %d.%d failed "
935 "(status %02x)\n", usb->name,
936 usb_endpoint_name ( ep ), index,
937 xfer->cons, desc->status );
939 ring->head->current = cpu_to_le32 ( link );
940 wmb();
941 iobuf = uhci_dequeue ( ring );
942 usb_complete_err ( ep, iobuf, -EIO );
943 break;
944 }
945
946 /* Consume this descriptor */
947 xfer->cons++;
948
949 /* Check for short packets */
950 if ( UHCI_SHORT_PACKET ( control, actual ) ) {
951
952 /* Sanity checks */
953 assert ( desc->flags & UHCI_FL_SPD );
954 link = virt_to_phys ( desc );
955 assert ( ( le32_to_cpu ( ring->head->current ) &
956 ~( UHCI_ALIGN - 1 ) ) == link );
957
958 /* If this is a message transfer, then restart
959 * at the status stage.
960 */
961 if ( uhci_is_message ( xfer ) ) {
962 xfer->cons = ( xfer->prod - 1 );
963 link = virt_to_phys ( &xfer->desc[xfer->cons] );
964 ring->head->current = cpu_to_le32 ( link );
965 break;
966 }
967
968 /* Otherwise, this is a stream transfer.
969 * First, prevent further hardware access to
970 * this transfer.
971 */
973 ring->head->current = cpu_to_le32 ( link );
974 wmb();
975
976 /* Determine expected data toggle for next descriptor */
977 toggle = ( ( control ^ UHCI_CONTROL_TOGGLE ) &
979
980 /* Consume this transfer */
981 len = xfer->len;
982 iobuf = uhci_dequeue ( ring );
983
984 /* Update packet length */
985 assert ( len <= iob_len ( iobuf ) );
986 iob_unput ( iobuf, ( iob_len ( iobuf ) - len ) );
987
988 /* Restart ring */
989 uhci_restart ( ring, toggle );
990
991 } else if ( xfer->cons == xfer->prod ) {
992
993 /* Completed a transfer: consume it */
994 len = xfer->len;
995 iobuf = uhci_dequeue ( ring );
996 assert ( len == iob_len ( iobuf ) );
997
998 } else {
999
1000 /* Not a short packet and not yet complete:
1001 * continue processing.
1002 */
1003 continue;
1004 }
1005
1006 /* Report completion to USB core */
1007 usb_complete ( ep, iobuf );
1008 }
1009}
#define EIO
Input/output error.
Definition errno.h:477
#define le16_to_cpu(value)
Definition byteswap.h:113
#define rmb()
Definition io.h:545
static void usb_complete(struct usb_endpoint *ep, struct io_buffer *iobuf)
Complete transfer (without error).
Definition usb.h:1097
#define iob_unput(iobuf, len)
Definition iobuf.h:200
char name[32]
Name.
Definition usb.h:735
static int uhci_is_message(struct uhci_transfer *xfer)
Check if transfer is a message transfer.
Definition uhci.c:882
#define UHCI_SHORT_PACKET(control, actual)
Check for short packet.
Definition uhci.h:183
#define UHCI_STATUS_STALLED
Stalled.
Definition uhci.h:125
#define UHCI_DATA_PACKET(control)
Check for data packet.
Definition uhci.h:180
#define UHCI_ACTUAL_LEN(actual)
Actual length.
Definition uhci.h:119
const char * usb_endpoint_name(struct usb_endpoint *ep)
Get USB endpoint name (for debugging).
Definition usb.c:220

References assert, uhci_ring::cons, uhci_transfer::cons, control, cpu_to_le32, uhci_queue_head::current, DBGC, desc, uhci_transfer::desc, EIO, uhci_endpoint::ep, usb_device::ep, uhci_ring::head, index, iob_len(), iob_unput, le16_to_cpu, le32_to_cpu, len, uhci_transfer::len, link, usb_device::name, NULL, uhci_transfer::prod, uhci_endpoint::ring, rmb, uhci_endpoint::uhci, UHCI_ACTUAL_LEN, UHCI_ALIGN, UHCI_CONTROL_TOGGLE, UHCI_DATA_PACKET, uhci_dequeue(), UHCI_FL_SPD, uhci_is_message(), UHCI_LINK_TERMINATE, uhci_restart(), UHCI_RING_COUNT, uhci_ring_fill(), UHCI_SHORT_PACKET, UHCI_STATUS_ACTIVE, UHCI_STATUS_STALLED, usb_endpoint::usb, usb_complete(), usb_complete_err(), usb_endpoint_name(), wmb, and uhci_ring::xfer.

Referenced by uhci_bus_poll().

◆ uhci_device_open()

int uhci_device_open ( struct usb_device * usb)
static

Open device.

Parameters
usbUSB device
Return values
rcReturn status code

Definition at line 1024 of file uhci.c.

1024 {
1025 struct uhci_device *uhci = usb_bus_get_hostdata ( usb->port->hub->bus );
1026
1027 usb_set_hostdata ( usb, uhci );
1028 return 0;
1029}
static void * usb_bus_get_hostdata(struct usb_bus *bus)
Get USB bus host controller private data.
Definition usb.h:1072
static void usb_set_hostdata(struct usb_device *usb, void *priv)
Set USB device host controller private data.
Definition usb.h:794
struct usb_port * port
USB port.
Definition usb.h:737
struct usb_bus * bus
USB bus.
Definition usb.h:855
struct usb_hub * hub
USB hub.
Definition usb.h:825

References usb_hub::bus, usb_port::hub, usb_device::port, usb_bus_get_hostdata(), and usb_set_hostdata().

◆ uhci_device_close()

void uhci_device_close ( struct usb_device * usb)
static

Close device.

Parameters
usbUSB device

Definition at line 1036 of file uhci.c.

1036 {
1037 struct uhci_device *uhci = usb_get_hostdata ( usb );
1038 struct usb_bus *bus = uhci->bus;
1039
1040 /* Free device address, if assigned */
1041 if ( usb->address )
1042 usb_free_address ( bus, usb->address );
1043}
uint8_t bus
Bus.
Definition edd.h:1
struct usb_bus * bus
USB bus.
Definition uhci.h:333
A USB bus.
Definition usb.h:976
void usb_free_address(struct usb_bus *bus, unsigned int address)
Free device address.
Definition usb.c:2283

References usb_device::address, bus, uhci_device::bus, usb_free_address(), and usb_get_hostdata().

◆ uhci_device_address()

int uhci_device_address ( struct usb_device * usb)
static

Assign device address.

Parameters
usbUSB device
Return values
rcReturn status code

Definition at line 1051 of file uhci.c.

1051 {
1052 struct uhci_device *uhci = usb_get_hostdata ( usb );
1053 struct usb_bus *bus = uhci->bus;
1054 struct usb_endpoint *ep0 = usb_endpoint ( usb, USB_EP0_ADDRESS );
1055 struct uhci_endpoint *endpoint0 = usb_endpoint_get_hostdata ( ep0 );
1056 int address;
1057 int rc;
1058
1059 /* Sanity checks */
1060 assert ( usb->address == 0 );
1061 assert ( ep0 != NULL );
1062
1063 /* Allocate device address */
1065 if ( address < 0 ) {
1066 rc = address;
1067 DBGC ( uhci, "UHCI %s could not allocate address: %s\n",
1068 usb->name, strerror ( rc ) );
1069 goto err_alloc_address;
1070 }
1071
1072 /* Set address */
1073 if ( ( rc = usb_set_address ( usb, address ) ) != 0 )
1074 goto err_set_address;
1075
1076 /* Update device address */
1077 usb->address = address;
1078 endpoint0->ring.control |= UHCI_CONTROL_DEVICE ( address );
1079
1080 return 0;
1081
1082 err_set_address:
1084 err_alloc_address:
1085 return rc;
1086}
uint64_t address
Base address.
Definition ena.h:13
static int usb_set_address(struct usb_device *usb, unsigned int address)
Set address.
Definition usb.h:1169
static struct usb_endpoint * usb_endpoint(struct usb_device *usb, unsigned int address)
Get USB endpoint.
Definition usb.h:816
#define USB_EP0_ADDRESS
Control endpoint address.
Definition usb.h:511
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int usb_alloc_address(struct usb_bus *bus)
Allocate device address.
Definition usb.c:2263

References address, usb_device::address, assert, bus, uhci_device::bus, uhci_ring::control, DBGC, usb_device::name, NULL, rc, uhci_endpoint::ring, strerror(), uhci_endpoint::uhci, UHCI_CONTROL_DEVICE, usb_endpoint::usb, usb_alloc_address(), usb_endpoint(), usb_endpoint_get_hostdata(), USB_EP0_ADDRESS, usb_free_address(), usb_get_hostdata(), and usb_set_address().

◆ uhci_hub_open()

int uhci_hub_open ( struct usb_hub *hub __unused)
static

Open hub.

Parameters
hubUSB hub
Return values
rcReturn status code

Definition at line 1101 of file uhci.c.

1101 {
1102
1103 /* Nothing to do */
1104 return 0;
1105}

References __unused.

◆ uhci_hub_close()

void uhci_hub_close ( struct usb_hub *hub __unused)
static

Close hub.

Parameters
hubUSB hub

Definition at line 1112 of file uhci.c.

1112 {
1113
1114 /* Nothing to do */
1115}

References __unused.

◆ uhci_root_open()

int uhci_root_open ( struct usb_hub *hub __unused)
static

Open root hub.

Parameters
hubUSB hub
Return values
rcReturn status code

Definition at line 1130 of file uhci.c.

1130 {
1131
1132 /* Nothing to do */
1133 return 0;
1134}

References __unused.

◆ uhci_root_close()

void uhci_root_close ( struct usb_hub *hub __unused)
static

Close root hub.

Parameters
hubUSB hub

Definition at line 1141 of file uhci.c.

1141 {
1142
1143 /* Nothing to do */
1144}

References __unused.

◆ uhci_root_enable()

int uhci_root_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 1153 of file uhci.c.

1153 {
1154 struct uhci_device *uhci = usb_hub_get_drvdata ( hub );
1155 uint16_t portsc;
1156 unsigned int i;
1157
1158 /* Reset port */
1159 portsc = inw ( uhci->regs + UHCI_PORTSC ( port->address ) );
1160 portsc |= UHCI_PORTSC_PR;
1161 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1163 portsc &= ~UHCI_PORTSC_PR;
1164 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1166
1167 /* Enable port */
1168 portsc |= UHCI_PORTSC_PED;
1169 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1171
1172 /* Wait for port to become enabled */
1173 for ( i = 0 ; i < UHCI_PORT_ENABLE_MAX_WAIT_MS ; i++ ) {
1174
1175 /* Check port status */
1176 portsc = inw ( uhci->regs + UHCI_PORTSC ( port->address ) );
1177 if ( portsc & UHCI_PORTSC_PED )
1178 return 0;
1179
1180 /* Delay */
1181 mdelay ( 1 );
1182 }
1183
1184 DBGC ( uhci, "UHCI %s-%d timed out waiting for port to enable "
1185 "(status %04x)\n", uhci->name, port->address, portsc );
1186 return -ETIMEDOUT;
1187}
u8 port
Port number.
Definition CIB_PRM.h:3
static void * usb_hub_get_drvdata(struct usb_hub *hub)
Get USB hub driver private data.
Definition usb.h:958
#define USB_RESET_RECOVER_DELAY_MS
Reset recovery time.
Definition usb.h:1345
#define USB_RESET_DELAY_MS
Minimum reset time.
Definition usb.h:1338
#define UHCI_PORTSC_PED
Port enabled.
Definition uhci.h:70
#define UHCI_PORTSC_PR
Port reset.
Definition uhci.h:61
#define UHCI_PORT_ENABLE_MAX_WAIT_MS
Maximum time to wait for a port to be enabled.
Definition uhci.h:305
#define UHCI_PORTSC(port)
Port status and control register.
Definition uhci.h:58

References DBGC, ETIMEDOUT, inw, mdelay(), uhci_device::name, outw, port, uhci_device::regs, UHCI_PORT_ENABLE_MAX_WAIT_MS, UHCI_PORTSC, UHCI_PORTSC_PED, UHCI_PORTSC_PR, usb_hub_get_drvdata(), USB_RESET_DELAY_MS, and USB_RESET_RECOVER_DELAY_MS.

◆ uhci_root_disable()

int uhci_root_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 1196 of file uhci.c.

1196 {
1197 struct uhci_device *uhci = usb_hub_get_drvdata ( hub );
1198 uint16_t portsc;
1199
1200 /* Disable port */
1201 portsc = inw ( uhci->regs + UHCI_PORTSC ( port->address ) );
1202 portsc &= ~UHCI_PORTSC_PED;
1203 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1204
1205 return 0;
1206}

References inw, outw, port, uhci_device::regs, UHCI_PORTSC, UHCI_PORTSC_PED, and usb_hub_get_drvdata().

◆ uhci_root_speed()

int uhci_root_speed ( struct usb_hub * hub,
struct usb_port * port )
static

Update root hub port speed.

Parameters
hubUSB hub
portUSB port
Return values
rcReturn status code

Definition at line 1215 of file uhci.c.

1215 {
1216 struct uhci_device *uhci = usb_hub_get_drvdata ( hub );
1217 struct pci_device pci;
1218 uint16_t portsc;
1219 unsigned int speed;
1220
1221 /* Read port status */
1222 portsc = inw ( uhci->regs + UHCI_PORTSC ( port->address ) );
1223 if ( ! ( portsc & UHCI_PORTSC_CCS ) ) {
1224 /* Port not connected */
1225 speed = USB_SPEED_NONE;
1226 } else if ( uhci->companion &&
1228 uhci->companion ) ) {
1229 /* Defer connection detection until companion
1230 * controller has been enumerated.
1231 */
1232 pci_init ( &pci, uhci->companion );
1233 DBGC ( uhci, "UHCI %s-%d deferring for companion " PCI_FMT "\n",
1234 uhci->name, port->address, PCI_ARGS ( &pci ) );
1235 speed = USB_SPEED_NONE;
1236 } else if ( portsc & UHCI_PORTSC_LS ) {
1237 /* Low-speed device */
1238 speed = USB_SPEED_LOW;
1239 } else {
1240 /* Full-speed device */
1241 speed = USB_SPEED_FULL;
1242 }
1243 port->speed = speed;
1244
1245 /* Record disconnections and clear changes */
1246 port->disconnected |= ( portsc & UHCI_PORTSC_CSC );
1247 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1248
1249 return 0;
1250}
#define BUS_TYPE_PCI
PCI bus type.
Definition device.h:44
@ USB_SPEED_LOW
Low speed (1.5Mbps).
Definition usb.h:49
@ USB_SPEED_NONE
Not connected.
Definition usb.h:47
#define PCI_FMT
PCI device debug message format.
Definition pci.h:315
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition pci.h:318
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition pci.h:345
A PCI device.
Definition pci.h:214
unsigned int companion
EHCI companion controller bus:dev.fn address (if any).
Definition uhci.h:315
#define UHCI_PORTSC_CCS
Current connect status.
Definition uhci.h:76
#define UHCI_PORTSC_LS
Low-speed device attached.
Definition uhci.h:64
#define UHCI_PORTSC_CSC
Connect status change.
Definition uhci.h:73
struct usb_bus * find_usb_bus_by_location(unsigned int bus_type, unsigned int location)
Find USB bus by device location.
Definition usb.c:2237

References BUS_TYPE_PCI, uhci_device::companion, DBGC, find_usb_bus_by_location(), inw, uhci_device::name, outw, PCI_ARGS, PCI_FMT, pci_init(), port, uhci_device::regs, UHCI_PORTSC, UHCI_PORTSC_CCS, UHCI_PORTSC_CSC, UHCI_PORTSC_LS, usb_hub_get_drvdata(), USB_SPEED_FULL, USB_SPEED_LOW, and USB_SPEED_NONE.

◆ uhci_root_clear_tt()

int uhci_root_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 1260 of file uhci.c.

1261 {
1262 struct uhci_device *uhci = usb_hub_get_drvdata ( hub );
1263
1264 /* Should never be called; this is a root hub */
1265 DBGC ( uhci, "UHCI %s-%d nonsensical CLEAR_TT for %s %s\n", uhci->name,
1266 port->address, ep->usb->name, usb_endpoint_name ( ep ) );
1267
1268 return -ENOTSUP;
1269}

References DBGC, ENOTSUP, uhci_device::name, usb_device::name, port, usb_endpoint::usb, usb_endpoint_name(), and usb_hub_get_drvdata().

◆ uhci_root_poll()

void uhci_root_poll ( struct usb_hub * hub,
struct usb_port * port )
static

Poll for port status changes.

Parameters
hubUSB hub
portUSB port

Definition at line 1277 of file uhci.c.

1277 {
1278 struct uhci_device *uhci = usb_hub_get_drvdata ( hub );
1279 uint16_t portsc;
1280 uint16_t change;
1281
1282 /* Do nothing unless something has changed */
1283 portsc = inw ( uhci->regs + UHCI_PORTSC ( port->address ) );
1284 change = ( portsc & UHCI_PORTSC_CHANGE );
1285 if ( ! change )
1286 return;
1287
1288 /* Record disconnections and clear changes */
1289 port->disconnected |= ( portsc & UHCI_PORTSC_CSC );
1290 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1291
1292 /* Report port status change */
1294}
#define UHCI_PORTSC_CHANGE
Port status change mask.
Definition uhci.h:79
void usb_port_changed(struct usb_port *port)
Report port status change.
Definition usb.c:1857

References inw, outw, port, uhci_device::regs, UHCI_PORTSC, UHCI_PORTSC_CHANGE, UHCI_PORTSC_CSC, usb_hub_get_drvdata(), and usb_port_changed().

Referenced by uhci_bus_poll().

◆ uhci_bus_open()

int uhci_bus_open ( struct usb_bus * bus)
static

Open USB bus.

Parameters
busUSB bus
Return values
rcReturn status code

Definition at line 1309 of file uhci.c.

1309 {
1310 struct uhci_device *uhci = usb_bus_get_hostdata ( bus );
1311 int rc;
1312
1313 /* Sanity checks */
1314 assert ( list_empty ( &uhci->async ) );
1315 assert ( list_empty ( &uhci->periodic ) );
1316
1317 /* Allocate and initialise asynchronous queue head */
1318 uhci->head = malloc_phys ( sizeof ( *uhci->head ), UHCI_ALIGN );
1319 if ( ! uhci->head ) {
1320 rc = -ENOMEM;
1321 goto err_alloc_head;
1322 }
1323 if ( ( rc = uhci_reachable ( uhci->head, sizeof ( *uhci->head ) ) ) !=0)
1324 goto err_unreachable_head;
1325 memset ( uhci->head, 0, sizeof ( *uhci->head ) );
1327 uhci_async_schedule ( uhci );
1328
1329 /* Allocate periodic frame list */
1330 uhci->frame = malloc_phys ( sizeof ( *uhci->frame ),
1331 sizeof ( *uhci->frame ) );
1332 if ( ! uhci->frame ) {
1333 rc = -ENOMEM;
1334 goto err_alloc_frame;
1335 }
1336 if ( ( rc = uhci_reachable ( uhci->frame,
1337 sizeof ( *uhci->frame ) ) ) != 0 )
1338 goto err_unreachable_frame;
1339 uhci_periodic_schedule ( uhci );
1340 outl ( virt_to_phys ( uhci->frame ), uhci->regs + UHCI_FLBASEADD );
1341
1342 /* Start controller */
1343 uhci_run ( uhci );
1344
1345 return 0;
1346
1347 uhci_stop ( uhci );
1348 err_unreachable_frame:
1349 free_phys ( uhci->frame, sizeof ( *uhci->frame ) );
1350 err_alloc_frame:
1351 err_unreachable_head:
1352 free_phys ( uhci->head, sizeof ( *uhci->head ) );
1353 err_alloc_head:
1354 return rc;
1355}
#define outl(data, io_addr)
Definition io.h:330
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
static void uhci_run(struct uhci_device *uhci)
Start UHCI device.
Definition uhci.c:84
#define UHCI_FLBASEADD
Frame list base address register.
Definition uhci.h:55

References assert, uhci_device::async, bus, cpu_to_le32, uhci_queue_head::current, ENOMEM, uhci_device::frame, free_phys(), uhci_device::head, list_empty, malloc_phys(), memset(), outl, uhci_device::periodic, rc, uhci_device::regs, UHCI_ALIGN, uhci_async_schedule(), UHCI_FLBASEADD, UHCI_LINK_TERMINATE, uhci_periodic_schedule(), uhci_reachable(), uhci_run(), uhci_stop(), and usb_bus_get_hostdata().

◆ uhci_bus_close()

void uhci_bus_close ( struct usb_bus * bus)
static

Close USB bus.

Parameters
busUSB bus

Definition at line 1362 of file uhci.c.

1362 {
1363 struct uhci_device *uhci = usb_bus_get_hostdata ( bus );
1364
1365 /* Sanity checks */
1366 assert ( list_empty ( &uhci->async ) );
1367 assert ( list_empty ( &uhci->periodic ) );
1368
1369 /* Stop controller */
1370 uhci_stop ( uhci );
1371
1372 /* Free periodic frame list */
1373 free_phys ( uhci->frame, sizeof ( *uhci->frame ) );
1374
1375 /* Free asynchronous schedule */
1376 free_phys ( uhci->head, sizeof ( *uhci->head ) );
1377}

References assert, uhci_device::async, bus, uhci_device::frame, free_phys(), uhci_device::head, list_empty, uhci_device::periodic, uhci_stop(), and usb_bus_get_hostdata().

◆ uhci_bus_poll()

void uhci_bus_poll ( struct usb_bus * bus)
static

Poll USB bus.

Parameters
busUSB bus

Definition at line 1384 of file uhci.c.

1384 {
1385 struct uhci_device *uhci = usb_bus_get_hostdata ( bus );
1386 struct usb_hub *hub = bus->hub;
1387 struct uhci_endpoint *endpoint;
1388 unsigned int i;
1389
1390 /* UHCI defers interrupts (including short packet detection)
1391 * until the end of the frame. This can result in bulk IN
1392 * endpoints remaining halted for much of the time, waiting
1393 * for software action to reset the data toggles. We
1394 * therefore ignore USBSTS and unconditionally poll all
1395 * endpoints for completed transfer descriptors.
1396 *
1397 * As with EHCI, we trust that completion handlers are minimal
1398 * and will not do anything that could plausibly affect the
1399 * endpoint list itself.
1400 */
1401 list_for_each_entry ( endpoint, &uhci->endpoints, list )
1402 uhci_endpoint_poll ( endpoint );
1403
1404 /* UHCI provides no single bit to indicate that a port status
1405 * change has occurred. We therefore unconditionally iterate
1406 * over all ports looking for status changes.
1407 */
1408 for ( i = 1 ; i <= UHCI_PORTS ; i++ )
1409 uhci_root_poll ( hub, usb_port ( hub, i ) );
1410}
A USB hub.
Definition usb.h:851
A USB port.
Definition usb.h:823
static void uhci_endpoint_poll(struct uhci_endpoint *endpoint)
Poll for completions.
Definition uhci.c:894
static void uhci_root_poll(struct usb_hub *hub, struct usb_port *port)
Poll for port status changes.
Definition uhci.c:1277
#define UHCI_PORTS
Number of ports.
Definition uhci.h:25

References bus, uhci_device::endpoints, uhci_endpoint::list, list_for_each_entry, uhci_endpoint::uhci, uhci_endpoint_poll(), UHCI_PORTS, uhci_root_poll(), and usb_bus_get_hostdata().

◆ ehci_companion()

__weak unsigned int ehci_companion ( struct pci_device *pci __unused)

Locate EHCI companion controller (when no EHCI support is present).

Parameters
pciPCI device
Return values
busdevfnEHCI companion controller bus:dev.fn (if any)

Definition at line 1459 of file uhci.c.

1459 {
1460 return 0;
1461}

References __unused, and __weak.

Referenced by uhci_probe().

◆ uhci_probe()

int uhci_probe ( struct pci_device * pci)
static

Probe PCI device.

Parameters
pciPCI device
Return values
rcReturn status code

Definition at line 1469 of file uhci.c.

1469 {
1470 struct uhci_device *uhci;
1471 struct usb_port *port;
1472 unsigned int i;
1473 int rc;
1474
1475 /* Allocate and initialise structure */
1476 uhci = zalloc ( sizeof ( *uhci ) );
1477 if ( ! uhci ) {
1478 rc = -ENOMEM;
1479 goto err_alloc;
1480 }
1481 uhci->name = pci->dev.name;
1482 INIT_LIST_HEAD ( &uhci->endpoints );
1483 INIT_LIST_HEAD ( &uhci->async );
1484 INIT_LIST_HEAD ( &uhci->periodic );
1485
1486 /* Fix up PCI device */
1487 adjust_pci_device ( pci );
1488
1489 /* Identify EHCI companion controller, if any */
1490 uhci->companion = ehci_companion ( pci );
1491
1492 /* Claim ownership from BIOS. (There is no release mechanism
1493 * for UHCI.)
1494 */
1496
1497 /* Map registers */
1498 uhci->regs = pci->ioaddr;
1499 if ( ! uhci->regs ) {
1500 rc = -ENODEV;
1501 goto err_ioremap;
1502 }
1503
1504 /* Reset device */
1505 if ( ( rc = uhci_reset ( uhci ) ) != 0 )
1506 goto err_reset;
1507
1508 /* Allocate USB bus */
1509 uhci->bus = alloc_usb_bus ( &pci->dev, UHCI_PORTS, UHCI_MTU,
1510 &uhci_operations );
1511 if ( ! uhci->bus ) {
1512 rc = -ENOMEM;
1513 goto err_alloc_bus;
1514 }
1515 usb_bus_set_hostdata ( uhci->bus, uhci );
1516 usb_hub_set_drvdata ( uhci->bus->hub, uhci );
1517
1518 /* Set port protocols */
1519 for ( i = 1 ; i <= UHCI_PORTS ; i++ ) {
1520 port = usb_port ( uhci->bus->hub, i );
1521 port->protocol = USB_PROTO_2_0;
1522 }
1523
1524 /* Register USB bus */
1525 if ( ( rc = register_usb_bus ( uhci->bus ) ) != 0 )
1526 goto err_register;
1527
1528 pci_set_drvdata ( pci, uhci );
1529 return 0;
1530
1531 unregister_usb_bus ( uhci->bus );
1532 err_register:
1533 free_usb_bus ( uhci->bus );
1534 err_alloc_bus:
1535 uhci_reset ( uhci );
1536 err_reset:
1537 err_ioremap:
1538 free ( uhci );
1539 err_alloc:
1540 return rc;
1541}
#define ENODEV
No such device.
Definition errno.h:553
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
@ USB_PROTO_2_0
USB 2.0.
Definition usb.h:23
static struct usb_port * usb_port(struct usb_hub *hub, unsigned int address)
Get USB port.
Definition usb.h:970
static void usb_hub_set_drvdata(struct usb_hub *hub, void *priv)
Set USB hub driver private data.
Definition usb.h:947
static void usb_bus_set_hostdata(struct usb_bus *bus, void *priv)
Set USB bus host controller private data.
Definition usb.h:1061
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition pci.c:255
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition pci.h:370
char name[40]
Name.
Definition device.h:79
unsigned long ioaddr
I/O address.
Definition pci.h:229
struct device dev
Generic device.
Definition pci.h:216
struct usb_hub * hub
Root hub.
Definition usb.h:1005
static int uhci_reset(struct uhci_device *uhci)
Reset UHCI device.
Definition uhci.c:131
__weak unsigned int ehci_companion(struct pci_device *pci __unused)
Locate EHCI companion controller (when no EHCI support is present).
Definition uhci.c:1459
static struct usb_host_operations uhci_operations
USB host controller operations.
Definition uhci.c:1420
#define UHCI_MTU
Maximum transfer size.
Definition uhci.h:28
#define UHCI_USBLEGSUP
USB legacy support register (in PCI configuration space).
Definition uhci.h:187
#define UHCI_USBLEGSUP_DEFAULT
USB legacy support default value.
Definition uhci.h:190
void unregister_usb_bus(struct usb_bus *bus)
Unregister USB bus.
Definition usb.c:2170
int register_usb_bus(struct usb_bus *bus)
Register USB bus.
Definition usb.c:2130
struct usb_bus * alloc_usb_bus(struct device *dev, unsigned int ports, size_t mtu, struct usb_host_operations *op)
Allocate USB bus.
Definition usb.c:2094
void free_usb_bus(struct usb_bus *bus)
Free USB bus.
Definition usb.c:2194

References adjust_pci_device(), alloc_usb_bus(), uhci_device::async, uhci_device::bus, uhci_device::companion, pci_device::dev, ehci_companion(), uhci_device::endpoints, ENODEV, ENOMEM, free, free_usb_bus(), usb_bus::hub, INIT_LIST_HEAD, pci_device::ioaddr, device::name, uhci_device::name, pci_set_drvdata(), pci_write_config_word(), uhci_device::periodic, port, rc, register_usb_bus(), uhci_device::regs, UHCI_MTU, uhci_operations, UHCI_PORTS, uhci_reset(), UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT, unregister_usb_bus(), usb_bus_set_hostdata(), usb_hub_set_drvdata(), usb_port(), USB_PROTO_2_0, and zalloc().

◆ uhci_remove()

void uhci_remove ( struct pci_device * pci)
static

Remove PCI device.

Parameters
pciPCI device

Definition at line 1548 of file uhci.c.

1548 {
1549 struct uhci_device *uhci = pci_get_drvdata ( pci );
1550 struct usb_bus *bus = uhci->bus;
1551
1553 assert ( list_empty ( &uhci->async ) );
1554 assert ( list_empty ( &uhci->periodic ) );
1555 free_usb_bus ( bus );
1556 uhci_reset ( uhci );
1557 free ( uhci );
1558}
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition pci.h:380

References assert, uhci_device::async, bus, uhci_device::bus, free, free_usb_bus(), list_empty, pci_get_drvdata(), uhci_device::periodic, uhci_reset(), and unregister_usb_bus().

Variable Documentation

◆ uhci_operations

struct usb_host_operations uhci_operations
static

USB host controller operations.

Definition at line 1420 of file uhci.c.

1420 {
1421 .endpoint = {
1422 .open = uhci_endpoint_open,
1423 .close = uhci_endpoint_close,
1424 .reset = uhci_endpoint_reset,
1425 .mtu = uhci_endpoint_mtu,
1426 .message = uhci_endpoint_message,
1427 .stream = uhci_endpoint_stream,
1428 },
1429 .device = {
1430 .open = uhci_device_open,
1431 .close = uhci_device_close,
1432 .address = uhci_device_address,
1433 },
1434 .bus = {
1435 .open = uhci_bus_open,
1436 .close = uhci_bus_close,
1437 .poll = uhci_bus_poll,
1438 },
1439 .hub = {
1440 .open = uhci_hub_open,
1441 .close = uhci_hub_close,
1442 },
1443 .root = {
1444 .open = uhci_root_open,
1445 .close = uhci_root_close,
1446 .enable = uhci_root_enable,
1447 .disable = uhci_root_disable,
1448 .speed = uhci_root_speed,
1449 .clear_tt = uhci_root_clear_tt,
1450 },
1451};
static void uhci_endpoint_close(struct usb_endpoint *ep)
Close endpoint.
Definition uhci.c:726
static void uhci_device_close(struct usb_device *usb)
Close device.
Definition uhci.c:1036
static int uhci_root_speed(struct usb_hub *hub, struct usb_port *port)
Update root hub port speed.
Definition uhci.c:1215
static int uhci_endpoint_message(struct usb_endpoint *ep, struct io_buffer *iobuf)
Enqueue message transfer.
Definition uhci.c:788
static int uhci_device_address(struct usb_device *usb)
Assign device address.
Definition uhci.c:1051
static int uhci_endpoint_mtu(struct usb_endpoint *ep)
Update MTU.
Definition uhci.c:772
static void uhci_bus_poll(struct usb_bus *bus)
Poll USB bus.
Definition uhci.c:1384
static int uhci_hub_open(struct usb_hub *hub __unused)
Open hub.
Definition uhci.c:1101
static void uhci_root_close(struct usb_hub *hub __unused)
Close root hub.
Definition uhci.c:1141
static void uhci_hub_close(struct usb_hub *hub __unused)
Close hub.
Definition uhci.c:1112
static int uhci_endpoint_open(struct usb_endpoint *ep)
Open endpoint.
Definition uhci.c:680
static int uhci_root_clear_tt(struct usb_hub *hub, struct usb_port *port, struct usb_endpoint *ep)
Clear transaction translator buffer.
Definition uhci.c:1260
static int uhci_bus_open(struct usb_bus *bus)
Open USB bus.
Definition uhci.c:1309
static int uhci_root_enable(struct usb_hub *hub, struct usb_port *port)
Enable port.
Definition uhci.c:1153
static int uhci_device_open(struct usb_device *usb)
Open device.
Definition uhci.c:1024
static int uhci_endpoint_reset(struct usb_endpoint *ep)
Reset endpoint.
Definition uhci.c:756
static int uhci_root_disable(struct usb_hub *hub, struct usb_port *port)
Disable port.
Definition uhci.c:1196
static int uhci_endpoint_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int zlp)
Enqueue stream transfer.
Definition uhci.c:842
static int uhci_root_open(struct usb_hub *hub __unused)
Open root hub.
Definition uhci.c:1130
static void uhci_bus_close(struct usb_bus *bus)
Close USB bus.
Definition uhci.c:1362

Referenced by uhci_probe().

◆ uhci_ids

struct pci_device_id uhci_ids[]
static
Initial value:
= {
PCI_ROM ( 0xffff, 0xffff, "uhci", "UHCI", 0 ),
}
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition pci.h:311

UHCI PCI device IDs.

Definition at line 1561 of file uhci.c.

1561 {
1562 PCI_ROM ( 0xffff, 0xffff, "uhci", "UHCI", 0 ),
1563};

◆ __pci_driver

struct pci_driver uhci_driver __pci_driver
Initial value:
= {
.ids = uhci_ids,
.id_count = ( sizeof ( uhci_ids ) / sizeof ( uhci_ids[0] ) ),
.probe = uhci_probe,
.remove = uhci_remove,
}
#define PCI_CLASS_SERIAL
Definition Pci22.h:266
#define PCI_CLASS_SERIAL_USB
Definition Pci22.h:272
#define PCI_CLASS_SERIAL_USB_UHCI
UHCI USB controller.
Definition pci.h:141
#define PCI_CLASS_ID(base, sub, progif)
Construct PCI class ID.
Definition pci.h:206
static struct pci_device_id uhci_ids[]
UHCI PCI device IDs.
Definition uhci.c:1561
static int uhci_probe(struct pci_device *pci)
Probe PCI device.
Definition uhci.c:1469
static void uhci_remove(struct pci_device *pci)
Remove PCI device.
Definition uhci.c:1548

UHCI PCI driver.

Definition at line 1566 of file uhci.c.

1566 {
1567 .ids = uhci_ids,
1568 .id_count = ( sizeof ( uhci_ids ) / sizeof ( uhci_ids[0] ) ),
1571 .probe = uhci_probe,
1572 .remove = uhci_remove,
1573};