diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/bsg.c | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/block/bsg.c b/block/bsg.c index 8917c5174dc2..302ac1f5af39 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -37,7 +37,6 @@ struct bsg_device { | |||
37 | struct list_head done_list; | 37 | struct list_head done_list; |
38 | struct hlist_node dev_list; | 38 | struct hlist_node dev_list; |
39 | atomic_t ref_count; | 39 | atomic_t ref_count; |
40 | int minor; | ||
41 | int queued_cmds; | 40 | int queued_cmds; |
42 | int done_cmds; | 41 | int done_cmds; |
43 | wait_queue_head_t wq_done; | 42 | wait_queue_head_t wq_done; |
@@ -368,7 +367,7 @@ static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd) | |||
368 | 367 | ||
369 | spin_lock_irq(&bd->lock); | 368 | spin_lock_irq(&bd->lock); |
370 | if (bd->done_cmds) { | 369 | if (bd->done_cmds) { |
371 | bc = list_entry(bd->done_list.next, struct bsg_command, list); | 370 | bc = list_first_entry(&bd->done_list, struct bsg_command, list); |
372 | list_del(&bc->list); | 371 | list_del(&bc->list); |
373 | bd->done_cmds--; | 372 | bd->done_cmds--; |
374 | } | 373 | } |
@@ -468,8 +467,6 @@ static int bsg_complete_all_commands(struct bsg_device *bd) | |||
468 | 467 | ||
469 | dprintk("%s: entered\n", bd->name); | 468 | dprintk("%s: entered\n", bd->name); |
470 | 469 | ||
471 | set_bit(BSG_F_BLOCK, &bd->flags); | ||
472 | |||
473 | /* | 470 | /* |
474 | * wait for all commands to complete | 471 | * wait for all commands to complete |
475 | */ | 472 | */ |
@@ -705,6 +702,7 @@ static struct bsg_device *bsg_alloc_device(void) | |||
705 | static int bsg_put_device(struct bsg_device *bd) | 702 | static int bsg_put_device(struct bsg_device *bd) |
706 | { | 703 | { |
707 | int ret = 0; | 704 | int ret = 0; |
705 | struct device *dev = bd->queue->bsg_dev.dev; | ||
708 | 706 | ||
709 | mutex_lock(&bsg_mutex); | 707 | mutex_lock(&bsg_mutex); |
710 | 708 | ||
@@ -730,6 +728,7 @@ static int bsg_put_device(struct bsg_device *bd) | |||
730 | kfree(bd); | 728 | kfree(bd); |
731 | out: | 729 | out: |
732 | mutex_unlock(&bsg_mutex); | 730 | mutex_unlock(&bsg_mutex); |
731 | put_device(dev); | ||
733 | return ret; | 732 | return ret; |
734 | } | 733 | } |
735 | 734 | ||
@@ -738,22 +737,26 @@ static struct bsg_device *bsg_add_device(struct inode *inode, | |||
738 | struct file *file) | 737 | struct file *file) |
739 | { | 738 | { |
740 | struct bsg_device *bd; | 739 | struct bsg_device *bd; |
740 | int ret; | ||
741 | #ifdef BSG_DEBUG | 741 | #ifdef BSG_DEBUG |
742 | unsigned char buf[32]; | 742 | unsigned char buf[32]; |
743 | #endif | 743 | #endif |
744 | ret = blk_get_queue(rq); | ||
745 | if (ret) | ||
746 | return ERR_PTR(-ENXIO); | ||
744 | 747 | ||
745 | bd = bsg_alloc_device(); | 748 | bd = bsg_alloc_device(); |
746 | if (!bd) | 749 | if (!bd) { |
750 | blk_put_queue(rq); | ||
747 | return ERR_PTR(-ENOMEM); | 751 | return ERR_PTR(-ENOMEM); |
752 | } | ||
748 | 753 | ||
749 | bd->queue = rq; | 754 | bd->queue = rq; |
750 | kobject_get(&rq->kobj); | ||
751 | bsg_set_block(bd, file); | 755 | bsg_set_block(bd, file); |
752 | 756 | ||
753 | atomic_set(&bd->ref_count, 1); | 757 | atomic_set(&bd->ref_count, 1); |
754 | bd->minor = iminor(inode); | ||
755 | mutex_lock(&bsg_mutex); | 758 | mutex_lock(&bsg_mutex); |
756 | hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(bd->minor)); | 759 | hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode))); |
757 | 760 | ||
758 | strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1); | 761 | strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1); |
759 | dprintk("bound to <%s>, max queue %d\n", | 762 | dprintk("bound to <%s>, max queue %d\n", |
@@ -763,23 +766,21 @@ static struct bsg_device *bsg_add_device(struct inode *inode, | |||
763 | return bd; | 766 | return bd; |
764 | } | 767 | } |
765 | 768 | ||
766 | static struct bsg_device *__bsg_get_device(int minor) | 769 | static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q) |
767 | { | 770 | { |
768 | struct bsg_device *bd = NULL; | 771 | struct bsg_device *bd; |
769 | struct hlist_node *entry; | 772 | struct hlist_node *entry; |
770 | 773 | ||
771 | mutex_lock(&bsg_mutex); | 774 | mutex_lock(&bsg_mutex); |
772 | 775 | ||
773 | hlist_for_each(entry, bsg_dev_idx_hash(minor)) { | 776 | hlist_for_each_entry(bd, entry, bsg_dev_idx_hash(minor), dev_list) { |
774 | bd = hlist_entry(entry, struct bsg_device, dev_list); | 777 | if (bd->queue == q) { |
775 | if (bd->minor == minor) { | ||
776 | atomic_inc(&bd->ref_count); | 778 | atomic_inc(&bd->ref_count); |
777 | break; | 779 | goto found; |
778 | } | 780 | } |
779 | |||
780 | bd = NULL; | ||
781 | } | 781 | } |
782 | 782 | bd = NULL; | |
783 | found: | ||
783 | mutex_unlock(&bsg_mutex); | 784 | mutex_unlock(&bsg_mutex); |
784 | return bd; | 785 | return bd; |
785 | } | 786 | } |
@@ -789,21 +790,27 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) | |||
789 | struct bsg_device *bd; | 790 | struct bsg_device *bd; |
790 | struct bsg_class_device *bcd; | 791 | struct bsg_class_device *bcd; |
791 | 792 | ||
792 | bd = __bsg_get_device(iminor(inode)); | ||
793 | if (bd) | ||
794 | return bd; | ||
795 | |||
796 | /* | 793 | /* |
797 | * find the class device | 794 | * find the class device |
798 | */ | 795 | */ |
799 | mutex_lock(&bsg_mutex); | 796 | mutex_lock(&bsg_mutex); |
800 | bcd = idr_find(&bsg_minor_idr, iminor(inode)); | 797 | bcd = idr_find(&bsg_minor_idr, iminor(inode)); |
798 | if (bcd) | ||
799 | get_device(bcd->dev); | ||
801 | mutex_unlock(&bsg_mutex); | 800 | mutex_unlock(&bsg_mutex); |
802 | 801 | ||
803 | if (!bcd) | 802 | if (!bcd) |
804 | return ERR_PTR(-ENODEV); | 803 | return ERR_PTR(-ENODEV); |
805 | 804 | ||
806 | return bsg_add_device(inode, bcd->queue, file); | 805 | bd = __bsg_get_device(iminor(inode), bcd->queue); |
806 | if (bd) | ||
807 | return bd; | ||
808 | |||
809 | bd = bsg_add_device(inode, bcd->queue, file); | ||
810 | if (IS_ERR(bd)) | ||
811 | put_device(bcd->dev); | ||
812 | |||
813 | return bd; | ||
807 | } | 814 | } |
808 | 815 | ||
809 | static int bsg_open(struct inode *inode, struct file *file) | 816 | static int bsg_open(struct inode *inode, struct file *file) |
@@ -942,7 +949,6 @@ void bsg_unregister_queue(struct request_queue *q) | |||
942 | class_device_unregister(bcd->class_dev); | 949 | class_device_unregister(bcd->class_dev); |
943 | put_device(bcd->dev); | 950 | put_device(bcd->dev); |
944 | bcd->class_dev = NULL; | 951 | bcd->class_dev = NULL; |
945 | bcd->dev = NULL; | ||
946 | mutex_unlock(&bsg_mutex); | 952 | mutex_unlock(&bsg_mutex); |
947 | } | 953 | } |
948 | EXPORT_SYMBOL_GPL(bsg_unregister_queue); | 954 | EXPORT_SYMBOL_GPL(bsg_unregister_queue); |