4 * Copyright (C) 2004 - 2008 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 - 2008 CMS Distribution Limited
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/proc_fs.h>
34 #include <linux/list.h>
35 #include <linux/ctype.h>
36 #include <linux/writeback.h>
37 #include <linux/vmalloc.h>
38 #include <asm/atomic.h>
39 #include <linux/kthread.h>
40 #include <linux/sched.h>
42 #define LOG_PREFIX "dev_vdisk"
46 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
48 #define TRACE_ORDER 0x80000000
50 static struct scst_proc_log vdisk_proc_local_trace_tbl[] =
52 { TRACE_ORDER, "order" },
55 #define trace_log_tbl vdisk_proc_local_trace_tbl
59 #include "scst_dev_handler.h"
61 /* 8 byte ASCII Vendor */
62 #define SCST_FIO_VENDOR "SCST_FIO"
63 #define SCST_BIO_VENDOR "SCST_BIO"
64 /* 4 byte ASCII Product Revision Level - left aligned */
65 #define SCST_FIO_REV " 101"
67 #define MAX_USN_LEN 20
69 #define INQ_BUF_SZ 128
73 #define MSENSE_BUF_SZ 256
74 #define DBD 0x08 /* disable block descriptor */
75 #define WP 0x80 /* write protect */
76 #define DPOFUA 0x10 /* DPOFUA bit */
77 #define WCE 0x04 /* write cache enable */
79 #define PF 0x10 /* page format */
80 #define SP 0x01 /* save pages */
81 #define PS 0x80 /* parameter saveable */
84 #define DEF_DISK_BLOCKSIZE_SHIFT 9
85 #define DEF_DISK_BLOCKSIZE (1 << DEF_DISK_BLOCKSIZE_SHIFT)
86 #define DEF_CDROM_BLOCKSIZE_SHIFT 11
87 #define DEF_CDROM_BLOCKSIZE (1 << DEF_CDROM_BLOCKSIZE_SHIFT)
88 #define DEF_SECTORS 56
90 #define LEN_MEM (32 * 1024)
91 #define VDISK_NAME "vdisk"
92 #define VCDROM_NAME "vcdrom"
94 #define DEF_TST SCST_CONTR_MODE_SEP_TASK_SETS
96 * Since we can't control backstorage device's reordering, we have to always
97 * report unrestricted reordering.
99 #define DEF_QUEUE_ALG_WT SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
100 #define DEF_QUEUE_ALG SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
104 #define VDISK_PROC_HELP "help"
106 static unsigned int random_values[256] = {
107 9862592UL, 3744545211UL, 2348289082UL, 4036111983UL,
108 435574201UL, 3110343764UL, 2383055570UL, 1826499182UL,
109 4076766377UL, 1549935812UL, 3696752161UL, 1200276050UL,
110 3878162706UL, 1783530428UL, 2291072214UL, 125807985UL,
111 3407668966UL, 547437109UL, 3961389597UL, 969093968UL,
112 56006179UL, 2591023451UL, 1849465UL, 1614540336UL,
113 3699757935UL, 479961779UL, 3768703953UL, 2529621525UL,
114 4157893312UL, 3673555386UL, 4091110867UL, 2193909423UL,
115 2800464448UL, 3052113233UL, 450394455UL, 3424338713UL,
116 2113709130UL, 4082064373UL, 3708640918UL, 3841182218UL,
117 3141803315UL, 1032476030UL, 1166423150UL, 1169646901UL,
118 2686611738UL, 575517645UL, 2829331065UL, 1351103339UL,
119 2856560215UL, 2402488288UL, 867847666UL, 8524618UL,
120 704790297UL, 2228765657UL, 231508411UL, 1425523814UL,
121 2146764591UL, 1287631730UL, 4142687914UL, 3879884598UL,
122 729945311UL, 310596427UL, 2263511876UL, 1983091134UL,
123 3500916580UL, 1642490324UL, 3858376049UL, 695342182UL,
124 780528366UL, 1372613640UL, 1100993200UL, 1314818946UL,
125 572029783UL, 3775573540UL, 776262915UL, 2684520905UL,
126 1007252738UL, 3505856396UL, 1974886670UL, 3115856627UL,
127 4194842288UL, 2135793908UL, 3566210707UL, 7929775UL,
128 1321130213UL, 2627281746UL, 3587067247UL, 2025159890UL,
129 2587032000UL, 3098513342UL, 3289360258UL, 130594898UL,
130 2258149812UL, 2275857755UL, 3966929942UL, 1521739999UL,
131 4191192765UL, 958953550UL, 4153558347UL, 1011030335UL,
132 524382185UL, 4099757640UL, 498828115UL, 2396978754UL,
133 328688935UL, 826399828UL, 3174103611UL, 3921966365UL,
134 2187456284UL, 2631406787UL, 3930669674UL, 4282803915UL,
135 1776755417UL, 374959755UL, 2483763076UL, 844956392UL,
136 2209187588UL, 3647277868UL, 291047860UL, 3485867047UL,
137 2223103546UL, 2526736133UL, 3153407604UL, 3828961796UL,
138 3355731910UL, 2322269798UL, 2752144379UL, 519897942UL,
139 3430536488UL, 1801511593UL, 1953975728UL, 3286944283UL,
140 1511612621UL, 1050133852UL, 409321604UL, 1037601109UL,
141 3352316843UL, 4198371381UL, 617863284UL, 994672213UL,
142 1540735436UL, 2337363549UL, 1242368492UL, 665473059UL,
143 2330728163UL, 3443103219UL, 2291025133UL, 3420108120UL,
144 2663305280UL, 1608969839UL, 2278959931UL, 1389747794UL,
145 2226946970UL, 2131266900UL, 3856979144UL, 1894169043UL,
146 2692697628UL, 3797290626UL, 3248126844UL, 3922786277UL,
147 343705271UL, 3739749888UL, 2191310783UL, 2962488787UL,
148 4119364141UL, 1403351302UL, 2984008923UL, 3822407178UL,
149 1932139782UL, 2323869332UL, 2793574182UL, 1852626483UL,
150 2722460269UL, 1136097522UL, 1005121083UL, 1805201184UL,
151 2212824936UL, 2979547931UL, 4133075915UL, 2585731003UL,
152 2431626071UL, 134370235UL, 3763236829UL, 1171434827UL,
153 2251806994UL, 1289341038UL, 3616320525UL, 392218563UL,
154 1544502546UL, 2993937212UL, 1957503701UL, 3579140080UL,
155 4270846116UL, 2030149142UL, 1792286022UL, 366604999UL,
156 2625579499UL, 790898158UL, 770833822UL, 815540197UL,
157 2747711781UL, 3570468835UL, 3976195842UL, 1257621341UL,
158 1198342980UL, 1860626190UL, 3247856686UL, 351473955UL,
159 993440563UL, 340807146UL, 1041994520UL, 3573925241UL,
160 480246395UL, 2104806831UL, 1020782793UL, 3362132583UL,
161 2272911358UL, 3440096248UL, 2356596804UL, 259492703UL,
162 3899500740UL, 252071876UL, 2177024041UL, 4284810959UL,
163 2775999888UL, 2653420445UL, 2876046047UL, 1025771859UL,
164 1994475651UL, 3564987377UL, 4112956647UL, 1821511719UL,
165 3113447247UL, 455315102UL, 1585273189UL, 2311494568UL,
166 774051541UL, 1898115372UL, 2637499516UL, 247231365UL,
167 1475014417UL, 803585727UL, 3911097303UL, 1714292230UL,
168 476579326UL, 2496900974UL, 3397613314UL, 341202244UL,
169 807790202UL, 4221326173UL, 499979741UL, 1301488547UL,
170 1056807896UL, 3525009458UL, 1174811641UL, 3049738746UL,
173 struct scst_vdisk_dev {
177 loff_t file_size; /* in bytes */
180 * This lock can be taken on both SIRQ and thread context, but in
181 * all cases for each particular instance it's taken consistenly either
182 * on SIRQ or thread context. Mix of them is impossible.
184 spinlock_t flags_lock;
187 * Below flags are protected by flags_lock or suspended activity
188 * with scst_vdisk_mutex.
190 unsigned int rd_only_flag:1;
191 unsigned int wt_flag:1;
192 unsigned int nv_cache:1;
193 unsigned int o_direct_flag:1;
194 unsigned int media_changed:1;
195 unsigned int prevent_allow_medium_removal:1;
196 unsigned int nullio:1;
197 unsigned int blockio:1;
198 unsigned int cdrom_empty:1;
199 unsigned int removable:1;
201 char name[16+1]; /* Name of virtual device,
202 must be <= SCSI Model + 1 */
203 char *file_name; /* File name */
205 struct scst_device *dev;
206 struct list_head vdisk_dev_list_entry;
209 struct scst_vdisk_tgt_dev {
211 * Used without locking since SCST core ensures that only commands
212 * with the same ORDERED type per tgt_dev can be processed
215 enum scst_cmd_queue_type last_write_cmd_queue_type;
218 struct scst_vdisk_thr {
219 struct scst_thr_data_hdr hdr;
221 struct block_device *bdev;
226 static struct kmem_cache *vdisk_thr_cachep;
228 static int vdisk_attach(struct scst_device *dev);
229 static void vdisk_detach(struct scst_device *dev);
230 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev);
231 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev);
232 static int vdisk_parse(struct scst_cmd *);
233 static int vdisk_do_job(struct scst_cmd *cmd);
234 static int vcdrom_parse(struct scst_cmd *);
235 static int vcdrom_exec(struct scst_cmd *cmd);
236 static void vdisk_exec_read(struct scst_cmd *cmd,
237 struct scst_vdisk_thr *thr, loff_t loff);
238 static void vdisk_exec_write(struct scst_cmd *cmd,
239 struct scst_vdisk_thr *thr, loff_t loff);
240 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
241 u64 lba_start, int write);
242 static void vdisk_exec_verify(struct scst_cmd *cmd,
243 struct scst_vdisk_thr *thr, loff_t loff);
244 static void vdisk_exec_read_capacity(struct scst_cmd *cmd);
245 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd);
246 static void vdisk_exec_inquiry(struct scst_cmd *cmd);
247 static void vdisk_exec_request_sense(struct scst_cmd *cmd);
248 static void vdisk_exec_mode_sense(struct scst_cmd *cmd);
249 static void vdisk_exec_mode_select(struct scst_cmd *cmd);
250 static void vdisk_exec_log(struct scst_cmd *cmd);
251 static void vdisk_exec_read_toc(struct scst_cmd *cmd);
252 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd);
253 static int vdisk_fsync(struct scst_vdisk_thr *thr,
254 loff_t loff, loff_t len, struct scst_cmd *cmd);
255 static int vdisk_read_proc(struct seq_file *seq,
256 struct scst_dev_type *dev_type);
257 static int vdisk_write_proc(char *buffer, char **start, off_t offset,
258 int length, int *eof, struct scst_dev_type *dev_type);
259 static int vcdrom_read_proc(struct seq_file *seq,
260 struct scst_dev_type *dev_type);
261 static int vcdrom_write_proc(char *buffer, char **start, off_t offset,
262 int length, int *eof, struct scst_dev_type *dev_type);
263 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
264 struct scst_tgt_dev *tgt_dev);
267 * Name of FILEIO vdisk can't be changed from "vdisk", since it is the name
268 * of the corresponding /proc/scsi_tgt entry, hence a part of user space ABI.
271 #define VDISK_TYPE { \
272 .name = VDISK_NAME, \
278 .dev_done_atomic = 1, \
279 .attach = vdisk_attach, \
280 .detach = vdisk_detach, \
281 .attach_tgt = vdisk_attach_tgt, \
282 .detach_tgt = vdisk_detach_tgt, \
283 .parse = vdisk_parse, \
284 .exec = vdisk_do_job, \
285 .read_proc = vdisk_read_proc, \
286 .write_proc = vdisk_write_proc, \
287 .task_mgmt_fn = vdisk_task_mgmt_fn, \
290 #define VDISK_BLK_TYPE { \
291 .name = VDISK_NAME "_blk", \
296 .dev_done_atomic = 1, \
298 .attach = vdisk_attach, \
299 .detach = vdisk_detach, \
300 .attach_tgt = vdisk_attach_tgt, \
301 .detach_tgt = vdisk_detach_tgt, \
302 .parse = vdisk_parse, \
303 .exec = vdisk_do_job, \
304 .task_mgmt_fn = vdisk_task_mgmt_fn, \
307 #define VDISK_NULL_TYPE { \
308 .name = VDISK_NAME "_null", \
313 .dev_done_atomic = 1, \
315 .attach = vdisk_attach, \
316 .detach = vdisk_detach, \
317 .attach_tgt = vdisk_attach_tgt, \
318 .detach_tgt = vdisk_detach_tgt, \
319 .parse = vdisk_parse, \
320 .exec = vdisk_do_job, \
321 .task_mgmt_fn = vdisk_task_mgmt_fn, \
324 #define VCDROM_TYPE { \
325 .name = VCDROM_NAME, \
331 .dev_done_atomic = 1, \
332 .attach = vdisk_attach, \
333 .detach = vdisk_detach, \
334 .attach_tgt = vdisk_attach_tgt, \
335 .detach_tgt = vdisk_detach_tgt, \
336 .parse = vcdrom_parse, \
337 .exec = vcdrom_exec, \
338 .read_proc = vcdrom_read_proc, \
339 .write_proc = vcdrom_write_proc, \
340 .task_mgmt_fn = vdisk_task_mgmt_fn, \
343 static DEFINE_MUTEX(scst_vdisk_mutex);
344 static LIST_HEAD(vdisk_dev_list);
345 static LIST_HEAD(vcdrom_dev_list);
347 static struct scst_dev_type vdisk_file_devtype = VDISK_TYPE;
348 static struct scst_dev_type vdisk_blk_devtype = VDISK_BLK_TYPE;
349 static struct scst_dev_type vdisk_null_devtype = VDISK_NULL_TYPE;
350 static struct scst_dev_type vcdrom_devtype = VCDROM_TYPE;
352 static struct scst_vdisk_thr nullio_thr_data;
354 static char *vdisk_proc_help_string =
355 "echo \"open|close NAME [FILE_NAME [BLOCK_SIZE] [WRITE_THROUGH "
356 "READ_ONLY O_DIRECT NULLIO NV_CACHE BLOCKIO]]\" >/proc/scsi_tgt/"
357 VDISK_NAME "/" VDISK_NAME "\n";
359 static char *vcdrom_proc_help_string =
360 "echo \"open|change|close NAME [FILE_NAME]\" "
361 ">/proc/scsi_tgt/" VCDROM_NAME "/" VCDROM_NAME "\n";
363 static int scst_vdisk_ID;
365 module_param_named(scst_vdisk_ID, scst_vdisk_ID, int, 0);
366 MODULE_PARM_DESC(scst_vdisk_ID, "SCST virtual disk subsystem ID");
369 /**************************************************************
370 * Function: vdisk_open
374 * Returns : fd, use IS_ERR(fd) to get error status
377 *************************************************************/
378 static struct file *vdisk_open(const struct scst_vdisk_dev *virt_dev)
385 if (virt_dev->rd_only_flag)
386 open_flags |= O_RDONLY;
388 open_flags |= O_RDWR;
389 if (virt_dev->o_direct_flag)
390 open_flags |= O_DIRECT;
391 if (virt_dev->wt_flag && !virt_dev->nv_cache)
392 open_flags |= O_SYNC;
393 TRACE_DBG("Opening file %s, flags 0x%x",
394 virt_dev->file_name, open_flags);
395 fd = filp_open(virt_dev->file_name, O_LARGEFILE | open_flags, 0600);
401 /**************************************************************
402 * Function: vdisk_attach
406 * Returns : 1 if attached, error code otherwise
409 *************************************************************/
410 static int vdisk_attach(struct scst_device *dev)
415 struct scst_vdisk_dev *virt_dev = NULL, *vv;
416 struct list_head *vd;
420 TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
422 if (dev->virt_id == 0) {
423 PRINT_ERROR("%s", "Not a virtual device");
428 vd = (dev->handler->type == TYPE_DISK) ?
433 * scst_vdisk_mutex must be already taken before
434 * scst_register_virtual_device()
436 list_for_each_entry(vv, vd, vdisk_dev_list_entry) {
437 if (strcmp(vv->name, dev->virt_name) == 0) {
443 if (virt_dev == NULL) {
444 PRINT_ERROR("Device %s not found", dev->virt_name);
451 if (dev->handler->type == TYPE_ROM)
452 virt_dev->rd_only_flag = 1;
454 if (!virt_dev->cdrom_empty) {
455 if (virt_dev->nullio)
456 err = 3LL*1024*1024*1024*1024/2;
460 fd = vdisk_open(virt_dev);
463 PRINT_ERROR("filp_open(%s) returned error %d",
464 virt_dev->file_name, res);
468 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
469 if ((fd->f_op == NULL) ||
470 (fd->f_op->readv == NULL) ||
471 (fd->f_op->writev == NULL)) {
473 if ((fd->f_op == NULL) ||
474 (fd->f_op->aio_read == NULL) ||
475 (fd->f_op->aio_write == NULL)) {
477 PRINT_ERROR("%s", "Wrong f_op or FS doesn't "
478 "have required capabilities");
480 filp_close(fd, NULL);
484 inode = fd->f_dentry->d_inode;
486 if (virt_dev->blockio && !S_ISBLK(inode->i_mode)) {
487 PRINT_ERROR("File %s is NOT a block device",
488 virt_dev->file_name);
490 filp_close(fd, NULL);
494 if (S_ISREG(inode->i_mode))
496 else if (S_ISBLK(inode->i_mode))
497 inode = inode->i_bdev->bd_inode;
500 filp_close(fd, NULL);
505 filp_close(fd, NULL);
507 virt_dev->file_size = err;
508 TRACE_DBG("size of file: %lld", (long long unsigned int)err);
510 virt_dev->file_size = 0;
512 if (dev->handler->type == TYPE_DISK) {
514 virt_dev->file_size >> virt_dev->block_shift;
516 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
517 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
519 virt_dev->file_size >> DEF_CDROM_BLOCKSIZE_SHIFT;
522 if (!virt_dev->cdrom_empty) {
523 PRINT_INFO("Attached SCSI target virtual %s %s "
524 "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
526 (dev->handler->type == TYPE_DISK) ? "disk" : "cdrom",
527 virt_dev->name, virt_dev->file_name,
528 virt_dev->file_size >> 20, virt_dev->block_size,
529 (long long unsigned int)virt_dev->nblocks,
530 (long long unsigned int)virt_dev->nblocks/64/32,
531 virt_dev->nblocks < 64*32
532 ? " !WARNING! cyln less than 1" : "");
534 PRINT_INFO("Attached empty SCSI target virtual cdrom %s",
538 dev->dh_priv = virt_dev;
541 if (virt_dev->wt_flag && !virt_dev->nv_cache)
542 dev->queue_alg = DEF_QUEUE_ALG_WT;
544 dev->queue_alg = DEF_QUEUE_ALG;
553 /************************************************************
554 * Function: vdisk_detach
560 * Description: Called to detach this device type driver
561 ************************************************************/
562 static void vdisk_detach(struct scst_device *dev)
564 struct scst_vdisk_dev *virt_dev =
565 (struct scst_vdisk_dev *)dev->dh_priv;
569 TRACE_DBG("virt_id %d", dev->virt_id);
571 PRINT_INFO("Detached SCSI target virtual device %s (\"%s\")",
572 virt_dev->name, virt_dev->file_name);
574 /* virt_dev will be freed by the caller */
581 static void vdisk_free_thr_data(struct scst_thr_data_hdr *d)
583 struct scst_vdisk_thr *thr =
584 container_of(d, struct scst_vdisk_thr, hdr);
589 filp_close(thr->fd, NULL);
593 kmem_cache_free(vdisk_thr_cachep, thr);
599 static struct scst_vdisk_thr *vdisk_init_thr_data(
600 struct scst_tgt_dev *tgt_dev)
602 struct scst_vdisk_thr *res;
603 struct scst_vdisk_dev *virt_dev =
604 (struct scst_vdisk_dev *)tgt_dev->dev->dh_priv;
608 EXTRACHECKS_BUG_ON(virt_dev->nullio);
610 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
611 res = kmem_cache_alloc(vdisk_thr_cachep, GFP_KERNEL);
613 memset(res, 0, sizeof(*res));
615 res = kmem_cache_zalloc(vdisk_thr_cachep, GFP_KERNEL);
618 TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct "
623 if (!virt_dev->cdrom_empty) {
624 res->fd = vdisk_open(virt_dev);
625 if (IS_ERR(res->fd)) {
626 PRINT_ERROR("filp_open(%s) returned an error %ld",
627 virt_dev->file_name, PTR_ERR(res->fd));
630 if (virt_dev->blockio)
631 res->bdev = res->fd->f_dentry->d_inode->i_bdev;
637 scst_add_thr_data(tgt_dev, &res->hdr, vdisk_free_thr_data);
640 TRACE_EXIT_HRES((unsigned long)res);
644 kmem_cache_free(vdisk_thr_cachep, res);
649 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev)
651 struct scst_vdisk_tgt_dev *ftgt_dev;
656 ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL);
657 if (ftgt_dev == NULL) {
658 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
659 "virtual device failed");
664 tgt_dev->dh_priv = ftgt_dev;
671 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev)
673 struct scst_vdisk_tgt_dev *ftgt_dev =
674 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
678 scst_del_all_thr_data(tgt_dev);
681 tgt_dev->dh_priv = NULL;
687 static inline int vdisk_sync_queue_type(enum scst_cmd_queue_type qt)
690 case SCST_CMD_QUEUE_ORDERED:
691 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
698 static inline int vdisk_need_pre_sync(enum scst_cmd_queue_type cur,
699 enum scst_cmd_queue_type last)
701 if (vdisk_sync_queue_type(cur))
702 if (!vdisk_sync_queue_type(last))
707 static int vdisk_do_job(struct scst_cmd *cmd)
710 uint64_t lba_start = 0;
712 uint8_t *cdb = cmd->cdb;
715 struct scst_device *dev = cmd->dev;
716 struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
717 struct scst_vdisk_dev *virt_dev =
718 (struct scst_vdisk_dev *)dev->dh_priv;
719 struct scst_thr_data_hdr *d;
720 struct scst_vdisk_thr *thr = NULL;
725 switch (cmd->queue_type) {
726 case SCST_CMD_QUEUE_ORDERED:
727 TRACE(TRACE_ORDER, "ORDERED cmd %p", cmd);
729 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
730 TRACE(TRACE_ORDER, "HQ cmd %p", cmd);
736 rc = scst_check_local_events(cmd);
737 if (unlikely(rc != 0))
742 cmd->host_status = DID_OK;
743 cmd->driver_status = 0;
745 if (!virt_dev->nullio) {
746 d = scst_find_thr_data(tgt_dev);
747 if (unlikely(d == NULL)) {
748 thr = vdisk_init_thr_data(tgt_dev);
753 scst_thr_data_get(&thr->hdr);
755 thr = container_of(d, struct scst_vdisk_thr, hdr);
757 thr = &nullio_thr_data;
758 scst_thr_data_get(&thr->hdr);
765 lba_start = (((cdb[1] & 0x1f) << (BYTE * 2)) +
766 (cdb[2] << (BYTE * 1)) +
767 (cdb[3] << (BYTE * 0)));
768 data_len = cmd->bufflen;
776 case WRITE_VERIFY_12:
778 lba_start |= ((u64)cdb[2]) << 24;
779 lba_start |= ((u64)cdb[3]) << 16;
780 lba_start |= ((u64)cdb[4]) << 8;
781 lba_start |= ((u64)cdb[5]);
782 data_len = cmd->bufflen;
786 case WRITE_VERIFY_16:
788 lba_start |= ((u64)cdb[2]) << 56;
789 lba_start |= ((u64)cdb[3]) << 48;
790 lba_start |= ((u64)cdb[4]) << 40;
791 lba_start |= ((u64)cdb[5]) << 32;
792 lba_start |= ((u64)cdb[6]) << 24;
793 lba_start |= ((u64)cdb[7]) << 16;
794 lba_start |= ((u64)cdb[8]) << 8;
795 lba_start |= ((u64)cdb[9]);
796 data_len = cmd->bufflen;
798 case SYNCHRONIZE_CACHE:
799 lba_start |= ((u64)cdb[2]) << 24;
800 lba_start |= ((u64)cdb[3]) << 16;
801 lba_start |= ((u64)cdb[4]) << 8;
802 lba_start |= ((u64)cdb[5]);
803 data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0)))
804 << virt_dev->block_shift;
806 data_len = virt_dev->file_size -
807 ((loff_t)lba_start << virt_dev->block_shift);
811 loff = (loff_t)lba_start << virt_dev->block_shift;
812 TRACE_DBG("cmd %p, lba_start %lld, loff %lld, data_len %lld", cmd,
813 (long long unsigned int)lba_start,
814 (long long unsigned int)loff,
815 (long long unsigned int)data_len);
816 if (unlikely(loff < 0) || unlikely(data_len < 0) ||
817 unlikely((loff + data_len) > virt_dev->file_size)) {
818 PRINT_INFO("Access beyond the end of the device "
819 "(%lld of %lld, len %lld)",
820 (long long unsigned int)loff,
821 (long long unsigned int)virt_dev->file_size,
822 (long long unsigned int)data_len);
823 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
824 scst_sense_block_out_range_error));
832 fua = (cdb[1] & 0x8);
834 TRACE(TRACE_ORDER, "FUA: loff=%lld, "
835 "data_len=%lld", (long long unsigned int)loff,
836 (long long unsigned int)data_len);
846 if (virt_dev->blockio) {
847 blockio_exec_rw(cmd, thr, lba_start, 0);
850 vdisk_exec_read(cmd, thr, loff);
856 if (likely(!virt_dev->rd_only_flag)) {
857 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
858 struct scst_vdisk_tgt_dev *ftgt_dev =
859 (struct scst_vdisk_tgt_dev *)
861 enum scst_cmd_queue_type last_queue_type =
862 ftgt_dev->last_write_cmd_queue_type;
863 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
864 if (vdisk_need_pre_sync(cmd->queue_type,
866 TRACE(TRACE_ORDER, "ORDERED "
867 "WRITE(%d): loff=%lld, data_len=%lld",
869 (long long unsigned int)loff,
870 (long long unsigned int)data_len);
872 if (vdisk_fsync(thr, 0, 0, cmd) != 0)
875 if (virt_dev->blockio) {
876 blockio_exec_rw(cmd, thr, lba_start, 1);
879 vdisk_exec_write(cmd, thr, loff);
880 /* O_SYNC flag is used for WT devices */
882 vdisk_fsync(thr, loff, data_len, cmd);
884 TRACE(TRACE_MINOR, "Attempt to write to read-only "
885 "device %s", virt_dev->name);
886 scst_set_cmd_error(cmd,
887 SCST_LOAD_SENSE(scst_sense_data_protect));
891 case WRITE_VERIFY_12:
892 case WRITE_VERIFY_16:
893 if (likely(!virt_dev->rd_only_flag)) {
894 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
895 struct scst_vdisk_tgt_dev *ftgt_dev =
896 (struct scst_vdisk_tgt_dev *)
898 enum scst_cmd_queue_type last_queue_type =
899 ftgt_dev->last_write_cmd_queue_type;
900 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
901 if (vdisk_need_pre_sync(cmd->queue_type,
903 TRACE(TRACE_ORDER, "ORDERED "
904 "WRITE_VERIFY(%d): loff=%lld,"
905 " data_len=%lld", cmd->queue_type,
906 (long long unsigned int)loff,
907 (long long unsigned int)data_len);
909 if (vdisk_fsync(thr, 0, 0, cmd) != 0)
912 /* ToDo: BLOCKIO VERIFY */
913 vdisk_exec_write(cmd, thr, loff);
914 /* O_SYNC flag is used for WT devices */
915 if (scsi_status_is_good(cmd->status))
916 vdisk_exec_verify(cmd, thr, loff);
918 vdisk_fsync(thr, loff, data_len, cmd);
920 TRACE(TRACE_MINOR, "Attempt to write to read-only "
921 "device %s", virt_dev->name);
922 scst_set_cmd_error(cmd,
923 SCST_LOAD_SENSE(scst_sense_data_protect));
926 case SYNCHRONIZE_CACHE:
928 int immed = cdb[1] & 0x2;
929 TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: "
930 "loff=%lld, data_len=%lld, immed=%d",
931 (long long unsigned int)loff,
932 (long long unsigned int)data_len, immed);
936 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
938 vdisk_fsync(thr, loff, data_len, NULL);
939 /* ToDo: vdisk_fsync() error processing */
943 vdisk_fsync(thr, loff, data_len, cmd);
951 vdisk_exec_verify(cmd, thr, loff);
955 vdisk_exec_mode_sense(cmd);
959 vdisk_exec_mode_select(cmd);
965 case ALLOW_MEDIUM_REMOVAL:
966 vdisk_exec_prevent_allow_medium_removal(cmd);
969 vdisk_exec_read_toc(cmd);
972 vdisk_fsync(thr, 0, virt_dev->file_size, cmd);
978 case TEST_UNIT_READY:
981 vdisk_exec_inquiry(cmd);
984 vdisk_exec_request_sense(cmd);
987 vdisk_exec_read_capacity(cmd);
989 case SERVICE_ACTION_IN:
990 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
991 vdisk_exec_read_capacity16(cmd);
994 /* else go through */
997 TRACE_DBG("Invalid opcode %d", opcode);
998 scst_set_cmd_error(cmd,
999 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1006 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1009 if (likely(thr != NULL))
1010 scst_thr_data_put(&thr->hdr);
1012 res = SCST_EXEC_COMPLETED;
1014 TRACE_EXIT_RES(res);
1018 static int vdisk_get_block_shift(struct scst_cmd *cmd)
1020 struct scst_vdisk_dev *virt_dev =
1021 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1022 return virt_dev->block_shift;
1025 /********************************************************************
1026 * Function: vdisk_parse
1030 * Returns : The state of the command
1032 * Description: This does the parsing of the command
1034 * Note: Not all states are allowed on return
1035 ********************************************************************/
1036 static int vdisk_parse(struct scst_cmd *cmd)
1038 scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
1039 return SCST_CMD_STATE_DEFAULT;
1042 /********************************************************************
1043 * Function: vcdrom_parse
1047 * Returns : The state of the command
1049 * Description: This does the parsing of the command
1051 * Note: Not all states are allowed on return
1052 ********************************************************************/
1053 static int vcdrom_parse(struct scst_cmd *cmd)
1055 scst_cdrom_generic_parse(cmd, vdisk_get_block_shift);
1056 return SCST_CMD_STATE_DEFAULT;
1059 /********************************************************************
1060 * Function: vcdrom_exec
1067 ********************************************************************/
1068 static int vcdrom_exec(struct scst_cmd *cmd)
1070 int res = SCST_EXEC_COMPLETED;
1071 int opcode = cmd->cdb[0];
1072 struct scst_vdisk_dev *virt_dev =
1073 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1078 cmd->msg_status = 0;
1079 cmd->host_status = DID_OK;
1080 cmd->driver_status = 0;
1082 if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1083 TRACE_DBG("%s", "CDROM empty");
1084 scst_set_cmd_error(cmd,
1085 SCST_LOAD_SENSE(scst_sense_not_ready));
1089 if (virt_dev->media_changed && (cmd->cdb[0] != INQUIRY) &&
1090 (cmd->cdb[0] != REQUEST_SENSE) && (cmd->cdb[0] != REPORT_LUNS)) {
1091 spin_lock(&virt_dev->flags_lock);
1092 if (virt_dev->media_changed) {
1093 virt_dev->media_changed = 0;
1094 TRACE_DBG("%s", "Reporting media changed");
1095 scst_set_cmd_error(cmd,
1096 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1097 spin_unlock(&virt_dev->flags_lock);
1100 spin_unlock(&virt_dev->flags_lock);
1103 res = vdisk_do_job(cmd);
1106 TRACE_EXIT_RES(res);
1110 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
1114 static void vdisk_exec_inquiry(struct scst_cmd *cmd)
1116 int32_t length, i, resp_len = 0;
1119 struct scst_vdisk_dev *virt_dev =
1120 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1122 /* ToDo: Performance Boost:
1123 * 1. remove kzalloc, buf
1124 * 2. do all checks before touching *address
1126 * 4. write directly to *address
1131 buf = kzalloc(INQ_BUF_SZ,
1132 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1138 length = scst_get_buf_first(cmd, &address);
1139 TRACE_DBG("length %d", length);
1140 if (unlikely(length <= 0)) {
1142 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1143 scst_set_cmd_error(cmd,
1144 SCST_LOAD_SENSE(scst_sense_hardw_error));
1149 if (cmd->cdb[1] & CMDDT) {
1150 TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported");
1151 scst_set_cmd_error(cmd,
1152 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1156 buf[0] = cmd->dev->handler->type; /* type dev */
1157 if ((buf[0] == TYPE_ROM) || virt_dev->removable)
1158 buf[1] = 0x80; /* removable */
1160 if (cmd->cdb[1] & EVPD) {
1161 int dev_id_num, dev_id_len;
1164 for (dev_id_num = 0, i = 0; i < (int)strlen(virt_dev->name);
1167 random_values[(int)(virt_dev->name[i])];
1169 * Device name maximum length = 16,
1170 * do some rotating of the bits.
1172 dev_id_num ^= ((rv << i) | (rv >> (32 - i)));
1175 dev_id_num += scst_vdisk_ID;
1177 dev_id_len = scnprintf(dev_id_str, sizeof(dev_id_str), "%d",
1179 TRACE_DBG("dev_id num %d, str %s, len %d", dev_id_num,
1180 dev_id_str, dev_id_len);
1181 if (0 == cmd->cdb[2]) {
1182 /* supported vital product data pages */
1184 buf[4] = 0x0; /* this page */
1185 buf[5] = 0x80; /* unit serial number */
1186 buf[6] = 0x83; /* device identification */
1187 resp_len = buf[3] + 4;
1188 } else if (0x80 == cmd->cdb[2]) {
1189 /* unit serial number */
1191 if (virt_dev->usn == NULL) {
1192 buf[3] = MAX_USN_LEN;
1193 memset(&buf[4], 0x20, MAX_USN_LEN);
1197 if (strlen(virt_dev->usn) > MAX_USN_LEN)
1198 usn_len = MAX_USN_LEN;
1200 usn_len = strlen(virt_dev->usn);
1202 strncpy(&buf[4], virt_dev->usn, usn_len);
1204 resp_len = buf[3] + 4;
1205 } else if (0x83 == cmd->cdb[2]) {
1206 /* device identification */
1210 /* Two identification descriptors: */
1211 /* T10 vendor identifier field format (faked) */
1212 buf[num + 0] = 0x2; /* ASCII */
1215 if (virt_dev->blockio)
1216 memcpy(&buf[num + 4], SCST_BIO_VENDOR, 8);
1218 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1220 memset(&buf[num + 12], ' ', 16);
1221 i = min(strlen(virt_dev->name), (size_t)16);
1222 memcpy(&buf[num + 12], virt_dev->name, i);
1223 memcpy(&buf[num + 28], dev_id_str, dev_id_len);
1224 buf[num + 3] = 8 + 16 + dev_id_len;
1225 num += buf[num + 3];
1227 #if 0 /* This isn't required and can be misleading, so let's disable it */
1230 /* NAA IEEE registered identifier (faked) */
1231 buf[num] = 0x1; /* binary */
1235 buf[num + 4] = 0x51; /* IEEE OUI=0x123456 (faked) */
1236 buf[num + 5] = 0x23;
1237 buf[num + 6] = 0x45;
1238 buf[num + 7] = 0x60;
1239 buf[num + 8] = (dev_id_num >> 24);
1240 buf[num + 9] = (dev_id_num >> 16) & 0xff;
1241 buf[num + 10] = (dev_id_num >> 8) & 0xff;
1242 buf[num + 11] = dev_id_num & 0xff;
1247 buf[2] = (resp_len >> 8) & 0xFF;
1248 buf[3] = resp_len & 0xFF;
1251 TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1253 scst_set_cmd_error(cmd,
1254 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1260 if (cmd->cdb[2] != 0) {
1261 TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1262 scst_set_cmd_error(cmd,
1263 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1267 buf[2] = 4; /* Device complies to this standard - SPC-2 */
1268 buf[3] = 0x12; /* HiSup + data in format specified in SPC-2 */
1269 buf[4] = 31;/* n - 4 = 35 - 4 = 31 for full 36 byte data */
1270 buf[6] = 1; /* MultiP 1 */
1271 buf[7] = 2; /* CMDQUE 1, BQue 0 => commands queuing supported */
1274 * 8 byte ASCII Vendor Identification of the target
1277 if (virt_dev->blockio)
1278 memcpy(&buf[8], SCST_BIO_VENDOR, 8);
1280 memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1283 * 16 byte ASCII Product Identification of the target - left
1286 memset(&buf[16], ' ', 16);
1287 len = strlen(virt_dev->name);
1288 len = len < 16 ? len : 16;
1289 memcpy(&buf[16], virt_dev->name, len);
1292 * 4 byte ASCII Product Revision Level of the target - left
1295 memcpy(&buf[32], SCST_FIO_REV, 4);
1296 resp_len = buf[4] + 5;
1299 sBUG_ON(resp_len >= INQ_BUF_SZ);
1300 if (length > resp_len)
1302 memcpy(address, buf, length);
1305 scst_put_buf(cmd, address);
1306 if (length < cmd->resp_data_len)
1307 scst_set_resp_data_len(cmd, length);
1317 static void vdisk_exec_request_sense(struct scst_cmd *cmd)
1324 length = scst_get_buf_first(cmd, &address);
1325 TRACE_DBG("length %d", length);
1326 if (unlikely(length < SCST_STANDARD_SENSE_LEN)) {
1328 PRINT_ERROR("scst_get_buf_first() failed or too small "
1329 "requested buffer (returned %d)", length);
1330 scst_set_cmd_error(cmd,
1332 scst_sense_invalid_field_in_parm_list));
1340 scst_set_sense(address, length, SCST_LOAD_SENSE(scst_sense_no_sense));
1343 scst_put_buf(cmd, address);
1351 * <<Following mode pages info copied from ST318451LW with some corrections>>
1355 static int vdisk_err_recov_pg(unsigned char *p, int pcontrol,
1356 struct scst_vdisk_dev *virt_dev)
1357 { /* Read-Write Error Recovery page for mode_sense */
1358 const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1361 memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1363 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1364 return sizeof(err_recov_pg);
1367 static int vdisk_disconnect_pg(unsigned char *p, int pcontrol,
1368 struct scst_vdisk_dev *virt_dev)
1369 { /* Disconnect-Reconnect page for mode_sense */
1370 const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1371 0, 0, 0, 0, 0, 0, 0, 0};
1373 memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1375 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1376 return sizeof(disconnect_pg);
1379 static int vdisk_rigid_geo_pg(unsigned char *p, int pcontrol,
1380 struct scst_vdisk_dev *virt_dev)
1382 unsigned char geo_m_pg[] = {0x04, 0x16, 0, 0, 0, DEF_HEADS, 0, 0,
1383 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1384 0x3a, 0x98/* 15K RPM */, 0, 0};
1385 int32_t ncyl, n, rem;
1387 memcpy(p, geo_m_pg, sizeof(geo_m_pg));
1388 ncyl = div_s64_rem(virt_dev->nblocks, DEF_HEADS * DEF_SECTORS, &rem);
1391 memcpy(&n, p + 2, sizeof(u32));
1392 n = n | (cpu_to_be32(ncyl) >> 8);
1393 memcpy(p + 2, &n, sizeof(u32));
1395 memset(p + 2, 0, sizeof(geo_m_pg) - 2);
1396 return sizeof(geo_m_pg);
1399 static int vdisk_format_pg(unsigned char *p, int pcontrol,
1400 struct scst_vdisk_dev *virt_dev)
1401 { /* Format device page for mode_sense */
1402 const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1403 0, 0, 0, 0, 0, 0, 0, 0,
1404 0, 0, 0, 0, 0x40, 0, 0, 0};
1406 memcpy(p, format_pg, sizeof(format_pg));
1407 p[10] = (DEF_SECTORS >> 8) & 0xff;
1408 p[11] = DEF_SECTORS & 0xff;
1409 p[12] = (virt_dev->block_size >> 8) & 0xff;
1410 p[13] = virt_dev->block_size & 0xff;
1412 memset(p + 2, 0, sizeof(format_pg) - 2);
1413 return sizeof(format_pg);
1416 static int vdisk_caching_pg(unsigned char *p, int pcontrol,
1417 struct scst_vdisk_dev *virt_dev)
1418 { /* Caching page for mode_sense */
1419 const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1420 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1422 memcpy(p, caching_pg, sizeof(caching_pg));
1423 p[2] |= !(virt_dev->wt_flag || virt_dev->nv_cache) ? WCE : 0;
1425 memset(p + 2, 0, sizeof(caching_pg) - 2);
1426 return sizeof(caching_pg);
1429 static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol,
1430 struct scst_vdisk_dev *virt_dev)
1431 { /* Control mode page for mode_sense */
1432 const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0, 0, 0, 0, 0, 0,
1435 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1438 p[2] |= virt_dev->dev->tst << 5;
1439 p[3] |= virt_dev->dev->queue_alg << 4;
1440 p[4] |= virt_dev->dev->swp << 3;
1441 p[5] |= virt_dev->dev->tas << 6;
1444 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1446 * It's too early to implement it, since we can't control the
1447 * backstorage device parameters. ToDo
1449 p[2] |= 7 << 5; /* TST */
1450 p[3] |= 0xF << 4; /* QUEUE ALGORITHM MODIFIER */
1452 p[4] |= 1 << 3; /* SWP */
1453 p[5] |= 1 << 6; /* TAS */
1456 p[2] |= DEF_TST << 5;
1457 if (virt_dev->wt_flag || virt_dev->nv_cache)
1458 p[3] |= DEF_QUEUE_ALG_WT << 4;
1460 p[3] |= DEF_QUEUE_ALG << 4;
1461 p[4] |= DEF_SWP << 3;
1462 p[5] |= DEF_TAS << 6;
1467 return sizeof(ctrl_m_pg);
1470 static int vdisk_iec_m_pg(unsigned char *p, int pcontrol,
1471 struct scst_vdisk_dev *virt_dev)
1472 { /* Informational Exceptions control mode page for mode_sense */
1473 const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1475 memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1477 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1478 return sizeof(iec_m_pg);
1481 static void vdisk_exec_mode_sense(struct scst_cmd *cmd)
1486 struct scst_vdisk_dev *virt_dev;
1489 unsigned char dbd, type;
1490 int pcontrol, pcode, subpcode;
1491 unsigned char dev_spec;
1492 int msense_6, offset = 0, len;
1497 buf = kzalloc(MSENSE_BUF_SZ,
1498 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1504 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1505 blocksize = virt_dev->block_size;
1506 nblocks = virt_dev->nblocks;
1508 type = cmd->dev->handler->type; /* type dev */
1509 dbd = cmd->cdb[1] & DBD;
1510 pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1511 pcode = cmd->cdb[2] & 0x3f;
1512 subpcode = cmd->cdb[3];
1513 msense_6 = (MODE_SENSE == cmd->cdb[0]);
1514 dev_spec = (virt_dev->rd_only_flag ? WP : 0) | DPOFUA;
1516 length = scst_get_buf_first(cmd, &address);
1517 if (unlikely(length <= 0)) {
1519 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1520 scst_set_cmd_error(cmd,
1521 SCST_LOAD_SENSE(scst_sense_hardw_error));
1526 if (0x3 == pcontrol) {
1527 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1528 scst_set_cmd_error(cmd,
1529 SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1543 if (0 != subpcode) {
1544 /* TODO: Control Extension page */
1545 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1546 scst_set_cmd_error(cmd,
1547 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1552 /* Create block descriptor */
1553 buf[offset - 1] = 0x08; /* block descriptor length */
1554 if (nblocks >> 32) {
1555 buf[offset + 0] = 0xFF;
1556 buf[offset + 1] = 0xFF;
1557 buf[offset + 2] = 0xFF;
1558 buf[offset + 3] = 0xFF;
1561 buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;
1562 buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1563 buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1564 buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1566 buf[offset + 4] = 0; /* density code */
1567 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1568 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1569 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1571 offset += 8; /* increment offset */
1577 case 0x1: /* Read-Write error recovery page, direct access */
1578 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1580 case 0x2: /* Disconnect-Reconnect page, all devices */
1581 len = vdisk_disconnect_pg(bp, pcontrol, virt_dev);
1583 case 0x3: /* Format device page, direct access */
1584 len = vdisk_format_pg(bp, pcontrol, virt_dev);
1586 case 0x4: /* Rigid disk geometry */
1587 len = vdisk_rigid_geo_pg(bp, pcontrol, virt_dev);
1589 case 0x8: /* Caching page, direct access */
1590 len = vdisk_caching_pg(bp, pcontrol, virt_dev);
1592 case 0xa: /* Control Mode page, all devices */
1593 len = vdisk_ctrl_m_pg(bp, pcontrol, virt_dev);
1595 case 0x1c: /* Informational Exceptions Mode page, all devices */
1596 len = vdisk_iec_m_pg(bp, pcontrol, virt_dev);
1598 case 0x3f: /* Read all Mode pages */
1599 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1600 len += vdisk_disconnect_pg(bp + len, pcontrol, virt_dev);
1601 len += vdisk_format_pg(bp + len, pcontrol, virt_dev);
1602 len += vdisk_caching_pg(bp + len, pcontrol, virt_dev);
1603 len += vdisk_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1604 len += vdisk_iec_m_pg(bp + len, pcontrol, virt_dev);
1605 len += vdisk_rigid_geo_pg(bp + len, pcontrol, virt_dev);
1608 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1609 scst_set_cmd_error(cmd,
1610 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1617 buf[0] = offset - 1;
1619 buf[0] = ((offset - 2) >> 8) & 0xff;
1620 buf[1] = (offset - 2) & 0xff;
1623 if (offset > length)
1625 memcpy(address, buf, offset);
1628 scst_put_buf(cmd, address);
1629 if (offset < cmd->resp_data_len)
1630 scst_set_resp_data_len(cmd, offset);
1640 static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt)
1646 if ((virt_dev->wt_flag == wt) || virt_dev->nullio || virt_dev->nv_cache)
1649 spin_lock(&virt_dev->flags_lock);
1650 virt_dev->wt_flag = wt;
1651 spin_unlock(&virt_dev->flags_lock);
1653 scst_dev_del_all_thr_data(virt_dev->dev);
1656 TRACE_EXIT_RES(res);
1660 static void vdisk_ctrl_m_pg_select(unsigned char *p,
1661 struct scst_vdisk_dev *virt_dev)
1663 struct scst_device *dev = virt_dev->dev;
1664 int old_swp = dev->swp, old_tas = dev->tas;
1667 /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */
1668 dev->tst = p[2] >> 5;
1669 dev->queue_alg = p[3] >> 4;
1671 dev->swp = (p[4] & 0x8) >> 3;
1672 dev->tas = (p[5] & 0x40) >> 6;
1674 PRINT_INFO("Device %s: new control mode page parameters: SWP %x "
1675 "(was %x), TAS %x (was %x)", virt_dev->name, dev->swp,
1676 old_swp, dev->tas, old_tas);
1680 static void vdisk_exec_mode_select(struct scst_cmd *cmd)
1684 struct scst_vdisk_dev *virt_dev;
1685 int mselect_6, offset;
1689 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1690 mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1692 length = scst_get_buf_first(cmd, &address);
1693 if (unlikely(length <= 0)) {
1695 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1696 scst_set_cmd_error(cmd,
1697 SCST_LOAD_SENSE(scst_sense_hardw_error));
1702 if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1703 TRACE(TRACE_MINOR|TRACE_SCSI, "MODE SELECT: Unsupported "
1704 "value(s) of PF and/or SP bits (cdb[1]=%x)",
1706 scst_set_cmd_error(cmd,
1707 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1716 if (address[offset - 1] == 8) {
1718 } else if (address[offset - 1] != 0) {
1719 PRINT_ERROR("%s", "MODE SELECT: Wrong parameters list "
1721 scst_set_cmd_error(cmd,
1722 SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1726 while (length > offset + 2) {
1727 if (address[offset] & PS) {
1728 PRINT_ERROR("%s", "MODE SELECT: Illegal PS bit");
1729 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1730 scst_sense_invalid_field_in_parm_list));
1733 if ((address[offset] & 0x3f) == 0x8) {
1735 if (address[offset + 1] != 18) {
1736 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1737 "caching page request");
1738 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1739 scst_sense_invalid_field_in_parm_list));
1742 if (vdisk_set_wt(virt_dev,
1743 (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1744 scst_set_cmd_error(cmd,
1745 SCST_LOAD_SENSE(scst_sense_hardw_error));
1749 } else if ((address[offset] & 0x3f) == 0xA) {
1751 if (address[offset + 1] != 0xA) {
1752 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1753 "control page request");
1754 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1755 scst_sense_invalid_field_in_parm_list));
1758 vdisk_ctrl_m_pg_select(&address[offset], virt_dev);
1760 PRINT_ERROR("MODE SELECT: Invalid request %x",
1761 address[offset] & 0x3f);
1762 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1763 scst_sense_invalid_field_in_parm_list));
1766 offset += address[offset + 1];
1770 scst_put_buf(cmd, address);
1777 static void vdisk_exec_log(struct scst_cmd *cmd)
1781 /* No log pages are supported */
1782 scst_set_cmd_error(cmd,
1783 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1789 static void vdisk_exec_read_capacity(struct scst_cmd *cmd)
1793 struct scst_vdisk_dev *virt_dev;
1796 uint8_t buffer[READ_CAP_LEN];
1800 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1801 blocksize = virt_dev->block_size;
1802 nblocks = virt_dev->nblocks;
1804 /* last block on the virt_dev is (nblocks-1) */
1805 memset(buffer, 0, sizeof(buffer));
1806 if (nblocks >> 32) {
1812 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
1813 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
1814 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
1815 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
1817 buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
1818 buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
1819 buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
1820 buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
1822 length = scst_get_buf_first(cmd, &address);
1823 if (unlikely(length <= 0)) {
1825 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1826 scst_set_cmd_error(cmd,
1827 SCST_LOAD_SENSE(scst_sense_hardw_error));
1832 if (length > READ_CAP_LEN)
1833 length = READ_CAP_LEN;
1834 memcpy(address, buffer, length);
1836 scst_put_buf(cmd, address);
1838 if (length < cmd->resp_data_len)
1839 scst_set_resp_data_len(cmd, length);
1846 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd)
1850 struct scst_vdisk_dev *virt_dev;
1853 uint8_t buffer[READ_CAP16_LEN];
1857 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1858 blocksize = virt_dev->block_size;
1859 nblocks = virt_dev->nblocks - 1;
1861 memset(buffer, 0, sizeof(buffer));
1862 buffer[0] = nblocks >> 56;
1863 buffer[1] = (nblocks >> 48) & 0xFF;
1864 buffer[2] = (nblocks >> 40) & 0xFF;
1865 buffer[3] = (nblocks >> 32) & 0xFF;
1866 buffer[4] = (nblocks >> 24) & 0xFF;
1867 buffer[5] = (nblocks >> 16) & 0xFF;
1868 buffer[6] = (nblocks >> 8) & 0xFF;
1869 buffer[7] = nblocks & 0xFF;
1871 buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
1872 buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
1873 buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
1874 buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
1876 length = scst_get_buf_first(cmd, &address);
1877 if (unlikely(length <= 0)) {
1879 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1880 scst_set_cmd_error(cmd,
1881 SCST_LOAD_SENSE(scst_sense_hardw_error));
1886 if (length > READ_CAP16_LEN)
1887 length = READ_CAP16_LEN;
1888 memcpy(address, buffer, length);
1890 scst_put_buf(cmd, address);
1892 if (length < cmd->resp_data_len)
1893 scst_set_resp_data_len(cmd, length);
1900 static void vdisk_exec_read_toc(struct scst_cmd *cmd)
1902 int32_t length, off = 0;
1904 struct scst_vdisk_dev *virt_dev;
1906 uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
1907 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
1911 if (cmd->dev->handler->type != TYPE_ROM) {
1912 PRINT_ERROR("%s", "READ TOC for non-CDROM device");
1913 scst_set_cmd_error(cmd,
1914 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1918 if (cmd->cdb[2] & 0x0e/*Format*/) {
1919 PRINT_ERROR("%s", "READ TOC: invalid requested data format");
1920 scst_set_cmd_error(cmd,
1921 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1925 if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
1926 (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
1927 PRINT_ERROR("READ TOC: invalid requested track number %x",
1929 scst_set_cmd_error(cmd,
1930 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1934 length = scst_get_buf_first(cmd, &address);
1935 if (unlikely(length <= 0)) {
1937 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1938 scst_set_cmd_error(cmd,
1939 SCST_LOAD_SENSE(scst_sense_hardw_error));
1944 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1945 /* ToDo when you have > 8TB ROM device. */
1946 nblocks = (uint32_t)virt_dev->nblocks;
1949 memset(buffer, 0, sizeof(buffer));
1950 buffer[2] = 0x01; /* First Track/Session */
1951 buffer[3] = 0x01; /* Last Track/Session */
1953 if (cmd->cdb[6] <= 1) {
1954 /* Fistr TOC Track Descriptor */
1955 /* ADDR 0x10 - Q Sub-channel encodes current position data
1956 CONTROL 0x04 - Data track, recoreded uninterrupted */
1957 buffer[off+1] = 0x14;
1959 buffer[off+2] = 0x01;
1962 if (!(cmd->cdb[2] & 0x01)) {
1963 /* Lead-out area TOC Track Descriptor */
1964 buffer[off+1] = 0x14;
1966 buffer[off+2] = 0xAA;
1967 /* Track Start Address */
1968 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF;
1969 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
1970 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
1971 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
1975 buffer[1] = off - 2; /* Data Length */
1979 memcpy(address, buffer, off);
1981 scst_put_buf(cmd, address);
1983 if (off < cmd->resp_data_len)
1984 scst_set_resp_data_len(cmd, off);
1991 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
1993 struct scst_vdisk_dev *virt_dev =
1994 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1996 TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
1998 if (cmd->dev->handler->type == TYPE_ROM) {
1999 spin_lock(&virt_dev->flags_lock);
2000 virt_dev->prevent_allow_medium_removal =
2001 cmd->cdb[4] & 0x01 ? 1 : 0;
2002 spin_unlock(&virt_dev->flags_lock);
2008 static int vdisk_fsync(struct scst_vdisk_thr *thr,
2009 loff_t loff, loff_t len, struct scst_cmd *cmd)
2012 struct scst_vdisk_dev *virt_dev =
2013 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2014 struct file *file = thr->fd;
2015 struct inode *inode;
2016 struct address_space *mapping;
2020 /* Hopefully, the compiler will generate the single comparison */
2021 if (virt_dev->nv_cache || virt_dev->blockio || virt_dev->wt_flag ||
2022 virt_dev->rd_only_flag || virt_dev->o_direct_flag ||
2026 inode = file->f_dentry->d_inode;
2027 mapping = file->f_mapping;
2029 res = sync_page_range(inode, mapping, loff, len);
2030 if (unlikely(res != 0)) {
2031 PRINT_ERROR("sync_page_range() failed (%d)", res);
2033 scst_set_cmd_error(cmd,
2034 SCST_LOAD_SENSE(scst_sense_write_error));
2038 /* ToDo: flush the device cache, if needed */
2041 TRACE_EXIT_RES(res);
2045 static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd,
2046 struct scst_vdisk_thr *thr)
2050 iv_count = scst_get_buf_count(cmd);
2051 if (iv_count > thr->iv_count) {
2053 /* It can't be called in atomic context */
2054 thr->iv = kmalloc(sizeof(*thr->iv) * iv_count, GFP_KERNEL);
2055 if (thr->iv == NULL) {
2056 PRINT_ERROR("Unable to allocate iv (%d)", iv_count);
2060 thr->iv_count = iv_count;
2068 * copied from <ksrc>/fs/read_write.*
2070 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
2071 static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
2073 set_current_state(TASK_UNINTERRUPTIBLE);
2074 if (!kiocbIsKicked(iocb))
2077 kiocbClearKicked(iocb);
2078 __set_current_state(TASK_RUNNING);
2081 typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
2082 unsigned long, loff_t);
2084 static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
2085 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
2090 init_sync_kiocb(&kiocb, filp);
2091 kiocb.ki_pos = *ppos;
2092 kiocb.ki_left = len;
2093 kiocb.ki_nbytes = len;
2096 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
2097 if (ret != -EIOCBRETRY)
2099 wait_on_retry_sync_kiocb(&kiocb);
2102 if (ret == -EIOCBQUEUED)
2103 ret = wait_on_sync_kiocb(&kiocb);
2104 *ppos = kiocb.ki_pos;
2109 static void vdisk_exec_read(struct scst_cmd *cmd,
2110 struct scst_vdisk_thr *thr, loff_t loff)
2112 mm_segment_t old_fs;
2114 ssize_t length, full_len;
2115 uint8_t __user *address;
2116 struct scst_vdisk_dev *virt_dev =
2117 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2118 struct file *fd = thr->fd;
2124 if (virt_dev->nullio)
2127 iv = vdisk_alloc_iv(cmd, thr);
2134 length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2135 while (length > 0) {
2139 iv[i].iov_base = address;
2140 iv[i].iov_len = length;
2141 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2143 if (unlikely(length < 0)) {
2144 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2145 scst_set_cmd_error(cmd,
2146 SCST_LOAD_SENSE(scst_sense_hardw_error));
2153 TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
2155 if (fd->f_op->llseek)
2156 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2158 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2160 PRINT_ERROR("lseek trouble %lld != %lld",
2161 (long long unsigned int)err,
2162 (long long unsigned int)loff);
2163 scst_set_cmd_error(cmd,
2164 SCST_LOAD_SENSE(scst_sense_hardw_error));
2169 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2170 err = fd->f_op->readv(fd, iv, iv_count, &fd->f_pos);
2172 err = do_sync_readv_writev(fd, iv, iv_count, full_len,
2173 &fd->f_pos, fd->f_op->aio_read);
2176 if ((err < 0) || (err < full_len)) {
2177 PRINT_ERROR("readv() returned %lld from %zd",
2178 (long long unsigned int)err,
2183 scst_set_cmd_error(cmd,
2184 SCST_LOAD_SENSE(scst_sense_read_error));
2194 scst_put_buf(cmd, (void __force *)(iv[i].iov_base));
2201 static void vdisk_exec_write(struct scst_cmd *cmd,
2202 struct scst_vdisk_thr *thr, loff_t loff)
2204 mm_segment_t old_fs;
2206 ssize_t length, full_len;
2207 uint8_t __user *address;
2208 struct scst_vdisk_dev *virt_dev =
2209 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2210 struct file *fd = thr->fd;
2211 struct iovec *iv, *eiv;
2212 int iv_count, eiv_count;
2216 if (virt_dev->nullio)
2219 iv = vdisk_alloc_iv(cmd, thr);
2225 length = scst_get_buf_first(cmd, (uint8_t __force **)&address);
2226 while (length > 0) {
2228 iv[iv_count].iov_base = address;
2229 iv[iv_count].iov_len = length;
2231 length = scst_get_buf_next(cmd, (uint8_t __force **)&address);
2233 if (unlikely(length < 0)) {
2234 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2235 scst_set_cmd_error(cmd,
2236 SCST_LOAD_SENSE(scst_sense_hardw_error));
2244 eiv_count = iv_count;
2246 TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2249 if (fd->f_op->llseek)
2250 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */);
2252 err = default_llseek(fd, loff, 0 /*SEEK_SET */);
2254 PRINT_ERROR("lseek trouble %lld != %lld",
2255 (long long unsigned int)err,
2256 (long long unsigned int)loff);
2257 scst_set_cmd_error(cmd,
2258 SCST_LOAD_SENSE(scst_sense_hardw_error));
2263 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2264 err = fd->f_op->writev(fd, eiv, eiv_count, &fd->f_pos);
2266 err = do_sync_readv_writev(fd, iv, iv_count, full_len, &fd->f_pos,
2267 fd->f_op->aio_write);
2271 PRINT_ERROR("write() returned %lld from %zd",
2272 (long long unsigned int)err,
2277 scst_set_cmd_error(cmd,
2278 SCST_LOAD_SENSE(scst_sense_write_error));
2281 } else if (err < full_len) {
2283 * Probably that's wrong, but sometimes write() returns
2284 * value less, than requested. Let's restart.
2286 int i, e = eiv_count;
2287 TRACE_MGMT_DBG("write() returned %d from %zd "
2288 "(iv_count=%d)", (int)err, full_len,
2291 PRINT_INFO("Suspicious: write() returned 0 from "
2292 "%zd (iv_count=%d)", full_len, eiv_count);
2295 for (i = 0; i < e; i++) {
2296 if ((long long)eiv->iov_len < err) {
2297 err -= eiv->iov_len;
2302 (uint8_t __force __user *)eiv->iov_base +
2304 eiv->iov_len -= err;
2315 while (iv_count > 0) {
2316 scst_put_buf(cmd, (void __force *)(iv[iv_count-1].iov_base));
2325 struct blockio_work {
2326 atomic_t bios_inflight;
2327 struct scst_cmd *cmd;
2330 static inline void blockio_check_finish(struct blockio_work *blockio_work)
2332 /* Decrement the bios in processing, and if zero signal completion */
2333 if (atomic_dec_and_test(&blockio_work->bios_inflight)) {
2334 blockio_work->cmd->completed = 1;
2335 blockio_work->cmd->scst_cmd_done(blockio_work->cmd,
2336 SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_DIRECT_ATOMIC);
2337 kfree(blockio_work);
2342 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2343 static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
2345 static void blockio_endio(struct bio *bio, int error)
2348 struct blockio_work *blockio_work = bio->bi_private;
2350 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2355 error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
2357 if (unlikely(error != 0)) {
2358 PRINT_ERROR("cmd %p returned error %d", blockio_work->cmd,
2361 * The race with other such bio's doesn't matter, since all
2362 * scst_set_cmd_error() calls do the same local to this cmd
2365 if (bio->bi_rw & WRITE)
2366 scst_set_cmd_error(blockio_work->cmd,
2367 SCST_LOAD_SENSE(scst_sense_write_error));
2369 scst_set_cmd_error(blockio_work->cmd,
2370 SCST_LOAD_SENSE(scst_sense_read_error));
2373 blockio_check_finish(blockio_work);
2376 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2383 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
2384 u64 lba_start, int write)
2386 struct scst_vdisk_dev *virt_dev =
2387 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2388 struct block_device *bdev = thr->bdev;
2389 struct request_queue *q = bdev_get_queue(bdev);
2390 int length, max_nr_vecs = 0;
2392 struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
2394 struct blockio_work *blockio_work;
2399 if (virt_dev->nullio)
2402 /* Allocate and initialize blockio_work struct */
2403 blockio_work = kmalloc(sizeof(*blockio_work), GFP_KERNEL);
2404 if (blockio_work == NULL)
2407 blockio_work->cmd = cmd;
2410 max_nr_vecs = min(bio_get_nr_vecs(bdev), BIO_MAX_PAGES);
2416 length = scst_get_buf_first(cmd, &address);
2417 while (length > 0) {
2418 int len, bytes, off, thislen;
2423 off = offset_in_page(addr);
2426 lba_start0 = lba_start;
2430 struct page *page = virt_to_page(addr);
2433 bio = bio_alloc(GFP_KERNEL, max_nr_vecs);
2435 PRINT_ERROR("Failed to create bio "
2436 "for data segment= %d cmd %p",
2437 cmd->get_sg_buf_entry_num, cmd);
2443 bio->bi_end_io = blockio_endio;
2444 bio->bi_sector = lba_start0 <<
2445 (virt_dev->block_shift - 9);
2446 bio->bi_bdev = bdev;
2447 bio->bi_private = blockio_work;
2448 #if 0 /* It could be win, but could be not, so a performance study is needed */
2449 bio->bi_rw |= 1 << BIO_RW_SYNC;
2454 tbio = tbio->bi_next = bio;
2457 bytes = min_t(unsigned int, len, PAGE_SIZE - off);
2459 rc = bio_add_page(bio, page, bytes, off);
2463 lba_start0 += thislen >> virt_dev->block_shift;
2474 lba_start += length >> virt_dev->block_shift;
2476 scst_put_buf(cmd, address);
2477 length = scst_get_buf_next(cmd, &address);
2480 /* +1 to prevent erroneous too early command completion */
2481 atomic_set(&blockio_work->bios_inflight, bios+1);
2485 hbio = hbio->bi_next;
2486 bio->bi_next = NULL;
2487 submit_bio(write, bio);
2490 if (q && q->unplug_fn)
2493 blockio_check_finish(blockio_work);
2502 hbio = hbio->bi_next;
2505 kfree(blockio_work);
2512 static void vdisk_exec_verify(struct scst_cmd *cmd,
2513 struct scst_vdisk_thr *thr, loff_t loff)
2515 mm_segment_t old_fs;
2517 ssize_t length, len_mem = 0;
2518 uint8_t *address_sav, *address;
2520 struct scst_vdisk_dev *virt_dev =
2521 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2522 struct file *fd = thr->fd;
2523 uint8_t *mem_verify = NULL;
2527 if (vdisk_fsync(thr, loff, cmd->bufflen, cmd) != 0)
2531 * Until the cache is cleared prior the verifying, there is not
2532 * much point in this code. ToDo.
2534 * Nevertherless, this code is valuable if the data have not read
2535 * from the file/disk yet.
2542 if (!virt_dev->nullio) {
2543 if (fd->f_op->llseek)
2544 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2546 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2548 PRINT_ERROR("lseek trouble %lld != %lld",
2549 (long long unsigned int)err,
2550 (long long unsigned int)loff);
2551 scst_set_cmd_error(cmd,
2552 SCST_LOAD_SENSE(scst_sense_hardw_error));
2557 mem_verify = vmalloc(LEN_MEM);
2558 if (mem_verify == NULL) {
2559 PRINT_ERROR("Unable to allocate memory %d for verify",
2561 scst_set_cmd_error(cmd,
2562 SCST_LOAD_SENSE(scst_sense_hardw_error));
2566 length = scst_get_buf_first(cmd, &address);
2567 address_sav = address;
2568 if (!length && cmd->data_len) {
2569 length = cmd->data_len;
2574 while (length > 0) {
2575 len_mem = (length > LEN_MEM) ? LEN_MEM : length;
2576 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2578 if (!virt_dev->nullio)
2579 err = fd->f_op->read(fd,
2580 (char __force __user *)mem_verify, len_mem,
2584 if ((err < 0) || (err < len_mem)) {
2585 PRINT_ERROR("verify() returned %lld from %zd",
2586 (long long unsigned int)err, len_mem);
2590 scst_set_cmd_error(cmd,
2591 SCST_LOAD_SENSE(scst_sense_read_error));
2594 scst_put_buf(cmd, address_sav);
2597 if (compare && memcmp(address, mem_verify, len_mem) != 0) {
2598 TRACE_DBG("Verify: error memcmp length %zd", length);
2599 scst_set_cmd_error(cmd,
2600 SCST_LOAD_SENSE(scst_sense_miscompare_error));
2601 scst_put_buf(cmd, address_sav);
2606 if (compare && length <= 0) {
2607 scst_put_buf(cmd, address_sav);
2608 length = scst_get_buf_next(cmd, &address);
2609 address_sav = address;
2614 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2615 scst_set_cmd_error(cmd,
2616 SCST_LOAD_SENSE(scst_sense_hardw_error));
2629 static inline struct scst_vdisk_dev *vdisk_alloc_dev(void)
2631 struct scst_vdisk_dev *dev;
2632 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2634 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of virtual "
2638 spin_lock_init(&dev->flags_lock);
2643 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2644 struct scst_tgt_dev *tgt_dev)
2648 if ((mcmd->fn == SCST_LUN_RESET) || (mcmd->fn == SCST_TARGET_RESET)) {
2649 /* Restore default values */
2650 struct scst_device *dev = tgt_dev->dev;
2651 struct scst_vdisk_dev *virt_dev =
2652 (struct scst_vdisk_dev *)dev->dh_priv;
2654 if (virt_dev->wt_flag && !virt_dev->nv_cache)
2655 dev->queue_alg = DEF_QUEUE_ALG_WT;
2657 dev->queue_alg = DEF_QUEUE_ALG;
2663 return SCST_DEV_TM_NOT_COMPLETED;
2667 * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is read
2669 static int vdisk_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type)
2672 struct scst_vdisk_dev *virt_dev;
2676 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
2681 seq_printf(seq, "%-17s %-11s %-11s %-15s %s\n",
2682 "Name", "Size(MB)", "Block size", "Options", "File name");
2684 list_for_each_entry(virt_dev, &vdisk_dev_list, vdisk_dev_list_entry) {
2686 seq_printf(seq, "%-17s %-11d %-12d", virt_dev->name,
2687 (uint32_t)(virt_dev->file_size >> 20),
2688 virt_dev->block_size);
2690 if (virt_dev->wt_flag) {
2691 seq_printf(seq, "WT ");
2694 if (virt_dev->nv_cache) {
2695 seq_printf(seq, "NV ");
2698 if (virt_dev->rd_only_flag) {
2699 seq_printf(seq, "RO ");
2702 if (virt_dev->o_direct_flag) {
2703 seq_printf(seq, "DR ");
2706 if (virt_dev->nullio) {
2707 seq_printf(seq, "NIO ");
2710 if (virt_dev->blockio) {
2711 seq_printf(seq, "BIO ");
2714 if (virt_dev->removable) {
2715 seq_printf(seq, "RM ");
2719 seq_printf(seq, " ");
2722 seq_printf(seq, "%s\n", virt_dev->file_name);
2724 mutex_unlock(&scst_vdisk_mutex);
2726 TRACE_EXIT_RES(res);
2730 static void vdisk_report_registering(const char *type,
2731 const struct scst_vdisk_dev *virt_dev)
2736 i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s ",
2737 type, virt_dev->name);
2740 if (virt_dev->wt_flag)
2741 i += snprintf(&buf[i], sizeof(buf) - i, "(WRITE_THROUGH");
2743 if (virt_dev->nv_cache)
2744 i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE",
2745 (j == i) ? "(" : ", ");
2747 if (virt_dev->rd_only_flag)
2748 i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY",
2749 (j == i) ? "(" : ", ");
2751 if (virt_dev->o_direct_flag)
2752 i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT",
2753 (j == i) ? "(" : ", ");
2755 if (virt_dev->nullio)
2756 i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO",
2757 (j == i) ? "(" : ", ");
2759 if (virt_dev->blockio)
2760 i += snprintf(&buf[i], sizeof(buf) - i, "%sBLOCKIO",
2761 (j == i) ? "(" : ", ");
2763 if (virt_dev->removable)
2764 i += snprintf(&buf[i], sizeof(buf) - i, "%sREMOVABLE",
2765 (j == i) ? "(" : ", ");
2768 PRINT_INFO("%s", buf);
2770 PRINT_INFO("%s)", buf);
2776 * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is written
2778 static int vdisk_write_proc(char *buffer, char **start, off_t offset,
2779 int length, int *eof, struct scst_dev_type *dev_type)
2781 int res = 0, action;
2782 char *p, *name, *file_name;
2783 struct scst_vdisk_dev *virt_dev, *vv;
2784 uint32_t block_size = DEF_DISK_BLOCKSIZE;
2785 int block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
2790 /* VERY UGLY code. You can rewrite it if you want */
2792 if (buffer[0] == '\0')
2795 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
2801 if (p[strlen(p) - 1] == '\n')
2802 p[strlen(p) - 1] = '\0';
2803 if (!strncmp("close ", p, 6)) {
2806 } else if (!strncmp("open ", p, 5)) {
2810 PRINT_ERROR("Unknown action \"%s\"", p);
2815 while (isspace(*p) && *p != '\0')
2818 while (!isspace(*p) && *p != '\0')
2821 if (*name == '\0') {
2822 PRINT_ERROR("%s", "Name required");
2825 } else if (strlen(name) >= sizeof(virt_dev->name)) {
2826 PRINT_ERROR("Name is too long (max %zd "
2827 "characters)", sizeof(virt_dev->name)-1);
2835 list_for_each_entry(vv, &vdisk_dev_list,
2836 vdisk_dev_list_entry)
2838 if (strcmp(vv->name, name) == 0) {
2844 PRINT_ERROR("Virtual device with name "
2845 "%s already exist", name);
2850 while (isspace(*p) && *p != '\0')
2853 while (!isspace(*p) && *p != '\0')
2856 if (*file_name == '\0') {
2857 PRINT_ERROR("%s", "File name required");
2862 virt_dev = vdisk_alloc_dev();
2863 if (virt_dev == NULL) {
2864 TRACE(TRACE_OUT_OF_MEM, "%s",
2865 "Allocation of virt_dev failed");
2870 while (isspace(*p) && *p != '\0')
2875 block_size = simple_strtoul(p, &pp, 0);
2877 if ((*p != '\0') && !isspace(*p)) {
2878 PRINT_ERROR("Parse error: \"%s\"", p);
2882 while (isspace(*p) && *p != '\0')
2885 block_shift = scst_calc_block_shift(block_size);
2886 if (block_shift < 9) {
2891 virt_dev->block_size = block_size;
2892 virt_dev->block_shift = block_shift;
2894 while (*p != '\0') {
2895 if (!strncmp("WRITE_THROUGH", p, 13)) {
2897 virt_dev->wt_flag = 1;
2898 TRACE_DBG("%s", "WRITE_THROUGH");
2899 } else if (!strncmp("NV_CACHE", p, 8)) {
2901 virt_dev->nv_cache = 1;
2902 TRACE_DBG("%s", "NON-VOLATILE CACHE");
2903 } else if (!strncmp("READ_ONLY", p, 9)) {
2905 virt_dev->rd_only_flag = 1;
2906 TRACE_DBG("%s", "READ_ONLY");
2907 } else if (!strncmp("O_DIRECT", p, 8)) {
2911 virt_dev->o_direct_flag = 1;
2912 TRACE_DBG("%s", "O_DIRECT");
2914 PRINT_INFO("%s flag doesn't currently"
2915 " work, ignoring it, use fileio_tgt "
2916 "in O_DIRECT mode instead", "O_DIRECT");
2918 } else if (!strncmp("NULLIO", p, 6)) {
2920 virt_dev->nullio = 1;
2921 TRACE_DBG("%s", "NULLIO");
2922 } else if (!strncmp("BLOCKIO", p, 7)) {
2924 virt_dev->blockio = 1;
2925 TRACE_DBG("%s", "BLOCKIO");
2926 } else if (!strncmp("REMOVABLE", p, 9)) {
2928 virt_dev->removable = 1;
2929 TRACE_DBG("%s", "REMOVABLE");
2931 PRINT_ERROR("Unknown flag \"%s\"", p);
2935 while (isspace(*p) && *p != '\0')
2939 if (!virt_dev->nullio && (*file_name != '/')) {
2940 PRINT_ERROR("File path \"%s\" is not "
2941 "absolute", file_name);
2946 strcpy(virt_dev->name, name);
2948 len = strlen(file_name) + 1;
2949 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
2950 if (virt_dev->file_name == NULL) {
2951 TRACE(TRACE_OUT_OF_MEM, "%s",
2952 "Allocation of file_name failed");
2956 strncpy(virt_dev->file_name, file_name, len);
2958 list_add_tail(&virt_dev->vdisk_dev_list_entry,
2961 if (virt_dev->blockio) {
2962 vdisk_report_registering("BLOCKIO", virt_dev);
2964 scst_register_virtual_device(&vdisk_blk_devtype,
2966 } else if (virt_dev->nullio) {
2967 vdisk_report_registering("NULLIO", virt_dev);
2969 scst_register_virtual_device(&vdisk_null_devtype,
2972 vdisk_report_registering("FILEIO", virt_dev);
2974 scst_register_virtual_device(&vdisk_file_devtype,
2977 if (virt_dev->virt_id < 0) {
2978 res = virt_dev->virt_id;
2979 goto out_free_vpath;
2981 TRACE_DBG("Added virt_dev (name %s, file name %s, "
2982 "id %d, block size %d) to "
2983 "vdisk_dev_list", virt_dev->name,
2984 virt_dev->file_name, virt_dev->virt_id,
2985 virt_dev->block_size);
2986 } else { /* close */
2988 list_for_each_entry(vv, &vdisk_dev_list,
2989 vdisk_dev_list_entry)
2991 if (strcmp(vv->name, name) == 0) {
2996 if (virt_dev == NULL) {
2997 PRINT_ERROR("Device %s not found", name);
3001 scst_unregister_virtual_device(virt_dev->virt_id);
3002 PRINT_INFO("Virtual device %s unregistered",
3004 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3006 list_del(&virt_dev->vdisk_dev_list_entry);
3008 kfree(virt_dev->file_name);
3014 mutex_unlock(&scst_vdisk_mutex);
3017 TRACE_EXIT_RES(res);
3021 list_del(&virt_dev->vdisk_dev_list_entry);
3022 kfree(virt_dev->file_name);
3029 /* scst_vdisk_mutex supposed to be held */
3030 static int vcdrom_open(char *p, char *name)
3032 struct scst_vdisk_dev *virt_dev, *vv;
3039 list_for_each_entry(vv, &vcdrom_dev_list, vdisk_dev_list_entry)
3041 if (strcmp(vv->name, name) == 0) {
3047 PRINT_ERROR("Virtual device with name "
3048 "%s already exist", name);
3053 while (isspace(*p) && *p != '\0')
3056 while (!isspace(*p) && *p != '\0')
3059 if (*file_name == '\0') {
3061 TRACE_DBG("%s", "No media");
3062 } else if (*file_name != '/') {
3063 PRINT_ERROR("File path \"%s\" is not "
3064 "absolute", file_name);
3070 virt_dev = vdisk_alloc_dev();
3071 if (virt_dev == NULL) {
3072 TRACE(TRACE_OUT_OF_MEM, "%s",
3073 "Allocation of virt_dev failed");
3077 virt_dev->cdrom_empty = cdrom_empty;
3079 strcpy(virt_dev->name, name);
3081 if (!virt_dev->cdrom_empty) {
3082 len = strlen(file_name) + 1;
3083 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
3084 if (virt_dev->file_name == NULL) {
3085 TRACE(TRACE_OUT_OF_MEM, "%s",
3086 "Allocation of file_name failed");
3090 strncpy(virt_dev->file_name, file_name, len);
3093 list_add_tail(&virt_dev->vdisk_dev_list_entry,
3096 PRINT_INFO("Registering virtual CDROM %s", name);
3099 scst_register_virtual_device(&vcdrom_devtype,
3101 if (virt_dev->virt_id < 0) {
3102 res = virt_dev->virt_id;
3103 goto out_free_vpath;
3105 TRACE_DBG("Added virt_dev (name %s file_name %s id %d) "
3106 "to vcdrom_dev_list", virt_dev->name,
3107 virt_dev->file_name, virt_dev->virt_id);
3113 list_del(&virt_dev->vdisk_dev_list_entry);
3114 kfree(virt_dev->file_name);
3121 /* scst_vdisk_mutex supposed to be held */
3122 static int vcdrom_close(char *name)
3124 struct scst_vdisk_dev *virt_dev, *vv;
3128 list_for_each_entry(vv, &vcdrom_dev_list,
3129 vdisk_dev_list_entry)
3131 if (strcmp(vv->name, name) == 0) {
3136 if (virt_dev == NULL) {
3137 PRINT_ERROR("Virtual device with name "
3138 "%s not found", name);
3142 scst_unregister_virtual_device(virt_dev->virt_id);
3143 PRINT_INFO("Virtual device %s unregistered",
3145 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3147 list_del(&virt_dev->vdisk_dev_list_entry);
3149 kfree(virt_dev->file_name);
3156 /* scst_vdisk_mutex supposed to be held */
3157 static int vcdrom_change(char *p, char *name)
3161 mm_segment_t old_fs;
3162 struct scst_vdisk_dev *virt_dev, *vv;
3163 char *file_name, *fn, *old_fn;
3168 list_for_each_entry(vv, &vcdrom_dev_list,
3169 vdisk_dev_list_entry)
3171 if (strcmp(vv->name, name) == 0) {
3176 if (virt_dev == NULL) {
3177 PRINT_ERROR("Virtual device with name "
3178 "%s not found", name);
3183 while (isspace(*p) && *p != '\0')
3186 while (!isspace(*p) && *p != '\0')
3189 if (*file_name == '\0') {
3190 virt_dev->cdrom_empty = 1;
3191 TRACE_DBG("%s", "No media");
3192 } else if (*file_name != '/') {
3193 PRINT_ERROR("File path \"%s\" is not "
3194 "absolute", file_name);
3198 virt_dev->cdrom_empty = 0;
3200 old_fn = virt_dev->file_name;
3202 if (!virt_dev->cdrom_empty && !virt_dev->nullio) {
3203 len = strlen(file_name) + 1;
3204 fn = kmalloc(len, GFP_KERNEL);
3206 TRACE(TRACE_OUT_OF_MEM, "%s",
3207 "Allocation of file_name failed");
3212 strncpy(fn, file_name, len);
3213 virt_dev->file_name = fn;
3215 fd = vdisk_open(virt_dev);
3218 PRINT_ERROR("filp_open(%s) returned an error %d",
3219 virt_dev->file_name, res);
3222 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
3223 if ((fd->f_op == NULL) || (fd->f_op->readv == NULL)) {
3225 if ((fd->f_op == NULL) || (fd->f_op->aio_read == NULL)) {
3227 PRINT_ERROR("%s", "Wrong f_op or FS doesn't "
3228 "have required capabilities");
3230 filp_close(fd, NULL);
3236 if (fd->f_op->llseek)
3237 err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/);
3239 err = default_llseek(fd, 0, 2/*SEEK_END*/);
3241 filp_close(fd, NULL);
3244 PRINT_ERROR("llseek %s returned an error %d",
3245 virt_dev->file_name, res);
3252 virt_dev->file_name = fn;
3255 res = scst_suspend_activity(true);
3259 if (virt_dev->prevent_allow_medium_removal) {
3260 PRINT_ERROR("Prevent medium removal for "
3261 "virtual device with name %s", name);
3263 goto out_free_resume;
3266 virt_dev->file_size = err;
3267 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
3268 if (!virt_dev->cdrom_empty)
3269 virt_dev->media_changed = 1;
3271 scst_dev_del_all_thr_data(virt_dev->dev);
3273 if (!virt_dev->cdrom_empty) {
3274 PRINT_INFO("Changed SCSI target virtual cdrom %s "
3275 "(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
3276 " cyln=%lld%s)", virt_dev->name, virt_dev->file_name,
3277 virt_dev->file_size >> 20, virt_dev->block_size,
3278 (long long unsigned int)virt_dev->nblocks,
3279 (long long unsigned int)virt_dev->nblocks/64/32,
3280 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
3283 PRINT_INFO("Removed media from SCSI target virtual cdrom %s",
3290 scst_resume_activity();
3296 virt_dev->file_name = old_fn;
3301 virt_dev->file_name = old_fn;
3307 * Called when a file in the /proc/VCDROM_NAME/VCDROM_NAME is read
3309 static int vcdrom_read_proc(struct seq_file *seq,
3310 struct scst_dev_type *dev_type)
3313 struct scst_vdisk_dev *virt_dev;
3317 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
3322 seq_printf(seq, "%-17s %-9s %s\n", "Name", "Size(MB)", "File name");
3324 list_for_each_entry(virt_dev, &vcdrom_dev_list,
3325 vdisk_dev_list_entry) {
3326 seq_printf(seq, "%-17s %-9d %s\n", virt_dev->name,
3327 (uint32_t)(virt_dev->file_size >> 20),
3328 virt_dev->file_name);
3331 mutex_unlock(&scst_vdisk_mutex);
3334 TRACE_EXIT_RES(res);
3339 * Called when a file in the /proc/VCDROM_NAME/VCDROM_NAME is written
3341 static int vcdrom_write_proc(char *buffer, char **start, off_t offset,
3342 int length, int *eof, struct scst_dev_type *dev_type)
3344 int res = 0, action;
3346 struct scst_vdisk_dev *virt_dev;
3350 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
3356 if (p[strlen(p) - 1] == '\n')
3357 p[strlen(p) - 1] = '\0';
3358 if (!strncmp("close ", p, 6)) {
3361 } else if (!strncmp("change ", p, 5)) {
3364 } else if (!strncmp("open ", p, 5)) {
3368 PRINT_ERROR("Unknown action \"%s\"", p);
3373 while (isspace(*p) && *p != '\0')
3376 while (!isspace(*p) && *p != '\0')
3379 if (*name == '\0') {
3380 PRINT_ERROR("%s", "Name required");
3383 } else if (strlen(name) >= sizeof(virt_dev->name)) {
3384 PRINT_ERROR("Name is too long (max %zd "
3385 "characters)", sizeof(virt_dev->name)-1);
3392 res = vcdrom_open(p, name);
3395 } else if (action == 1) {
3397 res = vcdrom_change(p, name);