freebsd-dev/sys/dev/hyperv/storvsc/hv_vstorage.h
Andriy Gapon efdba95d62 storvsc: port a Linux patch, properly set residual data length on errors
This change is based on Linux commit 40630f462824ee.  csio.resid should
account for transfer_len only for success and SRB_STATUS_DATA_OVERRUN
condition.

I am not sure how exactly this change works, but I have a report from a
user that they see lots of checksum errors when running a pool scrub
concurrently with iozone -l 1 -s 100G.  After applying this patch the
problem cannot be reproduced.

Reviewed by:	nobody
Sponsored by:	CyberSecure
Differential Revision: https://reviews.freebsd.org/D22312
2020-01-14 13:20:16 +00:00

290 lines
7.8 KiB
C

/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009-2012,2017 Microsoft Corp.
* Copyright (c) 2012 NetApp Inc.
* Copyright (c) 2012 Citrix Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __HV_VSTORAGE_H__
#define __HV_VSTORAGE_H__
/*
* Major/minor macros. Minor version is in LSB, meaning that earlier flat
* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1).
*/
#define VMSTOR_PROTOCOL_MAJOR(VERSION_) (((VERSION_) >> 8) & 0xff)
#define VMSTOR_PROTOCOL_MINOR(VERSION_) (((VERSION_) ) & 0xff)
#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \
(((MINOR_) & 0xff) ))
#define VMSTOR_PROTOCOL_VERSION_WIN6 VMSTOR_PROTOCOL_VERSION(2, 0)
#define VMSTOR_PROTOCOL_VERSION_WIN7 VMSTOR_PROTOCOL_VERSION(4, 2)
#define VMSTOR_PROTOCOL_VERSION_WIN8 VMSTOR_PROTOCOL_VERSION(5, 1)
#define VMSTOR_PROTOCOL_VERSION_WIN8_1 VMSTOR_PROTOCOL_VERSION(6, 0)
#define VMSTOR_PROTOCOL_VERSION_WIN10 VMSTOR_PROTOCOL_VERSION(6, 2)
/*
* Invalid version.
*/
#define VMSTOR_INVALID_PROTOCOL_VERSION -1
/*
* Version history:
* V1 Beta 0.1
* V1 RC < 2008/1/31 1.0
* V1 RC > 2008/1/31 2.0
* Win7: 4.2
* Win8: 5.1
*/
#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(5, 1)
/**
* Packet structure ops describing virtual storage requests.
*/
enum vstor_packet_ops {
VSTOR_OPERATION_COMPLETEIO = 1,
VSTOR_OPERATION_REMOVEDEVICE = 2,
VSTOR_OPERATION_EXECUTESRB = 3,
VSTOR_OPERATION_RESETLUN = 4,
VSTOR_OPERATION_RESETADAPTER = 5,
VSTOR_OPERATION_RESETBUS = 6,
VSTOR_OPERATION_BEGININITIALIZATION = 7,
VSTOR_OPERATION_ENDINITIALIZATION = 8,
VSTOR_OPERATION_QUERYPROTOCOLVERSION = 9,
VSTOR_OPERATION_QUERYPROPERTIES = 10,
VSTOR_OPERATION_ENUMERATE_BUS = 11,
VSTOR_OPERATION_FCHBA_DATA = 12,
VSTOR_OPERATION_CREATE_MULTI_CHANNELS = 13,
VSTOR_OPERATION_MAXIMUM = 13
};
/*
* Platform neutral description of a scsi request -
* this remains the same across the write regardless of 32/64 bit
* note: it's patterned off the Windows DDK SCSI_PASS_THROUGH structure
*/
#define CDB16GENERIC_LENGTH 0x10
#define SENSE_BUFFER_SIZE 0x14
#define MAX_DATA_BUFFER_LENGTH_WITH_PADDING 0x14
#define POST_WIN7_STORVSC_SENSE_BUFFER_SIZE 0x14
#define PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE 0x12
struct vmscsi_win8_extension {
/*
* The following were added in Windows 8
*/
uint16_t reserve;
uint8_t queue_tag;
uint8_t queue_action;
uint32_t srb_flags;
uint32_t time_out_value;
uint32_t queue_sort_ey;
} __packed;
struct vmscsi_req {
uint16_t length;
uint8_t srb_status;
uint8_t scsi_status;
/* HBA number, set to the order number detected by initiator. */
uint8_t port;
/* SCSI bus number or bus_id, different from CAM's path_id. */
uint8_t path_id;
uint8_t target_id;
uint8_t lun;
uint8_t cdb_len;
uint8_t sense_info_len;
uint8_t data_in;
uint8_t reserved;
uint32_t transfer_len;
union {
uint8_t cdb[CDB16GENERIC_LENGTH];
uint8_t sense_data[SENSE_BUFFER_SIZE];
uint8_t reserved_array[MAX_DATA_BUFFER_LENGTH_WITH_PADDING];
} u;
/*
* The following was added in win8.
*/
struct vmscsi_win8_extension win8_extension;
} __packed;
/**
* This structure is sent during the initialization phase to get the different
* properties of the channel.
*/
struct vmstor_chan_props {
uint16_t proto_ver;
uint8_t path_id;
uint8_t target_id;
uint16_t max_channel_cnt;
/**
* Note: port number is only really known on the client side
*/
uint16_t port;
uint32_t flags;
uint32_t max_transfer_bytes;
/**
* This id is unique for each channel and will correspond with
* vendor specific data in the inquiry_ata
*/
uint64_t unique_id;
} __packed;
/**
* This structure is sent during the storage protocol negotiations.
*/
struct vmstor_proto_ver
{
/**
* Major (MSW) and minor (LSW) version numbers.
*/
uint16_t major_minor;
uint16_t revision; /* always zero */
} __packed;
/**
* Channel Property Flags
*/
#define STORAGE_CHANNEL_REMOVABLE_FLAG 0x1
#define STORAGE_CHANNEL_EMULATED_IDE_FLAG 0x2
struct vstor_packet {
/**
* Requested operation type
*/
enum vstor_packet_ops operation;
/*
* Flags - see below for values
*/
uint32_t flags;
/**
* Status of the request returned from the server side.
*/
uint32_t status;
union
{
/**
* Structure used to forward SCSI commands from the client to
* the server.
*/
struct vmscsi_req vm_srb;
/**
* Structure used to query channel properties.
*/
struct vmstor_chan_props chan_props;
/**
* Used during version negotiations.
*/
struct vmstor_proto_ver version;
/**
* Number of multichannels to create
*/
uint16_t multi_channels_cnt;
} u;
} __packed;
/**
* SRB (SCSI Request Block) Status Codes
*/
#define SRB_STATUS_PENDING 0x00
#define SRB_STATUS_SUCCESS 0x01
#define SRB_STATUS_ABORTED 0x02
#define SRB_STATUS_ERROR 0x04
#define SRB_STATUS_DATA_OVERRUN 0x12
#define SRB_STATUS_INVALID_LUN 0x20
/**
* SRB Status Masks (can be combined with above status codes)
*/
#define SRB_STATUS_QUEUE_FROZEN 0x40
#define SRB_STATUS_AUTOSENSE_VALID 0x80
#define SRB_STATUS(status) \
((status) & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
/*
* SRB Flag Bits
*/
#define SRB_FLAGS_QUEUE_ACTION_ENABLE 0x00000002
#define SRB_FLAGS_DISABLE_DISCONNECT 0x00000004
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER 0x00000008
#define SRB_FLAGS_BYPASS_FROZEN_QUEUE 0x00000010
#define SRB_FLAGS_DISABLE_AUTOSENSE 0x00000020
#define SRB_FLAGS_DATA_IN 0x00000040
#define SRB_FLAGS_DATA_OUT 0x00000080
#define SRB_FLAGS_NO_DATA_TRANSFER 0x00000000
#define SRB_FLAGS_UNSPECIFIED_DIRECTION (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)
#define SRB_FLAGS_NO_QUEUE_FREEZE 0x00000100
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE 0x00000200
#define SRB_FLAGS_FREE_SENSE_BUFFER 0x00000400
/**
* Packet flags
*/
/**
* This flag indicates that the server should send back a completion for this
* packet.
*/
#define REQUEST_COMPLETION_FLAG 0x1
/**
* This is the set of flags that the vsc can set in any packets it sends
*/
#define VSC_LEGAL_FLAGS (REQUEST_COMPLETION_FLAG)
#endif /* __HV_VSTORAGE_H__ */