linux/drivers/message/i2o/i2o_proc.c
<<
>>
Prefs
   1/*
   2 *      procfs handler for Linux I2O subsystem
   3 *
   4 *      (c) Copyright 1999      Deepak Saxena
   5 *
   6 *      Originally written by Deepak Saxena(deepak@plexity.net)
   7 *
   8 *      This program is free software; you can redistribute it and/or modify it
   9 *      under the terms of the GNU General Public License as published by the
  10 *      Free Software Foundation; either version 2 of the License, or (at your
  11 *      option) any later version.
  12 *
  13 *      This is an initial test release. The code is based on the design of the
  14 *      ide procfs system (drivers/block/ide-proc.c). Some code taken from
  15 *      i2o-core module by Alan Cox.
  16 *
  17 *      DISCLAIMER: This code is still under development/test and may cause
  18 *      your system to behave unpredictably.  Use at your own discretion.
  19 *
  20 *
  21 *      Fixes/additions:
  22 *              Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI),
  23 *              Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
  24 *              University of Helsinki, Department of Computer Science
  25 *                      LAN entries
  26 *              Markus Lidel <Markus.Lidel@shadowconnect.com>
  27 *                      Changes for new I2O API
  28 */
  29
  30#define OSM_NAME        "proc-osm"
  31#define OSM_VERSION     "1.316"
  32#define OSM_DESCRIPTION "I2O ProcFS OSM"
  33
  34#define I2O_MAX_MODULES 4
  35// FIXME!
  36#define FMT_U64_HEX "0x%08x%08x"
  37#define U64_VAL(pu64) *((u32*)(pu64)+1), *((u32*)(pu64))
  38
  39#include <linux/types.h>
  40#include <linux/kernel.h>
  41#include <linux/pci.h>
  42#include <linux/i2o.h>
  43#include <linux/slab.h>
  44#include <linux/proc_fs.h>
  45#include <linux/seq_file.h>
  46#include <linux/init.h>
  47#include <linux/module.h>
  48#include <linux/errno.h>
  49#include <linux/spinlock.h>
  50#include <linux/workqueue.h>
  51
  52#include <asm/io.h>
  53#include <asm/uaccess.h>
  54#include <asm/byteorder.h>
  55
  56/* Structure used to define /proc entries */
  57typedef struct _i2o_proc_entry_t {
  58        char *name;             /* entry name */
  59        umode_t mode;           /* mode */
  60        const struct file_operations *fops;     /* open function */
  61} i2o_proc_entry;
  62
  63/* global I2O /proc/i2o entry */
  64static struct proc_dir_entry *i2o_proc_dir_root;
  65
  66/* proc OSM driver struct */
  67static struct i2o_driver i2o_proc_driver = {
  68        .name = OSM_NAME,
  69};
  70
  71static int print_serial_number(struct seq_file *seq, u8 * serialno, int max_len)
  72{
  73        int i;
  74
  75        /* 19990419 -sralston
  76         *      The I2O v1.5 (and v2.0 so far) "official specification"
  77         *      got serial numbers WRONG!
  78         *      Apparently, and despite what Section 3.4.4 says and
  79         *      Figure 3-35 shows (pg 3-39 in the pdf doc),
  80         *      the convention / consensus seems to be:
  81         *        + First byte is SNFormat
  82         *        + Second byte is SNLen (but only if SNFormat==7 (?))
  83         *        + (v2.0) SCSI+BS may use IEEE Registered (64 or 128 bit) format
  84         */
  85        switch (serialno[0]) {
  86        case I2O_SNFORMAT_BINARY:       /* Binary */
  87                seq_printf(seq, "0x");
  88                for (i = 0; i < serialno[1]; i++) {
  89                        seq_printf(seq, "%02X", serialno[2 + i]);
  90                }
  91                break;
  92
  93        case I2O_SNFORMAT_ASCII:        /* ASCII */
  94                if (serialno[1] < ' ') {        /* printable or SNLen? */
  95                        /* sanity */
  96                        max_len =
  97                            (max_len < serialno[1]) ? max_len : serialno[1];
  98                        serialno[1 + max_len] = '\0';
  99
 100                        /* just print it */
 101                        seq_printf(seq, "%s", &serialno[2]);
 102                } else {
 103                        /* print chars for specified length */
 104                        for (i = 0; i < serialno[1]; i++) {
 105                                seq_printf(seq, "%c", serialno[2 + i]);
 106                        }
 107                }
 108                break;
 109
 110        case I2O_SNFORMAT_UNICODE:      /* UNICODE */
 111                seq_printf(seq, "UNICODE Format.  Can't Display\n");
 112                break;
 113
 114        case I2O_SNFORMAT_LAN48_MAC:    /* LAN-48 MAC Address */
 115                seq_printf(seq, "LAN-48 MAC address @ %pM", &serialno[2]);
 116                break;
 117
 118        case I2O_SNFORMAT_WAN:  /* WAN MAC Address */
 119                /* FIXME: Figure out what a WAN access address looks like?? */
 120                seq_printf(seq, "WAN Access Address");
 121                break;
 122
 123/* plus new in v2.0 */
 124        case I2O_SNFORMAT_LAN64_MAC:    /* LAN-64 MAC Address */
 125                /* FIXME: Figure out what a LAN-64 address really looks like?? */
 126                seq_printf(seq,
 127                           "LAN-64 MAC address @ [?:%02X:%02X:?] %pM",
 128                           serialno[8], serialno[9], &serialno[2]);
 129                break;
 130
 131        case I2O_SNFORMAT_DDM:  /* I2O DDM */
 132                seq_printf(seq,
 133                           "DDM: Tid=%03Xh, Rsvd=%04Xh, OrgId=%04Xh",
 134                           *(u16 *) & serialno[2],
 135                           *(u16 *) & serialno[4], *(u16 *) & serialno[6]);
 136                break;
 137
 138        case I2O_SNFORMAT_IEEE_REG64:   /* IEEE Registered (64-bit) */
 139        case I2O_SNFORMAT_IEEE_REG128:  /* IEEE Registered (128-bit) */
 140                /* FIXME: Figure if this is even close?? */
 141                seq_printf(seq,
 142                           "IEEE NodeName(hi,lo)=(%08Xh:%08Xh), PortName(hi,lo)=(%08Xh:%08Xh)\n",
 143                           *(u32 *) & serialno[2],
 144                           *(u32 *) & serialno[6],
 145                           *(u32 *) & serialno[10], *(u32 *) & serialno[14]);
 146                break;
 147
 148        case I2O_SNFORMAT_UNKNOWN:      /* Unknown 0    */
 149        case I2O_SNFORMAT_UNKNOWN2:     /* Unknown 0xff */
 150        default:
 151                seq_printf(seq, "Unknown data format (0x%02x)", serialno[0]);
 152                break;
 153        }
 154
 155        return 0;
 156}
 157
 158/**
 159 *      i2o_get_class_name -    do i2o class name lookup
 160 *      @class: class number
 161 *
 162 *      Return a descriptive string for an i2o class.
 163 */
 164static const char *i2o_get_class_name(int class)
 165{
 166        int idx = 16;
 167        static char *i2o_class_name[] = {
 168                "Executive",
 169                "Device Driver Module",
 170                "Block Device",
 171                "Tape Device",
 172                "LAN Interface",
 173                "WAN Interface",
 174                "Fibre Channel Port",
 175                "Fibre Channel Device",
 176                "SCSI Device",
 177                "ATE Port",
 178                "ATE Device",
 179                "Floppy Controller",
 180                "Floppy Device",
 181                "Secondary Bus Port",
 182                "Peer Transport Agent",
 183                "Peer Transport",
 184                "Unknown"
 185        };
 186
 187        switch (class & 0xfff) {
 188        case I2O_CLASS_EXECUTIVE:
 189                idx = 0;
 190                break;
 191        case I2O_CLASS_DDM:
 192                idx = 1;
 193                break;
 194        case I2O_CLASS_RANDOM_BLOCK_STORAGE:
 195                idx = 2;
 196                break;
 197        case I2O_CLASS_SEQUENTIAL_STORAGE:
 198                idx = 3;
 199                break;
 200        case I2O_CLASS_LAN:
 201                idx = 4;
 202                break;
 203        case I2O_CLASS_WAN:
 204                idx = 5;
 205                break;
 206        case I2O_CLASS_FIBRE_CHANNEL_PORT:
 207                idx = 6;
 208                break;
 209        case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
 210                idx = 7;
 211                break;
 212        case I2O_CLASS_SCSI_PERIPHERAL:
 213                idx = 8;
 214                break;
 215        case I2O_CLASS_ATE_PORT:
 216                idx = 9;
 217                break;
 218        case I2O_CLASS_ATE_PERIPHERAL:
 219                idx = 10;
 220                break;
 221        case I2O_CLASS_FLOPPY_CONTROLLER:
 222                idx = 11;
 223                break;
 224        case I2O_CLASS_FLOPPY_DEVICE:
 225                idx = 12;
 226                break;
 227        case I2O_CLASS_BUS_ADAPTER:
 228                idx = 13;
 229                break;
 230        case I2O_CLASS_PEER_TRANSPORT_AGENT:
 231                idx = 14;
 232                break;
 233        case I2O_CLASS_PEER_TRANSPORT:
 234                idx = 15;
 235                break;
 236        }
 237
 238        return i2o_class_name[idx];
 239}
 240
 241#define SCSI_TABLE_SIZE 13
 242static char *scsi_devices[] = {
 243        "Direct-Access Read/Write",
 244        "Sequential-Access Storage",
 245        "Printer",
 246        "Processor",
 247        "WORM Device",
 248        "CD-ROM Device",
 249        "Scanner Device",
 250        "Optical Memory Device",
 251        "Medium Changer Device",
 252        "Communications Device",
 253        "Graphics Art Pre-Press Device",
 254        "Graphics Art Pre-Press Device",
 255        "Array Controller Device"
 256};
 257
 258static char *chtostr(u8 * chars, int n)
 259{
 260        char tmp[256];
 261        tmp[0] = 0;
 262        return strncat(tmp, (char *)chars, n);
 263}
 264
 265static int i2o_report_query_status(struct seq_file *seq, int block_status,
 266                                   char *group)
 267{
 268        switch (block_status) {
 269        case -ETIMEDOUT:
 270                return seq_printf(seq, "Timeout reading group %s.\n", group);
 271        case -ENOMEM:
 272                return seq_printf(seq, "No free memory to read the table.\n");
 273        case -I2O_PARAMS_STATUS_INVALID_GROUP_ID:
 274                return seq_printf(seq, "Group %s not supported.\n", group);
 275        default:
 276                return seq_printf(seq,
 277                                  "Error reading group %s. BlockStatus 0x%02X\n",
 278                                  group, -block_status);
 279        }
 280}
 281
 282static char *bus_strings[] = {
 283        "Local Bus",
 284        "ISA",
 285        "EISA",
 286        "MCA",
 287        "PCI",
 288        "PCMCIA",
 289        "NUBUS",
 290        "CARDBUS"
 291};
 292
 293static int i2o_seq_show_hrt(struct seq_file *seq, void *v)
 294{
 295        struct i2o_controller *c = (struct i2o_controller *)seq->private;
 296        i2o_hrt *hrt = (i2o_hrt *) c->hrt.virt;
 297        u32 bus;
 298        int i;
 299
 300        if (hrt->hrt_version) {
 301                seq_printf(seq,
 302                           "HRT table for controller is too new a version.\n");
 303                return 0;
 304        }
 305
 306        seq_printf(seq, "HRT has %d entries of %d bytes each.\n",
 307                   hrt->num_entries, hrt->entry_len << 2);
 308
 309        for (i = 0; i < hrt->num_entries; i++) {
 310                seq_printf(seq, "Entry %d:\n", i);
 311                seq_printf(seq, "   Adapter ID: %0#10x\n",
 312                           hrt->hrt_entry[i].adapter_id);
 313                seq_printf(seq, "   Controlling tid: %0#6x\n",
 314                           hrt->hrt_entry[i].parent_tid);
 315
 316                if (hrt->hrt_entry[i].bus_type != 0x80) {
 317                        bus = hrt->hrt_entry[i].bus_type;
 318                        seq_printf(seq, "   %s Information\n",
 319                                   bus_strings[bus]);
 320
 321                        switch (bus) {
 322                        case I2O_BUS_LOCAL:
 323                                seq_printf(seq, "     IOBase: %0#6x,",
 324                                           hrt->hrt_entry[i].bus.local_bus.
 325                                           LbBaseIOPort);
 326                                seq_printf(seq, " MemoryBase: %0#10x\n",
 327                                           hrt->hrt_entry[i].bus.local_bus.
 328                                           LbBaseMemoryAddress);
 329                                break;
 330
 331                        case I2O_BUS_ISA:
 332                                seq_printf(seq, "     IOBase: %0#6x,",
 333                                           hrt->hrt_entry[i].bus.isa_bus.
 334                                           IsaBaseIOPort);
 335                                seq_printf(seq, " MemoryBase: %0#10x,",
 336                                           hrt->hrt_entry[i].bus.isa_bus.
 337                                           IsaBaseMemoryAddress);
 338                                seq_printf(seq, " CSN: %0#4x,",
 339                                           hrt->hrt_entry[i].bus.isa_bus.CSN);
 340                                break;
 341
 342                        case I2O_BUS_EISA:
 343                                seq_printf(seq, "     IOBase: %0#6x,",
 344                                           hrt->hrt_entry[i].bus.eisa_bus.
 345                                           EisaBaseIOPort);
 346                                seq_printf(seq, " MemoryBase: %0#10x,",
 347                                           hrt->hrt_entry[i].bus.eisa_bus.
 348                                           EisaBaseMemoryAddress);
 349                                seq_printf(seq, " Slot: %0#4x,",
 350                                           hrt->hrt_entry[i].bus.eisa_bus.
 351                                           EisaSlotNumber);
 352                                break;
 353
 354                        case I2O_BUS_MCA:
 355                                seq_printf(seq, "     IOBase: %0#6x,",
 356                                           hrt->hrt_entry[i].bus.mca_bus.
 357                                           McaBaseIOPort);
 358                                seq_printf(seq, " MemoryBase: %0#10x,",
 359                                           hrt->hrt_entry[i].bus.mca_bus.
 360                                           McaBaseMemoryAddress);
 361                                seq_printf(seq, " Slot: %0#4x,",
 362                                           hrt->hrt_entry[i].bus.mca_bus.
 363                                           McaSlotNumber);
 364                                break;
 365
 366                        case I2O_BUS_PCI:
 367                                seq_printf(seq, "     Bus: %0#4x",
 368                                           hrt->hrt_entry[i].bus.pci_bus.
 369                                           PciBusNumber);
 370                                seq_printf(seq, " Dev: %0#4x",
 371                                           hrt->hrt_entry[i].bus.pci_bus.
 372                                           PciDeviceNumber);
 373                                seq_printf(seq, " Func: %0#4x",
 374                                           hrt->hrt_entry[i].bus.pci_bus.
 375                                           PciFunctionNumber);
 376                                seq_printf(seq, " Vendor: %0#6x",
 377                                           hrt->hrt_entry[i].bus.pci_bus.
 378                                           PciVendorID);
 379                                seq_printf(seq, " Device: %0#6x\n",
 380                                           hrt->hrt_entry[i].bus.pci_bus.
 381                                           PciDeviceID);
 382                                break;
 383
 384                        default:
 385                                seq_printf(seq, "      Unsupported Bus Type\n");
 386                        }
 387                } else
 388                        seq_printf(seq, "   Unknown Bus Type\n");
 389        }
 390
 391        return 0;
 392}
 393
 394static int i2o_seq_show_lct(struct seq_file *seq, void *v)
 395{
 396        struct i2o_controller *c = (struct i2o_controller *)seq->private;
 397        i2o_lct *lct = (i2o_lct *) c->lct;
 398        int entries;
 399        int i;
 400
 401#define BUS_TABLE_SIZE 3
 402        static char *bus_ports[] = {
 403                "Generic Bus",
 404                "SCSI Bus",
 405                "Fibre Channel Bus"
 406        };
 407
 408        entries = (lct->table_size - 3) / 9;
 409
 410        seq_printf(seq, "LCT contains %d %s\n", entries,
 411                   entries == 1 ? "entry" : "entries");
 412        if (lct->boot_tid)
 413                seq_printf(seq, "Boot Device @ ID %d\n", lct->boot_tid);
 414
 415        seq_printf(seq, "Current Change Indicator: %#10x\n", lct->change_ind);
 416
 417        for (i = 0; i < entries; i++) {
 418                seq_printf(seq, "Entry %d\n", i);
 419                seq_printf(seq, "  Class, SubClass  : %s",
 420                           i2o_get_class_name(lct->lct_entry[i].class_id));
 421
 422                /*
 423                 *      Classes which we'll print subclass info for
 424                 */
 425                switch (lct->lct_entry[i].class_id & 0xFFF) {
 426                case I2O_CLASS_RANDOM_BLOCK_STORAGE:
 427                        switch (lct->lct_entry[i].sub_class) {
 428                        case 0x00:
 429                                seq_printf(seq, ", Direct-Access Read/Write");
 430                                break;
 431
 432                        case 0x04:
 433                                seq_printf(seq, ", WORM Drive");
 434                                break;
 435
 436                        case 0x05:
 437                                seq_printf(seq, ", CD-ROM Drive");
 438                                break;
 439
 440                        case 0x07:
 441                                seq_printf(seq, ", Optical Memory Device");
 442                                break;
 443
 444                        default:
 445                                seq_printf(seq, ", Unknown (0x%02x)",
 446                                           lct->lct_entry[i].sub_class);
 447                                break;
 448                        }
 449                        break;
 450
 451                case I2O_CLASS_LAN:
 452                        switch (lct->lct_entry[i].sub_class & 0xFF) {
 453                        case 0x30:
 454                                seq_printf(seq, ", Ethernet");
 455                                break;
 456
 457                        case 0x40:
 458                                seq_printf(seq, ", 100base VG");
 459                                break;
 460
 461                        case 0x50:
 462                                seq_printf(seq, ", IEEE 802.5/Token-Ring");
 463                                break;
 464
 465                        case 0x60:
 466                                seq_printf(seq, ", ANSI X3T9.5 FDDI");
 467                                break;
 468
 469                        case 0x70:
 470                                seq_printf(seq, ", Fibre Channel");
 471                                break;
 472
 473                        default:
 474                                seq_printf(seq, ", Unknown Sub-Class (0x%02x)",
 475                                           lct->lct_entry[i].sub_class & 0xFF);
 476                                break;
 477                        }
 478                        break;
 479
 480                case I2O_CLASS_SCSI_PERIPHERAL:
 481                        if (lct->lct_entry[i].sub_class < SCSI_TABLE_SIZE)
 482                                seq_printf(seq, ", %s",
 483                                           scsi_devices[lct->lct_entry[i].
 484                                                        sub_class]);
 485                        else
 486                                seq_printf(seq, ", Unknown Device Type");
 487                        break;
 488
 489                case I2O_CLASS_BUS_ADAPTER:
 490                        if (lct->lct_entry[i].sub_class < BUS_TABLE_SIZE)
 491                                seq_printf(seq, ", %s",
 492                                           bus_ports[lct->lct_entry[i].
 493                                                     sub_class]);
 494                        else
 495                                seq_printf(seq, ", Unknown Bus Type");
 496                        break;
 497                }
 498                seq_printf(seq, "\n");
 499
 500                seq_printf(seq, "  Local TID        : 0x%03x\n",
 501                           lct->lct_entry[i].tid);
 502                seq_printf(seq, "  User TID         : 0x%03x\n",
 503                           lct->lct_entry[i].user_tid);
 504                seq_printf(seq, "  Parent TID       : 0x%03x\n",
 505                           lct->lct_entry[i].parent_tid);
 506                seq_printf(seq, "  Identity Tag     : 0x%x%x%x%x%x%x%x%x\n",
 507                           lct->lct_entry[i].identity_tag[0],
 508                           lct->lct_entry[i].identity_tag[1],
 509                           lct->lct_entry[i].identity_tag[2],
 510                           lct->lct_entry[i].identity_tag[3],
 511                           lct->lct_entry[i].identity_tag[4],
 512                           lct->lct_entry[i].identity_tag[5],
 513                           lct->lct_entry[i].identity_tag[6],
 514                           lct->lct_entry[i].identity_tag[7]);
 515                seq_printf(seq, "  Change Indicator : %0#10x\n",
 516                           lct->lct_entry[i].change_ind);
 517                seq_printf(seq, "  Event Capab Mask : %0#10x\n",
 518                           lct->lct_entry[i].device_flags);
 519        }
 520
 521        return 0;
 522}
 523
 524static int i2o_seq_show_status(struct seq_file *seq, void *v)
 525{
 526        struct i2o_controller *c = (struct i2o_controller *)seq->private;
 527        char prodstr[25];
 528        int version;
 529        i2o_status_block *sb = c->status_block.virt;
 530
 531        i2o_status_get(c);      // reread the status block
 532
 533        seq_printf(seq, "Organization ID        : %0#6x\n", sb->org_id);
 534
 535        version = sb->i2o_version;
 536
 537/* FIXME for Spec 2.0
 538        if (version == 0x02) {
 539                seq_printf(seq, "Lowest I2O version supported: ");
 540                switch(workspace[2]) {
 541                        case 0x00:
 542                                seq_printf(seq, "1.0\n");
 543                                break;
 544                        case 0x01:
 545                                seq_printf(seq, "1.5\n");
 546                                break;
 547                        case 0x02:
 548                                seq_printf(seq, "2.0\n");
 549                                break;
 550                }
 551
 552                seq_printf(seq, "Highest I2O version supported: ");
 553                switch(workspace[3]) {
 554                        case 0x00:
 555                                seq_printf(seq, "1.0\n");
 556                                break;
 557                        case 0x01:
 558                                seq_printf(seq, "1.5\n");
 559                                break;
 560                        case 0x02:
 561                                seq_printf(seq, "2.0\n");
 562                                break;
 563                }
 564        }
 565*/
 566        seq_printf(seq, "IOP ID                 : %0#5x\n", sb->iop_id);
 567        seq_printf(seq, "Host Unit ID           : %0#6x\n", sb->host_unit_id);
 568        seq_printf(seq, "Segment Number         : %0#5x\n", sb->segment_number);
 569
 570        seq_printf(seq, "I2O version            : ");
 571        switch (version) {
 572        case 0x00:
 573                seq_printf(seq, "1.0\n");
 574                break;
 575        case 0x01:
 576                seq_printf(seq, "1.5\n");
 577                break;
 578        case 0x02:
 579                seq_printf(seq, "2.0\n");
 580                break;
 581        default:
 582                seq_printf(seq, "Unknown version\n");
 583        }
 584
 585        seq_printf(seq, "IOP State              : ");
 586        switch (sb->iop_state) {
 587        case 0x01:
 588                seq_printf(seq, "INIT\n");
 589                break;
 590
 591        case 0x02:
 592                seq_printf(seq, "RESET\n");
 593                break;
 594
 595        case 0x04:
 596                seq_printf(seq, "HOLD\n");
 597                break;
 598
 599        case 0x05:
 600                seq_printf(seq, "READY\n");
 601                break;
 602
 603        case 0x08:
 604                seq_printf(seq, "OPERATIONAL\n");
 605                break;
 606
 607        case 0x10:
 608                seq_printf(seq, "FAILED\n");
 609                break;
 610
 611        case 0x11:
 612                seq_printf(seq, "FAULTED\n");
 613                break;
 614
 615        default:
 616                seq_printf(seq, "Unknown\n");
 617                break;
 618        }
 619
 620        seq_printf(seq, "Messenger Type         : ");
 621        switch (sb->msg_type) {
 622        case 0x00:
 623                seq_printf(seq, "Memory mapped\n");
 624                break;
 625        case 0x01:
 626                seq_printf(seq, "Memory mapped only\n");
 627                break;
 628        case 0x02:
 629                seq_printf(seq, "Remote only\n");
 630                break;
 631        case 0x03:
 632                seq_printf(seq, "Memory mapped and remote\n");
 633                break;
 634        default:
 635                seq_printf(seq, "Unknown\n");
 636        }
 637
 638        seq_printf(seq, "Inbound Frame Size     : %d bytes\n",
 639                   sb->inbound_frame_size << 2);
 640        seq_printf(seq, "Max Inbound Frames     : %d\n",
 641                   sb->max_inbound_frames);
 642        seq_printf(seq, "Current Inbound Frames : %d\n",
 643                   sb->cur_inbound_frames);
 644        seq_printf(seq, "Max Outbound Frames    : %d\n",
 645                   sb->max_outbound_frames);
 646
 647        /* Spec doesn't say if NULL terminated or not... */
 648        memcpy(prodstr, sb->product_id, 24);
 649        prodstr[24] = '\0';
 650        seq_printf(seq, "Product ID             : %s\n", prodstr);
 651        seq_printf(seq, "Expected LCT Size      : %d bytes\n",
 652                   sb->expected_lct_size);
 653
 654        seq_printf(seq, "IOP Capabilities\n");
 655        seq_printf(seq, "    Context Field Size Support : ");
 656        switch (sb->iop_capabilities & 0x0000003) {
 657        case 0:
 658                seq_printf(seq, "Supports only 32-bit context fields\n");
 659                break;
 660        case 1:
 661                seq_printf(seq, "Supports only 64-bit context fields\n");
 662                break;
 663        case 2:
 664                seq_printf(seq, "Supports 32-bit and 64-bit context fields, "
 665                           "but not concurrently\n");
 666                break;
 667        case 3:
 668                seq_printf(seq, "Supports 32-bit and 64-bit context fields "
 669                           "concurrently\n");
 670                break;
 671        default:
 672                seq_printf(seq, "0x%08x\n", sb->iop_capabilities);
 673        }
 674        seq_printf(seq, "    Current Context Field Size : ");
 675        switch (sb->iop_capabilities & 0x0000000C) {
 676        case 0:
 677                seq_printf(seq, "not configured\n");
 678                break;
 679        case 4:
 680                seq_printf(seq, "Supports only 32-bit context fields\n");
 681                break;
 682        case 8:
 683                seq_printf(seq, "Supports only 64-bit context fields\n");
 684                break;
 685        case 12:
 686                seq_printf(seq, "Supports both 32-bit or 64-bit context fields "
 687                           "concurrently\n");
 688                break;
 689        default:
 690                seq_printf(seq, "\n");
 691        }
 692        seq_printf(seq, "    Inbound Peer Support       : %s\n",
 693                   (sb->
 694                    iop_capabilities & 0x00000010) ? "Supported" :
 695                   "Not supported");
 696        seq_printf(seq, "    Outbound Peer Support      : %s\n",
 697                   (sb->
 698                    iop_capabilities & 0x00000020) ? "Supported" :
 699                   "Not supported");
 700        seq_printf(seq, "    Peer to Peer Support       : %s\n",
 701                   (sb->
 702                    iop_capabilities & 0x00000040) ? "Supported" :
 703                   "Not supported");
 704
 705        seq_printf(seq, "Desired private memory size   : %d kB\n",
 706                   sb->desired_mem_size >> 10);
 707        seq_printf(seq, "Allocated private memory size : %d kB\n",
 708                   sb->current_mem_size >> 10);
 709        seq_printf(seq, "Private memory base address   : %0#10x\n",
 710                   sb->current_mem_base);
 711        seq_printf(seq, "Desired private I/O size      : %d kB\n",
 712                   sb->desired_io_size >> 10);
 713        seq_printf(seq, "Allocated private I/O size    : %d kB\n",
 714                   sb->current_io_size >> 10);
 715        seq_printf(seq, "Private I/O base address      : %0#10x\n",
 716                   sb->current_io_base);
 717
 718        return 0;
 719}
 720
 721static int i2o_seq_show_hw(struct seq_file *seq, void *v)
 722{
 723        struct i2o_controller *c = (struct i2o_controller *)seq->private;
 724        static u32 work32[5];
 725        static u8 *work8 = (u8 *) work32;
 726        static u16 *work16 = (u16 *) work32;
 727        int token;
 728        u32 hwcap;
 729
 730        static char *cpu_table[] = {
 731                "Intel 80960 series",
 732                "AMD2900 series",
 733                "Motorola 68000 series",
 734                "ARM series",
 735                "MIPS series",
 736                "Sparc series",
 737                "PowerPC series",
 738                "Intel x86 series"
 739        };
 740
 741        token =
 742            i2o_parm_field_get(c->exec, 0x0000, -1, &work32, sizeof(work32));
 743
 744        if (token < 0) {
 745                i2o_report_query_status(seq, token, "0x0000 IOP Hardware");
 746                return 0;
 747        }
 748
 749        seq_printf(seq, "I2O Vendor ID    : %0#6x\n", work16[0]);
 750        seq_printf(seq, "Product ID       : %0#6x\n", work16[1]);
 751        seq_printf(seq, "CPU              : ");
 752        if (work8[16] > 8)
 753                seq_printf(seq, "Unknown\n");
 754        else
 755                seq_printf(seq, "%s\n", cpu_table[work8[16]]);
 756        /* Anyone using ProcessorVersion? */
 757
 758        seq_printf(seq, "RAM              : %dkB\n", work32[1] >> 10);
 759        seq_printf(seq, "Non-Volatile Mem : %dkB\n", work32[2] >> 10);
 760
 761        hwcap = work32[3];
 762        seq_printf(seq, "Capabilities : 0x%08x\n", hwcap);
 763        seq_printf(seq, "   [%s] Self booting\n",
 764                   (hwcap & 0x00000001) ? "+" : "-");
 765        seq_printf(seq, "   [%s] Upgradable IRTOS\n",
 766                   (hwcap & 0x00000002) ? "+" : "-");
 767        seq_printf(seq, "   [%s] Supports downloading DDMs\n",
 768                   (hwcap & 0x00000004) ? "+" : "-");
 769        seq_printf(seq, "   [%s] Supports installing DDMs\n",
 770                   (hwcap & 0x00000008) ? "+" : "-");
 771        seq_printf(seq, "   [%s] Battery-backed RAM\n",
 772                   (hwcap & 0x00000010) ? "+" : "-");
 773
 774        return 0;
 775}
 776
 777/* Executive group 0003h - Executing DDM List (table) */
 778static int i2o_seq_show_ddm_table(struct seq_file *seq, void *v)
 779{
 780        struct i2o_controller *c = (struct i2o_controller *)seq->private;
 781        int token;
 782        int i;
 783
 784        typedef struct _i2o_exec_execute_ddm_table {
 785                u16 ddm_tid;
 786                u8 module_type;
 787                u8 reserved;
 788                u16 i2o_vendor_id;
 789                u16 module_id;
 790                u8 module_name_version[28];
 791                u32 data_size;
 792                u32 code_size;
 793        } i2o_exec_execute_ddm_table;
 794
 795        struct {
 796                u16 result_count;
 797                u16 pad;
 798                u16 block_size;
 799                u8 block_status;
 800                u8 error_info_size;
 801                u16 row_count;
 802                u16 more_flag;
 803                i2o_exec_execute_ddm_table ddm_table[I2O_MAX_MODULES];
 804        } *result;
 805
 806        i2o_exec_execute_ddm_table ddm_table;
 807
 808        result = kmalloc(sizeof(*result), GFP_KERNEL);
 809        if (!result)
 810                return -ENOMEM;
 811
 812        token = i2o_parm_table_get(c->exec, I2O_PARAMS_TABLE_GET, 0x0003, -1,
 813                                   NULL, 0, result, sizeof(*result));
 814
 815        if (token < 0) {
 816                i2o_report_query_status(seq, token,
 817                                        "0x0003 Executing DDM List");
 818                goto out;
 819        }
 820
 821        seq_printf(seq,
 822                   "Tid   Module_type     Vendor Mod_id  Module_name             Vrs  Data_size Code_size\n");
 823        ddm_table = result->ddm_table[0];
 824
 825        for (i = 0; i < result->row_count; ddm_table = result->ddm_table[++i]) {
 826                seq_printf(seq, "0x%03x ", ddm_table.ddm_tid & 0xFFF);
 827
 828                switch (ddm_table.module_type) {
 829                case 0x01:
 830                        seq_printf(seq, "Downloaded DDM  ");
 831                        break;
 832                case 0x22:
 833                        seq_printf(seq, "Embedded DDM    ");
 834                        break;
 835                default:
 836                        seq_printf(seq, "                ");
 837                }
 838
 839                seq_printf(seq, "%-#7x", ddm_table.i2o_vendor_id);
 840                seq_printf(seq, "%-#8x", ddm_table.module_id);
 841                seq_printf(seq, "%-29s",
 842                           chtostr(ddm_table.module_name_version, 28));
 843                seq_printf(seq, "%9d  ", ddm_table.data_size);
 844                seq_printf(seq, "%8d", ddm_table.code_size);
 845
 846                seq_printf(seq, "\n");
 847        }
 848      out:
 849        kfree(result);
 850        return 0;
 851}
 852
 853/* Executive group 0004h - Driver Store (scalar) */
 854static int i2o_seq_show_driver_store(struct seq_file *seq, void *v)
 855{
 856        struct i2o_controller *c = (struct i2o_controller *)seq->private;
 857        u32 work32[8];
 858        int token;
 859
 860        token =
 861            i2o_parm_field_get(c->exec, 0x0004, -1, &work32, sizeof(work32));
 862        if (token < 0) {
 863                i2o_report_query_status(seq, token, "0x0004 Driver Store");
 864                return 0;
 865        }
 866
 867        seq_printf(seq, "Module limit  : %d\n"
 868                   "Module count  : %d\n"
 869                   "Current space : %d kB\n"
 870                   "Free space    : %d kB\n",
 871                   work32[0], work32[1], work32[2] >> 10, work32[3] >> 10);
 872
 873        return 0;
 874}
 875
 876/* Executive group 0005h - Driver Store Table (table) */
 877static int i2o_seq_show_drivers_stored(struct seq_file *seq, void *v)
 878{
 879        typedef struct _i2o_driver_store {
 880                u16 stored_ddm_index;
 881                u8 module_type;
 882                u8 reserved;
 883                u16 i2o_vendor_id;
 884                u16 module_id;
 885                u8 module_name_version[28];
 886                u8 date[8];
 887                u32 module_size;
 888                u32 mpb_size;
 889                u32 module_flags;
 890        } i2o_driver_store_table;
 891
 892        struct i2o_controller *c = (struct i2o_controller *)seq->private;
 893        int token;
 894        int i;
 895
 896        typedef struct {
 897                u16 result_count;
 898                u16 pad;
 899                u16 block_size;
 900                u8 block_status;
 901                u8 error_info_size;
 902                u16 row_count;
 903                u16 more_flag;
 904                i2o_driver_store_table dst[I2O_MAX_MODULES];
 905        } i2o_driver_result_table;
 906
 907        i2o_driver_result_table *result;
 908        i2o_driver_store_table *dst;
 909
 910        result = kmalloc(sizeof(i2o_driver_result_table), GFP_KERNEL);
 911        if (result == NULL)
 912                return -ENOMEM;
 913
 914        token = i2o_parm_table_get(c->exec, I2O_PARAMS_TABLE_GET, 0x0005, -1,
 915                                   NULL, 0, result, sizeof(*result));
 916
 917        if (token < 0) {
 918                i2o_report_query_status(seq, token,
 919                                        "0x0005 DRIVER STORE TABLE");
 920                kfree(result);
 921                return 0;
 922        }
 923
 924        seq_printf(seq,
 925                   "#  Module_type     Vendor Mod_id  Module_name             Vrs"
 926                   "Date     Mod_size Par_size Flags\n");
 927        for (i = 0, dst = &result->dst[0]; i < result->row_count;
 928             dst = &result->dst[++i]) {
 929                seq_printf(seq, "%-3d", dst->stored_ddm_index);
 930                switch (dst->module_type) {
 931                case 0x01:
 932                        seq_printf(seq, "Downloaded DDM  ");
 933                        break;
 934                case 0x22:
 935                        seq_printf(seq, "Embedded DDM    ");
 936                        break;
 937                default:
 938                        seq_printf(seq, "                ");
 939                }
 940
 941                seq_printf(seq, "%-#7x", dst->i2o_vendor_id);
 942                seq_printf(seq, "%-#8x", dst->module_id);
 943                seq_printf(seq, "%-29s", chtostr(dst->module_name_version, 28));
 944                seq_printf(seq, "%-9s", chtostr(dst->date, 8));
 945                seq_printf(seq, "%8d ", dst->module_size);
 946                seq_printf(seq, "%8d ", dst->mpb_size);
 947                seq_printf(seq, "0x%04x", dst->module_flags);
 948                seq_printf(seq, "\n");
 949        }
 950
 951        kfree(result);
 952        return 0;
 953}
 954
 955/* Generic group F000h - Params Descriptor (table) */
 956static int i2o_seq_show_groups(struct seq_file *seq, void *v)
 957{
 958        struct i2o_device *d = (struct i2o_device *)seq->private;
 959        int token;
 960        int i;
 961        u8 properties;
 962
 963        typedef struct _i2o_group_info {
 964                u16 group_number;
 965                u16 field_count;
 966                u16 row_count;
 967                u8 properties;
 968                u8 reserved;
 969        } i2o_group_info;
 970
 971        struct {
 972                u16 result_count;
 973                u16 pad;
 974                u16 block_size;
 975                u8 block_status;
 976                u8 error_info_size;
 977                u16 row_count;
 978                u16 more_flag;
 979                i2o_group_info group[256];
 980        } *result;
 981
 982        result = kmalloc(sizeof(*result), GFP_KERNEL);
 983        if (!result)
 984                return -ENOMEM;
 985
 986        token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF000, -1, NULL, 0,
 987                                   result, sizeof(*result));
 988
 989        if (token < 0) {
 990                i2o_report_query_status(seq, token, "0xF000 Params Descriptor");
 991                goto out;
 992        }
 993
 994        seq_printf(seq,
 995                   "#  Group   FieldCount RowCount Type   Add Del Clear\n");
 996
 997        for (i = 0; i < result->row_count; i++) {
 998                seq_printf(seq, "%-3d", i);
 999                seq_printf(seq, "0x%04X ", result->group[i].group_number);
1000                seq_printf(seq, "%10d ", result->group[i].field_count);
1001                seq_printf(seq, "%8d ", result->group[i].row_count);
1002
1003                properties = result->group[i].properties;
1004                if (properties & 0x1)
1005                        seq_printf(seq, "Table  ");
1006                else
1007                        seq_printf(seq, "Scalar ");
1008                if (properties & 0x2)
1009                        seq_printf(seq, " + ");
1010                else
1011                        seq_printf(seq, " - ");
1012                if (properties & 0x4)
1013                        seq_printf(seq, "  + ");
1014                else
1015                        seq_printf(seq, "  - ");
1016                if (properties & 0x8)
1017                        seq_printf(seq, "  + ");
1018                else
1019                        seq_printf(seq, "  - ");
1020
1021                seq_printf(seq, "\n");
1022        }
1023
1024        if (result->more_flag)
1025                seq_printf(seq, "There is more...\n");
1026      out:
1027        kfree(result);
1028        return 0;
1029}
1030
1031/* Generic group F001h - Physical Device Table (table) */
1032static int i2o_seq_show_phys_device(struct seq_file *seq, void *v)
1033{
1034        struct i2o_device *d = (struct i2o_device *)seq->private;
1035        int token;
1036        int i;
1037
1038        struct {
1039                u16 result_count;
1040                u16 pad;
1041                u16 block_size;
1042                u8 block_status;
1043                u8 error_info_size;
1044                u16 row_count;
1045                u16 more_flag;
1046                u32 adapter_id[64];
1047        } result;
1048
1049        token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF001, -1, NULL, 0,
1050                                   &result, sizeof(result));
1051
1052        if (token < 0) {
1053                i2o_report_query_status(seq, token,
1054                                        "0xF001 Physical Device Table");
1055                return 0;
1056        }
1057
1058        if (result.row_count)
1059                seq_printf(seq, "#  AdapterId\n");
1060
1061        for (i = 0; i < result.row_count; i++) {
1062                seq_printf(seq, "%-2d", i);
1063                seq_printf(seq, "%#7x\n", result.adapter_id[i]);
1064        }
1065
1066        if (result.more_flag)
1067                seq_printf(seq, "There is more...\n");
1068
1069        return 0;
1070}
1071
1072/* Generic group F002h - Claimed Table (table) */
1073static int i2o_seq_show_claimed(struct seq_file *seq, void *v)
1074{
1075        struct i2o_device *d = (struct i2o_device *)seq->private;
1076        int token;
1077        int i;
1078
1079        struct {
1080                u16 result_count;
1081                u16 pad;
1082                u16 block_size;
1083                u8 block_status;
1084                u8 error_info_size;
1085                u16 row_count;
1086                u16 more_flag;
1087                u16 claimed_tid[64];
1088        } result;
1089
1090        token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF002, -1, NULL, 0,
1091                                   &result, sizeof(result));
1092
1093        if (token < 0) {
1094                i2o_report_query_status(seq, token, "0xF002 Claimed Table");
1095                return 0;
1096        }
1097
1098        if (result.row_count)
1099                seq_printf(seq, "#  ClaimedTid\n");
1100
1101        for (i = 0; i < result.row_count; i++) {
1102                seq_printf(seq, "%-2d", i);
1103                seq_printf(seq, "%#7x\n", result.claimed_tid[i]);
1104        }
1105
1106        if (result.more_flag)
1107                seq_printf(seq, "There is more...\n");
1108
1109        return 0;
1110}
1111
1112/* Generic group F003h - User Table (table) */
1113static int i2o_seq_show_users(struct seq_file *seq, void *v)
1114{
1115        struct i2o_device *d = (struct i2o_device *)seq->private;
1116        int token;
1117        int i;
1118
1119        typedef struct _i2o_user_table {
1120                u16 instance;
1121                u16 user_tid;
1122                u8 claim_type;
1123                u8 reserved1;
1124                u16 reserved2;
1125        } i2o_user_table;
1126
1127        struct {
1128                u16 result_count;
1129                u16 pad;
1130                u16 block_size;
1131                u8 block_status;
1132                u8 error_info_size;
1133                u16 row_count;
1134                u16 more_flag;
1135                i2o_user_table user[64];
1136        } *result;
1137
1138        result = kmalloc(sizeof(*result), GFP_KERNEL);
1139        if (!result)
1140                return -ENOMEM;
1141
1142        token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF003, -1, NULL, 0,
1143                                   result, sizeof(*result));
1144
1145        if (token < 0) {
1146                i2o_report_query_status(seq, token, "0xF003 User Table");
1147                goto out;
1148        }
1149
1150        seq_printf(seq, "#  Instance UserTid ClaimType\n");
1151
1152        for (i = 0; i < result->row_count; i++) {
1153                seq_printf(seq, "%-3d", i);
1154                seq_printf(seq, "%#8x ", result->user[i].instance);
1155                seq_printf(seq, "%#7x ", result->user[i].user_tid);
1156                seq_printf(seq, "%#9x\n", result->user[i].claim_type);
1157        }
1158
1159        if (result->more_flag)
1160                seq_printf(seq, "There is more...\n");
1161      out:
1162        kfree(result);
1163        return 0;
1164}
1165
1166/* Generic group F005h - Private message extensions (table) (optional) */
1167static int i2o_seq_show_priv_msgs(struct seq_file *seq, void *v)
1168{
1169        struct i2o_device *d = (struct i2o_device *)seq->private;
1170        int token;
1171        int i;
1172
1173        typedef struct _i2o_private {
1174                u16 ext_instance;
1175                u16 organization_id;
1176                u16 x_function_code;
1177        } i2o_private;
1178
1179        struct {
1180                u16 result_count;
1181                u16 pad;
1182                u16 block_size;
1183                u8 block_status;
1184                u8 error_info_size;
1185                u16 row_count;
1186                u16 more_flag;
1187                i2o_private extension[64];
1188        } result;
1189
1190        token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF000, -1, NULL, 0,
1191                                   &result, sizeof(result));
1192
1193        if (token < 0) {
1194                i2o_report_query_status(seq, token,
1195                                        "0xF005 Private Message Extensions (optional)");
1196                return 0;
1197        }
1198
1199        seq_printf(seq, "Instance#  OrgId  FunctionCode\n");
1200
1201        for (i = 0; i < result.row_count; i++) {
1202                seq_printf(seq, "%0#9x ", result.extension[i].ext_instance);
1203                seq_printf(seq, "%0#6x ", result.extension[i].organization_id);
1204                seq_printf(seq, "%0#6x", result.extension[i].x_function_code);
1205
1206                seq_printf(seq, "\n");
1207        }
1208
1209        if (result.more_flag)
1210                seq_printf(seq, "There is more...\n");
1211
1212        return 0;
1213}
1214
1215/* Generic group F006h - Authorized User Table (table) */
1216static int i2o_seq_show_authorized_users(struct seq_file *seq, void *v)
1217{
1218        struct i2o_device *d = (struct i2o_device *)seq->private;
1219        int token;
1220        int i;
1221
1222        struct {
1223                u16 result_count;
1224                u16 pad;
1225                u16 block_size;
1226                u8 block_status;
1227                u8 error_info_size;
1228                u16 row_count;
1229                u16 more_flag;
1230                u32 alternate_tid[64];
1231        } result;
1232
1233        token = i2o_parm_table_get(d, I2O_PARAMS_TABLE_GET, 0xF006, -1, NULL, 0,
1234                                   &result, sizeof(result));
1235
1236        if (token < 0) {
1237                i2o_report_query_status(seq, token,
1238                                        "0xF006 Autohorized User Table");
1239                return 0;
1240        }
1241
1242        if (result.row_count)
1243                seq_printf(seq, "#  AlternateTid\n");
1244
1245        for (i = 0; i < result.row_count; i++) {
1246                seq_printf(seq, "%-2d", i);
1247                seq_printf(seq, "%#7x ", result.alternate_tid[i]);
1248        }
1249
1250        if (result.more_flag)
1251                seq_printf(seq, "There is more...\n");
1252
1253        return 0;
1254}
1255
1256/* Generic group F100h - Device Identity (scalar) */
1257static int i2o_seq_show_dev_identity(struct seq_file *seq, void *v)
1258{
1259        struct i2o_device *d = (struct i2o_device *)seq->private;
1260        static u32 work32[128]; // allow for "stuff" + up to 256 byte (max) serial number
1261        // == (allow) 512d bytes (max)
1262        static u16 *work16 = (u16 *) work32;
1263        int token;
1264
1265        token = i2o_parm_field_get(d, 0xF100, -1, &work32, sizeof(work32));
1266
1267        if (token < 0) {
1268                i2o_report_query_status(seq, token, "0xF100 Device Identity");
1269                return 0;
1270        }
1271
1272        seq_printf(seq, "Device Class  : %s\n", i2o_get_class_name(work16[0]));
1273        seq_printf(seq, "Owner TID     : %0#5x\n", work16[2]);
1274        seq_printf(seq, "Parent TID    : %0#5x\n", work16[3]);
1275        seq_printf(seq, "Vendor info   : %s\n",
1276                   chtostr((u8 *) (work32 + 2), 16));
1277        seq_printf(seq, "Product info  : %s\n",
1278                   chtostr((u8 *) (work32 + 6), 16));
1279        seq_printf(seq, "Description   : %s\n",
1280                   chtostr((u8 *) (work32 + 10), 16));
1281        seq_printf(seq, "Product rev.  : %s\n",
1282                   chtostr((u8 *) (work32 + 14), 8));
1283
1284        seq_printf(seq, "Serial number : ");
1285        print_serial_number(seq, (u8 *) (work32 + 16),
1286                            /* allow for SNLen plus
1287                             * possible trailing '\0'
1288                             */
1289                            sizeof(work32) - (16 * sizeof(u32)) - 2);
1290        seq_printf(seq, "\n");
1291
1292        return 0;
1293}
1294
1295static int i2o_seq_show_dev_name(struct seq_file *seq, void *v)
1296{
1297        struct i2o_device *d = (struct i2o_device *)seq->private;
1298
1299        seq_printf(seq, "%s\n", dev_name(&d->device));
1300
1301        return 0;
1302}
1303
1304/* Generic group F101h - DDM Identity (scalar) */
1305static int i2o_seq_show_ddm_identity(struct seq_file *seq, void *v)
1306{
1307        struct i2o_device *d = (struct i2o_device *)seq->private;
1308        int token;
1309
1310        struct {
1311                u16 ddm_tid;
1312                u8 module_name[24];
1313                u8 module_rev[8];
1314                u8 sn_format;
1315                u8 serial_number[12];
1316                u8 pad[256];    // allow up to 256 byte (max) serial number
1317        } result;
1318
1319        token = i2o_parm_field_get(d, 0xF101, -1, &result, sizeof(result));
1320
1321        if (token < 0) {
1322                i2o_report_query_status(seq, token, "0xF101 DDM Identity");
1323                return 0;
1324        }
1325
1326        seq_printf(seq, "Registering DDM TID : 0x%03x\n", result.ddm_tid);
1327        seq_printf(seq, "Module name         : %s\n",
1328                   chtostr(result.module_name, 24));
1329        seq_printf(seq, "Module revision     : %s\n",
1330                   chtostr(result.module_rev, 8));
1331
1332        seq_printf(seq, "Serial number       : ");
1333        print_serial_number(seq, result.serial_number, sizeof(result) - 36);
1334        /* allow for SNLen plus possible trailing '\0' */
1335
1336        seq_printf(seq, "\n");
1337
1338        return 0;
1339}
1340
1341/* Generic group F102h - User Information (scalar) */
1342static int i2o_seq_show_uinfo(struct seq_file *seq, void *v)
1343{
1344        struct i2o_device *d = (struct i2o_device *)seq->private;
1345        int token;
1346
1347        struct {
1348                u8 device_name[64];
1349                u8 service_name[64];
1350                u8 physical_location[64];
1351                u8 instance_number[4];
1352        } result;
1353
1354        token = i2o_parm_field_get(d, 0xF102, -1, &result, sizeof(result));
1355
1356        if (token < 0) {
1357                i2o_report_query_status(seq, token, "0xF102 User Information");
1358                return 0;
1359        }
1360
1361        seq_printf(seq, "Device name     : %s\n",
1362                   chtostr(result.device_name, 64));
1363        seq_printf(seq, "Service name    : %s\n",
1364                   chtostr(result.service_name, 64));
1365        seq_printf(seq, "Physical name   : %s\n",
1366                   chtostr(result.physical_location, 64));
1367        seq_printf(seq, "Instance number : %s\n",
1368                   chtostr(result.instance_number, 4));
1369
1370        return 0;
1371}
1372
1373/* Generic group F103h - SGL Operating Limits (scalar) */
1374static int i2o_seq_show_sgl_limits(struct seq_file *seq, void *v)
1375{
1376        struct i2o_device *d = (struct i2o_device *)seq->private;
1377        static u32 work32[12];
1378        static u16 *work16 = (u16 *) work32;
1379        static u8 *work8 = (u8 *) work32;
1380        int token;
1381
1382        token = i2o_parm_field_get(d, 0xF103, -1, &work32, sizeof(work32));
1383
1384        if (token < 0) {
1385                i2o_report_query_status(seq, token,
1386                                        "0xF103 SGL Operating Limits");
1387                return 0;
1388        }
1389
1390        seq_printf(seq, "SGL chain size        : %d\n", work32[0]);
1391        seq_printf(seq, "Max SGL chain size    : %d\n", work32[1]);
1392        seq_printf(seq, "SGL chain size target : %d\n", work32[2]);
1393        seq_printf(seq, "SGL frag count        : %d\n", work16[6]);
1394        seq_printf(seq, "Max SGL frag count    : %d\n", work16[7]);
1395        seq_printf(seq, "SGL frag count target : %d\n", work16[8]);
1396
1397/* FIXME
1398        if (d->i2oversion == 0x02)
1399        {
1400*/
1401        seq_printf(seq, "SGL data alignment    : %d\n", work16[8]);
1402        seq_printf(seq, "SGL addr limit        : %d\n", work8[20]);
1403        seq_printf(seq, "SGL addr sizes supported : ");
1404        if (work8[21] & 0x01)
1405                seq_printf(seq, "32 bit ");
1406        if (work8[21] & 0x02)
1407                seq_printf(seq, "64 bit ");
1408        if (work8[21] & 0x04)
1409                seq_printf(seq, "96 bit ");
1410        if (work8[21] & 0x08)
1411                seq_printf(seq, "128 bit ");
1412        seq_printf(seq, "\n");
1413/*
1414        }
1415*/
1416
1417        return 0;
1418}
1419
1420/* Generic group F200h - Sensors (scalar) */
1421static int i2o_seq_show_sensors(struct seq_file *seq, void *v)
1422{
1423        struct i2o_device *d = (struct i2o_device *)seq->private;
1424        int token;
1425
1426        struct {
1427                u16 sensor_instance;
1428                u8 component;
1429                u16 component_instance;
1430                u8 sensor_class;
1431                u8 sensor_type;
1432                u8 scaling_exponent;
1433                u32 actual_reading;
1434                u32 minimum_reading;
1435                u32 low2lowcat_treshold;
1436                u32 lowcat2low_treshold;
1437                u32 lowwarn2low_treshold;
1438                u32 low2lowwarn_treshold;
1439                u32 norm2lowwarn_treshold;
1440                u32 lowwarn2norm_treshold;
1441                u32 nominal_reading;
1442                u32 hiwarn2norm_treshold;
1443                u32 norm2hiwarn_treshold;
1444                u32 high2hiwarn_treshold;
1445                u32 hiwarn2high_treshold;
1446                u32 hicat2high_treshold;
1447                u32 hi2hicat_treshold;
1448                u32 maximum_reading;
1449                u8 sensor_state;
1450                u16 event_enable;
1451        } result;
1452
1453        token = i2o_parm_field_get(d, 0xF200, -1, &result, sizeof(result));
1454
1455        if (token < 0) {
1456                i2o_report_query_status(seq, token,
1457                                        "0xF200 Sensors (optional)");
1458                return 0;
1459        }
1460
1461        seq_printf(seq, "Sensor instance       : %d\n", result.sensor_instance);
1462
1463        seq_printf(seq, "Component             : %d = ", result.component);
1464        switch (result.component) {
1465        case 0:
1466                seq_printf(seq, "Other");
1467                break;
1468        case 1:
1469                seq_printf(seq, "Planar logic Board");
1470                break;
1471        case 2:
1472                seq_printf(seq, "CPU");
1473                break;
1474        case 3:
1475                seq_printf(seq, "Chassis");
1476                break;
1477        case 4:
1478                seq_printf(seq, "Power Supply");
1479                break;
1480        case 5:
1481                seq_printf(seq, "Storage");
1482                break;
1483        case 6:
1484                seq_printf(seq, "External");
1485                break;
1486        }
1487        seq_printf(seq, "\n");
1488
1489        seq_printf(seq, "Component instance    : %d\n",
1490                   result.component_instance);
1491        seq_printf(seq, "Sensor class          : %s\n",
1492                   result.sensor_class ? "Analog" : "Digital");
1493
1494        seq_printf(seq, "Sensor type           : %d = ", result.sensor_type);
1495        switch (result.sensor_type) {
1496        case 0:
1497                seq_printf(seq, "Other\n");
1498                break;
1499        case 1:
1500                seq_printf(seq, "Thermal\n");
1501                break;
1502        case 2:
1503                seq_printf(seq, "DC voltage (DC volts)\n");
1504                break;
1505        case 3:
1506                seq_printf(seq, "AC voltage (AC volts)\n");
1507                break;
1508        case 4:
1509                seq_printf(seq, "DC current (DC amps)\n");
1510                break;
1511        case 5:
1512                seq_printf(seq, "AC current (AC volts)\n");
1513                break;
1514        case 6:
1515                seq_printf(seq, "Door open\n");
1516                break;
1517        case 7:
1518                seq_printf(seq, "Fan operational\n");
1519                break;
1520        }
1521
1522        seq_printf(seq, "Scaling exponent      : %d\n",
1523                   result.scaling_exponent);
1524        seq_printf(seq, "Actual reading        : %d\n", result.actual_reading);
1525        seq_printf(seq, "Minimum reading       : %d\n", result.minimum_reading);
1526        seq_printf(seq, "Low2LowCat treshold   : %d\n",
1527                   result.low2lowcat_treshold);
1528        seq_printf(seq, "LowCat2Low treshold   : %d\n",
1529                   result.lowcat2low_treshold);
1530        seq_printf(seq, "LowWarn2Low treshold  : %d\n",
1531                   result.lowwarn2low_treshold);
1532        seq_printf(seq, "Low2LowWarn treshold  : %d\n",
1533                   result.low2lowwarn_treshold);
1534        seq_printf(seq, "Norm2LowWarn treshold : %d\n",
1535                   result.norm2lowwarn_treshold);
1536        seq_printf(seq, "LowWarn2Norm treshold : %d\n",
1537                   result.lowwarn2norm_treshold);
1538        seq_printf(seq, "Nominal reading       : %d\n", result.nominal_reading);
1539        seq_printf(seq, "HiWarn2Norm treshold  : %d\n",
1540                   result.hiwarn2norm_treshold);
1541        seq_printf(seq, "Norm2HiWarn treshold  : %d\n",
1542                   result.norm2hiwarn_treshold);
1543        seq_printf(seq, "High2HiWarn treshold  : %d\n",
1544                   result.high2hiwarn_treshold);
1545        seq_printf(seq, "HiWarn2High treshold  : %d\n",
1546                   result.hiwarn2high_treshold);
1547        seq_printf(seq, "HiCat2High treshold   : %d\n",
1548                   result.hicat2high_treshold);
1549        seq_printf(seq, "High2HiCat treshold   : %d\n",
1550                   result.hi2hicat_treshold);
1551        seq_printf(seq, "Maximum reading       : %d\n", result.maximum_reading);
1552
1553        seq_printf(seq, "Sensor state          : %d = ", result.sensor_state);
1554        switch (result.sensor_state) {
1555        case 0:
1556                seq_printf(seq, "Normal\n");
1557                break;
1558        case 1:
1559                seq_printf(seq, "Abnormal\n");
1560                break;
1561        case 2:
1562                seq_printf(seq, "Unknown\n");
1563                break;
1564        case 3:
1565                seq_printf(seq, "Low Catastrophic (LoCat)\n");
1566                break;
1567        case 4:
1568                seq_printf(seq, "Low (Low)\n");
1569                break;
1570        case 5:
1571                seq_printf(seq, "Low Warning (LoWarn)\n");
1572                break;
1573        case 6:
1574                seq_printf(seq, "High Warning (HiWarn)\n");
1575                break;
1576        case 7:
1577                seq_printf(seq, "High (High)\n");
1578                break;
1579        case 8:
1580                seq_printf(seq, "High Catastrophic (HiCat)\n");
1581                break;
1582        }
1583
1584        seq_printf(seq, "Event_enable : 0x%02X\n", result.event_enable);
1585        seq_printf(seq, "    [%s] Operational state change. \n",
1586                   (result.event_enable & 0x01) ? "+" : "-");
1587        seq_printf(seq, "    [%s] Low catastrophic. \n",
1588                   (result.event_enable & 0x02) ? "+" : "-");
1589        seq_printf(seq, "    [%s] Low reading. \n",
1590                   (result.event_enable & 0x04) ? "+" : "-");
1591        seq_printf(seq, "    [%s] Low warning. \n",
1592                   (result.event_enable & 0x08) ? "+" : "-");
1593        seq_printf(seq,
1594                   "    [%s] Change back to normal from out of range state. \n",
1595                   (result.event_enable & 0x10) ? "+" : "-");
1596        seq_printf(seq, "    [%s] High warning. \n",
1597                   (result.event_enable & 0x20) ? "+" : "-");
1598        seq_printf(seq, "    [%s] High reading. \n",
1599                   (result.event_enable & 0x40) ? "+" : "-");
1600        seq_printf(seq, "    [%s] High catastrophic. \n",
1601                   (result.event_enable & 0x80) ? "+" : "-");
1602
1603        return 0;
1604}
1605
1606static int i2o_seq_open_hrt(struct inode *inode, struct file *file)
1607{
1608        return single_open(file, i2o_seq_show_hrt, PDE(inode)->data);
1609};
1610
1611static int i2o_seq_open_lct(struct inode *inode, struct file *file)
1612{
1613        return single_open(file, i2o_seq_show_lct, PDE(inode)->data);
1614};
1615
1616static int i2o_seq_open_status(struct inode *inode, struct file *file)
1617{
1618        return single_open(file, i2o_seq_show_status, PDE(inode)->data);
1619};
1620
1621static int i2o_seq_open_hw(struct inode *inode, struct file *file)
1622{
1623        return single_open(file, i2o_seq_show_hw, PDE(inode)->data);
1624};
1625
1626static int i2o_seq_open_ddm_table(struct inode *inode, struct file *file)
1627{
1628        return single_open(file, i2o_seq_show_ddm_table, PDE(inode)->data);
1629};
1630
1631static int i2o_seq_open_driver_store(struct inode *inode, struct file *file)
1632{
1633        return single_open(file, i2o_seq_show_driver_store, PDE(inode)->data);
1634};
1635
1636static int i2o_seq_open_drivers_stored(struct inode *inode, struct file *file)
1637{
1638        return single_open(file, i2o_seq_show_drivers_stored, PDE(inode)->data);
1639};
1640
1641static int i2o_seq_open_groups(struct inode *inode, struct file *file)
1642{
1643        return single_open(file, i2o_seq_show_groups, PDE(inode)->data);
1644};
1645
1646static int i2o_seq_open_phys_device(struct inode *inode, struct file *file)
1647{
1648        return single_open(file, i2o_seq_show_phys_device, PDE(inode)->data);
1649};
1650
1651static int i2o_seq_open_claimed(struct inode *inode, struct file *file)
1652{
1653        return single_open(file, i2o_seq_show_claimed, PDE(inode)->data);
1654};
1655
1656static int i2o_seq_open_users(struct inode *inode, struct file *file)
1657{
1658        return single_open(file, i2o_seq_show_users, PDE(inode)->data);
1659};
1660
1661static int i2o_seq_open_priv_msgs(struct inode *inode, struct file *file)
1662{
1663        return single_open(file, i2o_seq_show_priv_msgs, PDE(inode)->data);
1664};
1665
1666static int i2o_seq_open_authorized_users(struct inode *inode, struct file *file)
1667{
1668        return single_open(file, i2o_seq_show_authorized_users,
1669                           PDE(inode)->data);
1670};
1671
1672static int i2o_seq_open_dev_identity(struct inode *inode, struct file *file)
1673{
1674        return single_open(file, i2o_seq_show_dev_identity, PDE(inode)->data);
1675};
1676
1677static int i2o_seq_open_ddm_identity(struct inode *inode, struct file *file)
1678{
1679        return single_open(file, i2o_seq_show_ddm_identity, PDE(inode)->data);
1680};
1681
1682static int i2o_seq_open_uinfo(struct inode *inode, struct file *file)
1683{
1684        return single_open(file, i2o_seq_show_uinfo, PDE(inode)->data);
1685};
1686
1687static int i2o_seq_open_sgl_limits(struct inode *inode, struct file *file)
1688{
1689        return single_open(file, i2o_seq_show_sgl_limits, PDE(inode)->data);
1690};
1691
1692static int i2o_seq_open_sensors(struct inode *inode, struct file *file)
1693{
1694        return single_open(file, i2o_seq_show_sensors, PDE(inode)->data);
1695};
1696
1697static int i2o_seq_open_dev_name(struct inode *inode, struct file *file)
1698{
1699        return single_open(file, i2o_seq_show_dev_name, PDE(inode)->data);
1700};
1701
1702static const struct file_operations i2o_seq_fops_lct = {
1703        .open = i2o_seq_open_lct,
1704        .read = seq_read,
1705        .llseek = seq_lseek,
1706        .release = single_release,
1707};
1708
1709static const struct file_operations i2o_seq_fops_hrt = {
1710        .open = i2o_seq_open_hrt,
1711        .read = seq_read,
1712        .llseek = seq_lseek,
1713        .release = single_release,
1714};
1715
1716static const struct file_operations i2o_seq_fops_status = {
1717        .open = i2o_seq_open_status,
1718        .read = seq_read,
1719        .llseek = seq_lseek,
1720        .release = single_release,
1721};
1722
1723static const struct file_operations i2o_seq_fops_hw = {
1724        .open = i2o_seq_open_hw,
1725        .read = seq_read,
1726        .llseek = seq_lseek,
1727        .release = single_release,
1728};
1729
1730static const struct file_operations i2o_seq_fops_ddm_table = {
1731        .open = i2o_seq_open_ddm_table,
1732        .read = seq_read,
1733        .llseek = seq_lseek,
1734        .release = single_release,
1735};
1736
1737static const struct file_operations i2o_seq_fops_driver_store = {
1738        .open = i2o_seq_open_driver_store,
1739        .read = seq_read,
1740        .llseek = seq_lseek,
1741        .release = single_release,
1742};
1743
1744static const struct file_operations i2o_seq_fops_drivers_stored = {
1745        .open = i2o_seq_open_drivers_stored,
1746        .read = seq_read,
1747        .llseek = seq_lseek,
1748        .release = single_release,
1749};
1750
1751static const struct file_operations i2o_seq_fops_groups = {
1752        .open = i2o_seq_open_groups,
1753        .read = seq_read,
1754        .llseek = seq_lseek,
1755        .release = single_release,
1756};
1757
1758static const struct file_operations i2o_seq_fops_phys_device = {
1759        .open = i2o_seq_open_phys_device,
1760        .read = seq_read,
1761        .llseek = seq_lseek,
1762        .release = single_release,
1763};
1764
1765static const struct file_operations i2o_seq_fops_claimed = {
1766        .open = i2o_seq_open_claimed,
1767        .read = seq_read,
1768        .llseek = seq_lseek,
1769        .release = single_release,
1770};
1771
1772static const struct file_operations i2o_seq_fops_users = {
1773        .open = i2o_seq_open_users,
1774        .read = seq_read,
1775        .llseek = seq_lseek,
1776        .release = single_release,
1777};
1778
1779static const struct file_operations i2o_seq_fops_priv_msgs = {
1780        .open = i2o_seq_open_priv_msgs,
1781        .read = seq_read,
1782        .llseek = seq_lseek,
1783        .release = single_release,
1784};
1785
1786static const struct file_operations i2o_seq_fops_authorized_users = {
1787        .open = i2o_seq_open_authorized_users,
1788        .read = seq_read,
1789        .llseek = seq_lseek,
1790        .release = single_release,
1791};
1792
1793static const struct file_operations i2o_seq_fops_dev_name = {
1794        .open = i2o_seq_open_dev_name,
1795        .read = seq_read,
1796        .llseek = seq_lseek,
1797        .release = single_release,
1798};
1799
1800static const struct file_operations i2o_seq_fops_dev_identity = {
1801        .open = i2o_seq_open_dev_identity,
1802        .read = seq_read,
1803        .llseek = seq_lseek,
1804        .release = single_release,
1805};
1806
1807static const struct file_operations i2o_seq_fops_ddm_identity = {
1808        .open = i2o_seq_open_ddm_identity,
1809        .read = seq_read,
1810        .llseek = seq_lseek,
1811        .release = single_release,
1812};
1813
1814static const struct file_operations i2o_seq_fops_uinfo = {
1815        .open = i2o_seq_open_uinfo,
1816        .read = seq_read,
1817        .llseek = seq_lseek,
1818        .release = single_release,
1819};
1820
1821static const struct file_operations i2o_seq_fops_sgl_limits = {
1822        .open = i2o_seq_open_sgl_limits,
1823        .read = seq_read,
1824        .llseek = seq_lseek,
1825        .release = single_release,
1826};
1827
1828static const struct file_operations i2o_seq_fops_sensors = {
1829        .open = i2o_seq_open_sensors,
1830        .read = seq_read,
1831        .llseek = seq_lseek,
1832        .release = single_release,
1833};
1834
1835/*
1836 * IOP specific entries...write field just in case someone
1837 * ever wants one.
1838 */
1839static i2o_proc_entry i2o_proc_generic_iop_entries[] = {
1840        {"hrt", S_IFREG | S_IRUGO, &i2o_seq_fops_hrt},
1841        {"lct", S_IFREG | S_IRUGO, &i2o_seq_fops_lct},
1842        {"status", S_IFREG | S_IRUGO, &i2o_seq_fops_status},
1843        {"hw", S_IFREG | S_IRUGO, &i2o_seq_fops_hw},
1844        {"ddm_table", S_IFREG | S_IRUGO, &i2o_seq_fops_ddm_table},
1845        {"driver_store", S_IFREG | S_IRUGO, &i2o_seq_fops_driver_store},
1846        {"drivers_stored", S_IFREG | S_IRUGO, &i2o_seq_fops_drivers_stored},
1847        {NULL, 0, NULL}
1848};
1849
1850/*
1851 * Device specific entries
1852 */
1853static i2o_proc_entry generic_dev_entries[] = {
1854        {"groups", S_IFREG | S_IRUGO, &i2o_seq_fops_groups},
1855        {"phys_dev", S_IFREG | S_IRUGO, &i2o_seq_fops_phys_device},
1856        {"claimed", S_IFREG | S_IRUGO, &i2o_seq_fops_claimed},
1857        {"users", S_IFREG | S_IRUGO, &i2o_seq_fops_users},
1858        {"priv_msgs", S_IFREG | S_IRUGO, &i2o_seq_fops_priv_msgs},
1859        {"authorized_users", S_IFREG | S_IRUGO, &i2o_seq_fops_authorized_users},
1860        {"dev_identity", S_IFREG | S_IRUGO, &i2o_seq_fops_dev_identity},
1861        {"ddm_identity", S_IFREG | S_IRUGO, &i2o_seq_fops_ddm_identity},
1862        {"user_info", S_IFREG | S_IRUGO, &i2o_seq_fops_uinfo},
1863        {"sgl_limits", S_IFREG | S_IRUGO, &i2o_seq_fops_sgl_limits},
1864        {"sensors", S_IFREG | S_IRUGO, &i2o_seq_fops_sensors},
1865        {NULL, 0, NULL}
1866};
1867
1868/*
1869 *  Storage unit specific entries (SCSI Periph, BS) with device names
1870 */
1871static i2o_proc_entry rbs_dev_entries[] = {
1872        {"dev_name", S_IFREG | S_IRUGO, &i2o_seq_fops_dev_name},
1873        {NULL, 0, NULL}
1874};
1875
1876/**
1877 *      i2o_proc_create_entries - Creates proc dir entries
1878 *      @dir: proc dir entry under which the entries should be placed
1879 *      @i2o_pe: pointer to the entries which should be added
1880 *      @data: pointer to I2O controller or device
1881 *
1882 *      Create proc dir entries for a I2O controller or I2O device.
1883 *
1884 *      Returns 0 on success or negative error code on failure.
1885 */
1886static int i2o_proc_create_entries(struct proc_dir_entry *dir,
1887                                   i2o_proc_entry * i2o_pe, void *data)
1888{
1889        struct proc_dir_entry *tmp;
1890
1891        while (i2o_pe->name) {
1892                tmp = proc_create_data(i2o_pe->name, i2o_pe->mode, dir,
1893                                       i2o_pe->fops, data);
1894                if (!tmp)
1895                        return -1;
1896
1897                i2o_pe++;
1898        }
1899
1900        return 0;
1901}
1902
1903/**
1904 *      i2o_proc_subdir_remove - Remove child entries from a proc entry
1905 *      @dir: proc dir entry from which the childs should be removed
1906 *
1907 *      Iterate over each i2o proc entry under dir and remove it. If the child
1908 *      also has entries, remove them too.
1909 */
1910static void i2o_proc_subdir_remove(struct proc_dir_entry *dir)
1911{
1912        struct proc_dir_entry *pe, *tmp;
1913        pe = dir->subdir;
1914        while (pe) {
1915                tmp = pe->next;
1916                i2o_proc_subdir_remove(pe);
1917                remove_proc_entry(pe->name, dir);
1918                pe = tmp;
1919        }
1920};
1921
1922/**
1923 *      i2o_proc_device_add - Add an I2O device to the proc dir
1924 *      @dir: proc dir entry to which the device should be added
1925 *      @dev: I2O device which should be added
1926 *
1927 *      Add an I2O device to the proc dir entry dir and create the entries for
1928 *      the device depending on the class of the I2O device.
1929 */
1930static void i2o_proc_device_add(struct proc_dir_entry *dir,
1931                                struct i2o_device *dev)
1932{
1933        char buff[10];
1934        struct proc_dir_entry *devdir;
1935        i2o_proc_entry *i2o_pe = NULL;
1936
1937        sprintf(buff, "%03x", dev->lct_data.tid);
1938
1939        osm_debug("adding device /proc/i2o/%s/%s\n", dev->iop->name, buff);
1940
1941        devdir = proc_mkdir(buff, dir);
1942        if (!devdir) {
1943                osm_warn("Could not allocate procdir!\n");
1944                return;
1945        }
1946
1947        devdir->data = dev;
1948
1949        i2o_proc_create_entries(devdir, generic_dev_entries, dev);
1950
1951        /* Inform core that we want updates about this device's status */
1952        switch (dev->lct_data.class_id) {
1953        case I2O_CLASS_SCSI_PERIPHERAL:
1954        case I2O_CLASS_RANDOM_BLOCK_STORAGE:
1955                i2o_pe = rbs_dev_entries;
1956                break;
1957        default:
1958                break;
1959        }
1960        if (i2o_pe)
1961                i2o_proc_create_entries(devdir, i2o_pe, dev);
1962}
1963
1964/**
1965 *      i2o_proc_iop_add - Add an I2O controller to the i2o proc tree
1966 *      @dir: parent proc dir entry
1967 *      @c: I2O controller which should be added
1968 *
1969 *      Add the entries to the parent proc dir entry. Also each device is added
1970 *      to the controllers proc dir entry.
1971 *
1972 *      Returns 0 on success or negative error code on failure.
1973 */
1974static int i2o_proc_iop_add(struct proc_dir_entry *dir,
1975                            struct i2o_controller *c)
1976{
1977        struct proc_dir_entry *iopdir;
1978        struct i2o_device *dev;
1979
1980        osm_debug("adding IOP /proc/i2o/%s\n", c->name);
1981
1982        iopdir = proc_mkdir(c->name, dir);
1983        if (!iopdir)
1984                return -1;
1985
1986        iopdir->data = c;
1987
1988        i2o_proc_create_entries(iopdir, i2o_proc_generic_iop_entries, c);
1989
1990        list_for_each_entry(dev, &c->devices, list)
1991            i2o_proc_device_add(iopdir, dev);
1992
1993        return 0;
1994}
1995
1996/**
1997 *      i2o_proc_iop_remove - Removes an I2O controller from the i2o proc tree
1998 *      @dir: parent proc dir entry
1999 *      @c: I2O controller which should be removed
2000 *
2001 *      Iterate over each i2o proc entry and search controller c. If it is found
2002 *      remove it from the tree.
2003 */
2004static void i2o_proc_iop_remove(struct proc_dir_entry *dir,
2005                                struct i2o_controller *c)
2006{
2007        struct proc_dir_entry *pe, *tmp;
2008
2009        pe = dir->subdir;
2010        while (pe) {
2011                tmp = pe->next;
2012                if (pe->data == c) {
2013                        i2o_proc_subdir_remove(pe);
2014                        remove_proc_entry(pe->name, dir);
2015                }
2016                osm_debug("removing IOP /proc/i2o/%s\n", c->name);
2017                pe = tmp;
2018        }
2019}
2020
2021/**
2022 *      i2o_proc_fs_create - Create the i2o proc fs.
2023 *
2024 *      Iterate over each I2O controller and create the entries for it.
2025 *
2026 *      Returns 0 on success or negative error code on failure.
2027 */
2028static int __init i2o_proc_fs_create(void)
2029{
2030        struct i2o_controller *c;
2031
2032        i2o_proc_dir_root = proc_mkdir("i2o", NULL);
2033        if (!i2o_proc_dir_root)
2034                return -1;
2035
2036        list_for_each_entry(c, &i2o_controllers, list)
2037            i2o_proc_iop_add(i2o_proc_dir_root, c);
2038
2039        return 0;
2040};
2041
2042/**
2043 *      i2o_proc_fs_destroy - Cleanup the all i2o proc entries
2044 *
2045 *      Iterate over each I2O controller and remove the entries for it.
2046 *
2047 *      Returns 0 on success or negative error code on failure.
2048 */
2049static int __exit i2o_proc_fs_destroy(void)
2050{
2051        struct i2o_controller *c;
2052
2053        list_for_each_entry(c, &i2o_controllers, list)
2054            i2o_proc_iop_remove(i2o_proc_dir_root, c);
2055
2056        remove_proc_entry("i2o", NULL);
2057
2058        return 0;
2059};
2060
2061/**
2062 *      i2o_proc_init - Init function for procfs
2063 *
2064 *      Registers Proc OSM and creates procfs entries.
2065 *
2066 *      Returns 0 on success or negative error code on failure.
2067 */
2068static int __init i2o_proc_init(void)
2069{
2070        int rc;
2071
2072        printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
2073
2074        rc = i2o_driver_register(&i2o_proc_driver);
2075        if (rc)
2076                return rc;
2077
2078        rc = i2o_proc_fs_create();
2079        if (rc) {
2080                i2o_driver_unregister(&i2o_proc_driver);
2081                return rc;
2082        }
2083
2084        return 0;
2085};
2086
2087/**
2088 *      i2o_proc_exit - Exit function for procfs
2089 *
2090 *      Unregisters Proc OSM and removes procfs entries.
2091 */
2092static void __exit i2o_proc_exit(void)
2093{
2094        i2o_driver_unregister(&i2o_proc_driver);
2095        i2o_proc_fs_destroy();
2096};
2097
2098MODULE_AUTHOR("Deepak Saxena");
2099MODULE_LICENSE("GPL");
2100MODULE_DESCRIPTION(OSM_DESCRIPTION);
2101MODULE_VERSION(OSM_VERSION);
2102
2103module_init(i2o_proc_init);
2104module_exit(i2o_proc_exit);
2105
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.