static int
dasd_do_ioctl(struct block_device *bdev, fmode_t mode,
	      unsigned int cmd, unsigned long arg)
{
	struct dasd_block *block = bdev->bd_disk->private_data;
	void __user *argp;

	if (is_compat_task())
		argp = compat_ptr(arg);
	else
		argp = (void __user *)arg;

	if (!block)
                return -ENODEV;

	if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) {
		PRINT_DEBUG("empty data ptr");
		return -EINVAL;
	}

	switch (cmd) {
	case BIODASDDISABLE:
		return dasd_ioctl_disable(bdev);
	case BIODASDENABLE:
		return dasd_ioctl_enable(bdev);
	case BIODASDQUIESCE:
		return dasd_ioctl_quiesce(block);
	case BIODASDRESUME:
		return dasd_ioctl_resume(block);
	case BIODASDFMT:
		return dasd_ioctl_format(bdev, argp);
	case BIODASDINFO:
		return dasd_ioctl_information(block, cmd, argp);
	case BIODASDINFO2:
		return dasd_ioctl_information(block, cmd, argp);
	case BIODASDPRRD:
		return dasd_ioctl_read_profile(block, argp);
	case BIODASDPRRST:
		return dasd_ioctl_reset_profile(block);
	case BLKROSET:
		return dasd_ioctl_set_ro(bdev, argp);
	case DASDAPIVER:
		return dasd_ioctl_api_version(argp);
	case BIODASDCMFENABLE:
		return enable_cmf(block->base->cdev);
	case BIODASDCMFDISABLE:
		return disable_cmf(block->base->cdev);
	case BIODASDREADALLCMB:
		return dasd_ioctl_readall_cmb(block, cmd, argp);
	default:
		/* if the discipline has an ioctl method try it. */
		if (block->base->discipline->ioctl) {
			int rval = block->base->discipline->ioctl(block, cmd, argp);
			if (rval != -ENOIOCTLCMD)
				return rval;
		}

		return -EINVAL;
	}
}
Beispiel #2
0
int dasd_ioctl(struct block_device *bdev, fmode_t mode,
	       unsigned int cmd, unsigned long arg)
{
	struct dasd_block *block;
	struct dasd_device *base;
	void __user *argp;
	int rc;

	if (is_compat_task())
		argp = compat_ptr(arg);
	else
		argp = (void __user *)arg;

	if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) {
		PRINT_DEBUG("empty data ptr");
		return -EINVAL;
	}

	base = dasd_device_from_gendisk(bdev->bd_disk);
	if (!base)
		return -ENODEV;
	block = base->block;
	rc = 0;
	switch (cmd) {
	case BIODASDDISABLE:
		rc = dasd_ioctl_disable(bdev);
		break;
	case BIODASDENABLE:
		rc = dasd_ioctl_enable(bdev);
		break;
	case BIODASDQUIESCE:
		rc = dasd_ioctl_quiesce(block);
		break;
	case BIODASDRESUME:
		rc = dasd_ioctl_resume(block);
		break;
	case BIODASDFMT:
		rc = dasd_ioctl_format(bdev, argp);
		break;
	case BIODASDINFO:
		rc = dasd_ioctl_information(block, cmd, argp);
		break;
	case BIODASDINFO2:
		rc = dasd_ioctl_information(block, cmd, argp);
		break;
	case BIODASDPRRD:
		rc = dasd_ioctl_read_profile(block, argp);
		break;
	case BIODASDPRRST:
		rc = dasd_ioctl_reset_profile(block);
		break;
	case BLKROSET:
		rc = dasd_ioctl_set_ro(bdev, argp);
		break;
	case DASDAPIVER:
		rc = dasd_ioctl_api_version(argp);
		break;
	case BIODASDCMFENABLE:
		rc = enable_cmf(base->cdev);
		break;
	case BIODASDCMFDISABLE:
		rc = disable_cmf(base->cdev);
		break;
	case BIODASDREADALLCMB:
		rc = dasd_ioctl_readall_cmb(block, cmd, argp);
		break;
	default:
		/* if the discipline has an ioctl method try it. */
		if (base->discipline->ioctl) {
			rc = base->discipline->ioctl(block, cmd, argp);
			if (rc == -ENOIOCTLCMD)
				rc = -EINVAL;
		} else
			rc = -EINVAL;
	}
	dasd_put_device(base);
	return rc;
}