ide: remove IDE_TFLAG_NO_SELECT_MASK taskfile flag
[pandora-kernel.git] / drivers / ide / ide-tape.c
index 8883eea..cc7991c 100644 (file)
@@ -72,26 +72,6 @@ enum {
 #endif
 
 /**************************** Tunable parameters *****************************/
-
-
-/*
- * Pipelined mode parameters.
- *
- * We try to use the minimum number of stages which is enough to keep the tape
- * constantly streaming. To accomplish that, we implement a feedback loop around
- * the maximum number of stages:
- *
- * We start from MIN maximum stages (we will not even use MIN stages if we don't
- * need them), increment it by RATE*(MAX-MIN) whenever we sense that the
- * pipeline is empty, until we reach the optimum value or until we reach MAX.
- *
- * Setting the following parameter to 0 is illegal: the pipelined mode cannot be
- * disabled (idetape_calculate_speeds() divides by tape->max_stages.)
- */
-#define IDETAPE_MIN_PIPELINE_STAGES      1
-#define IDETAPE_MAX_PIPELINE_STAGES    400
-#define IDETAPE_INCREASE_STAGES_RATE    20
-
 /*
  * After each failed packet command we issue a request sense command and retry
  * the packet command IDETAPE_MAX_PC_RETRIES times.
@@ -224,28 +204,17 @@ enum {
        /* 0 When the tape position is unknown */
        IDETAPE_FLAG_ADDRESS_VALID      = (1 << 1),
        /* Device already opened */
-       IDETAPE_FLAG_BUSY                       = (1 << 2),
-       /* Error detected in a pipeline stage */
-       IDETAPE_FLAG_PIPELINE_ERR       = (1 << 3),
+       IDETAPE_FLAG_BUSY               = (1 << 2),
        /* Attempt to auto-detect the current user block size */
-       IDETAPE_FLAG_DETECT_BS          = (1 << 4),
+       IDETAPE_FLAG_DETECT_BS          = (1 << 3),
        /* Currently on a filemark */
-       IDETAPE_FLAG_FILEMARK           = (1 << 5),
+       IDETAPE_FLAG_FILEMARK           = (1 << 4),
        /* DRQ interrupt device */
-       IDETAPE_FLAG_DRQ_INTERRUPT      = (1 << 6),
-       /* pipeline active */
-       IDETAPE_FLAG_PIPELINE_ACTIVE    = (1 << 7),
+       IDETAPE_FLAG_DRQ_INTERRUPT      = (1 << 5),
        /* 0 = no tape is loaded, so we don't rewind after ejecting */
-       IDETAPE_FLAG_MEDIUM_PRESENT     = (1 << 8),
+       IDETAPE_FLAG_MEDIUM_PRESENT     = (1 << 6),
 };
 
-/* A pipeline stage. */
-typedef struct idetape_stage_s {
-       struct request rq;                      /* The corresponding request */
-       struct idetape_bh *bh;                  /* The data buffers */
-       struct idetape_stage_s *next;           /* Pointer to the next stage */
-} idetape_stage_t;
-
 /*
  * Most of our global data which we need to save even as we leave the driver due
  * to an interrupt or a timer event is stored in the struct defined below.
@@ -289,9 +258,7 @@ typedef struct ide_tape_obj {
         * While polling for DSC we use postponed_rq to postpone the current
         * request so that ide.c will be able to service pending requests on the
         * other device. Note that at most we will have only one DSC (usually
-        * data transfer) request in the device request queue. Additional
-        * requests can be queued in our internal pipeline, but they will be
-        * visible to ide.c only one at a time.
+        * data transfer) request in the device request queue.
         */
        struct request *postponed_rq;
        /* The time in which we started polling for DSC */
@@ -331,41 +298,20 @@ typedef struct ide_tape_obj {
         * At most, there is only one ide-tape originated data transfer request
         * in the device request queue. This allows ide.c to easily service
         * requests from the other device when we postpone our active request.
-        * In the pipelined operation mode, we use our internal pipeline
-        * structure to hold more data requests. The data buffer size is chosen
-        * based on the tape's recommendation.
         */
-       /* ptr to the request which is waiting in the device request queue */
-       struct request *active_data_rq;
+
        /* Data buffer size chosen based on the tape's recommendation */
-       int stage_size;
-       idetape_stage_t *merge_stage;
-       int merge_stage_size;
+       int buffer_size;
+       /* merge buffer */
+       struct idetape_bh *merge_bh;
+       /* size of the merge buffer */
+       int merge_bh_size;
+       /* pointer to current buffer head within the merge buffer */
        struct idetape_bh *bh;
        char *b_data;
        int b_count;
 
-       /*
-        * Pipeline parameters.
-        *
-        * To accomplish non-pipelined mode, we simply set the following
-        * variables to zero (or NULL, where appropriate).
-        */
-       /* Number of currently used stages */
-       int nr_stages;
-       /* Number of pending stages */
-       int nr_pending_stages;
-       /* We will not allocate more than this number of stages */
-       int max_stages, min_pipeline, max_pipeline;
-       /* The first stage which will be removed from the pipeline */
-       idetape_stage_t *first_stage;
-       /* The currently active stage */
-       idetape_stage_t *active_stage;
-       /* Will be serviced after the currently active request */
-       idetape_stage_t *next_stage;
-       /* New requests will be added to the pipeline here */
-       idetape_stage_t *last_stage;
-       int pages_per_stage;
+       int pages_per_buffer;
        /* Wasted space in each stage */
        int excess_bh_size;
 
@@ -386,45 +332,6 @@ typedef struct ide_tape_obj {
        /* the tape is write protected (hardware or opened as read-only) */
        char write_prot;
 
-       /*
-        * Limit the number of times a request can be postponed, to avoid an
-        * infinite postpone deadlock.
-        */
-       int postpone_cnt;
-
-       /*
-        * Measures number of frames:
-        *
-        * 1. written/read to/from the driver pipeline (pipeline_head).
-        * 2. written/read to/from the tape buffers (idetape_bh).
-        * 3. written/read by the tape to/from the media (tape_head).
-        */
-       int pipeline_head;
-       int buffer_head;
-       int tape_head;
-       int last_tape_head;
-
-       /* Speed control at the tape buffers input/output */
-       unsigned long insert_time;
-       int insert_size;
-       int insert_speed;
-       int max_insert_speed;
-       int measure_insert_time;
-
-       /* Speed regulation negative feedback loop */
-       int speed_control;
-       int pipeline_head_speed;
-       int controlled_pipeline_head_speed;
-       int uncontrolled_pipeline_head_speed;
-       int controlled_last_pipeline_head;
-       unsigned long uncontrolled_pipeline_head_time;
-       unsigned long controlled_pipeline_head_time;
-       int controlled_previous_pipeline_head;
-       int uncontrolled_previous_pipeline_head;
-       unsigned long controlled_previous_head_time;
-       unsigned long uncontrolled_previous_head_time;
-       int restart_speed_control_req;
-
        u32 debug_mask;
 } idetape_tape_t;
 
@@ -488,13 +395,13 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
                if (bh == NULL) {
                        printk(KERN_ERR "ide-tape: bh == NULL in "
                                "idetape_input_buffers\n");
-                       ide_atapi_discard_data(drive, bcount);
+                       ide_pad_transfer(drive, 0, bcount);
                        return;
                }
                count = min(
                        (unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
                        bcount);
-               HWIF(drive)->atapi_input_bytes(drive, bh->b_data +
+               drive->hwif->input_data(drive, NULL, bh->b_data +
                                        atomic_read(&bh->b_count), count);
                bcount -= count;
                atomic_add(count, &bh->b_count);
@@ -520,7 +427,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
                        return;
                }
                count = min((unsigned int)pc->b_count, (unsigned int)bcount);
-               HWIF(drive)->atapi_output_bytes(drive, pc->b_data, count);
+               drive->hwif->output_data(drive, NULL, pc->b_data, count);
                bcount -= count;
                pc->b_data += count;
                pc->b_count -= count;
@@ -631,7 +538,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
        if (pc->flags & PC_FLAG_DMA_ERROR) {
                pc->xferred = pc->req_xfer -
                        tape->blk_size *
-                       be32_to_cpu(get_unaligned((u32 *)&sense[3]));
+                       get_unaligned_be32(&sense[3]);
                idetape_update_buffers(pc);
        }
 
@@ -672,128 +579,36 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
        }
 }
 
-static void idetape_activate_next_stage(ide_drive_t *drive)
+/* Free data buffers completely. */
+static void ide_tape_kfree_buffer(idetape_tape_t *tape)
 {
-       idetape_tape_t *tape = drive->driver_data;
-       idetape_stage_t *stage = tape->next_stage;
-       struct request *rq = &stage->rq;
+       struct idetape_bh *prev_bh, *bh = tape->merge_bh;
 
-       debug_log(DBG_PROCS, "Enter %s\n", __func__);
+       while (bh) {
+               u32 size = bh->b_size;
 
-       if (stage == NULL) {
-               printk(KERN_ERR "ide-tape: bug: Trying to activate a non"
-                               " existing stage\n");
-               return;
-       }
+               while (size) {
+                       unsigned int order = fls(size >> PAGE_SHIFT)-1;
 
-       rq->rq_disk = tape->disk;
-       rq->buffer = NULL;
-       rq->special = (void *)stage->bh;
-       tape->active_data_rq = rq;
-       tape->active_stage = stage;
-       tape->next_stage = stage->next;
-}
-
-/* Free a stage along with its related buffers completely. */
-static void __idetape_kfree_stage(idetape_stage_t *stage)
-{
-       struct idetape_bh *prev_bh, *bh = stage->bh;
-       int size;
-
-       while (bh != NULL) {
-               if (bh->b_data != NULL) {
-                       size = (int) bh->b_size;
-                       while (size > 0) {
-                               free_page((unsigned long) bh->b_data);
-                               size -= PAGE_SIZE;
-                               bh->b_data += PAGE_SIZE;
-                       }
+                       if (bh->b_data)
+                               free_pages((unsigned long)bh->b_data, order);
+
+                       size &= (order-1);
+                       bh->b_data += (1 << order) * PAGE_SIZE;
                }
                prev_bh = bh;
                bh = bh->b_reqnext;
                kfree(prev_bh);
        }
-       kfree(stage);
-}
-
-static void idetape_kfree_stage(idetape_tape_t *tape, idetape_stage_t *stage)
-{
-       __idetape_kfree_stage(stage);
-}
-
-/*
- * Remove tape->first_stage from the pipeline. The caller should avoid race
- * conditions.
- */
-static void idetape_remove_stage_head(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-       idetape_stage_t *stage;
-
-       debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
-       if (tape->first_stage == NULL) {
-               printk(KERN_ERR "ide-tape: bug: tape->first_stage is NULL\n");
-               return;
-       }
-       if (tape->active_stage == tape->first_stage) {
-               printk(KERN_ERR "ide-tape: bug: Trying to free our active "
-                               "pipeline stage\n");
-               return;
-       }
-       stage = tape->first_stage;
-       tape->first_stage = stage->next;
-       idetape_kfree_stage(tape, stage);
-       tape->nr_stages--;
-       if (tape->first_stage == NULL) {
-               tape->last_stage = NULL;
-               if (tape->next_stage != NULL)
-                       printk(KERN_ERR "ide-tape: bug: tape->next_stage !="
-                                       " NULL\n");
-               if (tape->nr_stages)
-                       printk(KERN_ERR "ide-tape: bug: nr_stages should be 0 "
-                                       "now\n");
-       }
-}
-
-/*
- * This will free all the pipeline stages starting from new_last_stage->next
- * to the end of the list, and point tape->last_stage to new_last_stage.
- */
-static void idetape_abort_pipeline(ide_drive_t *drive,
-                                  idetape_stage_t *new_last_stage)
-{
-       idetape_tape_t *tape = drive->driver_data;
-       idetape_stage_t *stage = new_last_stage->next;
-       idetape_stage_t *nstage;
-
-       debug_log(DBG_PROCS, "%s: Enter %s\n", tape->name, __func__);
-
-       while (stage) {
-               nstage = stage->next;
-               idetape_kfree_stage(tape, stage);
-               --tape->nr_stages;
-               --tape->nr_pending_stages;
-               stage = nstage;
-       }
-       if (new_last_stage)
-               new_last_stage->next = NULL;
-       tape->last_stage = new_last_stage;
-       tape->next_stage = NULL;
+       kfree(tape->merge_bh);
 }
 
-/*
- * Finish servicing a request and insert a pending pipeline request into the
- * main device queue.
- */
 static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
 {
        struct request *rq = HWGROUP(drive)->rq;
        idetape_tape_t *tape = drive->driver_data;
        unsigned long flags;
        int error;
-       int remove_stage = 0;
-       idetape_stage_t *active_stage;
 
        debug_log(DBG_PROCS, "Enter %s\n", __func__);
 
@@ -813,58 +628,8 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
 
        spin_lock_irqsave(&tape->lock, flags);
 
-       /* The request was a pipelined data transfer request */
-       if (tape->active_data_rq == rq) {
-               active_stage = tape->active_stage;
-               tape->active_stage = NULL;
-               tape->active_data_rq = NULL;
-               tape->nr_pending_stages--;
-               if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
-                       remove_stage = 1;
-                       if (error) {
-                               set_bit(IDETAPE_FLAG_PIPELINE_ERR,
-                                       &tape->flags);
-                               if (error == IDETAPE_ERROR_EOD)
-                                       idetape_abort_pipeline(drive,
-                                                               active_stage);
-                       }
-               } else if (rq->cmd[0] & REQ_IDETAPE_READ) {
-                       if (error == IDETAPE_ERROR_EOD) {
-                               set_bit(IDETAPE_FLAG_PIPELINE_ERR,
-                                       &tape->flags);
-                               idetape_abort_pipeline(drive, active_stage);
-                       }
-               }
-               if (tape->next_stage != NULL) {
-                       idetape_activate_next_stage(drive);
-
-                       /* Insert the next request into the request queue. */
-                       (void)ide_do_drive_cmd(drive, tape->active_data_rq,
-                                               ide_end);
-               } else if (!error) {
-                       /*
-                        * This is a part of the feedback loop which tries to
-                        * find the optimum number of stages. We are starting
-                        * from a minimum maximum number of stages, and if we
-                        * sense that the pipeline is empty, we try to increase
-                        * it, until we reach the user compile time memory
-                        * limit.
-                        */
-                       int i = (tape->max_pipeline - tape->min_pipeline) / 10;
-
-                       tape->max_stages += max(i, 1);
-                       tape->max_stages = max(tape->max_stages,
-                                               tape->min_pipeline);
-                       tape->max_stages = min(tape->max_stages,
-                                               tape->max_pipeline);
-               }
-       }
        ide_end_drive_cmd(drive, 0, 0);
 
-       if (remove_stage)
-               idetape_remove_stage_head(drive);
-       if (tape->active_data_rq == NULL)
-               clear_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags);
        spin_unlock_irqrestore(&tape->lock, flags);
        return 0;
 }
@@ -897,7 +662,7 @@ static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
 
 static void idetape_init_rq(struct request *rq, u8 cmd)
 {
-       memset(rq, 0, sizeof(*rq));
+       blk_rq_init(NULL, rq);
        rq->cmd_type = REQ_TYPE_SPECIAL;
        rq->cmd[0] = cmd;
 }
@@ -923,6 +688,7 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
        struct ide_tape_obj *tape = drive->driver_data;
 
        idetape_init_rq(rq, REQ_IDETAPE_PC1);
+       rq->cmd_flags |= REQ_PREEMPT;
        rq->buffer = (char *) pc;
        rq->rq_disk = tape->disk;
        (void) ide_do_drive_cmd(drive, rq, ide_preempt);
@@ -1081,10 +847,10 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
                return ide_do_reset(drive);
        }
        /* Get the number of bytes to transfer on this interrupt. */
-       bcount = (hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]) << 8) |
-                 hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]);
+       bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
+                 hwif->INB(hwif->io_ports.lbam_addr);
 
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+       ireason = hwif->INB(hwif->io_ports.nsect_addr);
 
        if (ireason & CD) {
                printk(KERN_ERR "ide-tape: CoD != 0 in %s\n", __func__);
@@ -1106,7 +872,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
                                printk(KERN_ERR "ide-tape: The tape wants to "
                                        "send us more data than expected "
                                        "- discarding data\n");
-                               ide_atapi_discard_data(drive, bcount);
+                               ide_pad_transfer(drive, 0, bcount);
                                ide_set_handler(drive, &idetape_pc_intr,
                                                IDETAPE_WAIT_CMD, NULL);
                                return ide_started;
@@ -1115,16 +881,16 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
                                "data than expected - allowing transfer\n");
                }
                iobuf = &idetape_input_buffers;
-               xferfunc = hwif->atapi_input_bytes;
+               xferfunc = hwif->input_data;
        } else {
                iobuf = &idetape_output_buffers;
-               xferfunc = hwif->atapi_output_bytes;
+               xferfunc = hwif->output_data;
        }
 
        if (pc->bh)
                iobuf(drive, pc, bcount);
        else
-               xferfunc(drive, pc->cur_pos, bcount);
+               xferfunc(drive, NULL, pc->cur_pos, bcount);
 
        /* Update the current position */
        pc->xferred += bcount;
@@ -1188,12 +954,12 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
                                "yet DRQ isn't asserted\n");
                return startstop;
        }
-       ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+       ireason = hwif->INB(hwif->io_ports.nsect_addr);
        while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) {
                printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing "
                                "a packet command, retrying\n");
                udelay(100);
-               ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]);
+               ireason = hwif->INB(hwif->io_ports.nsect_addr);
                if (retries == 0) {
                        printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while "
                                        "issuing a packet command, ignoring\n");
@@ -1214,7 +980,8 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
                hwif->dma_ops->dma_start(drive);
 #endif
        /* Send the actual packet */
-       HWIF(drive)->atapi_output_bytes(drive, pc->c, 12);
+       hwif->output_data(drive, NULL, pc->c, 12);
+
        return ide_started;
 }
 
@@ -1279,8 +1046,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
        if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma)
                dma_ok = !hwif->dma_ops->dma_setup(drive);
 
-       ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK |
-                          IDE_TFLAG_OUT_DEVICE, bcount, dma_ok);
+       ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma_ok);
 
        if (dma_ok)
                /* Will begin DMA later */
@@ -1290,7 +1056,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
                                    IDETAPE_WAIT_CMD, NULL);
                return ide_started;
        } else {
-               hwif->OUTB(WIN_PACKETCMD, hwif->io_ports[IDE_COMMAND_OFFSET]);
+               ide_execute_pkt_cmd(drive);
                return idetape_transfer_pc(drive);
        }
 }
@@ -1333,69 +1099,6 @@ static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
        pc->idetape_callback = &idetape_pc_callback;
 }
 
