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 = { ...@@ -875,9 +875,27 @@ static const struct blk_mq_ops pd_mq_ops = {
.queue_rq = pd_queue_rq, .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; 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)); memset(&disk->tag_set, 0, sizeof(disk->tag_set));
disk->tag_set.ops = &pd_mq_ops; disk->tag_set.ops = &pd_mq_ops;
...@@ -887,14 +905,14 @@ static void pd_probe_drive(struct pd_unit *disk) ...@@ -887,14 +905,14 @@ static void pd_probe_drive(struct pd_unit *disk)
disk->tag_set.queue_depth = 2; disk->tag_set.queue_depth = 2;
disk->tag_set.numa_node = NUMA_NO_NODE; disk->tag_set.numa_node = NUMA_NO_NODE;
disk->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING; disk->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING;
ret = blk_mq_alloc_tag_set(&disk->tag_set);
if (blk_mq_alloc_tag_set(&disk->tag_set)) if (ret)
return; goto pi_release;
p = blk_mq_alloc_disk(&disk->tag_set, disk); p = blk_mq_alloc_disk(&disk->tag_set, disk);
if (IS_ERR(p)) { if (IS_ERR(p)) {
blk_mq_free_tag_set(&disk->tag_set); ret = PTR_ERR(p);
return; goto free_tag_set;
} }
disk->gd = p; disk->gd = p;
...@@ -905,102 +923,84 @@ static void pd_probe_drive(struct pd_unit *disk) ...@@ -905,102 +923,84 @@ static void pd_probe_drive(struct pd_unit *disk)
p->minors = 1 << PD_BITS; p->minors = 1 << PD_BITS;
p->events = DISK_EVENT_MEDIA_CHANGE; p->events = DISK_EVENT_MEDIA_CHANGE;
p->private_data = disk; p->private_data = disk;
blk_queue_max_hw_sectors(p->queue, cluster); blk_queue_max_hw_sectors(p->queue, cluster);
blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH); blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH);
if (disk->drive == -1) { if (disk->drive == -1) {
for (disk->drive = 0; disk->drive <= 1; disk->drive++) for (disk->drive = 0; disk->drive <= 1; disk->drive++) {
if (pd_special_command(disk, pd_identify) == 0) ret = pd_special_command(disk, pd_identify);
return; if (ret == 0)
} else if (pd_special_command(disk, pd_identify) == 0) break;
return; }
disk->gd = NULL; } 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); 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; int found = 0, unit, pd_drive_count = 0;
struct pd_unit *disk; struct pd_unit *disk;
for (unit = 0; unit < PD_UNITS; unit++) { if (disable)
int *parm = *drives[unit]; return -ENODEV;
struct pd_unit *disk = pd + unit;
disk->pi = &disk->pia; if (register_blkdev(major, name))
disk->access = 0; return -ENODEV;
disk->changed = 1;
disk->capacity = 0; printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
disk->drive = parm[D_SLV]; name, name, PD_VERSION, major, cluster, nice);
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);
}
par_drv = pi_register_driver(name); par_drv = pi_register_driver(name);
if (!par_drv) { if (!par_drv) {
pr_err("failed to register %s driver\n", name); 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 */ for (unit = 0; unit < PD_UNITS; unit++) {
disk = pd; int *parm = *drives[unit];
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);
}
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 { } else {
for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) { for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
int *parm = *drives[unit]; int *parm = *drives[unit];
if (!parm[D_PRT]) if (!parm[D_PRT])
continue; continue;
if (pi_init(disk->pi, 0, parm[D_PRT], parm[D_MOD], if (!pd_probe_drive(disk, 0, parm[D_PRT], parm[D_MOD],
parm[D_UNI], parm[D_PRO], parm[D_DLY], parm[D_UNI], parm[D_PRO], parm[D_DLY]))
pd_scratch, PI_PD, verbose, disk->name)) { found++;
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 (!found) { if (!found) {
printk("%s: no valid drive found\n", name); 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; return 0;
out2: out_pi_unregister_driver:
pi_unregister_driver(par_drv);
out_unregister_blkdev:
unregister_blkdev(major, name); unregister_blkdev(major, name);
out1:
return -ENODEV; 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