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; }
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); }
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; }