parport/pd: stop sharing request queue across multiple gendisks

Compile-tested only.

Cc: Tim Waugh <tim@cyberelk.net>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
Omar Sandoval 2017-03-27 23:28:43 -07:00 committed by Jens Axboe
parent a893cd76bb
commit eaf487ca30
1 changed files with 34 additions and 16 deletions

View File

@ -381,12 +381,33 @@ static enum action do_pd_write_start(void);
static enum action do_pd_read_drq(void);
static enum action do_pd_write_done(void);
static struct request_queue *pd_queue;
static int pd_queue;
static int pd_claimed;
static struct pd_unit *pd_current; /* current request's drive */
static PIA *pi_current; /* current request's PIA */
static int set_next_request(void)
{
struct gendisk *disk;
struct request_queue *q;
int old_pos = pd_queue;
do {
disk = pd[pd_queue].gd;
q = disk ? disk->queue : NULL;
if (++pd_queue == PD_UNITS)
pd_queue = 0;
if (q) {
pd_req = blk_fetch_request(q);
if (pd_req)
break;
}
} while (pd_queue != old_pos);
return pd_req != NULL;
}
static void run_fsm(void)
{
while (1) {
@ -418,8 +439,7 @@ static void run_fsm(void)
spin_lock_irqsave(&pd_lock, saved_flags);
if (!__blk_end_request_cur(pd_req,
res == Ok ? 0 : -EIO)) {
pd_req = blk_fetch_request(pd_queue);
if (!pd_req)
if (!set_next_request())
stop = 1;
}
spin_unlock_irqrestore(&pd_lock, saved_flags);
@ -839,7 +859,13 @@ static void pd_probe_drive(struct pd_unit *disk)
p->first_minor = (disk - pd) << PD_BITS;
disk->gd = p;
p->private_data = disk;
p->queue = pd_queue;
p->queue = blk_init_queue(do_pd_request, &pd_lock);
if (!p->queue) {
disk->gd = NULL;
put_disk(p);
return;
}
blk_queue_max_hw_sectors(p->queue, cluster);
if (disk->drive == -1) {
for (disk->drive = 0; disk->drive <= 1; disk->drive++)
@ -919,26 +945,18 @@ static int __init pd_init(void)
if (disable)
goto out1;
pd_queue = blk_init_queue(do_pd_request, &pd_lock);
if (!pd_queue)
goto out1;
blk_queue_max_hw_sectors(pd_queue, cluster);
if (register_blkdev(major, name))
goto out2;
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 out3;
goto out2;
return 0;
out3:
unregister_blkdev(major, name);
out2:
blk_cleanup_queue(pd_queue);
unregister_blkdev(major, name);
out1:
return -ENODEV;
}
@ -953,11 +971,11 @@ static void __exit pd_exit(void)
if (p) {
disk->gd = NULL;
del_gendisk(p);
blk_cleanup_queue(p->queue);
put_disk(p);
pi_release(disk->pi);
}
}
blk_cleanup_queue(pd_queue);
}
MODULE_LICENSE("GPL");