Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Jan 2009 18:32:18 +0000 (10:32 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Jan 2009 18:32:18 +0000 (10:32 -0800)
* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (32 commits)
  ide-atapi: start dma in a drive-specific way
  ide-atapi: put the rest of non-ide-cd code into the else-clause of ide_transfer_pc
  ide-atapi: remove timeout arg to ide_issue_pc
  ide-cd: remove handler wrappers
  ide-cd: remove xferlen arg to cdrom_start_packet_command
  ide-atapi: split drive-specific functionality in ide_issue_pc
  ide-atapi: assign expiry and timeout based on device type
  ide-atapi: compute cmd_len based on device type in ide_transfer_pc
  ide: remove the last ide-scsi remnants
  ide-atapi: remove ide-scsi remnants from ide_pc_intr()
  ide-atapi: remove ide-scsi remnants from ide_transfer_pc()
  ide-atapi: remove ide-scsi remnants from ide_issue_pc
  ide-cd: move cdrom_timer_expiry to ide-atapi.c
  ide-atapi: teach ide atapi about drive->waiting_for_dma
  ide-atapi: accomodate transfer length calculation for ide-cd
  ide-atapi: setup dma for ide-cd
  ide-atapi: combine drive-specific assignments
  ide-atapi: add a dev_is_idecd-inline
  remove ide-scsi
  ide-floppy: allocate only toplevel packet commands
  ...

22 files changed:
Documentation/feature-removal-schedule.txt
MAINTAINERS
drivers/ide/Kconfig
drivers/ide/Makefile
drivers/ide/ide-atapi.c
drivers/ide/ide-cd.c
drivers/ide/ide-cd.h
drivers/ide/ide-floppy.c
drivers/ide/ide-floppy_ioctl.c
drivers/ide/ide-io.c
drivers/ide/ide-ioctls.c
drivers/ide/ide-park.c
drivers/ide/ide-probe.c
drivers/ide/ide-sysfs.c [new file with mode: 0644]
drivers/ide/ide-tape.c
drivers/ide/ide.c
drivers/ide/tx4938ide.c
drivers/ide/tx4939ide.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/ide-scsi.c [deleted file]
include/linux/ide.h

index dc7c681e532cacf9fbf9ec0f692e9fb2bd5740e7..df18d87c483796907378586f9b3d11955323b140 100644 (file)
@@ -310,15 +310,6 @@ Who:  Krzysztof Piotr Oledzki <ole@ans.pl>
 
 ---------------------------
 
-What: ide-scsi (BLK_DEV_IDESCSI)
-When: 2.6.29
-Why:  The 2.6 kernel supports direct writing to ide CD drives, which
-      eliminates the need for ide-scsi. The new method is more
-      efficient in every way.
-Who:  FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-
----------------------------
-
 What:  i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
 When:  2.6.29 (ideally) or 2.6.30 (more likely)
 Why:   Deprecated by the new (standard) device driver binding model. Use
index 3148de29afa752e66d2a09d686a31cff3757e62d..88f43e09aeb33c4791d420be54efe2b731d6ffe0 100644 (file)
@@ -2152,11 +2152,6 @@ M:       Gadi Oxman <gadio@netvision.net.il>
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
-IDE-SCSI DRIVER
-L:     linux-ide@vger.kernel.org
-L:     linux-scsi@vger.kernel.org
-S:     Orphan
-
 IDLE-I7300
 P:     Andy Henroid
 M:     andrew.d.henroid@intel.com
index c9f21e3d4ead835c2065e60e4b9cfec28d47a258..4ee85fcf9aaf024acff74aa94d48d1f8e5e94fcb 100644 (file)
@@ -137,6 +137,7 @@ config BLK_DEV_DELKIN
 
 config BLK_DEV_IDECD
        tristate "Include IDE/ATAPI CDROM support"
+       select IDE_ATAPI
        ---help---
          If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is
          a newer protocol used by IDE CD-ROM and TAPE drives, similar to the
@@ -185,23 +186,6 @@ config BLK_DEV_IDETAPE
          To compile this driver as a module, choose M here: the
          module will be called ide-tape.
 
-config BLK_DEV_IDESCSI
-       tristate "SCSI emulation support (DEPRECATED)"
-       depends on SCSI
-       select IDE_ATAPI
-       ---help---
-         WARNING: ide-scsi is no longer needed for cd writing applications!
-         The 2.6 kernel supports direct writing to ide-cd, which eliminates
-         the need for ide-scsi + the entire scsi stack just for writing a
-         cd. The new method is more efficient in every way.
-
-         This will provide SCSI host adapter emulation for IDE ATAPI devices,
-         and will allow you to use a SCSI device driver instead of a native
-         ATAPI driver.
-
-         If both this SCSI emulation and native ATAPI support are compiled
-         into the kernel, the native support will be used.
-
 config BLK_DEV_IDEACPI
        bool "IDE ACPI support"
        depends on ACPI
index 177e3f8523edd2fb16c106d21ecd5848f44fd1fe..410728992e6a65d72b1c4e946d7b91487481953b 100644 (file)
@@ -5,7 +5,7 @@
 EXTRA_CFLAGS                           += -Idrivers/ide
 
 ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
-             ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o
+             ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o
 
 # core IDE code
 ide-core-$(CONFIG_IDE_TIMINGS)         += ide-timings.o
index 4e58b9e7a58a01592eb3e130aee781a41e4891d1..e8688c0f8645858707bc439b3ec4f42dc252b153 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/cdrom.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
 #include <scsi/scsi.h>
 #define debug_log(fmt, args...) do {} while (0)
 #endif
 
+#define ATAPI_MIN_CDB_BYTES    12
+
+static inline int dev_is_idecd(ide_drive_t *drive)
+{
+       return drive->media == ide_cdrom || drive->media == ide_optical;
+}
+
 /*
  * Check whether we can support a device,
  * based on the ATAPI IDENTIFY command results.
@@ -233,18 +241,49 @@ void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk)
 }
 EXPORT_SYMBOL_GPL(ide_retry_pc);
 
-int ide_scsi_expiry(ide_drive_t *drive)
+int ide_cd_expiry(ide_drive_t *drive)
 {
-       struct ide_atapi_pc *pc = drive->pc;
+       struct request *rq = HWGROUP(drive)->rq;
+       unsigned long wait = 0;
 
-       debug_log("%s called for %lu at %lu\n", __func__,
-                 pc->scsi_cmd->serial_number, jiffies);
+       debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]);
 
-       pc->flags |= PC_FLAG_TIMEDOUT;
+       /*
+        * Some commands are *slow* and normally take a long time to complete.
+        * Usually we can use the ATAPI "disconnect" to bypass this, but not all
+        * commands/drives support that. Let ide_timer_expiry keep polling us
+        * for these.
+        */
+       switch (rq->cmd[0]) {
+       case GPCMD_BLANK:
+       case GPCMD_FORMAT_UNIT:
+       case GPCMD_RESERVE_RZONE_TRACK:
+       case GPCMD_CLOSE_TRACK:
+       case GPCMD_FLUSH_CACHE:
+               wait = ATAPI_WAIT_PC;
+               break;
+       default:
+               if (!(rq->cmd_flags & REQ_QUIET))
+                       printk(KERN_INFO "cmd 0x%x timed out\n",
+                                        rq->cmd[0]);
+               wait = 0;
+               break;
+       }
+       return wait;
+}
+EXPORT_SYMBOL_GPL(ide_cd_expiry);
 
-       return 0; /* we do not want the IDE subsystem to retry */
+int ide_cd_get_xferlen(struct request *rq)
+{
+       if (blk_fs_request(rq))
+               return 32768;
+       else if (blk_sense_request(rq) || blk_pc_request(rq) ||
+                        rq->cmd_type == REQ_TYPE_ATA_PC)
+               return rq->data_len;
+       else
+               return 0;
 }
-EXPORT_SYMBOL_GPL(ide_scsi_expiry);
+EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
 
 /*
  * This is the usual interrupt handler which will be called during a packet
@@ -258,21 +297,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
        struct request *rq = hwif->hwgroup->rq;
        const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        xfer_func_t *xferfunc;
-       ide_expiry_t *expiry;
        unsigned int timeout, temp;
        u16 bcount;
-       u8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0;
+       u8 stat, ireason, dsc = 0;
 
        debug_log("Enter %s - interrupt handler\n", __func__);
 
-       if (scsi) {
-               timeout = ide_scsi_get_timeout(pc);
-               expiry = ide_scsi_expiry;
-       } else {
-               timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
-                                                      : WAIT_TAPE_CMD;
-               expiry = NULL;
-       }
+       timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
+                                              : WAIT_TAPE_CMD;
 
        if (pc->flags & PC_FLAG_TIMEDOUT) {
                drive->pc_callback(drive, 0);
@@ -284,8 +316,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
 
        if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
                if (hwif->dma_ops->dma_end(drive) ||
-                   (drive->media == ide_tape && !scsi && (stat & ATA_ERR))) {
-                       if (drive->media == ide_floppy && !scsi)
+                   (drive->media == ide_tape && (stat & ATA_ERR))) {
+                       if (drive->media == ide_floppy)
                                printk(KERN_ERR "%s: DMA %s error\n",
                                        drive->name, rq_data_dir(pc->rq)
                                                     ? "write" : "read");
@@ -307,7 +339,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
 
                local_irq_enable_in_hardirq();
 
-               if (drive->media == ide_tape && !scsi &&
+               if (drive->media == ide_tape &&
                    (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE)
                        stat &= ~ATA_ERR;
 
@@ -315,11 +347,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
                        /* Error detected */
                        debug_log("%s: I/O error\n", drive->name);
 
-                       if (drive->media != ide_tape || scsi) {
+                       if (drive->media != ide_tape)
                                pc->rq->errors++;
-                               if (scsi)
-                                       goto cmd_finished;
-                       }
 
                        if (rq->cmd[0] == REQUEST_SENSE) {
                                printk(KERN_ERR "%s: I/O error in request sense"
@@ -335,7 +364,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
                        /* queued, but not started */
                        return ide_stopped;
                }
-cmd_finished:
                pc->error = 0;
 
                if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
@@ -382,25 +410,8 @@ cmd_finished:
                                                "us more data than expected - "
                                                "discarding data\n",
                                                drive->name);
-                               if (scsi)
-                                       temp = pc->buf_size - pc->xferred;
-                               else
-                                       temp = 0;
-                               if (temp) {
-                                       if (pc->sg)
-                                               drive->pc_io_buffers(drive, pc,
-                                                                    temp, 0);
-                                       else
-                                               tp_ops->input_data(drive, NULL,
-                                                       pc->cur_pos, temp);
-                                       printk(KERN_ERR "%s: transferred %d of "
-                                                       "%d bytes\n",
-                                                       drive->name,
-                                                       temp, bcount);
-                               }
-                               pc->xferred += temp;
-                               pc->cur_pos += temp;
-                               ide_pad_transfer(drive, 0, bcount - temp);
+
+                               ide_pad_transfer(drive, 0, bcount);
                                goto next_irq;
                        }
                        debug_log("The device wants to send us more data than "
@@ -410,14 +421,13 @@ cmd_finished:
        } else
                xferfunc = tp_ops->output_data;
 
-       if ((drive->media == ide_floppy && !scsi && !pc->buf) ||
-           (drive->media == ide_tape && !scsi && pc->bh) ||
-           (scsi && pc->sg)) {
+       if ((drive->media == ide_floppy && !pc->buf) ||
+           (drive->media == ide_tape && pc->bh)) {
                int done = drive->pc_io_buffers(drive, pc, bcount,
                                  !!(pc->flags & PC_FLAG_WRITING));
 
                /* FIXME: don't do partial completions */
-               if (drive->media == ide_floppy && !scsi)
+               if (drive->media == ide_floppy)
                        ide_end_request(drive, 1, done >> 9);
        } else
                xferfunc(drive, NULL, pc->cur_pos, bcount);
@@ -430,7 +440,7 @@ cmd_finished:
                  rq->cmd[0], bcount);
 next_irq:
        /* And set the interrupt handler again */
-       ide_set_handler(drive, ide_pc_intr, timeout, expiry);
+       ide_set_handler(drive, ide_pc_intr, timeout, NULL);
        return ide_started;
 }
 
@@ -479,11 +489,12 @@ static int ide_delayed_transfer_pc(ide_drive_t *drive)
 
 static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
 {
-       struct ide_atapi_pc *pc = drive->pc;
+       struct ide_atapi_pc *uninitialized_var(pc);
        ide_hwif_t *hwif = drive->hwif;
        struct request *rq = hwif->hwgroup->rq;
        ide_expiry_t *expiry;
        unsigned int timeout;
+       int cmd_len;
        ide_startstop_t startstop;
        u8 ireason;
 
@@ -493,101 +504,124 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
                return startstop;
        }
 
-       ireason = ide_read_ireason(drive);
-       if (drive->media == ide_tape &&
-           (drive->dev_flags & IDE_DFLAG_SCSI) == 0)
-               ireason = ide_wait_ireason(drive, ireason);
-
-       if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {
-               printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
-                               "a packet command\n", drive->name);
-               return ide_do_reset(drive);
+       if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
+               if (drive->dma)
+                       drive->waiting_for_dma = 1;
        }
 
