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 int ccid_card_exitfn(CCIDCardState *card)
512{
513 CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
514
515 if (cc->exitfn) {
516 return cc->exitfn(card);
517 }
518 return 0;
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 memcpy(p->abData, data, len);
817 ccid_reset_error_status(s);
818 usb_wakeup(s->bulk, 0);
819}
820
821static void ccid_report_error_failed(USBCCIDState *s, uint8_t error)
822{
823 s->bmCommandStatus = COMMAND_STATUS_FAILED;
824 s->bError = error;
825}
826
827static void ccid_write_data_block_answer(USBCCIDState *s,
828 const uint8_t *data, uint32_t len)
829{
830 uint8_t seq;
831 uint8_t slot;
832
833 if (!ccid_has_pending_answers(s)) {
834 DPRINTF(s, D_WARN, "error: no pending answer to return to guest\n");
835 ccid_report_error_failed(s, ERROR_ICC_MUTE);
836 return;
837 }
838 ccid_remove_pending_answer(s, &slot, &seq);
839 ccid_write_data_block(s, slot, seq, data, len);
840}
841
842static uint8_t atr_get_protocol_num(const uint8_t *atr, uint32_t len)
843{
844 int i;
845
846 if (len < 2 || !(atr[1] & 0x80)) {
847
848 return 0;
849 }
850 i = 1 + !!(atr[1] & 0x10) + !!(atr[1] & 0x20) + !!(atr[1] & 0x40);
851 i += !!(atr[1] & 0x80);
852 return atr[i] & 0x0f;
853}
854
855static void ccid_write_data_block_atr(USBCCIDState *s, CCID_Header *recv)
856{
857 const uint8_t *atr = NULL;
858 uint32_t len = 0;
859 uint8_t atr_protocol_num;
860 CCID_T0ProtocolDataStructure *t0 = &s->abProtocolDataStructure.t0;
861 CCID_T1ProtocolDataStructure *t1 = &s->abProtocolDataStructure.t1;
862
863 if (s->card) {
864 atr = ccid_card_get_atr(s->card, &len);
865 }
866 atr_protocol_num = atr_get_protocol_num(atr, len);
867 DPRINTF(s, D_VERBOSE, "%s: atr contains protocol=%d\n", __func__,
868 atr_protocol_num);
869
870 s->bProtocolNum = (atr_protocol_num <= 1 ? atr_protocol_num
871 : s->bProtocolNum);
872 switch (atr_protocol_num) {
873 case 0:
874
875 t0->bmFindexDindex = 0;
876 t0->bmTCCKST0 = 0;
877 t0->bGuardTimeT0 = 0;
878 t0->bWaitingIntegerT0 = 0;
879 t0->bClockStop = 0;
880 break;
881 case 1:
882
883 t1->bmFindexDindex = 0;
884 t1->bmTCCKST1 = 0;
885 t1->bGuardTimeT1 = 0;
886 t1->bWaitingIntegerT1 = 0;
887 t1->bClockStop = 0;
888 t1->bIFSC = 0;
889 t1->bNadValue = 0;
890 break;
891 default:
892 DPRINTF(s, D_WARN, "%s: error: unsupported ATR protocol %d\n",
893 __func__, atr_protocol_num);
894 }
895 ccid_write_data_block(s, recv->bSlot, recv->bSeq, atr, len);
896}
897
898static void ccid_set_parameters(USBCCIDState *s, CCID_Header *recv)
899{
900 CCID_SetParameters *ph = (CCID_SetParameters *) recv;
901 uint32_t protocol_num = ph->bProtocolNum & 3;
902
903 if (protocol_num != 0 && protocol_num != 1) {
904 ccid_report_error_failed(s, ERROR_CMD_NOT_SUPPORTED);
905 return;
906 }
907 s->bProtocolNum = protocol_num;
908 s->abProtocolDataStructure = ph->abProtocolDataStructure;
909}
910
911
912
913
914
915static const CCID_ProtocolDataStructure defaultProtocolDataStructure = {
916 .t1 = {
917 .bmFindexDindex = 0x77,
918 .bmTCCKST1 = 0x00,
919 .bGuardTimeT1 = 0x00,
920 .bWaitingIntegerT1 = 0x00,
921 .bClockStop = 0x00,
922 .bIFSC = 0xfe,
923 .bNadValue = 0x00,
924 }
925};
926
927static void ccid_reset_parameters(USBCCIDState *s)
928{
929 s->bProtocolNum = 0;
930 s->abProtocolDataStructure = defaultProtocolDataStructure;
931}
932
933
934static void ccid_on_slot_change(USBCCIDState *s, bool full)
935{
936
937 uint8_t current = s->bmSlotICCState;
938 if (full) {
939 s->bmSlotICCState |= SLOT_0_STATE_MASK;
940 } else {
941 s->bmSlotICCState &= ~SLOT_0_STATE_MASK;
942 }
943 if (current != s->bmSlotICCState) {
944 s->bmSlotICCState |= SLOT_0_CHANGED_MASK;
945 }
946 s->notify_slot_change = true;
947 usb_wakeup(s->intr, 0);
948}
949
950static void ccid_write_data_block_error(
951 USBCCIDState *s, uint8_t slot, uint8_t seq)
952{
953 ccid_write_data_block(s, slot, seq, NULL, 0);
954}
955
956static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv)
957{
958 uint32_t len;
959
960 if (ccid_card_status(s) != ICC_STATUS_PRESENT_ACTIVE) {
961 DPRINTF(s, 1,
962 "usb-ccid: not sending apdu to client, no card connected\n");
963 ccid_write_data_block_error(s, recv->hdr.bSlot, recv->hdr.bSeq);
964 return;
965 }
966 len = le32_to_cpu(recv->hdr.dwLength);
967 DPRINTF(s, 1, "%s: seq %d, len %d\n", __func__,
968 recv->hdr.bSeq, len);
969 ccid_add_pending_answer(s, (CCID_Header *)recv);
970 if (s->card) {
971 ccid_card_apdu_from_guest(s->card, recv->abData, len);
972 } else {
973 DPRINTF(s, D_WARN, "warning: discarded apdu\n");
974 }
975}
976
977static const char *ccid_message_type_to_str(uint8_t type)
978{
979 switch (type) {
980 case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn: return "IccPowerOn";
981 case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff: return "IccPowerOff";
982 case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus: return "GetSlotStatus";
983 case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock: return "XfrBlock";
984 case CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters: return "GetParameters";
985 case CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters: return "ResetParameters";
986 case CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters: return "SetParameters";
987 case CCID_MESSAGE_TYPE_PC_to_RDR_Escape: return "Escape";
988 case CCID_MESSAGE_TYPE_PC_to_RDR_IccClock: return "IccClock";
989 case CCID_MESSAGE_TYPE_PC_to_RDR_T0APDU: return "T0APDU";
990 case CCID_MESSAGE_TYPE_PC_to_RDR_Secure: return "Secure";
991 case CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical: return "Mechanical";
992 case CCID_MESSAGE_TYPE_PC_to_RDR_Abort: return "Abort";
993 case CCID_MESSAGE_TYPE_PC_to_RDR_SetDataRateAndClockFrequency:
994 return "SetDataRateAndClockFrequency";
995 }
996 return "unknown";
997}
998
999static void ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p)
1000{
1001 CCID_Header *ccid_header;
1002
1003 if (p->iov.size + s->bulk_out_pos > BULK_OUT_DATA_SIZE) {
1004 p->status = USB_RET_STALL;
1005 return;
1006 }
1007 ccid_header = (CCID_Header *)s->bulk_out_data;
1008 usb_packet_copy(p, s->bulk_out_data + s->bulk_out_pos, p->iov.size);
1009 s->bulk_out_pos += p->iov.size;
1010 if (p->iov.size == CCID_MAX_PACKET_SIZE) {
1011 DPRINTF(s, D_VERBOSE,
1012 "usb-ccid: bulk_in: expecting more packets (%zd/%d)\n",
1013 p->iov.size, ccid_header->dwLength);
1014 return;
1015 }
1016 if (s->bulk_out_pos < 10) {
1017 DPRINTF(s, 1,
1018 "%s: bad USB_TOKEN_OUT length, should be at least 10 bytes\n",
1019 __func__);
1020 } else {
1021 DPRINTF(s, D_MORE_INFO, "%s %x %s\n", __func__,
1022 ccid_header->bMessageType,
1023 ccid_message_type_to_str(ccid_header->bMessageType));
1024 switch (ccid_header->bMessageType) {
1025 case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus:
1026 ccid_write_slot_status(s, ccid_header);
1027 break;
1028 case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn:
1029 DPRINTF(s, 1, "%s: PowerOn: %d\n", __func__,
1030 ((CCID_IccPowerOn *)(ccid_header))->bPowerSelect);
1031 s->powered = true;
1032 if (!ccid_card_inserted(s)) {
1033 ccid_report_error_failed(s, ERROR_ICC_MUTE);
1034 }
1035
1036 ccid_write_data_block_atr(s, ccid_header);
1037 break;
1038 case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff:
1039 ccid_reset_error_status(s);
1040 s->powered = false;
1041 ccid_write_slot_status(s, ccid_header);
1042 break;
1043 case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock:
1044 ccid_on_apdu_from_guest(s, (CCID_XferBlock *)s->bulk_out_data);
1045 break;
1046 case CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters:
1047 ccid_reset_error_status(s);
1048 ccid_set_parameters(s, ccid_header);
1049 ccid_write_parameters(s, ccid_header);
1050 break;
1051 case CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters:
1052 ccid_reset_error_status(s);
1053 ccid_reset_parameters(s);
1054 ccid_write_parameters(s, ccid_header);
1055 break;
1056 case CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters:
1057 ccid_reset_error_status(s);
1058 ccid_write_parameters(s, ccid_header);
1059 break;
1060 case CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical:
1061 ccid_report_error_failed(s, 0);
1062 ccid_write_slot_status(s, ccid_header);
1063 break;
1064 default:
1065 DPRINTF(s, 1,
1066 "handle_data: ERROR: unhandled message type %Xh\n",
1067 ccid_header->bMessageType);
1068
1069
1070
1071
1072 ccid_report_error_failed(s, ERROR_CMD_NOT_SUPPORTED);
1073 ccid_write_slot_status(s, ccid_header);
1074 break;
1075 }
1076 }
1077 s->bulk_out_pos = 0;
1078}
1079
1080static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p)
1081{
1082 int len = 0;
1083
1084 ccid_bulk_in_get(s);
1085 if (s->current_bulk_in != NULL) {
1086 len = MIN(s->current_bulk_in->len - s->current_bulk_in->pos,
1087 p->iov.size);
1088 usb_packet_copy(p, s->current_bulk_in->data +
1089 s->current_bulk_in->pos, len);
1090 s->current_bulk_in->pos += len;
1091 if (s->current_bulk_in->pos == s->current_bulk_in->len) {
1092 ccid_bulk_in_release(s);
1093 }
1094 } else {
1095
1096 p->status = USB_RET_NAK;
1097 }
1098 if (len) {
1099 DPRINTF(s, D_MORE_INFO,
1100 "%s: %zd/%d req/act to guest (BULK_IN)\n",
1101 __func__, p->iov.size, len);
1102 }
1103 if (len < p->iov.size) {
1104 DPRINTF(s, 1,
1105 "%s: returning short (EREMOTEIO) %d < %zd\n",
1106 __func__, len, p->iov.size);
1107 }
1108}
1109
1110static void ccid_handle_data(USBDevice *dev, USBPacket *p)
1111{
1112 USBCCIDState *s = USB_CCID_DEV(dev);
1113 uint8_t buf[2];
1114
1115 switch (p->pid) {
1116 case USB_TOKEN_OUT:
1117 ccid_handle_bulk_out(s, p);
1118 break;
1119
1120 case USB_TOKEN_IN:
1121 switch (p->ep->nr) {
1122 case CCID_BULK_IN_EP:
1123 ccid_bulk_in_copy_to_guest(s, p);
1124 break;
1125 case CCID_INT_IN_EP:
1126 if (s->notify_slot_change) {
1127
1128 buf[0] = CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange;
1129 buf[1] = s->bmSlotICCState;
1130 usb_packet_copy(p, buf, 2);
1131 s->notify_slot_change = false;
1132 s->bmSlotICCState &= ~SLOT_0_CHANGED_MASK;
1133 DPRINTF(s, D_INFO,
1134 "handle_data: int_in: notify_slot_change %X, "
1135 "requested len %zd\n",
1136 s->bmSlotICCState, p->iov.size);
1137 } else {
1138 p->status = USB_RET_NAK;
1139 }
1140 break;
1141 default:
1142 DPRINTF(s, 1, "Bad endpoint\n");
1143 p->status = USB_RET_STALL;
1144 break;
1145 }
1146 break;
1147 default:
1148 DPRINTF(s, 1, "Bad token\n");
1149 p->status = USB_RET_STALL;
1150 break;
1151 }
1152}
1153
1154static void ccid_handle_destroy(USBDevice *dev)
1155{
1156 USBCCIDState *s = USB_CCID_DEV(dev);
1157
1158 ccid_bulk_in_clear(s);
1159}
1160
1161static void ccid_flush_pending_answers(USBCCIDState *s)
1162{
1163 while (ccid_has_pending_answers(s)) {
1164 ccid_write_data_block_answer(s, NULL, 0);
1165 }
1166}
1167
1168static Answer *ccid_peek_next_answer(USBCCIDState *s)
1169{
1170 return s->pending_answers_num == 0
1171 ? NULL
1172 : &s->pending_answers[s->pending_answers_start % PENDING_ANSWERS_NUM];
1173}
1174
1175static Property ccid_props[] = {
1176 DEFINE_PROP_UINT32("slot", struct CCIDCardState, slot, 0),
1177 DEFINE_PROP_END_OF_LIST(),
1178};
1179
1180#define TYPE_CCID_BUS "ccid-bus"
1181#define CCID_BUS(obj) OBJECT_CHECK(CCIDBus, (obj), TYPE_CCID_BUS)
1182
1183static const TypeInfo ccid_bus_info = {
1184 .name = TYPE_CCID_BUS,
1185 .parent = TYPE_BUS,
1186 .instance_size = sizeof(CCIDBus),
1187};
1188
1189void ccid_card_send_apdu_to_guest(CCIDCardState *card,
1190 uint8_t *apdu, uint32_t len)
1191{
1192 DeviceState *qdev = DEVICE(card);
1193 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1194 USBCCIDState *s = USB_CCID_DEV(dev);
1195 Answer *answer;
1196
1197 if (!ccid_has_pending_answers(s)) {
1198 DPRINTF(s, 1, "CCID ERROR: got an APDU without pending answers\n");
1199 return;
1200 }
1201 s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
1202 answer = ccid_peek_next_answer(s);
1203 if (answer == NULL) {
1204 DPRINTF(s, D_WARN, "%s: error: unexpected lack of answer\n", __func__);
1205 ccid_report_error_failed(s, ERROR_HW_ERROR);
1206 return;
1207 }
1208 DPRINTF(s, 1, "APDU returned to guest %d (answer seq %d, slot %d)\n",
1209 len, answer->seq, answer->slot);
1210 ccid_write_data_block_answer(s, apdu, len);
1211}
1212
1213void ccid_card_card_removed(CCIDCardState *card)
1214{
1215 DeviceState *qdev = DEVICE(card);
1216 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1217 USBCCIDState *s = USB_CCID_DEV(dev);
1218
1219 ccid_on_slot_change(s, false);
1220 ccid_flush_pending_answers(s);
1221 ccid_reset(s);
1222}
1223
1224int ccid_card_ccid_attach(CCIDCardState *card)
1225{
1226 DeviceState *qdev = DEVICE(card);
1227 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1228 USBCCIDState *s = USB_CCID_DEV(dev);
1229
1230 DPRINTF(s, 1, "CCID Attach\n");
1231 if (s->migration_state == MIGRATION_MIGRATED) {
1232 s->migration_state = MIGRATION_NONE;
1233 }
1234 return 0;
1235}
1236
1237void ccid_card_ccid_detach(CCIDCardState *card)
1238{
1239 DeviceState *qdev = DEVICE(card);
1240 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1241 USBCCIDState *s = USB_CCID_DEV(dev);
1242
1243 DPRINTF(s, 1, "CCID Detach\n");
1244 if (ccid_card_inserted(s)) {
1245 ccid_on_slot_change(s, false);
1246 }
1247 ccid_detach(s);
1248}
1249
1250void ccid_card_card_error(CCIDCardState *card, uint64_t error)
1251{
1252 DeviceState *qdev = DEVICE(card);
1253 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1254 USBCCIDState *s = USB_CCID_DEV(dev);
1255
1256 s->bmCommandStatus = COMMAND_STATUS_FAILED;
1257 s->last_answer_error = error;
1258 DPRINTF(s, 1, "VSC_Error: %" PRIX64 "\n", s->last_answer_error);
1259
1260
1261
1262
1263
1264 if (ccid_has_pending_answers(s)) {
1265 ccid_write_data_block_answer(s, NULL, 0);
1266 }
1267}
1268
1269void ccid_card_card_inserted(CCIDCardState *card)
1270{
1271 DeviceState *qdev = DEVICE(card);
1272 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1273 USBCCIDState *s = USB_CCID_DEV(dev);
1274
1275 s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
1276 ccid_flush_pending_answers(s);
1277 ccid_on_slot_change(s, true);
1278}
1279
1280static int ccid_card_exit(DeviceState *qdev)
1281{
1282 int ret = 0;
1283 CCIDCardState *card = CCID_CARD(qdev);
1284 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
1285 USBCCIDState *s = USB_CCID_DEV(dev);
1286
1287 if (ccid_card_inserted(s)) {
1288 ccid_card_card_removed(card);
1289 }
1290 ret = ccid_card_exitfn(card);
1291 s->card = NULL;
1292 return ret;
1293}
1294
1295static int ccid_card_init(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 int ret = 0;
1301
1302 if (card->slot != 0) {
1303 error_report("Warning: usb-ccid supports one slot, can't add %d",
1304 card->slot);
1305 return -1;
1306 }
1307 if (s->card != NULL) {
1308 error_report("Warning: usb-ccid card already full, not adding");
1309 return -1;
1310 }
1311 ret = ccid_card_initfn(card);
1312 if (ret == 0) {
1313 s->card = card;
1314 }
1315 return ret;
1316}
1317
1318static void ccid_realize(USBDevice *dev, Error **errp)
1319{
1320 USBCCIDState *s = USB_CCID_DEV(dev);
1321
1322 usb_desc_create_serial(dev);
1323 usb_desc_init(dev);
1324 qbus_create_inplace(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev),
1325 NULL);
1326 qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(dev), &error_abort);
1327 s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
1328 s->bulk = usb_ep_get(dev, USB_TOKEN_IN, CCID_BULK_IN_EP);
1329 s->card = NULL;
1330 s->migration_state = MIGRATION_NONE;
1331 s->migration_target_ip = 0;
1332 s->migration_target_port = 0;
1333 s->dev.speed = USB_SPEED_FULL;
1334 s->dev.speedmask = USB_SPEED_MASK_FULL;
1335 s->notify_slot_change = false;
1336 s->powered = true;
1337 s->pending_answers_num = 0;
1338 s->last_answer_error = 0;
1339 s->bulk_in_pending_start = 0;
1340 s->bulk_in_pending_end = 0;
1341 s->current_bulk_in = NULL;
1342 ccid_reset_error_status(s);
1343 s->bulk_out_pos = 0;
1344 ccid_reset_parameters(s);
1345 ccid_reset(s);
1346 s->debug = parse_debug_env("QEMU_CCID_DEBUG", D_VERBOSE, s->debug);
1347}
1348
1349static int ccid_post_load(void *opaque, int version_id)
1350{
1351 USBCCIDState *s = opaque;
1352
1353
1354
1355
1356
1357
1358
1359 s->dev.state = s->state_vmstate;
1360 return 0;
1361}
1362
1363static void ccid_pre_save(void *opaque)
1364{
1365 USBCCIDState *s = opaque;
1366
1367 s->state_vmstate = s->dev.state;
1368 if (s->dev.attached) {
1369
1370
1371
1372
1373 s->migration_state = MIGRATION_MIGRATED;
1374 }
1375}
1376
1377static VMStateDescription bulk_in_vmstate = {
1378 .name = "CCID BulkIn state",
1379 .version_id = 1,
1380 .minimum_version_id = 1,
1381 .fields = (VMStateField[]) {
1382 VMSTATE_BUFFER(data, BulkIn),
1383 VMSTATE_UINT32(len, BulkIn),
1384 VMSTATE_UINT32(pos, BulkIn),
1385 VMSTATE_END_OF_LIST()
1386 }
1387};
1388
1389static VMStateDescription answer_vmstate = {
1390 .name = "CCID Answer state",
1391 .version_id = 1,
1392 .minimum_version_id = 1,
1393 .fields = (VMStateField[]) {
1394 VMSTATE_UINT8(slot, Answer),
1395 VMSTATE_UINT8(seq, Answer),
1396 VMSTATE_END_OF_LIST()
1397 }
1398};
1399
1400static VMStateDescription usb_device_vmstate = {
1401 .name = "usb_device",
1402 .version_id = 1,
1403 .minimum_version_id = 1,
1404 .fields = (VMStateField[]) {
1405 VMSTATE_UINT8(addr, USBDevice),
1406 VMSTATE_BUFFER(setup_buf, USBDevice),
1407 VMSTATE_BUFFER(data_buf, USBDevice),
1408 VMSTATE_END_OF_LIST()
1409 }
1410};
1411
1412static VMStateDescription ccid_vmstate = {
1413 .name = "usb-ccid",
1414 .version_id = 1,
1415 .minimum_version_id = 1,
1416 .post_load = ccid_post_load,
1417 .pre_save = ccid_pre_save,
1418 .fields = (VMStateField[]) {
1419 VMSTATE_STRUCT(dev, USBCCIDState, 1, usb_device_vmstate, USBDevice),
1420 VMSTATE_UINT8(debug, USBCCIDState),
1421 VMSTATE_BUFFER(bulk_out_data, USBCCIDState),
1422 VMSTATE_UINT32(bulk_out_pos, USBCCIDState),
1423 VMSTATE_UINT8(bmSlotICCState, USBCCIDState),
1424 VMSTATE_UINT8(powered, USBCCIDState),
1425 VMSTATE_UINT8(notify_slot_change, USBCCIDState),
1426 VMSTATE_UINT64(last_answer_error, USBCCIDState),
1427 VMSTATE_UINT8(bError, USBCCIDState),
1428 VMSTATE_UINT8(bmCommandStatus, USBCCIDState),
1429 VMSTATE_UINT8(bProtocolNum, USBCCIDState),
1430 VMSTATE_BUFFER(abProtocolDataStructure.data, USBCCIDState),
1431 VMSTATE_UINT32(ulProtocolDataStructureSize, USBCCIDState),
1432 VMSTATE_STRUCT_ARRAY(bulk_in_pending, USBCCIDState,
1433 BULK_IN_PENDING_NUM, 1, bulk_in_vmstate, BulkIn),
1434 VMSTATE_UINT32(bulk_in_pending_start, USBCCIDState),
1435 VMSTATE_UINT32(bulk_in_pending_end, USBCCIDState),
1436 VMSTATE_STRUCT_ARRAY(pending_answers, USBCCIDState,
1437 PENDING_ANSWERS_NUM, 1, answer_vmstate, Answer),
1438 VMSTATE_UINT32(pending_answers_num, USBCCIDState),
1439 VMSTATE_UINT8(migration_state, USBCCIDState),
1440 VMSTATE_UINT32(state_vmstate, USBCCIDState),
1441 VMSTATE_END_OF_LIST()
1442 }
1443};
1444
1445static Property ccid_properties[] = {
1446 DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0),
1447 DEFINE_PROP_END_OF_LIST(),
1448};
1449
1450static void ccid_class_initfn(ObjectClass *klass, void *data)
1451{
1452 DeviceClass *dc = DEVICE_CLASS(klass);
1453 USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1454 HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
1455
1456 uc->realize = ccid_realize;
1457 uc->product_desc = "QEMU USB CCID";
1458 uc->usb_desc = &desc_ccid;
1459 uc->handle_reset = ccid_handle_reset;
1460 uc->handle_control = ccid_handle_control;
1461 uc->handle_data = ccid_handle_data;
1462 uc->handle_destroy = ccid_handle_destroy;
1463 dc->desc = "CCID Rev 1.1 smartcard reader";
1464 dc->vmsd = &ccid_vmstate;
1465 dc->props = ccid_properties;
1466 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1467 hc->unplug = qdev_simple_device_unplug_cb;
1468}
1469
1470static const TypeInfo ccid_info = {
1471 .name = CCID_DEV_NAME,
1472 .parent = TYPE_USB_DEVICE,
1473 .instance_size = sizeof(USBCCIDState),
1474 .class_init = ccid_class_initfn,
1475 .interfaces = (InterfaceInfo[]) {
1476 { TYPE_HOTPLUG_HANDLER },
1477 { }
1478 }
1479};
1480
1481static void ccid_card_class_init(ObjectClass *klass, void *data)
1482{
1483 DeviceClass *k = DEVICE_CLASS(klass);
1484 k->bus_type = TYPE_CCID_BUS;
1485 k->init = ccid_card_init;
1486 k->exit = ccid_card_exit;
1487 k->props = ccid_props;
1488}
1489
1490static const TypeInfo ccid_card_type_info = {
1491 .name = TYPE_CCID_CARD,
1492 .parent = TYPE_DEVICE,
1493 .instance_size = sizeof(CCIDCardState),
1494 .abstract = true,
1495 .class_size = sizeof(CCIDCardClass),
1496 .class_init = ccid_card_class_init,
1497};
1498
1499static void ccid_register_types(void)
1500{
1501 type_register_static(&ccid_bus_info);
1502 type_register_static(&ccid_card_type_info);
1503 type_register_static(&ccid_info);
1504 usb_legacy_register(CCID_DEV_NAME, "ccid", NULL);
1505}
1506
1507type_init(ccid_register_types)
1508