hv_storvsc_drv_freebsd.c revision 301866
1/*- 2 * Copyright (c) 2009-2012 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 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice unmodified, this list of conditions, and the following 12 * disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 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/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c 301866 2016-06-13 09:02:08Z 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> 45#include <sys/malloc.h> 46#include <sys/module.h> 47#include <sys/kernel.h> 48#include <sys/queue.h> 49#include <sys/lock.h> 50#include <sys/sx.h> 51#include <sys/taskqueue.h> 52#include <sys/bus.h> 53#include <sys/mutex.h> 54#include <sys/callout.h> 55#include <vm/vm.h> 56#include <vm/pmap.h> 57#include <vm/uma.h> 58#include <sys/lock.h> 59#include <sys/sema.h> 60#include <sys/sglist.h> 61#include <machine/bus.h> 62#include <sys/bus_dma.h> 63 64#include <cam/cam.h> 65#include <cam/cam_ccb.h> 66#include <cam/cam_periph.h> 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 "hv_vstorage.h" 76 77#define STORVSC_RINGBUFFER_SIZE (20*PAGE_SIZE) 78#define STORVSC_MAX_LUNS_PER_TARGET (64) 79#define STORVSC_MAX_IO_REQUESTS (STORVSC_MAX_LUNS_PER_TARGET * 2) 80#define BLKVSC_MAX_IDE_DISKS_PER_TARGET (1) 81#define BLKVSC_MAX_IO_REQUESTS STORVSC_MAX_IO_REQUESTS 82#define STORVSC_MAX_TARGETS (2) 83 84#define VSTOR_PKT_SIZE (sizeof(struct vstor_packet) - vmscsi_size_delta) 85 86#define HV_ALIGN(x, a) roundup2(x, a) 87 88struct storvsc_softc; 89 90struct hv_sgl_node { 91 LIST_ENTRY(hv_sgl_node) link; 92 struct sglist *sgl_data; 93}; 94 95struct hv_sgl_page_pool{ 96 LIST_HEAD(, hv_sgl_node) in_use_sgl_list; 97 LIST_HEAD(, hv_sgl_node) free_sgl_list; 98 boolean_t is_init; 99} g_hv_sgl_page_pool; 100 101#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * HV_MAX_MULTIPAGE_BUFFER_COUNT 102 103enum storvsc_request_type { 104 WRITE_TYPE, 105 READ_TYPE, 106 UNKNOWN_TYPE 107}; 108 109struct hv_storvsc_request { 110 LIST_ENTRY(hv_storvsc_request) link; 111 struct vstor_packet vstor_packet; 112 hv_vmbus_multipage_buffer data_buf; 113 void *sense_data; 114 uint8_t sense_info_len; 115 uint8_t retries; 116 union ccb *ccb; 117 struct storvsc_softc *softc; 118 struct callout callout; 119 struct sema synch_sema; /*Synchronize the request/response if needed */ 120 struct sglist *bounce_sgl; 121 unsigned int bounce_sgl_count; 122 uint64_t not_aligned_seg_bits; 123}; 124 125struct storvsc_softc { 126 struct hv_device *hs_dev; 127 LIST_HEAD(, hv_storvsc_request) hs_free_list; 128 struct mtx hs_lock; 129 struct storvsc_driver_props *hs_drv_props; 130 int hs_unit; 131 uint32_t hs_frozen; 132 struct cam_sim *hs_sim; 133 struct cam_path *hs_path; 134 uint32_t hs_num_out_reqs; 135 boolean_t hs_destroy; 136 boolean_t hs_drain_notify; 137 boolean_t hs_open_multi_channel; 138 struct sema hs_drain_sema; 139 struct hv_storvsc_request hs_init_req; 140 struct hv_storvsc_request hs_reset_req; 141}; 142 143 144/** 145 * HyperV storvsc timeout testing cases: 146 * a. IO returned after first timeout; 147 * b. IO returned after second timeout and queue freeze; 148 * c. IO returned while timer handler is running 149 * The first can be tested by "sg_senddiag -vv /dev/daX", 150 * and the second and third can be done by 151 * "sg_wr_mode -v -p 08 -c 0,1a -m 0,ff /dev/daX". 152 */ 153#define HVS_TIMEOUT_TEST 0 154 155/* 156 * Bus/adapter reset functionality on the Hyper-V host is 157 * buggy and it will be disabled until 158 * it can be further tested. 159 */ 160#define HVS_HOST_RESET 0 161 162struct storvsc_driver_props { 163 char *drv_name; 164 char *drv_desc; 165 uint8_t drv_max_luns_per_target; 166 uint8_t drv_max_ios_per_target; 167 uint32_t drv_ringbuffer_size; 168}; 169 170enum hv_storage_type { 171 DRIVER_BLKVSC, 172 DRIVER_STORVSC, 173 DRIVER_UNKNOWN 174}; 175 176#define HS_MAX_ADAPTERS 10 177 178#define HV_STORAGE_SUPPORTS_MULTI_CHANNEL 0x1 179 180/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ 181static const hv_guid gStorVscDeviceType={ 182 .data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 183 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f} 184}; 185 186/* {32412632-86cb-44a2-9b5c-50d1417354f5} */ 187static const hv_guid gBlkVscDeviceType={ 188 .data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, 189 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5} 190}; 191 192static struct storvsc_driver_props g_drv_props_table[] = { 193 {"blkvsc", "Hyper-V IDE Storage Interface", 194 BLKVSC_MAX_IDE_DISKS_PER_TARGET, BLKVSC_MAX_IO_REQUESTS, 195 STORVSC_RINGBUFFER_SIZE}, 196 {"storvsc", "Hyper-V SCSI Storage Interface", 197 STORVSC_MAX_LUNS_PER_TARGET, STORVSC_MAX_IO_REQUESTS, 198 STORVSC_RINGBUFFER_SIZE} 199}; 200 201/* 202 * Sense buffer size changed in win8; have a run-time 203 * variable to track the size we should use. 204 */ 205static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE; 206 207/* 208 * The size of the vmscsi_request has changed in win8. The 209 * additional size is for the newly added elements in the 210 * structure. These elements are valid only when we are talking 211 * to a win8 host. 212 * Track the correct size we need to apply. 213 */ 214static int vmscsi_size_delta; 215/* 216 * The storage protocol version is determined during the 217 * initial exchange with the host. It will indicate which 218 * storage functionality is available in the host. 219*/ 220static int vmstor_proto_version; 221 222struct vmstor_proto { 223 int proto_version; 224 int sense_buffer_size; 225 int vmscsi_size_delta; 226}; 227 228static const struct vmstor_proto vmstor_proto_list[] = { 229 { 230 VMSTOR_PROTOCOL_VERSION_WIN10, 231 POST_WIN7_STORVSC_SENSE_BUFFER_SIZE, 232 0 233 }, 234 { 235 VMSTOR_PROTOCOL_VERSION_WIN8_1, 236 POST_WIN7_STORVSC_SENSE_BUFFER_SIZE, 237 0 238 }, 239 { 240 VMSTOR_PROTOCOL_VERSION_WIN8, 241 POST_WIN7_STORVSC_SENSE_BUFFER_SIZE, 242 0 243 }, 244 { 245 VMSTOR_PROTOCOL_VERSION_WIN7, 246 PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE, 247 sizeof(struct vmscsi_win8_extension), 248 }, 249 { 250 VMSTOR_PROTOCOL_VERSION_WIN6, 251 PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE, 252 sizeof(struct vmscsi_win8_extension), 253 } 254}; 255 256/* static functions */ 257static int storvsc_probe(device_t dev); 258static int storvsc_attach(device_t dev); 259static int storvsc_detach(device_t dev); 260static void storvsc_poll(struct cam_sim * sim); 261static void storvsc_action(struct cam_sim * sim, union ccb * ccb); 262static int create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp); 263static void storvsc_free_request(struct storvsc_softc *sc, struct hv_storvsc_request *reqp); 264static enum hv_storage_type storvsc_get_storage_type(device_t dev); 265static void hv_storvsc_rescan_target(struct storvsc_softc *sc); 266static void hv_storvsc_on_channel_callback(void *context); 267static void hv_storvsc_on_iocompletion( struct storvsc_softc *sc, 268 struct vstor_packet *vstor_packet, 269 struct hv_storvsc_request *request); 270static int hv_storvsc_connect_vsp(struct hv_device *device); 271static void storvsc_io_done(struct hv_storvsc_request *reqp); 272static void storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl, 273 bus_dma_segment_t *orig_sgl, 274 unsigned int orig_sgl_count, 275 uint64_t seg_bits); 276void storvsc_copy_from_bounce_buf_to_sgl(bus_dma_segment_t *dest_sgl, 277 unsigned int dest_sgl_count, 278 struct sglist* src_sgl, 279 uint64_t seg_bits); 280 281static device_method_t storvsc_methods[] = { 282 /* Device interface */ 283 DEVMETHOD(device_probe, storvsc_probe), 284 DEVMETHOD(device_attach, storvsc_attach), 285 DEVMETHOD(device_detach, storvsc_detach), 286 DEVMETHOD(device_shutdown, bus_generic_shutdown), 287 DEVMETHOD_END 288}; 289 290static driver_t storvsc_driver = { 291 "storvsc", storvsc_methods, sizeof(struct storvsc_softc), 292}; 293 294static devclass_t storvsc_devclass; 295DRIVER_MODULE(storvsc, vmbus, storvsc_driver, storvsc_devclass, 0, 0); 296MODULE_VERSION(storvsc, 1); 297MODULE_DEPEND(storvsc, vmbus, 1, 1, 1); 298 299 300/** 301 * The host is capable of sending messages to us that are 302 * completely unsolicited. So, we need to address the race 303 * condition where we may be in the process of unloading the 304 * driver when the host may send us an unsolicited message. 305 * We address this issue by implementing a sequentially 306 * consistent protocol: 307 * 308 * 1. Channel callback is invoked while holding the the channel lock 309 * and an unloading driver will reset the channel callback under 310 * the protection of this channel lock. 311 * 312 * 2. To ensure bounded wait time for unloading a driver, we don't 313 * permit outgoing traffic once the device is marked as being 314 * destroyed. 315 * 316 * 3. Once the device is marked as being destroyed, we only 317 * permit incoming traffic to properly account for 318 * packets already sent out. 319 */ 320static inline struct storvsc_softc * 321get_stor_device(struct hv_device *device, 322 boolean_t outbound) 323{ 324 struct storvsc_softc *sc; 325 326 sc = device_get_softc(device->device); 327 if (sc == NULL) { 328 return NULL; 329 } 330 331 if (outbound) { 332 /* 333 * Here we permit outgoing I/O only 334 * if the device is not being destroyed. 335 */ 336 337 if (sc->hs_destroy) { 338 sc = NULL; 339 } 340 } else { 341 /* 342 * inbound case; if being destroyed 343 * only permit to account for 344 * messages already sent out. 345 */ 346 if (sc->hs_destroy && (sc->hs_num_out_reqs == 0)) { 347 sc = NULL; 348 } 349 } 350 return sc; 351} 352 353/** 354 * @brief Callback handler, will be invoked when receive mutil-channel offer 355 * 356 * @param context new multi-channel 357 */ 358static void 359storvsc_handle_sc_creation(void *context) 360{ 361 hv_vmbus_channel *new_channel; 362 struct hv_device *device; 363 struct storvsc_softc *sc; 364 struct vmstor_chan_props props; 365 int ret = 0; 366 367 new_channel = (hv_vmbus_channel *)context; 368 device = new_channel->primary_channel->device; 369 sc = get_stor_device(device, TRUE); 370 if (sc == NULL) 371 return; 372 373 if (FALSE == sc->hs_open_multi_channel) 374 return; 375 376 memset(&props, 0, sizeof(props)); 377 378 ret = hv_vmbus_channel_open(new_channel, 379 sc->hs_drv_props->drv_ringbuffer_size, 380 sc->hs_drv_props->drv_ringbuffer_size, 381 (void *)&props, 382 sizeof(struct vmstor_chan_props), 383 hv_storvsc_on_channel_callback, 384 new_channel); 385 386 return; 387} 388 389/** 390 * @brief Send multi-channel creation request to host 391 * 392 * @param device a Hyper-V device pointer 393 * @param max_chans the max channels supported by vmbus 394 */ 395static void 396storvsc_send_multichannel_request(struct hv_device *dev, int max_chans) 397{ 398 struct storvsc_softc *sc; 399 struct hv_storvsc_request *request; 400 struct vstor_packet *vstor_packet; 401 int request_channels_cnt = 0; 402 int ret; 403 404 /* get multichannels count that need to create */ 405 request_channels_cnt = MIN(max_chans, mp_ncpus); 406 407 sc = get_stor_device(dev, TRUE); 408 if (sc == NULL) { 409 printf("Storvsc_error: get sc failed while send mutilchannel " 410 "request\n"); 411 return; 412 } 413 414 request = &sc->hs_init_req; 415 416 /* Establish a handler for multi-channel */ 417 dev->channel->sc_creation_callback = storvsc_handle_sc_creation; 418 419 /* request the host to create multi-channel */ 420 memset(request, 0, sizeof(struct hv_storvsc_request)); 421 422 sema_init(&request->synch_sema, 0, ("stor_synch_sema")); 423 424 vstor_packet = &request->vstor_packet; 425 426 vstor_packet->operation = VSTOR_OPERATION_CREATE_MULTI_CHANNELS; 427 vstor_packet->flags = REQUEST_COMPLETION_FLAG; 428 vstor_packet->u.multi_channels_cnt = request_channels_cnt; 429 430 ret = hv_vmbus_channel_send_packet( 431 dev->channel, 432 vstor_packet, 433 VSTOR_PKT_SIZE, 434 (uint64_t)(uintptr_t)request, 435 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 436 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 437 438 /* wait for 5 seconds */ 439 ret = sema_timedwait(&request->synch_sema, 5 * hz); 440 if (ret != 0) { 441 printf("Storvsc_error: create multi-channel timeout, %d\n", 442 ret); 443 return; 444 } 445 446 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO || 447 vstor_packet->status != 0) { 448 printf("Storvsc_error: create multi-channel invalid operation " 449 "(%d) or statue (%u)\n", 450 vstor_packet->operation, vstor_packet->status); 451 return; 452 } 453 454 sc->hs_open_multi_channel = TRUE; 455 456 if (bootverbose) 457 printf("Storvsc create multi-channel success!\n"); 458} 459 460/** 461 * @brief initialize channel connection to parent partition 462 * 463 * @param dev a Hyper-V device pointer 464 * @returns 0 on success, non-zero error on failure 465 */ 466static int 467hv_storvsc_channel_init(struct hv_device *dev) 468{ 469 int ret = 0, i; 470 struct hv_storvsc_request *request; 471 struct vstor_packet *vstor_packet; 472 struct storvsc_softc *sc; 473 uint16_t max_chans = 0; 474 boolean_t support_multichannel = FALSE; 475 476 max_chans = 0; 477 support_multichannel = FALSE; 478 479 sc = get_stor_device(dev, TRUE); 480 if (sc == NULL) 481 return (ENODEV); 482 483 request = &sc->hs_init_req; 484 memset(request, 0, sizeof(struct hv_storvsc_request)); 485 vstor_packet = &request->vstor_packet; 486 request->softc = sc; 487 488 /** 489 * Initiate the vsc/vsp initialization protocol on the open channel 490 */ 491 sema_init(&request->synch_sema, 0, ("stor_synch_sema")); 492 493 vstor_packet->operation = VSTOR_OPERATION_BEGININITIALIZATION; 494 vstor_packet->flags = REQUEST_COMPLETION_FLAG; 495 496 497 ret = hv_vmbus_channel_send_packet( 498 dev->channel, 499 vstor_packet, 500 VSTOR_PKT_SIZE, 501 (uint64_t)(uintptr_t)request, 502 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 503 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 504 505 if (ret != 0) 506 goto cleanup; 507 508 /* wait 5 seconds */ 509 ret = sema_timedwait(&request->synch_sema, 5 * hz); 510 if (ret != 0) 511 goto cleanup; 512 513 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO || 514 vstor_packet->status != 0) { 515 goto cleanup; 516 } 517 518 for (i = 0; i < nitems(vmstor_proto_list); i++) { 519 /* reuse the packet for version range supported */ 520 521 memset(vstor_packet, 0, sizeof(struct vstor_packet)); 522 vstor_packet->operation = VSTOR_OPERATION_QUERYPROTOCOLVERSION; 523 vstor_packet->flags = REQUEST_COMPLETION_FLAG; 524 525 vstor_packet->u.version.major_minor = 526 vmstor_proto_list[i].proto_version; 527 528 /* revision is only significant for Windows guests */ 529 vstor_packet->u.version.revision = 0; 530 531 ret = hv_vmbus_channel_send_packet( 532 dev->channel, 533 vstor_packet, 534 VSTOR_PKT_SIZE, 535 (uint64_t)(uintptr_t)request, 536 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 537 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 538 539 if (ret != 0) 540 goto cleanup; 541 542 /* wait 5 seconds */ 543 ret = sema_timedwait(&request->synch_sema, 5 * hz); 544 545 if (ret) 546 goto cleanup; 547 548 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO) { 549 ret = EINVAL; 550 goto cleanup; 551 } 552 if (vstor_packet->status == 0) { 553 vmstor_proto_version = 554 vmstor_proto_list[i].proto_version; 555 sense_buffer_size = 556 vmstor_proto_list[i].sense_buffer_size; 557 vmscsi_size_delta = 558 vmstor_proto_list[i].vmscsi_size_delta; 559 break; 560 } 561 } 562 563 if (vstor_packet->status != 0) { 564 ret = EINVAL; 565 goto cleanup; 566 } 567 /** 568 * Query channel properties 569 */ 570 memset(vstor_packet, 0, sizeof(struct vstor_packet)); 571 vstor_packet->operation = VSTOR_OPERATION_QUERYPROPERTIES; 572 vstor_packet->flags = REQUEST_COMPLETION_FLAG; 573 574 ret = hv_vmbus_channel_send_packet( 575 dev->channel, 576 vstor_packet, 577 VSTOR_PKT_SIZE, 578 (uint64_t)(uintptr_t)request, 579 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 580 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 581 582 if ( ret != 0) 583 goto cleanup; 584 585 /* wait 5 seconds */ 586 ret = sema_timedwait(&request->synch_sema, 5 * hz); 587 588 if (ret != 0) 589 goto cleanup; 590 591 /* TODO: Check returned version */ 592 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO || 593 vstor_packet->status != 0) { 594 goto cleanup; 595 } 596 597 /* multi-channels feature is supported by WIN8 and above version */ 598 max_chans = vstor_packet->u.chan_props.max_channel_cnt; 599 if ((hv_vmbus_protocal_version != HV_VMBUS_VERSION_WIN7) && 600 (hv_vmbus_protocal_version != HV_VMBUS_VERSION_WS2008) && 601 (vstor_packet->u.chan_props.flags & 602 HV_STORAGE_SUPPORTS_MULTI_CHANNEL)) { 603 support_multichannel = TRUE; 604 } 605 606 memset(vstor_packet, 0, sizeof(struct vstor_packet)); 607 vstor_packet->operation = VSTOR_OPERATION_ENDINITIALIZATION; 608 vstor_packet->flags = REQUEST_COMPLETION_FLAG; 609 610 ret = hv_vmbus_channel_send_packet( 611 dev->channel, 612 vstor_packet, 613 VSTOR_PKT_SIZE, 614 (uint64_t)(uintptr_t)request, 615 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 616 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 617 618 if (ret != 0) { 619 goto cleanup; 620 } 621 622 /* wait 5 seconds */ 623 ret = sema_timedwait(&request->synch_sema, 5 * hz); 624 625 if (ret != 0) 626 goto cleanup; 627 628 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO || 629 vstor_packet->status != 0) 630 goto cleanup; 631 632 /* 633 * If multi-channel is supported, send multichannel create 634 * request to host. 635 */ 636 if (support_multichannel) 637 storvsc_send_multichannel_request(dev, max_chans); 638 639cleanup: 640 sema_destroy(&request->synch_sema); 641 return (ret); 642} 643 644/** 645 * @brief Open channel connection to paraent partition StorVSP driver 646 * 647 * Open and initialize channel connection to parent partition StorVSP driver. 648 * 649 * @param pointer to a Hyper-V device 650 * @returns 0 on success, non-zero error on failure 651 */ 652static int 653hv_storvsc_connect_vsp(struct hv_device *dev) 654{ 655 int ret = 0; 656 struct vmstor_chan_props props; 657 struct storvsc_softc *sc; 658 659 sc = device_get_softc(dev->device); 660 661 memset(&props, 0, sizeof(struct vmstor_chan_props)); 662 663 /* 664 * Open the channel 665 */ 666 667 ret = hv_vmbus_channel_open( 668 dev->channel, 669 sc->hs_drv_props->drv_ringbuffer_size, 670 sc->hs_drv_props->drv_ringbuffer_size, 671 (void *)&props, 672 sizeof(struct vmstor_chan_props), 673 hv_storvsc_on_channel_callback, 674 dev->channel); 675 676 if (ret != 0) { 677 return ret; 678 } 679 680 ret = hv_storvsc_channel_init(dev); 681 682 return (ret); 683} 684 685#if HVS_HOST_RESET 686static int 687hv_storvsc_host_reset(struct hv_device *dev) 688{ 689 int ret = 0; 690 struct storvsc_softc *sc; 691 692 struct hv_storvsc_request *request; 693 struct vstor_packet *vstor_packet; 694 695 sc = get_stor_device(dev, TRUE); 696 if (sc == NULL) { 697 return ENODEV; 698 } 699 700 request = &sc->hs_reset_req; 701 request->softc = sc; 702 vstor_packet = &request->vstor_packet; 703 704 sema_init(&request->synch_sema, 0, "stor synch sema"); 705 706 vstor_packet->operation = VSTOR_OPERATION_RESETBUS; 707 vstor_packet->flags = REQUEST_COMPLETION_FLAG; 708 709 ret = hv_vmbus_channel_send_packet(dev->channel, 710 vstor_packet, 711 VSTOR_PKT_SIZE, 712 (uint64_t)(uintptr_t)&sc->hs_reset_req, 713 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 714 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 715 716 if (ret != 0) { 717 goto cleanup; 718 } 719 720 ret = sema_timedwait(&request->synch_sema, 5 * hz); /* KYS 5 seconds */ 721 722 if (ret) { 723 goto cleanup; 724 } 725 726 727 /* 728 * At this point, all outstanding requests in the adapter 729 * should have been flushed out and return to us 730 */ 731 732cleanup: 733 sema_destroy(&request->synch_sema); 734 return (ret); 735} 736#endif /* HVS_HOST_RESET */ 737 738/** 739 * @brief Function to initiate an I/O request 740 * 741 * @param device Hyper-V device pointer 742 * @param request pointer to a request structure 743 * @returns 0 on success, non-zero error on failure 744 */ 745static int 746hv_storvsc_io_request(struct hv_device *device, 747 struct hv_storvsc_request *request) 748{ 749 struct storvsc_softc *sc; 750 struct vstor_packet *vstor_packet = &request->vstor_packet; 751 struct hv_vmbus_channel* outgoing_channel = NULL; 752 int ret = 0; 753 754 sc = get_stor_device(device, TRUE); 755 756 if (sc == NULL) { 757 return ENODEV; 758 } 759 760 vstor_packet->flags |= REQUEST_COMPLETION_FLAG; 761 762 vstor_packet->u.vm_srb.length = VSTOR_PKT_SIZE; 763 764 vstor_packet->u.vm_srb.sense_info_len = sense_buffer_size; 765 766 vstor_packet->u.vm_srb.transfer_len = request->data_buf.length; 767 768 vstor_packet->operation = VSTOR_OPERATION_EXECUTESRB; 769 770 outgoing_channel = vmbus_select_outgoing_channel(device->channel); 771 772 mtx_unlock(&request->softc->hs_lock); 773 if (request->data_buf.length) { 774 ret = hv_vmbus_channel_send_packet_multipagebuffer( 775 outgoing_channel, 776 &request->data_buf, 777 vstor_packet, 778 VSTOR_PKT_SIZE, 779 (uint64_t)(uintptr_t)request); 780 781 } else { 782 ret = hv_vmbus_channel_send_packet( 783 outgoing_channel, 784 vstor_packet, 785 VSTOR_PKT_SIZE, 786 (uint64_t)(uintptr_t)request, 787 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 788 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 789 } 790 mtx_lock(&request->softc->hs_lock); 791 792 if (ret != 0) { 793 printf("Unable to send packet %p ret %d", vstor_packet, ret); 794 } else { 795 atomic_add_int(&sc->hs_num_out_reqs, 1); 796 } 797 798 return (ret); 799} 800 801 802/** 803 * Process IO_COMPLETION_OPERATION and ready 804 * the result to be completed for upper layer 805 * processing by the CAM layer. 806 */ 807static void 808hv_storvsc_on_iocompletion(struct storvsc_softc *sc, 809 struct vstor_packet *vstor_packet, 810 struct hv_storvsc_request *request) 811{ 812 struct vmscsi_req *vm_srb; 813 814 vm_srb = &vstor_packet->u.vm_srb; 815 816 if (((vm_srb->scsi_status & 0xFF) == SCSI_STATUS_CHECK_COND) && 817 (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)) { 818 /* Autosense data available */ 819 820 KASSERT(vm_srb->sense_info_len <= request->sense_info_len, 821 ("vm_srb->sense_info_len <= " 822 "request->sense_info_len")); 823 824 memcpy(request->sense_data, vm_srb->u.sense_data, 825 vm_srb->sense_info_len); 826 827 request->sense_info_len = vm_srb->sense_info_len; 828 } 829 830 /* Complete request by passing to the CAM layer */ 831 storvsc_io_done(request); 832 atomic_subtract_int(&sc->hs_num_out_reqs, 1); 833 if (sc->hs_drain_notify && (sc->hs_num_out_reqs == 0)) { 834 sema_post(&sc->hs_drain_sema); 835 } 836} 837 838static void 839hv_storvsc_rescan_target(struct storvsc_softc *sc) 840{ 841 path_id_t pathid; 842 target_id_t targetid; 843 union ccb *ccb; 844 845 pathid = cam_sim_path(sc->hs_sim); 846 targetid = CAM_TARGET_WILDCARD; 847 848 /* 849 * Allocate a CCB and schedule a rescan. 850 */ 851 ccb = xpt_alloc_ccb_nowait(); 852 if (ccb == NULL) { 853 printf("unable to alloc CCB for rescan\n"); 854 return; 855 } 856 857 if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, targetid, 858 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 859 printf("unable to create path for rescan, pathid: %u," 860 "targetid: %u\n", pathid, targetid); 861 xpt_free_ccb(ccb); 862 return; 863 } 864 865 if (targetid == CAM_TARGET_WILDCARD) 866 ccb->ccb_h.func_code = XPT_SCAN_BUS; 867 else 868 ccb->ccb_h.func_code = XPT_SCAN_TGT; 869 870 xpt_rescan(ccb); 871} 872 873static void 874hv_storvsc_on_channel_callback(void *context) 875{ 876 int ret = 0; 877 hv_vmbus_channel *channel = (hv_vmbus_channel *)context; 878 struct hv_device *device = NULL; 879 struct storvsc_softc *sc; 880 uint32_t bytes_recvd; 881 uint64_t request_id; 882 uint8_t packet[roundup2(sizeof(struct vstor_packet), 8)]; 883 struct hv_storvsc_request *request; 884 struct vstor_packet *vstor_packet; 885 886 if (channel->primary_channel != NULL){ 887 device = channel->primary_channel->device; 888 } else { 889 device = channel->device; 890 } 891 892 KASSERT(device, ("device is NULL")); 893 894 sc = get_stor_device(device, FALSE); 895 if (sc == NULL) { 896 printf("Storvsc_error: get stor device failed.\n"); 897 return; 898 } 899 900 ret = hv_vmbus_channel_recv_packet( 901 channel, 902 packet, 903 roundup2(VSTOR_PKT_SIZE, 8), 904 &bytes_recvd, 905 &request_id); 906 907 while ((ret == 0) && (bytes_recvd > 0)) { 908 request = (struct hv_storvsc_request *)(uintptr_t)request_id; 909 910 if ((request == &sc->hs_init_req) || 911 (request == &sc->hs_reset_req)) { 912 memcpy(&request->vstor_packet, packet, 913 sizeof(struct vstor_packet)); 914 sema_post(&request->synch_sema); 915 } else { 916 vstor_packet = (struct vstor_packet *)packet; 917 switch(vstor_packet->operation) { 918 case VSTOR_OPERATION_COMPLETEIO: 919 if (request == NULL) 920 panic("VMBUS: storvsc received a " 921 "packet with NULL request id in " 922 "COMPLETEIO operation."); 923 924 hv_storvsc_on_iocompletion(sc, 925 vstor_packet, request); 926 break; 927 case VSTOR_OPERATION_REMOVEDEVICE: 928 printf("VMBUS: storvsc operation %d not " 929 "implemented.\n", vstor_packet->operation); 930 /* TODO: implement */ 931 break; 932 case VSTOR_OPERATION_ENUMERATE_BUS: 933 hv_storvsc_rescan_target(sc); 934 break; 935 default: 936 break; 937 } 938 } 939 ret = hv_vmbus_channel_recv_packet( 940 channel, 941 packet, 942 roundup2(VSTOR_PKT_SIZE, 8), 943 &bytes_recvd, 944 &request_id); 945 } 946} 947 948/** 949 * @brief StorVSC probe function 950 * 951 * Device probe function. Returns 0 if the input device is a StorVSC 952 * device. Otherwise, a ENXIO is returned. If the input device is 953 * for BlkVSC (paravirtual IDE) device and this support is disabled in 954 * favor of the emulated ATA/IDE device, return ENXIO. 955 * 956 * @param a device 957 * @returns 0 on success, ENXIO if not a matcing StorVSC device 958 */ 959static int 960storvsc_probe(device_t dev) 961{ 962 int ata_disk_enable = 0; 963 int ret = ENXIO; 964 965 switch (storvsc_get_storage_type(dev)) { 966 case DRIVER_BLKVSC: 967 if(bootverbose) 968 device_printf(dev, "DRIVER_BLKVSC-Emulated ATA/IDE probe\n"); 969 if (!getenv_int("hw.ata.disk_enable", &ata_disk_enable)) { 970 if(bootverbose) 971 device_printf(dev, 972 "Enlightened ATA/IDE detected\n"); 973 ret = BUS_PROBE_DEFAULT; 974 } else if(bootverbose) 975 device_printf(dev, "Emulated ATA/IDE set (hw.ata.disk_enable set)\n"); 976 break; 977 case DRIVER_STORVSC: 978 if(bootverbose) 979 device_printf(dev, "Enlightened SCSI device detected\n"); 980 ret = BUS_PROBE_DEFAULT; 981 break; 982 default: 983 ret = ENXIO; 984 } 985 return (ret); 986} 987 988/** 989 * @brief StorVSC attach function 990 * 991 * Function responsible for allocating per-device structures, 992 * setting up CAM interfaces and scanning for available LUNs to 993 * be used for SCSI device peripherals. 994 * 995 * @param a device 996 * @returns 0 on success or an error on failure 997 */ 998static int 999storvsc_attach(device_t dev) 1000{ 1001 struct hv_device *hv_dev = vmbus_get_devctx(dev); 1002 enum hv_storage_type stor_type; 1003 struct storvsc_softc *sc; 1004 struct cam_devq *devq; 1005 int ret, i, j; 1006 struct hv_storvsc_request *reqp; 1007 struct root_hold_token *root_mount_token = NULL; 1008 struct hv_sgl_node *sgl_node = NULL; 1009 void *tmp_buff = NULL; 1010 1011 /* 1012 * We need to serialize storvsc attach calls. 1013 */ 1014 root_mount_token = root_mount_hold("storvsc"); 1015 1016 sc = device_get_softc(dev); 1017 if (sc == NULL) { 1018 ret = ENOMEM; 1019 goto cleanup; 1020 } 1021 1022 stor_type = storvsc_get_storage_type(dev); 1023 1024 if (stor_type == DRIVER_UNKNOWN) { 1025 ret = ENODEV; 1026 goto cleanup; 1027 } 1028 1029 bzero(sc, sizeof(struct storvsc_softc)); 1030 1031 /* fill in driver specific properties */ 1032 sc->hs_drv_props = &g_drv_props_table[stor_type]; 1033 1034 /* fill in device specific properties */ 1035 sc->hs_unit = device_get_unit(dev); 1036 sc->hs_dev = hv_dev; 1037 device_set_desc(dev, g_drv_props_table[stor_type].drv_desc); 1038 1039 LIST_INIT(&sc->hs_free_list); 1040 mtx_init(&sc->hs_lock, "hvslck", NULL, MTX_DEF); 1041 1042 for (i = 0; i < sc->hs_drv_props->drv_max_ios_per_target; ++i) { 1043 reqp = malloc(sizeof(struct hv_storvsc_request), 1044 M_DEVBUF, M_WAITOK|M_ZERO); 1045 reqp->softc = sc; 1046 1047 LIST_INSERT_HEAD(&sc->hs_free_list, reqp, link); 1048 } 1049 1050 /* create sg-list page pool */ 1051 if (FALSE == g_hv_sgl_page_pool.is_init) { 1052 g_hv_sgl_page_pool.is_init = TRUE; 1053 LIST_INIT(&g_hv_sgl_page_pool.in_use_sgl_list); 1054 LIST_INIT(&g_hv_sgl_page_pool.free_sgl_list); 1055 1056 /* 1057 * Pre-create SG list, each SG list with 1058 * HV_MAX_MULTIPAGE_BUFFER_COUNT segments, each 1059 * segment has one page buffer 1060 */ 1061 for (i = 0; i < STORVSC_MAX_IO_REQUESTS; i++) { 1062 sgl_node = malloc(sizeof(struct hv_sgl_node), 1063 M_DEVBUF, M_WAITOK|M_ZERO); 1064 1065 sgl_node->sgl_data = 1066 sglist_alloc(HV_MAX_MULTIPAGE_BUFFER_COUNT, 1067 M_WAITOK|M_ZERO); 1068 1069 for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++) { 1070 tmp_buff = malloc(PAGE_SIZE, 1071 M_DEVBUF, M_WAITOK|M_ZERO); 1072 1073 sgl_node->sgl_data->sg_segs[j].ss_paddr = 1074 (vm_paddr_t)tmp_buff; 1075 } 1076 1077 LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list, 1078 sgl_node, link); 1079 } 1080 } 1081 1082 sc->hs_destroy = FALSE; 1083 sc->hs_drain_notify = FALSE; 1084 sc->hs_open_multi_channel = FALSE; 1085 sema_init(&sc->hs_drain_sema, 0, "Store Drain Sema"); 1086 1087 ret = hv_storvsc_connect_vsp(hv_dev); 1088 if (ret != 0) { 1089 goto cleanup; 1090 } 1091 1092 /* 1093 * Create the device queue. 1094 * Hyper-V maps each target to one SCSI HBA 1095 */ 1096 devq = cam_simq_alloc(sc->hs_drv_props->drv_max_ios_per_target); 1097 if (devq == NULL) { 1098 device_printf(dev, "Failed to alloc device queue\n"); 1099 ret = ENOMEM; 1100 goto cleanup; 1101 } 1102 1103 sc->hs_sim = cam_sim_alloc(storvsc_action, 1104 storvsc_poll, 1105 sc->hs_drv_props->drv_name, 1106 sc, 1107 sc->hs_unit, 1108 &sc->hs_lock, 1, 1109 sc->hs_drv_props->drv_max_ios_per_target, 1110 devq); 1111 1112 if (sc->hs_sim == NULL) { 1113 device_printf(dev, "Failed to alloc sim\n"); 1114 cam_simq_free(devq); 1115 ret = ENOMEM; 1116 goto cleanup; 1117 } 1118 1119 mtx_lock(&sc->hs_lock); 1120 /* bus_id is set to 0, need to get it from VMBUS channel query? */ 1121 if (xpt_bus_register(sc->hs_sim, dev, 0) != CAM_SUCCESS) { 1122 cam_sim_free(sc->hs_sim, /*free_devq*/TRUE); 1123 mtx_unlock(&sc->hs_lock); 1124 device_printf(dev, "Unable to register SCSI bus\n"); 1125 ret = ENXIO; 1126 goto cleanup; 1127 } 1128 1129 if (xpt_create_path(&sc->hs_path, /*periph*/NULL, 1130 cam_sim_path(sc->hs_sim), 1131 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1132 xpt_bus_deregister(cam_sim_path(sc->hs_sim)); 1133 cam_sim_free(sc->hs_sim, /*free_devq*/TRUE); 1134 mtx_unlock(&sc->hs_lock); 1135 device_printf(dev, "Unable to create path\n"); 1136 ret = ENXIO; 1137 goto cleanup; 1138 } 1139 1140 mtx_unlock(&sc->hs_lock); 1141 1142 root_mount_rel(root_mount_token); 1143 return (0); 1144 1145 1146cleanup: 1147 root_mount_rel(root_mount_token); 1148 while (!LIST_EMPTY(&sc->hs_free_list)) { 1149 reqp = LIST_FIRST(&sc->hs_free_list); 1150 LIST_REMOVE(reqp, link); 1151 free(reqp, M_DEVBUF); 1152 } 1153 1154 while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) { 1155 sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list); 1156 LIST_REMOVE(sgl_node, link); 1157 for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++) { 1158 if (NULL != 1159 (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) { 1160 free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF); 1161 } 1162 } 1163 sglist_free(sgl_node->sgl_data); 1164 free(sgl_node, M_DEVBUF); 1165 } 1166 1167 return (ret); 1168} 1169 1170/** 1171 * @brief StorVSC device detach function 1172 * 1173 * This function is responsible for safely detaching a 1174 * StorVSC device. This includes waiting for inbound responses 1175 * to complete and freeing associated per-device structures. 1176 * 1177 * @param dev a device 1178 * returns 0 on success 1179 */ 1180static int 1181storvsc_detach(device_t dev) 1182{ 1183 struct storvsc_softc *sc = device_get_softc(dev); 1184 struct hv_storvsc_request *reqp = NULL; 1185 struct hv_device *hv_device = vmbus_get_devctx(dev); 1186 struct hv_sgl_node *sgl_node = NULL; 1187 int j = 0; 1188 1189 mtx_lock(&hv_device->channel->inbound_lock); 1190 sc->hs_destroy = TRUE; 1191 mtx_unlock(&hv_device->channel->inbound_lock); 1192 1193 /* 1194 * At this point, all outbound traffic should be disabled. We 1195 * only allow inbound traffic (responses) to proceed so that 1196 * outstanding requests can be completed. 1197 */ 1198 1199 sc->hs_drain_notify = TRUE; 1200 sema_wait(&sc->hs_drain_sema); 1201 sc->hs_drain_notify = FALSE; 1202 1203 /* 1204 * Since we have already drained, we don't need to busy wait. 1205 * The call to close the channel will reset the callback 1206 * under the protection of the incoming channel lock. 1207 */ 1208 1209 hv_vmbus_channel_close(hv_device->channel); 1210 1211 mtx_lock(&sc->hs_lock); 1212 while (!LIST_EMPTY(&sc->hs_free_list)) { 1213 reqp = LIST_FIRST(&sc->hs_free_list); 1214 LIST_REMOVE(reqp, link); 1215 1216 free(reqp, M_DEVBUF); 1217 } 1218 mtx_unlock(&sc->hs_lock); 1219 1220 while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) { 1221 sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list); 1222 LIST_REMOVE(sgl_node, link); 1223 for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++){ 1224 if (NULL != 1225 (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) { 1226 free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF); 1227 } 1228 } 1229 sglist_free(sgl_node->sgl_data); 1230 free(sgl_node, M_DEVBUF); 1231 } 1232 1233 return (0); 1234} 1235 1236#if HVS_TIMEOUT_TEST 1237/** 1238 * @brief unit test for timed out operations 1239 * 1240 * This function provides unit testing capability to simulate 1241 * timed out operations. Recompilation with HV_TIMEOUT_TEST=1 1242 * is required. 1243 * 1244 * @param reqp pointer to a request structure 1245 * @param opcode SCSI operation being performed 1246 * @param wait if 1, wait for I/O to complete 1247 */ 1248static void 1249storvsc_timeout_test(struct hv_storvsc_request *reqp, 1250 uint8_t opcode, int wait) 1251{ 1252 int ret; 1253 union ccb *ccb = reqp->ccb; 1254 struct storvsc_softc *sc = reqp->softc; 1255 1256 if (reqp->vstor_packet.vm_srb.cdb[0] != opcode) { 1257 return; 1258 } 1259 1260 if (wait) { 1261 mtx_lock(&reqp->event.mtx); 1262 } 1263 ret = hv_storvsc_io_request(sc->hs_dev, reqp); 1264 if (ret != 0) { 1265 if (wait) { 1266 mtx_unlock(&reqp->event.mtx); 1267 } 1268 printf("%s: io_request failed with %d.\n", 1269 __func__, ret); 1270 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 1271 mtx_lock(&sc->hs_lock); 1272 storvsc_free_request(sc, reqp); 1273 xpt_done(ccb); 1274 mtx_unlock(&sc->hs_lock); 1275 return; 1276 } 1277 1278 if (wait) { 1279 xpt_print(ccb->ccb_h.path, 1280 "%u: %s: waiting for IO return.\n", 1281 ticks, __func__); 1282 ret = cv_timedwait(&reqp->event.cv, &reqp->event.mtx, 60*hz); 1283 mtx_unlock(&reqp->event.mtx); 1284 xpt_print(ccb->ccb_h.path, "%u: %s: %s.\n", 1285 ticks, __func__, (ret == 0)? 1286 "IO return detected" : 1287 "IO return not detected"); 1288 /* 1289 * Now both the timer handler and io done are running 1290 * simultaneously. We want to confirm the io done always 1291 * finishes after the timer handler exits. So reqp used by 1292 * timer handler is not freed or stale. Do busy loop for 1293 * another 1/10 second to make sure io done does 1294 * wait for the timer handler to complete. 1295 */ 1296 DELAY(100*1000); 1297 mtx_lock(&sc->hs_lock); 1298 xpt_print(ccb->ccb_h.path, 1299 "%u: %s: finishing, queue frozen %d, " 1300 "ccb status 0x%x scsi_status 0x%x.\n", 1301 ticks, __func__, sc->hs_frozen, 1302 ccb->ccb_h.status, 1303 ccb->csio.scsi_status); 1304 mtx_unlock(&sc->hs_lock); 1305 } 1306} 1307#endif /* HVS_TIMEOUT_TEST */ 1308 1309#ifdef notyet 1310/** 1311 * @brief timeout handler for requests 1312 * 1313 * This function is called as a result of a callout expiring. 1314 * 1315 * @param arg pointer to a request 1316 */ 1317static void 1318storvsc_timeout(void *arg) 1319{ 1320 struct hv_storvsc_request *reqp = arg; 1321 struct storvsc_softc *sc = reqp->softc; 1322 union ccb *ccb = reqp->ccb; 1323 1324 if (reqp->retries == 0) { 1325 mtx_lock(&sc->hs_lock); 1326 xpt_print(ccb->ccb_h.path, 1327 "%u: IO timed out (req=0x%p), wait for another %u secs.\n", 1328 ticks, reqp, ccb->ccb_h.timeout / 1000); 1329 cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL); 1330 mtx_unlock(&sc->hs_lock); 1331 1332 reqp->retries++; 1333 callout_reset_sbt(&reqp->callout, SBT_1MS * ccb->ccb_h.timeout, 1334 0, storvsc_timeout, reqp, 0); 1335#if HVS_TIMEOUT_TEST 1336 storvsc_timeout_test(reqp, SEND_DIAGNOSTIC, 0); 1337#endif 1338 return; 1339 } 1340 1341 mtx_lock(&sc->hs_lock); 1342 xpt_print(ccb->ccb_h.path, 1343 "%u: IO (reqp = 0x%p) did not return for %u seconds, %s.\n", 1344 ticks, reqp, ccb->ccb_h.timeout * (reqp->retries+1) / 1000, 1345 (sc->hs_frozen == 0)? 1346 "freezing the queue" : "the queue is already frozen"); 1347 if (sc->hs_frozen == 0) { 1348 sc->hs_frozen = 1; 1349 xpt_freeze_simq(xpt_path_sim(ccb->ccb_h.path), 1); 1350 } 1351 mtx_unlock(&sc->hs_lock); 1352 1353#if HVS_TIMEOUT_TEST 1354 storvsc_timeout_test(reqp, MODE_SELECT_10, 1); 1355#endif 1356} 1357#endif 1358 1359/** 1360 * @brief StorVSC device poll function 1361 * 1362 * This function is responsible for servicing requests when 1363 * interrupts are disabled (i.e when we are dumping core.) 1364 * 1365 * @param sim a pointer to a CAM SCSI interface module 1366 */ 1367static void 1368storvsc_poll(struct cam_sim *sim) 1369{ 1370 struct storvsc_softc *sc = cam_sim_softc(sim); 1371 1372 mtx_assert(&sc->hs_lock, MA_OWNED); 1373 mtx_unlock(&sc->hs_lock); 1374 hv_storvsc_on_channel_callback(sc->hs_dev->channel); 1375 mtx_lock(&sc->hs_lock); 1376} 1377 1378/** 1379 * @brief StorVSC device action function 1380 * 1381 * This function is responsible for handling SCSI operations which 1382 * are passed from the CAM layer. The requests are in the form of 1383 * CAM control blocks which indicate the action being performed. 1384 * Not all actions require converting the request to a VSCSI protocol 1385 * message - these actions can be responded to by this driver. 1386 * Requests which are destined for a backend storage device are converted 1387 * to a VSCSI protocol message and sent on the channel connection associated 1388 * with this device. 1389 * 1390 * @param sim pointer to a CAM SCSI interface module 1391 * @param ccb pointer to a CAM control block 1392 */ 1393static void 1394storvsc_action(struct cam_sim *sim, union ccb *ccb) 1395{ 1396 struct storvsc_softc *sc = cam_sim_softc(sim); 1397 int res; 1398 1399 mtx_assert(&sc->hs_lock, MA_OWNED); 1400 switch (ccb->ccb_h.func_code) { 1401 case XPT_PATH_INQ: { 1402 struct ccb_pathinq *cpi = &ccb->cpi; 1403 1404 cpi->version_num = 1; 1405 cpi->hba_inquiry = PI_TAG_ABLE|PI_SDTR_ABLE; 1406 cpi->target_sprt = 0; 1407 cpi->hba_misc = PIM_NOBUSRESET; 1408 cpi->hba_eng_cnt = 0; 1409 cpi->max_target = STORVSC_MAX_TARGETS; 1410 cpi->max_lun = sc->hs_drv_props->drv_max_luns_per_target; 1411 cpi->initiator_id = cpi->max_target; 1412 cpi->bus_id = cam_sim_bus(sim); 1413 cpi->base_transfer_speed = 300000; 1414 cpi->transport = XPORT_SAS; 1415 cpi->transport_version = 0; 1416 cpi->protocol = PROTO_SCSI; 1417 cpi->protocol_version = SCSI_REV_SPC2; 1418 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1419 strncpy(cpi->hba_vid, sc->hs_drv_props->drv_name, HBA_IDLEN); 1420 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1421 cpi->unit_number = cam_sim_unit(sim); 1422 1423 ccb->ccb_h.status = CAM_REQ_CMP; 1424 xpt_done(ccb); 1425 return; 1426 } 1427 case XPT_GET_TRAN_SETTINGS: { 1428 struct ccb_trans_settings *cts = &ccb->cts; 1429 1430 cts->transport = XPORT_SAS; 1431 cts->transport_version = 0; 1432 cts->protocol = PROTO_SCSI; 1433 cts->protocol_version = SCSI_REV_SPC2; 1434 1435 /* enable tag queuing and disconnected mode */ 1436 cts->proto_specific.valid = CTS_SCSI_VALID_TQ; 1437 cts->proto_specific.scsi.valid = CTS_SCSI_VALID_TQ; 1438 cts->proto_specific.scsi.flags = CTS_SCSI_FLAGS_TAG_ENB; 1439 cts->xport_specific.valid = CTS_SPI_VALID_DISC; 1440 cts->xport_specific.spi.flags = CTS_SPI_FLAGS_DISC_ENB; 1441 1442 ccb->ccb_h.status = CAM_REQ_CMP; 1443 xpt_done(ccb); 1444 return; 1445 } 1446 case XPT_SET_TRAN_SETTINGS: { 1447 ccb->ccb_h.status = CAM_REQ_CMP; 1448 xpt_done(ccb); 1449 return; 1450 } 1451 case XPT_CALC_GEOMETRY:{ 1452 cam_calc_geometry(&ccb->ccg, 1); 1453 xpt_done(ccb); 1454 return; 1455 } 1456 case XPT_RESET_BUS: 1457 case XPT_RESET_DEV:{ 1458#if HVS_HOST_RESET 1459 if ((res = hv_storvsc_host_reset(sc->hs_dev)) != 0) { 1460 xpt_print(ccb->ccb_h.path, 1461 "hv_storvsc_host_reset failed with %d\n", res); 1462 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 1463 xpt_done(ccb); 1464 return; 1465 } 1466 ccb->ccb_h.status = CAM_REQ_CMP; 1467 xpt_done(ccb); 1468 return; 1469#else 1470 xpt_print(ccb->ccb_h.path, 1471 "%s reset not supported.\n", 1472 (ccb->ccb_h.func_code == XPT_RESET_BUS)? 1473 "bus" : "dev"); 1474 ccb->ccb_h.status = CAM_REQ_INVALID; 1475 xpt_done(ccb); 1476 return; 1477#endif /* HVS_HOST_RESET */ 1478 } 1479 case XPT_SCSI_IO: 1480 case XPT_IMMED_NOTIFY: { 1481 struct hv_storvsc_request *reqp = NULL; 1482 1483 if (ccb->csio.cdb_len == 0) { 1484 panic("cdl_len is 0\n"); 1485 } 1486 1487 if (LIST_EMPTY(&sc->hs_free_list)) { 1488 ccb->ccb_h.status = CAM_REQUEUE_REQ; 1489 if (sc->hs_frozen == 0) { 1490 sc->hs_frozen = 1; 1491 xpt_freeze_simq(sim, /* count*/1); 1492 } 1493 xpt_done(ccb); 1494 return; 1495 } 1496 1497 reqp = LIST_FIRST(&sc->hs_free_list); 1498 LIST_REMOVE(reqp, link); 1499 1500 bzero(reqp, sizeof(struct hv_storvsc_request)); 1501 reqp->softc = sc; 1502 1503 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1504 if ((res = create_storvsc_request(ccb, reqp)) != 0) { 1505 ccb->ccb_h.status = CAM_REQ_INVALID; 1506 xpt_done(ccb); 1507 return; 1508 } 1509 1510#ifdef notyet 1511 if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) { 1512 callout_init(&reqp->callout, CALLOUT_MPSAFE); 1513 callout_reset_sbt(&reqp->callout, 1514 SBT_1MS * ccb->ccb_h.timeout, 0, 1515 storvsc_timeout, reqp, 0); 1516#if HVS_TIMEOUT_TEST 1517 cv_init(&reqp->event.cv, "storvsc timeout cv"); 1518 mtx_init(&reqp->event.mtx, "storvsc timeout mutex", 1519 NULL, MTX_DEF); 1520 switch (reqp->vstor_packet.vm_srb.cdb[0]) { 1521 case MODE_SELECT_10: 1522 case SEND_DIAGNOSTIC: 1523 /* To have timer send the request. */ 1524 return; 1525 default: 1526 break; 1527 } 1528#endif /* HVS_TIMEOUT_TEST */ 1529 } 1530#endif 1531 1532 if ((res = hv_storvsc_io_request(sc->hs_dev, reqp)) != 0) { 1533 xpt_print(ccb->ccb_h.path, 1534 "hv_storvsc_io_request failed with %d\n", res); 1535 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 1536 storvsc_free_request(sc, reqp); 1537 xpt_done(ccb); 1538 return; 1539 } 1540 return; 1541 } 1542 1543 default: 1544 ccb->ccb_h.status = CAM_REQ_INVALID; 1545 xpt_done(ccb); 1546 return; 1547 } 1548} 1549 1550/** 1551 * @brief destroy bounce buffer 1552 * 1553 * This function is responsible for destroy a Scatter/Gather list 1554 * that create by storvsc_create_bounce_buffer() 1555 * 1556 * @param sgl- the Scatter/Gather need be destroy 1557 * @param sg_count- page count of the SG list. 1558 * 1559 */ 1560static void 1561storvsc_destroy_bounce_buffer(struct sglist *sgl) 1562{ 1563 struct hv_sgl_node *sgl_node = NULL; 1564 if (LIST_EMPTY(&g_hv_sgl_page_pool.in_use_sgl_list)) { 1565 printf("storvsc error: not enough in use sgl\n"); 1566 return; 1567 } 1568 sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.in_use_sgl_list); 1569 LIST_REMOVE(sgl_node, link); 1570 sgl_node->sgl_data = sgl; 1571 LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list, sgl_node, link); 1572} 1573 1574/** 1575 * @brief create bounce buffer 1576 * 1577 * This function is responsible for create a Scatter/Gather list, 1578 * which hold several pages that can be aligned with page size. 1579 * 1580 * @param seg_count- SG-list segments count 1581 * @param write - if WRITE_TYPE, set SG list page used size to 0, 1582 * otherwise set used size to page size. 1583 * 1584 * return NULL if create failed 1585 */ 1586static struct sglist * 1587storvsc_create_bounce_buffer(uint16_t seg_count, int write) 1588{ 1589 int i = 0; 1590 struct sglist *bounce_sgl = NULL; 1591 unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE); 1592 struct hv_sgl_node *sgl_node = NULL; 1593 1594 /* get struct sglist from free_sgl_list */ 1595 if (LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) { 1596 printf("storvsc error: not enough free sgl\n"); 1597 return NULL; 1598 } 1599 sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list); 1600 LIST_REMOVE(sgl_node, link); 1601 bounce_sgl = sgl_node->sgl_data; 1602 LIST_INSERT_HEAD(&g_hv_sgl_page_pool.in_use_sgl_list, sgl_node, link); 1603 1604 bounce_sgl->sg_maxseg = seg_count; 1605 1606 if (write == WRITE_TYPE) 1607 bounce_sgl->sg_nseg = 0; 1608 else 1609 bounce_sgl->sg_nseg = seg_count; 1610 1611 for (i = 0; i < seg_count; i++) 1612 bounce_sgl->sg_segs[i].ss_len = buf_len; 1613 1614 return bounce_sgl; 1615} 1616 1617/** 1618 * @brief copy data from SG list to bounce buffer 1619 * 1620 * This function is responsible for copy data from one SG list's segments 1621 * to another SG list which used as bounce buffer. 1622 * 1623 * @param bounce_sgl - the destination SG list 1624 * @param orig_sgl - the segment of the source SG list. 1625 * @param orig_sgl_count - the count of segments. 1626 * @param orig_sgl_count - indicate which segment need bounce buffer, 1627 * set 1 means need. 1628 * 1629 */ 1630static void 1631storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl, 1632 bus_dma_segment_t *orig_sgl, 1633 unsigned int orig_sgl_count, 1634 uint64_t seg_bits) 1635{ 1636 int src_sgl_idx = 0; 1637 1638 for (src_sgl_idx = 0; src_sgl_idx < orig_sgl_count; src_sgl_idx++) { 1639 if (seg_bits & (1 << src_sgl_idx)) { 1640 memcpy((void*)bounce_sgl->sg_segs[src_sgl_idx].ss_paddr, 1641 (void*)orig_sgl[src_sgl_idx].ds_addr, 1642 orig_sgl[src_sgl_idx].ds_len); 1643 1644 bounce_sgl->sg_segs[src_sgl_idx].ss_len = 1645 orig_sgl[src_sgl_idx].ds_len; 1646 } 1647 } 1648} 1649 1650/** 1651 * @brief copy data from SG list which used as bounce to another SG list 1652 * 1653 * This function is responsible for copy data from one SG list with bounce 1654 * buffer to another SG list's segments. 1655 * 1656 * @param dest_sgl - the destination SG list's segments 1657 * @param dest_sgl_count - the count of destination SG list's segment. 1658 * @param src_sgl - the source SG list. 1659 * @param seg_bits - indicate which segment used bounce buffer of src SG-list. 1660 * 1661 */ 1662void 1663storvsc_copy_from_bounce_buf_to_sgl(bus_dma_segment_t *dest_sgl, 1664 unsigned int dest_sgl_count, 1665 struct sglist* src_sgl, 1666 uint64_t seg_bits) 1667{ 1668 int sgl_idx = 0; 1669 1670 for (sgl_idx = 0; sgl_idx < dest_sgl_count; sgl_idx++) { 1671 if (seg_bits & (1 << sgl_idx)) { 1672 memcpy((void*)(dest_sgl[sgl_idx].ds_addr), 1673 (void*)(src_sgl->sg_segs[sgl_idx].ss_paddr), 1674 src_sgl->sg_segs[sgl_idx].ss_len); 1675 } 1676 } 1677} 1678 1679/** 1680 * @brief check SG list with bounce buffer or not 1681 * 1682 * This function is responsible for check if need bounce buffer for SG list. 1683 * 1684 * @param sgl - the SG list's segments 1685 * @param sg_count - the count of SG list's segment. 1686 * @param bits - segmengs number that need bounce buffer 1687 * 1688 * return -1 if SG list needless bounce buffer 1689 */ 1690static int 1691storvsc_check_bounce_buffer_sgl(bus_dma_segment_t *sgl, 1692 unsigned int sg_count, 1693 uint64_t *bits) 1694{ 1695 int i = 0; 1696 int offset = 0; 1697 uint64_t phys_addr = 0; 1698 uint64_t tmp_bits = 0; 1699 boolean_t found_hole = FALSE; 1700 boolean_t pre_aligned = TRUE; 1701 1702 if (sg_count < 2){ 1703 return -1; 1704 } 1705 1706 *bits = 0; 1707 1708 phys_addr = vtophys(sgl[0].ds_addr); 1709 offset = phys_addr - trunc_page(phys_addr); 1710 1711 if (offset != 0) { 1712 pre_aligned = FALSE; 1713 tmp_bits |= 1; 1714 } 1715 1716 for (i = 1; i < sg_count; i++) { 1717 phys_addr = vtophys(sgl[i].ds_addr); 1718 offset = phys_addr - trunc_page(phys_addr); 1719 1720 if (offset == 0) { 1721 if (FALSE == pre_aligned){ 1722 /* 1723 * This segment is aligned, if the previous 1724 * one is not aligned, find a hole 1725 */ 1726 found_hole = TRUE; 1727 } 1728 pre_aligned = TRUE; 1729 } else { 1730 tmp_bits |= 1 << i; 1731 if (!pre_aligned) { 1732 if (phys_addr != vtophys(sgl[i-1].ds_addr + 1733 sgl[i-1].ds_len)) { 1734 /* 1735 * Check whether connect to previous 1736 * segment,if not, find the hole 1737 */ 1738 found_hole = TRUE; 1739 } 1740 } else { 1741 found_hole = TRUE; 1742 } 1743 pre_aligned = FALSE; 1744 } 1745 } 1746 1747 if (!found_hole) { 1748 return (-1); 1749 } else { 1750 *bits = tmp_bits; 1751 return 0; 1752 } 1753} 1754 1755/** 1756 * @brief Fill in a request structure based on a CAM control block 1757 * 1758 * Fills in a request structure based on the contents of a CAM control 1759 * block. The request structure holds the payload information for 1760 * VSCSI protocol request. 1761 * 1762 * @param ccb pointer to a CAM contorl block 1763 * @param reqp pointer to a request structure 1764 */ 1765static int 1766create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp) 1767{ 1768 struct ccb_scsiio *csio = &ccb->csio; 1769 uint64_t phys_addr; 1770 uint32_t bytes_to_copy = 0; 1771 uint32_t pfn_num = 0; 1772 uint32_t pfn; 1773 uint64_t not_aligned_seg_bits = 0; 1774 1775 /* refer to struct vmscsi_req for meanings of these two fields */ 1776 reqp->vstor_packet.u.vm_srb.port = 1777 cam_sim_unit(xpt_path_sim(ccb->ccb_h.path)); 1778 reqp->vstor_packet.u.vm_srb.path_id = 1779 cam_sim_bus(xpt_path_sim(ccb->ccb_h.path)); 1780 1781 reqp->vstor_packet.u.vm_srb.target_id = ccb->ccb_h.target_id; 1782 reqp->vstor_packet.u.vm_srb.lun = ccb->ccb_h.target_lun; 1783 1784 reqp->vstor_packet.u.vm_srb.cdb_len = csio->cdb_len; 1785 if(ccb->ccb_h.flags & CAM_CDB_POINTER) { 1786 memcpy(&reqp->vstor_packet.u.vm_srb.u.cdb, csio->cdb_io.cdb_ptr, 1787 csio->cdb_len); 1788 } else { 1789 memcpy(&reqp->vstor_packet.u.vm_srb.u.cdb, csio->cdb_io.cdb_bytes, 1790 csio->cdb_len); 1791 } 1792 1793 switch (ccb->ccb_h.flags & CAM_DIR_MASK) { 1794 case CAM_DIR_OUT: 1795 reqp->vstor_packet.u.vm_srb.data_in = WRITE_TYPE; 1796 break; 1797 case CAM_DIR_IN: 1798 reqp->vstor_packet.u.vm_srb.data_in = READ_TYPE; 1799 break; 1800 case CAM_DIR_NONE: 1801 reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE; 1802 break; 1803 default: 1804 reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE; 1805 break; 1806 } 1807 1808 reqp->sense_data = &csio->sense_data; 1809 reqp->sense_info_len = csio->sense_len; 1810 1811 reqp->ccb = ccb; 1812 1813 if (0 == csio->dxfer_len) { 1814 return (0); 1815 } 1816 1817 reqp->data_buf.length = csio->dxfer_len; 1818 1819 switch (ccb->ccb_h.flags & CAM_DATA_MASK) { 1820 case CAM_DATA_VADDR: 1821 { 1822 bytes_to_copy = csio->dxfer_len; 1823 phys_addr = vtophys(csio->data_ptr); 1824 reqp->data_buf.offset = phys_addr & PAGE_MASK; 1825 1826 while (bytes_to_copy != 0) { 1827 int bytes, page_offset; 1828 phys_addr = 1829 vtophys(&csio->data_ptr[reqp->data_buf.length - 1830 bytes_to_copy]); 1831 pfn = phys_addr >> PAGE_SHIFT; 1832 reqp->data_buf.pfn_array[pfn_num] = pfn; 1833 page_offset = phys_addr & PAGE_MASK; 1834 1835 bytes = min(PAGE_SIZE - page_offset, bytes_to_copy); 1836 1837 bytes_to_copy -= bytes; 1838 pfn_num++; 1839 } 1840 break; 1841 } 1842 1843 case CAM_DATA_SG: 1844 { 1845 int i = 0; 1846 int offset = 0; 1847 int ret; 1848 1849 bus_dma_segment_t *storvsc_sglist = 1850 (bus_dma_segment_t *)ccb->csio.data_ptr; 1851 u_int16_t storvsc_sg_count = ccb->csio.sglist_cnt; 1852 1853 printf("Storvsc: get SG I/O operation, %d\n", 1854 reqp->vstor_packet.u.vm_srb.data_in); 1855 1856 if (storvsc_sg_count > HV_MAX_MULTIPAGE_BUFFER_COUNT){ 1857 printf("Storvsc: %d segments is too much, " 1858 "only support %d segments\n", 1859 storvsc_sg_count, HV_MAX_MULTIPAGE_BUFFER_COUNT); 1860 return (EINVAL); 1861 } 1862 1863 /* 1864 * We create our own bounce buffer function currently. Idealy 1865 * we should use BUS_DMA(9) framework. But with current BUS_DMA 1866 * code there is no callback API to check the page alignment of 1867 * middle segments before busdma can decide if a bounce buffer 1868 * is needed for particular segment. There is callback, 1869 * "bus_dma_filter_t *filter", but the parrameters are not 1870 * sufficient for storvsc driver. 1871 * TODO: 1872 * Add page alignment check in BUS_DMA(9) callback. Once 1873 * this is complete, switch the following code to use 1874 * BUS_DMA(9) for storvsc bounce buffer support. 1875 */ 1876 /* check if we need to create bounce buffer */ 1877 ret = storvsc_check_bounce_buffer_sgl(storvsc_sglist, 1878 storvsc_sg_count, ¬_aligned_seg_bits); 1879 if (ret != -1) { 1880 reqp->bounce_sgl = 1881 storvsc_create_bounce_buffer(storvsc_sg_count, 1882 reqp->vstor_packet.u.vm_srb.data_in); 1883 if (NULL == reqp->bounce_sgl) { 1884 printf("Storvsc_error: " 1885 "create bounce buffer failed.\n"); 1886 return (ENOMEM); 1887 } 1888 1889 reqp->bounce_sgl_count = storvsc_sg_count; 1890 reqp->not_aligned_seg_bits = not_aligned_seg_bits; 1891 1892 /* 1893 * if it is write, we need copy the original data 1894 *to bounce buffer 1895 */ 1896 if (WRITE_TYPE == reqp->vstor_packet.u.vm_srb.data_in) { 1897 storvsc_copy_sgl_to_bounce_buf( 1898 reqp->bounce_sgl, 1899 storvsc_sglist, 1900 storvsc_sg_count, 1901 reqp->not_aligned_seg_bits); 1902 } 1903 1904 /* transfer virtual address to physical frame number */ 1905 if (reqp->not_aligned_seg_bits & 0x1){ 1906 phys_addr = 1907 vtophys(reqp->bounce_sgl->sg_segs[0].ss_paddr); 1908 }else{ 1909 phys_addr = 1910 vtophys(storvsc_sglist[0].ds_addr); 1911 } 1912 reqp->data_buf.offset = phys_addr & PAGE_MASK; 1913 1914 pfn = phys_addr >> PAGE_SHIFT; 1915 reqp->data_buf.pfn_array[0] = pfn; 1916 1917 for (i = 1; i < storvsc_sg_count; i++) { 1918 if (reqp->not_aligned_seg_bits & (1 << i)) { 1919 phys_addr = 1920 vtophys(reqp->bounce_sgl->sg_segs[i].ss_paddr); 1921 } else { 1922 phys_addr = 1923 vtophys(storvsc_sglist[i].ds_addr); 1924 } 1925 1926 pfn = phys_addr >> PAGE_SHIFT; 1927 reqp->data_buf.pfn_array[i] = pfn; 1928 } 1929 } else { 1930 phys_addr = vtophys(storvsc_sglist[0].ds_addr); 1931 1932 reqp->data_buf.offset = phys_addr & PAGE_MASK; 1933 1934 for (i = 0; i < storvsc_sg_count; i++) { 1935 phys_addr = vtophys(storvsc_sglist[i].ds_addr); 1936 pfn = phys_addr >> PAGE_SHIFT; 1937 reqp->data_buf.pfn_array[i] = pfn; 1938 } 1939 1940 /* check the last segment cross boundary or not */ 1941 offset = phys_addr & PAGE_MASK; 1942 if (offset) { 1943 phys_addr = 1944 vtophys(storvsc_sglist[i-1].ds_addr + 1945 PAGE_SIZE - offset); 1946 pfn = phys_addr >> PAGE_SHIFT; 1947 reqp->data_buf.pfn_array[i] = pfn; 1948 } 1949 1950 reqp->bounce_sgl_count = 0; 1951 } 1952 break; 1953 } 1954 default: 1955 printf("Unknow flags: %d\n", ccb->ccb_h.flags); 1956 return(EINVAL); 1957 } 1958 1959 return(0); 1960} 1961 1962/* 1963 * Modified based on scsi_print_inquiry which is responsible to 1964 * print the detail information for scsi_inquiry_data. 1965 * 1966 * Return 1 if it is valid, 0 otherwise. 1967 */ 1968static inline int 1969is_inquiry_valid(const struct scsi_inquiry_data *inq_data) 1970{ 1971 uint8_t type; 1972 char vendor[16], product[48], revision[16]; 1973 1974 /* 1975 * Check device type and qualifier 1976 */ 1977 if (!(SID_QUAL_IS_VENDOR_UNIQUE(inq_data) || 1978 SID_QUAL(inq_data) == SID_QUAL_LU_CONNECTED)) 1979 return (0); 1980 1981 type = SID_TYPE(inq_data); 1982 switch (type) { 1983 case T_DIRECT: 1984 case T_SEQUENTIAL: 1985 case T_PRINTER: 1986 case T_PROCESSOR: 1987 case T_WORM: 1988 case T_CDROM: 1989 case T_SCANNER: 1990 case T_OPTICAL: 1991 case T_CHANGER: 1992 case T_COMM: 1993 case T_STORARRAY: 1994 case T_ENCLOSURE: 1995 case T_RBC: 1996 case T_OCRW: 1997 case T_OSD: 1998 case T_ADC: 1999 break; 2000 case T_NODEVICE: 2001 default: 2002 return (0); 2003 } 2004 2005 /* 2006 * Check vendor, product, and revision 2007 */ 2008 cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor), 2009 sizeof(vendor)); 2010 cam_strvis(product, inq_data->product, sizeof(inq_data->product), 2011 sizeof(product)); 2012 cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision), 2013 sizeof(revision)); 2014 if (strlen(vendor) == 0 || 2015 strlen(product) == 0 || 2016 strlen(revision) == 0) 2017 return (0); 2018 2019 return (1); 2020} 2021 2022/** 2023 * @brief completion function before returning to CAM 2024 * 2025 * I/O process has been completed and the result needs 2026 * to be passed to the CAM layer. 2027 * Free resources related to this request. 2028 * 2029 * @param reqp pointer to a request structure 2030 */ 2031static void 2032storvsc_io_done(struct hv_storvsc_request *reqp) 2033{ 2034 union ccb *ccb = reqp->ccb; 2035 struct ccb_scsiio *csio = &ccb->csio; 2036 struct storvsc_softc *sc = reqp->softc; 2037 struct vmscsi_req *vm_srb = &reqp->vstor_packet.u.vm_srb; 2038 bus_dma_segment_t *ori_sglist = NULL; 2039 int ori_sg_count = 0; 2040 2041 /* destroy bounce buffer if it is used */ 2042 if (reqp->bounce_sgl_count) { 2043 ori_sglist = (bus_dma_segment_t *)ccb->csio.data_ptr; 2044 ori_sg_count = ccb->csio.sglist_cnt; 2045 2046 /* 2047 * If it is READ operation, we should copy back the data 2048 * to original SG list. 2049 */ 2050 if (READ_TYPE == reqp->vstor_packet.u.vm_srb.data_in) { 2051 storvsc_copy_from_bounce_buf_to_sgl(ori_sglist, 2052 ori_sg_count, 2053 reqp->bounce_sgl, 2054 reqp->not_aligned_seg_bits); 2055 } 2056 2057 storvsc_destroy_bounce_buffer(reqp->bounce_sgl); 2058 reqp->bounce_sgl_count = 0; 2059 } 2060 2061 if (reqp->retries > 0) { 2062 mtx_lock(&sc->hs_lock); 2063#if HVS_TIMEOUT_TEST 2064 xpt_print(ccb->ccb_h.path, 2065 "%u: IO returned after timeout, " 2066 "waking up timer handler if any.\n", ticks); 2067 mtx_lock(&reqp->event.mtx); 2068 cv_signal(&reqp->event.cv); 2069 mtx_unlock(&reqp->event.mtx); 2070#endif 2071 reqp->retries = 0; 2072 xpt_print(ccb->ccb_h.path, 2073 "%u: IO returned after timeout, " 2074 "stopping timer if any.\n", ticks); 2075 mtx_unlock(&sc->hs_lock); 2076 } 2077 2078#ifdef notyet 2079 /* 2080 * callout_drain() will wait for the timer handler to finish 2081 * if it is running. So we don't need any lock to synchronize 2082 * between this routine and the timer handler. 2083 * Note that we need to make sure reqp is not freed when timer 2084 * handler is using or will use it. 2085 */ 2086 if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) { 2087 callout_drain(&reqp->callout); 2088 } 2089#endif 2090 2091 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 2092 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2093 if (vm_srb->scsi_status == SCSI_STATUS_OK) { 2094 const struct scsi_generic *cmd; 2095 2096 /* 2097 * Check whether the data for INQUIRY cmd is valid or 2098 * not. Windows 10 and Windows 2016 send all zero 2099 * inquiry data to VM even for unpopulated slots. 2100 */ 2101 cmd = (const struct scsi_generic *) 2102 ((ccb->ccb_h.flags & CAM_CDB_POINTER) ? 2103 csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes); 2104 if (cmd->opcode == INQUIRY && 2105 /* 2106 * XXX: Temporary work around disk hot plugin on win2k12r2, 2107 * only filtering the invalid disk on win10 or 2016 server. 2108 * So, the hot plugin on win10 and 2016 server needs 2109 * to be fixed. 2110 */ 2111 vmstor_proto_version == VMSTOR_PROTOCOL_VERSION_WIN10 && 2112 is_inquiry_valid( 2113 (const struct scsi_inquiry_data *)csio->data_ptr) == 0) { 2114 ccb->ccb_h.status |= CAM_DEV_NOT_THERE; 2115 if (bootverbose) { 2116 mtx_lock(&sc->hs_lock); 2117 xpt_print(ccb->ccb_h.path, 2118 "storvsc uninstalled device\n"); 2119 mtx_unlock(&sc->hs_lock); 2120 } 2121 } else { 2122 ccb->ccb_h.status |= CAM_REQ_CMP; 2123 } 2124 } else { 2125 mtx_lock(&sc->hs_lock); 2126 xpt_print(ccb->ccb_h.path, 2127 "storvsc scsi_status = %d\n", 2128 vm_srb->scsi_status); 2129 mtx_unlock(&sc->hs_lock); 2130 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 2131 } 2132 2133 ccb->csio.scsi_status = (vm_srb->scsi_status & 0xFF); 2134 ccb->csio.resid = ccb->csio.dxfer_len - vm_srb->transfer_len; 2135 2136 if (reqp->sense_info_len != 0) { 2137 csio->sense_resid = csio->sense_len - reqp->sense_info_len; 2138 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 2139 } 2140 2141 mtx_lock(&sc->hs_lock); 2142 if (reqp->softc->hs_frozen == 1) { 2143 xpt_print(ccb->ccb_h.path, 2144 "%u: storvsc unfreezing softc 0x%p.\n", 2145 ticks, reqp->softc); 2146 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 2147 reqp->softc->hs_frozen = 0; 2148 } 2149 storvsc_free_request(sc, reqp); 2150 xpt_done(ccb); 2151 mtx_unlock(&sc->hs_lock); 2152} 2153 2154/** 2155 * @brief Free a request structure 2156 * 2157 * Free a request structure by returning it to the free list 2158 * 2159 * @param sc pointer to a softc 2160 * @param reqp pointer to a request structure 2161 */ 2162static void 2163storvsc_free_request(struct storvsc_softc *sc, struct hv_storvsc_request *reqp) 2164{ 2165 2166 LIST_INSERT_HEAD(&sc->hs_free_list, reqp, link); 2167} 2168 2169/** 2170 * @brief Determine type of storage device from GUID 2171 * 2172 * Using the type GUID, determine if this is a StorVSC (paravirtual 2173 * SCSI or BlkVSC (paravirtual IDE) device. 2174 * 2175 * @param dev a device 2176 * returns an enum 2177 */ 2178static enum hv_storage_type 2179storvsc_get_storage_type(device_t dev) 2180{ 2181 const char *p = vmbus_get_type(dev); 2182 2183 if (!memcmp(p, &gBlkVscDeviceType, sizeof(hv_guid))) { 2184 return DRIVER_BLKVSC; 2185 } else if (!memcmp(p, &gStorVscDeviceType, sizeof(hv_guid))) { 2186 return DRIVER_STORVSC; 2187 } 2188 return (DRIVER_UNKNOWN); 2189} 2190 2191