/* * VMware PVSCSI header file * * Copyright (C) 2008-2014, VMware, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; version 2 of the License and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or * NON INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifndef _VMW_PVSCSI_H_ #define _VMW_PVSCSI_H_ #include <linux/types.h> #define PVSCSI_DRIVER_VERSION_STRING … #define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT … #define MASK(n) … #define PCI_DEVICE_ID_VMWARE_PVSCSI … /* * host adapter status/error codes */ enum HostBusAdapterStatus { … }; /* * SCSI device status values. */ enum ScsiDeviceStatus { … }; /* * Register offsets. * * These registers are accessible both via i/o space and mm i/o. */ enum PVSCSIRegOffset { … }; /* * Virtual h/w commands. */ enum PVSCSICommands { … }; /* * Command descriptor for PVSCSI_CMD_RESET_DEVICE -- */ struct PVSCSICmdDescResetDevice { … } __packed; /* * Command descriptor for PVSCSI_CMD_CONFIG -- */ struct PVSCSICmdDescConfigCmd { … } __packed; /* * Command descriptor for PVSCSI_CMD_SETUP_REQCALLTHRESHOLD -- */ struct PVSCSICmdDescSetupReqCall { … } __packed; enum PVSCSIConfigPageType { … }; enum PVSCSIConfigPageAddressType { … }; /* * Command descriptor for PVSCSI_CMD_ABORT_CMD -- * * - currently does not support specifying the LUN. * - _pad should be 0. */ struct PVSCSICmdDescAbortCmd { … } __packed; /* * Command descriptor for PVSCSI_CMD_SETUP_RINGS -- * * Notes: * - reqRingNumPages and cmpRingNumPages need to be power of two. * - reqRingNumPages and cmpRingNumPages need to be different from 0, * - reqRingNumPages and cmpRingNumPages need to be inferior to * PVSCSI_SETUP_RINGS_MAX_NUM_PAGES. */ #define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES … struct PVSCSICmdDescSetupRings { … } __packed; /* * Command descriptor for PVSCSI_CMD_SETUP_MSG_RING -- * * Notes: * - this command was not supported in the initial revision of the h/w * interface. Before using it, you need to check that it is supported by * writing PVSCSI_CMD_SETUP_MSG_RING to the 'command' register, then * immediately after read the 'command status' register: * * a value of -1 means that the cmd is NOT supported, * * a value != -1 means that the cmd IS supported. * If it's supported the 'command status' register should return: * sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(u32). * - this command should be issued _after_ the usual SETUP_RINGS so that the * RingsState page is already setup. If not, the command is a nop. * - numPages needs to be a power of two, * - numPages needs to be different from 0, * - _pad should be zero. */ #define PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES … struct PVSCSICmdDescSetupMsgRing { … } __packed; enum PVSCSIMsgType { … }; /* * Msg descriptor. * * sizeof(struct PVSCSIRingMsgDesc) == 128. * * - type is of type enum PVSCSIMsgType. * - the content of args depend on the type of event being delivered. */ struct PVSCSIRingMsgDesc { … } __packed; struct PVSCSIMsgDescDevStatusChanged { … } __packed; /* * Rings state. * * - the fields: * . msgProdIdx, * . msgConsIdx, * . msgNumEntriesLog2, * .. are only used once the SETUP_MSG_RING cmd has been issued. * - '_pad' helps to ensure that the msg related fields are on their own * cache-line. */ struct PVSCSIRingsState { … } __packed; /* * Request descriptor. * * sizeof(RingReqDesc) = 128 * * - context: is a unique identifier of a command. It could normally be any * 64bit value, however we currently store it in the serialNumber variable * of struct SCSI_Command, so we have the following restrictions due to the * way this field is handled in the vmkernel storage stack: * * this value can't be 0, * * the upper 32bit need to be 0 since serialNumber is as a u32. * Currently tracked as PR 292060. * - dataLen: contains the total number of bytes that need to be transferred. * - dataAddr: * * if PVSCSI_FLAG_CMD_WITH_SG_LIST is set: dataAddr is the PA of the first * s/g table segment, each s/g segment is entirely contained on a single * page of physical memory, * * if PVSCSI_FLAG_CMD_WITH_SG_LIST is NOT set, then dataAddr is the PA of * the buffer used for the DMA transfer, * - flags: * * PVSCSI_FLAG_CMD_WITH_SG_LIST: see dataAddr above, * * PVSCSI_FLAG_CMD_DIR_NONE: no DMA involved, * * PVSCSI_FLAG_CMD_DIR_TOHOST: transfer from device to main memory, * * PVSCSI_FLAG_CMD_DIR_TODEVICE: transfer from main memory to device, * * PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB: reserved to handle CDBs larger than * 16bytes. To be specified. * - vcpuHint: vcpuId of the processor that will be most likely waiting for the * completion of the i/o. For guest OSes that use lowest priority message * delivery mode (such as windows), we use this "hint" to deliver the * completion action to the proper vcpu. For now, we can use the vcpuId of * the processor that initiated the i/o as a likely candidate for the vcpu * that will be waiting for the completion.. * - bus should be 0: we currently only support bus 0 for now. * - unused should be zero'd. */ #define PVSCSI_FLAG_CMD_WITH_SG_LIST … #define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB … #define PVSCSI_FLAG_CMD_DIR_NONE … #define PVSCSI_FLAG_CMD_DIR_TOHOST … #define PVSCSI_FLAG_CMD_DIR_TODEVICE … struct PVSCSIRingReqDesc { … } __packed; /* * Scatter-gather list management. * * As described above, when PVSCSI_FLAG_CMD_WITH_SG_LIST is set in the * RingReqDesc.flags, then RingReqDesc.dataAddr is the PA of the first s/g * table segment. * * - each segment of the s/g table contain a succession of struct * PVSCSISGElement. * - each segment is entirely contained on a single physical page of memory. * - a "chain" s/g element has the flag PVSCSI_SGE_FLAG_CHAIN_ELEMENT set in * PVSCSISGElement.flags and in this case: * * addr is the PA of the next s/g segment, * * length is undefined, assumed to be 0. */ struct PVSCSISGElement { … } __packed; /* * Completion descriptor. * * sizeof(RingCmpDesc) = 32 * * - context: identifier of the command. The same thing that was specified * under "context" as part of struct RingReqDesc at initiation time, * - dataLen: number of bytes transferred for the actual i/o operation, * - senseLen: number of bytes written into the sense buffer, * - hostStatus: adapter status, * - scsiStatus: device status, * - _pad should be zero. */ struct PVSCSIRingCmpDesc { … } __packed; struct PVSCSIConfigPageHeader { … } __packed; struct PVSCSIConfigPageController { … } __packed; /* * Interrupt status / IRQ bits. */ #define PVSCSI_INTR_CMPL_0 … #define PVSCSI_INTR_CMPL_1 … #define PVSCSI_INTR_CMPL_MASK … #define PVSCSI_INTR_MSG_0 … #define PVSCSI_INTR_MSG_1 … #define PVSCSI_INTR_MSG_MASK … #define PVSCSI_INTR_ALL_SUPPORTED … /* * Number of MSI-X vectors supported. */ #define PVSCSI_MAX_INTRS … /* * Misc constants for the rings. */ #define PVSCSI_MAX_NUM_PAGES_REQ_RING … #define PVSCSI_MAX_NUM_PAGES_CMP_RING … #define PVSCSI_MAX_NUM_PAGES_MSG_RING … #define PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE … #define PVSCSI_MAX_REQ_QUEUE_DEPTH … #define PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES … #define PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES … #define PVSCSI_MEM_SPACE_MISC_NUM_PAGES … #define PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES … #define PVSCSI_MEM_SPACE_MSIX_NUM_PAGES … enum PVSCSIMemSpace { … }; #define PVSCSI_MEM_SPACE_NUM_PAGES … #define PVSCSI_MEM_SPACE_SIZE … #endif /* _VMW_PVSCSI_H_ */