-static void idetape_calculate_speeds(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-
-       if (time_after(jiffies,
-                       tape->controlled_pipeline_head_time + 120 * HZ)) {
-               tape->controlled_previous_pipeline_head =
-                       tape->controlled_last_pipeline_head;
-               tape->controlled_previous_head_time =
-                       tape->controlled_pipeline_head_time;
-               tape->controlled_last_pipeline_head = tape->pipeline_head;
-               tape->controlled_pipeline_head_time = jiffies;
-       }
-       if (time_after(jiffies, tape->controlled_pipeline_head_time + 60 * HZ))
-               tape->controlled_pipeline_head_speed = (tape->pipeline_head -
-                               tape->controlled_last_pipeline_head) * 32 * HZ /
-                               (jiffies - tape->controlled_pipeline_head_time);
-       else if (time_after(jiffies, tape->controlled_previous_head_time))
-               tape->controlled_pipeline_head_speed = (tape->pipeline_head -
-                               tape->controlled_previous_pipeline_head) * 32 *
-                       HZ / (jiffies - tape->controlled_previous_head_time);
-
-       if (tape->nr_pending_stages < tape->max_stages/*- 1 */) {
-               /* -1 for read mode error recovery */
-               if (time_after(jiffies, tape->uncontrolled_previous_head_time +
-                                       10 * HZ)) {
-                       tape->uncontrolled_pipeline_head_time = jiffies;
-                       tape->uncontrolled_pipeline_head_speed =
-                               (tape->pipeline_head -
-                                tape->uncontrolled_previous_pipeline_head) *
-                               32 * HZ / (jiffies -
-                                       tape->uncontrolled_previous_head_time);
-               }
-       } else {
-               tape->uncontrolled_previous_head_time = jiffies;
-               tape->uncontrolled_previous_pipeline_head = tape->pipeline_head;
-               if (time_after(jiffies, tape->uncontrolled_pipeline_head_time +
-                                       30 * HZ))
-                       tape->uncontrolled_pipeline_head_time = jiffies;
-
-       }
-       tape->pipeline_head_speed = max(tape->uncontrolled_pipeline_head_speed,
-                                       tape->controlled_pipeline_head_speed);
-
-       if (tape->speed_control == 1) {
-               if (tape->nr_pending_stages >= tape->max_stages / 2)
-                       tape->max_insert_speed = tape->pipeline_head_speed +
-                               (1100 - tape->pipeline_head_speed) * 2 *
-                               (tape->nr_pending_stages - tape->max_stages / 2)
-                               / tape->max_stages;
-               else
-                       tape->max_insert_speed = 500 +
-                               (tape->pipeline_head_speed - 500) * 2 *
-                               tape->nr_pending_stages / tape->max_stages;
-
-               if (tape->nr_pending_stages >= tape->max_stages * 99 / 100)
-                       tape->max_insert_speed = 5000;
-       } else
-               tape->max_insert_speed = tape->speed_control;
-
-       tape->max_insert_speed = max(tape->max_insert_speed, 500);
-}
-
 static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
@@ -1430,17 +1133,7 @@ static ide_startstop_t idetape_rw_callback(ide_drive_t *drive)
        int blocks = tape->pc->xferred / tape->blk_size;
 
        tape->avg_size += blocks * tape->blk_size;
-       tape->insert_size += blocks * tape->blk_size;
-       if (tape->insert_size > 1024 * 1024)
-               tape->measure_insert_time = 1;
-       if (tape->measure_insert_time) {
-               tape->measure_insert_time = 0;
-               tape->insert_time = jiffies;
-               tape->insert_size = 0;
-       }
-       if (time_after(jiffies, tape->insert_time))
-               tape->insert_speed = tape->insert_size / 1024 * HZ /
-                                       (jiffies - tape->insert_time);
+
        if (time_after_eq(jiffies, tape->avg_time + HZ)) {
                tape->avg_speed = tape->avg_size * HZ /
                                (jiffies - tape->avg_time) / 1024;
@@ -1473,7 +1166,7 @@ static void idetape_create_read_cmd(idetape_tape_t *tape,
        pc->buf = NULL;
        pc->buf_size = length * tape->blk_size;
        pc->req_xfer = pc->buf_size;
-       if (pc->req_xfer == tape->stage_size)
+       if (pc->req_xfer == tape->buffer_size)
                pc->flags |= PC_FLAG_DMA_RECOMMENDED;
 }
 
@@ -1493,7 +1186,7 @@ static void idetape_create_write_cmd(idetape_tape_t *tape,
        pc->buf = NULL;
        pc->buf_size = length * tape->blk_size;
        pc->req_xfer = pc->buf_size;
-       if (pc->req_xfer == tape->stage_size)
+       if (pc->req_xfer == tape->buffer_size)
                pc->flags |= PC_FLAG_DMA_RECOMMENDED;
 }
 
@@ -1545,10 +1238,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                drive->post_reset = 0;
        }
 
-       if (time_after(jiffies, tape->insert_time))
-               tape->insert_speed = tape->insert_size / 1024 * HZ /
-                                       (jiffies - tape->insert_time);
-       idetape_calculate_speeds(drive);
        if (!test_and_clear_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags) &&
            (stat & SEEK_STAT) == 0) {
                if (postponed_rq == NULL) {
@@ -1572,16 +1261,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                return ide_stopped;
        }
        if (rq->cmd[0] & REQ_IDETAPE_READ) {
-               tape->buffer_head++;
-               tape->postpone_cnt = 0;
                pc = idetape_next_pc_storage(drive);
                idetape_create_read_cmd(tape, pc, rq->current_nr_sectors,
                                        (struct idetape_bh *)rq->special);
                goto out;
        }
        if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
-               tape->buffer_head++;
-               tape->postpone_cnt = 0;
                pc = idetape_next_pc_storage(drive);
                idetape_create_write_cmd(tape, pc, rq->current_nr_sectors,
                                         (struct idetape_bh *)rq->special);
@@ -1602,97 +1287,91 @@ out:
        return idetape_issue_pc(drive, pc);
 }
 
-/* Pipeline related functions */
-
 /*
- * The function below uses __get_free_page to allocate a pipeline stage, along
- * with all the necessary small buffers which together make a buffer of size
- * tape->stage_size (or a bit more). We attempt to combine sequential pages as
+ * The function below uses __get_free_pages to allocate a data buffer of size
+ * tape->buffer_size (or a bit more). We attempt to combine sequential pages as
  * much as possible.
  *
- * It returns a pointer to the new allocated stage, or NULL if we can't (or
- * don't want to) allocate a stage.
- *
- * Pipeline stages are optional and are used to increase performance. If we
- * can't allocate them, we'll manage without them.
+ * It returns a pointer to the newly allocated buffer, or NULL in case of
+ * failure.
  */
-static idetape_stage_t *__idetape_kmalloc_stage(idetape_tape_t *tape, int full,
-                                               int clear)
+static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape,
+                                                 int full, int clear)
 {
-       idetape_stage_t *stage;
-       struct idetape_bh *prev_bh, *bh;
-       int pages = tape->pages_per_stage;
+       struct idetape_bh *prev_bh, *bh, *merge_bh;
+       int pages = tape->pages_per_buffer;
+       unsigned int order, b_allocd;
        char *b_data = NULL;
 
-       stage = kmalloc(sizeof(idetape_stage_t), GFP_KERNEL);
-       if (!stage)
-               return NULL;
-       stage->next = NULL;
-
-       stage->bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
-       bh = stage->bh;
+       merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
+       bh = merge_bh;
        if (bh == NULL)
                goto abort;
-       bh->b_reqnext = NULL;
-       bh->b_data = (char *) __get_free_page(GFP_KERNEL);
+
+       order = fls(pages) - 1;
+       bh->b_data = (char *) __get_free_pages(GFP_KERNEL, order);
        if (!bh->b_data)
                goto abort;
+       b_allocd = (1 << order) * PAGE_SIZE;
+       pages &= (order-1);
+
        if (clear)
-               memset(bh->b_data, 0, PAGE_SIZE);
-       bh->b_size = PAGE_SIZE;
+               memset(bh->b_data, 0, b_allocd);
+       bh->b_reqnext = NULL;
+       bh->b_size = b_allocd;
        atomic_set(&bh->b_count, full ? bh->b_size : 0);
 
-       while (--pages) {
-               b_data = (char *) __get_free_page(GFP_KERNEL);
+       while (pages) {
+               order = fls(pages) - 1;
+               b_data = (char *) __get_free_pages(GFP_KERNEL, order);
                if (!b_data)
                        goto abort;
+               b_allocd = (1 << order) * PAGE_SIZE;
+
                if (clear)
-                       memset(b_data, 0, PAGE_SIZE);
-               if (bh->b_data == b_data + PAGE_SIZE) {
-                       bh->b_size += PAGE_SIZE;
-                       bh->b_data -= PAGE_SIZE;
+                       memset(b_data, 0, b_allocd);
+
+               /* newly allocated page frames below buffer header or ...*/
+               if (bh->b_data == b_data + b_allocd) {
+                       bh->b_size += b_allocd;
+                       bh->b_data -= b_allocd;
                        if (full)
-                               atomic_add(PAGE_SIZE, &bh->b_count);
+                               atomic_add(b_allocd, &bh->b_count);
                        continue;
                }
+               /* they are above the header */
                if (b_data == bh->b_data + bh->b_size) {
-                       bh->b_size += PAGE_SIZE;
+                       bh->b_size += b_allocd;
                        if (full)
-                               atomic_add(PAGE_SIZE, &bh->b_count);
+                               atomic_add(b_allocd, &bh->b_count);
                        continue;
                }
                prev_bh = bh;
                bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
                if (!bh) {
-                       free_page((unsigned long) b_data);
+                       free_pages((unsigned long) b_data, order);
                        goto abort;
                }
                bh->b_reqnext = NULL;
                bh->b_data = b_data;
-               bh->b_size = PAGE_SIZE;
+               bh->b_size = b_allocd;
                atomic_set(&bh->b_count, full ? bh->b_size : 0);
                prev_bh->b_reqnext = bh;
+
+               pages &= (order-1);
        }
+
        bh->b_size -= tape->excess_bh_size;
        if (full)
                atomic_sub(tape->excess_bh_size, &bh->b_count);
-       return stage;
+       return merge_bh;
 abort:
-       __idetape_kfree_stage(stage);
+       ide_tape_kfree_buffer(tape);
        return NULL;
 }
 
-static idetape_stage_t *idetape_kmalloc_stage(idetape_tape_t *tape)
-{
-       debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
-       if (tape->nr_stages >= tape->max_stages)
-               return NULL;
-       return __idetape_kmalloc_stage(tape, 0, 0);
-}
-
 static int idetape_copy_stage_from_user(idetape_tape_t *tape,
-               idetape_stage_t *stage, const char __user *buf, int n)
+                                       const char __user *buf, int n)
 {
        struct idetape_bh *bh = tape->bh;
        int count;
@@ -1724,7 +1403,7 @@ static int idetape_copy_stage_from_user(idetape_tape_t *tape,
 }
 
 static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf,
-               idetape_stage_t *stage, int n)
+                                     int n)
 {
        struct idetape_bh *bh = tape->bh;
        int count;
@@ -1755,11 +1434,11 @@ static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf,
        return ret;
 }
 
