Exemplo n.º 1
0
static int
profile_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	switch (cmd) {
	case DDI_ATTACH:
		break;
	case DDI_RESUME:
		return (DDI_SUCCESS);
	default:
		return (DDI_FAILURE);
	}

	if (ddi_create_minor_node(devi, "profile", S_IFCHR, 0,
	    DDI_PSEUDO, NULL) == DDI_FAILURE ||
	    dtrace_register("profile", &profile_attr,
	    DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER, NULL,
	    &profile_pops, NULL, &profile_id) != 0) {
		ddi_remove_minor_node(devi, NULL);
		return (DDI_FAILURE);
	}

	profile_max = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
	    "profile-max-probes", PROFILE_MAX_DEFAULT);

	ddi_report_dev(devi);
	profile_devi = devi;
	return (DDI_SUCCESS);
}
Exemplo n.º 2
0
void
pcieb_plat_initchild(dev_info_t *child)
{
	struct ddi_parent_private_data *pdptr;
	if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS, "interrupts",
	    -1) != -1) {
		pdptr = kmem_zalloc((sizeof (struct ddi_parent_private_data) +
		    sizeof (struct intrspec)), KM_SLEEP);
		pdptr->par_intr = (struct intrspec *)(pdptr + 1);
		pdptr->par_nintr = 1;
		ddi_set_parent_data(child, pdptr);
	} else
		ddi_set_parent_data(child, NULL);
}
Exemplo n.º 3
0
/*
 * Check if driver should be treated as an old pre 2.6 driver
 */
