aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-17 12:09:14 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-17 12:09:14 -0400
commit806f80a6fc203ad0bde84e5a9e94572617d2ae45 (patch)
tree20c684323e6e9f24af96df84008f06425a67ec6a /drivers/ide
parent79cb380397c834a35952d8497651d93b543ef968 (diff)
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>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Kconfig64
-rw-r--r--drivers/ide/Makefile19
-rw-r--r--drivers/ide/ide-disk.c39
-rw-r--r--drivers/ide/ide-disk.h24
-rw-r--r--drivers/ide/ide-disk_ioctl.c4
-rw-r--r--drivers/ide/ide-floppy.c45
-rw-r--r--drivers/ide/ide-floppy.h58
-rw-r--r--drivers/ide/ide-floppy_ioctl.c9
-rw-r--r--drivers/ide/ide-gd-floppy.c309
-rw-r--r--drivers/ide/ide-gd.c122
-rw-r--r--drivers/ide/ide-gd.h44
11 files changed, 283 insertions, 454 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 74a369a6116f..faa974e615da 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -84,21 +84,40 @@ config BLK_DEV_IDE_SATA
84 84
85 If unsure, say N. 85 If unsure, say N.
86 86
87config BLK_DEV_IDEDISK 87config IDE_GD
88 tristate "Include IDE/ATA-2 DISK support" 88 tristate "generic ATA/ATAPI disk support"
89 ---help--- 89 default y
90 This will include enhanced support for MFM/RLL/IDE hard disks. If 90 help
91 you have a MFM/RLL/IDE disk, and there is no special reason to use 91 Support for ATA/ATAPI disks (including ATAPI floppy drives).
92 the old hard disk driver instead, say Y. If you have an SCSI-only
93 system, you can say N here.
94 92
95 To compile this driver as a module, choose M here: the 93 To compile this driver as a module, choose M here.
96 module will be called ide-disk. 94 The module will be called ide-gd_mod.
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.
99 95
100 If unsure, say Y. 96 If unsure, say Y.
101 97
98config 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
107config 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
102config BLK_DEV_IDECS 121config BLK_DEV_IDECS
103 tristate "PCMCIA IDE support" 122 tristate "PCMCIA IDE support"
104 depends on PCMCIA 123 depends on PCMCIA
@@ -163,29 +182,6 @@ config BLK_DEV_IDETAPE
163 To compile this driver as a module, choose M here: the 182 To compile this driver as a module, choose M here: the
164 module will be called ide-tape. 183 module will be called ide-tape.
165 184
166config 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
189config BLK_DEV_IDESCSI 185config BLK_DEV_IDESCSI
190 tristate "SCSI emulation support (DEPRECATED)" 186 tristate "SCSI emulation support (DEPRECATED)"
191 depends on SCSI 187 depends on SCSI
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 7eeeab597959..093d3248ca89 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -37,18 +37,25 @@ obj-$(CONFIG_IDE_H8300) += h8300/
37obj-$(CONFIG_IDE_GENERIC) += ide-generic.o 37obj-$(CONFIG_IDE_GENERIC) += ide-generic.o
38obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o 38obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
39 39
40ide-disk_mod-y += ide-gd.o ide-disk.o ide-disk_ioctl.o 40ide-gd_mod-y += ide-gd.o
41ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o 41ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o
42ide-floppy_mod-y += ide-gd-floppy.o ide-floppy.o ide-floppy_ioctl.o
43 42
43ifeq ($(CONFIG_IDE_GD_ATA), y)
44 ide-gd_mod-y += ide-disk.o ide-disk_ioctl.o
44ifeq ($(CONFIG_IDE_PROC_FS), y) 45ifeq ($(CONFIG_IDE_PROC_FS), y)
45 ide-disk_mod-y += ide-disk_proc.o 46 ide-gd_mod-y += ide-disk_proc.o
46 ide-floppy_mod-y += ide-floppy_proc.o 47endif
48endif
49
50ifeq ($(CONFIG_IDE_GD_ATAPI), y)
51 ide-gd_mod-y += ide-floppy.o ide-floppy_ioctl.o
52ifeq ($(CONFIG_IDE_PROC_FS), y)
53 ide-gd_mod-y += ide-floppy_proc.o
54endif
47endif 55endif
48 56
49obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk_mod.o 57obj-$(CONFIG_IDE_GD) += ide-gd_mod.o
50obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o 58obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o
51obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy_mod.o
52obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o 59obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
53 60
54ifeq ($(CONFIG_BLK_DEV_IDECS), y) 61ifeq ($(CONFIG_BLK_DEV_IDECS), y)
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 751be7af22c2..223750c1b5a6 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -184,8 +184,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
184 * 1073741822 == 549756 MB or 48bit addressing fake drive 184 * 1073741822 == 549756 MB or 48bit addressing fake drive
185 */ 185 */
186 186
187ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, 187static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
188 sector_t block) 188 sector_t block)
189{ 189{
190 ide_hwif_t *hwif = HWIF(drive); 190 ide_hwif_t *hwif = HWIF(drive);
191 191
@@ -333,7 +333,7 @@ static void idedisk_check_hpa(ide_drive_t *drive)
333 } 333 }
334} 334}
335 335
336void ide_disk_init_capacity(ide_drive_t *drive) 336static int ide_disk_get_capacity(ide_drive_t *drive)
337{ 337{
338 u16 *id = drive->id; 338 u16 *id = drive->id;
339 int lba; 339 int lba;
@@ -382,6 +382,8 @@ void ide_disk_init_capacity(ide_drive_t *drive)
382 } else 382 } else
383 drive->dev_flags &= ~IDE_DFLAG_LBA48; 383 drive->dev_flags &= ~IDE_DFLAG_LBA48;
384 } 384 }
385
386 return 0;
385} 387}
386 388
387static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) 389static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
@@ -590,7 +592,12 @@ ide_ext_devset_rw(wcache, wcache);
590 592
591ide_ext_devset_rw_sync(nowerr, nowerr); 593ide_ext_devset_rw_sync(nowerr, nowerr);
592 594
593void ide_disk_setup(ide_drive_t *drive) 595static int ide_disk_check(ide_drive_t *drive, const char *s)
596{
597 return 1;
598}
599
600static void ide_disk_setup(ide_drive_t *drive)
594{ 601{
595 struct ide_disk_obj *idkp = drive->driver_data; 602 struct ide_disk_obj *idkp = drive->driver_data;
596 ide_hwif_t *hwif = drive->hwif; 603 ide_hwif_t *hwif = drive->hwif;
@@ -626,7 +633,7 @@ void ide_disk_setup(ide_drive_t *drive)
626 drive->queue->max_sectors / 2); 633 drive->queue->max_sectors / 2);
627 634
628 /* calculate drive capacity, and select LBA if possible */ 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 * if possible, give fdisk access to more of the drive, 639 * if possible, give fdisk access to more of the drive,
@@ -682,7 +689,7 @@ void ide_disk_setup(ide_drive_t *drive)
682 drive->dev_flags |= IDE_DFLAG_ATTACH; 689 drive->dev_flags |= IDE_DFLAG_ATTACH;
683} 690}
684 691
685void ide_disk_flush(ide_drive_t *drive) 692static void ide_disk_flush(ide_drive_t *drive)
686{ 693{
687 if (ata_id_flush_enabled(drive->id) == 0 || 694 if (ata_id_flush_enabled(drive->id) == 0 ||
688 (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) 695 (drive->dev_flags & IDE_DFLAG_WCACHE) == 0)
@@ -692,7 +699,13 @@ void ide_disk_flush(ide_drive_t *drive)
692 printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); 699 printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
693} 700}
694 701
695int ide_disk_set_doorlock(ide_drive_t *drive, int on) 702static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk)
703{
704 return 0;
705}
706
707static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
708 int on)
696{ 709{
697 ide_task_t task; 710 ide_task_t task;
698 int ret; 711 int ret;
@@ -711,3 +724,15 @@ int ide_disk_set_doorlock(ide_drive_t *drive, int on)
711 724
712 return ret; 725 return ret;
713} 726}
727
728const 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};
diff --git a/drivers/ide/ide-disk.h b/drivers/ide/ide-disk.h
index 104ad71288a5..b234b0feaf7b 100644
--- a/drivers/ide/ide-disk.h
+++ b/drivers/ide/ide-disk.h
@@ -1,22 +1,11 @@
1#ifndef __IDE_DISK_H 1#ifndef __IDE_DISK_H
2#define __IDE_DISK_H 2#define __IDE_DISK_H
3 3
4struct ide_disk_obj { 4#include "ide-gd.h"
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};
11
12sector_t ide_gd_capacity(ide_drive_t *);
13 5
6#ifdef CONFIG_IDE_GD_ATA
14/* ide-disk.c */ 7/* ide-disk.c */
15void ide_disk_init_capacity(ide_drive_t *); 8extern const struct ide_disk_ops ide_ata_disk_ops;
16void ide_disk_setup(ide_drive_t *);
17void ide_disk_flush(ide_drive_t *);
18int ide_disk_set_doorlock(ide_drive_t *, int);
19ide_startstop_t ide_do_rw_disk(ide_drive_t *, struct request *, sector_t);
20ide_decl_devset(address); 9ide_decl_devset(address);
21ide_decl_devset(multcount); 10ide_decl_devset(multcount);
22ide_decl_devset(nowerr); 11ide_decl_devset(nowerr);
@@ -24,12 +13,17 @@ ide_decl_devset(wcache);
24ide_decl_devset(acoustic); 13ide_decl_devset(acoustic);
25 14
26/* ide-disk_ioctl.c */ 15/* ide-disk_ioctl.c */
27int ide_disk_ioctl(struct inode *, struct file *, unsigned int, unsigned long); 16int ide_disk_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int,
17 unsigned long);
28 18
29#ifdef CONFIG_IDE_PROC_FS 19#ifdef CONFIG_IDE_PROC_FS
30/* ide-disk_proc.c */ 20/* ide-disk_proc.c */
31extern ide_proc_entry_t ide_disk_proc[]; 21extern ide_proc_entry_t ide_disk_proc[];
32extern const struct ide_proc_devset ide_disk_settings[]; 22extern const struct ide_proc_devset ide_disk_settings[];
33#endif 23#endif
24#else
25#define ide_disk_proc NULL
26#define ide_disk_settings NULL
27#endif
34 28
35#endif /* __IDE_DISK_H */ 29#endif /* __IDE_DISK_H */
diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c
index e6624eda9e69..a49698bcf966 100644
--- a/drivers/ide/ide-disk_ioctl.c
+++ b/drivers/ide/ide-disk_ioctl.c
@@ -13,12 +13,10 @@ static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = {
13{ 0 } 13{ 0 }
14}; 14};
15 15
16int ide_disk_ioctl(struct inode *inode, struct file *file, 16int ide_disk_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file,
17 unsigned int cmd, unsigned long arg) 17 unsigned int cmd, unsigned long arg)
18{ 18{
19 struct block_device *bdev = inode->i_bdev; 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 int err; 20 int err;
23 21
24 err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); 22 err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 802e0968e32f..58746c748c12 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -68,7 +68,7 @@
68 * Used to finish servicing a request. For read/write requests, we will call 68 * Used to finish servicing a request. For read/write requests, we will call
69 * ide_end_request to pass to the next buffer. 69 * ide_end_request to pass to the next buffer.
70 */ 70 */
71int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) 71static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
72{ 72{
73 idefloppy_floppy_t *floppy = drive->driver_data; 73 idefloppy_floppy_t *floppy = drive->driver_data;
74 struct request *rq = HWGROUP(drive)->rq; 74 struct request *rq = HWGROUP(drive)->rq;
@@ -280,13 +280,12 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
280 pc->req_xfer = pc->buf_size = rq->data_len; 280 pc->req_xfer = pc->buf_size = rq->data_len;
281} 281}
282 282
283ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, struct request *rq, 283static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
284 sector_t block_s) 284 struct request *rq, sector_t block)
285{ 285{
286 idefloppy_floppy_t *floppy = drive->driver_data; 286 idefloppy_floppy_t *floppy = drive->driver_data;
287 ide_hwif_t *hwif = drive->hwif; 287 ide_hwif_t *hwif = drive->hwif;
288 struct ide_atapi_pc *pc; 288 struct ide_atapi_pc *pc;
289 unsigned long block = (unsigned long)block_s;
290 289
291 ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " 290 ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
292 "errors: %d\n", 291 "errors: %d\n",
@@ -316,7 +315,7 @@ ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, struct request *rq,
316 return ide_stopped; 315 return ide_stopped;
317 } 316 }
318 pc = &floppy->queued_pc; 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 } else if (blk_special_request(rq)) { 319 } else if (blk_special_request(rq)) {
321 pc = (struct ide_atapi_pc *) rq->buffer; 320 pc = (struct ide_atapi_pc *) rq->buffer;
322 } else if (blk_pc_request(rq)) { 321 } else if (blk_pc_request(rq)) {
@@ -406,7 +405,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
406 * Determine if a media is present in the floppy drive, and if so, its LBA 405 * Determine if a media is present in the floppy drive, and if so, its LBA
407 * capacity. 406 * capacity.
408 */ 407 */
409int ide_floppy_get_capacity(ide_drive_t *drive) 408static int ide_floppy_get_capacity(ide_drive_t *drive)
410{ 409{
411 idefloppy_floppy_t *floppy = drive->driver_data; 410 idefloppy_floppy_t *floppy = drive->driver_data;
412 struct gendisk *disk = floppy->disk; 411 struct gendisk *disk = floppy->disk;
@@ -505,9 +504,9 @@ int ide_floppy_get_capacity(ide_drive_t *drive)
505 return rc; 504 return rc;
506} 505}
507 506
508void ide_floppy_setup(ide_drive_t *drive) 507static 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 u16 *id = drive->id; 510 u16 *id = drive->id;
512 511
513 drive->pc_callback = ide_floppy_callback; 512 drive->pc_callback = ide_floppy_callback;
@@ -547,3 +546,33 @@ void ide_floppy_setup(ide_drive_t *drive)
547 546
548 drive->dev_flags |= IDE_DFLAG_ATTACH; 547 drive->dev_flags |= IDE_DFLAG_ATTACH;
549} 548}
549
550static void ide_floppy_flush(ide_drive_t *drive)
551{
552}
553
554static 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
568const 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};
diff --git a/drivers/ide/ide-floppy.h b/drivers/ide/ide-floppy.h
index b965da2f41ce..acebc8c5a827 100644
--- a/drivers/ide/ide-floppy.h
+++ b/drivers/ide/ide-floppy.h
@@ -1,48 +1,10 @@
1#ifndef __IDE_FLOPPY_H 1#ifndef __IDE_FLOPPY_H
2#define __IDE_FLOPPY_H 2#define __IDE_FLOPPY_H
3 3
4#define DRV_NAME "ide-floppy" 4#include "ide-gd.h"
5#define PFX DRV_NAME ": "
6 5
7/* define to see debug info */ 6#ifdef CONFIG_IDE_GD_ATAPI
8#define IDEFLOPPY_DEBUG_LOG 0 7typedef struct ide_disk_obj idefloppy_floppy_t;
9
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/*
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 */
21typedef 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 8
47/* 9/*
48 * Pages of the SELECT SENSE / MODE SENSE packet commands. 10 * Pages of the SELECT SENSE / MODE SENSE packet commands.
@@ -57,23 +19,23 @@ typedef struct ide_floppy_obj {
57#define IDEFLOPPY_IOCTL_FORMAT_START 0x4602 19#define IDEFLOPPY_IOCTL_FORMAT_START 0x4602
58#define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 20#define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603
59 21
60sector_t ide_gd_capacity(ide_drive_t *);
61
62/* ide-floppy.c */ 22/* ide-floppy.c */
23extern const struct ide_disk_ops ide_atapi_disk_ops;
63void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); 24void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8);
64void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); 25void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *);
65int ide_floppy_get_capacity(ide_drive_t *);
66void ide_floppy_setup(ide_drive_t *);
67ide_startstop_t ide_floppy_do_request(ide_drive_t *, struct request *, sector_t);
68int ide_floppy_end_request(ide_drive_t *, int, int);
69 26
70/* ide-floppy_ioctl.c */ 27/* ide-floppy_ioctl.c */
71int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long); 28int ide_floppy_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int,
29 unsigned long);
72 30
73#ifdef CONFIG_IDE_PROC_FS 31#ifdef CONFIG_IDE_PROC_FS
74/* ide-floppy_proc.c */ 32/* ide-floppy_proc.c */
75extern ide_proc_entry_t ide_floppy_proc[]; 33extern ide_proc_entry_t ide_floppy_proc[];
76extern const struct ide_proc_devset ide_floppy_settings[]; 34extern const struct ide_proc_devset ide_floppy_settings[];
77#endif 35#endif
36#else
37#define ide_floppy_proc NULL
38#define ide_floppy_settings NULL
39#endif
78 40
79#endif /*__IDE_FLOPPY_H */ 41#endif /*__IDE_FLOPPY_H */
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index b1f391df6cca..e8aa0a5bf5dc 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -33,7 +33,7 @@
33 33
34static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) 34static 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 struct ide_atapi_pc pc; 37 struct ide_atapi_pc pc;
38 u8 header_len, desc_cnt; 38 u8 header_len, desc_cnt;
39 int i, blocks, length, u_array_size, u_index; 39 int i, blocks, length, u_array_size, u_index;
@@ -260,13 +260,10 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file,
260 } 260 }
261} 261}
262 262
263int ide_floppy_ioctl(struct inode *inode, struct file *file, 263int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode,
264 unsigned int cmd, unsigned long arg) 264 struct file *file, unsigned int cmd, unsigned long arg)
265{ 265{
266 struct block_device *bdev = inode->i_bdev; 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 struct ide_atapi_pc pc; 267 struct ide_atapi_pc pc;
271 void __user *argp = (void __user *)arg; 268 void __user *argp = (void __user *)arg;
272 int err; 269 int err;
diff --git a/drivers/ide/ide-gd-floppy.c b/drivers/ide/ide-gd-floppy.c
deleted file mode 100644
index 082800b9a558..000000000000
--- a/drivers/ide/ide-gd-floppy.c
+++ /dev/null
@@ -1,309 +0,0 @@
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 */
16static unsigned long debug_mask;
17module_param(debug_mask, ulong, 0644);
18
19static DEFINE_MUTEX(ide_disk_ref_mutex);
20
21static void ide_disk_release(struct kref *);
22
23static 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
39static 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
49sector_t ide_gd_capacity(ide_drive_t *drive)
50{
51 return drive->capacity64;
52}
53
54static int ide_gd_probe(ide_drive_t *);
55
56static 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
68static 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
81static ide_proc_entry_t *ide_floppy_proc_entries(ide_drive_t *drive)
82{
83 return ide_floppy_proc;
84}
85
86static const struct ide_proc_devset *ide_floppy_proc_devsets(ide_drive_t *drive)
87{
88 return ide_floppy_settings;
89}
90#endif
91
92static 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
110static 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
162out_put_idkp:
163 idkp->openers--;
164 ide_disk_put(idkp);
165 return ret;
166}
167
168static 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
188static 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
199static 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
217static 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
224static 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
234static 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
287out_free_idkp:
288 kfree(idkp);
289failed:
290 return -ENODEV;
291}
292
293static 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
299static void __exit ide_gd_exit(void)
300{
301 driver_unregister(&ide_gd_driver.gen_driver);
302}
303
304MODULE_ALIAS("ide:*m-floppy*");
305MODULE_ALIAS("ide-floppy");
306module_init(ide_gd_init);
307module_exit(ide_gd_exit);
308MODULE_LICENSE("GPL");
309MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index a3d4ad7db2af..d44898f46c33 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -15,9 +15,14 @@
15#endif 15#endif
16 16
17#include "ide-disk.h" 17#include "ide-disk.h"
18#include "ide-floppy.h"
18 19
19#define IDE_GD_VERSION "1.18" 20#define IDE_GD_VERSION "1.18"
20 21
22/* module parameters */
23static unsigned long debug_mask;
24module_param(debug_mask, ulong, 0644);
25
21static DEFINE_MUTEX(ide_disk_ref_mutex); 26static DEFINE_MUTEX(ide_disk_ref_mutex);
22 27
23static void ide_disk_release(struct kref *); 28static void ide_disk_release(struct kref *);
@@ -64,7 +69,7 @@ static void ide_gd_remove(ide_drive_t *drive)
64 69
65 del_gendisk(g); 70 del_gendisk(g);
66 71
67 ide_disk_flush(drive); 72 drive->disk_ops->flush(drive);
68 73
69 ide_disk_put(idkp); 74 ide_disk_put(idkp);
70} 75}
@@ -75,6 +80,7 @@ static void ide_disk_release(struct kref *kref)
75 ide_drive_t *drive = idkp->drive; 80 ide_drive_t *drive = idkp->drive;
76 struct gendisk *g = idkp->disk; 81 struct gendisk *g = idkp->disk;
77 82
83 drive->disk_ops = NULL;
78 drive->driver_data = NULL; 84 drive->driver_data = NULL;
79 g->private_data = NULL; 85 g->private_data = NULL;
80 put_disk(g); 86 put_disk(g);
@@ -89,7 +95,7 @@ static void ide_disk_release(struct kref *kref)
89static void ide_gd_resume(ide_drive_t *drive) 95static void ide_gd_resume(ide_drive_t *drive)
90{ 96{
91 if (ata_id_hpa_enabled(drive->id)) 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
95static void ide_gd_shutdown(ide_drive_t *drive) 101static void ide_gd_shutdown(ide_drive_t *drive)
@@ -110,7 +116,7 @@ static void ide_gd_shutdown(ide_drive_t *drive)
110#else 116#else
111 if (system_state == SYSTEM_RESTART) { 117 if (system_state == SYSTEM_RESTART) {
112#endif 118#endif
113 ide_disk_flush(drive); 119 drive->disk_ops->flush(drive);
114 return; 120 return;
115 } 121 }
116 122
@@ -122,19 +128,31 @@ static void ide_gd_shutdown(ide_drive_t *drive)
122#ifdef CONFIG_IDE_PROC_FS 128#ifdef CONFIG_IDE_PROC_FS
123static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive) 129static 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
128static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive) 134static 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#endif 139#endif
133 140
141static 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
147static 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
134static ide_driver_t ide_gd_driver = { 152static ide_driver_t ide_gd_driver = {
135 .gen_driver = { 153 .gen_driver = {
136 .owner = THIS_MODULE, 154 .owner = THIS_MODULE,
137 .name = "ide-disk", 155 .name = "ide-gd",
138 .bus = &ide_bus_type, 156 .bus = &ide_bus_type,
139 }, 157 },
140 .probe = ide_gd_probe, 158 .probe = ide_gd_probe,
@@ -142,8 +160,8 @@ static ide_driver_t ide_gd_driver = {
142 .resume = ide_gd_resume, 160 .resume = ide_gd_resume,
143 .shutdown = ide_gd_shutdown, 161 .shutdown = ide_gd_shutdown,
144 .version = IDE_GD_VERSION, 162 .version = IDE_GD_VERSION,
145 .do_request = ide_do_rw_disk, 163 .do_request = ide_gd_do_request,
146 .end_request = ide_end_request, 164 .end_request = ide_gd_end_request,
147 .error = __ide_error, 165 .error = __ide_error,
148#ifdef CONFIG_IDE_PROC_FS 166#ifdef CONFIG_IDE_PROC_FS
149 .proc_entries = ide_disk_proc_entries, 167 .proc_entries = ide_disk_proc_entries,
@@ -156,6 +174,7 @@ static int ide_gd_open(struct inode *inode, struct file *filp)
156 struct gendisk *disk = inode->i_bdev->bd_disk; 174 struct gendisk *disk = inode->i_bdev->bd_disk;
157 struct ide_disk_obj *idkp; 175 struct ide_disk_obj *idkp;
158 ide_drive_t *drive; 176 ide_drive_t *drive;
177 int ret = 0;
159 178
160 idkp = ide_disk_get(disk); 179 idkp = ide_disk_get(disk);
161 if (idkp == NULL) 180 if (idkp == NULL)
@@ -163,19 +182,49 @@ static int ide_gd_open(struct inode *inode, struct file *filp)
163 182
164 drive = idkp->drive; 183 drive = idkp->drive;
165 184
185 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
186
166 idkp->openers++; 187 idkp->openers++;
167 188
168 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { 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
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
169 /* 210 /*
170 * Ignore the return code from door_lock, 211 * Ignore the return code from door_lock,
171 * since the open() has already succeeded, 212 * since the open() has already succeeded,
172 * and the door_lock is irrelevant at this point. 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 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; 216 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
176 check_disk_change(inode->i_bdev); 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 return 0; 222 return 0;
223
224out_put_idkp:
225 idkp->openers--;
226 ide_disk_put(idkp);
227 return ret;
179} 228}
180 229
181static int ide_gd_release(struct inode *inode, struct file *filp) 230static int ide_gd_release(struct inode *inode, struct file *filp)
@@ -184,11 +233,15 @@ static int ide_gd_release(struct inode *inode, struct file *filp)
184 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); 233 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
185 ide_drive_t *drive = idkp->drive; 234 ide_drive_t *drive = idkp->drive;
186 235
236 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
237
187 if (idkp->openers == 1) 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) 241 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
191 ide_disk_set_doorlock(drive, 0); 242 drive->disk_ops->set_doorlock(drive, disk, 0);
243 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
244 }
192 245
193 idkp->openers--; 246 idkp->openers--;
194 247
@@ -233,11 +286,21 @@ static int ide_gd_revalidate_disk(struct gendisk *disk)
233 return 0; 286 return 0;
234} 287}
235 288
289static 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
236static struct block_device_operations ide_gd_ops = { 299static struct block_device_operations ide_gd_ops = {
237 .owner = THIS_MODULE, 300 .owner = THIS_MODULE,
238 .open = ide_gd_open, 301 .open = ide_gd_open,
239 .release = ide_gd_release, 302 .release = ide_gd_release,
240 .ioctl = ide_disk_ioctl, 303 .ioctl = ide_gd_ioctl,
241 .getgeo = ide_gd_getgeo, 304 .getgeo = ide_gd_getgeo,
242 .media_changed = ide_gd_media_changed, 305 .media_changed = ide_gd_media_changed,
243 .revalidate_disk = ide_gd_revalidate_disk 306 .revalidate_disk = ide_gd_revalidate_disk
@@ -245,19 +308,37 @@ static struct block_device_operations ide_gd_ops = {
245 308
246static int ide_gd_probe(ide_drive_t *drive) 309static int ide_gd_probe(ide_drive_t *drive)
247{ 310{
311 const struct ide_disk_ops *disk_ops = NULL;
248 struct ide_disk_obj *idkp; 312 struct ide_disk_obj *idkp;
249 struct gendisk *g; 313 struct gendisk *g;
250 314
251 /* strstr("foo", "") is non-NULL */ 315 /* strstr("foo", "") is non-NULL */
252 if (!strstr("ide-disk", drive->driver_req)) 316 if (!strstr("ide-gd", drive->driver_req))
317 goto failed;
318
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)
253 goto failed; 328 goto failed;
254 329
255 if (drive->media != ide_disk) 330 if (disk_ops->check(drive, DRV_NAME) == 0) {
331 printk(KERN_ERR PFX "%s: not supported by this driver\n",
332 drive->name);
256 goto failed; 333 goto failed;
334 }
257 335
258 idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); 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 goto failed; 340 goto failed;
341 }
261 342
262 g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); 343 g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
263 if (!g) 344 if (!g)
@@ -274,8 +355,10 @@ static int ide_gd_probe(ide_drive_t *drive)
274 g->private_data = &idkp->driver; 355 g->private_data = &idkp->driver;
275 356
276 drive->driver_data = idkp; 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 set_capacity(g, ide_gd_capacity(drive)); 363 set_capacity(g, ide_gd_capacity(drive));
281 364
@@ -296,6 +379,7 @@ failed:
296 379
297static int __init ide_gd_init(void) 380static int __init ide_gd_init(void)
298{ 381{
382 printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
299 return driver_register(&ide_gd_driver.gen_driver); 383 return driver_register(&ide_gd_driver.gen_driver);
300} 384}
301 385
@@ -306,7 +390,9 @@ static void __exit ide_gd_exit(void)
306 390
307MODULE_ALIAS("ide:*m-disk*"); 391MODULE_ALIAS("ide:*m-disk*");
308MODULE_ALIAS("ide-disk"); 392MODULE_ALIAS("ide-disk");
393MODULE_ALIAS("ide:*m-floppy*");
394MODULE_ALIAS("ide-floppy");
309module_init(ide_gd_init); 395module_init(ide_gd_init);
310module_exit(ide_gd_exit); 396module_exit(ide_gd_exit);
311MODULE_LICENSE("GPL"); 397MODULE_LICENSE("GPL");
312MODULE_DESCRIPTION("ATA DISK Driver"); 398MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h
new file mode 100644
index 000000000000..7d3d101713e0
--- /dev/null
+++ b/drivers/ide/ide-gd.h
@@ -0,0 +1,44 @@
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
16struct 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
42sector_t ide_gd_capacity(ide_drive_t *);
43
44#endif /* __IDE_GD_H */