-static void idetape_init_merge_stage(idetape_tape_t *tape)
+static void idetape_init_merge_buffer(idetape_tape_t *tape)
 {
-       struct idetape_bh *bh = tape->merge_stage->bh;
+       struct idetape_bh *bh = tape->merge_bh;
+       tape->bh = tape->merge_bh;
 
-       tape->bh = bh;
        if (tape->chrdev_dir == IDETAPE_DIR_WRITE)
                atomic_set(&bh->b_count, 0);
        else {
@@ -1768,61 +1447,6 @@ static void idetape_init_merge_stage(idetape_tape_t *tape)
        }
 }
 
-static void idetape_switch_buffers(idetape_tape_t *tape, idetape_stage_t *stage)
-{
-       struct idetape_bh *tmp;
-
-       tmp = stage->bh;
-       stage->bh = tape->merge_stage->bh;
-       tape->merge_stage->bh = tmp;
-       idetape_init_merge_stage(tape);
-}
-
-/* Add a new stage at the end of the pipeline. */
-static void idetape_add_stage_tail(ide_drive_t *drive, idetape_stage_t *stage)
-{
-       idetape_tape_t *tape = drive->driver_data;
-       unsigned long flags;
-
-       debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
-       spin_lock_irqsave(&tape->lock, flags);
-       stage->next = NULL;
-       if (tape->last_stage != NULL)
-               tape->last_stage->next = stage;
-       else
-               tape->first_stage = stage;
-               tape->next_stage  = stage;
-       tape->last_stage = stage;
-       if (tape->next_stage == NULL)
-               tape->next_stage = tape->last_stage;
-       tape->nr_stages++;
-       tape->nr_pending_stages++;
-       spin_unlock_irqrestore(&tape->lock, flags);
-}
-
-/* Install a completion in a pending request and sleep until it is serviced. The
- * caller should ensure that the request will not be serviced before we install
- * the completion (usually by disabling interrupts).
- */
-static void idetape_wait_for_request(ide_drive_t *drive, struct request *rq)
-{
-       DECLARE_COMPLETION_ONSTACK(wait);
-       idetape_tape_t *tape = drive->driver_data;
-
-       if (rq == NULL || !blk_special_request(rq)) {
-               printk(KERN_ERR "ide-tape: bug: Trying to sleep on non-valid"
-                                " request\n");
-               return;
-       }
-       rq->end_io_data = &wait;
-       rq->end_io = blk_end_sync_rq;
-       spin_unlock_irq(&tape->lock);
-       wait_for_completion(&wait);
-       /* The stage and its struct request have been deallocated */
-       spin_lock_irq(&tape->lock);
-}
-
 static ide_startstop_t idetape_read_position_callback(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
@@ -1891,15 +1515,19 @@ static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
  * to the request list without waiting for it to be serviced! In that case, we
  * usually use idetape_queue_pc_head().
  */
-static int __idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
+static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
 {
        struct ide_tape_obj *tape = drive->driver_data;
-       struct request rq;
+       struct request *rq;
+       int error;
 
-       idetape_init_rq(&rq, REQ_IDETAPE_PC1);
-       rq.buffer = (char *) pc;
-       rq.rq_disk = tape->disk;
-       return ide_do_drive_cmd(drive, &rq, ide_wait);
+       rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+       rq->cmd_type = REQ_TYPE_SPECIAL;
+       rq->cmd[0] = REQ_IDETAPE_PC1;
+       rq->buffer = (char *)pc;
+       error = blk_execute_rq(drive->queue, tape->disk, rq, 0);
+       blk_put_request(rq);
+       return error;
 }
 
 static void idetape_create_load_unload_cmd(ide_drive_t *drive,
@@ -1923,7 +1551,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
        timeout += jiffies;
        while (time_before(jiffies, timeout)) {
                idetape_create_test_unit_ready_cmd(&pc);
-               if (!__idetape_queue_pc_tail(drive, &pc))
+               if (!idetape_queue_pc_tail(drive, &pc))
                        return 0;
                if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2)
                    || (tape->asc == 0x3A)) {
@@ -1932,7 +1560,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
                                return -ENOMEDIUM;
                        idetape_create_load_unload_cmd(drive, &pc,
                                                        IDETAPE_LU_LOAD_MASK);
-                       __idetape_queue_pc_tail(drive, &pc);
+                       idetape_queue_pc_tail(drive, &pc);
                        load_attempted = 1;
                /* not about to be ready */
                } else if (!(tape->sense_key == 2 && tape->asc == 4 &&
@@ -1943,11 +1571,6 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
        return -EIO;
 }
 
-static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
-{
-       return __idetape_queue_pc_tail(drive, pc);
-}
-
 static int idetape_flush_tape_buffers(ide_drive_t *drive)
 {
        struct ide_atapi_pc pc;
@@ -2013,50 +1636,21 @@ static int idetape_create_prevent_cmd(ide_drive_t *drive,
        return 1;
 }
 
-static int __idetape_discard_read_pipeline(ide_drive_t *drive)
+static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
-       unsigned long flags;
-       int cnt;
 
        if (tape->chrdev_dir != IDETAPE_DIR_READ)
-               return 0;
+               return;
 
-       /* Remove merge stage. */
-       cnt = tape->merge_stage_size / tape->blk_size;
-       if (test_and_clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
-               ++cnt;          /* Filemarks count as 1 sector */
-       tape->merge_stage_size = 0;
-       if (tape->merge_stage != NULL) {
-               __idetape_kfree_stage(tape->merge_stage);
-               tape->merge_stage = NULL;
+       clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags);
+       tape->merge_bh_size = 0;
+       if (tape->merge_bh != NULL) {
+               ide_tape_kfree_buffer(tape);
+               tape->merge_bh = NULL;
        }
 
-       /* Clear pipeline flags. */
-       clear_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags);
        tape->chrdev_dir = IDETAPE_DIR_NONE;
-
-       /* Remove pipeline stages. */
-       if (tape->first_stage == NULL)
-               return 0;
-
-       spin_lock_irqsave(&tape->lock, flags);
-       tape->next_stage = NULL;
-       if (test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags))
-               idetape_wait_for_request(drive, tape->active_data_rq);
-       spin_unlock_irqrestore(&tape->lock, flags);
-
-       while (tape->first_stage != NULL) {
-               struct request *rq_ptr = &tape->first_stage->rq;
-
-               cnt += rq_ptr->nr_sectors - rq_ptr->current_nr_sectors;
-               if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK)
-                       ++cnt;
-               idetape_remove_stage_head(drive);
-       }
-       tape->nr_pending_stages = 0;
-       tape->max_stages = tape->min_pipeline;
-       return cnt;
 }
 
 /*
@@ -2073,7 +1667,7 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
        struct ide_atapi_pc pc;
 
        if (tape->chrdev_dir == IDETAPE_DIR_READ)
-               __idetape_discard_read_pipeline(drive);
+               __ide_tape_discard_merge_buffer(drive);
        idetape_wait_ready(drive, 60 * 5 * HZ);
        idetape_create_locate_cmd(drive, &pc, block, partition, skip);
        retval = idetape_queue_pc_tail(drive, &pc);
@@ -2084,20 +1678,19 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
        return (idetape_queue_pc_tail(drive, &pc));
 }
 
-static void idetape_discard_read_pipeline(ide_drive_t *drive,
+static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
                                          int restore_position)
 {
        idetape_tape_t *tape = drive->driver_data;
-       int cnt;
        int seek, position;
 
-       cnt = __idetape_discard_read_pipeline(drive);
+       __ide_tape_discard_merge_buffer(drive);
        if (restore_position) {
                position = idetape_read_position(drive);
-               seek = position > cnt ? position - cnt : 0;
+               seek = position > 0 ? position : 0;
                if (idetape_position_tape(drive, seek, 0, 0)) {
                        printk(KERN_INFO "ide-tape: %s: position_tape failed in"
-                                        " discard_pipeline()\n", tape->name);
+                                        " %s\n", tape->name, __func__);
                        return;
                }
        }
@@ -2111,45 +1704,33 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
                                 struct idetape_bh *bh)
 {
        idetape_tape_t *tape = drive->driver_data;
-       struct request rq;
+       struct request *rq;
+       int ret, errors;
 
        debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd);
 
-       if (test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) {
-               printk(KERN_ERR "ide-tape: bug: the pipeline is active in %s\n",
-                               __func__);
-               return (0);
-       }
+       rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+       rq->cmd_type = REQ_TYPE_SPECIAL;
+       rq->cmd[0] = cmd;
+       rq->rq_disk = tape->disk;
+       rq->special = (void *)bh;
+       rq->sector = tape->first_frame;
+       rq->nr_sectors = blocks;
+       rq->current_nr_sectors = blocks;
+       blk_execute_rq(drive->queue, tape->disk, rq, 0);
 
-       idetape_init_rq(&rq, cmd);
-       rq.rq_disk = tape->disk;
-       rq.special = (void *)bh;
-       rq.sector = tape->first_frame;
-       rq.nr_sectors           = blocks;
-       rq.current_nr_sectors   = blocks;
-       (void) ide_do_drive_cmd(drive, &rq, ide_wait);
+       errors = rq->errors;
+       ret = tape->blk_size * (blocks - rq->current_nr_sectors);
+       blk_put_request(rq);
 
        if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0)
                return 0;
 
-       if (tape->merge_stage)
-               idetape_init_merge_stage(tape);
-       if (rq.errors == IDETAPE_ERROR_GENERAL)
+       if (tape->merge_bh)
+               idetape_init_merge_buffer(tape);
+       if (errors == IDETAPE_ERROR_GENERAL)
                return -EIO;
-       return (tape->blk_size * (blocks-rq.current_nr_sectors));
-}
-
-/* start servicing the pipeline stages, starting from tape->next_stage. */
-static void idetape_plug_pipeline(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-
-       if (tape->next_stage == NULL)
-               return;
-       if (!test_and_set_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) {
-               idetape_activate_next_stage(drive);
-               (void) ide_do_drive_cmd(drive, tape->active_data_rq, ide_end);
-       }
+       return ret;
 }
 
 static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc)
