View | Details | Raw Unified | Return to bug 196185 | Differences between
and this patch

Collapse All | Expand All

(-)src/contrib/hv_kvp_daemon/hv_kvp_daemon.c (-1 / +1 lines)
Lines 285-291 kvp_file_init(void) Link Here
285
	int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
285
	int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
286
286
287
	if (mkdir("/var/db/hyperv/pool", S_IRUSR | S_IWUSR | S_IROTH) < 0 &&
287
	if (mkdir("/var/db/hyperv/pool", S_IRUSR | S_IWUSR | S_IROTH) < 0 &&
288
	    errno != EISDIR) {
288
	    errno != EEXIST) {
289
		KVP_LOG(LOG_ERR, " Failed to create /var/db/hyperv/pool\n");
289
		KVP_LOG(LOG_ERR, " Failed to create /var/db/hyperv/pool\n");
290
		exit(EXIT_FAILURE);
290
		exit(EXIT_FAILURE);
291
	}
291
	}
(-)src/sys/dev/hyperv/netvsc/hv_net_vsc.c (-1 / +2 lines)
Lines 39-49 Link Here
39
#include <sys/socket.h>
39
#include <sys/socket.h>
40
#include <sys/lock.h>
40
#include <sys/lock.h>
41
#include <net/if.h>
41
#include <net/if.h>
42
#include <net/if_var.h>
42
#include <net/if_arp.h>
43
#include <net/if_arp.h>
43
#include <machine/bus.h>
44
#include <machine/bus.h>
44
#include <machine/atomic.h>
45
#include <machine/atomic.h>
45
46
46
#include <dev/hyperv/include/hyperv.h>
47
#include <hyperv.h>
47
#include "hv_net_vsc.h"
48
#include "hv_net_vsc.h"
48
#include "hv_rndis.h"
49
#include "hv_rndis.h"
49
#include "hv_rndis_filter.h"
50
#include "hv_rndis_filter.h"
(-)src/sys/dev/hyperv/netvsc/hv_net_vsc.h (-1 / +1 lines)
Lines 43-49 Link Here
43
#include <sys/lock.h>
43
#include <sys/lock.h>
44
#include <sys/sx.h>
44
#include <sys/sx.h>
45
45
46
#include <dev/hyperv/include/hyperv.h>
46
#include <hyperv.h>
47
47
48
48
49
#define NVSP_INVALID_PROTOCOL_VERSION           (0xFFFFFFFF)
49
#define NVSP_INVALID_PROTOCOL_VERSION           (0xFFFFFFFF)
(-)src/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c (-1 / +1 lines)
Lines 103-109 __FBSDID("$FreeBSD: releng/10.1/sys/dev/ Link Here
103
103
104
#include <machine/intr_machdep.h>
104
#include <machine/intr_machdep.h>
105
105
106
#include <dev/hyperv/include/hyperv.h>
106
#include <hyperv.h>
107
#include "hv_net_vsc.h"
107
#include "hv_net_vsc.h"
108
#include "hv_rndis.h"
108
#include "hv_rndis.h"
109
#include "hv_rndis_filter.h"
109
#include "hv_rndis_filter.h"
(-)src/sys/dev/hyperv/netvsc/hv_rndis_filter.c (-1 / +1 lines)
Lines 43-49 __FBSDID("$FreeBSD: releng/10.1/sys/dev/ Link Here
43
#include <vm/vm_param.h>
43
#include <vm/vm_param.h>
44
#include <vm/pmap.h>
44
#include <vm/pmap.h>
45
45
46
#include <dev/hyperv/include/hyperv.h>
46
#include <hyperv.h>
47
#include "hv_net_vsc.h"
47
#include "hv_net_vsc.h"
48
#include "hv_rndis.h"
48
#include "hv_rndis.h"
49
#include "hv_rndis_filter.h"
49
#include "hv_rndis_filter.h"
(-)src/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c (-73 / +532 lines)
Lines 53-60 __FBSDID("$FreeBSD: releng/10.1/sys/dev/ Link Here
53
#include <sys/callout.h>
53
#include <sys/callout.h>
54
#include <vm/vm.h>
54
#include <vm/vm.h>
55
#include <vm/pmap.h>
55
#include <vm/pmap.h>
56
#include <vm/uma.h>
56
#include <sys/lock.h>
57
#include <sys/lock.h>
57
#include <sys/sema.h>
58
#include <sys/sema.h>
59
#include <sys/sglist.h>
60
#include <machine/bus.h>
61
#include <sys/bus_dma.h>
58
62
59
#include <cam/cam.h>
63
#include <cam/cam.h>
60
#include <cam/cam_ccb.h>
64
#include <cam/cam_ccb.h>
Lines 67-75 __FBSDID("$FreeBSD: releng/10.1/sys/dev/ Link Here
67
#include <cam/scsi/scsi_message.h>
71
#include <cam/scsi/scsi_message.h>
68
72
69
73
70
#include <dev/hyperv/include/hyperv.h>
74
#include <hyperv.h>
71
#include "hv_vstorage.h"
75
#include "hv_vstorage.h"
72
76
77
#include <sys/time.h>
78
73
#define STORVSC_RINGBUFFER_SIZE		(20*PAGE_SIZE)
79
#define STORVSC_RINGBUFFER_SIZE		(20*PAGE_SIZE)
74
#define STORVSC_MAX_LUNS_PER_TARGET	(64)
80
#define STORVSC_MAX_LUNS_PER_TARGET	(64)
75
#define STORVSC_MAX_IO_REQUESTS		(STORVSC_MAX_LUNS_PER_TARGET * 2)
81
#define STORVSC_MAX_IO_REQUESTS		(STORVSC_MAX_LUNS_PER_TARGET * 2)
Lines 77-84 __FBSDID("$FreeBSD: releng/10.1/sys/dev/ Link Here
77
#define BLKVSC_MAX_IO_REQUESTS		STORVSC_MAX_IO_REQUESTS
83
#define BLKVSC_MAX_IO_REQUESTS		STORVSC_MAX_IO_REQUESTS
78
#define STORVSC_MAX_TARGETS		(2)
84
#define STORVSC_MAX_TARGETS		(2)
79
85
86
#define STORVSC_WIN7_MAJOR 4
87
#define STORVSC_WIN7_MINOR 2
88
89
#define STORVSC_WIN8_MAJOR 5
90
#define STORVSC_WIN8_MINOR 1
91
92
#define HV_ALIGN(x, a)	(((x) + ((a) - 1)) & ~((a) - 1))
93
80
struct storvsc_softc;
94
struct storvsc_softc;
81
95
96
struct hv_sgl_node {
97
	LIST_ENTRY(hv_sgl_node) link;
98
	struct sglist *sgl_data;
99
};
100
101
struct hv_sgl_page_pool{
102
	LIST_HEAD(, hv_sgl_node) in_use_sgl_list;
103
	LIST_HEAD(, hv_sgl_node) free_sgl_list;
104
	boolean_t                is_init;
105
} g_hv_sgl_page_pool;
106
107
#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * HV_MAX_MULTIPAGE_BUFFER_COUNT
108
82
enum storvsc_request_type {
109
enum storvsc_request_type {
83
	WRITE_TYPE,
110
	WRITE_TYPE,
84
	READ_TYPE,
111
	READ_TYPE,
Lines 96-112 struct hv_storvsc_request { Link Here
96
	struct storvsc_softc *softc;
123
	struct storvsc_softc *softc;
97
	struct callout callout;
124
	struct callout callout;
98
	struct sema synch_sema; /*Synchronize the request/response if needed */
125
	struct sema synch_sema; /*Synchronize the request/response if needed */
126
	struct sglist *bounce_sgl;
127
	unsigned int bounce_sgl_count;
128
	uint64_t not_aligned_seg_bits;
99
};
129
};
100
130
101
struct storvsc_softc {
131
struct storvsc_softc {
102
	struct hv_device		*hs_dev;
132
	struct hv_device		*hs_dev;
103
        LIST_HEAD(, hv_storvsc_request) hs_free_list;
133
	LIST_HEAD(, hv_storvsc_request) hs_free_list;
104
        struct mtx      		hs_lock;
134
	struct mtx      		hs_lock;
105
        struct storvsc_driver_props     *hs_drv_props;
135
	struct storvsc_driver_props     *hs_drv_props;
106
        int 				hs_unit;
136
	int 				hs_unit;
107
        uint32_t         		hs_frozen;
137
	uint32_t         		hs_frozen;
108
        struct cam_sim  		*hs_sim;
138
	struct cam_sim  		*hs_sim;
109
        struct cam_path 		*hs_path;
139
	struct cam_path 		*hs_path;
110
	uint32_t			hs_num_out_reqs;
140
	uint32_t			hs_num_out_reqs;
111
	boolean_t			hs_destroy;
141
	boolean_t			hs_destroy;
112
	boolean_t			hs_drain_notify;
142
	boolean_t			hs_drain_notify;
Lines 124-130 struct storvsc_softc { Link Here
124
 * The first can be tested by "sg_senddiag -vv /dev/daX",
154
 * The first can be tested by "sg_senddiag -vv /dev/daX",
125
 * and the second and third can be done by
155
 * and the second and third can be done by
126
 * "sg_wr_mode -v -p 08 -c 0,1a -m 0,ff /dev/daX".
156
 * "sg_wr_mode -v -p 08 -c 0,1a -m 0,ff /dev/daX".
127
 */ 
157
 */
128
#define HVS_TIMEOUT_TEST 0
158
#define HVS_TIMEOUT_TEST 0
129
159
130
/*
160
/*
Lines 138-144 struct storvsc_driver_props { Link Here
138
	char		*drv_name;
168
	char		*drv_name;
139
	char		*drv_desc;
169
	char		*drv_desc;
140
	uint8_t		drv_max_luns_per_target;
170
	uint8_t		drv_max_luns_per_target;
141
	uint8_t		drv_max_ios_per_target; 
171
	uint8_t		drv_max_ios_per_target;
142
	uint32_t	drv_ringbuffer_size;
172
	uint32_t	drv_ringbuffer_size;
143
};
173
};
144
174
Lines 171-183 static struct storvsc_driver_props g_drv Link Here
171
	 STORVSC_RINGBUFFER_SIZE}
201
	 STORVSC_RINGBUFFER_SIZE}
172
};
202
};
173
203
204
static int storvsc_current_major;
205
static int storvsc_current_minor;
206
174
/* static functions */
207
/* static functions */
175
static int storvsc_probe(device_t dev);
208
static int storvsc_probe(device_t dev);
176
static int storvsc_attach(device_t dev);
209
static int storvsc_attach(device_t dev);
177
static int storvsc_detach(device_t dev);
210
static int storvsc_detach(device_t dev);
178
static void storvsc_poll(struct cam_sim * sim);
211
static void storvsc_poll(struct cam_sim * sim);
179
static void storvsc_action(struct cam_sim * sim, union ccb * ccb);
212
static void storvsc_action(struct cam_sim * sim, union ccb * ccb);
180
static void create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp);
213
static int create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp);
181
static void storvsc_free_request(struct storvsc_softc *sc, struct hv_storvsc_request *reqp);
214
static void storvsc_free_request(struct storvsc_softc *sc, struct hv_storvsc_request *reqp);
182
static enum hv_storage_type storvsc_get_storage_type(device_t dev);
215
static enum hv_storage_type storvsc_get_storage_type(device_t dev);
183
static void hv_storvsc_on_channel_callback(void *context);
216
static void hv_storvsc_on_channel_callback(void *context);
Lines 186-191 static void hv_storvsc_on_iocompletion( Link Here
186
					struct hv_storvsc_request *request);
219
					struct hv_storvsc_request *request);
187
static int hv_storvsc_connect_vsp(struct hv_device *device);
220
static int hv_storvsc_connect_vsp(struct hv_device *device);
188
static void storvsc_io_done(struct hv_storvsc_request *reqp);
221
static void storvsc_io_done(struct hv_storvsc_request *reqp);
222
void storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl,
223
				bus_dma_segment_t *orig_sgl,
224
				unsigned int orig_sgl_count,
225
				uint64_t seg_bits);
226
void storvsc_copy_from_bounce_buf_to_sgl(bus_dma_segment_t *dest_sgl,
227
	                unsigned int dest_sgl_count,
228
				    struct sglist* src_sgl,
229
				    uint64_t seg_bits);
189
230
190
static device_method_t storvsc_methods[] = {
231
static device_method_t storvsc_methods[] = {
191
	/* Device interface */
232
	/* Device interface */
Lines 197-213 static device_method_t storvsc_methods[] Link Here
197
};
238
};
198
239
199
static driver_t storvsc_driver = {
240
static driver_t storvsc_driver = {
200
	"storvsc", storvsc_methods, sizeof(struct storvsc_softc),
241
	"storvsc-port", storvsc_methods, sizeof(struct storvsc_softc),
201
};
242
};
202
243
203
static devclass_t storvsc_devclass;
244
static devclass_t storvsc_devclass;
204
DRIVER_MODULE(storvsc, vmbus, storvsc_driver, storvsc_devclass, 0, 0);
245
DRIVER_MODULE(storvsc_port, vmbus, storvsc_driver, storvsc_devclass, 0, 0);
205
MODULE_VERSION(storvsc, 1);
246
MODULE_VERSION(storvsc_port, 1);
206
MODULE_DEPEND(storvsc, vmbus, 1, 1, 1);
247
MODULE_DEPEND(storvsc_port, vmbus, 1, 1, 1);
207
248
208
249
209
/**
250
/**
210
 * The host is capable of sending messages to us that are 
251
 * The host is capable of sending messages to us that are
211
 * completely unsolicited. So, we need to address the race
252
 * completely unsolicited. So, we need to address the race
212
 * condition where we may be in the process of unloading the
253
 * condition where we may be in the process of unloading the
213
 * driver when the host may send us an unsolicited message.
254
 * driver when the host may send us an unsolicited message.
Lines 223-229 MODULE_DEPEND(storvsc, vmbus, 1, 1, 1); Link Here
223
 *    destroyed.
264
 *    destroyed.
224
 *
265
 *
225
 * 3. Once the device is marked as being destroyed, we only
266
 * 3. Once the device is marked as being destroyed, we only
226
 *    permit incoming traffic to properly account for 
267
 *    permit incoming traffic to properly account for
227
 *    packets already sent out.
268
 *    packets already sent out.
228
 */
269
 */
229
static inline struct storvsc_softc *
270
static inline struct storvsc_softc *
Lines 304-310 hv_storvsc_channel_init(struct hv_device Link Here
304
		goto cleanup;
345
		goto cleanup;
305
	}
346
	}
306
347
307
	ret = sema_timedwait(&request->synch_sema, 500); /* KYS 5 seconds */
348
	/* wait 500 ticks */
349
	ret = sema_timedwait(&request->synch_sema, 500);
308
350
309
	if (ret != 0) {
351
	if (ret != 0) {
310
		goto cleanup;
352
		goto cleanup;
Lines 321-327 hv_storvsc_channel_init(struct hv_device Link Here
321
	vstor_packet->operation = VSTOR_OPERATION_QUERYPROTOCOLVERSION;
363
	vstor_packet->operation = VSTOR_OPERATION_QUERYPROTOCOLVERSION;
322
	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
364
	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
323
365
324
	vstor_packet->u.version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT;
366
	vstor_packet->u.version.major_minor =
367
	    VMSTOR_PROTOCOL_VERSION(storvsc_current_major, storvsc_current_minor);
325
368
326
	/* revision is only significant for Windows guests */
369
	/* revision is only significant for Windows guests */
327
	vstor_packet->u.version.revision = 0;
370
	vstor_packet->u.version.revision = 0;
Lines 338-344 hv_storvsc_channel_init(struct hv_device Link Here
338
		goto cleanup;
381
		goto cleanup;
339
	}
382
	}
340
383
341
	ret = sema_timedwait(&request->synch_sema, 500); /* KYS 5 seconds */
384
	/* wait 500 ticks */
385
	ret = sema_timedwait(&request->synch_sema, 500);
342
386
343
	if (ret) {
387
	if (ret) {
344
		goto cleanup;
388
		goto cleanup;
Lines 369-375 hv_storvsc_channel_init(struct hv_device Link Here
369
		goto cleanup;
413
		goto cleanup;
370
	}
414
	}
371
415
372
	ret = sema_timedwait(&request->synch_sema, 500); /* KYS 5 seconds */
416
	/* wait 500 ticks */
417
	ret = sema_timedwait(&request->synch_sema, 500);
373
418
374
	if (ret != 0) {
419
	if (ret != 0) {
375
		goto cleanup;
420
		goto cleanup;
Lines 377-383 hv_storvsc_channel_init(struct hv_device Link Here
377
422
378
	/* TODO: Check returned version */
423
	/* TODO: Check returned version */
379
	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
424
	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
380
		vstor_packet->status != 0) {
425
	    vstor_packet->status != 0) {
381
		goto cleanup;
426
		goto cleanup;
382
	}
427
	}
383
428
Lines 397-410 hv_storvsc_channel_init(struct hv_device Link Here
397
		goto cleanup;
442
		goto cleanup;
398
	}
443
	}
399
444
400
	ret = sema_timedwait(&request->synch_sema, 500); /* KYS 5 seconds */
445
	/* wait 500 ticks */
446
	ret = sema_timedwait(&request->synch_sema, 500);
401
447
402
	if (ret != 0) {
448
	if (ret != 0) {
403
		goto cleanup;
449
		goto cleanup;
404
	}
450
	}
405
451
406
	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
452
	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
407
		vstor_packet->status != 0) {
453
	    vstor_packet->status != 0) {
408
		goto cleanup;
454
		goto cleanup;
409
	}
455
	}
410
456
Lines 445-451 hv_storvsc_connect_vsp(struct hv_device Link Here
445
		hv_storvsc_on_channel_callback,
491
		hv_storvsc_on_channel_callback,
446
		dev);
492
		dev);
447
493
448
449
	if (ret != 0) {
494
	if (ret != 0) {
450
		return ret;
495
		return ret;
451
	}
496
	}
Lines 498-504 hv_storvsc_host_reset(struct hv_device * Link Here
498
543
499
544
500
	/*
545
	/*
501
	 * At this point, all outstanding requests in the adapter 
546
	 * At this point, all outstanding requests in the adapter
502
	 * should have been flushed out and return to us
547
	 * should have been flushed out and return to us
503
	 */
548
	 */
504
549
Lines 545-552 hv_storvsc_io_request(struct hv_device * Link Here
545
		ret = hv_vmbus_channel_send_packet_multipagebuffer(
590
		ret = hv_vmbus_channel_send_packet_multipagebuffer(
546
				device->channel,
591
				device->channel,
547
				&request->data_buf,
592
				&request->data_buf,
548
				vstor_packet, 
593
				vstor_packet,
549
				sizeof(struct vstor_packet), 
594
				sizeof(struct vstor_packet),
550
				(uint64_t)(uintptr_t)request);
595
				(uint64_t)(uintptr_t)request);
551
596
552
	} else {
597
	} else {
Lines 620-630 hv_storvsc_on_channel_callback(void *con Link Here
620
665
621
	sc = get_stor_device(device, FALSE);
666
	sc = get_stor_device(device, FALSE);
622
	if (sc == NULL) {
667
	if (sc == NULL) {
668
		printf("Storvsc_error: get stor device failed.\n");
623
		return;
669
		return;
624
	}
670
	}
625
671
626
	KASSERT(device, ("device"));
627
628
	ret = hv_vmbus_channel_recv_packet(
672
	ret = hv_vmbus_channel_recv_packet(
629
			device->channel,
673
			device->channel,
630
			packet,
674
			packet,
Lines 634-646 hv_storvsc_on_channel_callback(void *con Link Here
634
678
635
	while ((ret == 0) && (bytes_recvd > 0)) {
679
	while ((ret == 0) && (bytes_recvd > 0)) {
636
		request = (struct hv_storvsc_request *)(uintptr_t)request_id;
680
		request = (struct hv_storvsc_request *)(uintptr_t)request_id;
637
		KASSERT(request, ("request"));
638
681
639
		if ((request == &sc->hs_init_req) ||
682
		if (request == NULL) {
683
			vstor_packet = (struct vstor_packet *)packet;
684
			printf("VMBUS: storvsc received a packet with an "
685
			    "invalid request id. Operation is %d.\n",
686
			    vstor_packet->operation);
687
			if (vstor_packet->operation ==
688
			    VSTOR_OPERATION_COMPLETEIO)
689
				KASSERT(request, ("request"));
690
		} else if ((request == &sc->hs_init_req) ||
640
			(request == &sc->hs_reset_req)) {
691
			(request == &sc->hs_reset_req)) {
641
			memcpy(&request->vstor_packet, packet,
692
			memcpy(&request->vstor_packet, packet,
642
				   sizeof(struct vstor_packet));
693
				   sizeof(struct vstor_packet));
643
			sema_post(&request->synch_sema); 
694
			sema_post(&request->synch_sema);
644
		} else {
695
		} else {
645
			vstor_packet = (struct vstor_packet *)packet;
696
			vstor_packet = (struct vstor_packet *)packet;
646
			switch(vstor_packet->operation) {
697
			switch(vstor_packet->operation) {
Lines 680-686 storvsc_probe(device_t dev) Link Here
680
{
731
{
681
	int ata_disk_enable = 0;
732
	int ata_disk_enable = 0;
682
	int ret	= ENXIO;
733
	int ret	= ENXIO;
683
734
	
735
		//storvsc_current_major = STORVSC_WIN8_MAJOR;
736
		//storvsc_current_minor = STORVSC_WIN8_MINOR;
737
		storvsc_current_major = STORVSC_WIN7_MAJOR;
738
		storvsc_current_minor = STORVSC_WIN7_MINOR;
739
	
684
	switch (storvsc_get_storage_type(dev)) {
740
	switch (storvsc_get_storage_type(dev)) {
685
	case DRIVER_BLKVSC:
741
	case DRIVER_BLKVSC:
686
		if(bootverbose)
742
		if(bootverbose)
Lines 689-702 storvsc_probe(device_t dev) Link Here
689
			if(bootverbose)
745
			if(bootverbose)
690
				device_printf(dev,
746
				device_printf(dev,
691
					"Enlightened ATA/IDE detected\n");
747
					"Enlightened ATA/IDE detected\n");
692
			ret = BUS_PROBE_DEFAULT;
748
			ret = BUS_PROBE_VENDOR;
693
		} else if(bootverbose)
749
		} else if(bootverbose)
694
			device_printf(dev, "Emulated ATA/IDE set (hw.ata.disk_enable set)\n");
750
			device_printf(dev, "Emulated ATA/IDE set (hw.ata.disk_enable set)\n");
695
		break;
751
		break;
696
	case DRIVER_STORVSC:
752
	case DRIVER_STORVSC:
697
		if(bootverbose)
753
		if(bootverbose)
698
			device_printf(dev, "Enlightened SCSI device detected\n");
754
			device_printf(dev, "Enlightened SCSI device detected\n");
699
		ret = BUS_PROBE_DEFAULT;
755
		ret = BUS_PROBE_VENDOR;
700
		break;
756
		break;
701
	default:
757
	default:
702
		ret = ENXIO;
758
		ret = ENXIO;
Lines 721-729 storvsc_attach(device_t dev) Link Here
721
	enum hv_storage_type stor_type;
777
	enum hv_storage_type stor_type;
722
	struct storvsc_softc *sc;
778
	struct storvsc_softc *sc;
723
	struct cam_devq *devq;
779
	struct cam_devq *devq;
724
	int ret, i;
780
	int ret, i, j;
725
	struct hv_storvsc_request *reqp;
781
	struct hv_storvsc_request *reqp;
726
	struct root_hold_token *root_mount_token = NULL;
782
	struct root_hold_token *root_mount_token = NULL;
783
	struct hv_sgl_node *sgl_node = NULL;
784
	void *tmp_buff = NULL;
727
785
728
	/*
786
	/*
729
	 * We need to serialize storvsc attach calls.
787
	 * We need to serialize storvsc attach calls.
Lines 764-769 storvsc_attach(device_t dev) Link Here
764
		LIST_INSERT_HEAD(&sc->hs_free_list, reqp, link);
822
		LIST_INSERT_HEAD(&sc->hs_free_list, reqp, link);
765
	}
823
	}
766
824
825
	/* create sg-list page pool */
826
	if (FALSE == g_hv_sgl_page_pool.is_init){
827
		g_hv_sgl_page_pool.is_init = TRUE;
828
		LIST_INIT(&g_hv_sgl_page_pool.in_use_sgl_list);
829
		LIST_INIT(&g_hv_sgl_page_pool.free_sgl_list);
830
831
	    /* pre-create SG list, each SG list with HV_MAX_MULTIPAGE_BUFFER_COUNT segments, each segment has one page buffer */
832
		for (i = 0; i < STORVSC_MAX_IO_REQUESTS; i++){
833
	        sgl_node = malloc(sizeof(struct hv_sgl_node),
834
				          M_DEVBUF, M_WAITOK|M_ZERO);
835
			if (NULL == sgl_node){
836
				ret = ENOMEM;
837
	            goto cleanup;
838
			}
839
840
			sgl_node->sgl_data = sglist_alloc(HV_MAX_MULTIPAGE_BUFFER_COUNT,
841
				                      M_WAITOK|M_ZERO);
842
			if (NULL == sgl_node->sgl_data){
843
				ret = ENOMEM;
844
	            goto cleanup;
845
			}
846
847
			for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++){
848
				tmp_buff = malloc(PAGE_SIZE,
849
				            M_DEVBUF, M_WAITOK|M_ZERO);
850
				if (NULL == tmp_buff){
851
	    			ret = ENOMEM;
852
		            goto cleanup;
853
				}
854
855
				sgl_node->sgl_data->sg_segs[j].ss_paddr = (vm_paddr_t)tmp_buff;
856
			}
857
858
			LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list, sgl_node, link);
859
		}
860
	}
861
767
	sc->hs_destroy = FALSE;
862
	sc->hs_destroy = FALSE;
768
	sc->hs_drain_notify = FALSE;
863
	sc->hs_drain_notify = FALSE;
769
	sema_init(&sc->hs_drain_sema, 0, "Store Drain Sema");
864
	sema_init(&sc->hs_drain_sema, 0, "Store Drain Sema");
Lines 834-839 cleanup: Link Here
834
		LIST_REMOVE(reqp, link);
929
		LIST_REMOVE(reqp, link);
835
		free(reqp, M_DEVBUF);
930
		free(reqp, M_DEVBUF);
836
	}
931
	}
932
933
	while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) {
934
		sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
935
		LIST_REMOVE(sgl_node, link);
936
		for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++){
937
			if (NULL != (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr){
938
		        free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF);
939
			}
940
		}
941
		sglist_free(sgl_node->sgl_data);
942
		free(sgl_node, M_DEVBUF);
943
	}
944
837
	return (ret);
945
	return (ret);
838
}
946
}
839
947
Lines 853-858 storvsc_detach(device_t dev) Link Here
853
	struct storvsc_softc *sc = device_get_softc(dev);
961
	struct storvsc_softc *sc = device_get_softc(dev);
854
	struct hv_storvsc_request *reqp = NULL;
962
	struct hv_storvsc_request *reqp = NULL;
855
	struct hv_device *hv_device = vmbus_get_devctx(dev);
963
	struct hv_device *hv_device = vmbus_get_devctx(dev);
964
	struct hv_sgl_node *sgl_node = NULL;
965
	int j = 0;
856
966
857
	mtx_lock(&hv_device->channel->inbound_lock);
967
	mtx_lock(&hv_device->channel->inbound_lock);
858
	sc->hs_destroy = TRUE;
968
	sc->hs_destroy = TRUE;
Lines 884-889 storvsc_detach(device_t dev) Link Here
884
		free(reqp, M_DEVBUF);
994
		free(reqp, M_DEVBUF);
885
	}
995
	}
886
	mtx_unlock(&sc->hs_lock);
996
	mtx_unlock(&sc->hs_lock);
997
998
	while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) {
999
		sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
1000
		LIST_REMOVE(sgl_node, link);
1001
		for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++){
1002
			if (NULL != (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr){
1003
		        free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF);
1004
			}
1005
		}
1006
		sglist_free(sgl_node->sgl_data);
1007
		free(sgl_node, M_DEVBUF);
1008
	}
1009
	
887
	return (0);
1010
	return (0);
888
}
1011
}
889
1012
Lines 939-945 storvsc_timeout_test(struct hv_storvsc_r Link Here
939
				ticks, __func__, (ret == 0)?
1062
				ticks, __func__, (ret == 0)?
940
				"IO return detected" :
1063
				"IO return detected" :
941
				"IO return not detected");
1064
				"IO return not detected");
942
		/* 
1065
		/*
943
		 * Now both the timer handler and io done are running
1066
		 * Now both the timer handler and io done are running
944
		 * simultaneously. We want to confirm the io done always
1067
		 * simultaneously. We want to confirm the io done always
945
		 * finishes after the timer handler exits. So reqp used by
1068
		 * finishes after the timer handler exits. So reqp used by
Lines 1152-1160 storvsc_action(struct cam_sim *sim, unio Link Here
1152
1275
1153
		bzero(reqp, sizeof(struct hv_storvsc_request));
1276
		bzero(reqp, sizeof(struct hv_storvsc_request));
1154
		reqp->softc = sc;
1277
		reqp->softc = sc;
1155
1278
		
1156
		ccb->ccb_h.status |= CAM_SIM_QUEUED;	    
1279
		ccb->ccb_h.status |= CAM_SIM_QUEUED;
1157
		create_storvsc_request(ccb, reqp);
1280
		if ((res = create_storvsc_request(ccb, reqp)) != 0) {
1281
			ccb->ccb_h.status = CAM_REQ_INVALID;
1282
			xpt_done(ccb);
1283
			return;
1284
		}
1158
1285
1159
		if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
1286
		if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
1160
			callout_init(&reqp->callout, CALLOUT_MPSAFE);
1287
			callout_init(&reqp->callout, CALLOUT_MPSAFE);
Lines 1195-1200 storvsc_action(struct cam_sim *sim, unio Link Here
1195
}
1322
}
1196
1323
1197
/**
1324
/**
1325
 * @brief destroy bounce buffer
1326
 *
1327
 * This function is responsible for destroy a Scatter/Gather list
1328
 * that create by storvsc_create_bounce_buffer()
1329
 *
1330
 * @param sgl- the Scatter/Gather need be destroy
1331
 * @param sg_count- page count of the SG list.
1332
 *
1333
 */
1334
static void
1335
storvsc_destroy_bounce_buffer(struct sglist *sgl)
1336
{
1337
	struct hv_sgl_node *sgl_node = NULL;
1338
1339
	sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.in_use_sgl_list);
1340
	LIST_REMOVE(sgl_node, link);
1341
	if (NULL == sgl_node) {
1342
		printf("storvsc error: not enough in use sgl\n");
1343
		return;
1344
	}
1345
	sgl_node->sgl_data = sgl;
1346
	LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list, sgl_node, link);
1347
}
1348
1349
/**
1350
 * @brief create bounce buffer
1351
 *
1352
 * This function is responsible for create a Scatter/Gather list,
1353
 * which hold several pages that can be aligned with page size.
1354
 *
1355
 * @param seg_count- SG-list segments count
1356
 * @param write - if WRITE_TYPE, set SG list page used size to 0,
1357
 * otherwise set used size to page size.
1358
 *
1359
 * return NULL if create failed
1360
 */
1361
static struct sglist *
1362
storvsc_create_bounce_buffer(uint16_t seg_count, int write)
1363
{
1364
	int i = 0;
1365
	struct sglist *bounce_sgl = NULL;
1366
	unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE);
1367
	struct hv_sgl_node *sgl_node = NULL;	
1368
1369
	/* get struct sglist from free_sgl_list */
1370
	sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
1371
	LIST_REMOVE(sgl_node, link);
1372
	if (NULL == sgl_node) {
1373
		printf("storvsc error: not enough free sgl\n");
1374
		return NULL;
1375
	}
1376
	bounce_sgl = sgl_node->sgl_data;
1377
	LIST_INSERT_HEAD(&g_hv_sgl_page_pool.in_use_sgl_list, sgl_node, link);
1378
1379
	bounce_sgl->sg_maxseg = seg_count;
1380
	if (write == WRITE_TYPE) {
1381
		bounce_sgl->sg_nseg = 0;
1382
	} else {
1383
		bounce_sgl->sg_nseg = seg_count;
1384
	}
1385
1386
	for (i = 0; i < seg_count; i++) {
1387
	        bounce_sgl->sg_segs[i].ss_len = buf_len;
1388
	}
1389
1390
	return bounce_sgl;
1391
}
1392
1393
/**
1394
 * @brief copy data from SG list to bounce buffer
1395
 *
1396
 * This function is responsible for copy data from one SG list's segments
1397
 * to another SG list which used as bounce buffer.
1398
 *
1399
 * @param bounce_sgl - the destination SG list
1400
 * @param orig_sgl - the segment of the source SG list.
1401
 * @param orig_sgl_count - the count of segments.
1402
 * @param orig_sgl_count - indicate which segment need bounce buffer, set 1 means need.
1403
 *
1404
 */
