Exemple #1
0
/*ARGSUSED*/
static int
smb_open(dev_t *dp, int flag, int otyp, cred_t *cred)
{
	minor_t c;

	if (ksmbios == NULL)
		return (ENXIO);

	/*
	 * Locate and reserve a clone structure.  We skip clone 0 as that is
	 * the real minor number, and we assign a new minor to each clone.
	 */
	for (c = 1; c < smb_nclones; c++) {
		if (casptr(&smb_clones[c].c_hdl, NULL, ksmbios) == NULL)
			break;
	}

	if (c >= smb_nclones)
		return (EAGAIN);

	smb_clones[c].c_eplen = P2ROUNDUP(sizeof (smbios_entry_t), 16);
	smb_clones[c].c_stlen = smbios_buflen(smb_clones[c].c_hdl);

	*dp = makedevice(getemajor(*dp), c);

	(void) ddi_prop_update_int(*dp, smb_devi, "size",
	    smb_clones[c].c_eplen + smb_clones[c].c_stlen);

	return (0);
}
/* ARGSUSED3 */
int
ip_helper_stream_setup(queue_t *q, dev_t *devp, int flag, int sflag,
    cred_t *credp, boolean_t isv6)
{
	major_t			maj;
	ip_helper_minfo_t	*ip_minfop;

	ASSERT((flag & ~(FKLYR)) == IP_HELPER_STR);

	ASSERT(RD(q) == q);

	ip_minfop = kmem_alloc(sizeof (ip_helper_minfo_t), KM_SLEEP);
	ASSERT(ip_minfop != NULL);

	ip_minfop->ip_minfo_dev = 0;
	ip_minfop->ip_minfo_arena = NULL;

	/*
	 * Clone the device, allocate minor device number
	 */
	if (ip_minor_arena_la != NULL)
		ip_minfop->ip_minfo_dev = inet_minor_alloc(ip_minor_arena_la);

	if (ip_minfop->ip_minfo_dev == 0) {
		/*
		 * numbers in the large arena are exhausted
		 * Try small arena.
		 * Or this is a 32 bit system, 32 bit systems do not have
		 * ip_minor_arena_la
		 */
		ip_minfop->ip_minfo_dev = inet_minor_alloc(ip_minor_arena_sa);
		if (ip_minfop->ip_minfo_dev == 0) {
			return (EBUSY);
		}
		ip_minfop->ip_minfo_arena = ip_minor_arena_sa;
	} else {
		ip_minfop->ip_minfo_arena = ip_minor_arena_la;
	}


	ASSERT(ip_minfop->ip_minfo_dev != 0);
	ASSERT(ip_minfop->ip_minfo_arena != NULL);

	RD(q)->q_ptr = WR(q)->q_ptr = ip_minfop;

	maj = getemajor(*devp);
	*devp = makedevice(maj, (ulong_t)(ip_minfop->ip_minfo_dev));

	q->q_qinfo = &ip_helper_stream_rinit;
	WR(q)->q_qinfo = &ip_helper_stream_winit;
	qprocson(q);
	return (0);
}
Exemple #3
0
/* ARGSUSED */
static int
ksyms_open(dev_t *devp, int flag, int otyp, struct cred *cred)
{
	minor_t clone;
	size_t size = 0;
	size_t realsize;
	char *addr;
	void *hptr = NULL;
	ksyms_buflist_hdr_t hdr;
	bzero(&hdr, sizeof (struct ksyms_buflist_hdr));
	list_create(&hdr.blist, PAGESIZE,
	    offsetof(ksyms_buflist_t, buflist_node));

	if (getminor(*devp) != 0)
		return (ENXIO);

	for (;;) {
		realsize = ksyms_snapshot(ksyms_bcopy, hptr, size);
		if (realsize <= size)
			break;
		size = realsize;
		size = ksyms_buflist_alloc(&hdr, size);
		if (size == 0)
			return (ENOMEM);
		hptr = (void *)&hdr;
	}

	addr = ksyms_mapin(&hdr, realsize);
	ksyms_buflist_free(&hdr);
	if (addr == NULL)
		return (EOVERFLOW);

	/*
	 * Reserve a clone entry.  Note that we don't use clone 0
	 * since that's the "real" minor number.
	 */
	for (clone = 1; clone < nksyms_clones; clone++) {
		if (atomic_cas_ptr(&ksyms_clones[clone].ksyms_base, 0, addr) ==
		    0) {
			ksyms_clones[clone].ksyms_size = realsize;
			*devp = makedevice(getemajor(*devp), clone);
			(void) ddi_prop_update_int(*devp, ksyms_devi,
			    "size", realsize);
			modunload_disable();
			return (0);
		}
	}
	cmn_err(CE_NOTE, "ksyms: too many open references");
	(void) as_unmap(curproc->p_as, addr, roundup(realsize, PAGESIZE));
	return (ENXIO);
}
Exemple #4
0
/* ARGSUSED */
static int
sadopen(
	queue_t *qp,	/* pointer to read queue */
	dev_t *devp,	/* major/minor device of stream */
	int flag,	/* file open flags */
	int sflag,	/* stream open flags */
	cred_t *credp)	/* user credentials */
{
	int i;

	if (sflag)		/* no longer called from clone driver */
		return (EINVAL);

	/*
	 * Both USRMIN and ADMMIN are clone interfaces.
	 */
	for (i = 0; i < sadcnt; i++)
		if (saddev[i].sa_qp == NULL)
			break;
	if (i >= sadcnt)		/* no such device */
		return (ENXIO);

	switch (getminor(*devp)) {
	case USRMIN:			/* mere mortal */
		saddev[i].sa_flags = 0;
		break;

	case ADMMIN:			/* privileged user */
		saddev[i].sa_flags = SADPRIV;
		break;

	default:
		return (EINVAL);
	}

	saddev[i].sa_qp = qp;
	qp->q_ptr = (caddr_t)&saddev[i];
	WR(qp)->q_ptr = (caddr_t)&saddev[i];

	/*
	 * NOTE: should the ADMMIN or USRMIN minors change
	 * then so should the offset of 2 below
	 * Both USRMIN and ADMMIN are clone interfaces and
	 * therefore their minor numbers (0 and 1) are reserved.
	 */
	*devp = makedevice(getemajor(*devp), i + 2);
	qprocson(qp);
	return (0);
}