mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-30 12:04:07 +00:00
bhyve: Avoid using a packed struct for xhci port registers
I believe the __packed annotation is there only because pci_xhci_portregs_read() is treating the register set as an array of uint32_t. clang warns about taking the address of portregs->portsc because it is a packed member and thus might not have expected alignment. Fix the problem by simply selecting the field to read with a switch statement. This mimics pci_xhci_portregs_write(). While here, switch to using some symbolic constants. There is a small semantic change here in that pci_xhci_portregs_read() would silently truncate unaligned offsets. For consistency with pci_xhci_portregs_write(), which does not do that, return all ones for unaligned reads instead. MFC after: 2 weeks Reviewed by: corvink, jhb Differential Revision: https://reviews.freebsd.org/D37408
This commit is contained in:
parent
c127c61efa
commit
0705b7f4e6
@ -568,6 +568,10 @@ pci_xhci_portregs_write(struct pci_xhci_softc *sc, uint64_t offset,
|
||||
*/
|
||||
p->porthlpmc = value;
|
||||
break;
|
||||
default:
|
||||
DPRINTF(("pci_xhci: unaligned portreg write offset %#lx",
|
||||
offset));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2132,12 +2136,13 @@ pci_xhci_portregs_read(struct pci_xhci_softc *sc, uint64_t offset)
|
||||
{
|
||||
struct pci_xhci_portregs *portregs;
|
||||
int port;
|
||||
uint32_t *p;
|
||||
uint32_t reg;
|
||||
|
||||
if (sc->portregs == NULL)
|
||||
return (0);
|
||||
|
||||
port = (offset - 0x3F0) / 0x10;
|
||||
port = (offset - XHCI_PORTREGS_PORT0) / XHCI_PORTREGS_SETSZ;
|
||||
offset = (offset - XHCI_PORTREGS_PORT0) % XHCI_PORTREGS_SETSZ;
|
||||
|
||||
if (port > XHCI_MAX_DEVS) {
|
||||
DPRINTF(("pci_xhci: portregs_read port %d >= XHCI_MAX_DEVS",
|
||||
@ -2147,16 +2152,31 @@ pci_xhci_portregs_read(struct pci_xhci_softc *sc, uint64_t offset)
|
||||
return (XHCI_PS_SPEED_SET(3));
|
||||
}
|
||||
|
||||
offset = (offset - 0x3F0) % 0x10;
|
||||
|
||||
portregs = XHCI_PORTREG_PTR(sc, port);
|
||||
p = &portregs->portsc;
|
||||
p += offset / sizeof(uint32_t);
|
||||
switch (offset) {
|
||||
case 0:
|
||||
reg = portregs->portsc;
|
||||
break;
|
||||
case 4:
|
||||
reg = portregs->portpmsc;
|
||||
break;
|
||||
case 8:
|
||||
reg = portregs->portli;
|
||||
break;
|
||||
case 12:
|
||||
reg = portregs->porthlpmc;
|
||||
break;
|
||||
default:
|
||||
DPRINTF(("pci_xhci: unaligned portregs read offset %#lx",
|
||||
offset));
|
||||
reg = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINTF(("pci_xhci: portregs read offset 0x%lx port %u -> 0x%x",
|
||||
offset, port, *p));
|
||||
offset, port, reg));
|
||||
|
||||
return (*p);
|
||||
return (reg);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user