static int
old_driver(dev_info_t *dip)
{
	extern int ignore_hardware_nodes;	/* force flag from ddi_impl.c */

	if (ndi_dev_is_persistent_node(dip)) {
		if (ignore_hardware_nodes)
			return (1);
		if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
		    "ignore-hardware-nodes", -1) != -1)
			return (1);
	}
	return (0);
}
Exemplo n.º 4
0
/*ARGSUSED1*/
static int
mm_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	int i;
	struct mem_minor {
		char *name;
		minor_t minor;
		int privonly;
		const char *rdpriv;
		const char *wrpriv;
		mode_t priv_mode;
	} mm[] = {
		{ "mem",	M_MEM,		0,	NULL,	"all",	0640 },
		{ "kmem",	M_KMEM,		0,	NULL,	"all",	0640 },
		{ "allkmem",	M_ALLKMEM,	0,	"all",	"all",	0600 },
		{ "null",	M_NULL,	PRIVONLY_DEV,	NULL,	NULL,	0666 },
		{ "zero",	M_ZERO, PRIVONLY_DEV,	NULL,	NULL,	0666 },
	};
	kstat_t *ksp;

	mutex_init(&mm_lock, NULL, MUTEX_DEFAULT, NULL);
	mm_map = vmem_alloc(heap_arena, PAGESIZE, VM_SLEEP);

	for (i = 0; i < (sizeof (mm) / sizeof (mm[0])); i++) {
		if (ddi_create_priv_minor_node(devi, mm[i].name, S_IFCHR,
		    mm[i].minor, DDI_PSEUDO, mm[i].privonly,
		    mm[i].rdpriv, mm[i].wrpriv, mm[i].priv_mode) ==
		    DDI_FAILURE) {
			ddi_remove_minor_node(devi, NULL);
			return (DDI_FAILURE);
		}
	}

	mm_dip = devi;

	ksp = kstat_create("mm", 0, "phys_installed", "misc",
	    KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VAR_SIZE | KSTAT_FLAG_VIRTUAL);
	if (ksp != NULL) {
		ksp->ks_update = mm_kstat_update;
		ksp->ks_snapshot = mm_kstat_snapshot;
		ksp->ks_lock = &mm_lock; /* XXX - not really needed */
		kstat_install(ksp);
	}

	mm_kmem_io_access = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
	    "kmem_io_access", 0);

	return (DDI_SUCCESS);
}
Exemplo n.º 5
0
/* ARGSUSED */
static int
log_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	if (ddi_create_minor_node(devi, "conslog", S_IFCHR,
	    LOG_CONSMIN, DDI_PSEUDO, NULL) == DDI_FAILURE ||
	    ddi_create_minor_node(devi, "log", S_IFCHR,
	    LOG_LOGMIN, DDI_PSEUDO, NULL) == DDI_FAILURE) {
		ddi_remove_minor_node(devi, NULL);
		return (DDI_FAILURE);
	}
	log_devi = devi;
	log_msgid = ddi_getprop(DDI_DEV_T_ANY, log_devi,
	    DDI_PROP_CANSLEEP, "msgid", 1);
	return (DDI_SUCCESS);
}
Exemplo n.º 6
0
/*ARGSUSED*/
static int
pcmem_ctlops(dev_info_t *dip, dev_info_t *rdip,
	ddi_ctl_enum_t ctlop, void *arg, void *result)
{

	char    name[MAXNAMELEN];
	int	techreg, cissp;

	switch (ctlop) {
	case DDI_CTLOPS_REPORTDEV:
		if (rdip == (dev_info_t *)0) {
			return (DDI_FAILURE);
		}
		PCMEM_DEBUG((CE_CONT,
		    "?pcmem_ctlops: %s%d at %s in socket %d\n",
		    ddi_get_name(rdip), ddi_get_instance(rdip),
		    ddi_get_name(dip),
		    ddi_getprop(DDI_DEV_T_NONE, rdip,
			DDI_PROP_DONTPASS, "socket", -1)));

		return (DDI_SUCCESS);

	case DDI_CTLOPS_INITCHILD:

		PCMEM_DEBUG((CE_CONT,
		    "pcmem_ctlops - DDI_CTLOPS_INITCHILD persistent=%x\n",
		    ndi_dev_is_persistent_node((dev_info_t *)arg)));

		if (!ndi_dev_is_persistent_node((dev_info_t *)arg))
			return (DDI_FAILURE);
		/*
		 * XXXX - Read card CIS to determine technology
		 *	region(tn) and CIS space(dn).
		 *	Refer to Bugid 1179336.
		 */

		/*
		 * see cis_handler.h for CISTPL_DEVICE
		 *	and CISTPL_DEVICE_A
		 *
		 * CISTPL_DEVICE_DTYPE_NULL	0x00	NULL device
		 * CISTPL_DEVICE_DTYPE_ROM	0x01	ROM
		 * CISTPL_DEVICE_DTYPE_OTPROM	0x02	OTPROM
		 * CISTPL_DEVICE_DTYPE_EPROM	0x03    EPROM
		 * CISTPL_DEVICE_DTYPE_EEPROM	0x04	EEPROM
		 * CISTPL_DEVICE_DTYPE_FLASH	0x05	FLASH
		 * CISTPL_DEVICE_DTYPE_SRAM	0x06	SRAM
		 * CISTPL_DEVICE_DTYPE_DRAM	0x07	DRAM
		 *
		 */
		/*
		 * XXXX - For now set to default SRAM device
		 */
		techreg = CISTPL_DEVICE_DTYPE_SRAM;
		cissp = 0;
		(void) sprintf(name, "%d,%d", techreg, cissp);
		ddi_set_name_addr((dev_info_t *)arg, name);

		PCMEM_DEBUG((CE_CONT,
		    "pcmem_ctlops - DDI_CTLOPS_INITCHILD name=%s\n", name));

		return (DDI_SUCCESS);

	case DDI_CTLOPS_UNINITCHILD:
		ddi_set_name_addr((dev_info_t *)arg, NULL);

		PCMEM_DEBUG((CE_CONT,
		    "pcmem_ctlops - DDI_CTLOPS_UNINITCHILD child: %s(%d)\n",
		    ddi_node_name(arg), ddi_get_instance(arg)));

		return (DDI_SUCCESS);

	default:
		return (ddi_ctlops(dip, rdip, ctlop, arg, result));
	}
}
Exemplo n.º 7
0
/*ARGSUSED*/
gtgt_t *
ghd_target_init(dev_info_t	*hba_dip,
		dev_info_t	*tgt_dip,
		ccc_t		*cccp,
		size_t		 tgt_private_size,
		void		*hba_private,
		ushort_t	 target,
		uchar_t		 lun)
{
	_NOTE(ARGUNUSED(hba_dip))
	gtgt_t	*gtgtp;
	size_t	 size = sizeof (*gtgtp) + tgt_private_size;
	gdev_t	*gdevp;
	ulong_t	 maxactive;

	gtgtp = kmem_zalloc(size, KM_SLEEP);

	/*
	 * initialize the per instance structure
	 */

	gtgtp->gt_tgt_private = (void *)(gtgtp + 1);
	gtgtp->gt_size = size;
	gtgtp->gt_hba_private = hba_private;
	gtgtp->gt_target = target;
	gtgtp->gt_lun = lun;
	gtgtp->gt_ccc = cccp;

	/*
	 * set the queue's maxactive to 1 if
	 * property not specified on target or hba devinfo node
	 */
	maxactive = ddi_getprop(DDI_DEV_T_ANY, tgt_dip, 0, "ghd-maxactive", 1);
	gtgtp->gt_maxactive = maxactive;

	/* initialize the linked list pointers */
	GTGT_INIT(gtgtp);

	/*
	 * grab both mutexes so the queue structures
	 * stay stable while adding this instance to the linked lists
	 */
	mutex_enter(&cccp->ccc_hba_mutex);
	mutex_enter(&cccp->ccc_waitq_mutex);

	/*
	 * Search the HBA's linked list of device structures.
	 *
	 * If this device is already attached then link this instance
	 * to the existing per-device-structure on the ccc_devs list.
	 *
	 */
	gdevp = CCCP2GDEVP(cccp);
	while (gdevp != NULL) {
		if (gdevp->gd_target == target && gdevp->gd_lun == lun) {
			GDBG_WAITQ(("ghd_target_init(%d,%d) found gdevp 0x%p"
				" gtgtp 0x%p max %lu\n",
					target, lun, gdevp, gtgtp, maxactive));

			goto foundit;
		}
		gdevp = GDEV_NEXTP(gdevp);
	}

	/*
	 * Not found. This is the first instance for this device.
	 */


	/* allocate the per-device-structure */

	gdevp = kmem_zalloc(sizeof (*gdevp), KM_SLEEP);
	gdevp->gd_target = target;
	gdevp->gd_lun = lun;

	/*
	 * link this second level queue to the HBA's first
	 * level queue
	 */
	GDEV_QATTACH(gdevp, cccp, maxactive);

	GDBG_WAITQ(("ghd_target_init(%d,%d) new gdevp 0x%p gtgtp 0x%p"
		    " max %lu\n", target, lun, gdevp, gtgtp, maxactive));

foundit:

	/* save the ptr to the per device structure */
	gtgtp->gt_gdevp = gdevp;

	/* Add the per instance structure to the per device list  */
	GTGT_ATTACH(gtgtp, gdevp);

	ghd_waitq_process_and_mutex_exit(cccp);

	return (gtgtp);
}
Exemplo n.º 8
0
static int
ppb_initchild(dev_info_t *child)
{
	char name[MAXNAMELEN];
	ddi_acc_handle_t config_handle;
	ushort_t command_preserve, command;
	uint_t n;
	ushort_t bcr;
	uchar_t header_type;
	uchar_t min_gnt, latency_timer;
	ppb_devstate_t *ppb;

	/*
	 * Name the child
	 */
	if (ppb_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
		return (DDI_FAILURE);

	ddi_set_name_addr(child, name);
	ddi_set_parent_data(child, NULL);

	/*
	 * Pseudo nodes indicate a prototype node with per-instance
	 * properties to be merged into the real h/w device node.
	 * The interpretation of the unit-address is DD[,F]
	 * where DD is the device id and F is the function.
	 */
	if (ndi_dev_is_persistent_node(child) == 0) {
		extern int pci_allow_pseudo_children;

		/*
		 * Try to merge the properties from this prototype
		 * node into real h/w nodes.
		 */
		if (ndi_merge_node(child, ppb_name_child) == DDI_SUCCESS) {
			/*
			 * Merged ok - return failure to remove the node.
			 */
			ppb_removechild(child);
			return (DDI_FAILURE);
		}

		/* workaround for ddivs to run under PCI */
		if (pci_allow_pseudo_children)
			return (DDI_SUCCESS);

		/*
		 * The child was not merged into a h/w node,
		 * but there's not much we can do with it other
		 * than return failure to cause the node to be removed.
		 */
		cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
		    ddi_driver_name(child), ddi_get_name_addr(child),
		    ddi_driver_name(child));
		ppb_removechild(child);
		return (DDI_NOT_WELL_FORMED);
	}

	ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
	    ddi_get_instance(ddi_get_parent(child)));

	ddi_set_parent_data(child, NULL);

	/*
	 * If hardware is PM capable, set up the power info structure.
	 * This also ensures the the bus will not be off (0MHz) otherwise
	 * system panics during a bus access.
	 */
	if (PM_CAPABLE(ppb->ppb_pwr_p)) {
		/*
		 * Create a pwr_info struct for child.  Bus will be
		 * at full speed after creating info.
		 */
		pci_pwr_create_info(ppb->ppb_pwr_p, child);
#ifdef DEBUG
		ASSERT(ppb->ppb_pwr_p->current_lvl == PM_LEVEL_B0);
#endif
	}

	/*
	 * If configuration registers were previously saved by
	 * child (before it entered D3), then let the child do the
	 * restore to set up the config regs as it'll first need to
	 * power the device out of D3.
	 */
	if (ddi_prop_exists(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
	    "config-regs-saved-by-child") == 1) {
		DEBUG2(DBG_PWR, ddi_get_parent(child),
		    "INITCHILD: config regs to be restored by child"
		    " for %s@%s\n", ddi_node_name(child),
		    ddi_get_name_addr(child));

		return (DDI_SUCCESS);
	}

	DEBUG2(DBG_PWR, ddi_get_parent(child),
	    "INITCHILD: config regs setup for %s@%s\n",
	    ddi_node_name(child), ddi_get_name_addr(child));

	if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) {
		if (PM_CAPABLE(ppb->ppb_pwr_p)) {
			pci_pwr_rm_info(ppb->ppb_pwr_p, child);
		}

		return (DDI_FAILURE);
	}

	/*
	 * Determine the configuration header type.
	 */
	header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);

	/*
	 * Support for the "command-preserve" property.
	 */
	command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
	    DDI_PROP_DONTPASS, "command-preserve", 0);
	command = pci_config_get16(config_handle, PCI_CONF_COMM);
	command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
	command |= (ppb_command_default & ~command_preserve);
	pci_config_put16(config_handle, PCI_CONF_COMM, command);

	/*
	 * If the device has a bus control register then program it
	 * based on the settings in the command register.
	 */
	if ((header_type  & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
		bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL);
		if (ppb_command_default & PCI_COMM_PARITY_DETECT)
			bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
		if (ppb_command_default & PCI_COMM_SERR_ENABLE)
			bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE;
		bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE;
		pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr);
	}

	/*
	 * Initialize cache-line-size configuration register if needed.
	 */
	if (ppb_set_cache_line_size_register &&
	    ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
	    "cache-line-size", 0) == 0) {
		pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ,
		    ppb->ppb_cache_line_size);
		n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
		if (n != 0) {
			(void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
			    "cache-line-size", n);
		}
	}

	/*
	 * Initialize latency timer configuration registers if needed.
	 */
	if (ppb_set_latency_timer_register &&
	    ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
	    "latency-timer", 0) == 0) {

		if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
			latency_timer = ppb->ppb_latency_timer;
			pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER,
			    ppb->ppb_latency_timer);
		} else {
			min_gnt = pci_config_get8(config_handle,
			    PCI_CONF_MIN_G);
			latency_timer = min_gnt * 8;
		}
		pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER,
		    latency_timer);
		n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
		if (n != 0) {
			(void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
			    "latency-timer", n);
		}
	}

	/*
	 * SPARC PCIe FMA specific
	 *
	 * Note: parent_data for parent is created only if this is sparc PCI-E
	 * platform, for which, SG take a different route to handle device
	 * errors.
	 */
	if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
		if (pcie_init_cfghdl(child) != DDI_SUCCESS) {
			pci_config_teardown(&config_handle);
			return (DDI_FAILURE);
		}
		pcie_init_dom(child);
	}

	/*
	 * Check to see if the XMITS/PCI-X workaround applies.
	 */
	n = ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_NOTPROM,
	    "pcix-update-cmd-reg", -1);

	if (n != -1) {
		extern void pcix_set_cmd_reg(dev_info_t *child, uint16_t value);
		DEBUG1(DBG_INIT_CLD, child, "Turning on XMITS NCPQ "
		    "Workaround: value = %x\n", n);
		pcix_set_cmd_reg(child, n);
	}
	pci_config_teardown(&config_handle);
	return (DDI_SUCCESS);
}
Exemplo n.º 9
0
static int
sbmem_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	struct sbusmem_unit *un;
	int error = DDI_FAILURE;
	int instance, ilen;
	uint_t size;
	char *ident;

	switch (cmd) {
	case DDI_ATTACH:
		instance = ddi_get_instance(devi);

		size = ddi_getprop(DDI_DEV_T_NONE, devi,
		    DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "size", -1);
		if (size == (uint_t)-1) {
#ifdef SBUSMEM_DEBUG
			sbusmem_debug(
			    "sbmem_attach%d: No size property\n", instance);
#endif /* SBUSMEM_DEBUG */
			break;
		}

#ifdef SBUSMEM_DEBUG
		{
			struct regspec *rp = ddi_rnumber_to_regspec(devi, 0);

			if (rp == NULL) {
				sbusmem_debug(
			    "sbmem_attach%d: No reg property\n", instance);
			} else {
				sbusmem_debug(
			    "sbmem_attach%d: slot 0x%x size 0x%x\n", instance,
				    rp->regspec_bustype, rp->regspec_size);
			}
		}
#endif /* SBUSMEM_DEBUG */

		if (ddi_getlongprop(DDI_DEV_T_ANY, devi,
		    DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "ident",
		    (caddr_t)&ident, &ilen) != DDI_PROP_SUCCESS) {
#ifdef SBUSMEM_DEBUG
			sbusmem_debug(
			    "sbmem_attach%d: No ident property\n", instance);
#endif /* SBUSMEM_DEBUG */
			break;
		}

		if (ddi_soft_state_zalloc(sbusmem_state_head,
		    instance) != DDI_SUCCESS)
			break;

		if ((un = ddi_get_soft_state(sbusmem_state_head,
		    instance)) == NULL) {
			ddi_soft_state_free(sbusmem_state_head, instance);
			break;
		}

		if (ddi_create_minor_node(devi, ident, S_IFCHR, instance,
		    DDI_PSEUDO, NULL) == DDI_FAILURE) {
			kmem_free(ident, ilen);
			ddi_remove_minor_node(devi, NULL);
			ddi_soft_state_free(sbusmem_state_head, instance);
			break;
		}
		kmem_free(ident, ilen);
		un->dip = devi;
		un->size = size;
		un->pagesize = ddi_ptob(devi, 1);

#ifdef SBUSMEM_DEBUG
		sbusmem_debug("sbmem_attach%d: dip 0x%p size 0x%x\n",
		    instance, devi, size);
#endif /* SBUSMEM_DEBUG */

		ddi_report_dev(devi);
		error = DDI_SUCCESS;
		break;
	case DDI_RESUME:
		error = DDI_SUCCESS;
		break;
	default:
		break;
	}
	return (error);
}
Exemplo n.º 10
0
/*
 * attach(9E) -- Attach a device to the system
 *
 * Called once for each board successfully probed.
 */
static int
SMCG_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
{
	gld_mac_info_t	*macinfo;
	Adapter_Struc	*pAd;
	smcg_t		*smcg;
	int		rc;
	ddi_acc_handle_t pcihandle;

#ifdef	DEBUG
	if (SMCG_debug & SMCGDDI)
		cmn_err(CE_CONT, SMCG_NAME "_attach(0x%p)", (void *)devinfo);
#endif

	if (cmd != DDI_ATTACH)
		return (DDI_FAILURE);

	/*
	 * Allocate gld_mac_info_t and Lower MAC Adapter_Struc structures
	 */
	if ((macinfo = gld_mac_alloc(devinfo)) == NULL)
		return (DDI_FAILURE);
	if ((pAd = kmem_zalloc(sizeof (Adapter_Struc), KM_NOSLEEP)) == NULL) {
		gld_mac_free(macinfo);
		return (DDI_FAILURE);
	}
	if ((smcg = kmem_zalloc(sizeof (smcg_t), KM_NOSLEEP)) == NULL) {
		gld_mac_free(macinfo);
		kmem_free(pAd, sizeof (Adapter_Struc));
		return (DDI_FAILURE);
	}

	pAd->pc_bus = SMCG_PCI_BUS;

	/* create pci handle for UM_PCI_Service */
	if (pci_config_setup(devinfo, (ddi_acc_handle_t *)&pcihandle)
	    != DDI_SUCCESS) {
		goto attach_fail_cleanup;
	}

	/*
	 * Query the LMAC for the device information
	 */
	pAd->pcihandle = (void *) pcihandle;
	rc = LM_GetCnfg(pAd);

	pci_config_teardown((ddi_acc_handle_t *)&pcihandle);
	pAd->pcihandle = NULL;

	if (rc != ADAPTER_AND_CONFIG) {
		cmn_err(CE_WARN,
		    SMCG_NAME "_attach: LM_GetCnfg failed (0x%x)", rc);
		goto attach_fail_cleanup;
	}

	/*
	 * Initialize pointers to device specific functions which will be
	 * used by the generic layer.
	 */
	macinfo->gldm_reset   = SMCG_reset;
	macinfo->gldm_start   = SMCG_start_board;
	macinfo->gldm_stop    = SMCG_stop_board;
	macinfo->gldm_set_mac_addr   = SMCG_set_mac_addr;
	macinfo->gldm_set_multicast = SMCG_set_multicast;
	macinfo->gldm_set_promiscuous = SMCG_set_promiscuous;
	macinfo->gldm_get_stats   = SMCG_get_stats;
	macinfo->gldm_send    = SMCG_send;
	macinfo->gldm_intr    = SMCG_intr;
	macinfo->gldm_ioctl   = NULL;

	/*
	 * Initialize board characteristics needed by the generic layer.
	 */
	macinfo->gldm_ident = SMCG_IDENT;
	macinfo->gldm_type = DL_ETHER;
	macinfo->gldm_minpkt = 0;	/* assumes we pad ourselves */
	macinfo->gldm_maxpkt = SMCGMAXPKT;
	macinfo->gldm_addrlen = ETHERADDRL;
	macinfo->gldm_saplen = -2;
	macinfo->gldm_ppa = ddi_get_instance(devinfo);

	pAd->receive_mask = ACCEPT_BROADCAST;
	pAd->max_packet_size = SMMAXPKT;

	macinfo->gldm_broadcast_addr = SMCG_broadcastaddr;

	/* Get the board's vendor-assigned hardware network address. */
	LM_Get_Addr(pAd);
	macinfo->gldm_vendor_addr = (unsigned char *)pAd->node_address;

	/* Link macinfo, smcg, and LMAC Adapter Structs */
	macinfo->gldm_private = (caddr_t)smcg;
	pAd->sm_private = (void *)smcg;
	smcg->smcg_pAd = pAd;
	smcg->smcg_macinfo = macinfo;

	pAd->ptr_rx_CRC_errors = &smcg->rx_CRC_errors;
	pAd->ptr_rx_too_big = &smcg->rx_too_big;
	pAd->ptr_rx_lost_pkts = &smcg->rx_lost_pkts;
	pAd->ptr_rx_align_errors = &smcg->rx_align_errors;
	pAd->ptr_rx_overruns = &smcg->rx_overruns;
	pAd->ptr_tx_deferred = &smcg->tx_deferred;
	pAd->ptr_tx_total_collisions = &smcg->tx_total_collisions;
	pAd->ptr_tx_max_collisions = &smcg->tx_max_collisions;
	pAd->ptr_tx_one_collision = &smcg->tx_one_collision;
	pAd->ptr_tx_mult_collisions = &smcg->tx_mult_collisions;
	pAd->ptr_tx_ow_collision = &smcg->tx_ow_collision;
	pAd->ptr_tx_CD_heartbeat = &smcg->tx_CD_heartbeat;
	pAd->ptr_tx_carrier_lost = &smcg->tx_carrier_lost;
	pAd->ptr_tx_underruns = &smcg->tx_underruns;
	pAd->ptr_ring_OVW = &smcg->ring_OVW;

	macinfo->gldm_devinfo = smcg->smcg_devinfo = devinfo;

	pAd->num_of_tx_buffs = ddi_getprop(DDI_DEV_T_ANY, devinfo,
	    DDI_PROP_DONTPASS, "num-tx-bufs", SMTRANSMIT_BUFS);
	if (pAd->num_of_tx_buffs > SMCG_MAX_TXDESCS) {
		pAd->num_of_tx_buffs = SMCG_MAX_TXDESCS;
		cmn_err(CE_WARN, SMCG_NAME
		    "Max number_of_tx_buffs is %d", SMCG_MAX_TXDESCS);
	}
	if (pAd->num_of_tx_buffs < 2) {
		pAd->num_of_tx_buffs = 2;
	}
	pAd->num_of_rx_buffs = ddi_getprop(DDI_DEV_T_ANY, devinfo,
	    DDI_PROP_DONTPASS, "num-rx-bufs", SMRECEIVE_BUFS);
	if (pAd->num_of_rx_buffs > SMCG_MAX_RXDESCS) {
		pAd->num_of_rx_buffs = SMCG_MAX_RXDESCS;
		cmn_err(CE_WARN, SMCG_NAME
		    "Max number_of_rx_buffs is %d", SMCG_MAX_RXDESCS);
	}
	if (pAd->num_of_rx_buffs < 2) {
		pAd->num_of_rx_buffs = 2;
	}

	if (ddi_get_iblock_cookie(devinfo, 0, &macinfo->gldm_cookie)
		!= DDI_SUCCESS)
		goto attach_fail_cleanup;

	/*
	 * rbuf_lock	Protects receive data structures
	 * txbuf_lock	Protects transmit data structures
	 * lm_lock	Protects all calls to LMAC layer
	 * rlist_lock	Protects receive buffer list
	 * Note: Locks should be acquired in the above order.
	 */
	mutex_init(&smcg->rbuf_lock, NULL, MUTEX_DRIVER, NULL);
	mutex_init(&smcg->txbuf_lock, NULL, MUTEX_DRIVER, NULL);
	mutex_init(&smcg->lm_lock, NULL, MUTEX_DRIVER, NULL);
	mutex_init(&smcg->rlist_lock, NULL, MUTEX_DRIVER, NULL);

	/*
	 * SMCG_dma_alloc is called before it is possible to get
	 * any interrupts, send or receive packets... Therefore I'm
	 * not going to take rlist_lock for it.
	 */
	if (SMCG_dma_alloc(smcg) != DDI_SUCCESS)
		goto attach_fail_cleanup1;

#ifdef SAFE
	LM_Reset_Adapter(pAd);
#endif
	/* Add the interrupt handler */
	if (ddi_add_intr(devinfo, 0,  NULL, NULL, gld_intr, (caddr_t)macinfo)
	    != DDI_SUCCESS) {
		SMCG_dma_unalloc(smcg);
		goto attach_fail_cleanup1;
	}

	/*
	 * Register ourselves with the GLD interface
	 *
	 * gld_register will:
	 *	link us with the GLD system;
	 *	create the minor node.
	 */
	if (gld_register(devinfo, SMCG_NAME, macinfo) != DDI_SUCCESS) {
		ddi_remove_intr(devinfo, 0, macinfo->gldm_cookie);
		SMCG_dma_unalloc(smcg);
		goto attach_fail_cleanup1;
	}

	return (DDI_SUCCESS);

attach_fail_cleanup1:
	mutex_destroy(&smcg->rbuf_lock);
	mutex_destroy(&smcg->txbuf_lock);
	mutex_destroy(&smcg->lm_lock);
	mutex_destroy(&smcg->rlist_lock);

attach_fail_cleanup:
	kmem_free(pAd, sizeof (Adapter_Struc));
	kmem_free(smcg, sizeof (smcg_t));
	gld_mac_free(macinfo);
	return (DDI_FAILURE);
}
Exemplo n.º 11
0
static int
ppb_initchild(dev_info_t *child)
{
	struct ddi_parent_private_data *pdptr;
	ppb_devstate_t *ppb;
	char name[MAXNAMELEN];
	ddi_acc_handle_t config_handle;
	ushort_t command_preserve, command;

	ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
	    ddi_get_instance(ddi_get_parent(child)));

	if (ppb_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
		return (DDI_FAILURE);
	ddi_set_name_addr(child, name);

	/*
	 * Pseudo nodes indicate a prototype node with per-instance
	 * properties to be merged into the real h/w device node.
	 * The interpretation of the unit-address is DD[,F]
	 * where DD is the device id and F is the function.
	 */
	if (ndi_dev_is_persistent_node(child) == 0) {
		extern int pci_allow_pseudo_children;

		ddi_set_parent_data(child, NULL);

		/*
		 * Try to merge the properties from this prototype
		 * node into real h/w nodes.
		 */
		if (ndi_merge_node(child, ppb_name_child) == DDI_SUCCESS) {
			/*
			 * Merged ok - return failure to remove the node.
			 */
			ddi_set_name_addr(child, NULL);
			return (DDI_FAILURE);
		}

		/* workaround for ddivs to run under PCI */
		if (pci_allow_pseudo_children)
			return (DDI_SUCCESS);

		/*
		 * The child was not merged into a h/w node,
		 * but there's not much we can do with it other
		 * than return failure to cause the node to be removed.
		 */
		cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
		    ddi_driver_name(child), ddi_get_name_addr(child),
		    ddi_driver_name(child));
		ddi_set_name_addr(child, NULL);
		return (DDI_NOT_WELL_FORMED);
	}

	ddi_set_parent_data(child, NULL);

	/*
	 * PCIe FMA specific
	 *
	 * Note: parent_data for parent is created only if this is PCI-E
	 * platform, for which, SG take a different route to handle device
	 * errors.
	 */
	if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
		if (pcie_init_cfghdl(child) != DDI_SUCCESS)
			return (DDI_FAILURE);
		pcie_init_dom(child);
	}

	/* transfer select properties from PROM to kernel */
	if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS,
	    "interrupts", -1) != -1) {
		pdptr = kmem_zalloc((sizeof (struct ddi_parent_private_data) +
		    sizeof (struct intrspec)), KM_SLEEP);
		pdptr->par_intr = (struct intrspec *)(pdptr + 1);
		pdptr->par_nintr = 1;
		ddi_set_parent_data(child, pdptr);
	} else
		ddi_set_parent_data(child, NULL);

	if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) {
		pcie_fini_dom(child);
		return (DDI_FAILURE);
	}

	/*
	 * Support for the "command-preserve" property.
	 */
	command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
	    DDI_PROP_DONTPASS, "command-preserve", 0);
	command = pci_config_get16(config_handle, PCI_CONF_COMM);
	command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
	command |= (ppb_command_default & ~command_preserve);
	pci_config_put16(config_handle, PCI_CONF_COMM, command);

	pci_config_teardown(&config_handle);
	return (DDI_SUCCESS);
}
Exemplo n.º 12
0
static int
logiinit(dev_info_t *dip)
{
	int	i;
	int	ioaddr;
	int	len;
	int	old_probe;

#ifdef LOGI_DEBUG
	if (logi_debug)
		PRF("logiinit: call BASE_IOA = %x\n", BASE_IOA);
#endif
	old_probe = ddi_getprop(DDI_DEV_T_ANY, dip, 0,
		"ignore-hardware-nodes", 0);

	if (old_probe) {
		len = sizeof (int);

		/*
		 * check if ioaddr is set in .conf file, it should be.  If it
		 * isn't then try the default i/o addr
		 */
		if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
		    DDI_PROP_DONTPASS, "ioaddr", (caddr_t)&ioaddr,
		    &len) == DDI_PROP_SUCCESS)
			BASE_IOA = ioaddr;
	} else {
		int reglen, nregs;
		int i;
		struct {
			int bustype;
			int base;
			int size;
		} *reglist;

		/* new probe */
		if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
		    "reg", (caddr_t)&reglist, &reglen) != DDI_PROP_SUCCESS)
			return (DDI_PROBE_FAILURE);
		nregs = reglen / sizeof (*reglist);
		for (i = 0; i < nregs; i++)
			if (reglist[i].bustype == 1) {
				ioaddr = reglist[i].base;
				BASE_IOA = ioaddr;
				break;
			}
		kmem_free(reglist, reglen);
	}
