firewire: core: fix iso context shutdown on card removal

If isochronous contexts existed when firewire-ohci was unloaded, the
core iso shutdown functions crashed with NULL dereferences, and buffers
etc. weren't released.

How the fix works: We first copy the card driver's iso shutdown hooks
into the dummy driver, then fw_destroy_nodes notifies upper layers of
devices going away, these should shut down (including their iso
contexts), wait_for_completion(&card->done) will be triggered after
upper layers gave up all fw_device references, after which the card
driver's shutdown proceeds.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

+11 -7
+11 -7
drivers/firewire/core-card.c
··· 461 461 462 462 463 463 /* 464 - * The next few functions implements a dummy driver that use once a 465 - * card driver shuts down an fw_card. This allows the driver to 466 - * cleanly unload, as all IO to the card will be handled by the dummy 467 - * driver instead of calling into the (possibly) unloaded module. The 468 - * dummy driver just fails all IO. 464 + * The next few functions implement a dummy driver that is used once a card 465 + * driver shuts down an fw_card. This allows the driver to cleanly unload, 466 + * as all IO to the card will be handled (and failed) by the dummy driver 467 + * instead of calling into the module. Only functions for iso context 468 + * shutdown still need to be provided by the card driver. 469 469 */ 470 470 471 471 static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length) ··· 512 512 return -ENODEV; 513 513 } 514 514 515 - static struct fw_card_driver dummy_driver = { 515 + static const struct fw_card_driver dummy_driver_template = { 516 516 .enable = dummy_enable, 517 517 .update_phy_reg = dummy_update_phy_reg, 518 518 .set_config_rom = dummy_set_config_rom, ··· 531 531 532 532 void fw_core_remove_card(struct fw_card *card) 533 533 { 534 + struct fw_card_driver dummy_driver = dummy_driver_template; 535 + 534 536 card->driver->update_phy_reg(card, 4, 535 537 PHY_LINK_ACTIVE | PHY_CONTENDER, 0); 536 538 fw_core_initiate_bus_reset(card, 1); ··· 541 539 list_del_init(&card->link); 542 540 mutex_unlock(&card_mutex); 543 541 544 - /* Set up the dummy driver. */ 542 + /* Switch off most of the card driver interface. */ 543 + dummy_driver.free_iso_context = card->driver->free_iso_context; 544 + dummy_driver.stop_iso = card->driver->stop_iso; 545 545 card->driver = &dummy_driver; 546 546 547 547 fw_destroy_nodes(card);