diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 13:22:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 13:22:06 -0400 |
commit | 55ddf14b04bfe5afaab892a8fb12164b803f1dd5 (patch) | |
tree | fd6e6f0b9508628fca8d0cadd4ece199201991b2 /drivers/firewire | |
parent | a9a0aff5b56d4c40288c000ff09c3f238b6b6fec (diff) | |
parent | 3014420b6b5d0a6483cf5e56c10df180a33e957e (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/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
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/core-card.c | 22 | ||||
-rw-r--r-- | drivers/firewire/core-cdev.c | 8 | ||||
-rw-r--r-- | drivers/firewire/core-transaction.c | 96 | ||||
-rw-r--r-- | drivers/firewire/core.h | 6 | ||||
-rw-r--r-- | drivers/firewire/ohci.c | 188 | ||||
-rw-r--r-- | drivers/firewire/ohci.h | 10 |
6 files changed, 235 insertions, 95 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 5045156c5313..9dcb30466ec0 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/timer.h> | ||
34 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
35 | 34 | ||
36 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
@@ -63,7 +62,7 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; | |||
63 | #define BIB_CRC(v) ((v) << 0) | 62 | #define BIB_CRC(v) ((v) << 0) |
64 | #define BIB_CRC_LENGTH(v) ((v) << 16) | 63 | #define BIB_CRC_LENGTH(v) ((v) << 16) |
65 | #define BIB_INFO_LENGTH(v) ((v) << 24) | 64 | #define BIB_INFO_LENGTH(v) ((v) << 24) |
66 | 65 | #define BIB_BUS_NAME 0x31333934 /* "1394" */ | |
67 | #define BIB_LINK_SPEED(v) ((v) << 0) | 66 | #define BIB_LINK_SPEED(v) ((v) << 0) |
68 | #define BIB_GENERATION(v) ((v) << 4) | 67 | #define BIB_GENERATION(v) ((v) << 4) |
69 | #define BIB_MAX_ROM(v) ((v) << 8) | 68 | #define BIB_MAX_ROM(v) ((v) << 8) |
@@ -73,7 +72,8 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; | |||
73 | #define BIB_BMC ((1) << 28) | 72 | #define BIB_BMC ((1) << 28) |
74 | #define BIB_ISC ((1) << 29) | 73 | #define BIB_ISC ((1) << 29) |
75 | #define BIB_CMC ((1) << 30) | 74 | #define BIB_CMC ((1) << 30) |
76 | #define BIB_IMC ((1) << 31) | 75 | #define BIB_IRMC ((1) << 31) |
76 | #define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */ | ||
77 | 77 | ||
78 | static void generate_config_rom(struct fw_card *card, __be32 *config_rom) | 78 | static void generate_config_rom(struct fw_card *card, __be32 *config_rom) |
79 | { | 79 | { |
@@ -91,18 +91,18 @@ static void generate_config_rom(struct fw_card *card, __be32 *config_rom) | |||
91 | 91 | ||
92 | config_rom[0] = cpu_to_be32( | 92 | config_rom[0] = cpu_to_be32( |
93 | BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0)); | 93 | BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0)); |
94 | config_rom[1] = cpu_to_be32(0x31333934); | 94 | config_rom[1] = cpu_to_be32(BIB_BUS_NAME); |
95 | config_rom[2] = cpu_to_be32( | 95 | config_rom[2] = cpu_to_be32( |
96 | BIB_LINK_SPEED(card->link_speed) | | 96 | BIB_LINK_SPEED(card->link_speed) | |
97 | BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | | 97 | BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | |
98 | BIB_MAX_ROM(2) | | 98 | BIB_MAX_ROM(2) | |
99 | BIB_MAX_RECEIVE(card->max_receive) | | 99 | BIB_MAX_RECEIVE(card->max_receive) | |
100 | BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC); | 100 | BIB_BMC | BIB_ISC | BIB_CMC | BIB_IRMC); |
101 | config_rom[3] = cpu_to_be32(card->guid >> 32); | 101 | config_rom[3] = cpu_to_be32(card->guid >> 32); |
102 | config_rom[4] = cpu_to_be32(card->guid); | 102 | config_rom[4] = cpu_to_be32(card->guid); |
103 | 103 | ||
104 | /* Generate root directory. */ | 104 | /* Generate root directory. */ |
105 | config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */ | 105 | config_rom[6] = cpu_to_be32(NODE_CAPABILITIES); |
106 | i = 7; | 106 | i = 7; |
107 | j = 7 + descriptor_count; | 107 | j = 7 + descriptor_count; |
108 | 108 | ||
@@ -407,13 +407,6 @@ static void fw_card_bm_work(struct work_struct *work) | |||
407 | fw_card_put(card); | 407 | fw_card_put(card); |
408 | } | 408 | } |
409 | 409 | ||
410 | static void flush_timer_callback(unsigned long data) | ||
411 | { | ||
412 | struct fw_card *card = (struct fw_card *)data; | ||
413 | |||
414 | fw_flush_transactions(card); | ||
415 | } | ||
416 | |||
417 | void fw_card_initialize(struct fw_card *card, | 410 | void fw_card_initialize(struct fw_card *card, |
418 | const struct fw_card_driver *driver, | 411 | const struct fw_card_driver *driver, |
419 | struct device *device) | 412 | struct device *device) |
@@ -432,8 +425,6 @@ void fw_card_initialize(struct fw_card *card, | |||
432 | init_completion(&card->done); | 425 | init_completion(&card->done); |
433 | INIT_LIST_HEAD(&card->transaction_list); | 426 | INIT_LIST_HEAD(&card->transaction_list); |
434 | spin_lock_init(&card->lock); | 427 | spin_lock_init(&card->lock); |
435 | setup_timer(&card->flush_timer, | ||
436 | flush_timer_callback, (unsigned long)card); | ||
437 | 428 | ||
438 | card->local_node = NULL; | 429 | card->local_node = NULL; |
439 | 430 | ||
@@ -558,7 +549,6 @@ void fw_core_remove_card(struct fw_card *card) | |||
558 | wait_for_completion(&card->done); | 549 | wait_for_completion(&card->done); |
559 | 550 | ||
560 | WARN_ON(!list_empty(&card->transaction_list)); | 551 | WARN_ON(!list_empty(&card->transaction_list)); |
561 | del_timer_sync(&card->flush_timer); | ||
562 | } | 552 | } |
563 | EXPORT_SYMBOL(fw_core_remove_card); | 553 | EXPORT_SYMBOL(fw_core_remove_card); |
564 | 554 | ||
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 14a34d99eea2..5bf106b9d791 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
@@ -227,7 +227,7 @@ static int fw_device_op_open(struct inode *inode, struct file *file) | |||
227 | list_add_tail(&client->link, &device->client_list); | 227 | list_add_tail(&client->link, &device->client_list); |
228 | mutex_unlock(&device->client_list_mutex); | 228 | mutex_unlock(&device->client_list_mutex); |
229 | 229 | ||
230 | return 0; | 230 | return nonseekable_open(inode, file); |
231 | } | 231 | } |
232 | 232 | ||
233 | static void queue_event(struct client *client, struct event *event, | 233 | static void queue_event(struct client *client, struct event *event, |
@@ -1496,13 +1496,13 @@ static unsigned int fw_device_op_poll(struct file *file, poll_table * pt) | |||
1496 | 1496 | ||
1497 | const struct file_operations fw_device_ops = { | 1497 | const struct file_operations fw_device_ops = { |
1498 | .owner = THIS_MODULE, | 1498 | .owner = THIS_MODULE, |
1499 | .llseek = no_llseek, | ||
1499 | .open = fw_device_op_open, | 1500 | .open = fw_device_op_open, |
1500 | .read = fw_device_op_read, | 1501 | .read = fw_device_op_read, |
1501 | .unlocked_ioctl = fw_device_op_ioctl, | 1502 | .unlocked_ioctl = fw_device_op_ioctl, |
1502 | .poll = fw_device_op_poll, | ||
1503 | .release = fw_device_op_release, | ||
1504 | .mmap = fw_device_op_mmap, | 1503 | .mmap = fw_device_op_mmap, |
1505 | 1504 | .release = fw_device_op_release, | |
1505 | .poll = fw_device_op_poll, | ||
1506 | #ifdef CONFIG_COMPAT | 1506 | #ifdef CONFIG_COMPAT |
1507 | .compat_ioctl = fw_device_op_compat_ioctl, | 1507 | .compat_ioctl = fw_device_op_compat_ioctl, |
1508 | #endif | 1508 | #endif |
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 673b03f8b4ec..fdc33ff06dc1 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -81,7 +81,7 @@ static int close_transaction(struct fw_transaction *transaction, | |||
81 | spin_lock_irqsave(&card->lock, flags); | 81 | spin_lock_irqsave(&card->lock, flags); |
82 | list_for_each_entry(t, &card->transaction_list, link) { | 82 | list_for_each_entry(t, &card->transaction_list, link) { |
83 | if (t == transaction) { | 83 | if (t == transaction) { |
84 | list_del(&t->link); | 84 | list_del_init(&t->link); |
85 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 85 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
86 | break; | 86 | break; |
87 | } | 87 | } |
@@ -89,6 +89,7 @@ static int close_transaction(struct fw_transaction *transaction, | |||
89 | spin_unlock_irqrestore(&card->lock, flags); | 89 | spin_unlock_irqrestore(&card->lock, flags); |
90 | 90 | ||
91 | if (&t->link != &card->transaction_list) { | 91 | if (&t->link != &card->transaction_list) { |
92 | del_timer_sync(&t->split_timeout_timer); | ||
92 | t->callback(card, rcode, NULL, 0, t->callback_data); | 93 | t->callback(card, rcode, NULL, 0, t->callback_data); |
93 | return 0; | 94 | return 0; |
94 | } | 95 | } |
@@ -121,6 +122,31 @@ int fw_cancel_transaction(struct fw_card *card, | |||
121 | } | 122 | } |
122 | EXPORT_SYMBOL(fw_cancel_transaction); | 123 | EXPORT_SYMBOL(fw_cancel_transaction); |
123 | 124 | ||
125 | static void split_transaction_timeout_callback(unsigned long data) | ||
126 | { | ||
127 | struct fw_transaction *t = (struct fw_transaction *)data; | ||
128 | struct fw_card *card = t->card; | ||
129 | unsigned long flags; | ||
130 | |||
131 | spin_lock_irqsave(&card->lock, flags); | ||
132 | if (list_empty(&t->link)) { | ||
133 | spin_unlock_irqrestore(&card->lock, flags); | ||
134 | return; | ||
135 | } | ||
136 | list_del(&t->link); | ||
137 | card->tlabel_mask &= ~(1ULL << t->tlabel); | ||
138 | spin_unlock_irqrestore(&card->lock, flags); | ||
139 | |||
140 | card->driver->cancel_packet(card, &t->packet); | ||
141 | |||
142 | /* | ||
143 | * At this point cancel_packet will never call the transaction | ||
144 | * callback, since we just took the transaction out of the list. | ||
145 | * So do it here. | ||
146 | */ | ||
147 | t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data); | ||
148 | } | ||
149 | |||
124 | static void transmit_complete_callback(struct fw_packet *packet, | 150 | static void transmit_complete_callback(struct fw_packet *packet, |
125 | struct fw_card *card, int status) | 151 | struct fw_card *card, int status) |
126 | { | 152 | { |
@@ -229,6 +255,23 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, | |||
229 | packet->payload_mapped = false; | 255 | packet->payload_mapped = false; |
230 | } | 256 | } |
231 | 257 | ||
258 | static int allocate_tlabel(struct fw_card *card) | ||
259 | { | ||
260 | int tlabel; | ||
261 | |||
262 | tlabel = card->current_tlabel; | ||
263 | while (card->tlabel_mask & (1ULL << tlabel)) { | ||
264 | tlabel = (tlabel + 1) & 0x3f; | ||
265 | if (tlabel == card->current_tlabel) | ||
266 | return -EBUSY; | ||
267 | } | ||
268 | |||
269 | card->current_tlabel = (tlabel + 1) & 0x3f; | ||
270 | card->tlabel_mask |= 1ULL << tlabel; | ||
271 | |||
272 | return tlabel; | ||
273 | } | ||
274 | |||
232 | /** | 275 | /** |
233 | * This function provides low-level access to the IEEE1394 transaction | 276 | * This function provides low-level access to the IEEE1394 transaction |
234 | * logic. Most C programs would use either fw_read(), fw_write() or | 277 | * logic. Most C programs would use either fw_read(), fw_write() or |
@@ -277,31 +320,26 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, | |||
277 | int tlabel; | 320 | int tlabel; |
278 | 321 | ||
279 | /* | 322 | /* |
280 | * Bump the flush timer up 100ms first of all so we | ||
281 | * don't race with a flush timer callback. | ||
282 | */ | ||
283 | |||
284 | mod_timer(&card->flush_timer, jiffies + DIV_ROUND_UP(HZ, 10)); | ||
285 | |||
286 | /* | ||
287 | * Allocate tlabel from the bitmap and put the transaction on | 323 | * Allocate tlabel from the bitmap and put the transaction on |
288 | * the list while holding the card spinlock. | 324 | * the list while holding the card spinlock. |
289 | */ | 325 | */ |
290 | 326 | ||
291 | spin_lock_irqsave(&card->lock, flags); | 327 | spin_lock_irqsave(&card->lock, flags); |
292 | 328 | ||
293 | tlabel = card->current_tlabel; | 329 | tlabel = allocate_tlabel(card); |
294 | if (card->tlabel_mask & (1ULL << tlabel)) { | 330 | if (tlabel < 0) { |
295 | spin_unlock_irqrestore(&card->lock, flags); | 331 | spin_unlock_irqrestore(&card->lock, flags); |
296 | callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data); | 332 | callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data); |
297 | return; | 333 | return; |
298 | } | 334 | } |
299 | 335 | ||
300 | card->current_tlabel = (card->current_tlabel + 1) & 0x3f; | ||
301 | card->tlabel_mask |= (1ULL << tlabel); | ||
302 | |||
303 | t->node_id = destination_id; | 336 | t->node_id = destination_id; |
304 | t->tlabel = tlabel; | 337 | t->tlabel = tlabel; |
338 | t->card = card; | ||
339 | setup_timer(&t->split_timeout_timer, | ||
340 | split_transaction_timeout_callback, (unsigned long)t); | ||
341 | /* FIXME: start this timer later, relative to t->timestamp */ | ||
342 | mod_timer(&t->split_timeout_timer, jiffies + DIV_ROUND_UP(HZ, 10)); | ||
305 | t->callback = callback; | 343 | t->callback = callback; |
306 | t->callback_data = callback_data; | 344 | t->callback_data = callback_data; |
307 | 345 | ||
@@ -347,11 +385,13 @@ int fw_run_transaction(struct fw_card *card, int tcode, int destination_id, | |||
347 | struct transaction_callback_data d; | 385 | struct transaction_callback_data d; |
348 | struct fw_transaction t; | 386 | struct fw_transaction t; |
349 | 387 | ||
388 | init_timer_on_stack(&t.split_timeout_timer); | ||
350 | init_completion(&d.done); | 389 | init_completion(&d.done); |
351 | d.payload = payload; | 390 | d.payload = payload; |
352 | fw_send_request(card, &t, tcode, destination_id, generation, speed, | 391 | fw_send_request(card, &t, tcode, destination_id, generation, speed, |
353 | offset, payload, length, transaction_callback, &d); | 392 | offset, payload, length, transaction_callback, &d); |
354 | wait_for_completion(&d.done); | 393 | wait_for_completion(&d.done); |
394 | destroy_timer_on_stack(&t.split_timeout_timer); | ||
355 | 395 | ||
356 | return d.rcode; | 396 | return d.rcode; |
357 | } | 397 | } |
@@ -394,30 +434,6 @@ void fw_send_phy_config(struct fw_card *card, | |||
394 | mutex_unlock(&phy_config_mutex); | 434 | mutex_unlock(&phy_config_mutex); |
395 | } | 435 | } |
396 | 436 | ||
397 | void fw_flush_transactions(struct fw_card *card) | ||
398 | { | ||
399 | struct fw_transaction *t, *next; | ||
400 | struct list_head list; | ||
401 | unsigned long flags; | ||
402 | |||
403 | INIT_LIST_HEAD(&list); | ||
404 | spin_lock_irqsave(&card->lock, flags); | ||
405 | list_splice_init(&card->transaction_list, &list); | ||
406 | card->tlabel_mask = 0; | ||
407 | spin_unlock_irqrestore(&card->lock, flags); | ||
408 | |||
409 | list_for_each_entry_safe(t, next, &list, link) { | ||
410 | card->driver->cancel_packet(card, &t->packet); | ||
411 | |||
412 | /* | ||
413 | * At this point cancel_packet will never call the | ||
414 | * transaction callback, since we just took all the | ||
415 | * transactions out of the list. So do it here. | ||
416 | */ | ||
417 | t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data); | ||
418 | } | ||
419 | } | ||
420 | |||
421 | static struct fw_address_handler *lookup_overlapping_address_handler( | 437 | static struct fw_address_handler *lookup_overlapping_address_handler( |
422 | struct list_head *list, unsigned long long offset, size_t length) | 438 | struct list_head *list, unsigned long long offset, size_t length) |
423 | { | 439 | { |
@@ -827,8 +843,8 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
827 | spin_lock_irqsave(&card->lock, flags); | 843 | spin_lock_irqsave(&card->lock, flags); |
828 | list_for_each_entry(t, &card->transaction_list, link) { | 844 | list_for_each_entry(t, &card->transaction_list, link) { |
829 | if (t->node_id == source && t->tlabel == tlabel) { | 845 | if (t->node_id == source && t->tlabel == tlabel) { |
830 | list_del(&t->link); | 846 | list_del_init(&t->link); |
831 | card->tlabel_mask &= ~(1 << t->tlabel); | 847 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
832 | break; | 848 | break; |
833 | } | 849 | } |
834 | } | 850 | } |
@@ -869,6 +885,8 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
869 | break; | 885 | break; |
870 | } | 886 | } |
871 | 887 | ||
888 | del_timer_sync(&t->split_timeout_timer); | ||
889 | |||
872 | /* | 890 | /* |
873 | * The response handler may be executed while the request handler | 891 | * The response handler may be executed while the request handler |
874 | * is still pending. Cancel the request handler. | 892 | * is still pending. Cancel the request handler. |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index fb0321300cce..0ecfcd95f4c5 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
@@ -27,7 +27,12 @@ struct fw_packet; | |||
27 | #define PHY_LINK_ACTIVE 0x80 | 27 | #define PHY_LINK_ACTIVE 0x80 |
28 | #define PHY_CONTENDER 0x40 | 28 | #define PHY_CONTENDER 0x40 |
29 | #define PHY_BUS_RESET 0x40 | 29 | #define PHY_BUS_RESET 0x40 |
30 | #define PHY_EXTENDED_REGISTERS 0xe0 | ||
30 | #define PHY_BUS_SHORT_RESET 0x40 | 31 | #define PHY_BUS_SHORT_RESET 0x40 |
32 | #define PHY_INT_STATUS_BITS 0x3c | ||
33 | #define PHY_ENABLE_ACCEL 0x02 | ||
34 | #define PHY_ENABLE_MULTI 0x01 | ||
35 | #define PHY_PAGE_SELECT 0xe0 | ||
31 | 36 | ||
32 | #define BANDWIDTH_AVAILABLE_INITIAL 4915 | 37 | #define BANDWIDTH_AVAILABLE_INITIAL 4915 |
33 | #define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31) | 38 | #define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31) |
@@ -215,7 +220,6 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *request); | |||
215 | void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet); | 220 | void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet); |
216 | void fw_fill_response(struct fw_packet *response, u32 *request_header, | 221 | void fw_fill_response(struct fw_packet *response, u32 *request_header, |
217 | int rcode, void *payload, size_t length); | 222 | int rcode, void *payload, size_t length); |
218 | void fw_flush_transactions(struct fw_card *card); | ||
219 | void fw_send_phy_config(struct fw_card *card, | 223 | void fw_send_phy_config(struct fw_card *card, |
220 | int node_id, int generation, int gap_count); | 224 | int node_id, int generation, int gap_count); |
221 | 225 | ||
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index a3b083a7403a..9f627e758cfc 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -236,13 +236,15 @@ static char ohci_driver_name[] = KBUILD_MODNAME; | |||
236 | #define QUIRK_CYCLE_TIMER 1 | 236 | #define QUIRK_CYCLE_TIMER 1 |
237 | #define QUIRK_RESET_PACKET 2 | 237 | #define QUIRK_RESET_PACKET 2 |
238 | #define QUIRK_BE_HEADERS 4 | 238 | #define QUIRK_BE_HEADERS 4 |
239 | #define QUIRK_NO_1394A 8 | ||
239 | 240 | ||
240 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ | 241 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ |
241 | static const struct { | 242 | static const struct { |
242 | unsigned short vendor, device, flags; | 243 | unsigned short vendor, device, flags; |
243 | } ohci_quirks[] = { | 244 | } ohci_quirks[] = { |
244 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | | 245 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | |
245 | QUIRK_RESET_PACKET}, | 246 | QUIRK_RESET_PACKET | |
247 | QUIRK_NO_1394A}, | ||
246 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, | 248 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, |
247 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 249 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, |
248 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 250 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, |
@@ -257,15 +259,16 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0" | |||
257 | ", nonatomic cycle timer = " __stringify(QUIRK_CYCLE_TIMER) | 259 | ", nonatomic cycle timer = " __stringify(QUIRK_CYCLE_TIMER) |
258 | ", reset packet generation = " __stringify(QUIRK_RESET_PACKET) | 260 | ", reset packet generation = " __stringify(QUIRK_RESET_PACKET) |
259 | ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) | 261 | ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) |
262 | ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A) | ||
260 | ")"); | 263 | ")"); |
261 | 264 | ||
262 | #ifdef CONFIG_FIREWIRE_OHCI_DEBUG | ||
263 | |||
264 | #define OHCI_PARAM_DEBUG_AT_AR 1 | 265 | #define OHCI_PARAM_DEBUG_AT_AR 1 |
265 | #define OHCI_PARAM_DEBUG_SELFIDS 2 | 266 | #define OHCI_PARAM_DEBUG_SELFIDS 2 |
266 | #define OHCI_PARAM_DEBUG_IRQS 4 | 267 | #define OHCI_PARAM_DEBUG_IRQS 4 |
267 | #define OHCI_PARAM_DEBUG_BUSRESETS 8 /* only effective before chip init */ | 268 | #define OHCI_PARAM_DEBUG_BUSRESETS 8 /* only effective before chip init */ |
268 | 269 | ||
270 | #ifdef CONFIG_FIREWIRE_OHCI_DEBUG | ||
271 | |||
269 | static int param_debug; | 272 | static int param_debug; |
270 | module_param_named(debug, param_debug, int, 0644); | 273 | module_param_named(debug, param_debug, int, 0644); |
271 | MODULE_PARM_DESC(debug, "Verbose logging (default = 0" | 274 | MODULE_PARM_DESC(debug, "Verbose logging (default = 0" |
@@ -438,9 +441,10 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) | |||
438 | 441 | ||
439 | #else | 442 | #else |
440 | 443 | ||
441 | #define log_irqs(evt) | 444 | #define param_debug 0 |
442 | #define log_selfids(node_id, generation, self_id_count, sid) | 445 | static inline void log_irqs(u32 evt) {} |
443 | #define log_ar_at_event(dir, speed, header, evt) | 446 | static inline void log_selfids(int node_id, int generation, int self_id_count, u32 *s) {} |
447 | static inline void log_ar_at_event(char dir, int speed, u32 *header, int evt) {} | ||
444 | 448 | ||
445 | #endif /* CONFIG_FIREWIRE_OHCI_DEBUG */ | 449 | #endif /* CONFIG_FIREWIRE_OHCI_DEBUG */ |
446 | 450 | ||
@@ -460,27 +464,71 @@ static inline void flush_writes(const struct fw_ohci *ohci) | |||
460 | reg_read(ohci, OHCI1394_Version); | 464 | reg_read(ohci, OHCI1394_Version); |
461 | } | 465 | } |
462 | 466 | ||
463 | static int ohci_update_phy_reg(struct fw_card *card, int addr, | 467 | static int read_phy_reg(struct fw_ohci *ohci, int addr) |
464 | int clear_bits, int set_bits) | ||
465 | { | 468 | { |
466 | struct fw_ohci *ohci = fw_ohci(card); | 469 | u32 val; |
467 | u32 val, old; | 470 | int i; |
468 | 471 | ||
469 | reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); | 472 | reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); |
470 | flush_writes(ohci); | 473 | for (i = 0; i < 10; i++) { |
471 | msleep(2); | 474 | val = reg_read(ohci, OHCI1394_PhyControl); |
472 | val = reg_read(ohci, OHCI1394_PhyControl); | 475 | if (val & OHCI1394_PhyControl_ReadDone) |
473 | if ((val & OHCI1394_PhyControl_ReadDone) == 0) { | 476 | return OHCI1394_PhyControl_ReadData(val); |
474 | fw_error("failed to set phy reg bits.\n"); | 477 | |
475 | return -EBUSY; | 478 | msleep(1); |
476 | } | 479 | } |
480 | fw_error("failed to read phy reg\n"); | ||
481 | |||
482 | return -EBUSY; | ||
483 | } | ||
484 | |||
485 | static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val) | ||
486 | { | ||
487 | int i; | ||
477 | 488 | ||
478 | old = OHCI1394_PhyControl_ReadData(val); | ||
479 | old = (old & ~clear_bits) | set_bits; | ||
480 | reg_write(ohci, OHCI1394_PhyControl, | 489 | reg_write(ohci, OHCI1394_PhyControl, |
481 | OHCI1394_PhyControl_Write(addr, old)); | 490 | OHCI1394_PhyControl_Write(addr, val)); |
491 | for (i = 0; i < 100; i++) { | ||
492 | val = reg_read(ohci, OHCI1394_PhyControl); | ||
493 | if (!(val & OHCI1394_PhyControl_WritePending)) | ||
494 | return 0; | ||
482 | 495 | ||
483 | return 0; | 496 | msleep(1); |
497 | } | ||
498 | fw_error("failed to write phy reg\n"); | ||
499 | |||
500 | return -EBUSY; | ||
501 | } | ||
502 | |||
503 | static int ohci_update_phy_reg(struct fw_card *card, int addr, | ||
504 | int clear_bits, int set_bits) | ||
505 | { | ||
506 | struct fw_ohci *ohci = fw_ohci(card); | ||
507 | int ret; | ||
508 | |||
509 | ret = read_phy_reg(ohci, addr); | ||
510 | if (ret < 0) | ||
511 | return ret; | ||
512 | |||
513 | /* | ||
514 | * The interrupt status bits are cleared by writing a one bit. | ||
515 | * Avoid clearing them unless explicitly requested in set_bits. | ||
516 | */ | ||
517 | if (addr == 5) | ||
518 | clear_bits |= PHY_INT_STATUS_BITS; | ||
519 | |||
520 | return write_phy_reg(ohci, addr, (ret & ~clear_bits) | set_bits); | ||
521 | } | ||
522 | |||
523 | static int read_paged_phy_reg(struct fw_ohci *ohci, int page, int addr) | ||
524 | { | ||
525 | int ret; | ||
526 | |||
527 | ret = ohci_update_phy_reg(&ohci->card, 7, PHY_PAGE_SELECT, page << 5); | ||
528 | if (ret < 0) | ||
529 | return ret; | ||
530 | |||
531 | return read_phy_reg(ohci, addr); | ||
484 | } | 532 | } |
485 | 533 | ||
486 | static int ar_context_add_page(struct ar_context *ctx) | 534 | static int ar_context_add_page(struct ar_context *ctx) |
@@ -1495,13 +1543,64 @@ static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length) | |||
1495 | memset(&dest[length], 0, CONFIG_ROM_SIZE - size); | 1543 | memset(&dest[length], 0, CONFIG_ROM_SIZE - size); |
1496 | } | 1544 | } |
1497 | 1545 | ||
1546 | static int configure_1394a_enhancements(struct fw_ohci *ohci) | ||
1547 | { | ||
1548 | bool enable_1394a; | ||
1549 | int ret, clear, set, offset; | ||
1550 | |||
1551 | /* Check if the driver should configure link and PHY. */ | ||
1552 | if (!(reg_read(ohci, OHCI1394_HCControlSet) & | ||
1553 | OHCI1394_HCControl_programPhyEnable)) | ||
1554 | return 0; | ||
1555 | |||
1556 | /* Paranoia: check whether the PHY supports 1394a, too. */ | ||
1557 | enable_1394a = false; | ||
1558 | ret = read_phy_reg(ohci, 2); | ||
1559 | if (ret < 0) | ||
1560 | return ret; | ||
1561 | if ((ret & PHY_EXTENDED_REGISTERS) == PHY_EXTENDED_REGISTERS) { | ||
1562 | ret = read_paged_phy_reg(ohci, 1, 8); | ||
1563 | if (ret < 0) | ||
1564 | return ret; | ||
1565 | if (ret >= 1) | ||
1566 | enable_1394a = true; | ||
1567 | } | ||
1568 | |||
1569 | if (ohci->quirks & QUIRK_NO_1394A) | ||
1570 | enable_1394a = false; | ||
1571 | |||
1572 | /* Configure PHY and link consistently. */ | ||
1573 | if (enable_1394a) { | ||
1574 | clear = 0; | ||
1575 | set = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; | ||
1576 | } else { | ||
1577 | clear = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; | ||
1578 | set = 0; | ||
1579 | } | ||
1580 | ret = ohci_update_phy_reg(&ohci->card, 5, clear, set); | ||
1581 | if (ret < 0) | ||
1582 | return ret; | ||
1583 | |||
1584 | if (enable_1394a) | ||
1585 | offset = OHCI1394_HCControlSet; | ||
1586 | else | ||
1587 | offset = OHCI1394_HCControlClear; | ||
1588 | reg_write(ohci, offset, OHCI1394_HCControl_aPhyEnhanceEnable); | ||
1589 | |||
1590 | /* Clean up: configuration has been taken care of. */ | ||
1591 | reg_write(ohci, OHCI1394_HCControlClear, | ||
1592 | OHCI1394_HCControl_programPhyEnable); | ||
1593 | |||
1594 | return 0; | ||
1595 | } | ||
1596 | |||
1498 | static int ohci_enable(struct fw_card *card, | 1597 | static int ohci_enable(struct fw_card *card, |
1499 | const __be32 *config_rom, size_t length) | 1598 | const __be32 *config_rom, size_t length) |
1500 | { | 1599 | { |
1501 | struct fw_ohci *ohci = fw_ohci(card); | 1600 | struct fw_ohci *ohci = fw_ohci(card); |
1502 | struct pci_dev *dev = to_pci_dev(card->device); | 1601 | struct pci_dev *dev = to_pci_dev(card->device); |
1503 | u32 lps; | 1602 | u32 lps; |
1504 | int i; | 1603 | int i, ret; |
1505 | 1604 | ||
1506 | if (software_reset(ohci)) { | 1605 | if (software_reset(ohci)) { |
1507 | fw_error("Failed to reset ohci card.\n"); | 1606 | fw_error("Failed to reset ohci card.\n"); |
@@ -1565,10 +1664,14 @@ static int ohci_enable(struct fw_card *card, | |||
1565 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) | 1664 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) |
1566 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); | 1665 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); |
1567 | 1666 | ||
1667 | ret = configure_1394a_enhancements(ohci); | ||
1668 | if (ret < 0) | ||
1669 | return ret; | ||
1670 | |||
1568 | /* Activate link_on bit and contender bit in our self ID packets.*/ | 1671 | /* Activate link_on bit and contender bit in our self ID packets.*/ |
1569 | if (ohci_update_phy_reg(card, 4, 0, | 1672 | ret = ohci_update_phy_reg(card, 4, 0, PHY_LINK_ACTIVE | PHY_CONTENDER); |
1570 | PHY_LINK_ACTIVE | PHY_CONTENDER) < 0) | 1673 | if (ret < 0) |
1571 | return -EIO; | 1674 | return ret; |
1572 | 1675 | ||
1573 | /* | 1676 | /* |
1574 | * When the link is not yet enabled, the atomic config rom | 1677 | * When the link is not yet enabled, the atomic config rom |
@@ -2304,7 +2407,7 @@ static const struct fw_card_driver ohci_driver = { | |||
2304 | }; | 2407 | }; |
2305 | 2408 | ||
2306 | #ifdef CONFIG_PPC_PMAC | 2409 | #ifdef CONFIG_PPC_PMAC |
2307 | static void ohci_pmac_on(struct pci_dev *dev) | 2410 | static void pmac_ohci_on(struct pci_dev *dev) |
2308 | { | 2411 | { |
2309 | if (machine_is(powermac)) { | 2412 | if (machine_is(powermac)) { |
2310 | struct device_node *ofn = pci_device_to_OF_node(dev); | 2413 | struct device_node *ofn = pci_device_to_OF_node(dev); |
@@ -2316,7 +2419,7 @@ static void ohci_pmac_on(struct pci_dev *dev) | |||
2316 | } | 2419 | } |
2317 | } | 2420 | } |
2318 | 2421 | ||
2319 | static void ohci_pmac_off(struct pci_dev *dev) | 2422 | static void pmac_ohci_off(struct pci_dev *dev) |
2320 | { | 2423 | { |
2321 | if (machine_is(powermac)) { | 2424 | if (machine_is(powermac)) { |
2322 | struct device_node *ofn = pci_device_to_OF_node(dev); | 2425 | struct device_node *ofn = pci_device_to_OF_node(dev); |
@@ -2328,15 +2431,15 @@ static void ohci_pmac_off(struct pci_dev *dev) | |||
2328 | } | 2431 | } |
2329 | } | 2432 | } |
2330 | #else | 2433 | #else |
2331 | #define ohci_pmac_on(dev) | 2434 | static inline void pmac_ohci_on(struct pci_dev *dev) {} |
2332 | #define ohci_pmac_off(dev) | 2435 | static inline void pmac_ohci_off(struct pci_dev *dev) {} |
2333 | #endif /* CONFIG_PPC_PMAC */ | 2436 | #endif /* CONFIG_PPC_PMAC */ |
2334 | 2437 | ||
2335 | static int __devinit pci_probe(struct pci_dev *dev, | 2438 | static int __devinit pci_probe(struct pci_dev *dev, |
2336 | const struct pci_device_id *ent) | 2439 | const struct pci_device_id *ent) |
2337 | { | 2440 | { |
2338 | struct fw_ohci *ohci; | 2441 | struct fw_ohci *ohci; |
2339 | u32 bus_options, max_receive, link_speed, version; | 2442 | u32 bus_options, max_receive, link_speed, version, link_enh; |
2340 | u64 guid; | 2443 | u64 guid; |
2341 | int i, err, n_ir, n_it; | 2444 | int i, err, n_ir, n_it; |
2342 | size_t size; | 2445 | size_t size; |
@@ -2349,7 +2452,7 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2349 | 2452 | ||
2350 | fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev); | 2453 | fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev); |
2351 | 2454 | ||
2352 | ohci_pmac_on(dev); | 2455 | pmac_ohci_on(dev); |
2353 | 2456 | ||
2354 | err = pci_enable_device(dev); | 2457 | err = pci_enable_device(dev); |
2355 | if (err) { | 2458 | if (err) { |
@@ -2389,6 +2492,23 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2389 | if (param_quirks) | 2492 | if (param_quirks) |
2390 | ohci->quirks = param_quirks; | 2493 | ohci->quirks = param_quirks; |
2391 | 2494 | ||
2495 | /* TI OHCI-Lynx and compatible: set recommended configuration bits. */ | ||
2496 | if (dev->vendor == PCI_VENDOR_ID_TI) { | ||
2497 | pci_read_config_dword(dev, PCI_CFG_TI_LinkEnh, &link_enh); | ||
2498 | |||
2499 | /* adjust latency of ATx FIFO: use 1.7 KB threshold */ | ||
2500 | link_enh &= ~TI_LinkEnh_atx_thresh_mask; | ||
2501 | link_enh |= TI_LinkEnh_atx_thresh_1_7K; | ||
2502 | |||
2503 | /* use priority arbitration for asynchronous responses */ | ||
2504 | link_enh |= TI_LinkEnh_enab_unfair; | ||
2505 | |||
2506 | /* required for aPhyEnhanceEnable to work */ | ||
2507 | link_enh |= TI_LinkEnh_enab_accel; | ||
2508 | |||
2509 | pci_write_config_dword(dev, PCI_CFG_TI_LinkEnh, link_enh); | ||
2510 | } | ||
2511 | |||
2392 | ar_context_init(&ohci->ar_request_ctx, ohci, | 2512 | ar_context_init(&ohci->ar_request_ctx, ohci, |
2393 | OHCI1394_AsReqRcvContextControlSet); | 2513 | OHCI1394_AsReqRcvContextControlSet); |
2394 | 2514 | ||
@@ -2466,7 +2586,7 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2466 | pci_disable_device(dev); | 2586 | pci_disable_device(dev); |
2467 | fail_free: | 2587 | fail_free: |
2468 | kfree(&ohci->card); | 2588 | kfree(&ohci->card); |
2469 | ohci_pmac_off(dev); | 2589 | pmac_ohci_off(dev); |
2470 | fail: | 2590 | fail: |
2471 | if (err == -ENOMEM) | 2591 | if (err == -ENOMEM) |
2472 | fw_error("Out of memory\n"); | 2592 | fw_error("Out of memory\n"); |
@@ -2509,7 +2629,7 @@ static void pci_remove(struct pci_dev *dev) | |||
2509 | pci_release_region(dev, 0); | 2629 | pci_release_region(dev, 0); |
2510 | pci_disable_device(dev); | 2630 | pci_disable_device(dev); |
2511 | kfree(&ohci->card); | 2631 | kfree(&ohci->card); |
2512 | ohci_pmac_off(dev); | 2632 | pmac_ohci_off(dev); |
2513 | 2633 | ||
2514 | fw_notify("Removed fw-ohci device.\n"); | 2634 | fw_notify("Removed fw-ohci device.\n"); |
2515 | } | 2635 | } |
@@ -2530,7 +2650,7 @@ static int pci_suspend(struct pci_dev *dev, pm_message_t state) | |||
2530 | err = pci_set_power_state(dev, pci_choose_state(dev, state)); | 2650 | err = pci_set_power_state(dev, pci_choose_state(dev, state)); |
2531 | if (err) | 2651 | if (err) |
2532 | fw_error("pci_set_power_state failed with %d\n", err); | 2652 | fw_error("pci_set_power_state failed with %d\n", err); |
2533 | ohci_pmac_off(dev); | 2653 | pmac_ohci_off(dev); |
2534 | 2654 | ||
2535 | return 0; | 2655 | return 0; |
2536 | } | 2656 | } |
@@ -2540,7 +2660,7 @@ static int pci_resume(struct pci_dev *dev) | |||
2540 | struct fw_ohci *ohci = pci_get_drvdata(dev); | 2660 | struct fw_ohci *ohci = pci_get_drvdata(dev); |
2541 | int err; | 2661 | int err; |
2542 | 2662 | ||
2543 | ohci_pmac_on(dev); | 2663 | pmac_ohci_on(dev); |
2544 | pci_set_power_state(dev, PCI_D0); | 2664 | pci_set_power_state(dev, PCI_D0); |
2545 | pci_restore_state(dev); | 2665 | pci_restore_state(dev); |
2546 | err = pci_enable_device(dev); | 2666 | err = pci_enable_device(dev); |
diff --git a/drivers/firewire/ohci.h b/drivers/firewire/ohci.h index ba492d85c516..3bc9a5d744eb 100644 --- a/drivers/firewire/ohci.h +++ b/drivers/firewire/ohci.h | |||
@@ -67,7 +67,7 @@ | |||
67 | #define OHCI1394_PhyControl_ReadDone 0x80000000 | 67 | #define OHCI1394_PhyControl_ReadDone 0x80000000 |
68 | #define OHCI1394_PhyControl_ReadData(r) (((r) & 0x00ff0000) >> 16) | 68 | #define OHCI1394_PhyControl_ReadData(r) (((r) & 0x00ff0000) >> 16) |
69 | #define OHCI1394_PhyControl_Write(addr, data) (((addr) << 8) | (data) | 0x00004000) | 69 | #define OHCI1394_PhyControl_Write(addr, data) (((addr) << 8) | (data) | 0x00004000) |
70 | #define OHCI1394_PhyControl_WriteDone 0x00004000 | 70 | #define OHCI1394_PhyControl_WritePending 0x00004000 |
71 | #define OHCI1394_IsochronousCycleTimer 0x0F0 | 71 | #define OHCI1394_IsochronousCycleTimer 0x0F0 |
72 | #define OHCI1394_AsReqFilterHiSet 0x100 | 72 | #define OHCI1394_AsReqFilterHiSet 0x100 |
73 | #define OHCI1394_AsReqFilterHiClear 0x104 | 73 | #define OHCI1394_AsReqFilterHiClear 0x104 |
@@ -154,4 +154,12 @@ | |||
154 | 154 | ||
155 | #define OHCI1394_phy_tcode 0xe | 155 | #define OHCI1394_phy_tcode 0xe |
156 | 156 | ||
157 | /* TI extensions */ | ||
158 | |||
159 | #define PCI_CFG_TI_LinkEnh 0xf4 | ||
160 | #define TI_LinkEnh_enab_accel 0x00000002 | ||
161 | #define TI_LinkEnh_enab_unfair 0x00000080 | ||
162 | #define TI_LinkEnh_atx_thresh_mask 0x00003000 | ||
163 | #define TI_LinkEnh_atx_thresh_1_7K 0x00001000 | ||
164 | |||
157 | #endif /* _FIREWIRE_OHCI_H */ | 165 | #endif /* _FIREWIRE_OHCI_H */ |