-       /*
-        * If necessary schedule the packet transfer to occur 'timeout'
-        * miliseconds later in ide_delayed_transfer_pc() after the device
-        * says it's ready for a packet.
-        */
-       if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
-               timeout = drive->pc_delay;
-               expiry = &ide_delayed_transfer_pc;
+       if (dev_is_idecd(drive)) {
+               /* ATAPI commands get padded out to 12 bytes minimum */
+               cmd_len = COMMAND_SIZE(rq->cmd[0]);
+               if (cmd_len < ATAPI_MIN_CDB_BYTES)
+                       cmd_len = ATAPI_MIN_CDB_BYTES;
+
+               timeout = rq->timeout;
+               expiry  = ide_cd_expiry;
        } else {
-               if (drive->dev_flags & IDE_DFLAG_SCSI) {
-                       timeout = ide_scsi_get_timeout(pc);
-                       expiry = ide_scsi_expiry;
+               pc = drive->pc;
+
+               cmd_len = ATAPI_MIN_CDB_BYTES;
+
+               /*
+                * If necessary schedule the packet transfer to occur 'timeout'
+                * miliseconds later in ide_delayed_transfer_pc() after the
+                * device says it's ready for a packet.
+                */
+               if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
+                       timeout = drive->pc_delay;
+                       expiry = &ide_delayed_transfer_pc;
                } else {
                        timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
                                                               : WAIT_TAPE_CMD;
                        expiry = NULL;
                }
+
+               ireason = ide_read_ireason(drive);
+               if (drive->media == ide_tape)
+                       ireason = ide_wait_ireason(drive, ireason);
+
+               if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {
+                       printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
+                                       "a packet command\n", drive->name);
+
+                       return ide_do_reset(drive);
+               }
        }
 
        /* Set the interrupt routine */
        ide_set_handler(drive, ide_pc_intr, timeout, expiry);
 
        /* Begin DMA, if necessary */
-       if (pc->flags & PC_FLAG_DMA_OK) {
-               pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
-               hwif->dma_ops->dma_start(drive);
+       if (dev_is_idecd(drive)) {
+               if (drive->dma)
+                       hwif->dma_ops->dma_start(drive);
+       } else {
+               if (pc->flags & PC_FLAG_DMA_OK) {
+                       pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
+                       hwif->dma_ops->dma_start(drive);
+               }
        }
 
        /* Send the actual packet */
        if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
-               hwif->tp_ops->output_data(drive, NULL, rq->cmd, 12);
+               hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
 
        return ide_started;
 }
 
-ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,
-                            ide_expiry_t *expiry)
+ide_startstop_t ide_issue_pc(ide_drive_t *drive)
 {
-       struct ide_atapi_pc *pc = drive->pc;
+       struct ide_atapi_pc *pc;
        ide_hwif_t *hwif = drive->hwif;
+       ide_expiry_t *expiry = NULL;
+       unsigned int timeout;
        u32 tf_flags;
        u16 bcount;
-       u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI);
 
-       /* We haven't transferred any data yet */
-       pc->xferred = 0;
-       pc->cur_pos = pc->buf;
+       if (dev_is_idecd(drive)) {
+               tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
+               bcount = ide_cd_get_xferlen(hwif->hwgroup->rq);
+               expiry = ide_cd_expiry;
+               timeout = ATAPI_WAIT_PC;
 
-       /* Request to transfer the entire buffer at once */
-       if (drive->media == ide_tape && scsi == 0)
-               bcount = pc->req_xfer;
-       else
-               bcount = min(pc->req_xfer, 63 * 1024);
+               if (drive->dma)
+                       drive->dma = !hwif->dma_ops->dma_setup(drive);
+       } else {
+               pc = drive->pc;
 
-       if (pc->flags & PC_FLAG_DMA_ERROR) {
-               pc->flags &= ~PC_FLAG_DMA_ERROR;
-               ide_dma_off(drive);
-       }
+               /* We haven't transferred any data yet */
+               pc->xferred = 0;
+               pc->cur_pos = pc->buf;
 
-       if ((pc->flags & PC_FLAG_DMA_OK) &&
-           (drive->dev_flags & IDE_DFLAG_USING_DMA)) {
-               if (scsi)
-                       hwif->sg_mapped = 1;
-               drive->dma = !hwif->dma_ops->dma_setup(drive);
-               if (scsi)
-                       hwif->sg_mapped = 0;
-       }
+               tf_flags = IDE_TFLAG_OUT_DEVICE;
+               bcount = ((drive->media == ide_tape) ?
+                               pc->req_xfer :
+                               min(pc->req_xfer, 63 * 1024));
 
-       if (!drive->dma)
-               pc->flags &= ~PC_FLAG_DMA_OK;
+               if (pc->flags & PC_FLAG_DMA_ERROR) {
+                       pc->flags &= ~PC_FLAG_DMA_ERROR;
+                       ide_dma_off(drive);
+               }
 
-       if (scsi)
-               tf_flags = 0;
-       else if (drive->media == ide_cdrom || drive->media == ide_optical)
-               tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
-       else
-               tf_flags = IDE_TFLAG_OUT_DEVICE;
+               if ((pc->flags & PC_FLAG_DMA_OK) &&
+                    (drive->dev_flags & IDE_DFLAG_USING_DMA))
+                       drive->dma = !hwif->dma_ops->dma_setup(drive);
+
+               if (!drive->dma)
+                       pc->flags &= ~PC_FLAG_DMA_OK;
+
+               timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
+                                                      : WAIT_TAPE_CMD;
+       }
 
        ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);
 
        /* Issue the packet command */
        if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
+               if (drive->dma)
+                       drive->waiting_for_dma = 0;
                ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
-                                   timeout, NULL);
+                                   timeout, expiry);
                return ide_started;
        } else {
                ide_execute_pkt_cmd(drive);
index 5daa4dd1b018a51e8b7dc73067edea997230a9e7..1a7410f882494907b3568d0263c917a0af73d2fa 100644 (file)
 
 #include "ide-cd.h"
 
-#define IDECD_DEBUG_LOG                1
-
-#if IDECD_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
-
 static DEFINE_MUTEX(idecd_ref_mutex);
 
 static void ide_cd_release(struct kref *);
@@ -519,37 +511,8 @@ end_request:
        return 1;
 }
 
-static int cdrom_timer_expiry(ide_drive_t *drive)
-{
-       struct request *rq = HWGROUP(drive)->rq;
-       unsigned long wait = 0;
-
-       ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd[0]: 0x%x\n", __func__,
-                     rq->cmd[0]);
-
-       /*
-        * Some commands are *slow* and normally take a long time to complete.
-        * Usually we can use the ATAPI "disconnect" to bypass this, but not all
-        * commands/drives support that. Let ide_timer_expiry keep polling us
-        * for these.
-        */
-       switch (rq->cmd[0]) {
-       case GPCMD_BLANK:
-       case GPCMD_FORMAT_UNIT:
-       case GPCMD_RESERVE_RZONE_TRACK:
-       case GPCMD_CLOSE_TRACK:
-       case GPCMD_FLUSH_CACHE:
-               wait = ATAPI_WAIT_PC;
-               break;
-       default:
-               if (!(rq->cmd_flags & REQ_QUIET))
-                       printk(KERN_INFO PFX "cmd 0x%x timed out\n",
-                                        rq->cmd[0]);
-               wait = 0;
-               break;
-       }
-       return wait;
-}
+static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *);
+static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
 
 /*
  * Set up the device registers for transferring a packet command on DEV,
@@ -559,11 +522,13 @@ static int cdrom_timer_expiry(ide_drive_t *drive)
  * called when the interrupt from the drive arrives.  Otherwise, HANDLER
  * will be called immediately after the drive is prepared for the transfer.
  */
-static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
-                                                 int xferlen,
-                                                 ide_handler_t *handler)
+static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
+       struct request *rq = hwif->hwgroup->rq;
+       int xferlen;
+
+       xferlen = ide_cd_get_xferlen(rq);
 
        ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen);
 
@@ -581,13 +546,14 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
                        drive->waiting_for_dma = 0;
 
                /* packet command */
-               ide_execute_command(drive, ATA_CMD_PACKET, handler,
-                                   ATAPI_WAIT_PC, cdrom_timer_expiry);
+               ide_execute_command(drive, ATA_CMD_PACKET,
+                                   cdrom_transfer_packet_command,
+                                   ATAPI_WAIT_PC, ide_cd_expiry);
                return ide_started;
        } else {
                ide_execute_pkt_cmd(drive);
 
-               return (*handler) (drive);
+               return cdrom_transfer_packet_command(drive);
        }
 }
 
@@ -598,11 +564,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
  * there's data ready.
  */
 #define ATAPI_MIN_CDB_BYTES 12
-static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
-                                         struct request *rq,
-                                         ide_handler_t *handler)
+static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
+       struct request *rq = hwif->hwgroup->rq;
        int cmd_len;
        ide_startstop_t startstop;
 
@@ -629,7 +594,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
        }
 
        /* arm the interrupt handler */
-       ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
+       ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, ide_cd_expiry);
 
        /* ATAPI commands get padded out to 12 bytes minimum */
        cmd_len = COMMAND_SIZE(rq->cmd[0]);
@@ -717,8 +682,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
        return 1;
 }
 
-static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
-
 static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
                                                 struct request *rq)
 {
@@ -760,20 +723,6 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
        return ide_started;
 }
 
-/*
- * Routine to send a read/write packet command to the drive. This is usually
- * called directly from cdrom_start_{read,write}(). However, for drq_interrupt
- * devices, it is called from an interrupt when the drive is ready to accept
- * the command.
- */
-static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
-{
-       struct request *rq = drive->hwif->hwgroup->rq;
-
-       /* send the command to the drive and return */
-       return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
-}
-
 /*
  * Fix up a possibly partially-processed request so that we can start it over
  * entirely, or even put it back on the request queue.
@@ -1096,7 +1045,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
        } else {
                timeout = ATAPI_WAIT_PC;
                if (!blk_fs_request(rq))
-                       expiry = cdrom_timer_expiry;
+                       expiry = ide_cd_expiry;
        }
 
        ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry);
@@ -1163,13 +1112,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
        return ide_started;
 }
 
-static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
-{
-       struct request *rq = HWGROUP(drive)->rq;
-
-       return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
-}
-
 static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 {
 
@@ -1214,18 +1156,12 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
                                        sector_t block)
 {
-       ide_handler_t *fn;
-       int xferlen;
-
        ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, "
                      "rq->cmd_type: 0x%x, block: %llu\n",
                      __func__, rq->cmd[0], rq->cmd_type,
                      (unsigned long long)block);
 
        if (blk_fs_request(rq)) {
-               xferlen = 32768;
-               fn = cdrom_start_rw_cont;
-
                if (cdrom_start_rw(drive, rq) == ide_stopped)
                        return ide_stopped;
 
@@ -1233,9 +1169,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
                        return ide_stopped;
        } else if (blk_sense_request(rq) || blk_pc_request(rq) ||
                   rq->cmd_type == REQ_TYPE_ATA_PC) {
-               xferlen = rq->data_len;
-               fn = cdrom_do_newpc_cont;
-
                if (!rq->timeout)
                        rq->timeout = ATAPI_WAIT_PC;
 
@@ -1250,7 +1183,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
                return ide_stopped;
        }
 
-       return cdrom_start_packet_command(drive, xferlen, fn);
+       return cdrom_start_packet_command(drive);
 }
 
 /*
index d5ce3362dbd144ab3c871f10a4378a2f4a17d6d0..bf676b26218129eca95bab9d676e8229e0e1fa0b 100644 (file)
@@ -8,10 +8,14 @@
 #include <linux/cdrom.h>
 #include <asm/byteorder.h>
 
-/*
- * typical timeout for packet command
- */
-#define ATAPI_WAIT_PC          (60 * HZ)
+#define IDECD_DEBUG_LOG                0
+
+#if IDECD_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
+
 #define ATAPI_WAIT_WRITE_BUSY  (10 * HZ)
 
 /************************************************************************/
index aeb1ad782f54e5fbc9d39d3cda3e6eeabfc1bef4..0a48e2dc53a281c2e7757ade400c700c02df609c 100644 (file)
@@ -197,7 +197,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
 
        pc->retries++;
 
-       return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL);
+       return ide_issue_pc(drive);
 }
 
 void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
@@ -342,38 +342,38 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
  * Look at the flexible disk page parameters. We ignore the CHS capacity
  * parameters and use the LBA parameters instead.
  */
-static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
+static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive,
+                                            struct ide_atapi_pc *pc)
 {
        struct ide_disk_obj *floppy = drive->driver_data;
        struct gendisk *disk = floppy->disk;
-       struct ide_atapi_pc pc;
        u8 *page;
        int capacity, lba_capacity;
        u16 transfer_rate, sector_size, cyls, rpm;
        u8 heads, sectors;
 
-       ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);
+       ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);
 
-       if (ide_queue_pc_tail(drive, disk, &pc)) {
+       if (ide_queue_pc_tail(drive, disk, pc)) {
                printk(KERN_ERR PFX "Can't get flexible disk page params\n");
                return 1;
        }
 
-       if (pc.buf[3] & 0x80)
+       if (pc->buf[3] & 0x80)
                drive->dev_flags |= IDE_DFLAG_WP;
        else
                drive->dev_flags &= ~IDE_DFLAG_WP;
 
        set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP));
 
-       page = &pc.buf[8];
+       page = &pc->buf[8];
 
-       transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]);
-       sector_size   = be16_to_cpup((__be16 *)&pc.buf[8 + 6]);
-       cyls          = be16_to_cpup((__be16 *)&pc.buf[8 + 8]);
-       rpm           = be16_to_cpup((__be16 *)&pc.buf[8 + 28]);
-       heads         = pc.buf[8 + 4];
-       sectors       = pc.buf[8 + 5];
+       transfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]);
+       sector_size   = be16_to_cpup((__be16 *)&pc->buf[8 + 6]);
+       cyls          = be16_to_cpup((__be16 *)&pc->buf[8 + 8]);
+       rpm           = be16_to_cpup((__be16 *)&pc->buf[8 + 28]);
+       heads         = pc->buf[8 + 4];
+       sectors       = pc->buf[8 + 5];
 
        capacity = cyls * heads * sectors * sector_size;
 
