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