#ifdef LOGI_DEBUG
	if (logi_debug)
		PRF("logiinit: call BASE_IOA = %x\n", BASE_IOA);
#endif
	mse_config.present = 0;
	/* Check if the mouse board exists */
	outb(CONFIGURATOR_PORT, 0x91);
	drv_usecwait(10);
	outb(SIGNATURE_PORT, 0xC);
	drv_usecwait(10);
	i = inb(SIGNATURE_PORT);
	drv_usecwait(10);
	outb(SIGNATURE_PORT, 0x50);
	drv_usecwait(10);
	if (i == 0xC && ((inb(SIGNATURE_PORT)) == 0x50)) {
		mse_config.present = 1;
#ifdef LOGI_DEBUG
	if (logi_debug)
		printf("logiinit:Disable interrupts ioaddr %x\n", BASE_IOA);
#endif
		control_port(INTR_DISABLE);	/* Disable interrupts */
#ifdef LOGI_DEBUG
	if (logi_debug)
		PRF("logiinit: succeeded\n");
#endif
		return (DDI_SUCCESS);
	} else {
#ifdef LOGI_DEBUG
	if (logi_debug)
		PRF("logiinit: failed\n");
#endif
		return (DDI_PROBE_FAILURE);
	}
}
Exemplo n.º 13
0
static int
simmstat_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
    struct simmstat_soft_state *softsp;
    int instance;

    switch (cmd) {
    case DDI_ATTACH:
        break;

    case DDI_RESUME:
        return (DDI_SUCCESS);

    default:
        return (DDI_FAILURE);
    }

    instance = ddi_get_instance(devi);

    if (ddi_soft_state_zalloc(simmstatp, instance) != DDI_SUCCESS)
        return (DDI_FAILURE);

    softsp = ddi_get_soft_state(simmstatp, instance);

    /* Set the dip in the soft state */
    softsp->dip = devi;

    /* Get the board number from this nodes parent device. */
    softsp->pdip = ddi_get_parent(softsp->dip);
    if ((softsp->board = (int)ddi_getprop(DDI_DEV_T_ANY, softsp->pdip,
                                          DDI_PROP_DONTPASS, OBP_BOARDNUM, -1)) == -1) {
        cmn_err(CE_WARN, "simmstat%d: unable to retrieve %s property",
                instance, OBP_BOARDNUM);
        goto bad;
    }

    DPRINTF(SIMMSTAT_ATTACH_DEBUG, ("simmstat%d: devi= 0x%p\n, "
                                    " softsp=0x%p\n", instance, (void *)devi, (void *)softsp));

    /* map in the registers for this device. */
    if (ddi_map_regs(softsp->dip, 0,
                     (caddr_t *)&softsp->simmstat_base, 0, 0)) {
        cmn_err(CE_WARN, "simmstat%d: unable to map registers",
                instance);
        goto bad;
    }

    /* nothing to suspend/resume here */
    (void) ddi_prop_update_string(DDI_DEV_T_NONE, devi,
                                  "pm-hardware-state", "no-suspend-resume");

    /* create the kstats for this device */
    simmstat_add_kstats(softsp);

    ddi_report_dev(devi);

    return (DDI_SUCCESS);

