static int proto_read(struct cdev *cdev, struct uio *uio, int ioflag) { union { uint8_t x1[8]; uint16_t x2[4]; uint32_t x4[2]; uint64_t x8[1]; } buf; struct proto_softc *sc; struct proto_res *r; device_t dev; off_t ofs; u_long width; int error; sc = cdev->si_drv1; dev = sc->sc_dev; r = cdev->si_drv2; width = uio->uio_resid; if (width < 1 || width > 8 || bitcount16(width) > 1) return (EIO); ofs = uio->uio_offset; if (ofs + width > r->r_size) return (EIO); switch (width) { case 1: buf.x1[0] = (r->r_type == PROTO_RES_PCICFG) ? pci_read_config(dev, ofs, 1) : bus_read_1(r->r_d.res, ofs); break; case 2: buf.x2[0] = (r->r_type == PROTO_RES_PCICFG) ? pci_read_config(dev, ofs, 2) : bus_read_2(r->r_d.res, ofs); break; case 4: buf.x4[0] = (r->r_type == PROTO_RES_PCICFG) ? pci_read_config(dev, ofs, 4) : bus_read_4(r->r_d.res, ofs); break; #ifndef __i386__ case 8: if (r->r_type == PROTO_RES_PCICFG) return (EINVAL); buf.x8[0] = bus_read_8(r->r_d.res, ofs); break; #endif default: return (EIO); } error = uiomove(&buf, width, uio); return (error); }
static void le_lebuffer_copyfromdesc(struct lance_softc *sc, void *tov, int off, int len) { struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc; caddr_t to = tov; for (; len >= 8; len -= 8, off += 8, to += 8) be64enc(to, bus_read_8(lesc->sc_bres, off)); for (; len >= 4; len -= 4, off += 4, to += 4) be32enc(to, bus_read_4(lesc->sc_bres, off)); for (; len >= 2; len -= 2, off += 2, to += 2) be16enc(to, bus_read_2(lesc->sc_bres, off)); if (len == 1) *to = bus_read_1(lesc->sc_bres, off); }
uint8_t __inline pci_bus_read8(paddr_t addr) { return bus_read_8(addr); }