+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
(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.
* 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
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;
* 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);
}
}
if (is_rewind_device ())
{
debug_printf ("rewinding");
- op.mt_op = MTREW;
- ioctl (MTIOCTOP, &op);
+ tape_set_pos (TAPE_REWIND, 0);
}
if (ret)
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:
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);
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 ();
}
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))
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)
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");
}
int
fhandler_dev_tape::tape_erase (int mode)
{
+ if (tape_set_pos (TAPE_REWIND, 0))
+ return lasterr;
switch (mode)
{
case TAPE_ERASE_SHORT:
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);
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)
{
(dmi->TINFO.BusSpecificData.ScsiInformation.DensityCode
<< MT_ST_DENSITY_SHIFT)
& MT_ST_DENSITY_MASK;
+ break;
}
#undef TINFO
}
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);
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)
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");
+}