scsi_sysfs.c 37.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9
/*
 * scsi_sysfs.c
 *
 * SCSI sysfs interface routines.
 *
 * Created to pull SCSI mid layer sysfs routines into one file.
 */

#include <linux/module.h>
10
#include <linux/slab.h>
L
Linus Torvalds 已提交
11 12 13
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/device.h>
14
#include <linux/pm_runtime.h>
L
Linus Torvalds 已提交
15 16 17 18 19

#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
20
#include <scsi/scsi_dh.h>
L
Linus Torvalds 已提交
21
#include <scsi/scsi_transport.h>
A
Adrian Bunk 已提交
22
#include <scsi/scsi_driver.h>
L
Linus Torvalds 已提交
23 24 25 26

#include "scsi_priv.h"
#include "scsi_logging.h"

27 28
static struct device_type scsi_dev_type;

29
static const struct {
L
Linus Torvalds 已提交
30 31 32 33 34 35 36 37 38
	enum scsi_device_state	value;
	char			*name;
} sdev_states[] = {
	{ SDEV_CREATED, "created" },
	{ SDEV_RUNNING, "running" },
	{ SDEV_CANCEL, "cancel" },
	{ SDEV_DEL, "deleted" },
	{ SDEV_QUIESCE, "quiesce" },
	{ SDEV_OFFLINE,	"offline" },
39
	{ SDEV_TRANSPORT_OFFLINE, "transport-offline" },
L
Linus Torvalds 已提交
40
	{ SDEV_BLOCK,	"blocked" },
41
	{ SDEV_CREATED_BLOCK, "created-blocked" },
L
Linus Torvalds 已提交
42 43 44 45 46 47 48
};

const char *scsi_device_state_name(enum scsi_device_state state)
{
	int i;
	char *name = NULL;

49
	for (i = 0; i < ARRAY_SIZE(sdev_states); i++) {
L
Linus Torvalds 已提交
50 51 52 53 54 55 56 57
		if (sdev_states[i].value == state) {
			name = sdev_states[i].name;
			break;
		}
	}
	return name;
}

58
static const struct {
59 60 61 62 63 64 65 66
	enum scsi_host_state	value;
	char			*name;
} shost_states[] = {
	{ SHOST_CREATED, "created" },
	{ SHOST_RUNNING, "running" },
	{ SHOST_CANCEL, "cancel" },
	{ SHOST_DEL, "deleted" },
	{ SHOST_RECOVERY, "recovery" },
67 68
	{ SHOST_CANCEL_RECOVERY, "cancel/recovery" },
	{ SHOST_DEL_RECOVERY, "deleted/recovery", },
69 70 71 72 73 74
};
const char *scsi_host_state_name(enum scsi_host_state state)
{
	int i;
	char *name = NULL;

75
	for (i = 0; i < ARRAY_SIZE(shost_states); i++) {
76 77 78 79 80 81 82 83
		if (shost_states[i].value == state) {
			name = shost_states[i].name;
			break;
		}
	}
	return name;
}

84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
static const struct {
	unsigned char	value;
	char		*name;
} sdev_access_states[] = {
	{ SCSI_ACCESS_STATE_OPTIMAL, "active/optimized" },
	{ SCSI_ACCESS_STATE_ACTIVE, "active/non-optimized" },
	{ SCSI_ACCESS_STATE_STANDBY, "standby" },
	{ SCSI_ACCESS_STATE_UNAVAILABLE, "unavailable" },
	{ SCSI_ACCESS_STATE_LBA, "lba-dependent" },
	{ SCSI_ACCESS_STATE_OFFLINE, "offline" },
	{ SCSI_ACCESS_STATE_TRANSITIONING, "transitioning" },
};

const char *scsi_access_state_name(unsigned char state)
{
	int i;
	char *name = NULL;

	for (i = 0; i < ARRAY_SIZE(sdev_access_states); i++) {
		if (sdev_access_states[i].value == state) {
			name = sdev_access_states[i].name;
			break;
		}
	}
	return name;
}

H
Hannes Reinecke 已提交
111
static int check_set(unsigned long long *val, char *src)
L
Linus Torvalds 已提交
112 113 114 115 116 117 118 119 120
{
	char *last;

	if (strncmp(src, "-", 20) == 0) {
		*val = SCAN_WILD_CARD;
	} else {
		/*
		 * Doesn't check for int overflow
		 */
H
Hannes Reinecke 已提交
121
		*val = simple_strtoull(src, &last, 0);
L
Linus Torvalds 已提交
122 123 124 125 126 127 128 129
		if (*last != '\0')
			return 1;
	}
	return 0;
}

static int scsi_scan(struct Scsi_Host *shost, const char *str)
{
H
Hannes Reinecke 已提交
130 131
	char s1[15], s2[15], s3[17], junk;
	unsigned long long channel, id, lun;
L
Linus Torvalds 已提交
132 133
	int res;

H
Hannes Reinecke 已提交
134
	res = sscanf(str, "%10s %10s %16s %c", s1, s2, s3, &junk);
L
Linus Torvalds 已提交
135 136 137 138 139 140 141 142
	if (res != 3)
		return -EINVAL;
	if (check_set(&channel, s1))
		return -EINVAL;
	if (check_set(&id, s2))
		return -EINVAL;
	if (check_set(&lun, s3))
		return -EINVAL;
143 144 145 146
	if (shost->transportt->user_scan)
		res = shost->transportt->user_scan(shost, channel, id, lun);
	else
		res = scsi_scan_host_selected(shost, channel, id, lun, 1);
L
Linus Torvalds 已提交
147 148 149 150 151 152 153 154 155
	return res;
}

/*
 * shost_show_function: macro to create an attr function that can be used to
 * show a non-bit field.
 */
#define shost_show_function(name, field, format_string)			\
static ssize_t								\
156 157
show_##name (struct device *dev, struct device_attribute *attr, 	\
	     char *buf)							\
L
Linus Torvalds 已提交
158
{									\
159
	struct Scsi_Host *shost = class_to_shost(dev);			\
L
Linus Torvalds 已提交
160 161 162 163 164 165 166 167 168
	return snprintf (buf, 20, format_string, shost->field);		\
}

/*
 * shost_rd_attr: macro to create a function and attribute variable for a
 * read only field.
 */
#define shost_rd_attr2(name, field, format_string)			\
	shost_show_function(name, field, format_string)			\
169
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
L
Linus Torvalds 已提交
170 171 172 173 174 175 176 177

#define shost_rd_attr(field, format_string) \
shost_rd_attr2(field, field, format_string)

/*
 * Create the actual show/store functions and data structures.
 */

178 179 180
static ssize_t
store_scan(struct device *dev, struct device_attribute *attr,
	   const char *buf, size_t count)
L
Linus Torvalds 已提交
181
{
182
	struct Scsi_Host *shost = class_to_shost(dev);
L
Linus Torvalds 已提交
183 184 185 186 187 188 189
	int res;

	res = scsi_scan(shost, buf);
	if (res == 0)
		res = count;
	return res;
};
190
static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);
L
Linus Torvalds 已提交
191

