]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-tape.c
ide: add ide_set_media_lock() helper
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-tape.c
index b711ab96e28751c053c105a05371ba073808d0fe..b7f3eebc0d15766917f5455ecc4c35760975ad2b 100644 (file)
@@ -15,6 +15,8 @@
  * Documentation/ide/ChangeLog.ide-tape.1995-2002
  */
 
+#define DRV_NAME "ide-tape"
+
 #define IDETAPE_VERSION "1.20"
 
 #include <linux/module.h>
@@ -54,8 +56,6 @@ enum {
        DBG_CHRDEV =            (1 << 2),
        /* all remaining procedures */
        DBG_PROCS =             (1 << 3),
-       /* buffer alloc info (pc_stack & rq_stack) */
-       DBG_PCRQ_STACK =        (1 << 4),
 };
 
 /* define to see debug info */
@@ -80,19 +80,6 @@ enum {
  */
 #define IDETAPE_MAX_PC_RETRIES         3
 
-/*
- * With each packet command, we allocate a buffer of IDETAPE_PC_BUFFER_SIZE
- * bytes. This is used for several packet commands (Not for READ/WRITE commands)
- */
-#define IDETAPE_PC_BUFFER_SIZE         256
-
-/*
- *     In various places in the driver, we need to allocate storage
- *     for packet commands and requests, which will remain valid while
- *     we leave the driver to wait for an interrupt or a timeout event.
- */
-#define IDETAPE_PC_STACK               (10 + IDETAPE_MAX_PC_RETRIES)
-
 /*
  * Some drives (for example, Seagate STT3401A Travan) require a very long
  * timeout, because they don't return an interrupt or clear their busy bit
@@ -172,20 +159,6 @@ struct idetape_bh {
 #define IDETAPE_LU_RETENSION_MASK      2
 #define IDETAPE_LU_EOT_MASK            4
 
-/*
- * Special requests for our block device strategy routine.
- *
- * In order to service a character device command, we add special requests to
- * the tail of our block device request queue and wait for their completion.
- */
-
-enum {
-       REQ_IDETAPE_PC1         = (1 << 0), /* packet command (first stage) */
-       REQ_IDETAPE_PC2         = (1 << 1), /* packet command (second stage) */
-       REQ_IDETAPE_READ        = (1 << 2),
-       REQ_IDETAPE_WRITE       = (1 << 3),
-};
-
 /* Error codes returned in rq->errors to the higher part of the driver. */
 #define IDETAPE_ERROR_GENERAL          101
 #define IDETAPE_ERROR_FILEMARK         102
@@ -195,23 +168,6 @@ enum {
 #define IDETAPE_BLOCK_DESCRIPTOR       0
 #define IDETAPE_CAPABILITIES_PAGE      0x2a
 
-/* Tape flag bits values. */
-enum {
-       IDETAPE_FLAG_IGNORE_DSC         = (1 << 0),
-       /* 0 When the tape position is unknown */
-       IDETAPE_FLAG_ADDRESS_VALID      = (1 << 1),
-       /* Device already opened */
-       IDETAPE_FLAG_BUSY               = (1 << 2),
-       /* Attempt to auto-detect the current user block size */
-       IDETAPE_FLAG_DETECT_BS          = (1 << 3),
-       /* Currently on a filemark */
-       IDETAPE_FLAG_FILEMARK           = (1 << 4),
-       /* DRQ interrupt device */
-       IDETAPE_FLAG_DRQ_INTERRUPT      = (1 << 5),
-       /* 0 = no tape is loaded, so we don't rewind after ejecting */
-       IDETAPE_FLAG_MEDIUM_PRESENT     = (1 << 6),
-};
-
 /*
  * Most of our global data which we need to save even as we leave the driver due
  * to an interrupt or a timer event is stored in the struct defined below.
@@ -223,13 +179,6 @@ typedef struct ide_tape_obj {
        struct kref     kref;
 
        /*
-        *      Since a typical character device operation requires more
-        *      than one packet command, we provide here enough memory
-        *      for the maximum of interconnected packet commands.
-        *      The packet commands are stored in the circular array pc_stack.
-        *      pc_stack_index points to the last used entry, and warps around
-        *      to the start when we get to the last array entry.
-        *
         *      pc points to the current processed packet command.
         *
         *      failed_pc points to the last failed packet command, or contains
@@ -241,13 +190,11 @@ typedef struct ide_tape_obj {
        struct ide_atapi_pc *pc;
        /* Last failed packet command */
        struct ide_atapi_pc *failed_pc;
-       /* Packet command stack */
-       struct ide_atapi_pc pc_stack[IDETAPE_PC_STACK];
-       /* Next free packet command storage space */
-       int pc_stack_index;
-       struct request rq_stack[IDETAPE_PC_STACK];
-       /* We implement a circular array */
-       int rq_stack_index;
+       /* used by REQ_IDETAPE_{READ,WRITE} requests */
+       struct ide_atapi_pc queued_pc;
+
+       struct ide_atapi_pc request_sense_pc;
+       struct request request_sense_rq;
 
        /*
         * DSC polling variables.
@@ -312,8 +259,6 @@ typedef struct ide_tape_obj {
        /* Wasted space in each stage */
        int excess_bh_size;
 
-       /* Status/Action flags: long for set_bit */
-       unsigned long flags;
        /* protects the ide-tape queue */
        spinlock_t lock;
 
@@ -341,24 +286,31 @@ static struct class *idetape_sysfs_class;
 #define ide_tape_g(disk) \
        container_of((disk)->private_data, struct ide_tape_obj, driver)
 
+static void ide_tape_release(struct kref *);
+
 static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
 {
        struct ide_tape_obj *tape = NULL;
 
        mutex_lock(&idetape_ref_mutex);
        tape = ide_tape_g(disk);
-       if (tape)
-               kref_get(&tape->kref);
+       if (tape) {
+               if (ide_device_get(tape->drive))
+                       tape = NULL;
+               else
+                       kref_get(&tape->kref);
+       }
        mutex_unlock(&idetape_ref_mutex);
        return tape;
 }
 
-static void ide_tape_release(struct kref *);
-
 static void ide_tape_put(struct ide_tape_obj *tape)
 {
+       ide_drive_t *drive = tape->drive;
+
        mutex_lock(&idetape_ref_mutex);
        kref_put(&tape->kref, ide_tape_release);
+       ide_device_put(drive);
        mutex_unlock(&idetape_ref_mutex);
 }
 
@@ -398,7 +350,7 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
                count = min(
                        (unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
                        bcount);
-               drive->hwif->input_data(drive, NULL, bh->b_data +
+               drive->hwif->tp_ops->input_data(drive, NULL, bh->b_data +
                                        atomic_read(&bh->b_count), count);
                bcount -= count;
                atomic_add(count, &bh->b_count);
@@ -424,7 +376,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
                        return;
                }
                count = min((unsigned int)pc->b_count, (unsigned int)bcount);
-               drive->hwif->output_data(drive, NULL, pc->b_data, count);
+               drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
                bcount -= count;
                pc->b_data += count;
                pc->b_count -= count;
@@ -462,47 +414,6 @@ static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
        pc->bh = bh;
 }
 
-/*
- *     idetape_next_pc_storage returns a pointer to a place in which we can
- *     safely store a packet command, even though we intend to leave the
- *     driver. A storage space for a maximum of IDETAPE_PC_STACK packet
- *     commands is allocated at initialization time.
- */
-static struct ide_atapi_pc *idetape_next_pc_storage(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-
-       debug_log(DBG_PCRQ_STACK, "pc_stack_index=%d\n", tape->pc_stack_index);
-
-       if (tape->pc_stack_index == IDETAPE_PC_STACK)
-               tape->pc_stack_index = 0;
-       return (&tape->pc_stack[tape->pc_stack_index++]);
-}
-
-/*
- *     idetape_next_rq_storage is used along with idetape_next_pc_storage.
- *     Since we queue packet commands in the request queue, we need to
- *     allocate a request, along with the allocation of a packet command.
- */
-
-/**************************************************************
- *                                                            *
- *  This should get fixed to use kmalloc(.., GFP_ATOMIC)      *
- *  followed later on by kfree().   -ml                       *
- *                                                            *
- **************************************************************/
-
-static struct request *idetape_next_rq_storage(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-
-       debug_log(DBG_PCRQ_STACK, "rq_stack_index=%d\n", tape->rq_stack_index);
-
-       if (tape->rq_stack_index == IDETAPE_PC_STACK)
-               tape->rq_stack_index = 0;
-       return (&tape->rq_stack[tape->rq_stack_index++]);
-}
-
 /*
  * called on each failed packet command retry to analyze the request sense. We
  * currently do not utilize this information.
@@ -585,7 +496,6 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape)
                bh = bh->b_reqnext;
                kfree(prev_bh);
        }
-       kfree(tape->merge_bh);
 }
 
 static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
@@ -665,76 +575,29 @@ static void ide_tape_callback(ide_drive_t *drive)
                if (readpos[0] & 0x4) {
                        printk(KERN_INFO "ide-tape: Block location is unknown"
                                         "to the tape\n");
-                       clear_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
+                       clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
                        uptodate = 0;
                } else {
                        debug_log(DBG_SENSE, "Block Location - %u\n",
-                                       be32_to_cpu(*(u32 *)&readpos[4]));
+                                       be32_to_cpup((__be32 *)&readpos[4]));
 
                        tape->partition = readpos[1];
-                       tape->first_frame = be32_to_cpu(*(u32 *)&readpos[4]);
-                       set_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
+                       tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]);
+                       set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
                }
        }
 
        idetape_end_request(drive, uptodate, 0);
 }
 
-static void idetape_init_pc(struct ide_atapi_pc *pc)
-{
-       memset(pc->c, 0, 12);
-       pc->retries = 0;
-       pc->flags = 0;
-       pc->req_xfer = 0;
-       pc->buf = pc->pc_buf;
-       pc->buf_size = IDETAPE_PC_BUFFER_SIZE;
-       pc->bh = NULL;
-       pc->b_data = NULL;
-       pc->callback = ide_tape_callback;
-}
-
 static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = REQUEST_SENSE;
        pc->c[4] = 20;
        pc->req_xfer = 20;
 }
 
-static void idetape_init_rq(struct request *rq, u8 cmd)
-{
-       blk_rq_init(NULL, rq);
-       rq->cmd_type = REQ_TYPE_SPECIAL;
-       rq->cmd[0] = cmd;
-}
-
-/*
- * Generate a new packet command request in front of the request queue, before
- * the current request, so that it will be processed immediately, on the next
- * pass through the driver. The function below is called from the request
- * handling part of the driver (the "bottom" part). Safe storage for the request
- * should be allocated with ide_tape_next_{pc,rq}_storage() prior to that.
- *
- * Memory for those requests is pre-allocated at initialization time, and is
- * limited to IDETAPE_PC_STACK requests. We assume that we have enough space for
- * the maximum possible number of inter-dependent packet commands.
- *
- * The higher level of the driver - The ioctl handler and the character device
- * handling functions should queue request to the lower level part and wait for
- * their completion using idetape_queue_pc_tail or idetape_queue_rw_tail.
- */
-static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
-                                 struct request *rq)
-{
-       struct ide_tape_obj *tape = drive->driver_data;
-
-       idetape_init_rq(rq, REQ_IDETAPE_PC1);
-       rq->cmd_flags |= REQ_PREEMPT;
-       rq->buffer = (char *) pc;
-       rq->rq_disk = tape->disk;
-       ide_do_drive_cmd(drive, rq);
-}
-
 /*
  *     idetape_retry_pc is called when an error was detected during the
  *     last packet command. We queue a request sense packet command in
@@ -742,16 +605,14 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
  */
 static void idetape_retry_pc(ide_drive_t *drive)
 {
-       idetape_tape_t *tape = drive->driver_data;
-       struct ide_atapi_pc *pc;
-       struct request *rq;
+       struct ide_tape_obj *tape = drive->driver_data;
+       struct request *rq = &tape->request_sense_rq;
+       struct ide_atapi_pc *pc = &tape->request_sense_pc;
 
        (void)ide_read_error(drive);
-       pc = idetape_next_pc_storage(drive);
-       rq = idetape_next_rq_storage(drive);
        idetape_create_request_sense_cmd(pc);
-       set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
-       idetape_queue_pc_head(drive, pc, rq);
+       set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
+       ide_queue_pc_head(drive, tape->disk, pc, rq);
 }
 
 /*
@@ -780,13 +641,15 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
        idetape_postpone_request(drive);
 }
 
-static void ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
                                unsigned int bcount, int write)
 {
        if (write)
                idetape_output_buffers(drive, pc, bcount);
        else
                idetape_input_buffers(drive, pc, bcount);
+
+       return bcount;
 }
 
 /*
@@ -887,7 +750,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
                        pc->error = IDETAPE_ERROR_GENERAL;
                }
                tape->failed_pc = NULL;
-               pc->callback(drive);
+               drive->pc_callback(drive);
                return ide_stopped;
        }
        debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);
@@ -901,7 +764,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
 /* A mode sense command is used to "sense" tape parameters. */
 static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = MODE_SENSE;
        if (page_code != IDETAPE_BLOCK_DESCRIPTOR)
                /* DBD = 1 - Don't return block descriptors */
@@ -927,14 +790,15 @@ static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
 
 static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
        idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc *pc = tape->pc;
        u8 stat;
 
-       stat = ide_read_status(drive);
+       stat = hwif->tp_ops->read_status(hwif);
 
-       if (stat & SEEK_STAT) {
-               if (stat & ERR_STAT) {
+       if (stat & ATA_DSC) {
+               if (stat & ATA_ERR) {
                        /* Error detected */
                        if (pc->c[0] != TEST_UNIT_READY)
                                printk(KERN_ERR "ide-tape: %s: I/O error, ",
@@ -948,15 +812,18 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
                pc->error = IDETAPE_ERROR_GENERAL;
                tape->failed_pc = NULL;
        }
-       pc->callback(drive);
+       drive->pc_callback(drive);
        return ide_stopped;
 }
 
 static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
-               struct ide_atapi_pc *pc, unsigned int length,
-               struct idetape_bh *bh, u8 opcode)
+                                  struct ide_atapi_pc *pc, struct request *rq,
+                                  u8 opcode)
 {
-       idetape_init_pc(pc);
+       struct idetape_bh *bh = (struct idetape_bh *)rq->special;
+       unsigned int length = rq->current_nr_sectors;
+
+       ide_init_pc(pc);
        put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
        pc->c[1] = 1;
        pc->bh = bh;
@@ -975,19 +842,23 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
                pc->b_data = bh->b_data;
                pc->b_count = atomic_read(&bh->b_count);
        }
+
+       memcpy(rq->cmd, pc->c, 12);
 }
 
 static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                                          struct request *rq, sector_t block)
 {
+       ide_hwif_t *hwif = drive->hwif;
        idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc *pc = NULL;
        struct request *postponed_rq = tape->postponed_rq;
        u8 stat;
 
-       debug_log(DBG_SENSE, "sector: %ld, nr_sectors: %ld,"
-                       " current_nr_sectors: %d\n",
-                       rq->sector, rq->nr_sectors, rq->current_nr_sectors);
+       debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu,"
+                       " current_nr_sectors: %u\n",
+                       (unsigned long long)rq->sector, rq->nr_sectors,
+                       rq->current_nr_sectors);
 
        if (!blk_special_request(rq)) {
                /* We do not support buffer cache originated requests. */
@@ -1017,18 +888,18 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
         * If the tape is still busy, postpone our request and service
         * the other device meanwhile.
         */
-       stat = ide_read_status(drive);
+       stat = hwif->tp_ops->read_status(hwif);
 
-       if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2))
-               set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
+       if (!drive->dsc_overlap && !(rq->cmd[13] & REQ_IDETAPE_PC2))
+               set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
 
        if (drive->post_reset == 1) {
-               set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
+               set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
                drive->post_reset = 0;
        }
 
