pf: cleanup initialization
Refactor the pf initialization to have a dedicated helper to initialize a single disk. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
af761f277b
commit
fb367e6bae
@ -214,7 +214,6 @@ static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo);
|
||||
|
||||
static void pf_release(struct gendisk *disk, fmode_t mode);
|
||||
|
||||
static int pf_detect(void);
|
||||
static void do_pf_read(void);
|
||||
static void do_pf_read_start(void);
|
||||
static void do_pf_write(void);
|
||||
@ -285,45 +284,6 @@ static const struct blk_mq_ops pf_mq_ops = {
|
||||
.queue_rq = pf_queue_rq,
|
||||
};
|
||||
|
||||
static void __init pf_init_units(void)
|
||||
{
|
||||
struct pf_unit *pf;
|
||||
int unit;
|
||||
|
||||
pf_drive_count = 0;
|
||||
for (unit = 0, pf = units; unit < PF_UNITS; unit++, pf++) {
|
||||
struct gendisk *disk;
|
||||
|
||||
if (blk_mq_alloc_sq_tag_set(&pf->tag_set, &pf_mq_ops, 1,
|
||||
BLK_MQ_F_SHOULD_MERGE))
|
||||
continue;
|
||||
|
||||
disk = blk_mq_alloc_disk(&pf->tag_set, pf);
|
||||
if (IS_ERR(disk)) {
|
||||
blk_mq_free_tag_set(&pf->tag_set);
|
||||
continue;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&pf->rq_list);
|
||||
blk_queue_max_segments(disk->queue, cluster);
|
||||
blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH);
|
||||
pf->disk = disk;
|
||||
pf->pi = &pf->pia;
|
||||
pf->media_status = PF_NM;
|
||||
pf->drive = (*drives[unit])[D_SLV];
|
||||
pf->lun = (*drives[unit])[D_LUN];
|
||||
snprintf(pf->name, PF_NAMELEN, "%s%d", name, unit);
|
||||
disk->major = major;
|
||||
disk->first_minor = unit;
|
||||
disk->minors = 1;
|
||||
strcpy(disk->disk_name, pf->name);
|
||||
disk->fops = &pf_fops;
|
||||
disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
if (!(*drives[unit])[D_PRT])
|
||||
pf_drive_count++;
|
||||
}
|
||||
}
|
||||
|
||||
static int pf_open(struct block_device *bdev, fmode_t mode)
|
||||
{
|
||||
struct pf_unit *pf = bdev->bd_disk->private_data;
|
||||
@ -718,59 +678,6 @@ static int pf_probe(struct pf_unit *pf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int pf_detect(void)
|
||||
{
|
||||
struct pf_unit *pf = units;
|
||||
int k, unit;
|
||||
|
||||
printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
|
||||
name, name, PF_VERSION, major, cluster, nice);
|
||||
|
||||
par_drv = pi_register_driver(name);
|
||||
if (!par_drv) {
|
||||
pr_err("failed to register %s driver\n", name);
|
||||
return -1;
|
||||
}
|
||||
k = 0;
|
||||
if (pf_drive_count == 0) {
|
||||
if (pi_init(pf->pi, 1, -1, -1, -1, -1, -1, pf_scratch, PI_PF,
|
||||
verbose, pf->name)) {
|
||||
if (!pf_probe(pf) && pf->disk) {
|
||||
pf->present = 1;
|
||||
k++;
|
||||
} else
|
||||
pi_release(pf->pi);
|
||||
}
|
||||
|
||||
} else
|
||||
for (unit = 0; unit < PF_UNITS; unit++, pf++) {
|
||||
int *conf = *drives[unit];
|
||||
if (!conf[D_PRT])
|
||||
continue;
|
||||
if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD],
|
||||
conf[D_UNI], conf[D_PRO], conf[D_DLY],
|
||||
pf_scratch, PI_PF, verbose, pf->name)) {
|
||||
if (pf->disk && !pf_probe(pf)) {
|
||||
pf->present = 1;
|
||||
k++;
|
||||
} else
|
||||
pi_release(pf->pi);
|
||||
}
|
||||
}
|
||||
if (k)
|
||||
return 0;
|
||||
|
||||
printk("%s: No ATAPI disk detected\n", name);
|
||||
for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
|
||||
if (!pf->disk)
|
||||
continue;
|
||||
blk_cleanup_disk(pf->disk);
|
||||
blk_mq_free_tag_set(&pf->tag_set);
|
||||
}
|
||||
pi_unregister_driver(par_drv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The i/o request engine */
|
||||
|
||||
static int pf_start(struct pf_unit *pf, int cmd, int b, int c)
|
||||
@ -1014,61 +921,129 @@ static void do_pf_write_done(void)
|
||||
next_request(0);
|
||||
}
|
||||
|
||||
static int __init pf_init_unit(struct pf_unit *pf, bool autoprobe, int port,
|
||||
int mode, int unit, int protocol, int delay, int ms)
|
||||
{
|
||||
struct gendisk *disk;
|
||||
int ret;
|
||||
|
||||
ret = blk_mq_alloc_sq_tag_set(&pf->tag_set, &pf_mq_ops, 1,
|
||||
BLK_MQ_F_SHOULD_MERGE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
disk = blk_mq_alloc_disk(&pf->tag_set, pf);
|
||||
if (IS_ERR(disk)) {
|
||||
ret = PTR_ERR(disk);
|
||||
goto out_free_tag_set;
|
||||
}
|
||||
disk->major = major;
|
||||
disk->first_minor = pf - units;
|
||||
disk->minors = 1;
|
||||
strcpy(disk->disk_name, pf->name);
|
||||
disk->fops = &pf_fops;
|
||||
disk->events = DISK_EVENT_MEDIA_CHANGE;
|
||||
disk->private_data = pf;
|
||||
|
||||
blk_queue_max_segments(disk->queue, cluster);
|
||||
blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH);
|
||||
|
||||
INIT_LIST_HEAD(&pf->rq_list);
|
||||
pf->disk = disk;
|
||||
pf->pi = &pf->pia;
|
||||
pf->media_status = PF_NM;
|
||||
pf->drive = (*drives[disk->first_minor])[D_SLV];
|
||||
pf->lun = (*drives[disk->first_minor])[D_LUN];
|
||||
snprintf(pf->name, PF_NAMELEN, "%s%d", name, disk->first_minor);
|
||||
|
||||
if (!pi_init(pf->pi, autoprobe, port, mode, unit, protocol, delay,
|
||||
pf_scratch, PI_PF, verbose, pf->name))
|
||||
goto out_free_disk;
|
||||
if (pf_probe(pf))
|
||||
goto out_pi_release;
|
||||
|
||||
add_disk(disk);
|
||||
pf->present = 1;
|
||||
return 0;
|
||||
|
||||
out_pi_release:
|
||||
pi_release(pf->pi);
|
||||
out_free_disk:
|
||||
blk_cleanup_disk(pf->disk);
|
||||
out_free_tag_set:
|
||||
blk_mq_free_tag_set(&pf->tag_set);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init pf_init(void)
|
||||
{ /* preliminary initialisation */
|
||||
struct pf_unit *pf;
|
||||
int unit;
|
||||
int found = 0, unit;
|
||||
|
||||
if (disable)
|
||||
return -EINVAL;
|
||||
|
||||
pf_init_units();
|
||||
|
||||
if (pf_detect())
|
||||
return -ENODEV;
|
||||
pf_busy = 0;
|
||||
|
||||
if (register_blkdev(major, name)) {
|
||||
for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
|
||||
if (!pf->disk)
|
||||
continue;
|
||||
blk_cleanup_queue(pf->disk->queue);
|
||||
blk_mq_free_tag_set(&pf->tag_set);
|
||||
put_disk(pf->disk);
|
||||
}
|
||||
if (register_blkdev(major, name))
|
||||
return -EBUSY;
|
||||
|
||||
printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
|
||||
name, name, PF_VERSION, major, cluster, nice);
|
||||
|
||||
par_drv = pi_register_driver(name);
|
||||
if (!par_drv) {
|
||||
pr_err("failed to register %s driver\n", name);
|
||||
goto out_unregister_blkdev;
|
||||
}
|
||||
|
||||
for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
|
||||
struct gendisk *disk = pf->disk;
|
||||
|
||||
if (!pf->present)
|
||||
continue;
|
||||
disk->private_data = pf;
|
||||
add_disk(disk);
|
||||
for (unit = 0; unit < PF_UNITS; unit++) {
|
||||
if (!(*drives[unit])[D_PRT])
|
||||
pf_drive_count++;
|
||||
}
|
||||
|
||||
pf = units;
|
||||
if (pf_drive_count == 0) {
|
||||
if (pf_init_unit(pf, 1, -1, -1, -1, -1, -1, verbose))
|
||||
found++;
|
||||
} else {
|
||||
for (unit = 0; unit < PF_UNITS; unit++, pf++) {
|
||||
int *conf = *drives[unit];
|
||||
if (!conf[D_PRT])
|
||||
continue;
|
||||
if (pf_init_unit(pf, 0, conf[D_PRT], conf[D_MOD],
|
||||
conf[D_UNI], conf[D_PRO], conf[D_DLY],
|
||||
verbose))
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
printk("%s: No ATAPI disk detected\n", name);
|
||||
goto out_unregister_pi_driver;
|
||||
}
|
||||
pf_busy = 0;
|
||||
return 0;
|
||||
|
||||
out_unregister_pi_driver:
|
||||
pi_unregister_driver(par_drv);
|
||||
out_unregister_blkdev:
|
||||
unregister_blkdev(major, name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit pf_exit(void)
|
||||
{
|
||||
struct pf_unit *pf;
|
||||
int unit;
|
||||
unregister_blkdev(major, name);
|
||||
|
||||
for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
|
||||
if (!pf->disk)
|
||||
if (!pf->present)
|
||||
continue;
|
||||
|
||||
if (pf->present)
|
||||
del_gendisk(pf->disk);
|
||||
|
||||
blk_cleanup_queue(pf->disk->queue);
|
||||
del_gendisk(pf->disk);
|
||||
blk_cleanup_disk(pf->disk);
|
||||
blk_mq_free_tag_set(&pf->tag_set);
|
||||
put_disk(pf->disk);
|
||||
|
||||
if (pf->present)
|
||||
pi_release(pf->pi);
|
||||
pi_release(pf->pi);
|
||||
}
|
||||
|
||||
unregister_blkdev(major, name);
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
Loading…
Reference in New Issue
Block a user