@@ -499,7 +499,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
 
        /* Clik! disk does not support get_flexible_disk_page */
        if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))
-               (void) ide_floppy_get_flexible_disk_page(drive);
+               (void) ide_floppy_get_flexible_disk_page(drive, &pc);
 
        return rc;
 }
index 2bc51ff73fee35b3863aea03b7dc6e6bf09bfc9c..8f8be8546038d5950d5e944e26871fc7f0186a49 100644 (file)
  * On exit we set nformats to the number of records we've actually initialized.
  */
 
-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,
+                                           struct ide_atapi_pc *pc,
+                                           int __user *arg)
 {
        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;
        int __user *argp;
@@ -45,13 +46,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
        if (u_array_size <= 0)
                return -EINVAL;
 
-       ide_floppy_create_read_capacity_cmd(&pc);
-       if (ide_queue_pc_tail(drive, floppy->disk, &pc)) {
+       ide_floppy_create_read_capacity_cmd(pc);
+       if (ide_queue_pc_tail(drive, floppy->disk, pc)) {
                printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
                return -EIO;
        }
 
-       header_len = pc.buf[3];
+       header_len = pc->buf[3];
        desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */
 
        u_index = 0;
@@ -68,8 +69,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
                if (u_index >= u_array_size)
                        break;  /* User-supplied buffer too small */
 
-               blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);
-               length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
+               blocks = be32_to_cpup((__be32 *)&pc->buf[desc_start]);
+               length = be16_to_cpup((__be16 *)&pc->buf[desc_start + 6]);
 
                if (put_user(blocks, argp))
                        return -EFAULT;
@@ -111,29 +112,28 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b,
        pc->flags |= PC_FLAG_WRITING;
 }
 
-static int ide_floppy_get_sfrp_bit(ide_drive_t *drive)
+static int ide_floppy_get_sfrp_bit(ide_drive_t *drive, struct ide_atapi_pc *pc)
 {
        struct ide_disk_obj *floppy = drive->driver_data;
-       struct ide_atapi_pc pc;
 
        drive->atapi_flags &= ~IDE_AFLAG_SRFP;
 
-       ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE);
-       pc.flags |= PC_FLAG_SUPPRESS_ERROR;
+       ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_CAPABILITIES_PAGE);
+       pc->flags |= PC_FLAG_SUPPRESS_ERROR;
 
-       if (ide_queue_pc_tail(drive, floppy->disk, &pc))
+       if (ide_queue_pc_tail(drive, floppy->disk, pc))
                return 1;
 
-       if (pc.buf[8 + 2] & 0x40)
+       if (pc->buf[8 + 2] & 0x40)
                drive->atapi_flags |= IDE_AFLAG_SRFP;
 
        return 0;
 }
 
-static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)
+static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,
+                                 int __user *arg)
 {
        struct ide_disk_obj *floppy = drive->driver_data;
-       struct ide_atapi_pc pc;
        int blocks, length, flags, err = 0;
 
        if (floppy->openers > 1) {
@@ -166,10 +166,10 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)
                goto out;
        }
 
-       (void)ide_floppy_get_sfrp_bit(drive);
-       ide_floppy_create_format_unit_cmd(&pc, blocks, length, flags);
+       ide_floppy_get_sfrp_bit(drive, pc);
+       ide_floppy_create_format_unit_cmd(pc, blocks, length, flags);
 
-       if (ide_queue_pc_tail(drive, floppy->disk, &pc))
+       if (ide_queue_pc_tail(drive, floppy->disk, pc))
                err = -EIO;
 
 out:
@@ -188,15 +188,16 @@ out:
  * the dsc bit, and return either 0 or 65536.
  */
 
-static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg)
+static int ide_floppy_get_format_progress(ide_drive_t *drive,
+                                         struct ide_atapi_pc *pc,
+                                         int __user *arg)
 {
        struct ide_disk_obj *floppy = drive->driver_data;
-       struct ide_atapi_pc pc;
        int progress_indication = 0x10000;
 
        if (drive->atapi_flags & IDE_AFLAG_SRFP) {
-               ide_create_request_sense_cmd(drive, &pc);
-               if (ide_queue_pc_tail(drive, floppy->disk, &pc))
+               ide_create_request_sense_cmd(drive, pc);
+               if (ide_queue_pc_tail(drive, floppy->disk, pc))
                        return -EIO;
 
                if (floppy->sense_key == 2 &&
@@ -241,20 +242,21 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc,
        return 0;
 }
 
-static int ide_floppy_format_ioctl(ide_drive_t *drive, fmode_t mode,
-                                  unsigned int cmd, void __user *argp)
+static int ide_floppy_format_ioctl(ide_drive_t *drive, struct ide_atapi_pc *pc,
+                                  fmode_t mode, unsigned int cmd,
+                                  void __user *argp)
 {
        switch (cmd) {
        case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:
                return 0;
        case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
-               return ide_floppy_get_format_capacities(drive, argp);
+               return ide_floppy_get_format_capacities(drive, pc, argp);
        case IDEFLOPPY_IOCTL_FORMAT_START:
                if (!(mode & FMODE_WRITE))
                        return -EPERM;
-               return ide_floppy_format_unit(drive, (int __user *)argp);
+               return ide_floppy_format_unit(drive, pc, (int __user *)argp);
        case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
-               return ide_floppy_get_format_progress(drive, argp);
+               return ide_floppy_get_format_progress(drive, pc, argp);
        default:
                return -ENOTTY;
        }
@@ -270,7 +272,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,
        if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR)
                return ide_floppy_lockdoor(drive, &pc, arg, cmd);
 
-       err = ide_floppy_format_ioctl(drive, mode, cmd, argp);
+       err = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp);
        if (err != -ENOTTY)
                return err;
 
index ecacc008fdafec71175fddfc73199acb302f0110..1c36a8e83d36000b1585080093e40a28b6681963 100644 (file)
@@ -426,9 +426,6 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq)
        ide_hwif_t *hwif = drive->hwif;
        struct scatterlist *sg = hwif->sg_table;
 
-       if (hwif->sg_mapped)    /* needed by ide-scsi */
-               return;
-
        if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) {
                hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
        } else {
@@ -667,85 +664,10 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)
        drive->sleep = timeout + jiffies;
        drive->dev_flags |= IDE_DFLAG_SLEEPING;
 }
-
 EXPORT_SYMBOL(ide_stall_queue);
 
-#define WAKEUP(drive)  ((drive)->service_start + 2 * (drive)->service_time)
-
-/**
- *     choose_drive            -       select a drive to service
- *     @hwgroup: hardware group to select on
- *
- *     choose_drive() selects the next drive which will be serviced.
- *     This is necessary because the IDE layer can't issue commands
- *     to both drives on the same cable, unlike SCSI.
- */
-static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
-{
-       ide_drive_t *drive, *best;
-
-repeat:        
-       best = NULL;
-       drive = hwgroup->drive;
-
-       /*
-        * drive is doing pre-flush, ordered write, post-flush sequence. even
-        * though that is 3 requests, it must be seen as a single transaction.
-        * we must not preempt this drive until that is complete
-        */
-       if (blk_queue_flushing(drive->queue)) {
-               /*
-                * small race where queue could get replugged during
-                * the 3-request flush cycle, just yank the plug since
-                * we want it to finish asap
-                */
-               blk_remove_plug(drive->queue);
-               return drive;
-       }
-
-       do {
-               u8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING);
-               u8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING));
-
-               if ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) &&
-                   !elv_queue_empty(drive->queue)) {
-                       if (best == NULL ||
-                           (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) ||
-                           (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) {
-                               if (!blk_queue_plugged(drive->queue))
-                                       best = drive;
-                       }
-               }
-       } while ((drive = drive->next) != hwgroup->drive);
-
-       if (best && (best->dev_flags & IDE_DFLAG_NICE1) &&
-           (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 &&
-           best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
-               long t = (signed long)(WAKEUP(best) - jiffies);
-               if (t >= WAIT_MIN_SLEEP) {
-               /*
-                * We *may* have some time to spare, but first let's see if
-                * someone can potentially benefit from our nice mood today..
-                */
-                       drive = best->next;
-                       do {
-                               if ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0
-                                && time_before(jiffies - best->service_time, WAKEUP(drive))
-                                && time_before(WAKEUP(drive), jiffies + t))
-                               {
-                                       ide_stall_queue(best, min_t(long, t, 10 * WAIT_MIN_SLEEP));
-                                       goto repeat;
-                               }
-                       } while ((drive = drive->next) != best);
-               }
-       }
-       return best;
-}
-
 /*
  * Issue a new request to a drive from hwgroup
- * Caller must have already done spin_lock_irqsave(&hwgroup->lock, ..);
  *
  * A hwgroup is a serialized group of IDE interfaces.  Usually there is
  * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)
@@ -757,8 +679,7 @@ repeat:
  * possibly along with many other devices.  This is especially common in
  * PCI-based systems with off-board IDE controller cards.
  *
- * The IDE driver uses a per-hwgroup spinlock to protect
- * access to the request queues, and to protect the hwgroup->busy flag.
+ * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag.
  *
  * The first thread into the driver for a particular hwgroup sets the
  * hwgroup->busy flag to indicate that this hwgroup is now active,
@@ -778,69 +699,41 @@ repeat:
  * the driver.  This makes the driver much more friendlier to shared IRQs
  * than previous designs, while remaining 100% (?) SMP safe and capable.
  */
-static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
+void do_ide_request(struct request_queue *q)
 {
-       ide_drive_t     *drive;
-       ide_hwif_t      *hwif;
+       ide_drive_t     *drive = q->queuedata;
+       ide_hwif_t      *hwif = drive->hwif;
+       ide_hwgroup_t   *hwgroup = hwif->hwgroup;
        struct request  *rq;
        ide_startstop_t startstop;
-       int             loops = 0;
-
-       /* caller must own hwgroup->lock */
-       BUG_ON(!irqs_disabled());
-
-       while (!hwgroup->busy) {
-               hwgroup->busy = 1;
-               /* for atari only */
-               ide_get_lock(ide_intr, hwgroup);
-               drive = choose_drive(hwgroup);
-               if (drive == NULL) {
-                       int sleeping = 0;
-                       unsigned long sleep = 0; /* shut up, gcc */
-                       hwgroup->rq = NULL;
-                       drive = hwgroup->drive;
-                       do {
-                               if ((drive->dev_flags & IDE_DFLAG_SLEEPING) &&
-                                   (sleeping == 0 ||
-                                    time_before(drive->sleep, sleep))) {
-                                       sleeping = 1;
-                                       sleep = drive->sleep;
-                               }
-                       } while ((drive = drive->next) != hwgroup->drive);
-                       if (sleeping) {
+
+       /*
+        * drive is doing pre-flush, ordered write, post-flush sequence. even
+        * though that is 3 requests, it must be seen as a single transaction.
+        * we must not preempt this drive until that is complete
+        */
+       if (blk_queue_flushing(q))
                /*
-                * Take a short snooze, and then wake up this hwgroup again.
-                * This gives other hwgroups on the same a chance to
-                * play fairly with us, just in case there are big differences
-                * in relative throughputs.. don't want to hog the cpu too much.
+                * small race where queue could get replugged during
+                * the 3-request flush cycle, just yank the plug since
+                * we want it to finish asap
                 */
-                               if (time_before(sleep, jiffies + WAIT_MIN_SLEEP))
-                                       sleep = jiffies + WAIT_MIN_SLEEP;
-#if 1
-                               if (timer_pending(&hwgroup->timer))
-                                       printk(KERN_CRIT "ide_set_handler: timer already active\n");
-#endif
-                               /* so that ide_timer_expiry knows what to do */
-                               hwgroup->sleeping = 1;
-                               hwgroup->req_gen_timer = hwgroup->req_gen;
-                               mod_timer(&hwgroup->timer, sleep);
-                               /* we purposely leave hwgroup->busy==1
-                                * while sleeping */
-                       } else {
-                               /* Ugly, but how can we sleep for the lock
-                                * otherwise? perhaps from tq_disk?
-                                */
+               blk_remove_plug(q);
 
-                               /* for atari only */
-                               ide_release_lock();
-                               hwgroup->busy = 0;
-                       }
+       spin_unlock_irq(q->queue_lock);
+       spin_lock_irq(&hwgroup->lock);
+
+       if (!ide_lock_hwgroup(hwgroup)) {
+repeat:
+               hwgroup->rq = NULL;
 
-                       /* no more work for this hwgroup (for now) */
-                       return;
+               if (drive->dev_flags & IDE_DFLAG_SLEEPING) {
+                       if (time_before(drive->sleep, jiffies)) {
+                               ide_unlock_hwgroup(hwgroup);
+                               goto plug_device;
+                       }
                }
-       again:
-               hwif = HWIF(drive);
+
                if (hwif != hwgroup->hwif) {
                        /*
                         * set nIEN for previous hwif, drives in the
@@ -852,16 +745,20 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
                hwgroup->hwif = hwif;
                hwgroup->drive = drive;
                drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
-               drive->service_start = jiffies;
 
+               spin_unlock_irq(&hwgroup->lock);
+               spin_lock_irq(q->queue_lock);
                /*
                 * we know that the queue isn't empty, but this can happen
                 * if the q->prep_rq_fn() decides to kill a request
                 */
                rq = elv_next_request(drive->queue);
+               spin_unlock_irq(q->queue_lock);
+               spin_lock_irq(&hwgroup->lock);
+
                if (!rq) {
-                       hwgroup->busy = 0;
-                       break;
+                       ide_unlock_hwgroup(hwgroup);
+                       goto out;
                }
 
                /*
@@ -876,53 +773,36 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
                 * though. I hope that doesn't happen too much, hopefully not
                 * unless the subdriver triggers such a thing in its own PM
                 * state machine.
-                *
-                * We count how many times we loop here to make sure we service
-                * all drives in the hwgroup without looping for ever
                 */
                if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
                    blk_pm_request(rq) == 0 &&
                    (rq->cmd_flags & REQ_PREEMPT) == 0) {
-                       drive = drive->next ? drive->next : hwgroup->drive;
-                       if (loops++ < 4 && !blk_queue_plugged(drive->queue))
-                               goto again;
-                       /* We clear busy, there should be no pending ATA command at this point. */
-                       hwgroup->busy = 0;
-                       break;
+                       /* there should be no pending command at this point */
+                       ide_unlock_hwgroup(hwgroup);
+                       goto plug_device;
                }
 
                hwgroup->rq = rq;
 
-               /*
-                * Some systems have trouble with IDE IRQs arriving while
-                * the driver is still setting things up.  So, here we disable
-                * the IRQ used by this interface while the request is being started.
-                * This may look bad at first, but pretty much the same thing
-                * happens anyway when any interrupt comes in, IDE or otherwise
-                *  -- the kernel masks the IRQ while it is being handled.
-                */
-               if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)
-                       disable_irq_nosync(hwif->irq);
-               spin_unlock(&hwgroup->lock);
-               local_irq_enable_in_hardirq();
-                       /* allow other IRQs while we start this request */
+               spin_unlock_irq(&hwgroup->lock);
                startstop = start_request(drive, rq);
                spin_lock_irq(&hwgroup->lock);
-               if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)
-                       enable_irq(hwif->irq);
+
                if (startstop == ide_stopped)
-                       hwgroup->busy = 0;
-       }
-}
+                       goto repeat;
+       } else
+               goto plug_device;
+out:
+       spin_unlock_irq(&hwgroup->lock);
+       spin_lock_irq(q->queue_lock);
+       return;
 