-       if (!test_and_clear_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags) &&
-           (stat & SEEK_STAT) == 0) {
+       if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) &&
+           (stat & ATA_DSC) == 0) {
                if (postponed_rq == NULL) {
                        tape->dsc_polling_start = jiffies;
                        tape->dsc_poll_freq = tape->best_dsc_rw_freq;
@@ -1036,7 +907,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                } else if (time_after(jiffies, tape->dsc_timeout)) {
                        printk(KERN_ERR "ide-tape: %s: DSC timeout\n",
                                tape->name);
-                       if (rq->cmd[0] & REQ_IDETAPE_PC2) {
+                       if (rq->cmd[13] & REQ_IDETAPE_PC2) {
                                idetape_media_access_finished(drive);
                                return ide_stopped;
                        } else {
@@ -1049,35 +920,29 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                idetape_postpone_request(drive);
                return ide_stopped;
        }
-       if (rq->cmd[0] & REQ_IDETAPE_READ) {
-               pc = idetape_next_pc_storage(drive);
-               ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors,
-                                       (struct idetape_bh *)rq->special,
-                                       READ_6);
+       if (rq->cmd[13] & REQ_IDETAPE_READ) {
+               pc = &tape->queued_pc;
+               ide_tape_create_rw_cmd(tape, pc, rq, READ_6);
                goto out;
        }
-       if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
-               pc = idetape_next_pc_storage(drive);
-               ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors,
-                                        (struct idetape_bh *)rq->special,
-                                        WRITE_6);
+       if (rq->cmd[13] & REQ_IDETAPE_WRITE) {
+               pc = &tape->queued_pc;
+               ide_tape_create_rw_cmd(tape, pc, rq, WRITE_6);
                goto out;
        }
-       if (rq->cmd[0] & REQ_IDETAPE_PC1) {
+       if (rq->cmd[13] & REQ_IDETAPE_PC1) {
                pc = (struct ide_atapi_pc *) rq->buffer;
-               rq->cmd[0] &= ~(REQ_IDETAPE_PC1);
-               rq->cmd[0] |= REQ_IDETAPE_PC2;
+               rq->cmd[13] &= ~(REQ_IDETAPE_PC1);
+               rq->cmd[13] |= REQ_IDETAPE_PC2;
                goto out;
        }
-       if (rq->cmd[0] & REQ_IDETAPE_PC2) {
+       if (rq->cmd[13] & REQ_IDETAPE_PC2) {
                idetape_media_access_finished(drive);
                return ide_stopped;
        }
        BUG();
-out:
-       if (test_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags))
-               pc->flags |= PC_FLAG_DRQ_INTERRUPT;
 
+out:
        return idetape_issue_pc(drive, pc);
 }
 
@@ -1248,7 +1113,7 @@ static void idetape_init_merge_buffer(idetape_tape_t *tape)
 static void idetape_create_write_filemark_cmd(ide_drive_t *drive,
                struct ide_atapi_pc *pc, int write_filemark)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = WRITE_FILEMARKS;
        pc->c[4] = write_filemark;
        pc->flags |= PC_FLAG_WAIT_FOR_DSC;
@@ -1256,42 +1121,14 @@ static void idetape_create_write_filemark_cmd(ide_drive_t *drive,
 
 static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = TEST_UNIT_READY;
 }
 
-/*
- * We add a special packet command request to the tail of the request queue, and
- * wait for it to be serviced. This is not to be called from within the request
- * handling part of the driver! We allocate here data on the stack and it is
- * valid until the request is finished. This is not the case for the bottom part
- * of the driver, where we are always leaving the functions to wait for an
- * interrupt or a timer event.
- *
- * From the bottom part of the driver, we should allocate safe memory using
- * idetape_next_pc_storage() and ide_tape_next_rq_storage(), and add 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, struct ide_atapi_pc *pc)
-{
-       struct ide_tape_obj *tape = drive->driver_data;
-       struct request *rq;
-       int error;
-
-       rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
-       rq->cmd_type = REQ_TYPE_SPECIAL;
-       rq->cmd[0] = REQ_IDETAPE_PC1;
-       rq->buffer = (char *)pc;
-       error = blk_execute_rq(drive->queue, tape->disk, rq, 0);
-       blk_put_request(rq);
-       return error;
-}
-
 static void idetape_create_load_unload_cmd(ide_drive_t *drive,
                struct ide_atapi_pc *pc, int cmd)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = START_STOP;
        pc->c[4] = cmd;
        pc->flags |= PC_FLAG_WAIT_FOR_DSC;
@@ -1300,15 +1137,16 @@ static void idetape_create_load_unload_cmd(ide_drive_t *drive,
 static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
 {
        idetape_tape_t *tape = drive->driver_data;
+       struct gendisk *disk = tape->disk;
        struct ide_atapi_pc pc;
        int load_attempted = 0;
 
        /* Wait for the tape to become ready */
-       set_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags);
+       set_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
        timeout += jiffies;
        while (time_before(jiffies, timeout)) {
                idetape_create_test_unit_ready_cmd(&pc);
-               if (!idetape_queue_pc_tail(drive, &pc))
+               if (!ide_queue_pc_tail(drive, disk, &pc))
                        return 0;
                if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2)
                    || (tape->asc == 0x3A)) {
@@ -1317,7 +1155,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
                                return -ENOMEDIUM;
                        idetape_create_load_unload_cmd(drive, &pc,
                                                        IDETAPE_LU_LOAD_MASK);
-                       idetape_queue_pc_tail(drive, &pc);
+                       ide_queue_pc_tail(drive, disk, &pc);
                        load_attempted = 1;
                /* not about to be ready */
                } else if (!(tape->sense_key == 2 && tape->asc == 4 &&
@@ -1330,11 +1168,12 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
 
 static int idetape_flush_tape_buffers(ide_drive_t *drive)
 {
+       struct ide_tape_obj *tape = drive->driver_data;
        struct ide_atapi_pc pc;
        int rc;
 
        idetape_create_write_filemark_cmd(drive, &pc, 0);
-       rc = idetape_queue_pc_tail(drive, &pc);
+       rc = ide_queue_pc_tail(drive, tape->disk, &pc);
        if (rc)
                return rc;
        idetape_wait_ready(drive, 60 * 5 * HZ);
@@ -1343,7 +1182,7 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive)
 
 static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = READ_POSITION;
        pc->req_xfer = 20;
 }
@@ -1357,7 +1196,7 @@ static int idetape_read_position(ide_drive_t *drive)
        debug_log(DBG_PROCS, "Enter %s\n", __func__);
 
        idetape_create_read_position_cmd(&pc);
-       if (idetape_queue_pc_tail(drive, &pc))
+       if (ide_queue_pc_tail(drive, tape->disk, &pc))
                return -1;
        position = tape->first_frame;
        return position;
@@ -1367,7 +1206,7 @@ static void idetape_create_locate_cmd(ide_drive_t *drive,
                struct ide_atapi_pc *pc,
                unsigned int block, u8 partition, int skip)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = POSITION_TO_ELEMENT;
        pc->c[1] = 2;
        put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]);
