Fixed missing media change handling (#690)

* Remember media change

* Added comment

* Added TODO

* Updated SCSI level for host services to SPC-5

* Manpage update
This commit is contained in:
Uwe Seimet 2022-02-21 21:01:17 +01:00 committed by GitHub
parent 5d92590877
commit ba8ad2e7f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 69 additions and 38 deletions

View File

@ -71,7 +71,7 @@ Set the vendor, product and revision for the device, to be returned with the INQ
The rascsi server port, default is 6868.
.TP
.BR \-r\fI " " \fIRESERVED_IDS
Comma-separated list of IDs to reserve.
Comma-separated list of IDs to reserve. Pass an empty list in order to not reserve anything.
.BR \-p\fI " " \fITYPE
The optional case-insensitive device type (SAHD, SCHD, SCRM, SCCD, SCMO, SCBR, SCDP, SCLP, SCHS). If no type is specified for devices that support an image file, rascsi tries to derive the type from the file extension.
.TP

View File

@ -91,35 +91,36 @@ OPTIONS
The rascsi server port, default is 6868.
-r RESERVED_IDS
Comma-separated list of IDs to reserve. -p TYPE The optional
case-insensitive device type (SAHD, SCHD, SCRM, SCCD, SCMO,
SCBR, SCDP, SCLP, SCHS). If no type is specified for devices
that support an image file, rascsi tries to derive the type from
the file extension.
Comma-separated list of IDs to reserve. Pass an empty list in
order to not reserve anything. -p TYPE The optional case-insen
sitive device type (SAHD, SCHD, SCRM, SCCD, SCMO, SCBR, SCDP,
SCLP, SCHS). If no type is specified for devices that support an
image file, rascsi tries to derive the type from the file exten
sion.
-v Display the rascsi version.
-z LOCALE
Overrides the default locale for client-faces error messages.
Overrides the default locale for client-faces error messages.
The client can override the locale.
-IDn[:u] FILE
n is the SCSI ID number (0-7). u (0-31) is the optional LUN
n is the SCSI ID number (0-7). u (0-31) is the optional LUN
(logical unit). The default LUN is 0.
FILE is the name of the image file to use for the SCSI device.
FILE is the name of the image file to use for the SCSI device.
For devices that do not support an image file (SCBR, SCDP, SCLP,
SCHS) the filename may have a special meaning or a dummy name
can be provided. For SCBR and SCDP it is an optioinal priori
tized list of network interfaces, an optional IP address and
SCHS) the filename may have a special meaning or a dummy name
can be provided. For SCBR and SCDP it is an optioinal priori
tized list of network interfaces, an optional IP address and
netmask, e.g. "interfaces=eth0,eth1,wlan0:inet=10.10.20.1/24".
For SCLP it is the print command to be used and a reservation
For SCLP it is the print command to be used and a reservation
timeout in seconds, e.g. "cmd=lp -oraw %f:timeout=60".
-HDn[:u] FILE
n is the SASI ID number (0-15). The effective SASI ID is calcu
lated as n/2, the effective SASI LUN is calculated is the re
mainder of n/2. Alternatively the n:u syntax can be used, where
n is the SASI ID number (0-15). The effective SASI ID is calcu
lated as n/2, the effective SASI LUN is calculated is the re
mainder of n/2. Alternatively the n:u syntax can be used, where
ns is the SASI ID (0-7) and u the LUN (0-1).
FILE is the name of the image file to use for the SASI device.
@ -136,7 +137,7 @@ EXAMPLES
rascsi -ID0 /path/to/harddrive.hda -ID2 /path/to/cdimage.iso
Launch RaSCSI with a removable SCSI drive image as ID 0 and the raw de
vice file /dev/hdb (e.g. a USB stick) and a DaynaPort network adapter
vice file /dev/hdb (e.g. a USB stick) and a DaynaPort network adapter
as ID 6:
rascsi -ID0 -t scrm /dev/hdb -ID6 -t scdp daynaport

View File