-/*
- * Passes the stuff to ide_do_request
- */
-void do_ide_request(struct request_queue *q)
-{
-       ide_drive_t *drive = q->queuedata;
+plug_device:
+       spin_unlock_irq(&hwgroup->lock);
+       spin_lock_irq(q->queue_lock);
 
-       ide_do_request(HWGROUP(drive), IDE_NO_IRQ);
+       if (!elv_queue_empty(q))
+               blk_plug_device(q);
 }
 
 /*
@@ -983,6 +863,17 @@ out:
        return ret;
 }
 
+static void ide_plug_device(ide_drive_t *drive)
+{
+       struct request_queue *q = drive->queue;
+       unsigned long flags;
+
+       spin_lock_irqsave(q->queue_lock, flags);
+       if (!elv_queue_empty(q))
+               blk_plug_device(q);
+       spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
 /**
  *     ide_timer_expiry        -       handle lack of an IDE interrupt
  *     @data: timer callback magic (hwgroup)
@@ -1000,10 +891,12 @@ out:
 void ide_timer_expiry (unsigned long data)
 {
        ide_hwgroup_t   *hwgroup = (ide_hwgroup_t *) data;
+       ide_drive_t     *uninitialized_var(drive);
        ide_handler_t   *handler;
        ide_expiry_t    *expiry;
        unsigned long   flags;
        unsigned long   wait = -1;
+       int             plug_device = 0;
 
        spin_lock_irqsave(&hwgroup->lock, flags);
 
@@ -1015,22 +908,15 @@ void ide_timer_expiry (unsigned long data)
                 * or we were "sleeping" to give other devices a chance.
                 * Either way, we don't really want to complain about anything.
                 */
-               if (hwgroup->sleeping) {
-                       hwgroup->sleeping = 0;
-                       hwgroup->busy = 0;
-               }
        } else {
-               ide_drive_t *drive = hwgroup->drive;
+               drive = hwgroup->drive;
                if (!drive) {
                        printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n");
                        hwgroup->handler = NULL;
                } else {
                        ide_hwif_t *hwif;
                        ide_startstop_t startstop = ide_stopped;
-                       if (!hwgroup->busy) {
-                               hwgroup->busy = 1;      /* paranoia */
-                               printk(KERN_ERR "%s: ide_timer_expiry: hwgroup->busy was 0 ??\n", drive->name);
-                       }
+
                        if ((expiry = hwgroup->expiry) != NULL) {
                                /* continue */
                                if ((wait = expiry(drive)) > 0) {
@@ -1071,15 +957,18 @@ void ide_timer_expiry (unsigned long data)
                                        ide_error(drive, "irq timeout",
                                                  hwif->tp_ops->read_status(hwif));
                        }
-                       drive->service_time = jiffies - drive->service_start;
                        spin_lock_irq(&hwgroup->lock);
                        enable_irq(hwif->irq);
-                       if (startstop == ide_stopped)
-                               hwgroup->busy = 0;
+                       if (startstop == ide_stopped) {
+                               ide_unlock_hwgroup(hwgroup);
+                               plug_device = 1;
+                       }
                }
        }
-       ide_do_request(hwgroup, IDE_NO_IRQ);
        spin_unlock_irqrestore(&hwgroup->lock, flags);
+
+       if (plug_device)
+               ide_plug_device(drive);
 }
 
 /**
@@ -1173,10 +1062,11 @@ irqreturn_t ide_intr (int irq, void *dev_id)
        unsigned long flags;
        ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;
        ide_hwif_t *hwif = hwgroup->hwif;
-       ide_drive_t *drive;
+       ide_drive_t *uninitialized_var(drive);
        ide_handler_t *handler;
        ide_startstop_t startstop;
        irqreturn_t irq_ret = IRQ_NONE;
+       int plug_device = 0;
 
        spin_lock_irqsave(&hwgroup->lock, flags);
 
@@ -1241,10 +1131,6 @@ irqreturn_t ide_intr (int irq, void *dev_id)
                 */
                goto out;
 
-       if (!hwgroup->busy) {
-               hwgroup->busy = 1;      /* paranoia */
-               printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name);
-       }
        hwgroup->handler = NULL;
        hwgroup->req_gen++;
        del_timer(&hwgroup->timer);
@@ -1267,20 +1153,22 @@ irqreturn_t ide_intr (int irq, void *dev_id)
         * same irq as is currently being serviced here, and Linux
         * won't allow another of the same (on any CPU) until we return.
         */
-       drive->service_time = jiffies - drive->service_start;
        if (startstop == ide_stopped) {
                if (hwgroup->handler == NULL) { /* paranoia */
-                       hwgroup->busy = 0;
-                       ide_do_request(hwgroup, hwif->irq);
-               } else {
-                       printk(KERN_ERR "%s: ide_intr: huh? expected NULL handler "
-                               "on exit\n", drive->name);
-               }
+                       ide_unlock_hwgroup(hwgroup);
+                       plug_device = 1;
+               } else
+                       printk(KERN_ERR "%s: %s: huh? expected NULL handler "
+                                       "on exit\n", __func__, drive->name);
        }
 out_handled:
        irq_ret = IRQ_HANDLED;
 out:
        spin_unlock_irqrestore(&hwgroup->lock, flags);
+
+       if (plug_device)
+               ide_plug_device(drive);
+
        return irq_ret;
 }
 
index 28232c64c3464becc4eef1319467d5a49dc86e00..1be263eb9c071c3cf7e3b48e0010ec9d4f02f476 100644 (file)
@@ -95,8 +95,7 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg)
                return -EPERM;
 
        if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) &&
-           (drive->media != ide_tape ||
-            (drive->dev_flags & IDE_DFLAG_SCSI)))
+           (drive->media != ide_tape))
                return -EPERM;
 
        if ((arg >> IDE_NICE_DSC_OVERLAP) & 1)
index 63d01c55f865504fa06b9562acf7021b4bb3c8ae..678454ac24837b051c5215deb87b20fa670973e9 100644 (file)
@@ -16,16 +16,19 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
        spin_lock_irq(&hwgroup->lock);
        if (drive->dev_flags & IDE_DFLAG_PARKED) {
                int reset_timer = time_before(timeout, drive->sleep);
+               int start_queue = 0;
 
                drive->sleep = timeout;
                wake_up_all(&ide_park_wq);
-               if (reset_timer && hwgroup->sleeping &&
-                   del_timer(&hwgroup->timer)) {
-                       hwgroup->sleeping = 0;
-                       hwgroup->busy = 0;
+               if (reset_timer && del_timer(&hwgroup->timer))
+                       start_queue = 1;
+               spin_unlock_irq(&hwgroup->lock);
+
+               if (start_queue) {
+                       spin_lock_irq(q->queue_lock);
                        blk_start_queueing(q);
+                       spin_unlock_irq(q->queue_lock);
                }
-               spin_unlock_irq(&hwgroup->lock);
                return;
        }
        spin_unlock_irq(&hwgroup->lock);
index a64ec259f3d13a50c01468c98669a9712f33d9f1..c5adb7b9c5b5eeedad09163c395a03dc64704259 100644 (file)
@@ -101,6 +101,82 @@ static void ide_disk_init_mult_count(ide_drive_t *drive)
        }
 }
 
+static void ide_classify_ata_dev(ide_drive_t *drive)
+{
+       u16 *id = drive->id;
+       char *m = (char *)&id[ATA_ID_PROD];
+       int is_cfa = ata_id_is_cfa(id);
+
+       /* CF devices are *not* removable in Linux definition of the term */
+       if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))
+               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
+
+       drive->media = ide_disk;
+
+       if (!ata_id_has_unload(drive->id))
+               drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
+
+       printk(KERN_INFO "%s: %s, %s DISK drive\n", drive->name, m,
+               is_cfa ? "CFA" : "ATA");
+}
+
+static void ide_classify_atapi_dev(ide_drive_t *drive)
+{
+       u16 *id = drive->id;
+       char *m = (char *)&id[ATA_ID_PROD];
+       u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;
+
+       printk(KERN_INFO "%s: %s, ATAPI ", drive->name, m);
+       switch (type) {
+       case ide_floppy:
+               if (!strstr(m, "CD-ROM")) {
+                       if (!strstr(m, "oppy") &&
+                           !strstr(m, "poyp") &&
+                           !strstr(m, "ZIP"))
+                               printk(KERN_CONT "cdrom or floppy?, assuming ");
+                       if (drive->media != ide_cdrom) {
+                               printk(KERN_CONT "FLOPPY");
+                               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
+                               break;
+                       }
+               }
+               /* Early cdrom models used zero */
+               type = ide_cdrom;
+       case ide_cdrom:
+               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
+#ifdef CONFIG_PPC
+               /* kludge for Apple PowerBook internal zip */
+               if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) {
+                       printk(KERN_CONT "FLOPPY");
+                       type = ide_floppy;
+                       break;
+               }
+#endif
+               printk(KERN_CONT "CD/DVD-ROM");
+               break;
+       case ide_tape:
+               printk(KERN_CONT "TAPE");
+               break;
+       case ide_optical:
+               printk(KERN_CONT "OPTICAL");
+               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
+               break;
+       default:
+               printk(KERN_CONT "UNKNOWN (type %d)", type);
+               break;
+       }
+
+       printk(KERN_CONT " drive\n");
+       drive->media = type;
+       /* an ATAPI device ignores DRDY */
+       drive->ready_stat = 0;
+       if (ata_id_cdb_intr(id))
+               drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
+       drive->dev_flags |= IDE_DFLAG_DOORLOCKING;
+       /* we don't do head unloading on ATAPI devices */
+       drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
+}
+
 /**
  *     do_identify     -       identify a drive
  *     @drive: drive to identify 
@@ -117,7 +193,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd)
        u16 *id = drive->id;
        char *m = (char *)&id[ATA_ID_PROD];
        unsigned long flags;
-       int bswap = 1, is_cfa;
+       int bswap = 1;
 
        /* local CPU only; some systems need this */
        local_irq_save(flags);
@@ -154,91 +230,23 @@ static void do_identify(ide_drive_t *drive, u8 cmd)
        if (strstr(m, "E X A B Y T E N E S T"))
                goto err_misc;
 
-       printk(KERN_INFO "%s: %s, ", drive->name, m);
-
        drive->dev_flags |= IDE_DFLAG_PRESENT;
        drive->dev_flags &= ~IDE_DFLAG_DEAD;
 
        /*
         * Check for an ATAPI device
         */
-       if (cmd == ATA_CMD_ID_ATAPI) {
-               u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;
-
-               printk(KERN_CONT "ATAPI ");
-               switch (type) {
-                       case ide_floppy:
-                               if (!strstr(m, "CD-ROM")) {
-                                       if (!strstr(m, "oppy") &&
-                                           !strstr(m, "poyp") &&
-                                           !strstr(m, "ZIP"))
-                                               printk(KERN_CONT "cdrom or floppy?, assuming ");
-                                       if (drive->media != ide_cdrom) {
-                                               printk(KERN_CONT "FLOPPY");
-                                               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
-                                               break;
-                                       }
-                               }
-                               /* Early cdrom models used zero */
-                               type = ide_cdrom;
-                       case ide_cdrom:
-                               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
-#ifdef CONFIG_PPC
-                               /* kludge for Apple PowerBook internal zip */
-                               if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) {
-                                       printk(KERN_CONT "FLOPPY");
-                                       type = ide_floppy;
-                                       break;
-                               }
-#endif
-                               printk(KERN_CONT "CD/DVD-ROM");
-                               break;
-                       case ide_tape:
-                               printk(KERN_CONT "TAPE");
-                               break;
-                       case ide_optical:
-                               printk(KERN_CONT "OPTICAL");
-                               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
-                               break;
-                       default:
-                               printk(KERN_CONT "UNKNOWN (type %d)", type);
-                               break;
-               }
-               printk(KERN_CONT " drive\n");
-               drive->media = type;
-               /* an ATAPI device ignores DRDY */
-               drive->ready_stat = 0;
-               if (ata_id_cdb_intr(id))
-                       drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
-               drive->dev_flags |= IDE_DFLAG_DOORLOCKING;
-               /* we don't do head unloading on ATAPI devices */
-               drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
-               return;
-       }
-
+       if (cmd == ATA_CMD_ID_ATAPI)
+               ide_classify_atapi_dev(drive);
+       else
        /*
         * Not an ATAPI device: looks like a "regular" hard disk
         */
