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:
  firewire: sbp2: parallelize login, reconnect, logout
  firewire: sbp2: octlet AT payloads can be stack-allocated
  firewire: sbp2: omit Scsi_Host lock from queuecommand
  firewire: core: use non-reentrant workqueue with rescuer
  firewire: optimize iso queueing by setting wake only after the last packet
  firewire: octlet AT payloads can be stack-allocated
  firewire: ohci: optimize find_branch_descriptor()
  firewire: ohci: avoid separate DMA mapping for small AT payloads
  firewire: ohci: do not start DMA contexts before link is enabled
  • Loading branch information
torvalds committed May 21, 2011
2 parents c21fd1a + 105e53f commit dcb4a1f
Show file tree
Hide file tree
Showing 16 changed files with 140 additions and 117 deletions.
27 changes: 16 additions & 11 deletions drivers/firewire/core-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ void fw_schedule_bus_reset(struct fw_card *card, bool delayed, bool short_reset)

/* Use an arbitrary short delay to combine multiple reset requests. */
fw_card_get(card);
if (!schedule_delayed_work(&card->br_work,
delayed ? DIV_ROUND_UP(HZ, 100) : 0))
if (!queue_delayed_work(fw_workqueue, &card->br_work,
delayed ? DIV_ROUND_UP(HZ, 100) : 0))
fw_card_put(card);
}
EXPORT_SYMBOL(fw_schedule_bus_reset);
Expand All @@ -241,7 +241,7 @@ static void br_work(struct work_struct *work)
/* Delay for 2s after last reset per IEEE 1394 clause 8.2.1. */
if (card->reset_jiffies != 0 &&
time_before64(get_jiffies_64(), card->reset_jiffies + 2 * HZ)) {
if (!schedule_delayed_work(&card->br_work, 2 * HZ))
if (!queue_delayed_work(fw_workqueue, &card->br_work, 2 * HZ))
fw_card_put(card);
return;
}
Expand All @@ -258,8 +258,7 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation)

if (!card->broadcast_channel_allocated) {
fw_iso_resource_manage(card, generation, 1ULL << 31,
&channel, &bandwidth, true,
card->bm_transaction_data);
&channel, &bandwidth, true);
if (channel != 31) {
fw_notify("failed to allocate broadcast channel\n");
return;
Expand Down Expand Up @@ -294,6 +293,7 @@ static void bm_work(struct work_struct *work)
bool root_device_is_cmc;
bool irm_is_1394_1995_only;
bool keep_this_irm;
__be32 transaction_data[2];

spin_lock_irq(&card->lock);

Expand Down Expand Up @@ -355,21 +355,21 @@ static void bm_work(struct work_struct *work)
goto pick_me;
}

card->bm_transaction_data[0] = cpu_to_be32(0x3f);
card->bm_transaction_data[1] = cpu_to_be32(local_id);
transaction_data[0] = cpu_to_be32(0x3f);
transaction_data[1] = cpu_to_be32(local_id);

spin_unlock_irq(&card->lock);

rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
irm_id, generation, SCODE_100,
CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
card->bm_transaction_data, 8);
transaction_data, 8);

if (rcode == RCODE_GENERATION)
/* Another bus reset, BM work has been rescheduled. */
goto out;

bm_id = be32_to_cpu(card->bm_transaction_data[0]);
bm_id = be32_to_cpu(transaction_data[0]);

spin_lock_irq(&card->lock);
if (rcode == RCODE_COMPLETE && generation == card->generation)
Expand Down Expand Up @@ -490,11 +490,11 @@ static void bm_work(struct work_struct *work)
/*
* Make sure that the cycle master sends cycle start packets.
*/
card->bm_transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
root_id, generation, SCODE_100,
CSR_REGISTER_BASE + CSR_STATE_SET,
card->bm_transaction_data, 4);
transaction_data, 4);
if (rcode == RCODE_GENERATION)
goto out;
}
Expand Down Expand Up @@ -630,6 +630,10 @@ static int dummy_queue_iso(struct fw_iso_context *ctx, struct fw_iso_packet *p,
return -ENODEV;
}

static void dummy_flush_queue_iso(struct fw_iso_context *ctx)
{
}

