4 * Copyright (C) 2004 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
5 * Copyright (C) 2004 - 2005 Leonid Stoljar
6 * Copyright (C) 2007 Ming Zhang <blackmagic02881 at gmail dot com>
7 * Copyright (C) 2007 Ross Walker <rswwalker at hotmail dot com>
8 * Copyright (C) 2007 - 2009 ID7 Ltd.
10 * SCSI disk (type 0) and CDROM (type 5) dev handler using files
11 * on file systems or block devices (VDISK)
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation, version 2
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
24 #include <linux/file.h>
26 #include <linux/string.h>
27 #include <linux/types.h>
28 #include <linux/unistd.h>
29 #include <linux/smp_lock.h>
30 #include <linux/spinlock.h>
31 #include <linux/init.h>
32 #include <linux/uio.h>
33 #include <linux/list.h>
34 #include <linux/ctype.h>
35 #include <linux/writeback.h>
36 #include <linux/vmalloc.h>
37 #include <asm/atomic.h>
38 #include <linux/kthread.h>
39 #include <linux/sched.h>
40 #include <linux/version.h>
41 #include <asm/div64.h>
43 #define LOG_PREFIX "dev_vdisk"
47 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
49 #define TRACE_ORDER 0x80000000
51 static struct scst_trace_log vdisk_local_trace_tbl[] =
53 { TRACE_ORDER, "order" },
56 #define trace_log_tbl vdisk_local_trace_tbl
58 #define VDISK_TRACE_TLB_HELP ", order"
62 #include "scst_dev_handler.h"
64 /* 8 byte ASCII Vendor */
65 #define SCST_FIO_VENDOR "SCST_FIO"
66 #define SCST_BIO_VENDOR "SCST_BIO"
67 /* 4 byte ASCII Product Revision Level - left aligned */
68 #define SCST_FIO_REV " 200"
70 #define MAX_USN_LEN (20+1) /* For '\0' */
72 #define INQ_BUF_SZ 128
76 #define MSENSE_BUF_SZ 256
77 #define DBD 0x08 /* disable block descriptor */
78 #define WP 0x80 /* write protect */
79 #define DPOFUA 0x10 /* DPOFUA bit */
80 #define WCE 0x04 /* write cache enable */
82 #define PF 0x10 /* page format */
83 #define SP 0x01 /* save pages */
84 #define PS 0x80 /* parameter saveable */
87 #define DEF_DISK_BLOCKSIZE_SHIFT 9
88 #define DEF_DISK_BLOCKSIZE (1 << DEF_DISK_BLOCKSIZE_SHIFT)
89 #define DEF_CDROM_BLOCKSIZE_SHIFT 11
90 #define DEF_CDROM_BLOCKSIZE (1 << DEF_CDROM_BLOCKSIZE_SHIFT)
91 #define DEF_SECTORS 56
93 #define LEN_MEM (32 * 1024)
95 #define VDISK_NULLIO_SIZE (3LL*1024*1024*1024*1024/2)
97 #define VDEV_NONE_FILENAME "none"
99 #define DEF_TST SCST_CONTR_MODE_SEP_TASK_SETS
101 * Since we can't control backstorage device's reordering, we have to always
102 * report unrestricted reordering.
104 #define DEF_QUEUE_ALG_WT SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
105 #define DEF_QUEUE_ALG SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
109 #define DEF_DSENSE SCST_CONTR_MODE_FIXED_SENSE
111 #ifdef CONFIG_SCST_PROC
112 #define VDISK_PROC_HELP "help"
115 static unsigned int random_values[256] = {
116 9862592UL, 3744545211UL, 2348289082UL, 4036111983UL,
117 435574201UL, 3110343764UL, 2383055570UL, 1826499182UL,
118 4076766377UL, 1549935812UL, 3696752161UL, 1200276050UL,
119 3878162706UL, 1783530428UL, 2291072214UL, 125807985UL,
120 3407668966UL, 547437109UL, 3961389597UL, 969093968UL,
121 56006179UL, 2591023451UL, 1849465UL, 1614540336UL,
122 3699757935UL, 479961779UL, 3768703953UL, 2529621525UL,
123 4157893312UL, 3673555386UL, 4091110867UL, 2193909423UL,
124 2800464448UL, 3052113233UL, 450394455UL, 3424338713UL,
125 2113709130UL, 4082064373UL, 3708640918UL, 3841182218UL,
126 3141803315UL, 1032476030UL, 1166423150UL, 1169646901UL,
127 2686611738UL, 575517645UL, 2829331065UL, 1351103339UL,
128 2856560215UL, 2402488288UL, 867847666UL, 8524618UL,
129 704790297UL, 2228765657UL, 231508411UL, 1425523814UL,
130 2146764591UL, 1287631730UL, 4142687914UL, 3879884598UL,
131 729945311UL, 310596427UL, 2263511876UL, 1983091134UL,
132 3500916580UL, 1642490324UL, 3858376049UL, 695342182UL,
133 780528366UL, 1372613640UL, 1100993200UL, 1314818946UL,
134 572029783UL, 3775573540UL, 776262915UL, 2684520905UL,
135 1007252738UL, 3505856396UL, 1974886670UL, 3115856627UL,
136 4194842288UL, 2135793908UL, 3566210707UL, 7929775UL,
137 1321130213UL, 2627281746UL, 3587067247UL, 2025159890UL,
138 2587032000UL, 3098513342UL, 3289360258UL, 130594898UL,
139 2258149812UL, 2275857755UL, 3966929942UL, 1521739999UL,
140 4191192765UL, 958953550UL, 4153558347UL, 1011030335UL,
141 524382185UL, 4099757640UL, 498828115UL, 2396978754UL,
142 328688935UL, 826399828UL, 3174103611UL, 3921966365UL,
143 2187456284UL, 2631406787UL, 3930669674UL, 4282803915UL,
144 1776755417UL, 374959755UL, 2483763076UL, 844956392UL,
145 2209187588UL, 3647277868UL, 291047860UL, 3485867047UL,
146 2223103546UL, 2526736133UL, 3153407604UL, 3828961796UL,
147 3355731910UL, 2322269798UL, 2752144379UL, 519897942UL,
148 3430536488UL, 1801511593UL, 1953975728UL, 3286944283UL,
149 1511612621UL, 1050133852UL, 409321604UL, 1037601109UL,
150 3352316843UL, 4198371381UL, 617863284UL, 994672213UL,
151 1540735436UL, 2337363549UL, 1242368492UL, 665473059UL,
152 2330728163UL, 3443103219UL, 2291025133UL, 3420108120UL,
153 2663305280UL, 1608969839UL, 2278959931UL, 1389747794UL,
154 2226946970UL, 2131266900UL, 3856979144UL, 1894169043UL,
155 2692697628UL, 3797290626UL, 3248126844UL, 3922786277UL,
156 343705271UL, 3739749888UL, 2191310783UL, 2962488787UL,
157 4119364141UL, 1403351302UL, 2984008923UL, 3822407178UL,
158 1932139782UL, 2323869332UL, 2793574182UL, 1852626483UL,
159 2722460269UL, 1136097522UL, 1005121083UL, 1805201184UL,
160 2212824936UL, 2979547931UL, 4133075915UL, 2585731003UL,
161 2431626071UL, 134370235UL, 3763236829UL, 1171434827UL,
162 2251806994UL, 1289341038UL, 3616320525UL, 392218563UL,
163 1544502546UL, 2993937212UL, 1957503701UL, 3579140080UL,
164 4270846116UL, 2030149142UL, 1792286022UL, 366604999UL,
165 2625579499UL, 790898158UL, 770833822UL, 815540197UL,
166 2747711781UL, 3570468835UL, 3976195842UL, 1257621341UL,
167 1198342980UL, 1860626190UL, 3247856686UL, 351473955UL,
168 993440563UL, 340807146UL, 1041994520UL, 3573925241UL,
169 480246395UL, 2104806831UL, 1020782793UL, 3362132583UL,
170 2272911358UL, 3440096248UL, 2356596804UL, 259492703UL,
171 3899500740UL, 252071876UL, 2177024041UL, 4284810959UL,
172 2775999888UL, 2653420445UL, 2876046047UL, 1025771859UL,
173 1994475651UL, 3564987377UL, 4112956647UL, 1821511719UL,
174 3113447247UL, 455315102UL, 1585273189UL, 2311494568UL,
175 774051541UL, 1898115372UL, 2637499516UL, 247231365UL,
176 1475014417UL, 803585727UL, 3911097303UL, 1714292230UL,
177 476579326UL, 2496900974UL, 3397613314UL, 341202244UL,
178 807790202UL, 4221326173UL, 499979741UL, 1301488547UL,
179 1056807896UL, 3525009458UL, 1174811641UL, 3049738746UL,
184 struct scst_vdisk_dev {
188 loff_t file_size; /* in bytes */
191 * This lock can be taken on both SIRQ and thread context, but in
192 * all cases for each particular instance it's taken consistenly either
193 * on SIRQ or thread context. Mix of them is forbidden.
195 spinlock_t flags_lock;
198 * Below flags are protected by flags_lock or suspended activity
199 * with scst_vdisk_mutex.
201 unsigned int rd_only:1;
202 unsigned int wt_flag:1;
203 unsigned int nv_cache:1;
204 unsigned int o_direct_flag:1;
205 unsigned int media_changed:1;
206 unsigned int prevent_allow_medium_removal:1;
207 unsigned int nullio:1;
208 unsigned int blockio:1;
209 unsigned int cdrom_empty:1;
210 unsigned int removable:1;
213 char name[16+1]; /* Name of the virtual device,
214 must be <= SCSI Model + 1 */
215 char *file_name; /* File name */
216 char usn[MAX_USN_LEN];
217 struct scst_device *dev;
218 struct list_head vdisk_dev_list_entry;
220 const struct vdev_type *vdt;
223 struct scst_vdisk_tgt_dev {
225 * Used without locking since SCST core ensures that only commands
226 * with the same ORDERED type per tgt_dev can be processed
229 enum scst_cmd_queue_type last_write_cmd_queue_type;
232 struct scst_vdisk_thr {
233 struct scst_thr_data_hdr hdr;
235 struct block_device *bdev;
241 *** We make virtual devices emulation in OOP-like fashion: vdev is
242 *** an abstract class serving SPC set of commands and some common management
243 *** tasks, vdisk - an SBC (abstract) class with fileio, blockio and nullio
244 *** end classes, vcdrom - an MMC device class.
246 *** Unfortunately, C doesn't support encapsulation and inheritance, so we
247 *** have to open code it, which makes the code look much less beautiful, than
250 *** Only part to of the work is done. The second half is ToDo.
253 /* VDEV sysfs actions */
254 #define VDEV_ACTION_OPEN 0
255 #define VDEV_ACTION_CLOSE 1
257 /* VDISK sysfs actions */
258 #define VDISK_ACTION_RESYNC_SIZE 100
260 /* VCDROM sysfs actions */
261 #define VCDROM_ACTION_CHANGE 100
263 struct vdev_type_funcs {
264 struct scst_vdisk_dev *(*vdev_create) (struct vdev_type *vdt);
265 void (*vdev_destroy) (struct scst_vdisk_dev *virt_dev);
267 void (*vdev_init) (struct vdev_type *vdt,
268 struct scst_vdisk_dev *virt_dev);
269 void (*vdev_deinit) (struct scst_vdisk_dev *virt_dev);
271 /* Both supposed to be called under scst_vdisk_mutex */
272 int (*vdev_open) (struct vdev_type *vdt, char *p, const char *name);
273 int (*vdev_close) (struct vdev_type *vdt, const char *name);
275 /* All 3 supposed to be called under scst_vdisk_mutex */
276 void (*vdev_add) (struct scst_vdisk_dev *virt_dev);
277 void (*vdev_del) (struct scst_vdisk_dev *virt_dev);
278 struct scst_vdisk_dev *(*vdev_find) (const char *name);
280 int (*parse_cmd) (struct vdev_type *vdt, char *p, int *action);
282 /* Supposed to be called under scst_vdisk_mutex */
283 int (*perform_cmd) (struct vdev_type *vdt, int action, char *p,
286 int (*parse_option) (struct scst_vdisk_dev *virt_dev, char *p);
288 int (*pre_register) (struct scst_vdisk_dev *virt_dev);
292 const char *vdt_name;
293 const char *help_string;
295 struct scst_dev_type *vdt_devt;
297 struct vdev_type_funcs vfns;
300 struct vdisk_fileio_type {
301 struct vdev_type parent_vdt;
302 struct vdev_type_funcs parent_vdt_vfns;
305 struct vdisk_blockio_type {
306 struct vdev_type parent_vdt;
307 struct vdev_type_funcs parent_vdt_vfns;
310 struct vdisk_nullio_type {
311 struct vdev_type parent_vdt;
312 struct vdev_type_funcs parent_vdt_vfns;
316 struct vdev_type parent_vdt;
317 struct vdev_type_funcs parent_vdt_vfns;
320 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
321 #define DEF_NUM_THREADS 5
323 /* Context RA patch supposed to be applied on the kernel */
324 #define DEF_NUM_THREADS 8
326 static int num_threads = DEF_NUM_THREADS;
328 module_param_named(num_threads, num_threads, int, S_IRUGO);
329 MODULE_PARM_DESC(num_threads, "vdisk threads count");
331 static int vdisk_attach(struct scst_device *dev);
332 static void vdisk_detach(struct scst_device *dev);
333 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev);
334 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev);
335 static int vdisk_parse(struct scst_cmd *);
336 static int vdisk_do_job(struct scst_cmd *cmd);
337 static int vcdrom_parse(struct scst_cmd *);
338 static int vcdrom_exec(struct scst_cmd *cmd);
339 static void vdisk_exec_read(struct scst_cmd *cmd,
340 struct scst_vdisk_thr *thr, loff_t loff);
341 static void vdisk_exec_write(struct scst_cmd *cmd,
342 struct scst_vdisk_thr *thr, loff_t loff);
343 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
344 u64 lba_start, int write);
345 static void vdisk_exec_verify(struct scst_cmd *cmd,
346 struct scst_vdisk_thr *thr, loff_t loff);
347 static void vdisk_exec_read_capacity(struct scst_cmd *cmd);
348 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd);
349 static void vdisk_exec_inquiry(struct scst_cmd *cmd);
350 static void vdisk_exec_request_sense(struct scst_cmd *cmd);
351 static void vdisk_exec_mode_sense(struct scst_cmd *cmd);
352 static void vdisk_exec_mode_select(struct scst_cmd *cmd);
353 static void vdisk_exec_log(struct scst_cmd *cmd);
354 static void vdisk_exec_read_toc(struct scst_cmd *cmd);
355 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd);
356 static int vdisk_fsync(struct scst_vdisk_thr *thr, loff_t loff,
357 loff_t len, struct scst_cmd *cmd, struct scst_device *dev);
358 #ifdef CONFIG_SCST_PROC
359 static int vdisk_read_proc(struct seq_file *seq,
360 struct scst_dev_type *dev_type);
361 static int vdisk_write_proc(char *buffer, char **start, off_t offset,
362 int length, int *eof, struct scst_dev_type *dev_type);
363 static int vcdrom_read_proc(struct seq_file *seq,
364 struct scst_dev_type *dev_type);
365 static int vcdrom_write_proc(char *buffer, char **start, off_t offset,
366 int length, int *eof, struct scst_dev_type *dev_type);
368 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
369 struct scst_tgt_dev *tgt_dev);
373 #ifndef CONFIG_SCST_PROC
375 static ssize_t vdisk_mgmt_show(struct kobject *kobj,
376 struct kobj_attribute *attr, char *buf);
377 static ssize_t vdisk_mgmt_store(struct kobject *kobj,
378 struct kobj_attribute *attr, const char *buf, size_t count);
380 struct kobj_attribute vdisk_mgmt_attr =
381 __ATTR(mgmt, S_IRUGO | S_IWUSR, vdisk_mgmt_show, vdisk_mgmt_store);
383 static const struct attribute *vdisk_attrs[] = {
384 &vdisk_mgmt_attr.attr,
388 static ssize_t vdisk_sysfs_size_show(struct kobject *kobj,
389 struct kobj_attribute *attr, char *buf);
390 static ssize_t vdisk_sysfs_blocksize_show(struct kobject *kobj,
391 struct kobj_attribute *attr, char *buf);
392 static ssize_t vdisk_sysfs_rd_only_show(struct kobject *kobj,
393 struct kobj_attribute *attr, char *buf);
394 static ssize_t vdisk_sysfs_wt_show(struct kobject *kobj,
395 struct kobj_attribute *attr, char *buf);
396 static ssize_t vdisk_sysfs_nv_cache_show(struct kobject *kobj,
397 struct kobj_attribute *attr, char *buf);
398 static ssize_t vdisk_sysfs_o_direct_show(struct kobject *kobj,
399 struct kobj_attribute *attr, char *buf);
400 static ssize_t vdisk_sysfs_removable_show(struct kobject *kobj,
401 struct kobj_attribute *attr, char *buf);
402 static ssize_t vdisk_sysfs_filename_show(struct kobject *kobj,
403 struct kobj_attribute *attr, char *buf);
404 static ssize_t vdisk_sysfs_resync_size_store(struct kobject *kobj,
405 struct kobj_attribute *attr, const char *buf, size_t count);
407 static struct kobj_attribute vdisk_size_attr =
408 __ATTR(size, S_IRUGO, vdisk_sysfs_size_show, NULL);
409 static struct kobj_attribute vdisk_blocksize_attr =
410 __ATTR(block_size, S_IRUGO, vdisk_sysfs_blocksize_show, NULL);
411 static struct kobj_attribute vdisk_rd_only_attr =
412 __ATTR(read_only, S_IRUGO, vdisk_sysfs_rd_only_show, NULL);
413 static struct kobj_attribute vdisk_wt_attr =
414 __ATTR(write_through, S_IRUGO, vdisk_sysfs_wt_show, NULL);
415 static struct kobj_attribute vdisk_nv_cache_attr =
416 __ATTR(nv_cache, S_IRUGO, vdisk_sysfs_nv_cache_show, NULL);
417 static struct kobj_attribute vdisk_o_direct_attr =
418 __ATTR(o_direct, S_IRUGO, vdisk_sysfs_o_direct_show, NULL);
419 static struct kobj_attribute vdisk_removable_attr =
420 __ATTR(removable, S_IRUGO, vdisk_sysfs_removable_show, NULL);
421 static struct kobj_attribute vdisk_filename_attr =
422 __ATTR(filename, S_IRUGO, vdisk_sysfs_filename_show, NULL);
423 static struct kobj_attribute vdisk_resync_size_attr =
424 __ATTR(resync_size, S_IWUSR, NULL, vdisk_sysfs_resync_size_store);
426 static const struct attribute *vdisk_fileio_attrs[] = {
427 &vdisk_size_attr.attr,
428 &vdisk_blocksize_attr.attr,
429 &vdisk_rd_only_attr.attr,
431 &vdisk_nv_cache_attr.attr,
432 &vdisk_o_direct_attr.attr,
433 &vdisk_removable_attr.attr,
434 &vdisk_filename_attr.attr,
435 &vdisk_resync_size_attr.attr,
439 static const struct attribute *vdisk_blockio_attrs[] = {
440 &vdisk_size_attr.attr,
441 &vdisk_blocksize_attr.attr,
442 &vdisk_rd_only_attr.attr,
443 &vdisk_removable_attr.attr,
444 &vdisk_filename_attr.attr,
445 &vdisk_resync_size_attr.attr,
449 static const struct attribute *vdisk_nullio_attrs[] = {
450 &vdisk_size_attr.attr,
451 &vdisk_blocksize_attr.attr,
452 &vdisk_rd_only_attr.attr,
453 &vdisk_removable_attr.attr,
457 static const struct attribute *vcdrom_attrs[] = {
458 &vdisk_size_attr.attr,
459 &vdisk_removable_attr.attr,
460 &vdisk_filename_attr.attr,
464 #endif /* CONFIG_SCST_PROC */
466 static DEFINE_MUTEX(scst_vdisk_mutex);
468 /* Both protected by scst_vdisk_mutex */
469 static LIST_HEAD(vdisk_dev_list);
470 static LIST_HEAD(vcdrom_dev_list);
472 static struct vdisk_fileio_type fileio_type;
473 static struct kmem_cache *vdisk_thr_cachep;
476 * Be careful changing "name" field, since it is the name of the corresponding
477 * /sys/kernel/scst_tgt entry, hence a part of user space ABI.
480 static struct scst_dev_type vdisk_file_devtype = {
481 .name = "vdisk_fileio",
487 .dev_done_atomic = 1,
488 .attach = vdisk_attach,
489 .detach = vdisk_detach,
490 .attach_tgt = vdisk_attach_tgt,
491 .detach_tgt = vdisk_detach_tgt,
492 .parse = vdisk_parse,
493 .exec = vdisk_do_job,
494 .task_mgmt_fn = vdisk_task_mgmt_fn,
495 #ifdef CONFIG_SCST_PROC
496 .read_proc = vdisk_read_proc,
497 .write_proc = vdisk_write_proc,
499 .devt_attrs = vdisk_attrs,
500 .dev_attrs = vdisk_fileio_attrs,
502 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
503 .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
504 .trace_flags = &trace_flag,
505 .trace_tbl = vdisk_local_trace_tbl,
506 .trace_tbl_help = VDISK_TRACE_TLB_HELP,
510 static struct vdisk_blockio_type blockio_type;
511 static struct kmem_cache *blockio_work_cachep;
513 static struct scst_dev_type vdisk_blk_devtype = {
514 .name = "vdisk_blockio",
519 .dev_done_atomic = 1,
520 #ifdef CONFIG_SCST_PROC
523 .attach = vdisk_attach,
524 .detach = vdisk_detach,
525 .attach_tgt = vdisk_attach_tgt,
526 .detach_tgt = vdisk_detach_tgt,
527 .parse = vdisk_parse,
528 .exec = vdisk_do_job,
529 .task_mgmt_fn = vdisk_task_mgmt_fn,
530 #ifndef CONFIG_SCST_PROC
531 .devt_attrs = vdisk_attrs,
532 .dev_attrs = vdisk_blockio_attrs,
534 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
535 .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
536 .trace_flags = &trace_flag,
537 .trace_tbl = vdisk_local_trace_tbl,
538 .trace_tbl_help = VDISK_TRACE_TLB_HELP,
542 static struct vdisk_blockio_type nullio_type;
543 static struct scst_dev_type vdisk_null_devtype = {
544 .name = "vdisk_nullio",
549 .dev_done_atomic = 1,
550 #ifdef CONFIG_SCST_PROC
553 .attach = vdisk_attach,
554 .detach = vdisk_detach,
555 .attach_tgt = vdisk_attach_tgt,
556 .detach_tgt = vdisk_detach_tgt,
557 .parse = vdisk_parse,
558 .exec = vdisk_do_job,
559 .task_mgmt_fn = vdisk_task_mgmt_fn,
560 #ifndef CONFIG_SCST_PROC
561 .devt_attrs = vdisk_attrs,
562 .dev_attrs = vdisk_nullio_attrs,
564 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
565 .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
566 .trace_flags = &trace_flag,
567 .trace_tbl = vdisk_local_trace_tbl,
568 .trace_tbl_help = VDISK_TRACE_TLB_HELP,
572 static struct vcdrom_type vcdrom_type;
573 static struct scst_dev_type vcdrom_devtype = {
580 .dev_done_atomic = 1,
581 .attach = vdisk_attach,
582 .detach = vdisk_detach,
583 .attach_tgt = vdisk_attach_tgt,
584 .detach_tgt = vdisk_detach_tgt,
585 .parse = vcdrom_parse,
587 .task_mgmt_fn = vdisk_task_mgmt_fn,
588 #ifdef CONFIG_SCST_PROC
589 .read_proc = vcdrom_read_proc,
590 .write_proc = vcdrom_write_proc,
592 .devt_attrs = vdisk_attrs,
593 .dev_attrs = vcdrom_attrs,
595 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
596 .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
597 .trace_flags = &trace_flag,
598 .trace_tbl = vdisk_local_trace_tbl,
599 .trace_tbl_help = VDISK_TRACE_TLB_HELP,
603 static struct scst_vdisk_thr nullio_thr_data;
605 #ifdef CONFIG_SCST_PROC
606 static char *vdisk_proc_help_string =
607 "echo \"open|close|resync_size NAME [FILE_NAME [BLOCK_SIZE] "
608 "[WRITE_THROUGH READ_ONLY O_DIRECT NULLIO NV_CACHE BLOCKIO]]\" "
609 ">/proc/scsi_tgt/vdisk/vdisk\n";
611 static char *vcdrom_proc_help_string =
612 "echo \"open|change|close NAME [FILE_NAME]\" "
613 ">/proc/scsi_tgt/vcdrom/vcdrom\n";
616 static int scst_vdisk_ID;
618 module_param_named(scst_vdisk_ID, scst_vdisk_ID, int, S_IRUGO);
619 MODULE_PARM_DESC(scst_vdisk_ID, "SCST virtual disk subsystem ID");
621 /**************************************************************
622 * Function: vdev_open_fd
626 * Returns : fd, use IS_ERR(fd) to get error status
629 *************************************************************/
630 static struct file *vdev_open_fd(const struct scst_vdisk_dev *virt_dev)
637 if (virt_dev->dev->rd_only)
638 open_flags |= O_RDONLY;
640 open_flags |= O_RDWR;
641 if (virt_dev->o_direct_flag)
642 open_flags |= O_DIRECT;
643 if (virt_dev->wt_flag && !virt_dev->nv_cache)
644 open_flags |= O_SYNC;
645 TRACE_DBG("Opening file %s, flags 0x%x",
646 virt_dev->file_name, open_flags);
647 fd = filp_open(virt_dev->file_name, O_LARGEFILE | open_flags, 0600);
653 /**************************************************************
654 * Function: vdisk_get_file_size
658 * Returns : 0 on success and file size in *file_size,
659 * error code otherwise
662 *************************************************************/
663 static int vdisk_get_file_size(const char *file_name, bool blockio,
674 fd = filp_open(file_name, O_LARGEFILE | O_RDONLY, 0600);
677 PRINT_ERROR("filp_open(%s) returned error %d", file_name, res);
681 inode = fd->f_dentry->d_inode;
683 if (blockio && !S_ISBLK(inode->i_mode)) {
684 PRINT_ERROR("File %s is NOT a block device", file_name);
689 if (S_ISREG(inode->i_mode))
691 else if (S_ISBLK(inode->i_mode))
692 inode = inode->i_bdev->bd_inode;
698 *file_size = inode->i_size;
701 filp_close(fd, NULL);
708 /**************************************************************
709 * Function: vdisk_attach
713 * Returns : 1 if attached, error code otherwise
716 *************************************************************/
717 static int vdisk_attach(struct scst_device *dev)
721 struct scst_vdisk_dev *virt_dev = NULL, *vv;
722 struct list_head *vd;
726 TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
728 if (dev->virt_id == 0) {
729 PRINT_ERROR("%s", "Not a virtual device");
734 vd = (dev->type == TYPE_DISK) ?
739 * scst_vdisk_mutex must be already taken before
740 * scst_register_virtual_device()
742 list_for_each_entry(vv, vd, vdisk_dev_list_entry) {
743 if (strcmp(vv->name, dev->virt_name) == 0) {
749 if (virt_dev == NULL) {
750 PRINT_ERROR("Device %s not found", dev->virt_name);
757 dev->rd_only = virt_dev->rd_only;
758 if (dev->type == TYPE_ROM)
761 if (!virt_dev->cdrom_empty) {
762 if (virt_dev->nullio)
763 err = VDISK_NULLIO_SIZE;
765 res = vdisk_get_file_size(virt_dev->file_name,
766 virt_dev->blockio, &err);
770 virt_dev->file_size = err;
771 TRACE_DBG("size of file: %lld", (long long unsigned int)err);
773 virt_dev->file_size = 0;
775 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
777 if (!virt_dev->cdrom_empty) {
778 PRINT_INFO("Attached SCSI target virtual %s %s "
779 "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
781 (dev->type == TYPE_DISK) ? "disk" : "cdrom",
782 virt_dev->name, virt_dev->file_name,
783 virt_dev->file_size >> 20, virt_dev->block_size,
784 (long long unsigned int)virt_dev->nblocks,
785 (long long unsigned int)virt_dev->nblocks/64/32,
786 virt_dev->nblocks < 64*32
787 ? " !WARNING! cyln less than 1" : "");
789 PRINT_INFO("Attached empty SCSI target virtual cdrom %s",
793 dev->dh_priv = virt_dev;
796 dev->d_sense = DEF_DSENSE;
797 if (virt_dev->wt_flag && !virt_dev->nv_cache)
798 dev->queue_alg = DEF_QUEUE_ALG_WT;
800 dev->queue_alg = DEF_QUEUE_ALG;
809 /************************************************************
810 * Function: vdisk_detach
816 * Description: Called to detach this device type driver
817 ************************************************************/
818 static void vdisk_detach(struct scst_device *dev)
820 struct scst_vdisk_dev *virt_dev =
821 (struct scst_vdisk_dev *)dev->dh_priv;
825 TRACE_DBG("virt_id %d", dev->virt_id);
827 PRINT_INFO("Detached SCSI target virtual device %s (\"%s\")",
828 virt_dev->name, virt_dev->file_name);
830 /* virt_dev will be freed by the caller */
837 static void vdisk_free_thr_data(struct scst_thr_data_hdr *d)
839 struct scst_vdisk_thr *thr =
840 container_of(d, struct scst_vdisk_thr, hdr);
845 filp_close(thr->fd, NULL);
849 kmem_cache_free(vdisk_thr_cachep, thr);
855 static struct scst_vdisk_thr *vdisk_init_thr_data(
856 struct scst_tgt_dev *tgt_dev)
858 struct scst_vdisk_thr *res;
859 struct scst_vdisk_dev *virt_dev =
860 (struct scst_vdisk_dev *)tgt_dev->dev->dh_priv;
864 EXTRACHECKS_BUG_ON(virt_dev->nullio);
866 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
867 res = kmem_cache_alloc(vdisk_thr_cachep, GFP_KERNEL);
869 memset(res, 0, sizeof(*res));
871 res = kmem_cache_zalloc(vdisk_thr_cachep, GFP_KERNEL);
874 TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct "
879 if (!virt_dev->cdrom_empty) {
880 res->fd = vdev_open_fd(virt_dev);
881 if (IS_ERR(res->fd)) {
882 PRINT_ERROR("filp_open(%s) returned an error %ld",
883 virt_dev->file_name, PTR_ERR(res->fd));
886 if (virt_dev->blockio)
887 res->bdev = res->fd->f_dentry->d_inode->i_bdev;
893 scst_add_thr_data(tgt_dev, &res->hdr, vdisk_free_thr_data);
896 TRACE_EXIT_HRES((unsigned long)res);
900 kmem_cache_free(vdisk_thr_cachep, res);
905 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev)
907 struct scst_vdisk_tgt_dev *ftgt_dev;
912 ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL);
913 if (ftgt_dev == NULL) {
914 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
915 "virtual device failed");
920 tgt_dev->dh_priv = ftgt_dev;
927 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev)
929 struct scst_vdisk_tgt_dev *ftgt_dev =
930 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
934 scst_del_all_thr_data(tgt_dev);
937 tgt_dev->dh_priv = NULL;
943 static inline int vdisk_sync_queue_type(enum scst_cmd_queue_type qt)
946 case SCST_CMD_QUEUE_ORDERED:
947 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
954 static inline int vdisk_need_pre_sync(enum scst_cmd_queue_type cur,
955 enum scst_cmd_queue_type last)
957 if (vdisk_sync_queue_type(cur))
958 if (!vdisk_sync_queue_type(last))
963 static int vdisk_do_job(struct scst_cmd *cmd)
966 uint64_t lba_start = 0;
968 uint8_t *cdb = cmd->cdb;
971 struct scst_device *dev = cmd->dev;
972 struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
973 struct scst_vdisk_dev *virt_dev =
974 (struct scst_vdisk_dev *)dev->dh_priv;
975 struct scst_thr_data_hdr *d;
976 struct scst_vdisk_thr *thr = NULL;
981 switch (cmd->queue_type) {
982 case SCST_CMD_QUEUE_ORDERED:
983 TRACE(TRACE_ORDER, "ORDERED cmd %p (op %x)", cmd, cmd->cdb[0]);
985 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
986 TRACE(TRACE_ORDER, "HQ cmd %p (op %x)", cmd, cmd->cdb[0]);
992 rc = scst_check_local_events(cmd);
993 if (unlikely(rc != 0))
998 cmd->host_status = DID_OK;
999 cmd->driver_status = 0;
1001 if (!virt_dev->nullio) {
1002 d = scst_find_thr_data(tgt_dev);
1003 if (unlikely(d == NULL)) {
1004 thr = vdisk_init_thr_data(tgt_dev);
1009 scst_thr_data_get(&thr->hdr);
1011 thr = container_of(d, struct scst_vdisk_thr, hdr);
1013 thr = &nullio_thr_data;
1014 scst_thr_data_get(&thr->hdr);
1021 lba_start = (((cdb[1] & 0x1f) << (BYTE * 2)) +
1022 (cdb[2] << (BYTE * 1)) +
1023 (cdb[3] << (BYTE * 0)));
1024 data_len = cmd->bufflen;
1032 case WRITE_VERIFY_12:
1034 lba_start |= ((u64)cdb[2]) << 24;
1035 lba_start |= ((u64)cdb[3]) << 16;
1036 lba_start |= ((u64)cdb[4]) << 8;
1037 lba_start |= ((u64)cdb[5]);
1038 data_len = cmd->bufflen;
1042 case WRITE_VERIFY_16:
1044 lba_start |= ((u64)cdb[2]) << 56;
1045 lba_start |= ((u64)cdb[3]) << 48;
1046 lba_start |= ((u64)cdb[4]) << 40;
1047 lba_start |= ((u64)cdb[5]) << 32;
1048 lba_start |= ((u64)cdb[6]) << 24;
1049 lba_start |= ((u64)cdb[7]) << 16;
1050 lba_start |= ((u64)cdb[8]) << 8;
1051 lba_start |= ((u64)cdb[9]);
1052 data_len = cmd->bufflen;
1054 case SYNCHRONIZE_CACHE:
1055 lba_start |= ((u64)cdb[2]) << 24;
1056 lba_start |= ((u64)cdb[3]) << 16;
1057 lba_start |= ((u64)cdb[4]) << 8;
1058 lba_start |= ((u64)cdb[5]);
1059 data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0)))
1060 << virt_dev->block_shift;
1062 data_len = virt_dev->file_size -
1063 ((loff_t)lba_start << virt_dev->block_shift);
1067 loff = (loff_t)lba_start << virt_dev->block_shift;
1068 TRACE_DBG("cmd %p, lba_start %lld, loff %lld, data_len %lld", cmd,
1069 (long long unsigned int)lba_start,
1070 (long long unsigned int)loff,
1071 (long long unsigned int)data_len);
1072 if (unlikely(loff < 0) || unlikely(data_len < 0) ||
1073 unlikely((loff + data_len) > virt_dev->file_size)) {
1074 PRINT_INFO("Access beyond the end of the device "
1075 "(%lld of %lld, len %lld)",
1076 (long long unsigned int)loff,
1077 (long long unsigned int)virt_dev->file_size,
1078 (long long unsigned int)data_len);
1079 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1080 scst_sense_block_out_range_error));
1088 fua = (cdb[1] & 0x8);
1090 TRACE(TRACE_ORDER, "FUA: loff=%lld, "
1091 "data_len=%lld", (long long unsigned int)loff,
1092 (long long unsigned int)data_len);
1102 if (virt_dev->blockio) {
1103 blockio_exec_rw(cmd, thr, lba_start, 0);
1106 vdisk_exec_read(cmd, thr, loff);
1113 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
1114 struct scst_vdisk_tgt_dev *ftgt_dev =
1115 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
1116 enum scst_cmd_queue_type last_queue_type =
1117 ftgt_dev->last_write_cmd_queue_type;
1118 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
1119 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
1120 TRACE(TRACE_ORDER, "ORDERED WRITE(%d): loff=%lld, "
1121 "data_len=%lld", cmd->queue_type,
1122 (long long unsigned int)loff,
1123 (long long unsigned int)data_len);
1125 if (vdisk_fsync(thr, 0, 0, cmd, dev) != 0)
1128 if (virt_dev->blockio) {
1129 blockio_exec_rw(cmd, thr, lba_start, 1);
1132 vdisk_exec_write(cmd, thr, loff);
1133 /* O_SYNC flag is used for WT devices */
1134 if (do_fsync || fua)
1135 vdisk_fsync(thr, loff, data_len, cmd, dev);
1139 case WRITE_VERIFY_12:
1140 case WRITE_VERIFY_16:
1142 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
1143 struct scst_vdisk_tgt_dev *ftgt_dev =
1144 (struct scst_vdisk_tgt_dev *) tgt_dev->dh_priv;
1145 enum scst_cmd_queue_type last_queue_type =
1146 ftgt_dev->last_write_cmd_queue_type;
1147 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
1148 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
1149 TRACE(TRACE_ORDER, "ORDERED "
1150 "WRITE_VERIFY(%d): loff=%lld,"
1151 " data_len=%lld", cmd->queue_type,
1152 (long long unsigned int)loff,
1153 (long long unsigned int)data_len);
1155 if (vdisk_fsync(thr, 0, 0, cmd, dev) != 0)
1158 /* ToDo: BLOCKIO VERIFY */
1159 vdisk_exec_write(cmd, thr, loff);
1160 /* O_SYNC flag is used for WT devices */
1161 if (scsi_status_is_good(cmd->status))
1162 vdisk_exec_verify(cmd, thr, loff);
1164 vdisk_fsync(thr, loff, data_len, cmd, dev);
1167 case SYNCHRONIZE_CACHE:
1169 int immed = cdb[1] & 0x2;
1170 TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: "
1171 "loff=%lld, data_len=%lld, immed=%d",
1172 (long long unsigned int)loff,
1173 (long long unsigned int)data_len, immed);
1175 scst_cmd_get(cmd); /* to protect dev */
1177 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
1179 vdisk_fsync(thr, loff, data_len, NULL, dev);
1180 /* ToDo: vdisk_fsync() error processing */
1184 vdisk_fsync(thr, loff, data_len, cmd, dev);
1192 vdisk_exec_verify(cmd, thr, loff);
1196 vdisk_exec_mode_sense(cmd);
1199 case MODE_SELECT_10:
1200 vdisk_exec_mode_select(cmd);
1204 vdisk_exec_log(cmd);
1206 case ALLOW_MEDIUM_REMOVAL:
1207 vdisk_exec_prevent_allow_medium_removal(cmd);
1210 vdisk_exec_read_toc(cmd);
1213 vdisk_fsync(thr, 0, virt_dev->file_size, cmd, dev);
1219 case TEST_UNIT_READY:
1222 vdisk_exec_inquiry(cmd);
1225 vdisk_exec_request_sense(cmd);
1228 vdisk_exec_read_capacity(cmd);
1230 case SERVICE_ACTION_IN:
1231 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
1232 vdisk_exec_read_capacity16(cmd);
1235 /* else go through */
1238 TRACE_DBG("Invalid opcode %d", opcode);
1239 scst_set_cmd_error(cmd,
1240 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1247 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1250 if (likely(thr != NULL))
1251 scst_thr_data_put(&thr->hdr);
1253 res = SCST_EXEC_COMPLETED;
1255 TRACE_EXIT_RES(res);
1259 static int vdisk_get_block_shift(struct scst_cmd *cmd)
1261 struct scst_vdisk_dev *virt_dev =
1262 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1263 return virt_dev->block_shift;
1266 /********************************************************************
1267 * Function: vdisk_parse
1271 * Returns : The state of the command
1273 * Description: This does the parsing of the command
1275 * Note: Not all states are allowed on return
1276 ********************************************************************/
1277 static int vdisk_parse(struct scst_cmd *cmd)
1279 scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
1280 return SCST_CMD_STATE_DEFAULT;
1283 /********************************************************************
1284 * Function: vcdrom_parse
1288 * Returns : The state of the command
1290 * Description: This does the parsing of the command
1292 * Note: Not all states are allowed on return
1293 ********************************************************************/
1294 static int vcdrom_parse(struct scst_cmd *cmd)
1296 scst_cdrom_generic_parse(cmd, vdisk_get_block_shift);
1297 return SCST_CMD_STATE_DEFAULT;
1300 /********************************************************************
1301 * Function: vcdrom_exec
1308 ********************************************************************/
1309 static int vcdrom_exec(struct scst_cmd *cmd)
1311 int res = SCST_EXEC_COMPLETED;
1312 int opcode = cmd->cdb[0];
1313 struct scst_vdisk_dev *virt_dev =
1314 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1319 cmd->msg_status = 0;
1320 cmd->host_status = DID_OK;
1321 cmd->driver_status = 0;
1323 if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1324 TRACE_DBG("%s", "CDROM empty");
1325 scst_set_cmd_error(cmd,
1326 SCST_LOAD_SENSE(scst_sense_not_ready));
1330 if (virt_dev->media_changed && scst_is_ua_command(cmd)) {
1331 spin_lock(&virt_dev->flags_lock);
1332 if (virt_dev->media_changed) {
1333 virt_dev->media_changed = 0;
1334 TRACE_DBG("%s", "Reporting media changed");
1335 scst_set_cmd_error(cmd,
1336 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1337 spin_unlock(&virt_dev->flags_lock);
1340 spin_unlock(&virt_dev->flags_lock);
1343 res = vdisk_do_job(cmd);
1346 TRACE_EXIT_RES(res);
1350 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1354 static uint64_t vdisk_gen_dev_id_num(struct scst_vdisk_dev *virt_dev)
1356 unsigned int dev_id_num, i;
1358 for (dev_id_num = 0, i = 0; i < strlen(virt_dev->name); i++) {
1359 unsigned int rv = random_values[(int)(virt_dev->name[i])];
1360 /* Do some rotating of the bits */
1361 dev_id_num ^= ((rv << i) | (rv >> (32 - i)));
1364 return ((uint64_t)scst_vdisk_ID << 32) | dev_id_num;
1367 static void vdisk_exec_inquiry(struct scst_cmd *cmd)
1369 int32_t length, i, resp_len = 0;
1372 struct scst_vdisk_dev *virt_dev =
1373 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1375 /* ToDo: Performance Boost:
1376 * 1. remove kzalloc, buf
1377 * 2. do all checks before touching *address
1379 * 4. write directly to *address
1384 buf = kzalloc(INQ_BUF_SZ,
1385 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1391 length = scst_get_buf_first(cmd, &address);
1392 TRACE_DBG("length %d", length);
1393 if (unlikely(length <= 0)) {
1395 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1396 scst_set_cmd_error(cmd,
1397 SCST_LOAD_SENSE(scst_sense_hardw_error));
1402 if (cmd->cdb[1] & CMDDT) {
1403 TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported");
1404 scst_set_cmd_error(cmd,
1405 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1409 buf[0] = cmd->dev->type; /* type dev */
1410 if (virt_dev->removable)
1411 buf[1] = 0x80; /* removable */
1413 if (cmd->cdb[1] & EVPD) {
1414 uint64_t dev_id_num;
1416 char dev_id_str[17];
1418 dev_id_num = vdisk_gen_dev_id_num(virt_dev);
1419 dev_id_len = scnprintf(dev_id_str, sizeof(dev_id_str), "%llx",
1421 TRACE_DBG("dev_id num %lld, str %s, len %d", dev_id_num,
1422 dev_id_str, dev_id_len);
1423 if (0 == cmd->cdb[2]) {
1424 /* supported vital product data pages */
1426 buf[4] = 0x0; /* this page */
1427 buf[5] = 0x80; /* unit serial number */
1428 buf[6] = 0x83; /* device identification */
1429 resp_len = buf[3] + 4;
1430 } else if (0x80 == cmd->cdb[2]) {
1431 /* unit serial number */
1432 int usn_len = strlen(virt_dev->usn);
1435 strncpy(&buf[4], virt_dev->usn, usn_len);
1436 resp_len = buf[3] + 4;
1437 } else if (0x83 == cmd->cdb[2]) {
1438 /* device identification */
1442 /* T10 vendor identifier field format (faked) */
1443 buf[num + 0] = 0x2; /* ASCII */
1444 buf[num + 1] = 0x1; /* Vendor ID */
1445 if (virt_dev->blockio)
1446 memcpy(&buf[num + 4], SCST_BIO_VENDOR, 8);
1448 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1450 i = strlen(virt_dev->name) + 1; /* for ' ' */
1451 memset(&buf[num + 12], ' ', i + dev_id_len);
1452 memcpy(&buf[num + 12], virt_dev->name, i-1);
1453 memcpy(&buf[num + 12 + i], dev_id_str, dev_id_len);
1454 buf[num + 3] = 8 + i + dev_id_len;
1455 num += buf[num + 3];
1457 #if 0 /* This isn't required and can be misleading, so let's disable it */
1460 /* NAA IEEE registered identifier (faked) */
1461 buf[num] = 0x1; /* binary */
1465 buf[num + 4] = 0x51; /* IEEE OUI=0x123456 (faked) */
1466 buf[num + 5] = 0x23;
1467 buf[num + 6] = 0x45;
1468 buf[num + 7] = 0x60;
1469 buf[num + 8] = (dev_id_num >> 24);
1470 buf[num + 9] = (dev_id_num >> 16) & 0xff;
1471 buf[num + 10] = (dev_id_num >> 8) & 0xff;
1472 buf[num + 11] = dev_id_num & 0xff;
1477 buf[2] = (resp_len >> 8) & 0xFF;
1478 buf[3] = resp_len & 0xFF;
1481 TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1483 scst_set_cmd_error(cmd,
1484 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1490 if (cmd->cdb[2] != 0) {
1491 TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1492 scst_set_cmd_error(cmd,
1493 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1497 buf[2] = 5; /* Device complies to SPC-3 */
1498 buf[3] = 0x12; /* HiSup + data in format specified in SPC */
1499 buf[4] = 31;/* n - 4 = 35 - 4 = 31 for full 36 byte data */
1500 buf[6] = 1; /* MultiP 1 */
1501 buf[7] = 2; /* CMDQUE 1, BQue 0 => commands queuing supported */
1504 * 8 byte ASCII Vendor Identification of the target
1507 if (virt_dev->blockio)
1508 memcpy(&buf[8], SCST_BIO_VENDOR, 8);
1510 memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1513 * 16 byte ASCII Product Identification of the target - left
1516 memset(&buf[16], ' ', 16);
1517 len = min(strlen(virt_dev->name), (size_t)16);
1518 memcpy(&buf[16], virt_dev->name, len);
1521 * 4 byte ASCII Product Revision Level of the target - left
1524 memcpy(&buf[32], SCST_FIO_REV, 4);
1525 resp_len = buf[4] + 5;
1528 sBUG_ON(resp_len >= INQ_BUF_SZ);
1529 if (length > resp_len)
1531 memcpy(address, buf, length);
1534 scst_put_buf(cmd, address);
1535 if (length < cmd->resp_data_len)
1536 scst_set_resp_data_len(cmd, length);
1546 static void vdisk_exec_request_sense(struct scst_cmd *cmd)
1550 uint8_t b[SCST_STANDARD_SENSE_LEN];
1554 sl = scst_set_sense(b, sizeof(b), cmd->dev->d_sense,
1555 SCST_LOAD_SENSE(scst_sense_no_sense));
1557 length = scst_get_buf_first(cmd, &address);
1558 TRACE_DBG("length %d", length);
1560 PRINT_ERROR("scst_get_buf_first() failed: %d)", length);
1561 scst_set_cmd_error(cmd,
1562 SCST_LOAD_SENSE(scst_sense_hardw_error));
1566 length = min(sl, length);
1567 memcpy(address, b, length);
1568 scst_set_resp_data_len(cmd, length);
1570 scst_put_buf(cmd, address);
1578 * <<Following mode pages info copied from ST318451LW with some corrections>>
1582 static int vdisk_err_recov_pg(unsigned char *p, int pcontrol,
1583 struct scst_vdisk_dev *virt_dev)
1584 { /* Read-Write Error Recovery page for mode_sense */
1585 const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1588 memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1590 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1591 return sizeof(err_recov_pg);
1594 static int vdisk_disconnect_pg(unsigned char *p, int pcontrol,
1595 struct scst_vdisk_dev *virt_dev)
1596 { /* Disconnect-Reconnect page for mode_sense */
1597 const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1598 0, 0, 0, 0, 0, 0, 0, 0};
1600 memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1602 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1603 return sizeof(disconnect_pg);
1606 static int vdisk_rigid_geo_pg(unsigned char *p, int pcontrol,
1607 struct scst_vdisk_dev *virt_dev)
1609 unsigned char geo_m_pg[] = {0x04, 0x16, 0, 0, 0, DEF_HEADS, 0, 0,
1610 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1611 0x3a, 0x98/* 15K RPM */, 0, 0};
1612 int32_t ncyl, n, rem;
1615 memcpy(p, geo_m_pg, sizeof(geo_m_pg));
1617 * Divide virt_dev->nblocks by (DEF_HEADS * DEF_SECTORS) and store
1618 * the quotient in ncyl and the remainder in rem.
1620 dividend = virt_dev->nblocks;
1621 rem = do_div(dividend, DEF_HEADS * DEF_SECTORS);
1625 memcpy(&n, p + 2, sizeof(u32));
1626 n = n | (cpu_to_be32(ncyl) >> 8);
1627 memcpy(p + 2, &n, sizeof(u32));
1629 memset(p + 2, 0, sizeof(geo_m_pg) - 2);
1630 return sizeof(geo_m_pg);
1633 static int vdisk_format_pg(unsigned char *p, int pcontrol,
1634 struct scst_vdisk_dev *virt_dev)
1635 { /* Format device page for mode_sense */
1636 const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1637 0, 0, 0, 0, 0, 0, 0, 0,
1638 0, 0, 0, 0, 0x40, 0, 0, 0};
1640 memcpy(p, format_pg, sizeof(format_pg));
1641 p[10] = (DEF_SECTORS >> 8) & 0xff;
1642 p[11] = DEF_SECTORS & 0xff;
1643 p[12] = (virt_dev->block_size >> 8) & 0xff;
1644 p[13] = virt_dev->block_size & 0xff;
1646 memset(p + 2, 0, sizeof(format_pg) - 2);
1647 return sizeof(format_pg);
1650 static int vdisk_caching_pg(unsigned char *p, int pcontrol,
1651 struct scst_vdisk_dev *virt_dev)
1652 { /* Caching page for mode_sense */
1653 const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1654 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1656 memcpy(p, caching_pg, sizeof(caching_pg));
1657 p[2] |= !(virt_dev->wt_flag || virt_dev->nv_cache) ? WCE : 0;
1659 memset(p + 2, 0, sizeof(caching_pg) - 2);
1660 return sizeof(caching_pg);
1663 static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol,
1664 struct scst_vdisk_dev *virt_dev)
1665 { /* Control mode page for mode_sense */
1666 const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0, 0, 0, 0, 0, 0,
1669 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1672 p[2] |= virt_dev->dev->tst << 5;
1673 p[2] |= virt_dev->dev->d_sense << 2;
1674 p[3] |= virt_dev->dev->queue_alg << 4;
1675 p[4] |= virt_dev->dev->swp << 3;
1676 p[5] |= virt_dev->dev->tas << 6;
1679 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1681 * It's too early to implement it, since we can't control the
1682 * backstorage device parameters. ToDo
1684 p[2] |= 7 << 5; /* TST */
1685 p[3] |= 0xF << 4; /* QUEUE ALGORITHM MODIFIER */
1687 p[2] |= 1 << 2; /* D_SENSE */
1688 p[4] |= 1 << 3; /* SWP */
1689 p[5] |= 1 << 6; /* TAS */
1692 p[2] |= DEF_TST << 5;
1693 p[2] |= DEF_DSENSE << 2;
1694 if (virt_dev->wt_flag || virt_dev->nv_cache)
1695 p[3] |= DEF_QUEUE_ALG_WT << 4;
1697 p[3] |= DEF_QUEUE_ALG << 4;
1698 p[4] |= DEF_SWP << 3;
1699 p[5] |= DEF_TAS << 6;
1704 return sizeof(ctrl_m_pg);
1707 static int vdisk_iec_m_pg(unsigned char *p, int pcontrol,
1708 struct scst_vdisk_dev *virt_dev)
1709 { /* Informational Exceptions control mode page for mode_sense */
1710 const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1712 memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1714 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1715 return sizeof(iec_m_pg);
1718 static void vdisk_exec_mode_sense(struct scst_cmd *cmd)
1723 struct scst_vdisk_dev *virt_dev;
1726 unsigned char dbd, type;
1727 int pcontrol, pcode, subpcode;
1728 unsigned char dev_spec;
1729 int msense_6, offset = 0, len;
1734 buf = kzalloc(MSENSE_BUF_SZ,
1735 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1741 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1742 blocksize = virt_dev->block_size;
1743 nblocks = virt_dev->nblocks;
1745 type = cmd->dev->type; /* type dev */
1746 dbd = cmd->cdb[1] & DBD;
1747 pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1748 pcode = cmd->cdb[2] & 0x3f;
1749 subpcode = cmd->cdb[3];
1750 msense_6 = (MODE_SENSE == cmd->cdb[0]);
1751 dev_spec = (virt_dev->dev->rd_only ? WP : 0) | DPOFUA;
1753 length = scst_get_buf_first(cmd, &address);
1754 if (unlikely(length <= 0)) {
1756 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1757 scst_set_cmd_error(cmd,
1758 SCST_LOAD_SENSE(scst_sense_hardw_error));
1763 if (0x3 == pcontrol) {
1764 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1765 scst_set_cmd_error(cmd,
1766 SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1780 if (0 != subpcode) {
1781 /* TODO: Control Extension page */
1782 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1783 scst_set_cmd_error(cmd,
1784 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1789 /* Create block descriptor */
1790 buf[offset - 1] = 0x08; /* block descriptor length */
1791 if (nblocks >> 32) {
1792 buf[offset + 0] = 0xFF;
1793 buf[offset + 1] = 0xFF;
1794 buf[offset + 2] = 0xFF;
1795 buf[offset + 3] = 0xFF;
1798 buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;
1799 buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1800 buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1801 buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1803 buf[offset + 4] = 0; /* density code */
1804 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1805 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1806 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1808 offset += 8; /* increment offset */
1814 case 0x1: /* Read-Write error recovery page, direct access */
1815 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1817 case 0x2: /* Disconnect-Reconnect page, all devices */
1818 len = vdisk_disconnect_pg(bp, pcontrol, virt_dev);
1820 case 0x3: /* Format device page, direct access */
1821 len = vdisk_format_pg(bp, pcontrol, virt_dev);
1823 case 0x4: /* Rigid disk geometry */
1824 len = vdisk_rigid_geo_pg(bp, pcontrol, virt_dev);
1826 case 0x8: /* Caching page, direct access */
1827 len = vdisk_caching_pg(bp, pcontrol, virt_dev);
1829 case 0xa: /* Control Mode page, all devices */
1830 len = vdisk_ctrl_m_pg(bp, pcontrol, virt_dev);
1832 case 0x1c: /* Informational Exceptions Mode page, all devices */
1833 len = vdisk_iec_m_pg(bp, pcontrol, virt_dev);
1835 case 0x3f: /* Read all Mode pages */
1836 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1837 len += vdisk_disconnect_pg(bp + len, pcontrol, virt_dev);
1838 len += vdisk_format_pg(bp + len, pcontrol, virt_dev);
1839 len += vdisk_caching_pg(bp + len, pcontrol, virt_dev);
1840 len += vdisk_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1841 len += vdisk_iec_m_pg(bp + len, pcontrol, virt_dev);
1842 len += vdisk_rigid_geo_pg(bp + len, pcontrol, virt_dev);
1845 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1846 scst_set_cmd_error(cmd,
1847 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1854 buf[0] = offset - 1;
1856 buf[0] = ((offset - 2) >> 8) & 0xff;
1857 buf[1] = (offset - 2) & 0xff;
1860 if (offset > length)
1862 memcpy(address, buf, offset);
1865 scst_put_buf(cmd, address);
1866 if (offset < cmd->resp_data_len)
1867 scst_set_resp_data_len(cmd, offset);
1877 static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt)
1883 if ((virt_dev->wt_flag == wt) || virt_dev->nullio || virt_dev->nv_cache)
1886 spin_lock(&virt_dev->flags_lock);
1887 virt_dev->wt_flag = wt;
1888 spin_unlock(&virt_dev->flags_lock);
1890 scst_dev_del_all_thr_data(virt_dev->dev);
1893 TRACE_EXIT_RES(res);
1897 static void vdisk_ctrl_m_pg_select(unsigned char *p,
1898 struct scst_vdisk_dev *virt_dev)
1900 struct scst_device *dev = virt_dev->dev;
1901 int old_swp = dev->swp, old_tas = dev->tas, old_dsense = dev->d_sense;
1904 /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */
1905 dev->tst = p[2] >> 5;
1906 dev->queue_alg = p[3] >> 4;
1908 dev->swp = (p[4] & 0x8) >> 3;
1909 dev->tas = (p[5] & 0x40) >> 6;
1910 dev->d_sense = (p[2] & 0x4) >> 2;
1912 PRINT_INFO("Device %s: new control mode page parameters: SWP %x "
1913 "(was %x), TAS %x (was %x), D_SENSE %d (was %d)",
1914 virt_dev->name, dev->swp, old_swp, dev->tas, old_tas,
1915 dev->d_sense, old_dsense);
1919 static void vdisk_exec_mode_select(struct scst_cmd *cmd)
1923 struct scst_vdisk_dev *virt_dev;
1924 int mselect_6, offset;
1928 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1929 mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1931 length = scst_get_buf_first(cmd, &address);
1932 if (unlikely(length <= 0)) {
1934 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1935 scst_set_cmd_error(cmd,
1936 SCST_LOAD_SENSE(scst_sense_hardw_error));
1941 if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1942 TRACE(TRACE_MINOR|TRACE_SCSI, "MODE SELECT: Unsupported "
1943 "value(s) of PF and/or SP bits (cdb[1]=%x)",
1945 scst_set_cmd_error(cmd,
1946 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1955 if (address[offset - 1] == 8) {
1957 } else if (address[offset - 1] != 0) {
1958 PRINT_ERROR("%s", "MODE SELECT: Wrong parameters list "
1960 scst_set_cmd_error(cmd,
1961 SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1965 while (length > offset + 2) {
1966 if (address[offset] & PS) {
1967 PRINT_ERROR("%s", "MODE SELECT: Illegal PS bit");
1968 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1969 scst_sense_invalid_field_in_parm_list));
1972 if ((address[offset] & 0x3f) == 0x8) {
1974 if (address[offset + 1] != 18) {
1975 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1976 "caching page request");
1977 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1978 scst_sense_invalid_field_in_parm_list));
1981 if (vdisk_set_wt(virt_dev,
1982 (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1983 scst_set_cmd_error(cmd,
1984 SCST_LOAD_SENSE(scst_sense_hardw_error));
1988 } else if ((address[offset] & 0x3f) == 0xA) {
1990 if (address[offset + 1] != 0xA) {
1991 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1992 "control page request");
1993 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1994 scst_sense_invalid_field_in_parm_list));
1997 vdisk_ctrl_m_pg_select(&address[offset], virt_dev);
1999 PRINT_ERROR("MODE SELECT: Invalid request %x",
2000 address[offset] & 0x3f);
2001 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
2002 scst_sense_invalid_field_in_parm_list));
2005 offset += address[offset + 1];
2009 scst_put_buf(cmd, address);
2016 static void vdisk_exec_log(struct scst_cmd *cmd)
2020 /* No log pages are supported */
2021 scst_set_cmd_error(cmd,
2022 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2028 static void vdisk_exec_read_capacity(struct scst_cmd *cmd)
2032 struct scst_vdisk_dev *virt_dev;
2035 uint8_t buffer[READ_CAP_LEN];
2039 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2040 blocksize = virt_dev->block_size;
2041 nblocks = virt_dev->nblocks;
2043 /* last block on the virt_dev is (nblocks-1) */
2044 memset(buffer, 0, sizeof(buffer));
2045 if (nblocks >> 32) {
2051 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
2052 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
2053 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
2054 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
2056 buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
2057 buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
2058 buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
2059 buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
2061 length = scst_get_buf_first(cmd, &address);
2062 if (unlikely(length <= 0)) {
2064 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2065 scst_set_cmd_error(cmd,
2066 SCST_LOAD_SENSE(scst_sense_hardw_error));
2071 if (length > READ_CAP_LEN)
2072 length = READ_CAP_LEN;
2073 memcpy(address, buffer, length);
2075 scst_put_buf(cmd, address);
2077 if (length < cmd->resp_data_len)
2078 scst_set_resp_data_len(cmd, length);
2085 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd)
2089 struct scst_vdisk_dev *virt_dev;
2092 uint8_t buffer[READ_CAP16_LEN];
2096 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2097 blocksize = virt_dev->block_size;
2098 nblocks = virt_dev->nblocks - 1;
2100 memset(buffer, 0, sizeof(buffer));
2102 buffer[0] = nblocks >> 56;
2103 buffer[1] = (nblocks >> 48) & 0xFF;
2104 buffer[2] = (nblocks >> 40) & 0xFF;
2105 buffer[3] = (nblocks >> 32) & 0xFF;
2106 buffer[4] = (nblocks >> 24) & 0xFF;
2107 buffer[5] = (nblocks >> 16) & 0xFF;
2108 buffer[6] = (nblocks >> 8) & 0xFF;
2109 buffer[7] = nblocks & 0xFF;
2111 buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
2112 buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
2113 buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
2114 buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
2116 switch (blocksize) {
2127 PRINT_ERROR("%s: Unexpected block size %d",
2128 cmd->op_name, blocksize);
2135 length = scst_get_buf_first(cmd, &address);
2136 if (unlikely(length <= 0)) {
2138 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2139 scst_set_cmd_error(cmd,
2140 SCST_LOAD_SENSE(scst_sense_hardw_error));
2146 * Some versions of Windows have a bug, which makes them consider
2147 * response of READ CAPACITY(16) longer than 12 bytes as a faulty one.
2148 * As the result, such Windows'es refuse to see SCST exported
2149 * devices >2TB in size. This is fixed by MS in latter Windows
2150 * versions, probably, by some hotfix.
2152 * But if you're using such buggy Windows and experience this problem,
2153 * change this '1' to '0'.
2156 if (length > READ_CAP16_LEN)
2157 length = READ_CAP16_LEN;
2162 memcpy(address, buffer, length);
2164 scst_put_buf(cmd, address);
2166 if (length < cmd->resp_data_len)
2167 scst_set_resp_data_len(cmd, length);
2174 static void vdisk_exec_read_toc(struct scst_cmd *cmd)
2176 int32_t length, off = 0;
2178 struct scst_vdisk_dev *virt_dev;
2180 uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
2181 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
2185 if (cmd->dev->type != TYPE_ROM) {
2186 PRINT_ERROR("%s", "READ TOC for non-CDROM device");
2187 scst_set_cmd_error(cmd,
2188 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
2192 if (cmd->cdb[2] & 0x0e/*Format*/) {
2193 PRINT_ERROR("%s", "READ TOC: invalid requested data format");
2194 scst_set_cmd_error(cmd,
2195 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2199 if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
2200 (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
2201 PRINT_ERROR("READ TOC: invalid requested track number %x",
2203 scst_set_cmd_error(cmd,
2204 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2208 length = scst_get_buf_first(cmd, &address);
2209 if (unlikely(length <= 0)) {
2211 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2212 scst_set_cmd_error(cmd,
2213 SCST_LOAD_SENSE(scst_sense_hardw_error));
2218 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2219 /* ToDo when you have > 8TB ROM device. */
2220 nblocks = (uint32_t)virt_dev->nblocks;
2223 memset(buffer, 0, sizeof(buffer));
2224 buffer[2] = 0x01; /* First Track/Session */
2225 buffer[3] = 0x01; /* Last Track/Session */
2227 if (cmd->cdb[6] <= 1) {
2228 /* Fistr TOC Track Descriptor */
2229 /* ADDR 0x10 - Q Sub-channel encodes current position data
2230 CONTROL 0x04 - Data track, recoreded uninterrupted */
2231 buffer[off+1] = 0x14;
2233 buffer[off+2] = 0x01;
2236 if (!(cmd->cdb[2] & 0x01)) {
2237 /* Lead-out area TOC Track Descriptor */
2238 buffer[off+1] = 0x14;
2240 buffer[off+2] = 0xAA;
2241 /* Track Start Address */
2242 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF;
2243 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
2244 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
2245 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
2249 buffer[1] = off - 2; /* Data Length */
2253 memcpy(address, buffer, off);
2255 scst_put_buf(cmd, address);
2257 if (off < cmd->resp_data_len)
2258 scst_set_resp_data_len(cmd, off);
2265 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
2267 struct scst_vdisk_dev *virt_dev =
2268 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2270 TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
2272 if (cmd->dev->type == TYPE_ROM) {
2273 spin_lock(&virt_dev->flags_lock);
2274 virt_dev->prevent_allow_medium_removal =
2275 cmd->cdb[4] & 0x01 ? 1 : 0;
2276 spin_unlock(&virt_dev->flags_lock);
2282 static int vdisk_fsync(struct scst_vdisk_thr *thr, loff_t loff,
2283 loff_t len, struct scst_cmd *cmd, struct scst_device *dev)
2286 struct scst_vdisk_dev *virt_dev =
2287 (struct scst_vdisk_dev *)dev->dh_priv;
2288 struct file *file = thr->fd;
2289 struct inode *inode;
2290 struct address_space *mapping;
2294 /* Hopefully, the compiler will generate the single comparison */
2295 if (virt_dev->nv_cache || virt_dev->blockio || virt_dev->wt_flag ||
2296 virt_dev->o_direct_flag || virt_dev->nullio)
2299 inode = file->f_dentry->d_inode;
2300 mapping = file->f_mapping;
2302 res = sync_page_range(inode, mapping, loff, len);
2303 if (unlikely(res != 0)) {
2304 PRINT_ERROR("sync_page_range() failed (%d)", res);
2306 scst_set_cmd_error(cmd,
2307 SCST_LOAD_SENSE(scst_sense_write_error));
2311 /* ToDo: flush the device cache, if needed */
2314 TRACE_EXIT_RES(res);
2318 static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd,
2319 struct scst_vdisk_thr *thr)
2323 iv_count = scst_get_buf_count(cmd);
2324 if (iv_count > thr->iv_count) {
2326 /* It can't be called in atomic context */
2327 thr->iv = kmalloc(sizeof(*thr->iv) * iv_count, GFP_KERNEL);
2328 if (thr->iv == NULL) {
2329 PRINT_ERROR("Unable to allocate iv (%d)", iv_count);
2333 thr->iv_count = iv_count;
2340 static void vdisk_exec_read(struct scst_cmd *cmd,
2341 struct scst_vdisk_thr *thr, loff_t loff)
2343 mm_segment_t old_fs;
2345 ssize_t length, full_len;
2346 uint8_t __user *address;
2347 struct scst_vdisk_dev *virt_dev =
2348 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2349 struct file *fd = thr->fd;
2355 if (virt_dev->nullio)
2358 iv = vdisk_alloc_iv(cmd, thr);
2365 length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2366 while (length > 0) {
2370 iv[i].iov_base = address;
2371 iv[i].iov_len = length;
2372 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2374 if (unlikely(length < 0)) {
2375 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2376 scst_set_cmd_error(cmd,
2377 SCST_LOAD_SENSE(scst_sense_hardw_error));
2384 TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
2386 if (fd->f_op->llseek)
2387 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2389 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2391 PRINT_ERROR("lseek trouble %lld != %lld",
2392 (long long unsigned int)err,
2393 (long long unsigned int)loff);
2394 scst_set_cmd_error(cmd,
2395 SCST_LOAD_SENSE(scst_sense_hardw_error));
2400 err = vfs_readv(fd, iv, iv_count, &fd->f_pos);
2402 if ((err < 0) || (err < full_len)) {
2403 PRINT_ERROR("readv() returned %lld from %zd",
2404 (long long unsigned int)err,
2409 scst_set_cmd_error(cmd,
2410 SCST_LOAD_SENSE(scst_sense_read_error));
2420 scst_put_buf(cmd, (void __force *)(iv[i].iov_base));
2427 static void vdisk_exec_write(struct scst_cmd *cmd,
2428 struct scst_vdisk_thr *thr, loff_t loff)
2430 mm_segment_t old_fs;
2432 ssize_t length, full_len;
2433 uint8_t __user *address;
2434 struct scst_vdisk_dev *virt_dev =
2435 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2436 struct file *fd = thr->fd;
2437 struct iovec *iv, *eiv;
2438 int iv_count, eiv_count;
2442 if (virt_dev->nullio)
2445 iv = vdisk_alloc_iv(cmd, thr);
2451 length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2452 while (length > 0) {
2454 iv[iv_count].iov_base = address;
2455 iv[iv_count].iov_len = length;
2457 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2459 if (unlikely(length < 0)) {
2460 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2461 scst_set_cmd_error(cmd,
2462 SCST_LOAD_SENSE(scst_sense_hardw_error));
2470 eiv_count = iv_count;
2472 TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2475 if (fd->f_op->llseek)
2476 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */);
2478 err = default_llseek(fd, loff, 0 /*SEEK_SET */);
2480 PRINT_ERROR("lseek trouble %lld != %lld",
2481 (long long unsigned int)err,
2482 (long long unsigned int)loff);
2483 scst_set_cmd_error(cmd,
2484 SCST_LOAD_SENSE(scst_sense_hardw_error));
2489 err = vfs_writev(fd, eiv, eiv_count, &fd->f_pos);
2492 PRINT_ERROR("write() returned %lld from %zd",
2493 (long long unsigned int)err,
2498 scst_set_cmd_error(cmd,
2499 SCST_LOAD_SENSE(scst_sense_write_error));
2502 } else if (err < full_len) {
2504 * Probably that's wrong, but sometimes write() returns
2505 * value less, than requested. Let's restart.
2507 int i, e = eiv_count;
2508 TRACE_MGMT_DBG("write() returned %d from %zd "
2509 "(iv_count=%d)", (int)err, full_len,
2512 PRINT_INFO("Suspicious: write() returned 0 from "
2513 "%zd (iv_count=%d)", full_len, eiv_count);
2516 for (i = 0; i < e; i++) {
2517 if ((long long)eiv->iov_len < err) {
2518 err -= eiv->iov_len;
2523 (uint8_t __force __user *)eiv->iov_base +
2525 eiv->iov_len -= err;
2536 while (iv_count > 0) {
2537 scst_put_buf(cmd, (void __force *)(iv[iv_count-1].iov_base));
2546 struct scst_blockio_work {
2547 atomic_t bios_inflight;
2548 struct scst_cmd *cmd;
2551 static inline void blockio_check_finish(struct scst_blockio_work *blockio_work)
2553 /* Decrement the bios in processing, and if zero signal completion */
2554 if (atomic_dec_and_test(&blockio_work->bios_inflight)) {
2555 blockio_work->cmd->completed = 1;
2556 blockio_work->cmd->scst_cmd_done(blockio_work->cmd,
2557 SCST_CMD_STATE_DEFAULT, scst_estimate_context());
2558 kmem_cache_free(blockio_work_cachep, blockio_work);
2563 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2564 static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
2566 static void blockio_endio(struct bio *bio, int error)
2569 struct scst_blockio_work *blockio_work = bio->bi_private;
2571 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2576 error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
2578 if (unlikely(error != 0)) {
2579 PRINT_ERROR("cmd %p returned error %d", blockio_work->cmd,
2582 * The race with other such bio's doesn't matter, since all
2583 * scst_set_cmd_error() calls do the same local to this cmd
2586 if (bio->bi_rw & WRITE)
2587 scst_set_cmd_error(blockio_work->cmd,
2588 SCST_LOAD_SENSE(scst_sense_write_error));
2590 scst_set_cmd_error(blockio_work->cmd,
2591 SCST_LOAD_SENSE(scst_sense_read_error));
2594 blockio_check_finish(blockio_work);
2597 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2604 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
2605 u64 lba_start, int write)
2607 struct scst_vdisk_dev *virt_dev =
2608 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2609 struct block_device *bdev = thr->bdev;
2610 struct request_queue *q = bdev_get_queue(bdev);
2611 int length, max_nr_vecs = 0;
2613 struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
2615 struct scst_blockio_work *blockio_work;
2620 if (virt_dev->nullio)
2623 /* Allocate and initialize blockio_work struct */
2624 blockio_work = kmem_cache_alloc(blockio_work_cachep, GFP_KERNEL);
2625 if (blockio_work == NULL)
2628 blockio_work->cmd = cmd;
2631 max_nr_vecs = min(bio_get_nr_vecs(bdev), BIO_MAX_PAGES);
2637 length = scst_get_buf_first(cmd, &address);
2638 while (length > 0) {
2639 int len, bytes, off, thislen;
2644 off = offset_in_page(addr);
2647 lba_start0 = lba_start;
2651 struct page *page = virt_to_page(addr);
2654 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
2655 bio = bio_kmalloc(GFP_KERNEL, max_nr_vecs);
2657 bio = bio_alloc(GFP_KERNEL, max_nr_vecs);
2660 PRINT_ERROR("Failed to create bio "
2661 "for data segment %d (cmd %p)",
2662 cmd->get_sg_buf_entry_num, cmd);
2668 bio->bi_end_io = blockio_endio;
2669 bio->bi_sector = lba_start0 <<
2670 (virt_dev->block_shift - 9);
2671 bio->bi_bdev = bdev;
2672 bio->bi_private = blockio_work;
2673 #if 0 /* It could be win, but could be not, so a performance study is needed */
2674 bio->bi_rw |= 1 << BIO_RW_SYNC;
2679 tbio = tbio->bi_next = bio;
2682 bytes = min_t(unsigned int, len, PAGE_SIZE - off);
2684 rc = bio_add_page(bio, page, bytes, off);
2688 lba_start0 += thislen >> virt_dev->block_shift;
2699 lba_start += length >> virt_dev->block_shift;
2701 scst_put_buf(cmd, address);
2702 length = scst_get_buf_next(cmd, &address);
2705 /* +1 to prevent erroneous too early command completion */
2706 atomic_set(&blockio_work->bios_inflight, bios+1);
2710 hbio = hbio->bi_next;
2711 bio->bi_next = NULL;
2712 submit_bio(write, bio);
2715 if (q && q->unplug_fn)
2718 blockio_check_finish(blockio_work);
2727 hbio = hbio->bi_next;
2730 kmem_cache_free(blockio_work_cachep, blockio_work);
2737 static void vdisk_exec_verify(struct scst_cmd *cmd,
2738 struct scst_vdisk_thr *thr, loff_t loff)
2740 mm_segment_t old_fs;
2742 ssize_t length, len_mem = 0;
2743 uint8_t *address_sav, *address;
2745 struct scst_vdisk_dev *virt_dev =
2746 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2747 struct file *fd = thr->fd;
2748 uint8_t *mem_verify = NULL;
2752 if (vdisk_fsync(thr, loff, cmd->bufflen, cmd, cmd->dev) != 0)
2756 * Until the cache is cleared prior the verifying, there is not
2757 * much point in this code. ToDo.
2759 * Nevertherless, this code is valuable if the data have not read
2760 * from the file/disk yet.
2767 if (!virt_dev->nullio) {
2768 if (fd->f_op->llseek)
2769 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2771 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2773 PRINT_ERROR("lseek trouble %lld != %lld",
2774 (long long unsigned int)err,
2775 (long long unsigned int)loff);
2776 scst_set_cmd_error(cmd,
2777 SCST_LOAD_SENSE(scst_sense_hardw_error));
2782 mem_verify = vmalloc(LEN_MEM);
2783 if (mem_verify == NULL) {
2784 PRINT_ERROR("Unable to allocate memory %d for verify",
2786 scst_set_cmd_error(cmd,
2787 SCST_LOAD_SENSE(scst_sense_hardw_error));
2791 length = scst_get_buf_first(cmd, &address);
2792 address_sav = address;
2793 if (!length && cmd->data_len) {
2794 length = cmd->data_len;
2799 while (length > 0) {
2800 len_mem = (length > LEN_MEM) ? LEN_MEM : length;
2801 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2803 if (!virt_dev->nullio)
2804 err = vfs_read(fd, (char __force __user *)mem_verify,
2805 len_mem, &fd->f_pos);
2808 if ((err < 0) || (err < len_mem)) {
2809 PRINT_ERROR("verify() returned %lld from %zd",
2810 (long long unsigned int)err, len_mem);
2814 scst_set_cmd_error(cmd,
2815 SCST_LOAD_SENSE(scst_sense_read_error));
2818 scst_put_buf(cmd, address_sav);
2821 if (compare && memcmp(address, mem_verify, len_mem) != 0) {
2822 TRACE_DBG("Verify: error memcmp length %zd", length);
2823 scst_set_cmd_error(cmd,
2824 SCST_LOAD_SENSE(scst_sense_miscompare_error));
2825 scst_put_buf(cmd, address_sav);
2830 if (compare && length <= 0) {
2831 scst_put_buf(cmd, address_sav);
2832 length = scst_get_buf_next(cmd, &address);
2833 address_sav = address;
2838 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2839 scst_set_cmd_error(cmd,
2840 SCST_LOAD_SENSE(scst_sense_hardw_error));
2853 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2854 struct scst_tgt_dev *tgt_dev)
2858 if ((mcmd->fn == SCST_LUN_RESET) || (mcmd->fn == SCST_TARGET_RESET)) {
2859 /* Restore default values */
2860 struct scst_device *dev = tgt_dev->dev;
2861 struct scst_vdisk_dev *virt_dev =
2862 (struct scst_vdisk_dev *)dev->dh_priv;
2865 dev->d_sense = DEF_DSENSE;
2866 if (virt_dev->wt_flag && !virt_dev->nv_cache)
2867 dev->queue_alg = DEF_QUEUE_ALG_WT;
2869 dev->queue_alg = DEF_QUEUE_ALG;
2873 virt_dev->prevent_allow_medium_removal = 0;
2877 return SCST_DEV_TM_NOT_COMPLETED;
2880 static void vdisk_report_registering(const struct scst_vdisk_dev *virt_dev)
2885 i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s ",
2886 virt_dev->vdt->vdt_name, virt_dev->name);
2889 if (virt_dev->wt_flag)
2890 i += snprintf(&buf[i], sizeof(buf) - i, "(WRITE_THROUGH");
2892 if (virt_dev->nv_cache)
2893 i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE",
2894 (j == i) ? "(" : ", ");
2896 if (virt_dev->rd_only)
2897 i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY",
2898 (j == i) ? "(" : ", ");
2900 if (virt_dev->o_direct_flag)
2901 i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT",
2902 (j == i) ? "(" : ", ");
2904 if (virt_dev->nullio)
2905 i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO",
2906 (j == i) ? "(" : ", ");
2908 if (virt_dev->blockio)
2909 i += snprintf(&buf[i], sizeof(buf) - i, "%sBLOCKIO",
2910 (j == i) ? "(" : ", ");
2912 if (virt_dev->removable)
2913 i += snprintf(&buf[i], sizeof(buf) - i, "%sREMOVABLE",
2914 (j == i) ? "(" : ", ");
2917 PRINT_INFO("%s", buf);
2919 PRINT_INFO("%s)", buf);
2924 /* scst_vdisk_mutex supposed to be held */
2925 static int __vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
2930 if (!virt_dev->nullio) {
2931 res = vdisk_get_file_size(virt_dev->file_name,
2932 virt_dev->blockio, &file_size);
2936 file_size = VDISK_NULLIO_SIZE;
2938 if (file_size == virt_dev->file_size) {
2939 PRINT_INFO("Size of virtual disk %s remained the same",
2944 res = scst_suspend_activity(true);
2948 virt_dev->file_size = file_size;
2949 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
2951 scst_dev_del_all_thr_data(virt_dev->dev);
2953 PRINT_INFO("New size of SCSI target virtual disk %s "
2954 "(fs=%lldMB, bs=%d, nblocks=%lld, cyln=%lld%s)",
2955 virt_dev->name, virt_dev->file_size >> 20,
2956 virt_dev->block_size,
2957 (long long unsigned int)virt_dev->nblocks,
2958 (long long unsigned int)virt_dev->nblocks/64/32,
2959 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
2962 scst_capacity_data_changed(virt_dev->dev);
2964 scst_resume_activity();
2970 /* scst_vdisk_mutex supposed to be held */
2971 static int vdisk_resync_size(struct vdev_type *vdt, char *p, const char *name)
2973 struct scst_vdisk_dev *virt_dev;
2976 virt_dev = vdt->vfns.vdev_find(name);
2977 if (virt_dev == NULL) {
2978 PRINT_ERROR("Device %s not found", name);
2983 res = __vdisk_resync_size(virt_dev);
2986 TRACE_EXIT_RES(res);
2990 static void vdev_init(struct vdev_type *vdt, struct scst_vdisk_dev *virt_dev)
2992 memset(virt_dev, 0, sizeof(*virt_dev));
2993 spin_lock_init(&virt_dev->flags_lock);
2994 virt_dev->vdt = vdt;
2996 virt_dev->block_size = DEF_DISK_BLOCKSIZE;
2997 virt_dev->block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
3002 static struct scst_vdisk_dev *vdev_create(struct vdev_type *vdt)
3004 struct scst_vdisk_dev *virt_dev;
3006 virt_dev = kmalloc(sizeof(*virt_dev), GFP_KERNEL);
3007 if (virt_dev == NULL) {
3008 PRINT_ERROR("Allocation of virtual device %s failed",
3013 vdt->vfns.vdev_init(vdt, virt_dev);
3019 static void vdev_deinit(struct scst_vdisk_dev *virt_dev)
3021 kfree(virt_dev->file_name);
3025 static void vdev_destroy(struct scst_vdisk_dev *virt_dev)
3027 virt_dev->vdt->vfns.vdev_deinit(virt_dev);
3032 static int vdisk_fileio_pre_register(struct scst_vdisk_dev *virt_dev)
3036 if ((virt_dev->file_name == NULL) ||
3037 (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0)) {
3038 PRINT_ERROR("%s", "File name required");
3043 if (virt_dev->rd_only && (virt_dev->wt_flag || virt_dev->nv_cache)) {
3044 PRINT_ERROR("Write options on read only device %s",
3054 static int vdisk_blockio_pre_register(struct scst_vdisk_dev *virt_dev)
3058 if ((virt_dev->file_name == NULL) ||
3059 (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0)) {
3060 PRINT_ERROR("%s", "File name required");
3069 static void vdisk_blockio_init(struct vdev_type *vdt,
3070 struct scst_vdisk_dev *virt_dev)
3072 struct vdisk_blockio_type *v;
3074 v = container_of(vdt, struct vdisk_blockio_type, parent_vdt);
3076 v->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3078 virt_dev->blockio = 1;
3082 static void vdisk_nullio_init(struct vdev_type *vdt,
3083 struct scst_vdisk_dev *virt_dev)
3085 struct vdisk_nullio_type *v;
3087 v = container_of(vdt, struct vdisk_nullio_type, parent_vdt);
3089 v->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3091 virt_dev->nullio = 1;
3095 static int vdisk_parse_option(struct scst_vdisk_dev *virt_dev, char *p)
3101 if (!strncmp("READ_ONLY", p, 9)) {
3103 virt_dev->rd_only = 1;
3104 TRACE_DBG("%s", "READ_ONLY");
3105 } else if (!strncmp("REMOVABLE", p, 9)) {
3107 virt_dev->removable = 1;
3108 TRACE_DBG("%s", "REMOVABLE");
3111 TRACE_EXIT_RES(res);
3115 static int vdisk_fileio_parse_option(struct scst_vdisk_dev *virt_dev, char *p)
3121 res = vdisk_parse_option(virt_dev, p);
3125 if (!strncmp("WRITE_THROUGH", p, 13)) {
3127 virt_dev->wt_flag = 1;
3128 TRACE_DBG("%s", "WRITE_THROUGH");
3129 } else if (!strncmp("NV_CACHE", p, 8)) {
3131 virt_dev->nv_cache = 1;
3132 TRACE_DBG("%s", "NON-VOLATILE CACHE");
3133 } else if (!strncmp("O_DIRECT", p, 8)) {
3136 virt_dev->o_direct_flag = 1;
3137 TRACE_DBG("%s", "O_DIRECT");
3139 PRINT_INFO("%s flag doesn't currently"
3140 " work, ignoring it, use fileio_tgt "
3141 "in O_DIRECT mode instead", "O_DIRECT");
3146 TRACE_EXIT_RES(res);
3150 /* scst_vdisk_mutex supposed to be held */
3151 static int vdev_open(struct vdev_type *vdt, char *p, const char *name)
3155 struct scst_vdisk_dev *virt_dev;
3160 virt_dev = vdt->vfns.vdev_find(name);
3161 if (virt_dev != NULL) {
3162 PRINT_ERROR("Virtual device with name %s already exist", name);
3167 while (isspace(*p) && *p != '\0')
3170 if ((*file_name == '/') || (strcmp(file_name, VDEV_NONE_FILENAME) == 0)) {
3171 while (!isspace(*p) && *p != '\0')
3175 TRACE_DBG("file name %s", file_name);
3177 while (isspace(*p) && *p != '\0')
3180 TRACE_DBG("file name %s", "not specified");
3184 virt_dev = vdt->vfns.vdev_create(vdt);
3185 if (virt_dev == NULL) {
3186 TRACE(TRACE_OUT_OF_MEM, "Creation of virt_dev %s failed", name);
3192 uint32_t block_size;
3196 block_size = simple_strtoul(p, &pp, 0);
3198 if ((*p != '\0') && !isspace(*p)) {
3199 PRINT_ERROR("Parse error: \"%s\"", p);
3203 while (isspace(*p) && *p != '\0')
3206 block_shift = scst_calc_block_shift(block_size);
3207 if (block_shift < 9) {
3212 TRACE_DBG("block_size %d, block_shift %d", block_size,
3215 virt_dev->block_size = block_size;
3216 virt_dev->block_shift = block_shift;
3219 while (*p != '\0') {
3220 while (isspace(*p) && *p != '\0')
3223 if (vdt->vfns.parse_option != NULL)
3224 res = vdt->vfns.parse_option(virt_dev, p);
3229 PRINT_ERROR("Unknown option \"%s\"", p);
3231 } else if (res == 0)
3236 if (!isspace(*p) && (*p != '\0')) {
3237 PRINT_ERROR("Syntax error on %s", p);
3242 strcpy(virt_dev->name, name);
3244 scnprintf(virt_dev->usn, sizeof(virt_dev->usn), "%llx",
3245 vdisk_gen_dev_id_num(virt_dev));
3246 TRACE_DBG("usn %s", virt_dev->usn);
3248 if (file_name != NULL) {
3249 len = strlen(file_name) + 1;
3250 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
3251 if (virt_dev->file_name == NULL) {
3252 TRACE(TRACE_OUT_OF_MEM, "Allocation of file_name %s "
3253 "failed", file_name);
3257 strncpy(virt_dev->file_name, file_name, len);
3260 if (vdt->vfns.pre_register != NULL) {
3261 res = vdt->vfns.pre_register(virt_dev);
3263 goto out_free_vpath;
3266 vdt->vfns.vdev_add(virt_dev);
3268 vdisk_report_registering(virt_dev);
3269 virt_dev->virt_id = scst_register_virtual_device(vdt->vdt_devt,
3271 if (virt_dev->virt_id < 0) {
3272 res = virt_dev->virt_id;
3276 TRACE_DBG("Added virt_dev (name %s, file name %s, id %d, block size "
3277 "%d) to vdisk_dev_list", virt_dev->name, virt_dev->file_name,
3278 virt_dev->virt_id, virt_dev->block_size);
3281 TRACE_EXIT_RES(res);
3285 vdt->vfns.vdev_del(virt_dev);
3288 kfree(virt_dev->file_name);
3295 /* scst_vdisk_mutex supposed to be held */
3296 static int vdev_close(struct vdev_type *vdt, const char *name)
3299 struct scst_vdisk_dev *virt_dev;
3303 virt_dev = vdt->vfns.vdev_find(name);
3304 if (virt_dev == NULL) {
3305 PRINT_ERROR("Device %s not found", name);
3310 scst_unregister_virtual_device(virt_dev->virt_id);
3312 PRINT_INFO("Virtual device %s unregistered", virt_dev->name);
3313 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3315 vdt->vfns.vdev_del(virt_dev);
3316 vdt->vfns.vdev_destroy(virt_dev);
3319 TRACE_EXIT_RES(res);
3323 /* scst_vdisk_mutex supposed to be held */
3324 static void vdev_del(struct scst_vdisk_dev *virt_dev)
3328 list_del(&virt_dev->vdisk_dev_list_entry);
3334 /* scst_vdisk_mutex supposed to be held */
3335 static void vdisk_add(struct scst_vdisk_dev *virt_dev)
3339 list_add_tail(&virt_dev->vdisk_dev_list_entry, &vdisk_dev_list);
3345 /* scst_vdisk_mutex supposed to be held */
3346 static struct scst_vdisk_dev *vdisk_find(const char *name)
3348 struct scst_vdisk_dev *res, *vv;
3353 list_for_each_entry(vv, &vdisk_dev_list, vdisk_dev_list_entry) {
3354 if (strcmp(vv->name, name) == 0) {
3360 TRACE_EXIT_HRES((unsigned long)res);
3364 /* scst_vdisk_mutex supposed to be held */
3365 static void vcdrom_add(struct scst_vdisk_dev *virt_dev)
3369 list_add_tail(&virt_dev->vdisk_dev_list_entry, &vcdrom_dev_list);
3375 /* scst_vdisk_mutex supposed to be held */
3376 static struct scst_vdisk_dev *vcdrom_find(const char *name)
3378 struct scst_vdisk_dev *res, *vv;
3383 list_for_each_entry(vv, &vcdrom_dev_list, vdisk_dev_list_entry) {
3384 if (strcmp(vv->name, name) == 0) {
3390 TRACE_EXIT_HRES((unsigned long)res);
3394 static int vdisk_parse_cmd(struct vdev_type *vdt, char *p, int *action)
3400 if (!strncmp("resync_size", p, 11)) {
3403 *action = VDISK_ACTION_RESYNC_SIZE;
3406 TRACE_EXIT_RES(res);
3410 /* scst_vdisk_mutex supposed to be held */
3411 static int vdisk_perform_cmd(struct vdev_type *vdt, int action, char *p,
3418 if (action == VDISK_ACTION_RESYNC_SIZE)
3419 res = vdisk_resync_size(vdt, p, name);
3421 TRACE_EXIT_RES(res);
3425 static void vcdrom_init(struct vdev_type *vdt,
3426 struct scst_vdisk_dev *virt_dev)
3428 struct vcdrom_type *vt;
3430 vt = container_of(vdt, struct vcdrom_type, parent_vdt);
3432 vt->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3434 virt_dev->rd_only = 1;
3435 virt_dev->removable = 1;
3437 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
3438 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
3443 static int vcdrom_pre_register(struct scst_vdisk_dev *virt_dev)
3447 if ((virt_dev->file_name == NULL) ||
3448 (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0))
3449 virt_dev->cdrom_empty = 1;
3451 if (virt_dev->block_size != DEF_CDROM_BLOCKSIZE) {
3452 PRINT_WARNING("Block size %d for vortual device %s ignored",
3453 virt_dev->block_size, virt_dev->name);
3454 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
3455 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
3461 /* scst_vdisk_mutex supposed to be held */
3462 static int vcdrom_change(struct vdev_type *vdt, char *p, const char *name)
3465 struct scst_vdisk_dev *virt_dev;
3466 char *file_name, *fn = NULL, *old_fn;
3470 virt_dev = vdt->vfns.vdev_find(name);
3471 if (virt_dev == NULL) {
3472 PRINT_ERROR("Virtual device with name "
3473 "%s not found", name);
3478 while (isspace(*p) && *p != '\0')
3481 while (!isspace(*p) && *p != '\0')
3484 if (*file_name == '\0') {
3485 virt_dev->cdrom_empty = 1;
3486 TRACE_DBG("%s", "No media");
3487 } else if (*file_name != '/') {
3488 PRINT_ERROR("File path \"%s\" is not "
3489 "absolute", file_name);
3493 virt_dev->cdrom_empty = 0;
3495 old_fn = virt_dev->file_name;
3497 if (!virt_dev->cdrom_empty) {
3498 len = strlen(file_name) + 1;
3499 fn = kmalloc(len, GFP_KERNEL);
3501 TRACE(TRACE_OUT_OF_MEM, "%s",
3502 "Allocation of file_name failed");
3507 strncpy(fn, file_name, len);
3508 virt_dev->file_name = fn;
3510 res = vdisk_get_file_size(virt_dev->file_name,
3511 virt_dev->blockio, &err);
3516 virt_dev->file_name = NULL;
3519 res = scst_suspend_activity(true);
3523 if (virt_dev->prevent_allow_medium_removal) {
3524 PRINT_ERROR("Prevent medium removal for "
3525 "virtual device with name %s", name);
3527 goto out_free_resume;
3530 virt_dev->file_size = err;
3531 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
3532 if (!virt_dev->cdrom_empty)
3533 virt_dev->media_changed = 1;
3535 scst_dev_del_all_thr_data(virt_dev->dev);
3537 if (!virt_dev->cdrom_empty) {
3538 PRINT_INFO("Changed SCSI target virtual cdrom %s "
3539 "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
3540 " cyln=%lld%s)", virt_dev->name, virt_dev->file_name,
3541 virt_dev->file_size >> 20, virt_dev->block_size,
3542 (long long unsigned int)virt_dev->nblocks,
3543 (long long unsigned int)virt_dev->nblocks/64/32,
3544 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
3547 PRINT_INFO("Removed media from SCSI target virtual cdrom %s",
3554 scst_resume_activity();
3560 virt_dev->file_name = old_fn;