-
-       is_cfa = ata_id_is_cfa(id);
-
-       /* CF devices are *not* removable in Linux definition of the term */
-       if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))
-               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
-
-       drive->media = ide_disk;
-
-       if (!ata_id_has_unload(drive->id))
-               drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
-
-       printk(KERN_CONT "%s DISK drive\n", is_cfa ? "CFA" : "ATA");
-
+               ide_classify_ata_dev(drive);
        return;
-
 err_misc:
        kfree(id);
        drive->dev_flags &= ~IDE_DFLAG_PRESENT;
-       return;
 }
 
 /**
@@ -641,14 +649,9 @@ static int ide_register_port(ide_hwif_t *hwif)
        /* register with global device tree */
        dev_set_name(&hwif->gendev, hwif->name);
        hwif->gendev.driver_data = hwif;
-       if (hwif->gendev.parent == NULL) {
-               if (hwif->dev)
-                       hwif->gendev.parent = hwif->dev;
-               else
-                       /* Would like to do = &device_legacy */
-                       hwif->gendev.parent = NULL;
-       }
+       hwif->gendev.parent = hwif->dev;
        hwif->gendev.release = hwif_release_dev;
+
        ret = device_register(&hwif->gendev);
        if (ret < 0) {
                printk(KERN_WARNING "IDE: %s: device_register error: %d\n",
@@ -878,8 +881,7 @@ static int ide_init_queue(ide_drive_t *drive)
         *      do not.
         */
 
-       q = blk_init_queue_node(do_ide_request, &hwif->hwgroup->lock,
-                               hwif_to_node(hwif));
+       q = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif));
        if (!q)
                return 1;
 
@@ -1139,8 +1141,6 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data)
 
        if (drive->media == ide_disk)
                request_module("ide-disk");
-       if (drive->dev_flags & IDE_DFLAG_SCSI)
-               request_module("ide-scsi");
        if (drive->media == ide_cdrom || drive->media == ide_optical)
                request_module("ide-cd");
        if (drive->media == ide_tape)
@@ -1417,58 +1417,6 @@ static void ide_port_cable_detect(ide_hwif_t *hwif)
        }
 }
 
-static ssize_t store_delete_devices(struct device *portdev,
-                                   struct device_attribute *attr,
-                                   const char *buf, size_t n)
-{
-       ide_hwif_t *hwif = dev_get_drvdata(portdev);
-
-       if (strncmp(buf, "1", n))
-               return -EINVAL;
-
-       ide_port_unregister_devices(hwif);
-
-       return n;
-};
-
-static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);
-
-static ssize_t store_scan(struct device *portdev,
-                         struct device_attribute *attr,
-                         const char *buf, size_t n)
-{
-       ide_hwif_t *hwif = dev_get_drvdata(portdev);
-
-       if (strncmp(buf, "1", n))
-               return -EINVAL;
-
-       ide_port_unregister_devices(hwif);
-       ide_port_scan(hwif);
-
-       return n;
-};
-
-static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);
-
-static struct device_attribute *ide_port_attrs[] = {
-       &dev_attr_delete_devices,
-       &dev_attr_scan,
-       NULL
-};
-
-static int ide_sysfs_register_port(ide_hwif_t *hwif)
-{
-       int i, uninitialized_var(rc);
-
-       for (i = 0; ide_port_attrs[i]; i++) {
-               rc = device_create_file(hwif->portdev, ide_port_attrs[i]);
-               if (rc)
-                       break;
-       }
-
-       return rc;
-}
-
 static unsigned int ide_indexes;
 
 /**
@@ -1655,9 +1603,6 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                if (hwif == NULL)
                        continue;
 
-               if (hwif->chipset == ide_unknown)
-                       hwif->chipset = ide_generic;
-
                if (hwif->present)
                        hwif_register_devices(hwif);
        }
diff --git a/drivers/ide/ide-sysfs.c b/drivers/ide/ide-sysfs.c
new file mode 100644 (file)
index 0000000..883ffac
--- /dev/null
@@ -0,0 +1,125 @@
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+char *ide_media_string(ide_drive_t *drive)
+{
+       switch (drive->media) {
+       case ide_disk:
+               return "disk";
+       case ide_cdrom:
+               return "cdrom";
+       case ide_tape:
+               return "tape";
+       case ide_floppy:
+               return "floppy";
+       case ide_optical:
+               return "optical";
+       default:
+               return "UNKNOWN";
+       }
+}
+
+static ssize_t media_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", ide_media_string(drive));
+}
+
+static ssize_t drivename_show(struct device *dev, struct device_attribute *attr,
+                             char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", drive->name);
+}
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "ide:m-%s\n", ide_media_string(drive));
+}
+
+static ssize_t model_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]);
+}
+
+static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]);
+}
+
+static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]);
+}
+
+struct device_attribute ide_dev_attrs[] = {
+       __ATTR_RO(media),
+       __ATTR_RO(drivename),
+       __ATTR_RO(modalias),
+       __ATTR_RO(model),
+       __ATTR_RO(firmware),
+       __ATTR(serial, 0400, serial_show, NULL),
+       __ATTR(unload_heads, 0644, ide_park_show, ide_park_store),
+       __ATTR_NULL
+};
+
+static ssize_t store_delete_devices(struct device *portdev,
+                                   struct device_attribute *attr,
+                                   const char *buf, size_t n)
+{
+       ide_hwif_t *hwif = dev_get_drvdata(portdev);
+
+       if (strncmp(buf, "1", n))
+               return -EINVAL;
+
+       ide_port_unregister_devices(hwif);
+
+       return n;
+};
+
+static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);
+
+static ssize_t store_scan(struct device *portdev,
+                         struct device_attribute *attr,
+                         const char *buf, size_t n)
+{
+       ide_hwif_t *hwif = dev_get_drvdata(portdev);
+
+       if (strncmp(buf, "1", n))
+               return -EINVAL;
+
+       ide_port_unregister_devices(hwif);
+       ide_port_scan(hwif);
+
+       return n;
+};
+
+static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);
+
+static struct device_attribute *ide_port_attrs[] = {
+       &dev_attr_delete_devices,
+       &dev_attr_scan,
+       NULL
+};
+
+int ide_sysfs_register_port(ide_hwif_t *hwif)
+{
+       int i, uninitialized_var(rc);
+
+       for (i = 0; ide_port_attrs[i]; i++) {
+               rc = device_create_file(hwif->portdev, ide_port_attrs[i]);
+               if (rc)
+                       break;
+       }
+
+       return rc;
+}
index a2d470eb2b55eed6d66c713ee51c00dd9f806d02..5d2aa22cd6e471617176ab38624f5b164ccb3f09 100644 (file)
@@ -694,7 +694,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
 
        pc->retries++;
 
-       return ide_issue_pc(drive, WAIT_TAPE_CMD, NULL);
+       return ide_issue_pc(drive);
 }
 
 /* A mode sense command is used to "sense" tape parameters. */
index f0f09f702e9ccf54b20f7ed85d1c9d00b6326275..46a2d4ca812bbf1b045b2d333958cfce003484a8 100644 (file)
@@ -440,81 +440,13 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv)
        return 1;
 }
 
-static char *media_string(ide_drive_t *drive)
-{
-       switch (drive->media) {
-       case ide_disk:
-               return "disk";
-       case ide_cdrom:
-               return "cdrom";
-       case ide_tape:
-               return "tape";
-       case ide_floppy:
-               return "floppy";
-       case ide_optical:
-               return "optical";
-       default:
-               return "UNKNOWN";
-       }
-}
-
-static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       ide_drive_t *drive = to_ide_device(dev);
-       return sprintf(buf, "%s\n", media_string(drive));
-}
-
-static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       ide_drive_t *drive = to_ide_device(dev);
-       return sprintf(buf, "%s\n", drive->name);
-}
-
-static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       ide_drive_t *drive = to_ide_device(dev);
-       return sprintf(buf, "ide:m-%s\n", media_string(drive));
-}
-
-static ssize_t model_show(struct device *dev, struct device_attribute *attr,
-                         char *buf)
-{
-       ide_drive_t *drive = to_ide_device(dev);
-       return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]);
-}
-
-static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,
-                            char *buf)
-{
-       ide_drive_t *drive = to_ide_device(dev);
-       return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]);
-}
-
-static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
-                          char *buf)
-{
-       ide_drive_t *drive = to_ide_device(dev);
-       return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]);
-}
-
-static struct device_attribute ide_dev_attrs[] = {
-       __ATTR_RO(media),
-       __ATTR_RO(drivename),
-       __ATTR_RO(modalias),
-       __ATTR_RO(model),
-       __ATTR_RO(firmware),
-       __ATTR(serial, 0400, serial_show, NULL),
-       __ATTR(unload_heads, 0644, ide_park_show, ide_park_store),
-       __ATTR_NULL
-};
-
 static int ide_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
        ide_drive_t *drive = to_ide_device(dev);
 
-       add_uevent_var(env, "MEDIA=%s", media_string(drive));
+       add_uevent_var(env, "MEDIA=%s", ide_media_string(drive));
        add_uevent_var(env, "DRIVENAME=%s", drive->name);
-       add_uevent_var(env, "MODALIAS=ide:m-%s", media_string(drive));
+       add_uevent_var(env, "MODALIAS=ide:m-%s", ide_media_string(drive));
        return 0;
 }
 
