summaryrefslogtreecommitdiff
path: root/drivers/ieee1394/nodemgr.h
blob: 3a2f0c02fd081e679ebe50b32fc7e33ce405f730 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
 * Copyright (C) 2000	Andreas E. Bombe
 *               2001	Ben Collins <bcollins@debian.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef _IEEE1394_NODEMGR_H
#define _IEEE1394_NODEMGR_H

#include <linux/device.h>
#include "csr1212.h"
#include "ieee1394_core.h"
#include "ieee1394_hotplug.h"

/* '1' '3' '9' '4' in ASCII */
#define IEEE1394_BUSID_MAGIC	__constant_cpu_to_be32(0x31333934)

/* This is the start of a Node entry structure. It should be a stable API
 * for which to gather info from the Node Manager about devices attached
 * to the bus.  */
struct bus_options {
	u8	irmc;		/* Iso Resource Manager Capable */
	u8	cmc;		/* Cycle Master Capable */
	u8	isc;		/* Iso Capable */
	u8	bmc;		/* Bus Master Capable */
	u8	pmc;		/* Power Manager Capable (PNP spec) */
	u8	cyc_clk_acc;	/* Cycle clock accuracy */
	u8	max_rom;	/* Maximum block read supported in the CSR */
	u8	generation;	/* Incremented when configrom changes */
	u8	lnkspd;		/* Link speed */
	u16	max_rec;	/* Maximum packet size node can receive */
};


#define UNIT_DIRECTORY_VENDOR_ID		0x01
#define UNIT_DIRECTORY_MODEL_ID			0x02
#define UNIT_DIRECTORY_SPECIFIER_ID		0x04
#define UNIT_DIRECTORY_VERSION			0x08
#define UNIT_DIRECTORY_HAS_LUN_DIRECTORY	0x10
#define UNIT_DIRECTORY_LUN_DIRECTORY		0x20
#define UNIT_DIRECTORY_HAS_LUN			0x40

/*
 * A unit directory corresponds to a protocol supported by the
 * node. If a node supports eg. IP/1394 and AV/C, its config rom has a
 * unit directory for each of these protocols.
 */
struct unit_directory {
	struct node_entry *ne;  /* The node which this directory belongs to */
	octlet_t address;       /* Address of the unit directory on the node */
	u8 flags;		/* Indicates which entries were read */

	quadlet_t vendor_id;
	struct csr1212_keyval *vendor_name_kv;
	const char *vendor_oui;

	quadlet_t model_id;
	struct csr1212_keyval *model_name_kv;
	quadlet_t specifier_id;
	quadlet_t version;

	unsigned int id;

	int ignore_driver;

	int length;		/* Number of quadlets */

	struct device device;

	struct class_device class_dev;

	struct csr1212_keyval *ud_kv;
	u32 lun;                /* logical unit number immediate value */
};

struct node_entry {
	u64 guid;			/* GUID of this node */
	u32 guid_vendor_id;		/* Top 24bits of guid */
	const char *guid_vendor_oui;	/* OUI name of guid vendor id */

	struct hpsb_host *host;		/* Host this node is attached to */
	nodeid_t nodeid;		/* NodeID */
	struct bus_options busopt;	/* Bus Options */
	int needs_probe;
	unsigned int generation;	/* Synced with hpsb generation */

	/* The following is read from the config rom */
	u32 vendor_id;
	struct csr1212_keyval *vendor_name_kv;
	const char *vendor_oui;

	u32 capabilities;
	struct hpsb_tlabel_pool *tpool;

	struct device device;

	struct class_device class_dev;

	/* Means this node is not attached anymore */
	int in_limbo;

	struct csr1212_csr *csr;
};

struct hpsb_protocol_driver {
	/* The name of the driver, e.g. SBP2 or IP1394 */
	const char *name;

	/*
	 * The device id table describing the protocols and/or devices
	 * supported by this driver.  This is used by the nodemgr to
	 * decide if a driver could support a given node, but the
	 * probe function below can implement further protocol
	 * dependent or vendor dependent checking.
	 */
	struct ieee1394_device_id *id_table;

	/*
	 * The update function is called when the node has just
	 * survived a bus reset, i.e. it is still present on the bus.
	 * However, it may be necessary to reestablish the connection
	 * or login into the node again, depending on the protocol. If the
	 * probe fails (returns non-zero), we unbind the driver from this
	 * device.
	 */
	int (*update)(struct unit_directory *ud);

	/* Our LDM structure */
	struct device_driver driver;
};

int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);

static inline int hpsb_node_entry_valid(struct node_entry *ne)
{
	return ne->generation == get_hpsb_generation(ne->host);
}

/*
 * Returns a node entry (which has its reference count incremented) or NULL if
 * the GUID in question is not known.  Getting a valid entry does not mean that
 * the node with this GUID is currently accessible (might be powered down).
 */
struct node_entry *hpsb_guid_get_entry(u64 guid);

/* Same as above, but use the nodeid to get an node entry. This is not
 * fool-proof by itself, since the nodeid can change.  */
struct node_entry *hpsb_nodeid_get_entry(struct hpsb_host *host, nodeid_t nodeid);

/*
 * If the entry refers to a local host, this function will return the pointer
 * to the hpsb_host structure.  It will return NULL otherwise.  Once you have
 * established it is a local host, you can use that knowledge from then on (the
 * GUID won't wander to an external node).  */
struct hpsb_host *hpsb_get_host_by_ne(struct node_entry *ne);

/*
 * This will fill in the given, pre-initialised hpsb_packet with the current
 * information from the node entry (host, node ID, generation number).  It will
 * return false if the node owning the GUID is not accessible (and not modify the
 * hpsb_packet) and return true otherwise.
 *
 * Note that packet sending may still fail in hpsb_send_packet if a bus reset
 * happens while you are trying to set up the packet (due to obsolete generation
 * number).  It will at least reliably fail so that you don't accidentally and
 * unknowingly send your packet to the wrong node.
 */
void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt);

int hpsb_node_read(struct node_entry *ne, u64 addr,
		   quadlet_t *buffer, size_t length);
int hpsb_node_write(struct node_entry *ne, u64 addr,
		    quadlet_t *buffer, size_t length);
int hpsb_node_lock(struct node_entry *ne, u64 addr,
		   int extcode, quadlet_t *data, quadlet_t arg);


/* Iterate the hosts, calling a given function with supplied data for each
 * host. */
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *));


int init_ieee1394_nodemgr(void);
void cleanup_ieee1394_nodemgr(void);


/* The template for a host device */
extern struct device nodemgr_dev_template_host;

/* Bus attributes we export */
extern struct bus_attribute *const fw_bus_attrs[];

#endif /* _IEEE1394_NODEMGR_H */