Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 34008
b: refs/heads/master
c: 4ed4b54
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Sep 19, 2006
1 parent 47fbb3b commit fa8b7b2
Show file tree
Hide file tree
Showing 30 changed files with 367 additions and 185 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: 5c2d97cb31fb77981797fec46230ca005b865799
refs/heads/master: 4ed4b5475211fab6a0ad00eed2f9297395e7598e
2 changes: 0 additions & 2 deletions trunk/Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1189,8 +1189,6 @@ running once the system is up.
Mechanism 2.
nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI
Configuration
mmconf [IA-32,X86_64] Force MMCONFIG. This is useful
to override the builtin blacklist.
nomsi [MSI] If the PCI_MSI kernel config parameter is
enabled, this kernel boot option can be used to
disable the use of MSI interrupts system-wide.
Expand Down
1 change: 1 addition & 0 deletions trunk/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,7 @@ help:
@echo 'Static analysers'
@echo ' checkstack - Generate a list of stack hogs'
@echo ' namespacecheck - Name space analysis on compiled kernel'
@echo ' headers_check - Sanity check on exported headers'
@echo ''
@echo 'Kernel packaging:'
@$(MAKE) $(build)=$(package-dir) help
Expand Down
32 changes: 32 additions & 0 deletions trunk/arch/i386/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,38 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
return 0;
}

/*
* This function checks if the entire range <start,end> is mapped with type.
*
* Note: this function only works correct if the e820 table is sorted and
* not-overlapping, which is the case
*/
int __init
e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
{
u64 start = s;
u64 end = e;
int i;
for (i = 0; i < e820.nr_map; i++) {
struct e820entry *ei = &e820.map[i];
if (type && ei->type != type)
continue;
/* is the region (part) in overlap with the current region ?*/
if (ei->addr >= end || ei->addr + ei->size <= start)
continue;
/* if the region is at the beginning of <start,end> we move
* start to the end of the region since it's ok until there
*/
if (ei->addr <= start)
start = ei->addr + ei->size;
/* if start is now at or beyond end, we're done, full
* coverage */
if (start >= end)
return 1; /* we're done */
}
return 0;
}

/*
* Find the highest page frame number we have available
*/
Expand Down
5 changes: 0 additions & 5 deletions trunk/arch/i386/pci/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,6 @@ char * __devinit pcibios_setup(char *str)
pci_probe &= ~PCI_PROBE_MMCONF;
return NULL;
}
/* override DMI blacklist */
else if (!strcmp(str, "mmconf")) {
pci_probe |= PCI_PROBE_MMCONF_FORCE;
return NULL;
}
#endif
else if (!strcmp(str, "noacpi")) {
acpi_noirq_set();
Expand Down
34 changes: 10 additions & 24 deletions trunk/arch/i386/pci/mmconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <asm/e820.h>
#include "pci.h"

Expand Down Expand Up @@ -188,31 +187,9 @@ static __init void unreachable_devices(void)
}
}

static int disable_mcfg(struct dmi_system_id *d)
{
printk("PCI: %s detected. Disabling MCFG.\n", d->ident);
pci_probe &= ~PCI_PROBE_MMCONF;
return 0;
}

static struct dmi_system_id __initdata dmi_bad_mcfg[] = {
/* Has broken MCFG table that makes the system hang when used */
{
.callback = disable_mcfg,
.ident = "Intel D3C5105 SDV",
.matches = {
DMI_MATCH(DMI_BIOS_VENDOR, "Intel"),
DMI_MATCH(DMI_BOARD_NAME, "D26928"),
},
},
{}
};

void __init pci_mmcfg_init(void)
{
dmi_check_system(dmi_bad_mcfg);

if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0)
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
return;

acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
Expand All @@ -221,6 +198,15 @@ void __init pci_mmcfg_init(void)
(pci_mmcfg_config[0].base_address == 0))
return;

if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
E820_RESERVED)) {
printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
pci_mmcfg_config[0].base_address);
printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
return;
}

printk(KERN_INFO "PCI: Using MMCONFIG\n");
raw_pci_ops = &pci_mmcfg;
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
Expand Down
3 changes: 1 addition & 2 deletions trunk/arch/i386/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
#define PCI_PROBE_CONF1 0x0002
#define PCI_PROBE_CONF2 0x0004
#define PCI_PROBE_MMCONF 0x0008
#define PCI_PROBE_MMCONF_FORCE 0x0010
#define PCI_PROBE_MASK 0x00ff
#define PCI_PROBE_MASK 0x000f

#define PCI_NO_SORT 0x0100
#define PCI_BIOS_SORT 0x0200
Expand Down
29 changes: 29 additions & 0 deletions trunk/arch/x86_64/kernel/e820.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,35 @@ e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
return 0;
}

/*
* This function checks if the entire range <start,end> is mapped with type.
*
* Note: this function only works correct if the e820 table is sorted and
* not-overlapping, which is the case
*/
int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type)
{
int i;
for (i = 0; i < e820.nr_map; i++) {
struct e820entry *ei = &e820.map[i];
if (type && ei->type != type)
continue;
/* is the region (part) in overlap with the current region ?*/
if (ei->addr >= end || ei->addr + ei->size <= start)
continue;

/* if the region is at the beginning of <start,end> we move
* start to the end of the region since it's ok until there
*/
if (ei->addr <= start)
start = ei->addr + ei->size;
/* if start is now at or beyond end, we're done, full coverage */
if (start >= end)
return 1; /* we're done */
}
return 0;
}

/*
* Find a free area in a specific range.
*/
Expand Down
34 changes: 10 additions & 24 deletions trunk/arch/x86_64/pci/mmconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/bitmap.h>
#include <linux/dmi.h>
#include <asm/e820.h>

