blob: 753241429c26b4e9b370c72e388a79990a780028 [file] [log] [blame]
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +02001#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>
Bruno Prémontb0aedb02009-04-22 20:33:41 +020010#include <linux/dmi.h>
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020011
12#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
13#define IDE_DISK_MINORS (1 << PARTN_BITS)
14#else
15#define IDE_DISK_MINORS 0
16#endif
17
18#include "ide-disk.h"
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +020019#include "ide-floppy.h"
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020020
21#define IDE_GD_VERSION "1.18"
22
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +020023/* module parameters */
24static unsigned long debug_mask;
25module_param(debug_mask, ulong, 0644);
26
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020027static DEFINE_MUTEX(ide_disk_ref_mutex);
28
Bartlomiej Zolnierkiewicz8fed4362009-02-25 20:28:24 +010029static void ide_disk_release(struct device *);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020030
31static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
32{
33 struct ide_disk_obj *idkp = NULL;
34
35 mutex_lock(&ide_disk_ref_mutex);
36 idkp = ide_drv_g(disk, ide_disk_obj);
37 if (idkp) {
38 if (ide_device_get(idkp->drive))
39 idkp = NULL;
40 else
Bartlomiej Zolnierkiewicz8fed4362009-02-25 20:28:24 +010041 get_device(&idkp->dev);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020042 }
43 mutex_unlock(&ide_disk_ref_mutex);
44 return idkp;
45}
46
47static void ide_disk_put(struct ide_disk_obj *idkp)
48{
49 ide_drive_t *drive = idkp->drive;
50
51 mutex_lock(&ide_disk_ref_mutex);
Bartlomiej Zolnierkiewicz8fed4362009-02-25 20:28:24 +010052 put_device(&idkp->dev);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020053 ide_device_put(drive);
54 mutex_unlock(&ide_disk_ref_mutex);
55}
56
57sector_t ide_gd_capacity(ide_drive_t *drive)
58{
59 return drive->capacity64;
60}
61
62static int ide_gd_probe(ide_drive_t *);
63
64static void ide_gd_remove(ide_drive_t *drive)
65{
66 struct ide_disk_obj *idkp = drive->driver_data;
67 struct gendisk *g = idkp->disk;
68
69 ide_proc_unregister_driver(drive, idkp->driver);
Bartlomiej Zolnierkiewicz8fed4362009-02-25 20:28:24 +010070 device_del(&idkp->dev);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020071 del_gendisk(g);
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +020072 drive->disk_ops->flush(drive);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020073
Bartlomiej Zolnierkiewicz8fed4362009-02-25 20:28:24 +010074 mutex_lock(&ide_disk_ref_mutex);
75 put_device(&idkp->dev);
76 mutex_unlock(&ide_disk_ref_mutex);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020077}
78
Bartlomiej Zolnierkiewicz8fed4362009-02-25 20:28:24 +010079static void ide_disk_release(struct device *dev)
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020080{
Bartlomiej Zolnierkiewicz8fed4362009-02-25 20:28:24 +010081 struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020082 ide_drive_t *drive = idkp->drive;
83 struct gendisk *g = idkp->disk;
84
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +020085 drive->disk_ops = NULL;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +020086 drive->driver_data = NULL;
87 g->private_data = NULL;
88 put_disk(g);
89 kfree(idkp);
90}
91
92/*
93 * On HPA drives the capacity needs to be
94 * reinitilized on resume otherwise the disk
95 * can not be used and a hard reset is required
96 */
97static void ide_gd_resume(ide_drive_t *drive)
98{
99 if (ata_id_hpa_enabled(drive->id))
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200100 (void)drive->disk_ops->get_capacity(drive);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200101}
102
Bruno Prémontb0aedb02009-04-22 20:33:41 +0200103static const struct dmi_system_id ide_coldreboot_table[] = {
104 {
105 /* Acer TravelMate 66x cuts power during reboot */
106 .ident = "Acer TravelMate 660",
107 .matches = {
108 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
109 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
110 },
111 },
112
113 { } /* terminate list */
114};
115
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200116static void ide_gd_shutdown(ide_drive_t *drive)
117{
118#ifdef CONFIG_ALPHA
119 /* On Alpha, halt(8) doesn't actually turn the machine off,
120 it puts you into the sort of firmware monitor. Typically,
121 it's used to boot another kernel image, so it's not much
122 different from reboot(8). Therefore, we don't need to
123 spin down the disk in this case, especially since Alpha
124 firmware doesn't handle disks in standby mode properly.
125 On the other hand, it's reasonably safe to turn the power
126 off when the shutdown process reaches the firmware prompt,
127 as the firmware initialization takes rather long time -
128 at least 10 seconds, which should be sufficient for
129 the disk to expire its write cache. */
130 if (system_state != SYSTEM_POWER_OFF) {
131#else
Bruno Prémontb0aedb02009-04-22 20:33:41 +0200132 if (system_state == SYSTEM_RESTART &&
133 !dmi_check_system(ide_coldreboot_table)) {
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200134#endif
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200135 drive->disk_ops->flush(drive);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200136 return;
137 }
138
139 printk(KERN_INFO "Shutdown: %s\n", drive->name);
140
141 drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
142}
143
Bartlomiej Zolnierkiewicz79cb3802008-10-17 18:09:13 +0200144#ifdef CONFIG_IDE_PROC_FS
145static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
146{
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200147 return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc;
Bartlomiej Zolnierkiewicz79cb3802008-10-17 18:09:13 +0200148}
149
150static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
151{
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200152 return (drive->media == ide_disk) ? ide_disk_settings
153 : ide_floppy_settings;
Bartlomiej Zolnierkiewicz79cb3802008-10-17 18:09:13 +0200154}
155#endif
156
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200157static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
158 struct request *rq, sector_t sector)
159{
160 return drive->disk_ops->do_request(drive, rq, sector);
161}
162
Bartlomiej Zolnierkiewicz7f3c8682009-01-06 17:20:53 +0100163static struct ide_driver ide_gd_driver = {
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200164 .gen_driver = {
165 .owner = THIS_MODULE,
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200166 .name = "ide-gd",
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200167 .bus = &ide_bus_type,
168 },
169 .probe = ide_gd_probe,
170 .remove = ide_gd_remove,
171 .resume = ide_gd_resume,
172 .shutdown = ide_gd_shutdown,
173 .version = IDE_GD_VERSION,
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200174 .do_request = ide_gd_do_request,
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200175#ifdef CONFIG_IDE_PROC_FS
Bartlomiej Zolnierkiewicz79cb3802008-10-17 18:09:13 +0200176 .proc_entries = ide_disk_proc_entries,
177 .proc_devsets = ide_disk_proc_devsets,
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200178#endif
179};
180
Al Virob2f21e02008-10-16 10:34:00 -0400181static int ide_gd_open(struct block_device *bdev, fmode_t mode)
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200182{
Al Virob2f21e02008-10-16 10:34:00 -0400183 struct gendisk *disk = bdev->bd_disk;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200184 struct ide_disk_obj *idkp;
185 ide_drive_t *drive;
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200186 int ret = 0;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200187
188 idkp = ide_disk_get(disk);
189 if (idkp == NULL)
190 return -ENXIO;
191
192 drive = idkp->drive;
193
Borislav Petkov088b1b82009-01-02 13:34:47 +0100194 ide_debug_log(IDE_DBG_FUNC, "enter");
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200195
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200196 idkp->openers++;
197
198 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200199 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
200 /* Just in case */
201
202 ret = drive->disk_ops->init_media(drive, disk);
203
204 /*
205 * Allow O_NDELAY to open a drive without a disk, or with an
206 * unreadable disk, so that we can get the format capacity
207 * of the drive or begin the format - Sam
208 */
Al Virob2f21e02008-10-16 10:34:00 -0400209 if (ret && (mode & FMODE_NDELAY) == 0) {
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200210 ret = -EIO;
211 goto out_put_idkp;
212 }
213
Al Virob2f21e02008-10-16 10:34:00 -0400214 if ((drive->dev_flags & IDE_DFLAG_WP) && (mode & FMODE_WRITE)) {
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200215 ret = -EROFS;
216 goto out_put_idkp;
217 }
218
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200219 /*
220 * Ignore the return code from door_lock,
221 * since the open() has already succeeded,
222 * and the door_lock is irrelevant at this point.
223 */
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200224 drive->disk_ops->set_doorlock(drive, disk, 1);
Bartlomiej Zolnierkiewiczcedd1202008-10-17 18:09:12 +0200225 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
Al Virob2f21e02008-10-16 10:34:00 -0400226 check_disk_change(bdev);
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200227 } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
228 ret = -EBUSY;
229 goto out_put_idkp;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200230 }
231 return 0;
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200232
233out_put_idkp:
234 idkp->openers--;
235 ide_disk_put(idkp);
236 return ret;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200237}
238
Al Virob2f21e02008-10-16 10:34:00 -0400239static int ide_gd_release(struct gendisk *disk, fmode_t mode)
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200240{
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200241 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
242 ide_drive_t *drive = idkp->drive;
243
Borislav Petkov088b1b82009-01-02 13:34:47 +0100244 ide_debug_log(IDE_DBG_FUNC, "enter");
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200245
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200246 if (idkp->openers == 1)
247 drive->disk_ops->flush(drive);
248
249 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
250 drive->disk_ops->set_doorlock(drive, disk, 0);
251 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
252 }
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200253
254 idkp->openers--;
255
256 ide_disk_put(idkp);
257
258 return 0;
259}
260
261static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
262{
263 struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
264 ide_drive_t *drive = idkp->drive;
265
266 geo->heads = drive->bios_head;
267 geo->sectors = drive->bios_sect;
268 geo->cylinders = (u16)drive->bios_cyl; /* truncate */
269 return 0;
270}
271
272static int ide_gd_media_changed(struct gendisk *disk)
273{
274 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
275 ide_drive_t *drive = idkp->drive;
Bartlomiej Zolnierkiewiczcedd1202008-10-17 18:09:12 +0200276 int ret;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200277
278 /* do not scan partitions twice if this is a removable device */
279 if (drive->dev_flags & IDE_DFLAG_ATTACH) {
280 drive->dev_flags &= ~IDE_DFLAG_ATTACH;
281 return 0;
282 }
283
Bartlomiej Zolnierkiewiczcedd1202008-10-17 18:09:12 +0200284 ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED);
285 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
286
287 return ret;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200288}
289
Bartlomiej Zolnierkiewicze957b602009-06-07 13:52:52 +0200290static unsigned long long ide_gd_set_capacity(struct gendisk *disk,
291 unsigned long long capacity)
292{
293 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
294 ide_drive_t *drive = idkp->drive;
295 const struct ide_disk_ops *disk_ops = drive->disk_ops;
296
297 if (disk_ops->set_capacity)
298 return disk_ops->set_capacity(drive, capacity);
299
300 return drive->capacity64;
301}
302
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200303static int ide_gd_revalidate_disk(struct gendisk *disk)
304{
305 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
Borislav Petkov52ebb432008-11-02 21:40:10 +0100306 ide_drive_t *drive = idkp->drive;
307
308 if (ide_gd_media_changed(disk))
309 drive->disk_ops->get_capacity(drive);
310
311 set_capacity(disk, ide_gd_capacity(drive));
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200312 return 0;
313}
314
Al Virob2f21e02008-10-16 10:34:00 -0400315static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode,
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200316 unsigned int cmd, unsigned long arg)
317{
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200318 struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
319 ide_drive_t *drive = idkp->drive;
320
Al Virob2f21e02008-10-16 10:34:00 -0400321 return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg);
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200322}
323
Alexey Dobriyan83d5cde2009-09-21 17:01:13 -0700324static const struct block_device_operations ide_gd_ops = {
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200325 .owner = THIS_MODULE,
Al Virob2f21e02008-10-16 10:34:00 -0400326 .open = ide_gd_open,
327 .release = ide_gd_release,
328 .locked_ioctl = ide_gd_ioctl,
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200329 .getgeo = ide_gd_getgeo,
330 .media_changed = ide_gd_media_changed,
Bartlomiej Zolnierkiewicze957b602009-06-07 13:52:52 +0200331 .set_capacity = ide_gd_set_capacity,
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200332 .revalidate_disk = ide_gd_revalidate_disk
333};
334
335static int ide_gd_probe(ide_drive_t *drive)
336{
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200337 const struct ide_disk_ops *disk_ops = NULL;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200338 struct ide_disk_obj *idkp;
339 struct gendisk *g;
340
341 /* strstr("foo", "") is non-NULL */
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200342 if (!strstr("ide-gd", drive->driver_req))
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200343 goto failed;
344
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200345#ifdef CONFIG_IDE_GD_ATA
346 if (drive->media == ide_disk)
347 disk_ops = &ide_ata_disk_ops;
348#endif
349#ifdef CONFIG_IDE_GD_ATAPI
350 if (drive->media == ide_floppy)
351 disk_ops = &ide_atapi_disk_ops;
352#endif
353 if (disk_ops == NULL)
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200354 goto failed;
355
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200356 if (disk_ops->check(drive, DRV_NAME) == 0) {
357 printk(KERN_ERR PFX "%s: not supported by this driver\n",
358 drive->name);
359 goto failed;
360 }
361
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200362 idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200363 if (!idkp) {
364 printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
365 drive->name);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200366 goto failed;
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200367 }
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200368
369 g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
370 if (!g)
371 goto out_free_idkp;
372
373 ide_init_disk(g, drive);
374
Bartlomiej Zolnierkiewicz8fed4362009-02-25 20:28:24 +0100375 idkp->dev.parent = &drive->gendev;
376 idkp->dev.release = ide_disk_release;
377 dev_set_name(&idkp->dev, dev_name(&drive->gendev));
378
379 if (device_register(&idkp->dev))
380 goto out_free_disk;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200381
382 idkp->drive = drive;
383 idkp->driver = &ide_gd_driver;
384 idkp->disk = g;
385
386 g->private_data = &idkp->driver;
387
388 drive->driver_data = idkp;
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200389 drive->debug_mask = debug_mask;
390 drive->disk_ops = disk_ops;
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200391
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200392 disk_ops->setup(drive);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200393
394 set_capacity(g, ide_gd_capacity(drive));
395
396 g->minors = IDE_DISK_MINORS;
397 g->driverfs_dev = &drive->gendev;
398 g->flags |= GENHD_FL_EXT_DEVT;
399 if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
400 g->flags = GENHD_FL_REMOVABLE;
401 g->fops = &ide_gd_ops;
402 add_disk(g);
403 return 0;
404
Bartlomiej Zolnierkiewicz8fed4362009-02-25 20:28:24 +0100405out_free_disk:
406 put_disk(g);
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200407out_free_idkp:
408 kfree(idkp);
409failed:
410 return -ENODEV;
411}
412
413static int __init ide_gd_init(void)
414{
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200415 printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200416 return driver_register(&ide_gd_driver.gen_driver);
417}
418
419static void __exit ide_gd_exit(void)
420{
421 driver_unregister(&ide_gd_driver.gen_driver);
422}
423
424MODULE_ALIAS("ide:*m-disk*");
425MODULE_ALIAS("ide-disk");
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200426MODULE_ALIAS("ide:*m-floppy*");
427MODULE_ALIAS("ide-floppy");
Bartlomiej Zolnierkiewicz5fef0e52008-10-17 18:09:12 +0200428module_init(ide_gd_init);
429module_exit(ide_gd_exit);
430MODULE_LICENSE("GPL");
Bartlomiej Zolnierkiewicz806f80a2008-10-17 18:09:14 +0200431MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");