Пример #1
0
 /// <summary>
 /// Initializes a qTD with specified underlying data structure.
 /// </summary>
 /// <param name="aqTD">The existing underlying data structure.</param>
 public EHCI_qTD(EHCI_qTD_Struct* aqTD)
 {
     qtd = aqTD;
 }
Пример #2
0
        /// <summary>
        /// Allocates memory for a new qTD and does initialisation common to all qTD types.
        /// </summary>
        /// <param name="next">A pointer to the next qTD in the linked list or 1 to specify no pointer.</param>
        /// <returns>The new qTD.</returns>
        protected static EHCI_qTD AllocAndInitQTD(EHCI_qTD_Struct* next)
        {
            EHCI_qTD newQTD = new EHCI_qTD();

            if (next != null)
            {
                newQTD.NextqTDPointerTerminate = false;
                newQTD.NextqTDPointer = (EHCI_qTD_Struct*)VirtMemManager.GetPhysicalAddress(next);
            }
            else
            {
                newQTD.NextqTDPointerTerminate = true;
            }

            newQTD.AlternateNextqTDPointerTerminate = true;  // No alternate next, so T-Bit is set to 1
            newQTD.Status = 0x80; // This will be filled by the Host Controller. Active bit set
            newQTD.ErrorCounter = 0x0;  // Written by the Host Controller.
            newQTD.CurrentPage = 0x0;  // Written by the Host Controller.
            newQTD.InterruptOnComplete = false; //Set only for the last transaction of a transfer

            return newQTD;
        }
Пример #3
0
        /// <summary>
        /// Creates and initialises a new qTD as a SETUP qTD.
        /// </summary>
        /// <param name="next">A pointer to the next qTD in the linked list or 1 to specify no pointer.</param>
        /// <param name="toggle">The toggle state for the new qTD.</param>
        /// <param name="tokenBytes">The number of bytes to transfer.</param>
        /// <param name="type">The USB Request type.</param>
        /// <param name="req">The specific USB Request.</param>
        /// <param name="hiVal">The USB Request Hi-Val.</param>
        /// <param name="loVal">The USB Request Lo-Val.</param>
        /// <param name="index">The index of the USB Request.</param>
        /// <param name="length">The length of the USB Request.</param>
        /// <returns>The new qTD.</returns>
        protected EHCI_qTD CreateQTD_SETUP(EHCI_qTD_Struct* next, bool toggle, ushort tokenBytes, byte type, byte req,
                                                 byte hiVal, byte loVal, ushort index, ushort length)
        {
            EHCI_qTD td = AllocAndInitQTD(next);

            td.PIDCode = (byte)EHCI_qTDTypes.SETUP;      // SETUP = 2
            td.TotalBytesToTransfer = tokenBytes; // dependent on transfer
            td.DataToggle = toggle;     // Should be toggled every list entry

            USBRequest* request = (USBRequest*)(AllocQTDbuffer(td));
            request->type = type;
            request->request = req;
            request->valueHi = hiVal;
            request->valueLo = loVal;
            request->index = index;
            request->length = length;
            
            return td;
        }
Пример #4
0
        /// <summary>
        /// Creates a new qTD and initialises it as an IN or OUT qTD.
        /// </summary>
        /// <param name="next">A pointer to the next qTD in the linked list or 1 to specify no pointer.</param>
        /// <param name="direction">The direction of the qTD (in or out)</param>
        /// <param name="toggle">The toggle state for the new qTD.</param>
        /// <param name="tokenBytes">The number of bytes to transfer.</param>
        /// <param name="bufferSize">The size of the qTD data buffer.</param>
        /// <returns>The new qTD.</returns>
        protected EHCI_qTD CreateQTD_IO(EHCI_qTD_Struct* next, byte direction, bool toggle, ushort tokenBytes, uint bufferSize)
        {
            EHCI_qTD td = AllocAndInitQTD(next);

            td.PIDCode = direction;
            td.TotalBytesToTransfer = tokenBytes; // dependent on transfer
            td.DataToggle = toggle;     // Should be toggled every list entry

            AllocQTDbuffer(td);

            return td;
        }
Пример #5
0
 /// <summary>
 /// Initialises a queue head - memory must already be allocated.
 /// </summary>
 /// <param name="headPtr">A pointer to the queue head structure to initialise.</param>
 /// <param name="horizPtr">
 /// The virtual address of the next queue head in the list (or the first queue head since the 
 /// async queue is a circular buffer). This is translated into the physical address internally.
 /// </param>
 /// <param name="firstQTD">A pointer to the first qTD of the queue head.</param>
 /// <param name="H">The Head of Reclamation list flag.</param>
 /// <param name="deviceAddr">The address of the USB device to which this queue head belongs.</param>
 /// <param name="endpoint">The endpoint number of the USB device to which this queue head belongs.</param>
 /// <param name="maxPacketSize">The maximum packet size to use when transferring.</param>
 protected void InitQH(EHCI_QueueHead_Struct* headPtr, EHCI_QueueHead_Struct* horizPtr, EHCI_qTD_Struct* firstQTD, bool H, byte deviceAddr,
                            byte endpoint, ushort maxPacketSize)
 {
     EHCI_QueueHead head = new EHCI_QueueHead(headPtr);
     head.HorizontalLinkPointer = (EHCI_QueueHead_Struct*)VirtMemManager.GetPhysicalAddress(horizPtr);
     head.Type = 0x1;        // Types:  00b iTD,   01b QH,   10b siTD,   11b FSTN
     head.Terminate = false;
     head.DeviceAddress = deviceAddr;         // The device address
     head.InactiveOnNextTransaction = false;
     head.EndpointNumber = endpoint;       // endpoint 0 contains Device infos such as name
     head.EndpointSpeed = 2;              // 00b = full speed; 01b = low speed; 10b = high speed
     head.DataToggleControl = true;              // get the Data Toggle bit out of the included qTD
     head.HeadOfReclamationList = H;              // mark a queue head as being the head of the reclaim list
     head.MaximumPacketLength = maxPacketSize;     // 64 byte for a control transfer to a high speed device
     head.ControlEndpointFlag = false;              // only used if endpoint is a control endpoint and not high speed
     head.NakCountReload = 0;              // this value is used by EHCI to reload the Nak Counter field. 0=ignores NAK counter.
     head.InterruptScheduleMask = 0;              // not used for async schedule
     head.SplitCompletionMask = 0;              // unused if (not low/full speed and in periodic schedule)
     head.HubAddr = 0;              // unused if high speed (Split transfer)
     head.PortNumber = 0;              // unused if high speed (Split transfer)
     head.HighBandwidthPipeMultiplier = 1;              // 1-3 transaction per micro-frame, 0 means undefined results
     if (firstQTD == null)
     {
         head.NextqTDPointer = null;
         head.NextqTDPointerTerminate = true;
     }
     else
     {
         head.NextqTDPointer = (EHCI_qTD_Struct*)VirtMemManager.GetPhysicalAddress(firstQTD);
         head.NextqTDPointerTerminate = false;
     }
 }