@@ -1375,21 +1214,6 @@ static void idetape_create_locate_cmd(ide_drive_t *drive,
        pc->flags |= PC_FLAG_WAIT_FOR_DSC;
 }
 
-static int idetape_create_prevent_cmd(ide_drive_t *drive,
-               struct ide_atapi_pc *pc, int prevent)
-{
-       idetape_tape_t *tape = drive->driver_data;
-
-       /* device supports locking according to capabilities page */
-       if (!(tape->caps[6] & 0x01))
-               return 0;
-
-       idetape_init_pc(pc);
-       pc->c[0] = ALLOW_MEDIUM_REMOVAL;
-       pc->c[4] = prevent;
-       return 1;
-}
-
 static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
@@ -1397,7 +1221,7 @@ static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
        if (tape->chrdev_dir != IDETAPE_DIR_READ)
                return;
 
-       clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags);
+       clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags);
        tape->merge_bh_size = 0;
        if (tape->merge_bh != NULL) {
                ide_tape_kfree_buffer(tape);
@@ -1417,6 +1241,7 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
                u8 partition, int skip)
 {
        idetape_tape_t *tape = drive->driver_data;
+       struct gendisk *disk = tape->disk;
        int retval;
        struct ide_atapi_pc pc;
 
@@ -1424,12 +1249,12 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
                __ide_tape_discard_merge_buffer(drive);
        idetape_wait_ready(drive, 60 * 5 * HZ);
        idetape_create_locate_cmd(drive, &pc, block, partition, skip);
-       retval = idetape_queue_pc_tail(drive, &pc);
+       retval = ide_queue_pc_tail(drive, disk, &pc);
        if (retval)
                return (retval);
 
        idetape_create_read_position_cmd(&pc);
-       return (idetape_queue_pc_tail(drive, &pc));
+       return ide_queue_pc_tail(drive, disk, &pc);
 }
 
 static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
@@ -1465,7 +1290,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
 
        rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
        rq->cmd_type = REQ_TYPE_SPECIAL;
-       rq->cmd[0] = cmd;
+       rq->cmd[13] = cmd;
        rq->rq_disk = tape->disk;
        rq->special = (void *)bh;
        rq->sector = tape->first_frame;
@@ -1489,7 +1314,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
 
 static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = INQUIRY;
        pc->c[4] = 254;
        pc->req_xfer = 254;
@@ -1498,14 +1323,14 @@ static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc)
 static void idetape_create_rewind_cmd(ide_drive_t *drive,
                struct ide_atapi_pc *pc)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = REZERO_UNIT;
        pc->flags |= PC_FLAG_WAIT_FOR_DSC;
 }
 
 static void idetape_create_erase_cmd(struct ide_atapi_pc *pc)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = ERASE;
        pc->c[1] = 1;
        pc->flags |= PC_FLAG_WAIT_FOR_DSC;
@@ -1513,7 +1338,7 @@ static void idetape_create_erase_cmd(struct ide_atapi_pc *pc)
 
 static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
 {
-       idetape_init_pc(pc);
+       ide_init_pc(pc);
        pc->c[0] = SPACE;
        put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]);
        pc->c[1] = cmd;
@@ -1636,7 +1461,7 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
        debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks);
 
        /* If we are at a filemark, return a read length of 0 */