bad:
    ddi_soft_state_free(simmstatp, instance);
    return (DDI_FAILURE);
}
Exemplo n.º 14
0
int
mii_init_phy(mii_handle_t mac, int phy)
{
	ushort_t status;
	void *dip;
	struct phydata *phydata;

	if ((mac == (mii_handle_t)NULL) || phy < 0 || phy > 31)
		return (MII_PARAM);

	dip = mac->mii_dip;

	/* Create a phydata structure for this new phy */
	if (mac->phys[phy])
		return (MII_PHYPRESENT);

	mac->phys[phy] = phydata = (struct phydata *)
	    kmem_zalloc(sizeof (struct phydata), KM_NOSLEEP);

	if (!phydata)
		return (MII_NOMEM);

	phydata->id = (ulong_t)mac->mii_read(dip, phy, MII_PHYIDH) << 16;
	phydata->id |= (ulong_t)mac->mii_read(dip, phy, MII_PHYIDL);
	phydata->state = phy_state_unknown;

	/* Override speed and duplex mode from conf-file if present */
	phydata->fix_duplex =
	    ddi_getprop(DDI_DEV_T_NONE,
	    mac->mii_dip, DDI_PROP_DONTPASS, "full-duplex", 0);

	phydata->fix_speed =
	    ddi_getprop(DDI_DEV_T_NONE,
	    mac->mii_dip, DDI_PROP_DONTPASS, "speed", 0);

	status = mac->mii_read(dip, phy, MII_STATUS);

	/*
	 * when explicitly setting speed or duplex, we must
	 * disable autonegotiation
	 */
	if (!(status & MII_STATUS_CANAUTONEG) ||
	    phydata->fix_speed || phydata->fix_duplex) {
		/*
		 * If local side cannot autonegotiate, we can't try to enable
		 * full duplex without the user's consent, because we cannot
		 * tell without AN if the partner can support it
		 */
		if ((status & (MII_STATUS_100_BASEX | MII_STATUS_100_BASEX_FD |
		    MII_STATUS_100_BASE_T4)) && phydata->fix_speed == 0) {
			phydata->fix_speed = 100;
		} else if ((status & (MII_STATUS_10 | MII_STATUS_10_FD)) &&
		    phydata->fix_speed == 0) {
			phydata->fix_speed = 10;
		} else if (phydata->fix_speed == 0) {
			/* A very stupid PHY would not be supported */
			kmem_free(mac->phys[phy], sizeof (struct phydata));
			mac->phys[phy] = NULL;
			return (MII_NOTSUPPORTED);
		}
		/* mii_sync will sort out the speed selection on the PHY */
	} else
		phydata->control = MII_CONTROL_ANE;

	switch (MII_PHY_MFG(phydata->id)) {
	case OUI_NATIONAL_SEMICONDUCTOR:
		switch (MII_PHY_MODEL(phydata->id)) {
		case NS_DP83840:
			phydata->phy_postreset = postreset_NS83840;
			phydata->phy_dump = dump_NS83840;
			phydata->description =
			    "National Semiconductor DP-83840";
			phydata->phy_getspeed = getspeed_NS83840;
			break;
		default:
			phydata->description = "Unknown NS";
			break;
		}
		break;

	case OUI_INTEL:
		switch (MII_PHY_MODEL(phydata->id)) {
		case INTEL_82553_CSTEP:
			phydata->description = "Intel 82553 C-step";
			phydata->phy_getspeed = getspeed_82553;
			break;
		case INTEL_82555:
			phydata->description = "Intel 82555";
			phydata->phy_getspeed = getspeed_82553;
			break;
		case INTEL_82562_EH:
			phydata->description = "Intel 82562 EH";
			phydata->phy_getspeed = getspeed_82553;
			break;
		case INTEL_82562_ET:
			phydata->description = "Intel 82562 ET";
			phydata->phy_getspeed = getspeed_82553;
			break;
		case INTEL_82562_EM:
			phydata->description = "Intel 82562 EM";
			phydata->phy_getspeed = getspeed_82553;
			break;
		default:
			phydata->description = "Unknown INTEL";
			break;
		}
		break;

	case OUI_ICS:
		switch (MII_PHY_MODEL(phydata->id)) {
		case ICS_1890:
		case ICS_1889:
			phydata->phy_postreset = postreset_ICS1890;
			phydata->description = "ICS 1890/1889 PHY";
			phydata->phy_getspeed = getspeed_ICS1890;
			phydata->phy_dump = dump_ICS1890;
			break;
		default:
			phydata->description = "ICS Unknown PHY";
			break;
		}
		break;

	default: /* Non-standard PHYs, that encode weird IDs */
		phydata->description = "Unknown PHY";
		phydata->phy_dump = NULL;
		phydata->phy_getspeed = getspeed_generic;
		break;
	}

	/* Do all post-reset hacks and user settings */
	(void) mii_sync(mac, phy);

	if (ddi_getprop(DDI_DEV_T_NONE, mac->mii_dip, DDI_PROP_DONTPASS,
	    "dump-phy", 0))
		(void) mii_dump_phy(mac, phy);

	return (MII_SUCCESS);
}