patch-2.4.7 linux/drivers/ieee1394/guid.c
Next file: linux/drivers/ieee1394/guid.h
Previous file: linux/drivers/ieee1394/csr.c
Back to the patch index
Back to the overall index
- Lines: 238
- Date:
Wed Dec 31 16:00:00 1969
- Orig file:
v2.4.6/linux/drivers/ieee1394/guid.c
- Orig date:
Thu Mar 1 16:57:11 2001
diff -u --recursive --new-file v2.4.6/linux/drivers/ieee1394/guid.c linux/drivers/ieee1394/guid.c
@@ -1,237 +0,0 @@
-/*
- * IEEE 1394 for Linux
- *
- * GUID collection and management
- *
- * Copyright (C) 2000 Andreas E. Bombe
- *
- * This code is licensed under the GPL. See the file COPYING in the root
- * directory of the kernel sources for details.
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-#include <asm/atomic.h>
-
-#include "ieee1394_types.h"
-#include "ieee1394.h"
-#include "hosts.h"
-#include "ieee1394_transactions.h"
-#include "highlevel.h"
-#include "csr.h"
-
-
-static atomic_t outstanding_requests;
-
-static LIST_HEAD(guid_list);
-rwlock_t guid_lock = RW_LOCK_UNLOCKED;
-
-struct guid_entry {
- struct list_head list;
- atomic_t refcount;
-
- u64 guid;
-
- struct hpsb_host *host;
- nodeid_t node_id;
-
- atomic_t generation;
-};
-
-struct guid_req {
- struct hpsb_packet *pkt;
- struct tq_struct tq;
-};
-
-
-static struct guid_entry *create_guid_entry(void)
-{
- struct guid_entry *ge;
- unsigned long flags;
-
- ge = kmalloc(sizeof(struct guid_entry), SLAB_ATOMIC);
- if (!ge) return NULL;
-
- INIT_LIST_HEAD(&ge->list);
- atomic_set(&ge->refcount, 0);
- ge->guid = (u64) -1;
- ge->host = NULL;
- ge->node_id = 0;
- atomic_set(&ge->generation, -1);
-
- write_lock_irqsave(&guid_lock, flags);
- list_add_tail(&ge->list, &guid_list);
- write_unlock_irqrestore(&guid_lock, flags);
-
- return ge;
-}
-
-static struct guid_entry *find_entry(u64 guid)
-{
- struct list_head *lh;
- struct guid_entry *ge;
-
- lh = guid_list.next;
- while (lh != &guid_list) {
- ge = list_entry(lh, struct guid_entry, list);
- if (ge->guid == guid) return ge;
- lh = lh->next;
- }
-
- return NULL;
-}
-
-static void associate_guid(struct hpsb_host *host, nodeid_t nodeid, u64 guid)
-{
- struct guid_entry *ge;
- unsigned long flags;
-
- HPSB_DEBUG("node %d on host 0x%p has GUID 0x%08x%08x",
- nodeid & NODE_MASK, host, (unsigned int)(guid >> 32),
- (unsigned int)(guid & 0xffffffff));
-
- read_lock_irqsave(&guid_lock, flags);
- ge = find_entry(guid);
- read_unlock_irqrestore(&guid_lock, flags);
-
- if (!ge) ge = create_guid_entry();
- if (!ge) return;
-
- ge->host = host;
- ge->node_id = nodeid;
- ge->guid = guid;
-
- atomic_set(&ge->generation, get_hpsb_generation());
-}
-
-static void pkt_complete(struct guid_req *req)
-{
- struct hpsb_packet *pkt = req->pkt;
- int rcode = (pkt->header[1] >> 12) & 0xf;
-
- if (pkt->ack_code == ACK_PENDING && rcode == RCODE_COMPLETE) {
- if (*(char *)pkt->data > 1) {
- associate_guid(pkt->host, pkt->node_id,
- ((u64)be32_to_cpu(pkt->data[3]) << 32)
- | be32_to_cpu(pkt->data[4]));
- } else {
- HPSB_DEBUG("minimal ROM on node %d",
- pkt->node_id & NODE_MASK);
- }
- } else {
- HPSB_DEBUG("guid transaction error: ack %d, rcode %d",
- pkt->ack_code, rcode);
- }
-
- free_tlabel(pkt->host, pkt->node_id, pkt->tlabel);
- free_hpsb_packet(pkt);
- kfree(req);
-
- if (atomic_dec_and_test(&outstanding_requests)) {
- /* FIXME: free unreferenced and inactive GUID entries. */
- }
-}
-
-
-static void host_reset(struct hpsb_host *host)
-{
- struct guid_req *greq;
- struct hpsb_packet *pkt;
- struct selfid *sid = (struct selfid *)host->topology_map;
- int nodecount = host->node_count;
- nodeid_t nodeid = LOCAL_BUS;
-
- for (; nodecount; nodecount--, nodeid++, sid++) {
- while (sid->extended) sid++;
- if (!sid->link_active) continue;
- if (nodeid == host->node_id) continue;
-
- greq = kmalloc(sizeof(struct guid_req), SLAB_ATOMIC);
- if (!greq) {
- HPSB_ERR("out of memory in GUID processing");
- return;
- }
-
- pkt = hpsb_make_readbpacket(host, nodeid,
- CSR_REGISTER_BASE + CSR_CONFIG_ROM,
- 20);
- if (!pkt) {
- kfree(greq);
- HPSB_ERR("out of memory in GUID processing");
- return;
- }
-
- INIT_TQ_LINK(greq->tq);
- greq->tq.sync = 0;
- greq->tq.routine = (void (*)(void*))pkt_complete;
- greq->tq.data = greq;
- greq->pkt = pkt;
-
- queue_task(&greq->tq, &pkt->complete_tq);
-
- if (!hpsb_send_packet(pkt)) {
- free_tlabel(pkt->host, pkt->node_id, pkt->tlabel);
- free_hpsb_packet(pkt);
- kfree(greq);
- HPSB_NOTICE("failed to send packet in GUID processing");
- }
-
- HPSB_INFO("GUID request sent to node %d", nodeid & NODE_MASK);
- atomic_inc(&outstanding_requests);
- }
-}
-
-
-struct guid_entry *hpsb_guid_get_handle(u64 guid)
-{
- unsigned long flags;
- struct guid_entry *ge;
-
- read_lock_irqsave(&guid_lock, flags);
- ge = find_entry(guid);
- if (ge) atomic_inc(&ge->refcount);
- read_unlock_irqrestore(&guid_lock, flags);
-
- return ge;
-}
-
-struct hpsb_host *hpsb_guid_localhost(struct guid_entry *ge)
-{
- if (atomic_read(&ge->generation) != get_hpsb_generation()) return NULL;
- if (ge->node_id == ge->host->node_id) return ge->host;
- return NULL;
-}
-
-int hpsb_guid_fill_packet(struct guid_entry *ge, struct hpsb_packet *pkt)
-{
- if (atomic_read(&ge->generation) != get_hpsb_generation()) return 0;
-
- pkt->host = ge->host;
- pkt->node_id = ge->node_id;
- pkt->generation = atomic_read(&ge->generation);
- return 1;
-}
-
-
-static struct hpsb_highlevel_ops guid_ops = {
- host_reset: host_reset,
-};
-
-static struct hpsb_highlevel *hl;
-
-void init_ieee1394_guid(void)
-{
- atomic_set(&outstanding_requests, 0);
-
- hl = hpsb_register_highlevel("GUID manager", &guid_ops);
- if (!hl) {
- HPSB_ERR("out of memory during ieee1394 initialization");
- }
-}
-
-void cleanup_ieee1394_guid(void)
-{
- hpsb_unregister_highlevel(hl);
-}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)