1405
void storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl,
1406
				bus_dma_segment_t *orig_sgl,
1407
				unsigned int orig_sgl_count,
1408
				uint64_t seg_bits)
1409
{
1410
	int src_sgl_idx = 0;
1411
1412
	for (src_sgl_idx = 0; src_sgl_idx < orig_sgl_count; src_sgl_idx++) {
1413
		if (seg_bits & (1 << src_sgl_idx)) {
1414
			memcpy((void*)bounce_sgl->sg_segs[src_sgl_idx].ss_paddr,
1415
			    (void*)orig_sgl[src_sgl_idx].ds_addr,
1416
			    orig_sgl[src_sgl_idx].ds_len);
1417
			bounce_sgl->sg_segs[src_sgl_idx].ss_len =
1418
			    orig_sgl[src_sgl_idx].ds_len;
1419
		}
1420
	}
1421
}
1422
1423
/**
1424
 * @brief copy data from SG list which used as bounce to another SG list
1425
 *
1426
 * This function is responsible for copy data from one SG list with bounce
1427
 * buffer to another SG list's segments.
1428
 *
1429
 * @param dest_sgl - the destination SG list's segments
1430
 * @param dest_sgl_count - the count of destination SG list's segment.
1431
 * @param src_sgl - the source SG list.
1432
 * @param seg_bits - indicate which segment used bounce buffer of src SG-list.
1433
 *
1434
 */
