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:590

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:505
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
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:535
#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:707
void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition malloc.c:723
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:322
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
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:65
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:499
#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:160
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
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:53
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 = 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:38
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:539
#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:416
#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:404
unsigned int attributes
Attributes.
Definition usb.h:410
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:795
static void usb_endpoint_set_hostdata(struct usb_endpoint *ep, void *priv)
Set USB endpoint host controller private data.
Definition usb.h:576
@ USB_SPEED_FULL
Full speed (12Mbps)
Definition usb.h:51
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
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:723
unsigned int address
Device address, if assigned.
Definition usb.h:733
struct usb_endpoint * ep[32]
Endpoint list.
Definition usb.h:745
unsigned int speed
Device speed.
Definition usb.h:729
size_t mtu
Maximum transfer size.
Definition usb.h:412
struct usb_device * usb
USB device.
Definition usb.h:406
unsigned int address
Endpoint address.
Definition usb.h:408
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:344
static void * usb_endpoint_get_hostdata(struct usb_endpoint *ep)
Get USB endpoint host controller private data.
Definition usb.h:587
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:587

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:107
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 ) + ( zlp ? 1 : 0 ) );
854
855 /* Enqueue transfer */
856 if ( ( rc = uhci_enqueue ( ring, iobuf, count ) ) != 0 )
857 return rc;
858
859 /* Describe data packet */
860 input = ( ep->address & USB_DIR_IN );
861 uhci_describe ( ring, iobuf->data, len,
862 ( input ? USB_PID_IN : USB_PID_OUT ) );
863
864 /* Describe zero-length packet, if applicable */
865 if ( zlp )
866 uhci_describe ( ring, NULL, 0, USB_PID_OUT );
867
868 /* Sanity check */
869 assert ( ring->end->prod == count );
870
871 return 0;
872}

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 880 of file uhci.c.

