Exemple #1
0
static inline struct ra_softc *
mscp_device_lookup(dev_t dev)
{
	struct ra_softc *ra;
	int unit;

	unit = DISKUNIT(dev);
#if NRA
	if (cdevsw_lookup(dev) == &ra_cdevsw)
		ra = device_lookup_private(&ra_cd, unit);
	else
#endif
#if NRACD
	if (cdevsw_lookup(dev) == &racd_cdevsw)
		ra = device_lookup_private(&racd_cd, unit);
	else
#endif
#if NRX
	if (cdevsw_lookup(dev) == &rx_cdevsw)
		ra = device_lookup_private(&rx_cd, unit);
	else
#endif
		panic("mscp_device_lookup: unexpected major %"PRIu32" unit %u",
		    major(dev), unit);
	return ra;
}
Exemple #2
0
/*
 * (Try to) put the drive online. This is done the first time the
 * drive is opened, or if it has fallen offline.
 */
int
ra_putonline(dev_t dev, struct ra_softc *ra)
{
	struct	disklabel *dl;
	const char *msg;

	if (rx_putonline(ra) != MSCP_DONE)
		return MSCP_FAILED;

	dl = ra->ra_disk.dk_label;

	ra->ra_state = DK_RDLABEL;
	printf("%s", device_xname(ra->ra_dev));
	if ((msg = readdisklabel(
	    MAKEDISKDEV(major(dev), device_unit(ra->ra_dev), RAW_PART),
	    rastrategy, dl, NULL)) == NULL) {
		ra->ra_havelabel = 1;
		ra->ra_state = DK_OPEN;
	}
#if NRACD
	else if (cdevsw_lookup(dev) == &racd_cdevsw) {
		dl->d_partitions[0].p_offset = 0;
		dl->d_partitions[0].p_size = dl->d_secperunit;
		dl->d_partitions[0].p_fstype = FS_ISO9660;
	}
#endif /* NRACD */
	else {
		printf(": %s", msg);
	}

	printf(": size %d sectors\n", dl->d_secperunit);

	return MSCP_DONE;
}
Exemple #3
0
/*
 * XXX Pathetic hack to make svgalib work. This will fake the major
 * device number of an opened VT so that svgalib likes it. grmbl.
 * Should probably do it 'wrong the right way' and use a mapping
 * array for all major device numbers, and map linux_mknod too.
 */
dev_t
linux_fakedev(dev_t dev, int raw)
{
	extern const struct cdevsw ptc_cdevsw, pts_cdevsw;
	const struct cdevsw *cd = cdevsw_lookup(dev);

	if (raw) {
#if (NWSDISPLAY > 0)
		extern const struct cdevsw wsdisplay_cdevsw;
		if (cd == &wsdisplay_cdevsw)
			return makedev(LINUX_CONS_MAJOR, (minor(dev) + 1));
#endif
	}

	if (cd == &ptc_cdevsw)
		return makedev(LINUX_PTC_MAJOR, minor(dev));
	if (cd == &pts_cdevsw)
		return makedev(LINUX_PTS_MAJOR, minor(dev));

	return dev;
}
dev_t
linux_fakedev(dev_t dev, int raw)
{

       extern const struct cdevsw ptc_cdevsw, pts_cdevsw;
       const struct cdevsw *cd = cdevsw_lookup(dev);

       if (raw) {
#if (NWSDISPLAY > 0)
	       extern const struct cdevsw wsdisplay_cdevsw;
	       if (cd == &wsdisplay_cdevsw)
		       return makedev(LINUX_CONS_MAJOR, (minor(dev) + 1));
#endif
       }

       if (cd == &ptc_cdevsw)
	       return makedev(LINUX_PTC_MAJOR, minor(dev));
       if (cd == &pts_cdevsw)
	       return makedev(LINUX_PTS_MAJOR, minor(dev));

	return ((minor(dev) & 0xff) | ((major(dev) & 0xfff) << 8)
	    | (((unsigned long long int) (minor(dev) & ~0xff)) << 12)
	    | (((unsigned long long int) (major(dev) & ~0xfff)) << 32));
}
/*
 * Most ioctl command are just converted to their NetBSD values,
 * and passed on. The ones that take structure pointers and (flag)
 * values need some massaging.
 */
