Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/ieee1394/linux1394-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6: (53 commits)
  DVB: firedtv: FireDTV S2 problems with tuning solved
  DVB: firedtv: fix printk format mismatch
  ieee1394: constify device ID tables
  ieee1394: raw1394: add sparse annotations to raw1394_compat_write
  ieee1394: Storage class should be before const qualifier
  ieee1394: sbp2: follow up on "ieee1394: inherit ud vendor_id from node vendor_id"
  firewire: core: optimize propagation of BROADCAST_CHANNEL
  firewire: core: simplify broadcast channel allocation
  firewire: core: increase bus manager grace period
  firewire: core: drop unused call parameters of close_transaction
  firewire: cdev: add closure to async stream ioctl
  firewire: cdev: simplify FW_CDEV_IOC_SEND_REQUEST return value
  firewire: cdev: fix race of ioctl_send_request with bus reset
  firewire: cdev: secure add_descriptor ioctl
  firewire: cdev: amendment to "add ioctl to query maximum transmission speed"
  firewire: broadcast channel support
  firewire: implement asynchronous stream transmission
  firewire: core: normalize a function argument name
  firewire: normalize a variable name
  firewire: core: remove condition which is always false
  ...
  • Loading branch information
Linus Torvalds committed Mar 28, 2009
2 parents 0b4d569 + 32a0f48 commit febb02b
Show file tree
Hide file tree
Showing 22 changed files with 1,684 additions and 925 deletions.
149 changes: 80 additions & 69 deletions drivers/firewire/fw-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ static int descriptor_count;
#define BIB_CMC ((1) << 30)
#define BIB_IMC ((1) << 31)

static u32 *
generate_config_rom(struct fw_card *card, size_t *config_rom_length)
static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
{
struct fw_descriptor *desc;
static u32 config_rom[256];
Expand Down Expand Up @@ -128,8 +127,7 @@ generate_config_rom(struct fw_card *card, size_t *config_rom_length)
return config_rom;
}

static void
update_config_roms(void)
static void update_config_roms(void)
{
struct fw_card *card;
u32 *config_rom;
Expand All @@ -141,8 +139,7 @@ update_config_roms(void)
}
}

int
fw_core_add_descriptor(struct fw_descriptor *desc)
int fw_core_add_descriptor(struct fw_descriptor *desc)
{
size_t i;

Expand Down Expand Up @@ -171,8 +168,7 @@ fw_core_add_descriptor(struct fw_descriptor *desc)
return 0;
}

void
fw_core_remove_descriptor(struct fw_descriptor *desc)
void fw_core_remove_descriptor(struct fw_descriptor *desc)
{
mutex_lock(&card_mutex);

Expand All @@ -185,12 +181,30 @@ fw_core_remove_descriptor(struct fw_descriptor *desc)
mutex_unlock(&card_mutex);
}

static int set_broadcast_channel(struct device *dev, void *data)
{
fw_device_set_broadcast_channel(fw_device(dev), (long)data);
return 0;
}

static void allocate_broadcast_channel(struct fw_card *card, int generation)
{
int channel, bandwidth = 0;

fw_iso_resource_manage(card, generation, 1ULL << 31,
&channel, &bandwidth, true);
if (channel == 31) {
card->broadcast_channel_allocated = true;
device_for_each_child(card->device, (void *)(long)generation,
set_broadcast_channel);
}
}

static const char gap_count_table[] = {
63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
};

void
fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
{
int scheduled;

Expand All @@ -200,37 +214,38 @@ fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
fw_card_put(card);
}

static void
fw_card_bm_work(struct work_struct *work)
static void fw_card_bm_work(struct work_struct *work)
{
struct fw_card *card = container_of(work, struct fw_card, work.work);
struct fw_device *root_device;
struct fw_node *root_node, *local_node;
struct fw_node *root_node;
unsigned long flags;
int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
int root_id, new_root_id, irm_id, local_id;
int gap_count, generation, grace, rcode;
bool do_reset = false;
bool root_device_is_running;
bool root_device_is_cmc;
__be32 lock_data[2];

spin_lock_irqsave(&card->lock, flags);
local_node = card->local_node;
root_node = card->root_node;

if (local_node == NULL) {
if (card->local_node == NULL) {
spin_unlock_irqrestore(&card->lock, flags);
goto out_put_card;
}
fw_node_get(local_node);
fw_node_get(root_node);

generation = card->generation;
root_node = card->root_node;
fw_node_get(root_node);
root_device = root_node->data;
root_device_is_running = root_device &&
atomic_read(&root_device->state) == FW_DEVICE_RUNNING;
root_device_is_cmc = root_device && root_device->cmc;
root_id = root_node->node_id;
grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
root_id = root_node->node_id;
irm_id = card->irm_node->node_id;
local_id = card->local_node->node_id;

grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8));

if (is_next_generation(generation, card->bm_generation) ||
(card->bm_generation != generation && grace)) {
Expand All @@ -246,16 +261,15 @@ fw_card_bm_work(struct work_struct *work)
* next generation.
*/

irm_id = card->irm_node->node_id;
if (!card->irm_node->link_on) {
new_root_id = local_node->node_id;
new_root_id = local_id;
fw_notify("IRM has link off, making local node (%02x) root.\n",
new_root_id);
goto pick_me;
}

lock_data[0] = cpu_to_be32(0x3f);
lock_data[1] = cpu_to_be32(local_node->node_id);
lock_data[1] = cpu_to_be32(local_id);

spin_unlock_irqrestore(&card->lock, flags);

Expand All @@ -269,9 +283,14 @@ fw_card_bm_work(struct work_struct *work)
goto out;

if (rcode == RCODE_COMPLETE &&
lock_data[0] != cpu_to_be32(0x3f))
/* Somebody else is BM, let them do the work. */
lock_data[0] != cpu_to_be32(0x3f)) {

/* Somebody else is BM. Only act as IRM. */
if (local_id == irm_id)
allocate_broadcast_channel(card, generation);

goto out;
}

spin_lock_irqsave(&card->lock, flags);

Expand All @@ -282,19 +301,18 @@ fw_card_bm_work(struct work_struct *work)
* do a bus reset and pick the local node as
* root, and thus, IRM.
*/
new_root_id = local_node->node_id;
new_root_id = local_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
* less than 100ms since last bus reset. Reschedule
* this task 100ms from now.
* We weren't BM in the last generation, and the last
* bus reset is less than 125ms ago. Reschedule this job.
*/
spin_unlock_irqrestore(&card->lock, flags);
fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 10));
fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 8));
goto out;
}

Expand All @@ -310,7 +328,7 @@ fw_card_bm_work(struct work_struct *work)
* Either link_on is false, or we failed to read the
* config rom. In either case, pick another root.
*/
new_root_id = local_node->node_id;
new_root_id = local_id;
} else if (!root_device_is_running) {
/*
* If we haven't probed this device yet, bail out now
Expand All @@ -332,7 +350,7 @@ fw_card_bm_work(struct work_struct *work)
* successfully read the config rom, but it's not
* cycle master capable.
*/
new_root_id = local_node->node_id;
new_root_id = local_id;
}

pick_me:
Expand Down Expand Up @@ -363,25 +381,28 @@ fw_card_bm_work(struct work_struct *work)
card->index, new_root_id, gap_count);
fw_send_phy_config(card, new_root_id, generation, gap_count);
fw_core_initiate_bus_reset(card, 1);
/* Will allocate broadcast channel after the reset. */
} else {
if (local_id == irm_id)
allocate_broadcast_channel(card, generation);
}

out:
fw_node_put(root_node);
fw_node_put(local_node);
out_put_card:
fw_card_put(card);
}

static void
flush_timer_callback(unsigned long data)
static void flush_timer_callback(unsigned long data)
{
struct fw_card *card = (struct fw_card *)data;

fw_flush_transactions(card);
}

void
fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
struct device *device)
void fw_card_initialize(struct fw_card *card,
const struct fw_card_driver *driver,
struct device *device)
{
static atomic_t index = ATOMIC_INIT(-1);

Expand All @@ -406,13 +427,12 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
}
EXPORT_SYMBOL(fw_card_initialize);

int
fw_card_add(struct fw_card *card,
u32 max_receive, u32 link_speed, u64 guid)
int fw_card_add(struct fw_card *card,
u32 max_receive, u32 link_speed, u64 guid)
{
u32 *config_rom;
size_t length;
int err;
int ret;

card->max_receive = max_receive;
card->link_speed = link_speed;
Expand All @@ -423,13 +443,14 @@ fw_card_add(struct fw_card *card,
list_add_tail(&card->link, &card_list);
mutex_unlock(&card_mutex);

err = card->driver->enable(card, config_rom, length);
if (err < 0) {
ret = card->driver->enable(card, config_rom, length);
if (ret < 0) {
mutex_lock(&card_mutex);
list_del(&card->link);
mutex_unlock(&card_mutex);
}
return err;

return ret;
}
EXPORT_SYMBOL(fw_card_add);

Expand All @@ -442,23 +463,20 @@ EXPORT_SYMBOL(fw_card_add);
* dummy driver just fails all IO.
*/

static int
dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
{
BUG();
return -1;
}

static int
dummy_update_phy_reg(struct fw_card *card, int address,
int clear_bits, int set_bits)
static int dummy_update_phy_reg(struct fw_card *card, int address,
int clear_bits, int set_bits)
{
return -ENODEV;
}

static int
dummy_set_config_rom(struct fw_card *card,
u32 *config_rom, size_t length)
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
Expand All @@ -468,27 +486,23 @@ dummy_set_config_rom(struct fw_card *card,
return -1;
}

static void
dummy_send_request(struct fw_card *card, struct fw_packet *packet)
static void dummy_send_request(struct fw_card *card, struct fw_packet *packet)
{
packet->callback(packet, card, -ENODEV);
}

static void
dummy_send_response(struct fw_card *card, struct fw_packet *packet)
static void dummy_send_response(struct fw_card *card, struct fw_packet *packet)
{
packet->callback(packet, card, -ENODEV);
}

static int
dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet)
static int dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet)
{
return -ENOENT;
}

static int
dummy_enable_phys_dma(struct fw_card *card,
int node_id, int generation)
static int dummy_enable_phys_dma(struct fw_card *card,
int node_id, int generation)
{
return -ENODEV;
}
Expand All @@ -503,16 +517,14 @@ static struct fw_card_driver dummy_driver = {
.enable_phys_dma = dummy_enable_phys_dma,
};

void
fw_card_release(struct kref *kref)
void fw_card_release(struct kref *kref)
{
struct fw_card *card = container_of(kref, struct fw_card, kref);

complete(&card->done);
}

void
fw_core_remove_card(struct fw_card *card)
void fw_core_remove_card(struct fw_card *card)
{
card->driver->update_phy_reg(card, 4,
PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
Expand All @@ -536,8 +548,7 @@ fw_core_remove_card(struct fw_card *card)
}
EXPORT_SYMBOL(fw_core_remove_card);

int
fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
{
int reg = short_reset ? 5 : 1;
int bit = short_reset ? PHY_BUS_SHORT_RESET : PHY_BUS_RESET;
Expand Down
Loading

0 comments on commit febb02b

Please sign in to comment.