📄 i2o_proc.c
字号:
/* * procfs handler for Linux I2O subsystem * * (c) Copyright 1999 Deepak Saxena * * Originally written by Deepak Saxena(deepak@plexity.net) * * This program is free software. You can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * This is an initial test release. The code is based on the design * of the ide procfs system (drivers/block/ide-proc.c). Some code * taken from i2o-core module by Alan Cox. * * DISCLAIMER: This code is still under development/test and may cause * your system to behave unpredictably. Use at your own discretion. * * LAN entries by Juha Siev鋘en (Juha.Sievanen@cs.Helsinki.FI), * Auvo H鋕kinen (Auvo.Hakkinen@cs.Helsinki.FI) * University of Helsinki, Department of Computer Science *//* * set tabstop=3 *//* * TODO List * * - Add support for any version 2.0 spec changes once 2.0 IRTOS is * is available to test with * - Clean up code to use official structure definitions */// FIXME!#define FMT_U64_HEX "0x%08x%08x"#define U64_VAL(pu64) *((u32*)(pu64)+1), *((u32*)(pu64))#include <linux/types.h>#include <linux/kernel.h>#include <linux/pci.h>#include <linux/i2o.h>#include <linux/proc_fs.h>#include <linux/init.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/spinlock.h>#include <asm/io.h>#include <asm/uaccess.h>#include <asm/byteorder.h>#include "i2o_lan.h"/* * Structure used to define /proc entries */typedef struct _i2o_proc_entry_t{ char *name; /* entry name */ mode_t mode; /* mode */ read_proc_t *read_proc; /* read func */ write_proc_t *write_proc; /* write func */} i2o_proc_entry;// #define DRIVERDEBUGstatic int i2o_proc_read_lct(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_hrt(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_status(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_hw(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_ddm_table(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_driver_store(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_drivers_stored(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_groups(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_phys_device(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_claimed(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_users(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_priv_msgs(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_authorized_users(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_dev_name(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_dev_identity(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_ddm_identity(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_uinfo(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_sgl_limits(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_sensors(char *, char **, off_t, int, int *, void *);static int print_serial_number(char *, int, u8 *, int);static int i2o_proc_create_entries(void *, i2o_proc_entry *, struct proc_dir_entry *);static void i2o_proc_remove_entries(i2o_proc_entry *, struct proc_dir_entry *);static int i2o_proc_add_controller(struct i2o_controller *, struct proc_dir_entry * );static void i2o_proc_remove_controller(struct i2o_controller *, struct proc_dir_entry * );static void i2o_proc_add_device(struct i2o_device *, struct proc_dir_entry *);static void i2o_proc_remove_device(struct i2o_device *);static int create_i2o_procfs(void);static int destroy_i2o_procfs(void);static void i2o_proc_new_dev(struct i2o_controller *, struct i2o_device *);static void i2o_proc_dev_del(struct i2o_controller *, struct i2o_device *);static int i2o_proc_read_lan_dev_info(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_mac_addr(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_mcast_addr(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_batch_control(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_operation(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_media_operation(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_alt_addr(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_tx_info(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_rx_info(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_hist_stats(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_eth_stats(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_tr_stats(char *, char **, off_t, int, int *, void *);static int i2o_proc_read_lan_fddi_stats(char *, char **, off_t, int, int *, void *);static struct proc_dir_entry *i2o_proc_dir_root;/* * I2O OSM descriptor */static struct i2o_handler i2o_proc_handler ={ NULL, i2o_proc_new_dev, i2o_proc_dev_del, NULL, "I2O procfs Layer", 0, 0xffffffff // All classes};/* * IOP specific entries...write field just in case someone * ever wants one. */static i2o_proc_entry generic_iop_entries[] = { {"hrt", S_IFREG|S_IRUGO, i2o_proc_read_hrt, NULL}, {"lct", S_IFREG|S_IRUGO, i2o_proc_read_lct, NULL}, {"status", S_IFREG|S_IRUGO, i2o_proc_read_status, NULL}, {"hw", S_IFREG|S_IRUGO, i2o_proc_read_hw, NULL}, {"ddm_table", S_IFREG|S_IRUGO, i2o_proc_read_ddm_table, NULL}, {"driver_store", S_IFREG|S_IRUGO, i2o_proc_read_driver_store, NULL}, {"drivers_stored", S_IFREG|S_IRUGO, i2o_proc_read_drivers_stored, NULL}, {NULL, 0, NULL, NULL}};/* * Device specific entries */static i2o_proc_entry generic_dev_entries[] = { {"groups", S_IFREG|S_IRUGO, i2o_proc_read_groups, NULL}, {"phys_dev", S_IFREG|S_IRUGO, i2o_proc_read_phys_device, NULL}, {"claimed", S_IFREG|S_IRUGO, i2o_proc_read_claimed, NULL}, {"users", S_IFREG|S_IRUGO, i2o_proc_read_users, NULL}, {"priv_msgs", S_IFREG|S_IRUGO, i2o_proc_read_priv_msgs, NULL}, {"authorized_users", S_IFREG|S_IRUGO, i2o_proc_read_authorized_users, NULL}, {"dev_identity", S_IFREG|S_IRUGO, i2o_proc_read_dev_identity, NULL}, {"ddm_identity", S_IFREG|S_IRUGO, i2o_proc_read_ddm_identity, NULL}, {"user_info", S_IFREG|S_IRUGO, i2o_proc_read_uinfo, NULL}, {"sgl_limits", S_IFREG|S_IRUGO, i2o_proc_read_sgl_limits, NULL}, {"sensors", S_IFREG|S_IRUGO, i2o_proc_read_sensors, NULL}, {NULL, 0, NULL, NULL}};/* * Storage unit specific entries (SCSI Periph, BS) with device names */static i2o_proc_entry rbs_dev_entries[] = { {"dev_name", S_IFREG|S_IRUGO, i2o_proc_read_dev_name, NULL}, {NULL, 0, NULL, NULL}};#define SCSI_TABLE_SIZE 13static char *scsi_devices[] = { "Direct-Access Read/Write", "Sequential-Access Storage", "Printer", "Processor", "WORM Device", "CD-ROM Device", "Scanner Device", "Optical Memory Device", "Medium Changer Device", "Communications Device", "Graphics Art Pre-Press Device", "Graphics Art Pre-Press Device", "Array Controller Device"};/* private *//* * Generic LAN specific entries * * Should groups with r/w entries have their own subdirectory? * */static i2o_proc_entry lan_entries[] = { {"lan_dev_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_dev_info, NULL}, {"lan_mac_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_mac_addr, NULL}, {"lan_mcast_addr", S_IFREG|S_IRUGO|S_IWUSR, i2o_proc_read_lan_mcast_addr, NULL}, {"lan_batch_ctrl", S_IFREG|S_IRUGO|S_IWUSR, i2o_proc_read_lan_batch_control, NULL}, {"lan_operation", S_IFREG|S_IRUGO, i2o_proc_read_lan_operation, NULL}, {"lan_media_operation", S_IFREG|S_IRUGO, i2o_proc_read_lan_media_operation, NULL}, {"lan_alt_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_alt_addr, NULL}, {"lan_tx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_tx_info, NULL}, {"lan_rx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_rx_info, NULL}, {"lan_hist_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_hist_stats, NULL}, {NULL, 0, NULL, NULL}};/* * Port specific LAN entries * */static i2o_proc_entry lan_eth_entries[] = { {"lan_eth_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_eth_stats, NULL}, {NULL, 0, NULL, NULL}};static i2o_proc_entry lan_tr_entries[] = { {"lan_tr_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_tr_stats, NULL}, {NULL, 0, NULL, NULL}};static i2o_proc_entry lan_fddi_entries[] = { {"lan_fddi_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_fddi_stats, NULL}, {NULL, 0, NULL, NULL}};static char *chtostr(u8 *chars, int n){ char tmp[256]; tmp[0] = 0; return strncat(tmp, (char *)chars, n);}static int i2o_report_query_status(char *buf, int block_status, char *group){ switch (block_status) { case -ETIMEDOUT: return sprintf(buf, "Timeout reading group %s.\n",group); case -ENOMEM: return sprintf(buf, "No free memory to read the table.\n"); case -I2O_PARAMS_STATUS_INVALID_GROUP_ID: return sprintf(buf, "Group %s not supported.\n", group); default: return sprintf(buf, "Error reading group %s. BlockStatus 0x%02X\n", group, -block_status); }}static char* bus_strings[] = { "Local Bus", "ISA", "EISA", "MCA", "PCI", "PCMCIA", "NUBUS", "CARDBUS"};static spinlock_t i2o_proc_lock = SPIN_LOCK_UNLOCKED;int i2o_proc_read_hrt(char *buf, char **start, off_t offset, int count, int *eof, void *data){ struct i2o_controller *c = (struct i2o_controller *)data; i2o_hrt *hrt = (i2o_hrt *)c->hrt; u32 bus; int len, i; spin_lock(&i2o_proc_lock); len = 0; if(hrt->hrt_version) { len += sprintf(buf+len, "HRT table for controller is too new a version.\n"); spin_unlock(&i2o_proc_lock); return len; } if((hrt->num_entries * hrt->entry_len + 8) > 2048) { printk(KERN_WARNING "i2o_proc: HRT does not fit into buffer\n"); len += sprintf(buf+len, "HRT table too big to fit in buffer.\n"); spin_unlock(&i2o_proc_lock); return len; } len += sprintf(buf+len, "HRT has %d entries of %d bytes each.\n", hrt->num_entries, hrt->entry_len << 2); for(i = 0; i < hrt->num_entries && len < count; i++) { len += sprintf(buf+len, "Entry %d:\n", i); len += sprintf(buf+len, " Adapter ID: %0#10x\n", hrt->hrt_entry[i].adapter_id); len += sprintf(buf+len, " Controlling tid: %0#6x\n", hrt->hrt_entry[i].parent_tid); if(hrt->hrt_entry[i].bus_type != 0x80) { bus = hrt->hrt_entry[i].bus_type; len += sprintf(buf+len, " %s Information\n", bus_strings[bus]); switch(bus) { case I2O_BUS_LOCAL: len += sprintf(buf+len, " IOBase: %0#6x,", hrt->hrt_entry[i].bus.local_bus.LbBaseIOPort); len += sprintf(buf+len, " MemoryBase: %0#10x\n", hrt->hrt_entry[i].bus.local_bus.LbBaseMemoryAddress); break; case I2O_BUS_ISA: len += sprintf(buf+len, " IOBase: %0#6x,", hrt->hrt_entry[i].bus.isa_bus.IsaBaseIOPort); len += sprintf(buf+len, " MemoryBase: %0#10x,", hrt->hrt_entry[i].bus.isa_bus.IsaBaseMemoryAddress); len += sprintf(buf+len, " CSN: %0#4x,", hrt->hrt_entry[i].bus.isa_bus.CSN); break; case I2O_BUS_EISA: len += sprintf(buf+len, " IOBase: %0#6x,", hrt->hrt_entry[i].bus.eisa_bus.EisaBaseIOPort); len += sprintf(buf+len, " MemoryBase: %0#10x,", hrt->hrt_entry[i].bus.eisa_bus.EisaBaseMemoryAddress); len += sprintf(buf+len, " Slot: %0#4x,", hrt->hrt_entry[i].bus.eisa_bus.EisaSlotNumber); break; case I2O_BUS_MCA: len += sprintf(buf+len, " IOBase: %0#6x,", hrt->hrt_entry[i].bus.mca_bus.McaBaseIOPort); len += sprintf(buf+len, " MemoryBase: %0#10x,", hrt->hrt_entry[i].bus.mca_bus.McaBaseMemoryAddress); len += sprintf(buf+len, " Slot: %0#4x,", hrt->hrt_entry[i].bus.mca_bus.McaSlotNumber); break; case I2O_BUS_PCI: len += sprintf(buf+len, " Bus: %0#4x", hrt->hrt_entry[i].bus.pci_bus.PciBusNumber); len += sprintf(buf+len, " Dev: %0#4x", hrt->hrt_entry[i].bus.pci_bus.PciDeviceNumber); len += sprintf(buf+len, " Func: %0#4x", hrt->hrt_entry[i].bus.pci_bus.PciFunctionNumber); len += sprintf(buf+len, " Vendor: %0#6x", hrt->hrt_entry[i].bus.pci_bus.PciVendorID); len += sprintf(buf+len, " Device: %0#6x\n", hrt->hrt_entry[i].bus.pci_bus.PciDeviceID); break; default: len += sprintf(buf+len, " Unsupported Bus Type\n"); } } else len += sprintf(buf+len, " Unknown Bus Type\n"); } spin_unlock(&i2o_proc_lock); return len;}int i2o_proc_read_lct(char *buf, char **start, off_t offset, int len, int *eof, void *data){ struct i2o_controller *c = (struct i2o_controller*)data; i2o_lct *lct = (i2o_lct *)c->lct; int entries; int i;#define BUS_TABLE_SIZE 3 static char *bus_ports[] = { "Generic Bus", "SCSI Bus", "Fibre Channel Bus" }; spin_lock(&i2o_proc_lock); len = 0; entries = (lct->table_size - 3)/9; len += sprintf(buf, "LCT contains %d %s\n", entries, entries == 1 ? "entry" : "entries"); if(lct->boot_tid) len += sprintf(buf+len, "Boot Device @ ID %d\n", lct->boot_tid); len += sprintf(buf+len, "Current Change Indicator: %#10x\n", lct->change_ind); for(i = 0; i < entries; i++) { len += sprintf(buf+len, "Entry %d\n", i); len += sprintf(buf+len, " Class, SubClass : %s", i2o_get_class_name(lct->lct_entry[i].class_id)); /* * Classes which we'll print subclass info for */ switch(lct->lct_entry[i].class_id & 0xFFF) { case I2O_CLASS_RANDOM_BLOCK_STORAGE: switch(lct->lct_entry[i].sub_class) { case 0x00: len += sprintf(buf+len, ", Direct-Access Read/Write"); break; case 0x04: len += sprintf(buf+len, ", WORM Drive"); break; case 0x05: len += sprintf(buf+len, ", CD-ROM Drive"); break; case 0x07: len += sprintf(buf+len, ", Optical Memory Device"); break; default: len += sprintf(buf+len, ", Unknown (0x%02x)", lct->lct_entry[i].sub_class); break; } break; case I2O_CLASS_LAN: switch(lct->lct_entry[i].sub_class & 0xFF) { case 0x30: len += sprintf(buf+len, ", Ethernet"); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -