]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/ide/ide-tape.c
ide-tape: remove struct idetape_data_compression_page_t
[mv-sheeva.git] / drivers / ide / ide-tape.c
index 045bd2ae0c0f35014563aaad1a571e1d6a56b679..b9ba7901f716a8c4b82411afd4499a9f602c34e0 100644 (file)
@@ -106,10 +106,7 @@ typedef struct os_dat_s {
 /*
  *     The following are used to debug the driver:
  *
- *     Setting IDETAPE_DEBUG_INFO to 1 will report device capabilities.
  *     Setting IDETAPE_DEBUG_LOG to 1 will log driver flow control.
- *     Setting IDETAPE_DEBUG_BUGS to 1 will enable self-sanity checks in
- *     some places.
  *
  *     Setting them to 0 will restore normal operation mode:
  *
@@ -121,9 +118,7 @@ typedef struct os_dat_s {
  *     is verified to be stable enough. This will make it much more
  *     esthetic.
  */
-#define IDETAPE_DEBUG_INFO             0
 #define IDETAPE_DEBUG_LOG              0
-#define IDETAPE_DEBUG_BUGS             1
 
 /*
  *     After each failed packet command we issue a request sense command
@@ -264,47 +259,6 @@ typedef struct idetape_packet_command_s {
 /* Data direction */
 #define        PC_WRITING                      5
 
-/*
- *     Capabilities and Mechanical Status Page
- */
-typedef struct {
-       unsigned        page_code       :6;     /* Page code - Should be 0x2a */
-       __u8            reserved0_6     :1;
-       __u8            ps              :1;     /* parameters saveable */
-       __u8            page_length;            /* Page Length - Should be 0x12 */
-       __u8            reserved2, reserved3;
-       unsigned        ro              :1;     /* Read Only Mode */
-       unsigned        reserved4_1234  :4;
-       unsigned        sprev           :1;     /* Supports SPACE in the reverse direction */
-       unsigned        reserved4_67    :2;
-       unsigned        reserved5_012   :3;
-       unsigned        efmt            :1;     /* Supports ERASE command initiated formatting */
-       unsigned        reserved5_4     :1;
-       unsigned        qfa             :1;     /* Supports the QFA two partition formats */
-       unsigned        reserved5_67    :2;
-       unsigned        lock            :1;     /* Supports locking the volume */
-       unsigned        locked          :1;     /* The volume is locked */
-       unsigned        prevent         :1;     /* The device defaults in the prevent state after power up */   
-       unsigned        eject           :1;     /* The device can eject the volume */
-       __u8            disconnect      :1;     /* The device can break request > ctl */        
-       __u8            reserved6_5     :1;
-       unsigned        ecc             :1;     /* Supports error correction */
-       unsigned        cmprs           :1;     /* Supports data compression */
-       unsigned        reserved7_0     :1;
-       unsigned        blk512          :1;     /* Supports 512 bytes block size */
-       unsigned        blk1024         :1;     /* Supports 1024 bytes block size */
-       unsigned        reserved7_3_6   :4;
-       unsigned        blk32768        :1;     /* slowb - the device restricts the byte count for PIO */
-                                               /* transfers for slow buffer memory ??? */
-                                               /* Also 32768 block size in some cases */
-       __u16           max_speed;              /* Maximum speed supported in KBps */
-       __u8            reserved10, reserved11;
-       __u16           ctl;                    /* Continuous Transfer Limit in blocks */
-       __u16           speed;                  /* Current Speed, in KBps */
-       __u16           buffer_size;            /* Buffer Size, in 512 bytes */
-       __u8            reserved18, reserved19;
-} idetape_capabilities_page_t;
-
 /*
  *     Block Size Page
  */
@@ -332,32 +286,6 @@ typedef struct idetape_stage_s {
        struct idetape_stage_s *next;           /* Pointer to the next stage */
 } idetape_stage_t;
 
-/*
- *     REQUEST SENSE packet command result - Data Format.
- */
-typedef struct {
-       unsigned        error_code      :7;     /* Current of deferred errors */
-       unsigned        valid           :1;     /* The information field conforms to QIC-157C */
-       __u8            reserved1       :8;     /* Segment Number - Reserved */
-       unsigned        sense_key       :4;     /* Sense Key */
-       unsigned        reserved2_4     :1;     /* Reserved */
-       unsigned        ili             :1;     /* Incorrect Length Indicator */
-       unsigned        eom             :1;     /* End Of Medium */
-       unsigned        filemark        :1;     /* Filemark */
-       __u32           information __attribute__ ((packed));
-       __u8            asl;                    /* Additional sense length (n-7) */
-       __u32           command_specific;       /* Additional command specific information */
-       __u8            asc;                    /* Additional Sense Code */
-       __u8            ascq;                   /* Additional Sense Code Qualifier */
-       __u8            replaceable_unit_code;  /* Field Replaceable Unit Code */
-       unsigned        sk_specific1    :7;     /* Sense Key Specific */
-       unsigned        sksv            :1;     /* Sense Key Specific information is valid */
-       __u8            sk_specific2;           /* Sense Key Specific */
-       __u8            sk_specific3;           /* Sense Key Specific */
-       __u8            pad[2];                 /* Padding to 20 bytes */
-} idetape_request_sense_result_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 a variable
@@ -448,8 +376,9 @@ typedef struct ide_tape_obj {
        /* Usually 512 or 1024 bytes */
        unsigned short tape_block_size;
        int user_bs_factor;
+
        /* Copy of the tape's Capabilities and Mechanical Page */
-       idetape_capabilities_page_t capabilities;
+       u8 caps[20];
 
        /*
         *      Active data transfer request parameters.
@@ -512,9 +441,6 @@ typedef struct ide_tape_obj {
        int avg_size;
        int avg_speed;
 
-       /* last sense information */
-       idetape_request_sense_result_t sense;
-
        char vendor_id[10];
        char product_id[18];
        char firmware_revision[6];
@@ -722,31 +648,6 @@ struct idetape_id_gcw {
        unsigned protocol               :2;     /* Protocol type */
 };
 
-/*
- *     INQUIRY packet command - Data Format (From Table 6-8 of QIC-157C)
- */
-typedef struct {
-       unsigned        device_type     :5;     /* Peripheral Device Type */
-       unsigned        reserved0_765   :3;     /* Peripheral Qualifier - Reserved */
-       unsigned        reserved1_6t0   :7;     /* Reserved */
-       unsigned        rmb             :1;     /* Removable Medium Bit */
-       unsigned        ansi_version    :3;     /* ANSI Version */
-       unsigned        ecma_version    :3;     /* ECMA Version */
-       unsigned        iso_version     :2;     /* ISO Version */
-       unsigned        response_format :4;     /* Response Data Format */
-       unsigned        reserved3_45    :2;     /* Reserved */
-       unsigned        reserved3_6     :1;     /* TrmIOP - Reserved */
-       unsigned        reserved3_7     :1;     /* AENC - Reserved */
-       __u8            additional_length;      /* Additional Length (total_length-4) */
-       __u8            rsv5, rsv6, rsv7;       /* Reserved */
-       __u8            vendor_id[8];           /* Vendor Identification */
-       __u8            product_id[16];         /* Product Identification */
-       __u8            revision_level[4];      /* Revision Level */
-       __u8            vendor_specific[20];    /* Vendor Specific - Optional */
-       __u8            reserved56t95[40];      /* Reserved - Optional */
-                                               /* Additional information may be returned */
-} idetape_inquiry_result_t;
-
 /*
  *     READ POSITION packet command - Data Format (From Table 6-57)
  */
@@ -776,31 +677,6 @@ typedef struct {
 #define IDETAPE_BLOCK_SIZE_PAGE                0x30
 #define IDETAPE_BUFFER_FILLING_PAGE    0x33
 
-/*
- *     Mode Parameter Header for the MODE SENSE packet command
- */
-typedef struct {
-       __u8    mode_data_length;       /* Length of the following data transfer */
-       __u8    medium_type;            /* Medium Type */
-       __u8    dsp;                    /* Device Specific Parameter */
-       __u8    bdl;                    /* Block Descriptor Length */
-#if 0
-       /* data transfer page */
-       __u8    page_code       :6;
-       __u8    reserved0_6     :1;
-       __u8    ps              :1;     /* parameters saveable */
-       __u8    page_length;            /* page Length == 0x02 */
-       __u8    reserved2;
-       __u8    read32k         :1;     /* 32k blk size (data only) */
-       __u8    read32k5        :1;     /* 32.5k blk size (data&AUX) */
-       __u8    reserved3_23    :2;
-       __u8    write32k        :1;     /* 32k blk size (data only) */
-       __u8    write32k5       :1;     /* 32.5k blk size (data&AUX) */
-       __u8    reserved3_6     :1;
-       __u8    streaming       :1;     /* streaming mode enable */
-#endif
-} idetape_mode_parameter_header_t;
-
 /*
  *     Mode Parameter Block Descriptor the MODE SENSE packet command
  *
@@ -813,25 +689,6 @@ typedef struct {
        __u8            length[3];              /* Block Length */
 } idetape_parameter_block_descriptor_t;
 
-/*
- *     The Data Compression Page, as returned by the MODE SENSE packet command.
- */
-typedef struct {
-       unsigned        page_code       :6;     /* Page Code - Should be 0xf */
-       unsigned        reserved0       :1;     /* Reserved */
-       unsigned        ps              :1;
-       __u8            page_length;            /* Page Length - Should be 14 */
-       unsigned        reserved2       :6;     /* Reserved */
-       unsigned        dcc             :1;     /* Data Compression Capable */
-       unsigned        dce             :1;     /* Data Compression Enable */
-       unsigned        reserved3       :5;     /* Reserved */
-       unsigned        red             :2;     /* Report Exception on Decompression */
-       unsigned        dde             :1;     /* Data Decompression Enable */
-       __u32           ca;                     /* Compression Algorithm */
-       __u32           da;                     /* Decompression Algorithm */
-       __u8            reserved[4];            /* Reserved */
-} idetape_data_compression_page_t;
-
 /*
  *     The Medium Partition Page, as returned by the MODE SENSE packet command.
  */
@@ -903,14 +760,12 @@ static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigne
        int count;
 
        while (bcount) {
-#if IDETAPE_DEBUG_BUGS
                if (bh == NULL) {
                        printk(KERN_ERR "ide-tape: bh == NULL in "
                                "idetape_input_buffers\n");
                        idetape_discard_data(drive, bcount);
                        return;
                }
-#endif /* IDETAPE_DEBUG_BUGS */
                count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), bcount);
                HWIF(drive)->atapi_input_bytes(drive, bh->b_data + atomic_read(&bh->b_count), count);
                bcount -= count;
@@ -930,13 +785,11 @@ static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsign
        int count;
 
        while (bcount) {
-#if IDETAPE_DEBUG_BUGS
                if (bh == NULL) {
                        printk(KERN_ERR "ide-tape: bh == NULL in "
                                "idetape_output_buffers\n");
                        return;
                }
-#endif /* IDETAPE_DEBUG_BUGS */
                count = min((unsigned int)pc->b_count, (unsigned int)bcount);
                HWIF(drive)->atapi_output_bytes(drive, pc->b_data, count);
                bcount -= count;
@@ -961,13 +814,11 @@ static void idetape_update_buffers (idetape_pc_t *pc)
        if (test_bit(PC_WRITING, &pc->flags))
                return;
        while (bcount) {
-#if IDETAPE_DEBUG_BUGS
                if (bh == NULL) {
                        printk(KERN_ERR "ide-tape: bh == NULL in "
                                "idetape_update_buffers\n");
                        return;
                }
-#endif /* IDETAPE_DEBUG_BUGS */
                count = min((unsigned int)bh->b_size, (unsigned int)bcount);
                atomic_set(&bh->b_count, count);
                if (atomic_read(&bh->b_count) == bh->b_size)
@@ -1040,36 +891,34 @@ static void idetape_init_pc (idetape_pc_t *pc)
 }
 
 /*
- *     idetape_analyze_error is called on each failed packet command retry
- *     to analyze the request sense. We currently do not utilize this
- *     information.
+ * called on each failed packet command retry 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, u8 *sense)
 {
        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_key = sense[2] & 0xF;
+       tape->asc       = sense[12];
+       tape->ascq      = sense[13];
 #if IDETAPE_DEBUG_LOG
        /*
-        *      Without debugging, we only log an error if we decided to
-        *      give up retrying.
+        * 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);
+                       pc->c[0], tape->sense_key,
+                       tape->asc, tape->ascq);
 #endif /* IDETAPE_DEBUG_LOG */
 
-       /*
-        *      Correct pc->actually_transferred by asking the tape.
-        */
+       /* Correct pc->actually_transferred by asking the tape.  */
        if (test_bit(PC_DMA_ERROR, &pc->flags)) {
-               pc->actually_transferred = pc->request_transfer - tape->tape_block_size * ntohl(get_unaligned(&result->information));
+               pc->actually_transferred = pc->request_transfer -
+                       tape->tape_block_size *
+                       ntohl(get_unaligned((u32 *)&sense[3]));
                idetape_update_buffers(pc);
        }
 
@@ -1079,28 +928,28 @@ static void idetape_analyze_error (ide_drive_t *drive, idetape_request_sense_res
         * (i.e. Seagate STT3401A Travan) don't support 0-length read/writes.
         */
        if ((pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD)
-           && pc->c[4] == 0 && pc->c[3] == 0 && pc->c[2] == 0) { /* length==0 */
-               if (result->sense_key == 5) {
+           /* length == 0 */
+           && pc->c[4] == 0 && pc->c[3] == 0 && pc->c[2] == 0) {
+               if (tape->sense_key == 5) {
                        /* don't report an error, everything's ok */
                        pc->error = 0;
                        /* don't retry read/write */
                        set_bit(PC_ABORT, &pc->flags);
                }
        }
-       if (pc->c[0] == IDETAPE_READ_CMD && result->filemark) {
+       if (pc->c[0] == IDETAPE_READ_CMD && (sense[2] & 0x80)) {
                pc->error = IDETAPE_ERROR_FILEMARK;
                set_bit(PC_ABORT, &pc->flags);
        }
        if (pc->c[0] == IDETAPE_WRITE_CMD) {
-               if (result->eom ||
-                   (result->sense_key == 0xd && result->asc == 0x0 &&
-                    result->ascq == 0x2)) {
+               if ((sense[2] & 0x40) || (tape->sense_key == 0xd
+                    && tape->asc == 0x0 && tape->ascq == 0x2)) {
                        pc->error = IDETAPE_ERROR_EOD;
                        set_bit(PC_ABORT, &pc->flags);
                }
        }
        if (pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD) {
-               if (result->sense_key == 8) {
+               if (tape->sense_key == 8) {
                        pc->error = IDETAPE_ERROR_EOD;
                        set_bit(PC_ABORT, &pc->flags);
                }
@@ -1123,12 +972,10 @@ static void idetape_active_next_stage (ide_drive_t *drive)
        if (tape->debug_level >= 4)
                printk(KERN_INFO "ide-tape: Reached idetape_active_next_stage\n");
 #endif /* IDETAPE_DEBUG_LOG */
-#if IDETAPE_DEBUG_BUGS
        if (stage == NULL) {
                printk(KERN_ERR "ide-tape: bug: Trying to activate a non existing stage\n");
                return;
        }
-#endif /* IDETAPE_DEBUG_BUGS */        
 
        rq->rq_disk = tape->disk;
        rq->buffer = NULL;
@@ -1203,28 +1050,24 @@ static void idetape_remove_stage_head (ide_drive_t *drive)
        if (tape->debug_level >= 4)
                printk(KERN_INFO "ide-tape: Reached idetape_remove_stage_head\n");
 #endif /* IDETAPE_DEBUG_LOG */
-#if IDETAPE_DEBUG_BUGS
        if (tape->first_stage == NULL) {
                printk(KERN_ERR "ide-tape: bug: tape->first_stage is NULL\n");
-               return;         
+               return;
        }
        if (tape->active_stage == tape->first_stage) {
                printk(KERN_ERR "ide-tape: bug: Trying to free our active pipeline stage\n");
                return;
        }
-#endif /* IDETAPE_DEBUG_BUGS */
        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 IDETAPE_DEBUG_BUGS
                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");
-#endif /* IDETAPE_DEBUG_BUGS */
        }
 }
 
@@ -1342,7 +1185,7 @@ static ide_startstop_t idetape_request_sense_callback (ide_drive_t *drive)
                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_analyze_error(drive, tape->pc->buffer);
                idetape_end_request(drive, 1, 0);
        } else {
                printk(KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n");
@@ -1712,13 +1555,11 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
        int dma_ok = 0;
        u16 bcount;
 
-#if IDETAPE_DEBUG_BUGS
        if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD &&
            pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
                printk(KERN_ERR "ide-tape: possible ide-tape.c bug - "
                        "Two request sense in serial were issued\n");
        }
-#endif /* IDETAPE_DEBUG_BUGS */
 
        if (tape->failed_pc == NULL && pc->c[0] != IDETAPE_REQUEST_SENSE_CMD)
                tape->failed_pc = pc;
@@ -2006,12 +1847,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
        u8 stat;
 
 #if IDETAPE_DEBUG_LOG
-#if 0
-       if (tape->debug_level >= 5)
-               printk(KERN_INFO "ide-tape:  %d, "
-                       "dev: %s, cmd: %ld, errors: %d\n",
-                        rq->rq_disk->disk_name, rq->cmd[0], rq->errors);
-#endif
        if (tape->debug_level >= 2)
                printk(KERN_INFO "ide-tape: sector: %ld, "
                        "nr_sectors: %ld, current_nr_sectors: %d\n",
@@ -2035,7 +1870,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
            tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
                return idetape_issue_packet_command(drive, tape->failed_pc);
        }
-#if IDETAPE_DEBUG_BUGS
        if (postponed_rq != NULL)
                if (rq != postponed_rq) {
                        printk(KERN_ERR "ide-tape: ide-tape.c bug - "
@@ -2043,7 +1877,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                        idetape_end_request(drive, 0, 0);
                        return ide_stopped;
                }
-#endif /* IDETAPE_DEBUG_BUGS */
 
        tape->postponed_rq = NULL;
 
@@ -2230,13 +2063,11 @@ static int idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *
        int ret = 0;
 
        while (n) {
-#if IDETAPE_DEBUG_BUGS
                if (bh == NULL) {
                        printk(KERN_ERR "ide-tape: bh == NULL in "
                                "idetape_copy_stage_from_user\n");
                        return 1;
                }
-#endif /* IDETAPE_DEBUG_BUGS */
                count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), (unsigned int)n);
                if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, count))
                        ret = 1;
@@ -2260,13 +2091,11 @@ static int idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, i
        int ret = 0;
 
        while (n) {
-#if IDETAPE_DEBUG_BUGS
                if (bh == NULL) {
                        printk(KERN_ERR "ide-tape: bh == NULL in "
                                "idetape_copy_stage_to_user\n");
                        return 1;
                }
-#endif /* IDETAPE_DEBUG_BUGS */
                count = min(tape->b_count, n);
                if  (copy_to_user(buf, tape->b_data, count))
                        ret = 1;
@@ -2346,12 +2175,10 @@ 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 IDETAPE_DEBUG_BUGS
        if (rq == NULL || !blk_special_request(rq)) {
                printk (KERN_ERR "ide-tape: bug: Trying to sleep on non-valid request\n");
                return;
        }
-#endif /* IDETAPE_DEBUG_BUGS */
        rq->end_io_data = &wait;
        rq->end_io = blk_end_sync_rq;
        spin_unlock_irq(&tape->spinlock);
@@ -2553,7 +2380,8 @@ static int idetape_create_prevent_cmd (ide_drive_t *drive, idetape_pc_t *pc, int
 {
        idetape_tape_t *tape = drive->driver_data;
 
-       if (!tape->capabilities.lock)
+       /* device supports locking according to capabilities page */
+       if (!(tape->caps[6] & 0x01))
                return 0;
 
        idetape_init_pc(pc);
@@ -2666,12 +2494,10 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct
        if (tape->debug_level >= 2)
                printk(KERN_INFO "ide-tape: idetape_queue_rw_tail: cmd=%d\n",cmd);
 #endif /* IDETAPE_DEBUG_LOG */
-#if IDETAPE_DEBUG_BUGS
        if (idetape_pipeline_active(tape)) {
                printk(KERN_ERR "ide-tape: bug: the pipeline is active in idetape_queue_rw_tail\n");
                return (0);
        }
-#endif /* IDETAPE_DEBUG_BUGS */        
 
        idetape_init_rq(&rq, cmd);
        rq.rq_disk = tape->disk;
@@ -2723,19 +2549,6 @@ static void idetape_create_rewind_cmd (ide_drive_t *drive, idetape_pc_t *pc)
        pc->callback = &idetape_pc_callback;
 }
 
-#if 0
-static void idetape_create_mode_select_cmd (idetape_pc_t *pc, int length)
-{
-       idetape_init_pc(pc);
-       set_bit(PC_WRITING, &pc->flags);
-       pc->c[0] = IDETAPE_MODE_SELECT_CMD;
-       pc->c[1] = 0x10;
-       put_unaligned(htons(length), (unsigned short *) &pc->c[3]);
-       pc->request_transfer = 255;
-       pc->callback = &idetape_pc_callback;
-}
-#endif
-
 static void idetape_create_erase_cmd (idetape_pc_t *pc)
 {
        idetape_init_pc(pc);
@@ -2869,8 +2682,7 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
        idetape_tape_t *tape = drive->driver_data;
        int blocks, min;
        struct idetape_bh *bh;
-       
-#if IDETAPE_DEBUG_BUGS
+
        if (tape->chrdev_direction != idetape_direction_write) {
                printk(KERN_ERR "ide-tape: bug: Trying to empty write pipeline, but we are not writing.\n");
                return;
@@ -2879,7 +2691,6 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
                printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n");
                tape->merge_stage_size = tape->stage_size;
        }
-#endif /* IDETAPE_DEBUG_BUGS */
        if (tape->merge_stage_size) {
                blocks = tape->merge_stage_size / tape->tape_block_size;
                if (tape->merge_stage_size % tape->tape_block_size) {
@@ -2924,7 +2735,6 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
         *       can be totally different on the next backup).
         */
        tape->max_stages = tape->min_pipeline;
-#if IDETAPE_DEBUG_BUGS
        if (tape->first_stage != NULL ||
            tape->next_stage != NULL ||
            tape->last_stage != NULL ||
@@ -2935,7 +2745,6 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
                        tape->first_stage, tape->next_stage,
                        tape->last_stage, tape->nr_stages);
        }
-#endif /* IDETAPE_DEBUG_BUGS */
 }
 
 static void idetape_restart_speed_control (ide_drive_t *drive)
@@ -2958,7 +2767,7 @@ static int idetape_initiate_read (ide_drive_t *drive, int max_stages)
        idetape_stage_t *new_stage;
        struct request rq;
        int bytes_read;
-       int blocks = tape->capabilities.ctl;
+       u16 blocks = *(u16 *)&tape->caps[12];
 
        /* Initialize read operation */
        if (tape->chrdev_direction != idetape_direction_read) {
@@ -2966,12 +2775,10 @@ static int idetape_initiate_read (ide_drive_t *drive, int max_stages)
                        idetape_empty_write_pipeline(drive);
                        idetape_flush_tape_buffers(drive);
                }
-#if IDETAPE_DEBUG_BUGS
                if (tape->merge_stage || tape->merge_stage_size) {
                        printk (KERN_ERR "ide-tape: merge_stage_size should be 0 now\n");
                        tape->merge_stage_size = 0;
                }
-#endif /* IDETAPE_DEBUG_BUGS */
                if ((tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0)) == NULL)
                        return -ENOMEM;
                tape->chrdev_direction = idetape_direction_read;
@@ -3072,12 +2879,10 @@ static int idetape_add_chrdev_read_request (ide_drive_t *drive,int blocks)
                tape->pipeline_head++;
                calculate_speeds(drive);
        }
-#if IDETAPE_DEBUG_BUGS
        if (bytes_read > blocks * tape->tape_block_size) {
                printk(KERN_ERR "ide-tape: bug: trying to return more bytes than requested\n");
                bytes_read = blocks * tape->tape_block_size;
        }
-#endif /* IDETAPE_DEBUG_BUGS */
        return (bytes_read);
 }
 
@@ -3202,11 +3007,12 @@ static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_c
        idetape_pc_t pc;
        unsigned long flags;
        int retval,count=0;
+       int sprev = !!(tape->caps[4] & 0x20);
 
        if (mt_count == 0)
                return 0;
        if (MTBSF == mt_op || MTBSFM == mt_op) {
-               if (!tape->capabilities.sprev)
+               if (!sprev)
                        return -EIO;
                mt_count = - mt_count;
        }
@@ -3260,7 +3066,7 @@ static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_c
                        return (idetape_queue_pc_tail(drive, &pc));
                case MTFSFM:
                case MTBSFM:
-                       if (!tape->capabilities.sprev)
+                       if (!sprev)
                                return (-EIO);
                        retval = idetape_space_over_filemarks(drive, MTFSF, mt_count-count);
                        if (retval) return (retval);
@@ -3297,6 +3103,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf,
        ide_drive_t *drive = tape->drive;
        ssize_t bytes_read,temp, actually_read = 0, rc;
        ssize_t ret = 0;
+       u16 ctl = *(u16 *)&tape->caps[12];
 
 #if IDETAPE_DEBUG_LOG
        if (tape->debug_level >= 3)
@@ -3322,7 +3129,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf,
                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, ctl);
                if (bytes_read <= 0)
                        goto finish;
                if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, bytes_read))
@@ -3332,7 +3139,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf,
                actually_read += bytes_read;
        }
        if (count) {
-               bytes_read = idetape_add_chrdev_read_request(drive, tape->capabilities.ctl);
+               bytes_read = idetape_add_chrdev_read_request(drive, ctl);
                if (bytes_read <= 0)
                        goto finish;
                temp = min((unsigned long)count, (unsigned long)bytes_read);
@@ -3361,6 +3168,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
        ide_drive_t *drive = tape->drive;
        ssize_t actually_written = 0;
        ssize_t ret = 0;
+       u16 ctl = *(u16 *)&tape->caps[12];
 
        /* The drive is write protected. */
        if (tape->write_prot)
@@ -3376,13 +3184,11 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
        if (tape->chrdev_direction != idetape_direction_write) {
                if (tape->chrdev_direction == idetape_direction_read)
                        idetape_discard_read_pipeline(drive, 1);
-#if IDETAPE_DEBUG_BUGS
                if (tape->merge_stage || tape->merge_stage_size) {
                        printk(KERN_ERR "ide-tape: merge_stage_size "
                                "should be 0 now\n");
                        tape->merge_stage_size = 0;
                }
-#endif /* IDETAPE_DEBUG_BUGS */
                if ((tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0)) == NULL)
                        return -ENOMEM;
                tape->chrdev_direction = idetape_direction_write;
@@ -3410,12 +3216,10 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
        if (tape->restart_speed_control_req)
                idetape_restart_speed_control(drive);
        if (tape->merge_stage_size) {
-#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;
                }
-#endif /* IDETAPE_DEBUG_BUGS */
                actually_written = min((unsigned int)(tape->stage_size - tape->merge_stage_size), (unsigned int)count);
                if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, actually_written))
                                ret = -EFAULT;
@@ -3426,7 +3230,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
                if (tape->merge_stage_size == tape->stage_size) {
                        ssize_t retval;
                        tape->merge_stage_size = 0;
-                       retval = idetape_add_chrdev_write_request(drive, tape->capabilities.ctl);
+                       retval = idetape_add_chrdev_write_request(drive, ctl);
                        if (retval <= 0)
                                return (retval);
                }
@@ -3437,7 +3241,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
                        ret = -EFAULT;
                buf += tape->stage_size;
                count -= tape->stage_size;
-               retval = idetape_add_chrdev_write_request(drive, tape->capabilities.ctl);
+               retval = idetape_add_chrdev_write_request(drive, ctl);
                actually_written += tape->stage_size;
                if (retval <= 0)
                        return (retval);
@@ -3890,159 +3694,100 @@ static int idetape_identify_device (ide_drive_t *drive)
 
        *((unsigned short *) &gcw) = id->config;
 
-#if IDETAPE_DEBUG_INFO
-       printk(KERN_INFO "ide-tape: Dumping ATAPI Identify Device tape parameters\n");
-       printk(KERN_INFO "ide-tape: Protocol Type: ");
-       switch (gcw.protocol) {
-               case 0: case 1: printk("ATA\n");break;
-               case 2: printk("ATAPI\n");break;
-               case 3: printk("Reserved (Unknown to ide-tape)\n");break;
-       }
-       printk(KERN_INFO "ide-tape: Device Type: %x - ",gcw.device_type);       
-       switch (gcw.device_type) {
-               case 0: printk("Direct-access Device\n");break;
-               case 1: printk("Streaming Tape Device\n");break;
-               case 2: case 3: case 4: printk("Reserved\n");break;
-               case 5: printk("CD-ROM Device\n");break;
-               case 6: printk("Reserved\n");
-               case 7: printk("Optical memory Device\n");break;
-               case 0x1f: printk("Unknown or no Device type\n");break;
-               default: printk("Reserved\n");
-       }
-       printk(KERN_INFO "ide-tape: Removable: %s",gcw.removable ? "Yes\n":"No\n");     
-       printk(KERN_INFO "ide-tape: Command Packet DRQ Type: ");
-       switch (gcw.drq_type) {
-               case 0: printk("Microprocessor DRQ\n");break;
-               case 1: printk("Interrupt DRQ\n");break;
-               case 2: printk("Accelerated DRQ\n");break;
-               case 3: printk("Reserved\n");break;
-       }
-       printk(KERN_INFO "ide-tape: Command Packet Size: ");
-       switch (gcw.packet_size) {
-               case 0: printk("12 bytes\n");break;
-               case 1: printk("16 bytes\n");break;
-               default: printk("Reserved\n");break;
-       }
-#endif /* IDETAPE_DEBUG_INFO */
-
        /* Check that we can support this device */
 