192
static ssize_t
193 194
store_shost_state(struct device *dev, struct device_attribute *attr,
		  const char *buf, size_t count)
195 196
{
	int i;
197
	struct Scsi_Host *shost = class_to_shost(dev);
198 199
	enum scsi_host_state state = 0;

200
	for (i = 0; i < ARRAY_SIZE(shost_states); i++) {
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
		const int len = strlen(shost_states[i].name);
		if (strncmp(shost_states[i].name, buf, len) == 0 &&
		   buf[len] == '\n') {
			state = shost_states[i].value;
			break;
		}
	}
	if (!state)
		return -EINVAL;

	if (scsi_host_set_state(shost, state))
		return -EINVAL;
	return count;
}

static ssize_t
217
show_shost_state(struct device *dev, struct device_attribute *attr, char *buf)
218
{
219
	struct Scsi_Host *shost = class_to_shost(dev);
220 221 222 223 224 225 226 227
	const char *name = scsi_host_state_name(shost->shost_state);

	if (!name)
		return -EINVAL;

	return snprintf(buf, 20, "%s\n", name);
}

228 229 230
/* DEVICE_ATTR(state) clashes with dev_attr_state for sdev */
struct device_attribute dev_attr_hstate =
	__ATTR(state, S_IRUGO | S_IWUSR, show_shost_state, store_shost_state);
231

232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
static ssize_t
show_shost_mode(unsigned int mode, char *buf)
{
	ssize_t len = 0;

	if (mode & MODE_INITIATOR)
		len = sprintf(buf, "%s", "Initiator");

	if (mode & MODE_TARGET)
		len += sprintf(buf + len, "%s%s", len ? ", " : "", "Target");

	len += sprintf(buf + len, "\n");

	return len;
}

248 249 250
static ssize_t
show_shost_supported_mode(struct device *dev, struct device_attribute *attr,
			  char *buf)
251
{
252
	struct Scsi_Host *shost = class_to_shost(dev);
253
	unsigned int supported_mode = shost->hostt->supported_mode;
254

255 256 257 258 259
	if (supported_mode == MODE_UNKNOWN)
		/* by default this should be initiator */
		supported_mode = MODE_INITIATOR;

	return show_shost_mode(supported_mode, buf);
260 261
}

262
static DEVICE_ATTR(supported_mode, S_IRUGO | S_IWUSR, show_shost_supported_mode, NULL);
263

264 265 266
static ssize_t
show_shost_active_mode(struct device *dev,
		       struct device_attribute *attr, char *buf)
267
{
268
	struct Scsi_Host *shost = class_to_shost(dev);
269 270 271 272 273 274 275

	if (shost->active_mode == MODE_UNKNOWN)
		return snprintf(buf, 20, "unknown\n");
	else
		return show_shost_mode(shost->active_mode, buf);
}

276
static DEVICE_ATTR(active_mode, S_IRUGO | S_IWUSR, show_shost_active_mode, NULL);
277

278
static int check_reset_type(const char *str)
279
{
280
	if (sysfs_streq(str, "adapter"))
281
		return SCSI_ADAPTER_RESET;
282
	else if (sysfs_streq(str, "firmware"))
283 284 285 286 287 288 289 290 291 292 293 294 295 296
		return SCSI_FIRMWARE_RESET;
	else
		return 0;
}

static ssize_t
store_host_reset(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	struct scsi_host_template *sht = shost->hostt;
	int ret = -EINVAL;
	int type;

297
	type = check_reset_type(buf);
298 299 300 301 302 303 304 305 306 307 308 309 310 311
	if (!type)
		goto exit_store_host_reset;

	if (sht->host_reset)
		ret = sht->host_reset(shost, type);

exit_store_host_reset:
	if (ret == 0)
		ret = count;
	return ret;
}

static DEVICE_ATTR(host_reset, S_IWUSR, NULL, store_host_reset);

312 313 314 315 316 317
static ssize_t
show_shost_eh_deadline(struct device *dev,
		      struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);

318 319 320
	if (shost->eh_deadline == -1)
		return snprintf(buf, strlen("off") + 2, "off\n");
	return sprintf(buf, "%u\n", shost->eh_deadline / HZ);
321 322 323 324 325 326 327 328
}

static ssize_t
store_shost_eh_deadline(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	int ret = -EINVAL;
329
	unsigned long deadline, flags;
330

331 332 333
	if (shost->transportt &&
	    (shost->transportt->eh_strategy_handler ||
	     !shost->hostt->eh_host_reset_handler))
334 335
		return ret;

336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
	if (!strncmp(buf, "off", strlen("off")))
		deadline = -1;
	else {
		ret = kstrtoul(buf, 10, &deadline);
		if (ret)
			return ret;
		if (deadline * HZ > UINT_MAX)
			return -EINVAL;
	}

	spin_lock_irqsave(shost->host_lock, flags);
	if (scsi_host_in_recovery(shost))
		ret = -EBUSY;
	else {
		if (deadline == -1)
			shost->eh_deadline = -1;
		else
353
			shost->eh_deadline = deadline * HZ;
354 355

		ret = count;
356
	}
357 358
	spin_unlock_irqrestore(shost->host_lock, flags);

359 360 361 362 363
	return ret;
}

static DEVICE_ATTR(eh_deadline, S_IRUGO | S_IWUSR, show_shost_eh_deadline, store_shost_eh_deadline);

364
shost_rd_attr(use_blk_mq, "%d\n");
L
Linus Torvalds 已提交
365 366
shost_rd_attr(unique_id, "%u\n");
shost_rd_attr(cmd_per_lun, "%hd\n");
367
shost_rd_attr(can_queue, "%hd\n");
L
Linus Torvalds 已提交
368
shost_rd_attr(sg_tablesize, "%hu\n");
369
shost_rd_attr(sg_prot_tablesize, "%hu\n");
L
Linus Torvalds 已提交
370
shost_rd_attr(unchecked_isa_dma, "%d\n");
371 372
shost_rd_attr(prot_capabilities, "%u\n");
shost_rd_attr(prot_guard_type, "%hd\n");
L
Linus Torvalds 已提交
373 374
shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");

375 376 377 378 379 380 381 382
static ssize_t
show_host_busy(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	return snprintf(buf, 20, "%d\n", atomic_read(&shost->host_busy));
}
static DEVICE_ATTR(host_busy, S_IRUGO, show_host_busy, NULL);

