Blame view

drivers/ieee1394/config_roms.c 4.47 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
  /*
   * IEEE 1394 for Linux
   *
   * ConfigROM  entries
   *
   * Copyright (C) 2004 Ben Collins
   *
   * This code is licensed under the GPL.  See the file COPYING in the root
   * directory of the kernel sources for details.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  #include <linux/types.h>
  
  #include "csr1212.h"
  #include "ieee1394.h"
  #include "ieee1394_types.h"
  #include "hosts.h"
  #include "ieee1394_core.h"
  #include "highlevel.h"
  #include "csr.h"
  #include "config_roms.h"
  
  struct hpsb_config_rom_entry {
  	const char *name;
  
  	/* Base initialization, called at module load */
  	int (*init)(void);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
  	/* Cleanup called at module exit */
  	void (*cleanup)(void);
  
  	/* The flag added to host->config_roms */
  	unsigned int flag;
  };
afd6546d8   Stefan Richter   ieee1394: move so...
33
  /* The default host entry. This must succeed. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  int hpsb_default_host_entry(struct hpsb_host *host)
  {
  	struct csr1212_keyval *root;
  	struct csr1212_keyval *vend_id = NULL;
  	struct csr1212_keyval *text = NULL;
  	char csr_name[128];
  	int ret;
  
  	sprintf(csr_name, "Linux - %s", host->driver->name);
  	root = host->csr.rom->root_kv;
  
  	vend_id = csr1212_new_immediate(CSR1212_KV_ID_VENDOR, host->csr.guid_hi >> 8);
  	text = csr1212_new_string_descriptor_leaf(csr_name);
  
  	if (!vend_id || !text) {
  		if (vend_id)
  			csr1212_release_keyval(vend_id);
  		if (text)
  			csr1212_release_keyval(text);
  		csr1212_destroy_csr(host->csr.rom);
  		return -ENOMEM;
  	}
64ff71232   Stefan Richter   ieee1394: stricte...
56
  	csr1212_associate_keyval(vend_id, text);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
  	csr1212_release_keyval(text);
64ff71232   Stefan Richter   ieee1394: stricte...
58
  	ret = csr1212_attach_keyval_to_directory(root, vend_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
64
65
66
67
68
  	csr1212_release_keyval(vend_id);
  	if (ret != CSR1212_SUCCESS) {
  		csr1212_destroy_csr(host->csr.rom);
  		return -ENOMEM;
  	}
  
  	host->update_config_rom = 1;
  
  	return 0;
  }
70093cfde   Stefan Richter   ieee1394: eth1394...
69
  #ifdef CONFIG_IEEE1394_ETH1394_ROM_ENTRY
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  #include "eth1394.h"
  
  static struct csr1212_keyval *ip1394_ud;
  
  static int config_rom_ip1394_init(void)
  {
  	struct csr1212_keyval *spec_id = NULL;
  	struct csr1212_keyval *spec_desc = NULL;
  	struct csr1212_keyval *ver = NULL;
  	struct csr1212_keyval *ver_desc = NULL;
  	int ret = -ENOMEM;
  
  	ip1394_ud = csr1212_new_directory(CSR1212_KV_ID_UNIT);
  
  	spec_id = csr1212_new_immediate(CSR1212_KV_ID_SPECIFIER_ID,
  					ETHER1394_GASP_SPECIFIER_ID);
  	spec_desc = csr1212_new_string_descriptor_leaf("IANA");
  	ver = csr1212_new_immediate(CSR1212_KV_ID_VERSION,
  				    ETHER1394_GASP_VERSION);
  	ver_desc = csr1212_new_string_descriptor_leaf("IPv4");
  
  	if (!ip1394_ud || !spec_id || !spec_desc || !ver || !ver_desc)
  		goto ip1394_fail;
64ff71232   Stefan Richter   ieee1394: stricte...
93
94
95
96
97
98
  	csr1212_associate_keyval(spec_id, spec_desc);
  	csr1212_associate_keyval(ver, ver_desc);
  	if (csr1212_attach_keyval_to_directory(ip1394_ud, spec_id)
  			== CSR1212_SUCCESS &&
  	    csr1212_attach_keyval_to_directory(ip1394_ud, ver)
  			== CSR1212_SUCCESS)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
  		ret = 0;
  
  ip1394_fail:
  	if (ret && ip1394_ud) {
  		csr1212_release_keyval(ip1394_ud);
  		ip1394_ud = NULL;
  	}
  
  	if (spec_id)
  		csr1212_release_keyval(spec_id);
  	if (spec_desc)
  		csr1212_release_keyval(spec_desc);
  	if (ver)
  		csr1212_release_keyval(ver);
  	if (ver_desc)
  		csr1212_release_keyval(ver_desc);
  
  	return ret;
  }
  
  static void config_rom_ip1394_cleanup(void)
  {
  	if (ip1394_ud) {
  		csr1212_release_keyval(ip1394_ud);
  		ip1394_ud = NULL;
  	}
  }
70093cfde   Stefan Richter   ieee1394: eth1394...
126
  int hpsb_config_rom_ip1394_add(struct hpsb_host *host)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
130
131
132
133
  {
  	if (!ip1394_ud)
  		return -ENODEV;
  
  	if (csr1212_attach_keyval_to_directory(host->csr.rom->root_kv,
  					       ip1394_ud) != CSR1212_SUCCESS)
  		return -ENOMEM;
70093cfde   Stefan Richter   ieee1394: eth1394...
134
135
  	host->config_roms |= HPSB_CONFIG_ROM_ENTRY_IP1394;
  	host->update_config_rom = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
137
  	return 0;
  }
70093cfde   Stefan Richter   ieee1394: eth1394...
138
  EXPORT_SYMBOL_GPL(hpsb_config_rom_ip1394_add);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139

70093cfde   Stefan Richter   ieee1394: eth1394...
140
  void hpsb_config_rom_ip1394_remove(struct hpsb_host *host)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
  {
  	csr1212_detach_keyval_from_directory(host->csr.rom->root_kv, ip1394_ud);
70093cfde   Stefan Richter   ieee1394: eth1394...
143
144
  	host->config_roms &= ~HPSB_CONFIG_ROM_ENTRY_IP1394;
  	host->update_config_rom = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  }
70093cfde   Stefan Richter   ieee1394: eth1394...
146
  EXPORT_SYMBOL_GPL(hpsb_config_rom_ip1394_remove);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
148
149
150
  
  static struct hpsb_config_rom_entry ip1394_entry = {
  	.name		= "ip1394",
  	.init		= config_rom_ip1394_init,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
  	.cleanup	= config_rom_ip1394_cleanup,
  	.flag		= HPSB_CONFIG_ROM_ENTRY_IP1394,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154

70093cfde   Stefan Richter   ieee1394: eth1394...
155
  #endif /* CONFIG_IEEE1394_ETH1394_ROM_ENTRY */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
  
  static struct hpsb_config_rom_entry *const config_rom_entries[] = {
70093cfde   Stefan Richter   ieee1394: eth1394...
158
  #ifdef CONFIG_IEEE1394_ETH1394_ROM_ENTRY
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
160
  	&ip1394_entry,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  };
afd6546d8   Stefan Richter   ieee1394: move so...
162
  /* Initialize all config roms */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
164
165
  int hpsb_init_config_roms(void)
  {
  	int i, error = 0;
70093cfde   Stefan Richter   ieee1394: eth1394...
166
  	for (i = 0; i < ARRAY_SIZE(config_rom_entries); i++)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
168
169
170
  		if (config_rom_entries[i]->init()) {
  			HPSB_ERR("Failed to initialize config rom entry `%s'",
  				 config_rom_entries[i]->name);
  			error = -1;
70093cfde   Stefan Richter   ieee1394: eth1394...
171
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
174
  
  	return error;
  }
afd6546d8   Stefan Richter   ieee1394: move so...
175
  /* Cleanup all config roms */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
178
  void hpsb_cleanup_config_roms(void)
  {
  	int i;
70093cfde   Stefan Richter   ieee1394: eth1394...
179
180
  	for (i = 0; i < ARRAY_SIZE(config_rom_entries); i++)
  		config_rom_entries[i]->cleanup();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  }