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>
9 #include <linux/hdreg.h>
11 #include "ide-floppy.h"
13 #define IDEFLOPPY_VERSION "1.00"
15 /* module parameters */
16 static unsigned long debug_mask
;
17 module_param(debug_mask
, ulong
, 0644);
19 static DEFINE_MUTEX(ide_disk_ref_mutex
);
21 static void ide_disk_release(struct kref
*);
23 static struct ide_floppy_obj
*ide_disk_get(struct gendisk
*disk
)
25 struct ide_floppy_obj
*idkp
= NULL
;
27 mutex_lock(&ide_disk_ref_mutex
);
28 idkp
= ide_drv_g(disk
, ide_floppy_obj
);
30 if (ide_device_get(idkp
->drive
))
33 kref_get(&idkp
->kref
);
35 mutex_unlock(&ide_disk_ref_mutex
);
39 static void ide_disk_put(struct ide_floppy_obj
*idkp
)
41 ide_drive_t
*drive
= idkp
->drive
;
43 mutex_lock(&ide_disk_ref_mutex
);
44 kref_put(&idkp
->kref
, ide_disk_release
);
45 ide_device_put(drive
);
46 mutex_unlock(&ide_disk_ref_mutex
);
49 sector_t
ide_gd_capacity(ide_drive_t
*drive
)
51 return drive
->capacity64
;
54 static int ide_gd_probe(ide_drive_t
*);
56 static void ide_gd_remove(ide_drive_t
*drive
)
58 struct ide_floppy_obj
*idkp
= drive
->driver_data
;
59 struct gendisk
*g
= idkp
->disk
;
61 ide_proc_unregister_driver(drive
, idkp
->driver
);
68 static void ide_disk_release(struct kref
*kref
)
70 struct ide_floppy_obj
*idkp
= to_ide_drv(kref
, ide_floppy_obj
);
71 ide_drive_t
*drive
= idkp
->drive
;
72 struct gendisk
*g
= idkp
->disk
;
74 drive
->driver_data
= NULL
;
75 g
->private_data
= NULL
;
80 #ifdef CONFIG_IDE_PROC_FS
81 static ide_proc_entry_t
*ide_floppy_proc_entries(ide_drive_t
*drive
)
83 return ide_floppy_proc
;
86 static const struct ide_proc_devset
*ide_floppy_proc_devsets(ide_drive_t
*drive
)
88 return ide_floppy_settings
;
92 static ide_driver_t ide_gd_driver
= {
98 .probe
= ide_gd_probe
,
99 .remove
= ide_gd_remove
,
100 .version
= IDEFLOPPY_VERSION
,
101 .do_request
= ide_floppy_do_request
,
102 .end_request
= ide_floppy_end_request
,
103 .error
= __ide_error
,
104 #ifdef CONFIG_IDE_PROC_FS
105 .proc_entries
= ide_floppy_proc_entries
,
106 .proc_devsets
= ide_floppy_proc_devsets
,
110 static int ide_gd_open(struct inode
*inode
, struct file
*filp
)
112 struct gendisk
*disk
= inode
->i_bdev
->bd_disk
;
113 struct ide_floppy_obj
*idkp
;
117 idkp
= ide_disk_get(disk
);
123 ide_debug_log(IDE_DBG_FUNC
, "Call %s\n", __func__
);
127 if (idkp
->openers
== 1) {
128 drive
->dev_flags
&= ~IDE_DFLAG_FORMAT_IN_PROGRESS
;
131 if (ide_do_test_unit_ready(drive
, disk
))
132 ide_do_start_stop(drive
, disk
, 1);
134 ret
= ide_floppy_get_capacity(drive
);
136 set_capacity(disk
, ide_gd_capacity(drive
));
138 if (ret
&& (filp
->f_flags
& O_NDELAY
) == 0) {
140 * Allow O_NDELAY to open a drive without a disk, or with an
141 * unreadable disk, so that we can get the format capacity
142 * of the drive or begin the format - Sam
148 if ((drive
->dev_flags
& IDE_DFLAG_WP
) && (filp
->f_mode
& 2)) {
153 ide_set_media_lock(drive
, disk
, 1);
154 drive
->dev_flags
|= IDE_DFLAG_MEDIA_CHANGED
;
155 check_disk_change(inode
->i_bdev
);
156 } else if (drive
->dev_flags
& IDE_DFLAG_FORMAT_IN_PROGRESS
) {
168 static int ide_gd_release(struct inode
*inode
, struct file
*filp
)
170 struct gendisk
*disk
= inode
->i_bdev
->bd_disk
;
171 struct ide_floppy_obj
*idkp
= ide_drv_g(disk
, ide_floppy_obj
);
172 ide_drive_t
*drive
= idkp
->drive
;
174 ide_debug_log(IDE_DBG_FUNC
, "Call %s\n", __func__
);
176 if (idkp
->openers
== 1) {
177 ide_set_media_lock(drive
, disk
, 0);
178 drive
->dev_flags
&= ~IDE_DFLAG_FORMAT_IN_PROGRESS
;
188 static int ide_gd_getgeo(struct block_device
*bdev
, struct hd_geometry
*geo
)
190 struct ide_floppy_obj
*idkp
= ide_drv_g(bdev
->bd_disk
, ide_floppy_obj
);
191 ide_drive_t
*drive
= idkp
->drive
;
193 geo
->heads
= drive
->bios_head
;
194 geo
->sectors
= drive
->bios_sect
;
195 geo
->cylinders
= (u16
)drive
->bios_cyl
; /* truncate */
199 static int ide_gd_media_changed(struct gendisk
*disk
)
201 struct ide_floppy_obj
*idkp
= ide_drv_g(disk
, ide_floppy_obj
);
202 ide_drive_t
*drive
= idkp
->drive
;
205 /* do not scan partitions twice if this is a removable device */
206 if (drive
->dev_flags
& IDE_DFLAG_ATTACH
) {
207 drive
->dev_flags
&= ~IDE_DFLAG_ATTACH
;
211 ret
= !!(drive
->dev_flags
& IDE_DFLAG_MEDIA_CHANGED
);
212 drive
->dev_flags
&= ~IDE_DFLAG_MEDIA_CHANGED
;
217 static int ide_gd_revalidate_disk(struct gendisk
*disk
)
219 struct ide_floppy_obj
*idkp
= ide_drv_g(disk
, ide_floppy_obj
);
220 set_capacity(disk
, ide_gd_capacity(idkp
->drive
));
224 static struct block_device_operations ide_gd_ops
= {
225 .owner
= THIS_MODULE
,
227 .release
= ide_gd_release
,
228 .ioctl
= ide_floppy_ioctl
,
229 .getgeo
= ide_gd_getgeo
,
230 .media_changed
= ide_gd_media_changed
,
231 .revalidate_disk
= ide_gd_revalidate_disk
234 static int ide_gd_probe(ide_drive_t
*drive
)
236 struct ide_floppy_obj
*idkp
;
239 if (!strstr("ide-floppy", drive
->driver_req
))
242 if (drive
->media
!= ide_floppy
)
245 if (!ide_check_atapi_device(drive
, DRV_NAME
)) {
246 printk(KERN_ERR PFX
"%s: not supported by this version of "
247 DRV_NAME
"\n", drive
->name
);
250 idkp
= kzalloc(sizeof(*idkp
), GFP_KERNEL
);
252 printk(KERN_ERR PFX
"%s: Can't allocate a floppy structure\n",
257 g
= alloc_disk_node(1 << PARTN_BITS
, hwif_to_node(drive
->hwif
));
261 ide_init_disk(g
, drive
);
263 kref_init(&idkp
->kref
);
266 idkp
->driver
= &ide_gd_driver
;
269 g
->private_data
= &idkp
->driver
;
271 drive
->driver_data
= idkp
;
273 drive
->debug_mask
= debug_mask
;
275 ide_floppy_setup(drive
);
277 set_capacity(g
, ide_gd_capacity(drive
));
279 g
->minors
= 1 << PARTN_BITS
;
280 g
->driverfs_dev
= &drive
->gendev
;
281 if (drive
->dev_flags
& IDE_DFLAG_REMOVABLE
)
282 g
->flags
= GENHD_FL_REMOVABLE
;
283 g
->fops
= &ide_gd_ops
;
293 static int __init
ide_gd_init(void)
295 printk(KERN_INFO DRV_NAME
" driver " IDEFLOPPY_VERSION
"\n");
296 return driver_register(&ide_gd_driver
.gen_driver
);
299 static void __exit
ide_gd_exit(void)
301 driver_unregister(&ide_gd_driver
.gen_driver
);
304 MODULE_ALIAS("ide:*m-floppy*");
305 MODULE_ALIAS("ide-floppy");
306 module_init(ide_gd_init
);
307 module_exit(ide_gd_exit
);
308 MODULE_LICENSE("GPL");
309 MODULE_DESCRIPTION("ATAPI FLOPPY Driver");