static int m3ua_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp) { m3ua_t *m3ua, **m3p = &m3ua_devices; int cmajor = getmajor(*devp); int cminor = getmajor(*devp); trace(); if (q->q_ptr != NULL) return (0); if (sflag == MODOPEN || WR(q)->q_next) return EIO; if (!cminor) { if (!m3ua_ctrlq) m3ua_ctrlq = q; else sflag = CLONEOPEN; } if (sflag == CLONEOPEN) cminor = 1; for (; cminor <= NMINORS && *m3p; m3p = &(*m3p)->next) { int dminor = getminor((*m3p)->devnum); if (cminor < dminor) break; if (cminor == dminor) { if (sflag == CLONEOPEN) { cminor++; continue; } return EIO; } } if (cminor > M3UA_MINOR) return ENXIO; *devp = makedevice(cmajor, cminor); if (!(m3ua = kmalloc(sizeof(*m3ua), GFP_KERNEL))) return ENOMEM; bzero(m3ua, sizeof(*m3ua)); q->q_ptr = WR(q)->q_ptr; m3ua->rq = RD(q); m3ua->wq = WR(q); m3ua->state = FIXME; m3ua->devnum = *devp; return (0); }
static int vnode_match(vnode_t *v1, vnode_t *v2, cred_t *cr) { vattr_t v1attr, v2attr; /* * If we have a device file, check to see if is a cloned open of the * same device. For self-cloning devices, the major numbers will match. * For devices cloned through the 'clone' driver, the minor number of * the source device will be the same as the major number of the cloned * device. */ if ((v1->v_type == VCHR || v1->v_type == VBLK) && v1->v_type == v2->v_type) { if ((spec_is_selfclone(v1) || spec_is_selfclone(v2)) && getmajor(v1->v_rdev) == getmajor(v2->v_rdev)) return (1); if (spec_is_clone(v1) && getmajor(v1->v_rdev) == getminor(v2->v_rdev)) return (1); if (spec_is_clone(v2) && getmajor(v2->v_rdev) == getminor(v1->v_rdev)) return (1); } v1attr.va_mask = v2attr.va_mask = AT_TYPE; /* * This check for symbolic links handles the pseudo-symlinks in procfs. * These particular links have v_type of VDIR, but the attributes have a * type of VLNK. We need to avoid these links because otherwise if we * are currently in '/proc/self/fd', then '/proc/self/cwd' will compare * as the same vnode. */ if (VOP_GETATTR(v1, &v1attr, 0, cr, NULL) != 0 || VOP_GETATTR(v2, &v2attr, 0, cr, NULL) != 0 || v1attr.va_type == VLNK || v2attr.va_type == VLNK) return (0); v1attr.va_mask = v2attr.va_mask = AT_TYPE | AT_FSID | AT_NODEID; if (VOP_GETATTR(v1, &v1attr, ATTR_REAL, cr, NULL) != 0 || VOP_GETATTR(v2, &v2attr, ATTR_REAL, cr, NULL) != 0) return (0); return (v1attr.va_fsid == v2attr.va_fsid && v1attr.va_nodeid == v2attr.va_nodeid); }
/*ARGSUSED*/ static int ipmi_open(dev_t *devp, int flag, int otyp, cred_t *cred) { minor_t minor; ipmi_device_t *dev; if (ipmi_attached == B_FALSE) return (ENXIO); if (ipmi_found == B_FALSE) return (ENODEV); /* exclusive opens are not supported */ if (flag & FEXCL) return (ENOTSUP); if ((minor = (minor_t)id_alloc_nosleep(minor_ids)) == 0) return (ENODEV); /* Initialize the per file descriptor data. */ dev = kmem_zalloc(sizeof (ipmi_device_t), KM_SLEEP); dev->ipmi_pollhead = kmem_zalloc(sizeof (pollhead_t), KM_SLEEP); TAILQ_INIT(&dev->ipmi_completed_requests); dev->ipmi_address = IPMI_BMC_SLAVE_ADDR; dev->ipmi_lun = IPMI_BMC_SMS_LUN; *devp = makedevice(getmajor(*devp), minor); dev->ipmi_dev = *devp; list_insert_head(&dev_list, dev); return (0); }
/* ARGSUSED1 */ static int dropen(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp) { struct drstate *dsp; if (sflag != MODOPEN) { /* must be a pushed module */ return (EINVAL); } if (secpolicy_net_rawaccess(crp) != 0) { return (EPERM); } if (q->q_ptr != NULL) { return (0); /* already open */ } dsp = kmem_zalloc(sizeof (*dsp), KM_SLEEP); dsp->dr_major = getmajor(*devp); mutex_init(&dsp->dr_lock, NULL, MUTEX_DEFAULT, NULL); q->q_ptr = OTHERQ(q)->q_ptr = dsp; qprocson(q); ddi_assoc_queue_with_devi(q, NULL); return (0); }
/* * Create the "mac" kstat. The "mac" kstat is comprised of three kinds of * statistics: statistics maintained by the mac module itself, generic mac * statistics maintained by the driver, and MAC-type specific statistics * also maintained by the driver. */ void mac_driver_stat_create(mac_impl_t *mip) { kstat_t *ksp; kstat_named_t *knp; uint_t count; major_t major = getmajor(mip->mi_phy_dev); count = MAC_MOD_NKSTAT + MAC_NKSTAT + mip->mi_type->mt_statcount; ksp = kstat_create_zone((const char *)ddi_major_to_name(major), getminor(mip->mi_phy_dev) - 1, MAC_KSTAT_NAME, MAC_KSTAT_CLASS, KSTAT_TYPE_NAMED, count, 0, getzoneid()); if (ksp == NULL) return; ksp->ks_update = i_mac_driver_stat_update; ksp->ks_private = mip; mip->mi_ksp = ksp; mip->mi_kstat_count = count; knp = (kstat_named_t *)ksp->ks_data; i_mac_kstat_init(knp, i_mac_mod_si, MAC_MOD_NKSTAT); knp += MAC_MOD_NKSTAT; i_mac_kstat_init(knp, i_mac_si, MAC_NKSTAT); if (mip->mi_type->mt_statcount > 0) { knp += MAC_NKSTAT; i_mac_kstat_init(knp, mip->mi_type->mt_stats, mip->mi_type->mt_statcount); } kstat_install(ksp); }
/* There are two minors 0 is the /dev/sad/admin driver and 1 is the /dev/sad/user driver. Permission for access to the /dev/sad/admin minor is performed by filesystem permission on the character device and a check on open. */ static streamscall int sad_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp) { major_t major = getmajor(*devp); minor_t minor = getminor(*devp); if (q->q_ptr) return (0); /* already open */ switch (sflag) { case CLONEOPEN: minor = 1; if (sads[minor].assigned != 0) break; case DRVOPEN: if (minor != 0 && minor != 1) break; #ifdef HAVE_KMEMB_STRUCT_CRED_UID_VAL if (minor == 0 && crp->cr_uid.val != 0 && crp->cr_ruid.val != 0) return (-EACCES); #else if (minor == 0 && crp->cr_uid != 0 && crp->cr_ruid != 0) return (-EACCES); #endif *devp = makedevice(major, minor); sads[minor].assigned |= 1; q->q_ptr = WR(q)->q_ptr = &sads[minor]; qprocson(q); return (0); } return (-ENXIO); }
/*ARGSUSED1*/ static int ds1287_open(dev_t *devp, int flags, int otyp, cred_t *credp) { struct ds1287 *softsp; int clone; if (otyp != OTYP_CHR) return (EINVAL); if ((softsp = ddi_get_soft_state(ds1287_state, instance)) == NULL) return (ENXIO); mutex_enter(&softsp->ds1287_mutex); for (clone = 1; clone < DS1287_MAX_CLONE; clone++) if (!softsp->clones[clone]) break; if (clone == DS1287_MAX_CLONE) { cmn_err(CE_WARN, "ds1287_open: No more allocation left " "to clone a minor."); mutex_exit(&softsp->ds1287_mutex); return (ENXIO); } *devp = makedevice(getmajor(*devp), (instance << 8) + clone); softsp->clones[clone] = 1; mutex_exit(&softsp->ds1287_mutex); return (0); }
/* * Returns held device policy for the specific device node. * Note devfs_devpolicy returns with a hold on the policy. */ devplcy_t * devpolicy_find(vnode_t *vp) { dev_t dev = vp->v_rdev; vtype_t spec = vp->v_type; major_t maj = getmajor(dev); int i; devplcy_t *res; if (maj == clone_major) maj = getminor(dev); rw_enter(&policyrw, RW_READER); i = devpolicyent_bymajor(maj); if (i != -1) { res = match_policy(devpolicy[i].t_ent, dev, spec); dphold(res); } else if (devfs_devpolicy(vp, &res) != 0) { res = NETWORK_DRV(maj) ? netpolicy : dfltpolicy; dphold(res); } rw_exit(&policyrw); return (res); }
void wscnprobe(struct consdev *cp) { extern int getmajor(void *); /* conf.c */ int major; major = getmajor(wsdisplayopen); if (major < 0) return; #if NGPX > 0 FRAMEBUFFER_PROBE(gpx); #endif #if NLCG > 0 FRAMEBUFFER_PROBE(lcg); #endif #if NLCSPX > 0 FRAMEBUFFER_PROBE(lcspx); #endif #if NSMG > 0 FRAMEBUFFER_PROBE(smg); #endif return; found: cp->cn_pri = CN_INTERNAL; cp->cn_dev = makedev(major, 0); }
/* ARGSUSED */ static int log_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *cr) { log_t *lp; minor_t minor; if (sflag & (MODOPEN | CLONEOPEN)) return (ENXIO); switch (minor = getminor(*devp)) { case LOG_CONSMIN: /* clone open of /dev/conslog */ if (flag & FREAD) return (EINVAL); /* write-only device */ if (q->q_ptr) return (0); break; case LOG_LOGMIN: /* clone open of /dev/log */ break; default: return (ENXIO); } lp = log_alloc(minor); if (lp == NULL) return (ENXIO); *devp = makedevice(getmajor(*devp), lp->log_minor); q->q_ptr = lp; WR(q)->q_ptr = lp; lp->log_inuse = 1; qprocson(q); return (0); }
void check_promisc(int fildes, dl_promiscon_req_t * promiscon) { char *device; file_t *file; cred_t *cred; dev_t rdev; if (promiscon->dl_primitive == DL_PROMISCON_REQ && promiscon->dl_level == DL_PROMISC_PHYS) { file = getf(fildes); if (!file) return; rdev = file->f_vnode->v_rdev; device = ddi_major_to_name(getmajor(rdev)); cred = ddi_get_cred(); log_msg(CE_WARN, "Promiscuous mode enabled on interface %s", device ? device : "unknown"); releasef(fildes); } return; }
STATIC streamscall int spm_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *crp) { int cmajor = getmajor(*devp); int cminor = getminor(*devp); spm_t *s, **sp = &spm_list; (void) crp; MOD_INC_USE_COUNT; /* keep module from unloading in our face */ if (q->q_ptr != NULL) { MOD_DEC_USE_COUNT; return (0); /* already open */ } if (sflag == DRVOPEN || WR(q)->q_next == NULL) { ptrace(("spm: ERROR: Can't open as driver\n")); MOD_DEC_USE_COUNT; return (EIO); } for (; *sp && (*sp)->cmajor < cmajor; sp = &(*sp)->next) ; for (; *sp && (*sp)->cmajor == cmajor && (*sp)->cminor < cminor; sp = &(*sp)->next) ; if (*sp && (*sp)->cmajor == cmajor && (*sp)->cminor == cminor) { ptrace(("spm: ERROR: Multiple push\n")); MOD_DEC_USE_COUNT; return (ENXIO); } printd(("spm: Pushed module for char device %d:%d\n", cmajor, cminor)); if (!(s = spm_alloc_priv(q, sp, cmajor, cminor))) { ptrace(("spm: ERROR: No cache memory\n")); MOD_DEC_USE_COUNT; return (ENOMEM); } return (0); }
static streamscall int zap_qopen(queue_t *q, dev_t *devp, int oflags, int sflag, cred_t *crp) { major_t cmajor = getmajor(*devp); minor_t cminor = getminor(*devp); struct zt_chan *chan; int err; if (q->q_ptr != NULL) return (0); /* already open */ if (sflag == DRVOPEN && cmajor == CMAJOR_0) { if (cminor == 0) { /* explicit open of control device */ } else if (cminor == 253) { /* special timining device */ } else if (cminor == 254) { } else if (cminor == 255) { } else if (cminor < ZT_MAX_CHANNELS) { chan = &chans[cminor]; } else goto enxio; } else if (sflag == CLONEOPEN && cmajor == CMAJOR_0) { if ((cminor == 255 && !(chan = zt_alloc_pseudo())) || cminor != 255) goto enxio; } else goto enxio; *devp = makedevice(cmajor, chan->channo); if ((err = zt_specchan_open(NULL, qstream(q)->sd_file, chan->channo, 1))) return (err < 0 ? -err : err); q->q_ptr = WR(q)->q_ptr = (void *) chan; return (0); enxio: return (ENXIO); }
/* * Returns -1 or the instance number of the given dev_t as * interpreted by the device driver. The code may load the driver * but it does not attach any instances. * * Instance is supposed to be a int but drivers have assumed that * the pointer was a pointer to "void *" instead of a pointer to * "int *" so we now explicitly pass a pointer to "void *" and then * cast the result to an int when returning the value. */ int dev_to_instance(dev_t dev) { major_t major = getmajor(dev); struct dev_ops *ops; void *vinstance; int error; /* verify that the driver is loaded */ if ((ops = mod_hold_dev_by_major(major)) == NULL) return (-1); ASSERT(CB_DRV_INSTALLED(ops)); /* verify that it supports the getinfo(9E) entry point */ if (ops->devo_getinfo == NULL) { mod_rele_dev_by_major(major); return (-1); } /* ask the driver to extract the instance number from the devt */ error = (*ops->devo_getinfo)(NULL, DDI_INFO_DEVT2INSTANCE, (void *)dev, &vinstance); /* release the driver */ mod_rele_dev_by_major(major); if (error != DDI_SUCCESS) return (-1); return ((int)(uintptr_t)vinstance); }
/* * Leaf driver entry points. The following [cb]dev_* functions are *not* part * of the DDI, please use functions defined in <sys/sunldi.h> and driver_lyr.c. */ int dev_open(dev_t *devp, int flag, int type, struct cred *cred) { struct cb_ops *cb; cb = devopsp[getmajor(*devp)]->devo_cb_ops; return ((*cb->cb_open)(devp, flag, type, cred)); }
int dev_close(dev_t dev, int flag, int type, struct cred *cred) { struct cb_ops *cb; cb = (devopsp[getmajor(dev)])->devo_cb_ops; return ((*cb->cb_close)(dev, flag, type, cred)); }
static void zvol_size_changed(zvol_state_t *zv, dev_t dev) { dev = makedevice(getmajor(dev), zv->zv_minor); VERIFY(ddi_prop_update_int64(dev, zfs_dip, "Size", zv->zv_volsize) == DDI_SUCCESS); VERIFY(ddi_prop_update_int64(dev, zfs_dip, "Nblocks", lbtodb(zv->zv_volsize)) == DDI_SUCCESS); }
/** * User context entry points * * @remarks fFlags are the flags passed to open() or to ldi_open_by_name. In * the latter case the FKLYR flag is added to indicate that the caller * is a kernel component rather than user land. */ static int vgdrvSolarisOpen(dev_t *pDev, int fFlags, int fType, cred_t *pCred) { int rc; PVBOXGUESTSESSION pSession = NULL; LogFlow(("vgdrvSolarisOpen:\n")); /* * Verify we are being opened as a character device. */ if (fType != OTYP_CHR) return EINVAL; vboxguest_state_t *pState = NULL; unsigned iOpenInstance; for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++) { if ( !ddi_get_soft_state(g_pvgdrvSolarisState, iOpenInstance) /* faster */ && ddi_soft_state_zalloc(g_pvgdrvSolarisState, iOpenInstance) == DDI_SUCCESS) { pState = ddi_get_soft_state(g_pvgdrvSolarisState, iOpenInstance); break; } } if (!pState) { Log(("vgdrvSolarisOpen: too many open instances.")); return ENXIO; } /* * Create a new session. */ if (!(fFlags & FKLYR)) rc = VGDrvCommonCreateUserSession(&g_DevExt, &pSession); else rc = VGDrvCommonCreateKernelSession(&g_DevExt, &pSession); if (RT_SUCCESS(rc)) { if (!(fFlags & FKLYR)) pState->pvProcRef = proc_ref(); else pState->pvProcRef = NULL; pState->pSession = pSession; *pDev = makedevice(getmajor(*pDev), iOpenInstance); Log(("vgdrvSolarisOpen: pSession=%p pState=%p pid=%d\n", pSession, pState, (int)RTProcSelf())); return 0; } /* Failed, clean up. */ ddi_soft_state_free(g_pvgdrvSolarisState, iOpenInstance); LogRel((DEVICE_NAME "::Open: VGDrvCommonCreateUserSession failed. rc=%d\n", rc)); return EFAULT; }
/* * Get a physical device name, and maybe load and attach * the driver. * * XXX Need better checking of whether or not a device * actually exists if the user typed in a pathname. * * XXX Are we sure we want to expose users to this sort * of physical namespace gobbledygook (now there's * a word to conjure with..) * * XXX Note that on an OBP machine, we can easily ask the * prom and pretty-print some plausible set of bootable * devices. We can also user the prom to verify any * such device. Later tim.. later. */ static int getphysdev(char *askfor, char *name, size_t namelen) { static char fmt[] = "Enter physical name of %s device\n[%s]: "; dev_t dev; static char defaultpath[BO_MAXOBJNAME]; /* * Establish 'default' values - we get the root device from * boot, and we infer the swap device is the same but with * a 'b' on the end instead of an 'a'. A first stab at * ease-of-use .. */ if (strcmp(askfor, "root") == 0) { if (get_bootpath_prop(defaultpath) == -1) boothowto |= RB_ASKNAME | RB_VERBOSE; } else { (void) strcpy(defaultpath, rootfs.bo_name); defaultpath[strlen(defaultpath) - 1] = 'b'; } retry: if (boothowto & RB_ASKNAME) { printf(fmt, askfor, defaultpath); console_gets(name, namelen); } if (*name == '\0') (void) strcpy(name, defaultpath); if (strcmp(askfor, "swap") == 0) { /* * Try to load and install the swap device driver. */ dev = ddi_pathname_to_dev_t(name); if (dev == (dev_t)-1) { printf("Not a supported device for swap.\n"); boothowto |= RB_ASKNAME | RB_VERBOSE; goto retry; } /* * Ensure that we're not trying to swap on the floppy. */ if (strncmp(ddi_major_to_name(getmajor(dev)), "fd", 2) == 0) { printf("Too dangerous to swap on the floppy\n"); if (boothowto & RB_ASKNAME) goto retry; return (-1); } } return (0); }
/*ARGSUSED1*/ static int kcpc_open(dev_t *dev, int flags, int otyp, cred_t *cr) { processorid_t cpuid; int error; ASSERT(pcbe_ops != NULL); if ((error = secpolicy_cpc_cpu(cr)) != 0) return (error); if (getminor(*dev) != KCPC_MINOR_SHARED) return (ENXIO); if ((cpuid = curthread->t_bind_cpu) == PBIND_NONE) return (EINVAL); if (cpuid > max_cpuid) return (EINVAL); rw_enter(&kcpc_cpuctx_lock, RW_WRITER); if (++kcpc_cpuctx == 1) { ASSERT(kcpc_cpumap == NULL); /* * Bail out if DTrace is already using the counters. */ if (dtrace_cpc_in_use) { kcpc_cpuctx--; rw_exit(&kcpc_cpuctx_lock); return (EAGAIN); } kcpc_cpumap = kmem_zalloc(BT_SIZEOFMAP(max_cpuid + 1), KM_SLEEP); /* * When this device is open for processor-based contexts, * no further lwp-based contexts can be created. * * Since this is the first open, ensure that all existing * contexts are invalidated. */ kcpc_invalidate_all(); } else if (BT_TEST(kcpc_cpumap, cpuid)) { kcpc_cpuctx--; rw_exit(&kcpc_cpuctx_lock); return (EAGAIN); } else if (kcpc_hw_cpu_hook(cpuid, kcpc_cpumap) != 0) { kcpc_cpuctx--; rw_exit(&kcpc_cpuctx_lock); return (EACCES); } BT_SET(kcpc_cpumap, cpuid); rw_exit(&kcpc_cpuctx_lock); *dev = makedevice(getmajor(*dev), (minor_t)cpuid); return (0); }
/* ARGSUSED */ static int evtchndrv_open(dev_t *devp, int flag, int otyp, cred_t *credp) { struct evtsoftdata *ep; minor_t minor = getminor(*devp); if (otyp == OTYP_BLK) return (ENXIO); /* * only allow open on minor = 0 - the clone device */ if (minor != 0) return (ENXIO); /* * find a free slot and grab it */ mutex_enter(&evtchndrv_clone_tab_mutex); for (minor = 1; minor < evtchndrv_nclones; minor++) { if (evtchndrv_clone_tab[minor] == 0) { evtchndrv_clone_tab[minor] = 1; break; } } mutex_exit(&evtchndrv_clone_tab_mutex); if (minor == evtchndrv_nclones) return (EAGAIN); /* Allocate softstate structure */ if (ddi_soft_state_zalloc(evtchndrv_statep, EVTCHNDRV_MINOR2INST(minor)) != DDI_SUCCESS) { mutex_enter(&evtchndrv_clone_tab_mutex); evtchndrv_clone_tab[minor] = 0; mutex_exit(&evtchndrv_clone_tab_mutex); return (EAGAIN); } ep = EVTCHNDRV_INST2SOFTS(EVTCHNDRV_MINOR2INST(minor)); /* ... and init it */ ep->dip = evtchndrv_dip; cv_init(&ep->evtchn_wait, NULL, CV_DEFAULT, NULL); mutex_init(&ep->evtchn_lock, NULL, MUTEX_DEFAULT, NULL); ep->ring = kmem_alloc(PAGESIZE, KM_SLEEP); /* clone driver */ *devp = makedevice(getmajor(*devp), minor); return (0); }
int streamscall ip2xinet_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp) { mblk_t *bp; minor_t minor; struct stroptions *sop; /* already open */ if (sflag != CLONEOPEN) return ENXIO; spin_lock(&ip2xinet_lock); /* Can only open one time */ if (ip2xinet_numopen) { spin_unlock(&ip2xinet_lock); return ENXIO; } else ip2xinet_numopen = 1; if (q->q_count != 0) printk("ip2x level:q_count is %lu", (ulong) q->q_count); /* Set up the flow control parameters and send them up to the stream head. */ minor = getminor(*devp); if ((bp = allocb(sizeof(struct stroptions), BPRI_LO)) == NULL) { spin_unlock(&ip2xinet_lock); printk("%s: allocb failed", __FUNCTION__); return ENOMEM; } ip2xinet_status.myminor = minor; ip2xinet_status.ip2x_dlstate = DL_UNATTACHED; /* These are dummy to keep track of the fact the device is open */ q->q_ptr = (char *) &ip2xinet_numopen; WR(q)->q_ptr = (char *) &ip2xinet_numopen; spin_unlock(&ip2xinet_lock); bp->b_datap->db_type = M_SETOPTS; bp->b_wptr += sizeof(struct stroptions); sop = (struct stroptions *) bp->b_rptr; sop->so_flags = SO_HIWAT | SO_LOWAT; sop->so_hiwat = ip2xinet_minfo.mi_hiwat; sop->so_lowat = ip2xinet_minfo.mi_lowat; putnext(q, bp); *devp = makedevice(getmajor(*devp), 0); return 0; }
/* * Helper for SMBIOC_DUP_DEV * Duplicate state from the FD @arg ("from") onto * the FD for this device instance. */ int smb_usr_dup_dev(smb_dev_t *sdp, intptr_t arg, int flags) { file_t *fp = NULL; vnode_t *vp; smb_dev_t *from_sdp; dev_t dev; int32_t ufd; int err; /* Should be no VC */ if (sdp->sd_vc != NULL) return (EISCONN); /* * Get from_sdp (what we will duplicate) */ if (ddi_copyin((void *) arg, &ufd, sizeof (ufd), flags)) return (EFAULT); if ((fp = getf(ufd)) == NULL) return (EBADF); /* rele fp below */ vp = fp->f_vnode; dev = vp->v_rdev; if (dev == 0 || dev == NODEV || getmajor(dev) != nsmb_major) { err = EINVAL; goto out; } from_sdp = ddi_get_soft_state(statep, getminor(dev)); if (from_sdp == NULL) { err = EINVAL; goto out; } /* * Duplicate VC and share references onto this FD. */ if ((sdp->sd_vc = from_sdp->sd_vc) != NULL) smb_vc_hold(sdp->sd_vc); if ((sdp->sd_share = from_sdp->sd_share) != NULL) smb_share_hold(sdp->sd_share); sdp->sd_level = from_sdp->sd_level; err = 0; out: if (fp) releasef(ufd); return (err); }
static int audio_close(dev_t dev, int flag, int otyp, cred_t *credp) { audio_client_t *c; audio_dev_t *d; _NOTE(ARGUNUSED(flag)); _NOTE(ARGUNUSED(credp)); _NOTE(ARGUNUSED(otyp)); if ((c = auclnt_hold_by_devt(dev)) == NULL) { audio_dev_warn(NULL, "close on bogus devt %x,%x", getmajor(dev), getminor(dev)); return (ENXIO); } /* we don't want any upcalls anymore */ auimpl_client_deactivate(c); /* * Pick up any data sitting around in input buffers. This * avoids leaving record data stuck in queues. */ if (c->c_istream.s_engine != NULL) audio_engine_produce(c->c_istream.s_engine); /* get a local hold on the device */ d = c->c_dev; auimpl_dev_hold(c->c_dev); /* * NB: This must be done before c->c_close, since it calls * auclnt_close which will block waiting for the refence count * to drop to zero. */ auclnt_release(c); /* Call personality specific close handler */ c->c_close(c); auimpl_client_destroy(c); /* notify peers that a change has occurred */ atomic_inc_uint(&d->d_serial); /* now we can drop the release we had on the device */ auimpl_dev_release(d); return (0); }
/* ARGSUSED */ static int cryptoadm_open(dev_t *devp, int flag, int otyp, cred_t *credp) { if (otyp != OTYP_CHR || cryptoadm_dip == NULL) return (ENXIO); /* exclusive opens are not supported */ if (flag & FEXCL) return (ENOTSUP); *devp = makedevice(getmajor(*devp), 0); kcf_sched_start(); return (0); }
/*ARGSUSED*/ int snode(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { snode_cbdata_t sd; struct snode snode; uintptr_t major = 0, dev = 0; sd.sd_major = -1; sd.sd_minor = -1; sd.sd_verbose = !(flags & DCMD_PIPE_OUT); if (mdb_getopts(argc, argv, 'm', MDB_OPT_UINTPTR, &major, 'd', MDB_OPT_UINTPTR, &dev, NULL) != argc) return (DCMD_USAGE); if (dev != 0) { sd.sd_major = getmajor(dev); sd.sd_minor = getminor(dev); } if (major != 0) sd.sd_major = major; if (DCMD_HDRSPEC(flags) && !(flags & DCMD_PIPE_OUT)) { mdb_printf("%<u>%?s %?s %6s %16s %-15s%</u>\n", "ADDR", "VNODE", "COUNT", "DEV", "FLAG"); } if (!(flags & DCMD_ADDRSPEC)) { if (mdb_walk("snode", (mdb_walk_cb_t)snode_cb, &sd) == -1) { mdb_warn("can't walk snodes"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_vread(&snode, sizeof (snode), addr) == -1) { mdb_warn("failed to read snode structure at %p", addr); return (DCMD_ERR); } snode_cb(addr, &snode, &sd); return (DCMD_OK); }
/*ARGSUSED3*/ int dev2snode(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { snode_cbdata_t sd; if (!(flags & DCMD_ADDRSPEC) || argc != 0) return (DCMD_USAGE); sd.sd_major = getmajor(addr); sd.sd_minor = getminor(addr); sd.sd_verbose = 0; if (mdb_pwalk("snode", (mdb_walk_cb_t)snode_cb, &sd, 0) != 0) return (DCMD_ERR); return (DCMD_OK); }
/* * Helper used by smbfs_mount */ int smb_dev2share(int fd, struct smb_share **sspp) { file_t *fp = NULL; vnode_t *vp; smb_dev_t *sdp; smb_share_t *ssp; dev_t dev; int err; if ((fp = getf(fd)) == NULL) return (EBADF); /* rele fp below */ vp = fp->f_vnode; dev = vp->v_rdev; if (dev == 0 || dev == NODEV || getmajor(dev) != nsmb_major) { err = EINVAL; goto out; } sdp = ddi_get_soft_state(statep, getminor(dev)); if (sdp == NULL) { err = EINVAL; goto out; } ssp = sdp->sd_share; if (ssp == NULL) { err = ENOTCONN; goto out; } /* * Our caller gains a ref. to this share. */ *sspp = ssp; smb_share_hold(ssp); err = 0; out: if (fp) releasef(fd); return (err); }
/*ARGSUSED*/ static int opromopen(dev_t *devp, int flag, int otyp, cred_t *credp) { int m; struct oprom_state *st = oprom_state; if (getminor(*devp) != 0) return (ENXIO); mutex_enter(&oprom_lock); for (m = 0; m < MAX_OPENS; m++) if (st->already_open) st++; else { st->already_open = 1; /* * It's ours. */ st->current_id = (pnode_t)0; ASSERT(st->snapshot == NULL && st->size == 0); ASSERT(st->ioc_state == IOC_IDLE); break; } mutex_exit(&oprom_lock); if (m == MAX_OPENS) { /* * "Thank you for calling, but all our lines are * busy at the moment.." * * We could get sophisticated here, and go into a * sleep-retry loop .. but hey, I just can't see * that many processes sitting in this driver. * * (And if it does become possible, then we should * change the interface so that the 'state' is held * external to the driver) */ return (EAGAIN); } *devp = makedevice(getmajor(*devp), (minor_t)m); return (0); }
static int VBoxUSBMonSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred) { vboxusbmon_state_t *pState = NULL; unsigned iOpenInstance; LogFunc((DEVICE_NAME ": VBoxUSBMonSolarisOpen\n")); /* * Verify we are being opened as a character device. */ if (fType != OTYP_CHR) return EINVAL; /* * Verify that we're called after attach. */ if (!g_pDip) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisOpen: Invalid state for opening\n")); return ENXIO; } for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++) { if ( !ddi_get_soft_state(g_pVBoxUSBMonSolarisState, iOpenInstance) /* faster */ && ddi_soft_state_zalloc(g_pVBoxUSBMonSolarisState, iOpenInstance) == DDI_SUCCESS) { pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, iOpenInstance); break; } } if (!pState) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisOpen: Too many open instances")); return ENXIO; } pState->Process = RTProcSelf(); *pDev = makedevice(getmajor(*pDev), iOpenInstance); NOREF(fFlag); NOREF(pCred); return 0; }