-       if (gcw.protocol !=2 )
-               printk(KERN_ERR "ide-tape: Protocol is not ATAPI\n");
+       if (gcw.protocol != 2)
+               printk(KERN_ERR "ide-tape: Protocol (0x%02x) is not ATAPI\n",
+                               gcw.protocol);
        else if (gcw.device_type != 1)
-               printk(KERN_ERR "ide-tape: Device type is not set to tape\n");
+               printk(KERN_ERR "ide-tape: Device type (0x%02x) is not set "
+                               "to tape\n", gcw.device_type);
        else if (!gcw.removable)
                printk(KERN_ERR "ide-tape: The removable flag is not set\n");
        else if (gcw.packet_size != 0) {
-               printk(KERN_ERR "ide-tape: Packet size is not 12 bytes long\n");
-               if (gcw.packet_size == 1)
-                       printk(KERN_ERR "ide-tape: Sorry, padding to 16 bytes is still not supported\n");
+               printk(KERN_ERR "ide-tape: Packet size (0x%02x) is not 12 "
+                               "bytes long\n", gcw.packet_size);
        } else
                return 1;
        return 0;
 }
 
-/*
- * Use INQUIRY to get the firmware revision
- */
-static void idetape_get_inquiry_results (ide_drive_t *drive)
+static void idetape_get_inquiry_results(ide_drive_t *drive)
 {
        char *r;
        idetape_tape_t *tape = drive->driver_data;
        idetape_pc_t pc;
-       idetape_inquiry_result_t *inquiry;
-       
+
        idetape_create_inquiry_cmd(&pc);
        if (idetape_queue_pc_tail(drive, &pc)) {
-               printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", tape->name);
+               printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
+                               tape->name);
                return;
        }
-       inquiry = (idetape_inquiry_result_t *) pc.buffer;
-       memcpy(tape->vendor_id, inquiry->vendor_id, 8);
-       memcpy(tape->product_id, inquiry->product_id, 16);
-       memcpy(tape->firmware_revision, inquiry->revision_level, 4);
+       memcpy(tape->vendor_id, &pc.buffer[8], 8);
+       memcpy(tape->product_id, &pc.buffer[16], 16);
+       memcpy(tape->firmware_revision, &pc.buffer[32], 4);
+
        ide_fixstring(tape->vendor_id, 10, 0);
        ide_fixstring(tape->product_id, 18, 0);
        ide_fixstring(tape->firmware_revision, 6, 0);
        r = tape->firmware_revision;
        if (*(r + 1) == '.')
-               tape->firmware_revision_num = (*r - '0') * 100 + (*(r + 2) - '0') * 10 + *(r + 3) - '0';
-       printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n", drive->name, tape->name, tape->vendor_id, tape->product_id, tape->firmware_revision);
+               tape->firmware_revision_num = (*r - '0') * 100 +
+                       (*(r + 2) - '0') * 10 + *(r + 3) - '0';
+       printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n",
+                       drive->name, tape->name, tape->vendor_id,
+                       tape->product_id, tape->firmware_revision);
 }
 
 /*
- *     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.
+ * Ask 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.
  */
 static void idetape_get_mode_sense_results (ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
        idetape_pc_t pc;
-       idetape_mode_parameter_header_t *header;
-       idetape_capabilities_page_t *capabilities;
-       
+       u8 *caps;
+       u8 speed, max_speed;
+
        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");
+               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;
+               put_unaligned(52,   (u16 *)&tape->caps[12]);
+               put_unaligned(540,  (u16 *)&tape->caps[14]);
+               put_unaligned(6*52, (u16 *)&tape->caps[16]);
                return;
        }
