Commit 1ad392ad authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

pd: cleanup initialization



Refactor the pf initialization to have a dedicated helper to initialize
a single disk.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent fb367e6b
Loading
Loading
Loading
Loading
+70 −70
Original line number Diff line number Diff line
@@ -875,9 +875,27 @@ static const struct blk_mq_ops pd_mq_ops = {
	.queue_rq	= pd_queue_rq,
};

static void pd_probe_drive(struct pd_unit *disk)
static int pd_probe_drive(struct pd_unit *disk, int autoprobe, int port,
		int mode, int unit, int protocol, int delay)
{
	int index = disk - pd;
	int *parm = *drives[index];
	struct gendisk *p;
	int ret;

	disk->pi = &disk->pia;
	disk->access = 0;
	disk->changed = 1;
	disk->capacity = 0;
	disk->drive = parm[D_SLV];
	snprintf(disk->name, PD_NAMELEN, "%s%c", name, 'a' + index);
	disk->alt_geom = parm[D_GEO];
	disk->standby = parm[D_SBY];
	INIT_LIST_HEAD(&disk->rq_list);

	if (!pi_init(disk->pi, autoprobe, port, mode, unit, protocol, delay,
			pd_scratch, PI_PD, verbose, disk->name))
		return -ENXIO;

	memset(&disk->tag_set, 0, sizeof(disk->tag_set));
	disk->tag_set.ops = &pd_mq_ops;
@@ -887,14 +905,14 @@ static void pd_probe_drive(struct pd_unit *disk)
	disk->tag_set.queue_depth = 2;
	disk->tag_set.numa_node = NUMA_NO_NODE;
	disk->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING;

	if (blk_mq_alloc_tag_set(&disk->tag_set))
		return;
	ret = blk_mq_alloc_tag_set(&disk->tag_set);
	if (ret)
		goto pi_release;

	p = blk_mq_alloc_disk(&disk->tag_set, disk);
	if (IS_ERR(p)) {
		blk_mq_free_tag_set(&disk->tag_set);
		return;
		ret = PTR_ERR(p);
		goto free_tag_set;
	}
	disk->gd = p;

@@ -905,102 +923,84 @@ static void pd_probe_drive(struct pd_unit *disk)
	p->minors = 1 << PD_BITS;
	p->events = DISK_EVENT_MEDIA_CHANGE;
	p->private_data = disk;

	blk_queue_max_hw_sectors(p->queue, cluster);
	blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH);

	if (disk->drive == -1) {
		for (disk->drive = 0; disk->drive <= 1; disk->drive++)
			if (pd_special_command(disk, pd_identify) == 0)
				return;
	} else if (pd_special_command(disk, pd_identify) == 0)
		return;
	disk->gd = NULL;
		for (disk->drive = 0; disk->drive <= 1; disk->drive++) {
			ret = pd_special_command(disk, pd_identify);
			if (ret == 0)
				break;
		}
	} else {
		ret = pd_special_command(disk, pd_identify);
	}
	if (ret)
		goto put_disk;
	set_capacity(disk->gd, disk->capacity);
	add_disk(disk->gd);
	return 0;
put_disk:
	put_disk(p);
	disk->gd = NULL;
free_tag_set:
	blk_mq_free_tag_set(&disk->tag_set);
pi_release:
	pi_release(disk->pi);
	return ret;
}

static int pd_detect(void)
static int __init pd_init(void)
{
	int found = 0, unit, pd_drive_count = 0;
	struct pd_unit *disk;

	for (unit = 0; unit < PD_UNITS; unit++) {
		int *parm = *drives[unit];
		struct pd_unit *disk = pd + unit;
		disk->pi = &disk->pia;
		disk->access = 0;
		disk->changed = 1;
		disk->capacity = 0;
		disk->drive = parm[D_SLV];
		snprintf(disk->name, PD_NAMELEN, "%s%c", name, 'a'+unit);
		disk->alt_geom = parm[D_GEO];
		disk->standby = parm[D_SBY];
		if (parm[D_PRT])
			pd_drive_count++;
		INIT_LIST_HEAD(&disk->rq_list);
	}
	if (disable)
		return -ENODEV;

	if (register_blkdev(major, name))
		return -ENODEV;

	printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
	       name, name, PD_VERSION, major, cluster, nice);

	par_drv = pi_register_driver(name);
	if (!par_drv) {
		pr_err("failed to register %s driver\n", name);
		return -1;
		goto out_unregister_blkdev;
	}

	if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
		disk = pd;
		if (pi_init(disk->pi, 1, -1, -1, -1, -1, -1, pd_scratch,
			    PI_PD, verbose, disk->name)) {
			pd_probe_drive(disk);
			if (!disk->gd)
				pi_release(disk->pi);
	for (unit = 0; unit < PD_UNITS; unit++) {
		int *parm = *drives[unit];

		if (parm[D_PRT])
			pd_drive_count++;
	}

	if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
		if (!pd_probe_drive(pd, 1, -1, -1, -1, -1, -1))
			found++;
	} else {
		for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
			int *parm = *drives[unit];
			if (!parm[D_PRT])
				continue;
			if (pi_init(disk->pi, 0, parm[D_PRT], parm[D_MOD],
				     parm[D_UNI], parm[D_PRO], parm[D_DLY],
				     pd_scratch, PI_PD, verbose, disk->name)) {
				pd_probe_drive(disk);
				if (!disk->gd)
					pi_release(disk->pi);
			}
		}
	}
	for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
		if (disk->gd) {
			set_capacity(disk->gd, disk->capacity);
			add_disk(disk->gd);
			found = 1;
			if (!pd_probe_drive(disk, 0, parm[D_PRT], parm[D_MOD],
					parm[D_UNI], parm[D_PRO], parm[D_DLY]))
				found++;
		}
	}
	if (!found) {
		printk("%s: no valid drive found\n", name);
		pi_unregister_driver(par_drv);
	}
	return found;
		goto out_pi_unregister_driver;
	}

static int __init pd_init(void)
{
	if (disable)
		goto out1;

	if (register_blkdev(major, name))
		goto out1;

	printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
	       name, name, PD_VERSION, major, cluster, nice);
	if (!pd_detect())
		goto out2;

	return 0;

out2:
out_pi_unregister_driver:
	pi_unregister_driver(par_drv);
out_unregister_blkdev:
	unregister_blkdev(major, name);
out1:
	return -ENODEV;
}