diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-16 18:02:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-16 18:02:24 -0400 |
commit | 1eee21abaf54338b379b33d85b28b495292c2211 (patch) | |
tree | f51f3e270c7e075f2844a2c5e400cfc1b9481ce3 /drivers/firewire/fw-card.c | |
parent | 9d85db2244d71fa4f2f9747a090c1920f07a8b4b (diff) | |
parent | be585c07dd577faac26014db4246e6d7c7a131e7 (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:
firewire: Add more documentation to firewire-cdev.h
firewire: fix ioctl() return code
firewire: fix setting tag and sy in iso transmission
firewire: fw-sbp2: fix another small generation access bug
firewire: fw-sbp2: enforce s/g segment size limit
firewire: fw_send_request_sync()
ieee1394: survive a few seconds connection loss
ieee1394: nodemgr clean up class iterators
ieee1394: dv1394, video1394: remove unnecessary expressions
ieee1394: raw1394: make write() thread-safe
ieee1394: raw1394: narrow down the state_mutex protected region
ieee1394: raw1394: replace BKL by local mutex, make ioctl() and mmap() thread-safe
ieee1394: sbp2: enforce s/g segment size limit
ieee1394: sbp2: check for DMA mapping failures
ieee1394: sbp2: stricter dma_sync
ieee1394: Use DIV_ROUND_UP
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 |