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