diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-17 12:09:13 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-17 12:09:13 -0400 |
commit | c84d9bbe7c77aea7e1194da056d44a2ed982e72b (patch) | |
tree | c7b9ee5e2b94ba87a2124e731bd8281439c0fb5d /drivers/ide/ide-gd-floppy.c | |
parent | cedd120cac61fa149ba215eabc57b2578068be00 (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.c | 298 |
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 */ | ||
16 | static unsigned long debug_mask; | ||
17 | module_param(debug_mask, ulong, 0644); | ||
18 | |||
19 | static DEFINE_MUTEX(idefloppy_ref_mutex); | ||
20 | |||
21 | static void idefloppy_cleanup_obj(struct kref *); | ||
22 | |||
23 | static 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 | |||
39 | static 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 | |||
49 | sector_t ide_floppy_capacity(ide_drive_t *drive) | ||
50 | { | ||
51 | return drive->capacity64; | ||
52 | } | ||
53 | |||
54 | static 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 | |||
66 | static 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 | |||
78 | static int ide_floppy_probe(ide_drive_t *); | ||
79 | |||
80 | static 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 | |||
98 | static 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 | |||
150 | out_put_floppy: | ||
151 | floppy->openers--; | ||
152 | ide_floppy_put(floppy); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | static 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 | |||
176 | static 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 | |||
188 | static 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 | |||
206 | static 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 | |||
213 | static 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 | |||
223 | static 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 | |||
276 | out_free_floppy: | ||
277 | kfree(floppy); | ||
278 | failed: | ||
279 | return -ENODEV; | ||
280 | } | ||
281 | |||
282 | static 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 | |||
288 | static void __exit idefloppy_exit(void) | ||
289 | { | ||
290 | driver_unregister(&idefloppy_driver.gen_driver); | ||
291 | } | ||
292 | |||
293 | MODULE_ALIAS("ide:*m-floppy*"); | ||
294 | MODULE_ALIAS("ide-floppy"); | ||
295 | module_init(idefloppy_init); | ||
296 | module_exit(idefloppy_exit); | ||
297 | MODULE_LICENSE("GPL"); | ||
298 | MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); | ||