@@ -2189,137 +1770,39 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
        pc->idetape_callback = &idetape_pc_callback;
 }
 
-static void idetape_wait_first_stage(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-       unsigned long flags;
-
-       if (tape->first_stage == NULL)
-               return;
-       spin_lock_irqsave(&tape->lock, flags);
-       if (tape->active_stage == tape->first_stage)
-               idetape_wait_for_request(drive, tape->active_data_rq);
-       spin_unlock_irqrestore(&tape->lock, flags);
-}
-
-/*
- * Try to add a character device originated write request to our pipeline. In
- * case we don't succeed, we revert to non-pipelined operation mode for this
- * request. In order to accomplish that, we
- *
- * 1. Try to allocate a new pipeline stage.
- * 2. If we can't, wait for more and more requests to be serviced and try again
- * each time.
- * 3. If we still can't allocate a stage, fallback to non-pipelined operation
- * mode for this request.
- */
+/* Queue up a character device originated write request. */
 static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks)
 {
        idetape_tape_t *tape = drive->driver_data;
-       idetape_stage_t *new_stage;
-       unsigned long flags;
-       struct request *rq;
 
        debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
 
-       /* Attempt to allocate a new stage. Beware possible race conditions. */
-       while ((new_stage = idetape_kmalloc_stage(tape)) == NULL) {
-               spin_lock_irqsave(&tape->lock, flags);
-               if (test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) {
-                       idetape_wait_for_request(drive, tape->active_data_rq);
-                       spin_unlock_irqrestore(&tape->lock, flags);
-               } else {
-                       spin_unlock_irqrestore(&tape->lock, flags);
-                       idetape_plug_pipeline(drive);
-                       if (test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE,
-                                       &tape->flags))
-                               continue;
-                       /*
-                        * The machine is short on memory. Fallback to non-
-                        * pipelined operation mode for this request.
-                        */
-                       return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE,
-                                               blocks, tape->merge_stage->bh);
-               }
-       }
-       rq = &new_stage->rq;
-       idetape_init_rq(rq, REQ_IDETAPE_WRITE);
-       /* Doesn't actually matter - We always assume sequential access */
-       rq->sector = tape->first_frame;
-       rq->current_nr_sectors = blocks;
-       rq->nr_sectors = blocks;
-
-       idetape_switch_buffers(tape, new_stage);
-       idetape_add_stage_tail(drive, new_stage);
-       tape->pipeline_head++;
-       idetape_calculate_speeds(drive);
-
-       /*
-        * Estimate whether the tape has stopped writing by checking if our
-        * write pipeline is currently empty. If we are not writing anymore,
-        * wait for the pipeline to be almost completely full (90%) before
-        * starting to service requests, so that we will be able to keep up with
-        * the higher speeds of the tape.
-        */
-       if (!test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) {
-               if (tape->nr_stages >= tape->max_stages * 9 / 10 ||
-                       tape->nr_stages >= tape->max_stages -
-                       tape->uncontrolled_pipeline_head_speed * 3 * 1024 /
-                       tape->blk_size) {
-                       tape->measure_insert_time = 1;
-                       tape->insert_time = jiffies;
-                       tape->insert_size = 0;
-                       tape->insert_speed = 0;
-                       idetape_plug_pipeline(drive);
-               }
-       }
-       if (test_and_clear_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags))
-               /* Return a deferred error */
-               return -EIO;
-       return blocks;
+       return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE,
+                                    blocks, tape->merge_bh);
 }
 
-/*
- * Wait until all pending pipeline requests are serviced. Typically called on
- * device close.
- */
-static void idetape_wait_for_pipeline(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-       unsigned long flags;
-
-       while (tape->next_stage || test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE,
-                                               &tape->flags)) {
-               idetape_plug_pipeline(drive);
-               spin_lock_irqsave(&tape->lock, flags);
-               if (test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags))
-                       idetape_wait_for_request(drive, tape->active_data_rq);
-               spin_unlock_irqrestore(&tape->lock, flags);
-       }
-}
-
-static void idetape_empty_write_pipeline(ide_drive_t *drive)
+static void ide_tape_flush_merge_buffer(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
        int blocks, min;
        struct idetape_bh *bh;
 
        if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
-               printk(KERN_ERR "ide-tape: bug: Trying to empty write pipeline,"
+               printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer"
                                " but we are not writing.\n");
                return;
        }
-       if (tape->merge_stage_size > tape->stage_size) {
+       if (tape->merge_bh_size > tape->buffer_size) {
                printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n");
-               tape->merge_stage_size = tape->stage_size;
+               tape->merge_bh_size = tape->buffer_size;
        }
-       if (tape->merge_stage_size) {
-               blocks = tape->merge_stage_size / tape->blk_size;
-               if (tape->merge_stage_size % tape->blk_size) {
+       if (tape->merge_bh_size) {
+               blocks = tape->merge_bh_size / tape->blk_size;
+               if (tape->merge_bh_size % tape->blk_size) {
                        unsigned int i;
 
                        blocks++;
-                       i = tape->blk_size - tape->merge_stage_size %
+                       i = tape->blk_size - tape->merge_bh_size %
                                tape->blk_size;
                        bh = tape->bh->b_reqnext;
                        while (bh) {
@@ -2343,74 +1826,33 @@ static void idetape_empty_write_pipeline(ide_drive_t *drive)
                        }
                }
                (void) idetape_add_chrdev_write_request(drive, blocks);
-               tape->merge_stage_size = 0;
+               tape->merge_bh_size = 0;
        }
-       idetape_wait_for_pipeline(drive);
-       if (tape->merge_stage != NULL) {
-               __idetape_kfree_stage(tape->merge_stage);
-               tape->merge_stage = NULL;
+       if (tape->merge_bh != NULL) {
+               ide_tape_kfree_buffer(tape);
+               tape->merge_bh = NULL;
        }
-       clear_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags);
        tape->chrdev_dir = IDETAPE_DIR_NONE;
-
-       /*
-        * On the next backup, perform the feedback loop again. (I don't want to
-        * keep sense information between backups, as some systems are
-        * constantly on, and the system load can be totally different on the
-        * next backup).
-        */
-       tape->max_stages = tape->min_pipeline;
-       if (tape->first_stage != NULL ||
-           tape->next_stage != NULL ||
-           tape->last_stage != NULL ||
-           tape->nr_stages != 0) {
-               printk(KERN_ERR "ide-tape: ide-tape pipeline bug, "
-                       "first_stage %p, next_stage %p, "
-                       "last_stage %p, nr_stages %d\n",
-                       tape->first_stage, tape->next_stage,
-                       tape->last_stage, tape->nr_stages);
-       }
-}
-
-static void idetape_restart_speed_control(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-
-       tape->restart_speed_control_req = 0;
-       tape->pipeline_head = 0;
-       tape->controlled_last_pipeline_head = 0;
-       tape->controlled_previous_pipeline_head = 0;
-       tape->uncontrolled_previous_pipeline_head = 0;
-       tape->controlled_pipeline_head_speed = 5000;
-       tape->pipeline_head_speed = 5000;
-       tape->uncontrolled_pipeline_head_speed = 0;
-       tape->controlled_pipeline_head_time =
-               tape->uncontrolled_pipeline_head_time = jiffies;
-       tape->controlled_previous_head_time =
-               tape->uncontrolled_previous_head_time = jiffies;
 }
 
-static int idetape_init_read(ide_drive_t *drive, int max_stages)
+static int idetape_init_read(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
-       idetape_stage_t *new_stage;
-       struct request rq;
        int bytes_read;
-       u16 blocks = *(u16 *)&tape->caps[12];
 
        /* Initialize read operation */
        if (tape->chrdev_dir != IDETAPE_DIR_READ) {
                if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
-                       idetape_empty_write_pipeline(drive);
+                       ide_tape_flush_merge_buffer(drive);
                        idetape_flush_tape_buffers(drive);
                }
-               if (tape->merge_stage || tape->merge_stage_size) {
-                       printk(KERN_ERR "ide-tape: merge_stage_size should be"
+               if (tape->merge_bh || tape->merge_bh_size) {
+                       printk(KERN_ERR "ide-tape: merge_bh_size should be"
                                         " 0 now\n");
-                       tape->merge_stage_size = 0;
+                       tape->merge_bh_size = 0;
                }
-               tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0);
-               if (!tape->merge_stage)
+               tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
+               if (!tape->merge_bh)
                        return -ENOMEM;
                tape->chrdev_dir = IDETAPE_DIR_READ;
 
@@ -2423,54 +1865,23 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages)
                if (drive->dsc_overlap) {
                        bytes_read = idetape_queue_rw_tail(drive,
                                                        REQ_IDETAPE_READ, 0,
-                                                       tape->merge_stage->bh);
+                                                       tape->merge_bh);
                        if (bytes_read < 0) {
-                               __idetape_kfree_stage(tape->merge_stage);
-                               tape->merge_stage = NULL;
+                               ide_tape_kfree_buffer(tape);
+                               tape->merge_bh = NULL;
                                tape->chrdev_dir = IDETAPE_DIR_NONE;
                                return bytes_read;
                        }
                }
        }
-       if (tape->restart_speed_control_req)
-               idetape_restart_speed_control(drive);
-       idetape_init_rq(&rq, REQ_IDETAPE_READ);
-       rq.sector = tape->first_frame;
-       rq.nr_sectors = blocks;
-       rq.current_nr_sectors = blocks;
-       if (!test_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags) &&
-           tape->nr_stages < max_stages) {
-               new_stage = idetape_kmalloc_stage(tape);
-               while (new_stage != NULL) {
-                       new_stage->rq = rq;
-                       idetape_add_stage_tail(drive, new_stage);
-                       if (tape->nr_stages >= max_stages)
-                               break;
-                       new_stage = idetape_kmalloc_stage(tape);
-               }
-       }
-       if (!test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) {
-               if (tape->nr_pending_stages >= 3 * max_stages / 4) {
-                       tape->measure_insert_time = 1;
-                       tape->insert_time = jiffies;
-                       tape->insert_size = 0;
-                       tape->insert_speed = 0;
-                       idetape_plug_pipeline(drive);
-               }
-       }
+
        return 0;
 }
 
-/*
- * Called from idetape_chrdev_read() to service a character device read request
- * and add read-ahead requests to our pipeline.
- */
+/* called from idetape_chrdev_read() to service a chrdev read request. */
 static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
 {
        idetape_tape_t *tape = drive->driver_data;
-       unsigned long flags;
-       struct request *rq_ptr;
-       int bytes_read;
 
        debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks);
 
@@ -2478,39 +1889,10 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
        if (test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
                return 0;
 
-       /* Wait for the next block to reach the head of the pipeline. */
-       idetape_init_read(drive, tape->max_stages);
-       if (tape->first_stage == NULL) {
-               if (test_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags))
-                       return 0;
-               return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks,
-                                       tape->merge_stage->bh);
-       }
-       idetape_wait_first_stage(drive);
-       rq_ptr = &tape->first_stage->rq;
-       bytes_read = tape->blk_size * (rq_ptr->nr_sectors -
-                                       rq_ptr->current_nr_sectors);
-       rq_ptr->nr_sectors = 0;
-       rq_ptr->current_nr_sectors = 0;
+       idetape_init_read(drive);
 
-       if (rq_ptr->errors == IDETAPE_ERROR_EOD)
-               return 0;
-       else {
-               idetape_switch_buffers(tape, tape->first_stage);
-               if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK)
-                       set_bit(IDETAPE_FLAG_FILEMARK, &tape->flags);
-               spin_lock_irqsave(&tape->lock, flags);
-               idetape_remove_stage_head(drive);
-               spin_unlock_irqrestore(&tape->lock, flags);
-               tape->pipeline_head++;
-               idetape_calculate_speeds(drive);
-       }
-       if (bytes_read > blocks * tape->blk_size) {
-               printk(KERN_ERR "ide-tape: bug: trying to return more bytes"
-                               " than requested\n");
-               bytes_read = blocks * tape->blk_size;
-       }
-       return (bytes_read);
+       return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks,
+                                    tape->merge_bh);
 }
 
 static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
@@ -2522,8 +1904,8 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
        while (bcount) {
                unsigned int count;
 
-               bh = tape->merge_stage->bh;
-               count = min(tape->stage_size, bcount);
+               bh = tape->merge_bh;
+               count = min(tape->buffer_size, bcount);
                bcount -= count;
                blocks = count / tape->blk_size;
                while (count) {
@@ -2534,31 +1916,10 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
                        bh = bh->b_reqnext;
                }
                idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks,
-                                     tape->merge_stage->bh);
+                                     tape->merge_bh);
        }
 }
 
-static int idetape_pipeline_size(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-       idetape_stage_t *stage;
-       struct request *rq;
-       int size = 0;
-
-       idetape_wait_for_pipeline(drive);
-       stage = tape->first_stage;
-       while (stage != NULL) {
-               rq = &stage->rq;
-               size += tape->blk_size * (rq->nr_sectors -
-                               rq->current_nr_sectors);
-               if (rq->errors == IDETAPE_ERROR_FILEMARK)
-                       size += tape->blk_size;
-               stage = stage->next;
-       }
-       size += tape->merge_stage_size;
-       return size;
-}
-
 /*
  * Rewinds the tape to the Beginning Of the current Partition (BOP). We
  * currently support only one partition.
@@ -2604,11 +1965,10 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,
                if (copy_from_user(&config, argp, sizeof(config)))
                        return -EFAULT;
                tape->best_dsc_rw_freq = config.dsc_rw_frequency;
-               tape->max_stages = config.nr_stages;
                break;
        case 0x0350:
                config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq;
-               config.nr_stages = tape->max_stages;
+               config.nr_stages = 1;
                if (copy_to_user(argp, &config, sizeof(config)))
                        return -EFAULT;
                break;
@@ -2618,19 +1978,11 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,
        return 0;
 }
 
-/*
- * The function below is now a bit more complicated than just passing the
- * command to the tape since we may have crossed some filemarks during our
- * pipelined read-ahead mode. As a minor side effect, the pipeline enables us to
- * support MTFSFM when the filemark is in our internal pipeline even if the tape
- * doesn't support spacing over filemarks in the reverse direction.
- */
 static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
                                        int mt_count)
 {
        idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc pc;
-       unsigned long flags;
        int retval, count = 0;
        int sprev = !!(tape->caps[4] & 0x20);
 
@@ -2643,48 +1995,12 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
        }
 
        if (tape->chrdev_dir == IDETAPE_DIR_READ) {
-               /* its a read-ahead buffer, scan it for crossed filemarks. */
-               tape->merge_stage_size = 0;
+               tape->merge_bh_size = 0;
                if (test_and_clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
                        ++count;
-               while (tape->first_stage != NULL) {
-                       if (count == mt_count) {
-                               if (mt_op == MTFSFM)
-                                       set_bit(IDETAPE_FLAG_FILEMARK,
-                                               &tape->flags);
-                               return 0;
-                       }
-                       spin_lock_irqsave(&tape->lock, flags);
-                       if (tape->first_stage == tape->active_stage) {
-                               /*
-                                * We have reached the active stage in the read
-                                * pipeline. There is no point in allowing the
-                                * drive to continue reading any farther, so we
-                                * stop the pipeline.
-                                *
-                                * This section should be moved to a separate
-                                * subroutine because similar operations are
-                                * done in __idetape_discard_read_pipeline(),
-                                * for example.
-                                */
-                               tape->next_stage = NULL;
-                               spin_unlock_irqrestore(&tape->lock, flags);
-                               idetape_wait_first_stage(drive);
-                               tape->next_stage = tape->first_stage->next;
-                       } else
-                               spin_unlock_irqrestore(&tape->lock, flags);
-                       if (tape->first_stage->rq.errors ==
-                                       IDETAPE_ERROR_FILEMARK)
-                               ++count;
-                       idetape_remove_stage_head(drive);
-               }
-               idetape_discard_read_pipeline(drive, 0);
+               ide_tape_discard_merge_buffer(drive, 0);
        }
 
-       /*
-        * The filemark was not found in our internal pipeline; now we can issue
-        * the space command.
-        */
        switch (mt_op) {
        case MTFSF:
        case MTBSF:
@@ -2740,27 +2056,25 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
                            (count % tape->blk_size) == 0)
                                tape->user_bs_factor = count / tape->blk_size;
        }
-       rc = idetape_init_read(drive, tape->max_stages);
+       rc = idetape_init_read(drive);
        if (rc < 0)
                return rc;
        if (count == 0)
                return (0);
-       if (tape->merge_stage_size) {
-               actually_read = min((unsigned int)(tape->merge_stage_size),
+       if (tape->merge_bh_size) {
+               actually_read = min((unsigned int)(tape->merge_bh_size),
                                    (unsigned int)count);
-               if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage,
-                                              actually_read))
+               if (idetape_copy_stage_to_user(tape, buf, actually_read))
                        ret = -EFAULT;
                buf += actually_read;
-               tape->merge_stage_size -= actually_read;
+               tape->merge_bh_size -= actually_read;
                count -= actually_read;
        }
