1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using Antmicro.Renode.Core; 10 using Antmicro.Renode.Core.Structure; 11 using Antmicro.Renode.Logging; 12 using Antmicro.Renode.Peripherals.Network; 13 using System.Collections.Generic; 14 using Antmicro.Renode.Utilities; 15 using Antmicro.Renode.Storage; 16 using Antmicro.Renode.Peripherals; 17 using System.Linq; 18 using System.Threading; 19 using Antmicro.Renode.Peripherals.Bus; 20 21 namespace Antmicro.Renode.Peripherals.USBDeprecated 22 { 23 public class UsbHub : IUSBHub, IUSBPeripheral 24 { 25 public event Action <uint> SendInterrupt 26 { 27 add {} 28 remove {} 29 } 30 31 public event Action <uint> SendPacket 32 { 33 add {} 34 remove {} 35 } 36 37 private readonly IMachine machine; 38 39 public event Action <uint> Connected ; 40 public event Action <uint,uint> Disconnected ; 41 public event Action <IUSBHub> RegisterHub ; 42 public event Action <IUSBPeripheral> ActiveDevice ; 43 44 byte[] controlPacket; 45 46 public byte NumberOfPorts { get; set; } 47 WriteDataControl(USBPacket packet)48 public void WriteDataControl(USBPacket packet) 49 { 50 //throw new System.NotImplementedException(); 51 } 52 GetTransferStatus()53 public byte GetTransferStatus() 54 { 55 return 0; 56 } 57 GetSpeed()58 public USBDeviceSpeed GetSpeed() 59 { 60 return USBDeviceSpeed.High; 61 } 62 WriteDataBulk(USBPacket packet)63 public void WriteDataBulk(USBPacket packet) 64 { 65 // throw new System.NotImplementedException(); 66 } 67 GetDataControl(USBPacket packet)68 public byte[] GetDataControl(USBPacket packet) 69 { 70 return controlPacket; 71 } 72 GetDataBulk(USBPacket packet)73 public byte[] GetDataBulk(USBPacket packet) 74 { 75 throw new System.NotImplementedException(); 76 // return 77 } 78 79 uint DeviceAddress; 80 GetAddress()81 public uint GetAddress() 82 { 83 return DeviceAddress; 84 } 85 UsbHub(IMachine machine)86 public UsbHub(IMachine machine) 87 { 88 this.machine = machine; 89 registeredDevices = new Dictionary<byte, IUSBPeripheral>(); 90 endpointDescriptor = new EndpointUSBDescriptor[NumberOfEndpoints]; 91 NumberOfPorts = 3; 92 ports = new uint [NumberOfPorts]; 93 hubDescriptor.NbrPorts = NumberOfPorts; 94 for(int i=0; i<NumberOfEndpoints; i++) 95 { 96 endpointDescriptor[i] = new EndpointUSBDescriptor(); 97 } 98 fillEndpointsDescriptors(endpointDescriptor); 99 interfaceDescriptor[0].EndpointDescriptor = endpointDescriptor; 100 configurationDescriptor.InterfaceDescriptor = interfaceDescriptor; 101 102 for(int i=0; i<NumberOfPorts; i++) 103 { 104 ports[i] = (uint)PortStatus.PortPower; 105 } 106 } 107 UsbHub(IMachine machine, byte nrPorts)108 public UsbHub(IMachine machine, byte nrPorts) 109 { 110 this.machine = machine; 111 registeredDevices = new Dictionary<byte, IUSBPeripheral>(); 112 endpointDescriptor = new EndpointUSBDescriptor[3]; 113 NumberOfPorts = nrPorts; 114 ports = new uint [NumberOfPorts]; 115 hubDescriptor.NbrPorts = NumberOfPorts; 116 for(int i=0; i<NumberOfEndpoints; i++) 117 { 118 endpointDescriptor[i] = new EndpointUSBDescriptor(); 119 } 120 fillEndpointsDescriptors(endpointDescriptor); 121 interfaceDescriptor[0].EndpointDescriptor = endpointDescriptor; 122 configurationDescriptor.InterfaceDescriptor = interfaceDescriptor; 123 124 for(int i=0; i<NumberOfPorts; i++) 125 { 126 ports[i] = (uint)PortStatus.PortPower; 127 } 128 } 129 130 public IUSBHub Parent 131 { 132 get; 133 set; 134 } 135 136 Register(IUSBPeripheral peripheral, USBRegistrationPoint registrationPoint)137 public void Register(IUSBPeripheral peripheral, USBRegistrationPoint registrationPoint) 138 { 139 AttachDevice(peripheral, registrationPoint.Address.Value); 140 machine.RegisterAsAChildOf(this, peripheral, registrationPoint); 141 registrationPoints.Add(peripheral, registrationPoint); 142 } 143 Register(IUSBHub peripheral, USBRegistrationPoint registrationPoint)144 public void Register(IUSBHub peripheral, USBRegistrationPoint registrationPoint) 145 { 146 peripheral.Connected += Connected; 147 peripheral.Disconnected += Disconnected; 148 peripheral.RegisterHub += RegisterHub; 149 peripheral.ActiveDevice += ActiveDevice; 150 AttachDevice(peripheral, registrationPoint.Address.Value); 151 machine.RegisterAsAChildOf(this, peripheral, registrationPoint); 152 } 153 Unregister(IUSBHub peripheral)154 public void Unregister(IUSBHub peripheral) 155 { 156 var port = registeredDevices.FirstOrDefault(x => x.Value == peripheral).Key; 157 DetachDevice(port); 158 machine.UnregisterAsAChildOf(this, peripheral); 159 registrationPoints.Remove(peripheral); 160 registeredDevices.Remove(port); 161 } 162 Unregister(IUSBPeripheral peripheral)163 public void Unregister(IUSBPeripheral peripheral) 164 { 165 DetachDevice(registrationPoints[peripheral].Address.Value); 166 machine.UnregisterAsAChildOf(this, registrationPoints[peripheral]); 167 registrationPoints.Remove(peripheral); 168 } 169 GetRegistrationPoints(IUSBPeripheral peripheral)170 public IEnumerable<USBRegistrationPoint> GetRegistrationPoints(IUSBPeripheral peripheral) 171 { 172 throw new System.NotImplementedException(); 173 } 174 175 public IEnumerable<IRegistered<IUSBPeripheral, USBRegistrationPoint>> Children 176 { 177 get 178 { 179 throw new System.NotImplementedException(); 180 } 181 } 182 GetDevice(byte port)183 public IUSBPeripheral GetDevice(byte port) 184 { 185 if(registeredDevices.ContainsKey(port)) 186 { 187 return registeredDevices[port]; 188 } 189 else 190 { 191 return null; 192 } 193 } 194 AttachDevice(IUSBPeripheral device, byte port)195 public void AttachDevice(IUSBPeripheral device, byte port) 196 { 197 if (device.GetSpeed()==USBDeviceSpeed.High) 198 ports[port - 1] |= (uint)PortStatus.CPortConnection | (uint)PortStatus.PortConnection | (uint)PortStatus.PortHighSpeed; 199 else 200 if (device.GetSpeed()==USBDeviceSpeed.Low) 201 ports[port - 1] |= (uint)PortStatus.CPortConnection | (uint)PortStatus.PortConnection | (uint)PortStatus.PortLowSpeed; 202 else 203 ports[port - 1] |= (uint)PortStatus.CPortConnection | (uint)PortStatus.PortConnection; 204 205 registeredDevices.Add(port, device); 206 207 changed = true; 208 /* Connect device to controller and send interrupt*/ 209 var connected = Connected; 210 if(connected != null) 211 { 212 connected(DeviceAddress); 213 } 214 } 215 DetachDevice(byte port)216 public void DetachDevice(byte port) 217 { 218 changed = true; 219 ports[port - 1] &= (~(uint)PortStatus.PortConnection); 220 ports[port - 1] |= ((uint)PortStatus.CPortConnection); 221 if((ports[port - 1] & (uint)PortStatus.PortEnable) != 0) 222 { 223 ports[port - 1] &= ~((uint)PortStatus.PortEnable); 224 ports[port - 1] |= ((uint)PortStatus.CPortEnable); 225 } 226 /* Disconnect device from controller and send interrupt*/ 227 Disconnected(DeviceAddress, registeredDevices[port].GetAddress()); 228 /* Unregister device from controller */ 229 registeredDevices.Remove(port); 230 } 231 Reset()232 public void Reset() 233 { 234 for(int i=0; i<NumberOfPorts; i++) 235 { 236 if ((ports[i] & (uint)PortStatus.PortEnable)!=0) 237 ports[i] = (uint)PortStatus.CPortConnection | (uint)PortStatus.PortConnection | 1 << 10; 238 } 239 } 240 241 private readonly Dictionary<IUSBPeripheral, USBRegistrationPoint> registrationPoints = new Dictionary<IUSBPeripheral, USBRegistrationPoint>(); 242 private Dictionary <byte,IUSBPeripheral> registeredDevices; 243 244 #region IUSBDevice implementation ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket)245 public byte[] ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket) 246 { 247 byte[] returnValue; 248 //MessageRecipient recipient = (MessageRecipient)(setupPacket.requestType & 0x3); 249 ushort index = setupPacket.index; 250 byte request = setupPacket.request; 251 //ushort value = setupPacket.value; 252 returnValue = new byte[4]; 253 switch((HUBRequestCode)request) 254 { 255 case HUBRequestCode.GetStatus: 256 if(index == 0) 257 { 258 returnValue[0] = 0; 259 returnValue[1] = 0; 260 returnValue[2] = 0; 261 returnValue[3] = 0; 262 controlPacket = returnValue; 263 return controlPacket; 264 } 265 else 266 { 267 if(index - 1 < NumberOfPorts) 268 { 269 returnValue[0] = (byte)ports[index - 1]; 270 returnValue[1] = (byte)(ports[index - 1] >> 8); 271 returnValue[2] = (byte)(ports[index - 1] >> 16); 272 returnValue[3] = (byte)(ports[index - 1] >> 24); 273 } 274 else 275 { 276 return null; 277 } 278 controlPacket = returnValue; 279 return controlPacket; 280 } 281 case HUBRequestCode.GetHubDescriptor: 282 controlPacket = hubDescriptor.ToArray(); 283 return controlPacket; 284 default: 285 controlPacket = new byte[0]; 286 this.Log(LogLevel.Warning, "Unsupported HUB ProcessClassGet request!!!"); 287 return controlPacket; 288 } 289 } 290 ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket)291 public void ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket) 292 { 293 //MessageRecipient recipient = (MessageRecipient)(setupPacket.requestType & 0x3); 294 ushort index = setupPacket.index; 295 byte request = setupPacket.request; 296 ushort value = setupPacket.value; 297 switch((HUBRequestCode)request) 298 { 299 case HUBRequestCode.ClearHubFeature: 300 if(index > 0) 301 { 302 switch((PortFeature)value) 303 { 304 case PortFeature.CPortSuspend: 305 ports[index - 1] = (uint)(ports[index - 1] & (~((uint)PortStatus.CPortSuspend))); 306 break; 307 case PortFeature.CPortOverCurrent: 308 ports[index - 1] = (uint)(ports[index - 1] & (~((uint)PortStatus.CPortOverCurrent))); 309 break; 310 case PortFeature.CPortEnable: 311 ports[index - 1] = (uint)(ports[index - 1] & (~((uint)PortStatus.CPortEnable))); 312 break; 313 case PortFeature.PortEnable: 314 ports[index - 1] = (uint)(ports[index - 1] & (uint)PortStatus.PortEnable); 315 break; 316 case PortFeature.PortSuspend: 317 ports[index - 1] = (uint)(ports[index - 1] & (uint)PortStatus.PortSuspend); 318 break; 319 case PortFeature.CPortConnection: 320 ports[index - 1] = (uint)(ports[index - 1] & (~((uint)PortStatus.CPortConnection))); 321 break; 322 case PortFeature.CPortReset: 323 ActiveDevice(this.GetDevice((byte)(index))); 324 ports[index - 1] = (uint)(ports[index - 1] & (~((uint)PortStatus.CPortReset))); 325 break; 326 default: 327 this.Log(LogLevel.Warning, "Unsupported ClearHubFeature request!!!"); 328 break; 329 } 330 } 331 break; 332 case HUBRequestCode.SetHubFeature: 333 if(index > 0) 334 { 335 if((PortFeature)value == PortFeature.PortReset) 336 { 337 IUSBPeripheral device = GetDevice((byte)(index)); 338 ports[index - 1] |= (uint)PortStatus.CPortReset; 339 ports[index - 1] |= (uint)PortStatus.PortEnable; 340 if(device != null) 341 { 342 device.SetAddress(0); 343 device.Reset(); 344 } 345 } 346 else if((PortFeature)value == PortFeature.PortSuspend) 347 { 348 ports[index - 1] |= (uint)PortStatus.PortSuspend; 349 } 350 } 351 352 break; 353 default: 354 this.Log(LogLevel.Warning, "Unsupported HUB ProcessClassSet request!!!"); 355 break; 356 } 357 } 358 SetDataToggle(byte endpointNumber)359 public void SetDataToggle(byte endpointNumber) 360 { 361 throw new NotImplementedException(); 362 } 363 CleanDataToggle(byte endpointNumber)364 public void CleanDataToggle(byte endpointNumber) 365 { 366 throw new NotImplementedException(); 367 } 368 ToggleDataToggle(byte endpointNumber)369 public void ToggleDataToggle(byte endpointNumber) 370 { 371 throw new NotImplementedException(); 372 } 373 GetDataToggle(byte endpointNumber)374 public bool GetDataToggle(byte endpointNumber) 375 { 376 throw new NotImplementedException(); 377 } 378 ClearFeature(USBPacket packet, USBSetupPacket setupPacket)379 public void ClearFeature(USBPacket packet, USBSetupPacket setupPacket) 380 { 381 throw new NotImplementedException(); 382 } 383 GetConfiguration()384 public byte[] GetConfiguration() 385 { 386 throw new NotImplementedException(); 387 } 388 GetDescriptor(USBPacket packet, USBSetupPacket setupPacket)389 public byte[] GetDescriptor(USBPacket packet, USBSetupPacket setupPacket) 390 { 391 DescriptorType type; 392 type = (DescriptorType)((setupPacket.value & 0xff00) >> 8); 393 uint index = (uint)(setupPacket.value & 0xff); 394 switch(type) 395 { 396 case DescriptorType.Device: 397 controlPacket = new byte[deviceDescriptor.ToArray().Length]; 398 deviceDescriptor.ToArray().CopyTo(controlPacket, 0); 399 return deviceDescriptor.ToArray(); 400 case DescriptorType.Configuration: 401 controlPacket = new byte[configurationDescriptor.ToArray().Length]; 402 configurationDescriptor.ToArray().CopyTo(controlPacket, 0); 403 return configurationDescriptor.ToArray(); 404 case DescriptorType.DeviceQualifier: 405 controlPacket = new byte[deviceQualifierDescriptor.ToArray().Length]; 406 deviceQualifierDescriptor.ToArray().CopyTo(controlPacket, 0); 407 return deviceQualifierDescriptor.ToArray(); 408 case DescriptorType.InterfacePower: 409 throw new NotImplementedException("Interface Power Descriptor is not yet implemented. Please contact AntMicro for further support."); 410 case DescriptorType.OtherSpeedConfiguration: 411 controlPacket = new byte[otherConfigurationDescriptor.ToArray().Length]; 412 otherConfigurationDescriptor.ToArray().CopyTo(controlPacket, 0); 413 return otherConfigurationDescriptor.ToArray(); 414 case DescriptorType.String: 415 if(index == 0) 416 { 417 stringDescriptor = new StringUSBDescriptor(1); 418 stringDescriptor.LangId[0] = EnglishLangId; 419 } 420 else 421 { 422 stringDescriptor = new StringUSBDescriptor(stringValues[setupPacket.index][index]); 423 } 424 controlPacket = new byte[stringDescriptor.ToArray().Length]; 425 stringDescriptor.ToArray().CopyTo(controlPacket, 0); 426 return stringDescriptor.ToArray(); 427 default: 428 this.Log(LogLevel.Warning, "Unsupported HUB GetDescriptor request!!!"); 429 return null; 430 } 431 } 432 GetInterface(USBPacket packet, USBSetupPacket setupPacket)433 public byte[] GetInterface(USBPacket packet, USBSetupPacket setupPacket) 434 { 435 throw new NotImplementedException(); 436 } 437 GetStatus(USBPacket packet, USBSetupPacket setupPacket)438 public byte[] GetStatus(USBPacket packet, USBSetupPacket setupPacket) 439 { 440 var arr = new byte[2]; 441 MessageRecipient recipient = (MessageRecipient)(setupPacket.requestType & 0x3); 442 switch(recipient) 443 { 444 case MessageRecipient.Device: 445 arr[0] = (byte)(((configurationDescriptor.RemoteWakeup ? 1 : 0) << 1) | (configurationDescriptor.SelfPowered ? 1 : 0)); 446 break; 447 case MessageRecipient.Endpoint: 448 goto default; 449 default: 450 arr[0] = 0; 451 break; 452 } 453 controlPacket = new byte[arr.Length]; 454 arr.CopyTo(controlPacket, 0); 455 return arr; 456 } 457 SetAddress(uint address)458 public void SetAddress(uint address) 459 { 460 DeviceAddress = address; 461 } 462 SetConfiguration(USBPacket packet, USBSetupPacket setupPacket)463 public void SetConfiguration(USBPacket packet, USBSetupPacket setupPacket) 464 { 465 //throw new NotImplementedException(); 466 } 467 SetDescriptor(USBPacket packet, USBSetupPacket setupPacket)468 public void SetDescriptor(USBPacket packet, USBSetupPacket setupPacket) 469 { 470 throw new NotImplementedException(); 471 } 472 SetFeature(USBPacket packet, USBSetupPacket setupPacket)473 public void SetFeature(USBPacket packet, USBSetupPacket setupPacket) 474 { 475 throw new NotImplementedException(); 476 } 477 SetInterface(USBPacket packet, USBSetupPacket setupPacket)478 public void SetInterface(USBPacket packet, USBSetupPacket setupPacket) 479 { 480 throw new NotImplementedException(); 481 } 482 SyncFrame(uint endpointId)483 public void SyncFrame(uint endpointId) 484 { 485 throw new NotImplementedException(); 486 } 487 WriteData(byte[] data)488 public void WriteData(byte[] data) 489 { 490 return; 491 } 492 493 public int ii = 0; 494 bool changed = false; 495 WriteInterrupt(USBPacket packet)496 public byte[] WriteInterrupt(USBPacket packet) 497 { 498 499 byte [] buf = new byte[8]; 500 buf[0] = 0x00; 501 buf[1] = 0x00; 502 buf[2] = 0x00; 503 buf[3] = 0x00; 504 buf[4] = 0x00; 505 buf[5] = 0x00; 506 buf[6] = 0x00; 507 buf[7] = 0x00; 508 509 int status = 0; 510 for(int i = 0; i < NumberOfPorts; i++) 511 { 512 if(((ports[i] >> 16) & 0xffff) != 0) 513 { 514 status |= (1 << (i + 1)); 515 } 516 } 517 if(status != 0) 518 { 519 for(int i = 0; i < 1; i++) 520 { 521 buf[i] = (byte)(status >> (8 * i)); 522 } 523 524 if(changed == true) 525 { 526 changed = false; 527 return buf; 528 } 529 else 530 { 531 return null; 532 } 533 } 534 else 535 { 536 return null; 537 } 538 } 539 ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket)540 public byte[] ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket) 541 { 542 throw new NotImplementedException(); 543 } 544 ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket)545 public void ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket) 546 { 547 throw new NotImplementedException(); 548 } 549 #endregion 550 551 552 #region Device constans 553 private const byte maxLun = 0; 554 private const byte NumberOfEndpoints = 1; 555 private const ushort EnglishLangId = 0x09; 556 #endregion 557 558 559 560 #region USB descriptors 561 562 private ConfigurationUSBDescriptor configurationDescriptor = new ConfigurationUSBDescriptor() 563 { 564 ConfigurationIndex = 0, 565 SelfPowered = true, 566 NumberOfInterfaces = 1, 567 RemoteWakeup = true, 568 MaxPower = 10, //500mA 569 ConfigurationValue = 1 570 }; 571 private ConfigurationUSBDescriptor otherConfigurationDescriptor = new ConfigurationUSBDescriptor(); 572 private StringUSBDescriptor stringDescriptor = null; 573 private StandardUSBDescriptor deviceDescriptor = new StandardUSBDescriptor 574 { 575 DeviceClass=0x09,//specified in interface descritor 576 DeviceSubClass = 0x00,//specified in interface descritor 577 USB = 0x0200, 578 DeviceProtocol = 0x01,//specified in interface descritor 579 MaxPacketSize = 64, 580 VendorId = 0x05e3, 581 ProductId = 0x0608, 582 Device = 0x0901, 583 ManufacturerIndex = 0, 584 ProductIndex = 0, 585 SerialNumberIndex = 0, 586 NumberOfConfigurations = 1 587 }; 588 private DeviceQualifierUSBDescriptor deviceQualifierDescriptor = new DeviceQualifierUSBDescriptor(); 589 private EndpointUSBDescriptor[] endpointDescriptor; 590 private InterfaceUSBDescriptor[] interfaceDescriptor = new[]{new InterfaceUSBDescriptor 591 { 592 AlternateSetting = 0, 593 InterfaceNumber = 0, 594 NumberOfEndpoints = NumberOfEndpoints, 595 InterfaceClass = 0x09, //vendor specific 596 InterfaceProtocol = 0x01, 597 InterfaceSubClass = 0x00, 598 InterfaceIndex = 0 599 } 600 }; 601 private Dictionary<ushort, string[]> stringValues = new Dictionary<ushort, string[]>() 602 { 603 {EnglishLangId, new string[]{ 604 "", 605 "HUB USB", 606 "0xALLMAN", 607 "Configuration", 608 "AntMicro" 609 }} 610 }; 611 private HubUSBDescriptor hubDescriptor = new HubUSBDescriptor 612 { 613 NbrPorts = (byte)3, 614 HubCharacteristics=0x0089, 615 PwrOn2PwrGood =0x10, 616 HubContrCurrent = 0x00 617 }; 618 fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc)619 private void fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc) 620 { 621 endpointDesc[0].EndpointNumber = 1; 622 endpointDesc[0].InEnpoint = true; 623 endpointDesc[0].TransferType = EndpointUSBDescriptor.TransferTypeEnum.Interrupt; 624 endpointDesc[0].MaxPacketSize = 0x1; 625 endpointDesc[0].SynchronizationType = EndpointUSBDescriptor.SynchronizationTypeEnum.NoSynchronization; 626 endpointDesc[0].UsageType = EndpointUSBDescriptor.UsageTypeEnum.Data; 627 endpointDesc[0].Interval = 12; 628 629 } 630 public class HubUSBDescriptor:USBDescriptor 631 { HubUSBDescriptor()632 public HubUSBDescriptor() 633 { 634 Type = (DescriptorType)0x29; 635 Length = 0x9; 636 } 637 638 public byte NbrPorts { get; set; } 639 640 public ushort HubCharacteristics { get; set; } 641 642 public byte PwrOn2PwrGood { get; set; } 643 644 public byte HubContrCurrent { get; set; } 645 ToArray()646 public override byte[] ToArray() 647 { 648 var arr = base.ToArray(); 649 arr[0x2] = NbrPorts; 650 arr[0x3] = HubCharacteristics.LoByte(); 651 arr[0x4] = HubCharacteristics.HiByte(); 652 arr[0x5] = PwrOn2PwrGood; 653 arr[0x6] = HubContrCurrent; 654 arr[0x7] = 0x00; 655 arr[0x8] = 0xff; 656 return arr; 657 } 658 } 659 660 private enum HUBRequestCode 661 { 662 GetStatus = 0x00, 663 ClearHubFeature=0x01, 664 SetHubFeature = 0x03, 665 GetHubDescriptor = 0x06 666 } 667 668 private enum PortFeature 669 { 670 PortConnection=0, 671 PortEnable=1, 672 PortSuspend=2, 673 PortOverCurrent=3, 674 PortReset=4, 675 PortPower=8, 676 PortLowSpeed1=9, 677 CPortConnection=16, 678 CPortEnable=17, 679 CPortSuspend=18, 680 CPortOverCurrent=19, 681 CPortReset=20 682 } 683 684 private enum PortStatus 685 { 686 PortConnection=0x0001, 687 PortEnable=0x0002, 688 PortSuspend=0x0004, 689 PortOverCurrent=0x0008, 690 PortReset=0x0010, 691 PortPower=0x0100, 692 PortLowSpeed=0x0200, 693 PortHighSpeed=0x0400, 694 CPortConnection=0x10000, 695 CPortEnable=0x20000, 696 CPortSuspend=0x40000, 697 CPortOverCurrent=0x80000, 698 CPortReset=0x100000 699 } 700 public uint[] ports; 701 #endregion 702 703 } 704 } 705