1435
void
1436
storvsc_copy_from_bounce_buf_to_sgl(bus_dma_segment_t *dest_sgl,
1437
	                unsigned int dest_sgl_count,
1438
				    struct sglist* src_sgl,
1439
				    uint64_t seg_bits)
1440
{
1441
	int sgl_idx = 0;
1442
	
1443
	for (sgl_idx = 0; sgl_idx < dest_sgl_count; sgl_idx++) {
1444
		if (seg_bits & (1 << sgl_idx)) {
1445
			memcpy((void*)(dest_sgl[sgl_idx].ds_addr),
1446
			    (void*)(src_sgl->sg_segs[sgl_idx].ss_paddr),
1447
			    src_sgl->sg_segs[sgl_idx].ss_len);
1448
		}
1449
	}
1450
}
1451
1452
/**
1453
 * @brief check SG list with bounce buffer or not
1454
 *
1455
 * This function is responsible for check if need bounce buffer for SG list.
1456
 *
1457
 * @param sgl - the SG list's segments
1458
 * @param sg_count - the count of SG list's segment.
1459
 * @param bits - segmengs number that need bounce buffer
1460
 *
1461
 * return -1 if SG list needless bounce buffer
1462
 */
1463
static int
1464
storvsc_check_bounce_buffer_sgl(bus_dma_segment_t *sgl, unsigned int sg_count, uint64_t *bits)
1465
{
1466
	int i = 0;
1467
	int offset = 0;
1468
	uint64_t phys_addr = 0;
1469
	uint64_t tmp_bits = 0;
1470
	boolean_t found_hole = FALSE;
1471
	boolean_t pre_aligned = TRUE;
1472
1473
	if (sg_count < 2){
1474
		return -1;
1475
	}
1476
1477
	*bits = 0;
1478
	
1479
	phys_addr = vtophys(sgl[0].ds_addr);
1480
	offset =  phys_addr - trunc_page(phys_addr);
1481
	if (offset){
1482
	    pre_aligned = FALSE;
1483
		tmp_bits |= 1;
1484
	}
1485
1486
	for (i = 1; i < sg_count; i++) {
1487
		phys_addr = vtophys(sgl[i].ds_addr);
1488
		offset =  phys_addr - trunc_page(phys_addr);
1489
1490
		if (0 == offset) {
1491
			if (FALSE == pre_aligned){
1492
				/*
1493
				 * This segment is aligned, if the previous
1494
				 * one is not aligned, find a hole
1495
				 */
1496
				found_hole = TRUE;
1497
			}
1498
			pre_aligned = TRUE;
1499
		} else {
1500
			tmp_bits |= 1 << i;
1501
			if (FALSE == pre_aligned) {
1502
				if (phys_addr != vtophys(sgl[i-1].ds_addr +
1503
				    sgl[i-1].ds_len)) {
1504
					/*
1505
					 * Check whether connect to previous
1506
					 * segment,if not, find the hole
1507
					 */
1508
					found_hole = TRUE;
1509
				}
1510
			} else {
1511
				found_hole = TRUE;
1512
			}
1513
			pre_aligned = FALSE;
1514
		}
1515
	}
1516
1517
	if (FALSE == found_hole) {
1518
		return -1;
1519
	} else {
1520
		*bits = tmp_bits;
1521
		return 0;
1522
	}
1523
}
1524
1525
/**
1198
 * @brief Fill in a request structure based on a CAM control block
1526
 * @brief Fill in a request structure based on a CAM control block
1199
 *
1527
 *
1200
 * Fills in a request structure based on the contents of a CAM control
1528
 * Fills in a request structure based on the contents of a CAM control
Lines 1204-1210 storvsc_action(struct cam_sim *sim, unio Link Here
1204
 * @param ccb pointer to a CAM contorl block
1532
 * @param ccb pointer to a CAM contorl block
1205
 * @param reqp pointer to a request structure
1533
 * @param reqp pointer to a request structure
1206
 */
