firewire: Clean up comment style.
Drop filenames from file preamble, drop editor annotations and use standard indent style for block comments. Signed-off-by: Kristian Hoegsberg <krh@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (fixed typo)
This commit is contained in:
parent
e175569c46
commit
c781c06d11
|
@ -1,8 +1,5 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
*
|
||||
* fw-card.c - card level functions
|
||||
*
|
||||
* Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -69,12 +66,14 @@ generate_config_rom (struct fw_card *card, size_t *config_rom_length)
|
|||
static u32 config_rom[256];
|
||||
int i, j, length;
|
||||
|
||||
/* Initialize contents of config rom buffer. On the OHCI
|
||||
/*
|
||||
* Initialize contents of config rom buffer. On the OHCI
|
||||
* controller, block reads to the config rom accesses the host
|
||||
* memory, but quadlet read access the hardware bus info block
|
||||
* registers. That's just crack, but it means we should make
|
||||
* sure the contents of bus info block in host memory mathces
|
||||
* the version stored in the OHCI registers. */
|
||||
* the version stored in the OHCI registers.
|
||||
*/
|
||||
|
||||
memset(config_rom, 0, sizeof config_rom);
|
||||
config_rom[0] = bib_crc_length(4) | bib_info_length(4) | bib_crc(0);
|
||||
|
@ -143,9 +142,11 @@ fw_core_add_descriptor (struct fw_descriptor *desc)
|
|||
{
|
||||
size_t i;
|
||||
|
||||
/* Check descriptor is valid; the length of all blocks in the
|
||||
/*
|
||||
* Check descriptor is valid; the length of all blocks in the
|
||||
* descriptor has to add up to exactly the length of the
|
||||
* block. */
|
||||
* block.
|
||||
*/
|
||||
i = 0;
|
||||
while (i < desc->length)
|
||||
i += (desc->data[i] >> 16) + 1;
|
||||
|
@ -228,7 +229,8 @@ fw_card_bm_work(struct work_struct *work)
|
|||
|
||||
if (card->bm_generation + 1 == generation ||
|
||||
(card->bm_generation != generation && grace)) {
|
||||
/* This first step is to figure out who is IRM and
|
||||
/*
|
||||
* This first step is to figure out who is IRM and
|
||||
* then try to become bus manager. If the IRM is not
|
||||
* well defined (e.g. does not have an active link
|
||||
* layer or does not responds to our lock request, we
|
||||
|
@ -236,7 +238,8 @@ fw_card_bm_work(struct work_struct *work)
|
|||
* In that case, we do a goto into the gap count logic
|
||||
* so that when we do the reset, we still optimize the
|
||||
* gap count. That could well save a reset in the
|
||||
* next generation. */
|
||||
* next generation.
|
||||
*/
|
||||
|
||||
irm_id = card->irm_node->node_id;
|
||||
if (!card->irm_node->link_on) {
|
||||
|
@ -260,8 +263,10 @@ fw_card_bm_work(struct work_struct *work)
|
|||
wait_for_completion(&bmd.done);
|
||||
|
||||
if (bmd.rcode == RCODE_GENERATION) {
|
||||
/* Another bus reset happened. Just return,
|
||||
* the BM work has been rescheduled. */
|
||||
/*
|
||||
* Another bus reset happened. Just return,
|
||||
* the BM work has been rescheduled.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -271,48 +276,62 @@ fw_card_bm_work(struct work_struct *work)
|
|||
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
if (bmd.rcode != RCODE_COMPLETE) {
|
||||
/* The lock request failed, maybe the IRM
|
||||
/*
|
||||
* The lock request failed, maybe the IRM
|
||||
* isn't really IRM capable after all. Let's
|
||||
* do a bus reset and pick the local node as
|
||||
* root, and thus, IRM. */
|
||||
* root, and thus, IRM.
|
||||
*/
|
||||
new_root_id = card->local_node->node_id;
|
||||
fw_notify("BM lock failed, making local node (%02x) root.\n",
|
||||
new_root_id);
|
||||
goto pick_me;
|
||||
}
|
||||
} else if (card->bm_generation != generation) {
|
||||
/* OK, we weren't BM in the last generation, and it's
|
||||
/*
|
||||
* OK, we weren't BM in the last generation, and it's
|
||||
* less than 100ms since last bus reset. Reschedule
|
||||
* this task 100ms from now. */
|
||||
* this task 100ms from now.
|
||||
*/
|
||||
spin_unlock_irqrestore(&card->lock, flags);
|
||||
schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10));
|
||||
return;
|
||||
}
|
||||
|
||||
/* We're bus manager for this generation, so next step is to
|
||||
/*
|
||||
* We're bus manager for this generation, so next step is to
|
||||
* make sure we have an active cycle master and do gap count
|
||||
* optimization. */
|
||||
* optimization.
|
||||
*/
|
||||
card->bm_generation = generation;
|
||||
|
||||
if (root == NULL) {
|
||||
/* Either link_on is false, or we failed to read the
|
||||
* config rom. In either case, pick another root. */
|
||||
/*
|
||||
* Either link_on is false, or we failed to read the
|
||||
* config rom. In either case, pick another root.
|
||||
*/
|
||||
new_root_id = card->local_node->node_id;
|
||||
} else if (atomic_read(&root->state) != FW_DEVICE_RUNNING) {
|
||||
/* If we haven't probed this device yet, bail out now
|
||||
* and let's try again once that's done. */
|
||||
/*
|
||||
* If we haven't probed this device yet, bail out now
|
||||
* and let's try again once that's done.
|
||||
*/
|
||||
spin_unlock_irqrestore(&card->lock, flags);
|
||||
return;
|
||||
} else if (root->config_rom[2] & bib_cmc) {
|
||||
/* FIXME: I suppose we should set the cmstr bit in the
|
||||
/*
|
||||
* FIXME: I suppose we should set the cmstr bit in the
|
||||
* STATE_CLEAR register of this node, as described in
|
||||
* 1394-1995, 8.4.2.6. Also, send out a force root
|
||||
* packet for this node. */
|
||||
* packet for this node.
|
||||
*/
|
||||
new_root_id = root_id;
|
||||
} else {
|
||||
/* Current root has an active link layer and we
|
||||
/*
|
||||
* Current root has an active link layer and we
|
||||
* successfully read the config rom, but it's not
|
||||
* cycle master capable. */
|
||||
* cycle master capable.
|
||||
*/
|
||||
new_root_id = card->local_node->node_id;
|
||||
}
|
||||
|
||||
|
@ -324,9 +343,11 @@ fw_card_bm_work(struct work_struct *work)
|
|||
else
|
||||
gap_count = 63;
|
||||
|
||||
/* Finally, figure out if we should do a reset or not. If we've
|
||||
/*
|
||||
* Finally, figure out if we should do a reset or not. If we've
|
||||
* done less that 5 resets with the same physical topology and we
|
||||
* have either a new root or a new gap count setting, let's do it. */
|
||||
* have either a new root or a new gap count setting, let's do it.
|
||||
*/
|
||||
|
||||
if (card->bm_retries++ < 5 &&
|
||||
(card->gap_count != gap_count || new_root_id != root_id))
|
||||
|
@ -391,8 +412,10 @@ fw_card_add(struct fw_card *card,
|
|||
PHY_LINK_ACTIVE | PHY_CONTENDER) < 0)
|
||||
return -EIO;
|
||||
|
||||
/* The subsystem grabs a reference when the card is added and
|
||||
* drops it when the driver calls fw_core_remove_card. */
|
||||
/*
|
||||
* The subsystem grabs a reference when the card is added and
|
||||
* drops it when the driver calls fw_core_remove_card.
|
||||
*/
|
||||
fw_card_get(card);
|
||||
|
||||
down_write(&card_rwsem);
|
||||
|
@ -405,11 +428,13 @@ fw_card_add(struct fw_card *card,
|
|||
EXPORT_SYMBOL(fw_card_add);
|
||||
|
||||
|
||||
/* The next few functions implements a dummy driver that use once a
|
||||
/*
|
||||
* The next few functions implements a dummy driver that use once a
|
||||
* card driver shuts down an fw_card. This allows the driver to
|
||||
* cleanly unload, as all IO to the card will be handled by the dummy
|
||||
* driver instead of calling into the (possibly) unloaded module. The
|
||||
* dummy driver just fails all IO. */
|
||||
* dummy driver just fails all IO.
|
||||
*/
|
||||
|
||||
static int
|
||||
dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
|
||||
|
@ -429,8 +454,10 @@ static int
|
|||
dummy_set_config_rom(struct fw_card *card,
|
||||
u32 *config_rom, size_t length)
|
||||
{
|
||||
/* We take the card out of card_list before setting the dummy
|
||||
* driver, so this should never get called. */
|
||||
/*
|
||||
* We take the card out of card_list before setting the dummy
|
||||
* driver, so this should never get called.
|
||||
*/
|
||||
BUG();
|
||||
return -1;
|
||||
}
|
||||
|
@ -510,9 +537,11 @@ release_card(struct kref *kref)
|
|||
kfree(card);
|
||||
}
|
||||
|
||||
/* An assumption for fw_card_put() is that the card driver allocates
|
||||
/*
|
||||
* An assumption for fw_card_put() is that the card driver allocates
|
||||
* the fw_card struct with kalloc and that it has been shut down
|
||||
* before the last ref is dropped. */
|
||||
* before the last ref is dropped.
|
||||
*/
|
||||
void
|
||||
fw_card_put(struct fw_card *card)
|
||||
{
|
||||
|
@ -524,8 +553,6 @@ int
|
|||
fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
|
||||
{
|
||||
int reg = short_reset ? 5 : 1;
|
||||
/* The following values happen to be the same bit. However be
|
||||
* explicit for clarity. */
|
||||
int bit = short_reset ? PHY_BUS_SHORT_RESET : PHY_BUS_RESET;
|
||||
|
||||
return card->driver->update_phy_reg(card, reg, 0, bit);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
/*
|
||||
* Char device for device raw access
|
||||
*
|
||||
* fw-device-cdev.c - Char device for device raw access
|
||||
*
|
||||
* Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
* Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -36,9 +35,6 @@
|
|||
#include "fw-topology.h"
|
||||
#include "fw-device.h"
|
||||
|
||||
/* dequeue_event() just kfree()'s the event, so the event has to be
|
||||
* the first field in the struct. */
|
||||
|
||||
struct client;
|
||||
struct client_resource {
|
||||
struct list_head link;
|
||||
|
@ -46,6 +42,11 @@ struct client_resource {
|
|||
u32 handle;
|
||||
};
|
||||
|
||||
/*
|
||||
* dequeue_event() just kfree()'s the event, so the event has to be
|
||||
* the first field in the struct.
|
||||
*/
|
||||
|
||||
struct event {
|
||||
struct { void *data; size_t size; } v[2];
|
||||
struct list_head link;
|
||||
|
@ -691,13 +692,15 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
|
|||
if (ctx == NULL || request->handle != 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* If the user passes a non-NULL data pointer, has mmap()'ed
|
||||
/*
|
||||
* If the user passes a non-NULL data pointer, has mmap()'ed
|
||||
* the iso buffer, and the pointer points inside the buffer,
|
||||
* we setup the payload pointers accordingly. Otherwise we
|
||||
* set them both to 0, which will still let packets with
|
||||
* payload_length == 0 through. In other words, if no packets
|
||||
* use the indirect payload, the iso buffer need not be mapped
|
||||
* and the request->data pointer is ignored.*/
|
||||
* and the request->data pointer is ignored.
|
||||
*/
|
||||
|
||||
payload = (unsigned long)request->data - client->vm_start;
|
||||
buffer_end = client->buffer.page_count << PAGE_SHIFT;
|
||||
|
@ -720,8 +723,10 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
|
|||
if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
|
||||
header_length = u.packet.header_length;
|
||||
} else {
|
||||
/* We require that header_length is a multiple of
|
||||
* the fixed header size, ctx->header_size */
|
||||
/*
|
||||
* We require that header_length is a multiple of
|
||||
* the fixed header size, ctx->header_size.
|
||||
*/
|
||||
if (ctx->header_size == 0) {
|
||||
if (u.packet.header_length > 0)
|
||||
return -EINVAL;
|
||||
|
@ -908,8 +913,10 @@ static int fw_device_op_release(struct inode *inode, struct file *file)
|
|||
list_for_each_entry_safe(r, next_r, &client->resource_list, link)
|
||||
r->release(client, r);
|
||||
|
||||
/* FIXME: We should wait for the async tasklets to stop
|
||||
* running before freeing the memory. */
|
||||
/*
|
||||
* FIXME: We should wait for the async tasklets to stop
|
||||
* running before freeing the memory.
|
||||
*/
|
||||
|
||||
list_for_each_entry_safe(e, next_e, &client->event_list, link)
|
||||
kfree(e);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
*
|
||||
* fw-device.c - Device probing and sysfs code.
|
||||
/*
|
||||
* Device probing and sysfs code.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
|
@ -174,8 +173,10 @@ static void fw_device_release(struct device *dev)
|
|||
struct fw_device *device = fw_device(dev);
|
||||
unsigned long flags;
|
||||
|
||||
/* Take the card lock so we don't set this to NULL while a
|
||||
* FW_NODE_UPDATED callback is being handled. */
|
||||
/*
|
||||
* Take the card lock so we don't set this to NULL while a
|
||||
* FW_NODE_UPDATED callback is being handled.
|
||||
*/
|
||||
spin_lock_irqsave(&device->card->lock, flags);
|
||||
device->node->data = NULL;
|
||||
spin_unlock_irqrestore(&device->card->lock, flags);
|
||||
|
@ -421,34 +422,42 @@ static int read_bus_info_block(struct fw_device *device)
|
|||
for (i = 0; i < 5; i++) {
|
||||
if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE)
|
||||
return -1;
|
||||
/* As per IEEE1212 7.2, during power-up, devices can
|
||||
/*
|
||||
* As per IEEE1212 7.2, during power-up, devices can
|
||||
* reply with a 0 for the first quadlet of the config
|
||||
* rom to indicate that they are booting (for example,
|
||||
* if the firmware is on the disk of a external
|
||||
* harddisk). In that case we just fail, and the
|
||||
* retry mechanism will try again later. */
|
||||
* retry mechanism will try again later.
|
||||
*/
|
||||
if (i == 0 && rom[i] == 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now parse the config rom. The config rom is a recursive
|
||||
/*
|
||||
* Now parse the config rom. The config rom is a recursive
|
||||
* directory structure so we parse it using a stack of
|
||||
* references to the blocks that make up the structure. We
|
||||
* push a reference to the root directory on the stack to
|
||||
* start things off. */
|
||||
* start things off.
|
||||
*/
|
||||
length = i;
|
||||
sp = 0;
|
||||
stack[sp++] = 0xc0000005;
|
||||
while (sp > 0) {
|
||||
/* Pop the next block reference of the stack. The
|
||||
/*
|
||||
* Pop the next block reference of the stack. The
|
||||
* lower 24 bits is the offset into the config rom,
|
||||
* the upper 8 bits are the type of the reference the
|
||||
* block. */
|
||||
* block.
|
||||
*/
|
||||
key = stack[--sp];
|
||||
i = key & 0xffffff;
|
||||
if (i >= ARRAY_SIZE(rom))
|
||||
/* The reference points outside the standard
|
||||
* config rom area, something's fishy. */
|
||||
/*
|
||||
* The reference points outside the standard
|
||||
* config rom area, something's fishy.
|
||||
*/
|
||||
return -1;
|
||||
|
||||
/* Read header quadlet for the block to get the length. */
|
||||
|
@ -457,15 +466,19 @@ static int read_bus_info_block(struct fw_device *device)
|
|||
end = i + (rom[i] >> 16) + 1;
|
||||
i++;
|
||||
if (end > ARRAY_SIZE(rom))
|
||||
/* This block extends outside standard config
|
||||
/*
|
||||
* This block extends outside standard config
|
||||
* area (and the array we're reading it
|
||||
* into). That's broken, so ignore this
|
||||
* device. */
|
||||
* device.
|
||||
*/
|
||||
return -1;
|
||||
|
||||
/* Now read in the block. If this is a directory
|
||||
/*
|
||||
* Now read in the block. If this is a directory
|
||||
* block, check the entries as we read them to see if
|
||||
* it references another block, and push it in that case. */
|
||||
* it references another block, and push it in that case.
|
||||
*/
|
||||
while (i < end) {
|
||||
if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE)
|
||||
return -1;
|
||||
|
@ -516,8 +529,10 @@ static void create_units(struct fw_device *device)
|
|||
if (key != (CSR_UNIT | CSR_DIRECTORY))
|
||||
continue;
|
||||
|
||||
/* Get the address of the unit directory and try to
|
||||
* match the drivers id_tables against it. */
|
||||
/*
|
||||
* Get the address of the unit directory and try to
|
||||
* match the drivers id_tables against it.
|
||||
*/
|
||||
unit = kzalloc(sizeof *unit, GFP_KERNEL);
|
||||
if (unit == NULL) {
|
||||
fw_error("failed to allocate memory for unit\n");
|
||||
|
@ -585,14 +600,16 @@ static struct device_type fw_device_type = {
|
|||
.release = fw_device_release,
|
||||
};
|
||||
|
||||
/* These defines control the retry behavior for reading the config
|
||||
/*
|
||||
* These defines control the retry behavior for reading the config
|
||||
* rom. It shouldn't be necessary to tweak these; if the device
|
||||
* doesn't respond to a config rom read within 10 seconds, it's not
|
||||
* going to respond at all. As for the initial delay, a lot of
|
||||
* devices will be able to respond within half a second after bus
|
||||
* reset. On the other hand, it's not really worth being more
|
||||
* aggressive than that, since it scales pretty well; if 10 devices
|
||||
* are plugged in, they're all getting read within one second. */
|
||||
* are plugged in, they're all getting read within one second.
|
||||
*/
|
||||
|
||||
#define MAX_RETRIES 10
|
||||
#define RETRY_DELAY (3 * HZ)
|
||||
|
@ -604,9 +621,11 @@ static void fw_device_init(struct work_struct *work)
|
|||
container_of(work, struct fw_device, work.work);
|
||||
int minor, err;
|
||||
|
||||
/* All failure paths here set node->data to NULL, so that we
|
||||
/*
|
||||
* All failure paths here set node->data to NULL, so that we
|
||||
* don't try to do device_for_each_child() on a kfree()'d
|
||||
* device. */
|
||||
* device.
|
||||
*/
|
||||
|
||||
if (read_bus_info_block(device) < 0) {
|
||||
if (device->config_rom_retries < MAX_RETRIES) {
|
||||
|
@ -647,13 +666,15 @@ static void fw_device_init(struct work_struct *work)
|
|||
|
||||
create_units(device);
|
||||
|
||||
/* Transition the device to running state. If it got pulled
|
||||
/*
|
||||
* Transition the device to running state. If it got pulled
|
||||
* out from under us while we did the intialization work, we
|
||||
* have to shut down the device again here. Normally, though,
|
||||
* fw_node_event will be responsible for shutting it down when
|
||||
* necessary. We have to use the atomic cmpxchg here to avoid
|
||||
* racing with the FW_NODE_DESTROYED case in
|
||||
* fw_node_event(). */
|
||||
* fw_node_event().
|
||||
*/
|
||||
if (atomic_cmpxchg(&device->state,
|
||||
FW_DEVICE_INITIALIZING,
|
||||
FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
|
||||
|
@ -662,10 +683,12 @@ static void fw_device_init(struct work_struct *work)
|
|||
fw_notify("created new fw device %s (%d config rom retries)\n",
|
||||
device->device.bus_id, device->config_rom_retries);
|
||||
|
||||
/* Reschedule the IRM work if we just finished reading the
|
||||
/*
|
||||
* Reschedule the IRM work if we just finished reading the
|
||||
* root node config rom. If this races with a bus reset we
|
||||
* just end up running the IRM work a couple of extra times -
|
||||
* pretty harmless. */
|
||||
* pretty harmless.
|
||||
*/
|
||||
if (device->node == device->card->root_node)
|
||||
schedule_delayed_work(&device->card->work, 0);
|
||||
|
||||
|
@ -716,12 +739,14 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
|
|||
if (device == NULL)
|
||||
break;
|
||||
|
||||
/* Do minimal intialization of the device here, the
|
||||
/*
|
||||
* Do minimal intialization of the device here, the
|
||||
* rest will happen in fw_device_init(). We need the
|
||||
* card and node so we can read the config rom and we
|
||||
* need to do device_initialize() now so
|
||||
* device_for_each_child() in FW_NODE_UPDATED is
|
||||
* doesn't freak out. */
|
||||
* doesn't freak out.
|
||||
*/
|
||||
device_initialize(&device->device);
|
||||
atomic_set(&device->state, FW_DEVICE_INITIALIZING);
|
||||
device->card = fw_card_get(card);
|
||||
|
@ -730,15 +755,19 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
|
|||
device->generation = card->generation;
|
||||
INIT_LIST_HEAD(&device->client_list);
|
||||
|
||||
/* Set the node data to point back to this device so
|
||||
/*
|
||||
* Set the node data to point back to this device so
|
||||
* FW_NODE_UPDATED callbacks can update the node_id
|
||||
* and generation for the device. */
|
||||
* and generation for the device.
|
||||
*/
|
||||
node->data = device;
|
||||
|
||||
/* Many devices are slow to respond after bus resets,
|
||||
/*
|
||||
* Many devices are slow to respond after bus resets,
|
||||
* especially if they are bus powered and go through
|
||||
* power-up after getting plugged in. We schedule the
|
||||
* first config rom scan half a second after bus reset. */
|
||||
* first config rom scan half a second after bus reset.
|
||||
*/
|
||||
INIT_DELAYED_WORK(&device->work, fw_device_init);
|
||||
schedule_delayed_work(&device->work, INITIAL_DELAY);
|
||||
break;
|
||||
|
@ -761,7 +790,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
|
|||
if (!node->data)
|
||||
break;
|
||||
|
||||
/* Destroy the device associated with the node. There
|
||||
/*
|
||||
* Destroy the device associated with the node. There
|
||||
* are two cases here: either the device is fully
|
||||
* initialized (FW_DEVICE_RUNNING) or we're in the
|
||||
* process of reading its config rom
|
||||
|
@ -770,7 +800,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
|
|||
* full fw_device_shutdown(). If not, there's work
|
||||
* scheduled to read it's config rom, and we just put
|
||||
* the device in shutdown state to have that code fail
|
||||
* to create the device. */
|
||||
* to create the device.
|
||||
*/
|
||||
device = node->data;
|
||||
if (atomic_xchg(&device->state,
|
||||
FW_DEVICE_SHUTDOWN) == FW_DEVICE_RUNNING) {
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
*
|
||||
* fw-device.h - Device probing and sysfs code.
|
||||
*
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
/*
|
||||
* Isochronous IO functionality
|
||||
*
|
||||
* fw-iso.c - Isochronous IO
|
||||
* Copyright (C) 2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
/*
|
||||
* Driver for OHCI 1394 controllers
|
||||
*
|
||||
* fw-ohci.c - Driver for OHCI 1394 boards
|
||||
* Copyright (C) 2003-2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -141,8 +141,10 @@ struct fw_ohci {
|
|||
int request_generation;
|
||||
u32 bus_seconds;
|
||||
|
||||
/* Spinlock for accessing fw_ohci data. Never call out of
|
||||
* this driver with this lock held. */
|
||||
/*
|
||||
* Spinlock for accessing fw_ohci data. Never call out of
|
||||
* this driver with this lock held.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
u32 self_id_buffer[512];
|
||||
|
||||
|
@ -328,13 +330,15 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
|
|||
p.timestamp = status & 0xffff;
|
||||
p.generation = ohci->request_generation;
|
||||
|
||||
/* The OHCI bus reset handler synthesizes a phy packet with
|
||||
/*
|
||||
* The OHCI bus reset handler synthesizes a phy packet with
|
||||
* the new generation number when a bus reset happens (see
|
||||
* section 8.4.2.3). This helps us determine when a request
|
||||
* was received and make sure we send the response in the same
|
||||
* generation. We only need this for requests; for responses
|
||||
* we use the unique tlabel for finding the matching
|
||||
* request. */
|
||||
* request.
|
||||
*/
|
||||
|
||||
if (p.ack + 16 == 0x09)
|
||||
ohci->request_generation = (buffer[2] >> 16) & 0xff;
|
||||
|
@ -360,9 +364,11 @@ static void ar_context_tasklet(unsigned long data)
|
|||
if (d->res_count == 0) {
|
||||
size_t size, rest, offset;
|
||||
|
||||
/* This descriptor is finished and we may have a
|
||||
/*
|
||||
* This descriptor is finished and we may have a
|
||||
* packet split across this and the next buffer. We
|
||||
* reuse the page for reassembling the split packet. */
|
||||
* reuse the page for reassembling the split packet.
|
||||
*/
|
||||
|
||||
offset = offsetof(struct ar_buffer, data);
|
||||
dma_unmap_single(ohci->card.device,
|
||||
|
@ -473,11 +479,13 @@ context_init(struct context *ctx, struct fw_ohci *ohci,
|
|||
ctx->tail_descriptor = ctx->buffer;
|
||||
ctx->tail_descriptor_last = ctx->buffer;
|
||||
|
||||
/* We put a dummy descriptor in the buffer that has a NULL
|
||||
/*
|
||||
* We put a dummy descriptor in the buffer that has a NULL
|
||||
* branch address and looks like it's been sent. That way we
|
||||
* have a descriptor to append DMA programs to. Also, the
|
||||
* ring buffer invariant is that it always has at least one
|
||||
* element so that head == tail means buffer full. */
|
||||
* element so that head == tail means buffer full.
|
||||
*/
|
||||
|
||||
memset(ctx->head_descriptor, 0, sizeof *ctx->head_descriptor);
|
||||
ctx->head_descriptor->control = cpu_to_le16(descriptor_output_last);
|
||||
|
@ -575,9 +583,11 @@ struct driver_data {
|
|||
struct fw_packet *packet;
|
||||
};
|
||||
|
||||
/* This function apppends a packet to the DMA queue for transmission.
|
||||
/*
|
||||
* This function apppends a packet to the DMA queue for transmission.
|
||||
* Must always be called with the ochi->lock held to ensure proper
|
||||
* generation handling and locking around packet queue manipulation. */
|
||||
* generation handling and locking around packet queue manipulation.
|
||||
*/
|
||||
static int
|
||||
at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
|
||||
{
|
||||
|
@ -598,10 +608,12 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
|
|||
d[0].control = cpu_to_le16(descriptor_key_immediate);
|
||||
d[0].res_count = cpu_to_le16(packet->timestamp);
|
||||
|
||||
/* The DMA format for asyncronous link packets is different
|
||||
/*
|
||||
* The DMA format for asyncronous link packets is different
|
||||
* from the IEEE1394 layout, so shift the fields around
|
||||
* accordingly. If header_length is 8, it's a PHY packet, to
|
||||
* which we need to prepend an extra quadlet. */
|
||||
* which we need to prepend an extra quadlet.
|
||||
*/
|
||||
|
||||
header = (__le32 *) &d[1];
|
||||
if (packet->header_length > 8) {
|
||||
|
@ -703,14 +715,18 @@ static int handle_at_packet(struct context *context,
|
|||
break;
|
||||
|
||||
case OHCI1394_evt_flushed:
|
||||
/* The packet was flushed should give same error as
|
||||
* when we try to use a stale generation count. */
|
||||
/*
|
||||
* The packet was flushed should give same error as
|
||||
* when we try to use a stale generation count.
|
||||
*/
|
||||
packet->ack = RCODE_GENERATION;
|
||||
break;
|
||||
|
||||
case OHCI1394_evt_missing_ack:
|
||||
/* Using a valid (current) generation count, but the
|
||||
* node is not on the bus or not sending acks. */
|
||||
/*
|
||||
* Using a valid (current) generation count, but the
|
||||
* node is not on the bus or not sending acks.
|
||||
*/
|
||||
packet->ack = RCODE_NO_ACK;
|
||||
break;
|
||||
|
||||
|
@ -887,10 +903,12 @@ static void bus_reset_tasklet(unsigned long data)
|
|||
}
|
||||
ohci->node_id = reg & 0xffff;
|
||||
|
||||
/* The count in the SelfIDCount register is the number of
|
||||
/*
|
||||
* The count in the SelfIDCount register is the number of
|
||||
* bytes in the self ID receive buffer. Since we also receive
|
||||
* the inverted quadlets and a header quadlet, we shift one
|
||||
* bit extra to get the actual number of self IDs. */
|
||||
* bit extra to get the actual number of self IDs.
|
||||
*/
|
||||
|
||||
self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff;
|
||||
generation = (le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
|
||||
|
@ -901,7 +919,8 @@ static void bus_reset_tasklet(unsigned long data)
|
|||
ohci->self_id_buffer[j] = le32_to_cpu(ohci->self_id_cpu[i]);
|
||||
}
|
||||
|
||||
/* Check the consistency of the self IDs we just read. The
|
||||
/*
|
||||
* Check the consistency of the self IDs we just read. The
|
||||
* problem we face is that a new bus reset can start while we
|
||||
* read out the self IDs from the DMA buffer. If this happens,
|
||||
* the DMA buffer will be overwritten with new self IDs and we
|
||||
|
@ -911,7 +930,8 @@ static void bus_reset_tasklet(unsigned long data)
|
|||
* self IDs in the buffer before reading them out and compare
|
||||
* it to the current generation after reading them out. If
|
||||
* the two generations match we know we have a consistent set
|
||||
* of self IDs. */
|
||||
* of self IDs.
|
||||
*/
|
||||
|
||||
new_generation = (reg_read(ohci, OHCI1394_SelfIDCount) >> 16) & 0xff;
|
||||
if (new_generation != generation) {
|
||||
|
@ -928,12 +948,14 @@ static void bus_reset_tasklet(unsigned long data)
|
|||
context_stop(&ohci->at_response_ctx);
|
||||
reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
|
||||
|
||||
/* This next bit is unrelated to the AT context stuff but we
|
||||
/*
|
||||
* This next bit is unrelated to the AT context stuff but we
|
||||
* have to do it under the spinlock also. If a new config rom
|
||||
* was set up before this reset, the old one is now no longer
|
||||
* in use and we can free it. Update the config rom pointers
|
||||
* to point to the current config rom and clear the
|
||||
* next_config_rom pointer so a new udpate can take place. */
|
||||
* next_config_rom pointer so a new udpate can take place.
|
||||
*/
|
||||
|
||||
if (ohci->next_config_rom != NULL) {
|
||||
dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
|
||||
|
@ -942,10 +964,12 @@ static void bus_reset_tasklet(unsigned long data)
|
|||
ohci->config_rom_bus = ohci->next_config_rom_bus;
|
||||
ohci->next_config_rom = NULL;
|
||||
|
||||
/* Restore config_rom image and manually update
|
||||
/*
|
||||
* Restore config_rom image and manually update
|
||||
* config_rom registers. Writing the header quadlet
|
||||
* will indicate that the config rom is ready, so we
|
||||
* do that last. */
|
||||
* do that last.
|
||||
*/
|
||||
reg_write(ohci, OHCI1394_BusOptions,
|
||||
be32_to_cpu(ohci->config_rom[2]));
|
||||
ohci->config_rom[0] = cpu_to_be32(ohci->next_header);
|
||||
|
@ -1018,7 +1042,8 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
|
|||
struct fw_ohci *ohci = fw_ohci(card);
|
||||
struct pci_dev *dev = to_pci_dev(card->device);
|
||||
|
||||
/* When the link is not yet enabled, the atomic config rom
|
||||
/*
|
||||
* When the link is not yet enabled, the atomic config rom
|
||||
* update mechanism described below in ohci_set_config_rom()
|
||||
* is not active. We have to update ConfigRomHeader and
|
||||
* BusOptions manually, and the write to ConfigROMmap takes
|
||||
|
@ -1067,8 +1092,10 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
|
|||
OHCI1394_HCControl_BIBimageValid);
|
||||
flush_writes(ohci);
|
||||
|
||||
/* We are ready to go, initiate bus reset to finish the
|
||||
* initialization. */
|
||||
/*
|
||||
* We are ready to go, initiate bus reset to finish the
|
||||
* initialization.
|
||||
*/
|
||||
|
||||
fw_core_initiate_bus_reset(&ohci->card, 1);
|
||||
|
||||
|
@ -1086,7 +1113,8 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
|
|||
|
||||
ohci = fw_ohci(card);
|
||||
|
||||
/* When the OHCI controller is enabled, the config rom update
|
||||
/*
|
||||
* When the OHCI controller is enabled, the config rom update
|
||||
* mechanism is a bit tricky, but easy enough to use. See
|
||||
* section 5.5.6 in the OHCI specification.
|
||||
*
|
||||
|
@ -1141,11 +1169,13 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
|
|||
|
||||
spin_unlock_irqrestore(&ohci->lock, flags);
|
||||
|
||||
/* Now initiate a bus reset to have the changes take
|
||||
/*
|
||||
* Now initiate a bus reset to have the changes take
|
||||
* effect. We clean up the old config rom memory and DMA
|
||||
* mappings in the bus reset tasklet, since the OHCI
|
||||
* controller could need to access it before the bus reset
|
||||
* takes effect. */
|
||||
* takes effect.
|
||||
*/
|
||||
if (retval == 0)
|
||||
fw_core_initiate_bus_reset(&ohci->card, 1);
|
||||
|
||||
|
@ -1196,8 +1226,10 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
|
|||
unsigned long flags;
|
||||
int n, retval = 0;
|
||||
|
||||
/* FIXME: Make sure this bitmask is cleared when we clear the busReset
|
||||
* interrupt bit. Clear physReqResourceAllBuses on bus reset. */
|
||||
/*
|
||||
* FIXME: Make sure this bitmask is cleared when we clear the busReset
|
||||
* interrupt bit. Clear physReqResourceAllBuses on bus reset.
|
||||
*/
|
||||
|
||||
spin_lock_irqsave(&ohci->lock, flags);
|
||||
|
||||
|
@ -1206,8 +1238,10 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* NOTE, if the node ID contains a non-local bus ID, physical DMA is
|
||||
* enabled for _all_ nodes on remote buses. */
|
||||
/*
|
||||
* Note, if the node ID contains a non-local bus ID, physical DMA is
|
||||
* enabled for _all_ nodes on remote buses.
|
||||
*/
|
||||
|
||||
n = (node_id & 0xffc0) == LOCAL_BUS ? node_id & 0x3f : 63;
|
||||
if (n < 32)
|
||||
|
@ -1257,11 +1291,13 @@ static int handle_ir_dualbuffer_packet(struct context *context,
|
|||
p = db + 1;
|
||||
end = p + header_length;
|
||||
while (p < end && i + ctx->base.header_size <= PAGE_SIZE) {
|
||||
/* The iso header is byteswapped to little endian by
|
||||
/*
|
||||
* The iso header is byteswapped to little endian by
|
||||
* the controller, but the remaining header quadlets
|
||||
* are big endian. We want to present all the headers
|
||||
* as big endian, so we have to swap the first
|
||||
* quadlet. */
|
||||
* quadlet.
|
||||
*/
|
||||
*(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
|
||||
memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
|
||||
i += ctx->base.header_size;
|
||||
|
@ -1457,8 +1493,10 @@ ohci_queue_iso_transmit(struct fw_iso_context *base,
|
|||
u32 payload_index, payload_end_index, next_page_index;
|
||||
int page, end_page, i, length, offset;
|
||||
|
||||
/* FIXME: Cycle lost behavior should be configurable: lose
|
||||
* packet, retransmit or terminate.. */
|
||||
/*
|
||||
* FIXME: Cycle lost behavior should be configurable: lose
|
||||
* packet, retransmit or terminate..
|
||||
*/
|
||||
|
||||
p = packet;
|
||||
payload_index = payload;
|
||||
|
@ -1553,8 +1591,10 @@ ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
|
|||
u32 z, header_z, length, rest;
|
||||
int page, offset, packet_count, header_size;
|
||||
|
||||
/* FIXME: Cycle lost behavior should be configurable: lose
|
||||
* packet, retransmit or terminate.. */
|
||||
/*
|
||||
* FIXME: Cycle lost behavior should be configurable: lose
|
||||
* packet, retransmit or terminate..
|
||||
*/
|
||||
|
||||
if (packet->skip) {
|
||||
d = context_get_descriptors(&ctx->context, 2, &d_bus);
|
||||
|
@ -1572,8 +1612,10 @@ ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
|
|||
p = packet;
|
||||
z = 2;
|
||||
|
||||
/* The OHCI controller puts the status word in the header
|
||||
* buffer too, so we need 4 extra bytes per packet. */
|
||||
/*
|
||||
* The OHCI controller puts the status word in the header
|
||||
* buffer too, so we need 4 extra bytes per packet.
|
||||
*/
|
||||
packet_count = p->header_length / ctx->base.header_size;
|
||||
header_size = packet_count * (ctx->base.header_size + 4);
|
||||
|
||||
|
@ -1673,8 +1715,6 @@ static int software_reset(struct fw_ohci *ohci)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* ---------- pci subsystem interface ---------- */
|
||||
|
||||
enum {
|
||||
CLEANUP_SELF_ID,
|
||||
CLEANUP_REGISTERS,
|
||||
|
@ -1753,11 +1793,13 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
|
|||
return cleanup(ohci, CLEANUP_REGISTERS, -EBUSY);
|
||||
}
|
||||
|
||||
/* Now enable LPS, which we need in order to start accessing
|
||||
/*
|
||||
* Now enable LPS, which we need in order to start accessing
|
||||
* most of the registers. In fact, on some cards (ALI M5251),
|
||||
* accessing registers in the SClk domain without LPS enabled
|
||||
* will lock up the machine. Wait 50msec to make sure we have
|
||||
* full link enabled. */
|
||||
* full link enabled.
|
||||
*/
|
||||
reg_write(ohci, OHCI1394_HCControlSet,
|
||||
OHCI1394_HCControl_LPS |
|
||||
OHCI1394_HCControl_postedWriteEnable);
|
||||
|
@ -1854,8 +1896,10 @@ static void pci_remove(struct pci_dev *dev)
|
|||
flush_writes(ohci);
|
||||
fw_core_remove_card(&ohci->card);
|
||||
|
||||
/* FIXME: Fail all pending packets here, now that the upper
|
||||
* layers can't queue any more. */
|
||||
/*
|
||||
* FIXME: Fail all pending packets here, now that the upper
|
||||
* layers can't queue any more.
|
||||
*/
|
||||
|
||||
software_reset(ohci);
|
||||
free_irq(dev->irq, ohci);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
* fw-spb2.c -- SBP2 driver (SCSI over IEEE1394)
|
||||
/*
|
||||
* SBP2 driver (SCSI over IEEE1394)
|
||||
*
|
||||
* Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
|
@ -18,7 +18,8 @@
|
|||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* The basic structure of this driver is based the old storage driver,
|
||||
/*
|
||||
* The basic structure of this driver is based on the old storage driver,
|
||||
* drivers/ieee1394/sbp2.c, originally written by
|
||||
* James Goodwin <jamesg@filanet.com>
|
||||
* with later contributions and ongoing maintenance from
|
||||
|
@ -60,11 +61,13 @@ struct sbp2_device {
|
|||
u32 workarounds;
|
||||
int login_id;
|
||||
|
||||
/* We cache these addresses and only update them once we've
|
||||
/*
|
||||
* We cache these addresses and only update them once we've
|
||||
* logged in or reconnected to the sbp2 device. That way, any
|
||||
* IO to the device will automatically fail and get retried if
|
||||
* it happens in a window where the device is not ready to
|
||||
* handle it (e.g. after a bus reset but before we reconnect). */
|
||||
* handle it (e.g. after a bus reset but before we reconnect).
|
||||
*/
|
||||
int node_id;
|
||||
int address_high;
|
||||
int generation;
|
||||
|
@ -239,10 +242,14 @@ static const struct {
|
|||
.model = ~0,
|
||||
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
|
||||
},
|
||||
/* There are iPods (2nd gen, 3rd gen) with model_id == 0, but
|
||||
|
||||
/*
|
||||
* There are iPods (2nd gen, 3rd gen) with model_id == 0, but
|
||||
* these iPods do not feature the read_capacity bug according
|
||||
* to one report. Read_capacity behaviour as well as model_id
|
||||
* could change due to Apple-supplied firmware updates though. */
|
||||
* could change due to Apple-supplied firmware updates though.
|
||||
*/
|
||||
|
||||
/* iPod 4th generation. */ {
|
||||
.firmware_revision = 0x0a2700,
|
||||
.model = 0x000021,
|
||||
|
@ -398,9 +405,10 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
|
|||
if (orb == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* The sbp2 device is going to send a block read request to
|
||||
* read out the request from host memory, so map it for
|
||||
* dma. */
|
||||
/*
|
||||
* The sbp2 device is going to send a block read request to
|
||||
* read out the request from host memory, so map it for dma.
|
||||
*/
|
||||
orb->base.request_bus =
|
||||
dma_map_single(device->card->device, &orb->request,
|
||||
sizeof orb->request, DMA_TO_DEVICE);
|
||||
|
@ -426,10 +434,11 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
|
|||
orb->request.status_fifo.high = sd->address_handler.offset >> 32;
|
||||
orb->request.status_fifo.low = sd->address_handler.offset;
|
||||
|
||||
/* FIXME: Yeah, ok this isn't elegant, we hardwire exclusive
|
||||
/*
|
||||
* FIXME: Yeah, ok this isn't elegant, we hardwire exclusive
|
||||
* login and 1 second reconnect time. The reconnect setting
|
||||
* is probably fine, but the exclusive login should be an
|
||||
* option. */
|
||||
* is probably fine, but the exclusive login should be an option.
|
||||
*/
|
||||
if (function == SBP2_LOGIN_REQUEST) {
|
||||
orb->request.misc |=
|
||||
management_orb_exclusive |
|
||||
|
@ -592,8 +601,10 @@ static void sbp2_login(struct work_struct *work)
|
|||
sbp2_send_management_orb(unit, sd->node_id, sd->generation,
|
||||
SBP2_LOGOUT_REQUEST, sd->login_id,
|
||||
NULL);
|
||||
/* Set this back to sbp2_login so we fall back and
|
||||
* retry login on bus reset. */
|
||||
/*
|
||||
* Set this back to sbp2_login so we fall back and
|
||||
* retry login on bus reset.
|
||||
*/
|
||||
PREPARE_DELAYED_WORK(&sd->work, sbp2_login);
|
||||
}
|
||||
kref_put(&sd->kref, release_sbp2_device);
|
||||
|
@ -633,9 +644,11 @@ static int sbp2_probe(struct device *dev)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Scan unit directory to get management agent address,
|
||||
/*
|
||||
* Scan unit directory to get management agent address,
|
||||
* firmware revison and model. Initialize firmware_revision
|
||||
* and model to values that wont match anything in our table. */
|
||||
* and model to values that wont match anything in our table.
|
||||
*/
|
||||
firmware_revision = 0xff000000;
|
||||
model = 0xff000000;
|
||||
fw_csr_iterator_init(&ci, unit->directory);
|
||||
|
@ -673,9 +686,11 @@ static int sbp2_probe(struct device *dev)
|
|||
|
||||
get_device(&unit->device);
|
||||
|
||||
/* We schedule work to do the login so we can easily
|
||||
/*
|
||||
* We schedule work to do the login so we can easily
|
||||
* reschedule retries. Always get the ref before scheduling
|
||||
* work.*/
|
||||
* work.
|
||||
*/
|
||||
INIT_DELAYED_WORK(&sd->work, sbp2_login);
|
||||
if (schedule_delayed_work(&sd->work, 0))
|
||||
kref_get(&sd->kref);
|
||||
|
@ -834,9 +849,11 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
|
|||
result = sbp2_status_to_sense_data(status_get_data(*status),
|
||||
orb->cmd->sense_buffer);
|
||||
} else {
|
||||
/* If the orb completes with status == NULL, something
|
||||
/*
|
||||
* If the orb completes with status == NULL, something
|
||||
* went wrong, typically a bus reset happened mid-orb
|
||||
* or when sending the write (less likely). */
|
||||
* or when sending the write (less likely).
|
||||
*/
|
||||
result = DID_BUS_BUSY << 16;
|
||||
}
|
||||
|
||||
|
@ -878,11 +895,13 @@ static void sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
|
|||
count = dma_map_sg(device->card->device, sg, orb->cmd->use_sg,
|
||||
orb->cmd->sc_data_direction);
|
||||
|
||||
/* Handle the special case where there is only one element in
|
||||
/*
|
||||
* Handle the special case where there is only one element in
|
||||
* the scatter list by converting it to an immediate block
|
||||
* request. This is also a workaround for broken devices such
|
||||
* as the second generation iPod which doesn't support page
|
||||
* tables. */
|
||||
* tables.
|
||||
*/
|
||||
if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) {
|
||||
orb->request.data_descriptor.high = sd->address_high;
|
||||
orb->request.data_descriptor.low = sg_dma_address(sg);
|
||||
|
@ -891,8 +910,10 @@ static void sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Convert the scatterlist to an sbp2 page table. If any
|
||||
* scatterlist entries are too big for sbp2 we split the as we go. */
|
||||
/*
|
||||
* Convert the scatterlist to an sbp2 page table. If any
|
||||
* scatterlist entries are too big for sbp2 we split the as we go.
|
||||
*/
|
||||
for (i = 0, j = 0; i < count; i++) {
|
||||
sg_len = sg_dma_len(sg + i);
|
||||
sg_addr = sg_dma_address(sg + i);
|
||||
|
@ -908,11 +929,13 @@ static void sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
|
|||
|
||||
size = sizeof orb->page_table[0] * j;
|
||||
|
||||
/* The data_descriptor pointer is the one case where we need
|
||||
/*
|
||||
* The data_descriptor pointer is the one case where we need
|
||||
* to fill in the node ID part of the address. All other
|
||||
* pointers assume that the data referenced reside on the
|
||||
* initiator (i.e. us), but data_descriptor can refer to data
|
||||
* on other nodes so we need to put our ID in descriptor.high. */
|
||||
* on other nodes so we need to put our ID in descriptor.high.
|
||||
*/
|
||||
|
||||
orb->page_table_bus =
|
||||
dma_map_single(device->card->device, orb->page_table,
|
||||
|
@ -933,8 +956,10 @@ static void sbp2_command_orb_map_buffer(struct sbp2_command_orb *orb)
|
|||
struct fw_device *device = fw_device(unit->device.parent);
|
||||
struct sbp2_device *sd = unit->device.driver_data;
|
||||
|
||||
/* As for map_scatterlist, we need to fill in the high bits of
|
||||
* the data_descriptor pointer. */
|
||||
/*
|
||||
* As for map_scatterlist, we need to fill in the high bits of
|
||||
* the data_descriptor pointer.
|
||||
*/
|
||||
|
||||
orb->request_buffer_bus =
|
||||
dma_map_single(device->card->device,
|
||||
|
@ -956,8 +981,10 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
|
|||
struct sbp2_device *sd = unit->device.driver_data;
|
||||
struct sbp2_command_orb *orb;
|
||||
|
||||
/* Bidirectional commands are not yet implemented, and unknown
|
||||
* transfer direction not handled. */
|
||||
/*
|
||||
* Bidirectional commands are not yet implemented, and unknown
|
||||
* transfer direction not handled.
|
||||
*/
|
||||
if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) {
|
||||
fw_error("Cannot handle DMA_BIDIRECTIONAL - rejecting command");
|
||||
goto fail_alloc;
|
||||
|
@ -983,10 +1010,12 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
|
|||
|
||||
orb->request.next.high = SBP2_ORB_NULL;
|
||||
orb->request.next.low = 0x0;
|
||||
/* At speed 100 we can do 512 bytes per packet, at speed 200,
|
||||
/*
|
||||
* At speed 100 we can do 512 bytes per packet, at speed 200,
|
||||
* 1024 bytes per packet etc. The SBP-2 max_payload field
|
||||
* specifies the max payload size as 2 ^ (max_payload + 2), so
|
||||
* if we set this to max_speed + 7, we get the right value. */
|
||||
* if we set this to max_speed + 7, we get the right value.
|
||||
*/
|
||||
orb->request.misc =
|
||||
command_orb_max_payload(device->node->max_speed + 7) |
|
||||
command_orb_speed(device->node->max_speed) |
|
||||
|
@ -1002,9 +1031,11 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
|
|||
if (cmd->use_sg) {
|
||||
sbp2_command_orb_map_scatterlist(orb);
|
||||
} else if (cmd->request_bufflen > SBP2_MAX_SG_ELEMENT_LENGTH) {
|
||||
/* FIXME: Need to split this into a sg list... but
|
||||
/*
|
||||
* FIXME: Need to split this into a sg list... but
|
||||
* could we get the scsi or blk layer to do that by
|
||||
* reporting our max supported block size? */
|
||||
* reporting our max supported block size?
|
||||
*/
|
||||
fw_error("command > 64k\n");
|
||||
goto fail_bufflen;
|
||||
} else if (cmd->request_bufflen > 0) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
*
|
||||
* fw-topology.c - Incremental bus scan, based on bus topology
|
||||
/*
|
||||
* Incremental bus scan, based on bus topology
|
||||
*
|
||||
* Copyright (C) 2004-2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
|
@ -69,10 +68,12 @@ static u32 *count_ports(u32 *sid, int *total_port_count, int *child_port_count)
|
|||
sid++;
|
||||
q = *sid;
|
||||
|
||||
/* Check that the extra packets actually are
|
||||
/*
|
||||
* Check that the extra packets actually are
|
||||
* extended self ID packets and that the
|
||||
* sequence numbers in the extended self ID
|
||||
* packets increase as expected. */
|
||||
* packets increase as expected.
|
||||
*/
|
||||
|
||||
if (!self_id_extended(q) ||
|
||||
seq != self_id_ext_sequence(q))
|
||||
|
@ -113,7 +114,8 @@ static struct fw_node *fw_node_create(u32 sid, int port_count, int color)
|
|||
return node;
|
||||
}
|
||||
|
||||
/* Compute the maximum hop count for this node and it's children. The
|
||||
/*
|
||||
* Compute the maximum hop count for this node and it's children. The
|
||||
* maximum hop count is the maximum number of connections between any
|
||||
* two nodes in the subtree rooted at this node. We need this for
|
||||
* setting the gap count. As we build the tree bottom up in
|
||||
|
@ -202,8 +204,10 @@ static struct fw_node *build_tree(struct fw_card *card,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Seek back from the top of our stack to find the
|
||||
* start of the child nodes for this node. */
|
||||
/*
|
||||
* Seek back from the top of our stack to find the
|
||||
* start of the child nodes for this node.
|
||||
*/
|
||||
for (i = 0, h = &stack; i < child_port_count; i++)
|
||||
h = h->prev;
|
||||
child = fw_node(h);
|
||||
|
@ -230,7 +234,8 @@ static struct fw_node *build_tree(struct fw_card *card,
|
|||
for (i = 0; i < port_count; i++) {
|
||||
switch (get_port_type(sid, i)) {
|
||||
case SELFID_PORT_PARENT:
|
||||
/* Who's your daddy? We dont know the
|
||||
/*
|
||||
* Who's your daddy? We dont know the
|
||||
* parent node at this time, so we
|
||||
* temporarily abuse node->color for
|
||||
* remembering the entry in the
|
||||
|
@ -245,8 +250,10 @@ static struct fw_node *build_tree(struct fw_card *card,
|
|||
|
||||
case SELFID_PORT_CHILD:
|
||||
node->ports[i].node = child;
|
||||
/* Fix up parent reference for this
|
||||
* child node. */
|
||||
/*
|
||||
* Fix up parent reference for this
|
||||
* child node.
|
||||
*/
|
||||
child->ports[child->color].node = node;
|
||||
child->color = card->color;
|
||||
child = fw_node(child->link.next);
|
||||
|
@ -254,9 +261,11 @@ static struct fw_node *build_tree(struct fw_card *card,
|
|||
}
|
||||
}
|
||||
|
||||
/* Check that the node reports exactly one parent
|
||||
/*
|
||||
* Check that the node reports exactly one parent
|
||||
* port, except for the root, which of course should
|
||||
* have no parents. */
|
||||
* have no parents.
|
||||
*/
|
||||
if ((next_sid == end && parent_count != 0) ||
|
||||
(next_sid < end && parent_count != 1)) {
|
||||
fw_error("Parent port inconsistency for node %d: "
|
||||
|
@ -269,9 +278,11 @@ static struct fw_node *build_tree(struct fw_card *card,
|
|||
list_add_tail(&node->link, &stack);
|
||||
stack_depth += 1 - child_port_count;
|
||||
|
||||
/* If all PHYs does not report the same gap count
|
||||
/*
|
||||
* If all PHYs does not report the same gap count
|
||||
* setting, we fall back to 63 which will force a gap
|
||||
* count reconfiguration and a reset. */
|
||||
* count reconfiguration and a reset.
|
||||
*/
|
||||
if (self_id_gap_count(q) != gap_count)
|
||||
gap_count = 63;
|
||||
|
||||
|
@ -427,9 +438,11 @@ update_tree(struct fw_card *card, struct fw_node *root)
|
|||
|
||||
for (i = 0; i < node0->port_count; i++) {
|
||||
if (node0->ports[i].node && node1->ports[i].node) {
|
||||
/* This port didn't change, queue the
|
||||
/*
|
||||
* This port didn't change, queue the
|
||||
* connected node for further
|
||||
* investigation. */
|
||||
* investigation.
|
||||
*/
|
||||
if (node0->ports[i].node->color == card->color)
|
||||
continue;
|
||||
list_add_tail(&node0->ports[i].node->link,
|
||||
|
@ -437,19 +450,23 @@ update_tree(struct fw_card *card, struct fw_node *root)
|
|||
list_add_tail(&node1->ports[i].node->link,
|
||||
&list1);
|
||||
} else if (node0->ports[i].node) {
|
||||
/* The nodes connected here were
|
||||
/*
|
||||
* The nodes connected here were
|
||||
* unplugged; unref the lost nodes and
|
||||
* queue FW_NODE_LOST callbacks for
|
||||
* them. */
|
||||
* them.
|
||||
*/
|
||||
|
||||
for_each_fw_node(card, node0->ports[i].node,
|
||||
report_lost_node);
|
||||
node0->ports[i].node = NULL;
|
||||
} else if (node1->ports[i].node) {
|
||||
/* One or more node were connected to
|
||||
/*
|
||||
* One or more node were connected to
|
||||
* this port. Move the new nodes into
|
||||
* the tree and queue FW_NODE_CREATED
|
||||
* callbacks for them. */
|
||||
* callbacks for them.
|
||||
*/
|
||||
move_tree(node0, node1, i);
|
||||
for_each_fw_node(card, node0->ports[i].node,
|
||||
report_found_node);
|
||||
|
@ -486,9 +503,11 @@ fw_core_handle_bus_reset(struct fw_card *card,
|
|||
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
|
||||
/* If the new topology has a different self_id_count the topology
|
||||
/*
|
||||
* If the new topology has a different self_id_count the topology
|
||||
* changed, either nodes were added or removed. In that case we
|
||||
* reset the IRM reset counter. */
|
||||
* reset the IRM reset counter.
|
||||
*/
|
||||
if (card->self_id_count != self_id_count)
|
||||
card->bm_retries = 0;
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
*
|
||||
* fw-topology.h -- Incremental bus scan, based on bus topology
|
||||
*
|
||||
/*
|
||||
* Copyright (C) 2003-2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
*
|
||||
* fw-transaction.c - core IEEE1394 transaction logic
|
||||
/*
|
||||
* Core IEEE1394 transaction logic
|
||||
*
|
||||
* Copyright (C) 2004-2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
|
@ -85,21 +84,27 @@ close_transaction(struct fw_transaction *transaction,
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Only valid for transactions that are potentially pending (ie have
|
||||
* been sent). */
|
||||
/*
|
||||
* Only valid for transactions that are potentially pending (ie have
|
||||
* been sent).
|
||||
*/
|
||||
int
|
||||
fw_cancel_transaction(struct fw_card *card,
|
||||
struct fw_transaction *transaction)
|
||||
{
|
||||
/* Cancel the packet transmission if it's still queued. That
|
||||
/*
|
||||
* Cancel the packet transmission if it's still queued. That
|
||||
* will call the packet transmission callback which cancels
|
||||
* the transaction. */
|
||||
* the transaction.
|
||||
*/
|
||||
|
||||
if (card->driver->cancel_packet(card, &transaction->packet) == 0)
|
||||
return 0;
|
||||
|
||||
/* If the request packet has already been sent, we need to see
|
||||
* if the transaction is still pending and remove it in that case. */
|
||||
/*
|
||||
* If the request packet has already been sent, we need to see
|
||||
* if the transaction is still pending and remove it in that case.
|
||||
*/
|
||||
|
||||
return close_transaction(transaction, card, RCODE_CANCELLED, NULL, 0);
|
||||
}
|
||||
|
@ -131,8 +136,10 @@ transmit_complete_callback(struct fw_packet *packet,
|
|||
close_transaction(t, card, RCODE_TYPE_ERROR, NULL, 0);
|
||||
break;
|
||||
default:
|
||||
/* In this case the ack is really a juju specific
|
||||
* rcode, so just forward that to the callback. */
|
||||
/*
|
||||
* In this case the ack is really a juju specific
|
||||
* rcode, so just forward that to the callback.
|
||||
*/
|
||||
close_transaction(t, card, status, NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
@ -243,13 +250,17 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
|
|||
unsigned long flags;
|
||||
int tlabel, source;
|
||||
|
||||
/* Bump the flush timer up 100ms first of all so we
|
||||
* don't race with a flush timer callback. */
|
||||
/*
|
||||
* Bump the flush timer up 100ms first of all so we
|
||||
* don't race with a flush timer callback.
|
||||
*/
|
||||
|
||||
mod_timer(&card->flush_timer, jiffies + DIV_ROUND_UP(HZ, 10));
|
||||
|
||||
/* Allocate tlabel from the bitmap and put the transaction on
|
||||
* the list while holding the card spinlock. */
|
||||
/*
|
||||
* Allocate tlabel from the bitmap and put the transaction on
|
||||
* the list while holding the card spinlock.
|
||||
*/
|
||||
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
|
||||
|
@ -336,9 +347,11 @@ void fw_flush_transactions(struct fw_card *card)
|
|||
list_for_each_entry_safe(t, next, &list, link) {
|
||||
card->driver->cancel_packet(card, &t->packet);
|
||||
|
||||
/* At this point cancel_packet will never call the
|
||||
/*
|
||||
* At this point cancel_packet will never call the
|
||||
* transaction callback, since we just took all the
|
||||
* transactions out of the list. So do it here.*/
|
||||
* transactions out of the list. So do it here.
|
||||
*/
|
||||
t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data);
|
||||
}
|
||||
}
|
||||
|
@ -587,9 +600,11 @@ allocate_request(struct fw_packet *p)
|
|||
void
|
||||
fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
|
||||
{
|
||||
/* Broadcast packets are reported as ACK_COMPLETE, so this
|
||||
/*
|
||||
* Broadcast packets are reported as ACK_COMPLETE, so this
|
||||
* check is sufficient to ensure we don't send response to
|
||||
* broadcast packets or posted writes. */
|
||||
* broadcast packets or posted writes.
|
||||
*/
|
||||
if (request->ack != ACK_PENDING)
|
||||
return;
|
||||
|
||||
|
@ -639,11 +654,13 @@ fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
|
|||
offset, request->length);
|
||||
spin_unlock_irqrestore(&address_handler_lock, flags);
|
||||
|
||||
/* FIXME: lookup the fw_node corresponding to the sender of
|
||||
/*
|
||||
* FIXME: lookup the fw_node corresponding to the sender of
|
||||
* this request and pass that to the address handler instead
|
||||
* of the node ID. We may also want to move the address
|
||||
* allocations to fw_node so we only do this callback if the
|
||||
* upper layers registered it for this node. */
|
||||
* upper layers registered it for this node.
|
||||
*/
|
||||
|
||||
if (handler == NULL)
|
||||
fw_send_response(card, request, RCODE_ADDRESS_ERROR);
|
||||
|
@ -687,8 +704,10 @@ fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
|
|||
return;
|
||||
}
|
||||
|
||||
/* FIXME: sanity check packet, is length correct, does tcodes
|
||||
* and addresses match. */
|
||||
/*
|
||||
* FIXME: sanity check packet, is length correct, does tcodes
|
||||
* and addresses match.
|
||||
*/
|
||||
|
||||
switch (tcode) {
|
||||
case TCODE_READ_QUADLET_RESPONSE:
|
||||
|
@ -790,11 +809,13 @@ handle_registers(struct fw_card *card, struct fw_request *request,
|
|||
case CSR_BANDWIDTH_AVAILABLE:
|
||||
case CSR_CHANNELS_AVAILABLE_HI:
|
||||
case CSR_CHANNELS_AVAILABLE_LO:
|
||||
/* FIXME: these are handled by the OHCI hardware and
|
||||
/*
|
||||
* FIXME: these are handled by the OHCI hardware and
|
||||
* the stack never sees these request. If we add
|
||||
* support for a new type of controller that doesn't
|
||||
* handle this in hardware we need to deal with these
|
||||
* transactions. */
|
||||
* transactions.
|
||||
*/
|
||||
BUG();
|
||||
break;
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
/* -*- c-basic-offset: 8 -*-
|
||||
*
|
||||
* fw-transaction.h - Header for IEEE1394 transaction logic
|
||||
*
|
||||
/*
|
||||
* Copyright (C) 2003-2006 Kristian Hoegsberg <krh@bitplanet.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -209,7 +206,8 @@ struct fw_packet {
|
|||
size_t payload_length;
|
||||
u32 timestamp;
|
||||
|
||||
/* This callback is called when the packet transmission has
|
||||
/*
|
||||
* This callback is called when the packet transmission has
|
||||
* completed; for successful transmission, the status code is
|
||||
* the ack received from the destination, otherwise it's a
|
||||
* negative errno: ENOMEM, ESTALE, ETIMEDOUT, ENODEV, EIO.
|
||||
|
@ -230,8 +228,10 @@ struct fw_transaction {
|
|||
|
||||
struct fw_packet packet;
|
||||
|
||||
/* The data passed to the callback is valid only during the
|
||||
* callback. */
|
||||
/*
|
||||
* The data passed to the callback is valid only during the
|
||||
* callback.
|
||||
*/
|
||||
fw_transaction_callback_t callback;
|
||||
void *callback_data;
|
||||
};
|
||||
|
@ -291,8 +291,10 @@ struct fw_card {
|
|||
int link_speed;
|
||||
int config_rom_generation;
|
||||
|
||||
/* We need to store up to 4 self ID for a maximum of 63
|
||||
* devices plus 3 words for the topology map header. */
|
||||
/*
|
||||
* We need to store up to 4 self ID for a maximum of 63
|
||||
* devices plus 3 words for the topology map header.
|
||||
*/
|
||||
int self_id_count;
|
||||
u32 topology_map[252 + 3];
|
||||
|
||||
|
@ -318,12 +320,14 @@ struct fw_card {
|
|||
struct fw_card *fw_card_get(struct fw_card *card);
|
||||
void fw_card_put(struct fw_card *card);
|
||||
|
||||
/* The iso packet format allows for an immediate header/payload part
|
||||
/*
|
||||
* The iso packet format allows for an immediate header/payload part
|
||||
* stored in 'header' immediately after the packet info plus an
|
||||
* indirect payload part that is pointer to by the 'payload' field.
|
||||
* Applications can use one or the other or both to implement simple
|
||||
* low-bandwidth streaming (e.g. audio) or more advanced
|
||||
* scatter-gather streaming (e.g. assembling video frame automatically). */
|
||||
* scatter-gather streaming (e.g. assembling video frame automatically).
|
||||
*/
|
||||
|
||||
struct fw_iso_packet {
|
||||
u16 payload_length; /* Length of indirect payload. */
|
||||
|
@ -352,11 +356,13 @@ typedef void (*fw_iso_callback_t) (struct fw_iso_context *context,
|
|||
void *header,
|
||||
void *data);
|
||||
|
||||
/* An iso buffer is just a set of pages mapped for DMA in the
|
||||
/*
|
||||
* An iso buffer is just a set of pages mapped for DMA in the
|
||||
* specified direction. Since the pages are to be used for DMA, they
|
||||
* are not mapped into the kernel virtual address space. We store the
|
||||
* DMA address in the page private. The helper function
|
||||
* fw_iso_buffer_map() will map the pages into a given vma. */
|
||||
* fw_iso_buffer_map() will map the pages into a given vma.
|
||||
*/
|
||||
|
||||
struct fw_iso_buffer {
|
||||
enum dma_data_direction direction;
|
||||
|
@ -408,18 +414,22 @@ fw_iso_context_stop(struct fw_iso_context *ctx);
|
|||
struct fw_card_driver {
|
||||
const char *name;
|
||||
|
||||
/* Enable the given card with the given initial config rom.
|
||||
/*
|
||||
* Enable the given card with the given initial config rom.
|
||||
* This function is expected to activate the card, and either
|
||||
* enable the PHY or set the link_on bit and initiate a bus
|
||||
* reset. */
|
||||
* reset.
|
||||
*/
|
||||
int (*enable) (struct fw_card *card, u32 *config_rom, size_t length);
|
||||
|
||||
int (*update_phy_reg) (struct fw_card *card, int address,
|
||||
int clear_bits, int set_bits);
|
||||
|
||||
/* Update the config rom for an enabled card. This function
|
||||
/*
|
||||
* Update the config rom for an enabled card. This function
|
||||
* should change the config rom that is presented on the bus
|
||||
* an initiate a bus reset. */
|
||||
* an initiate a bus reset.
|
||||
*/
|
||||
int (*set_config_rom) (struct fw_card *card,
|
||||
u32 *config_rom, size_t length);
|
||||
|
||||
|
@ -428,12 +438,14 @@ struct fw_card_driver {
|
|||
/* Calling cancel is valid once a packet has been submitted. */
|
||||
int (*cancel_packet) (struct fw_card *card, struct fw_packet *packet);
|
||||
|
||||
/* Allow the specified node ID to do direct DMA out and in of
|
||||
/*
|
||||
* Allow the specified node ID to do direct DMA out and in of
|
||||
* host memory. The card will disable this for all node when
|
||||
* a bus reset happens, so driver need to reenable this after
|
||||
* bus reset. Returns 0 on success, -ENODEV if the card
|
||||
* doesn't support this, -ESTALE if the generation doesn't
|
||||
* match. */
|
||||
* match.
|
||||
*/
|
||||
int (*enable_phys_dma) (struct fw_card *card,
|
||||
int node_id, int generation);
|
||||
|
||||
|
@ -473,15 +485,15 @@ void fw_flush_transactions(struct fw_card *card);
|
|||
void fw_send_phy_config(struct fw_card *card,
|
||||
int node_id, int generation, int gap_count);
|
||||
|
||||
/* Called by the topology code to inform the device code of node
|
||||
* activity; found, lost, or updated nodes */
|
||||
/*
|
||||
* Called by the topology code to inform the device code of node
|
||||
* activity; found, lost, or updated nodes.
|
||||
*/
|
||||
void
|
||||
fw_node_event(struct fw_card *card, struct fw_node *node, int event);
|
||||
|
||||
/* API used by card level drivers */
|
||||
|
||||
/* Do we need phy speed here also? If we add more args, maybe we
|
||||
should go back to struct fw_card_info. */
|
||||
void
|
||||
fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
|
||||
struct device *device);
|
||||
|
|
Loading…
Reference in New Issue