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