1534
 */
1207
static void
1535
static int
1208
create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp)
1536
create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp)
1209
{
1537
{
1210
	struct ccb_scsiio *csio = &ccb->csio;
1538
	struct ccb_scsiio *csio = &ccb->csio;
Lines 1212-1217 create_storvsc_request(union ccb *ccb, s Link Here
1212
	uint32_t bytes_to_copy = 0;
1540
	uint32_t bytes_to_copy = 0;
1213
	uint32_t pfn_num = 0;
1541
	uint32_t pfn_num = 0;
1214
	uint32_t pfn;
1542
	uint32_t pfn;
1543
	uint64_t not_aligned_seg_bits = 0;
1215
	
1544
	
1216
	/* refer to struct vmscsi_req for meanings of these two fields */
1545
	/* refer to struct vmscsi_req for meanings of these two fields */
1217
	reqp->vstor_packet.u.vm_srb.port =
1546
	reqp->vstor_packet.u.vm_srb.port =
Lines 1232-1279 create_storvsc_request(union ccb *ccb, s Link Here
1232
	}
1561
	}
1233
1562
1234
	switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
1563
	switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
1235
    	case CAM_DIR_OUT: 
1564
	case CAM_DIR_OUT:
1236
    		reqp->vstor_packet.u.vm_srb.data_in = WRITE_TYPE;
1565
		reqp->vstor_packet.u.vm_srb.data_in = WRITE_TYPE;	
1237
    		break;
1566
		break;
1238
    	case CAM_DIR_IN:
1567
	case CAM_DIR_IN:
1239
    		reqp->vstor_packet.u.vm_srb.data_in = READ_TYPE;
1568
		reqp->vstor_packet.u.vm_srb.data_in = READ_TYPE;
1240
    		break;
1569
		break;
1241
    	case CAM_DIR_NONE:
1570
	case CAM_DIR_NONE:
1242
    		reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE;
1571
		reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE;
1243
    		break;
1572
		break;
1244
    	default:
1573
	default:
1245
    		reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE;
1574
		reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE;
1246
    		break;
1575
		break;
1247
	}
1576
	}
1248
1577
1249
	reqp->sense_data     = &csio->sense_data;
1578
	reqp->sense_data     = &csio->sense_data;
1250
	reqp->sense_info_len = csio->sense_len;
1579
	reqp->sense_info_len = csio->sense_len;
1251
1580
1252
	reqp->ccb = ccb;
1581
	reqp->ccb = ccb;
1253
	/*
1582
1254
	KASSERT((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0,
1583
	if (0 == csio->dxfer_len) {
1255
			("ccb is scatter gather valid\n"));
1584
		return 0;
1256
	*/
1585
	}
1257
	if (csio->dxfer_len != 0) {
1586
1258
		reqp->data_buf.length = csio->dxfer_len;
1587
	reqp->data_buf.length = csio->dxfer_len;
1588
1589
	switch (ccb->ccb_h.flags & CAM_DATA_MASK) {
1590
	case CAM_DATA_VADDR:{
1259
		bytes_to_copy = csio->dxfer_len;
1591
		bytes_to_copy = csio->dxfer_len;
1260
		phys_addr = vtophys(csio->data_ptr);
1592
		phys_addr = vtophys(csio->data_ptr);
1261
		reqp->data_buf.offset = phys_addr - trunc_page(phys_addr);
1593
		reqp->data_buf.offset = phys_addr & PAGE_MASK;
1594
		
1595
		while (bytes_to_copy != 0) {
1596
			int bytes, page_offset;
1597
			phys_addr =
1598
			    vtophys(&csio->data_ptr[reqp->data_buf.length -
1599
			    bytes_to_copy]);
1600
			pfn = phys_addr >> PAGE_SHIFT;
1601
			reqp->data_buf.pfn_array[pfn_num] = pfn;
1602
			page_offset = phys_addr & PAGE_MASK;
1603
1604
			bytes = min(PAGE_SIZE - page_offset, bytes_to_copy);
1605
1606
			bytes_to_copy -= bytes;
1607
			pfn_num++;
1608
		}
1609
		break;
1262
	}
1610
	}
1611
	case CAM_DATA_SG:{
1612
		int i = 0;
1613
		int offset = 0;
1614
		bus_dma_segment_t *storvsc_sglist =
1615
		    (bus_dma_segment_t *)ccb->csio.data_ptr;
1616
		u_int16_t storvsc_sg_count = ccb->csio.sglist_cnt;
1617
1618
		printf("Storvsc: get SG I/O operation, %d\n",
1619
		    reqp->vstor_packet.u.vm_srb.data_in);
1620
1621
		if (storvsc_sg_count > HV_MAX_MULTIPAGE_BUFFER_COUNT){
1622
			printf("Storvsc: %d segments is too much, "
1623
			    "only support %d segments\n",
1624
			    storvsc_sg_count, HV_MAX_MULTIPAGE_BUFFER_COUNT);
1625
			return EINVAL;
1626
		}
1627
1628
		/* check if we need to create bounce buffer */
1629
		if (storvsc_check_bounce_buffer_sgl(
1630
			          storvsc_sglist,
1631
			          storvsc_sg_count,
1632
			          &not_aligned_seg_bits) != -1) {
1633
			reqp->bounce_sgl =
1634
			    storvsc_create_bounce_buffer(storvsc_sg_count,
1635
			       reqp->vstor_packet.u.vm_srb.data_in);
1636
			if (NULL == reqp->bounce_sgl) {
1637
				printf("Storvsc_error: create bounce buffer failed.\n");
1638
				return ENOMEM;
1639
			}
1640
1641
			reqp->bounce_sgl_count = storvsc_sg_count;
1642
			reqp->not_aligned_seg_bits = not_aligned_seg_bits;
1643
1644
			/*
1645
			 * if it is write, we need copy the original data
1646
			 *to bounce buffer
1647
			 */
1648
			if (WRITE_TYPE == reqp->vstor_packet.u.vm_srb.data_in) {
1649
				storvsc_copy_sgl_to_bounce_buf(
1650
				    reqp->bounce_sgl,
1651
				    storvsc_sglist,
1652
				    storvsc_sg_count,
1653
				    reqp->not_aligned_seg_bits);
1654
			}
1655
1656
			/* transfer virtual address to physical frame number */
1657
			if (reqp->not_aligned_seg_bits & 0x1){
1658
 				phys_addr =
1659
					vtophys(reqp->bounce_sgl->sg_segs[0].ss_paddr);
1660
			}else{
1661
 				phys_addr =
1662
					vtophys(storvsc_sglist[0].ds_addr);
1663
			}
1664
			reqp->data_buf.offset = phys_addr & PAGE_MASK;
1665
1666
			pfn = phys_addr >> PAGE_SHIFT;
1667
			reqp->data_buf.pfn_array[0] = pfn;
1668
			
1669
			for (i = 1; i < storvsc_sg_count; i++) {
1670
				if (reqp->not_aligned_seg_bits & (1 << i)){
1671
					phys_addr =
1672
						vtophys(reqp->bounce_sgl->sg_segs[i].ss_paddr);
1673
				}
1674
				else{
1675
					phys_addr =
1676
						vtophys(storvsc_sglist[i].ds_addr);
1677
				}
1263
1678
1264
	while (bytes_to_copy != 0) {
1679
				pfn = phys_addr >> PAGE_SHIFT;
1265
		int bytes, page_offset;
1680
				reqp->data_buf.pfn_array[i] = pfn;
1266
		phys_addr = vtophys(&csio->data_ptr[reqp->data_buf.length -
1681
			}
1267
		                                    bytes_to_copy]);
1682
		}
1268
		pfn = phys_addr >> PAGE_SHIFT;
1683
		else {
1269
		reqp->data_buf.pfn_array[pfn_num] = pfn;
1684
			phys_addr = vtophys(storvsc_sglist[0].ds_addr);
1270
		page_offset = phys_addr - trunc_page(phys_addr);
1685
1686
			reqp->data_buf.offset = phys_addr & PAGE_MASK;
1271
1687
1272
		bytes = min(PAGE_SIZE - page_offset, bytes_to_copy);
1688
			for (i = 0; i < storvsc_sg_count; i++){
1689
				phys_addr = vtophys(storvsc_sglist[i].ds_addr);
1690
				pfn = phys_addr >> PAGE_SHIFT;
1691
				reqp->data_buf.pfn_array[i] = pfn;
1692
			}
1273
1693
1274
		bytes_to_copy -= bytes;
1694
			/* check the last segment cross boundary or not */
1275
		pfn_num++;
1695
			offset = phys_addr & PAGE_MASK;
1696
			if (offset){
1697
				phys_addr =
1698
				    vtophys(storvsc_sglist[i-1].ds_addr +
1699
				    PAGE_SIZE - offset);
1700
				pfn = phys_addr >> PAGE_SHIFT;
1701
				reqp->data_buf.pfn_array[i] = pfn;
1702
			}
1703
			
1704
			reqp->bounce_sgl_count = 0;
1705
		}
1706
		break;
1276
	}
1707
	}
1708
	default:
1709
		printf("Unknow flags: %d\n", ccb->ccb_h.flags);
1710
		return EINVAL;
1711
	}
