rapide: remove write-only hwif->hwif_data
[safe/jmp/linux-2.6] / drivers / ide / ide-floppy.c
index 07fa37d..ff8232e 100644 (file)
@@ -99,6 +99,8 @@
 #include <linux/bitops.h>
 #include <linux/mutex.h>
 
+#include <scsi/scsi_ioctl.h>
+
 #include <asm/byteorder.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
@@ -279,6 +281,7 @@ typedef struct ide_floppy_obj {
        ide_driver_t    *driver;
        struct gendisk  *disk;
        struct kref     kref;
+       unsigned int    openers;        /* protected by BKL for now */
 
        /* Current packet command */
        idefloppy_pc_t *pc;
@@ -366,27 +369,6 @@ typedef struct ide_floppy_obj {
 #define        IDEFLOPPY_IOCTL_FORMAT_START            0x4602
 #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS    0x4603
 
-#if 0
-/*
- *     Special requests for our block device strategy routine.
- */
-#define        IDEFLOPPY_FIRST_RQ      90
-
-/*
- *     IDEFLOPPY_PC_RQ is used to queue a packet command in the request queue.
- */
-#define        IDEFLOPPY_PC_RQ         90
-
-#define IDEFLOPPY_LAST_RQ      90
-
-/*
- *     A macro which can be used to check if a given request command
- *     originated in the driver or in the buffer cache layer.
- */
-#define IDEFLOPPY_RQ_CMD(cmd)  ((cmd >= IDEFLOPPY_FIRST_RQ) && (cmd <= IDEFLOPPY_LAST_RQ))
-
-#endif
-
 /*
  *     Error codes which are returned in rq->errors to the higher part
  *     of the driver.
@@ -603,26 +585,24 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns
 {
        struct request *rq = pc->rq;
        struct bio_vec *bvec;
-       struct bio *bio;
+       struct req_iterator iter;
        unsigned long flags;
        char *data;
-       int count, i, done = 0;
+       int count, done = 0;
 
-       rq_for_each_bio(bio, rq) {
-               bio_for_each_segment(bvec, bio, i) {
-                       if (!bcount)
-                               break;
+       rq_for_each_segment(bvec, rq, iter) {
+               if (!bcount)
+                       break;
 
-                       count = min(bvec->bv_len, bcount);
+               count = min(bvec->bv_len, bcount);
 
-                       data = bvec_kmap_irq(bvec, &flags);
-                       drive->hwif->atapi_input_bytes(drive, data, count);
-                       bvec_kunmap_irq(data, &flags);
+               data = bvec_kmap_irq(bvec, &flags);
+               drive->hwif->atapi_input_bytes(drive, data, count);
+               bvec_kunmap_irq(data, &flags);
 
-                       bcount -= count;
-                       pc->b_count += count;
-                       done += count;
-               }
+               bcount -= count;
+               pc->b_count += count;
+               done += count;
        }
 
        idefloppy_do_end_request(drive, 1, done >> 9);
@@ -636,27 +616,25 @@ static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, uns
 static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
 {
        struct request *rq = pc->rq;
-       struct bio *bio;
+       struct req_iterator iter;
        struct bio_vec *bvec;
        unsigned long flags;
-       int count, i, done = 0;
+       int count, done = 0;
        char *data;
 
-       rq_for_each_bio(bio, rq) {
-               bio_for_each_segment(bvec, bio, i) {
-                       if (!bcount)
-                               break;
+       rq_for_each_segment(bvec, rq, iter) {
+               if (!bcount)
+                       break;
 
-                       count = min(bvec->bv_len, bcount);
+               count = min(bvec->bv_len, bcount);
 
-                       data = bvec_kmap_irq(bvec, &flags);
-                       drive->hwif->atapi_output_bytes(drive, data, count);
-                       bvec_kunmap_irq(data, &flags);
+               data = bvec_kmap_irq(bvec, &flags);
+               drive->hwif->atapi_output_bytes(drive, data, count);
+               bvec_kunmap_irq(data, &flags);
 
-                       bcount -= count;
-                       pc->b_count += count;
-                       done += count;
-               }
+               bcount -= count;
+               pc->b_count += count;
+               done += count;
        }
 
        idefloppy_do_end_request(drive, 1, done >> 9);
@@ -794,9 +772,8 @@ static void idefloppy_retry_pc (ide_drive_t *drive)
 {
        idefloppy_pc_t *pc;
        struct request *rq;
-       atapi_error_t error;
 
-       error.all = HWIF(drive)->INB(IDE_ERROR_REG);
+       (void)drive->hwif->INB(IDE_ERROR_REG);
        pc = idefloppy_next_pc_storage(drive);
        rq = idefloppy_next_rq_storage(drive);
        idefloppy_create_request_sense_cmd(pc);
@@ -810,12 +787,12 @@ static void idefloppy_retry_pc (ide_drive_t *drive)
 static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
-       atapi_status_t status;
-       atapi_bcount_t bcount;
-       atapi_ireason_t ireason;
+       ide_hwif_t *hwif = drive->hwif;
        idefloppy_pc_t *pc = floppy->pc;
        struct request *rq = pc->rq;
        unsigned int temp;
+       u16 bcount;
+       u8 stat, ireason;
 
        debug_log(KERN_INFO "ide-floppy: Reached %s interrupt handler\n",
                __FUNCTION__);
@@ -831,16 +808,16 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
        }
 
        /* Clear the interrupt */
-       status.all = HWIF(drive)->INB(IDE_STATUS_REG);
+       stat = drive->hwif->INB(IDE_STATUS_REG);
 
-       if (!status.b.drq) {                    /* No more interrupts */
+       if ((stat & DRQ_STAT) == 0) {           /* No more interrupts */
                debug_log(KERN_INFO "Packet command completed, %d bytes "
                        "transferred\n", pc->actually_transferred);
                clear_bit(PC_DMA_IN_PROGRESS, &pc->flags);
 
                local_irq_enable_in_hardirq();
 
-               if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) {
+               if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) {
                        /* Error detected */
                        debug_log(KERN_INFO "ide-floppy: %s: I/O error\n",
                                drive->name);
@@ -866,37 +843,37 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
        if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
                printk(KERN_ERR "ide-floppy: The floppy wants to issue "
                        "more interrupts in DMA mode\n");
-               (void)__ide_dma_off(drive);
+               ide_dma_off(drive);
                return ide_do_reset(drive);
        }
 
        /* Get the number of bytes to transfer */
-       bcount.b.high = HWIF(drive)->INB(IDE_BCOUNTH_REG);
-       bcount.b.low = HWIF(drive)->INB(IDE_BCOUNTL_REG);
+       bcount = (hwif->INB(IDE_BCOUNTH_REG) << 8) |
+                 hwif->INB(IDE_BCOUNTL_REG);
        /* on this interrupt */
-       ireason.all = HWIF(drive)->INB(IDE_IREASON_REG);
+       ireason = hwif->INB(IDE_IREASON_REG);
 
-       if (ireason.b.cod) {
+       if (ireason & CD) {
                printk(KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n");
                return ide_do_reset(drive);
        }
-       if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) {
+       if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) {
                /* Hopefully, we will never get here */
                printk(KERN_ERR "ide-floppy: We wanted to %s, ",
-                       ireason.b.io ? "Write":"Read");
+                               (ireason & IO) ? "Write" : "Read");
                printk(KERN_ERR "but the floppy wants us to %s !\n",
-                       ireason.b.io ? "Read":"Write");
+                               (ireason & IO) ? "Read" : "Write");
                return ide_do_reset(drive);
        }
        if (!test_bit(PC_WRITING, &pc->flags)) {
                /* Reading - Check that we have enough space */
-               temp = pc->actually_transferred + bcount.all;
+               temp = pc->actually_transferred + bcount;
                if (temp > pc->request_transfer) {
                        if (temp > pc->buffer_size) {
                                printk(KERN_ERR "ide-floppy: The floppy wants "
                                        "to send us more data than expected "
                                        "- discarding data\n");
-                               idefloppy_discard_data(drive,bcount.all);
+                               idefloppy_discard_data(drive, bcount);
                                BUG_ON(HWGROUP(drive)->handler != NULL);
                                ide_set_handler(drive,
                                                &idefloppy_pc_intr,
@@ -912,23 +889,21 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
        if (test_bit(PC_WRITING, &pc->flags)) {
                if (pc->buffer != NULL)
                        /* Write the current buffer */
-                       HWIF(drive)->atapi_output_bytes(drive,
-                                               pc->current_position,
-                                               bcount.all);
+                       hwif->atapi_output_bytes(drive, pc->current_position,
+                                                bcount);
                else
-                       idefloppy_output_buffers(drive, pc, bcount.all);
+                       idefloppy_output_buffers(drive, pc, bcount);
        } else {
                if (pc->buffer != NULL)
                        /* Read the current buffer */
-                       HWIF(drive)->atapi_input_bytes(drive,
-                                               pc->current_position,
-                                               bcount.all);
+                       hwif->atapi_input_bytes(drive, pc->current_position,
+                                               bcount);
                else
-                       idefloppy_input_buffers(drive, pc, bcount.all);
+                       idefloppy_input_buffers(drive, pc, bcount);
        }
        /* Update the current position */
-       pc->actually_transferred += bcount.all;
-       pc->current_position += bcount.all;
+       pc->actually_transferred += bcount;
+       pc->current_position += bcount;
 
        BUG_ON(HWGROUP(drive)->handler != NULL);
        ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);           /* And set the interrupt handler again */
@@ -944,15 +919,15 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive)
 {
        ide_startstop_t startstop;
        idefloppy_floppy_t *floppy = drive->driver_data;
-       atapi_ireason_t ireason;
+       u8 ireason;
 
        if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
                printk(KERN_ERR "ide-floppy: Strange, packet command "
                                "initiated yet DRQ isn't asserted\n");
                return startstop;
        }
-       ireason.all = HWIF(drive)->INB(IDE_IREASON_REG);
-       if (!ireason.b.cod || ireason.b.io) {
+       ireason = drive->hwif->INB(IDE_IREASON_REG);
+       if ((ireason & CD) == 0 || (ireason & IO)) {
                printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while "
                                "issuing a packet command\n");
                return ide_do_reset(drive);
@@ -992,15 +967,15 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive)
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
        ide_startstop_t startstop;
-       atapi_ireason_t ireason;
+       u8 ireason;
 
        if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
                printk(KERN_ERR "ide-floppy: Strange, packet command "
                                "initiated yet DRQ isn't asserted\n");
                return startstop;
        }
-       ireason.all = HWIF(drive)->INB(IDE_IREASON_REG);
-       if (!ireason.b.cod || ireason.b.io) {
+       ireason = drive->hwif->INB(IDE_IREASON_REG);
+       if ((ireason & CD) == 0 || (ireason & IO)) {
                printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) "
                                "while issuing a packet command\n");
                return ide_do_reset(drive);
@@ -1042,21 +1017,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
        ide_hwif_t *hwif = drive->hwif;
-       atapi_feature_t feature;
-       atapi_bcount_t bcount;
        ide_handler_t *pkt_xfer_routine;
-
-#if 0 /* Accessing floppy->pc is not valid here, the previous pc may be gone
-         and have lived on another thread's stack; that stack may have become
-         unmapped meanwhile (CONFIG_DEBUG_PAGEALLOC). */
-#if IDEFLOPPY_DEBUG_BUGS
-       if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD &&
-           pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
-               printk(KERN_ERR "ide-floppy: possible ide-floppy.c bug - "
-                       "Two request sense in serial were issued\n");
-       }
-#endif /* IDEFLOPPY_DEBUG_BUGS */
-#endif
+       u16 bcount;
+       u8 dma;
 
        if (floppy->failed_pc == NULL &&
            pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD)
@@ -1094,25 +1057,20 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
        /* We haven't transferred any data yet */
        pc->actually_transferred = 0;
        pc->current_position = pc->buffer;
-       bcount.all = min(pc->request_transfer, 63 * 1024);
+       bcount = min(pc->request_transfer, 63 * 1024);
 
-       if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
-               (void)__ide_dma_off(drive);
-       }
-       feature.all = 0;
+       if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags))
+               ide_dma_off(drive);
+
+       dma = 0;
 
        if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