-       if (test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
+       if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
                return 0;
 
        idetape_init_read(drive);
@@ -1676,20 +1501,20 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
  */
 static int idetape_rewind_tape(ide_drive_t *drive)
 {
+       struct ide_tape_obj *tape = drive->driver_data;
+       struct gendisk *disk = tape->disk;
        int retval;
        struct ide_atapi_pc pc;
-       idetape_tape_t *tape;
-       tape = drive->driver_data;
 
        debug_log(DBG_SENSE, "Enter %s\n", __func__);
 
        idetape_create_rewind_cmd(drive, &pc);
-       retval = idetape_queue_pc_tail(drive, &pc);
+       retval = ide_queue_pc_tail(drive, disk, &pc);
        if (retval)
                return retval;
 
        idetape_create_read_position_cmd(&pc);
-       retval = idetape_queue_pc_tail(drive, &pc);
+       retval = ide_queue_pc_tail(drive, disk, &pc);
        if (retval)
                return retval;
        return 0;
@@ -1732,6 +1557,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
                                        int mt_count)
 {
        idetape_tape_t *tape = drive->driver_data;
+       struct gendisk *disk = tape->disk;
        struct ide_atapi_pc pc;
        int retval, count = 0;
        int sprev = !!(tape->caps[4] & 0x20);
@@ -1746,7 +1572,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
 
        if (tape->chrdev_dir == IDETAPE_DIR_READ) {
                tape->merge_bh_size = 0;
-               if (test_and_clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
+               if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
                        ++count;
                ide_tape_discard_merge_buffer(drive, 0);
        }
@@ -1756,7 +1582,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
        case MTBSF:
                idetape_create_space_cmd(&pc, mt_count - count,
                                         IDETAPE_SPACE_OVER_FILEMARK);
-               return idetape_queue_pc_tail(drive, &pc);
+               return ide_queue_pc_tail(drive, disk, &pc);
        case MTFSFM:
        case MTBSFM:
                if (!sprev)
@@ -1801,7 +1627,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
        debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
 
        if (tape->chrdev_dir != IDETAPE_DIR_READ) {
-               if (test_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags))
+               if (test_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags))
                        if (count > tape->blk_size &&
                            (count % tape->blk_size) == 0)
                                tape->user_bs_factor = count / tape->blk_size;
@@ -1841,7 +1667,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
                tape->merge_bh_size = bytes_read-temp;
        }
 finish:
-       if (!actually_read && test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags)) {
+       if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) {
                debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name);
 
                idetape_space_over_filemarks(drive, MTFSF, 1);
