IDEState *ide_if;
BlockDriverCompletionFunc *dma_cb;
BlockDriverAIOCB *aiocb;
+ struct iovec iov;
+ QEMUIOVector qiov;
int64_t sector_num;
uint32_t nsector;
} BMDMAState;
static inline void cpu_to_ube16(uint8_t *buf, int val)
{
buf[0] = val >> 8;
- buf[1] = val;
+ buf[1] = val & 0xff;
}
static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
buf[0] = val >> 24;
buf[1] = val >> 16;
buf[2] = val >> 8;
- buf[3] = val;
+ buf[3] = val & 0xff;
}
static inline int ube16_to_cpu(const uint8_t *buf)
#ifdef DEBUG_AIO
printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
#endif
- bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,
- s->io_buffer + data_offset, n * 4,
- ide_atapi_cmd_read_dma_cb, bm);
+ bm->iov.iov_base = (void *)(s->io_buffer + data_offset);
+ bm->iov.iov_len = n * 4 * 512;
+ qemu_iovec_init_external(&bm->qiov, &bm->iov, 1);
+ bm->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2, &bm->qiov,
+ n * 4, ide_atapi_cmd_read_dma_cb, bm);
if (!bm->aiocb) {
/* Note: media not present is the most likely case */
ide_atapi_cmd_error(s, SENSE_NOT_READY,
for(i = 0; i < 2; i++) {
s = ide_state + i;
- s->io_buffer = qemu_memalign(512, IDE_DMA_BUF_SECTORS*512 + 4);
if (i == 0)
s->bs = hd0;
else
s->bs = hd1;
+ s->io_buffer = qemu_blockalign(s->bs, IDE_DMA_BUF_SECTORS*512 + 4);
if (s->bs) {
bdrv_get_geometry(s->bs, &nb_sectors);
bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
pci_conf[0x09] = 0x8f;
pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
- pci_conf[0x0e] = 0x00; // header_type
+ pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
pci_conf[0x51] = 0x04; // enable IDE0
if (secondary_ide_enabled) {
ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], irq[1]);
register_savevm("ide", 0, 2, pci_ide_save, pci_ide_load, d);
- qemu_register_reset(cmd646_reset, d);
+ qemu_register_reset(cmd646_reset, 0, d);
cmd646_reset(d);
}
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_1);
pci_conf[0x09] = 0x80; // legacy ATA mode
pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
- pci_conf[0x0e] = 0x00; // header_type
+ pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
- qemu_register_reset(piix3_reset, d);
+ qemu_register_reset(piix3_reset, 0, d);
piix3_reset(d);
pci_register_io_region((PCIDevice *)d, 4, 0x10,
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB);
pci_conf[0x09] = 0x80; // legacy ATA mode
pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
- pci_conf[0x0e] = 0x00; // header_type
+ pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
- qemu_register_reset(piix3_reset, d);
+ qemu_register_reset(piix3_reset, 0, d);
piix3_reset(d);
pci_register_io_region((PCIDevice *)d, 4, 0x10,
typedef struct MACIOIDEState {
IDEState ide_if[2];
- int stream_index;
+ BlockDriverAIOCB *aiocb;
} MACIOIDEState;
-static void pmac_atapi_read(DBDMA_io *io)
+static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
{
+ DBDMA_io *io = opaque;
MACIOIDEState *m = io->opaque;
IDEState *s = m->ide_if->cur_drive;
- int ret, len;
-
- while (io->len > 0 &&
- s->packet_transfer_size > 0) {
- len = s->cd_sector_size;
- ret = cd_read_sector(s->bs, s->lba, s->io_buffer, len);
- if (ret < 0) {
- io->dma_end(io);
- ide_transfer_stop(s);
- ide_atapi_io_error(s, ret);
- return;
- }
+ if (ret < 0) {
+ m->aiocb = NULL;
+ qemu_sglist_destroy(&s->sg);
+ ide_atapi_io_error(s, ret);
+ io->dma_end(opaque);
+ return;
+ }
- if (len > io->len)
- len = io->len;
+ if (s->io_buffer_size > 0) {
+ m->aiocb = NULL;
+ qemu_sglist_destroy(&s->sg);
- cpu_physical_memory_write(io->addr,
- s->io_buffer + m->stream_index, len);
+ s->packet_transfer_size -= s->io_buffer_size;
- /* db-dma can ask for 512 bytes whereas block size is 2048... */
+ s->io_buffer_index += s->io_buffer_size;
+ s->lba += s->io_buffer_index >> 11;
+ s->io_buffer_index &= 0x7ff;
+ }
- m->stream_index += len;
- s->lba += m->stream_index / s->cd_sector_size;
- m->stream_index %= s->cd_sector_size;
+ if (s->packet_transfer_size <= 0)
+ ide_atapi_cmd_ok(s);
- io->len -= len;
- io->addr += len;
- s->packet_transfer_size -= len;
+ if (io->len == 0) {
+ io->dma_end(opaque);
+ return;
}
- if (io->len <= 0)
- io->dma_end(io);
+ /* launch next transfer */
- if (s->packet_transfer_size <= 0) {
- s->status = READY_STAT | SEEK_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO
- | ATAPI_INT_REASON_CD;
- ide_set_irq(s);
+ s->io_buffer_size = io->len;
+
+ qemu_sglist_init(&s->sg, io->len / TARGET_PAGE_SIZE + 1);
+ qemu_sglist_add(&s->sg, io->addr, io->len);
+ io->addr += io->len;
+ io->len = 0;
+
+ m->aiocb = dma_bdrv_read(s->bs, &s->sg,
+ (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9),
+ pmac_ide_atapi_transfer_cb, io);
+ if (!m->aiocb) {
+ qemu_sglist_destroy(&s->sg);
+ /* Note: media not present is the most likely case */
+ ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ ASC_MEDIUM_NOT_PRESENT);
+ io->dma_end(opaque);
+ return;
}
}
-static void pmac_ide_transfer(DBDMA_io *io)
+static void pmac_ide_transfer_cb(void *opaque, int ret)
{
+ DBDMA_io *io = opaque;
MACIOIDEState *m = io->opaque;
IDEState *s = m->ide_if->cur_drive;
+ int n;
int64_t sector_num;
- int ret, n;
- int len;
- if (s->is_cdrom) {
- pmac_atapi_read(io);
+ if (ret < 0) {
+ m->aiocb = NULL;
+ qemu_sglist_destroy(&s->sg);
+ ide_dma_error(s);
+ io->dma_end(io);
return;
}
- while (io->len > 0 && s->nsector > 0) {
+ sector_num = ide_get_sector(s);
+ if (s->io_buffer_size > 0) {
+ m->aiocb = NULL;
+ qemu_sglist_destroy(&s->sg);
+ n = (s->io_buffer_size + 0x1ff) >> 9;
+ sector_num += n;
+ ide_set_sector(s, sector_num);
+ s->nsector -= n;
+ }
+
+ /* end of transfer ? */
+ if (s->nsector == 0) {
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s);
+ }
- sector_num = ide_get_sector(s);
+ /* end of DMA ? */
- n = s->nsector;
- if (n > IDE_DMA_BUF_SECTORS)
- n = IDE_DMA_BUF_SECTORS;
+ if (io->len == 0) {
+ io->dma_end(io);
+ return;
+ }
- len = n << 9;
- if (len > io->len)
- len = io->len;
- n = (len + 511) >> 9;
+ /* launch next transfer */
- if (s->is_read) {
- ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
- cpu_physical_memory_write(io->addr, s->io_buffer, len);
- } else {
- cpu_physical_memory_read(io->addr, s->io_buffer, len);
- ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
- }
+ s->io_buffer_index = 0;
+ s->io_buffer_size = io->len;
- if (ret != 0) {
- io->dma_end(io);
- ide_rw_error(s);
- return;
- }
+ qemu_sglist_init(&s->sg, io->len / TARGET_PAGE_SIZE + 1);
+ qemu_sglist_add(&s->sg, io->addr, io->len);
+ io->addr += io->len;
+ io->len = 0;
- io->len -= len;
- io->addr += len;
- ide_set_sector(s, sector_num + n);
- s->nsector -= n;
- }
+ if (s->is_read)
+ m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,
+ pmac_ide_transfer_cb, io);
+ else
+ m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,
+ pmac_ide_transfer_cb, io);
+ if (!m->aiocb)
+ pmac_ide_transfer_cb(io, -1);
+}
- if (io->len <= 0)
- io->dma_end(io);
+static void pmac_ide_transfer(DBDMA_io *io)
+{
+ MACIOIDEState *m = io->opaque;
+ IDEState *s = m->ide_if->cur_drive;
- if (s->nsector <= 0) {
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
+ s->io_buffer_size = 0;
+ if (s->is_cdrom) {
+ pmac_ide_atapi_transfer_cb(io, 0);
+ return;
}
- return;
+ pmac_ide_transfer_cb(io, 0);
+}
+
+static void pmac_ide_flush(DBDMA_io *io)
+{
+ MACIOIDEState *m = io->opaque;
+
+ if (m->aiocb)
+ qemu_aio_flush();
}
/* PowerMac IDE memory IO */
ide_init2(d->ide_if, hd_table[0], hd_table[1], irq);
if (dbdma)
- DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, d);
+ DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d);
pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
pmac_ide_write, d);
register_savevm("ide", 0, 1, pmac_ide_save, pmac_ide_load, d);
- qemu_register_reset(pmac_ide_reset, d);
+ qemu_register_reset(pmac_ide_reset, 0, d);
pmac_ide_reset(d);
return pmac_ide_memory;
#define METADATA_SIZE 0x20
/* DSCM-1XXXX Microdrive hard disk with CF+ II / PCMCIA interface. */
-struct md_s {
+typedef struct {
IDEState ide[2];
- struct pcmcia_card_s card;
+ PCMCIACardState card;
uint32_t attr_base;
uint32_t io_base;
uint8_t ctrl;
uint16_t io;
int cycle;
-};
+} MicroDriveState;
/* Register bitfields */
enum md_opt {
CTRL_SRST = 0x04,
};
-static inline void md_interrupt_update(struct md_s *s)
+static inline void md_interrupt_update(MicroDriveState *s)
{
if (!s->card.slot)
return;
static void md_set_irq(void *opaque, int irq, int level)
{
- struct md_s *s = (struct md_s *) opaque;
+ MicroDriveState *s = (MicroDriveState *) opaque;
if (level)
s->stat |= STAT_INT;
else
md_interrupt_update(s);
}
-static void md_reset(struct md_s *s)
+static void md_reset(MicroDriveState *s)
{
s->opt = OPT_MODE_MMAP;
s->stat = 0;
static uint8_t md_attr_read(void *opaque, uint32_t at)
{
- struct md_s *s = (struct md_s *) opaque;
+ MicroDriveState *s = (MicroDriveState *) opaque;
if (at < s->attr_base) {
if (at < s->card.cis_len)
return s->card.cis[at];
static void md_attr_write(void *opaque, uint32_t at, uint8_t value)
{
- struct md_s *s = (struct md_s *) opaque;
+ MicroDriveState *s = (MicroDriveState *) opaque;
at -= s->attr_base;
switch (at) {
static uint16_t md_common_read(void *opaque, uint32_t at)
{
- struct md_s *s = (struct md_s *) opaque;
+ MicroDriveState *s = (MicroDriveState *) opaque;
uint16_t ret;
at -= s->io_base;
static void md_common_write(void *opaque, uint32_t at, uint16_t value)
{
- struct md_s *s = (struct md_s *) opaque;
+ MicroDriveState *s = (MicroDriveState *) opaque;
at -= s->io_base;
switch (s->opt & OPT_MODE) {
static void md_save(QEMUFile *f, void *opaque)
{
- struct md_s *s = (struct md_s *) opaque;
+ MicroDriveState *s = (MicroDriveState *) opaque;
int i;
uint8_t drive1_selected;
static int md_load(QEMUFile *f, void *opaque, int version_id)
{
- struct md_s *s = (struct md_s *) opaque;
+ MicroDriveState *s = (MicroDriveState *) opaque;
int i;
uint8_t drive1_selected;
static int dscm1xxxx_attach(void *opaque)
{
- struct md_s *md = (struct md_s *) opaque;
+ MicroDriveState *md = (MicroDriveState *) opaque;
md->card.attr_read = md_attr_read;
md->card.attr_write = md_attr_write;
md->card.common_read = md_common_read;
static int dscm1xxxx_detach(void *opaque)
{
- struct md_s *md = (struct md_s *) opaque;
+ MicroDriveState *md = (MicroDriveState *) opaque;
md_reset(md);
return 0;
}
-struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv)
+PCMCIACardState *dscm1xxxx_init(BlockDriverState *bdrv)
{
- struct md_s *md = (struct md_s *) qemu_mallocz(sizeof(struct md_s));
+ MicroDriveState *md = (MicroDriveState *) qemu_mallocz(sizeof(MicroDriveState));
md->card.state = md;
md->card.attach = dscm1xxxx_attach;
md->card.detach = dscm1xxxx_detach;