コード例 #1
0
ファイル: htifbd.c プロジェクト: rishinaidu/riscv-linux
static int htifbd_probe(struct device *dev)
{
	static unsigned int htifbd_nr = 0;
	static const char size_str[] = "size=";

	struct htif_dev *htif_dev;
	struct htifbd_dev *htifbd_dev;
	struct gendisk *gd;
	unsigned long size;

	htif_dev = to_htif_dev(dev);
	pr_info(DRIVER_NAME ": detected disk with ID %u\n", htif_dev->minor);

	if (unlikely(strncmp(htif_dev->spec, size_str, sizeof(size_str) - 1)
		|| kstrtoul(htif_dev->spec + sizeof(size_str) - 1, 10, &size))) {
		pr_err(DRIVER_NAME ": unable to determine size of disk %u\n",
			htif_dev->minor);
		goto err_out;
	}
	if (unlikely(size & (SECTOR_SIZE - 1))) {
		pr_warn(DRIVER_NAME ": size of disk %u not a multiple of sector size\n",
			htif_dev->minor);
	}

	htifbd_dev = kzalloc(sizeof(struct htifbd_dev), GFP_KERNEL);
	if (unlikely(htifbd_dev == NULL))
		goto err_out;
	htifbd_dev->size = size;
	htifbd_dev->dev = htif_dev;

	gd = alloc_disk(1);
	if (unlikely(gd == NULL))
		goto err_gd_alloc;

	spin_lock_init(&htifbd_dev->lock);
	gd->queue = blk_init_queue(htifbd_request, &htifbd_dev->lock);
	if (unlikely(gd->queue == NULL))
		goto err_queue_init;

	gd->major = htifbd_major;
	gd->minors = 1;
	gd->first_minor = 0;
	gd->fops = &htifbd_ops;
	gd->private_data = htifbd_dev;
	set_capacity(gd, size >> SECTOR_SIZE_SHIFT);
	snprintf(gd->disk_name, DISK_NAME_LEN - 1, "htifbd%u", htifbd_nr++);
	pr_info(DRIVER_NAME ": adding %s\n", gd->disk_name);

	htifbd_dev->gd = gd;
	add_disk(gd);
	return 0;

err_queue_init:
	put_disk(gd);
err_gd_alloc:
	kfree(htifbd_dev);
err_out:
	return -ENODEV;
}
コード例 #2
0
ファイル: htif-drv.c プロジェクト: arunthomas/riscv-linux
static int htif_bus_match(struct device *dev, struct device_driver *drv)
{
	const char *id;
	const char *s;
	size_t n;

	id = to_htif_dev(dev)->id;
	s = strnchr(id, HTIF_MAX_ID, ' ');
	n = (s != NULL) ? (s - id) : HTIF_MAX_ID;
	return !strncmp(id, to_htif_driver(drv)->type, n);
}
コード例 #3
0
static int htifblk_probe(struct device *dev)
{
	static unsigned int index = 0;
	static const char prefix[] = " size=";

	struct htif_device *htif_dev;
	struct htifblk_device *htifblk_dev;
	struct gendisk *disk;
	struct request_queue *queue;
	const char *str;
	u64 size;
	int ret;

	dev_info(dev, "detected disk\n");
	htif_dev = to_htif_dev(dev);

	str = strstr(htif_dev->id, prefix);
	if (unlikely(str == NULL
	    || kstrtou64(str + sizeof(prefix) - 1, 10, &size))) {
		dev_err(dev, "error determining size of disk\n");
		return -ENODEV;
	}
	if (unlikely(size & (SECTOR_SIZE - 1))) {
		dev_warn(dev, "disk size not a multiple of sector size:"
			" %llu\n", size);
	}

	ret = -ENOMEM;
	htifblk_dev = devm_kzalloc(dev, sizeof(struct htifblk_device), GFP_KERNEL);
	if (unlikely(htifblk_dev == NULL))
		goto out;

	htifblk_dev->size = size;
	htifblk_dev->dev = htif_dev;
	htifblk_dev->tag = index;
	spin_lock_init(&htifblk_dev->lock);

	disk = alloc_disk(1);
	if (unlikely(disk == NULL))
		goto out;

	queue = blk_init_queue(htifblk_request, &htifblk_dev->lock);
	if (unlikely(queue == NULL))
		goto out_put_disk;

	queue->queuedata = htifblk_dev;
	blk_queue_max_segments(queue, 1);
	blk_queue_dma_alignment(queue, HTIF_ALIGN - 1);

	disk->queue = queue;
	disk->major = major;
	disk->minors = 1;
	disk->first_minor = 0;
	disk->fops = &htifblk_fops;
	set_capacity(disk, size >> SECTOR_SIZE_SHIFT);
	snprintf(disk->disk_name, DISK_NAME_LEN - 1, "htifblk%u", index++);

	htifblk_dev->disk = disk;
	add_disk(disk);
	dev_info(dev, "added %s\n", disk->disk_name);

	ret = htif_request_irq(htif_dev, htifblk_isr);
	if (unlikely(ret))
		goto out_del_disk;

	dev_set_drvdata(dev, htifblk_dev);
	return 0;

out_del_disk:
	del_gendisk(disk);
	blk_cleanup_queue(disk->queue);
out_put_disk:
	put_disk(disk);
out:
	return ret;
}