diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c index fe5cf6eb8..3421d630c 100644 --- a/grub-core/bus/usb/ehci.c +++ b/grub-core/bus/usb/ehci.c @@ -405,18 +405,14 @@ grub_ehci_port_setbits (struct grub_ehci *e, grub_uint32_t port, static inline void * grub_ehci_phys2virt (grub_uint32_t phys, struct grub_pci_dma_chunk *chunk) { - if (!phys) - return NULL; - return (void *) (phys - grub_dma_get_phys (chunk) - + (grub_uint32_t) grub_dma_get_virt (chunk)); + return ((grub_uint8_t *) grub_dma_get_virt (chunk) + + (phys - grub_dma_get_phys (chunk))); } static inline grub_uint32_t grub_ehci_virt2phys (volatile void *virt, struct grub_pci_dma_chunk *chunk) { - if (!virt) - return 0; - return ((grub_uint32_t) virt - (grub_uint32_t) grub_dma_get_virt (chunk) + return (((grub_uint8_t *) virt - (grub_uint8_t *) grub_dma_get_virt (chunk)) + grub_dma_get_phys (chunk)); } @@ -666,7 +662,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, for (i = 1; i < GRUB_EHCI_N_QH; i++) { e->qh_virt[i].qh_hptr = - grub_cpu_to_le32 ((grub_ehci_virt2phys ((void *) &e->qh_virt[i], + grub_cpu_to_le32 ((grub_ehci_virt2phys (&e->qh_virt[i], e->qh_chunk) & GRUB_EHCI_POINTER_MASK) | GRUB_EHCI_HPTR_TYPE_QH); e->qh_virt[i].td_overlay.next_td = @@ -758,7 +754,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, /* Setup list address registers */ grub_ehci_oper_write32 (e, GRUB_EHCI_FL_BASE, e->framelist_phys); grub_ehci_oper_write32 (e, GRUB_EHCI_CUR_AL_ADDR, - grub_ehci_virt2phys ((void *) &e->qh_virt[1], + grub_ehci_virt2phys (&e->qh_virt[1], e->qh_chunk)); /* Set ownership of root hub ports to EHCI */ @@ -970,12 +966,11 @@ grub_ehci_find_qh (struct grub_ehci *e, grub_usb_transfer_t transfer) grub_ehci_setup_qh (&qh[i], transfer); /* Linking - this new (last) QH will point to first QH */ qh[i].qh_hptr = grub_cpu_to_le32 (GRUB_EHCI_HPTR_TYPE_QH - | grub_ehci_virt2phys ((void *) &qh[1], + | grub_ehci_virt2phys (&qh[1], e->qh_chunk)); /* Linking - previous last QH will point to this new QH */ qh[i - 1].qh_hptr = grub_cpu_to_le32 (GRUB_EHCI_HPTR_TYPE_QH - | grub_ehci_virt2phys ((void *) - &qh[i], + | grub_ehci_virt2phys (&qh[i], e->qh_chunk)); return &qh[i]; @@ -995,7 +990,10 @@ grub_ehci_alloc_td (struct grub_ehci *e) ret = e->tdfree_virt; /* Take current free TD */ /* Advance to next free TD in chain */ - e->tdfree_virt = grub_ehci_phys2virt (ret->link_td, e->td_chunk); + if (ret->link_td) + e->tdfree_virt = grub_ehci_phys2virt (ret->link_td, e->td_chunk); + else + e->tdfree_virt = NULL; ret->link_td = 0; /* Reset link_td in allocated TD */ return ret; } @@ -1004,7 +1002,10 @@ static void grub_ehci_free_td (struct grub_ehci *e, grub_ehci_td_t td) { /* Chain new free TD & rest */ - td->link_td = grub_ehci_virt2phys (e->tdfree_virt, e->td_chunk); + if (e->tdfree_virt) + td->link_td = grub_ehci_virt2phys (e->tdfree_virt, e->td_chunk); + else + td->link_td = 0; e->tdfree_virt = td; /* Change address of first free TD */ } @@ -1037,7 +1038,10 @@ grub_ehci_free_tds (struct grub_ehci *e, grub_ehci_td_t td, /* Unlink the TD */ tdprev = td; - td = grub_ehci_phys2virt (td->link_td, e->td_chunk); + if (td->link_td) + td = grub_ehci_phys2virt (td->link_td, e->td_chunk); + else + td = NULL; /* Free the TD. */ grub_ehci_free_td (e, tdprev); @@ -1108,8 +1112,8 @@ grub_ehci_transaction (struct grub_ehci *e, * will not be really fetched because it is not active. But don't * forget, EHCI will try to fetch alternate TD every scan of AL * until QH is halted. */ - td->alt_next_td = - grub_cpu_to_le32 (grub_ehci_virt2phys ((void *) td_alt, e->td_chunk)); + td->alt_next_td = grub_cpu_to_le32 (grub_ehci_virt2phys (td_alt, + e->td_chunk)); /* token: * TOGGLE - according to toggle * TOTAL SIZE = size @@ -1292,7 +1296,7 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev, /* Link new TDs with QH via next_td */ cdata->qh_virt->td_overlay.next_td = grub_cpu_to_le32 (grub_ehci_virt2phys - ((void *) cdata->td_first_virt, e->td_chunk)); + (cdata->td_first_virt, e->td_chunk)); /* Reset Active and Halted bits in QH to activate Advance Queue, * i.e. reset token */ cdata->qh_virt->td_overlay.token = grub_cpu_to_le32 (0); @@ -1544,7 +1548,7 @@ grub_ehci_cancel_transfer (grub_usb_controller_t dev, /* Finaly we should return QH back to the AL... */ e->qh_virt[i - 1].qh_hptr = grub_cpu_to_le32 (grub_ehci_virt2phys - ((void *) cdata->qh_virt, e->qh_chunk)); + (cdata->qh_virt, e->qh_chunk)); grub_free (cdata); grub_dprintf ("ehci", "cancel_transfer: end\n"); @@ -1741,7 +1745,7 @@ grub_ehci_restore_hw (void) /* Setup some EHCI registers and enable EHCI */ grub_ehci_oper_write32 (e, GRUB_EHCI_FL_BASE, e->framelist_phys); grub_ehci_oper_write32 (e, GRUB_EHCI_CUR_AL_ADDR, - grub_ehci_virt2phys ((void *) &e->qh_virt[1], + grub_ehci_virt2phys (&e->qh_virt[1], e->qh_chunk)); grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, GRUB_EHCI_CMD_RUNSTOP |