-       while (count >= tape->stage_size) {
+       while (count >= tape->buffer_size) {
                bytes_read = idetape_add_chrdev_read_request(drive, ctl);
                if (bytes_read <= 0)
                        goto finish;
-               if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage,
-                                              bytes_read))
+               if (idetape_copy_stage_to_user(tape, buf, bytes_read))
                        ret = -EFAULT;
                buf += bytes_read;
                count -= bytes_read;
@@ -2771,11 +2085,10 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
                if (bytes_read <= 0)
                        goto finish;
                temp = min((unsigned long)count, (unsigned long)bytes_read);
-               if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage,
-                                              temp))
+               if (idetape_copy_stage_to_user(tape, buf, temp))
                        ret = -EFAULT;
                actually_read += temp;
-               tape->merge_stage_size = bytes_read-temp;
+               tape->merge_bh_size = bytes_read-temp;
        }
 finish:
        if (!actually_read && test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags)) {
@@ -2806,17 +2119,17 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
        /* Initialize write operation */
        if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
                if (tape->chrdev_dir == IDETAPE_DIR_READ)
-                       idetape_discard_read_pipeline(drive, 1);
-               if (tape->merge_stage || tape->merge_stage_size) {
-                       printk(KERN_ERR "ide-tape: merge_stage_size "
+                       ide_tape_discard_merge_buffer(drive, 1);
+               if (tape->merge_bh || tape->merge_bh_size) {
+                       printk(KERN_ERR "ide-tape: merge_bh_size "
                                "should be 0 now\n");
-                       tape->merge_stage_size = 0;
+                       tape->merge_bh_size = 0;
                }
-               tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0);
-               if (!tape->merge_stage)
+               tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
+               if (!tape->merge_bh)
                        return -ENOMEM;
                tape->chrdev_dir = IDETAPE_DIR_WRITE;
-               idetape_init_merge_stage(tape);
+               idetape_init_merge_buffer(tape);
 
                /*
                 * Issue a write 0 command to ensure that DSC handshake is
@@ -2827,10 +2140,10 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
                if (drive->dsc_overlap) {
                        ssize_t retval = idetape_queue_rw_tail(drive,
                                                        REQ_IDETAPE_WRITE, 0,
-                                                       tape->merge_stage->bh);
+                                                       tape->merge_bh);
                        if (retval < 0) {
-                               __idetape_kfree_stage(tape->merge_stage);
-                               tape->merge_stage = NULL;
+                               ide_tape_kfree_buffer(tape);
+                               tape->merge_bh = NULL;
                                tape->chrdev_dir = IDETAPE_DIR_NONE;
                                return retval;
                        }
@@ -2838,49 +2151,44 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
        }
        if (count == 0)
                return (0);
-       if (tape->restart_speed_control_req)
-               idetape_restart_speed_control(drive);
-       if (tape->merge_stage_size) {
-               if (tape->merge_stage_size >= tape->stage_size) {
+       if (tape->merge_bh_size) {
+               if (tape->merge_bh_size >= tape->buffer_size) {
                        printk(KERN_ERR "ide-tape: bug: merge buf too big\n");
-                       tape->merge_stage_size = 0;
+                       tape->merge_bh_size = 0;
                }
                actually_written = min((unsigned int)
-                               (tape->stage_size - tape->merge_stage_size),
+                               (tape->buffer_size - tape->merge_bh_size),
                                (unsigned int)count);
-               if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf,
-                                                actually_written))
+               if (idetape_copy_stage_from_user(tape, buf, actually_written))
                                ret = -EFAULT;
                buf += actually_written;
-               tape->merge_stage_size += actually_written;
+               tape->merge_bh_size += actually_written;
                count -= actually_written;
 
-               if (tape->merge_stage_size == tape->stage_size) {
+               if (tape->merge_bh_size == tape->buffer_size) {
                        ssize_t retval;
-                       tape->merge_stage_size = 0;
+                       tape->merge_bh_size = 0;
                        retval = idetape_add_chrdev_write_request(drive, ctl);
                        if (retval <= 0)
                                return (retval);
                }
        }
-       while (count >= tape->stage_size) {
+       while (count >= tape->buffer_size) {
                ssize_t retval;
-               if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf,
-                                                tape->stage_size))
+               if (idetape_copy_stage_from_user(tape, buf, tape->buffer_size))
                        ret = -EFAULT;
-               buf += tape->stage_size;
-               count -= tape->stage_size;
+               buf += tape->buffer_size;
+               count -= tape->buffer_size;
                retval = idetape_add_chrdev_write_request(drive, ctl);
-               actually_written += tape->stage_size;
+               actually_written += tape->buffer_size;
                if (retval <= 0)
                        return (retval);
        }
        if (count) {
                actually_written += count;
-               if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf,
-                                                count))
+               if (idetape_copy_stage_from_user(tape, buf, count))
                        ret = -EFAULT;
-               tape->merge_stage_size += count;
+               tape->merge_bh_size += count;
        }
        return ret ? ret : actually_written;
 }
@@ -2904,8 +2212,7 @@ static int idetape_write_filemark(ide_drive_t *drive)
  *
  * Note: MTBSF and MTBSFM are not supported when the tape doesn't support
  * spacing over filemarks in the reverse direction. In this case, MTFSFM is also
- * usually not supported (it is supported in the rare case in which we crossed
- * the filemark during our read-ahead pipelined operation mode).
+ * usually not supported.
  *
  * The following commands are currently not supported:
  *
@@ -2921,7 +2228,6 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
        debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n",
                        mt_op, mt_count);
 
-       /* Commands which need our pipelined read-ahead stages. */
        switch (mt_op) {
        case MTFSF:
        case MTFSFM:
@@ -2938,7 +2244,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
        case MTWEOF:
                if (tape->write_prot)
                        return -EACCES;
-               idetape_discard_read_pipeline(drive, 1);
+               ide_tape_discard_merge_buffer(drive, 1);
                for (i = 0; i < mt_count; i++) {
                        retval = idetape_write_filemark(drive);
                        if (retval)
@@ -2946,12 +2252,12 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
                }
                return 0;
        case MTREW:
-               idetape_discard_read_pipeline(drive, 0);
+               ide_tape_discard_merge_buffer(drive, 0);
                if (idetape_rewind_tape(drive))
                        return -EIO;
                return 0;
        case MTLOAD:
-               idetape_discard_read_pipeline(drive, 0);
+               ide_tape_discard_merge_buffer(drive, 0);
                idetape_create_load_unload_cmd(drive, &pc,
                                               IDETAPE_LU_LOAD_MASK);
                return idetape_queue_pc_tail(drive, &pc);
@@ -2966,7 +2272,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
                                if (!idetape_queue_pc_tail(drive, &pc))
                                        tape->door_locked = DOOR_UNLOCKED;
                }
-               idetape_discard_read_pipeline(drive, 0);
+               ide_tape_discard_merge_buffer(drive, 0);
                idetape_create_load_unload_cmd(drive, &pc,
                                              !IDETAPE_LU_LOAD_MASK);
                retval = idetape_queue_pc_tail(drive, &pc);
@@ -2974,10 +2280,10 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
                        clear_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags);
                return retval;
        case MTNOP:
-               idetape_discard_read_pipeline(drive, 0);
+               ide_tape_discard_merge_buffer(drive, 0);
                return idetape_flush_tape_buffers(drive);
        case MTRETEN:
-               idetape_discard_read_pipeline(drive, 0);
+               ide_tape_discard_merge_buffer(drive, 0);
                idetape_create_load_unload_cmd(drive, &pc,
                        IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK);
                return idetape_queue_pc_tail(drive, &pc);
@@ -2999,11 +2305,11 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
                        set_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags);
                return 0;
        case MTSEEK:
-               idetape_discard_read_pipeline(drive, 0);
+               ide_tape_discard_merge_buffer(drive, 0);
                return idetape_position_tape(drive,
                        mt_count * tape->user_bs_factor, tape->partition, 0);
        case MTSETPART:
-               idetape_discard_read_pipeline(drive, 0);
+               ide_tape_discard_merge_buffer(drive, 0);
                return idetape_position_tape(drive, 0, mt_count, 0);
        case MTFSR:
        case MTBSR:
@@ -3048,13 +2354,12 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
 
        debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd);
 
-       tape->restart_speed_control_req = 1;
        if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
-               idetape_empty_write_pipeline(drive);
+               ide_tape_flush_merge_buffer(drive);
                idetape_flush_tape_buffers(drive);
        }
        if (cmd == MTIOCGET || cmd == MTIOCPOS) {
-               block_offset = idetape_pipeline_size(drive) /
+               block_offset = tape->merge_bh_size /
                        (tape->blk_size * tape->user_bs_factor);
                position = idetape_read_position(drive);
                if (position < 0)
@@ -3086,7 +2391,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
                return 0;
        default:
                if (tape->chrdev_dir == IDETAPE_DIR_READ)
-                       idetape_discard_read_pipeline(drive, 1);
+                       ide_tape_discard_merge_buffer(drive, 1);
                return idetape_blkdev_ioctl(drive, cmd, arg);
        }
 }
@@ -3160,9 +2465,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
        if (!test_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags))
                (void)idetape_rewind_tape(drive);
 
-       if (tape->chrdev_dir != IDETAPE_DIR_READ)
-               clear_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags);
-
        /* Read block size and write protect status from drive. */
        ide_tape_get_bsize_from_bdesc(drive);
 
