--- hw/ccid-card-emulated.c | 27 ++++++++++++------- hw/ccid-card-passthru.c | 27 ++++++++++++------- hw/ccid.h | 26 ++++++++----------- hw/usb-ccid.c | 63 ++++++++++++++++++++++++++++++++++------------ 4 files changed, 91 insertions(+), 52 deletions(-)
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c index 092301b..2748fd8 100644 --- a/hw/ccid-card-emulated.c +++ b/hw/ccid-card-emulated.c @@ -567,16 +567,23 @@ static int emulated_exitfn(CCIDCardState *base) return 0; } -static CCIDCardInfo emulated_card_info = { - .qdev.name = EMULATED_DEV_NAME, - .qdev.desc = "emulated smartcard", - .qdev.size = sizeof(EmulatedState), - .initfn = emulated_initfn, - .exitfn = emulated_exitfn, - .get_atr = emulated_get_atr, - .apdu_from_guest = emulated_apdu_from_guest, - .qdev.unplug = qdev_simple_unplug_cb, - .qdev.props = (Property[]) { +static void emulated_class_initfn(ObjectClass *klass, void *data) +{ + CCIDCardClass *cc = CCID_CARD_CLASS(klass); + + cc->initfn = emulated_initfn; + cc->exitfn = emulated_exitfn; + cc->get_atr = emulated_get_atr; + cc->apdu_from_guest = emulated_apdu_from_guest; +} + +static DeviceInfo emulated_card_info = { + .name = EMULATED_DEV_NAME, + .desc = "emulated smartcard", + .size = sizeof(EmulatedState), + .unplug = qdev_simple_unplug_cb, + .class_init = emulated_class_initfn, + .props = (Property[]) { DEFINE_PROP_STRING("backend", EmulatedState, backend_str), DEFINE_PROP_STRING("cert1", EmulatedState, cert1), DEFINE_PROP_STRING("cert2", EmulatedState, cert2), diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c index 9f51c6c..f563d97 100644 --- a/hw/ccid-card-passthru.c +++ b/hw/ccid-card-passthru.c @@ -316,16 +316,23 @@ static VMStateDescription passthru_vmstate = { } }; -static CCIDCardInfo passthru_card_info = { - .qdev.name = PASSTHRU_DEV_NAME, - .qdev.desc = "passthrough smartcard", - .qdev.size = sizeof(PassthruState), - .qdev.vmsd = &passthru_vmstate, - .initfn = passthru_initfn, - .exitfn = passthru_exitfn, - .get_atr = passthru_get_atr, - .apdu_from_guest = passthru_apdu_from_guest, - .qdev.props = (Property[]) { +static void passthru_class_initfn(ObjectClass *klass, void *data) +{ + CCIDCardClass *cc = CCID_CARD_CLASS(klass); + + cc->initfn = passthru_initfn; + cc->exitfn = passthru_exitfn; + cc->get_atr = passthru_get_atr; + cc->apdu_from_guest = passthru_apdu_from_guest; +} + +static DeviceInfo passthru_card_info = { + .name = PASSTHRU_DEV_NAME, + .desc = "passthrough smartcard", + .size = sizeof(PassthruState), + .vmsd = &passthru_vmstate, + .class_init = passthru_class_initfn, + .props = (Property[]) { DEFINE_PROP_CHR("chardev", PassthruState, cs), DEFINE_PROP_UINT8("debug", PassthruState, debug, 0), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/ccid.h b/hw/ccid.h index d8e0485..9e4979c 100644 --- a/hw/ccid.h +++ b/hw/ccid.h @@ -23,30 +23,26 @@ typedef struct CCIDCardInfo CCIDCardInfo; #define CCID_CARD_GET_CLASS(obj) \ OBJECT_GET_CLASS(CCIDCardClass, (obj), TYPE_CCID_CARD) -typedef struct CCIDCardClass { - DeviceClass parent_class; -} CCIDCardClass; - -/* - * state of the CCID Card device (i.e. hw/ccid-card-*.c) - */ -struct CCIDCardState { - DeviceState qdev; - uint32_t slot; /* For future use with multiple slot reader. */ -}; - /* * callbacks to be used by the CCID device (hw/usb-ccid.c) to call * into the smartcard device (hw/ccid-card-*.c) */ -struct CCIDCardInfo { - DeviceInfo qdev; +typedef struct CCIDCardClass { + DeviceClass parent_class; const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len); void (*apdu_from_guest)(CCIDCardState *card, const uint8_t *apdu, uint32_t len); int (*exitfn)(CCIDCardState *card); int (*initfn)(CCIDCardState *card); +} CCIDCardClass; + +/* + * state of the CCID Card device (i.e. hw/ccid-card-*.c) + */ +struct CCIDCardState { + DeviceState qdev; + uint32_t slot; /* For future use with multiple slot reader. */ }; /* @@ -58,7 +54,7 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card, void ccid_card_card_removed(CCIDCardState *card); void ccid_card_card_inserted(CCIDCardState *card); void ccid_card_card_error(CCIDCardState *card, uint64_t error); -void ccid_card_qdev_register(CCIDCardInfo *card); +void ccid_card_qdev_register(DeviceInfo *card); /* * support guest visible insertion/removal of ccid devices based on actual diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c index 41a53aa..a803c71 100644 --- a/hw/usb-ccid.c +++ b/hw/usb-ccid.c @@ -269,7 +269,6 @@ typedef struct USBCCIDState { USBDevice dev; CCIDBus bus; CCIDCardState *card; - CCIDCardInfo *cardinfo; /* caching the info pointer */ BulkIn bulk_in_pending[BULK_IN_PENDING_NUM]; /* circular */ uint32_t bulk_in_pending_start; uint32_t bulk_in_pending_end; /* first free */ @@ -468,6 +467,43 @@ static const USBDesc desc_ccid = { .str = desc_strings, }; +static const uint8_t *ccid_card_get_atr(CCIDCardState *card, uint32_t *len) +{ + CCIDCardClass *cc = CCID_CARD_GET_CLASS(card); + if (cc->get_atr) { + return cc->get_atr(card, len); + } + return NULL; +} + +static void ccid_card_apdu_from_guest(CCIDCardState *card, + const uint8_t *apdu, + uint32_t len) +{ + CCIDCardClass *cc = CCID_CARD_GET_CLASS(card); + if (cc->apdu_from_guest) { + cc->apdu_from_guest(card, apdu, len); + } +} + +static int ccid_card_exitfn(CCIDCardState *card) +{ + CCIDCardClass *cc = CCID_CARD_GET_CLASS(card); + if (cc->exitfn) { + return cc->exitfn(card); + } + return 0; +} + +static int ccid_card_initfn(CCIDCardState *card) +{ + CCIDCardClass *cc = CCID_CARD_GET_CLASS(card); + if (cc->initfn) { + return cc->initfn(card); + } + return 0; +} + static bool ccid_has_pending_answers(USBCCIDState *s) { return s->pending_answers_num > 0; @@ -749,7 +785,7 @@ static void ccid_write_data_block_atr(USBCCIDState *s, CCID_Header *recv) uint32_t len = 0; if (s->card) { - atr = s->cardinfo->get_atr(s->card, &len); + atr = ccid_card_get_atr(s->card, &len); } ccid_write_data_block(s, recv->bSlot, recv->bSeq, atr, len); } @@ -835,7 +871,7 @@ static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv) recv->hdr.bSeq, len); ccid_add_pending_answer(s, (CCID_Header *)recv); if (s->card) { - s->cardinfo->apdu_from_guest(s->card, recv->abData, len); + ccid_card_apdu_from_guest(s->card, recv->abData, len); } else { DPRINTF(s, D_WARN, "warning: discarded apdu\n"); } @@ -1122,25 +1158,20 @@ static int ccid_card_exit(DeviceState *qdev) { int ret = 0; CCIDCardState *card = CCID_CARD(qdev); - CCIDCardInfo *info = DO_UPCAST(CCIDCardInfo, qdev, qdev_get_info(qdev)); USBCCIDState *s = DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent); if (ccid_card_inserted(s)) { ccid_card_card_removed(card); } - if (info->exitfn) { - ret = info->exitfn(card); - } + ret = ccid_card_exitfn(card); s->card = NULL; - s->cardinfo = NULL; return ret; } static int ccid_card_init(DeviceState *qdev, DeviceInfo *base) { CCIDCardState *card = CCID_CARD(qdev); - CCIDCardInfo *info = DO_UPCAST(CCIDCardInfo, qdev, base); USBCCIDState *s = DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent); int ret = 0; @@ -1154,20 +1185,19 @@ static int ccid_card_init(DeviceState *qdev, DeviceInfo *base) error_report("Warning: usb-ccid card already full, not adding"); return -1; } - ret = info->initfn ? info->initfn(card) : ret; + ret = ccid_card_initfn(card); if (ret == 0) { s->card = card; - s->cardinfo = info; } return ret; } -void ccid_card_qdev_register(CCIDCardInfo *card) +void ccid_card_qdev_register(DeviceInfo *info) { - card->qdev.bus_info = &ccid_bus_info; - card->qdev.init = ccid_card_init; - card->qdev.exit = ccid_card_exit; - qdev_register_subclass(&card->qdev, TYPE_CCID_CARD); + info->bus_info = &ccid_bus_info; + info->init = ccid_card_init; + info->exit = ccid_card_exit; + qdev_register_subclass(info, TYPE_CCID_CARD); } static int ccid_initfn(USBDevice *dev) @@ -1178,7 +1208,6 @@ static int ccid_initfn(USBDevice *dev) qbus_create_inplace(&s->bus.qbus, &ccid_bus_info, &dev->qdev, NULL); s->bus.qbus.allow_hotplug = 1; s->card = NULL; - s->cardinfo = NULL; s->migration_state = MIGRATION_NONE; s->migration_target_ip = 0; s->migration_target_port = 0; -- 1.7.4.1