Commit 198bb971 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'linus' into sched/urgent

parents ea71a546 481c5346
...@@ -542,7 +542,7 @@ otherwise initial value -1 that indicates the cpuset has no request. ...@@ -542,7 +542,7 @@ otherwise initial value -1 that indicates the cpuset has no request.
2 : search cores in a package. 2 : search cores in a package.
3 : search cpus in a node [= system wide on non-NUMA system] 3 : search cpus in a node [= system wide on non-NUMA system]
( 4 : search nodes in a chunk of node [on NUMA system] ) ( 4 : search nodes in a chunk of node [on NUMA system] )
( 5~ : search system wide [on NUMA system]) ( 5 : search system wide [on NUMA system] )
This file is per-cpuset and affect the sched domain where the cpuset This file is per-cpuset and affect the sched domain where the cpuset
belongs to. Therefore if the flag 'sched_load_balance' of a cpuset belongs to. Therefore if the flag 'sched_load_balance' of a cpuset
......
...@@ -2,17 +2,12 @@ Naming and data format standards for sysfs files ...@@ -2,17 +2,12 @@ Naming and data format standards for sysfs files
------------------------------------------------ ------------------------------------------------
The libsensors library offers an interface to the raw sensors data The libsensors library offers an interface to the raw sensors data
through the sysfs interface. See libsensors documentation and source for through the sysfs interface. Since lm-sensors 3.0.0, libsensors is
further information. As of writing this document, libsensors completely chip-independent. It assumes that all the kernel drivers
(from lm_sensors 2.8.3) is heavily chip-dependent. Adding or updating implement the standard sysfs interface described in this document.
support for any given chip requires modifying the library's code. This makes adding or updating support for any given chip very easy, as
This is because libsensors was written for the procfs interface libsensors, and applications using it, do not need to be modified.
older kernel modules were using, which wasn't standardized enough. This is a major improvement compared to lm-sensors 2.
Recent versions of libsensors (from lm_sensors 2.8.2 and later) have
support for the sysfs interface, though.
The new sysfs interface was designed to be as chip-independent as
possible.
Note that motherboards vary widely in the connections to sensor chips. Note that motherboards vary widely in the connections to sensor chips.
There is no standard that ensures, for example, that the second There is no standard that ensures, for example, that the second
...@@ -35,19 +30,17 @@ access this data in a simple and consistent way. That said, such programs ...@@ -35,19 +30,17 @@ access this data in a simple and consistent way. That said, such programs
will have to implement conversion, labeling and hiding of inputs. For will have to implement conversion, labeling and hiding of inputs. For
this reason, it is still not recommended to bypass the library. this reason, it is still not recommended to bypass the library.
If you are developing a userspace application please send us feedback on
this standard.
Note that this standard isn't completely established yet, so it is subject
to changes. If you are writing a new hardware monitoring driver those
features can't seem to fit in this interface, please contact us with your
extension proposal. Keep in mind that backward compatibility must be
preserved.
Each chip gets its own directory in the sysfs /sys/devices tree. To Each chip gets its own directory in the sysfs /sys/devices tree. To
find all sensor chips, it is easier to follow the device symlinks from find all sensor chips, it is easier to follow the device symlinks from
/sys/class/hwmon/hwmon*. /sys/class/hwmon/hwmon*.
Up to lm-sensors 3.0.0, libsensors looks for hardware monitoring attributes
in the "physical" device directory. Since lm-sensors 3.0.1, attributes found
in the hwmon "class" device directory are also supported. Complex drivers
(e.g. drivers for multifunction chips) may want to use this possibility to
avoid namespace pollution. The only drawback will be that older versions of
libsensors won't support the driver in question.
All sysfs values are fixed point numbers. All sysfs values are fixed point numbers.
There is only one value per file, unlike the older /proc specification. There is only one value per file, unlike the older /proc specification.
......
...@@ -4431,10 +4431,10 @@ M: johnpol@2ka.mipt.ru ...@@ -4431,10 +4431,10 @@ M: johnpol@2ka.mipt.ru
S: Maintained S: Maintained
W83791D HARDWARE MONITORING DRIVER W83791D HARDWARE MONITORING DRIVER
P: Charles Spirakis P: Marc Hulsman
M: bezaur@gmail.com M: m.hulsman@tudelft.nl
L: lm-sensors@lm-sensors.org L: lm-sensors@lm-sensors.org
S: Odd Fixes S: Maintained
W83793 HARDWARE MONITORING DRIVER W83793 HARDWARE MONITORING DRIVER
P: Rudolf Marek P: Rudolf Marek
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 26 SUBLEVEL = 26
EXTRAVERSION = -rc6 EXTRAVERSION = -rc7
NAME = Rotary Wombat NAME = Rotary Wombat
# *DOCUMENTATION* # *DOCUMENTATION*
......
...@@ -13,6 +13,7 @@ NM := $(NM) -B ...@@ -13,6 +13,7 @@ NM := $(NM) -B
LDFLAGS_vmlinux := -static -N #-relax LDFLAGS_vmlinux := -static -N #-relax
CHECKFLAGS += -D__alpha__ -m64 CHECKFLAGS += -D__alpha__ -m64
cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data
cflags-y += $(call cc-option, -fno-jump-tables)
cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4 cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4
cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5 cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5
......
...@@ -74,6 +74,8 @@ ...@@ -74,6 +74,8 @@
# define DBG(args) # define DBG(args)
#endif #endif
DEFINE_SPINLOCK(t2_hae_lock);
static volatile unsigned int t2_mcheck_any_expected; static volatile unsigned int t2_mcheck_any_expected;
static volatile unsigned int t2_mcheck_last_taken; static volatile unsigned int t2_mcheck_last_taken;
......
...@@ -71,6 +71,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_i ...@@ -71,6 +71,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_i
static void __init static void __init
quirk_cypress(struct pci_dev *dev) quirk_cypress(struct pci_dev *dev)
{ {
/* The Notorious Cy82C693 chip. */
/* The generic legacy mode IDE fixup in drivers/pci/probe.c
doesn't work correctly with the Cypress IDE controller as
it has non-standard register layout. Fix that. */
if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) {
dev->resource[2].start = dev->resource[3].start = 0;
dev->resource[2].end = dev->resource[3].end = 0;
dev->resource[2].flags = dev->resource[3].flags = 0;
if (PCI_FUNC(dev->devfn) == 2) {
dev->resource[0].start = 0x170;
dev->resource[0].end = 0x177;
dev->resource[1].start = 0x376;
dev->resource[1].end = 0x376;
}
}
/* The Cypress bridge responds on the PCI bus in the address range /* The Cypress bridge responds on the PCI bus in the address range
0xffff0000-0xffffffff (conventional x86 BIOS ROM). There is no 0xffff0000-0xffffffff (conventional x86 BIOS ROM). There is no
way to turn this off. The bridge also supports several extended way to turn this off. The bridge also supports several extended
......
...@@ -447,7 +447,7 @@ struct unaligned_stat { ...@@ -447,7 +447,7 @@ struct unaligned_stat {
/* Macro for exception fixup code to access integer registers. */ /* Macro for exception fixup code to access integer registers. */
#define una_reg(r) (regs->regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)]) #define una_reg(r) (_regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
asmlinkage void asmlinkage void
...@@ -456,6 +456,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, ...@@ -456,6 +456,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
{ {
long error, tmp1, tmp2, tmp3, tmp4; long error, tmp1, tmp2, tmp3, tmp4;
unsigned long pc = regs->pc - 4; unsigned long pc = regs->pc - 4;
unsigned long *_regs = regs->regs;
const struct exception_table_entry *fixup; const struct exception_table_entry *fixup;
unaligned[0].count++; unaligned[0].count++;
......
...@@ -512,6 +512,8 @@ static ssize_t sn2_ptc_proc_write(struct file *file, const char __user *user, si ...@@ -512,6 +512,8 @@ static ssize_t sn2_ptc_proc_write(struct file *file, const char __user *user, si
int cpu; int cpu;
char optstr[64]; char optstr[64];
if (count > sizeof(optstr))
return -EINVAL;
if (copy_from_user(optstr, user, count)) if (copy_from_user(optstr, user, count))
return -EFAULT; return -EFAULT;
optstr[count - 1] = '\0'; optstr[count - 1] = '\0';
......
...@@ -142,7 +142,7 @@ static void dump_one_vdso_page(struct page *pg, struct page *upg) ...@@ -142,7 +142,7 @@ static void dump_one_vdso_page(struct page *pg, struct page *upg)
printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT), printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT),
page_count(pg), page_count(pg),
pg->flags); pg->flags);
if (upg/* && pg != upg*/) { if (upg && !IS_ERR(upg) /* && pg != upg*/) {
printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg) printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg)
<< PAGE_SHIFT), << PAGE_SHIFT),
page_count(upg), page_count(upg),
......
...@@ -166,6 +166,8 @@ int geode_has_vsa2(void) ...@@ -166,6 +166,8 @@ int geode_has_vsa2(void)
static int has_vsa2 = -1; static int has_vsa2 = -1;
if (has_vsa2 == -1) { if (has_vsa2 == -1) {
u16 val;
/* /*
* The VSA has virtual registers that we can query for a * The VSA has virtual registers that we can query for a
* signature. * signature.
...@@ -173,7 +175,8 @@ int geode_has_vsa2(void) ...@@ -173,7 +175,8 @@ int geode_has_vsa2(void)
outw(VSA_VR_UNLOCK, VSA_VRC_INDEX); outw(VSA_VR_UNLOCK, VSA_VRC_INDEX);
outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX); outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX);
has_vsa2 = (inw(VSA_VRC_DATA) == VSA_SIG); val = inw(VSA_VRC_DATA);
has_vsa2 = (val == AMD_VSA_SIG || val == GSW_VSA_SIG);
} }
return has_vsa2; return has_vsa2;
......
...@@ -333,6 +333,7 @@ void flush_thread(void) ...@@ -333,6 +333,7 @@ void flush_thread(void)
/* /*
* Forget coprocessor state.. * Forget coprocessor state..
*/ */
tsk->fpu_counter = 0;
clear_fpu(tsk); clear_fpu(tsk);
clear_used_math(); clear_used_math();
} }
......
...@@ -294,6 +294,7 @@ void flush_thread(void) ...@@ -294,6 +294,7 @@ void flush_thread(void)
/* /*
* Forget coprocessor state.. * Forget coprocessor state..
*/ */
tsk->fpu_counter = 0;
clear_fpu(tsk); clear_fpu(tsk);
clear_used_math(); clear_used_math();
} }
......
...@@ -532,10 +532,16 @@ static void __init reserve_crashkernel(void) ...@@ -532,10 +532,16 @@ static void __init reserve_crashkernel(void)
(unsigned long)(crash_size >> 20), (unsigned long)(crash_size >> 20),
(unsigned long)(crash_base >> 20), (unsigned long)(crash_base >> 20),
(unsigned long)(total_mem >> 20)); (unsigned long)(total_mem >> 20));
if (reserve_bootmem(crash_base, crash_size,
BOOTMEM_EXCLUSIVE) < 0) {
printk(KERN_INFO "crashkernel reservation "
"failed - memory is in use\n");
return;
}
crashk_res.start = crash_base; crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1; crashk_res.end = crash_base + crash_size - 1;
reserve_bootmem(crash_base, crash_size,
BOOTMEM_DEFAULT);
} else } else
printk(KERN_INFO "crashkernel reservation failed - " printk(KERN_INFO "crashkernel reservation failed - "
"you have to specify a base address\n"); "you have to specify a base address\n");
......
...@@ -14,7 +14,10 @@ ...@@ -14,7 +14,10 @@
#include "mach_timer.h" #include "mach_timer.h"
static int tsc_disabled; /* native_sched_clock() is called before tsc_init(), so
we must start with the TSC soft disabled to prevent
erroneous rdtsc usage on !cpu_has_tsc processors */
static int tsc_disabled = -1;
/* /*
* On some systems the TSC frequency does not * On some systems the TSC frequency does not
...@@ -402,25 +405,20 @@ void __init tsc_init(void) ...@@ -402,25 +405,20 @@ void __init tsc_init(void)
{ {
int cpu; int cpu;
if (!cpu_has_tsc || tsc_disabled) { if (!cpu_has_tsc || tsc_disabled > 0)
/* Disable the TSC in case of !cpu_has_tsc */
tsc_disabled = 1;
return; return;
}
cpu_khz = calculate_cpu_khz(); cpu_khz = calculate_cpu_khz();
tsc_khz = cpu_khz; tsc_khz = cpu_khz;
if (!cpu_khz) { if (!cpu_khz) {
mark_tsc_unstable("could not calculate TSC khz"); mark_tsc_unstable("could not calculate TSC khz");
/*
* We need to disable the TSC completely in this case
* to prevent sched_clock() from using it.
*/
tsc_disabled = 1;
return; return;
} }
/* now allow native_sched_clock() to use rdtsc */
tsc_disabled = 0;
printk("Detected %lu.%03lu MHz processor.\n", printk("Detected %lu.%03lu MHz processor.\n",
(unsigned long)cpu_khz / 1000, (unsigned long)cpu_khz / 1000,
(unsigned long)cpu_khz % 1000); (unsigned long)cpu_khz % 1000);
......
...@@ -233,6 +233,9 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) ...@@ -233,6 +233,9 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
device = ac->device; device = ac->device;
switch (event) { switch (event) {
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
case ACPI_AC_NOTIFY_STATUS: case ACPI_AC_NOTIFY_STATUS:
case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK: case ACPI_NOTIFY_DEVICE_CHECK:
...@@ -244,11 +247,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) ...@@ -244,11 +247,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
#ifdef CONFIG_ACPI_SYSFS_POWER #ifdef CONFIG_ACPI_SYSFS_POWER
kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
#endif #endif
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
} }
return; return;
......
...@@ -1713,7 +1713,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, ...@@ -1713,7 +1713,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
status = acpi_video_bus_get_one_device(dev, video); status = acpi_video_bus_get_one_device(dev, video);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Cant attach device")); ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Cant attach device"));
continue; continue;
} }
} }
......
...@@ -651,9 +651,17 @@ config PATA_WINBOND_VLB ...@@ -651,9 +651,17 @@ config PATA_WINBOND_VLB
Support for the Winbond W83759A controller on Vesa Local Bus Support for the Winbond W83759A controller on Vesa Local Bus
systems. systems.
config HAVE_PATA_PLATFORM
bool
help
This is an internal configuration node for any machine that
uses pata-platform driver to enable the relevant driver in the
configuration structure without having to submit endless patches
to update the PATA_PLATFORM entry.
config PATA_PLATFORM config PATA_PLATFORM
tristate "Generic platform device PATA support" tristate "Generic platform device PATA support"
depends on EMBEDDED || ARCH_RPC || PPC depends on EMBEDDED || ARCH_RPC || PPC || HAVE_PATA_PLATFORM
help help
This option enables support for generic directly connected ATA This option enables support for generic directly connected ATA
devices commonly found on embedded systems. devices commonly found on embedded systems.
......
...@@ -90,6 +90,7 @@ enum { ...@@ -90,6 +90,7 @@ enum {
board_ahci_mv = 4, board_ahci_mv = 4,
board_ahci_sb700 = 5, board_ahci_sb700 = 5,
board_ahci_mcp65 = 6, board_ahci_mcp65 = 6,
board_ahci_nopmp = 7,
/* global controller registers */ /* global controller registers */
HOST_CAP = 0x00, /* host capabilities */ HOST_CAP = 0x00, /* host capabilities */
...@@ -401,6 +402,14 @@ static const struct ata_port_info ahci_port_info[] = { ...@@ -401,6 +402,14 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops, .port_ops = &ahci_ops,
}, },
/* board_ahci_nopmp */
{
AHCI_HFLAGS (AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
}; };
static const struct pci_device_id ahci_pci_tbl[] = { static const struct pci_device_id ahci_pci_tbl[] = {
...@@ -525,9 +534,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { ...@@ -525,9 +534,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */ { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */
/* SiS */ /* SiS */
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ { PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp }, /* SiS 966 */
{ PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */ { PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp }, /* SiS 968 */
{ PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ { PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp }, /* SiS 968 */
/* Marvell */ /* Marvell */
{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
...@@ -653,6 +662,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev, ...@@ -653,6 +662,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
cap &= ~HOST_CAP_PMP; cap &= ~HOST_CAP_PMP;
} }
if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 &&
port_map != 1) {
dev_printk(KERN_INFO, &pdev->dev,
"JMB361 has only one port, port_map 0x%x -> 0x%x\n",
port_map, 1);
port_map = 1;
}
/* /*
* Temporary Marvell 6145 hack: PATA port presence * Temporary Marvell 6145 hack: PATA port presence
* is asserted through the standard AHCI port * is asserted through the standard AHCI port
......
...@@ -1042,6 +1042,13 @@ static int piix_broken_suspend(void) ...@@ -1042,6 +1042,13 @@ static int piix_broken_suspend(void)
DMI_MATCH(DMI_PRODUCT_NAME, "Tecra M4"), DMI_MATCH(DMI_PRODUCT_NAME, "Tecra M4"),
}, },
}, },
{
.ident = "TECRA M4",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M4"),
},
},
{ {
.ident = "TECRA M5", .ident = "TECRA M5",
.matches = { .matches = {
......
...@@ -4297,7 +4297,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc) ...@@ -4297,7 +4297,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
} }
/** /**
* ata_check_atapi_dma - Check whether ATAPI DMA can be supported * atapi_check_dma - Check whether ATAPI DMA can be supported
* @qc: Metadata associated with taskfile to check * @qc: Metadata associated with taskfile to check
* *
* Allow low-level driver to filter ATA PACKET commands, returning * Allow low-level driver to filter ATA PACKET commands, returning
...@@ -4310,7 +4310,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc) ...@@ -4310,7 +4310,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
* RETURNS: 0 when ATAPI DMA can be used * RETURNS: 0 when ATAPI DMA can be used
* nonzero otherwise * nonzero otherwise
*/ */
int ata_check_atapi_dma(struct ata_queued_cmd *qc) int atapi_check_dma(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
......
...@@ -2343,8 +2343,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) ...@@ -2343,8 +2343,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
{ {
struct scsi_cmnd *scmd = qc->scsicmd; struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_device *dev = qc->dev; struct ata_device *dev = qc->dev;
int using_pio = (dev->flags & ATA_DFLAG_PIO);
int nodata = (scmd->sc_data_direction == DMA_NONE); int nodata = (scmd->sc_data_direction == DMA_NONE);
int using_pio = !nodata && (dev->flags & ATA_DFLAG_PIO);
unsigned int nbytes; unsigned int nbytes;
memset(qc->cdb, 0, dev->cdb_len); memset(qc->cdb, 0, dev->cdb_len);
...@@ -2362,7 +2362,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) ...@@ -2362,7 +2362,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
ata_qc_set_pc_nbytes(qc); ata_qc_set_pc_nbytes(qc);
/* check whether ATAPI DMA is safe */ /* check whether ATAPI DMA is safe */
if (!using_pio && ata_check_atapi_dma(qc)) if (!nodata && !using_pio && atapi_check_dma(qc))
using_pio = 1; using_pio = 1;
/* Some controller variants snoop this value for Packet /* Some controller variants snoop this value for Packet
...@@ -2402,13 +2402,11 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) ...@@ -2402,13 +2402,11 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
qc->tf.lbam = (nbytes & 0xFF); qc->tf.lbam = (nbytes & 0xFF);
qc->tf.lbah = (nbytes >> 8); qc->tf.lbah = (nbytes >> 8);
if (using_pio || nodata) { if (nodata)
/* no data, or PIO data xfer */ qc->tf.protocol = ATAPI_PROT_NODATA;
if (nodata) else if (using_pio)
qc->tf.protocol = ATAPI_PROT_NODATA; qc->tf.protocol = ATAPI_PROT_PIO;
else else {
qc->tf.protocol = ATAPI_PROT_PIO;
} else {
/* DMA data xfer */ /* DMA data xfer */
qc->tf.protocol = ATAPI_PROT_DMA; qc->tf.protocol = ATAPI_PROT_DMA;
qc->tf.feature |= ATAPI_PKT_DMA; qc->tf.feature |= ATAPI_PKT_DMA;
......
...@@ -106,7 +106,7 @@ extern void ata_sg_clean(struct ata_queued_cmd *qc); ...@@ -106,7 +106,7 @@ extern void ata_sg_clean(struct ata_queued_cmd *qc);
extern void ata_qc_free(struct ata_queued_cmd *qc); extern void ata_qc_free(struct ata_queued_cmd *qc);
extern void ata_qc_issue(struct ata_queued_cmd *qc); extern void ata_qc_issue(struct ata_queued_cmd *qc);
extern void __ata_qc_complete(struct ata_queued_cmd *qc); extern void __ata_qc_complete(struct ata_queued_cmd *qc);
extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); extern int atapi_check_dma(struct ata_queued_cmd *qc);
extern void swap_buf_le16(u16 *buf, unsigned int buf_words); extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
extern void ata_dev_init(struct ata_device *dev); extern void ata_dev_init(struct ata_device *dev);
extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp); extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
......
...@@ -414,6 +414,7 @@ static struct pcmcia_device_id pcmcia_devices[] = { ...@@ -414,6 +414,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674), PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b), PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b),
PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF300", 0x7ed2ad87, 0x7e9e78ee),
PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c), PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79), PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
...@@ -424,6 +425,7 @@ static struct pcmcia_device_id pcmcia_devices[] = { ...@@ -424,6 +425,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF45", 0x709b1bf1, 0xf68b6f32),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
......
...@@ -1322,6 +1322,9 @@ static int mv_port_start(struct ata_port *ap) ...@@ -1322,6 +1322,9 @@ static int mv_port_start(struct ata_port *ap)
goto out_port_free_dma_mem; goto out_port_free_dma_mem;
memset(pp->crpb, 0, MV_CRPB_Q_SZ); memset(pp->crpb, 0, MV_CRPB_Q_SZ);
/* 6041/6081 Rev. "C0" (and newer) are okay with async notify */
if (hpriv->hp_flags & MV_HP_ERRATA_60X1C0)
ap->flags |= ATA_FLAG_AN;
/* /*
* For GEN_I, there's no NCQ, so we only allocate a single sg_tbl. * For GEN_I, there's no NCQ, so we only allocate a single sg_tbl.
* For later hardware, we need one unique sg_tbl per NCQ tag. * For later hardware, we need one unique sg_tbl per NCQ tag.
...@@ -1592,6 +1595,24 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) ...@@ -1592,6 +1595,24 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
if ((qc->tf.protocol != ATA_PROT_DMA) && if ((qc->tf.protocol != ATA_PROT_DMA) &&
(qc->tf.protocol != ATA_PROT_NCQ)) { (qc->tf.protocol != ATA_PROT_NCQ)) {
static int limit_warnings = 10;
/*
* Errata SATA#16, SATA#24: warn if multiple DRQs expected.
*
* Someday, we might implement special polling workarounds
* for these, but it all seems rather unnecessary since we
* normally use only DMA for commands which transfer more
* than a single block of data.
*
* Much of the time, this could just work regardless.
* So for now, just log the incident, and allow the attempt.
*/
if (limit_warnings && (qc->nbytes / qc->sect_size) > 1) {
--limit_warnings;
ata_link_printk(qc->dev->link, KERN_WARNING, DRV_NAME
": attempting PIO w/multiple DRQ: "
"this may fail due to h/w errata\n");
}
/* /*
* We're about to send a non-EDMA capable command to the * We're about to send a non-EDMA capable command to the
* port. Turn off EDMA so there won't be problems accessing * port. Turn off EDMA so there won't be problems accessing
......
...@@ -948,7 +948,7 @@ static void intel_i9xx_setup_flush(void) ...@@ -948,7 +948,7 @@ static void intel_i9xx_setup_flush(void)
intel_private.ifp_resource.flags = IORESOURCE_MEM; intel_private.ifp_resource.flags = IORESOURCE_MEM;
/* Setup chipset flush for 915 */ /* Setup chipset flush for 915 */
if (IS_I965 || IS_G33) { if (IS_I965 || IS_G33 || IS_G4X) {
intel_i965_g33_setup_chipset_flush(); intel_i965_g33_setup_chipset_flush();
} else { } else {
intel_i915_setup_chipset_flush(); intel_i915_setup_chipset_flush();
......
...@@ -76,7 +76,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info ...@@ -76,7 +76,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info
for (i = 0; i < pages; i++) { for (i = 0; i < pages; i++) {
if (!entry->busaddr[i]) if (!entry->busaddr[i])
break; break;
pci_unmap_single(dev->pdev, entry->busaddr[i], pci_unmap_page(dev->pdev, entry->busaddr[i],
PAGE_SIZE, PCI_DMA_TODEVICE); PAGE_SIZE, PCI_DMA_TODEVICE);
} }
...@@ -137,10 +137,8 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga ...@@ -137,10 +137,8 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
for (i = 0; i < pages; i++) { for (i = 0; i < pages; i++) {
/* we need to support large memory configurations */ /* we need to support large memory configurations */
entry->busaddr[i] = pci_map_single(dev->pdev, entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i],
page_address(entry-> 0, PAGE_SIZE, PCI_DMA_TODEVICE);
pagelist[i]),
PAGE_SIZE, PCI_DMA_TODEVICE);
if (entry->busaddr[i] == 0) { if (entry->busaddr[i] == 0) {
DRM_ERROR("unable to map PCIGART pages!\n"); DRM_ERROR("unable to map PCIGART pages!\n");
drm_ati_pcigart_cleanup(dev, gart_info); drm_ati_pcigart_cleanup(dev, gart_info);
......
...@@ -628,7 +628,7 @@ struct drm_set_version { ...@@ -628,7 +628,7 @@ struct drm_set_version {
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding) #define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding) #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding)
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, struct drm_scatter_gather) #define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather)
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather) #define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather)
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank) #define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
......
...@@ -470,17 +470,18 @@ int drm_ioctl(struct inode *inode, struct file *filp, ...@@ -470,17 +470,18 @@ int drm_ioctl(struct inode *inode, struct file *filp,
if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
(nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
ioctl = &drm_ioctls[nr]; ioctl = &drm_ioctls[nr];
else cmd = ioctl->cmd;
} else
goto err_i1; goto err_i1;
/* Do not trust userspace, use our own definition */
func = ioctl->func; func = ioctl->func;
/* is there a local override? */ /* is there a local override? */
if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl) if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl)
func = dev->driver->dma_ioctl; func = dev->driver->dma_ioctl;
if (!func) { if (!func) {
DRM_DEBUG("no function\n"); DRM_DEBUG("no function\n");
retcode = -EINVAL; retcode = -EINVAL;
......
...@@ -103,20 +103,18 @@ ...@@ -103,20 +103,18 @@
{0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
{0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5974, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ {0x1002, 0x5974, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ {0x1002, 0x5975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
{0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
...@@ -411,4 +409,7 @@ ...@@ -411,4 +409,7 @@
{0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2a12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2a12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0} {0, 0, 0}
...@@ -1112,12 +1112,19 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); ...@@ -1112,12 +1112,19 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
(dev)->pci_device == 0x29A2 || \ (dev)->pci_device == 0x29A2 || \
(dev)->pci_device == 0x2A02 || \ (dev)->pci_device == 0x2A02 || \
(dev)->pci_device == 0x2A12 || \ (dev)->pci_device == 0x2A12 || \
(dev)->pci_device == 0x2A42) (dev)->pci_device == 0x2A42 || \
(dev)->pci_device == 0x2E02 || \
(dev)->pci_device == 0x2E12 || \
(dev)->pci_device == 0x2E22)
#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) #define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42) #define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42)
#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \
(dev)->pci_device == 0x2E12 || \
(dev)->pci_device == 0x2E22)
#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ #define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
(dev)->pci_device == 0x29B2 || \ (dev)->pci_device == 0x29B2 || \
(dev)->pci_device == 0x29D2) (dev)->pci_device == 0x29D2)
...@@ -1128,7 +1135,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); ...@@ -1128,7 +1135,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev)) IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev)) #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev) || IS_G4X(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024) #define PRIMARY_RINGBUFFER_SIZE (128*1024)
......
...@@ -189,18 +189,12 @@ void r300_init_reg_flags(struct drm_device *dev) ...@@ -189,18 +189,12 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(R300_RE_CULL_CNTL, 1); ADD_RANGE(R300_RE_CULL_CNTL, 1);
ADD_RANGE(0x42C0, 2); ADD_RANGE(0x42C0, 2);
ADD_RANGE(R300_RS_CNTL_0, 2); ADD_RANGE(R300_RS_CNTL_0, 2);
ADD_RANGE(R300_RS_INTERP_0, 8);
ADD_RANGE(R300_RS_ROUTE_0, 8); ADD_RANGE(R300_SC_HYPERZ, 2);
ADD_RANGE(0x43A4, 2);
ADD_RANGE(0x43E8, 1); ADD_RANGE(0x43E8, 1);
ADD_RANGE(R300_PFS_CNTL_0, 3);
ADD_RANGE(R300_PFS_NODE_0, 4);
ADD_RANGE(R300_PFS_TEXI_0, 64);
ADD_RANGE(0x46A4, 5); ADD_RANGE(0x46A4, 5);
ADD_RANGE(R300_PFS_INSTR0_0, 64);
ADD_RANGE(R300_PFS_INSTR1_0, 64);
ADD_RANGE(R300_PFS_INSTR2_0, 64);
ADD_RANGE(R300_PFS_INSTR3_0, 64);
ADD_RANGE(R300_RE_FOG_STATE, 1); ADD_RANGE(R300_RE_FOG_STATE, 1);
ADD_RANGE(R300_FOG_COLOR_R, 3); ADD_RANGE(R300_FOG_COLOR_R, 3);
ADD_RANGE(R300_PP_ALPHA_TEST, 2); ADD_RANGE(R300_PP_ALPHA_TEST, 2);
...@@ -215,14 +209,12 @@ void r300_init_reg_flags(struct drm_device *dev) ...@@ -215,14 +209,12 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(0x4E50, 9); ADD_RANGE(0x4E50, 9);
ADD_RANGE(0x4E88, 1); ADD_RANGE(0x4E88, 1);
ADD_RANGE(0x4EA0, 2); ADD_RANGE(0x4EA0, 2);
ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3); ADD_RANGE(R300_ZB_CNTL, 3);
ADD_RANGE(R300_RB3D_ZSTENCIL_FORMAT, 4); ADD_RANGE(R300_ZB_FORMAT, 4);
ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */ ADD_RANGE_MARK(R300_ZB_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
ADD_RANGE(R300_RB3D_DEPTHPITCH, 1); ADD_RANGE(R300_ZB_DEPTHPITCH, 1);
ADD_RANGE(0x4F28, 1); ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1);
ADD_RANGE(0x4F30, 2); ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13);
ADD_RANGE(0x4F44, 1);
ADD_RANGE(0x4F54, 1);
ADD_RANGE(R300_TX_FILTER_0, 16); ADD_RANGE(R300_TX_FILTER_0, 16);
ADD_RANGE(R300_TX_FILTER1_0, 16); ADD_RANGE(R300_TX_FILTER1_0, 16);
...@@ -235,13 +227,32 @@ void r300_init_reg_flags(struct drm_device *dev) ...@@ -235,13 +227,32 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
/* Sporadic registers used as primitives are emitted */ /* Sporadic registers used as primitives are emitted */
ADD_RANGE(R300_RB3D_ZCACHE_CTLSTAT, 1); ADD_RANGE(R300_ZB_ZCACHE_CTLSTAT, 1);
ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1); ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1);
ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
ADD_RANGE(0x4074, 16); ADD_RANGE(R500_VAP_INDEX_OFFSET, 1);
ADD_RANGE(R500_US_CONFIG, 2);
ADD_RANGE(R500_US_CODE_ADDR, 3);
ADD_RANGE(R500_US_FC_CTRL, 1);
ADD_RANGE(R500_RS_IP_0, 16);
ADD_RANGE(R500_RS_INST_0, 16);
ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2);
ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2);
ADD_RANGE(R500_ZB_FIFO_SIZE, 2);
} else {
ADD_RANGE(R300_PFS_CNTL_0, 3);
ADD_RANGE(R300_PFS_NODE_0, 4);
ADD_RANGE(R300_PFS_TEXI_0, 64);
ADD_RANGE(R300_PFS_INSTR0_0, 64);
ADD_RANGE(R300_PFS_INSTR1_0, 64);
ADD_RANGE(R300_PFS_INSTR2_0, 64);
ADD_RANGE(R300_PFS_INSTR3_0, 64);
ADD_RANGE(R300_RS_INTERP_0, 8);
ADD_RANGE(R300_RS_ROUTE_0, 8);
} }
} }
...@@ -707,8 +718,9 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) ...@@ -707,8 +718,9 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
BEGIN_RING(6); BEGIN_RING(6);
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A); OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A);
OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0));
OUT_RING(R300_RB3D_ZCACHE_UNKNOWN_03); OUT_RING(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE|
R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0));
OUT_RING(0x0); OUT_RING(0x0);
ADVANCE_RING(); ADVANCE_RING();
...@@ -828,6 +840,54 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, ...@@ -828,6 +840,54 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
return 0; return 0;
} }
/**
* Uploads user-supplied vertex program instructions or parameters onto
* the graphics card.
* Called by r300_do_cp_cmdbuf.
*/
static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv,
drm_radeon_kcmd_buffer_t *cmdbuf,
drm_r300_cmd_header_t header)
{
int sz;
int addr;
int type;
int clamp;
int stride;
RING_LOCALS;
sz = header.r500fp.count;
/* address is 9 bits 0 - 8, bit 1 of flags is part of address */
addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo;
type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE);
clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);
addr |= (type << 16);
addr |= (clamp << 17);
stride = type ? 4 : 6;
DRM_DEBUG("r500fp %d %d type: %d\n", sz, addr, type);
if (!sz)
return 0;
if (sz * stride * 4 > cmdbuf->bufsz)
return -EINVAL;
BEGIN_RING(3 + sz * stride);
OUT_RING_REG(R500_GA_US_VECTOR_INDEX, addr);
OUT_RING(CP_PACKET0_TABLE(R500_GA_US_VECTOR_DATA, sz * stride - 1));
OUT_RING_TABLE((int *)cmdbuf->buf, sz * stride);
ADVANCE_RING();
cmdbuf->buf += sz * stride * 4;
cmdbuf->bufsz -= sz * stride * 4;
return 0;
}
/** /**
* Parses and validates a user-supplied command buffer and emits appropriate * Parses and validates a user-supplied command buffer and emits appropriate
* commands on the DMA ring buffer. * commands on the DMA ring buffer.
...@@ -963,6 +1023,19 @@ int r300_do_cp_cmdbuf(struct drm_device *dev, ...@@ -963,6 +1023,19 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
} }
break; break;
case R300_CMD_R500FP:
if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) {
DRM_ERROR("Calling r500 command on r300 card\n");
ret = -EINVAL;
goto cleanup;
}
DRM_DEBUG("R300_CMD_R500FP\n");
ret = r300_emit_r500fp(dev_priv, cmdbuf, header);
if (ret) {
DRM_ERROR("r300_emit_r500fp failed\n");
goto cleanup;
}
break;
default: default:
DRM_ERROR("bad cmd_type %i at %p\n", DRM_ERROR("bad cmd_type %i at %p\n",
header.header.cmd_type, header.header.cmd_type,
......
This diff is collapsed.
This diff is collapsed.
...@@ -240,6 +240,7 @@ typedef union { ...@@ -240,6 +240,7 @@ typedef union {
# define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN 0x8 # define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN 0x8
#define R300_CMD_SCRATCH 8 #define R300_CMD_SCRATCH 8
#define R300_CMD_R500FP 9
typedef union { typedef union {
unsigned int u; unsigned int u;
...@@ -268,6 +269,9 @@ typedef union { ...@@ -268,6 +269,9 @@ typedef union {
struct { struct {
unsigned char cmd_type, reg, n_bufs, flags; unsigned char cmd_type, reg, n_bufs, flags;
} scratch; } scratch;
struct {
unsigned char cmd_type, count, adrlo, adrhi_flags;
} r500fp;
} drm_r300_cmd_header_t; } drm_r300_cmd_header_t;
#define RADEON_FRONT 0x1 #define RADEON_FRONT 0x1
...@@ -278,6 +282,9 @@ typedef union { ...@@ -278,6 +282,9 @@ typedef union {
#define RADEON_USE_HIERZ 0x40000000 #define RADEON_USE_HIERZ 0x40000000
#define RADEON_USE_COMP_ZBUF 0x20000000 #define RADEON_USE_COMP_ZBUF 0x20000000
#define R500FP_CONSTANT_TYPE (1 << 1)
#define R500FP_CONSTANT_CLAMP (1 << 2)
/* Primitive types /* Primitive types
*/ */
#define RADEON_POINTS 0x1 #define RADEON_POINTS 0x1
...@@ -669,6 +676,7 @@ typedef struct drm_radeon_indirect { ...@@ -669,6 +676,7 @@ typedef struct drm_radeon_indirect {
#define RADEON_PARAM_CARD_TYPE 12 #define RADEON_PARAM_CARD_TYPE 12
#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */
#define RADEON_PARAM_FB_LOCATION 14 /* FB location */ #define RADEON_PARAM_FB_LOCATION 14 /* FB location */
#define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */
typedef struct drm_radeon_getparam { typedef struct drm_radeon_getparam {
int param; int param;
......
This diff is collapsed.
...@@ -234,7 +234,7 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr ...@@ -234,7 +234,7 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
return radeon_wait_irq(dev, irqwait->irq_seq); return radeon_wait_irq(dev, irqwait->irq_seq);
} }
static void radeon_enable_interrupt(struct drm_device *dev) void radeon_enable_interrupt(struct drm_device *dev)
{ {
drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
......
This diff is collapsed.
...@@ -1662,7 +1662,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, ...@@ -1662,7 +1662,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
u32 height; u32 height;
int i; int i;
u32 texpitch, microtile; u32 texpitch, microtile;
u32 offset; u32 offset, byte_offset;
RING_LOCALS; RING_LOCALS;
if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) { if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) {
...@@ -1727,6 +1727,13 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, ...@@ -1727,6 +1727,13 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
} else } else
microtile = 0; microtile = 0;
/* this might fail for zero-sized uploads - are those illegal? */
if (!radeon_check_offset(dev_priv, tex->offset + image->height *
blit_width - 1)) {
DRM_ERROR("Invalid final destination offset\n");
return -EINVAL;
}
DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width); DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
do { do {
...@@ -1840,6 +1847,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, ...@@ -1840,6 +1847,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
} }
#undef RADEON_COPY_MT #undef RADEON_COPY_MT
byte_offset = (image->y & ~2047) * blit_width;
buf->file_priv = file_priv; buf->file_priv = file_priv;
buf->used = size; buf->used = size;
offset = dev_priv->gart_buffers_offset + buf->offset; offset = dev_priv->gart_buffers_offset + buf->offset;
...@@ -1854,9 +1862,9 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, ...@@ -1854,9 +1862,9 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
RADEON_DP_SRC_SOURCE_MEMORY | RADEON_DP_SRC_SOURCE_MEMORY |
RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
OUT_RING((spitch << 22) | (offset >> 10)); OUT_RING((spitch << 22) | (offset >> 10));
OUT_RING((texpitch << 22) | (tex->offset >> 10)); OUT_RING((texpitch << 22) | ((tex->offset >> 10) + (byte_offset >> 10)));
OUT_RING(0); OUT_RING(0);
OUT_RING((image->x << 16) | image->y); OUT_RING((image->x << 16) | (image->y % 2048));
OUT_RING((image->width << 16) | height); OUT_RING((image->width << 16) | height);
RADEON_WAIT_UNTIL_2D_IDLE(); RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING(); ADVANCE_RING();
...@@ -3037,6 +3045,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil ...@@ -3037,6 +3045,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
case RADEON_PARAM_FB_LOCATION: case RADEON_PARAM_FB_LOCATION:
value = radeon_read_fb_location(dev_priv); value = radeon_read_fb_location(dev_priv);
break; break;
case RADEON_PARAM_NUM_GB_PIPES:
value = dev_priv->num_gb_pipes;
break;
default: default:
DRM_DEBUG("Invalid parameter %d\n", param->param); DRM_DEBUG("Invalid parameter %d\n", param->param);
return -EINVAL; return -EINVAL;
......
comment "An alternative FireWire stack is available with EXPERIMENTAL=y" comment "A new alternative FireWire stack is available with EXPERIMENTAL=y"
depends on EXPERIMENTAL=n depends on EXPERIMENTAL=n
comment "Enable only one of the two stacks, unless you know what you are doing"
depends on EXPERIMENTAL
config FIREWIRE config FIREWIRE
tristate "IEEE 1394 (FireWire) support - alternative stack, EXPERIMENTAL" tristate "New FireWire stack, EXPERIMENTAL"
depends on EXPERIMENTAL depends on EXPERIMENTAL
select CRC_ITU_T select CRC_ITU_T
help help
This is the "Juju" FireWire stack, a new alternative implementation This is the "Juju" FireWire stack, a new alternative implementation
designed for robustness and simplicity. You can build either this designed for robustness and simplicity. You can build either this
stack, or the classic stack (the ieee1394 driver, ohci1394 etc.) stack, or the old stack (the ieee1394 driver, ohci1394 etc.) or both.
or both. Please read http://wiki.linux1394.org/JujuMigration before Please read http://wiki.linux1394.org/JujuMigration before you
you enable the new stack. enable the new stack.
To compile this driver as a module, say M here: the module will be To compile this driver as a module, say M here: the module will be
called firewire-core. It functionally replaces ieee1394, raw1394, called firewire-core. It functionally replaces ieee1394, raw1394,
and video1394. and video1394.
NOTE:
You should only build ONE of the stacks, unless you REALLY know what
you are doing.
config FIREWIRE_OHCI config FIREWIRE_OHCI
tristate "Support for OHCI FireWire host controllers" tristate "OHCI-1394 controllers"
depends on PCI && FIREWIRE depends on PCI && FIREWIRE
help help
Enable this driver if you have a FireWire controller based Enable this driver if you have a FireWire controller based
...@@ -33,12 +31,12 @@ config FIREWIRE_OHCI ...@@ -33,12 +31,12 @@ config FIREWIRE_OHCI
called firewire-ohci. It replaces ohci1394 of the classic IEEE 1394 called firewire-ohci. It replaces ohci1394 of the classic IEEE 1394
stack. stack.
NOTE: NOTE:
You should only build ohci1394 or firewire-ohci, but not both. You should only build either firewire-ohci or the old ohci1394 driver,
If you nevertheless want to install both, you should configure them but not both. If you nevertheless want to install both, you should
only as modules and blacklist the driver(s) which you don't want to configure them only as modules and blacklist the driver(s) which you
have auto-loaded. Add either don't want to have auto-loaded. Add either
blacklist firewire-ohci blacklist firewire-ohci
or or
...@@ -60,7 +58,7 @@ config FIREWIRE_OHCI_DEBUG ...@@ -60,7 +58,7 @@ config FIREWIRE_OHCI_DEBUG
default y default y
config FIREWIRE_SBP2 config FIREWIRE_SBP2
tristate "Support for storage devices (SBP-2 protocol driver)" tristate "Storage devices (SBP-2 protocol)"
depends on FIREWIRE && SCSI depends on FIREWIRE && SCSI
help help
This option enables you to use SBP-2 devices connected to a This option enables you to use SBP-2 devices connected to a
......
...@@ -205,6 +205,7 @@ fw_device_op_read(struct file *file, ...@@ -205,6 +205,7 @@ fw_device_op_read(struct file *file,
return dequeue_event(client, buffer, count); return dequeue_event(client, buffer, count);
} }
/* caller must hold card->lock so that node pointers can be dereferenced here */
static void static void
fill_bus_reset_event(struct fw_cdev_event_bus_reset *event, fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
struct client *client) struct client *client)
...@@ -214,7 +215,6 @@ fill_bus_reset_event(struct fw_cdev_event_bus_reset *event, ...@@ -214,7 +215,6 @@ fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
event->closure = client->bus_reset_closure; event->closure = client->bus_reset_closure;
event->type = FW_CDEV_EVENT_BUS_RESET; event->type = FW_CDEV_EVENT_BUS_RESET;
event->generation = client->device->generation; event->generation = client->device->generation;
smp_rmb(); /* node_id must not be older than generation */
event->node_id = client->device->node_id; event->node_id = client->device->node_id;
event->local_node_id = card->local_node->node_id; event->local_node_id = card->local_node->node_id;
event->bm_node_id = 0; /* FIXME: We don't track the BM. */ event->bm_node_id = 0; /* FIXME: We don't track the BM. */
...@@ -274,6 +274,7 @@ static int ioctl_get_info(struct client *client, void *buffer) ...@@ -274,6 +274,7 @@ static int ioctl_get_info(struct client *client, void *buffer)
{ {
struct fw_cdev_get_info *get_info = buffer; struct fw_cdev_get_info *get_info = buffer;
struct fw_cdev_event_bus_reset bus_reset; struct fw_cdev_event_bus_reset bus_reset;
struct fw_card *card = client->device->card;
unsigned long ret = 0; unsigned long ret = 0;
client->version = get_info->version; client->version = get_info->version;
...@@ -299,13 +300,17 @@ static int ioctl_get_info(struct client *client, void *buffer) ...@@ -299,13 +300,17 @@ static int ioctl_get_info(struct client *client, void *buffer)
client->bus_reset_closure = get_info->bus_reset_closure; client->bus_reset_closure = get_info->bus_reset_closure;
if (get_info->bus_reset != 0) { if (get_info->bus_reset != 0) {
void __user *uptr = u64_to_uptr(get_info->bus_reset); void __user *uptr = u64_to_uptr(get_info->bus_reset);
unsigned long flags;
spin_lock_irqsave(&card->lock, flags);
fill_bus_reset_event(&bus_reset, client); fill_bus_reset_event(&bus_reset, client);
spin_unlock_irqrestore(&card->lock, flags);
if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset))) if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset)))
return -EFAULT; return -EFAULT;
} }
get_info->card = client->device->card->index; get_info->card = card->index;
return 0; return 0;
} }
......
...@@ -265,27 +265,25 @@ static void log_irqs(u32 evt) ...@@ -265,27 +265,25 @@ static void log_irqs(u32 evt)
!(evt & OHCI1394_busReset)) !(evt & OHCI1394_busReset))
return; return;
printk(KERN_DEBUG KBUILD_MODNAME ": IRQ " fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
"%08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt & OHCI1394_selfIDComplete ? " selfID" : "",
evt, evt & OHCI1394_RQPkt ? " AR_req" : "",
evt & OHCI1394_selfIDComplete ? " selfID" : "", evt & OHCI1394_RSPkt ? " AR_resp" : "",
evt & OHCI1394_RQPkt ? " AR_req" : "", evt & OHCI1394_reqTxComplete ? " AT_req" : "",
evt & OHCI1394_RSPkt ? " AR_resp" : "", evt & OHCI1394_respTxComplete ? " AT_resp" : "",
evt & OHCI1394_reqTxComplete ? " AT_req" : "", evt & OHCI1394_isochRx ? " IR" : "",
evt & OHCI1394_respTxComplete ? " AT_resp" : "", evt & OHCI1394_isochTx ? " IT" : "",
evt & OHCI1394_isochRx ? " IR" : "", evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "",
evt & OHCI1394_isochTx ? " IT" : "", evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "",
evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "",
evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", evt & OHCI1394_regAccessFail ? " regAccessFail" : "",
evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", evt & OHCI1394_busReset ? " busReset" : "",
evt & OHCI1394_regAccessFail ? " regAccessFail" : "", evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
evt & OHCI1394_busReset ? " busReset" : "", OHCI1394_RSPkt | OHCI1394_reqTxComplete |
evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | OHCI1394_respTxComplete | OHCI1394_isochRx |
OHCI1394_RSPkt | OHCI1394_reqTxComplete | OHCI1394_isochTx | OHCI1394_postedWriteErr |
OHCI1394_respTxComplete | OHCI1394_isochRx | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
OHCI1394_isochTx | OHCI1394_postedWriteErr | OHCI1394_regAccessFail | OHCI1394_busReset)
OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
OHCI1394_regAccessFail | OHCI1394_busReset)
? " ?" : ""); ? " ?" : "");
} }
...@@ -308,23 +306,22 @@ static void log_selfids(int node_id, int generation, int self_id_count, u32 *s) ...@@ -308,23 +306,22 @@ static void log_selfids(int node_id, int generation, int self_id_count, u32 *s)
if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS))) if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS)))
return; return;
printk(KERN_DEBUG KBUILD_MODNAME ": %d selfIDs, generation %d, " fw_notify("%d selfIDs, generation %d, local node ID %04x\n",
"local node ID %04x\n", self_id_count, generation, node_id); self_id_count, generation, node_id);
for (; self_id_count--; ++s) for (; self_id_count--; ++s)
if ((*s & 1 << 23) == 0) if ((*s & 1 << 23) == 0)
printk(KERN_DEBUG "selfID 0: %08x, phy %d [%c%c%c] " fw_notify("selfID 0: %08x, phy %d [%c%c%c] "
"%s gc=%d %s %s%s%s\n", "%s gc=%d %s %s%s%s\n",
*s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2), *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2),
speed[*s >> 14 & 3], *s >> 16 & 63, speed[*s >> 14 & 3], *s >> 16 & 63,
power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "", power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "",
*s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : ""); *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : "");
else else
printk(KERN_DEBUG "selfID n: %08x, phy %d " fw_notify("selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n",
"[%c%c%c%c%c%c%c%c]\n", *s, *s >> 24 & 63,
*s, *s >> 24 & 63, _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10),
_p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10), _p(s, 8), _p(s, 6), _p(s, 4), _p(s, 2));
_p(s, 8), _p(s, 6), _p(s, 4), _p(s, 2));
} }
static const char *evts[] = { static const char *evts[] = {
...@@ -373,15 +370,14 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) ...@@ -373,15 +370,14 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
evt = 0x1f; evt = 0x1f;
if (evt == OHCI1394_evt_bus_reset) { if (evt == OHCI1394_evt_bus_reset) {
printk(KERN_DEBUG "A%c evt_bus_reset, generation %d\n", fw_notify("A%c evt_bus_reset, generation %d\n",
dir, (header[2] >> 16) & 0xff); dir, (header[2] >> 16) & 0xff);
return; return;
} }
if (header[0] == ~header[1]) { if (header[0] == ~header[1]) {
printk(KERN_DEBUG "A%c %s, %s, %08x\n", fw_notify("A%c %s, %s, %08x\n",
dir, evts[evt], phys[header[0] >> 30 & 0x3], dir, evts[evt], phys[header[0] >> 30 & 0x3], header[0]);
header[0]);
return; return;
} }
...@@ -400,24 +396,23 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) ...@@ -400,24 +396,23 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
switch (tcode) { switch (tcode) {
case 0xe: case 0xa: case 0xe: case 0xa:
printk(KERN_DEBUG "A%c %s, %s\n", fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]);
dir, evts[evt], tcodes[tcode]);
break; break;
case 0x0: case 0x1: case 0x4: case 0x5: case 0x9: case 0x0: case 0x1: case 0x4: case 0x5: case 0x9:
printk(KERN_DEBUG "A%c spd %x tl %02x, " fw_notify("A%c spd %x tl %02x, "
"%04x -> %04x, %s, " "%04x -> %04x, %s, "
"%s, %04x%08x%s\n", "%s, %04x%08x%s\n",
dir, speed, header[0] >> 10 & 0x3f, dir, speed, header[0] >> 10 & 0x3f,
header[1] >> 16, header[0] >> 16, evts[evt], header[1] >> 16, header[0] >> 16, evts[evt],
tcodes[tcode], header[1] & 0xffff, header[2], specific); tcodes[tcode], header[1] & 0xffff, header[2], specific);
break; break;
default: default:
printk(KERN_DEBUG "A%c spd %x tl %02x, " fw_notify("A%c spd %x tl %02x, "
"%04x -> %04x, %s, " "%04x -> %04x, %s, "
"%s%s\n", "%s%s\n",
dir, speed, header[0] >> 10 & 0x3f, dir, speed, header[0] >> 10 & 0x3f,
header[1] >> 16, header[0] >> 16, evts[evt], header[1] >> 16, header[0] >> 16, evts[evt],
tcodes[tcode], specific); tcodes[tcode], specific);
} }
} }
...@@ -548,6 +543,11 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) ...@@ -548,6 +543,11 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
p.header_length = 12; p.header_length = 12;
p.payload_length = 0; p.payload_length = 0;
break; break;
default:
/* FIXME: Stop context, discard everything, and restart? */
p.header_length = 0;
p.payload_length = 0;
} }
p.payload = (void *) buffer + p.header_length; p.payload = (void *) buffer + p.header_length;
...@@ -1468,6 +1468,9 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) ...@@ -1468,6 +1468,9 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
reg_write(ohci, OHCI1394_HCControlClear, reg_write(ohci, OHCI1394_HCControlClear,
OHCI1394_HCControl_noByteSwapData); OHCI1394_HCControl_noByteSwapData);
reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
reg_write(ohci, OHCI1394_LinkControlClear,
OHCI1394_LinkControl_rcvPhyPkt);
reg_write(ohci, OHCI1394_LinkControlSet, reg_write(ohci, OHCI1394_LinkControlSet,
OHCI1394_LinkControl_rcvSelfID | OHCI1394_LinkControl_rcvSelfID |
OHCI1394_LinkControl_cycleTimerEnable | OHCI1394_LinkControl_cycleTimerEnable |
...@@ -1481,7 +1484,6 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) ...@@ -1481,7 +1484,6 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
ar_context_run(&ohci->ar_request_ctx); ar_context_run(&ohci->ar_request_ctx);
ar_context_run(&ohci->ar_response_ctx); ar_context_run(&ohci->ar_response_ctx);
reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000); reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
reg_write(ohci, OHCI1394_IntEventClear, ~0); reg_write(ohci, OHCI1394_IntEventClear, ~0);
reg_write(ohci, OHCI1394_IntMaskClear, ~0); reg_write(ohci, OHCI1394_IntMaskClear, ~0);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -297,37 +298,55 @@ EXPORT_SYMBOL(fw_send_request); ...@@ -297,37 +298,55 @@ EXPORT_SYMBOL(fw_send_request);
struct fw_phy_packet { struct fw_phy_packet {
struct fw_packet packet; struct fw_packet packet;
struct completion done; struct completion done;
struct kref kref;
}; };
static void static void phy_packet_release(struct kref *kref)
transmit_phy_packet_callback(struct fw_packet *packet, {
struct fw_card *card, int status) struct fw_phy_packet *p =
container_of(kref, struct fw_phy_packet, kref);
kfree(p);
}
static void transmit_phy_packet_callback(struct fw_packet *packet,
struct fw_card *card, int status)
{ {
struct fw_phy_packet *p = struct fw_phy_packet *p =
container_of(packet, struct fw_phy_packet, packet); container_of(packet, struct fw_phy_packet, packet);
complete(&p->done); complete(&p->done);
kref_put(&p->kref, phy_packet_release);
} }
void fw_send_phy_config(struct fw_card *card, void fw_send_phy_config(struct fw_card *card,
int node_id, int generation, int gap_count) int node_id, int generation, int gap_count)
{ {
struct fw_phy_packet p; struct fw_phy_packet *p;
long timeout = DIV_ROUND_UP(HZ, 10);
u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) |
PHY_CONFIG_ROOT_ID(node_id) | PHY_CONFIG_ROOT_ID(node_id) |
PHY_CONFIG_GAP_COUNT(gap_count); PHY_CONFIG_GAP_COUNT(gap_count);
p.packet.header[0] = data; p = kmalloc(sizeof(*p), GFP_KERNEL);
p.packet.header[1] = ~data; if (p == NULL)
p.packet.header_length = 8; return;
p.packet.payload_length = 0;
p.packet.speed = SCODE_100; p->packet.header[0] = data;
p.packet.generation = generation; p->packet.header[1] = ~data;
p.packet.callback = transmit_phy_packet_callback; p->packet.header_length = 8;
init_completion(&p.done); p->packet.payload_length = 0;
p->packet.speed = SCODE_100;
card->driver->send_request(card, &p.packet); p->packet.generation = generation;
wait_for_completion(&p.done); p->packet.callback = transmit_phy_packet_callback;
init_completion(&p->done);
kref_set(&p->kref, 2);
card->driver->send_request(card, &p->packet);
timeout = wait_for_completion_timeout(&p->done, timeout);
kref_put(&p->kref, phy_packet_release);
/* will leak p if the callback is never executed */
WARN_ON(timeout == 0);
} }
void fw_flush_transactions(struct fw_card *card) void fw_flush_transactions(struct fw_card *card)
...@@ -572,7 +591,8 @@ allocate_request(struct fw_packet *p) ...@@ -572,7 +591,8 @@ allocate_request(struct fw_packet *p)
break; break;
default: default:
BUG(); fw_error("ERROR - corrupt request received - %08x %08x %08x\n",
p->header[0], p->header[1], p->header[2]);
return NULL; return NULL;
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment