#include <linux/kernel.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/hyperv.h>
#include <linux/blkdev.h>
#include <linux/dma-mapping.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_devinfo.h>
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_transport_fc.h>
#include <scsi/scsi_transport.h>
#define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_) …
#define VMSTOR_PROTO_VERSION_WIN6 …
#define VMSTOR_PROTO_VERSION_WIN7 …
#define VMSTOR_PROTO_VERSION_WIN8 …
#define VMSTOR_PROTO_VERSION_WIN8_1 …
#define VMSTOR_PROTO_VERSION_WIN10 …
#define CALLBACK_TIMEOUT …
enum vstor_packet_operation { … };
struct hv_fc_wwn_packet { … };
#define SRB_FLAGS_QUEUE_ACTION_ENABLE …
#define SRB_FLAGS_DISABLE_DISCONNECT …
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER …
#define SRB_FLAGS_BYPASS_FROZEN_QUEUE …
#define SRB_FLAGS_DISABLE_AUTOSENSE …
#define SRB_FLAGS_DATA_IN …
#define SRB_FLAGS_DATA_OUT …
#define SRB_FLAGS_NO_DATA_TRANSFER …
#define SRB_FLAGS_UNSPECIFIED_DIRECTION …
#define SRB_FLAGS_NO_QUEUE_FREEZE …
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE …
#define SRB_FLAGS_FREE_SENSE_BUFFER …
#define SRB_FLAGS_D3_PROCESSING …
#define SRB_FLAGS_IS_ACTIVE …
#define SRB_FLAGS_ALLOCATED_FROM_ZONE …
#define SRB_FLAGS_SGLIST_FROM_POOL …
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE …
#define SRB_FLAGS_NO_KEEP_AWAKE …
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE …
#define SRB_FLAGS_PORT_DRIVER_SENSEHASPORT …
#define SRB_FLAGS_DONT_START_NEXT_PACKET …
#define SRB_FLAGS_PORT_DRIVER_RESERVED …
#define SRB_FLAGS_CLASS_DRIVER_RESERVED …
#define SP_UNTAGGED …
#define SRB_SIMPLE_TAG_REQUEST …
#define STORVSC_MAX_CMD_LEN …
#define STORVSC_SENSE_BUFFER_SIZE …
#define STORVSC_MAX_BUF_LEN_WITH_PADDING …
static int vmstor_proto_version;
#define STORVSC_LOGGING_NONE …
#define STORVSC_LOGGING_ERROR …
#define STORVSC_LOGGING_WARN …
static int logging_level = …;
module_param(logging_level, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
static inline bool do_logging(int level)
{ … }
#define storvsc_log(dev, level, fmt, ...) …
struct vmscsi_request { … } __attribute((packed));
static const int protocol_version[] = …;
#define STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL …
struct vmstorage_channel_properties { … } __packed;
struct vmstorage_protocol_version { … } __packed;
#define STORAGE_CHANNEL_REMOVABLE_FLAG …
#define STORAGE_CHANNEL_EMULATED_IDE_FLAG …
struct vstor_packet { … } __packed;
#define REQUEST_COMPLETION_FLAG …
enum storvsc_request_type { … };
#define SRB_STATUS_AUTOSENSE_VALID …
#define SRB_STATUS_QUEUE_FROZEN …
#define SRB_STATUS_SUCCESS …
#define SRB_STATUS_ABORTED …
#define SRB_STATUS_ERROR …
#define SRB_STATUS_INVALID_REQUEST …
#define SRB_STATUS_TIMEOUT …
#define SRB_STATUS_SELECTION_TIMEOUT …
#define SRB_STATUS_BUS_RESET …
#define SRB_STATUS_DATA_OVERRUN …
#define SRB_STATUS_INVALID_LUN …
#define SRB_STATUS_INTERNAL_ERROR …
#define SRB_STATUS(status) …
static int storvsc_ringbuffer_size = …;
static int aligned_ringbuffer_size;
static u32 max_outstanding_req_per_channel;
static int storvsc_change_queue_depth(struct scsi_device *sdev, int queue_depth);
static int storvsc_vcpus_per_sub_channel = …;
static unsigned int storvsc_max_hw_queues;
module_param(storvsc_ringbuffer_size, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
module_param(storvsc_max_hw_queues, uint, 0644);
MODULE_PARM_DESC(…) …;
module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
static int ring_avail_percent_lowater = …;
module_param(ring_avail_percent_lowater, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
static int storvsc_timeout = …;
#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
static struct scsi_transport_template *fc_transport_template;
#endif
static struct scsi_host_template scsi_driver;
static void storvsc_on_channel_callback(void *context);
#define STORVSC_MAX_LUNS_PER_TARGET …
#define STORVSC_MAX_TARGETS …
#define STORVSC_MAX_CHANNELS …
#define STORVSC_FC_MAX_LUNS_PER_TARGET …
#define STORVSC_FC_MAX_TARGETS …
#define STORVSC_FC_MAX_CHANNELS …
#define STORVSC_FC_MAX_XFER_SIZE …
#define STORVSC_IDE_MAX_LUNS_PER_TARGET …
#define STORVSC_IDE_MAX_TARGETS …
#define STORVSC_IDE_MAX_CHANNELS …
#define STORVSC_MAX_PKT_SIZE …
struct storvsc_cmd_request { … };
struct storvsc_device { … };
struct hv_host_device { … };
struct storvsc_scan_work { … };
static void storvsc_device_scan(struct work_struct *work)
{ … }
static void storvsc_host_scan(struct work_struct *work)
{ … }
static void storvsc_remove_lun(struct work_struct *work)
{ … }
static inline struct storvsc_device *get_out_stor_device(
struct hv_device *device)
{ … }
static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
{ … }
static inline struct storvsc_device *get_in_stor_device(
struct hv_device *device)
{ … }
static void storvsc_change_target_cpu(struct vmbus_channel *channel, u32 old,
u32 new)
{ … }
static u64 storvsc_next_request_id(struct vmbus_channel *channel, u64 rqst_addr)
{ … }
static void handle_sc_creation(struct vmbus_channel *new_sc)
{ … }
static void handle_multichannel_storage(struct hv_device *device, int max_chns)
{ … }
static void cache_wwn(struct storvsc_device *stor_device,
struct vstor_packet *vstor_packet)
{ … }
static int storvsc_execute_vstor_op(struct hv_device *device,
struct storvsc_cmd_request *request,
bool status_check)
{ … }
static int storvsc_channel_init(struct hv_device *device, bool is_fc)
{ … }
static void storvsc_handle_error(struct vmscsi_request *vm_srb,
struct scsi_cmnd *scmnd,
struct Scsi_Host *host,
u8 asc, u8 ascq)
{ … }
static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
struct storvsc_device *stor_dev)
{ … }
static void storvsc_on_io_completion(struct storvsc_device *stor_device,
struct vstor_packet *vstor_packet,
struct storvsc_cmd_request *request)
{ … }
static void storvsc_on_receive(struct storvsc_device *stor_device,
struct vstor_packet *vstor_packet,
struct storvsc_cmd_request *request)
{ … }
static void storvsc_on_channel_callback(void *context)
{ … }
static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size,
bool is_fc)
{ … }
static int storvsc_dev_remove(struct hv_device *device)
{ … }
static struct vmbus_channel *get_og_chn(struct storvsc_device *stor_device,
u16 q_num)
{ … }
static int storvsc_do_io(struct hv_device *device,
struct storvsc_cmd_request *request, u16 q_num)
{ … }
static int storvsc_device_alloc(struct scsi_device *sdevice)
{ … }
static int storvsc_device_configure(struct scsi_device *sdevice)
{ … }
static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
sector_t capacity, int *info)
{ … }
static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
{ … }
static enum scsi_timeout_action storvsc_eh_timed_out(struct scsi_cmnd *scmnd)
{ … }
static bool storvsc_scsi_cmd_ok(struct scsi_cmnd *scmnd)
{ … }
static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
{ … }
static struct scsi_host_template scsi_driver = …;
enum { … };
static const struct hv_vmbus_device_id id_table[] = …;
MODULE_DEVICE_TABLE(vmbus, id_table);
static const struct { … } fc_guid = …;
static bool hv_dev_is_fc(struct hv_device *hv_dev)
{ … }
static int storvsc_probe(struct hv_device *device,
const struct hv_vmbus_device_id *dev_id)
{ … }
static int storvsc_change_queue_depth(struct scsi_device *sdev, int queue_depth)
{ … }
static void storvsc_remove(struct hv_device *dev)
{ … }
static int storvsc_suspend(struct hv_device *hv_dev)
{ … }
static int storvsc_resume(struct hv_device *hv_dev)
{ … }
static struct hv_driver storvsc_drv = …;
#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
static struct fc_function_template fc_transport_functions = …;
#endif
static int __init storvsc_drv_init(void)
{ … }
static void __exit storvsc_drv_exit(void)
{ … }
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;
module_init(…) …;
module_exit(storvsc_drv_exit);