1712
1713
	return 0;
1277
}
1714
}
1278
1715
1279
/**
1716
/**
Lines 1292-1298 storvsc_io_done(struct hv_storvsc_reques Link Here
1292
	struct ccb_scsiio *csio = &ccb->csio;
1729
	struct ccb_scsiio *csio = &ccb->csio;
1293
	struct storvsc_softc *sc = reqp->softc;
1730
	struct storvsc_softc *sc = reqp->softc;
1294
	struct vmscsi_req *vm_srb = &reqp->vstor_packet.u.vm_srb;
1731
	struct vmscsi_req *vm_srb = &reqp->vstor_packet.u.vm_srb;
1295
	
1732
	bus_dma_segment_t *ori_sglist = NULL;
1733
	int ori_sg_count = 0;
1734
1735
	/* destroy bounce buffer if it is used */
1736
	if (reqp->bounce_sgl_count) {
1737
		ori_sglist = (bus_dma_segment_t *)ccb->csio.data_ptr;
1738
		ori_sg_count = ccb->csio.sglist_cnt;
1739
1740
		/*
1741
		 * If it is READ operation, we should copy back the data
1742
		 * to original SG list.
1743
		 */
1744
		if (READ_TYPE == reqp->vstor_packet.u.vm_srb.data_in) {
1745
			storvsc_copy_from_bounce_buf_to_sgl(ori_sglist,
1746
			    ori_sg_count,
1747
			    reqp->bounce_sgl,
1748
			    reqp->not_aligned_seg_bits);
1749
		}
1750
1751
		storvsc_destroy_bounce_buffer(reqp->bounce_sgl);
1752
		reqp->bounce_sgl_count = 0;
1753
	}