383
static struct attribute *scsi_sysfs_shost_attrs[] = {
384
	&dev_attr_use_blk_mq.attr,
385 386 387 388 389
	&dev_attr_unique_id.attr,
	&dev_attr_host_busy.attr,
	&dev_attr_cmd_per_lun.attr,
	&dev_attr_can_queue.attr,
	&dev_attr_sg_tablesize.attr,
390
	&dev_attr_sg_prot_tablesize.attr,
391 392 393 394 395 396
	&dev_attr_unchecked_isa_dma.attr,
	&dev_attr_proc_name.attr,
	&dev_attr_scan.attr,
	&dev_attr_hstate.attr,
	&dev_attr_supported_mode.attr,
	&dev_attr_active_mode.attr,
397 398
	&dev_attr_prot_capabilities.attr,
	&dev_attr_prot_guard_type.attr,
399
	&dev_attr_host_reset.attr,
400
	&dev_attr_eh_deadline.attr,
401 402 403 404 405 406 407
	NULL
};

struct attribute_group scsi_shost_attr_group = {
	.attrs =	scsi_sysfs_shost_attrs,
};

408
const struct attribute_group *scsi_sysfs_shost_attr_groups[] = {
409
	&scsi_shost_attr_group,
L
Linus Torvalds 已提交
410 411 412
	NULL
};

413
static void scsi_device_cls_release(struct device *class_dev)
L
Linus Torvalds 已提交
414 415 416 417 418 419 420
{
	struct scsi_device *sdev;

	sdev = class_to_sdev(class_dev);
	put_device(&sdev->sdev_gendev);
}

421
static void scsi_device_dev_release_usercontext(struct work_struct *work)
L
Linus Torvalds 已提交
422 423 424
{
	struct scsi_device *sdev;
	struct device *parent;
425
	struct list_head *this, *tmp;
L
Linus Torvalds 已提交
426 427
	unsigned long flags;

428 429
	sdev = container_of(work, struct scsi_device, ew.work);

430 431
	scsi_dh_release_device(sdev);

432
	parent = sdev->sdev_gendev.parent;
L
Linus Torvalds 已提交
433 434 435 436 437 438 439

	spin_lock_irqsave(sdev->host->host_lock, flags);
	list_del(&sdev->siblings);
	list_del(&sdev->same_target_siblings);
	list_del(&sdev->starved_entry);
	spin_unlock_irqrestore(sdev->host->host_lock, flags);

440 441 442 443 444 445 446 447 448 449
	cancel_work_sync(&sdev->event_work);

	list_for_each_safe(this, tmp, &sdev->event_list) {
		struct scsi_event *evt;

		evt = list_entry(this, struct scsi_event, node);
		list_del(&evt->node);
		kfree(evt);
	}

450
	blk_put_queue(sdev->request_queue);
451 452
	/* NULL queue means the device can't be used */
	sdev->request_queue = NULL;
L
Linus Torvalds 已提交
453

454 455
	kfree(sdev->vpd_pg83);
	kfree(sdev->vpd_pg80);
L
Linus Torvalds 已提交
456 457 458 459 460 461 462
	kfree(sdev->inquiry);
	kfree(sdev);

	if (parent)
		put_device(parent);
}

463 464
static void scsi_device_dev_release(struct device *dev)
{
465
	struct scsi_device *sdp = to_scsi_device(dev);
466
	execute_in_process_context(scsi_device_dev_release_usercontext,
467
				   &sdp->ew);
468 469
}

A
Adrian Bunk 已提交
470
static struct class sdev_class = {
L
Linus Torvalds 已提交
471
	.name		= "scsi_device",
472
	.dev_release	= scsi_device_cls_release,
L
Linus Torvalds 已提交
473 474 475 476 477
};

/* all probing is done in the individual ->probe routines */
static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
{
478 479 480 481 482 483
	struct scsi_device *sdp;

	if (dev->type != &scsi_dev_type)
		return 0;

	sdp = to_scsi_device(dev);
L
Linus Torvalds 已提交
484 485 486 487 488
	if (sdp->no_uld_attach)
		return 0;
	return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
}

489
static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
490
{
491 492 493 494 495 496
	struct scsi_device *sdev;

	if (dev->type != &scsi_dev_type)
		return 0;

	sdev = to_scsi_device(dev);
497

498
	add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type);
499 500 501
	return 0;
}

L
Linus Torvalds 已提交
502 503 504
struct bus_type scsi_bus_type = {
        .name		= "scsi",
        .match		= scsi_bus_match,
505
	.uevent		= scsi_bus_uevent,
R
Rafael J. Wysocki 已提交
506
#ifdef CONFIG_PM
507
	.pm		= &scsi_bus_pm_ops,
508
#endif
L
Linus Torvalds 已提交
509
};
510
EXPORT_SYMBOL_GPL(scsi_bus_type);
L
Linus Torvalds 已提交
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537

int scsi_sysfs_register(void)
{
	int error;

	error = bus_register(&scsi_bus_type);
	if (!error) {
		error = class_register(&sdev_class);
		if (error)
			bus_unregister(&scsi_bus_type);
	}

	return error;
}

void scsi_sysfs_unregister(void)
{
	class_unregister(&sdev_class);
	bus_unregister(&scsi_bus_type);
}

/*
 * sdev_show_function: macro to create an attr function that can be used to
 * show a non-bit field.
 */
#define sdev_show_function(field, format_string)				\
static ssize_t								\
538 539
sdev_show_##field (struct device *dev, struct device_attribute *attr,	\
		   char *buf)						\
L
Linus Torvalds 已提交
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
{									\
	struct scsi_device *sdev;					\
	sdev = to_scsi_device(dev);					\
	return snprintf (buf, 20, format_string, sdev->field);		\
}									\

/*
 * sdev_rd_attr: macro to create a function and attribute variable for a
 * read only field.
 */
#define sdev_rd_attr(field, format_string)				\
	sdev_show_function(field, format_string)			\
static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL);


/*
556
 * sdev_rw_attr: create a function and attribute variable for a
L
Linus Torvalds 已提交
557 558 559 560 561 562
 * read/write field.
 */
#define sdev_rw_attr(field, format_string)				\
	sdev_show_function(field, format_string)				\
									\
static ssize_t								\
563 564
sdev_store_##field (struct device *dev, struct device_attribute *attr,	\
		    const char *buf, size_t count)			\
L
Linus Torvalds 已提交
565 566 567
{									\
	struct scsi_device *sdev;					\
	sdev = to_scsi_device(dev);					\
568
	sscanf (buf, format_string, &sdev->field);			\
L
Linus Torvalds 已提交
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
	return count;							\
}									\
static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field);

/* Currently we don't export bit fields, but we might in future,
 * so leave this code in */
#if 0
/*
 * sdev_rd_attr: create a function and attribute variable for a
 * read/write bit field.
 */
#define sdev_rw_attr_bit(field)						\
	sdev_show_function(field, "%d\n")					\
									\
static ssize_t								\
584 585
sdev_store_##field (struct device *dev, struct device_attribute *attr,	\
		    const char *buf, size_t count)			\
L
Linus Torvalds 已提交
586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624
{									\
	int ret;							\
	struct scsi_device *sdev;					\
	ret = scsi_sdev_check_buf_bit(buf);				\
	if (ret >= 0)	{						\
		sdev = to_scsi_device(dev);				\
		sdev->field = ret;					\
		ret = count;						\
	}								\
	return ret;							\
}									\
static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field);

