diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 17:29:46 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 17:29:46 -0400 |
| commit | f83b1e616f2f68b56b09b2f5116591981fee0c1c (patch) | |
| tree | d8c423502853b46ec82c58ee31b695552579f7da | |
| parent | 2f38d70fb4e97e7d00e12eaac45790cf6ebd7b22 (diff) | |
| parent | 1e626fdcef61460dc75fe7377f38bb019722b848 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
firewire: core: use more outbound tlabels
firewire: core: don't update Broadcast_Channel if RFC 2734 conditions aren't met
firewire: core: prepare for non-core children of card devices
firewire: core: include linux/uaccess.h instead of asm/uaccess.h
firewire: add parent-of-unit accessor
firewire: rename source files
firewire: reorganize header files
firewire: clean up includes
firewire: ohci: access bus_seconds atomically
firewire: also use vendor ID in root directory for driver matches
firewire: share device ID table type with ieee1394
firewire: core: add sysfs attribute for easier udev rules
firewire: core: check for missing struct update at build time, not run time
firewire: core: improve check for local node
| -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 a7c31e9039c1..bc3b9bf822bf 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 8b8c8c22f0fc..4c1be64fdddd 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 7eb6594cc3e5..d1d30c615b0f 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 a47e2129d83d..97e656af2d22 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 2baf1007253e..28076c892d7e 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 d0deecc4de93..fddf2b358936 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 283dac6d327d..479b22f5a1eb 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 000000000000..0a25a7b38a80 --- /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 97588937c018..000000000000 --- 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 3c497bb4fae4..000000000000 --- 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 dfa799068f89..000000000000 --- 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 1180d0be0bb4..ecddd11b797a 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 a2fbb6240ca7..ba492d85c516 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 a70e66e78c7b..24c45635376a 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 000000000000..e584b7215e8b --- /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 */ | ||