@@ -1945,11 +1771,12 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
 
 static int idetape_write_filemark(ide_drive_t *drive)
 {
+       struct ide_tape_obj *tape = drive->driver_data;
        struct ide_atapi_pc pc;
 
        /* Write a filemark */
        idetape_create_write_filemark_cmd(drive, &pc, 1);
-       if (idetape_queue_pc_tail(drive, &pc)) {
+       if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
                printk(KERN_ERR "ide-tape: Couldn't write a filemark\n");
                return -EIO;
        }
@@ -1972,6 +1799,7 @@ static int idetape_write_filemark(ide_drive_t *drive)
 static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
 {
        idetape_tape_t *tape = drive->driver_data;
+       struct gendisk *disk = tape->disk;
        struct ide_atapi_pc pc;
        int i, retval;
 
@@ -2010,7 +1838,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
                ide_tape_discard_merge_buffer(drive, 0);
                idetape_create_load_unload_cmd(drive, &pc,
                                               IDETAPE_LU_LOAD_MASK);
-               return idetape_queue_pc_tail(drive, &pc);
+               return ide_queue_pc_tail(drive, disk, &pc);
        case MTUNLOAD:
        case MTOFFL:
                /*
@@ -2018,16 +1846,15 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
                 * attempting to eject.
                 */
                if (tape->door_locked) {
-                       if (idetape_create_prevent_cmd(drive, &pc, 0))
-                               if (!idetape_queue_pc_tail(drive, &pc))
-                                       tape->door_locked = DOOR_UNLOCKED;
+                       if (!ide_set_media_lock(drive, disk, 0))
+                               tape->door_locked = DOOR_UNLOCKED;
                }
                ide_tape_discard_merge_buffer(drive, 0);
                idetape_create_load_unload_cmd(drive, &pc,
                                              !IDETAPE_LU_LOAD_MASK);
-               retval = idetape_queue_pc_tail(drive, &pc);
+               retval = ide_queue_pc_tail(drive, disk, &pc);
                if (!retval)
-                       clear_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags);
+                       clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
                return retval;
        case MTNOP:
                ide_tape_discard_merge_buffer(drive, 0);
@@ -2036,23 +1863,23 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
                ide_tape_discard_merge_buffer(drive, 0);
                idetape_create_load_unload_cmd(drive, &pc,
                        IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK);
-               return idetape_queue_pc_tail(drive, &pc);
+               return ide_queue_pc_tail(drive, disk, &pc);
        case MTEOM:
                idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD);
-               return idetape_queue_pc_tail(drive, &pc);
+               return ide_queue_pc_tail(drive, disk, &pc);
        case MTERASE:
                (void)idetape_rewind_tape(drive);
                idetape_create_erase_cmd(&pc);
-               return idetape_queue_pc_tail(drive, &pc);
+               return ide_queue_pc_tail(drive, disk, &pc);
        case MTSETBLK:
                if (mt_count) {
                        if (mt_count < tape->blk_size ||
                            mt_count % tape->blk_size)
                                return -EIO;
                        tape->user_bs_factor = mt_count / tape->blk_size;
-                       clear_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags);
+                       clear_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags);
                } else
-                       set_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags);
+                       set_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags);
                return 0;
        case MTSEEK:
                ide_tape_discard_merge_buffer(drive, 0);
@@ -2064,17 +1891,13 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
        case MTFSR:
        case MTBSR:
        case MTLOCK:
-               if (!idetape_create_prevent_cmd(drive, &pc, 1))
-                       return 0;
-               retval = idetape_queue_pc_tail(drive, &pc);
+               retval = ide_set_media_lock(drive, disk, 1);
                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 = ide_set_media_lock(drive, disk, 0);
                if (retval)
                        return retval;
                tape->door_locked = DOOR_UNLOCKED;
@@ -2156,7 +1979,7 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
        struct ide_atapi_pc pc;
 
        idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR);
-       if (idetape_queue_pc_tail(drive, &pc)) {
+       if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
                printk(KERN_ERR "ide-tape: Can't get block descriptor\n");
                if (tape->blk_size == 0) {
                        printk(KERN_WARNING "ide-tape: Cannot deal with zero "
@@ -2176,7 +1999,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
        unsigned int minor = iminor(inode), i = minor & ~0xc0;
        ide_drive_t *drive;
        idetape_tape_t *tape;
-       struct ide_atapi_pc pc;
        int retval;
 
        if (i >= MAX_HWIFS * MAX_DRIVES)
@@ -2202,20 +2024,20 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
 
        filp->private_data = tape;
 
-       if (test_and_set_bit(IDETAPE_FLAG_BUSY, &tape->flags)) {
+       if (test_and_set_bit(IDE_AFLAG_BUSY, &drive->atapi_flags)) {
                retval = -EBUSY;
                goto out_put_tape;
        }
 
        retval = idetape_wait_ready(drive, 60 * HZ);
        if (retval) {
-               clear_bit(IDETAPE_FLAG_BUSY, &tape->flags);
+               clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
                printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
                goto out_put_tape;
        }
 
        idetape_read_position(drive);
-       if (!test_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags))
+       if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags))
                (void)idetape_rewind_tape(drive);
 
        /* Read block size and write protect status from drive. */
@@ -2231,7 +2053,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
        if (tape->write_prot) {
                if ((filp->f_flags & O_ACCMODE) == O_WRONLY ||
                    (filp->f_flags & O_ACCMODE) == O_RDWR) {
-                       clear_bit(IDETAPE_FLAG_BUSY, &tape->flags);
+                       clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
                        retval = -EROFS;
                        goto out_put_tape;
                }
@@ -2239,11 +2061,9 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
 
        /* Lock the tape drive door so user can't eject. */
        if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
-               if (idetape_create_prevent_cmd(drive, &pc, 1)) {
-                       if (!idetape_queue_pc_tail(drive, &pc)) {
-                               if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
-                                       tape->door_locked = DOOR_LOCKED;
-                       }
+               if (!ide_set_media_lock(drive, tape->disk, 1)) {
+                       if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
+                               tape->door_locked = DOOR_LOCKED;
                }
        }
        unlock_kernel();
@@ -2276,7 +2096,6 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
 {
        struct ide_tape_obj *tape = ide_tape_f(filp);
        ide_drive_t *drive = tape->drive;
-       struct ide_atapi_pc pc;
        unsigned int minor = iminor(inode);
 
        lock_kernel();
@@ -2291,69 +2110,28 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
                        ide_tape_discard_merge_buffer(drive, 1);
        }
 
-       if (minor < 128 && test_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags))
+       if (minor < 128 && test_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags))
                (void) idetape_rewind_tape(drive);
        if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
                if (tape->door_locked == DOOR_LOCKED) {
-                       if (idetape_create_prevent_cmd(drive, &pc, 0)) {
-                               if (!idetape_queue_pc_tail(drive, &pc))
-                                       tape->door_locked = DOOR_UNLOCKED;
-                       }
+                       if (!ide_set_media_lock(drive, tape->disk, 0))
+                               tape->door_locked = DOOR_UNLOCKED;
                }
        }
