Loading drivers/block/paride/pd.c +66 −28 Original line number Diff line number Diff line Loading @@ -151,7 +151,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV}; #include <linux/delay.h> #include <linux/hdreg.h> #include <linux/cdrom.h> /* for the eject ioctl */ #include <linux/blkdev.h> #include <linux/blk-mq.h> #include <linux/blkpg.h> #include <linux/kernel.h> #include <linux/mutex.h> Loading Loading @@ -236,6 +236,8 @@ struct pd_unit { int alt_geom; char name[PD_NAMELEN]; /* pda, pdb, etc ... */ struct gendisk *gd; struct blk_mq_tag_set tag_set; struct list_head rq_list; }; static struct pd_unit pd[PD_UNITS]; Loading Loading @@ -399,8 +401,16 @@ static int set_next_request(void) if (++pd_queue == PD_UNITS) pd_queue = 0; if (q) { pd_req = blk_fetch_request(q); if (pd_req) struct pd_unit *disk = q->queuedata; if (list_empty(&disk->rq_list)) continue; pd_req = list_first_entry(&disk->rq_list, struct request, queuelist); list_del_init(&pd_req->queuelist); blk_mq_start_request(pd_req); break; } } while (pd_queue != old_pos); Loading @@ -412,7 +422,6 @@ static void run_fsm(void) { while (1) { enum action res; unsigned long saved_flags; int stop = 0; if (!phase) { Loading @@ -433,19 +442,24 @@ static void run_fsm(void) } switch(res = phase()) { case Ok: case Fail: case Ok: case Fail: { blk_status_t err; err = res == Ok ? 0 : BLK_STS_IOERR; pi_disconnect(pi_current); pd_claimed = 0; phase = NULL; spin_lock_irqsave(&pd_lock, saved_flags); if (!__blk_end_request_cur(pd_req, res == Ok ? 0 : BLK_STS_IOERR)) { if (!set_next_request()) stop = 1; } spin_unlock_irqrestore(&pd_lock, saved_flags); spin_lock_irq(&pd_lock); if (!blk_update_request(pd_req, err, blk_rq_cur_bytes(pd_req))) { __blk_mq_end_request(pd_req, err); pd_req = NULL; stop = !set_next_request(); } spin_unlock_irq(&pd_lock); if (stop) return; } /* fall through */ case Hold: schedule_fsm(); Loading Loading @@ -505,11 +519,17 @@ static int pd_next_buf(void) if (pd_count) return 0; spin_lock_irqsave(&pd_lock, saved_flags); __blk_end_request_cur(pd_req, 0); if (!blk_update_request(pd_req, 0, blk_rq_cur_bytes(pd_req))) { __blk_mq_end_request(pd_req, 0); pd_req = NULL; pd_count = 0; pd_buf = NULL; } else { pd_count = blk_rq_cur_sectors(pd_req); pd_buf = bio_data(pd_req->bio); } spin_unlock_irqrestore(&pd_lock, saved_flags); return 0; return !pd_count; } static unsigned long pd_timeout; Loading Loading @@ -726,15 +746,21 @@ static enum action pd_identify(struct pd_unit *disk) /* end of io request engine */ static void do_pd_request(struct request_queue * q) static blk_status_t pd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { if (pd_req) return; pd_req = blk_fetch_request(q); if (!pd_req) return; struct pd_unit *disk = hctx->queue->queuedata; schedule_fsm(); spin_lock_irq(&pd_lock); if (!pd_req) { pd_req = bd->rq; blk_mq_start_request(pd_req); } else list_add_tail(&bd->rq->queuelist, &disk->rq_list); spin_unlock_irq(&pd_lock); run_fsm(); return BLK_STS_OK; } static int pd_special_command(struct pd_unit *disk, Loading Loading @@ -847,23 +873,33 @@ static const struct block_device_operations pd_fops = { /* probing */ static const struct blk_mq_ops pd_mq_ops = { .queue_rq = pd_queue_rq, }; static void pd_probe_drive(struct pd_unit *disk) { struct gendisk *p = alloc_disk(1 << PD_BITS); struct gendisk *p; p = alloc_disk(1 << PD_BITS); if (!p) return; strcpy(p->disk_name, disk->name); p->fops = &pd_fops; p->major = major; p->first_minor = (disk - pd) << PD_BITS; disk->gd = p; p->private_data = disk; p->queue = blk_init_queue(do_pd_request, &pd_lock); if (!p->queue) { disk->gd = NULL; put_disk(p); p->queue = blk_mq_init_sq_queue(&disk->tag_set, &pd_mq_ops, 2, BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING); if (IS_ERR(p->queue)) { p->queue = NULL; return; } p->queue->queuedata = disk; blk_queue_max_hw_sectors(p->queue, cluster); blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH); Loading Loading @@ -895,6 +931,7 @@ static int pd_detect(void) disk->standby = parm[D_SBY]; if (parm[D_PRT]) pd_drive_count++; INIT_LIST_HEAD(&disk->rq_list); } par_drv = pi_register_driver(name); Loading Loading @@ -972,6 +1009,7 @@ static void __exit pd_exit(void) disk->gd = NULL; del_gendisk(p); blk_cleanup_queue(p->queue); blk_mq_free_tag_set(&disk->tag_set); put_disk(p); pi_release(disk->pi); } Loading Loading
drivers/block/paride/pd.c +66 −28 Original line number Diff line number Diff line Loading @@ -151,7 +151,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV}; #include <linux/delay.h> #include <linux/hdreg.h> #include <linux/cdrom.h> /* for the eject ioctl */ #include <linux/blkdev.h> #include <linux/blk-mq.h> #include <linux/blkpg.h> #include <linux/kernel.h> #include <linux/mutex.h> Loading Loading @@ -236,6 +236,8 @@ struct pd_unit { int alt_geom; char name[PD_NAMELEN]; /* pda, pdb, etc ... */ struct gendisk *gd; struct blk_mq_tag_set tag_set; struct list_head rq_list; }; static struct pd_unit pd[PD_UNITS]; Loading Loading @@ -399,8 +401,16 @@ static int set_next_request(void) if (++pd_queue == PD_UNITS) pd_queue = 0; if (q) { pd_req = blk_fetch_request(q); if (pd_req) struct pd_unit *disk = q->queuedata; if (list_empty(&disk->rq_list)) continue; pd_req = list_first_entry(&disk->rq_list, struct request, queuelist); list_del_init(&pd_req->queuelist); blk_mq_start_request(pd_req); break; } } while (pd_queue != old_pos); Loading @@ -412,7 +422,6 @@ static void run_fsm(void) { while (1) { enum action res; unsigned long saved_flags; int stop = 0; if (!phase) { Loading @@ -433,19 +442,24 @@ static void run_fsm(void) } switch(res = phase()) { case Ok: case Fail: case Ok: case Fail: { blk_status_t err; err = res == Ok ? 0 : BLK_STS_IOERR; pi_disconnect(pi_current); pd_claimed = 0; phase = NULL; spin_lock_irqsave(&pd_lock, saved_flags); if (!__blk_end_request_cur(pd_req, res == Ok ? 0 : BLK_STS_IOERR)) { if (!set_next_request()) stop = 1; } spin_unlock_irqrestore(&pd_lock, saved_flags); spin_lock_irq(&pd_lock); if (!blk_update_request(pd_req, err, blk_rq_cur_bytes(pd_req))) { __blk_mq_end_request(pd_req, err); pd_req = NULL; stop = !set_next_request(); } spin_unlock_irq(&pd_lock); if (stop) return; } /* fall through */ case Hold: schedule_fsm(); Loading Loading @@ -505,11 +519,17 @@ static int pd_next_buf(void) if (pd_count) return 0; spin_lock_irqsave(&pd_lock, saved_flags); __blk_end_request_cur(pd_req, 0); if (!blk_update_request(pd_req, 0, blk_rq_cur_bytes(pd_req))) { __blk_mq_end_request(pd_req, 0); pd_req = NULL; pd_count = 0; pd_buf = NULL; } else { pd_count = blk_rq_cur_sectors(pd_req); pd_buf = bio_data(pd_req->bio); } spin_unlock_irqrestore(&pd_lock, saved_flags); return 0; return !pd_count; } static unsigned long pd_timeout; Loading Loading @@ -726,15 +746,21 @@ static enum action pd_identify(struct pd_unit *disk) /* end of io request engine */ static void do_pd_request(struct request_queue * q) static blk_status_t pd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { if (pd_req) return; pd_req = blk_fetch_request(q); if (!pd_req) return; struct pd_unit *disk = hctx->queue->queuedata; schedule_fsm(); spin_lock_irq(&pd_lock); if (!pd_req) { pd_req = bd->rq; blk_mq_start_request(pd_req); } else list_add_tail(&bd->rq->queuelist, &disk->rq_list); spin_unlock_irq(&pd_lock); run_fsm(); return BLK_STS_OK; } static int pd_special_command(struct pd_unit *disk, Loading Loading @@ -847,23 +873,33 @@ static const struct block_device_operations pd_fops = { /* probing */ static const struct blk_mq_ops pd_mq_ops = { .queue_rq = pd_queue_rq, }; static void pd_probe_drive(struct pd_unit *disk) { struct gendisk *p = alloc_disk(1 << PD_BITS); struct gendisk *p; p = alloc_disk(1 << PD_BITS); if (!p) return; strcpy(p->disk_name, disk->name); p->fops = &pd_fops; p->major = major; p->first_minor = (disk - pd) << PD_BITS; disk->gd = p; p->private_data = disk; p->queue = blk_init_queue(do_pd_request, &pd_lock); if (!p->queue) { disk->gd = NULL; put_disk(p); p->queue = blk_mq_init_sq_queue(&disk->tag_set, &pd_mq_ops, 2, BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING); if (IS_ERR(p->queue)) { p->queue = NULL; return; } p->queue->queuedata = disk; blk_queue_max_hw_sectors(p->queue, cluster); blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH); Loading Loading @@ -895,6 +931,7 @@ static int pd_detect(void) disk->standby = parm[D_SBY]; if (parm[D_PRT]) pd_drive_count++; INIT_LIST_HEAD(&disk->rq_list); } par_drv = pi_register_driver(name); Loading Loading @@ -972,6 +1009,7 @@ static void __exit pd_exit(void) disk->gd = NULL; del_gendisk(p); blk_cleanup_queue(p->queue); blk_mq_free_tag_set(&disk->tag_set); put_disk(p); pi_release(disk->pi); } Loading