* [PATCH] (for ide-tape.c in 2.4.22-ac4) ide-tape.c doesn't work with Seagate Trav
@ 2003-10-21 22:21 stuart hayes
2003-10-22 22:15 ` Bartlomiej Zolnierkiewicz
0 siblings, 1 reply; 4+ messages in thread
From: stuart hayes @ 2003-10-21 22:21 UTC (permalink / raw)
To: B.Zolnierkiewicz; +Cc: linux-ide, stuart_hayes
This patch gets ide-tape.c working with Seagate Travan drives (and also fixes a bug with the pipeline). Note that this is for the 2.4.22-ac4 kernel.
Please respond to me at stuart_hayes@dell.com (which is on the cc: list above)--I am only using this email address so the patch text doesn't get mangled.
Thanks
--Stuart
--- ide-tape.c.rc2 Fri Oct 10 15:27:59 2003
+++ ide-tape-sgfix-try11.c Fri Oct 10 14:30:39 2003
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/ide-tape.c Version 1.17c Sep, 2003
+ * linux/drivers/ide/ide-tape.c Version 1.18 Sep, 2003
*
* Copyright (C) 1995 - 1999 Gadi Oxman <gadio@netvision.net.il>
*
@@ -316,6 +316,27 @@
* Ver 1.17c Sep 2003 Stuart Hayes <stuart_hayes@dell.com>
* Initialized "feature" in idetape_issue_packet_command
* (this was causing lockups on certain systems)
+ * Ver 1.18 Sep 2003 Stuart Hayes <stuart_hayes@dell.com>
+ * Check drive's write protect bit, try to return appropriate
+ * errors when attempting to write a write-protected tape
+ * Moved "idetape_read_position" call in idetape_chrdev_open
+ * after the "wait_ready" call
+ * Added IDETAPE_MEDIUM_PRESENT flag so driver would know
+ * not to rewind tape after ejecting it
+ * Fixed bug with ide_abort_pipeline (it was deleting stages
+ * from tape->next_stage to end, instead of from
+ * new_last_stage->next (tape->next_stage was set to NULL
+ * by idetape_discard_read_pipeline before calling!)
+ * Deleted "idetape_do_end_request"--this was just a copy of
+ * ide_end_request
+ * Made improvements to idetape_wait_ready
+ * Added a few comments here and there
+ * Made MTOFFL unlock tape drive door before attempting to eject
+ * Added fixes to get Seagate STT3401A Travan working:
+ * handle drives that don't support 0-length reads/writes
+ * increased timeout (retension takes ~10 minutes before
+ * irq is returned)
+ * fixed request mode page packet command byte 3
*
* Here are some words from the first releases of hd.c, which are quoted
* in ide.c and apply here as well:
@@ -425,7 +446,7 @@
* sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
*/
-#define IDETAPE_VERSION "1.17c"
+#define IDETAPE_VERSION "1.18"
#include <linux/config.h>
#include <linux/module.h>
@@ -653,8 +674,13 @@
/*
* Some tape drives require a long irq timeout
+ *
+ * Some drives (for example, the Seagate STT3401A Travan)
+ * require a very long timeout, because they don't
+ * return an interrupt or clear their busy bit until after the
+ * command completes--even retension commands.
*/
-#define IDETAPE_WAIT_CMD (60*HZ)
+#define IDETAPE_WAIT_CMD (900*HZ)
/*
* The following parameter is used to select the point in the internal
@@ -1040,6 +1066,8 @@
/* the door is currently locked */
int door_locked;
+ /* the tape is write protected */
+ int drv_write_prot;
/*
* OnStream flags
@@ -1172,7 +1200,9 @@
#define IDETAPE_DRQ_INTERRUPT 6 /* DRQ interrupt device */
#define IDETAPE_READ_ERROR 7
#define IDETAPE_PIPELINE_ACTIVE 8 /* pipeline active */
-
+#define IDETAPE_MEDIUM_PRESENT 9 /* 0=no tape loaded, so we don't rewind after ejecting */
+#define IDETAPE_WRITE_0_SUPPORTED 10 /* writes of length 0 supported by drive */
+#define IDETAPE_READ_0_SUPPORTED 11 /* reads of length 0 supported by drive */
/*
* Supported ATAPI tape drives packet commands
*/
@@ -1701,6 +1731,26 @@
idetape_update_buffers(pc);
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+ /* If error was the result of a zero-length read or write
+ * command, with sense key=5, asc=0x22, ascq=0, let it
+ * slide... some drives (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) {
+ pc->error = 0; /* don't report an error, everything's ok */
+ set_bit(PC_ABORT, &pc->flags); /* don't retry read/write */
+ if (pc->c[0] == IDETAPE_READ_CMD) {
+ clear_bit(IDETAPE_READ_0_SUPPORTED,&tape->flags);
+ } else {
+ clear_bit(IDETAPE_WRITE_0_SUPPORTED,&tape->flags);
+ }
+ }
+ }
+
if (pc->c[0] == IDETAPE_READ_CMD && result->filemark) {
pc->error = IDETAPE_ERROR_FILEMARK;
set_bit(PC_ABORT, &pc->flags);
@@ -1844,10 +1893,18 @@
}
}
-static void idetape_abort_pipeline (ide_drive_t *drive, idetape_stage_t *last_stage)
+/*
+ * idetape_abort_pipeline
+ * ----------------------
+ * This will free all the pipeline stages starting from
+ * new_last_stage->next to the end of the list, and point
+ * tape->last_stage to new_last_stage.
+ */
+
+static void idetape_abort_pipeline (ide_drive_t *drive, idetape_stage_t *new_last_stage)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_stage_t *stage = tape->next_stage;
+ idetape_stage_t *stage = new_last_stage->next;
idetape_stage_t *nstage;
#if IDETAPE_DEBUG_LOG
@@ -1862,9 +1919,9 @@
--tape->nr_pending_stages;
stage = nstage;
}
- tape->last_stage = last_stage;
- if (last_stage)
- last_stage->next = NULL;
+ if (new_last_stage)
+ new_last_stage->next = NULL;
+ tape->last_stage = new_last_stage;
tape->next_stage = NULL;
}
@@ -2492,7 +2548,11 @@
if (page_code != IDETAPE_BLOCK_DESCRIPTOR)
pc->c[1] = 8; /* DBD = 1 - Don't return block descriptors */
pc->c[2] = page_code;
- pc->c[3] = 255; /* Don't limit the returned information */
+ /* Changed pc->c[3] (subpages) to 0... 255 will at best return *
+ * unused info... for SCSI, this byte is defined as subpage *
+ * instead of high byte of length, and some IDE drives *
+ * seem to interpret it this way and return an error. */
+ pc->c[3] = 0; /* Don't limit the returned information */
pc->c[4] = 255; /* (We will just discard data in that case) */
if (page_code == IDETAPE_BLOCK_DESCRIPTOR)
pc->request_transfer = 12;
@@ -2609,11 +2669,11 @@
if (status.b.dsc) {
if (status.b.check) {
/* Error detected */
- printk(KERN_ERR "ide-tape: %s: I/O error: "
- "pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
- tape->name, pc->c[0],
- tape->sense_key, tape->asc, tape->ascq);
-
+ if (pc->c[0] != IDETAPE_TEST_UNIT_READY_CMD)
+ printk(KERN_ERR "ide-tape: %s: I/O error: "
+ "pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
+ tape->name, pc->c[0],
+ tape->sense_key, tape->asc, tape->ascq);
/* Retry operation */
return idetape_retry_pc(drive);
}
@@ -2749,38 +2809,6 @@
}
/*
- * This is our end_request replacement function.
- */
-static int idetape_do_end_request (ide_drive_t *drive, int uptodate)
-{
- struct request *rq;
- unsigned long flags;
- int ret = 1;
-
- spin_lock_irqsave(&io_request_lock, flags);
- rq = HWGROUP(drive)->rq;
-
- /*
- * decide whether to reenable DMA -- 3 is a random magic for now,
- * if we DMA timeout more than 3 times, just stay in PIO
- */
- if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
- drive->state = 0;
- HWGROUP(drive)->hwif->ide_dma_on(drive);
- }
-
- if (!end_that_request_first(rq, uptodate, drive->name)) {
- add_blkdev_randomness(MAJOR(rq->rq_dev));
- blkdev_dequeue_request(rq);
- HWGROUP(drive)->rq = NULL;
- end_that_request_last(rq);
- ret = 0;
- }
- spin_unlock_irqrestore(&io_request_lock, flags);
- return ret;
-}
-
-/*
* idetape_do_request is our request handling function.
*/
static ide_startstop_t idetape_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
@@ -2807,7 +2835,7 @@
*/
printk(KERN_NOTICE "ide-tape: %s: Unsupported command in "
"request queue (%d)\n", drive->name, rq->cmd);
- idetape_do_end_request(drive, 0);
+ ide_end_request(drive, 0);
return ide_stopped;
}
@@ -3406,29 +3434,31 @@
pc->callback = &idetape_pc_callback;
}
-static int idetape_wait_ready (ide_drive_t *drive, unsigned long long timeout)
+static int idetape_wait_ready (ide_drive_t *drive, unsigned long timeout)
{
idetape_tape_t *tape = drive->driver_data;
idetape_pc_t pc;
-
+ int load_attempted = 0;
/*
* Wait for the tape to become ready
*/
+ set_bit(IDETAPE_MEDIUM_PRESENT,&tape->flags);
timeout += jiffies;
while (time_before(jiffies, timeout)) {
idetape_create_test_unit_ready_cmd(&pc);
- if (!__idetape_queue_pc_tail(drive, &pc))
+ if (!__idetape_queue_pc_tail(drive, &pc)) {
return 0;
- if (tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) {
- idetape_create_load_unload_cmd(drive, &pc, IDETAPE_LU_LOAD_MASK);
- __idetape_queue_pc_tail(drive, &pc);
- idetape_create_test_unit_ready_cmd(&pc);
- if (!__idetape_queue_pc_tail(drive, &pc))
- return 0;
}
- if (!(tape->sense_key == 2 && tape->asc == 4 &&
- (tape->ascq == 1 || tape->ascq == 8)))
- break;
+ if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2)
+ || (tape->asc == 0x3A)) { /* no media... */
+ if (!load_attempted) {
+ idetape_create_load_unload_cmd(drive, &pc, IDETAPE_LU_LOAD_MASK);
+ __idetape_queue_pc_tail(drive, &pc);
+ load_attempted = 1;
+ } else return -ENOMEDIUM;
+ } else if (!(tape->sense_key == 2 && tape->asc == 4 &&
+ (tape->ascq == 1 || tape->ascq == 8))) /* not about to be ready... */
+ return -EIO;
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ / 10);
}
@@ -3536,6 +3566,8 @@
if (tape->chrdev_direction != idetape_direction_read)
return 0;
+
+ /* Remove merge_stage */
cnt = tape->merge_stage_size / tape->tape_block_size;
if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags))
++cnt; /* Filemarks count as 1 sector */
@@ -3544,12 +3576,14 @@
__idetape_kfree_stage(tape->merge_stage);
tape->merge_stage = NULL;
}
+
+ /* Clear pipeline flags */
clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
tape->chrdev_direction = idetape_direction_none;
+ /* Remove pipeline stages */
if (tape->first_stage == NULL)
return 0;
-
spin_lock_irqsave(&tape->spinlock, flags);
tape->next_stage = NULL;
if (idetape_pipeline_active(tape))
@@ -4183,13 +4215,18 @@
* Issue a read 0 command to ensure that DSC handshake
* is switched from completion mode to buffer available
* mode.
+ * No point in issuing this if dsc_overlap isn't supported
+ * (some drives will return an error).
*/
- bytes_read = idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 0, tape->merge_stage->bh);
- if (bytes_read < 0) {
- __idetape_kfree_stage(tape->merge_stage);
- tape->merge_stage = NULL;
- tape->chrdev_direction = idetape_direction_none;
- return bytes_read;
+ if (drive->dsc_overlap &&
+ test_bit(IDETAPE_READ_0_SUPPORTED,&tape->flags)) {
+ bytes_read = idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 0, tape->merge_stage->bh);
+ if (bytes_read < 0) {
+ __idetape_kfree_stage(tape->merge_stage);
+ tape->merge_stage = NULL;
+ tape->chrdev_direction = idetape_direction_none;
+ return bytes_read;
+ }
}
}
if (tape->restart_speed_control_req)
@@ -4230,7 +4267,7 @@
idetape_tape_t *tape = drive->driver_data;
unsigned long flags;
int cnt = 0, x, position;
-
+
/*
* Search and wait for the next logical tape block
*/
@@ -5083,6 +5119,11 @@
return -ENXIO;
}
+ if (tape->drv_write_prot) {
+ /* The drive is write protected. */
+ return -EACCES;
+ }
+
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 3)
printk (KERN_INFO "ide-tape: Reached idetape_chrdev_write, count %Zd\n", count);
@@ -5157,13 +5198,18 @@
* Issue a write 0 command to ensure that DSC handshake
* is switched from completion mode to buffer available
* mode.
+ * No point in issuing this if dsc_overlap isn't supported
+ * (some drives will return an error).
*/
- retval = idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 0, tape->merge_stage->bh);
- if (retval < 0) {
- __idetape_kfree_stage(tape->merge_stage);
- tape->merge_stage = NULL;
- tape->chrdev_direction = idetape_direction_none;
- return retval;
+ if (drive->dsc_overlap &&
+ test_bit(IDETAPE_WRITE_0_SUPPORTED,&tape->flags)) {
+ retval = idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 0, tape->merge_stage->bh);
+ if (retval < 0) {
+ __idetape_kfree_stage(tape->merge_stage);
+ tape->merge_stage = NULL;
+ tape->chrdev_direction = idetape_direction_none;
+ return retval;
+ }
}
#if ONSTREAM_DEBUG
if (tape->debug_level >= 2)
@@ -5318,7 +5364,7 @@
* Note:
*
* MTBSF and MTBSFM are not supported when the tape doesn't
- * supports spacing over filemarks in the reverse direction.
+ * support spacing over filemarks in the reverse direction.
* In this case, MTFSFM is also usually not supported (it is
* supported in the rare case in which we crossed the filemark
* during our read-ahead pipelined operation mode).
@@ -5388,6 +5434,8 @@
}
switch (mt_op) {
case MTWEOF:
+ if (tape->drv_write_prot)
+ return (-EACCES);
idetape_discard_read_pipeline(drive, 1);
for (i = 0; i < mt_count; i++) {
retval = idetape_write_filemark(drive);
@@ -5408,8 +5456,16 @@
case MTUNLOAD:
case MTOFFL:
idetape_discard_read_pipeline(drive, 0);
+ /* if door is locked, attempt to unlock */
+ /* before 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;
idetape_create_load_unload_cmd(drive, &pc,!IDETAPE_LU_LOAD_MASK);
- return (idetape_queue_pc_tail(drive, &pc));
+ if (!(retval= idetape_queue_pc_tail(drive, &pc)))
+ clear_bit(IDETAPE_MEDIUM_PRESENT,&tape->flags);
+ return retval;
case MTNOP:
idetape_discard_read_pipeline(drive, 0);
return (idetape_flush_tape_buffers(drive));
@@ -5577,12 +5633,15 @@
mtget.mt_blkno = tape->logical_blk_num;
}
mtget.mt_dsreg = ((tape->tape_block_size * tape->user_bs_factor) << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK;
+ mtget.mt_gstat = 0;
if (tape->onstream) {
mtget.mt_gstat |= GMT_ONLINE(0xffffffff);
if (tape->first_stage && tape->first_stage->aux->frame_type == OS_FRAME_TYPE_EOD)
mtget.mt_gstat |= GMT_EOD(0xffffffff);
if (position <= OS_DATA_STARTFRAME1)
mtget.mt_gstat |= GMT_BOT(0xffffffff);
+ } else {
+ if (tape->drv_write_prot) mtget.mt_gstat |= GMT_WR_PROT(0xffffffff);
}
if (copy_to_user ((char *) arg,(char *) &mtget, sizeof (struct mtget)))
return -EFAULT;
@@ -5703,6 +5762,8 @@
return 1;
}
+static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive);
+
/*
* Our character device open function.
*/
@@ -5712,6 +5773,7 @@
idetape_tape_t *tape;
idetape_pc_t pc;
unsigned int minor = MINOR(inode->i_rdev);
+ int retval;
#if IDETAPE_DEBUG_LOG
printk (KERN_INFO "ide-tape: Reached idetape_chrdev_open\n");
@@ -5724,11 +5786,9 @@
if (test_and_set_bit(IDETAPE_BUSY, &tape->flags))
return -EBUSY;
MOD_INC_USE_COUNT;
- if (!tape->onstream) {
- idetape_read_position(drive);
- if (!test_bit(IDETAPE_ADDRESS_VALID, &tape->flags))
- (void) idetape_rewind_tape(drive);
- } else {
+
+ /* Initialize some onstream stuff */
+ if (tape->onstream) {
if (minor & 64) {
tape->tape_block_size = tape->stage_size = 32768 + 512;
tape->raw = 1;
@@ -5738,18 +5798,42 @@
}
idetape_onstream_mode_sense_tape_parameter_page(drive, tape->debug_level);
}
- if (idetape_wait_ready(drive, 60 * HZ)) {
+
+ /* See if the drive is ready to go */
+ if ((retval = idetape_wait_ready(drive, 60 * HZ))) {
clear_bit(IDETAPE_BUSY, &tape->flags);
printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
MOD_DEC_USE_COUNT;
- return -EBUSY;
+ return retval;
}
- if (tape->onstream)
- idetape_read_position(drive);
- MOD_DEC_USE_COUNT;
+
+ /* Read the tape position */
+ idetape_read_position(drive);
+ if (!test_bit(IDETAPE_ADDRESS_VALID, &tape->flags))
+ (void) idetape_rewind_tape(drive);
+
+ MOD_DEC_USE_COUNT;
+
if (tape->chrdev_direction != idetape_direction_read)
clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
+ /* Read block size and write protect status from drive */
+ idetape_get_blocksize_from_block_descriptor(drive);
+
+ /* Make sure drive isn't write protected if user wants to write */
+ if (tape->drv_write_prot)
+ if ( (filp->f_flags & O_ACCMODE)==O_WRONLY ||
+ (filp->f_flags & O_ACCMODE)==O_RDWR) {
+ clear_bit(IDETAPE_BUSY, &tape->flags);
+ return -EROFS;
+ }
+
+ /* Set write protect flag if device is opened as read-only */
+ if ( (filp->f_flags & O_ACCMODE)==O_RDONLY)
+ tape->drv_write_prot == 1;
+
+ /* Lock the tape drive door so user can't eject */
+ /* (and analyze headers for Onstream drives) */
if (tape->chrdev_direction == idetape_direction_none) {
MOD_INC_USE_COUNT;
if (idetape_create_prevent_cmd(drive, &pc, 1)) {
@@ -5818,7 +5902,7 @@
__idetape_kfree_stage(tape->cache_stage);
tape->cache_stage = NULL;
}
- if (minor < 128)
+ if ((minor < 128) && (test_bit(IDETAPE_MEDIUM_PRESENT,&tape->flags)))
(void) idetape_rewind_tape(drive);
if (tape->chrdev_direction == idetape_direction_none) {
if (tape->door_locked == DOOR_LOCKED) {
@@ -6239,6 +6323,8 @@
header = (idetape_mode_parameter_header_t *) pc.buffer;
block_descrp = (idetape_parameter_block_descriptor_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t));
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 */
@@ -6322,6 +6408,9 @@
tape->max_insert_speed = 10000;
tape->speed_control = 1;
*((unsigned short *) &gcw) = drive->id->config;
+ /* For now, assume drive supports read/writes of 0 length */
+ set_bit(IDETAPE_READ_0_SUPPORTED,&tape->flags);
+ set_bit(IDETAPE_WRITE_0_SUPPORTED,&tape->flags);
if (gcw.drq_type == 1)
set_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags);
____________________________________________________________
Enter for a chance to win one year's supply of allergy relief!
http://r.hotbot.com/r/lmt_clrtn/http://mocda3.com/1/c/563632/125699/307982/307982
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] (for ide-tape.c in 2.4.22-ac4) ide-tape.c doesn't work with Seagate Trav
2003-10-21 22:21 [PATCH] (for ide-tape.c in 2.4.22-ac4) ide-tape.c doesn't work with Seagate Trav stuart hayes
@ 2003-10-22 22:15 ` Bartlomiej Zolnierkiewicz
2003-10-23 18:59 ` Stuart Hayes
0 siblings, 1 reply; 4+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2003-10-22 22:15 UTC (permalink / raw)
To: stuart_hayes; +Cc: linux-ide
Patch looks really good, only some minor issues.
> @@ -316,6 +316,27 @@
> * Ver 1.17c Sep 2003 Stuart Hayes <stuart_hayes@dell.com>
> * Initialized "feature" in idetape_issue_packet_command
> * (this was causing lockups on certain systems)
> + * Ver 1.18 Sep 2003 Stuart Hayes <stuart_hayes@dell.com>
> + * Check drive's write protect bit, try to return appropriate
> + * errors when attempting to write a write-protected tape
> + * Moved "idetape_read_position" call in idetape_chrdev_open
> + * after the "wait_ready" call
> + * Added IDETAPE_MEDIUM_PRESENT flag so driver would know
> + * not to rewind tape after ejecting it
> + * Fixed bug with ide_abort_pipeline (it was deleting stages
> + * from tape->next_stage to end, instead of from
> + * new_last_stage->next (tape->next_stage was set to NULL
> + * by idetape_discard_read_pipeline before calling!)
> + * Deleted "idetape_do_end_request"--this was just a copy of
> + * ide_end_request
> + * Made improvements to idetape_wait_ready
> + * Added a few comments here and there
> + * Made MTOFFL unlock tape drive door before attempting to eject
> + * Added fixes to get Seagate STT3401A Travan working:
> + * handle drives that don't support 0-length reads/writes
> + * increased timeout (retension takes ~10 minutes before
> + * irq is returned)
> + * fixed request mode page packet command byte 3
> *
> * Here are some words from the first releases of hd.c, which are quoted
> * in ide.c and apply here as well:
Please make this a patch comment,
so when it is merged into -bk we have patch+changelog.
> @@ -4230,7 +4267,7 @@
> idetape_tape_t *tape = drive->driver_data;
> unsigned long flags;
> int cnt = 0, x, position;
> -
> +
> /*
> * Search and wait for the next logical tape block
> */
no need for extra tab
> @@ -5388,6 +5434,8 @@
> }
> switch (mt_op) {
> case MTWEOF:
> + if (tape->drv_write_prot)
> + return (-EACCES);
> idetape_discard_read_pipeline(drive, 1);
> for (i = 0; i < mt_count; i++) {
> retval = idetape_write_filemark(drive);
return -EACCES;
> @@ -6322,6 +6408,9 @@
> tape->max_insert_speed = 10000;
> tape->speed_control = 1;
> *((unsigned short *) &gcw) = drive->id->config;
> + /* For now, assume drive supports read/writes of 0 length */
> + set_bit(IDETAPE_READ_0_SUPPORTED,&tape->flags);
> + set_bit(IDETAPE_WRITE_0_SUPPORTED,&tape->flags);
> if (gcw.drq_type == 1)
> set_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags);
If my analysis is correct the only possibility of issuing READ or WRITE with
length 0 is when switching from DSC handshake from completion mode to buffer
available mode and these cases are now covered by drive->dsc_overlap check.
I guess Travan doesn't support DSC, so IDETAPE_{READ, WRITE}_0_SUPPORTED flags
can be removed unless you know about another tape drive which errors on zero
length READ/WRITE commands (we should leave comments about Travan of course).
Stuart, could you also forward-port these chances to 2.6.x and test them?
I don't have any ide-tape drive.
thanks,
--bartlomiej
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] (for ide-tape.c in 2.4.22-ac4) ide-tape.c doesn't work with Seagate Trav
2003-10-22 22:15 ` Bartlomiej Zolnierkiewicz
@ 2003-10-23 18:59 ` Stuart Hayes
2003-10-23 20:43 ` Bartlomiej Zolnierkiewicz
0 siblings, 1 reply; 4+ messages in thread
From: Stuart Hayes @ 2003-10-23 18:59 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide
On Wed, 22 Oct 2003, Bartlomiej Zolnierkiewicz wrote:
>
> Patch looks really good, only some minor issues.
>
> > @@ -316,6 +316,27 @@
> > * Ver 1.17c Sep 2003 Stuart Hayes <stuart_hayes@dell.com>
> > * Initialized "feature" in
> idetape_issue_packet_command
> > * (this was causing lockups on certain systems)
> > + * Ver 1.18 Sep 2003 Stuart Hayes <stuart_hayes@dell.com>
> > + * Check drive's write protect bit, try to return
> appropriate
> > + * errors when attempting to write a
> write-protected tape
> > + * Moved "idetape_read_position" call in
> idetape_chrdev_open
> > + * after the "wait_ready" call
> > + * Added IDETAPE_MEDIUM_PRESENT flag so driver would
> know
> > + * not to rewind tape after ejecting it
> > + * Fixed bug with ide_abort_pipeline (it was
> deleting stages
> > + * from tape->next_stage to end, instead of from
> > + * new_last_stage->next (tape->next_stage was set
> to NULL
> > + * by idetape_discard_read_pipeline before
> calling!)
> > + * Deleted "idetape_do_end_request"--this was just a
> copy of
> > + * ide_end_request
> > + * Made improvements to idetape_wait_ready
> > + * Added a few comments here and there
> > + * Made MTOFFL unlock tape drive door before
> attempting to eject
> > + * Added fixes to get Seagate STT3401A Travan
> working:
> > + * handle drives that don't support 0-length
> reads/writes
> > + * increased timeout (retension takes ~10 minutes
> before
> > + * irq is returned)
> > + * fixed request mode page packet command byte 3
> > *
> > * Here are some words from the first releases of hd.c, which are
> quoted
> > * in ide.c and apply here as well:
>
> Please make this a patch comment,
> so when it is merged into -bk we have patch+changelog.
>
> > @@ -4230,7 +4267,7 @@
> > idetape_tape_t *tape = drive->driver_data;
> > unsigned long flags;
> > int cnt = 0, x, position;
> > -
> > +
> > /*
> > * Search and wait for the next logical tape block
> > */
>
> no need for extra tab
>
> > @@ -5388,6 +5434,8 @@
> > }
> > switch (mt_op) {
> > case MTWEOF:
> > + if (tape->drv_write_prot)
> > + return (-EACCES);
> > idetape_discard_read_pipeline(drive, 1);
> > for (i = 0; i < mt_count; i++) {
> > retval = idetape_write_filemark(drive);
>
> return -EACCES;
>
> > @@ -6322,6 +6408,9 @@
> > tape->max_insert_speed = 10000;
> > tape->speed_control = 1;
> > *((unsigned short *) &gcw) = drive->id->config;
> > + /* For now, assume drive supports read/writes of 0 length */
> > + set_bit(IDETAPE_READ_0_SUPPORTED,&tape->flags);
> > + set_bit(IDETAPE_WRITE_0_SUPPORTED,&tape->flags);
> > if (gcw.drq_type == 1)
> > set_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags);
>
> If my analysis is correct the only possibility of issuing READ or WRITE
> with
> length 0 is when switching from DSC handshake from completion mode to
> buffer
> available mode and these cases are now covered by drive->dsc_overlap
> check.
>
> I guess Travan doesn't support DSC, so IDETAPE_{READ, WRITE}_0_SUPPORTED
> flags
> can be removed unless you know about another tape drive which errors on
> zero
> length READ/WRITE commands (we should leave comments about Travan of
> course).
>
>
> Stuart, could you also forward-port these chances to 2.6.x and test them?
> I don't have any ide-tape drive.
>
> thanks,
> --bartlomiej
>
>
>
Right now the dsc_overlap flag isn't set for this (or any) drive--it's
only set for a couple of controllers that don't support DSC at all. I
thought it would be better to fail gracefully (and not try 0-length reads
or writes anymore) if the drive can't handle them, rather than to just clear
dsc_overlap for a particular drive. If you don't agree I can change
that to get rid of the flags.
I can do this for 2.6, too, but it may be a few days before I get a chance
to do so.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] (for ide-tape.c in 2.4.22-ac4) ide-tape.c doesn't work with Seagate Trav
2003-10-23 18:59 ` Stuart Hayes
@ 2003-10-23 20:43 ` Bartlomiej Zolnierkiewicz
0 siblings, 0 replies; 4+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2003-10-23 20:43 UTC (permalink / raw)
To: Stuart Hayes; +Cc: linux-ide
On Thursday 23 of October 2003 20:59, Stuart Hayes wrote:
> On Wed, 22 Oct 2003, Bartlomiej Zolnierkiewicz wrote:
> > Patch looks really good, only some minor issues.
> >
> > > @@ -316,6 +316,27 @@
> > > * Ver 1.17c Sep 2003 Stuart Hayes <stuart_hayes@dell.com>
> > > * Initialized "feature" in
> >
> > idetape_issue_packet_command
> >
> > > * (this was causing lockups on certain systems)
> > > + * Ver 1.18 Sep 2003 Stuart Hayes <stuart_hayes@dell.com>
> > > + * Check drive's write protect bit, try to return
> >
> > appropriate
> >
> > > + * errors when attempting to write a
> >
> > write-protected tape
> >
> > > + * Moved "idetape_read_position" call in
> >
> > idetape_chrdev_open
> >
> > > + * after the "wait_ready" call
> > > + * Added IDETAPE_MEDIUM_PRESENT flag so driver would
> >
> > know
> >
> > > + * not to rewind tape after ejecting it
> > > + * Fixed bug with ide_abort_pipeline (it was
> >
> > deleting stages
> >
> > > + * from tape->next_stage to end, instead of from
> > > + * new_last_stage->next (tape->next_stage was set
> >
> > to NULL
> >
> > > + * by idetape_discard_read_pipeline before
> >
> > calling!)
> >
> > > + * Deleted "idetape_do_end_request"--this was just a
> >
> > copy of
> >
> > > + * ide_end_request
> > > + * Made improvements to idetape_wait_ready
> > > + * Added a few comments here and there
> > > + * Made MTOFFL unlock tape drive door before
> >
> > attempting to eject
> >
> > > + * Added fixes to get Seagate STT3401A Travan
> >
> > working:
> > > + * handle drives that don't support 0-length
> >
> > reads/writes
> >
> > > + * increased timeout (retension takes ~10 minutes
> >
> > before
> >
> > > + * irq is returned)
> > > + * fixed request mode page packet command byte 3
> > > *
> > > * Here are some words from the first releases of hd.c, which are
> >
> > quoted
> >
> > > * in ide.c and apply here as well:
> >
> > Please make this a patch comment,
> > so when it is merged into -bk we have patch+changelog.
> >
> > > @@ -4230,7 +4267,7 @@
> > > idetape_tape_t *tape = drive->driver_data;
> > > unsigned long flags;
> > > int cnt = 0, x, position;
> > > -
> > > +
> > > /*
> > > * Search and wait for the next logical tape block
> > > */
> >
> > no need for extra tab
> >
> > > @@ -5388,6 +5434,8 @@
> > > }
> > > switch (mt_op) {
> > > case MTWEOF:
> > > + if (tape->drv_write_prot)
> > > + return (-EACCES);
> > > idetape_discard_read_pipeline(drive, 1);
> > > for (i = 0; i < mt_count; i++) {
> > > retval = idetape_write_filemark(drive);
> >
> > return -EACCES;
> >
> > > @@ -6322,6 +6408,9 @@
> > > tape->max_insert_speed = 10000;
> > > tape->speed_control = 1;
> > > *((unsigned short *) &gcw) = drive->id->config;
> > > + /* For now, assume drive supports read/writes of 0 length */
> > > + set_bit(IDETAPE_READ_0_SUPPORTED,&tape->flags);
> > > + set_bit(IDETAPE_WRITE_0_SUPPORTED,&tape->flags);
> > > if (gcw.drq_type == 1)
> > > set_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags);
> >
> > If my analysis is correct the only possibility of issuing READ or WRITE
> > with
> > length 0 is when switching from DSC handshake from completion mode to
> > buffer
> > available mode and these cases are now covered by drive->dsc_overlap
> > check.
> >
> > I guess Travan doesn't support DSC, so IDETAPE_{READ, WRITE}_0_SUPPORTED
> > flags
> > can be removed unless you know about another tape drive which errors on
> > zero
> > length READ/WRITE commands (we should leave comments about Travan of
> > course).
> >
> >
> > Stuart, could you also forward-port these chances to 2.6.x and test them?
> > I don't have any ide-tape drive.
> >
> > thanks,
> > --bartlomiej
>
> Right now the dsc_overlap flag isn't set for this (or any) drive--it's
> only set for a couple of controllers that don't support DSC at all. I
I've just checked idetape_setup() and it's quite opposite,
drive->dsc_overlap is set for every drive, except if drive is on
controller which is known not to support DSC.
> thought it would be better to fail gracefully (and not try 0-length reads
> or writes anymore) if the drive can't handle them, rather than to just
> clear dsc_overlap for a particular drive. If you don't agree I can change
> that to get rid of the flags.
If drive->dsc_overlap flag is not set there is no possibility of issuing
0-length read/write. I think that sufficient fix for now is not to set
drive->dsc_overlap for this particular drive. However we should leave
comment in a driver about this problem (0-length reads/writes) and solution,
so if in future somebody decides to change driver interworkings, she/he won't
break support for Travan.
> I can do this for 2.6, too, but it may be a few days before I get a chance
> to do so.
Great.
thanks,
--bartlomiej
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2003-10-23 20:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-10-21 22:21 [PATCH] (for ide-tape.c in 2.4.22-ac4) ide-tape.c doesn't work with Seagate Trav stuart hayes
2003-10-22 22:15 ` Bartlomiej Zolnierkiewicz
2003-10-23 18:59 ` Stuart Hayes
2003-10-23 20:43 ` Bartlomiej Zolnierkiewicz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).