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