1754
		
1296
	if (reqp->retries > 0) {
1755
	if (reqp->retries > 0) {
1297
		mtx_lock(&sc->hs_lock);
1756
		mtx_lock(&sc->hs_lock);
1298
#if HVS_TIMEOUT_TEST
1757
#if HVS_TIMEOUT_TEST
Lines 1310-1316 storvsc_io_done(struct hv_storvsc_reques Link Here
1310
		mtx_unlock(&sc->hs_lock);
1769
		mtx_unlock(&sc->hs_lock);
1311
	}
1770
	}
1312
1771
1313
	/* 
1772
	/*
1314
	 * callout_drain() will wait for the timer handler to finish
1773
	 * callout_drain() will wait for the timer handler to finish
1315
	 * if it is running. So we don't need any lock to synchronize
1774
	 * if it is running. So we don't need any lock to synchronize
1316
	 * between this routine and the timer handler.
1775
	 * between this routine and the timer handler.
(-)src/sys/dev/hyperv/storvsc/hv_vstorage.h (-3 / +13 lines)
Lines 53-59 Link Here
53
 * V1 RC > 2008/1/31          2.0
53
 * V1 RC > 2008/1/31          2.0
54
 */
54
 */
55
55
56
#define VMSTOR_PROTOCOL_VERSION_CURRENT	VMSTOR_PROTOCOL_VERSION(2, 0)
56
#define VMSTOR_PROTOCOL_VERSION_CURRENT	VMSTOR_PROTOCOL_VERSION(5, 1)
57
57
58
/**
58
/**
59
 *  Packet structure ops describing virtual storage requests.
59
 *  Packet structure ops describing virtual storage requests.
Lines 69-75 enum vstor_packet_ops { Link Here
69
	VSTOR_OPERATION_ENDINITIALIZATION     = 8,
69
	VSTOR_OPERATION_ENDINITIALIZATION     = 8,
70
	VSTOR_OPERATION_QUERYPROTOCOLVERSION  = 9,
70
	VSTOR_OPERATION_QUERYPROTOCOLVERSION  = 9,
71
	VSTOR_OPERATION_QUERYPROPERTIES       = 10,
71
	VSTOR_OPERATION_QUERYPROPERTIES       = 10,
72
	VSTOR_OPERATION_MAXIMUM               = 10
72
	VSTOR_OPERATION_ENUMERATE_BUS         = 11,
73
	VSTOR_OPERATION_FCHBA_DATA            = 12,
74
	VSTOR_OPERATION_CREATE_MULTI_CHANNELS = 13,
75
	VSTOR_OPERATION_MAXIMUM               = 13
73
};
76
};
74
77
75
78
Lines 123-132 struct vmstor_chan_props { Link Here
123
	uint8_t  path_id;
126
	uint8_t  path_id;
124
	uint8_t  target_id;
127
	uint8_t  target_id;
125
128
129
	uint16_t max_channel_cnt;
130
126
	/**
131
	/**
127
	 * Note: port number is only really known on the client side
132
	 * Note: port number is only really known on the client side
128
	 */
133
	 */
129
	uint32_t port;
134
	uint16_t port;
130
	uint32_t flags;
135
	uint32_t flags;
131
	uint32_t max_transfer_bytes;
136
	uint32_t max_transfer_bytes;
132
137
Lines 193-198 struct vstor_packet { Link Here
193
	     * Used during version negotiations.
198
	     * Used during version negotiations.
194
	     */
199
	     */
195
	    struct vmstor_proto_ver version;
200
	    struct vmstor_proto_ver version;
201
202
	    /**
203
             * Number of multichannels to create
204
	     */
205
	    uint16_t multi_channels_cnt;
196
	} u;
206
	} u;
