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#include <linux/dmi.h>
11#include <linux/slab.h>
12
13#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
14#define IDE_DISK_MINORS (1 << PARTN_BITS)
15#else
16#define IDE_DISK_MINORS 0
17#endif
18
19#include "ide-disk.h"
20#include "ide-floppy.h"
21
22#define IDE_GD_VERSION "1.18"
23
24
25static DEFINE_MUTEX(ide_gd_mutex);
26static unsigned long debug_mask;
27module_param(debug_mask, ulong, 0644);
28
29static DEFINE_MUTEX(ide_disk_ref_mutex);
30
31static void ide_disk_release(struct device *);
32
33static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
34{
35 struct ide_disk_obj *idkp = NULL;
36
37 mutex_lock(&ide_disk_ref_mutex);
38 idkp = ide_drv_g(disk, ide_disk_obj);
39 if (idkp) {
40 if (ide_device_get(idkp->drive))
41 idkp = NULL;
42 else
43 get_device(&idkp->dev);
44 }
45 mutex_unlock(&ide_disk_ref_mutex);
46 return idkp;
47}
48
49static void ide_disk_put(struct ide_disk_obj *idkp)
50{
51 ide_drive_t *drive = idkp->drive;
52
53 mutex_lock(&ide_disk_ref_mutex);
54 put_device(&idkp->dev);
55 ide_device_put(drive);
56 mutex_unlock(&ide_disk_ref_mutex);
57}
58
59sector_t ide_gd_capacity(ide_drive_t *drive)
60{
61 return drive->capacity64;
62}
63
64static int ide_gd_probe(ide_drive_t *);
65
66static void ide_gd_remove(ide_drive_t *drive)
67{
68 struct ide_disk_obj *idkp = drive->driver_data;
69 struct gendisk *g = idkp->disk;
70
71 ide_proc_unregister_driver(drive, idkp->driver);
72 device_del(&idkp->dev);
73 del_gendisk(g);
74 drive->disk_ops->flush(drive);
75
76 mutex_lock(&ide_disk_ref_mutex);
77 put_device(&idkp->dev);
78 mutex_unlock(&ide_disk_ref_mutex);
79}
80
81static void ide_disk_release(struct device *dev)
82{
83 struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj);
84 ide_drive_t *drive = idkp->drive;
85 struct gendisk *g = idkp->disk;
86
87 drive->disk_ops = NULL;
88 drive->driver_data = NULL;
89 g->private_data = NULL;
90 put_disk(g);
91 kfree(idkp);
92}
93
94
95
96
97
98
99static void ide_gd_resume(ide_drive_t *drive)
100{
101 if (ata_id_hpa_enabled(drive->id))
102 (void)drive->disk_ops->get_capacity(drive);
103}
104
105static const struct dmi_system_id ide_coldreboot_table[] = {
106 {
107
108 .ident = "Acer TravelMate 660",
109 .matches = {
110 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
111 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
112 },
113 },
114
115 { }
116};
117
118static void ide_gd_shutdown(ide_drive_t *drive)
119{
120#ifdef CONFIG_ALPHA
121
122
123
124
125
126
127
128
129
130
131
132 if (system_state != SYSTEM_POWER_OFF) {
133#else
134 if (system_state == SYSTEM_RESTART &&
135 !dmi_check_system(ide_coldreboot_table)) {
136#endif
137 drive->disk_ops->flush(drive);
138 return;
139 }
140
141 printk(KERN_INFO "Shutdown: %s\n", drive->name);
142
143 drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
144}
145
146#ifdef CONFIG_IDE_PROC_FS
147static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
148{
149 return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc;
150}
151
152static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
153{
154 return (drive->media == ide_disk) ? ide_disk_settings
155 : ide_floppy_settings;
156}
157#endif
158
159static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
160 struct request *rq, sector_t sector)
161{
162 return drive->disk_ops->do_request(drive, rq, sector);
163}
164
165static struct ide_driver ide_gd_driver = {
166 .gen_driver = {
167 .owner = THIS_MODULE,
168 .name = "ide-gd",
169 .bus = &ide_bus_type,
170 },
171 .probe = ide_gd_probe,
172 .remove = ide_gd_remove,
173 .resume = ide_gd_resume,
174 .shutdown = ide_gd_shutdown,
175 .version = IDE_GD_VERSION,
176 .do_request = ide_gd_do_request,
177#ifdef CONFIG_IDE_PROC_FS
178 .proc_entries = ide_disk_proc_entries,
179 .proc_devsets = ide_disk_proc_devsets,
180#endif
181};
182
183static int ide_gd_open(struct block_device *bdev, fmode_t mode)
184{
185 struct gendisk *disk = bdev->bd_disk;
186 struct ide_disk_obj *idkp;
187 ide_drive_t *drive;
188 int ret = 0;
189
190 idkp = ide_disk_get(disk);
191 if (idkp == NULL)
192 return -ENXIO;
193
194 drive = idkp->drive;
195
196 ide_debug_log(IDE_DBG_FUNC, "enter");
197
198 idkp->openers++;
199
200 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
201 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
202
203
204 ret = drive->disk_ops->init_media(drive, disk);
205
206
207
208
209
210
211 if (ret && (mode & FMODE_NDELAY) == 0) {
212 ret = -EIO;
213 goto out_put_idkp;
214 }
215
216 if ((drive->dev_flags & IDE_DFLAG_WP) && (mode & FMODE_WRITE)) {
217 ret = -EROFS;
218 goto out_put_idkp;
219 }
220
221
222
223
224
225
226 drive->disk_ops->set_doorlock(drive, disk, 1);
227 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
228 check_disk_change(bdev);
229 } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
230 ret = -EBUSY;
231 goto out_put_idkp;
232 }
233 return 0;
234
235out_put_idkp:
236 idkp->openers--;
237 ide_disk_put(idkp);
238 return ret;
239}
240
241static int ide_gd_unlocked_open(struct block_device *bdev, fmode_t mode)
242{
243 int ret;
244
245 mutex_lock(&ide_gd_mutex);
246 ret = ide_gd_open(bdev, mode);
247 mutex_unlock(&ide_gd_mutex);
248
249 return ret;
250}
251
252
253static void ide_gd_release(struct gendisk *disk, fmode_t mode)
254{
255 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
256 ide_drive_t *drive = idkp->drive;
257
258 ide_debug_log(IDE_DBG_FUNC, "enter");
259
260 mutex_lock(&ide_gd_mutex);
261 if (idkp->openers == 1)
262 drive->disk_ops->flush(drive);
263
264 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
265 drive->disk_ops->set_doorlock(drive, disk, 0);
266 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
267 }
268
269 idkp->openers--;
270
271 ide_disk_put(idkp);
272 mutex_unlock(&ide_gd_mutex);
273}
274
275static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
276{
277 struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
278 ide_drive_t *drive = idkp->drive;
279
280 geo->heads = drive->bios_head;
281 geo->sectors = drive->bios_sect;
282 geo->cylinders = (u16)drive->bios_cyl;
283 return 0;
284}
285
286static unsigned int ide_gd_check_events(struct gendisk *disk,
287 unsigned int clearing)
288{
289 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
290 ide_drive_t *drive = idkp->drive;
291 bool ret;
292
293
294 if (drive->dev_flags & IDE_DFLAG_ATTACH) {
295 drive->dev_flags &= ~IDE_DFLAG_ATTACH;
296 return 0;
297 }
298
299
300
301
302
303
304
305 ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED;
306 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
307
308 return ret ? DISK_EVENT_MEDIA_CHANGE : 0;
309}
310
311static void ide_gd_unlock_native_capacity(struct gendisk *disk)
312{
313 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
314 ide_drive_t *drive = idkp->drive;
315 const struct ide_disk_ops *disk_ops = drive->disk_ops;
316
317 if (disk_ops->unlock_native_capacity)
318 disk_ops->unlock_native_capacity(drive);
319}
320
321static int ide_gd_revalidate_disk(struct gendisk *disk)
322{
323 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
324 ide_drive_t *drive = idkp->drive;
325
326 if (ide_gd_check_events(disk, 0))
327 drive->disk_ops->get_capacity(drive);
328
329 set_capacity(disk, ide_gd_capacity(drive));
330 return 0;
331}
332
333static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode,
334 unsigned int cmd, unsigned long arg)
335{
336 struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
337 ide_drive_t *drive = idkp->drive;
338
339 return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg);
340}
341
342static const struct block_device_operations ide_gd_ops = {
343 .owner = THIS_MODULE,
344 .open = ide_gd_unlocked_open,
345 .release = ide_gd_release,
346 .ioctl = ide_gd_ioctl,
347 .getgeo = ide_gd_getgeo,
348 .check_events = ide_gd_check_events,
349 .unlock_native_capacity = ide_gd_unlock_native_capacity,
350 .revalidate_disk = ide_gd_revalidate_disk
351};
352
353static int ide_gd_probe(ide_drive_t *drive)
354{
355 const struct ide_disk_ops *disk_ops = NULL;
356 struct ide_disk_obj *idkp;
357 struct gendisk *g;
358
359
360 if (!strstr("ide-gd", drive->driver_req))
361 goto failed;
362
363#ifdef CONFIG_IDE_GD_ATA
364 if (drive->media == ide_disk)
365 disk_ops = &ide_ata_disk_ops;
366#endif
367#ifdef CONFIG_IDE_GD_ATAPI
368 if (drive->media == ide_floppy)
369 disk_ops = &ide_atapi_disk_ops;
370#endif
371 if (disk_ops == NULL)
372 goto failed;
373
374 if (disk_ops->check(drive, DRV_NAME) == 0) {
375 printk(KERN_ERR PFX "%s: not supported by this driver\n",
376 drive->name);
377 goto failed;
378 }
379
380 idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
381 if (!idkp) {
382 printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
383 drive->name);
384 goto failed;
385 }
386
387 g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
388 if (!g)
389 goto out_free_idkp;
390
391 ide_init_disk(g, drive);
392
393 idkp->dev.parent = &drive->gendev;
394 idkp->dev.release = ide_disk_release;
395 dev_set_name(&idkp->dev, "%s", dev_name(&drive->gendev));
396
397 if (device_register(&idkp->dev))
398 goto out_free_disk;
399
400 idkp->drive = drive;
401 idkp->driver = &ide_gd_driver;
402 idkp->disk = g;
403
404 g->private_data = &idkp->driver;
405
406 drive->driver_data = idkp;
407 drive->debug_mask = debug_mask;
408 drive->disk_ops = disk_ops;
409
410 disk_ops->setup(drive);
411
412 set_capacity(g, ide_gd_capacity(drive));
413
414 g->minors = IDE_DISK_MINORS;
415 g->driverfs_dev = &drive->gendev;
416 g->flags |= GENHD_FL_EXT_DEVT;
417 if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
418 g->flags = GENHD_FL_REMOVABLE;
419 g->fops = &ide_gd_ops;
420 add_disk(g);
421 return 0;
422
423out_free_disk:
424 put_disk(g);
425out_free_idkp:
426 kfree(idkp);
427failed:
428 return -ENODEV;
429}
430
431static int __init ide_gd_init(void)
432{
433 printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
434 return driver_register(&ide_gd_driver.gen_driver);
435}
436
437static void __exit ide_gd_exit(void)
438{
439 driver_unregister(&ide_gd_driver.gen_driver);
440}
441
442MODULE_ALIAS("ide:*m-disk*");
443MODULE_ALIAS("ide-disk");
444MODULE_ALIAS("ide:*m-floppy*");
445MODULE_ALIAS("ide-floppy");
446module_init(ide_gd_init);
447module_exit(ide_gd_exit);
448MODULE_LICENSE("GPL");
449MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");
450