diff options
-rw-r--r-- | drivers/firewire/Makefile | 8 | ||||
-rw-r--r-- | drivers/firewire/core-card.c (renamed from drivers/firewire/fw-card.c) | 25 | ||||
-rw-r--r-- | drivers/firewire/core-cdev.c (renamed from drivers/firewire/fw-cdev.c) | 13 | ||||
-rw-r--r-- | drivers/firewire/core-device.c (renamed from drivers/firewire/fw-device.c) | 154 | ||||
-rw-r--r-- | drivers/firewire/core-iso.c (renamed from drivers/firewire/fw-iso.c) | 6 | ||||
-rw-r--r-- | drivers/firewire/core-topology.c (renamed from drivers/firewire/fw-topology.c) | 24 | ||||
-rw-r--r-- | drivers/firewire/core-transaction.c (renamed from drivers/firewire/fw-transaction.c) | 42 | ||||
-rw-r--r-- | drivers/firewire/core.h | 293 | ||||
-rw-r--r-- | drivers/firewire/fw-device.h | 202 | ||||
-rw-r--r-- | drivers/firewire/fw-topology.h | 77 | ||||
-rw-r--r-- | drivers/firewire/fw-transaction.h | 446 | ||||
-rw-r--r-- | drivers/firewire/ohci.c (renamed from drivers/firewire/fw-ohci.c) | 19 | ||||
-rw-r--r-- | drivers/firewire/ohci.h (renamed from drivers/firewire/fw-ohci.h) | 6 | ||||
-rw-r--r-- | drivers/firewire/sbp2.c (renamed from drivers/firewire/fw-sbp2.c) | 58 | ||||
-rw-r--r-- | include/linux/firewire.h | 358 |
15 files changed, 902 insertions, 829 deletions
diff --git a/drivers/firewire/Makefile b/drivers/firewire/Makefile index a7c31e9039c..bc3b9bf822b 100644 --- a/drivers/firewire/Makefile +++ b/drivers/firewire/Makefile | |||
@@ -2,10 +2,10 @@ | |||
2 | # Makefile for the Linux IEEE 1394 implementation | 2 | # Makefile for the Linux IEEE 1394 implementation |
3 | # | 3 | # |
4 | 4 | ||
5 | firewire-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \ | 5 | firewire-core-y += core-card.o core-cdev.o core-device.o \ |
6 | fw-device.o fw-cdev.o | 6 | core-iso.o core-topology.o core-transaction.o |
7 | firewire-ohci-y += fw-ohci.o | 7 | firewire-ohci-y += ohci.o |
8 | firewire-sbp2-y += fw-sbp2.o | 8 | firewire-sbp2-y += sbp2.o |
9 | 9 | ||
10 | obj-$(CONFIG_FIREWIRE) += firewire-core.o | 10 | obj-$(CONFIG_FIREWIRE) += firewire-core.o |
11 | obj-$(CONFIG_FIREWIRE_OHCI) += firewire-ohci.o | 11 | obj-$(CONFIG_FIREWIRE_OHCI) += firewire-ohci.o |
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/core-card.c index 8b8c8c22f0f..4c1be64fddd 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -16,18 +16,27 @@ | |||
16 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 16 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/bug.h> | ||
19 | #include <linux/completion.h> | 20 | #include <linux/completion.h> |
20 | #include <linux/crc-itu-t.h> | 21 | #include <linux/crc-itu-t.h> |
21 | #include <linux/delay.h> | ||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/firewire.h> | ||
25 | #include <linux/firewire-constants.h> | ||
26 | #include <linux/jiffies.h> | ||
27 | #include <linux/kernel.h> | ||
24 | #include <linux/kref.h> | 28 | #include <linux/kref.h> |
29 | #include <linux/list.h> | ||
25 | #include <linux/module.h> | 30 | #include <linux/module.h> |
26 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
32 | #include <linux/spinlock.h> | ||
33 | #include <linux/timer.h> | ||
34 | #include <linux/workqueue.h> | ||
27 | 35 | ||
28 | #include "fw-transaction.h" | 36 | #include <asm/atomic.h> |
29 | #include "fw-topology.h" | 37 | #include <asm/byteorder.h> |
30 | #include "fw-device.h" | 38 | |
39 | #include "core.h" | ||
31 | 40 | ||
32 | int fw_compute_block_crc(u32 *block) | 41 | int fw_compute_block_crc(u32 *block) |
33 | { | 42 | { |
@@ -181,12 +190,6 @@ void fw_core_remove_descriptor(struct fw_descriptor *desc) | |||
181 | mutex_unlock(&card_mutex); | 190 | mutex_unlock(&card_mutex); |
182 | } | 191 | } |
183 | 192 | ||
184 | static int set_broadcast_channel(struct device *dev, void *data) | ||
185 | { | ||
186 | fw_device_set_broadcast_channel(fw_device(dev), (long)data); | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static void allocate_broadcast_channel(struct fw_card *card, int generation) | 193 | static void allocate_broadcast_channel(struct fw_card *card, int generation) |
191 | { | 194 | { |
192 | int channel, bandwidth = 0; | 195 | int channel, bandwidth = 0; |
@@ -196,7 +199,7 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation) | |||
196 | if (channel == 31) { | 199 | if (channel == 31) { |
197 | card->broadcast_channel_allocated = true; | 200 | card->broadcast_channel_allocated = true; |
198 | device_for_each_child(card->device, (void *)(long)generation, | 201 | device_for_each_child(card->device, (void *)(long)generation, |
199 | set_broadcast_channel); | 202 | fw_device_set_broadcast_channel); |
200 | } | 203 | } |
201 | } | 204 | } |
202 | 205 | ||
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/core-cdev.c index 7eb6594cc3e..d1d30c615b0 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/firewire.h> | ||
25 | #include <linux/firewire-cdev.h> | 26 | #include <linux/firewire-cdev.h> |
26 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
27 | #include <linux/jiffies.h> | 28 | #include <linux/jiffies.h> |
@@ -34,16 +35,14 @@ | |||
34 | #include <linux/preempt.h> | 35 | #include <linux/preempt.h> |
35 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
36 | #include <linux/time.h> | 37 | #include <linux/time.h> |
38 | #include <linux/uaccess.h> | ||
37 | #include <linux/vmalloc.h> | 39 | #include <linux/vmalloc.h> |
38 | #include <linux/wait.h> | 40 | #include <linux/wait.h> |
39 | #include <linux/workqueue.h> | 41 | #include <linux/workqueue.h> |
40 | 42 | ||
41 | #include <asm/system.h> | 43 | #include <asm/system.h> |
42 | #include <asm/uaccess.h> | ||
43 | 44 | ||
44 | #include "fw-device.h" | 45 | #include "core.h" |
45 | #include "fw-topology.h" | ||
46 | #include "fw-transaction.h" | ||
47 | 46 | ||
48 | struct client { | 47 | struct client { |
49 | u32 version; | 48 | u32 version; |
@@ -739,15 +738,11 @@ static void release_descriptor(struct client *client, | |||
739 | static int ioctl_add_descriptor(struct client *client, void *buffer) | 738 | static int ioctl_add_descriptor(struct client *client, void *buffer) |
740 | { | 739 | { |
741 | struct fw_cdev_add_descriptor *request = buffer; | 740 | struct fw_cdev_add_descriptor *request = buffer; |
742 | struct fw_card *card = client->device->card; | ||
743 | struct descriptor_resource *r; | 741 | struct descriptor_resource *r; |
744 | int ret; | 742 | int ret; |
745 | 743 | ||
746 | /* Access policy: Allow this ioctl only on local nodes' device files. */ | 744 | /* Access policy: Allow this ioctl only on local nodes' device files. */ |
747 | spin_lock_irq(&card->lock); | 745 | if (!client->device->is_local) |
748 | ret = client->device->node_id != card->local_node->node_id; | ||
749 | spin_unlock_irq(&card->lock); | ||
750 | if (ret) | ||
751 | return -ENOSYS; | 746 | return -ENOSYS; |
752 | 747 | ||
753 | if (request->length > 256) | 748 | if (request->length > 256) |
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/core-device.c index a47e2129d83..97e656af2d2 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/core-device.c | |||
@@ -22,10 +22,14 @@ | |||
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/firewire.h> | ||
26 | #include <linux/firewire-constants.h> | ||
25 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
26 | #include <linux/jiffies.h> | 28 | #include <linux/jiffies.h> |
27 | #include <linux/kobject.h> | 29 | #include <linux/kobject.h> |
28 | #include <linux/list.h> | 30 | #include <linux/list.h> |
31 | #include <linux/mod_devicetable.h> | ||
32 | #include <linux/module.h> | ||
29 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
30 | #include <linux/rwsem.h> | 34 | #include <linux/rwsem.h> |
31 | #include <linux/semaphore.h> | 35 | #include <linux/semaphore.h> |
@@ -33,11 +37,11 @@ | |||
33 | #include <linux/string.h> | 37 | #include <linux/string.h> |
34 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
35 | 39 | ||
40 | #include <asm/atomic.h> | ||
41 | #include <asm/byteorder.h> | ||
36 | #include <asm/system.h> | 42 | #include <asm/system.h> |
37 | 43 | ||
38 | #include "fw-device.h" | 44 | #include "core.h" |
39 | #include "fw-topology.h" | ||
40 | #include "fw-transaction.h" | ||
41 | 45 | ||
42 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 * p) | 46 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 * p) |
43 | { | 47 | { |
@@ -55,9 +59,10 @@ int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value) | |||
55 | } | 59 | } |
56 | EXPORT_SYMBOL(fw_csr_iterator_next); | 60 | EXPORT_SYMBOL(fw_csr_iterator_next); |
57 | 61 | ||
58 | static int is_fw_unit(struct device *dev); | 62 | static bool is_fw_unit(struct device *dev); |
59 | 63 | ||
60 | static int match_unit_directory(u32 * directory, const struct fw_device_id *id) | 64 | static int match_unit_directory(u32 *directory, u32 match_flags, |
65 | const struct ieee1394_device_id *id) | ||
61 | { | 66 | { |
62 | struct fw_csr_iterator ci; | 67 | struct fw_csr_iterator ci; |
63 | int key, value, match; | 68 | int key, value, match; |
@@ -65,31 +70,42 @@ static int match_unit_directory(u32 * directory, const struct fw_device_id *id) | |||
65 | match = 0; | 70 | match = 0; |
66 | fw_csr_iterator_init(&ci, directory); | 71 | fw_csr_iterator_init(&ci, directory); |
67 | while (fw_csr_iterator_next(&ci, &key, &value)) { | 72 | while (fw_csr_iterator_next(&ci, &key, &value)) { |
68 | if (key == CSR_VENDOR && value == id->vendor) | 73 | if (key == CSR_VENDOR && value == id->vendor_id) |
69 | match |= FW_MATCH_VENDOR; | 74 | match |= IEEE1394_MATCH_VENDOR_ID; |
70 | if (key == CSR_MODEL && value == id->model) | 75 | if (key == CSR_MODEL && value == id->model_id) |
71 | match |= FW_MATCH_MODEL; | 76 | match |= IEEE1394_MATCH_MODEL_ID; |
72 | if (key == CSR_SPECIFIER_ID && value == id->specifier_id) | 77 | if (key == CSR_SPECIFIER_ID && value == id->specifier_id) |
73 | match |= FW_MATCH_SPECIFIER_ID; | 78 | match |= IEEE1394_MATCH_SPECIFIER_ID; |
74 | if (key == CSR_VERSION && value == id->version) | 79 | if (key == CSR_VERSION && value == id->version) |
75 | match |= FW_MATCH_VERSION; | 80 | match |= IEEE1394_MATCH_VERSION; |
76 | } | 81 | } |
77 | 82 | ||
78 | return (match & id->match_flags) == id->match_flags; | 83 | return (match & match_flags) == match_flags; |
79 | } | 84 | } |
80 | 85 | ||
81 | static int fw_unit_match(struct device *dev, struct device_driver *drv) | 86 | static int fw_unit_match(struct device *dev, struct device_driver *drv) |
82 | { | 87 | { |
83 | struct fw_unit *unit = fw_unit(dev); | 88 | struct fw_unit *unit = fw_unit(dev); |
84 | struct fw_driver *driver = fw_driver(drv); | 89 | struct fw_device *device; |
85 | int i; | 90 | const struct ieee1394_device_id *id; |
86 | 91 | ||
87 | /* We only allow binding to fw_units. */ | 92 | /* We only allow binding to fw_units. */ |
88 | if (!is_fw_unit(dev)) | 93 | if (!is_fw_unit(dev)) |
89 | return 0; | 94 | return 0; |
90 | 95 | ||
91 | for (i = 0; driver->id_table[i].match_flags != 0; i++) { | 96 | device = fw_parent_device(unit); |
92 | if (match_unit_directory(unit->directory, &driver->id_table[i])) | 97 | id = container_of(drv, struct fw_driver, driver)->id_table; |
98 | |||
99 | for (; id->match_flags != 0; id++) { | ||
100 | if (match_unit_directory(unit->directory, id->match_flags, id)) | ||
101 | return 1; | ||
102 | |||
103 | /* Also check vendor ID in the root directory. */ | ||
104 | if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) && | ||
105 | match_unit_directory(&device->config_rom[5], | ||
106 | IEEE1394_MATCH_VENDOR_ID, id) && | ||
107 | match_unit_directory(unit->directory, id->match_flags | ||
108 | & ~IEEE1394_MATCH_VENDOR_ID, id)) | ||
93 | return 1; | 109 | return 1; |
94 | } | 110 | } |
95 | 111 | ||
@@ -98,7 +114,7 @@ static int fw_unit_match(struct device *dev, struct device_driver *drv) | |||
98 | 114 | ||
99 | static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) | 115 | static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) |
100 | { | 116 | { |
101 | struct fw_device *device = fw_device(unit->device.parent); | 117 | struct fw_device *device = fw_parent_device(unit); |
102 | struct fw_csr_iterator ci; | 118 | struct fw_csr_iterator ci; |
103 | 119 | ||
104 | int key, value; | 120 | int key, value; |
@@ -292,8 +308,7 @@ static void init_fw_attribute_group(struct device *dev, | |||
292 | group->attrs[j++] = &attr->attr; | 308 | group->attrs[j++] = &attr->attr; |
293 | } | 309 | } |
294 | 310 | ||
295 | BUG_ON(j >= ARRAY_SIZE(group->attrs)); | 311 | group->attrs[j] = NULL; |
296 | group->attrs[j++] = NULL; | ||
297 | group->groups[0] = &group->group; | 312 | group->groups[0] = &group->group; |
298 | group->groups[1] = NULL; | 313 | group->groups[1] = NULL; |
299 | group->group.attrs = group->attrs; | 314 | group->group.attrs = group->attrs; |
@@ -356,9 +371,56 @@ static ssize_t guid_show(struct device *dev, | |||
356 | return ret; | 371 | return ret; |
357 | } | 372 | } |
358 | 373 | ||
374 | static int units_sprintf(char *buf, u32 *directory) | ||
375 | { | ||
376 | struct fw_csr_iterator ci; | ||
377 | int key, value; | ||
378 | int specifier_id = 0; | ||
379 | int version = 0; | ||
380 | |||
381 | fw_csr_iterator_init(&ci, directory); | ||
382 | while (fw_csr_iterator_next(&ci, &key, &value)) { | ||
383 | switch (key) { | ||
384 | case CSR_SPECIFIER_ID: | ||
385 | specifier_id = value; | ||
386 | break; | ||
387 | case CSR_VERSION: | ||
388 | version = value; | ||
389 | break; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | return sprintf(buf, "0x%06x:0x%06x ", specifier_id, version); | ||
394 | } | ||
395 | |||
396 | static ssize_t units_show(struct device *dev, | ||
397 | struct device_attribute *attr, char *buf) | ||
398 | { | ||
399 | struct fw_device *device = fw_device(dev); | ||
400 | struct fw_csr_iterator ci; | ||
401 | int key, value, i = 0; | ||
402 | |||
403 | down_read(&fw_device_rwsem); | ||
404 | fw_csr_iterator_init(&ci, &device->config_rom[5]); | ||
405 | while (fw_csr_iterator_next(&ci, &key, &value)) { | ||
406 | if (key != (CSR_UNIT | CSR_DIRECTORY)) | ||
407 | continue; | ||
408 | i += units_sprintf(&buf[i], ci.p + value - 1); | ||
409 | if (i >= PAGE_SIZE - (8 + 1 + 8 + 1)) | ||
410 | break; | ||
411 | } | ||
412 | up_read(&fw_device_rwsem); | ||
413 | |||
414 | if (i) | ||
415 | buf[i - 1] = '\n'; | ||
416 | |||
417 | return i; | ||
418 | } | ||
419 | |||
359 | static struct device_attribute fw_device_attributes[] = { | 420 | static struct device_attribute fw_device_attributes[] = { |
360 | __ATTR_RO(config_rom), | 421 | __ATTR_RO(config_rom), |
361 | __ATTR_RO(guid), | 422 | __ATTR_RO(guid), |
423 | __ATTR_RO(units), | ||
362 | __ATTR_NULL, | 424 | __ATTR_NULL, |
363 | }; | 425 | }; |
364 | 426 | ||
@@ -518,7 +580,9 @@ static int read_bus_info_block(struct fw_device *device, int generation) | |||
518 | 580 | ||
519 | kfree(old_rom); | 581 | kfree(old_rom); |
520 | ret = 0; | 582 | ret = 0; |
521 | device->cmc = rom[2] >> 30 & 1; | 583 | device->max_rec = rom[2] >> 12 & 0xf; |
584 | device->cmc = rom[2] >> 30 & 1; | ||
585 | device->irmc = rom[2] >> 31 & 1; | ||
522 | out: | 586 | out: |
523 | kfree(rom); | 587 | kfree(rom); |
524 | 588 | ||
@@ -537,7 +601,7 @@ static struct device_type fw_unit_type = { | |||
537 | .release = fw_unit_release, | 601 | .release = fw_unit_release, |
538 | }; | 602 | }; |
539 | 603 | ||
540 | static int is_fw_unit(struct device *dev) | 604 | static bool is_fw_unit(struct device *dev) |
541 | { | 605 | { |
542 | return dev->type == &fw_unit_type; | 606 | return dev->type == &fw_unit_type; |
543 | } | 607 | } |
@@ -570,9 +634,13 @@ static void create_units(struct fw_device *device) | |||
570 | unit->device.parent = &device->device; | 634 | unit->device.parent = &device->device; |
571 | dev_set_name(&unit->device, "%s.%d", dev_name(&device->device), i++); | 635 | dev_set_name(&unit->device, "%s.%d", dev_name(&device->device), i++); |
572 | 636 | ||
637 | BUILD_BUG_ON(ARRAY_SIZE(unit->attribute_group.attrs) < | ||
638 | ARRAY_SIZE(fw_unit_attributes) + | ||
639 | ARRAY_SIZE(config_rom_attributes)); | ||
573 | init_fw_attribute_group(&unit->device, | 640 | init_fw_attribute_group(&unit->device, |
574 | fw_unit_attributes, | 641 | fw_unit_attributes, |
575 | &unit->attribute_group); | 642 | &unit->attribute_group); |
643 | |||
576 | if (device_register(&unit->device) < 0) | 644 | if (device_register(&unit->device) < 0) |
577 | goto skip_unit; | 645 | goto skip_unit; |
578 | 646 | ||
@@ -683,6 +751,11 @@ static struct device_type fw_device_type = { | |||
683 | .release = fw_device_release, | 751 | .release = fw_device_release, |
684 | }; | 752 | }; |
685 | 753 | ||
754 | static bool is_fw_device(struct device *dev) | ||
755 | { | ||
756 | return dev->type == &fw_device_type; | ||
757 | } | ||
758 | |||
686 | static int update_unit(struct device *dev, void *data) | 759 | static int update_unit(struct device *dev, void *data) |
687 | { | 760 | { |
688 | struct fw_unit *unit = fw_unit(dev); | 761 | struct fw_unit *unit = fw_unit(dev); |
@@ -719,6 +792,9 @@ static int lookup_existing_device(struct device *dev, void *data) | |||
719 | struct fw_card *card = new->card; | 792 | struct fw_card *card = new->card; |
720 | int match = 0; | 793 | int match = 0; |
721 | 794 | ||
795 | if (!is_fw_device(dev)) | ||
796 | return 0; | ||
797 | |||
722 | down_read(&fw_device_rwsem); /* serialize config_rom access */ | 798 | down_read(&fw_device_rwsem); /* serialize config_rom access */ |
723 | spin_lock_irq(&card->lock); /* serialize node access */ | 799 | spin_lock_irq(&card->lock); /* serialize node access */ |
724 | 800 | ||
@@ -758,7 +834,7 @@ static int lookup_existing_device(struct device *dev, void *data) | |||
758 | 834 | ||
759 | enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, }; | 835 | enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, }; |
760 | 836 | ||
761 | void fw_device_set_broadcast_channel(struct fw_device *device, int generation) | 837 | static void set_broadcast_channel(struct fw_device *device, int generation) |
762 | { | 838 | { |
763 | struct fw_card *card = device->card; | 839 | struct fw_card *card = device->card; |
764 | __be32 data; | 840 | __be32 data; |
@@ -767,6 +843,20 @@ void fw_device_set_broadcast_channel(struct fw_device *device, int generation) | |||
767 | if (!card->broadcast_channel_allocated) | 843 | if (!card->broadcast_channel_allocated) |
768 | return; | 844 | return; |
769 | 845 | ||
846 | /* | ||
847 | * The Broadcast_Channel Valid bit is required by nodes which want to | ||
848 | * transmit on this channel. Such transmissions are practically | ||
849 | * exclusive to IP over 1394 (RFC 2734). IP capable nodes are required | ||
850 | * to be IRM capable and have a max_rec of 8 or more. We use this fact | ||
851 | * to narrow down to which nodes we send Broadcast_Channel updates. | ||
852 | */ | ||
853 | if (!device->irmc || device->max_rec < 8) | ||
854 | return; | ||
855 | |||
856 | /* | ||
857 | * Some 1394-1995 nodes crash if this 1394a-2000 register is written. | ||
858 | * Perform a read test first. | ||
859 | */ | ||
770 | if (device->bc_implemented == BC_UNKNOWN) { | 860 | if (device->bc_implemented == BC_UNKNOWN) { |
771 | rcode = fw_run_transaction(card, TCODE_READ_QUADLET_REQUEST, | 861 | rcode = fw_run_transaction(card, TCODE_READ_QUADLET_REQUEST, |
772 | device->node_id, generation, device->max_speed, | 862 | device->node_id, generation, device->max_speed, |
@@ -794,6 +884,14 @@ void fw_device_set_broadcast_channel(struct fw_device *device, int generation) | |||
794 | } | 884 | } |
795 | } | 885 | } |
796 | 886 | ||
887 | int fw_device_set_broadcast_channel(struct device *dev, void *gen) | ||
888 | { | ||
889 | if (is_fw_device(dev)) | ||
890 | set_broadcast_channel(fw_device(dev), (long)gen); | ||
891 | |||
892 | return 0; | ||
893 | } | ||
894 | |||
797 | static void fw_device_init(struct work_struct *work) | 895 | static void fw_device_init(struct work_struct *work) |
798 | { | 896 | { |
799 | struct fw_device *device = | 897 | struct fw_device *device = |
@@ -849,9 +947,13 @@ static void fw_device_init(struct work_struct *work) | |||
849 | device->device.devt = MKDEV(fw_cdev_major, minor); | 947 | device->device.devt = MKDEV(fw_cdev_major, minor); |
850 | dev_set_name(&device->device, "fw%d", minor); | 948 | dev_set_name(&device->device, "fw%d", minor); |
851 | 949 | ||
950 | BUILD_BUG_ON(ARRAY_SIZE(device->attribute_group.attrs) < | ||
951 | ARRAY_SIZE(fw_device_attributes) + | ||
952 | ARRAY_SIZE(config_rom_attributes)); | ||
852 | init_fw_attribute_group(&device->device, | 953 | init_fw_attribute_group(&device->device, |
853 | fw_device_attributes, | 954 | fw_device_attributes, |
854 | &device->attribute_group); | 955 | &device->attribute_group); |
956 | |||
855 | if (device_add(&device->device)) { | 957 | if (device_add(&device->device)) { |
856 | fw_error("Failed to add device.\n"); | 958 | fw_error("Failed to add device.\n"); |
857 | goto error_with_cdev; | 959 | goto error_with_cdev; |
@@ -888,7 +990,7 @@ static void fw_device_init(struct work_struct *work) | |||
888 | 1 << device->max_speed); | 990 | 1 << device->max_speed); |
889 | device->config_rom_retries = 0; | 991 | device->config_rom_retries = 0; |
890 | 992 | ||
891 | fw_device_set_broadcast_channel(device, device->generation); | 993 | set_broadcast_channel(device, device->generation); |
892 | } | 994 | } |
893 | 995 | ||
894 | /* | 996 | /* |
@@ -993,6 +1095,9 @@ static void fw_device_refresh(struct work_struct *work) | |||
993 | 1095 | ||
994 | create_units(device); | 1096 | create_units(device); |
995 | 1097 | ||
1098 | /* Userspace may want to re-read attributes. */ | ||
1099 | kobject_uevent(&device->device.kobj, KOBJ_CHANGE); | ||
1100 | |||
996 | if (atomic_cmpxchg(&device->state, | 1101 | if (atomic_cmpxchg(&device->state, |
997 | FW_DEVICE_INITIALIZING, | 1102 | FW_DEVICE_INITIALIZING, |
998 | FW_DEVICE_RUNNING) == FW_DEVICE_GONE) | 1103 | FW_DEVICE_RUNNING) == FW_DEVICE_GONE) |
@@ -1042,6 +1147,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1042 | device->node = fw_node_get(node); | 1147 | device->node = fw_node_get(node); |
1043 | device->node_id = node->node_id; | 1148 | device->node_id = node->node_id; |
1044 | device->generation = card->generation; | 1149 | device->generation = card->generation; |
1150 | device->is_local = node == card->local_node; | ||
1045 | mutex_init(&device->client_list_mutex); | 1151 | mutex_init(&device->client_list_mutex); |
1046 | INIT_LIST_HEAD(&device->client_list); | 1152 | INIT_LIST_HEAD(&device->client_list); |
1047 | 1153 | ||
@@ -1075,7 +1181,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1075 | FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { | 1181 | FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { |
1076 | PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); | 1182 | PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); |
1077 | schedule_delayed_work(&device->work, | 1183 | schedule_delayed_work(&device->work, |
1078 | node == card->local_node ? 0 : INITIAL_DELAY); | 1184 | device->is_local ? 0 : INITIAL_DELAY); |
1079 | } | 1185 | } |
1080 | break; | 1186 | break; |
1081 | 1187 | ||
diff --git a/drivers/firewire/fw-iso.c b/drivers/firewire/core-iso.c index 2baf1007253..28076c892d7 100644 --- a/drivers/firewire/fw-iso.c +++ b/drivers/firewire/core-iso.c | |||
@@ -22,14 +22,16 @@ | |||
22 | 22 | ||
23 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/firewire.h> | ||
25 | #include <linux/firewire-constants.h> | 26 | #include <linux/firewire-constants.h> |
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
27 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
28 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
29 | #include <linux/vmalloc.h> | 30 | #include <linux/vmalloc.h> |
30 | 31 | ||
31 | #include "fw-topology.h" | 32 | #include <asm/byteorder.h> |
32 | #include "fw-transaction.h" | 33 | |
34 | #include "core.h" | ||
33 | 35 | ||
34 | /* | 36 | /* |
35 | * Isochronous DMA context management | 37 | * Isochronous DMA context management |
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/core-topology.c index d0deecc4de9..fddf2b35893 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/core-topology.c | |||
@@ -18,13 +18,22 @@ | |||
18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/module.h> | 21 | #include <linux/bug.h> |
22 | #include <linux/wait.h> | ||
23 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
24 | #include <asm/bug.h> | 23 | #include <linux/firewire.h> |
24 | #include <linux/firewire-constants.h> | ||
25 | #include <linux/jiffies.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/string.h> | ||
32 | |||
33 | #include <asm/atomic.h> | ||
25 | #include <asm/system.h> | 34 | #include <asm/system.h> |
26 | #include "fw-transaction.h" | 35 | |
27 | #include "fw-topology.h" | 36 | #include "core.h" |
28 | 37 | ||
29 | #define SELF_ID_PHY_ID(q) (((q) >> 24) & 0x3f) | 38 | #define SELF_ID_PHY_ID(q) (((q) >> 24) & 0x3f) |
30 | #define SELF_ID_EXTENDED(q) (((q) >> 23) & 0x01) | 39 | #define SELF_ID_EXTENDED(q) (((q) >> 23) & 0x01) |
@@ -37,6 +46,11 @@ | |||
37 | 46 | ||
38 | #define SELF_ID_EXT_SEQUENCE(q) (((q) >> 20) & 0x07) | 47 | #define SELF_ID_EXT_SEQUENCE(q) (((q) >> 20) & 0x07) |
39 | 48 | ||
49 | #define SELFID_PORT_CHILD 0x3 | ||
50 | #define SELFID_PORT_PARENT 0x2 | ||
51 | #define SELFID_PORT_NCONN 0x1 | ||
52 | #define SELFID_PORT_NONE 0x0 | ||
53 | |||
40 | static u32 *count_ports(u32 *sid, int *total_port_count, int *child_port_count) | 54 | static u32 *count_ports(u32 *sid, int *total_port_count, int *child_port_count) |
41 | { | 55 | { |
42 | u32 q; | 56 | u32 q; |
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/core-transaction.c index 283dac6d327..479b22f5a1e 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -18,24 +18,28 @@ | |||
18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/bug.h> | ||
21 | #include <linux/completion.h> | 22 | #include <linux/completion.h> |
23 | #include <linux/device.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/firewire.h> | ||
26 | #include <linux/firewire-constants.h> | ||
27 | #include <linux/fs.h> | ||
28 | #include <linux/init.h> | ||
22 | #include <linux/idr.h> | 29 | #include <linux/idr.h> |
30 | #include <linux/jiffies.h> | ||
23 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
24 | #include <linux/kref.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/pci.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/poll.h> | ||
32 | #include <linux/list.h> | 32 | #include <linux/list.h> |
33 | #include <linux/kthread.h> | 33 | #include <linux/module.h> |
34 | #include <asm/uaccess.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/spinlock.h> | ||
36 | #include <linux/string.h> | ||
37 | #include <linux/timer.h> | ||
38 | #include <linux/types.h> | ||
35 | 39 | ||
36 | #include "fw-transaction.h" | 40 | #include <asm/byteorder.h> |
37 | #include "fw-topology.h" | 41 | |
38 | #include "fw-device.h" | 42 | #include "core.h" |
39 | 43 | ||
40 | #define HEADER_PRI(pri) ((pri) << 0) | 44 | #define HEADER_PRI(pri) ((pri) << 0) |
41 | #define HEADER_TCODE(tcode) ((tcode) << 4) | 45 | #define HEADER_TCODE(tcode) ((tcode) << 4) |
@@ -60,6 +64,10 @@ | |||
60 | #define HEADER_DESTINATION_IS_BROADCAST(q) \ | 64 | #define HEADER_DESTINATION_IS_BROADCAST(q) \ |
61 | (((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f)) | 65 | (((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f)) |
62 | 66 | ||
67 | #define PHY_PACKET_CONFIG 0x0 | ||
68 | #define PHY_PACKET_LINK_ON 0x1 | ||
69 | #define PHY_PACKET_SELF_ID 0x2 | ||
70 | |||
63 | #define PHY_CONFIG_GAP_COUNT(gap_count) (((gap_count) << 16) | (1 << 22)) | 71 | #define PHY_CONFIG_GAP_COUNT(gap_count) (((gap_count) << 16) | (1 << 22)) |
64 | #define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23)) | 72 | #define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23)) |
65 | #define PHY_IDENTIFIER(id) ((id) << 30) | 73 | #define PHY_IDENTIFIER(id) ((id) << 30) |
@@ -74,7 +82,7 @@ static int close_transaction(struct fw_transaction *transaction, | |||
74 | list_for_each_entry(t, &card->transaction_list, link) { | 82 | list_for_each_entry(t, &card->transaction_list, link) { |
75 | if (t == transaction) { | 83 | if (t == transaction) { |
76 | list_del(&t->link); | 84 | list_del(&t->link); |
77 | card->tlabel_mask &= ~(1 << t->tlabel); | 85 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
78 | break; | 86 | break; |
79 | } | 87 | } |
80 | } | 88 | } |
@@ -280,14 +288,14 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, | |||
280 | spin_lock_irqsave(&card->lock, flags); | 288 | spin_lock_irqsave(&card->lock, flags); |
281 | 289 | ||
282 | tlabel = card->current_tlabel; | 290 | tlabel = card->current_tlabel; |
283 | if (card->tlabel_mask & (1 << tlabel)) { | 291 | if (card->tlabel_mask & (1ULL << tlabel)) { |
284 | spin_unlock_irqrestore(&card->lock, flags); | 292 | spin_unlock_irqrestore(&card->lock, flags); |
285 | callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data); | 293 | callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data); |
286 | return; | 294 | return; |
287 | } | 295 | } |
288 | 296 | ||
289 | card->current_tlabel = (card->current_tlabel + 1) & 0x1f; | 297 | card->current_tlabel = (card->current_tlabel + 1) & 0x3f; |
290 | card->tlabel_mask |= (1 << tlabel); | 298 | card->tlabel_mask |= (1ULL << tlabel); |
291 | 299 | ||
292 | t->node_id = destination_id; | 300 | t->node_id = destination_id; |
293 | t->tlabel = tlabel; | 301 | t->tlabel = tlabel; |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h new file mode 100644 index 00000000000..0a25a7b38a8 --- /dev/null +++ b/drivers/firewire/core.h | |||
@@ -0,0 +1,293 @@ | |||
1 | #ifndef _FIREWIRE_CORE_H | ||
2 | #define _FIREWIRE_CORE_H | ||
3 | |||
4 | #include <linux/dma-mapping.h> | ||
5 | #include <linux/fs.h> | ||
6 | #include <linux/list.h> | ||
7 | #include <linux/idr.h> | ||
8 | #include <linux/mm_types.h> | ||
9 | #include <linux/rwsem.h> | ||
10 | #include <linux/slab.h> | ||
11 | #include <linux/types.h> | ||
12 | |||
13 | #include <asm/atomic.h> | ||
14 | |||
15 | struct device; | ||
16 | struct fw_card; | ||
17 | struct fw_device; | ||
18 | struct fw_iso_buffer; | ||
19 | struct fw_iso_context; | ||
20 | struct fw_iso_packet; | ||
21 | struct fw_node; | ||
22 | struct fw_packet; | ||
23 | |||
24 | |||
25 | /* -card */ | ||
26 | |||
27 | /* bitfields within the PHY registers */ | ||
28 | #define PHY_LINK_ACTIVE 0x80 | ||
29 | #define PHY_CONTENDER 0x40 | ||
30 | #define PHY_BUS_RESET 0x40 | ||
31 | #define PHY_BUS_SHORT_RESET 0x40 | ||
32 | |||
33 | #define BANDWIDTH_AVAILABLE_INITIAL 4915 | ||
34 | #define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31) | ||
35 | #define BROADCAST_CHANNEL_VALID (1 << 30) | ||
36 | |||
37 | struct fw_card_driver { | ||
38 | /* | ||
39 | * Enable the given card with the given initial config rom. | ||
40 | * This function is expected to activate the card, and either | ||
41 | * enable the PHY or set the link_on bit and initiate a bus | ||
42 | * reset. | ||
43 | */ | ||
44 | int (*enable)(struct fw_card *card, u32 *config_rom, size_t length); | ||
45 | |||
46 | int (*update_phy_reg)(struct fw_card *card, int address, | ||
47 | int clear_bits, int set_bits); | ||
48 | |||
49 | /* | ||
50 | * Update the config rom for an enabled card. This function | ||
51 | * should change the config rom that is presented on the bus | ||
52 | * an initiate a bus reset. | ||
53 | */ | ||
54 | int (*set_config_rom)(struct fw_card *card, | ||
55 | u32 *config_rom, size_t length); | ||
56 | |||
57 | void (*send_request)(struct fw_card *card, struct fw_packet *packet); | ||
58 | void (*send_response)(struct fw_card *card, struct fw_packet *packet); | ||
59 | /* Calling cancel is valid once a packet has been submitted. */ | ||
60 | int (*cancel_packet)(struct fw_card *card, struct fw_packet *packet); | ||
61 | |||
62 | /* | ||
63 | * Allow the specified node ID to do direct DMA out and in of | ||
64 | * host memory. The card will disable this for all node when | ||
65 | * a bus reset happens, so driver need to reenable this after | ||
66 | * bus reset. Returns 0 on success, -ENODEV if the card | ||
67 | * doesn't support this, -ESTALE if the generation doesn't | ||
68 | * match. | ||
69 | */ | ||
70 | int (*enable_phys_dma)(struct fw_card *card, | ||
71 | int node_id, int generation); | ||
72 | |||
73 | u64 (*get_bus_time)(struct fw_card *card); | ||
74 | |||
75 | struct fw_iso_context * | ||
76 | (*allocate_iso_context)(struct fw_card *card, | ||
77 | int type, int channel, size_t header_size); | ||
78 | void (*free_iso_context)(struct fw_iso_context *ctx); | ||
79 | |||
80 | int (*start_iso)(struct fw_iso_context *ctx, | ||
81 | s32 cycle, u32 sync, u32 tags); | ||
82 | |||
83 | int (*queue_iso)(struct fw_iso_context *ctx, | ||
84 | struct fw_iso_packet *packet, | ||
85 | struct fw_iso_buffer *buffer, | ||
86 | unsigned long payload); | ||
87 | |||
88 | int (*stop_iso)(struct fw_iso_context *ctx); | ||
89 | }; | ||
90 | |||
91 | void fw_card_initialize(struct fw_card *card, | ||
92 | const struct fw_card_driver *driver, struct device *device); | ||
93 | int fw_card_add(struct fw_card *card, | ||
94 | u32 max_receive, u32 link_speed, u64 guid); | ||
95 | void fw_core_remove_card(struct fw_card *card); | ||
96 | int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset); | ||
97 | int fw_compute_block_crc(u32 *block); | ||
98 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); | ||
99 | |||
100 | struct fw_descriptor { | ||
101 | struct list_head link; | ||
102 | size_t length; | ||
103 | u32 immediate; | ||
104 | u32 key; | ||
105 | const u32 *data; | ||
106 | }; | ||
107 | |||
108 | int fw_core_add_descriptor(struct fw_descriptor *desc); | ||
109 | void fw_core_remove_descriptor(struct fw_descriptor *desc); | ||
110 | |||
111 | |||
112 | /* -cdev */ | ||
113 | |||
114 | extern const struct file_operations fw_device_ops; | ||
115 | |||
116 | void fw_device_cdev_update(struct fw_device *device); | ||
117 | void fw_device_cdev_remove(struct fw_device *device); | ||
118 | |||
119 | |||
120 | /* -device */ | ||
121 | |||
122 | extern struct rw_semaphore fw_device_rwsem; | ||
123 | extern struct idr fw_device_idr; | ||
124 | extern int fw_cdev_major; | ||
125 | |||
126 | struct fw_device *fw_device_get_by_devt(dev_t devt); | ||
127 | int fw_device_set_broadcast_channel(struct device *dev, void *gen); | ||
128 | void fw_node_event(struct fw_card *card, struct fw_node *node, int event); | ||
129 | |||
130 | |||
131 | /* -iso */ | ||
132 | |||
133 | /* | ||
134 | * The iso packet format allows for an immediate header/payload part | ||
135 | * stored in 'header' immediately after the packet info plus an | ||
136 | * indirect payload part that is pointer to by the 'payload' field. | ||
137 | * Applications can use one or the other or both to implement simple | ||
138 | * low-bandwidth streaming (e.g. audio) or more advanced | ||
139 | * scatter-gather streaming (e.g. assembling video frame automatically). | ||
140 | */ | ||
141 | struct fw_iso_packet { | ||
142 | u16 payload_length; /* Length of indirect payload. */ | ||
143 | u32 interrupt:1; /* Generate interrupt on this packet */ | ||
144 | u32 skip:1; /* Set to not send packet at all. */ | ||
145 | u32 tag:2; | ||
146 | u32 sy:4; | ||
147 | u32 header_length:8; /* Length of immediate header. */ | ||
148 | u32 header[0]; | ||
149 | }; | ||
150 | |||
151 | #define FW_ISO_CONTEXT_TRANSMIT 0 | ||
152 | #define FW_ISO_CONTEXT_RECEIVE 1 | ||
153 | |||
154 | #define FW_ISO_CONTEXT_MATCH_TAG0 1 | ||
155 | #define FW_ISO_CONTEXT_MATCH_TAG1 2 | ||
156 | #define FW_ISO_CONTEXT_MATCH_TAG2 4 | ||
157 | #define FW_ISO_CONTEXT_MATCH_TAG3 8 | ||
158 | #define FW_ISO_CONTEXT_MATCH_ALL_TAGS 15 | ||
159 | |||
160 | /* | ||
161 | * An iso buffer is just a set of pages mapped for DMA in the | ||
162 | * specified direction. Since the pages are to be used for DMA, they | ||
163 | * are not mapped into the kernel virtual address space. We store the | ||
164 | * DMA address in the page private. The helper function | ||
165 | * fw_iso_buffer_map() will map the pages into a given vma. | ||
166 | */ | ||
167 | struct fw_iso_buffer { | ||
168 | enum dma_data_direction direction; | ||
169 | struct page **pages; | ||
170 | int page_count; | ||
171 | }; | ||
172 | |||
173 | typedef void (*fw_iso_callback_t)(struct fw_iso_context *context, | ||
174 | u32 cycle, size_t header_length, | ||
175 | void *header, void *data); | ||
176 | |||
177 | struct fw_iso_context { | ||
178 | struct fw_card *card; | ||
179 | int type; | ||
180 | int channel; | ||
181 | int speed; | ||
182 | size_t header_size; | ||
183 | fw_iso_callback_t callback; | ||
184 | void *callback_data; | ||
185 | }; | ||
186 | |||
187 | int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card, | ||
188 | int page_count, enum dma_data_direction direction); | ||
189 | int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma); | ||
190 | void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card); | ||
191 | |||
192 | struct fw_iso_context *fw_iso_context_create(struct fw_card *card, | ||
193 | int type, int channel, int speed, size_t header_size, | ||
194 | fw_iso_callback_t callback, void *callback_data); | ||
195 | int fw_iso_context_queue(struct fw_iso_context *ctx, | ||
196 | struct fw_iso_packet *packet, | ||
197 | struct fw_iso_buffer *buffer, | ||
198 | unsigned long payload); | ||
199 | int fw_iso_context_start(struct fw_iso_context *ctx, | ||
200 | int cycle, int sync, int tags); | ||
201 | int fw_iso_context_stop(struct fw_iso_context *ctx); | ||
202 | void fw_iso_context_destroy(struct fw_iso_context *ctx); | ||
203 | |||
204 | void fw_iso_resource_manage(struct fw_card *card, int generation, | ||
205 | u64 channels_mask, int *channel, int *bandwidth, bool allocate); | ||
206 | |||
207 | |||
208 | /* -topology */ | ||
209 | |||
210 | enum { | ||
211 | FW_NODE_CREATED, | ||
212 | FW_NODE_UPDATED, | ||
213 | FW_NODE_DESTROYED, | ||
214 | FW_NODE_LINK_ON, | ||
215 | FW_NODE_LINK_OFF, | ||
216 | FW_NODE_INITIATED_RESET, | ||
217 | }; | ||
218 | |||
219 | struct fw_node { | ||
220 | u16 node_id; | ||
221 | u8 color; | ||
222 | u8 port_count; | ||
223 | u8 link_on:1; | ||
224 | u8 initiated_reset:1; | ||
225 | u8 b_path:1; | ||
226 | u8 phy_speed:2; /* As in the self ID packet. */ | ||
227 | u8 max_speed:2; /* Minimum of all phy-speeds on the path from the | ||
228 | * local node to this node. */ | ||
229 | u8 max_depth:4; /* Maximum depth to any leaf node */ | ||
230 | u8 max_hops:4; /* Max hops in this sub tree */ | ||
231 | atomic_t ref_count; | ||
232 | |||
233 | /* For serializing node topology into a list. */ | ||
234 | struct list_head link; | ||
235 | |||
236 | /* Upper layer specific data. */ | ||
237 | void *data; | ||
238 | |||
239 | struct fw_node *ports[0]; | ||
240 | }; | ||
241 | |||
242 | static inline struct fw_node *fw_node_get(struct fw_node *node) | ||
243 | { | ||
244 | atomic_inc(&node->ref_count); | ||
245 | |||
246 | return node; | ||
247 | } | ||
248 | |||
249 | static inline void fw_node_put(struct fw_node *node) | ||
250 | { | ||
251 | if (atomic_dec_and_test(&node->ref_count)) | ||
252 | kfree(node); | ||
253 | } | ||
254 | |||
255 | void fw_core_handle_bus_reset(struct fw_card *card, int node_id, | ||
256 | int generation, int self_id_count, u32 *self_ids); | ||
257 | void fw_destroy_nodes(struct fw_card *card); | ||
258 | |||
259 | /* | ||
260 | * Check whether new_generation is the immediate successor of old_generation. | ||
261 | * Take counter roll-over at 255 (as per OHCI) into account. | ||
262 | */ | ||
263 | static inline bool is_next_generation(int new_generation, int old_generation) | ||
264 | { | ||
265 | return (new_generation & 0xff) == ((old_generation + 1) & 0xff); | ||
266 | } | ||
267 | |||
268 | |||
269 | /* -transaction */ | ||
270 | |||
271 | #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) | ||
272 | #define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) | ||
273 | #define TCODE_IS_REQUEST(tcode) (((tcode) & 2) == 0) | ||
274 | #define TCODE_IS_RESPONSE(tcode) (((tcode) & 2) != 0) | ||
275 | #define TCODE_HAS_REQUEST_DATA(tcode) (((tcode) & 12) != 4) | ||
276 | #define TCODE_HAS_RESPONSE_DATA(tcode) (((tcode) & 12) != 0) | ||
277 | |||
278 | #define LOCAL_BUS 0xffc0 | ||
279 | |||
280 | void fw_core_handle_request(struct fw_card *card, struct fw_packet *request); | ||
281 | void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet); | ||
282 | void fw_fill_response(struct fw_packet *response, u32 *request_header, | ||
283 | int rcode, void *payload, size_t length); | ||
284 | void fw_flush_transactions(struct fw_card *card); | ||
285 | void fw_send_phy_config(struct fw_card *card, | ||
286 | int node_id, int generation, int gap_count); | ||
287 | |||
288 | static inline int fw_stream_packet_destination_id(int tag, int channel, int sy) | ||
289 | { | ||
290 | return tag << 14 | channel << 8 | sy; | ||
291 | } | ||
292 | |||
293 | #endif /* _FIREWIRE_CORE_H */ | ||
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h deleted file mode 100644 index 97588937c01..00000000000 --- a/drivers/firewire/fw-device.h +++ /dev/null | |||
@@ -1,202 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software Foundation, | ||
16 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #ifndef __fw_device_h | ||
20 | #define __fw_device_h | ||
21 | |||
22 | #include <linux/device.h> | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/idr.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/list.h> | ||
27 | #include <linux/mutex.h> | ||
28 | #include <linux/rwsem.h> | ||
29 | #include <linux/sysfs.h> | ||
30 | #include <linux/types.h> | ||
31 | #include <linux/workqueue.h> | ||
32 | |||
33 | #include <asm/atomic.h> | ||
34 | |||
35 | enum fw_device_state { | ||
36 | FW_DEVICE_INITIALIZING, | ||
37 | FW_DEVICE_RUNNING, | ||
38 | FW_DEVICE_GONE, | ||
39 | FW_DEVICE_SHUTDOWN, | ||
40 | }; | ||
41 | |||
42 | struct fw_attribute_group { | ||
43 | struct attribute_group *groups[2]; | ||
44 | struct attribute_group group; | ||
45 | struct attribute *attrs[11]; | ||
46 | }; | ||
47 | |||
48 | struct fw_node; | ||
49 | struct fw_card; | ||
50 | |||
51 | /* | ||
52 | * Note, fw_device.generation always has to be read before fw_device.node_id. | ||
53 | * Use SMP memory barriers to ensure this. Otherwise requests will be sent | ||
54 | * to an outdated node_id if the generation was updated in the meantime due | ||
55 | * to a bus reset. | ||
56 | * | ||
57 | * Likewise, fw-core will take care to update .node_id before .generation so | ||
58 | * that whenever fw_device.generation is current WRT the actual bus generation, | ||
59 | * fw_device.node_id is guaranteed to be current too. | ||
60 | * | ||
61 | * The same applies to fw_device.card->node_id vs. fw_device.generation. | ||
62 | * | ||
63 | * fw_device.config_rom and fw_device.config_rom_length may be accessed during | ||
64 | * the lifetime of any fw_unit belonging to the fw_device, before device_del() | ||
65 | * was called on the last fw_unit. Alternatively, they may be accessed while | ||
66 | * holding fw_device_rwsem. | ||
67 | */ | ||
68 | struct fw_device { | ||
69 | atomic_t state; | ||
70 | struct fw_node *node; | ||
71 | int node_id; | ||
72 | int generation; | ||
73 | unsigned max_speed; | ||
74 | struct fw_card *card; | ||
75 | struct device device; | ||
76 | |||
77 | struct mutex client_list_mutex; | ||
78 | struct list_head client_list; | ||
79 | |||
80 | u32 *config_rom; | ||
81 | size_t config_rom_length; | ||
82 | int config_rom_retries; | ||
83 | unsigned cmc:1; | ||
84 | unsigned bc_implemented:2; | ||
85 | |||
86 | struct delayed_work work; | ||
87 | struct fw_attribute_group attribute_group; | ||
88 | }; | ||
89 | |||
90 | static inline struct fw_device *fw_device(struct device *dev) | ||
91 | { | ||
92 | return container_of(dev, struct fw_device, device); | ||
93 | } | ||
94 | |||
95 | static inline int fw_device_is_shutdown(struct fw_device *device) | ||
96 | { | ||
97 | return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; | ||
98 | } | ||
99 | |||
100 | static inline struct fw_device *fw_device_get(struct fw_device *device) | ||
101 | { | ||
102 | get_device(&device->device); | ||
103 | |||
104 | return device; | ||
105 | } | ||
106 | |||
107 | static inline void fw_device_put(struct fw_device *device) | ||
108 | { | ||
109 | put_device(&device->device); | ||
110 | } | ||
111 | |||
112 | struct fw_device *fw_device_get_by_devt(dev_t devt); | ||
113 | int fw_device_enable_phys_dma(struct fw_device *device); | ||
114 | void fw_device_set_broadcast_channel(struct fw_device *device, int generation); | ||
115 | |||
116 | void fw_device_cdev_update(struct fw_device *device); | ||
117 | void fw_device_cdev_remove(struct fw_device *device); | ||
118 | |||
119 | extern struct rw_semaphore fw_device_rwsem; | ||
120 | extern struct idr fw_device_idr; | ||
121 | extern int fw_cdev_major; | ||
122 | |||
123 | /* | ||
124 | * fw_unit.directory must not be accessed after device_del(&fw_unit.device). | ||
125 | */ | ||
126 | struct fw_unit { | ||
127 | struct device device; | ||
128 | u32 *directory; | ||
129 | struct fw_attribute_group attribute_group; | ||
130 | }; | ||
131 | |||
132 | static inline struct fw_unit *fw_unit(struct device *dev) | ||
133 | { | ||
134 | return container_of(dev, struct fw_unit, device); | ||
135 | } | ||
136 | |||
137 | static inline struct fw_unit *fw_unit_get(struct fw_unit *unit) | ||
138 | { | ||
139 | get_device(&unit->device); | ||
140 | |||
141 | return unit; | ||
142 | } | ||
143 | |||
144 | static inline void fw_unit_put(struct fw_unit *unit) | ||
145 | { | ||
146 | put_device(&unit->device); | ||
147 | } | ||
148 | |||
149 | #define CSR_OFFSET 0x40 | ||
150 | #define CSR_LEAF 0x80 | ||
151 | #define CSR_DIRECTORY 0xc0 | ||
152 | |||
153 | #define CSR_DESCRIPTOR 0x01 | ||
154 | #define CSR_VENDOR 0x03 | ||
155 | #define CSR_HARDWARE_VERSION 0x04 | ||
156 | #define CSR_NODE_CAPABILITIES 0x0c | ||
157 | #define CSR_UNIT 0x11 | ||
158 | #define CSR_SPECIFIER_ID 0x12 | ||
159 | #define CSR_VERSION 0x13 | ||
160 | #define CSR_DEPENDENT_INFO 0x14 | ||
161 | #define CSR_MODEL 0x17 | ||
162 | #define CSR_INSTANCE 0x18 | ||
163 | #define CSR_DIRECTORY_ID 0x20 | ||
164 | |||
165 | struct fw_csr_iterator { | ||
166 | u32 *p; | ||
167 | u32 *end; | ||
168 | }; | ||
169 | |||
170 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 *p); | ||
171 | int fw_csr_iterator_next(struct fw_csr_iterator *ci, | ||
172 | int *key, int *value); | ||
173 | |||
174 | #define FW_MATCH_VENDOR 0x0001 | ||
175 | #define FW_MATCH_MODEL 0x0002 | ||
176 | #define FW_MATCH_SPECIFIER_ID 0x0004 | ||
177 | #define FW_MATCH_VERSION 0x0008 | ||
178 | |||
179 | struct fw_device_id { | ||
180 | u32 match_flags; | ||
181 | u32 vendor; | ||
182 | u32 model; | ||
183 | u32 specifier_id; | ||
184 | u32 version; | ||
185 | void *driver_data; | ||
186 | }; | ||
187 | |||
188 | struct fw_driver { | ||
189 | struct device_driver driver; | ||
190 | /* Called when the parent device sits through a bus reset. */ | ||
191 | void (*update) (struct fw_unit *unit); | ||
192 | const struct fw_device_id *id_table; | ||
193 | }; | ||
194 | |||
195 | static inline struct fw_driver *fw_driver(struct device_driver *drv) | ||
196 | { | ||
197 | return container_of(drv, struct fw_driver, driver); | ||
198 | } | ||
199 | |||
200 | extern const struct file_operations fw_device_ops; | ||
201 | |||
202 | #endif /* __fw_device_h */ | ||
diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h deleted file mode 100644 index 3c497bb4fae..00000000000 --- a/drivers/firewire/fw-topology.h +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2006 Kristian Hoegsberg <krh@bitplanet.net> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software Foundation, | ||
16 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #ifndef __fw_topology_h | ||
20 | #define __fw_topology_h | ||
21 | |||
22 | #include <linux/list.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | #include <asm/atomic.h> | ||
26 | |||
27 | enum { | ||
28 | FW_NODE_CREATED, | ||
29 | FW_NODE_UPDATED, | ||
30 | FW_NODE_DESTROYED, | ||
31 | FW_NODE_LINK_ON, | ||
32 | FW_NODE_LINK_OFF, | ||
33 | FW_NODE_INITIATED_RESET, | ||
34 | }; | ||
35 | |||
36 | struct fw_node { | ||
37 | u16 node_id; | ||
38 | u8 color; | ||
39 | u8 port_count; | ||
40 | u8 link_on : 1; | ||
41 | u8 initiated_reset : 1; | ||
42 | u8 b_path : 1; | ||
43 | u8 phy_speed : 2; /* As in the self ID packet. */ | ||
44 | u8 max_speed : 2; /* Minimum of all phy-speeds on the path from the | ||
45 | * local node to this node. */ | ||
46 | u8 max_depth : 4; /* Maximum depth to any leaf node */ | ||
47 | u8 max_hops : 4; /* Max hops in this sub tree */ | ||
48 | atomic_t ref_count; | ||
49 | |||
50 | /* For serializing node topology into a list. */ | ||
51 | struct list_head link; | ||
52 | |||
53 | /* Upper layer specific data. */ | ||
54 | void *data; | ||
55 | |||
56 | struct fw_node *ports[0]; | ||
57 | }; | ||
58 | |||
59 | static inline struct fw_node *fw_node_get(struct fw_node *node) | ||
60 | { | ||
61 | atomic_inc(&node->ref_count); | ||
62 | |||
63 | return node; | ||
64 | } | ||
65 | |||
66 | static inline void fw_node_put(struct fw_node *node) | ||
67 | { | ||
68 | if (atomic_dec_and_test(&node->ref_count)) | ||
69 | kfree(node); | ||
70 | } | ||
71 | |||
72 | struct fw_card; | ||
73 | void fw_destroy_nodes(struct fw_card *card); | ||
74 | |||
75 | int fw_compute_block_crc(u32 *block); | ||
76 | |||
77 | #endif /* __fw_topology_h */ | ||
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h deleted file mode 100644 index dfa799068f8..00000000000 --- a/drivers/firewire/fw-transaction.h +++ /dev/null | |||
@@ -1,446 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2006 Kristian Hoegsberg <krh@bitplanet.net> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software Foundation, | ||
16 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #ifndef __fw_transaction_h | ||
20 | #define __fw_transaction_h | ||
21 | |||
22 | #include <linux/completion.h> | ||
23 | #include <linux/device.h> | ||
24 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/firewire-constants.h> | ||
26 | #include <linux/kref.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <linux/spinlock_types.h> | ||
29 | #include <linux/timer.h> | ||
30 | #include <linux/types.h> | ||
31 | #include <linux/workqueue.h> | ||
32 | |||
33 | #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) | ||
34 | #define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) | ||
35 | #define TCODE_IS_REQUEST(tcode) (((tcode) & 2) == 0) | ||
36 | #define TCODE_IS_RESPONSE(tcode) (((tcode) & 2) != 0) | ||
37 | #define TCODE_HAS_REQUEST_DATA(tcode) (((tcode) & 12) != 4) | ||
38 | #define TCODE_HAS_RESPONSE_DATA(tcode) (((tcode) & 12) != 0) | ||
39 | |||
40 | #define LOCAL_BUS 0xffc0 | ||
41 | |||
42 | #define SELFID_PORT_CHILD 0x3 | ||
43 | #define SELFID_PORT_PARENT 0x2 | ||
44 | #define SELFID_PORT_NCONN 0x1 | ||
45 | #define SELFID_PORT_NONE 0x0 | ||
46 | |||
47 | #define PHY_PACKET_CONFIG 0x0 | ||
48 | #define PHY_PACKET_LINK_ON 0x1 | ||
49 | #define PHY_PACKET_SELF_ID 0x2 | ||
50 | |||
51 | /* Bit fields _within_ the PHY registers. */ | ||
52 | #define PHY_LINK_ACTIVE 0x80 | ||
53 | #define PHY_CONTENDER 0x40 | ||
54 | #define PHY_BUS_RESET 0x40 | ||
55 | #define PHY_BUS_SHORT_RESET 0x40 | ||
56 | |||
57 | #define CSR_REGISTER_BASE 0xfffff0000000ULL | ||
58 | |||
59 | /* register offsets relative to CSR_REGISTER_BASE */ | ||
60 | #define CSR_STATE_CLEAR 0x0 | ||
61 | #define CSR_STATE_SET 0x4 | ||
62 | #define CSR_NODE_IDS 0x8 | ||
63 | #define CSR_RESET_START 0xc | ||
64 | #define CSR_SPLIT_TIMEOUT_HI 0x18 | ||
65 | #define CSR_SPLIT_TIMEOUT_LO 0x1c | ||
66 | #define CSR_CYCLE_TIME 0x200 | ||
67 | #define CSR_BUS_TIME 0x204 | ||
68 | #define CSR_BUSY_TIMEOUT 0x210 | ||
69 | #define CSR_BUS_MANAGER_ID 0x21c | ||
70 | #define CSR_BANDWIDTH_AVAILABLE 0x220 | ||
71 | #define CSR_CHANNELS_AVAILABLE 0x224 | ||
72 | #define CSR_CHANNELS_AVAILABLE_HI 0x224 | ||
73 | #define CSR_CHANNELS_AVAILABLE_LO 0x228 | ||
74 | #define CSR_BROADCAST_CHANNEL 0x234 | ||
75 | #define CSR_CONFIG_ROM 0x400 | ||
76 | #define CSR_CONFIG_ROM_END 0x800 | ||
77 | #define CSR_FCP_COMMAND 0xB00 | ||
78 | #define CSR_FCP_RESPONSE 0xD00 | ||
79 | #define CSR_FCP_END 0xF00 | ||
80 | #define CSR_TOPOLOGY_MAP 0x1000 | ||
81 | #define CSR_TOPOLOGY_MAP_END 0x1400 | ||
82 | #define CSR_SPEED_MAP 0x2000 | ||
83 | #define CSR_SPEED_MAP_END 0x3000 | ||
84 | |||
85 | #define BANDWIDTH_AVAILABLE_INITIAL 4915 | ||
86 | #define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31) | ||
87 | #define BROADCAST_CHANNEL_VALID (1 << 30) | ||
88 | |||
89 | #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) | ||
90 | #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) | ||
91 | |||
92 | static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size) | ||
93 | { | ||
94 | u32 *dst = _dst; | ||
95 | __be32 *src = _src; | ||
96 | int i; | ||
97 | |||
98 | for (i = 0; i < size / 4; i++) | ||
99 | dst[i] = be32_to_cpu(src[i]); | ||
100 | } | ||
101 | |||
102 | static inline void fw_memcpy_to_be32(void *_dst, void *_src, size_t size) | ||
103 | { | ||
104 | fw_memcpy_from_be32(_dst, _src, size); | ||
105 | } | ||
106 | |||
107 | struct fw_card; | ||
108 | struct fw_packet; | ||
109 | struct fw_node; | ||
110 | struct fw_request; | ||
111 | |||
112 | struct fw_descriptor { | ||
113 | struct list_head link; | ||
114 | size_t length; | ||
115 | u32 immediate; | ||
116 | u32 key; | ||
117 | const u32 *data; | ||
118 | }; | ||
119 | |||
120 | int fw_core_add_descriptor(struct fw_descriptor *desc); | ||
121 | void fw_core_remove_descriptor(struct fw_descriptor *desc); | ||
122 | |||
123 | typedef void (*fw_packet_callback_t)(struct fw_packet *packet, | ||
124 | struct fw_card *card, int status); | ||
125 | |||
126 | typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode, | ||
127 | void *data, size_t length, | ||
128 | void *callback_data); | ||
129 | |||
130 | /* | ||
131 | * Important note: The callback must guarantee that either fw_send_response() | ||
132 | * or kfree() is called on the @request. | ||
133 | */ | ||
134 | typedef void (*fw_address_callback_t)(struct fw_card *card, | ||
135 | struct fw_request *request, | ||
136 | int tcode, int destination, int source, | ||
137 | int generation, int speed, | ||
138 | unsigned long long offset, | ||
139 | void *data, size_t length, | ||
140 | void *callback_data); | ||
141 | |||
142 | struct fw_packet { | ||
143 | int speed; | ||
144 | int generation; | ||
145 | u32 header[4]; | ||
146 | size_t header_length; | ||
147 | void *payload; | ||
148 | size_t payload_length; | ||
149 | dma_addr_t payload_bus; | ||
150 | u32 timestamp; | ||
151 | |||
152 | /* | ||
153 | * This callback is called when the packet transmission has | ||
154 | * completed; for successful transmission, the status code is | ||
155 | * the ack received from the destination, otherwise it's a | ||
156 | * negative errno: ENOMEM, ESTALE, ETIMEDOUT, ENODEV, EIO. | ||
157 | * The callback can be called from tasklet context and thus | ||
158 | * must never block. | ||
159 | */ | ||
160 | fw_packet_callback_t callback; | ||
161 | int ack; | ||
162 | struct list_head link; | ||
163 | void *driver_data; | ||
164 | }; | ||
165 | |||
166 | struct fw_transaction { | ||
167 | int node_id; /* The generation is implied; it is always the current. */ | ||
168 | int tlabel; | ||
169 | int timestamp; | ||
170 | struct list_head link; | ||
171 | |||
172 | struct fw_packet packet; | ||
173 | |||
174 | /* | ||
175 | * The data passed to the callback is valid only during the | ||
176 | * callback. | ||
177 | */ | ||
178 | fw_transaction_callback_t callback; | ||
179 | void *callback_data; | ||
180 | }; | ||
181 | |||
182 | struct fw_address_handler { | ||
183 | u64 offset; | ||
184 | size_t length; | ||
185 | fw_address_callback_t address_callback; | ||
186 | void *callback_data; | ||
187 | struct list_head link; | ||
188 | }; | ||
189 | |||
190 | struct fw_address_region { | ||
191 | u64 start; | ||
192 | u64 end; | ||
193 | }; | ||
194 | |||
195 | extern const struct fw_address_region fw_high_memory_region; | ||
196 | |||
197 | int fw_core_add_address_handler(struct fw_address_handler *handler, | ||
198 | const struct fw_address_region *region); | ||
199 | void fw_core_remove_address_handler(struct fw_address_handler *handler); | ||
200 | void fw_fill_response(struct fw_packet *response, u32 *request_header, | ||
201 | int rcode, void *payload, size_t length); | ||
202 | void fw_send_response(struct fw_card *card, | ||
203 | struct fw_request *request, int rcode); | ||
204 | |||
205 | extern struct bus_type fw_bus_type; | ||
206 | |||
207 | struct fw_card { | ||
208 | const struct fw_card_driver *driver; | ||
209 | struct device *device; | ||
210 | struct kref kref; | ||
211 | struct completion done; | ||
212 | |||
213 | int node_id; | ||
214 | int generation; | ||
215 | int current_tlabel, tlabel_mask; | ||
216 | struct list_head transaction_list; | ||
217 | struct timer_list flush_timer; | ||
218 | unsigned long reset_jiffies; | ||
219 | |||
220 | unsigned long long guid; | ||
221 | unsigned max_receive; | ||
222 | int link_speed; | ||
223 | int config_rom_generation; | ||
224 | |||
225 | spinlock_t lock; /* Take this lock when handling the lists in | ||
226 | * this struct. */ | ||
227 | struct fw_node *local_node; | ||
228 | struct fw_node *root_node; | ||
229 | struct fw_node *irm_node; | ||
230 | u8 color; /* must be u8 to match the definition in struct fw_node */ | ||
231 | int gap_count; | ||
232 | bool beta_repeaters_present; | ||
233 | |||
234 | int index; | ||
235 | |||
236 | struct list_head link; | ||
237 | |||
238 | /* Work struct for BM duties. */ | ||
239 | struct delayed_work work; | ||
240 | int bm_retries; | ||
241 | int bm_generation; | ||
242 | |||
243 | bool broadcast_channel_allocated; | ||
244 | u32 broadcast_channel; | ||
245 | u32 topology_map[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4]; | ||
246 | }; | ||
247 | |||
248 | static inline struct fw_card *fw_card_get(struct fw_card *card) | ||
249 | { | ||
250 | kref_get(&card->kref); | ||
251 | |||
252 | return card; | ||
253 | } | ||
254 | |||
255 | void fw_card_release(struct kref *kref); | ||
256 | |||
257 | static inline void fw_card_put(struct fw_card *card) | ||
258 | { | ||
259 | kref_put(&card->kref, fw_card_release); | ||
260 | } | ||
261 | |||
262 | extern void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); | ||
263 | |||
264 | /* | ||
265 | * Check whether new_generation is the immediate successor of old_generation. | ||
266 | * Take counter roll-over at 255 (as per to OHCI) into account. | ||
267 | */ | ||
268 | static inline bool is_next_generation(int new_generation, int old_generation) | ||
269 | { | ||
270 | return (new_generation & 0xff) == ((old_generation + 1) & 0xff); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * The iso packet format allows for an immediate header/payload part | ||
275 | * stored in 'header' immediately after the packet info plus an | ||
276 | * indirect payload part that is pointer to by the 'payload' field. | ||
277 | * Applications can use one or the other or both to implement simple | ||
278 | * low-bandwidth streaming (e.g. audio) or more advanced | ||
279 | * scatter-gather streaming (e.g. assembling video frame automatically). | ||
280 | */ | ||
281 | |||
282 | struct fw_iso_packet { | ||
283 | u16 payload_length; /* Length of indirect payload. */ | ||
284 | u32 interrupt : 1; /* Generate interrupt on this packet */ | ||
285 | u32 skip : 1; /* Set to not send packet at all. */ | ||
286 | u32 tag : 2; | ||
287 | u32 sy : 4; | ||
288 | u32 header_length : 8; /* Length of immediate header. */ | ||
289 | u32 header[0]; | ||
290 | }; | ||
291 | |||
292 | #define FW_ISO_CONTEXT_TRANSMIT 0 | ||
293 | #define FW_ISO_CONTEXT_RECEIVE 1 | ||
294 | |||
295 | #define FW_ISO_CONTEXT_MATCH_TAG0 1 | ||
296 | #define FW_ISO_CONTEXT_MATCH_TAG1 2 | ||
297 | #define FW_ISO_CONTEXT_MATCH_TAG2 4 | ||
298 | #define FW_ISO_CONTEXT_MATCH_TAG3 8 | ||
299 | #define FW_ISO_CONTEXT_MATCH_ALL_TAGS 15 | ||
300 | |||
301 | struct fw_iso_context; | ||
302 | |||
303 | typedef void (*fw_iso_callback_t)(struct fw_iso_context *context, | ||
304 | u32 cycle, size_t header_length, | ||
305 | void *header, void *data); | ||
306 | |||
307 | /* | ||
308 | * An iso buffer is just a set of pages mapped for DMA in the | ||
309 | * specified direction. Since the pages are to be used for DMA, they | ||
310 | * are not mapped into the kernel virtual address space. We store the | ||
311 | * DMA address in the page private. The helper function | ||
312 | * fw_iso_buffer_map() will map the pages into a given vma. | ||
313 | */ | ||
314 | |||
315 | struct fw_iso_buffer { | ||
316 | enum dma_data_direction direction; | ||
317 | struct page **pages; | ||
318 | int page_count; | ||
319 | }; | ||
320 | |||
321 | struct fw_iso_context { | ||
322 | struct fw_card *card; | ||
323 | int type; | ||
324 | int channel; | ||
325 | int speed; | ||
326 | size_t header_size; | ||
327 | fw_iso_callback_t callback; | ||
328 | void *callback_data; | ||
329 | }; | ||
330 | |||
331 | int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card, | ||
332 | int page_count, enum dma_data_direction direction); | ||
333 | int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma); | ||
334 | void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card); | ||
335 | |||
336 | struct fw_iso_context *fw_iso_context_create(struct fw_card *card, | ||
337 | int type, int channel, int speed, size_t header_size, | ||
338 | fw_iso_callback_t callback, void *callback_data); | ||
339 | int fw_iso_context_queue(struct fw_iso_context *ctx, | ||
340 | struct fw_iso_packet *packet, | ||
341 | struct fw_iso_buffer *buffer, | ||
342 | unsigned long payload); | ||
343 | int fw_iso_context_start(struct fw_iso_context *ctx, | ||
344 | int cycle, int sync, int tags); | ||
345 | int fw_iso_context_stop(struct fw_iso_context *ctx); | ||
346 | void fw_iso_context_destroy(struct fw_iso_context *ctx); | ||
347 | |||
348 | void fw_iso_resource_manage(struct fw_card *card, int generation, | ||
349 | u64 channels_mask, int *channel, int *bandwidth, bool allocate); | ||
350 | |||
351 | struct fw_card_driver { | ||
352 | /* | ||
353 | * Enable the given card with the given initial config rom. | ||
354 | * This function is expected to activate the card, and either | ||
355 | * enable the PHY or set the link_on bit and initiate a bus | ||
356 | * reset. | ||
357 | */ | ||
358 | int (*enable)(struct fw_card *card, u32 *config_rom, size_t length); | ||
359 | |||
360 | int (*update_phy_reg)(struct fw_card *card, int address, | ||
361 | int clear_bits, int set_bits); | ||
362 | |||
363 | /* | ||
364 | * Update the config rom for an enabled card. This function | ||
365 | * should change the config rom that is presented on the bus | ||
366 | * an initiate a bus reset. | ||
367 | */ | ||
368 | int (*set_config_rom)(struct fw_card *card, | ||
369 | u32 *config_rom, size_t length); | ||
370 | |||
371 | void (*send_request)(struct fw_card *card, struct fw_packet *packet); | ||
372 | void (*send_response)(struct fw_card *card, struct fw_packet *packet); | ||
373 | /* Calling cancel is valid once a packet has been submitted. */ | ||
374 | int (*cancel_packet)(struct fw_card *card, struct fw_packet *packet); | ||
375 | |||
376 | /* | ||
377 | * Allow the specified node ID to do direct DMA out and in of | ||
378 | * host memory. The card will disable this for all node when | ||
379 | * a bus reset happens, so driver need to reenable this after | ||
380 | * bus reset. Returns 0 on success, -ENODEV if the card | ||
381 | * doesn't support this, -ESTALE if the generation doesn't | ||
382 | * match. | ||
383 | */ | ||
384 | int (*enable_phys_dma)(struct fw_card *card, | ||
385 | int node_id, int generation); | ||
386 | |||
387 | u64 (*get_bus_time)(struct fw_card *card); | ||
388 | |||
389 | struct fw_iso_context * | ||
390 | (*allocate_iso_context)(struct fw_card *card, | ||
391 | int type, int channel, size_t header_size); | ||
392 | void (*free_iso_context)(struct fw_iso_context *ctx); | ||
393 | |||
394 | int (*start_iso)(struct fw_iso_context *ctx, | ||
395 | s32 cycle, u32 sync, u32 tags); | ||
396 | |||
397 | int (*queue_iso)(struct fw_iso_context *ctx, | ||
398 | struct fw_iso_packet *packet, | ||
399 | struct fw_iso_buffer *buffer, | ||
400 | unsigned long payload); | ||
401 | |||
402 | int (*stop_iso)(struct fw_iso_context *ctx); | ||
403 | }; | ||
404 | |||
405 | int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset); | ||
406 | |||
407 | void fw_send_request(struct fw_card *card, struct fw_transaction *t, | ||
408 | int tcode, int destination_id, int generation, int speed, | ||
409 | unsigned long long offset, void *payload, size_t length, | ||
410 | fw_transaction_callback_t callback, void *callback_data); | ||
411 | int fw_cancel_transaction(struct fw_card *card, | ||
412 | struct fw_transaction *transaction); | ||
413 | void fw_flush_transactions(struct fw_card *card); | ||
414 | int fw_run_transaction(struct fw_card *card, int tcode, int destination_id, | ||
415 | int generation, int speed, unsigned long long offset, | ||
416 | void *payload, size_t length); | ||
417 | void fw_send_phy_config(struct fw_card *card, | ||
418 | int node_id, int generation, int gap_count); | ||
419 | |||
420 | static inline int fw_stream_packet_destination_id(int tag, int channel, int sy) | ||
421 | { | ||
422 | return tag << 14 | channel << 8 | sy; | ||
423 | } | ||
424 | |||
425 | /* | ||
426 | * Called by the topology code to inform the device code of node | ||
427 | * activity; found, lost, or updated nodes. | ||
428 | */ | ||
429 | void fw_node_event(struct fw_card *card, struct fw_node *node, int event); | ||
430 | |||
431 | /* API used by card level drivers */ | ||
432 | |||
433 | void fw_card_initialize(struct fw_card *card, | ||
434 | const struct fw_card_driver *driver, struct device *device); | ||
435 | int fw_card_add(struct fw_card *card, | ||
436 | u32 max_receive, u32 link_speed, u64 guid); | ||
437 | void fw_core_remove_card(struct fw_card *card); | ||
438 | void fw_core_handle_bus_reset(struct fw_card *card, int node_id, | ||
439 | int generation, int self_id_count, u32 *self_ids); | ||
440 | void fw_core_handle_request(struct fw_card *card, struct fw_packet *request); | ||
441 | void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet); | ||
442 | |||
443 | extern int fw_irm_set_broadcast_channel_register(struct device *dev, | ||
444 | void *data); | ||
445 | |||
446 | #endif /* __fw_transaction_h */ | ||
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/ohci.c index 1180d0be0bb..ecddd11b797 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -20,17 +20,25 @@ | |||
20 | 20 | ||
21 | #include <linux/compiler.h> | 21 | #include <linux/compiler.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/device.h> | ||
23 | #include <linux/dma-mapping.h> | 24 | #include <linux/dma-mapping.h> |
25 | #include <linux/firewire.h> | ||
26 | #include <linux/firewire-constants.h> | ||
24 | #include <linux/gfp.h> | 27 | #include <linux/gfp.h> |
25 | #include <linux/init.h> | 28 | #include <linux/init.h> |
26 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/io.h> | ||
27 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/list.h> | ||
28 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
29 | #include <linux/module.h> | 34 | #include <linux/module.h> |
30 | #include <linux/moduleparam.h> | 35 | #include <linux/moduleparam.h> |
31 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
32 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | #include <linux/string.h> | ||
33 | 39 | ||
40 | #include <asm/atomic.h> | ||
41 | #include <asm/byteorder.h> | ||
34 | #include <asm/page.h> | 42 | #include <asm/page.h> |
35 | #include <asm/system.h> | 43 | #include <asm/system.h> |
36 | 44 | ||
@@ -38,8 +46,8 @@ | |||
38 | #include <asm/pmac_feature.h> | 46 | #include <asm/pmac_feature.h> |
39 | #endif | 47 | #endif |
40 | 48 | ||
41 | #include "fw-ohci.h" | 49 | #include "core.h" |
42 | #include "fw-transaction.h" | 50 | #include "ohci.h" |
43 | 51 | ||
44 | #define DESCRIPTOR_OUTPUT_MORE 0 | 52 | #define DESCRIPTOR_OUTPUT_MORE 0 |
45 | #define DESCRIPTOR_OUTPUT_LAST (1 << 12) | 53 | #define DESCRIPTOR_OUTPUT_LAST (1 << 12) |
@@ -178,7 +186,7 @@ struct fw_ohci { | |||
178 | int node_id; | 186 | int node_id; |
179 | int generation; | 187 | int generation; |
180 | int request_generation; /* for timestamping incoming requests */ | 188 | int request_generation; /* for timestamping incoming requests */ |
181 | u32 bus_seconds; | 189 | atomic_t bus_seconds; |
182 | 190 | ||
183 | bool use_dualbuffer; | 191 | bool use_dualbuffer; |
184 | bool old_uninorth; | 192 | bool old_uninorth; |
@@ -231,7 +239,6 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
231 | #define OHCI1394_MAX_AT_RESP_RETRIES 0x2 | 239 | #define OHCI1394_MAX_AT_RESP_RETRIES 0x2 |
232 | #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 | 240 | #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 |
233 | 241 | ||
234 | #define FW_OHCI_MAJOR 240 | ||
235 | #define OHCI1394_REGISTER_SIZE 0x800 | 242 | #define OHCI1394_REGISTER_SIZE 0x800 |
236 | #define OHCI_LOOP_COUNT 500 | 243 | #define OHCI_LOOP_COUNT 500 |
237 | #define OHCI1394_PCI_HCI_Control 0x40 | 244 | #define OHCI1394_PCI_HCI_Control 0x40 |
@@ -1434,7 +1441,7 @@ static irqreturn_t irq_handler(int irq, void *data) | |||
1434 | if (event & OHCI1394_cycle64Seconds) { | 1441 | if (event & OHCI1394_cycle64Seconds) { |
1435 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1442 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); |
1436 | if ((cycle_time & 0x80000000) == 0) | 1443 | if ((cycle_time & 0x80000000) == 0) |
1437 | ohci->bus_seconds++; | 1444 | atomic_inc(&ohci->bus_seconds); |
1438 | } | 1445 | } |
1439 | 1446 | ||
1440 | return IRQ_HANDLED; | 1447 | return IRQ_HANDLED; |
@@ -1770,7 +1777,7 @@ static u64 ohci_get_bus_time(struct fw_card *card) | |||
1770 | u64 bus_time; | 1777 | u64 bus_time; |
1771 | 1778 | ||
1772 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1779 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); |
1773 | bus_time = ((u64) ohci->bus_seconds << 32) | cycle_time; | 1780 | bus_time = ((u64)atomic_read(&ohci->bus_seconds) << 32) | cycle_time; |
1774 | 1781 | ||
1775 | return bus_time; | 1782 | return bus_time; |
1776 | } | 1783 | } |
diff --git a/drivers/firewire/fw-ohci.h b/drivers/firewire/ohci.h index a2fbb6240ca..ba492d85c51 100644 --- a/drivers/firewire/fw-ohci.h +++ b/drivers/firewire/ohci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | #ifndef __fw_ohci_h | 1 | #ifndef _FIREWIRE_OHCI_H |
2 | #define __fw_ohci_h | 2 | #define _FIREWIRE_OHCI_H |
3 | 3 | ||
4 | /* OHCI register map */ | 4 | /* OHCI register map */ |
5 | 5 | ||
@@ -154,4 +154,4 @@ | |||
154 | 154 | ||
155 | #define OHCI1394_phy_tcode 0xe | 155 | #define OHCI1394_phy_tcode 0xe |
156 | 156 | ||
157 | #endif /* __fw_ohci_h */ | 157 | #endif /* _FIREWIRE_OHCI_H */ |
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/sbp2.c index a70e66e78c7..24c45635376 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -30,18 +30,28 @@ | |||
30 | 30 | ||
31 | #include <linux/blkdev.h> | 31 | #include <linux/blkdev.h> |
32 | #include <linux/bug.h> | 32 | #include <linux/bug.h> |
33 | #include <linux/completion.h> | ||
33 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
34 | #include <linux/device.h> | 35 | #include <linux/device.h> |
35 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
37 | #include <linux/firewire.h> | ||
38 | #include <linux/firewire-constants.h> | ||
39 | #include <linux/init.h> | ||
40 | #include <linux/jiffies.h> | ||
36 | #include <linux/kernel.h> | 41 | #include <linux/kernel.h> |
42 | #include <linux/kref.h> | ||
43 | #include <linux/list.h> | ||
37 | #include <linux/mod_devicetable.h> | 44 | #include <linux/mod_devicetable.h> |
38 | #include <linux/module.h> | 45 | #include <linux/module.h> |
39 | #include <linux/moduleparam.h> | 46 | #include <linux/moduleparam.h> |
40 | #include <linux/scatterlist.h> | 47 | #include <linux/scatterlist.h> |
48 | #include <linux/slab.h> | ||
49 | #include <linux/spinlock.h> | ||
41 | #include <linux/string.h> | 50 | #include <linux/string.h> |
42 | #include <linux/stringify.h> | 51 | #include <linux/stringify.h> |
43 | #include <linux/timer.h> | ||
44 | #include <linux/workqueue.h> | 52 | #include <linux/workqueue.h> |
53 | |||
54 | #include <asm/byteorder.h> | ||
45 | #include <asm/system.h> | 55 | #include <asm/system.h> |
46 | 56 | ||
47 | #include <scsi/scsi.h> | 57 | #include <scsi/scsi.h> |
@@ -49,10 +59,6 @@ | |||
49 | #include <scsi/scsi_device.h> | 59 | #include <scsi/scsi_device.h> |
50 | #include <scsi/scsi_host.h> | 60 | #include <scsi/scsi_host.h> |
51 | 61 | ||
52 | #include "fw-device.h" | ||
53 | #include "fw-topology.h" | ||
54 | #include "fw-transaction.h" | ||
55 | |||
56 | /* | 62 | /* |
57 | * So far only bridges from Oxford Semiconductor are known to support | 63 | * So far only bridges from Oxford Semiconductor are known to support |
58 | * concurrent logins. Depending on firmware, four or two concurrent logins | 64 | * concurrent logins. Depending on firmware, four or two concurrent logins |
@@ -174,6 +180,11 @@ struct sbp2_target { | |||
174 | int blocked; /* ditto */ | 180 | int blocked; /* ditto */ |
175 | }; | 181 | }; |
176 | 182 | ||
183 | static struct fw_device *target_device(struct sbp2_target *tgt) | ||
184 | { | ||
185 | return fw_parent_device(tgt->unit); | ||
186 | } | ||
187 | |||
177 | /* Impossible login_id, to detect logout attempt before successful login */ | 188 | /* Impossible login_id, to detect logout attempt before successful login */ |
178 | #define INVALID_LOGIN_ID 0x10000 | 189 | #define INVALID_LOGIN_ID 0x10000 |
179 | 190 | ||
@@ -482,7 +493,7 @@ static void complete_transaction(struct fw_card *card, int rcode, | |||
482 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | 493 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, |
483 | int node_id, int generation, u64 offset) | 494 | int node_id, int generation, u64 offset) |
484 | { | 495 | { |
485 | struct fw_device *device = fw_device(lu->tgt->unit->device.parent); | 496 | struct fw_device *device = target_device(lu->tgt); |
486 | unsigned long flags; | 497 | unsigned long flags; |
487 | 498 | ||
488 | orb->pointer.high = 0; | 499 | orb->pointer.high = 0; |
@@ -504,7 +515,7 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | |||
504 | 515 | ||
505 | static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu) | 516 | static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu) |
506 | { | 517 | { |
507 | struct fw_device *device = fw_device(lu->tgt->unit->device.parent); | 518 | struct fw_device *device = target_device(lu->tgt); |
508 | struct sbp2_orb *orb, *next; | 519 | struct sbp2_orb *orb, *next; |
509 | struct list_head list; | 520 | struct list_head list; |
510 | unsigned long flags; | 521 | unsigned long flags; |
@@ -542,7 +553,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, | |||
542 | int generation, int function, | 553 | int generation, int function, |
543 | int lun_or_login_id, void *response) | 554 | int lun_or_login_id, void *response) |
544 | { | 555 | { |
545 | struct fw_device *device = fw_device(lu->tgt->unit->device.parent); | 556 | struct fw_device *device = target_device(lu->tgt); |
546 | struct sbp2_management_orb *orb; | 557 | struct sbp2_management_orb *orb; |
547 | unsigned int timeout; | 558 | unsigned int timeout; |
548 | int retval = -ENOMEM; | 559 | int retval = -ENOMEM; |
@@ -638,7 +649,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, | |||
638 | 649 | ||
639 | static void sbp2_agent_reset(struct sbp2_logical_unit *lu) | 650 | static void sbp2_agent_reset(struct sbp2_logical_unit *lu) |
640 | { | 651 | { |
641 | struct fw_device *device = fw_device(lu->tgt->unit->device.parent); | 652 | struct fw_device *device = target_device(lu->tgt); |
642 | __be32 d = 0; | 653 | __be32 d = 0; |
643 | 654 | ||
644 | fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, | 655 | fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, |
@@ -655,7 +666,7 @@ static void complete_agent_reset_write_no_wait(struct fw_card *card, | |||
655 | 666 | ||
656 | static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) | 667 | static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) |
657 | { | 668 | { |
658 | struct fw_device *device = fw_device(lu->tgt->unit->device.parent); | 669 | struct fw_device *device = target_device(lu->tgt); |
659 | struct fw_transaction *t; | 670 | struct fw_transaction *t; |
660 | static __be32 d; | 671 | static __be32 d; |
661 | 672 | ||
@@ -694,7 +705,7 @@ static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) | |||
694 | static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) | 705 | static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) |
695 | { | 706 | { |
696 | struct sbp2_target *tgt = lu->tgt; | 707 | struct sbp2_target *tgt = lu->tgt; |
697 | struct fw_card *card = fw_device(tgt->unit->device.parent)->card; | 708 | struct fw_card *card = target_device(tgt)->card; |
698 | struct Scsi_Host *shost = | 709 | struct Scsi_Host *shost = |
699 | container_of((void *)tgt, struct Scsi_Host, hostdata[0]); | 710 | container_of((void *)tgt, struct Scsi_Host, hostdata[0]); |
700 | unsigned long flags; | 711 | unsigned long flags; |
@@ -718,7 +729,7 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) | |||
718 | static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) | 729 | static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) |
719 | { | 730 | { |
720 | struct sbp2_target *tgt = lu->tgt; | 731 | struct sbp2_target *tgt = lu->tgt; |
721 | struct fw_card *card = fw_device(tgt->unit->device.parent)->card; | 732 | struct fw_card *card = target_device(tgt)->card; |
722 | struct Scsi_Host *shost = | 733 | struct Scsi_Host *shost = |
723 | container_of((void *)tgt, struct Scsi_Host, hostdata[0]); | 734 | container_of((void *)tgt, struct Scsi_Host, hostdata[0]); |
724 | unsigned long flags; | 735 | unsigned long flags; |
@@ -743,7 +754,7 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) | |||
743 | */ | 754 | */ |
744 | static void sbp2_unblock(struct sbp2_target *tgt) | 755 | static void sbp2_unblock(struct sbp2_target *tgt) |
745 | { | 756 | { |
746 | struct fw_card *card = fw_device(tgt->unit->device.parent)->card; | 757 | struct fw_card *card = target_device(tgt)->card; |
747 | struct Scsi_Host *shost = | 758 | struct Scsi_Host *shost = |
748 | container_of((void *)tgt, struct Scsi_Host, hostdata[0]); | 759 | container_of((void *)tgt, struct Scsi_Host, hostdata[0]); |
749 | unsigned long flags; | 760 | unsigned long flags; |
@@ -773,7 +784,7 @@ static void sbp2_release_target(struct kref *kref) | |||
773 | struct Scsi_Host *shost = | 784 | struct Scsi_Host *shost = |
774 | container_of((void *)tgt, struct Scsi_Host, hostdata[0]); | 785 | container_of((void *)tgt, struct Scsi_Host, hostdata[0]); |
775 | struct scsi_device *sdev; | 786 | struct scsi_device *sdev; |
776 | struct fw_device *device = fw_device(tgt->unit->device.parent); | 787 | struct fw_device *device = target_device(tgt); |
777 | 788 | ||
778 | /* prevent deadlocks */ | 789 | /* prevent deadlocks */ |
779 | sbp2_unblock(tgt); | 790 | sbp2_unblock(tgt); |
@@ -846,7 +857,7 @@ static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) | |||
846 | */ | 857 | */ |
847 | static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu) | 858 | static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu) |
848 | { | 859 | { |
849 | struct fw_device *device = fw_device(lu->tgt->unit->device.parent); | 860 | struct fw_device *device = target_device(lu->tgt); |
850 | __be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT); | 861 | __be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT); |
851 | 862 | ||
852 | fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, | 863 | fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, |
@@ -862,7 +873,7 @@ static void sbp2_login(struct work_struct *work) | |||
862 | struct sbp2_logical_unit *lu = | 873 | struct sbp2_logical_unit *lu = |
863 | container_of(work, struct sbp2_logical_unit, work.work); | 874 | container_of(work, struct sbp2_logical_unit, work.work); |
864 | struct sbp2_target *tgt = lu->tgt; | 875 | struct sbp2_target *tgt = lu->tgt; |
865 | struct fw_device *device = fw_device(tgt->unit->device.parent); | 876 | struct fw_device *device = target_device(tgt); |
866 | struct Scsi_Host *shost; | 877 | struct Scsi_Host *shost; |
867 | struct scsi_device *sdev; | 878 | struct scsi_device *sdev; |
868 | struct sbp2_login_response response; | 879 | struct sbp2_login_response response; |
@@ -1110,7 +1121,7 @@ static struct scsi_host_template scsi_driver_template; | |||
1110 | static int sbp2_probe(struct device *dev) | 1121 | static int sbp2_probe(struct device *dev) |
1111 | { | 1122 | { |
1112 | struct fw_unit *unit = fw_unit(dev); | 1123 | struct fw_unit *unit = fw_unit(dev); |
1113 | struct fw_device *device = fw_device(unit->device.parent); | 1124 | struct fw_device *device = fw_parent_device(unit); |
1114 | struct sbp2_target *tgt; | 1125 | struct sbp2_target *tgt; |
1115 | struct sbp2_logical_unit *lu; | 1126 | struct sbp2_logical_unit *lu; |
1116 | struct Scsi_Host *shost; | 1127 | struct Scsi_Host *shost; |
@@ -1191,7 +1202,7 @@ static void sbp2_reconnect(struct work_struct *work) | |||
1191 | struct sbp2_logical_unit *lu = | 1202 | struct sbp2_logical_unit *lu = |
1192 | container_of(work, struct sbp2_logical_unit, work.work); | 1203 | container_of(work, struct sbp2_logical_unit, work.work); |
1193 | struct sbp2_target *tgt = lu->tgt; | 1204 | struct sbp2_target *tgt = lu->tgt; |
1194 | struct fw_device *device = fw_device(tgt->unit->device.parent); | 1205 | struct fw_device *device = target_device(tgt); |
1195 | int generation, node_id, local_node_id; | 1206 | int generation, node_id, local_node_id; |
1196 | 1207 | ||
1197 | if (fw_device_is_shutdown(device)) | 1208 | if (fw_device_is_shutdown(device)) |
@@ -1243,7 +1254,7 @@ static void sbp2_update(struct fw_unit *unit) | |||
1243 | struct sbp2_target *tgt = dev_get_drvdata(&unit->device); | 1254 | struct sbp2_target *tgt = dev_get_drvdata(&unit->device); |
1244 | struct sbp2_logical_unit *lu; | 1255 | struct sbp2_logical_unit *lu; |
1245 | 1256 | ||
1246 | fw_device_enable_phys_dma(fw_device(unit->device.parent)); | 1257 | fw_device_enable_phys_dma(fw_parent_device(unit)); |
1247 | 1258 | ||
1248 | /* | 1259 | /* |
1249 | * Fw-core serializes sbp2_update() against sbp2_remove(). | 1260 | * Fw-core serializes sbp2_update() against sbp2_remove(). |
@@ -1259,9 +1270,10 @@ static void sbp2_update(struct fw_unit *unit) | |||
1259 | #define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e | 1270 | #define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e |
1260 | #define SBP2_SW_VERSION_ENTRY 0x00010483 | 1271 | #define SBP2_SW_VERSION_ENTRY 0x00010483 |
1261 | 1272 | ||
1262 | static const struct fw_device_id sbp2_id_table[] = { | 1273 | static const struct ieee1394_device_id sbp2_id_table[] = { |
1263 | { | 1274 | { |
1264 | .match_flags = FW_MATCH_SPECIFIER_ID | FW_MATCH_VERSION, | 1275 | .match_flags = IEEE1394_MATCH_SPECIFIER_ID | |
1276 | IEEE1394_MATCH_VERSION, | ||
1265 | .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY, | 1277 | .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY, |
1266 | .version = SBP2_SW_VERSION_ENTRY, | 1278 | .version = SBP2_SW_VERSION_ENTRY, |
1267 | }, | 1279 | }, |
@@ -1335,7 +1347,7 @@ static void complete_command_orb(struct sbp2_orb *base_orb, | |||
1335 | { | 1347 | { |
1336 | struct sbp2_command_orb *orb = | 1348 | struct sbp2_command_orb *orb = |
1337 | container_of(base_orb, struct sbp2_command_orb, base); | 1349 | container_of(base_orb, struct sbp2_command_orb, base); |
1338 | struct fw_device *device = fw_device(orb->lu->tgt->unit->device.parent); | 1350 | struct fw_device *device = target_device(orb->lu->tgt); |
1339 | int result; | 1351 | int result; |
1340 | 1352 | ||
1341 | if (status != NULL) { | 1353 | if (status != NULL) { |
@@ -1442,7 +1454,7 @@ static int sbp2_map_scatterlist(struct sbp2_command_orb *orb, | |||
1442 | static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) | 1454 | static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) |
1443 | { | 1455 | { |
1444 | struct sbp2_logical_unit *lu = cmd->device->hostdata; | 1456 | struct sbp2_logical_unit *lu = cmd->device->hostdata; |
1445 | struct fw_device *device = fw_device(lu->tgt->unit->device.parent); | 1457 | struct fw_device *device = target_device(lu->tgt); |
1446 | struct sbp2_command_orb *orb; | 1458 | struct sbp2_command_orb *orb; |
1447 | int generation, retval = SCSI_MLQUEUE_HOST_BUSY; | 1459 | int generation, retval = SCSI_MLQUEUE_HOST_BUSY; |
1448 | 1460 | ||
diff --git a/include/linux/firewire.h b/include/linux/firewire.h new file mode 100644 index 00000000000..e584b7215e8 --- /dev/null +++ b/include/linux/firewire.h | |||
@@ -0,0 +1,358 @@ | |||
1 | #ifndef _LINUX_FIREWIRE_H | ||
2 | #define _LINUX_FIREWIRE_H | ||
3 | |||
4 | #include <linux/completion.h> | ||
5 | #include <linux/device.h> | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/kref.h> | ||
8 | #include <linux/list.h> | ||
9 | #include <linux/mutex.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/sysfs.h> | ||
12 | #include <linux/timer.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/workqueue.h> | ||
15 | |||
16 | #include <asm/atomic.h> | ||
17 | #include <asm/byteorder.h> | ||
18 | |||
19 | #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) | ||
20 | #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) | ||
21 | |||
22 | static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size) | ||
23 | { | ||
24 | u32 *dst = _dst; | ||
25 | __be32 *src = _src; | ||
26 | int i; | ||
27 | |||
28 | for (i = 0; i < size / 4; i++) | ||
29 | dst[i] = be32_to_cpu(src[i]); | ||
30 | } | ||
31 | |||
32 | static inline void fw_memcpy_to_be32(void *_dst, void *_src, size_t size) | ||
33 | { | ||
34 | fw_memcpy_from_be32(_dst, _src, size); | ||
35 | } | ||
36 | #define CSR_REGISTER_BASE 0xfffff0000000ULL | ||
37 | |||
38 | /* register offsets are relative to CSR_REGISTER_BASE */ | ||
39 | #define CSR_STATE_CLEAR 0x0 | ||
40 | #define CSR_STATE_SET 0x4 | ||
41 | #define CSR_NODE_IDS 0x8 | ||
42 | #define CSR_RESET_START 0xc | ||
43 | #define CSR_SPLIT_TIMEOUT_HI 0x18 | ||
44 | #define CSR_SPLIT_TIMEOUT_LO 0x1c | ||
45 | #define CSR_CYCLE_TIME 0x200 | ||
46 | #define CSR_BUS_TIME 0x204 | ||
47 | #define CSR_BUSY_TIMEOUT 0x210 | ||
48 | #define CSR_BUS_MANAGER_ID 0x21c | ||
49 | #define CSR_BANDWIDTH_AVAILABLE 0x220 | ||
50 | #define CSR_CHANNELS_AVAILABLE 0x224 | ||
51 | #define CSR_CHANNELS_AVAILABLE_HI 0x224 | ||
52 | #define CSR_CHANNELS_AVAILABLE_LO 0x228 | ||
53 | #define CSR_BROADCAST_CHANNEL 0x234 | ||
54 | #define CSR_CONFIG_ROM 0x400 | ||
55 | #define CSR_CONFIG_ROM_END 0x800 | ||
56 | #define CSR_FCP_COMMAND 0xB00 | ||
57 | #define CSR_FCP_RESPONSE 0xD00 | ||
58 | #define CSR_FCP_END 0xF00 | ||
59 | #define CSR_TOPOLOGY_MAP 0x1000 | ||
60 | #define CSR_TOPOLOGY_MAP_END 0x1400 | ||
61 | #define CSR_SPEED_MAP 0x2000 | ||
62 | #define CSR_SPEED_MAP_END 0x3000 | ||
63 | |||
64 | #define CSR_OFFSET 0x40 | ||
65 | #define CSR_LEAF 0x80 | ||
66 | #define CSR_DIRECTORY 0xc0 | ||
67 | |||
68 | #define CSR_DESCRIPTOR 0x01 | ||
69 | #define CSR_VENDOR 0x03 | ||
70 | #define CSR_HARDWARE_VERSION 0x04 | ||
71 | #define CSR_NODE_CAPABILITIES 0x0c | ||
72 | #define CSR_UNIT 0x11 | ||
73 | #define CSR_SPECIFIER_ID 0x12 | ||
74 | #define CSR_VERSION 0x13 | ||
75 | #define CSR_DEPENDENT_INFO 0x14 | ||
76 | #define CSR_MODEL 0x17 | ||
77 | #define CSR_INSTANCE 0x18 | ||
78 | #define CSR_DIRECTORY_ID 0x20 | ||
79 | |||
80 | struct fw_csr_iterator { | ||
81 | u32 *p; | ||
82 | u32 *end; | ||
83 | }; | ||
84 | |||
85 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 *p); | ||
86 | int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value); | ||
87 | |||
88 | extern struct bus_type fw_bus_type; | ||
89 | |||
90 | struct fw_card_driver; | ||
91 | struct fw_node; | ||
92 | |||
93 | struct fw_card { | ||
94 | const struct fw_card_driver *driver; | ||
95 | struct device *device; | ||
96 | struct kref kref; | ||
97 | struct completion done; | ||
98 | |||
99 | int node_id; | ||
100 | int generation; | ||
101 | int current_tlabel; | ||
102 | u64 tlabel_mask; | ||
103 | struct list_head transaction_list; | ||
104 | struct timer_list flush_timer; | ||
105 | unsigned long reset_jiffies; | ||
106 | |||
107 | unsigned long long guid; | ||
108 | unsigned max_receive; | ||
109 | int link_speed; | ||
110 | int config_rom_generation; | ||
111 | |||
112 | spinlock_t lock; /* Take this lock when handling the lists in | ||
113 | * this struct. */ | ||
114 | struct fw_node *local_node; | ||
115 | struct fw_node *root_node; | ||
116 | struct fw_node *irm_node; | ||
117 | u8 color; /* must be u8 to match the definition in struct fw_node */ | ||
118 | int gap_count; | ||
119 | bool beta_repeaters_present; | ||
120 | |||
121 | int index; | ||
122 | |||
123 | struct list_head link; | ||
124 | |||
125 | /* Work struct for BM duties. */ | ||
126 | struct delayed_work work; | ||
127 | int bm_retries; | ||
128 | int bm_generation; | ||
129 | |||
130 | bool broadcast_channel_allocated; | ||
131 | u32 broadcast_channel; | ||
132 | u32 topology_map[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4]; | ||
133 | }; | ||
134 | |||
135 | static inline struct fw_card *fw_card_get(struct fw_card *card) | ||
136 | { | ||
137 | kref_get(&card->kref); | ||
138 | |||
139 | return card; | ||
140 | } | ||
141 | |||
142 | void fw_card_release(struct kref *kref); | ||
143 | |||
144 | static inline void fw_card_put(struct fw_card *card) | ||
145 | { | ||
146 | kref_put(&card->kref, fw_card_release); | ||
147 | } | ||
148 | |||
149 | struct fw_attribute_group { | ||
150 | struct attribute_group *groups[2]; | ||
151 | struct attribute_group group; | ||
152 | struct attribute *attrs[12]; | ||
153 | }; | ||
154 | |||
155 | enum fw_device_state { | ||
156 | FW_DEVICE_INITIALIZING, | ||
157 | FW_DEVICE_RUNNING, | ||
158 | FW_DEVICE_GONE, | ||
159 | FW_DEVICE_SHUTDOWN, | ||
160 | }; | ||
161 | |||
162 | /* | ||
163 | * Note, fw_device.generation always has to be read before fw_device.node_id. | ||
164 | * Use SMP memory barriers to ensure this. Otherwise requests will be sent | ||
165 | * to an outdated node_id if the generation was updated in the meantime due | ||
166 | * to a bus reset. | ||
167 | * | ||
168 | * Likewise, fw-core will take care to update .node_id before .generation so | ||
169 | * that whenever fw_device.generation is current WRT the actual bus generation, | ||
170 | * fw_device.node_id is guaranteed to be current too. | ||
171 | * | ||
172 | * The same applies to fw_device.card->node_id vs. fw_device.generation. | ||
173 | * | ||
174 | * fw_device.config_rom and fw_device.config_rom_length may be accessed during | ||
175 | * the lifetime of any fw_unit belonging to the fw_device, before device_del() | ||
176 | * was called on the last fw_unit. Alternatively, they may be accessed while | ||
177 | * holding fw_device_rwsem. | ||
178 | */ | ||
179 | struct fw_device { | ||
180 | atomic_t state; | ||
181 | struct fw_node *node; | ||
182 | int node_id; | ||
183 | int generation; | ||
184 | unsigned max_speed; | ||
185 | struct fw_card *card; | ||
186 | struct device device; | ||
187 | |||
188 | struct mutex client_list_mutex; | ||
189 | struct list_head client_list; | ||
190 | |||
191 | u32 *config_rom; | ||
192 | size_t config_rom_length; | ||
193 | int config_rom_retries; | ||
194 | unsigned is_local:1; | ||
195 | unsigned max_rec:4; | ||
196 | unsigned cmc:1; | ||
197 | unsigned irmc:1; | ||
198 | unsigned bc_implemented:2; | ||
199 | |||
200 | struct delayed_work work; | ||
201 | struct fw_attribute_group attribute_group; | ||
202 | }; | ||
203 | |||
204 | static inline struct fw_device *fw_device(struct device *dev) | ||
205 | { | ||
206 | return container_of(dev, struct fw_device, device); | ||
207 | } | ||
208 | |||
209 | static inline int fw_device_is_shutdown(struct fw_device *device) | ||
210 | { | ||
211 | return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; | ||
212 | } | ||
213 | |||
214 | static inline struct fw_device *fw_device_get(struct fw_device *device) | ||
215 | { | ||
216 | get_device(&device->device); | ||
217 | |||
218 | return device; | ||
219 | } | ||
220 | |||
221 | static inline void fw_device_put(struct fw_device *device) | ||
222 | { | ||
223 | put_device(&device->device); | ||
224 | } | ||
225 | |||
226 | int fw_device_enable_phys_dma(struct fw_device *device); | ||
227 | |||
228 | /* | ||
229 | * fw_unit.directory must not be accessed after device_del(&fw_unit.device). | ||
230 | */ | ||
231 | struct fw_unit { | ||
232 | struct device device; | ||
233 | u32 *directory; | ||
234 | struct fw_attribute_group attribute_group; | ||
235 | }; | ||
236 | |||
237 | static inline struct fw_unit *fw_unit(struct device *dev) | ||
238 | { | ||
239 | return container_of(dev, struct fw_unit, device); | ||
240 | } | ||
241 | |||
242 | static inline struct fw_unit *fw_unit_get(struct fw_unit *unit) | ||
243 | { | ||
244 | get_device(&unit->device); | ||
245 | |||
246 | return unit; | ||
247 | } | ||
248 | |||
249 | static inline void fw_unit_put(struct fw_unit *unit) | ||
250 | { | ||
251 | put_device(&unit->device); | ||
252 | } | ||
253 | |||
254 | static inline struct fw_device *fw_parent_device(struct fw_unit *unit) | ||
255 | { | ||
256 | return fw_device(unit->device.parent); | ||
257 | } | ||
258 | |||
259 | struct ieee1394_device_id; | ||
260 | |||
261 | struct fw_driver { | ||
262 | struct device_driver driver; | ||
263 | /* Called when the parent device sits through a bus reset. */ | ||
264 | void (*update)(struct fw_unit *unit); | ||
265 | const struct ieee1394_device_id *id_table; | ||
266 | }; | ||
267 | |||
268 | struct fw_packet; | ||
269 | struct fw_request; | ||
270 | |||
271 | typedef void (*fw_packet_callback_t)(struct fw_packet *packet, | ||
272 | struct fw_card *card, int status); | ||
273 | typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode, | ||
274 | void *data, size_t length, | ||
275 | void *callback_data); | ||
276 | /* | ||
277 | * Important note: The callback must guarantee that either fw_send_response() | ||
278 | * or kfree() is called on the @request. | ||
279 | */ | ||
280 | typedef void (*fw_address_callback_t)(struct fw_card *card, | ||
281 | struct fw_request *request, | ||
282 | int tcode, int destination, int source, | ||
283 | int generation, int speed, | ||
284 | unsigned long long offset, | ||
285 | void *data, size_t length, | ||
286 | void *callback_data); | ||
287 | |||
288 | struct fw_packet { | ||
289 | int speed; | ||
290 | int generation; | ||
291 | u32 header[4]; | ||
292 | size_t header_length; | ||
293 | void *payload; | ||
294 | size_t payload_length; | ||
295 | dma_addr_t payload_bus; | ||
296 | u32 timestamp; | ||
297 | |||
298 | /* | ||
299 | * This callback is called when the packet transmission has | ||
300 | * completed; for successful transmission, the status code is | ||
301 | * the ack received from the destination, otherwise it's a | ||
302 | * negative errno: ENOMEM, ESTALE, ETIMEDOUT, ENODEV, EIO. | ||
303 | * The callback can be called from tasklet context and thus | ||
304 | * must never block. | ||
305 | */ | ||
306 | fw_packet_callback_t callback; | ||
307 | int ack; | ||
308 | struct list_head link; | ||
309 | void *driver_data; | ||
310 | }; | ||
311 | |||
312 | struct fw_transaction { | ||
313 | int node_id; /* The generation is implied; it is always the current. */ | ||
314 | int tlabel; | ||
315 | int timestamp; | ||
316 | struct list_head link; | ||
317 | |||
318 | struct fw_packet packet; | ||
319 | |||
320 | /* | ||
321 | * The data passed to the callback is valid only during the | ||
322 | * callback. | ||
323 | */ | ||
324 | fw_transaction_callback_t callback; | ||
325 | void *callback_data; | ||
326 | }; | ||
327 | |||
328 | struct fw_address_handler { | ||
329 | u64 offset; | ||
330 | size_t length; | ||
331 | fw_address_callback_t address_callback; | ||
332 | void *callback_data; | ||
333 | struct list_head link; | ||
334 | }; | ||
335 | |||
336 | struct fw_address_region { | ||
337 | u64 start; | ||
338 | u64 end; | ||
339 | }; | ||
340 | |||
341 | extern const struct fw_address_region fw_high_memory_region; | ||
342 | |||
343 | int fw_core_add_address_handler(struct fw_address_handler *handler, | ||
344 | const struct fw_address_region *region); | ||
345 | void fw_core_remove_address_handler(struct fw_address_handler *handler); | ||
346 | void fw_send_response(struct fw_card *card, | ||
347 | struct fw_request *request, int rcode); | ||
348 | void fw_send_request(struct fw_card *card, struct fw_transaction *t, | ||
349 | int tcode, int destination_id, int generation, int speed, | ||
350 | unsigned long long offset, void *payload, size_t length, | ||
351 | fw_transaction_callback_t callback, void *callback_data); | ||
352 | int fw_cancel_transaction(struct fw_card *card, | ||
353 | struct fw_transaction *transaction); | ||
354 | int fw_run_transaction(struct fw_card *card, int tcode, int destination_id, | ||
355 | int generation, int speed, unsigned long long offset, | ||
356 | void *payload, size_t length); | ||
357 | |||
358 | #endif /* _LINUX_FIREWIRE_H */ | ||