static const struct fw_card_driver dummy_driver_template = {
.read_phy_reg = dummy_read_phy_reg,
.update_phy_reg = dummy_update_phy_reg,
Expand All @@ -641,6 +645,7 @@ static const struct fw_card_driver dummy_driver_template = {
.start_iso = dummy_start_iso,
.set_iso_channels = dummy_set_iso_channels,
.queue_iso = dummy_queue_iso,
.flush_queue_iso = dummy_flush_queue_iso,
};

void fw_card_release(struct kref *kref)
Expand Down
7 changes: 3 additions & 4 deletions drivers/firewire/core-cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ struct iso_resource {
int generation;
u64 channels;
s32 bandwidth;
__be32 transaction_data[2];
struct iso_resource_event *e_alloc, *e_dealloc;
};

Expand All @@ -150,7 +149,7 @@ static void release_iso_resource(struct client *, struct client_resource *);
static void schedule_iso_resource(struct iso_resource *r, unsigned long delay)
{
client_get(r->client);
if (!schedule_delayed_work(&r->work, delay))
if (!queue_delayed_work(fw_workqueue, &r->work, delay))
client_put(r->client);
}

Expand Down Expand Up @@ -1108,6 +1107,7 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
payload += u.packet.payload_length;
count++;
}
fw_iso_context_queue_flush(ctx);

a->size -= uptr_to_u64(p) - a->packets;
a->packets = uptr_to_u64(p);
Expand Down Expand Up @@ -1229,8 +1229,7 @@ static void iso_resource_work(struct work_struct *work)
r->channels, &channel, &bandwidth,
todo == ISO_RES_ALLOC ||
todo == ISO_RES_REALLOC ||
todo == ISO_RES_ALLOC_ONCE,
r->transaction_data);
todo == ISO_RES_ALLOC_ONCE);
/*
* Is this generation outdated already? As long as this resource sticks
* in the idr, it will be scheduled again for a newer generation or at
Expand Down
31 changes: 20 additions & 11 deletions drivers/firewire/core-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,15 @@ struct fw_device *fw_device_get_by_devt(dev_t devt)
return device;
}

struct workqueue_struct *fw_workqueue;
EXPORT_SYMBOL(fw_workqueue);

static void fw_schedule_device_work(struct fw_device *device,
unsigned long delay)
{
queue_delayed_work(fw_workqueue, &device->work, delay);
}

/*
* These defines control the retry behavior for reading the config
* rom. It shouldn't be necessary to tweak these; if the device
Expand All @@ -750,7 +759,7 @@ static void fw_device_shutdown(struct work_struct *work)
if (time_before64(get_jiffies_64(),
device->card->reset_jiffies + SHUTDOWN_DELAY)
&& !list_empty(&device->card->link)) {
schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
fw_schedule_device_work(device, SHUTDOWN_DELAY);
return;
}

Expand Down Expand Up @@ -862,7 +871,7 @@ static int lookup_existing_device(struct device *dev, void *data)
fw_notify("rediscovered device %s\n", dev_name(dev));

PREPARE_DELAYED_WORK(&old->work, fw_device_update);
schedule_delayed_work(&old->work, 0);
fw_schedule_device_work(old, 0);

if (current_node == card->root_node)
fw_schedule_bm_work(card, 0);
Expand Down Expand Up @@ -953,7 +962,7 @@ static void fw_device_init(struct work_struct *work)
if (device->config_rom_retries < MAX_RETRIES &&
atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
device->config_rom_retries++;
schedule_delayed_work(&device->work, RETRY_DELAY);
fw_schedule_device_work(device, RETRY_DELAY);
} else {
if (device->node->link_on)
fw_notify("giving up on config rom for node id %x\n",
Expand Down Expand Up @@ -1019,7 +1028,7 @@ static void fw_device_init(struct work_struct *work)
FW_DEVICE_INITIALIZING,
FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
fw_schedule_device_work(device, SHUTDOWN_DELAY);
} else {
if (device->config_rom_retries)
fw_notify("created device %s: GUID %08x%08x, S%d00, "
Expand Down Expand Up @@ -1098,7 +1107,7 @@ static void fw_device_refresh(struct work_struct *work)
if (device->config_rom_retries < MAX_RETRIES / 2 &&
atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
device->config_rom_retries++;
schedule_delayed_work(&device->work, RETRY_DELAY / 2);
fw_schedule_device_work(device, RETRY_DELAY / 2);

return;
}
Expand Down Expand Up @@ -1131,7 +1140,7 @@ static void fw_device_refresh(struct work_struct *work)
if (device->config_rom_retries < MAX_RETRIES &&
atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
device->config_rom_retries++;
schedule_delayed_work(&device->work, RETRY_DELAY);
fw_schedule_device_work(device, RETRY_DELAY);

return;
}
Expand All @@ -1158,7 +1167,7 @@ static void fw_device_refresh(struct work_struct *work)
gone:
atomic_set(&device->state, FW_DEVICE_GONE);
PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
fw_schedule_device_work(device, SHUTDOWN_DELAY);
out:
if (node_id == card->root_node->node_id)
fw_schedule_bm_work(card, 0);
Expand Down Expand Up @@ -1214,7 +1223,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
* 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);
fw_schedule_device_work(device, INITIAL_DELAY);
break;

case FW_NODE_INITIATED_RESET:
Expand All @@ -1230,7 +1239,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
FW_DEVICE_RUNNING,
FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) {
PREPARE_DELAYED_WORK(&device->work, fw_device_refresh);
schedule_delayed_work(&device->work,
fw_schedule_device_work(device,
device->is_local ? 0 : INITIAL_DELAY);
}
break;
Expand All @@ -1245,7 +1254,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
device->generation = card->generation;
if (atomic_read(&device->state) == FW_DEVICE_RUNNING) {
PREPARE_DELAYED_WORK(&device->work, fw_device_update);
schedule_delayed_work(&device->work, 0);
fw_schedule_device_work(device, 0);
}
break;

Expand All @@ -1270,7 +1279,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
if (atomic_xchg(&device->state,
FW_DEVICE_GONE) == FW_DEVICE_RUNNING) {
PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
schedule_delayed_work(&device->work,
fw_schedule_device_work(device,
list_empty(&card->link) ? 0 : SHUTDOWN_DELAY);
}
break;
Expand Down
27 changes: 17 additions & 10 deletions drivers/firewire/core-iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ int fw_iso_context_queue(struct fw_iso_context *ctx,
}
EXPORT_SYMBOL(fw_iso_context_queue);

void fw_iso_context_queue_flush(struct fw_iso_context *ctx)
{
ctx->card->driver->flush_queue_iso(ctx);
}
EXPORT_SYMBOL(fw_iso_context_queue_flush);

int fw_iso_context_stop(struct fw_iso_context *ctx)
{
return ctx->card->driver->stop_iso(ctx);
Expand All @@ -196,9 +202,10 @@ EXPORT_SYMBOL(fw_iso_context_stop);
*/

static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
int bandwidth, bool allocate, __be32 data[2])
int bandwidth, bool allocate)
{
int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
__be32 data[2];

/*
* On a 1394a IRM with low contention, try < 1 is enough.
Expand Down Expand Up @@ -233,9 +240,10 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
}

static int manage_channel(struct fw_card *card, int irm_id, int generation,
u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
u32 channels_mask, u64 offset, bool allocate)
{
__be32 bit, all, old;
__be32 data[2];
int channel, ret = -EIO, retry = 5;

old = all = allocate ? cpu_to_be32(~0) : 0;
Expand Down Expand Up @@ -284,7 +292,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
}

static void deallocate_channel(struct fw_card *card, int irm_id,
int generation, int channel, __be32 buffer[2])
int generation, int channel)
{
u32 mask;
u64 offset;
Expand All @@ -293,7 +301,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id,
offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;

manage_channel(card, irm_id, generation, mask, offset, false, buffer);
manage_channel(card, irm_id, generation, mask, offset, false);
}

/**
Expand Down Expand Up @@ -322,7 +330,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id,
*/
void fw_iso_resource_manage(struct fw_card *card, int generation,
u64 channels_mask, int *channel, int *bandwidth,
bool allocate, __be32 buffer[2])
bool allocate)
{
u32 channels_hi = channels_mask; /* channels 31...0 */
u32 channels_lo = channels_mask >> 32; /* channels 63...32 */
Expand All @@ -335,11 +343,11 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
if (channels_hi)
c = manage_channel(card, irm_id, generation, channels_hi,
CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI,
allocate, buffer);
allocate);
if (channels_lo && c < 0) {
c = manage_channel(card, irm_id, generation, channels_lo,
CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO,
allocate, buffer);
allocate);
if (c >= 0)
c += 32;
}
Expand All @@ -351,14 +359,13 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
if (*bandwidth == 0)
return;

ret = manage_bandwidth(card, irm_id, generation, *bandwidth,
allocate, buffer);
ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
if (ret < 0)
*bandwidth = 0;

if (allocate && ret < 0) {
if (c >= 0)
deallocate_channel(card, irm_id, generation, c, buffer);
deallocate_channel(card, irm_id, generation, c);
*channel = ret;
}
}
Expand Down
Loading

0 comments on commit dcb4a1f

Please sign in to comment.