pcmcia: QOM'ify PCMCIACardState and MicroDriveState
Turn PCMCIACardState into a device. Move callbacks to new PCMCIACardClass. Derive TYPE_MICRODRIVE from TYPE_PCMCIA_CARD. Replace ide_init2_with_non_qdev_drives(). Signed-off-by: Othmar Pasteka <pasteka@kabsi.at> Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
		
							parent
							
								
									853ca11daf
								
							
						
					
					
						commit
						d1f2c96a81
					
				| 
						 | 
				
			
			@ -18,6 +18,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += net/
 | 
			
		|||
devices-dirs-$(CONFIG_SOFTMMU) += nvram/
 | 
			
		||||
devices-dirs-$(CONFIG_SOFTMMU) += pci/
 | 
			
		||||
devices-dirs-$(CONFIG_PCI) += pci-bridge/ pci-host/
 | 
			
		||||
devices-dirs-$(CONFIG_SOFTMMU) += pcmcia/
 | 
			
		||||
devices-dirs-$(CONFIG_SOFTMMU) += scsi/
 | 
			
		||||
devices-dirs-$(CONFIG_SOFTMMU) += sd/
 | 
			
		||||
devices-dirs-$(CONFIG_SOFTMMU) += ssi/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,15 +30,22 @@
 | 
			
		|||
 | 
			
		||||
#include <hw/ide/internal.h>
 | 
			
		||||
 | 
			
		||||
#define TYPE_MICRODRIVE "microdrive"
 | 
			
		||||
#define MICRODRIVE(obj) OBJECT_CHECK(MicroDriveState, (obj), TYPE_MICRODRIVE)
 | 
			
		||||
 | 
			
		||||
/***********************************************************/
 | 
			
		||||
/* CF-ATA Microdrive */
 | 
			
		||||
 | 
			
		||||
#define METADATA_SIZE	0x20
 | 
			
		||||
 | 
			
		||||
/* DSCM-1XXXX Microdrive hard disk with CF+ II / PCMCIA interface.  */
 | 
			
		||||
typedef struct {
 | 
			
		||||
 | 
			
		||||
typedef struct MicroDriveState {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    PCMCIACardState parent_obj;
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
 | 
			
		||||
    IDEBus bus;
 | 
			
		||||
    PCMCIACardState card;
 | 
			
		||||
    uint32_t attr_base;
 | 
			
		||||
    uint32_t io_base;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -81,10 +88,13 @@ enum md_ctrl {
 | 
			
		|||
 | 
			
		||||
static inline void md_interrupt_update(MicroDriveState *s)
 | 
			
		||||
{
 | 
			
		||||
    if (!s->card.slot)
 | 
			
		||||
        return;
 | 
			
		||||
    PCMCIACardState *card = PCMCIA_CARD(s);
 | 
			
		||||
 | 
			
		||||
    qemu_set_irq(s->card.slot->irq,
 | 
			
		||||
    if (card->slot == NULL) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qemu_set_irq(card->slot->irq,
 | 
			
		||||
                    !(s->stat & STAT_INT) &&	/* Inverted */
 | 
			
		||||
                    !(s->ctrl & (CTRL_IEN | CTRL_SRST)) &&
 | 
			
		||||
                    !(s->opt & OPT_SRESET));
 | 
			
		||||
| 
						 | 
				
			
			@ -101,8 +111,10 @@ static void md_set_irq(void *opaque, int irq, int level)
 | 
			
		|||
    md_interrupt_update(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void md_reset(MicroDriveState *s)
 | 
			
		||||
static void md_reset(DeviceState *dev)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *s = MICRODRIVE(dev);
 | 
			
		||||
 | 
			
		||||
    s->opt = OPT_MODE_MMAP;
 | 
			
		||||
    s->stat = 0;
 | 
			
		||||
    s->pins = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -111,14 +123,17 @@ static void md_reset(MicroDriveState *s)
 | 
			
		|||
    ide_bus_reset(&s->bus);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8_t md_attr_read(void *opaque, uint32_t at)
 | 
			
		||||
static uint8_t md_attr_read(PCMCIACardState *card, uint32_t at)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *s = opaque;
 | 
			
		||||
    MicroDriveState *s = MICRODRIVE(card);
 | 
			
		||||
    PCMCIACardClass *pcc = PCMCIA_CARD_GET_CLASS(card);
 | 
			
		||||
 | 
			
		||||
    if (at < s->attr_base) {
 | 
			
		||||
        if (at < s->card.cis_len)
 | 
			
		||||
            return s->card.cis[at];
 | 
			
		||||
        else
 | 
			
		||||
        if (at < pcc->cis_len) {
 | 
			
		||||
            return pcc->cis[at];
 | 
			
		||||
        } else {
 | 
			
		||||
            return 0x00;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    at -= s->attr_base;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,16 +159,18 @@ static uint8_t md_attr_read(void *opaque, uint32_t at)
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void md_attr_write(void *opaque, uint32_t at, uint8_t value)
 | 
			
		||||
static void md_attr_write(PCMCIACardState *card, uint32_t at, uint8_t value)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *s = opaque;
 | 
			
		||||
    MicroDriveState *s = MICRODRIVE(card);
 | 
			
		||||
 | 
			
		||||
    at -= s->attr_base;
 | 
			
		||||
 | 
			
		||||
    switch (at) {
 | 
			
		||||
    case 0x00:	/* Configuration Option Register */
 | 
			
		||||
        s->opt = value & 0xcf;
 | 
			
		||||
        if (value & OPT_SRESET)
 | 
			
		||||
            md_reset(s);
 | 
			
		||||
        if (value & OPT_SRESET) {
 | 
			
		||||
            device_reset(DEVICE(s));
 | 
			
		||||
        }
 | 
			
		||||
        md_interrupt_update(s);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x02:	/* Card Configuration Status Register */
 | 
			
		||||
| 
						 | 
				
			
			@ -175,9 +192,9 @@ static void md_attr_write(void *opaque, uint32_t at, uint8_t value)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint16_t md_common_read(void *opaque, uint32_t at)
 | 
			
		||||
static uint16_t md_common_read(PCMCIACardState *card, uint32_t at)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *s = opaque;
 | 
			
		||||
    MicroDriveState *s = MICRODRIVE(card);
 | 
			
		||||
    IDEState *ifs;
 | 
			
		||||
    uint16_t ret;
 | 
			
		||||
    at -= s->io_base;
 | 
			
		||||
| 
						 | 
				
			
			@ -237,9 +254,9 @@ static uint16_t md_common_read(void *opaque, uint32_t at)
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void md_common_write(void *opaque, uint32_t at, uint16_t value)
 | 
			
		||||
static void md_common_write(PCMCIACardState *card, uint32_t at, uint16_t value)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *s = opaque;
 | 
			
		||||
    MicroDriveState *s = MICRODRIVE(card);
 | 
			
		||||
    at -= s->io_base;
 | 
			
		||||
 | 
			
		||||
    switch (s->opt & OPT_MODE) {
 | 
			
		||||
| 
						 | 
				
			
			@ -285,8 +302,9 @@ static void md_common_write(void *opaque, uint32_t at, uint16_t value)
 | 
			
		|||
        break;
 | 
			
		||||
    case 0xe:	/* Device Control */
 | 
			
		||||
        s->ctrl = value;
 | 
			
		||||
        if (value & CTRL_SRST)
 | 
			
		||||
            md_reset(s);
 | 
			
		||||
        if (value & CTRL_SRST) {
 | 
			
		||||
            device_reset(DEVICE(s));
 | 
			
		||||
        }
 | 
			
		||||
        md_interrupt_update(s);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -501,49 +519,107 @@ static const uint8_t dscm1xxxx_cis[0x14a] = {
 | 
			
		|||
    [0x146] = CISTPL_END,	/* Tuple End */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int dscm1xxxx_attach(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *md = opaque;
 | 
			
		||||
    md->card.attr_read = md_attr_read;
 | 
			
		||||
    md->card.attr_write = md_attr_write;
 | 
			
		||||
    md->card.common_read = md_common_read;
 | 
			
		||||
    md->card.common_write = md_common_write;
 | 
			
		||||
    md->card.io_read = md_common_read;
 | 
			
		||||
    md->card.io_write = md_common_write;
 | 
			
		||||
#define TYPE_DSCM1XXXX "dscm1xxxx"
 | 
			
		||||
 | 
			
		||||
    md->attr_base = md->card.cis[0x74] | (md->card.cis[0x76] << 8);
 | 
			
		||||
static int dscm1xxxx_attach(PCMCIACardState *card)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *md = MICRODRIVE(card);
 | 
			
		||||
    PCMCIACardClass *pcc = PCMCIA_CARD_GET_CLASS(card);
 | 
			
		||||
 | 
			
		||||
    md->attr_base = pcc->cis[0x74] | (pcc->cis[0x76] << 8);
 | 
			
		||||
    md->io_base = 0x0;
 | 
			
		||||
 | 
			
		||||
    md_reset(md);
 | 
			
		||||
    device_reset(DEVICE(md));
 | 
			
		||||
    md_interrupt_update(md);
 | 
			
		||||
 | 
			
		||||
    md->card.slot->card_string = "DSCM-1xxxx Hitachi Microdrive";
 | 
			
		||||
    card->slot->card_string = "DSCM-1xxxx Hitachi Microdrive";
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int dscm1xxxx_detach(void *opaque)
 | 
			
		||||
static int dscm1xxxx_detach(PCMCIACardState *card)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *md = opaque;
 | 
			
		||||
    md_reset(md);
 | 
			
		||||
    MicroDriveState *md = MICRODRIVE(card);
 | 
			
		||||
 | 
			
		||||
    device_reset(DEVICE(md));
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv)
 | 
			
		||||
PCMCIACardState *dscm1xxxx_init(DriveInfo *dinfo)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *md = (MicroDriveState *) g_malloc0(sizeof(MicroDriveState));
 | 
			
		||||
    md->card.state = md;
 | 
			
		||||
    md->card.attach = dscm1xxxx_attach;
 | 
			
		||||
    md->card.detach = dscm1xxxx_detach;
 | 
			
		||||
    md->card.cis = dscm1xxxx_cis;
 | 
			
		||||
    md->card.cis_len = sizeof(dscm1xxxx_cis);
 | 
			
		||||
    MicroDriveState *md = MICRODRIVE(object_new(TYPE_DSCM1XXXX));
 | 
			
		||||
    PCMCIACardState *card = PCMCIA_CARD(md);
 | 
			
		||||
 | 
			
		||||
    ide_init2_with_non_qdev_drives(&md->bus, bdrv, NULL,
 | 
			
		||||
                                   qemu_allocate_irqs(md_set_irq, md, 1)[0]);
 | 
			
		||||
    if (dinfo != NULL) {
 | 
			
		||||
        ide_create_drive(&md->bus, 0, dinfo);
 | 
			
		||||
    }
 | 
			
		||||
    md->bus.ifs[0].drive_kind = IDE_CFATA;
 | 
			
		||||
    md->bus.ifs[0].mdata_size = METADATA_SIZE;
 | 
			
		||||
    md->bus.ifs[0].mdata_storage = (uint8_t *) g_malloc0(METADATA_SIZE);
 | 
			
		||||
 | 
			
		||||
    vmstate_register(NULL, -1, &vmstate_microdrive, md);
 | 
			
		||||
 | 
			
		||||
    return &md->card;
 | 
			
		||||
    return card;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dscm1xxxx_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    PCMCIACardClass *pcc = PCMCIA_CARD_CLASS(oc);
 | 
			
		||||
 | 
			
		||||
    pcc->cis = dscm1xxxx_cis;
 | 
			
		||||
    pcc->cis_len = sizeof(dscm1xxxx_cis);
 | 
			
		||||
 | 
			
		||||
    pcc->attach = dscm1xxxx_attach;
 | 
			
		||||
    pcc->detach = dscm1xxxx_detach;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo dscm1xxxx_type_info = {
 | 
			
		||||
    .name = TYPE_DSCM1XXXX,
 | 
			
		||||
    .parent = TYPE_MICRODRIVE,
 | 
			
		||||
    .class_init = dscm1xxxx_class_init,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void microdrive_realize(DeviceState *dev, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *md = MICRODRIVE(dev);
 | 
			
		||||
 | 
			
		||||
    ide_init2(&md->bus, qemu_allocate_irqs(md_set_irq, md, 1)[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void microdrive_init(Object *obj)
 | 
			
		||||
{
 | 
			
		||||
    MicroDriveState *md = MICRODRIVE(obj);
 | 
			
		||||
 | 
			
		||||
    ide_bus_new(&md->bus, sizeof(md->bus), DEVICE(obj), 0, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void microdrive_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    DeviceClass *dc = DEVICE_CLASS(oc);
 | 
			
		||||
    PCMCIACardClass *pcc = PCMCIA_CARD_CLASS(oc);
 | 
			
		||||
 | 
			
		||||
    pcc->attr_read = md_attr_read;
 | 
			
		||||
    pcc->attr_write = md_attr_write;
 | 
			
		||||
    pcc->common_read = md_common_read;
 | 
			
		||||
    pcc->common_write = md_common_write;
 | 
			
		||||
    pcc->io_read = md_common_read;
 | 
			
		||||
    pcc->io_write = md_common_write;
 | 
			
		||||
 | 
			
		||||
    dc->realize = microdrive_realize;
 | 
			
		||||
    dc->reset = md_reset;
 | 
			
		||||
    dc->vmsd = &vmstate_microdrive;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo microdrive_type_info = {
 | 
			
		||||
    .name = TYPE_MICRODRIVE,
 | 
			
		||||
    .parent = TYPE_PCMCIA_CARD,
 | 
			
		||||
    .instance_size = sizeof(MicroDriveState),
 | 
			
		||||
    .instance_init = microdrive_init,
 | 
			
		||||
    .abstract = true,
 | 
			
		||||
    .class_init = microdrive_class_init,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void microdrive_register_types(void)
 | 
			
		||||
{
 | 
			
		||||
    type_register_static(µdrive_type_info);
 | 
			
		||||
    type_register_static(&dscm1xxxx_type_info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type_init(microdrive_register_types)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,6 @@ obj-$(CONFIG_OMAP) += omap_gpmc.o
 | 
			
		|||
obj-$(CONFIG_OMAP) += omap_l4.o
 | 
			
		||||
obj-$(CONFIG_OMAP) += omap_sdrc.o
 | 
			
		||||
obj-$(CONFIG_OMAP) += omap_tap.o
 | 
			
		||||
obj-$(CONFIG_PXA2XX) += pxa2xx_pcmcia.o
 | 
			
		||||
obj-$(CONFIG_SLAVIO) += slavio_misc.o
 | 
			
		||||
obj-$(CONFIG_ZYNQ) += zynq_slcr.o
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
common-obj-y += pcmcia.o
 | 
			
		||||
obj-$(CONFIG_PXA2XX) += pxa2xx.o
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
/*
 | 
			
		||||
 * PCMCIA emulation
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2013 SUSE LINUX Products GmbH
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "qemu-common.h"
 | 
			
		||||
#include "hw/hw.h"
 | 
			
		||||
#include "hw/pcmcia.h"
 | 
			
		||||
 | 
			
		||||
static const TypeInfo pcmcia_card_type_info = {
 | 
			
		||||
    .name = TYPE_PCMCIA_CARD,
 | 
			
		||||
    .parent = TYPE_DEVICE,
 | 
			
		||||
    .instance_size = sizeof(PCMCIACardState),
 | 
			
		||||
    .abstract = true,
 | 
			
		||||
    .class_size = sizeof(PCMCIACardClass),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void pcmcia_register_types(void)
 | 
			
		||||
{
 | 
			
		||||
    type_register_static(&pcmcia_card_type_info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type_init(pcmcia_register_types)
 | 
			
		||||
| 
						 | 
				
			
			@ -30,9 +30,11 @@ static uint64_t pxa2xx_pcmcia_common_read(void *opaque,
 | 
			
		|||
                hwaddr offset, unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | 
			
		||||
    PCMCIACardClass *pcc;
 | 
			
		||||
 | 
			
		||||
    if (s->slot.attached) {
 | 
			
		||||
        return s->card->common_read(s->card->state, offset);
 | 
			
		||||
        pcc = PCMCIA_CARD_GET_CLASS(s->card);
 | 
			
		||||
        return pcc->common_read(s->card, offset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -42,9 +44,11 @@ static void pxa2xx_pcmcia_common_write(void *opaque, hwaddr offset,
 | 
			
		|||
                                       uint64_t value, unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | 
			
		||||
    PCMCIACardClass *pcc;
 | 
			
		||||
 | 
			
		||||
    if (s->slot.attached) {
 | 
			
		||||
        s->card->common_write(s->card->state, offset, value);
 | 
			
		||||
        pcc = PCMCIA_CARD_GET_CLASS(s->card);
 | 
			
		||||
        pcc->common_write(s->card, offset, value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -52,9 +56,11 @@ static uint64_t pxa2xx_pcmcia_attr_read(void *opaque,
 | 
			
		|||
                hwaddr offset, unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | 
			
		||||
    PCMCIACardClass *pcc;
 | 
			
		||||
 | 
			
		||||
    if (s->slot.attached) {
 | 
			
		||||
        return s->card->attr_read(s->card->state, offset);
 | 
			
		||||
        pcc = PCMCIA_CARD_GET_CLASS(s->card);
 | 
			
		||||
        return pcc->attr_read(s->card, offset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -64,9 +70,11 @@ static void pxa2xx_pcmcia_attr_write(void *opaque, hwaddr offset,
 | 
			
		|||
                                     uint64_t value, unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | 
			
		||||
    PCMCIACardClass *pcc;
 | 
			
		||||
 | 
			
		||||
    if (s->slot.attached) {
 | 
			
		||||
        s->card->attr_write(s->card->state, offset, value);
 | 
			
		||||
        pcc = PCMCIA_CARD_GET_CLASS(s->card);
 | 
			
		||||
        pcc->attr_write(s->card, offset, value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -74,9 +82,11 @@ static uint64_t pxa2xx_pcmcia_io_read(void *opaque,
 | 
			
		|||
                hwaddr offset, unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | 
			
		||||
    PCMCIACardClass *pcc;
 | 
			
		||||
 | 
			
		||||
    if (s->slot.attached) {
 | 
			
		||||
        return s->card->io_read(s->card->state, offset);
 | 
			
		||||
        pcc = PCMCIA_CARD_GET_CLASS(s->card);
 | 
			
		||||
        return pcc->io_read(s->card, offset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -86,9 +96,11 @@ static void pxa2xx_pcmcia_io_write(void *opaque, hwaddr offset,
 | 
			
		|||
                                   uint64_t value, unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | 
			
		||||
    PCMCIACardClass *pcc;
 | 
			
		||||
 | 
			
		||||
    if (s->slot.attached) {
 | 
			
		||||
        s->card->io_write(s->card->state, offset, value);
 | 
			
		||||
        pcc = PCMCIA_CARD_GET_CLASS(s->card);
 | 
			
		||||
        pcc->io_write(s->card, offset, value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -161,18 +173,22 @@ PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
 | 
			
		|||
int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
 | 
			
		||||
{
 | 
			
		||||
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | 
			
		||||
    if (s->slot.attached)
 | 
			
		||||
    PCMCIACardClass *pcc;
 | 
			
		||||
 | 
			
		||||
    if (s->slot.attached) {
 | 
			
		||||
        return -EEXIST;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (s->cd_irq) {
 | 
			
		||||
        qemu_irq_raise(s->cd_irq);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->card = card;
 | 
			
		||||
    pcc = PCMCIA_CARD_GET_CLASS(s->card);
 | 
			
		||||
 | 
			
		||||
    s->slot.attached = 1;
 | 
			
		||||
    s->slot.attached = true;
 | 
			
		||||
    s->card->slot = &s->slot;
 | 
			
		||||
    s->card->attach(s->card->state);
 | 
			
		||||
    pcc->attach(s->card);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -181,19 +197,25 @@ int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
 | 
			
		|||
int pxa2xx_pcmcia_detach(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | 
			
		||||
    if (!s->slot.attached)
 | 
			
		||||
        return -ENOENT;
 | 
			
		||||
    PCMCIACardClass *pcc;
 | 
			
		||||
 | 
			
		||||
    s->card->detach(s->card->state);
 | 
			
		||||
    if (!s->slot.attached) {
 | 
			
		||||
        return -ENOENT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pcc = PCMCIA_CARD_GET_CLASS(s->card);
 | 
			
		||||
    pcc->detach(s->card);
 | 
			
		||||
    s->card->slot = NULL;
 | 
			
		||||
    s->card = NULL;
 | 
			
		||||
 | 
			
		||||
    s->slot.attached = 0;
 | 
			
		||||
    s->slot.attached = false;
 | 
			
		||||
 | 
			
		||||
    if (s->irq)
 | 
			
		||||
    if (s->irq) {
 | 
			
		||||
        qemu_irq_lower(s->irq);
 | 
			
		||||
    if (s->cd_irq)
 | 
			
		||||
    }
 | 
			
		||||
    if (s->cd_irq) {
 | 
			
		||||
        qemu_irq_lower(s->cd_irq);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,11 +3,11 @@
 | 
			
		|||
 | 
			
		||||
/* PCMCIA/Cardbus */
 | 
			
		||||
 | 
			
		||||
#include "qemu-common.h"
 | 
			
		||||
#include "hw/qdev.h"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
typedef struct PCMCIASocket {
 | 
			
		||||
    qemu_irq irq;
 | 
			
		||||
    int attached;
 | 
			
		||||
    bool attached;
 | 
			
		||||
    const char *slot_string;
 | 
			
		||||
    const char *card_string;
 | 
			
		||||
} PCMCIASocket;
 | 
			
		||||
| 
						 | 
				
			
			@ -16,22 +16,42 @@ void pcmcia_socket_register(PCMCIASocket *socket);
 | 
			
		|||
void pcmcia_socket_unregister(PCMCIASocket *socket);
 | 
			
		||||
void pcmcia_info(Monitor *mon, const QDict *qdict);
 | 
			
		||||
 | 
			
		||||
#define TYPE_PCMCIA_CARD "pcmcia-card"
 | 
			
		||||
#define PCMCIA_CARD(obj) \
 | 
			
		||||
    OBJECT_CHECK(PCMCIACardState, (obj), TYPE_PCMCIA_CARD)
 | 
			
		||||
#define PCMCIA_CARD_GET_CLASS(obj) \
 | 
			
		||||
    OBJECT_GET_CLASS(PCMCIACardClass, obj, TYPE_PCMCIA_CARD)
 | 
			
		||||
#define PCMCIA_CARD_CLASS(cls) \
 | 
			
		||||
    OBJECT_CLASS_CHECK(PCMCIACardClass, cls, TYPE_PCMCIA_CARD)
 | 
			
		||||
 | 
			
		||||
struct PCMCIACardState {
 | 
			
		||||
    void *state;
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    DeviceState parent_obj;
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
 | 
			
		||||
    PCMCIASocket *slot;
 | 
			
		||||
    int (*attach)(void *state);
 | 
			
		||||
    int (*detach)(void *state);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct PCMCIACardClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    DeviceClass parent_class;
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
 | 
			
		||||
    int (*attach)(PCMCIACardState *state);
 | 
			
		||||
    int (*detach)(PCMCIACardState *state);
 | 
			
		||||
 | 
			
		||||
    const uint8_t *cis;
 | 
			
		||||
    int cis_len;
 | 
			
		||||
 | 
			
		||||
    /* Only valid if attached */
 | 
			
		||||
    uint8_t (*attr_read)(void *state, uint32_t address);
 | 
			
		||||
    void (*attr_write)(void *state, uint32_t address, uint8_t value);
 | 
			
		||||
    uint16_t (*common_read)(void *state, uint32_t address);
 | 
			
		||||
    void (*common_write)(void *state, uint32_t address, uint16_t value);
 | 
			
		||||
    uint16_t (*io_read)(void *state, uint32_t address);
 | 
			
		||||
    void (*io_write)(void *state, uint32_t address, uint16_t value);
 | 
			
		||||
};
 | 
			
		||||
    uint8_t (*attr_read)(PCMCIACardState *card, uint32_t address);
 | 
			
		||||
    void (*attr_write)(PCMCIACardState *card, uint32_t address, uint8_t value);
 | 
			
		||||
    uint16_t (*common_read)(PCMCIACardState *card, uint32_t address);
 | 
			
		||||
    void (*common_write)(PCMCIACardState *card,
 | 
			
		||||
                         uint32_t address, uint16_t value);
 | 
			
		||||
    uint16_t (*io_read)(PCMCIACardState *card, uint32_t address);
 | 
			
		||||
    void (*io_write)(PCMCIACardState *card, uint32_t address, uint16_t value);
 | 
			
		||||
} PCMCIACardClass;
 | 
			
		||||
 | 
			
		||||
#define CISTPL_DEVICE		0x01	/* 5V Device Information Tuple */
 | 
			
		||||
#define CISTPL_NO_LINK		0x14	/* No Link Tuple */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue