1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#include "qemu/osdep.h"
38#include "qemu/units.h"
39#include "qapi/error.h"
40#include "qemu/cutils.h"
41#include "qemu/error-report.h"
42#include "qemu/module.h"
43#include "hw/qdev-properties.h"
44#include "hw/usb.h"
45#include "migration/vmstate.h"
46#include "desc.h"
47
48#include "ccid.h"
49#include "qom/object.h"
50
51#define DPRINTF(s, lvl, fmt, ...) \
52do { \
53 if (lvl <= s->debug) { \
54 printf("usb-ccid: " fmt , ## __VA_ARGS__); \
55 } \
56} while (0)
57
58#define D_WARN 1
59#define D_INFO 2
60#define D_MORE_INFO 3
61#define D_VERBOSE 4
62
63#define TYPE_USB_CCID_DEV "usb-ccid"
64OBJECT_DECLARE_SIMPLE_TYPE(USBCCIDState, USB_CCID_DEV)
65
66
67
68
69
70
71#define BULK_OUT_DATA_SIZE (64 * KiB)
72#define PENDING_ANSWERS_NUM 128
73
74#define BULK_IN_BUF_SIZE 384
75#define BULK_IN_PENDING_NUM 8
76
77#define CCID_MAX_PACKET_SIZE 64
78
79#define CCID_CONTROL_ABORT 0x1
80#define CCID_CONTROL_GET_CLOCK_FREQUENCIES 0x2
81#define CCID_CONTROL_GET_DATA_RATES 0x3
82
83#define CCID_PRODUCT_DESCRIPTION "QEMU USB CCID"
84#define CCID_VENDOR_DESCRIPTION "QEMU"
85#define CCID_INTERFACE_NAME "CCID Interface"
86#define CCID_SERIAL_NUMBER_STRING "1"
87
88
89
90
91
92
93
94#define CCID_VENDOR_ID 0x08e6
95#define CCID_PRODUCT_ID 0x4433
96#define CCID_DEVICE_VERSION 0x0000
97
98
99
100
101
102#define CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn 0x62
103#define CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff 0x63
104#define CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus 0x65
105#define CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock 0x6f
106#define CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters 0x6c
107#define CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters 0x6d
108#define CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters 0x61
109#define CCID_MESSAGE_TYPE_PC_to_RDR_Escape 0x6b
110#define CCID_MESSAGE_TYPE_PC_to_RDR_IccClock 0x6e
111#define CCID_MESSAGE_TYPE_PC_to_RDR_T0APDU 0x6a
112#define CCID_MESSAGE_TYPE_PC_to_RDR_Secure 0x69
113#define CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical 0x71
114#define CCID_MESSAGE_TYPE_PC_to_RDR_Abort 0x72
115#define CCID_MESSAGE_TYPE_PC_to_RDR_SetDataRateAndClockFrequency 0x73
116
117
118
119
120
121#define CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock 0x80
122#define CCID_MESSAGE_TYPE_RDR_to_PC_SlotStatus 0x81
123#define CCID_MESSAGE_TYPE_RDR_to_PC_Parameters 0x82
124#define CCID_MESSAGE_TYPE_RDR_to_PC_Escape 0x83
125#define CCID_MESSAGE_TYPE_RDR_to_PC_DataRateAndClockFrequency 0x84
126
127
128
129
130
131#define CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange 0x50
132#define CCID_MESSAGE_TYPE_RDR_to_PC_HardwareError 0x51
133
134
135
136
137
138
139
140#define CCID_INT_IN_EP 1
141#define CCID_BULK_IN_EP 2
142#define CCID_BULK_OUT_EP 3
143
144
145#define SLOT_0_STATE_MASK 1
146#define SLOT_0_CHANGED_MASK 2
147
148
149enum {
150 ICC_STATUS_PRESENT_ACTIVE = 0,
151 ICC_STATUS_PRESENT_INACTIVE,
152 ICC_STATUS_NOT_PRESENT
153};
154
155enum {
156 COMMAND_STATUS_NO_ERROR = 0,
157 COMMAND_STATUS_FAILED,
158 COMMAND_STATUS_TIME_EXTENSION_REQUIRED
159};
160
161
162enum {
163 ERROR_CMD_NOT_SUPPORTED = 0,
164 ERROR_CMD_ABORTED = -1,
165 ERROR_ICC_MUTE = -2,
166 ERROR_XFR_PARITY_ERROR = -3,
167 ERROR_XFR_OVERRUN = -4,
168 ERROR_HW_ERROR = -5,
169};
170
171
172enum {
173 CLOCK_STATUS_RUNNING = 0,
174
175
176
177
178};
179
180typedef struct QEMU_PACKED CCID_Header {
181 uint8_t bMessageType;
182 uint32_t dwLength;
183 uint8_t bSlot;
184 uint8_t bSeq;
185} CCID_Header;
186
187typedef struct QEMU_PACKED CCID_BULK_IN {
188 CCID_Header hdr;
189 uint8_t bStatus;
190 uint8_t bError;
191} CCID_BULK_IN;
192
193typedef struct QEMU_PACKED CCID_SlotStatus {
194 CCID_BULK_IN b;
195 uint8_t bClockStatus;
196} CCID_SlotStatus;
197
198typedef struct QEMU_PACKED CCID_T0ProtocolDataStructure {
199 uint8_t bmFindexDindex;
200 uint8_t bmTCCKST0;
201 uint8_t bGuardTimeT0;
202 uint8_t bWaitingIntegerT0;
203 uint8_t bClockStop;
204} CCID_T0ProtocolDataStructure;
205
206typedef struct QEMU_PACKED CCID_T1ProtocolDataStructure {
207 uint8_t bmFindexDindex;
208 uint8_t bmTCCKST1;
209 uint8_t bGuardTimeT1;
210 uint8_t bWaitingIntegerT1;
211 uint8_t bClockStop;
212 uint8_t bIFSC;
213 uint8_t bNadValue;
214} CCID_T1ProtocolDataStructure;
215
216typedef union CCID_ProtocolDataStructure {
217 CCID_T0ProtocolDataStructure t0;
218 CCID_T1ProtocolDataStructure t1;
219 uint8_t data[7];
220} CCID_ProtocolDataStructure;
221
222typedef struct QEMU_PACKED CCID_Parameter {
223 CCID_BULK_IN b;
224 uint8_t bProtocolNum;
225 CCID_ProtocolDataStructure abProtocolDataStructure;
226} CCID_Parameter;
227
228typedef struct QEMU_PACKED CCID_DataBlock {
229 CCID_BULK_IN b;
230 uint8_t bChainParameter;
231 uint8_t abData[];
232} CCID_DataBlock;
233
234
235typedef struct QEMU_PACKED CCID_XferBlock {
236 CCID_Header hdr;
237 uint8_t bBWI;
238 uint16_t wLevelParameter;
239 uint8_t abData[];
240} CCID_XferBlock;
241
242typedef struct QEMU_PACKED CCID_IccPowerOn {
243 CCID_Header hdr;
244 uint8_t bPowerSelect;
245 uint16_t abRFU;
246} CCID_IccPowerOn;
247
248typedef struct QEMU_PACKED CCID_IccPowerOff {
249 CCID_Header hdr;
250 uint16_t abRFU;
251} CCID_IccPowerOff;
252
253typedef struct QEMU_PACKED CCID_SetParameters {
254 CCID_Header hdr;
255 uint8_t bProtocolNum;
256 uint16_t abRFU;
257 CCID_ProtocolDataStructure abProtocolDataStructure;
258} CCID_SetParameters;
259
260typedef struct CCID_Notify_Slot_Change {
261 uint8_t bMessageType;
262 uint8_t bmSlotICCState;
263} CCID_Notify_Slot_Change;
264
265
266typedef struct Answer {
267 uint8_t slot;
268 uint8_t seq;
269} Answer;
270
271
272typedef struct BulkIn {
273 uint8_t data[BULK_IN_BUF_SIZE];
274 uint32_t len;
275 uint32_t pos;
276} BulkIn;
277
278struct CCIDBus {
279 BusState qbus;
280};
281
282#define TYPE_CCID_BUS "ccid-bus"
283OBJECT_DECLARE_SIMPLE_TYPE(CCIDBus, CCID_BUS)
284
285
286
287
288struct USBCCIDState {
289 USBDevice dev;
290 USBEndpoint *intr;
291 USBEndpoint *bulk;
292 CCIDBus bus;
293 CCIDCardState *card;
294 BulkIn bulk_in_pending[BULK_IN_PENDING_NUM];
295 uint32_t bulk_in_pending_start;
296 uint32_t bulk_in_pending_end;
297 uint32_t bulk_in_pending_num;
298 BulkIn *current_bulk_in;
299 uint8_t bulk_out_data[BULK_OUT_DATA_SIZE];
300 uint32_t bulk_out_pos;
301 uint64_t last_answer_error;
302 Answer pending_answers[PENDING_ANSWERS_NUM];
303 uint32_t pending_answers_start;
304 uint32_t pending_answers_end;
305 uint32_t pending_answers_num;
306 uint8_t bError;
307 uint8_t bmCommandStatus;
308 uint8_t bProtocolNum;
309 CCID_ProtocolDataStructure abProtocolDataStructure;
310 uint32_t ulProtocolDataStructureSize;
311 uint32_t state_vmstate;
312 uint8_t bmSlotICCState;
313 uint8_t powered;
314 uint8_t notify_slot_change;
315 uint8_t debug;
316};
317
318
319
320
321
322
323
324
325
326
327
328static const uint8_t qemu_ccid_descriptor[] = {
329
330 0x36,
331 0x21,
332 0x10, 0x01,
333 0x00,
334
335
336
337
338 0x07,
339
340 0x01, 0x00,
341 0x00, 0x00,
342
343 0xa0, 0x0f, 0x00, 0x00,
344
345 0x00, 0x00, 0x01, 0x00,
346 0x00,
347
348
349 0x80, 0x25, 0x00, 0x00,
350
351 0x00, 0xC2, 0x01, 0x00,
352 0x00,
353
354
355
356
357 0xfe, 0x00, 0x00, 0x00,
358
359 0x00, 0x00, 0x00, 0x00,
360
361 0x00, 0x00, 0x00, 0x00,
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 0xfe, 0x04, 0x01, 0x00,
385
386
387
388
389
390 0x12, 0x00, 0x01, 0x00,
391 0xFF,
392
393
394
395
396
397
398
399 0xFF,
400
401
402
403 0x00, 0x00,
404
405
406
407 0x01,
408
409
410
411 0x01,
412};
413
414enum {
415 STR_MANUFACTURER = 1,
416 STR_PRODUCT,
417 STR_SERIALNUMBER,
418 STR_INTERFACE,
419};
420
421static const USBDescStrings desc_strings = {
422 [STR_MANUFACTURER] = "QEMU",
423 [STR_PRODUCT] = "QEMU USB CCID",
424 [STR_SERIALNUMBER] = "1",
425 [STR_INTERFACE] = "CCID Interface",
426};
427
428static const USBDescIface desc_iface0 = {
429 .bInterfaceNumber = 0,
430 .bNumEndpoints = 3,
431 .bInterfaceClass = USB_CLASS_CSCID,
432 .bInterfaceSubClass = USB_SUBCLASS_UNDEFINED,
433 .bInterfaceProtocol = 0x00,
434 .iInterface = STR_INTERFACE,
435 .ndesc = 1,
436 .descs = (USBDescOther[]) {
437 {
438
439 .data = qemu_ccid_descriptor,
440 },
441 },
442 .eps = (USBDescEndpoint[]) {
443 {
444 .bEndpointAddress = USB_DIR_IN | CCID_INT_IN_EP,
445 .bmAttributes = USB_ENDPOINT_XFER_INT,
446 .bInterval = 255,
447 .wMaxPacketSize = 64,
448 },{
449 .bEndpointAddress = USB_DIR_IN | CCID_BULK_IN_EP,
450 .bmAttributes = USB_ENDPOINT_XFER_BULK,
451 .wMaxPacketSize = 64,
452 },{
453 .bEndpointAddress = USB_DIR_OUT | CCID_BULK_OUT_EP,
454 .bmAttributes = USB_ENDPOINT_XFER_BULK,
455 .wMaxPacketSize = 64,
456 },
457 }
458};
459
460static const USBDescDevice desc_device = {
461 .bcdUSB = 0x0110,
462 .bMaxPacketSize0 = 64,
463 .bNumConfigurations = 1,
464 .confs = (USBDescConfig[]) {
465 {
466 .bNumInterfaces = 1,
467 .bConfigurationValue = 1,
468 .bmAttributes = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER |
469 USB_CFG_ATT_WAKEUP,
470 .bMaxPower = 50,
471 .nif = 1,
472 .ifs = &desc_iface0,
473 },
474 },
475};
476
477static const USBDesc desc_ccid = {
478 .id = {
479 .idVendor = CCID_VENDOR_ID,
480 .idProduct = CCID_PRODUCT_ID,
481 .bcdDevice = CCID_DEVICE_VERSION,
482 .iManufacturer = STR_MANUFACTURER,
483 .iProduct = STR_PRODUCT,
484 .iSerialNumber = STR_SERIALNUMBER,
485 },
486 .full = &desc_device,
487 .str = desc_strings,
488};
489
490static const uint8_t *ccid_card_get_atr(CCIDCardState *card, uint32_t *len)
491{
492 CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
493
494 if (cc->get_atr) {
495 return cc->get_atr(card, len);
496 }
497 return NULL;
498}
499
500static void ccid_card_apdu_from_guest(CCIDCardState *card,
501 const uint8_t *apdu,
502 uint32_t len)
503{
504 CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
505
506 if (cc->apdu_from_guest) {
507 cc->apdu_from_guest(card, apdu, len);
508 }
509}
510
511static bool ccid_has_pending_answers(USBCCIDState *s)
512{
513 return s->pending_answers_num > 0;
514}
515
516static void ccid_clear_pending_answers(USBCCIDState *s)
517{
518 s->pending_answers_num = 0;
519 s->pending_answers_start = 0;
520 s->pending_answers_end = 0;
521}
522
523static void ccid_print_pending_answers(USBCCIDState *s)
524{
525 Answer *answer;
526 int i, count;
527
528 DPRINTF(s, D_VERBOSE, "usb-ccid: pending answers:");
529 if (!ccid_has_pending_answers(s)) {
530 DPRINTF(s, D_VERBOSE, " empty\n");
531 return;
532 }
533 for (i = s->pending_answers_start, count = s->pending_answers_num ;
534 count > 0; count--, i++) {
535 answer = &s->pending_answers[i % PENDING_ANSWERS_NUM];
536 if (count == 1) {
537 DPRINTF(s, D_VERBOSE, "%d:%d\n", answer->slot, answer->seq);
538 } else {
539 DPRINTF(s, D_VERBOSE, "%d:%d,", answer->slot, answer->seq);
540 }
541 }
542}
543
544static void ccid_add_pending_answer(USBCCIDState *s, CCID_Header *hdr)
545{
546 Answer *answer;
547
548 assert(s->pending_answers_num < PENDING_ANSWERS_NUM);
549 s->pending_answers_num++;
550 answer =
551 &s->pending_answers[(s->pending_answers_end++) % PENDING_ANSWERS_NUM];
552 answer->slot = hdr->bSlot;
553 answer->seq = hdr->bSeq;
554 ccid_print_pending_answers(s);
555}
556
557static void ccid_remove_pending_answer(USBCCIDState *s,
558 uint8_t *slot, uint8_t *seq)
559{
560 Answer *answer;
561
562 assert(s->pending_answers_num > 0);
563 s->pending_answers_num--;
564 answer =
565 &s->pending_answers[(s->pending_answers_start++) % PENDING_ANSWERS_NUM];
566 *slot = answer->slot;
567 *seq = answer->seq;
568 ccid_print_pending_answers(s);
569}
570
571static void ccid_bulk_in_clear(USBCCIDState *s)
572{
573 s->bulk_in_pending_start = 0;
574 s->bulk_in_pending_end = 0;
575 s->bulk_in_pending_num = 0;
576}
577
578static void ccid_bulk_in_release(USBCCIDState *s)
579{
580 assert(s->current_bulk_in != NULL);
581 s->current_bulk_in->pos = 0;
582 s->current_bulk_in = NULL;
583}
584
585static void ccid_bulk_in_get(USBCCIDState *s)
586{
587 if (s->current_bulk_in != NULL || s->bulk_in_pending_num == 0) {
588 return;
589 }
590 assert(s->bulk_in_pending_num > 0);
591 s->bulk_in_pending_num--;
592 s->current_bulk_in =
593 &s->bulk_in_pending[(s->bulk_in_pending_start++) % BULK_IN_PENDING_NUM];
594}
595
596static void *ccid_reserve_recv_buf(USBCCIDState *s, uint16_t len)
597{
598 BulkIn *bulk_in;
599
600 DPRINTF(s, D_VERBOSE, "%s: QUEUE: reserve %d bytes\n", __func__, len);
601
602
603 if (len > BULK_IN_BUF_SIZE) {
604 DPRINTF(s, D_WARN, "usb-ccid.c: %s: len larger then max (%d>%d). "
605 "discarding message.\n",
606 __func__, len, BULK_IN_BUF_SIZE);
607 return NULL;
608 }
609 if (s->bulk_in_pending_num >= BULK_IN_PENDING_NUM) {
610 DPRINTF(s, D_WARN, "usb-ccid.c: %s: No free bulk_in buffers. "
611 "discarding message.\n", __func__);
612 return NULL;
613 }
614 bulk_in =
615 &s->bulk_in_pending[(s->bulk_in_pending_end++) % BULK_IN_PENDING_NUM];
616 s->bulk_in_pending_num++;
617 bulk_in->len = len;
618 return bulk_in->data;
619}
620
621static void ccid_reset(USBCCIDState *s)
622{
623 ccid_bulk_in_clear(s);
624 ccid_clear_pending_answers(s);
625}
626
627static void ccid_detach(USBCCIDState *s)
628{
629 ccid_reset(s);
630}
631
632static void ccid_handle_reset(USBDevice *dev)
633{
634 USBCCIDState *s = USB_CCID_DEV(dev);
635
636 DPRINTF(s, 1, "Reset\n");
637
638 ccid_reset(s);
639}
640
641static const char *ccid_control_to_str(USBCCIDState *s, int request)
642{
643 switch (request) {
644
645 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
646 return "(generic) set address";
647 case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
648 return "(generic) get descriptor";
649 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
650 return "(generic) get configuration";
651 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
652 return "(generic) set configuration";
653 case DeviceRequest | USB_REQ_GET_STATUS:
654 return "(generic) get status";
655 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
656 return "(generic) clear feature";
657 case DeviceOutRequest | USB_REQ_SET_FEATURE:
658 return "(generic) set_feature";
659 case InterfaceRequest | USB_REQ_GET_INTERFACE:
660 return "(generic) get interface";
661 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
662 return "(generic) set interface";
663
664 case ClassInterfaceOutRequest | CCID_CONTROL_ABORT:
665 return "ABORT";
666 case ClassInterfaceRequest | CCID_CONTROL_GET_CLOCK_FREQUENCIES:
667 return "GET_CLOCK_FREQUENCIES";
668 case ClassInterfaceRequest | CCID_CONTROL_GET_DATA_RATES:
669 return "GET_DATA_RATES";
670 }
671 return "unknown";
672}
673
674static void ccid_handle_control(USBDevice *dev, USBPacket *p, int request,
675 int value, int index, int length, uint8_t *data)
676{
677 USBCCIDState *s = USB_CCID_DEV(dev);
678 int ret;
679
680 DPRINTF(s, 1, "%s: got control %s (%x), value %x\n", __func__,
681 ccid_control_to_str(s, request), request, value);
682 ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
683 if (ret >= 0) {
684 return;
685 }
686
687 switch (request) {
688
689 case ClassInterfaceOutRequest | CCID_CONTROL_ABORT:
690 DPRINTF(s, 1, "ccid_control abort UNIMPLEMENTED\n");
691 p->status = USB_RET_STALL;
692 break;
693 case ClassInterfaceRequest | CCID_CONTROL_GET_CLOCK_FREQUENCIES:
694 DPRINTF(s, 1, "ccid_control get clock frequencies UNIMPLEMENTED\n");
695 p->status = USB_RET_STALL;
696 break;
697 case ClassInterfaceRequest | CCID_CONTROL_GET_DATA_RATES:
698 DPRINTF(s, 1, "ccid_control get data rates UNIMPLEMENTED\n");
699 p->status = USB_RET_STALL;
700 break;
701 default:
702 DPRINTF(s, 1, "got unsupported/bogus control %x, value %x\n",
703 request, value);
704 p->status = USB_RET_STALL;
705 break;
706 }
707}
708
709static bool ccid_card_inserted(USBCCIDState *s)
710{
711 return s->bmSlotICCState & SLOT_0_STATE_MASK;
712}
713
714static uint8_t ccid_card_status(USBCCIDState *s)
715{
716 return ccid_card_inserted(s)
717 ? (s->powered ?
718 ICC_STATUS_PRESENT_ACTIVE
719 : ICC_STATUS_PRESENT_INACTIVE
720 )
721 : ICC_STATUS_NOT_PRESENT;
722}
723
724static uint8_t ccid_calc_status(USBCCIDState *s)
725{
726
727
728
729
730 uint8_t ret = ccid_card_status(s) | (s->bmCommandStatus << 6);
731 DPRINTF(s, D_VERBOSE, "%s: status = %d\n", __func__, ret);
732 return ret;
733}
734
735static void ccid_reset_error_status(USBCCIDState *s)
736{
737 s->bError = ERROR_CMD_NOT_SUPPORTED;
738 s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
739}
740
741static void ccid_write_slot_status(USBCCIDState *s, CCID_Header *recv)
742{
743 CCID_SlotStatus *h = ccid_reserve_recv_buf(s, sizeof(CCID_SlotStatus));
744 if (h == NULL) {
745 return;
746 }
747 h->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_SlotStatus;
748 h->b.hdr.dwLength = 0;
749 h->b.hdr.bSlot = recv->bSlot;
750 h->b.hdr.bSeq = recv->bSeq;
751 h->b.bStatus = ccid_calc_status(s);
752 h->b.bError = s->bError;
753 h->bClockStatus = CLOCK_STATUS_RUNNING;
754 ccid_reset_error_status(s);
755 usb_wakeup(s->bulk, 0);
756}
757
758static void ccid_write_parameters(USBCCIDState *s, CCID_Header *recv)
759{
760 CCID_Parameter *h;
761 uint32_t len = s->ulProtocolDataStructureSize;
762
763 h = ccid_reserve_recv_buf(s, sizeof(CCID_Parameter) + len);
764 if (h == NULL) {
765 return;
766 }
767 h->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_Parameters;
768 h->b.hdr.dwLength = 0;
769 h->b.hdr.bSlot = recv->bSlot;
770 h->b.hdr.bSeq = recv->bSeq;
771 h->b.bStatus = ccid_calc_status(s);
772 h->b.bError = s->bError;
773 h->bProtocolNum = s->bProtocolNum;
774 h->abProtocolDataStructure = s->abProtocolDataStructure;
775 ccid_reset_error_status(s);
776 usb_wakeup(s->bulk, 0);
777}
778
779static void ccid_write_data_block(USBCCIDState *s, uint8_t slot, uint8_t seq,
780 const uint8_t *data, uint32_t len)
781{
782 CCID_DataBlock *p = ccid_reserve_recv_buf(s, sizeof(*p) + len);
783
784 if (p == NULL) {
785 return;
786 }
787 p->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock;
788 p->b.hdr.dwLength = cpu_to_le32(len);
789 p->b.hdr.bSlot = slot;
790 p->b.hdr.bSeq = seq;
791 p->b.bStatus = ccid_calc_status(s);
792 p->b.bError = s->bError;
793 if (p->b.bError) {
794 DPRINTF(s, D_VERBOSE, "error %d\n", p->b.bError);
795 }
796 if (len) {
797 assert(data);
798 memcpy(p->abData, data, len);
799 }
800 ccid_reset_error_status(s);
801 usb_wakeup(s->bulk, 0);
802}
803
804static void ccid_report_error_failed(USBCCIDState *s, uint8_t error)
805{
806 s->bmCommandStatus = COMMAND_STATUS_FAILED;
807 s->bError = error;
808}
809
810static void ccid_write_data_block_answer(USBCCIDState *s,
811 const uint8_t *data, uint32_t len)
812{
813 uint8_t seq;
814 uint8_t slot;
815
816 if (!ccid_has_pending_answers(s)) {
817 DPRINTF(s, D_WARN, "error: no pending answer to return to guest\n");
818 ccid_report_error_failed(s, ERROR_ICC_MUTE);
819 return;
820 }
821 ccid_remove_pending_answer(s, &slot, &seq);
822 ccid_write_data_block(s, slot, seq, data, len);
823}
824
825static uint8_t atr_get_protocol_num(const uint8_t *atr, uint32_t len)
826{
827 int i;
828
829 if (len < 2 || !(atr[1] & 0x80)) {
830
831 return 0;
832 }
833 i = 1 + !!(atr[1] & 0x10) + !!(atr[1] & 0x20) + !!(atr[1] & 0x40);
834 i += !!(atr[1] & 0x80);
835 return atr[i] & 0x0f;
836}
837
838static void ccid_write_data_block_atr(USBCCIDState *s, CCID_Header *recv)
839{
840 const uint8_t *atr = NULL;
841 uint32_t len = 0;
842 uint8_t atr_protocol_num;
843 CCID_T0ProtocolDataStructure *t0 = &s->abProtocolDataStructure.t0;
844 CCID_T1ProtocolDataStructure *t1 = &s->abProtocolDataStructure.t1;
845
846 if (s->card) {
847 atr = ccid_card_get_atr(s->card, &len);
848 }
849 atr_protocol_num = atr_get_protocol_num(atr, len);
850 DPRINTF(s, D_VERBOSE, "%s: atr contains protocol=%d\n", __func__,
851 atr_protocol_num);
852
853 s->bProtocolNum = (atr_protocol_num <= 1 ? atr_protocol_num
854 : s->bProtocolNum);
855 switch (atr_protocol_num) {
856 case 0:
857
858 t0->bmFindexDindex = 0;
859 t0->bmTCCKST0 = 0;
860 t0->bGuardTimeT0 = 0;
861 t0->bWaitingIntegerT0 = 0;
862 t0->bClockStop = 0;
863 break;
864 case 1:
865
866 t1->bmFindexDindex = 0;
867 t1->bmTCCKST1 = 0;
868 t1->bGuardTimeT1 = 0;
869 t1->bWaitingIntegerT1 = 0;
870 t1->bClockStop = 0;
871 t1->bIFSC = 0;
872 t1->bNadValue = 0;
873 break;
874 default:
875 DPRINTF(s, D_WARN, "%s: error: unsupported ATR protocol %d\n",
876 __func__, atr_protocol_num);
877 }
878 ccid_write_data_block(s, recv->bSlot, recv->bSeq, atr, len);
879}
880
881static void ccid_set_parameters(USBCCIDState *s, CCID_Header *recv)
882{
883 CCID_SetParameters *ph = (CCID_SetParameters *) recv;
884 uint32_t protocol_num = ph->bProtocolNum & 3;
885
886 if (protocol_num != 0 && protocol_num != 1) {
887 ccid_report_error_failed(s, ERROR_CMD_NOT_SUPPORTED);
888 return;
889 }
890 s->bProtocolNum = protocol_num;
891 s->abProtocolDataStructure = ph->abProtocolDataStructure;
892}
893
894
895
896
897
898static const CCID_ProtocolDataStructure defaultProtocolDataStructure = {
899 .t1 = {
900 .bmFindexDindex = 0x77,
901 .bmTCCKST1 = 0x00,
902 .bGuardTimeT1 = 0x00,
903 .bWaitingIntegerT1 = 0x00,
904 .bClockStop = 0x00,
905 .bIFSC = 0xfe,
906 .bNadValue = 0x00,
907 }
908};
909
910static void ccid_reset_parameters(USBCCIDState *s)
911{
912 s->bProtocolNum = 0;
913 s->abProtocolDataStructure = defaultProtocolDataStructure;
914}
915
916
917static void ccid_on_slot_change(USBCCIDState *s, bool full)
918{
919
920 uint8_t current = s->bmSlotICCState;
921 if (full) {
922 s->bmSlotICCState |= SLOT_0_STATE_MASK;
923 } else {
924 s->bmSlotICCState &= ~SLOT_0_STATE_MASK;
925 }
926 if (current != s->bmSlotICCState) {
927 s->bmSlotICCState |= SLOT_0_CHANGED_MASK;
928 }
929 s->notify_slot_change = true;
930 usb_wakeup(s->intr, 0);
931}
932
933static void ccid_write_data_block_error(
934 USBCCIDState *s, uint8_t slot, uint8_t seq)
935{
936 ccid_write_data_block(s, slot, seq, NULL, 0);
937}
938
939static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv)
940{
941 uint32_t len;
942
943 if (ccid_card_status(s) != ICC_STATUS_PRESENT_ACTIVE) {
944 DPRINTF(s, 1,
945 "usb-ccid: not sending apdu to client, no card connected\n");
946 ccid_write_data_block_error(s, recv->hdr.bSlot, recv->hdr.bSeq);
947 return;
948 }
949 len = le32_to_cpu(recv->hdr.dwLength);
950 DPRINTF(s, 1, "%s: seq %d, len %u\n", __func__,
951 recv->hdr.bSeq, len);
952 ccid_add_pending_answer(s, (CCID_Header *)recv);
953 if (s->card && len <= BULK_OUT_DATA_SIZE) {
954 ccid_card_apdu_from_guest(s->card, recv->abData, len);
955 } else {
956 DPRINTF(s, D_WARN, "warning: discarded apdu\n");
957 }
958}
959
960static const char *ccid_message_type_to_str(uint8_t type)
961{
962 switch (type) {
963 case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn: return "IccPowerOn";
964 case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff: return "IccPowerOff";
965 case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus: return "GetSlotStatus";
966 case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock: return "XfrBlock";
967 case CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters: return "GetParameters";
968 case CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters: return "ResetParameters";
969 case CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters: return "SetParameters";
970 case CCID_MESSAGE_TYPE_PC_to_RDR_Escape: return "Escape";
971 case CCID_MESSAGE_TYPE_PC_to_RDR_IccClock: return "IccClock";
972 case CCID_MESSAGE_TYPE_PC_to_RDR_T0APDU: return "T0APDU";
973 case CCID_MESSAGE_TYPE_PC_to_RDR_Secure: return "Secure";
974 case CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical: return "Mechanical";
975 case CCID_MESSAGE_TYPE_PC_to_RDR_Abort: return "Abort";
976 case CCID_MESSAGE_TYPE_PC_to_RDR_SetDataRateAndClockFrequency:
977 return "SetDataRateAndClockFrequency";
978 }
979 return "unknown";
980}
981
982static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p)
983{
984 CCID_Header *ccid_header;
985
986 if (p->iov.size + s->bulk_out_pos > BULK_OUT_DATA_SIZE) {
987 goto err;
988 }
989 usb_packet_copy(p, s->bulk_out_data + s->bulk_out_pos, p->iov.size);
990 s->bulk_out_pos += p->iov.size;
991 if (s->bulk_out_pos < 10) {
992 DPRINTF(s, 1, "%s: header incomplete\n", __func__);
993 goto err;
994 }
995
996 ccid_header = (CCID_Header *)s->bulk_out_data;
997 if ((s->bulk_out_pos - 10 < ccid_header->dwLength) &&
998 (p->iov.size == CCID_MAX_PACKET_SIZE)) {
999 DPRINTF(s, D_VERBOSE,
1000 "usb-ccid: bulk_in: expecting more packets (%u/%u)\n",
1001 s->bulk_out_pos - 10, ccid_header->dwLength);
1002 return;
1003 }
1004 if (s->bulk_out_pos - 10 != ccid_header->dwLength) {
1005 DPRINTF(s, 1,
1006 "usb-ccid: bulk_in: message size mismatch (got %u, expected %u)\n",
1007 s->bulk_out_pos - 10, ccid_header->dwLength);
1008 goto err;
1009 }
1010
1011 DPRINTF(s, D_MORE_INFO, "%s %x %s\n", __func__,
1012 ccid_header->bMessageType,
1013 ccid_message_type_to_str(ccid_header->bMessageType));
1014 switch (ccid_header->bMessageType) {
1015 case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus:
1016 ccid_write_slot_status(s, ccid_header);
1017 break;
1018 case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn:
1019 DPRINTF(s, 1, "%s: PowerOn: %d\n", __func__,
1020 ((CCID_IccPowerOn *)(ccid_header))->bPowerSelect);
1021 s->powered = true;
1022 if (!ccid_card_inserted(s)) {
1023 ccid_report_error_failed(s, ERROR_ICC_MUTE);
1024 }
1025
1026 ccid_write_data_block_atr(s, ccid_header);
1027 break;
1028 case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff:
1029 ccid_reset_error_status(s);
1030 s->powered = false;
1031 ccid_write_slot_status(s, ccid_header);
1032 break;
1033 case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock:
1034 ccid_on_apdu_from_guest(s, (CCID_XferBlock *)s->bulk_out_data);
1035 break;
1036 case CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters:
1037 ccid_reset_error_status(s);
1038 ccid_set_parameters(s, ccid_header);
1039 ccid_write_parameters(s, ccid_header);
1040 break;
1041 case CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters:
1042 ccid_reset_error_status(s);
1043 ccid_reset_parameters(s);
1044 ccid_write_parameters(s, ccid_header);
1045 break;
1046 case CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters:
1047 ccid_reset_error_status(s);
1048 ccid_write_parameters(s, ccid_header);
1049 break;
1050 case CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical:
1051 ccid_report_error_failed(s, 0);
1052 ccid_write_slot_status(s, ccid_header);
1053 break;
1054 default:
1055 DPRINTF(s, 1,
1056 "handle_data: ERROR: unhandled message type %Xh\n",
1057 ccid_header->bMessageType);
1058
1059
1060
1061
1062 ccid_report_error_failed(s, ERROR_CMD_NOT_SUPPORTED);
1063 ccid_write_slot_status(s, ccid_header);
1064 break;
1065 }
1066 s->bulk_out_pos = 0;
1067 return;
1068
1069err:
1070 p->status = USB_RET_STALL;
1071 s->bulk_out_pos = 0;
1072 return;
1073}
1074
1075static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p,
1076 unsigned int max_packet_size)
1077{
1078 int len = 0;
1079
1080 ccid_bulk_in_get(s);
1081 if (s->current_bulk_in != NULL) {
1082 len = MIN(s->current_bulk_in->len - s->current_bulk_in->pos,
1083 p->iov.size);
1084 if (len) {
1085 usb_packet_copy(p, s->current_bulk_in->data +
1086 s->current_bulk_in->pos, len);
1087 }
1088 s->current_bulk_in->pos += len;
1089 if (s->current_bulk_in->pos == s->current_bulk_in->len
1090 && len != max_packet_size) {
1091 ccid_bulk_in_release(s);
1092 }
1093 } else {
1094
1095 p->status = USB_RET_NAK;
1096 }
1097 if (len) {
1098 DPRINTF(s, D_MORE_INFO,
1099 "%s: %zd/%d req/act to guest (BULK_IN)\n",
1100 __func__, p->iov.size, len);
1101 }
1102 if (len < p->iov.size) {
1103 DPRINTF(s, 1,
1104 "%s: returning short (EREMOTEIO) %d < %zd\n",
1105 __func__, len, p->iov.size);
1106 }
1107}
1108
1109static void ccid_handle_data(USBDevice *dev, USBPacket *p)
1110{
1111 USBCCIDState *s = USB_CCID_DEV(dev);
1112 uint8_t buf[2];
1113
1114 switch (p->pid) {
1115 case USB_TOKEN_OUT:
1116 ccid_handle_bulk_out(s, p);
1117 break;
1118
1119 case USB_TOKEN_IN:
1120 switch (p->ep->nr) {
1121 case CCID_BULK_IN_EP:
1122 ccid_bulk_in_copy_to_guest(s, p, dev->ep_ctl.max_packet_size);
1123 break;
1124 case CCID_INT_IN_EP:
1125 if (s->notify_slot_change) {
1126
1127 buf[0] = CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange;
1128 buf[1] = s->bmSlotICCState;
1129 usb_packet_copy(p, buf, 2);
1130 s->notify_slot_change = false;
1131 s->bmSlotICCState &= ~SLOT_0_CHANGED_MASK;
1132 DPRINTF(s, D_INFO,
1133 "handle_data: int_in: notify_slot_change %X, "
1134 "requested len %zd\n",
1135 s->bmSlotICCState, p->iov.size);
1136 } else {
1137 p->status = USB_RET_NAK;
1138 }
1139 break;
1140 default:
1141 DPRINTF(s, 1, "Bad endpoint\n");
1142 p->status = USB_RET_STALL;
1143 break;
1144 }
1145 break;
1146 default:
1147 DPRINTF(s, 1, "Bad token\n");
1148 p->status = USB_RET_STALL;
1149 break;
1150 }
1151}
1152
1153static void ccid_unrealize(USBDevice *dev)
1154{
1155 USBCCIDState *s = USB_CCID_DEV(dev);
1156
1157 ccid_bulk_in_clear(s);
1158}
1159
1160static void ccid_flush_pending_answers(USBCCIDState *s)
1161{
1162 while (ccid_has_pending_answers(s)) {
1163 ccid_write_data_block_answer(s, NULL, 0);
1164 }
1165}
1166
1167static Answer *ccid_peek_next_answer(USBCCIDState *s)
1168{
1169 return s->pending_answers_num == 0
1170 ? NULL
1171 : &s->pending_answers[s->pending_answers_start % PENDING_ANSWERS_NUM];
1172}
1173
1174static Property ccid_props[] = {
1175 DEFINE_PROP_UINT32("slot", struct CCIDCardState, slot, 0),
1176 DEFINE_PROP_END_OF_LIST(),
1177};
1178
1179static const TypeInfo ccid_bus_info = {
1180 .name = TYPE_CCID_BUS,
1181 .parent = TYPE_BUS,
1182 .instance_size = sizeof(CCIDBus),
1183};
1184
1185void ccid_card_send_apdu_to_guest(CCIDCardState *card,
1186 uint8_t *apdu, uint32_t len)
1187{
1188 DeviceState *qdev = DEVICE(card);
1189 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1190 USBCCIDState *s = USB_CCID_DEV(dev);
1191 Answer *answer;
1192
1193 if (!ccid_has_pending_answers(s)) {
1194 DPRINTF(s, 1, "CCID ERROR: got an APDU without pending answers\n");
1195 return;
1196 }
1197 s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
1198 answer = ccid_peek_next_answer(s);
1199 if (answer == NULL) {
1200 DPRINTF(s, D_WARN, "%s: error: unexpected lack of answer\n", __func__);
1201 ccid_report_error_failed(s, ERROR_HW_ERROR);
1202 return;
1203 }
1204 DPRINTF(s, 1, "APDU returned to guest %u (answer seq %d, slot %d)\n",
1205 len, answer->seq, answer->slot);
1206 ccid_write_data_block_answer(s, apdu, len);
1207}
1208
1209void ccid_card_card_removed(CCIDCardState *card)
1210{
1211 DeviceState *qdev = DEVICE(card);
1212 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1213 USBCCIDState *s = USB_CCID_DEV(dev);
1214
1215 ccid_on_slot_change(s, false);
1216 ccid_flush_pending_answers(s);
1217 ccid_reset(s);
1218}
1219
1220int ccid_card_ccid_attach(CCIDCardState *card)
1221{
1222 DeviceState *qdev = DEVICE(card);
1223 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1224 USBCCIDState *s = USB_CCID_DEV(dev);
1225
1226 DPRINTF(s, 1, "CCID Attach\n");
1227 return 0;
1228}
1229
1230void ccid_card_ccid_detach(CCIDCardState *card)
1231{
1232 DeviceState *qdev = DEVICE(card);
1233 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1234 USBCCIDState *s = USB_CCID_DEV(dev);
1235
1236 DPRINTF(s, 1, "CCID Detach\n");
1237 if (ccid_card_inserted(s)) {
1238 ccid_on_slot_change(s, false);
1239 }
1240 ccid_detach(s);
1241}
1242
1243void ccid_card_card_error(CCIDCardState *card, uint64_t error)
1244{
1245 DeviceState *qdev = DEVICE(card);
1246 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1247 USBCCIDState *s = USB_CCID_DEV(dev);
1248
1249 s->bmCommandStatus = COMMAND_STATUS_FAILED;
1250 s->last_answer_error = error;
1251 DPRINTF(s, 1, "VSC_Error: %" PRIX64 "\n", s->last_answer_error);
1252
1253
1254
1255
1256
1257 if (ccid_has_pending_answers(s)) {
1258 ccid_write_data_block_answer(s, NULL, 0);
1259 }
1260}
1261
1262void ccid_card_card_inserted(CCIDCardState *card)
1263{
1264 DeviceState *qdev = DEVICE(card);
1265 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1266 USBCCIDState *s = USB_CCID_DEV(dev);
1267
1268 s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
1269 ccid_flush_pending_answers(s);
1270 ccid_on_slot_change(s, true);
1271}
1272
1273static void ccid_card_unrealize(DeviceState *qdev)
1274{
1275 CCIDCardState *card = CCID_CARD(qdev);
1276 CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
1277 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1278 USBCCIDState *s = USB_CCID_DEV(dev);
1279
1280 if (ccid_card_inserted(s)) {
1281 ccid_card_card_removed(card);
1282 }
1283 if (cc->unrealize) {
1284 cc->unrealize(card);
1285 }
1286 s->card = NULL;
1287}
1288
1289static void ccid_card_realize(DeviceState *qdev, Error **errp)
1290{
1291 CCIDCardState *card = CCID_CARD(qdev);
1292 CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
1293 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1294 USBCCIDState *s = USB_CCID_DEV(dev);
1295 Error *local_err = NULL;
1296
1297 if (card->slot != 0) {
1298 error_setg(errp, "usb-ccid supports one slot, can't add %d",
1299 card->slot);
1300 return;
1301 }
1302 if (s->card != NULL) {
1303 error_setg(errp, "usb-ccid card already full, not adding");
1304 return;
1305 }
1306 if (cc->realize) {
1307 cc->realize(card, &local_err);
1308 if (local_err != NULL) {
1309 error_propagate(errp, local_err);
1310 return;
1311 }
1312 }
1313 s->card = card;
1314}
1315
1316static void ccid_realize(USBDevice *dev, Error **errp)
1317{
1318 USBCCIDState *s = USB_CCID_DEV(dev);
1319
1320 usb_desc_create_serial(dev);
1321 usb_desc_init(dev);
1322 qbus_init(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev), NULL);
1323 qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev));
1324 s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
1325 s->bulk = usb_ep_get(dev, USB_TOKEN_IN, CCID_BULK_IN_EP);
1326 s->card = NULL;
1327 s->dev.speed = USB_SPEED_FULL;
1328 s->dev.speedmask = USB_SPEED_MASK_FULL;
1329 s->notify_slot_change = false;
1330 s->powered = true;
1331 s->pending_answers_num = 0;
1332 s->last_answer_error = 0;
1333 s->bulk_in_pending_start = 0;
1334 s->bulk_in_pending_end = 0;
1335 s->current_bulk_in = NULL;
1336 ccid_reset_error_status(s);
1337 s->bulk_out_pos = 0;
1338 ccid_reset_parameters(s);
1339 ccid_reset(s);
1340 s->debug = parse_debug_env("QEMU_CCID_DEBUG", D_VERBOSE, s->debug);
1341}
1342
1343static int ccid_post_load(void *opaque, int version_id)
1344{
1345 USBCCIDState *s = opaque;
1346
1347
1348
1349
1350
1351
1352
1353 s->dev.state = s->state_vmstate;
1354 return 0;
1355}
1356
1357static int ccid_pre_save(void *opaque)
1358{
1359 USBCCIDState *s = opaque;
1360
1361 s->state_vmstate = s->dev.state;
1362
1363 return 0;
1364}
1365
1366static const VMStateDescription bulk_in_vmstate = {
1367 .name = "CCID BulkIn state",
1368 .version_id = 1,
1369 .minimum_version_id = 1,
1370 .fields = (VMStateField[]) {
1371 VMSTATE_BUFFER(data, BulkIn),
1372 VMSTATE_UINT32(len, BulkIn),
1373 VMSTATE_UINT32(pos, BulkIn),
1374 VMSTATE_END_OF_LIST()
1375 }
1376};
1377
1378static const VMStateDescription answer_vmstate = {
1379 .name = "CCID Answer state",
1380 .version_id = 1,
1381 .minimum_version_id = 1,
1382 .fields = (VMStateField[]) {
1383 VMSTATE_UINT8(slot, Answer),
1384 VMSTATE_UINT8(seq, Answer),
1385 VMSTATE_END_OF_LIST()
1386 }
1387};
1388
1389static const VMStateDescription usb_device_vmstate = {
1390 .name = "usb_device",
1391 .version_id = 1,
1392 .minimum_version_id = 1,
1393 .fields = (VMStateField[]) {
1394 VMSTATE_UINT8(addr, USBDevice),
1395 VMSTATE_BUFFER(setup_buf, USBDevice),
1396 VMSTATE_BUFFER(data_buf, USBDevice),
1397 VMSTATE_END_OF_LIST()
1398 }
1399};
1400
1401static const VMStateDescription ccid_vmstate = {
1402 .name = "usb-ccid",
1403 .version_id = 1,
1404 .minimum_version_id = 1,
1405 .post_load = ccid_post_load,
1406 .pre_save = ccid_pre_save,
1407 .fields = (VMStateField[]) {
1408 VMSTATE_STRUCT(dev, USBCCIDState, 1, usb_device_vmstate, USBDevice),
1409 VMSTATE_UINT8(debug, USBCCIDState),
1410 VMSTATE_BUFFER(bulk_out_data, USBCCIDState),
1411 VMSTATE_UINT32(bulk_out_pos, USBCCIDState),
1412 VMSTATE_UINT8(bmSlotICCState, USBCCIDState),
1413 VMSTATE_UINT8(powered, USBCCIDState),
1414 VMSTATE_UINT8(notify_slot_change, USBCCIDState),
1415 VMSTATE_UINT64(last_answer_error, USBCCIDState),
1416 VMSTATE_UINT8(bError, USBCCIDState),
1417 VMSTATE_UINT8(bmCommandStatus, USBCCIDState),
1418 VMSTATE_UINT8(bProtocolNum, USBCCIDState),
1419 VMSTATE_BUFFER(abProtocolDataStructure.data, USBCCIDState),
1420 VMSTATE_UINT32(ulProtocolDataStructureSize, USBCCIDState),
1421 VMSTATE_STRUCT_ARRAY(bulk_in_pending, USBCCIDState,
1422 BULK_IN_PENDING_NUM, 1, bulk_in_vmstate, BulkIn),
1423 VMSTATE_UINT32(bulk_in_pending_start, USBCCIDState),
1424 VMSTATE_UINT32(bulk_in_pending_end, USBCCIDState),
1425 VMSTATE_STRUCT_ARRAY(pending_answers, USBCCIDState,
1426 PENDING_ANSWERS_NUM, 1, answer_vmstate, Answer),
1427 VMSTATE_UINT32(pending_answers_num, USBCCIDState),
1428 VMSTATE_UNUSED(1),
1429 VMSTATE_UINT32(state_vmstate, USBCCIDState),
1430 VMSTATE_END_OF_LIST()
1431 }
1432};
1433
1434static Property ccid_properties[] = {
1435 DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0),
1436 DEFINE_PROP_END_OF_LIST(),
1437};
1438
1439static void ccid_class_initfn(ObjectClass *klass, void *data)
1440{
1441 DeviceClass *dc = DEVICE_CLASS(klass);
1442 USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1443 HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
1444
1445 uc->realize = ccid_realize;
1446 uc->product_desc = "QEMU USB CCID";
1447 uc->usb_desc = &desc_ccid;
1448 uc->handle_reset = ccid_handle_reset;
1449 uc->handle_control = ccid_handle_control;
1450 uc->handle_data = ccid_handle_data;
1451 uc->unrealize = ccid_unrealize;
1452 dc->desc = "CCID Rev 1.1 smartcard reader";
1453 dc->vmsd = &ccid_vmstate;
1454 device_class_set_props(dc, ccid_properties);
1455 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1456 hc->unplug = qdev_simple_device_unplug_cb;
1457}
1458
1459static const TypeInfo ccid_info = {
1460 .name = TYPE_USB_CCID_DEV,
1461 .parent = TYPE_USB_DEVICE,
1462 .instance_size = sizeof(USBCCIDState),
1463 .class_init = ccid_class_initfn,
1464 .interfaces = (InterfaceInfo[]) {
1465 { TYPE_HOTPLUG_HANDLER },
1466 { }
1467 }
1468};
1469
1470static void ccid_card_class_init(ObjectClass *klass, void *data)
1471{
1472 DeviceClass *k = DEVICE_CLASS(klass);
1473 k->bus_type = TYPE_CCID_BUS;
1474 k->realize = ccid_card_realize;
1475 k->unrealize = ccid_card_unrealize;
1476 device_class_set_props(k, ccid_props);
1477}
1478
1479static const TypeInfo ccid_card_type_info = {
1480 .name = TYPE_CCID_CARD,
1481 .parent = TYPE_DEVICE,
1482 .instance_size = sizeof(CCIDCardState),
1483 .abstract = true,
1484 .class_size = sizeof(CCIDCardClass),
1485 .class_init = ccid_card_class_init,
1486};
1487
1488static void ccid_register_types(void)
1489{
1490 type_register_static(&ccid_bus_info);
1491 type_register_static(&ccid_card_type_info);
1492 type_register_static(&ccid_info);
1493}
1494
1495type_init(ccid_register_types)
1496