@ -94,7 +94,7 @@ Rename an image file in the default image folder.
The rascsi port to connect to, default is 6868.
.TP
.BR \-r\fI " " \fIRESERVED_IDS
Comma-separated list of IDs to reserve.
Comma-separated list of IDs to reserve. Pass an empty list in order to not reserve anything.
.TP
.BR \-s\fI
Display server-side settings like available images or supported device types.

View File

@ -71,9 +71,10 @@ OPTIONS
The rascsi port to connect to, default is 6868.
-r RESERVED_IDS
Comma-separated list of IDs to reserve.
Comma-separated list of IDs to reserve. Pass an empty list in
order to not reserve anything.
-s Display server-side settings like available images or supported
-s Display server-side settings like available images or supported
device types.
-T Display all device types and their properties.
@ -100,7 +101,7 @@ OPTIONS
d(etach): Detach disk
i(nsert): Insert media (removable media devices only)
e(ject): Eject media (removable media devices only)
p(rotect): Write protect the medium (not for CD-ROMs, which
p(rotect): Write protect the medium (not for CD-ROMs, which
are always read-only)
u(nprotect): Remove write protection from the medium (not for
CD-ROMs, which are always read-only)
@ -110,18 +111,18 @@ OPTIONS
-b BLOCK_SIZE
The optional block size. For SCSI drives 512, 1024, 2048 or 4096
bytes, default size is 512 bytes. For SASI drives 256 or 1024
bytes, default size is 512 bytes. For SASI drives 256 or 1024
bytes, default is 256 bytes.
-f FILE|PARAM
Device-specific: Either a path to a disk image file, or a param
eter for a non-disk device. See the rascsi(1) man page for per
eter for a non-disk device. See the rascsi(1) man page for per
mitted file types.
-t TYPE
Specifies the device type. This type overrides the type derived
Specifies the device type. This type overrides the type derived
from the file extension of the specified image. See the
rascsi(1) man page for the available device types. For some
rascsi(1) man page for the available device types. For some
types there are shortcuts (only the first letter is required):
hd: SCSI hard disk drive
rm: SCSI removable media drive
@ -133,16 +134,16 @@ OPTIONS
services: Host services device
-n VENDOR:PRODUCT:REVISION
The vendor, product and revision for the device, to be returned
The vendor, product and revision for the device, to be returned
with the INQUIRY data. A complete set of name components must be
provided. VENDOR may have up to 8, PRODUCT up to 16, REVISION up
to 4 characters. Padding with blanks to the maxium length is au
tomatically applied. Once set the name of a device cannot be
tomatically applied. Once set the name of a device cannot be
changed.
-u UNIT
Unit number (0-31). This will default to 0. This option is only
used when there are multiple SCSI devices on a shared SCSI con
Unit number (0-31). This will default to 0. This option is only
used when there are multiple SCSI devices on a shared SCSI con
troller. (This is not common)
EXAMPLES

View File

@ -31,6 +31,7 @@ Disk::Disk(const string& id) : ModePageDevice(id), ScsiBlockCommands()
disk.blocks = 0;
disk.dcache = NULL;
disk.image_offset = 0;
disk.is_medium_changed = false;
dispatcher.AddCommand(eCmdRezero, "Rezero", &Disk::Rezero);
dispatcher.AddCommand(eCmdFormat, "FormatUnit", &Disk::FormatUnit);
@ -79,6 +80,16 @@ Disk::~Disk()
bool Disk::Dispatch(SCSIDEV *controller)
{
// Media changes must be reported on the next access, i.e. not only for TEST UNIT READY
if (disk.is_medium_changed) {
assert(IsRemovable());
disk.is_medium_changed = false;
controller->Error(ERROR_CODES::sense_key::UNIT_ATTENTION, ERROR_CODES::asc::NOT_READY_TO_READY_CHANGE);
return true;
}
// The superclass handles the less specific commands
return dispatcher.Dispatch(this, controller) ? true : super::Dispatch(controller);
}
@ -395,6 +406,15 @@ void Disk::ReadDefectData10(SASIDEV *controller)
controller->DataIn();
}
void Disk::MediumChanged()
{
assert(IsRemovable());
if (IsRemovable()) {
disk.is_medium_changed = true;
}
}
bool Disk::Eject(bool force)
{
bool status = Device::Eject(force);

View File

@ -51,6 +51,7 @@ private:
uint32_t blocks; // Total number of sectors
DiskCache *dcache; // Disk cache
off_t image_offset; // Offset to actual data
bool is_medium_changed;
} disk_t;
Dispatcher<Disk, SASIDEV> dispatcher;
@ -61,6 +62,7 @@ public:
virtual bool Dispatch(SCSIDEV *) override;
void MediumChanged();
void ReserveFile(const string&);
// Media Operations

View File

@ -58,8 +58,8 @@ void HostServices::TestUnitReady(SCSIDEV *controller)
int HostServices::Inquiry(const DWORD *cdb, BYTE *buf)
{
// Processor device, not removable
return PrimaryDevice::Inquiry(3, false, cdb, buf);
// Processor device, SPC-5, not removable
return PrimaryDevice::Inquiry(3, 7, false, cdb, buf);
}
void HostServices::StartStopUnit(SCSIDEV *controller)

View File

@ -92,6 +92,7 @@ void ModePageDevice::ModeSelect10(SASIDEV *controller)
int ModePageDevice::ModeSelectCheck(const DWORD *cdb, int length)
{
// Error if save parameters are set for other types than of SCHD or SCRM
// TODO This assumption is not correct, and this code should be located elsewhere
if (!IsSCSIHD() && (cdb[1] & 0x01)) {
SetStatusCode(STATUS_INVALIDCDB);
return 0;

View File

@ -149,7 +149,7 @@ bool PrimaryDevice::CheckReady()
return true;
}
int PrimaryDevice::Inquiry(int type, bool is_removable, const DWORD *cdb, BYTE *buf)
int PrimaryDevice::Inquiry(int type, int scsi_level, bool is_removable, const DWORD *cdb, BYTE *buf)
{
int allocation_length = cdb[4] + (((DWORD)cdb[3]) << 8);
if (allocation_length > 4) {
@ -166,7 +166,7 @@ int PrimaryDevice::Inquiry(int type, bool is_removable, const DWORD *cdb, BYTE *
memset(buf, 0, allocation_length);
buf[0] = type;
buf[1] = is_removable ? 0x80 : 0x00;
buf[2] = 0x02;
buf[2] = scsi_level;
buf[4] = 0x1F;
// Padded vendor, product, revision

View File

@ -40,7 +40,7 @@ public:
protected:
int Inquiry(int, bool, const DWORD *, BYTE *);
int Inquiry(int, int, bool, const DWORD *, BYTE *);
SASIDEV::ctrl_t *ctrl;

View File

@ -114,8 +114,8 @@ void SCSIDaynaPort::Open(const Filepath& path)
int SCSIDaynaPort::Inquiry(const DWORD *cdb, BYTE *buf)
{
// Processor device, not removable
return PrimaryDevice::Inquiry(3, false, cdb, buf);
// Processor device, SCSI-2, not removable
return PrimaryDevice::Inquiry(3, 2, false, cdb, buf);
}
//---------------------------------------------------------------------------

View File

@ -105,8 +105,8 @@ void SCSIPrinter::TestUnitReady(SCSIDEV *controller)
int SCSIPrinter::Inquiry(const DWORD *cdb, BYTE *buf)
{
// Printer device, not removable
return PrimaryDevice::Inquiry(2, false, cdb, buf);
// Printer device, SCSI-2, not removable
return PrimaryDevice::Inquiry(2, 2, false, cdb, buf);
}
void SCSIPrinter::ReserveUnit(SCSIDEV *controller)

View File

@ -822,6 +822,11 @@ bool Insert(const CommandContext& context, const PbDeviceDefinition& pb_device,
device->SetProtected(pb_device.protected_());
}
Disk *disk = dynamic_cast<Disk *>(device);
if (disk) {
disk->MediumChanged();
}
return true;
}

View File

@ -58,6 +58,7 @@ public:
INVALID_FIELD_IN_CDB = 0x24,
INVALID_LUN = 0x25,
WRITE_PROTECTED = 0x27,
NOT_READY_TO_READY_CHANGE = 0x28,
MEDIUM_NOT_PRESENT = 0x3a
};
};