Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1// SPDX-License-Identifier: GPL-2.0-only
  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>
 11#include <linux/dmi.h>
 12#include <linux/slab.h>
 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"
 21#include "ide-floppy.h"
 22
 23#define IDE_GD_VERSION	"1.18"
 24
 25/* module parameters */
 26static DEFINE_MUTEX(ide_gd_mutex);
 27static unsigned long debug_mask;
 28module_param(debug_mask, ulong, 0644);
 29
 30static DEFINE_MUTEX(ide_disk_ref_mutex);
 31
 32static void ide_disk_release(struct device *);
 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
 44			get_device(&idkp->dev);
 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);
 55	put_device(&idkp->dev);
 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);
 73	device_del(&idkp->dev);
 74	del_gendisk(g);
 75	drive->disk_ops->flush(drive);
 76
 77	mutex_lock(&ide_disk_ref_mutex);
 78	put_device(&idkp->dev);
 79	mutex_unlock(&ide_disk_ref_mutex);
 80}
 81
 82static void ide_disk_release(struct device *dev)
 83{
 84	struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj);
 85	ide_drive_t *drive = idkp->drive;
 86	struct gendisk *g = idkp->disk;
 87
 88	drive->disk_ops = NULL;
 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
 97 * reinitialized on resume otherwise the disk
 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))
