Root/
1 | /* |
2 | * Copyright (c) 2009, Microsoft Corporation. |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms and conditions of the GNU General Public License, |
6 | * version 2, as published by the Free Software Foundation. |
7 | * |
8 | * This program is distributed in the hope it will be useful, but WITHOUT |
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
11 | * more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along with |
14 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
15 | * Place - Suite 330, Boston, MA 02111-1307 USA. |
16 | * |
17 | * Authors: |
18 | * Haiyang Zhang <haiyangz@microsoft.com> |
19 | * Hank Janssen <hjanssen@microsoft.com> |
20 | * K. Y. Srinivasan <kys@microsoft.com> |
21 | */ |
22 | |
23 | #include <linux/kernel.h> |
24 | #include <linux/wait.h> |
25 | #include <linux/sched.h> |
26 | #include <linux/completion.h> |
27 | #include <linux/string.h> |
28 | #include <linux/mm.h> |
29 | #include <linux/delay.h> |
30 | #include <linux/init.h> |
31 | #include <linux/slab.h> |
32 | #include <linux/module.h> |
33 | #include <linux/device.h> |
34 | #include <linux/hyperv.h> |
35 | #include <linux/mempool.h> |
36 | #include <scsi/scsi.h> |
37 | #include <scsi/scsi_cmnd.h> |
38 | #include <scsi/scsi_host.h> |
39 | #include <scsi/scsi_device.h> |
40 | #include <scsi/scsi_tcq.h> |
41 | #include <scsi/scsi_eh.h> |
42 | #include <scsi/scsi_devinfo.h> |
43 | #include <scsi/scsi_dbg.h> |
44 | |
45 | /* |
46 | * All wire protocol details (storage protocol between the guest and the host) |
47 | * are consolidated here. |
48 | * |
49 | * Begin protocol definitions. |
50 | */ |
51 | |
52 | /* |
53 | * Version history: |
54 | * V1 Beta: 0.1 |
55 | * V1 RC < 2008/1/31: 1.0 |
56 | * V1 RC > 2008/1/31: 2.0 |
57 | * Win7: 4.2 |
58 | * Win8: 5.1 |
59 | */ |
60 | |
61 | |
62 | #define VMSTOR_WIN7_MAJOR 4 |
63 | #define VMSTOR_WIN7_MINOR 2 |
64 | |
65 | #define VMSTOR_WIN8_MAJOR 5 |
66 | #define VMSTOR_WIN8_MINOR 1 |
67 | |
68 | |
69 | /* Packet structure describing virtual storage requests. */ |
70 | enum vstor_packet_operation { |
71 | VSTOR_OPERATION_COMPLETE_IO = 1, |
72 | VSTOR_OPERATION_REMOVE_DEVICE = 2, |
73 | VSTOR_OPERATION_EXECUTE_SRB = 3, |
74 | VSTOR_OPERATION_RESET_LUN = 4, |
75 | VSTOR_OPERATION_RESET_ADAPTER = 5, |
76 | VSTOR_OPERATION_RESET_BUS = 6, |
77 | VSTOR_OPERATION_BEGIN_INITIALIZATION = 7, |
78 | VSTOR_OPERATION_END_INITIALIZATION = 8, |
79 | VSTOR_OPERATION_QUERY_PROTOCOL_VERSION = 9, |
80 | VSTOR_OPERATION_QUERY_PROPERTIES = 10, |
81 | VSTOR_OPERATION_ENUMERATE_BUS = 11, |
82 | VSTOR_OPERATION_FCHBA_DATA = 12, |
83 | VSTOR_OPERATION_CREATE_SUB_CHANNELS = 13, |
84 | VSTOR_OPERATION_MAXIMUM = 13 |
85 | }; |
86 | |
87 | /* |
88 | * WWN packet for Fibre Channel HBA |
89 | */ |
90 | |
91 | struct hv_fc_wwn_packet { |
92 | bool primary_active; |
93 | u8 reserved1; |
94 | u8 reserved2; |
95 | u8 primary_port_wwn[8]; |
96 | u8 primary_node_wwn[8]; |
97 | u8 secondary_port_wwn[8]; |
98 | u8 secondary_node_wwn[8]; |
99 | }; |
100 | |
101 | |
102 | |
103 | /* |
104 | * SRB Flag Bits |
105 | */ |
106 | |
107 | #define SRB_FLAGS_QUEUE_ACTION_ENABLE 0x00000002 |
108 | #define SRB_FLAGS_DISABLE_DISCONNECT 0x00000004 |
109 | #define SRB_FLAGS_DISABLE_SYNCH_TRANSFER 0x00000008 |
110 | #define SRB_FLAGS_BYPASS_FROZEN_QUEUE 0x00000010 |
111 | #define SRB_FLAGS_DISABLE_AUTOSENSE 0x00000020 |
112 | #define SRB_FLAGS_DATA_IN 0x00000040 |
113 | #define SRB_FLAGS_DATA_OUT 0x00000080 |
114 | #define SRB_FLAGS_NO_DATA_TRANSFER 0x00000000 |
115 | #define SRB_FLAGS_UNSPECIFIED_DIRECTION (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) |
116 | #define SRB_FLAGS_NO_QUEUE_FREEZE 0x00000100 |
117 | #define SRB_FLAGS_ADAPTER_CACHE_ENABLE 0x00000200 |
118 | #define SRB_FLAGS_FREE_SENSE_BUFFER 0x00000400 |
119 | |
120 | /* |
121 | * This flag indicates the request is part of the workflow for processing a D3. |
122 | */ |
123 | #define SRB_FLAGS_D3_PROCESSING 0x00000800 |
124 | #define SRB_FLAGS_IS_ACTIVE 0x00010000 |
125 | #define SRB_FLAGS_ALLOCATED_FROM_ZONE 0x00020000 |
126 | #define SRB_FLAGS_SGLIST_FROM_POOL 0x00040000 |
127 | #define SRB_FLAGS_BYPASS_LOCKED_QUEUE 0x00080000 |
128 | #define SRB_FLAGS_NO_KEEP_AWAKE 0x00100000 |
129 | #define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE 0x00200000 |
130 | #define SRB_FLAGS_PORT_DRIVER_SENSEHASPORT 0x00400000 |
131 | #define SRB_FLAGS_DONT_START_NEXT_PACKET 0x00800000 |
132 | #define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000 |
133 | #define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000 |
134 | |
135 | |
136 | /* |
137 | * Platform neutral description of a scsi request - |
138 | * this remains the same across the write regardless of 32/64 bit |
139 | * note: it's patterned off the SCSI_PASS_THROUGH structure |
140 | */ |
141 | #define STORVSC_MAX_CMD_LEN 0x10 |
142 | |
143 | #define POST_WIN7_STORVSC_SENSE_BUFFER_SIZE 0x14 |
144 | #define PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE 0x12 |
145 | |
146 | #define STORVSC_SENSE_BUFFER_SIZE 0x14 |
147 | #define STORVSC_MAX_BUF_LEN_WITH_PADDING 0x14 |
148 | |
149 | /* |
150 | * Sense buffer size changed in win8; have a run-time |
151 | * variable to track the size we should use. |
152 | */ |
153 | static int sense_buffer_size; |
154 | |
155 | /* |
156 | * The size of the vmscsi_request has changed in win8. The |
157 | * additional size is because of new elements added to the |
158 | * structure. These elements are valid only when we are talking |
159 | * to a win8 host. |
160 | * Track the correction to size we need to apply. |
161 | */ |
162 | |
163 | static int vmscsi_size_delta; |
164 | static int vmstor_current_major; |
165 | static int vmstor_current_minor; |
166 | |
167 | struct vmscsi_win8_extension { |
168 | /* |
169 | * The following were added in Windows 8 |
170 | */ |
171 | u16 reserve; |
172 | u8 queue_tag; |
173 | u8 queue_action; |
174 | u32 srb_flags; |
175 | u32 time_out_value; |
176 | u32 queue_sort_ey; |
177 | } __packed; |
178 | |
179 | struct vmscsi_request { |
180 | u16 length; |
181 | u8 srb_status; |
182 | u8 scsi_status; |
183 | |
184 | u8 port_number; |
185 | u8 path_id; |
186 | u8 target_id; |
187 | u8 lun; |
188 | |
189 | u8 cdb_length; |
190 | u8 sense_info_length; |
191 | u8 data_in; |
192 | u8 reserved; |
193 | |
194 | u32 data_transfer_length; |
195 | |
196 | union { |
197 | u8 cdb[STORVSC_MAX_CMD_LEN]; |
198 | u8 sense_data[STORVSC_SENSE_BUFFER_SIZE]; |
199 | u8 reserved_array[STORVSC_MAX_BUF_LEN_WITH_PADDING]; |
200 | }; |
201 | /* |
202 | * The following was added in win8. |
203 | */ |
204 | struct vmscsi_win8_extension win8_extension; |
205 | |
206 | } __attribute((packed)); |
207 | |
208 | |
209 | /* |
210 | * This structure is sent during the intialization phase to get the different |
211 | * properties of the channel. |
212 | */ |
213 | |
214 | #define STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL 0x1 |
215 | |
216 | struct vmstorage_channel_properties { |
217 | u32 reserved; |
218 | u16 max_channel_cnt; |
219 | u16 reserved1; |
220 | |
221 | u32 flags; |
222 | u32 max_transfer_bytes; |
223 | |
224 | u64 reserved2; |
225 | } __packed; |
226 | |
227 | /* This structure is sent during the storage protocol negotiations. */ |
228 | struct vmstorage_protocol_version { |
229 | /* Major (MSW) and minor (LSW) version numbers. */ |
230 | u16 major_minor; |
231 | |
232 | /* |
233 | * Revision number is auto-incremented whenever this file is changed |
234 | * (See FILL_VMSTOR_REVISION macro above). Mismatch does not |
235 | * definitely indicate incompatibility--but it does indicate mismatched |
236 | * builds. |
237 | * This is only used on the windows side. Just set it to 0. |
238 | */ |
239 | u16 revision; |
240 | } __packed; |
241 | |
242 | /* Channel Property Flags */ |
243 | #define STORAGE_CHANNEL_REMOVABLE_FLAG 0x1 |
244 | #define STORAGE_CHANNEL_EMULATED_IDE_FLAG 0x2 |
245 | |
246 | struct vstor_packet { |
247 | /* Requested operation type */ |
248 | enum vstor_packet_operation operation; |
249 | |
250 | /* Flags - see below for values */ |
251 | u32 flags; |
252 | |
253 | /* Status of the request returned from the server side. */ |
254 | u32 status; |
255 | |
256 | /* Data payload area */ |
257 | union { |
258 | /* |
259 | * Structure used to forward SCSI commands from the |
260 | * client to the server. |
261 | */ |
262 | struct vmscsi_request vm_srb; |
263 | |
264 | /* Structure used to query channel properties. */ |
265 | struct vmstorage_channel_properties storage_channel_properties; |
266 | |
267 | /* Used during version negotiations. */ |
268 | struct vmstorage_protocol_version version; |
269 | |
270 | /* Fibre channel address packet */ |
271 | struct hv_fc_wwn_packet wwn_packet; |
272 | |
273 | /* Number of sub-channels to create */ |
274 | u16 sub_channel_count; |
275 | |
276 | /* This will be the maximum of the union members */ |
277 | u8 buffer[0x34]; |
278 | }; |
279 | } __packed; |
280 | |
281 | /* |
282 | * Packet Flags: |
283 | * |
284 | * This flag indicates that the server should send back a completion for this |
285 | * packet. |
286 | */ |
287 | |
288 | #define REQUEST_COMPLETION_FLAG 0x1 |
289 | |
290 | /* Matches Windows-end */ |
291 | enum storvsc_request_type { |
292 | WRITE_TYPE = 0, |
293 | READ_TYPE, |
294 | UNKNOWN_TYPE, |
295 | }; |
296 | |
297 | /* |
298 | * SRB status codes and masks; a subset of the codes used here. |
299 | */ |
300 | |
301 | #define SRB_STATUS_AUTOSENSE_VALID 0x80 |
302 | #define SRB_STATUS_INVALID_LUN 0x20 |
303 | #define SRB_STATUS_SUCCESS 0x01 |
304 | #define SRB_STATUS_ABORTED 0x02 |
305 | #define SRB_STATUS_ERROR 0x04 |
306 | |
307 | /* |
308 | * This is the end of Protocol specific defines. |
309 | */ |
310 | |
311 | |
312 | /* |
313 | * We setup a mempool to allocate request structures for this driver |
314 | * on a per-lun basis. The following define specifies the number of |
315 | * elements in the pool. |
316 | */ |
317 | |
318 | #define STORVSC_MIN_BUF_NR 64 |
319 | static int storvsc_ringbuffer_size = (20 * PAGE_SIZE); |
320 | |
321 | module_param(storvsc_ringbuffer_size, int, S_IRUGO); |
322 | MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); |
323 | |
324 | /* |
325 | * Timeout in seconds for all devices managed by this driver. |
326 | */ |
327 | static int storvsc_timeout = 180; |
328 | |
329 | #define STORVSC_MAX_IO_REQUESTS 200 |
330 | |
331 | static void storvsc_on_channel_callback(void *context); |
332 | |
333 | /* |
334 | * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In |
335 | * reality, the path/target is not used (ie always set to 0) so our |
336 | * scsi host adapter essentially has 1 bus with 1 target that contains |
337 | * up to 256 luns. |
338 | */ |
339 | #define STORVSC_MAX_LUNS_PER_TARGET 64 |
340 | #define STORVSC_MAX_TARGETS 1 |
341 | #define STORVSC_MAX_CHANNELS 1 |
342 | |
343 | |
344 | |
345 | struct storvsc_cmd_request { |
346 | struct list_head entry; |
347 | struct scsi_cmnd *cmd; |
348 | |
349 | unsigned int bounce_sgl_count; |
350 | struct scatterlist *bounce_sgl; |
351 | |
352 | struct hv_device *device; |
353 | |
354 | /* Synchronize the request/response if needed */ |
355 | struct completion wait_event; |
356 | |
357 | unsigned char *sense_buffer; |
358 | struct hv_multipage_buffer data_buffer; |
359 | struct vstor_packet vstor_packet; |
360 | }; |
361 | |
362 | |
363 | /* A storvsc device is a device object that contains a vmbus channel */ |
364 | struct storvsc_device { |
365 | struct hv_device *device; |
366 | |
367 | bool destroy; |
368 | bool drain_notify; |
369 | bool open_sub_channel; |
370 | atomic_t num_outstanding_req; |
371 | struct Scsi_Host *host; |
372 | |
373 | wait_queue_head_t waiting_to_drain; |
374 | |
375 | /* |
376 | * Each unique Port/Path/Target represents 1 channel ie scsi |
377 | * controller. In reality, the pathid, targetid is always 0 |
378 | * and the port is set by us |
379 | */ |
380 | unsigned int port_number; |
381 | unsigned char path_id; |
382 | unsigned char target_id; |
383 | |
384 | /* Used for vsc/vsp channel reset process */ |
385 | struct storvsc_cmd_request init_request; |
386 | struct storvsc_cmd_request reset_request; |
387 | }; |
388 | |
389 | struct stor_mem_pools { |
390 | struct kmem_cache *request_pool; |
391 | mempool_t *request_mempool; |
392 | }; |
393 | |
394 | struct hv_host_device { |
395 | struct hv_device *dev; |
396 | unsigned int port; |
397 | unsigned char path; |
398 | unsigned char target; |
399 | }; |
400 | |
401 | struct storvsc_scan_work { |
402 | struct work_struct work; |
403 | struct Scsi_Host *host; |
404 | uint lun; |
405 | }; |
406 | |
407 | static void storvsc_device_scan(struct work_struct *work) |
408 | { |
409 | struct storvsc_scan_work *wrk; |
410 | uint lun; |
411 | struct scsi_device *sdev; |
412 | |
413 | wrk = container_of(work, struct storvsc_scan_work, work); |
414 | lun = wrk->lun; |
415 | |
416 | sdev = scsi_device_lookup(wrk->host, 0, 0, lun); |
417 | if (!sdev) |
418 | goto done; |
419 | scsi_rescan_device(&sdev->sdev_gendev); |
420 | scsi_device_put(sdev); |
421 | |
422 | done: |
423 | kfree(wrk); |
424 | } |
425 | |
426 | static void storvsc_bus_scan(struct work_struct *work) |
427 | { |
428 | struct storvsc_scan_work *wrk; |
429 | int id, order_id; |
430 | |
431 | wrk = container_of(work, struct storvsc_scan_work, work); |
432 | for (id = 0; id < wrk->host->max_id; ++id) { |
433 | if (wrk->host->reverse_ordering) |
434 | order_id = wrk->host->max_id - id - 1; |
435 | else |
436 | order_id = id; |
437 | |
438 | scsi_scan_target(&wrk->host->shost_gendev, 0, |
439 | order_id, SCAN_WILD_CARD, 1); |
440 | } |
441 | kfree(wrk); |
442 | } |
443 | |
444 | static void storvsc_remove_lun(struct work_struct *work) |
445 | { |
446 | struct storvsc_scan_work *wrk; |
447 | struct scsi_device *sdev; |
448 | |
449 | wrk = container_of(work, struct storvsc_scan_work, work); |
450 | if (!scsi_host_get(wrk->host)) |
451 | goto done; |
452 | |
453 | sdev = scsi_device_lookup(wrk->host, 0, 0, wrk->lun); |
454 | |
455 | if (sdev) { |
456 | scsi_remove_device(sdev); |
457 | scsi_device_put(sdev); |
458 | } |
459 | scsi_host_put(wrk->host); |
460 | |
461 | done: |
462 | kfree(wrk); |
463 | } |
464 | |
465 | /* |
466 | * Major/minor macros. Minor version is in LSB, meaning that earlier flat |
467 | * version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). |
468 | */ |
469 | |
470 | static inline u16 storvsc_get_version(u8 major, u8 minor) |
471 | { |
472 | u16 version; |
473 | |
474 | version = ((major << 8) | minor); |
475 | return version; |
476 | } |
477 | |
478 | /* |
479 | * We can get incoming messages from the host that are not in response to |
480 | * messages that we have sent out. An example of this would be messages |
481 | * received by the guest to notify dynamic addition/removal of LUNs. To |
482 | * deal with potential race conditions where the driver may be in the |
483 | * midst of being unloaded when we might receive an unsolicited message |
484 | * from the host, we have implemented a mechanism to gurantee sequential |
485 | * consistency: |
486 | * |
487 | * 1) Once the device is marked as being destroyed, we will fail all |
488 | * outgoing messages. |
489 | * 2) We permit incoming messages when the device is being destroyed, |
490 | * only to properly account for messages already sent out. |
491 | */ |
492 | |
493 | static inline struct storvsc_device *get_out_stor_device( |
494 | struct hv_device *device) |
495 | { |
496 | struct storvsc_device *stor_device; |
497 | |
498 | stor_device = hv_get_drvdata(device); |
499 | |
500 | if (stor_device && stor_device->destroy) |
501 | stor_device = NULL; |
502 | |
503 | return stor_device; |
504 | } |
505 | |
506 | |
507 | static inline void storvsc_wait_to_drain(struct storvsc_device *dev) |
508 | { |
509 | dev->drain_notify = true; |
510 | wait_event(dev->waiting_to_drain, |
511 | atomic_read(&dev->num_outstanding_req) == 0); |
512 | dev->drain_notify = false; |
513 | } |
514 | |
515 | static inline struct storvsc_device *get_in_stor_device( |
516 | struct hv_device *device) |
517 | { |
518 | struct storvsc_device *stor_device; |
519 | |
520 | stor_device = hv_get_drvdata(device); |
521 | |
522 | if (!stor_device) |
523 | goto get_in_err; |
524 | |
525 | /* |
526 | * If the device is being destroyed; allow incoming |
527 | * traffic only to cleanup outstanding requests. |
528 | */ |
529 | |
530 | if (stor_device->destroy && |
531 | (atomic_read(&stor_device->num_outstanding_req) == 0)) |
532 | stor_device = NULL; |
533 | |
534 | get_in_err: |
535 | return stor_device; |
536 | |
537 | } |
538 | |
539 | static void destroy_bounce_buffer(struct scatterlist *sgl, |
540 | unsigned int sg_count) |
541 | { |
542 | int i; |
543 | struct page *page_buf; |
544 | |
545 | for (i = 0; i < sg_count; i++) { |
546 | page_buf = sg_page((&sgl[i])); |
547 | if (page_buf != NULL) |
548 | __free_page(page_buf); |
549 | } |
550 | |
551 | kfree(sgl); |
552 | } |
553 | |
554 | static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count) |
555 | { |
556 | int i; |
557 | |
558 | /* No need to check */ |
559 | if (sg_count < 2) |
560 | return -1; |
561 | |
562 | /* We have at least 2 sg entries */ |
563 | for (i = 0; i < sg_count; i++) { |
564 | if (i == 0) { |
565 | /* make sure 1st one does not have hole */ |
566 | if (sgl[i].offset + sgl[i].length != PAGE_SIZE) |
567 | return i; |
568 | } else if (i == sg_count - 1) { |
569 | /* make sure last one does not have hole */ |
570 | if (sgl[i].offset != 0) |
571 | return i; |
572 | } else { |
573 | /* make sure no hole in the middle */ |
574 | if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0) |
575 | return i; |
576 | } |
577 | } |
578 | return -1; |
579 | } |
580 | |
581 | static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl, |
582 | unsigned int sg_count, |
583 | unsigned int len, |
584 | int write) |
585 | { |
586 | int i; |
587 | int num_pages; |
588 | struct scatterlist *bounce_sgl; |
589 | struct page *page_buf; |
590 | unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE); |
591 | |
592 | num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT; |
593 | |
594 | bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC); |
595 | if (!bounce_sgl) |
596 | return NULL; |
597 | |
598 | sg_init_table(bounce_sgl, num_pages); |
599 | for (i = 0; i < num_pages; i++) { |
600 | page_buf = alloc_page(GFP_ATOMIC); |
601 | if (!page_buf) |
602 | goto cleanup; |
603 | sg_set_page(&bounce_sgl[i], page_buf, buf_len, 0); |
604 | } |
605 | |
606 | return bounce_sgl; |
607 | |
608 | cleanup: |
609 | destroy_bounce_buffer(bounce_sgl, num_pages); |
610 | return NULL; |
611 | } |
612 | |
613 | /* Disgusting wrapper functions */ |
614 | static inline unsigned long sg_kmap_atomic(struct scatterlist *sgl, int idx) |
615 | { |
616 | void *addr = kmap_atomic(sg_page(sgl + idx)); |
617 | return (unsigned long)addr; |
618 | } |
619 | |
620 | static inline void sg_kunmap_atomic(unsigned long addr) |
621 | { |
622 | kunmap_atomic((void *)addr); |
623 | } |
624 | |
625 | |
626 | /* Assume the original sgl has enough room */ |
627 | static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, |
628 | struct scatterlist *bounce_sgl, |
629 | unsigned int orig_sgl_count, |
630 | unsigned int bounce_sgl_count) |
631 | { |
632 | int i; |
633 | int j = 0; |
634 | unsigned long src, dest; |
635 | unsigned int srclen, destlen, copylen; |
636 | unsigned int total_copied = 0; |
637 | unsigned long bounce_addr = 0; |
638 | unsigned long dest_addr = 0; |
639 | unsigned long flags; |
640 | |
641 | local_irq_save(flags); |
642 | |
643 | for (i = 0; i < orig_sgl_count; i++) { |
644 | dest_addr = sg_kmap_atomic(orig_sgl,i) + orig_sgl[i].offset; |
645 | dest = dest_addr; |
646 | destlen = orig_sgl[i].length; |
647 | |
648 | if (bounce_addr == 0) |
649 | bounce_addr = sg_kmap_atomic(bounce_sgl,j); |
650 | |
651 | while (destlen) { |
652 | src = bounce_addr + bounce_sgl[j].offset; |
653 | srclen = bounce_sgl[j].length - bounce_sgl[j].offset; |
654 | |
655 | copylen = min(srclen, destlen); |
656 | memcpy((void *)dest, (void *)src, copylen); |
657 | |
658 | total_copied += copylen; |
659 | bounce_sgl[j].offset += copylen; |
660 | destlen -= copylen; |
661 | dest += copylen; |
662 | |
663 | if (bounce_sgl[j].offset == bounce_sgl[j].length) { |
664 | /* full */ |
665 | sg_kunmap_atomic(bounce_addr); |
666 | j++; |
667 | |
668 | /* |
669 | * It is possible that the number of elements |
670 | * in the bounce buffer may not be equal to |
671 | * the number of elements in the original |
672 | * scatter list. Handle this correctly. |
673 | */ |
674 | |
675 | if (j == bounce_sgl_count) { |
676 | /* |
677 | * We are done; cleanup and return. |
678 | */ |
679 | sg_kunmap_atomic(dest_addr - orig_sgl[i].offset); |
680 | local_irq_restore(flags); |
681 | return total_copied; |
682 | } |
683 | |
684 | /* if we need to use another bounce buffer */ |
685 | if (destlen || i != orig_sgl_count - 1) |
686 | bounce_addr = sg_kmap_atomic(bounce_sgl,j); |
687 | } else if (destlen == 0 && i == orig_sgl_count - 1) { |
688 | /* unmap the last bounce that is < PAGE_SIZE */ |
689 | sg_kunmap_atomic(bounce_addr); |
690 | } |
691 | } |
692 | |
693 | sg_kunmap_atomic(dest_addr - orig_sgl[i].offset); |
694 | } |
695 | |
696 | local_irq_restore(flags); |
697 | |
698 | return total_copied; |
699 | } |
700 | |
701 | /* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */ |
702 | static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, |
703 | struct scatterlist *bounce_sgl, |
704 | unsigned int orig_sgl_count) |
705 | { |
706 | int i; |
707 | int j = 0; |
708 | unsigned long src, dest; |
709 | unsigned int srclen, destlen, copylen; |
710 | unsigned int total_copied = 0; |
711 | unsigned long bounce_addr = 0; |
712 | unsigned long src_addr = 0; |
713 | unsigned long flags; |
714 | |
715 | local_irq_save(flags); |
716 | |
717 | for (i = 0; i < orig_sgl_count; i++) { |
718 | src_addr = sg_kmap_atomic(orig_sgl,i) + orig_sgl[i].offset; |
719 | src = src_addr; |
720 | srclen = orig_sgl[i].length; |
721 | |
722 | if (bounce_addr == 0) |
723 | bounce_addr = sg_kmap_atomic(bounce_sgl,j); |
724 | |
725 | while (srclen) { |
726 | /* assume bounce offset always == 0 */ |
727 | dest = bounce_addr + bounce_sgl[j].length; |
728 | destlen = PAGE_SIZE - bounce_sgl[j].length; |
729 | |
730 | copylen = min(srclen, destlen); |
731 | memcpy((void *)dest, (void *)src, copylen); |
732 | |
733 | total_copied += copylen; |
734 | bounce_sgl[j].length += copylen; |
735 | srclen -= copylen; |
736 | src += copylen; |
737 | |
738 | if (bounce_sgl[j].length == PAGE_SIZE) { |
739 | /* full..move to next entry */ |
740 | sg_kunmap_atomic(bounce_addr); |
741 | j++; |
742 | |
743 | /* if we need to use another bounce buffer */ |
744 | if (srclen || i != orig_sgl_count - 1) |
745 | bounce_addr = sg_kmap_atomic(bounce_sgl,j); |
746 | |
747 | } else if (srclen == 0 && i == orig_sgl_count - 1) { |
748 | /* unmap the last bounce that is < PAGE_SIZE */ |
749 | sg_kunmap_atomic(bounce_addr); |
750 | } |
751 | } |
752 | |
753 | sg_kunmap_atomic(src_addr - orig_sgl[i].offset); |
754 | } |
755 | |
756 | local_irq_restore(flags); |
757 | |
758 | return total_copied; |
759 | } |
760 | |
761 | static void handle_sc_creation(struct vmbus_channel *new_sc) |
762 | { |
763 | struct hv_device *device = new_sc->primary_channel->device_obj; |
764 | struct storvsc_device *stor_device; |
765 | struct vmstorage_channel_properties props; |
766 | |
767 | stor_device = get_out_stor_device(device); |
768 | if (!stor_device) |
769 | return; |
770 | |
771 | if (stor_device->open_sub_channel == false) |
772 | return; |
773 | |
774 | memset(&props, 0, sizeof(struct vmstorage_channel_properties)); |
775 | |
776 | vmbus_open(new_sc, |
777 | storvsc_ringbuffer_size, |
778 | storvsc_ringbuffer_size, |
779 | (void *)&props, |
780 | sizeof(struct vmstorage_channel_properties), |
781 | storvsc_on_channel_callback, new_sc); |
782 | } |
783 | |
784 | static void handle_multichannel_storage(struct hv_device *device, int max_chns) |
785 | { |
786 | struct storvsc_device *stor_device; |
787 | int num_cpus = num_online_cpus(); |
788 | int num_sc; |
789 | struct storvsc_cmd_request *request; |
790 | struct vstor_packet *vstor_packet; |
791 | int ret, t; |
792 | |
793 | num_sc = ((max_chns > num_cpus) ? num_cpus : max_chns); |
794 | stor_device = get_out_stor_device(device); |
795 | if (!stor_device) |
796 | return; |
797 | |
798 | request = &stor_device->init_request; |
799 | vstor_packet = &request->vstor_packet; |
800 | |
801 | stor_device->open_sub_channel = true; |
802 | /* |
803 | * Establish a handler for dealing with subchannels. |
804 | */ |
805 | vmbus_set_sc_create_callback(device->channel, handle_sc_creation); |
806 | |
807 | /* |
808 | * Check to see if sub-channels have already been created. This |
809 | * can happen when this driver is re-loaded after unloading. |
810 | */ |
811 | |
812 | if (vmbus_are_subchannels_present(device->channel)) |
813 | return; |
814 | |
815 | stor_device->open_sub_channel = false; |
816 | /* |
817 | * Request the host to create sub-channels. |
818 | */ |
819 | memset(request, 0, sizeof(struct storvsc_cmd_request)); |
820 | init_completion(&request->wait_event); |
821 | vstor_packet->operation = VSTOR_OPERATION_CREATE_SUB_CHANNELS; |
822 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; |
823 | vstor_packet->sub_channel_count = num_sc; |
824 | |
825 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
826 | (sizeof(struct vstor_packet) - |
827 | vmscsi_size_delta), |
828 | (unsigned long)request, |
829 | VM_PKT_DATA_INBAND, |
830 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); |
831 | |
832 | if (ret != 0) |
833 | return; |
834 | |
835 | t = wait_for_completion_timeout(&request->wait_event, 10*HZ); |
836 | if (t == 0) |
837 | return; |
838 | |
839 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || |
840 | vstor_packet->status != 0) |
841 | return; |
842 | |
843 | /* |
844 | * Now that we created the sub-channels, invoke the check; this |
845 | * may trigger the callback. |
846 | */ |
847 | stor_device->open_sub_channel = true; |
848 | vmbus_are_subchannels_present(device->channel); |
849 | } |
850 | |
851 | static int storvsc_channel_init(struct hv_device *device) |
852 | { |
853 | struct storvsc_device *stor_device; |
854 | struct storvsc_cmd_request *request; |
855 | struct vstor_packet *vstor_packet; |
856 | int ret, t; |
857 | int max_chns; |
858 | bool process_sub_channels = false; |
859 | |
860 | stor_device = get_out_stor_device(device); |
861 | if (!stor_device) |
862 | return -ENODEV; |
863 | |
864 | request = &stor_device->init_request; |
865 | vstor_packet = &request->vstor_packet; |
866 | |
867 | /* |
868 | * Now, initiate the vsc/vsp initialization protocol on the open |
869 | * channel |
870 | */ |
871 | memset(request, 0, sizeof(struct storvsc_cmd_request)); |
872 | init_completion(&request->wait_event); |
873 | vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; |
874 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; |
875 | |
876 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
877 | (sizeof(struct vstor_packet) - |
878 | vmscsi_size_delta), |
879 | (unsigned long)request, |
880 | VM_PKT_DATA_INBAND, |
881 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); |
882 | if (ret != 0) |
883 | goto cleanup; |
884 | |
885 | t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
886 | if (t == 0) { |
887 | ret = -ETIMEDOUT; |
888 | goto cleanup; |
889 | } |
890 | |
891 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || |
892 | vstor_packet->status != 0) |
893 | goto cleanup; |
894 | |
895 | |
896 | /* reuse the packet for version range supported */ |
897 | memset(vstor_packet, 0, sizeof(struct vstor_packet)); |
898 | vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION; |
899 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; |
900 | |
901 | vstor_packet->version.major_minor = |
902 | storvsc_get_version(vmstor_current_major, vmstor_current_minor); |
903 | |
904 | /* |
905 | * The revision number is only used in Windows; set it to 0. |
906 | */ |
907 | vstor_packet->version.revision = 0; |
908 | |
909 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
910 | (sizeof(struct vstor_packet) - |
911 | vmscsi_size_delta), |
912 | (unsigned long)request, |
913 | VM_PKT_DATA_INBAND, |
914 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); |
915 | if (ret != 0) |
916 | goto cleanup; |
917 | |
918 | t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
919 | if (t == 0) { |
920 | ret = -ETIMEDOUT; |
921 | goto cleanup; |
922 | } |
923 | |
924 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || |
925 | vstor_packet->status != 0) |
926 | goto cleanup; |
927 | |
928 | |
929 | memset(vstor_packet, 0, sizeof(struct vstor_packet)); |
930 | vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES; |
931 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; |
932 | |
933 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
934 | (sizeof(struct vstor_packet) - |
935 | vmscsi_size_delta), |
936 | (unsigned long)request, |
937 | VM_PKT_DATA_INBAND, |
938 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); |
939 | |
940 | if (ret != 0) |
941 | goto cleanup; |
942 | |
943 | t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
944 | if (t == 0) { |
945 | ret = -ETIMEDOUT; |
946 | goto cleanup; |
947 | } |
948 | |
949 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || |
950 | vstor_packet->status != 0) |
951 | goto cleanup; |
952 | |
953 | /* |
954 | * Check to see if multi-channel support is there. |
955 | * Hosts that implement protocol version of 5.1 and above |
956 | * support multi-channel. |
957 | */ |
958 | max_chns = vstor_packet->storage_channel_properties.max_channel_cnt; |
959 | if ((vmbus_proto_version != VERSION_WIN7) && |
960 | (vmbus_proto_version != VERSION_WS2008)) { |
961 | if (vstor_packet->storage_channel_properties.flags & |
962 | STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL) |
963 | process_sub_channels = true; |
964 | } |
965 | |
966 | memset(vstor_packet, 0, sizeof(struct vstor_packet)); |
967 | vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; |
968 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; |
969 | |
970 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
971 | (sizeof(struct vstor_packet) - |
972 | vmscsi_size_delta), |
973 | (unsigned long)request, |
974 | VM_PKT_DATA_INBAND, |
975 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); |
976 | |
977 | if (ret != 0) |
978 | goto cleanup; |
979 | |
980 | t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
981 | if (t == 0) { |
982 | ret = -ETIMEDOUT; |
983 | goto cleanup; |
984 | } |
985 | |
986 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || |
987 | vstor_packet->status != 0) |
988 | goto cleanup; |
989 | |
990 | if (process_sub_channels) |
991 | handle_multichannel_storage(device, max_chns); |
992 | |
993 | |
994 | cleanup: |
995 | return ret; |
996 | } |
997 | |
998 | static void storvsc_handle_error(struct vmscsi_request *vm_srb, |
999 | struct scsi_cmnd *scmnd, |
1000 | struct Scsi_Host *host, |
1001 | u8 asc, u8 ascq) |
1002 | { |
1003 | struct storvsc_scan_work *wrk; |
1004 | void (*process_err_fn)(struct work_struct *work); |
1005 | bool do_work = false; |
1006 | |
1007 | switch (vm_srb->srb_status) { |
1008 | case SRB_STATUS_ERROR: |
1009 | /* |
1010 | * If there is an error; offline the device since all |
1011 | * error recovery strategies would have already been |
1012 | * deployed on the host side. However, if the command |
1013 | * were a pass-through command deal with it appropriately. |
1014 | */ |
1015 | switch (scmnd->cmnd[0]) { |
1016 | case ATA_16: |
1017 | case ATA_12: |
1018 | set_host_byte(scmnd, DID_PASSTHROUGH); |
1019 | break; |
1020 | default: |
1021 | set_host_byte(scmnd, DID_TARGET_FAILURE); |
1022 | } |
1023 | break; |
1024 | case SRB_STATUS_INVALID_LUN: |
1025 | do_work = true; |
1026 | process_err_fn = storvsc_remove_lun; |
1027 | break; |
1028 | case (SRB_STATUS_ABORTED | SRB_STATUS_AUTOSENSE_VALID): |
1029 | if ((asc == 0x2a) && (ascq == 0x9)) { |
1030 | do_work = true; |
1031 | process_err_fn = storvsc_device_scan; |
1032 | /* |
1033 | * Retry the I/O that trigerred this. |
1034 | */ |
1035 | set_host_byte(scmnd, DID_REQUEUE); |
1036 | } |
1037 | break; |
1038 | } |
1039 | |
1040 | if (!do_work) |
1041 | return; |
1042 | |
1043 | /* |
1044 | * We need to schedule work to process this error; schedule it. |
1045 | */ |
1046 | wrk = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC); |
1047 | if (!wrk) { |
1048 | set_host_byte(scmnd, DID_TARGET_FAILURE); |
1049 | return; |
1050 | } |
1051 | |
1052 | wrk->host = host; |
1053 | wrk->lun = vm_srb->lun; |
1054 | INIT_WORK(&wrk->work, process_err_fn); |
1055 | schedule_work(&wrk->work); |
1056 | } |
1057 | |
1058 | |
1059 | static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) |
1060 | { |
1061 | struct scsi_cmnd *scmnd = cmd_request->cmd; |
1062 | struct hv_host_device *host_dev = shost_priv(scmnd->device->host); |
1063 | void (*scsi_done_fn)(struct scsi_cmnd *); |
1064 | struct scsi_sense_hdr sense_hdr; |
1065 | struct vmscsi_request *vm_srb; |
1066 | struct stor_mem_pools *memp = scmnd->device->hostdata; |
1067 | struct Scsi_Host *host; |
1068 | struct storvsc_device *stor_dev; |
1069 | struct hv_device *dev = host_dev->dev; |
1070 | |
1071 | stor_dev = get_in_stor_device(dev); |
1072 | host = stor_dev->host; |
1073 | |
1074 | vm_srb = &cmd_request->vstor_packet.vm_srb; |
1075 | if (cmd_request->bounce_sgl_count) { |
1076 | if (vm_srb->data_in == READ_TYPE) |
1077 | copy_from_bounce_buffer(scsi_sglist(scmnd), |
1078 | cmd_request->bounce_sgl, |
1079 | scsi_sg_count(scmnd), |
1080 | cmd_request->bounce_sgl_count); |
1081 | destroy_bounce_buffer(cmd_request->bounce_sgl, |
1082 | cmd_request->bounce_sgl_count); |
1083 | } |
1084 | |
1085 | scmnd->result = vm_srb->scsi_status; |
1086 | |
1087 | if (scmnd->result) { |
1088 | if (scsi_normalize_sense(scmnd->sense_buffer, |
1089 | SCSI_SENSE_BUFFERSIZE, &sense_hdr)) |
1090 | scsi_print_sense_hdr("storvsc", &sense_hdr); |
1091 | } |
1092 | |
1093 | if (vm_srb->srb_status != SRB_STATUS_SUCCESS) |
1094 | storvsc_handle_error(vm_srb, scmnd, host, sense_hdr.asc, |
1095 | sense_hdr.ascq); |
1096 | |
1097 | scsi_set_resid(scmnd, |
1098 | cmd_request->data_buffer.len - |
1099 | vm_srb->data_transfer_length); |
1100 | |
1101 | scsi_done_fn = scmnd->scsi_done; |
1102 | |
1103 | scmnd->host_scribble = NULL; |
1104 | scmnd->scsi_done = NULL; |
1105 | |
1106 | scsi_done_fn(scmnd); |
1107 | |
1108 | mempool_free(cmd_request, memp->request_mempool); |
1109 | } |
1110 | |
1111 | static void storvsc_on_io_completion(struct hv_device *device, |
1112 | struct vstor_packet *vstor_packet, |
1113 | struct storvsc_cmd_request *request) |
1114 | { |
1115 | struct storvsc_device *stor_device; |
1116 | struct vstor_packet *stor_pkt; |
1117 | |
1118 | stor_device = hv_get_drvdata(device); |
1119 | stor_pkt = &request->vstor_packet; |
1120 | |
1121 | /* |
1122 | * The current SCSI handling on the host side does |
1123 | * not correctly handle: |
1124 | * INQUIRY command with page code parameter set to 0x80 |
1125 | * MODE_SENSE command with cmd[2] == 0x1c |
1126 | * |
1127 | * Setup srb and scsi status so this won't be fatal. |
1128 | * We do this so we can distinguish truly fatal failues |
1129 | * (srb status == 0x4) and off-line the device in that case. |
1130 | */ |
1131 | |
1132 | if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) || |
1133 | (stor_pkt->vm_srb.cdb[0] == MODE_SENSE)) { |
1134 | vstor_packet->vm_srb.scsi_status = 0; |
1135 | vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS; |
1136 | } |
1137 | |
1138 | |
1139 | /* Copy over the status...etc */ |
1140 | stor_pkt->vm_srb.scsi_status = vstor_packet->vm_srb.scsi_status; |
1141 | stor_pkt->vm_srb.srb_status = vstor_packet->vm_srb.srb_status; |
1142 | stor_pkt->vm_srb.sense_info_length = |
1143 | vstor_packet->vm_srb.sense_info_length; |
1144 | |
1145 | if (vstor_packet->vm_srb.scsi_status != 0 || |
1146 | vstor_packet->vm_srb.srb_status != SRB_STATUS_SUCCESS){ |
1147 | dev_warn(&device->device, |
1148 | "cmd 0x%x scsi status 0x%x srb status 0x%x\n", |
1149 | stor_pkt->vm_srb.cdb[0], |
1150 | vstor_packet->vm_srb.scsi_status, |
1151 | vstor_packet->vm_srb.srb_status); |
1152 | } |
1153 | |
1154 | if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) { |
1155 | /* CHECK_CONDITION */ |
1156 | if (vstor_packet->vm_srb.srb_status & |
1157 | SRB_STATUS_AUTOSENSE_VALID) { |
1158 | /* autosense data available */ |
1159 | dev_warn(&device->device, |
1160 | "stor pkt %p autosense data valid - len %d\n", |
1161 | request, |
1162 | vstor_packet->vm_srb.sense_info_length); |
1163 | |
1164 | memcpy(request->sense_buffer, |
1165 | vstor_packet->vm_srb.sense_data, |
1166 | vstor_packet->vm_srb.sense_info_length); |
1167 | |
1168 | } |
1169 | } |
1170 | |
1171 | stor_pkt->vm_srb.data_transfer_length = |
1172 | vstor_packet->vm_srb.data_transfer_length; |
1173 | |
1174 | storvsc_command_completion(request); |
1175 | |
1176 | if (atomic_dec_and_test(&stor_device->num_outstanding_req) && |
1177 | stor_device->drain_notify) |
1178 | wake_up(&stor_device->waiting_to_drain); |
1179 | |
1180 | |
1181 | } |
1182 | |
1183 | static void storvsc_on_receive(struct hv_device *device, |
1184 | struct vstor_packet *vstor_packet, |
1185 | struct storvsc_cmd_request *request) |
1186 | { |
1187 | struct storvsc_scan_work *work; |
1188 | struct storvsc_device *stor_device; |
1189 | |
1190 | switch (vstor_packet->operation) { |
1191 | case VSTOR_OPERATION_COMPLETE_IO: |
1192 | storvsc_on_io_completion(device, vstor_packet, request); |
1193 | break; |
1194 | |
1195 | case VSTOR_OPERATION_REMOVE_DEVICE: |
1196 | case VSTOR_OPERATION_ENUMERATE_BUS: |
1197 | stor_device = get_in_stor_device(device); |
1198 | work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC); |
1199 | if (!work) |
1200 | return; |
1201 | |
1202 | INIT_WORK(&work->work, storvsc_bus_scan); |
1203 | work->host = stor_device->host; |
1204 | schedule_work(&work->work); |
1205 | break; |
1206 | |
1207 | default: |
1208 | break; |
1209 | } |
1210 | } |
1211 | |
1212 | static void storvsc_on_channel_callback(void *context) |
1213 | { |
1214 | struct vmbus_channel *channel = (struct vmbus_channel *)context; |
1215 | struct hv_device *device; |
1216 | struct storvsc_device *stor_device; |
1217 | u32 bytes_recvd; |
1218 | u64 request_id; |
1219 | unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)]; |
1220 | struct storvsc_cmd_request *request; |
1221 | int ret; |
1222 | |
1223 | if (channel->primary_channel != NULL) |
1224 | device = channel->primary_channel->device_obj; |
1225 | else |
1226 | device = channel->device_obj; |
1227 | |
1228 | stor_device = get_in_stor_device(device); |
1229 | if (!stor_device) |
1230 | return; |
1231 | |
1232 | do { |
1233 | ret = vmbus_recvpacket(channel, packet, |
1234 | ALIGN((sizeof(struct vstor_packet) - |
1235 | vmscsi_size_delta), 8), |
1236 | &bytes_recvd, &request_id); |
1237 | if (ret == 0 && bytes_recvd > 0) { |
1238 | |
1239 | request = (struct storvsc_cmd_request *) |
1240 | (unsigned long)request_id; |
1241 | |
1242 | if ((request == &stor_device->init_request) || |
1243 | (request == &stor_device->reset_request)) { |
1244 | |
1245 | memcpy(&request->vstor_packet, packet, |
1246 | (sizeof(struct vstor_packet) - |
1247 | vmscsi_size_delta)); |
1248 | complete(&request->wait_event); |
1249 | } else { |
1250 | storvsc_on_receive(device, |
1251 | (struct vstor_packet *)packet, |
1252 | request); |
1253 | } |
1254 | } else { |
1255 | break; |
1256 | } |
1257 | } while (1); |
1258 | |
1259 | return; |
1260 | } |
1261 | |
1262 | static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) |
1263 | { |
1264 | struct vmstorage_channel_properties props; |
1265 | int ret; |
1266 | |
1267 | memset(&props, 0, sizeof(struct vmstorage_channel_properties)); |
1268 | |
1269 | ret = vmbus_open(device->channel, |
1270 | ring_size, |
1271 | ring_size, |
1272 | (void *)&props, |
1273 | sizeof(struct vmstorage_channel_properties), |
1274 | storvsc_on_channel_callback, device->channel); |
1275 | |
1276 | if (ret != 0) |
1277 | return ret; |
1278 | |
1279 | ret = storvsc_channel_init(device); |
1280 | |
1281 | return ret; |
1282 | } |
1283 | |
1284 | static int storvsc_dev_remove(struct hv_device *device) |
1285 | { |
1286 | struct storvsc_device *stor_device; |
1287 | unsigned long flags; |
1288 | |
1289 | stor_device = hv_get_drvdata(device); |
1290 | |
1291 | spin_lock_irqsave(&device->channel->inbound_lock, flags); |
1292 | stor_device->destroy = true; |
1293 | spin_unlock_irqrestore(&device->channel->inbound_lock, flags); |
1294 | |
1295 | /* |
1296 | * At this point, all outbound traffic should be disable. We |
1297 | * only allow inbound traffic (responses) to proceed so that |
1298 | * outstanding requests can be completed. |
1299 | */ |
1300 | |
1301 | storvsc_wait_to_drain(stor_device); |
1302 | |
1303 | /* |
1304 | * Since we have already drained, we don't need to busy wait |
1305 | * as was done in final_release_stor_device() |
1306 | * Note that we cannot set the ext pointer to NULL until |
1307 | * we have drained - to drain the outgoing packets, we need to |
1308 | * allow incoming packets. |
1309 | */ |
1310 | spin_lock_irqsave(&device->channel->inbound_lock, flags); |
1311 | hv_set_drvdata(device, NULL); |
1312 | spin_unlock_irqrestore(&device->channel->inbound_lock, flags); |
1313 | |
1314 | /* Close the channel */ |
1315 | vmbus_close(device->channel); |
1316 | |
1317 | kfree(stor_device); |
1318 | return 0; |
1319 | } |
1320 | |
1321 | static int storvsc_do_io(struct hv_device *device, |
1322 | struct storvsc_cmd_request *request) |
1323 | { |
1324 | struct storvsc_device *stor_device; |
1325 | struct vstor_packet *vstor_packet; |
1326 | struct vmbus_channel *outgoing_channel; |
1327 | int ret = 0; |
1328 | |
1329 | vstor_packet = &request->vstor_packet; |
1330 | stor_device = get_out_stor_device(device); |
1331 | |
1332 | if (!stor_device) |
1333 | return -ENODEV; |
1334 | |
1335 | |
1336 | request->device = device; |
1337 | /* |
1338 | * Select an an appropriate channel to send the request out. |
1339 | */ |
1340 | |
1341 | outgoing_channel = vmbus_get_outgoing_channel(device->channel); |
1342 | |
1343 | |
1344 | vstor_packet->flags |= REQUEST_COMPLETION_FLAG; |
1345 | |
1346 | vstor_packet->vm_srb.length = (sizeof(struct vmscsi_request) - |
1347 | vmscsi_size_delta); |
1348 | |
1349 | |
1350 | vstor_packet->vm_srb.sense_info_length = sense_buffer_size; |
1351 | |
1352 | |
1353 | vstor_packet->vm_srb.data_transfer_length = |
1354 | request->data_buffer.len; |
1355 | |
1356 | vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB; |
1357 | |
1358 | if (request->data_buffer.len) { |
1359 | ret = vmbus_sendpacket_multipagebuffer(outgoing_channel, |
1360 | &request->data_buffer, |
1361 | vstor_packet, |
1362 | (sizeof(struct vstor_packet) - |
1363 | vmscsi_size_delta), |
1364 | (unsigned long)request); |
1365 | } else { |
1366 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
1367 | (sizeof(struct vstor_packet) - |
1368 | vmscsi_size_delta), |
1369 | (unsigned long)request, |
1370 | VM_PKT_DATA_INBAND, |
1371 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); |
1372 | } |
1373 | |
1374 | if (ret != 0) |
1375 | return ret; |
1376 | |
1377 | atomic_inc(&stor_device->num_outstanding_req); |
1378 | |
1379 | return ret; |
1380 | } |
1381 | |
1382 | static int storvsc_device_alloc(struct scsi_device *sdevice) |
1383 | { |
1384 | struct stor_mem_pools *memp; |
1385 | int number = STORVSC_MIN_BUF_NR; |
1386 | |
1387 | memp = kzalloc(sizeof(struct stor_mem_pools), GFP_KERNEL); |
1388 | if (!memp) |
1389 | return -ENOMEM; |
1390 | |
1391 | memp->request_pool = |
1392 | kmem_cache_create(dev_name(&sdevice->sdev_dev), |
1393 | sizeof(struct storvsc_cmd_request), 0, |
1394 | SLAB_HWCACHE_ALIGN, NULL); |
1395 | |
1396 | if (!memp->request_pool) |
1397 | goto err0; |
1398 | |
1399 | memp->request_mempool = mempool_create(number, mempool_alloc_slab, |
1400 | mempool_free_slab, |
1401 | memp->request_pool); |
1402 | |
1403 | if (!memp->request_mempool) |
1404 | goto err1; |
1405 | |
1406 | sdevice->hostdata = memp; |
1407 | |
1408 | return 0; |
1409 | |
1410 | err1: |
1411 | kmem_cache_destroy(memp->request_pool); |
1412 | |
1413 | err0: |
1414 | kfree(memp); |
1415 | return -ENOMEM; |
1416 | } |
1417 | |
1418 | static void storvsc_device_destroy(struct scsi_device *sdevice) |
1419 | { |
1420 | struct stor_mem_pools *memp = sdevice->hostdata; |
1421 | |
1422 | mempool_destroy(memp->request_mempool); |
1423 | kmem_cache_destroy(memp->request_pool); |
1424 | kfree(memp); |
1425 | sdevice->hostdata = NULL; |
1426 | } |
1427 | |
1428 | static int storvsc_device_configure(struct scsi_device *sdevice) |
1429 | { |
1430 | scsi_adjust_queue_depth(sdevice, MSG_SIMPLE_TAG, |
1431 | STORVSC_MAX_IO_REQUESTS); |
1432 | |
1433 | blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE); |
1434 | |
1435 | blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY); |
1436 | |
1437 | blk_queue_rq_timeout(sdevice->request_queue, (storvsc_timeout * HZ)); |
1438 | |
1439 | sdevice->no_write_same = 1; |
1440 | |
1441 | return 0; |
1442 | } |
1443 | |
1444 | static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev, |
1445 | sector_t capacity, int *info) |
1446 | { |
1447 | sector_t nsect = capacity; |
1448 | sector_t cylinders = nsect; |
1449 | int heads, sectors_pt; |
1450 | |
1451 | /* |
1452 | * We are making up these values; let us keep it simple. |
1453 | */ |
1454 | heads = 0xff; |
1455 | sectors_pt = 0x3f; /* Sectors per track */ |
1456 | sector_div(cylinders, heads * sectors_pt); |
1457 | if ((sector_t)(cylinders + 1) * heads * sectors_pt < nsect) |
1458 | cylinders = 0xffff; |
1459 | |
1460 | info[0] = heads; |
1461 | info[1] = sectors_pt; |
1462 | info[2] = (int)cylinders; |
1463 | |
1464 | return 0; |
1465 | } |
1466 | |
1467 | static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) |
1468 | { |
1469 | struct hv_host_device *host_dev = shost_priv(scmnd->device->host); |
1470 | struct hv_device *device = host_dev->dev; |
1471 | |
1472 | struct storvsc_device *stor_device; |
1473 | struct storvsc_cmd_request *request; |
1474 | struct vstor_packet *vstor_packet; |
1475 | int ret, t; |
1476 | |
1477 | |
1478 | stor_device = get_out_stor_device(device); |
1479 | if (!stor_device) |
1480 | return FAILED; |
1481 | |
1482 | request = &stor_device->reset_request; |
1483 | vstor_packet = &request->vstor_packet; |
1484 | |
1485 | init_completion(&request->wait_event); |
1486 | |
1487 | vstor_packet->operation = VSTOR_OPERATION_RESET_BUS; |
1488 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; |
1489 | vstor_packet->vm_srb.path_id = stor_device->path_id; |
1490 | |
1491 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
1492 | (sizeof(struct vstor_packet) - |
1493 | vmscsi_size_delta), |
1494 | (unsigned long)&stor_device->reset_request, |
1495 | VM_PKT_DATA_INBAND, |
1496 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); |
1497 | if (ret != 0) |
1498 | return FAILED; |
1499 | |
1500 | t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
1501 | if (t == 0) |
1502 | return TIMEOUT_ERROR; |
1503 | |
1504 | |
1505 | /* |
1506 | * At this point, all outstanding requests in the adapter |
1507 | * should have been flushed out and return to us |
1508 | * There is a potential race here where the host may be in |
1509 | * the process of responding when we return from here. |
1510 | * Just wait for all in-transit packets to be accounted for |
1511 | * before we return from here. |
1512 | */ |
1513 | storvsc_wait_to_drain(stor_device); |
1514 | |
1515 | return SUCCESS; |
1516 | } |
1517 | |
1518 | static bool storvsc_scsi_cmd_ok(struct scsi_cmnd *scmnd) |
1519 | { |
1520 | bool allowed = true; |
1521 | u8 scsi_op = scmnd->cmnd[0]; |
1522 | |
1523 | switch (scsi_op) { |
1524 | /* the host does not handle WRITE_SAME, log accident usage */ |
1525 | case WRITE_SAME: |
1526 | /* |
1527 | * smartd sends this command and the host does not handle |
1528 | * this. So, don't send it. |
1529 | */ |
1530 | case SET_WINDOW: |
1531 | scmnd->result = ILLEGAL_REQUEST << 16; |
1532 | allowed = false; |
1533 | break; |
1534 | default: |
1535 | break; |
1536 | } |
1537 | return allowed; |
1538 | } |
1539 | |
1540 | static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) |
1541 | { |
1542 | int ret; |
1543 | struct hv_host_device *host_dev = shost_priv(host); |
1544 | struct hv_device *dev = host_dev->dev; |
1545 | struct storvsc_cmd_request *cmd_request; |
1546 | unsigned int request_size = 0; |
1547 | int i; |
1548 | struct scatterlist *sgl; |
1549 | unsigned int sg_count = 0; |
1550 | struct vmscsi_request *vm_srb; |
1551 | struct stor_mem_pools *memp = scmnd->device->hostdata; |
1552 | |
1553 | if (!storvsc_scsi_cmd_ok(scmnd)) { |
1554 | scmnd->scsi_done(scmnd); |
1555 | return 0; |
1556 | } |
1557 | |
1558 | request_size = sizeof(struct storvsc_cmd_request); |
1559 | |
1560 | cmd_request = mempool_alloc(memp->request_mempool, |
1561 | GFP_ATOMIC); |
1562 | |
1563 | /* |
1564 | * We might be invoked in an interrupt context; hence |
1565 | * mempool_alloc() can fail. |
1566 | */ |
1567 | if (!cmd_request) |
1568 | return SCSI_MLQUEUE_DEVICE_BUSY; |
1569 | |
1570 | memset(cmd_request, 0, sizeof(struct storvsc_cmd_request)); |
1571 | |
1572 | /* Setup the cmd request */ |
1573 | cmd_request->cmd = scmnd; |
1574 | |
1575 | scmnd->host_scribble = (unsigned char *)cmd_request; |
1576 | |
1577 | vm_srb = &cmd_request->vstor_packet.vm_srb; |
1578 | vm_srb->win8_extension.time_out_value = 60; |
1579 | |
1580 | |
1581 | /* Build the SRB */ |
1582 | switch (scmnd->sc_data_direction) { |
1583 | case DMA_TO_DEVICE: |
1584 | vm_srb->data_in = WRITE_TYPE; |
1585 | vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_OUT; |
1586 | vm_srb->win8_extension.srb_flags |= |
1587 | (SRB_FLAGS_QUEUE_ACTION_ENABLE | |
1588 | SRB_FLAGS_DISABLE_SYNCH_TRANSFER); |
1589 | break; |
1590 | case DMA_FROM_DEVICE: |
1591 | vm_srb->data_in = READ_TYPE; |
1592 | vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_IN; |
1593 | vm_srb->win8_extension.srb_flags |= |
1594 | (SRB_FLAGS_QUEUE_ACTION_ENABLE | |
1595 | SRB_FLAGS_DISABLE_SYNCH_TRANSFER); |
1596 | break; |
1597 | default: |
1598 | vm_srb->data_in = UNKNOWN_TYPE; |
1599 | vm_srb->win8_extension.srb_flags = 0; |
1600 | break; |
1601 | } |
1602 | |
1603 | |
1604 | vm_srb->port_number = host_dev->port; |
1605 | vm_srb->path_id = scmnd->device->channel; |
1606 | vm_srb->target_id = scmnd->device->id; |
1607 | vm_srb->lun = scmnd->device->lun; |
1608 | |
1609 | vm_srb->cdb_length = scmnd->cmd_len; |
1610 | |
1611 | memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length); |
1612 | |
1613 | cmd_request->sense_buffer = scmnd->sense_buffer; |
1614 | |
1615 | |
1616 | cmd_request->data_buffer.len = scsi_bufflen(scmnd); |
1617 | if (scsi_sg_count(scmnd)) { |
1618 | sgl = (struct scatterlist *)scsi_sglist(scmnd); |
1619 | sg_count = scsi_sg_count(scmnd); |
1620 | |
1621 | /* check if we need to bounce the sgl */ |
1622 | if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) { |
1623 | cmd_request->bounce_sgl = |
1624 | create_bounce_buffer(sgl, scsi_sg_count(scmnd), |
1625 | scsi_bufflen(scmnd), |
1626 | vm_srb->data_in); |
1627 | if (!cmd_request->bounce_sgl) { |
1628 | ret = SCSI_MLQUEUE_HOST_BUSY; |
1629 | goto queue_error; |
1630 | } |
1631 | |
1632 | cmd_request->bounce_sgl_count = |
1633 | ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >> |
1634 | PAGE_SHIFT; |
1635 | |
1636 | if (vm_srb->data_in == WRITE_TYPE) |
1637 | copy_to_bounce_buffer(sgl, |
1638 | cmd_request->bounce_sgl, |
1639 | scsi_sg_count(scmnd)); |
1640 | |
1641 | sgl = cmd_request->bounce_sgl; |
1642 | sg_count = cmd_request->bounce_sgl_count; |
1643 | } |
1644 | |
1645 | cmd_request->data_buffer.offset = sgl[0].offset; |
1646 | |
1647 | for (i = 0; i < sg_count; i++) |
1648 | cmd_request->data_buffer.pfn_array[i] = |
1649 | page_to_pfn(sg_page((&sgl[i]))); |
1650 | |
1651 | } else if (scsi_sglist(scmnd)) { |
1652 | cmd_request->data_buffer.offset = |
1653 | virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1); |
1654 | cmd_request->data_buffer.pfn_array[0] = |
1655 | virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT; |
1656 | } |
1657 | |
1658 | /* Invokes the vsc to start an IO */ |
1659 | ret = storvsc_do_io(dev, cmd_request); |
1660 | |
1661 | if (ret == -EAGAIN) { |
1662 | /* no more space */ |
1663 | |
1664 | if (cmd_request->bounce_sgl_count) { |
1665 | destroy_bounce_buffer(cmd_request->bounce_sgl, |
1666 | cmd_request->bounce_sgl_count); |
1667 | |
1668 | ret = SCSI_MLQUEUE_DEVICE_BUSY; |
1669 | goto queue_error; |
1670 | } |
1671 | } |
1672 | |
1673 | return 0; |
1674 | |
1675 | queue_error: |
1676 | mempool_free(cmd_request, memp->request_mempool); |
1677 | scmnd->host_scribble = NULL; |
1678 | return ret; |
1679 | } |
1680 | |
1681 | static struct scsi_host_template scsi_driver = { |
1682 | .module = THIS_MODULE, |
1683 | .name = "storvsc_host_t", |
1684 | .bios_param = storvsc_get_chs, |
1685 | .queuecommand = storvsc_queuecommand, |
1686 | .eh_host_reset_handler = storvsc_host_reset_handler, |
1687 | .slave_alloc = storvsc_device_alloc, |
1688 | .slave_destroy = storvsc_device_destroy, |
1689 | .slave_configure = storvsc_device_configure, |
1690 | .cmd_per_lun = 1, |
1691 | /* 64 max_queue * 1 target */ |
1692 | .can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS, |
1693 | .this_id = -1, |
1694 | /* no use setting to 0 since ll_blk_rw reset it to 1 */ |
1695 | /* currently 32 */ |
1696 | .sg_tablesize = MAX_MULTIPAGE_BUFFER_COUNT, |
1697 | .use_clustering = DISABLE_CLUSTERING, |
1698 | /* Make sure we dont get a sg segment crosses a page boundary */ |
1699 | .dma_boundary = PAGE_SIZE-1, |
1700 | }; |
1701 | |
1702 | enum { |
1703 | SCSI_GUID, |
1704 | IDE_GUID, |
1705 | SFC_GUID, |
1706 | }; |
1707 | |
1708 | static const struct hv_vmbus_device_id id_table[] = { |
1709 | /* SCSI guid */ |
1710 | { HV_SCSI_GUID, |
1711 | .driver_data = SCSI_GUID |
1712 | }, |
1713 | /* IDE guid */ |
1714 | { HV_IDE_GUID, |
1715 | .driver_data = IDE_GUID |
1716 | }, |
1717 | /* Fibre Channel GUID */ |
1718 | { |
1719 | HV_SYNTHFC_GUID, |
1720 | .driver_data = SFC_GUID |
1721 | }, |
1722 | { }, |
1723 | }; |
1724 | |
1725 | MODULE_DEVICE_TABLE(vmbus, id_table); |
1726 | |
1727 | static int storvsc_probe(struct hv_device *device, |
1728 | const struct hv_vmbus_device_id *dev_id) |
1729 | { |
1730 | int ret; |
1731 | struct Scsi_Host *host; |
1732 | struct hv_host_device *host_dev; |
1733 | bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false); |
1734 | int target = 0; |
1735 | struct storvsc_device *stor_device; |
1736 | |
1737 | /* |
1738 | * Based on the windows host we are running on, |
1739 | * set state to properly communicate with the host. |
1740 | */ |
1741 | |
1742 | if (vmbus_proto_version == VERSION_WIN8) { |
1743 | sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE; |
1744 | vmscsi_size_delta = 0; |
1745 | vmstor_current_major = VMSTOR_WIN8_MAJOR; |
1746 | vmstor_current_minor = VMSTOR_WIN8_MINOR; |
1747 | } else { |
1748 | sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE; |
1749 | vmscsi_size_delta = sizeof(struct vmscsi_win8_extension); |
1750 | vmstor_current_major = VMSTOR_WIN7_MAJOR; |
1751 | vmstor_current_minor = VMSTOR_WIN7_MINOR; |
1752 | } |
1753 | |
1754 | |
1755 | host = scsi_host_alloc(&scsi_driver, |
1756 | sizeof(struct hv_host_device)); |
1757 | if (!host) |
1758 | return -ENOMEM; |
1759 | |
1760 | host_dev = shost_priv(host); |
1761 | memset(host_dev, 0, sizeof(struct hv_host_device)); |
1762 | |
1763 | host_dev->port = host->host_no; |
1764 | host_dev->dev = device; |
1765 | |
1766 | |
1767 | stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL); |
1768 | if (!stor_device) { |
1769 | ret = -ENOMEM; |
1770 | goto err_out0; |
1771 | } |
1772 | |
1773 | stor_device->destroy = false; |
1774 | stor_device->open_sub_channel = false; |
1775 | init_waitqueue_head(&stor_device->waiting_to_drain); |
1776 | stor_device->device = device; |
1777 | stor_device->host = host; |
1778 | hv_set_drvdata(device, stor_device); |
1779 | |
1780 | stor_device->port_number = host->host_no; |
1781 | ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size); |
1782 | if (ret) |
1783 | goto err_out1; |
1784 | |
1785 | host_dev->path = stor_device->path_id; |
1786 | host_dev->target = stor_device->target_id; |
1787 | |
1788 | /* max # of devices per target */ |
1789 | host->max_lun = STORVSC_MAX_LUNS_PER_TARGET; |
1790 | /* max # of targets per channel */ |
1791 | host->max_id = STORVSC_MAX_TARGETS; |
1792 | /* max # of channels */ |
1793 | host->max_channel = STORVSC_MAX_CHANNELS - 1; |
1794 | /* max cmd length */ |
1795 | host->max_cmd_len = STORVSC_MAX_CMD_LEN; |
1796 | |
1797 | /* Register the HBA and start the scsi bus scan */ |
1798 | ret = scsi_add_host(host, &device->device); |
1799 | if (ret != 0) |
1800 | goto err_out2; |
1801 | |
1802 | if (!dev_is_ide) { |
1803 | scsi_scan_host(host); |
1804 | } else { |
1805 | target = (device->dev_instance.b[5] << 8 | |
1806 | device->dev_instance.b[4]); |
1807 | ret = scsi_add_device(host, 0, target, 0); |
1808 | if (ret) { |
1809 | scsi_remove_host(host); |
1810 | goto err_out2; |
1811 | } |
1812 | } |
1813 | return 0; |
1814 | |
1815 | err_out2: |
1816 | /* |
1817 | * Once we have connected with the host, we would need to |
1818 | * to invoke storvsc_dev_remove() to rollback this state and |
1819 | * this call also frees up the stor_device; hence the jump around |
1820 | * err_out1 label. |
1821 | */ |
1822 | storvsc_dev_remove(device); |
1823 | goto err_out0; |
1824 | |
1825 | err_out1: |
1826 | kfree(stor_device); |
1827 | |
1828 | err_out0: |
1829 | scsi_host_put(host); |
1830 | return ret; |
1831 | } |
1832 | |
1833 | static int storvsc_remove(struct hv_device *dev) |
1834 | { |
1835 | struct storvsc_device *stor_device = hv_get_drvdata(dev); |
1836 | struct Scsi_Host *host = stor_device->host; |
1837 | |
1838 | scsi_remove_host(host); |
1839 | storvsc_dev_remove(dev); |
1840 | scsi_host_put(host); |
1841 | |
1842 | return 0; |
1843 | } |
1844 | |
1845 | static struct hv_driver storvsc_drv = { |
1846 | .name = KBUILD_MODNAME, |
1847 | .id_table = id_table, |
1848 | .probe = storvsc_probe, |
1849 | .remove = storvsc_remove, |
1850 | }; |
1851 | |
1852 | static int __init storvsc_drv_init(void) |
1853 | { |
1854 | u32 max_outstanding_req_per_channel; |
1855 | |
1856 | /* |
1857 | * Divide the ring buffer data size (which is 1 page less |
1858 | * than the ring buffer size since that page is reserved for |
1859 | * the ring buffer indices) by the max request size (which is |
1860 | * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) |
1861 | */ |
1862 | max_outstanding_req_per_channel = |
1863 | ((storvsc_ringbuffer_size - PAGE_SIZE) / |
1864 | ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + |
1865 | sizeof(struct vstor_packet) + sizeof(u64) - |
1866 | vmscsi_size_delta, |
1867 | sizeof(u64))); |
1868 | |
1869 | if (max_outstanding_req_per_channel < |
1870 | STORVSC_MAX_IO_REQUESTS) |
1871 | return -EINVAL; |
1872 | |
1873 | return vmbus_driver_register(&storvsc_drv); |
1874 | } |
1875 | |
1876 | static void __exit storvsc_drv_exit(void) |
1877 | { |
1878 | vmbus_driver_unregister(&storvsc_drv); |
1879 | } |
1880 | |
1881 | MODULE_LICENSE("GPL"); |
1882 | MODULE_VERSION(HV_DRV_VERSION); |
1883 | MODULE_DESCRIPTION("Microsoft Hyper-V virtual storage driver"); |
1884 | module_init(storvsc_drv_init); |
1885 | module_exit(storvsc_drv_exit); |
1886 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9