/* * If the device is a PCI bus device (i.e bus-range property exists) then * claim the bus numbers used by the device from the specified bus * resource map. */ static int claim_pci_busnum(dev_info_t *dip, void *arg) { struct bus_range pci_bus_range; struct busnum_ctrl *ctrl; ndi_ra_request_t req; char bus_type[16] = "(unknown)"; int len; uint64_t base; uint64_t retlen; ctrl = (struct busnum_ctrl *)arg; /* check if this is a PCI bus node */ len = sizeof (bus_type); if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF, DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "device_type", (caddr_t)&bus_type, &len) != DDI_SUCCESS) return (DDI_WALK_PRUNECHILD); /* it is not a pci/pci-ex bus type */ if ((strcmp(bus_type, "pci") != 0) && (strcmp(bus_type, "pciex") != 0)) return (DDI_WALK_PRUNECHILD); /* look for the bus-range property */ len = sizeof (struct bus_range); if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "bus-range", (caddr_t)&pci_bus_range, &len) == DDI_SUCCESS) { if ((pci_bus_range.lo >= ctrl->range->lo) && (pci_bus_range.hi <= ctrl->range->hi)) { /* claim the bus range from the bus resource map */ bzero((caddr_t)&req, sizeof (req)); req.ra_addr = (uint64_t)pci_bus_range.lo; req.ra_flags |= NDI_RA_ALLOC_SPECIFIED; req.ra_len = (uint64_t)pci_bus_range.hi - (uint64_t)pci_bus_range.lo + 1; if (ndi_ra_alloc(ctrl->dip, &req, &base, &retlen, NDI_RA_TYPE_PCI_BUSNUM, 0) == NDI_SUCCESS) return (DDI_WALK_PRUNECHILD); } } /* * Error return. */ ctrl->rv = DDI_FAILURE; return (DDI_WALK_TERMINATE); }
/* * gfc_claim_memory * * claim-memory ( align size vhint -- vaddr) */ static int gfc_claim_memory(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp) { int align, size, vhint; ndi_ra_request_t request; uint64_t answer, alen; struct fc_resource *ip; if (fc_cell2int(cp->nargs) != 3) return (fc_syntax_error(cp, "nargs must be 3")); if (fc_cell2int(cp->nresults) < 1) return (fc_syntax_error(cp, "nresults must be >= 1")); vhint = fc_cell2int(fc_arg(cp, 2)); size = fc_cell2int(fc_arg(cp, 1)); align = fc_cell2int(fc_arg(cp, 0)); FC_DEBUG3(1, CE_CONT, "gfc_claim_memory: align=0x%x size=0x%x " "vhint=0x%x\n", align, size, vhint); if (size == 0) { cmn_err(CE_WARN, " gfc_claim_memory - unable to allocate " "contigiuos memory of size zero\n"); return (fc_priv_error(cp, "allocation error")); } if (vhint) { cmn_err(CE_WARN, "gfc_claim_memory - vhint is not zero " "vhint=0x%x - Ignoring Argument\n", vhint); } bzero((caddr_t)&request, sizeof (ndi_ra_request_t)); request.ra_flags = NDI_RA_ALLOC_BOUNDED; request.ra_boundbase = 0; request.ra_boundlen = 0xffffffff; request.ra_len = size; request.ra_align_mask = align - 1; if (ndi_ra_alloc(ddi_root_node(), &request, &answer, &alen, "gptwo-contigousmem", NDI_RA_PASS) != NDI_SUCCESS) { cmn_err(CE_WARN, " gfc_claim_memory - unable to allocate " "contigiuos memory\n"); return (fc_priv_error(cp, "allocation error")); } FC_DEBUG2(1, CE_CONT, "gfc_claim_memory: address allocated=0x%lx " "size=0x%x\n", answer, alen); cp->nresults = fc_int2cell(1); fc_result(cp, 0) = answer; /* * Log this resource ... */ ip = kmem_zalloc(sizeof (struct fc_resource), KM_SLEEP); ip->type = RT_CONTIGIOUS; ip->fc_contig_virt = (void *)answer; ip->fc_contig_len = size; fc_add_resource(rp, ip); return (fc_success_op(ap, rp, cp)); }
/* * isa_resource_setup * check for /used-resources and initialize * based on info there. If no /used-resources, * fail. */ int isa_resource_setup() { dev_info_t *used, *usedpdip; /* * note that at this time bootconf creates 32 bit properties for * io-space and device-memory */ struct iorange { uint32_t base; uint32_t len; } *iorange; struct memrange { uint32_t base; uint32_t len; } *memrange; uint32_t *irq; int proplen; int i, len; int maxrange; ndi_ra_request_t req; uint64_t retbase; uint64_t retlen; used = ddi_find_devinfo("used-resources", -1, 0); if (used == NULL) { DEBUGPRT(CE_CONT, "isa_resource_setup: used-resources not found"); return (NDI_FAILURE); } /* * initialize to all resources being present * and then remove the ones in use. */ usedpdip = ddi_root_node(); DEBUGPRT(CE_CONT, "isa_resource_setup: used = %p usedpdip = %p\n", (void *)used, (void *)usedpdip); if (ndi_ra_map_setup(usedpdip, NDI_RA_TYPE_IO) == NDI_FAILURE) { return (NDI_FAILURE); } /* initialize io space, highest end base is 0xffff */ /* note that length is highest addr + 1 since starts from 0 */ (void) ndi_ra_free(usedpdip, 0, 0xffff + 1, NDI_RA_TYPE_IO, 0); if (ddi_getlongprop(DDI_DEV_T_ANY, used, DDI_PROP_DONTPASS, "io-space", (caddr_t)&iorange, &proplen) == DDI_SUCCESS) { maxrange = proplen / sizeof (struct iorange); /* remove the "used" I/O resources */ for (i = 0; i < maxrange; i++) { bzero((caddr_t)&req, sizeof (req)); req.ra_addr = (uint64_t)iorange[i].base; req.ra_len = (uint64_t)iorange[i].len; req.ra_flags = NDI_RA_ALLOC_SPECIFIED; (void) ndi_ra_alloc(usedpdip, &req, &retbase, &retlen, NDI_RA_TYPE_IO, 0); } kmem_free((caddr_t)iorange, proplen); } if (ndi_ra_map_setup(usedpdip, NDI_RA_TYPE_MEM) == NDI_FAILURE) { return (NDI_FAILURE); } /* initialize memory space where highest end base is 0xffffffff */ /* note that length is highest addr + 1 since starts from 0 */ (void) ndi_ra_free(usedpdip, 0, ((uint64_t)((uint32_t)~0)) + 1, NDI_RA_TYPE_MEM, 0); if (ddi_getlongprop(DDI_DEV_T_ANY, used, DDI_PROP_DONTPASS, "device-memory", (caddr_t)&memrange, &proplen) == DDI_SUCCESS) { maxrange = proplen / sizeof (struct memrange); /* remove the "used" memory resources */ for (i = 0; i < maxrange; i++) { bzero((caddr_t)&req, sizeof (req)); req.ra_addr = (uint64_t)memrange[i].base; req.ra_len = (uint64_t)memrange[i].len; req.ra_flags = NDI_RA_ALLOC_SPECIFIED; (void) ndi_ra_alloc(usedpdip, &req, &retbase, &retlen, NDI_RA_TYPE_MEM, 0); } kmem_free((caddr_t)memrange, proplen); } if (ndi_ra_map_setup(usedpdip, NDI_RA_TYPE_INTR) == NDI_FAILURE) { return (NDI_FAILURE); } /* initialize the interrupt space */ (void) ndi_ra_free(usedpdip, 0, 16, NDI_RA_TYPE_INTR, 0); #if defined(__i386) || defined(__amd64) bzero(&req, sizeof (req)); req.ra_addr = 2; /* 2 == 9 so never allow */ req.ra_len = 1; req.ra_flags = NDI_RA_ALLOC_SPECIFIED; (void) ndi_ra_alloc(usedpdip, &req, &retbase, &retlen, NDI_RA_TYPE_INTR, 0); #endif if (ddi_getlongprop(DDI_DEV_T_ANY, used, DDI_PROP_DONTPASS, "interrupts", (caddr_t)&irq, &proplen) == DDI_SUCCESS) { /* Initialize available interrupts by negating the used */ len = (proplen / sizeof (uint32_t)); for (i = 0; i < len; i++) { bzero((caddr_t)&req, sizeof (req)); req.ra_addr = (uint64_t)irq[i]; req.ra_len = 1; req.ra_flags = NDI_RA_ALLOC_SPECIFIED; (void) ndi_ra_alloc(usedpdip, &req, &retbase, &retlen, NDI_RA_TYPE_INTR, 0); } kmem_free((caddr_t)irq, proplen); } #ifdef BUSRA_DEBUG if (busra_debug) { (void) ra_dump_all(NULL, usedpdip); } #endif return (NDI_SUCCESS); }