Hi guys,

Below is a patch to fix some problems in the OnStream tape drive support
in ide-tape.c.

- It implements Early Warning (e.g. retuns ENOSPC) for reaching end-of-tape. 
  This fixes a real nasty problem when writing beyond end-of-tape, rendering
  the 'backup' more ore less useless.
- Includes a workaround for a read error around block 3000.
- The module use counts were gone allowing to remove the module while it was
  still busy.
- Support for other IDE OnStream tape drives (e.g. DI-50).
- A few cosmetic fixes to improve readability.

Patch is against linux 2.4.0-prerelease.

Andre: a patch for 2.2.18 is almost ready to be included in the ide patchset.

-Marcel
-- 
     ======--------         Marcel J.E. Mol                MESA Consulting B.V.
    =======---------        ph. +31-(0)6-54724868          P.O. Box 112
    =======---------        [EMAIL PROTECTED]                 2630 AC  Nootdorp
__==== www.mesa.nl ---____U_n_i_x______I_n_t_e_r_n_e_t____ The Netherlands ____
 They couldn't think of a number, so they gave me a name!
                                -- Rupert Hine       http://www.ruperthine.com/

--- linux/drivers/ide/ide-tape.c.org    Wed Jan  3 00:13:40 2001
+++ linux/drivers/ide/ide-tape.c        Thu Jan 11 22:41:36 2001
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/ide-tape.c                Version 1.16f   Dec  15, 1999
+ * linux/drivers/ide/ide-tape.c                Version 1.17    Jan, 2001
  *
  * Copyright (C) 1995 - 1999 Gadi Oxman <[EMAIL PROTECTED]>
  *
@@ -274,6 +274,18 @@
  *                     this section correctly, a hypothetical and unwanted situation
  *                      is being described)
  * Ver 1.16f Dec 15 99   Change place of the secondary OnStream header frames.
+ * Ver 1.17  Nov 2000 / Jan 2001  Marcel Mol, [EMAIL PROTECTED]
+ *                     - Add idetape_onstream_mode_sense_tape_parameter_page
+ *                       function to get tape capacity in frames: tape->capacity.
+ *                     - Add support for DI-50 drives( or any DI- drive).
+ *                     - 'workaround' for read error/blank block arround block 3000.
+ *                     - Implement Early warning for end of media for Onstream.
+ *                     - Cosmetic code changes for readability.
+ *                     - Idetape_position_tape should not use SKIP bit during
+ *                       Onstream read recovery.
+ *                     - Add capacity, logical_blk_num and first/last_frame_position
+ *                       to /proc/ide/hd?/settings.
+ *                     - Module use count was gone in the Linux 2.4 driver.
  *
  *
  * Here are some words from the first releases of hd.c, which are quoted
@@ -384,7 +396,7 @@
  *             sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
  */
 
-#define IDETAPE_VERSION "1.16f"
+#define IDETAPE_VERSION "1.17"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -421,7 +433,11 @@
 #define OS_CONFIG_PARTITION    (0xff)
 #define OS_DATA_PARTITION      (0)
 #define OS_PARTITION_VERSION   (1)
+#define OS_EW                  300
+#define OS_ADR_MINREV          2
 
+#define OS_DATA_STARTFRAME1    20
+#define OS_DATA_ENDFRAME1      2980
 /*
  * partition
  */
@@ -512,12 +528,33 @@
 } os_header_t;
 
 /*
+ *     OnStream Tape Parameters Page
+ */
+typedef struct {
+       unsigned        page_code       :6;     /* Page code - Should be 0x2b */
+       unsigned        reserved1_6     :1;
+       unsigned        ps              :1;
+       __u8            reserved2;
+       __u8            density;                /* kbpi */
+       __u8            reserved3,reserved4;
+       __u16           segtrk;                 /* segment of per track */
+       __u16           trks;                   /* tracks per tape */
+       __u8            reserved5,reserved6,reserved7,reserved8,reserved9,reserved10;
+} onstream_tape_paramtr_page_t;
+
+/*
  * OnStream ADRL frame
  */
 #define OS_FRAME_SIZE  (32 * 1024 + 512)
 #define OS_DATA_SIZE   (32 * 1024)
 #define OS_AUX_SIZE    (512)
 
+/*
+ * internal error codes for onstream
+ */
+#define OS_PART_ERROR    2
+#define OS_WRITE_ERROR   1
+
 #include <linux/mtio.h>
 
 /**************************** Tunable parameters *****************************/
@@ -949,6 +986,7 @@
        int eod_frame_addr;
        unsigned long cmd_start_time;
        unsigned long max_cmd_time;
+       unsigned capacity;
 
        /*
         * Optimize the number of "buffer filling"
@@ -1157,7 +1195,7 @@
 typedef union {
        unsigned all                    :8;
        struct {
-               unsigned dma            :1;     /* Using DMA of PIO */
+               unsigned dma            :1;     /* Using DMA or PIO */
                unsigned reserved321    :3;     /* Reserved */
                unsigned reserved654    :3;     /* Reserved (Tag Type) */
                unsigned reserved7      :1;     /* Reserved */
@@ -1287,7 +1325,9 @@
  *     by ide-tape.
  */
 #define        IDETAPE_CAPABILITIES_PAGE       0x2a
+#define IDETAPE_PARAMTR_PAGE           0x2b   /* onstream only */
 #define IDETAPE_BLOCK_SIZE_PAGE                0x30
+#define IDETAPE_BUFFER_FILLING_PAGE    0x33
 
 /*
  *     Mode Parameter Header for the MODE SENSE packet command
@@ -1428,6 +1468,14 @@
 #endif /* IDETAPE_DEBUG_LOG_VERBOSE */
 
 /*
+ *      Function declarations
+ *
+ */
+static void idetape_onstream_mode_sense_tape_parameter_page(ide_drive_t *drive, int 
+debug);
+static int idetape_chrdev_release (struct inode *inode, struct file *filp);
+static void idetape_write_release (struct inode *inode);
+
+/*
  *     Too bad. The drive wants to send us data which we are not ready to accept.
  *     Just throw it away.
  */
