Fix pciutils non-32bit PCI write on OpenBSD. OpenBSD supports only 32bit accesses to PCI config space. Emulate smaller writes with a read/modify/write cycle.
First try, untested. May break on bigendian architectures (actually, the existing code looks like it is broken on big endian for either read or write, so my patch may break it more, or actually fix it). This should get flashrom running. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2...@gmx.net> diff --git a/lib/obsd-device.c b/lib/obsd-device.c index dc68422..257902c 100644 --- a/lib/obsd-device.c +++ b/lib/obsd-device.c @@ -113,19 +113,31 @@ obsd_write(struct pci_dev *d, int pos, byte *buf, int len) 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; }