aboutsummaryrefslogtreecommitdiffstats
path: root/block/bsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/bsg.c')
-rw-r--r--block/bsg.c52
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)
705static int bsg_put_device(struct bsg_device *bd) 702static 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);
731out: 729out:
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
766static struct bsg_device *__bsg_get_device(int minor) 769static 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;
783found:
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
809static int bsg_open(struct inode *inode, struct file *file) 816static 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}
948EXPORT_SYMBOL_GPL(bsg_unregister_queue); 954EXPORT_SYMBOL_GPL(bsg_unregister_queue);