openbsd-ports/sysutils/flashrom/patches/patchpci-pciutils_lib_obsd-device_c
2022-03-07 21:45:09 +00:00

45 lines
1.3 KiB
Plaintext

OpenBSD's /dev/pci only permits aligned 32 bit writes.
Emulate smaller writes by doing read/modify/write.
http://marc.info/?l=openbsd-ports&m=127780030728045&w=2
--- pciutils/lib/obsd-device.c.orig Sat May 21 22:41:31 2016
+++ pciutils/lib/obsd-device.c Sat May 21 22:41:34 2016
@@ -109,19 +109,31 @@ obsd_write(struct pci_dev *d, int pos, byte *buf, int
pi.pi_sel.pc_dev = d->dev;
pi.pi_sel.pc_func = d->func;
- pi.pi_reg = pos;
- pi.pi_width = len;
+ pi.pi_reg = pos - (pos % 4);
+ pi.pi_width = 4;
+ pi.pi_data = 0xffffffff;
+ /* Questionable read-modify-write cycle for non-32-bit writes */
+ if (len != 4)
+ if (ioctl(d->access->fd, PCIOCREAD, &pi) < 0)
+ {
+ /* Abort on any error because the write will contain garbage */
+ d->access->error("obsd_read: ioctl(PCIOCREAD) failed");
+ return 0;
+ }
+
switch (len)
{
case 1:
- pi.pi_data = buf[0];
+ pi.pi_data &= ~(0xff << ((pos % 4) * 8));
+ pi.pi_data |= buf[0] << ((pos % 4) * 8);
break;
case 2:
- pi.pi_data = ((u16 *) buf)[0];
+ pi.pi_data &= ~(0xffff << ((pos % 4) * 8));
+ pi.pi_data |= htole16(((u16 *) buf)[0]) << ((pos % 4) * 8);
break;
case 4:
- pi.pi_data = ((u32 *) buf)[0];
+ pi.pi_data = htole32(((u32 *) buf)[0]);
break;
}