/*
 * scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1",
 * else return -EINVAL.
 */
static int scsi_sdev_check_buf_bit(const char *buf)
{
	if ((buf[1] == '\0') || ((buf[1] == '\n') && (buf[2] == '\0'))) {
		if (buf[0] == '1')
			return 1;
		else if (buf[0] == '0')
			return 0;
		else 
			return -EINVAL;
	} else
		return -EINVAL;
}
#endif
/*
 * Create the actual show/store functions and data structures.
 */
sdev_rd_attr (type, "%d\n");
sdev_rd_attr (scsi_level, "%d\n");
sdev_rd_attr (vendor, "%.8s\n");
sdev_rd_attr (model, "%.16s\n");
sdev_rd_attr (rev, "%.4s\n");

625 626 627 628 629 630 631 632 633
static ssize_t
sdev_show_device_busy(struct device *dev, struct device_attribute *attr,
		char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	return snprintf(buf, 20, "%d\n", atomic_read(&sdev->device_busy));
}
static DEVICE_ATTR(device_busy, S_IRUGO, sdev_show_device_busy, NULL);

634 635 636 637 638 639 640 641 642
static ssize_t
sdev_show_device_blocked(struct device *dev, struct device_attribute *attr,
		char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	return snprintf(buf, 20, "%d\n", atomic_read(&sdev->device_blocked));
}
static DEVICE_ATTR(device_blocked, S_IRUGO, sdev_show_device_blocked, NULL);

J
Jens Axboe 已提交
643 644 645
/*
 * TODO: can we make these symlinks to the block layer ones?
 */
L
Linus Torvalds 已提交
646
static ssize_t
647
sdev_show_timeout (struct device *dev, struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
648 649 650
{
	struct scsi_device *sdev;
	sdev = to_scsi_device(dev);
J
Jens Axboe 已提交
651
	return snprintf(buf, 20, "%d\n", sdev->request_queue->rq_timeout / HZ);
L
Linus Torvalds 已提交
652 653 654
}

static ssize_t
655 656
sdev_store_timeout (struct device *dev, struct device_attribute *attr,
		    const char *buf, size_t count)
L
Linus Torvalds 已提交
657 658 659 660 661
{
	struct scsi_device *sdev;
	int timeout;
	sdev = to_scsi_device(dev);
	sscanf (buf, "%d\n", &timeout);
J
Jens Axboe 已提交
662
	blk_queue_rq_timeout(sdev->request_queue, timeout * HZ);
L
Linus Torvalds 已提交
663 664 665 666
	return count;
}
static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout);

667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
static ssize_t
sdev_show_eh_timeout(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct scsi_device *sdev;
	sdev = to_scsi_device(dev);
	return snprintf(buf, 20, "%u\n", sdev->eh_timeout / HZ);
}

static ssize_t
sdev_store_eh_timeout(struct device *dev, struct device_attribute *attr,
		    const char *buf, size_t count)
{
	struct scsi_device *sdev;
	unsigned int eh_timeout;
	int err;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;

	sdev = to_scsi_device(dev);
	err = kstrtouint(buf, 10, &eh_timeout);
	if (err)
		return err;
	sdev->eh_timeout = eh_timeout * HZ;

	return count;
}
static DEVICE_ATTR(eh_timeout, S_IRUGO | S_IWUSR, sdev_show_eh_timeout, sdev_store_eh_timeout);

L
Linus Torvalds 已提交
696
static ssize_t
697 698
store_rescan_field (struct device *dev, struct device_attribute *attr,
		    const char *buf, size_t count)
L
Linus Torvalds 已提交
699 700 701 702 703 704
{
	scsi_rescan_device(dev);
	return count;
}
static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field);

705 706 707
static ssize_t
sdev_store_delete(struct device *dev, struct device_attribute *attr,
		  const char *buf, size_t count)
L
Linus Torvalds 已提交
708
{
709 710
	if (device_remove_file_self(dev, attr))
		scsi_remove_device(to_scsi_device(dev));
L
Linus Torvalds 已提交
711 712 713 714 715
	return count;
};
static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete);

static ssize_t
716 717
store_state_field(struct device *dev, struct device_attribute *attr,
		  const char *buf, size_t count)
L
Linus Torvalds 已提交
718 719 720 721 722
{
	int i;
	struct scsi_device *sdev = to_scsi_device(dev);
	enum scsi_device_state state = 0;

723
	for (i = 0; i < ARRAY_SIZE(sdev_states); i++) {
L
Linus Torvalds 已提交
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
		const int len = strlen(sdev_states[i].name);
		if (strncmp(sdev_states[i].name, buf, len) == 0 &&
		   buf[len] == '\n') {
			state = sdev_states[i].value;
			break;
		}
	}
	if (!state)
		return -EINVAL;

	if (scsi_device_set_state(sdev, state))
		return -EINVAL;
	return count;
}

static ssize_t
740
show_state_field(struct device *dev, struct device_attribute *attr, char *buf)
L
Linus Torvalds 已提交
741 742 743 744 745 746 747 748 749 750 751 752 753
{
	struct scsi_device *sdev = to_scsi_device(dev);
	const char *name = scsi_device_state_name(sdev->sdev_state);

	if (!name)
		return -EINVAL;

	return snprintf(buf, 20, "%s\n", name);
}

static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_state_field, store_state_field);

static ssize_t
754 755
show_queue_type_field(struct device *dev, struct device_attribute *attr,
		      char *buf)
L
Linus Torvalds 已提交
756 757 758 759
{
	struct scsi_device *sdev = to_scsi_device(dev);
	const char *name = "none";

760
	if (sdev->simple_tags)
L
Linus Torvalds 已提交
761 762 763 764 765
		name = "simple";

	return snprintf(buf, 20, "%s\n", name);
}

766 767 768 769 770 771
static ssize_t
store_queue_type_field(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{
	struct scsi_device *sdev = to_scsi_device(dev);

772
	if (!sdev->tagged_supported)
773
		return -EINVAL;
774 775 776
		
	sdev_printk(KERN_INFO, sdev,
		    "ignoring write to deprecated queue_type attribute");
777 778 779 780 781
	return count;
}

static DEVICE_ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field,
		   store_queue_type_field);
L
Linus Torvalds 已提交
782