index 13b63e7fa353df1075e1fdfdfffcf74929a1cdcf..b4ef218072cd1629737fb35b4cad89505037fffb 100644 (file)
@@ -216,16 +216,17 @@ static const struct ide_tp_ops tx4938ide_tp_ops = {
 #endif /* __BIG_ENDIAN */
 
 static const struct ide_port_ops tx4938ide_port_ops = {
-       .set_pio_mode = tx4938ide_set_pio_mode,
+       .set_pio_mode           = tx4938ide_set_pio_mode,
 };
 
 static const struct ide_port_info tx4938ide_port_info __initdata = {
-       .port_ops = &tx4938ide_port_ops,
+       .port_ops               = &tx4938ide_port_ops,
 #ifdef __BIG_ENDIAN
-       .tp_ops = &tx4938ide_tp_ops,
+       .tp_ops                 = &tx4938ide_tp_ops,
 #endif
-       .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
-       .pio_mask = ATA_PIO5,
+       .host_flags             = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+       .pio_mask               = ATA_PIO5,
+       .chipset                = ide_generic,
 };
 
 static int __init tx4938ide_probe(struct platform_device *pdev)
index 97cd9e0f66f692cdc1fe76a8e8f781f7e878e730..4a8c5a21bd4c0cc3ab15c172e697193e1ad79a7f 100644 (file)
@@ -623,33 +623,34 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
 #endif /* __LITTLE_ENDIAN */
 
 static const struct ide_port_ops tx4939ide_port_ops = {
-       .set_pio_mode = tx4939ide_set_pio_mode,
-       .set_dma_mode = tx4939ide_set_dma_mode,
-       .clear_irq = tx4939ide_clear_irq,
-       .cable_detect = tx4939ide_cable_detect,
+       .set_pio_mode           = tx4939ide_set_pio_mode,
+       .set_dma_mode           = tx4939ide_set_dma_mode,
+       .clear_irq              = tx4939ide_clear_irq,
+       .cable_detect           = tx4939ide_cable_detect,
 };
 
 static const struct ide_dma_ops tx4939ide_dma_ops = {
-       .dma_host_set = tx4939ide_dma_host_set,
-       .dma_setup = tx4939ide_dma_setup,
-       .dma_exec_cmd = ide_dma_exec_cmd,
-       .dma_start = ide_dma_start,
-       .dma_end = tx4939ide_dma_end,
-       .dma_test_irq = tx4939ide_dma_test_irq,
-       .dma_lost_irq = ide_dma_lost_irq,
-       .dma_timeout = ide_dma_timeout,
+       .dma_host_set           = tx4939ide_dma_host_set,
+       .dma_setup              = tx4939ide_dma_setup,
+       .dma_exec_cmd           = ide_dma_exec_cmd,
+       .dma_start              = ide_dma_start,
+       .dma_end                = tx4939ide_dma_end,
+       .dma_test_irq           = tx4939ide_dma_test_irq,
+       .dma_lost_irq           = ide_dma_lost_irq,
+       .dma_timeout            = ide_dma_timeout,
 };
 
 static const struct ide_port_info tx4939ide_port_info __initdata = {
-       .init_hwif = tx4939ide_init_hwif,
-       .init_dma = tx4939ide_init_dma,
-       .port_ops = &tx4939ide_port_ops,
-       .dma_ops = &tx4939ide_dma_ops,
-       .tp_ops = &tx4939ide_tp_ops,
-       .host_flags = IDE_HFLAG_MMIO,
-       .pio_mask = ATA_PIO4,
-       .mwdma_mask = ATA_MWDMA2,
-       .udma_mask = ATA_UDMA5,
+       .init_hwif              = tx4939ide_init_hwif,
+       .init_dma               = tx4939ide_init_dma,
+       .port_ops               = &tx4939ide_port_ops,
+       .dma_ops                = &tx4939ide_dma_ops,
+       .tp_ops                 = &tx4939ide_tp_ops,
+       .host_flags             = IDE_HFLAG_MMIO,
+       .pio_mask               = ATA_PIO4,
+       .mwdma_mask             = ATA_MWDMA2,
+       .udma_mask              = ATA_UDMA5,
+       .chipset                = ide_generic,
 };
 
 static int __init tx4939ide_probe(struct platform_device *pdev)
index 152d4aa9354f598df30f8ee81c23409b0945ef54..b7322976d2b7c7e3c131deecd577181209804d83 100644 (file)
@@ -21,7 +21,7 @@ config SCSI
          You also need to say Y here if you have a device which speaks
          the SCSI protocol.  Examples of this include the parallel port
          version of the IOMEGA ZIP drive, USB storage devices, Fibre
-         Channel, FireWire storage and the IDE-SCSI emulation driver.
+         Channel, and FireWire storage.
 
          To compile this driver as a module, choose M here and read
          <file:Documentation/scsi/scsi.txt>.
@@ -101,9 +101,9 @@ config CHR_DEV_OSST
        ---help---
          The OnStream SC-x0 SCSI tape drives cannot be driven by the
          standard st driver, but instead need this special osst driver and
-         use the  /dev/osstX char device nodes (major 206).  Via usb-storage
-         and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives
-         as well.  Note that there is also a second generation of OnStream
+         use the  /dev/osstX char device nodes (major 206).  Via usb-storage,
+         you may be able to drive the USB-x0 and DI-x0 drives as well.
+         Note that there is also a second generation of OnStream
          tape drives (ADR-x0) that supports the standard SCSI-2 commands for
          tapes (QIC-157) and can be driven by the standard driver st.
          For more information, you may have a look at the SCSI-HOWTO
index 1410697257cb8aed064e560da8d08fa85bc9f272..7461eb09a031080b517de0fba9367eedbcf637d5 100644 (file)
@@ -105,7 +105,6 @@ obj-$(CONFIG_SCSI_GDTH)             += gdth.o
 obj-$(CONFIG_SCSI_INITIO)      += initio.o
 obj-$(CONFIG_SCSI_INIA100)     += a100u2w.o
 obj-$(CONFIG_SCSI_QLOGICPTI)   += qlogicpti.o
-obj-$(CONFIG_BLK_DEV_IDESCSI)  += ide-scsi.o
 obj-$(CONFIG_SCSI_MESH)                += mesh.o
 obj-$(CONFIG_SCSI_MAC53C94)    += mac53c94.o
 obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
deleted file mode 100644 (file)
index c24140a..0000000
+++ /dev/null
@@ -1,840 +0,0 @@
-/*
- * Copyright (C) 1996-1999  Gadi Oxman <gadio@netvision.net.il>
- * Copyright (C) 2004-2005  Bartlomiej Zolnierkiewicz
- */
-
-/*
- * Emulation of a SCSI host adapter for IDE ATAPI devices.
- *
- * With this driver, one can use the Linux SCSI drivers instead of the
- * native IDE ATAPI drivers.
- *
- * Ver 0.1   Dec  3 96   Initial version.
- * Ver 0.2   Jan 26 97   Fixed bug in cleanup_module() and added emulation
- *                        of MODE_SENSE_6/MODE_SELECT_6 for cdroms. Thanks
- *                        to Janos Farkas for pointing this out.
- *                       Avoid using bitfields in structures for m68k.
- *                       Added Scatter/Gather and DMA support.
- * Ver 0.4   Dec  7 97   Add support for ATAPI PD/CD drives.
- *                       Use variable timeout for each command.
- * Ver 0.5   Jan  2 98   Fix previous PD/CD support.
- *                       Allow disabling of SCSI-6 to SCSI-10 transformation.
- * Ver 0.6   Jan 27 98   Allow disabling of SCSI command translation layer
- *                        for access through /dev/sg.
- *                       Fix MODE_SENSE_6/MODE_SELECT_6/INQUIRY translation.
- * Ver 0.7   Dec 04 98   Ignore commands where lun != 0 to avoid multiple
- *                        detection of devices with CONFIG_SCSI_MULTI_LUN
- * Ver 0.8   Feb 05 99   Optical media need translation too. Reverse 0.7.
- * Ver 0.9   Jul 04 99   Fix a bug in SG_SET_TRANSFORM.
- * Ver 0.91  Jun 10 02   Fix "off by one" error in transforms
- * Ver 0.92  Dec 31 02   Implement new SCSI mid level API
- */
-
-#define IDESCSI_VERSION "0.92"
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/ide.h>
-#include <linux/scatterlist.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/sg.h>
-
-#define IDESCSI_DEBUG_LOG              0
-
-#if IDESCSI_DEBUG_LOG
-#define debug_log(fmt, args...) \
-       printk(KERN_INFO "ide-scsi: " fmt, ## args)
-#else
-#define debug_log(fmt, args...) do {} while (0)
-#endif
-
-/*
- *     SCSI command transformation layer
- */
-#define IDESCSI_SG_TRANSFORM           1       /* /dev/sg transformation */
-
-/*
- *     Log flags
- */
-#define IDESCSI_LOG_CMD                        0       /* Log SCSI commands */
-
-typedef struct ide_scsi_obj {
-       ide_drive_t             *drive;
-       ide_driver_t            *driver;
-       struct gendisk          *disk;
-       struct Scsi_Host        *host;
-
-       unsigned long transform;                /* SCSI cmd translation layer */
-       unsigned long log;                      /* log flags */
-} idescsi_scsi_t;
-
-static DEFINE_MUTEX(idescsi_ref_mutex);
-/* Set by module param to skip cd */
-static int idescsi_nocd;
-
-#define ide_scsi_g(disk) \
-       container_of((disk)->private_data, struct ide_scsi_obj, driver)
-
-static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk)
-{
-       struct ide_scsi_obj *scsi = NULL;
-
-       mutex_lock(&idescsi_ref_mutex);
-       scsi = ide_scsi_g(disk);
-       if (scsi) {
-               if (ide_device_get(scsi->drive))
-                       scsi = NULL;
-               else
-                       scsi_host_get(scsi->host);
-       }
-       mutex_unlock(&idescsi_ref_mutex);
-       return scsi;
-}
-
-static void ide_scsi_put(struct ide_scsi_obj *scsi)
-{
-       ide_drive_t *drive = scsi->drive;
-
-       mutex_lock(&idescsi_ref_mutex);
-       scsi_host_put(scsi->host);
-       ide_device_put(drive);
-       mutex_unlock(&idescsi_ref_mutex);
-}
-
-static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host)
-{
-       return (idescsi_scsi_t*) (&host[1]);
-}
-
-static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)
-{
-       return scsihost_to_idescsi(ide_drive->driver_data);
-}
-
-static void ide_scsi_hex_dump(u8 *data, int len)
-{
-       print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0);
-}
-
-static int idescsi_end_request(ide_drive_t *, int, int);
-
-static void ide_scsi_callback(ide_drive_t *drive, int dsc)
-{
-       idescsi_scsi_t *scsi = drive_to_idescsi(drive);
-       struct ide_atapi_pc *pc = drive->pc;
-
-       if (pc->flags & PC_FLAG_TIMEDOUT)
-               debug_log("%s: got timed out packet %lu at %lu\n", __func__,
-                         pc->scsi_cmd->serial_number, jiffies);
-               /* end this request now - scsi should retry it*/
-       else if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
-               printk(KERN_INFO "Packet command completed, %d bytes"
-                                " transferred\n", pc->xferred);
-
-       idescsi_end_request(drive, 1, 0);
-}
-
-static int idescsi_check_condition(ide_drive_t *drive,
-               struct request *failed_cmd)
-{
-       idescsi_scsi_t *scsi = drive_to_idescsi(drive);
-       struct ide_atapi_pc   *pc;
-       struct request *rq;
-       u8             *buf;
-
-       /* stuff a sense request in front of our current request */
-       pc = kzalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC);
-       rq = blk_get_request(drive->queue, READ, GFP_ATOMIC);
-       buf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);
-       if (!pc || !rq || !buf) {
-               kfree(buf);
-               if (rq)
-                       blk_put_request(rq);
-               kfree(pc);
-               return -ENOMEM;
-       }
-       rq->special = (char *) pc;
-       pc->rq = rq;
-       pc->buf = buf;
-       pc->c[0] = REQUEST_SENSE;
-       pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE;
-       rq->cmd_type = REQ_TYPE_SENSE;
-       rq->cmd_flags |= REQ_PREEMPT;
-       pc->timeout = jiffies + WAIT_READY;
-       /* NOTE! Save the failed packet command in "rq->buffer" */
-       rq->buffer = (void *) failed_cmd->special;
-       pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd;
-       if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
-               printk ("ide-scsi: %s: queue cmd = ", drive->name);
-               ide_scsi_hex_dump(pc->c, 6);
-       }
-       rq->rq_disk = scsi->disk;
-       rq->ref_count++;
-       memcpy(rq->cmd, pc->c, 12);
-       ide_do_drive_cmd(drive, rq);
-       return 0;
-}
-
-static ide_startstop_t
-idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
-       ide_hwif_t *hwif = drive->hwif;
-
-       if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
-               /* force an abort */
-               hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
-
-       rq->errors++;
-
-       idescsi_end_request(drive, 0, 0);
-
-       return ide_stopped;
-}
-
-static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
-{
-       idescsi_scsi_t *scsi = drive_to_idescsi(drive);
-       struct request *rq = HWGROUP(drive)->rq;
-       struct ide_atapi_pc *pc = (struct ide_atapi_pc *) rq->special;
-       int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
-       struct Scsi_Host *host;
-       int errors = rq->errors;
-       unsigned long flags;
-
-       if (!blk_special_request(rq) && !blk_sense_request(rq)) {
-               ide_end_request(drive, uptodate, nrsecs);
-               return 0;
-       }
-       ide_end_drive_cmd (drive, 0, 0);
-       if (blk_sense_request(rq)) {
-               struct ide_atapi_pc *opc = (struct ide_atapi_pc *) rq->buffer;
-               if (log) {
-                       printk ("ide-scsi: %s: wrap up check %lu, rst = ", drive->name, opc->scsi_cmd->serial_number);
-                       ide_scsi_hex_dump(pc->buf, 16);
-               }
-               memcpy((void *) opc->scsi_cmd->sense_buffer, pc->buf,
-                       SCSI_SENSE_BUFFERSIZE);
-               kfree(pc->buf);
-               kfree(pc);
-               blk_put_request(rq);
-               pc = opc;
-               rq = pc->rq;
-               pc->scsi_cmd->result = (CHECK_CONDITION << 1) |
-                               (((pc->flags & PC_FLAG_TIMEDOUT) ?
-                                 DID_TIME_OUT :
-                                 DID_OK) << 16);
-       } else if (pc->flags & PC_FLAG_TIMEDOUT) {
-               if (log)
-                       printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n",
-                                       drive->name, pc->scsi_cmd->serial_number);
-               pc->scsi_cmd->result = DID_TIME_OUT << 16;
-       } else if (errors >= ERROR_MAX) {
-               pc->scsi_cmd->result = DID_ERROR << 16;
-               if (log)
-                       printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number);
-       } else if (errors) {
-               if (log)
-                       printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number);
-               if (!idescsi_check_condition(drive, rq))
-                       /* we started a request sense, so we'll be back, exit for now */
-                       return 0;
-               pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
-       } else {
-               pc->scsi_cmd->result = DID_OK << 16;
-       }
-       host = pc->scsi_cmd->device->host;
-       spin_lock_irqsave(host->host_lock, flags);
-       pc->done(pc->scsi_cmd);
-       spin_unlock_irqrestore(host->host_lock, flags);
-       kfree(pc);
-       blk_put_request(rq);
-       drive->pc = NULL;
-       return 0;
-}
-
-static inline int idescsi_set_direction(struct ide_atapi_pc *pc)
-{
-       switch (pc->c[0]) {
-               case READ_6: case READ_10: case READ_12:
-                       pc->flags &= ~PC_FLAG_WRITING;
-                       return 0;
-               case WRITE_6: case WRITE_10: case WRITE_12:
-                       pc->flags |= PC_FLAG_WRITING;
-                       return 0;
-               default:
-                       return 1;
-       }
-}
-
-static int idescsi_map_sg(ide_drive_t *drive, struct ide_atapi_pc *pc)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       struct scatterlist *sg, *scsi_sg;
-       int segments;
-
-       if (!pc->req_xfer || pc->req_xfer % 1024)
-               return 1;
-
-       if (idescsi_set_direction(pc))
-               return 1;
-
-       sg = hwif->sg_table;
-       scsi_sg = scsi_sglist(pc->scsi_cmd);
-       segments = scsi_sg_count(pc->scsi_cmd);
-
-       if (segments > hwif->sg_max_nents)
-               return 1;
-
-       hwif->sg_nents = segments;
-       memcpy(sg, scsi_sg, sizeof(*sg) * segments);
-
-       return 0;
-}
-
-static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
-               struct ide_atapi_pc *pc)
-{
-       /* Set the current packet command */
-       drive->pc = pc;
-
-       return ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry);
-}
-
-/*
- *     idescsi_do_request is our request handling function.
- */
-static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
-{
-       debug_log("dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,
-                 rq->cmd[0], rq->errors);
-       debug_log("sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",
-                 rq->sector, rq->nr_sectors, rq->current_nr_sectors);
-
-       if (blk_sense_request(rq) || blk_special_request(rq)) {
-               struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;
-
-               if ((drive->dev_flags & IDE_DFLAG_USING_DMA) &&
-                   idescsi_map_sg(drive, pc) == 0)
-                       pc->flags |= PC_FLAG_DMA_OK;
-
-               return idescsi_issue_pc(drive, pc);
-       }
-       blk_dump_rq_flags(rq, "ide-scsi: unsup command");
-       idescsi_end_request (drive, 0, 0);
-       return ide_stopped;
-}
-
-#ifdef CONFIG_IDE_PROC_FS
-static ide_proc_entry_t idescsi_proc[] = {
-       { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },
-       { NULL, 0, NULL, NULL }
-};
-
-#define ide_scsi_devset_get(name, field) \
-static int get_##name(ide_drive_t *drive) \
-{ \
-       idescsi_scsi_t *scsi = drive_to_idescsi(drive); \
-       return scsi->field; \
-}
-
-#define ide_scsi_devset_set(name, field) \
-static int set_##name(ide_drive_t *drive, int arg) \
-{ \
-       idescsi_scsi_t *scsi = drive_to_idescsi(drive); \
-       scsi->field = arg; \
-       return 0; \
-}
-
-#define ide_scsi_devset_rw_field(_name, _field) \
-ide_scsi_devset_get(_name, _field); \
-ide_scsi_devset_set(_name, _field); \
-IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name);
-
-ide_devset_rw_field(bios_cyl, bios_cyl);
-ide_devset_rw_field(bios_head, bios_head);
-ide_devset_rw_field(bios_sect, bios_sect);
-
-ide_scsi_devset_rw_field(transform, transform);
-ide_scsi_devset_rw_field(log, log);
-
-static const struct ide_proc_devset idescsi_settings[] = {
-       IDE_PROC_DEVSET(bios_cyl,  0, 1023),
-       IDE_PROC_DEVSET(bios_head, 0,  255),
-       IDE_PROC_DEVSET(bios_sect, 0,   63),
-       IDE_PROC_DEVSET(log,       0,    1),
-       IDE_PROC_DEVSET(transform, 0,    3),
-       { 0 },
-};
-
-static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive)
-{
-       return idescsi_proc;
-}
-
-static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive)
-{
-       return idescsi_settings;
-}
-#endif
-
-/*
- *     Driver initialization.
- */
-static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
-{
-       clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
-#if IDESCSI_DEBUG_LOG
-       set_bit(IDESCSI_LOG_CMD, &scsi->log);
-#endif /* IDESCSI_DEBUG_LOG */
-
-       drive->pc_callback       = ide_scsi_callback;
-       drive->pc_update_buffers = NULL;
-       drive->pc_io_buffers     = ide_io_buffers;
-
-       ide_proc_register_driver(drive, scsi->driver);
-}
-
-static void ide_scsi_remove(ide_drive_t *drive)
-{
-       struct Scsi_Host *scsihost = drive->driver_data;
-       struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
-       struct gendisk *g = scsi->disk;
-
-       scsi_remove_host(scsihost);
-       ide_proc_unregister_driver(drive, scsi->driver);
-
-       ide_unregister_region(g);
-
-       drive->driver_data = NULL;
-       g->private_data = NULL;
-       put_disk(g);
-
-       ide_scsi_put(scsi);
-
-       drive->dev_flags &= ~IDE_DFLAG_SCSI;
-}
-
-static int ide_scsi_probe(ide_drive_t *);
-
-static ide_driver_t idescsi_driver = {
-       .gen_driver = {
-               .owner          = THIS_MODULE,
-               .name           = "ide-scsi",
-               .bus            = &ide_bus_type,
-       },
-       .probe                  = ide_scsi_probe,
-       .remove                 = ide_scsi_remove,
-       .version                = IDESCSI_VERSION,
-       .do_request             = idescsi_do_request,
-       .end_request            = idescsi_end_request,
-       .error                  = idescsi_atapi_error,
-#ifdef CONFIG_IDE_PROC_FS
-       .proc_entries           = ide_scsi_proc_entries,
-       .proc_devsets           = ide_scsi_proc_devsets,
-#endif
-};
-
-static int idescsi_ide_open(struct block_device *bdev, fmode_t mode)
-{
-       struct ide_scsi_obj *scsi = ide_scsi_get(bdev->bd_disk);
-
-       if (!scsi)
-               return -ENXIO;
-
-       return 0;
-}
-
-static int idescsi_ide_release(struct gendisk *disk, fmode_t mode)
-{
-       ide_scsi_put(ide_scsi_g(disk));
-       return 0;
-}
-
-static int idescsi_ide_ioctl(struct block_device *bdev, fmode_t mode,
-                       unsigned int cmd, unsigned long arg)
-{
-       struct ide_scsi_obj *scsi = ide_scsi_g(bdev->bd_disk);
-       return generic_ide_ioctl(scsi->drive, bdev, cmd, arg);
-}
-
-static struct block_device_operations idescsi_ops = {
-       .owner          = THIS_MODULE,
-       .open           = idescsi_ide_open,
-       .release        = idescsi_ide_release,
-       .locked_ioctl   = idescsi_ide_ioctl,
-};
-
-static int idescsi_slave_configure(struct scsi_device * sdp)
-{
-       /* Configure detected device */
-       sdp->use_10_for_rw = 1;
-       sdp->use_10_for_ms = 1;
-       scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun);
-       return 0;
-}
-
-static const char *idescsi_info (struct Scsi_Host *host)
-{
-       return "SCSI host adapter emulation for IDE ATAPI devices";
-}
-
-static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg)
-{
-       idescsi_scsi_t *scsi = scsihost_to_idescsi(dev->host);
-
-       if (cmd == SG_SET_TRANSFORM) {
-               if (arg)
-                       set_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
-               else
-                       clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
-               return 0;
-       } else if (cmd == SG_GET_TRANSFORM)
-               return put_user(test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform), (int __user *) arg);
-       return -EINVAL;
-}
-
-static int idescsi_queue (struct scsi_cmnd *cmd,
-               void (*done)(struct scsi_cmnd *))
-{
-       struct Scsi_Host *host = cmd->device->host;
-       idescsi_scsi_t *scsi = scsihost_to_idescsi(host);
-       ide_drive_t *drive = scsi->drive;
-       struct request *rq = NULL;
-       struct ide_atapi_pc *pc = NULL;
-       int write = cmd->sc_data_direction == DMA_TO_DEVICE;
-
-       if (!drive) {
-               scmd_printk (KERN_ERR, cmd, "drive not present\n");
-               goto abort;
-       }
-       scsi = drive_to_idescsi(drive);
-       pc = kmalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC);
-       rq = blk_get_request(drive->queue, write, GFP_ATOMIC);
-       if (rq == NULL || pc == NULL) {
-               printk (KERN_ERR "ide-scsi: %s: out of memory\n", drive->name);
-               goto abort;
-       }
-
-       memset (pc->c, 0, 12);
-       pc->flags = 0;
-       if (cmd->sc_data_direction == DMA_TO_DEVICE)
-               pc->flags |= PC_FLAG_WRITING;
-       pc->rq = rq;
-       memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
-       pc->buf = NULL;
-       pc->sg = scsi_sglist(cmd);
-       pc->sg_cnt = scsi_sg_count(cmd);
-       pc->b_count = 0;
-       pc->req_xfer = pc->buf_size = scsi_bufflen(cmd);
-       pc->scsi_cmd = cmd;
-       pc->done = done;
-       pc->timeout = jiffies + cmd->request->timeout;
-
-       if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
-               printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number);
-               ide_scsi_hex_dump(cmd->cmnd, cmd->cmd_len);
-               if (memcmp(pc->c, cmd->cmnd, cmd->cmd_len)) {
-                       printk ("ide-scsi: %s: que %lu, tsl = ", drive->name, cmd->serial_number);
-                       ide_scsi_hex_dump(pc->c, 12);
-               }
-       }
-
-       rq->special = (char *) pc;
-       rq->cmd_type = REQ_TYPE_SPECIAL;
-       spin_unlock_irq(host->host_lock);
-       rq->ref_count++;
-       memcpy(rq->cmd, pc->c, 12);
-       blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL);
-       spin_lock_irq(host->host_lock);
-       return 0;
-abort:
-       kfree (pc);
-       if (rq)
-               blk_put_request(rq);
-       cmd->result = DID_ERROR << 16;
-       done(cmd);
-       return 0;
-}
-
-static int idescsi_eh_abort (struct scsi_cmnd *cmd)
-{
-       idescsi_scsi_t *scsi  = scsihost_to_idescsi(cmd->device->host);
-       ide_drive_t    *drive = scsi->drive;
-       ide_hwif_t     *hwif;
-       ide_hwgroup_t  *hwgroup;
-       int             busy;
-       int             ret   = FAILED;
-
-       struct ide_atapi_pc *pc;
-
-       /* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */
-
-       if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
-               printk (KERN_WARNING "ide-scsi: abort called for %lu\n", cmd->serial_number);
-
-       if (!drive) {
-               printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_abort\n");
-               WARN_ON(1);
-               goto no_drive;
-       }
-
-       hwif = drive->hwif;
-       hwgroup = hwif->hwgroup;
-
-       /* First give it some more time, how much is "right" is hard to say :-(
-          FIXME - uses mdelay which causes latency? */
-       busy = ide_wait_not_busy(hwif, 100);
-       if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
-               printk (KERN_WARNING "ide-scsi: drive did%s become ready\n", busy?" not":"");
-
-       spin_lock_irq(&hwgroup->lock);
-
-       /* If there is no pc running we're done (our interrupt took care of it) */
-       pc = drive->pc;
-       if (pc == NULL) {
-               ret = SUCCESS;
-               goto ide_unlock;
-       }
-
-       /* It's somewhere in flight. Does ide subsystem agree? */
-       if (pc->scsi_cmd->serial_number == cmd->serial_number && !busy &&
-           elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) {
-               /*
-                * FIXME - not sure this condition can ever occur
-                */
-               printk (KERN_ERR "ide-scsi: cmd aborted!\n");
-
-               if (blk_sense_request(pc->rq))
-                       kfree(pc->buf);
-               /* we need to call blk_put_request twice. */
-               blk_put_request(pc->rq);
-               blk_put_request(pc->rq);
-               kfree(pc);
-               drive->pc = NULL;
-
-               ret = SUCCESS;
-       }
-
-ide_unlock:
-       spin_unlock_irq(&hwgroup->lock);
-no_drive:
-       if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
-               printk (KERN_WARNING "ide-scsi: abort returns %s\n", ret == SUCCESS?"success":"failed");
-
-       return ret;
-}
-
-static int idescsi_eh_reset (struct scsi_cmnd *cmd)
-{
-       struct request *req;
-       idescsi_scsi_t *scsi  = scsihost_to_idescsi(cmd->device->host);
-       ide_drive_t    *drive = scsi->drive;
-       ide_hwgroup_t  *hwgroup;
-       int             ready = 0;
-       int             ret   = SUCCESS;
-
-       struct ide_atapi_pc *pc;
-
-       /* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */
-
-       if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
-               printk (KERN_WARNING "ide-scsi: reset called for %lu\n", cmd->serial_number);
-
-       if (!drive) {
-               printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_reset\n");
-               WARN_ON(1);
-               return FAILED;
-       }
-
-       hwgroup = drive->hwif->hwgroup;
-
-       spin_lock_irq(cmd->device->host->host_lock);
-       spin_lock(&hwgroup->lock);
-
-       pc = drive->pc;
-       if (pc)
-               req = pc->rq;
-
-       if (pc == NULL || req != hwgroup->rq || hwgroup->handler == NULL) {
-               printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n");
-               spin_unlock(&hwgroup->lock);
-               spin_unlock_irq(cmd->device->host->host_lock);
-               return FAILED;
-       }
-
-       /* kill current request */
-       if (__blk_end_request(req, -EIO, 0))
-               BUG();
-       if (blk_sense_request(req))
-               kfree(pc->buf);
-       kfree(pc);
-       drive->pc = NULL;
-       blk_put_request(req);
-
-       /* now nuke the drive queue */
-       while ((req = elv_next_request(drive->queue))) {
-               if (__blk_end_request(req, -EIO, 0))
-                       BUG();
-       }
-
-       hwgroup->rq = NULL;
-       hwgroup->handler = NULL;
-       hwgroup->busy = 1; /* will set this to zero when ide reset finished */
-       spin_unlock(&hwgroup->lock);
-
-       ide_do_reset(drive);
-
-       /* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */
-
-       do {
-               spin_unlock_irq(cmd->device->host->host_lock);
-               msleep(50);
-               spin_lock_irq(cmd->device->host->host_lock);
-       } while ( HWGROUP(drive)->handler );
-
-       ready = drive_is_ready(drive);
-       HWGROUP(drive)->busy--;
-       if (!ready) {
-               printk (KERN_ERR "ide-scsi: reset failed!\n");
-               ret = FAILED;
-       }
-
-       spin_unlock_irq(cmd->device->host->host_lock);
-       return ret;
-}
-
-static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev,
-               sector_t capacity, int *parm)
-{
-       idescsi_scsi_t *idescsi = scsihost_to_idescsi(sdev->host);
-       ide_drive_t *drive = idescsi->drive;
-
-       if (drive->bios_cyl && drive->bios_head && drive->bios_sect) {
-               parm[0] = drive->bios_head;
-               parm[1] = drive->bios_sect;
-               parm[2] = drive->bios_cyl;
-       }
-       return 0;
-}
-
-static struct scsi_host_template idescsi_template = {
-       .module                 = THIS_MODULE,
-       .name                   = "idescsi",
-       .info                   = idescsi_info,
-       .slave_configure        = idescsi_slave_configure,
-       .ioctl                  = idescsi_ioctl,
-       .queuecommand           = idescsi_queue,
-       .eh_abort_handler       = idescsi_eh_abort,
-       .eh_host_reset_handler  = idescsi_eh_reset,
-       .bios_param             = idescsi_bios,
-       .can_queue              = 40,
-       .this_id                = -1,
-       .sg_tablesize           = 256,
-       .cmd_per_lun            = 5,
-       .max_sectors            = 128,
-       .use_clustering         = DISABLE_CLUSTERING,
-       .emulated               = 1,
-       .proc_name              = "ide-scsi",
-};
-
-static int ide_scsi_probe(ide_drive_t *drive)
-{
-       idescsi_scsi_t *idescsi;
-       struct Scsi_Host *host;
-       struct gendisk *g;
-       static int warned;
-       int err = -ENOMEM;
-       u16 last_lun;
-
-       if (!warned && drive->media == ide_cdrom) {
-               printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n");
-               warned = 1;
-       }
-
-       if (idescsi_nocd && drive->media == ide_cdrom)
-               return -ENODEV;
-
-       if (!strstr("ide-scsi", drive->driver_req) ||
-           drive->media == ide_disk ||
-           !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
-               return -ENODEV;
-
-       drive->dev_flags |= IDE_DFLAG_SCSI;
-
-       g = alloc_disk(1 << PARTN_BITS);
-       if (!g)
-               goto out_host_put;
-
-       ide_init_disk(g, drive);
-
-       host->max_id = 1;
-
-       last_lun = drive->id[ATA_ID_LAST_LUN];
-       if (last_lun)
-               debug_log("%s: last_lun=%u\n", drive->name, last_lun);
-
-       if ((last_lun & 7) != 7)
-               host->max_lun = (last_lun & 7) + 1;
-       else
-               host->max_lun = 1;
-
-       drive->driver_data = host;
-       idescsi = scsihost_to_idescsi(host);
-       idescsi->drive = drive;
-       idescsi->driver = &idescsi_driver;
-       idescsi->host = host;
-       idescsi->disk = g;
-       g->private_data = &idescsi->driver;
-       err = 0;
-       idescsi_setup(drive, idescsi);
-       g->fops = &idescsi_ops;
-       ide_register_region(g);
-       err = scsi_add_host(host, &drive->gendev);
-       if (!err) {
-               scsi_scan_host(host);
-               return 0;
-       }
-       /* fall through on error */
-       ide_unregister_region(g);
-       ide_proc_unregister_driver(drive, &idescsi_driver);
-
-       put_disk(g);
-out_host_put:
-       drive->dev_flags &= ~IDE_DFLAG_SCSI;
-       scsi_host_put(host);
-       return err;
-}
-
-static int __init init_idescsi_module(void)
-{
-       return driver_register(&idescsi_driver.gen_driver);
-}
-
-static void __exit exit_idescsi_module(void)
-{
-       driver_unregister(&idescsi_driver.gen_driver);
-}
-
-module_param(idescsi_nocd, int, 0600);
-MODULE_PARM_DESC(idescsi_nocd, "Disable handling of CD-ROMs so they may be driven by ide-cd");
-module_init(init_idescsi_module);
-module_exit(exit_idescsi_module);
-MODULE_LICENSE("GPL");
index e99c56de7f56e23a71e0a4b7daca0537c75b3012..db5ef8ae1ab95b342ecca1e5aed16f19d3e58085 100644 (file)
 # define SUPPORT_VLB_SYNC 1
 #endif
 
-/*
- * Used to indicate "no IRQ", should be a value that cannot be an IRQ
- * number.
- */
-#define IDE_NO_IRQ             (-1)
-
 typedef unsigned char  byte;   /* used everywhere */
 
 /*
@@ -403,6 +396,7 @@ enum {
  * This is used for several packet commands (not for READ/WRITE commands).
  */
 #define IDE_PC_BUFFER_SIZE     256
+#define ATAPI_WAIT_PC          (60 * HZ)
 
 struct ide_atapi_pc {
        /* actual packet bytes */
@@ -480,53 +474,53 @@ enum {
 
        /* ide-cd */
        /* Drive cannot eject the disc. */
-       IDE_AFLAG_NO_EJECT              = (1 << 3),
+       IDE_AFLAG_NO_EJECT              = (1 << 1),
        /* Drive is a pre ATAPI 1.2 drive. */
-       IDE_AFLAG_PRE_ATAPI12           = (1 << 4),
+       IDE_AFLAG_PRE_ATAPI12           = (1 << 2),
        /* TOC addresses are in BCD. */
-       IDE_AFLAG_TOCADDR_AS_BCD        = (1 << 5),
+       IDE_AFLAG_TOCADDR_AS_BCD        = (1 << 3),
        /* TOC track numbers are in BCD. */
-       IDE_AFLAG_TOCTRACKS_AS_BCD      = (1 << 6),
+       IDE_AFLAG_TOCTRACKS_AS_BCD      = (1 << 4),
        /*
         * Drive does not provide data in multiples of SECTOR_SIZE
         * when more than one interrupt is needed.
         */
-       IDE_AFLAG_LIMIT_NFRAMES         = (1 << 7),
+       IDE_AFLAG_LIMIT_NFRAMES         = (1 << 5),
        /* Saved TOC information is current. */
-       IDE_AFLAG_TOC_VALID             = (1 << 9),
+       IDE_AFLAG_TOC_VALID             = (1 << 6),
        /* We think that the drive door is locked. */
-       IDE_AFLAG_DOOR_LOCKED           = (1 << 10),
+       IDE_AFLAG_DOOR_LOCKED           = (1 << 7),
        /* SET_CD_SPEED command is unsupported. */
-       IDE_AFLAG_NO_SPEED_SELECT       = (1 << 11),
-       IDE_AFLAG_VERTOS_300_SSD        = (1 << 12),
-       IDE_AFLAG_VERTOS_600_ESD        = (1 << 13),
-       IDE_AFLAG_SANYO_3CD             = (1 << 14),
-       IDE_AFLAG_FULL_CAPS_PAGE        = (1 << 15),
-       IDE_AFLAG_PLAY_AUDIO_OK         = (1 << 16),
-       IDE_AFLAG_LE_SPEED_FIELDS       = (1 << 17),
+       IDE_AFLAG_NO_SPEED_SELECT       = (1 << 8),
+       IDE_AFLAG_VERTOS_300_SSD        = (1 << 9),
+       IDE_AFLAG_VERTOS_600_ESD        = (1 << 10),
+       IDE_AFLAG_SANYO_3CD             = (1 << 11),
+       IDE_AFLAG_FULL_CAPS_PAGE        = (1 << 12),
+       IDE_AFLAG_PLAY_AUDIO_OK         = (1 << 13),
+       IDE_AFLAG_LE_SPEED_FIELDS       = (1 << 14),
 
        /* ide-floppy */
        /* Avoid commands not supported in Clik drive */
-       IDE_AFLAG_CLIK_DRIVE            = (1 << 19),
+       IDE_AFLAG_CLIK_DRIVE            = (1 << 15),
        /* Requires BH algorithm for packets */
-       IDE_AFLAG_ZIP_DRIVE             = (1 << 20),
+       IDE_AFLAG_ZIP_DRIVE             = (1 << 16),
        /* Supports format progress report */
-       IDE_AFLAG_SRFP                  = (1 << 22),
+       IDE_AFLAG_SRFP                  = (1 << 17),
 
        /* ide-tape */
-       IDE_AFLAG_IGNORE_DSC            = (1 << 23),
+       IDE_AFLAG_IGNORE_DSC            = (1 << 18),
        /* 0 When the tape position is unknown */
-       IDE_AFLAG_ADDRESS_VALID         = (1 << 24),
+       IDE_AFLAG_ADDRESS_VALID         = (1 << 19),
        /* Device already opened */
-       IDE_AFLAG_BUSY                  = (1 << 25),
+       IDE_AFLAG_BUSY                  = (1 << 20),
        /* Attempt to auto-detect the current user block size */
-       IDE_AFLAG_DETECT_BS             = (1 << 26),
+       IDE_AFLAG_DETECT_BS             = (1 << 21),
        /* Currently on a filemark */
-       IDE_AFLAG_FILEMARK              = (1 << 27),
+       IDE_AFLAG_FILEMARK              = (1 << 22),
        /* 0 = no tape is loaded, so we don't rewind after ejecting */
-       IDE_AFLAG_MEDIUM_PRESENT        = (1 << 28),
+       IDE_AFLAG_MEDIUM_PRESENT        = (1 << 23),
 
-       IDE_AFLAG_NO_AUTOCLOSE          = (1 << 29),
+       IDE_AFLAG_NO_AUTOCLOSE          = (1 << 24),
 };
 
 /* device flags */
@@ -565,28 +559,26 @@ enum {
        IDE_DFLAG_NODMA                 = (1 << 16),
        /* powermanagment told us not to do anything, so sleep nicely */
        IDE_DFLAG_BLOCKED               = (1 << 17),
-       /* ide-scsi emulation */
-       IDE_DFLAG_SCSI                  = (1 << 18),
        /* sleeping & sleep field valid */
-       IDE_DFLAG_SLEEPING              = (1 << 19),
-       IDE_DFLAG_POST_RESET            = (1 << 20),
-       IDE_DFLAG_UDMA33_WARNED         = (1 << 21),
-       IDE_DFLAG_LBA48                 = (1 << 22),
+       IDE_DFLAG_SLEEPING              = (1 << 18),
+       IDE_DFLAG_POST_RESET            = (1 << 19),
+       IDE_DFLAG_UDMA33_WARNED         = (1 << 20),
+       IDE_DFLAG_LBA48                 = (1 << 21),
        /* status of write cache */
-       IDE_DFLAG_WCACHE                = (1 << 23),
+       IDE_DFLAG_WCACHE                = (1 << 22),
        /* used for ignoring ATA_DF */
-       IDE_DFLAG_NOWERR                = (1 << 24),
+       IDE_DFLAG_NOWERR                = (1 << 23),
        /* retrying in PIO */
-       IDE_DFLAG_DMA_PIO_RETRY         = (1 << 25),
-       IDE_DFLAG_LBA                   = (1 << 26),
+       IDE_DFLAG_DMA_PIO_RETRY         = (1 << 24),
+       IDE_DFLAG_LBA                   = (1 << 25),
        /* don't unload heads */
-       IDE_DFLAG_NO_UNLOAD             = (1 << 27),
+       IDE_DFLAG_NO_UNLOAD             = (1 << 26),
        /* heads unloaded, please don't reset port */
-       IDE_DFLAG_PARKED                = (1 << 28),
-       IDE_DFLAG_MEDIA_CHANGED         = (1 << 29),
+       IDE_DFLAG_PARKED                = (1 << 27),
+       IDE_DFLAG_MEDIA_CHANGED         = (1 << 28),
        /* write protect */
-       IDE_DFLAG_WP                    = (1 << 30),
-       IDE_DFLAG_FORMAT_IN_PROGRESS    = (1 << 31),
+       IDE_DFLAG_WP                    = (1 << 29),
+       IDE_DFLAG_FORMAT_IN_PROGRESS    = (1 << 30),
 };
 
 struct ide_drive_s {
@@ -610,8 +602,6 @@ struct ide_drive_s {
        unsigned long dev_flags;
 
        unsigned long sleep;            /* sleep until this time */
-       unsigned long service_start;    /* time we started last request */
-       unsigned long service_time;     /* service time of last request */
        unsigned long timeout;          /* max time to wait for irq */
 
        special_t       special;        /* special action flags */
@@ -879,8 +869,6 @@ typedef struct hwgroup_s {
 
                /* BOOL: protects all fields below */
        volatile int busy;
-               /* BOOL: wake us up on timer expiry */
-       unsigned int sleeping   : 1;
                /* BOOL: polling active & poll_timeout field valid */
        unsigned int polling    : 1;
 
@@ -1258,14 +1246,11 @@ int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);
 void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *);
 void ide_retry_pc(ide_drive_t *, struct gendisk *);
 
-static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc)
-{
-       return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies);
-}
+int ide_cd_expiry(ide_drive_t *);
 
-int ide_scsi_expiry(ide_drive_t *);
+int ide_cd_get_xferlen(struct request *);
 
-ide_startstop_t ide_issue_pc(ide_drive_t *, unsigned int, ide_expiry_t *);
+ide_startstop_t ide_issue_pc(ide_drive_t *);
 
 ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);
 
