aboutsummaryrefslogtreecommitdiffstats
path: root/block/genhd.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/genhd.c')
-rw-r--r--block/genhd.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 93a2cf654597..863a8c0623ed 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -423,7 +423,10 @@ static ssize_t disk_size_read(struct gendisk * disk, char *page)
423{ 423{
424 return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk)); 424 return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
425} 425}
426 426static ssize_t disk_capability_read(struct gendisk *disk, char *page)
427{
428 return sprintf(page, "%x\n", disk->flags);
429}
427static ssize_t disk_stats_read(struct gendisk * disk, char *page) 430static ssize_t disk_stats_read(struct gendisk * disk, char *page)
428{ 431{
429 preempt_disable(); 432 preempt_disable();
@@ -466,6 +469,10 @@ static struct disk_attribute disk_attr_size = {
466 .attr = {.name = "size", .mode = S_IRUGO }, 469 .attr = {.name = "size", .mode = S_IRUGO },
467 .show = disk_size_read 470 .show = disk_size_read
468}; 471};
472static struct disk_attribute disk_attr_capability = {
473 .attr = {.name = "capability", .mode = S_IRUGO },
474 .show = disk_capability_read
475};
469static struct disk_attribute disk_attr_stat = { 476static struct disk_attribute disk_attr_stat = {
470 .attr = {.name = "stat", .mode = S_IRUGO }, 477 .attr = {.name = "stat", .mode = S_IRUGO },
471 .show = disk_stats_read 478 .show = disk_stats_read
@@ -506,6 +513,7 @@ static struct attribute * default_attrs[] = {
506 &disk_attr_removable.attr, 513 &disk_attr_removable.attr,
507 &disk_attr_size.attr, 514 &disk_attr_size.attr,
508 &disk_attr_stat.attr, 515 &disk_attr_stat.attr,
516 &disk_attr_capability.attr,
509#ifdef CONFIG_FAIL_MAKE_REQUEST 517#ifdef CONFIG_FAIL_MAKE_REQUEST
510 &disk_attr_fail.attr, 518 &disk_attr_fail.attr,
511#endif 519#endif
@@ -688,6 +696,27 @@ struct seq_operations diskstats_op = {
688 .show = diskstats_show 696 .show = diskstats_show
689}; 697};
690 698
699static void media_change_notify_thread(struct work_struct *work)
700{
701 struct gendisk *gd = container_of(work, struct gendisk, async_notify);
702 char event[] = "MEDIA_CHANGE=1";
703 char *envp[] = { event, NULL };
704
705 /*
706 * set enviroment vars to indicate which event this is for
707 * so that user space will know to go check the media status.
708 */
709 kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp);
710 put_device(gd->driverfs_dev);
711}
712
713void genhd_media_change_notify(struct gendisk *disk)
714{
715 get_device(disk->driverfs_dev);
716 schedule_work(&disk->async_notify);
717}
718EXPORT_SYMBOL_GPL(genhd_media_change_notify);
719
691struct gendisk *alloc_disk(int minors) 720struct gendisk *alloc_disk(int minors)
692{ 721{
693 return alloc_disk_node(minors, -1); 722 return alloc_disk_node(minors, -1);
@@ -717,6 +746,8 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
717 kobj_set_kset_s(disk,block_subsys); 746 kobj_set_kset_s(disk,block_subsys);
718 kobject_init(&disk->kobj); 747 kobject_init(&disk->kobj);
719 rand_initialize_disk(disk); 748 rand_initialize_disk(disk);
749 INIT_WORK(&disk->async_notify,
750 media_change_notify_thread);
720 } 751 }
721 return disk; 752 return disk;
722} 753}