int
linux_sys_ioctl(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(u_long) com;
		syscallarg(void *) data;
	} */
	int error;

	switch (LINUX_IOCGROUP(SCARG(uap, com))) {
	case 'M':
		switch(SCARG(uap, com)) {
		case LINUX_MEGARAID_CMD:
		case LINUX_MEGARAID_GET_AEN:
		{
			struct sys_ioctl_args ua;
			u_long com = 0;
			if (SCARG(uap, com) & IOC_IN)
				com |= IOC_OUT;
			if (SCARG(uap, com) & IOC_OUT)
				com |= IOC_IN;
			SCARG(&ua, fd) = SCARG(uap, fd);
			SCARG(&ua, com) = SCARG(uap, com);
			SCARG(&ua, com) &= ~IOC_DIRMASK;
			SCARG(&ua, com) |= com;
			SCARG(&ua, data) = SCARG(uap, data);
			error = sys_ioctl(l, (const void *)&ua, retval);
			break;
		}
		default:
			error = oss_ioctl_mixer(l, LINUX_TO_OSS(uap), retval);
			break;
		}
		break;
	case 'Q':
		error = oss_ioctl_sequencer(l, LINUX_TO_OSS(uap), retval);
		break;
	case 'P':
		error = oss_ioctl_audio(l, LINUX_TO_OSS(uap), retval);
		break;
	case 'V':	/* video4linux2 */
	case 'd':	/* drm */
	{
		struct sys_ioctl_args ua;
		u_long com = 0;
		if (SCARG(uap, com) & IOC_IN)
			com |= IOC_OUT;
		if (SCARG(uap, com) & IOC_OUT)
			com |= IOC_IN;
		SCARG(&ua, fd) = SCARG(uap, fd);
		SCARG(&ua, com) = SCARG(uap, com);
		SCARG(&ua, com) &= ~IOC_DIRMASK;
		SCARG(&ua, com) |= com;
		SCARG(&ua, data) = SCARG(uap, data);
		error = sys_ioctl(l, (const void *)&ua, retval);
		break;
	}
	case 'r': /* VFAT ioctls; not yet supported */
		error = ENOSYS;
		break;
	case 'S':
		error = linux_ioctl_cdrom(l, uap, retval);
		break;
	case 't':
	case 'f':
		error = linux_ioctl_termios(l, uap, retval);
		break;
	case 'm':
		error = linux_ioctl_mtio(l, uap, retval);
		break;
	case 'T':
	{
#if NSEQUENCER > 0
/* XXX XAX 2x check this. */
		/*
		 * Both termios and the MIDI sequencer use 'T' to identify
		 * the ioctl, so we have to differentiate them in another
		 * way.  We do it by indexing in the cdevsw with the major
		 * device number and check if that is the sequencer entry.
		 */
		bool is_sequencer = false;
		struct file *fp;
		struct vnode *vp;
		struct vattr va;
		extern const struct cdevsw sequencer_cdevsw;

		if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
			return EBADF;
		if (fp->f_type == DTYPE_VNODE &&
		    (vp = (struct vnode *)fp->f_data) != NULL &&
		    vp->v_type == VCHR) {
			vn_lock(vp, LK_SHARED | LK_RETRY);
			error = VOP_GETATTR(vp, &va, l->l_cred);
			VOP_UNLOCK(vp);
			if (error == 0 &&
			    cdevsw_lookup(va.va_rdev) == &sequencer_cdevsw)
				is_sequencer = true;
		}
		if (is_sequencer) {
			error = oss_ioctl_sequencer(l, (const void *)LINUX_TO_OSS(uap),
						   retval);
		}
		else {
			error = linux_ioctl_termios(l, uap, retval);
		}
		fd_putfile(SCARG(uap, fd));
#else
		error = linux_ioctl_termios(l, uap, retval);
#endif
	}
		break;
	case '"':
		error = linux_ioctl_sg(l, uap, retval);
		break;
	case 0x89:
		error = linux_ioctl_socket(l, uap, retval);
		break;
	case 0x03:
		error = linux_ioctl_hdio(l, uap, retval);
		break;
	case 0x02:
		error = linux_ioctl_fdio(l, uap, retval);
		break;
	case 0x12:
		error = linux_ioctl_blkio(l, uap, retval);
		break;
	default:
		error = linux_machdepioctl(l, uap, retval);
		break;
	}
	if (error == EPASSTHROUGH) {
		/*
		 * linux returns EINVAL or ENOTTY for not supported ioctls.
		 */ 
		error = EINVAL;
	}

	return error;
}
Exemple #6
0
/*ARGSUSED*/
int
coda_mount(struct mount *vfsp,	/* Allocated and initialized by mount(2) */
    const char *path,	/* path covered: ignored by the fs-layer */
    void *data,		/* Need to define a data type for this in netbsd? */
    size_t *data_len)
{
    struct lwp *l = curlwp;
    struct vnode *dvp;
    struct cnode *cp;
    dev_t dev;
    struct coda_mntinfo *mi;
    struct vnode *rtvp;
    const struct cdevsw *cdev;
    CodaFid rootfid = INVAL_FID;
    CodaFid ctlfid = CTL_FID;
    int error;

    if (data == NULL)
	return EINVAL;
    if (vfsp->mnt_flag & MNT_GETARGS)
	return EINVAL;
    ENTRY;

    coda_vfsopstats_init();
    coda_vnodeopstats_init();

    MARK_ENTRY(CODA_MOUNT_STATS);
    if (CODA_MOUNTED(vfsp)) {
	MARK_INT_FAIL(CODA_MOUNT_STATS);
	return(EBUSY);
    }

    /* Validate mount device.  Similar to getmdev(). */

    /*
     * XXX: coda passes the mount device as the entire mount args,
     * All other fs pass a structure contining a pointer.
     * In order to get sys_mount() to do the copyin() we've set a
     * fixed default size for the filename buffer.
     */
    /* Ensure that namei() doesn't run off the filename buffer */
    ((char *)data)[*data_len - 1] = 0;
    error = namei_simple_kernel((char *)data, NSM_FOLLOW_NOEMULROOT,
		&dvp);

    if (error) {
	MARK_INT_FAIL(CODA_MOUNT_STATS);
	return (error);
    }
    if (dvp->v_type != VCHR) {
	MARK_INT_FAIL(CODA_MOUNT_STATS);
	vrele(dvp);
	return(ENXIO);
    }
    dev = dvp->v_rdev;
    vrele(dvp);
    cdev = cdevsw_lookup(dev);
    if (cdev == NULL) {
	MARK_INT_FAIL(CODA_MOUNT_STATS);
	return(ENXIO);
    }

    /*
     * See if the device table matches our expectations.
     */
    if (cdev != &vcoda_cdevsw)
    {
	MARK_INT_FAIL(CODA_MOUNT_STATS);
	return(ENXIO);
    }

    if (minor(dev) >= NVCODA) {
	MARK_INT_FAIL(CODA_MOUNT_STATS);
	return(ENXIO);
    }

    /*
     * Initialize the mount record and link it to the vfs struct
     */
    mi = &coda_mnttbl[minor(dev)];

    if (!VC_OPEN(&mi->mi_vcomm)) {
	MARK_INT_FAIL(CODA_MOUNT_STATS);
	return(ENODEV);
    }

    /* No initialization (here) of mi_vcomm! */
    vfsp->mnt_data = mi;
    vfsp->mnt_stat.f_fsidx.__fsid_val[0] = 0;
    vfsp->mnt_stat.f_fsidx.__fsid_val[1] = makefstype(MOUNT_CODA);
    vfsp->mnt_stat.f_fsid = vfsp->mnt_stat.f_fsidx.__fsid_val[0];
    vfsp->mnt_stat.f_namemax = CODA_MAXNAMLEN;
    mi->mi_vfsp = vfsp;

    /*
     * Make a root vnode to placate the Vnode interface, but don't
     * actually make the CODA_ROOT call to venus until the first call
     * to coda_root in case a server is down while venus is starting.
     */
    cp = make_coda_node(&rootfid, vfsp, VDIR);
    rtvp = CTOV(cp);
    rtvp->v_vflag |= VV_ROOT;

    cp = make_coda_node(&ctlfid, vfsp, VCHR);

    coda_ctlvp = CTOV(cp);

    /* Add vfs and rootvp to chain of vfs hanging off mntinfo */
    mi->mi_vfsp = vfsp;
    mi->mi_rootvp = rtvp;

    /* set filesystem block size */
    vfsp->mnt_stat.f_bsize = 8192;	    /* XXX -JJK */
    vfsp->mnt_stat.f_frsize = 8192;	    /* XXX -JJK */

    /* error is currently guaranteed to be zero, but in case some
       code changes... */
    CODADEBUG(1,
	     myprintf(("coda_mount returned %d\n",error)););