(for ide-tape.c in 2.4.22-ac4) ide-tape.c doesn't work with Seagate Trav
PATCH 1/1 (for ide-tape.c in 2.4.22-ac4) ide-tape.c doesn't work with Seagate Trav
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 [email protected] (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-sgfix-try11.c renamed from ide-tape.c.rc2 +181 -87
@@ -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 <[email protected]> *
@@ -316,6 +316,27 @@* Ver 1.17c Sep 2003 Stuart Hayes <[email protected]> * Initialized "feature" in idetape_issue_packet_command * (this was causing lockups on certain systems) +* Ver 1.18 Sep 2003 Stuart Hayes <[email protected]> +* 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
Patch looks really good, only some minor issues.
Quoted 18 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +14
-0@@ -316,6 +316,27 @@* Ver 1.17c Sep 2003 Stuart Hayes <[email protected]> * Initialized "feature" in idetape_issue_packet_command * (this was causing lockups on certain systems) +* Ver 1.18 Sep 2003 Stuart Hayes <[email protected]> +* 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
ide-tape-sgfix-try11.c line 342
Quoted 10 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +7
-0+* 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.
ide-tape-sgfix-try11.c line 4273
Quoted 9 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +1
-1@@ -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
ide-tape-sgfix-try11.c line 5441
Quoted 9 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +2
-0@@ -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;
ide-tape-sgfix-try11.c line 6415
Quoted 9 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +3
-0@@ -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
Quoted 98 lines · Bartlomiej Zolnierkiewicz
Patch looks really good, only some minor issues.
Review line 317
Quoted 3 lines
(quoted diff) +0
-0@@ -316,6 +316,27 @@ * Ver 1.17c Sep 2003 Stuart Hayes <[email protected]> * Initialized "feature" in
idetape_issue_packet_commandide-tape-sgfix-try11.c
Quoted 3 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +2
-0* (this was causing lockups on certain systems) + * Ver 1.18 Sep 2003 Stuart Hayes <[email protected]> + * Check drive's write protect bit, try to returnappropriate
Review line 321
Quoted 1 line
(quoted diff) +1
-0+ * errors when attempting to write awrite-protected tape
Review line 322
Quoted 1 line
(quoted diff) +1
-0+ * Moved "idetape_read_position" call in
idetape_chrdev_openReview line 324
Quoted 2 lines
(quoted diff) +2
-0+ * after the "wait_ready" call + * Added IDETAPE_MEDIUM_PRESENT flag so driver wouldknow
Review line 326
Quoted 2 lines
(quoted diff) +2
-0+ * not to rewind tape after ejecting it + * Fixed bug with ide_abort_pipeline (it wasdeleting stages
Review line 328
Quoted 2 lines
(quoted diff) +2
-0+ * from tape->next_stage to end, instead of from + * new_last_stage->next (tape->next_stage was setto NULL
Review line 329
Quoted 1 line
(quoted diff) +1
-0+ * by idetape_discard_read_pipeline beforecalling!)
Review line 330
Quoted 1 line
(quoted diff) +1
-0+ * Deleted "idetape_do_end_request"--this was just acopy of
ide-tape-sgfix-try11.c
Quoted 4 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +4
-0+ * ide_end_request + * Made improvements to idetape_wait_ready + * Added a few comments here and there + * Made MTOFFL unlock tape drive door beforeattempting to eject
Review line 335
Quoted 1 line
(quoted diff) +1
-0+ * Added fixes to get Seagate STT3401A Travanworking:
Review line 336
Quoted 1 line
(quoted diff) +1
-0+ * handle drives that don't support 0-lengthreads/writes
Review line 337
Quoted 1 line
(quoted diff) +1
-0+ * increased timeout (retension takes ~10 minutesbefore
ide-tape-sgfix-try11.c
Quoted 4 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +2
-0+ * irq is returned) + * fixed request mode page packet command byte 3 * * Here are some words from the first releases of hd.c, which arequoted
ide-tape-sgfix-try11.c line 342
Quoted 1 line
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +0
-0* 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.ide-tape-sgfix-try11.c line 4273
Quoted 9 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +1
-1@@ -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
Quoted 9 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +0
-0@@ -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;ide-tape-sgfix-try11.c line 6415
Quoted 9 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +3
-0@@ -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 bydrive->dsc_overlapcheck.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).
Quoted 8 lines
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.
Quoted 125 lines · Stuart Hayes
Quoted 124 lines · Bartlomiej Zolnierkiewicz
Patch looks really good, only some minor issues.
Review line 317
Quoted 3 lines
(quoted diff) +0
-0@@ -316,6 +316,27 @@ * Ver 1.17c Sep 2003 Stuart Hayes <[email protected]> * Initialized "feature" in
idetape_issue_packet_commandide-tape-sgfix-try11.c
Quoted 3 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +2
-0* (this was causing lockups on certain systems) +* Ver 1.18 Sep 2003 Stuart Hayes <[email protected]> +* Check drive's write protect bit, try to return appropriate
Review line 321
Quoted 1 line
(quoted diff) +1
-0+ * errors when attempting to write awrite-protected tape
Review line 322
Quoted 1 line
(quoted diff) +1
-0+ * Moved "idetape_read_position" call in
idetape_chrdev_openReview line 324
Quoted 2 lines
(quoted diff) +2
-0+ * after the "wait_ready" call + * Added IDETAPE_MEDIUM_PRESENT flag so driver wouldknow
Review line 326
Quoted 2 lines
(quoted diff) +2
-0+ * not to rewind tape after ejecting it + * Fixed bug with ide_abort_pipeline (it wasdeleting stages
Review line 328
Quoted 2 lines
(quoted diff) +2
-0+ * from tape->next_stage to end, instead of from + * new_last_stage->next (tape->next_stage was setto NULL
Review line 329
Quoted 1 line
(quoted diff) +1
-0+ * by idetape_discard_read_pipeline beforecalling!)
Review line 330
Quoted 1 line
(quoted diff) +1
-0+ * Deleted "idetape_do_end_request"--this was just acopy of
ide-tape-sgfix-try11.c
Quoted 4 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +4
-0+* 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
Review line 335
Quoted 1 line
(quoted diff) +1
-0+ * Added fixes to get Seagate STT3401A Travanworking:
Review line 336
Quoted 1 line
(quoted diff) +1
-0+ * handle drives that don't support 0-lengthreads/writes
Review line 337
Quoted 1 line
(quoted diff) +1
-0+ * increased timeout (retension takes ~10 minutesbefore
ide-tape-sgfix-try11.c
Quoted 4 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +2
-0+* 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
ide-tape-sgfix-try11.c line 342
Quoted 1 line
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +0
-0* 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.ide-tape-sgfix-try11.c line 4273
Quoted 9 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +1
-1@@ -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
ide-tape-sgfix-try11.c line 5441
Quoted 9 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +2
-0@@ -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;ide-tape-sgfix-try11.c line 6415
Quoted 9 lines
ide-tape-sgfix-try11.c renamed from ide-tape.c.rc2 +3
-0@@ -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 bydrive->dsc_overlapcheck.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).
Quoted 8 lines
Quoted 5 lines
Stuart, could you also forward-port these chances to 2.6.x and test them? I don't have any ide-tape drive.
thanks,
--bartlomiejRight now the
dsc_overlapflag 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.
Quoted 4 lines
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_overlapfor 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.
Quoted 2 lines
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