diff options
-rw-r--r-- | winsup/cygwin/ChangeLog | 33 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 6 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_tape.cc | 126 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/mtio.h | 6 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 3 |
5 files changed, 109 insertions, 65 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 2941cd3e0..a6eccbdcd 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,32 @@ +2004-03-15 Corinna Vinschen <corinna@vinschen.de> + + * fhandler.h (fhandler_dev_tape::tape_get_pos): Declare with extra + parameter for partition number. + (fhandler_dev_tape::_tape_set_pos): Ditto. + (fhandler_dev_tape::tape_partition): New method. + (fhandler_dev_tape::tape_set_partition): New method. + * fhandler_tape.cc (fhandler_dev_tape::open): Call private methods + directly instead of ioctl. + (fhandler_dev_tape::ioctl): Use long erase on MTERASE by default. + Don't use absolute positioning on MTSEEK. Call tape_set_partition + on MTSETPART, tape_partition on MTMKPART. + (fhandler_dev_tape::tape_get_pos): Add partition number parameter. + Prefer logical position information over absolute position information. + Return partition number. + (fhandler_dev_tape::_tape_set_pos): Add partition number parameter. + Use in SetTapePosition. + (fhandler_dev_tape::tape_set_pos): Remove special TAPE_ABSOLUTE_BLOCK + handling. + (fhandler_dev_tape::tape_erase): Rewind before erasing. + (fhandler_dev_tape::tape_status): Rearrange slightly. Try to get a + MediaType even if no tape is loaded. Store active partition in + mt_resid as on Linux. + (fhandler_dev_tape::tape_partition): New method. + (fhandler_dev_tape::tape_set_partition): New method. + * include/cygwin/mtio.h: Fix copyright. Add comment to explain + mt_resid content. + * include/cygwin/version.h: Bump API minor number. + 2004-03-14 Christopher Faylor <cgf@redhat.com> * cygtls.cc (_cygtls::remove): Call remove_wq even when we can't @@ -8,7 +37,7 @@ (proc_terminate): Don't NULL sync_proc_subproc since other threads may still try to access it. -2004-03-12 Corinna Vinschen <corinna@vinschen.de> +2004-03-14 Corinna Vinschen <corinna@vinschen.de> * errno.cc (errmap): Map ERROR_BEGINNING_OF_MEDIA and ERROR_SETMARK_DETECTED to EIO instead of ESPIPE. @@ -46,7 +75,7 @@ * spawn.cc (spawn_guts): Return -1 when wait() fails for spawn types that require waiting. -2004-03-12 Corinna Vinschen <corinna@vinschen.de> +2004-03-13 Corinna Vinschen <corinna@vinschen.de> * errno.cc (errmap): Handle ERROR_BUS_RESET. * fhandler.h (fhandler_dev_raw::write_file): New method, created diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index dbbac2c12..9d3a56ac0 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -607,14 +607,16 @@ class fhandler_dev_tape: public fhandler_dev_raw } int tape_error (const char *txt); int tape_write_marks (int marktype, DWORD len); - int tape_get_pos (unsigned long *ret); + int tape_get_pos (unsigned long *block, unsigned long *partition = NULL); int tape_set_pos (int mode, long count, bool sfm_func = false); - int _tape_set_pos (int mode, long count); + int _tape_set_pos (int mode, long count, int partition = 0); int tape_erase (int mode); int tape_prepare (int action); int tape_set_blocksize (long count); int tape_status (struct mtget *get); int tape_compression (long count); + int tape_partition (long count); + int tape_set_partition (long count); }; /* Standard disk file */ diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index 2fa5f433f..a99e4a2aa 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -124,15 +124,14 @@ fhandler_dev_tape::open (int flags, mode_t) ret = fhandler_dev_raw::open (flags); if (ret) { - struct mtget get; - struct mtop op; - struct mtpos pos; DWORD varlen; + struct mtget get; + unsigned long block; TAPE_FUNC (GetTapeParameters (get_handle (), GET_TAPE_DRIVE_INFORMATION, (varlen = sizeof dp, &varlen), &dp)); - if (!ioctl (MTIOCGET, &get)) + if (!tape_status (&get)) { long blksize = (get.mt_dsreg & MT_ST_BLKSIZE_MASK) >> MT_ST_BLKSIZE_SHIFT; @@ -152,19 +151,16 @@ fhandler_dev_tape::open (int flags, mode_t) * returns ERROR_NO_DATA_DETECTED. After media change, all subsequent * ReadFile calls return ERROR_NO_DATA_DETECTED, too. * The call to tape_set_pos seems to reset some internal flags. */ - if ((!ioctl (MTIOCPOS, &pos)) && (!pos.mt_blkno)) + if (!tape_get_pos (&block) && !block) { debug_printf ("rewinding"); - op.mt_op = MTREW; - ioctl (MTIOCTOP, &op); + tape_set_pos (TAPE_REWIND, 0); } if (flags & O_APPEND) { /* In append mode, seek to beginning of next filemark */ - op.mt_op = MTFSFM; - op.mt_count = 1; - ioctl (MTIOCTOP, &op); + tape_set_pos (TAPE_SPACE_FILEMARKS, 1, true); } } @@ -196,8 +192,7 @@ fhandler_dev_tape::close (void) if (is_rewind_device ()) { debug_printf ("rewinding"); - op.mt_op = MTREW; - ioctl (MTIOCTOP, &op); + tape_set_pos (TAPE_REWIND, 0); } if (ret) @@ -354,7 +349,7 @@ fhandler_dev_tape::ioctl (unsigned int cmd, void *buf) ret = tape_set_pos (TAPE_SPACE_FILEMARKS, 32767); break; case MTERASE: - ret = tape_erase (TAPE_ERASE_SHORT); + ret = tape_erase (TAPE_ERASE_LONG); break; case MTRAS1: case MTRAS2: @@ -417,9 +412,8 @@ fhandler_dev_tape::ioctl (unsigned int cmd, void *buf) reset_devbuf (); break; case MTSEEK: - if (tape_get_feature (TAPE_DRIVE_ABSOLUTE_BLK) - || tape_get_feature (TAPE_DRIVE_LOGICAL_BLK)) - ret = tape_set_pos (TAPE_ABSOLUTE_BLOCK, op->mt_count); + if (tape_get_feature (TAPE_DRIVE_LOGICAL_BLK)) + ret = tape_set_pos (TAPE_LOGICAL_BLOCK, op->mt_count); else if (!(ret = tape_get_pos (&block))) ret = tape_set_pos (TAPE_SPACE_RELATIVE_BLOCKS, op->mt_count - block); @@ -451,7 +445,13 @@ fhandler_dev_tape::ioctl (unsigned int cmd, void *buf) ret = tape_compression (op->mt_count); break; case MTSETPART: + ret = tape_set_partition (op->mt_count); + reset_devbuf (); + break; case MTMKPART: + ret = tape_partition (op->mt_count); + reset_devbuf (); + break; case MTSETDENSITY: case MTSETDRVBUFFER: reset_devbuf (); @@ -502,37 +502,34 @@ fhandler_dev_tape::tape_write_marks (int marktype, DWORD len) } int -fhandler_dev_tape::tape_get_pos (unsigned long *ret) +fhandler_dev_tape::tape_get_pos (unsigned long *block, + unsigned long *partition) { DWORD part, low, high; lasterr = ERROR_INVALID_PARAMETER; - if (tape_get_feature (TAPE_DRIVE_GET_ABSOLUTE_BLK)) - { - TAPE_FUNC (GetTapePosition (get_handle (), TAPE_ABSOLUTE_POSITION, - &part, &low, &high)); - /* Workaround bug in Tandberg SLR device driver, which pretends - to support reporting of absolute blocks but instead returns - ERROR_INVALID_FUNCTION. */ - if (lasterr != ERROR_INVALID_FUNCTION) - goto out; - dp.FeaturesLow &= ~TAPE_DRIVE_GET_ABSOLUTE_BLK; - } if (tape_get_feature (TAPE_DRIVE_GET_LOGICAL_BLK)) TAPE_FUNC (GetTapePosition (get_handle (), TAPE_LOGICAL_POSITION, &part, &low, &high)); + else if (tape_get_feature (TAPE_DRIVE_GET_ABSOLUTE_BLK)) + TAPE_FUNC (GetTapePosition (get_handle (), TAPE_ABSOLUTE_POSITION, + &part, &low, &high)); -out: - if (!tape_error ("tape_get_pos") && ret) - *ret = low; + if (!tape_error ("tape_get_pos")) + { + if (block) + *block = low; + if (partition) + *partition = part > 0 ? part - 1 : part; + } return lasterr; } int -fhandler_dev_tape::_tape_set_pos (int mode, long count) +fhandler_dev_tape::_tape_set_pos (int mode, long count, int partition) { - TAPE_FUNC (SetTapePosition (get_handle (), mode, 0, count, + TAPE_FUNC (SetTapePosition (get_handle (), mode, partition, count, count < 0 ? -1 : 0, FALSE)); /* Reset buffer after successful repositioning. */ if (!lasterr || IS_EOF (lasterr) || IS_EOM (lasterr)) @@ -557,10 +554,6 @@ fhandler_dev_tape::tape_set_pos (int mode, long count, bool sfm_func) return tape_error ("tape_set_pos"); } break; - case TAPE_ABSOLUTE_BLOCK: - if (!tape_get_feature (TAPE_DRIVE_ABSOLUTE_BLK)) - mode = TAPE_LOGICAL_BLOCK; - break; } _tape_set_pos (mode, count); switch (mode) @@ -569,17 +562,6 @@ fhandler_dev_tape::tape_set_pos (int mode, long count, bool sfm_func) if (!lasterr && sfm_func) return tape_set_pos (mode, count > 0 ? -1 : 1, false); break; - case TAPE_ABSOLUTE_BLOCK: - /* Workaround bug in Tandberg SLR device driver, which pretends - to support absolute block positioning but instead returns - ERROR_INVALID_FUNCTION. */ - if (lasterr == ERROR_INVALID_FUNCTION && mode == TAPE_ABSOLUTE_BLOCK) - { - dp.FeaturesHigh &= TAPE_DRIVE_HIGH_FEATURES - | ~TAPE_DRIVE_ABSOLUTE_BLK; - _tape_set_pos (TAPE_LOGICAL_BLOCK, count); - } - break; } return tape_error ("tape_set_pos"); } @@ -587,6 +569,8 @@ fhandler_dev_tape::tape_set_pos (int mode, long count, bool sfm_func) int fhandler_dev_tape::tape_erase (int mode) { + if (tape_set_pos (TAPE_REWIND, 0)) + return lasterr; switch (mode) { case TAPE_ERASE_SHORT: @@ -648,18 +632,13 @@ fhandler_dev_tape::tape_status (struct mtget *get) get->mt_type = MT_ISUNKNOWN; - if (!notape && tape_get_feature (TAPE_DRIVE_TAPE_REMAINING)) - { - get->mt_remaining = get_ll (mp.Remaining); - get->mt_resid = get->mt_remaining >> 10; - } - - if (tape_get_feature (TAPE_DRIVE_SET_BLOCK_SIZE) && !notape) + if (!notape && tape_get_feature (TAPE_DRIVE_SET_BLOCK_SIZE)) get->mt_dsreg = (mp.BlockSize << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK; else get->mt_dsreg = (dp.DefaultBlockSize << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK; + if (wincap.has_ioctl_storage_get_media_types_ex ()) { DWORD size = sizeof (GET_MEDIA_TYPES) + 10 * sizeof (DEVICE_MEDIA_INFO); @@ -672,6 +651,7 @@ fhandler_dev_tape::tape_status (struct mtget *get) for (DWORD i = 0; i < gmt->MediaInfoCount; ++i) { PDEVICE_MEDIA_INFO dmi = &gmt->MediaInfo[i]; + get->mt_type = dmi->DeviceSpecific.TapeInfo.MediaType; #define TINFO DeviceSpecific.TapeInfo if (dmi->TINFO.MediaCharacteristics & MEDIA_CURRENTLY_MOUNTED) { @@ -681,6 +661,7 @@ fhandler_dev_tape::tape_status (struct mtget *get) (dmi->TINFO.BusSpecificData.ScsiInformation.DensityCode << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK; + break; } #undef TINFO } @@ -691,9 +672,10 @@ fhandler_dev_tape::tape_status (struct mtget *get) if (!notape) { - if (tape_get_feature (TAPE_DRIVE_GET_ABSOLUTE_BLK) - || tape_get_feature (TAPE_DRIVE_GET_LOGICAL_BLK)) - tape_get_pos ((unsigned long *) &get->mt_blkno); + if (tape_get_feature (TAPE_DRIVE_GET_LOGICAL_BLK) + || tape_get_feature (TAPE_DRIVE_GET_ABSOLUTE_BLK)) + tape_get_pos ((unsigned long *) &get->mt_blkno, + (unsigned long *) &get->mt_resid); if (!get->mt_blkno) get->mt_gstat |= GMT_BOT (-1); @@ -705,6 +687,9 @@ fhandler_dev_tape::tape_status (struct mtget *get) if (tape_get_feature (TAPE_DRIVE_TAPE_CAPACITY)) get->mt_capacity = get_ll (mp.Capacity); + + if (tape_get_feature (TAPE_DRIVE_TAPE_REMAINING)) + get->mt_remaining = get_ll (mp.Remaining); } if (tape_get_feature (TAPE_DRIVE_COMPRESSION) && dp.Compression) @@ -751,3 +736,28 @@ fhandler_dev_tape::tape_compression (long count) return tape_error ("tape_compression"); } +int +fhandler_dev_tape::tape_partition (long count) +{ + if (dp.MaximumPartitionCount <= 1) + return ERROR_INVALID_PARAMETER; + if (tape_set_pos (TAPE_REWIND, 0)) + return lasterr; + if (count <= 0) + debug_printf ("Formatting tape with one partition"); + else + debug_printf ("Formatting tape with two partitions"); + TAPE_FUNC (CreateTapePartition (get_handle (), TAPE_SELECT_PARTITIONS, + count <= 0 ? 1 : 2, 0)); + return tape_error ("tape_partition"); +} + +int +fhandler_dev_tape::tape_set_partition (long count) +{ + if (count < 0 || (unsigned long) count >= dp.MaximumPartitionCount) + lasterr = ERROR_INVALID_PARAMETER; + else + lasterr = _tape_set_pos (TAPE_LOGICAL_BLOCK, 0, count + 1); + return tape_error ("tape_set_partition"); +} diff --git a/winsup/cygwin/include/cygwin/mtio.h b/winsup/cygwin/include/cygwin/mtio.h index dabf81290..6aab34095 100644 --- a/winsup/cygwin/include/cygwin/mtio.h +++ b/winsup/cygwin/include/cygwin/mtio.h @@ -1,6 +1,6 @@ /* cygwin/mtio.h - Copyright 1999, 2001 Red Hat, Inc. + Copyright 1999, 2001, 2004 Red Hat, Inc. Written by Corinna Vinschen <corinna@vinschen.de> @@ -86,7 +86,9 @@ struct mtget { * number of bytes ignored, or * number of files not skipped, or * number of records not skipped. - * Cygwin: remaining KB. + * Cygwin: remaining KB until 1.5.7. + * active partition since 1.5.8, + * same as on linux. */ /* the following registers are device dependent */ long mt_dsreg; /* status register, Contains blocksize and diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index a4d938427..0633af504 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -237,12 +237,13 @@ details. */ 110: Export clock_gettime, sigwaitinfo, timer_create, timer_delete, timer_settime 111: Export sigqueue, sighold. + 112: Redefine some mtget fields. */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 111 +#define CYGWIN_VERSION_API_MINOR 112 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible |