nodemgr.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:25k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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. #include <linux/kernel.h>
  11. #include <linux/list.h>
  12. #include <linux/slab.h>
  13. #include <asm/byteorder.h>
  14. #include <asm/atomic.h>
  15. #include <linux/smp_lock.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/kmod.h>
  18. #include "ieee1394_types.h"
  19. #include "ieee1394.h"
  20. #include "hosts.h"
  21. #include "ieee1394_transactions.h"
  22. #include "ieee1394_hotplug.h"
  23. #include "highlevel.h"
  24. #include "csr.h"
  25. #include "nodemgr.h"
  26. /* 
  27.  * Basically what we do here is start off retrieving the bus_info block.
  28.  * From there will fill in some info about the node, verify it is of IEEE
  29.  * 1394 type, and that the crc checks out ok. After that we start off with
  30.  * the root directory, and subdirectories. To do this, we retrieve the
  31.  * quadlet header for a directory, find out the length, and retrieve the
  32.  * complete directory entry (be it a leaf or a directory). We then process
  33.  * it and add the info to our structure for that particular node.
  34.  *
  35.  * We verify CRC's along the way for each directory/block/leaf. The
  36.  * entire node structure is generic, and simply stores the information in
  37.  * a way that's easy to parse by the protocol interface.
  38.  */
  39. static LIST_HEAD(node_list);
  40. static rwlock_t node_lock = RW_LOCK_UNLOCKED;
  41. static LIST_HEAD(driver_list);
  42. static rwlock_t driver_lock = RW_LOCK_UNLOCKED;
  43. /* The rwlock unit_directory_lock is always held when manipulating the
  44.  * global unit_directory_list, but this also protects access to the
  45.  * lists of unit directories stored in the protocol drivers.
  46.  */
  47. static LIST_HEAD(unit_directory_list);
  48. static rwlock_t unit_directory_lock = RW_LOCK_UNLOCKED;
  49. static LIST_HEAD(host_info_list);
  50. static spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
  51. struct host_info {
  52. struct hpsb_host *host;
  53. struct tq_struct task;
  54. struct list_head list;
  55. };
  56. static void nodemgr_process_config_rom(struct node_entry *ne, 
  57.        quadlet_t busoptions);
  58. static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoptions,
  59.       struct hpsb_host *host, nodeid_t nodeid)
  60. {
  61.         struct node_entry *ne;
  62.         unsigned long flags;
  63.         ne = kmalloc(sizeof(struct node_entry), SLAB_ATOMIC);
  64.         if (!ne) return NULL;
  65.         INIT_LIST_HEAD(&ne->list);
  66. INIT_LIST_HEAD(&ne->unit_directories);
  67.         ne->host = host;
  68.         ne->nodeid = nodeid;
  69.         ne->guid = guid;
  70. atomic_set(&ne->generation, get_hpsb_generation(ne->host));
  71.         write_lock_irqsave(&node_lock, flags);
  72.         list_add_tail(&ne->list, &node_list);
  73.         write_unlock_irqrestore(&node_lock, flags);
  74. nodemgr_process_config_rom (ne, busoptions);
  75. HPSB_DEBUG("%s added: node " NODE_BUS_FMT ", GUID %016Lx",
  76.    (host->node_id == nodeid) ? "Local host" : "Device",
  77.    NODE_BUS_ARGS(nodeid), (unsigned long long)guid);
  78.         return ne;
  79. }
  80. static struct node_entry *find_entry_by_guid(u64 guid)
  81. {
  82.         struct list_head *lh;
  83.         struct node_entry *ne;
  84.         
  85.         list_for_each(lh, &node_list) {
  86.                 ne = list_entry(lh, struct node_entry, list);
  87.                 if (ne->guid == guid) return ne;
  88.         }
  89.         return NULL;
  90. }
  91. static struct node_entry *find_entry_by_nodeid(nodeid_t nodeid)
  92. {
  93. struct list_head *lh;
  94. struct node_entry *ne;
  95. list_for_each(lh, &node_list) {
  96. ne = list_entry(lh, struct node_entry, list);
  97. if (ne->nodeid == nodeid) return ne;
  98. }
  99. return NULL;
  100. }
  101. int nodemgr_read_quadlet(struct node_entry *ne,
  102.  octlet_t address, quadlet_t *quad)
  103. {
  104. int i;
  105. int ret = 0;
  106. for (i = 0; i < 3; i++) {
  107. ret = hpsb_read(ne->host, ne->nodeid, address, quad, 4);
  108. if (ret != -EAGAIN)
  109. break;
  110. }
  111. *quad = be32_to_cpu(*quad);
  112. return ret;
  113. }
  114. #define CONFIG_ROM_VENDOR_ID 0x03
  115. #define CONFIG_ROM_MODEL_ID 0x17
  116. #define CONFIG_ROM_NODE_CAPABILITES 0x0C
  117. #define CONFIG_ROM_UNIT_DIRECTORY 0xd1
  118. #define CONFIG_ROM_SPECIFIER_ID 0x12 
  119. #define CONFIG_ROM_VERSION 0x13
  120. #define CONFIG_ROM_DESCRIPTOR_LEAF 0x81
  121. #define CONFIG_ROM_DESCRIPTOR_DIRECTORY 0xc1
  122. /* This implementation currently only scans the config rom and its
  123.  * immediate unit directories looking for software_id and
  124.  * software_version entries, in order to get driver autoloading working.
  125.  */
  126. static void nodemgr_process_unit_directory(struct node_entry *ne, 
  127.    octlet_t address)
  128. {
  129. struct unit_directory *ud;
  130. octlet_t a;
  131. quadlet_t quad;
  132. int length, i;
  133. if (!(ud = kmalloc (sizeof *ud, GFP_KERNEL)))
  134. goto unit_directory_error;
  135. memset (ud, 0, sizeof *ud);
  136. ud->ne = ne;
  137. ud->address = address;
  138. ud->arb_count = 0;
  139. if (nodemgr_read_quadlet(ne, address, &quad))
  140. goto unit_directory_error;
  141. length = quad >> 16;
  142. a = address + 4;
  143. for (i = 0; i < length; i++, a += 4) {
  144. int code;
  145. quadlet_t value;
  146. if (nodemgr_read_quadlet(ne, a, &quad))
  147. goto unit_directory_error;
  148. code = quad >> 24;
  149. value = quad & 0xffffff;
  150. switch (code) {
  151. case CONFIG_ROM_VENDOR_ID:
  152. ud->vendor_id = value;
  153. ud->flags |= UNIT_DIRECTORY_VENDOR_ID;
  154. break;
  155. case CONFIG_ROM_MODEL_ID:
  156. ud->model_id = value;
  157. ud->flags |= UNIT_DIRECTORY_MODEL_ID;
  158. break;
  159. case CONFIG_ROM_SPECIFIER_ID:
  160. ud->specifier_id = value;
  161. ud->flags |= UNIT_DIRECTORY_SPECIFIER_ID;
  162. break;
  163. case CONFIG_ROM_VERSION:
  164. ud->version = value;
  165. ud->flags |= UNIT_DIRECTORY_VERSION;
  166. break;
  167. case CONFIG_ROM_DESCRIPTOR_LEAF:
  168. case CONFIG_ROM_DESCRIPTOR_DIRECTORY:
  169. /* TODO: read strings... icons? */
  170. break;
  171. default:
  172. if (ud->arb_count < 16) {
  173. /* Place them in the arbitrary pairs */
  174. ud->arb_keys[ud->arb_count] = code;
  175. ud->arb_values[ud->arb_count] = value;
  176. ud->arb_count++;
  177. }
  178. }
  179. }
  180. list_add_tail(&ud->node_list, &ne->unit_directories);
  181. list_add_tail(&ud->driver_list, &unit_directory_list);
  182. return;
  183. unit_directory_error:
  184. if (ud != NULL)
  185. kfree(ud);
  186. }
  187. static void dump_directories (struct node_entry *ne)
  188. {
  189. #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
  190. struct list_head *l;
  191. HPSB_DEBUG("vendor_id=0x%06x, capabilities=0x%06x",
  192.    ne->vendor_id, ne->capabilities);
  193. list_for_each (l, &ne->unit_directories) {
  194. struct unit_directory *ud = list_entry (l, struct unit_directory, node_list);
  195. HPSB_DEBUG("unit directory:");
  196. if (ud->flags & UNIT_DIRECTORY_VENDOR_ID)
  197. HPSB_DEBUG("  vendor_id=0x%06x ", ud->vendor_id);
  198. if (ud->flags & UNIT_DIRECTORY_MODEL_ID)
  199. HPSB_DEBUG("  model_id=0x%06x ", ud->model_id);
  200. if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
  201. HPSB_DEBUG("  sw_specifier_id=0x%06x ", ud->specifier_id);
  202. if (ud->flags & UNIT_DIRECTORY_VERSION)
  203. HPSB_DEBUG("  sw_version=0x%06x ", ud->version);
  204. }
  205. #else
  206. return;
  207. #endif
  208. }
  209. static void nodemgr_process_root_directory(struct node_entry *ne)
  210. {
  211. octlet_t address;
  212. quadlet_t quad;
  213. int length, i;
  214. address = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
  215. if (nodemgr_read_quadlet(ne, address, &quad))
  216. return;
  217. address += 4 + (quad >> 24) * 4;
  218. if (nodemgr_read_quadlet(ne, address, &quad))
  219. return;
  220. length = quad >> 16;
  221. address += 4;
  222. for (i = 0; i < length; i++, address += 4) {
  223. int code, value;
  224. if (nodemgr_read_quadlet(ne, address, &quad))
  225. return;
  226. code = quad >> 24;
  227. value = quad & 0xffffff;
  228. switch (code) {
  229. case CONFIG_ROM_VENDOR_ID:
  230. ne->vendor_id = value;
  231. break;
  232. case CONFIG_ROM_NODE_CAPABILITES:
  233. ne->capabilities = value;
  234. break;
  235. case CONFIG_ROM_UNIT_DIRECTORY:
  236. nodemgr_process_unit_directory(ne, address + value * 4);
  237. break;
  238. case CONFIG_ROM_DESCRIPTOR_LEAF:
  239. case CONFIG_ROM_DESCRIPTOR_DIRECTORY:
  240. /* TODO: read strings... icons? */
  241. break;
  242. }
  243. }
  244. dump_directories(ne);
  245. }
  246. #ifdef CONFIG_HOTPLUG
  247. static void nodemgr_call_policy(char *verb, struct unit_directory *ud)
  248. {
  249. char *argv [3], **envp, *buf, *scratch;
  250. int i = 0, value;
  251. if (!hotplug_path [0])
  252. return;
  253. if (!current->fs->root)
  254. return;
  255. if (!(envp = (char **) kmalloc(20 * sizeof (char *), GFP_KERNEL))) {
  256. HPSB_DEBUG ("ENOMEM");
  257. return;
  258. }
  259. if (!(buf = kmalloc(256, GFP_KERNEL))) {
  260. kfree(envp);
  261. HPSB_DEBUG("ENOMEM2");
  262. return;
  263. }
  264. /* only one standardized param to hotplug command: type */
  265. argv[0] = hotplug_path;
  266. argv[1] = "ieee1394";
  267. argv[2] = 0;
  268. /* minimal command environment */
  269. envp[i++] = "HOME=/";
  270. envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
  271. #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
  272. /* hint that policy agent should enter no-stdout debug mode */
  273. envp[i++] = "DEBUG=kernel";
  274. #endif
  275. /* extensible set of named bus-specific parameters,
  276.  * supporting multiple driver selection algorithms.
  277.  */
  278. scratch = buf;
  279. envp[i++] = scratch;
  280. scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
  281. envp[i++] = scratch;
  282. scratch += sprintf(scratch, "VENDOR_ID=%06x", ud->ne->vendor_id) + 1;
  283. envp[i++] = scratch;
  284. scratch += sprintf(scratch, "GUID=%016Lx", (long long unsigned)ud->ne->guid) + 1;
  285. envp[i++] = scratch;
  286. scratch += sprintf(scratch, "SPECIFIER_ID=%06x", ud->specifier_id) + 1;
  287. envp[i++] = scratch;
  288. scratch += sprintf(scratch, "VERSION=%06x", ud->version) + 1;
  289. envp[i++] = 0;
  290. /* NOTE: user mode daemons can call the agents too */
  291. #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
  292. HPSB_DEBUG("NodeMgr: %s %s %016Lx", argv[0], verb, (long long unsigned)ud->ne->guid);
  293. #endif
  294. value = call_usermodehelper(argv[0], argv, envp);
  295. kfree(buf);
  296. kfree(envp);
  297. if (value != 0)
  298. HPSB_DEBUG("NodeMgr: hotplug policy returned %d", value);
  299. }
  300. #else
  301. static inline void
  302. nodemgr_call_policy(char *verb, struct unit_directory *ud)
  303. {
  304. #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
  305. HPSB_DEBUG("NodeMgr: nodemgr_call_policy(): hotplug not enabled");
  306. #endif
  307. return;
  308. #endif /* CONFIG_HOTPLUG */
  309. static void nodemgr_claim_unit_directory(struct unit_directory *ud,
  310.  struct hpsb_protocol_driver *driver)
  311. {
  312. ud->driver = driver;
  313. list_del(&ud->driver_list);
  314. list_add_tail(&ud->driver_list, &driver->unit_directories);
  315. }
  316. static void nodemgr_release_unit_directory(struct unit_directory *ud)
  317. {
  318. ud->driver = NULL;
  319. list_del(&ud->driver_list);
  320. list_add_tail(&ud->driver_list, &unit_directory_list);
  321. }
  322. void hpsb_release_unit_directory(struct unit_directory *ud)
  323. {
  324. unsigned long flags;
  325. write_lock_irqsave(&unit_directory_lock, flags);
  326. nodemgr_release_unit_directory(ud);
  327. write_unlock_irqrestore(&unit_directory_lock, flags);
  328. }
  329. static void nodemgr_free_unit_directories(struct node_entry *ne)
  330. {
  331. struct list_head *lh;
  332. struct unit_directory *ud;
  333. lh = ne->unit_directories.next;
  334. while (lh != &ne->unit_directories) {
  335. ud = list_entry(lh, struct unit_directory, node_list);
  336. lh = lh->next;
  337. if (ud->driver && ud->driver->disconnect)
  338. ud->driver->disconnect(ud);
  339. nodemgr_release_unit_directory(ud);
  340. nodemgr_call_policy("remove", ud);
  341. list_del(&ud->driver_list);
  342. kfree(ud);
  343. }
  344. }
  345. static struct ieee1394_device_id *
  346. nodemgr_match_driver(struct hpsb_protocol_driver *driver, 
  347.      struct unit_directory *ud)
  348. {
  349. struct ieee1394_device_id *id;
  350. for (id = driver->id_table; id->match_flags != 0; id++) {
  351. if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
  352.     id->vendor_id != ud->vendor_id)
  353. continue;
  354. if ((id->match_flags & IEEE1394_MATCH_MODEL_ID) &&
  355.     id->model_id != ud->model_id)
  356. continue;
  357. if ((id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) &&
  358.     id->specifier_id != ud->specifier_id)
  359. continue;
  360. if ((id->match_flags & IEEE1394_MATCH_VERSION) &&
  361.     id->version != ud->version)
  362. continue;
  363. return id;
  364. }
  365. return NULL;
  366. }
  367. static struct hpsb_protocol_driver *
  368. nodemgr_find_driver(struct unit_directory *ud)
  369. {
  370. struct list_head *l;
  371. struct hpsb_protocol_driver *match, *driver;
  372. struct ieee1394_device_id *device_id;
  373. match = NULL;
  374. list_for_each(l, &driver_list) {
  375. driver = list_entry(l, struct hpsb_protocol_driver, list);
  376. device_id = nodemgr_match_driver(driver, ud);
  377. if (device_id != NULL) {
  378. match = driver;
  379. break;
  380. }
  381. }
  382. return match;
  383. }
  384. static void nodemgr_bind_drivers (struct node_entry *ne)
  385. {
  386. struct list_head *lh;
  387. struct hpsb_protocol_driver *driver;
  388. struct unit_directory *ud;
  389. list_for_each(lh, &ne->unit_directories) {
  390. ud = list_entry(lh, struct unit_directory, node_list);
  391. driver = nodemgr_find_driver(ud);
  392. if (driver != NULL && driver->probe(ud) == 0)
  393. nodemgr_claim_unit_directory(ud, driver);
  394. nodemgr_call_policy("add", ud);
  395. }
  396. }
  397. int hpsb_register_protocol(struct hpsb_protocol_driver *driver)
  398. {
  399. struct unit_directory *ud;
  400. struct list_head *lh;
  401. unsigned long flags;
  402.         write_lock_irqsave(&driver_lock, flags);
  403. list_add_tail(&driver->list, &driver_list);
  404. write_unlock_irqrestore(&driver_lock, flags);
  405. write_lock_irqsave(&unit_directory_lock, flags);
  406. INIT_LIST_HEAD(&driver->unit_directories);
  407. lh = unit_directory_list.next;
  408. while (lh != &unit_directory_list) {
  409. ud = list_entry(lh, struct unit_directory, driver_list);
  410. lh = lh->next;
  411. if (nodemgr_match_driver(driver, ud) && driver->probe(ud) == 0)
  412. nodemgr_claim_unit_directory(ud, driver);
  413. }
  414. write_unlock_irqrestore(&unit_directory_lock, flags);
  415. /*
  416.  * Right now registration always succeeds, but maybe we should
  417.  * detect clashes in protocols handled by other drivers.
  418.  */
  419. return 0;
  420. }
  421. void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
  422. {
  423. struct list_head *lh;
  424. struct unit_directory *ud;
  425. unsigned long flags;
  426.         write_lock_irqsave(&driver_lock, flags);
  427. list_del(&driver->list);
  428. write_unlock_irqrestore(&driver_lock, flags);
  429. write_lock_irqsave(&unit_directory_lock, flags);
  430. lh = driver->unit_directories.next;
  431. while (lh != &driver->unit_directories) {
  432. ud = list_entry(lh, struct unit_directory, driver_list);
  433. lh = lh->next;
  434. if (ud->driver && ud->driver->disconnect)
  435. ud->driver->disconnect(ud);
  436. nodemgr_release_unit_directory(ud);
  437. }
  438. write_unlock_irqrestore(&unit_directory_lock, flags);
  439. }
  440. static void nodemgr_process_config_rom(struct node_entry *ne, 
  441.        quadlet_t busoptions)
  442. {
  443. unsigned long flags;
  444. ne->busopt.irmc = (busoptions >> 31) & 1;
  445. ne->busopt.cmc = (busoptions >> 30) & 1;
  446. ne->busopt.isc = (busoptions >> 29) & 1;
  447. ne->busopt.bmc = (busoptions >> 28) & 1;
  448. ne->busopt.pmc = (busoptions >> 27) & 1;
  449. ne->busopt.cyc_clk_acc = (busoptions >> 16) & 0xff;
  450. ne->busopt.max_rec = 1 << (((busoptions >> 12) & 0xf) + 1);
  451. ne->busopt.generation = (busoptions >> 4) & 0xf;
  452. ne->busopt.lnkspd = busoptions & 0x7;
  453. #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
  454. HPSB_DEBUG("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
  455.    "cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d",
  456.    busoptions, ne->busopt.irmc, ne->busopt.cmc,
  457.    ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc,
  458.    ne->busopt.cyc_clk_acc, ne->busopt.max_rec,
  459.    ne->busopt.generation, ne->busopt.lnkspd);
  460. #endif
  461. /*
  462.  * When the config rom changes we disconnect all drivers and
  463.  * free the cached unit directories and reread the whole
  464.  * thing.  If this was a new device, the call to
  465.  * nodemgr_disconnect_drivers is a no-op and all is well.
  466.  */
  467. write_lock_irqsave(&unit_directory_lock, flags);
  468. nodemgr_free_unit_directories(ne);
  469. nodemgr_process_root_directory(ne);
  470. nodemgr_bind_drivers(ne);
  471. write_unlock_irqrestore(&unit_directory_lock, flags);
  472. }
  473. /*
  474.  * This function updates nodes that were present on the bus before the
  475.  * reset and still are after the reset.  The nodeid and the config rom
  476.  * may have changed, and the drivers managing this device must be
  477.  * informed that this device just went through a bus reset, to allow
  478.  * the to take whatever actions required.
  479.  */
  480. static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions,
  481.                                struct hpsb_host *host, nodeid_t nodeid)
  482. {
  483. struct list_head *lh;
  484. struct unit_directory *ud;
  485. if (ne->nodeid != nodeid) {
  486. HPSB_DEBUG("Node " NODE_BUS_FMT " changed to " NODE_BUS_FMT,
  487.    NODE_BUS_ARGS(ne->nodeid), NODE_BUS_ARGS(nodeid));
  488. ne->nodeid = nodeid;
  489. }
  490. if (ne->busopt.generation != ((busoptions >> 4) & 0xf))
  491. nodemgr_process_config_rom (ne, busoptions);
  492. /* Since that's done, we can declare this record current */
  493. atomic_set(&ne->generation, get_hpsb_generation(ne->host));
  494. list_for_each (lh, &ne->unit_directories) {
  495. ud = list_entry (lh, struct unit_directory, node_list);
  496. if (ud->driver != NULL && ud->driver->update != NULL)
  497. ud->driver->update(ud);
  498. }
  499. }
  500. static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid,
  501.       quadlet_t *buffer, int buffer_length)
  502. {
  503. octlet_t base = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
  504. int retries = 3;
  505. int header_count;
  506. unsigned header_size;
  507. quadlet_t quad;
  508. retry_configrom:
  509. if (!retries--) {
  510. HPSB_ERR("Giving up on node " NODE_BUS_FMT
  511.  " for ConfigROM probe, too many errors",
  512.  NODE_BUS_ARGS(nodeid));
  513. return -1;
  514. }
  515. header_count = 0;
  516. header_size = 0;
  517. #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
  518. HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT,
  519.   NODE_BUS_ARGS(nodeid));
  520. #endif
  521. /* Now, P1212 says that devices should support 64byte block
  522.  * reads, aligned on 64byte boundaries. That doesn't seem
  523.  * to work though, and we are forced to doing quadlet
  524.  * sized reads.  */
  525. if (hpsb_read(host, nodeid, base, &quad, 4)) {
  526. HPSB_ERR("ConfigROM quadlet transaction error for node " NODE_BUS_FMT,
  527.  NODE_BUS_ARGS(nodeid));
  528. goto retry_configrom;
  529. }
  530. buffer[header_count++] = be32_to_cpu(quad);
  531. header_size = buffer[0] >> 24;
  532. if (header_size < 4) {
  533. HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM format (%d quads), "
  534.   "cannot parse", NODE_BUS_ARGS(nodeid), header_size);
  535. return -1;
  536. }
  537. while (header_count <= header_size && header_count < buffer_length) {
  538. if (hpsb_read(host, nodeid, base + (header_count<<2), &quad, 4)) {
  539. HPSB_ERR("ConfigROM quadlet transaction error for " NODE_BUS_FMT,
  540.  NODE_BUS_ARGS(nodeid));
  541. goto retry_configrom;
  542. }
  543. buffer[header_count++] = be32_to_cpu(quad);
  544. }
  545. return 0;
  546. }
  547. static void nodemgr_remove_node(struct node_entry *ne)
  548. {
  549. unsigned long flags;
  550. HPSB_DEBUG("Device removed: node " NODE_BUS_FMT ", GUID %016Lx",
  551.    NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid);
  552. write_lock_irqsave(&unit_directory_lock, flags);
  553. nodemgr_free_unit_directories(ne);
  554. write_unlock_irqrestore(&unit_directory_lock, flags);
  555. list_del(&ne->list);
  556. kfree(ne);
  557. return;
  558. }
  559. /* Used to schedule each nodes config rom probe */
  560. struct node_probe_task {
  561. nodeid_t nodeid;
  562. struct hpsb_host *host;
  563. atomic_t *count;
  564. struct tq_struct task;
  565. };
  566. /* This is where we probe the nodes for their information and provided
  567.  * features.  */
  568. static void nodemgr_node_probe_one(void *__npt)
  569. {
  570. struct node_probe_task *npt = (struct node_probe_task *)__npt;
  571. struct node_entry *ne;
  572. quadlet_t buffer[5];
  573. octlet_t guid;
  574. /* We need to detect when the ConfigROM's generation has changed,
  575.  * so we only update the node's info when it needs to be.  */
  576. if (read_businfo_block (npt->host, npt->nodeid, buffer, sizeof(buffer) >> 2))
  577. goto probe_complete;
  578. if (buffer[1] != IEEE1394_BUSID_MAGIC) {
  579. /* This isn't a 1394 device */
  580. HPSB_ERR("Node " NODE_BUS_FMT " isn't an IEEE 1394 device",
  581.  NODE_BUS_ARGS(npt->nodeid));
  582. goto probe_complete;
  583. }
  584. guid = ((u64)buffer[3] << 32) | buffer[4];
  585. ne = hpsb_guid_get_entry(guid);
  586. if (!ne)
  587. nodemgr_create_node(guid, buffer[2], npt->host, npt->nodeid);
  588. else
  589. nodemgr_update_node(ne, buffer[2], npt->host, npt->nodeid);
  590. probe_complete:
  591. atomic_dec(npt->count);
  592. kfree(npt);
  593. return;
  594. }
  595. static void nodemgr_node_probe_cleanup(void *__npt)
  596. {
  597. struct node_probe_task *npt = (struct node_probe_task *)__npt;
  598. unsigned long flags;
  599. struct list_head *lh, *next;
  600. struct node_entry *ne;
  601. /* If things aren't done yet, reschedule ourselves. */
  602.         if (atomic_read(npt->count)) {
  603.                 schedule_task(&npt->task);
  604. return;
  605. }
  606. kfree(npt->count);
  607. /* Now check to see if we have any nodes that aren't referenced
  608.  * any longer.  */
  609. write_lock_irqsave(&node_lock, flags);
  610. for (lh = node_list.next; lh != &node_list; lh = next) {
  611. ne = list_entry(lh, struct node_entry, list);
  612. next = lh->next;
  613. /* Only checking this host */
  614. if (ne->host != npt->host)
  615. continue;
  616. /* If the generation didn't get updated, then either the
  617.  * node was removed, or it failed the above probe. Either
  618.  * way, we remove references to it, since they are
  619.  * invalid.  */
  620. if (!hpsb_node_entry_valid(ne))
  621. nodemgr_remove_node(ne);
  622. }
  623. write_unlock_irqrestore(&node_lock, flags);
  624. kfree(npt);
  625. return;
  626. }
  627. static void nodemgr_node_probe(void *__host)
  628. {
  629. struct hpsb_host *host = (struct hpsb_host *)__host;
  630. int nodecount = host->node_count;
  631. struct selfid *sid = (struct selfid *)host->topology_map;
  632. nodeid_t nodeid = LOCAL_BUS;
  633. struct node_probe_task *npt;
  634. atomic_t *count;
  635. count = kmalloc(sizeof (*count), GFP_KERNEL);
  636. if (count == NULL) {
  637. HPSB_ERR ("NodeMgr: out of memory in nodemgr_node_probe");
  638. return;
  639. }
  640. atomic_set(count, 0);
  641. for (; nodecount; nodecount--, nodeid++, sid++) {
  642. while (sid->extended)
  643. sid++;
  644. if (!sid->link_active || nodeid == host->node_id)
  645. continue;
  646. npt = kmalloc(sizeof (*npt), GFP_KERNEL);
  647. if (npt == NULL) {
  648. HPSB_ERR ("NodeMgr: out of memory in nodemgr_node_probe");
  649. break;
  650. }
  651. INIT_TQUEUE(&npt->task, nodemgr_node_probe_one, npt);
  652. npt->host = host;
  653. npt->nodeid = nodeid;
  654. npt->count = count;
  655. atomic_inc(count);
  656. schedule_task(&npt->task);
  657. }
  658. /* Now schedule a task to clean things up after the node probes
  659.  * are done.  */
  660. npt = kmalloc (sizeof (*npt), GFP_KERNEL);
  661. if (npt == NULL) {
  662. HPSB_ERR ("NodeMgr: out of memory in nodemgr_node_probe");
  663. return;
  664. }
  665. INIT_TQUEUE(&npt->task, nodemgr_node_probe_cleanup, npt);
  666. npt->host = host;
  667. npt->nodeid = 0;
  668. npt->count = count;
  669. schedule_task(&npt->task);
  670. return;
  671. }
  672. struct node_entry *hpsb_guid_get_entry(u64 guid)
  673. {
  674.         unsigned long flags;
  675.         struct node_entry *ne;
  676.         read_lock_irqsave(&node_lock, flags);
  677.         ne = find_entry_by_guid(guid);
  678.         read_unlock_irqrestore(&node_lock, flags);
  679.         return ne;
  680. }
  681. struct node_entry *hpsb_nodeid_get_entry(nodeid_t nodeid)
  682. {
  683. unsigned long flags;
  684. struct node_entry *ne;
  685. read_lock_irqsave(&node_lock, flags);
  686. ne = find_entry_by_nodeid(nodeid);
  687. read_unlock_irqrestore(&node_lock, flags);
  688. return ne;
  689. }
  690. struct hpsb_host *hpsb_get_host_by_ne(struct node_entry *ne)
  691. {
  692.         if (atomic_read(&ne->generation) != get_hpsb_generation(ne->host))
  693. return NULL;
  694.         if (ne->nodeid == ne->host->node_id) return ne->host;
  695.         return NULL;
  696. }
  697. int hpsb_guid_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
  698. {
  699.         if (atomic_read(&ne->generation) != get_hpsb_generation(ne->host))
  700. return 0;
  701.         pkt->host = ne->host;
  702.         pkt->node_id = ne->nodeid;
  703.         pkt->generation = atomic_read(&ne->generation);
  704.         return 1;
  705. }
  706. static void nodemgr_add_host(struct hpsb_host *host)
  707. {
  708. struct host_info *hi = kmalloc (sizeof (struct host_info), GFP_KERNEL);
  709. unsigned long flags;
  710. if (!hi) {
  711. HPSB_ERR ("NodeMgr: out of memory in add host");
  712. return;
  713. }
  714. /* We simply initialize the struct here. We don't start the thread
  715.  * until the first bus reset.  */
  716. hi->host = host;
  717. INIT_LIST_HEAD(&hi->list);
  718. INIT_TQUEUE(&hi->task, nodemgr_node_probe, host);
  719. spin_lock_irqsave (&host_info_lock, flags);
  720. list_add_tail (&hi->list, &host_info_list);
  721. spin_unlock_irqrestore (&host_info_lock, flags);
  722. return;
  723. }
  724. static void nodemgr_host_reset(struct hpsb_host *host)
  725. {
  726. struct list_head *lh;
  727. struct host_info *hi = NULL;
  728. unsigned long flags;
  729. spin_lock_irqsave (&host_info_lock, flags);
  730. list_for_each(lh, &host_info_list) {
  731. struct host_info *myhi = list_entry(lh, struct host_info, list);
  732. if (myhi->host == host) {
  733. hi = myhi;
  734. break;
  735. }
  736. }
  737. if (hi == NULL) {
  738. HPSB_ERR ("NodeMgr: could not process reset of non-existent host");
  739. goto done_reset_host;
  740. }
  741. schedule_task(&hi->task);
  742. done_reset_host:
  743. spin_unlock_irqrestore (&host_info_lock, flags);
  744. return;
  745. }
  746. static void nodemgr_remove_host(struct hpsb_host *host)
  747. {
  748. struct list_head *lh, *next;
  749. struct node_entry *ne;
  750. unsigned long flags;
  751. /* Make sure we have no active scans */
  752. flush_scheduled_tasks();
  753. /* First remove all node entries for this host */
  754. write_lock_irqsave(&node_lock, flags);
  755. for (lh = node_list.next; lh != &node_list; lh = next) {
  756. ne = list_entry(lh, struct node_entry, list);
  757. next = lh->next;
  758. /* Only checking this host */
  759. if (ne->host != host)
  760. continue;
  761. nodemgr_remove_node(ne);
  762. }
  763. write_unlock_irqrestore(&node_lock, flags);
  764. spin_lock_irqsave (&host_info_lock, flags);
  765. list_for_each_safe(lh, next, &host_info_list) {
  766. struct host_info *hi = list_entry(lh, struct host_info, list);
  767. if (hi->host == host) {
  768. list_del(&hi->list);
  769. kfree (hi);
  770. break;
  771. }
  772. }
  773. if (lh == host_info_list.next)
  774. HPSB_ERR ("NodeMgr: could not remove non-existent host");
  775. spin_unlock_irqrestore (&host_info_lock, flags);
  776. return;
  777. }
  778. static struct hpsb_highlevel_ops nodemgr_ops = {
  779. add_host: nodemgr_add_host,
  780. host_reset: nodemgr_host_reset,
  781. remove_host: nodemgr_remove_host,
  782. };
  783. static struct hpsb_highlevel *hl;
  784. void init_ieee1394_nodemgr(void)
  785. {
  786.         hl = hpsb_register_highlevel("Node manager", &nodemgr_ops);
  787.         if (!hl) {
  788. HPSB_ERR("NodeMgr: out of memory during ieee1394 initialization");
  789.         }
  790. }
  791. void cleanup_ieee1394_nodemgr(void)
  792. {
  793.         hpsb_unregister_highlevel(hl);
  794. }