@@ -1287,6 +1272,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
 
 extern void ide_timer_expiry(unsigned long);
 extern irqreturn_t ide_intr(int irq, void *dev_id);
+
+static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup)
+{
+       if (hwgroup->busy)
+               return 1;
+
+       hwgroup->busy = 1;
+       /* for atari only */
+       ide_get_lock(ide_intr, hwgroup);
+
+       return 0;
+}
+
+static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)
+{
+       /* for atari only */
+       ide_release_lock();
+       hwgroup->busy = 0;
+}
+
 extern void do_ide_request(struct request_queue *);
 
 void ide_init_disk(struct gendisk *, ide_drive_t *);
@@ -1533,6 +1538,7 @@ void ide_unregister_region(struct gendisk *);
 void ide_undecoded_slave(ide_drive_t *);
 
 void ide_port_apply_params(ide_hwif_t *);
+int ide_sysfs_register_port(ide_hwif_t *);
 
 struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **);
 void ide_host_free(struct ide_host *);
@@ -1627,6 +1633,9 @@ extern struct mutex ide_cfg_mtx;
 
 #define local_irq_set(flags)   do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0)
 
+char *ide_media_string(ide_drive_t *);
+
+extern struct device_attribute ide_dev_attrs[];
 extern struct bus_type ide_bus_type;
 extern struct class *ide_port_class;