Commit 837b41b5de356aa67abb2cadb5eef3efc7776f91
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: state userland requirements in Kconfig help firewire: avoid memleak after phy config transmit failure firewire: fw-ohci: TSB43AB22/A dualbuffer workaround firewire: queue the right number of data firewire: warn on unfinished transactions during card removal firewire: small fw_fill_request cleanup firewire: fully initialize fw_transaction before marking it pending firewire: fix race of bus reset with request transmission
Showing 7 changed files Side-by-side Diff
drivers/firewire/Kconfig
... | ... | @@ -16,8 +16,13 @@ |
16 | 16 | enable the new stack. |
17 | 17 | |
18 | 18 | To compile this driver as a module, say M here: the module will be |
19 | - called firewire-core. It functionally replaces ieee1394, raw1394, | |
20 | - and video1394. | |
19 | + called firewire-core. | |
20 | + | |
21 | + This module functionally replaces ieee1394, raw1394, and video1394. | |
22 | + To access it from application programs, you generally need at least | |
23 | + libraw1394 version 2. IIDC/DCAM applications also need libdc1394 | |
24 | + version 2. No libraries are required to access storage devices | |
25 | + through the firewire-sbp2 driver. | |
21 | 26 | |
22 | 27 | config FIREWIRE_OHCI |
23 | 28 | tristate "OHCI-1394 controllers" |
drivers/firewire/fw-card.c
... | ... | @@ -539,7 +539,7 @@ |
539 | 539 | wait_for_completion(&card->done); |
540 | 540 | |
541 | 541 | cancel_delayed_work_sync(&card->work); |
542 | - fw_flush_transactions(card); | |
542 | + WARN_ON(!list_empty(&card->transaction_list)); | |
543 | 543 | del_timer_sync(&card->flush_timer); |
544 | 544 | } |
545 | 545 | EXPORT_SYMBOL(fw_core_remove_card); |
drivers/firewire/fw-cdev.c
... | ... | @@ -382,9 +382,9 @@ |
382 | 382 | |
383 | 383 | response->response.type = FW_CDEV_EVENT_RESPONSE; |
384 | 384 | response->response.rcode = rcode; |
385 | - queue_event(client, &response->event, | |
386 | - &response->response, sizeof(response->response), | |
387 | - response->response.data, response->response.length); | |
385 | + queue_event(client, &response->event, &response->response, | |
386 | + sizeof(response->response) + response->response.length, | |
387 | + NULL, 0); | |
388 | 388 | } |
389 | 389 | |
390 | 390 | static int ioctl_send_request(struct client *client, void *buffer) |
drivers/firewire/fw-ohci.c
... | ... | @@ -171,7 +171,6 @@ |
171 | 171 | struct fw_ohci { |
172 | 172 | struct fw_card card; |
173 | 173 | |
174 | - u32 version; | |
175 | 174 | __iomem char *registers; |
176 | 175 | dma_addr_t self_id_bus; |
177 | 176 | __le32 *self_id_cpu; |
... | ... | @@ -180,6 +179,8 @@ |
180 | 179 | int generation; |
181 | 180 | int request_generation; /* for timestamping incoming requests */ |
182 | 181 | u32 bus_seconds; |
182 | + | |
183 | + bool use_dualbuffer; | |
183 | 184 | bool old_uninorth; |
184 | 185 | bool bus_reset_packet_quirk; |
185 | 186 | |
... | ... | @@ -1885,7 +1886,7 @@ |
1885 | 1886 | } else { |
1886 | 1887 | mask = &ohci->ir_context_mask; |
1887 | 1888 | list = ohci->ir_context_list; |
1888 | - if (ohci->version >= OHCI_VERSION_1_1) | |
1889 | + if (ohci->use_dualbuffer) | |
1889 | 1890 | callback = handle_ir_dualbuffer_packet; |
1890 | 1891 | else |
1891 | 1892 | callback = handle_ir_packet_per_buffer; |
... | ... | @@ -1949,7 +1950,7 @@ |
1949 | 1950 | } else { |
1950 | 1951 | index = ctx - ohci->ir_context_list; |
1951 | 1952 | control = IR_CONTEXT_ISOCH_HEADER; |
1952 | - if (ohci->version >= OHCI_VERSION_1_1) | |
1953 | + if (ohci->use_dualbuffer) | |
1953 | 1954 | control |= IR_CONTEXT_DUAL_BUFFER_MODE; |
1954 | 1955 | match = (tags << 28) | (sync << 8) | ctx->base.channel; |
1955 | 1956 | if (cycle >= 0) { |
... | ... | @@ -2279,7 +2280,7 @@ |
2279 | 2280 | spin_lock_irqsave(&ctx->context.ohci->lock, flags); |
2280 | 2281 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) |
2281 | 2282 | retval = ohci_queue_iso_transmit(base, packet, buffer, payload); |
2282 | - else if (ctx->context.ohci->version >= OHCI_VERSION_1_1) | |
2283 | + else if (ctx->context.ohci->use_dualbuffer) | |
2283 | 2284 | retval = ohci_queue_iso_receive_dualbuffer(base, packet, |
2284 | 2285 | buffer, payload); |
2285 | 2286 | else |
... | ... | @@ -2341,7 +2342,7 @@ |
2341 | 2342 | pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) |
2342 | 2343 | { |
2343 | 2344 | struct fw_ohci *ohci; |
2344 | - u32 bus_options, max_receive, link_speed; | |
2345 | + u32 bus_options, max_receive, link_speed, version; | |
2345 | 2346 | u64 guid; |
2346 | 2347 | int err; |
2347 | 2348 | size_t size; |
... | ... | @@ -2366,12 +2367,6 @@ |
2366 | 2367 | pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0); |
2367 | 2368 | pci_set_drvdata(dev, ohci); |
2368 | 2369 | |
2369 | -#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | |
2370 | - ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | |
2371 | - dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | |
2372 | -#endif | |
2373 | - ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | |
2374 | - | |
2375 | 2370 | spin_lock_init(&ohci->lock); |
2376 | 2371 | |
2377 | 2372 | tasklet_init(&ohci->bus_reset_tasklet, |
... | ... | @@ -2390,6 +2385,23 @@ |
2390 | 2385 | goto fail_iomem; |
2391 | 2386 | } |
2392 | 2387 | |
2388 | + version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | |
2389 | + ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; | |
2390 | + | |
2391 | +/* x86-32 currently doesn't use highmem for dma_alloc_coherent */ | |
2392 | +#if !defined(CONFIG_X86_32) | |
2393 | + /* dual-buffer mode is broken with descriptor addresses above 2G */ | |
2394 | + if (dev->vendor == PCI_VENDOR_ID_TI && | |
2395 | + dev->device == PCI_DEVICE_ID_TI_TSB43AB22) | |
2396 | + ohci->use_dualbuffer = false; | |
2397 | +#endif | |
2398 | + | |
2399 | +#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | |
2400 | + ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | |
2401 | + dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | |
2402 | +#endif | |
2403 | + ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | |
2404 | + | |
2393 | 2405 | ar_context_init(&ohci->ar_request_ctx, ohci, |
2394 | 2406 | OHCI1394_AsReqRcvContextControlSet); |
2395 | 2407 | |
2396 | 2408 | |
... | ... | @@ -2441,9 +2453,8 @@ |
2441 | 2453 | if (err < 0) |
2442 | 2454 | goto fail_self_id; |
2443 | 2455 | |
2444 | - ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | |
2445 | 2456 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", |
2446 | - dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff); | |
2457 | + dev->dev.bus_id, version >> 16, version & 0xff); | |
2447 | 2458 | return 0; |
2448 | 2459 | |
2449 | 2460 | fail_self_id: |
drivers/firewire/fw-topology.c
drivers/firewire/fw-transaction.c
... | ... | @@ -22,6 +22,7 @@ |
22 | 22 | #include <linux/kernel.h> |
23 | 23 | #include <linux/kref.h> |
24 | 24 | #include <linux/module.h> |
25 | +#include <linux/mutex.h> | |
25 | 26 | #include <linux/init.h> |
26 | 27 | #include <linux/interrupt.h> |
27 | 28 | #include <linux/pci.h> |
... | ... | @@ -151,7 +152,7 @@ |
151 | 152 | |
152 | 153 | static void |
153 | 154 | fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, |
154 | - int node_id, int source_id, int generation, int speed, | |
155 | + int destination_id, int source_id, int generation, int speed, | |
155 | 156 | unsigned long long offset, void *payload, size_t length) |
156 | 157 | { |
157 | 158 | int ext_tcode; |
... | ... | @@ -166,7 +167,7 @@ |
166 | 167 | HEADER_RETRY(RETRY_X) | |
167 | 168 | HEADER_TLABEL(tlabel) | |
168 | 169 | HEADER_TCODE(tcode) | |
169 | - HEADER_DESTINATION(node_id); | |
170 | + HEADER_DESTINATION(destination_id); | |
170 | 171 | packet->header[1] = |
171 | 172 | HEADER_OFFSET_HIGH(offset >> 32) | HEADER_SOURCE(source_id); |
172 | 173 | packet->header[2] = |
... | ... | @@ -252,7 +253,7 @@ |
252 | 253 | fw_transaction_callback_t callback, void *callback_data) |
253 | 254 | { |
254 | 255 | unsigned long flags; |
255 | - int tlabel, source; | |
256 | + int tlabel; | |
256 | 257 | |
257 | 258 | /* |
258 | 259 | * Bump the flush timer up 100ms first of all so we |
... | ... | @@ -268,7 +269,6 @@ |
268 | 269 | |
269 | 270 | spin_lock_irqsave(&card->lock, flags); |
270 | 271 | |
271 | - source = card->node_id; | |
272 | 272 | tlabel = card->current_tlabel; |
273 | 273 | if (card->tlabel_mask & (1 << tlabel)) { |
274 | 274 | spin_unlock_irqrestore(&card->lock, flags); |
275 | 275 | |
276 | 276 | |
277 | 277 | |
278 | 278 | |
279 | 279 | |
280 | 280 | |
281 | 281 | |
282 | 282 | |
283 | 283 | |
284 | 284 | |
285 | 285 | |
... | ... | @@ -279,77 +279,58 @@ |
279 | 279 | card->current_tlabel = (card->current_tlabel + 1) & 0x1f; |
280 | 280 | card->tlabel_mask |= (1 << tlabel); |
281 | 281 | |
282 | - list_add_tail(&t->link, &card->transaction_list); | |
283 | - | |
284 | - spin_unlock_irqrestore(&card->lock, flags); | |
285 | - | |
286 | - /* Initialize rest of transaction, fill out packet and send it. */ | |
287 | 282 | t->node_id = node_id; |
288 | 283 | t->tlabel = tlabel; |
289 | 284 | t->callback = callback; |
290 | 285 | t->callback_data = callback_data; |
291 | 286 | |
292 | - fw_fill_request(&t->packet, tcode, t->tlabel, | |
293 | - node_id, source, generation, | |
294 | - speed, offset, payload, length); | |
287 | + fw_fill_request(&t->packet, tcode, t->tlabel, node_id, card->node_id, | |
288 | + generation, speed, offset, payload, length); | |
295 | 289 | t->packet.callback = transmit_complete_callback; |
296 | 290 | |
291 | + list_add_tail(&t->link, &card->transaction_list); | |
292 | + | |
293 | + spin_unlock_irqrestore(&card->lock, flags); | |
294 | + | |
297 | 295 | card->driver->send_request(card, &t->packet); |
298 | 296 | } |
299 | 297 | EXPORT_SYMBOL(fw_send_request); |
300 | 298 | |
301 | -struct fw_phy_packet { | |
302 | - struct fw_packet packet; | |
303 | - struct completion done; | |
304 | - struct kref kref; | |
305 | -}; | |
299 | +static DEFINE_MUTEX(phy_config_mutex); | |
300 | +static DECLARE_COMPLETION(phy_config_done); | |
306 | 301 | |
307 | -static void phy_packet_release(struct kref *kref) | |
308 | -{ | |
309 | - struct fw_phy_packet *p = | |
310 | - container_of(kref, struct fw_phy_packet, kref); | |
311 | - kfree(p); | |
312 | -} | |
313 | - | |
314 | 302 | static void transmit_phy_packet_callback(struct fw_packet *packet, |
315 | 303 | struct fw_card *card, int status) |
316 | 304 | { |
317 | - struct fw_phy_packet *p = | |
318 | - container_of(packet, struct fw_phy_packet, packet); | |
319 | - | |
320 | - complete(&p->done); | |
321 | - kref_put(&p->kref, phy_packet_release); | |
305 | + complete(&phy_config_done); | |
322 | 306 | } |
323 | 307 | |
308 | +static struct fw_packet phy_config_packet = { | |
309 | + .header_length = 8, | |
310 | + .payload_length = 0, | |
311 | + .speed = SCODE_100, | |
312 | + .callback = transmit_phy_packet_callback, | |
313 | +}; | |
314 | + | |
324 | 315 | void fw_send_phy_config(struct fw_card *card, |
325 | 316 | int node_id, int generation, int gap_count) |
326 | 317 | { |
327 | - struct fw_phy_packet *p; | |
328 | 318 | long timeout = DIV_ROUND_UP(HZ, 10); |
329 | 319 | u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | |
330 | 320 | PHY_CONFIG_ROOT_ID(node_id) | |
331 | 321 | PHY_CONFIG_GAP_COUNT(gap_count); |
332 | 322 | |
333 | - p = kmalloc(sizeof(*p), GFP_KERNEL); | |
334 | - if (p == NULL) | |
335 | - return; | |
323 | + mutex_lock(&phy_config_mutex); | |
336 | 324 | |
337 | - p->packet.header[0] = data; | |
338 | - p->packet.header[1] = ~data; | |
339 | - p->packet.header_length = 8; | |
340 | - p->packet.payload_length = 0; | |
341 | - p->packet.speed = SCODE_100; | |
342 | - p->packet.generation = generation; | |
343 | - p->packet.callback = transmit_phy_packet_callback; | |
344 | - init_completion(&p->done); | |
345 | - kref_set(&p->kref, 2); | |
325 | + phy_config_packet.header[0] = data; | |
326 | + phy_config_packet.header[1] = ~data; | |
327 | + phy_config_packet.generation = generation; | |
328 | + INIT_COMPLETION(phy_config_done); | |
346 | 329 | |
347 | - card->driver->send_request(card, &p->packet); | |
348 | - timeout = wait_for_completion_timeout(&p->done, timeout); | |
349 | - kref_put(&p->kref, phy_packet_release); | |
330 | + card->driver->send_request(card, &phy_config_packet); | |
331 | + wait_for_completion_timeout(&phy_config_done, timeout); | |
350 | 332 | |
351 | - /* will leak p if the callback is never executed */ | |
352 | - WARN_ON(timeout == 0); | |
333 | + mutex_unlock(&phy_config_mutex); | |
353 | 334 | } |
354 | 335 | |
355 | 336 | void fw_flush_transactions(struct fw_card *card) |
include/linux/pci_ids.h
... | ... | @@ -748,6 +748,7 @@ |
748 | 748 | #define PCI_VENDOR_ID_TI 0x104c |
749 | 749 | #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 |
750 | 750 | #define PCI_DEVICE_ID_TI_4450 0x8011 |
751 | +#define PCI_DEVICE_ID_TI_TSB43AB22 0x8023 | |
751 | 752 | #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 |
752 | 753 | #define PCI_DEVICE_ID_TI_XX21_XX11_FM 0x8033 |
753 | 754 | #define PCI_DEVICE_ID_TI_XX21_XX11_SD 0x8034 |