Loading drivers/firewire/fw-card.c +43 −18 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/errno.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/device.h> #include <linux/mutex.h> #include <linux/mutex.h> #include <linux/crc-itu-t.h> #include <linux/crc-itu-t.h> Loading Loading @@ -214,17 +215,29 @@ static void fw_card_bm_work(struct work_struct *work) fw_card_bm_work(struct work_struct *work) { { struct fw_card *card = container_of(work, struct fw_card, work.work); struct fw_card *card = container_of(work, struct fw_card, work.work); struct fw_device *root; struct fw_device *root_device; struct fw_node *root_node, *local_node; struct bm_data bmd; struct bm_data bmd; unsigned long flags; unsigned long flags; int root_id, new_root_id, irm_id, gap_count, generation, grace; int root_id, new_root_id, irm_id, gap_count, generation, grace; int do_reset = 0; int do_reset = 0; spin_lock_irqsave(&card->lock, flags); spin_lock_irqsave(&card->lock, flags); local_node = card->local_node; root_node = card->root_node; if (local_node == NULL) { spin_unlock_irqrestore(&card->lock, flags); return; } fw_node_get(local_node); fw_node_get(root_node); generation = card->generation; generation = card->generation; root = card->root_node->data; root_device = root_node->data; root_id = card->root_node->node_id; if (root_device) fw_device_get(root_device); root_id = root_node->node_id; grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); if (card->bm_generation + 1 == generation || if (card->bm_generation + 1 == generation || Loading @@ -243,14 +256,14 @@ fw_card_bm_work(struct work_struct *work) irm_id = card->irm_node->node_id; irm_id = card->irm_node->node_id; if (!card->irm_node->link_on) { if (!card->irm_node->link_on) { new_root_id = card->local_node->node_id; new_root_id = local_node->node_id; fw_notify("IRM has link off, making local node (%02x) root.\n", fw_notify("IRM has link off, making local node (%02x) root.\n", new_root_id); new_root_id); goto pick_me; goto pick_me; } } bmd.lock.arg = cpu_to_be32(0x3f); bmd.lock.arg = cpu_to_be32(0x3f); bmd.lock.data = cpu_to_be32(card->local_node->node_id); bmd.lock.data = cpu_to_be32(local_node->node_id); spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags); Loading @@ -267,12 +280,12 @@ fw_card_bm_work(struct work_struct *work) * Another bus reset happened. Just return, * Another bus reset happened. Just return, * the BM work has been rescheduled. * the BM work has been rescheduled. */ */ return; goto out; } } if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f) if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f) /* Somebody else is BM, let them do the work. */ /* Somebody else is BM, let them do the work. */ return; goto out; spin_lock_irqsave(&card->lock, flags); spin_lock_irqsave(&card->lock, flags); if (bmd.rcode != RCODE_COMPLETE) { if (bmd.rcode != RCODE_COMPLETE) { Loading @@ -282,7 +295,7 @@ fw_card_bm_work(struct work_struct *work) * do a bus reset and pick the local node as * do a bus reset and pick the local node as * root, and thus, IRM. * root, and thus, IRM. */ */ new_root_id = card->local_node->node_id; new_root_id = local_node->node_id; fw_notify("BM lock failed, making local node (%02x) root.\n", fw_notify("BM lock failed, making local node (%02x) root.\n", new_root_id); new_root_id); goto pick_me; goto pick_me; Loading @@ -295,7 +308,7 @@ fw_card_bm_work(struct work_struct *work) */ */ spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags); schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10)); schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10)); return; goto out; } } /* /* Loading @@ -305,20 +318,20 @@ fw_card_bm_work(struct work_struct *work) */ */ card->bm_generation = generation; card->bm_generation = generation; if (root == NULL) { if (root_device == NULL) { /* /* * Either link_on is false, or we failed to read the * Either link_on is false, or we failed to read the * config rom. In either case, pick another root. * config rom. In either case, pick another root. */ */ new_root_id = card->local_node->node_id; new_root_id = local_node->node_id; } else if (atomic_read(&root->state) != FW_DEVICE_RUNNING) { } else if (atomic_read(&root_device->state) != FW_DEVICE_RUNNING) { /* /* * If we haven't probed this device yet, bail out now * If we haven't probed this device yet, bail out now * and let's try again once that's done. * and let's try again once that's done. */ */ spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags); return; goto out; } else if (root->config_rom[2] & BIB_CMC) { } else if (root_device->config_rom[2] & BIB_CMC) { /* /* * FIXME: I suppose we should set the cmstr bit in the * FIXME: I suppose we should set the cmstr bit in the * STATE_CLEAR register of this node, as described in * STATE_CLEAR register of this node, as described in Loading @@ -332,7 +345,7 @@ fw_card_bm_work(struct work_struct *work) * successfully read the config rom, but it's not * successfully read the config rom, but it's not * cycle master capable. * cycle master capable. */ */ new_root_id = card->local_node->node_id; new_root_id = local_node->node_id; } } pick_me: pick_me: Loading @@ -341,8 +354,8 @@ fw_card_bm_work(struct work_struct *work) * the typically much larger 1394b beta repeater delays though. * the typically much larger 1394b beta repeater delays though. */ */ if (!card->beta_repeaters_present && if (!card->beta_repeaters_present && card->root_node->max_hops < ARRAY_SIZE(gap_count_table)) root_node->max_hops < ARRAY_SIZE(gap_count_table)) gap_count = gap_count_table[card->root_node->max_hops]; gap_count = gap_count_table[root_node->max_hops]; else else gap_count = 63; gap_count = 63; Loading @@ -364,6 +377,11 @@ fw_card_bm_work(struct work_struct *work) fw_send_phy_config(card, new_root_id, generation, gap_count); fw_send_phy_config(card, new_root_id, generation, gap_count); fw_core_initiate_bus_reset(card, 1); fw_core_initiate_bus_reset(card, 1); } } out: if (root_device) fw_device_put(root_device); fw_node_put(root_node); fw_node_put(local_node); } } static void static void Loading @@ -381,6 +399,7 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, static atomic_t index = ATOMIC_INIT(-1); static atomic_t index = ATOMIC_INIT(-1); kref_init(&card->kref); kref_init(&card->kref); atomic_set(&card->device_count, 0); card->index = atomic_inc_return(&index); card->index = atomic_inc_return(&index); card->driver = driver; card->driver = driver; card->device = device; card->device = device; Loading Loading @@ -511,8 +530,14 @@ fw_core_remove_card(struct fw_card *card) card->driver = &dummy_driver; card->driver = &dummy_driver; fw_destroy_nodes(card); fw_destroy_nodes(card); flush_scheduled_work(); /* * Wait for all device workqueue jobs to finish. Otherwise the * firewire-core module could be unloaded before the jobs ran. */ while (atomic_read(&card->device_count) > 0) msleep(100); cancel_delayed_work_sync(&card->work); fw_flush_transactions(card); fw_flush_transactions(card); del_timer_sync(&card->flush_timer); del_timer_sync(&card->flush_timer); Loading drivers/firewire/fw-device.c +6 −15 Original line number Original line Diff line number Diff line Loading @@ -150,21 +150,10 @@ struct bus_type fw_bus_type = { }; }; EXPORT_SYMBOL(fw_bus_type); EXPORT_SYMBOL(fw_bus_type); struct fw_device *fw_device_get(struct fw_device *device) { get_device(&device->device); return device; } void fw_device_put(struct fw_device *device) { put_device(&device->device); } static void fw_device_release(struct device *dev) static void fw_device_release(struct device *dev) { { struct fw_device *device = fw_device(dev); struct fw_device *device = fw_device(dev); struct fw_card *card = device->card; unsigned long flags; unsigned long flags; /* /* Loading @@ -176,9 +165,9 @@ static void fw_device_release(struct device *dev) spin_unlock_irqrestore(&device->card->lock, flags); spin_unlock_irqrestore(&device->card->lock, flags); fw_node_put(device->node); fw_node_put(device->node); fw_card_put(device->card); kfree(device->config_rom); kfree(device->config_rom); kfree(device); kfree(device); atomic_dec(&card->device_count); } } int fw_device_enable_phys_dma(struct fw_device *device) int fw_device_enable_phys_dma(struct fw_device *device) Loading Loading @@ -668,7 +657,8 @@ static void fw_device_init(struct work_struct *work) */ */ if (read_bus_info_block(device, device->generation) < 0) { if (read_bus_info_block(device, device->generation) < 0) { if (device->config_rom_retries < MAX_RETRIES) { if (device->config_rom_retries < MAX_RETRIES && atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { device->config_rom_retries++; device->config_rom_retries++; schedule_delayed_work(&device->work, RETRY_DELAY); schedule_delayed_work(&device->work, RETRY_DELAY); } else { } else { Loading Loading @@ -805,7 +795,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) */ */ device_initialize(&device->device); device_initialize(&device->device); atomic_set(&device->state, FW_DEVICE_INITIALIZING); atomic_set(&device->state, FW_DEVICE_INITIALIZING); device->card = fw_card_get(card); atomic_inc(&card->device_count); device->card = card; device->node = fw_node_get(node); device->node = fw_node_get(node); device->node_id = node->node_id; device->node_id = node->node_id; device->generation = card->generation; device->generation = card->generation; Loading drivers/firewire/fw-device.h +14 −2 Original line number Original line Diff line number Diff line Loading @@ -76,9 +76,21 @@ fw_device_is_shutdown(struct fw_device *device) return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; } } struct fw_device *fw_device_get(struct fw_device *device); static inline struct fw_device * fw_device_get(struct fw_device *device) { get_device(&device->device); return device; } static inline void fw_device_put(struct fw_device *device) { put_device(&device->device); } struct fw_device *fw_device_get_by_devt(dev_t devt); struct fw_device *fw_device_get_by_devt(dev_t devt); void fw_device_put(struct fw_device *device); int fw_device_enable_phys_dma(struct fw_device *device); int fw_device_enable_phys_dma(struct fw_device *device); void fw_device_cdev_update(struct fw_device *device); void fw_device_cdev_update(struct fw_device *device); Loading drivers/firewire/fw-sbp2.c +31 −19 Original line number Original line Diff line number Diff line Loading @@ -122,7 +122,6 @@ static const char sbp2_driver_name[] = "sbp2"; struct sbp2_logical_unit { struct sbp2_logical_unit { struct sbp2_target *tgt; struct sbp2_target *tgt; struct list_head link; struct list_head link; struct scsi_device *sdev; struct fw_address_handler address_handler; struct fw_address_handler address_handler; struct list_head orb_list; struct list_head orb_list; Loading @@ -139,6 +138,7 @@ struct sbp2_logical_unit { int generation; int generation; int retries; int retries; struct delayed_work work; struct delayed_work work; bool has_sdev; bool blocked; bool blocked; }; }; Loading Loading @@ -751,20 +751,34 @@ static void sbp2_unblock(struct sbp2_target *tgt) scsi_unblock_requests(shost); scsi_unblock_requests(shost); } } static int sbp2_lun2int(u16 lun) { struct scsi_lun eight_bytes_lun; memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); eight_bytes_lun.scsi_lun[0] = (lun >> 8) & 0xff; eight_bytes_lun.scsi_lun[1] = lun & 0xff; return scsilun_to_int(&eight_bytes_lun); } static void sbp2_release_target(struct kref *kref) static void sbp2_release_target(struct kref *kref) { { struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref); struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref); struct sbp2_logical_unit *lu, *next; struct sbp2_logical_unit *lu, *next; struct Scsi_Host *shost = struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); container_of((void *)tgt, struct Scsi_Host, hostdata[0]); struct scsi_device *sdev; struct fw_device *device = fw_device(tgt->unit->device.parent); /* prevent deadlocks */ /* prevent deadlocks */ sbp2_unblock(tgt); sbp2_unblock(tgt); list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { if (lu->sdev) { sdev = scsi_device_lookup(shost, 0, 0, sbp2_lun2int(lu->lun)); scsi_remove_device(lu->sdev); if (sdev) { scsi_device_put(lu->sdev); scsi_remove_device(sdev); scsi_device_put(sdev); } } sbp2_send_management_orb(lu, tgt->node_id, lu->generation, sbp2_send_management_orb(lu, tgt->node_id, lu->generation, SBP2_LOGOUT_REQUEST, lu->login_id, NULL); SBP2_LOGOUT_REQUEST, lu->login_id, NULL); Loading @@ -778,6 +792,7 @@ static void sbp2_release_target(struct kref *kref) put_device(&tgt->unit->device); put_device(&tgt->unit->device); scsi_host_put(shost); scsi_host_put(shost); fw_device_put(device); } } static struct workqueue_struct *sbp2_wq; static struct workqueue_struct *sbp2_wq; Loading Loading @@ -807,7 +822,6 @@ static void sbp2_login(struct work_struct *work) struct fw_device *device = fw_device(tgt->unit->device.parent); struct fw_device *device = fw_device(tgt->unit->device.parent); struct Scsi_Host *shost; struct Scsi_Host *shost; struct scsi_device *sdev; struct scsi_device *sdev; struct scsi_lun eight_bytes_lun; struct sbp2_login_response response; struct sbp2_login_response response; int generation, node_id, local_node_id; int generation, node_id, local_node_id; Loading @@ -820,7 +834,7 @@ static void sbp2_login(struct work_struct *work) local_node_id = device->card->node_id; local_node_id = device->card->node_id; /* If this is a re-login attempt, log out, or we might be rejected. */ /* If this is a re-login attempt, log out, or we might be rejected. */ if (lu->sdev) if (lu->has_sdev) sbp2_send_management_orb(lu, device->node_id, generation, sbp2_send_management_orb(lu, device->node_id, generation, SBP2_LOGOUT_REQUEST, lu->login_id, NULL); SBP2_LOGOUT_REQUEST, lu->login_id, NULL); Loading Loading @@ -859,7 +873,7 @@ static void sbp2_login(struct work_struct *work) sbp2_agent_reset(lu); sbp2_agent_reset(lu); /* This was a re-login. */ /* This was a re-login. */ if (lu->sdev) { if (lu->has_sdev) { sbp2_cancel_orbs(lu); sbp2_cancel_orbs(lu); sbp2_conditionally_unblock(lu); sbp2_conditionally_unblock(lu); goto out; goto out; Loading @@ -868,13 +882,8 @@ static void sbp2_login(struct work_struct *work) if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) ssleep(SBP2_INQUIRY_DELAY); ssleep(SBP2_INQUIRY_DELAY); memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff; eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff; shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); sdev = __scsi_add_device(shost, 0, 0, sbp2_lun2int(lu->lun), lu); sdev = __scsi_add_device(shost, 0, 0, scsilun_to_int(&eight_bytes_lun), lu); /* /* * FIXME: We are unable to perform reconnects while in sbp2_login(). * FIXME: We are unable to perform reconnects while in sbp2_login(). * Therefore __scsi_add_device() will get into trouble if a bus reset * Therefore __scsi_add_device() will get into trouble if a bus reset Loading @@ -896,7 +905,8 @@ static void sbp2_login(struct work_struct *work) } } /* No error during __scsi_add_device() */ /* No error during __scsi_add_device() */ lu->sdev = sdev; lu->has_sdev = true; scsi_device_put(sdev); sbp2_allow_block(lu); sbp2_allow_block(lu); goto out; goto out; Loading Loading @@ -935,9 +945,9 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) } } lu->tgt = tgt; lu->tgt = tgt; lu->sdev = NULL; lu->lun = lun_entry & 0xffff; lu->lun = lun_entry & 0xffff; lu->retries = 0; lu->retries = 0; lu->has_sdev = false; lu->blocked = false; lu->blocked = false; ++tgt->dont_block; ++tgt->dont_block; INIT_LIST_HEAD(&lu->orb_list); INIT_LIST_HEAD(&lu->orb_list); Loading Loading @@ -1080,6 +1090,8 @@ static int sbp2_probe(struct device *dev) if (scsi_add_host(shost, &unit->device) < 0) if (scsi_add_host(shost, &unit->device) < 0) goto fail_shost_put; goto fail_shost_put; fw_device_get(device); /* Initialize to values that won't match anything in our table. */ /* Initialize to values that won't match anything in our table. */ firmware_revision = 0xff000000; firmware_revision = 0xff000000; model = 0xff000000; model = 0xff000000; Loading drivers/firewire/fw-topology.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -383,6 +383,7 @@ void fw_destroy_nodes(struct fw_card *card) card->color++; card->color++; if (card->local_node != NULL) if (card->local_node != NULL) for_each_fw_node(card, card->local_node, report_lost_node); for_each_fw_node(card, card->local_node, report_lost_node); card->local_node = NULL; spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags); } } Loading Loading
drivers/firewire/fw-card.c +43 −18 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/errno.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/device.h> #include <linux/mutex.h> #include <linux/mutex.h> #include <linux/crc-itu-t.h> #include <linux/crc-itu-t.h> Loading Loading @@ -214,17 +215,29 @@ static void fw_card_bm_work(struct work_struct *work) fw_card_bm_work(struct work_struct *work) { { struct fw_card *card = container_of(work, struct fw_card, work.work); struct fw_card *card = container_of(work, struct fw_card, work.work); struct fw_device *root; struct fw_device *root_device; struct fw_node *root_node, *local_node; struct bm_data bmd; struct bm_data bmd; unsigned long flags; unsigned long flags; int root_id, new_root_id, irm_id, gap_count, generation, grace; int root_id, new_root_id, irm_id, gap_count, generation, grace; int do_reset = 0; int do_reset = 0; spin_lock_irqsave(&card->lock, flags); spin_lock_irqsave(&card->lock, flags); local_node = card->local_node; root_node = card->root_node; if (local_node == NULL) { spin_unlock_irqrestore(&card->lock, flags); return; } fw_node_get(local_node); fw_node_get(root_node); generation = card->generation; generation = card->generation; root = card->root_node->data; root_device = root_node->data; root_id = card->root_node->node_id; if (root_device) fw_device_get(root_device); root_id = root_node->node_id; grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); if (card->bm_generation + 1 == generation || if (card->bm_generation + 1 == generation || Loading @@ -243,14 +256,14 @@ fw_card_bm_work(struct work_struct *work) irm_id = card->irm_node->node_id; irm_id = card->irm_node->node_id; if (!card->irm_node->link_on) { if (!card->irm_node->link_on) { new_root_id = card->local_node->node_id; new_root_id = local_node->node_id; fw_notify("IRM has link off, making local node (%02x) root.\n", fw_notify("IRM has link off, making local node (%02x) root.\n", new_root_id); new_root_id); goto pick_me; goto pick_me; } } bmd.lock.arg = cpu_to_be32(0x3f); bmd.lock.arg = cpu_to_be32(0x3f); bmd.lock.data = cpu_to_be32(card->local_node->node_id); bmd.lock.data = cpu_to_be32(local_node->node_id); spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags); Loading @@ -267,12 +280,12 @@ fw_card_bm_work(struct work_struct *work) * Another bus reset happened. Just return, * Another bus reset happened. Just return, * the BM work has been rescheduled. * the BM work has been rescheduled. */ */ return; goto out; } } if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f) if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f) /* Somebody else is BM, let them do the work. */ /* Somebody else is BM, let them do the work. */ return; goto out; spin_lock_irqsave(&card->lock, flags); spin_lock_irqsave(&card->lock, flags); if (bmd.rcode != RCODE_COMPLETE) { if (bmd.rcode != RCODE_COMPLETE) { Loading @@ -282,7 +295,7 @@ fw_card_bm_work(struct work_struct *work) * do a bus reset and pick the local node as * do a bus reset and pick the local node as * root, and thus, IRM. * root, and thus, IRM. */ */ new_root_id = card->local_node->node_id; new_root_id = local_node->node_id; fw_notify("BM lock failed, making local node (%02x) root.\n", fw_notify("BM lock failed, making local node (%02x) root.\n", new_root_id); new_root_id); goto pick_me; goto pick_me; Loading @@ -295,7 +308,7 @@ fw_card_bm_work(struct work_struct *work) */ */ spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags); schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10)); schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10)); return; goto out; } } /* /* Loading @@ -305,20 +318,20 @@ fw_card_bm_work(struct work_struct *work) */ */ card->bm_generation = generation; card->bm_generation = generation; if (root == NULL) { if (root_device == NULL) { /* /* * Either link_on is false, or we failed to read the * Either link_on is false, or we failed to read the * config rom. In either case, pick another root. * config rom. In either case, pick another root. */ */ new_root_id = card->local_node->node_id; new_root_id = local_node->node_id; } else if (atomic_read(&root->state) != FW_DEVICE_RUNNING) { } else if (atomic_read(&root_device->state) != FW_DEVICE_RUNNING) { /* /* * If we haven't probed this device yet, bail out now * If we haven't probed this device yet, bail out now * and let's try again once that's done. * and let's try again once that's done. */ */ spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags); return; goto out; } else if (root->config_rom[2] & BIB_CMC) { } else if (root_device->config_rom[2] & BIB_CMC) { /* /* * FIXME: I suppose we should set the cmstr bit in the * FIXME: I suppose we should set the cmstr bit in the * STATE_CLEAR register of this node, as described in * STATE_CLEAR register of this node, as described in Loading @@ -332,7 +345,7 @@ fw_card_bm_work(struct work_struct *work) * successfully read the config rom, but it's not * successfully read the config rom, but it's not * cycle master capable. * cycle master capable. */ */ new_root_id = card->local_node->node_id; new_root_id = local_node->node_id; } } pick_me: pick_me: Loading @@ -341,8 +354,8 @@ fw_card_bm_work(struct work_struct *work) * the typically much larger 1394b beta repeater delays though. * the typically much larger 1394b beta repeater delays though. */ */ if (!card->beta_repeaters_present && if (!card->beta_repeaters_present && card->root_node->max_hops < ARRAY_SIZE(gap_count_table)) root_node->max_hops < ARRAY_SIZE(gap_count_table)) gap_count = gap_count_table[card->root_node->max_hops]; gap_count = gap_count_table[root_node->max_hops]; else else gap_count = 63; gap_count = 63; Loading @@ -364,6 +377,11 @@ fw_card_bm_work(struct work_struct *work) fw_send_phy_config(card, new_root_id, generation, gap_count); fw_send_phy_config(card, new_root_id, generation, gap_count); fw_core_initiate_bus_reset(card, 1); fw_core_initiate_bus_reset(card, 1); } } out: if (root_device) fw_device_put(root_device); fw_node_put(root_node); fw_node_put(local_node); } } static void static void Loading @@ -381,6 +399,7 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, static atomic_t index = ATOMIC_INIT(-1); static atomic_t index = ATOMIC_INIT(-1); kref_init(&card->kref); kref_init(&card->kref); atomic_set(&card->device_count, 0); card->index = atomic_inc_return(&index); card->index = atomic_inc_return(&index); card->driver = driver; card->driver = driver; card->device = device; card->device = device; Loading Loading @@ -511,8 +530,14 @@ fw_core_remove_card(struct fw_card *card) card->driver = &dummy_driver; card->driver = &dummy_driver; fw_destroy_nodes(card); fw_destroy_nodes(card); flush_scheduled_work(); /* * Wait for all device workqueue jobs to finish. Otherwise the * firewire-core module could be unloaded before the jobs ran. */ while (atomic_read(&card->device_count) > 0) msleep(100); cancel_delayed_work_sync(&card->work); fw_flush_transactions(card); fw_flush_transactions(card); del_timer_sync(&card->flush_timer); del_timer_sync(&card->flush_timer); Loading
drivers/firewire/fw-device.c +6 −15 Original line number Original line Diff line number Diff line Loading @@ -150,21 +150,10 @@ struct bus_type fw_bus_type = { }; }; EXPORT_SYMBOL(fw_bus_type); EXPORT_SYMBOL(fw_bus_type); struct fw_device *fw_device_get(struct fw_device *device) { get_device(&device->device); return device; } void fw_device_put(struct fw_device *device) { put_device(&device->device); } static void fw_device_release(struct device *dev) static void fw_device_release(struct device *dev) { { struct fw_device *device = fw_device(dev); struct fw_device *device = fw_device(dev); struct fw_card *card = device->card; unsigned long flags; unsigned long flags; /* /* Loading @@ -176,9 +165,9 @@ static void fw_device_release(struct device *dev) spin_unlock_irqrestore(&device->card->lock, flags); spin_unlock_irqrestore(&device->card->lock, flags); fw_node_put(device->node); fw_node_put(device->node); fw_card_put(device->card); kfree(device->config_rom); kfree(device->config_rom); kfree(device); kfree(device); atomic_dec(&card->device_count); } } int fw_device_enable_phys_dma(struct fw_device *device) int fw_device_enable_phys_dma(struct fw_device *device) Loading Loading @@ -668,7 +657,8 @@ static void fw_device_init(struct work_struct *work) */ */ if (read_bus_info_block(device, device->generation) < 0) { if (read_bus_info_block(device, device->generation) < 0) { if (device->config_rom_retries < MAX_RETRIES) { if (device->config_rom_retries < MAX_RETRIES && atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { device->config_rom_retries++; device->config_rom_retries++; schedule_delayed_work(&device->work, RETRY_DELAY); schedule_delayed_work(&device->work, RETRY_DELAY); } else { } else { Loading Loading @@ -805,7 +795,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) */ */ device_initialize(&device->device); device_initialize(&device->device); atomic_set(&device->state, FW_DEVICE_INITIALIZING); atomic_set(&device->state, FW_DEVICE_INITIALIZING); device->card = fw_card_get(card); atomic_inc(&card->device_count); device->card = card; device->node = fw_node_get(node); device->node = fw_node_get(node); device->node_id = node->node_id; device->node_id = node->node_id; device->generation = card->generation; device->generation = card->generation; Loading
drivers/firewire/fw-device.h +14 −2 Original line number Original line Diff line number Diff line Loading @@ -76,9 +76,21 @@ fw_device_is_shutdown(struct fw_device *device) return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; } } struct fw_device *fw_device_get(struct fw_device *device); static inline struct fw_device * fw_device_get(struct fw_device *device) { get_device(&device->device); return device; } static inline void fw_device_put(struct fw_device *device) { put_device(&device->device); } struct fw_device *fw_device_get_by_devt(dev_t devt); struct fw_device *fw_device_get_by_devt(dev_t devt); void fw_device_put(struct fw_device *device); int fw_device_enable_phys_dma(struct fw_device *device); int fw_device_enable_phys_dma(struct fw_device *device); void fw_device_cdev_update(struct fw_device *device); void fw_device_cdev_update(struct fw_device *device); Loading
drivers/firewire/fw-sbp2.c +31 −19 Original line number Original line Diff line number Diff line Loading @@ -122,7 +122,6 @@ static const char sbp2_driver_name[] = "sbp2"; struct sbp2_logical_unit { struct sbp2_logical_unit { struct sbp2_target *tgt; struct sbp2_target *tgt; struct list_head link; struct list_head link; struct scsi_device *sdev; struct fw_address_handler address_handler; struct fw_address_handler address_handler; struct list_head orb_list; struct list_head orb_list; Loading @@ -139,6 +138,7 @@ struct sbp2_logical_unit { int generation; int generation; int retries; int retries; struct delayed_work work; struct delayed_work work; bool has_sdev; bool blocked; bool blocked; }; }; Loading Loading @@ -751,20 +751,34 @@ static void sbp2_unblock(struct sbp2_target *tgt) scsi_unblock_requests(shost); scsi_unblock_requests(shost); } } static int sbp2_lun2int(u16 lun) { struct scsi_lun eight_bytes_lun; memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); eight_bytes_lun.scsi_lun[0] = (lun >> 8) & 0xff; eight_bytes_lun.scsi_lun[1] = lun & 0xff; return scsilun_to_int(&eight_bytes_lun); } static void sbp2_release_target(struct kref *kref) static void sbp2_release_target(struct kref *kref) { { struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref); struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref); struct sbp2_logical_unit *lu, *next; struct sbp2_logical_unit *lu, *next; struct Scsi_Host *shost = struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); container_of((void *)tgt, struct Scsi_Host, hostdata[0]); struct scsi_device *sdev; struct fw_device *device = fw_device(tgt->unit->device.parent); /* prevent deadlocks */ /* prevent deadlocks */ sbp2_unblock(tgt); sbp2_unblock(tgt); list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { if (lu->sdev) { sdev = scsi_device_lookup(shost, 0, 0, sbp2_lun2int(lu->lun)); scsi_remove_device(lu->sdev); if (sdev) { scsi_device_put(lu->sdev); scsi_remove_device(sdev); scsi_device_put(sdev); } } sbp2_send_management_orb(lu, tgt->node_id, lu->generation, sbp2_send_management_orb(lu, tgt->node_id, lu->generation, SBP2_LOGOUT_REQUEST, lu->login_id, NULL); SBP2_LOGOUT_REQUEST, lu->login_id, NULL); Loading @@ -778,6 +792,7 @@ static void sbp2_release_target(struct kref *kref) put_device(&tgt->unit->device); put_device(&tgt->unit->device); scsi_host_put(shost); scsi_host_put(shost); fw_device_put(device); } } static struct workqueue_struct *sbp2_wq; static struct workqueue_struct *sbp2_wq; Loading Loading @@ -807,7 +822,6 @@ static void sbp2_login(struct work_struct *work) struct fw_device *device = fw_device(tgt->unit->device.parent); struct fw_device *device = fw_device(tgt->unit->device.parent); struct Scsi_Host *shost; struct Scsi_Host *shost; struct scsi_device *sdev; struct scsi_device *sdev; struct scsi_lun eight_bytes_lun; struct sbp2_login_response response; struct sbp2_login_response response; int generation, node_id, local_node_id; int generation, node_id, local_node_id; Loading @@ -820,7 +834,7 @@ static void sbp2_login(struct work_struct *work) local_node_id = device->card->node_id; local_node_id = device->card->node_id; /* If this is a re-login attempt, log out, or we might be rejected. */ /* If this is a re-login attempt, log out, or we might be rejected. */ if (lu->sdev) if (lu->has_sdev) sbp2_send_management_orb(lu, device->node_id, generation, sbp2_send_management_orb(lu, device->node_id, generation, SBP2_LOGOUT_REQUEST, lu->login_id, NULL); SBP2_LOGOUT_REQUEST, lu->login_id, NULL); Loading Loading @@ -859,7 +873,7 @@ static void sbp2_login(struct work_struct *work) sbp2_agent_reset(lu); sbp2_agent_reset(lu); /* This was a re-login. */ /* This was a re-login. */ if (lu->sdev) { if (lu->has_sdev) { sbp2_cancel_orbs(lu); sbp2_cancel_orbs(lu); sbp2_conditionally_unblock(lu); sbp2_conditionally_unblock(lu); goto out; goto out; Loading @@ -868,13 +882,8 @@ static void sbp2_login(struct work_struct *work) if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) ssleep(SBP2_INQUIRY_DELAY); ssleep(SBP2_INQUIRY_DELAY); memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff; eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff; shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); sdev = __scsi_add_device(shost, 0, 0, sbp2_lun2int(lu->lun), lu); sdev = __scsi_add_device(shost, 0, 0, scsilun_to_int(&eight_bytes_lun), lu); /* /* * FIXME: We are unable to perform reconnects while in sbp2_login(). * FIXME: We are unable to perform reconnects while in sbp2_login(). * Therefore __scsi_add_device() will get into trouble if a bus reset * Therefore __scsi_add_device() will get into trouble if a bus reset Loading @@ -896,7 +905,8 @@ static void sbp2_login(struct work_struct *work) } } /* No error during __scsi_add_device() */ /* No error during __scsi_add_device() */ lu->sdev = sdev; lu->has_sdev = true; scsi_device_put(sdev); sbp2_allow_block(lu); sbp2_allow_block(lu); goto out; goto out; Loading Loading @@ -935,9 +945,9 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) } } lu->tgt = tgt; lu->tgt = tgt; lu->sdev = NULL; lu->lun = lun_entry & 0xffff; lu->lun = lun_entry & 0xffff; lu->retries = 0; lu->retries = 0; lu->has_sdev = false; lu->blocked = false; lu->blocked = false; ++tgt->dont_block; ++tgt->dont_block; INIT_LIST_HEAD(&lu->orb_list); INIT_LIST_HEAD(&lu->orb_list); Loading Loading @@ -1080,6 +1090,8 @@ static int sbp2_probe(struct device *dev) if (scsi_add_host(shost, &unit->device) < 0) if (scsi_add_host(shost, &unit->device) < 0) goto fail_shost_put; goto fail_shost_put; fw_device_get(device); /* Initialize to values that won't match anything in our table. */ /* Initialize to values that won't match anything in our table. */ firmware_revision = 0xff000000; firmware_revision = 0xff000000; model = 0xff000000; model = 0xff000000; Loading
drivers/firewire/fw-topology.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -383,6 +383,7 @@ void fw_destroy_nodes(struct fw_card *card) card->color++; card->color++; if (card->local_node != NULL) if (card->local_node != NULL) for_each_fw_node(card, card->local_node, report_lost_node); for_each_fw_node(card, card->local_node, report_lost_node); card->local_node = NULL; spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags); } } Loading