3 * Copyright (c) 2009, Microsoft Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 * Haiyang Zhang <haiyangz@microsoft.com>
20 * Hank Janssen <hjanssen@microsoft.com>
26 #include <linux/kernel.h>
27 #include <linux/string.h>
29 #include "include/logging.h"
31 #include "include/StorVscApi.h"
32 #include "include/VmbusPacketFormat.h"
33 #include "include/vstorage.h"
44 typedef struct _STORVSC_REQUEST_EXTENSION
{
45 //LIST_ENTRY ListEntry;
47 STORVSC_REQUEST
*Request
;
48 DEVICE_OBJECT
*Device
;
50 // Synchronize the request/response if needed
53 VSTOR_PACKET VStorPacket
;
54 } STORVSC_REQUEST_EXTENSION
;
57 // A storvsc device is a device object that contains a vmbus channel
58 typedef struct _STORVSC_DEVICE
{
59 DEVICE_OBJECT
*Device
;
61 int RefCount
; // 0 indicates the device is being destroyed
63 int NumOutstandingRequests
;
65 // Each unique Port/Path/Target represents 1 channel ie scsi controller. In reality, the pathid, targetid is always 0
66 // and the port is set by us
67 unsigned int PortNumber
;
69 unsigned char TargetId
;
71 //LIST_ENTRY OutstandingRequestList;
72 //HANDLE OutstandingRequestLock;
74 // Used for vsc/vsp channel reset process
75 STORVSC_REQUEST_EXTENSION InitRequest
;
77 STORVSC_REQUEST_EXTENSION ResetRequest
;
85 static const char* gDriverName
="storvsc";
87 //{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}
88 static const GUID gStorVscDeviceType
={
89 .Data
= {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f}
97 DEVICE_OBJECT
*Device
,
102 StorVscOnDeviceRemove(
103 DEVICE_OBJECT
*Device
108 DEVICE_OBJECT
*Device
,
109 STORVSC_REQUEST
*Request
114 DEVICE_OBJECT
*Device
119 DRIVER_OBJECT
*Device
123 StorVscOnChannelCallback(
128 StorVscOnIOCompletion(
129 DEVICE_OBJECT
*Device
,
130 VSTOR_PACKET
*VStorPacket
,
131 STORVSC_REQUEST_EXTENSION
*RequestExt
136 DEVICE_OBJECT
*Device
,
137 VSTOR_PACKET
*VStorPacket
,
138 STORVSC_REQUEST_EXTENSION
*RequestExt
143 DEVICE_OBJECT
*Device
146 static inline STORVSC_DEVICE
* AllocStorDevice(DEVICE_OBJECT
*Device
)
148 STORVSC_DEVICE
*storDevice
;
150 storDevice
= kzalloc(sizeof(STORVSC_DEVICE
), GFP_KERNEL
);
154 // Set to 2 to allow both inbound and outbound traffics
155 // (ie GetStorDevice() and MustGetStorDevice()) to proceed.
156 InterlockedCompareExchange(&storDevice
->RefCount
, 2, 0);
158 storDevice
->Device
= Device
;
159 Device
->Extension
= storDevice
;
164 static inline void FreeStorDevice(STORVSC_DEVICE
*Device
)
166 ASSERT(Device
->RefCount
== 0);
170 // Get the stordevice object iff exists and its refcount > 1
171 static inline STORVSC_DEVICE
* GetStorDevice(DEVICE_OBJECT
*Device
)
173 STORVSC_DEVICE
*storDevice
;
175 storDevice
= (STORVSC_DEVICE
*)Device
->Extension
;
176 if (storDevice
&& storDevice
->RefCount
> 1)
178 InterlockedIncrement(&storDevice
->RefCount
);
188 // Get the stordevice object iff exists and its refcount > 0
189 static inline STORVSC_DEVICE
* MustGetStorDevice(DEVICE_OBJECT
*Device
)
191 STORVSC_DEVICE
*storDevice
;
193 storDevice
= (STORVSC_DEVICE
*)Device
->Extension
;
194 if (storDevice
&& storDevice
->RefCount
)
196 InterlockedIncrement(&storDevice
->RefCount
);
206 static inline void PutStorDevice(DEVICE_OBJECT
*Device
)
208 STORVSC_DEVICE
*storDevice
;
210 storDevice
= (STORVSC_DEVICE
*)Device
->Extension
;
213 InterlockedDecrement(&storDevice
->RefCount
);
214 ASSERT(storDevice
->RefCount
);
217 // Drop ref count to 1 to effectively disable GetStorDevice()
218 static inline STORVSC_DEVICE
* ReleaseStorDevice(DEVICE_OBJECT
*Device
)
220 STORVSC_DEVICE
*storDevice
;
222 storDevice
= (STORVSC_DEVICE
*)Device
->Extension
;
225 // Busy wait until the ref drop to 2, then set it to 1
226 while (InterlockedCompareExchange(&storDevice
->RefCount
, 1, 2) != 2)
234 // Drop ref count to 0. No one can use StorDevice object.
235 static inline STORVSC_DEVICE
* FinalReleaseStorDevice(DEVICE_OBJECT
*Device
)
237 STORVSC_DEVICE
*storDevice
;
239 storDevice
= (STORVSC_DEVICE
*)Device
->Extension
;
242 // Busy wait until the ref drop to 1, then set it to 0
243 while (InterlockedCompareExchange(&storDevice
->RefCount
, 0, 1) != 1)
248 Device
->Extension
= NULL
;
264 DRIVER_OBJECT
*Driver
267 STORVSC_DRIVER_OBJECT
* storDriver
= (STORVSC_DRIVER_OBJECT
*)Driver
;
270 DPRINT_ENTER(STORVSC
);
272 DPRINT_DBG(STORVSC
, "sizeof(STORVSC_REQUEST)=%d sizeof(STORVSC_REQUEST_EXTENSION)=%d sizeof(VSTOR_PACKET)=%d, sizeof(VMSCSI_REQUEST)=%d",
273 sizeof(STORVSC_REQUEST
), sizeof(STORVSC_REQUEST_EXTENSION
), sizeof(VSTOR_PACKET
), sizeof(VMSCSI_REQUEST
));
275 // Make sure we are at least 2 pages since 1 page is used for control
276 ASSERT(storDriver
->RingBufferSize
>= (PAGE_SIZE
<< 1));
278 Driver
->name
= gDriverName
;
279 memcpy(&Driver
->deviceType
, &gStorVscDeviceType
, sizeof(GUID
));
281 storDriver
->RequestExtSize
= sizeof(STORVSC_REQUEST_EXTENSION
);
283 // Divide the ring buffer data size (which is 1 page less than the ring buffer size since that page is reserved for the ring buffer indices)
284 // by the max request size (which is VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + VSTOR_PACKET + u64)
285 storDriver
->MaxOutstandingRequestsPerChannel
=
286 ((storDriver
->RingBufferSize
- PAGE_SIZE
) / ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET
+ sizeof(VSTOR_PACKET
) + sizeof(u64
),sizeof(u64
)));
288 DPRINT_INFO(STORVSC
, "max io %u, currently %u\n", storDriver
->MaxOutstandingRequestsPerChannel
, STORVSC_MAX_IO_REQUESTS
);
290 // Setup the dispatch table
291 storDriver
->Base
.OnDeviceAdd
= StorVscOnDeviceAdd
;
292 storDriver
->Base
.OnDeviceRemove
= StorVscOnDeviceRemove
;
293 storDriver
->Base
.OnCleanup
= StorVscOnCleanup
;
295 storDriver
->OnIORequest
= StorVscOnIORequest
;
296 storDriver
->OnHostReset
= StorVscOnHostReset
;
298 DPRINT_EXIT(STORVSC
);
309 Callback when the device belonging to this driver is added
314 DEVICE_OBJECT
*Device
,
319 STORVSC_DEVICE
*storDevice
;
320 //VMSTORAGE_CHANNEL_PROPERTIES *props;
321 STORVSC_DEVICE_INFO
*deviceInfo
= (STORVSC_DEVICE_INFO
*)AdditionalInfo
;
323 DPRINT_ENTER(STORVSC
);
325 storDevice
= AllocStorDevice(Device
);
332 // Save the channel properties to our storvsc channel
333 //props = (VMSTORAGE_CHANNEL_PROPERTIES*) channel->offerMsg.Offer.u.Standard.UserDefined;
336 // If we support more than 1 scsi channel, we need to set the port number here
337 // to the scsi channel but how do we get the scsi channel prior to the bus scan
338 /*storChannel->PortNumber = 0;
339 storChannel->PathId = props->PathId;
340 storChannel->TargetId = props->TargetId;*/
342 storDevice
->PortNumber
= deviceInfo
->PortNumber
;
344 ret
= StorVscConnectToVsp(Device
);
346 //deviceInfo->PortNumber = storDevice->PortNumber;
347 deviceInfo
->PathId
= storDevice
->PathId
;
348 deviceInfo
->TargetId
= storDevice
->TargetId
;
350 DPRINT_DBG(STORVSC
, "assigned port %u, path %u target %u\n", storDevice
->PortNumber
, storDevice
->PathId
, storDevice
->TargetId
);
353 DPRINT_EXIT(STORVSC
);
358 static int StorVscChannelInit(DEVICE_OBJECT
*Device
)
361 STORVSC_DEVICE
*storDevice
;
362 STORVSC_REQUEST_EXTENSION
*request
;
363 VSTOR_PACKET
*vstorPacket
;
365 storDevice
= GetStorDevice(Device
);
368 DPRINT_ERR(STORVSC
, "unable to get stor device...device being destroyed?");
369 DPRINT_EXIT(STORVSC
);
373 request
= &storDevice
->InitRequest
;
374 vstorPacket
= &request
->VStorPacket
;
376 // Now, initiate the vsc/vsp initialization protocol on the open channel
378 memset(request
, sizeof(STORVSC_REQUEST_EXTENSION
), 0);
379 request
->WaitEvent
= WaitEventCreate();
381 vstorPacket
->Operation
= VStorOperationBeginInitialization
;
382 vstorPacket
->Flags
= REQUEST_COMPLETION_FLAG
;
384 /*SpinlockAcquire(gDriverExt.packetListLock);
385 INSERT_TAIL_LIST(&gDriverExt.packetList, &packet->listEntry.entry);
386 SpinlockRelease(gDriverExt.packetListLock);*/
388 DPRINT_INFO(STORVSC
, "BEGIN_INITIALIZATION_OPERATION...");
390 ret
= Device
->Driver
->VmbusChannelInterface
.SendPacket(Device
,
392 sizeof(VSTOR_PACKET
),
393 (unsigned long)request
,
394 VmbusPacketTypeDataInBand
,
395 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
398 DPRINT_ERR(STORVSC
, "unable to send BEGIN_INITIALIZATION_OPERATION");
402 WaitEventWait(request
->WaitEvent
);
404 if (vstorPacket
->Operation
!= VStorOperationCompleteIo
|| vstorPacket
->Status
!= 0)
406 DPRINT_ERR(STORVSC
, "BEGIN_INITIALIZATION_OPERATION failed (op %d status 0x%x)", vstorPacket
->Operation
, vstorPacket
->Status
);
410 DPRINT_INFO(STORVSC
, "QUERY_PROTOCOL_VERSION_OPERATION...");
412 // reuse the packet for version range supported
413 memset(vstorPacket
, sizeof(VSTOR_PACKET
), 0);
414 vstorPacket
->Operation
= VStorOperationQueryProtocolVersion
;
415 vstorPacket
->Flags
= REQUEST_COMPLETION_FLAG
;
417 vstorPacket
->Version
.MajorMinor
= VMSTOR_PROTOCOL_VERSION_CURRENT
;
418 FILL_VMSTOR_REVISION(vstorPacket
->Version
.Revision
);
420 ret
= Device
->Driver
->VmbusChannelInterface
.SendPacket(Device
,
422 sizeof(VSTOR_PACKET
),
423 (unsigned long)request
,
424 VmbusPacketTypeDataInBand
,
425 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
428 DPRINT_ERR(STORVSC
, "unable to send BEGIN_INITIALIZATION_OPERATION");
432 WaitEventWait(request
->WaitEvent
);
434 // TODO: Check returned version
435 if (vstorPacket
->Operation
!= VStorOperationCompleteIo
|| vstorPacket
->Status
!= 0)
437 DPRINT_ERR(STORVSC
, "QUERY_PROTOCOL_VERSION_OPERATION failed (op %d status 0x%x)", vstorPacket
->Operation
, vstorPacket
->Status
);
441 // Query channel properties
442 DPRINT_INFO(STORVSC
, "QUERY_PROPERTIES_OPERATION...");
444 memset(vstorPacket
, sizeof(VSTOR_PACKET
), 0);
445 vstorPacket
->Operation
= VStorOperationQueryProperties
;
446 vstorPacket
->Flags
= REQUEST_COMPLETION_FLAG
;
447 vstorPacket
->StorageChannelProperties
.PortNumber
= storDevice
->PortNumber
;
449 ret
= Device
->Driver
->VmbusChannelInterface
.SendPacket(Device
,
451 sizeof(VSTOR_PACKET
),
452 (unsigned long)request
,
453 VmbusPacketTypeDataInBand
,
454 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
458 DPRINT_ERR(STORVSC
, "unable to send QUERY_PROPERTIES_OPERATION");
462 WaitEventWait(request
->WaitEvent
);
464 // TODO: Check returned version
465 if (vstorPacket
->Operation
!= VStorOperationCompleteIo
|| vstorPacket
->Status
!= 0)
467 DPRINT_ERR(STORVSC
, "QUERY_PROPERTIES_OPERATION failed (op %d status 0x%x)", vstorPacket
->Operation
, vstorPacket
->Status
);
471 //storDevice->PortNumber = vstorPacket->StorageChannelProperties.PortNumber;
472 storDevice
->PathId
= vstorPacket
->StorageChannelProperties
.PathId
;
473 storDevice
->TargetId
= vstorPacket
->StorageChannelProperties
.TargetId
;
475 DPRINT_DBG(STORVSC
, "channel flag 0x%x, max xfer len 0x%x", vstorPacket
->StorageChannelProperties
.Flags
, vstorPacket
->StorageChannelProperties
.MaxTransferBytes
);
477 DPRINT_INFO(STORVSC
, "END_INITIALIZATION_OPERATION...");
479 memset(vstorPacket
, sizeof(VSTOR_PACKET
), 0);
480 vstorPacket
->Operation
= VStorOperationEndInitialization
;
481 vstorPacket
->Flags
= REQUEST_COMPLETION_FLAG
;
483 ret
= Device
->Driver
->VmbusChannelInterface
.SendPacket(Device
,
485 sizeof(VSTOR_PACKET
),
486 (unsigned long)request
,
487 VmbusPacketTypeDataInBand
,
488 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
492 DPRINT_ERR(STORVSC
, "unable to send END_INITIALIZATION_OPERATION");
496 WaitEventWait(request
->WaitEvent
);
498 if (vstorPacket
->Operation
!= VStorOperationCompleteIo
|| vstorPacket
->Status
!= 0)
500 DPRINT_ERR(STORVSC
, "END_INITIALIZATION_OPERATION failed (op %d status 0x%x)", vstorPacket
->Operation
, vstorPacket
->Status
);
504 DPRINT_INFO(STORVSC
, "**** storage channel up and running!! ****");
507 if (request
->WaitEvent
)
509 WaitEventClose(request
->WaitEvent
);
510 request
->WaitEvent
= NULL
;
513 PutStorDevice(Device
);
515 DPRINT_EXIT(STORVSC
);
522 DEVICE_OBJECT
*Device
526 VMSTORAGE_CHANNEL_PROPERTIES props
;
528 STORVSC_DRIVER_OBJECT
*storDriver
= (STORVSC_DRIVER_OBJECT
*) Device
->Driver
;;
530 memset(&props
, sizeof(VMSTORAGE_CHANNEL_PROPERTIES
), 0);
533 ret
= Device
->Driver
->VmbusChannelInterface
.Open(Device
,
534 storDriver
->RingBufferSize
,
535 storDriver
->RingBufferSize
,
537 sizeof(VMSTORAGE_CHANNEL_PROPERTIES
),
538 StorVscOnChannelCallback
,
542 DPRINT_DBG(STORVSC
, "storage props: path id %d, tgt id %d, max xfer %d", props
.PathId
, props
.TargetId
, props
.MaxTransferBytes
);
546 DPRINT_ERR(STORVSC
, "unable to open channel: %d", ret
);
550 ret
= StorVscChannelInit(Device
);
559 StorVscOnDeviceRemove()
562 Callback when the our device is being removed
566 StorVscOnDeviceRemove(
567 DEVICE_OBJECT
*Device
570 STORVSC_DEVICE
*storDevice
;
573 DPRINT_ENTER(STORVSC
);
575 DPRINT_INFO(STORVSC
, "disabling storage device (%p)...", Device
->Extension
);
577 storDevice
= ReleaseStorDevice(Device
);
579 // At this point, all outbound traffic should be disable. We only allow inbound traffic (responses) to proceed
580 // so that outstanding requests can be completed.
581 while (storDevice
->NumOutstandingRequests
)
583 DPRINT_INFO(STORVSC
, "waiting for %d requests to complete...", storDevice
->NumOutstandingRequests
);
588 DPRINT_INFO(STORVSC
, "removing storage device (%p)...", Device
->Extension
);
590 storDevice
= FinalReleaseStorDevice(Device
);
592 DPRINT_INFO(STORVSC
, "storage device (%p) safe to remove", storDevice
);
595 Device
->Driver
->VmbusChannelInterface
.Close(Device
);
597 FreeStorDevice(storDevice
);
599 DPRINT_EXIT(STORVSC
);
605 //StorVscOnTargetRescan(
609 // DEVICE_OBJECT *device=(DEVICE_OBJECT*)Context;
610 // STORVSC_DRIVER_OBJECT *storDriver;
612 // DPRINT_ENTER(STORVSC);
614 // storDriver = (STORVSC_DRIVER_OBJECT*) device->Driver;
615 // storDriver->OnHostRescan(device);
617 // DPRINT_EXIT(STORVSC);
622 DEVICE_OBJECT
*Device
627 STORVSC_DEVICE
*storDevice
;
628 STORVSC_REQUEST_EXTENSION
*request
;
629 VSTOR_PACKET
*vstorPacket
;
631 DPRINT_ENTER(STORVSC
);
633 DPRINT_INFO(STORVSC
, "resetting host adapter...");
635 storDevice
= GetStorDevice(Device
);
638 DPRINT_ERR(STORVSC
, "unable to get stor device...device being destroyed?");
639 DPRINT_EXIT(STORVSC
);
643 request
= &storDevice
->ResetRequest
;
644 vstorPacket
= &request
->VStorPacket
;
646 request
->WaitEvent
= WaitEventCreate();
648 vstorPacket
->Operation
= VStorOperationResetBus
;
649 vstorPacket
->Flags
= REQUEST_COMPLETION_FLAG
;
650 vstorPacket
->VmSrb
.PathId
= storDevice
->PathId
;
652 ret
= Device
->Driver
->VmbusChannelInterface
.SendPacket(Device
,
654 sizeof(VSTOR_PACKET
),
655 (unsigned long)&storDevice
->ResetRequest
,
656 VmbusPacketTypeDataInBand
,
657 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
660 DPRINT_ERR(STORVSC
, "Unable to send reset packet %p ret %d", vstorPacket
, ret
);
664 // FIXME: Add a timeout
665 WaitEventWait(request
->WaitEvent
);
667 WaitEventClose(request
->WaitEvent
);
668 DPRINT_INFO(STORVSC
, "host adapter reset completed");
670 // At this point, all outstanding requests in the adapter should have been flushed out and return to us
673 PutStorDevice(Device
);
674 DPRINT_EXIT(STORVSC
);
684 Callback to initiate an I/O request
689 DEVICE_OBJECT
*Device
,
690 STORVSC_REQUEST
*Request
693 STORVSC_DEVICE
*storDevice
;
694 STORVSC_REQUEST_EXTENSION
* requestExtension
= (STORVSC_REQUEST_EXTENSION
*) Request
->Extension
;
695 VSTOR_PACKET
* vstorPacket
=&requestExtension
->VStorPacket
;
698 DPRINT_ENTER(STORVSC
);
700 storDevice
= GetStorDevice(Device
);
702 DPRINT_DBG(STORVSC
, "enter - Device %p, DeviceExt %p, Request %p, Extension %p",
703 Device
, storDevice
, Request
, requestExtension
);
705 DPRINT_DBG(STORVSC
, "req %p len %d bus %d, target %d, lun %d cdblen %d",
706 Request
, Request
->DataBuffer
.Length
, Request
->Bus
, Request
->TargetId
, Request
->LunId
, Request
->CdbLen
);
710 DPRINT_ERR(STORVSC
, "unable to get stor device...device being destroyed?");
711 DPRINT_EXIT(STORVSC
);
715 //PrintBytes(Request->Cdb, Request->CdbLen);
717 requestExtension
->Request
= Request
;
718 requestExtension
->Device
= Device
;
720 memset(vstorPacket
, 0 , sizeof(VSTOR_PACKET
));
722 vstorPacket
->Flags
|= REQUEST_COMPLETION_FLAG
;
724 vstorPacket
->VmSrb
.Length
= sizeof(VMSCSI_REQUEST
);
726 vstorPacket
->VmSrb
.PortNumber
= Request
->Host
;
727 vstorPacket
->VmSrb
.PathId
= Request
->Bus
;
728 vstorPacket
->VmSrb
.TargetId
= Request
->TargetId
;
729 vstorPacket
->VmSrb
.Lun
= Request
->LunId
;
731 vstorPacket
->VmSrb
.SenseInfoLength
= SENSE_BUFFER_SIZE
;
733 // Copy over the scsi command descriptor block
734 vstorPacket
->VmSrb
.CdbLength
= Request
->CdbLen
;
735 memcpy(&vstorPacket
->VmSrb
.Cdb
, Request
->Cdb
, Request
->CdbLen
);
737 vstorPacket
->VmSrb
.DataIn
= Request
->Type
;
738 vstorPacket
->VmSrb
.DataTransferLength
= Request
->DataBuffer
.Length
;
740 vstorPacket
->Operation
= VStorOperationExecuteSRB
;
742 DPRINT_DBG(STORVSC
, "srb - len %d port %d, path %d, target %d, lun %d senselen %d cdblen %d",
743 vstorPacket
->VmSrb
.Length
,
744 vstorPacket
->VmSrb
.PortNumber
,
745 vstorPacket
->VmSrb
.PathId
,
746 vstorPacket
->VmSrb
.TargetId
,
747 vstorPacket
->VmSrb
.Lun
,
748 vstorPacket
->VmSrb
.SenseInfoLength
,
749 vstorPacket
->VmSrb
.CdbLength
);
751 if (requestExtension
->Request
->DataBuffer
.Length
)
753 ret
= Device
->Driver
->VmbusChannelInterface
.SendPacketMultiPageBuffer(Device
,
754 &requestExtension
->Request
->DataBuffer
,
756 sizeof(VSTOR_PACKET
),
757 (unsigned long)requestExtension
);
761 ret
= Device
->Driver
->VmbusChannelInterface
.SendPacket(Device
,
763 sizeof(VSTOR_PACKET
),
764 (unsigned long)requestExtension
,
765 VmbusPacketTypeDataInBand
,
766 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
);
771 DPRINT_DBG(STORVSC
, "Unable to send packet %p ret %d", vstorPacket
, ret
);
774 InterlockedIncrement(&storDevice
->NumOutstandingRequests
);
776 PutStorDevice(Device
);
778 DPRINT_EXIT(STORVSC
);
788 Perform any cleanup when the driver is removed
793 DRIVER_OBJECT
*Driver
796 DPRINT_ENTER(STORVSC
);
797 DPRINT_EXIT(STORVSC
);
802 StorVscOnIOCompletion(
803 DEVICE_OBJECT
*Device
,
804 VSTOR_PACKET
*VStorPacket
,
805 STORVSC_REQUEST_EXTENSION
*RequestExt
808 STORVSC_REQUEST
*request
;
809 STORVSC_DEVICE
*storDevice
;
811 DPRINT_ENTER(STORVSC
);
813 storDevice
= MustGetStorDevice(Device
);
816 DPRINT_ERR(STORVSC
, "unable to get stor device...device being destroyed?");
817 DPRINT_EXIT(STORVSC
);
821 DPRINT_DBG(STORVSC
, "IO_COMPLETE_OPERATION - request extension %p completed bytes xfer %u",
822 RequestExt
, VStorPacket
->VmSrb
.DataTransferLength
);
824 ASSERT(RequestExt
!= NULL
);
825 ASSERT(RequestExt
->Request
!= NULL
);
827 request
= RequestExt
->Request
;
829 ASSERT(request
->OnIOCompletion
!= NULL
);
831 // Copy over the status...etc
832 request
->Status
= VStorPacket
->VmSrb
.ScsiStatus
;
834 if (request
->Status
!= 0 || VStorPacket
->VmSrb
.SrbStatus
!= 1)
836 DPRINT_WARN(STORVSC
, "cmd 0x%x scsi status 0x%x srb status 0x%x\n",
838 VStorPacket
->VmSrb
.ScsiStatus
,
839 VStorPacket
->VmSrb
.SrbStatus
);
842 if ((request
->Status
& 0xFF) == 0x02) // CHECK_CONDITION
844 if (VStorPacket
->VmSrb
.SrbStatus
& 0x80) // autosense data available
846 DPRINT_WARN(STORVSC
, "storvsc pkt %p autosense data valid - len %d\n",
847 RequestExt
, VStorPacket
->VmSrb
.SenseInfoLength
);
849 ASSERT(VStorPacket
->VmSrb
.SenseInfoLength
<= request
->SenseBufferSize
);
850 memcpy(request
->SenseBuffer
,
851 VStorPacket
->VmSrb
.SenseData
,
852 VStorPacket
->VmSrb
.SenseInfoLength
);
854 request
->SenseBufferSize
= VStorPacket
->VmSrb
.SenseInfoLength
;
859 request
->BytesXfer
= VStorPacket
->VmSrb
.DataTransferLength
;
861 request
->OnIOCompletion(request
);
863 InterlockedDecrement(&storDevice
->NumOutstandingRequests
);
865 PutStorDevice(Device
);
867 DPRINT_EXIT(STORVSC
);
873 DEVICE_OBJECT
*Device
,
874 VSTOR_PACKET
*VStorPacket
,
875 STORVSC_REQUEST_EXTENSION
*RequestExt
878 switch(VStorPacket
->Operation
)
880 case VStorOperationCompleteIo
:
882 DPRINT_DBG(STORVSC
, "IO_COMPLETE_OPERATION");
883 StorVscOnIOCompletion(Device
, VStorPacket
, RequestExt
);
886 //case ENUMERATE_DEVICE_OPERATION:
888 // DPRINT_INFO(STORVSC, "ENUMERATE_DEVICE_OPERATION");
890 // StorVscOnTargetRescan(Device);
893 case VStorOperationRemoveDevice
:
895 DPRINT_INFO(STORVSC
, "REMOVE_DEVICE_OPERATION");
900 DPRINT_INFO(STORVSC
, "Unknown operation received - %d", VStorPacket
->Operation
);
906 StorVscOnChannelCallback(
911 DEVICE_OBJECT
*device
= (DEVICE_OBJECT
*)Context
;
912 STORVSC_DEVICE
*storDevice
;
915 unsigned char packet
[ALIGN_UP(sizeof(VSTOR_PACKET
),8)];
916 STORVSC_REQUEST_EXTENSION
*request
;
918 DPRINT_ENTER(STORVSC
);
922 storDevice
= MustGetStorDevice(device
);
925 DPRINT_ERR(STORVSC
, "unable to get stor device...device being destroyed?");
926 DPRINT_EXIT(STORVSC
);
932 ret
= device
->Driver
->VmbusChannelInterface
.RecvPacket(device
,
934 ALIGN_UP(sizeof(VSTOR_PACKET
),8),
937 if (ret
== 0 && bytesRecvd
> 0)
939 DPRINT_DBG(STORVSC
, "receive %d bytes - tid %llx", bytesRecvd
, requestId
);
941 //ASSERT(bytesRecvd == sizeof(VSTOR_PACKET));
943 request
= (STORVSC_REQUEST_EXTENSION
*)(unsigned long)requestId
;
946 //if (vstorPacket.Flags & SYNTHETIC_FLAG)
947 if ((request
== &storDevice
->InitRequest
) || (request
== &storDevice
->ResetRequest
))
949 //DPRINT_INFO(STORVSC, "reset completion - operation %u status %u", vstorPacket.Operation, vstorPacket.Status);
951 memcpy(&request
->VStorPacket
, packet
, sizeof(VSTOR_PACKET
));
953 WaitEventSet(request
->WaitEvent
);
957 StorVscOnReceive(device
, (VSTOR_PACKET
*)packet
, request
);
962 //DPRINT_DBG(STORVSC, "nothing else to read...");
967 PutStorDevice(device
);
969 DPRINT_EXIT(STORVSC
);