@@ -3191,8 +2493,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
                        }
                }
        }
-       idetape_restart_speed_control(drive);
-       tape->restart_speed_control_req = 0;
        return 0;
 
 out_put_tape:
@@ -3204,13 +2504,13 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor)
 {
        idetape_tape_t *tape = drive->driver_data;
 
-       idetape_empty_write_pipeline(drive);
-       tape->merge_stage = __idetape_kmalloc_stage(tape, 1, 0);
-       if (tape->merge_stage != NULL) {
+       ide_tape_flush_merge_buffer(drive);
+       tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0);
+       if (tape->merge_bh != NULL) {
                idetape_pad_zeros(drive, tape->blk_size *
                                (tape->user_bs_factor - 1));
-               __idetape_kfree_stage(tape->merge_stage);
-               tape->merge_stage = NULL;
+               ide_tape_kfree_buffer(tape);
+               tape->merge_bh = NULL;
        }
        idetape_write_filemark(drive);
        idetape_flush_tape_buffers(drive);
@@ -3233,9 +2533,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
                idetape_write_release(drive, minor);
        if (tape->chrdev_dir == IDETAPE_DIR_READ) {
                if (minor < 128)
-                       idetape_discard_read_pipeline(drive, 1);
-               else
-                       idetape_wait_for_pipeline(drive);
+                       ide_tape_discard_merge_buffer(drive, 1);
        }
 
        if (minor < 128 && test_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags))
@@ -3374,33 +2672,15 @@ static void idetape_add_settings(ide_drive_t *drive)
 
        ide_add_setting(drive, "buffer", SETTING_READ, TYPE_SHORT, 0, 0xffff,
                        1, 2, (u16 *)&tape->caps[16], NULL);
-       ide_add_setting(drive, "pipeline_min", SETTING_RW, TYPE_INT, 1, 0xffff,
-                       tape->stage_size / 1024, 1, &tape->min_pipeline, NULL);
-       ide_add_setting(drive, "pipeline", SETTING_RW, TYPE_INT, 1, 0xffff,
-                       tape->stage_size / 1024, 1, &tape->max_stages, NULL);
-       ide_add_setting(drive, "pipeline_max", SETTING_RW, TYPE_INT, 1, 0xffff,
-                       tape->stage_size / 1024, 1, &tape->max_pipeline, NULL);
-       ide_add_setting(drive, "pipeline_used", SETTING_READ, TYPE_INT, 0,
-                       0xffff, tape->stage_size / 1024, 1, &tape->nr_stages,
-                       NULL);
-       ide_add_setting(drive, "pipeline_pending", SETTING_READ, TYPE_INT, 0,
-                       0xffff, tape->stage_size / 1024, 1,
-                       &tape->nr_pending_stages, NULL);
        ide_add_setting(drive, "speed", SETTING_READ, TYPE_SHORT, 0, 0xffff,
                        1, 1, (u16 *)&tape->caps[14], NULL);
-       ide_add_setting(drive, "stage", SETTING_READ, TYPE_INT, 0, 0xffff, 1,
-                       1024, &tape->stage_size, NULL);
+       ide_add_setting(drive, "buffer_size", SETTING_READ, TYPE_INT, 0, 0xffff,
+                       1, 1024, &tape->buffer_size, NULL);
        ide_add_setting(drive, "tdsc", SETTING_RW, TYPE_INT, IDETAPE_DSC_RW_MIN,
                        IDETAPE_DSC_RW_MAX, 1000, HZ, &tape->best_dsc_rw_freq,
                        NULL);
        ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1,
                        1, &drive->dsc_overlap, NULL);
-       ide_add_setting(drive, "pipeline_head_speed_c", SETTING_READ, TYPE_INT,
-                       0, 0xffff, 1, 1, &tape->controlled_pipeline_head_speed,
-                       NULL);
-       ide_add_setting(drive, "pipeline_head_speed_u", SETTING_READ, TYPE_INT,
-                       0, 0xffff, 1, 1,
-                       &tape->uncontrolled_pipeline_head_speed, NULL);
        ide_add_setting(drive, "avg_speed", SETTING_READ, TYPE_INT, 0, 0xffff,
                        1, 1, &tape->avg_speed, NULL);
        ide_add_setting(drive, "debug_mask", SETTING_RW, TYPE_INT, 0, 0xffff, 1,
@@ -3423,11 +2703,10 @@ static inline void idetape_add_settings(ide_drive_t *drive) { ; }
  */
 static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
 {
-       unsigned long t1, tmid, tn, t;
+       unsigned long t;
        int speed;
-       int stage_size;
+       int buffer_size;
        u8 gcw[2];
-       struct sysinfo si;
        u16 *ctl = (u16 *)&tape->caps[12];
 
        spin_lock_init(&tape->lock);
@@ -3446,79 +2725,45 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
        tape->name[2] = '0' + minor;
        tape->chrdev_dir = IDETAPE_DIR_NONE;
        tape->pc = tape->pc_stack;
-       tape->max_insert_speed = 10000;
-       tape->speed_control = 1;
        *((unsigned short *) &gcw) = drive->id->config;
 
        /* Command packet DRQ type */
        if (((gcw[0] & 0x60) >> 5) == 1)
                set_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags);
 
-       tape->min_pipeline = 10;
-       tape->max_pipeline = 10;
-       tape->max_stages   = 10;
-
        idetape_get_inquiry_results(drive);
        idetape_get_mode_sense_results(drive);
        ide_tape_get_bsize_from_bdesc(drive);
        tape->user_bs_factor = 1;
-       tape->stage_size = *ctl * tape->blk_size;
-       while (tape->stage_size > 0xffff) {
+       tape->buffer_size = *ctl * tape->blk_size;
+       while (tape->buffer_size > 0xffff) {
                printk(KERN_NOTICE "ide-tape: decreasing stage size\n");
                *ctl /= 2;
-               tape->stage_size = *ctl * tape->blk_size;
+               tape->buffer_size = *ctl * tape->blk_size;
        }
-       stage_size = tape->stage_size;
-       tape->pages_per_stage = stage_size / PAGE_SIZE;
-       if (stage_size % PAGE_SIZE) {
-               tape->pages_per_stage++;
-               tape->excess_bh_size = PAGE_SIZE - stage_size % PAGE_SIZE;
+       buffer_size = tape->buffer_size;
+       tape->pages_per_buffer = buffer_size / PAGE_SIZE;
+       if (buffer_size % PAGE_SIZE) {
+               tape->pages_per_buffer++;
+               tape->excess_bh_size = PAGE_SIZE - buffer_size % PAGE_SIZE;
        }
 
-       /* Select the "best" DSC read/write polling freq and pipeline size. */
+       /* select the "best" DSC read/write polling freq */
        speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]);
 
-       tape->max_stages = speed * 1000 * 10 / tape->stage_size;
-
-       /* Limit memory use for pipeline to 10% of physical memory */
-       si_meminfo(&si);
-       if (tape->max_stages * tape->stage_size >
-                       si.totalram * si.mem_unit / 10)
-               tape->max_stages =
-                       si.totalram * si.mem_unit / (10 * tape->stage_size);
-
-       tape->max_stages   = min(tape->max_stages, IDETAPE_MAX_PIPELINE_STAGES);
-       tape->min_pipeline = min(tape->max_stages, IDETAPE_MIN_PIPELINE_STAGES);
-       tape->max_pipeline =
-               min(tape->max_stages * 2, IDETAPE_MAX_PIPELINE_STAGES);
-       if (tape->max_stages == 0) {
-               tape->max_stages   = 1;
-               tape->min_pipeline = 1;
-               tape->max_pipeline = 1;
-       }
-
-       t1 = (tape->stage_size * HZ) / (speed * 1000);
-       tmid = (*(u16 *)&tape->caps[16] * 32 * HZ) / (speed * 125);
-       tn = (IDETAPE_FIFO_THRESHOLD * tape->stage_size * HZ) / (speed * 1000);
-
-       if (tape->max_stages)
-               t = tn;
-       else
-               t = t1;
+       t = (IDETAPE_FIFO_THRESHOLD * tape->buffer_size * HZ) / (speed * 1000);
 
        /*
         * Ensure that the number we got makes sense; limit it within
         * IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX.
         */
-       tape->best_dsc_rw_freq = max_t(unsigned long,
-                               min_t(unsigned long, t, IDETAPE_DSC_RW_MAX),
-                               IDETAPE_DSC_RW_MIN);
+       tape->best_dsc_rw_freq = clamp_t(unsigned long, t, IDETAPE_DSC_RW_MIN,
+                                        IDETAPE_DSC_RW_MAX);
        printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, "
-               "%dkB pipeline, %lums tDSC%s\n",
+               "%lums tDSC%s\n",
                drive->name, tape->name, *(u16 *)&tape->caps[14],
-               (*(u16 *)&tape->caps[16] * 512) / tape->stage_size,
-               tape->stage_size / 1024,
-               tape->max_stages * tape->stage_size / 1024,
+               (*(u16 *)&tape->caps[16] * 512) / tape->buffer_size,
+               tape->buffer_size / 1024,
                tape->best_dsc_rw_freq * 1000 / HZ,
                drive->using_dma ? ", DMA":"");
 
@@ -3542,7 +2787,7 @@ static void ide_tape_release(struct kref *kref)
        ide_drive_t *drive = tape->drive;
        struct gendisk *g = tape->disk;
 
-       BUG_ON(tape->first_stage != NULL || tape->merge_stage_size);
+       BUG_ON(tape->merge_bh_size);
 
        drive->dsc_overlap = 0;
        drive->driver_data = NULL;