880 {
881 struct uhci_transfer_descriptor *desc = &xfer->desc[0];
882
883 return ( ( desc->control & cpu_to_le32 ( UHCI_CONTROL_PID_MASK ) ) ==
885}
#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 892 of file uhci.c.

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

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 1022 of file uhci.c.

1022 {
1023 struct uhci_device *uhci = usb_bus_get_hostdata ( usb->port->hub->bus );
1024
1025 usb_set_hostdata ( usb, uhci );
1026 return 0;
1027}
static void * usb_bus_get_hostdata(struct usb_bus *bus)
Get USB bus host controller private data.
Definition usb.h:1062
static void usb_set_hostdata(struct usb_device *usb, void *priv)
Set USB device host controller private data.
Definition usb.h:784
struct usb_port * port
USB port.
Definition usb.h:727
struct usb_bus * bus
USB bus.
Definition usb.h:845
struct usb_hub * hub
USB hub.
Definition usb.h:815

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 1034 of file uhci.c.

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

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 1049 of file uhci.c.

1049 {
1050 struct uhci_device *uhci = usb_get_hostdata ( usb );
1051 struct usb_bus *bus = uhci->bus;
1052 struct usb_endpoint *ep0 = usb_endpoint ( usb, USB_EP0_ADDRESS );
1053 struct uhci_endpoint *endpoint0 = usb_endpoint_get_hostdata ( ep0 );
1054 int address;
1055 int rc;
1056
1057 /* Sanity checks */
1058 assert ( usb->address == 0 );
1059 assert ( ep0 != NULL );
1060
1061 /* Allocate device address */
1063 if ( address < 0 ) {
1064 rc = address;
1065 DBGC ( uhci, "UHCI %s could not allocate address: %s\n",
1066 usb->name, strerror ( rc ) );
1067 goto err_alloc_address;
1068 }
1069
1070 /* Set address */
1071 if ( ( rc = usb_set_address ( usb, address ) ) != 0 )
1072 goto err_set_address;
1073
1074 /* Update device address */
1075 usb->address = address;
1076 endpoint0->ring.control |= UHCI_CONTROL_DEVICE ( address );
1077
1078 return 0;
1079
1080 err_set_address:
1082 err_alloc_address:
1083 return rc;
1084}
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:1159
static struct usb_endpoint * usb_endpoint(struct usb_device *usb, unsigned int address)
Get USB endpoint.
Definition usb.h:806
#define USB_EP0_ADDRESS
Control endpoint address.
Definition usb.h:501
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:2264

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 1099 of file uhci.c.

1099 {
1100
1101 /* Nothing to do */
1102 return 0;
1103}

References __unused.

◆ uhci_hub_close()

void uhci_hub_close ( struct usb_hub *hub __unused)
static

Close hub.

Parameters
hubUSB hub

Definition at line 1110 of file uhci.c.

1110 {
1111
1112 /* Nothing to do */
1113}

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 1128 of file uhci.c.

1128 {
1129
1130 /* Nothing to do */
1131 return 0;
1132}

References __unused.

◆ uhci_root_close()

void uhci_root_close ( struct usb_hub *hub __unused)
static

Close root hub.

Parameters
hubUSB hub

Definition at line 1139 of file uhci.c.

1139 {
1140
1141 /* Nothing to do */
1142}

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 1151 of file uhci.c.

1151 {
1152 struct uhci_device *uhci = usb_hub_get_drvdata ( hub );
1153 uint16_t portsc;
1154 unsigned int i;
1155
1156 /* Reset port */
1157 portsc = inw ( uhci->regs + UHCI_PORTSC ( port->address ) );
1158 portsc |= UHCI_PORTSC_PR;
1159 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1161 portsc &= ~UHCI_PORTSC_PR;
1162 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1164
1165 /* Enable port */
1166 portsc |= UHCI_PORTSC_PED;
1167 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1169
1170 /* Wait for port to become enabled */
1171 for ( i = 0 ; i < UHCI_PORT_ENABLE_MAX_WAIT_MS ; i++ ) {
1172
1173 /* Check port status */
1174 portsc = inw ( uhci->regs + UHCI_PORTSC ( port->address ) );
1175 if ( portsc & UHCI_PORTSC_PED )
1176 return 0;
1177
1178 /* Delay */
1179 mdelay ( 1 );
1180 }
1181
1182 DBGC ( uhci, "UHCI %s-%d timed out waiting for port to enable "
1183 "(status %04x)\n", uhci->name, port->address, portsc );
1184 return -ETIMEDOUT;
1185}
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:948
#define USB_RESET_RECOVER_DELAY_MS
Reset recovery time.
Definition usb.h:1335
#define USB_RESET_DELAY_MS
Minimum reset time.
Definition usb.h:1328
#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 1194 of file uhci.c.

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

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 1213 of file uhci.c.

1213 {
1214 struct uhci_device *uhci = usb_hub_get_drvdata ( hub );
1215 struct pci_device pci;
1216 uint16_t portsc;
1217 unsigned int speed;
1218
1219 /* Read port status */
1220 portsc = inw ( uhci->regs + UHCI_PORTSC ( port->address ) );
1221 if ( ! ( portsc & UHCI_PORTSC_CCS ) ) {
1222 /* Port not connected */
1223 speed = USB_SPEED_NONE;
1224 } else if ( uhci->companion &&
1226 uhci->companion ) ) {
1227 /* Defer connection detection until companion
1228 * controller has been enumerated.
1229 */
1230 pci_init ( &pci, uhci->companion );
1231 DBGC ( uhci, "UHCI %s-%d deferring for companion " PCI_FMT "\n",
1232 uhci->name, port->address, PCI_ARGS ( &pci ) );
1233 speed = USB_SPEED_NONE;
1234 } else if ( portsc & UHCI_PORTSC_LS ) {
1235 /* Low-speed device */
1236 speed = USB_SPEED_LOW;
1237 } else {
1238 /* Full-speed device */
1239 speed = USB_SPEED_FULL;
1240 }
1241 port->speed = speed;
1242
1243 /* Record disconnections and clear changes */
1244 port->disconnected |= ( portsc & UHCI_PORTSC_CSC );
1245 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1246
1247 return 0;
1248}
#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:312
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition pci.h:315
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition pci.h:341
A PCI device.
Definition pci.h:211
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:2238

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 1258 of file uhci.c.

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

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 1275 of file uhci.c.

1275 {
1276 struct uhci_device *uhci = usb_hub_get_drvdata ( hub );
1277 uint16_t portsc;
1278 uint16_t change;
1279
1280 /* Do nothing unless something has changed */
1281 portsc = inw ( uhci->regs + UHCI_PORTSC ( port->address ) );
1282 change = ( portsc & UHCI_PORTSC_CHANGE );
1283 if ( ! change )
1284 return;
1285
1286 /* Record disconnections and clear changes */
1287 port->disconnected |= ( portsc & UHCI_PORTSC_CSC );
1288 outw ( portsc, uhci->regs + UHCI_PORTSC ( port->address ) );
1289
1290 /* Report port status change */
1292}
#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:1858

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 1307 of file uhci.c.

