示例#1
0
文件: busra.c 项目: andreiw/polaris
/*
 * 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);
}
示例#2
0
/*
 * 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));
}
示例#3
0
文件: busra.c 项目: andreiw/polaris
/*
 * 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);

}