blob: 07dbeaf9df997b1ff6a64ded115062b183ef7e50 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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:
Jan Engelhardt96de0e22007-10-19 23:21:04 +020022 * Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI),
23 * Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 * 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"
Markus Lidel2e1973a2006-01-06 00:19:32 -080031#define OSM_VERSION "1.316"
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090043#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#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 mode_t mode; /* mode */
Arjan van de Ven99ac48f2006-03-28 01:56:41 -080060 const struct file_operations *fops; /* open function */
Linus Torvalds1da177e2005-04-16 15:20:36 -070061} 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 */
H Hartley Sweetencf302732010-01-07 01:18:23 -0800115 seq_printf(seq, "LAN-48 MAC address @ %pM", &serialno[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 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,
H Hartley Sweetencf302732010-01-07 01:18:23 -0800127 "LAN-64 MAC address @ [?:%02X:%02X:?] %pM",
128 serialno[8], serialno[9], &serialno[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 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 *
Randy Dunlapd9489fb2006-12-06 20:38:43 -0800162 * Return a descriptive string for an i2o class.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 */
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;
Markus Lidelf10378f2005-06-23 22:02:16 -0700227 case I2O_CLASS_BUS_ADAPTER:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 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
Markus Lidelf10378f2005-06-23 22:02:16 -0700489 case I2O_CLASS_BUS_ADAPTER:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 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
Kay Sieverscd3ed6b2009-01-06 10:44:40 -08001299 seq_printf(seq, "%s\n", dev_name(&d->device));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300
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
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001702static const struct file_operations i2o_seq_fops_lct = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 .open = i2o_seq_open_lct,
1704 .read = seq_read,
1705 .llseek = seq_lseek,
1706 .release = single_release,
1707};
1708
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001709static const struct file_operations i2o_seq_fops_hrt = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 .open = i2o_seq_open_hrt,
1711 .read = seq_read,
1712 .llseek = seq_lseek,
1713 .release = single_release,
1714};
1715
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001716static const struct file_operations i2o_seq_fops_status = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 .open = i2o_seq_open_status,
1718 .read = seq_read,
1719 .llseek = seq_lseek,
1720 .release = single_release,
1721};
1722
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001723static const struct file_operations i2o_seq_fops_hw = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 .open = i2o_seq_open_hw,
1725 .read = seq_read,
1726 .llseek = seq_lseek,
1727 .release = single_release,
1728};
1729
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001730static const struct file_operations i2o_seq_fops_ddm_table = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 .open = i2o_seq_open_ddm_table,
1732 .read = seq_read,
1733 .llseek = seq_lseek,
1734 .release = single_release,
1735};
1736
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001737static const struct file_operations i2o_seq_fops_driver_store = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 .open = i2o_seq_open_driver_store,
1739 .read = seq_read,
1740 .llseek = seq_lseek,
1741 .release = single_release,
1742};
1743
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001744static const struct file_operations i2o_seq_fops_drivers_stored = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 .open = i2o_seq_open_drivers_stored,
1746 .read = seq_read,
1747 .llseek = seq_lseek,
1748 .release = single_release,
1749};
1750
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001751static const struct file_operations i2o_seq_fops_groups = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 .open = i2o_seq_open_groups,
1753 .read = seq_read,
1754 .llseek = seq_lseek,
1755 .release = single_release,
1756};
1757
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001758static const struct file_operations i2o_seq_fops_phys_device = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 .open = i2o_seq_open_phys_device,
1760 .read = seq_read,
1761 .llseek = seq_lseek,
1762 .release = single_release,
1763};
1764
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001765static const struct file_operations i2o_seq_fops_claimed = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 .open = i2o_seq_open_claimed,
1767 .read = seq_read,
1768 .llseek = seq_lseek,
1769 .release = single_release,
1770};
1771
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001772static const struct file_operations i2o_seq_fops_users = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 .open = i2o_seq_open_users,
1774 .read = seq_read,
1775 .llseek = seq_lseek,
1776 .release = single_release,
1777};
1778
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001779static const struct file_operations i2o_seq_fops_priv_msgs = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 .open = i2o_seq_open_priv_msgs,
1781 .read = seq_read,
1782 .llseek = seq_lseek,
1783 .release = single_release,
1784};
1785
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001786static const struct file_operations i2o_seq_fops_authorized_users = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 .open = i2o_seq_open_authorized_users,
1788 .read = seq_read,
1789 .llseek = seq_lseek,
1790 .release = single_release,
1791};
1792
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001793static const struct file_operations i2o_seq_fops_dev_name = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 .open = i2o_seq_open_dev_name,
1795 .read = seq_read,
1796 .llseek = seq_lseek,
1797 .release = single_release,
1798};
1799
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001800static const struct file_operations i2o_seq_fops_dev_identity = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 .open = i2o_seq_open_dev_identity,
1802 .read = seq_read,
1803 .llseek = seq_lseek,
1804 .release = single_release,
1805};
1806
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001807static const struct file_operations i2o_seq_fops_ddm_identity = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 .open = i2o_seq_open_ddm_identity,
1809 .read = seq_read,
1810 .llseek = seq_lseek,
1811 .release = single_release,
1812};
1813
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001814static const struct file_operations i2o_seq_fops_uinfo = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 .open = i2o_seq_open_uinfo,
1816 .read = seq_read,
1817 .llseek = seq_lseek,
1818 .release = single_release,
1819};
1820
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001821static const struct file_operations i2o_seq_fops_sgl_limits = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 .open = i2o_seq_open_sgl_limits,
1823 .read = seq_read,
1824 .llseek = seq_lseek,
1825 .release = single_release,
1826};
1827
Arjan van de Vend54b1fd2007-02-12 00:55:34 -08001828static const struct file_operations i2o_seq_fops_sensors = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 .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) {
Denis V. Lunevc7705f3442008-04-29 01:02:35 -07001892 tmp = proc_create_data(i2o_pe->name, i2o_pe->mode, dir,
1893 i2o_pe->fops, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 if (!tmp)
1895 return -1;
1896
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 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
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036 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);