Пример #1
0
        private static void InitTransmit(EHCITransferDescriptor *td, EHCITransferDescriptor *previous,
                                         USBDeviceSpeed speed, uint address, uint endp, uint toggle, uint type, uint len, byte *data)
        {
            td->NextLink = TD_TERMINATE;
            td->Reserved = TD_TERMINATE;
            td->Next     = null;

            // Add link
            if (previous != null)
            {
                previous->NextLink = (int)td;
                previous->Next     = td;
            }

            // Set token
            td->Token = (int)((toggle << TD_TOK_TOGGLE_SHIFT) |
                              (len << TD_TOK_TBTT_SHIFT) |
                              (3 << TD_TOK_CERR_SHIFT) |
                              (type << TD_TOK_PID_SHIFT) |
                              TD_TOK_STATUS_ACTIVE);

            // Set data buffer
            int ptr = (int)data;

            td->Buffer[0]    = ptr;
            td->ExtBuffer[0] = (ptr >> 32);
            ptr &= ~0xFFF;

            for (int i = 1; i < 4; i++)
            {
                ptr             += 0x1000;
                td->Buffer[i]    = ptr;
                td->ExtBuffer[i] = (ptr >> 32);
            }
        }
Пример #2
0
        /// <summary>
        /// Process Queue Head
        /// </summary>
        /// <param name="device"></param>
        /// <param name="head"></param>
        public static void ProcessHead(EHCIController controller, EHCIQueueHead *head)
        {
            USBTransfer *transfer = head->Transfer;

            EHCITransferDescriptor *td = head->Transmit;

            Console.WriteHex(td->Token);
            Console.WriteLine(" :)");

            if (transfer->Executed)
            {
                //if(transfer->ID > 0)
                //{
                //    PrintQueue(transfer->ID, head);
                //}

                head->Transfer = null;

                /**
                 * We need to toggle endpoint state here
                 */

                /**
                 * Remove head from schedule
                 */
                RemoveHead(controller, head);

                /**
                 * Free transmit descriptors
                 */
                EHCITransferDescriptor *tdE = td;

                while (tdE != null)
                {
                    EHCITransferDescriptor *next = tdE->Next;
                    FreeTransmit(controller, tdE);
                    tdE = next;
                }
            }
        }
Пример #3
0
 public static void FreeTransmit(EHCIController controller, EHCITransferDescriptor *transmit)
 {
     transmit->Allocated = false;
 }
Пример #4
0
        private unsafe static EHCITransferDescriptor *AllocateEmptyTransmit(EHCIController controller)
        {
            EHCITransferDescriptor *queueHead = GetTransmitDescriptor(controller);

            return(queueHead);
        }
Пример #5
0
        /// <summary>
        /// Control USB Device
        /// </summary>
        /// <param name="dev"></param>
        /// <param name="transfer"></param>
        private unsafe static void Control(USBDevice dev, USBTransfer *transfer)
        {
            USBDeviceRequest request = transfer->Request;

            transfer->Executed = false;

            EHCIController controller = (EHCIController)dev.Controller;

            EHCITransferDescriptor *td = AllocateEmptyTransmit(controller);

            EHCITransferDescriptor *head = td;
            EHCITransferDescriptor *prev = null;

            USBDeviceRequest *a = (USBDeviceRequest *)Heap.Alloc(sizeof(USBDeviceRequest));

            a->Request = request.Request;
            a->Index   = request.Index;
            a->Length  = request.Length;
            a->Type    = request.Type;
            a->Value   = request.Value;

            InitTransmit(td, prev, dev.Speed, dev.Address, 0, 0, TRANS_PACKET_SETUP, (uint)sizeof(USBDeviceRequest), (byte *)a);
            prev = td;

            uint packetType = ((request.Type & USBDevice.TYPE_DEVICETOHOST) > 0) ? TRANS_PACKET_IN : TRANS_PACKET_OUT;

            byte *ptr        = transfer->Data;
            uint  packetSize = transfer->Length;
            uint  offset     = 0;

            uint toggle = 0;

            uint remaining = packetSize;

            while (remaining > 0)
            {
                td = AllocateEmptyTransmit(controller);
                if (td == null)
                {
                    return;
                }

                packetSize = remaining;
                if (packetSize > dev.MaxPacketSize)
                {
                    packetSize = dev.MaxPacketSize;
                }

                remaining -= packetSize;

                toggle ^= 1;

                InitTransmit(td, prev, dev.Speed, dev.Address, 0, toggle, packetType, packetSize, ptr + offset);
                prev = td;

                offset += packetSize;
            }

            td = AllocateEmptyTransmit(controller);
            if (td == null)
            {
                return;
            }

            packetType = ((request.Type & USBDevice.TYPE_DEVICETOHOST) > 0) ? TRANS_PACKET_OUT : TRANS_PACKET_IN;

            toggle = 1;
            InitTransmit(td, prev, dev.Speed, dev.Address, 0, toggle, packetType, 0, null);

            EHCIQueueHead *qh = AllocateEmptyQH(controller);

            InitHead(qh, null, dev.Address, 0, packetSize);
            qh->NextLink = (int)td;
            qh->Transmit = td;
            qh->Transfer = transfer;

            InsertHead(controller, qh);
            WaitForQueueHead(controller, qh);
        }