1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun #include <linux/module.h>
3*4882a593Smuzhiyun #include <linux/types.h>
4*4882a593Smuzhiyun #include <linux/string.h>
5*4882a593Smuzhiyun #include <linux/kernel.h>
6*4882a593Smuzhiyun #include <linux/errno.h>
7*4882a593Smuzhiyun #include <linux/genhd.h>
8*4882a593Smuzhiyun #include <linux/mutex.h>
9*4882a593Smuzhiyun #include <linux/ide.h>
10*4882a593Smuzhiyun #include <linux/hdreg.h>
11*4882a593Smuzhiyun #include <linux/dmi.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
15*4882a593Smuzhiyun #define IDE_DISK_MINORS (1 << PARTN_BITS)
16*4882a593Smuzhiyun #else
17*4882a593Smuzhiyun #define IDE_DISK_MINORS 0
18*4882a593Smuzhiyun #endif
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #include "ide-disk.h"
21*4882a593Smuzhiyun #include "ide-floppy.h"
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define IDE_GD_VERSION "1.18"
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun /* module parameters */
26*4882a593Smuzhiyun static DEFINE_MUTEX(ide_gd_mutex);
27*4882a593Smuzhiyun static unsigned long debug_mask;
28*4882a593Smuzhiyun module_param(debug_mask, ulong, 0644);
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun static DEFINE_MUTEX(ide_disk_ref_mutex);
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun static void ide_disk_release(struct device *);
33*4882a593Smuzhiyun
ide_disk_get(struct gendisk * disk)34*4882a593Smuzhiyun static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun struct ide_disk_obj *idkp = NULL;
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun mutex_lock(&ide_disk_ref_mutex);
39*4882a593Smuzhiyun idkp = ide_drv_g(disk, ide_disk_obj);
40*4882a593Smuzhiyun if (idkp) {
41*4882a593Smuzhiyun if (ide_device_get(idkp->drive))
42*4882a593Smuzhiyun idkp = NULL;
43*4882a593Smuzhiyun else
44*4882a593Smuzhiyun get_device(&idkp->dev);
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun mutex_unlock(&ide_disk_ref_mutex);
47*4882a593Smuzhiyun return idkp;
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun
ide_disk_put(struct ide_disk_obj * idkp)50*4882a593Smuzhiyun static void ide_disk_put(struct ide_disk_obj *idkp)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun ide_drive_t *drive = idkp->drive;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun mutex_lock(&ide_disk_ref_mutex);
55*4882a593Smuzhiyun put_device(&idkp->dev);
56*4882a593Smuzhiyun ide_device_put(drive);
57*4882a593Smuzhiyun mutex_unlock(&ide_disk_ref_mutex);
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
ide_gd_capacity(ide_drive_t * drive)60*4882a593Smuzhiyun sector_t ide_gd_capacity(ide_drive_t *drive)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun return drive->capacity64;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun static int ide_gd_probe(ide_drive_t *);
66*4882a593Smuzhiyun
ide_gd_remove(ide_drive_t * drive)67*4882a593Smuzhiyun static void ide_gd_remove(ide_drive_t *drive)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun struct ide_disk_obj *idkp = drive->driver_data;
70*4882a593Smuzhiyun struct gendisk *g = idkp->disk;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun ide_proc_unregister_driver(drive, idkp->driver);
73*4882a593Smuzhiyun device_del(&idkp->dev);
74*4882a593Smuzhiyun del_gendisk(g);
75*4882a593Smuzhiyun drive->disk_ops->flush(drive);
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun mutex_lock(&ide_disk_ref_mutex);
78*4882a593Smuzhiyun put_device(&idkp->dev);
79*4882a593Smuzhiyun mutex_unlock(&ide_disk_ref_mutex);
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun
ide_disk_release(struct device * dev)82*4882a593Smuzhiyun static void ide_disk_release(struct device *dev)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj);
85*4882a593Smuzhiyun ide_drive_t *drive = idkp->drive;
86*4882a593Smuzhiyun struct gendisk *g = idkp->disk;
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun drive->disk_ops = NULL;
89*4882a593Smuzhiyun drive->driver_data = NULL;
90*4882a593Smuzhiyun g->private_data = NULL;
91*4882a593Smuzhiyun put_disk(g);
92*4882a593Smuzhiyun kfree(idkp);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /*
96*4882a593Smuzhiyun * On HPA drives the capacity needs to be
97*4882a593Smuzhiyun * reinitialized on resume otherwise the disk
98*4882a593Smuzhiyun * can not be used and a hard reset is required
99*4882a593Smuzhiyun */
ide_gd_resume(ide_drive_t * drive)100*4882a593Smuzhiyun static void ide_gd_resume(ide_drive_t *drive)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun if (ata_id_hpa_enabled(drive->id))
103*4882a593Smuzhiyun (void)drive->disk_ops->get_capacity(drive);
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun static const struct dmi_system_id ide_coldreboot_table[] = {
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun /* Acer TravelMate 66x cuts power during reboot */
109*4882a593Smuzhiyun .ident = "Acer TravelMate 660",
110*4882a593Smuzhiyun .matches = {
111*4882a593Smuzhiyun DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
112*4882a593Smuzhiyun DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
113*4882a593Smuzhiyun },
114*4882a593Smuzhiyun },
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun { } /* terminate list */
117*4882a593Smuzhiyun };
118*4882a593Smuzhiyun
ide_gd_shutdown(ide_drive_t * drive)119*4882a593Smuzhiyun static void ide_gd_shutdown(ide_drive_t *drive)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun #ifdef CONFIG_ALPHA
122*4882a593Smuzhiyun /* On Alpha, halt(8) doesn't actually turn the machine off,
123*4882a593Smuzhiyun it puts you into the sort of firmware monitor. Typically,
124*4882a593Smuzhiyun it's used to boot another kernel image, so it's not much
125*4882a593Smuzhiyun different from reboot(8). Therefore, we don't need to
126*4882a593Smuzhiyun spin down the disk in this case, especially since Alpha
127*4882a593Smuzhiyun firmware doesn't handle disks in standby mode properly.
128*4882a593Smuzhiyun On the other hand, it's reasonably safe to turn the power
129*4882a593Smuzhiyun off when the shutdown process reaches the firmware prompt,
130*4882a593Smuzhiyun as the firmware initialization takes rather long time -
131*4882a593Smuzhiyun at least 10 seconds, which should be sufficient for
132*4882a593Smuzhiyun the disk to expire its write cache. */
133*4882a593Smuzhiyun if (system_state != SYSTEM_POWER_OFF) {
134*4882a593Smuzhiyun #else
135*4882a593Smuzhiyun if (system_state == SYSTEM_RESTART &&
136*4882a593Smuzhiyun !dmi_check_system(ide_coldreboot_table)) {
137*4882a593Smuzhiyun #endif
138*4882a593Smuzhiyun drive->disk_ops->flush(drive);
139*4882a593Smuzhiyun return;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun printk(KERN_INFO "Shutdown: %s\n", drive->name);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun #ifdef CONFIG_IDE_PROC_FS
148*4882a593Smuzhiyun static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun return (drive->media == ide_disk) ? ide_disk_settings
156*4882a593Smuzhiyun : ide_floppy_settings;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun #endif
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
161*4882a593Smuzhiyun struct request *rq, sector_t sector)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun return drive->disk_ops->do_request(drive, rq, sector);
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun static struct ide_driver ide_gd_driver = {
167*4882a593Smuzhiyun .gen_driver = {
168*4882a593Smuzhiyun .owner = THIS_MODULE,
169*4882a593Smuzhiyun .name = "ide-gd",
170*4882a593Smuzhiyun .bus = &ide_bus_type,
171*4882a593Smuzhiyun },
172*4882a593Smuzhiyun .probe = ide_gd_probe,
173*4882a593Smuzhiyun .remove = ide_gd_remove,
174*4882a593Smuzhiyun .resume = ide_gd_resume,
175*4882a593Smuzhiyun .shutdown = ide_gd_shutdown,
176*4882a593Smuzhiyun .version = IDE_GD_VERSION,
177*4882a593Smuzhiyun .do_request = ide_gd_do_request,
178*4882a593Smuzhiyun #ifdef CONFIG_IDE_PROC_FS
179*4882a593Smuzhiyun .proc_entries = ide_disk_proc_entries,
180*4882a593Smuzhiyun .proc_devsets = ide_disk_proc_devsets,
181*4882a593Smuzhiyun #endif
182*4882a593Smuzhiyun };
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun static int ide_gd_open(struct block_device *bdev, fmode_t mode)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun struct gendisk *disk = bdev->bd_disk;
187*4882a593Smuzhiyun struct ide_disk_obj *idkp;
188*4882a593Smuzhiyun ide_drive_t *drive;
189*4882a593Smuzhiyun int ret = 0;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun idkp = ide_disk_get(disk);
192*4882a593Smuzhiyun if (idkp == NULL)
193*4882a593Smuzhiyun return -ENXIO;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun drive = idkp->drive;
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun ide_debug_log(IDE_DBG_FUNC, "enter");
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun idkp->openers++;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
202*4882a593Smuzhiyun drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
203*4882a593Smuzhiyun /* Just in case */
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun ret = drive->disk_ops->init_media(drive, disk);
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun /*
208*4882a593Smuzhiyun * Allow O_NDELAY to open a drive without a disk, or with an
209*4882a593Smuzhiyun * unreadable disk, so that we can get the format capacity
210*4882a593Smuzhiyun * of the drive or begin the format - Sam
211*4882a593Smuzhiyun */
212*4882a593Smuzhiyun if (ret && (mode & FMODE_NDELAY) == 0) {
213*4882a593Smuzhiyun ret = -EIO;
214*4882a593Smuzhiyun goto out_put_idkp;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun if ((drive->dev_flags & IDE_DFLAG_WP) && (mode & FMODE_WRITE)) {
218*4882a593Smuzhiyun ret = -EROFS;
219*4882a593Smuzhiyun goto out_put_idkp;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /*
223*4882a593Smuzhiyun * Ignore the return code from door_lock,
224*4882a593Smuzhiyun * since the open() has already succeeded,
225*4882a593Smuzhiyun * and the door_lock is irrelevant at this point.
226*4882a593Smuzhiyun */
227*4882a593Smuzhiyun drive->disk_ops->set_doorlock(drive, disk, 1);
228*4882a593Smuzhiyun if (__invalidate_device(bdev, true))
229*4882a593Smuzhiyun pr_warn("VFS: busy inodes on changed media %s\n",
230*4882a593Smuzhiyun bdev->bd_disk->disk_name);
231*4882a593Smuzhiyun drive->disk_ops->get_capacity(drive);
232*4882a593Smuzhiyun set_capacity(disk, ide_gd_capacity(drive));
233*4882a593Smuzhiyun set_bit(GD_NEED_PART_SCAN, &disk->state);
234*4882a593Smuzhiyun } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
235*4882a593Smuzhiyun ret = -EBUSY;
236*4882a593Smuzhiyun goto out_put_idkp;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun return 0;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun out_put_idkp:
241*4882a593Smuzhiyun idkp->openers--;
242*4882a593Smuzhiyun ide_disk_put(idkp);
243*4882a593Smuzhiyun return ret;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun static int ide_gd_unlocked_open(struct block_device *bdev, fmode_t mode)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun int ret;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun mutex_lock(&ide_gd_mutex);
251*4882a593Smuzhiyun ret = ide_gd_open(bdev, mode);
252*4882a593Smuzhiyun mutex_unlock(&ide_gd_mutex);
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun return ret;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun static void ide_gd_release(struct gendisk *disk, fmode_t mode)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
261*4882a593Smuzhiyun ide_drive_t *drive = idkp->drive;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun ide_debug_log(IDE_DBG_FUNC, "enter");
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun mutex_lock(&ide_gd_mutex);
266*4882a593Smuzhiyun if (idkp->openers == 1)
267*4882a593Smuzhiyun drive->disk_ops->flush(drive);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
270*4882a593Smuzhiyun drive->disk_ops->set_doorlock(drive, disk, 0);
271*4882a593Smuzhiyun drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun idkp->openers--;
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun ide_disk_put(idkp);
277*4882a593Smuzhiyun mutex_unlock(&ide_gd_mutex);
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
283*4882a593Smuzhiyun ide_drive_t *drive = idkp->drive;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun geo->heads = drive->bios_head;
286*4882a593Smuzhiyun geo->sectors = drive->bios_sect;
287*4882a593Smuzhiyun geo->cylinders = (u16)drive->bios_cyl; /* truncate */
288*4882a593Smuzhiyun return 0;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun static void ide_gd_unlock_native_capacity(struct gendisk *disk)
292*4882a593Smuzhiyun {
293*4882a593Smuzhiyun struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
294*4882a593Smuzhiyun ide_drive_t *drive = idkp->drive;
295*4882a593Smuzhiyun const struct ide_disk_ops *disk_ops = drive->disk_ops;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun if (disk_ops->unlock_native_capacity)
298*4882a593Smuzhiyun disk_ops->unlock_native_capacity(drive);
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode,
302*4882a593Smuzhiyun unsigned int cmd, unsigned long arg)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
305*4882a593Smuzhiyun ide_drive_t *drive = idkp->drive;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun #ifdef CONFIG_COMPAT
311*4882a593Smuzhiyun static int ide_gd_compat_ioctl(struct block_device *bdev, fmode_t mode,
312*4882a593Smuzhiyun unsigned int cmd, unsigned long arg)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
315*4882a593Smuzhiyun ide_drive_t *drive = idkp->drive;
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun if (!drive->disk_ops->compat_ioctl)
318*4882a593Smuzhiyun return -ENOIOCTLCMD;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun return drive->disk_ops->compat_ioctl(drive, bdev, mode, cmd, arg);
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun #endif
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun static const struct block_device_operations ide_gd_ops = {
325*4882a593Smuzhiyun .owner = THIS_MODULE,
326*4882a593Smuzhiyun .open = ide_gd_unlocked_open,
327*4882a593Smuzhiyun .release = ide_gd_release,
328*4882a593Smuzhiyun .ioctl = ide_gd_ioctl,
329*4882a593Smuzhiyun #ifdef CONFIG_COMPAT
330*4882a593Smuzhiyun .compat_ioctl = ide_gd_compat_ioctl,
331*4882a593Smuzhiyun #endif
332*4882a593Smuzhiyun .getgeo = ide_gd_getgeo,
333*4882a593Smuzhiyun .unlock_native_capacity = ide_gd_unlock_native_capacity,
334*4882a593Smuzhiyun };
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun static int ide_gd_probe(ide_drive_t *drive)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun const struct ide_disk_ops *disk_ops = NULL;
339*4882a593Smuzhiyun struct ide_disk_obj *idkp;
340*4882a593Smuzhiyun struct gendisk *g;
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun /* strstr("foo", "") is non-NULL */
343*4882a593Smuzhiyun if (!strstr("ide-gd", drive->driver_req))
344*4882a593Smuzhiyun goto failed;
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun #ifdef CONFIG_IDE_GD_ATA
347*4882a593Smuzhiyun if (drive->media == ide_disk)
348*4882a593Smuzhiyun disk_ops = &ide_ata_disk_ops;
349*4882a593Smuzhiyun #endif
350*4882a593Smuzhiyun #ifdef CONFIG_IDE_GD_ATAPI
351*4882a593Smuzhiyun if (drive->media == ide_floppy)
352*4882a593Smuzhiyun disk_ops = &ide_atapi_disk_ops;
353*4882a593Smuzhiyun #endif
354*4882a593Smuzhiyun if (disk_ops == NULL)
355*4882a593Smuzhiyun goto failed;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun if (disk_ops->check(drive, DRV_NAME) == 0) {
358*4882a593Smuzhiyun printk(KERN_ERR PFX "%s: not supported by this driver\n",
359*4882a593Smuzhiyun drive->name);
360*4882a593Smuzhiyun goto failed;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
364*4882a593Smuzhiyun if (!idkp) {
365*4882a593Smuzhiyun printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
366*4882a593Smuzhiyun drive->name);
367*4882a593Smuzhiyun goto failed;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
371*4882a593Smuzhiyun if (!g)
372*4882a593Smuzhiyun goto out_free_idkp;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun ide_init_disk(g, drive);
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun idkp->dev.parent = &drive->gendev;
377*4882a593Smuzhiyun idkp->dev.release = ide_disk_release;
378*4882a593Smuzhiyun dev_set_name(&idkp->dev, "%s", dev_name(&drive->gendev));
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun if (device_register(&idkp->dev))
381*4882a593Smuzhiyun goto out_free_disk;
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun idkp->drive = drive;
384*4882a593Smuzhiyun idkp->driver = &ide_gd_driver;
385*4882a593Smuzhiyun idkp->disk = g;
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun g->private_data = &idkp->driver;
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun drive->driver_data = idkp;
390*4882a593Smuzhiyun drive->debug_mask = debug_mask;
391*4882a593Smuzhiyun drive->disk_ops = disk_ops;
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun disk_ops->setup(drive);
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun set_capacity(g, ide_gd_capacity(drive));
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun g->minors = IDE_DISK_MINORS;
398*4882a593Smuzhiyun g->flags |= GENHD_FL_EXT_DEVT;
399*4882a593Smuzhiyun if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
400*4882a593Smuzhiyun g->flags = GENHD_FL_REMOVABLE;
401*4882a593Smuzhiyun g->fops = &ide_gd_ops;
402*4882a593Smuzhiyun g->events = DISK_EVENT_MEDIA_CHANGE;
403*4882a593Smuzhiyun device_add_disk(&drive->gendev, g, NULL);
404*4882a593Smuzhiyun return 0;
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun out_free_disk:
407*4882a593Smuzhiyun put_disk(g);
408*4882a593Smuzhiyun out_free_idkp:
409*4882a593Smuzhiyun kfree(idkp);
410*4882a593Smuzhiyun failed:
411*4882a593Smuzhiyun return -ENODEV;
412*4882a593Smuzhiyun }
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun static int __init ide_gd_init(void)
415*4882a593Smuzhiyun {
416*4882a593Smuzhiyun printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
417*4882a593Smuzhiyun return driver_register(&ide_gd_driver.gen_driver);
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun static void __exit ide_gd_exit(void)
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun driver_unregister(&ide_gd_driver.gen_driver);
423*4882a593Smuzhiyun }
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun MODULE_ALIAS("ide:*m-disk*");
426*4882a593Smuzhiyun MODULE_ALIAS("ide-disk");
427*4882a593Smuzhiyun MODULE_ALIAS("ide:*m-floppy*");
428*4882a593Smuzhiyun MODULE_ALIAS("ide-floppy");
429*4882a593Smuzhiyun module_init(ide_gd_init);
430*4882a593Smuzhiyun module_exit(ide_gd_exit);
431*4882a593Smuzhiyun MODULE_LICENSE("GPL");
432*4882a593Smuzhiyun MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");
433