#include "pci.h"
Expand Down Expand Up @@ -165,33 +164,11 @@ static __init void unreachable_devices(void)
}
}

static int disable_mcfg(struct dmi_system_id *d)
{
printk("PCI: %s detected. Disabling MCFG.\n", d->ident);
pci_probe &= ~PCI_PROBE_MMCONF;
return 0;
}

static struct dmi_system_id __initdata dmi_bad_mcfg[] = {
/* Has broken MCFG table that makes the system hang when used */
{
.callback = disable_mcfg,
.ident = "Intel D3C5105 SDV",
.matches = {
DMI_MATCH(DMI_BIOS_VENDOR, "Intel"),
DMI_MATCH(DMI_BOARD_NAME, "D26928"),
},
},
{}
};

void __init pci_mmcfg_init(void)
{
int i;

dmi_check_system(dmi_bad_mcfg);

if ((pci_probe & (PCI_PROBE_MMCONF|PCI_PROBE_MMCONF_FORCE)) == 0)
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
return;

acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
Expand All @@ -200,6 +177,15 @@ void __init pci_mmcfg_init(void)
(pci_mmcfg_config[0].base_address == 0))
return;

if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
E820_RESERVED)) {
printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
pci_mmcfg_config[0].base_address);
printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
return;
}

/* RED-PEN i386 doesn't do _nocache right now */
pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
if (pci_mmcfg_virt == NULL) {
Expand Down
87 changes: 43 additions & 44 deletions trunk/drivers/mtd/chips/cfi_cmdset_0001.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,

static int __xipram xip_wait_for_operation(
struct map_info *map, struct flchip *chip,
unsigned long adr, int *chip_op_time )
unsigned long adr, unsigned int chip_op_time )
{
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
Expand All @@ -917,7 +917,7 @@ static int __xipram xip_wait_for_operation(
flstate_t oldstate, newstate;

start = xip_currtime();
usec = *chip_op_time * 8;
usec = chip_op_time * 8;
if (usec == 0)
usec = 500000;
done = 0;
Expand Down Expand Up @@ -1027,8 +1027,8 @@ static int __xipram xip_wait_for_operation(
#define XIP_INVAL_CACHED_RANGE(map, from, size) \
INVALIDATE_CACHED_RANGE(map, from, size)

#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \
xip_wait_for_operation(map, chip, cmd_adr, p_usec)
#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \
xip_wait_for_operation(map, chip, cmd_adr, usec)

#else

Expand All @@ -1040,64 +1040,64 @@ static int __xipram xip_wait_for_operation(
static int inval_cache_and_wait_for_operation(
struct map_info *map, struct flchip *chip,
unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
int *chip_op_time )
unsigned int chip_op_time)
{
struct cfi_private *cfi = map->fldrv_priv;
map_word status, status_OK = CMD(0x80);
int z, chip_state = chip->state;
unsigned long timeo;
int chip_state = chip->state;
unsigned int timeo, sleep_time;

spin_unlock(chip->mutex);
if (inval_len)
INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
if (*chip_op_time)
cfi_udelay(*chip_op_time);
spin_lock(chip->mutex);

timeo = *chip_op_time * 8 * HZ / 1000000;
if (timeo < HZ/2)
timeo = HZ/2;
timeo += jiffies;
/* set our timeout to 8 times the expected delay */
timeo = chip_op_time * 8;
if (!timeo)
timeo = 500000;
sleep_time = chip_op_time / 2;

z = 0;
for (;;) {
if (chip->state != chip_state) {
/* Someone's suspended the operation: sleep */
DECLARE_WAITQUEUE(wait, current);

set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + (HZ / 2); /* FIXME */
spin_lock(chip->mutex);
continue;
}

status = map_read(map, cmd_adr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;

/* OK Still waiting */
if (time_after(jiffies, timeo)) {
if (!timeo) {
map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
return -ETIME;
}

/* Latency issues. Drop the lock, wait a while and retry */
z++;
/* OK Still waiting. Drop the lock, wait a while and retry. */
spin_unlock(chip->mutex);
cfi_udelay(1);
if (sleep_time >= 1000000/HZ) {
/*
* Half of the normal delay still remaining
* can be performed with a sleeping delay instead
* of busy waiting.
*/
msleep(sleep_time/1000);
timeo -= sleep_time;
sleep_time = 1000000/HZ;
} else {
udelay(1);
cond_resched();
timeo--;
}
spin_lock(chip->mutex);
}

if (!z) {
if (!--(*chip_op_time))
*chip_op_time = 1;
} else if (z > 1)
++(*chip_op_time);
if (chip->state != chip_state) {
/* Someone's suspended the operation: sleep */
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
spin_lock(chip->mutex);
}
}

/* Done and happy. */
chip->state = FL_STATUS;
Expand All @@ -1107,8 +1107,7 @@ static int inval_cache_and_wait_for_operation(
#endif

#define WAIT_TIMEOUT(map, chip, adr, udelay) \
({ int __udelay = (udelay); \
INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); })
INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay);


static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
Expand Down Expand Up @@ -1332,7 +1331,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,

ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, map_bankwidth(map),
&chip->word_write_time);
chip->word_write_time);
if (ret) {
xip_enable(map, chip, adr);
printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
Expand Down Expand Up @@ -1569,7 +1568,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,

ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
adr, len,
&chip->buffer_write_time);
chip->buffer_write_time);
if (ret) {
map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
Expand Down Expand Up @@ -1704,7 +1703,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,

ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, len,
&chip->erase_time);
chip->erase_time);
if (ret) {
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
Expand Down
Loading

0 comments on commit fa8b7b2

Please sign in to comment.