i2o_proc.c
来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 2,414 行 · 第 1/5 页
C
2,414 行
/* * 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/seq_file.h>#include <linux/init.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/spinlock.h>#include <linux/workqueue.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 */ struct file_operations *fops_proc; /* file operations func */} i2o_proc_entry;// #define DRIVERDEBUGstatic int i2o_seq_show_lct(struct seq_file *, void *);static int i2o_seq_show_hrt(struct seq_file *, void *);static int i2o_seq_show_status(struct seq_file *, 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};static int i2o_seq_open_hrt(struct inode *inode, struct file *file){ return single_open(file, i2o_seq_show_hrt, PDE(inode)->data);};struct file_operations i2o_seq_fops_hrt = { .open = i2o_seq_open_hrt, .read = seq_read, .llseek = seq_lseek, .release = single_release};static int i2o_seq_open_lct(struct inode *inode, struct file *file){ return single_open(file, i2o_seq_show_lct, PDE(inode)->data);};struct file_operations i2o_seq_fops_lct = { .open = i2o_seq_open_lct, .read = seq_read, .llseek = seq_lseek, .release = single_release};static int i2o_seq_open_status(struct inode *inode, struct file *file){ return single_open(file, i2o_seq_show_status, PDE(inode)->data);};struct file_operations i2o_seq_fops_status = { .open = i2o_seq_open_status, .read = seq_read, .llseek = seq_lseek, .release = single_release};/* * IOP specific entries...write field just in case someone * ever wants one. */static i2o_proc_entry generic_iop_entries[] = { {"hrt", S_IFREG|S_IRUGO, NULL, NULL, &i2o_seq_fops_hrt}, {"lct", S_IFREG|S_IRUGO, NULL, NULL, &i2o_seq_fops_lct}, {"status", S_IFREG|S_IRUGO, NULL, NULL, &i2o_seq_fops_status}, {"hw", S_IFREG|S_IRUGO, i2o_proc_read_hw, NULL, NULL}, {"ddm_table", S_IFREG|S_IRUGO, i2o_proc_read_ddm_table, NULL, NULL}, {"driver_store", S_IFREG|S_IRUGO, i2o_proc_read_driver_store, NULL, NULL}, {"drivers_stored", S_IFREG|S_IRUGO, i2o_proc_read_drivers_stored, NULL, NULL}, {NULL, 0, NULL, NULL, NULL}};/* * Device specific entries */static i2o_proc_entry generic_dev_entries[] = { {"groups", S_IFREG|S_IRUGO, i2o_proc_read_groups, NULL, NULL}, {"phys_dev", S_IFREG|S_IRUGO, i2o_proc_read_phys_device, NULL, NULL}, {"claimed", S_IFREG|S_IRUGO, i2o_proc_read_claimed, NULL, NULL}, {"users", S_IFREG|S_IRUGO, i2o_proc_read_users, NULL, NULL}, {"priv_msgs", S_IFREG|S_IRUGO, i2o_proc_read_priv_msgs, NULL, NULL}, {"authorized_users", S_IFREG|S_IRUGO, i2o_proc_read_authorized_users, NULL, NULL}, {"dev_identity", S_IFREG|S_IRUGO, i2o_proc_read_dev_identity, NULL, NULL}, {"ddm_identity", S_IFREG|S_IRUGO, i2o_proc_read_ddm_identity, NULL, NULL}, {"user_info", S_IFREG|S_IRUGO, i2o_proc_read_uinfo, NULL, NULL}, {"sgl_limits", S_IFREG|S_IRUGO, i2o_proc_read_sgl_limits, NULL, NULL}, {"sensors", S_IFREG|S_IRUGO, i2o_proc_read_sensors, NULL, NULL}, {NULL, 0, NULL, 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}, {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, NULL}, {"lan_mac_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_mac_addr, NULL, NULL}, {"lan_mcast_addr", S_IFREG|S_IRUGO|S_IWUSR, i2o_proc_read_lan_mcast_addr, NULL, NULL}, {"lan_batch_ctrl", S_IFREG|S_IRUGO|S_IWUSR, i2o_proc_read_lan_batch_control, NULL, NULL}, {"lan_operation", S_IFREG|S_IRUGO, i2o_proc_read_lan_operation, NULL, NULL}, {"lan_media_operation", S_IFREG|S_IRUGO, i2o_proc_read_lan_media_operation, NULL, NULL}, {"lan_alt_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_alt_addr, NULL, NULL}, {"lan_tx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_tx_info, NULL, NULL}, {"lan_rx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_rx_info, NULL, NULL}, {"lan_hist_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_hist_stats, NULL, NULL}, {NULL, 0, NULL, 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}, {NULL, 0, NULL, NULL, NULL}};static i2o_proc_entry lan_tr_entries[] = { {"lan_tr_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_tr_stats, NULL, NULL}, {NULL, 0, NULL, NULL, NULL}};static i2o_proc_entry lan_fddi_entries[] = { {"lan_fddi_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_fddi_stats, NULL, NULL}, {NULL, 0, NULL, 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_seq_show_hrt(struct seq_file *seq, void *v){ struct i2o_controller *c = (struct i2o_controller *)seq->private; i2o_hrt *hrt = (i2o_hrt *)c->hrt; u32 bus; int i; if(hrt->hrt_version) { seq_printf(seq, "HRT table for controller is too new a version.\n"); return 0; } seq_printf(seq, "HRT has %d entries of %d bytes each.\n", hrt->num_entries, hrt->entry_len << 2); for(i = 0; i < hrt->num_entries; i++) { seq_printf(seq, "Entry %d:\n", i); seq_printf(seq, " Adapter ID: %0#10x\n", hrt->hrt_entry[i].adapter_id); seq_printf(seq, " 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; seq_printf(seq, " %s Information\n", bus_strings[bus]); switch(bus) { case I2O_BUS_LOCAL: seq_printf(seq, " IOBase: %0#6x,", hrt->hrt_entry[i].bus.local_bus.LbBaseIOPort); seq_printf(seq, " MemoryBase: %0#10x\n", hrt->hrt_entry[i].bus.local_bus.LbBaseMemoryAddress); break; case I2O_BUS_ISA: seq_printf(seq, " IOBase: %0#6x,", hrt->hrt_entry[i].bus.isa_bus.IsaBaseIOPort); seq_printf(seq, " MemoryBase: %0#10x,", hrt->hrt_entry[i].bus.isa_bus.IsaBaseMemoryAddress); seq_printf(seq, " CSN: %0#4x,", hrt->hrt_entry[i].bus.isa_bus.CSN); break; case I2O_BUS_EISA: seq_printf(seq, " IOBase: %0#6x,", hrt->hrt_entry[i].bus.eisa_bus.EisaBaseIOPort); seq_printf(seq, " MemoryBase: %0#10x,", hrt->hrt_entry[i].bus.eisa_bus.EisaBaseMemoryAddress); seq_printf(seq, " Slot: %0#4x,", hrt->hrt_entry[i].bus.eisa_bus.EisaSlotNumber); break; case I2O_BUS_MCA: seq_printf(seq, " IOBase: %0#6x,", hrt->hrt_entry[i].bus.mca_bus.McaBaseIOPort); seq_printf(seq, " MemoryBase: %0#10x,", hrt->hrt_entry[i].bus.mca_bus.McaBaseMemoryAddress); seq_printf(seq, " Slot: %0#4x,", hrt->hrt_entry[i].bus.mca_bus.McaSlotNumber); break; case I2O_BUS_PCI: seq_printf(seq, " Bus: %0#4x", hrt->hrt_entry[i].bus.pci_bus.PciBusNumber); seq_printf(seq, " Dev: %0#4x", hrt->hrt_entry[i].bus.pci_bus.PciDeviceNumber); seq_printf(seq, " Func: %0#4x", hrt->hrt_entry[i].bus.pci_bus.PciFunctionNumber); seq_printf(seq, " Vendor: %0#6x", hrt->hrt_entry[i].bus.pci_bus.PciVendorID); seq_printf(seq, " Device: %0#6x\n", hrt->hrt_entry[i].bus.pci_bus.PciDeviceID); break; default: seq_printf(seq, " Unsupported Bus Type\n"); } } else seq_printf(seq, " Unknown Bus Type\n"); } return 0;}int i2o_seq_show_lct(struct seq_file *seq, void *v){ struct i2o_controller *c = (struct i2o_controller*)seq->private; 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" }; entries = (lct->table_size - 3)/9; seq_printf(seq, "LCT contains %d %s\n", entries, entries == 1 ? "entry" : "entries"); if(lct->boot_tid) seq_printf(seq, "Boot Device @ ID %d\n", lct->boot_tid); seq_printf(seq, "Current Change Indicator: %#10x\n", lct->change_ind); for(i = 0; i < entries; i++) { seq_printf(seq, "Entry %d\n", i); seq_printf(seq, " 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: seq_printf(seq, ", Direct-Access Read/Write"); break; case 0x04: seq_printf(seq, ", WORM Drive"); break; case 0x05: seq_printf(seq, ", CD-ROM Drive"); break; case 0x07: seq_printf(seq, ", Optical Memory Device"); break; default:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?