]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
ide: add generic ATA/ATAPI disk driver
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Fri, 17 Oct 2008 16:09:14 +0000 (18:09 +0200)
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Fri, 17 Oct 2008 16:09:14 +0000 (18:09 +0200)
* 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>
13 files changed:
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 [deleted file]
drivers/ide/ide-gd.c
drivers/ide/ide-gd.h [new file with mode: 0644]
drivers/leds/Kconfig
include/linux/ide.h

index 74a369a6116fc7fbeb7bea0c68c629ec4cfb1102..faa974e615dac0381cdbb558d6fdb91c80e9e54e 100644 (file)
@@ -84,21 +84,40 @@ config BLK_DEV_IDE_SATA
 
          If unsure, say N.
 
 
          If unsure, say N.
 
-config BLK_DEV_IDEDISK
-       tristate "Include IDE/ATA-2 DISK support"
-       ---help---
-         This will include enhanced support for MFM/RLL/IDE hard disks.  If
-         you have a MFM/RLL/IDE disk, and there is no special reason to use
-         the old hard disk driver instead, say Y.  If you have an SCSI-only
-         system, you can say N here.
+config IDE_GD
+       tristate "generic ATA/ATAPI disk support"
+       default y
+       help
+         Support for ATA/ATAPI disks (including ATAPI floppy drives).
 
 
-         To compile this driver as a module, choose M here: the
-         module will be called ide-disk.
-         Do not compile this driver as a module if your root file system
-         (the one containing the directory /) is located on the IDE disk.
+         To compile this driver as a module, choose M here.
+         The module will be called ide-gd_mod.
 
          If unsure, say Y.
 
 
          If unsure, say Y.
 
+config IDE_GD_ATA
+       bool "ATA disk support"
+       depends on IDE_GD
+       default y
+       help
+         This will include support for ATA hard disks.
+
+         If unsure, say Y.
+
+config IDE_GD_ATAPI
+       bool "ATAPI floppy support"
+       depends on IDE_GD
+       select IDE_ATAPI
+       help
+         This will include support for ATAPI floppy drives
+         (i.e. Iomega ZIP or MKE LS-120).
+
+         For information about jumper settings and the question
+         of when a ZIP drive uses a partition table, see
+         <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>.
+
+         If unsure, say N.
+
 config BLK_DEV_IDECS
        tristate "PCMCIA IDE support"
        depends on PCMCIA
 config BLK_DEV_IDECS
        tristate "PCMCIA IDE support"
        depends on PCMCIA
@@ -163,29 +182,6 @@ config BLK_DEV_IDETAPE
          To compile this driver as a module, choose M here: the
          module will be called ide-tape.
 
          To compile this driver as a module, choose M here: the
          module will be called ide-tape.
 
-config BLK_DEV_IDEFLOPPY
-       tristate "Include IDE/ATAPI FLOPPY support"
-       select IDE_ATAPI
-       ---help---
-         If you have an IDE floppy drive which uses the ATAPI protocol,
-         answer Y.  ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy
-         drives, similar to the SCSI protocol.
-
-         The LS-120 and the IDE/ATAPI Iomega ZIP drive are also supported by
-         this driver. For information about jumper settings and the question
-         of when a ZIP drive uses a partition table, see
-         <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>.
-         (ATAPI PD-CD/CDR drives are not supported by this driver; support
-         for PD-CD/CDR drives is available if you answer Y to
-         "SCSI emulation support", below).
-
-         If you say Y here, the FLOPPY drive will be identified along with
-         other IDE devices, as "hdb" or "hdc", or something similar (check
-         the boot messages with dmesg).
-
-         To compile this driver as a module, choose M here: the
-         module will be called ide-floppy.
-
 config BLK_DEV_IDESCSI
        tristate "SCSI emulation support (DEPRECATED)"
        depends on SCSI
 config BLK_DEV_IDESCSI
        tristate "SCSI emulation support (DEPRECATED)"
        depends on SCSI
index 7eeeab59795965c7508d1485a2db7575afe5dfd5..093d3248ca898359b1e874fd9a9d4153eb21eed7 100644 (file)
@@ -37,18 +37,25 @@ obj-$(CONFIG_IDE_H8300)                     += h8300/
 obj-$(CONFIG_IDE_GENERIC)              += ide-generic.o
 obj-$(CONFIG_BLK_DEV_IDEPNP)           += ide-pnp.o
 
 obj-$(CONFIG_IDE_GENERIC)              += ide-generic.o
 obj-$(CONFIG_BLK_DEV_IDEPNP)           += ide-pnp.o
 
-ide-disk_mod-y += ide-gd.o ide-disk.o ide-disk_ioctl.o
+ide-gd_mod-y += ide-gd.o
 ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o
 ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o
-ide-floppy_mod-y += ide-gd-floppy.o ide-floppy.o ide-floppy_ioctl.o
 
 
+ifeq ($(CONFIG_IDE_GD_ATA), y)
+       ide-gd_mod-y += ide-disk.o ide-disk_ioctl.o
 ifeq ($(CONFIG_IDE_PROC_FS), y)
 ifeq ($(CONFIG_IDE_PROC_FS), y)
-       ide-disk_mod-y += ide-disk_proc.o
-       ide-floppy_mod-y += ide-floppy_proc.o
+       ide-gd_mod-y += ide-disk_proc.o
+endif
+endif
+
+ifeq ($(CONFIG_IDE_GD_ATAPI), y)
+       ide-gd_mod-y += ide-floppy.o ide-floppy_ioctl.o
+ifeq ($(CONFIG_IDE_PROC_FS), y)
+       ide-gd_mod-y += ide-floppy_proc.o
+endif
 endif
 
 endif
 
-obj-$(CONFIG_BLK_DEV_IDEDISK)          += ide-disk_mod.o
+obj-$(CONFIG_IDE_GD)                   += ide-gd_mod.o
 obj-$(CONFIG_BLK_DEV_IDECD)            += ide-cd_mod.o
 obj-$(CONFIG_BLK_DEV_IDECD)            += ide-cd_mod.o
-obj-$(CONFIG_BLK_DEV_IDEFLOPPY)                += ide-floppy_mod.o
 obj-$(CONFIG_BLK_DEV_IDETAPE)          += ide-tape.o
 
 ifeq ($(CONFIG_BLK_DEV_IDECS), y)
 obj-$(CONFIG_BLK_DEV_IDETAPE)          += ide-tape.o
 
 ifeq ($(CONFIG_BLK_DEV_IDECS), y)
index 751be7af22c291fe3f4ba7ff0449dffe0512007a..223750c1b5a6a170bccfcd0b6171b022df0c5caa 100644 (file)
@@ -184,8 +184,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
  * 1073741822 == 549756 MB or 48bit addressing fake drive
  */
 
  * 1073741822 == 549756 MB or 48bit addressing fake drive
  */
 
-ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
-                              sector_t block)
+static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
+                                     sector_t block)
 {
        ide_hwif_t *hwif = HWIF(drive);
 
 {
        ide_hwif_t *hwif = HWIF(drive);
 
@@ -333,7 +333,7 @@ static void idedisk_check_hpa(ide_drive_t *drive)
        }
 }
 
        }
 }
 
-void ide_disk_init_capacity(ide_drive_t *drive)
+static int ide_disk_get_capacity(ide_drive_t *drive)
 {
        u16 *id = drive->id;
        int lba;
 {
        u16 *id = drive->id;
        int lba;
@@ -382,6 +382,8 @@ void ide_disk_init_capacity(ide_drive_t *drive)
                } else
                        drive->dev_flags &= ~IDE_DFLAG_LBA48;
        }
                } else
                        drive->dev_flags &= ~IDE_DFLAG_LBA48;
        }
+
+       return 0;
 }
 
 static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
 }
 
 static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
@@ -590,7 +592,12 @@ ide_ext_devset_rw(wcache, wcache);
 
 ide_ext_devset_rw_sync(nowerr, nowerr);
 
 
 ide_ext_devset_rw_sync(nowerr, nowerr);
 
-void ide_disk_setup(ide_drive_t *drive)
+static int ide_disk_check(ide_drive_t *drive, const char *s)
+{
+       return 1;
+}
+
+static void ide_disk_setup(ide_drive_t *drive)
 {
        struct ide_disk_obj *idkp = drive->driver_data;
        ide_hwif_t *hwif = drive->hwif;
 {
        struct ide_disk_obj *idkp = drive->driver_data;
        ide_hwif_t *hwif = drive->hwif;
@@ -626,7 +633,7 @@ void ide_disk_setup(ide_drive_t *drive)
                         drive->queue->max_sectors / 2);
 
        /* calculate drive capacity, and select LBA if possible */
                         drive->queue->max_sectors / 2);
 
        /* calculate drive capacity, and select LBA if possible */
-       ide_disk_init_capacity(drive);
+       ide_disk_get_capacity(drive);
 
        /*
         * if possible, give fdisk access to more of the drive,
 
        /*
         * if possible, give fdisk access to more of the drive,
@@ -682,7 +689,7 @@ void ide_disk_setup(ide_drive_t *drive)
                drive->dev_flags |= IDE_DFLAG_ATTACH;
 }
 
                drive->dev_flags |= IDE_DFLAG_ATTACH;
 }
 
-void ide_disk_flush(ide_drive_t *drive)
+static void ide_disk_flush(ide_drive_t *drive)
 {
        if (ata_id_flush_enabled(drive->id) == 0 ||
            (drive->dev_flags & IDE_DFLAG_WCACHE) == 0)
 {
        if (ata_id_flush_enabled(drive->id) == 0 ||
            (drive->dev_flags & IDE_DFLAG_WCACHE) == 0)
@@ -692,7 +699,13 @@ void ide_disk_flush(ide_drive_t *drive)
                printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
 }
 
                printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
 }
 
-int ide_disk_set_doorlock(ide_drive_t *drive, int on)
+static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk)
+{
+       return 0;
+}
+
+static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
+                                int on)
 {
        ide_task_t task;
        int ret;
 {
        ide_task_t task;
        int ret;
@@ -711,3 +724,15 @@ int ide_disk_set_doorlock(ide_drive_t *drive, int on)
 
        return ret;
 }
 
        return ret;
 }
+
+const struct ide_disk_ops ide_ata_disk_ops = {
+       .check          = ide_disk_check,
+       .get_capacity   = ide_disk_get_capacity,
+       .setup          = ide_disk_setup,
+       .flush          = ide_disk_flush,
+       .init_media     = ide_disk_init_media,
+       .set_doorlock   = ide_disk_set_doorlock,
+       .do_request     = ide_do_rw_disk,
+       .end_request    = ide_end_request,
+       .ioctl          = ide_disk_ioctl,
+};
index 104ad71288a58d668f026f72c85975121e39d4cd..b234b0feaf7b2f03c9a180891c97d7f8734f997d 100644 (file)
@@ -1,22 +1,11 @@
 #ifndef __IDE_DISK_H
 #define __IDE_DISK_H
 
 #ifndef __IDE_DISK_H
 #define __IDE_DISK_H
 
-struct ide_disk_obj {
-       ide_drive_t     *drive;
-       ide_driver_t    *driver;
-       struct gendisk  *disk;
-       struct kref     kref;
-       unsigned int    openers;        /* protected by BKL for now */
-};
-
-sector_t ide_gd_capacity(ide_drive_t *);
+#include "ide-gd.h"
 
 
+#ifdef CONFIG_IDE_GD_ATA
 /* ide-disk.c */
 /* ide-disk.c */
-void ide_disk_init_capacity(ide_drive_t *);
-void ide_disk_setup(ide_drive_t *);
-void ide_disk_flush(ide_drive_t *);
-int ide_disk_set_doorlock(ide_drive_t *, int);
-ide_startstop_t ide_do_rw_disk(ide_drive_t *, struct request *, sector_t);
+extern const struct ide_disk_ops ide_ata_disk_ops;
 ide_decl_devset(address);
 ide_decl_devset(multcount);
 ide_decl_devset(nowerr);
 ide_decl_devset(address);
 ide_decl_devset(multcount);
 ide_decl_devset(nowerr);
@@ -24,12 +13,17 @@ ide_decl_devset(wcache);
 ide_decl_devset(acoustic);
 
 /* ide-disk_ioctl.c */
 ide_decl_devset(acoustic);
 
 /* ide-disk_ioctl.c */
-int ide_disk_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int ide_disk_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int,
+                  unsigned long);
 
 #ifdef CONFIG_IDE_PROC_FS
 /* ide-disk_proc.c */
 extern ide_proc_entry_t ide_disk_proc[];
 extern const struct ide_proc_devset ide_disk_settings[];
 #endif
 
 #ifdef CONFIG_IDE_PROC_FS
 /* ide-disk_proc.c */
 extern ide_proc_entry_t ide_disk_proc[];
 extern const struct ide_proc_devset ide_disk_settings[];
 #endif
+#else
+#define ide_disk_proc          NULL
+#define ide_disk_settings      NULL
+#endif
 
 #endif /* __IDE_DISK_H */
 
 #endif /* __IDE_DISK_H */
index e6624eda9e69bcfea5b0be4f160500df77bdd69e..a49698bcf9667e097ae7ab3899aae29efa5b3136 100644 (file)
@@ -13,12 +13,10 @@ static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = {
 { 0 }
 };
 
 { 0 }
 };
 
-int ide_disk_ioctl(struct inode *inode, struct file *file,
+int ide_disk_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file,
                   unsigned int cmd, unsigned long arg)
 {
        struct block_device *bdev = inode->i_bdev;
                   unsigned int cmd, unsigned long arg)
 {
        struct block_device *bdev = inode->i_bdev;
-       struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
-       ide_drive_t *drive = idkp->drive;
        int err;
 
        err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings);
        int err;
 
        err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings);
index 802e0968e32fd18a0c7e491e8dfd8362e369e453..58746c748c123bc05298e6d6a3f9bb47194ac8b9 100644 (file)
@@ -68,7 +68,7 @@
  * Used to finish servicing a request. For read/write requests, we will call
  * ide_end_request to pass to the next buffer.
  */
  * Used to finish servicing a request. For read/write requests, we will call
  * ide_end_request to pass to the next buffer.
  */
-int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
+static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
        struct request *rq = HWGROUP(drive)->rq;
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
        struct request *rq = HWGROUP(drive)->rq;
@@ -280,13 +280,12 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
        pc->req_xfer = pc->buf_size = rq->data_len;
 }
 
        pc->req_xfer = pc->buf_size = rq->data_len;
 }
 
-ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, struct request *rq,
-                                     sector_t block_s)
+static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
+                                            struct request *rq, sector_t block)
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
        ide_hwif_t *hwif = drive->hwif;
        struct ide_atapi_pc *pc;
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
        ide_hwif_t *hwif = drive->hwif;
        struct ide_atapi_pc *pc;
-       unsigned long block = (unsigned long)block_s;
 
        ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
                      "errors: %d\n",
 
        ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
                      "errors: %d\n",
@@ -316,7 +315,7 @@ ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, struct request *rq,
                        return ide_stopped;
                }
                pc = &floppy->queued_pc;
                        return ide_stopped;
                }
                pc = &floppy->queued_pc;
-               idefloppy_create_rw_cmd(drive, pc, rq, block);
+               idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
        } else if (blk_special_request(rq)) {
                pc = (struct ide_atapi_pc *) rq->buffer;
        } else if (blk_pc_request(rq)) {
        } else if (blk_special_request(rq)) {
                pc = (struct ide_atapi_pc *) rq->buffer;
        } else if (blk_pc_request(rq)) {
@@ -406,7 +405,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
  * Determine if a media is present in the floppy drive, and if so, its LBA
  * capacity.
  */
  * Determine if a media is present in the floppy drive, and if so, its LBA
  * capacity.
  */
-int ide_floppy_get_capacity(ide_drive_t *drive)
+static int ide_floppy_get_capacity(ide_drive_t *drive)
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
        struct gendisk *disk = floppy->disk;
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
        struct gendisk *disk = floppy->disk;
@@ -505,9 +504,9 @@ int ide_floppy_get_capacity(ide_drive_t *drive)
        return rc;
 }
 
        return rc;
 }
 
-void ide_floppy_setup(ide_drive_t *drive)
+static void ide_floppy_setup(ide_drive_t *drive)
 {
 {
-       struct ide_floppy_obj *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        u16 *id = drive->id;
 
        drive->pc_callback       = ide_floppy_callback;
        u16 *id = drive->id;
 
        drive->pc_callback       = ide_floppy_callback;
@@ -547,3 +546,33 @@ void ide_floppy_setup(ide_drive_t *drive)
 
        drive->dev_flags |= IDE_DFLAG_ATTACH;
 }
 
        drive->dev_flags |= IDE_DFLAG_ATTACH;
 }
+
+static void ide_floppy_flush(ide_drive_t *drive)
+{
+}
+
+static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk)
+{
+       int ret = 0;
+
+       if (ide_do_test_unit_ready(drive, disk))
+               ide_do_start_stop(drive, disk, 1);
+
+       ret = ide_floppy_get_capacity(drive);
+
+       set_capacity(disk, ide_gd_capacity(drive));
+
+       return ret;
+}
+
+const struct ide_disk_ops ide_atapi_disk_ops = {
+       .check          = ide_check_atapi_device,
+       .get_capacity   = ide_floppy_get_capacity,
+       .setup          = ide_floppy_setup,
+       .flush          = ide_floppy_flush,
+       .init_media     = ide_floppy_init_media,
+       .set_doorlock   = ide_set_media_lock,
+       .do_request     = ide_floppy_do_request,
+       .end_request    = ide_floppy_end_request,
+       .ioctl          = ide_floppy_ioctl,
+};
index b965da2f41ce987118b38d2aff8d9937644efde3..acebc8c5a827fcbc5e8f8458bd95f21e9567e60c 100644 (file)
@@ -1,48 +1,10 @@
 #ifndef __IDE_FLOPPY_H
 #define __IDE_FLOPPY_H
 
 #ifndef __IDE_FLOPPY_H
 #define __IDE_FLOPPY_H
 
-#define DRV_NAME "ide-floppy"
-#define PFX DRV_NAME ": "
+#include "ide-gd.h"
 
 
-/* define to see debug info */
-#define IDEFLOPPY_DEBUG_LOG    0
-
-#if IDEFLOPPY_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
-#else
-#define ide_debug_log(lvl, fmt, args...) do {} while (0)
-#endif
-
-/*
- * Most of our global data which we need to save even as we leave the driver
- * due to an interrupt or a timer event is stored in a variable of type
- * idefloppy_floppy_t, defined below.
- */
-typedef struct ide_floppy_obj {
-       ide_drive_t     *drive;
-       ide_driver_t    *driver;
-       struct gendisk  *disk;
-       struct kref     kref;
-       unsigned int    openers;        /* protected by BKL for now */
-
-       /* Last failed packet command */
-       struct ide_atapi_pc *failed_pc;
-       /* used for blk_{fs,pc}_request() requests */
-       struct ide_atapi_pc queued_pc;
-
-       /* Last error information */
-       u8 sense_key, asc, ascq;
-
-       int progress_indication;
-
-       /* Device information */
-       /* Current format */
-       int blocks, block_size, bs_factor;
-       /* Last format capacity descriptor */
-       u8 cap_desc[8];
-       /* Copy of the flexible disk page */
-       u8 flexible_disk_page[32];
-} idefloppy_floppy_t;
+#ifdef CONFIG_IDE_GD_ATAPI
+typedef struct ide_disk_obj idefloppy_floppy_t;
 
 /*
  * Pages of the SELECT SENSE / MODE SENSE packet commands.
 
 /*
  * Pages of the SELECT SENSE / MODE SENSE packet commands.
@@ -57,23 +19,23 @@ typedef struct ide_floppy_obj {
 #define        IDEFLOPPY_IOCTL_FORMAT_START            0x4602
 #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS    0x4603
 
 #define        IDEFLOPPY_IOCTL_FORMAT_START            0x4602
 #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS    0x4603
 
-sector_t ide_gd_capacity(ide_drive_t *);
-
 /* ide-floppy.c */
 /* ide-floppy.c */
+extern const struct ide_disk_ops ide_atapi_disk_ops;
 void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8);
 void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *);
 void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8);
 void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *);
-int ide_floppy_get_capacity(ide_drive_t *);
-void ide_floppy_setup(ide_drive_t *);
-ide_startstop_t ide_floppy_do_request(ide_drive_t *, struct request *, sector_t);
-int ide_floppy_end_request(ide_drive_t *, int, int);
 
 /* ide-floppy_ioctl.c */
 
 /* ide-floppy_ioctl.c */
-int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long);
+int ide_floppy_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int,
+                    unsigned long);
 
 #ifdef CONFIG_IDE_PROC_FS
 /* ide-floppy_proc.c */
 extern ide_proc_entry_t ide_floppy_proc[];
 extern const struct ide_proc_devset ide_floppy_settings[];
 #endif
 
 #ifdef CONFIG_IDE_PROC_FS
 /* ide-floppy_proc.c */
 extern ide_proc_entry_t ide_floppy_proc[];
 extern const struct ide_proc_devset ide_floppy_settings[];
 #endif
+#else
+#define ide_floppy_proc                NULL
+#define ide_floppy_settings    NULL
+#endif
 
 #endif /*__IDE_FLOPPY_H */
 
 #endif /*__IDE_FLOPPY_H */
index b1f391df6cca09fd2bbe85eb53dfb1dd4aa48a51..e8aa0a5bf5dcd0dab430f51b2c78f0943ff41ee8 100644 (file)
@@ -33,7 +33,7 @@
 
 static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
 {
 
 static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
 {
-       struct ide_floppy_obj *floppy = drive->driver_data;
+       struct ide_disk_obj *floppy = drive->driver_data;
        struct ide_atapi_pc pc;
        u8 header_len, desc_cnt;
        int i, blocks, length, u_array_size, u_index;
        struct ide_atapi_pc pc;
        u8 header_len, desc_cnt;
        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,
        }
 }
 
        }
 }
 
-int ide_floppy_ioctl(struct inode *inode, struct file *file,
-                   unsigned int cmd, unsigned long arg)
+int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode,
+                    struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct block_device *bdev = inode->i_bdev;
 {
        struct block_device *bdev = inode->i_bdev;
-       struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk,
-                                                    ide_floppy_obj);
-       ide_drive_t *drive = floppy->drive;
        struct ide_atapi_pc pc;
        void __user *argp = (void __user *)arg;
        int err;
        struct ide_atapi_pc pc;
        void __user *argp = (void __user *)arg;
        int err;
