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