mirror of https://github.com/akuker/RASCSI.git
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:
parent
5d92590877
commit
ba8ad2e7f5
|
@ -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
|
||||
|
|
|
@ -91,11 +91,12 @@ 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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -71,7 +71,8 @@ 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
|
||||
device types.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue