static void le_lebuffer_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val) { struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc; bus_write_2(lesc->sc_rres, LEREG1_RAP, port); bus_barrier(lesc->sc_rres, LEREG1_RAP, 2, BUS_SPACE_BARRIER_WRITE); bus_write_2(lesc->sc_rres, LEREG1_RDP, val); }
static void le_isa_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val) { struct le_isa_softc *lesc = (struct le_isa_softc *)sc; bus_write_2(lesc->sc_rres, lesc->sc_rap, port); bus_barrier(lesc->sc_rres, lesc->sc_rap, 2, BUS_SPACE_BARRIER_WRITE); bus_write_2(lesc->sc_rres, lesc->sc_rdp, val); }
static void le_pci_wrbcr(struct lance_softc *sc, uint16_t port, uint16_t val) { struct le_pci_softc *lesc = (struct le_pci_softc *)sc; bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, port); bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE); bus_write_2(lesc->sc_rres, PCNET_PCI_BDP, val); }
static void sdhci_fdt_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val) { struct sdhci_fdt_softc *sc = device_get_softc(dev); bus_write_2(sc->mem_res[slot->num], off, val); }
/** * Write a 1, 2, or 4 byte data item to the PCI core's registers at @p offset. * * @param sc bhndb PCI driver state. * @param offset register write offset. * @param value value to be written. * @param width item width (1, 2, or 4 bytes). */ static void bhndb_pci_write_core(struct bhndb_pci_softc *sc, bus_size_t offset, uint32_t value, u_int width) { struct resource *r; bus_size_t r_offset; int error; error = bhndb_pci_get_core_regs(sc, offset, width, &r, &r_offset); if (error) { panic("no PCI register window mapping %#jx+%#x: %d", (uintmax_t)offset, width, error); } switch (width) { case 1: bus_write_1(r, r_offset, value); break; case 2: bus_write_2(r, r_offset, value); break; case 4: bus_write_4(r, r_offset, value); break; default: panic("invalid width: %u", width); } }
/** * Write a data item to the bridged address space at the given @p offset from * @p addr. * * A dynamic register window will be used to map @p addr. * * @param probe The bhndb_pci probe state to be used to perform the * write. * @param addr The base address. * @param offset The offset from @p addr at which @p value will be * written. * @param value The data item to be written. * @param width The data item width (1, 2, or 4 bytes). */ static void bhndb_pci_probe_write(struct bhndb_pci_probe *probe, bhnd_addr_t addr, bhnd_size_t offset, uint32_t value, u_int width) { struct resource *r; bus_size_t res_offset; int error; /* Map the target address */ error = bhndb_pci_probe_map(probe, addr, offset, width, &r, &res_offset); if (error) { device_printf(probe->dev, "error mapping %#jx+%#jx for " "writing: %d\n", addr, offset, error); return; } /* Perform write */ switch (width) { case 1: return (bus_write_1(r, res_offset, value)); case 2: return (bus_write_2(r, res_offset, value)); case 4: return (bus_write_4(r, res_offset, value)); default: panic("unsupported width: %u", width); } }
static void imx_ata_intr(void *data) { struct ata_pci_controller *ctrl = data; bus_write_2(ctrl->r_res1, 0x28, bus_read_2(ctrl->r_res1, 0x28)); ctrl->interrupt[0].function(ctrl->interrupt[0].argument); }
static uint16_t le_isa_rdcsr(struct lance_softc *sc, uint16_t port) { struct le_isa_softc *lesc = (struct le_isa_softc *)sc; bus_write_2(lesc->sc_rres, lesc->sc_rap, port); bus_barrier(lesc->sc_rres, lesc->sc_rap, 2, BUS_SPACE_BARRIER_WRITE); return (bus_read_2(lesc->sc_rres, lesc->sc_rdp)); }
static void isf_write_cmd(struct isf_softc *sc, off_t off, uint16_t cmd) { if (isf_debug) device_printf(sc->isf_dev, "isf_write_cmd(0x%08jx, 0x%02x)\n", off, cmd); bus_write_2(sc->isf_res, off, htole16(cmd)); }
static void le_pci_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val) { struct le_pci_softc *lesc = (struct le_pci_softc *)sc; #ifdef __HAIKU__ HAIKU_INTR_REGISTER_STATE; if (port == LE_CSR0) HAIKU_INTR_REGISTER_ENTER(); #endif bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, port); bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE); bus_write_2(lesc->sc_rres, PCNET_PCI_RDP, val); #ifdef __HAIKU__ if (port == LE_CSR0) HAIKU_INTR_REGISTER_LEAVE(); #endif }
static uint16_t le_pci_rdbcr(struct lance_softc *sc, uint16_t port) { struct le_pci_softc *lesc = (struct le_pci_softc *)sc; bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, port); bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE); return (bus_read_2(lesc->sc_rres, PCNET_PCI_BDP)); }
static uint16_t le_lebuffer_rdcsr(struct lance_softc *sc, uint16_t port) { struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc; bus_write_2(lesc->sc_rres, LEREG1_RAP, port); bus_barrier(lesc->sc_rres, LEREG1_RAP, 2, BUS_SPACE_BARRIER_WRITE); return (bus_read_2(lesc->sc_rres, LEREG1_RDP)); }
static __inline void smc_select_bank(struct smc_softc *sc, uint16_t bank) { bus_barrier(sc->smc_reg, BSR, 2, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); bus_write_2(sc->smc_reg, BSR, bank & BSR_BANK_MASK); bus_barrier(sc->smc_reg, BSR, 2, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); }
static void le_lebuffer_zerobuf(struct lance_softc *sc, int off, int len) { struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc; for (; len >= 2; len -= 2, off += 2) bus_write_2(lesc->sc_bres, off, 0); if (len == 1) bus_write_1(lesc->sc_bres, off + 1, 0); }
static void le_lebuffer_copytobuf(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 >= 2; len -= 2, off += 2, from += 2) bus_write_2(lesc->sc_bres, off, le16dec(from)); if (len == 1) bus_write_1(lesc->sc_bres, off + 1, *from); }
void gdt_mpr_copy_cmd(struct gdt_softc *gdt, struct gdt_ccb *gccb) { u_int16_t cp_count = roundup(gccb->gc_cmd_len, sizeof (u_int32_t)); u_int16_t dp_offset = gdt->sc_cmd_off; u_int16_t cmd_no = gdt->sc_cmd_cnt++; GDT_DPRINTF(GDT_D_CMD, ("gdt_mpr_copy_cmd(%p) ", gdt)); gdt->sc_cmd_off += cp_count; bus_write_region_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_DPR_CMD + dp_offset, (u_int32_t *)gccb->gc_cmd, cp_count >> 2); bus_write_2(gdt->sc_dpmem, GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_OFFSET, htole16(GDT_DPMEM_COMMAND_OFFSET + dp_offset)); bus_write_2(gdt->sc_dpmem, GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_SERV_ID, htole16(gccb->gc_service)); }
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 uint16_t le_pci_rdcsr(struct lance_softc *sc, uint16_t port) { struct le_pci_softc *lesc = (struct le_pci_softc *)sc; #ifdef __HAIKU__ HAIKU_INTR_REGISTER_STATE; uint16_t value; if (port == LE_CSR0) HAIKU_INTR_REGISTER_ENTER(); #endif bus_write_2(lesc->sc_rres, PCNET_PCI_RAP, port); bus_barrier(lesc->sc_rres, PCNET_PCI_RAP, 2, BUS_SPACE_BARRIER_WRITE); #ifndef __HAIKU__ return (bus_read_2(lesc->sc_rres, PCNET_PCI_RDP)); #else value = bus_read_2(lesc->sc_rres, PCNET_PCI_RDP); if (port == LE_CSR0) HAIKU_INTR_REGISTER_LEAVE(); return value; #endif }
static inline void WR2(struct ffec_softc *sc, bus_size_t off, uint16_t val) { bus_write_2(sc->mem_res, off, 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 isf_write(struct isf_softc *sc, off_t off, void *data, size_t len) { int cycles, error = 0; uint16_t *dp; uint16_t status; off_t coff; KASSERT((uintptr_t)data % 2 == 0, ("%s: unaligned data %p", __func__, data)); KASSERT((len <= ISF_SECTORSIZE) && (len % 2 == 0), ("%s: invalid length %ju", __func__, len)); KASSERT(off % ISF_SECTORSIZE == 0, ("%s: invalid offset %ju\n", __func__, off)); KASSERT(!sc->isf_erasing, ("%s: trying to write while erasing\n", __func__)); KASSERT(sc->isf_bstate[off / ISF_ERASE_BLOCK] != BS_ERASING, ("%s: block being erased at %ju\n", __func__, off)); isf_unlock_block(sc, off); #ifdef ISF_BUFFER_PROGRAM for (dp = data, coff = off; dp - (uint16_t *)data < len / 2; dp += 32, coff += 64) { isf_clear_status(sc); isf_write_cmd(sc, coff, ISF_CMD_BPS); cycles = 0xFFFF; while ( !(isf_read_off(sc, coff) & ISF_SR_DWS) ) { if (cycles-- == 0) { device_printf(sc->isf_dev, "timeout waiting" " for write to start at 0x08%jx\n", (intmax_t)coff); return (EIO); } isf_write_cmd(sc, coff, ISF_CMD_BPS); } /* When writing N blocks, send N-1 as the count */ isf_write_cmd(sc, coff, 31); bus_write_region_2(sc->isf_res, coff, dp, 32); isf_write_cmd(sc, coff, ISF_CMD_BPC); status = isf_read_off(sc, coff); cycles = 0xFFFFF; while ( !(status & ISF_SR_DWS) ) { if (cycles-- == 0) { device_printf(sc->isf_dev, "timeout waiting" " for write to complete at 0x08%jx\n", (intmax_t)coff); error = EIO; break; } status = isf_read_off(sc, coff); } isf_full_status_check(sc, off); isf_write_cmd(sc, coff, ISF_CMD_RA); } #else for (dp = data, coff = off; dp - (uint16_t *)data < len / 2; dp++, coff += 2) { isf_write_cmd(sc, coff, ISF_CMD_WPS); bus_write_2(sc->isf_res, coff, *dp); status = isf_read_off(sc, coff); cycles=0xFFFFF; while ( !(status & ISF_SR_DWS) ) { if (cycles-- == 0) { device_printf(sc->isf_dev, "timeout waiting" " for write to complete at 0x08%jx\n", (intmax_t)coff); error = EIO; break; } status = isf_read_off(sc, coff); } } isf_full_status_check(sc, off); isf_write_cmd(sc, coff, ISF_CMD_RA); #endif isf_lock_block(sc, off); return error; }
/** * ti_i2c_write_2 - writes a 16-bit value to one of the I2C registers * @sc: I2C device context * @off: the byte offset within the register bank to read from. * @val: the value to write into the register * * LOCKING: * No locking required * * RETURNS: * 16-bit value read from the register. */ static inline void ti_i2c_write_2(struct ti_i2c_softc *sc, bus_size_t off, uint16_t val) { bus_write_2(sc->sc_mem_res, off, val); }
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 int ti_i2c_reset(struct ti_i2c_softc *sc, u_char speed) { int timeout; struct ti_i2c_clock_config *clkcfg; u_int busfreq; uint16_t fifo_trsh, reg, scll, sclh; switch (ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: clkcfg = ti_omap4_i2c_clock_configs; break; #endif #ifdef SOC_TI_AM335X case CHIP_AM335X: clkcfg = ti_am335x_i2c_clock_configs; break; #endif default: panic("Unknown Ti SoC, unable to reset the i2c"); } /* * If we haven't attached the bus yet, just init at the default slow * speed. This lets us get the hardware initialized enough to attach * the bus which is where the real speed configuration is handled. After * the bus is attached, get the configured speed from it. Search the * configuration table for the best speed we can do that doesn't exceed * the requested speed. */ if (sc->sc_iicbus == NULL) busfreq = 100000; else busfreq = IICBUS_GET_FREQUENCY(sc->sc_iicbus, speed); for (;;) { if (clkcfg[1].frequency == 0 || clkcfg[1].frequency > busfreq) break; clkcfg++; } /* * 23.1.4.3 - HS I2C Software Reset * From OMAP4 TRM at page 4068. * * 1. Ensure that the module is disabled. */ sc->sc_con_reg = 0; ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg); /* 2. Issue a softreset to the controller. */ bus_write_2(sc->sc_mem_res, I2C_REG_SYSC, I2C_REG_SYSC_SRST); /* * 3. Enable the module. * The I2Ci.I2C_SYSS[0] RDONE bit is asserted only after the module * is enabled by setting the I2Ci.I2C_CON[15] I2C_EN bit to 1. */ ti_i2c_write_2(sc, I2C_REG_CON, I2C_CON_I2C_EN); /* 4. Wait for the software reset to complete. */ timeout = 0; while ((ti_i2c_read_2(sc, I2C_REG_SYSS) & I2C_SYSS_RDONE) == 0) { if (timeout++ > 100) return (EBUSY); DELAY(100); } /* * Disable the I2C controller once again, now that the reset has * finished. */ ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg); /* * The following sequence is taken from the OMAP4 TRM at page 4077. * * 1. Enable the functional and interface clocks (see Section * 23.1.5.1.1.1.1). Done at ti_i2c_activate(). * * 2. Program the prescaler to obtain an approximately 12MHz internal * sampling clock (I2Ci_INTERNAL_CLK) by programming the * corresponding value in the I2Ci.I2C_PSC[3:0] PSC field. * This value depends on the frequency of the functional clock * (I2Ci_FCLK). Because this frequency is 96MHz, the * I2Ci.I2C_PSC[7:0] PSC field value is 0x7. */ ti_i2c_write_2(sc, I2C_REG_PSC, clkcfg->psc); /* * 3. Program the I2Ci.I2C_SCLL[7:0] SCLL and I2Ci.I2C_SCLH[7:0] SCLH * bit fields to obtain a bit rate of 100 Kbps, 400 Kbps or 1Mbps. * These values depend on the internal sampling clock frequency * (see Table 23-8). */ scll = clkcfg->scll & I2C_SCLL_MASK; sclh = clkcfg->sclh & I2C_SCLH_MASK; /* * 4. (Optional) Program the I2Ci.I2C_SCLL[15:8] HSSCLL and * I2Ci.I2C_SCLH[15:8] HSSCLH fields to obtain a bit rate of * 400K bps or 3.4M bps (for the second phase of HS mode). These * values depend on the internal sampling clock frequency (see * Table 23-8). * * 5. (Optional) If a bit rate of 3.4M bps is used and the bus line * capacitance exceeds 45 pF, (see Section 18.4.8, PAD Functional * Multiplexing and Configuration). */ switch (ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: if ((clkcfg->hsscll + clkcfg->hssclh) > 0) { scll |= clkcfg->hsscll << I2C_HSSCLL_SHIFT; sclh |= clkcfg->hssclh << I2C_HSSCLH_SHIFT; sc->sc_con_reg |= I2C_CON_OPMODE_HS; } break; #endif } /* Write the selected bit rate. */ ti_i2c_write_2(sc, I2C_REG_SCLL, scll); ti_i2c_write_2(sc, I2C_REG_SCLH, sclh); /* * 6. Configure the Own Address of the I2C controller by storing it in * the I2Ci.I2C_OA0 register. Up to four Own Addresses can be * programmed in the I2Ci.I2C_OAi registers (where i = 0, 1, 2, 3) * for each I2C controller. * * Note: For a 10-bit address, set the corresponding expand Own Address * bit in the I2Ci.I2C_CON register. * * Driver currently always in single master mode so ignore this step. */ /* * 7. Set the TX threshold (in transmitter mode) and the RX threshold * (in receiver mode) by setting the I2Ci.I2C_BUF[5:0]XTRSH field to * (TX threshold - 1) and the I2Ci.I2C_BUF[13:8]RTRSH field to (RX * threshold - 1), where the TX and RX thresholds are greater than * or equal to 1. * * The threshold is set to 5 for now. */ fifo_trsh = (sc->sc_fifo_trsh - 1) & I2C_BUF_TRSH_MASK; reg = fifo_trsh | (fifo_trsh << I2C_BUF_RXTRSH_SHIFT); ti_i2c_write_2(sc, I2C_REG_BUF, reg); /* * 8. Take the I2C controller out of reset by setting the * I2Ci.I2C_CON[15] I2C_EN bit to 1. * * 23.1.5.1.1.1.2 - Initialize the I2C Controller * * To initialize the I2C controller, perform the following steps: * * 1. Configure the I2Ci.I2C_CON register: * . For master or slave mode, set the I2Ci.I2C_CON[10] MST bit * (0: slave, 1: master). * . For transmitter or receiver mode, set the I2Ci.I2C_CON[9] TRX * bit (0: receiver, 1: transmitter). */ /* Enable the I2C controller in master mode. */ sc->sc_con_reg |= I2C_CON_I2C_EN | I2C_CON_MST; ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg); /* * 2. If using an interrupt to transmit/receive data, set the * corresponding bit in the I2Ci.I2C_IE register (the I2Ci.I2C_IE[4] * XRDY_IE bit for the transmit interrupt, the I2Ci.I2C_IE[3] RRDY * bit for the receive interrupt). */ /* Set the interrupts we want to be notified. */ reg = I2C_IE_XDR | /* Transmit draining interrupt. */ I2C_IE_XRDY | /* Transmit Data Ready interrupt. */ I2C_IE_RDR | /* Receive draining interrupt. */ I2C_IE_RRDY | /* Receive Data Ready interrupt. */ I2C_IE_ARDY | /* Register Access Ready interrupt. */ I2C_IE_NACK | /* No Acknowledgment interrupt. */ I2C_IE_AL; /* Arbitration lost interrupt. */ /* Enable the interrupts. */ ti_i2c_write_2(sc, I2C_REG_IRQENABLE_SET, reg); /* * 3. If using DMA to receive/transmit data, set to 1 the corresponding * bit in the I2Ci.I2C_BUF register (the I2Ci.I2C_BUF[15] RDMA_EN * bit for the receive DMA channel, the I2Ci.I2C_BUF[7] XDMA_EN bit * for the transmit DMA channel). * * Not using DMA for now, so ignore this. */ return (0); }
static __inline void smc_write_2(struct smc_softc *sc, bus_size_t offset, uint16_t val) { bus_write_2(sc->smc_reg, offset, val); }
int smc_probe(device_t dev) { int rid, type, error; uint16_t val; struct smc_softc *sc; struct resource *reg; sc = device_get_softc(dev); rid = 0; type = SYS_RES_IOPORT; error = 0; if (sc->smc_usemem) type = SYS_RES_MEMORY; reg = bus_alloc_resource(dev, type, &rid, 0, ~0, 16, RF_ACTIVE); if (reg == NULL) { if (bootverbose) device_printf(dev, "could not allocate I/O resource for probe\n"); return (ENXIO); } /* Check for the identification value in the BSR. */ val = bus_read_2(reg, BSR); if ((val & BSR_IDENTIFY_MASK) != BSR_IDENTIFY) { if (bootverbose) device_printf(dev, "identification value not in BSR\n"); error = ENXIO; goto done; } /* * Try switching banks and make sure we still get the identification * value. */ bus_write_2(reg, BSR, 0); val = bus_read_2(reg, BSR); if ((val & BSR_IDENTIFY_MASK) != BSR_IDENTIFY) { if (bootverbose) device_printf(dev, "identification value not in BSR after write\n"); error = ENXIO; goto done; } #if 0 /* Check the BAR. */ bus_write_2(reg, BSR, 1); val = bus_read_2(reg, BAR); val = BAR_ADDRESS(val); if (rman_get_start(reg) != val) { if (bootverbose) device_printf(dev, "BAR address %x does not match " "I/O resource address %lx\n", val, rman_get_start(reg)); error = ENXIO; goto done; } #endif /* Compare REV against known chip revisions. */ bus_write_2(reg, BSR, 3); val = bus_read_2(reg, REV); val = (val & REV_CHIP_MASK) >> REV_CHIP_SHIFT; if (smc_chip_ids[val] == NULL) { if (bootverbose) device_printf(dev, "Unknown chip revision: %d\n", val); error = ENXIO; goto done; } device_set_desc(dev, smc_chip_ids[val]); done: bus_release_resource(dev, type, rid, reg); return (error); }
static __inline void smc_select_bank(struct smc_softc *sc, uint16_t bank) { bus_write_2(sc->smc_reg, BSR, bank & BSR_BANK_MASK); }