783 784 785 786 787 788 789 790
#define sdev_vpd_pg_attr(_page)						\
static ssize_t							\
show_vpd_##_page(struct file *filp, struct kobject *kobj,	\
		 struct bin_attribute *bin_attr,			\
		 char *buf, loff_t off, size_t count)			\
{									\
	struct device *dev = container_of(kobj, struct device, kobj);	\
	struct scsi_device *sdev = to_scsi_device(dev);			\
H
Hannes Reinecke 已提交
791
	int ret;							\
792 793
	if (!sdev->vpd_##_page)						\
		return -EINVAL;						\
H
Hannes Reinecke 已提交
794 795 796
	rcu_read_lock();						\
	ret = memory_read_from_buffer(buf, count, &off,			\
				      rcu_dereference(sdev->vpd_##_page), \
797
				       sdev->vpd_##_page##_len);	\
H
Hannes Reinecke 已提交
798 799
	rcu_read_unlock();						\
	return ret;						\
800 801 802 803 804 805 806 807 808
}									\
static struct bin_attribute dev_attr_vpd_##_page = {		\
	.attr =	{.name = __stringify(vpd_##_page), .mode = S_IRUGO },	\
	.size = 0,							\
	.read = show_vpd_##_page,					\
};

sdev_vpd_pg_attr(pg83);
sdev_vpd_pg_attr(pg80);
L
Linus Torvalds 已提交
809

810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
static ssize_t show_inquiry(struct file *filep, struct kobject *kobj,
			    struct bin_attribute *bin_attr,
			    char *buf, loff_t off, size_t count)
{
	struct device *dev = container_of(kobj, struct device, kobj);
	struct scsi_device *sdev = to_scsi_device(dev);

	if (!sdev->inquiry)
		return -EINVAL;

	return memory_read_from_buffer(buf, count, &off, sdev->inquiry,
				       sdev->inquiry_len);
}

static struct bin_attribute dev_attr_inquiry = {
	.attr = {
		.name = "inquiry",
		.mode = S_IRUGO,
	},
	.size = 0,
	.read = show_inquiry,
};

L
Linus Torvalds 已提交
833
static ssize_t
834 835
show_iostat_counterbits(struct device *dev, struct device_attribute *attr,
			char *buf)
L
Linus Torvalds 已提交
836 837 838 839 840 841 842 843
{
	return snprintf(buf, 20, "%d\n", (int)sizeof(atomic_t) * 8);
}

static DEVICE_ATTR(iocounterbits, S_IRUGO, show_iostat_counterbits, NULL);

#define show_sdev_iostat(field)						\
static ssize_t								\
844 845
show_iostat_##field(struct device *dev, struct device_attribute *attr,	\
		    char *buf)						\
L
Linus Torvalds 已提交
846 847 848 849 850 851 852 853 854 855 856
{									\
	struct scsi_device *sdev = to_scsi_device(dev);			\
	unsigned long long count = atomic_read(&sdev->field);		\
	return snprintf(buf, 20, "0x%llx\n", count);			\
}									\
static DEVICE_ATTR(field, S_IRUGO, show_iostat_##field, NULL)

show_sdev_iostat(iorequest_cnt);
show_sdev_iostat(iodone_cnt);
show_sdev_iostat(ioerr_cnt);

857 858 859 860 861 862 863 864
static ssize_t
sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct scsi_device *sdev;
	sdev = to_scsi_device(dev);
	return snprintf (buf, 20, SCSI_DEVICE_MODALIAS_FMT "\n", sdev->type);
}
static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL);
L
Linus Torvalds 已提交
865

866 867 868
#define DECLARE_EVT_SHOW(name, Cap_name)				\
static ssize_t								\
sdev_show_evt_##name(struct device *dev, struct device_attribute *attr,	\
869
		     char *buf)						\
870 871 872 873 874 875 876 877
{									\
	struct scsi_device *sdev = to_scsi_device(dev);			\
	int val = test_bit(SDEV_EVT_##Cap_name, sdev->supported_events);\
	return snprintf(buf, 20, "%d\n", val);				\
}

#define DECLARE_EVT_STORE(name, Cap_name)				\
static ssize_t								\
878
sdev_store_evt_##name(struct device *dev, struct device_attribute *attr,\
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899
		      const char *buf, size_t count)			\
{									\
	struct scsi_device *sdev = to_scsi_device(dev);			\
	int val = simple_strtoul(buf, NULL, 0);				\
	if (val == 0)							\
		clear_bit(SDEV_EVT_##Cap_name, sdev->supported_events);	\
	else if (val == 1)						\
		set_bit(SDEV_EVT_##Cap_name, sdev->supported_events);	\
	else								\
		return -EINVAL;						\
	return count;							\
}

#define DECLARE_EVT(name, Cap_name)					\
	DECLARE_EVT_SHOW(name, Cap_name)				\
	DECLARE_EVT_STORE(name, Cap_name)				\
	static DEVICE_ATTR(evt_##name, S_IRUGO, sdev_show_evt_##name,	\
			   sdev_store_evt_##name);
#define REF_EVT(name) &dev_attr_evt_##name.attr

DECLARE_EVT(media_change, MEDIA_CHANGE)
900 901 902 903 904
DECLARE_EVT(inquiry_change_reported, INQUIRY_CHANGE_REPORTED)
DECLARE_EVT(capacity_change_reported, CAPACITY_CHANGE_REPORTED)
DECLARE_EVT(soft_threshold_reached, SOFT_THRESHOLD_REACHED_REPORTED)
DECLARE_EVT(mode_parameter_change_reported, MODE_PARAMETER_CHANGE_REPORTED)
DECLARE_EVT(lun_change_reported, LUN_CHANGE_REPORTED)
905

906
static ssize_t
907 908
sdev_store_queue_depth(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
L
Linus Torvalds 已提交
909 910 911 912 913 914 915 916 917 918
{
	int depth, retval;
	struct scsi_device *sdev = to_scsi_device(dev);
	struct scsi_host_template *sht = sdev->host->hostt;

	if (!sht->change_queue_depth)
		return -EINVAL;

	depth = simple_strtoul(buf, NULL, 0);

919
	if (depth < 1 || depth > sdev->host->can_queue)
L
Linus Torvalds 已提交
920 921
		return -EINVAL;

922
	retval = sht->change_queue_depth(sdev, depth);
L
Linus Torvalds 已提交
923 924 925
	if (retval < 0)
		return retval;

V
Vasu Dev 已提交
926 927
	sdev->max_queue_depth = sdev->queue_depth;

L
Linus Torvalds 已提交
928 929
	return count;
}
930
sdev_show_function(queue_depth, "%d\n");
L
Linus Torvalds 已提交
931

932 933
static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth,
		   sdev_store_queue_depth);
L
Linus Torvalds 已提交
934

H
Hannes Reinecke 已提交
935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950
static ssize_t
sdev_show_wwid(struct device *dev, struct device_attribute *attr,
		    char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	ssize_t count;

	count = scsi_vpd_lun_id(sdev, buf, PAGE_SIZE);
	if (count > 0) {
		buf[count] = '\n';
		count++;
	}
	return count;
}
static DEVICE_ATTR(wwid, S_IRUGO, sdev_show_wwid, NULL);

951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
#ifdef CONFIG_SCSI_DH
static ssize_t
sdev_show_dh_state(struct device *dev, struct device_attribute *attr,
		   char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);

	if (!sdev->handler)
		return snprintf(buf, 20, "detached\n");

	return snprintf(buf, 20, "%s\n", sdev->handler->name);
}

static ssize_t
sdev_store_dh_state(struct device *dev, struct device_attribute *attr,
		    const char *buf, size_t count)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	int err = -EINVAL;

	if (sdev->sdev_state == SDEV_CANCEL ||
	    sdev->sdev_state == SDEV_DEL)
		return -ENODEV;

	if (!sdev->handler) {
		/*
		 * Attach to a device handler
		 */
		err = scsi_dh_attach(sdev->request_queue, buf);
	} else if (!strncmp(buf, "activate", 8)) {
		/*
		 * Activate a device handler
		 */
		if (sdev->handler->activate)
			err = sdev->handler->activate(sdev, NULL, NULL);
		else
			err = 0;
	} else if (!strncmp(buf, "detach", 6)) {
		/*
		 * Detach from a device handler
		 */
		sdev_printk(KERN_WARNING, sdev,
			    "can't detach handler %s.\n",
			    sdev->handler->name);
		err = -EINVAL;
	}

	return err < 0 ? err : count;
}

static DEVICE_ATTR(dh_state, S_IRUGO | S_IWUSR, sdev_show_dh_state,
		   sdev_store_dh_state);
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039

static ssize_t
sdev_show_access_state(struct device *dev,
		       struct device_attribute *attr,
		       char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	unsigned char access_state;
	const char *access_state_name;

	if (!sdev->handler)
		return -EINVAL;

	access_state = (sdev->access_state & SCSI_ACCESS_STATE_MASK);
	access_state_name = scsi_access_state_name(access_state);

	return sprintf(buf, "%s\n",
		       access_state_name ? access_state_name : "unknown");
}
static DEVICE_ATTR(access_state, S_IRUGO, sdev_show_access_state, NULL);

static ssize_t
sdev_show_preferred_path(struct device *dev,
			 struct device_attribute *attr,
			 char *buf)
{
	struct scsi_device *sdev = to_scsi_device(dev);

	if (!sdev->handler)
		return -EINVAL;

	if (sdev->access_state & SCSI_ACCESS_STATE_PREFERRED)
		return sprintf(buf, "1\n");
	else
		return sprintf(buf, "0\n");
}
static DEVICE_ATTR(preferred_path, S_IRUGO, sdev_show_preferred_path, NULL);
1040 1041
#endif

V
Vasu Dev 已提交
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
static ssize_t
sdev_show_queue_ramp_up_period(struct device *dev,
			       struct device_attribute *attr,
			       char *buf)
{
	struct scsi_device *sdev;
	sdev = to_scsi_device(dev);
	return snprintf(buf, 20, "%u\n",
			jiffies_to_msecs(sdev->queue_ramp_up_period));
}

static ssize_t
sdev_store_queue_ramp_up_period(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct scsi_device *sdev = to_scsi_device(dev);
1059
	unsigned int period;
V
Vasu Dev 已提交
1060

1061
	if (kstrtouint(buf, 10, &period))
V
Vasu Dev 已提交
1062 1063 1064
		return -EINVAL;

	sdev->queue_ramp_up_period = msecs_to_jiffies(period);
1065
	return count;
V
Vasu Dev 已提交
1066 1067
}

1068 1069 1070
static DEVICE_ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
		   sdev_show_queue_ramp_up_period,
		   sdev_store_queue_ramp_up_period);
V
Vasu Dev 已提交
1071

1072 1073
static umode_t scsi_sdev_attr_is_visible(struct kobject *kobj,
					 struct attribute *attr, int i)
L
Linus Torvalds 已提交
1074
{
1075
	struct device *dev = container_of(kobj, struct device, kobj);
L
Linus Torvalds 已提交
1076 1077 1078
	struct scsi_device *sdev = to_scsi_device(dev);


1079 1080 1081
	if (attr == &dev_attr_queue_depth.attr &&
	    !sdev->host->hostt->change_queue_depth)
		return S_IRUGO;
L
Linus Torvalds 已提交
1082

1083 1084 1085
	if (attr == &dev_attr_queue_ramp_up_period.attr &&
	    !sdev->host->hostt->change_queue_depth)
		return 0;
L
Linus Torvalds 已提交
1086

1087 1088 1089 1090 1091 1092 1093 1094
#ifdef CONFIG_SCSI_DH
	if (attr == &dev_attr_access_state.attr &&
	    !sdev->handler)
		return 0;
	if (attr == &dev_attr_preferred_path.attr &&
	    !sdev->handler)
		return 0;
#endif
1095
	return attr->mode;
L
Linus Torvalds 已提交
1096 1097
}

1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
static umode_t scsi_sdev_bin_attr_is_visible(struct kobject *kobj,
					     struct bin_attribute *attr, int i)
{
	struct device *dev = container_of(kobj, struct device, kobj);
	struct scsi_device *sdev = to_scsi_device(dev);


	if (attr == &dev_attr_vpd_pg80 && !sdev->vpd_pg80)
		return 0;

	if (attr == &dev_attr_vpd_pg83 && sdev->vpd_pg83)
		return 0;

	return S_IRUGO;
}

1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
/* Default template for device attributes.  May NOT be modified */
static struct attribute *scsi_sdev_attrs[] = {
	&dev_attr_device_blocked.attr,
	&dev_attr_type.attr,
	&dev_attr_scsi_level.attr,
	&dev_attr_device_busy.attr,
	&dev_attr_vendor.attr,
	&dev_attr_model.attr,
	&dev_attr_rev.attr,
	&dev_attr_rescan.attr,
	&dev_attr_delete.attr,
	&dev_attr_state.attr,
	&dev_attr_timeout.attr,
	&dev_attr_eh_timeout.attr,
	&dev_attr_iocounterbits.attr,
	&dev_attr_iorequest_cnt.attr,
	&dev_attr_iodone_cnt.attr,
	&dev_attr_ioerr_cnt.attr,
	&dev_attr_modalias.attr,
	&dev_attr_queue_depth.attr,
	&dev_attr_queue_type.attr,
H
Hannes Reinecke 已提交
1135
	&dev_attr_wwid.attr,
1136 1137
#ifdef CONFIG_SCSI_DH
	&dev_attr_dh_state.attr,
1138 1139
	&dev_attr_access_state.attr,
	&dev_attr_preferred_path.attr,
1140
#endif
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150
	&dev_attr_queue_ramp_up_period.attr,
	REF_EVT(media_change),
	REF_EVT(inquiry_change_reported),
	REF_EVT(capacity_change_reported),
	REF_EVT(soft_threshold_reached),
	REF_EVT(mode_parameter_change_reported),
	REF_EVT(lun_change_reported),
	NULL
};

1151 1152 1153
static struct bin_attribute *scsi_sdev_bin_attrs[] = {
	&dev_attr_vpd_pg83,
	&dev_attr_vpd_pg80,
1154
	&dev_attr_inquiry,
1155 1156
	NULL
};
1157 1158
static struct attribute_group scsi_sdev_attr_group = {
	.attrs =	scsi_sdev_attrs,
1159
	.bin_attrs =	scsi_sdev_bin_attrs,
1160
	.is_visible =	scsi_sdev_attr_is_visible,
1161
	.is_bin_visible = scsi_sdev_bin_attr_is_visible,
1162 1163 1164 1165 1166 1167 1168
};

static const struct attribute_group *scsi_sdev_attr_groups[] = {
	&scsi_sdev_attr_group,
	NULL
};

1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183
static int scsi_target_add(struct scsi_target *starget)
{
	int error;

	if (starget->state != STARGET_CREATED)
		return 0;

	error = device_add(&starget->dev);
	if (error) {
		dev_err(&starget->dev, "target device_add failed, error %d\n", error);
		return error;
	}
	transport_add_device(&starget->dev);
	starget->state = STARGET_RUNNING;

1184 1185 1186 1187
	pm_runtime_set_active(&starget->dev);
	pm_runtime_enable(&starget->dev);
	device_enable_async_suspend(&starget->dev);

1188 1189 1190
	return 0;
}

L
Linus Torvalds 已提交
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200
/**
 * scsi_sysfs_add_sdev - add scsi device to sysfs
 * @sdev:	scsi_device to add
 *
 * Return value:
 * 	0 on Success / non-zero on Failure
 **/
int scsi_sysfs_add_sdev(struct scsi_device *sdev)
{
	int error, i;
1201
	struct request_queue *rq = sdev->request_queue;
1202
	struct scsi_target *starget = sdev->sdev_target;
L
Linus Torvalds 已提交
1203

1204 1205
	error = scsi_device_set_state(sdev, SDEV_RUNNING);
	if (error)
L
Linus Torvalds 已提交
1206 1207
		return error;

1208 1209 1210 1211 1212
	error = scsi_target_add(starget);
	if (error)
		return error;

	transport_configure_device(&starget->dev);
1213

1214
	device_enable_async_suspend(&sdev->sdev_gendev);
1215 1216 1217 1218 1219 1220 1221 1222
	scsi_autopm_get_target(starget);
	pm_runtime_set_active(&sdev->sdev_gendev);
	pm_runtime_forbid(&sdev->sdev_gendev);
	pm_runtime_enable(&sdev->sdev_gendev);
	scsi_autopm_put_target(starget);

	scsi_autopm_get_device(sdev);

1223
	error = scsi_dh_add_device(sdev);
1224 1225 1226 1227
	if (error)
		/*
		 * device_handler is optional, so any error can be ignored
		 */
1228 1229 1230
		sdev_printk(KERN_INFO, sdev,
				"failed to add device handler: %d\n", error);

1231 1232 1233 1234 1235 1236 1237 1238
	error = device_add(&sdev->sdev_gendev);
	if (error) {
		sdev_printk(KERN_INFO, sdev,
				"failed to add device: %d\n", error);
		scsi_dh_remove_device(sdev);
		return error;
	}

1239
	device_enable_async_suspend(&sdev->sdev_dev);
1240
	error = device_add(&sdev->sdev_dev);
L
Linus Torvalds 已提交
1241
	if (error) {
A
Alan Stern 已提交
1242 1243
		sdev_printk(KERN_INFO, sdev,
				"failed to add class device: %d\n", error);
1244
		scsi_dh_remove_device(sdev);
1245
		device_del(&sdev->sdev_gendev);
1246
		return error;
L
Linus Torvalds 已提交
1247
	}
1248 1249
	transport_add_device(&sdev->sdev_gendev);
	sdev->is_visible = 1;
L
Linus Torvalds 已提交
1250

1251
	error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL);
1252 1253

	if (error)
1254 1255
		/* we're treating error on bsg register as non-fatal,
		 * so pretend nothing went wrong */
1256 1257 1258
		sdev_printk(KERN_INFO, sdev,
			    "Failed to register bsg queue, errno=%d\n", error);

1259
	/* add additional host specific attributes */
L
Linus Torvalds 已提交
1260 1261
	if (sdev->host->hostt->sdev_attrs) {
		for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
1262
			error = device_create_file(&sdev->sdev_gendev,
L
Linus Torvalds 已提交
1263
					sdev->host->hostt->sdev_attrs[i]);
1264
			if (error)
1265
				return error;
L
Linus Torvalds 已提交
1266 1267 1268
		}
	}

