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:
  ieee1394: schedule for removal
  firewire: core: use separate timeout for each transaction
  firewire: core: Fix tlabel exhaustion problem
  firewire: core: make transaction label allocation more robust
  firewire: core: clean up config ROM related defined constants
  ieee1394: mark char device files as not seekable
  firewire: cdev: mark char device files as not seekable
  firewire: ohci: cleanups and fix for nonstandard build without debug facility
  firewire: ohci: wait for PHY register accesses to complete
  firewire: ohci: fix up configuration of TI chips
  firewire: ohci: enable 1394a enhancements
  firewire: ohci: do not clear PHY interrupt status inadvertently
  firewire: ohci: add a function for reading PHY registers

Trivial conflicts in Documentation/feature-removal-schedule.txt
  • Loading branch information
Linus Torvalds committed May 27, 2010
2 parents a9a0aff + 3014420 commit 55ddf14
Show file tree
Hide file tree
Showing 11 changed files with 258 additions and 106 deletions.
10 changes: 10 additions & 0 deletions Documentation/feature-removal-schedule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -646,3 +646,13 @@ Who: Thomas Gleixner <tglx@linutronix.de>

----------------------------

What: old ieee1394 subsystem (CONFIG_IEEE1394)
When: 2.6.37
Files: drivers/ieee1394/ except init_ohci1394_dma.c
Why: superseded by drivers/firewire/ (CONFIG_FIREWIRE) which offers more
features, better performance, and better security, all with smaller
and more modern code base
Who: Stefan Richter <stefanr@s5r6.in-berlin.de>

----------------------------

22 changes: 6 additions & 16 deletions drivers/firewire/core-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/workqueue.h>

#include <asm/atomic.h>
Expand Down Expand Up @@ -63,7 +62,7 @@ static size_t config_rom_length = 1 + 4 + 1 + 1;
#define BIB_CRC(v) ((v) << 0)
#define BIB_CRC_LENGTH(v) ((v) << 16)
#define BIB_INFO_LENGTH(v) ((v) << 24)

#define BIB_BUS_NAME 0x31333934 /* "1394" */
#define BIB_LINK_SPEED(v) ((v) << 0)
#define BIB_GENERATION(v) ((v) << 4)
#define BIB_MAX_ROM(v) ((v) << 8)
Expand All @@ -73,7 +72,8 @@ static size_t config_rom_length = 1 + 4 + 1 + 1;
#define BIB_BMC ((1) << 28)
#define BIB_ISC ((1) << 29)
#define BIB_CMC ((1) << 30)
#define BIB_IMC ((1) << 31)
#define BIB_IRMC ((1) << 31)
#define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */

static void generate_config_rom(struct fw_card *card, __be32 *config_rom)
{
Expand All @@ -91,18 +91,18 @@ static void generate_config_rom(struct fw_card *card, __be32 *config_rom)

config_rom[0] = cpu_to_be32(
BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0));
config_rom[1] = cpu_to_be32(0x31333934);
config_rom[1] = cpu_to_be32(BIB_BUS_NAME);
config_rom[2] = cpu_to_be32(
BIB_LINK_SPEED(card->link_speed) |
BIB_GENERATION(card->config_rom_generation++ % 14 + 2) |
BIB_MAX_ROM(2) |
BIB_MAX_RECEIVE(card->max_receive) |
BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC);
BIB_BMC | BIB_ISC | BIB_CMC | BIB_IRMC);
config_rom[3] = cpu_to_be32(card->guid >> 32);
config_rom[4] = cpu_to_be32(card->guid);

/* Generate root directory. */
config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */
config_rom[6] = cpu_to_be32(NODE_CAPABILITIES);
i = 7;
j = 7 + descriptor_count;

Expand Down Expand Up @@ -407,13 +407,6 @@ static void fw_card_bm_work(struct work_struct *work)
fw_card_put(card);
}

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)
Expand All @@ -432,8 +425,6 @@ void fw_card_initialize(struct fw_card *card,
init_completion(&card->done);
INIT_LIST_HEAD(&card->transaction_list);
spin_lock_init(&card->lock);
setup_timer(&card->flush_timer,
flush_timer_callback, (unsigned long)card);

card->local_node = NULL;

Expand Down Expand Up @@ -558,7 +549,6 @@ void fw_core_remove_card(struct fw_card *card)
wait_for_completion(&card->done);

WARN_ON(!list_empty(&card->transaction_list));
del_timer_sync(&card->flush_timer);
}
EXPORT_SYMBOL(fw_core_remove_card);

Expand Down
8 changes: 4 additions & 4 deletions drivers/firewire/core-cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
list_add_tail(&client->link, &device->client_list);
mutex_unlock(&device->client_list_mutex);

return 0;
return nonseekable_open(inode, file);
}

