]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiTcp4Io.c
Update the copyright notice format
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiTcp4Io.c
CommitLineData
12618416 1/** @file\r
02aa4e52 2 The wrap of TCP/IP Socket interface.\r
6a690e23 3\r
e5eed7d3
HT
4Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
7a444476 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
6a690e23 12\r
12618416 13**/\r
6a690e23 14\r
15#include "IScsiImpl.h"\r
16\r
12618416 17/**\r
18 The common notify function associated with various Tcp4Io events. \r
19\r
02aa4e52 20 @param[in] Event The event signaled.\r
21 @param[in] Context The context.\r
12618416 22**/\r
6a690e23 23VOID\r
24EFIAPI\r
25Tcp4IoCommonNotify (\r
26 IN EFI_EVENT Event,\r
27 IN VOID *Context\r
28 )\r
12618416 29{\r
30 *((BOOLEAN *) Context) = TRUE;\r
31}\r
6a690e23 32\r
12618416 33/**\r
34 Create a TCP socket with the specified configuration data. \r
6a690e23 35\r
02aa4e52 36 @param[in] Image The handle of the driver image.\r
37 @param[in] Controller The handle of the controller.\r
38 @param[in] ConfigData The Tcp4 configuration data.\r
39 @param[in] Tcp4Io The Tcp4Io.\r
12618416 40 \r
41 @retval EFI_SUCCESS The TCP socket is created and configured.\r
02aa4e52 42 @retval Others Failed to create the TCP socket or configure it.\r
12618416 43**/\r
6a690e23 44EFI_STATUS\r
45Tcp4IoCreateSocket (\r
46 IN EFI_HANDLE Image,\r
47 IN EFI_HANDLE Controller,\r
48 IN TCP4_IO_CONFIG_DATA *ConfigData,\r
49 IN TCP4_IO *Tcp4Io\r
50 )\r
6a690e23 51{\r
52 EFI_STATUS Status;\r
53 EFI_TCP4_PROTOCOL *Tcp4;\r
54 EFI_TCP4_CONFIG_DATA Tcp4ConfigData;\r
55 EFI_TCP4_OPTION ControlOption;\r
56 EFI_TCP4_ACCESS_POINT *AccessPoint;\r
57\r
58 Tcp4Io->Handle = NULL;\r
59 Tcp4Io->ConnToken.CompletionToken.Event = NULL;\r
60 Tcp4Io->TxToken.CompletionToken.Event = NULL;\r
61 Tcp4Io->RxToken.CompletionToken.Event = NULL;\r
62 Tcp4Io->CloseToken.CompletionToken.Event = NULL;\r
63 Tcp4 = NULL;\r
64\r
65 //\r
66 // Create the TCP4 child instance and get the TCP4 protocol.\r
67 //\r
68 Status = NetLibCreateServiceChild (\r
69 Controller,\r
70 Image,\r
71 &gEfiTcp4ServiceBindingProtocolGuid,\r
72 &Tcp4Io->Handle\r
73 );\r
74 if (EFI_ERROR (Status)) {\r
75 return Status;\r
76 }\r
77\r
78 Status = gBS->OpenProtocol (\r
79 Tcp4Io->Handle,\r
80 &gEfiTcp4ProtocolGuid,\r
81 (VOID **)&Tcp4Io->Tcp4,\r
82 Image,\r
83 Controller,\r
84 EFI_OPEN_PROTOCOL_BY_DRIVER\r
85 );\r
86 if (EFI_ERROR (Status)) {\r
87 goto ON_ERROR;\r
88 }\r
89\r
90 Tcp4Io->Image = Image;\r
91 Tcp4Io->Controller = Controller;\r
92 Tcp4 = Tcp4Io->Tcp4;\r
93\r
94 //\r
95 // Set the configuration parameters.\r
96 //\r
97 ControlOption.ReceiveBufferSize = 0x200000;\r
98 ControlOption.SendBufferSize = 0x200000;\r
99 ControlOption.MaxSynBackLog = 0;\r
100 ControlOption.ConnectionTimeout = 0;\r
101 ControlOption.DataRetries = 6;\r
102 ControlOption.FinTimeout = 0;\r
103 ControlOption.TimeWaitTimeout = 0;\r
104 ControlOption.KeepAliveProbes = 4;\r
105 ControlOption.KeepAliveTime = 0;\r
106 ControlOption.KeepAliveInterval = 0;\r
107 ControlOption.EnableNagle = FALSE;\r
108 ControlOption.EnableTimeStamp = FALSE;\r
109 ControlOption.EnableWindowScaling = TRUE;\r
110 ControlOption.EnableSelectiveAck = FALSE;\r
111 ControlOption.EnablePathMtuDiscovery = FALSE;\r
112\r
113 Tcp4ConfigData.TypeOfService = 8;\r
114 Tcp4ConfigData.TimeToLive = 255;\r
115 Tcp4ConfigData.ControlOption = &ControlOption;\r
116\r
117 AccessPoint = &Tcp4ConfigData.AccessPoint;\r
118\r
119 AccessPoint->UseDefaultAddress = FALSE;\r
120 AccessPoint->StationPort = 0;\r
121 AccessPoint->RemotePort = ConfigData->RemotePort;\r
122 AccessPoint->ActiveFlag = TRUE;\r
123\r
e48e37fc 124 CopyMem (&AccessPoint->StationAddress, &ConfigData->LocalIp, sizeof (EFI_IPv4_ADDRESS));\r
125 CopyMem (&AccessPoint->SubnetMask, &ConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
126 CopyMem (&AccessPoint->RemoteAddress, &ConfigData->RemoteIp, sizeof (EFI_IPv4_ADDRESS));\r
6a690e23 127\r
128 //\r
129 // Configure the TCP4 protocol.\r
130 //\r
131 Status = Tcp4->Configure (Tcp4, &Tcp4ConfigData);\r
132 if (EFI_ERROR (Status)) {\r
133 goto ON_ERROR;\r
134 }\r
135\r
136 if (!EFI_IP4_EQUAL (&ConfigData->Gateway, &mZeroIp4Addr)) {\r
137 //\r
138 // the gateway is not zero, add the default route by hand\r
139 //\r
140 Status = Tcp4->Routes (Tcp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &ConfigData->Gateway);\r
141 if (EFI_ERROR (Status)) {\r
142 goto ON_ERROR;\r
143 }\r
144 }\r
145 //\r
146 // Create events for variuos asynchronous operations.\r
147 //\r
148 Status = gBS->CreateEvent (\r
e53a6ea9 149 EVT_NOTIFY_SIGNAL,\r
e48e37fc 150 TPL_NOTIFY,\r
6a690e23 151 Tcp4IoCommonNotify,\r
152 &Tcp4Io->IsConnDone,\r
153 &Tcp4Io->ConnToken.CompletionToken.Event\r
154 );\r
155 if (EFI_ERROR (Status)) {\r
156 goto ON_ERROR;\r
157 }\r
158\r
159 Status = gBS->CreateEvent (\r
e53a6ea9 160 EVT_NOTIFY_SIGNAL,\r
e48e37fc 161 TPL_NOTIFY,\r
6a690e23 162 Tcp4IoCommonNotify,\r
163 &Tcp4Io->IsTxDone,\r
164 &Tcp4Io->TxToken.CompletionToken.Event\r
165 );\r
166 if (EFI_ERROR (Status)) {\r
167 goto ON_ERROR;\r
168 }\r
169\r
170 Status = gBS->CreateEvent (\r
e53a6ea9 171 EVT_NOTIFY_SIGNAL,\r
e48e37fc 172 TPL_NOTIFY,\r
6a690e23 173 Tcp4IoCommonNotify,\r
174 &Tcp4Io->IsRxDone,\r
175 &Tcp4Io->RxToken.CompletionToken.Event\r
176 );\r
177 if (EFI_ERROR (Status)) {\r
178 goto ON_ERROR;\r
179 }\r
180\r
181 Status = gBS->CreateEvent (\r
e53a6ea9 182 EVT_NOTIFY_SIGNAL,\r
e48e37fc 183 TPL_NOTIFY,\r
6a690e23 184 Tcp4IoCommonNotify,\r
185 &Tcp4Io->IsCloseDone,\r
186 &Tcp4Io->CloseToken.CompletionToken.Event\r
187 );\r
188 if (EFI_ERROR (Status)) {\r
189 goto ON_ERROR;\r
190 }\r
191\r
192 Tcp4Io->IsTxDone = FALSE;\r
193 Tcp4Io->IsRxDone = FALSE;\r
194\r
195 return EFI_SUCCESS;\r
196\r
197ON_ERROR:\r
198\r
199 if (Tcp4Io->RxToken.CompletionToken.Event != NULL) {\r
200 gBS->CloseEvent (Tcp4Io->RxToken.CompletionToken.Event);\r
201 }\r
202\r
203 if (Tcp4Io->TxToken.CompletionToken.Event != NULL) {\r
204 gBS->CloseEvent (Tcp4Io->TxToken.CompletionToken.Event);\r
205 }\r
206\r
207 if (Tcp4Io->ConnToken.CompletionToken.Event != NULL) {\r
208 gBS->CloseEvent (Tcp4Io->ConnToken.CompletionToken.Event);\r
209 }\r
210\r
211 if (Tcp4 != NULL) {\r
212 Tcp4->Configure (Tcp4, NULL);\r
213\r
214 gBS->CloseProtocol (\r
215 Tcp4Io->Handle,\r
216 &gEfiTcp4ProtocolGuid,\r
217 Image,\r
218 Controller\r
219 );\r
220 }\r
221\r
222 NetLibDestroyServiceChild (\r
223 Controller,\r
224 Image,\r
225 &gEfiTcp4ServiceBindingProtocolGuid,\r
226 Tcp4Io->Handle\r
227 );\r
228\r
229 return Status;\r
230}\r
231\r
12618416 232/**\r
6a690e23 233 Destroy the socket. \r
234\r
12618416 235 @param[in] Tcp4Io The Tcp4Io which wraps the socket to be destroyeds.\r
12618416 236**/\r
237VOID\r
238Tcp4IoDestroySocket (\r
239 IN TCP4_IO *Tcp4Io\r
240 )\r
6a690e23 241{\r
242 EFI_TCP4_PROTOCOL *Tcp4;\r
243\r
244 Tcp4 = Tcp4Io->Tcp4;\r
245\r
246 Tcp4->Configure (Tcp4, NULL);\r
247\r
248 gBS->CloseEvent (Tcp4Io->TxToken.CompletionToken.Event);\r
249 gBS->CloseEvent (Tcp4Io->RxToken.CompletionToken.Event);\r
250 gBS->CloseEvent (Tcp4Io->ConnToken.CompletionToken.Event);\r
251\r
252 gBS->CloseProtocol (\r
253 Tcp4Io->Handle,\r
254 &gEfiTcp4ProtocolGuid,\r
255 Tcp4Io->Image,\r
256 Tcp4Io->Controller\r
257 );\r
258\r
259 NetLibDestroyServiceChild (\r
260 Tcp4Io->Controller,\r
261 Tcp4Io->Image,\r
262 &gEfiTcp4ServiceBindingProtocolGuid,\r
263 Tcp4Io->Handle\r
264 );\r
265}\r
266\r
12618416 267/**\r
6a690e23 268 Connect to the other endpoint of the TCP socket.\r
269\r
c5de0d55 270 @param[in, out] Tcp4Io The Tcp4Io wrapping the TCP socket.\r
271 @param[in] Timeout The time to wait for connection done.\r
02aa4e52 272 \r
273 @retval EFI_SUCCESS Connect to the other endpoint of the TCP socket successfully.\r
274 @retval EFI_TIMEOUT Failed to connect to the other endpoint of the TCP socket in the specified time period.\r
963dbb30 275 @retval Others Other errors as indicated.\r
12618416 276**/\r
277EFI_STATUS\r
278Tcp4IoConnect (\r
c5de0d55 279 IN OUT TCP4_IO *Tcp4Io,\r
280 IN EFI_EVENT Timeout\r
12618416 281 )\r
6a690e23 282{\r
283 EFI_TCP4_PROTOCOL *Tcp4;\r
284 EFI_STATUS Status;\r
285\r
286 Tcp4Io->IsConnDone = FALSE;\r
287 Tcp4 = Tcp4Io->Tcp4;\r
288 Status = Tcp4->Connect (Tcp4, &Tcp4Io->ConnToken);\r
289 if (EFI_ERROR (Status)) {\r
290 return Status;\r
291 }\r
292\r
293 while (!Tcp4Io->IsConnDone && EFI_ERROR (gBS->CheckEvent (Timeout))) {\r
294 Tcp4->Poll (Tcp4);\r
295 }\r
296\r
297 if (!Tcp4Io->IsConnDone) {\r
298 Status = EFI_TIMEOUT;\r
299 } else {\r
300 Status = Tcp4Io->ConnToken.CompletionToken.Status;\r
301 }\r
302\r
303 return Status;\r
304}\r
305\r
12618416 306/**\r
6a690e23 307 Reset the socket.\r
308\r
c5de0d55 309 @param[in, out] Tcp4Io The Tcp4Io wrapping the TCP socket.\r
12618416 310**/\r
311VOID\r
312Tcp4IoReset (\r
c5de0d55 313 IN OUT TCP4_IO *Tcp4Io\r
12618416 314 )\r
6a690e23 315{\r
316 EFI_STATUS Status;\r
317 EFI_TCP4_PROTOCOL *Tcp4;\r
318\r
319 Tcp4Io->CloseToken.AbortOnClose = TRUE;\r
320 Tcp4Io->IsCloseDone = FALSE;\r
321\r
322 Tcp4 = Tcp4Io->Tcp4;\r
323 Status = Tcp4->Close (Tcp4, &Tcp4Io->CloseToken);\r
324 if (EFI_ERROR (Status)) {\r
325 return ;\r
326 }\r
327\r
328 while (!Tcp4Io->IsCloseDone) {\r
329 Tcp4->Poll (Tcp4);\r
330 }\r
331}\r
332\r
12618416 333/**\r
6a690e23 334 Transmit the Packet to the other endpoint of the socket.\r
335\r
02aa4e52 336 @param[in] Tcp4Io The Tcp4Io wrapping the TCP socket.\r
337 @param[in] Packet The packet to transmit.\r
338 \r
12618416 339 @retval EFI_SUCCESS The packet is trasmitted.\r
12618416 340 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
963dbb30 341 @retval Others Other errors as indicated.\r
12618416 342**/\r
343EFI_STATUS\r
344Tcp4IoTransmit (\r
345 IN TCP4_IO *Tcp4Io,\r
346 IN NET_BUF *Packet\r
347 )\r
6a690e23 348{\r
349 EFI_TCP4_TRANSMIT_DATA *TxData;\r
350 EFI_TCP4_PROTOCOL *Tcp4;\r
351 EFI_STATUS Status;\r
352\r
e48e37fc 353 TxData = AllocatePool (sizeof (EFI_TCP4_TRANSMIT_DATA) + (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA));\r
6a690e23 354 if (TxData == NULL) {\r
355 return EFI_OUT_OF_RESOURCES;\r
356 }\r
357\r
358 TxData->Push = TRUE;\r
359 TxData->Urgent = FALSE;\r
360 TxData->DataLength = Packet->TotalSize;\r
361\r
362 //\r
363 // Build the fragment table.\r
364 //\r
365 TxData->FragmentCount = Packet->BlockOpNum;\r
366 NetbufBuildExt (Packet, (NET_FRAGMENT *) &TxData->FragmentTable[0], &TxData->FragmentCount);\r
367\r
368 Tcp4Io->TxToken.Packet.TxData = TxData;\r
369\r
370 //\r
371 // Trasnmit the packet.\r
372 //\r
373 Tcp4 = Tcp4Io->Tcp4;\r
374 Status = Tcp4->Transmit (Tcp4, &Tcp4Io->TxToken);\r
375 if (EFI_ERROR (Status)) {\r
376 goto ON_EXIT;\r
377 }\r
378\r
379 while (!Tcp4Io->IsTxDone) {\r
380 Tcp4->Poll (Tcp4);\r
381 }\r
382\r
383 Tcp4Io->IsTxDone = FALSE;\r
384\r
385 Status = Tcp4Io->TxToken.CompletionToken.Status;\r
386\r
387ON_EXIT:\r
388\r
766c7483 389 FreePool (TxData);\r
6a690e23 390\r
391 return Status;\r
392}\r
393\r
12618416 394/**\r
395 Receive data from the socket.\r
6a690e23 396\r
02aa4e52 397 @param[in] Tcp4Io The Tcp4Io which wraps the socket to be destroyed.\r
398 @param[in] Packet The buffer to hold the data copy from the soket rx buffer.\r
399 @param[in] AsyncMode Is this receive asyncronous or not.\r
400 @param[in] Timeout The time to wait for receiving the amount of data the Packet\r
12618416 401 can hold.\r
6a690e23 402\r
12618416 403 @retval EFI_SUCCESS The required amount of data is received from the socket.\r
12618416 404 @retval EFI_OUT_OF_RESOURCES Failed to allocate momery.\r
12618416 405 @retval EFI_TIMEOUT Failed to receive the required amount of data in the\r
406 specified time period.\r
963dbb30 407 @retval Others Other errors as indicated.\r
12618416 408**/\r
409EFI_STATUS\r
410Tcp4IoReceive (\r
411 IN TCP4_IO *Tcp4Io,\r
412 IN NET_BUF *Packet,\r
413 IN BOOLEAN AsyncMode,\r
414 IN EFI_EVENT Timeout\r
415 )\r
6a690e23 416{\r
417 EFI_TCP4_PROTOCOL *Tcp4;\r
418 EFI_TCP4_RECEIVE_DATA RxData;\r
419 EFI_STATUS Status;\r
420 NET_FRAGMENT *Fragment;\r
421 UINT32 FragmentCount;\r
422 UINT32 CurrentFragment;\r
423\r
424 FragmentCount = Packet->BlockOpNum;\r
e48e37fc 425 Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));\r
6a690e23 426 if (Fragment == NULL) {\r
427 return EFI_OUT_OF_RESOURCES;\r
428 }\r
429 //\r
430 // Build the fragment table.\r
431 //\r
432 NetbufBuildExt (Packet, Fragment, &FragmentCount);\r
433\r
434 RxData.FragmentCount = 1;\r
435 Tcp4Io->RxToken.Packet.RxData = &RxData;\r
436 CurrentFragment = 0;\r
437 Tcp4 = Tcp4Io->Tcp4;\r
438 Status = EFI_SUCCESS;\r
439\r
440 while (CurrentFragment < FragmentCount) {\r
441 RxData.DataLength = Fragment[CurrentFragment].Len;\r
442 RxData.FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;\r
443 RxData.FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;\r
444\r
445 Status = Tcp4->Receive (Tcp4, &Tcp4Io->RxToken);\r
446 if (EFI_ERROR (Status)) {\r
447 goto ON_EXIT;\r
448 }\r
449\r
450 while (!Tcp4Io->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
451 //\r
452 // Poll until some data is received or something error happens.\r
453 //\r
454 Tcp4->Poll (Tcp4);\r
455 }\r
456\r
457 if (!Tcp4Io->IsRxDone) {\r
458 //\r
459 // Timeout occurs, cancel the receive request.\r
460 //\r
461 Tcp4->Cancel (Tcp4, &Tcp4Io->RxToken.CompletionToken);\r
462\r
463 Status = EFI_TIMEOUT;\r
464 goto ON_EXIT;\r
465 } else {\r
466 Tcp4Io->IsRxDone = FALSE;\r
467 }\r
468\r
469 if (EFI_ERROR (Tcp4Io->RxToken.CompletionToken.Status)) {\r
470 Status = Tcp4Io->RxToken.CompletionToken.Status;\r
471 goto ON_EXIT;\r
472 }\r
473\r
474 Fragment[CurrentFragment].Len -= RxData.FragmentTable[0].FragmentLength;\r
475 if (Fragment[CurrentFragment].Len == 0) {\r
476 CurrentFragment++;\r
477 } else {\r
478 Fragment[CurrentFragment].Bulk += RxData.FragmentTable[0].FragmentLength;\r
479 }\r
480 }\r
481\r
482ON_EXIT:\r
653ef62e 483 Tcp4Io->RxToken.Packet.RxData = NULL;\r
766c7483 484 FreePool (Fragment);\r
6a690e23 485\r
486 return Status;\r
487}\r