-               feature.b.dma = !hwif->dma_setup(drive);
+               dma = !hwif->dma_setup(drive);
 
-       if (IDE_CONTROL_REG)
-               HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
-       /* Use PIO/DMA */
-       HWIF(drive)->OUTB(feature.all, IDE_FEATURE_REG);
-       HWIF(drive)->OUTB(bcount.b.high, IDE_BCOUNTH_REG);
-       HWIF(drive)->OUTB(bcount.b.low, IDE_BCOUNTL_REG);
-       HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG);
+       ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK |
+                          IDE_TFLAG_OUT_DEVICE, bcount, dma);
 
-       if (feature.b.dma) {    /* Begin DMA, if necessary */
+       if (dma) {      /* Begin DMA, if necessary */
                set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
                hwif->dma_start(drive);
        }
@@ -1257,19 +1215,25 @@ static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t
        set_bit(PC_DMA_RECOMMENDED, &pc->flags);
 }
 
-static int
+static void
 idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq)
 {
-       /*
-        * just support eject for now, it would not be hard to make the
-        * REQ_BLOCK_PC support fully-featured
-        */
-       if (rq->cmd[0] != IDEFLOPPY_START_STOP_CMD)
-               return 1;
-
        idefloppy_init_pc(pc);
+       pc->callback = &idefloppy_rw_callback;
        memcpy(pc->c, rq->cmd, sizeof(pc->c));
-       return 0;
+       pc->rq = rq;
+       pc->b_count = rq->data_len;
+       if (rq->data_len && rq_data_dir(rq) == WRITE)
+               set_bit(PC_WRITING, &pc->flags);
+       pc->buffer = rq->data;
+       if (rq->bio)
+               set_bit(PC_DMA_RECOMMENDED, &pc->flags);
+               
+       /*
+        * possibly problematic, doesn't look like ide-floppy correctly
+        * handled scattered requests if dma fails...
+        */
+       pc->request_transfer = pc->buffer_size = rq->data_len;
 }
 
 /*
@@ -1316,10 +1280,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
                pc = (idefloppy_pc_t *) rq->buffer;
        } else if (blk_pc_request(rq)) {
                pc = idefloppy_next_pc_storage(drive);
-               if (idefloppy_blockpc_cmd(floppy, pc, rq)) {
-                       idefloppy_do_end_request(drive, 0, 0);
-                       return ide_stopped;
-               }
+               idefloppy_blockpc_cmd(floppy, pc, rq);
        } else {
                blk_dump_rq_flags(rq,
                        "ide-floppy: unsupported command in queue");
@@ -1663,14 +1624,14 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
                /* Else assume format_unit has finished, and we're
                ** at 0x10000 */
        } else {
-               atapi_status_t status;
                unsigned long flags;
+               u8 stat;
 
                local_irq_save(flags);
-               status.all = HWIF(drive)->INB(IDE_STATUS_REG);
+               stat = drive->hwif->INB(IDE_STATUS_REG);
                local_irq_restore(flags);
 
-               progress_indication = !status.b.dsc ? 0 : 0x10000;
+               progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000;
        }
        if (put_user(progress_indication, arg))
                return (-EFAULT);
