aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/hv/StorVsc.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2009-09-01 01:31:22 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-15 15:02:02 -0400
commit163680b4dbc056c2f1ccf497d12ae8f6fa38c455 (patch)
treef29c27ef4d1f3dcac5d1ba5e87031a6e7defd221 /drivers/staging/hv/StorVsc.c
parent068c5df20e7118d37e8c3f866ec22ee081548704 (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.c515
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
82static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo);
83static int StorVscOnDeviceRemove(struct hv_device *Device);
84static int StorVscOnIORequest(struct hv_device *Device,
85 struct hv_storvsc_request *Request);
86static int StorVscOnHostReset(struct hv_device *Device);
87static void StorVscOnCleanup(struct hv_driver *Device);
88static void StorVscOnChannelCallback(void *Context);
89static void StorVscOnIOCompletion(struct hv_device *Device,
90 struct vstor_packet *VStorPacket,
91 struct storvsc_request_extension *RequestExt);
92static void StorVscOnReceive(struct hv_device *Device,
93 struct vstor_packet *VStorPacket,
94 struct storvsc_request_extension *RequestExt);
95static int StorVscConnectToVsp(struct hv_device *Device);
96
97static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) 82static 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 */
195int 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 */
253static 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
296Cleanup:
297 DPRINT_EXIT(STORVSC);
298
299 return ret;
300}
301
302static int StorVscChannelInit(struct hv_device *Device) 177static 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
347static 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
416static 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
437static 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
472static int StorVscConnectToVsp(struct hv_device *Device) 504static 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 */
538static 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
581Cleanup:
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
711static void StorVscOnIOCompletion(struct hv_device *Device, 794/**
712 struct vstor_packet *VStorPacket, 795 * StorVscInitialize - Main entry point
713 struct storvsc_request_extension *RequestExt) 796 */
797int 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
781static 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
802static 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}