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

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
......@@ -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);
goto out_pi_unregister_driver;
}
return found;
}
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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment