diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index 7692603..c080943 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -112,9 +112,9 @@ 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 *opaque, uint32_t at)
 {
-    MicroDriveState *s = opaque;
+    MicroDriveState *s = DO_UPCAST(MicroDriveState, card, opaque);
     if (at < s->attr_base) {
         if (at < s->card.cis_len)
             return s->card.cis[at];
@@ -145,9 +145,9 @@ 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 *opaque, uint32_t at, uint8_t value)
 {
-    MicroDriveState *s = opaque;
+    MicroDriveState *s = DO_UPCAST(MicroDriveState, card, opaque);
     at -= s->attr_base;
 
     switch (at) {
@@ -176,9 +176,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 *opaque, uint32_t at)
 {
-    MicroDriveState *s = opaque;
+    MicroDriveState *s = DO_UPCAST(MicroDriveState, card, opaque);
     IDEState *ifs;
     uint16_t ret;
     at -= s->io_base;
@@ -238,9 +238,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 *opaque, uint32_t at, uint16_t value)
 {
-    MicroDriveState *s = opaque;
+    MicroDriveState *s = DO_UPCAST(MicroDriveState, card, opaque);
     at -= s->io_base;
 
     switch (s->opt & OPT_MODE) {
@@ -502,15 +502,9 @@ static const uint8_t dscm1xxxx_cis[0x14a] = {
     [0x146] = CISTPL_END,	/* Tuple End */
 };
 
-static int dscm1xxxx_attach(void *opaque)
+static int dscm1xxxx_attach(PCMCIACardState *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;
+    MicroDriveState *md = DO_UPCAST(MicroDriveState, card, opaque);
 
     md->attr_base = md->card.cis[0x74] | (md->card.cis[0x76] << 8);
     md->io_base = 0x0;
@@ -522,9 +516,9 @@ static int dscm1xxxx_attach(void *opaque)
     return 0;
 }
 
-static int dscm1xxxx_detach(void *opaque)
+static int dscm1xxxx_detach(PCMCIACardState *opaque)
 {
-    MicroDriveState *md = opaque;
+    MicroDriveState *md = DO_UPCAST(MicroDriveState, card, opaque);
     md_reset(md);
     return 0;
 }
@@ -551,9 +545,6 @@ static int dscm1xxxx_initfn(PCMCIACardState *state)
     MicroDriveState *md;
     md = DO_UPCAST(MicroDriveState, card, state);
 
-    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);
 
@@ -570,6 +561,14 @@ static PCMCIACardInfo dscm1xxxx_info = {
     .init           = dscm1xxxx_initfn,
     .qdev.size      = sizeof(MicroDriveState),
     .qdev.vmsd      = &vmstate_microdrive,
+    .attach         = dscm1xxxx_attach,
+    .detach         = dscm1xxxx_detach,
+    .attr_read      = md_attr_read,
+    .attr_write     = md_attr_write,
+    .common_read    = md_common_read,
+    .common_write   = md_common_write,
+    .io_read        = md_common_read,
+    .io_write       = md_common_write,
 };
 
 static void dscm1xxxx_register(void)
diff --git a/hw/pcmcia.h b/hw/pcmcia.h
index c6b8100..2c012d9 100644
--- a/hw/pcmcia.h
+++ b/hw/pcmcia.h
@@ -3,13 +3,15 @@
 #include "qemu-common.h"
 #include "qdev.h"
 
-typedef struct {
+typedef struct PCMCIASocket PCMCIASocket;
+
+struct PCMCIASocket {
     BusState qbus;
     qemu_irq irq;
     int attached;
     const char *slot_string;
     const char *card_string;
-} PCMCIASocket;
+};
 
 void pcmcia_socket_register(PCMCIASocket *socket, DeviceState *parent);
 void pcmcia_socket_unregister(PCMCIASocket *socket);
@@ -19,26 +21,25 @@ typedef struct PCMCIACardInfo {
     DeviceInfo qdev;
 
     int (*init)(PCMCIACardState *state);
+
+    int (*attach)(PCMCIACardState *state);
+    int (*detach)(PCMCIACardState *state);
+
+    /* Only valid if attached */
+    uint8_t (*attr_read)(PCMCIACardState *state, uint32_t address);
+    void (*attr_write)(PCMCIACardState *state, uint32_t address, uint8_t value);
+    uint16_t (*common_read)(PCMCIACardState *state, uint32_t address);
+    void (*common_write)(PCMCIACardState *state, uint32_t address, uint16_t value);
+    uint16_t (*io_read)(PCMCIACardState *state, uint32_t address);
+    void (*io_write)(PCMCIACardState *state, uint32_t address, uint16_t value);
 } PCMCIACardInfo;
 
 struct PCMCIACardState {
     DeviceState dev;
     PCMCIACardInfo *info;
-
-    void *state;
     PCMCIASocket *slot;
-    int (*attach)(void *state);
-    int (*detach)(void *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);
 };
 
 void pcmcia_card_register(PCMCIACardInfo *info);
diff --git a/hw/pxa2xx_pcmcia.c b/hw/pxa2xx_pcmcia.c
index 61afaf1..ae7d01a 100644
--- a/hw/pxa2xx_pcmcia.c
+++ b/hw/pxa2xx_pcmcia.c
@@ -29,7 +29,7 @@ static uint32_t pxa2xx_pcmcia_common_read(void *opaque,
     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
     if (s->slot.attached) {
-        return s->card->common_read(s->card->state, offset);
+        return s->card->info->common_read(s->card, offset);
     }
 
     return 0;
@@ -41,7 +41,7 @@ static void pxa2xx_pcmcia_common_write(void *opaque,
     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
     if (s->slot.attached) {
-        s->card->common_write(s->card->state, offset, value);
+        s->card->info->common_write(s->card, offset, value);
     }
 }
 
@@ -51,7 +51,7 @@ static uint32_t pxa2xx_pcmcia_attr_read(void *opaque,
     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
     if (s->slot.attached) {
-        return s->card->attr_read(s->card->state, offset);
+        return s->card->info->attr_read(s->card, offset);
     }
 
     return 0;
@@ -63,7 +63,7 @@ static void pxa2xx_pcmcia_attr_write(void *opaque,
     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
     if (s->slot.attached) {
-        s->card->attr_write(s->card->state, offset, value);
+        s->card->info->attr_write(s->card, offset, value);
     }
 }
 
@@ -73,7 +73,7 @@ static uint32_t pxa2xx_pcmcia_io_read(void *opaque,
     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
     if (s->slot.attached) {
-        return s->card->io_read(s->card->state, offset);
+        return s->card->info->io_read(s->card, offset);
     }
 
     return 0;
@@ -85,7 +85,7 @@ static void pxa2xx_pcmcia_io_write(void *opaque,
     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
     if (s->slot.attached) {
-        s->card->io_write(s->card->state, offset, value);
+        s->card->info->io_write(s->card, offset, value);
     }
 }
 
@@ -206,7 +206,7 @@ int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
 
     s->slot.attached = 1;
     s->card->slot = &s->slot;
-    s->card->attach(s->card->state);
+    s->card->info->attach(s->card);
 
     return 0;
 }
@@ -218,7 +218,7 @@ int pxa2xx_pcmcia_dettach(void *opaque)
     if (!s->slot.attached)
         return -ENOENT;
 
-    s->card->detach(s->card->state);
+    s->card->info->detach(s->card);
     s->card->slot = NULL;
     s->card = NULL;
 