@@ -1810,18 +1771,22 @@ static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id)
        return 0;
 }
 
+#ifdef CONFIG_IDE_PROC_FS
 static void idefloppy_add_settings(ide_drive_t *drive)
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
 
 /*
- *                     drive   setting name    read/write      ioctl   ioctl           data type       min     max     mul_factor      div_factor      data pointer            set function
+ *                     drive   setting name    read/write      data type       min     max     mul_factor      div_factor      data pointer            set function
  */
-       ide_add_setting(drive,  "bios_cyl",             SETTING_RW,                                     -1,                     -1,                     TYPE_INT,       0,      1023,                           1,      1,      &drive->bios_cyl,               NULL);
-       ide_add_setting(drive,  "bios_head",            SETTING_RW,                                     -1,                     -1,                     TYPE_BYTE,      0,      255,                            1,      1,      &drive->bios_head,              NULL);
-       ide_add_setting(drive,  "bios_sect",            SETTING_RW,                                     -1,                     -1,                     TYPE_BYTE,      0,      63,                             1,      1,      &drive->bios_sect,              NULL);
-       ide_add_setting(drive,  "ticks",                SETTING_RW,                                     -1,                     -1,                     TYPE_BYTE,      0,      255,                            1,      1,      &floppy->ticks,         NULL);
+       ide_add_setting(drive,  "bios_cyl",     SETTING_RW,     TYPE_INT,       0,      1023,           1,              1,      &drive->bios_cyl,       NULL);
+       ide_add_setting(drive,  "bios_head",    SETTING_RW,     TYPE_BYTE,      0,      255,            1,              1,      &drive->bios_head,      NULL);
+       ide_add_setting(drive,  "bios_sect",    SETTING_RW,     TYPE_BYTE,      0,      63,             1,              1,      &drive->bios_sect,      NULL);
+       ide_add_setting(drive,  "ticks",        SETTING_RW,     TYPE_BYTE,      0,      255,            1,              1,      &floppy->ticks,         NULL);
 }
+#else
+static inline void idefloppy_add_settings(ide_drive_t *drive) { ; }
+#endif
 
 /*
  *     Driver initialization.
@@ -1872,7 +1837,7 @@ static void ide_floppy_remove(ide_drive_t *drive)
        idefloppy_floppy_t *floppy = drive->driver_data;
        struct gendisk *g = floppy->disk;
 
-       ide_unregister_subdriver(drive, floppy->driver);
+       ide_proc_unregister_driver(drive, floppy->driver);
 
        del_gendisk(g);
 
@@ -1891,8 +1856,7 @@ static void ide_floppy_release(struct kref *kref)
        kfree(floppy);
 }
 
-#ifdef CONFIG_PROC_FS
-
+#ifdef CONFIG_IDE_PROC_FS
 static int proc_idefloppy_read_capacity
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
@@ -1908,12 +1872,7 @@ static ide_proc_entry_t idefloppy_proc[] = {
        { "geometry",   S_IFREG|S_IRUGO,        proc_ide_read_geometry, NULL },
        { NULL, 0, NULL, NULL }
 };
-
-#else
-
-#define        idefloppy_proc  NULL
-
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_IDE_PROC_FS */
 
 static int ide_floppy_probe(ide_drive_t *);
 
@@ -1932,7 +1891,9 @@ static ide_driver_t idefloppy_driver = {
        .end_request            = idefloppy_do_end_request,
        .error                  = __ide_error,
        .abort                  = __ide_abort,
+#ifdef CONFIG_IDE_PROC_FS
        .proc                   = idefloppy_proc,
+#endif
 };
 
 static int idefloppy_open(struct inode *inode, struct file *filp)
