/// <summary> /// Control USB Device /// </summary> /// <param name="dev"></param> /// <param name="transfer"></param> private static void Control(USBDevice dev, USBTransfer *transfer) { USBDeviceRequest request = transfer->Request; #if __UHCI_DIAG Console.WriteLine("------ UHCI Control message ---------"); Console.Write("Request: "); Console.WriteHex(request.Request); Console.WriteLine(""); Console.Write("Index: "); Console.WriteHex(request.Index); Console.WriteLine(""); Console.Write("Length:"); Console.WriteHex(request.Length); Console.WriteLine(""); Console.Write("Type:"); Console.WriteHex(request.Type); Console.WriteLine(""); Console.Write("Value:"); Console.WriteHex(request.Value); Console.WriteLine(""); Console.WriteLine("--------------------------------------"); #endif UHCIController controller = (UHCIController)dev.Controller; UHCITransmitDescriptor *td = GetTransmit(controller); UHCITransmitDescriptor *head = td; UHCITransmitDescriptor *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 = GetTransmit(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 = GetTransmit(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); UHCIQueueHead *qh = GetQueueHead(controller); qh->Element = (int)Paging.GetPhysicalFromVirtual(head); qh->Head = 0; qh->Transfer = transfer; qh->Transmit = head; InsertHead(controller, qh); WaitForQueueHead(controller, qh); }
/// <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); }