@@ -1452,7 +1500,8 @@
 #endif /* IDETAPE_DEBUG_BUGS */
                count = IDE_MIN (bh->b_size - atomic_read(&bh->b_count), bcount);
                atapi_input_bytes (drive, bh->b_data + atomic_read(&bh->b_count), 
count);
-               bcount -= count; atomic_add(count, &bh->b_count);
+               bcount -= count;
+               atomic_add(count, &bh->b_count);
                if (atomic_read(&bh->b_count) == bh->b_size) {
                        bh = bh->b_reqnext;
                        if (bh)
@@ -1476,7 +1525,9 @@
 #endif /* IDETAPE_DEBUG_BUGS */
                count = IDE_MIN (pc->b_count, bcount);
                atapi_output_bytes (drive, pc->b_data, count);
-               bcount -= count; pc->b_data += count; pc->b_count -= count;
+               bcount -= count;
+               pc->b_data += count;
+               pc->b_count -= count;
                if (!pc->b_count) {
                        pc->bh = bh = bh->b_reqnext;
                        if (bh) {
@@ -1577,20 +1628,23 @@
  *     to analyze the request sense. We currently do not utilize this
  *     information.
  */
-static void idetape_analyze_error (ide_drive_t *drive,idetape_request_sense_result_t 
*result)
+static void idetape_analyze_error (ide_drive_t *drive, idetape_request_sense_result_t 
+*result)
 {
        idetape_tape_t *tape = drive->driver_data;
        idetape_pc_t *pc = tape->failed_pc;
 
-       tape->sense = *result;
-       tape->sense_key = result->sense_key; tape->asc = result->asc; tape->ascq = 
result->ascq;
+       tape->sense     = *result;
+       tape->sense_key = result->sense_key;
+       tape->asc       = result->asc;
+       tape->ascq      = result->ascq;
 #if IDETAPE_DEBUG_LOG
        /*
         *      Without debugging, we only log an error if we decided to
         *      give up retrying.
         */
        if (tape->debug_level >= 1)
-               printk (KERN_INFO "ide-tape: pc = %x, sense key = %x, asc = %x, ascq = 
%x\n",pc->c[0],result->sense_key,result->asc,result->ascq);
+               printk (KERN_INFO "ide-tape: pc = %x, sense key = %x, asc = %x, ascq = 
+%x\n",
+                               pc->c[0], result->sense_key, result->asc, 
+result->ascq);
 #if IDETAPE_DEBUG_LOG_VERBOSE
        if (tape->debug_level >= 1)
                printk (KERN_INFO "ide-tape: pc = %s, sense key = %x, asc = %x, ascq = 
%x\n",
@@ -1660,7 +1714,7 @@
 static void idetape_active_next_stage (ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
-       idetape_stage_t *stage=tape->next_stage;
+       idetape_stage_t *stage = tape->next_stage;
        struct request *rq = &stage->rq;
 
 #if IDETAPE_DEBUG_LOG
@@ -1676,9 +1730,9 @@
 
        rq->buffer = NULL;
        rq->bh = stage->bh;
-       tape->active_data_request=rq;
-       tape->active_stage=stage;
-       tape->next_stage=stage->next;
+       tape->active_data_request = rq;
+       tape->active_stage = stage;
+       tape->next_stage = stage->next;
 }
 
 /*
@@ -1756,12 +1810,12 @@
                return;
        }
 #endif /* IDETAPE_DEBUG_BUGS */
-       stage=tape->first_stage;
-       tape->first_stage=stage->next;
+       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;
+               tape->last_stage = NULL;
 #if IDETAPE_DEBUG_BUGS
                if (tape->next_stage != NULL)
                        printk (KERN_ERR "ide-tape: bug: tape->next_stage != NULL\n");
@@ -1821,12 +1875,12 @@
                        }
 #endif
                        if (tape->onstream && !tape->raw) {
-                               if (tape->first_frame_position == 0xba4) {
+                               if (tape->first_frame_position == OS_DATA_ENDFRAME1) { 
 #if ONSTREAM_DEBUG
-                               if (tape->debug_level >= 2)
-                                       printk("ide-tape: %s: skipping over config 
parition..\n", tape->name);
+                                       if (tape->debug_level >= 2)
+                                               printk("ide-tape: %s: skipping over 
+config parition..\n", tape->name);
 #endif
-                                       tape->onstream_write_error = 2;
+                                       tape->onstream_write_error = OS_PART_ERROR;
                                        if (tape->sem)
                                                up(tape->sem);
                                }
@@ -1839,7 +1893,7 @@
                                if (tape->onstream && !tape->raw && error == 
IDETAPE_ERROR_GENERAL && tape->sense.sense_key == 3) {
                                        clear_bit (IDETAPE_PIPELINE_ERROR, 
&tape->flags);
                                        printk(KERN_ERR "ide-tape: %s: write error, 
enabling error recovery\n", tape->name);
-                                       tape->onstream_write_error = 1;
+                                       tape->onstream_write_error = OS_WRITE_ERROR;
                                        remove_stage = 0;
                                        tape->nr_pending_stages++;
                                        tape->next_stage = tape->first_stage;
@@ -1883,11 +1937,11 @@
                printk (KERN_INFO "ide-tape: Reached 
idetape_request_sense_callback\n");
 #endif /* IDETAPE_DEBUG_LOG */
        if (!tape->pc->error) {
-               idetape_analyze_error (drive,(idetape_request_sense_result_t *) 
tape->pc->buffer);
-               idetape_end_request (1,HWGROUP (drive));
+               idetape_analyze_error (drive, (idetape_request_sense_result_t *) 
+tape->pc->buffer);
+               idetape_end_request (1, HWGROUP (drive));
        } else {
                printk (KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting 
request!\n");
-               idetape_end_request (0,HWGROUP (drive));
+               idetape_end_request (0, HWGROUP (drive));
        }
        return ide_stopped;
 }
@@ -1980,7 +2034,7 @@
        idetape_status_reg_t status;
        idetape_bcount_reg_t bcount;
        idetape_ireason_reg_t ireason;
-       idetape_pc_t *pc=tape->pc;
+       idetape_pc_t *pc = tape->pc;
 
        unsigned int temp;
        unsigned long cmd_time;
@@ -2011,7 +2065,7 @@
                         */
                        set_bit (PC_DMA_ERROR, &pc->flags);
                } else if (!status.b.check) {
-                       pc->actually_transferred=pc->request_transfer;
+                       pc->actually_transferred = pc->request_transfer;
                        idetape_update_buffers (pc);
                }
 #if IDETAPE_DEBUG_LOG
@@ -2064,7 +2118,7 @@
                        return ide_stopped;
                }
                if (tape->failed_pc == pc)
-                       tape->failed_pc=NULL;
+                       tape->failed_pc = NULL;
                return pc->callback(drive);                     /* Command finished - 
Call the callback function */
        }
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -2075,9 +2129,9 @@
                return ide_do_reset (drive);
        }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
-       bcount.b.high=IN_BYTE (IDE_BCOUNTH_REG);                        /* Get the 
number of bytes to transfer */
-       bcount.b.low=IN_BYTE (IDE_BCOUNTL_REG);                         /* on this 
interrupt */
-       ireason.all=IN_BYTE (IDE_IREASON_REG);
+       bcount.b.high = IN_BYTE (IDE_BCOUNTH_REG);                      /* Get the 
+number of bytes to transfer */
+       bcount.b.low  = IN_BYTE (IDE_BCOUNTL_REG);                      /* on this 
+interrupt */
+       ireason.all   = IN_BYTE (IDE_IREASON_REG);
 
        if (ireason.b.cod) {
                printk (KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n");
@@ -2093,8 +2147,8 @@
                if ( temp > pc->request_transfer) {
                        if (temp > pc->buffer_size) {
                                printk (KERN_ERR "ide-tape: The tape wants to send us 
more data than expected - discarding data\n");
-                               idetape_discard_data (drive,bcount.all);
-                               ide_set_handler 
(drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL);
+                               idetape_discard_data (drive, bcount.all);
+                               ide_set_handler (drive, &idetape_pc_intr, 
+IDETAPE_WAIT_CMD, NULL);
                                return ide_started;
                        }
 #if IDETAPE_DEBUG_LOG
@@ -2114,13 +2168,13 @@
                else
                        atapi_input_bytes (drive,pc->current_position,bcount.all);     
 /* Read the current buffer */
        }
-       pc->actually_transferred+=bcount.all;                                   /* 
Update the current position */
+       pc->actually_transferred += bcount.all;                                 /* 
+Update the current position */
        pc->current_position+=bcount.all;
 #if IDETAPE_DEBUG_LOG
        if (tape->debug_level >= 2)
                printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that 
interrupt\n", pc->c[0], bcount.all);
 #endif
-       ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL);         /* And 
set the interrupt handler again */
+       ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);      /* And 
+set the interrupt handler again */
        return ide_started;
 }
 
@@ -2178,7 +2232,7 @@
                printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ 
isn't asserted\n");
                return startstop;
        }
-       ireason.all=IN_BYTE (IDE_IREASON_REG);
+       ireason.all = IN_BYTE (IDE_IREASON_REG);
        while (retries-- && (!ireason.b.cod || ireason.b.io)) {
                printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet 
command, retrying\n");
                udelay(100);
@@ -2203,7 +2257,7 @@
 {
        idetape_tape_t *tape = drive->driver_data;
        idetape_bcount_reg_t bcount;
-       int dma_ok=0;
+       int dma_ok = 0;
 
 #if IDETAPE_DEBUG_BUGS
        if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD && pc->c[0] == 
IDETAPE_REQUEST_SENSE_CMD) {
@@ -2212,8 +2266,8 @@
 #endif /* IDETAPE_DEBUG_BUGS */
 
        if (tape->failed_pc == NULL && pc->c[0] != IDETAPE_REQUEST_SENSE_CMD)
-               tape->failed_pc=pc;
-       tape->pc=pc;                                                    /* Set the 
current packet command */
+               tape->failed_pc = pc;
+       tape->pc = pc;                                                  /* Set the 
+current packet command */
 
        if (pc->retries > IDETAPE_MAX_PC_RETRIES || test_bit (PC_ABORT, &pc->flags)) {
                /*
@@ -2223,24 +2277,25 @@
                 *      example).
                 */
                if (!test_bit (PC_ABORT, &pc->flags)) {
-                       if (!(pc->c[0] == 0 && tape->sense_key == 2 && tape->asc == 4 
&& (tape->ascq == 1 || tape->ascq == 8))) {
+                       if (!(pc->c[0] == IDETAPE_TEST_UNIT_READY_CMD && 
+tape->sense_key == 2 &&
+                             tape->asc == 4 && (tape->ascq == 1 || tape->ascq == 8))) 
+{
                                printk (KERN_ERR "ide-tape: %s: I/O error, pc = %2x, 
key = %2x, asc = %2x, ascq = %2x\n",
                                        tape->name, pc->c[0], tape->sense_key, 
tape->asc, tape->ascq);
-                               if (tape->onstream && pc->c[0] == 8 && tape->sense_key 
== 3 && tape->asc == 0x11)  /* AJN-1: 11 should be 0x11 */
+                               if (tape->onstream && pc->c[0] == IDETAPE_READ_CMD && 
+tape->sense_key == 3 && tape->asc == 0x11)  /* AJN-1: 11 should be 0x11 */
                                        printk(KERN_ERR "ide-tape: %s: enabling read 
error recovery\n", tape->name);
                        }
                        pc->error = IDETAPE_ERROR_GENERAL;              /* Giving up */
                }
-               tape->failed_pc=NULL;
+               tape->failed_pc = NULL;
                return pc->callback(drive);
        }
 #if IDETAPE_DEBUG_LOG
        if (tape->debug_level >= 2)
-               printk (KERN_INFO "ide-tape: Retry number - %d\n",pc->retries);
+               printk (KERN_INFO "ide-tape: Retry number - %d\n", pc->retries);
 #endif /* IDETAPE_DEBUG_LOG */
 
        pc->retries++;
-       pc->actually_transferred=0;                                     /* We haven't 
transferred any data yet */
+       pc->actually_transferred = 0;                                   /* We haven't 
+transferred any data yet */
        pc->current_position=pc->buffer;
        bcount.all=pc->request_transfer;                                /* Request to 
transfer the entire buffer at once */
 
@@ -2250,15 +2305,15 @@
                (void) HWIF(drive)->dmaproc(ide_dma_off, drive);
        }
        if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
-               dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? 
ide_dma_write : ide_dma_read, drive);
+               dma_ok = !HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? 
+ide_dma_write : ide_dma_read, drive);
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
        if (IDE_CONTROL_REG)
-               OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
-       OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG);                        /* Use PIO/DMA 
*/
-       OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);
-       OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);
-       OUT_BYTE (drive->select.all,IDE_SELECT_REG);
+               OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
+       OUT_BYTE (dma_ok ? 1 : 0,    IDE_FEATURE_REG);                  /* Use PIO/DMA 
+*/
+       OUT_BYTE (bcount.b.high,     IDE_BCOUNTH_REG);
+       OUT_BYTE (bcount.b.low,      IDE_BCOUNTL_REG);
+       OUT_BYTE (drive->select.all, IDE_SELECT_REG);
 #ifdef CONFIG_BLK_DEV_IDEDMA
        if (dma_ok) {                                           /* Begin DMA, if 
necessary */
                set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
@@ -2287,7 +2342,7 @@
                printk (KERN_INFO "ide-tape: Reached idetape_pc_callback\n");
 #endif /* IDETAPE_DEBUG_LOG */
 
-       idetape_end_request (tape->pc->error ? 0:1, HWGROUP(drive));
+       idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive));
        return ide_stopped;
 }
 
@@ -2333,7 +2388,7 @@
        if (tape->debug_level >= 1)
                printk(KERN_INFO "ide-tape: buffer fill callback, %d/%d\n", 
tape->cur_frames, tape->max_frames);
 #endif
-       idetape_end_request (tape->pc->error ? 0:1, HWGROUP(drive));
+       idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive));
        return ide_stopped;
 }
 
