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