]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/ide/ide-gd.c
const: make lock_manager_operations const
[net-next-2.6.git] / drivers / ide / ide-gd.c
CommitLineData
5fef0e5c
BZ
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>
b0aedb04 10#include <linux/dmi.h>
5fef0e5c
BZ
11
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"
806f80a6 19#include "ide-floppy.h"
5fef0e5c
BZ
20
21#define IDE_GD_VERSION "1.18"
22
806f80a6
BZ
23/* module parameters */
24static unsigned long debug_mask;
25module_param(debug_mask, ulong, 0644);
26
5fef0e5c
BZ
27static DEFINE_MUTEX(ide_disk_ref_mutex);
28
8fed4368 29static void ide_disk_release(struct device *);
5fef0e5c
BZ
30
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
8fed4368 41 get_device(&idkp->dev);
5fef0e5c
BZ
42 }
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);
8fed4368 52 put_device(&idkp->dev);
5fef0e5c
BZ
53 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);
8fed4368 70 device_del(&idkp->dev);
5fef0e5c 71 del_gendisk(g);
806f80a6 72 drive->disk_ops->flush(drive);
5fef0e5c 73
8fed4368
BZ
74 mutex_lock(&ide_disk_ref_mutex);
75 put_device(&idkp->dev);
76 mutex_unlock(&ide_disk_ref_mutex);
5fef0e5c
BZ
77}
78
8fed4368 79static void ide_disk_release(struct device *dev)
5fef0e5c 80{
8fed4368 81 struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj);
5fef0e5c
BZ
82 ide_drive_t *drive = idkp->drive;
83 struct gendisk *g = idkp->disk;
84
806f80a6 85 drive->disk_ops = NULL;
5fef0e5c
BZ
86 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))
806f80a6 100 (void)drive->disk_ops->get_capacity(drive);
5fef0e5c
BZ
101}
102
b0aedb04
BP
103static 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
5fef0e5c
BZ
116static 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
b0aedb04
BP
132 if (system_state == SYSTEM_RESTART &&
133 !dmi_check_system(ide_coldreboot_table)) {
5fef0e5c 134#endif
806f80a6 135 drive->disk_ops->flush(drive);
5fef0e5c
BZ
136 return;
137 }
138
139 printk(KERN_INFO "Shutdown: %s\n", drive->name);
140
141 drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
142}
143
79cb3803
BZ
144#ifdef CONFIG_IDE_PROC_FS
145static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
146{
806f80a6 147 return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc;
79cb3803
BZ
148}
149
150static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
151{
806f80a6
BZ
152 return (drive->media == ide_disk) ? ide_disk_settings
153 : ide_floppy_settings;
79cb3803
BZ
154}
155#endif
156
806f80a6
BZ
157static 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
7f3c868b 163static struct ide_driver ide_gd_driver = {
5fef0e5c
BZ
164 .gen_driver = {
165 .owner = THIS_MODULE,
806f80a6 166 .name = "ide-gd",
5fef0e5c
BZ
167 .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,
806f80a6 174 .do_request = ide_gd_do_request,
5fef0e5c 175#ifdef CONFIG_IDE_PROC_FS
79cb3803
BZ
176 .proc_entries = ide_disk_proc_entries,
177 .proc_devsets = ide_disk_proc_devsets,
5fef0e5c
BZ
178#endif
179};
180
b2f21e05 181static int ide_gd_open(struct block_device *bdev, fmode_t mode)
5fef0e5c 182{
b2f21e05 183 struct gendisk *disk = bdev->bd_disk;
5fef0e5c
BZ
184 struct ide_disk_obj *idkp;
185 ide_drive_t *drive;
806f80a6 186 int ret = 0;
5fef0e5c
BZ
187
188 idkp = ide_disk_get(disk);
189 if (idkp == NULL)
190 return -ENXIO;
191
192 drive = idkp->drive;
193
088b1b88 194 ide_debug_log(IDE_DBG_FUNC, "enter");
806f80a6 195
5fef0e5c
BZ
196 idkp->openers++;
197
198 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
806f80a6
BZ
199 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 */
b2f21e05 209 if (ret && (mode & FMODE_NDELAY) == 0) {
806f80a6
BZ
210 ret = -EIO;
211 goto out_put_idkp;
212 }
213
b2f21e05 214 if ((drive->dev_flags & IDE_DFLAG_WP) && (mode & FMODE_WRITE)) {
806f80a6
BZ
215 ret = -EROFS;
216 goto out_put_idkp;
217 }
218
5fef0e5c
BZ
219 /*
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 */
806f80a6 224 drive->disk_ops->set_doorlock(drive, disk, 1);
cedd120c 225 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
b2f21e05 226 check_disk_change(bdev);
806f80a6
BZ
227 } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
228 ret = -EBUSY;
229 goto out_put_idkp;
5fef0e5c
BZ
230 }
231 return 0;
806f80a6
BZ
232
233out_put_idkp:
234 idkp->openers--;
235 ide_disk_put(idkp);
236 return ret;
5fef0e5c
BZ
237}
238
b2f21e05 239static int ide_gd_release(struct gendisk *disk, fmode_t mode)
5fef0e5c 240{
5fef0e5c
BZ
241 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
242 ide_drive_t *drive = idkp->drive;
243
088b1b88 244 ide_debug_log(IDE_DBG_FUNC, "enter");
806f80a6 245
5fef0e5c 246 if (idkp->openers == 1)
806f80a6 247 drive->disk_ops->flush(drive);
5fef0e5c 248
806f80a6
BZ
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 }
5fef0e5c
BZ
253
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;
cedd120c 276 int ret;
5fef0e5c
BZ
277
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
cedd120c
BZ
284 ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED);
285 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
286
287 return ret;
5fef0e5c
BZ
288}
289
e957b60d
BZ
290static 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
5fef0e5c
BZ
303static int ide_gd_revalidate_disk(struct gendisk *disk)
304{
305 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
52ebb438
BP
306 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));
5fef0e5c
BZ
312 return 0;
313}
314
b2f21e05 315static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode,
806f80a6
BZ
316 unsigned int cmd, unsigned long arg)
317{
806f80a6
BZ
318 struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
319 ide_drive_t *drive = idkp->drive;
320
b2f21e05 321 return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg);
806f80a6
BZ
322}
323
5fef0e5c
BZ
324static struct block_device_operations ide_gd_ops = {
325 .owner = THIS_MODULE,
b2f21e05
AV
326 .open = ide_gd_open,
327 .release = ide_gd_release,
328 .locked_ioctl = ide_gd_ioctl,
5fef0e5c
BZ
329 .getgeo = ide_gd_getgeo,
330 .media_changed = ide_gd_media_changed,
e957b60d 331 .set_capacity = ide_gd_set_capacity,
5fef0e5c
BZ
332 .revalidate_disk = ide_gd_revalidate_disk
333};
334
335static int ide_gd_probe(ide_drive_t *drive)
336{
806f80a6 337 const struct ide_disk_ops *disk_ops = NULL;
5fef0e5c
BZ
338 struct ide_disk_obj *idkp;
339 struct gendisk *g;
340
341 /* strstr("foo", "") is non-NULL */
806f80a6
BZ
342 if (!strstr("ide-gd", drive->driver_req))
343 goto failed;
344
345#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)
5fef0e5c
BZ
354 goto failed;
355
806f80a6
BZ
356 if (disk_ops->check(drive, DRV_NAME) == 0) {
357 printk(KERN_ERR PFX "%s: not supported by this driver\n",
358 drive->name);
5fef0e5c 359 goto failed;
806f80a6 360 }
5fef0e5c
BZ
361
362 idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
806f80a6
BZ
363 if (!idkp) {
364 printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
365 drive->name);
5fef0e5c 366 goto failed;
806f80a6 367 }
5fef0e5c
BZ
368
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
8fed4368
BZ
375 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;
5fef0e5c
BZ
381
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;
806f80a6
BZ
389 drive->debug_mask = debug_mask;
390 drive->disk_ops = disk_ops;
5fef0e5c 391
806f80a6 392 disk_ops->setup(drive);
5fef0e5c
BZ
393
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
8fed4368
BZ
405out_free_disk:
406 put_disk(g);
5fef0e5c
BZ
407out_free_idkp:
408 kfree(idkp);
409failed:
410 return -ENODEV;
411}
412
413static int __init ide_gd_init(void)
414{
806f80a6 415 printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
5fef0e5c
BZ
416 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");
806f80a6
BZ
426MODULE_ALIAS("ide:*m-floppy*");
427MODULE_ALIAS("ide-floppy");
5fef0e5c
BZ
428module_init(ide_gd_init);
429module_exit(ide_gd_exit);
430MODULE_LICENSE("GPL");
806f80a6 431MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");