@@ -2344,7 +2399,7 @@
 
        pc = idetape_next_pc_storage (drive);
        rq = idetape_next_rq_storage (drive);
-       idetape_create_mode_sense_cmd (pc, 0x33);
+       idetape_create_mode_sense_cmd (pc, IDETAPE_BUFFER_FILLING_PAGE);
        pc->callback = idetape_onstream_buffer_fill_callback;
        idetape_queue_pc_head (drive, pc, rq);
 }
@@ -2564,7 +2619,7 @@
                 *      We do not support buffer cache originated requests.
                 */
                printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request 
queue (%d)\n", drive->name, rq->cmd);
-               ide_end_request (0,HWGROUP (drive));                    /* Let the 
common code handle it */
+               ide_end_request (0, HWGROUP (drive));                   /* Let the 
+common code handle it */
                return ide_stopped;
        }
 
@@ -2578,7 +2633,7 @@
        if (postponed_rq != NULL)
                if (rq != postponed_rq) {
                        printk (KERN_ERR "ide-tape: ide-tape.c bug - Two DSC requests 
were queued\n");
-                       idetape_end_request (0,HWGROUP (drive));
+                       idetape_end_request (0, HWGROUP (drive));
                        return ide_stopped;
                }
 #endif /* IDETAPE_DEBUG_BUGS */
@@ -2624,8 +2679,15 @@
                tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - 
tape->insert_time);
        calculate_speeds(drive);
        if (tape->onstream && tape->max_frames &&
-          ((rq->cmd == IDETAPE_WRITE_RQ && (tape->cur_frames == tape->max_frames || 
(tape->speed_control && tape->cur_frames > 5 && (tape->insert_speed > 
tape->max_insert_speed || (0 /* tape->cur_frames > 30 && tape->tape_still_time > 200 
*/))))) ||
-           (rq->cmd == IDETAPE_READ_RQ && (tape->cur_frames == 0 || 
(tape->speed_control && (tape->cur_frames < tape->max_frames - 5) && 
tape->insert_speed > tape->max_insert_speed)) && rq->nr_sectors))) {
+           ((rq->cmd == IDETAPE_WRITE_RQ &&
+              ( tape->cur_frames == tape->max_frames ||
+                ( tape->speed_control && tape->cur_frames > 5 &&
+                       (tape->insert_speed > tape->max_insert_speed ||
+                        (0 /* tape->cur_frames > 30 && tape->tape_still_time > 200 
+*/) ) ) ) ) ||
+            (rq->cmd == IDETAPE_READ_RQ &&
+             ( tape->cur_frames == 0 ||
+               ( tape->speed_control && (tape->cur_frames < tape->max_frames - 5) &&
+                       tape->insert_speed > tape->max_insert_speed ) ) && 
+rq->nr_sectors) ) ) {
 #if IDETAPE_DEBUG_LOG
                if (tape->debug_level >= 4)
                        printk(KERN_INFO "ide-tape: postponing request, cmd %d, cur 
%d, max %d\n",
@@ -2672,7 +2734,7 @@
                                if (jiffies > tape->last_buffer_fill + 5 * HZ / 100)
                                        tape->req_buffer_fill = 1;
                        }
-                       pc=idetape_next_pc_storage (drive);
+                       pc = idetape_next_pc_storage (drive);
                        idetape_create_read_cmd (tape, pc, rq->current_nr_sectors, 
rq->bh);
                        break;
                case IDETAPE_WRITE_RQ:
@@ -2689,12 +2751,12 @@
                                        tape->req_buffer_fill = 1;
                                calculate_speeds(drive);
                        }
-                       pc=idetape_next_pc_storage (drive);
+                       pc = idetape_next_pc_storage (drive);
                        idetape_create_write_cmd (tape, pc, rq->current_nr_sectors, 
rq->bh);
                        break;
                case IDETAPE_READ_BUFFER_RQ:
                        tape->postpone_cnt = 0;
-                       pc=idetape_next_pc_storage (drive);
+                       pc = idetape_next_pc_storage (drive);
                        idetape_create_read_buffer_cmd (tape, pc, 
rq->current_nr_sectors, rq->bh);
                        break;
                case IDETAPE_ABORTED_WRITE_RQ:
@@ -2710,7 +2772,7 @@
                        idetape_end_request (IDETAPE_ERROR_EOD, HWGROUP(drive));
                        return ide_stopped;
                case IDETAPE_PC_RQ1:
-                       pc=(idetape_pc_t *) rq->buffer;
+                       pc = (idetape_pc_t *) rq->buffer;
                        rq->cmd = IDETAPE_PC_RQ2;
                        break;
                case IDETAPE_PC_RQ2:
@@ -2718,7 +2780,7 @@
                        return ide_stopped;
                default:
                        printk (KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n");
-                       idetape_end_request (0,HWGROUP (drive));
+                       idetape_end_request (0, HWGROUP (drive));
                        return ide_stopped;
        }
        return idetape_issue_packet_command (drive, pc);
@@ -2844,7 +2906,9 @@
 #endif /* IDETAPE_DEBUG_BUGS */
                count = IDE_MIN (bh->b_size - atomic_read(&bh->b_count), n);
                copy_from_user (bh->b_data + atomic_read(&bh->b_count), buf, count);
-               n -= count; atomic_add(count, &bh->b_count); buf += count;
+               n -= count;
+               atomic_add(count, &bh->b_count);
+               buf += count;
                if (atomic_read(&bh->b_count) == bh->b_size) {
                        bh = bh->b_reqnext;
                        if (bh)
@@ -2868,7 +2932,10 @@
 #endif /* IDETAPE_DEBUG_BUGS */
                count = IDE_MIN (tape->b_count, n);
                copy_to_user (buf, tape->b_data, count);
-               n -= count; tape->b_data += count; tape->b_count -= count; buf += 
count;
+               n -= count;
+               tape->b_data += count;
+               tape->b_count -= count;
+               buf += count;
                if (!tape->b_count) {
                        tape->bh = bh = bh->b_reqnext;
                        if (bh) {
@@ -2920,10 +2987,10 @@
        if (tape->last_stage != NULL)
                tape->last_stage->next=stage;
        else
-               tape->first_stage=tape->next_stage=stage;
-       tape->last_stage=stage;
+               tape->first_stage = tape->next_stage=stage;
+       tape->last_stage = stage;
        if (tape->next_stage == NULL)
-               tape->next_stage=tape->last_stage;
+               tape->next_stage = tape->last_stage;
        tape->nr_stages++;
        tape->nr_pending_stages++;
        spin_unlock_irqrestore(&tape->spinlock, flags);
@@ -2953,26 +3020,21 @@
                par->par_desc_ver = OS_PARTITION_VERSION;
                par->wrt_pass_cntr = htons(0xffff);
                par->first_frame_addr = htonl(0);
-               par->last_frame_addr = htonl(0xbb7);
+               par->last_frame_addr = htonl(0xbb7); /* 2999 */
+               aux->frame_seq_num = htonl(0);
+               aux->logical_blk_num_high = htonl(0);
+               aux->logical_blk_num = htonl(0);
+               aux->next_mark_addr = htonl(tape->first_mark_addr);
        } else {
                aux->update_frame_cntr = htonl(0);
                par->partition_num = OS_DATA_PARTITION;
                par->par_desc_ver = OS_PARTITION_VERSION;
                par->wrt_pass_cntr = htons(tape->wrt_pass_cntr);
-               par->first_frame_addr = htonl(0x14);
-               par->last_frame_addr = htonl(19239 * 24);
-       }
-       if (frame_type != OS_FRAME_TYPE_HEADER) {
+               par->first_frame_addr = htonl(OS_DATA_STARTFRAME1);
+               par->last_frame_addr = htonl(tape->capacity);
                aux->frame_seq_num = htonl(logical_blk_num);
                aux->logical_blk_num_high = htonl(0);
                aux->logical_blk_num = htonl(logical_blk_num);
-       } else {
-               aux->frame_seq_num = htonl(0);
-               aux->logical_blk_num_high = htonl(0);
-               aux->logical_blk_num = htonl(0);
-       }
-
-       if (frame_type != OS_FRAME_TYPE_HEADER) {
                dat->dat_sz = 8;
                dat->reserved1 = 0;
                dat->entry_cnt = 1;
@@ -2987,11 +3049,10 @@
                else
                        dat->dat_list[0].flags = OS_DAT_FLAGS_DATA;
                dat->dat_list[0].reserved = 0;
-       } else
-               aux->next_mark_addr = htonl(tape->first_mark_addr);
-       aux->filemark_cnt = ntohl(tape->filemark_cnt);
-       aux->phys_fm = ntohl(0xffffffff);
-       aux->last_mark_addr = ntohl(tape->last_mark_addr);
+       } 
+       aux->filemark_cnt = ntohl(tape->filemark_cnt);          /* shouldn't this be 
+htonl ?? */
+       aux->phys_fm = ntohl(0xffffffff);                       /* shouldn't this be 
+htonl ?? */
+       aux->last_mark_addr = ntohl(tape->last_mark_addr);      /* shouldn't this be 
+htonl ?? */
 }
 
 /*
@@ -3042,7 +3103,7 @@
                if (result->bpu) {
                        printk (KERN_INFO "ide-tape: Block location is unknown to the 
tape\n");
                        clear_bit (IDETAPE_ADDRESS_VALID, &tape->flags);
-                       idetape_end_request (0,HWGROUP (drive));
+                       idetape_end_request (0, HWGROUP (drive));
                } else {
 #if IDETAPE_DEBUG_LOG
                        if (tape->debug_level >= 2)
@@ -3053,10 +3114,10 @@
                        tape->last_frame_position = ntohl (result->last_block);
                        tape->blocks_in_buffer = result->blocks_in_buffer[2];
                        set_bit (IDETAPE_ADDRESS_VALID, &tape->flags);
-                       idetape_end_request (1,HWGROUP (drive));
+                       idetape_end_request (1, HWGROUP (drive));
                }
        } else {
-               idetape_end_request (0,HWGROUP (drive));
+               idetape_end_request (0, HWGROUP (drive));
        }
        return ide_stopped;
 }
@@ -3076,8 +3137,8 @@
        idetape_init_pc (pc);
        pc->c[0] = IDETAPE_WRITE_FILEMARK_CMD;
        if (tape->onstream)
-               pc->c[1] = 1;
-       pc->c[4] = write_filemark;
+               pc->c[1] = 1; /* Immed bit */
+       pc->c[4] = write_filemark;  /* not used for OnStream ?? */
        set_bit (PC_WAIT_FOR_DSC, &pc->flags);
        pc->callback = &idetape_pc_callback;
 }
