#define DEF_VIRTUAL_GB 0
#define DEF_FAKE_RW 0
#define DEF_VPD_USE_HOSTNO 1
+#define DEF_SECTOR_SIZE 512
/* bit mask values for scsi_debug_opts */
#define SCSI_DEBUG_OPT_NOISE 1
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_sector_size = DEF_SECTOR_SIZE;
static int scsi_debug_cmnd_count = 0;
static int sdebug_cylinders_per; /* cylinders per surface */
static int sdebug_sectors_per; /* sectors per cylinder */
-/* default sector size is 512 bytes, 2**9 bytes */
-#define POW2_SECT_SIZE 9
-#define SECT_SIZE (1 << POW2_SECT_SIZE)
-#define SECT_SIZE_PER(TGT) SECT_SIZE
-
#define SDEBUG_MAX_PARTS 4
#define SDEBUG_SENSE_LEN 32
static char sdebug_proc_name[] = "scsi_debug";
-static int sdebug_driver_probe(struct device *);
-static int sdebug_driver_remove(struct device *);
static struct bus_type pseudo_lld_bus;
static struct device_driver sdebug_driverfs_driver = {
static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
0, 0, 0x0, 0x0};
-static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev);
-static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
- int asc, int asq);
-static void stop_all_queued(void);
-static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
-
static int sdebug_add_adapter(void);
static void sdebug_remove_adapter(void);
-static void sdebug_max_tgts_luns(void);
-static struct device pseudo_primary;
-static struct bus_type pseudo_lld_bus;
+static void sdebug_max_tgts_luns(void)
+{
+ struct sdebug_host_info *sdbg_host;
+ struct Scsi_Host *hpnt;
+
+ spin_lock(&sdebug_host_list_lock);
+ list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
+ hpnt = sdbg_host->shost;
+ if ((hpnt->this_id >= 0) &&
+ (scsi_debug_num_tgts > hpnt->this_id))
+ hpnt->max_id = scsi_debug_num_tgts + 1;
+ else
+ hpnt->max_id = scsi_debug_num_tgts;
+ /* scsi_debug_max_luns; */
+ hpnt->max_lun = SAM2_WLUN_REPORT_LUNS;
+ }
+ spin_unlock(&sdebug_host_list_lock);
+}
+
+static void mk_sense_buffer(struct sdebug_dev_info *devip, int key,
+ int asc, int asq)
+{
+ unsigned char *sbuff;
+
+ sbuff = devip->sense_buff;
+ memset(sbuff, 0, SDEBUG_SENSE_LEN);
+
+ scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq);
+
+ if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+ printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: "
+ "[0x%x,0x%x,0x%x]\n", key, asc, asq);
+}
static void get_data_transfer_info(unsigned char *cmd,
unsigned long long *lba, unsigned int *num)
return sizeof(vpdb0_data);
}
+static int inquiry_evpd_b1(unsigned char *arr)
+{
+ memset(arr, 0, 0x3c);
+ arr[0] = 0;
+ arr[1] = 1;
+
+ return 0x3c;
+}
#define SDEBUG_LONG_INQ_SZ 96
#define SDEBUG_MAX_INQ_ARR_SZ 584
arr[n++] = 0x88; /* SCSI ports */
arr[n++] = 0x89; /* ATA information */
arr[n++] = 0xb0; /* Block limits (SBC) */
+ arr[n++] = 0xb1; /* Block characteristics (SBC) */
arr[3] = n - 4; /* number of supported VPD pages */
} else if (0x80 == cmd[2]) { /* unit serial number */
arr[1] = cmd[2]; /*sanity */
} else if (0xb0 == cmd[2]) { /* Block limits (SBC) */
arr[1] = cmd[2]; /*sanity */
arr[3] = inquiry_evpd_b0(&arr[4]);
+ } else if (0xb1 == cmd[2]) { /* Block characteristics (SBC) */
+ arr[1] = cmd[2]; /*sanity */
+ arr[3] = inquiry_evpd_b1(&arr[4]);
} else {
/* Illegal request, invalid field in cdb */
mk_sense_buffer(devip, ILLEGAL_REQUEST,
arr[2] = 0xff;
arr[3] = 0xff;
}
- arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff;
- arr[7] = SECT_SIZE_PER(target) & 0xff;
+ arr[6] = (scsi_debug_sector_size >> 8) & 0xff;
+ arr[7] = scsi_debug_sector_size & 0xff;
return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ);
}
capac = sdebug_capacity - 1;
for (k = 0; k < 8; ++k, capac >>= 8)
arr[7 - k] = capac & 0xff;
- arr[8] = (SECT_SIZE_PER(target) >> 24) & 0xff;
- arr[9] = (SECT_SIZE_PER(target) >> 16) & 0xff;
- arr[10] = (SECT_SIZE_PER(target) >> 8) & 0xff;
- arr[11] = SECT_SIZE_PER(target) & 0xff;
+ arr[8] = (scsi_debug_sector_size >> 24) & 0xff;
+ arr[9] = (scsi_debug_sector_size >> 16) & 0xff;
+ arr[10] = (scsi_debug_sector_size >> 8) & 0xff;
+ arr[11] = scsi_debug_sector_size & 0xff;
return fill_from_dev_buffer(scp, arr,
min(alloc_len, SDEBUG_READCAP16_ARR_SZ));
}
static int resp_format_pg(unsigned char * p, int pcontrol, int target)
{ /* Format device page for mode_sense */
- unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0x40, 0, 0, 0};
-
- memcpy(p, format_pg, sizeof(format_pg));
- p[10] = (sdebug_sectors_per >> 8) & 0xff;
- p[11] = sdebug_sectors_per & 0xff;
- p[12] = (SECT_SIZE >> 8) & 0xff;
- p[13] = SECT_SIZE & 0xff;
- if (DEV_REMOVEABLE(target))
- p[20] |= 0x20; /* should agree with INQUIRY */
- if (1 == pcontrol)
- memset(p + 2, 0, sizeof(format_pg) - 2);
- return sizeof(format_pg);
+ unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0x40, 0, 0, 0};
+
+ memcpy(p, format_pg, sizeof(format_pg));
+ p[10] = (sdebug_sectors_per >> 8) & 0xff;
+ p[11] = sdebug_sectors_per & 0xff;
+ p[12] = (scsi_debug_sector_size >> 8) & 0xff;
+ p[13] = scsi_debug_sector_size & 0xff;
+ if (DEV_REMOVEABLE(target))
+ p[20] |= 0x20; /* should agree with INQUIRY */
+ if (1 == pcontrol)
+ memset(p + 2, 0, sizeof(format_pg) - 2);
+ return sizeof(format_pg);
}
static int resp_caching_pg(unsigned char * p, int pcontrol, int target)
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;
+ ap[6] = (scsi_debug_sector_size >> 8) & 0xff;
+ ap[7] = scsi_debug_sector_size & 0xff;
offset += bd_len;
ap = arr + offset;
} else if (16 == bd_len) {
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;
+ ap[12] = (scsi_debug_sector_size >> 24) & 0xff;
+ ap[13] = (scsi_debug_sector_size >> 16) & 0xff;
+ ap[14] = (scsi_debug_sector_size >> 8) & 0xff;
+ ap[15] = scsi_debug_sector_size & 0xff;
offset += bd_len;
ap = arr + offset;
}
if (block + num > sdebug_store_sectors)
rest = block + num - sdebug_store_sectors;
- ret = func(scmd, fake_storep + (block * SECT_SIZE),
- (num - rest) * SECT_SIZE);
+ ret = func(scmd, fake_storep + (block * scsi_debug_sector_size),
+ (num - rest) * scsi_debug_sector_size);
if (!ret && rest)
- ret = func(scmd, fake_storep, rest * SECT_SIZE);
+ ret = func(scmd, fake_storep, rest * scsi_debug_sector_size);
return ret;
}
write_unlock_irqrestore(&atomic_rw, iflags);
if (-1 == ret)
return (DID_ERROR << 16);
- else if ((ret < (num * SECT_SIZE)) &&
+ else if ((ret < (num * scsi_debug_sector_size)) &&
(SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, "
- " IO sent=%d bytes\n", num * SECT_SIZE, ret);
+ " IO sent=%d bytes\n", num * scsi_debug_sector_size, ret);
return 0;
}
spin_unlock_irqrestore(&queued_arr_lock, iflags);
}
-static int scsi_debug_slave_alloc(struct scsi_device * sdp)
-{
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n",
- sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
- set_bit(QUEUE_FLAG_BIDI, &sdp->request_queue->queue_flags);
- return 0;
-}
-
-static int scsi_debug_slave_configure(struct scsi_device * sdp)
-{
- struct sdebug_dev_info * devip;
-
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n",
- sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
- if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
- sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
- devip = devInfoReg(sdp);
- if (NULL == devip)
- return 1; /* no resources, will be marked offline */
- sdp->hostdata = devip;
- if (sdp->host->cmd_per_lun)
- scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
- sdp->host->cmd_per_lun);
- blk_queue_max_segment_size(sdp->request_queue, 256 * 1024);
- return 0;
-}
-
-static void scsi_debug_slave_destroy(struct scsi_device * sdp)
-{
- struct sdebug_dev_info * devip =
- (struct sdebug_dev_info *)sdp->hostdata;
-
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n",
- sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
- if (devip) {
- /* make this slot avaliable for re-use */
- devip->used = 0;
- sdp->hostdata = NULL;
- }
-}
-struct sdebug_dev_info *sdebug_device_create(struct sdebug_host_info *sdbg_host,
- gfp_t flags)
+static struct sdebug_dev_info *
+sdebug_device_create(struct sdebug_host_info *sdbg_host, gfp_t flags)
{
struct sdebug_dev_info *devip;
return open_devip;
}
-static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
- int asc, int asq)
+static int scsi_debug_slave_alloc(struct scsi_device *sdp)
{
- unsigned char *sbuff;
+ if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+ printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n",
+ sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
+ queue_flag_set_unlocked(QUEUE_FLAG_BIDI, sdp->request_queue);
+ return 0;
+}
- sbuff = devip->sense_buff;
- memset(sbuff, 0, SDEBUG_SENSE_LEN);
+static int scsi_debug_slave_configure(struct scsi_device *sdp)
+{
+ struct sdebug_dev_info *devip;
- scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq);
+ if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+ printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n",
+ sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
+ if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
+ sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
+ devip = devInfoReg(sdp);
+ if (NULL == devip)
+ return 1; /* no resources, will be marked offline */
+ sdp->hostdata = devip;
+ if (sdp->host->cmd_per_lun)
+ scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
+ sdp->host->cmd_per_lun);
+ blk_queue_max_segment_size(sdp->request_queue, 256 * 1024);
+ return 0;
+}
+
+static void scsi_debug_slave_destroy(struct scsi_device *sdp)
+{
+ struct sdebug_dev_info *devip =
+ (struct sdebug_dev_info *)sdp->hostdata;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: "
- "[0x%x,0x%x,0x%x]\n", key, asc, asq);
+ printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n",
+ sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
+ if (devip) {
+ /* make this slot avaliable for re-use */
+ devip->used = 0;
+ sdp->hostdata = NULL;
+ }
+}
+
+/* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */
+static int stop_queued_cmnd(struct scsi_cmnd *cmnd)
+{
+ unsigned long iflags;
+ int k;
+ struct sdebug_queued_cmd *sqcp;
+
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
+ sqcp = &queued_arr[k];
+ if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) {
+ del_timer_sync(&sqcp->cmnd_timer);
+ sqcp->in_use = 0;
+ sqcp->a_cmnd = NULL;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0;
+}
+
+/* Deletes (stops) timers of all queued commands */
+static void stop_all_queued(void)
+{
+ unsigned long iflags;
+ int k;
+ struct sdebug_queued_cmd *sqcp;
+
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
+ sqcp = &queued_arr[k];
+ if (sqcp->in_use && sqcp->a_cmnd) {
+ del_timer_sync(&sqcp->cmnd_timer);
+ sqcp->in_use = 0;
+ sqcp->a_cmnd = NULL;
+ }
+ }
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
}
static int scsi_debug_abort(struct scsi_cmnd * SCpnt)
return SUCCESS;
}
-/* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */
-static int stop_queued_cmnd(struct scsi_cmnd * cmnd)
-{
- unsigned long iflags;
- int k;
- struct sdebug_queued_cmd * sqcp;
-
- spin_lock_irqsave(&queued_arr_lock, iflags);
- for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
- sqcp = &queued_arr[k];
- if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) {
- del_timer_sync(&sqcp->cmnd_timer);
- sqcp->in_use = 0;
- sqcp->a_cmnd = NULL;
- break;
- }
- }
- spin_unlock_irqrestore(&queued_arr_lock, iflags);
- return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0;
-}
-
-/* Deletes (stops) timers of all queued commands */
-static void stop_all_queued(void)
-{
- unsigned long iflags;
- int k;
- struct sdebug_queued_cmd * sqcp;
-
- spin_lock_irqsave(&queued_arr_lock, iflags);
- for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
- sqcp = &queued_arr[k];
- if (sqcp->in_use && sqcp->a_cmnd) {
- del_timer_sync(&sqcp->cmnd_timer);
- sqcp->in_use = 0;
- sqcp->a_cmnd = NULL;
- }
- }
- spin_unlock_irqrestore(&queued_arr_lock, iflags);
-}
-
/* Initializes timers in queued array */
static void __init init_all_queued(void)
{
return 0;
}
}
-
/* 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
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_param_named(sector_size, scsi_debug_sector_size, int, S_IRUGO);
MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
MODULE_DESCRIPTION("SCSI debug adapter driver");
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)");
+MODULE_PARM_DESC(sector_size, "hardware sector size in bytes (def=512)");
static char sdebug_info[256];
scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth,
scsi_debug_cmnd_count, scsi_debug_delay,
scsi_debug_max_luns, scsi_debug_scsi_level,
- SECT_SIZE, sdebug_cylinders_per, sdebug_heads, sdebug_sectors_per,
- num_aborts, num_dev_resets, num_bus_resets, num_host_resets);
+ scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads,
+ sdebug_sectors_per, num_aborts, num_dev_resets, num_bus_resets,
+ num_host_resets);
if (pos < offset) {
len = 0;
begin = pos;
DRIVER_ATTR(vpd_use_hostno, S_IRUGO | S_IWUSR, sdebug_vpd_use_hostno_show,
sdebug_vpd_use_hostno_store);
+static ssize_t sdebug_sector_size_show(struct device_driver * ddp, char * buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%u\n", scsi_debug_sector_size);
+}
+DRIVER_ATTR(sector_size, S_IRUGO, sdebug_sector_size_show, NULL);
+
/* 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
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);
+ ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_sector_size);
return ret;
}
static void do_remove_driverfs_files(void)
{
+ driver_remove_file(&sdebug_driverfs_driver, &driver_attr_sector_size);
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_add_host);
}
+static void pseudo_0_release(struct device *dev)
+{
+ if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+ printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n");
+}
+
+static struct device pseudo_primary = {
+ .bus_id = "pseudo_0",
+ .release = pseudo_0_release,
+};
+
static int __init scsi_debug_init(void)
{
unsigned long sz;
int k;
int ret;
+ switch (scsi_debug_sector_size) {
+ case 512:
+ case 1024:
+ case 2048:
+ case 4096:
+ break;
+ default:
+ printk(KERN_ERR "scsi_debug_init: invalid sector_size %u\n",
+ scsi_debug_sector_size);
+ return -EINVAL;
+ }
+
if (scsi_debug_dev_size_mb < 1)
scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */
sz = (unsigned long)scsi_debug_dev_size_mb * 1048576;
- sdebug_store_sectors = sz / SECT_SIZE;
+ sdebug_store_sectors = sz / scsi_debug_sector_size;
sdebug_capacity = get_sdebug_capacity();
/* play around with geometry, don't waste too much on track 0 */
device_initcall(scsi_debug_init);
module_exit(scsi_debug_exit);
-static void pseudo_0_release(struct device * dev)
-{
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n");
-}
-
-static struct device pseudo_primary = {
- .bus_id = "pseudo_0",
- .release = pseudo_0_release,
-};
-
-static int pseudo_lld_bus_match(struct device *dev,
- struct device_driver *dev_driver)
-{
- return 1;
-}
-
-static struct bus_type pseudo_lld_bus = {
- .name = "pseudo",
- .match = pseudo_lld_bus_match,
- .probe = sdebug_driver_probe,
- .remove = sdebug_driver_remove,
-};
-
static void sdebug_release_adapter(struct device * dev)
{
struct sdebug_host_info *sdbg_host;
return 0;
}
-static void sdebug_max_tgts_luns(void)
+static int pseudo_lld_bus_match(struct device *dev,
+ struct device_driver *dev_driver)
{
- struct sdebug_host_info * sdbg_host;
- struct Scsi_Host *hpnt;
-
- spin_lock(&sdebug_host_list_lock);
- list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
- hpnt = sdbg_host->shost;
- if ((hpnt->this_id >= 0) &&
- (scsi_debug_num_tgts > hpnt->this_id))
- hpnt->max_id = scsi_debug_num_tgts + 1;
- else
- hpnt->max_id = scsi_debug_num_tgts;
- hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* scsi_debug_max_luns; */
- }
- spin_unlock(&sdebug_host_list_lock);
+ return 1;
}
+
+static struct bus_type pseudo_lld_bus = {
+ .name = "pseudo",
+ .match = pseudo_lld_bus_match,
+ .probe = sdebug_driver_probe,
+ .remove = sdebug_driver_remove,
+};