Implement ERASE(10/12) for magneto-optical disks.

This commit is contained in:
2020-03-27 21:42:20 +00:00
parent 224b37065c
commit 26ba28988c
2 changed files with 88 additions and 2 deletions

View File

@@ -1122,6 +1122,7 @@ do_command(void *p, uint8_t *cdb)
unsigned preamble_len;
int32_t blen = 0;
int32_t *BufLen;
uint32_t previous_pos = 0;
if (dev->drv->bus_type == MO_BUS_SCSI) {
BufLen = &scsi_devices[dev->drv->bus_id.scsi.id][dev->drv->bus_id.scsi.lun].buffer_length;
@@ -1586,7 +1587,56 @@ atapi_out:
data_command_finish(dev, len, len, len, 0);
break;
default:
case GPCMD_ERASE_10:
case GPCMD_ERASE_12:
// Relative address
if((cdb[1] & 1))
previous_pos = dev->sector_pos;
switch(cdb[0]) {
case GPCMD_ERASE_10:
dev->sector_len = (cdb[7] << 8) | cdb[8];
break;
case GPCMD_ERASE_12:
dev->sector_len = ((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]);
break;
}
// Erase all remaining sectors
if((cdb[1] & 4))
{
// Cannot have a sector number when erase all
if(dev->sector_len)
{
invalid_field(dev);
return;
}
mo_format(dev);
set_phase(dev, SCSI_PHASE_STATUS);
command_complete(dev);
break;
}
switch(cdb[0]) {
case GPCMD_ERASE_10:
dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
break;
case GPCMD_ERASE_12:
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]);
break;
}
dev->sector_pos += previous_pos;
mo_erase(dev);
set_phase(dev, SCSI_PHASE_STATUS);
command_complete(dev);
break;
default:
illegal_opcode(dev);
break;
}
@@ -2557,3 +2607,39 @@ mo_format(mo_t *dev)
}
#endif
}
static int
mo_erase(mo_t *dev)
{
if (! dev->sector_len) {
command_complete(dev);
return -1;
}
DEBUG("Erasing %i blocks starting from %i...\n", dev->sector_len, dev->sector_pos);
if (dev->sector_pos >= dev->drv->medium_size) {
DEBUG("MO %i: Trying to erase beyond the end of disk\n", dev->id);
lba_out_of_range(dev);
return 0;
}
buf_alloc(dev->drv->sector_size);
memset(dev->buffer, 0, dev->drv->sector_size);
fseek(dev->drv->f, dev->drv->base + (dev->sector_pos * dev->drv->sector_size), SEEK_SET);
for (i = 0; i < dev->requested_blocks; i++) {
if (feof(dev->drv->f))
break;
fwrite(dev->buffer, 1, dev->drv->sector_size, dev->drv->f);
}
DEBUG("Erased %i bytes of blocks...\n", i * dev->drv->sector_size);
dev->sector_pos += i;
dev->sector_len -= i;
return 1;
}

View File

@@ -145,7 +145,7 @@ extern const char *mo_bus_to_string(int bus);
extern int mo_load(mo_t *dev, const wchar_t *fn);
extern void mo_close(void);
extern void mo_format(mo_t *dev);
static int mo_erase(mo_t *dev)
#ifdef __cplusplus
}
#endif