aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-card.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2006-12-19 19:58:31 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-03-09 16:02:33 -0500
commit19a15b937b26638933307bb02f7b1801310d6eb2 (patch)
tree817efaa8c1d2f4633fa811ba27fa1aee7f00c352 /drivers/firewire/fw-card.c
parent3038e353cfaf548eb94f02b172b9dbe412abd24c (diff)
firewire: Add device probing and sysfs integration.
Signed-off-by: Kristian Høgsberg <krh@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-card.c')
-rw-r--r--drivers/firewire/fw-card.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index d8abd70ce843..79773907e10d 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -24,6 +24,7 @@
24#include <linux/device.h> 24#include <linux/device.h>
25#include "fw-transaction.h" 25#include "fw-transaction.h"
26#include "fw-topology.h" 26#include "fw-topology.h"
27#include "fw-device.h"
27 28
28/* The lib/crc16.c implementation uses the standard (0x8005) 29/* The lib/crc16.c implementation uses the standard (0x8005)
29 * polynomial, but we need the ITU-T (or CCITT) polynomial (0x1021). 30 * polynomial, but we need the ITU-T (or CCITT) polynomial (0x1021).
@@ -186,6 +187,59 @@ fw_core_remove_descriptor (struct fw_descriptor *desc)
186EXPORT_SYMBOL(fw_core_remove_descriptor); 187EXPORT_SYMBOL(fw_core_remove_descriptor);
187 188
188static void 189static void
190fw_card_irm_work(struct work_struct *work)
191{
192 struct fw_card *card =
193 container_of(work, struct fw_card, work.work);
194 struct fw_device *root;
195 unsigned long flags;
196 int new_irm_id, generation;
197
198 /* FIXME: This simple bus management unconditionally picks a
199 * cycle master if the current root can't do it. We need to
200 * not do this if there is a bus manager already. Also, some
201 * hubs set the contender bit, which is bogus, so we should
202 * probably do a little sanity check on the IRM (like, read
203 * the bandwidth register) if it's not us. */
204
205 spin_lock_irqsave(&card->lock, flags);
206
207 generation = card->generation;
208 root = card->root_node->data;
209
210 if (root == NULL)
211 /* Either link_on is false, or we failed to read the
212 * config rom. In either case, pick another root. */
213 new_irm_id = card->local_node->node_id;
214 else if (root->state != FW_DEVICE_RUNNING)
215 /* If we haven't probed this device yet, bail out now
216 * and let's try again once that's done. */
217 new_irm_id = -1;
218 else if (root->config_rom[2] & bib_cmc)
219 /* FIXME: I suppose we should set the cmstr bit in the
220 * STATE_CLEAR register of this node, as described in
221 * 1394-1995, 8.4.2.6. Also, send out a force root
222 * packet for this node. */
223 new_irm_id = -1;
224 else
225 /* Current root has an active link layer and we
226 * successfully read the config rom, but it's not
227 * cycle master capable. */
228 new_irm_id = card->local_node->node_id;
229
230 if (card->irm_retries++ > 5)
231 new_irm_id = -1;
232
233 spin_unlock_irqrestore(&card->lock, flags);
234
235 if (new_irm_id > 0) {
236 fw_notify("Trying to become root (card %d)\n", card->index);
237 fw_send_force_root(card, new_irm_id, generation);
238 fw_core_initiate_bus_reset(card, 1);
239 }
240}
241
242static void
189release_card(struct device *device) 243release_card(struct device *device)
190{ 244{
191 struct fw_card *card = 245 struct fw_card *card =
@@ -222,6 +276,8 @@ fw_card_initialize(struct fw_card *card, struct fw_card_driver *driver,
222 276
223 card->local_node = NULL; 277 card->local_node = NULL;
224 278
279 INIT_DELAYED_WORK(&card->work, fw_card_irm_work);
280
225 card->card_device.bus = &fw_bus_type; 281 card->card_device.bus = &fw_bus_type;
226 card->card_device.release = release_card; 282 card->card_device.release = release_card;
227 card->card_device.parent = card->device; 283 card->card_device.parent = card->device;