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 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
682 if ((fd->f_op == NULL) ||
683 (fd->f_op->readv == NULL) ||
684 (fd->f_op->writev == NULL)) {
686 if ((fd->f_op == NULL) ||
687 (fd->f_op->aio_read == NULL) ||
688 (fd->f_op->aio_write == NULL)) {
690 PRINT_ERROR("%s", "Wrong f_op or FS doesn't have required "
696 inode = fd->f_dentry->d_inode;
698 if (blockio && !S_ISBLK(inode->i_mode)) {
699 PRINT_ERROR("File %s is NOT a block device", file_name);
704 if (S_ISREG(inode->i_mode))
706 else if (S_ISBLK(inode->i_mode))
707 inode = inode->i_bdev->bd_inode;
713 *file_size = inode->i_size;
716 filp_close(fd, NULL);
723 /**************************************************************
724 * Function: vdisk_attach
728 * Returns : 1 if attached, error code otherwise
731 *************************************************************/
732 static int vdisk_attach(struct scst_device *dev)
736 struct scst_vdisk_dev *virt_dev = NULL, *vv;
737 struct list_head *vd;
741 TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
743 if (dev->virt_id == 0) {
744 PRINT_ERROR("%s", "Not a virtual device");
749 vd = (dev->type == TYPE_DISK) ?
754 * scst_vdisk_mutex must be already taken before
755 * scst_register_virtual_device()
757 list_for_each_entry(vv, vd, vdisk_dev_list_entry) {
758 if (strcmp(vv->name, dev->virt_name) == 0) {
764 if (virt_dev == NULL) {
765 PRINT_ERROR("Device %s not found", dev->virt_name);
772 dev->rd_only = virt_dev->rd_only;
773 if (dev->type == TYPE_ROM)
776 if (!virt_dev->cdrom_empty) {
777 if (virt_dev->nullio)
778 err = VDISK_NULLIO_SIZE;
780 res = vdisk_get_file_size(virt_dev->file_name,
781 virt_dev->blockio, &err);
785 virt_dev->file_size = err;
786 TRACE_DBG("size of file: %lld", (long long unsigned int)err);
788 virt_dev->file_size = 0;
790 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
792 if (!virt_dev->cdrom_empty) {
793 PRINT_INFO("Attached SCSI target virtual %s %s "
794 "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
796 (dev->type == TYPE_DISK) ? "disk" : "cdrom",
797 virt_dev->name, virt_dev->file_name,
798 virt_dev->file_size >> 20, virt_dev->block_size,
799 (long long unsigned int)virt_dev->nblocks,
800 (long long unsigned int)virt_dev->nblocks/64/32,
801 virt_dev->nblocks < 64*32
802 ? " !WARNING! cyln less than 1" : "");
804 PRINT_INFO("Attached empty SCSI target virtual cdrom %s",
808 dev->dh_priv = virt_dev;
811 dev->d_sense = DEF_DSENSE;
812 if (virt_dev->wt_flag && !virt_dev->nv_cache)
813 dev->queue_alg = DEF_QUEUE_ALG_WT;
815 dev->queue_alg = DEF_QUEUE_ALG;
824 /************************************************************
825 * Function: vdisk_detach
831 * Description: Called to detach this device type driver
832 ************************************************************/
833 static void vdisk_detach(struct scst_device *dev)
835 struct scst_vdisk_dev *virt_dev =
836 (struct scst_vdisk_dev *)dev->dh_priv;
840 TRACE_DBG("virt_id %d", dev->virt_id);
842 PRINT_INFO("Detached SCSI target virtual device %s (\"%s\")",
843 virt_dev->name, virt_dev->file_name);
845 /* virt_dev will be freed by the caller */
852 static void vdisk_free_thr_data(struct scst_thr_data_hdr *d)
854 struct scst_vdisk_thr *thr =
855 container_of(d, struct scst_vdisk_thr, hdr);
860 filp_close(thr->fd, NULL);
864 kmem_cache_free(vdisk_thr_cachep, thr);
870 static struct scst_vdisk_thr *vdisk_init_thr_data(
871 struct scst_tgt_dev *tgt_dev)
873 struct scst_vdisk_thr *res;
874 struct scst_vdisk_dev *virt_dev =
875 (struct scst_vdisk_dev *)tgt_dev->dev->dh_priv;
879 EXTRACHECKS_BUG_ON(virt_dev->nullio);
881 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
882 res = kmem_cache_alloc(vdisk_thr_cachep, GFP_KERNEL);
884 memset(res, 0, sizeof(*res));
886 res = kmem_cache_zalloc(vdisk_thr_cachep, GFP_KERNEL);
889 TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct "
894 if (!virt_dev->cdrom_empty) {
895 res->fd = vdev_open_fd(virt_dev);
896 if (IS_ERR(res->fd)) {
897 PRINT_ERROR("filp_open(%s) returned an error %ld",
898 virt_dev->file_name, PTR_ERR(res->fd));
901 if (virt_dev->blockio)
902 res->bdev = res->fd->f_dentry->d_inode->i_bdev;
908 scst_add_thr_data(tgt_dev, &res->hdr, vdisk_free_thr_data);
911 TRACE_EXIT_HRES((unsigned long)res);
915 kmem_cache_free(vdisk_thr_cachep, res);
920 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev)
922 struct scst_vdisk_tgt_dev *ftgt_dev;
927 ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL);
928 if (ftgt_dev == NULL) {
929 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
930 "virtual device failed");
935 tgt_dev->dh_priv = ftgt_dev;
942 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev)
944 struct scst_vdisk_tgt_dev *ftgt_dev =
945 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
949 scst_del_all_thr_data(tgt_dev);
952 tgt_dev->dh_priv = NULL;
958 static inline int vdisk_sync_queue_type(enum scst_cmd_queue_type qt)
961 case SCST_CMD_QUEUE_ORDERED:
962 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
969 static inline int vdisk_need_pre_sync(enum scst_cmd_queue_type cur,
970 enum scst_cmd_queue_type last)
972 if (vdisk_sync_queue_type(cur))
973 if (!vdisk_sync_queue_type(last))
978 static int vdisk_do_job(struct scst_cmd *cmd)
981 uint64_t lba_start = 0;
983 uint8_t *cdb = cmd->cdb;
986 struct scst_device *dev = cmd->dev;
987 struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
988 struct scst_vdisk_dev *virt_dev =
989 (struct scst_vdisk_dev *)dev->dh_priv;
990 struct scst_thr_data_hdr *d;
991 struct scst_vdisk_thr *thr = NULL;
996 switch (cmd->queue_type) {
997 case SCST_CMD_QUEUE_ORDERED:
998 TRACE(TRACE_ORDER, "ORDERED cmd %p (op %x)", cmd, cmd->cdb[0]);
1000 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
1001 TRACE(TRACE_ORDER, "HQ cmd %p (op %x)", cmd, cmd->cdb[0]);
1007 rc = scst_check_local_events(cmd);
1008 if (unlikely(rc != 0))
1012 cmd->msg_status = 0;
1013 cmd->host_status = DID_OK;
1014 cmd->driver_status = 0;
1016 if (!virt_dev->nullio) {
1017 d = scst_find_thr_data(tgt_dev);
1018 if (unlikely(d == NULL)) {
1019 thr = vdisk_init_thr_data(tgt_dev);
1024 scst_thr_data_get(&thr->hdr);
1026 thr = container_of(d, struct scst_vdisk_thr, hdr);
1028 thr = &nullio_thr_data;
1029 scst_thr_data_get(&thr->hdr);
1036 lba_start = (((cdb[1] & 0x1f) << (BYTE * 2)) +
1037 (cdb[2] << (BYTE * 1)) +
1038 (cdb[3] << (BYTE * 0)));
1039 data_len = cmd->bufflen;
1047 case WRITE_VERIFY_12:
1049 lba_start |= ((u64)cdb[2]) << 24;
1050 lba_start |= ((u64)cdb[3]) << 16;
1051 lba_start |= ((u64)cdb[4]) << 8;
1052 lba_start |= ((u64)cdb[5]);
1053 data_len = cmd->bufflen;
1057 case WRITE_VERIFY_16:
1059 lba_start |= ((u64)cdb[2]) << 56;
1060 lba_start |= ((u64)cdb[3]) << 48;
1061 lba_start |= ((u64)cdb[4]) << 40;
1062 lba_start |= ((u64)cdb[5]) << 32;
1063 lba_start |= ((u64)cdb[6]) << 24;
1064 lba_start |= ((u64)cdb[7]) << 16;
1065 lba_start |= ((u64)cdb[8]) << 8;
1066 lba_start |= ((u64)cdb[9]);
1067 data_len = cmd->bufflen;
1069 case SYNCHRONIZE_CACHE:
1070 lba_start |= ((u64)cdb[2]) << 24;
1071 lba_start |= ((u64)cdb[3]) << 16;
1072 lba_start |= ((u64)cdb[4]) << 8;
1073 lba_start |= ((u64)cdb[5]);
1074 data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0)))
1075 << virt_dev->block_shift;
1077 data_len = virt_dev->file_size -
1078 ((loff_t)lba_start << virt_dev->block_shift);
1082 loff = (loff_t)lba_start << virt_dev->block_shift;
1083 TRACE_DBG("cmd %p, lba_start %lld, loff %lld, data_len %lld", cmd,
1084 (long long unsigned int)lba_start,
1085 (long long unsigned int)loff,
1086 (long long unsigned int)data_len);
1087 if (unlikely(loff < 0) || unlikely(data_len < 0) ||
1088 unlikely((loff + data_len) > virt_dev->file_size)) {
1089 PRINT_INFO("Access beyond the end of the device "
1090 "(%lld of %lld, len %lld)",
1091 (long long unsigned int)loff,
1092 (long long unsigned int)virt_dev->file_size,
1093 (long long unsigned int)data_len);
1094 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1095 scst_sense_block_out_range_error));
1103 fua = (cdb[1] & 0x8);
1105 TRACE(TRACE_ORDER, "FUA: loff=%lld, "
1106 "data_len=%lld", (long long unsigned int)loff,
1107 (long long unsigned int)data_len);
1117 if (virt_dev->blockio) {
1118 blockio_exec_rw(cmd, thr, lba_start, 0);
1121 vdisk_exec_read(cmd, thr, loff);
1128 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
1129 struct scst_vdisk_tgt_dev *ftgt_dev =
1130 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
1131 enum scst_cmd_queue_type last_queue_type =
1132 ftgt_dev->last_write_cmd_queue_type;
1133 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
1134 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
1135 TRACE(TRACE_ORDER, "ORDERED WRITE(%d): loff=%lld, "
1136 "data_len=%lld", cmd->queue_type,
1137 (long long unsigned int)loff,
1138 (long long unsigned int)data_len);
1140 if (vdisk_fsync(thr, 0, 0, cmd, dev) != 0)
1143 if (virt_dev->blockio) {
1144 blockio_exec_rw(cmd, thr, lba_start, 1);
1147 vdisk_exec_write(cmd, thr, loff);
1148 /* O_SYNC flag is used for WT devices */
1149 if (do_fsync || fua)
1150 vdisk_fsync(thr, loff, data_len, cmd, dev);
1154 case WRITE_VERIFY_12:
1155 case WRITE_VERIFY_16:
1157 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
1158 struct scst_vdisk_tgt_dev *ftgt_dev =
1159 (struct scst_vdisk_tgt_dev *) tgt_dev->dh_priv;
1160 enum scst_cmd_queue_type last_queue_type =
1161 ftgt_dev->last_write_cmd_queue_type;
1162 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
1163 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
1164 TRACE(TRACE_ORDER, "ORDERED "
1165 "WRITE_VERIFY(%d): loff=%lld,"
1166 " data_len=%lld", cmd->queue_type,
1167 (long long unsigned int)loff,
1168 (long long unsigned int)data_len);
1170 if (vdisk_fsync(thr, 0, 0, cmd, dev) != 0)
1173 /* ToDo: BLOCKIO VERIFY */
1174 vdisk_exec_write(cmd, thr, loff);
1175 /* O_SYNC flag is used for WT devices */
1176 if (scsi_status_is_good(cmd->status))
1177 vdisk_exec_verify(cmd, thr, loff);
1179 vdisk_fsync(thr, loff, data_len, cmd, dev);
1182 case SYNCHRONIZE_CACHE:
1184 int immed = cdb[1] & 0x2;
1185 TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: "
1186 "loff=%lld, data_len=%lld, immed=%d",
1187 (long long unsigned int)loff,
1188 (long long unsigned int)data_len, immed);
1190 scst_cmd_get(cmd); /* to protect dev */
1192 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
1194 vdisk_fsync(thr, loff, data_len, NULL, dev);
1195 /* ToDo: vdisk_fsync() error processing */
1199 vdisk_fsync(thr, loff, data_len, cmd, dev);
1207 vdisk_exec_verify(cmd, thr, loff);
1211 vdisk_exec_mode_sense(cmd);
1214 case MODE_SELECT_10:
1215 vdisk_exec_mode_select(cmd);
1219 vdisk_exec_log(cmd);
1221 case ALLOW_MEDIUM_REMOVAL:
1222 vdisk_exec_prevent_allow_medium_removal(cmd);
1225 vdisk_exec_read_toc(cmd);
1228 vdisk_fsync(thr, 0, virt_dev->file_size, cmd, dev);
1234 case TEST_UNIT_READY:
1237 vdisk_exec_inquiry(cmd);
1240 vdisk_exec_request_sense(cmd);
1243 vdisk_exec_read_capacity(cmd);
1245 case SERVICE_ACTION_IN:
1246 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
1247 vdisk_exec_read_capacity16(cmd);
1250 /* else go through */
1253 TRACE_DBG("Invalid opcode %d", opcode);
1254 scst_set_cmd_error(cmd,
1255 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1262 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1265 if (likely(thr != NULL))
1266 scst_thr_data_put(&thr->hdr);
1268 res = SCST_EXEC_COMPLETED;
1270 TRACE_EXIT_RES(res);
1274 static int vdisk_get_block_shift(struct scst_cmd *cmd)
1276 struct scst_vdisk_dev *virt_dev =
1277 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1278 return virt_dev->block_shift;
1281 /********************************************************************
1282 * Function: vdisk_parse
1286 * Returns : The state of the command
1288 * Description: This does the parsing of the command
1290 * Note: Not all states are allowed on return
1291 ********************************************************************/
1292 static int vdisk_parse(struct scst_cmd *cmd)
1294 scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
1295 return SCST_CMD_STATE_DEFAULT;
1298 /********************************************************************
1299 * Function: vcdrom_parse
1303 * Returns : The state of the command
1305 * Description: This does the parsing of the command
1307 * Note: Not all states are allowed on return
1308 ********************************************************************/
1309 static int vcdrom_parse(struct scst_cmd *cmd)
1311 scst_cdrom_generic_parse(cmd, vdisk_get_block_shift);
1312 return SCST_CMD_STATE_DEFAULT;
1315 /********************************************************************
1316 * Function: vcdrom_exec
1323 ********************************************************************/
1324 static int vcdrom_exec(struct scst_cmd *cmd)
1326 int res = SCST_EXEC_COMPLETED;
1327 int opcode = cmd->cdb[0];
1328 struct scst_vdisk_dev *virt_dev =
1329 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1334 cmd->msg_status = 0;
1335 cmd->host_status = DID_OK;
1336 cmd->driver_status = 0;
1338 if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1339 TRACE_DBG("%s", "CDROM empty");
1340 scst_set_cmd_error(cmd,
1341 SCST_LOAD_SENSE(scst_sense_not_ready));
1345 if (virt_dev->media_changed && scst_is_ua_command(cmd)) {
1346 spin_lock(&virt_dev->flags_lock);
1347 if (virt_dev->media_changed) {
1348 virt_dev->media_changed = 0;
1349 TRACE_DBG("%s", "Reporting media changed");
1350 scst_set_cmd_error(cmd,
1351 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1352 spin_unlock(&virt_dev->flags_lock);
1355 spin_unlock(&virt_dev->flags_lock);
1358 res = vdisk_do_job(cmd);
1361 TRACE_EXIT_RES(res);
1365 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1369 static uint64_t vdisk_gen_dev_id_num(struct scst_vdisk_dev *virt_dev)
1371 unsigned int dev_id_num, i;
1373 for (dev_id_num = 0, i = 0; i < strlen(virt_dev->name); i++) {
1374 unsigned int rv = random_values[(int)(virt_dev->name[i])];
1375 /* Do some rotating of the bits */
1376 dev_id_num ^= ((rv << i) | (rv >> (32 - i)));
1379 return ((uint64_t)scst_vdisk_ID << 32) | dev_id_num;
1382 static void vdisk_exec_inquiry(struct scst_cmd *cmd)
1384 int32_t length, i, resp_len = 0;
1387 struct scst_vdisk_dev *virt_dev =
1388 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1390 /* ToDo: Performance Boost:
1391 * 1. remove kzalloc, buf
1392 * 2. do all checks before touching *address
1394 * 4. write directly to *address
1399 buf = kzalloc(INQ_BUF_SZ,
1400 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1406 length = scst_get_buf_first(cmd, &address);
1407 TRACE_DBG("length %d", length);
1408 if (unlikely(length <= 0)) {
1410 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1411 scst_set_cmd_error(cmd,
1412 SCST_LOAD_SENSE(scst_sense_hardw_error));
1417 if (cmd->cdb[1] & CMDDT) {
1418 TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported");
1419 scst_set_cmd_error(cmd,
1420 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1424 buf[0] = cmd->dev->type; /* type dev */
1425 if (virt_dev->removable)
1426 buf[1] = 0x80; /* removable */
1428 if (cmd->cdb[1] & EVPD) {
1429 uint64_t dev_id_num;
1431 char dev_id_str[17];
1433 dev_id_num = vdisk_gen_dev_id_num(virt_dev);
1434 dev_id_len = scnprintf(dev_id_str, sizeof(dev_id_str), "%llx",
1436 TRACE_DBG("dev_id num %lld, str %s, len %d", dev_id_num,
1437 dev_id_str, dev_id_len);
1438 if (0 == cmd->cdb[2]) {
1439 /* supported vital product data pages */
1441 buf[4] = 0x0; /* this page */
1442 buf[5] = 0x80; /* unit serial number */
1443 buf[6] = 0x83; /* device identification */
1444 resp_len = buf[3] + 4;
1445 } else if (0x80 == cmd->cdb[2]) {
1446 /* unit serial number */
1447 int usn_len = strlen(virt_dev->usn);
1450 strncpy(&buf[4], virt_dev->usn, usn_len);
1451 resp_len = buf[3] + 4;
1452 } else if (0x83 == cmd->cdb[2]) {
1453 /* device identification */
1457 /* T10 vendor identifier field format (faked) */
1458 buf[num + 0] = 0x2; /* ASCII */
1459 buf[num + 1] = 0x1; /* Vendor ID */
1460 if (virt_dev->blockio)
1461 memcpy(&buf[num + 4], SCST_BIO_VENDOR, 8);
1463 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1465 i = strlen(virt_dev->name) + 1; /* for ' ' */
1466 memset(&buf[num + 12], ' ', i + dev_id_len);
1467 memcpy(&buf[num + 12], virt_dev->name, i-1);
1468 memcpy(&buf[num + 12 + i], dev_id_str, dev_id_len);
1469 buf[num + 3] = 8 + i + dev_id_len;
1470 num += buf[num + 3];
1472 #if 0 /* This isn't required and can be misleading, so let's disable it */
1475 /* NAA IEEE registered identifier (faked) */
1476 buf[num] = 0x1; /* binary */
1480 buf[num + 4] = 0x51; /* IEEE OUI=0x123456 (faked) */
1481 buf[num + 5] = 0x23;
1482 buf[num + 6] = 0x45;
1483 buf[num + 7] = 0x60;
1484 buf[num + 8] = (dev_id_num >> 24);
1485 buf[num + 9] = (dev_id_num >> 16) & 0xff;
1486 buf[num + 10] = (dev_id_num >> 8) & 0xff;
1487 buf[num + 11] = dev_id_num & 0xff;
1492 buf[2] = (resp_len >> 8) & 0xFF;
1493 buf[3] = resp_len & 0xFF;
1496 TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1498 scst_set_cmd_error(cmd,
1499 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1505 if (cmd->cdb[2] != 0) {
1506 TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1507 scst_set_cmd_error(cmd,
1508 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1512 buf[2] = 5; /* Device complies to SPC-3 */
1513 buf[3] = 0x12; /* HiSup + data in format specified in SPC */
1514 buf[4] = 31;/* n - 4 = 35 - 4 = 31 for full 36 byte data */
1515 buf[6] = 1; /* MultiP 1 */
1516 buf[7] = 2; /* CMDQUE 1, BQue 0 => commands queuing supported */
1519 * 8 byte ASCII Vendor Identification of the target
1522 if (virt_dev->blockio)
1523 memcpy(&buf[8], SCST_BIO_VENDOR, 8);
1525 memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1528 * 16 byte ASCII Product Identification of the target - left
1531 memset(&buf[16], ' ', 16);
1532 len = min(strlen(virt_dev->name), (size_t)16);
1533 memcpy(&buf[16], virt_dev->name, len);
1536 * 4 byte ASCII Product Revision Level of the target - left
1539 memcpy(&buf[32], SCST_FIO_REV, 4);
1540 resp_len = buf[4] + 5;
1543 sBUG_ON(resp_len >= INQ_BUF_SZ);
1544 if (length > resp_len)
1546 memcpy(address, buf, length);
1549 scst_put_buf(cmd, address);
1550 if (length < cmd->resp_data_len)
1551 scst_set_resp_data_len(cmd, length);
1561 static void vdisk_exec_request_sense(struct scst_cmd *cmd)
1565 uint8_t b[SCST_STANDARD_SENSE_LEN];
1569 sl = scst_set_sense(b, sizeof(b), cmd->dev->d_sense,
1570 SCST_LOAD_SENSE(scst_sense_no_sense));
1572 length = scst_get_buf_first(cmd, &address);
1573 TRACE_DBG("length %d", length);
1575 PRINT_ERROR("scst_get_buf_first() failed: %d)", length);
1576 scst_set_cmd_error(cmd,
1577 SCST_LOAD_SENSE(scst_sense_hardw_error));
1581 length = min(sl, length);
1582 memcpy(address, b, length);
1583 scst_set_resp_data_len(cmd, length);
1585 scst_put_buf(cmd, address);
1593 * <<Following mode pages info copied from ST318451LW with some corrections>>
1597 static int vdisk_err_recov_pg(unsigned char *p, int pcontrol,
1598 struct scst_vdisk_dev *virt_dev)
1599 { /* Read-Write Error Recovery page for mode_sense */
1600 const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1603 memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1605 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1606 return sizeof(err_recov_pg);
1609 static int vdisk_disconnect_pg(unsigned char *p, int pcontrol,
1610 struct scst_vdisk_dev *virt_dev)
1611 { /* Disconnect-Reconnect page for mode_sense */
1612 const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1613 0, 0, 0, 0, 0, 0, 0, 0};
1615 memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1617 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1618 return sizeof(disconnect_pg);
1621 static int vdisk_rigid_geo_pg(unsigned char *p, int pcontrol,
1622 struct scst_vdisk_dev *virt_dev)
1624 unsigned char geo_m_pg[] = {0x04, 0x16, 0, 0, 0, DEF_HEADS, 0, 0,
1625 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1626 0x3a, 0x98/* 15K RPM */, 0, 0};
1627 int32_t ncyl, n, rem;
1630 memcpy(p, geo_m_pg, sizeof(geo_m_pg));
1632 * Divide virt_dev->nblocks by (DEF_HEADS * DEF_SECTORS) and store
1633 * the quotient in ncyl and the remainder in rem.
1635 dividend = virt_dev->nblocks;
1636 rem = do_div(dividend, DEF_HEADS * DEF_SECTORS);
1640 memcpy(&n, p + 2, sizeof(u32));
1641 n = n | (cpu_to_be32(ncyl) >> 8);
1642 memcpy(p + 2, &n, sizeof(u32));
1644 memset(p + 2, 0, sizeof(geo_m_pg) - 2);
1645 return sizeof(geo_m_pg);
1648 static int vdisk_format_pg(unsigned char *p, int pcontrol,
1649 struct scst_vdisk_dev *virt_dev)
1650 { /* Format device page for mode_sense */
1651 const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1652 0, 0, 0, 0, 0, 0, 0, 0,
1653 0, 0, 0, 0, 0x40, 0, 0, 0};
1655 memcpy(p, format_pg, sizeof(format_pg));
1656 p[10] = (DEF_SECTORS >> 8) & 0xff;
1657 p[11] = DEF_SECTORS & 0xff;
1658 p[12] = (virt_dev->block_size >> 8) & 0xff;
1659 p[13] = virt_dev->block_size & 0xff;
1661 memset(p + 2, 0, sizeof(format_pg) - 2);
1662 return sizeof(format_pg);
1665 static int vdisk_caching_pg(unsigned char *p, int pcontrol,
1666 struct scst_vdisk_dev *virt_dev)
1667 { /* Caching page for mode_sense */
1668 const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1669 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1671 memcpy(p, caching_pg, sizeof(caching_pg));
1672 p[2] |= !(virt_dev->wt_flag || virt_dev->nv_cache) ? WCE : 0;
1674 memset(p + 2, 0, sizeof(caching_pg) - 2);
1675 return sizeof(caching_pg);
1678 static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol,
1679 struct scst_vdisk_dev *virt_dev)
1680 { /* Control mode page for mode_sense */
1681 const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0, 0, 0, 0, 0, 0,
1684 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1687 p[2] |= virt_dev->dev->tst << 5;
1688 p[2] |= virt_dev->dev->d_sense << 2;
1689 p[3] |= virt_dev->dev->queue_alg << 4;
1690 p[4] |= virt_dev->dev->swp << 3;
1691 p[5] |= virt_dev->dev->tas << 6;
1694 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1696 * It's too early to implement it, since we can't control the
1697 * backstorage device parameters. ToDo
1699 p[2] |= 7 << 5; /* TST */
1700 p[3] |= 0xF << 4; /* QUEUE ALGORITHM MODIFIER */
1702 p[2] |= 1 << 2; /* D_SENSE */
1703 p[4] |= 1 << 3; /* SWP */
1704 p[5] |= 1 << 6; /* TAS */
1707 p[2] |= DEF_TST << 5;
1708 p[2] |= DEF_DSENSE << 2;
1709 if (virt_dev->wt_flag || virt_dev->nv_cache)
1710 p[3] |= DEF_QUEUE_ALG_WT << 4;
1712 p[3] |= DEF_QUEUE_ALG << 4;
1713 p[4] |= DEF_SWP << 3;
1714 p[5] |= DEF_TAS << 6;
1719 return sizeof(ctrl_m_pg);
1722 static int vdisk_iec_m_pg(unsigned char *p, int pcontrol,
1723 struct scst_vdisk_dev *virt_dev)
1724 { /* Informational Exceptions control mode page for mode_sense */
1725 const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1727 memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1729 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1730 return sizeof(iec_m_pg);
1733 static void vdisk_exec_mode_sense(struct scst_cmd *cmd)
1738 struct scst_vdisk_dev *virt_dev;
1741 unsigned char dbd, type;
1742 int pcontrol, pcode, subpcode;
1743 unsigned char dev_spec;
1744 int msense_6, offset = 0, len;
1749 buf = kzalloc(MSENSE_BUF_SZ,
1750 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1756 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1757 blocksize = virt_dev->block_size;
1758 nblocks = virt_dev->nblocks;
1760 type = cmd->dev->type; /* type dev */
1761 dbd = cmd->cdb[1] & DBD;
1762 pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1763 pcode = cmd->cdb[2] & 0x3f;
1764 subpcode = cmd->cdb[3];
1765 msense_6 = (MODE_SENSE == cmd->cdb[0]);
1766 dev_spec = (virt_dev->dev->rd_only ? WP : 0) | DPOFUA;
1768 length = scst_get_buf_first(cmd, &address);
1769 if (unlikely(length <= 0)) {
1771 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1772 scst_set_cmd_error(cmd,
1773 SCST_LOAD_SENSE(scst_sense_hardw_error));
1778 if (0x3 == pcontrol) {
1779 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1780 scst_set_cmd_error(cmd,
1781 SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1795 if (0 != subpcode) {
1796 /* TODO: Control Extension page */
1797 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1798 scst_set_cmd_error(cmd,
1799 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1804 /* Create block descriptor */
1805 buf[offset - 1] = 0x08; /* block descriptor length */
1806 if (nblocks >> 32) {
1807 buf[offset + 0] = 0xFF;
1808 buf[offset + 1] = 0xFF;
1809 buf[offset + 2] = 0xFF;
1810 buf[offset + 3] = 0xFF;
1813 buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;
1814 buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1815 buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1816 buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1818 buf[offset + 4] = 0; /* density code */
1819 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1820 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1821 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1823 offset += 8; /* increment offset */
1829 case 0x1: /* Read-Write error recovery page, direct access */
1830 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1832 case 0x2: /* Disconnect-Reconnect page, all devices */
1833 len = vdisk_disconnect_pg(bp, pcontrol, virt_dev);
1835 case 0x3: /* Format device page, direct access */
1836 len = vdisk_format_pg(bp, pcontrol, virt_dev);
1838 case 0x4: /* Rigid disk geometry */
1839 len = vdisk_rigid_geo_pg(bp, pcontrol, virt_dev);
1841 case 0x8: /* Caching page, direct access */
1842 len = vdisk_caching_pg(bp, pcontrol, virt_dev);
1844 case 0xa: /* Control Mode page, all devices */
1845 len = vdisk_ctrl_m_pg(bp, pcontrol, virt_dev);
1847 case 0x1c: /* Informational Exceptions Mode page, all devices */
1848 len = vdisk_iec_m_pg(bp, pcontrol, virt_dev);
1850 case 0x3f: /* Read all Mode pages */
1851 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1852 len += vdisk_disconnect_pg(bp + len, pcontrol, virt_dev);
1853 len += vdisk_format_pg(bp + len, pcontrol, virt_dev);
1854 len += vdisk_caching_pg(bp + len, pcontrol, virt_dev);
1855 len += vdisk_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1856 len += vdisk_iec_m_pg(bp + len, pcontrol, virt_dev);
1857 len += vdisk_rigid_geo_pg(bp + len, pcontrol, virt_dev);
1860 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1861 scst_set_cmd_error(cmd,
1862 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1869 buf[0] = offset - 1;
1871 buf[0] = ((offset - 2) >> 8) & 0xff;
1872 buf[1] = (offset - 2) & 0xff;
1875 if (offset > length)
1877 memcpy(address, buf, offset);
1880 scst_put_buf(cmd, address);
1881 if (offset < cmd->resp_data_len)
1882 scst_set_resp_data_len(cmd, offset);
1892 static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt)
1898 if ((virt_dev->wt_flag == wt) || virt_dev->nullio || virt_dev->nv_cache)
1901 spin_lock(&virt_dev->flags_lock);
1902 virt_dev->wt_flag = wt;
1903 spin_unlock(&virt_dev->flags_lock);
1905 scst_dev_del_all_thr_data(virt_dev->dev);
1908 TRACE_EXIT_RES(res);
1912 static void vdisk_ctrl_m_pg_select(unsigned char *p,
1913 struct scst_vdisk_dev *virt_dev)
1915 struct scst_device *dev = virt_dev->dev;
1916 int old_swp = dev->swp, old_tas = dev->tas, old_dsense = dev->d_sense;
1919 /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */
1920 dev->tst = p[2] >> 5;
1921 dev->queue_alg = p[3] >> 4;
1923 dev->swp = (p[4] & 0x8) >> 3;
1924 dev->tas = (p[5] & 0x40) >> 6;
1925 dev->d_sense = (p[2] & 0x4) >> 2;
1927 PRINT_INFO("Device %s: new control mode page parameters: SWP %x "
1928 "(was %x), TAS %x (was %x), D_SENSE %d (was %d)",
1929 virt_dev->name, dev->swp, old_swp, dev->tas, old_tas,
1930 dev->d_sense, old_dsense);
1934 static void vdisk_exec_mode_select(struct scst_cmd *cmd)
1938 struct scst_vdisk_dev *virt_dev;
1939 int mselect_6, offset;
1943 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1944 mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1946 length = scst_get_buf_first(cmd, &address);
1947 if (unlikely(length <= 0)) {
1949 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1950 scst_set_cmd_error(cmd,
1951 SCST_LOAD_SENSE(scst_sense_hardw_error));
1956 if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1957 TRACE(TRACE_MINOR|TRACE_SCSI, "MODE SELECT: Unsupported "
1958 "value(s) of PF and/or SP bits (cdb[1]=%x)",
1960 scst_set_cmd_error(cmd,
1961 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1970 if (address[offset - 1] == 8) {
1972 } else if (address[offset - 1] != 0) {
1973 PRINT_ERROR("%s", "MODE SELECT: Wrong parameters list "
1975 scst_set_cmd_error(cmd,
1976 SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1980 while (length > offset + 2) {
1981 if (address[offset] & PS) {
1982 PRINT_ERROR("%s", "MODE SELECT: Illegal PS bit");
1983 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1984 scst_sense_invalid_field_in_parm_list));
1987 if ((address[offset] & 0x3f) == 0x8) {
1989 if (address[offset + 1] != 18) {
1990 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1991 "caching page request");
1992 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1993 scst_sense_invalid_field_in_parm_list));
1996 if (vdisk_set_wt(virt_dev,
1997 (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1998 scst_set_cmd_error(cmd,
1999 SCST_LOAD_SENSE(scst_sense_hardw_error));
2003 } else if ((address[offset] & 0x3f) == 0xA) {
2005 if (address[offset + 1] != 0xA) {
2006 PRINT_ERROR("%s", "MODE SELECT: Invalid "
2007 "control page request");
2008 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
2009 scst_sense_invalid_field_in_parm_list));
2012 vdisk_ctrl_m_pg_select(&address[offset], virt_dev);
2014 PRINT_ERROR("MODE SELECT: Invalid request %x",
2015 address[offset] & 0x3f);
2016 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
2017 scst_sense_invalid_field_in_parm_list));
2020 offset += address[offset + 1];
2024 scst_put_buf(cmd, address);
2031 static void vdisk_exec_log(struct scst_cmd *cmd)
2035 /* No log pages are supported */
2036 scst_set_cmd_error(cmd,
2037 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2043 static void vdisk_exec_read_capacity(struct scst_cmd *cmd)
2047 struct scst_vdisk_dev *virt_dev;
2050 uint8_t buffer[READ_CAP_LEN];
2054 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2055 blocksize = virt_dev->block_size;
2056 nblocks = virt_dev->nblocks;
2058 /* last block on the virt_dev is (nblocks-1) */
2059 memset(buffer, 0, sizeof(buffer));
2060 if (nblocks >> 32) {
2066 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
2067 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
2068 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
2069 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
2071 buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
2072 buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
2073 buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
2074 buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
2076 length = scst_get_buf_first(cmd, &address);
2077 if (unlikely(length <= 0)) {
2079 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2080 scst_set_cmd_error(cmd,
2081 SCST_LOAD_SENSE(scst_sense_hardw_error));
2086 if (length > READ_CAP_LEN)
2087 length = READ_CAP_LEN;
2088 memcpy(address, buffer, length);
2090 scst_put_buf(cmd, address);
2092 if (length < cmd->resp_data_len)
2093 scst_set_resp_data_len(cmd, length);
2100 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd)
2104 struct scst_vdisk_dev *virt_dev;
2107 uint8_t buffer[READ_CAP16_LEN];
2111 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2112 blocksize = virt_dev->block_size;
2113 nblocks = virt_dev->nblocks - 1;
2115 memset(buffer, 0, sizeof(buffer));
2117 buffer[0] = nblocks >> 56;
2118 buffer[1] = (nblocks >> 48) & 0xFF;
2119 buffer[2] = (nblocks >> 40) & 0xFF;
2120 buffer[3] = (nblocks >> 32) & 0xFF;
2121 buffer[4] = (nblocks >> 24) & 0xFF;
2122 buffer[5] = (nblocks >> 16) & 0xFF;
2123 buffer[6] = (nblocks >> 8) & 0xFF;
2124 buffer[7] = nblocks & 0xFF;
2126 buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
2127 buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
2128 buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
2129 buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
2131 switch (blocksize) {
2142 PRINT_ERROR("%s: Unexpected block size %d",
2143 cmd->op_name, blocksize);
2150 length = scst_get_buf_first(cmd, &address);
2151 if (unlikely(length <= 0)) {
2153 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2154 scst_set_cmd_error(cmd,
2155 SCST_LOAD_SENSE(scst_sense_hardw_error));
2161 * Some versions of Windows have a bug, which makes them consider
2162 * response of READ CAPACITY(16) longer than 12 bytes as a faulty one.
2163 * As the result, such Windows'es refuse to see SCST exported
2164 * devices >2TB in size. This is fixed by MS in latter Windows
2165 * versions, probably, by some hotfix.
2167 * But if you're using such buggy Windows and experience this problem,
2168 * change this '1' to '0'.
2171 if (length > READ_CAP16_LEN)
2172 length = READ_CAP16_LEN;
2177 memcpy(address, buffer, length);
2179 scst_put_buf(cmd, address);
2181 if (length < cmd->resp_data_len)
2182 scst_set_resp_data_len(cmd, length);
2189 static void vdisk_exec_read_toc(struct scst_cmd *cmd)
2191 int32_t length, off = 0;
2193 struct scst_vdisk_dev *virt_dev;
2195 uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
2196 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
2200 if (cmd->dev->type != TYPE_ROM) {
2201 PRINT_ERROR("%s", "READ TOC for non-CDROM device");
2202 scst_set_cmd_error(cmd,
2203 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
2207 if (cmd->cdb[2] & 0x0e/*Format*/) {
2208 PRINT_ERROR("%s", "READ TOC: invalid requested data format");
2209 scst_set_cmd_error(cmd,
2210 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2214 if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
2215 (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
2216 PRINT_ERROR("READ TOC: invalid requested track number %x",
2218 scst_set_cmd_error(cmd,
2219 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
2223 length = scst_get_buf_first(cmd, &address);
2224 if (unlikely(length <= 0)) {
2226 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
2227 scst_set_cmd_error(cmd,
2228 SCST_LOAD_SENSE(scst_sense_hardw_error));
2233 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2234 /* ToDo when you have > 8TB ROM device. */
2235 nblocks = (uint32_t)virt_dev->nblocks;
2238 memset(buffer, 0, sizeof(buffer));
2239 buffer[2] = 0x01; /* First Track/Session */
2240 buffer[3] = 0x01; /* Last Track/Session */
2242 if (cmd->cdb[6] <= 1) {
2243 /* Fistr TOC Track Descriptor */
2244 /* ADDR 0x10 - Q Sub-channel encodes current position data
2245 CONTROL 0x04 - Data track, recoreded uninterrupted */
2246 buffer[off+1] = 0x14;
2248 buffer[off+2] = 0x01;
2251 if (!(cmd->cdb[2] & 0x01)) {
2252 /* Lead-out area TOC Track Descriptor */
2253 buffer[off+1] = 0x14;
2255 buffer[off+2] = 0xAA;
2256 /* Track Start Address */
2257 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF;
2258 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
2259 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
2260 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
2264 buffer[1] = off - 2; /* Data Length */
2268 memcpy(address, buffer, off);
2270 scst_put_buf(cmd, address);
2272 if (off < cmd->resp_data_len)
2273 scst_set_resp_data_len(cmd, off);
2280 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
2282 struct scst_vdisk_dev *virt_dev =
2283 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2285 TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
2287 if (cmd->dev->type == TYPE_ROM) {
2288 spin_lock(&virt_dev->flags_lock);
2289 virt_dev->prevent_allow_medium_removal =
2290 cmd->cdb[4] & 0x01 ? 1 : 0;
2291 spin_unlock(&virt_dev->flags_lock);
2297 static int vdisk_fsync(struct scst_vdisk_thr *thr, loff_t loff,
2298 loff_t len, struct scst_cmd *cmd, struct scst_device *dev)
2301 struct scst_vdisk_dev *virt_dev =
2302 (struct scst_vdisk_dev *)dev->dh_priv;
2303 struct file *file = thr->fd;
2304 struct inode *inode;
2305 struct address_space *mapping;
2309 /* Hopefully, the compiler will generate the single comparison */
2310 if (virt_dev->nv_cache || virt_dev->blockio || virt_dev->wt_flag ||
2311 virt_dev->o_direct_flag || virt_dev->nullio)
2314 inode = file->f_dentry->d_inode;
2315 mapping = file->f_mapping;
2317 res = sync_page_range(inode, mapping, loff, len);
2318 if (unlikely(res != 0)) {
2319 PRINT_ERROR("sync_page_range() failed (%d)", res);
2321 scst_set_cmd_error(cmd,
2322 SCST_LOAD_SENSE(scst_sense_write_error));
2326 /* ToDo: flush the device cache, if needed */
2329 TRACE_EXIT_RES(res);
2333 static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd,
2334 struct scst_vdisk_thr *thr)
2338 iv_count = scst_get_buf_count(cmd);
2339 if (iv_count > thr->iv_count) {
2341 /* It can't be called in atomic context */
2342 thr->iv = kmalloc(sizeof(*thr->iv) * iv_count, GFP_KERNEL);
2343 if (thr->iv == NULL) {
2344 PRINT_ERROR("Unable to allocate iv (%d)", iv_count);
2348 thr->iv_count = iv_count;
2356 * copied from <ksrc>/fs/read_write.*
2358 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
2359 static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
2361 set_current_state(TASK_UNINTERRUPTIBLE);
2362 if (!kiocbIsKicked(iocb))
2365 kiocbClearKicked(iocb);
2366 __set_current_state(TASK_RUNNING);
2369 typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
2370 unsigned long, loff_t);
2372 static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
2373 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
2378 init_sync_kiocb(&kiocb, filp);
2379 kiocb.ki_pos = *ppos;
2380 kiocb.ki_left = len;
2381 kiocb.ki_nbytes = len;
2384 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
2385 if (ret != -EIOCBRETRY)
2387 wait_on_retry_sync_kiocb(&kiocb);
2390 if (ret == -EIOCBQUEUED)
2391 ret = wait_on_sync_kiocb(&kiocb);
2392 *ppos = kiocb.ki_pos;
2397 static void vdisk_exec_read(struct scst_cmd *cmd,
2398 struct scst_vdisk_thr *thr, loff_t loff)
2400 mm_segment_t old_fs;
2402 ssize_t length, full_len;
2403 uint8_t __user *address;
2404 struct scst_vdisk_dev *virt_dev =
2405 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2406 struct file *fd = thr->fd;
2412 if (virt_dev->nullio)
2415 iv = vdisk_alloc_iv(cmd, thr);
2422 length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2423 while (length > 0) {
2427 iv[i].iov_base = address;
2428 iv[i].iov_len = length;
2429 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2431 if (unlikely(length < 0)) {
2432 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2433 scst_set_cmd_error(cmd,
2434 SCST_LOAD_SENSE(scst_sense_hardw_error));
2441 TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
2443 if (fd->f_op->llseek)
2444 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2446 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2448 PRINT_ERROR("lseek trouble %lld != %lld",
2449 (long long unsigned int)err,
2450 (long long unsigned int)loff);
2451 scst_set_cmd_error(cmd,
2452 SCST_LOAD_SENSE(scst_sense_hardw_error));
2457 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2458 err = fd->f_op->readv(fd, iv, iv_count, &fd->f_pos);
2460 err = do_sync_readv_writev(fd, iv, iv_count, full_len,
2461 &fd->f_pos, fd->f_op->aio_read);
2464 if ((err < 0) || (err < full_len)) {
2465 PRINT_ERROR("readv() returned %lld from %zd",
2466 (long long unsigned int)err,
2471 scst_set_cmd_error(cmd,
2472 SCST_LOAD_SENSE(scst_sense_read_error));
2482 scst_put_buf(cmd, (void __force *)(iv[i].iov_base));
2489 static void vdisk_exec_write(struct scst_cmd *cmd,
2490 struct scst_vdisk_thr *thr, loff_t loff)
2492 mm_segment_t old_fs;
2494 ssize_t length, full_len;
2495 uint8_t __user *address;
2496 struct scst_vdisk_dev *virt_dev =
2497 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2498 struct file *fd = thr->fd;
2499 struct iovec *iv, *eiv;
2500 int iv_count, eiv_count;
2504 if (virt_dev->nullio)
2507 iv = vdisk_alloc_iv(cmd, thr);
2513 length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2514 while (length > 0) {
2516 iv[iv_count].iov_base = address;
2517 iv[iv_count].iov_len = length;
2519 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2521 if (unlikely(length < 0)) {
2522 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2523 scst_set_cmd_error(cmd,
2524 SCST_LOAD_SENSE(scst_sense_hardw_error));
2532 eiv_count = iv_count;
2534 TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2537 if (fd->f_op->llseek)
2538 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */);
2540 err = default_llseek(fd, loff, 0 /*SEEK_SET */);
2542 PRINT_ERROR("lseek trouble %lld != %lld",
2543 (long long unsigned int)err,
2544 (long long unsigned int)loff);
2545 scst_set_cmd_error(cmd,
2546 SCST_LOAD_SENSE(scst_sense_hardw_error));
2551 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2552 err = fd->f_op->writev(fd, eiv, eiv_count, &fd->f_pos);
2554 err = do_sync_readv_writev(fd, iv, iv_count, full_len, &fd->f_pos,
2555 fd->f_op->aio_write);
2559 PRINT_ERROR("write() returned %lld from %zd",
2560 (long long unsigned int)err,
2565 scst_set_cmd_error(cmd,
2566 SCST_LOAD_SENSE(scst_sense_write_error));
2569 } else if (err < full_len) {
2571 * Probably that's wrong, but sometimes write() returns
2572 * value less, than requested. Let's restart.
2574 int i, e = eiv_count;
2575 TRACE_MGMT_DBG("write() returned %d from %zd "
2576 "(iv_count=%d)", (int)err, full_len,
2579 PRINT_INFO("Suspicious: write() returned 0 from "
2580 "%zd (iv_count=%d)", full_len, eiv_count);
2583 for (i = 0; i < e; i++) {
2584 if ((long long)eiv->iov_len < err) {
2585 err -= eiv->iov_len;
2590 (uint8_t __force __user *)eiv->iov_base +
2592 eiv->iov_len -= err;
2603 while (iv_count > 0) {
2604 scst_put_buf(cmd, (void __force *)(iv[iv_count-1].iov_base));
2613 struct scst_blockio_work {
2614 atomic_t bios_inflight;
2615 struct scst_cmd *cmd;
2618 static inline void blockio_check_finish(struct scst_blockio_work *blockio_work)
2620 /* Decrement the bios in processing, and if zero signal completion */
2621 if (atomic_dec_and_test(&blockio_work->bios_inflight)) {
2622 blockio_work->cmd->completed = 1;
2623 blockio_work->cmd->scst_cmd_done(blockio_work->cmd,
2624 SCST_CMD_STATE_DEFAULT, scst_estimate_context());
2625 kmem_cache_free(blockio_work_cachep, blockio_work);
2630 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2631 static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
2633 static void blockio_endio(struct bio *bio, int error)
2636 struct scst_blockio_work *blockio_work = bio->bi_private;
2638 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2643 error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
2645 if (unlikely(error != 0)) {
2646 PRINT_ERROR("cmd %p returned error %d", blockio_work->cmd,
2649 * The race with other such bio's doesn't matter, since all
2650 * scst_set_cmd_error() calls do the same local to this cmd
2653 if (bio->bi_rw & WRITE)
2654 scst_set_cmd_error(blockio_work->cmd,
2655 SCST_LOAD_SENSE(scst_sense_write_error));
2657 scst_set_cmd_error(blockio_work->cmd,
2658 SCST_LOAD_SENSE(scst_sense_read_error));
2661 blockio_check_finish(blockio_work);
2664 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2671 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
2672 u64 lba_start, int write)
2674 struct scst_vdisk_dev *virt_dev =
2675 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2676 struct block_device *bdev = thr->bdev;
2677 struct request_queue *q = bdev_get_queue(bdev);
2678 int length, max_nr_vecs = 0;
2680 struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
2682 struct scst_blockio_work *blockio_work;
2687 if (virt_dev->nullio)
2690 /* Allocate and initialize blockio_work struct */
2691 blockio_work = kmem_cache_alloc(blockio_work_cachep, GFP_KERNEL);
2692 if (blockio_work == NULL)
2695 blockio_work->cmd = cmd;
2698 max_nr_vecs = min(bio_get_nr_vecs(bdev), BIO_MAX_PAGES);
2704 length = scst_get_buf_first(cmd, &address);
2705 while (length > 0) {
2706 int len, bytes, off, thislen;
2711 off = offset_in_page(addr);
2714 lba_start0 = lba_start;
2718 struct page *page = virt_to_page(addr);
2721 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
2722 bio = bio_kmalloc(GFP_KERNEL, max_nr_vecs);
2724 bio = bio_alloc(GFP_KERNEL, max_nr_vecs);
2727 PRINT_ERROR("Failed to create bio "
2728 "for data segment %d (cmd %p)",
2729 cmd->get_sg_buf_entry_num, cmd);
2735 bio->bi_end_io = blockio_endio;
2736 bio->bi_sector = lba_start0 <<
2737 (virt_dev->block_shift - 9);
2738 bio->bi_bdev = bdev;
2739 bio->bi_private = blockio_work;
2740 #if 0 /* It could be win, but could be not, so a performance study is needed */
2741 bio->bi_rw |= 1 << BIO_RW_SYNC;
2746 tbio = tbio->bi_next = bio;
2749 bytes = min_t(unsigned int, len, PAGE_SIZE - off);
2751 rc = bio_add_page(bio, page, bytes, off);
2755 lba_start0 += thislen >> virt_dev->block_shift;
2766 lba_start += length >> virt_dev->block_shift;
2768 scst_put_buf(cmd, address);
2769 length = scst_get_buf_next(cmd, &address);
2772 /* +1 to prevent erroneous too early command completion */
2773 atomic_set(&blockio_work->bios_inflight, bios+1);
2777 hbio = hbio->bi_next;
2778 bio->bi_next = NULL;
2779 submit_bio(write, bio);
2782 if (q && q->unplug_fn)
2785 blockio_check_finish(blockio_work);
2794 hbio = hbio->bi_next;
2797 kmem_cache_free(blockio_work_cachep, blockio_work);
2804 static void vdisk_exec_verify(struct scst_cmd *cmd,
2805 struct scst_vdisk_thr *thr, loff_t loff)
2807 mm_segment_t old_fs;
2809 ssize_t length, len_mem = 0;
2810 uint8_t *address_sav, *address;
2812 struct scst_vdisk_dev *virt_dev =
2813 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2814 struct file *fd = thr->fd;
2815 uint8_t *mem_verify = NULL;
2819 if (vdisk_fsync(thr, loff, cmd->bufflen, cmd, cmd->dev) != 0)
2823 * Until the cache is cleared prior the verifying, there is not
2824 * much point in this code. ToDo.
2826 * Nevertherless, this code is valuable if the data have not read
2827 * from the file/disk yet.
2834 if (!virt_dev->nullio) {
2835 if (fd->f_op->llseek)
2836 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2838 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2840 PRINT_ERROR("lseek trouble %lld != %lld",
2841 (long long unsigned int)err,
2842 (long long unsigned int)loff);
2843 scst_set_cmd_error(cmd,
2844 SCST_LOAD_SENSE(scst_sense_hardw_error));
2849 mem_verify = vmalloc(LEN_MEM);
2850 if (mem_verify == NULL) {
2851 PRINT_ERROR("Unable to allocate memory %d for verify",
2853 scst_set_cmd_error(cmd,
2854 SCST_LOAD_SENSE(scst_sense_hardw_error));
2858 length = scst_get_buf_first(cmd, &address);
2859 address_sav = address;
2860 if (!length && cmd->data_len) {
2861 length = cmd->data_len;
2866 while (length > 0) {
2867 len_mem = (length > LEN_MEM) ? LEN_MEM : length;
2868 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2870 if (!virt_dev->nullio)
2871 err = fd->f_op->read(fd,
2872 (char __force __user *)mem_verify, len_mem,
2876 if ((err < 0) || (err < len_mem)) {
2877 PRINT_ERROR("verify() returned %lld from %zd",
2878 (long long unsigned int)err, len_mem);
2882 scst_set_cmd_error(cmd,
2883 SCST_LOAD_SENSE(scst_sense_read_error));
2886 scst_put_buf(cmd, address_sav);
2889 if (compare && memcmp(address, mem_verify, len_mem) != 0) {
2890 TRACE_DBG("Verify: error memcmp length %zd", length);
2891 scst_set_cmd_error(cmd,
2892 SCST_LOAD_SENSE(scst_sense_miscompare_error));
2893 scst_put_buf(cmd, address_sav);
2898 if (compare && length <= 0) {
2899 scst_put_buf(cmd, address_sav);
2900 length = scst_get_buf_next(cmd, &address);
2901 address_sav = address;
2906 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2907 scst_set_cmd_error(cmd,
2908 SCST_LOAD_SENSE(scst_sense_hardw_error));
2921 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2922 struct scst_tgt_dev *tgt_dev)
2926 if ((mcmd->fn == SCST_LUN_RESET) || (mcmd->fn == SCST_TARGET_RESET)) {
2927 /* Restore default values */
2928 struct scst_device *dev = tgt_dev->dev;
2929 struct scst_vdisk_dev *virt_dev =
2930 (struct scst_vdisk_dev *)dev->dh_priv;
2933 dev->d_sense = DEF_DSENSE;
2934 if (virt_dev->wt_flag && !virt_dev->nv_cache)
2935 dev->queue_alg = DEF_QUEUE_ALG_WT;
2937 dev->queue_alg = DEF_QUEUE_ALG;
2941 virt_dev->prevent_allow_medium_removal = 0;
2945 return SCST_DEV_TM_NOT_COMPLETED;
2948 static void vdisk_report_registering(const struct scst_vdisk_dev *virt_dev)
2953 i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s ",
2954 virt_dev->vdt->vdt_name, virt_dev->name);
2957 if (virt_dev->wt_flag)
2958 i += snprintf(&buf[i], sizeof(buf) - i, "(WRITE_THROUGH");
2960 if (virt_dev->nv_cache)
2961 i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE",
2962 (j == i) ? "(" : ", ");
2964 if (virt_dev->rd_only)
2965 i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY",
2966 (j == i) ? "(" : ", ");
2968 if (virt_dev->o_direct_flag)
2969 i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT",
2970 (j == i) ? "(" : ", ");
2972 if (virt_dev->nullio)
2973 i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO",
2974 (j == i) ? "(" : ", ");
2976 if (virt_dev->blockio)
2977 i += snprintf(&buf[i], sizeof(buf) - i, "%sBLOCKIO",
2978 (j == i) ? "(" : ", ");
2980 if (virt_dev->removable)
2981 i += snprintf(&buf[i], sizeof(buf) - i, "%sREMOVABLE",
2982 (j == i) ? "(" : ", ");
2985 PRINT_INFO("%s", buf);
2987 PRINT_INFO("%s)", buf);
2992 /* scst_vdisk_mutex supposed to be held */
2993 static int __vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
2998 if (!virt_dev->nullio) {
2999 res = vdisk_get_file_size(virt_dev->file_name,
3000 virt_dev->blockio, &file_size);
3004 file_size = VDISK_NULLIO_SIZE;
3006 if (file_size == virt_dev->file_size) {
3007 PRINT_INFO("Size of virtual disk %s remained the same",
3012 res = scst_suspend_activity(true);
3016 virt_dev->file_size = file_size;
3017 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
3019 scst_dev_del_all_thr_data(virt_dev->dev);
3021 PRINT_INFO("New size of SCSI target virtual disk %s "
3022 "(fs=%lldMB, bs=%d, nblocks=%lld, cyln=%lld%s)",
3023 virt_dev->name, virt_dev->file_size >> 20,
3024 virt_dev->block_size,
3025 (long long unsigned int)virt_dev->nblocks,
3026 (long long unsigned int)virt_dev->nblocks/64/32,
3027 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
3030 scst_capacity_data_changed(virt_dev->dev);
3032 scst_resume_activity();
3038 /* scst_vdisk_mutex supposed to be held */
3039 static int vdisk_resync_size(struct vdev_type *vdt, char *p, const char *name)
3041 struct scst_vdisk_dev *virt_dev;
3044 virt_dev = vdt->vfns.vdev_find(name);
3045 if (virt_dev == NULL) {
3046 PRINT_ERROR("Device %s not found", name);
3051 res = __vdisk_resync_size(virt_dev);
3054 TRACE_EXIT_RES(res);
3058 static void vdev_init(struct vdev_type *vdt, struct scst_vdisk_dev *virt_dev)
3060 memset(virt_dev, 0, sizeof(*virt_dev));
3061 spin_lock_init(&virt_dev->flags_lock);
3062 virt_dev->vdt = vdt;
3064 virt_dev->block_size = DEF_DISK_BLOCKSIZE;
3065 virt_dev->block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
3070 static struct scst_vdisk_dev *vdev_create(struct vdev_type *vdt)
3072 struct scst_vdisk_dev *virt_dev;
3074 virt_dev = kmalloc(sizeof(*virt_dev), GFP_KERNEL);
3075 if (virt_dev == NULL) {
3076 PRINT_ERROR("Allocation of virtual device %s failed",
3081 vdt->vfns.vdev_init(vdt, virt_dev);
3087 static void vdev_deinit(struct scst_vdisk_dev *virt_dev)
3089 kfree(virt_dev->file_name);
3093 static void vdev_destroy(struct scst_vdisk_dev *virt_dev)
3095 virt_dev->vdt->vfns.vdev_deinit(virt_dev);
3100 static int vdisk_fileio_pre_register(struct scst_vdisk_dev *virt_dev)
3104 if ((virt_dev->file_name == NULL) ||
3105 (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0)) {
3106 PRINT_ERROR("%s", "File name required");
3111 if (virt_dev->rd_only && (virt_dev->wt_flag || virt_dev->nv_cache)) {
3112 PRINT_ERROR("Write options on read only device %s",
3122 static int vdisk_blockio_pre_register(struct scst_vdisk_dev *virt_dev)
3126 if ((virt_dev->file_name == NULL) ||
3127 (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0)) {
3128 PRINT_ERROR("%s", "File name required");
3137 static void vdisk_blockio_init(struct vdev_type *vdt,
3138 struct scst_vdisk_dev *virt_dev)
3140 struct vdisk_blockio_type *v;
3142 v = container_of(vdt, struct vdisk_blockio_type, parent_vdt);
3144 v->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3146 virt_dev->blockio = 1;
3150 static void vdisk_nullio_init(struct vdev_type *vdt,
3151 struct scst_vdisk_dev *virt_dev)
3153 struct vdisk_nullio_type *v;
3155 v = container_of(vdt, struct vdisk_nullio_type, parent_vdt);
3157 v->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3159 virt_dev->nullio = 1;
3163 static int vdisk_parse_option(struct scst_vdisk_dev *virt_dev, char *p)
3169 if (!strncmp("READ_ONLY", p, 9)) {
3171 virt_dev->rd_only = 1;
3172 TRACE_DBG("%s", "READ_ONLY");
3173 } else if (!strncmp("REMOVABLE", p, 9)) {
3175 virt_dev->removable = 1;
3176 TRACE_DBG("%s", "REMOVABLE");
3179 TRACE_EXIT_RES(res);
3183 static int vdisk_fileio_parse_option(struct scst_vdisk_dev *virt_dev, char *p)
3189 res = vdisk_parse_option(virt_dev, p);
3193 if (!strncmp("WRITE_THROUGH", p, 13)) {
3195 virt_dev->wt_flag = 1;
3196 TRACE_DBG("%s", "WRITE_THROUGH");
3197 } else if (!strncmp("NV_CACHE", p, 8)) {
3199 virt_dev->nv_cache = 1;
3200 TRACE_DBG("%s", "NON-VOLATILE CACHE");
3201 } else if (!strncmp("O_DIRECT", p, 8)) {
3204 virt_dev->o_direct_flag = 1;
3205 TRACE_DBG("%s", "O_DIRECT");
3207 PRINT_INFO("%s flag doesn't currently"
3208 " work, ignoring it, use fileio_tgt "
3209 "in O_DIRECT mode instead", "O_DIRECT");
3214 TRACE_EXIT_RES(res);
3218 /* scst_vdisk_mutex supposed to be held */
3219 static int vdev_open(struct vdev_type *vdt, char *p, const char *name)
3223 struct scst_vdisk_dev *virt_dev;
3228 virt_dev = vdt->vfns.vdev_find(name);
3229 if (virt_dev != NULL) {
3230 PRINT_ERROR("Virtual device with name %s already exist", name);
3235 while (isspace(*p) && *p != '\0')
3238 if ((*file_name == '/') || (strcmp(file_name, VDEV_NONE_FILENAME) == 0)) {
3239 while (!isspace(*p) && *p != '\0')
3243 TRACE_DBG("file name %s", file_name);
3245 while (isspace(*p) && *p != '\0')
3248 TRACE_DBG("file name %s", "not specified");
3252 virt_dev = vdt->vfns.vdev_create(vdt);
3253 if (virt_dev == NULL) {
3254 TRACE(TRACE_OUT_OF_MEM, "Creation of virt_dev %s failed", name);
3260 uint32_t block_size;
3264 block_size = simple_strtoul(p, &pp, 0);
3266 if ((*p != '\0') && !isspace(*p)) {
3267 PRINT_ERROR("Parse error: \"%s\"", p);
3271 while (isspace(*p) && *p != '\0')
3274 block_shift = scst_calc_block_shift(block_size);
3275 if (block_shift < 9) {
3280 TRACE_DBG("block_size %d, block_shift %d", block_size,
3283 virt_dev->block_size = block_size;
3284 virt_dev->block_shift = block_shift;
3287 while (*p != '\0') {
3288 while (isspace(*p) && *p != '\0')
3291 if (vdt->vfns.parse_option != NULL)
3292 res = vdt->vfns.parse_option(virt_dev, p);
3297 PRINT_ERROR("Unknown option \"%s\"", p);
3299 } else if (res == 0)
3304 if (!isspace(*p) && (*p != '\0')) {
3305 PRINT_ERROR("Syntax error on %s", p);
3310 strcpy(virt_dev->name, name);
3312 scnprintf(virt_dev->usn, sizeof(virt_dev->usn), "%llx",
3313 vdisk_gen_dev_id_num(virt_dev));
3314 TRACE_DBG("usn %s", virt_dev->usn);
3316 if (file_name != NULL) {
3317 len = strlen(file_name) + 1;
3318 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
3319 if (virt_dev->file_name == NULL) {
3320 TRACE(TRACE_OUT_OF_MEM, "Allocation of file_name %s "
3321 "failed", file_name);
3325 strncpy(virt_dev->file_name, file_name, len);
3328 if (vdt->vfns.pre_register != NULL) {
3329 res = vdt->vfns.pre_register(virt_dev);
3331 goto out_free_vpath;
3334 vdt->vfns.vdev_add(virt_dev);
3336 vdisk_report_registering(virt_dev);
3337 virt_dev->virt_id = scst_register_virtual_device(vdt->vdt_devt,
3339 if (virt_dev->virt_id < 0) {
3340 res = virt_dev->virt_id;
3344 TRACE_DBG("Added virt_dev (name %s, file name %s, id %d, block size "
3345 "%d) to vdisk_dev_list", virt_dev->name, virt_dev->file_name,
3346 virt_dev->virt_id, virt_dev->block_size);
3349 TRACE_EXIT_RES(res);
3353 vdt->vfns.vdev_del(virt_dev);
3356 kfree(virt_dev->file_name);
3363 /* scst_vdisk_mutex supposed to be held */
3364 static int vdev_close(struct vdev_type *vdt, const char *name)
3367 struct scst_vdisk_dev *virt_dev;
3371 virt_dev = vdt->vfns.vdev_find(name);
3372 if (virt_dev == NULL) {
3373 PRINT_ERROR("Device %s not found", name);
3378 scst_unregister_virtual_device(virt_dev->virt_id);
3380 PRINT_INFO("Virtual device %s unregistered", virt_dev->name);
3381 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3383 vdt->vfns.vdev_del(virt_dev);
3384 vdt->vfns.vdev_destroy(virt_dev);
3387 TRACE_EXIT_RES(res);
3391 /* scst_vdisk_mutex supposed to be held */
3392 static void vdev_del(struct scst_vdisk_dev *virt_dev)
3396 list_del(&virt_dev->vdisk_dev_list_entry);
3402 /* scst_vdisk_mutex supposed to be held */
3403 static void vdisk_add(struct scst_vdisk_dev *virt_dev)
3407 list_add_tail(&virt_dev->vdisk_dev_list_entry, &vdisk_dev_list);
3413 /* scst_vdisk_mutex supposed to be held */
3414 static struct scst_vdisk_dev *vdisk_find(const char *name)
3416 struct scst_vdisk_dev *res, *vv;
3421 list_for_each_entry(vv, &vdisk_dev_list, vdisk_dev_list_entry) {
3422 if (strcmp(vv->name, name) == 0) {
3428 TRACE_EXIT_HRES((unsigned long)res);
3432 /* scst_vdisk_mutex supposed to be held */
3433 static void vcdrom_add(struct scst_vdisk_dev *virt_dev)
3437 list_add_tail(&virt_dev->vdisk_dev_list_entry, &vcdrom_dev_list);
3443 /* scst_vdisk_mutex supposed to be held */
3444 static struct scst_vdisk_dev *vcdrom_find(const char *name)
3446 struct scst_vdisk_dev *res, *vv;
3451 list_for_each_entry(vv, &vcdrom_dev_list, vdisk_dev_list_entry) {
3452 if (strcmp(vv->name, name) == 0) {
3458 TRACE_EXIT_HRES((unsigned long)res);
3462 static int vdisk_parse_cmd(struct vdev_type *vdt, char *p, int *action)
3468 if (!strncmp("resync_size", p, 11)) {
3471 *action = VDISK_ACTION_RESYNC_SIZE;
3474 TRACE_EXIT_RES(res);
3478 /* scst_vdisk_mutex supposed to be held */
3479 static int vdisk_perform_cmd(struct vdev_type *vdt, int action, char *p,
3486 if (action == VDISK_ACTION_RESYNC_SIZE)
3487 res = vdisk_resync_size(vdt, p, name);
3489 TRACE_EXIT_RES(res);
3493 static void vcdrom_init(struct vdev_type *vdt,
3494 struct scst_vdisk_dev *virt_dev)
3496 struct vcdrom_type *vt;
3498 vt = container_of(vdt, struct vcdrom_type, parent_vdt);
3500 vt->parent_vdt_vfns.vdev_init(vdt, virt_dev);
3502 virt_dev->rd_only = 1;
3503 virt_dev->removable = 1;
3505 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
3506 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
3511 static int vcdrom_pre_register(struct scst_vdisk_dev *virt_dev)
3515 if ((virt_dev->file_name == NULL) ||
3516 (strcmp(virt_dev->file_name, VDEV_NONE_FILENAME) == 0))
3517 virt_dev->cdrom_empty = 1;
3519 if (virt_dev->block_size != DEF_CDROM_BLOCKSIZE) {
3520 PRINT_WARNING("Block size %d for vortual device %s ignored",
3521 virt_dev->block_size, virt_dev->name);
3522 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
3523 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
3529 /* scst_vdisk_mutex supposed to be held */
3530 static int vcdrom_change(struct vdev_type *vdt, char *p, const char *name)
3533 struct scst_vdisk_dev *virt_dev;
3534 char *file_name, *fn = NULL, *old_fn;
3538 virt_dev = vdt->vfns.vdev_find(name);
3539 if (virt_dev == NULL) {
3540 PRINT_ERROR("Virtual device with name "
3541 "%s not found", name);
3546 while (isspace(*p) && *p != '\0')
3549 while (!isspace(*p) && *p != '\0')
3552 if (*file_name == '\0') {
3553 virt_dev->cdrom_empty = 1;
3554 TRACE_DBG("%s", "No media");
3555 } else if (*file_name != '/') {
3556 PRINT_ERROR("File path \"%s\" is not "
3557 "absolute", file_name);
3561 virt_dev->cdrom_empty = 0;
3563 old_fn = virt_dev->file_name;
3565 if (!virt_dev->cdrom_empty) {
3566 len = strlen(file_name) + 1;