-       header = (idetape_mode_parameter_header_t *) pc.buffer;
-       capabilities = (idetape_capabilities_page_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t) + header->bdl);
+       caps = pc.buffer + 4 + pc.buffer[3];
+
+       /* convert to host order and save for later use */
+       speed = be16_to_cpu(*(u16 *)&caps[14]);
+       max_speed = be16_to_cpu(*(u16 *)&caps[8]);
 
-       capabilities->max_speed = ntohs(capabilities->max_speed);
-       capabilities->ctl = ntohs(capabilities->ctl);
-       capabilities->speed = ntohs(capabilities->speed);
-       capabilities->buffer_size = ntohs(capabilities->buffer_size);
+       put_unaligned(max_speed, (u16 *)&caps[8]);
+       put_unaligned(be16_to_cpu(*(u16 *)&caps[12]), (u16 *)&caps[12]);
+       put_unaligned(speed, (u16 *)&caps[14]);
+       put_unaligned(be16_to_cpu(*(u16 *)&caps[16]), (u16 *)&caps[16]);
 
-       if (!capabilities->speed) {
-               printk(KERN_INFO "ide-tape: %s: overriding capabilities->speed (assuming 650KB/sec)\n", drive->name);
-               capabilities->speed = 650;
+       if (!speed) {
+               printk(KERN_INFO "ide-tape: %s: invalid tape speed "
+                               "(assuming 650KB/sec)\n", drive->name);
+               put_unaligned(650, (u16 *)&caps[14]);
        }
-       if (!capabilities->max_speed) {
-               printk(KERN_INFO "ide-tape: %s: overriding capabilities->max_speed (assuming 650KB/sec)\n", drive->name);
-               capabilities->max_speed = 650;
+       if (!max_speed) {
+               printk(KERN_INFO "ide-tape: %s: invalid max_speed "
+                               "(assuming 650KB/sec)\n", drive->name);
+               put_unaligned(650, (u16 *)&caps[8]);
        }
 
-       tape->capabilities = *capabilities;             /* Save us a copy */
-       if (capabilities->blk512)
+       memcpy(&tape->caps, caps, 20);
+       if (caps[7] & 0x02)
                tape->tape_block_size = 512;
-       else if (capabilities->blk1024)
+       else if (caps[7] & 0x04)
                tape->tape_block_size = 1024;
-
-#if IDETAPE_DEBUG_INFO
-       printk(KERN_INFO "ide-tape: Dumping the results of the MODE SENSE packet command\n");
-       printk(KERN_INFO "ide-tape: Mode Parameter Header:\n");
-       printk(KERN_INFO "ide-tape: Mode Data Length - %d\n",header->mode_data_length);
-       printk(KERN_INFO "ide-tape: Medium Type - %d\n",header->medium_type);
-       printk(KERN_INFO "ide-tape: Device Specific Parameter - %d\n",header->dsp);
-       printk(KERN_INFO "ide-tape: Block Descriptor Length - %d\n",header->bdl);
-       
-       printk(KERN_INFO "ide-tape: Capabilities and Mechanical Status Page:\n");
-       printk(KERN_INFO "ide-tape: Page code - %d\n",capabilities->page_code);
-       printk(KERN_INFO "ide-tape: Page length - %d\n",capabilities->page_length);
-       printk(KERN_INFO "ide-tape: Read only - %s\n",capabilities->ro ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports reverse space - %s\n",capabilities->sprev ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports erase initiated formatting - %s\n",capabilities->efmt ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports QFA two Partition format - %s\n",capabilities->qfa ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports locking the medium - %s\n",capabilities->lock ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: The volume is currently locked - %s\n",capabilities->locked ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: The device defaults in the prevent state - %s\n",capabilities->prevent ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports ejecting the medium - %s\n",capabilities->eject ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports error correction - %s\n",capabilities->ecc ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports data compression - %s\n",capabilities->cmprs ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports 512 bytes block size - %s\n",capabilities->blk512 ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports 1024 bytes block size - %s\n",capabilities->blk1024 ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Supports 32768 bytes block size / Restricted byte count for PIO transfers - %s\n",capabilities->blk32768 ? "Yes":"No");
-       printk(KERN_INFO "ide-tape: Maximum supported speed in KBps - %d\n",capabilities->max_speed);
-       printk(KERN_INFO "ide-tape: Continuous transfer limits in blocks - %d\n",capabilities->ctl);
-       printk(KERN_INFO "ide-tape: Current speed in KBps - %d\n",capabilities->speed); 
-       printk(KERN_INFO "ide-tape: Buffer size - %d\n",capabilities->buffer_size*512);
-#endif /* IDETAPE_DEBUG_INFO */
 }
 
 /*
@@ -4054,9 +3799,8 @@ static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive)
 
        idetape_tape_t *tape = drive->driver_data;
        idetape_pc_t pc;
-       idetape_mode_parameter_header_t *header;
        idetape_parameter_block_descriptor_t *block_descrp;
-       
+
        idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR);
        if (idetape_queue_pc_tail(drive, &pc)) {
                printk(KERN_ERR "ide-tape: Can't get block descriptor\n");
@@ -4066,14 +3810,9 @@ static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive)
                }
                return;
        }
-       header = (idetape_mode_parameter_header_t *) pc.buffer;
-       block_descrp = (idetape_parameter_block_descriptor_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t));
+       block_descrp = (idetape_parameter_block_descriptor_t *)(pc.buffer + 4);
        tape->tape_block_size =( block_descrp->length[0]<<16) + (block_descrp->length[1]<<8) + block_descrp->length[2];
-       tape->drv_write_prot = (header->dsp & 0x80) >> 7;
-
-#if IDETAPE_DEBUG_INFO
-       printk(KERN_INFO "ide-tape: Adjusted block size - %d\n", tape->tape_block_size);
-#endif /* IDETAPE_DEBUG_INFO */
+       tape->drv_write_prot = (pc.buffer[2] & 0x80) >> 7;
 }
 
 #ifdef CONFIG_IDE_PROC_FS
