aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-06-10 02:26:28 -0400
committerClemens Ladisch <clemens@ladisch.de>2010-06-10 02:26:28 -0400
commit8e4b50f94e8c1435a3e0ece42b7f97bc857d0145 (patch)
treeaad5b85a0bf67b5a7bbd80e1dad2d2a2d9b85470 /drivers
parent446eba0d6896787b2f02f7a665838d32aa7b9d3f (diff)
firewire: core: add CSR SPLIT_TIMEOUT support
Implement the SPLIT_TIMEOUT registers. Besides being required by the spec, this is desirable for some IIDC devices and necessary for many audio devices to be able to increase the timeout from userspace. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firewire/core-card.c4
-rw-r--r--drivers/firewire/core-transaction.c76
2 files changed, 69 insertions, 11 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index 901435cdd5c2..d0f15c2f1e1d 100644
--- a/drivers/firewire/core-card.c
+++ b/drivers/firewire/core-card.c
@@ -428,6 +428,10 @@ void fw_card_initialize(struct fw_card *card,
428 card->device = device; 428 card->device = device;
429 card->current_tlabel = 0; 429 card->current_tlabel = 0;
430 card->tlabel_mask = 0; 430 card->tlabel_mask = 0;
431 card->split_timeout_hi = 0;
432 card->split_timeout_lo = 800 << 19;
433 card->split_timeout_cycles = 800;
434 card->split_timeout_jiffies = DIV_ROUND_UP(HZ, 10);
431 card->color = 0; 435 card->color = 0;
432 card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; 436 card->broadcast_channel = BROADCAST_CHANNEL_INITIAL;
433 437
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 0034229dfd14..9a7d3ec23f2b 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -339,7 +339,8 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
339 setup_timer(&t->split_timeout_timer, 339 setup_timer(&t->split_timeout_timer,
340 split_transaction_timeout_callback, (unsigned long)t); 340 split_transaction_timeout_callback, (unsigned long)t);
341 /* FIXME: start this timer later, relative to t->timestamp */ 341 /* FIXME: start this timer later, relative to t->timestamp */
342 mod_timer(&t->split_timeout_timer, jiffies + DIV_ROUND_UP(HZ, 10)); 342 mod_timer(&t->split_timeout_timer,
343 jiffies + card->split_timeout_jiffies);
343 t->callback = callback; 344 t->callback = callback;
344 t->callback_data = callback_data; 345 t->callback_data = callback_data;
345 346
@@ -673,11 +674,28 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header,
673} 674}
674EXPORT_SYMBOL(fw_fill_response); 675EXPORT_SYMBOL(fw_fill_response);
675 676
676static struct fw_request *allocate_request(struct fw_packet *p) 677static u32 compute_split_timeout_timestamp(struct fw_card *card,
678 u32 request_timestamp)
679{
680 unsigned int cycles;
681 u32 timestamp;
682
683 cycles = card->split_timeout_cycles;
684 cycles += request_timestamp & 0x1fff;
685
686 timestamp = request_timestamp & ~0x1fff;
687 timestamp += (cycles / 8000) << 13;
688 timestamp |= cycles % 8000;
689
690 return timestamp;
691}
692
693static struct fw_request *allocate_request(struct fw_card *card,
694 struct fw_packet *p)
677{ 695{
678 struct fw_request *request; 696 struct fw_request *request;
679 u32 *data, length; 697 u32 *data, length;
680 int request_tcode, t; 698 int request_tcode;
681 699
682 request_tcode = HEADER_GET_TCODE(p->header[0]); 700 request_tcode = HEADER_GET_TCODE(p->header[0]);
683 switch (request_tcode) { 701 switch (request_tcode) {
@@ -712,14 +730,9 @@ static struct fw_request *allocate_request(struct fw_packet *p)
712 if (request == NULL) 730 if (request == NULL)
713 return NULL; 731 return NULL;
714 732
715 t = (p->timestamp & 0x1fff) + 4000;
716 if (t >= 8000)
717 t = (p->timestamp & ~0x1fff) + 0x2000 + t - 8000;
718 else
719 t = (p->timestamp & ~0x1fff) + t;
720
721 request->response.speed = p->speed; 733 request->response.speed = p->speed;
722 request->response.timestamp = t; 734 request->response.timestamp =
735 compute_split_timeout_timestamp(card, p->timestamp);
723 request->response.generation = p->generation; 736 request->response.generation = p->generation;
724 request->response.ack = 0; 737 request->response.ack = 0;
725 request->response.callback = free_response_callback; 738 request->response.callback = free_response_callback;
@@ -845,7 +858,7 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
845 if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE) 858 if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
846 return; 859 return;
847 860
848 request = allocate_request(p); 861 request = allocate_request(card, p);
849 if (request == NULL) { 862 if (request == NULL) {
850 /* FIXME: send statically allocated busy packet. */ 863 /* FIXME: send statically allocated busy packet. */
851 return; 864 return;
@@ -993,6 +1006,19 @@ static u32 read_state_register(struct fw_card *card)
993 return 0; 1006 return 0;
994} 1007}
995 1008
1009static void update_split_timeout(struct fw_card *card)
1010{
1011 unsigned int cycles;
1012
1013 cycles = card->split_timeout_hi * 8000 + (card->split_timeout_lo >> 19);
1014
1015 cycles = max(cycles, 800u); /* minimum as per the spec */
1016 cycles = min(cycles, 3u * 8000u); /* maximum OHCI timeout */
1017
1018 card->split_timeout_cycles = cycles;
1019 card->split_timeout_jiffies = DIV_ROUND_UP(cycles * HZ, 8000);
1020}
1021
996static void handle_registers(struct fw_card *card, struct fw_request *request, 1022static void handle_registers(struct fw_card *card, struct fw_request *request,
997 int tcode, int destination, int source, int generation, 1023 int tcode, int destination, int source, int generation,
998 int speed, unsigned long long offset, 1024 int speed, unsigned long long offset,
@@ -1001,6 +1027,7 @@ static void handle_registers(struct fw_card *card, struct fw_request *request,
1001 int reg = offset & ~CSR_REGISTER_BASE; 1027 int reg = offset & ~CSR_REGISTER_BASE;
1002 __be32 *data = payload; 1028 __be32 *data = payload;
1003 int rcode = RCODE_COMPLETE; 1029 int rcode = RCODE_COMPLETE;
1030 unsigned long flags;
1004 1031
1005 switch (reg) { 1032 switch (reg) {
1006 case CSR_STATE_CLEAR: 1033 case CSR_STATE_CLEAR:
@@ -1039,6 +1066,33 @@ static void handle_registers(struct fw_card *card, struct fw_request *request,
1039 rcode = RCODE_TYPE_ERROR; 1066 rcode = RCODE_TYPE_ERROR;
1040 break; 1067 break;
1041 1068
1069 case CSR_SPLIT_TIMEOUT_HI:
1070 if (tcode == TCODE_READ_QUADLET_REQUEST) {
1071 *data = cpu_to_be32(card->split_timeout_hi);
1072 } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
1073 spin_lock_irqsave(&card->lock, flags);
1074 card->split_timeout_hi = be32_to_cpu(*data) & 7;
1075 update_split_timeout(card);
1076 spin_unlock_irqrestore(&card->lock, flags);
1077 } else {
1078 rcode = RCODE_TYPE_ERROR;
1079 }
1080 break;
1081
1082 case CSR_SPLIT_TIMEOUT_LO:
1083 if (tcode == TCODE_READ_QUADLET_REQUEST) {
1084 *data = cpu_to_be32(card->split_timeout_lo);
1085 } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
1086 spin_lock_irqsave(&card->lock, flags);
1087 card->split_timeout_lo =
1088 be32_to_cpu(*data) & 0xfff80000;
1089 update_split_timeout(card);
1090 spin_unlock_irqrestore(&card->lock, flags);
1091 } else {
1092 rcode = RCODE_TYPE_ERROR;
1093 }
1094 break;
1095
1042 case CSR_CYCLE_TIME: 1096 case CSR_CYCLE_TIME:
1043 if (TCODE_IS_READ_REQUEST(tcode) && length == 4) 1097 if (TCODE_IS_READ_REQUEST(tcode) && length == 4)
1044 *data = cpu_to_be32(card->driver-> 1098 *data = cpu_to_be32(card->driver->