PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/hv/hyperv_storage.h

https://github.com/mstsirkin/linux
C Header | 334 lines | 171 code | 71 blank | 92 comment | 6 complexity | 5dddd8a845353b4dac53efefeda515cf MD5 | raw file
  1. /*
  2. *
  3. * Copyright (c) 2011, Microsoft Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  16. * Place - Suite 330, Boston, MA 02111-1307 USA.
  17. *
  18. * Authors:
  19. * Haiyang Zhang <haiyangz@microsoft.com>
  20. * Hank Janssen <hjanssen@microsoft.com>
  21. * K. Y. Srinivasan <kys@microsoft.com>
  22. *
  23. */
  24. #ifndef _HYPERV_STORAGE_H
  25. #define _HYPERV_STORAGE_H
  26. /* vstorage.w revision number. This is used in the case of a version match, */
  27. /* to alert the user that structure sizes may be mismatched even though the */
  28. /* protocol versions match. */
  29. #define REVISION_STRING(REVISION_) #REVISION_
  30. #define FILL_VMSTOR_REVISION(RESULT_LVALUE_) \
  31. do { \
  32. char *revision_string \
  33. = REVISION_STRING($Rev : 6 $) + 6; \
  34. RESULT_LVALUE_ = 0; \
  35. while (*revision_string >= '0' \
  36. && *revision_string <= '9') { \
  37. RESULT_LVALUE_ *= 10; \
  38. RESULT_LVALUE_ += *revision_string - '0'; \
  39. revision_string++; \
  40. } \
  41. } while (0)
  42. /* Major/minor macros. Minor version is in LSB, meaning that earlier flat */
  43. /* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */
  44. #define VMSTOR_PROTOCOL_MAJOR(VERSION_) (((VERSION_) >> 8) & 0xff)
  45. #define VMSTOR_PROTOCOL_MINOR(VERSION_) (((VERSION_)) & 0xff)
  46. #define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \
  47. (((MINOR_) & 0xff)))
  48. #define VMSTOR_INVALID_PROTOCOL_VERSION (-1)
  49. /* Version history: */
  50. /* V1 Beta 0.1 */
  51. /* V1 RC < 2008/1/31 1.0 */
  52. /* V1 RC > 2008/1/31 2.0 */
  53. #define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
  54. /* This will get replaced with the max transfer length that is possible on */
  55. /* the host adapter. */
  56. /* The max transfer length will be published when we offer a vmbus channel. */
  57. #define MAX_TRANSFER_LENGTH 0x40000
  58. #define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) + \
  59. sizeof(struct vstor_packet) + \
  60. sizesizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
  61. /* Packet structure describing virtual storage requests. */
  62. enum vstor_packet_operation {
  63. VSTOR_OPERATION_COMPLETE_IO = 1,
  64. VSTOR_OPERATION_REMOVE_DEVICE = 2,
  65. VSTOR_OPERATION_EXECUTE_SRB = 3,
  66. VSTOR_OPERATION_RESET_LUN = 4,
  67. VSTOR_OPERATION_RESET_ADAPTER = 5,
  68. VSTOR_OPERATION_RESET_BUS = 6,
  69. VSTOR_OPERATION_BEGIN_INITIALIZATION = 7,
  70. VSTOR_OPERATION_END_INITIALIZATION = 8,
  71. VSTOR_OPERATION_QUERY_PROTOCOL_VERSION = 9,
  72. VSTOR_OPERATION_QUERY_PROPERTIES = 10,
  73. VSTOR_OPERATION_MAXIMUM = 10
  74. };
  75. /*
  76. * Platform neutral description of a scsi request -
  77. * this remains the same across the write regardless of 32/64 bit
  78. * note: it's patterned off the SCSI_PASS_THROUGH structure
  79. */
  80. #define CDB16GENERIC_LENGTH 0x10
  81. #ifndef SENSE_BUFFER_SIZE
  82. #define SENSE_BUFFER_SIZE 0x12
  83. #endif
  84. #define MAX_DATA_BUF_LEN_WITH_PADDING 0x14
  85. struct vmscsi_request {
  86. unsigned short length;
  87. unsigned char srb_status;
  88. unsigned char scsi_status;
  89. unsigned char port_number;
  90. unsigned char path_id;
  91. unsigned char target_id;
  92. unsigned char lun;
  93. unsigned char cdb_length;
  94. unsigned char sense_info_length;
  95. unsigned char data_in;
  96. unsigned char reserved;
  97. unsigned int data_transfer_length;
  98. union {
  99. unsigned char cdb[CDB16GENERIC_LENGTH];
  100. unsigned char sense_data[SENSE_BUFFER_SIZE];
  101. unsigned char reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING];
  102. };
  103. } __attribute((packed));
  104. /*
  105. * This structure is sent during the intialization phase to get the different
  106. * properties of the channel.
  107. */
  108. struct vmstorage_channel_properties {
  109. unsigned short protocol_version;
  110. unsigned char path_id;
  111. unsigned char target_id;
  112. /* Note: port number is only really known on the client side */
  113. unsigned int port_number;
  114. unsigned int flags;
  115. unsigned int max_transfer_bytes;
  116. /* This id is unique for each channel and will correspond with */
  117. /* vendor specific data in the inquirydata */
  118. unsigned long long unique_id;
  119. } __packed;
  120. /* This structure is sent during the storage protocol negotiations. */
  121. struct vmstorage_protocol_version {
  122. /* Major (MSW) and minor (LSW) version numbers. */
  123. unsigned short major_minor;
  124. /*
  125. * Revision number is auto-incremented whenever this file is changed
  126. * (See FILL_VMSTOR_REVISION macro above). Mismatch does not
  127. * definitely indicate incompatibility--but it does indicate mismatched
  128. * builds.
  129. */
  130. unsigned short revision;
  131. } __packed;
  132. /* Channel Property Flags */
  133. #define STORAGE_CHANNEL_REMOVABLE_FLAG 0x1
  134. #define STORAGE_CHANNEL_EMULATED_IDE_FLAG 0x2
  135. struct vstor_packet {
  136. /* Requested operation type */
  137. enum vstor_packet_operation operation;
  138. /* Flags - see below for values */
  139. unsigned int flags;
  140. /* Status of the request returned from the server side. */
  141. unsigned int status;
  142. /* Data payload area */
  143. union {
  144. /*
  145. * Structure used to forward SCSI commands from the
  146. * client to the server.
  147. */
  148. struct vmscsi_request vm_srb;
  149. /* Structure used to query channel properties. */
  150. struct vmstorage_channel_properties storage_channel_properties;
  151. /* Used during version negotiations. */
  152. struct vmstorage_protocol_version version;
  153. };
  154. } __packed;
  155. /* Packet flags */
  156. /*
  157. * This flag indicates that the server should send back a completion for this
  158. * packet.
  159. */
  160. #define REQUEST_COMPLETION_FLAG 0x1
  161. /* This is the set of flags that the vsc can set in any packets it sends */
  162. #define VSC_LEGAL_FLAGS (REQUEST_COMPLETION_FLAG)
  163. #include <linux/kernel.h>
  164. #include <linux/wait.h>
  165. #include "hyperv_storage.h"
  166. #include "hyperv.h"
  167. /* Defines */
  168. #define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE)
  169. #define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE)
  170. #define STORVSC_MAX_IO_REQUESTS 128
  171. /*
  172. * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In
  173. * reality, the path/target is not used (ie always set to 0) so our
  174. * scsi host adapter essentially has 1 bus with 1 target that contains
  175. * up to 256 luns.
  176. */
  177. #define STORVSC_MAX_LUNS_PER_TARGET 64
  178. #define STORVSC_MAX_TARGETS 1
  179. #define STORVSC_MAX_CHANNELS 1
  180. struct hv_storvsc_request;
  181. /* Matches Windows-end */
  182. enum storvsc_request_type {
  183. WRITE_TYPE,
  184. READ_TYPE,
  185. UNKNOWN_TYPE,
  186. };
  187. struct hv_storvsc_request {
  188. struct hv_storvsc_request *request;
  189. struct hv_device *device;
  190. /* Synchronize the request/response if needed */
  191. struct completion wait_event;
  192. unsigned char *sense_buffer;
  193. void *context;
  194. void (*on_io_completion)(struct hv_storvsc_request *request);
  195. struct hv_multipage_buffer data_buffer;
  196. struct vstor_packet vstor_packet;
  197. };
  198. struct storvsc_device_info {
  199. u32 ring_buffer_size;
  200. unsigned int port_number;
  201. unsigned char path_id;
  202. unsigned char target_id;
  203. };
  204. struct storvsc_major_info {
  205. int major;
  206. int index;
  207. bool do_register;
  208. char *devname;
  209. char *diskname;
  210. };
  211. /* A storvsc device is a device object that contains a vmbus channel */
  212. struct storvsc_device {
  213. struct hv_device *device;
  214. /* 0 indicates the device is being destroyed */
  215. atomic_t ref_count;
  216. bool drain_notify;
  217. atomic_t num_outstanding_req;
  218. wait_queue_head_t waiting_to_drain;
  219. /*
  220. * Each unique Port/Path/Target represents 1 channel ie scsi
  221. * controller. In reality, the pathid, targetid is always 0
  222. * and the port is set by us
  223. */
  224. unsigned int port_number;
  225. unsigned char path_id;
  226. unsigned char target_id;
  227. /* Used for vsc/vsp channel reset process */
  228. struct hv_storvsc_request init_request;
  229. struct hv_storvsc_request reset_request;
  230. };
  231. /* Get the stordevice object iff exists and its refcount > 1 */
  232. static inline struct storvsc_device *get_stor_device(struct hv_device *device)
  233. {
  234. struct storvsc_device *stor_device;
  235. stor_device = (struct storvsc_device *)device->ext;
  236. if (stor_device && atomic_read(&stor_device->ref_count) > 1)
  237. atomic_inc(&stor_device->ref_count);
  238. else
  239. stor_device = NULL;
  240. return stor_device;
  241. }
  242. static inline void put_stor_device(struct hv_device *device)
  243. {
  244. struct storvsc_device *stor_device;
  245. stor_device = (struct storvsc_device *)device->ext;
  246. atomic_dec(&stor_device->ref_count);
  247. }
  248. static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
  249. {
  250. dev->drain_notify = true;
  251. wait_event(dev->waiting_to_drain,
  252. atomic_read(&dev->num_outstanding_req) == 0);
  253. dev->drain_notify = false;
  254. }
  255. /* Interface */
  256. int storvsc_dev_add(struct hv_device *device,
  257. void *additional_info);
  258. int storvsc_dev_remove(struct hv_device *device);
  259. int storvsc_do_io(struct hv_device *device,
  260. struct hv_storvsc_request *request);
  261. int storvsc_get_major_info(struct storvsc_device_info *device_info,
  262. struct storvsc_major_info *major_info);
  263. #endif /* _HYPERV_STORAGE_H */