1269
	scsi_autopm_put_device(sdev);
L
Linus Torvalds 已提交
1270 1271 1272
	return error;
}

1273
void __scsi_remove_device(struct scsi_device *sdev)
L
Linus Torvalds 已提交
1274
{
J
James Bottomley 已提交
1275 1276
	struct device *dev = &sdev->sdev_gendev;

1277 1278 1279 1280 1281 1282 1283 1284
	/*
	 * This cleanup path is not reentrant and while it is impossible
	 * to get a new reference with scsi_device_get() someone can still
	 * hold a previously acquired one.
	 */
	if (sdev->sdev_state == SDEV_DEL)
		return;

1285 1286 1287
	if (sdev->is_visible) {
		if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
			return;
L
Linus Torvalds 已提交
1288

1289 1290 1291
		bsg_unregister_queue(sdev->request_queue);
		device_unregister(&sdev->sdev_dev);
		transport_remove_device(dev);
1292
		scsi_dh_remove_device(sdev);
1293 1294 1295
		device_del(dev);
	} else
		put_device(&sdev->sdev_dev);
1296 1297 1298 1299 1300 1301

	/*
	 * Stop accepting new requests and wait until all queuecommand() and
	 * scsi_run_queue() invocations have finished before tearing down the
	 * device.
	 */
L
Linus Torvalds 已提交
1302
	scsi_device_set_state(sdev, SDEV_DEL);
1303 1304 1305
	blk_cleanup_queue(sdev->request_queue);
	cancel_work_sync(&sdev->requeue_work);

L
Linus Torvalds 已提交
1306 1307
	if (sdev->host->hostt->slave_destroy)
		sdev->host->hostt->slave_destroy(sdev);
J
James Bottomley 已提交
1308
	transport_destroy_device(dev);
1309

1310 1311 1312 1313 1314 1315 1316
	/*
	 * Paired with the kref_get() in scsi_sysfs_initialize().  We have
	 * remoed sysfs visibility from the device, so make the target
	 * invisible if this was the last device underneath it.
	 */
	scsi_target_reap(scsi_target(sdev));

J
James Bottomley 已提交
1317
	put_device(dev);
1318 1319 1320 1321 1322 1323 1324 1325
}

