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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2026-present Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Device CCID Class */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_class_ccid.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_ccid_control_abort PORTABLE C */
/* 6.2.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles control request Abort of the USB CCID device. */
/* */
/* INPUT */
/* */
/* ccid Pointer to ccid instance */
/* slot Slot to abort */
/* seq Sequence number of message */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* */
/* CALLED BY */
/* */
/* USBX Source Code */
/* */
/**************************************************************************/
UINT _ux_device_class_ccid_control_abort(UX_DEVICE_CLASS_CCID *ccid, ULONG slot, ULONG seq)
{
UX_DEVICE_CLASS_CCID_PARAMETER *parameter;
UX_DEVICE_CLASS_CCID_HANDLES *handles;
UX_DEVICE_CLASS_CCID_SLOT *ccid_slot;
UX_SLAVE_TRANSFER *transfer_in, *transfer_out;
UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *msg;
/* Get parameter. */
parameter = &ccid -> ux_device_class_ccid_parameter;
handles = parameter -> ux_device_class_ccid_handles;
/* Check if slot is available. */
if (slot >= parameter -> ux_device_class_ccid_max_n_slots)
return(UX_INVALID_PARAMETER);
/* Check if command is supported. */
if (handles -> ux_device_class_ccid_handles_abort == UX_NULL)
return(UX_FUNCTION_NOT_SUPPORTED);
/* Get slot to process. */
ccid_slot = &ccid -> ux_device_class_ccid_slots[slot];
/* Check if message header received. */
transfer_out = &ccid -> ux_device_class_ccid_endpoint_out ->
ux_slave_endpoint_transfer_request;
if (transfer_out -> ux_slave_transfer_request_actual_length <
UX_DEVICE_CLASS_CCID_MESSAGE_HEADER_LENGTH)
{
/* Message header not available, cancel current bulk OUT transfer. */
_ux_device_stack_transfer_abort(transfer_out, UX_ABORTED);
}
else
{
/* Message header available, check message. */
msg = (UX_DEVICE_CLASS_CCID_MESSAGE_HEADER *)
transfer_out -> ux_slave_transfer_request_data_pointer;
/* Check if abort applies to the slot. */
if (msg -> bSlot == (UCHAR)slot)
{
/* Yes, aborting current message, cancel current bulk OUT transfer. */
_ux_device_stack_transfer_abort(transfer_out, UX_ABORTED);
}
else
{
/* Aborting another slot. */
/* Check slot busy. */
if ((signed char)ccid_slot -> ux_device_class_ccid_slot_runner >= 0)
{
/* Possible sending something, abort IN transfer. */
transfer_in = &ccid -> ux_device_class_ccid_endpoint_in ->
ux_slave_endpoint_transfer_request;
_ux_device_stack_transfer_abort(transfer_in, UX_ABORTED);
}
}
}
#if defined(UX_DEVICE_STANDALONE)
if (ccid -> ux_device_class_ccid_cmd_state == UX_DEVICE_CLASS_CCID_CMD_WAIT)
ccid -> ux_device_class_ccid_cmd_state = UX_DEVICE_CLASS_CCID_CMD_START;
if (ccid -> ux_device_class_ccid_rsp_state == UX_DEVICE_CLASS_CCID_RSP_WAIT)
ccid -> ux_device_class_ccid_rsp_state = UX_DEVICE_CLASS_CCID_RSP_IDLE;
#endif
/* Set aborting state. */
ccid_slot -> ux_device_class_ccid_slot_aborting = UX_TRUE;
ccid_slot -> ux_device_class_ccid_slot_aborting_seq = (UCHAR)seq;
/* Invoke control abort to let application do something. */
handles -> ux_device_class_ccid_handles_abort(slot, UX_NULL);
return(UX_SUCCESS);
}
|