1307 {
1308 struct uhci_device *uhci = usb_bus_get_hostdata ( bus );
1309 int rc;
1310
1311 /* Sanity checks */
1312 assert ( list_empty ( &uhci->async ) );
1313 assert ( list_empty ( &uhci->periodic ) );
1314
1315 /* Allocate and initialise asynchronous queue head */
1316 uhci->head = malloc_phys ( sizeof ( *uhci->head ), UHCI_ALIGN );
1317 if ( ! uhci->head ) {
1318 rc = -ENOMEM;
1319 goto err_alloc_head;
1320 }
1321 if ( ( rc = uhci_reachable ( uhci->head, sizeof ( *uhci->head ) ) ) !=0)
1322 goto err_unreachable_head;
1323 memset ( uhci->head, 0, sizeof ( *uhci->head ) );
1325 uhci_async_schedule ( uhci );
1326
1327 /* Allocate periodic frame list */
1328 uhci->frame = malloc_phys ( sizeof ( *uhci->frame ),
1329 sizeof ( *uhci->frame ) );
1330 if ( ! uhci->frame ) {
1331 rc = -ENOMEM;
1332 goto err_alloc_frame;
1333 }
1334 if ( ( rc = uhci_reachable ( uhci->frame,
1335 sizeof ( *uhci->frame ) ) ) != 0 )
1336 goto err_unreachable_frame;
1337 uhci_periodic_schedule ( uhci );
1338 outl ( virt_to_phys ( uhci->frame ), uhci->regs + UHCI_FLBASEADD );
1339
1340 /* Start controller */
1341 uhci_run ( uhci );
1342
1343 return 0;
1344
1345 uhci_stop ( uhci );
1346 err_unreachable_frame:
1347 free_phys ( uhci->frame, sizeof ( *uhci->frame ) );
1348 err_alloc_frame:
1349 err_unreachable_head:
1350 free_phys ( uhci->head, sizeof ( *uhci->head ) );
1351 err_alloc_head:
1352 return rc;
1353}
#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 1360 of file uhci.c.

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

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 1382 of file uhci.c.

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

1457 {
1458 return 0;
1459}

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 1467 of file uhci.c.

1467 {
1468 struct uhci_device *uhci;
1469 struct usb_port *port;
1470 unsigned int i;
1471 int rc;
1472
1473 /* Allocate and initialise structure */
1474 uhci = zalloc ( sizeof ( *uhci ) );
1475 if ( ! uhci ) {
1476 rc = -ENOMEM;
1477 goto err_alloc;
1478 }
1479 uhci->name = pci->dev.name;
1480 INIT_LIST_HEAD ( &uhci->endpoints );
1481 INIT_LIST_HEAD ( &uhci->async );
1482 INIT_LIST_HEAD ( &uhci->periodic );
1483
1484 /* Fix up PCI device */
1485 adjust_pci_device ( pci );
1486
1487 /* Identify EHCI companion controller, if any */
1488 uhci->companion = ehci_companion ( pci );
1489
1490 /* Claim ownership from BIOS. (There is no release mechanism
1491 * for UHCI.)
1492 */
1494
1495 /* Map registers */
1496 uhci->regs = pci->ioaddr;
1497 if ( ! uhci->regs ) {
1498 rc = -ENODEV;
1499 goto err_ioremap;
1500 }
1501
1502 /* Reset device */
1503 if ( ( rc = uhci_reset ( uhci ) ) != 0 )
1504 goto err_reset;
1505
1506 /* Allocate USB bus */
1507 uhci->bus = alloc_usb_bus ( &pci->dev, UHCI_PORTS, UHCI_MTU,
1508 &uhci_operations );
1509 if ( ! uhci->bus ) {
1510 rc = -ENOMEM;
1511 goto err_alloc_bus;
1512 }
1513 usb_bus_set_hostdata ( uhci->bus, uhci );
1514 usb_hub_set_drvdata ( uhci->bus->hub, uhci );
1515
1516 /* Set port protocols */
1517 for ( i = 1 ; i <= UHCI_PORTS ; i++ ) {
1518 port = usb_port ( uhci->bus->hub, i );
1519 port->protocol = USB_PROTO_2_0;
1520 }
1521
1522 /* Register USB bus */
1523 if ( ( rc = register_usb_bus ( uhci->bus ) ) != 0 )
1524 goto err_register;
1525
1526 pci_set_drvdata ( pci, uhci );
1527 return 0;
1528
1529 unregister_usb_bus ( uhci->bus );
1530 err_register:
1531 free_usb_bus ( uhci->bus );
1532 err_alloc_bus:
1533 uhci_reset ( uhci );
1534 err_reset:
1535 err_ioremap:
1536 free ( uhci );
1537 err_alloc:
1538 return rc;
1539}
#define ENODEV
No such device.
Definition errno.h:510
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:960
static void usb_hub_set_drvdata(struct usb_hub *hub, void *priv)
Set USB hub driver private data.
Definition usb.h:937
static void usb_bus_set_hostdata(struct usb_bus *bus, void *priv)
Set USB bus host controller private data.
Definition usb.h:1051
#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:241
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition pci.h:366
char name[40]
Name.
Definition device.h:79
unsigned long ioaddr
I/O address.
Definition pci.h:226
struct device dev
Generic device.
Definition pci.h:213
struct usb_hub * hub
Root hub.
Definition usb.h:995
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:1457
static struct usb_host_operations uhci_operations
USB host controller operations.
Definition uhci.c:1418
#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:2171
int register_usb_bus(struct usb_bus *bus)
Register USB bus.
Definition usb.c:2131
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:2095
void free_usb_bus(struct usb_bus *bus)
Free USB bus.
Definition usb.c:2195

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 1546 of file uhci.c.

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

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 1418 of file uhci.c.

1418 {
1419 .endpoint = {
1420 .open = uhci_endpoint_open,
1421 .close = uhci_endpoint_close,
1422 .reset = uhci_endpoint_reset,
1423 .mtu = uhci_endpoint_mtu,
1424 .message = uhci_endpoint_message,
1425 .stream = uhci_endpoint_stream,
1426 },
1427 .device = {
1428 .open = uhci_device_open,
1429 .close = uhci_device_close,
1430 .address = uhci_device_address,
1431 },
1432 .bus = {
1433 .open = uhci_bus_open,
1434 .close = uhci_bus_close,
1435 .poll = uhci_bus_poll,
1436 },
1437 .hub = {
1438 .open = uhci_hub_open,
1439 .close = uhci_hub_close,
1440 },
1441 .root = {
1442 .open = uhci_root_open,
1443 .close = uhci_root_close,
1444 .enable = uhci_root_enable,
1445 .disable = uhci_root_disable,
1446 .speed = uhci_root_speed,
1447 .clear_tt = uhci_root_clear_tt,
1448 },
1449};
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:1034
static int uhci_root_speed(struct usb_hub *hub, struct usb_port *port)
Update root hub port speed.
Definition uhci.c:1213
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:1049
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:1382
static int uhci_hub_open(struct usb_hub *hub __unused)
Open hub.
Definition uhci.c:1099
static void uhci_root_close(struct usb_hub *hub __unused)
Close root hub.
Definition uhci.c:1139
static void uhci_hub_close(struct usb_hub *hub __unused)
Close hub.
Definition uhci.c:1110
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:1258
static int uhci_bus_open(struct usb_bus *bus)
Open USB bus.
Definition uhci.c:1307
static int uhci_root_enable(struct usb_hub *hub, struct usb_port *port)
Enable port.
Definition uhci.c:1151
static int uhci_device_open(struct usb_device *usb)
Open device.
Definition uhci.c:1022
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:1194
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:1128
static void uhci_bus_close(struct usb_bus *bus)
Close USB bus.
Definition uhci.c:1360

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:308

UHCI PCI device IDs.

Definition at line 1559 of file uhci.c.

1559 {
1560 PCI_ROM ( 0xffff, 0xffff, "uhci", "UHCI", 0 ),
1561};

◆ __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:267
#define PCI_CLASS_SERIAL_USB
Definition Pci22.h:273
#define PCI_CLASS_SERIAL_USB_UHCI
UHCI USB controller.
Definition pci.h:138
#define PCI_CLASS_ID(base, sub, progif)
Construct PCI class ID.
Definition pci.h:203
static struct pci_device_id uhci_ids[]
UHCI PCI device IDs.
Definition uhci.c:1559
static int uhci_probe(struct pci_device *pci)
Probe PCI device.
Definition uhci.c:1467
static void uhci_remove(struct pci_device *pci)
Remove PCI device.
Definition uhci.c:1546

UHCI PCI driver.

Definition at line 1564 of file uhci.c.

1564 {
1565 .ids = uhci_ids,
1566 .id_count = ( sizeof ( uhci_ids ) / sizeof ( uhci_ids[0] ) ),
1569 .probe = uhci_probe,
1570 .remove = uhci_remove,
1571};