@@ -3109,7 +3170,7 @@
  *     the request 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,idetape_pc_t *pc)
+static int __idetape_queue_pc_tail (ide_drive_t *drive, idetape_pc_t *pc)
 {
        struct request rq;
 
@@ -3150,7 +3211,7 @@
                        return 0;
                if (tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) {
                        idetape_create_load_unload_cmd (drive, &pc, 
IDETAPE_LU_LOAD_MASK);
-                       __idetape_queue_pc_tail(drive,&pc);
+                       __idetape_queue_pc_tail(drive, &pc);
                        idetape_create_test_unit_ready_cmd(&pc);
                        if (!__idetape_queue_pc_tail(drive, &pc))
                                return 0;
@@ -3169,7 +3230,8 @@
        int rc;
 
        rc = __idetape_queue_pc_tail(drive, pc);
-       if (rc) return rc;
+       if (rc)
+               return rc;
        if (tape->onstream && test_bit(PC_WAIT_FOR_DSC, &pc->flags))
                rc = idetape_wait_ready(drive, 60 * 10 * HZ);   /* AJN-4: Changed from 
5 to 10 minutes;
                           because retension takes approx. 8:20 with Onstream 30GB 
tape */
@@ -3182,7 +3244,7 @@
        int rc;
 
        idetape_create_write_filemark_cmd(drive, &pc, 0);
-       if ((rc = idetape_queue_pc_tail (drive,&pc)))
+       if ((rc = idetape_queue_pc_tail (drive, &pc)))
                return rc;
        idetape_wait_ready(drive, 60 * 5 * HZ);
        return 0;
@@ -3206,7 +3268,7 @@
        idetape_flush_tape_buffers(drive);
 #endif
        idetape_create_read_position_cmd(&pc);
-       if (idetape_queue_pc_tail (drive,&pc))
+       if (idetape_queue_pc_tail (drive, &pc))
                return -1;
        position = tape->first_frame_position;
 #ifdef NO_LONGER_REQUIRED
@@ -3231,12 +3293,17 @@
        idetape_init_pc (pc);
        pc->c[0] = IDETAPE_LOCATE_CMD;
        if (tape->onstream)
-               pc->c[1] = 1;
+               pc->c[1] = 1; /* Immediate bit */
        else
                pc->c[1] = 2;
        put_unaligned (htonl (block), (unsigned int *) &pc->c[3]);
        pc->c[8] = partition;
        if (tape->onstream)
+                /*
+                 * Set SKIP bit.
+                 * In case of write error this will write buffered
+                 * data in the drive to this new position!
+                 */
                pc->c[9] = skip << 7;
        set_bit (PC_WAIT_FOR_DSC, &pc->flags);
        pc->callback = &idetape_pc_callback;
@@ -3307,11 +3374,12 @@
                __idetape_discard_read_pipeline(drive);
        idetape_wait_ready(drive, 60 * 5 * HZ);
        idetape_create_locate_cmd (drive, &pc, block, partition, skip);
-       retval=idetape_queue_pc_tail (drive,&pc);
-       if (retval) return (retval);
+       retval = idetape_queue_pc_tail (drive, &pc);
+       if (retval)
+               return (retval);
 
        idetape_create_read_position_cmd (&pc);
-       return (idetape_queue_pc_tail (drive,&pc));
+       return (idetape_queue_pc_tail (drive, &pc));
 }
 
 static void idetape_discard_read_pipeline (ide_drive_t *drive, int restore_position)
@@ -3339,7 +3407,7 @@
 {
        idetape_pc_t pc;
 
-       idetape_create_mode_sense_cmd (&pc, 0x33);
+       idetape_create_mode_sense_cmd (&pc, IDETAPE_BUFFER_FILLING_PAGE);
        pc.callback = idetape_onstream_buffer_fill_callback;
        (void) idetape_queue_pc_tail(drive, &pc);
 }
@@ -3447,33 +3515,41 @@
        idetape_tape_t *tape = drive->driver_data;
        unsigned int block;
 
-       if (tape->onstream_write_error == 1) {
-               printk(KERN_ERR "ide-tape: %s: detected physical bad block at %u\n", 
tape->name, ntohl(tape->sense.information));
-               block = ntohl(tape->sense.information) + 80;
+       if (tape->onstream_write_error == OS_WRITE_ERROR) {
+               printk(KERN_ERR "ide-tape: %s: onstream_write_error_recovery: detected 
+physical bad block at %u, logical %u first frame %u last_frame %u bufblocks %u stages 
+%u skipping %u frames\n",
+                       tape->name, ntohl(tape->sense.information), 
+tape->logical_blk_num,
+                       tape->first_frame_position, tape->last_frame_position,
+                       tape->blocks_in_buffer, tape->nr_stages,
+                       (ntohl(tape->sense.command_specific) >> 16) & 0xff );
+               block = ntohl(tape->sense.information) + 
+((ntohl(tape->sense.command_specific) >> 16) & 0xff);
                idetape_update_stats(drive);
                printk(KERN_ERR "ide-tape: %s: relocating %d buffered logical blocks 
to physical block %u\n", tape->name, tape->cur_frames, block);
+#if 0  /* isn't once enough ??? MM */
                idetape_update_stats(drive);
+#endif
                if (tape->firmware_revision_num >= 106)
                        idetape_position_tape(drive, block, 0, 1);
                else {
                        idetape_onstream_read_back_buffer(drive);
                        idetape_position_tape(drive, block, 0, 0);
                }
+#if 0     /* already done in idetape_position_tape MM */
                idetape_read_position(drive);
+#endif
 #if ONSTREAM_DEBUG
                if (tape->debug_level >= 1)
                        printk(KERN_ERR "ide-tape: %s: positioning complete, 
cur_frames %d, pos %d, tape pos %d\n", tape->name, tape->cur_frames, 
tape->first_frame_position, tape->last_frame_position);
 #endif
-       } else if (tape->onstream_write_error == 2) {
+       } else if (tape->onstream_write_error == OS_PART_ERROR) {
 #if ONSTREAM_DEBUG
                if (tape->debug_level >= 1)
                        printk(KERN_INFO "ide-tape: %s: skipping over config 
partition\n", tape->name);
 #endif
                idetape_flush_tape_buffers(drive);
                block = idetape_read_position(drive);
-               if (block != 0xba4) 
-                       printk(KERN_ERR "ide-tape: warning, current position %d, 
expected %d\n", block, 0xba4);
-               idetape_position_tape(drive, 0xbb8, 0, 0);
+               if (block != OS_DATA_ENDFRAME1)  
+                       printk(KERN_ERR "ide-tape: warning, current position %d, 
+expected %d\n", block, OS_DATA_ENDFRAME1);
+               idetape_position_tape(drive, 0xbb8, 0, 0); /* 3000 */
        }
        tape->onstream_write_error = 0;
 }
@@ -3572,48 +3648,48 @@
                return 1;
        }
        if (rq->errors == IDETAPE_ERROR_GENERAL) {
-               printk(KERN_INFO "ide-tape: %s: skipping frame, read error\n", 
tape->name);
+               printk(KERN_INFO "ide-tape: %s: skipping frame %d, read error\n", 
+tape->name, tape->first_frame_position);
                return 0;
        }
        if (rq->errors == IDETAPE_ERROR_EOD) {
-               printk(KERN_INFO "ide-tape: %s: skipping frame, eod\n", tape->name);
+               printk(KERN_INFO "ide-tape: %s: skipping frame %d, eod\n", tape->name, 
+tape->first_frame_position);
                return 0;
        }
        if (ntohl(aux->format_id) != 0) {
-               printk(KERN_INFO "ide-tape: %s: skipping frame, format_id %u\n", 
tape->name, ntohl(aux->format_id));
+               printk(KERN_INFO "ide-tape: %s: skipping frame %d, format_id %u\n", 
+tape->name, tape->first_frame_position, ntohl(aux->format_id));
                return 0;
        }
        if (memcmp(aux->application_sig, tape->application_sig, 4) != 0) {
-               printk(KERN_INFO "ide-tape: %s: skipping frame, incorrect application 
signature\n", tape->name);
+               printk(KERN_INFO "ide-tape: %s: skipping frame %d, incorrect 
+application signature\n", tape->name, tape->first_frame_position);
                return 0;
        }
        if (aux->frame_type != OS_FRAME_TYPE_DATA &&
            aux->frame_type != OS_FRAME_TYPE_EOD &&
            aux->frame_type != OS_FRAME_TYPE_MARKER) {
-               printk(KERN_INFO "ide-tape: %s: skipping frame, frame type %x\n", 
tape->name, aux->frame_type);
+               printk(KERN_INFO "ide-tape: %s: skipping frame %d, frame type %x\n", 
+tape->name, tape->first_frame_position, aux->frame_type);
                return 0;
        }
        if (par->partition_num != OS_DATA_PARTITION) {
                if (!tape->linux_media || tape->linux_media_version != 2) {
-                       printk(KERN_INFO "ide-tape: %s: skipping frame, partition num 
%d\n", tape->name, par->partition_num);
+                       printk(KERN_INFO "ide-tape: %s: skipping frame %d, partition 
+num %d\n", tape->name, tape->first_frame_position, par->partition_num);
                        return 0;
                }
        }
        if (par->par_desc_ver != OS_PARTITION_VERSION) {
-               printk(KERN_INFO "ide-tape: %s: skipping frame, partition version 
%d\n", tape->name, par->par_desc_ver);
+               printk(KERN_INFO "ide-tape: %s: skipping frame %d, partition version 
+%d\n", tape->name, tape->first_frame_position, par->par_desc_ver);
                return 0;
        }
        if (ntohs(par->wrt_pass_cntr) != tape->wrt_pass_cntr) {
-               printk(KERN_INFO "ide-tape: %s: skipping frame, wrt_pass_cntr %d 
(expected %d)(logical_blk_num %u)\n", tape->name, ntohs(par->wrt_pass_cntr), 
tape->wrt_pass_cntr, ntohl(aux->logical_blk_num));
+               printk(KERN_INFO "ide-tape: %s: skipping frame %d, wrt_pass_cntr %d 
+(expected %d)(logical_blk_num %u)\n", tape->name, tape->first_frame_position, 
+ntohs(par->wrt_pass_cntr), tape->wrt_pass_cntr, ntohl(aux->logical_blk_num));
                return 0;
        }
        if (aux->frame_seq_num != aux->logical_blk_num) {
-               printk(KERN_INFO "ide-tape: %s: skipping frame, seq != logical\n", 
tape->name);
+               printk(KERN_INFO "ide-tape: %s: skipping frame %d, seq != logical\n", 
+tape->name, tape->first_frame_position);
                return 0;
        }
        if (logical_blk_num != -1 && ntohl(aux->logical_blk_num) != logical_blk_num) {
                if (!quiet)
-                       printk(KERN_INFO "ide-tape: %s: skipping frame, 
logical_blk_num %u (expected %d)\n", tape->name, ntohl(aux->logical_blk_num), 
logical_blk_num);
+                       printk(KERN_INFO "ide-tape: %s: skipping frame %d, 
+logical_blk_num %u (expected %d)\n", tape->name, tape->first_frame_position, 
+ntohl(aux->logical_blk_num), logical_blk_num);
                return 0;
        }
        if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
@@ -3689,7 +3765,7 @@
        idetape_switch_buffers (tape, new_stage);
        idetape_init_stage(drive, new_stage, OS_FRAME_TYPE_DATA, 
tape->logical_blk_num);
        tape->logical_blk_num++;
-       idetape_add_stage_tail (drive,new_stage);
+       idetape_add_stage_tail (drive, new_stage);
        tape->pipeline_head++;
 #if USE_IOTRACE
        IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, 
tape->tape_head, tape->minor);
@@ -3766,7 +3842,7 @@
        }
 #endif /* IDETAPE_DEBUG_BUGS */
        if (tape->merge_stage_size) {
-               blocks=tape->merge_stage_size/tape->tape_block_size;
+               blocks = tape->merge_stage_size / tape->tape_block_size;
                if (tape->merge_stage_size % tape->tape_block_size) {
                        blocks++;
                        i = tape->tape_block_size - tape->merge_stage_size % 
tape->tape_block_size;
@@ -3797,7 +3873,7 @@
                tape->merge_stage = NULL;
        }
        clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags);
-       tape->chrdev_direction=idetape_direction_none;
+       tape->chrdev_direction = idetape_direction_none;
 
        /*
         *      On the next backup, perform the feedback loop again.
@@ -3874,13 +3950,13 @@
        rq.sector = tape->first_frame_position;
        rq.nr_sectors = rq.current_nr_sectors = blocks;
        if (!test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags) && tape->nr_stages <= 
max_stages) {
-               new_stage=idetape_kmalloc_stage (tape);
+               new_stage = idetape_kmalloc_stage (tape);
                while (new_stage != NULL) {
-                       new_stage->rq=rq;
-                       idetape_add_stage_tail (drive,new_stage);
+                       new_stage->rq = rq;
+                       idetape_add_stage_tail (drive, new_stage);
                        if (tape->nr_stages >= max_stages)
                                break;
-                       new_stage=idetape_kmalloc_stage (tape);
+                       new_stage = idetape_kmalloc_stage (tape);
                }
        }
        if (!idetape_pipeline_active(tape)) {
@@ -3922,16 +3998,23 @@
 #endif
                                clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
                                position = idetape_read_position(drive);
+                               printk(KERN_INFO "ide-tape: %s: blank block detected 
+at %d\n", tape->name, position);
                                if (position >= 3000 && position < 3080)
-                                       position += 32;
-                               if (position >= 2980 && position < 3000)
+                                       position += 32;  /* Why is this check and 
+number ??? MM */
+                               if (position >= OS_DATA_ENDFRAME1 && position < 3000)
                                        position = 3000;
                                else
+                                       /*
+                                        * compensate for write errors that generally 
+skip 80 frames,
+                                        * expect around 20 read errors in a row...
+                                        */
                                        position += 60;
-                               if (position >= 2980 && position < 3000)
+                               if (position >= OS_DATA_ENDFRAME1 && position < 3000)
                                        position = 3000;
-                               printk(KERN_INFO "ide-tape: %s: blank block detected, 
positioning tape to block %d\n", tape->name, position);
-                               idetape_position_tape(drive, position, 0, 1);
+                               printk(KERN_INFO "ide-tape: %s: positioning tape to 
+block %d\n", tape->name, position);
+                               if (position == 3000)  /* seems to be needed to 
+correctly position at block 3000 MM */
+                                       idetape_position_tape(drive, 0, 0, 0);
+                               idetape_position_tape(drive, position, 0, 0);
                                cnt += 40;
                                continue;
                        } else
@@ -4089,12 +4172,14 @@
 #endif /* IDETAPE_DEBUG_LOG */ 
        
        idetape_create_rewind_cmd (drive, &pc);
-       retval=idetape_queue_pc_tail (drive,&pc);
-       if (retval) return retval;
+       retval = idetape_queue_pc_tail (drive, &pc);
+       if (retval)
+               return retval;
 
        idetape_create_read_position_cmd (&pc);
-       retval = idetape_queue_pc_tail (drive,&pc);
-       if (retval) return retval;
+       retval = idetape_queue_pc_tail (drive, &pc);
+       if (retval)
+               return retval;
        tape->logical_blk_num = 0;
        return 0;
 }
@@ -4412,7 +4497,7 @@
        switch (mt_op) {
                case MTFSF:
                        idetape_create_space_cmd 
(&pc,mt_count-count,IDETAPE_SPACE_OVER_FILEMARK);
-                       return (idetape_queue_pc_tail (drive,&pc));
+                       return (idetape_queue_pc_tail (drive, &pc));
                case MTFSFM:
                        if (!tape->capabilities.sprev)
                                return (-EIO);
@@ -4423,7 +4508,7 @@
                        if (!tape->capabilities.sprev)
                                return (-EIO);
                        idetape_create_space_cmd 
(&pc,-(mt_count+count),IDETAPE_SPACE_OVER_FILEMARK);
-                       return (idetape_queue_pc_tail (drive,&pc));
+                       return (idetape_queue_pc_tail (drive, &pc));
                case MTBSFM:
                        if (!tape->capabilities.sprev)
                                return (-EIO);
@@ -4460,7 +4545,7 @@
        struct inode *inode = file->f_dentry->d_inode;
        ide_drive_t *drive = get_drive_ptr (inode->i_rdev);
        idetape_tape_t *tape = drive->driver_data;
-       ssize_t bytes_read,temp,actually_read=0, rc;
+       ssize_t bytes_read,temp, actually_read = 0, rc;
 
        if (ppos != &file->f_pos) {
                /* "A request was outside the capabilities of the device." */
@@ -4482,28 +4567,32 @@
        }
        if ((rc = idetape_initiate_read(drive, tape->max_stages)) < 0)
                return rc;
-       if (count==0)
+       if (count == 0)
                return (0);
        if (tape->merge_stage_size) {
-               actually_read=IDE_MIN (tape->merge_stage_size,count);
+               actually_read = IDE_MIN (tape->merge_stage_size, count);
                idetape_copy_stage_to_user (tape, buf, tape->merge_stage, 
actually_read);
-               buf += actually_read; tape->merge_stage_size -= actually_read; 
count-=actually_read;
+               buf += actually_read;
+               tape->merge_stage_size -= actually_read;
+               count -= actually_read;
        }
        while (count >= tape->stage_size) {
-               bytes_read=idetape_add_chrdev_read_request (drive, 
tape->capabilities.ctl);
+               bytes_read = idetape_add_chrdev_read_request (drive, 
+tape->capabilities.ctl);
                if (bytes_read <= 0)
                        goto finish;
                idetape_copy_stage_to_user (tape, buf, tape->merge_stage, bytes_read);
-               buf += bytes_read; count -= bytes_read; actually_read += bytes_read;
+               buf += bytes_read;
+               count -= bytes_read;
+               actually_read += bytes_read;
        }
        if (count) {
                bytes_read=idetape_add_chrdev_read_request (drive, 
tape->capabilities.ctl);
                if (bytes_read <= 0)
                        goto finish;
-               temp=IDE_MIN (count,bytes_read);
+               temp = IDE_MIN (count, bytes_read);
                idetape_copy_stage_to_user (tape, buf, tape->merge_stage, temp);
-               actually_read+=temp;
-               tape->merge_stage_size=bytes_read-temp;
+               actually_read += temp;
+               tape->merge_stage_size = bytes_read-temp;
        }
 finish:
        if (!actually_read && test_bit (IDETAPE_FILEMARK, &tape->flags)) {
@@ -4515,7 +4604,8 @@
                return 0;
        }
        if (tape->onstream && !actually_read && test_and_clear_bit(IDETAPE_READ_ERROR, 
&tape->flags)) {
-               printk(KERN_ERR "ide-tape: %s: unrecovered read error on logical block 
number %d, skipping\n", tape->name, tape->logical_blk_num);
+               printk(KERN_ERR "ide-tape: %s: unrecovered read error on logical block 
+number %d, skipping\n",
+                                       tape->name, tape->logical_blk_num);
                tape->logical_blk_num++;
                return -EIO;
        }
@@ -4576,6 +4666,37 @@
        return;
 }
 
+static void idetape_write_filler (ide_drive_t *drive, int block, int cnt)
+{
+       idetape_tape_t *tape = drive->driver_data;
+       idetape_stage_t *stage;
+       int rc;
+
+       if (!tape->onstream || tape->raw)
+               return;
+       stage = __idetape_kmalloc_stage(tape, 1, 1);
+       if (stage == NULL)
+               return;
+       idetape_init_stage(drive, stage, OS_FRAME_TYPE_FILL, 0);
+       idetape_wait_ready(drive, 60 * 5 * HZ);
+       rc = idetape_position_tape(drive, block, 0, 0);
+#if ONSTREAM_DEBUG
+       printk(KERN_INFO "write_filler: positioning failed it returned %d\n", rc);
+#endif
+       if (rc != 0) 
+               return; /* don't write fillers if we cannot position the tape. */
+
+       strcpy(stage->bh->b_data, "Filler");
+       while (cnt--) {
+               if (!idetape_queue_rw_tail (drive, IDETAPE_WRITE_RQ, 1, stage->bh)) {
+                       printk(KERN_INFO "ide-tape: %s: write_filler: couldn't write 
+header frame\n", tape->name);
+                       __idetape_kfree_stage (stage);
+                       return;
+               }
+       }
+       __idetape_kfree_stage (stage);
+}
+
 static void __idetape_write_header (ide_drive_t *drive, int block, int cnt)
 {
        idetape_tape_t *tape = drive->driver_data;
@@ -4591,12 +4712,12 @@
        memset(&header, 0, sizeof(header));
        strcpy(header.ident_str, "ADR_SEQ");
        header.major_rev = 1;
-       header.minor_rev = 2;
+       header.minor_rev = OS_ADR_MINREV;
        header.par_num = 1;
        header.partition.partition_num = OS_DATA_PARTITION;
        header.partition.par_desc_ver = OS_PARTITION_VERSION;
-       header.partition.first_frame_addr = htonl(0x14);
-       header.partition.last_frame_addr = htonl(19239 * 24);
+       header.partition.first_frame_addr = htonl(OS_DATA_STARTFRAME1);
+       header.partition.last_frame_addr = htonl(tape->capacity);
        header.partition.wrt_pass_cntr = htons(tape->wrt_pass_cntr);
        header.partition.eod_frame_addr = htonl(tape->eod_frame_addr);
        memcpy(stage->bh->b_data, &header, sizeof(header));
@@ -4623,7 +4744,7 @@
                return;
        tape->update_frame_cntr++;
        __idetape_write_header(drive, 5, 5);
-       __idetape_write_header(drive, 0xbae, 5);
+       __idetape_write_header(drive, 0xbae, 5); /* 2990 */
        if (locate_eod) {
 #if ONSTREAM_DEBUG
                if (tape->debug_level >= 2)
@@ -4639,22 +4760,39 @@
        struct inode *inode = file->f_dentry->d_inode;
        ide_drive_t *drive = get_drive_ptr (inode->i_rdev);
        idetape_tape_t *tape = drive->driver_data;
-       ssize_t retval,actually_written=0;
+       ssize_t retval, actually_written = 0;
        int position;
 
        if (ppos != &file->f_pos) {
                /* "A request was outside the capabilities of the device." */
                return -ENXIO;
        }
-       if (tape->onstream && (count != tape->tape_block_size)) {
-               printk(KERN_ERR "ide-tape: %s: use %d bytes as block size (%Zd 
used)\n", tape->name, tape->tape_block_size, count);
-               return -EINVAL;
-       }
+
 #if IDETAPE_DEBUG_LOG
        if (tape->debug_level >= 3)
                printk (KERN_INFO "ide-tape: Reached idetape_chrdev_write, count 
%Zd\n", count);
 #endif /* IDETAPE_DEBUG_LOG */
 
+       if (tape->onstream) {
+               if (count != tape->tape_block_size) {
+                       printk(KERN_ERR "ide-tape: %s: chrdev_write: use %d bytes as 
+block size (%d used)\n",
+                                       tape->name, tape->tape_block_size, count);
+                       return -EINVAL;
+               }
+               /*
+                * Check if we reach the end of the tape. Just assume the whole 
+pipeline
+                * is filled with write requests!
+                */
+               if (tape->first_frame_position + tape->nr_stages >= tape->capacity - 
+OS_EW)  {
+#if ONSTREAM_DEBUG
+                       printk(KERN_INFO, "chrdev_write: Write truncated at EOM early 
+warning");
+#endif
+                       if (tape->chrdev_direction == idetape_direction_write)
+                               idetape_write_release(inode);
+                       return -ENOSPC;
+               }
+       }
+
        if (tape->chrdev_direction != idetape_direction_write) {        /* Initialize 
write operation */
                if (tape->chrdev_direction == idetape_direction_read)
                        idetape_discard_read_pipeline (drive, 1);
@@ -4671,17 +4809,17 @@
 
                if (tape->onstream) {
                        position = idetape_read_position(drive);
-                       if (position <= 20) {
+                       if (position <= OS_DATA_STARTFRAME1) {
                                tape->logical_blk_num = 0;
                                tape->wrt_pass_cntr++;
 #if ONSTREAM_DEBUG
                                if (tape->debug_level >= 2)
-                                       printk(KERN_INFO "ide-tape: %s: logical block 
num 0, setting eod to 20\n", tape->name);
+                                       printk(KERN_INFO "ide-tape: %s: logical block 
+num 0, setting eod to %d\n", tape->name, OS_DATA_STARTFRAME1);
                                if (tape->debug_level >= 2)
                                        printk(KERN_INFO "ide-tape: %s: allocating new 
write pass counter %d\n", tape->name, tape->wrt_pass_cntr);
 #endif
                                tape->filemark_cnt = 0;
-                               tape->eod_frame_addr = 20;
+                               tape->eod_frame_addr = OS_DATA_STARTFRAME1;
                                tape->first_mark_addr = tape->last_mark_addr = -1;
                                idetape_write_header(drive, 1);
                        }
@@ -4715,7 +4853,7 @@
                        printk("ide-tape: first_frame_position %d\n", 
tape->first_frame_position);
 #endif
        }
-       if (count==0)
+       if (count == 0)
                return (0);
        if (tape->restart_speed_control_req)
                idetape_restart_speed_control(drive);
@@ -4723,32 +4861,35 @@
 #if IDETAPE_DEBUG_BUGS
                if (tape->merge_stage_size >= tape->stage_size) {
                        printk (KERN_ERR "ide-tape: bug: merge buffer too big\n");
-                       tape->merge_stage_size=0;
+                       tape->merge_stage_size = 0;
                }
 #endif /* IDETAPE_DEBUG_BUGS */
-               actually_written=IDE_MIN 
(tape->stage_size-tape->merge_stage_size,count);
+               actually_written = IDE_MIN (tape->stage_size - tape->merge_stage_size, 
+count);
                idetape_copy_stage_from_user (tape, tape->merge_stage, buf, 
actually_written);
-               
buf+=actually_written;tape->merge_stage_size+=actually_written;count-=actually_written;
+               buf += actually_written;
+               tape->merge_stage_size += actually_written;
+               count -= actually_written;
 
                if (tape->merge_stage_size == tape->stage_size) {
                        tape->merge_stage_size = 0;
-                       retval=idetape_add_chrdev_write_request (drive, 
tape->capabilities.ctl);
+                       retval = idetape_add_chrdev_write_request (drive, 
+tape->capabilities.ctl);
                        if (retval <= 0)
                                return (retval);
                }
        }
        while (count >= tape->stage_size) {
                idetape_copy_stage_from_user (tape, tape->merge_stage, buf, 
tape->stage_size);
-               buf+=tape->stage_size;count-=tape->stage_size;
-               retval=idetape_add_chrdev_write_request (drive, 
tape->capabilities.ctl);
-               actually_written+=tape->stage_size;
+               buf += tape->stage_size;
+               count -= tape->stage_size;
+               retval = idetape_add_chrdev_write_request (drive, 
+tape->capabilities.ctl);
+               actually_written += tape->stage_size;
                if (retval <= 0)
                        return (retval);
        }
        if (count) {
                actually_written+=count;
                idetape_copy_stage_from_user (tape, tape->merge_stage, buf, count);
-               tape->merge_stage_size+=count;
+               tape->merge_stage_size += count;
        }
        return (actually_written);
 }
@@ -4760,8 +4901,8 @@
        idetape_pc_t pc;
 
        if (!tape->onstream) {
-               idetape_create_write_filemark_cmd(drive, &pc,1);        /* Write a 
filemark */
-               if (idetape_queue_pc_tail (drive,&pc)) {
+               idetape_create_write_filemark_cmd(drive, &pc, 1);       /* Write a 
+filemark */
+               if (idetape_queue_pc_tail (drive, &pc)) {
                        printk (KERN_ERR "ide-tape: Couldn't write a filemark\n");
                        return -EIO;
                }
@@ -4937,24 +5078,24 @@
                        if (idetape_rewind_tape(drive))
                                return -EIO;
                        if (tape->onstream && !tape->raw)
-                               return idetape_position_tape(drive, 20, 0, 0);
+                               return idetape_position_tape(drive, 
+OS_DATA_STARTFRAME1, 0, 0);
                        return 0;
                case MTLOAD:
                        idetape_discard_read_pipeline (drive, 0);
                        idetape_create_load_unload_cmd (drive, &pc, 
IDETAPE_LU_LOAD_MASK);
-                       return (idetape_queue_pc_tail (drive,&pc));
+                       return (idetape_queue_pc_tail (drive, &pc));
                case MTUNLOAD:
                case MTOFFL:
                        idetape_discard_read_pipeline (drive, 0);
                        idetape_create_load_unload_cmd (drive, 
&pc,!IDETAPE_LU_LOAD_MASK);
-                       return (idetape_queue_pc_tail (drive,&pc));
+                       return (idetape_queue_pc_tail (drive, &pc));
                case MTNOP:
                        idetape_discard_read_pipeline (drive, 0);
                        return (idetape_flush_tape_buffers (drive));
                case MTRETEN:
                        idetape_discard_read_pipeline (drive, 0);
                        idetape_create_load_unload_cmd (drive, 
&pc,IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK);
-                       return (idetape_queue_pc_tail (drive,&pc));
+                       return (idetape_queue_pc_tail (drive, &pc));
                case MTEOM:
                        if (tape->onstream) {
 #if ONSTREAM_DEBUG
@@ -4968,24 +5109,30 @@
                                        return -EIO;
                                return 0;
                        }
-                       idetape_create_space_cmd (&pc,0,IDETAPE_SPACE_TO_EOD);
-                       return (idetape_queue_pc_tail (drive,&pc));
+                       idetape_create_space_cmd (&pc, 0, IDETAPE_SPACE_TO_EOD);
+                       return (idetape_queue_pc_tail (drive, &pc));
                case MTERASE:
                        if (tape->onstream) {
-                               tape->eod_frame_addr = 20;
+                               tape->eod_frame_addr = OS_DATA_STARTFRAME1;
                                tape->logical_blk_num = 0;
                                tape->first_mark_addr = tape->last_mark_addr = -1;
                                idetape_position_tape(drive, tape->eod_frame_addr, 0, 
0);
                                idetape_write_eod(drive);
                                idetape_flush_tape_buffers (drive);
                                idetape_write_header(drive, 0);
+                               /*
+                                * write filler frames to the unused frames...
+                                * REMOVE WHEN going to LIN4 application type...
+                                */
+                               idetape_write_filler(drive, OS_DATA_STARTFRAME1 - 10, 
+10);
+                               idetape_write_filler(drive, OS_DATA_ENDFRAME1, 10);
                                idetape_flush_tape_buffers (drive);
                                (void) idetape_rewind_tape (drive);
                                return 0;
                        }
                        (void) idetape_rewind_tape (drive);
                        idetape_create_erase_cmd (&pc);
-                       return (idetape_queue_pc_tail (drive,&pc));
+                       return (idetape_queue_pc_tail (drive, &pc));
                case MTSETBLK:
                        if (tape->onstream) {
                                if (mt_count != tape->tape_block_size) {
@@ -5028,14 +5175,14 @@
                case MTLOCK:
                        if (!idetape_create_prevent_cmd(drive, &pc, 1))
                                return 0;
-                       retval = idetape_queue_pc_tail (drive,&pc);
+                       retval = idetape_queue_pc_tail (drive, &pc);
                        if (retval) return retval;
                        tape->door_locked = DOOR_EXPLICITLY_LOCKED;
                        return 0;
                case MTUNLOCK:
                        if (!idetape_create_prevent_cmd(drive, &pc, 0))
                                return 0;
-                       retval = idetape_queue_pc_tail (drive,&pc);
+                       retval = idetape_queue_pc_tail (drive, &pc);
                        if (retval) return retval;
                        tape->door_locked = DOOR_UNLOCKED;
                        return 0;
@@ -5113,7 +5260,7 @@
                                mtget.mt_gstat |= GMT_ONLINE(0xffffffff);
                                if (tape->first_stage && 
tape->first_stage->aux->frame_type == OS_FRAME_TYPE_EOD)
                                        mtget.mt_gstat |= GMT_EOD(0xffffffff);
-                               if (position <= 20)
+                               if (position <= OS_DATA_STARTFRAME1)
                                        mtget.mt_gstat |= GMT_BOT(0xffffffff);
                        }
                        if (copy_to_user ((char *) arg,(char *) &mtget, sizeof (struct 
mtget)))
@@ -5150,7 +5297,7 @@
        tape->header_ok = tape->linux_media = 0;
        tape->update_frame_cntr = 0;
        tape->wrt_pass_cntr = 0;
-       tape->eod_frame_addr = 20;
+       tape->eod_frame_addr = OS_DATA_STARTFRAME1;
        tape->first_mark_addr = tape->last_mark_addr = -1;
        stage = __idetape_kmalloc_stage (tape, 0, 0);
        if (stage == NULL)
@@ -5172,8 +5319,8 @@
                __idetape_kfree_stage (stage);
                return 0;
        }
-       if (header->major_rev != 1 || (header->minor_rev != 1 && header->minor_rev != 
2))
-               printk(KERN_INFO "ide-tape: warning: revision %d.%d detected (1.1/1.2 
supported)\n", header->major_rev, header->minor_rev);
+       if (header->major_rev != 1 || (header->minor_rev > OS_ADR_MINREV))
+               printk(KERN_INFO "ide-tape: warning: revision %d.%d detected (up to 
+1.%d supported)\n", header->major_rev, header->minor_rev, OS_ADR_MINREV);
        if (header->par_num != 1)
                printk(KERN_INFO "ide-tape: warning: %d partitions defined, only one 
supported\n", header->par_num);
        tape->wrt_pass_cntr = ntohs(header->partition.wrt_pass_cntr);
@@ -5182,12 +5329,14 @@
        tape->first_mark_addr = ntohl(aux->next_mark_addr);
        tape->last_mark_addr = ntohl(aux->last_mark_addr);
        tape->update_frame_cntr = ntohl(aux->update_frame_cntr);
-       memcpy(tape->application_sig, aux->application_sig, 4); 
tape->application_sig[4] = 0;
+       memcpy(tape->application_sig, aux->application_sig, 4);
+       tape->application_sig[4] = 0;
        if (memcmp(tape->application_sig, "LIN", 3) == 0) {
                tape->linux_media = 1;
                tape->linux_media_version = tape->application_sig[3] - '0';
                if (tape->linux_media_version != 3)
-                       printk(KERN_INFO "ide-tape: %s: Linux media version %d 
detected (current 3)\n", tape->name, tape->linux_media_version);
+                       printk(KERN_INFO "ide-tape: %s: Linux media version %d 
+detected (current 3)\n",
+                                        tape->name, tape->linux_media_version);
        } else {
                printk(KERN_INFO "ide-tape: %s: non Linux media detected (%s)\n", 
tape->name, tape->application_sig);
                tape->linux_media = 0;
@@ -5214,18 +5363,14 @@
        for (block = 5; block < 10; block++)
                if (__idetape_analyze_headers(drive, block))
                        goto ok;
-#if 0
-       for (block = 0xbae; block < 0xbb8; block++)
-#else
-       for (block = 0xbae; block < 0xbb3; block++)
-#endif
+       for (block = 0xbae; block < 0xbb3; block++) /* 2990 - 2994 */
                if (__idetape_analyze_headers(drive, block))
                        goto ok;
        printk(KERN_ERR "ide-tape: %s: failed to find valid ADRL header\n", 
tape->name);
        return 0;
 ok:
-       if (position < 20)
-               position = 20;
+       if (position < OS_DATA_STARTFRAME1)
+               position = OS_DATA_STARTFRAME1;
        idetape_position_tape(drive, position, 0, 0);
        tape->header_ok = 1;
        return 1;
@@ -5251,6 +5396,7 @@
 
        if (test_and_set_bit (IDETAPE_BUSY, &tape->flags))
                return -EBUSY;
+       MOD_INC_USE_COUNT;
        if (!tape->onstream) {
                idetape_read_position(drive);
                if (!test_bit (IDETAPE_ADDRESS_VALID, &tape->flags))
@@ -5263,18 +5409,22 @@
                        tape->tape_block_size = tape->stage_size = 32768;
                        tape->raw = 0;
                }
+                idetape_onstream_mode_sense_tape_parameter_page(drive, 
+tape->debug_level);
        }
        if (idetape_wait_ready(drive, 60 * HZ)) {
                clear_bit(IDETAPE_BUSY, &tape->flags);
                printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
        idetape_read_position(drive);
+       MOD_DEC_USE_COUNT;
        clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags);
 
        if (tape->chrdev_direction == idetape_direction_none) {
+               MOD_INC_USE_COUNT;
                if (idetape_create_prevent_cmd(drive, &pc, 1)) {
-                       if (!idetape_queue_pc_tail (drive,&pc)) {
+                       if (!idetape_queue_pc_tail (drive, &pc)) {
                                if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
                                        tape->door_locked = DOOR_LOCKED;
                        }
@@ -5287,6 +5437,28 @@
        return 0;
 }
 
+static void idetape_write_release (struct inode *inode)
+{
+       ide_drive_t *drive = get_drive_ptr (inode->i_rdev);
+       idetape_tape_t *tape = drive->driver_data;
+       unsigned int minor=MINOR (inode->i_rdev);
+
+       idetape_empty_write_pipeline (drive);
+       tape->merge_stage = __idetape_kmalloc_stage (tape, 1, 0);
+       if (tape->merge_stage != NULL) {
+               idetape_pad_zeros (drive, tape->tape_block_size * 
+(tape->user_bs_factor - 1));
+               __idetape_kfree_stage (tape->merge_stage);
+               tape->merge_stage = NULL;
+       }
+       idetape_write_filemark(drive);
+       idetape_write_eod(drive);
+       idetape_flush_tape_buffers (drive);
+       idetape_write_header(drive, minor >= 128);
+       idetape_flush_tape_buffers (drive);
+
+       return;
+}
+
 /*
  *     Our character device release function.
  */
@@ -5305,18 +5477,7 @@
 #endif /* IDETAPE_DEBUG_LOG */
 
        if (tape->chrdev_direction == idetape_direction_write) {
-               idetape_empty_write_pipeline (drive);
-               tape->merge_stage = __idetape_kmalloc_stage (tape, 1, 0);
-               if (tape->merge_stage != NULL) {
-                       idetape_pad_zeros (drive, tape->tape_block_size * 
(tape->user_bs_factor - 1));
-                       __idetape_kfree_stage (tape->merge_stage);
-                       tape->merge_stage = NULL;
-               }
-               idetape_write_filemark(drive);
-               idetape_write_eod(drive);
-               idetape_flush_tape_buffers (drive);
-               idetape_write_header(drive, minor >= 128);
-               idetape_flush_tape_buffers (drive);
+               idetape_write_release(inode);
        }
        if (tape->chrdev_direction == idetape_direction_read) {
                if (minor < 128)
@@ -5333,9 +5494,10 @@
        if (tape->chrdev_direction == idetape_direction_none) {
                if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) {
                        if (idetape_create_prevent_cmd(drive, &pc, 0))
-                               if (!idetape_queue_pc_tail (drive,&pc))
+                               if (!idetape_queue_pc_tail (drive, &pc))
                                        tape->door_locked = DOOR_UNLOCKED;
                }
+               MOD_DEC_USE_COUNT;
        }
        clear_bit (IDETAPE_BUSY, &tape->flags);
        unlock_kernel();
@@ -5491,7 +5653,7 @@
        pc.buffer[4 + 5] = vendor[3];
        pc.buffer[4 + 6] = 0;
        pc.buffer[4 + 7] = 0;
-       if (idetape_queue_pc_tail (drive,&pc))
+       if (idetape_queue_pc_tail (drive, &pc))
                printk (KERN_ERR "ide-tape: Couldn't set vendor name to %s\n", vendor);
 
 }
@@ -5513,7 +5675,7 @@
        pc.buffer[4 + 1] = 2;
        pc.buffer[4 + 2] = 4;
        pc.buffer[4 + 3] = retries;
-       if (idetape_queue_pc_tail (drive,&pc))
+       if (idetape_queue_pc_tail (drive, &pc))
                printk (KERN_ERR "ide-tape: Couldn't set retries to %d\n", retries);
 }
 #endif
@@ -5530,8 +5692,8 @@
        /*
         * Get the current block size from the block size mode page
         */
-       idetape_create_mode_sense_cmd (&pc,IDETAPE_BLOCK_SIZE_PAGE);
-       if (idetape_queue_pc_tail (drive,&pc))
+       idetape_create_mode_sense_cmd (&pc, IDETAPE_BLOCK_SIZE_PAGE);
+       if (idetape_queue_pc_tail (drive, &pc))
                printk (KERN_ERR "ide-tape: can't get tape block size mode page\n");
        header = (idetape_mode_parameter_header_t *) pc.buffer;
        bs = (idetape_block_size_page_t *) (pc.buffer + 
sizeof(idetape_mode_parameter_header_t) + header->bdl);
@@ -5552,7 +5714,7 @@
        bs->record32 = 0;
        bs->record32_5 = 1;
        idetape_create_mode_select_cmd(&pc, sizeof(*header) + sizeof(*bs));
-       if (idetape_queue_pc_tail (drive,&pc))
+       if (idetape_queue_pc_tail (drive, &pc))
                printk (KERN_ERR "ide-tape: Couldn't set tape block size mode page\n");
 
 #if ONSTREAM_DEBUG
@@ -5575,7 +5737,7 @@
        idetape_inquiry_result_t *inquiry;
        
        idetape_create_inquiry_cmd(&pc);
-       if (idetape_queue_pc_tail (drive,&pc)) {
+       if (idetape_queue_pc_tail (drive, &pc)) {
                printk (KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", 
tape->name);
                return;
        }
@@ -5618,6 +5780,34 @@
 }
 
 /*
+ *     idetape_get_mode_sense_parameters asks the tape about its various
+ *     parameters. This may work for other drives to???
+ */
+static void idetape_onstream_mode_sense_tape_parameter_page(ide_drive_t *drive, int 
+debug)
+{
+       idetape_tape_t *tape = drive->driver_data;
+       idetape_pc_t pc;
+       idetape_mode_parameter_header_t *header;
+       onstream_tape_paramtr_page_t *prm;
+       
+       idetape_create_mode_sense_cmd (&pc, IDETAPE_PARAMTR_PAGE);
+       if (idetape_queue_pc_tail (drive, &pc)) {
+               printk (KERN_ERR "ide-tape: Can't get tape parameters page - probably 
+no tape inserted in onstream drive\n");
+               return;
+       }
+       header = (idetape_mode_parameter_header_t *) pc.buffer;
+       prm = (onstream_tape_paramtr_page_t *) (pc.buffer + 
+sizeof(idetape_mode_parameter_header_t) + header->bdl);
+
+        tape->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
+        if (debug) {
+           printk (KERN_INFO "ide-tape: %s <-> %s: Tape length %dMB (%d frames/track, 
+%d tracks = %d blocks, density: %dKbpi)\n",
+               drive->name, tape->name, tape->capacity/32, ntohs(prm->segtrk), 
+ntohs(prm->trks), tape->capacity, prm->density);
+        }
+
+        return;
+}
+
+/*
  *     idetape_get_mode_sense_results asks the tape about its various
  *     parameters. In particular, we will adjust our data transfer buffer
  *     size to the recommended value as returned by the tape.
@@ -5629,8 +5819,8 @@
        idetape_mode_parameter_header_t *header;
        idetape_capabilities_page_t *capabilities;
        
-       idetape_create_mode_sense_cmd (&pc,IDETAPE_CAPABILITIES_PAGE);
-       if (idetape_queue_pc_tail (drive,&pc)) {
+       idetape_create_mode_sense_cmd (&pc, IDETAPE_CAPABILITIES_PAGE);
+       if (idetape_queue_pc_tail (drive, &pc)) {
                printk (KERN_ERR "ide-tape: Can't get tape parameters - assuming some 
default values\n");
                tape->tape_block_size = 512; tape->capabilities.ctl = 52;
                tape->capabilities.speed = 450; tape->capabilities.buffer_size = 6 * 
52;
@@ -5721,6 +5911,9 @@
                ide_add_setting(drive,  "tape_still_time",SETTING_READ, -1,     -1,    
         TYPE_INT,       0,                      0xffff,                 1,            
                  1,                              &tape->tape_still_time,         
NULL);
                ide_add_setting(drive,  "max_insert_speed",SETTING_RW,  -1,     -1,    
         TYPE_INT,       0,                      0xffff,                 1,            
                  1,                              &tape->max_insert_speed,        
NULL);
                ide_add_setting(drive,  "insert_size",  SETTING_READ,   -1,     -1,    
         TYPE_INT,       0,                      0xffff,                 1,            
                  1,                              &tape->insert_size,             
NULL);
+               ide_add_setting(drive,  "capacity",     SETTING_READ,   -1,     -1,    
+         TYPE_INT,       0,                      0xffff,                 1,           
+                   1,                              &tape->capacity,                
+NULL);
+               ide_add_setting(drive,  "first_frame",  SETTING_READ,   -1,     -1,    
+         TYPE_INT,       0,                      0xffff,                 1,           
+                   1,                              &tape->first_frame_position,       
+     NULL);
+               ide_add_setting(drive,  "logical_blk",  SETTING_READ,   -1,     -1,    
+         TYPE_INT,       0,                      0xffff,                 1,           
+                   1,                              &tape->logical_blk_num,         
+NULL);
        }
 }
 
@@ -5747,7 +5940,7 @@
        spin_lock_init(&tape->spinlock);
        drive->driver_data = tape;
        drive->ready_stat = 0;                  /* An ATAPI device ignores DRDY */
-       if (strstr(drive->id->model, "OnStream DI-30"))
+       if (strstr(drive->id->model, "OnStream DI-"))
                tape->onstream = 1;
        drive->dsc_overlap = 1;
 #ifdef CONFIG_BLK_DEV_IDEPCI
@@ -5778,8 +5971,10 @@
        
        idetape_get_inquiry_results(drive);
        idetape_get_mode_sense_results(drive);
-       if (tape->onstream)
-               idetape_configure_onstream(drive);
+       if (tape->onstream) {
+               idetape_onstream_mode_sense_tape_parameter_page(drive, 1);
+               idetape_configure_onstream(drive);
+       }
 
        tape->user_bs_factor = 1;
        tape->stage_size = tape->capabilities.ctl * tape->tape_block_size;
@@ -5867,8 +6062,8 @@
        char            *out = page;
        int             len;
 
-       len = sprintf(out,"%s\n", tape->name);
-       PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+       len = sprintf(out, "%s\n", tape->name);
+       PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static ide_proc_entry_t idetape_proc[] = {
@@ -5962,7 +6157,7 @@
                        continue;
                }
                if (drive->scsi) {
-                       if (strstr(drive->id->model, "OnStream DI-30")) {
+                       if (strstr(drive->id->model, "OnStream DI-")) {
                                printk("ide-tape: ide-scsi emulation is not supported 
for %s.\n", drive->id->model);
                        } else {
                                printk("ide-tape: passing drive %s to ide-scsi 
emulation.\n", drive->name);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to