aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/fw-device.c')
-rw-r--r--drivers/firewire/fw-device.c263
1 files changed, 215 insertions, 48 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 870125a3638e..2d01bc1b9752 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -25,7 +25,7 @@
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/idr.h> 27#include <linux/idr.h>
28#include <linux/rwsem.h> 28#include <linux/string.h>
29#include <asm/semaphore.h> 29#include <asm/semaphore.h>
30#include <asm/system.h> 30#include <asm/system.h>
31#include <linux/ctype.h> 31#include <linux/ctype.h>
@@ -160,9 +160,9 @@ static void fw_device_release(struct device *dev)
160 * Take the card lock so we don't set this to NULL while a 160 * Take the card lock so we don't set this to NULL while a
161 * FW_NODE_UPDATED callback is being handled. 161 * FW_NODE_UPDATED callback is being handled.
162 */ 162 */
163 spin_lock_irqsave(&device->card->lock, flags); 163 spin_lock_irqsave(&card->lock, flags);
164 device->node->data = NULL; 164 device->node->data = NULL;
165 spin_unlock_irqrestore(&device->card->lock, flags); 165 spin_unlock_irqrestore(&card->lock, flags);
166 166
167 fw_node_put(device->node); 167 fw_node_put(device->node);
168 kfree(device->config_rom); 168 kfree(device->config_rom);
@@ -195,7 +195,9 @@ show_immediate(struct device *dev, struct device_attribute *dattr, char *buf)
195 container_of(dattr, struct config_rom_attribute, attr); 195 container_of(dattr, struct config_rom_attribute, attr);
196 struct fw_csr_iterator ci; 196 struct fw_csr_iterator ci;
197 u32 *dir; 197 u32 *dir;
198 int key, value; 198 int key, value, ret = -ENOENT;
199
200 down_read(&fw_device_rwsem);
199 201
200 if (is_fw_unit(dev)) 202 if (is_fw_unit(dev))
201 dir = fw_unit(dev)->directory; 203 dir = fw_unit(dev)->directory;
@@ -204,11 +206,15 @@ show_immediate(struct device *dev, struct device_attribute *dattr, char *buf)
204 206
205 fw_csr_iterator_init(&ci, dir); 207 fw_csr_iterator_init(&ci, dir);
206 while (fw_csr_iterator_next(&ci, &key, &value)) 208 while (fw_csr_iterator_next(&ci, &key, &value))
207 if (attr->key == key) 209 if (attr->key == key) {
208 return snprintf(buf, buf ? PAGE_SIZE : 0, 210 ret = snprintf(buf, buf ? PAGE_SIZE : 0,
209 "0x%06x\n", value); 211 "0x%06x\n", value);
212 break;
213 }
214
215 up_read(&fw_device_rwsem);
210 216
211 return -ENOENT; 217 return ret;
212} 218}
213 219
214#define IMMEDIATE_ATTR(name, key) \ 220#define IMMEDIATE_ATTR(name, key) \
@@ -221,9 +227,11 @@ show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf)
221 container_of(dattr, struct config_rom_attribute, attr); 227 container_of(dattr, struct config_rom_attribute, attr);
222 struct fw_csr_iterator ci; 228 struct fw_csr_iterator ci;
223 u32 *dir, *block = NULL, *p, *end; 229 u32 *dir, *block = NULL, *p, *end;
224 int length, key, value, last_key = 0; 230 int length, key, value, last_key = 0, ret = -ENOENT;
225 char *b; 231 char *b;
226 232
233 down_read(&fw_device_rwsem);
234
227 if (is_fw_unit(dev)) 235 if (is_fw_unit(dev))
228 dir = fw_unit(dev)->directory; 236 dir = fw_unit(dev)->directory;
229 else 237 else
@@ -238,18 +246,20 @@ show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf)
238 } 246 }
239 247
240 if (block == NULL) 248 if (block == NULL)
241 return -ENOENT; 249 goto out;
242 250
243 length = min(block[0] >> 16, 256U); 251 length = min(block[0] >> 16, 256U);
244 if (length < 3) 252 if (length < 3)
245 return -ENOENT; 253 goto out;
246 254
247 if (block[1] != 0 || block[2] != 0) 255 if (block[1] != 0 || block[2] != 0)
248 /* Unknown encoding. */ 256 /* Unknown encoding. */
249 return -ENOENT; 257 goto out;
250 258
251 if (buf == NULL) 259 if (buf == NULL) {
252 return length * 4; 260 ret = length * 4;
261 goto out;
262 }
253 263
254 b = buf; 264 b = buf;
255 end = &block[length + 1]; 265 end = &block[length + 1];
@@ -259,8 +269,11 @@ show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf)
259 /* Strip trailing whitespace and add newline. */ 269 /* Strip trailing whitespace and add newline. */
260 while (b--, (isspace(*b) || *b == '\0') && b > buf); 270 while (b--, (isspace(*b) || *b == '\0') && b > buf);
261 strcpy(b + 1, "\n"); 271 strcpy(b + 1, "\n");
272 ret = b + 2 - buf;
273 out:
274 up_read(&fw_device_rwsem);
262 275
263 return b + 2 - buf; 276 return ret;
264} 277}
265 278
266#define TEXT_LEAF_ATTR(name, key) \ 279#define TEXT_LEAF_ATTR(name, key) \
@@ -337,19 +350,28 @@ static ssize_t
337config_rom_show(struct device *dev, struct device_attribute *attr, char *buf) 350config_rom_show(struct device *dev, struct device_attribute *attr, char *buf)
338{ 351{
339 struct fw_device *device = fw_device(dev); 352 struct fw_device *device = fw_device(dev);
353 size_t length;
340 354
341 memcpy(buf, device->config_rom, device->config_rom_length * 4); 355 down_read(&fw_device_rwsem);
356 length = device->config_rom_length * 4;
357 memcpy(buf, device->config_rom, length);
358 up_read(&fw_device_rwsem);
342 359
343 return device->config_rom_length * 4; 360 return length;
344} 361}
345 362
346static ssize_t 363static ssize_t
347guid_show(struct device *dev, struct device_attribute *attr, char *buf) 364guid_show(struct device *dev, struct device_attribute *attr, char *buf)
348{ 365{
349 struct fw_device *device = fw_device(dev); 366 struct fw_device *device = fw_device(dev);
367 int ret;
368
369 down_read(&fw_device_rwsem);
370 ret = snprintf(buf, PAGE_SIZE, "0x%08x%08x\n",
371 device->config_rom[3], device->config_rom[4]);
372 up_read(&fw_device_rwsem);
350 373
351 return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n", 374 return ret;
352 device->config_rom[3], device->config_rom[4]);
353} 375}
354 376
355static struct device_attribute fw_device_attributes[] = { 377static struct device_attribute fw_device_attributes[] = {
@@ -388,7 +410,7 @@ read_rom(struct fw_device *device, int generation, int index, u32 *data)
388 410
389 init_completion(&callback_data.done); 411 init_completion(&callback_data.done);
390 412
391 offset = 0xfffff0000400ULL + index * 4; 413 offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
392 fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, 414 fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
393 device->node_id, generation, device->max_speed, 415 device->node_id, generation, device->max_speed,
394 offset, NULL, 4, complete_transaction, &callback_data); 416 offset, NULL, 4, complete_transaction, &callback_data);
@@ -400,6 +422,9 @@ read_rom(struct fw_device *device, int generation, int index, u32 *data)
400 return callback_data.rcode; 422 return callback_data.rcode;
401} 423}
402 424
425#define READ_BIB_ROM_SIZE 256
426#define READ_BIB_STACK_SIZE 16
427
403/* 428/*
404 * Read the bus info block, perform a speed probe, and read all of the rest of 429 * Read the bus info block, perform a speed probe, and read all of the rest of
405 * the config ROM. We do all this with a cached bus generation. If the bus 430 * the config ROM. We do all this with a cached bus generation. If the bus
@@ -409,16 +434,23 @@ read_rom(struct fw_device *device, int generation, int index, u32 *data)
409 */ 434 */
410static int read_bus_info_block(struct fw_device *device, int generation) 435static int read_bus_info_block(struct fw_device *device, int generation)
411{ 436{
412 static u32 rom[256]; 437 u32 *rom, *stack, *old_rom, *new_rom;
413 u32 stack[16], sp, key; 438 u32 sp, key;
414 int i, end, length; 439 int i, end, length, ret = -1;
440
441 rom = kmalloc(sizeof(*rom) * READ_BIB_ROM_SIZE +
442 sizeof(*stack) * READ_BIB_STACK_SIZE, GFP_KERNEL);
443 if (rom == NULL)
444 return -ENOMEM;
445
446 stack = &rom[READ_BIB_ROM_SIZE];
415 447
416 device->max_speed = SCODE_100; 448 device->max_speed = SCODE_100;
417 449
418 /* First read the bus info block. */ 450 /* First read the bus info block. */
419 for (i = 0; i < 5; i++) { 451 for (i = 0; i < 5; i++) {
420 if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE) 452 if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
421 return -1; 453 goto out;
422 /* 454 /*
423 * As per IEEE1212 7.2, during power-up, devices can 455 * As per IEEE1212 7.2, during power-up, devices can
424 * reply with a 0 for the first quadlet of the config 456 * reply with a 0 for the first quadlet of the config
@@ -428,7 +460,7 @@ static int read_bus_info_block(struct fw_device *device, int generation)
428 * retry mechanism will try again later. 460 * retry mechanism will try again later.
429 */ 461 */
430 if (i == 0 && rom[i] == 0) 462 if (i == 0 && rom[i] == 0)
431 return -1; 463 goto out;
432 } 464 }
433 465
434 device->max_speed = device->node->max_speed; 466 device->max_speed = device->node->max_speed;
@@ -478,26 +510,26 @@ static int read_bus_info_block(struct fw_device *device, int generation)
478 */ 510 */
479 key = stack[--sp]; 511 key = stack[--sp];
480 i = key & 0xffffff; 512 i = key & 0xffffff;
481 if (i >= ARRAY_SIZE(rom)) 513 if (i >= READ_BIB_ROM_SIZE)
482 /* 514 /*
483 * The reference points outside the standard 515 * The reference points outside the standard
484 * config rom area, something's fishy. 516 * config rom area, something's fishy.
485 */ 517 */
486 return -1; 518 goto out;
487 519
488 /* Read header quadlet for the block to get the length. */ 520 /* Read header quadlet for the block to get the length. */
489 if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE) 521 if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
490 return -1; 522 goto out;
491 end = i + (rom[i] >> 16) + 1; 523 end = i + (rom[i] >> 16) + 1;
492 i++; 524 i++;
493 if (end > ARRAY_SIZE(rom)) 525 if (end > READ_BIB_ROM_SIZE)
494 /* 526 /*
495 * This block extends outside standard config 527 * This block extends outside standard config
496 * area (and the array we're reading it 528 * area (and the array we're reading it
497 * into). That's broken, so ignore this 529 * into). That's broken, so ignore this
498 * device. 530 * device.
499 */ 531 */
500 return -1; 532 goto out;
501 533
502 /* 534 /*
503 * Now read in the block. If this is a directory 535 * Now read in the block. If this is a directory
@@ -507,9 +539,9 @@ static int read_bus_info_block(struct fw_device *device, int generation)
507 while (i < end) { 539 while (i < end) {
508 if (read_rom(device, generation, i, &rom[i]) != 540 if (read_rom(device, generation, i, &rom[i]) !=
509 RCODE_COMPLETE) 541 RCODE_COMPLETE)
510 return -1; 542 goto out;
511 if ((key >> 30) == 3 && (rom[i] >> 30) > 1 && 543 if ((key >> 30) == 3 && (rom[i] >> 30) > 1 &&
512 sp < ARRAY_SIZE(stack)) 544 sp < READ_BIB_STACK_SIZE)
513 stack[sp++] = i + rom[i]; 545 stack[sp++] = i + rom[i];
514 i++; 546 i++;
515 } 547 }
@@ -517,13 +549,23 @@ static int read_bus_info_block(struct fw_device *device, int generation)
517 length = i; 549 length = i;
518 } 550 }
519 551
520 device->config_rom = kmalloc(length * 4, GFP_KERNEL); 552 old_rom = device->config_rom;
521 if (device->config_rom == NULL) 553 new_rom = kmemdup(rom, length * 4, GFP_KERNEL);
522 return -1; 554 if (new_rom == NULL)
523 memcpy(device->config_rom, rom, length * 4); 555 goto out;
556
557 down_write(&fw_device_rwsem);
558 device->config_rom = new_rom;
524 device->config_rom_length = length; 559 device->config_rom_length = length;
560 up_write(&fw_device_rwsem);
525 561
526 return 0; 562 kfree(old_rom);
563 ret = 0;
564 device->cmc = rom[2] & 1 << 30;
565 out:
566 kfree(rom);
567
568 return ret;
527} 569}
528 570
529static void fw_unit_release(struct device *dev) 571static void fw_unit_release(struct device *dev)
@@ -592,7 +634,14 @@ static int shutdown_unit(struct device *device, void *data)
592 return 0; 634 return 0;
593} 635}
594 636
595static DECLARE_RWSEM(idr_rwsem); 637/*
638 * fw_device_rwsem acts as dual purpose mutex:
639 * - serializes accesses to fw_device_idr,
640 * - serializes accesses to fw_device.config_rom/.config_rom_length and
641 * fw_unit.directory, unless those accesses happen at safe occasions
642 */
643DECLARE_RWSEM(fw_device_rwsem);
644
596static DEFINE_IDR(fw_device_idr); 645static DEFINE_IDR(fw_device_idr);
597int fw_cdev_major; 646int fw_cdev_major;
598 647
@@ -600,11 +649,11 @@ struct fw_device *fw_device_get_by_devt(dev_t devt)
600{ 649{
601 struct fw_device *device; 650 struct fw_device *device;
602 651
603 down_read(&idr_rwsem); 652 down_read(&fw_device_rwsem);
604 device = idr_find(&fw_device_idr, MINOR(devt)); 653 device = idr_find(&fw_device_idr, MINOR(devt));
605 if (device) 654 if (device)
606 fw_device_get(device); 655 fw_device_get(device);
607 up_read(&idr_rwsem); 656 up_read(&fw_device_rwsem);
608 657
609 return device; 658 return device;
610} 659}
@@ -619,9 +668,9 @@ static void fw_device_shutdown(struct work_struct *work)
619 device_for_each_child(&device->device, NULL, shutdown_unit); 668 device_for_each_child(&device->device, NULL, shutdown_unit);
620 device_unregister(&device->device); 669 device_unregister(&device->device);
621 670
622 down_write(&idr_rwsem); 671 down_write(&fw_device_rwsem);
623 idr_remove(&fw_device_idr, minor); 672 idr_remove(&fw_device_idr, minor);
624 up_write(&idr_rwsem); 673 up_write(&fw_device_rwsem);
625 fw_device_put(device); 674 fw_device_put(device);
626} 675}
627 676
@@ -674,10 +723,10 @@ static void fw_device_init(struct work_struct *work)
674 err = -ENOMEM; 723 err = -ENOMEM;
675 724
676 fw_device_get(device); 725 fw_device_get(device);
677 down_write(&idr_rwsem); 726 down_write(&fw_device_rwsem);
678 if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) 727 if (idr_pre_get(&fw_device_idr, GFP_KERNEL))
679 err = idr_get_new(&fw_device_idr, device, &minor); 728 err = idr_get_new(&fw_device_idr, device, &minor);
680 up_write(&idr_rwsem); 729 up_write(&fw_device_rwsem);
681 730
682 if (err < 0) 731 if (err < 0)
683 goto error; 732 goto error;
@@ -711,7 +760,7 @@ static void fw_device_init(struct work_struct *work)
711 if (atomic_cmpxchg(&device->state, 760 if (atomic_cmpxchg(&device->state,
712 FW_DEVICE_INITIALIZING, 761 FW_DEVICE_INITIALIZING,
713 FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) { 762 FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
714 fw_device_shutdown(&device->work.work); 763 fw_device_shutdown(work);
715 } else { 764 } else {
716 if (device->config_rom_retries) 765 if (device->config_rom_retries)
717 fw_notify("created device %s: GUID %08x%08x, S%d00, " 766 fw_notify("created device %s: GUID %08x%08x, S%d00, "
@@ -725,6 +774,7 @@ static void fw_device_init(struct work_struct *work)
725 device->device.bus_id, 774 device->device.bus_id,
726 device->config_rom[3], device->config_rom[4], 775 device->config_rom[3], device->config_rom[4],
727 1 << device->max_speed); 776 1 << device->max_speed);
777 device->config_rom_retries = 0;
728 } 778 }
729 779
730 /* 780 /*
@@ -739,9 +789,9 @@ static void fw_device_init(struct work_struct *work)
739 return; 789 return;
740 790
741 error_with_cdev: 791 error_with_cdev:
742 down_write(&idr_rwsem); 792 down_write(&fw_device_rwsem);
743 idr_remove(&fw_device_idr, minor); 793 idr_remove(&fw_device_idr, minor);
744 up_write(&idr_rwsem); 794 up_write(&fw_device_rwsem);
745 error: 795 error:
746 fw_device_put(device); /* fw_device_idr's reference */ 796 fw_device_put(device); /* fw_device_idr's reference */
747 797
@@ -771,6 +821,106 @@ static void fw_device_update(struct work_struct *work)
771 device_for_each_child(&device->device, NULL, update_unit); 821 device_for_each_child(&device->device, NULL, update_unit);
772} 822}
773 823
824enum {
825 REREAD_BIB_ERROR,
826 REREAD_BIB_GONE,
827 REREAD_BIB_UNCHANGED,
828 REREAD_BIB_CHANGED,
829};
830
831/* Reread and compare bus info block and header of root directory */
832static int reread_bus_info_block(struct fw_device *device, int generation)
833{
834 u32 q;
835 int i;
836
837 for (i = 0; i < 6; i++) {
838 if (read_rom(device, generation, i, &q) != RCODE_COMPLETE)
839 return REREAD_BIB_ERROR;
840
841 if (i == 0 && q == 0)
842 return REREAD_BIB_GONE;
843
844 if (i > device->config_rom_length || q != device->config_rom[i])
845 return REREAD_BIB_CHANGED;
846 }
847
848 return REREAD_BIB_UNCHANGED;
849}
850
851static void fw_device_refresh(struct work_struct *work)
852{
853 struct fw_device *device =
854 container_of(work, struct fw_device, work.work);
855 struct fw_card *card = device->card;
856 int node_id = device->node_id;
857
858 switch (reread_bus_info_block(device, device->generation)) {
859 case REREAD_BIB_ERROR:
860 if (device->config_rom_retries < MAX_RETRIES / 2 &&
861 atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
862 device->config_rom_retries++;
863 schedule_delayed_work(&device->work, RETRY_DELAY / 2);
864
865 return;
866 }
867 goto give_up;
868
869 case REREAD_BIB_GONE:
870 goto gone;
871
872 case REREAD_BIB_UNCHANGED:
873 if (atomic_cmpxchg(&device->state,
874 FW_DEVICE_INITIALIZING,
875 FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
876 goto gone;
877
878 fw_device_update(work);
879 device->config_rom_retries = 0;
880 goto out;
881
882 case REREAD_BIB_CHANGED:
883 break;
884 }
885
886 /*
887 * Something changed. We keep things simple and don't investigate
888 * further. We just destroy all previous units and create new ones.
889 */
890 device_for_each_child(&device->device, NULL, shutdown_unit);
891
892 if (read_bus_info_block(device, device->generation) < 0) {
893 if (device->config_rom_retries < MAX_RETRIES &&
894 atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
895 device->config_rom_retries++;
896 schedule_delayed_work(&device->work, RETRY_DELAY);
897
898 return;
899 }
900 goto give_up;
901 }
902
903 create_units(device);
904
905 if (atomic_cmpxchg(&device->state,
906 FW_DEVICE_INITIALIZING,
907 FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
908 goto gone;
909
910 fw_notify("refreshed device %s\n", device->device.bus_id);
911 device->config_rom_retries = 0;
912 goto out;
913
914 give_up:
915 fw_notify("giving up on refresh of device %s\n", device->device.bus_id);
916 gone:
917 atomic_set(&device->state, FW_DEVICE_SHUTDOWN);
918 fw_device_shutdown(work);
919 out:
920 if (node_id == card->root_node->node_id)
921 schedule_delayed_work(&card->work, 0);
922}
923
774void fw_node_event(struct fw_card *card, struct fw_node *node, int event) 924void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
775{ 925{
776 struct fw_device *device; 926 struct fw_device *device;
@@ -780,7 +930,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
780 case FW_NODE_LINK_ON: 930 case FW_NODE_LINK_ON:
781 if (!node->link_on) 931 if (!node->link_on)
782 break; 932 break;
783 933 create:
784 device = kzalloc(sizeof(*device), GFP_ATOMIC); 934 device = kzalloc(sizeof(*device), GFP_ATOMIC);
785 if (device == NULL) 935 if (device == NULL)
786 break; 936 break;
@@ -819,6 +969,23 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
819 schedule_delayed_work(&device->work, INITIAL_DELAY); 969 schedule_delayed_work(&device->work, INITIAL_DELAY);
820 break; 970 break;
821 971
972 case FW_NODE_INITIATED_RESET:
973 device = node->data;
974 if (device == NULL)
975 goto create;
976
977 device->node_id = node->node_id;
978 smp_wmb(); /* update node_id before generation */
979 device->generation = card->generation;
980 if (atomic_cmpxchg(&device->state,
981 FW_DEVICE_RUNNING,
982 FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) {
983 PREPARE_DELAYED_WORK(&device->work, fw_device_refresh);
984 schedule_delayed_work(&device->work,
985 node == card->local_node ? 0 : INITIAL_DELAY);
986 }
987 break;
988
822 case FW_NODE_UPDATED: 989 case FW_NODE_UPDATED:
823 if (!node->link_on || node->data == NULL) 990 if (!node->link_on || node->data == NULL)
824 break; 991 break;