@@ -1950,9 +1911,9 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
 
        drive = floppy->drive;
 
-       drive->usage++;
+       floppy->openers++;
 
-       if (drive->usage == 1) {
+       if (floppy->openers == 1) {
                clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
                /* Just in case */
 
@@ -1970,13 +1931,11 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
                    ** capacity of the drive or begin the format - Sam
                    */
                    ) {
-                       drive->usage--;
                        ret = -EIO;
                        goto out_put_floppy;
                }
 
                if (floppy->wp && (filp->f_mode & 2)) {
-                       drive->usage--;
                        ret = -EROFS;
                        goto out_put_floppy;
                }
@@ -1988,13 +1947,13 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
                }
                check_disk_change(inode->i_bdev);
        } else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) {
-               drive->usage--;
                ret = -EBUSY;
                goto out_put_floppy;
        }
        return 0;
 
 out_put_floppy:
+       floppy->openers--;
        ide_floppy_put(floppy);
        return ret;
 }
@@ -2008,7 +1967,7 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
        
        debug_log(KERN_INFO "Reached idefloppy_release\n");
 
-       if (drive->usage == 1) {
+       if (floppy->openers == 1) {
                /* IOMEGA Clik! drives do not support lock/unlock commands */
                 if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
                        idefloppy_create_prevent_cmd(&pc, 0);
@@ -2017,7 +1976,8 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
 
                clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
        }
-       drive->usage--;
+
+       floppy->openers--;
 
        ide_floppy_put(floppy);
 
@@ -2051,7 +2011,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
                prevent = 0;
                /* fall through */
        case CDROM_LOCKDOOR:
-               if (drive->usage > 1)
+               if (floppy->openers > 1)
                        return -EBUSY;
 
                /* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
@@ -2073,7 +2033,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
                if (!(file->f_mode & 2))
                        return -EPERM;
 
-               if (drive->usage > 1) {
+               if (floppy->openers > 1) {
                        /* Don't format if someone is using the disk */
 
                        clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,
@@ -2096,7 +2056,21 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
        case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
                return idefloppy_get_format_progress(drive, argp);
        }
-       return generic_ide_ioctl(drive, file, bdev, cmd, arg);
+
+       /*
+        * skip SCSI_IOCTL_SEND_COMMAND (deprecated)
+        * and CDROM_SEND_PACKET (legacy) ioctls
+        */
+       if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND)
+               err = scsi_cmd_ioctl(file, bdev->bd_disk->queue,
+                                       bdev->bd_disk, cmd, argp);
+       else
+               err = -ENOTTY;
+
+       if (err == -ENOTTY)
+               err = generic_ide_ioctl(drive, file, bdev, cmd, arg);
+
+       return err;
 }
 
 static int idefloppy_media_changed(struct gendisk *disk)
@@ -2159,7 +2133,7 @@ static int ide_floppy_probe(ide_drive_t *drive)
 
        ide_init_disk(g, drive);
 
-       ide_register_subdriver(drive, &idefloppy_driver);
+       ide_proc_register_driver(drive, &idefloppy_driver);
 
        kref_init(&floppy->kref);