v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / drivers / ieee1394 / nodemgr.c
1 /*
2  * Node information (ConfigROM) collection and management.
3  *
4  * Copyright (C) 2000 Andreas E. Bombe
5  *               2001 Ben Collins <bcollins@debian.net>
6  *
7  * This code is licensed under the GPL.  See the file COPYING in the root
8  * directory of the kernel sources for details.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/list.h>
13 #include <linux/slab.h>
14 #include <asm/byteorder.h>
15 #include <asm/atomic.h>
16 #include <linux/smp_lock.h>
17 #include <linux/interrupt.h>
18
19 #include "ieee1394_types.h"
20 #include "ieee1394.h"
21 #include "hosts.h"
22 #include "ieee1394_transactions.h"
23 #include "highlevel.h"
24 #include "csr.h"
25 #include "nodemgr.h"
26
27
28 #define NODE_BUS_FMT    "%d:%d"
29 #define NODE_BUS_ARGS(nodeid) \
30         (nodeid & NODE_MASK), ((nodeid & BUS_MASK) >> 6)
31
32 /* Basically what we do here is start off retrieving the bus_info block.
33  * From there will fill in some info about the node, verify it is of IEEE
34  * 1394 type, and that the crc checks out ok. After that we start off with
35  * the root directory, and subdirectories. To do this, we retrieve the
36  * quadlet header for a directory, find out the length, and retrieve the
37  * complete directory entry (be it a leaf or a directory). We then process
38  * it and add the info to our structure for that particular node.
39  *
40  * We verify CRC's along the way for each directory/block/leaf. The
41  * entire node structure is generic, and simply stores the information in
42  * a way that's easy to parse by the protocol interface.
43  *
44  * XXX: Most of this isn't done yet :)  */
45
46
47 static LIST_HEAD(node_list);
48 static rwlock_t node_lock = RW_LOCK_UNLOCKED;
49
50 static LIST_HEAD(host_info_list);
51 static spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
52
53 struct host_info {
54         struct hpsb_host *host;
55         struct tq_struct task;
56         struct list_head list;
57 };
58
59 static struct node_entry *create_node_entry(void)
60 {
61         struct node_entry *ne;
62         unsigned long flags;
63
64         ne = kmalloc(sizeof(struct node_entry), SLAB_ATOMIC);
65         if (!ne) return NULL;
66
67         INIT_LIST_HEAD(&ne->list);
68         INIT_LIST_HEAD(&ne->unit_directories);
69         ne->guid = (u64) -1;
70         ne->host = NULL;
71         ne->nodeid = 0;
72         atomic_set(&ne->generation, -1);
73
74         write_lock_irqsave(&node_lock, flags);
75         list_add_tail(&ne->list, &node_list);
76         write_unlock_irqrestore(&node_lock, flags);
77
78         return ne;
79 }
80
81 static struct node_entry *find_entry_by_guid(u64 guid)
82 {
83         struct list_head *lh;
84         struct node_entry *ne;
85         
86         list_for_each(lh, &node_list) {
87                 ne = list_entry(lh, struct node_entry, list);
88                 if (ne->guid == guid) return ne;
89         }
90
91         return NULL;
92 }
93
94 static struct node_entry *find_entry_by_nodeid(nodeid_t nodeid)
95 {
96         struct list_head *lh;
97         struct node_entry *ne;
98
99         list_for_each(lh, &node_list) {
100                 ne = list_entry(lh, struct node_entry, list);
101                 if (ne->nodeid == nodeid) return ne;
102         }
103
104         return NULL;
105 }
106
107 int nodemgr_read_quadlet(struct node_entry *ne, 
108                          octlet_t address, quadlet_t *quad)
109 {
110         if (hpsb_read(ne->host, ne->nodeid, address, quad, 4)) {
111                 HPSB_DEBUG("read of address %Lx failed", address);
112                 return -EAGAIN;
113         }
114         *quad = be32_to_cpu(*quad);
115
116         return 0;
117 }
118
119 #define CONFIG_ROM_VENDOR_ID            0x03
120 #define CONFIG_ROM_MODEL_ID             0x17
121 #define CONFIG_ROM_NODE_CAPABILITES     0x0C
122 #define CONFIG_ROM_UNIT_DIRECTORY       0xd1
123 #define CONFIG_ROM_SPECIFIER_ID         0x12 
124 #define CONFIG_ROM_VERSION              0x13
125 #define CONFIG_ROM_DESCRIPTOR_LEAF      0x81
126 #define CONFIG_ROM_DESCRIPTOR_DIRECTORY 0xc1
127
128 /* This implementation currently only scans the config rom and its
129  * immediate unit directories looking for software_id and
130  * software_version entries, in order to get driver autoloading working.
131  */
132
133 static void nodemgr_process_unit_directory(struct node_entry *ne, 
134                                            octlet_t address)
135 {
136         struct unit_directory *ud;
137         octlet_t a;
138         quadlet_t quad;
139         int length, i;
140         
141
142         if (!(ud = kmalloc (sizeof *ud, GFP_KERNEL)))
143                 goto unit_directory_error;
144
145         memset (ud, 0, sizeof *ud);
146         ud->address = address;
147
148         if (nodemgr_read_quadlet(ne, address, &quad))
149                 goto unit_directory_error;
150         length = quad >> 16;
151         a = address + 4;
152
153         for (i = 0; i < length; i++, a += 4) {
154                 int code, value;
155
156                 if (nodemgr_read_quadlet(ne, a, &quad))
157                         goto unit_directory_error;
158                 code = quad >> 24;
159                 value = quad & 0xffffff;
160
161                 switch (code) {
162                 case CONFIG_ROM_VENDOR_ID:
163                         ud->vendor_id = value;
164                         ud->flags |= UNIT_DIRECTORY_VENDOR_ID;
165                         break;
166
167                 case CONFIG_ROM_MODEL_ID:
168                         ud->model_id = value;
169                         ud->flags |= UNIT_DIRECTORY_MODEL_ID;
170                         break;
171
172                 case CONFIG_ROM_SPECIFIER_ID:
173                         ud->specifier_id = value;
174                         ud->flags |= UNIT_DIRECTORY_SPECIFIER_ID;
175                         break;
176
177                 case CONFIG_ROM_VERSION:
178                         ud->version = value;
179                         ud->flags |= UNIT_DIRECTORY_VERSION;
180                         break;
181
182                 case CONFIG_ROM_DESCRIPTOR_LEAF:
183                 case CONFIG_ROM_DESCRIPTOR_DIRECTORY:
184                         /* TODO: read strings... icons? */
185                         break;
186                 }
187         }
188
189         list_add_tail (&ud->list, &ne->unit_directories);
190         return;
191
192 unit_directory_error:   
193         if (ud != NULL)
194                 kfree(ud);
195 }
196
197 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
198 static void dump_directories (struct node_entry *ne)
199 {
200         struct list_head *l;
201
202         HPSB_DEBUG("vendor_id=0x%06x, capabilities=0x%06x",
203                    ne->vendor_id, ne->capabilities);
204         list_for_each (l, &ne->unit_directories) {
205                 struct unit_directory *ud = list_entry (l, struct unit_directory, list);
206                 HPSB_DEBUG("unit directory:");
207                 if (ud->flags & UNIT_DIRECTORY_VENDOR_ID)
208                         HPSB_DEBUG("  vendor_id=0x%06x ", ud->vendor_id);
209                 if (ud->flags & UNIT_DIRECTORY_MODEL_ID)
210                         HPSB_DEBUG("  model_id=0x%06x ", ud->model_id);
211                 if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
212                         HPSB_DEBUG("  specifier_id=0x%06x ", ud->specifier_id);
213                 if (ud->flags & UNIT_DIRECTORY_VERSION)
214                         HPSB_DEBUG("  version=0x%06x ", ud->version);
215         }
216 }
217 #endif
218
219 static void nodemgr_process_root_directory(struct node_entry *ne)
220 {
221         octlet_t address;
222         quadlet_t quad;
223         int length, i;
224
225         address = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
226         
227         if (nodemgr_read_quadlet(ne, address, &quad))
228                 return;
229         address += 4 + (quad >> 24) * 4;
230
231         if (nodemgr_read_quadlet(ne, address, &quad))
232                 return;
233         length = quad >> 16;
234         address += 4;
235
236         for (i = 0; i < length; i++, address += 4) {
237                 int code, value;
238
239                 if (nodemgr_read_quadlet(ne, address, &quad))
240                         return;
241                 code = quad >> 24;
242                 value = quad & 0xffffff;
243
244                 switch (code) {
245                 case CONFIG_ROM_VENDOR_ID:
246                         ne->vendor_id = value;
247                         break;
248
249                 case CONFIG_ROM_NODE_CAPABILITES:
250                         ne->capabilities = value;
251                         break;
252
253                 case CONFIG_ROM_UNIT_DIRECTORY:
254                         nodemgr_process_unit_directory(ne, address + value * 4);
255                         break;                  
256
257                 case CONFIG_ROM_DESCRIPTOR_LEAF:
258                 case CONFIG_ROM_DESCRIPTOR_DIRECTORY:
259                         /* TODO: read strings... icons? */
260                         break;
261                 }
262         }
263 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
264         dump_directories(ne);
265 #endif
266 }
267
268 static void register_node(struct hpsb_host *host, nodeid_t nodeid, u64 guid,
269                           quadlet_t busoptions)
270 {
271         struct node_entry *ne;
272         unsigned long flags, new = 0;
273
274         read_lock_irqsave(&node_lock, flags);
275         ne = find_entry_by_guid(guid);
276         read_unlock_irqrestore(&node_lock, flags);
277
278         /* New entry */
279         if (!ne) {
280                 if ((ne = create_node_entry()) == NULL)
281                         return;
282
283                 HPSB_DEBUG("%s added: node " NODE_BUS_FMT
284                            ", GUID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
285                            (host->node_id == nodeid) ? "Local host" : "Device",
286                            NODE_BUS_ARGS(nodeid), ((u8 *)&guid)[0],
287                            ((u8 *)&guid)[1], ((u8 *)&guid)[2], ((u8 *)&guid)[3],
288                            ((u8 *)&guid)[4], ((u8 *)&guid)[5], ((u8 *)&guid)[6],
289                            ((u8 *)&guid)[7]);
290
291                 ne->guid = guid;
292                 new = 1;
293         }
294
295         if (!new && ne->nodeid != nodeid)
296                 HPSB_DEBUG("Node " NODE_BUS_FMT " changed to " NODE_BUS_FMT,
297                            NODE_BUS_ARGS(ne->nodeid), NODE_BUS_ARGS(nodeid));
298
299         ne->host = host;
300         ne->nodeid = nodeid;
301
302         /* Now set the bus options. Only do all this crap if this is a new
303          * node, or if the generation number has changed.  */
304         if (new || ne->busopt.generation != ((busoptions >> 6) & 0x3)) {
305                 ne->busopt.irmc         = (busoptions >> 31) & 1;
306                 ne->busopt.cmc          = (busoptions >> 30) & 1;
307                 ne->busopt.isc          = (busoptions >> 29) & 1;
308                 ne->busopt.bmc          = (busoptions >> 28) & 1;
309                 ne->busopt.pmc          = (busoptions >> 27) & 1;
310                 ne->busopt.cyc_clk_acc  = (busoptions >> 16) & 0xff;
311                 ne->busopt.max_rec      = 1 << (((busoptions >> 12) & 0xf) + 1);
312                 ne->busopt.generation   = (busoptions >> 6) & 0x3;
313                 ne->busopt.lnkspd       = busoptions & 0x7;
314
315                 /* Now, process the rest of the tree */
316                 nodemgr_process_root_directory(ne);
317         }
318
319         /* Since that's done, we can declare this record current */
320         atomic_set(&ne->generation, get_hpsb_generation(host));
321
322 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
323         HPSB_DEBUG("raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d cyc_clk_acc=%d "
324                    "max_rec=%d gen=%d lspd=%d", busoptions,
325                    ne->busopt.irmc, ne->busopt.cmc, ne->busopt.isc, ne->busopt.bmc,
326                    ne->busopt.pmc, ne->busopt.cyc_clk_acc, ne->busopt.max_rec,
327                    ne->busopt.generation, ne->busopt.lnkspd);
328 #endif
329
330         return;
331 }
332
333 static void nodemgr_remove_node(struct node_entry *ne)
334 {
335         HPSB_DEBUG("Device removed: node " NODE_BUS_FMT ", GUID "
336                    "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
337                    NODE_BUS_ARGS(ne->nodeid),
338                    ((u8 *)&ne->guid)[0], ((u8 *)&ne->guid)[1],
339                    ((u8 *)&ne->guid)[2], ((u8 *)&ne->guid)[3],
340                    ((u8 *)&ne->guid)[4], ((u8 *)&ne->guid)[5],
341                    ((u8 *)&ne->guid)[6], ((u8 *)&ne->guid)[7]);
342
343         list_del(&ne->list);
344         kfree(ne);
345
346         return;
347 }
348
349 /* This is where we probe the nodes for their information and provided
350  * features.  */
351 static void nodemgr_node_probe(void *data)
352 {
353         struct hpsb_host *host = (struct hpsb_host *)data;
354         struct selfid *sid = (struct selfid *)host->topology_map;
355         struct list_head *lh;
356         struct node_entry *ne;
357         int nodecount = host->node_count;
358         nodeid_t nodeid = LOCAL_BUS;
359         quadlet_t buffer[5], quad;
360         octlet_t base = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
361         int flags;
362
363         /* We need to detect when the ConfigROM's generation has changed,
364          * so we only update the node's info when it needs to be.  */
365         for (; nodecount; nodecount--, nodeid++, sid++) {
366                 int retries = 3;
367                 int header_count;
368                 unsigned header_size;
369                 octlet_t guid;
370
371                 /* Skip extended, and non-active node's */
372                 while (sid->extended)
373                         sid++;
374                 if (!sid->link_active)
375                         continue;
376
377                 /* Just use our local ROM */
378                 if (nodeid == host->node_id) {
379                         int i;
380                         for (i = 0; i < 5; i++)
381                                 buffer[i] = be32_to_cpu(host->csr.rom[i]);
382                         goto set_options;
383                 }
384
385 retry_configrom:
386                 
387                 if (!retries--) {
388                         HPSB_ERR("Giving up on node " NODE_BUS_FMT
389                                  " for ConfigROM probe, too many errors",
390                                  NODE_BUS_ARGS(nodeid));
391                         continue;
392                 }
393
394                 header_count = 0;
395                 header_size = 0;
396
397 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
398                 HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT,
399                           NODE_BUS_ARGS(nodeid));
400 #endif
401
402                 /* Now, P1212 says that devices should support 64byte block
403                  * reads, aligned on 64byte boundaries. That doesn't seem
404                  * to work though, and we are forced to doing quadlet
405                  * sized reads.  */
406
407                 if (hpsb_read(host, nodeid, base, &quad, 4)) {
408                         HPSB_ERR("ConfigROM quadlet transaction error for node " NODE_BUS_FMT,
409                                  NODE_BUS_ARGS(nodeid));
410                         goto retry_configrom;
411                 }
412                 buffer[header_count++] = be32_to_cpu(quad);
413
414                 header_size = buffer[0] >> 24;
415
416                 if (header_size < 4) {
417                         HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM format (%d quads), "
418                                   "cannot parse", NODE_BUS_ARGS(nodeid), header_size);
419                         continue;
420                 }
421
422                 while (header_count <= header_size && (header_count<<2) < sizeof(buffer)) {
423                         if (hpsb_read(host, nodeid, base + (header_count<<2), &quad, 4)) {
424                                 HPSB_ERR("ConfigROM quadlet transaction error for " NODE_BUS_FMT,
425                                          NODE_BUS_ARGS(nodeid));
426                                 goto retry_configrom;
427                         }
428                         buffer[header_count++] = be32_to_cpu(quad);
429                 }
430 set_options:
431                 if (buffer[1] != IEEE1394_BUSID_MAGIC) {
432                         /* This isn't a 1394 device */
433                         HPSB_ERR("Node " NODE_BUS_FMT " isn't an IEEE 1394 device",
434                                  NODE_BUS_ARGS(nodeid));
435                         continue;
436                 }
437
438                 guid = be64_to_cpu(((u64)buffer[3] << 32) | buffer[4]);
439                 register_node(host, nodeid, guid, buffer[2]);
440         }
441
442         /* Now check to see if we have any nodes that aren't referenced
443          * any longer.  */
444         write_lock_irqsave(&node_lock, flags);
445         list_for_each(lh, &node_list) {
446                 ne = list_entry(lh, struct node_entry, list);
447
448                 /* Only checking this host */
449                 if (ne->host != host)
450                         continue;
451
452                 /* If the generation didn't get updated, then either the
453                  * node was removed, or it failed the above probe. Either
454                  * way, we remove references to it, since they are
455                  * invalid.  */
456                 if (atomic_read(&ne->generation) != get_hpsb_generation(host))
457                         nodemgr_remove_node(ne);
458         }
459         write_unlock_irqrestore(&node_lock, flags);
460
461         return;
462 }
463
464
465 struct node_entry *hpsb_guid_get_entry(u64 guid)
466 {
467         unsigned long flags;
468         struct node_entry *ne;
469
470         read_lock_irqsave(&node_lock, flags);
471         ne = find_entry_by_guid(guid);
472         read_unlock_irqrestore(&node_lock, flags);
473
474         return ne;
475 }
476
477 struct node_entry *hpsb_nodeid_get_entry(nodeid_t nodeid)
478 {
479         unsigned long flags;
480         struct node_entry *ne;
481
482         read_lock_irqsave(&node_lock, flags);
483         ne = find_entry_by_nodeid(nodeid);
484         read_unlock_irqrestore(&node_lock, flags);
485
486         return ne;
487 }
488
489 struct hpsb_host *hpsb_get_host_by_ne(struct node_entry *ne)
490 {
491         if (atomic_read(&ne->generation) != get_hpsb_generation(ne->host))
492                 return NULL;
493         if (ne->nodeid == ne->host->node_id) return ne->host;
494         return NULL;
495 }
496
497 int hpsb_guid_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
498 {
499         if (atomic_read(&ne->generation) != get_hpsb_generation(ne->host))
500                 return 0;
501
502         pkt->host = ne->host;
503         pkt->node_id = ne->nodeid;
504         pkt->generation = atomic_read(&ne->generation);
505         return 1;
506 }
507
508 static void nodemgr_add_host(struct hpsb_host *host)
509 {
510         struct host_info *hi = kmalloc (sizeof (struct host_info), GFP_KERNEL);
511         int flags;
512
513         if (!hi) {
514                 HPSB_ERR ("Out of memory in Node Manager");
515                 return;
516         }
517
518         /* We simply initialize the struct here. We don't start the thread
519          * until the first bus reset.  */
520         hi->host = host;
521         INIT_LIST_HEAD(&hi->list);
522         INIT_TQUEUE(&hi->task, nodemgr_node_probe, host);
523
524         spin_lock_irqsave (&host_info_lock, flags);
525         list_add_tail (&hi->list, &host_info_list);
526         spin_unlock_irqrestore (&host_info_lock, flags);
527
528         return;
529 }
530
531 static void nodemgr_host_reset(struct hpsb_host *host)
532 {
533         struct list_head *lh;
534         struct host_info *hi = NULL;
535         int flags;
536
537         spin_lock_irqsave (&host_info_lock, flags);
538         list_for_each(lh, &host_info_list) {
539                 struct host_info *myhi = list_entry(lh, struct host_info, list);
540                 if (myhi->host == host) {
541                         hi = myhi;
542                         break;
543                 }
544         }
545
546         if (hi == NULL) {
547                 HPSB_ERR ("Could not process reset of non-existent host in Node Manager");
548                 goto done_reset_host;
549         }
550
551         schedule_task(&hi->task);
552
553 done_reset_host:
554         spin_unlock_irqrestore (&host_info_lock, flags);
555
556         return;
557 }
558
559 static void nodemgr_remove_host(struct hpsb_host *host)
560 {
561         struct list_head *lh;
562         struct host_info *hi = NULL;
563         struct node_entry *ne;
564         int flags;
565
566         /* Make sure we have no active scans */
567         flush_scheduled_tasks();
568
569         /* First remove all node entries for this host */
570         write_lock_irqsave(&node_lock, flags);
571         list_for_each(lh, &node_list) {
572                 ne = list_entry(lh, struct node_entry, list);
573
574                 /* Only checking this host */
575                 if (ne->host != host)
576                         continue;
577
578                 nodemgr_remove_node(ne);
579         }
580         write_unlock_irqrestore(&node_lock, flags);
581
582         spin_lock_irqsave (&host_info_lock, flags);
583         list_for_each(lh, &host_info_list) {
584                 struct host_info *myhi = list_entry(lh, struct host_info, list);
585                 if (myhi->host == host) {
586                         hi = myhi;
587                         break;
588                 }
589         }
590
591         if (hi == NULL) {
592                 HPSB_ERR ("Could not remove non-existent host in Node Manager");
593                 goto done_remove_host;
594         }
595
596         list_del(&hi->list);
597         kfree (hi);
598
599 done_remove_host:
600         spin_unlock_irqrestore (&host_info_lock, flags);
601
602         return;
603 }
604
605 static struct hpsb_highlevel_ops nodemgr_ops = {
606         add_host:       nodemgr_add_host,
607         host_reset:     nodemgr_host_reset,
608         remove_host:    nodemgr_remove_host,
609 };
610
611 static struct hpsb_highlevel *hl;
612
613 void init_ieee1394_nodemgr(void)
614 {
615         hl = hpsb_register_highlevel("Node manager", &nodemgr_ops);
616         if (!hl) {
617                 HPSB_ERR("Out of memory during ieee1394 initialization");
618         }
619 }
620
621 void cleanup_ieee1394_nodemgr(void)
622 {
623         hpsb_unregister_highlevel(hl);
624 }