Block patches for 2.3

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJU/uuVAAoJEH8JsnLIjy/WULwP/jeARjYkFuG3ahSWpeY0JnTK
 QCkLF06iSQQUiirXI4H+Tofl8kNVBd/Iinv+LbkF27iWbTiwalmLz7NiyboX8dl+
 NJZtCrqp44q7KFbl3g19/jop/zdZ9N5Gxp8BARVUILHQb1y5cXJwrDhBxTmNRDL+
 sSZXfomCgKtMP40nGLa0CcNIYKlm8MePJEM2TsMoWv7tYz4CXgBG39EqK6NJluCY
 kTTMcbdrLbR0imfKOVPutCgV8rhRXJ0oGVD3Q+D3/LFmPG++hoRnWCcDm6ZZ62Hi
 Ra7u87TBfAUUtiT+vFQJnd7hTpN+stQidsCDBLEY3qPTKYhzm648PHvcEwOAv6YW
 sjAELF2Rrsbe4vkL3/qgYDusnaPMElrHVEdbKtHofWtg6KctLnYIhusV+qKq1Fpa
 cRQEbQIZMVFeWN1G9WuYH8RBYrwJqp+/qq7DcnV62lUAdY4e3iO7E3yMLFDwpxku
 PLl7eofU/ZpnAOrrU2QAQvgXZRqy1ie/Unv8jFwefQkK5mXHoCtkAeBlOM8t4kJf
 HjkC/hYO7kwPdaz6xK80wpXqYd3vT6jKi7mlJqC5oQQLGJbRigxlMZ16UIAx+IrL
 NxhnQChp7IP21KMATFbpvYjcJyGMw3ZuVRaUhQBgqQArIomVHvM5WcN9M6S5dsmj
 vClFOIqjlSbtsmChceWr
 =hlbC
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block patches for 2.3

# gpg: Signature made Tue Mar 10 13:03:17 2015 GMT using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (73 commits)
  MAINTAINERS: Add jcody as blockjobs, block devices maintainer
  iotests: add O_DIRECT alignment probing test
  block/raw-posix: fix launching with failed disks
  MAINTAINERS: Add jsnow as IDE maintainer
  sheepdog: Fix misleading error messages in sd_snapshot_create()
  Add testcase for scsi-hd devices without drive property
  scsi-hd: fix property unset case
  block/vdi: Add locking for parallel requests
  iotests: Drop vpc from 004's and 104's format list
  iotests: Remove 006
  iotests: Fix 051's reference output
  virtio-blk: Remove the stale FIXME comment
  tests: Check QVIRTIO_F_ANY_LAYOUT flag in virtio-blk test
  libqos: Solve bug in interrupt checking when using MSIX in virtio-pci.c
  sheepdog: fix confused return values
  qtest/ahci: add fragmented dma test
  qtest/ahci: Add PIO and LBA48 tests
  qtest/ahci: Add DMA test variants
  libqos/ahci: add ahci command helpers
  qtest/ahci: Add a macro bootup routine
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-03-10 14:01:22 +00:00
commit 1976058109
85 changed files with 2693 additions and 840 deletions

View file

@ -1160,6 +1160,11 @@ static void ahci_start_dma(IDEDMA *dma, IDEState *s,
dma_cb(s, 0);
}
static void ahci_restart_dma(IDEDMA *dma)
{
/* Nothing to do, ahci_start_dma already resets s->io_buffer_offset. */
}
/**
* Called in DMA R/W chains to read the PRDT, utilizing ahci_populate_sglist.
* Not currently invoked by PIO R/W chains,
@ -1226,12 +1231,6 @@ static int ahci_dma_rw_buf(IDEDMA *dma, int is_write)
return 1;
}
static int ahci_dma_set_unit(IDEDMA *dma, int unit)
{
/* only a single unit per link */
return 0;
}
static void ahci_cmd_done(IDEDMA *dma)
{
AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
@ -1252,19 +1251,14 @@ static void ahci_irq_set(void *opaque, int n, int level)
{
}
static void ahci_dma_restart_cb(void *opaque, int running, RunState state)
{
}
static const IDEDMAOps ahci_dma_ops = {
.start_dma = ahci_start_dma,
.restart_dma = ahci_restart_dma,
.start_transfer = ahci_start_transfer,
.prepare_buf = ahci_dma_prepare_buf,
.commit_buf = ahci_commit_buf,
.rw_buf = ahci_dma_rw_buf,
.set_unit = ahci_dma_set_unit,
.cmd_done = ahci_cmd_done,
.restart_cb = ahci_dma_restart_cb,
};
void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
@ -1294,6 +1288,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
ad->port_no = i;
ad->port.dma = &ad->dma;
ad->port.dma->ops = &ahci_dma_ops;
ide_register_restart_cb(&ad->port);
}
}
@ -1333,6 +1328,7 @@ static const VMStateDescription vmstate_ahci_device = {
.version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_IDE_BUS(port, AHCIDevice),
VMSTATE_IDE_DRIVE(port.ifs[0], AHCIDevice),
VMSTATE_UINT32(port_state, AHCIDevice),
VMSTATE_UINT32(finished, AHCIDevice),
VMSTATE_UINT32(port_regs.lst_addr, AHCIDevice),
@ -1371,16 +1367,23 @@ static int ahci_state_post_load(void *opaque, int version_id)
map_page(s->as, &ad->res_fis,
((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256);
/*
* All pending i/o should be flushed out on a migrate. However,
* we might not have cleared the busy_slot since this is done
* in a bh. Also, issue i/o against any slots that are pending.
* If an error is present, ad->busy_slot will be valid and not -1.
* In this case, an operation is waiting to resume and will re-check
* for additional AHCI commands to execute upon completion.
*
* In the case where no error was present, busy_slot will be -1,
* and we should check to see if there are additional commands waiting.
*/
if ((ad->busy_slot != -1) &&
!(ad->port.ifs[0].status & (BUSY_STAT|DRQ_STAT))) {
pr->cmd_issue &= ~(1 << ad->busy_slot);
ad->busy_slot = -1;
if (ad->busy_slot == -1) {
check_cmd(s, i);
} else {
/* We are in the middle of a command, and may need to access
* the command header in guest memory again. */
if (ad->busy_slot < 0 || ad->busy_slot >= AHCI_MAX_CMDS) {
return -1;
}
ad->cur_cmd = &((AHCICmdHdr *)ad->lst)[ad->busy_slot];
}
check_cmd(s, i);
}
return 0;

View file

@ -252,7 +252,6 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
s->packet_transfer_size = size;
s->io_buffer_size = size; /* dma: send the reply data as one chunk */
s->elementary_transfer_size = 0;
s->io_buffer_index = 0;
if (s->atapi_dma) {
block_acct_start(blk_get_stats(s->blk), &s->acct, size,
@ -261,6 +260,7 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
ide_start_dma(s, ide_atapi_cmd_read_dma_cb);
} else {
s->status = READY_STAT | SEEK_STAT;
s->io_buffer_index = 0;
ide_atapi_cmd_reply_end(s);
}
}
@ -368,7 +368,6 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
{
s->lba = lba;
s->packet_transfer_size = nb_sectors * sector_size;
s->io_buffer_index = 0;
s->io_buffer_size = 0;
s->cd_sector_size = sector_size;

View file

@ -368,8 +368,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
bmdma_init(&d->bus[i], &d->bmdma[i], d);
d->bmdma[i].bus = &d->bus[i];
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&d->bmdma[i].dma);
ide_register_restart_cb(&d->bus[i]);
}
vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d);

View file

@ -561,6 +561,8 @@ static bool ide_sect_range_ok(IDEState *s,
return true;
}
static void ide_sector_read(IDEState *s);
static void ide_sector_read_cb(void *opaque, int ret)
{
IDEState *s = opaque;
@ -595,7 +597,7 @@ static void ide_sector_read_cb(void *opaque, int ret)
s->io_buffer_offset += 512 * n;
}
void ide_sector_read(IDEState *s)
static void ide_sector_read(IDEState *s)
{
int64_t sector_num;
int n;
@ -646,6 +648,9 @@ static void dma_buf_commit(IDEState *s, uint32_t tx_bytes)
void ide_set_inactive(IDEState *s, bool more)
{
s->bus->dma->aiocb = NULL;
s->bus->retry_unit = -1;
s->bus->retry_sector_num = 0;
s->bus->retry_nsector = 0;
if (s->bus->dma->ops->set_inactive) {
s->bus->dma->ops->set_inactive(s->bus->dma, more);
}
@ -666,7 +671,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
if (action == BLOCK_ERROR_ACTION_STOP) {
s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
assert(s->bus->retry_unit == s->unit);
s->bus->error_status = op;
} else if (action == BLOCK_ERROR_ACTION_REPORT) {
if (op & IDE_RETRY_DMA) {
@ -679,7 +684,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
return action != BLOCK_ERROR_ACTION_IGNORE;
}
void ide_dma_cb(void *opaque, int ret)
static void ide_dma_cb(void *opaque, int ret)
{
IDEState *s = opaque;
int n;
@ -777,7 +782,6 @@ eot:
static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
{
s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
s->io_buffer_index = 0;
s->io_buffer_size = 0;
s->dma_cmd = dma_cmd;
@ -799,11 +803,17 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
void ide_start_dma(IDEState *s, BlockCompletionFunc *cb)
{
s->io_buffer_index = 0;
s->bus->retry_unit = s->unit;
s->bus->retry_sector_num = ide_get_sector(s);
s->bus->retry_nsector = s->nsector;
if (s->bus->dma->ops->start_dma) {
s->bus->dma->ops->start_dma(s->bus->dma, s, cb);
}
}
static void ide_sector_write(IDEState *s);
static void ide_sector_write_timer_cb(void *opaque)
{
IDEState *s = opaque;
@ -863,7 +873,7 @@ static void ide_sector_write_cb(void *opaque, int ret)
}
}
void ide_sector_write(IDEState *s)
static void ide_sector_write(IDEState *s)
{
int64_t sector_num;
int n;
@ -917,7 +927,7 @@ static void ide_flush_cb(void *opaque, int ret)
ide_set_irq(s->bus);
}
void ide_flush_cache(IDEState *s)
static void ide_flush_cache(IDEState *s)
{
if (s->blk == NULL) {
ide_flush_cb(s, 0);
@ -2314,22 +2324,101 @@ static int ide_nop_int(IDEDMA *dma, int x)
return 0;
}
static void ide_nop(IDEDMA *dma)
{
}
static int32_t ide_nop_int32(IDEDMA *dma, int x)
{
return 0;
}
static void ide_nop_restart(void *opaque, int x, RunState y)
{
}
static const IDEDMAOps ide_dma_nop_ops = {
.prepare_buf = ide_nop_int32,
.restart_dma = ide_nop,
.rw_buf = ide_nop_int,
.set_unit = ide_nop_int,
.restart_cb = ide_nop_restart,
};
static void ide_restart_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
{
s->unit = s->bus->retry_unit;
ide_set_sector(s, s->bus->retry_sector_num);
s->nsector = s->bus->retry_nsector;
s->bus->dma->ops->restart_dma(s->bus->dma);
s->io_buffer_size = 0;
s->dma_cmd = dma_cmd;
ide_start_dma(s, ide_dma_cb);
}
static void ide_restart_bh(void *opaque)
{
IDEBus *bus = opaque;
IDEState *s;
bool is_read;
int error_status;
qemu_bh_delete(bus->bh);
bus->bh = NULL;
error_status = bus->error_status;
if (bus->error_status == 0) {
return;
}
s = idebus_active_if(bus);
is_read = (bus->error_status & IDE_RETRY_READ) != 0;
/* The error status must be cleared before resubmitting the request: The
* request may fail again, and this case can only be distinguished if the
* called function can set a new error status. */
bus->error_status = 0;
if (error_status & IDE_RETRY_DMA) {
if (error_status & IDE_RETRY_TRIM) {
ide_restart_dma(s, IDE_DMA_TRIM);
} else {
ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
}
} else if (error_status & IDE_RETRY_PIO) {
if (is_read) {
ide_sector_read(s);
} else {
ide_sector_write(s);
}
} else if (error_status & IDE_RETRY_FLUSH) {
ide_flush_cache(s);
} else {
/*
* We've not got any bits to tell us about ATAPI - but
* we do have the end_transfer_func that tells us what
* we're trying to do.
*/
if (s->end_transfer_func == ide_atapi_cmd) {
ide_atapi_dma_restart(s);
}
}
}
static void ide_restart_cb(void *opaque, int running, RunState state)
{
IDEBus *bus = opaque;
if (!running)
return;
if (!bus->bh) {
bus->bh = qemu_bh_new(ide_restart_bh, bus);
qemu_bh_schedule(bus->bh);
}
}
void ide_register_restart_cb(IDEBus *bus)
{
if (bus->dma->ops->restart_dma) {
qemu_add_vm_change_state_handler(ide_restart_cb, bus);
}
}
static IDEDMA ide_dma_nop = {
.ops = &ide_dma_nop_ops,
.aiocb = NULL,
@ -2557,10 +2646,13 @@ const VMStateDescription vmstate_ide_drive = {
static const VMStateDescription vmstate_ide_error_status = {
.name ="ide_bus/error",
.version_id = 1,
.version_id = 2,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_INT32(error_status, IDEBus),
VMSTATE_INT64_V(retry_sector_num, IDEBus, 2),
VMSTATE_UINT32_V(retry_nsector, IDEBus, 2),
VMSTATE_UINT8_V(retry_unit, IDEBus, 2),
VMSTATE_END_OF_LIST()
}
};

View file

@ -436,10 +436,9 @@ struct IDEDMAOps {
DMAInt32Func *prepare_buf;
DMAu32Func *commit_buf;
DMAIntFunc *rw_buf;
DMAIntFunc *set_unit;
DMAVoidFunc *restart_dma;
DMAStopFunc *set_inactive;
DMAVoidFunc *cmd_done;
DMARestartFunc *restart_cb;
DMAVoidFunc *reset;
};
@ -455,6 +454,8 @@ struct IDEBus {
IDEDevice *master;
IDEDevice *slave;
IDEState ifs[2];
QEMUBH *bh;
int bus_id;
int max_units;
IDEDMA *dma;
@ -463,6 +464,9 @@ struct IDEBus {
qemu_irq irq;
int error_status;
uint8_t retry_unit;
int64_t retry_sector_num;
uint32_t retry_nsector;
};
#define TYPE_IDE_DEVICE "ide-device"
@ -522,6 +526,9 @@ extern const VMStateDescription vmstate_ide_drive;
#define VMSTATE_IDE_DRIVES(_field, _state) \
VMSTATE_STRUCT_ARRAY(_field, _state, 2, 3, vmstate_ide_drive, IDEState)
#define VMSTATE_IDE_DRIVE(_field, _state) \
VMSTATE_STRUCT(_field, _state, 1, vmstate_ide_drive, IDEState)
void ide_bus_reset(IDEBus *bus);
int64_t ide_get_sector(IDEState *s);
void ide_set_sector(IDEState *s, int64_t sector_num);
@ -550,12 +557,9 @@ int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
int chs_trans);
void ide_init2(IDEBus *bus, qemu_irq irq);
void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2);
void ide_register_restart_cb(IDEBus *bus);
void ide_exec_cmd(IDEBus *bus, uint32_t val);
void ide_dma_cb(void *opaque, int ret);
void ide_sector_write(IDEState *s);
void ide_sector_read(IDEState *s);
void ide_flush_cache(IDEState *s);
void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
EndTransferFunc *end_transfer_func);

View file

@ -74,7 +74,8 @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp)
isa_init_irq(isadev, &s->irq, s->isairq);
ide_init2(&s->bus, s->irq);
vmstate_register(dev, 0, &vmstate_ide_isa, s);
};
ide_register_restart_cb(&s->bus);
}
ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
DriveInfo *hd0, DriveInfo *hd1)

View file

@ -558,10 +558,6 @@ static int32_t ide_nop_int32(IDEDMA *dma, int x)
return 0;
}
static void ide_nop_restart(void *opaque, int x, RunState y)
{
}
static void ide_dbdma_start(IDEDMA *dma, IDEState *s,
BlockCompletionFunc *cb)
{
@ -576,8 +572,6 @@ static const IDEDMAOps dbdma_ops = {
.start_dma = ide_dbdma_start,
.prepare_buf = ide_nop_int32,
.rw_buf = ide_nop_int,
.set_unit = ide_nop_int,
.restart_cb = ide_nop_restart,
};
static void macio_ide_realizefn(DeviceState *dev, Error **errp)

View file

@ -42,13 +42,10 @@ static void bmdma_start_dma(IDEDMA *dma, IDEState *s,
{
BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
bm->unit = s->unit;
bm->dma_cb = dma_cb;
bm->cur_prd_last = 0;
bm->cur_prd_addr = 0;
bm->cur_prd_len = 0;
bm->sector_num = ide_get_sector(s);
bm->nsector = s->nsector;
if (bm->status & BM_STATUS_DMAING) {
bm->dma_cb(bmdma_active_if(bm), 0);
@ -163,20 +160,11 @@ static int bmdma_rw_buf(IDEDMA *dma, int is_write)
return 1;
}
static int bmdma_set_unit(IDEDMA *dma, int unit)
{
BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
bm->unit = unit;
return 0;
}
static void bmdma_set_inactive(IDEDMA *dma, bool more)
{
BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
bm->dma_cb = NULL;
bm->unit = -1;
if (more) {
bm->status |= BM_STATUS_DMAING;
} else {
@ -184,83 +172,11 @@ static void bmdma_set_inactive(IDEDMA *dma, bool more)
}
}
static void bmdma_restart_dma(BMDMAState *bm, enum ide_dma_cmd dma_cmd)
static void bmdma_restart_dma(IDEDMA *dma)
{
IDEState *s = bmdma_active_if(bm);
ide_set_sector(s, bm->sector_num);
s->io_buffer_index = 0;
s->io_buffer_size = 0;
s->nsector = bm->nsector;
s->dma_cmd = dma_cmd;
bm->cur_addr = bm->addr;
bm->dma_cb = ide_dma_cb;
bmdma_start_dma(&bm->dma, s, bm->dma_cb);
}
/* TODO This should be common IDE code */
static void bmdma_restart_bh(void *opaque)
{
BMDMAState *bm = opaque;
IDEBus *bus = bm->bus;
bool is_read;
int error_status;
qemu_bh_delete(bm->bh);
bm->bh = NULL;
if (bm->unit == (uint8_t) -1) {
return;
}
is_read = (bus->error_status & IDE_RETRY_READ) != 0;
/* The error status must be cleared before resubmitting the request: The
* request may fail again, and this case can only be distinguished if the
* called function can set a new error status. */
error_status = bus->error_status;
bus->error_status = 0;
if (error_status & IDE_RETRY_DMA) {
if (error_status & IDE_RETRY_TRIM) {
bmdma_restart_dma(bm, IDE_DMA_TRIM);
} else {
bmdma_restart_dma(bm, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
}
} else if (error_status & IDE_RETRY_PIO) {
if (is_read) {
ide_sector_read(bmdma_active_if(bm));
} else {
ide_sector_write(bmdma_active_if(bm));
}
} else if (error_status & IDE_RETRY_FLUSH) {
ide_flush_cache(bmdma_active_if(bm));
} else {
IDEState *s = bmdma_active_if(bm);
/*
* We've not got any bits to tell us about ATAPI - but
* we do have the end_transfer_func that tells us what
* we're trying to do.
*/
if (s->end_transfer_func == ide_atapi_cmd) {
ide_atapi_dma_restart(s);
}
}
}
static void bmdma_restart_cb(void *opaque, int running, RunState state)
{
IDEDMA *dma = opaque;
BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
if (!running)
return;
if (!bm->bh) {
bm->bh = qemu_bh_new(bmdma_restart_bh, &bm->dma);
qemu_bh_schedule(bm->bh);
}
bm->cur_addr = bm->addr;
}
static void bmdma_cancel(BMDMAState *bm)
@ -286,8 +202,6 @@ static void bmdma_reset(IDEDMA *dma)
bm->cur_prd_last = 0;
bm->cur_prd_addr = 0;
bm->cur_prd_len = 0;
bm->sector_num = 0;
bm->nsector = 0;
}
static void bmdma_irq(void *opaque, int n, int level)
@ -404,6 +318,9 @@ static void ide_bmdma_pre_save(void *opaque)
BMDMAState *bm = opaque;
uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS;
bm->migration_retry_unit = bm->bus->retry_unit;
bm->migration_retry_sector_num = bm->bus->retry_sector_num;
bm->migration_retry_nsector = bm->bus->retry_nsector;
bm->migration_compat_status =
(bm->status & ~abused_bits) | (bm->bus->error_status & abused_bits);
}
@ -420,6 +337,11 @@ static int ide_bmdma_post_load(void *opaque, int version_id)
bm->status = bm->migration_compat_status & ~abused_bits;
bm->bus->error_status |= bm->migration_compat_status & abused_bits;
}
if (bm->bus->error_status) {
bm->bus->retry_sector_num = bm->migration_retry_sector_num;
bm->bus->retry_nsector = bm->migration_retry_nsector;
bm->bus->retry_unit = bm->migration_retry_unit;
}
return 0;
}
@ -456,9 +378,9 @@ static const VMStateDescription vmstate_bmdma = {
VMSTATE_UINT8(cmd, BMDMAState),
VMSTATE_UINT8(migration_compat_status, BMDMAState),
VMSTATE_UINT32(addr, BMDMAState),
VMSTATE_INT64(sector_num, BMDMAState),
VMSTATE_UINT32(nsector, BMDMAState),
VMSTATE_UINT8(unit, BMDMAState),
VMSTATE_INT64(migration_retry_sector_num, BMDMAState),
VMSTATE_UINT32(migration_retry_nsector, BMDMAState),
VMSTATE_UINT8(migration_retry_unit, BMDMAState),
VMSTATE_END_OF_LIST()
},
.subsections = (VMStateSubsection []) {
@ -482,7 +404,7 @@ static int ide_pci_post_load(void *opaque, int version_id)
for(i = 0; i < 2; i++) {
/* current versions always store 0/1, but older version
stored bigger values. We only need last bit */
d->bmdma[i].unit &= 1;
d->bmdma[i].migration_retry_unit &= 1;
ide_bmdma_post_load(&d->bmdma[i], -1);
}
@ -523,9 +445,8 @@ static const struct IDEDMAOps bmdma_ops = {
.start_dma = bmdma_start_dma,
.prepare_buf = bmdma_prepare_buf,
.rw_buf = bmdma_rw_buf,
.set_unit = bmdma_set_unit,
.restart_dma = bmdma_restart_dma,
.set_inactive = bmdma_set_inactive,
.restart_cb = bmdma_restart_cb,
.reset = bmdma_reset,
};

View file

@ -22,18 +22,18 @@ typedef struct BMDMAState {
uint32_t cur_prd_last;
uint32_t cur_prd_addr;
uint32_t cur_prd_len;
uint8_t unit;
BlockCompletionFunc *dma_cb;
int64_t sector_num;
uint32_t nsector;
MemoryRegion addr_ioport;
MemoryRegion extra_io;
QEMUBH *bh;
qemu_irq irq;
/* Bit 0-2 and 7: BM status register
* Bit 3-6: bus->error_status */
uint8_t migration_compat_status;
uint8_t migration_retry_unit;
int64_t migration_retry_sector_num;
uint32_t migration_retry_nsector;
struct PCIIDEState *pci_dev;
} BMDMAState;
@ -62,8 +62,8 @@ typedef struct PCIIDEState {
static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
{
assert(bmdma->unit != (uint8_t)-1);
return bmdma->bus->ifs + bmdma->unit;
assert(bmdma->bus->retry_unit != (uint8_t)-1);
return bmdma->bus->ifs + bmdma->bus->retry_unit;
}

View file

@ -143,8 +143,7 @@ static void pci_piix_init_ports(PCIIDEState *d) {
bmdma_init(&d->bus[i], &d->bmdma[i], d);
d->bmdma[i].bus = &d->bus[i];
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&d->bmdma[i].dma);
ide_register_restart_cb(&d->bus[i]);
}
}

View file

@ -163,6 +163,7 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
return -1;
}
blkconf_blocksizes(&dev->conf);
if (dev->conf.logical_block_size != 512) {
error_report("logical_block_size must be 512 for IDE");
return -1;

View file

@ -166,8 +166,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
bmdma_init(&d->bus[i], &d->bmdma[i], d);
d->bmdma[i].bus = &d->bus[i];
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&d->bmdma[i].dma);
ide_register_restart_cb(&d->bus[i]);
}
}