diff options
-rw-r--r-- | drivers/scsi/scsi_proc.c | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index c99da926fda..f46855cd853 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c | |||
@@ -386,13 +386,59 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, | |||
386 | * @s: output goes here | 386 | * @s: output goes here |
387 | * @p: not used | 387 | * @p: not used |
388 | */ | 388 | */ |
389 | static int proc_scsi_show(struct seq_file *s, void *p) | 389 | static int always_match(struct device *dev, void *data) |
390 | { | 390 | { |
391 | seq_printf(s, "Attached devices:\n"); | 391 | return 1; |
392 | bus_for_each_dev(&scsi_bus_type, NULL, s, proc_print_scsidevice); | 392 | } |
393 | return 0; | 393 | |
394 | static inline struct device *next_scsi_device(struct device *start) | ||
395 | { | ||
396 | struct device *next = bus_find_device(&scsi_bus_type, start, NULL, | ||
397 | always_match); | ||
398 | put_device(start); | ||
399 | return next; | ||
394 | } | 400 | } |
395 | 401 | ||
402 | static void *scsi_seq_start(struct seq_file *sfile, loff_t *pos) | ||
403 | { | ||
404 | struct device *dev = NULL; | ||
405 | loff_t n = *pos; | ||
406 | |||
407 | while ((dev = next_scsi_device(dev))) { | ||
408 | if (!n--) | ||
409 | break; | ||
410 | sfile->private++; | ||
411 | } | ||
412 | return dev; | ||
413 | } | ||
414 | |||
415 | static void *scsi_seq_next(struct seq_file *sfile, void *v, loff_t *pos) | ||
416 | { | ||
417 | (*pos)++; | ||
418 | sfile->private++; | ||
419 | return next_scsi_device(v); | ||
420 | } | ||
421 | |||
422 | static void scsi_seq_stop(struct seq_file *sfile, void *v) | ||
423 | { | ||
424 | put_device(v); | ||
425 | } | ||
426 | |||
427 | static int scsi_seq_show(struct seq_file *sfile, void *dev) | ||
428 | { | ||
429 | if (!sfile->private) | ||
430 | seq_puts(sfile, "Attached devices:\n"); | ||
431 | |||
432 | return proc_print_scsidevice(dev, sfile); | ||
433 | } | ||
434 | |||
435 | static const struct seq_operations scsi_seq_ops = { | ||
436 | .start = scsi_seq_start, | ||
437 | .next = scsi_seq_next, | ||
438 | .stop = scsi_seq_stop, | ||
439 | .show = scsi_seq_show | ||
440 | }; | ||
441 | |||
396 | /** | 442 | /** |
397 | * proc_scsi_open - glue function | 443 | * proc_scsi_open - glue function |
398 | * @inode: not used | 444 | * @inode: not used |
@@ -406,7 +452,7 @@ static int proc_scsi_open(struct inode *inode, struct file *file) | |||
406 | * We don't really need this for the write case but it doesn't | 452 | * We don't really need this for the write case but it doesn't |
407 | * harm either. | 453 | * harm either. |
408 | */ | 454 | */ |
409 | return single_open(file, proc_scsi_show, NULL); | 455 | return seq_open(file, &scsi_seq_ops); |
410 | } | 456 | } |
411 | 457 | ||
412 | static const struct file_operations proc_scsi_operations = { | 458 | static const struct file_operations proc_scsi_operations = { |
@@ -415,7 +461,7 @@ static const struct file_operations proc_scsi_operations = { | |||
415 | .read = seq_read, | 461 | .read = seq_read, |
416 | .write = proc_scsi_write, | 462 | .write = proc_scsi_write, |
417 | .llseek = seq_lseek, | 463 | .llseek = seq_lseek, |
418 | .release = single_release, | 464 | .release = seq_release, |
419 | }; | 465 | }; |
420 | 466 | ||
421 | /** | 467 | /** |