aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-05-06 17:51:29 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-07 15:13:02 -0400
commit2e3f5251ac716879df6b6271f243f657c6e02e9a (patch)
tree2395a370a84775541aa9c4a05b51b1d3c46eeae3
parentd8839354a04181b4cc95cebf7f7622cf336bd58e (diff)
uml: drivers get release methods
Define release methods for the ubd and net drivers. They contain as much of the remove methods as make sense. All error checking must have already been done as well as anything else that might be holding a reference on the device kobject. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/um/drivers/net_kern.c19
-rw-r--r--arch/um/drivers/ubd_kern.c17
2 files changed, 27 insertions, 9 deletions
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index b2c292a66218..baac4ad5e68e 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -341,6 +341,19 @@ static struct platform_driver uml_net_driver = {
341}; 341};
342static int driver_registered; 342static int driver_registered;
343 343
344static void net_device_release(struct device *dev)
345{
346 struct uml_net *device = dev->driver_data;
347 struct net_device *netdev = device->dev;
348 struct uml_net_private *lp = netdev->priv;
349
350 if(lp->remove != NULL)
351 (*lp->remove)(&lp->user);
352 list_del(&device->list);
353 kfree(device);
354 free_netdev(netdev);
355}
356
344static void eth_configure(int n, void *init, char *mac, 357static void eth_configure(int n, void *init, char *mac,
345 struct transport *transport) 358 struct transport *transport)
346{ 359{
@@ -396,6 +409,8 @@ static void eth_configure(int n, void *init, char *mac,
396 } 409 }
397 device->pdev.id = n; 410 device->pdev.id = n;
398 device->pdev.name = DRIVER_NAME; 411 device->pdev.name = DRIVER_NAME;
412 device->pdev.dev.release = net_device_release;
413 device->pdev.dev.driver_data = device;
399 if(platform_device_register(&device->pdev)) 414 if(platform_device_register(&device->pdev))
400 goto out_free_netdev; 415 goto out_free_netdev;
401 SET_NETDEV_DEV(dev,&device->pdev.dev); 416 SET_NETDEV_DEV(dev,&device->pdev.dev);
@@ -689,13 +704,9 @@ static int net_remove(int n, char **error_out)
689 lp = dev->priv; 704 lp = dev->priv;
690 if(lp->fd > 0) 705 if(lp->fd > 0)
691 return -EBUSY; 706 return -EBUSY;
692 if(lp->remove != NULL) (*lp->remove)(&lp->user);
693 unregister_netdev(dev); 707 unregister_netdev(dev);
694 platform_device_unregister(&device->pdev); 708 platform_device_unregister(&device->pdev);
695 709
696 list_del(&device->list);
697 kfree(device);
698 free_netdev(dev);
699 return 0; 710 return 0;
700} 711}
701 712
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 962b8fb35f80..83189e188c3f 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -622,6 +622,14 @@ static int ubd_open_dev(struct ubd *ubd_dev)
622 return(err); 622 return(err);
623} 623}
624 624
625static void ubd_device_release(struct device *dev)
626{
627 struct ubd *ubd_dev = dev->driver_data;
628
629 blk_cleanup_queue(ubd_dev->queue);
630 *ubd_dev = ((struct ubd) DEFAULT_UBD);
631}
632
625static int ubd_disk_register(int major, u64 size, int unit, 633static int ubd_disk_register(int major, u64 size, int unit,
626 struct gendisk **disk_out) 634 struct gendisk **disk_out)
627{ 635{
@@ -644,6 +652,8 @@ static int ubd_disk_register(int major, u64 size, int unit,
644 if (major == MAJOR_NR) { 652 if (major == MAJOR_NR) {
645 ubd_devs[unit].pdev.id = unit; 653 ubd_devs[unit].pdev.id = unit;
646 ubd_devs[unit].pdev.name = DRIVER_NAME; 654 ubd_devs[unit].pdev.name = DRIVER_NAME;
655 ubd_devs[unit].pdev.dev.release = ubd_device_release;
656 ubd_devs[unit].pdev.dev.driver_data = &ubd_devs[unit];
647 platform_device_register(&ubd_devs[unit].pdev); 657 platform_device_register(&ubd_devs[unit].pdev);
648 disk->driverfs_dev = &ubd_devs[unit].pdev.dev; 658 disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
649 } 659 }
@@ -787,7 +797,7 @@ static int ubd_id(char **str, int *start_out, int *end_out)
787 797
788static int ubd_remove(int n, char **error_out) 798static int ubd_remove(int n, char **error_out)
789{ 799{
790 struct gendisk *disk; 800 struct gendisk *disk = ubd_gendisk[n];
791 struct ubd *ubd_dev; 801 struct ubd *ubd_dev;
792 int err = -ENODEV; 802 int err = -ENODEV;
793 803
@@ -803,7 +813,6 @@ static int ubd_remove(int n, char **error_out)
803 if(ubd_dev->count > 0) 813 if(ubd_dev->count > 0)
804 goto out; 814 goto out;
805 815
806 disk = ubd_gendisk[n];
807 ubd_gendisk[n] = NULL; 816 ubd_gendisk[n] = NULL;
808 if(disk != NULL){ 817 if(disk != NULL){
809 del_gendisk(disk); 818 del_gendisk(disk);
@@ -816,10 +825,8 @@ static int ubd_remove(int n, char **error_out)
816 fake_gendisk[n] = NULL; 825 fake_gendisk[n] = NULL;
817 } 826 }
818 827
819 blk_cleanup_queue(ubd_dev->queue);
820 platform_device_unregister(&ubd_dev->pdev);
821 *ubd_dev = ((struct ubd) DEFAULT_UBD);
822 err = 0; 828 err = 0;
829 platform_device_unregister(&ubd_dev->pdev);
823out: 830out:
824 mutex_unlock(&ubd_lock); 831 mutex_unlock(&ubd_lock);
825 return err; 832 return err;