diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 11:13:10 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-08 11:13:10 -0500 |
commit | bb592cf474404e51cbf3c419fb72fda83c4b7d72 (patch) | |
tree | 05823f536d5f095857a7aff732e205d249e4b7a1 /drivers/firewire | |
parent | 79c9601c2e0dbbe69895d302de4d19f3a31fbd30 (diff) | |
parent | af0940dac37545b1e7900b19c464fb6367d3f82f (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
ieee1394: Use hweight32
firewire: cdev: reduce stack usage by ioctl_dispatch
firewire: ohci: 0 may be a valid DMA address
firewire: core: WARN on wrong usage of core transaction functions
firewire: core: optimize Topology Map creation
firewire: core: clarify generate_config_rom usage
firewire: optimize config ROM creation
firewire: cdev: normalize variable names
firewire: normalize style of queue_work wrappers
firewire: cdev: fix memory leak in an error path
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/core-card.c | 75 | ||||
-rw-r--r-- | drivers/firewire/core-cdev.c | 113 | ||||
-rw-r--r-- | drivers/firewire/core-topology.c | 17 | ||||
-rw-r--r-- | drivers/firewire/core-transaction.c | 19 | ||||
-rw-r--r-- | drivers/firewire/core.h | 9 | ||||
-rw-r--r-- | drivers/firewire/ohci.c | 39 | ||||
-rw-r--r-- | drivers/firewire/sbp2.c | 9 |
7 files changed, 155 insertions, 126 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index e4864e894e4f..7083bcc1b9c7 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -38,15 +38,14 @@ | |||
38 | 38 | ||
39 | #include "core.h" | 39 | #include "core.h" |
40 | 40 | ||
41 | int fw_compute_block_crc(u32 *block) | 41 | int fw_compute_block_crc(__be32 *block) |
42 | { | 42 | { |
43 | __be32 be32_block[256]; | 43 | int length; |
44 | int i, length; | 44 | u16 crc; |
45 | 45 | ||
46 | length = (*block >> 16) & 0xff; | 46 | length = (be32_to_cpu(block[0]) >> 16) & 0xff; |
47 | for (i = 0; i < length; i++) | 47 | crc = crc_itu_t(0, (u8 *)&block[1], length * 4); |
48 | be32_block[i] = cpu_to_be32(block[i + 1]); | 48 | *block |= cpu_to_be32(crc); |
49 | *block |= crc_itu_t(0, (u8 *) be32_block, length * 4); | ||
50 | 49 | ||
51 | return length; | 50 | return length; |
52 | } | 51 | } |
@@ -57,6 +56,8 @@ static LIST_HEAD(card_list); | |||
57 | static LIST_HEAD(descriptor_list); | 56 | static LIST_HEAD(descriptor_list); |
58 | static int descriptor_count; | 57 | static int descriptor_count; |
59 | 58 | ||
59 | static __be32 tmp_config_rom[256]; | ||
60 | |||
60 | #define BIB_CRC(v) ((v) << 0) | 61 | #define BIB_CRC(v) ((v) << 0) |
61 | #define BIB_CRC_LENGTH(v) ((v) << 16) | 62 | #define BIB_CRC_LENGTH(v) ((v) << 16) |
62 | #define BIB_INFO_LENGTH(v) ((v) << 24) | 63 | #define BIB_INFO_LENGTH(v) ((v) << 24) |
@@ -72,11 +73,10 @@ static int descriptor_count; | |||
72 | #define BIB_CMC ((1) << 30) | 73 | #define BIB_CMC ((1) << 30) |
73 | #define BIB_IMC ((1) << 31) | 74 | #define BIB_IMC ((1) << 31) |
74 | 75 | ||
75 | static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length) | 76 | static size_t generate_config_rom(struct fw_card *card, __be32 *config_rom) |
76 | { | 77 | { |
77 | struct fw_descriptor *desc; | 78 | struct fw_descriptor *desc; |
78 | static u32 config_rom[256]; | 79 | int i, j, k, length; |
79 | int i, j, length; | ||
80 | 80 | ||
81 | /* | 81 | /* |
82 | * Initialize contents of config rom buffer. On the OHCI | 82 | * Initialize contents of config rom buffer. On the OHCI |
@@ -87,40 +87,39 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length) | |||
87 | * the version stored in the OHCI registers. | 87 | * the version stored in the OHCI registers. |
88 | */ | 88 | */ |
89 | 89 | ||
90 | memset(config_rom, 0, sizeof(config_rom)); | 90 | config_rom[0] = cpu_to_be32( |
91 | config_rom[0] = BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0); | 91 | BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0)); |
92 | config_rom[1] = 0x31333934; | 92 | config_rom[1] = cpu_to_be32(0x31333934); |
93 | 93 | config_rom[2] = cpu_to_be32( | |
94 | config_rom[2] = | ||
95 | BIB_LINK_SPEED(card->link_speed) | | 94 | BIB_LINK_SPEED(card->link_speed) | |
96 | BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | | 95 | BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | |
97 | BIB_MAX_ROM(2) | | 96 | BIB_MAX_ROM(2) | |
98 | BIB_MAX_RECEIVE(card->max_receive) | | 97 | BIB_MAX_RECEIVE(card->max_receive) | |
99 | BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC; | 98 | BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC); |
100 | config_rom[3] = card->guid >> 32; | 99 | config_rom[3] = cpu_to_be32(card->guid >> 32); |
101 | config_rom[4] = card->guid; | 100 | config_rom[4] = cpu_to_be32(card->guid); |
102 | 101 | ||
103 | /* Generate root directory. */ | 102 | /* Generate root directory. */ |
104 | i = 5; | 103 | config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */ |
105 | config_rom[i++] = 0; | 104 | i = 7; |
106 | config_rom[i++] = 0x0c0083c0; /* node capabilities */ | 105 | j = 7 + descriptor_count; |
107 | j = i + descriptor_count; | ||
108 | 106 | ||
109 | /* Generate root directory entries for descriptors. */ | 107 | /* Generate root directory entries for descriptors. */ |
110 | list_for_each_entry (desc, &descriptor_list, link) { | 108 | list_for_each_entry (desc, &descriptor_list, link) { |
111 | if (desc->immediate > 0) | 109 | if (desc->immediate > 0) |
112 | config_rom[i++] = desc->immediate; | 110 | config_rom[i++] = cpu_to_be32(desc->immediate); |
113 | config_rom[i] = desc->key | (j - i); | 111 | config_rom[i] = cpu_to_be32(desc->key | (j - i)); |
114 | i++; | 112 | i++; |
115 | j += desc->length; | 113 | j += desc->length; |
116 | } | 114 | } |
117 | 115 | ||
118 | /* Update root directory length. */ | 116 | /* Update root directory length. */ |
119 | config_rom[5] = (i - 5 - 1) << 16; | 117 | config_rom[5] = cpu_to_be32((i - 5 - 1) << 16); |
120 | 118 | ||
121 | /* End of root directory, now copy in descriptors. */ | 119 | /* End of root directory, now copy in descriptors. */ |
122 | list_for_each_entry (desc, &descriptor_list, link) { | 120 | list_for_each_entry (desc, &descriptor_list, link) { |
123 | memcpy(&config_rom[i], desc->data, desc->length * 4); | 121 | for (k = 0; k < desc->length; k++) |
122 | config_rom[i + k] = cpu_to_be32(desc->data[k]); | ||
124 | i += desc->length; | 123 | i += desc->length; |
125 | } | 124 | } |
126 | 125 | ||
@@ -131,20 +130,17 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length) | |||
131 | for (i = 0; i < j; i += length + 1) | 130 | for (i = 0; i < j; i += length + 1) |
132 | length = fw_compute_block_crc(config_rom + i); | 131 | length = fw_compute_block_crc(config_rom + i); |
133 | 132 | ||
134 | *config_rom_length = j; | 133 | return j; |
135 | |||
136 | return config_rom; | ||
137 | } | 134 | } |
138 | 135 | ||
139 | static void update_config_roms(void) | 136 | static void update_config_roms(void) |
140 | { | 137 | { |
141 | struct fw_card *card; | 138 | struct fw_card *card; |
142 | u32 *config_rom; | ||
143 | size_t length; | 139 | size_t length; |
144 | 140 | ||
145 | list_for_each_entry (card, &card_list, link) { | 141 | list_for_each_entry (card, &card_list, link) { |
146 | config_rom = generate_config_rom(card, &length); | 142 | length = generate_config_rom(card, tmp_config_rom); |
147 | card->driver->set_config_rom(card, config_rom, length); | 143 | card->driver->set_config_rom(card, tmp_config_rom, length); |
148 | } | 144 | } |
149 | } | 145 | } |
150 | 146 | ||
@@ -211,11 +207,8 @@ static const char gap_count_table[] = { | |||
211 | 207 | ||
212 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) | 208 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) |
213 | { | 209 | { |
214 | int scheduled; | ||
215 | |||
216 | fw_card_get(card); | 210 | fw_card_get(card); |
217 | scheduled = schedule_delayed_work(&card->work, delay); | 211 | if (!schedule_delayed_work(&card->work, delay)) |
218 | if (!scheduled) | ||
219 | fw_card_put(card); | 212 | fw_card_put(card); |
220 | } | 213 | } |
221 | 214 | ||
@@ -435,7 +428,6 @@ EXPORT_SYMBOL(fw_card_initialize); | |||
435 | int fw_card_add(struct fw_card *card, | 428 | int fw_card_add(struct fw_card *card, |
436 | u32 max_receive, u32 link_speed, u64 guid) | 429 | u32 max_receive, u32 link_speed, u64 guid) |
437 | { | 430 | { |
438 | u32 *config_rom; | ||
439 | size_t length; | 431 | size_t length; |
440 | int ret; | 432 | int ret; |
441 | 433 | ||
@@ -445,8 +437,8 @@ int fw_card_add(struct fw_card *card, | |||
445 | 437 | ||
446 | mutex_lock(&card_mutex); | 438 | mutex_lock(&card_mutex); |
447 | 439 | ||
448 | config_rom = generate_config_rom(card, &length); | 440 | length = generate_config_rom(card, tmp_config_rom); |
449 | ret = card->driver->enable(card, config_rom, length); | 441 | ret = card->driver->enable(card, tmp_config_rom, length); |
450 | if (ret == 0) | 442 | if (ret == 0) |
451 | list_add_tail(&card->link, &card_list); | 443 | list_add_tail(&card->link, &card_list); |
452 | 444 | ||
@@ -465,7 +457,8 @@ EXPORT_SYMBOL(fw_card_add); | |||
465 | * shutdown still need to be provided by the card driver. | 457 | * shutdown still need to be provided by the card driver. |
466 | */ | 458 | */ |
467 | 459 | ||
468 | static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length) | 460 | static int dummy_enable(struct fw_card *card, |
461 | const __be32 *config_rom, size_t length) | ||
469 | { | 462 | { |
470 | BUG(); | 463 | BUG(); |
471 | return -1; | 464 | return -1; |
@@ -478,7 +471,7 @@ static int dummy_update_phy_reg(struct fw_card *card, int address, | |||
478 | } | 471 | } |
479 | 472 | ||
480 | static int dummy_set_config_rom(struct fw_card *card, | 473 | static int dummy_set_config_rom(struct fw_card *card, |
481 | u32 *config_rom, size_t length) | 474 | const __be32 *config_rom, size_t length) |
482 | { | 475 | { |
483 | /* | 476 | /* |
484 | * We take the card out of card_list before setting the dummy | 477 | * We take the card out of card_list before setting the dummy |
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 5089331544ed..231e6ee5ba43 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
@@ -130,9 +130,22 @@ struct iso_resource { | |||
130 | struct iso_resource_event *e_alloc, *e_dealloc; | 130 | struct iso_resource_event *e_alloc, *e_dealloc; |
131 | }; | 131 | }; |
132 | 132 | ||
133 | static void schedule_iso_resource(struct iso_resource *); | ||
134 | static void release_iso_resource(struct client *, struct client_resource *); | 133 | static void release_iso_resource(struct client *, struct client_resource *); |
135 | 134 | ||
135 | static void schedule_iso_resource(struct iso_resource *r, unsigned long delay) | ||
136 | { | ||
137 | client_get(r->client); | ||
138 | if (!schedule_delayed_work(&r->work, delay)) | ||
139 | client_put(r->client); | ||
140 | } | ||
141 | |||
142 | static void schedule_if_iso_resource(struct client_resource *resource) | ||
143 | { | ||
144 | if (resource->release == release_iso_resource) | ||
145 | schedule_iso_resource(container_of(resource, | ||
146 | struct iso_resource, resource), 0); | ||
147 | } | ||
148 | |||
136 | /* | 149 | /* |
137 | * dequeue_event() just kfree()'s the event, so the event has to be | 150 | * dequeue_event() just kfree()'s the event, so the event has to be |
138 | * the first field in a struct XYZ_event. | 151 | * the first field in a struct XYZ_event. |
@@ -166,7 +179,7 @@ struct iso_interrupt_event { | |||
166 | 179 | ||
167 | struct iso_resource_event { | 180 | struct iso_resource_event { |
168 | struct event event; | 181 | struct event event; |
169 | struct fw_cdev_event_iso_resource resource; | 182 | struct fw_cdev_event_iso_resource iso_resource; |
170 | }; | 183 | }; |
171 | 184 | ||
172 | static inline void __user *u64_to_uptr(__u64 value) | 185 | static inline void __user *u64_to_uptr(__u64 value) |
@@ -314,11 +327,8 @@ static void for_each_client(struct fw_device *device, | |||
314 | 327 | ||
315 | static int schedule_reallocations(int id, void *p, void *data) | 328 | static int schedule_reallocations(int id, void *p, void *data) |
316 | { | 329 | { |
317 | struct client_resource *r = p; | 330 | schedule_if_iso_resource(p); |
318 | 331 | ||
319 | if (r->release == release_iso_resource) | ||
320 | schedule_iso_resource(container_of(r, | ||
321 | struct iso_resource, resource)); | ||
322 | return 0; | 332 | return 0; |
323 | } | 333 | } |
324 | 334 | ||
@@ -414,9 +424,7 @@ static int add_client_resource(struct client *client, | |||
414 | &resource->handle); | 424 | &resource->handle); |
415 | if (ret >= 0) { | 425 | if (ret >= 0) { |
416 | client_get(client); | 426 | client_get(client); |
417 | if (resource->release == release_iso_resource) | 427 | schedule_if_iso_resource(resource); |
418 | schedule_iso_resource(container_of(resource, | ||
419 | struct iso_resource, resource)); | ||
420 | } | 428 | } |
421 | spin_unlock_irqrestore(&client->lock, flags); | 429 | spin_unlock_irqrestore(&client->lock, flags); |
422 | 430 | ||
@@ -428,26 +436,26 @@ static int add_client_resource(struct client *client, | |||
428 | 436 | ||
429 | static int release_client_resource(struct client *client, u32 handle, | 437 | static int release_client_resource(struct client *client, u32 handle, |
430 | client_resource_release_fn_t release, | 438 | client_resource_release_fn_t release, |
431 | struct client_resource **resource) | 439 | struct client_resource **return_resource) |
432 | { | 440 | { |
433 | struct client_resource *r; | 441 | struct client_resource *resource; |
434 | 442 | ||
435 | spin_lock_irq(&client->lock); | 443 | spin_lock_irq(&client->lock); |
436 | if (client->in_shutdown) | 444 | if (client->in_shutdown) |
437 | r = NULL; | 445 | resource = NULL; |
438 | else | 446 | else |
439 | r = idr_find(&client->resource_idr, handle); | 447 | resource = idr_find(&client->resource_idr, handle); |
440 | if (r && r->release == release) | 448 | if (resource && resource->release == release) |
441 | idr_remove(&client->resource_idr, handle); | 449 | idr_remove(&client->resource_idr, handle); |
442 | spin_unlock_irq(&client->lock); | 450 | spin_unlock_irq(&client->lock); |
443 | 451 | ||
444 | if (!(r && r->release == release)) | 452 | if (!(resource && resource->release == release)) |
445 | return -EINVAL; | 453 | return -EINVAL; |
446 | 454 | ||
447 | if (resource) | 455 | if (return_resource) |
448 | *resource = r; | 456 | *return_resource = resource; |
449 | else | 457 | else |
450 | r->release(client, r); | 458 | resource->release(client, resource); |
451 | 459 | ||
452 | client_put(client); | 460 | client_put(client); |
453 | 461 | ||
@@ -699,6 +707,7 @@ static int ioctl_send_response(struct client *client, void *buffer) | |||
699 | struct fw_cdev_send_response *request = buffer; | 707 | struct fw_cdev_send_response *request = buffer; |
700 | struct client_resource *resource; | 708 | struct client_resource *resource; |
701 | struct inbound_transaction_resource *r; | 709 | struct inbound_transaction_resource *r; |
710 | int ret = 0; | ||
702 | 711 | ||
703 | if (release_client_resource(client, request->handle, | 712 | if (release_client_resource(client, request->handle, |
704 | release_request, &resource) < 0) | 713 | release_request, &resource) < 0) |
@@ -708,13 +717,17 @@ static int ioctl_send_response(struct client *client, void *buffer) | |||
708 | resource); | 717 | resource); |
709 | if (request->length < r->length) | 718 | if (request->length < r->length) |
710 | r->length = request->length; | 719 | r->length = request->length; |
711 | if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) | 720 | |
712 | return -EFAULT; | 721 | if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) { |
722 | ret = -EFAULT; | ||
723 | goto out; | ||
724 | } | ||
713 | 725 | ||
714 | fw_send_response(client->device->card, r->request, request->rcode); | 726 | fw_send_response(client->device->card, r->request, request->rcode); |
727 | out: | ||
715 | kfree(r); | 728 | kfree(r); |
716 | 729 | ||
717 | return 0; | 730 | return ret; |
718 | } | 731 | } |
719 | 732 | ||
720 | static int ioctl_initiate_bus_reset(struct client *client, void *buffer) | 733 | static int ioctl_initiate_bus_reset(struct client *client, void *buffer) |
@@ -1028,8 +1041,7 @@ static void iso_resource_work(struct work_struct *work) | |||
1028 | /* Allow 1000ms grace period for other reallocations. */ | 1041 | /* Allow 1000ms grace period for other reallocations. */ |
1029 | if (todo == ISO_RES_ALLOC && | 1042 | if (todo == ISO_RES_ALLOC && |
1030 | time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) { | 1043 | time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) { |
1031 | if (schedule_delayed_work(&r->work, DIV_ROUND_UP(HZ, 3))) | 1044 | schedule_iso_resource(r, DIV_ROUND_UP(HZ, 3)); |
1032 | client_get(client); | ||
1033 | skip = true; | 1045 | skip = true; |
1034 | } else { | 1046 | } else { |
1035 | /* We could be called twice within the same generation. */ | 1047 | /* We could be called twice within the same generation. */ |
@@ -1097,12 +1109,12 @@ static void iso_resource_work(struct work_struct *work) | |||
1097 | e = r->e_dealloc; | 1109 | e = r->e_dealloc; |
1098 | r->e_dealloc = NULL; | 1110 | r->e_dealloc = NULL; |
1099 | } | 1111 | } |
1100 | e->resource.handle = r->resource.handle; | 1112 | e->iso_resource.handle = r->resource.handle; |
1101 | e->resource.channel = channel; | 1113 | e->iso_resource.channel = channel; |
1102 | e->resource.bandwidth = bandwidth; | 1114 | e->iso_resource.bandwidth = bandwidth; |
1103 | 1115 | ||
1104 | queue_event(client, &e->event, | 1116 | queue_event(client, &e->event, |
1105 | &e->resource, sizeof(e->resource), NULL, 0); | 1117 | &e->iso_resource, sizeof(e->iso_resource), NULL, 0); |
1106 | 1118 | ||
1107 | if (free) { | 1119 | if (free) { |
1108 | cancel_delayed_work(&r->work); | 1120 | cancel_delayed_work(&r->work); |
@@ -1114,13 +1126,6 @@ static void iso_resource_work(struct work_struct *work) | |||
1114 | client_put(client); | 1126 | client_put(client); |
1115 | } | 1127 | } |
1116 | 1128 | ||
1117 | static void schedule_iso_resource(struct iso_resource *r) | ||
1118 | { | ||
1119 | client_get(r->client); | ||
1120 | if (!schedule_delayed_work(&r->work, 0)) | ||
1121 | client_put(r->client); | ||
1122 | } | ||
1123 | |||
1124 | static void release_iso_resource(struct client *client, | 1129 | static void release_iso_resource(struct client *client, |
1125 | struct client_resource *resource) | 1130 | struct client_resource *resource) |
1126 | { | 1131 | { |
@@ -1129,7 +1134,7 @@ static void release_iso_resource(struct client *client, | |||
1129 | 1134 | ||
1130 | spin_lock_irq(&client->lock); | 1135 | spin_lock_irq(&client->lock); |
1131 | r->todo = ISO_RES_DEALLOC; | 1136 | r->todo = ISO_RES_DEALLOC; |
1132 | schedule_iso_resource(r); | 1137 | schedule_iso_resource(r, 0); |
1133 | spin_unlock_irq(&client->lock); | 1138 | spin_unlock_irq(&client->lock); |
1134 | } | 1139 | } |
1135 | 1140 | ||
@@ -1162,10 +1167,10 @@ static int init_iso_resource(struct client *client, | |||
1162 | r->e_alloc = e1; | 1167 | r->e_alloc = e1; |
1163 | r->e_dealloc = e2; | 1168 | r->e_dealloc = e2; |
1164 | 1169 | ||
1165 | e1->resource.closure = request->closure; | 1170 | e1->iso_resource.closure = request->closure; |
1166 | e1->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED; | 1171 | e1->iso_resource.type = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED; |
1167 | e2->resource.closure = request->closure; | 1172 | e2->iso_resource.closure = request->closure; |
1168 | e2->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED; | 1173 | e2->iso_resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED; |
1169 | 1174 | ||
1170 | if (todo == ISO_RES_ALLOC) { | 1175 | if (todo == ISO_RES_ALLOC) { |
1171 | r->resource.release = release_iso_resource; | 1176 | r->resource.release = release_iso_resource; |
@@ -1175,7 +1180,7 @@ static int init_iso_resource(struct client *client, | |||
1175 | } else { | 1180 | } else { |
1176 | r->resource.release = NULL; | 1181 | r->resource.release = NULL; |
1177 | r->resource.handle = -1; | 1182 | r->resource.handle = -1; |
1178 | schedule_iso_resource(r); | 1183 | schedule_iso_resource(r, 0); |
1179 | } | 1184 | } |
1180 | request->handle = r->resource.handle; | 1185 | request->handle = r->resource.handle; |
1181 | 1186 | ||
@@ -1295,7 +1300,23 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { | |||
1295 | static int dispatch_ioctl(struct client *client, | 1300 | static int dispatch_ioctl(struct client *client, |
1296 | unsigned int cmd, void __user *arg) | 1301 | unsigned int cmd, void __user *arg) |
1297 | { | 1302 | { |
1298 | char buffer[256]; | 1303 | char buffer[sizeof(union { |
1304 | struct fw_cdev_get_info _00; | ||
1305 | struct fw_cdev_send_request _01; | ||
1306 | struct fw_cdev_allocate _02; | ||
1307 | struct fw_cdev_deallocate _03; | ||
1308 | struct fw_cdev_send_response _04; | ||
1309 | struct fw_cdev_initiate_bus_reset _05; | ||
1310 | struct fw_cdev_add_descriptor _06; | ||
1311 | struct fw_cdev_remove_descriptor _07; | ||
1312 | struct fw_cdev_create_iso_context _08; | ||
1313 | struct fw_cdev_queue_iso _09; | ||
1314 | struct fw_cdev_start_iso _0a; | ||
1315 | struct fw_cdev_stop_iso _0b; | ||
1316 | struct fw_cdev_get_cycle_timer _0c; | ||
1317 | struct fw_cdev_allocate_iso_resource _0d; | ||
1318 | struct fw_cdev_send_stream_packet _13; | ||
1319 | })]; | ||
1299 | int ret; | 1320 | int ret; |
1300 | 1321 | ||
1301 | if (_IOC_TYPE(cmd) != '#' || | 1322 | if (_IOC_TYPE(cmd) != '#' || |
@@ -1390,10 +1411,10 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma) | |||
1390 | 1411 | ||
1391 | static int shutdown_resource(int id, void *p, void *data) | 1412 | static int shutdown_resource(int id, void *p, void *data) |
1392 | { | 1413 | { |
1393 | struct client_resource *r = p; | 1414 | struct client_resource *resource = p; |
1394 | struct client *client = data; | 1415 | struct client *client = data; |
1395 | 1416 | ||
1396 | r->release(client, r); | 1417 | resource->release(client, resource); |
1397 | client_put(client); | 1418 | client_put(client); |
1398 | 1419 | ||
1399 | return 0; | 1420 | return 0; |
@@ -1402,7 +1423,7 @@ static int shutdown_resource(int id, void *p, void *data) | |||
1402 | static int fw_device_op_release(struct inode *inode, struct file *file) | 1423 | static int fw_device_op_release(struct inode *inode, struct file *file) |
1403 | { | 1424 | { |
1404 | struct client *client = file->private_data; | 1425 | struct client *client = file->private_data; |
1405 | struct event *e, *next_e; | 1426 | struct event *event, *next_event; |
1406 | 1427 | ||
1407 | mutex_lock(&client->device->client_list_mutex); | 1428 | mutex_lock(&client->device->client_list_mutex); |
1408 | list_del(&client->link); | 1429 | list_del(&client->link); |
@@ -1423,8 +1444,8 @@ static int fw_device_op_release(struct inode *inode, struct file *file) | |||
1423 | idr_remove_all(&client->resource_idr); | 1444 | idr_remove_all(&client->resource_idr); |
1424 | idr_destroy(&client->resource_idr); | 1445 | idr_destroy(&client->resource_idr); |
1425 | 1446 | ||
1426 | list_for_each_entry_safe(e, next_e, &client->event_list, link) | 1447 | list_for_each_entry_safe(event, next_event, &client->event_list, link) |
1427 | kfree(e); | 1448 | kfree(event); |
1428 | 1449 | ||
1429 | client_put(client); | 1450 | client_put(client); |
1430 | 1451 | ||
diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c index fddf2b358936..9a5f38c80b0e 100644 --- a/drivers/firewire/core-topology.c +++ b/drivers/firewire/core-topology.c | |||
@@ -28,9 +28,9 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/string.h> | ||
32 | 31 | ||
33 | #include <asm/atomic.h> | 32 | #include <asm/atomic.h> |
33 | #include <asm/byteorder.h> | ||
34 | #include <asm/system.h> | 34 | #include <asm/system.h> |
35 | 35 | ||
36 | #include "core.h" | 36 | #include "core.h" |
@@ -510,13 +510,16 @@ static void update_tree(struct fw_card *card, struct fw_node *root) | |||
510 | static void update_topology_map(struct fw_card *card, | 510 | static void update_topology_map(struct fw_card *card, |
511 | u32 *self_ids, int self_id_count) | 511 | u32 *self_ids, int self_id_count) |
512 | { | 512 | { |
513 | int node_count; | 513 | int node_count = (card->root_node->node_id & 0x3f) + 1; |
514 | __be32 *map = card->topology_map; | ||
515 | |||
516 | *map++ = cpu_to_be32((self_id_count + 2) << 16); | ||
517 | *map++ = cpu_to_be32(be32_to_cpu(card->topology_map[1]) + 1); | ||
518 | *map++ = cpu_to_be32((node_count << 16) | self_id_count); | ||
519 | |||
520 | while (self_id_count--) | ||
521 | *map++ = cpu_to_be32p(self_ids++); | ||
514 | 522 | ||
515 | card->topology_map[1]++; | ||
516 | node_count = (card->root_node->node_id & 0x3f) + 1; | ||
517 | card->topology_map[2] = (node_count << 16) | self_id_count; | ||
518 | card->topology_map[0] = (self_id_count + 2) << 16; | ||
519 | memcpy(&card->topology_map[3], self_ids, self_id_count * 4); | ||
520 | fw_compute_block_crc(card->topology_map); | 523 | fw_compute_block_crc(card->topology_map); |
521 | } | 524 | } |
522 | 525 | ||
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index da628c72a462..842739df23e2 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -218,12 +218,15 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, | |||
218 | packet->header_length = 16; | 218 | packet->header_length = 16; |
219 | packet->payload_length = 0; | 219 | packet->payload_length = 0; |
220 | break; | 220 | break; |
221 | |||
222 | default: | ||
223 | WARN(1, KERN_ERR "wrong tcode %d", tcode); | ||
221 | } | 224 | } |
222 | common: | 225 | common: |
223 | packet->speed = speed; | 226 | packet->speed = speed; |
224 | packet->generation = generation; | 227 | packet->generation = generation; |
225 | packet->ack = 0; | 228 | packet->ack = 0; |
226 | packet->payload_bus = 0; | 229 | packet->payload_mapped = false; |
227 | } | 230 | } |
228 | 231 | ||
229 | /** | 232 | /** |
@@ -595,11 +598,10 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header, | |||
595 | break; | 598 | break; |
596 | 599 | ||
597 | default: | 600 | default: |
598 | BUG(); | 601 | WARN(1, KERN_ERR "wrong tcode %d", tcode); |
599 | return; | ||
600 | } | 602 | } |
601 | 603 | ||
602 | response->payload_bus = 0; | 604 | response->payload_mapped = false; |
603 | } | 605 | } |
604 | EXPORT_SYMBOL(fw_fill_response); | 606 | EXPORT_SYMBOL(fw_fill_response); |
605 | 607 | ||
@@ -810,8 +812,7 @@ static void handle_topology_map(struct fw_card *card, struct fw_request *request | |||
810 | int speed, unsigned long long offset, | 812 | int speed, unsigned long long offset, |
811 | void *payload, size_t length, void *callback_data) | 813 | void *payload, size_t length, void *callback_data) |
812 | { | 814 | { |
813 | int i, start, end; | 815 | int start; |
814 | __be32 *map; | ||
815 | 816 | ||
816 | if (!TCODE_IS_READ_REQUEST(tcode)) { | 817 | if (!TCODE_IS_READ_REQUEST(tcode)) { |
817 | fw_send_response(card, request, RCODE_TYPE_ERROR); | 818 | fw_send_response(card, request, RCODE_TYPE_ERROR); |
@@ -824,11 +825,7 @@ static void handle_topology_map(struct fw_card *card, struct fw_request *request | |||
824 | } | 825 | } |
825 | 826 | ||
826 | start = (offset - topology_map_region.start) / 4; | 827 | start = (offset - topology_map_region.start) / 4; |
827 | end = start + length / 4; | 828 | memcpy(payload, &card->topology_map[start], length); |
828 | map = payload; | ||
829 | |||
830 | for (i = 0; i < length / 4; i++) | ||
831 | map[i] = cpu_to_be32(card->topology_map[start + i]); | ||
832 | 829 | ||
833 | fw_send_response(card, request, RCODE_COMPLETE); | 830 | fw_send_response(card, request, RCODE_COMPLETE); |
834 | } | 831 | } |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index 7ff6e7585152..ed3b1a765c00 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
@@ -40,7 +40,8 @@ struct fw_card_driver { | |||
40 | * enable the PHY or set the link_on bit and initiate a bus | 40 | * enable the PHY or set the link_on bit and initiate a bus |
41 | * reset. | 41 | * reset. |
42 | */ | 42 | */ |
43 | int (*enable)(struct fw_card *card, u32 *config_rom, size_t length); | 43 | int (*enable)(struct fw_card *card, |
44 | const __be32 *config_rom, size_t length); | ||
44 | 45 | ||
45 | int (*update_phy_reg)(struct fw_card *card, int address, | 46 | int (*update_phy_reg)(struct fw_card *card, int address, |
46 | int clear_bits, int set_bits); | 47 | int clear_bits, int set_bits); |
@@ -48,10 +49,10 @@ struct fw_card_driver { | |||
48 | /* | 49 | /* |
49 | * Update the config rom for an enabled card. This function | 50 | * Update the config rom for an enabled card. This function |
50 | * should change the config rom that is presented on the bus | 51 | * should change the config rom that is presented on the bus |
51 | * an initiate a bus reset. | 52 | * and initiate a bus reset. |
52 | */ | 53 | */ |
53 | int (*set_config_rom)(struct fw_card *card, | 54 | int (*set_config_rom)(struct fw_card *card, |
54 | u32 *config_rom, size_t length); | 55 | const __be32 *config_rom, size_t length); |
55 | 56 | ||
56 | void (*send_request)(struct fw_card *card, struct fw_packet *packet); | 57 | void (*send_request)(struct fw_card *card, struct fw_packet *packet); |
57 | void (*send_response)(struct fw_card *card, struct fw_packet *packet); | 58 | void (*send_response)(struct fw_card *card, struct fw_packet *packet); |
@@ -93,7 +94,7 @@ int fw_card_add(struct fw_card *card, | |||
93 | u32 max_receive, u32 link_speed, u64 guid); | 94 | u32 max_receive, u32 link_speed, u64 guid); |
94 | void fw_core_remove_card(struct fw_card *card); | 95 | void fw_core_remove_card(struct fw_card *card); |
95 | int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset); | 96 | int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset); |
96 | int fw_compute_block_crc(u32 *block); | 97 | int fw_compute_block_crc(__be32 *block); |
97 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); | 98 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); |
98 | 99 | ||
99 | static inline struct fw_card *fw_card_get(struct fw_card *card) | 100 | static inline struct fw_card *fw_card_get(struct fw_card *card) |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 94260aa76aa3..ae4556f0c0c1 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -205,7 +205,7 @@ struct fw_ohci { | |||
205 | dma_addr_t config_rom_bus; | 205 | dma_addr_t config_rom_bus; |
206 | __be32 *next_config_rom; | 206 | __be32 *next_config_rom; |
207 | dma_addr_t next_config_rom_bus; | 207 | dma_addr_t next_config_rom_bus; |
208 | u32 next_header; | 208 | __be32 next_header; |
209 | 209 | ||
210 | struct ar_context ar_request_ctx; | 210 | struct ar_context ar_request_ctx; |
211 | struct ar_context ar_response_ctx; | 211 | struct ar_context ar_response_ctx; |
@@ -997,7 +997,8 @@ static int at_context_queue_packet(struct context *ctx, | |||
997 | packet->ack = RCODE_SEND_ERROR; | 997 | packet->ack = RCODE_SEND_ERROR; |
998 | return -1; | 998 | return -1; |
999 | } | 999 | } |
1000 | packet->payload_bus = payload_bus; | 1000 | packet->payload_bus = payload_bus; |
1001 | packet->payload_mapped = true; | ||
1001 | 1002 | ||
1002 | d[2].req_count = cpu_to_le16(packet->payload_length); | 1003 | d[2].req_count = cpu_to_le16(packet->payload_length); |
1003 | d[2].data_address = cpu_to_le32(payload_bus); | 1004 | d[2].data_address = cpu_to_le32(payload_bus); |
@@ -1025,7 +1026,7 @@ static int at_context_queue_packet(struct context *ctx, | |||
1025 | */ | 1026 | */ |
1026 | if (ohci->generation != packet->generation || | 1027 | if (ohci->generation != packet->generation || |
1027 | reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) { | 1028 | reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) { |
1028 | if (packet->payload_length > 0) | 1029 | if (packet->payload_mapped) |
1029 | dma_unmap_single(ohci->card.device, payload_bus, | 1030 | dma_unmap_single(ohci->card.device, payload_bus, |
1030 | packet->payload_length, DMA_TO_DEVICE); | 1031 | packet->payload_length, DMA_TO_DEVICE); |
1031 | packet->ack = RCODE_GENERATION; | 1032 | packet->ack = RCODE_GENERATION; |
@@ -1061,7 +1062,7 @@ static int handle_at_packet(struct context *context, | |||
1061 | /* This packet was cancelled, just continue. */ | 1062 | /* This packet was cancelled, just continue. */ |
1062 | return 1; | 1063 | return 1; |
1063 | 1064 | ||
1064 | if (packet->payload_bus) | 1065 | if (packet->payload_mapped) |
1065 | dma_unmap_single(ohci->card.device, packet->payload_bus, | 1066 | dma_unmap_single(ohci->card.device, packet->payload_bus, |
1066 | packet->payload_length, DMA_TO_DEVICE); | 1067 | packet->payload_length, DMA_TO_DEVICE); |
1067 | 1068 | ||
@@ -1357,8 +1358,9 @@ static void bus_reset_tasklet(unsigned long data) | |||
1357 | */ | 1358 | */ |
1358 | reg_write(ohci, OHCI1394_BusOptions, | 1359 | reg_write(ohci, OHCI1394_BusOptions, |
1359 | be32_to_cpu(ohci->config_rom[2])); | 1360 | be32_to_cpu(ohci->config_rom[2])); |
1360 | ohci->config_rom[0] = cpu_to_be32(ohci->next_header); | 1361 | ohci->config_rom[0] = ohci->next_header; |
1361 | reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header); | 1362 | reg_write(ohci, OHCI1394_ConfigROMhdr, |
1363 | be32_to_cpu(ohci->next_header)); | ||
1362 | } | 1364 | } |
1363 | 1365 | ||
1364 | #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA | 1366 | #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA |
@@ -1477,7 +1479,17 @@ static int software_reset(struct fw_ohci *ohci) | |||
1477 | return -EBUSY; | 1479 | return -EBUSY; |
1478 | } | 1480 | } |
1479 | 1481 | ||
1480 | static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | 1482 | static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length) |
1483 | { | ||
1484 | size_t size = length * 4; | ||
1485 | |||
1486 | memcpy(dest, src, size); | ||
1487 | if (size < CONFIG_ROM_SIZE) | ||
1488 | memset(&dest[length], 0, CONFIG_ROM_SIZE - size); | ||
1489 | } | ||
1490 | |||
1491 | static int ohci_enable(struct fw_card *card, | ||
1492 | const __be32 *config_rom, size_t length) | ||
1481 | { | 1493 | { |
1482 | struct fw_ohci *ohci = fw_ohci(card); | 1494 | struct fw_ohci *ohci = fw_ohci(card); |
1483 | struct pci_dev *dev = to_pci_dev(card->device); | 1495 | struct pci_dev *dev = to_pci_dev(card->device); |
@@ -1579,8 +1591,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1579 | if (ohci->next_config_rom == NULL) | 1591 | if (ohci->next_config_rom == NULL) |
1580 | return -ENOMEM; | 1592 | return -ENOMEM; |
1581 | 1593 | ||
1582 | memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE); | 1594 | copy_config_rom(ohci->next_config_rom, config_rom, length); |
1583 | fw_memcpy_to_be32(ohci->next_config_rom, config_rom, length * 4); | ||
1584 | } else { | 1595 | } else { |
1585 | /* | 1596 | /* |
1586 | * In the suspend case, config_rom is NULL, which | 1597 | * In the suspend case, config_rom is NULL, which |
@@ -1590,7 +1601,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1590 | ohci->next_config_rom_bus = ohci->config_rom_bus; | 1601 | ohci->next_config_rom_bus = ohci->config_rom_bus; |
1591 | } | 1602 | } |
1592 | 1603 | ||
1593 | ohci->next_header = be32_to_cpu(ohci->next_config_rom[0]); | 1604 | ohci->next_header = ohci->next_config_rom[0]; |
1594 | ohci->next_config_rom[0] = 0; | 1605 | ohci->next_config_rom[0] = 0; |
1595 | reg_write(ohci, OHCI1394_ConfigROMhdr, 0); | 1606 | reg_write(ohci, OHCI1394_ConfigROMhdr, 0); |
1596 | reg_write(ohci, OHCI1394_BusOptions, | 1607 | reg_write(ohci, OHCI1394_BusOptions, |
@@ -1624,7 +1635,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1624 | } | 1635 | } |
1625 | 1636 | ||
1626 | static int ohci_set_config_rom(struct fw_card *card, | 1637 | static int ohci_set_config_rom(struct fw_card *card, |
1627 | u32 *config_rom, size_t length) | 1638 | const __be32 *config_rom, size_t length) |
1628 | { | 1639 | { |
1629 | struct fw_ohci *ohci; | 1640 | struct fw_ohci *ohci; |
1630 | unsigned long flags; | 1641 | unsigned long flags; |
@@ -1673,9 +1684,7 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
1673 | ohci->next_config_rom = next_config_rom; | 1684 | ohci->next_config_rom = next_config_rom; |
1674 | ohci->next_config_rom_bus = next_config_rom_bus; | 1685 | ohci->next_config_rom_bus = next_config_rom_bus; |
1675 | 1686 | ||
1676 | memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE); | 1687 | copy_config_rom(ohci->next_config_rom, config_rom, length); |
1677 | fw_memcpy_to_be32(ohci->next_config_rom, config_rom, | ||
1678 | length * 4); | ||
1679 | 1688 | ||
1680 | ohci->next_header = config_rom[0]; | 1689 | ohci->next_header = config_rom[0]; |
1681 | ohci->next_config_rom[0] = 0; | 1690 | ohci->next_config_rom[0] = 0; |
@@ -1729,7 +1738,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet) | |||
1729 | if (packet->ack != 0) | 1738 | if (packet->ack != 0) |
1730 | goto out; | 1739 | goto out; |
1731 | 1740 | ||
1732 | if (packet->payload_bus) | 1741 | if (packet->payload_mapped) |
1733 | dma_unmap_single(ohci->card.device, packet->payload_bus, | 1742 | dma_unmap_single(ohci->card.device, packet->payload_bus, |
1734 | packet->payload_length, DMA_TO_DEVICE); | 1743 | packet->payload_length, DMA_TO_DEVICE); |
1735 | 1744 | ||
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 98dbbda3ad41..d485cdd8cbac 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -820,20 +820,25 @@ static void sbp2_release_target(struct kref *kref) | |||
820 | fw_device_put(device); | 820 | fw_device_put(device); |
821 | } | 821 | } |
822 | 822 | ||
823 | static struct workqueue_struct *sbp2_wq; | 823 | static void sbp2_target_get(struct sbp2_target *tgt) |
824 | { | ||
825 | kref_get(&tgt->kref); | ||
826 | } | ||
824 | 827 | ||
825 | static void sbp2_target_put(struct sbp2_target *tgt) | 828 | static void sbp2_target_put(struct sbp2_target *tgt) |
826 | { | 829 | { |
827 | kref_put(&tgt->kref, sbp2_release_target); | 830 | kref_put(&tgt->kref, sbp2_release_target); |
828 | } | 831 | } |
829 | 832 | ||
833 | static struct workqueue_struct *sbp2_wq; | ||
834 | |||
830 | /* | 835 | /* |
831 | * Always get the target's kref when scheduling work on one its units. | 836 | * Always get the target's kref when scheduling work on one its units. |
832 | * Each workqueue job is responsible to call sbp2_target_put() upon return. | 837 | * Each workqueue job is responsible to call sbp2_target_put() upon return. |
833 | */ | 838 | */ |
834 | static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) | 839 | static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) |
835 | { | 840 | { |
836 | kref_get(&lu->tgt->kref); | 841 | sbp2_target_get(lu->tgt); |
837 | if (!queue_delayed_work(sbp2_wq, &lu->work, delay)) | 842 | if (!queue_delayed_work(sbp2_wq, &lu->work, delay)) |
838 | sbp2_target_put(lu->tgt); | 843 | sbp2_target_put(lu->tgt); |
839 | } | 844 | } |