[SCSI] scsi_debug version 1.80
See http://www.torque.net/sg/sdebug26.html for more information on the scsi_debug driver. ChangeLog: - add 'vpd_use_hostno' parameter to allow simulated hosts to see the same set of targets (and luns). For testing multipath software. - add 'fake_rw' parameter to ignore the data in READ and WRITE commands - add support for log subpages (new in SPC-4) - yield appropriate block descriptor for MODE SENSE commands (only for pdt=0 (i.e. disks)) - REQUEST SENSE response no longer shows the stopped power condition (SAT changed to agree with SPC-3) Signed-off-by: Douglas Gilbert <dougg@torque.net> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
c9802cd957
commit
231839102b
|
@ -1,5 +1,4 @@
|
|||
/*
|
||||
* linux/kernel/scsi_debug.c
|
||||
* vvvvvvvvvvvvvvvvvvvvvvv Original vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
* Copyright (C) 1992 Eric Youngdale
|
||||
* Simulate a host adapter with 2 disks attached. Do a lot of checking
|
||||
|
@ -8,7 +7,9 @@
|
|||
* ^^^^^^^^^^^^^^^^^^^^^^^ Original ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
*
|
||||
* This version is more generic, simulating a variable number of disk
|
||||
* (or disk like devices) sharing a common amount of RAM
|
||||
* (or disk like devices) sharing a common amount of RAM. To be more
|
||||
* realistic, the simulated devices have the transport attributes of
|
||||
* SAS disks.
|
||||
*
|
||||
*
|
||||
* For documentation see http://www.torque.net/sg/sdebug26.html
|
||||
|
@ -50,8 +51,8 @@
|
|||
#include "scsi_logging.h"
|
||||
#include "scsi_debug.h"
|
||||
|
||||
#define SCSI_DEBUG_VERSION "1.79"
|
||||
static const char * scsi_debug_version_date = "20060604";
|
||||
#define SCSI_DEBUG_VERSION "1.80"
|
||||
static const char * scsi_debug_version_date = "20060914";
|
||||
|
||||
/* Additional Sense Code (ASC) used */
|
||||
#define NO_ADDITIONAL_SENSE 0x0
|
||||
|
@ -86,6 +87,8 @@ static const char * scsi_debug_version_date = "20060604";
|
|||
#define DEF_D_SENSE 0
|
||||
#define DEF_NO_LUN_0 0
|
||||
#define DEF_VIRTUAL_GB 0
|
||||
#define DEF_FAKE_RW 0
|
||||
#define DEF_VPD_USE_HOSTNO 1
|
||||
|
||||
/* bit mask values for scsi_debug_opts */
|
||||
#define SCSI_DEBUG_OPT_NOISE 1
|
||||
|
@ -127,6 +130,8 @@ static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */
|
|||
static int scsi_debug_dsense = DEF_D_SENSE;
|
||||
static int scsi_debug_no_lun_0 = DEF_NO_LUN_0;
|
||||
static int scsi_debug_virtual_gb = DEF_VIRTUAL_GB;
|
||||
static int scsi_debug_fake_rw = DEF_FAKE_RW;
|
||||
static int scsi_debug_vpd_use_hostno = DEF_VPD_USE_HOSTNO;
|
||||
|
||||
static int scsi_debug_cmnd_count = 0;
|
||||
|
||||
|
@ -423,6 +428,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
|
|||
case READ_6:
|
||||
if ((errsts = check_readiness(SCpnt, 0, devip)))
|
||||
break;
|
||||
if (scsi_debug_fake_rw)
|
||||
break;
|
||||
if ((*cmd) == READ_16) {
|
||||
for (lba = 0, j = 0; j < 8; ++j) {
|
||||
if (j > 0)
|
||||
|
@ -465,6 +472,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
|
|||
case WRITE_6:
|
||||
if ((errsts = check_readiness(SCpnt, 0, devip)))
|
||||
break;
|
||||
if (scsi_debug_fake_rw)
|
||||
break;
|
||||
if ((*cmd) == WRITE_16) {
|
||||
for (lba = 0, j = 0; j < 8; ++j) {
|
||||
if (j > 0)
|
||||
|
@ -941,6 +950,8 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
|
|||
char lu_id_str[6];
|
||||
int host_no = devip->sdbg_host->shost->host_no;
|
||||
|
||||
if (0 == scsi_debug_vpd_use_hostno)
|
||||
host_no = 0;
|
||||
lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) +
|
||||
(devip->target * 1000) + devip->lun);
|
||||
target_dev_id = ((host_no + 1) * 2000) +
|
||||
|
@ -1059,19 +1070,6 @@ static int resp_requests(struct scsi_cmnd * scp,
|
|||
arr[12] = THRESHOLD_EXCEEDED;
|
||||
arr[13] = 0xff; /* TEST set and MRIE==6 */
|
||||
}
|
||||
} else if (devip->stopped) {
|
||||
if (want_dsense) {
|
||||
arr[0] = 0x72;
|
||||
arr[1] = 0x0; /* NO_SENSE in sense_key */
|
||||
arr[2] = LOW_POWER_COND_ON;
|
||||
arr[3] = 0x0; /* TEST set and MRIE==6 */
|
||||
} else {
|
||||
arr[0] = 0x70;
|
||||
arr[2] = 0x0; /* NO_SENSE in sense_key */
|
||||
arr[7] = 0xa; /* 18 byte sense buffer */
|
||||
arr[12] = LOW_POWER_COND_ON;
|
||||
arr[13] = 0x0; /* TEST set and MRIE==6 */
|
||||
}
|
||||
} else {
|
||||
memcpy(arr, sbuff, SDEBUG_SENSE_LEN);
|
||||
if ((cmd[1] & 1) && (! scsi_debug_dsense)) {
|
||||
|
@ -1325,21 +1323,26 @@ static int resp_sas_sha_m_spg(unsigned char * p, int pcontrol)
|
|||
static int resp_mode_sense(struct scsi_cmnd * scp, int target,
|
||||
struct sdebug_dev_info * devip)
|
||||
{
|
||||
unsigned char dbd;
|
||||
int pcontrol, pcode, subpcode;
|
||||
unsigned char dbd, llbaa;
|
||||
int pcontrol, pcode, subpcode, bd_len;
|
||||
unsigned char dev_spec;
|
||||
int alloc_len, msense_6, offset, len, errsts, target_dev_id;
|
||||
int k, alloc_len, msense_6, offset, len, errsts, target_dev_id;
|
||||
unsigned char * ap;
|
||||
unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
|
||||
unsigned char *cmd = (unsigned char *)scp->cmnd;
|
||||
|
||||
if ((errsts = check_readiness(scp, 1, devip)))
|
||||
return errsts;
|
||||
dbd = cmd[1] & 0x8;
|
||||
dbd = !!(cmd[1] & 0x8);
|
||||
pcontrol = (cmd[2] & 0xc0) >> 6;
|
||||
pcode = cmd[2] & 0x3f;
|
||||
subpcode = cmd[3];
|
||||
msense_6 = (MODE_SENSE == cmd[0]);
|
||||
llbaa = msense_6 ? 0 : !!(cmd[1] & 0x10);
|
||||
if ((0 == scsi_debug_ptype) && (0 == dbd))
|
||||
bd_len = llbaa ? 16 : 8;
|
||||
else
|
||||
bd_len = 0;
|
||||
alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[8]);
|
||||
memset(arr, 0, SDEBUG_MAX_MSENSE_SZ);
|
||||
if (0x3 == pcontrol) { /* Saving values not supported */
|
||||
|
@ -1349,15 +1352,58 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target,
|
|||
}
|
||||
target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) +
|
||||
(devip->target * 1000) - 3;
|
||||
dev_spec = DEV_READONLY(target) ? 0x80 : 0x0;
|
||||
/* set DPOFUA bit for disks */
|
||||
if (0 == scsi_debug_ptype)
|
||||
dev_spec = (DEV_READONLY(target) ? 0x80 : 0x0) | 0x10;
|
||||
else
|
||||
dev_spec = 0x0;
|
||||
if (msense_6) {
|
||||
arr[2] = dev_spec;
|
||||
arr[3] = bd_len;
|
||||
offset = 4;
|
||||
} else {
|
||||
arr[3] = dev_spec;
|
||||
if (16 == bd_len)
|
||||
arr[4] = 0x1; /* set LONGLBA bit */
|
||||
arr[7] = bd_len; /* assume 255 or less */
|
||||
offset = 8;
|
||||
}
|
||||
ap = arr + offset;
|
||||
if ((bd_len > 0) && (0 == sdebug_capacity)) {
|
||||
if (scsi_debug_virtual_gb > 0) {
|
||||
sdebug_capacity = 2048 * 1024;
|
||||
sdebug_capacity *= scsi_debug_virtual_gb;
|
||||
} else
|
||||
sdebug_capacity = sdebug_store_sectors;
|
||||
}
|
||||
if (8 == bd_len) {
|
||||
if (sdebug_capacity > 0xfffffffe) {
|
||||
ap[0] = 0xff;
|
||||
ap[1] = 0xff;
|
||||
ap[2] = 0xff;
|
||||
ap[3] = 0xff;
|
||||
} else {
|
||||
ap[0] = (sdebug_capacity >> 24) & 0xff;
|
||||
ap[1] = (sdebug_capacity >> 16) & 0xff;
|
||||
ap[2] = (sdebug_capacity >> 8) & 0xff;
|
||||
ap[3] = sdebug_capacity & 0xff;
|
||||
}
|
||||
ap[6] = (SECT_SIZE_PER(target) >> 8) & 0xff;
|
||||
ap[7] = SECT_SIZE_PER(target) & 0xff;
|
||||
offset += bd_len;
|
||||
ap = arr + offset;
|
||||
} else if (16 == bd_len) {
|
||||
unsigned long long capac = sdebug_capacity;
|
||||
|
||||
for (k = 0; k < 8; ++k, capac >>= 8)
|
||||
ap[7 - k] = capac & 0xff;
|
||||
ap[12] = (SECT_SIZE_PER(target) >> 24) & 0xff;
|
||||
ap[13] = (SECT_SIZE_PER(target) >> 16) & 0xff;
|
||||
ap[14] = (SECT_SIZE_PER(target) >> 8) & 0xff;
|
||||
ap[15] = SECT_SIZE_PER(target) & 0xff;
|
||||
offset += bd_len;
|
||||
ap = arr + offset;
|
||||
}
|
||||
|
||||
if ((subpcode > 0x0) && (subpcode < 0xff) && (0x19 != pcode)) {
|
||||
/* TODO: Control Extension page */
|
||||
|
@ -1471,7 +1517,7 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
|
|||
" IO sent=%d bytes\n", param_len, res);
|
||||
md_len = mselect6 ? (arr[0] + 1) : ((arr[0] << 8) + arr[1] + 2);
|
||||
bd_len = mselect6 ? arr[3] : ((arr[6] << 8) + arr[7]);
|
||||
if ((md_len > 2) || (0 != bd_len)) {
|
||||
if (md_len > 2) {
|
||||
mk_sense_buffer(devip, ILLEGAL_REQUEST,
|
||||
INVALID_FIELD_IN_PARAM_LIST, 0);
|
||||
return check_condition_result;
|
||||
|
@ -1544,7 +1590,7 @@ static int resp_ie_l_pg(unsigned char * arr)
|
|||
static int resp_log_sense(struct scsi_cmnd * scp,
|
||||
struct sdebug_dev_info * devip)
|
||||
{
|
||||
int ppc, sp, pcontrol, pcode, alloc_len, errsts, len, n;
|
||||
int ppc, sp, pcontrol, pcode, subpcode, alloc_len, errsts, len, n;
|
||||
unsigned char arr[SDEBUG_MAX_LSENSE_SZ];
|
||||
unsigned char *cmd = (unsigned char *)scp->cmnd;
|
||||
|
||||
|
@ -1560,23 +1606,63 @@ static int resp_log_sense(struct scsi_cmnd * scp,
|
|||
}
|
||||
pcontrol = (cmd[2] & 0xc0) >> 6;
|
||||
pcode = cmd[2] & 0x3f;
|
||||
subpcode = cmd[3] & 0xff;
|
||||
alloc_len = (cmd[7] << 8) + cmd[8];
|
||||
arr[0] = pcode;
|
||||
switch (pcode) {
|
||||
case 0x0: /* Supported log pages log page */
|
||||
n = 4;
|
||||
arr[n++] = 0x0; /* this page */
|
||||
arr[n++] = 0xd; /* Temperature */
|
||||
arr[n++] = 0x2f; /* Informational exceptions */
|
||||
arr[3] = n - 4;
|
||||
break;
|
||||
case 0xd: /* Temperature log page */
|
||||
arr[3] = resp_temp_l_pg(arr + 4);
|
||||
break;
|
||||
case 0x2f: /* Informational exceptions log page */
|
||||
arr[3] = resp_ie_l_pg(arr + 4);
|
||||
break;
|
||||
default:
|
||||
if (0 == subpcode) {
|
||||
switch (pcode) {
|
||||
case 0x0: /* Supported log pages log page */
|
||||
n = 4;
|
||||
arr[n++] = 0x0; /* this page */
|
||||
arr[n++] = 0xd; /* Temperature */
|
||||
arr[n++] = 0x2f; /* Informational exceptions */
|
||||
arr[3] = n - 4;
|
||||
break;
|
||||
case 0xd: /* Temperature log page */
|
||||
arr[3] = resp_temp_l_pg(arr + 4);
|
||||
break;
|
||||
case 0x2f: /* Informational exceptions log page */
|
||||
arr[3] = resp_ie_l_pg(arr + 4);
|
||||
break;
|
||||
default:
|
||||
mk_sense_buffer(devip, ILLEGAL_REQUEST,
|
||||
INVALID_FIELD_IN_CDB, 0);
|
||||
return check_condition_result;
|
||||
}
|
||||
} else if (0xff == subpcode) {
|
||||
arr[0] |= 0x40;
|
||||
arr[1] = subpcode;
|
||||
switch (pcode) {
|
||||
case 0x0: /* Supported log pages and subpages log page */
|
||||
n = 4;
|
||||
arr[n++] = 0x0;
|
||||
arr[n++] = 0x0; /* 0,0 page */
|
||||
arr[n++] = 0x0;
|
||||
arr[n++] = 0xff; /* this page */
|
||||
arr[n++] = 0xd;
|
||||
arr[n++] = 0x0; /* Temperature */
|
||||
arr[n++] = 0x2f;
|
||||
arr[n++] = 0x0; /* Informational exceptions */
|
||||
arr[3] = n - 4;
|
||||
break;
|
||||
case 0xd: /* Temperature subpages */
|
||||
n = 4;
|
||||
arr[n++] = 0xd;
|
||||
arr[n++] = 0x0; /* Temperature */
|
||||
arr[3] = n - 4;
|
||||
break;
|
||||
case 0x2f: /* Informational exceptions subpages */
|
||||
n = 4;
|
||||
arr[n++] = 0x2f;
|
||||
arr[n++] = 0x0; /* Informational exceptions */
|
||||
arr[3] = n - 4;
|
||||
break;
|
||||
default:
|
||||
mk_sense_buffer(devip, ILLEGAL_REQUEST,
|
||||
INVALID_FIELD_IN_CDB, 0);
|
||||
return check_condition_result;
|
||||
}
|
||||
} else {
|
||||
mk_sense_buffer(devip, ILLEGAL_REQUEST,
|
||||
INVALID_FIELD_IN_CDB, 0);
|
||||
return check_condition_result;
|
||||
|
@ -2151,11 +2237,18 @@ static int schedule_resp(struct scsi_cmnd * cmnd,
|
|||
}
|
||||
}
|
||||
|
||||
/* Note: The following macros create attribute files in the
|
||||
/sys/module/scsi_debug/parameters directory. Unfortunately this
|
||||
driver is unaware of a change and cannot trigger auxiliary actions
|
||||
as it can when the corresponding attribute in the
|
||||
/sys/bus/pseudo/drivers/scsi_debug directory is changed.
|
||||
*/
|
||||
module_param_named(add_host, scsi_debug_add_host, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(delay, scsi_debug_delay, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, S_IRUGO);
|
||||
module_param_named(dsense, scsi_debug_dsense, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(fake_rw, scsi_debug_fake_rw, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO);
|
||||
|
@ -2164,6 +2257,8 @@ module_param_named(opts, scsi_debug_opts, int, S_IRUGO | S_IWUSR);
|
|||
module_param_named(ptype, scsi_debug_ptype, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(scsi_level, scsi_debug_scsi_level, int, S_IRUGO);
|
||||
module_param_named(virtual_gb, scsi_debug_virtual_gb, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(vpd_use_hostno, scsi_debug_vpd_use_hostno, int,
|
||||
S_IRUGO | S_IWUSR);
|
||||
|
||||
MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
|
||||
MODULE_DESCRIPTION("SCSI debug adapter driver");
|
||||
|
@ -2175,6 +2270,7 @@ MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)");
|
|||
MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)");
|
||||
MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)");
|
||||
MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)");
|
||||
MODULE_PARM_DESC(fake_rw, "fake reads/writes instead of copying (def=0)");
|
||||
MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)");
|
||||
MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)");
|
||||
MODULE_PARM_DESC(num_parts, "number of partitions(def=0)");
|
||||
|
@ -2183,6 +2279,7 @@ MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->... (def=0)");
|
|||
MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
|
||||
MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
|
||||
MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)");
|
||||
MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)");
|
||||
|
||||
|
||||
static char sdebug_info[256];
|
||||
|
@ -2334,6 +2431,24 @@ static ssize_t sdebug_dsense_store(struct device_driver * ddp,
|
|||
DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show,
|
||||
sdebug_dsense_store);
|
||||
|
||||
static ssize_t sdebug_fake_rw_show(struct device_driver * ddp, char * buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_fake_rw);
|
||||
}
|
||||
static ssize_t sdebug_fake_rw_store(struct device_driver * ddp,
|
||||
const char * buf, size_t count)
|
||||
{
|
||||
int n;
|
||||
|
||||
if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
|
||||
scsi_debug_fake_rw = n;
|
||||
return count;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
DRIVER_ATTR(fake_rw, S_IRUGO | S_IWUSR, sdebug_fake_rw_show,
|
||||
sdebug_fake_rw_store);
|
||||
|
||||
static ssize_t sdebug_no_lun_0_show(struct device_driver * ddp, char * buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_no_lun_0);
|
||||
|
@ -2487,6 +2602,31 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
|
|||
DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show,
|
||||
sdebug_add_host_store);
|
||||
|
||||
static ssize_t sdebug_vpd_use_hostno_show(struct device_driver * ddp,
|
||||
char * buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_vpd_use_hostno);
|
||||
}
|
||||
static ssize_t sdebug_vpd_use_hostno_store(struct device_driver * ddp,
|
||||
const char * buf, size_t count)
|
||||
{
|
||||
int n;
|
||||
|
||||
if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
|
||||
scsi_debug_vpd_use_hostno = n;
|
||||
return count;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
DRIVER_ATTR(vpd_use_hostno, S_IRUGO | S_IWUSR, sdebug_vpd_use_hostno_show,
|
||||
sdebug_vpd_use_hostno_store);
|
||||
|
||||
/* Note: The following function creates attribute files in the
|
||||
/sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these
|
||||
files (over those found in the /sys/module/scsi_debug/parameters
|
||||
directory) is that auxiliary actions can be triggered when an attribute
|
||||
is changed. For example see: sdebug_add_host_store() above.
|
||||
*/
|
||||
static int do_create_driverfs_files(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -2496,23 +2636,31 @@ static int do_create_driverfs_files(void)
|
|||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_fake_rw);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb);
|
||||
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void do_remove_driverfs_files(void)
|
||||
{
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_no_lun_0);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_fake_rw);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dsense);
|
||||
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
|
||||
|
|
Loading…
Reference in New Issue