diff options
Diffstat (limited to 'sys/dev/proto')
-rw-r--r-- | sys/dev/proto/proto_bus_pci.c | 19 | ||||
-rw-r--r-- | sys/dev/proto/proto_busdma.c | 22 | ||||
-rw-r--r-- | sys/dev/proto/proto_dev.h | 6 |
3 files changed, 35 insertions, 12 deletions
diff --git a/sys/dev/proto/proto_bus_pci.c b/sys/dev/proto/proto_bus_pci.c index 46ec41e..53ebb5e 100644 --- a/sys/dev/proto/proto_bus_pci.c +++ b/sys/dev/proto/proto_bus_pci.c @@ -82,6 +82,7 @@ proto_pci_attach(device_t dev) { struct proto_softc *sc; struct resource *res; + uint32_t val; int bar, rid, type; sc = device_get_softc(dev); @@ -91,15 +92,17 @@ proto_pci_attach(device_t dev) for (bar = 0; bar < PCIR_MAX_BAR_0; bar++) { rid = PCIR_BAR(bar); - type = SYS_RES_MEMORY; + val = pci_read_config(dev, rid, 4); + type = (PCI_BAR_IO(val)) ? SYS_RES_IOPORT : SYS_RES_MEMORY; res = bus_alloc_resource_any(dev, type, &rid, RF_ACTIVE); - if (res == NULL) { - type = SYS_RES_IOPORT; - res = bus_alloc_resource_any(dev, type, &rid, - RF_ACTIVE); - } - if (res != NULL) - proto_add_resource(sc, type, rid, res); + if (res == NULL) + continue; + proto_add_resource(sc, type, rid, res); + if (type == SYS_RES_IOPORT) + continue; + /* Skip over adjacent BAR for 64-bit memory BARs. */ + if ((val & PCIM_BAR_MEM_TYPE) == PCIM_BAR_MEM_64) + bar++; } rid = 0; diff --git a/sys/dev/proto/proto_busdma.c b/sys/dev/proto/proto_busdma.c index ced4eed..e01e76f 100644 --- a/sys/dev/proto/proto_busdma.c +++ b/sys/dev/proto/proto_busdma.c @@ -129,6 +129,16 @@ proto_busdma_tag_lookup(struct proto_busdma *busdma, u_long key) return (NULL); } +static void +proto_busdma_mem_alloc_callback(void *arg, bus_dma_segment_t *segs, int nseg, + int error) +{ + struct proto_ioc_busdma *ioc = arg; + + ioc->u.mem.bus_nsegs = nseg; + ioc->u.mem.bus_addr = segs[0].ds_addr; +} + static int proto_busdma_mem_alloc(struct proto_busdma *busdma, struct proto_tag *tag, struct proto_ioc_busdma *ioc) @@ -153,10 +163,18 @@ proto_busdma_mem_alloc(struct proto_busdma *busdma, struct proto_tag *tag, return (error); } md->physaddr = pmap_kextract((uintptr_t)(md->virtaddr)); + error = bus_dmamap_load(md->bd_tag, md->bd_map, md->virtaddr, + tag->maxsz, proto_busdma_mem_alloc_callback, ioc, BUS_DMA_NOWAIT); + if (error) { + bus_dmamem_free(md->bd_tag, md->virtaddr, md->bd_map); + bus_dma_tag_destroy(md->bd_tag); + free(md, M_PROTO_BUSDMA); + return (error); + } LIST_INSERT_HEAD(&tag->mds, md, peers); LIST_INSERT_HEAD(&busdma->mds, md, mds); - ioc->u.mem.nsegs = 1; - ioc->u.mem.physaddr = md->physaddr; + ioc->u.mem.phys_nsegs = 1; + ioc->u.mem.phys_addr = md->physaddr; ioc->result = (uintptr_t)(void *)md; return (0); } diff --git a/sys/dev/proto/proto_dev.h b/sys/dev/proto/proto_dev.h index 0050f0b..88a61a7 100644 --- a/sys/dev/proto/proto_dev.h +++ b/sys/dev/proto/proto_dev.h @@ -62,8 +62,10 @@ struct proto_ioc_busdma { struct { unsigned long tag; unsigned int flags; - unsigned int nsegs; - unsigned long physaddr; + unsigned int phys_nsegs; + unsigned long phys_addr; + unsigned long bus_addr; + unsigned int bus_nsegs; } mem; } u; unsigned long result; |