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