1 /* uhci.c - UHCI Support. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
22 #include <grub/misc.h>
24 #include <grub/usbtrans.h>
26 #include <grub/cpu/pci.h>
27 #include <grub/i386/io.h>
28 #include <grub/time.h>
30 #define GRUB_UHCI_IOMASK (0x7FF << 5)
34 GRUB_UHCI_REG_USBCMD
= 0x00,
35 GRUB_UHCI_REG_FLBASEADD
= 0x08,
36 GRUB_UHCI_REG_PORTSC1
= 0x10,
37 GRUB_UHCI_REG_PORTSC2
= 0x12
40 #define GRUB_UHCI_LINK_TERMINATE 1
41 #define GRUB_UHCI_LINK_QUEUE_HEAD 2
44 /* UHCI Queue Head. */
47 /* Queue head link pointer which points to the next queue head. */
48 grub_uint32_t linkptr
;
50 /* Queue element link pointer which points to the first data object
52 grub_uint32_t elinkptr
;
54 /* Queue heads are aligned on 16 bytes, pad so a queue head is 16
55 bytes so we can store many in a 4K page. */
57 } __attribute__ ((packed
));
59 /* UHCI Transfer Descriptor. */
62 /* Pointer to the next TD in the list. */
63 grub_uint32_t linkptr
;
65 /* Control and status bits. */
66 grub_uint32_t ctrl_status
;
68 /* All information required to transfer the Token packet. */
71 /* A pointer to the data buffer, UHCI requires this pointer to be 32
75 /* Another linkptr that is not overwritten by the Host Controller.
76 This is GRUB specific. */
77 grub_uint32_t linkptr2
;
79 /* 3 additional 32 bits words reserved for the Host Controller Driver. */
80 grub_uint32_t data
[3];
81 } __attribute__ ((packed
));
83 typedef volatile struct grub_uhci_td
*grub_uhci_td_t
;
84 typedef volatile struct grub_uhci_qh
*grub_uhci_qh_t
;
89 grub_uint32_t
*framelist
;
91 /* 256 Queue Heads. */
94 /* 256 Transfer Descriptors. */
97 /* Free Transfer Descriptors. */
98 grub_uhci_td_t tdfree
;
100 struct grub_uhci
*next
;
103 static struct grub_uhci
*uhci
;
106 grub_uhci_readreg16 (struct grub_uhci
*u
, grub_uhci_reg_t reg
)
108 return grub_inw (u
->iobase
+ reg
);
113 grub_uhci_readreg32 (struct grub_uhci
*u
, grub_uhci_reg_t reg
)
115 return grub_inl (u
->iobase
+ reg
);
120 grub_uhci_writereg16 (struct grub_uhci
*u
,
121 grub_uhci_reg_t reg
, grub_uint16_t val
)
123 grub_outw (val
, u
->iobase
+ reg
);
127 grub_uhci_writereg32 (struct grub_uhci
*u
,
128 grub_uhci_reg_t reg
, grub_uint32_t val
)
130 grub_outl (val
, u
->iobase
+ reg
);
134 grub_uhci_portstatus (grub_usb_controller_t dev
,
135 unsigned int port
, unsigned int enable
);
138 /* Iterate over all PCI devices. Determine if a device is an UHCI
139 controller. If this is the case, initialize it. */
140 static int NESTED_FUNC_ATTR
141 grub_uhci_pci_iter (int bus
, int device
, int func
,
142 grub_pci_id_t pciid
__attribute__((unused
)))
144 grub_uint32_t class_code
;
146 grub_uint32_t subclass
;
147 grub_uint32_t interf
;
150 grub_pci_address_t addr
;
154 addr
= grub_pci_make_address (bus
, device
, func
, 2);
155 class_code
= grub_pci_read (addr
) >> 8;
157 interf
= class_code
& 0xFF;
158 subclass
= (class_code
>> 8) & 0xFF;
159 class = class_code
>> 16;
161 /* If this is not an UHCI controller, just return. */
162 if (class != 0x0c || subclass
!= 0x03 || interf
!= 0x00)
165 /* Determine IO base address. */
166 addr
= grub_pci_make_address (bus
, device
, func
, 8);
167 base
= grub_pci_read (addr
);
168 /* Stop if there is no IO space base address defined. */
172 /* Allocate memory for the controller and register it. */
173 u
= grub_zalloc (sizeof (*u
));
177 u
->iobase
= base
& GRUB_UHCI_IOMASK
;
178 grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x\n",
179 class, subclass
, interf
, u
->iobase
);
181 /* Reserve a page for the frame list. */
182 u
->framelist
= grub_memalign (4096, 4096);
186 /* The framelist pointer of UHCI is only 32 bits, make sure this
187 code works on on 64 bits architectures. */
188 #if GRUB_CPU_SIZEOF_VOID_P == 8
189 if ((grub_uint64_t
) u
->framelist
>> 32)
191 grub_error (GRUB_ERR_OUT_OF_MEMORY
,
192 "allocated frame list memory not <4GB");
197 /* The QH pointer of UHCI is only 32 bits, make sure this
198 code works on on 64 bits architectures. */
199 u
->qh
= (grub_uhci_qh_t
) grub_memalign (4096, 4096);
203 #if GRUB_CPU_SIZEOF_VOID_P == 8
204 if ((grub_uint64_t
) u
->qh
>> 32)
206 grub_error (GRUB_ERR_OUT_OF_MEMORY
, "allocated QH memory not <4GB");
211 /* The TD pointer of UHCI is only 32 bits, make sure this
212 code works on on 64 bits architectures. */
213 u
->td
= (grub_uhci_td_t
) grub_memalign (4096, 4096*2);
217 #if GRUB_CPU_SIZEOF_VOID_P == 8
218 if ((grub_uint64_t
) u
->td
>> 32)
220 grub_error (GRUB_ERR_OUT_OF_MEMORY
, "allocated TD memory not <4GB");
225 /* Link all Transfer Descriptors in a list of available Transfer
227 for (i
= 0; i
< 256; i
++)
228 u
->td
[i
].linkptr
= (grub_uint32_t
) &u
->td
[i
+ 1];
229 u
->td
[255 - 1].linkptr
= 0;
232 /* Make sure UHCI is disabled! */
233 grub_uhci_writereg16 (u
, GRUB_UHCI_REG_USBCMD
, 0);
235 /* Setup the frame list pointers. Since no isochronous transfers
236 are and will be supported, they all point to the (same!) queue
238 fp
= (grub_uint32_t
) u
->qh
& (~15);
239 /* Mark this as a queue head. */
241 for (i
= 0; i
< 1024; i
++)
242 u
->framelist
[i
] = fp
;
243 /* Program the framelist address into the UHCI controller. */
244 grub_uhci_writereg32 (u
, GRUB_UHCI_REG_FLBASEADD
,
245 (grub_uint32_t
) u
->framelist
);
247 /* Make the Queue Heads point to each other. */
248 for (i
= 0; i
< 256; i
++)
250 /* Point to the next QH. */
251 u
->qh
[i
].linkptr
= (grub_uint32_t
) (&u
->qh
[i
+ 1]) & (~15);
254 u
->qh
[i
].linkptr
|= GRUB_UHCI_LINK_QUEUE_HEAD
;
256 /* For the moment, do not point to a Transfer Descriptor. These
257 are set at transfer time, so just terminate it. */
258 u
->qh
[i
].elinkptr
= 1;
261 /* The last Queue Head should terminate. 256 are too many QHs so
263 u
->qh
[50 - 1].linkptr
= 1;
265 /* Enable UHCI again. */
266 grub_uhci_writereg16 (u
, GRUB_UHCI_REG_USBCMD
, 1 | (1 << 7));
268 /* UHCI is initialized and ready for transfers. */
269 grub_dprintf ("uhci", "UHCI initialized\n");
275 for (i
= 0; i
< 10; i
++)
279 frnum
= grub_uhci_readreg16 (u
, 6);
280 grub_dprintf ("uhci", "Framenum=%d\n", frnum
);
281 grub_millisleep (100);
286 /* Link to uhci now that initialisation is successful. */
295 grub_free ((void *) u
->qh
);
296 grub_free (u
->framelist
);
304 grub_uhci_inithw (void)
306 grub_pci_iterate (grub_uhci_pci_iter
);
309 static grub_uhci_td_t
310 grub_alloc_td (struct grub_uhci
*u
)
314 /* Check if there is a Transfer Descriptor available. */
319 u
->tdfree
= (grub_uhci_td_t
) u
->tdfree
->linkptr
;
325 grub_free_td (struct grub_uhci
*u
, grub_uhci_td_t td
)
327 td
->linkptr
= (grub_uint32_t
) u
->tdfree
;
332 grub_free_queue (struct grub_uhci
*u
, grub_uhci_td_t td
)
334 /* Free the TDs in this queue. */
337 grub_uhci_td_t tdprev
;
339 /* Unlink the queue. */
341 td
= (grub_uhci_td_t
) td
->linkptr2
;
344 grub_free_td (u
, tdprev
);
348 static grub_uhci_qh_t
349 grub_alloc_qh (struct grub_uhci
*u
,
350 grub_transaction_type_t tr
__attribute__((unused
)))
355 /* Look for a Queue Head for this transfer. Skip the first QH if
356 this is a Interrupt Transfer. */
358 if (tr
== GRUB_USB_TRANSACTION_TYPE_INTERRUPT
)
366 if (u
->qh
[i
].elinkptr
& 1)
370 if (! (qh
->elinkptr
& 1))
372 grub_error (GRUB_ERR_OUT_OF_MEMORY
,
373 "no free queue heads available");
380 static grub_uhci_td_t
381 grub_uhci_transaction (struct grub_uhci
*u
, unsigned int endp
,
382 grub_transfer_type_t type
, unsigned int addr
,
383 unsigned int toggle
, grub_size_t size
,
387 static const unsigned int tf
[] = { 0x69, 0xE1, 0x2D };
389 /* XXX: Check if data is <4GB. If it isn't, just copy stuff around.
390 This is only relevant for 64 bits architectures. */
392 /* Grab a free Transfer Descriptor and initialize it. */
393 td
= grub_alloc_td (u
);
396 grub_error (GRUB_ERR_OUT_OF_MEMORY
,
397 "no transfer descriptors available for UHCI transfer");
401 grub_dprintf ("uhci",
402 "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n",
403 endp
, type
, addr
, toggle
, size
, data
, td
);
405 /* Don't point to any TD, just terminate. */
408 /* Active! Only retry a transfer 3 times. */
409 td
->ctrl_status
= (1 << 23) | (3 << 27);
411 /* If zero bytes are transmitted, size is 0x7FF. Otherwise size is
418 /* Setup whatever is required for the token packet. */
419 td
->token
= ((size
<< 21) | (toggle
<< 19) | (endp
<< 15)
420 | (addr
<< 8) | tf
[type
]);
422 td
->buffer
= (grub_uint32_t
) data
;
427 static grub_usb_err_t
428 grub_uhci_transfer (grub_usb_controller_t dev
,
429 grub_usb_transfer_t transfer
)
431 struct grub_uhci
*u
= (struct grub_uhci
*) dev
->data
;
434 grub_uhci_td_t td_first
= NULL
;
435 grub_uhci_td_t td_prev
= NULL
;
436 grub_usb_err_t err
= GRUB_USB_ERR_NONE
;
439 /* Allocate a queue head for the transfer queue. */
440 qh
= grub_alloc_qh (u
, GRUB_USB_TRANSACTION_TYPE_CONTROL
);
444 for (i
= 0; i
< transfer
->transcnt
; i
++)
446 grub_usb_transaction_t tr
= &transfer
->transactions
[i
];
448 td
= grub_uhci_transaction (u
, transfer
->endpoint
, tr
->pid
,
449 transfer
->devaddr
, tr
->toggle
,
453 /* Terminate and free. */
454 td_prev
->linkptr2
= 0;
455 td_prev
->linkptr
= 1;
458 grub_free_queue (u
, td_first
);
460 return GRUB_USB_ERR_INTERNAL
;
467 td_prev
->linkptr2
= (grub_uint32_t
) td
;
468 td_prev
->linkptr
= (grub_uint32_t
) td
;
469 td_prev
->linkptr
|= 4;
473 td_prev
->linkptr2
= 0;
474 td_prev
->linkptr
= 1;
476 grub_dprintf ("uhci", "setup transaction %d\n", transfer
->type
);
478 /* Link it into the queue and terminate. Now the transaction can
480 qh
->elinkptr
= (grub_uint32_t
) td_first
;
482 grub_dprintf ("uhci", "initiate transaction\n");
484 /* Wait until either the transaction completed or an error
488 grub_uhci_td_t errtd
;
490 errtd
= (grub_uhci_td_t
) (qh
->elinkptr
& ~0x0f);
492 grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
493 errtd
->ctrl_status
, errtd
->buffer
& (~15), errtd
);
495 /* Check if the transaction completed. */
496 if (qh
->elinkptr
& 1)
499 grub_dprintf ("uhci", "t status=0x%02x\n", errtd
->ctrl_status
);
501 /* Check if the TD is not longer active. */
502 if (! (errtd
->ctrl_status
& (1 << 23)))
504 grub_dprintf ("uhci", ">>t status=0x%02x\n", errtd
->ctrl_status
);
506 /* Check if the endpoint is stalled. */
507 if (errtd
->ctrl_status
& (1 << 22))
508 err
= GRUB_USB_ERR_STALL
;
510 /* Check if an error related to the data buffer occurred. */
511 if (errtd
->ctrl_status
& (1 << 21))
512 err
= GRUB_USB_ERR_DATA
;
514 /* Check if a babble error occurred. */
515 if (errtd
->ctrl_status
& (1 << 20))
516 err
= GRUB_USB_ERR_BABBLE
;
518 /* Check if a NAK occurred. */
519 if (errtd
->ctrl_status
& (1 << 19))
520 err
= GRUB_USB_ERR_NAK
;
522 /* Check if a timeout occurred. */
523 if (errtd
->ctrl_status
& (1 << 18))
524 err
= GRUB_USB_ERR_TIMEOUT
;
526 /* Check if a bitstuff error occurred. */
527 if (errtd
->ctrl_status
& (1 << 17))
528 err
= GRUB_USB_ERR_BITSTUFF
;
533 /* Fall through, no errors occurred, so the QH might be
535 grub_dprintf ("uhci", "transaction fallthrough\n");
539 grub_dprintf ("uhci", "transaction complete\n");
543 grub_dprintf ("uhci", "transaction failed\n");
545 /* Place the QH back in the free list and deallocate the associated
548 grub_free_queue (u
, td_first
);
554 grub_uhci_iterate (int (*hook
) (grub_usb_controller_t dev
))
557 struct grub_usb_controller dev
;
559 for (u
= uhci
; u
; u
= u
->next
)
570 grub_uhci_portstatus (grub_usb_controller_t dev
,
571 unsigned int port
, unsigned int enable
)
573 struct grub_uhci
*u
= (struct grub_uhci
*) dev
->data
;
577 grub_dprintf ("uhci", "enable=%d port=%d\n", enable
, port
);
580 reg
= GRUB_UHCI_REG_PORTSC1
;
582 reg
= GRUB_UHCI_REG_PORTSC2
;
584 return grub_error (GRUB_ERR_OUT_OF_RANGE
,
585 "UHCI Root Hub port does not exist");
587 status
= grub_uhci_readreg16 (u
, reg
);
588 grub_dprintf ("uhci", "detect=0x%02x\n", status
);
590 /* Reset the port. */
591 grub_uhci_writereg16 (u
, reg
, enable
<< 9);
593 /* Wait for the reset to complete. XXX: How long exactly? */
594 grub_millisleep (10);
595 status
= grub_uhci_readreg16 (u
, reg
);
596 grub_uhci_writereg16 (u
, reg
, status
& ~(1 << 9));
597 grub_dprintf ("uhci", "reset completed\n");
599 /* Enable the port. */
600 grub_uhci_writereg16 (u
, reg
, enable
<< 2);
601 grub_millisleep (10);
603 grub_dprintf ("uhci", "waiting for the port to be enabled\n");
605 while (! (grub_uhci_readreg16 (u
, reg
) & (1 << 2)));
607 status
= grub_uhci_readreg16 (u
, reg
);
608 grub_dprintf ("uhci", ">3detect=0x%02x\n", status
);
611 return GRUB_ERR_NONE
;
614 static grub_usb_speed_t
615 grub_uhci_detect_dev (grub_usb_controller_t dev
, int port
)
617 struct grub_uhci
*u
= (struct grub_uhci
*) dev
->data
;
622 reg
= GRUB_UHCI_REG_PORTSC1
;
624 reg
= GRUB_UHCI_REG_PORTSC2
;
626 return grub_error (GRUB_ERR_OUT_OF_RANGE
,
627 "UHCI Root Hub port does not exist");
629 status
= grub_uhci_readreg16 (u
, reg
);
631 grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status
, port
);
634 return GRUB_USB_SPEED_NONE
;
635 else if (status
& (1 << 8))
636 return GRUB_USB_SPEED_LOW
;
638 return GRUB_USB_SPEED_FULL
;
642 grub_uhci_hubports (grub_usb_controller_t dev
__attribute__((unused
)))
644 /* The root hub has exactly two ports. */
649 static struct grub_usb_controller_dev usb_controller
=
652 .iterate
= grub_uhci_iterate
,
653 .transfer
= grub_uhci_transfer
,
654 .hubports
= grub_uhci_hubports
,
655 .portstatus
= grub_uhci_portstatus
,
656 .detect_dev
= grub_uhci_detect_dev
662 grub_usb_controller_dev_register (&usb_controller
);
663 grub_dprintf ("uhci", "registered\n");
670 /* Disable all UHCI controllers. */
671 for (u
= uhci
; u
; u
= u
->next
)
672 grub_uhci_writereg16 (u
, GRUB_UHCI_REG_USBCMD
, 0);
674 /* Unregister the controller. */
675 grub_usb_controller_dev_unregister (&usb_controller
);