@@ -4084,13 +3823,15 @@ static void idetape_add_settings (ide_drive_t *drive)
 /*
  *                     drive   setting name            read/write      data type       min                     max                     mul_factor                      div_factor      data pointer                            set function
  */
-       ide_add_setting(drive,  "buffer",               SETTING_READ,   TYPE_SHORT,     0,                      0xffff,                 1,                              2,              &tape->capabilities.buffer_size,        NULL);
+       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,              &tape->capabilities.speed,              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,  "tdsc",                 SETTING_RW,     TYPE_INT,       IDETAPE_DSC_RW_MIN,     IDETAPE_DSC_RW_MAX,     1000,                           HZ,             &tape->best_dsc_rw_frequency,           NULL);
        ide_add_setting(drive,  "dsc_overlap",          SETTING_RW,     TYPE_BYTE,      0,                      1,                      1,                              1,              &drive->dsc_overlap,                    NULL);
@@ -4122,6 +3863,7 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
        struct idetape_id_gcw gcw;
        int stage_size;
        struct sysinfo si;
+       u16 *ctl = (u16 *)&tape->caps[12];
 
        spin_lock_init(&tape->spinlock);
        drive->dsc_overlap = 1;
@@ -4151,11 +3893,11 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
        idetape_get_mode_sense_results(drive);
        idetape_get_blocksize_from_block_descriptor(drive);
        tape->user_bs_factor = 1;
