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