Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 81435
b: refs/heads/master
c: 8af03e7
h: refs/heads/master
i:
  81433: d080229
  81431: 8ae6c31
v: v3
  • Loading branch information
Linus Torvalds committed Jan 31, 2008
1 parent 3c61e4c commit 544dd58
Show file tree
Hide file tree
Showing 29 changed files with 469 additions and 461 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 99e139126ab2e84be67969650f92eb37c12ab5cd
refs/heads/master: 8af03e782cae1e0a0f530ddd22301cdd12cf9dc0
4 changes: 2 additions & 2 deletions trunk/MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1595,7 +1595,7 @@ P: Alexander Viro
M: viro@zeniv.linux.org.uk
S: Maintained

FIREWIRE SUBSYSTEM
FIREWIRE SUBSYSTEM (drivers/firewire, <linux/firewire*.h>)
P: Kristian Hoegsberg, Stefan Richter
M: krh@redhat.com, stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
Expand Down Expand Up @@ -1917,7 +1917,7 @@ L: linux-ide@vger.kernel.org
L: linux-scsi@vger.kernel.org
S: Orphan

IEEE 1394 SUBSYSTEM
IEEE 1394 SUBSYSTEM (drivers/ieee1394)
P: Ben Collins
M: ben.collins@ubuntu.com
P: Stefan Richter
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/ia64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ config GENERIC_TIME_VSYSCALL
bool
default y

config ARCH_SETS_UP_PER_CPU_AREA
config HAVE_SETUP_PER_CPU_AREA
def_bool y

config DMI
Expand Down
11 changes: 0 additions & 11 deletions trunk/arch/ia64/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -940,14 +940,3 @@ module_arch_cleanup (struct module *mod)
if (mod->arch.core_unw_table)
unw_remove_unwind_table(mod->arch.core_unw_table);
}

#ifdef CONFIG_SMP
void
percpu_modcopy (void *pcpudst, const void *src, unsigned long size)
{
unsigned int i;
for_each_possible_cpu(i) {
memcpy(pcpudst + per_cpu_offset(i), src, size);
}
}
#endif /* CONFIG_SMP */
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ config GENERIC_HARDIRQS
bool
default y

config ARCH_SETS_UP_PER_CPU_AREA
config HAVE_SETUP_PER_CPU_AREA
def_bool PPC64

config IRQ_PER_CPU
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/sparc64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ config AUDIT_ARCH
bool
default y

config ARCH_SETS_UP_PER_CPU_AREA
config HAVE_SETUP_PER_CPU_AREA
def_bool y

config ARCH_NO_VIRT_TO_BUS
Expand Down
5 changes: 5 additions & 0 deletions trunk/arch/sparc64/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,11 @@ pgd_t swapper_pg_dir[2048];
static void sun4u_pgprot_init(void);
static void sun4v_pgprot_init(void);

/* Dummy function */
void __init setup_per_cpu_areas(void)
{
}

void __init paging_init(void)
{
unsigned long end_pfn, pages_avail, shift, phys_base;
Expand Down
5 changes: 5 additions & 0 deletions trunk/arch/x86/kernel/test_nx.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,13 @@ static noinline int test_address(void *address)
".previous\n"
".section __ex_table,\"a\"\n"
" .align 8\n"
#ifdef CONFIG_X86_32
" .long 0b\n"
" .long 2b\n"
#else
" .quad 0b\n"
" .quad 2b\n"
#endif
".previous\n"
: [rslt] "=r" (result)
: [fake_code] "r" (address), [zero] "r" (0UL), "0" (result)
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/x86/lib/usercopy_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@ unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from,
#endif
return n;
}
EXPORT_SYMBOL(__copy_from_user_ll_nocache);

unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from,
unsigned long n)
Expand All @@ -831,6 +832,7 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *fr
#endif
return n;
}
EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero);

/**
* copy_to_user: - Copy a block of data into user space.
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/firewire/fw-cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,13 @@ fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,

event->closure = client->bus_reset_closure;
event->type = FW_CDEV_EVENT_BUS_RESET;
event->generation = client->device->generation;
smp_rmb(); /* node_id must not be older than generation */
event->node_id = client->device->node_id;
event->local_node_id = card->local_node->node_id;
event->bm_node_id = 0; /* FIXME: We don't track the BM. */
event->irm_node_id = card->irm_node->node_id;
event->root_node_id = card->root_node->node_id;
event->generation = card->generation;
}

static void
Expand Down
38 changes: 29 additions & 9 deletions trunk/drivers/firewire/fw-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/idr.h>
#include <linux/rwsem.h>
#include <asm/semaphore.h>
#include <asm/system.h>
#include <linux/ctype.h>
#include "fw-transaction.h"
#include "fw-topology.h"
Expand Down Expand Up @@ -182,9 +183,14 @@ static void fw_device_release(struct device *dev)