-       clear_bit(IDETAPE_FLAG_BUSY, &tape->flags);
+       clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
        ide_tape_put(tape);
        unlock_kernel();
        return 0;
 }
 
-/*
- * check the contents of the ATAPI IDENTIFY command results. We return:
- *
- * 1 - If the tape can be supported by us, based on the information we have so
- * far.
- *
- * 0 - If this tape driver is not currently supported by us.
- */
-static int idetape_identify_device(ide_drive_t *drive)
-{
-       u8 gcw[2], protocol, device_type, removable, packet_size;
-
-       if (drive->id_read == 0)
-               return 1;
-
-       *((unsigned short *) &gcw) = drive->id->config;
-
-       protocol        =   (gcw[1] & 0xC0) >> 6;
-       device_type     =    gcw[1] & 0x1F;
-       removable       = !!(gcw[0] & 0x80);
-       packet_size     =    gcw[0] & 0x3;
-
-       /* Check that we can support this device */
-       if (protocol != 2)
-               printk(KERN_ERR "ide-tape: Protocol (0x%02x) is not ATAPI\n",
-                               protocol);
-       else if (device_type != 1)
-               printk(KERN_ERR "ide-tape: Device type (0x%02x) is not set "
-                               "to tape\n", device_type);
-       else if (!removable)
-               printk(KERN_ERR "ide-tape: The removable flag is not set\n");
-       else if (packet_size != 0) {
-               printk(KERN_ERR "ide-tape: Packet size (0x%02x) is not 12"
-                               " bytes\n", packet_size);
-       } else
-               return 1;
-       return 0;
-}
-
 static void idetape_get_inquiry_results(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc pc;
-       char fw_rev[6], vendor_id[10], product_id[18];
+       char fw_rev[4], vendor_id[8], product_id[16];
 
        idetape_create_inquiry_cmd(&pc);
-       if (idetape_queue_pc_tail(drive, &pc)) {
+       if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
                printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
                                tape->name);
                return;
@@ -2362,11 +2140,11 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
        memcpy(product_id, &pc.buf[16], 16);
        memcpy(fw_rev, &pc.buf[32], 4);
 
-       ide_fixstring(vendor_id, 10, 0);
-       ide_fixstring(product_id, 18, 0);
-       ide_fixstring(fw_rev, 6, 0);
+       ide_fixstring(vendor_id, 8, 0);
+       ide_fixstring(product_id, 16, 0);
+       ide_fixstring(fw_rev, 4, 0);
 
-       printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n",
+       printk(KERN_INFO "ide-tape: %s <-> %s: %.8s %.16s rev %.4s\n",
                        drive->name, tape->name, vendor_id, product_id, fw_rev);
 }
 
@@ -2382,7 +2160,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
        u8 speed, max_speed;
 
        idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE);
-       if (idetape_queue_pc_tail(drive, &pc)) {
+       if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
                printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming"
                                " some default values\n");
                tape->blk_size = 512;
@@ -2394,26 +2172,31 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
        caps = pc.buf + 4 + pc.buf[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]);
+       speed = be16_to_cpup((__be16 *)&caps[14]);
+       max_speed = be16_to_cpup((__be16 *)&caps[8]);
 
-       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]);
+       *(u16 *)&caps[8] = max_speed;
+       *(u16 *)&caps[12] = be16_to_cpup((__be16 *)&caps[12]);
+       *(u16 *)&caps[14] = speed;
+       *(u16 *)&caps[16] = be16_to_cpup((__be16 *)&caps[16]);
 
        if (!speed) {
                printk(KERN_INFO "ide-tape: %s: invalid tape speed "
                                "(assuming 650KB/sec)\n", drive->name);
-               put_unaligned(650, (u16 *)&caps[14]);
+               *(u16 *)&caps[14] = 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]);
+               *(u16 *)&caps[8] = 650;
        }
 
        memcpy(&tape->caps, caps, 20);
+
+       /* device lacks locking support according to capabilities page */
+       if ((caps[6] & 1) == 0)
+               drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+
        if (caps[7] & 0x02)
                tape->blk_size = 512;
        else if (caps[7] & 0x04)
@@ -2421,28 +2204,56 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
 }
 
 #ifdef CONFIG_IDE_PROC_FS
