Commit 806f80a6fc203ad0bde84e5a9e94572617d2ae45
1 parent
79cb380397
Exists in
master
and in
4 other branches
ide: add generic ATA/ATAPI disk driver
* Add struct ide_disk_ops containing protocol specific methods. * Add 'struct ide_disk_ops *' to ide_drive_t. * Convert ide-{disk,floppy} drivers to use struct ide_disk_ops. * Merge ide-{disk,floppy} drivers into generic ide-gd driver. While at it: - ide_disk_init_capacity() -> ide_disk_get_capacity() Acked-by: Borislav Petkov <petkovbb@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Showing 13 changed files with 303 additions and 455 deletions Side-by-side Diff
- drivers/ide/Kconfig
- drivers/ide/Makefile
- drivers/ide/ide-disk.c
- drivers/ide/ide-disk.h
- drivers/ide/ide-disk_ioctl.c
- drivers/ide/ide-floppy.c
- drivers/ide/ide-floppy.h
- drivers/ide/ide-floppy_ioctl.c
- drivers/ide/ide-gd-floppy.c
- drivers/ide/ide-gd.c
- drivers/ide/ide-gd.h
- drivers/leds/Kconfig
- include/linux/ide.h
drivers/ide/Kconfig
... | ... | @@ -84,21 +84,40 @@ |
84 | 84 | |
85 | 85 | If unsure, say N. |
86 | 86 | |
87 | -config BLK_DEV_IDEDISK | |
88 | - tristate "Include IDE/ATA-2 DISK support" | |
89 | - ---help--- | |
90 | - This will include enhanced support for MFM/RLL/IDE hard disks. If | |
91 | - you have a MFM/RLL/IDE disk, and there is no special reason to use | |
92 | - the old hard disk driver instead, say Y. If you have an SCSI-only | |
93 | - system, you can say N here. | |
87 | +config IDE_GD | |
88 | + tristate "generic ATA/ATAPI disk support" | |
89 | + default y | |
90 | + help | |
91 | + Support for ATA/ATAPI disks (including ATAPI floppy drives). | |
94 | 92 | |
95 | - To compile this driver as a module, choose M here: the | |
96 | - module will be called ide-disk. | |
97 | - Do not compile this driver as a module if your root file system | |
98 | - (the one containing the directory /) is located on the IDE disk. | |
93 | + To compile this driver as a module, choose M here. | |
94 | + The module will be called ide-gd_mod. | |
99 | 95 | |
100 | 96 | If unsure, say Y. |
101 | 97 | |
98 | +config IDE_GD_ATA | |
99 | + bool "ATA disk support" | |
100 | + depends on IDE_GD | |
101 | + default y | |
102 | + help | |
103 | + This will include support for ATA hard disks. | |
104 | + | |
105 | + If unsure, say Y. | |
106 | + | |
107 | +config IDE_GD_ATAPI | |
108 | + bool "ATAPI floppy support" | |
109 | + depends on IDE_GD | |
110 | + select IDE_ATAPI | |
111 | + help | |
112 | + This will include support for ATAPI floppy drives | |
113 | + (i.e. Iomega ZIP or MKE LS-120). | |
114 | + | |
115 | + For information about jumper settings and the question | |
116 | + of when a ZIP drive uses a partition table, see | |
117 | + <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>. | |
118 | + | |
119 | + If unsure, say N. | |
120 | + | |
102 | 121 | config BLK_DEV_IDECS |
103 | 122 | tristate "PCMCIA IDE support" |
104 | 123 | depends on PCMCIA |
... | ... | @@ -162,29 +181,6 @@ |
162 | 181 | |
163 | 182 | To compile this driver as a module, choose M here: the |
164 | 183 | module will be called ide-tape. |
165 | - | |
166 | -config BLK_DEV_IDEFLOPPY | |
167 | - tristate "Include IDE/ATAPI FLOPPY support" | |
168 | - select IDE_ATAPI | |
169 | - ---help--- | |
170 | - If you have an IDE floppy drive which uses the ATAPI protocol, | |
171 | - answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy | |
172 | - drives, similar to the SCSI protocol. | |
173 | - | |
174 | - The LS-120 and the IDE/ATAPI Iomega ZIP drive are also supported by | |
175 | - this driver. For information about jumper settings and the question | |
176 | - of when a ZIP drive uses a partition table, see | |
177 | - <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>. | |
178 | - (ATAPI PD-CD/CDR drives are not supported by this driver; support | |
179 | - for PD-CD/CDR drives is available if you answer Y to | |
180 | - "SCSI emulation support", below). | |
181 | - | |
182 | - If you say Y here, the FLOPPY drive will be identified along with | |
183 | - other IDE devices, as "hdb" or "hdc", or something similar (check | |
184 | - the boot messages with dmesg). | |
185 | - | |
186 | - To compile this driver as a module, choose M here: the | |
187 | - module will be called ide-floppy. | |
188 | 184 | |
189 | 185 | config BLK_DEV_IDESCSI |
190 | 186 | tristate "SCSI emulation support (DEPRECATED)" |
drivers/ide/Makefile
... | ... | @@ -37,18 +37,25 @@ |
37 | 37 | obj-$(CONFIG_IDE_GENERIC) += ide-generic.o |
38 | 38 | obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o |
39 | 39 | |
40 | -ide-disk_mod-y += ide-gd.o ide-disk.o ide-disk_ioctl.o | |
40 | +ide-gd_mod-y += ide-gd.o | |
41 | 41 | ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o |
42 | -ide-floppy_mod-y += ide-gd-floppy.o ide-floppy.o ide-floppy_ioctl.o | |
43 | 42 | |
43 | +ifeq ($(CONFIG_IDE_GD_ATA), y) | |
44 | + ide-gd_mod-y += ide-disk.o ide-disk_ioctl.o | |
44 | 45 | ifeq ($(CONFIG_IDE_PROC_FS), y) |
45 | - ide-disk_mod-y += ide-disk_proc.o | |
46 | - ide-floppy_mod-y += ide-floppy_proc.o | |
46 | + ide-gd_mod-y += ide-disk_proc.o | |
47 | 47 | endif |
48 | +endif | |
48 | 49 | |
49 | -obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk_mod.o | |
50 | +ifeq ($(CONFIG_IDE_GD_ATAPI), y) | |
51 | + ide-gd_mod-y += ide-floppy.o ide-floppy_ioctl.o | |
52 | +ifeq ($(CONFIG_IDE_PROC_FS), y) | |
53 | + ide-gd_mod-y += ide-floppy_proc.o | |
54 | +endif | |
55 | +endif | |
56 | + | |
57 | +obj-$(CONFIG_IDE_GD) += ide-gd_mod.o | |
50 | 58 | obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o |
51 | -obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy_mod.o | |
52 | 59 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o |
53 | 60 | |
54 | 61 | ifeq ($(CONFIG_BLK_DEV_IDECS), y) |
drivers/ide/ide-disk.c
... | ... | @@ -184,8 +184,8 @@ |
184 | 184 | * 1073741822 == 549756 MB or 48bit addressing fake drive |
185 | 185 | */ |
186 | 186 | |
187 | -ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |
188 | - sector_t block) | |
187 | +static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |
188 | + sector_t block) | |
189 | 189 | { |
190 | 190 | ide_hwif_t *hwif = HWIF(drive); |
191 | 191 | |
... | ... | @@ -333,7 +333,7 @@ |
333 | 333 | } |
334 | 334 | } |
335 | 335 | |
336 | -void ide_disk_init_capacity(ide_drive_t *drive) | |
336 | +static int ide_disk_get_capacity(ide_drive_t *drive) | |
337 | 337 | { |
338 | 338 | u16 *id = drive->id; |
339 | 339 | int lba; |
... | ... | @@ -382,6 +382,8 @@ |
382 | 382 | } else |
383 | 383 | drive->dev_flags &= ~IDE_DFLAG_LBA48; |
384 | 384 | } |
385 | + | |
386 | + return 0; | |
385 | 387 | } |
386 | 388 | |
387 | 389 | static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) |
388 | 390 | |
... | ... | @@ -590,8 +592,13 @@ |
590 | 592 | |
591 | 593 | ide_ext_devset_rw_sync(nowerr, nowerr); |
592 | 594 | |
593 | -void ide_disk_setup(ide_drive_t *drive) | |
595 | +static int ide_disk_check(ide_drive_t *drive, const char *s) | |
594 | 596 | { |
597 | + return 1; | |
598 | +} | |
599 | + | |
600 | +static void ide_disk_setup(ide_drive_t *drive) | |
601 | +{ | |
595 | 602 | struct ide_disk_obj *idkp = drive->driver_data; |
596 | 603 | ide_hwif_t *hwif = drive->hwif; |
597 | 604 | u16 *id = drive->id; |
... | ... | @@ -626,7 +633,7 @@ |
626 | 633 | drive->queue->max_sectors / 2); |
627 | 634 | |
628 | 635 | /* calculate drive capacity, and select LBA if possible */ |
629 | - ide_disk_init_capacity(drive); | |
636 | + ide_disk_get_capacity(drive); | |
630 | 637 | |
631 | 638 | /* |
632 | 639 | * if possible, give fdisk access to more of the drive, |
... | ... | @@ -682,7 +689,7 @@ |
682 | 689 | drive->dev_flags |= IDE_DFLAG_ATTACH; |
683 | 690 | } |
684 | 691 | |
685 | -void ide_disk_flush(ide_drive_t *drive) | |
692 | +static void ide_disk_flush(ide_drive_t *drive) | |
686 | 693 | { |
687 | 694 | if (ata_id_flush_enabled(drive->id) == 0 || |
688 | 695 | (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) |
689 | 696 | |
... | ... | @@ -692,8 +699,14 @@ |
692 | 699 | printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); |
693 | 700 | } |
694 | 701 | |
695 | -int ide_disk_set_doorlock(ide_drive_t *drive, int on) | |
702 | +static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk) | |
696 | 703 | { |
704 | + return 0; | |
705 | +} | |
706 | + | |
707 | +static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, | |
708 | + int on) | |
709 | +{ | |
697 | 710 | ide_task_t task; |
698 | 711 | int ret; |
699 | 712 | |
... | ... | @@ -711,4 +724,16 @@ |
711 | 724 | |
712 | 725 | return ret; |
713 | 726 | } |
727 | + | |
728 | +const struct ide_disk_ops ide_ata_disk_ops = { | |
729 | + .check = ide_disk_check, | |
730 | + .get_capacity = ide_disk_get_capacity, | |
731 | + .setup = ide_disk_setup, | |
732 | + .flush = ide_disk_flush, | |
733 | + .init_media = ide_disk_init_media, | |
734 | + .set_doorlock = ide_disk_set_doorlock, | |
735 | + .do_request = ide_do_rw_disk, | |
736 | + .end_request = ide_end_request, | |
737 | + .ioctl = ide_disk_ioctl, | |
738 | +}; |
drivers/ide/ide-disk.h
1 | 1 | #ifndef __IDE_DISK_H |
2 | 2 | #define __IDE_DISK_H |
3 | 3 | |
4 | -struct ide_disk_obj { | |
5 | - ide_drive_t *drive; | |
6 | - ide_driver_t *driver; | |
7 | - struct gendisk *disk; | |
8 | - struct kref kref; | |
9 | - unsigned int openers; /* protected by BKL for now */ | |
10 | -}; | |
4 | +#include "ide-gd.h" | |
11 | 5 | |
12 | -sector_t ide_gd_capacity(ide_drive_t *); | |
13 | - | |
6 | +#ifdef CONFIG_IDE_GD_ATA | |
14 | 7 | /* ide-disk.c */ |
15 | -void ide_disk_init_capacity(ide_drive_t *); | |
16 | -void ide_disk_setup(ide_drive_t *); | |
17 | -void ide_disk_flush(ide_drive_t *); | |
18 | -int ide_disk_set_doorlock(ide_drive_t *, int); | |
19 | -ide_startstop_t ide_do_rw_disk(ide_drive_t *, struct request *, sector_t); | |
8 | +extern const struct ide_disk_ops ide_ata_disk_ops; | |
20 | 9 | ide_decl_devset(address); |
21 | 10 | ide_decl_devset(multcount); |
22 | 11 | ide_decl_devset(nowerr); |
23 | 12 | |
... | ... | @@ -24,12 +13,17 @@ |
24 | 13 | ide_decl_devset(acoustic); |
25 | 14 | |
26 | 15 | /* ide-disk_ioctl.c */ |
27 | -int ide_disk_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | |
16 | +int ide_disk_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, | |
17 | + unsigned long); | |
28 | 18 | |
29 | 19 | #ifdef CONFIG_IDE_PROC_FS |
30 | 20 | /* ide-disk_proc.c */ |
31 | 21 | extern ide_proc_entry_t ide_disk_proc[]; |
32 | 22 | extern const struct ide_proc_devset ide_disk_settings[]; |
23 | +#endif | |
24 | +#else | |
25 | +#define ide_disk_proc NULL | |
26 | +#define ide_disk_settings NULL | |
33 | 27 | #endif |
34 | 28 | |
35 | 29 | #endif /* __IDE_DISK_H */ |
drivers/ide/ide-disk_ioctl.c
... | ... | @@ -13,12 +13,10 @@ |
13 | 13 | { 0 } |
14 | 14 | }; |
15 | 15 | |
16 | -int ide_disk_ioctl(struct inode *inode, struct file *file, | |
16 | +int ide_disk_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, | |
17 | 17 | unsigned int cmd, unsigned long arg) |
18 | 18 | { |
19 | 19 | struct block_device *bdev = inode->i_bdev; |
20 | - struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); | |
21 | - ide_drive_t *drive = idkp->drive; | |
22 | 20 | int err; |
23 | 21 | |
24 | 22 | err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); |
drivers/ide/ide-floppy.c
... | ... | @@ -68,7 +68,7 @@ |
68 | 68 | * Used to finish servicing a request. For read/write requests, we will call |
69 | 69 | * ide_end_request to pass to the next buffer. |
70 | 70 | */ |
71 | -int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) | |
71 | +static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) | |
72 | 72 | { |
73 | 73 | idefloppy_floppy_t *floppy = drive->driver_data; |
74 | 74 | struct request *rq = HWGROUP(drive)->rq; |
75 | 75 | |
... | ... | @@ -280,13 +280,12 @@ |
280 | 280 | pc->req_xfer = pc->buf_size = rq->data_len; |
281 | 281 | } |
282 | 282 | |
283 | -ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, struct request *rq, | |
284 | - sector_t block_s) | |
283 | +static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, | |
284 | + struct request *rq, sector_t block) | |
285 | 285 | { |
286 | 286 | idefloppy_floppy_t *floppy = drive->driver_data; |
287 | 287 | ide_hwif_t *hwif = drive->hwif; |
288 | 288 | struct ide_atapi_pc *pc; |
289 | - unsigned long block = (unsigned long)block_s; | |
290 | 289 | |
291 | 290 | ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " |
292 | 291 | "errors: %d\n", |
... | ... | @@ -316,7 +315,7 @@ |
316 | 315 | return ide_stopped; |
317 | 316 | } |
318 | 317 | pc = &floppy->queued_pc; |
319 | - idefloppy_create_rw_cmd(drive, pc, rq, block); | |
318 | + idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); | |
320 | 319 | } else if (blk_special_request(rq)) { |
321 | 320 | pc = (struct ide_atapi_pc *) rq->buffer; |
322 | 321 | } else if (blk_pc_request(rq)) { |
... | ... | @@ -406,7 +405,7 @@ |
406 | 405 | * Determine if a media is present in the floppy drive, and if so, its LBA |
407 | 406 | * capacity. |
408 | 407 | */ |
409 | -int ide_floppy_get_capacity(ide_drive_t *drive) | |
408 | +static int ide_floppy_get_capacity(ide_drive_t *drive) | |
410 | 409 | { |
411 | 410 | idefloppy_floppy_t *floppy = drive->driver_data; |
412 | 411 | struct gendisk *disk = floppy->disk; |
413 | 412 | |
... | ... | @@ -505,9 +504,9 @@ |
505 | 504 | return rc; |
506 | 505 | } |
507 | 506 | |
508 | -void ide_floppy_setup(ide_drive_t *drive) | |
507 | +static void ide_floppy_setup(ide_drive_t *drive) | |
509 | 508 | { |
510 | - struct ide_floppy_obj *floppy = drive->driver_data; | |
509 | + struct ide_disk_obj *floppy = drive->driver_data; | |
511 | 510 | u16 *id = drive->id; |
512 | 511 | |
513 | 512 | drive->pc_callback = ide_floppy_callback; |
... | ... | @@ -547,4 +546,34 @@ |
547 | 546 | |
548 | 547 | drive->dev_flags |= IDE_DFLAG_ATTACH; |
549 | 548 | } |
549 | + | |
550 | +static void ide_floppy_flush(ide_drive_t *drive) | |
551 | +{ | |
552 | +} | |
553 | + | |
554 | +static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) | |
555 | +{ | |
556 | + int ret = 0; | |
557 | + | |
558 | + if (ide_do_test_unit_ready(drive, disk)) | |
559 | + ide_do_start_stop(drive, disk, 1); | |
560 | + | |
561 | + ret = ide_floppy_get_capacity(drive); | |
562 | + | |
563 | + set_capacity(disk, ide_gd_capacity(drive)); | |
564 | + | |
565 | + return ret; | |
566 | +} | |
567 | + | |
568 | +const struct ide_disk_ops ide_atapi_disk_ops = { | |
569 | + .check = ide_check_atapi_device, | |
570 | + .get_capacity = ide_floppy_get_capacity, | |
571 | + .setup = ide_floppy_setup, | |
572 | + .flush = ide_floppy_flush, | |
573 | + .init_media = ide_floppy_init_media, | |
574 | + .set_doorlock = ide_set_media_lock, | |
575 | + .do_request = ide_floppy_do_request, | |
576 | + .end_request = ide_floppy_end_request, | |
577 | + .ioctl = ide_floppy_ioctl, | |
578 | +}; |
drivers/ide/ide-floppy.h
1 | 1 | #ifndef __IDE_FLOPPY_H |
2 | 2 | #define __IDE_FLOPPY_H |
3 | 3 | |
4 | -#define DRV_NAME "ide-floppy" | |
5 | -#define PFX DRV_NAME ": " | |
4 | +#include "ide-gd.h" | |
6 | 5 | |
7 | -/* define to see debug info */ | |
8 | -#define IDEFLOPPY_DEBUG_LOG 0 | |
6 | +#ifdef CONFIG_IDE_GD_ATAPI | |
7 | +typedef struct ide_disk_obj idefloppy_floppy_t; | |
9 | 8 | |
10 | -#if IDEFLOPPY_DEBUG_LOG | |
11 | -#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) | |
12 | -#else | |
13 | -#define ide_debug_log(lvl, fmt, args...) do {} while (0) | |
14 | -#endif | |
15 | - | |
16 | 9 | /* |
17 | - * Most of our global data which we need to save even as we leave the driver | |
18 | - * due to an interrupt or a timer event is stored in a variable of type | |
19 | - * idefloppy_floppy_t, defined below. | |
20 | - */ | |
21 | -typedef struct ide_floppy_obj { | |
22 | - ide_drive_t *drive; | |
23 | - ide_driver_t *driver; | |
24 | - struct gendisk *disk; | |
25 | - struct kref kref; | |
26 | - unsigned int openers; /* protected by BKL for now */ | |
27 | - | |
28 | - /* Last failed packet command */ | |
29 | - struct ide_atapi_pc *failed_pc; | |
30 | - /* used for blk_{fs,pc}_request() requests */ | |
31 | - struct ide_atapi_pc queued_pc; | |
32 | - | |
33 | - /* Last error information */ | |
34 | - u8 sense_key, asc, ascq; | |
35 | - | |
36 | - int progress_indication; | |
37 | - | |
38 | - /* Device information */ | |
39 | - /* Current format */ | |
40 | - int blocks, block_size, bs_factor; | |
41 | - /* Last format capacity descriptor */ | |
42 | - u8 cap_desc[8]; | |
43 | - /* Copy of the flexible disk page */ | |
44 | - u8 flexible_disk_page[32]; | |
45 | -} idefloppy_floppy_t; | |
46 | - | |
47 | -/* | |
48 | 10 | * Pages of the SELECT SENSE / MODE SENSE packet commands. |
49 | 11 | * See SFF-8070i spec. |
50 | 12 | */ |
51 | 13 | |
52 | 14 | |
53 | 15 | |
54 | 16 | |
... | ... | @@ -57,23 +19,23 @@ |
57 | 19 | #define IDEFLOPPY_IOCTL_FORMAT_START 0x4602 |
58 | 20 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 |
59 | 21 | |
60 | -sector_t ide_gd_capacity(ide_drive_t *); | |
61 | - | |
62 | 22 | /* ide-floppy.c */ |
23 | +extern const struct ide_disk_ops ide_atapi_disk_ops; | |
63 | 24 | void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); |
64 | 25 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); |
65 | -int ide_floppy_get_capacity(ide_drive_t *); | |
66 | -void ide_floppy_setup(ide_drive_t *); | |
67 | -ide_startstop_t ide_floppy_do_request(ide_drive_t *, struct request *, sector_t); | |
68 | -int ide_floppy_end_request(ide_drive_t *, int, int); | |
69 | 26 | |
70 | 27 | /* ide-floppy_ioctl.c */ |
71 | -int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long); | |
28 | +int ide_floppy_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, | |
29 | + unsigned long); | |
72 | 30 | |
73 | 31 | #ifdef CONFIG_IDE_PROC_FS |
74 | 32 | /* ide-floppy_proc.c */ |
75 | 33 | extern ide_proc_entry_t ide_floppy_proc[]; |
76 | 34 | extern const struct ide_proc_devset ide_floppy_settings[]; |
35 | +#endif | |
36 | +#else | |
37 | +#define ide_floppy_proc NULL | |
38 | +#define ide_floppy_settings NULL | |
77 | 39 | #endif |
78 | 40 | |
79 | 41 | #endif /*__IDE_FLOPPY_H */ |
drivers/ide/ide-floppy_ioctl.c
... | ... | @@ -33,7 +33,7 @@ |
33 | 33 | |
34 | 34 | static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) |
35 | 35 | { |
36 | - struct ide_floppy_obj *floppy = drive->driver_data; | |
36 | + struct ide_disk_obj *floppy = drive->driver_data; | |
37 | 37 | struct ide_atapi_pc pc; |
38 | 38 | u8 header_len, desc_cnt; |
39 | 39 | int i, blocks, length, u_array_size, u_index; |
40 | 40 | |
... | ... | @@ -260,13 +260,10 @@ |
260 | 260 | } |
261 | 261 | } |
262 | 262 | |
263 | -int ide_floppy_ioctl(struct inode *inode, struct file *file, | |
264 | - unsigned int cmd, unsigned long arg) | |
263 | +int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode, | |
264 | + struct file *file, unsigned int cmd, unsigned long arg) | |
265 | 265 | { |
266 | 266 | struct block_device *bdev = inode->i_bdev; |
267 | - struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk, | |
268 | - ide_floppy_obj); | |
269 | - ide_drive_t *drive = floppy->drive; | |
270 | 267 | struct ide_atapi_pc pc; |
271 | 268 | void __user *argp = (void __user *)arg; |
272 | 269 | int err; |
drivers/ide/ide-gd-floppy.c
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> | |
10 | - | |
11 | -#include "ide-floppy.h" | |
12 | - | |
13 | -#define IDEFLOPPY_VERSION "1.00" | |
14 | - | |
15 | -/* module parameters */ | |
16 | -static unsigned long debug_mask; | |
17 | -module_param(debug_mask, ulong, 0644); | |
18 | - | |
19 | -static DEFINE_MUTEX(ide_disk_ref_mutex); | |
20 | - | |
21 | -static void ide_disk_release(struct kref *); | |
22 | - | |
23 | -static struct ide_floppy_obj *ide_disk_get(struct gendisk *disk) | |
24 | -{ | |
25 | - struct ide_floppy_obj *idkp = NULL; | |
26 | - | |
27 | - mutex_lock(&ide_disk_ref_mutex); | |
28 | - idkp = ide_drv_g(disk, ide_floppy_obj); | |
29 | - if (idkp) { | |
30 | - if (ide_device_get(idkp->drive)) | |
31 | - idkp = NULL; | |
32 | - else | |
33 | - kref_get(&idkp->kref); | |
34 | - } | |
35 | - mutex_unlock(&ide_disk_ref_mutex); | |
36 | - return idkp; | |
37 | -} | |
38 | - | |
39 | -static void ide_disk_put(struct ide_floppy_obj *idkp) | |
40 | -{ | |
41 | - ide_drive_t *drive = idkp->drive; | |
42 | - | |
43 | - mutex_lock(&ide_disk_ref_mutex); | |
44 | - kref_put(&idkp->kref, ide_disk_release); | |
45 | - ide_device_put(drive); | |
46 | - mutex_unlock(&ide_disk_ref_mutex); | |
47 | -} | |
48 | - | |
49 | -sector_t ide_gd_capacity(ide_drive_t *drive) | |
50 | -{ | |
51 | - return drive->capacity64; | |
52 | -} | |
53 | - | |
54 | -static int ide_gd_probe(ide_drive_t *); | |
55 | - | |
56 | -static void ide_gd_remove(ide_drive_t *drive) | |
57 | -{ | |
58 | - struct ide_floppy_obj *idkp = drive->driver_data; | |
59 | - struct gendisk *g = idkp->disk; | |
60 | - | |
61 | - ide_proc_unregister_driver(drive, idkp->driver); | |
62 | - | |
63 | - del_gendisk(g); | |
64 | - | |
65 | - ide_disk_put(idkp); | |
66 | -} | |
67 | - | |
68 | -static void ide_disk_release(struct kref *kref) | |
69 | -{ | |
70 | - struct ide_floppy_obj *idkp = to_ide_drv(kref, ide_floppy_obj); | |
71 | - ide_drive_t *drive = idkp->drive; | |
72 | - struct gendisk *g = idkp->disk; | |
73 | - | |
74 | - drive->driver_data = NULL; | |
75 | - g->private_data = NULL; | |
76 | - put_disk(g); | |
77 | - kfree(idkp); | |
78 | -} | |
79 | - | |
80 | -#ifdef CONFIG_IDE_PROC_FS | |
81 | -static ide_proc_entry_t *ide_floppy_proc_entries(ide_drive_t *drive) | |
82 | -{ | |
83 | - return ide_floppy_proc; | |
84 | -} | |
85 | - | |
86 | -static const struct ide_proc_devset *ide_floppy_proc_devsets(ide_drive_t *drive) | |
87 | -{ | |
88 | - return ide_floppy_settings; | |
89 | -} | |
90 | -#endif | |
91 | - | |
92 | -static ide_driver_t ide_gd_driver = { | |
93 | - .gen_driver = { | |
94 | - .owner = THIS_MODULE, | |
95 | - .name = "ide-floppy", | |
96 | - .bus = &ide_bus_type, | |
97 | - }, | |
98 | - .probe = ide_gd_probe, | |
99 | - .remove = ide_gd_remove, | |
100 | - .version = IDEFLOPPY_VERSION, | |
101 | - .do_request = ide_floppy_do_request, | |
102 | - .end_request = ide_floppy_end_request, | |
103 | - .error = __ide_error, | |
104 | -#ifdef CONFIG_IDE_PROC_FS | |
105 | - .proc_entries = ide_floppy_proc_entries, | |
106 | - .proc_devsets = ide_floppy_proc_devsets, | |
107 | -#endif | |
108 | -}; | |
109 | - | |
110 | -static int ide_gd_open(struct inode *inode, struct file *filp) | |
111 | -{ | |
112 | - struct gendisk *disk = inode->i_bdev->bd_disk; | |
113 | - struct ide_floppy_obj *idkp; | |
114 | - ide_drive_t *drive; | |
115 | - int ret = 0; | |
116 | - | |
117 | - idkp = ide_disk_get(disk); | |
118 | - if (idkp == NULL) | |
119 | - return -ENXIO; | |
120 | - | |
121 | - drive = idkp->drive; | |
122 | - | |
123 | - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | |
124 | - | |
125 | - idkp->openers++; | |
126 | - | |
127 | - if (idkp->openers == 1) { | |
128 | - drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; | |
129 | - /* Just in case */ | |
130 | - | |
131 | - if (ide_do_test_unit_ready(drive, disk)) | |
132 | - ide_do_start_stop(drive, disk, 1); | |
133 | - | |
134 | - ret = ide_floppy_get_capacity(drive); | |
135 | - | |
136 | - set_capacity(disk, ide_gd_capacity(drive)); | |
137 | - | |
138 | - if (ret && (filp->f_flags & O_NDELAY) == 0) { | |
139 | - /* | |
140 | - * Allow O_NDELAY to open a drive without a disk, or with an | |
141 | - * unreadable disk, so that we can get the format capacity | |
142 | - * of the drive or begin the format - Sam | |
143 | - */ | |
144 | - ret = -EIO; | |
145 | - goto out_put_idkp; | |
146 | - } | |
147 | - | |
148 | - if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) { | |
149 | - ret = -EROFS; | |
150 | - goto out_put_idkp; | |
151 | - } | |
152 | - | |
153 | - ide_set_media_lock(drive, disk, 1); | |
154 | - drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; | |
155 | - check_disk_change(inode->i_bdev); | |
156 | - } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) { | |
157 | - ret = -EBUSY; | |
158 | - goto out_put_idkp; | |
159 | - } | |
160 | - return 0; | |
161 | - | |
162 | -out_put_idkp: | |
163 | - idkp->openers--; | |
164 | - ide_disk_put(idkp); | |
165 | - return ret; | |
166 | -} | |
167 | - | |
168 | -static int ide_gd_release(struct inode *inode, struct file *filp) | |
169 | -{ | |
170 | - struct gendisk *disk = inode->i_bdev->bd_disk; | |
171 | - struct ide_floppy_obj *idkp = ide_drv_g(disk, ide_floppy_obj); | |
172 | - ide_drive_t *drive = idkp->drive; | |
173 | - | |
174 | - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | |
175 | - | |
176 | - if (idkp->openers == 1) { | |
177 | - ide_set_media_lock(drive, disk, 0); | |
178 | - drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; | |
179 | - } | |
180 | - | |
181 | - idkp->openers--; | |
182 | - | |
183 | - ide_disk_put(idkp); | |
184 | - | |
185 | - return 0; | |
186 | -} | |
187 | - | |
188 | -static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |
189 | -{ | |
190 | - struct ide_floppy_obj *idkp = ide_drv_g(bdev->bd_disk, ide_floppy_obj); | |
191 | - ide_drive_t *drive = idkp->drive; | |
192 | - | |
193 | - geo->heads = drive->bios_head; | |
194 | - geo->sectors = drive->bios_sect; | |
195 | - geo->cylinders = (u16)drive->bios_cyl; /* truncate */ | |
196 | - return 0; | |
197 | -} | |
198 | - | |
199 | -static int ide_gd_media_changed(struct gendisk *disk) | |
200 | -{ | |
201 | - struct ide_floppy_obj *idkp = ide_drv_g(disk, ide_floppy_obj); | |
202 | - ide_drive_t *drive = idkp->drive; | |
203 | - int ret; | |
204 | - | |
205 | - /* do not scan partitions twice if this is a removable device */ | |
206 | - if (drive->dev_flags & IDE_DFLAG_ATTACH) { | |
207 | - drive->dev_flags &= ~IDE_DFLAG_ATTACH; | |
208 | - return 0; | |
209 | - } | |
210 | - | |
211 | - ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); | |
212 | - drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; | |
213 | - | |
214 | - return ret; | |
215 | -} | |
216 | - | |
217 | -static int ide_gd_revalidate_disk(struct gendisk *disk) | |
218 | -{ | |
219 | - struct ide_floppy_obj *idkp = ide_drv_g(disk, ide_floppy_obj); | |
220 | - set_capacity(disk, ide_gd_capacity(idkp->drive)); | |
221 | - return 0; | |
222 | -} | |
223 | - | |
224 | -static struct block_device_operations ide_gd_ops = { | |
225 | - .owner = THIS_MODULE, | |
226 | - .open = ide_gd_open, | |
227 | - .release = ide_gd_release, | |
228 | - .ioctl = ide_floppy_ioctl, | |
229 | - .getgeo = ide_gd_getgeo, | |
230 | - .media_changed = ide_gd_media_changed, | |
231 | - .revalidate_disk = ide_gd_revalidate_disk | |
232 | -}; | |
233 | - | |
234 | -static int ide_gd_probe(ide_drive_t *drive) | |
235 | -{ | |
236 | - struct ide_floppy_obj *idkp; | |
237 | - struct gendisk *g; | |
238 | - | |
239 | - if (!strstr("ide-floppy", drive->driver_req)) | |
240 | - goto failed; | |
241 | - | |
242 | - if (drive->media != ide_floppy) | |
243 | - goto failed; | |
244 | - | |
245 | - if (!ide_check_atapi_device(drive, DRV_NAME)) { | |
246 | - printk(KERN_ERR PFX "%s: not supported by this version of " | |
247 | - DRV_NAME "\n", drive->name); | |
248 | - goto failed; | |
249 | - } | |
250 | - idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); | |
251 | - if (!idkp) { | |
252 | - printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n", | |
253 | - drive->name); | |
254 | - goto failed; | |
255 | - } | |
256 | - | |
257 | - g = alloc_disk_node(1 << PARTN_BITS, hwif_to_node(drive->hwif)); | |
258 | - if (!g) | |
259 | - goto out_free_idkp; | |
260 | - | |
261 | - ide_init_disk(g, drive); | |
262 | - | |
263 | - kref_init(&idkp->kref); | |
264 | - | |
265 | - idkp->drive = drive; | |
266 | - idkp->driver = &ide_gd_driver; | |
267 | - idkp->disk = g; | |
268 | - | |
269 | - g->private_data = &idkp->driver; | |
270 | - | |
271 | - drive->driver_data = idkp; | |
272 | - | |
273 | - drive->debug_mask = debug_mask; | |
274 | - | |
275 | - ide_floppy_setup(drive); | |
276 | - | |
277 | - set_capacity(g, ide_gd_capacity(drive)); | |
278 | - | |
279 | - g->minors = 1 << PARTN_BITS; | |
280 | - g->driverfs_dev = &drive->gendev; | |
281 | - if (drive->dev_flags & IDE_DFLAG_REMOVABLE) | |
282 | - g->flags = GENHD_FL_REMOVABLE; | |
283 | - g->fops = &ide_gd_ops; | |
284 | - add_disk(g); | |
285 | - return 0; | |
286 | - | |
287 | -out_free_idkp: | |
288 | - kfree(idkp); | |
289 | -failed: | |
290 | - return -ENODEV; | |
291 | -} | |
292 | - | |
293 | -static int __init ide_gd_init(void) | |
294 | -{ | |
295 | - printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n"); | |
296 | - return driver_register(&ide_gd_driver.gen_driver); | |
297 | -} | |
298 | - | |
299 | -static void __exit ide_gd_exit(void) | |
300 | -{ | |
301 | - driver_unregister(&ide_gd_driver.gen_driver); | |
302 | -} | |
303 | - | |
304 | -MODULE_ALIAS("ide:*m-floppy*"); | |
305 | -MODULE_ALIAS("ide-floppy"); | |
306 | -module_init(ide_gd_init); | |
307 | -module_exit(ide_gd_exit); | |
308 | -MODULE_LICENSE("GPL"); | |
309 | -MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); |
drivers/ide/ide-gd.c
... | ... | @@ -15,9 +15,14 @@ |
15 | 15 | #endif |
16 | 16 | |
17 | 17 | #include "ide-disk.h" |
18 | +#include "ide-floppy.h" | |
18 | 19 | |
19 | 20 | #define IDE_GD_VERSION "1.18" |
20 | 21 | |
22 | +/* module parameters */ | |
23 | +static unsigned long debug_mask; | |
24 | +module_param(debug_mask, ulong, 0644); | |
25 | + | |
21 | 26 | static DEFINE_MUTEX(ide_disk_ref_mutex); |
22 | 27 | |
23 | 28 | static void ide_disk_release(struct kref *); |
... | ... | @@ -64,7 +69,7 @@ |
64 | 69 | |
65 | 70 | del_gendisk(g); |
66 | 71 | |
67 | - ide_disk_flush(drive); | |
72 | + drive->disk_ops->flush(drive); | |
68 | 73 | |
69 | 74 | ide_disk_put(idkp); |
70 | 75 | } |
... | ... | @@ -75,6 +80,7 @@ |
75 | 80 | ide_drive_t *drive = idkp->drive; |
76 | 81 | struct gendisk *g = idkp->disk; |
77 | 82 | |
83 | + drive->disk_ops = NULL; | |
78 | 84 | drive->driver_data = NULL; |
79 | 85 | g->private_data = NULL; |
80 | 86 | put_disk(g); |
... | ... | @@ -89,7 +95,7 @@ |
89 | 95 | static void ide_gd_resume(ide_drive_t *drive) |
90 | 96 | { |
91 | 97 | if (ata_id_hpa_enabled(drive->id)) |
92 | - ide_disk_init_capacity(drive); | |
98 | + (void)drive->disk_ops->get_capacity(drive); | |
93 | 99 | } |
94 | 100 | |
95 | 101 | static void ide_gd_shutdown(ide_drive_t *drive) |
... | ... | @@ -110,7 +116,7 @@ |
110 | 116 | #else |
111 | 117 | if (system_state == SYSTEM_RESTART) { |
112 | 118 | #endif |
113 | - ide_disk_flush(drive); | |
119 | + drive->disk_ops->flush(drive); | |
114 | 120 | return; |
115 | 121 | } |
116 | 122 | |
117 | 123 | |
118 | 124 | |
119 | 125 | |
... | ... | @@ -122,19 +128,31 @@ |
122 | 128 | #ifdef CONFIG_IDE_PROC_FS |
123 | 129 | static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive) |
124 | 130 | { |
125 | - return ide_disk_proc; | |
131 | + return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc; | |
126 | 132 | } |
127 | 133 | |
128 | 134 | static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive) |
129 | 135 | { |
130 | - return ide_disk_settings; | |
136 | + return (drive->media == ide_disk) ? ide_disk_settings | |
137 | + : ide_floppy_settings; | |
131 | 138 | } |
132 | 139 | #endif |
133 | 140 | |
141 | +static ide_startstop_t ide_gd_do_request(ide_drive_t *drive, | |
142 | + struct request *rq, sector_t sector) | |
143 | +{ | |
144 | + return drive->disk_ops->do_request(drive, rq, sector); | |
145 | +} | |
146 | + | |
147 | +static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs) | |
148 | +{ | |
149 | + return drive->disk_ops->end_request(drive, uptodate, nrsecs); | |
150 | +} | |
151 | + | |
134 | 152 | static ide_driver_t ide_gd_driver = { |
135 | 153 | .gen_driver = { |
136 | 154 | .owner = THIS_MODULE, |
137 | - .name = "ide-disk", | |
155 | + .name = "ide-gd", | |
138 | 156 | .bus = &ide_bus_type, |
139 | 157 | }, |
140 | 158 | .probe = ide_gd_probe, |
... | ... | @@ -142,8 +160,8 @@ |
142 | 160 | .resume = ide_gd_resume, |
143 | 161 | .shutdown = ide_gd_shutdown, |
144 | 162 | .version = IDE_GD_VERSION, |
145 | - .do_request = ide_do_rw_disk, | |
146 | - .end_request = ide_end_request, | |
163 | + .do_request = ide_gd_do_request, | |
164 | + .end_request = ide_gd_end_request, | |
147 | 165 | .error = __ide_error, |
148 | 166 | #ifdef CONFIG_IDE_PROC_FS |
149 | 167 | .proc_entries = ide_disk_proc_entries, |
... | ... | @@ -156,6 +174,7 @@ |
156 | 174 | struct gendisk *disk = inode->i_bdev->bd_disk; |
157 | 175 | struct ide_disk_obj *idkp; |
158 | 176 | ide_drive_t *drive; |
177 | + int ret = 0; | |
159 | 178 | |
160 | 179 | idkp = ide_disk_get(disk); |
161 | 180 | if (idkp == NULL) |
162 | 181 | |
163 | 182 | |
164 | 183 | |
165 | 184 | |
166 | 185 | |
... | ... | @@ -163,19 +182,49 @@ |
163 | 182 | |
164 | 183 | drive = idkp->drive; |
165 | 184 | |
185 | + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | |
186 | + | |
166 | 187 | idkp->openers++; |
167 | 188 | |
168 | 189 | if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { |
190 | + drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; | |
191 | + /* Just in case */ | |
192 | + | |
193 | + ret = drive->disk_ops->init_media(drive, disk); | |
194 | + | |
169 | 195 | /* |
196 | + * Allow O_NDELAY to open a drive without a disk, or with an | |
197 | + * unreadable disk, so that we can get the format capacity | |
198 | + * of the drive or begin the format - Sam | |
199 | + */ | |
200 | + if (ret && (filp->f_flags & O_NDELAY) == 0) { | |
201 | + ret = -EIO; | |
202 | + goto out_put_idkp; | |
203 | + } | |
204 | + | |
205 | + if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) { | |
206 | + ret = -EROFS; | |
207 | + goto out_put_idkp; | |
208 | + } | |
209 | + | |
210 | + /* | |
170 | 211 | * Ignore the return code from door_lock, |
171 | 212 | * since the open() has already succeeded, |
172 | 213 | * and the door_lock is irrelevant at this point. |
173 | 214 | */ |
174 | - ide_disk_set_doorlock(drive, 1); | |
215 | + drive->disk_ops->set_doorlock(drive, disk, 1); | |
175 | 216 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; |
176 | 217 | check_disk_change(inode->i_bdev); |
218 | + } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) { | |
219 | + ret = -EBUSY; | |
220 | + goto out_put_idkp; | |
177 | 221 | } |
178 | 222 | return 0; |
223 | + | |
224 | +out_put_idkp: | |
225 | + idkp->openers--; | |
226 | + ide_disk_put(idkp); | |
227 | + return ret; | |
179 | 228 | } |
180 | 229 | |
181 | 230 | static int ide_gd_release(struct inode *inode, struct file *filp) |
182 | 231 | |
183 | 232 | |
... | ... | @@ -184,11 +233,15 @@ |
184 | 233 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); |
185 | 234 | ide_drive_t *drive = idkp->drive; |
186 | 235 | |
236 | + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | |
237 | + | |
187 | 238 | if (idkp->openers == 1) |
188 | - ide_disk_flush(drive); | |
239 | + drive->disk_ops->flush(drive); | |
189 | 240 | |
190 | - if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) | |
191 | - ide_disk_set_doorlock(drive, 0); | |
241 | + if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { | |
242 | + drive->disk_ops->set_doorlock(drive, disk, 0); | |
243 | + drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; | |
244 | + } | |
192 | 245 | |
193 | 246 | idkp->openers--; |
194 | 247 | |
195 | 248 | |
... | ... | @@ -233,11 +286,21 @@ |
233 | 286 | return 0; |
234 | 287 | } |
235 | 288 | |
289 | +static int ide_gd_ioctl(struct inode *inode, struct file *file, | |
290 | + unsigned int cmd, unsigned long arg) | |
291 | +{ | |
292 | + struct block_device *bdev = inode->i_bdev; | |
293 | + struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); | |
294 | + ide_drive_t *drive = idkp->drive; | |
295 | + | |
296 | + return drive->disk_ops->ioctl(drive, inode, file, cmd, arg); | |
297 | +} | |
298 | + | |
236 | 299 | static struct block_device_operations ide_gd_ops = { |
237 | 300 | .owner = THIS_MODULE, |
238 | 301 | .open = ide_gd_open, |
239 | 302 | .release = ide_gd_release, |
240 | - .ioctl = ide_disk_ioctl, | |
303 | + .ioctl = ide_gd_ioctl, | |
241 | 304 | .getgeo = ide_gd_getgeo, |
242 | 305 | .media_changed = ide_gd_media_changed, |
243 | 306 | .revalidate_disk = ide_gd_revalidate_disk |
244 | 307 | |
245 | 308 | |
246 | 309 | |
247 | 310 | |
248 | 311 | |
... | ... | @@ -245,19 +308,37 @@ |
245 | 308 | |
246 | 309 | static int ide_gd_probe(ide_drive_t *drive) |
247 | 310 | { |
311 | + const struct ide_disk_ops *disk_ops = NULL; | |
248 | 312 | struct ide_disk_obj *idkp; |
249 | 313 | struct gendisk *g; |
250 | 314 | |
251 | 315 | /* strstr("foo", "") is non-NULL */ |
252 | - if (!strstr("ide-disk", drive->driver_req)) | |
316 | + if (!strstr("ide-gd", drive->driver_req)) | |
253 | 317 | goto failed; |
254 | 318 | |
255 | - if (drive->media != ide_disk) | |
319 | +#ifdef CONFIG_IDE_GD_ATA | |
320 | + if (drive->media == ide_disk) | |
321 | + disk_ops = &ide_ata_disk_ops; | |
322 | +#endif | |
323 | +#ifdef CONFIG_IDE_GD_ATAPI | |
324 | + if (drive->media == ide_floppy) | |
325 | + disk_ops = &ide_atapi_disk_ops; | |
326 | +#endif | |
327 | + if (disk_ops == NULL) | |
256 | 328 | goto failed; |
257 | 329 | |
330 | + if (disk_ops->check(drive, DRV_NAME) == 0) { | |
331 | + printk(KERN_ERR PFX "%s: not supported by this driver\n", | |
332 | + drive->name); | |
333 | + goto failed; | |
334 | + } | |
335 | + | |
258 | 336 | idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); |
259 | - if (!idkp) | |
337 | + if (!idkp) { | |
338 | + printk(KERN_ERR PFX "%s: can't allocate a disk structure\n", | |
339 | + drive->name); | |
260 | 340 | goto failed; |
341 | + } | |
261 | 342 | |
262 | 343 | g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); |
263 | 344 | if (!g) |
264 | 345 | |
... | ... | @@ -274,8 +355,10 @@ |
274 | 355 | g->private_data = &idkp->driver; |
275 | 356 | |
276 | 357 | drive->driver_data = idkp; |
358 | + drive->debug_mask = debug_mask; | |
359 | + drive->disk_ops = disk_ops; | |
277 | 360 | |
278 | - ide_disk_setup(drive); | |
361 | + disk_ops->setup(drive); | |
279 | 362 | |
280 | 363 | set_capacity(g, ide_gd_capacity(drive)); |
281 | 364 | |
... | ... | @@ -296,6 +379,7 @@ |
296 | 379 | |
297 | 380 | static int __init ide_gd_init(void) |
298 | 381 | { |
382 | + printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n"); | |
299 | 383 | return driver_register(&ide_gd_driver.gen_driver); |
300 | 384 | } |
301 | 385 | |
302 | 386 | |
... | ... | @@ -306,8 +390,10 @@ |
306 | 390 | |
307 | 391 | MODULE_ALIAS("ide:*m-disk*"); |
308 | 392 | MODULE_ALIAS("ide-disk"); |
393 | +MODULE_ALIAS("ide:*m-floppy*"); | |
394 | +MODULE_ALIAS("ide-floppy"); | |
309 | 395 | module_init(ide_gd_init); |
310 | 396 | module_exit(ide_gd_exit); |
311 | 397 | MODULE_LICENSE("GPL"); |
312 | -MODULE_DESCRIPTION("ATA DISK Driver"); | |
398 | +MODULE_DESCRIPTION("generic ATA/ATAPI disk driver"); |
drivers/ide/ide-gd.h
1 | +#ifndef __IDE_GD_H | |
2 | +#define __IDE_GD_H | |
3 | + | |
4 | +#define DRV_NAME "ide-gd" | |
5 | +#define PFX DRV_NAME ": " | |
6 | + | |
7 | +/* define to see debug info */ | |
8 | +#define IDE_GD_DEBUG_LOG 0 | |
9 | + | |
10 | +#if IDE_GD_DEBUG_LOG | |
11 | +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) | |
12 | +#else | |
13 | +#define ide_debug_log(lvl, fmt, args...) do {} while (0) | |
14 | +#endif | |
15 | + | |
16 | +struct ide_disk_obj { | |
17 | + ide_drive_t *drive; | |
18 | + ide_driver_t *driver; | |
19 | + struct gendisk *disk; | |
20 | + struct kref kref; | |
21 | + unsigned int openers; /* protected by BKL for now */ | |
22 | + | |
23 | + /* Last failed packet command */ | |
24 | + struct ide_atapi_pc *failed_pc; | |
25 | + /* used for blk_{fs,pc}_request() requests */ | |
26 | + struct ide_atapi_pc queued_pc; | |
27 | + | |
28 | + /* Last error information */ | |
29 | + u8 sense_key, asc, ascq; | |
30 | + | |
31 | + int progress_indication; | |
32 | + | |
33 | + /* Device information */ | |
34 | + /* Current format */ | |
35 | + int blocks, block_size, bs_factor; | |
36 | + /* Last format capacity descriptor */ | |
37 | + u8 cap_desc[8]; | |
38 | + /* Copy of the flexible disk page */ | |
39 | + u8 flexible_disk_page[32]; | |
40 | +}; | |
41 | + | |
42 | +sector_t ide_gd_capacity(ide_drive_t *); | |
43 | + | |
44 | +#endif /* __IDE_GD_H */ |
drivers/leds/Kconfig
... | ... | @@ -179,7 +179,7 @@ |
179 | 179 | |
180 | 180 | config LEDS_TRIGGER_IDE_DISK |
181 | 181 | bool "LED IDE Disk Trigger" |
182 | - depends on LEDS_TRIGGERS && BLK_DEV_IDEDISK | |
182 | + depends on LEDS_TRIGGERS && IDE_GD_ATA | |
183 | 183 | help |
184 | 184 | This allows LEDs to be controlled by IDE disk activity. |
185 | 185 | If unsure, say Y. |
include/linux/ide.h
... | ... | @@ -461,6 +461,23 @@ |
461 | 461 | struct ide_acpi_hwif_link; |
462 | 462 | #endif |
463 | 463 | |
464 | +struct ide_drive_s; | |
465 | + | |
466 | +struct ide_disk_ops { | |
467 | + int (*check)(struct ide_drive_s *, const char *); | |
468 | + int (*get_capacity)(struct ide_drive_s *); | |
469 | + void (*setup)(struct ide_drive_s *); | |
470 | + void (*flush)(struct ide_drive_s *); | |
471 | + int (*init_media)(struct ide_drive_s *, struct gendisk *); | |
472 | + int (*set_doorlock)(struct ide_drive_s *, struct gendisk *, | |
473 | + int); | |
474 | + ide_startstop_t (*do_request)(struct ide_drive_s *, struct request *, | |
475 | + sector_t); | |
476 | + int (*end_request)(struct ide_drive_s *, int, int); | |
477 | + int (*ioctl)(struct ide_drive_s *, struct inode *, | |
478 | + struct file *, unsigned int, unsigned long); | |
479 | +}; | |
480 | + | |
464 | 481 | /* ATAPI device flags */ |
465 | 482 | enum { |
466 | 483 | IDE_AFLAG_DRQ_INTERRUPT = (1 << 0), |
... | ... | @@ -593,6 +610,8 @@ |
593 | 610 | const struct ide_proc_devset *settings; /* /proc/ide/ drive settings */ |
594 | 611 | #endif |
595 | 612 | struct hwif_s *hwif; /* actually (ide_hwif_t *) */ |
613 | + | |
614 | + const struct ide_disk_ops *disk_ops; | |
596 | 615 | |
597 | 616 | unsigned long dev_flags; |
598 | 617 |