int fw_device_enable_phys_dma(struct fw_device *device)
{
int generation = device->generation;

/* device->node_id, accessed below, must not be older than generation */
smp_rmb();

return device->card->driver->enable_phys_dma(device->card,
device->node_id,
device->generation);
generation);
}
EXPORT_SYMBOL(fw_device_enable_phys_dma);

Expand Down Expand Up @@ -384,17 +390,21 @@ complete_transaction(struct fw_card *card, int rcode,
complete(&callback_data->done);
}

static int read_rom(struct fw_device *device, int index, u32 * data)
static int
read_rom(struct fw_device *device, int generation, int index, u32 *data)
{
struct read_quadlet_callback_data callback_data;
struct fw_transaction t;
u64 offset;

/* device->node_id, accessed below, must not be older than generation */
smp_rmb();

init_completion(&callback_data.done);

offset = 0xfffff0000400ULL + index * 4;
fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
device->node_id, device->generation, device->max_speed,
device->node_id, generation, device->max_speed,
offset, NULL, 4, complete_transaction, &callback_data);

wait_for_completion(&callback_data.done);
Expand All @@ -404,7 +414,14 @@ static int read_rom(struct fw_device *device, int index, u32 * data)
return callback_data.rcode;
}

static int read_bus_info_block(struct fw_device *device)
/*
* Read the bus info block, perform a speed probe, and read all of the rest of
* the config ROM. We do all this with a cached bus generation. If the bus
* generation changes under us, read_bus_info_block will fail and get retried.
* It's better to start all over in this case because the node from which we
* are reading the ROM may have changed the ROM during the reset.
*/
static int read_bus_info_block(struct fw_device *device, int generation)
{
static u32 rom[256];
u32 stack[16], sp, key;
Expand All @@ -414,7 +431,7 @@ static int read_bus_info_block(struct fw_device *device)

/* First read the bus info block. */
for (i = 0; i < 5; i++) {
if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE)
if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
return -1;
/*
* As per IEEE1212 7.2, during power-up, devices can
Expand Down Expand Up @@ -449,7 +466,8 @@ static int read_bus_info_block(struct fw_device *device)
device->max_speed = device->card->link_speed;

while (device->max_speed > SCODE_100) {
if (read_rom(device, 0, &dummy) == RCODE_COMPLETE)
if (read_rom(device, generation, 0, &dummy) ==
RCODE_COMPLETE)
break;
device->max_speed--;
}
Expand Down Expand Up @@ -482,7 +500,7 @@ static int read_bus_info_block(struct fw_device *device)
return -1;

/* Read header quadlet for the block to get the length. */
if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE)
if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
return -1;
end = i + (rom[i] >> 16) + 1;
i++;
Expand All @@ -501,7 +519,8 @@ static int read_bus_info_block(struct fw_device *device)
* it references another block, and push it in that case.
*/
while (i < end) {
if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE)
if (read_rom(device, generation, i, &rom[i]) !=
RCODE_COMPLETE)
return -1;
if ((key >> 30) == 3 && (rom[i] >> 30) > 1 &&
sp < ARRAY_SIZE(stack))
Expand Down Expand Up @@ -648,7 +667,7 @@ static void fw_device_init(struct work_struct *work)
* device.
*/

if (read_bus_info_block(device) < 0) {
if (read_bus_info_block(device, device->generation) < 0) {
if (device->config_rom_retries < MAX_RETRIES) {
device->config_rom_retries++;
schedule_delayed_work(&device->work, RETRY_DELAY);
Expand Down Expand Up @@ -801,6 +820,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)

device = node->data;
device->node_id = node->node_id;
smp_wmb(); /* update node_id before generation */
device->generation = card->generation;
if (atomic_read(&device->state) == FW_DEVICE_RUNNING) {
PREPARE_DELAYED_WORK(&device->work, fw_device_update);
Expand Down
12 changes: 12 additions & 0 deletions trunk/drivers/firewire/fw-device.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ struct fw_attribute_group {
struct attribute *attrs[11];
};

/*
* Note, fw_device.generation always has to be read before fw_device.node_id.
* Use SMP memory barriers to ensure this. Otherwise requests will be sent
* to an outdated node_id if the generation was updated in the meantime due
* to a bus reset.
*
* Likewise, fw-core will take care to update .node_id before .generation so
* that whenever fw_device.generation is current WRT the actual bus generation,
* fw_device.node_id is guaranteed to be current too.
*
* The same applies to fw_device.card->node_id vs. fw_device.generation.
*/
struct fw_device {
atomic_t state;
struct fw_node *node;
Expand Down
Loading

0 comments on commit 544dd58

Please sign in to comment.