diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/ieee1394/ieee1394_core.c |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/ieee1394/ieee1394_core.c')
-rw-r--r-- | drivers/ieee1394/ieee1394_core.c | 1330 |
1 files changed, 1330 insertions, 0 deletions
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c new file mode 100644 index 000000000000..1c5845f7e4ab --- /dev/null +++ b/drivers/ieee1394/ieee1394_core.c | |||
@@ -0,0 +1,1330 @@ | |||
1 | /* | ||
2 | * IEEE 1394 for Linux | ||
3 | * | ||
4 | * Core support: hpsb_packet management, packet handling and forwarding to | ||
5 | * highlevel or lowlevel code | ||
6 | * | ||
7 | * Copyright (C) 1999, 2000 Andreas E. Bombe | ||
8 | * 2002 Manfred Weihs <weihs@ict.tuwien.ac.at> | ||
9 | * | ||
10 | * This code is licensed under the GPL. See the file COPYING in the root | ||
11 | * directory of the kernel sources for details. | ||
12 | * | ||
13 | * | ||
14 | * Contributions: | ||
15 | * | ||
16 | * Manfred Weihs <weihs@ict.tuwien.ac.at> | ||
17 | * loopback functionality in hpsb_send_packet | ||
18 | * allow highlevel drivers to disable automatic response generation | ||
19 | * and to generate responses themselves (deferred) | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/config.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/list.h> | ||
26 | #include <linux/string.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/moduleparam.h> | ||
32 | #include <linux/bitops.h> | ||
33 | #include <linux/kdev_t.h> | ||
34 | #include <linux/skbuff.h> | ||
35 | #include <linux/suspend.h> | ||
36 | |||
37 | #include <asm/byteorder.h> | ||
38 | #include <asm/semaphore.h> | ||
39 | |||
40 | #include "ieee1394_types.h" | ||
41 | #include "ieee1394.h" | ||
42 | #include "hosts.h" | ||
43 | #include "ieee1394_core.h" | ||
44 | #include "highlevel.h" | ||
45 | #include "ieee1394_transactions.h" | ||
46 | #include "csr.h" | ||
47 | #include "nodemgr.h" | ||
48 | #include "dma.h" | ||
49 | #include "iso.h" | ||
50 | #include "config_roms.h" | ||
51 | |||
52 | /* | ||
53 | * Disable the nodemgr detection and config rom reading functionality. | ||
54 | */ | ||
55 | static int disable_nodemgr = 0; | ||
56 | module_param(disable_nodemgr, int, 0444); | ||
57 | MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality."); | ||
58 | |||
59 | /* Disable Isochronous Resource Manager functionality */ | ||
60 | int hpsb_disable_irm = 0; | ||
61 | module_param_named(disable_irm, hpsb_disable_irm, bool, 0); | ||
62 | MODULE_PARM_DESC(disable_irm, | ||
63 | "Disable Isochronous Resource Manager functionality."); | ||
64 | |||
65 | /* We are GPL, so treat us special */ | ||
66 | MODULE_LICENSE("GPL"); | ||
67 | |||
68 | /* Some globals used */ | ||
69 | const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" }; | ||
70 | struct class_simple *hpsb_protocol_class; | ||
71 | |||
72 | #ifdef CONFIG_IEEE1394_VERBOSEDEBUG | ||
73 | static void dump_packet(const char *text, quadlet_t *data, int size) | ||
74 | { | ||
75 | int i; | ||
76 | |||
77 | size /= 4; | ||
78 | size = (size > 4 ? 4 : size); | ||
79 | |||
80 | printk(KERN_DEBUG "ieee1394: %s", text); | ||
81 | for (i = 0; i < size; i++) | ||
82 | printk(" %08x", data[i]); | ||
83 | printk("\n"); | ||
84 | } | ||
85 | #else | ||
86 | #define dump_packet(x,y,z) | ||
87 | #endif | ||
88 | |||
89 | static void abort_requests(struct hpsb_host *host); | ||
90 | static void queue_packet_complete(struct hpsb_packet *packet); | ||
91 | |||
92 | |||
93 | /** | ||
94 | * hpsb_set_packet_complete_task - set the task that runs when a packet | ||
95 | * completes. You cannot call this more than once on a single packet | ||
96 | * before it is sent. | ||
97 | * | ||
98 | * @packet: the packet whose completion we want the task added to | ||
99 | * @routine: function to call | ||
100 | * @data: data (if any) to pass to the above function | ||
101 | */ | ||
102 | void hpsb_set_packet_complete_task(struct hpsb_packet *packet, | ||
103 | void (*routine)(void *), void *data) | ||
104 | { | ||
105 | WARN_ON(packet->complete_routine != NULL); | ||
106 | packet->complete_routine = routine; | ||
107 | packet->complete_data = data; | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | /** | ||
112 | * hpsb_alloc_packet - allocate new packet structure | ||
113 | * @data_size: size of the data block to be allocated | ||
114 | * | ||
115 | * This function allocates, initializes and returns a new &struct hpsb_packet. | ||
116 | * It can be used in interrupt context. A header block is always included, its | ||
117 | * size is big enough to contain all possible 1394 headers. The data block is | ||
118 | * only allocated when @data_size is not zero. | ||
119 | * | ||
120 | * For packets for which responses will be received the @data_size has to be big | ||
121 | * enough to contain the response's data block since no further allocation | ||
122 | * occurs at response matching time. | ||
123 | * | ||
124 | * The packet's generation value will be set to the current generation number | ||
125 | * for ease of use. Remember to overwrite it with your own recorded generation | ||
126 | * number if you can not be sure that your code will not race with a bus reset. | ||
127 | * | ||
128 | * Return value: A pointer to a &struct hpsb_packet or NULL on allocation | ||
129 | * failure. | ||
130 | */ | ||
131 | struct hpsb_packet *hpsb_alloc_packet(size_t data_size) | ||
132 | { | ||
133 | struct hpsb_packet *packet = NULL; | ||
134 | struct sk_buff *skb; | ||
135 | |||
136 | data_size = ((data_size + 3) & ~3); | ||
137 | |||
138 | skb = alloc_skb(data_size + sizeof(*packet), GFP_ATOMIC); | ||
139 | if (skb == NULL) | ||
140 | return NULL; | ||
141 | |||
142 | memset(skb->data, 0, data_size + sizeof(*packet)); | ||
143 | |||
144 | packet = (struct hpsb_packet *)skb->data; | ||
145 | packet->skb = skb; | ||
146 | |||
147 | packet->header = packet->embedded_header; | ||
148 | packet->state = hpsb_unused; | ||
149 | packet->generation = -1; | ||
150 | INIT_LIST_HEAD(&packet->driver_list); | ||
151 | atomic_set(&packet->refcnt, 1); | ||
152 | |||
153 | if (data_size) { | ||
154 | packet->data = (quadlet_t *)(skb->data + sizeof(*packet)); | ||
155 | packet->data_size = data_size; | ||
156 | } | ||
157 | |||
158 | return packet; | ||
159 | } | ||
160 | |||
161 | |||
162 | /** | ||
163 | * hpsb_free_packet - free packet and data associated with it | ||
164 | * @packet: packet to free (is NULL safe) | ||
165 | * | ||
166 | * This function will free packet->data and finally the packet itself. | ||
167 | */ | ||
168 | void hpsb_free_packet(struct hpsb_packet *packet) | ||
169 | { | ||
170 | if (packet && atomic_dec_and_test(&packet->refcnt)) { | ||
171 | BUG_ON(!list_empty(&packet->driver_list)); | ||
172 | kfree_skb(packet->skb); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | |||
177 | int hpsb_reset_bus(struct hpsb_host *host, int type) | ||
178 | { | ||
179 | if (!host->in_bus_reset) { | ||
180 | host->driver->devctl(host, RESET_BUS, type); | ||
181 | return 0; | ||
182 | } else { | ||
183 | return 1; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | |||
188 | int hpsb_bus_reset(struct hpsb_host *host) | ||
189 | { | ||
190 | if (host->in_bus_reset) { | ||
191 | HPSB_NOTICE("%s called while bus reset already in progress", | ||
192 | __FUNCTION__); | ||
193 | return 1; | ||
194 | } | ||
195 | |||
196 | abort_requests(host); | ||
197 | host->in_bus_reset = 1; | ||
198 | host->irm_id = -1; | ||
199 | host->is_irm = 0; | ||
200 | host->busmgr_id = -1; | ||
201 | host->is_busmgr = 0; | ||
202 | host->is_cycmst = 0; | ||
203 | host->node_count = 0; | ||
204 | host->selfid_count = 0; | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | |||
210 | /* | ||
211 | * Verify num_of_selfids SelfIDs and return number of nodes. Return zero in | ||
212 | * case verification failed. | ||
213 | */ | ||
214 | static int check_selfids(struct hpsb_host *host) | ||
215 | { | ||
216 | int nodeid = -1; | ||
217 | int rest_of_selfids = host->selfid_count; | ||
218 | struct selfid *sid = (struct selfid *)host->topology_map; | ||
219 | struct ext_selfid *esid; | ||
220 | int esid_seq = 23; | ||
221 | |||
222 | host->nodes_active = 0; | ||
223 | |||
224 | while (rest_of_selfids--) { | ||
225 | if (!sid->extended) { | ||
226 | nodeid++; | ||
227 | esid_seq = 0; | ||
228 | |||
229 | if (sid->phy_id != nodeid) { | ||
230 | HPSB_INFO("SelfIDs failed monotony check with " | ||
231 | "%d", sid->phy_id); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | if (sid->link_active) { | ||
236 | host->nodes_active++; | ||
237 | if (sid->contender) | ||
238 | host->irm_id = LOCAL_BUS | sid->phy_id; | ||
239 | } | ||
240 | } else { | ||
241 | esid = (struct ext_selfid *)sid; | ||
242 | |||
243 | if ((esid->phy_id != nodeid) | ||
244 | || (esid->seq_nr != esid_seq)) { | ||
245 | HPSB_INFO("SelfIDs failed monotony check with " | ||
246 | "%d/%d", esid->phy_id, esid->seq_nr); | ||
247 | return 0; | ||
248 | } | ||
249 | esid_seq++; | ||
250 | } | ||
251 | sid++; | ||
252 | } | ||
253 | |||
254 | esid = (struct ext_selfid *)(sid - 1); | ||
255 | while (esid->extended) { | ||
256 | if ((esid->porta == 0x2) || (esid->portb == 0x2) | ||
257 | || (esid->portc == 0x2) || (esid->portd == 0x2) | ||
258 | || (esid->porte == 0x2) || (esid->portf == 0x2) | ||
259 | || (esid->portg == 0x2) || (esid->porth == 0x2)) { | ||
260 | HPSB_INFO("SelfIDs failed root check on " | ||
261 | "extended SelfID"); | ||
262 | return 0; | ||
263 | } | ||
264 | esid--; | ||
265 | } | ||
266 | |||
267 | sid = (struct selfid *)esid; | ||
268 | if ((sid->port0 == 0x2) || (sid->port1 == 0x2) || (sid->port2 == 0x2)) { | ||
269 | HPSB_INFO("SelfIDs failed root check"); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | host->node_count = nodeid + 1; | ||
274 | return 1; | ||
275 | } | ||
276 | |||
277 | static void build_speed_map(struct hpsb_host *host, int nodecount) | ||
278 | { | ||
279 | u8 speedcap[nodecount]; | ||
280 | u8 cldcnt[nodecount]; | ||
281 | u8 *map = host->speed_map; | ||
282 | struct selfid *sid; | ||
283 | struct ext_selfid *esid; | ||
284 | int i, j, n; | ||
285 | |||
286 | for (i = 0; i < (nodecount * 64); i += 64) { | ||
287 | for (j = 0; j < nodecount; j++) { | ||
288 | map[i+j] = IEEE1394_SPEED_MAX; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | for (i = 0; i < nodecount; i++) { | ||
293 | cldcnt[i] = 0; | ||
294 | } | ||
295 | |||
296 | /* find direct children count and speed */ | ||
297 | for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1], | ||
298 | n = nodecount - 1; | ||
299 | (void *)sid >= (void *)host->topology_map; sid--) { | ||
300 | if (sid->extended) { | ||
301 | esid = (struct ext_selfid *)sid; | ||
302 | |||
303 | if (esid->porta == 0x3) cldcnt[n]++; | ||
304 | if (esid->portb == 0x3) cldcnt[n]++; | ||
305 | if (esid->portc == 0x3) cldcnt[n]++; | ||
306 | if (esid->portd == 0x3) cldcnt[n]++; | ||
307 | if (esid->porte == 0x3) cldcnt[n]++; | ||
308 | if (esid->portf == 0x3) cldcnt[n]++; | ||
309 | if (esid->portg == 0x3) cldcnt[n]++; | ||
310 | if (esid->porth == 0x3) cldcnt[n]++; | ||
311 | } else { | ||
312 | if (sid->port0 == 0x3) cldcnt[n]++; | ||
313 | if (sid->port1 == 0x3) cldcnt[n]++; | ||
314 | if (sid->port2 == 0x3) cldcnt[n]++; | ||
315 | |||
316 | speedcap[n] = sid->speed; | ||
317 | n--; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | /* set self mapping */ | ||
322 | for (i = 0; i < nodecount; i++) { | ||
323 | map[64*i + i] = speedcap[i]; | ||
324 | } | ||
325 | |||
326 | /* fix up direct children count to total children count; | ||
327 | * also fix up speedcaps for sibling and parent communication */ | ||
328 | for (i = 1; i < nodecount; i++) { | ||
329 | for (j = cldcnt[i], n = i - 1; j > 0; j--) { | ||
330 | cldcnt[i] += cldcnt[n]; | ||
331 | speedcap[n] = min(speedcap[n], speedcap[i]); | ||
332 | n -= cldcnt[n] + 1; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | for (n = 0; n < nodecount; n++) { | ||
337 | for (i = n - cldcnt[n]; i <= n; i++) { | ||
338 | for (j = 0; j < (n - cldcnt[n]); j++) { | ||
339 | map[j*64 + i] = map[i*64 + j] = | ||
340 | min(map[i*64 + j], speedcap[n]); | ||
341 | } | ||
342 | for (j = n + 1; j < nodecount; j++) { | ||
343 | map[j*64 + i] = map[i*64 + j] = | ||
344 | min(map[i*64 + j], speedcap[n]); | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | |||
350 | |||
351 | void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid) | ||
352 | { | ||
353 | if (host->in_bus_reset) { | ||
354 | HPSB_VERBOSE("Including SelfID 0x%x", sid); | ||
355 | host->topology_map[host->selfid_count++] = sid; | ||
356 | } else { | ||
357 | HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d", | ||
358 | sid, NODEID_TO_BUS(host->node_id)); | ||
359 | } | ||
360 | } | ||
361 | |||
362 | void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot) | ||
363 | { | ||
364 | if (!host->in_bus_reset) | ||
365 | HPSB_NOTICE("SelfID completion called outside of bus reset!"); | ||
366 | |||
367 | host->node_id = LOCAL_BUS | phyid; | ||
368 | host->is_root = isroot; | ||
369 | |||
370 | if (!check_selfids(host)) { | ||
371 | if (host->reset_retries++ < 20) { | ||
372 | /* selfid stage did not complete without error */ | ||
373 | HPSB_NOTICE("Error in SelfID stage, resetting"); | ||
374 | host->in_bus_reset = 0; | ||
375 | /* this should work from ohci1394 now... */ | ||
376 | hpsb_reset_bus(host, LONG_RESET); | ||
377 | return; | ||
378 | } else { | ||
379 | HPSB_NOTICE("Stopping out-of-control reset loop"); | ||
380 | HPSB_NOTICE("Warning - topology map and speed map will not be valid"); | ||
381 | host->reset_retries = 0; | ||
382 | } | ||
383 | } else { | ||
384 | host->reset_retries = 0; | ||
385 | build_speed_map(host, host->node_count); | ||
386 | } | ||
387 | |||
388 | HPSB_VERBOSE("selfid_complete called with successful SelfID stage " | ||
389 | "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id); | ||
390 | |||
391 | /* irm_id is kept up to date by check_selfids() */ | ||
392 | if (host->irm_id == host->node_id) { | ||
393 | host->is_irm = 1; | ||
394 | } else { | ||
395 | host->is_busmgr = 0; | ||
396 | host->is_irm = 0; | ||
397 | } | ||
398 | |||
399 | if (isroot) { | ||
400 | host->driver->devctl(host, ACT_CYCLE_MASTER, 1); | ||
401 | host->is_cycmst = 1; | ||
402 | } | ||
403 | atomic_inc(&host->generation); | ||
404 | host->in_bus_reset = 0; | ||
405 | highlevel_host_reset(host); | ||
406 | } | ||
407 | |||
408 | |||
409 | void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, | ||
410 | int ackcode) | ||
411 | { | ||
412 | unsigned long flags; | ||
413 | |||
414 | spin_lock_irqsave(&host->pending_packet_queue.lock, flags); | ||
415 | |||
416 | packet->ack_code = ackcode; | ||
417 | |||
418 | if (packet->no_waiter || packet->state == hpsb_complete) { | ||
419 | /* if packet->no_waiter, must not have a tlabel allocated */ | ||
420 | spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); | ||
421 | hpsb_free_packet(packet); | ||
422 | return; | ||
423 | } | ||
424 | |||
425 | atomic_dec(&packet->refcnt); /* drop HC's reference */ | ||
426 | /* here the packet must be on the host->pending_packet_queue */ | ||
427 | |||
428 | if (ackcode != ACK_PENDING || !packet->expect_response) { | ||
429 | packet->state = hpsb_complete; | ||
430 | __skb_unlink(packet->skb, &host->pending_packet_queue); | ||
431 | spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); | ||
432 | queue_packet_complete(packet); | ||
433 | return; | ||
434 | } | ||
435 | |||
436 | packet->state = hpsb_pending; | ||
437 | packet->sendtime = jiffies; | ||
438 | |||
439 | spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); | ||
440 | |||
441 | mod_timer(&host->timeout, jiffies + host->timeout_interval); | ||
442 | } | ||
443 | |||
444 | /** | ||
445 | * hpsb_send_phy_config - transmit a PHY configuration packet on the bus | ||
446 | * @host: host that PHY config packet gets sent through | ||
447 | * @rootid: root whose force_root bit should get set (-1 = don't set force_root) | ||
448 | * @gapcnt: gap count value to set (-1 = don't set gap count) | ||
449 | * | ||
450 | * This function sends a PHY config packet on the bus through the specified host. | ||
451 | * | ||
452 | * Return value: 0 for success or error number otherwise. | ||
453 | */ | ||
454 | int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt) | ||
455 | { | ||
456 | struct hpsb_packet *packet; | ||
457 | int retval = 0; | ||
458 | |||
459 | if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 || | ||
460 | (rootid == -1 && gapcnt == -1)) { | ||
461 | HPSB_DEBUG("Invalid Parameter: rootid = %d gapcnt = %d", | ||
462 | rootid, gapcnt); | ||
463 | return -EINVAL; | ||
464 | } | ||
465 | |||
466 | packet = hpsb_alloc_packet(0); | ||
467 | if (!packet) | ||
468 | return -ENOMEM; | ||
469 | |||
470 | packet->host = host; | ||
471 | packet->header_size = 8; | ||
472 | packet->data_size = 0; | ||
473 | packet->expect_response = 0; | ||
474 | packet->no_waiter = 0; | ||
475 | packet->type = hpsb_raw; | ||
476 | packet->header[0] = 0; | ||
477 | if (rootid != -1) | ||
478 | packet->header[0] |= rootid << 24 | 1 << 23; | ||
479 | if (gapcnt != -1) | ||
480 | packet->header[0] |= gapcnt << 16 | 1 << 22; | ||
481 | |||
482 | packet->header[1] = ~packet->header[0]; | ||
483 | |||
484 | packet->generation = get_hpsb_generation(host); | ||
485 | |||
486 | retval = hpsb_send_packet_and_wait(packet); | ||
487 | hpsb_free_packet(packet); | ||
488 | |||
489 | return retval; | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * hpsb_send_packet - transmit a packet on the bus | ||
494 | * @packet: packet to send | ||
495 | * | ||
496 | * The packet is sent through the host specified in the packet->host field. | ||
497 | * Before sending, the packet's transmit speed is automatically determined | ||
498 | * using the local speed map when it is an async, non-broadcast packet. | ||
499 | * | ||
500 | * Possibilities for failure are that host is either not initialized, in bus | ||
501 | * reset, the packet's generation number doesn't match the current generation | ||
502 | * number or the host reports a transmit error. | ||
503 | * | ||
504 | * Return value: 0 on success, negative errno on failure. | ||
505 | */ | ||
506 | int hpsb_send_packet(struct hpsb_packet *packet) | ||
507 | { | ||
508 | struct hpsb_host *host = packet->host; | ||
509 | |||
510 | if (host->is_shutdown) | ||
511 | return -EINVAL; | ||
512 | if (host->in_bus_reset || | ||
513 | (packet->generation != get_hpsb_generation(host))) | ||
514 | return -EAGAIN; | ||
515 | |||
516 | packet->state = hpsb_queued; | ||
517 | |||
518 | /* This just seems silly to me */ | ||
519 | WARN_ON(packet->no_waiter && packet->expect_response); | ||
520 | |||
521 | if (!packet->no_waiter || packet->expect_response) { | ||
522 | atomic_inc(&packet->refcnt); | ||
523 | packet->sendtime = jiffies; | ||
524 | skb_queue_tail(&host->pending_packet_queue, packet->skb); | ||
525 | } | ||
526 | |||
527 | if (packet->node_id == host->node_id) { | ||
528 | /* it is a local request, so handle it locally */ | ||
529 | |||
530 | quadlet_t *data; | ||
531 | size_t size = packet->data_size + packet->header_size; | ||
532 | |||
533 | data = kmalloc(size, GFP_ATOMIC); | ||
534 | if (!data) { | ||
535 | HPSB_ERR("unable to allocate memory for concatenating header and data"); | ||
536 | return -ENOMEM; | ||
537 | } | ||
538 | |||
539 | memcpy(data, packet->header, packet->header_size); | ||
540 | |||
541 | if (packet->data_size) | ||
542 | memcpy(((u8*)data) + packet->header_size, packet->data, packet->data_size); | ||
543 | |||
544 | dump_packet("send packet local:", packet->header, | ||
545 | packet->header_size); | ||
546 | |||
547 | hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE); | ||
548 | hpsb_packet_received(host, data, size, 0); | ||
549 | |||
550 | kfree(data); | ||
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | if (packet->type == hpsb_async && packet->node_id != ALL_NODES) { | ||
556 | packet->speed_code = | ||
557 | host->speed_map[NODEID_TO_NODE(host->node_id) * 64 | ||
558 | + NODEID_TO_NODE(packet->node_id)]; | ||
559 | } | ||
560 | |||
561 | #ifdef CONFIG_IEEE1394_VERBOSEDEBUG | ||
562 | switch (packet->speed_code) { | ||
563 | case 2: | ||
564 | dump_packet("send packet 400:", packet->header, | ||
565 | packet->header_size); | ||
566 | break; | ||
567 | case 1: | ||
568 | dump_packet("send packet 200:", packet->header, | ||
569 | packet->header_size); | ||
570 | break; | ||
571 | default: | ||
572 | dump_packet("send packet 100:", packet->header, | ||
573 | packet->header_size); | ||
574 | } | ||
575 | #endif | ||
576 | |||
577 | return host->driver->transmit_packet(host, packet); | ||
578 | } | ||
579 | |||
580 | /* We could just use complete() directly as the packet complete | ||
581 | * callback, but this is more typesafe, in the sense that we get a | ||
582 | * compiler error if the prototype for complete() changes. */ | ||
583 | |||
584 | static void complete_packet(void *data) | ||
585 | { | ||
586 | complete((struct completion *) data); | ||
587 | } | ||
588 | |||
589 | int hpsb_send_packet_and_wait(struct hpsb_packet *packet) | ||
590 | { | ||
591 | struct completion done; | ||
592 | int retval; | ||
593 | |||
594 | init_completion(&done); | ||
595 | hpsb_set_packet_complete_task(packet, complete_packet, &done); | ||
596 | retval = hpsb_send_packet(packet); | ||
597 | if (retval == 0) | ||
598 | wait_for_completion(&done); | ||
599 | |||
600 | return retval; | ||
601 | } | ||
602 | |||
603 | static void send_packet_nocare(struct hpsb_packet *packet) | ||
604 | { | ||
605 | if (hpsb_send_packet(packet) < 0) { | ||
606 | hpsb_free_packet(packet); | ||
607 | } | ||
608 | } | ||
609 | |||
610 | |||
611 | static void handle_packet_response(struct hpsb_host *host, int tcode, | ||
612 | quadlet_t *data, size_t size) | ||
613 | { | ||
614 | struct hpsb_packet *packet = NULL; | ||
615 | struct sk_buff *skb; | ||
616 | int tcode_match = 0; | ||
617 | int tlabel; | ||
618 | unsigned long flags; | ||
619 | |||
620 | tlabel = (data[0] >> 10) & 0x3f; | ||
621 | |||
622 | spin_lock_irqsave(&host->pending_packet_queue.lock, flags); | ||
623 | |||
624 | skb_queue_walk(&host->pending_packet_queue, skb) { | ||
625 | packet = (struct hpsb_packet *)skb->data; | ||
626 | if ((packet->tlabel == tlabel) | ||
627 | && (packet->node_id == (data[1] >> 16))){ | ||
628 | break; | ||
629 | } | ||
630 | |||
631 | packet = NULL; | ||
632 | } | ||
633 | |||
634 | if (packet == NULL) { | ||
635 | HPSB_DEBUG("unsolicited response packet received - no tlabel match"); | ||
636 | dump_packet("contents:", data, 16); | ||
637 | spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); | ||
638 | return; | ||
639 | } | ||
640 | |||
641 | switch (packet->tcode) { | ||
642 | case TCODE_WRITEQ: | ||
643 | case TCODE_WRITEB: | ||
644 | if (tcode != TCODE_WRITE_RESPONSE) | ||
645 | break; | ||
646 | tcode_match = 1; | ||
647 | memcpy(packet->header, data, 12); | ||
648 | break; | ||
649 | case TCODE_READQ: | ||
650 | if (tcode != TCODE_READQ_RESPONSE) | ||
651 | break; | ||
652 | tcode_match = 1; | ||
653 | memcpy(packet->header, data, 16); | ||
654 | break; | ||
655 | case TCODE_READB: | ||
656 | if (tcode != TCODE_READB_RESPONSE) | ||
657 | break; | ||
658 | tcode_match = 1; | ||
659 | BUG_ON(packet->skb->len - sizeof(*packet) < size - 16); | ||
660 | memcpy(packet->header, data, 16); | ||
661 | memcpy(packet->data, data + 4, size - 16); | ||
662 | break; | ||
663 | case TCODE_LOCK_REQUEST: | ||
664 | if (tcode != TCODE_LOCK_RESPONSE) | ||
665 | break; | ||
666 | tcode_match = 1; | ||
667 | size = min((size - 16), (size_t)8); | ||
668 | BUG_ON(packet->skb->len - sizeof(*packet) < size); | ||
669 | memcpy(packet->header, data, 16); | ||
670 | memcpy(packet->data, data + 4, size); | ||
671 | break; | ||
672 | } | ||
673 | |||
674 | if (!tcode_match) { | ||
675 | spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); | ||
676 | HPSB_INFO("unsolicited response packet received - tcode mismatch"); | ||
677 | dump_packet("contents:", data, 16); | ||
678 | return; | ||
679 | } | ||
680 | |||
681 | __skb_unlink(skb, skb->list); | ||
682 | |||
683 | if (packet->state == hpsb_queued) { | ||
684 | packet->sendtime = jiffies; | ||
685 | packet->ack_code = ACK_PENDING; | ||
686 | } | ||
687 | |||
688 | packet->state = hpsb_complete; | ||
689 | spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); | ||
690 | |||
691 | queue_packet_complete(packet); | ||
692 | } | ||
693 | |||
694 | |||
695 | static struct hpsb_packet *create_reply_packet(struct hpsb_host *host, | ||
696 | quadlet_t *data, size_t dsize) | ||
697 | { | ||
698 | struct hpsb_packet *p; | ||
699 | |||
700 | p = hpsb_alloc_packet(dsize); | ||
701 | if (unlikely(p == NULL)) { | ||
702 | /* FIXME - send data_error response */ | ||
703 | return NULL; | ||
704 | } | ||
705 | |||
706 | p->type = hpsb_async; | ||
707 | p->state = hpsb_unused; | ||
708 | p->host = host; | ||
709 | p->node_id = data[1] >> 16; | ||
710 | p->tlabel = (data[0] >> 10) & 0x3f; | ||
711 | p->no_waiter = 1; | ||
712 | |||
713 | p->generation = get_hpsb_generation(host); | ||
714 | |||
715 | if (dsize % 4) | ||
716 | p->data[dsize / 4] = 0; | ||
717 | |||
718 | return p; | ||
719 | } | ||
720 | |||
721 | #define PREP_ASYNC_HEAD_RCODE(tc) \ | ||
722 | packet->tcode = tc; \ | ||
723 | packet->header[0] = (packet->node_id << 16) | (packet->tlabel << 10) \ | ||
724 | | (1 << 8) | (tc << 4); \ | ||
725 | packet->header[1] = (packet->host->node_id << 16) | (rcode << 12); \ | ||
726 | packet->header[2] = 0 | ||
727 | |||
728 | static void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode, | ||
729 | quadlet_t data) | ||
730 | { | ||
731 | PREP_ASYNC_HEAD_RCODE(TCODE_READQ_RESPONSE); | ||
732 | packet->header[3] = data; | ||
733 | packet->header_size = 16; | ||
734 | packet->data_size = 0; | ||
735 | } | ||
736 | |||
737 | static void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode, | ||
738 | int length) | ||
739 | { | ||
740 | if (rcode != RCODE_COMPLETE) | ||
741 | length = 0; | ||
742 | |||
743 | PREP_ASYNC_HEAD_RCODE(TCODE_READB_RESPONSE); | ||
744 | packet->header[3] = length << 16; | ||
745 | packet->header_size = 16; | ||
746 | packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0); | ||
747 | } | ||
748 | |||
749 | static void fill_async_write_resp(struct hpsb_packet *packet, int rcode) | ||
750 | { | ||
751 | PREP_ASYNC_HEAD_RCODE(TCODE_WRITE_RESPONSE); | ||
752 | packet->header[2] = 0; | ||
753 | packet->header_size = 12; | ||
754 | packet->data_size = 0; | ||
755 | } | ||
756 | |||
757 | static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode, | ||
758 | int length) | ||
759 | { | ||
760 | if (rcode != RCODE_COMPLETE) | ||
761 | length = 0; | ||
762 | |||
763 | PREP_ASYNC_HEAD_RCODE(TCODE_LOCK_RESPONSE); | ||
764 | packet->header[3] = (length << 16) | extcode; | ||
765 | packet->header_size = 16; | ||
766 | packet->data_size = length; | ||
767 | } | ||
768 | |||
769 | #define PREP_REPLY_PACKET(length) \ | ||
770 | packet = create_reply_packet(host, data, length); \ | ||
771 | if (packet == NULL) break | ||
772 | |||
773 | static void handle_incoming_packet(struct hpsb_host *host, int tcode, | ||
774 | quadlet_t *data, size_t size, int write_acked) | ||
775 | { | ||
776 | struct hpsb_packet *packet; | ||
777 | int length, rcode, extcode; | ||
778 | quadlet_t buffer; | ||
779 | nodeid_t source = data[1] >> 16; | ||
780 | nodeid_t dest = data[0] >> 16; | ||
781 | u16 flags = (u16) data[0]; | ||
782 | u64 addr; | ||
783 | |||
784 | /* big FIXME - no error checking is done for an out of bounds length */ | ||
785 | |||
786 | switch (tcode) { | ||
787 | case TCODE_WRITEQ: | ||
788 | addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; | ||
789 | rcode = highlevel_write(host, source, dest, data+3, | ||
790 | addr, 4, flags); | ||
791 | |||
792 | if (!write_acked | ||
793 | && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK) | ||
794 | && (rcode >= 0)) { | ||
795 | /* not a broadcast write, reply */ | ||
796 | PREP_REPLY_PACKET(0); | ||
797 | fill_async_write_resp(packet, rcode); | ||
798 | send_packet_nocare(packet); | ||
799 | } | ||
800 | break; | ||
801 | |||
802 | case TCODE_WRITEB: | ||
803 | addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; | ||
804 | rcode = highlevel_write(host, source, dest, data+4, | ||
805 | addr, data[3]>>16, flags); | ||
806 | |||
807 | if (!write_acked | ||
808 | && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK) | ||
809 | && (rcode >= 0)) { | ||
810 | /* not a broadcast write, reply */ | ||
811 | PREP_REPLY_PACKET(0); | ||
812 | fill_async_write_resp(packet, rcode); | ||
813 | send_packet_nocare(packet); | ||
814 | } | ||
815 | break; | ||
816 | |||
817 | case TCODE_READQ: | ||
818 | addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; | ||
819 | rcode = highlevel_read(host, source, &buffer, addr, 4, flags); | ||
820 | |||
821 | if (rcode >= 0) { | ||
822 | PREP_REPLY_PACKET(0); | ||
823 | fill_async_readquad_resp(packet, rcode, buffer); | ||
824 | send_packet_nocare(packet); | ||
825 | } | ||
826 | break; | ||
827 | |||
828 | case TCODE_READB: | ||
829 | length = data[3] >> 16; | ||
830 | PREP_REPLY_PACKET(length); | ||
831 | |||
832 | addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; | ||
833 | rcode = highlevel_read(host, source, packet->data, addr, | ||
834 | length, flags); | ||
835 | |||
836 | if (rcode >= 0) { | ||
837 | fill_async_readblock_resp(packet, rcode, length); | ||
838 | send_packet_nocare(packet); | ||
839 | } else { | ||
840 | hpsb_free_packet(packet); | ||
841 | } | ||
842 | break; | ||
843 | |||
844 | case TCODE_LOCK_REQUEST: | ||
845 | length = data[3] >> 16; | ||
846 | extcode = data[3] & 0xffff; | ||
847 | addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; | ||
848 | |||
849 | PREP_REPLY_PACKET(8); | ||
850 | |||
851 | if ((extcode == 0) || (extcode >= 7)) { | ||
852 | /* let switch default handle error */ | ||
853 | length = 0; | ||
854 | } | ||
855 | |||
856 | switch (length) { | ||
857 | case 4: | ||
858 | rcode = highlevel_lock(host, source, packet->data, addr, | ||
859 | data[4], 0, extcode,flags); | ||
860 | fill_async_lock_resp(packet, rcode, extcode, 4); | ||
861 | break; | ||
862 | case 8: | ||
863 | if ((extcode != EXTCODE_FETCH_ADD) | ||
864 | && (extcode != EXTCODE_LITTLE_ADD)) { | ||
865 | rcode = highlevel_lock(host, source, | ||
866 | packet->data, addr, | ||
867 | data[5], data[4], | ||
868 | extcode, flags); | ||
869 | fill_async_lock_resp(packet, rcode, extcode, 4); | ||
870 | } else { | ||
871 | rcode = highlevel_lock64(host, source, | ||
872 | (octlet_t *)packet->data, addr, | ||
873 | *(octlet_t *)(data + 4), 0ULL, | ||
874 | extcode, flags); | ||
875 | fill_async_lock_resp(packet, rcode, extcode, 8); | ||
876 | } | ||
877 | break; | ||
878 | case 16: | ||
879 | rcode = highlevel_lock64(host, source, | ||
880 | (octlet_t *)packet->data, addr, | ||
881 | *(octlet_t *)(data + 6), | ||
882 | *(octlet_t *)(data + 4), | ||
883 | extcode, flags); | ||
884 | fill_async_lock_resp(packet, rcode, extcode, 8); | ||
885 | break; | ||
886 | default: | ||
887 | rcode = RCODE_TYPE_ERROR; | ||
888 | fill_async_lock_resp(packet, rcode, | ||
889 | extcode, 0); | ||
890 | } | ||
891 | |||
892 | if (rcode >= 0) { | ||
893 | send_packet_nocare(packet); | ||
894 | } else { | ||
895 | hpsb_free_packet(packet); | ||
896 | } | ||
897 | break; | ||
898 | } | ||
899 | |||
900 | } | ||
901 | #undef PREP_REPLY_PACKET | ||
902 | |||
903 | |||
904 | void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, | ||
905 | int write_acked) | ||
906 | { | ||
907 | int tcode; | ||
908 | |||
909 | if (host->in_bus_reset) { | ||
910 | HPSB_INFO("received packet during reset; ignoring"); | ||
911 | return; | ||
912 | } | ||
913 | |||
914 | dump_packet("received packet:", data, size); | ||
915 | |||
916 | tcode = (data[0] >> 4) & 0xf; | ||
917 | |||
918 | switch (tcode) { | ||
919 | case TCODE_WRITE_RESPONSE: | ||
920 | case TCODE_READQ_RESPONSE: | ||
921 | case TCODE_READB_RESPONSE: | ||
922 | case TCODE_LOCK_RESPONSE: | ||
923 | handle_packet_response(host, tcode, data, size); | ||
924 | break; | ||
925 | |||
926 | case TCODE_WRITEQ: | ||
927 | case TCODE_WRITEB: | ||
928 | case TCODE_READQ: | ||
929 | case TCODE_READB: | ||
930 | case TCODE_LOCK_REQUEST: | ||
931 | handle_incoming_packet(host, tcode, data, size, write_acked); | ||
932 | break; | ||
933 | |||
934 | |||
935 | case TCODE_ISO_DATA: | ||
936 | highlevel_iso_receive(host, data, size); | ||
937 | break; | ||
938 | |||
939 | case TCODE_CYCLE_START: | ||
940 | /* simply ignore this packet if it is passed on */ | ||
941 | break; | ||
942 | |||
943 | default: | ||
944 | HPSB_NOTICE("received packet with bogus transaction code %d", | ||
945 | tcode); | ||
946 | break; | ||
947 | } | ||
948 | } | ||
949 | |||
950 | |||
951 | static void abort_requests(struct hpsb_host *host) | ||
952 | { | ||
953 | struct hpsb_packet *packet; | ||
954 | struct sk_buff *skb; | ||
955 | |||
956 | host->driver->devctl(host, CANCEL_REQUESTS, 0); | ||
957 | |||
958 | while ((skb = skb_dequeue(&host->pending_packet_queue)) != NULL) { | ||
959 | packet = (struct hpsb_packet *)skb->data; | ||
960 | |||
961 | packet->state = hpsb_complete; | ||
962 | packet->ack_code = ACKX_ABORTED; | ||
963 | queue_packet_complete(packet); | ||
964 | } | ||
965 | } | ||
966 | |||
967 | void abort_timedouts(unsigned long __opaque) | ||
968 | { | ||
969 | struct hpsb_host *host = (struct hpsb_host *)__opaque; | ||
970 | unsigned long flags; | ||
971 | struct hpsb_packet *packet; | ||
972 | struct sk_buff *skb; | ||
973 | unsigned long expire; | ||
974 | |||
975 | spin_lock_irqsave(&host->csr.lock, flags); | ||
976 | expire = host->csr.expire; | ||
977 | spin_unlock_irqrestore(&host->csr.lock, flags); | ||
978 | |||
979 | /* Hold the lock around this, since we aren't dequeuing all | ||
980 | * packets, just ones we need. */ | ||
981 | spin_lock_irqsave(&host->pending_packet_queue.lock, flags); | ||
982 | |||
983 | while (!skb_queue_empty(&host->pending_packet_queue)) { | ||
984 | skb = skb_peek(&host->pending_packet_queue); | ||
985 | |||
986 | packet = (struct hpsb_packet *)skb->data; | ||
987 | |||
988 | if (time_before(packet->sendtime + expire, jiffies)) { | ||
989 | __skb_unlink(skb, skb->list); | ||
990 | packet->state = hpsb_complete; | ||
991 | packet->ack_code = ACKX_TIMEOUT; | ||
992 | queue_packet_complete(packet); | ||
993 | } else { | ||
994 | /* Since packets are added to the tail, the oldest | ||
995 | * ones are first, always. When we get to one that | ||
996 | * isn't timed out, the rest aren't either. */ | ||
997 | break; | ||
998 | } | ||
999 | } | ||
1000 | |||
1001 | if (!skb_queue_empty(&host->pending_packet_queue)) | ||
1002 | mod_timer(&host->timeout, jiffies + host->timeout_interval); | ||
1003 | |||
1004 | spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); | ||
1005 | } | ||
1006 | |||
1007 | |||
1008 | /* Kernel thread and vars, which handles packets that are completed. Only | ||
1009 | * packets that have a "complete" function are sent here. This way, the | ||
1010 | * completion is run out of kernel context, and doesn't block the rest of | ||
1011 | * the stack. */ | ||
1012 | static int khpsbpkt_pid = -1, khpsbpkt_kill; | ||
1013 | static DECLARE_COMPLETION(khpsbpkt_complete); | ||
1014 | static struct sk_buff_head hpsbpkt_queue; | ||
1015 | static DECLARE_MUTEX_LOCKED(khpsbpkt_sig); | ||
1016 | |||
1017 | |||
1018 | static void queue_packet_complete(struct hpsb_packet *packet) | ||
1019 | { | ||
1020 | if (packet->no_waiter) { | ||
1021 | hpsb_free_packet(packet); | ||
1022 | return; | ||
1023 | } | ||
1024 | if (packet->complete_routine != NULL) { | ||
1025 | skb_queue_tail(&hpsbpkt_queue, packet->skb); | ||
1026 | |||
1027 | /* Signal the kernel thread to handle this */ | ||
1028 | up(&khpsbpkt_sig); | ||
1029 | } | ||
1030 | return; | ||
1031 | } | ||
1032 | |||
1033 | static int hpsbpkt_thread(void *__hi) | ||
1034 | { | ||
1035 | struct sk_buff *skb; | ||
1036 | struct hpsb_packet *packet; | ||
1037 | void (*complete_routine)(void*); | ||
1038 | void *complete_data; | ||
1039 | |||
1040 | daemonize("khpsbpkt"); | ||
1041 | |||
1042 | while (1) { | ||
1043 | if (down_interruptible(&khpsbpkt_sig)) { | ||
1044 | if (current->flags & PF_FREEZE) { | ||
1045 | refrigerator(0); | ||
1046 | continue; | ||
1047 | } | ||
1048 | printk("khpsbpkt: received unexpected signal?!\n" ); | ||
1049 | break; | ||
1050 | } | ||
1051 | |||
1052 | if (khpsbpkt_kill) | ||
1053 | break; | ||
1054 | |||
1055 | while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { | ||
1056 | packet = (struct hpsb_packet *)skb->data; | ||
1057 | |||
1058 | complete_routine = packet->complete_routine; | ||
1059 | complete_data = packet->complete_data; | ||
1060 | |||
1061 | packet->complete_routine = packet->complete_data = NULL; | ||
1062 | |||
1063 | complete_routine(complete_data); | ||
1064 | } | ||
1065 | } | ||
1066 | |||
1067 | complete_and_exit(&khpsbpkt_complete, 0); | ||
1068 | } | ||
1069 | |||
1070 | static int __init ieee1394_init(void) | ||
1071 | { | ||
1072 | int i, ret; | ||
1073 | |||
1074 | skb_queue_head_init(&hpsbpkt_queue); | ||
1075 | |||
1076 | /* non-fatal error */ | ||
1077 | if (hpsb_init_config_roms()) { | ||
1078 | HPSB_ERR("Failed to initialize some config rom entries.\n"); | ||
1079 | HPSB_ERR("Some features may not be available\n"); | ||
1080 | } | ||
1081 | |||
1082 | khpsbpkt_pid = kernel_thread(hpsbpkt_thread, NULL, CLONE_KERNEL); | ||
1083 | if (khpsbpkt_pid < 0) { | ||
1084 | HPSB_ERR("Failed to start hpsbpkt thread!\n"); | ||
1085 | ret = -ENOMEM; | ||
1086 | goto exit_cleanup_config_roms; | ||
1087 | } | ||
1088 | |||
1089 | if (register_chrdev_region(IEEE1394_CORE_DEV, 256, "ieee1394")) { | ||
1090 | HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR); | ||
1091 | ret = -ENODEV; | ||
1092 | goto exit_release_kernel_thread; | ||
1093 | } | ||
1094 | |||
1095 | /* actually this is a non-fatal error */ | ||
1096 | ret = devfs_mk_dir("ieee1394"); | ||
1097 | if (ret < 0) { | ||
1098 | HPSB_ERR("unable to make devfs dir for device major %d!\n", IEEE1394_MAJOR); | ||
1099 | goto release_chrdev; | ||
1100 | } | ||
1101 | |||
1102 | ret = bus_register(&ieee1394_bus_type); | ||
1103 | if (ret < 0) { | ||
1104 | HPSB_INFO("bus register failed"); | ||
1105 | goto release_devfs; | ||
1106 | } | ||
1107 | |||
1108 | for (i = 0; fw_bus_attrs[i]; i++) { | ||
1109 | ret = bus_create_file(&ieee1394_bus_type, fw_bus_attrs[i]); | ||
1110 | if (ret < 0) { | ||
1111 | while (i >= 0) { | ||
1112 | bus_remove_file(&ieee1394_bus_type, | ||
1113 | fw_bus_attrs[i--]); | ||
1114 | } | ||
1115 | bus_unregister(&ieee1394_bus_type); | ||
1116 | goto release_devfs; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | ret = class_register(&hpsb_host_class); | ||
1121 | if (ret < 0) | ||
1122 | goto release_all_bus; | ||
1123 | |||
1124 | hpsb_protocol_class = class_simple_create(THIS_MODULE, "ieee1394_protocol"); | ||
1125 | if (IS_ERR(hpsb_protocol_class)) { | ||
1126 | ret = PTR_ERR(hpsb_protocol_class); | ||
1127 | goto release_class_host; | ||
1128 | } | ||
1129 | |||
1130 | ret = init_csr(); | ||
1131 | if (ret) { | ||
1132 | HPSB_INFO("init csr failed"); | ||
1133 | ret = -ENOMEM; | ||
1134 | goto release_class_protocol; | ||
1135 | } | ||
1136 | |||
1137 | if (disable_nodemgr) { | ||
1138 | HPSB_INFO("nodemgr and IRM functionality disabled"); | ||
1139 | /* We shouldn't contend for IRM with nodemgr disabled, since | ||
1140 | nodemgr implements functionality required of ieee1394a-2000 | ||
1141 | IRMs */ | ||
1142 | hpsb_disable_irm = 1; | ||
1143 | |||
1144 | return 0; | ||
1145 | } | ||
1146 | |||
1147 | if (hpsb_disable_irm) { | ||
1148 | HPSB_INFO("IRM functionality disabled"); | ||
1149 | } | ||
1150 | |||
1151 | ret = init_ieee1394_nodemgr(); | ||
1152 | if (ret < 0) { | ||
1153 | HPSB_INFO("init nodemgr failed"); | ||
1154 | goto cleanup_csr; | ||
1155 | } | ||
1156 | |||
1157 | return 0; | ||
1158 | |||
1159 | cleanup_csr: | ||
1160 | cleanup_csr(); | ||
1161 | release_class_protocol: | ||
1162 | class_simple_destroy(hpsb_protocol_class); | ||
1163 | release_class_host: | ||
1164 | class_unregister(&hpsb_host_class); | ||
1165 | release_all_bus: | ||
1166 | for (i = 0; fw_bus_attrs[i]; i++) | ||
1167 | bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); | ||
1168 | bus_unregister(&ieee1394_bus_type); | ||
1169 | release_devfs: | ||
1170 | devfs_remove("ieee1394"); | ||
1171 | release_chrdev: | ||
1172 | unregister_chrdev_region(IEEE1394_CORE_DEV, 256); | ||
1173 | exit_release_kernel_thread: | ||
1174 | if (khpsbpkt_pid >= 0) { | ||
1175 | kill_proc(khpsbpkt_pid, SIGTERM, 1); | ||
1176 | wait_for_completion(&khpsbpkt_complete); | ||
1177 | } | ||
1178 | exit_cleanup_config_roms: | ||
1179 | hpsb_cleanup_config_roms(); | ||
1180 | return ret; | ||
1181 | } | ||
1182 | |||
1183 | static void __exit ieee1394_cleanup(void) | ||
1184 | { | ||
1185 | int i; | ||
1186 | |||
1187 | if (!disable_nodemgr) | ||
1188 | cleanup_ieee1394_nodemgr(); | ||
1189 | |||
1190 | cleanup_csr(); | ||
1191 | |||
1192 | class_simple_destroy(hpsb_protocol_class); | ||
1193 | class_unregister(&hpsb_host_class); | ||
1194 | for (i = 0; fw_bus_attrs[i]; i++) | ||
1195 | bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); | ||
1196 | bus_unregister(&ieee1394_bus_type); | ||
1197 | |||
1198 | if (khpsbpkt_pid >= 0) { | ||
1199 | khpsbpkt_kill = 1; | ||
1200 | mb(); | ||
1201 | up(&khpsbpkt_sig); | ||
1202 | wait_for_completion(&khpsbpkt_complete); | ||
1203 | } | ||
1204 | |||
1205 | hpsb_cleanup_config_roms(); | ||
1206 | |||
1207 | unregister_chrdev_region(IEEE1394_CORE_DEV, 256); | ||
1208 | devfs_remove("ieee1394"); | ||
1209 | } | ||
1210 | |||
1211 | module_init(ieee1394_init); | ||
1212 | module_exit(ieee1394_cleanup); | ||
1213 | |||
1214 | /* Exported symbols */ | ||
1215 | |||
1216 | /** hosts.c **/ | ||
1217 | EXPORT_SYMBOL(hpsb_alloc_host); | ||
1218 | EXPORT_SYMBOL(hpsb_add_host); | ||
1219 | EXPORT_SYMBOL(hpsb_remove_host); | ||
1220 | EXPORT_SYMBOL(hpsb_update_config_rom_image); | ||
1221 | |||
1222 | /** ieee1394_core.c **/ | ||
1223 | EXPORT_SYMBOL(hpsb_speedto_str); | ||
1224 | EXPORT_SYMBOL(hpsb_protocol_class); | ||
1225 | EXPORT_SYMBOL(hpsb_set_packet_complete_task); | ||
1226 | EXPORT_SYMBOL(hpsb_alloc_packet); | ||
1227 | EXPORT_SYMBOL(hpsb_free_packet); | ||
1228 | EXPORT_SYMBOL(hpsb_send_phy_config); | ||
1229 | EXPORT_SYMBOL(hpsb_send_packet); | ||
1230 | EXPORT_SYMBOL(hpsb_send_packet_and_wait); | ||
1231 | EXPORT_SYMBOL(hpsb_reset_bus); | ||
1232 | EXPORT_SYMBOL(hpsb_bus_reset); | ||
1233 | EXPORT_SYMBOL(hpsb_selfid_received); | ||
1234 | EXPORT_SYMBOL(hpsb_selfid_complete); | ||
1235 | EXPORT_SYMBOL(hpsb_packet_sent); | ||
1236 | EXPORT_SYMBOL(hpsb_packet_received); | ||
1237 | EXPORT_SYMBOL_GPL(hpsb_disable_irm); | ||
1238 | |||
1239 | /** ieee1394_transactions.c **/ | ||
1240 | EXPORT_SYMBOL(hpsb_get_tlabel); | ||
1241 | EXPORT_SYMBOL(hpsb_free_tlabel); | ||
1242 | EXPORT_SYMBOL(hpsb_make_readpacket); | ||
1243 | EXPORT_SYMBOL(hpsb_make_writepacket); | ||
1244 | EXPORT_SYMBOL(hpsb_make_streampacket); | ||
1245 | EXPORT_SYMBOL(hpsb_make_lockpacket); | ||
1246 | EXPORT_SYMBOL(hpsb_make_lock64packet); | ||
1247 | EXPORT_SYMBOL(hpsb_make_phypacket); | ||
1248 | EXPORT_SYMBOL(hpsb_make_isopacket); | ||
1249 | EXPORT_SYMBOL(hpsb_read); | ||
1250 | EXPORT_SYMBOL(hpsb_write); | ||
1251 | EXPORT_SYMBOL(hpsb_lock); | ||
1252 | EXPORT_SYMBOL(hpsb_packet_success); | ||
1253 | |||
1254 | /** highlevel.c **/ | ||
1255 | EXPORT_SYMBOL(hpsb_register_highlevel); | ||
1256 | EXPORT_SYMBOL(hpsb_unregister_highlevel); | ||
1257 | EXPORT_SYMBOL(hpsb_register_addrspace); | ||
1258 | EXPORT_SYMBOL(hpsb_unregister_addrspace); | ||
1259 | EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace); | ||
1260 | EXPORT_SYMBOL(hpsb_listen_channel); | ||
1261 | EXPORT_SYMBOL(hpsb_unlisten_channel); | ||
1262 | EXPORT_SYMBOL(hpsb_get_hostinfo); | ||
1263 | EXPORT_SYMBOL(hpsb_create_hostinfo); | ||
1264 | EXPORT_SYMBOL(hpsb_destroy_hostinfo); | ||
1265 | EXPORT_SYMBOL(hpsb_set_hostinfo_key); | ||
1266 | EXPORT_SYMBOL(hpsb_get_hostinfo_bykey); | ||
1267 | EXPORT_SYMBOL(hpsb_set_hostinfo); | ||
1268 | EXPORT_SYMBOL(highlevel_add_host); | ||
1269 | EXPORT_SYMBOL(highlevel_remove_host); | ||
1270 | EXPORT_SYMBOL(highlevel_host_reset); | ||
1271 | |||
1272 | /** nodemgr.c **/ | ||
1273 | EXPORT_SYMBOL(hpsb_node_fill_packet); | ||
1274 | EXPORT_SYMBOL(hpsb_node_write); | ||
1275 | EXPORT_SYMBOL(hpsb_register_protocol); | ||
1276 | EXPORT_SYMBOL(hpsb_unregister_protocol); | ||
1277 | EXPORT_SYMBOL(ieee1394_bus_type); | ||
1278 | EXPORT_SYMBOL(nodemgr_for_each_host); | ||
1279 | |||
1280 | /** csr.c **/ | ||
1281 | EXPORT_SYMBOL(hpsb_update_config_rom); | ||
1282 | |||
1283 | /** dma.c **/ | ||
1284 | EXPORT_SYMBOL(dma_prog_region_init); | ||
1285 | EXPORT_SYMBOL(dma_prog_region_alloc); | ||
1286 | EXPORT_SYMBOL(dma_prog_region_free); | ||
1287 | EXPORT_SYMBOL(dma_region_init); | ||
1288 | EXPORT_SYMBOL(dma_region_alloc); | ||
1289 | EXPORT_SYMBOL(dma_region_free); | ||
1290 | EXPORT_SYMBOL(dma_region_sync_for_cpu); | ||
1291 | EXPORT_SYMBOL(dma_region_sync_for_device); | ||
1292 | EXPORT_SYMBOL(dma_region_mmap); | ||
1293 | EXPORT_SYMBOL(dma_region_offset_to_bus); | ||
1294 | |||
1295 | /** iso.c **/ | ||
1296 | EXPORT_SYMBOL(hpsb_iso_xmit_init); | ||
1297 | EXPORT_SYMBOL(hpsb_iso_recv_init); | ||
1298 | EXPORT_SYMBOL(hpsb_iso_xmit_start); | ||
1299 | EXPORT_SYMBOL(hpsb_iso_recv_start); | ||
1300 | EXPORT_SYMBOL(hpsb_iso_recv_listen_channel); | ||
1301 | EXPORT_SYMBOL(hpsb_iso_recv_unlisten_channel); | ||
1302 | EXPORT_SYMBOL(hpsb_iso_recv_set_channel_mask); | ||
1303 | EXPORT_SYMBOL(hpsb_iso_stop); | ||
1304 | EXPORT_SYMBOL(hpsb_iso_shutdown); | ||
1305 | EXPORT_SYMBOL(hpsb_iso_xmit_queue_packet); | ||
1306 | EXPORT_SYMBOL(hpsb_iso_xmit_sync); | ||
1307 | EXPORT_SYMBOL(hpsb_iso_recv_release_packets); | ||
1308 | EXPORT_SYMBOL(hpsb_iso_n_ready); | ||
1309 | EXPORT_SYMBOL(hpsb_iso_packet_sent); | ||
1310 | EXPORT_SYMBOL(hpsb_iso_packet_received); | ||
1311 | EXPORT_SYMBOL(hpsb_iso_wake); | ||
1312 | EXPORT_SYMBOL(hpsb_iso_recv_flush); | ||
1313 | |||
1314 | /** csr1212.c **/ | ||
1315 | EXPORT_SYMBOL(csr1212_create_csr); | ||
1316 | EXPORT_SYMBOL(csr1212_init_local_csr); | ||
1317 | EXPORT_SYMBOL(csr1212_new_immediate); | ||
1318 | EXPORT_SYMBOL(csr1212_new_directory); | ||
1319 | EXPORT_SYMBOL(csr1212_associate_keyval); | ||
1320 | EXPORT_SYMBOL(csr1212_attach_keyval_to_directory); | ||
1321 | EXPORT_SYMBOL(csr1212_new_string_descriptor_leaf); | ||
1322 | EXPORT_SYMBOL(csr1212_detach_keyval_from_directory); | ||
1323 | EXPORT_SYMBOL(csr1212_release_keyval); | ||
1324 | EXPORT_SYMBOL(csr1212_destroy_csr); | ||
1325 | EXPORT_SYMBOL(csr1212_read); | ||
1326 | EXPORT_SYMBOL(csr1212_generate_csr_image); | ||
1327 | EXPORT_SYMBOL(csr1212_parse_keyval); | ||
1328 | EXPORT_SYMBOL(csr1212_parse_csr); | ||
1329 | EXPORT_SYMBOL(_csr1212_read_keyval); | ||
1330 | EXPORT_SYMBOL(_csr1212_destroy_keyval); | ||