Commit 28d1aea6 authored by Christoph Hellwig's avatar Christoph Hellwig

[PATCH] switch /proc/scsi/scsi to seq_file and proper device model

parent 0859138b
...@@ -130,5 +130,6 @@ extern struct class_device_attribute *scsi_sysfs_shost_attrs[]; ...@@ -130,5 +130,6 @@ extern struct class_device_attribute *scsi_sysfs_shost_attrs[];
extern struct device_attribute *scsi_sysfs_sdev_attrs[]; extern struct device_attribute *scsi_sysfs_sdev_attrs[];
extern struct class shost_class; extern struct class shost_class;
extern struct bus_type scsi_bus_type;
#endif /* _SCSI_PRIV_H */ #endif /* _SCSI_PRIV_H */
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/blk.h> #include <linux/blk.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "scsi.h" #include "scsi.h"
...@@ -86,7 +87,7 @@ static int proc_scsi_read(char *buffer, char **start, off_t offset, ...@@ -86,7 +87,7 @@ static int proc_scsi_read(char *buffer, char **start, off_t offset,
return n; return n;
} }
static int proc_scsi_write(struct file *file, const char *buf, static int proc_scsi_write_proc(struct file *file, const char *buf,
unsigned long count, void *data) unsigned long count, void *data)
{ {
struct Scsi_Host *shost = data; struct Scsi_Host *shost = data;
...@@ -137,7 +138,7 @@ void scsi_proc_host_add(struct Scsi_Host *shost) ...@@ -137,7 +138,7 @@ void scsi_proc_host_add(struct Scsi_Host *shost)
return; return;
} }
p->write_proc = proc_scsi_write; p->write_proc = proc_scsi_write_proc;
p->owner = shost->hostt->module; p->owner = shost->hostt->module;
} }
...@@ -152,96 +153,52 @@ void scsi_proc_host_rm(struct Scsi_Host *shost) ...@@ -152,96 +153,52 @@ void scsi_proc_host_rm(struct Scsi_Host *shost)
remove_proc_entry(shost->hostt->proc_name, proc_scsi); remove_proc_entry(shost->hostt->proc_name, proc_scsi);
} }
static void proc_print_scsidevice(struct scsi_device* sdev, char *buffer, static int proc_print_scsidevice(struct device *dev, void *data)
int *size, int len)
{ {
struct scsi_device *sdev = to_scsi_device(dev);
struct seq_file *s = data;
int i;
int x, y = *size; seq_printf(s,
extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
y = sprintf(buffer + len,
"Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n Vendor: ", "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
for (x = 0; x < 8; x++) { for (i = 0; i < 8; i++) {
if (sdev->vendor[x] >= 0x20) if (sdev->vendor[i] >= 0x20)
y += sprintf(buffer + len + y, "%c", sdev->vendor[x]); seq_printf(s, "%c", sdev->vendor[i]);
else else
y += sprintf(buffer + len + y, " "); seq_printf(s, " ");
} }
y += sprintf(buffer + len + y, " Model: ");
for (x = 0; x < 16; x++) { seq_printf(s, " Model: ");
if (sdev->model[x] >= 0x20) for (i = 0; i < 16; i++) {
y += sprintf(buffer + len + y, "%c", sdev->model[x]); if (sdev->model[i] >= 0x20)
seq_printf(s, "%c", sdev->model[i]);
else else
y += sprintf(buffer + len + y, " "); seq_printf(s, " ");
} }
y += sprintf(buffer + len + y, " Rev: ");
for (x = 0; x < 4; x++) { seq_printf(s, " Rev: ");
if (sdev->rev[x] >= 0x20) for (i = 0; i < 4; i++) {
y += sprintf(buffer + len + y, "%c", sdev->rev[x]); if (sdev->rev[i] >= 0x20)
seq_printf(s, "%c", sdev->rev[i]);
else else
y += sprintf(buffer + len + y, " "); seq_printf(s, " ");
} }
y += sprintf(buffer + len + y, "\n");
y += sprintf(buffer + len + y, " Type: %s ", seq_printf(s, "\n");
seq_printf(s, " Type: %s ",
sdev->type < MAX_SCSI_DEVICE_CODE ? sdev->type < MAX_SCSI_DEVICE_CODE ?
scsi_device_types[(int) sdev->type] : "Unknown "); scsi_device_types[(int) sdev->type] : "Unknown ");
y += sprintf(buffer + len + y, " ANSI" seq_printf(s, " ANSI"
" SCSI revision: %02x", (sdev->scsi_level - 1) ? " SCSI revision: %02x", (sdev->scsi_level - 1) ?
sdev->scsi_level - 1 : 1); sdev->scsi_level - 1 : 1);
if (sdev->scsi_level == 2) if (sdev->scsi_level == 2)
y += sprintf(buffer + len + y, " CCS\n"); seq_printf(s, " CCS\n");
else else
y += sprintf(buffer + len + y, "\n"); seq_printf(s, "\n");
*size = y; return 0;
return;
}
static int scsi_proc_info(char *buffer, char **start, off_t offset, int length)
{
struct Scsi_Host *shost;
Scsi_Device *sdev;
int size, len = 0;
off_t begin = 0;
off_t pos = 0;
/*
* First, see if there are any attached devices or not.
*/
for (shost = scsi_host_get_next(NULL); shost;
shost = scsi_host_get_next(shost)) {
if (!list_empty(&shost->my_devices)) {
break;
}
}
size = sprintf(buffer + len, "Attached devices: %s\n",
(shost) ? "" : "none");
len += size;
pos = begin + len;
for (shost = scsi_host_get_next(NULL); shost;
shost = scsi_host_get_next(shost)) {
list_for_each_entry(sdev, &shost->my_devices, siblings) {
proc_print_scsidevice(sdev, buffer, &size, len);
len += size;
pos = begin + len;
if (pos < offset) {
len = 0;
begin = pos;
}
if (pos > offset + length)
goto stop_output;
}
}
stop_output:
*start = buffer + (offset - begin); /* Start of wanted data */
len -= (offset - begin); /* Start slop */
if (len > length)
len = length; /* Ending slop */
return (len);
} }
static int scsi_add_single_device(uint host, uint channel, uint id, uint lun) static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
...@@ -287,8 +244,8 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun) ...@@ -287,8 +244,8 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
return error; return error;
} }
static int proc_scsi_gen_write(struct file * file, const char * buf, static int proc_scsi_write(struct file *file, const char* buf,
unsigned long length, void *data) size_t length, loff_t *ppos)
{ {
int host, channel, id, lun; int host, channel, id, lun;
char *buffer, *p; char *buffer, *p;
...@@ -431,6 +388,30 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, ...@@ -431,6 +388,30 @@ static int proc_scsi_gen_write(struct file * file, const char * buf,
return err; return err;
} }
static int proc_scsi_show(struct seq_file *s, void *p)
{
seq_printf(s, "Attached devices:\n");
bus_for_each_dev(&scsi_bus_type, NULL, s, proc_print_scsidevice);
return 0;
}
static int proc_scsi_open(struct inode *inode, struct file *file)
{
/*
* We don't really needs this for the write case but it doesn't
* harm either.
*/
return single_open(file, proc_scsi_show, NULL);
}
static struct file_operations proc_scsi_operations = {
.open = proc_scsi_open,
.read = seq_read,
.write = proc_scsi_write,
.llseek = seq_lseek,
.release = single_release,
};
int __init scsi_init_procfs(void) int __init scsi_init_procfs(void)
{ {
struct proc_dir_entry *pde; struct proc_dir_entry *pde;
...@@ -439,10 +420,10 @@ int __init scsi_init_procfs(void) ...@@ -439,10 +420,10 @@ int __init scsi_init_procfs(void)
if (!proc_scsi) if (!proc_scsi)
goto err1; goto err1;
pde = create_proc_info_entry("scsi/scsi", 0, 0, scsi_proc_info); pde = create_proc_entry("scsi/scsi", 0, NULL);
if (!pde) if (!pde)
goto err2; goto err2;
pde->write_proc = proc_scsi_gen_write; pde->proc_fops = &proc_scsi_operations;
return 0; return 0;
......
...@@ -68,7 +68,7 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) ...@@ -68,7 +68,7 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
return 1; return 1;
} }
static struct bus_type scsi_bus_type = { struct bus_type scsi_bus_type = {
.name = "scsi", .name = "scsi",
.match = scsi_bus_match, .match = scsi_bus_match,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment