/*
 * Return dasd information. Used for BIODASDINFO and BIODASDINFO2.
 */
static int dasd_ioctl_information(struct dasd_block *block,
				  unsigned int cmd, void __user *argp)
{
	struct dasd_information2_t *dasd_info;
	unsigned long flags;
	int rc;
	struct dasd_device *base;
	struct ccw_device *cdev;
	struct ccw_dev_id dev_id;

	base = block->base;
	if (!base->discipline->fill_info)
		return -EINVAL;

	dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL);
	if (dasd_info == NULL)
		return -ENOMEM;

	rc = base->discipline->fill_info(base, dasd_info);
	if (rc) {
		kfree(dasd_info);
		return rc;
	}

	cdev = base->cdev;
	ccw_device_get_id(cdev, &dev_id);

	dasd_info->devno = dev_id.devno;
	dasd_info->schid = _ccw_device_get_subchannel_number(base->cdev);
	dasd_info->cu_type = cdev->id.cu_type;
	dasd_info->cu_model = cdev->id.cu_model;
	dasd_info->dev_type = cdev->id.dev_type;
	dasd_info->dev_model = cdev->id.dev_model;
	dasd_info->status = base->state;
	/*
	 * The open_count is increased for every opener, that includes
	 * the blkdev_get in dasd_scan_partitions.
	 * This must be hidden from user-space.
	 */
	dasd_info->open_count = atomic_read(&block->open_count);
	if (!block->bdev)
		dasd_info->open_count++;

	/*
	 * check if device is really formatted
	 * LDL / CDL was returned by 'fill_info'
	 */
	if ((base->state < DASD_STATE_READY) ||
	    (dasd_check_blocksize(block->bp_block)))
		dasd_info->format = DASD_FORMAT_NONE;

	dasd_info->features |=
		((base->features & DASD_FEATURE_READONLY) != 0);

	if (base->discipline)
		memcpy(dasd_info->type, base->discipline->name, 4);
	else
		memcpy(dasd_info->type, "none", 4);

	if (block->request_queue->request_fn) {
		struct list_head *l;
#ifdef DASD_EXTENDED_PROFILING
		{
			struct list_head *l;
			spin_lock_irqsave(&block->lock, flags);
			list_for_each(l, &block->request_queue->queue_head)
				dasd_info->req_queue_len++;
			spin_unlock_irqrestore(&block->lock, flags);
		}
#endif				/* DASD_EXTENDED_PROFILING */
		spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
		list_for_each(l, &base->ccw_queue)
			dasd_info->chanq_len++;
		spin_unlock_irqrestore(get_ccwdev_lock(base->cdev),
				       flags);
	}

	rc = 0;
	if (copy_to_user(argp, dasd_info,
			 ((cmd == (unsigned int) BIODASDINFO2) ?
			  sizeof(struct dasd_information2_t) :
			  sizeof(struct dasd_information_t))))
		rc = -EFAULT;
	kfree(dasd_info);
	return rc;
}
Exemple #2
0
static int
dasd_devices_show(struct seq_file *m, void *v)
{
    struct dasd_device *device;
    struct dasd_block *block;
    char *substr;

    device = dasd_device_from_devindex((unsigned long) v - 1);
    if (IS_ERR(device))
        return 0;
    if (device->block)
        block = device->block;
    else {
        dasd_put_device(device);
        return 0;
    }
    /* Print device number. */
    seq_printf(m, "%s", dev_name(&device->cdev->dev));
    /* Print discipline string. */
    if (device != NULL && device->discipline != NULL)
        seq_printf(m, "(%s)", device->discipline->name);
    else
        seq_printf(m, "(none)");
    /* Print kdev. */
    if (block->gdp)
        seq_printf(m, " at (%3d:%6d)",
                   MAJOR(disk_devt(block->gdp)),
                   MINOR(disk_devt(block->gdp)));
    else
        seq_printf(m, "  at (???:??????)");
    /* Print device name. */
    if (block->gdp)
        seq_printf(m, " is %-8s", block->gdp->disk_name);
    else
        seq_printf(m, " is ????????");
    /* Print devices features. */
    substr = (device->features & DASD_FEATURE_READONLY) ? "(ro)" : " ";
    seq_printf(m, "%4s: ", substr);
    /* Print device status information. */
    switch ((device != NULL) ? device->state : -1) {
    case -1:
        seq_printf(m, "unknown");
        break;
    case DASD_STATE_NEW:
        seq_printf(m, "new");
        break;
    case DASD_STATE_KNOWN:
        seq_printf(m, "detected");
        break;
    case DASD_STATE_BASIC:
        seq_printf(m, "basic");
        break;
    case DASD_STATE_UNFMT:
        seq_printf(m, "unformatted");
        break;
    case DASD_STATE_READY:
    case DASD_STATE_ONLINE:
        seq_printf(m, "active ");
        if (dasd_check_blocksize(block->bp_block))
            seq_printf(m, "n/f	 ");
        else
            seq_printf(m,
                       "at blocksize: %d, %ld blocks, %ld MB",
                       block->bp_block, block->blocks,
                       ((block->bp_block >> 9) *
                        block->blocks) >> 11);
        break;
    default:
        seq_printf(m, "no stat");
        break;
    }
    dasd_put_device(device);
    if (dasd_probeonly)
        seq_printf(m, "(probeonly)");
    seq_printf(m, "\n");
    return 0;
}
Exemple #3
0
static int
dasd_devices_show(struct seq_file *m, void *v)
{
	struct dasd_device *device;
	char *substr;

	device = dasd_device_from_devindex((unsigned long) v - 1);
	if (IS_ERR(device))
		return 0;
	/* Print device number. */
	seq_printf(m, "%s", device->cdev->dev.bus_id);
	/* Print discipline string. */
	if (device != NULL && device->discipline != NULL)
		seq_printf(m, "(%s)", device->discipline->name);
	else
		seq_printf(m, "(none)");
	/* Print kdev. */
	if (device->gdp)
		seq_printf(m, " at (%3d:%6d)",
			   device->gdp->major, device->gdp->first_minor);
	else
		seq_printf(m, "  at (???:??????)");
	/* Print device name. */
	if (device->gdp)
		seq_printf(m, " is %-8s", device->gdp->disk_name);
	else
		seq_printf(m, " is ????????");
	/* Print devices features. */
	substr = test_bit(DASD_FLAG_RO, &device->flags) ? "(ro)" : " ";
	seq_printf(m, "%4s: ", substr);
	/* Print device status information. */
	switch ((device != NULL) ? device->state : -1) {
	case -1:
		seq_printf(m, "unknown");
		break;
	case DASD_STATE_NEW:
		seq_printf(m, "new");
		break;
	case DASD_STATE_KNOWN:
		seq_printf(m, "detected");
		break;
	case DASD_STATE_BASIC:
		seq_printf(m, "basic");
		break;
	case DASD_STATE_READY:
	case DASD_STATE_ONLINE:
		seq_printf(m, "active ");
		if (dasd_check_blocksize(device->bp_block))
			seq_printf(m, "n/f	 ");
		else
			seq_printf(m,
				   "at blocksize: %d, %ld blocks, %ld MB",
				   device->bp_block, device->blocks,
				   ((device->bp_block >> 9) *
				    device->blocks) >> 11);
		break;
	default:
		seq_printf(m, "no stat");
		break;
	}
	dasd_put_device(device);
	if (dasd_probeonly)
		seq_printf(m, "(probeonly)");
	seq_printf(m, "\n");
	return 0;
}