static void queue_event(struct client *client, struct event *event,
Expand Down Expand Up @@ -1496,13 +1496,13 @@ static unsigned int fw_device_op_poll(struct file *file, poll_table * pt)

const struct file_operations fw_device_ops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.open = fw_device_op_open,
.read = fw_device_op_read,
.unlocked_ioctl = fw_device_op_ioctl,
.poll = fw_device_op_poll,
.release = fw_device_op_release,
.mmap = fw_device_op_mmap,

.release = fw_device_op_release,
.poll = fw_device_op_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = fw_device_op_compat_ioctl,
#endif
Expand Down
96 changes: 57 additions & 39 deletions drivers/firewire/core-transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,15 @@ static int close_transaction(struct fw_transaction *transaction,
spin_lock_irqsave(&card->lock, flags);
list_for_each_entry(t, &card->transaction_list, link) {
if (t == transaction) {
list_del(&t->link);
list_del_init(&t->link);
card->tlabel_mask &= ~(1ULL << t->tlabel);
break;
}
}
spin_unlock_irqrestore(&card->lock, flags);

if (&t->link != &card->transaction_list) {
del_timer_sync(&t->split_timeout_timer);
t->callback(card, rcode, NULL, 0, t->callback_data);
return 0;
}
Expand Down Expand Up @@ -121,6 +122,31 @@ int fw_cancel_transaction(struct fw_card *card,
}
EXPORT_SYMBOL(fw_cancel_transaction);

static void split_transaction_timeout_callback(unsigned long data)
{
struct fw_transaction *t = (struct fw_transaction *)data;
struct fw_card *card = t->card;
unsigned long flags;

spin_lock_irqsave(&card->lock, flags);
if (list_empty(&t->link)) {
spin_unlock_irqrestore(&card->lock, flags);
return;
}
list_del(&t->link);
card->tlabel_mask &= ~(1ULL << t->tlabel);
spin_unlock_irqrestore(&card->lock, flags);

card->driver->cancel_packet(card, &t->packet);

/*
* At this point cancel_packet will never call the transaction
* callback, since we just took the transaction out of the list.
* So do it here.
*/
t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data);
}

static void transmit_complete_callback(struct fw_packet *packet,
struct fw_card *card, int status)
{
Expand Down Expand Up @@ -229,6 +255,23 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
packet->payload_mapped = false;
}

static int allocate_tlabel(struct fw_card *card)
{
int tlabel;

tlabel = card->current_tlabel;
while (card->tlabel_mask & (1ULL << tlabel)) {
tlabel = (tlabel + 1) & 0x3f;
if (tlabel == card->current_tlabel)
return -EBUSY;
}

card->current_tlabel = (tlabel + 1) & 0x3f;
card->tlabel_mask |= 1ULL << tlabel;

return tlabel;
}

/**
* This function provides low-level access to the IEEE1394 transaction
* logic. Most C programs would use either fw_read(), fw_write() or
Expand Down Expand Up @@ -276,32 +319,27 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
unsigned long flags;
int tlabel;

/*
* 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.
*/

spin_lock_irqsave(&card->lock, flags);

tlabel = card->current_tlabel;
if (card->tlabel_mask & (1ULL << tlabel)) {
tlabel = allocate_tlabel(card);
if (tlabel < 0) {
spin_unlock_irqrestore(&card->lock, flags);
callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data);
return;
}

card->current_tlabel = (card->current_tlabel + 1) & 0x3f;
card->tlabel_mask |= (1ULL << tlabel);

t->node_id = destination_id;
t->tlabel = tlabel;
t->card = card;
setup_timer(&t->split_timeout_timer,
split_transaction_timeout_callback, (unsigned long)t);
/* FIXME: start this timer later, relative to t->timestamp */
mod_timer(&t->split_timeout_timer, jiffies + DIV_ROUND_UP(HZ, 10));
t->callback = callback;
t->callback_data = callback_data;

Expand Down Expand Up @@ -347,11 +385,13 @@ int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
struct transaction_callback_data d;
struct fw_transaction t;

init_timer_on_stack(&t.split_timeout_timer);
init_completion(&d.done);
d.payload = payload;
fw_send_request(card, &t, tcode, destination_id, generation, speed,
offset, payload, length, transaction_callback, &d);
wait_for_completion(&d.done);
destroy_timer_on_stack(&t.split_timeout_timer);

return d.rcode;
}
Expand Down Expand Up @@ -394,30 +434,6 @@ void fw_send_phy_config(struct fw_card *card,
mutex_unlock(&phy_config_mutex);
}

void fw_flush_transactions(struct fw_card *card)
{
struct fw_transaction *t, *next;
struct list_head list;
unsigned long flags;

INIT_LIST_HEAD(&list);
spin_lock_irqsave(&card->lock, flags);
list_splice_init(&card->transaction_list, &list);
card->tlabel_mask = 0;
spin_unlock_irqrestore(&card->lock, flags);

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
* transaction callback, since we just took all the
* transactions out of the list. So do it here.
*/
t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data);
}
}

static struct fw_address_handler *lookup_overlapping_address_handler(
struct list_head *list, unsigned long long offset, size_t length)
{
Expand Down Expand Up @@ -827,8 +843,8 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
spin_lock_irqsave(&card->lock, flags);
list_for_each_entry(t, &card->transaction_list, link) {
if (t->node_id == source && t->tlabel == tlabel) {
list_del(&t->link);
card->tlabel_mask &= ~(1 << t->tlabel);
list_del_init(&t->link);
card->tlabel_mask &= ~(1ULL << t->tlabel);
break;
}
}
Expand Down Expand Up @@ -869,6 +885,8 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
break;
}

del_timer_sync(&t->split_timeout_timer);

/*
* The response handler may be executed while the request handler
* is still pending. Cancel the request handler.
Expand Down
6 changes: 5 additions & 1 deletion drivers/firewire/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ struct fw_packet;
#define PHY_LINK_ACTIVE 0x80
#define PHY_CONTENDER 0x40
#define PHY_BUS_RESET 0x40
#define PHY_EXTENDED_REGISTERS 0xe0
#define PHY_BUS_SHORT_RESET 0x40
#define PHY_INT_STATUS_BITS 0x3c
#define PHY_ENABLE_ACCEL 0x02
#define PHY_ENABLE_MULTI 0x01
#define PHY_PAGE_SELECT 0xe0

#define BANDWIDTH_AVAILABLE_INITIAL 4915
#define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31)
Expand Down Expand Up @@ -215,7 +220,6 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *request);
void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet);
void fw_fill_response(struct fw_packet *response, u32 *request_header,
int rcode, void *payload, size_t length);
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);

Expand Down
Loading

0 comments on commit 55ddf14

Please sign in to comment.