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