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