197
207
198
} __packed;
208
} __packed;
(-)src/sys/dev/hyperv/utilities/hv_kvp.c (-13 / +13 lines)
Lines 39-45 __FBSDID("$FreeBSD: releng/10.1/sys/dev/ Link Here
39
#include <sys/uio.h>
39
#include <sys/uio.h>
40
#include <sys/bus.h>
40
#include <sys/bus.h>
41
#include <sys/malloc.h>
41
#include <sys/malloc.h>
42
#include <sys/mbuf.h>
43
#include <sys/module.h>
42
#include <sys/module.h>
44
#include <sys/reboot.h>
43
#include <sys/reboot.h>
45
#include <sys/lock.h>
44
#include <sys/lock.h>
Lines 55-65 __FBSDID("$FreeBSD: releng/10.1/sys/dev/ Link Here
55
#include <sys/_null.h>
54
#include <sys/_null.h>
56
#include <sys/signal.h>
55
#include <sys/signal.h>
57
#include <sys/syslog.h>
56
#include <sys/syslog.h>
57
#include <sys/systm.h>
58
#include <sys/mutex.h>
58
#include <sys/mutex.h>
59
#include <net/if_arp.h>
59
#include <net/if_arp.h>
60
60
61
#include <dev/hyperv/include/hyperv.h>
61
#include <hyperv.h>
62
#include <dev/hyperv/netvsc/hv_net_vsc.h>
62
#include <hv_net_vsc.h>
63
63
64
#include "unicode.h"
64
#include "unicode.h"
65
#include "hv_kvp.h"
65
#include "hv_kvp.h"
Lines 71-87 __FBSDID("$FreeBSD: releng/10.1/sys/dev/ Link Here
71
#define kvp_hdr		hdr.kvp_hdr
71
#define kvp_hdr		hdr.kvp_hdr
72
72
73
/* hv_kvp debug control */
73
/* hv_kvp debug control */
74
static int hv_kvp_log = 0;
74
static int hv_kvp_port_log = 0;
75
SYSCTL_INT(_dev, OID_AUTO, hv_kvp_log, CTLFLAG_RW, &hv_kvp_log, 0,
75
SYSCTL_INT(_dev, OID_AUTO, hv_kvp_port_log, CTLFLAG_RW, &hv_kvp_port_log, 0,
76
	"hv_kvp log");
76
	"hv_kvp log");
77
77
78
#define	hv_kvp_log_error(...)	do {				\
78
#define	hv_kvp_log_error(...)	do {				\
79
	if (hv_kvp_log > 0)				\
79
	if (hv_kvp_port_log > 0)				\
80
		log(LOG_ERR, "hv_kvp: " __VA_ARGS__);	\
80
		log(LOG_ERR, "hv_kvp: " __VA_ARGS__);	\
81
} while (0)
81
} while (0)
82
82
83
#define	hv_kvp_log_info(...) do {				\
83
#define	hv_kvp_log_info(...) do {				\
84
	if (hv_kvp_log > 1)				\
84
	if (hv_kvp_port_log > 1)				\
85
		log(LOG_INFO, "hv_kvp: " __VA_ARGS__);		\
85
		log(LOG_INFO, "hv_kvp: " __VA_ARGS__);		\
86
} while (0)
86
} while (0)
87
87
Lines 232-238 hv_kvp_negotiate_version(struct hv_vmbus Link Here
232
	 */
232
	 */
233
	if ((icframe_vercnt >= 2) && (negop->icversion_data[1].major == 3)) {
233
	if ((icframe_vercnt >= 2) && (negop->icversion_data[1].major == 3)) {
234
		icframe_vercnt = 3;
234
		icframe_vercnt = 3;
235
		if (icmsg_vercnt >= 2)
235
		if (icmsg_vercnt > 2)
236
			icmsg_vercnt = 4;
236
			icmsg_vercnt = 4;
237
		else
237
		else
238
			icmsg_vercnt = 3;
238
			icmsg_vercnt = 3;
Lines 734-742 hv_kvp_process_request(void *context) Link Here
734
		recvlen = 0;
734
		recvlen = 0;
735
		ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * PAGE_SIZE,
735
		ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * PAGE_SIZE,
736
			&recvlen, &requestid);
736
			&recvlen, &requestid);
737
		hv_kvp_log_info("%s: read: context %p, pending_cnt %ju ret =%d, recvlen=%d\n",
737
		hv_kvp_log_info("%s: read: context %p, pending_cnt %llu ret =%d, recvlen=%d\n",
738
			__func__, context, pending_cnt, ret, recvlen);
738
			__func__, context, (unsigned long long)pending_cnt, ret, recvlen);
739
	} 
739
	}
740
}
740
}
741
741
742
742
Lines 813-821 static void Link Here
813
hv_kvp_dev_destroy(void)
813
hv_kvp_dev_destroy(void)
814
{
814
{
815
815
816
        if (daemon_task != NULL) {
816
	if (daemon_task != NULL) {
817
		PROC_LOCK(daemon_task);
817
		PROC_LOCK(daemon_task);
818
        	kern_psignal(daemon_task, SIGKILL);
818
		kern_psignal(daemon_task, SIGKILL);
819
		PROC_UNLOCK(daemon_task);
819
		PROC_UNLOCK(daemon_task);
820
	}
820
	}
821
	
821
	
(-)src/sys/dev/hyperv/utilities/hv_kvp.h (-1 / +1 lines)
Lines 220-226 struct hv_kvp_register { Link Here
220
struct hv_kvp_msg {
220
struct hv_kvp_msg {
221
	union {
221
	union {
222
		struct hv_kvp_hdr kvp_hdr;
222
		struct hv_kvp_hdr kvp_hdr;
223
		uint32_t error;
223
		int error;
224
	} hdr;
224
	} hdr;
225
	union {
225
	union {
226
		struct hv_kvp_msg_get		kvp_get;
226
		struct hv_kvp_msg_get		kvp_get;
(-)src/sys/dev/hyperv/utilities/hv_util.c (-6 / +6 lines)
Lines 39-45 Link Here
39
#include <sys/timetc.h>
39
#include <sys/timetc.h>
40
#include <sys/syscallsubr.h>
40
#include <sys/syscallsubr.h>
41
41
42
#include <dev/hyperv/include/hyperv.h>
42
#include <hyperv.h>
43
#include "hv_kvp.h"
43
#include "hv_kvp.h"
44
44
45
/* Time Sync data */
45
/* Time Sync data */
Lines 378-384 hv_util_probe(device_t dev) Link Here
378
	    const char *p = vmbus_get_type(dev);
378
	    const char *p = vmbus_get_type(dev);
379
	    if (service_table[i].enabled && !memcmp(p, &service_table[i].guid, sizeof(hv_guid))) {
379
	    if (service_table[i].enabled && !memcmp(p, &service_table[i].guid, sizeof(hv_guid))) {
380
		device_set_softc(dev, (void *) (&service_table[i]));
380
		device_set_softc(dev, (void *) (&service_table[i]));
381
		rtn_value = BUS_PROBE_DEFAULT;
381
		rtn_value = BUS_PROBE_VENDOR;
382
	    }
382
	    }
383
	}
383
	}
384
384
Lines 479-491 static device_method_t util_methods[] = Link Here
479
	{ 0, 0 } }
479
	{ 0, 0 } }
480
;
480
;
481
481
482
static driver_t util_driver = { "hyperv-utils", util_methods, 0 };
482
static driver_t util_driver = { "hyperv-utils-port", util_methods, 0 };
483
483
484
static devclass_t util_devclass;
484
static devclass_t util_devclass;
485
485
486
DRIVER_MODULE(hv_utils, vmbus, util_driver, util_devclass, hv_util_modevent, 0);
486
DRIVER_MODULE(hv_utils_port, vmbus, util_driver, util_devclass, hv_util_modevent, 0);
487
MODULE_VERSION(hv_utils, 1);
487
MODULE_VERSION(hv_utils_port, 1);
488
MODULE_DEPEND(hv_utils, vmbus, 1, 1, 1);
488
MODULE_DEPEND(hv_utils_port, vmbus, 1, 1, 1);
489
489
490
SYSINIT(hv_util_initx, SI_SUB_KTHREAD_IDLE, SI_ORDER_MIDDLE + 1,
490
SYSINIT(hv_util_initx, SI_SUB_KTHREAD_IDLE, SI_ORDER_MIDDLE + 1,
491
	hv_util_init, NULL);
491
	hv_util_init, NULL);
(-)src/sys/dev/hyperv/vmbus/hv_vmbus_priv.h (-1 / +1 lines)
Lines 36-42 Link Here
36
#include <sys/mutex.h>
36
#include <sys/mutex.h>
37
#include <sys/sema.h>
37
#include <sys/sema.h>
38
38
39
#include <dev/hyperv/include/hyperv.h>
39
#include <hyperv.h>
40
40
41
41
42
/*
42
/*

Return to bug 196185