diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-01 01:31:22 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-15 15:02:02 -0400 |
commit | 163680b4dbc056c2f1ccf497d12ae8f6fa38c455 (patch) | |
tree | f29c27ef4d1f3dcac5d1ba5e87031a6e7defd221 /drivers/staging/hv/StorVsc.c | |
parent | 068c5df20e7118d37e8c3f866ec22ee081548704 (diff) |
Staging: hv: reorg StorVsc.c
This gets rid of all of the forward declarations.
Cc: Hank Janssen <hjanssen@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/hv/StorVsc.c')
-rw-r--r-- | drivers/staging/hv/StorVsc.c | 515 |
1 files changed, 249 insertions, 266 deletions
diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c index c06ea8c2e96..14015c92794 100644 --- a/drivers/staging/hv/StorVsc.c +++ b/drivers/staging/hv/StorVsc.c | |||
@@ -79,21 +79,6 @@ static const struct hv_guid gStorVscDeviceType = { | |||
79 | }; | 79 | }; |
80 | 80 | ||
81 | 81 | ||
82 | static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); | ||
83 | static int StorVscOnDeviceRemove(struct hv_device *Device); | ||
84 | static int StorVscOnIORequest(struct hv_device *Device, | ||
85 | struct hv_storvsc_request *Request); | ||
86 | static int StorVscOnHostReset(struct hv_device *Device); | ||
87 | static void StorVscOnCleanup(struct hv_driver *Device); | ||
88 | static void StorVscOnChannelCallback(void *Context); | ||
89 | static void StorVscOnIOCompletion(struct hv_device *Device, | ||
90 | struct vstor_packet *VStorPacket, | ||
91 | struct storvsc_request_extension *RequestExt); | ||
92 | static void StorVscOnReceive(struct hv_device *Device, | ||
93 | struct vstor_packet *VStorPacket, | ||
94 | struct storvsc_request_extension *RequestExt); | ||
95 | static int StorVscConnectToVsp(struct hv_device *Device); | ||
96 | |||
97 | static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) | 82 | static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) |
98 | { | 83 | { |
99 | struct storvsc_device *storDevice; | 84 | struct storvsc_device *storDevice; |
@@ -189,116 +174,6 @@ static inline struct storvsc_device *FinalReleaseStorDevice( | |||
189 | return storDevice; | 174 | return storDevice; |
190 | } | 175 | } |
191 | 176 | ||
192 | /** | ||
193 | * StorVscInitialize - Main entry point | ||
194 | */ | ||
195 | int StorVscInitialize(struct hv_driver *Driver) | ||
196 | { | ||
197 | struct storvsc_driver_object *storDriver; | ||
198 | |||
199 | DPRINT_ENTER(STORVSC); | ||
200 | |||
201 | storDriver = (struct storvsc_driver_object *)Driver; | ||
202 | |||
203 | DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd " | ||
204 | "sizeof(struct storvsc_request_extension)=%zd " | ||
205 | "sizeof(struct vstor_packet)=%zd, " | ||
206 | "sizeof(struct vmscsi_request)=%zd", | ||
207 | sizeof(struct hv_storvsc_request), | ||
208 | sizeof(struct storvsc_request_extension), | ||
209 | sizeof(struct vstor_packet), | ||
210 | sizeof(struct vmscsi_request)); | ||
211 | |||
212 | /* Make sure we are at least 2 pages since 1 page is used for control */ | ||
213 | ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); | ||
214 | |||
215 | Driver->name = gDriverName; | ||
216 | memcpy(&Driver->deviceType, &gStorVscDeviceType, | ||
217 | sizeof(struct hv_guid)); | ||
218 | |||
219 | storDriver->RequestExtSize = sizeof(struct storvsc_request_extension); | ||
220 | |||
221 | /* | ||
222 | * Divide the ring buffer data size (which is 1 page less | ||
223 | * than the ring buffer size since that page is reserved for | ||
224 | * the ring buffer indices) by the max request size (which is | ||
225 | * VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + struct vstor_packet + u64) | ||
226 | */ | ||
227 | storDriver->MaxOutstandingRequestsPerChannel = | ||
228 | ((storDriver->RingBufferSize - PAGE_SIZE) / | ||
229 | ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + | ||
230 | sizeof(struct vstor_packet) + sizeof(u64), | ||
231 | sizeof(u64))); | ||
232 | |||
233 | DPRINT_INFO(STORVSC, "max io %u, currently %u\n", | ||
234 | storDriver->MaxOutstandingRequestsPerChannel, | ||
235 | STORVSC_MAX_IO_REQUESTS); | ||
236 | |||
237 | /* Setup the dispatch table */ | ||
238 | storDriver->Base.OnDeviceAdd = StorVscOnDeviceAdd; | ||
239 | storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove; | ||
240 | storDriver->Base.OnCleanup = StorVscOnCleanup; | ||
241 | |||
242 | storDriver->OnIORequest = StorVscOnIORequest; | ||
243 | storDriver->OnHostReset = StorVscOnHostReset; | ||
244 | |||
245 | DPRINT_EXIT(STORVSC); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | /** | ||
251 | * StorVscOnDeviceAdd - Callback when the device belonging to this driver is added | ||
252 | */ | ||
253 | static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) | ||
254 | { | ||
255 | struct storvsc_device *storDevice; | ||
256 | /* struct vmstorage_channel_properties *props; */ | ||
257 | struct storvsc_device_info *deviceInfo; | ||
258 | int ret = 0; | ||
259 | |||
260 | DPRINT_ENTER(STORVSC); | ||
261 | |||
262 | deviceInfo = (struct storvsc_device_info *)AdditionalInfo; | ||
263 | storDevice = AllocStorDevice(Device); | ||
264 | if (!storDevice) { | ||
265 | ret = -1; | ||
266 | goto Cleanup; | ||
267 | } | ||
268 | |||
269 | /* Save the channel properties to our storvsc channel */ | ||
270 | /* props = (struct vmstorage_channel_properties *) | ||
271 | * channel->offerMsg.Offer.u.Standard.UserDefined; */ | ||
272 | |||
273 | /* FIXME: */ | ||
274 | /* | ||
275 | * If we support more than 1 scsi channel, we need to set the | ||
276 | * port number here to the scsi channel but how do we get the | ||
277 | * scsi channel prior to the bus scan | ||
278 | */ | ||
279 | |||
280 | /* storChannel->PortNumber = 0; | ||
281 | storChannel->PathId = props->PathId; | ||
282 | storChannel->TargetId = props->TargetId; */ | ||
283 | |||
284 | storDevice->PortNumber = deviceInfo->PortNumber; | ||
285 | /* Send it back up */ | ||
286 | ret = StorVscConnectToVsp(Device); | ||
287 | |||
288 | /* deviceInfo->PortNumber = storDevice->PortNumber; */ | ||
289 | deviceInfo->PathId = storDevice->PathId; | ||
290 | deviceInfo->TargetId = storDevice->TargetId; | ||
291 | |||
292 | DPRINT_DBG(STORVSC, "assigned port %u, path %u target %u\n", | ||
293 | storDevice->PortNumber, storDevice->PathId, | ||
294 | storDevice->TargetId); | ||
295 | |||
296 | Cleanup: | ||
297 | DPRINT_EXIT(STORVSC); | ||
298 | |||
299 | return ret; | ||
300 | } | ||
301 | |||
302 | static int StorVscChannelInit(struct hv_device *Device) | 177 | static int StorVscChannelInit(struct hv_device *Device) |
303 | { | 178 | { |
304 | struct storvsc_device *storDevice; | 179 | struct storvsc_device *storDevice; |
@@ -469,6 +344,163 @@ Cleanup: | |||
469 | return ret; | 344 | return ret; |
470 | } | 345 | } |
471 | 346 | ||
347 | static void StorVscOnIOCompletion(struct hv_device *Device, | ||
348 | struct vstor_packet *VStorPacket, | ||
349 | struct storvsc_request_extension *RequestExt) | ||
350 | { | ||
351 | struct hv_storvsc_request *request; | ||
352 | struct storvsc_device *storDevice; | ||
353 | |||
354 | DPRINT_ENTER(STORVSC); | ||
355 | |||
356 | storDevice = MustGetStorDevice(Device); | ||
357 | if (!storDevice) { | ||
358 | DPRINT_ERR(STORVSC, "unable to get stor device..." | ||
359 | "device being destroyed?"); | ||
360 | DPRINT_EXIT(STORVSC); | ||
361 | return; | ||
362 | } | ||
363 | |||
364 | DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request extension %p " | ||
365 | "completed bytes xfer %u", RequestExt, | ||
366 | VStorPacket->VmSrb.DataTransferLength); | ||
367 | |||
368 | ASSERT(RequestExt != NULL); | ||
369 | ASSERT(RequestExt->Request != NULL); | ||
370 | |||
371 | request = RequestExt->Request; | ||
372 | |||
373 | ASSERT(request->OnIOCompletion != NULL); | ||
374 | |||
375 | /* Copy over the status...etc */ | ||
376 | request->Status = VStorPacket->VmSrb.ScsiStatus; | ||
377 | |||
378 | if (request->Status != 0 || VStorPacket->VmSrb.SrbStatus != 1) { | ||
379 | DPRINT_WARN(STORVSC, | ||
380 | "cmd 0x%x scsi status 0x%x srb status 0x%x\n", | ||
381 | request->Cdb[0], VStorPacket->VmSrb.ScsiStatus, | ||
382 | VStorPacket->VmSrb.SrbStatus); | ||
383 | } | ||
384 | |||
385 | if ((request->Status & 0xFF) == 0x02) { | ||
386 | /* CHECK_CONDITION */ | ||
387 | if (VStorPacket->VmSrb.SrbStatus & 0x80) { | ||
388 | /* autosense data available */ | ||
389 | DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data " | ||
390 | "valid - len %d\n", RequestExt, | ||
391 | VStorPacket->VmSrb.SenseInfoLength); | ||
392 | |||
393 | ASSERT(VStorPacket->VmSrb.SenseInfoLength <= | ||
394 | request->SenseBufferSize); | ||
395 | memcpy(request->SenseBuffer, | ||
396 | VStorPacket->VmSrb.SenseData, | ||
397 | VStorPacket->VmSrb.SenseInfoLength); | ||
398 | |||
399 | request->SenseBufferSize = | ||
400 | VStorPacket->VmSrb.SenseInfoLength; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | /* TODO: */ | ||
405 | request->BytesXfer = VStorPacket->VmSrb.DataTransferLength; | ||
406 | |||
407 | request->OnIOCompletion(request); | ||
408 | |||
409 | atomic_dec(&storDevice->NumOutstandingRequests); | ||
410 | |||
411 | PutStorDevice(Device); | ||
412 | |||
413 | DPRINT_EXIT(STORVSC); | ||
414 | } | ||
415 | |||
416 | static void StorVscOnReceive(struct hv_device *Device, | ||
417 | struct vstor_packet *VStorPacket, | ||
418 | struct storvsc_request_extension *RequestExt) | ||
419 | { | ||
420 | switch (VStorPacket->Operation) { | ||
421 | case VStorOperationCompleteIo: | ||
422 | DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION"); | ||
423 | StorVscOnIOCompletion(Device, VStorPacket, RequestExt); | ||
424 | break; | ||
425 | case VStorOperationRemoveDevice: | ||
426 | DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION"); | ||
427 | /* TODO: */ | ||
428 | break; | ||
429 | |||
430 | default: | ||
431 | DPRINT_INFO(STORVSC, "Unknown operation received - %d", | ||
432 | VStorPacket->Operation); | ||
433 | break; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | static void StorVscOnChannelCallback(void *context) | ||
438 | { | ||
439 | struct hv_device *device = (struct hv_device *)context; | ||
440 | struct storvsc_device *storDevice; | ||
441 | u32 bytesRecvd; | ||
442 | u64 requestId; | ||
443 | unsigned char packet[ALIGN_UP(sizeof(struct vstor_packet), 8)]; | ||
444 | struct storvsc_request_extension *request; | ||
445 | int ret; | ||
446 | |||
447 | DPRINT_ENTER(STORVSC); | ||
448 | |||
449 | ASSERT(device); | ||
450 | |||
451 | storDevice = MustGetStorDevice(device); | ||
452 | if (!storDevice) { | ||
453 | DPRINT_ERR(STORVSC, "unable to get stor device..." | ||
454 | "device being destroyed?"); | ||
455 | DPRINT_EXIT(STORVSC); | ||
456 | return; | ||
457 | } | ||
458 | |||
459 | do { | ||
460 | ret = device->Driver->VmbusChannelInterface.RecvPacket(device, | ||
461 | packet, | ||
462 | ALIGN_UP(sizeof(struct vstor_packet), 8), | ||
463 | &bytesRecvd, &requestId); | ||
464 | if (ret == 0 && bytesRecvd > 0) { | ||
465 | DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx", | ||
466 | bytesRecvd, requestId); | ||
467 | |||
468 | /* ASSERT(bytesRecvd == sizeof(struct vstor_packet)); */ | ||
469 | |||
470 | request = (struct storvsc_request_extension *) | ||
471 | (unsigned long)requestId; | ||
472 | ASSERT(request); | ||
473 | |||
474 | /* if (vstorPacket.Flags & SYNTHETIC_FLAG) */ | ||
475 | if ((request == &storDevice->InitRequest) || | ||
476 | (request == &storDevice->ResetRequest)) { | ||
477 | /* DPRINT_INFO(STORVSC, | ||
478 | * "reset completion - operation " | ||
479 | * "%u status %u", | ||
480 | * vstorPacket.Operation, | ||
481 | * vstorPacket.Status); */ | ||
482 | |||
483 | memcpy(&request->VStorPacket, packet, | ||
484 | sizeof(struct vstor_packet)); | ||
485 | |||
486 | osd_WaitEventSet(request->WaitEvent); | ||
487 | } else { | ||
488 | StorVscOnReceive(device, | ||
489 | (struct vstor_packet *)packet, | ||
490 | request); | ||
491 | } | ||
492 | } else { | ||
493 | /* DPRINT_DBG(STORVSC, "nothing else to read..."); */ | ||
494 | break; | ||
495 | } | ||
496 | } while (1); | ||
497 | |||
498 | PutStorDevice(device); | ||
499 | |||
500 | DPRINT_EXIT(STORVSC); | ||
501 | return; | ||
502 | } | ||
503 | |||
472 | static int StorVscConnectToVsp(struct hv_device *Device) | 504 | static int StorVscConnectToVsp(struct hv_device *Device) |
473 | { | 505 | { |
474 | struct vmstorage_channel_properties props; | 506 | struct vmstorage_channel_properties props; |
@@ -500,6 +532,57 @@ static int StorVscConnectToVsp(struct hv_device *Device) | |||
500 | return ret; | 532 | return ret; |
501 | } | 533 | } |
502 | 534 | ||
535 | /** | ||
536 | * StorVscOnDeviceAdd - Callback when the device belonging to this driver is added | ||
537 | */ | ||
538 | static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) | ||
539 | { | ||
540 | struct storvsc_device *storDevice; | ||
541 | /* struct vmstorage_channel_properties *props; */ | ||
542 | struct storvsc_device_info *deviceInfo; | ||
543 | int ret = 0; | ||
544 | |||
545 | DPRINT_ENTER(STORVSC); | ||
546 | |||
547 | deviceInfo = (struct storvsc_device_info *)AdditionalInfo; | ||
548 | storDevice = AllocStorDevice(Device); | ||
549 | if (!storDevice) { | ||
550 | ret = -1; | ||
551 | goto Cleanup; | ||
552 | } | ||
553 | |||
554 | /* Save the channel properties to our storvsc channel */ | ||
555 | /* props = (struct vmstorage_channel_properties *) | ||
556 | * channel->offerMsg.Offer.u.Standard.UserDefined; */ | ||
557 | |||
558 | /* FIXME: */ | ||
559 | /* | ||
560 | * If we support more than 1 scsi channel, we need to set the | ||
561 | * port number here to the scsi channel but how do we get the | ||
562 | * scsi channel prior to the bus scan | ||
563 | */ | ||
564 | |||
565 | /* storChannel->PortNumber = 0; | ||
566 | storChannel->PathId = props->PathId; | ||
567 | storChannel->TargetId = props->TargetId; */ | ||
568 | |||
569 | storDevice->PortNumber = deviceInfo->PortNumber; | ||
570 | /* Send it back up */ | ||
571 | ret = StorVscConnectToVsp(Device); | ||
572 | |||
573 | /* deviceInfo->PortNumber = storDevice->PortNumber; */ | ||
574 | deviceInfo->PathId = storDevice->PathId; | ||
575 | deviceInfo->TargetId = storDevice->TargetId; | ||
576 | |||
577 | DPRINT_DBG(STORVSC, "assigned port %u, path %u target %u\n", | ||
578 | storDevice->PortNumber, storDevice->PathId, | ||
579 | storDevice->TargetId); | ||
580 | |||
581 | Cleanup: | ||
582 | DPRINT_EXIT(STORVSC); | ||
583 | |||
584 | return ret; | ||
585 | } | ||
503 | 586 | ||
504 | /** | 587 | /** |
505 | * StorVscOnDeviceRemove - Callback when the our device is being removed | 588 | * StorVscOnDeviceRemove - Callback when the our device is being removed |
@@ -708,160 +791,60 @@ static void StorVscOnCleanup(struct hv_driver *Driver) | |||
708 | DPRINT_EXIT(STORVSC); | 791 | DPRINT_EXIT(STORVSC); |
709 | } | 792 | } |
710 | 793 | ||
711 | static void StorVscOnIOCompletion(struct hv_device *Device, | 794 | /** |
712 | struct vstor_packet *VStorPacket, | 795 | * StorVscInitialize - Main entry point |
713 | struct storvsc_request_extension *RequestExt) | 796 | */ |
797 | int StorVscInitialize(struct hv_driver *Driver) | ||
714 | { | 798 | { |
715 | struct hv_storvsc_request *request; | 799 | struct storvsc_driver_object *storDriver; |
716 | struct storvsc_device *storDevice; | ||
717 | 800 | ||
718 | DPRINT_ENTER(STORVSC); | 801 | DPRINT_ENTER(STORVSC); |
719 | 802 | ||
720 | storDevice = MustGetStorDevice(Device); | 803 | storDriver = (struct storvsc_driver_object *)Driver; |
721 | if (!storDevice) { | ||
722 | DPRINT_ERR(STORVSC, "unable to get stor device..." | ||
723 | "device being destroyed?"); | ||
724 | DPRINT_EXIT(STORVSC); | ||
725 | return; | ||
726 | } | ||
727 | |||
728 | DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request extension %p " | ||
729 | "completed bytes xfer %u", RequestExt, | ||
730 | VStorPacket->VmSrb.DataTransferLength); | ||
731 | |||
732 | ASSERT(RequestExt != NULL); | ||
733 | ASSERT(RequestExt->Request != NULL); | ||
734 | |||
735 | request = RequestExt->Request; | ||
736 | |||
737 | ASSERT(request->OnIOCompletion != NULL); | ||
738 | |||
739 | /* Copy over the status...etc */ | ||
740 | request->Status = VStorPacket->VmSrb.ScsiStatus; | ||
741 | 804 | ||
742 | if (request->Status != 0 || VStorPacket->VmSrb.SrbStatus != 1) { | 805 | DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd " |
743 | DPRINT_WARN(STORVSC, | 806 | "sizeof(struct storvsc_request_extension)=%zd " |
744 | "cmd 0x%x scsi status 0x%x srb status 0x%x\n", | 807 | "sizeof(struct vstor_packet)=%zd, " |
745 | request->Cdb[0], VStorPacket->VmSrb.ScsiStatus, | 808 | "sizeof(struct vmscsi_request)=%zd", |
746 | VStorPacket->VmSrb.SrbStatus); | 809 | sizeof(struct hv_storvsc_request), |
747 | } | 810 | sizeof(struct storvsc_request_extension), |
811 | sizeof(struct vstor_packet), | ||
812 | sizeof(struct vmscsi_request)); | ||
748 | 813 | ||
749 | if ((request->Status & 0xFF) == 0x02) { | 814 | /* Make sure we are at least 2 pages since 1 page is used for control */ |
750 | /* CHECK_CONDITION */ | 815 | ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); |
751 | if (VStorPacket->VmSrb.SrbStatus & 0x80) { | ||
752 | /* autosense data available */ | ||
753 | DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data " | ||
754 | "valid - len %d\n", RequestExt, | ||
755 | VStorPacket->VmSrb.SenseInfoLength); | ||
756 | 816 | ||
757 | ASSERT(VStorPacket->VmSrb.SenseInfoLength <= | 817 | Driver->name = gDriverName; |
758 | request->SenseBufferSize); | 818 | memcpy(&Driver->deviceType, &gStorVscDeviceType, |
759 | memcpy(request->SenseBuffer, | 819 | sizeof(struct hv_guid)); |
760 | VStorPacket->VmSrb.SenseData, | ||
761 | VStorPacket->VmSrb.SenseInfoLength); | ||
762 | 820 | ||
763 | request->SenseBufferSize = | 821 | storDriver->RequestExtSize = sizeof(struct storvsc_request_extension); |
764 | VStorPacket->VmSrb.SenseInfoLength; | ||
765 | } | ||
766 | } | ||
767 | 822 | ||
768 | /* TODO: */ | 823 | /* |
769 | request->BytesXfer = VStorPacket->VmSrb.DataTransferLength; | 824 | * Divide the ring buffer data size (which is 1 page less |
825 | * than the ring buffer size since that page is reserved for | ||
826 | * the ring buffer indices) by the max request size (which is | ||
827 | * VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + struct vstor_packet + u64) | ||
828 | */ | ||
829 | storDriver->MaxOutstandingRequestsPerChannel = | ||
830 | ((storDriver->RingBufferSize - PAGE_SIZE) / | ||
831 | ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + | ||
832 | sizeof(struct vstor_packet) + sizeof(u64), | ||
833 | sizeof(u64))); | ||
770 | 834 | ||
771 | request->OnIOCompletion(request); | 835 | DPRINT_INFO(STORVSC, "max io %u, currently %u\n", |
836 | storDriver->MaxOutstandingRequestsPerChannel, | ||
837 | STORVSC_MAX_IO_REQUESTS); | ||
772 | 838 | ||
773 | atomic_dec(&storDevice->NumOutstandingRequests); | 839 | /* Setup the dispatch table */ |
840 | storDriver->Base.OnDeviceAdd = StorVscOnDeviceAdd; | ||
841 | storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove; | ||
842 | storDriver->Base.OnCleanup = StorVscOnCleanup; | ||
774 | 843 | ||
775 | PutStorDevice(Device); | 844 | storDriver->OnIORequest = StorVscOnIORequest; |
845 | storDriver->OnHostReset = StorVscOnHostReset; | ||
776 | 846 | ||
777 | DPRINT_EXIT(STORVSC); | 847 | DPRINT_EXIT(STORVSC); |
778 | } | ||
779 | |||
780 | |||
781 | static void StorVscOnReceive(struct hv_device *Device, | ||
782 | struct vstor_packet *VStorPacket, | ||
783 | struct storvsc_request_extension *RequestExt) | ||
784 | { | ||
785 | switch (VStorPacket->Operation) { | ||
786 | case VStorOperationCompleteIo: | ||
787 | DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION"); | ||
788 | StorVscOnIOCompletion(Device, VStorPacket, RequestExt); | ||
789 | break; | ||
790 | case VStorOperationRemoveDevice: | ||
791 | DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION"); | ||
792 | /* TODO: */ | ||
793 | break; | ||
794 | |||
795 | default: | ||
796 | DPRINT_INFO(STORVSC, "Unknown operation received - %d", | ||
797 | VStorPacket->Operation); | ||
798 | break; | ||
799 | } | ||
800 | } | ||
801 | |||
802 | static void StorVscOnChannelCallback(void *context) | ||
803 | { | ||
804 | struct hv_device *device = (struct hv_device *)context; | ||
805 | struct storvsc_device *storDevice; | ||
806 | u32 bytesRecvd; | ||
807 | u64 requestId; | ||
808 | unsigned char packet[ALIGN_UP(sizeof(struct vstor_packet), 8)]; | ||
809 | struct storvsc_request_extension *request; | ||
810 | int ret; | ||
811 | |||
812 | DPRINT_ENTER(STORVSC); | ||
813 | |||
814 | ASSERT(device); | ||
815 | |||
816 | storDevice = MustGetStorDevice(device); | ||
817 | if (!storDevice) { | ||
818 | DPRINT_ERR(STORVSC, "unable to get stor device..." | ||
819 | "device being destroyed?"); | ||
820 | DPRINT_EXIT(STORVSC); | ||
821 | return; | ||
822 | } | ||
823 | |||
824 | do { | ||
825 | ret = device->Driver->VmbusChannelInterface.RecvPacket(device, | ||
826 | packet, | ||
827 | ALIGN_UP(sizeof(struct vstor_packet), 8), | ||
828 | &bytesRecvd, &requestId); | ||
829 | if (ret == 0 && bytesRecvd > 0) { | ||
830 | DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx", | ||
831 | bytesRecvd, requestId); | ||
832 | 848 | ||
833 | /* ASSERT(bytesRecvd == sizeof(struct vstor_packet)); */ | 849 | return 0; |
834 | |||
835 | request = (struct storvsc_request_extension *) | ||
836 | (unsigned long)requestId; | ||
837 | ASSERT(request); | ||
838 | |||
839 | /* if (vstorPacket.Flags & SYNTHETIC_FLAG) */ | ||
840 | if ((request == &storDevice->InitRequest) || | ||
841 | (request == &storDevice->ResetRequest)) { | ||
842 | /* DPRINT_INFO(STORVSC, | ||
843 | * "reset completion - operation " | ||
844 | * "%u status %u", | ||
845 | * vstorPacket.Operation, | ||
846 | * vstorPacket.Status); */ | ||
847 | |||
848 | memcpy(&request->VStorPacket, packet, | ||
849 | sizeof(struct vstor_packet)); | ||
850 | |||
851 | osd_WaitEventSet(request->WaitEvent); | ||
852 | } else { | ||
853 | StorVscOnReceive(device, | ||
854 | (struct vstor_packet *)packet, | ||
855 | request); | ||
856 | } | ||
857 | } else { | ||
858 | /* DPRINT_DBG(STORVSC, "nothing else to read..."); */ | ||
859 | break; | ||
860 | } | ||
861 | } while (1); | ||
862 | |||
863 | PutStorDevice(device); | ||
864 | |||
865 | DPRINT_EXIT(STORVSC); | ||
866 | return; | ||
867 | } | 850 | } |