aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-17 12:09:13 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-17 12:09:13 -0400
commitc84d9bbe7c77aea7e1194da056d44a2ed982e72b (patch)
treec7b9ee5e2b94ba87a2124e731bd8281439c0fb5d
parentcedd120cac61fa149ba215eabc57b2578068be00 (diff)
ide-floppy: factor out generic disk handling code to ide-gd-floppy.c
While at it: - idefloppy_do_request() -> ide_floppy_do_request() - idefloppy_end_request() -> ide_floppy_end_request() - idefloppy_setup() -> ide_floppy_setup() There should be no functional changes caused by this patch. Acked-by: Borislav Petkov <petkovbb@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/Makefile2
-rw-r--r--drivers/ide/ide-floppy.c319
-rw-r--r--drivers/ide/ide-floppy.h19
-rw-r--r--drivers/ide/ide-gd-floppy.c298
4 files changed, 327 insertions, 311 deletions
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 8aad9395a427..7eeeab597959 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -39,7 +39,7 @@ obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
39 39
40ide-disk_mod-y += ide-gd.o ide-disk.o ide-disk_ioctl.o 40ide-disk_mod-y += ide-gd.o ide-disk.o ide-disk_ioctl.o
41ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o 41ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o
42ide-floppy_mod-y += ide-floppy.o ide-floppy_ioctl.o 42ide-floppy_mod-y += ide-gd-floppy.o ide-floppy.o ide-floppy_ioctl.o
43 43
44ifeq ($(CONFIG_IDE_PROC_FS), y) 44ifeq ($(CONFIG_IDE_PROC_FS), y)
45 ide-disk_mod-y += ide-disk_proc.o 45 ide-disk_mod-y += ide-disk_proc.o
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 791a9d6f371c..802e0968e32f 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -15,12 +15,6 @@
15 * Documentation/ide/ChangeLog.ide-floppy.1996-2002 15 * Documentation/ide/ChangeLog.ide-floppy.1996-2002
16 */ 16 */
17 17
18#define DRV_NAME "ide-floppy"
19#define PFX DRV_NAME ": "
20
21#define IDEFLOPPY_VERSION "1.00"
22
23#include <linux/module.h>
24#include <linux/types.h> 18#include <linux/types.h>
25#include <linux/string.h> 19#include <linux/string.h>
26#include <linux/kernel.h> 20#include <linux/kernel.h>
@@ -49,19 +43,6 @@
49 43
50#include "ide-floppy.h" 44#include "ide-floppy.h"
51 45
52/* module parameters */
53static unsigned long debug_mask;
54module_param(debug_mask, ulong, 0644);
55
56/* define to see debug info */
57#define IDEFLOPPY_DEBUG_LOG 0
58
59#if IDEFLOPPY_DEBUG_LOG
60#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
61#else
62#define ide_debug_log(lvl, fmt, args...) do {} while (0)
63#endif
64
65/* 46/*
66 * After each failed packet command we issue a request sense command and retry 47 * After each failed packet command we issue a request sense command and retry
67 * the packet command IDEFLOPPY_MAX_PC_RETRIES times. 48 * the packet command IDEFLOPPY_MAX_PC_RETRIES times.
@@ -83,41 +64,11 @@ module_param(debug_mask, ulong, 0644);
83/* Error code returned in rq->errors to the higher part of the driver. */ 64/* Error code returned in rq->errors to the higher part of the driver. */
84#define IDEFLOPPY_ERROR_GENERAL 101 65#define IDEFLOPPY_ERROR_GENERAL 101
85 66
86static DEFINE_MUTEX(idefloppy_ref_mutex);
87
88static void idefloppy_cleanup_obj(struct kref *);
89
90static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk)
91{
92 struct ide_floppy_obj *floppy = NULL;
93
94 mutex_lock(&idefloppy_ref_mutex);
95 floppy = ide_drv_g(disk, ide_floppy_obj);
96 if (floppy) {
97 if (ide_device_get(floppy->drive))
98 floppy = NULL;
99 else
100 kref_get(&floppy->kref);
101 }
102 mutex_unlock(&idefloppy_ref_mutex);
103 return floppy;
104}
105
106static void ide_floppy_put(struct ide_floppy_obj *floppy)
107{
108 ide_drive_t *drive = floppy->drive;
109
110 mutex_lock(&idefloppy_ref_mutex);
111 kref_put(&floppy->kref, idefloppy_cleanup_obj);
112 ide_device_put(drive);
113 mutex_unlock(&idefloppy_ref_mutex);
114}
115
116/* 67/*
117 * Used to finish servicing a request. For read/write requests, we will call 68 * Used to finish servicing a request. For read/write requests, we will call
118 * ide_end_request to pass to the next buffer. 69 * ide_end_request to pass to the next buffer.
119 */ 70 */
120static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) 71int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
121{ 72{
122 idefloppy_floppy_t *floppy = drive->driver_data; 73 idefloppy_floppy_t *floppy = drive->driver_data;
123 struct request *rq = HWGROUP(drive)->rq; 74 struct request *rq = HWGROUP(drive)->rq;
@@ -161,7 +112,7 @@ static void idefloppy_update_buffers(ide_drive_t *drive,
161 struct bio *bio = rq->bio; 112 struct bio *bio = rq->bio;
162 113
163 while ((bio = rq->bio) != NULL) 114 while ((bio = rq->bio) != NULL)
164 idefloppy_end_request(drive, 1, 0); 115 ide_floppy_end_request(drive, 1, 0);
165} 116}
166 117
167static void ide_floppy_callback(ide_drive_t *drive, int dsc) 118static void ide_floppy_callback(ide_drive_t *drive, int dsc)
@@ -200,7 +151,7 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc)
200 "Aborting request!\n"); 151 "Aborting request!\n");
201 } 152 }
202 153
203 idefloppy_end_request(drive, uptodate, 0); 154 ide_floppy_end_request(drive, uptodate, 0);
204} 155}
205 156
206static void ide_floppy_report_error(idefloppy_floppy_t *floppy, 157static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
@@ -329,8 +280,8 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
329 pc->req_xfer = pc->buf_size = rq->data_len; 280 pc->req_xfer = pc->buf_size = rq->data_len;
330} 281}
331 282
332static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, 283ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, struct request *rq,
333 struct request *rq, sector_t block_s) 284 sector_t block_s)
334{ 285{
335 idefloppy_floppy_t *floppy = drive->driver_data; 286 idefloppy_floppy_t *floppy = drive->driver_data;
336 ide_hwif_t *hwif = drive->hwif; 287 ide_hwif_t *hwif = drive->hwif;
@@ -353,7 +304,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
353 else 304 else
354 printk(KERN_ERR PFX "%s: I/O error\n", drive->name); 305 printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
355 306
356 idefloppy_end_request(drive, 0, 0); 307 ide_floppy_end_request(drive, 0, 0);
357 return ide_stopped; 308 return ide_stopped;
358 } 309 }
359 if (blk_fs_request(rq)) { 310 if (blk_fs_request(rq)) {
@@ -361,7 +312,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
361 (rq->nr_sectors % floppy->bs_factor)) { 312 (rq->nr_sectors % floppy->bs_factor)) {
362 printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", 313 printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
363 drive->name); 314 drive->name);
364 idefloppy_end_request(drive, 0, 0); 315 ide_floppy_end_request(drive, 0, 0);
365 return ide_stopped; 316 return ide_stopped;
366 } 317 }
367 pc = &floppy->queued_pc; 318 pc = &floppy->queued_pc;
@@ -373,7 +324,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
373 idefloppy_blockpc_cmd(floppy, pc, rq); 324 idefloppy_blockpc_cmd(floppy, pc, rq);
374 } else { 325 } else {
375 blk_dump_rq_flags(rq, PFX "unsupported command in queue"); 326 blk_dump_rq_flags(rq, PFX "unsupported command in queue");
376 idefloppy_end_request(drive, 0, 0); 327 ide_floppy_end_request(drive, 0, 0);
377 return ide_stopped; 328 return ide_stopped;
378 } 329 }
379 330
@@ -455,7 +406,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
455 * Determine if a media is present in the floppy drive, and if so, its LBA 406 * Determine if a media is present in the floppy drive, and if so, its LBA
456 * capacity. 407 * capacity.
457 */ 408 */
458static int ide_floppy_get_capacity(ide_drive_t *drive) 409int ide_floppy_get_capacity(ide_drive_t *drive)
459{ 410{
460 idefloppy_floppy_t *floppy = drive->driver_data; 411 idefloppy_floppy_t *floppy = drive->driver_data;
461 struct gendisk *disk = floppy->disk; 412 struct gendisk *disk = floppy->disk;
@@ -554,12 +505,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
554 return rc; 505 return rc;
555} 506}
556 507
557sector_t ide_floppy_capacity(ide_drive_t *drive) 508void ide_floppy_setup(ide_drive_t *drive)
558{
559 return drive->capacity64;
560}
561
562static void idefloppy_setup(ide_drive_t *drive)
563{ 509{
564 struct ide_floppy_obj *floppy = drive->driver_data; 510 struct ide_floppy_obj *floppy = drive->driver_data;
565 u16 *id = drive->id; 511 u16 *id = drive->id;
@@ -601,248 +547,3 @@ static void idefloppy_setup(ide_drive_t *drive)
601 547
602 drive->dev_flags |= IDE_DFLAG_ATTACH; 548 drive->dev_flags |= IDE_DFLAG_ATTACH;
603} 549}
604
605static void ide_floppy_remove(ide_drive_t *drive)
606{
607 idefloppy_floppy_t *floppy = drive->driver_data;
608 struct gendisk *g = floppy->disk;
609
610 ide_proc_unregister_driver(drive, floppy->driver);
611
612 del_gendisk(g);
613
614 ide_floppy_put(floppy);
615}
616
617static void idefloppy_cleanup_obj(struct kref *kref)
618{
619 struct ide_floppy_obj *floppy = to_ide_drv(kref, ide_floppy_obj);
620 ide_drive_t *drive = floppy->drive;
621 struct gendisk *g = floppy->disk;
622
623 drive->driver_data = NULL;
624 g->private_data = NULL;
625 put_disk(g);
626 kfree(floppy);
627}
628
629static int ide_floppy_probe(ide_drive_t *);
630
631static ide_driver_t idefloppy_driver = {
632 .gen_driver = {
633 .owner = THIS_MODULE,
634 .name = "ide-floppy",
635 .bus = &ide_bus_type,
636 },
637 .probe = ide_floppy_probe,
638 .remove = ide_floppy_remove,
639 .version = IDEFLOPPY_VERSION,
640 .do_request = idefloppy_do_request,
641 .end_request = idefloppy_end_request,
642 .error = __ide_error,
643#ifdef CONFIG_IDE_PROC_FS
644 .proc = ide_floppy_proc,
645 .settings = ide_floppy_settings,
646#endif
647};
648
649static int idefloppy_open(struct inode *inode, struct file *filp)
650{
651 struct gendisk *disk = inode->i_bdev->bd_disk;
652 struct ide_floppy_obj *floppy;
653 ide_drive_t *drive;
654 int ret = 0;
655
656 floppy = ide_floppy_get(disk);
657 if (!floppy)
658 return -ENXIO;
659
660 drive = floppy->drive;
661
662 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
663
664 floppy->openers++;
665
666 if (floppy->openers == 1) {
667 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
668 /* Just in case */
669
670 if (ide_do_test_unit_ready(drive, disk))
671 ide_do_start_stop(drive, disk, 1);
672
673 ret = ide_floppy_get_capacity(drive);
674
675 set_capacity(disk, ide_floppy_capacity(drive));
676
677 if (ret && (filp->f_flags & O_NDELAY) == 0) {
678 /*
679 * Allow O_NDELAY to open a drive without a disk, or with an
680 * unreadable disk, so that we can get the format capacity
681 * of the drive or begin the format - Sam
682 */
683 ret = -EIO;
684 goto out_put_floppy;
685 }
686
687 if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) {
688 ret = -EROFS;
689 goto out_put_floppy;
690 }
691
692 ide_set_media_lock(drive, disk, 1);
693 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
694 check_disk_change(inode->i_bdev);
695 } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
696 ret = -EBUSY;
697 goto out_put_floppy;
698 }
699 return 0;
700
701out_put_floppy:
702 floppy->openers--;
703 ide_floppy_put(floppy);
704 return ret;
705}
706
707static int idefloppy_release(struct inode *inode, struct file *filp)
708{
709 struct gendisk *disk = inode->i_bdev->bd_disk;
710 struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
711 ide_drive_t *drive = floppy->drive;
712
713 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
714
715 if (floppy->openers == 1) {
716 ide_set_media_lock(drive, disk, 0);
717 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
718 }
719
720 floppy->openers--;
721
722 ide_floppy_put(floppy);
723
724 return 0;
725}
726
727static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
728{
729 struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk,
730 ide_floppy_obj);
731 ide_drive_t *drive = floppy->drive;
732
733 geo->heads = drive->bios_head;
734 geo->sectors = drive->bios_sect;
735 geo->cylinders = (u16)drive->bios_cyl; /* truncate */
736 return 0;
737}
738
739static int idefloppy_media_changed(struct gendisk *disk)
740{
741 struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
742 ide_drive_t *drive = floppy->drive;
743 int ret;
744
745 /* do not scan partitions twice if this is a removable device */
746 if (drive->dev_flags & IDE_DFLAG_ATTACH) {
747 drive->dev_flags &= ~IDE_DFLAG_ATTACH;
748 return 0;
749 }
750 ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED);
751 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
752 return ret;
753}
754
755static int idefloppy_revalidate_disk(struct gendisk *disk)
756{
757 struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
758 set_capacity(disk, ide_floppy_capacity(floppy->drive));
759 return 0;
760}
761
762static struct block_device_operations idefloppy_ops = {
763 .owner = THIS_MODULE,
764 .open = idefloppy_open,
765 .release = idefloppy_release,
766 .ioctl = ide_floppy_ioctl,
767 .getgeo = idefloppy_getgeo,
768 .media_changed = idefloppy_media_changed,
769 .revalidate_disk = idefloppy_revalidate_disk
770};
771
772static int ide_floppy_probe(ide_drive_t *drive)
773{
774 idefloppy_floppy_t *floppy;
775 struct gendisk *g;
776
777 if (!strstr("ide-floppy", drive->driver_req))
778 goto failed;
779
780 if (drive->media != ide_floppy)
781 goto failed;
782
783 if (!ide_check_atapi_device(drive, DRV_NAME)) {
784 printk(KERN_ERR PFX "%s: not supported by this version of "
785 DRV_NAME "\n", drive->name);
786 goto failed;
787 }
788 floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL);
789 if (!floppy) {
790 printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n",
791 drive->name);
792 goto failed;
793 }
794
795 g = alloc_disk_node(1 << PARTN_BITS, hwif_to_node(drive->hwif));
796 if (!g)
797 goto out_free_floppy;
798
799 ide_init_disk(g, drive);
800
801 kref_init(&floppy->kref);
802
803 floppy->drive = drive;
804 floppy->driver = &idefloppy_driver;
805 floppy->disk = g;
806
807 g->private_data = &floppy->driver;
808
809 drive->driver_data = floppy;
810
811 drive->debug_mask = debug_mask;
812
813 idefloppy_setup(drive);
814
815 set_capacity(g, ide_floppy_capacity(drive));
816
817 g->minors = 1 << PARTN_BITS;
818 g->driverfs_dev = &drive->gendev;
819 if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
820 g->flags = GENHD_FL_REMOVABLE;
821 g->fops = &idefloppy_ops;
822 add_disk(g);
823 return 0;
824
825out_free_floppy:
826 kfree(floppy);
827failed:
828 return -ENODEV;
829}
830
831static void __exit idefloppy_exit(void)
832{
833 driver_unregister(&idefloppy_driver.gen_driver);
834}
835
836static int __init idefloppy_init(void)
837{
838 printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n");
839 return driver_register(&idefloppy_driver.gen_driver);
840}
841
842MODULE_ALIAS("ide:*m-floppy*");
843MODULE_ALIAS("ide-floppy");
844module_init(idefloppy_init);
845module_exit(idefloppy_exit);
846MODULE_LICENSE("GPL");
847MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
848
diff --git a/drivers/ide/ide-floppy.h b/drivers/ide/ide-floppy.h
index 17cf865e583d..836a70e6e3ef 100644
--- a/drivers/ide/ide-floppy.h
+++ b/drivers/ide/ide-floppy.h
@@ -1,6 +1,18 @@
1#ifndef __IDE_FLOPPY_H 1#ifndef __IDE_FLOPPY_H
2#define __IDE_FLOPPY_H 2#define __IDE_FLOPPY_H
3 3
4#define DRV_NAME "ide-floppy"
5#define PFX DRV_NAME ": "
6
7/* define to see debug info */
8#define IDEFLOPPY_DEBUG_LOG 0
9
10#if IDEFLOPPY_DEBUG_LOG
11#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
12#else
13#define ide_debug_log(lvl, fmt, args...) do {} while (0)
14#endif
15
4/* 16/*
5 * Most of our global data which we need to save even as we leave the driver 17 * Most of our global data which we need to save even as we leave the driver
6 * due to an interrupt or a timer event is stored in a variable of type 18 * due to an interrupt or a timer event is stored in a variable of type
@@ -45,10 +57,15 @@ typedef struct ide_floppy_obj {
45#define IDEFLOPPY_IOCTL_FORMAT_START 0x4602 57#define IDEFLOPPY_IOCTL_FORMAT_START 0x4602
46#define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 58#define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603
47 59
60sector_t ide_floppy_capacity(ide_drive_t *);
61
48/* ide-floppy.c */ 62/* ide-floppy.c */
49void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); 63void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8);
50void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); 64void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *);
51sector_t ide_floppy_capacity(ide_drive_t *); 65int ide_floppy_get_capacity(ide_drive_t *);
66void ide_floppy_setup(ide_drive_t *);
67ide_startstop_t ide_floppy_do_request(ide_drive_t *, struct request *, sector_t);
68int ide_floppy_end_request(ide_drive_t *, int, int);
52 69
53/* ide-floppy_ioctl.c */ 70/* ide-floppy_ioctl.c */
54int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long); 71int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long);
diff --git a/drivers/ide/ide-gd-floppy.c b/drivers/ide/ide-gd-floppy.c
new file mode 100644
index 000000000000..7afd013b4c55
--- /dev/null
+++ b/drivers/ide/ide-gd-floppy.c
@@ -0,0 +1,298 @@
1#include <linux/module.h>
2#include <linux/types.h>
3#include <linux/string.h>
4#include <linux/kernel.h>
5#include <linux/errno.h>
6#include <linux/genhd.h>
7#include <linux/mutex.h>
8#include <linux/ide.h>
9#include <linux/hdreg.h>
10
11#include "ide-floppy.h"
12
13#define IDEFLOPPY_VERSION "1.00"
14
15/* module parameters */
16static unsigned long debug_mask;
17module_param(debug_mask, ulong, 0644);
18
19static DEFINE_MUTEX(idefloppy_ref_mutex);
20
21static void idefloppy_cleanup_obj(struct kref *);
22
23static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk)
24{
25 struct ide_floppy_obj *floppy = NULL;
26
27 mutex_lock(&idefloppy_ref_mutex);
28 floppy = ide_drv_g(disk, ide_floppy_obj);
29 if (floppy) {
30 if (ide_device_get(floppy->drive))
31 floppy = NULL;
32 else
33 kref_get(&floppy->kref);
34 }
35 mutex_unlock(&idefloppy_ref_mutex);
36 return floppy;
37}
38
39static void ide_floppy_put(struct ide_floppy_obj *floppy)
40{
41 ide_drive_t *drive = floppy->drive;
42
43 mutex_lock(&idefloppy_ref_mutex);
44 kref_put(&floppy->kref, idefloppy_cleanup_obj);
45 ide_device_put(drive);
46 mutex_unlock(&idefloppy_ref_mutex);
47}
48
49sector_t ide_floppy_capacity(ide_drive_t *drive)
50{
51 return drive->capacity64;
52}
53
54static void ide_floppy_remove(ide_drive_t *drive)
55{
56 idefloppy_floppy_t *floppy = drive->driver_data;
57 struct gendisk *g = floppy->disk;
58
59 ide_proc_unregister_driver(drive, floppy->driver);
60
61 del_gendisk(g);
62
63 ide_floppy_put(floppy);
64}
65
66static void idefloppy_cleanup_obj(struct kref *kref)
67{
68 struct ide_floppy_obj *floppy = to_ide_drv(kref, ide_floppy_obj);
69 ide_drive_t *drive = floppy->drive;
70 struct gendisk *g = floppy->disk;
71
72 drive->driver_data = NULL;
73 g->private_data = NULL;
74 put_disk(g);
75 kfree(floppy);
76}
77
78static int ide_floppy_probe(ide_drive_t *);
79
80static ide_driver_t idefloppy_driver = {
81 .gen_driver = {
82 .owner = THIS_MODULE,
83 .name = "ide-floppy",
84 .bus = &ide_bus_type,
85 },
86 .probe = ide_floppy_probe,
87 .remove = ide_floppy_remove,
88 .version = IDEFLOPPY_VERSION,
89 .do_request = ide_floppy_do_request,
90 .end_request = ide_floppy_end_request,
91 .error = __ide_error,
92#ifdef CONFIG_IDE_PROC_FS
93 .proc = ide_floppy_proc,
94 .settings = ide_floppy_settings,
95#endif
96};
97
98static int idefloppy_open(struct inode *inode, struct file *filp)
99{
100 struct gendisk *disk = inode->i_bdev->bd_disk;
101 struct ide_floppy_obj *floppy;
102 ide_drive_t *drive;
103 int ret = 0;
104
105 floppy = ide_floppy_get(disk);
106 if (!floppy)
107 return -ENXIO;
108
109 drive = floppy->drive;
110
111 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
112
113 floppy->openers++;
114
115 if (floppy->openers == 1) {
116 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
117 /* Just in case */
118
119 if (ide_do_test_unit_ready(drive, disk))
120 ide_do_start_stop(drive, disk, 1);
121
122 ret = ide_floppy_get_capacity(drive);
123
124 set_capacity(disk, ide_floppy_capacity(drive));
125
126 if (ret && (filp->f_flags & O_NDELAY) == 0) {
127 /*
128 * Allow O_NDELAY to open a drive without a disk, or with an
129 * unreadable disk, so that we can get the format capacity
130 * of the drive or begin the format - Sam
131 */
132 ret = -EIO;
133 goto out_put_floppy;
134 }
135
136 if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) {
137 ret = -EROFS;
138 goto out_put_floppy;
139 }
140
141 ide_set_media_lock(drive, disk, 1);
142 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
143 check_disk_change(inode->i_bdev);
144 } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
145 ret = -EBUSY;
146 goto out_put_floppy;
147 }
148 return 0;
149
150out_put_floppy:
151 floppy->openers--;
152 ide_floppy_put(floppy);
153 return ret;
154}
155
156static int idefloppy_release(struct inode *inode, struct file *filp)
157{
158 struct gendisk *disk = inode->i_bdev->bd_disk;
159 struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
160 ide_drive_t *drive = floppy->drive;
161
162 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
163
164 if (floppy->openers == 1) {
165 ide_set_media_lock(drive, disk, 0);
166 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
167 }
168
169 floppy->openers--;
170
171 ide_floppy_put(floppy);
172
173 return 0;
174}
175
176static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
177{
178 struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk,
179 ide_floppy_obj);
180 ide_drive_t *drive = floppy->drive;
181
182 geo->heads = drive->bios_head;
183 geo->sectors = drive->bios_sect;
184 geo->cylinders = (u16)drive->bios_cyl; /* truncate */
185 return 0;
186}
187
188static int idefloppy_media_changed(struct gendisk *disk)
189{
190 struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
191 ide_drive_t *drive = floppy->drive;
192 int ret;
193
194 /* do not scan partitions twice if this is a removable device */
195 if (drive->dev_flags & IDE_DFLAG_ATTACH) {
196 drive->dev_flags &= ~IDE_DFLAG_ATTACH;
197 return 0;
198 }
199
200 ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED);
201 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
202
203 return ret;
204}
205
206static int idefloppy_revalidate_disk(struct gendisk *disk)
207{
208 struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
209 set_capacity(disk, ide_floppy_capacity(floppy->drive));
210 return 0;
211}
212
213static struct block_device_operations idefloppy_ops = {
214 .owner = THIS_MODULE,
215 .open = idefloppy_open,
216 .release = idefloppy_release,
217 .ioctl = ide_floppy_ioctl,
218 .getgeo = idefloppy_getgeo,
219 .media_changed = idefloppy_media_changed,
220 .revalidate_disk = idefloppy_revalidate_disk
221};
222
223static int ide_floppy_probe(ide_drive_t *drive)
224{
225 idefloppy_floppy_t *floppy;
226 struct gendisk *g;
227
228 if (!strstr("ide-floppy", drive->driver_req))
229 goto failed;
230
231 if (drive->media != ide_floppy)
232 goto failed;
233
234 if (!ide_check_atapi_device(drive, DRV_NAME)) {
235 printk(KERN_ERR PFX "%s: not supported by this version of "
236 DRV_NAME "\n", drive->name);
237 goto failed;
238 }
239 floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL);
240 if (!floppy) {
241 printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n",
242 drive->name);
243 goto failed;
244 }
245
246 g = alloc_disk_node(1 << PARTN_BITS, hwif_to_node(drive->hwif));
247 if (!g)
248 goto out_free_floppy;
249
250 ide_init_disk(g, drive);
251
252 kref_init(&floppy->kref);
253
254 floppy->drive = drive;
255 floppy->driver = &idefloppy_driver;
256 floppy->disk = g;
257
258 g->private_data = &floppy->driver;
259
260 drive->driver_data = floppy;
261
262 drive->debug_mask = debug_mask;
263
264 ide_floppy_setup(drive);
265
266 set_capacity(g, ide_floppy_capacity(drive));
267
268 g->minors = 1 << PARTN_BITS;
269 g->driverfs_dev = &drive->gendev;
270 if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
271 g->flags = GENHD_FL_REMOVABLE;
272 g->fops = &idefloppy_ops;
273 add_disk(g);
274 return 0;
275
276out_free_floppy:
277 kfree(floppy);
278failed:
279 return -ENODEV;
280}
281
282static int __init idefloppy_init(void)
283{
284 printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n");
285 return driver_register(&idefloppy_driver.gen_driver);
286}
287
288static void __exit idefloppy_exit(void)
289{
290 driver_unregister(&idefloppy_driver.gen_driver);
291}
292
293MODULE_ALIAS("ide:*m-floppy*");
294MODULE_ALIAS("ide-floppy");
295module_init(idefloppy_init);
296module_exit(idefloppy_exit);
297MODULE_LICENSE("GPL");
298MODULE_DESCRIPTION("ATAPI FLOPPY Driver");