Deleted Added
full compact
hv_storvsc_drv_freebsd.c (307448) hv_storvsc_drv_freebsd.c (307455)
1/*-
2 * Copyright (c) 2009-2012,2016 Microsoft Corp.
3 * Copyright (c) 2012 NetApp Inc.
4 * Copyright (c) 2012 Citrix Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 19 unchanged lines hidden (view full) ---

28
29/**
30 * StorVSC driver for Hyper-V. This driver presents a SCSI HBA interface
31 * to the Comman Access Method (CAM) layer. CAM control blocks (CCBs) are
32 * converted into VSCSI protocol messages which are delivered to the parent
33 * partition StorVSP driver over the Hyper-V VMBUS.
34 */
35#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2009-2012,2016 Microsoft Corp.
3 * Copyright (c) 2012 NetApp Inc.
4 * Copyright (c) 2012 Citrix Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 19 unchanged lines hidden (view full) ---

28
29/**
30 * StorVSC driver for Hyper-V. This driver presents a SCSI HBA interface
31 * to the Comman Access Method (CAM) layer. CAM control blocks (CCBs) are
32 * converted into VSCSI protocol messages which are delivered to the parent
33 * partition StorVSP driver over the Hyper-V VMBUS.
34 */
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: stable/11/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c 307448 2016-10-17 01:47:49Z sephe $");
36__FBSDID("$FreeBSD: stable/11/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c 307455 2016-10-17 02:30:45Z sephe $");
37
38#include <sys/param.h>
39#include <sys/proc.h>
40#include <sys/condvar.h>
41#include <sys/time.h>
42#include <sys/systm.h>
43#include <sys/sockio.h>
44#include <sys/mbuf.h>

--- 22 unchanged lines hidden (view full) ---

67#include <cam/cam_sim.h>
68#include <cam/cam_xpt_sim.h>
69#include <cam/cam_xpt_internal.h>
70#include <cam/cam_debug.h>
71#include <cam/scsi/scsi_all.h>
72#include <cam/scsi/scsi_message.h>
73
74#include <dev/hyperv/include/hyperv.h>
37
38#include <sys/param.h>
39#include <sys/proc.h>
40#include <sys/condvar.h>
41#include <sys/time.h>
42#include <sys/systm.h>
43#include <sys/sockio.h>
44#include <sys/mbuf.h>

--- 22 unchanged lines hidden (view full) ---

67#include <cam/cam_sim.h>
68#include <cam/cam_xpt_sim.h>
69#include <cam/cam_xpt_internal.h>
70#include <cam/cam_debug.h>
71#include <cam/scsi/scsi_all.h>
72#include <cam/scsi/scsi_message.h>
73
74#include <dev/hyperv/include/hyperv.h>
75#include <dev/hyperv/include/vmbus.h>
75
76#include "hv_vstorage.h"
77#include "vmbus_if.h"
78
79#define STORVSC_RINGBUFFER_SIZE (20*PAGE_SIZE)
80#define STORVSC_MAX_LUNS_PER_TARGET (64)
81#define STORVSC_MAX_IO_REQUESTS (STORVSC_MAX_LUNS_PER_TARGET * 2)
82#define BLKVSC_MAX_IDE_DISKS_PER_TARGET (1)

--- 12 unchanged lines hidden (view full) ---

95};
96
97struct hv_sgl_page_pool{
98 LIST_HEAD(, hv_sgl_node) in_use_sgl_list;
99 LIST_HEAD(, hv_sgl_node) free_sgl_list;
100 boolean_t is_init;
101} g_hv_sgl_page_pool;
102
76
77#include "hv_vstorage.h"
78#include "vmbus_if.h"
79
80#define STORVSC_RINGBUFFER_SIZE (20*PAGE_SIZE)
81#define STORVSC_MAX_LUNS_PER_TARGET (64)
82#define STORVSC_MAX_IO_REQUESTS (STORVSC_MAX_LUNS_PER_TARGET * 2)
83#define BLKVSC_MAX_IDE_DISKS_PER_TARGET (1)

--- 12 unchanged lines hidden (view full) ---

96};
97
98struct hv_sgl_page_pool{
99 LIST_HEAD(, hv_sgl_node) in_use_sgl_list;
100 LIST_HEAD(, hv_sgl_node) free_sgl_list;
101 boolean_t is_init;
102} g_hv_sgl_page_pool;
103
103#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * HV_MAX_MULTIPAGE_BUFFER_COUNT
104#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * VMBUS_CHAN_PRPLIST_MAX
104
105enum storvsc_request_type {
106 WRITE_TYPE,
107 READ_TYPE,
108 UNKNOWN_TYPE
109};
110
105
106enum storvsc_request_type {
107 WRITE_TYPE,
108 READ_TYPE,
109 UNKNOWN_TYPE
110};
111
112struct hvs_gpa_range {
113 struct vmbus_gpa_range gpa_range;
114 uint64_t gpa_page[VMBUS_CHAN_PRPLIST_MAX];
115} __packed;
116
111struct hv_storvsc_request {
112 LIST_ENTRY(hv_storvsc_request) link;
113 struct vstor_packet vstor_packet;
117struct hv_storvsc_request {
118 LIST_ENTRY(hv_storvsc_request) link;
119 struct vstor_packet vstor_packet;
114 hv_vmbus_multipage_buffer data_buf;
120 int prp_cnt;
121 struct hvs_gpa_range prp_list;
115 void *sense_data;
116 uint8_t sense_info_len;
117 uint8_t retries;
118 union ccb *ccb;
119 struct storvsc_softc *softc;
120 struct callout callout;
121 struct sema synch_sema; /*Synchronize the request/response if needed */
122 struct sglist *bounce_sgl;

--- 226 unchanged lines hidden (view full) ---

349 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
350 vstor_packet->u.multi_channels_cnt = request_channels_cnt;
351
352 ret = hv_vmbus_channel_send_packet(
353 sc->hs_chan,
354 vstor_packet,
355 VSTOR_PKT_SIZE,
356 (uint64_t)(uintptr_t)request,
122 void *sense_data;
123 uint8_t sense_info_len;
124 uint8_t retries;
125 union ccb *ccb;
126 struct storvsc_softc *softc;
127 struct callout callout;
128 struct sema synch_sema; /*Synchronize the request/response if needed */
129 struct sglist *bounce_sgl;

--- 226 unchanged lines hidden (view full) ---

356 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
357 vstor_packet->u.multi_channels_cnt = request_channels_cnt;
358
359 ret = hv_vmbus_channel_send_packet(
360 sc->hs_chan,
361 vstor_packet,
362 VSTOR_PKT_SIZE,
363 (uint64_t)(uintptr_t)request,
357 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
358 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
364 VMBUS_CHANPKT_TYPE_INBAND,
365 VMBUS_CHANPKT_FLAG_RC);
359
360 /* wait for 5 seconds */
361 ret = sema_timedwait(&request->synch_sema, 5 * hz);
362 if (ret != 0) {
363 printf("Storvsc_error: create multi-channel timeout, %d\n",
364 ret);
365 return;
366 }

--- 53 unchanged lines hidden (view full) ---

420 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
421
422
423 ret = hv_vmbus_channel_send_packet(
424 sc->hs_chan,
425 vstor_packet,
426 VSTOR_PKT_SIZE,
427 (uint64_t)(uintptr_t)request,
366
367 /* wait for 5 seconds */
368 ret = sema_timedwait(&request->synch_sema, 5 * hz);
369 if (ret != 0) {
370 printf("Storvsc_error: create multi-channel timeout, %d\n",
371 ret);
372 return;
373 }

--- 53 unchanged lines hidden (view full) ---

427 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
428
429
430 ret = hv_vmbus_channel_send_packet(
431 sc->hs_chan,
432 vstor_packet,
433 VSTOR_PKT_SIZE,
434 (uint64_t)(uintptr_t)request,
428 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
429 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
435 VMBUS_CHANPKT_TYPE_INBAND,
436 VMBUS_CHANPKT_FLAG_RC);
430
431 if (ret != 0)
432 goto cleanup;
433
434 /* wait 5 seconds */
435 ret = sema_timedwait(&request->synch_sema, 5 * hz);
436 if (ret != 0)
437 goto cleanup;

--- 16 unchanged lines hidden (view full) ---

454 /* revision is only significant for Windows guests */
455 vstor_packet->u.version.revision = 0;
456
457 ret = hv_vmbus_channel_send_packet(
458 sc->hs_chan,
459 vstor_packet,
460 VSTOR_PKT_SIZE,
461 (uint64_t)(uintptr_t)request,
437
438 if (ret != 0)
439 goto cleanup;
440
441 /* wait 5 seconds */
442 ret = sema_timedwait(&request->synch_sema, 5 * hz);
443 if (ret != 0)
444 goto cleanup;

--- 16 unchanged lines hidden (view full) ---

461 /* revision is only significant for Windows guests */
462 vstor_packet->u.version.revision = 0;
463
464 ret = hv_vmbus_channel_send_packet(
465 sc->hs_chan,
466 vstor_packet,
467 VSTOR_PKT_SIZE,
468 (uint64_t)(uintptr_t)request,
462 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
463 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
469 VMBUS_CHANPKT_TYPE_INBAND,
470 VMBUS_CHANPKT_FLAG_RC);
464
465 if (ret != 0)
466 goto cleanup;
467
468 /* wait 5 seconds */
469 ret = sema_timedwait(&request->synch_sema, 5 * hz);
470
471 if (ret)

--- 25 unchanged lines hidden (view full) ---

497 vstor_packet->operation = VSTOR_OPERATION_QUERYPROPERTIES;
498 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
499
500 ret = hv_vmbus_channel_send_packet(
501 sc->hs_chan,
502 vstor_packet,
503 VSTOR_PKT_SIZE,
504 (uint64_t)(uintptr_t)request,
471
472 if (ret != 0)
473 goto cleanup;
474
475 /* wait 5 seconds */
476 ret = sema_timedwait(&request->synch_sema, 5 * hz);
477
478 if (ret)

--- 25 unchanged lines hidden (view full) ---

504 vstor_packet->operation = VSTOR_OPERATION_QUERYPROPERTIES;
505 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
506
507 ret = hv_vmbus_channel_send_packet(
508 sc->hs_chan,
509 vstor_packet,
510 VSTOR_PKT_SIZE,
511 (uint64_t)(uintptr_t)request,
505 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
506 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
512 VMBUS_CHANPKT_TYPE_INBAND,
513 VMBUS_CHANPKT_FLAG_RC);
507
508 if ( ret != 0)
509 goto cleanup;
510
511 /* wait 5 seconds */
512 ret = sema_timedwait(&request->synch_sema, 5 * hz);
513
514 if (ret != 0)

--- 18 unchanged lines hidden (view full) ---

533 vstor_packet->operation = VSTOR_OPERATION_ENDINITIALIZATION;
534 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
535
536 ret = hv_vmbus_channel_send_packet(
537 sc->hs_chan,
538 vstor_packet,
539 VSTOR_PKT_SIZE,
540 (uint64_t)(uintptr_t)request,
514
515 if ( ret != 0)
516 goto cleanup;
517
518 /* wait 5 seconds */
519 ret = sema_timedwait(&request->synch_sema, 5 * hz);
520
521 if (ret != 0)

--- 18 unchanged lines hidden (view full) ---

540 vstor_packet->operation = VSTOR_OPERATION_ENDINITIALIZATION;
541 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
542
543 ret = hv_vmbus_channel_send_packet(
544 sc->hs_chan,
545 vstor_packet,
546 VSTOR_PKT_SIZE,
547 (uint64_t)(uintptr_t)request,
541 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
542 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
548 VMBUS_CHANPKT_TYPE_INBAND,
549 VMBUS_CHANPKT_FLAG_RC);
543
544 if (ret != 0) {
545 goto cleanup;
546 }
547
548 /* wait 5 seconds */
549 ret = sema_timedwait(&request->synch_sema, 5 * hz);
550

--- 72 unchanged lines hidden (view full) ---

623
624 vstor_packet->operation = VSTOR_OPERATION_RESETBUS;
625 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
626
627 ret = hv_vmbus_channel_send_packet(dev->channel,
628 vstor_packet,
629 VSTOR_PKT_SIZE,
630 (uint64_t)(uintptr_t)&sc->hs_reset_req,
550
551 if (ret != 0) {
552 goto cleanup;
553 }
554
555 /* wait 5 seconds */
556 ret = sema_timedwait(&request->synch_sema, 5 * hz);
557

--- 72 unchanged lines hidden (view full) ---

630
631 vstor_packet->operation = VSTOR_OPERATION_RESETBUS;
632 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
633
634 ret = hv_vmbus_channel_send_packet(dev->channel,
635 vstor_packet,
636 VSTOR_PKT_SIZE,
637 (uint64_t)(uintptr_t)&sc->hs_reset_req,
631 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
632 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
638 VMBUS_CHANPKT_TYPE_INBAND,
639 VMBUS_CHANPKT_FLAG_RC);
633
634 if (ret != 0) {
635 goto cleanup;
636 }
637
638 ret = sema_timedwait(&request->synch_sema, 5 * hz); /* KYS 5 seconds */
639
640 if (ret) {

--- 29 unchanged lines hidden (view full) ---

670
671 vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
672
673 vstor_packet->u.vm_srb.length =
674 sizeof(struct vmscsi_req) - vmscsi_size_delta;
675
676 vstor_packet->u.vm_srb.sense_info_len = sense_buffer_size;
677
640
641 if (ret != 0) {
642 goto cleanup;
643 }
644
645 ret = sema_timedwait(&request->synch_sema, 5 * hz); /* KYS 5 seconds */
646
647 if (ret) {

--- 29 unchanged lines hidden (view full) ---

677
678 vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
679
680 vstor_packet->u.vm_srb.length =
681 sizeof(struct vmscsi_req) - vmscsi_size_delta;
682
683 vstor_packet->u.vm_srb.sense_info_len = sense_buffer_size;
684
678 vstor_packet->u.vm_srb.transfer_len = request->data_buf.length;
685 vstor_packet->u.vm_srb.transfer_len =
686 request->prp_list.gpa_range.gpa_len;
679
680 vstor_packet->operation = VSTOR_OPERATION_EXECUTESRB;
681
682 outgoing_channel = vmbus_select_outgoing_channel(sc->hs_chan);
683
684 mtx_unlock(&request->softc->hs_lock);
687
688 vstor_packet->operation = VSTOR_OPERATION_EXECUTESRB;
689
690 outgoing_channel = vmbus_select_outgoing_channel(sc->hs_chan);
691
692 mtx_unlock(&request->softc->hs_lock);
685 if (request->data_buf.length) {
686 ret = hv_vmbus_channel_send_packet_multipagebuffer(
687 outgoing_channel,
688 &request->data_buf,
689 vstor_packet,
690 VSTOR_PKT_SIZE,
691 (uint64_t)(uintptr_t)request);
692
693 if (request->prp_list.gpa_range.gpa_len) {
694 ret = vmbus_chan_send_prplist(outgoing_channel,
695 &request->prp_list.gpa_range, request->prp_cnt,
696 vstor_packet, VSTOR_PKT_SIZE, (uint64_t)(uintptr_t)request);
693 } else {
694 ret = hv_vmbus_channel_send_packet(
695 outgoing_channel,
696 vstor_packet,
697 VSTOR_PKT_SIZE,
698 (uint64_t)(uintptr_t)request,
697 } else {
698 ret = hv_vmbus_channel_send_packet(
699 outgoing_channel,
700 vstor_packet,
701 VSTOR_PKT_SIZE,
702 (uint64_t)(uintptr_t)request,
699 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
700 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
703 VMBUS_CHANPKT_TYPE_INBAND,
704 VMBUS_CHANPKT_FLAG_RC);
701 }
702 mtx_lock(&request->softc->hs_lock);
703
704 if (ret != 0) {
705 printf("Unable to send packet %p ret %d", vstor_packet, ret);
706 } else {
707 atomic_add_int(&sc->hs_num_out_reqs, 1);
708 }

--- 242 unchanged lines hidden (view full) ---

951 /* create sg-list page pool */
952 if (FALSE == g_hv_sgl_page_pool.is_init) {
953 g_hv_sgl_page_pool.is_init = TRUE;
954 LIST_INIT(&g_hv_sgl_page_pool.in_use_sgl_list);
955 LIST_INIT(&g_hv_sgl_page_pool.free_sgl_list);
956
957 /*
958 * Pre-create SG list, each SG list with
705 }
706 mtx_lock(&request->softc->hs_lock);
707
708 if (ret != 0) {
709 printf("Unable to send packet %p ret %d", vstor_packet, ret);
710 } else {
711 atomic_add_int(&sc->hs_num_out_reqs, 1);
712 }

--- 242 unchanged lines hidden (view full) ---

955 /* create sg-list page pool */
956 if (FALSE == g_hv_sgl_page_pool.is_init) {
957 g_hv_sgl_page_pool.is_init = TRUE;
958 LIST_INIT(&g_hv_sgl_page_pool.in_use_sgl_list);
959 LIST_INIT(&g_hv_sgl_page_pool.free_sgl_list);
960
961 /*
962 * Pre-create SG list, each SG list with
959 * HV_MAX_MULTIPAGE_BUFFER_COUNT segments, each
963 * VMBUS_CHAN_PRPLIST_MAX segments, each
960 * segment has one page buffer
961 */
962 for (i = 0; i < STORVSC_MAX_IO_REQUESTS; i++) {
963 sgl_node = malloc(sizeof(struct hv_sgl_node),
964 M_DEVBUF, M_WAITOK|M_ZERO);
965
966 sgl_node->sgl_data =
964 * segment has one page buffer
965 */
966 for (i = 0; i < STORVSC_MAX_IO_REQUESTS; i++) {
967 sgl_node = malloc(sizeof(struct hv_sgl_node),
968 M_DEVBUF, M_WAITOK|M_ZERO);
969
970 sgl_node->sgl_data =
967 sglist_alloc(HV_MAX_MULTIPAGE_BUFFER_COUNT,
971 sglist_alloc(VMBUS_CHAN_PRPLIST_MAX,
968 M_WAITOK|M_ZERO);
969
972 M_WAITOK|M_ZERO);
973
970 for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++) {
974 for (j = 0; j < VMBUS_CHAN_PRPLIST_MAX; j++) {
971 tmp_buff = malloc(PAGE_SIZE,
972 M_DEVBUF, M_WAITOK|M_ZERO);
973
974 sgl_node->sgl_data->sg_segs[j].ss_paddr =
975 (vm_paddr_t)tmp_buff;
976 }
977
978 LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list,

--- 70 unchanged lines hidden (view full) ---

1049 reqp = LIST_FIRST(&sc->hs_free_list);
1050 LIST_REMOVE(reqp, link);
1051 free(reqp, M_DEVBUF);
1052 }
1053
1054 while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) {
1055 sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
1056 LIST_REMOVE(sgl_node, link);
975 tmp_buff = malloc(PAGE_SIZE,
976 M_DEVBUF, M_WAITOK|M_ZERO);
977
978 sgl_node->sgl_data->sg_segs[j].ss_paddr =
979 (vm_paddr_t)tmp_buff;
980 }
981
982 LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list,

--- 70 unchanged lines hidden (view full) ---

1053 reqp = LIST_FIRST(&sc->hs_free_list);
1054 LIST_REMOVE(reqp, link);
1055 free(reqp, M_DEVBUF);
1056 }
1057
1058 while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) {
1059 sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
1060 LIST_REMOVE(sgl_node, link);
1057 for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++) {
1061 for (j = 0; j < VMBUS_CHAN_PRPLIST_MAX; j++) {
1058 if (NULL !=
1059 (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) {
1060 free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF);
1061 }
1062 }
1063 sglist_free(sgl_node->sgl_data);
1064 free(sgl_node, M_DEVBUF);
1065 }

--- 46 unchanged lines hidden (view full) ---

1112
1113 free(reqp, M_DEVBUF);
1114 }
1115 mtx_unlock(&sc->hs_lock);
1116
1117 while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) {
1118 sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
1119 LIST_REMOVE(sgl_node, link);
1062 if (NULL !=
1063 (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) {
1064 free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF);
1065 }
1066 }
1067 sglist_free(sgl_node->sgl_data);
1068 free(sgl_node, M_DEVBUF);
1069 }

--- 46 unchanged lines hidden (view full) ---

1116
1117 free(reqp, M_DEVBUF);
1118 }
1119 mtx_unlock(&sc->hs_lock);
1120
1121 while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) {
1122 sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
1123 LIST_REMOVE(sgl_node, link);
1120 for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++){
1124 for (j = 0; j < VMBUS_CHAN_PRPLIST_MAX; j++){
1121 if (NULL !=
1122 (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) {
1123 free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF);
1124 }
1125 }
1126 sglist_free(sgl_node->sgl_data);
1127 free(sgl_node, M_DEVBUF);
1128 }

--- 534 unchanged lines hidden (view full) ---

1663create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp)
1664{
1665 struct ccb_scsiio *csio = &ccb->csio;
1666 uint64_t phys_addr;
1667 uint32_t bytes_to_copy = 0;
1668 uint32_t pfn_num = 0;
1669 uint32_t pfn;
1670 uint64_t not_aligned_seg_bits = 0;
1125 if (NULL !=
1126 (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) {
1127 free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF);
1128 }
1129 }
1130 sglist_free(sgl_node->sgl_data);
1131 free(sgl_node, M_DEVBUF);
1132 }

--- 534 unchanged lines hidden (view full) ---

1667create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp)
1668{
1669 struct ccb_scsiio *csio = &ccb->csio;
1670 uint64_t phys_addr;
1671 uint32_t bytes_to_copy = 0;
1672 uint32_t pfn_num = 0;
1673 uint32_t pfn;
1674 uint64_t not_aligned_seg_bits = 0;
1675 struct hvs_gpa_range *prplist;
1671
1672 /* refer to struct vmscsi_req for meanings of these two fields */
1673 reqp->vstor_packet.u.vm_srb.port =
1674 cam_sim_unit(xpt_path_sim(ccb->ccb_h.path));
1675 reqp->vstor_packet.u.vm_srb.path_id =
1676 cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
1677
1678 reqp->vstor_packet.u.vm_srb.target_id = ccb->ccb_h.target_id;

--- 27 unchanged lines hidden (view full) ---

1706 reqp->sense_info_len = csio->sense_len;
1707
1708 reqp->ccb = ccb;
1709
1710 if (0 == csio->dxfer_len) {
1711 return (0);
1712 }
1713
1676
1677 /* refer to struct vmscsi_req for meanings of these two fields */
1678 reqp->vstor_packet.u.vm_srb.port =
1679 cam_sim_unit(xpt_path_sim(ccb->ccb_h.path));
1680 reqp->vstor_packet.u.vm_srb.path_id =
1681 cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
1682
1683 reqp->vstor_packet.u.vm_srb.target_id = ccb->ccb_h.target_id;

--- 27 unchanged lines hidden (view full) ---

1711 reqp->sense_info_len = csio->sense_len;
1712
1713 reqp->ccb = ccb;
1714
1715 if (0 == csio->dxfer_len) {
1716 return (0);
1717 }
1718
1714 reqp->data_buf.length = csio->dxfer_len;
1719 prplist = &reqp->prp_list;
1720 prplist->gpa_range.gpa_len = csio->dxfer_len;
1715
1716 switch (ccb->ccb_h.flags & CAM_DATA_MASK) {
1717 case CAM_DATA_VADDR:
1718 {
1719 bytes_to_copy = csio->dxfer_len;
1720 phys_addr = vtophys(csio->data_ptr);
1721
1722 switch (ccb->ccb_h.flags & CAM_DATA_MASK) {
1723 case CAM_DATA_VADDR:
1724 {
1725 bytes_to_copy = csio->dxfer_len;
1726 phys_addr = vtophys(csio->data_ptr);
1721 reqp->data_buf.offset = phys_addr & PAGE_MASK;
1727 prplist->gpa_range.gpa_ofs = phys_addr & PAGE_MASK;
1722
1723 while (bytes_to_copy != 0) {
1724 int bytes, page_offset;
1725 phys_addr =
1728
1729 while (bytes_to_copy != 0) {
1730 int bytes, page_offset;
1731 phys_addr =
1726 vtophys(&csio->data_ptr[reqp->data_buf.length -
1732 vtophys(&csio->data_ptr[prplist->gpa_range.gpa_len -
1727 bytes_to_copy]);
1728 pfn = phys_addr >> PAGE_SHIFT;
1733 bytes_to_copy]);
1734 pfn = phys_addr >> PAGE_SHIFT;
1729 reqp->data_buf.pfn_array[pfn_num] = pfn;
1735 prplist->gpa_page[pfn_num] = pfn;
1730 page_offset = phys_addr & PAGE_MASK;
1731
1732 bytes = min(PAGE_SIZE - page_offset, bytes_to_copy);
1733
1734 bytes_to_copy -= bytes;
1735 pfn_num++;
1736 }
1736 page_offset = phys_addr & PAGE_MASK;
1737
1738 bytes = min(PAGE_SIZE - page_offset, bytes_to_copy);
1739
1740 bytes_to_copy -= bytes;
1741 pfn_num++;
1742 }
1743 reqp->prp_cnt = pfn_num;
1737 break;
1738 }
1739
1740 case CAM_DATA_SG:
1741 {
1742 int i = 0;
1743 int offset = 0;
1744 int ret;
1745
1746 bus_dma_segment_t *storvsc_sglist =
1747 (bus_dma_segment_t *)ccb->csio.data_ptr;
1748 u_int16_t storvsc_sg_count = ccb->csio.sglist_cnt;
1749
1750 printf("Storvsc: get SG I/O operation, %d\n",
1751 reqp->vstor_packet.u.vm_srb.data_in);
1752
1744 break;
1745 }
1746
1747 case CAM_DATA_SG:
1748 {
1749 int i = 0;
1750 int offset = 0;
1751 int ret;
1752
1753 bus_dma_segment_t *storvsc_sglist =
1754 (bus_dma_segment_t *)ccb->csio.data_ptr;
1755 u_int16_t storvsc_sg_count = ccb->csio.sglist_cnt;
1756
1757 printf("Storvsc: get SG I/O operation, %d\n",
1758 reqp->vstor_packet.u.vm_srb.data_in);
1759
1753 if (storvsc_sg_count > HV_MAX_MULTIPAGE_BUFFER_COUNT){
1760 if (storvsc_sg_count > VMBUS_CHAN_PRPLIST_MAX){
1754 printf("Storvsc: %d segments is too much, "
1755 "only support %d segments\n",
1761 printf("Storvsc: %d segments is too much, "
1762 "only support %d segments\n",
1756 storvsc_sg_count, HV_MAX_MULTIPAGE_BUFFER_COUNT);
1763 storvsc_sg_count, VMBUS_CHAN_PRPLIST_MAX);
1757 return (EINVAL);
1758 }
1759
1760 /*
1761 * We create our own bounce buffer function currently. Idealy
1762 * we should use BUS_DMA(9) framework. But with current BUS_DMA
1763 * code there is no callback API to check the page alignment of
1764 * middle segments before busdma can decide if a bounce buffer

--- 36 unchanged lines hidden (view full) ---

1801 /* transfer virtual address to physical frame number */
1802 if (reqp->not_aligned_seg_bits & 0x1){
1803 phys_addr =
1804 vtophys(reqp->bounce_sgl->sg_segs[0].ss_paddr);
1805 }else{
1806 phys_addr =
1807 vtophys(storvsc_sglist[0].ds_addr);
1808 }
1764 return (EINVAL);
1765 }
1766
1767 /*
1768 * We create our own bounce buffer function currently. Idealy
1769 * we should use BUS_DMA(9) framework. But with current BUS_DMA
1770 * code there is no callback API to check the page alignment of
1771 * middle segments before busdma can decide if a bounce buffer

--- 36 unchanged lines hidden (view full) ---

1808 /* transfer virtual address to physical frame number */
1809 if (reqp->not_aligned_seg_bits & 0x1){
1810 phys_addr =
1811 vtophys(reqp->bounce_sgl->sg_segs[0].ss_paddr);
1812 }else{
1813 phys_addr =
1814 vtophys(storvsc_sglist[0].ds_addr);
1815 }
1809 reqp->data_buf.offset = phys_addr & PAGE_MASK;
1816 prplist->gpa_range.gpa_ofs = phys_addr & PAGE_MASK;
1810
1811 pfn = phys_addr >> PAGE_SHIFT;
1817
1818 pfn = phys_addr >> PAGE_SHIFT;
1812 reqp->data_buf.pfn_array[0] = pfn;
1819 prplist->gpa_page[0] = pfn;
1813
1814 for (i = 1; i < storvsc_sg_count; i++) {
1815 if (reqp->not_aligned_seg_bits & (1 << i)) {
1816 phys_addr =
1817 vtophys(reqp->bounce_sgl->sg_segs[i].ss_paddr);
1818 } else {
1819 phys_addr =
1820 vtophys(storvsc_sglist[i].ds_addr);
1821 }
1822
1823 pfn = phys_addr >> PAGE_SHIFT;
1820
1821 for (i = 1; i < storvsc_sg_count; i++) {
1822 if (reqp->not_aligned_seg_bits & (1 << i)) {
1823 phys_addr =
1824 vtophys(reqp->bounce_sgl->sg_segs[i].ss_paddr);
1825 } else {
1826 phys_addr =
1827 vtophys(storvsc_sglist[i].ds_addr);
1828 }
1829
1830 pfn = phys_addr >> PAGE_SHIFT;
1824 reqp->data_buf.pfn_array[i] = pfn;
1831 prplist->gpa_page[i] = pfn;
1825 }
1832 }
1833 reqp->prp_cnt = i;
1826 } else {
1827 phys_addr = vtophys(storvsc_sglist[0].ds_addr);
1828
1834 } else {
1835 phys_addr = vtophys(storvsc_sglist[0].ds_addr);
1836
1829 reqp->data_buf.offset = phys_addr & PAGE_MASK;
1837 prplist->gpa_range.gpa_ofs = phys_addr & PAGE_MASK;
1830
1831 for (i = 0; i < storvsc_sg_count; i++) {
1832 phys_addr = vtophys(storvsc_sglist[i].ds_addr);
1833 pfn = phys_addr >> PAGE_SHIFT;
1838
1839 for (i = 0; i < storvsc_sg_count; i++) {
1840 phys_addr = vtophys(storvsc_sglist[i].ds_addr);
1841 pfn = phys_addr >> PAGE_SHIFT;
1834 reqp->data_buf.pfn_array[i] = pfn;
1842 prplist->gpa_page[i] = pfn;
1835 }
1843 }
1844 reqp->prp_cnt = i;
1836
1837 /* check the last segment cross boundary or not */
1838 offset = phys_addr & PAGE_MASK;
1839 if (offset) {
1845
1846 /* check the last segment cross boundary or not */
1847 offset = phys_addr & PAGE_MASK;
1848 if (offset) {
1849 /* Add one more PRP entry */
1840 phys_addr =
1841 vtophys(storvsc_sglist[i-1].ds_addr +
1842 PAGE_SIZE - offset);
1843 pfn = phys_addr >> PAGE_SHIFT;
1850 phys_addr =
1851 vtophys(storvsc_sglist[i-1].ds_addr +
1852 PAGE_SIZE - offset);
1853 pfn = phys_addr >> PAGE_SHIFT;
1844 reqp->data_buf.pfn_array[i] = pfn;
1854 prplist->gpa_page[i] = pfn;
1855 reqp->prp_cnt++;
1845 }
1846
1847 reqp->bounce_sgl_count = 0;
1848 }
1849 break;
1850 }
1851 default:
1852 printf("Unknow flags: %d\n", ccb->ccb_h.flags);

--- 210 unchanged lines hidden ---
1856 }
1857
1858 reqp->bounce_sgl_count = 0;
1859 }
1860 break;
1861 }
1862 default:
1863 printf("Unknow flags: %d\n", ccb->ccb_h.flags);

--- 210 unchanged lines hidden ---