Fix ehci on amd64.

* grub-core/bus/usb/usbhub.c (grub_usb_hub_add_dev): Use %p to print
	pointers.
	* grub-core/bus/usb/ehci.c (grub_ehci_pci_iter): Likewise.
	(grub_ehci_setup_qh): Likewise.
	(grub_ehci_find_qh): Likewise.
	(grub_ehci_transaction): Likewise.
	(grub_ehci_setup_transfer): Likewise.
	(grub_ehci_check_transfer): Likewise.
	(grub_ehci_portstatus): Likewise.
	(grub_ehci_detect_dev): Likewise.
	(grub_ehci_transfer_controller_data): New field td_last_phys.
	(grub_ehci_setup_transfer): Fill td_last_phys.
	(grub_ehci_check_transfer): Use td_last_phys.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-02-01 16:13:17 +01:00
parent 3008675bea
commit d3e3fab52a
3 changed files with 52 additions and 32 deletions

View file

@ -1,3 +1,21 @@
2012-02-01 Vladimir Serbinenko <phcoder@gmail.com>
Fix ehci on amd64.
* grub-core/bus/usb/usbhub.c (grub_usb_hub_add_dev): Use %p to print
pointers.
* grub-core/bus/usb/ehci.c (grub_ehci_pci_iter): Likewise.
(grub_ehci_setup_qh): Likewise.
(grub_ehci_find_qh): Likewise.
(grub_ehci_transaction): Likewise.
(grub_ehci_setup_transfer): Likewise.
(grub_ehci_check_transfer): Likewise.
(grub_ehci_portstatus): Likewise.
(grub_ehci_detect_dev): Likewise.
(grub_ehci_transfer_controller_data): New field td_last_phys.
(grub_ehci_setup_transfer): Fill td_last_phys.
(grub_ehci_check_transfer): Use td_last_phys.
2012-02-01 Seth Goldberg <seth.goldberg@oracle.com> 2012-02-01 Seth Goldberg <seth.goldberg@oracle.com>
* grub-core/normal/context.c (grub_env_extractor_close): Don't crash * grub-core/normal/context.c (grub_env_extractor_close): Don't crash

View file

