aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/core-card.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/core-card.c')
-rw-r--r--drivers/firewire/core-card.c104
1 files changed, 56 insertions, 48 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index e4864e894e4f..5045156c5313 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
41int fw_compute_block_crc(u32 *block) 41int 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,10 @@ static LIST_HEAD(card_list);
57static LIST_HEAD(descriptor_list); 56static LIST_HEAD(descriptor_list);
58static int descriptor_count; 57static int descriptor_count;
59 58
59static __be32 tmp_config_rom[256];
60/* ROM header, bus info block, root dir header, capabilities = 7 quadlets */
61static size_t config_rom_length = 1 + 4 + 1 + 1;
62
60#define BIB_CRC(v) ((v) << 0) 63#define BIB_CRC(v) ((v) << 0)
61#define BIB_CRC_LENGTH(v) ((v) << 16) 64#define BIB_CRC_LENGTH(v) ((v) << 16)
62#define BIB_INFO_LENGTH(v) ((v) << 24) 65#define BIB_INFO_LENGTH(v) ((v) << 24)
@@ -72,11 +75,10 @@ static int descriptor_count;
72#define BIB_CMC ((1) << 30) 75#define BIB_CMC ((1) << 30)
73#define BIB_IMC ((1) << 31) 76#define BIB_IMC ((1) << 31)
74 77
75static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length) 78static void generate_config_rom(struct fw_card *card, __be32 *config_rom)
76{ 79{
77 struct fw_descriptor *desc; 80 struct fw_descriptor *desc;
78 static u32 config_rom[256]; 81 int i, j, k, length;
79 int i, j, length;
80 82
81 /* 83 /*
82 * Initialize contents of config rom buffer. On the OHCI 84 * Initialize contents of config rom buffer. On the OHCI
@@ -87,40 +89,39 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
87 * the version stored in the OHCI registers. 89 * the version stored in the OHCI registers.
88 */ 90 */
89 91
90 memset(config_rom, 0, sizeof(config_rom)); 92 config_rom[0] = cpu_to_be32(
91 config_rom[0] = BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0); 93 BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0));
92 config_rom[1] = 0x31333934; 94 config_rom[1] = cpu_to_be32(0x31333934);
93 95 config_rom[2] = cpu_to_be32(
94 config_rom[2] =
95 BIB_LINK_SPEED(card->link_speed) | 96 BIB_LINK_SPEED(card->link_speed) |
96 BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | 97 BIB_GENERATION(card->config_rom_generation++ % 14 + 2) |
97 BIB_MAX_ROM(2) | 98 BIB_MAX_ROM(2) |
98 BIB_MAX_RECEIVE(card->max_receive) | 99 BIB_MAX_RECEIVE(card->max_receive) |
99 BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC; 100 BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC);
100 config_rom[3] = card->guid >> 32; 101 config_rom[3] = cpu_to_be32(card->guid >> 32);
101 config_rom[4] = card->guid; 102 config_rom[4] = cpu_to_be32(card->guid);
102 103
103 /* Generate root directory. */ 104 /* Generate root directory. */
104 i = 5; 105 config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */
105 config_rom[i++] = 0; 106 i = 7;
106 config_rom[i++] = 0x0c0083c0; /* node capabilities */ 107 j = 7 + descriptor_count;
107 j = i + descriptor_count;
108 108
109 /* Generate root directory entries for descriptors. */ 109 /* Generate root directory entries for descriptors. */
110 list_for_each_entry (desc, &descriptor_list, link) { 110 list_for_each_entry (desc, &descriptor_list, link) {
111 if (desc->immediate > 0) 111 if (desc->immediate > 0)
112 config_rom[i++] = desc->immediate; 112 config_rom[i++] = cpu_to_be32(desc->immediate);
113 config_rom[i] = desc->key | (j - i); 113 config_rom[i] = cpu_to_be32(desc->key | (j - i));
114 i++; 114 i++;
115 j += desc->length; 115 j += desc->length;
116 } 116 }
117 117
118 /* Update root directory length. */ 118 /* Update root directory length. */
119 config_rom[5] = (i - 5 - 1) << 16; 119 config_rom[5] = cpu_to_be32((i - 5 - 1) << 16);
120 120
121 /* End of root directory, now copy in descriptors. */ 121 /* End of root directory, now copy in descriptors. */
122 list_for_each_entry (desc, &descriptor_list, link) { 122 list_for_each_entry (desc, &descriptor_list, link) {
123 memcpy(&config_rom[i], desc->data, desc->length * 4); 123 for (k = 0; k < desc->length; k++)
124 config_rom[i + k] = cpu_to_be32(desc->data[k]);
124 i += desc->length; 125 i += desc->length;
125 } 126 }
126 127
@@ -131,26 +132,30 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
131 for (i = 0; i < j; i += length + 1) 132 for (i = 0; i < j; i += length + 1)
132 length = fw_compute_block_crc(config_rom + i); 133 length = fw_compute_block_crc(config_rom + i);
133 134
134 *config_rom_length = j; 135 WARN_ON(j != config_rom_length);
135
136 return config_rom;
137} 136}
138 137
139static void update_config_roms(void) 138static void update_config_roms(void)
140{ 139{
141 struct fw_card *card; 140 struct fw_card *card;
142 u32 *config_rom;
143 size_t length;
144 141
145 list_for_each_entry (card, &card_list, link) { 142 list_for_each_entry (card, &card_list, link) {
146 config_rom = generate_config_rom(card, &length); 143 generate_config_rom(card, tmp_config_rom);
147 card->driver->set_config_rom(card, config_rom, length); 144 card->driver->set_config_rom(card, tmp_config_rom,
145 config_rom_length);
148 } 146 }
149} 147}
150 148
149static size_t required_space(struct fw_descriptor *desc)
150{
151 /* descriptor + entry into root dir + optional immediate entry */
152 return desc->length + 1 + (desc->immediate > 0 ? 1 : 0);
153}
154
151int fw_core_add_descriptor(struct fw_descriptor *desc) 155int fw_core_add_descriptor(struct fw_descriptor *desc)
152{ 156{
153 size_t i; 157 size_t i;
158 int ret;
154 159
155 /* 160 /*
156 * Check descriptor is valid; the length of all blocks in the 161 * Check descriptor is valid; the length of all blocks in the
@@ -166,15 +171,21 @@ int fw_core_add_descriptor(struct fw_descriptor *desc)
166 171
167 mutex_lock(&card_mutex); 172 mutex_lock(&card_mutex);
168 173
169 list_add_tail(&desc->link, &descriptor_list); 174 if (config_rom_length + required_space(desc) > 256) {
170 descriptor_count++; 175 ret = -EBUSY;
171 if (desc->immediate > 0) 176 } else {
177 list_add_tail(&desc->link, &descriptor_list);
178 config_rom_length += required_space(desc);
172 descriptor_count++; 179 descriptor_count++;
173 update_config_roms(); 180 if (desc->immediate > 0)
181 descriptor_count++;
182 update_config_roms();
183 ret = 0;
184 }
174 185
175 mutex_unlock(&card_mutex); 186 mutex_unlock(&card_mutex);
176 187
177 return 0; 188 return ret;
178} 189}
179EXPORT_SYMBOL(fw_core_add_descriptor); 190EXPORT_SYMBOL(fw_core_add_descriptor);
180 191
@@ -183,6 +194,7 @@ void fw_core_remove_descriptor(struct fw_descriptor *desc)
183 mutex_lock(&card_mutex); 194 mutex_lock(&card_mutex);
184 195
185 list_del(&desc->link); 196 list_del(&desc->link);
197 config_rom_length -= required_space(desc);
186 descriptor_count--; 198 descriptor_count--;
187 if (desc->immediate > 0) 199 if (desc->immediate > 0)
188 descriptor_count--; 200 descriptor_count--;
@@ -211,11 +223,8 @@ static const char gap_count_table[] = {
211 223
212void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) 224void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
213{ 225{
214 int scheduled;
215
216 fw_card_get(card); 226 fw_card_get(card);
217 scheduled = schedule_delayed_work(&card->work, delay); 227 if (!schedule_delayed_work(&card->work, delay))
218 if (!scheduled)
219 fw_card_put(card); 228 fw_card_put(card);
220} 229}
221 230
@@ -435,8 +444,6 @@ EXPORT_SYMBOL(fw_card_initialize);
435int fw_card_add(struct fw_card *card, 444int fw_card_add(struct fw_card *card,
436 u32 max_receive, u32 link_speed, u64 guid) 445 u32 max_receive, u32 link_speed, u64 guid)
437{ 446{
438 u32 *config_rom;
439 size_t length;
440 int ret; 447 int ret;
441 448
442 card->max_receive = max_receive; 449 card->max_receive = max_receive;
@@ -445,8 +452,8 @@ int fw_card_add(struct fw_card *card,
445 452
446 mutex_lock(&card_mutex); 453 mutex_lock(&card_mutex);
447 454
448 config_rom = generate_config_rom(card, &length); 455 generate_config_rom(card, tmp_config_rom);
449 ret = card->driver->enable(card, config_rom, length); 456 ret = card->driver->enable(card, tmp_config_rom, config_rom_length);
450 if (ret == 0) 457 if (ret == 0)
451 list_add_tail(&card->link, &card_list); 458 list_add_tail(&card->link, &card_list);
452 459
@@ -465,7 +472,8 @@ EXPORT_SYMBOL(fw_card_add);
465 * shutdown still need to be provided by the card driver. 472 * shutdown still need to be provided by the card driver.
466 */ 473 */
467 474
468static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length) 475static int dummy_enable(struct fw_card *card,
476 const __be32 *config_rom, size_t length)
469{ 477{
470 BUG(); 478 BUG();
471 return -1; 479 return -1;
@@ -478,7 +486,7 @@ static int dummy_update_phy_reg(struct fw_card *card, int address,
478} 486}
479 487
480static int dummy_set_config_rom(struct fw_card *card, 488static int dummy_set_config_rom(struct fw_card *card,
481 u32 *config_rom, size_t length) 489 const __be32 *config_rom, size_t length)
482{ 490{
483 /* 491 /*
484 * We take the card out of card_list before setting the dummy 492 * We take the card out of card_list before setting the dummy