win-pvdrivers

annotate xenvbd/xenvbd.c @ 310:60372bd2582d

First cut of putting xenbus config details in the .inf file - xenvbd may yet pass WHQL
author James Harper <james.harper@bendigoit.com.au>
date Fri Jun 13 14:16:50 2008 +1000 (2008-06-13)
parents b4f7d75fbe24
children 0488ef11be09
rev   line source
james@267 1 /*
james@267 2 PV Drivers for Windows Xen HVM Domains
james@267 3 Copyright (C) 2007 James Harper
james@267 4
james@267 5 This program is free software; you can redistribute it and/or
james@267 6 modify it under the terms of the GNU General Public License
james@267 7 as published by the Free Software Foundation; either version 2
james@267 8 of the License, or (at your option) any later version.
james@267 9
james@267 10 This program is distributed in the hope that it will be useful,
james@267 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
james@267 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
james@267 13 GNU General Public License for more details.
james@267 14
james@267 15 You should have received a copy of the GNU General Public License
james@267 16 along with this program; if not, write to the Free Software
james@267 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
james@267 18 */
james@267 19
james@0 20 #include "xenvbd.h"
james@0 21 #include <io/blkif.h>
james@0 22 #include <scsi.h>
james@0 23 #include <ntddscsi.h>
james@0 24 #include <ntdddisk.h>
james@0 25 #include <stdlib.h>
james@0 26 #include <xen_public.h>
james@0 27 #include <io/xenbus.h>
james@160 28 #include <io/protocols.h>
james@0 29
andy@119 30 #pragma warning(disable: 4127)
andy@119 31
james@0 32 DRIVER_INITIALIZE DriverEntry;
james@0 33
james@0 34 #ifdef ALLOC_PRAGMA
james@0 35 #pragma alloc_text (INIT, DriverEntry)
james@0 36 #endif
james@0 37
james@310 38 #if 0
james@267 39 static PDRIVER_DISPATCH XenVbd_Pnp_Original;
james@267 40
james@267 41 static NTSTATUS
james@267 42 XenVbd_Pnp(PDEVICE_OBJECT device_object, PIRP irp)
james@267 43 {
james@267 44 PIO_STACK_LOCATION stack;
james@267 45 NTSTATUS status;
james@267 46 PCM_RESOURCE_LIST old_crl, new_crl;
james@305 47 ULONG i;
james@267 48 PCM_PARTIAL_RESOURCE_LIST prl;
james@267 49 PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
james@267 50 ULONG old_length, new_length;
james@267 51 PMDL mdl;
james@267 52 PUCHAR start, ptr;
james@267 53
james@267 54 KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
james@267 55
james@267 56 stack = IoGetCurrentIrpStackLocation(irp);
james@267 57
james@268 58 // check if the Irp is meant for us... maybe the stack->DeviceObject field?
james@268 59
james@267 60 switch (stack->MinorFunction)
james@267 61 {
james@267 62 case IRP_MN_START_DEVICE:
james@268 63 KdPrint((__DRIVER_NAME " IRP_MN_START_DEVICE - DeviceObject = %p\n", stack->DeviceObject));
james@267 64 old_crl = stack->Parameters.StartDevice.AllocatedResourcesTranslated;
james@268 65 if (old_crl != NULL)
james@268 66 {
james@274 67 mdl = AllocateUncachedPage();
james@268 68 old_length = FIELD_OFFSET(CM_RESOURCE_LIST, List) +
james@268 69 FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) +
james@268 70 FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
james@268 71 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * old_crl->List[0].PartialResourceList.Count;
james@268 72 new_length = old_length + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * 1;
james@268 73 new_crl = ExAllocatePoolWithTag(PagedPool, new_length, XENVBD_POOL_TAG);
james@268 74 memcpy(new_crl, old_crl, old_length);
james@268 75 prl = &new_crl->List[0].PartialResourceList;
james@268 76 prd = &prl->PartialDescriptors[prl->Count++];
james@268 77 prd->Type = CmResourceTypeMemory;
james@268 78 prd->ShareDisposition = CmResourceShareDeviceExclusive;
james@305 79 prd->Flags = CM_RESOURCE_MEMORY_READ_WRITE; //|CM_RESOURCE_MEMORY_PREFETCHABLE; //|CM_RESOURCE_MEMORY_CACHEABLE;
james@274 80 KdPrint((__DRIVER_NAME " PFN[0] = %p\n", MmGetMdlPfnArray(mdl)[0]));
james@268 81 prd->u.Memory.Start.QuadPart = MmGetMdlPfnArray(mdl)[0] << PAGE_SHIFT;
james@268 82 prd->u.Memory.Length = PAGE_SIZE;
james@274 83 KdPrint((__DRIVER_NAME " Start = %08x:%08x, Length = %d\n", prd->u.Memory.Start.HighPart, prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
james@268 84 ptr = start = MmGetMdlVirtualAddress(mdl);
james@268 85 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL);
james@268 86 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_IRQ, "event-channel", NULL);
james@268 87 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_FRONT, "device-type", NULL);
james@268 88 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sectors", NULL);
james@268 89 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "sector-size", NULL);
james@268 90 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_VECTORS, NULL, NULL);
james@310 91 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_GRANT_ENTRIES, NULL, UlongToPtr(GRANT_ENTRIES));
james@268 92 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL);
james@268 93
james@268 94 stack->Parameters.StartDevice.AllocatedResourcesTranslated = new_crl;
james@267 95
james@268 96 old_crl = stack->Parameters.StartDevice.AllocatedResources;
james@268 97 new_crl = ExAllocatePoolWithTag(PagedPool, new_length, XENVBD_POOL_TAG);
james@268 98 memcpy(new_crl, old_crl, old_length);
james@268 99 prl = &new_crl->List[0].PartialResourceList;
james@268 100 prd = &prl->PartialDescriptors[prl->Count++];
james@268 101 prd->Type = CmResourceTypeMemory;
james@268 102 prd->ShareDisposition = CmResourceShareDeviceExclusive;
james@268 103 prd->Flags = CM_RESOURCE_MEMORY_READ_WRITE|CM_RESOURCE_MEMORY_PREFETCHABLE|CM_RESOURCE_MEMORY_CACHEABLE;
james@268 104 prd->u.Memory.Start.QuadPart = MmGetMdlPfnArray(mdl)[0] << PAGE_SHIFT;
james@268 105 prd->u.Memory.Length = PAGE_SIZE;
james@268 106 stack->Parameters.StartDevice.AllocatedResources = new_crl;
james@268 107 IoCopyCurrentIrpStackLocationToNext(irp);
james@268 108 }
james@267 109 status = XenVbd_Pnp_Original(device_object, irp);
james@267 110
james@267 111 break;
james@291 112 #if 0
james@267 113 case IRP_MN_QUERY_STOP_DEVICE:
james@267 114 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_STOP_DEVICE\n"));
james@267 115 status = XenVbd_Pnp_Original(device_object, irp);
james@267 116 break;
james@267 117
james@267 118 case IRP_MN_STOP_DEVICE:
james@267 119 KdPrint((__DRIVER_NAME " IRP_MN_STOP_DEVICE\n"));
james@267 120 status = XenVbd_Pnp_Original(device_object, irp);
james@267 121 break;
james@267 122
james@267 123 case IRP_MN_CANCEL_STOP_DEVICE:
james@267 124 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_STOP_DEVICE\n"));
james@267 125 status = XenVbd_Pnp_Original(device_object, irp);
james@267 126 break;
james@267 127
james@267 128 case IRP_MN_QUERY_REMOVE_DEVICE:
james@267 129 KdPrint((__DRIVER_NAME " IRP_MN_QUERY_REMOVE_DEVICE\n"));
james@267 130 status = XenVbd_Pnp_Original(device_object, irp);
james@267 131 break;
james@267 132
james@267 133 case IRP_MN_REMOVE_DEVICE:
james@267 134 KdPrint((__DRIVER_NAME " IRP_MN_REMOVE_DEVICE\n"));
james@267 135 status = XenVbd_Pnp_Original(device_object, irp);
james@267 136 break;
james@267 137
james@267 138 case IRP_MN_CANCEL_REMOVE_DEVICE:
james@267 139 KdPrint((__DRIVER_NAME " IRP_MN_CANCEL_REMOVE_DEVICE\n"));
james@267 140 status = XenVbd_Pnp_Original(device_object, irp);
james@267 141 break;
james@267 142
james@267 143 case IRP_MN_SURPRISE_REMOVAL:
james@267 144 KdPrint((__DRIVER_NAME " IRP_MN_SURPRISE_REMOVAL\n"));
james@267 145 status = XenVbd_Pnp_Original(device_object, irp);
james@267 146 break;
james@291 147 #endif
james@267 148
james@267 149 default:
james@291 150 //KdPrint((__DRIVER_NAME " Unknown Minor = %d\n", stack->MinorFunction));
james@267 151 status = XenVbd_Pnp_Original(device_object, irp);
james@267 152 break;
james@267 153 }
james@267 154
james@267 155 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
james@267 156
james@267 157 return status;
james@267 158 }
james@310 159 #endif
james@0 160
james@0 161 NTSTATUS
james@0 162 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
james@0 163 {
james@274 164 ULONG status;
james@48 165 HW_INITIALIZATION_DATA HwInitializationData;
james@0 166
james@124 167 KdPrint((__DRIVER_NAME " --> "__FUNCTION__ "\n"));
james@116 168 KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql()));
james@0 169
james@48 170 RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
james@0 171
james@48 172 HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
james@267 173 HwInitializationData.AdapterInterfaceType = Internal;
james@267 174 HwInitializationData.DeviceExtensionSize = sizeof(XENVBD_DEVICE_DATA);
james@48 175 HwInitializationData.SpecificLuExtensionSize = 0;
james@284 176 /* SrbExtension is not always aligned to a page boundary, so we add PAGE_SIZE-1 to it to make sure we have at least UNALIGNED_DOUBLE_BUFFER_SIZE bytes of page aligned memory */
james@284 177 HwInitializationData.SrbExtensionSize = UNALIGNED_DOUBLE_BUFFER_SIZE + PAGE_SIZE - 1;
james@48 178 HwInitializationData.NumberOfAccessRanges = 1;
james@48 179 HwInitializationData.MapBuffers = TRUE;
james@48 180 HwInitializationData.NeedPhysicalAddresses = FALSE;
james@284 181 HwInitializationData.TaggedQueuing = FALSE;
james@284 182 HwInitializationData.AutoRequestSense = TRUE;
james@157 183 HwInitializationData.MultipleRequestPerLu = TRUE;
james@124 184 HwInitializationData.ReceiveEvent = FALSE;
james@48 185 HwInitializationData.VendorIdLength = 0;
james@48 186 HwInitializationData.VendorId = NULL;
james@48 187 HwInitializationData.DeviceIdLength = 0;
james@48 188 HwInitializationData.DeviceId = NULL;
james@0 189
james@267 190 XenVbd_FillInitCallbacks(&HwInitializationData);
james@195 191
james@274 192 status = ScsiPortInitialize(DriverObject, RegistryPath, &HwInitializationData, NULL);
james@267 193
james@310 194
james@310 195 #if 0
james@288 196 /* DriverObject will be NULL if we are being called in dump mode */
james@288 197 if (DriverObject != NULL)
james@288 198 {
james@288 199 /* this is a bit naughty... */
james@288 200 XenVbd_Pnp_Original = DriverObject->MajorFunction[IRP_MJ_PNP];
james@288 201 DriverObject->MajorFunction[IRP_MJ_PNP] = XenVbd_Pnp;
james@288 202 }
james@288 203 else
james@288 204 XenVbd_Pnp_Original = NULL;
james@310 205 #endif
james@48 206
james@274 207 if(!NT_SUCCESS(status))
james@0 208 {
james@274 209 KdPrint((__DRIVER_NAME " ScsiPortInitialize failed with status 0x%08x\n", status));
james@0 210 }
james@0 211
james@124 212 KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
james@0 213
james@274 214 return status;
james@48 215 }