/*++\r
-Copyright (c) 2006, Intel Corporation\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
//\r
// timeout unit is in millisecond.\r
//\r
-#define USBFLPTIMEOUT 1000\r
-#define STALL_1_MILLI_SECOND 1000\r
\r
+#define STALL_1_MILLI_SECOND 1000\r
+#define USBFLPTIMEOUT STALL_1_MILLI_SECOND\r
+#define USBDATATIMEOUT 2 * STALL_1_MILLI_SECOND\r
//\r
// ATAPI Packet Command\r
//\r
/*++\r
\r
-Copyright (c) 2006, Intel Corporation\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
\r
ByteCount = SectorCount * BlockSize;\r
\r
- TimeOut = (UINT16) (SectorCount * USBFLPTIMEOUT);\r
+ TimeOut = (UINT16) (SectorCount * USBDATATIMEOUT);\r
\r
\r
Status = USBFloppyPacketCommand (\r
\r
ByteCount = SectorCount * BlockSize;\r
\r
- TimeOut = (UINT16) (SectorCount * USBFLPTIMEOUT);\r
+ TimeOut = (UINT16) (SectorCount * USBDATATIMEOUT);\r
\r
Status = USBFloppyPacketCommand (\r
UsbFloppyDevice,\r
--*/\r
{\r
EFI_PXE_BASE_CODE_MODE *PxebcMode;\r
+ EFI_STATUS StatCode;\r
PXE_BASECODE_DEVICE *Private;\r
+ UINT32 SubnetMask;\r
\r
//\r
// Lock the instance data and make sure started\r
//\r
+ StatCode = EFI_SUCCESS;\r
\r
if (This == NULL) {\r
DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));\r
\r
if (This->Mode == NULL || !This->Mode->Started) {\r
DEBUG ((EFI_D_ERROR, "BC was not started."));\r
- EfiReleaseLock (&Private->Lock);\r
- return EFI_NOT_STARTED;\r
+ StatCode = EFI_NOT_STARTED;\r
+ goto RELEASE_LOCK;\r
}\r
\r
PxebcMode = Private->EfiBc.Mode;\r
\r
- if (StationIpPtr != NULL) {\r
- CopyMem (&PxebcMode->StationIp, StationIpPtr, sizeof (EFI_IP_ADDRESS));\r
- Private->GoodStationIp = TRUE;\r
+ if (!Private->GoodStationIp && ((StationIpPtr == NULL) || (SubnetMaskPtr == NULL))) {\r
+ //\r
+ // It's not allowed to only set one of the two addresses while there isn't a previous\r
+ // GOOD address configuration.\r
+ //\r
+ StatCode = EFI_INVALID_PARAMETER;\r
+ goto RELEASE_LOCK;\r
}\r
\r
if (SubnetMaskPtr != NULL) {\r
- CopyMem (&PxebcMode->SubnetMask, SubnetMaskPtr, sizeof (EFI_IP_ADDRESS));\r
+ SubnetMask = SubnetMaskPtr->Addr[0];\r
+\r
+ if (SubnetMask & (SubnetMask + 1)) {\r
+ //\r
+ // the subnet mask is valid if it's with leading continuous 1 bits.\r
+ //\r
+ StatCode = EFI_INVALID_PARAMETER;\r
+ goto RELEASE_LOCK;\r
+ }\r
+ } else {\r
+ SubnetMaskPtr = &PxebcMode->SubnetMask;\r
+ SubnetMask = SubnetMaskPtr->Addr[0];\r
}\r
+\r
+ if (StationIpPtr == NULL) {\r
+ StationIpPtr = &PxebcMode->StationIp;\r
+ }\r
+\r
+ if (!IS_INADDR_UNICAST (StationIpPtr) || \r
+ ((StationIpPtr->Addr[0] | SubnetMask) == BROADCAST_IPv4)) {\r
+ //\r
+ // The station IP is not a unicast address.\r
+ //\r
+ StatCode = EFI_INVALID_PARAMETER;\r
+ goto RELEASE_LOCK;\r
+ }\r
+\r
+ CopyMem (&PxebcMode->StationIp, StationIpPtr, sizeof (EFI_IP_ADDRESS));\r
+ CopyMem (&PxebcMode->SubnetMask, SubnetMaskPtr, sizeof (EFI_IP_ADDRESS));\r
+\r
+ Private->GoodStationIp = TRUE;\r
+\r
+RELEASE_LOCK:\r
//\r
// Unlock the instance data\r
//\r
EfiReleaseLock (&Private->Lock);\r
\r
- return EFI_SUCCESS;\r
+ return StatCode;\r
}\r
\r
EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {\r