diff --git a/drivers/ide/ide-gd-floppy.c b/drivers/ide/ide-gd-floppy.c
deleted file mode 100644 (file)
index 082800b..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/genhd.h>
-#include <linux/mutex.h>
-#include <linux/ide.h>
-#include <linux/hdreg.h>
-
-#include "ide-floppy.h"
-
-#define IDEFLOPPY_VERSION "1.00"
-
-/* module parameters */
-static unsigned long debug_mask;
-module_param(debug_mask, ulong, 0644);
-
-static DEFINE_MUTEX(ide_disk_ref_mutex);
-
-static void ide_disk_release(struct kref *);
-
-static struct ide_floppy_obj *ide_disk_get(struct gendisk *disk)
-{
-       struct ide_floppy_obj *idkp = NULL;
-
-       mutex_lock(&ide_disk_ref_mutex);
-       idkp = ide_drv_g(disk, ide_floppy_obj);
-       if (idkp) {
-               if (ide_device_get(idkp->drive))
-                       idkp = NULL;
-               else
-                       kref_get(&idkp->kref);
-       }
-       mutex_unlock(&ide_disk_ref_mutex);
-       return idkp;
-}
-
-static void ide_disk_put(struct ide_floppy_obj *idkp)
-{
-       ide_drive_t *drive = idkp->drive;
-
-       mutex_lock(&ide_disk_ref_mutex);
-       kref_put(&idkp->kref, ide_disk_release);
-       ide_device_put(drive);
-       mutex_unlock(&ide_disk_ref_mutex);
-}
-
-sector_t ide_gd_capacity(ide_drive_t *drive)
-{
-       return drive->capacity64;
-}
-
-static int ide_gd_probe(ide_drive_t *);
-
-static void ide_gd_remove(ide_drive_t *drive)
-{
-       struct ide_floppy_obj *idkp = drive->driver_data;
-       struct gendisk *g = idkp->disk;
-
-       ide_proc_unregister_driver(drive, idkp->driver);
-
-       del_gendisk(g);
-
-       ide_disk_put(idkp);
-}
-
-static void ide_disk_release(struct kref *kref)
-{
-       struct ide_floppy_obj *idkp = to_ide_drv(kref, ide_floppy_obj);
-       ide_drive_t *drive = idkp->drive;
-       struct gendisk *g = idkp->disk;
-
-       drive->driver_data = NULL;
-       g->private_data = NULL;
-       put_disk(g);
-       kfree(idkp);
-}
-
-#ifdef CONFIG_IDE_PROC_FS
-static ide_proc_entry_t *ide_floppy_proc_entries(ide_drive_t *drive)
-{
-       return ide_floppy_proc;
-}
-
-static const struct ide_proc_devset *ide_floppy_proc_devsets(ide_drive_t *drive)
-{
-       return ide_floppy_settings;
-}
-#endif
-
-static ide_driver_t ide_gd_driver = {
-       .gen_driver = {
-               .owner          = THIS_MODULE,
-               .name           = "ide-floppy",
-               .bus            = &ide_bus_type,
-       },
-       .probe                  = ide_gd_probe,
-       .remove                 = ide_gd_remove,
-       .version                = IDEFLOPPY_VERSION,
-       .do_request             = ide_floppy_do_request,
-       .end_request            = ide_floppy_end_request,
-       .error                  = __ide_error,
-#ifdef CONFIG_IDE_PROC_FS
-       .proc_entries           = ide_floppy_proc_entries,
-       .proc_devsets           = ide_floppy_proc_devsets,
-#endif
-};
-
-static int ide_gd_open(struct inode *inode, struct file *filp)
-{
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ide_floppy_obj *idkp;
-       ide_drive_t *drive;
-       int ret = 0;
-
-       idkp = ide_disk_get(disk);
-       if (idkp == NULL)
-               return -ENXIO;
-
-       drive = idkp->drive;
-
-       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
-       idkp->openers++;
-
-       if (idkp->openers == 1) {
-               drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
-               /* Just in case */
-
-               if (ide_do_test_unit_ready(drive, disk))
-                       ide_do_start_stop(drive, disk, 1);
-
-               ret = ide_floppy_get_capacity(drive);
-
-               set_capacity(disk, ide_gd_capacity(drive));
-
-               if (ret && (filp->f_flags & O_NDELAY) == 0) {
-                   /*
-                    * Allow O_NDELAY to open a drive without a disk, or with an
-                    * unreadable disk, so that we can get the format capacity
-                    * of the drive or begin the format - Sam
-                    */
-                       ret = -EIO;
-                       goto out_put_idkp;
-               }
-
-               if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) {
-                       ret = -EROFS;
-                       goto out_put_idkp;
-               }
-
-               ide_set_media_lock(drive, disk, 1);
-               drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
-               check_disk_change(inode->i_bdev);
-       } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
-               ret = -EBUSY;
-               goto out_put_idkp;
-       }
-       return 0;
-
-out_put_idkp:
-       idkp->openers--;
-       ide_disk_put(idkp);
-       return ret;
-}
-
-static int ide_gd_release(struct inode *inode, struct file *filp)
-{
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ide_floppy_obj *idkp = ide_drv_g(disk, ide_floppy_obj);
-       ide_drive_t *drive = idkp->drive;
-
-       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
-       if (idkp->openers == 1) {
-               ide_set_media_lock(drive, disk, 0);
-               drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
-       }
-
-       idkp->openers--;
-
-       ide_disk_put(idkp);
-
-       return 0;
-}
-
-static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
-       struct ide_floppy_obj *idkp = ide_drv_g(bdev->bd_disk, ide_floppy_obj);
-       ide_drive_t *drive = idkp->drive;
-
-       geo->heads = drive->bios_head;
-       geo->sectors = drive->bios_sect;
-       geo->cylinders = (u16)drive->bios_cyl; /* truncate */
-       return 0;
-}
-
-static int ide_gd_media_changed(struct gendisk *disk)
-{
-       struct ide_floppy_obj *idkp = ide_drv_g(disk, ide_floppy_obj);
-       ide_drive_t *drive = idkp->drive;
-       int ret;
-
-       /* do not scan partitions twice if this is a removable device */
-       if (drive->dev_flags & IDE_DFLAG_ATTACH) {
-               drive->dev_flags &= ~IDE_DFLAG_ATTACH;
-               return 0;
-       }
-
-       ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED);
-       drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
-
-       return ret;
-}
-
-static int ide_gd_revalidate_disk(struct gendisk *disk)
-{
-       struct ide_floppy_obj *idkp = ide_drv_g(disk, ide_floppy_obj);
-       set_capacity(disk, ide_gd_capacity(idkp->drive));
-       return 0;
-}
-
-static struct block_device_operations ide_gd_ops = {
-       .owner                  = THIS_MODULE,
-       .open                   = ide_gd_open,
-       .release                = ide_gd_release,
-       .ioctl                  = ide_floppy_ioctl,
-       .getgeo                 = ide_gd_getgeo,
-       .media_changed          = ide_gd_media_changed,
-       .revalidate_disk        = ide_gd_revalidate_disk
-};
-
-static int ide_gd_probe(ide_drive_t *drive)
-{
-       struct ide_floppy_obj *idkp;
-       struct gendisk *g;
-
-       if (!strstr("ide-floppy", drive->driver_req))
-               goto failed;
-
-       if (drive->media != ide_floppy)
-               goto failed;
-
-       if (!ide_check_atapi_device(drive, DRV_NAME)) {
-               printk(KERN_ERR PFX "%s: not supported by this version of "
-                      DRV_NAME "\n", drive->name);
-               goto failed;
-       }
-       idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
-       if (!idkp) {
-               printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n",
-                      drive->name);
-               goto failed;
-       }
-
-       g = alloc_disk_node(1 << PARTN_BITS, hwif_to_node(drive->hwif));
-       if (!g)
-               goto out_free_idkp;
-
-       ide_init_disk(g, drive);
-
-       kref_init(&idkp->kref);
-
-       idkp->drive = drive;
-       idkp->driver = &ide_gd_driver;
-       idkp->disk = g;
-
-       g->private_data = &idkp->driver;
-
-       drive->driver_data = idkp;
-
-       drive->debug_mask = debug_mask;
-
-       ide_floppy_setup(drive);
-
-       set_capacity(g, ide_gd_capacity(drive));
-
-       g->minors = 1 << PARTN_BITS;
-       g->driverfs_dev = &drive->gendev;
-       if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
-               g->flags = GENHD_FL_REMOVABLE;
-       g->fops = &ide_gd_ops;
-       add_disk(g);
-       return 0;
-
-out_free_idkp:
-       kfree(idkp);
-failed:
-       return -ENODEV;
-}
-
-static int __init ide_gd_init(void)
-{
-       printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n");
-       return driver_register(&ide_gd_driver.gen_driver);
-}
-
-static void __exit ide_gd_exit(void)
-{
-       driver_unregister(&ide_gd_driver.gen_driver);
-}
-
-MODULE_ALIAS("ide:*m-floppy*");
-MODULE_ALIAS("ide-floppy");
-module_init(ide_gd_init);
-module_exit(ide_gd_exit);
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
index a3d4ad7db2af54fcec26d649705e2a615852c7b2..d44898f46c330ccd33da5a231f2af8426b1b20df 100644 (file)
 #endif
 
 #include "ide-disk.h"
 #endif
 
 #include "ide-disk.h"
