Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 206808
b: refs/heads/master
c: 8e4b50f
h: refs/heads/master
v: v3
  • Loading branch information
Clemens Ladisch committed Jun 10, 2010
1 parent a64bbad commit 73aabcc
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 446eba0d6896787b2f02f7a665838d32aa7b9d3f
refs/heads/master: 8e4b50f94e8c1435a3e0ece42b7f97bc857d0145
4 changes: 4 additions & 0 deletions trunk/drivers/firewire/core-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,10 @@ void fw_card_initialize(struct fw_card *card,
card->device = device;
card->current_tlabel = 0;
card->tlabel_mask = 0;
card->split_timeout_hi = 0;
card->split_timeout_lo = 800 << 19;
card->split_timeout_cycles = 800;
card->split_timeout_jiffies = DIV_ROUND_UP(HZ, 10);
card->color = 0;
card->broadcast_channel = BROADCAST_CHANNEL_INITIAL;

Expand Down
76 changes: 65 additions & 11 deletions trunk/drivers/firewire/core-transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
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));
mod_timer(&t->split_timeout_timer,
jiffies + card->split_timeout_jiffies);
t->callback = callback;
t->callback_data = callback_data;

Expand Down Expand Up @@ -673,11 +674,28 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header,
}
EXPORT_SYMBOL(fw_fill_response);

static struct fw_request *allocate_request(struct fw_packet *p)
static u32 compute_split_timeout_timestamp(struct fw_card *card,
u32 request_timestamp)
{
unsigned int cycles;
u32 timestamp;

cycles = card->split_timeout_cycles;
cycles += request_timestamp & 0x1fff;

timestamp = request_timestamp & ~0x1fff;
timestamp += (cycles / 8000) << 13;
timestamp |= cycles % 8000;

return timestamp;
}

static struct fw_request *allocate_request(struct fw_card *card,
struct fw_packet *p)
{
struct fw_request *request;
u32 *data, length;
int request_tcode, t;
int request_tcode;

request_tcode = HEADER_GET_TCODE(p->header[0]);
switch (request_tcode) {
Expand Down Expand Up @@ -712,14 +730,9 @@ static struct fw_request *allocate_request(struct fw_packet *p)
if (request == NULL)
return NULL;

t = (p->timestamp & 0x1fff) + 4000;
if (t >= 8000)
t = (p->timestamp & ~0x1fff) + 0x2000 + t - 8000;
else
t = (p->timestamp & ~0x1fff) + t;

request->response.speed = p->speed;
request->response.timestamp = t;
request->response.timestamp =
compute_split_timeout_timestamp(card, p->timestamp);
request->response.generation = p->generation;
request->response.ack = 0;
request->response.callback = free_response_callback;
Expand Down Expand Up @@ -845,7 +858,7 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
return;

request = allocate_request(p);
request = allocate_request(card, p);
if (request == NULL) {
/* FIXME: send statically allocated busy packet. */
return;
Expand Down Expand Up @@ -993,6 +1006,19 @@ static u32 read_state_register(struct fw_card *card)
return 0;
}

static void update_split_timeout(struct fw_card *card)
{
unsigned int cycles;

cycles = card->split_timeout_hi * 8000 + (card->split_timeout_lo >> 19);

cycles = max(cycles, 800u); /* minimum as per the spec */
cycles = min(cycles, 3u * 8000u); /* maximum OHCI timeout */

card->split_timeout_cycles = cycles;
card->split_timeout_jiffies = DIV_ROUND_UP(cycles * HZ, 8000);
}

static void handle_registers(struct fw_card *card, struct fw_request *request,
int tcode, int destination, int source, int generation,
int speed, unsigned long long offset,
Expand All @@ -1001,6 +1027,7 @@ static void handle_registers(struct fw_card *card, struct fw_request *request,
int reg = offset & ~CSR_REGISTER_BASE;
__be32 *data = payload;
int rcode = RCODE_COMPLETE;
unsigned long flags;

switch (reg) {
case CSR_STATE_CLEAR:
Expand Down Expand Up @@ -1039,6 +1066,33 @@ static void handle_registers(struct fw_card *card, struct fw_request *request,
rcode = RCODE_TYPE_ERROR;
break;

case CSR_SPLIT_TIMEOUT_HI:
if (tcode == TCODE_READ_QUADLET_REQUEST) {
*data = cpu_to_be32(card->split_timeout_hi);
} else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
spin_lock_irqsave(&card->lock, flags);
card->split_timeout_hi = be32_to_cpu(*data) & 7;
update_split_timeout(card);
spin_unlock_irqrestore(&card->lock, flags);
} else {
rcode = RCODE_TYPE_ERROR;
}
break;

case CSR_SPLIT_TIMEOUT_LO:
if (tcode == TCODE_READ_QUADLET_REQUEST) {
*data = cpu_to_be32(card->split_timeout_lo);
} else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
spin_lock_irqsave(&card->lock, flags);
card->split_timeout_lo =
be32_to_cpu(*data) & 0xfff80000;
update_split_timeout(card);
spin_unlock_irqrestore(&card->lock, flags);
} else {
rcode = RCODE_TYPE_ERROR;
}
break;

case CSR_CYCLE_TIME:
if (TCODE_IS_READ_REQUEST(tcode) && length == 4)
*data = cpu_to_be32(card->driver->
Expand Down
5 changes: 5 additions & 0 deletions trunk/include/linux/firewire.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ struct fw_card {
struct list_head transaction_list;
unsigned long reset_jiffies;

u32 split_timeout_hi;
u32 split_timeout_lo;
unsigned int split_timeout_cycles;
unsigned int split_timeout_jiffies;

unsigned long long guid;
unsigned max_receive;
int link_speed;
Expand Down

0 comments on commit 73aabcc

Please sign in to comment.