4 * Copyright (C) 2004-2007 Vladislav Bolkhovitin <vst@vlnb.net>
6 * (C) 2007 Ming Zhang <blackmagic02881 at gmail dot com>
7 * (C) 2007 Ross Walker <rswwalker at hotmail dot com>
9 * SCSI disk (type 0) and CDROM (type 5) dev handler using files
10 * on file systems or block devices (VDISK)
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, version 2
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
23 #include <asm/uaccess.h>
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(DEBUG) || defined(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 " 096"
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 512
85 #define DEF_DISK_BLOCKSIZE_SHIFT 9
86 #define DEF_CDROM_BLOCKSIZE 2048
87 #define DEF_CDROM_BLOCKSIZE_SHIFT 11
88 #define DEF_SECTORS_PER 63
89 #define LEN_MEM (32 * 1024)
90 #define VDISK_NAME "vdisk"
91 #define VCDROM_NAME "vcdrom"
93 #define DEF_TST SCST_CONTR_MODE_SEP_TASK_SETS
95 * Since we can't control backstorage device's reordering, we have to always
96 * report unrestricted reordering.
98 #define DEF_QUEUE_ALG_WT SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
99 #define DEF_QUEUE_ALG SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER
103 #define VDISK_PROC_HELP "help"
105 static unsigned int random_values[256] = {
106 9862592UL, 3744545211UL, 2348289082UL, 4036111983UL,
107 435574201UL, 3110343764UL, 2383055570UL, 1826499182UL,
108 4076766377UL, 1549935812UL, 3696752161UL, 1200276050UL,
109 3878162706UL, 1783530428UL, 2291072214UL, 125807985UL,
110 3407668966UL, 547437109UL, 3961389597UL, 969093968UL,
111 56006179UL, 2591023451UL, 1849465UL, 1614540336UL,
112 3699757935UL, 479961779UL, 3768703953UL, 2529621525UL,
113 4157893312UL, 3673555386UL, 4091110867UL, 2193909423UL,
114 2800464448UL, 3052113233UL, 450394455UL, 3424338713UL,
115 2113709130UL, 4082064373UL, 3708640918UL, 3841182218UL,
116 3141803315UL, 1032476030UL, 1166423150UL, 1169646901UL,
117 2686611738UL, 575517645UL, 2829331065UL, 1351103339UL,
118 2856560215UL, 2402488288UL, 867847666UL, 8524618UL,
119 704790297UL, 2228765657UL, 231508411UL, 1425523814UL,
120 2146764591UL, 1287631730UL, 4142687914UL, 3879884598UL,
121 729945311UL, 310596427UL, 2263511876UL, 1983091134UL,
122 3500916580UL, 1642490324UL, 3858376049UL, 695342182UL,
123 780528366UL, 1372613640UL, 1100993200UL, 1314818946UL,
124 572029783UL, 3775573540UL, 776262915UL, 2684520905UL,
125 1007252738UL, 3505856396UL, 1974886670UL, 3115856627UL,
126 4194842288UL, 2135793908UL, 3566210707UL, 7929775UL,
127 1321130213UL, 2627281746UL, 3587067247UL, 2025159890UL,
128 2587032000UL, 3098513342UL, 3289360258UL, 130594898UL,
129 2258149812UL, 2275857755UL, 3966929942UL, 1521739999UL,
130 4191192765UL, 958953550UL, 4153558347UL, 1011030335UL,
131 524382185UL, 4099757640UL, 498828115UL, 2396978754UL,
132 328688935UL, 826399828UL, 3174103611UL, 3921966365UL,
133 2187456284UL, 2631406787UL, 3930669674UL, 4282803915UL,
134 1776755417UL, 374959755UL, 2483763076UL, 844956392UL,
135 2209187588UL, 3647277868UL, 291047860UL, 3485867047UL,
136 2223103546UL, 2526736133UL, 3153407604UL, 3828961796UL,
137 3355731910UL, 2322269798UL, 2752144379UL, 519897942UL,
138 3430536488UL, 1801511593UL, 1953975728UL, 3286944283UL,
139 1511612621UL, 1050133852UL, 409321604UL, 1037601109UL,
140 3352316843UL, 4198371381UL, 617863284UL, 994672213UL,
141 1540735436UL, 2337363549UL, 1242368492UL, 665473059UL,
142 2330728163UL, 3443103219UL, 2291025133UL, 3420108120UL,
143 2663305280UL, 1608969839UL, 2278959931UL, 1389747794UL,
144 2226946970UL, 2131266900UL, 3856979144UL, 1894169043UL,
145 2692697628UL, 3797290626UL, 3248126844UL, 3922786277UL,
146 343705271UL, 3739749888UL, 2191310783UL, 2962488787UL,
147 4119364141UL, 1403351302UL, 2984008923UL, 3822407178UL,
148 1932139782UL, 2323869332UL, 2793574182UL, 1852626483UL,
149 2722460269UL, 1136097522UL, 1005121083UL, 1805201184UL,
150 2212824936UL, 2979547931UL, 4133075915UL, 2585731003UL,
151 2431626071UL, 134370235UL, 3763236829UL, 1171434827UL,
152 2251806994UL, 1289341038UL, 3616320525UL, 392218563UL,
153 1544502546UL, 2993937212UL, 1957503701UL, 3579140080UL,
154 4270846116UL, 2030149142UL, 1792286022UL, 366604999UL,
155 2625579499UL, 790898158UL, 770833822UL, 815540197UL,
156 2747711781UL, 3570468835UL, 3976195842UL, 1257621341UL,
157 1198342980UL, 1860626190UL, 3247856686UL, 351473955UL,
158 993440563UL, 340807146UL, 1041994520UL, 3573925241UL,
159 480246395UL, 2104806831UL, 1020782793UL, 3362132583UL,
160 2272911358UL, 3440096248UL, 2356596804UL, 259492703UL,
161 3899500740UL, 252071876UL, 2177024041UL, 4284810959UL,
162 2775999888UL, 2653420445UL, 2876046047UL, 1025771859UL,
163 1994475651UL, 3564987377UL, 4112956647UL, 1821511719UL,
164 3113447247UL, 455315102UL, 1585273189UL, 2311494568UL,
165 774051541UL, 1898115372UL, 2637499516UL, 247231365UL,
166 1475014417UL, 803585727UL, 3911097303UL, 1714292230UL,
167 476579326UL, 2496900974UL, 3397613314UL, 341202244UL,
168 807790202UL, 4221326173UL, 499979741UL, 1301488547UL,
169 1056807896UL, 3525009458UL, 1174811641UL, 3049738746UL,
172 struct scst_vdisk_dev {
176 loff_t file_size; /* in bytes */
177 spinlock_t flags_lock;
179 * Below flags are protected by flags_lock or suspended activity
180 * with scst_vdisk_mutex.
182 unsigned int rd_only_flag:1;
183 unsigned int wt_flag:1;
184 unsigned int nv_cache:1;
185 unsigned int o_direct_flag:1;
186 unsigned int media_changed:1;
187 unsigned int prevent_allow_medium_removal:1;
188 unsigned int nullio:1;
189 unsigned int blockio:1;
190 unsigned int cdrom_empty:1;
191 unsigned int removable:1;
193 char name[16+1]; /* Name of virtual device,
194 must be <= SCSI Model + 1 */
195 char *file_name; /* File name */
197 struct scst_device *dev;
198 struct list_head vdisk_dev_list_entry;
201 struct scst_vdisk_tgt_dev {
203 * Used without locking since SCST core ensures that only commands
204 * with the same ORDERED type per tgt_dev can be processed
207 enum scst_cmd_queue_type last_write_cmd_queue_type;
210 struct scst_vdisk_thr {
211 struct scst_thr_data_hdr hdr;
213 struct block_device *bdev;
216 struct scst_vdisk_dev *virt_dev;
219 static struct kmem_cache *vdisk_thr_cachep;
221 static int vdisk_attach(struct scst_device *dev);
222 static void vdisk_detach(struct scst_device *dev);
223 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev);
224 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev);
225 static int vdisk_parse(struct scst_cmd *);
226 static int vdisk_do_job(struct scst_cmd *cmd);
227 static int vcdrom_parse(struct scst_cmd *);
228 static int vcdrom_exec(struct scst_cmd *cmd);
229 static void vdisk_exec_read(struct scst_cmd *cmd,
230 struct scst_vdisk_thr *thr, loff_t loff);
231 static void vdisk_exec_write(struct scst_cmd *cmd,
232 struct scst_vdisk_thr *thr, loff_t loff);
233 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
234 u64 lba_start, int write);
235 static void vdisk_exec_verify(struct scst_cmd *cmd,
236 struct scst_vdisk_thr *thr, loff_t loff);
237 static void vdisk_exec_read_capacity(struct scst_cmd *cmd);
238 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd);
239 static void vdisk_exec_inquiry(struct scst_cmd *cmd);
240 static void vdisk_exec_request_sense(struct scst_cmd *cmd);
241 static void vdisk_exec_mode_sense(struct scst_cmd *cmd);
242 static void vdisk_exec_mode_select(struct scst_cmd *cmd);
243 static void vdisk_exec_log(struct scst_cmd *cmd);
244 static void vdisk_exec_read_toc(struct scst_cmd *cmd);
245 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd);
246 static int vdisk_fsync(struct scst_vdisk_thr *thr,
247 loff_t loff, loff_t len, struct scst_cmd *cmd);
248 static int vdisk_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type);
249 static int vdisk_write_proc(char *buffer, char **start, off_t offset,
250 int length, int *eof, struct scst_dev_type *dev_type);
251 static int vcdrom_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type);
252 static int vcdrom_write_proc(char *buffer, char **start, off_t offset,
253 int length, int *eof, struct scst_dev_type *dev_type);
254 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
255 struct scst_tgt_dev *tgt_dev);
257 #define VDISK_TYPE { \
258 .name = VDISK_NAME, \
264 .dev_done_atomic = 1, \
265 .attach = vdisk_attach, \
266 .detach = vdisk_detach, \
267 .attach_tgt = vdisk_attach_tgt, \
268 .detach_tgt = vdisk_detach_tgt, \
269 .parse = vdisk_parse, \
270 .exec = vdisk_do_job, \
271 .read_proc = vdisk_read_proc, \
272 .write_proc = vdisk_write_proc, \
273 .task_mgmt_fn = vdisk_task_mgmt_fn, \
276 #define VDISK_BLK_TYPE { \
277 .name = VDISK_NAME "_blk", \
282 .dev_done_atomic = 1, \
284 .attach = vdisk_attach, \
285 .detach = vdisk_detach, \
286 .attach_tgt = vdisk_attach_tgt, \
287 .detach_tgt = vdisk_detach_tgt, \
288 .parse = vdisk_parse, \
289 .exec = vdisk_do_job, \
290 .task_mgmt_fn = vdisk_task_mgmt_fn, \
293 #define VCDROM_TYPE { \
294 .name = VCDROM_NAME, \
300 .dev_done_atomic = 1, \
301 .attach = vdisk_attach, \
302 .detach = vdisk_detach, \
303 .attach_tgt = vdisk_attach_tgt, \
304 .detach_tgt = vdisk_detach_tgt, \
305 .parse = vcdrom_parse, \
306 .exec = vcdrom_exec, \
307 .read_proc = vcdrom_read_proc, \
308 .write_proc = vcdrom_write_proc, \
309 .task_mgmt_fn = vdisk_task_mgmt_fn, \
312 static DEFINE_MUTEX(scst_vdisk_mutex);
313 static LIST_HEAD(vdisk_dev_list);
314 static LIST_HEAD(vcdrom_dev_list);
316 static struct scst_dev_type vdisk_devtype = VDISK_TYPE;
317 static struct scst_dev_type vdisk_blk_devtype = VDISK_BLK_TYPE;
318 static struct scst_dev_type vcdrom_devtype = VCDROM_TYPE;
320 static char *vdisk_proc_help_string =
321 "echo \"open|close NAME [FILE_NAME [BLOCK_SIZE] [WRITE_THROUGH "
322 "READ_ONLY O_DIRECT NULLIO NV_CACHE BLOCKIO]]\" >/proc/scsi_tgt/"
323 VDISK_NAME "/" VDISK_NAME "\n";
325 static char *vcdrom_proc_help_string =
326 "echo \"open|change|close NAME [FILE_NAME]\" "
327 ">/proc/scsi_tgt/" VCDROM_NAME "/" VCDROM_NAME "\n";
329 static int scst_vdisk_ID;
331 module_param_named(scst_vdisk_ID, scst_vdisk_ID, int, 0);
332 MODULE_PARM_DESC(scst_vdisk_ID, "SCST virtual disk subsystem ID");
335 /**************************************************************
336 * Function: vdisk_open
340 * Returns : fd, use IS_ERR(fd) to get error status
343 *************************************************************/
344 static struct file *vdisk_open(const struct scst_vdisk_dev *virt_dev)
351 if (virt_dev->rd_only_flag)
352 open_flags |= O_RDONLY;
354 open_flags |= O_RDWR;
355 if (virt_dev->o_direct_flag)
356 open_flags |= O_DIRECT;
357 if (virt_dev->wt_flag && !virt_dev->nv_cache)
358 open_flags |= O_SYNC;
359 TRACE_DBG("Opening file %s, flags 0x%x", virt_dev->file_name, open_flags);
360 fd = filp_open(virt_dev->file_name, O_LARGEFILE | open_flags, 0600);
366 /**************************************************************
367 * Function: vdisk_attach
371 * Returns : 1 if attached, error code otherwise
374 *************************************************************/
375 static int vdisk_attach(struct scst_device *dev)
380 struct scst_vdisk_dev *virt_dev = NULL, *vv;
381 struct list_head *vd;
385 TRACE_DBG("virt_id %d (%s)", dev->virt_id, dev->virt_name);
387 if (dev->virt_id == 0) {
388 PRINT_ERROR("%s", "Not a virtual device");
393 vd = (dev->handler->type == TYPE_DISK) ?
398 * scst_vdisk_mutex must be already taken before
399 * scst_register_virtual_device()
401 list_for_each_entry(vv, vd, vdisk_dev_list_entry) {
402 if (strcmp(vv->name, dev->virt_name) == 0) {
408 if (virt_dev == NULL) {
409 PRINT_ERROR("Device %s not found", dev->virt_name);
416 if (dev->handler->type == TYPE_ROM)
417 virt_dev->rd_only_flag = 1;
419 if (!virt_dev->cdrom_empty) {
420 if (virt_dev->nullio)
421 err = 3LL*1024*1024*1024*1024/2;
425 fd = vdisk_open(virt_dev);
428 PRINT_ERROR("filp_open(%s) returned an error %d",
429 virt_dev->file_name, res);
433 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
434 if ((fd->f_op == NULL) || (fd->f_op->readv == NULL) ||
435 (fd->f_op->writev == NULL))
437 if ((fd->f_op == NULL) || (fd->f_op->aio_read == NULL) ||
438 (fd->f_op->aio_write == NULL))
441 PRINT_ERROR("%s", "Wrong f_op or FS doesn't have "
442 "required capabilities");
444 filp_close(fd, NULL);
448 inode = fd->f_dentry->d_inode;
450 if (virt_dev->blockio && !S_ISBLK(inode->i_mode)) {
451 PRINT_ERROR("File %s is NOT a block device",
452 virt_dev->file_name);
454 filp_close(fd, NULL);
458 if (S_ISREG(inode->i_mode))
460 else if (S_ISBLK(inode->i_mode))
461 inode = inode->i_bdev->bd_inode;
464 filp_close(fd, NULL);
469 filp_close(fd, NULL);
471 virt_dev->file_size = err;
472 TRACE_DBG("size of file: %Ld", (uint64_t)err);
474 virt_dev->file_size = 0;
476 if (dev->handler->type == TYPE_DISK) {
477 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
479 virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
480 virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
481 virt_dev->nblocks = virt_dev->file_size >> DEF_CDROM_BLOCKSIZE_SHIFT;
484 if (!virt_dev->cdrom_empty) {
485 PRINT_INFO("Attached SCSI target virtual %s %s "
486 "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)",
487 (dev->handler->type == TYPE_DISK) ? "disk" : "cdrom",
488 virt_dev->name, virt_dev->file_name,
489 virt_dev->file_size >> 20, virt_dev->block_size,
490 virt_dev->nblocks, virt_dev->nblocks/64/32,
491 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less than 1" : "");
493 PRINT_INFO("Attached empty SCSI target virtual cdrom %s",
497 dev->dh_priv = virt_dev;
500 if (virt_dev->wt_flag && !virt_dev->nv_cache)
501 dev->queue_alg = DEF_QUEUE_ALG_WT;
503 dev->queue_alg = DEF_QUEUE_ALG;
512 /************************************************************
513 * Function: vdisk_detach
519 * Description: Called to detach this device type driver
520 ************************************************************/
521 static void vdisk_detach(struct scst_device *dev)
523 struct scst_vdisk_dev *virt_dev =
524 (struct scst_vdisk_dev *)dev->dh_priv;
528 TRACE_DBG("virt_id %d", dev->virt_id);
530 PRINT_INFO("Detached SCSI target virtual device %s (\"%s\")",
531 virt_dev->name, virt_dev->file_name);
533 /* virt_dev will be freed by the caller */
540 static void vdisk_free_thr_data(struct scst_thr_data_hdr *d)
542 struct scst_vdisk_thr *thr = container_of(d, struct scst_vdisk_thr,
548 filp_close(thr->fd, NULL);
553 kmem_cache_free(vdisk_thr_cachep, thr);
559 static struct scst_vdisk_thr *vdisk_init_thr_data(
560 struct scst_tgt_dev *tgt_dev)
562 struct scst_vdisk_thr *res;
563 struct scst_vdisk_dev *virt_dev =
564 (struct scst_vdisk_dev *)tgt_dev->dev->dh_priv;
568 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
569 res = kmem_cache_alloc(vdisk_thr_cachep, GFP_KERNEL);
571 memset(res, 0, sizeof(*res));
573 res = kmem_cache_zalloc(vdisk_thr_cachep, GFP_KERNEL);
576 TRACE(TRACE_OUT_OF_MEM, "%s", "Unable to allocate struct "
581 res->virt_dev = virt_dev;
583 if (!virt_dev->cdrom_empty && !virt_dev->nullio) {
584 res->fd = vdisk_open(virt_dev);
585 if (IS_ERR(res->fd)) {
586 PRINT_ERROR("filp_open(%s) returned an error %ld",
587 virt_dev->file_name, PTR_ERR(res->fd));
590 if (virt_dev->blockio)
591 res->bdev = res->fd->f_dentry->d_inode->i_bdev;
597 scst_add_thr_data(tgt_dev, &res->hdr, vdisk_free_thr_data);
600 TRACE_EXIT_HRES((unsigned long)res);
604 kmem_cache_free(vdisk_thr_cachep, res);
609 static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev)
611 struct scst_vdisk_tgt_dev *ftgt_dev;
616 ftgt_dev = kzalloc(sizeof(*ftgt_dev), GFP_KERNEL);
617 if (ftgt_dev == NULL) {
618 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of per-session "
619 "virtual device failed");
624 tgt_dev->dh_priv = ftgt_dev;
631 static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev)
633 struct scst_vdisk_tgt_dev *ftgt_dev =
634 (struct scst_vdisk_tgt_dev *)tgt_dev->dh_priv;
638 scst_del_all_thr_data(tgt_dev);
641 tgt_dev->dh_priv = NULL;
647 static inline int vdisk_sync_queue_type(enum scst_cmd_queue_type qt)
650 case SCST_CMD_QUEUE_ORDERED:
651 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
658 static inline int vdisk_need_pre_sync(enum scst_cmd_queue_type cur,
659 enum scst_cmd_queue_type last)
661 if (vdisk_sync_queue_type(cur))
662 if (!vdisk_sync_queue_type(last))
667 static int vdisk_do_job(struct scst_cmd *cmd)
670 uint64_t lba_start = 0;
672 uint8_t *cdb = cmd->cdb;
675 struct scst_device *dev = cmd->dev;
676 struct scst_vdisk_dev *virt_dev =
677 (struct scst_vdisk_dev *)dev->dh_priv;
678 struct scst_thr_data_hdr *d;
679 struct scst_vdisk_thr *thr = NULL;
684 if (scst_cmd_atomic(cmd)) {
685 TRACE_DBG("%s", "vdisk exec() can not be done in atomic "
686 "context, requesting thread context");
687 res = SCST_EXEC_NEED_THREAD;
691 switch (cmd->queue_type) {
692 case SCST_CMD_QUEUE_ORDERED:
693 TRACE(TRACE_ORDER, "ORDERED cmd %p", cmd);
695 case SCST_CMD_QUEUE_HEAD_OF_QUEUE:
696 TRACE(TRACE_ORDER, "HQ cmd %p", cmd);
702 rc = scst_check_local_events(cmd);
703 if (unlikely(rc != 0))
708 cmd->host_status = DID_OK;
709 cmd->driver_status = 0;
711 d = scst_find_thr_data(cmd->tgt_dev);
712 if (unlikely(d == NULL)) {
713 thr = vdisk_init_thr_data(cmd->tgt_dev);
718 scst_thr_data_get(&thr->hdr);
720 thr = container_of(d, struct scst_vdisk_thr, hdr);
726 lba_start = (((cdb[1] & 0x1f) << (BYTE * 2)) +
727 (cdb[2] << (BYTE * 1)) +
728 (cdb[3] << (BYTE * 0)));
729 data_len = cmd->bufflen;
737 case WRITE_VERIFY_12:
739 lba_start |= ((u64)cdb[2]) << 24;
740 lba_start |= ((u64)cdb[3]) << 16;
741 lba_start |= ((u64)cdb[4]) << 8;
742 lba_start |= ((u64)cdb[5]);
743 data_len = cmd->bufflen;
747 case WRITE_VERIFY_16:
749 lba_start |= ((u64)cdb[2]) << 56;
750 lba_start |= ((u64)cdb[3]) << 48;
751 lba_start |= ((u64)cdb[4]) << 40;
752 lba_start |= ((u64)cdb[5]) << 32;
753 lba_start |= ((u64)cdb[6]) << 24;
754 lba_start |= ((u64)cdb[7]) << 16;
755 lba_start |= ((u64)cdb[8]) << 8;
756 lba_start |= ((u64)cdb[9]);
757 data_len = cmd->bufflen;
759 case SYNCHRONIZE_CACHE:
760 lba_start |= ((u64)cdb[2]) << 24;
761 lba_start |= ((u64)cdb[3]) << 16;
762 lba_start |= ((u64)cdb[4]) << 8;
763 lba_start |= ((u64)cdb[5]);
764 data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0)))
765 << virt_dev->block_shift;
767 data_len = virt_dev->file_size -
768 ((loff_t)lba_start << virt_dev->block_shift);
772 loff = (loff_t)lba_start << virt_dev->block_shift;
773 TRACE_DBG("cmd %p, lba_start %Ld, loff %Ld, data_len %Ld", cmd,
774 lba_start, (uint64_t)loff, (uint64_t)data_len);
775 if (unlikely(loff < 0) || unlikely(data_len < 0) ||
776 unlikely((loff + data_len) > virt_dev->file_size)) {
777 PRINT_INFO("Access beyond the end of the device "
778 "(%lld of %lld, len %Ld)", (uint64_t)loff,
779 (uint64_t)virt_dev->file_size, (uint64_t)data_len);
780 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
781 scst_sense_block_out_range_error));
789 fua = (cdb[1] & 0x8);
791 TRACE(TRACE_ORDER, "FUA: loff=%Ld, "
792 "data_len=%Ld", (uint64_t)loff,
803 if (virt_dev->blockio) {
804 blockio_exec_rw(cmd, thr, lba_start, 0);
807 vdisk_exec_read(cmd, thr, loff);
813 if (likely(!virt_dev->rd_only_flag)) {
814 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
815 struct scst_vdisk_tgt_dev *ftgt_dev =
816 (struct scst_vdisk_tgt_dev *)
817 cmd->tgt_dev->dh_priv;
818 enum scst_cmd_queue_type last_queue_type =
819 ftgt_dev->last_write_cmd_queue_type;
820 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
821 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
822 TRACE(TRACE_ORDER, "ORDERED "
823 "WRITE(%d): loff=%Ld, data_len=%Ld",
824 cmd->queue_type, (uint64_t)loff,
827 if (vdisk_fsync(thr, 0, 0, cmd) != 0)
830 if (virt_dev->blockio) {
831 blockio_exec_rw(cmd, thr, lba_start, 1);
834 vdisk_exec_write(cmd, thr, loff);
835 /* O_SYNC flag is used for WT devices */
837 vdisk_fsync(thr, loff, data_len, cmd);
839 TRACE(TRACE_MINOR, "Attempt to write to read-only "
840 "device %s", virt_dev->name);
841 scst_set_cmd_error(cmd,
842 SCST_LOAD_SENSE(scst_sense_data_protect));
846 case WRITE_VERIFY_12:
847 case WRITE_VERIFY_16:
848 if (likely(!virt_dev->rd_only_flag)) {
849 int do_fsync = vdisk_sync_queue_type(cmd->queue_type);
850 struct scst_vdisk_tgt_dev *ftgt_dev =
851 (struct scst_vdisk_tgt_dev *)
852 cmd->tgt_dev->dh_priv;
853 enum scst_cmd_queue_type last_queue_type =
854 ftgt_dev->last_write_cmd_queue_type;
855 ftgt_dev->last_write_cmd_queue_type = cmd->queue_type;
856 if (vdisk_need_pre_sync(cmd->queue_type, last_queue_type)) {
857 TRACE(TRACE_ORDER, "ORDERED "
858 "WRITE_VERIFY(%d): loff=%Ld, data_len=%Ld",
859 cmd->queue_type, (uint64_t)loff,
862 if (vdisk_fsync(thr, 0, 0, cmd) != 0)
865 /* ToDo: BLOCKIO VERIFY */
866 vdisk_exec_write(cmd, thr, loff);
867 /* O_SYNC flag is used for WT devices */
868 if (scsi_status_is_good(cmd->status))
869 vdisk_exec_verify(cmd, thr, loff);
871 vdisk_fsync(thr, loff, data_len, cmd);
873 TRACE(TRACE_MINOR, "Attempt to write to read-only "
874 "device %s", virt_dev->name);
875 scst_set_cmd_error(cmd,
876 SCST_LOAD_SENSE(scst_sense_data_protect));
879 case SYNCHRONIZE_CACHE:
881 int immed = cdb[1] & 0x2;
882 TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: "
883 "loff=%Ld, data_len=%Ld, immed=%d", (uint64_t)loff,
884 (uint64_t)data_len, immed);
888 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
889 vdisk_fsync(thr, loff, data_len, NULL);
890 /* ToDo: vdisk_fsync() error processing */
894 vdisk_fsync(thr, loff, data_len, cmd);
902 vdisk_exec_verify(cmd, thr, loff);
906 vdisk_exec_mode_sense(cmd);
910 vdisk_exec_mode_select(cmd);
916 case ALLOW_MEDIUM_REMOVAL:
917 vdisk_exec_prevent_allow_medium_removal(cmd);
920 vdisk_exec_read_toc(cmd);
923 vdisk_fsync(thr, 0, virt_dev->file_size, cmd);
929 case TEST_UNIT_READY:
932 vdisk_exec_inquiry(cmd);
935 vdisk_exec_request_sense(cmd);
938 vdisk_exec_read_capacity(cmd);
940 case SERVICE_ACTION_IN:
941 if ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) {
942 vdisk_exec_read_capacity16(cmd);
945 /* else go through */
948 TRACE_DBG("Invalid opcode %d", opcode);
949 scst_set_cmd_error(cmd,
950 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
957 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
960 if (likely(thr != NULL))
961 scst_thr_data_put(&thr->hdr);
963 res = SCST_EXEC_COMPLETED;
970 static int vdisk_get_block_shift(struct scst_cmd *cmd)
972 struct scst_vdisk_dev *virt_dev =
973 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
974 return virt_dev->block_shift;
977 /********************************************************************
978 * Function: vdisk_parse
982 * Returns : The state of the command
984 * Description: This does the parsing of the command
986 * Note: Not all states are allowed on return
987 ********************************************************************/
988 static int vdisk_parse(struct scst_cmd *cmd)
990 scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
991 return SCST_CMD_STATE_DEFAULT;
994 /********************************************************************
995 * Function: vcdrom_parse
999 * Returns : The state of the command
1001 * Description: This does the parsing of the command
1003 * Note: Not all states are allowed on return
1004 ********************************************************************/
1005 static int vcdrom_parse(struct scst_cmd *cmd)
1007 scst_cdrom_generic_parse(cmd, vdisk_get_block_shift);
1008 return SCST_CMD_STATE_DEFAULT;
1011 /********************************************************************
1012 * Function: vcdrom_exec
1019 ********************************************************************/
1020 static int vcdrom_exec(struct scst_cmd *cmd)
1022 int res = SCST_EXEC_COMPLETED;
1023 int opcode = cmd->cdb[0];
1024 struct scst_vdisk_dev *virt_dev =
1025 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1030 cmd->msg_status = 0;
1031 cmd->host_status = DID_OK;
1032 cmd->driver_status = 0;
1034 if (virt_dev->cdrom_empty && (opcode != INQUIRY)) {
1035 TRACE_DBG("%s", "CDROM empty");
1036 scst_set_cmd_error(cmd,
1037 SCST_LOAD_SENSE(scst_sense_not_ready));
1041 if (virt_dev->media_changed && (cmd->cdb[0] != INQUIRY) &&
1042 (cmd->cdb[0] != REQUEST_SENSE) && (cmd->cdb[0] != REPORT_LUNS)) {
1043 spin_lock(&virt_dev->flags_lock);
1044 if (virt_dev->media_changed) {
1045 virt_dev->media_changed = 0;
1046 TRACE_DBG("%s", "Reporting media changed");
1047 scst_set_cmd_error(cmd,
1048 SCST_LOAD_SENSE(scst_sense_medium_changed_UA));
1049 spin_unlock(&virt_dev->flags_lock);
1052 spin_unlock(&virt_dev->flags_lock);
1055 res = vdisk_do_job(cmd);
1058 TRACE_EXIT_RES(res);
1062 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
1066 static void vdisk_exec_inquiry(struct scst_cmd *cmd)
1068 int32_t length, len, i, resp_len = 0;
1071 struct scst_vdisk_dev *virt_dev =
1072 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1074 /* ToDo: Performance Boost:
1075 * 1. remove kzalloc, buf
1076 * 2. do all checks before touching *address
1078 * 4. write directly to *address
1083 buf = kzalloc(INQ_BUF_SZ,
1084 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1090 length = scst_get_buf_first(cmd, &address);
1091 TRACE_DBG("length %d", length);
1092 if (unlikely(length <= 0)) {
1093 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1094 scst_set_cmd_error(cmd,
1095 SCST_LOAD_SENSE(scst_sense_hardw_error));
1099 if (cmd->cdb[1] & CMDDT) {
1100 TRACE_DBG("%s", "INQUIRY: CMDDT is unsupported");
1101 scst_set_cmd_error(cmd,
1102 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1106 buf[0] = cmd->dev->handler->type; /* type dev */
1107 if ((buf[0] == TYPE_ROM) || virt_dev->removable)
1108 buf[1] = 0x80; /* removable */
1110 if (cmd->cdb[1] & EVPD) {
1114 for (dev_id_num = 0, i = 0; i < (int)strlen(virt_dev->name); i++) {
1115 unsigned int rv = random_values[(int)(virt_dev->name[i])];
1117 * Device name maximum length = 16,
1118 * do some rotating of the bits.
1120 dev_id_num ^= ((rv << i) | (rv >> (32 - i)));
1123 dev_id_num += scst_vdisk_ID;
1125 len = scnprintf(dev_id_str, 6, "%d", dev_id_num);
1126 TRACE_DBG("num %d, str <%s>, len %d",
1127 dev_id_num, dev_id_str, len);
1128 if (0 == cmd->cdb[2]) { /* supported vital product data pages */
1130 buf[4] = 0x0; /* this page */
1131 buf[5] = 0x80; /* unit serial number */
1132 buf[6] = 0x83; /* device identification */
1133 resp_len = buf[3] + 4;
1134 } else if (0x80 == cmd->cdb[2]) { /* unit serial number */
1136 if (virt_dev->usn == NULL) {
1137 buf[3] = MAX_USN_LEN;
1138 memset(&buf[4], 0x20, MAX_USN_LEN);
1142 if (strlen(virt_dev->usn) > MAX_USN_LEN)
1143 usn_len = MAX_USN_LEN;
1147 strncpy(&buf[4], virt_dev->usn, usn_len);
1149 resp_len = buf[3] + 4;
1150 } else if (0x83 == cmd->cdb[2]) { /* device identification */
1154 /* Two identification descriptors: */
1155 /* T10 vendor identifier field format (faked) */
1156 buf[num + 0] = 0x2; /* ASCII */
1159 if (virt_dev->blockio)
1160 memcpy(&buf[num + 4], SCST_BIO_VENDOR, 8);
1162 memcpy(&buf[num + 4], SCST_FIO_VENDOR, 8);
1163 memset(&buf[num + 12], ' ', 16);
1164 i = strlen(virt_dev->name);
1165 i = i < 16 ? i : 16;
1166 memcpy(&buf[num + 12], virt_dev->name, len);
1167 memcpy(&buf[num + 28], dev_id_str, len);
1168 buf[num + 3] = 8 + 16 + len;
1169 num += buf[num + 3] + 4;
1170 /* NAA IEEE registered identifier (faked) */
1171 buf[num] = 0x1; /* binary */
1175 buf[num + 4] = 0x51; /* ieee company id=0x123456 (faked) */
1176 buf[num + 5] = 0x23;
1177 buf[num + 6] = 0x45;
1178 buf[num + 7] = 0x60;
1179 buf[num + 8] = (dev_id_num >> 24);
1180 buf[num + 9] = (dev_id_num >> 16) & 0xff;
1181 buf[num + 10] = (dev_id_num >> 8) & 0xff;
1182 buf[num + 11] = dev_id_num & 0xff;
1184 resp_len = num + 12 - 4;
1185 buf[2] = (resp_len >> 8) & 0xFF;
1186 buf[3] = resp_len & 0xFF;
1189 TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
1191 scst_set_cmd_error(cmd,
1192 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1196 if (cmd->cdb[2] != 0) {
1197 TRACE_DBG("INQUIRY: Unsupported page %x", cmd->cdb[2]);
1198 scst_set_cmd_error(cmd,
1199 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1203 buf[2] = 4; /* Device complies to this standard - SPC-2 */
1204 buf[3] = 2; /* data in format specified in this standard */
1205 buf[4] = 31; /* n - 4 = 35 - 4 = 31 for full 36 byte data */
1206 buf[6] = 0; buf[7] = 2; /* BQue = 0, CMDQUE = 1 commands queuing supported */
1208 /* 8 byte ASCII Vendor Identification of the target - left aligned */
1209 if (virt_dev->blockio)
1210 memcpy(&buf[8], SCST_BIO_VENDOR, 8);
1212 memcpy(&buf[8], SCST_FIO_VENDOR, 8);
1214 /* 16 byte ASCII Product Identification of the target - left aligned */
1215 memset(&buf[16], ' ', 16);
1216 len = strlen(virt_dev->name);
1217 len = len < 16 ? len : 16;
1218 memcpy(&buf[16], virt_dev->name, len);
1220 /* 4 byte ASCII Product Revision Level of the target - left aligned */
1221 memcpy(&buf[32], SCST_FIO_REV, 4);
1222 resp_len = buf[4] + 5;
1225 sBUG_ON(resp_len >= INQ_BUF_SZ);
1226 if (length > resp_len)
1228 memcpy(address, buf, length);
1231 scst_put_buf(cmd, address);
1232 if (length < cmd->resp_data_len)
1233 scst_set_resp_data_len(cmd, length);
1243 static void vdisk_exec_request_sense(struct scst_cmd *cmd)
1250 length = scst_get_buf_first(cmd, &address);
1251 TRACE_DBG("length %d", length);
1252 if (unlikely(length < SCST_STANDARD_SENSE_LEN)) {
1253 PRINT_ERROR("scst_get_buf_first() failed or too small "
1254 "requested buffer (returned %d)", length);
1255 scst_set_cmd_error(cmd,
1256 SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1263 scst_set_sense(address, length, SCST_LOAD_SENSE(scst_sense_no_sense));
1266 scst_put_buf(cmd, address);
1274 * <<Following mode pages info copied from ST318451LW with some corrections>>
1279 static int vdisk_err_recov_pg(unsigned char *p, int pcontrol,
1280 struct scst_vdisk_dev *virt_dev)
1281 { /* Read-Write Error Recovery page for mode_sense */
1282 const unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
1285 memcpy(p, err_recov_pg, sizeof(err_recov_pg));
1287 memset(p + 2, 0, sizeof(err_recov_pg) - 2);
1288 return sizeof(err_recov_pg);
1291 static int vdisk_disconnect_pg(unsigned char *p, int pcontrol,
1292 struct scst_vdisk_dev *virt_dev)
1293 { /* Disconnect-Reconnect page for mode_sense */
1294 const unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
1295 0, 0, 0, 0, 0, 0, 0, 0};
1297 memcpy(p, disconnect_pg, sizeof(disconnect_pg));
1299 memset(p + 2, 0, sizeof(disconnect_pg) - 2);
1300 return sizeof(disconnect_pg);
1303 static int vdisk_format_pg(unsigned char *p, int pcontrol,
1304 struct scst_vdisk_dev *virt_dev)
1305 { /* Format device page for mode_sense */
1306 const unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
1307 0, 0, 0, 0, 0, 0, 0, 0,
1308 0, 0, 0, 0, 0x40, 0, 0, 0};
1310 memcpy(p, format_pg, sizeof(format_pg));
1311 p[10] = (DEF_SECTORS_PER >> 8) & 0xff;
1312 p[11] = DEF_SECTORS_PER & 0xff;
1313 p[12] = (virt_dev->block_size >> 8) & 0xff;
1314 p[13] = virt_dev->block_size & 0xff;
1316 memset(p + 2, 0, sizeof(format_pg) - 2);
1317 return sizeof(format_pg);
1320 static int vdisk_caching_pg(unsigned char *p, int pcontrol,
1321 struct scst_vdisk_dev *virt_dev)
1322 { /* Caching page for mode_sense */
1323 const unsigned char caching_pg[] = {0x8, 18, 0x10, 0, 0xff, 0xff, 0, 0,
1324 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
1326 memcpy(p, caching_pg, sizeof(caching_pg));
1327 p[2] |= !(virt_dev->wt_flag || virt_dev->nv_cache) ? WCE : 0;
1329 memset(p + 2, 0, sizeof(caching_pg) - 2);
1330 return sizeof(caching_pg);
1333 static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol,
1334 struct scst_vdisk_dev *virt_dev)
1335 { /* Control mode page for mode_sense */
1336 const unsigned char ctrl_m_pg[] = {0xa, 0xa, 0, 0, 0, 0, 0, 0,
1339 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg));
1342 p[2] |= virt_dev->dev->tst << 5;
1343 p[3] |= virt_dev->dev->queue_alg << 4;
1344 p[4] |= virt_dev->dev->swp << 3;
1345 p[5] |= virt_dev->dev->tas << 6;
1348 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2);
1349 #if 0 /* Too early, see corresponding comment in vdisk_exec_mode_select() */
1357 p[2] |= DEF_TST << 5;
1358 if (virt_dev->wt_flag || virt_dev->nv_cache)
1359 p[3] |= DEF_QUEUE_ALG_WT << 4;
1361 p[3] |= DEF_QUEUE_ALG << 4;
1362 p[4] |= DEF_SWP << 3;
1363 p[5] |= DEF_TAS << 6;
1368 return sizeof(ctrl_m_pg);
1371 static int vdisk_iec_m_pg(unsigned char *p, int pcontrol,
1372 struct scst_vdisk_dev *virt_dev)
1373 { /* Informational Exceptions control mode page for mode_sense */
1374 const unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
1376 memcpy(p, iec_m_pg, sizeof(iec_m_pg));
1378 memset(p + 2, 0, sizeof(iec_m_pg) - 2);
1379 return sizeof(iec_m_pg);
1382 static void vdisk_exec_mode_sense(struct scst_cmd *cmd)
1387 struct scst_vdisk_dev *virt_dev;
1390 unsigned char dbd, type;
1391 int pcontrol, pcode, subpcode;
1392 unsigned char dev_spec;
1393 int msense_6, offset = 0, len;
1398 buf = kzalloc(MSENSE_BUF_SZ,
1399 scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
1405 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1406 blocksize = virt_dev->block_size;
1407 nblocks = virt_dev->nblocks;
1409 type = cmd->dev->handler->type; /* type dev */
1410 dbd = cmd->cdb[1] & DBD;
1411 pcontrol = (cmd->cdb[2] & 0xc0) >> 6;
1412 pcode = cmd->cdb[2] & 0x3f;
1413 subpcode = cmd->cdb[3];
1414 msense_6 = (MODE_SENSE == cmd->cdb[0]);
1415 dev_spec = (virt_dev->rd_only_flag ? WP : 0) | DPOFUA;
1417 length = scst_get_buf_first(cmd, &address);
1418 if (unlikely(length <= 0)) {
1419 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1420 scst_set_cmd_error(cmd,
1421 SCST_LOAD_SENSE(scst_sense_hardw_error));
1425 if (0x3 == pcontrol) {
1426 TRACE_DBG("%s", "MODE SENSE: Saving values not supported");
1427 scst_set_cmd_error(cmd,
1428 SCST_LOAD_SENSE(scst_sense_saving_params_unsup));
1442 if (0 != subpcode) { /* TODO: Control Extension page */
1443 TRACE_DBG("%s", "MODE SENSE: Only subpage 0 is supported");
1444 scst_set_cmd_error(cmd,
1445 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1450 /* Create block descriptor */
1451 buf[offset - 1] = 0x08; /* block descriptor length */
1452 if (nblocks >> 32) {
1453 buf[offset + 0] = 0xFF;
1454 buf[offset + 1] = 0xFF;
1455 buf[offset + 2] = 0xFF;
1456 buf[offset + 3] = 0xFF;
1458 buf[offset + 0] = (nblocks >> (BYTE * 3)) & 0xFF;/* num blks */
1459 buf[offset + 1] = (nblocks >> (BYTE * 2)) & 0xFF;
1460 buf[offset + 2] = (nblocks >> (BYTE * 1)) & 0xFF;
1461 buf[offset + 3] = (nblocks >> (BYTE * 0)) & 0xFF;
1463 buf[offset + 4] = 0; /* density code */
1464 buf[offset + 5] = (blocksize >> (BYTE * 2)) & 0xFF;/* blklen */
1465 buf[offset + 6] = (blocksize >> (BYTE * 1)) & 0xFF;
1466 buf[offset + 7] = (blocksize >> (BYTE * 0)) & 0xFF;
1468 offset += 8; /* increment offset */
1474 case 0x1: /* Read-Write error recovery page, direct access */
1475 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1478 case 0x2: /* Disconnect-Reconnect page, all devices */
1479 len = vdisk_disconnect_pg(bp, pcontrol, virt_dev);
1482 case 0x3: /* Format device page, direct access */
1483 len = vdisk_format_pg(bp, pcontrol, virt_dev);
1486 case 0x8: /* Caching page, direct access */
1487 len = vdisk_caching_pg(bp, pcontrol, virt_dev);
1490 case 0xa: /* Control Mode page, all devices */
1491 len = vdisk_ctrl_m_pg(bp, pcontrol, virt_dev);
1494 case 0x1c: /* Informational Exceptions Mode page, all devices */
1495 len = vdisk_iec_m_pg(bp, pcontrol, virt_dev);
1498 case 0x3f: /* Read all Mode pages */
1499 len = vdisk_err_recov_pg(bp, pcontrol, virt_dev);
1500 len += vdisk_disconnect_pg(bp + len, pcontrol, virt_dev);
1501 len += vdisk_format_pg(bp + len, pcontrol, virt_dev);
1502 len += vdisk_caching_pg(bp + len, pcontrol, virt_dev);
1503 len += vdisk_ctrl_m_pg(bp + len, pcontrol, virt_dev);
1504 len += vdisk_iec_m_pg(bp + len, pcontrol, virt_dev);
1508 TRACE_DBG("MODE SENSE: Unsupported page %x", pcode);
1509 scst_set_cmd_error(cmd,
1510 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1514 buf[0] = offset - 1;
1516 buf[0] = ((offset - 2) >> 8) & 0xff;
1517 buf[1] = (offset - 2) & 0xff;
1520 if (offset > length)
1522 memcpy(address, buf, offset);
1525 scst_put_buf(cmd, address);
1526 if (offset < cmd->resp_data_len)
1527 scst_set_resp_data_len(cmd, offset);
1537 static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt)
1543 if ((virt_dev->wt_flag == wt) || virt_dev->nullio || virt_dev->nv_cache)
1546 spin_lock(&virt_dev->flags_lock);
1547 virt_dev->wt_flag = wt;
1548 spin_unlock(&virt_dev->flags_lock);
1550 scst_dev_del_all_thr_data(virt_dev->dev);
1553 TRACE_EXIT_RES(res);
1557 static void vdisk_exec_mode_select(struct scst_cmd *cmd)
1561 struct scst_vdisk_dev *virt_dev;
1562 int mselect_6, offset;
1566 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1567 mselect_6 = (MODE_SELECT == cmd->cdb[0]);
1569 length = scst_get_buf_first(cmd, &address);
1570 if (unlikely(length <= 0)) {
1571 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1572 scst_set_cmd_error(cmd,
1573 SCST_LOAD_SENSE(scst_sense_hardw_error));
1577 if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) {
1578 TRACE(TRACE_MINOR|TRACE_SCSI, "MODE SELECT: Unsupported "
1579 "value(s) of PF and/or SP bits (cdb[1]=%x)",
1581 scst_set_cmd_error(cmd,
1582 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1592 if (address[offset - 1] == 8) {
1594 } else if (address[offset - 1] != 0) {
1595 PRINT_ERROR("%s", "MODE SELECT: Wrong parameters list "
1597 scst_set_cmd_error(cmd,
1598 SCST_LOAD_SENSE(scst_sense_invalid_field_in_parm_list));
1602 while (length > offset + 2) {
1603 if (address[offset] & PS) {
1604 PRINT_ERROR("%s", "MODE SELECT: Illegal PS bit");
1605 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1606 scst_sense_invalid_field_in_parm_list));
1609 if ((address[offset] & 0x3f) == 0x8) { /* Caching page */
1610 if (address[offset + 1] != 18) {
1611 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1612 "caching page request");
1613 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1614 scst_sense_invalid_field_in_parm_list));
1617 if (vdisk_set_wt(virt_dev,
1618 (address[offset + 2] & WCE) ? 0 : 1) != 0) {
1619 scst_set_cmd_error(cmd,
1620 SCST_LOAD_SENSE(scst_sense_hardw_error));
1625 * It's too early to implement it, since we can't control the backstorage
1626 * device parameters. ToDo
1628 } else if ((address[offset] & 0x3f) == 0xA) { /* Control page */
1629 if (address[offset + 1] != 0xA) {
1630 PRINT_ERROR("%s", "MODE SELECT: Invalid "
1631 "control page request");
1632 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1633 scst_sense_invalid_field_in_parm_list));
1638 PRINT_ERROR("MODE SELECT: Invalid request %x",
1639 address[offset] & 0x3f);
1640 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(
1641 scst_sense_invalid_field_in_parm_list));
1644 offset += address[offset + 1];
1648 scst_put_buf(cmd, address);
1655 static void vdisk_exec_log(struct scst_cmd *cmd)
1659 /* No log pages are supported */
1660 scst_set_cmd_error(cmd,
1661 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1667 static void vdisk_exec_read_capacity(struct scst_cmd *cmd)
1671 struct scst_vdisk_dev *virt_dev;
1674 uint8_t buffer[READ_CAP_LEN];
1678 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1679 blocksize = virt_dev->block_size;
1680 nblocks = virt_dev->nblocks;
1682 /* last block on the virt_dev is (nblocks-1) */
1683 memset(buffer, 0, sizeof(buffer));
1684 if (nblocks >> 32) {
1690 buffer[0] = ((nblocks - 1) >> (BYTE * 3)) & 0xFF;
1691 buffer[1] = ((nblocks - 1) >> (BYTE * 2)) & 0xFF;
1692 buffer[2] = ((nblocks - 1) >> (BYTE * 1)) & 0xFF;
1693 buffer[3] = ((nblocks - 1) >> (BYTE * 0)) & 0xFF;
1695 buffer[4] = (blocksize >> (BYTE * 3)) & 0xFF;
1696 buffer[5] = (blocksize >> (BYTE * 2)) & 0xFF;
1697 buffer[6] = (blocksize >> (BYTE * 1)) & 0xFF;
1698 buffer[7] = (blocksize >> (BYTE * 0)) & 0xFF;
1700 length = scst_get_buf_first(cmd, &address);
1701 if (unlikely(length <= 0)) {
1702 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1703 scst_set_cmd_error(cmd,
1704 SCST_LOAD_SENSE(scst_sense_hardw_error));
1708 if (length > READ_CAP_LEN)
1709 length = READ_CAP_LEN;
1710 memcpy(address, buffer, length);
1712 scst_put_buf(cmd, address);
1714 if (length < cmd->resp_data_len)
1715 scst_set_resp_data_len(cmd, length);
1722 static void vdisk_exec_read_capacity16(struct scst_cmd *cmd)
1726 struct scst_vdisk_dev *virt_dev;
1729 uint8_t buffer[READ_CAP16_LEN];
1733 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1734 blocksize = virt_dev->block_size;
1735 nblocks = virt_dev->nblocks - 1;
1737 memset(buffer, 0, sizeof(buffer));
1738 buffer[0] = nblocks >> 56;
1739 buffer[1] = (nblocks >> 48) & 0xFF;
1740 buffer[2] = (nblocks >> 40) & 0xFF;
1741 buffer[3] = (nblocks >> 32) & 0xFF;
1742 buffer[4] = (nblocks >> 24) & 0xFF;
1743 buffer[5] = (nblocks >> 16) & 0xFF;
1744 buffer[6] = (nblocks >> 8) & 0xFF;
1745 buffer[7] = nblocks& 0xFF;
1747 buffer[8] = (blocksize >> (BYTE * 3)) & 0xFF;
1748 buffer[9] = (blocksize >> (BYTE * 2)) & 0xFF;
1749 buffer[10] = (blocksize >> (BYTE * 1)) & 0xFF;
1750 buffer[11] = (blocksize >> (BYTE * 0)) & 0xFF;
1752 length = scst_get_buf_first(cmd, &address);
1753 if (unlikely(length <= 0)) {
1754 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1755 scst_set_cmd_error(cmd,
1756 SCST_LOAD_SENSE(scst_sense_hardw_error));
1760 if (length > READ_CAP16_LEN)
1761 length = READ_CAP16_LEN;
1762 memcpy(address, buffer, length);
1764 scst_put_buf(cmd, address);
1766 if (length < cmd->resp_data_len)
1767 scst_set_resp_data_len(cmd, length);
1774 static void vdisk_exec_read_toc(struct scst_cmd *cmd)
1776 int32_t length, off = 0;
1778 struct scst_vdisk_dev *virt_dev;
1780 uint8_t buffer[4+8+8] = { 0x00, 0x0a, 0x01, 0x01, 0x00, 0x14,
1781 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
1785 if (cmd->dev->handler->type != TYPE_ROM) {
1786 PRINT_ERROR("%s", "READ TOC for non-CDROM device");
1787 scst_set_cmd_error(cmd,
1788 SCST_LOAD_SENSE(scst_sense_invalid_opcode));
1792 if (cmd->cdb[2] & 0x0e/*Format*/) {
1793 PRINT_ERROR("%s", "READ TOC: invalid requested data format");
1794 scst_set_cmd_error(cmd,
1795 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1799 if ((cmd->cdb[6] != 0 && (cmd->cdb[2] & 0x01)) ||
1800 (cmd->cdb[6] > 1 && cmd->cdb[6] != 0xAA)) {
1801 PRINT_ERROR("READ TOC: invalid requested track number %x",
1803 scst_set_cmd_error(cmd,
1804 SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb));
1808 length = scst_get_buf_first(cmd, &address);
1809 if (unlikely(length <= 0)) {
1810 PRINT_ERROR("scst_get_buf_first() failed: %d", length);
1811 scst_set_cmd_error(cmd,
1812 SCST_LOAD_SENSE(scst_sense_hardw_error));
1816 virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1817 /* FIXME when you have > 8TB ROM device. */
1818 nblocks = (uint32_t)virt_dev->nblocks;
1821 memset(buffer, 0, sizeof(buffer));
1822 buffer[2] = 0x01; /* First Track/Session */
1823 buffer[3] = 0x01; /* Last Track/Session */
1825 if (cmd->cdb[6] <= 1)
1827 /* Fistr TOC Track Descriptor */
1828 buffer[off+1] = 0x14; /* ADDR 0x10 - Q Sub-channel encodes current position data
1829 CONTROL 0x04 - Data track, recoreded uninterrupted */
1830 buffer[off+2] = 0x01; /* Track Number */
1833 if (!(cmd->cdb[2] & 0x01))
1835 /* Lead-out area TOC Track Descriptor */
1836 buffer[off+1] = 0x14;
1837 buffer[off+2] = 0xAA; /* Track Number */
1838 buffer[off+4] = (nblocks >> (BYTE * 3)) & 0xFF; /* Track Start Address */
1839 buffer[off+5] = (nblocks >> (BYTE * 2)) & 0xFF;
1840 buffer[off+6] = (nblocks >> (BYTE * 1)) & 0xFF;
1841 buffer[off+7] = (nblocks >> (BYTE * 0)) & 0xFF;
1845 buffer[1] = off - 2; /* Data Length */
1849 memcpy(address, buffer, off);
1851 scst_put_buf(cmd, address);
1853 if (off < cmd->resp_data_len)
1854 scst_set_resp_data_len(cmd, off);
1861 static void vdisk_exec_prevent_allow_medium_removal(struct scst_cmd *cmd)
1863 struct scst_vdisk_dev *virt_dev =
1864 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1866 TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]);
1868 if (cmd->dev->handler->type == TYPE_ROM) {
1869 spin_lock(&virt_dev->flags_lock);
1870 virt_dev->prevent_allow_medium_removal =
1871 cmd->cdb[4] & 0x01 ? 1 : 0;
1872 spin_unlock(&virt_dev->flags_lock);
1878 static int vdisk_fsync(struct scst_vdisk_thr *thr,
1879 loff_t loff, loff_t len, struct scst_cmd *cmd)
1882 struct scst_vdisk_dev *virt_dev = thr->virt_dev;
1883 struct file *file = thr->fd;
1884 struct inode *inode;
1885 struct address_space *mapping;
1889 /* Hopefully, the compiler will generate the single comparison */
1890 if (virt_dev->nv_cache || virt_dev->blockio || virt_dev->wt_flag ||
1891 virt_dev->rd_only_flag || virt_dev->o_direct_flag ||
1895 inode = file->f_dentry->d_inode;
1896 mapping = file->f_mapping;
1898 res = sync_page_range(inode, mapping, loff, len);
1899 if (unlikely(res != 0)) {
1900 PRINT_ERROR("sync_page_range() failed (%d)", res);
1902 scst_set_cmd_error(cmd,
1903 SCST_LOAD_SENSE(scst_sense_write_error));
1907 /* ToDo: flush the device cache, if needed */
1910 TRACE_EXIT_RES(res);
1914 static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd,
1915 struct scst_vdisk_thr *thr)
1919 iv_count = scst_get_buf_count(cmd);
1920 if (iv_count > thr->iv_count) {
1921 if (thr->iv != NULL)
1923 thr->iv = kmalloc(sizeof(*thr->iv) * iv_count, GFP_KERNEL);
1924 if (thr->iv == NULL) {
1925 PRINT_ERROR("Unable to allocate iv (%d)", iv_count);
1929 thr->iv_count = iv_count;
1937 * copied from <ksrc>/fs/read_write.*
1939 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
1940 static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
1942 set_current_state(TASK_UNINTERRUPTIBLE);
1943 if (!kiocbIsKicked(iocb))
1946 kiocbClearKicked(iocb);
1947 __set_current_state(TASK_RUNNING);
1950 typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
1951 unsigned long, loff_t);
1953 ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
1954 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
1959 init_sync_kiocb(&kiocb, filp);
1960 kiocb.ki_pos = *ppos;
1961 kiocb.ki_left = len;
1962 kiocb.ki_nbytes = len;
1965 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
1966 if (ret != -EIOCBRETRY)
1968 wait_on_retry_sync_kiocb(&kiocb);
1971 if (ret == -EIOCBQUEUED)
1972 ret = wait_on_sync_kiocb(&kiocb);
1973 *ppos = kiocb.ki_pos;
1978 static void vdisk_exec_read(struct scst_cmd *cmd,
1979 struct scst_vdisk_thr *thr, loff_t loff)
1981 mm_segment_t old_fs;
1983 ssize_t length, full_len;
1985 struct scst_vdisk_dev *virt_dev =
1986 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
1987 struct file *fd = thr->fd;
1993 iv = vdisk_alloc_iv(cmd, thr);
2000 length = scst_get_buf_first(cmd, &address);
2001 while (length > 0) {
2005 iv[i].iov_base = address;
2006 iv[i].iov_len = length;
2007 length = scst_get_buf_next(cmd, &address);
2009 if (unlikely(length < 0)) {
2010 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2011 scst_set_cmd_error(cmd,
2012 SCST_LOAD_SENSE(scst_sense_hardw_error));
2019 TRACE_DBG("reading(iv_count %d, full_len %zd)", iv_count, full_len);
2020 if (virt_dev->nullio)
2024 if (fd->f_op->llseek) {
2025 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2027 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2030 PRINT_ERROR("lseek trouble %Ld != %Ld", (uint64_t)err,
2032 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
2036 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2037 err = fd->f_op->readv(fd, iv, iv_count, &fd->f_pos);
2039 err = do_sync_readv_writev(fd, iv, iv_count, full_len, &fd->f_pos, fd->f_op->aio_read);
2043 if ((err < 0) || (err < full_len)) {
2044 PRINT_ERROR("readv() returned %Ld from %zd", (uint64_t)err,
2049 scst_set_cmd_error(cmd,
2050 SCST_LOAD_SENSE(scst_sense_read_error));
2060 scst_put_buf(cmd, iv[i].iov_base);
2067 static void vdisk_exec_write(struct scst_cmd *cmd,
2068 struct scst_vdisk_thr *thr, loff_t loff)
2070 mm_segment_t old_fs;
2072 ssize_t length, full_len;
2074 struct scst_vdisk_dev *virt_dev =
2075 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2076 struct file *fd = thr->fd;
2077 struct iovec *iv, *eiv;
2078 int iv_count, eiv_count;
2082 iv = vdisk_alloc_iv(cmd, thr);
2088 length = scst_get_buf_first(cmd, &address);
2089 while (length > 0) {
2091 iv[iv_count].iov_base = address;
2092 iv[iv_count].iov_len = length;
2094 length = scst_get_buf_next(cmd, &address);
2096 if (unlikely(length < 0)) {
2097 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2098 scst_set_cmd_error(cmd,
2099 SCST_LOAD_SENSE(scst_sense_hardw_error));
2107 eiv_count = iv_count;
2109 TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len);
2111 if (virt_dev->nullio)
2115 if (fd->f_op->llseek) {
2116 err = fd->f_op->llseek(fd, loff, 0 /*SEEK_SET */);
2118 err = default_llseek(fd, loff, 0 /*SEEK_SET */);
2121 PRINT_ERROR("lseek trouble %Ld != %Ld", (uint64_t)err,
2123 scst_set_cmd_error(cmd,
2124 SCST_LOAD_SENSE(scst_sense_hardw_error));
2129 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
2130 err = fd->f_op->writev(fd, eiv, eiv_count, &fd->f_pos);
2132 err = do_sync_readv_writev(fd, iv, iv_count, full_len, &fd->f_pos,
2133 fd->f_op->aio_write);
2138 PRINT_ERROR("write() returned %Ld from %zd",
2139 (uint64_t)err, full_len);
2143 scst_set_cmd_error(cmd,
2144 SCST_LOAD_SENSE(scst_sense_write_error));
2147 } else if (err < full_len) {
2149 * Probably that's wrong, but sometimes write() returns
2150 * value less, than requested. Let's restart.
2152 int i, e = eiv_count;
2153 TRACE_MGMT_DBG("write() returned %d from %zd "
2154 "(iv_count=%d)", (int)err, full_len,
2157 PRINT_INFO("Suspicious: write() returned 0 from "
2158 "%zd (iv_count=%d)", full_len, eiv_count);
2161 for (i = 0; i < e; i++) {
2162 if (eiv->iov_len < err) {
2163 err -= eiv->iov_len;
2168 (uint8_t *)eiv->iov_base + err;
2169 eiv->iov_len -= err;
2180 while (iv_count > 0) {
2181 scst_put_buf(cmd, iv[iv_count-1].iov_base);
2190 struct blockio_work {
2191 atomic_t bios_inflight;
2192 struct scst_cmd *cmd;
2195 static inline void blockio_check_finish(struct blockio_work *blockio_work)
2197 /* Decrement the bios in processing, and if zero signal completion */
2198 if (atomic_dec_and_test(&blockio_work->bios_inflight)) {
2199 blockio_work->cmd->completed = 1;
2200 blockio_work->cmd->scst_cmd_done(blockio_work->cmd,
2201 SCST_CMD_STATE_DEFAULT);
2202 kfree(blockio_work);
2206 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2207 static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
2209 static void blockio_endio(struct bio *bio, int error)
2212 struct blockio_work *blockio_work = bio->bi_private;
2214 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2219 error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
2221 if (unlikely(error != 0)) {
2222 PRINT_ERROR("cmd %p returned error %d", blockio_work->cmd,
2225 * The race with other such bio's doesn't matter, since all
2226 * scst_set_cmd_error() calls do the same local to this cmd
2229 if (bio->bi_rw & WRITE)
2230 scst_set_cmd_error(blockio_work->cmd,
2231 SCST_LOAD_SENSE(scst_sense_write_error));
2233 scst_set_cmd_error(blockio_work->cmd,
2234 SCST_LOAD_SENSE(scst_sense_read_error));
2237 blockio_check_finish(blockio_work);
2240 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
2247 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
2248 u64 lba_start, int write)
2250 struct scst_vdisk_dev *virt_dev = thr->virt_dev;
2251 struct block_device *bdev = thr->bdev;
2252 struct request_queue *q = bdev_get_queue(bdev);
2253 int length, max_nr_vecs = 0;
2255 struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
2257 struct blockio_work *blockio_work;
2262 if (virt_dev->nullio)
2265 /* Allocate and initialize blockio_work struct */
2266 blockio_work = kmalloc(sizeof(*blockio_work), GFP_KERNEL);
2267 if (blockio_work == NULL)
2270 blockio_work->cmd = cmd;
2273 max_nr_vecs = min(bio_get_nr_vecs(bdev), BIO_MAX_PAGES);
2279 length = scst_get_buf_first(cmd, &address);
2280 while (length > 0) {
2281 int len, bytes, off, thislen;
2286 off = offset_in_page(addr);
2289 lba_start0 = lba_start;
2293 struct page *page = virt_to_page(addr);
2296 bio = bio_alloc(GFP_KERNEL, max_nr_vecs);
2298 PRINT_ERROR("Failed to create bio "
2299 "for data segment= %d cmd %p",
2300 cmd->get_sg_buf_entry_num, cmd);
2306 bio->bi_end_io = blockio_endio;
2307 bio->bi_sector = lba_start0 <<
2308 (virt_dev->block_shift - 9);
2309 bio->bi_bdev = bdev;
2310 bio->bi_private = blockio_work;
2311 #if 0 /* It could be win, but could be not, so a performance study is needed */
2312 bio->bi_rw |= 1 << BIO_RW_SYNC;
2317 tbio = tbio->bi_next = bio;
2320 bytes = min_t(unsigned int, len, PAGE_SIZE - off);
2322 rc = bio_add_page(bio, page, bytes, off);
2326 lba_start0 += thislen >> virt_dev->block_shift;
2337 lba_start += length >> virt_dev->block_shift;
2339 scst_put_buf(cmd, address);
2340 length = scst_get_buf_next(cmd, &address);
2343 /* +1 to prevent erroneous too early command completion */
2344 atomic_set(&blockio_work->bios_inflight, bios+1);
2349 hbio = hbio->bi_next;
2350 bio->bi_next = NULL;
2351 submit_bio(write, bio);
2354 if (q && q->unplug_fn)
2357 blockio_check_finish(blockio_work);
2366 hbio = hbio->bi_next;
2369 kfree(blockio_work);
2376 static void vdisk_exec_verify(struct scst_cmd *cmd,
2377 struct scst_vdisk_thr *thr, loff_t loff)
2379 mm_segment_t old_fs;
2381 ssize_t length, len_mem = 0;
2382 uint8_t *address_sav, *address;
2384 struct scst_vdisk_dev *virt_dev =
2385 (struct scst_vdisk_dev *)cmd->dev->dh_priv;
2386 struct file *fd = thr->fd;
2387 uint8_t *mem_verify = NULL;
2391 if (vdisk_fsync(thr, loff, cmd->bufflen, cmd) != 0)
2395 * Until the cache is cleared prior the verifying, there is not
2396 * much point in this code. ToDo.
2398 * Nevertherless, this code is valuable if the data have not read
2399 * from the file/disk yet.
2406 if (!virt_dev->nullio) {
2407 if (fd->f_op->llseek) {
2408 err = fd->f_op->llseek(fd, loff, 0/*SEEK_SET*/);
2410 err = default_llseek(fd, loff, 0/*SEEK_SET*/);
2413 PRINT_ERROR("lseek trouble %Ld != %Ld", (uint64_t)err,
2415 scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
2420 mem_verify = vmalloc(LEN_MEM);
2421 if (mem_verify == NULL) {
2422 PRINT_ERROR("Unable to allocate memory %d for verify",
2424 scst_set_cmd_error(cmd,
2425 SCST_LOAD_SENSE(scst_sense_hardw_error));
2429 length = scst_get_buf_first(cmd, &address);
2430 address_sav = address;
2431 if (!length && cmd->data_len) {
2432 length = cmd->data_len;
2437 while (length > 0) {
2438 len_mem = (length > LEN_MEM) ? LEN_MEM : length;
2439 TRACE_DBG("Verify: length %zd - len_mem %zd", length, len_mem);
2441 if (!virt_dev->nullio)
2442 err = fd->f_op->read(fd, (char *)mem_verify, len_mem, &fd->f_pos);
2445 if ((err < 0) || (err < len_mem)) {
2446 PRINT_ERROR("verify() returned %Ld from %zd",
2447 (uint64_t)err, len_mem);
2451 scst_set_cmd_error(cmd,
2452 SCST_LOAD_SENSE(scst_sense_read_error));
2454 scst_put_buf(cmd, address_sav);
2457 if (compare && memcmp(address, mem_verify, len_mem) != 0) {
2458 TRACE_DBG("Verify: error memcmp length %zd", length);
2459 scst_set_cmd_error(cmd,
2460 SCST_LOAD_SENSE(scst_sense_miscompare_error));
2461 scst_put_buf(cmd, address_sav);
2466 if (compare && length <= 0) {
2467 scst_put_buf(cmd, address_sav);
2468 length = scst_get_buf_next(cmd, &address);
2469 address_sav = address;
2474 PRINT_ERROR("scst_get_buf_() failed: %zd", length);
2475 scst_set_cmd_error(cmd,
2476 SCST_LOAD_SENSE(scst_sense_hardw_error));
2489 static inline struct scst_vdisk_dev *vdisk_alloc_dev(void)
2491 struct scst_vdisk_dev *dev;
2492 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2494 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of virtual "
2498 spin_lock_init(&dev->flags_lock);
2503 static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd,
2504 struct scst_tgt_dev *tgt_dev)
2508 if ((mcmd->fn == SCST_LUN_RESET) || (mcmd->fn == SCST_TARGET_RESET)) {
2509 /* Restore default values */
2510 struct scst_device *dev = tgt_dev->dev;
2511 struct scst_vdisk_dev *virt_dev =
2512 (struct scst_vdisk_dev *)dev->dh_priv;
2514 if (virt_dev->wt_flag && !virt_dev->nv_cache)
2515 dev->queue_alg = DEF_QUEUE_ALG_WT;
2517 dev->queue_alg = DEF_QUEUE_ALG;
2523 return SCST_DEV_TM_NOT_COMPLETED;
2527 * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is read
2529 static int vdisk_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type)
2532 struct scst_vdisk_dev *virt_dev;
2536 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
2541 seq_printf(seq, "%-17s %-11s %-11s %-15s %s\n",
2542 "Name", "Size(MB)", "Block size", "Options", "File name");
2544 list_for_each_entry(virt_dev, &vdisk_dev_list, vdisk_dev_list_entry) {
2546 seq_printf(seq, "%-17s %-11d %-12d", virt_dev->name,
2547 (uint32_t)(virt_dev->file_size >> 20),
2548 virt_dev->block_size);
2550 if (virt_dev->wt_flag) {
2551 seq_printf(seq, "WT ");
2554 if (virt_dev->nv_cache) {
2555 seq_printf(seq, "NV ");
2558 if (virt_dev->rd_only_flag) {
2559 seq_printf(seq, "RO ");
2562 if (virt_dev->o_direct_flag) {
2563 seq_printf(seq, "DR ");
2566 if (virt_dev->nullio) {
2567 seq_printf(seq, "NIO ");
2570 if (virt_dev->blockio) {
2571 seq_printf(seq, "BIO ");
2574 if (virt_dev->removable) {
2575 seq_printf(seq, "RM ");
2579 seq_printf(seq, " ");
2582 seq_printf(seq, "%s\n", virt_dev->file_name);
2584 mutex_unlock(&scst_vdisk_mutex);
2586 TRACE_EXIT_RES(res);
2590 static void vdisk_report_registering(const char *type,
2591 const struct scst_vdisk_dev *virt_dev)
2596 i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s ",
2597 type, virt_dev->name);
2600 if (virt_dev->wt_flag)
2601 i += snprintf(&buf[i], sizeof(buf) - i, " (WRITE_THROUGH");
2603 if (virt_dev->nv_cache)
2604 i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE",
2605 (j == i) ? "(" : ", ");
2607 if (virt_dev->rd_only_flag)
2608 i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY",
2609 (j == i) ? "(" : ", ");
2611 if (virt_dev->o_direct_flag)
2612 i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT",
2613 (j == i) ? "(" : ", ");
2615 if (virt_dev->nullio)
2616 i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO",
2617 (j == i) ? "(" : ", ");
2619 if (virt_dev->blockio)
2620 i += snprintf(&buf[i], sizeof(buf) - i, "%sBLOCKIO",
2621 (j == i) ? "(" : ", ");
2623 if (virt_dev->removable)
2624 i += snprintf(&buf[i], sizeof(buf) - i, "%sREMOVABLE",
2625 (j == i) ? "(" : ", ");
2628 PRINT_INFO("%s", buf);
2630 PRINT_INFO("%s)", buf);
2636 * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is written
2638 static int vdisk_write_proc(char *buffer, char **start, off_t offset,
2639 int length, int *eof, struct scst_dev_type *dev_type)
2641 int res = 0, action;
2642 char *p, *name, *file_name;
2643 struct scst_vdisk_dev *virt_dev, *vv;
2644 uint32_t block_size = DEF_DISK_BLOCKSIZE;
2645 int block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
2650 /* VERY UGLY code. You can rewrite it if you want */
2652 if (buffer[0] == '\0')
2655 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
2661 if (p[strlen(p) - 1] == '\n') {
2662 p[strlen(p) - 1] = '\0';
2664 if (!strncmp("close ", p, 6)) {
2667 } else if (!strncmp("open ", p, 5)) {
2671 PRINT_ERROR("Unknown action \"%s\"", p);
2676 while (isspace(*p) && *p != '\0')
2679 while (!isspace(*p) && *p != '\0')
2682 if (*name == '\0') {
2683 PRINT_ERROR("%s", "Name required");
2686 } else if (strlen(name) >= sizeof(virt_dev->name)) {
2687 PRINT_ERROR("Name is too long (max %zd "
2688 "characters)", sizeof(virt_dev->name)-1);
2693 if (action) { /* open */
2695 list_for_each_entry(vv, &vdisk_dev_list,
2696 vdisk_dev_list_entry)
2698 if (strcmp(vv->name, name) == 0) {
2704 PRINT_ERROR("Virtual device with name "
2705 "%s already exist", name);
2710 while (isspace(*p) && *p != '\0')
2713 while (!isspace(*p) && *p != '\0')
2716 if (*file_name == '\0') {
2717 PRINT_ERROR("%s", "File name required");
2722 virt_dev = vdisk_alloc_dev();
2723 if (virt_dev == NULL) {
2724 TRACE(TRACE_OUT_OF_MEM, "%s",
2725 "Allocation of virt_dev failed");
2730 while (isspace(*p) && *p != '\0')
2735 block_size = simple_strtoul(p, &pp, 0);
2737 if ((*p != '\0') && !isspace(*p)) {
2738 PRINT_ERROR("Parse error: \"%s\"", p);
2742 while (isspace(*p) && *p != '\0')
2745 block_shift = scst_calc_block_shift(block_size);
2746 if (block_shift < 9) {
2751 virt_dev->block_size = block_size;
2752 virt_dev->block_shift = block_shift;
2754 while (*p != '\0') {
2755 if (!strncmp("WRITE_THROUGH", p, 13)) {
2757 virt_dev->wt_flag = 1;
2758 TRACE_DBG("%s", "WRITE_THROUGH");
2759 } else if (!strncmp("NV_CACHE", p, 8)) {
2761 virt_dev->nv_cache = 1;
2762 TRACE_DBG("%s", "NON-VOLATILE CACHE");
2763 } else if (!strncmp("READ_ONLY", p, 9)) {
2765 virt_dev->rd_only_flag = 1;
2766 TRACE_DBG("%s", "READ_ONLY");
2767 } else if (!strncmp("O_DIRECT", p, 8)) {
2771 virt_dev->o_direct_flag = 1;
2772 TRACE_DBG("%s", "O_DIRECT");
2774 PRINT_INFO("%s flag doesn't currently"
2775 " work, ignoring it, use fileio_tgt "
2776 "in O_DIRECT mode instead", "O_DIRECT");
2778 } else if (!strncmp("NULLIO", p, 6)) {
2780 virt_dev->nullio = 1;
2781 TRACE_DBG("%s", "NULLIO");
2782 } else if (!strncmp("BLOCKIO", p, 7)) {
2784 virt_dev->blockio = 1;
2785 TRACE_DBG("%s", "BLOCKIO");
2786 } else if (!strncmp("REMOVABLE", p, 9)) {
2788 virt_dev->removable = 1;
2789 TRACE_DBG("%s", "REMOVABLE");
2791 PRINT_ERROR("Unknown flag \"%s\"", p);
2795 while (isspace(*p) && *p != '\0')
2799 if (!virt_dev->nullio && (*file_name != '/')) {
2800 PRINT_ERROR("File path \"%s\" is not "
2801 "absolute", file_name);
2806 strcpy(virt_dev->name, name);
2808 len = strlen(file_name) + 1;
2809 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
2810 if (virt_dev->file_name == NULL) {
2811 TRACE(TRACE_OUT_OF_MEM, "%s",
2812 "Allocation of file_name failed");
2816 strncpy(virt_dev->file_name, file_name, len);
2818 list_add_tail(&virt_dev->vdisk_dev_list_entry,
2821 if (virt_dev->blockio) {
2822 vdisk_report_registering("BLOCKIO", virt_dev);
2824 scst_register_virtual_device(&vdisk_blk_devtype,
2827 vdisk_report_registering("FILEIO", virt_dev);
2829 scst_register_virtual_device(&vdisk_devtype,
2832 if (virt_dev->virt_id < 0) {
2833 res = virt_dev->virt_id;
2834 goto out_free_vpath;
2836 TRACE_DBG("Added virt_dev (name %s, file name %s, "
2837 "id %d, block size %d) to "
2838 "vdisk_dev_list", virt_dev->name,
2839 virt_dev->file_name, virt_dev->virt_id,
2840 virt_dev->block_size);
2841 } else { /* close */
2843 list_for_each_entry(vv, &vdisk_dev_list,
2844 vdisk_dev_list_entry)
2846 if (strcmp(vv->name, name) == 0) {
2851 if (virt_dev == NULL) {
2852 PRINT_ERROR("Device %s not found", name);
2856 scst_unregister_virtual_device(virt_dev->virt_id);
2857 PRINT_INFO("Virtual device %s unregistered",
2859 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
2861 list_del(&virt_dev->vdisk_dev_list_entry);
2863 kfree(virt_dev->file_name);
2869 mutex_unlock(&scst_vdisk_mutex);
2872 TRACE_EXIT_RES(res);
2876 list_del(&virt_dev->vdisk_dev_list_entry);
2877 kfree(virt_dev->file_name);
2884 /* scst_vdisk_mutex supposed to be held */
2885 static int vcdrom_open(char *p, char *name)
2887 struct scst_vdisk_dev *virt_dev, *vv;
2894 list_for_each_entry(vv, &vcdrom_dev_list, vdisk_dev_list_entry)
2896 if (strcmp(vv->name, name) == 0) {
2902 PRINT_ERROR("Virtual device with name "
2903 "%s already exist", name);
2908 while (isspace(*p) && *p != '\0')
2911 while (!isspace(*p) && *p != '\0')
2914 if (*file_name == '\0') {
2916 TRACE_DBG("%s", "No media");
2917 } else if (*file_name != '/') {
2918 PRINT_ERROR("File path \"%s\" is not "
2919 "absolute", file_name);
2925 virt_dev = vdisk_alloc_dev();
2926 if (virt_dev == NULL) {
2927 TRACE(TRACE_OUT_OF_MEM, "%s",
2928 "Allocation of virt_dev failed");
2932 virt_dev->cdrom_empty = cdrom_empty;
2934 strcpy(virt_dev->name, name);
2936 if (!virt_dev->cdrom_empty) {
2937 len = strlen(file_name) + 1;
2938 virt_dev->file_name = kmalloc(len, GFP_KERNEL);
2939 if (virt_dev->file_name == NULL) {
2940 TRACE(TRACE_OUT_OF_MEM, "%s",
2941 "Allocation of file_name failed");
2945 strncpy(virt_dev->file_name, file_name, len);
2948 list_add_tail(&virt_dev->vdisk_dev_list_entry,
2951 PRINT_INFO("Registering virtual CDROM %s", name);
2954 scst_register_virtual_device(&vcdrom_devtype,
2956 if (virt_dev->virt_id < 0) {
2957 res = virt_dev->virt_id;
2958 goto out_free_vpath;
2960 TRACE_DBG("Added virt_dev (name %s file_name %s id %d) "
2961 "to vcdrom_dev_list", virt_dev->name,
2962 virt_dev->file_name, virt_dev->virt_id);
2968 list_del(&virt_dev->vdisk_dev_list_entry);
2969 kfree(virt_dev->file_name);
2976 /* scst_vdisk_mutex supposed to be held */
2977 static int vcdrom_close(char *name)
2979 struct scst_vdisk_dev *virt_dev, *vv;
2983 list_for_each_entry(vv, &vcdrom_dev_list,
2984 vdisk_dev_list_entry)
2986 if (strcmp(vv->name, name) == 0) {
2991 if (virt_dev == NULL) {
2992 PRINT_ERROR("Virtual device with name "
2993 "%s not found", name);
2997 scst_unregister_virtual_device(virt_dev->virt_id);
2998 PRINT_INFO("Virtual device %s unregistered",
3000 TRACE_DBG("virt_id %d unregister", virt_dev->virt_id);
3002 list_del(&virt_dev->vdisk_dev_list_entry);
3004 if (virt_dev->file_name)
3005 kfree(virt_dev->file_name);
3012 /* scst_vdisk_mutex supposed to be held */
3013 static int vcdrom_change(char *p, char *name)
3017 mm_segment_t old_fs;
3018 struct scst_vdisk_dev *virt_dev, *vv;
3019 char *file_name, *fn, *old_fn;
3024 list_for_each_entry(vv, &vcdrom_dev_list,
3025 vdisk_dev_list_entry)
3027 if (strcmp(vv->name, name) == 0) {
3032 if (virt_dev == NULL) {
3033 PRINT_ERROR("Virtual device with name "
3034 "%s not found", name);
3039 while (isspace(*p) && *p != '\0')
3042 while (!isspace(*p) && *p != '\0')
3045 if (*file_name == '\0') {
3046 virt_dev->cdrom_empty = 1;
3047 TRACE_DBG("%s", "No media");
3048 } else if (*file_name != '/') {
3049 PRINT_ERROR("File path \"%s\" is not "
3050 "absolute", file_name);
3054 virt_dev->cdrom_empty = 0;
3056 old_fn = virt_dev->file_name;
3058 if (!virt_dev->cdrom_empty && !virt_dev->nullio) {
3059 len = strlen(file_name) + 1;
3060 fn = kmalloc(len, GFP_KERNEL);
3062 TRACE(TRACE_OUT_OF_MEM, "%s",
3063 "Allocation of file_name failed");
3068 strncpy(fn, file_name, len);
3069 virt_dev->file_name = fn;
3071 fd = vdisk_open(virt_dev);
3074 PRINT_ERROR("filp_open(%s) returned an error %d",
3075 virt_dev->file_name, res);
3078 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
3079 if ((fd->f_op == NULL) || (fd->f_op->readv == NULL)) {
3081 if ((fd->f_op == NULL) || (fd->f_op->aio_read == NULL)) {
3083 PRINT_ERROR("%s", "Wrong f_op or FS doesn't "
3084 "have required capabilities");
3086 filp_close(fd, NULL);
3092 if (fd->f_op->llseek) {
3093 err = fd->f_op->llseek(fd, 0, 2/*SEEK_END*/);
3095 err = default_llseek(fd, 0, 2/*SEEK_END*/);
3098 filp_close(fd, NULL);
3101 PRINT_ERROR("llseek %s returned an error %d",
3102 virt_dev->file_name, res);
3109 virt_dev->file_name = fn;
3112 scst_suspend_activity();
3114 if (virt_dev->prevent_allow_medium_removal) {
3115 PRINT_ERROR("Prevent medium removal for "
3116 "virtual device with name %s", name);
3118 goto out_free_resume;
3121 virt_dev->file_size = err;
3122 virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
3123 if (!virt_dev->cdrom_empty)
3124 virt_dev->media_changed = 1;
3126 scst_dev_del_all_thr_data(virt_dev->dev);
3128 if (!virt_dev->cdrom_empty) {
3129 PRINT_INFO("Changed SCSI target virtual cdrom %s "
3130 "(file=\"%s\", fs=%LdMB, bs=%d, nblocks=%Ld, cyln=%Ld%s)",
3131 virt_dev->name, virt_dev->file_name,
3132 virt_dev->file_size >> 20, virt_dev->block_size,
3133 virt_dev->nblocks, virt_dev->nblocks/64/32,
3134 virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
3137 PRINT_INFO("Removed media from SCSI target virtual cdrom %s",
3145 scst_resume_activity();
3151 virt_dev->file_name = old_fn;
3156 virt_dev->file_name = old_fn;
3162 * Called when a file in the /proc/VCDROM_NAME/VCDROM_NAME is read
3164 static int vcdrom_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type)
3167 struct scst_vdisk_dev *virt_dev;
3171 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
3176 seq_printf(seq, "%-17s %-9s %s\n", "Name", "Size(MB)", "File name");
3178 list_for_each_entry(virt_dev, &vcdrom_dev_list,
3179 vdisk_dev_list_entry) {
3180 seq_printf(seq, "%-17s %-9d %s\n", virt_dev->name,
3181 (uint32_t)(virt_dev->file_size >> 20),
3182 virt_dev->file_name);
3185 mutex_unlock(&scst_vdisk_mutex);
3188 TRACE_EXIT_RES(res);
3193 * Called when a file in the /proc/VCDROM_NAME/VCDROM_NAME is written
3195 static int vcdrom_write_proc(char *buffer, char **start, off_t offset,
3196 int length, int *eof, struct scst_dev_type *dev_type)
3198 int res = 0, action;
3200 struct scst_vdisk_dev *virt_dev;
3204 if (mutex_lock_interruptible(&scst_vdisk_mutex) != 0) {
3210 if (p[strlen(p) - 1] == '\n') {
3211 p[strlen(p) - 1] = '\0';
3213 if (!strncmp("close ", p, 6)) {
3216 } else if (!strncmp("change ", p, 5)) {
3219 } else if (!strncmp("open ", p, 5)) {
3223 PRINT_ERROR("Unknown action \"%s\"", p);
3228 while (isspace(*p) && *p != '\0')
3231 while (!isspace(*p) && *p != '\0')
3234 if (*name == '\0') {
3235 PRINT_ERROR("%s", "Name required");
3238 } else if (strlen(name) >= sizeof(virt_dev->name)) {
3239 PRINT_ERROR("Name is too long (max %zd "
3240 "characters)", sizeof(virt_dev->name)-1);
3245 if (action == 2) { /* open */
3246 res = vcdrom_open(p, name);
3249 } else if (action == 1) { /* change */
3250 res = vcdrom_change(p, name);
3253 } else { /* close */
3254 res = vcdrom_close(name);
3261 mutex_unlock(&scst_vdisk_mutex);
3264 TRACE_EXIT_RES(res);
3268 static int vdisk_help_info_show(struct seq_file *seq, void *v)
3270 char *s = (char *)seq->private;
3274 seq_printf(seq, "%s", s);
3280 static struct scst_proc_data vdisk_help_proc_data = {
3281 SCST_DEF_RW_SEQ_OP(NULL)
3282 .show = vdisk_help_info_show,
3285 static int vdisk_proc_help_build(struct scst_dev_type *dev_type)
3288 struct proc_dir_entry *p, *root;
3292 root = scst_proc_get_dev_type_root(dev_type);
3293 vdisk_help_proc_data.data = (dev_type->type == TYPE_DISK) ?
3294 vdisk_proc_help_string :
3295 vcdrom_proc_help_string;
3296 p = scst_create_proc_entry(root, VDISK_PROC_HELP, &vdisk_help_proc_data);
3298 PRINT_ERROR("Not enough memory to register dev "
3299 "handler %s entry %s in /proc",
3300 dev_type->name, VDISK_PROC_HELP);
3304 TRACE_EXIT_RES(res);
3308 static void vdisk_proc_help_destroy(struct scst_dev_type *dev_type)
3310 struct proc_dir_entry *root;
3314 root = scst_proc_get_dev_type_root(dev_type);
3316 remove_proc_entry(VDISK_PROC_HELP, root);
3321 static int __init init_scst_vdisk(struct scst_dev_type *devtype)
3327 devtype->module = THIS_MODULE;
3329 res = scst_register_virtual_dev_driver(devtype);
3333 if (!devtype->no_proc) {
3334 res = scst_dev_handler_build_std_proc(devtype);
3338 res = vdisk_proc_help_build(devtype);
3340 goto out_destroy_proc;
3344 TRACE_EXIT_RES(res);
3348 if (!devtype->no_proc)
3349 scst_dev_handler_destroy_std_proc(devtype);
3352 scst_unregister_virtual_dev_driver(devtype);
3356 static void exit_scst_vdisk(struct scst_dev_type *devtype,
3357 struct list_head *vdisk_dev_list)
3361 mutex_lock(&scst_vdisk_mutex);
3363 struct scst_vdisk_dev *virt_dev;
3365 if (list_empty(vdisk_dev_list))
3368 virt_dev = list_entry(vdisk_dev_list->next, typeof(*virt_dev),
3369 vdisk_dev_list_entry);
3371 scst_unregister_virtual_device(virt_dev->virt_id);
3373 list_del(&virt_dev->vdisk_dev_list_entry);
3375 PRINT_INFO("Virtual device %s unregistered", virt_dev->name);
3376 TRACE_DBG("virt_id %d", virt_dev->virt_id);
3377 kfree(virt_dev->file_name);
3380 mutex_unlock(&scst_vdisk_mutex);
3382 if (!devtype->no_proc) {
3383 vdisk_proc_help_destroy(devtype);
3384 scst_dev_handler_destroy_std_proc(devtype);
3387 scst_unregister_virtual_dev_driver(devtype);
3393 static int __init init_scst_vdisk_driver(void)
3395 int res, num_threads;
3397 vdisk_thr_cachep = KMEM_CACHE(scst_vdisk_thr, SCST_SLAB_FLAGS);
3398 if (vdisk_thr_cachep == NULL) {
3403 num_threads = num_online_cpus() + 2;
3404 vdisk_devtype.threads_num = num_threads;
3405 vcdrom_devtype.threads_num = num_threads;
3407 res = init_scst_vdisk(&vdisk_devtype);
3411 res = init_scst_vdisk(&vdisk_blk_devtype);
3413 goto out_free_vdisk;
3415 res = init_scst_vdisk(&vcdrom_devtype);
3423 exit_scst_vdisk(&vdisk_blk_devtype, &vdisk_dev_list);
3426 exit_scst_vdisk(&vdisk_devtype, &vdisk_dev_list);
3429 kmem_cache_destroy(vdisk_thr_cachep);
3433 static void __exit exit_scst_vdisk_driver(void)
3435 exit_scst_vdisk(&vdisk_blk_devtype, &vdisk_dev_list);
3436 exit_scst_vdisk(&vdisk_devtype, &vdisk_dev_list);