Lines Matching +full:recv +full:- +full:empty
8 * Based on usb-serial.c, see its copyright and attributions below.
11 * See the COPYING file in the top-level directory.
12 * ------- (original copyright & attribution for usb-serial.c below) --------
14 * Copyright (c) 2008 Samuel Thibault <samuel.thibault@ens-lyon.org>
31 * symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. This can happen
32 * when a short packet is sent, as seen in uhci-usb.c, resulting from a urb
41 #include "qemu/error-report.h"
43 #include "hw/qdev-properties.h"
53 if (lvl <= s->debug) { \
54 printf("usb-ccid: " fmt , ## __VA_ARGS__); \
63 #define TYPE_USB_CCID_DEV "usb-ccid"
68 * or handle the migration complexity - VMState doesn't handle this case.
135 * Endpoints for CCID - addresses are up to us to decide.
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,
175 * 0 - Clock Running, 1 - Clock stopped in State L, 2 - H,
176 * 3 - unknown state. rest are RFU
282 #define TYPE_CCID_BUS "ccid-bus"
286 * powered - defaults to true, changed by PowerOn/PowerOff messages
338 0x07, /* u8 bVoltageSupport; 01h - 5.0v, 02h - 3.0, 03 - 1.8 */
358 /* u32 dwSyncProtocols; 1 - 2-wire, 2 - 3-wire, 4 - I2C */
360 /* u32 dwMechanical; 0 - no special characteristics. */
364 * 0 - No special characteristics
388 * wMaxPacketSize of the Bulk-OUT endpoint
405 * line for LCD display used for PIN entry. 0000 - no LCD
494 if (cc->get_atr) { in ccid_card_get_atr()
495 return cc->get_atr(card, len); in ccid_card_get_atr()
506 if (cc->apdu_from_guest) { in ccid_card_apdu_from_guest()
507 cc->apdu_from_guest(card, apdu, len); in ccid_card_apdu_from_guest()
513 return s->pending_answers_num > 0; in ccid_has_pending_answers()
518 s->pending_answers_num = 0; in ccid_clear_pending_answers()
519 s->pending_answers_start = 0; in ccid_clear_pending_answers()
520 s->pending_answers_end = 0; in ccid_clear_pending_answers()
528 DPRINTF(s, D_VERBOSE, "usb-ccid: pending answers:"); in ccid_print_pending_answers()
530 DPRINTF(s, D_VERBOSE, " empty\n"); in ccid_print_pending_answers()
533 for (i = s->pending_answers_start, count = s->pending_answers_num ; in ccid_print_pending_answers()
534 count > 0; count--, i++) { in ccid_print_pending_answers()
535 answer = &s->pending_answers[i % PENDING_ANSWERS_NUM]; in ccid_print_pending_answers()
537 DPRINTF(s, D_VERBOSE, "%d:%d\n", answer->slot, answer->seq); in ccid_print_pending_answers()
539 DPRINTF(s, D_VERBOSE, "%d:%d,", answer->slot, answer->seq); in ccid_print_pending_answers()
548 assert(s->pending_answers_num < PENDING_ANSWERS_NUM); in ccid_add_pending_answer()
549 s->pending_answers_num++; in ccid_add_pending_answer()
551 &s->pending_answers[(s->pending_answers_end++) % PENDING_ANSWERS_NUM]; in ccid_add_pending_answer()
552 answer->slot = hdr->bSlot; in ccid_add_pending_answer()
553 answer->seq = hdr->bSeq; in ccid_add_pending_answer()
562 assert(s->pending_answers_num > 0); in ccid_remove_pending_answer()
563 s->pending_answers_num--; in ccid_remove_pending_answer()
565 &s->pending_answers[(s->pending_answers_start++) % PENDING_ANSWERS_NUM]; in ccid_remove_pending_answer()
566 *slot = answer->slot; in ccid_remove_pending_answer()
567 *seq = answer->seq; in ccid_remove_pending_answer()
573 s->bulk_in_pending_start = 0; in ccid_bulk_in_clear()
574 s->bulk_in_pending_end = 0; in ccid_bulk_in_clear()
575 s->bulk_in_pending_num = 0; in ccid_bulk_in_clear()
580 assert(s->current_bulk_in != NULL); in ccid_bulk_in_release()
581 s->current_bulk_in->pos = 0; in ccid_bulk_in_release()
582 s->current_bulk_in = NULL; in ccid_bulk_in_release()
587 if (s->current_bulk_in != NULL || s->bulk_in_pending_num == 0) { in ccid_bulk_in_get()
590 assert(s->bulk_in_pending_num > 0); in ccid_bulk_in_get()
591 s->bulk_in_pending_num--; in ccid_bulk_in_get()
592 s->current_bulk_in = in ccid_bulk_in_get()
593 &s->bulk_in_pending[(s->bulk_in_pending_start++) % BULK_IN_PENDING_NUM]; in ccid_bulk_in_get()
604 DPRINTF(s, D_WARN, "usb-ccid.c: %s: len larger then max (%d>%d). " in ccid_reserve_recv_buf()
609 if (s->bulk_in_pending_num >= BULK_IN_PENDING_NUM) { in ccid_reserve_recv_buf()
610 DPRINTF(s, D_WARN, "usb-ccid.c: %s: No free bulk_in buffers. " in ccid_reserve_recv_buf()
615 &s->bulk_in_pending[(s->bulk_in_pending_end++) % BULK_IN_PENDING_NUM]; in ccid_reserve_recv_buf()
616 s->bulk_in_pending_num++; in ccid_reserve_recv_buf()
617 bulk_in->len = len; in ccid_reserve_recv_buf()
618 return bulk_in->data; in ccid_reserve_recv_buf()
644 /* generic - should be factored out if there are other debugees */ in ccid_control_to_str()
691 p->status = USB_RET_STALL; in ccid_handle_control()
695 p->status = USB_RET_STALL; in ccid_handle_control()
699 p->status = USB_RET_STALL; in ccid_handle_control()
704 p->status = USB_RET_STALL; in ccid_handle_control()
711 return s->bmSlotICCState & SLOT_0_STATE_MASK; in ccid_card_inserted()
717 ? (s->powered ? in ccid_card_status()
730 uint8_t ret = ccid_card_status(s) | (s->bmCommandStatus << 6); in ccid_calc_status()
737 s->bError = ERROR_CMD_NOT_SUPPORTED; in ccid_reset_error_status()
738 s->bmCommandStatus = COMMAND_STATUS_NO_ERROR; in ccid_reset_error_status()
741 static void ccid_write_slot_status(USBCCIDState *s, CCID_Header *recv) in ccid_write_slot_status() argument
747 h->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_SlotStatus; in ccid_write_slot_status()
748 h->b.hdr.dwLength = 0; in ccid_write_slot_status()
749 h->b.hdr.bSlot = recv->bSlot; in ccid_write_slot_status()
750 h->b.hdr.bSeq = recv->bSeq; in ccid_write_slot_status()
751 h->b.bStatus = ccid_calc_status(s); in ccid_write_slot_status()
752 h->b.bError = s->bError; in ccid_write_slot_status()
753 h->bClockStatus = CLOCK_STATUS_RUNNING; in ccid_write_slot_status()
755 usb_wakeup(s->bulk, 0); in ccid_write_slot_status()
758 static void ccid_write_parameters(USBCCIDState *s, CCID_Header *recv) in ccid_write_parameters() argument
761 uint32_t len = s->ulProtocolDataStructureSize; in ccid_write_parameters()
767 h->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_Parameters; in ccid_write_parameters()
768 h->b.hdr.dwLength = 0; in ccid_write_parameters()
769 h->b.hdr.bSlot = recv->bSlot; in ccid_write_parameters()
770 h->b.hdr.bSeq = recv->bSeq; in ccid_write_parameters()
771 h->b.bStatus = ccid_calc_status(s); in ccid_write_parameters()
772 h->b.bError = s->bError; in ccid_write_parameters()
773 h->bProtocolNum = s->bProtocolNum; in ccid_write_parameters()
774 h->abProtocolDataStructure = s->abProtocolDataStructure; in ccid_write_parameters()
776 usb_wakeup(s->bulk, 0); in ccid_write_parameters()
787 p->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock; in ccid_write_data_block()
788 p->b.hdr.dwLength = cpu_to_le32(len); in ccid_write_data_block()
789 p->b.hdr.bSlot = slot; in ccid_write_data_block()
790 p->b.hdr.bSeq = seq; in ccid_write_data_block()
791 p->b.bStatus = ccid_calc_status(s); in ccid_write_data_block()
792 p->b.bError = s->bError; in ccid_write_data_block()
793 if (p->b.bError) { in ccid_write_data_block()
794 DPRINTF(s, D_VERBOSE, "error %d\n", p->b.bError); in ccid_write_data_block()
798 memcpy(p->abData, data, len); in ccid_write_data_block()
801 usb_wakeup(s->bulk, 0); in ccid_write_data_block()
806 s->bmCommandStatus = COMMAND_STATUS_FAILED; in ccid_report_error_failed()
807 s->bError = error; in ccid_report_error_failed()
838 static void ccid_write_data_block_atr(USBCCIDState *s, CCID_Header *recv) in ccid_write_data_block_atr() argument
843 CCID_T0ProtocolDataStructure *t0 = &s->abProtocolDataStructure.t0; in ccid_write_data_block_atr()
844 CCID_T1ProtocolDataStructure *t1 = &s->abProtocolDataStructure.t1; in ccid_write_data_block_atr()
846 if (s->card) { in ccid_write_data_block_atr()
847 atr = ccid_card_get_atr(s->card, &len); in ccid_write_data_block_atr()
852 /* set parameters from ATR - see spec page 109 */ in ccid_write_data_block_atr()
853 s->bProtocolNum = (atr_protocol_num <= 1 ? atr_protocol_num in ccid_write_data_block_atr()
854 : s->bProtocolNum); in ccid_write_data_block_atr()
858 t0->bmFindexDindex = 0; in ccid_write_data_block_atr()
859 t0->bmTCCKST0 = 0; in ccid_write_data_block_atr()
860 t0->bGuardTimeT0 = 0; in ccid_write_data_block_atr()
861 t0->bWaitingIntegerT0 = 0; in ccid_write_data_block_atr()
862 t0->bClockStop = 0; in ccid_write_data_block_atr()
866 t1->bmFindexDindex = 0; in ccid_write_data_block_atr()
867 t1->bmTCCKST1 = 0; in ccid_write_data_block_atr()
868 t1->bGuardTimeT1 = 0; in ccid_write_data_block_atr()
869 t1->bWaitingIntegerT1 = 0; in ccid_write_data_block_atr()
870 t1->bClockStop = 0; in ccid_write_data_block_atr()
871 t1->bIFSC = 0; in ccid_write_data_block_atr()
872 t1->bNadValue = 0; in ccid_write_data_block_atr()
878 ccid_write_data_block(s, recv->bSlot, recv->bSeq, atr, len); in ccid_write_data_block_atr()
881 static void ccid_set_parameters(USBCCIDState *s, CCID_Header *recv) in ccid_set_parameters() argument
883 CCID_SetParameters *ph = (CCID_SetParameters *) recv; in ccid_set_parameters()
884 uint32_t protocol_num = ph->bProtocolNum & 3; in ccid_set_parameters()
890 s->bProtocolNum = protocol_num; in ccid_set_parameters()
891 s->abProtocolDataStructure = ph->abProtocolDataStructure; in ccid_set_parameters()
912 s->bProtocolNum = 0; /* T=0 */ in ccid_reset_parameters()
913 s->abProtocolDataStructure = defaultProtocolDataStructure; in ccid_reset_parameters()
920 uint8_t current = s->bmSlotICCState; in ccid_on_slot_change()
922 s->bmSlotICCState |= SLOT_0_STATE_MASK; in ccid_on_slot_change()
924 s->bmSlotICCState &= ~SLOT_0_STATE_MASK; in ccid_on_slot_change()
926 if (current != s->bmSlotICCState) { in ccid_on_slot_change()
927 s->bmSlotICCState |= SLOT_0_CHANGED_MASK; in ccid_on_slot_change()
929 s->notify_slot_change = true; in ccid_on_slot_change()
930 usb_wakeup(s->intr, 0); in ccid_on_slot_change()
939 static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv) in ccid_on_apdu_from_guest() argument
945 "usb-ccid: not sending apdu to client, no card connected\n"); in ccid_on_apdu_from_guest()
946 ccid_write_data_block_error(s, recv->hdr.bSlot, recv->hdr.bSeq); in ccid_on_apdu_from_guest()
949 len = le32_to_cpu(recv->hdr.dwLength); in ccid_on_apdu_from_guest()
951 recv->hdr.bSeq, len); in ccid_on_apdu_from_guest()
952 ccid_add_pending_answer(s, (CCID_Header *)recv); in ccid_on_apdu_from_guest()
953 if (s->card && len <= BULK_OUT_DATA_SIZE) { in ccid_on_apdu_from_guest()
954 ccid_card_apdu_from_guest(s->card, recv->abData, len); in ccid_on_apdu_from_guest()
986 if (p->iov.size + s->bulk_out_pos > BULK_OUT_DATA_SIZE) { in ccid_handle_bulk_out()
989 usb_packet_copy(p, s->bulk_out_data + s->bulk_out_pos, p->iov.size); in ccid_handle_bulk_out()
990 s->bulk_out_pos += p->iov.size; in ccid_handle_bulk_out()
991 if (s->bulk_out_pos < 10) { in ccid_handle_bulk_out()
996 ccid_header = (CCID_Header *)s->bulk_out_data; in ccid_handle_bulk_out()
997 if ((s->bulk_out_pos - 10 < ccid_header->dwLength) && in ccid_handle_bulk_out()
998 (p->iov.size == CCID_MAX_PACKET_SIZE)) { in ccid_handle_bulk_out()
1000 "usb-ccid: bulk_in: expecting more packets (%u/%u)\n", in ccid_handle_bulk_out()
1001 s->bulk_out_pos - 10, ccid_header->dwLength); in ccid_handle_bulk_out()
1004 if (s->bulk_out_pos - 10 != ccid_header->dwLength) { in ccid_handle_bulk_out()
1006 "usb-ccid: bulk_in: message size mismatch (got %u, expected %u)\n", in ccid_handle_bulk_out()
1007 s->bulk_out_pos - 10, ccid_header->dwLength); in ccid_handle_bulk_out()
1012 ccid_header->bMessageType, in ccid_handle_bulk_out()
1013 ccid_message_type_to_str(ccid_header->bMessageType)); in ccid_handle_bulk_out()
1014 switch (ccid_header->bMessageType) { in ccid_handle_bulk_out()
1020 ((CCID_IccPowerOn *)(ccid_header))->bPowerSelect); in ccid_handle_bulk_out()
1021 s->powered = true; in ccid_handle_bulk_out()
1030 s->powered = false; in ccid_handle_bulk_out()
1034 ccid_on_apdu_from_guest(s, (CCID_XferBlock *)s->bulk_out_data); in ccid_handle_bulk_out()
1057 ccid_header->bMessageType); in ccid_handle_bulk_out()
1066 s->bulk_out_pos = 0; in ccid_handle_bulk_out()
1070 p->status = USB_RET_STALL; in ccid_handle_bulk_out()
1071 s->bulk_out_pos = 0; in ccid_handle_bulk_out()
1081 if (s->current_bulk_in != NULL) { in ccid_bulk_in_copy_to_guest()
1082 len = MIN(s->current_bulk_in->len - s->current_bulk_in->pos, in ccid_bulk_in_copy_to_guest()
1083 p->iov.size); in ccid_bulk_in_copy_to_guest()
1085 usb_packet_copy(p, s->current_bulk_in->data + in ccid_bulk_in_copy_to_guest()
1086 s->current_bulk_in->pos, len); in ccid_bulk_in_copy_to_guest()
1088 s->current_bulk_in->pos += len; in ccid_bulk_in_copy_to_guest()
1089 if (s->current_bulk_in->pos == s->current_bulk_in->len in ccid_bulk_in_copy_to_guest()
1094 /* return when device has no data - usb 2.0 spec Table 8-4 */ in ccid_bulk_in_copy_to_guest()
1095 p->status = USB_RET_NAK; in ccid_bulk_in_copy_to_guest()
1100 __func__, p->iov.size, len); in ccid_bulk_in_copy_to_guest()
1102 if (len < p->iov.size) { in ccid_bulk_in_copy_to_guest()
1105 __func__, len, p->iov.size); in ccid_bulk_in_copy_to_guest()
1114 switch (p->pid) { in ccid_handle_data()
1120 switch (p->ep->nr) { in ccid_handle_data()
1122 ccid_bulk_in_copy_to_guest(s, p, dev->ep_ctl.max_packet_size); in ccid_handle_data()
1125 if (s->notify_slot_change) { in ccid_handle_data()
1128 buf[1] = s->bmSlotICCState; in ccid_handle_data()
1130 s->notify_slot_change = false; in ccid_handle_data()
1131 s->bmSlotICCState &= ~SLOT_0_CHANGED_MASK; in ccid_handle_data()
1135 s->bmSlotICCState, p->iov.size); in ccid_handle_data()
1137 p->status = USB_RET_NAK; in ccid_handle_data()
1142 p->status = USB_RET_STALL; in ccid_handle_data()
1148 p->status = USB_RET_STALL; in ccid_handle_data()
1169 return s->pending_answers_num == 0 in ccid_peek_next_answer()
1171 : &s->pending_answers[s->pending_answers_start % PENDING_ANSWERS_NUM]; in ccid_peek_next_answer()
1189 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); in ccid_card_send_apdu_to_guest()
1197 s->bmCommandStatus = COMMAND_STATUS_NO_ERROR; in ccid_card_send_apdu_to_guest()
1205 len, answer->seq, answer->slot); in ccid_card_send_apdu_to_guest()
1212 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); in ccid_card_card_removed()
1223 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); in ccid_card_ccid_attach()
1233 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); in ccid_card_ccid_detach()
1246 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); in ccid_card_card_error()
1249 s->bmCommandStatus = COMMAND_STATUS_FAILED; in ccid_card_card_error()
1250 s->last_answer_error = error; in ccid_card_card_error()
1251 DPRINTF(s, 1, "VSC_Error: %" PRIX64 "\n", s->last_answer_error); in ccid_card_card_error()
1254 * We flush all pending answers on CardRemove message in ccid-card-passthru, in ccid_card_card_error()
1265 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); in ccid_card_card_inserted()
1268 s->bmCommandStatus = COMMAND_STATUS_NO_ERROR; in ccid_card_card_inserted()
1277 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); in ccid_card_unrealize()
1283 if (cc->unrealize) { in ccid_card_unrealize()
1284 cc->unrealize(card); in ccid_card_unrealize()
1286 s->card = NULL; in ccid_card_unrealize()
1293 USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent); in ccid_card_realize()
1297 if (card->slot != 0) { in ccid_card_realize()
1298 error_setg(errp, "usb-ccid supports one slot, can't add %d", in ccid_card_realize()
1299 card->slot); in ccid_card_realize()
1302 if (s->card != NULL) { in ccid_card_realize()
1303 error_setg(errp, "usb-ccid card already full, not adding"); in ccid_card_realize()
1306 if (cc->realize) { in ccid_card_realize()
1307 cc->realize(card, &local_err); in ccid_card_realize()
1313 s->card = card; in ccid_card_realize()
1322 qbus_init(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev), NULL); in ccid_realize()
1323 qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev)); in ccid_realize()
1324 s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP); in ccid_realize()
1325 s->bulk = usb_ep_get(dev, USB_TOKEN_IN, CCID_BULK_IN_EP); in ccid_realize()
1326 s->card = NULL; in ccid_realize()
1327 s->dev.speed = USB_SPEED_FULL; in ccid_realize()
1328 s->dev.speedmask = USB_SPEED_MASK_FULL; in ccid_realize()
1329 s->notify_slot_change = false; in ccid_realize()
1330 s->powered = true; in ccid_realize()
1331 s->pending_answers_num = 0; in ccid_realize()
1332 s->last_answer_error = 0; in ccid_realize()
1333 s->bulk_in_pending_start = 0; in ccid_realize()
1334 s->bulk_in_pending_end = 0; in ccid_realize()
1335 s->current_bulk_in = NULL; in ccid_realize()
1337 s->bulk_out_pos = 0; in ccid_realize()
1340 s->debug = parse_debug_env("QEMU_CCID_DEBUG", D_VERBOSE, s->debug); in ccid_realize()
1353 s->dev.state = s->state_vmstate; in ccid_post_load()
1361 s->state_vmstate = s->dev.state; in ccid_pre_save()
1402 .name = "usb-ccid",
1445 uc->realize = ccid_realize; in ccid_class_initfn()
1446 uc->product_desc = "QEMU USB CCID"; in ccid_class_initfn()
1447 uc->usb_desc = &desc_ccid; in ccid_class_initfn()
1448 uc->handle_reset = ccid_handle_reset; in ccid_class_initfn()
1449 uc->handle_control = ccid_handle_control; in ccid_class_initfn()
1450 uc->handle_data = ccid_handle_data; in ccid_class_initfn()
1451 uc->unrealize = ccid_unrealize; in ccid_class_initfn()
1452 dc->desc = "CCID Rev 1.1 smartcard reader"; in ccid_class_initfn()
1453 dc->vmsd = &ccid_vmstate; in ccid_class_initfn()
1455 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); in ccid_class_initfn()
1456 hc->unplug = qdev_simple_device_unplug_cb; in ccid_class_initfn()
1473 k->bus_type = TYPE_CCID_BUS; in ccid_card_class_init()
1474 k->realize = ccid_card_realize; in ccid_card_class_init()
1475 k->unrealize = ccid_card_unrealize; in ccid_card_class_init()