+#include "ide-floppy.h"
 
 #define IDE_GD_VERSION "1.18"
 
 
 #define IDE_GD_VERSION "1.18"
 
+/* module parameters */
+static unsigned long debug_mask;
+module_param(debug_mask, ulong, 0644);
+
 static DEFINE_MUTEX(ide_disk_ref_mutex);
 
 static void ide_disk_release(struct kref *);
 static DEFINE_MUTEX(ide_disk_ref_mutex);
 
 static void ide_disk_release(struct kref *);
@@ -64,7 +69,7 @@ static void ide_gd_remove(ide_drive_t *drive)
 
        del_gendisk(g);
 
 
        del_gendisk(g);
 
-       ide_disk_flush(drive);
+       drive->disk_ops->flush(drive);
 
        ide_disk_put(idkp);
 }
 
        ide_disk_put(idkp);
 }
@@ -75,6 +80,7 @@ static void ide_disk_release(struct kref *kref)
        ide_drive_t *drive = idkp->drive;
        struct gendisk *g = idkp->disk;
 
        ide_drive_t *drive = idkp->drive;
        struct gendisk *g = idkp->disk;
 
+       drive->disk_ops = NULL;
        drive->driver_data = NULL;
        g->private_data = NULL;
        put_disk(g);
        drive->driver_data = NULL;
        g->private_data = NULL;
        put_disk(g);
@@ -89,7 +95,7 @@ static void ide_disk_release(struct kref *kref)
 static void ide_gd_resume(ide_drive_t *drive)
 {
        if (ata_id_hpa_enabled(drive->id))
 static void ide_gd_resume(ide_drive_t *drive)
 {
        if (ata_id_hpa_enabled(drive->id))
-               ide_disk_init_capacity(drive);
+               (void)drive->disk_ops->get_capacity(drive);
 }
 
 static void ide_gd_shutdown(ide_drive_t *drive)
 }
 
 static void ide_gd_shutdown(ide_drive_t *drive)
@@ -110,7 +116,7 @@ static void ide_gd_shutdown(ide_drive_t *drive)
 #else
        if (system_state == SYSTEM_RESTART) {
 #endif
 #else
        if (system_state == SYSTEM_RESTART) {
 #endif
-               ide_disk_flush(drive);
+               drive->disk_ops->flush(drive);
                return;
        }
 
                return;
        }
 
@@ -122,19 +128,31 @@ static void ide_gd_shutdown(ide_drive_t *drive)
 #ifdef CONFIG_IDE_PROC_FS
 static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
 {
 #ifdef CONFIG_IDE_PROC_FS
 static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
 {
-       return ide_disk_proc;
+       return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc;
 }
 
 static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
 {
 }
 
 static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
 {
-       return ide_disk_settings;
+       return (drive->media == ide_disk) ? ide_disk_settings
+                                         : ide_floppy_settings;
 }
 #endif
 
 }
 #endif
 
+static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
+                                        struct request *rq, sector_t sector)
+{
+       return drive->disk_ops->do_request(drive, rq, sector);
+}
+
+static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs)
+{
+       return drive->disk_ops->end_request(drive, uptodate, nrsecs);
+}
+
 static ide_driver_t ide_gd_driver = {
        .gen_driver = {
                .owner          = THIS_MODULE,
 static ide_driver_t ide_gd_driver = {
        .gen_driver = {
                .owner          = THIS_MODULE,
-               .name           = "ide-disk",
+               .name           = "ide-gd",
                .bus            = &ide_bus_type,
        },
        .probe                  = ide_gd_probe,
                .bus            = &ide_bus_type,
        },
        .probe                  = ide_gd_probe,
@@ -142,8 +160,8 @@ static ide_driver_t ide_gd_driver = {
        .resume                 = ide_gd_resume,
        .shutdown               = ide_gd_shutdown,
        .version                = IDE_GD_VERSION,
        .resume                 = ide_gd_resume,
        .shutdown               = ide_gd_shutdown,
        .version                = IDE_GD_VERSION,
-       .do_request             = ide_do_rw_disk,
-       .end_request            = ide_end_request,
+       .do_request             = ide_gd_do_request,
+       .end_request            = ide_gd_end_request,
        .error                  = __ide_error,
 #ifdef CONFIG_IDE_PROC_FS
        .proc_entries           = ide_disk_proc_entries,
        .error                  = __ide_error,
 #ifdef CONFIG_IDE_PROC_FS
        .proc_entries           = ide_disk_proc_entries,
@@ -156,6 +174,7 @@ static int ide_gd_open(struct inode *inode, struct file *filp)
        struct gendisk *disk = inode->i_bdev->bd_disk;
        struct ide_disk_obj *idkp;
        ide_drive_t *drive;
        struct gendisk *disk = inode->i_bdev->bd_disk;
        struct ide_disk_obj *idkp;
        ide_drive_t *drive;
+       int ret = 0;
 
        idkp = ide_disk_get(disk);
        if (idkp == NULL)
 
        idkp = ide_disk_get(disk);
        if (idkp == NULL)
@@ -163,19 +182,49 @@ static int ide_gd_open(struct inode *inode, struct file *filp)
 
        drive = idkp->drive;
 
 
        drive = idkp->drive;
 
+       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+
        idkp->openers++;
 
        if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
        idkp->openers++;
 
        if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
+               drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
+               /* Just in case */
+
+               ret = drive->disk_ops->init_media(drive, disk);
+
+               /*
+                * Allow O_NDELAY to open a drive without a disk, or with an
+                * unreadable disk, so that we can get the format capacity
+                * of the drive or begin the format - Sam
+                */
+               if (ret && (filp->f_flags & O_NDELAY) == 0) {
+                       ret = -EIO;
+                       goto out_put_idkp;
+               }
+
+               if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) {
+                       ret = -EROFS;
+                       goto out_put_idkp;
+               }
+
                /*
                 * Ignore the return code from door_lock,
                 * since the open() has already succeeded,
                 * and the door_lock is irrelevant at this point.
                 */
                /*
                 * Ignore the return code from door_lock,
                 * since the open() has already succeeded,
                 * and the door_lock is irrelevant at this point.
                 */
-               ide_disk_set_doorlock(drive, 1);
+               drive->disk_ops->set_doorlock(drive, disk, 1);
                drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
                check_disk_change(inode->i_bdev);
                drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
                check_disk_change(inode->i_bdev);
+       } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
+               ret = -EBUSY;
+               goto out_put_idkp;
        }
        return 0;
        }
        return 0;
+
+out_put_idkp:
+       idkp->openers--;
+       ide_disk_put(idkp);
+       return ret;
 }
 
 static int ide_gd_release(struct inode *inode, struct file *filp)
 }
 
 static 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)
        struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
        ide_drive_t *drive = idkp->drive;
 
        struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
        ide_drive_t *drive = idkp->drive;
 
+       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+
        if (idkp->openers == 1)
        if (idkp->openers == 1)
-               ide_disk_flush(drive);
+               drive->disk_ops->flush(drive);
 
 
-       if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1)
-               ide_disk_set_doorlock(drive, 0);
+       if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
+               drive->disk_ops->set_doorlock(drive, disk, 0);
+               drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
+       }
 
        idkp->openers--;
 
 
        idkp->openers--;
 
@@ -233,11 +286,21 @@ static int ide_gd_revalidate_disk(struct gendisk *disk)
        return 0;
 }
 
        return 0;
 }
 
