Fix p2v and v2p

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-10-01 21:31:53 +02:00
parent 4fbface043
commit e5c0534f0b

View file

@ -405,18 +405,14 @@ grub_ehci_port_setbits (struct grub_ehci *e, grub_uint32_t port,
static inline void * static inline void *
grub_ehci_phys2virt (grub_uint32_t phys, struct grub_pci_dma_chunk *chunk) grub_ehci_phys2virt (grub_uint32_t phys, struct grub_pci_dma_chunk *chunk)
{ {
if (!phys) return ((grub_uint8_t *) grub_dma_get_virt (chunk)
return NULL; + (phys - grub_dma_get_phys (chunk)));
return (void *) (phys - grub_dma_get_phys (chunk)
+ (grub_uint32_t) grub_dma_get_virt (chunk));
} }
static inline grub_uint32_t static inline grub_uint32_t
grub_ehci_virt2phys (volatile void *virt, struct grub_pci_dma_chunk *chunk) grub_ehci_virt2phys (volatile void *virt, struct grub_pci_dma_chunk *chunk)
{ {
if (!virt) return (((grub_uint8_t *) virt - (grub_uint8_t *) grub_dma_get_virt (chunk))
return 0;
return ((grub_uint32_t) virt - (grub_uint32_t) grub_dma_get_virt (chunk)
+ grub_dma_get_phys (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++) for (i = 1; i < GRUB_EHCI_N_QH; i++)
{ {
e->qh_virt[i].qh_hptr = 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) & e->qh_chunk) &
GRUB_EHCI_POINTER_MASK) | GRUB_EHCI_HPTR_TYPE_QH); GRUB_EHCI_POINTER_MASK) | GRUB_EHCI_HPTR_TYPE_QH);
e->qh_virt[i].td_overlay.next_td = 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 */ /* Setup list address registers */
grub_ehci_oper_write32 (e, GRUB_EHCI_FL_BASE, e->framelist_phys); grub_ehci_oper_write32 (e, GRUB_EHCI_FL_BASE, e->framelist_phys);
grub_ehci_oper_write32 (e, GRUB_EHCI_CUR_AL_ADDR, 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)); e->qh_chunk));
/* Set ownership of root hub ports to EHCI */ /* 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); grub_ehci_setup_qh (&qh[i], transfer);
/* Linking - this new (last) QH will point to first QH */ /* Linking - this new (last) QH will point to first QH */
qh[i].qh_hptr = grub_cpu_to_le32 (GRUB_EHCI_HPTR_TYPE_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)); e->qh_chunk));
/* Linking - previous last QH will point to this new QH */ /* Linking - previous last QH will point to this new QH */
qh[i - 1].qh_hptr = grub_cpu_to_le32 (GRUB_EHCI_HPTR_TYPE_QH qh[i - 1].qh_hptr = grub_cpu_to_le32 (GRUB_EHCI_HPTR_TYPE_QH
| grub_ehci_virt2phys ((void *) | grub_ehci_virt2phys (&qh[i],
&qh[i],
e->qh_chunk)); e->qh_chunk));
return &qh[i]; return &qh[i];
@ -995,7 +990,10 @@ grub_ehci_alloc_td (struct grub_ehci *e)
ret = e->tdfree_virt; /* Take current free TD */ ret = e->tdfree_virt; /* Take current free TD */
/* Advance to next free TD in chain */ /* 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 */ ret->link_td = 0; /* Reset link_td in allocated TD */
return ret; return ret;
} }
@ -1004,7 +1002,10 @@ static void
grub_ehci_free_td (struct grub_ehci *e, grub_ehci_td_t td) grub_ehci_free_td (struct grub_ehci *e, grub_ehci_td_t td)
{ {
/* Chain new free TD & rest */ /* 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 */ 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 */ /* Unlink the TD */
tdprev = 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. */ /* Free the TD. */
grub_ehci_free_td (e, tdprev); 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 * 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 * forget, EHCI will try to fetch alternate TD every scan of AL
* until QH is halted. */ * until QH is halted. */
td->alt_next_td = td->alt_next_td = grub_cpu_to_le32 (grub_ehci_virt2phys (td_alt,
grub_cpu_to_le32 (grub_ehci_virt2phys ((void *) td_alt, e->td_chunk)); e->td_chunk));
/* token: /* token:
* TOGGLE - according to toggle * TOGGLE - according to toggle
* TOTAL SIZE = size * TOTAL SIZE = size
@ -1292,7 +1296,7 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev,
/* Link new TDs with QH via next_td */ /* Link new TDs with QH via next_td */
cdata->qh_virt->td_overlay.next_td = cdata->qh_virt->td_overlay.next_td =
grub_cpu_to_le32 (grub_ehci_virt2phys 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, /* Reset Active and Halted bits in QH to activate Advance Queue,
* i.e. reset token */ * i.e. reset token */
cdata->qh_virt->td_overlay.token = grub_cpu_to_le32 (0); 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... */ /* Finaly we should return QH back to the AL... */
e->qh_virt[i - 1].qh_hptr = e->qh_virt[i - 1].qh_hptr =
grub_cpu_to_le32 (grub_ehci_virt2phys grub_cpu_to_le32 (grub_ehci_virt2phys
((void *) cdata->qh_virt, e->qh_chunk)); (cdata->qh_virt, e->qh_chunk));
grub_free (cdata); grub_free (cdata);
grub_dprintf ("ehci", "cancel_transfer: end\n"); grub_dprintf ("ehci", "cancel_transfer: end\n");
@ -1741,7 +1745,7 @@ grub_ehci_restore_hw (void)
/* Setup some EHCI registers and enable EHCI */ /* 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_FL_BASE, e->framelist_phys);
grub_ehci_oper_write32 (e, GRUB_EHCI_CUR_AL_ADDR, 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)); e->qh_chunk));
grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND,
GRUB_EHCI_CMD_RUNSTOP | GRUB_EHCI_CMD_RUNSTOP |