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 --- |