103		(void)drive->disk_ops->get_capacity(drive);
104}
105
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
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
135	if (system_state == SYSTEM_RESTART &&
136		!dmi_check_system(ide_coldreboot_table)) {
137#endif
138		drive->disk_ops->flush(drive);
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
147#ifdef CONFIG_IDE_PROC_FS
148static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
149{
150	return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc;
151}
152
153static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
154{
155	return (drive->media == ide_disk) ? ide_disk_settings
156					  : ide_floppy_settings;
157}
158#endif
159
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
166static struct ide_driver ide_gd_driver = {
167	.gen_driver = {
168		.owner		= THIS_MODULE,
169		.name		= "ide-gd",
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,
177	.do_request		= ide_gd_do_request,
178#ifdef CONFIG_IDE_PROC_FS
179	.proc_entries		= ide_disk_proc_entries,
180	.proc_devsets		= ide_disk_proc_devsets,
181#endif
182};
183
184static int ide_gd_open(struct block_device *bdev, fmode_t mode)
185{
186	struct gendisk *disk = bdev->bd_disk;
187	struct ide_disk_obj *idkp;
188	ide_drive_t *drive;
189	int ret = 0;
190
191	idkp = ide_disk_get(disk);
192	if (idkp == NULL)
193		return -ENXIO;
194
195	drive = idkp->drive;
196
197	ide_debug_log(IDE_DBG_FUNC, "enter");
198
199	idkp->openers++;
200
201	if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
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		 */
212		if (ret && (mode & FMODE_NDELAY) == 0) {
213			ret = -EIO;
214			goto out_put_idkp;
215		}
216
217		if ((drive->dev_flags & IDE_DFLAG_WP) && (mode & FMODE_WRITE)) {
218			ret = -EROFS;
219			goto out_put_idkp;
220		}
221
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		 */
227		drive->disk_ops->set_doorlock(drive, disk, 1);
228		drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
229		check_disk_change(bdev);
230	} else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
231		ret = -EBUSY;
232		goto out_put_idkp;
233	}
234	return 0;
235
236out_put_idkp:
237	idkp->openers--;
238	ide_disk_put(idkp);
239	return ret;
240}
241
242static int ide_gd_unlocked_open(struct block_device *bdev, fmode_t mode)
243{
244	int ret;
245
246	mutex_lock(&ide_gd_mutex);
247	ret = ide_gd_open(bdev, mode);
248	mutex_unlock(&ide_gd_mutex);
249
250	return ret;
251}
252
253
254static void ide_gd_release(struct gendisk *disk, fmode_t mode)
255{
256	struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
257	ide_drive_t *drive = idkp->drive;
258
259	ide_debug_log(IDE_DBG_FUNC, "enter");
260
261	mutex_lock(&ide_gd_mutex);
262	if (idkp->openers == 1)
263		drive->disk_ops->flush(drive);
264
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	}
269
270	idkp->openers--;
271
272	ide_disk_put(idkp);
273	mutex_unlock(&ide_gd_mutex);
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
287static unsigned int ide_gd_check_events(struct gendisk *disk,
288					unsigned int clearing)
289{
290	struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
291	ide_drive_t *drive = idkp->drive;
292	bool ret;
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
300	/*
301	 * The following is used to force revalidation on the first open on
302	 * removeable devices, and never gets reported to userland as
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.
306	 */
307	ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED;
308	drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
309
310	return ret ? DISK_EVENT_MEDIA_CHANGE : 0;
311}
312
313static void ide_gd_unlock_native_capacity(struct gendisk *disk)
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
319	if (disk_ops->unlock_native_capacity)
320		disk_ops->unlock_native_capacity(drive);
321}
322
323static int ide_gd_revalidate_disk(struct gendisk *disk)
324{
325	struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
326	ide_drive_t *drive = idkp->drive;
327
328	if (ide_gd_check_events(disk, 0))
329		drive->disk_ops->get_capacity(drive);
330
331	set_capacity(disk, ide_gd_capacity(drive));
332	return 0;
333}
334
335static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode,
336			     unsigned int cmd, unsigned long arg)
337{
338	struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
339	ide_drive_t *drive = idkp->drive;
340
341	return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg);
342}
343
344static const struct block_device_operations ide_gd_ops = {
345	.owner			= THIS_MODULE,
346	.open			= ide_gd_unlocked_open,
347	.release		= ide_gd_release,
348	.ioctl			= ide_gd_ioctl,
349	.getgeo			= ide_gd_getgeo,
350	.check_events		= ide_gd_check_events,
351	.unlock_native_capacity	= ide_gd_unlock_native_capacity,
352	.revalidate_disk	= ide_gd_revalidate_disk
353};
354
355static int ide_gd_probe(ide_drive_t *drive)
356{
357	const struct ide_disk_ops *disk_ops = NULL;
358	struct ide_disk_obj *idkp;
359	struct gendisk *g;
360
361	/* strstr("foo", "") is non-NULL */
362	if (!strstr("ide-gd", drive->driver_req))
363		goto failed;
364
365#ifdef CONFIG_IDE_GD_ATA
366	if (drive->media == ide_disk)
367		disk_ops = &ide_ata_disk_ops;
368#endif
369#ifdef CONFIG_IDE_GD_ATAPI
370	if (drive->media == ide_floppy)
371		disk_ops = &ide_atapi_disk_ops;
372#endif
373	if (disk_ops == NULL)
374		goto failed;
375
376	if (disk_ops->check(drive, DRV_NAME) == 0) {
377		printk(KERN_ERR PFX "%s: not supported by this driver\n",
378			drive->name);
379		goto failed;
380	}
381
382	idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
383	if (!idkp) {
384		printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
385			drive->name);
386		goto failed;
387	}
388
389	g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
390	if (!g)
391		goto out_free_idkp;
392
393	ide_init_disk(g, drive);
394
395	idkp->dev.parent = &drive->gendev;
396	idkp->dev.release = ide_disk_release;
397	dev_set_name(&idkp->dev, "%s", dev_name(&drive->gendev));
398
399	if (device_register(&idkp->dev))
400		goto out_free_disk;
401
402	idkp->drive = drive;
403	idkp->driver = &ide_gd_driver;
404	idkp->disk = g;
405
406	g->private_data = &idkp->driver;
407
408	drive->driver_data = idkp;
409	drive->debug_mask = debug_mask;
410	drive->disk_ops = disk_ops;
411
412	disk_ops->setup(drive);
413
414	set_capacity(g, ide_gd_capacity(drive));
415
416	g->minors = IDE_DISK_MINORS;
417	g->flags |= GENHD_FL_EXT_DEVT;
418	if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
419		g->flags = GENHD_FL_REMOVABLE;
420	g->fops = &ide_gd_ops;
421	g->events = DISK_EVENT_MEDIA_CHANGE;
422	device_add_disk(&drive->gendev, g, NULL);
423	return 0;
424
425out_free_disk:
426	put_disk(g);
427out_free_idkp:
428	kfree(idkp);
429failed:
430	return -ENODEV;
431}
432
433static int __init ide_gd_init(void)
434{
435	printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
436	return driver_register(&ide_gd_driver.gen_driver);
437}
438
439static void __exit ide_gd_exit(void)
440{
441	driver_unregister(&ide_gd_driver.gen_driver);
442}
443
444MODULE_ALIAS("ide:*m-disk*");
445MODULE_ALIAS("ide-disk");
446MODULE_ALIAS("ide:*m-floppy*");
447MODULE_ALIAS("ide-floppy");
448module_init(ide_gd_init);
449module_exit(ide_gd_exit);
450MODULE_LICENSE("GPL");
451MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");