-static void idetape_add_settings(ide_drive_t *drive)
-{
-       idetape_tape_t *tape = drive->driver_data;
-
-       ide_add_setting(drive, "buffer", SETTING_READ, TYPE_SHORT, 0, 0xffff,
-                       1, 2, (u16 *)&tape->caps[16], NULL);
-       ide_add_setting(drive, "speed", SETTING_READ, TYPE_SHORT, 0, 0xffff,
-                       1, 1, (u16 *)&tape->caps[14], NULL);
-       ide_add_setting(drive, "buffer_size", SETTING_READ, TYPE_INT, 0, 0xffff,
-                       1, 1024, &tape->buffer_size, NULL);
-       ide_add_setting(drive, "tdsc", SETTING_RW, TYPE_INT, IDETAPE_DSC_RW_MIN,
-                       IDETAPE_DSC_RW_MAX, 1000, HZ, &tape->best_dsc_rw_freq,
-                       NULL);
-       ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1,
-                       1, &drive->dsc_overlap, NULL);
-       ide_add_setting(drive, "avg_speed", SETTING_READ, TYPE_INT, 0, 0xffff,
-                       1, 1, &tape->avg_speed, NULL);
-       ide_add_setting(drive, "debug_mask", SETTING_RW, TYPE_INT, 0, 0xffff, 1,
-                       1, &tape->debug_mask, NULL);
-}
-#else
-static inline void idetape_add_settings(ide_drive_t *drive) { ; }
+#define ide_tape_devset_get(name, field) \
+static int get_##name(ide_drive_t *drive) \
+{ \
+       idetape_tape_t *tape = drive->driver_data; \
+       return tape->field; \
+}
+
+#define ide_tape_devset_set(name, field) \
+static int set_##name(ide_drive_t *drive, int arg) \
+{ \
+       idetape_tape_t *tape = drive->driver_data; \
+       tape->field = arg; \
+       return 0; \
+}
+
+#define ide_tape_devset_rw(_name, _min, _max, _field, _mulf, _divf) \
+ide_tape_devset_get(_name, _field) \
+ide_tape_devset_set(_name, _field) \
+__IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name, _mulf, _divf)
+
+#define ide_tape_devset_r(_name, _min, _max, _field, _mulf, _divf) \
+ide_tape_devset_get(_name, _field) \
+__IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL, _mulf, _divf)
+
+static int mulf_tdsc(ide_drive_t *drive)       { return 1000; }
+static int divf_tdsc(ide_drive_t *drive)       { return   HZ; }
+static int divf_buffer(ide_drive_t *drive)     { return    2; }
+static int divf_buffer_size(ide_drive_t *drive)        { return 1024; }
+
+ide_devset_rw(dsc_overlap,     0,      1, dsc_overlap);
+
+ide_tape_devset_rw(debug_mask, 0, 0xffff, debug_mask,  NULL, NULL);
+ide_tape_devset_rw(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
+                  best_dsc_rw_freq, mulf_tdsc, divf_tdsc);
+
+ide_tape_devset_r(avg_speed,   0, 0xffff, avg_speed,   NULL, NULL);
+ide_tape_devset_r(speed,       0, 0xffff, caps[14],    NULL, NULL);
+ide_tape_devset_r(buffer,      0, 0xffff, caps[16],    NULL, divf_buffer);
+ide_tape_devset_r(buffer_size, 0, 0xffff, buffer_size, NULL, divf_buffer_size);
+
+static const struct ide_devset *idetape_settings[] = {
+       &ide_devset_avg_speed,
+       &ide_devset_buffer,
+       &ide_devset_buffer_size,
+       &ide_devset_debug_mask,
+       &ide_devset_dsc_overlap,
+       &ide_devset_speed,
+       &ide_devset_tdsc,
+       NULL
+};
 #endif
 
 /*
@@ -2464,6 +2275,8 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
        u8 gcw[2];
        u16 *ctl = (u16 *)&tape->caps[12];
 
+       drive->pc_callback = ide_tape_callback;
+
        spin_lock_init(&tape->lock);
        drive->dsc_overlap = 1;
        if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
@@ -2472,19 +2285,19 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
                drive->dsc_overlap = 0;
        }
        /* Seagate Travan drives do not support DSC overlap. */
-       if (strstr(drive->id->model, "Seagate STT3401"))
+       if (strstr((char *)&drive->id[ATA_ID_PROD], "Seagate STT3401"))
                drive->dsc_overlap = 0;
        tape->minor = minor;
        tape->name[0] = 'h';
        tape->name[1] = 't';
        tape->name[2] = '0' + minor;
        tape->chrdev_dir = IDETAPE_DIR_NONE;
-       tape->pc = tape->pc_stack;
-       *((unsigned short *) &gcw) = drive->id->config;
+
+       *((u16 *)&gcw) = drive->id[ATA_ID_CONFIG];
 
        /* Command packet DRQ type */
        if (((gcw[0] & 0x60) >> 5) == 1)
-               set_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags);
+               set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags);
 
        idetape_get_inquiry_results(drive);
        idetape_get_mode_sense_results(drive);
@@ -2522,7 +2335,7 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
                tape->best_dsc_rw_freq * 1000 / HZ,
                drive->using_dma ? ", DMA":"");
 
-       idetape_add_settings(drive);
+       ide_proc_register_driver(drive, tape->driver);
 }
 
 static void ide_tape_remove(ide_drive_t *drive)
@@ -2587,12 +2400,12 @@ static ide_driver_t idetape_driver = {
        .remove                 = ide_tape_remove,
        .version                = IDETAPE_VERSION,
        .media                  = ide_tape,
-       .supports_dsc_overlap   = 1,
        .do_request             = idetape_do_request,
        .end_request            = idetape_end_request,
        .error                  = __ide_error,
 #ifdef CONFIG_IDE_PROC_FS
        .proc                   = idetape_proc,
+       .settings               = idetape_settings,
 #endif
 };
 
@@ -2655,11 +2468,11 @@ static int ide_tape_probe(ide_drive_t *drive)
 
        if (!strstr("ide-tape", drive->driver_req))
                goto failed;
-       if (!drive->present)
-               goto failed;
+
        if (drive->media != ide_tape)
                goto failed;
-       if (!idetape_identify_device(drive)) {
+
+       if (drive->id_read == 1 && !ide_check_atapi_device(drive, DRV_NAME)) {
                printk(KERN_ERR "ide-tape: %s: not supported by this version of"
                                " the driver\n", drive->name);
                goto failed;
@@ -2677,8 +2490,6 @@ static int ide_tape_probe(ide_drive_t *drive)
 
        ide_init_disk(g, drive);
 
-       ide_proc_register_driver(drive, &idetape_driver);
-
        kref_init(&tape->kref);
 
        tape->drive = drive;
@@ -2697,10 +2508,12 @@ static int ide_tape_probe(ide_drive_t *drive)
 
        idetape_setup(drive, tape, minor);
 
-       device_create(idetape_sysfs_class, &drive->gendev,
-                     MKDEV(IDETAPE_MAJOR, minor), "%s", tape->name);
-       device_create(idetape_sysfs_class, &drive->gendev,
-                       MKDEV(IDETAPE_MAJOR, minor + 128), "n%s", tape->name);
+       device_create_drvdata(idetape_sysfs_class, &drive->gendev,
+                             MKDEV(IDETAPE_MAJOR, minor), NULL,
+                             "%s", tape->name);
+       device_create_drvdata(idetape_sysfs_class, &drive->gendev,
+                             MKDEV(IDETAPE_MAJOR, minor + 128), NULL,
+                             "n%s", tape->name);
 
        g->fops = &idetape_block_ops;
        ide_register_region(g);