/**
 * scsi_remove_device - unregister a device from the scsi bus
 * @sdev:	scsi_device to unregister
 **/
void scsi_remove_device(struct scsi_device *sdev)
{
1326 1327
	struct Scsi_Host *shost = sdev->host;

1328
	mutex_lock(&shost->scan_mutex);
1329
	__scsi_remove_device(sdev);
1330
	mutex_unlock(&shost->scan_mutex);
L
Linus Torvalds 已提交
1331 1332 1333
}
EXPORT_SYMBOL(scsi_remove_device);

A
Adrian Bunk 已提交
1334
static void __scsi_remove_target(struct scsi_target *starget)
L
Linus Torvalds 已提交
1335 1336 1337
{
	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
	unsigned long flags;
1338
	struct scsi_device *sdev;
L
Linus Torvalds 已提交
1339 1340

	spin_lock_irqsave(shost->host_lock, flags);
1341 1342
 restart:
	list_for_each_entry(sdev, &shost->__devices, siblings) {
L
Linus Torvalds 已提交
1343
		if (sdev->channel != starget->channel ||
1344
		    sdev->id != starget->id ||
1345
		    scsi_device_get(sdev))
L
Linus Torvalds 已提交
1346 1347 1348
			continue;
		spin_unlock_irqrestore(shost->host_lock, flags);
		scsi_remove_device(sdev);
1349
		scsi_device_put(sdev);
L
Linus Torvalds 已提交
1350
		spin_lock_irqsave(shost->host_lock, flags);
1351
		goto restart;
L
Linus Torvalds 已提交
1352 1353
	}
	spin_unlock_irqrestore(shost->host_lock, flags);
1354 1355
}

L
Linus Torvalds 已提交
1356 1357 1358 1359 1360 1361 1362 1363 1364 1365
/**
 * scsi_remove_target - try to remove a target and all its devices
 * @dev: generic starget or parent of generic stargets to be removed
 *
 * Note: This is slightly racy.  It is possible that if the user
 * requests the addition of another device then the target won't be
 * removed.
 */
void scsi_remove_target(struct device *dev)
{
1366
	struct Scsi_Host *shost = dev_to_shost(dev->parent);
1367
	struct scsi_target *starget, *last_target = NULL;
1368 1369
	unsigned long flags;

1370
restart:
1371 1372
	spin_lock_irqsave(shost->host_lock, flags);
	list_for_each_entry(starget, &shost->__targets, siblings) {
1373 1374
		if (starget->state == STARGET_DEL ||
		    starget == last_target)
1375 1376
			continue;
		if (starget->dev.parent == dev || &starget->dev == dev) {
1377
			kref_get(&starget->reap_ref);
1378
			last_target = starget;
1379 1380
			spin_unlock_irqrestore(shost->host_lock, flags);
			__scsi_remove_target(starget);
1381 1382
			scsi_target_reap(starget);
			goto restart;
1383
		}
L
Linus Torvalds 已提交
1384
	}
1385
	spin_unlock_irqrestore(shost->host_lock, flags);
L
Linus Torvalds 已提交
1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
}
EXPORT_SYMBOL(scsi_remove_target);

int scsi_register_driver(struct device_driver *drv)
{
	drv->bus = &scsi_bus_type;

	return driver_register(drv);
}
EXPORT_SYMBOL(scsi_register_driver);

int scsi_register_interface(struct class_interface *intf)
{
	intf->class = &sdev_class;

	return class_interface_register(intf);
}
EXPORT_SYMBOL(scsi_register_interface);

/**
 * scsi_sysfs_add_host - add scsi host to subsystem
 * @shost:     scsi host struct to add to subsystem
 **/
int scsi_sysfs_add_host(struct Scsi_Host *shost)
{
	int error, i;

1413
	/* add host specific attributes */
L
Linus Torvalds 已提交
1414 1415
	if (shost->hostt->shost_attrs) {
		for (i = 0; shost->hostt->shost_attrs[i]; i++) {
1416
			error = device_create_file(&shost->shost_dev,
1417
					shost->hostt->shost_attrs[i]);
L
Linus Torvalds 已提交
1418 1419 1420 1421 1422 1423
			if (error)
				return error;
		}
	}

	transport_register_device(&shost->shost_gendev);
1424
	transport_configure_device(&shost->shost_gendev);
L
Linus Torvalds 已提交
1425 1426 1427
	return 0;
}

1428 1429 1430 1431 1432 1433
static struct device_type scsi_dev_type = {
	.name =		"scsi_device",
	.release =	scsi_device_dev_release,
	.groups =	scsi_sdev_attr_groups,
};

L
Linus Torvalds 已提交
1434 1435 1436 1437 1438 1439 1440 1441
void scsi_sysfs_device_initialize(struct scsi_device *sdev)
{
	unsigned long flags;
	struct Scsi_Host *shost = sdev->host;
	struct scsi_target  *starget = sdev->sdev_target;

	device_initialize(&sdev->sdev_gendev);
	sdev->sdev_gendev.bus = &scsi_bus_type;
1442
	sdev->sdev_gendev.type = &scsi_dev_type;
H
Hannes Reinecke 已提交
1443
	dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu",
1444 1445
		     sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);

1446
	device_initialize(&sdev->sdev_dev);
1447
	sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev);
1448
	sdev->sdev_dev.class = &sdev_class;
H
Hannes Reinecke 已提交
1449
	dev_set_name(&sdev->sdev_dev, "%d:%d:%d:%llu",
1450
		     sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
1451 1452 1453 1454 1455 1456 1457
	/*
	 * Get a default scsi_level from the target (derived from sibling
	 * devices).  This is the best we can do for guessing how to set
	 * sdev->lun_in_cdb for the initial INQUIRY command.  For LUN 0 the
	 * setting doesn't matter, because all the bits are zero anyway.
	 * But it does matter for higher LUNs.
	 */
1458
	sdev->scsi_level = starget->scsi_level;
1459 1460 1461 1462 1463
	if (sdev->scsi_level <= SCSI_2 &&
			sdev->scsi_level != SCSI_UNKNOWN &&
			!shost->no_scsi2_lun_in_cdb)
		sdev->lun_in_cdb = 1;

L
Linus Torvalds 已提交
1464 1465 1466 1467 1468
	transport_setup_device(&sdev->sdev_gendev);
	spin_lock_irqsave(shost->host_lock, flags);
	list_add_tail(&sdev->same_target_siblings, &starget->devices);
	list_add_tail(&sdev->siblings, &shost->__devices);
	spin_unlock_irqrestore(shost->host_lock, flags);
1469 1470 1471 1472 1473 1474
	/*
	 * device can now only be removed via __scsi_remove_device() so hold
	 * the target.  Target will be held in CREATED state until something
	 * beneath it becomes visible (in which case it moves to RUNNING)
	 */
	kref_get(&starget->reap_ref);
L
Linus Torvalds 已提交
1475 1476 1477 1478
}

int scsi_is_sdev_device(const struct device *dev)
{
1479
	return dev->type == &scsi_dev_type;
L
Linus Torvalds 已提交
1480 1481 1482 1483 1484 1485
}
EXPORT_SYMBOL(scsi_is_sdev_device);

/* A blank transport template that is used in drivers that don't
 * yet implement Transport Attributes */
struct scsi_transport_template blank_transport_template = { { { {NULL, }, }, }, };