+static int ide_gd_ioctl(struct inode *inode, struct file *file,
+                            unsigned int cmd, unsigned long arg)
+{
+       struct block_device *bdev = inode->i_bdev;
+       struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
+       ide_drive_t *drive = idkp->drive;
+
+       return drive->disk_ops->ioctl(drive, inode, file, cmd, arg);
+}
+
 static struct block_device_operations ide_gd_ops = {
        .owner                  = THIS_MODULE,
        .open                   = ide_gd_open,
        .release                = ide_gd_release,
 static struct block_device_operations ide_gd_ops = {
        .owner                  = THIS_MODULE,
        .open                   = ide_gd_open,
        .release                = ide_gd_release,
-       .ioctl                  = ide_disk_ioctl,
+       .ioctl                  = ide_gd_ioctl,
        .getgeo                 = ide_gd_getgeo,
        .media_changed          = ide_gd_media_changed,
        .revalidate_disk        = ide_gd_revalidate_disk
        .getgeo                 = ide_gd_getgeo,
        .media_changed          = ide_gd_media_changed,
        .revalidate_disk        = ide_gd_revalidate_disk
@@ -245,19 +308,37 @@ static struct block_device_operations ide_gd_ops = {
 
 static int ide_gd_probe(ide_drive_t *drive)
 {
 
 static int ide_gd_probe(ide_drive_t *drive)
 {
+       const struct ide_disk_ops *disk_ops = NULL;
        struct ide_disk_obj *idkp;
        struct gendisk *g;
 
        /* strstr("foo", "") is non-NULL */
        struct ide_disk_obj *idkp;
        struct gendisk *g;
 
        /* strstr("foo", "") is non-NULL */
-       if (!strstr("ide-disk", drive->driver_req))
+       if (!strstr("ide-gd", drive->driver_req))
+               goto failed;
+
+#ifdef CONFIG_IDE_GD_ATA
+       if (drive->media == ide_disk)
+               disk_ops = &ide_ata_disk_ops;
+#endif
+#ifdef CONFIG_IDE_GD_ATAPI
+       if (drive->media == ide_floppy)
+               disk_ops = &ide_atapi_disk_ops;
+#endif
+       if (disk_ops == NULL)
                goto failed;
 
                goto failed;
 
-       if (drive->media != ide_disk)
+       if (disk_ops->check(drive, DRV_NAME) == 0) {
+               printk(KERN_ERR PFX "%s: not supported by this driver\n",
+                       drive->name);
                goto failed;
                goto failed;
+       }
 
        idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
 
        idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
-       if (!idkp)
+       if (!idkp) {
+               printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
+                       drive->name);
                goto failed;
                goto failed;
+       }
 
        g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
        if (!g)
 
        g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
        if (!g)
@@ -274,8 +355,10 @@ static int ide_gd_probe(ide_drive_t *drive)
        g->private_data = &idkp->driver;
 
        drive->driver_data = idkp;
        g->private_data = &idkp->driver;
 
        drive->driver_data = idkp;
+       drive->debug_mask = debug_mask;
+       drive->disk_ops = disk_ops;
 
 
-       ide_disk_setup(drive);
+       disk_ops->setup(drive);
 
        set_capacity(g, ide_gd_capacity(drive));
 
 
        set_capacity(g, ide_gd_capacity(drive));
 
@@ -296,6 +379,7 @@ failed:
 
 static int __init ide_gd_init(void)
 {
 
 static int __init ide_gd_init(void)
 {
+       printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
        return driver_register(&ide_gd_driver.gen_driver);
 }
 
        return driver_register(&ide_gd_driver.gen_driver);
 }
 
@@ -306,7 +390,9 @@ static void __exit ide_gd_exit(void)
 
 MODULE_ALIAS("ide:*m-disk*");
 MODULE_ALIAS("ide-disk");
 
 MODULE_ALIAS("ide:*m-disk*");
 MODULE_ALIAS("ide-disk");
+MODULE_ALIAS("ide:*m-floppy*");
+MODULE_ALIAS("ide-floppy");
 module_init(ide_gd_init);
 module_exit(ide_gd_exit);
 MODULE_LICENSE("GPL");
 module_init(ide_gd_init);
 module_exit(ide_gd_exit);
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ATA DISK Driver");
+MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h
new file mode 100644 (file)
index 0000000..7d3d101
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __IDE_GD_H
+#define __IDE_GD_H
+
+#define DRV_NAME "ide-gd"
+#define PFX DRV_NAME ": "
+
+/* define to see debug info */
+#define IDE_GD_DEBUG_LOG       0
+
+#if IDE_GD_DEBUG_LOG
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#else
+#define ide_debug_log(lvl, fmt, args...) do {} while (0)
+#endif
+
+struct ide_disk_obj {
+       ide_drive_t     *drive;
+       ide_driver_t    *driver;
+       struct gendisk  *disk;
+       struct kref     kref;
+       unsigned int    openers;        /* protected by BKL for now */
+
+       /* Last failed packet command */
+       struct ide_atapi_pc *failed_pc;
+       /* used for blk_{fs,pc}_request() requests */
+       struct ide_atapi_pc queued_pc;
+
+       /* Last error information */
+       u8 sense_key, asc, ascq;
+
+       int progress_indication;
+
+       /* Device information */
+       /* Current format */
+       int blocks, block_size, bs_factor;
+       /* Last format capacity descriptor */
+       u8 cap_desc[8];
+       /* Copy of the flexible disk page */
+       u8 flexible_disk_page[32];
+};
+
+sector_t ide_gd_capacity(ide_drive_t *);
+
+#endif /* __IDE_GD_H */
index e3e40427e00e8f9081d1a5326785c021727cb158..c7ff1e11ea853c11dc70b25079f9ccc8b943280a 100644 (file)
@@ -179,7 +179,7 @@ config LEDS_TRIGGER_TIMER
 
 config LEDS_TRIGGER_IDE_DISK
        bool "LED IDE Disk Trigger"
 
 config LEDS_TRIGGER_IDE_DISK
        bool "LED IDE Disk Trigger"
-       depends on LEDS_TRIGGERS && BLK_DEV_IDEDISK
+       depends on LEDS_TRIGGERS && IDE_GD_ATA
        help
          This allows LEDs to be controlled by IDE disk activity.
          If unsure, say Y.
        help
          This allows LEDs to be controlled by IDE disk activity.
          If unsure, say Y.
index 488808891acbe6f614ca02653506d2fb0697b7e7..89e53cfbc787fdcb60635764ce9bae5d48239287 100644 (file)
@@ -461,6 +461,23 @@ struct ide_acpi_drive_link;
 struct ide_acpi_hwif_link;
 #endif
 
 struct ide_acpi_hwif_link;
 #endif
 
+struct ide_drive_s;
+
+struct ide_disk_ops {
+       int             (*check)(struct ide_drive_s *, const char *);
+       int             (*get_capacity)(struct ide_drive_s *);
+       void            (*setup)(struct ide_drive_s *);
+       void            (*flush)(struct ide_drive_s *);
+       int             (*init_media)(struct ide_drive_s *, struct gendisk *);
+       int             (*set_doorlock)(struct ide_drive_s *, struct gendisk *,
+                                       int);
+       ide_startstop_t (*do_request)(struct ide_drive_s *, struct request *,
+                                     sector_t);
+       int             (*end_request)(struct ide_drive_s *, int, int);
+       int             (*ioctl)(struct ide_drive_s *, struct inode *,
+                                struct file *, unsigned int, unsigned long);
+};
+
 /* ATAPI device flags */
 enum {
        IDE_AFLAG_DRQ_INTERRUPT         = (1 << 0),
 /* ATAPI device flags */
 enum {
        IDE_AFLAG_DRQ_INTERRUPT         = (1 << 0),
@@ -594,6 +611,8 @@ struct ide_drive_s {
 #endif
        struct hwif_s           *hwif;  /* actually (ide_hwif_t *) */
 
 #endif
        struct hwif_s           *hwif;  /* actually (ide_hwif_t *) */
 
+       const struct ide_disk_ops *disk_ops;
+
        unsigned long dev_flags;
 
        unsigned long sleep;            /* sleep until this time */
        unsigned long dev_flags;
 
        unsigned long sleep;            /* sleep until this time */