win-pvdrivers

view xenvbd/xenvbd.c @ 283:3c65d6c6453f

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