diff options
-rw-r--r-- | drivers/firewire/core-card.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 7083bcc1b9c7..5045156c5313 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -57,6 +57,8 @@ static LIST_HEAD(descriptor_list); | |||
57 | static int descriptor_count; | 57 | static int descriptor_count; |
58 | 58 | ||
59 | static __be32 tmp_config_rom[256]; | 59 | static __be32 tmp_config_rom[256]; |
60 | /* ROM header, bus info block, root dir header, capabilities = 7 quadlets */ | ||
61 | static size_t config_rom_length = 1 + 4 + 1 + 1; | ||
60 | 62 | ||
61 | #define BIB_CRC(v) ((v) << 0) | 63 | #define BIB_CRC(v) ((v) << 0) |
62 | #define BIB_CRC_LENGTH(v) ((v) << 16) | 64 | #define BIB_CRC_LENGTH(v) ((v) << 16) |
@@ -73,7 +75,7 @@ static __be32 tmp_config_rom[256]; | |||
73 | #define BIB_CMC ((1) << 30) | 75 | #define BIB_CMC ((1) << 30) |
74 | #define BIB_IMC ((1) << 31) | 76 | #define BIB_IMC ((1) << 31) |
75 | 77 | ||
76 | static size_t generate_config_rom(struct fw_card *card, __be32 *config_rom) | 78 | static void generate_config_rom(struct fw_card *card, __be32 *config_rom) |
77 | { | 79 | { |
78 | struct fw_descriptor *desc; | 80 | struct fw_descriptor *desc; |
79 | int i, j, k, length; | 81 | int i, j, k, length; |
@@ -130,23 +132,30 @@ static size_t generate_config_rom(struct fw_card *card, __be32 *config_rom) | |||
130 | for (i = 0; i < j; i += length + 1) | 132 | for (i = 0; i < j; i += length + 1) |
131 | length = fw_compute_block_crc(config_rom + i); | 133 | length = fw_compute_block_crc(config_rom + i); |
132 | 134 | ||
133 | return j; | 135 | WARN_ON(j != config_rom_length); |
134 | } | 136 | } |
135 | 137 | ||
136 | static void update_config_roms(void) | 138 | static void update_config_roms(void) |
137 | { | 139 | { |
138 | struct fw_card *card; | 140 | struct fw_card *card; |
139 | size_t length; | ||
140 | 141 | ||
141 | list_for_each_entry (card, &card_list, link) { | 142 | list_for_each_entry (card, &card_list, link) { |
142 | length = generate_config_rom(card, tmp_config_rom); | 143 | generate_config_rom(card, tmp_config_rom); |
143 | card->driver->set_config_rom(card, tmp_config_rom, length); | 144 | card->driver->set_config_rom(card, tmp_config_rom, |
145 | config_rom_length); | ||
144 | } | 146 | } |
145 | } | 147 | } |
146 | 148 | ||
149 | static 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 | |||
147 | int fw_core_add_descriptor(struct fw_descriptor *desc) | 155 | int fw_core_add_descriptor(struct fw_descriptor *desc) |
148 | { | 156 | { |
149 | size_t i; | 157 | size_t i; |
158 | int ret; | ||
150 | 159 | ||
151 | /* | 160 | /* |
152 | * Check descriptor is valid; the length of all blocks in the | 161 | * Check descriptor is valid; the length of all blocks in the |
@@ -162,15 +171,21 @@ int fw_core_add_descriptor(struct fw_descriptor *desc) | |||
162 | 171 | ||
163 | mutex_lock(&card_mutex); | 172 | mutex_lock(&card_mutex); |
164 | 173 | ||
165 | list_add_tail(&desc->link, &descriptor_list); | 174 | if (config_rom_length + required_space(desc) > 256) { |
166 | descriptor_count++; | 175 | ret = -EBUSY; |
167 | if (desc->immediate > 0) | 176 | } else { |
177 | list_add_tail(&desc->link, &descriptor_list); | ||
178 | config_rom_length += required_space(desc); | ||
168 | descriptor_count++; | 179 | descriptor_count++; |
169 | update_config_roms(); | 180 | if (desc->immediate > 0) |
181 | descriptor_count++; | ||
182 | update_config_roms(); | ||
183 | ret = 0; | ||
184 | } | ||
170 | 185 | ||
171 | mutex_unlock(&card_mutex); | 186 | mutex_unlock(&card_mutex); |
172 | 187 | ||
173 | return 0; | 188 | return ret; |
174 | } | 189 | } |
175 | EXPORT_SYMBOL(fw_core_add_descriptor); | 190 | EXPORT_SYMBOL(fw_core_add_descriptor); |
176 | 191 | ||
@@ -179,6 +194,7 @@ void fw_core_remove_descriptor(struct fw_descriptor *desc) | |||
179 | mutex_lock(&card_mutex); | 194 | mutex_lock(&card_mutex); |
180 | 195 | ||
181 | list_del(&desc->link); | 196 | list_del(&desc->link); |
197 | config_rom_length -= required_space(desc); | ||
182 | descriptor_count--; | 198 | descriptor_count--; |
183 | if (desc->immediate > 0) | 199 | if (desc->immediate > 0) |
184 | descriptor_count--; | 200 | descriptor_count--; |
@@ -428,7 +444,6 @@ EXPORT_SYMBOL(fw_card_initialize); | |||
428 | int fw_card_add(struct fw_card *card, | 444 | int fw_card_add(struct fw_card *card, |
429 | u32 max_receive, u32 link_speed, u64 guid) | 445 | u32 max_receive, u32 link_speed, u64 guid) |
430 | { | 446 | { |
431 | size_t length; | ||
432 | int ret; | 447 | int ret; |
433 | 448 | ||
434 | card->max_receive = max_receive; | 449 | card->max_receive = max_receive; |
@@ -437,8 +452,8 @@ int fw_card_add(struct fw_card *card, | |||
437 | 452 | ||
438 | mutex_lock(&card_mutex); | 453 | mutex_lock(&card_mutex); |
439 | 454 | ||
440 | length = generate_config_rom(card, tmp_config_rom); | 455 | generate_config_rom(card, tmp_config_rom); |
441 | ret = card->driver->enable(card, tmp_config_rom, length); | 456 | ret = card->driver->enable(card, tmp_config_rom, config_rom_length); |
442 | if (ret == 0) | 457 | if (ret == 0) |
443 | list_add_tail(&card->link, &card_list); | 458 | list_add_tail(&card->link, &card_list); |
444 | 459 | ||