diff options
| -rw-r--r-- | drivers/firewire/core-cdev.c | 16 | ||||
| -rw-r--r-- | drivers/firewire/core-device.c | 127 | ||||
| -rw-r--r-- | drivers/firewire/core-transaction.c | 17 | ||||
| -rw-r--r-- | drivers/firewire/core.h | 2 | ||||
| -rw-r--r-- | drivers/firewire/ohci.c | 87 | ||||
| -rw-r--r-- | drivers/firewire/sbp2.c | 5 | ||||
| -rw-r--r-- | drivers/media/dvb/firewire/firedtv-fw.c | 39 | ||||
| -rw-r--r-- | include/linux/firewire.h | 11 |
8 files changed, 180 insertions, 124 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 4eeaed57e219..3c1ac0933d24 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/firewire.h> | 25 | #include <linux/firewire.h> |
| 26 | #include <linux/firewire-cdev.h> | 26 | #include <linux/firewire-cdev.h> |
| 27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
| 28 | #include <linux/irqflags.h> | ||
| 28 | #include <linux/jiffies.h> | 29 | #include <linux/jiffies.h> |
| 29 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
| 30 | #include <linux/kref.h> | 31 | #include <linux/kref.h> |
| @@ -32,7 +33,6 @@ | |||
| 32 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
| 34 | #include <linux/poll.h> | 35 | #include <linux/poll.h> |
| 35 | #include <linux/preempt.h> | ||
| 36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
| 37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
| 38 | #include <linux/string.h> | 38 | #include <linux/string.h> |
| @@ -1035,21 +1035,19 @@ static int ioctl_get_cycle_timer(struct client *client, void *buffer) | |||
| 1035 | { | 1035 | { |
| 1036 | struct fw_cdev_get_cycle_timer *request = buffer; | 1036 | struct fw_cdev_get_cycle_timer *request = buffer; |
| 1037 | struct fw_card *card = client->device->card; | 1037 | struct fw_card *card = client->device->card; |
| 1038 | unsigned long long bus_time; | ||
| 1039 | struct timeval tv; | 1038 | struct timeval tv; |
| 1040 | unsigned long flags; | 1039 | u32 cycle_time; |
| 1041 | 1040 | ||
| 1042 | preempt_disable(); | 1041 | local_irq_disable(); |
| 1043 | local_irq_save(flags); | ||
| 1044 | 1042 | ||
| 1045 | bus_time = card->driver->get_bus_time(card); | 1043 | cycle_time = card->driver->get_cycle_time(card); |
| 1046 | do_gettimeofday(&tv); | 1044 | do_gettimeofday(&tv); |
| 1047 | 1045 | ||
| 1048 | local_irq_restore(flags); | 1046 | local_irq_enable(); |
| 1049 | preempt_enable(); | ||
| 1050 | 1047 | ||
| 1051 | request->local_time = tv.tv_sec * 1000000ULL + tv.tv_usec; | 1048 | request->local_time = tv.tv_sec * 1000000ULL + tv.tv_usec; |
| 1052 | request->cycle_timer = bus_time & 0xffffffff; | 1049 | request->cycle_timer = cycle_time; |
| 1050 | |||
| 1053 | return 0; | 1051 | return 0; |
| 1054 | } | 1052 | } |
| 1055 | 1053 | ||
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 9d0dfcbe2c1c..eecd52dc8e98 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c | |||
| @@ -43,7 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | #include "core.h" | 44 | #include "core.h" |
| 45 | 45 | ||
| 46 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 * p) | 46 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, const u32 *p) |
| 47 | { | 47 | { |
| 48 | ci->p = p + 1; | 48 | ci->p = p + 1; |
| 49 | ci->end = ci->p + (p[0] >> 16); | 49 | ci->end = ci->p + (p[0] >> 16); |
| @@ -59,9 +59,76 @@ int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value) | |||
| 59 | } | 59 | } |
| 60 | EXPORT_SYMBOL(fw_csr_iterator_next); | 60 | EXPORT_SYMBOL(fw_csr_iterator_next); |
| 61 | 61 | ||
| 62 | static const u32 *search_leaf(const u32 *directory, int search_key) | ||
| 63 | { | ||
| 64 | struct fw_csr_iterator ci; | ||
| 65 | int last_key = 0, key, value; | ||
| 66 | |||
| 67 | fw_csr_iterator_init(&ci, directory); | ||
| 68 | while (fw_csr_iterator_next(&ci, &key, &value)) { | ||
| 69 | if (last_key == search_key && | ||
| 70 | key == (CSR_DESCRIPTOR | CSR_LEAF)) | ||
| 71 | return ci.p - 1 + value; | ||
| 72 | |||
| 73 | last_key = key; | ||
| 74 | } | ||
| 75 | |||
| 76 | return NULL; | ||
| 77 | } | ||
| 78 | |||
| 79 | static int textual_leaf_to_string(const u32 *block, char *buf, size_t size) | ||
| 80 | { | ||
| 81 | unsigned int quadlets, i; | ||
| 82 | char c; | ||
| 83 | |||
| 84 | if (!size || !buf) | ||
| 85 | return -EINVAL; | ||
| 86 | |||
| 87 | quadlets = min(block[0] >> 16, 256U); | ||
| 88 | if (quadlets < 2) | ||
| 89 | return -ENODATA; | ||
| 90 | |||
| 91 | if (block[1] != 0 || block[2] != 0) | ||
| 92 | /* unknown language/character set */ | ||
| 93 | return -ENODATA; | ||
| 94 | |||
| 95 | block += 3; | ||
| 96 | quadlets -= 2; | ||
| 97 | for (i = 0; i < quadlets * 4 && i < size - 1; i++) { | ||
| 98 | c = block[i / 4] >> (24 - 8 * (i % 4)); | ||
| 99 | if (c == '\0') | ||
| 100 | break; | ||
| 101 | buf[i] = c; | ||
| 102 | } | ||
| 103 | buf[i] = '\0'; | ||
| 104 | |||
| 105 | return i; | ||
| 106 | } | ||
| 107 | |||
| 108 | /** | ||
| 109 | * fw_csr_string - reads a string from the configuration ROM | ||
| 110 | * @directory: e.g. root directory or unit directory | ||
| 111 | * @key: the key of the preceding directory entry | ||
| 112 | * @buf: where to put the string | ||
| 113 | * @size: size of @buf, in bytes | ||
| 114 | * | ||
| 115 | * The string is taken from a minimal ASCII text descriptor leaf after | ||
| 116 | * the immediate entry with @key. The string is zero-terminated. | ||
| 117 | * Returns strlen(buf) or a negative error code. | ||
| 118 | */ | ||
| 119 | int fw_csr_string(const u32 *directory, int key, char *buf, size_t size) | ||
| 120 | { | ||
| 121 | const u32 *leaf = search_leaf(directory, key); | ||
| 122 | if (!leaf) | ||
| 123 | return -ENOENT; | ||
| 124 | |||
| 125 | return textual_leaf_to_string(leaf, buf, size); | ||
| 126 | } | ||
| 127 | EXPORT_SYMBOL(fw_csr_string); | ||
| 128 | |||
| 62 | static bool is_fw_unit(struct device *dev); | 129 | static bool is_fw_unit(struct device *dev); |
| 63 | 130 | ||
| 64 | static int match_unit_directory(u32 *directory, u32 match_flags, | 131 | static int match_unit_directory(const u32 *directory, u32 match_flags, |
| 65 | const struct ieee1394_device_id *id) | 132 | const struct ieee1394_device_id *id) |
| 66 | { | 133 | { |
| 67 | struct fw_csr_iterator ci; | 134 | struct fw_csr_iterator ci; |
| @@ -195,7 +262,7 @@ static ssize_t show_immediate(struct device *dev, | |||
| 195 | struct config_rom_attribute *attr = | 262 | struct config_rom_attribute *attr = |
| 196 | container_of(dattr, struct config_rom_attribute, attr); | 263 | container_of(dattr, struct config_rom_attribute, attr); |
| 197 | struct fw_csr_iterator ci; | 264 | struct fw_csr_iterator ci; |
| 198 | u32 *dir; | 265 | const u32 *dir; |
| 199 | int key, value, ret = -ENOENT; | 266 | int key, value, ret = -ENOENT; |
| 200 | 267 | ||
| 201 | down_read(&fw_device_rwsem); | 268 | down_read(&fw_device_rwsem); |
| @@ -226,10 +293,10 @@ static ssize_t show_text_leaf(struct device *dev, | |||
| 226 | { | 293 | { |
| 227 | struct config_rom_attribute *attr = | 294 | struct config_rom_attribute *attr = |
| 228 | container_of(dattr, struct config_rom_attribute, attr); | 295 | container_of(dattr, struct config_rom_attribute, attr); |
| 229 | struct fw_csr_iterator ci; | 296 | const u32 *dir; |
| 230 | u32 *dir, *block = NULL, *p, *end; | 297 | size_t bufsize; |
| 231 | int length, key, value, last_key = 0, ret = -ENOENT; | 298 | char dummy_buf[2]; |
| 232 | char *b; | 299 | int ret; |
| 233 | 300 | ||
| 234 | down_read(&fw_device_rwsem); | 301 | down_read(&fw_device_rwsem); |
| 235 | 302 | ||
| @@ -238,40 +305,23 @@ static ssize_t show_text_leaf(struct device *dev, | |||
| 238 | else | 305 | else |
| 239 | dir = fw_device(dev)->config_rom + 5; | 306 | dir = fw_device(dev)->config_rom + 5; |
| 240 | 307 | ||
| 241 | fw_csr_iterator_init(&ci, dir); | 308 | if (buf) { |
| 242 | while (fw_csr_iterator_next(&ci, &key, &value)) { | 309 | bufsize = PAGE_SIZE - 1; |
| 243 | if (attr->key == last_key && | 310 | } else { |
| 244 | key == (CSR_DESCRIPTOR | CSR_LEAF)) | 311 | buf = dummy_buf; |
| 245 | block = ci.p - 1 + value; | 312 | bufsize = 1; |
| 246 | last_key = key; | ||
| 247 | } | 313 | } |
| 248 | 314 | ||
| 249 | if (block == NULL) | 315 | ret = fw_csr_string(dir, attr->key, buf, bufsize); |
| 250 | goto out; | ||
| 251 | |||
| 252 | length = min(block[0] >> 16, 256U); | ||
| 253 | if (length < 3) | ||
| 254 | goto out; | ||
| 255 | 316 | ||
| 256 | if (block[1] != 0 || block[2] != 0) | 317 | if (ret >= 0) { |
| 257 | /* Unknown encoding. */ | 318 | /* Strip trailing whitespace and add newline. */ |
| 258 | goto out; | 319 | while (ret > 0 && isspace(buf[ret - 1])) |
| 259 | 320 | ret--; | |
| 260 | if (buf == NULL) { | 321 | strcpy(buf + ret, "\n"); |
| 261 | ret = length * 4; | 322 | ret++; |
| 262 | goto out; | ||
| 263 | } | 323 | } |
| 264 | 324 | ||
| 265 | b = buf; | ||
| 266 | end = &block[length + 1]; | ||
| 267 | for (p = &block[3]; p < end; p++, b += 4) | ||
| 268 | * (u32 *) b = (__force u32) __cpu_to_be32(*p); | ||
| 269 | |||
| 270 | /* Strip trailing whitespace and add newline. */ | ||
| 271 | while (b--, (isspace(*b) || *b == '\0') && b > buf); | ||
| 272 | strcpy(b + 1, "\n"); | ||
| 273 | ret = b + 2 - buf; | ||
| 274 | out: | ||
| 275 | up_read(&fw_device_rwsem); | 325 | up_read(&fw_device_rwsem); |
| 276 | 326 | ||
| 277 | return ret; | 327 | return ret; |
| @@ -371,7 +421,7 @@ static ssize_t guid_show(struct device *dev, | |||
| 371 | return ret; | 421 | return ret; |
| 372 | } | 422 | } |
| 373 | 423 | ||
| 374 | static int units_sprintf(char *buf, u32 *directory) | 424 | static int units_sprintf(char *buf, const u32 *directory) |
| 375 | { | 425 | { |
| 376 | struct fw_csr_iterator ci; | 426 | struct fw_csr_iterator ci; |
| 377 | int key, value; | 427 | int key, value; |
| @@ -453,7 +503,8 @@ static int read_rom(struct fw_device *device, | |||
| 453 | */ | 503 | */ |
| 454 | static int read_bus_info_block(struct fw_device *device, int generation) | 504 | static int read_bus_info_block(struct fw_device *device, int generation) |
| 455 | { | 505 | { |
| 456 | u32 *rom, *stack, *old_rom, *new_rom; | 506 | const u32 *old_rom, *new_rom; |
| 507 | u32 *rom, *stack; | ||
| 457 | u32 sp, key; | 508 | u32 sp, key; |
| 458 | int i, end, length, ret = -1; | 509 | int i, end, length, ret = -1; |
| 459 | 510 | ||
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 495849eb13cc..673b03f8b4ec 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
| @@ -921,23 +921,15 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
| 921 | void *payload, size_t length, void *callback_data) | 921 | void *payload, size_t length, void *callback_data) |
| 922 | { | 922 | { |
| 923 | int reg = offset & ~CSR_REGISTER_BASE; | 923 | int reg = offset & ~CSR_REGISTER_BASE; |
| 924 | unsigned long long bus_time; | ||
| 925 | __be32 *data = payload; | 924 | __be32 *data = payload; |
| 926 | int rcode = RCODE_COMPLETE; | 925 | int rcode = RCODE_COMPLETE; |
| 927 | 926 | ||
| 928 | switch (reg) { | 927 | switch (reg) { |
| 929 | case CSR_CYCLE_TIME: | 928 | case CSR_CYCLE_TIME: |
| 930 | case CSR_BUS_TIME: | 929 | if (TCODE_IS_READ_REQUEST(tcode) && length == 4) |
| 931 | if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) { | 930 | *data = cpu_to_be32(card->driver->get_cycle_time(card)); |
| 932 | rcode = RCODE_TYPE_ERROR; | ||
| 933 | break; | ||
| 934 | } | ||
| 935 | |||
| 936 | bus_time = card->driver->get_bus_time(card); | ||
| 937 | if (reg == CSR_CYCLE_TIME) | ||
| 938 | *data = cpu_to_be32(bus_time); | ||
| 939 | else | 931 | else |
| 940 | *data = cpu_to_be32(bus_time >> 25); | 932 | rcode = RCODE_TYPE_ERROR; |
| 941 | break; | 933 | break; |
| 942 | 934 | ||
| 943 | case CSR_BROADCAST_CHANNEL: | 935 | case CSR_BROADCAST_CHANNEL: |
| @@ -968,6 +960,9 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
| 968 | case CSR_BUSY_TIMEOUT: | 960 | case CSR_BUSY_TIMEOUT: |
| 969 | /* FIXME: Implement this. */ | 961 | /* FIXME: Implement this. */ |
| 970 | 962 | ||
| 963 | case CSR_BUS_TIME: | ||
| 964 | /* Useless without initialization by the bus manager. */ | ||
| 965 | |||
| 971 | default: | 966 | default: |
| 972 | rcode = RCODE_ADDRESS_ERROR; | 967 | rcode = RCODE_ADDRESS_ERROR; |
| 973 | break; | 968 | break; |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index ed3b1a765c00..fb0321300cce 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
| @@ -70,7 +70,7 @@ struct fw_card_driver { | |||
| 70 | int (*enable_phys_dma)(struct fw_card *card, | 70 | int (*enable_phys_dma)(struct fw_card *card, |
| 71 | int node_id, int generation); | 71 | int node_id, int generation); |
| 72 | 72 | ||
| 73 | u64 (*get_bus_time)(struct fw_card *card); | 73 | u32 (*get_cycle_time)(struct fw_card *card); |
| 74 | 74 | ||
| 75 | struct fw_iso_context * | 75 | struct fw_iso_context * |
| 76 | (*allocate_iso_context)(struct fw_card *card, | 76 | (*allocate_iso_context)(struct fw_card *card, |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 43ebf337b131..0f7c4bb978e7 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
| 39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
| 40 | 40 | ||
| 41 | #include <asm/atomic.h> | ||
| 42 | #include <asm/byteorder.h> | 41 | #include <asm/byteorder.h> |
| 43 | #include <asm/page.h> | 42 | #include <asm/page.h> |
| 44 | #include <asm/system.h> | 43 | #include <asm/system.h> |
| @@ -187,11 +186,11 @@ struct fw_ohci { | |||
| 187 | int node_id; | 186 | int node_id; |
| 188 | int generation; | 187 | int generation; |
| 189 | int request_generation; /* for timestamping incoming requests */ | 188 | int request_generation; /* for timestamping incoming requests */ |
| 190 | atomic_t bus_seconds; | ||
| 191 | 189 | ||
| 192 | bool use_dualbuffer; | 190 | bool use_dualbuffer; |
| 193 | bool old_uninorth; | 191 | bool old_uninorth; |
| 194 | bool bus_reset_packet_quirk; | 192 | bool bus_reset_packet_quirk; |
| 193 | bool iso_cycle_timer_quirk; | ||
| 195 | 194 | ||
| 196 | /* | 195 | /* |
| 197 | * Spinlock for accessing fw_ohci data. Never call out of | 196 | * Spinlock for accessing fw_ohci data. Never call out of |
| @@ -275,7 +274,7 @@ static void log_irqs(u32 evt) | |||
| 275 | !(evt & OHCI1394_busReset)) | 274 | !(evt & OHCI1394_busReset)) |
| 276 | return; | 275 | return; |
| 277 | 276 | ||
| 278 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, | 277 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, |
| 279 | evt & OHCI1394_selfIDComplete ? " selfID" : "", | 278 | evt & OHCI1394_selfIDComplete ? " selfID" : "", |
| 280 | evt & OHCI1394_RQPkt ? " AR_req" : "", | 279 | evt & OHCI1394_RQPkt ? " AR_req" : "", |
| 281 | evt & OHCI1394_RSPkt ? " AR_resp" : "", | 280 | evt & OHCI1394_RSPkt ? " AR_resp" : "", |
| @@ -285,7 +284,6 @@ static void log_irqs(u32 evt) | |||
| 285 | evt & OHCI1394_isochTx ? " IT" : "", | 284 | evt & OHCI1394_isochTx ? " IT" : "", |
| 286 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", | 285 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", |
| 287 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", | 286 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", |
| 288 | evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", | ||
| 289 | evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", | 287 | evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", |
| 290 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", | 288 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", |
| 291 | evt & OHCI1394_busReset ? " busReset" : "", | 289 | evt & OHCI1394_busReset ? " busReset" : "", |
| @@ -293,8 +291,7 @@ static void log_irqs(u32 evt) | |||
| 293 | OHCI1394_RSPkt | OHCI1394_reqTxComplete | | 291 | OHCI1394_RSPkt | OHCI1394_reqTxComplete | |
| 294 | OHCI1394_respTxComplete | OHCI1394_isochRx | | 292 | OHCI1394_respTxComplete | OHCI1394_isochRx | |
| 295 | OHCI1394_isochTx | OHCI1394_postedWriteErr | | 293 | OHCI1394_isochTx | OHCI1394_postedWriteErr | |
| 296 | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | | 294 | OHCI1394_cycleTooLong | OHCI1394_cycleInconsistent | |
| 297 | OHCI1394_cycleInconsistent | | ||
| 298 | OHCI1394_regAccessFail | OHCI1394_busReset) | 295 | OHCI1394_regAccessFail | OHCI1394_busReset) |
| 299 | ? " ?" : ""); | 296 | ? " ?" : ""); |
| 300 | } | 297 | } |
| @@ -1384,7 +1381,7 @@ static void bus_reset_tasklet(unsigned long data) | |||
| 1384 | static irqreturn_t irq_handler(int irq, void *data) | 1381 | static irqreturn_t irq_handler(int irq, void *data) |
| 1385 | { | 1382 | { |
| 1386 | struct fw_ohci *ohci = data; | 1383 | struct fw_ohci *ohci = data; |
| 1387 | u32 event, iso_event, cycle_time; | 1384 | u32 event, iso_event; |
| 1388 | int i; | 1385 | int i; |
| 1389 | 1386 | ||
| 1390 | event = reg_read(ohci, OHCI1394_IntEventClear); | 1387 | event = reg_read(ohci, OHCI1394_IntEventClear); |
| @@ -1454,12 +1451,6 @@ static irqreturn_t irq_handler(int irq, void *data) | |||
| 1454 | fw_notify("isochronous cycle inconsistent\n"); | 1451 | fw_notify("isochronous cycle inconsistent\n"); |
| 1455 | } | 1452 | } |
| 1456 | 1453 | ||
| 1457 | if (event & OHCI1394_cycle64Seconds) { | ||
| 1458 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
| 1459 | if ((cycle_time & 0x80000000) == 0) | ||
| 1460 | atomic_inc(&ohci->bus_seconds); | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | return IRQ_HANDLED; | 1454 | return IRQ_HANDLED; |
| 1464 | } | 1455 | } |
| 1465 | 1456 | ||
| @@ -1553,8 +1544,7 @@ static int ohci_enable(struct fw_card *card, | |||
| 1553 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | | 1544 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | |
| 1554 | OHCI1394_isochRx | OHCI1394_isochTx | | 1545 | OHCI1394_isochRx | OHCI1394_isochTx | |
| 1555 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | | 1546 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | |
| 1556 | OHCI1394_cycleInconsistent | | 1547 | OHCI1394_cycleInconsistent | OHCI1394_regAccessFail | |
| 1557 | OHCI1394_cycle64Seconds | OHCI1394_regAccessFail | | ||
| 1558 | OHCI1394_masterIntEnable); | 1548 | OHCI1394_masterIntEnable); |
| 1559 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) | 1549 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) |
| 1560 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); | 1550 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); |
| @@ -1794,16 +1784,61 @@ static int ohci_enable_phys_dma(struct fw_card *card, | |||
| 1794 | #endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */ | 1784 | #endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */ |
| 1795 | } | 1785 | } |
| 1796 | 1786 | ||
| 1797 | static u64 ohci_get_bus_time(struct fw_card *card) | 1787 | static u32 cycle_timer_ticks(u32 cycle_timer) |
| 1798 | { | 1788 | { |
| 1799 | struct fw_ohci *ohci = fw_ohci(card); | 1789 | u32 ticks; |
| 1800 | u32 cycle_time; | ||
| 1801 | u64 bus_time; | ||
| 1802 | 1790 | ||
| 1803 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1791 | ticks = cycle_timer & 0xfff; |
| 1804 | bus_time = ((u64)atomic_read(&ohci->bus_seconds) << 32) | cycle_time; | 1792 | ticks += 3072 * ((cycle_timer >> 12) & 0x1fff); |
| 1793 | ticks += (3072 * 8000) * (cycle_timer >> 25); | ||
| 1805 | 1794 | ||
| 1806 | return bus_time; | 1795 | return ticks; |
| 1796 | } | ||
| 1797 | |||
| 1798 | /* | ||
| 1799 | * Some controllers exhibit one or more of the following bugs when updating the | ||
| 1800 | * iso cycle timer register: | ||
| 1801 | * - When the lowest six bits are wrapping around to zero, a read that happens | ||
| 1802 | * at the same time will return garbage in the lowest ten bits. | ||
| 1803 | * - When the cycleOffset field wraps around to zero, the cycleCount field is | ||
| 1804 | * not incremented for about 60 ns. | ||
| 1805 | * - Occasionally, the entire register reads zero. | ||
| 1806 | * | ||
| 1807 | * To catch these, we read the register three times and ensure that the | ||
| 1808 | * difference between each two consecutive reads is approximately the same, i.e. | ||
| 1809 | * less than twice the other. Furthermore, any negative difference indicates an | ||
| 1810 | * error. (A PCI read should take at least 20 ticks of the 24.576 MHz timer to | ||
| 1811 | * execute, so we have enough precision to compute the ratio of the differences.) | ||
| 1812 | */ | ||
| 1813 | static u32 ohci_get_cycle_time(struct fw_card *card) | ||
| 1814 | { | ||
| 1815 | struct fw_ohci *ohci = fw_ohci(card); | ||
| 1816 | u32 c0, c1, c2; | ||
| 1817 | u32 t0, t1, t2; | ||
| 1818 | s32 diff01, diff12; | ||
| 1819 | int i; | ||
| 1820 | |||
| 1821 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
| 1822 | |||
| 1823 | if (ohci->iso_cycle_timer_quirk) { | ||
| 1824 | i = 0; | ||
| 1825 | c1 = c2; | ||
| 1826 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
| 1827 | do { | ||
| 1828 | c0 = c1; | ||
| 1829 | c1 = c2; | ||
| 1830 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
| 1831 | t0 = cycle_timer_ticks(c0); | ||
| 1832 | t1 = cycle_timer_ticks(c1); | ||
| 1833 | t2 = cycle_timer_ticks(c2); | ||
| 1834 | diff01 = t1 - t0; | ||
| 1835 | diff12 = t2 - t1; | ||
| 1836 | } while ((diff01 <= 0 || diff12 <= 0 || | ||
| 1837 | diff01 / diff12 >= 2 || diff12 / diff01 >= 2) | ||
| 1838 | && i++ < 20); | ||
| 1839 | } | ||
| 1840 | |||
| 1841 | return c2; | ||
| 1807 | } | 1842 | } |
| 1808 | 1843 | ||
| 1809 | static void copy_iso_headers(struct iso_context *ctx, void *p) | 1844 | static void copy_iso_headers(struct iso_context *ctx, void *p) |
| @@ -2383,7 +2418,7 @@ static const struct fw_card_driver ohci_driver = { | |||
| 2383 | .send_response = ohci_send_response, | 2418 | .send_response = ohci_send_response, |
| 2384 | .cancel_packet = ohci_cancel_packet, | 2419 | .cancel_packet = ohci_cancel_packet, |
| 2385 | .enable_phys_dma = ohci_enable_phys_dma, | 2420 | .enable_phys_dma = ohci_enable_phys_dma, |
| 2386 | .get_bus_time = ohci_get_bus_time, | 2421 | .get_cycle_time = ohci_get_cycle_time, |
| 2387 | 2422 | ||
| 2388 | .allocate_iso_context = ohci_allocate_iso_context, | 2423 | .allocate_iso_context = ohci_allocate_iso_context, |
| 2389 | .free_iso_context = ohci_free_iso_context, | 2424 | .free_iso_context = ohci_free_iso_context, |
| @@ -2503,6 +2538,10 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
| 2503 | #endif | 2538 | #endif |
| 2504 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | 2539 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; |
| 2505 | 2540 | ||
| 2541 | ohci->iso_cycle_timer_quirk = dev->vendor == PCI_VENDOR_ID_AL || | ||
| 2542 | dev->vendor == PCI_VENDOR_ID_NEC || | ||
| 2543 | dev->vendor == PCI_VENDOR_ID_VIA; | ||
| 2544 | |||
| 2506 | ar_context_init(&ohci->ar_request_ctx, ohci, | 2545 | ar_context_init(&ohci->ar_request_ctx, ohci, |
| 2507 | OHCI1394_AsReqRcvContextControlSet); | 2546 | OHCI1394_AsReqRcvContextControlSet); |
| 2508 | 2547 | ||
| @@ -2662,7 +2701,7 @@ static int pci_resume(struct pci_dev *dev) | |||
| 2662 | } | 2701 | } |
| 2663 | #endif | 2702 | #endif |
| 2664 | 2703 | ||
| 2665 | static struct pci_device_id pci_table[] = { | 2704 | static const struct pci_device_id pci_table[] = { |
| 2666 | { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) }, | 2705 | { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) }, |
| 2667 | { } | 2706 | { } |
| 2668 | }; | 2707 | }; |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index d485cdd8cbac..7e33b0b1704c 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
| @@ -1014,7 +1014,8 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) | |||
| 1014 | return 0; | 1014 | return 0; |
| 1015 | } | 1015 | } |
| 1016 | 1016 | ||
| 1017 | static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory) | 1017 | static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, |
| 1018 | const u32 *directory) | ||
| 1018 | { | 1019 | { |
| 1019 | struct fw_csr_iterator ci; | 1020 | struct fw_csr_iterator ci; |
| 1020 | int key, value; | 1021 | int key, value; |
| @@ -1027,7 +1028,7 @@ static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory) | |||
| 1027 | return 0; | 1028 | return 0; |
| 1028 | } | 1029 | } |
| 1029 | 1030 | ||
| 1030 | static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory, | 1031 | static int sbp2_scan_unit_dir(struct sbp2_target *tgt, const u32 *directory, |
| 1031 | u32 *model, u32 *firmware_revision) | 1032 | u32 *model, u32 *firmware_revision) |
| 1032 | { | 1033 | { |
| 1033 | struct fw_csr_iterator ci; | 1034 | struct fw_csr_iterator ci; |
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index 6223bf01efe9..4253b7ab0097 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c | |||
| @@ -239,47 +239,18 @@ static const struct fw_address_region fcp_region = { | |||
| 239 | }; | 239 | }; |
| 240 | 240 | ||
| 241 | /* Adjust the template string if models with longer names appear. */ | 241 | /* Adjust the template string if models with longer names appear. */ |
| 242 | #define MAX_MODEL_NAME_LEN ((int)DIV_ROUND_UP(sizeof("FireDTV ????"), 4)) | 242 | #define MAX_MODEL_NAME_LEN sizeof("FireDTV ????") |
| 243 | |||
| 244 | static size_t model_name(u32 *directory, __be32 *buffer) | ||
| 245 | { | ||
| 246 | struct fw_csr_iterator ci; | ||
| 247 | int i, length, key, value, last_key = 0; | ||
| 248 | u32 *block = NULL; | ||
| 249 | |||
| 250 | fw_csr_iterator_init(&ci, directory); | ||
| 251 | while (fw_csr_iterator_next(&ci, &key, &value)) { | ||
| 252 | if (last_key == CSR_MODEL && | ||
| 253 | key == (CSR_DESCRIPTOR | CSR_LEAF)) | ||
| 254 | block = ci.p - 1 + value; | ||
| 255 | last_key = key; | ||
| 256 | } | ||
| 257 | |||
| 258 | if (block == NULL) | ||
| 259 | return 0; | ||
| 260 | |||
| 261 | length = min((int)(block[0] >> 16) - 2, MAX_MODEL_NAME_LEN); | ||
| 262 | if (length <= 0) | ||
| 263 | return 0; | ||
| 264 | |||
| 265 | /* fast-forward to text string */ | ||
| 266 | block += 3; | ||
| 267 | |||
| 268 | for (i = 0; i < length; i++) | ||
| 269 | buffer[i] = cpu_to_be32(block[i]); | ||
| 270 | |||
| 271 | return length * 4; | ||
| 272 | } | ||
| 273 | 243 | ||
| 274 | static int node_probe(struct device *dev) | 244 | static int node_probe(struct device *dev) |
| 275 | { | 245 | { |
| 276 | struct firedtv *fdtv; | 246 | struct firedtv *fdtv; |
| 277 | __be32 name[MAX_MODEL_NAME_LEN]; | 247 | char name[MAX_MODEL_NAME_LEN]; |
| 278 | int name_len, err; | 248 | int name_len, err; |
| 279 | 249 | ||
| 280 | name_len = model_name(fw_unit(dev)->directory, name); | 250 | name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL, |
| 251 | name, sizeof(name)); | ||
| 281 | 252 | ||
| 282 | fdtv = fdtv_alloc(dev, &backend, (char *)name, name_len); | 253 | fdtv = fdtv_alloc(dev, &backend, name, name_len >= 0 ? name_len : 0); |
| 283 | if (!fdtv) | 254 | if (!fdtv) |
| 284 | return -ENOMEM; | 255 | return -ENOMEM; |
| 285 | 256 | ||
diff --git a/include/linux/firewire.h b/include/linux/firewire.h index a0e67150a729..4bd94bf5e739 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h | |||
| @@ -65,12 +65,13 @@ | |||
| 65 | #define CSR_DIRECTORY_ID 0x20 | 65 | #define CSR_DIRECTORY_ID 0x20 |
| 66 | 66 | ||
| 67 | struct fw_csr_iterator { | 67 | struct fw_csr_iterator { |
| 68 | u32 *p; | 68 | const u32 *p; |
| 69 | u32 *end; | 69 | const u32 *end; |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 *p); | 72 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, const u32 *p); |
| 73 | int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value); | 73 | int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value); |
| 74 | int fw_csr_string(const u32 *directory, int key, char *buf, size_t size); | ||
| 74 | 75 | ||
| 75 | extern struct bus_type fw_bus_type; | 76 | extern struct bus_type fw_bus_type; |
| 76 | 77 | ||
| @@ -162,7 +163,7 @@ struct fw_device { | |||
| 162 | struct mutex client_list_mutex; | 163 | struct mutex client_list_mutex; |
| 163 | struct list_head client_list; | 164 | struct list_head client_list; |
| 164 | 165 | ||
| 165 | u32 *config_rom; | 166 | const u32 *config_rom; |
| 166 | size_t config_rom_length; | 167 | size_t config_rom_length; |
| 167 | int config_rom_retries; | 168 | int config_rom_retries; |
| 168 | unsigned is_local:1; | 169 | unsigned is_local:1; |
| @@ -204,7 +205,7 @@ int fw_device_enable_phys_dma(struct fw_device *device); | |||
| 204 | */ | 205 | */ |
| 205 | struct fw_unit { | 206 | struct fw_unit { |
| 206 | struct device device; | 207 | struct device device; |
| 207 | u32 *directory; | 208 | const u32 *directory; |
| 208 | struct fw_attribute_group attribute_group; | 209 | struct fw_attribute_group attribute_group; |
| 209 | }; | 210 | }; |
| 210 | 211 | ||
