aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-gd-floppy.c
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 /drivers/ide/ide-gd-floppy.c
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>
Diffstat (limited to 'drivers/ide/ide-gd-floppy.c')
-rw-r--r--drivers/ide/ide-gd-floppy.c298
1 files changed, 298 insertions, 0 deletions
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");