--- kernel/Makefile | 2 - kernel/config.c | 1 kernel/iscsi.h | 3 ++ kernel/proc_vpd.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) Index: iscsitarget/trunk/kernel/config.c =================================================================== --- iscsitarget.orig/trunk/kernel/config.c +++ iscsitarget/trunk/kernel/config.c @@ -18,6 +18,7 @@ static struct proc_entries iet_proc_entr { {"volume", &volume_seq_fops}, {"session", &session_seq_fops}, + {"vpd", &vpd_seq_fops}, }; static struct proc_dir_entry *proc_iet_dir; Index: iscsitarget/trunk/kernel/proc_vpd.c =================================================================== --- /dev/null +++ iscsitarget/trunk/kernel/proc_vpd.c @@ -0,0 +1,80 @@ +/* + * VPD proc + * Copyright (C) 2006 Steffen Plotner swplotner@amherst.edu + * Released under the terms of the GNU GPL v2.0. + */ + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +#include +#include + +void hex_dump(struct seq_file *seq, u8 *p, int len) +{ + while (len--) { + seq_printf(seq, "%02x ", *p++); + } +} + +void ascii_dump(struct seq_file *seq, u8 *p, int len) +{ + while (len--) { + if (isascii(*p) && isprint(*p)) + seq_printf(seq, "%c", *p); + else + seq_printf(seq, "."); + p++; + } +} + +void ascii_printable_dump(struct seq_file *seq, u8 *p, int len) +{ + while (len--) { + if (isascii(*p) && isprint(*p)) + seq_printf(seq, "%c", *p); + p++; + } +} + +static void vpd_info_show(struct seq_file *seq, struct iscsi_target *target) +{ + struct iet_volume *volume; + + list_for_each_entry(volume, &target->volumes, list) { + seq_printf(seq, "\tlun:%u", + volume->lun); + if (volume->iotype->show) + volume->iotype->show(volume, seq); + else + seq_printf(seq, "\n"); + + seq_printf(seq, "\t\tvpd_83_scsi_id: "); + hex_dump(seq, volume->scsi_id, SCSI_ID_LEN); + ascii_dump(seq, volume->scsi_id, SCSI_ID_LEN); + seq_printf(seq, "\n"); + + seq_printf(seq, "\t\tvpd_80_scsi_sn: "); + ascii_printable_dump(seq, volume->scsi_sn, SCSI_SN_LEN); + seq_printf(seq, "\n"); + } +} + +static int iet_vpds_info_show(struct seq_file *seq, void *v) +{ + return iet_info_show(seq, vpd_info_show); +} + +static int iet_vpd_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, iet_vpds_info_show, NULL); +} + +struct file_operations vpd_seq_fops = { + .owner = THIS_MODULE, + .open = iet_vpd_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; Index: iscsitarget/trunk/kernel/iscsi.h =================================================================== --- iscsitarget.orig/trunk/kernel/iscsi.h +++ iscsitarget/trunk/kernel/iscsi.h @@ -365,6 +365,9 @@ extern int event_send(u32, u64, u32, u32 extern int event_init(void); extern void event_exit(void); +/* proc_vpd.c */ +extern struct file_operations vpd_seq_fops; + #define get_pgcnt(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) static inline void iscsi_cmnd_get_length(struct iscsi_pdu *pdu) Index: iscsitarget/trunk/kernel/Makefile =================================================================== --- iscsitarget.orig/trunk/kernel/Makefile +++ iscsitarget/trunk/kernel/Makefile @@ -13,5 +13,5 @@ obj-m += iscsi_trgt.o iscsi_trgt-objs := tio.o iscsi.o nthread.o wthread.o config.o digest.o \ conn.o session.o target.o volume.o iotype.o \ file-io.o null-io.o target_disk.o event.o param.o \ - block-io.o + block-io.o proc_vpd.o