/*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); }
/* 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); }
/* 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); }