int pci_mapreg_info(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t type, bus_addr_t *basep, bus_size_t *sizep, int *flagsp) { if (PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_IO) return (pci_io_find(pc, tag, reg, type, basep, sizep, flagsp)); else return (pci_mem_find(pc, tag, reg, type, basep, sizep, flagsp)); }
/* * Decode a BAR register. */ int sti_readbar(struct sti_softc *sc, struct pci_attach_args *pa, u_int region, int bar) { bus_addr_t addr; bus_size_t size; u_int32_t cf; int rc; if (bar == 0) { sc->bases[region] = 0; return (0); } #ifdef DIAGNOSTIC if (bar < PCI_MAPREG_START || bar > PCI_MAPREG_PPB_END) { sti_pci_disable_rom(sc); printf("%s: unexpected bar %02x for region %d\n", sc->sc_dev.dv_xname, bar, region); sti_pci_enable_rom(sc); } #endif cf = pci_conf_read(pa->pa_pc, pa->pa_tag, bar); if (PCI_MAPREG_TYPE(cf) == PCI_MAPREG_TYPE_IO) rc = pci_io_find(pa->pa_pc, pa->pa_tag, bar, &addr, &size); else rc = pci_mem_find(pa->pa_pc, pa->pa_tag, bar, &addr, &size, NULL); if (rc != 0) { sti_pci_disable_rom(sc); printf("%s: invalid bar %02x for region %d\n", sc->sc_dev.dv_xname, bar, region); sti_pci_enable_rom(sc); return (rc); } sc->bases[region] = addr; return (0); }
static void atp_attach(struct device * parent, struct device * self, void *aux) { atp_sata_t *sc = (atp_sata_t * )self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; bus_space_tag_t iot = pa->pa_iot; bus_addr_t iobase; bus_size_t iosize; bus_addr_t ideaddr; atp_sata_info_t info; u32 iog_base; u32 ioaddr; int i; if (pci_io_find(pc, pa->pa_tag, 0x14, &iobase, &iosize)) { printf(": can't find i/o space\n"); return; } if (bus_space_map(iot, iobase, iosize, 0, &sc->reg_base)) { printf(": can't map i/o space\n"); return; } ioaddr = sc->reg_base; if (pci_io_find(pc, pa->pa_tag, 0x10, &iobase, &iosize)) { printf(": can't find i/o space\n"); return; } if (bus_space_map(iot, iobase, iosize, 0, &ideaddr)) { printf(": can't map i/o space\n"); return; } iog_base = ioaddr + 0x100; outb(iog_base + 0x0004,0x01);//send COMRESET while(inb(iog_base + 0x0004) & 0x01) { myudelay(10); } outb(iog_base + 0x0004,0x0); for(i = 0;i <= 1;i++) { info.sata_reg_base = ioaddr + i * 0x80; info.flags = i; info.aa_link.aa_type=0xff; //just for not match ide config_found(self,(void *)&info,NULL); } sc->sc_wdcdev.PIO_cap = 0; sc->sc_wdcdev.DMA_cap = 0; sc->sc_wdcdev.channels = sc->wdc_chanarray; sc->sc_wdcdev.nchannels = 1; sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA32;//WDC_CAPABILITY_DATA16; sc->wdc_chanarray[0] = &sc->wdc_channel; sc->wdc_channel.channel = 0; sc->wdc_channel.wdc = &sc->sc_wdcdev; sc->wdc_channel.ch_queue = malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT); if (sc->wdc_channel.ch_queue == NULL) { printf("%s: " "cannot allocate memory for command queue", sc->sc_wdcdev.sc_dev.dv_xname); return ; } sc->wdc_channel.cmd_iot=iot; sc->wdc_channel.ctl_iot=iot; sc->wdc_channel.cmd_ioh= ideaddr+0x80; sc->wdc_channel.ctl_ioh= ideaddr+0x8e; sc->wdc_channel.data32iot = sc->wdc_channel.cmd_iot; sc->wdc_channel.data32ioh = sc->wdc_channel.cmd_ioh; wdcattach(sc->wdc_chanarray[0]); }
int pci_mapreg_submap(struct pci_attach_args *pa, int reg, pcireg_t type, int busflags, bus_size_t maxsize, bus_size_t offset, bus_space_tag_t *tagp, bus_space_handle_t *handlep, bus_addr_t *basep, bus_size_t *sizep) { bus_space_tag_t tag; bus_space_handle_t handle; bus_addr_t base; bus_size_t size; int flags; if (PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_IO) { if ((pa->pa_flags & PCI_FLAGS_IO_ENABLED) == 0) return (1); if (pci_io_find(pa->pa_pc, pa->pa_tag, reg, type, &base, &size, &flags)) return (1); tag = pa->pa_iot; } else { if ((pa->pa_flags & PCI_FLAGS_MEM_ENABLED) == 0) return (1); if (pci_mem_find(pa->pa_pc, pa->pa_tag, reg, type, &base, &size, &flags)) return (1); tag = pa->pa_memt; } if (reg == PCI_MAPREG_ROM) { pcireg_t mask; int s; /* we have to enable the ROM address decoder... */ s = splhigh(); mask = pci_conf_read(pa->pa_pc, pa->pa_tag, reg); mask |= PCI_MAPREG_ROM_ENABLE; pci_conf_write(pa->pa_pc, pa->pa_tag, reg, mask); splx(s); } /* If we're called with maxsize/offset of 0, behave like * pci_mapreg_map. */ maxsize = (maxsize && offset) ? maxsize : size; base += offset; if ((maxsize < size && offset + maxsize <= size) || offset != 0) return (1); if (bus_space_map(tag, base, maxsize, busflags | flags, &handle)) return (1); if (tagp != 0) *tagp = tag; if (handlep != 0) *handlep = handle; if (basep != 0) *basep = base; if (sizep != 0) *sizep = maxsize; return (0); }