-       tape->stage_size = tape->capabilities.ctl * tape->tape_block_size;
+       tape->stage_size = *ctl * tape->tape_block_size;
        while (tape->stage_size > 0xffff) {
                printk(KERN_NOTICE "ide-tape: decreasing stage size\n");
-               tape->capabilities.ctl /= 2;
-               tape->stage_size = tape->capabilities.ctl * tape->tape_block_size;
+               *ctl /= 2;
+               tape->stage_size = *ctl * tape->tape_block_size;
        }
        stage_size = tape->stage_size;
        tape->pages_per_stage = stage_size / PAGE_SIZE;
@@ -4164,11 +3906,8 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
                tape->excess_bh_size = PAGE_SIZE - stage_size % PAGE_SIZE;
        }
 
-       /*
-        *      Select the "best" DSC read/write polling frequency
-        *      and pipeline size.
-        */
-       speed = max(tape->capabilities.speed, tape->capabilities.max_speed);
+       /* Select the "best" DSC read/write polling freq and pipeline size. */
+       speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]);
 
        tape->max_stages = speed * 1000 * 10 / tape->stage_size;
 
@@ -4185,7 +3924,7 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
                tape->max_stages = tape->min_pipeline = tape->max_pipeline = 1;
 
        t1 = (tape->stage_size * HZ) / (speed * 1000);
-       tmid = (tape->capabilities.buffer_size * 32 * HZ) / (speed * 125);
+       tmid = (*(u16 *)&tape->caps[16] * 32 * HZ) / (speed * 125);
        tn = (IDETAPE_FIFO_THRESHOLD * tape->stage_size * HZ) / (speed * 1000);
 
        if (tape->max_stages)
@@ -4200,8 +3939,8 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
        tape->best_dsc_rw_frequency = max_t(unsigned long, min_t(unsigned long, t, IDETAPE_DSC_RW_MAX), IDETAPE_DSC_RW_MIN);
        printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, "
                "%dkB pipeline, %lums tDSC%s\n",
-               drive->name, tape->name, tape->capabilities.speed,
-               (tape->capabilities.buffer_size * 512) / tape->stage_size,
+               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,
                tape->best_dsc_rw_frequency * 1000 / HZ,