@ -601,8 +601,8 @@ grub_ehci_pci_iter (grub_pci_device_t dev,
e->framelist_phys = grub_dma_get_phys (e->framelist_chunk); e->framelist_phys = grub_dma_get_phys (e->framelist_chunk);
grub_memset ((void *) e->framelist_virt, 0, 4096); grub_memset ((void *) e->framelist_virt, 0, 4096);
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: framelist mem=0x%08x. OK\n", grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: framelist mem=%p. OK\n",
(grub_uint32_t) e->framelist_virt); e->framelist_virt);
/* Allocate memory for the QHs and register it in "e". */ /* Allocate memory for the QHs and register it in "e". */
e->qh_chunk = grub_memalign_dma32 (4096, e->qh_chunk = grub_memalign_dma32 (4096,
@ -615,8 +615,8 @@ grub_ehci_pci_iter (grub_pci_device_t dev,
grub_memset ((void *) e->qh_virt, 0, grub_memset ((void *) e->qh_virt, 0,
sizeof (struct grub_ehci_qh) * GRUB_EHCI_N_QH); sizeof (struct grub_ehci_qh) * GRUB_EHCI_N_QH);
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH mem=0x%08x. OK\n", grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH mem=%p. OK\n",
(grub_uint32_t) e->qh_virt); e->qh_virt);
/* Allocate memory for the TDs and register it in "e". */ /* Allocate memory for the TDs and register it in "e". */
e->td_chunk = grub_memalign_dma32 (4096, e->td_chunk = grub_memalign_dma32 (4096,
@ -629,8 +629,8 @@ grub_ehci_pci_iter (grub_pci_device_t dev,
grub_memset ((void *) e->td_virt, 0, grub_memset ((void *) e->td_virt, 0,
sizeof (struct grub_ehci_td) * GRUB_EHCI_N_TD); sizeof (struct grub_ehci_td) * GRUB_EHCI_N_TD);
grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: TD mem=0x%08x. OK\n", grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: TD mem=%p. OK\n",
(grub_uint32_t) e->td_virt); e->td_virt);
/* Setup all frame list pointers. Since no isochronous transfers /* Setup all frame list pointers. Since no isochronous transfers
are supported, they all point to the (same!) queue are supported, they all point to the (same!) queue
@ -928,8 +928,8 @@ grub_ehci_setup_qh (grub_ehci_qh_t qh, grub_usb_transfer_t transfer)
& GRUB_EHCI_HUBADDR_MASK; & GRUB_EHCI_HUBADDR_MASK;
qh->ep_cap = grub_cpu_to_le32 (ep_cap); qh->ep_cap = grub_cpu_to_le32 (ep_cap);
grub_dprintf ("ehci", "setup_qh: qh=%08x, not changed: qh_hptr=%08x\n", grub_dprintf ("ehci", "setup_qh: qh=%p, not changed: qh_hptr=%08x\n",
(grub_uint32_t) qh, grub_le_to_cpu32 (qh->qh_hptr)); qh, grub_le_to_cpu32 (qh->qh_hptr));
grub_dprintf ("ehci", "setup_qh: ep_char=%08x, ep_cap=%08x\n", grub_dprintf ("ehci", "setup_qh: ep_char=%08x, ep_cap=%08x\n",
ep_char, ep_cap); ep_char, ep_cap);
grub_dprintf ("ehci", "setup_qh: end\n"); grub_dprintf ("ehci", "setup_qh: end\n");
@ -962,9 +962,10 @@ grub_ehci_find_qh (struct grub_ehci *e, grub_usb_transfer_t transfer)
if (!qh[i].ep_char) if (!qh[i].ep_char)
break; /* Found first not-allocated QH, finish */ break; /* Found first not-allocated QH, finish */
if (target == (qh[i].ep_char & mask)) if (target == (qh[i].ep_char & mask))
{ /* Found proper existing (and linked) QH, do setup of QH */ {
grub_dprintf ("ehci", "find_qh: found, i=%d, QH=%08x\n", /* Found proper existing (and linked) QH, do setup of QH */
i, (grub_uint32_t) & qh[i]); grub_dprintf ("ehci", "find_qh: found, i=%d, QH=%p\n",
i, &qh[i]);
grub_ehci_setup_qh (&qh[i], transfer); grub_ehci_setup_qh (&qh[i], transfer);
return &qh[i]; return &qh[i];
} }
@ -976,8 +977,8 @@ grub_ehci_find_qh (struct grub_ehci *e, grub_usb_transfer_t transfer)
grub_dprintf ("ehci", "find_qh: end - no free QH\n"); grub_dprintf ("ehci", "find_qh: end - no free QH\n");
return NULL; return NULL;
} }
grub_dprintf ("ehci", "find_qh: new, i=%d, QH=%08x\n", grub_dprintf ("ehci", "find_qh: new, i=%d, QH=%p\n",
i, (grub_uint32_t) & qh[i]); i, &qh[i]);
/* Currently we simply take next (current) QH in array, no allocation /* Currently we simply take next (current) QH in array, no allocation
* function is used. It should be no problem until we will need to * function is used. It should be no problem until we will need to
* de-allocate QHs of unplugged devices. */ * de-allocate QHs of unplugged devices. */
@ -1178,7 +1179,7 @@ grub_ehci_transaction (struct grub_ehci *e,
/* Remember data size for future use... */ /* Remember data size for future use... */
td->size = (grub_uint32_t) size; td->size = (grub_uint32_t) size;
grub_dprintf ("ehci", "td=%08x\n", (grub_uint32_t) td); grub_dprintf ("ehci", "td=%p\n", td);
grub_dprintf ("ehci", "HW: next_td=%08x, alt_next_td=%08x\n", grub_dprintf ("ehci", "HW: next_td=%08x, alt_next_td=%08x\n",
grub_le_to_cpu32 (td->next_td), grub_le_to_cpu32 (td->next_td),
grub_le_to_cpu32 (td->alt_next_td)); grub_le_to_cpu32 (td->alt_next_td));
@ -1203,6 +1204,7 @@ struct grub_ehci_transfer_controller_data
grub_ehci_td_t td_first_virt; grub_ehci_td_t td_first_virt;
grub_ehci_td_t td_alt_virt; grub_ehci_td_t td_alt_virt;
grub_ehci_td_t td_last_virt; grub_ehci_td_t td_last_virt;
grub_uint32_t td_last_phys;
}; };
static grub_usb_err_t static grub_usb_err_t
@ -1297,16 +1299,17 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
/* Remember last TD */ /* Remember last TD */
cdata->td_last_virt = td; cdata->td_last_virt = td;
cdata->td_last_phys = grub_dma_virt2phys (td, e->td_chunk);
/* Last TD should not have set alternate TD */ /* Last TD should not have set alternate TD */
cdata->td_last_virt->alt_next_td = grub_cpu_to_le32 (GRUB_EHCI_TERMINATE); cdata->td_last_virt->alt_next_td = grub_cpu_to_le32 (GRUB_EHCI_TERMINATE);
grub_dprintf ("ehci", "setup_transfer: cdata=%08x, qh=%08x\n", grub_dprintf ("ehci", "setup_transfer: cdata=%p, qh=%p\n",
(grub_uint32_t) cdata, (grub_uint32_t) cdata->qh_virt); cdata,cdata->qh_virt);
grub_dprintf ("ehci", "setup_transfer: td_first=%08x, td_alt=%08x\n", grub_dprintf ("ehci", "setup_transfer: td_first=%p, td_alt=%p\n",
(grub_uint32_t) cdata->td_first_virt, cdata->td_first_virt,
(grub_uint32_t) cdata->td_alt_virt); cdata->td_alt_virt);
grub_dprintf ("ehci", "setup_transfer: td_last=%08x\n", grub_dprintf ("ehci", "setup_transfer: td_last=%p\n",
(grub_uint32_t) cdata->td_last_virt); cdata->td_last_virt);
/* Start transfer: */ /* Start transfer: */
/* Unlink possible alternate pointer in QH */ /* Unlink possible alternate pointer in QH */
@ -1449,9 +1452,9 @@ grub_ehci_check_transfer (grub_usb_controller_t dev,
grub_uint32_t token; grub_uint32_t token;
grub_dprintf ("ehci", grub_dprintf ("ehci",
"check_transfer: EHCI STATUS=%08x, cdata=%08x, qh=%08x\n", "check_transfer: EHCI STATUS=%08x, cdata=%p, qh=%p\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS), grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS),
(grub_uint32_t) cdata, (grub_uint32_t) cdata->qh_virt); cdata, cdata->qh_virt);
grub_dprintf ("ehci", "check_transfer: qh_hptr=%08x, ep_char=%08x\n", grub_dprintf ("ehci", "check_transfer: qh_hptr=%08x, ep_char=%08x\n",
grub_le_to_cpu32 (cdata->qh_virt->qh_hptr), grub_le_to_cpu32 (cdata->qh_virt->qh_hptr),
grub_le_to_cpu32 (cdata->qh_virt->ep_char)); grub_le_to_cpu32 (cdata->qh_virt->ep_char));
@ -1486,7 +1489,7 @@ grub_ehci_check_transfer (grub_usb_controller_t dev,
if ((grub_le_to_cpu32 (cdata->qh_virt->td_overlay.next_td) if ((grub_le_to_cpu32 (cdata->qh_virt->td_overlay.next_td)
& GRUB_EHCI_TERMINATE) && & GRUB_EHCI_TERMINATE) &&
((grub_le_to_cpu32 (cdata->qh_virt->td_current) ((grub_le_to_cpu32 (cdata->qh_virt->td_current)
& GRUB_EHCI_QHTDPTR_MASK) == (grub_uint32_t) cdata->td_last_virt)) & GRUB_EHCI_QHTDPTR_MASK) == cdata->td_last_phys))
/* Normal finish */ /* Normal finish */
return grub_ehci_parse_success (dev, transfer, actual); return grub_ehci_parse_success (dev, transfer, actual);
else if ((token & GRUB_EHCI_TOTAL_MASK) != 0) else if ((token & GRUB_EHCI_TOTAL_MASK) != 0)
@ -1597,9 +1600,8 @@ grub_ehci_portstatus (grub_usb_controller_t dev,
grub_dprintf ("ehci", "portstatus: EHCI STATUS: %08x\n", grub_dprintf ("ehci", "portstatus: EHCI STATUS: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)); grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS));
grub_dprintf ("ehci", grub_dprintf ("ehci",
"portstatus: begin, iobase=0x%02x, port=%d, status=0x%02x\n", "portstatus: begin, iobase=%p, port=%d, status=0x%02x\n",
(grub_uint32_t) e->iobase, port, grub_ehci_port_read (e, e->iobase, port, grub_ehci_port_read (e, port));
port));
/* In any case we need to disable port: /* In any case we need to disable port:
* - if enable==false - we should disable port * - if enable==false - we should disable port
@ -1674,8 +1676,8 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
grub_dprintf ("ehci", "detect_dev: EHCI STATUS: %08x\n", grub_dprintf ("ehci", "detect_dev: EHCI STATUS: %08x\n",
grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)); grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS));
grub_dprintf ("ehci", "detect_dev: iobase=0x%02x, port=%d, status=0x%02x\n", grub_dprintf ("ehci", "detect_dev: iobase=%p, port=%d, status=0x%02x\n",
(grub_uint32_t) e->iobase, port, status); e->iobase, port, status);
/* Connect Status Change bit - it detects change of connection */ /* Connect Status Change bit - it detects change of connection */
if (status & GRUB_EHCI_PORT_CONNECT_CH) if (status & GRUB_EHCI_PORT_CONNECT_CH)

View file

@ -101,10 +101,10 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
dev->initialized = 1; dev->initialized = 1;
grub_usb_devs[i] = dev; grub_usb_devs[i] = dev;
grub_dprintf ("usb", "Added new usb device: %08x, addr=%d\n", grub_dprintf ("usb", "Added new usb device: %p, addr=%d\n",
(grub_uint32_t)dev, i); dev, i);
grub_dprintf ("usb", "speed=%d, port=%d, hubaddr=%d\n", grub_dprintf ("usb", "speed=%d, port=%d, hubaddr=%d\n",
speed, port, hubaddr); speed, port, hubaddr);
/* Wait "recovery interval", spec. says 2ms */ /* Wait "recovery interval", spec. says 2ms */
grub_millisleep (2); grub_millisleep (2);