int ichsmb_writeb(device_t dev, u_char slave, char cmd, char byte) { const sc_p sc = device_get_softc(dev); int smb_error; DBG("slave=0x%02x cmd=0x%02x byte=0x%02x\n", slave, (u_char)cmd, (u_char)byte); KASSERT(sc->ich_cmd == -1, ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); mtx_lock(&sc->mutex); sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA; bus_write_1(sc->io_res, ICH_XMIT_SLVA, slave | ICH_XMIT_SLVA_WRITE); bus_write_1(sc->io_res, ICH_HST_CMD, cmd); bus_write_1(sc->io_res, ICH_D0, byte); bus_write_1(sc->io_res, ICH_HST_CNT, ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); smb_error = ichsmb_wait(sc); mtx_unlock(&sc->mutex); DBG("smb_error=%d\n", smb_error); return (smb_error); }
/* Counterpart of smbtx_smb_free(). */ static int intsmb_free(struct intsmb_softc *sc) { INTSMB_LOCK_ASSERT(sc); if ((bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) & PIIX4_SMBHSTSTAT_BUSY) || #ifdef ENABLE_ALART (bus_read_1(sc->io_res, PIIX4_SMBSLVSTS) & PIIX4_SMBSLVSTS_BUSY) || #endif sc->isbusy) return (SMB_EBUSY); sc->isbusy = 1; /* Disable Interrupt in slave part. */ #ifndef ENABLE_ALART bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 0); #endif /* Reset INTR Flag to prepare INTR. */ bus_write_1(sc->io_res, PIIX4_SMBHSTSTS, PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR | PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL); return (0); }
static int intsmb_readw(device_t dev, u_char slave, char cmd, short *word) { struct intsmb_softc *sc = device_get_softc(dev); int error; INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0); error = intsmb_stop(sc); if (error == 0) { *word = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); *word |= bus_read_1(sc->io_res, PIIX4_SMBHSTDAT1) << 8; } INTSMB_UNLOCK(sc); return (error); }
void macgpio_write(device_t dev, uint8_t val) { struct macgpio_softc *sc; struct macgpio_devinfo *dinfo; sc = device_get_softc(device_get_parent(dev)); dinfo = device_get_ivars(dev); if (dinfo->gpio_num < 0) return; bus_write_1(sc->sc_gpios,dinfo->gpio_num,val); }
int ichsmb_writew(device_t dev, u_char slave, char cmd, short word) { const sc_p sc = device_get_softc(dev); int smb_error; DBG("slave=0x%02x cmd=0x%02x word=0x%04x\n", slave, (u_char)cmd, (u_int16_t)word); KASSERT(sc->ich_cmd == -1, ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); mtx_lock(&sc->mutex); sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA; bus_write_1(sc->io_res, ICH_XMIT_SLVA, slave | ICH_XMIT_SLVA_WRITE); bus_write_1(sc->io_res, ICH_HST_CMD, cmd); bus_write_1(sc->io_res, ICH_D0, word & 0xff); bus_write_1(sc->io_res, ICH_D1, word >> 8); bus_write_1(sc->io_res, ICH_HST_CNT, ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); smb_error = ichsmb_wait(sc); mtx_unlock(&sc->mutex); DBG("smb_error=%d\n", smb_error); return (smb_error); }
/* * Wait for completion and return result. */ static int intsmb_stop(struct intsmb_softc *sc) { int error, status; INTSMB_LOCK_ASSERT(sc); if (sc->poll || cold) /* So that it can use device during device probe on SMBus. */ return (intsmb_stop_poll(sc)); error = msleep(sc, &sc->lock, PWAIT | PCATCH, "SMBWAI", hz / 8); if (error == 0) { status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); if (!(status & PIIX4_SMBHSTSTAT_BUSY)) { error = intsmb_error(sc->dev, status); if (error == 0 && !(status & PIIX4_SMBHSTSTAT_INTR)) device_printf(sc->dev, "unknown cause why?\n"); #ifdef ENABLE_ALART bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); #endif return (error); } } /* Timeout Procedure. */ sc->isbusy = 0; /* Re-enable suppressed interrupt from slave part. */ bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); if (error == EWOULDBLOCK) return (SMB_ETIMEOUT); else return (SMB_EABORT); }
static void le_lebuffer_copytodesc(struct lance_softc *sc, void *fromv, int off, int len) { struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc; caddr_t from = fromv; for (; len >= 8; len -= 8, off += 8, from += 8) bus_write_8(lesc->sc_bres, off, be64dec(from)); for (; len >= 4; len -= 4, off += 4, from += 4) bus_write_4(lesc->sc_bres, off, be32dec(from)); for (; len >= 2; len -= 2, off += 2, from += 2) bus_write_2(lesc->sc_bres, off, be16dec(from)); if (len == 1) bus_write_1(lesc->sc_bres, off, *from); }
static int rb_nand_send_address(device_t dev, uint8_t addr) { struct rb_nand_softc *sc; nand_debug(NDBG_DRV,"rb_nand: send address %x", addr); sc = device_get_softc(dev); GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 0); GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 1); GPIO_PIN_SET(sc->sc_gpio, sc->sc_nce_pin, 0); bus_write_1(sc->sc_mem, RB_NAND_DATA, addr); GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 0); return (0); }
static void intsmb_start(struct intsmb_softc *sc, unsigned char cmd, int nointr) { unsigned char tmp; INTSMB_LOCK_ASSERT(sc); tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); tmp &= 0xe0; tmp |= cmd; tmp |= PIIX4_SMBHSTCNT_START; /* While not in autoconfiguration enable interrupts. */ if (!sc->poll && !cold && !nointr) tmp |= PIIX4_SMBHSTCNT_INTREN; bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp); }
static int intsmb_slvintr(struct intsmb_softc *sc) { int status; status = bus_read_1(sc->io_res, PIIX4_SMBSLVSTS); if (status & PIIX4_SMBSLVSTS_BUSY) return (1); if (status & PIIX4_SMBSLVSTS_ALART) intsmb_alrintr(sc); else if (status & ~(PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2 | PIIX4_SMBSLVSTS_SDW1)) { } /* Reset Status Register */ bus_write_1(sc->io_res, PIIX4_SMBSLVSTS, PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2 | PIIX4_SMBSLVSTS_SDW1 | PIIX4_SMBSLVSTS_SLV); return (0); }
static void rb_nand_write_buf(device_t dev, void* buf, uint32_t len) { struct rb_nand_softc *sc; int i; uint8_t *b = (uint8_t*)buf; sc = device_get_softc(dev); for (i = 0; i < len; i++) { #ifdef NAND_DEBUG if (!(i % 16)) printf("%s", i == 0 ? "rb_nand:\n" : "\n"); printf(" %x", b[i]); if (i == len - 1) printf("\n"); #endif bus_write_1(sc->sc_mem, RB_NAND_DATA, b[i]); } }
int macio_enable_wireless(device_t dev, bool enable) { struct macio_softc *sc = device_get_softc(dev); uint32_t x; if (enable) { x = bus_read_4(sc->sc_memr, KEYLARGO_FCR2); x |= 0x4; bus_write_4(sc->sc_memr, KEYLARGO_FCR2, x); /* Enable card slot. */ bus_write_1(sc->sc_memr, KEYLARGO_GPIO_BASE + 0x0f, 5); DELAY(1000); bus_write_1(sc->sc_memr, KEYLARGO_GPIO_BASE + 0x0f, 4); DELAY(1000); x = bus_read_4(sc->sc_memr, KEYLARGO_FCR2); x &= ~0x80000000; bus_write_4(sc->sc_memr, KEYLARGO_FCR2, x); /* out8(gpio + 0x10, 4); */ bus_write_1(sc->sc_memr, KEYLARGO_EXTINT_GPIO_REG_BASE + 0x0b, 0); bus_write_1(sc->sc_memr, KEYLARGO_EXTINT_GPIO_REG_BASE + 0x0a, 0x28); bus_write_1(sc->sc_memr, KEYLARGO_EXTINT_GPIO_REG_BASE + 0x0d, 0x28); bus_write_1(sc->sc_memr, KEYLARGO_GPIO_BASE + 0x0d, 0x28); bus_write_1(sc->sc_memr, KEYLARGO_GPIO_BASE + 0x0e, 0x28); bus_write_4(sc->sc_memr, 0x1c000, 0); /* Initialize the card. */ bus_write_4(sc->sc_memr, 0x1a3e0, 0x41); x = bus_read_4(sc->sc_memr, KEYLARGO_FCR2); x |= 0x80000000; bus_write_4(sc->sc_memr, KEYLARGO_FCR2, x); } else { x = bus_read_4(sc->sc_memr, KEYLARGO_FCR2); x &= ~0x4; bus_write_4(sc->sc_memr, KEYLARGO_FCR2, x); /* out8(gpio + 0x10, 0); */ } return (0); }
static int macgpio_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *res) { struct macgpio_softc *sc; struct macgpio_devinfo *dinfo; u_char val; sc = device_get_softc(bus); dinfo = device_get_ivars(child); if (type != SYS_RES_IRQ) return ENXIO; if (dinfo->gpio_num >= 0) { val = bus_read_1(sc->sc_gpios,dinfo->gpio_num); val &= ~0x80; bus_write_1(sc->sc_gpios,dinfo->gpio_num,val); } return (bus_deactivate_resource(bus, type, rid, res)); }
/* * Handle attach-time duties that are independent of the bus * our device lives on. */ int ichsmb_attach(device_t dev) { const sc_p sc = device_get_softc(dev); int error; /* Create mutex */ mtx_init(&sc->mutex, device_get_nameunit(dev), "ichsmb", MTX_DEF); /* Add child: an instance of the "smbus" device */ if ((sc->smb = device_add_child(dev, DRIVER_SMBUS, -1)) == NULL) { device_printf(dev, "no \"%s\" child found\n", DRIVER_SMBUS); error = ENXIO; goto fail; } /* Clear interrupt conditions */ bus_write_1(sc->io_res, ICH_HST_STA, 0xff); /* Set up interrupt handler */ error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, NULL, ichsmb_device_intr, sc, &sc->irq_handle); if (error != 0) { device_printf(dev, "can't setup irq\n"); goto fail; } /* Attach "smbus" child */ if ((error = bus_generic_attach(dev)) != 0) { device_printf(dev, "failed to attach child: %d\n", error); goto fail; } return (0); fail: mtx_destroy(&sc->mutex); return (error); }
static int intsmb_intr(struct intsmb_softc *sc) { int status, tmp; status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); if (status & PIIX4_SMBHSTSTAT_BUSY) return (1); if (status & (PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR | PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL)) { tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp & ~PIIX4_SMBHSTCNT_INTREN); if (sc->isbusy) { sc->isbusy = 0; wakeup(sc); } return (0); } return (1); /* Not Completed */ }
static int s3c2xx0_rtc_attach(device_t dev) { struct s3c2xx0_rtc_softc *sc; int error, rid; sc = device_get_softc(dev); error = 0; rid = 0; sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); if (sc->mem_res == NULL) { error = ENOMEM; goto out; } bus_write_1(sc->mem_res, RTC_RTCCON, RTCCON_RTCEN); clock_register(dev, 1000000); out: return (error); }
static int s3c2xx0_rtc_settime(device_t dev, struct timespec *ts) { struct s3c2xx0_rtc_softc *sc; struct clocktime ct; sc = device_get_softc(dev); /* Resolution: 1 sec */ if (ts->tv_nsec >= 500000000) ts->tv_sec++; ts->tv_nsec = 0; clock_ts_to_ct(ts, &ct); bus_write_1(sc->mem_res, RTC_BCDSEC, TOBCD(ct.sec)); bus_write_1(sc->mem_res, RTC_BCDMIN, TOBCD(ct.min)); bus_write_1(sc->mem_res, RTC_BCDHOUR, TOBCD(ct.hour)); bus_write_1(sc->mem_res, RTC_BCDDATE, TOBCD(ct.day)); bus_write_1(sc->mem_res, RTC_BCDDAY, TOBCD(ct.dow)); bus_write_1(sc->mem_res, RTC_BCDMON, TOBCD(ct.mon)); bus_write_1(sc->mem_res, RTC_BCDYEAR, TOBCD(ct.year - YEAR_BASE)); return (0); }
static __inline void smc_write_1(struct smc_softc *sc, bus_size_t offset, uint8_t val) { bus_write_1(sc->smc_reg, offset, val); }
static int imx_ata_ch_attach(device_t dev) { struct ata_pci_controller *ctrl; struct ata_channel *ch; int i; ctrl = device_get_softc(device_get_parent(dev)); ch = device_get_softc(dev); for (i = ATA_DATA; i < ATA_MAX_RES; i++) ch->r_io[i].res = ctrl->r_res1; bus_write_2(ctrl->r_res1, 0x24, 0x80); DELAY(100); bus_write_2(ctrl->r_res1, 0x24, 0xc0); DELAY(100); /* Write TIME_OFF/ON/1/2W */ bus_write_1(ctrl->r_res1, 0x00, 3); bus_write_1(ctrl->r_res1, 0x01, 3); bus_write_1(ctrl->r_res1, 0x02, (25 + 15) / 15); bus_write_1(ctrl->r_res1, 0x03, (70 + 15) / 15); /* Write TIME_2R/AX/RDX/4 */ bus_write_1(ctrl->r_res1, 0x04, (70 + 15) / 15); bus_write_1(ctrl->r_res1, 0x05, (50 + 15) / 15 + 2); bus_write_1(ctrl->r_res1, 0x06, 1); bus_write_1(ctrl->r_res1, 0x07, (10 + 15) / 15); /* Write TIME_9 ; the rest of timing registers is irrelevant for PIO */ bus_write_1(ctrl->r_res1, 0x08, (10 + 15) / 15); bus_write_2(ctrl->r_res1, 0x24, 0xc1); DELAY(30000); /* setup ATA registers */ ch->r_io[ATA_DATA ].offset = 0xa0; ch->r_io[ATA_FEATURE].offset = 0xa4; ch->r_io[ATA_ERROR ].offset = 0xa4; ch->r_io[ATA_COUNT ].offset = 0xa8; ch->r_io[ATA_SECTOR ].offset = 0xac; ch->r_io[ATA_CYL_LSB].offset = 0xb0; ch->r_io[ATA_CYL_MSB].offset = 0xb4; ch->r_io[ATA_DRIVE ].offset = 0xb8; ch->r_io[ATA_COMMAND].offset = 0xbc; ch->r_io[ATA_STATUS ].offset = 0xbc; ch->r_io[ATA_ALTSTAT].offset = 0xd8; ch->r_io[ATA_CONTROL].offset = 0xd8; ata_pci_hw(dev); ch->flags |= ATA_NO_SLAVE; ch->flags |= ATA_USE_16BIT; ch->flags |= ATA_CHECKS_CABLE; ch->flags |= ATA_KNOWN_PRESENCE; /* Clear pending interrupts. */ bus_write_2(ctrl->r_res1, 0x28, 0xf8); /* Enable all, but Idle interrupts. */ bus_write_2(ctrl->r_res1, 0x2c, 0x88); return 0; }
static int pcii_probe(device_t dev) { int rid, i, j; u_long start, count, addr; int error = 0; struct pcii_softc *sc; device_set_desc(dev, "PCII IEEE-4888 controller"); sc = device_get_softc(dev); rid = 0; if (bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count) != 0) return ENXIO; /* * The PCIIA decodes a fixed pattern of 0x2e1 for the lower 10 * address bits A0 ... A9. Bits A10 through A12 are used by * the µPD7210 register select lines. This makes the * individual 7210 register being 0x400 bytes apart in the ISA * bus address space. Address bits A13 and A14 are compared * to a DIP switch setting on the card, allowing for up to 4 * different cards being installed (at base addresses 0x2e1, * 0x22e1, 0x42e1, and 0x62e1, respectively). A15 has been * used to select an optional on-board time-of-day clock chip * (MM58167A) on the original PCIIA rather than the µPD7210 * (which is not implemented on later boards). The * documentation states the respective addresses for that chip * should be handled as reserved addresses, which we don't do * (right now). Finally, the IO addresses 0x2f0 ... 0x2f7 for * a "special interrupt handling feature" (re-enable * interrupts so the IRQ can be shared). * * Usually, the user will only set the base address in the * device hints, so we handle the rest here. * * (Source: GPIB-PCIIA Technical Reference Manual, September * 1989 Edition, National Instruments.) */ if ((start & 0x3ff) != 0x2e1) { if (bootverbose) printf("pcii_probe: PCIIA base address 0x%lx not " "0x2e1/0x22e1/0x42e1/0x62e1\n", start); return (ENXIO); } for (rid = 0, addr = start; rid < 8; rid++, addr += 0x400) { if (bus_set_resource(dev, SYS_RES_IOPORT, rid, addr, 1) != 0) { printf("pcii_probe: could not set IO port 0x%lx\n", addr); return (ENXIO); } } if (bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &count) != 0) { printf("pcii_probe: cannot obtain IRQ level\n"); return ENXIO; } if (start > 7) { printf("pcii_probe: IRQ level %lu too high\n", start); return ENXIO; } if (bus_set_resource(dev, SYS_RES_IOPORT, 8, 0x2f0 + start, 1) != 0) { printf("pcii_probe: could not set IO port 0x%3lx\n", 0x2f0 + start); return (ENXIO); } error = bus_alloc_resources(dev, pcii_res_spec, sc->res); if (error) { printf("pcii_probe: Could not allocate resources\n"); return (error); } error = ENXIO; /* * Perform some basic tests on the µPD7210 registers. At * least *some* register must read different from 0x00 or * 0xff. */ for (i = 0; i < 8; i++) { j = bus_read_1(sc->res[2 + i], 0); if (j != 0x00 && j != 0xff) error = 0; } /* SPSR/SPMR read/write test */ if (!error) { bus_write_1(sc->res[2 + 3], 0, 0x55); if (bus_read_1(sc->res[2 + 3], 0) != 0x55) error = ENXIO; } if (!error) { bus_write_1(sc->res[2 + 3], 0, 0xaa); if (bus_read_1(sc->res[2 + 3], 0) != 0xaa) error = ENXIO; } if (error) printf("pcii_probe: probe failure\n"); bus_release_resources(dev, pcii_res_spec, sc->res); return (error); }
/* * Interrupt handler. This handler is bus-independent. Note that our * interrupt may be shared, so we must handle "false" interrupts. */ void ichsmb_device_intr(void *cookie) { const sc_p sc = cookie; const device_t dev = sc->dev; const int maxloops = 16; u_int8_t status; u_int8_t ok_bits; int cmd_index; int count; mtx_lock(&sc->mutex); for (count = 0; count < maxloops; count++) { /* Get and reset status bits */ status = bus_read_1(sc->io_res, ICH_HST_STA); #if ICHSMB_DEBUG if ((status & ~(ICH_HST_STA_INUSE_STS | ICH_HST_STA_HOST_BUSY)) || count > 0) { DBG("%d stat=0x%02x\n", count, status); } #endif status &= ~(ICH_HST_STA_INUSE_STS | ICH_HST_STA_HOST_BUSY); if (status == 0) break; /* Check for unexpected interrupt */ ok_bits = ICH_HST_STA_SMBALERT_STS; cmd_index = sc->ich_cmd >> 2; if (sc->ich_cmd != -1) { KASSERT(cmd_index < sizeof(ichsmb_state_irqs), ("%s: ich_cmd=%d", device_get_nameunit(dev), sc->ich_cmd)); ok_bits |= ichsmb_state_irqs[cmd_index]; } if ((status & ~ok_bits) != 0) { device_printf(dev, "irq 0x%02x during %d\n", status, cmd_index); bus_write_1(sc->io_res, ICH_HST_STA, (status & ~ok_bits)); continue; } /* Handle SMBALERT interrupt */ if (status & ICH_HST_STA_SMBALERT_STS) { static int smbalert_count = 16; if (smbalert_count > 0) { device_printf(dev, "SMBALERT# rec'd\n"); if (--smbalert_count == 0) { device_printf(dev, "not logging anymore\n"); } } } /* Check for bus error */ if (status & ICH_HST_STA_BUS_ERR) { sc->smb_error = SMB_ECOLLI; /* XXX SMB_EBUSERR? */ goto finished; } /* Check for device error */ if (status & ICH_HST_STA_DEV_ERR) { sc->smb_error = SMB_ENOACK; /* or SMB_ETIMEOUT? */ goto finished; } /* Check for byte completion in block transfer */ if (status & ICH_HST_STA_BYTE_DONE_STS) { if (sc->block_write) { if (sc->block_index < sc->block_count) { /* Write next byte */ bus_write_1(sc->io_res, ICH_BLOCK_DB, sc->block_data[sc->block_index++]); } } else { /* First interrupt, get the count also */ if (sc->block_index == 0) { sc->block_count = bus_read_1( sc->io_res, ICH_D0); } /* Get next byte, if any */ if (sc->block_index < sc->block_count) { /* Read next byte */ sc->block_data[sc->block_index++] = bus_read_1(sc->io_res, ICH_BLOCK_DB); /* Set "LAST_BYTE" bit before reading the last byte of block data */ if (sc->block_index >= sc->block_count - 1) { bus_write_1(sc->io_res, ICH_HST_CNT, ICH_HST_CNT_LAST_BYTE | ICH_HST_CNT_INTREN | sc->ich_cmd); } } } } /* Check command completion */ if (status & ICH_HST_STA_INTR) { sc->smb_error = SMB_ENOERR; finished: sc->ich_cmd = -1; bus_write_1(sc->io_res, ICH_HST_STA, status); wakeup(sc); break; } /* Clear status bits and try again */ bus_write_1(sc->io_res, ICH_HST_STA, status); } mtx_unlock(&sc->mutex); /* Too many loops? */ if (count == maxloops) { device_printf(dev, "interrupt loop, status=0x%02x\n", bus_read_1(sc->io_res, ICH_HST_STA)); } }
static __inline void i2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val) { bus_write_1(sc->res, off, val); }
static int iir_pci_attach(device_t dev) { struct gdt_softc *gdt; struct resource *irq = NULL; int retries, rid, error = 0; void *ih; u_int8_t protocol; gdt = device_get_softc(dev); mtx_init(&gdt->sc_lock, "iir", NULL, MTX_DEF); /* map DPMEM */ rid = PCI_DPMEM; gdt->sc_dpmem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (gdt->sc_dpmem == NULL) { device_printf(dev, "can't allocate register resources\n"); error = ENOMEM; goto err; } /* get IRQ */ rid = 0; irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | RF_SHAREABLE); if (irq == NULL) { device_printf(dev, "can't find IRQ value\n"); error = ENOMEM; goto err; } gdt->sc_devnode = dev; gdt->sc_init_level = 0; gdt->sc_hanum = device_get_unit(dev); gdt->sc_bus = pci_get_bus(dev); gdt->sc_slot = pci_get_slot(dev); gdt->sc_vendor = pci_get_vendor(dev); gdt->sc_device = pci_get_device(dev); gdt->sc_subdevice = pci_get_subdevice(dev); gdt->sc_class = GDT_MPR; /* no FC ctr. if (gdt->sc_device >= GDT_PCI_PRODUCT_FC) gdt->sc_class |= GDT_FC; */ /* initialize RP controller */ /* check and reset interface area */ bus_write_4(gdt->sc_dpmem, GDT_MPR_IC, htole32(GDT_MPR_MAGIC)); if (bus_read_4(gdt->sc_dpmem, GDT_MPR_IC) != htole32(GDT_MPR_MAGIC)) { device_printf(dev, "cannot access DPMEM at 0x%lx (shadowed?)\n", rman_get_start(gdt->sc_dpmem)); error = ENXIO; goto err; } bus_set_region_4(gdt->sc_dpmem, GDT_I960_SZ, htole32(0), GDT_MPR_SZ >> 2); /* Disable everything */ bus_write_1(gdt->sc_dpmem, GDT_EDOOR_EN, bus_read_1(gdt->sc_dpmem, GDT_EDOOR_EN) | 4); bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_CMD_INDEX, 0); bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO, htole32(rman_get_start(gdt->sc_dpmem))); bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xff); bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xff) { if (--retries == 0) { device_printf(dev, "DEINIT failed\n"); error = ENXIO; goto err; } DELAY(1); } protocol = (uint8_t)le32toh(bus_read_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO)); bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); if (protocol != GDT_PROTOCOL_VERSION) { device_printf(dev, "unsupported protocol %d\n", protocol); error = ENXIO; goto err; } /* special command to controller BIOS */ bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO, htole32(0)); bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), htole32(0)); bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), htole32(1)); bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), htole32(0)); bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xfe); bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xfe) { if (--retries == 0) { device_printf(dev, "initialization error\n"); error = ENXIO; goto err; } DELAY(1); } bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); gdt->sc_ic_all_size = GDT_MPR_SZ; gdt->sc_copy_cmd = gdt_mpr_copy_cmd; gdt->sc_get_status = gdt_mpr_get_status; gdt->sc_intr = gdt_mpr_intr; gdt->sc_release_event = gdt_mpr_release_event; gdt->sc_set_sema0 = gdt_mpr_set_sema0; gdt->sc_test_busy = gdt_mpr_test_busy; /* Allocate a dmatag representing the capabilities of this attachment */ if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignemnt*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, /*nsegments*/BUS_SPACE_UNRESTRICTED, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, /*lockfunc*/busdma_lock_mutex, /*lockarg*/&gdt->sc_lock, &gdt->sc_parent_dmat) != 0) { error = ENXIO; goto err; } gdt->sc_init_level++; if (iir_init(gdt) != 0) { iir_free(gdt); error = ENXIO; goto err; } /* Register with the XPT */ iir_attach(gdt); /* associate interrupt handler */ if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_MPSAFE, NULL, iir_intr, gdt, &ih )) { device_printf(dev, "Unable to register interrupt handler\n"); error = ENXIO; goto err; } gdt_pci_enable_intr(gdt); return (0); err: if (irq) bus_release_resource( dev, SYS_RES_IRQ, 0, irq ); if (gdt->sc_dpmem) bus_release_resource( dev, SYS_RES_MEMORY, rid, gdt->sc_dpmem ); mtx_destroy(&gdt->sc_lock); return (error); }
static int proto_write(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); error = uiomove(&buf, width, uio); if (error) return (error); switch (width) { case 1: if (r->r_type == PROTO_RES_PCICFG) pci_write_config(dev, ofs, buf.x1[0], 1); else bus_write_1(r->r_d.res, ofs, buf.x1[0]); break; case 2: if (r->r_type == PROTO_RES_PCICFG) pci_write_config(dev, ofs, buf.x2[0], 2); else bus_write_2(r->r_d.res, ofs, buf.x2[0]); break; case 4: if (r->r_type == PROTO_RES_PCICFG) pci_write_config(dev, ofs, buf.x4[0], 4); else bus_write_4(r->r_d.res, ofs, buf.x4[0]); break; #ifndef __i386__ case 8: if (r->r_type == PROTO_RES_PCICFG) return (EINVAL); bus_write_8(r->r_d.res, ofs, buf.x8[0]); break; #endif default: return (EIO); } return (0); }
static void cuda_write_reg(struct cuda_softc *sc, u_int offset, uint8_t value) { bus_write_1(sc->sc_memr, offset, value); }
static int intsmb_attach(device_t dev) { struct intsmb_softc *sc = device_get_softc(dev); int error, rid, value; char *str; sc->dev = dev; mtx_init(&sc->lock, device_get_nameunit(dev), "intsmb", MTX_DEF); rid = PCI_BASE_ADDR_SMB; sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); if (sc->io_res == NULL) { device_printf(dev, "Could not allocate I/O space\n"); error = ENXIO; goto fail; } #ifndef NO_CHANGE_PCICONF pci_write_config(dev, PCIR_INTLINE, 0x9, 1); pci_write_config(dev, PCI_HST_CFG_SMB, PCI_INTR_SMB_IRQ9 | PCI_INTR_SMB_ENABLE, 1); #endif value = pci_read_config(dev, PCI_HST_CFG_SMB, 1); switch (value & 0xe) { case PCI_INTR_SMB_SMI: str = "SMI"; break; case PCI_INTR_SMB_IRQ9: str = "IRQ 9"; break; default: str = "BOGUS"; } device_printf(dev, "intr %s %s ", str, (value & 1) ? "enabled" : "disabled"); printf("revision %d\n", pci_read_config(dev, PCI_REVID_SMB, 1)); if ((value & 0xe) != PCI_INTR_SMB_IRQ9) { device_printf(dev, "Unsupported interrupt mode\n"); error = ENXIO; goto fail; } /* Force IRQ 9. */ rid = 0; bus_set_resource(dev, SYS_RES_IRQ, rid, 9, 1); sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (sc->irq_res == NULL) { device_printf(dev, "Could not allocate irq\n"); error = ENXIO; goto fail; } error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, NULL, intsmb_rawintr, sc, &sc->irq_hand); if (error) { device_printf(dev, "Failed to map intr\n"); goto fail; } sc->isbusy = 0; sc->smbus = device_add_child(dev, "smbus", -1); if (sc->smbus == NULL) { error = ENXIO; goto fail; } error = device_probe_and_attach(sc->smbus); if (error) goto fail; #ifdef ENABLE_ALART /* Enable Arart */ bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); #endif return (0); fail: intsmb_detach(dev); return (error); }
static inline void omap_tll_writeb(struct omap_ehci_softc *sc, bus_size_t off, uint8_t val) { bus_write_1(sc->tll_mem_res, off, val); }
static uint8_t pmio_read(struct resource *res, uint8_t reg) { bus_write_1(res, 0, reg); /* Index */ return (bus_read_1(res, 1)); /* Data */ }
static void pmio_write(struct resource *res, uint8_t reg, uint8_t val) { bus_write_1(res, 0, reg); /* Index */ bus_write_1(res, 1, val); /* Data */ }
static int intsmb_attach(device_t dev) { struct intsmb_softc *sc = device_get_softc(dev); int error, rid, value; int intr; char *str; sc->dev = dev; mtx_init(&sc->lock, device_get_nameunit(dev), "intsmb", MTX_DEF); sc->cfg_irq9 = 0; switch (pci_get_devid(dev)) { #ifndef NO_CHANGE_PCICONF case 0x71138086: /* Intel 82371AB */ case 0x719b8086: /* Intel 82443MX */ /* Changing configuration is allowed. */ sc->cfg_irq9 = 1; break; #endif case 0x43851002: case 0x780b1022: if (pci_get_revid(dev) >= 0x40) sc->sb8xx = 1; break; } if (sc->sb8xx) { error = sb8xx_attach(dev); if (error != 0) goto fail; else goto no_intr; } sc->io_rid = PCI_BASE_ADDR_SMB; sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->io_rid, RF_ACTIVE); if (sc->io_res == NULL) { device_printf(dev, "Could not allocate I/O space\n"); error = ENXIO; goto fail; } if (sc->cfg_irq9) { pci_write_config(dev, PCIR_INTLINE, 0x9, 1); pci_write_config(dev, PCI_HST_CFG_SMB, PCI_INTR_SMB_IRQ9 | PCI_INTR_SMB_ENABLE, 1); } value = pci_read_config(dev, PCI_HST_CFG_SMB, 1); sc->poll = (value & PCI_INTR_SMB_ENABLE) == 0; intr = value & PCI_INTR_SMB_MASK; switch (intr) { case PCI_INTR_SMB_SMI: str = "SMI"; break; case PCI_INTR_SMB_IRQ9: str = "IRQ 9"; break; case PCI_INTR_SMB_IRQ_PCI: str = "PCI IRQ"; break; default: str = "BOGUS"; } device_printf(dev, "intr %s %s ", str, sc->poll == 0 ? "enabled" : "disabled"); printf("revision %d\n", pci_read_config(dev, PCI_REVID_SMB, 1)); if (!sc->poll && intr == PCI_INTR_SMB_SMI) { device_printf(dev, "using polling mode when configured interrupt is SMI\n"); sc->poll = 1; } if (sc->poll) goto no_intr; if (intr != PCI_INTR_SMB_IRQ9 && intr != PCI_INTR_SMB_IRQ_PCI) { device_printf(dev, "Unsupported interrupt mode\n"); error = ENXIO; goto fail; } /* Force IRQ 9. */ rid = 0; if (sc->cfg_irq9) bus_set_resource(dev, SYS_RES_IRQ, rid, 9, 1); sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (sc->irq_res == NULL) { device_printf(dev, "Could not allocate irq\n"); error = ENXIO; goto fail; } error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, NULL, intsmb_rawintr, sc, &sc->irq_hand); if (error) { device_printf(dev, "Failed to map intr\n"); goto fail; } no_intr: sc->isbusy = 0; sc->smbus = device_add_child(dev, "smbus", -1); if (sc->smbus == NULL) { error = ENXIO; goto fail; } error = device_probe_and_attach(sc->smbus); if (error) goto fail; #ifdef ENABLE_ALART /* Enable Arart */ bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); #endif return (0); fail: intsmb_detach(dev); return (error); }