mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 11:39:53 +00:00
[Core Change] Port HDD locking from XQEMU 1.x
This commit is contained in:
parent
68b54a7cc9
commit
7ea10931d1
@ -776,6 +776,10 @@ QemuOptsList qemu_legacy_drive_opts = {
|
||||
.name = "copy-on-read",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "copy read data from backing file into image file",
|
||||
},{
|
||||
.name = "locked",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "emulate a security locked drive",
|
||||
},
|
||||
|
||||
{ /* end of list */ }
|
||||
@ -804,6 +808,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
const char *deprecated[] = {
|
||||
"serial", "trans", "secs", "heads", "cyls", "addr"
|
||||
};
|
||||
bool locked;
|
||||
|
||||
/* Change legacy command line options into QMP ones */
|
||||
static const struct {
|
||||
@ -1021,6 +1026,9 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Locked */
|
||||
locked = qemu_opt_get_bool(legacy_opts, "locked", false);
|
||||
|
||||
/* Serial number */
|
||||
serial = qemu_opt_get(legacy_opts, "serial");
|
||||
|
||||
@ -1114,6 +1122,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
dinfo->unit = unit_id;
|
||||
dinfo->devaddr = devaddr;
|
||||
dinfo->serial = g_strdup(serial);
|
||||
dinfo->locked = locked;
|
||||
|
||||
blk_set_legacy_dinfo(blk, dinfo);
|
||||
|
||||
|
@ -15,6 +15,14 @@
|
||||
#include "qapi/qapi-types-block.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
void blkconf_locked(BlockConf *conf, bool *locked)
|
||||
{
|
||||
DriveInfo *dinfo;
|
||||
|
||||
dinfo = blk_legacy_dinfo(conf->blk);
|
||||
*locked = dinfo->locked;
|
||||
}
|
||||
|
||||
void blkconf_serial(BlockConf *conf, char **serial)
|
||||
{
|
||||
DriveInfo *dinfo;
|
||||
|
@ -76,6 +76,7 @@ static const char *IDE_DMA_CMD_str(enum ide_dma_cmd enval)
|
||||
}
|
||||
|
||||
static void ide_dummy_transfer_stop(IDEState *s);
|
||||
static void ide_security_cmd(IDEState *s);
|
||||
|
||||
static void padstr(char *str, const char *src, int len)
|
||||
{
|
||||
@ -213,6 +214,13 @@ static void ide_identify(IDEState *s)
|
||||
put_le16(p + 217, dev->rotation_rate); /* Nominal media rotation rate */
|
||||
}
|
||||
|
||||
/* 2: locked, 1: security enabled, 0: security supported */
|
||||
if (dev && dev->locked) {
|
||||
put_le16(p + 128, (1 << 2) | (1 << 1) | 1);
|
||||
} else {
|
||||
put_le16(p + 128, (1 << 0));
|
||||
}
|
||||
|
||||
ide_identify_size(s);
|
||||
s->identify_set = 1;
|
||||
|
||||
@ -1712,6 +1720,15 @@ static bool cmd_packet(IDEState *s, uint8_t cmd)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool cmd_security_unlock(IDEState *s, uint8_t cmd)
|
||||
{
|
||||
s->error = 0;
|
||||
s->status = READY_STAT | SEEK_STAT;
|
||||
ide_transfer_start(s, s->io_buffer, 512,
|
||||
ide_security_cmd);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*** CF-ATA commands ***/
|
||||
|
||||
@ -2046,6 +2063,7 @@ static const struct {
|
||||
[IBM_SENSE_CONDITION] = { cmd_ibm_sense_condition, CFA_OK | SET_DSC },
|
||||
[CFA_WEAR_LEVEL] = { cmd_cfa_erase_sectors, HD_CFA_OK | SET_DSC },
|
||||
[WIN_READ_NATIVE_MAX] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
|
||||
[WIN_SECURITY_UNLOCK] = { cmd_security_unlock, ALL_OK | SET_DSC },
|
||||
};
|
||||
|
||||
static bool ide_cmd_permitted(IDEState *s, uint32_t cmd)
|
||||
@ -2264,7 +2282,8 @@ void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
static bool ide_is_pio_out(IDEState *s)
|
||||
{
|
||||
if (s->end_transfer_func == ide_sector_write ||
|
||||
s->end_transfer_func == ide_atapi_cmd) {
|
||||
s->end_transfer_func == ide_atapi_cmd ||
|
||||
s->end_transfer_func == ide_security_cmd) {
|
||||
return false;
|
||||
} else if (s->end_transfer_func == ide_sector_read ||
|
||||
s->end_transfer_func == ide_transfer_stop ||
|
||||
@ -2404,6 +2423,17 @@ static void ide_dummy_transfer_stop(IDEState *s)
|
||||
s->io_buffer[3] = 0xff;
|
||||
}
|
||||
|
||||
static void ide_security_cmd(IDEState *s)
|
||||
{
|
||||
/* XXX: Actually verify the password... */
|
||||
|
||||
put_le16((uint16_t *)s->identify_data + 128, (1 << 1) | 1);
|
||||
|
||||
s->error = 0;
|
||||
s->status = READY_STAT | SEEK_STAT;
|
||||
ide_set_irq(s->bus);
|
||||
}
|
||||
|
||||
void ide_bus_reset(IDEBus *bus)
|
||||
{
|
||||
bus->unit = 0;
|
||||
@ -2724,6 +2754,7 @@ static EndTransferFunc* transfer_end_table[] = {
|
||||
ide_atapi_cmd_reply_end,
|
||||
ide_atapi_cmd,
|
||||
ide_dummy_transfer_stop,
|
||||
ide_security_cmd,
|
||||
};
|
||||
|
||||
static int transfer_end_table_idx(EndTransferFunc *fn)
|
||||
|
@ -188,6 +188,8 @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
blkconf_locked(&dev->conf, &dev->locked);
|
||||
|
||||
blkconf_serial(&dev->conf, &dev->serial);
|
||||
if (kind != IDE_CD) {
|
||||
if (!blkconf_geometry(&dev->conf, &dev->chs_trans, 65535, 16, 255,
|
||||
|
@ -72,6 +72,7 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
|
||||
|
||||
/* Configuration helpers */
|
||||
|
||||
void blkconf_locked(BlockConf *conf, bool *locked);
|
||||
void blkconf_serial(BlockConf *conf, char **serial);
|
||||
bool blkconf_geometry(BlockConf *conf, int *trans,
|
||||
unsigned cyls_max, unsigned heads_max, unsigned secs_max,
|
||||
|
@ -506,6 +506,7 @@ struct IDEDevice {
|
||||
char *version;
|
||||
char *serial;
|
||||
char *model;
|
||||
bool locked;
|
||||
uint64_t wwn;
|
||||
/*
|
||||
* 0x0000 - rotation rate not reported
|
||||
|
@ -38,6 +38,7 @@ struct DriveInfo {
|
||||
int cyls, heads, secs, trans;
|
||||
QemuOpts *opts;
|
||||
char *serial;
|
||||
bool locked;
|
||||
QTAILQ_ENTRY(DriveInfo) next;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user