diff options
Diffstat (limited to 'drivers/firewire/fw-card.c')
-rw-r--r-- | drivers/firewire/fw-card.c | 56 |
1 files changed, 14 insertions, 42 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index bbd73a406e53..418c18f07e9d 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c | |||
@@ -189,39 +189,16 @@ static const char gap_count_table[] = { | |||
189 | 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40 | 189 | 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40 |
190 | }; | 190 | }; |
191 | 191 | ||
192 | struct bm_data { | ||
193 | struct fw_transaction t; | ||
194 | struct { | ||
195 | __be32 arg; | ||
196 | __be32 data; | ||
197 | } lock; | ||
198 | u32 old; | ||
199 | int rcode; | ||
200 | struct completion done; | ||
201 | }; | ||
202 | |||
203 | static void | ||
204 | complete_bm_lock(struct fw_card *card, int rcode, | ||
205 | void *payload, size_t length, void *data) | ||
206 | { | ||
207 | struct bm_data *bmd = data; | ||
208 | |||
209 | if (rcode == RCODE_COMPLETE) | ||
210 | bmd->old = be32_to_cpu(*(__be32 *) payload); | ||
211 | bmd->rcode = rcode; | ||
212 | complete(&bmd->done); | ||
213 | } | ||
214 | |||
215 | static void | 192 | static void |
216 | fw_card_bm_work(struct work_struct *work) | 193 | fw_card_bm_work(struct work_struct *work) |
217 | { | 194 | { |
218 | struct fw_card *card = container_of(work, struct fw_card, work.work); | 195 | struct fw_card *card = container_of(work, struct fw_card, work.work); |
219 | struct fw_device *root_device; | 196 | struct fw_device *root_device; |
220 | struct fw_node *root_node, *local_node; | 197 | struct fw_node *root_node, *local_node; |
221 | struct bm_data bmd; | ||
222 | unsigned long flags; | 198 | unsigned long flags; |
223 | int root_id, new_root_id, irm_id, gap_count, generation, grace; | 199 | int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode; |
224 | bool do_reset = false; | 200 | bool do_reset = false; |
201 | __be32 lock_data[2]; | ||
225 | 202 | ||
226 | spin_lock_irqsave(&card->lock, flags); | 203 | spin_lock_irqsave(&card->lock, flags); |
227 | local_node = card->local_node; | 204 | local_node = card->local_node; |
@@ -263,33 +240,28 @@ fw_card_bm_work(struct work_struct *work) | |||
263 | goto pick_me; | 240 | goto pick_me; |
264 | } | 241 | } |
265 | 242 | ||
266 | bmd.lock.arg = cpu_to_be32(0x3f); | 243 | lock_data[0] = cpu_to_be32(0x3f); |
267 | bmd.lock.data = cpu_to_be32(local_node->node_id); | 244 | lock_data[1] = cpu_to_be32(local_node->node_id); |
268 | 245 | ||
269 | spin_unlock_irqrestore(&card->lock, flags); | 246 | spin_unlock_irqrestore(&card->lock, flags); |
270 | 247 | ||
271 | init_completion(&bmd.done); | 248 | rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, |
272 | fw_send_request(card, &bmd.t, TCODE_LOCK_COMPARE_SWAP, | 249 | irm_id, generation, SCODE_100, |
273 | irm_id, generation, | 250 | CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, |
274 | SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, | 251 | lock_data, sizeof(lock_data)); |
275 | &bmd.lock, sizeof(bmd.lock), | ||
276 | complete_bm_lock, &bmd); | ||
277 | wait_for_completion(&bmd.done); | ||
278 | 252 | ||
279 | if (bmd.rcode == RCODE_GENERATION) { | 253 | if (rcode == RCODE_GENERATION) |
280 | /* | 254 | /* Another bus reset, BM work has been rescheduled. */ |
281 | * Another bus reset happened. Just return, | ||
282 | * the BM work has been rescheduled. | ||
283 | */ | ||
284 | goto out; | 255 | goto out; |
285 | } | ||
286 | 256 | ||
287 | if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f) | 257 | if (rcode == RCODE_COMPLETE && |
258 | lock_data[0] != cpu_to_be32(0x3f)) | ||
288 | /* Somebody else is BM, let them do the work. */ | 259 | /* Somebody else is BM, let them do the work. */ |
289 | goto out; | 260 | goto out; |
290 | 261 | ||
291 | spin_lock_irqsave(&card->lock, flags); | 262 | spin_lock_irqsave(&card->lock, flags); |
292 | if (bmd.rcode != RCODE_COMPLETE) { | 263 | |
264 | if (rcode != RCODE_COMPLETE) { | ||
293 | /* | 265 | /* |
294 | * The lock request failed, maybe the IRM | 266 | * The lock request failed, maybe the IRM |
295 | * isn't really IRM capable after all. Let's | 267 | * isn't really IRM capable after all. Let's |