summaryrefslogtreecommitdiff
path: root/sd
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
committerDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
commit97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch)
tree46f3701832d70b420eb0fc0eb93261f9da45db3f /sd
parentef1905bf1e8825bb31120dfb27e0daf3154d859a (diff)
Initial publish
Diffstat (limited to 'sd')
-rw-r--r--sd/sdiomars/ReadMe.md24
-rw-r--r--sd/sdiomars/mars.c1124
-rw-r--r--sd/sdiomars/mars.h200
-rw-r--r--sd/sdiomars/mars.inxbin0 -> 4408 bytes
-rw-r--r--sd/sdiomars/mars.vcxproj180
-rw-r--r--sd/sdiomars/mars.vcxproj.Filters34
-rw-r--r--sd/sdiomars/ntddmars.h113
-rw-r--r--sd/sdiomars/sdiomars.sln28
8 files changed, 1703 insertions, 0 deletions
diff --git a/sd/sdiomars/ReadMe.md b/sd/sdiomars/ReadMe.md
new file mode 100644
index 00000000..313f0dd5
--- /dev/null
+++ b/sd/sdiomars/ReadMe.md
@@ -0,0 +1,24 @@
+Storage SDIO Driver
+===================
+
+This is a sample for a functional Secure Digital (SD) IO driver. The driver is written using the Kernel Mode Driver Framework. It is a driver for a generic mars development board that implements the SDIO protocol without additional functionality.
+
+## Universal Compliant
+This sample builds a Windows Universal driver. It uses only APIs and DDIs that are included in Windows Core.
+
+The mars board driver exemplifies several different functions that are essential for writing an SDIO driver that leverages KDMF and the SDBUS API. It will show how to:
+
+- Install and start an SDIO device.
+
+- Release an SDIO device.
+
+- Perform data transfers.
+
+- Alter the settings that the SDIO device uses to communicate with the SD Host Controller.
+
+For more information, see [Secure Digital (SD) Card Drivers](http://msdn.microsoft.com/en-us/library/windows/hardware/ff537945).
+
+**Note**  
+
+This sample provides an example of a minimal driver. Neither the driver nor the sample programs are intended for use in a production environment. Rather, they are intended for educational purposes and as a skeleton driver.
+
diff --git a/sd/sdiomars/mars.c b/sd/sdiomars/mars.c
new file mode 100644
index 00000000..a6225fcc
--- /dev/null
+++ b/sd/sdiomars/mars.c
@@ -0,0 +1,1124 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ Mars.c
+
+Abstract:
+Environment:
+
+ kernel
+
+Notes:
+
+
+Revision History:
+
+
+--*/
+#include "mars.h"
+
+#ifdef ALLOC_PRAGMA
+ #pragma alloc_text (INIT, DriverEntry)
+ #pragma alloc_text (PAGE, MarsEvtDeviceAdd)
+ #pragma alloc_text (PAGE, MarsEvtIoDeviceControl)
+#endif
+
+
+BOOLEAN NoisyMode = FALSE;
+
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+
+ Installable driver initialization entry point.
+ This entry point is called directly by the I/O system.
+
+Arguments:
+
+ DriverObject - pointer to the driver object
+
+ RegistryPath - pointer to a unicode string representing the path,
+ to driver-specific key in the registry.
+
+Return Value:
+
+ STATUS_SUCCESS if successful,
+ STATUS_UNSUCCESSFUL otherwise.
+
+--*/
+{
+
+ NTSTATUS status = STATUS_SUCCESS;
+ WDF_DRIVER_CONFIG config;
+
+ WDF_DRIVER_CONFIG_INIT(&config,
+ MarsEvtDeviceAdd
+ );
+
+ status = WdfDriverCreate(DriverObject,
+ RegistryPath,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &config,
+ WDF_NO_HANDLE
+ );
+
+ return status;
+}
+
+
+NTSTATUS
+MarsEvtDeviceAdd(
+ IN WDFDRIVER Driver,
+ IN PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+Routine Description:
+
+ EvtDeviceAdd is called by the framework in response to AddDevice
+ call from the PnP manager.
+
+Arguments:
+
+ Driver - Handle to a framework driver object created in DriverEntry
+
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PFDO_DATA fdoData;
+ WDF_IO_QUEUE_CONFIG queueConfig;
+ WDF_OBJECT_ATTRIBUTES fdoAttributes;
+ WDFDEVICE device;
+ WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
+ SDBUS_INTERFACE_PARAMETERS interfaceParameters = {0};
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ PAGED_CODE();
+
+ WdfDeviceInitSetPowerPageable(DeviceInit);
+
+ WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
+
+ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
+
+ //
+ // Register PNP callbacks.
+ //
+ pnpPowerCallbacks.EvtDevicePrepareHardware = MarsEvtDevicePrepareHardware;
+ pnpPowerCallbacks.EvtDeviceReleaseHardware = MarsEvtDeviceReleaseHardware;
+
+ WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&fdoAttributes);
+ WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&fdoAttributes, FDO_DATA);
+
+ status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device);
+ if (!NT_SUCCESS(status)) {
+ return status;
+ }
+
+ fdoData = MarsFdoGetData(device); //Gets device context
+
+ //
+ // Open an interface to the SD bus driver
+ //
+ status = SdBusOpenInterface(WdfDeviceWdmGetPhysicalDevice (device),
+ &fdoData->BusInterface,
+ sizeof(SDBUS_INTERFACE_STANDARD),
+ SDBUS_INTERFACE_VERSION);
+
+ if (!NT_SUCCESS(status)) {
+ return status;
+ }
+
+ interfaceParameters.Size = sizeof(SDBUS_INTERFACE_PARAMETERS);
+ interfaceParameters.TargetObject = WdfDeviceWdmGetAttachedDevice(device);
+ interfaceParameters.DeviceGeneratesInterrupts = TRUE; //change to true eventually
+ interfaceParameters.CallbackRoutine = MarsEventCallback;
+ interfaceParameters.CallbackRoutineContext = fdoData;
+
+ status = STATUS_UNSUCCESSFUL;
+ if (fdoData->BusInterface.InitializeInterface) {
+ status = (fdoData->BusInterface.InitializeInterface)(fdoData->BusInterface.Context,
+ &interfaceParameters);
+ }
+
+ if (!NT_SUCCESS(status)) {
+ return status;
+ }
+
+ //
+ // Register New device
+ //
+
+ status = WdfDeviceCreateDeviceInterface(device,
+ (LPGUID) &GUID_DEVINTERFACE_MARS,
+ NULL
+ );
+ if (!NT_SUCCESS(status)) {
+ return status;
+ }
+
+ fdoData->WdfDevice = device;
+
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchSequential);
+
+ queueConfig.EvtIoRead = MarsEvtIoRead;
+ queueConfig.EvtIoWrite = MarsEvtIoWrite;
+ queueConfig.EvtIoDeviceControl = MarsEvtIoDeviceControl;
+
+ status = WdfIoQueueCreate(device,
+ &queueConfig,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &fdoData->IoctlQueue
+ );
+
+ return status;
+}
+
+NTSTATUS
+MarsEvtDevicePrepareHardware(
+ WDFDEVICE Device,
+ WDFCMRESLIST Resources,
+ WDFCMRESLIST ResourcesTranslated
+ )
+/*++
+
+Routine Description:
+
+ EvtDevicePrepareHardware event callback performs operations that are necessary
+ to make the driver's device operational. The framework calls the driver's
+ EvtDeviceStart callback when the PnP manager sends an IRP_MN_START_DEVICE
+ request to the driver stack.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+ Resources - Handle to a collection of framework resource objects.
+ This collection identifies the raw (bus-relative) hardware
+ resources that have been assigned to the device.
+
+ ResourcesTranslated - Handle to a collection of framework resource objects.
+ This collection identifies the translated (system-physical)
+ hardware resources that have been assigned to the device.
+ The resources appear from the CPU's point of view.
+ Use this list of resources to map I/O space and
+ device-accessible memory into virtual address space
+
+Return Value:
+
+ WDF status code
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ USHORT maxBlockLength;
+ USHORT hostBlockLength;
+ PFDO_DATA fdoData;
+
+ UNREFERENCED_PARAMETER(Resources);
+ UNREFERENCED_PARAMETER(ResourcesTranslated);
+
+ fdoData = MarsFdoGetData(Device);
+
+ //
+ // Get the function number
+ //
+
+ status = SdioGetProperty(Device,
+ SDP_FUNCTION_NUMBER,
+ &fdoData->FunctionNumber,
+ sizeof(fdoData->FunctionNumber));
+
+ if (!NT_SUCCESS(status)) {
+ return status;
+ }
+
+ fdoData->FunctionFocus = fdoData->FunctionNumber;
+
+
+ //
+ // Get the SD bus driver version
+ //
+
+ fdoData->DriverVersion = SDBUS_DRIVER_VERSION_1;
+
+ SdioGetProperty(Device,
+ SDP_BUS_DRIVER_VERSION,
+ &fdoData->DriverVersion,
+ sizeof(fdoData->DriverVersion));
+
+ if (fdoData->DriverVersion < SDBUS_DRIVER_VERSION_2) {
+ fdoData->BlockMode = 0;
+ } else {
+ fdoData->BlockMode = 1;
+ }
+
+
+ //
+ // Get the host buffer block size
+ //
+
+ status = SdioGetProperty(Device,
+ SDP_HOST_BLOCK_LENGTH,
+ &hostBlockLength,
+ sizeof(hostBlockLength));
+
+ if (!NT_SUCCESS(status)) {
+ return status;
+ }
+
+ maxBlockLength = 128; // just a value for testing
+
+ if (hostBlockLength < maxBlockLength) {
+ maxBlockLength = hostBlockLength;
+
+ }
+
+ //
+ // set the block count since the MARS board may not have any
+ // tuples in its FLASH
+ //
+
+ status = SdioSetProperty(Device,
+ SDP_FUNCTION_BLOCK_LENGTH,
+ &maxBlockLength,
+ sizeof(maxBlockLength));
+
+ return status;
+}
+
+
+NTSTATUS
+MarsEvtDeviceReleaseHardware(
+ IN WDFDEVICE Device,
+ IN WDFCMRESLIST ResourcesTranslated
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceReleaseHardware is called by the framework whenever the PnP manager
+ is revoking ownership of our resources. This may be in response to either
+ IRP_MN_STOP_DEVICE or IRP_MN_REMOVE_DEVICE. The callback is made before
+ passing down the IRP to the lower driver.
+
+ In this callback, do anything necessary to free those resources.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+ ResourcesTranslated - Handle to a collection of framework resource objects.
+ This collection identifies the translated (system-physical)
+ hardware resources that have been assigned to the device.
+ The resources appear from the CPU's point of view.
+ Use this list of resources to map I/O space and
+ device-accessible memory into virtual address space
+
+Return Value:
+
+ NTSTATUS - Failures will be logged, but not acted on.
+
+--*/
+{
+ PFDO_DATA fdoData;
+
+ UNREFERENCED_PARAMETER(ResourcesTranslated);
+
+ fdoData = MarsFdoGetData(Device);
+
+ if (fdoData->BusInterface.InterfaceDereference) {
+
+ (fdoData->BusInterface.InterfaceDereference)(fdoData->BusInterface.Context);
+ fdoData->BusInterface.InterfaceDereference = NULL;
+
+ }
+
+ return STATUS_SUCCESS;
+}
+
+//
+// Io events callbacks.
+//
+VOID
+MarsEvtIoDeviceControl(
+ IN WDFQUEUE Queue,
+ IN WDFREQUEST Request,
+ IN size_t OutputBufferLength,
+ IN size_t InputBufferLength,
+ IN ULONG IoControlCode
+ )
+/*++
+
+Routine Description:
+
+ This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
+ requests from the system.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated
+ with the I/O request.
+ Request - Handle to a framework request object.
+
+ OutputBufferLength - length of the request's output buffer,
+ if an output buffer is available.
+ InputBufferLength - length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - the driver-defined or system-defined I/O control code
+ (IOCTL) that is associated with the request.
+Return Value:
+
+ VOID
+
+--*/
+{
+ PFDO_DATA fdoData = NULL;
+ WDFDEVICE device;
+ NTSTATUS status = STATUS_SUCCESS;
+ PVOID inBuffer = NULL, outBuffer = NULL;
+ size_t bytesReturned = 0;
+ size_t size = 0;
+
+ PAGED_CODE();
+
+ //DbgPrint(("Started MarsEvtIODeviceControl\n"));
+
+ device = WdfIoQueueGetDevice(Queue);
+ fdoData = MarsFdoGetData(device); //Gets device context
+
+ //
+ // Get the ioctl input & output buffers
+ //
+ if (InputBufferLength != 0) {
+ status = WdfRequestRetrieveInputBuffer(Request,
+ InputBufferLength,
+ &inBuffer,
+ &size);
+
+ if (!NT_SUCCESS(status)) {
+ WdfRequestComplete(Request, status);
+ return;
+ }
+ }
+
+ if (OutputBufferLength != 0) {
+ status = WdfRequestRetrieveOutputBuffer(Request,
+ OutputBufferLength,
+ &outBuffer,
+ &size);
+ if (!NT_SUCCESS(status)) {
+ WdfRequestComplete(Request, status);
+ return;
+ }
+ }
+
+ switch (IoControlCode) {
+
+ case IOCTL_MARS_GET_DRIVER_VERSION:
+
+ if (OutputBufferLength < sizeof(USHORT)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ *(PUSHORT)outBuffer = fdoData->DriverVersion;
+ bytesReturned = sizeof(USHORT);
+ break;
+
+
+ case IOCTL_MARS_GET_FUNCTION_NUMBER:
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ *(PUCHAR)outBuffer = fdoData->FunctionNumber;
+ bytesReturned = sizeof(UCHAR);
+ break;
+
+
+ case IOCTL_MARS_GET_FUNCTION_FOCUS:
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ *(PUCHAR)outBuffer = fdoData->FunctionFocus;
+ bytesReturned = sizeof(UCHAR);
+ break;
+
+
+ case IOCTL_MARS_SET_FUNCTION_FOCUS:
+
+ if (InputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ fdoData->FunctionFocus = *(PUCHAR)inBuffer;
+ break;
+
+
+ //---------------------------------------------------
+ //
+ // SDP_BUS_WIDTH
+ //
+ //---------------------------------------------------
+
+ case IOCTL_MARS_GET_BUS_WIDTH:
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ status = SdioGetProperty(device, SDP_BUS_WIDTH,
+ outBuffer, sizeof(UCHAR));
+
+ if (NT_SUCCESS(status)) {
+ bytesReturned = sizeof(UCHAR);
+ }
+ break;
+
+
+ case IOCTL_MARS_SET_BUS_WIDTH:
+
+ if (InputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ status = SdioSetProperty(device, SDP_BUS_WIDTH,
+ inBuffer, sizeof(UCHAR));
+ break;
+
+
+ //---------------------------------------------------
+ //
+ // SDP_BUS_CLOCK
+ //
+ //---------------------------------------------------
+
+ case IOCTL_MARS_GET_BUS_CLOCK:
+
+ if (OutputBufferLength < sizeof(ULONG)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ status = SdioGetProperty(device, SDP_BUS_CLOCK,
+ outBuffer, sizeof(ULONG));
+
+ if (NT_SUCCESS(status)) {
+ bytesReturned = sizeof(ULONG);
+ }
+ break;
+
+
+ case IOCTL_MARS_SET_BUS_CLOCK:
+
+ if (InputBufferLength < sizeof(ULONG)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ status = SdioSetProperty(device, SDP_BUS_CLOCK,
+ inBuffer, sizeof(ULONG));
+ break;
+
+
+ //---------------------------------------------------
+ //
+ // SDP_FUNCTION_BLOCK_LENGTH
+ //
+ //---------------------------------------------------
+
+
+ case IOCTL_MARS_GET_BLOCKLEN:
+
+ if (OutputBufferLength < sizeof(USHORT)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ status = SdioGetProperty(device, SDP_FUNCTION_BLOCK_LENGTH,
+ outBuffer, sizeof(SHORT));
+
+ if (NT_SUCCESS(status)) {
+ bytesReturned = sizeof(USHORT);
+ }
+ break;
+
+
+ case IOCTL_MARS_SET_BLOCKLEN:
+
+ if (InputBufferLength < sizeof(USHORT)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ status = SdioSetProperty(device, SDP_FUNCTION_BLOCK_LENGTH,
+ inBuffer, sizeof(SHORT));
+ break;
+
+
+ //---------------------------------------------------
+ //
+ // SDP_FN0_BLOCK_LENGTH
+ //
+ //---------------------------------------------------
+
+
+ case IOCTL_MARS_GET_FN0_BLOCKLEN:
+
+ if (OutputBufferLength < sizeof(USHORT)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ status = SdioGetProperty(device, SDP_FN0_BLOCK_LENGTH,
+ outBuffer, sizeof(SHORT));
+
+ if (NT_SUCCESS(status)) {
+ bytesReturned = sizeof(USHORT);
+ }
+ break;
+
+
+ case IOCTL_MARS_SET_FN0_BLOCKLEN:
+
+ if (InputBufferLength < sizeof(USHORT)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ status = SdioSetProperty(device, SDP_FN0_BLOCK_LENGTH,
+ inBuffer, sizeof(SHORT));
+ break;
+
+
+ //---------------------------------------------------
+ //
+ // SDP_BUS_INTERFACE_CONTROL
+ //
+ //---------------------------------------------------
+
+
+ case IOCTL_MARS_GET_BUS_INTERFACE_CONTROL:
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ status = SdioGetProperty(device, SDP_BUS_INTERFACE_CONTROL,
+ outBuffer, sizeof(UCHAR));
+
+ if (NT_SUCCESS(status)) {
+ bytesReturned = sizeof(UCHAR);
+ }
+ break;
+
+
+ case IOCTL_MARS_SET_BUS_INTERFACE_CONTROL:
+
+ if (InputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ status = SdioSetProperty(device, SDP_BUS_INTERFACE_CONTROL,
+ inBuffer, sizeof(UCHAR));
+ break;
+
+
+ //---------------------------------------------------
+ //
+ // SDP_FUNCTION_INT_ENABLE
+ //
+ //---------------------------------------------------
+
+
+ case IOCTL_MARS_GET_INT_ENABLE:
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ status = SdioGetProperty(device, SDP_FUNCTION_INT_ENABLE,
+ outBuffer, sizeof(UCHAR));
+
+ if (NT_SUCCESS(status)) {
+ bytesReturned = sizeof(UCHAR);
+ }
+ break;
+
+
+ case IOCTL_MARS_SET_INT_ENABLE:
+
+ if (InputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ status = SdioSetProperty(device, SDP_FUNCTION_INT_ENABLE,
+ inBuffer, sizeof(UCHAR));
+ break;
+
+
+ //---------------------------------------------------
+ //
+ // READ/WRITE BYTE
+ //
+ //---------------------------------------------------
+
+
+ case IOCTL_MARS_READ_BYTE:
+
+ if ((InputBufferLength < sizeof(ULONG)) || (OutputBufferLength < sizeof(UCHAR))) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ status = SdioReadWriteByte(device,
+ fdoData->FunctionFocus,
+ (PUCHAR)outBuffer,
+ *(PULONG)inBuffer,
+ FALSE);
+
+ if (NT_SUCCESS(status)) {
+ bytesReturned = sizeof(UCHAR);
+ }
+
+ break;
+
+
+ case IOCTL_MARS_WRITE_BYTE:
+
+ if ((InputBufferLength < sizeof(ULONG)*2)) {//||(OutputBufferLength < sizeof(UCHAR))) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ // BUGBUG: check for output buffer length
+
+ status = SdioReadWriteByte(device,
+ fdoData->FunctionFocus,
+ (PUCHAR)(&((PULONG)inBuffer)[1]),
+ *(PULONG)inBuffer,
+ TRUE);
+
+ // BUGBUG: Return the right size
+
+ if (NT_SUCCESS(status)) {
+ bytesReturned = sizeof(UCHAR);
+ }
+
+
+ break;
+
+
+ //---------------------------------------------------
+ //
+ // Mode settings
+ //
+ //---------------------------------------------------
+
+ case IOCTL_MARS_SET_TRANSFER_MODE:
+
+ bytesReturned = 0;
+
+ break;
+
+ case IOCTL_MARS_TOGGLE_MODE:
+
+ if (OutputBufferLength < sizeof(UCHAR)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ if (fdoData->DriverVersion < SDBUS_DRIVER_VERSION_2) {
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ fdoData->BlockMode = fdoData->BlockMode ? 0 : 1;
+ *(PUCHAR)outBuffer = fdoData->BlockMode;
+ bytesReturned = sizeof(UCHAR);
+ break;
+
+
+ case IOCTL_MARS_TOGGLE_NOISY:
+
+ if (OutputBufferLength < sizeof(BOOLEAN)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ NoisyMode = NoisyMode ? 0 : 1;
+ *(PBOOLEAN)outBuffer = NoisyMode;
+ bytesReturned = sizeof(BOOLEAN);
+
+ if (NoisyMode) {
+ KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "MARS: Noisy mode\n"));
+ } else {
+ KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "MARS: Quiet mode\n"));
+ }
+ break;
+
+
+ default:
+ NT_ASSERTMSG("Invalid IOCTL request\n", FALSE);
+
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ WdfRequestCompleteWithInformation(Request, status, bytesReturned);
+ return;
+}
+
+VOID
+MarsEvtIoRead (
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t Length
+ )
+/*++
+
+Routine Description:
+
+ This event is called when the framework receives IRP_MJ_READ requests.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated with the
+ I/O request.
+ Request - Handle to a framework request object.
+
+ Lenght - Length of the data buffer associated with the request.
+ The default property of the queue is to not dispatch
+ zero lenght read & write requests to the driver and
+ complete is with status success. So we will never get
+ a zero length request.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ WDFDEVICE device;
+ PFDO_DATA fdoData;
+ PMDL mdlAddress;
+ WDF_REQUEST_PARAMETERS parameters;
+ NTSTATUS status;
+ ULONG bytesRead;
+
+ device = WdfIoQueueGetDevice(Queue);
+ fdoData = MarsFdoGetData(device);
+
+ status = WdfRequestRetrieveOutputWdmMdl(Request,&mdlAddress);
+ if (!NT_SUCCESS(status)) {
+ WdfRequestComplete(Request, status);
+ return;
+ }
+
+ WDF_REQUEST_PARAMETERS_INIT(&parameters);
+ WdfRequestGetParameters(Request, &parameters);
+
+ status = SdioReadWriteBuffer(device,
+ fdoData->FunctionFocus,
+ mdlAddress,
+ (ULONG)parameters.Parameters.Read.DeviceOffset,
+ (ULONG)parameters.Parameters.Read.Length,
+ FALSE,
+ &bytesRead);
+
+ WdfRequestCompleteWithInformation(Request, status, bytesRead);
+
+ return;
+}
+
+VOID
+MarsEvtIoWrite (
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t Length
+ )
+/*++
+
+Routine Description:
+
+ Called by the framework as soon as it receive a write IRP.
+ If the device is not ready, fail the request. Otherwise
+ get scatter-gather list for this request and send the
+ packet to the hardware for DMA.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated
+ with the I/O request.
+ Request - Handle to a framework request object.
+
+ Length - Length of the IO operation
+ The default property of the queue is to not dispatch
+ zero lenght read & write requests to the driver and
+ complete is with status success. So we will never get
+ a zero length request.
+
+Return Value:
+
+
+--*/
+{
+ WDFDEVICE device;
+ PFDO_DATA fdoData;
+ PMDL mdlAddress;
+ WDF_REQUEST_PARAMETERS parameters;
+ NTSTATUS status;
+ ULONG bytesRead;
+
+ device = WdfIoQueueGetDevice(Queue);
+ fdoData = MarsFdoGetData(device);
+
+ status = WdfRequestRetrieveInputWdmMdl(Request,&mdlAddress);
+ if (!NT_SUCCESS(status)) {
+ WdfRequestComplete(Request, status);
+ return;
+ }
+
+ WDF_REQUEST_PARAMETERS_INIT(&parameters);
+ WdfRequestGetParameters(Request, &parameters);
+
+ status = SdioReadWriteBuffer(device,
+ fdoData->FunctionFocus,
+ mdlAddress,
+ (ULONG)parameters.Parameters.Read.DeviceOffset,
+ (ULONG)parameters.Parameters.Read.Length,
+ TRUE,
+ &bytesRead);
+
+ WdfRequestCompleteWithInformation(Request, status, bytesRead);
+ return;
+}
+
+VOID
+MarsEventCallback(
+ IN PVOID Context,
+ IN ULONG InterruptType
+ )
+/*++
+
+Routine Description:
+
+ This routine is called by the SD bus driver when a card interrupt is
+ detected. It will launch the EventWorker routine which reads the data from
+ the card.
+
+Arguments:
+
+ Context, interrupt type are defined in the SDBUS api
+
+Return Values:
+
+ none
+
+--*/
+{
+ PFDO_DATA fdoData = (PFDO_DATA) Context;
+ static ULONG intCount = 0;
+
+ if (NoisyMode) {
+ KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "MARS: got card interrupt %d\n",
+ intCount++));
+ }
+
+
+ (fdoData->BusInterface.AcknowledgeInterrupt)(fdoData->BusInterface.Context);
+
+}
+
+NTSTATUS
+SdioReadWriteBuffer(
+ IN WDFDEVICE Device,
+ IN ULONG Function,
+ IN PMDL Mdl,
+ IN ULONG Address,
+ IN ULONG Length,
+ IN BOOLEAN WriteToDevice,
+ OUT PULONG BytesRead
+ )
+{
+ PFDO_DATA fdoData;
+ SDBUS_REQUEST_PACKET sdrp;
+ SD_RW_EXTENDED_ARGUMENT extendedArgument;
+ NTSTATUS status;
+ const SDCMD_DESCRIPTOR ReadIoExtendedDesc =
+ {SDCMD_IO_RW_EXTENDED, SDCC_STANDARD, SDTD_READ, SDTT_SINGLE_BLOCK, SDRT_5};
+
+ const SDCMD_DESCRIPTOR WriteIoExtendedDesc =
+ {SDCMD_IO_RW_EXTENDED, SDCC_STANDARD, SDTD_WRITE, SDTT_SINGLE_BLOCK, SDRT_5};
+
+ //PAGED_CODE();
+
+ fdoData = MarsFdoGetData(Device);
+
+ RtlZeroMemory(&sdrp, sizeof(SDBUS_REQUEST_PACKET));
+
+ sdrp.RequestFunction = SDRF_DEVICE_COMMAND;
+ sdrp.Parameters.DeviceCommand.Mdl = Mdl;
+
+ extendedArgument.u.AsULONG = 0;
+ extendedArgument.u.bits.Function = Function;
+ extendedArgument.u.bits.OpCode = 1; // increment address
+ extendedArgument.u.bits.BlockMode = fdoData->BlockMode;
+ extendedArgument.u.bits.Address = Address;
+
+ if (WriteToDevice) {
+ extendedArgument.u.bits.WriteToDevice = 1;
+ sdrp.Parameters.DeviceCommand.CmdDesc = WriteIoExtendedDesc;
+ } else {
+ sdrp.Parameters.DeviceCommand.CmdDesc = ReadIoExtendedDesc;
+ }
+
+ if (fdoData->BlockMode == 1) {
+ sdrp.Parameters.DeviceCommand.CmdDesc.TransferType = SDTT_MULTI_BLOCK_NO_CMD12;
+ }
+
+
+ sdrp.Parameters.DeviceCommand.Argument = extendedArgument.u.AsULONG;
+ sdrp.Parameters.DeviceCommand.Length = Length;
+
+ //
+ // Send the IO request down to the bus driver
+ //
+
+ status = SdBusSubmitRequest(fdoData->BusInterface.Context, &sdrp);
+ *BytesRead = (ULONG)sdrp.Information;
+ return status;
+
+}
+
+NTSTATUS
+SdioReadWriteByte(
+ IN WDFDEVICE Device,
+ IN ULONG Function,
+ IN PUCHAR Data,
+ IN ULONG Address,
+ IN BOOLEAN WriteToDevice
+ )
+/*++
+
+
+--*/
+
+{
+ PFDO_DATA fdoData;
+ NTSTATUS status;
+ SDBUS_REQUEST_PACKET sdrp;
+ SD_RW_DIRECT_ARGUMENT directArgument;
+
+ const SDCMD_DESCRIPTOR ReadIoDirectDesc =
+ {SDCMD_IO_RW_DIRECT, SDCC_STANDARD, SDTD_READ, SDTT_CMD_ONLY, SDRT_5};
+
+ const SDCMD_DESCRIPTOR WriteIoDirectDesc =
+ {SDCMD_IO_RW_DIRECT, SDCC_STANDARD, SDTD_WRITE, SDTT_CMD_ONLY, SDRT_5};
+
+ //
+ // get an SD request packet
+ //
+
+ fdoData = MarsFdoGetData(Device);
+
+ RtlZeroMemory(&sdrp, sizeof(SDBUS_REQUEST_PACKET));
+
+ sdrp.RequestFunction = SDRF_DEVICE_COMMAND;
+
+ directArgument.u.AsULONG = 0;
+ directArgument.u.bits.Function = Function;
+ directArgument.u.bits.Address = Address;
+
+
+ if (WriteToDevice) {
+ directArgument.u.bits.WriteToDevice = 1;
+ directArgument.u.bits.Data = *Data;
+ sdrp.Parameters.DeviceCommand.CmdDesc = WriteIoDirectDesc;
+ } else {
+ sdrp.Parameters.DeviceCommand.CmdDesc = ReadIoDirectDesc;
+ }
+
+ sdrp.Parameters.DeviceCommand.Argument = directArgument.u.AsULONG;
+
+ //
+ // Send the IO request down to the bus driver
+ //
+
+ status = SdBusSubmitRequest(fdoData->BusInterface.Context, &sdrp);
+
+ if (NT_SUCCESS(status) && !WriteToDevice) {
+ *Data = sdrp.ResponseData.AsUCHAR[0];
+ }
+
+ return status;
+}
+
+NTSTATUS
+SdioGetProperty(
+ IN WDFDEVICE Device,
+ IN SDBUS_PROPERTY Property,
+ IN PVOID Buffer,
+ IN ULONG Length
+ )
+{
+ PFDO_DATA fdoData;
+ SDBUS_REQUEST_PACKET sdrp;
+
+ fdoData = MarsFdoGetData(Device);
+ RtlZeroMemory(&sdrp, sizeof(SDBUS_REQUEST_PACKET));
+
+ sdrp.RequestFunction = SDRF_GET_PROPERTY;
+ sdrp.Parameters.GetSetProperty.Property = Property;
+ sdrp.Parameters.GetSetProperty.Buffer = Buffer;
+ sdrp.Parameters.GetSetProperty.Length = Length;
+
+ return SdBusSubmitRequest(fdoData->BusInterface.Context, &sdrp);
+}
+
+
+NTSTATUS
+SdioSetProperty(
+ IN WDFDEVICE Device,
+ IN SDBUS_PROPERTY Property,
+ IN PVOID Buffer,
+ IN ULONG Length
+ )
+{
+ PFDO_DATA fdoData;
+ SDBUS_REQUEST_PACKET sdrp;
+
+ fdoData = MarsFdoGetData(Device);
+
+ RtlZeroMemory(&sdrp, sizeof(SDBUS_REQUEST_PACKET));
+
+ sdrp.RequestFunction = SDRF_SET_PROPERTY;
+ sdrp.Parameters.GetSetProperty.Property = Property;
+ sdrp.Parameters.GetSetProperty.Buffer = Buffer;
+ sdrp.Parameters.GetSetProperty.Length = Length;
+
+ return SdBusSubmitRequest(fdoData->BusInterface.Context, &sdrp);
+}
+
diff --git a/sd/sdiomars/mars.h b/sd/sdiomars/mars.h
new file mode 100644
index 00000000..b9baed39
--- /dev/null
+++ b/sd/sdiomars/mars.h
@@ -0,0 +1,200 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ Mars.h
+
+Abstract:
+
+ Mars.h defines the data types used in the different stages of the function
+ driver.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+
+#if !defined(_MARS_H_)
+#define _MARS_H_
+
+#include <ntddk.h>
+#include <wdf.h>
+#include <initguid.h> // required for GUID definitions
+//
+// Disables few warnings so that we can build our driver with MSC W4 level.
+// Disable warning C4057; X differs in indirection to slightly different base types from Y
+// Disable warning C4100: unreferenced formal parameter
+//
+#pragma warning(disable:4100 4057)
+
+#include <ntddsd.h>
+#include <ntddmars.h>
+
+#define MARS_POOL_TAG (ULONG) 'sraM'
+
+
+//
+// The FDO_DATA structure describes the Mars sample function driver's device
+// extension. The device extension is where all per-device-instance information
+// is kept.
+//
+typedef struct _FDO_DATA {
+
+ WDFDEVICE WdfDevice;
+
+ WDFQUEUE IoctlQueue;
+ //
+ // Context for SD BUS api
+ //
+ SDBUS_INTERFACE_STANDARD BusInterface;
+ //
+ // Driver version
+ //
+ USHORT DriverVersion;
+ //
+ // Function number on SD card
+ //
+ UCHAR FunctionNumber;
+
+ //
+ // Target function for I/O transactions (not necessarily our function#)
+ //
+ UCHAR FunctionFocus;
+
+ //
+ // Send data transactions in byte mode (0) or block mode (1)
+ //
+ UCHAR BlockMode;
+} FDO_DATA, *PFDO_DATA;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_DATA, MarsFdoGetData)
+
+
+//
+// Declare the function prototypes for all of the function driver's routines in all
+// the stages of the function driver.
+//
+
+DRIVER_INITIALIZE DriverEntry;
+
+EVT_WDF_DRIVER_DEVICE_ADD MarsEvtDeviceAdd;
+/*
+NTSTATUS
+MarsEvtDeviceAdd(
+ IN WDFDRIVER Driver,
+ IN PWDFDEVICE_INIT DeviceInit
+ );
+*/
+
+EVT_WDF_DEVICE_PREPARE_HARDWARE MarsEvtDevicePrepareHardware;
+/*
+NTSTATUS
+MarsEvtDevicePrepareHardware(
+ WDFDEVICE Device,
+ WDFCMRESLIST Resources,
+ WDFCMRESLIST ResourcesTranslated
+ );
+*/
+
+EVT_WDF_DEVICE_RELEASE_HARDWARE MarsEvtDeviceReleaseHardware;
+/*
+NTSTATUS
+MarsEvtDeviceReleaseHardware(
+ IN WDFDEVICE Device,
+ IN WDFCMRESLIST ResourcesTranslated
+ );
+*/
+
+
+//
+// Io events callbacks.
+//
+
+EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL MarsEvtIoDeviceControl;
+/*
+VOID
+MarsEvtIoDeviceControl(
+ IN WDFQUEUE Queue,
+ IN WDFREQUEST Request,
+ IN size_t OutputBufferLength,
+ IN size_t InputBufferLength,
+ IN ULONG IoControlCode
+ );
+*/
+
+EVT_WDF_IO_QUEUE_IO_READ MarsEvtIoRead;
+/*
+VOID
+MarsEvtIoRead (
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t Length
+ );
+*/
+
+EVT_WDF_IO_QUEUE_IO_WRITE MarsEvtIoWrite;
+/*
+VOID
+MarsEvtIoWrite (
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t Length
+ );
+*/
+
+SDBUS_CALLBACK_ROUTINE MarsEventCallback;
+/*
+VOID
+MarsEventCallback(
+ IN PVOID Context,
+ IN ULONG InterruptType
+ );
+*/
+
+NTSTATUS
+SdioReadWriteBuffer(
+ IN WDFDEVICE Device,
+ IN ULONG Function,
+ IN PMDL Mdl,
+ IN ULONG Address,
+ IN ULONG Length,
+ IN BOOLEAN WriteToDevice,
+ OUT PULONG BytesRead
+ );
+
+NTSTATUS
+SdioReadWriteByte(
+ IN WDFDEVICE Device,
+ IN ULONG Function,
+ IN PUCHAR Data,
+ IN ULONG Address,
+ IN BOOLEAN WriteToDevice
+ );
+
+NTSTATUS
+SdioGetProperty(
+ IN WDFDEVICE Device,
+ IN SDBUS_PROPERTY Property,
+ IN PVOID Buffer,
+ IN ULONG Length
+ );
+
+NTSTATUS
+SdioSetProperty(
+ IN WDFDEVICE Device,
+ IN SDBUS_PROPERTY Property,
+ IN PVOID Buffer,
+ IN ULONG Length
+ );
+#endif // _MARS_H_
+
+
diff --git a/sd/sdiomars/mars.inx b/sd/sdiomars/mars.inx
new file mode 100644
index 00000000..e8f4d3d9
--- /dev/null
+++ b/sd/sdiomars/mars.inx
Binary files differ
diff --git a/sd/sdiomars/mars.vcxproj b/sd/sdiomars/mars.vcxproj
new file mode 100644
index 00000000..6bebd02e
--- /dev/null
+++ b/sd/sdiomars/mars.vcxproj
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{83B758B0-F972-48D1-823B-3B817E5497AD}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>KMDF</DriverType>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems">
+ <Inf Include=".\mars.inx">
+ <Architecture>$(InfArch)</Architecture>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <TimeStamp>1.0.0.5054</TimeStamp>
+ <SpecifyDriverVerDirectiveVersion>true</SpecifyDriverVerDirectiveVersion>
+ <CopyOutput>.\$(IntDir)\mars.inf</CopyOutput>
+ </Inf>
+ </ItemGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>mars</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>mars</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>mars</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>mars</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\sdbus.lib;$(DDK_LIB_PATH)\ntstrsafe.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\sdbus.lib;$(DDK_LIB_PATH)\ntstrsafe.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\sdbus.lib;$(DDK_LIB_PATH)\ntstrsafe.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\sdbus.lib;$(DDK_LIB_PATH)\ntstrsafe.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="mars.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/sd/sdiomars/mars.vcxproj.Filters b/sd/sdiomars/mars.vcxproj.Filters
new file mode 100644
index 00000000..f3dd1af1
--- /dev/null
+++ b/sd/sdiomars/mars.vcxproj.Filters
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{149057E1-1BB6-43A6-8760-824CA3861F1D}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{A9A3E7C6-26AD-4B64-B75B-B1BCF262750C}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{39C916B8-B030-41D4-A3C1-4EFD5E0D83F7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{297888D3-E8F6-4472-8CCA-71D8D1E66B79}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include=".\Debug\\mars.inf">
+ <Filter>Driver Files</Filter>
+ </FilesToPackage>
+ <Inf Include=".\mars.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="mars.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/sd/sdiomars/ntddmars.h b/sd/sdiomars/ntddmars.h
new file mode 100644
index 00000000..d62c4f56
--- /dev/null
+++ b/sd/sdiomars/ntddmars.h
@@ -0,0 +1,113 @@
+/*++
+Copyright (c) 1990-2000 Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ ntddmars.h
+
+Abstract:
+
+ This module contains the common declarations shared by driver
+ and user applications.
+
+Environment:
+
+ user and kernel
+Notes:
+
+
+Revision History:
+
+
+--*/
+
+
+//
+// Define an Interface Guid for the mars device class.
+//
+
+DEFINE_GUID (GUID_DEVINTERFACE_MARS,
+ 0xf00896ba, 0x23a8, 0x41f1, 0x80, 0xed, 0xda, 0xd9, 0x81, 0x7a, 0xd7, 0x29);
+
+
+//
+// GUID definition are required to be outside of header inclusion pragma to avoid
+// error during precompiled headers.
+//
+
+#ifndef __NTDDMARS_H
+#define __NTDDMARS_H
+
+
+#define FILE_DEVICE_MARS FILE_DEVICE_CONTROLLER
+
+#define IOCTL_MARS_GET_DRIVER_VERSION \
+ CTL_CODE( FILE_DEVICE_MARS, 0x780, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_MARS_GET_FUNCTION_NUMBER \
+ CTL_CODE( FILE_DEVICE_MARS, 0x781, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_MARS_GET_FUNCTION_FOCUS \
+ CTL_CODE( FILE_DEVICE_MARS, 0x782, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_MARS_SET_FUNCTION_FOCUS \
+ CTL_CODE( FILE_DEVICE_MARS, 0x783, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+
+
+#define IOCTL_MARS_GET_BUS_WIDTH \
+ CTL_CODE( FILE_DEVICE_MARS, 0x784, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MARS_SET_BUS_WIDTH \
+ CTL_CODE( FILE_DEVICE_MARS, 0x785, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+
+#define IOCTL_MARS_GET_BUS_CLOCK \
+ CTL_CODE( FILE_DEVICE_MARS, 0x786, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MARS_SET_BUS_CLOCK \
+ CTL_CODE( FILE_DEVICE_MARS, 0x787, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+
+#define IOCTL_MARS_GET_BLOCKLEN \
+ CTL_CODE( FILE_DEVICE_MARS, 0x788, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MARS_SET_BLOCKLEN \
+ CTL_CODE( FILE_DEVICE_MARS, 0x789, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+
+#define IOCTL_MARS_GET_FN0_BLOCKLEN \
+ CTL_CODE( FILE_DEVICE_MARS, 0x78a, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MARS_SET_FN0_BLOCKLEN \
+ CTL_CODE( FILE_DEVICE_MARS, 0x78b, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+
+#define IOCTL_MARS_GET_BUS_INTERFACE_CONTROL \
+ CTL_CODE( FILE_DEVICE_MARS, 0x78c, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MARS_SET_BUS_INTERFACE_CONTROL \
+ CTL_CODE( FILE_DEVICE_MARS, 0x78d, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_MARS_GET_INT_ENABLE \
+ CTL_CODE( FILE_DEVICE_MARS, 0x78e, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MARS_SET_INT_ENABLE \
+ CTL_CODE( FILE_DEVICE_MARS, 0x78f, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+
+
+#define IOCTL_MARS_READ_BYTE \
+ CTL_CODE( FILE_DEVICE_MARS, 0x7b0, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_MARS_WRITE_BYTE \
+ CTL_CODE( FILE_DEVICE_MARS, 0x7b1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_MARS_SET_TRANSFER_MODE \
+ CTL_CODE( FILE_DEVICE_MARS, 0x7b2, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_MARS_TOGGLE_MODE \
+ CTL_CODE( FILE_DEVICE_MARS, 0x7b3, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_MARS_TOGGLE_NOISY \
+ CTL_CODE( FILE_DEVICE_MARS, 0x7b4, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+
+#endif
+
+
+
diff --git a/sd/sdiomars/sdiomars.sln b/sd/sdiomars/sdiomars.sln
new file mode 100644
index 00000000..23cfa5ea
--- /dev/null
+++ b/sd/sdiomars/sdiomars.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0
+MinimumVisualStudioVersion = 12.0
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mars", "mars.vcxproj", "{18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}.Debug|Win32.Build.0 = Debug|Win32
+ {18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}.Release|Win32.ActiveCfg = Release|Win32
+ {18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}.Release|Win32.Build.0 = Release|Win32
+ {18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}.Debug|x64.ActiveCfg = Debug|x64
+ {18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}.Debug|x64.Build.0 = Debug|x64
+ {18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}.Release|x64.ActiveCfg = Release|x64
+ {18D5F2EE-E11C-44E7-BCB6-E4C39F679B9D}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal