blob: bc808fdfac55fdc5044525c0839362d94331a912 (
plain)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
/***************************************************************************
* 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 */
/** */
/** Asix Class */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define UX_SOURCE_CODE
#include "ux_api.h"
#include "ux_host_class_asix.h"
#include "ux_host_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_reception_callback PORTABLE C */
/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the callback from the USBX transfer functions, */
/* it is called when a full or partial transfer has been done for a */
/* bulk in transfer. It calls back the application. */
/* */
/* It's deprecated. */
/* */
/* INPUT */
/* */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_host_stack_transfer_request Process transfer request */
/* _ux_utility_short_get_big_endian Get 16-bit big endian */
/* _ux_network_driver_packet_received Process received packet */
/* nx_packet_transmit_release Release NetX packet */
/* nx_packet_allocate Allocate NetX packet */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/**************************************************************************/
VOID _ux_host_class_asix_reception_callback (UX_TRANSFER *transfer_request)
{
#if defined(UX_HOST_STANDALONE)
UX_PARAMETER_NOT_USED(transfer_request);
#else
UX_HOST_CLASS_ASIX *asix;
NX_PACKET *packet;
ULONG ip_given_length;
UINT status;
/* Get the class instance for this transfer request. */
asix = (UX_HOST_CLASS_ASIX *) transfer_request -> ux_transfer_request_class_instance;
/* Load the packet that is associated with this reception. */
packet = transfer_request -> ux_transfer_request_user_specific;
/* Check the state of the transfer. If there is an error, we do not proceed with this report. */
if (transfer_request -> ux_transfer_request_completion_code == UX_SUCCESS)
{
/* Adjust the prepend, length, append fields to take the Ether header out */
packet -> nx_packet_prepend_ptr += 4;
packet -> nx_packet_length = transfer_request -> ux_transfer_request_actual_length - 4;
packet -> nx_packet_append_ptr =
packet->nx_packet_prepend_ptr + transfer_request -> ux_transfer_request_actual_length ;
/* Calculate the accurate packet length from ip header */
if((*(packet -> nx_packet_prepend_ptr + 12) == 0x08) &&
(*(packet -> nx_packet_prepend_ptr + 13) == 0))
{
ip_given_length = _ux_utility_short_get_big_endian(packet -> nx_packet_prepend_ptr + 16) + UX_HOST_CLASS_ASIX_ETHERNET_SIZE;
packet->nx_packet_length = ip_given_length ;
packet->nx_packet_append_ptr = packet->nx_packet_prepend_ptr + ip_given_length;
}
/* Send that packet to the NetX USB broker. */
_ux_network_driver_packet_received(asix -> ux_host_class_asix_network_handle, packet);
}
else
/* Free the packet that was not successfully received. */
nx_packet_transmit_release(packet);
/* We can accept new reception. Get a NX Packet */
if (nx_packet_allocate(asix -> ux_host_class_asix_packet_pool, &packet,
NX_RECEIVE_PACKET, NX_NO_WAIT) == NX_SUCCESS)
{
/* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
packet -> nx_packet_prepend_ptr += sizeof(USHORT);
/* Set the data pointer. */
transfer_request -> ux_transfer_request_data_pointer = packet -> nx_packet_prepend_ptr;
/* And length. */
transfer_request -> ux_transfer_request_requested_length = UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE;
transfer_request -> ux_transfer_request_actual_length = 0;
/* Store the packet that owns this transaction. */
transfer_request -> ux_transfer_request_user_specific = packet;
/* Memorize this packet at the beginning of the queue. */
asix -> ux_host_class_asix_receive_queue = packet;
/* Reset the queue pointer of this packet. */
packet -> nx_packet_queue_next = UX_NULL;
/* Ask USB to schedule a reception. */
status = _ux_host_stack_transfer_request(transfer_request);
/* Check if the transaction was armed successfully. We do not wait for the packet to be sent here. */
if (status != UX_SUCCESS)
{
/* Cancel the packet. */
asix -> ux_host_class_asix_receive_queue = UX_NULL;
}
}
/* There is no status to be reported back to the stack. */
return;
#endif
}
|