Skip to contentSkip to conversation

Xenon support

RFC PATCH In review Felix Domke 11 participants 26 messages Mar 7, 2007 – Mar 9, 2007

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

cover Xenon support

This series of patches add support for the Xbox 360 gaming console.

Note that these patches were written by different people, who want to remain anonymous. These drivers were written without hardware documentation being available.

There are probably more than some rough edges. Please comment and/or provide patches.

To actually run this, you need a special loader which exploits the recently announced vulnerability. This loader was developed seperately and should be available soon.

thanks,
Felix

--

#1 lore raw

PATCH 1/7 xenon: add PCI Vendor ID: Microsoft

---
 include/linux/pci_ids.h |    2 ++
 1 file changed, 2 insertions(+)
include/linux/pci_ids.h +2 -0
Index: linux-2.6.20/include/linux/pci_ids.h
===================================================================
@@ -2383,3 +2383,5 @@
 
 #define PCI_VENDOR_ID_QUICKNET		0x15E2
 #define PCI_DEVICE_ID_QUICKNET_XJ	0x0500
+
+#define PCI_VENDOR_ID_MICROSOFT		0x1414

--

#2 lore raw

PATCH 2/7 xenon: add platform support

In reply to Felix Domke

This patch adds platform support for the 'Xenon' platform (Xbox 360).

---
 arch/powerpc/Kconfig                     |    7 
 arch/powerpc/boot/Makefile               |    5 
 arch/powerpc/kernel/cputable.c           |   12 +
 arch/powerpc/platforms/Makefile          |    1 
 arch/powerpc/platforms/xenon/Makefile    |    4 
 arch/powerpc/platforms/xenon/interrupt.c |  303 +++++++++++++++++++++++++++++++
 arch/powerpc/platforms/xenon/interrupt.h |   11 +
 arch/powerpc/platforms/xenon/pci.c       |  188 +++++++++++++++++++
 arch/powerpc/platforms/xenon/setup.c     |  151 +++++++++++++++
 arch/powerpc/platforms/xenon/smp.c       |  157 ++++++++++++++++
 include/asm-powerpc/cputable.h           |    6 
 11 files changed, 845 insertions(+)
arch/powerpc/Kconfig +7 -0
Index: linux-2.6.20/arch/powerpc/Kconfig
===================================================================
@@ -463,6 +463,13 @@
 	select PPC_970_NAP
 	default y
 
+config PPC_XENON
+	bool "Xenon"
+	depends on PPC_MULTIPLATFORM  && PPC64
+	select PPC_RTAS
+	select PPC_NATIVE
+	default y
+
 config PPC_PREP
 	bool "PowerPC Reference Platform (PReP) based machines"
 	depends on PPC_MULTIPLATFORM && PPC32 && BROKEN
arch/powerpc/boot/Makefile +5 -0
Index: linux-2.6.20/arch/powerpc/boot/Makefile
===================================================================
@@ -149,6 +149,10 @@
 $(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits)
 	$(call cmd,wrap_initrd,miboot)
 
+$(obj)/zImage.xenon: vmlinux $(wrapperbits)
+	$(call cmd,wrap,chrp)
+	${CROSS}objcopy -O elf32-powerpc vmlinux vmlinux.xenon
+
 $(obj)/zImage.ps3: vmlinux
 	$(STRIP) -s -R .comment $< -o $@
 
@@ -161,6 +165,7 @@
 image-$(CONFIG_PPC_PSERIES)		+= zImage.pseries
 image-$(CONFIG_PPC_MAPLE)		+= zImage.pseries
 image-$(CONFIG_PPC_IBM_CELL_BLADE)	+= zImage.pseries
+image-$(CONFIG_PPC_XENON)		+= zImage.xenon
 image-$(CONFIG_PPC_PS3)			+= zImage.ps3
 image-$(CONFIG_PPC_CHRP)		+= zImage.chrp
 image-$(CONFIG_PPC_EFIKA)		+= zImage.chrp
arch/powerpc/kernel/cputable.c +12 -0
Index: linux-2.6.20/arch/powerpc/kernel/cputable.c
===================================================================
@@ -355,6 +355,18 @@
 		.num_pmcs		= 6,
 		.platform		= "pa6t",
 	},
+	{	/* Xenon */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value	= 0x00710000,
+		.cpu_name		= "Xenon",
+		.cpu_features		= CPU_FTRS_XENON,
+		.cpu_user_features	= COMMON_USER_PPC64 |
+			PPC_FEATURE_HAS_ALTIVEC_COMP |
+			PPC_FEATURE_SMT,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.platform		= "xenon",
+	},
 	{	/* default match */
 		.pvr_mask		= 0x00000000,
 		.pvr_value		= 0x00000000,
arch/powerpc/platforms/Makefile +1 -0
Index: linux-2.6.20/arch/powerpc/platforms/Makefile
===================================================================
@@ -18,3 +18,4 @@
 obj-$(CONFIG_PPC_CELL)		+= cell/
 obj-$(CONFIG_PPC_PS3)		+= ps3/
 obj-$(CONFIG_EMBEDDED6xx)	+= embedded6xx/
+obj-$(CONFIG_PPC_XENON)	  += xenon/
arch/powerpc/platforms/xenon/Makefile new file +4 -0
Index: linux-2.6.20/arch/powerpc/platforms/xenon/Makefile
===================================================================
@@ -0,0 +1,4 @@
+obj-$(CONFIG_PPC_XENON)		+= setup.o interrupt.o pci.o
+ifeq ($(CONFIG_SMP),y)
+obj-$(CONFIG_PPC_XENON)		+= smp.o
+endif
arch/powerpc/platforms/xenon/interrupt.c new file +303 -0

303 lines not on this page · raw message

arch/powerpc/platforms/xenon/interrupt.h new file +11 -0
Index: linux-2.6.20/arch/powerpc/platforms/xenon/interrupt.h
===================================================================
@@ -0,0 +1,11 @@
+#ifndef ASM_XENON_PIC_H
+#define ASM_XENON_PIC_H
+#ifdef __KERNEL__
+
+extern void xenon_init_irq_on_cpu(int cpu);
+extern void __init xenon_iic_init_IRQ(void);
+extern void xenon_cause_IPI(int target, int msg);
+extern void xenon_request_IPIs(void);
+
+#endif
+#endif /* ASM_XENON_PIC_H */
arch/powerpc/platforms/xenon/pci.c new file +188 -0

188 lines not on this page · raw message

arch/powerpc/platforms/xenon/setup.c new file +151 -0

151 lines not on this page · raw message

arch/powerpc/platforms/xenon/smp.c new file +157 -0

157 lines not on this page · raw message

include/asm-powerpc/cputable.h +6 -0
Index: linux-2.6.20/include/asm-powerpc/cputable.h
===================================================================
@@ -347,6 +347,12 @@
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
 	    CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG)
+#define CPU_FTRS_XENON ((CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
+	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
+	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
+	    CPU_FTR_CTRL )&~CPU_FTR_16M_PAGE)
+// | CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE  /* we need to setup large pages before, and we don't do that yet */
+
 #define CPU_FTRS_PA6T (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \

--

maintainer
#3 lore raw

Re: [patch 2/7] xenon: add platform support

Quoted 12 lines
arch/powerpc/platforms/xenon/interrupt.c new file +12 -0
+#define PRIO_IPI_4       0x08
+#define PRIO_IPI_3       0x10
+#define PRIO_SMM         0x14
+#define PRIO_SFCX        0x18
+#define PRIO_SATA_HDD    0x20
+#define PRIO_SATA_CDROM  0x24
+#define PRIO_OHCI_0      0x2c
+#define PRIO_EHCI_0      0x30
+#define PRIO_OHCI_1      0x34
+#define PRIO_EHCI_1      0x38
+#define PRIO_XMA         0x40
+#define PRIO_AUDIO       0x44

arch/powerpc/platforms/xenon/interrupt.c line 53

Quoted 10 lines
arch/powerpc/platforms/xenon/interrupt.c new file +10 -0
+#define PRIO_ENET        0x4C
+#define PRIO_XPS         0x54
+#define PRIO_GRAPHICS    0x58
+#define PRIO_PROFILER    0x60
+#define PRIO_BIU         0x64
+#define PRIO_IOC         0x68
+#define PRIO_FSB         0x6c
+#define PRIO_IPI_2       0x70
+#define PRIO_CLOCK       0x74
+#define PRIO_IPI_1       0x78

These should probably all come from the device tree instead of compile-time constants.

arch/powerpc/platforms/xenon/interrupt.c line 196

Quoted 6 lines
arch/powerpc/platforms/xenon/interrupt.c new file +6 -0
+void __init xenon_iic_init_IRQ(void)
+{
+	int i;
+	struct device_node *dn;
+
+	printk("XENON init IRQ\n");

needs a printk level, KERN_DEBUG or KERN_INFO.

arch/powerpc/platforms/xenon/interrupt.c line 206

Quoted 9 lines
arch/powerpc/platforms/xenon/interrupt.c new file +9 -0
+			/* search for our interrupt controller inside the device tree */
+	for (dn = NULL;
+	     (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
+		if (!device_is_compatible(dn,
+				     "xenon"))
+			continue;
+
+		irq_set_virq_count(0x80);
+		iic_base = ioremap_nocache(0x20000050000, 0x10000);

This should come from the 'reg' property of the above node.

Quoted 9 lines
arch/powerpc/platforms/xenon/interrupt.c new file +7 -0
+void xenon_cause_IPI(int target, int msg)
+{
+	int ipi_prio;
+
+	ipi_prio = ipi_to_prio(msg);
+
+	__raw_writeq( (0x10000<<target) | ipi_prio, iic_base + 0x10 +

hard_smp_processor_id() * 0x1000); +}
+

You seem to have a line wrapping problem and might need to fix your mail client.
Also, don't use __raw_writeq here. In order to access on-chip data, use out_be64().

arch/powerpc/platforms/xenon/pci.c line 170

Quoted 3 lines
arch/powerpc/platforms/xenon/pci.c new file +3 -0
+	hose->ops = &xenon_pci_ops;
+	hose->cfg_addr = ioremap(0xd0000000, 0x1000000);
+

The addresses should come from the device tree, don't hardcode them in the source.

arch/powerpc/platforms/xenon/setup.c line 17

Quoted 2 lines
arch/powerpc/platforms/xenon/setup.c new file +2 -0
+#define DEBUG
+

really?

arch/powerpc/platforms/xenon/setup.c line 67

Quoted 4 lines
arch/powerpc/platforms/xenon/setup.c new file +4 -0
+void __init xenon_pci_init(void);
+#ifdef CONFIG_SMP
+extern void smp_init_xenon(void);
+#endif

move these declarations to a header

arch/powerpc/platforms/xenon/setup.c line 80

Quoted 11 lines
arch/powerpc/platforms/xenon/setup.c new file +11 -0
+static void xenon_show_cpuinfo(struct seq_file *m)
+{
+	struct device_node *root;
+	const char *model = "";
+
+	root = of_find_node_by_path("/");
+	if (root)
+		model = get_property(root, "model", NULL);
+	seq_printf(m, "machine\t\t: CHRP %s\n", model);
+	of_node_put(root);
+}

CHRP???

arch/powerpc/platforms/xenon/setup.c line 93

Quoted 7 lines
arch/powerpc/platforms/xenon/setup.c new file +7 -0
+static void __init xenon_pcibios_fixup(void)
+{
+	struct pci_dev *dev = NULL;
+
+	for_each_pci_dev(dev)
+		pci_read_irq_line(dev);
+}

I guess you copied that from cell? You should not need it.

arch/powerpc/platforms/xenon/setup.c line 112

Quoted 4 lines
arch/powerpc/platforms/xenon/setup.c new file +4 -0
+	if (ROOT_DEV == 0) {
+		printk("No ramdisk, default root is /dev/hda2\n");
+		ROOT_DEV = Root_HDA2;
+	}

kill this, it's unnecessary (and probably wrong in your case)

arch/powerpc/platforms/xenon/setup.c line 129

Quoted 6 lines
arch/powerpc/platforms/xenon/setup.c new file +6 -0
+static int __init xenon_probe(void)
+{
+       hpte_init_native();
+
+       return 1;
+}

This definitely needs to check the device tree whether it's running on the right platform, otherwise you can not build a multiplatform kernel.

arch/powerpc/platforms/xenon/setup.c line 123

Quoted 2 lines
arch/powerpc/platforms/xenon/setup.c new file +2 -0
+void __init xenon_hpte_init(unsigned long htab_size);
+

move this to a header file

Quoted 1 line

+#include <asm/rtas.h>

rtas???

arch/powerpc/platforms/xenon/smp.c line 48

Quoted 6 lines
arch/powerpc/platforms/xenon/smp.c new file +6 -0
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+

Don't define your own macros like this, use the pr_debug() one from kernel.h.

arch/powerpc/platforms/xenon/smp.c line 105

Quoted 6 lines
arch/powerpc/platforms/xenon/smp.c new file +6 -0
+void smp_init_xenon(void);
+
+extern void xenon_request_IPIs(void);
+extern void xenon_init_irq_on_cpu(int cpu);
+
+extern void xenon_cause_IPI(int target, int msg);

extern declarations should go to header files, not into the implementation.

arch/powerpc/platforms/xenon/smp.c line 152

Quoted 13 lines
arch/powerpc/platforms/xenon/smp.c new file +13 -0
+	/* Mark threads which are still spinning in hold loops. */
+	if (cpu_has_feature(CPU_FTR_SMT)) {
+		for_each_present_cpu(i) {
+			if (i % 2 == 0)
+				/*
+				 * Even-numbered logical cpus correspond to
+				 * primary threads.
+				 */
+				cpu_set(i, of_spin_map);
+		}
+	} else {
+		of_spin_map = cpu_present_map;
+	}

Yes, we wrote code like that for CBE, but that doesn't mean it's good enough to copy it ;-)

Relying on the cpu number to mean something specific is bad, and we're trying to get rid of that in other places, so you should not introduce it again here.

include/asm-powerpc/cputable.h

Quoted 5 lines
include/asm-powerpc/cputable.h +5 -0
+#define CPU_FTRS_XENON ((CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
+	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
+	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
+	    CPU_FTR_CTRL )&~CPU_FTR_16M_PAGE)
+// | CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE  /* we need to setup large

If the CPU doesn't do 16M pages, you need to make sure that CPU_FTRS_ALWAYS is adapted properly.

#4 lore raw

PATCH 3/7 xenon: udbg support (ugly)

In reply to Felix Domke

This adds support for a serial kernel output on the Xenon platform.

---
 arch/powerpc/kernel/misc_64.S |    2 +-
 arch/powerpc/kernel/udbg.c    |   14 ++++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)
arch/powerpc/kernel/misc_64.S +1 -1
Index: linux-2.6.20/arch/powerpc/kernel/misc_64.S
===================================================================
@@ -247,7 +247,7 @@
 	blr
 
 
-#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
+#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_XENON)
 /*
  * Do an IO access in real mode
  */
arch/powerpc/kernel/udbg.c +14 -0
Index: linux-2.6.20/arch/powerpc/kernel/udbg.c
===================================================================
@@ -25,6 +25,18 @@
  * Early debugging facilities. You can enable _one_ of these via .config,
  * if you do so your kernel _will not boot_ on anything else. Be careful.
  */
+
+extern u8 real_readb(volatile u8 __iomem  *addr);
+extern void real_writeb(u8 data, volatile u8 __iomem *addr);
+
+void udbg_xenon_real_putc(char c)
+{
+	if (c == '\n')
+		udbg_xenon_real_putc('\r');
+	while (!(real_readb((void*)0x80000200ea001018ULL)&0x02));
+	real_writeb(c, (void*)0x80000200ea001014ULL);
+}
+
 void __init udbg_early_init(void)
 {
 #if defined(CONFIG_PPC_EARLY_DEBUG_LPAR)
@@ -46,6 +58,7 @@
 	/* For iSeries - hit Ctrl-x Ctrl-x to see the output */
 	udbg_init_iseries();
 #endif
+	udbg_putc = udbg_xenon_real_putc;
 }
 
 /* udbg library, used by xmon et al */
@@ -150,6 +163,7 @@
 		printk(KERN_INFO "early console immortal !\n");
 		return;
 	}
+	return;
 	unregister_console(&udbg_console);
 	early_console_initialized = 0;
 }

--

#5 lore raw

Re: [patch 3/7] xenon: udbg support (ugly)

Quoted 22 lines · Felix Domke
arch/powerpc/kernel/udbg.c +12 -0
@@ -25,6 +25,18 @@
  * Early debugging facilities. You can enable _one_ of these via .config,
  * if you do so your kernel _will not boot_ on anything else. Be careful.
  */
+
+extern u8 real_readb(volatile u8 __iomem  *addr);
+extern void real_writeb(u8 data, volatile u8 __iomem *addr);
+
+void udbg_xenon_real_putc(char c)
+{
+	if (c == '\n')
+		udbg_xenon_real_putc('\r');
+	while (!(real_readb((void*)0x80000200ea001018ULL)&0x02));
+	real_writeb(c, (void*)0x80000200ea001014ULL);
+}
+
 void __init udbg_early_init(void)
 {
 #if defined(CONFIG_PPC_EARLY_DEBUG_LPAR)

arch/powerpc/kernel/udbg.c line 61

Quoted 4 lines
arch/powerpc/kernel/udbg.c +1 -0
@@ -46,6 +58,7 @@
 	/* For iSeries - hit Ctrl-x Ctrl-x to see the output */
 	udbg_init_iseries();
 #endif
+	udbg_putc = udbg_xenon_real_putc;

No #ifdef?

arch/powerpc/kernel/udbg.c line 166

Quoted 8 lines
arch/powerpc/kernel/udbg.c +1 -0
 }
 
 /* udbg library, used by xmon et al */
@@ -150,6 +163,7 @@
 		printk(KERN_INFO "early console immortal !\n");
 		return;
 	}
+	return;

??

arch/powerpc/kernel/udbg.c line 169

Quoted 3 lines
arch/powerpc/kernel/udbg.c +0 -0
 	unregister_console(&udbg_console);
 	early_console_initialized = 0;
 }

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#6 lore raw

PATCH 4/7 xenon: add southbridge ethernet support

In reply to Felix Domke

This adds support for the Ethernet controller used in the Xenon southbridge.

It is based on the skeleton code, and works surprisingly good. It has some rough edges, especially regarding SMP locks, and probably needs some code cleanup.

---
 drivers/net/Kconfig     |    4 
 drivers/net/Makefile    |    2 
 drivers/net/xenon_net.c |  725 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 731 insertions(+)
drivers/net/Kconfig +4 -0
Index: linux-2.6.20/drivers/net/Kconfig
===================================================================
@@ -1622,6 +1622,10 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called 8139cp.  This is recommended.
 
+config XENON_ENET
+	tristate "Xenon Fast Ethernet Adapter support"
+	depends on NET_PCI && PCI
+
 config 8139TOO
 	tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
 	depends on NET_PCI && PCI
drivers/net/Makefile +2 -0
Index: linux-2.6.20/drivers/net/Makefile
===================================================================
@@ -217,3 +217,5 @@
 obj-$(CONFIG_FS_ENET) += fs_enet/
 
 obj-$(CONFIG_NETXEN_NIC) += netxen/
+
+obj-$(CONFIG_XENON_ENET) += xenon_net.o
drivers/net/xenon_net.c new file +725 -0

725 lines not on this page · raw message

--

maintainer
#7 lore raw

Re: [patch 4/7] xenon: add southbridge ethernet support

Quoted 6 lines · On Wednesday 07 March 2007 19:01:48 Felix Domke wrote:

This adds support for the Ethernet controller used in the Xenon southbridge.

It is based on the skeleton code, and works surprisingly good. It has some rough edges, especially regarding SMP locks, and probably needs some code cleanup.

Right, though it appears that some of the code that needs to be cleaned up even comes from the skeleton driver...

It's also the wrong mailing list to post this to, it should go to netdev.

Furthermore, this driver should have MODULE_LICENSE, MODULE_AUTHOR and MODULE_DESCRIPTION field, like any loadable module.

Quoted 4 lines

+0100 @@ -0,0 +1,725 @@
+/*
+ * based on skeleton code.
+ */

Your other files have a long copyright notice, why the inconsistency?

drivers/net/xenon_net.c line 22

Quoted 5 lines
drivers/net/xenon_net.c new file +5 -0
+#define assert(expr) \
+        if(!(expr)) {					\
+        printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
+        #expr,__FILE__,__FUNCTION__,__LINE__);		\
+        }

use BUG_ON() instead of assert()

Quoted 11 lines
drivers/net/xenon_net.c new file +11 -0
+/* Symbolic offsets to registers. */
+enum XENONNET_registers {
+	TxConfig = 0x00,
+	TxDescriptorBase = 0x04,
+	TxDescriptorStatus = 0x0C,
+	RxConfig = 0x10,
+	RxDescriptorBase = 0x14,
+	InterruptStatus = 0x20,
+	InterruptMask = 0x24,
+	Config0 = 0x28,
+	Power = 0x30,

drivers/net/xenon_net.c line 65

Quoted 10 lines
drivers/net/xenon_net.c new file +10 -0
+	PhyConfig = 0x40,
+	PhyControl = 0x44,
+	Config1 = 0x50,
+	RetryCount = 0x54,
+	MulticastFilterControl = 0x60,
+	Address0 = 0x62,
+	MulticastHash = 0x68,
+	MaxPacketSize = 0x78,
+	Address1 = 0x7A
+};

Don't use mixed case identifiers.

drivers/net/xenon_net.c line 98

Quoted 8 lines
drivers/net/xenon_net.c new file +4 -0
+static int xenon_net_open (struct net_device *dev);
+static void xenon_net_tx_timeout (struct net_device *dev);
+static void xenon_net_init_ring (struct net_device *dev);
+static int xenon_net_start_xmit (struct sk_buff *skb, struct net_device

*dev); +static irqreturn_t xenon_net_interrupt(int irq, void *dev_id);

drivers/net/xenon_net.c new file +3 -0
+static int xenon_net_close (struct net_device *dev);
+static void xenon_net_hw_start (struct net_device *dev);
+static int xenon_net_poll(struct net_device *dev, int *budget);

avoid forward declarations for static functions

drivers/net/xenon_net.c line 105

Quoted 6 lines
drivers/net/xenon_net.c new file +3 -0
+#define XENONNET_W8(reg, val8)	writeb ((val8), ioaddr + (reg))
+#define XENONNET_W16(reg, val16)	writew ((val16), ioaddr + (reg))
+#define XENONNET_W32(reg, val32)	do { writel ((val32), ioaddr + (reg));  }

while (0) +#define XENONNET_R8(reg) readb (ioaddr + (reg))

drivers/net/xenon_net.c new file +2 -0
+#define XENONNET_R16(reg)		readw (ioaddr + (reg))
+#define XENONNET_R32(reg)		((u32) readl (ioaddr + (reg)))

get rid of these, just use the {read,write}{b,w,l} directly

drivers/net/xenon_net.c line 127

Quoted 1 line
drivers/net/xenon_net.c new file +1 -0
+		printk ("EXIT, returning -ENOMEM\n");

use proper printk levels or kill this output. also watch your whitespace.

drivers/net/xenon_net.c line 130

Quoted 1 line
drivers/net/xenon_net.c new file +1 -0
+	SET_MODULE_OWNER(dev);

SET_MODULE_OWNER is deprecated, just remove this.

drivers/net/xenon_net.c line 215

Quoted 1 line
drivers/net/xenon_net.c new file +1 -0
+	memcpy(dev->dev_addr, "\0\0\1\2\3\4", 6);

use random_ether_address

drivers/net/xenon_net.c line 593

Quoted 4 lines
drivers/net/xenon_net.c new file +4 -0
+	while (1)
+	{
+		int index = atomic_read(&tp->rx_next);
+		volatile u32 *descr = tp->rx_descriptor_base + index * 0x10;

'volatile' is most likely wrong here, I guess you need to convert this to use the right barriers.

Quoted 22 lines
drivers/net/xenon_net.c new file +22 -0
+static irqreturn_t xenon_net_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct xenon_net_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	u32 status;
+
+	spin_lock (&tp->lock);
+
+	status = XENONNET_R32(InterruptStatus);
+
+	if (status & 0x40)
+	{
+		if (netif_rx_schedule_prep(dev)) {
+			status &= ~0x40;
+			__netif_rx_schedule (dev);
+		}
+	}
+
+	if (status & 4)
+	{
+		xenon_net_tx_interrupt(dev, tp, ioaddr);

drivers/net/xenon_net.c line 671

Quoted 10 lines
drivers/net/xenon_net.c new file +10 -0
+		status &= ~0x4;
+	}
+
+//	if (status)
+//		printk("other interrupt: %08x\n", status);
+
+	spin_unlock (&tp->lock);
+
+	return IRQ_HANDLED;
+}

Usually, you'd want to use a single poll function for both receive and transmit, and call __netif_rx_schedule in both cases.

drivers/net/xenon_net.c line 684

Quoted 2 lines
drivers/net/xenon_net.c new file +2 -0
+	spin_lock_irqsave (&tp->lock, flags);
+	spin_unlock_irqrestore (&tp->lock, flags);

huh?

drivers/net/xenon_net.c line 686

Quoted 2 lines
drivers/net/xenon_net.c new file +2 -0
+	synchronize_irq (dev->irq);
+	free_irq (dev->irq, dev);

free_irq does syncronize_irq itself, iirc

	Arnd <><
#8 lore raw

PATCH 5/7 xenon: add SATA support

In reply to Felix Domke

This adds support for the HDD and DVD SATA controller on the xenon southbridge.

It also disables ATA_TFLAG_POLLING in libata-core, which prevented the DVD drive from being detected. It needs to be investigated what exactly is wrong here.

---
 drivers/ata/Kconfig       |    8 +
 drivers/ata/Makefile      |    1 
 drivers/ata/libata-core.c |    2 
 drivers/ata/sata_xenon.c  |  272 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 282 insertions(+), 1 deletion(-)
drivers/ata/Kconfig +8 -0
Index: linux-2.6.20/drivers/ata/Kconfig
===================================================================
@@ -123,6 +123,14 @@
 
 	  If unsure, say N.
 
+config SATA_XENON
+	tristate "Xenon SATA support"
+	depends on PCI
+	help
+	  This option enables support for Xenon southbridge.
+
+	  If unsure, say N.
+
 config SATA_ULI
 	tristate "ULi Electronics SATA support"
 	depends on PCI
drivers/ata/Makefile +1 -0
Index: linux-2.6.20/drivers/ata/Makefile
===================================================================
@@ -11,6 +11,7 @@
 obj-$(CONFIG_SATA_VIA)		+= sata_via.o
 obj-$(CONFIG_SATA_VITESSE)	+= sata_vsc.o
 obj-$(CONFIG_SATA_SIS)		+= sata_sis.o
+obj-$(CONFIG_SATA_XENON)	+= sata_xenon.o
 obj-$(CONFIG_SATA_SX4)		+= sata_sx4.o
 obj-$(CONFIG_SATA_NV)		+= sata_nv.o
 obj-$(CONFIG_SATA_ULI)		+= sata_uli.o
drivers/ata/libata-core.c +1 -1
Index: linux-2.6.20/drivers/ata/libata-core.c
===================================================================
@@ -1478,7 +1478,7 @@
 	}
 
 	tf.protocol = ATA_PROT_PIO;
-	tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
+//	tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
 
 	err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
 				     id, sizeof(id[0]) * ATA_ID_WORDS);
drivers/ata/sata_xenon.c new file +272 -0

272 lines not on this page · raw message

--

#9 lore raw

Re: [patch 5/7] xenon: add SATA support

Quoted 1 line · Felix Domke

This adds support for the HDD and DVD SATA controller on the xenon southbridge.

Pleas post this to [email protected] in the future.

Quoted 48 lines

It also disables ATA_TFLAG_POLLING in libata-core, which prevented the DVD drive from being detected. It needs to be investigated what exactly is wrong here.

---
 drivers/ata/Kconfig       |    8 +
 drivers/ata/Makefile      |    1 
 drivers/ata/libata-core.c |    2 
 drivers/ata/sata_xenon.c  |  272 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 282 insertions(+), 1 deletion(-)

Index: linux-2.6.20/drivers/ata/Kconfig
===================================================================

drivers/ata/Kconfig +8 -0
@@ -123,6 +123,14 @@
 
 	  If unsure, say N.
 
+config SATA_XENON
+	tristate "Xenon SATA support"
+	depends on PCI
+	help
+	  This option enables support for Xenon southbridge.
+
+	  If unsure, say N.
+
 config SATA_ULI
 	tristate "ULi Electronics SATA support"
 	depends on PCI

Index: linux-2.6.20/drivers/ata/Makefile
===================================================================

drivers/ata/Makefile +1 -0
@@ -11,6 +11,7 @@
 obj-$(CONFIG_SATA_VIA)		+= sata_via.o
 obj-$(CONFIG_SATA_VITESSE)	+= sata_vsc.o
 obj-$(CONFIG_SATA_SIS)		+= sata_sis.o
+obj-$(CONFIG_SATA_XENON)	+= sata_xenon.o
 obj-$(CONFIG_SATA_SX4)		+= sata_sx4.o
 obj-$(CONFIG_SATA_NV)		+= sata_nv.o
 obj-$(CONFIG_SATA_ULI)		+= sata_uli.o

Index: linux-2.6.20/drivers/ata/libata-core.c
===================================================================

drivers/ata/libata-core.c line 1481

Quoted 5 lines
drivers/ata/libata-core.c +1 -1
@@ -1478,7 +1478,7 @@
 	}
 
 	tf.protocol = ATA_PROT_PIO;
-	tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
+//	tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */

I doubt that this could *ever* get accepted.

Quoted 150 lines
drivers/ata/libata-core.c +0 -0
 	err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
 				     id, sizeof(id[0]) * ATA_ID_WORDS);

Index: linux-2.6.20/drivers/ata/sata_xenon.c
===================================================================

drivers/ata/sata_xenon.c new file +143 -0
@@ -0,0 +1,272 @@
+/*
+ *  sata_xenon.c - SATA support for xenon southbridge
+ *
+ *  based on sata_sis.c, modifications by anonymous xbox360 hacker,
+ *
+ *  		    Please ALWAYS copy [email protected]
+ *		    on emails.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ *  libata documentation is available via 'make {ps|pdf}docs',
+ *  as Documentation/DocBook/libata.*
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+
+#define DRV_NAME	"sata_xenon"
+#define DRV_VERSION	"0.1"
+
+	/* small note: it's completely unknown whether the xenon southbridge sata
+	   is really based on SiS technology.
+	   Most of SATA is standardized anyway.
+
+
+	   So, we have these two pci devices, one for each port.
+
+	   They have two BARs, one for the IDE registers (0..7,
+	   altstatus/devctl is +0xA), and one for the BMDMA.
+
+	   SCR seem to be sis-like in pci config space, but that should
+	   be verified!
+
+	   Note on the DVD-ROM part:
+
+	   The drives usually require some tweaks to be usable under linux.
+
+	   You either need to hack the scsi layer, or, in case of the GDR3120L,
+	   set 'modeB' in the bootloader.
+	*/
+
+enum {
+	/* PCI configuration registers */
+	SIS_SCR_BASE		= 0xc0, /* sata0 phy SCR registers */
+};
+
+extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
+						 const struct ata_port_info *port);
+
+static int xenon_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static u32 xenon_scr_read (struct ata_port *ap, unsigned int sc_reg);
+static void xenon_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+
+static const struct pci_device_id xenon_pci_tbl[] = {
+	{ PCI_VDEVICE(MICROSOFT, 0x5803), 0 },
+	{ PCI_VDEVICE(MICROSOFT, 0x5802), 0 },
+
+	{ }	/* terminate list */
+};
+
+static struct pci_driver xenon_pci_driver = {
+	.name			= DRV_NAME,
+	.id_table		= xenon_pci_tbl,
+	.probe			= xenon_init_one,
+	.remove			= ata_pci_remove_one,
+};
+
+static struct scsi_host_template xenon_sht = {
+	.module			= THIS_MODULE,
+	.name			= DRV_NAME,
+	.ioctl			= ata_scsi_ioctl,
+	.queuecommand		= ata_scsi_queuecmd,
+	.can_queue		= ATA_DEF_QUEUE,
+	.this_id		= ATA_SHT_THIS_ID,
+	.sg_tablesize		= ATA_MAX_PRD,
+	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
+	.emulated		= ATA_SHT_EMULATED,
+	.use_clustering		= ATA_SHT_USE_CLUSTERING,
+	.proc_name		= DRV_NAME,
+	.dma_boundary		= ATA_DMA_BOUNDARY,
+	.slave_configure	= ata_scsi_slave_config,
+	.slave_destroy		= ata_scsi_slave_destroy,
+	.bios_param		= ata_std_bios_param,
+};
+
+static const struct ata_port_operations xenon_ops = {
+	.port_disable		= ata_port_disable,
+	.tf_load		= ata_tf_load,
+	.tf_read		= ata_tf_read,
+	.check_status		= ata_check_status,
+	.exec_command		= ata_exec_command,
+	.dev_select		= ata_std_dev_select,
+	.bmdma_setup            = ata_bmdma_setup,
+	.bmdma_start            = ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
+	.qc_prep		= ata_qc_prep,
+	.qc_issue		= ata_qc_issue_prot,
+	.data_xfer		= ata_pio_data_xfer,
+	.freeze			= ata_bmdma_freeze,
+	.thaw			= ata_bmdma_thaw,
+	.error_handler		= ata_bmdma_error_handler,
+	.post_internal_cmd	= ata_bmdma_post_internal_cmd,
+	.irq_handler		= ata_interrupt,
+	.irq_clear		= ata_bmdma_irq_clear,
+	.scr_read		= xenon_scr_read,
+	.scr_write		= xenon_scr_write,
+	.port_start		= ata_port_start,
+	.port_stop		= ata_port_stop,
+	.host_stop		= ata_host_stop,
+};
+
+static struct ata_port_info xenon_port_info = {
+	.sht		= &xenon_sht,
+	.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+	.pio_mask	= 0x1f,
+	.mwdma_mask	= 0x7,
+	.udma_mask	= 0x7f,
+	.port_ops	= &xenon_ops,
+};
+

drivers/ata/sata_xenon.c line 153

Quoted 10 lines
drivers/ata/sata_xenon.c new file +10 -0
+
+MODULE_DESCRIPTION("low-level driver for Xenon Southbridge SATA controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, xenon_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, int device)
+{
+	unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
+

Why we need device and port_no arguments here?

drivers/ata/sata_xenon.c line 164

Quoted 11 lines
drivers/ata/sata_xenon.c new file +11 -0
+	return addr;
+}
+
+static u32 xenon_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device);
+	u32 val;
+
+	if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
+		return 0; /* assume no error */

Since SCR_ERROR == 1, this check seems broken.

drivers/ata/sata_xenon.c line 177

Quoted 13 lines
drivers/ata/sata_xenon.c new file +13 -0
+
+	pci_read_config_dword(pdev, cfg_addr, &val);
+
+	return val;
+}
+
+static void xenon_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr, pdev->device);
+
+	if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
+		return;

Same here.

Quoted 10 lines
drivers/ata/sata_xenon.c new file +10 -0
+
+	pci_write_config_dword(pdev, cfg_addr, val);
+}
+
+static u32 xenon_scr_read (struct ata_port *ap, unsigned int sc_reg)
+{
+	if (sc_reg > SCR_CONTROL)
+		return 0xffffffffU;
+
+	return xenon_scr_cfg_read(ap, sc_reg);

drivers/ata/sata_xenon.c line 197

Quoted 10 lines
drivers/ata/sata_xenon.c new file +10 -0
+}
+
+static void xenon_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
+{
+	if (sc_reg > SCR_CONTROL)
+		return;
+
+	xenon_scr_cfg_write(ap, sc_reg, val);
+}
+

Reading SATA regs via config. space... isn't that ugly? :-]

Quoted 65 lines
drivers/ata/sata_xenon.c new file +65 -0
+static int xenon_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	static int printed_version;
+	struct ata_probe_ent *probe_ent = NULL;
+	int rc;
+	int pci_dev_busy = 0;
+
+	if (!printed_version++)
+		dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
+	rc = pci_enable_device(pdev);
+	if (rc)
+		return rc;
+
+	rc = pci_request_regions(pdev, DRV_NAME);
+	if (rc) {
+		pci_dev_busy = 1;
+		goto err_out;
+	}
+
+	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+	if (rc)
+		goto err_out_regions;
+	rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+	if (rc)
+		goto err_out_regions;
+
+	probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), &xenon_port_info);
+	if (!probe_ent) {
+		rc = -ENOMEM;
+		goto err_out_regions;
+	}
+
+	probe_ent->irq = pdev->irq;
+	probe_ent->irq_flags = IRQF_SHARED;
+
+	probe_ent->port->cmd_addr = (long)ioremap(pci_resource_start(pdev, 0), PAGE_SIZE);
+	probe_ent->port->altstatus_addr = probe_ent->port->cmd_addr + 0xa;
+	probe_ent->port->ctl_addr = probe_ent->port->cmd_addr + 0xa;
+	probe_ent->port->bmdma_addr = (long)ioremap(pci_resource_start(pdev, 1), PAGE_SIZE);
+	ata_std_ports(probe_ent->port);
+	probe_ent->n_ports = 1;
+
+	pci_set_master(pdev);
+	pci_intx(pdev, 1);
+
+	/* FIXME: check ata_device_add return value */
+	ata_device_add(probe_ent);
+	kfree(probe_ent);
+
+	return 0;
+
+err_out_regions:
+	pci_release_regions(pdev);
+
+err_out:
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
+	return rc;
+
+}
+
+static int __init xenon_init(void)
+{
+	return pci_register_driver(&xenon_pci_driver);

drivers/ata/sata_xenon.c line 272

Quoted 10 lines
drivers/ata/sata_xenon.c new file +10 -0
+}
+
+static void __exit xenon_exit(void)
+{
+	pci_unregister_driver(&xenon_pci_driver);
+}
+
+module_init(xenon_init);
+module_exit(xenon_exit);
+

MBR, Sergei

#10 lore raw

Re: [patch 5/7] xenon: add SATA support

Quoted 4 lines · Sergei Shtylyov
Quoted 2 lines · Felix Domke

This adds support for the HDD and DVD SATA controller on the xenon southbridge.

Pleas post this to [email protected] in the future.

I'll do.

Quoted 10 lines
Quoted 9 lines

It also disables ATA_TFLAG_POLLING in libata-core, which prevented the DVD drive
from being detected. It needs to be investigated what exactly is wrong here.

     tf.protocol = ATA_PROT_PIO;
(quoted diff) +1 -1
-    tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
+//    tf.flags |= ATA_TFLAG_POLLING; /* for polling presence

detection */

I doubt that this could *ever* get accepted.

It was not meant to be accepted, but to work around the problem which was introduced in 2.6.19. I have far too less knowledge of the SATA layer to understand why this flag exactly causes the detection of the DVD-Drive fail.

As said, this needs to be investigated, and fixed (in the driver, of course, not in the subsystem).

Quoted 6 lines

drivers/ata/sata_xenon.c line 153

Quoted 5 lines

+static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, int device)

drivers/ata/sata_xenon.c new file +3 -0
+{
+    unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
+

Why we need device and port_no arguments here?

As there is only one device/port per PCI device, the arguments should probably be removed from this function, right.

Quoted 3 lines

drivers/ata/sata_xenon.c line 164

Quoted 2 lines
drivers/ata/sata_xenon.c new file +2 -0
+    if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
+        return 0; /* assume no error */

Since SCR_ERROR == 1, this check seems broken.

Why?

Felix

#11 lore raw

Re: [patch 5/7] xenon: add SATA support

Quoted 21 lines · Felix Domke
Quoted 6 lines
Quoted 2 lines · Felix Domke

This adds support for the HDD and DVD SATA controller on the xenon southbridge.

Pleas post this to [email protected] in the future.

I'll do.

Quoted 11 lines
Quoted 9 lines

It also disables ATA_TFLAG_POLLING in libata-core, which prevented the DVD drive
from being detected. It needs to be investigated what exactly is wrong here.

    tf.protocol = ATA_PROT_PIO;
(quoted diff) +1 -1
-    tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
+//    tf.flags |= ATA_TFLAG_POLLING; /* for polling presence

detection */

I doubt that this could *ever* get accepted.

Quoted 7 lines

It was not meant to be accepted, but to work around the problem which was introduced in 2.6.19. I have far too less knowledge of the SATA layer to understand why this flag exactly causes the detection of the DVD-Drive fail.

As said, this needs to be investigated, and fixed (in the driver, of course, not in the subsystem).

Yeah, I've missed it in the patch description. :-<

Quoted 11 lines
Quoted 7 lines

drivers/ata/sata_xenon.c line 153

Quoted 5 lines

+static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, int device)

drivers/ata/sata_xenon.c new file +3 -0
+{
+    unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
+

Why we need device and port_no arguments here?

As there is only one device/port per PCI device, the arguments should probably be removed from this function, right.

Quoted 6 lines
Quoted 4 lines

drivers/ata/sata_xenon.c line 164

Quoted 2 lines
drivers/ata/sata_xenon.c new file +2 -0
+    if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
+        return 0; /* assume no error */

Since SCR_ERROR == 1, this check seems broken.

Why?

Since get_scr_cfg_addr() will never return 1... oh wait, we're checking
another variable... :-<
Maybe worth merging to get_scr_cfg_addr() then, along with (sc_reg >
SCR_CONTROL) checks, to avoid duplicate code.

Quoted 1 line

Felix

MBR, Sergei

#12 lore raw

RFC PATCH 5/7 xenon: add SATA support

In reply to Felix Domke

This adds support for the HDD and DVD SATA controller on the xenon southbridge.

It also disables ATA_TFLAG_POLLING in libata-core, which prevented the DVD drive
from being detected. It needs to be investigated what exactly is wrong here.

---
 drivers/ata/Kconfig       |    8 +
 drivers/ata/Makefile      |    1
 drivers/ata/libata-core.c |    2
 drivers/ata/sata_xenon.c  |  272
++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 282 insertions(+), 1 deletion(-)

Index: linux-2.6.20/drivers/ata/Kconfig
===================================================================
--- linux-2.6.20.orig/drivers/ata/Kconfig 2007-03-07 19:01:12.000000000
+0100
+++ linux-2.6.20/drivers/ata/Kconfig 2007-03-07 19:01:22.000000000 +0100
@@ -123,6 +123,14 @@

If unsure, say N.

+config SATA_XENON
+ tristate "Xenon SATA support"
+ depends on PCI
+ help
+ This option enables support for Xenon southbridge.
+
+ If unsure, say N.
+
config SATA_ULI
tristate "ULi Electronics SATA support"
depends on PCI
Index: linux-2.6.20/drivers/ata/Makefile
===================================================================
--- linux-2.6.20.orig/drivers/ata/Makefile 2007-03-07 19:01:12.000000000
+0100
+++ linux-2.6.20/drivers/ata/Makefile 2007-03-07 19:01:22.000000000 +0100
@@ -11,6 +11,7 @@
obj-$(CONFIG_SATA_VIA) += sata_via.o
obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o
obj-$(CONFIG_SATA_SIS) += sata_sis.o
+obj-$(CONFIG_SATA_XENON) += sata_xenon.o
obj-$(CONFIG_SATA_SX4) += sata_sx4.o
obj-$(CONFIG_SATA_NV) += sata_nv.o
obj-$(CONFIG_SATA_ULI) += sata_uli.o
Index: linux-2.6.20/drivers/ata/libata-core.c
===================================================================
--- linux-2.6.20.orig/drivers/ata/libata-core.c 2007-03-07
19:01:12.000000000 +0100
+++ linux-2.6.20/drivers/ata/libata-core.c 2007-03-07 19:01:22.000000000
+0100
@@ -1478,7 +1478,7 @@
}

tf.protocol = ATA_PROT_PIO;
- tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
+// tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */

err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
id, sizeof(id[0]) * ATA_ID_WORDS);

drivers/ata/sata_xenon.c new file +0 -0
Index: linux-2.6.20/drivers/ata/sata_xenon.c
===================================================================

+0100
@@ -0,0 +1,272 @@
+/*
+ * sata_xenon.c - SATA support for xenon southbridge
+ *
+ * based on sata_sis.c, modifications by anonymous xbox360 hacker,
+ *
+ * Please ALWAYS copy [email protected]
+ * on emails.
+ *

+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

+ *
+ *
+ * libata documentation is available via 'make {ps|pdf}docs',
+ * as Documentation/DocBook/libata.*
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+
+#define DRV_NAME "sata_xenon"
+#define DRV_VERSION "0.1"
+
+ /* small note: it's completely unknown whether the xenon southbridge sata
+ is really based on SiS technology.
+ Most of SATA is standardized anyway.
+
+
+ So, we have these two pci devices, one for each port.
+
+ They have two BARs, one for the IDE registers (0..7,
+ altstatus/devctl is +0xA), and one for the BMDMA.
+
+ SCR seem to be sis-like in pci config space, but that should
+ be verified!
+
+ Note on the DVD-ROM part:
+
+ The drives usually require some tweaks to be usable under linux.
+
+ You either need to hack the scsi layer, or, in case of the GDR3120L,
+ set 'modeB' in the bootloader.
+ */
+
+enum {
+ /* PCI configuration registers */
+ SIS_SCR_BASE = 0xc0, /* sata0 phy SCR registers */
+};
+
+extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
+ const struct ata_port_info *port);
+
+static int xenon_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static u32 xenon_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void xenon_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+
+static const struct pci_device_id xenon_pci_tbl[] = {
+ { PCI_VDEVICE(MICROSOFT, 0x5803), 0 },
+ { PCI_VDEVICE(MICROSOFT, 0x5802), 0 },
+
+ { } /* terminate list */
+};
+
+static struct pci_driver xenon_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = xenon_pci_tbl,
+ .probe = xenon_init_one,
+ .remove = ata_pci_remove_one,
+};
+
+static struct scsi_host_template xenon_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = ATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+};
+
+static const struct ata_port_operations xenon_ops = {
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+ .data_xfer = ata_pio_data_xfer,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+ .scr_read = xenon_scr_read,
+ .scr_write = xenon_scr_write,
+ .port_start = ata_port_start,
+ .port_stop = ata_port_stop,
+ .host_stop = ata_host_stop,
+};
+
+static struct ata_port_info xenon_port_info = {
+ .sht = &xenon_sht,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x7,
+ .udma_mask = 0x7f,
+ .port_ops = &xenon_ops,
+};
+
+
+MODULE_DESCRIPTION("low-level driver for Xenon Southbridge SATA controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, xenon_pci_tbl); +MODULE_VERSION(DRV_VERSION);
+
+static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, int device)
+{
+ unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
+
+ return addr;
+}
+
+static u32 xenon_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) +{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg,
pdev->device);
+ u32 val;
+
+ if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
+ return 0; /* assume no error */
+
+ pci_read_config_dword(pdev, cfg_addr, &val);
+
+ return val;
+}
+
+static void xenon_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr, pdev->device);
+
+ if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
+ return;
+
+ pci_write_config_dword(pdev, cfg_addr, val);
+}
+
+static u32 xenon_scr_read (struct ata_port *ap, unsigned int sc_reg) +{
+ if (sc_reg > SCR_CONTROL)
+ return 0xffffffffU;
+
+ return xenon_scr_cfg_read(ap, sc_reg);
+}
+
+static void xenon_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
+{
+ if (sc_reg > SCR_CONTROL)
+ return;
+
+ xenon_scr_cfg_write(ap, sc_reg, val);
+}
+
+static int xenon_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ static int printed_version;
+ struct ata_probe_ent *probe_ent = NULL;
+ int rc;
+ int pci_dev_busy = 0;
+
+ if (!printed_version++)
+ dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc) {
+ pci_dev_busy = 1;
+ goto err_out;
+ }
+
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ goto err_out_regions;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ goto err_out_regions;
+
+ probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), &xenon_port_info);
+ if (!probe_ent) {
+ rc = -ENOMEM;
+ goto err_out_regions;
+ }
+
+ probe_ent->irq = pdev->irq;
+ probe_ent->irq_flags = IRQF_SHARED;
+
+ probe_ent->port->cmd_addr = (long)ioremap(pci_resource_start(pdev, 0),
PAGE_SIZE);
+ probe_ent->port->altstatus_addr = probe_ent->port->cmd_addr + 0xa;
+ probe_ent->port->ctl_addr = probe_ent->port->cmd_addr + 0xa;
+ probe_ent->port->bmdma_addr = (long)ioremap(pci_resource_start(pdev,
1), PAGE_SIZE);
+ ata_std_ports(probe_ent->port);
+ probe_ent->n_ports = 1;
+
+ pci_set_master(pdev);
+ pci_intx(pdev, 1);
+
+ /* FIXME: check ata_device_add return value */
+ ata_device_add(probe_ent);
+ kfree(probe_ent);
+
+ return 0;
+
+err_out_regions:
+ pci_release_regions(pdev);
+
+err_out:
+ if (!pci_dev_busy)
+ pci_disable_device(pdev);
+ return rc;
+
+}
+
+static int __init xenon_init(void)
+{
+ return pci_register_driver(&xenon_pci_driver);
+}
+
+static void __exit xenon_exit(void)
+{
+ pci_unregister_driver(&xenon_pci_driver);
+}
+
+module_init(xenon_init);
+module_exit(xenon_exit);
+

--

_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev

#13 lore raw

Re: [patch 5/7] [RFC] xenon: add SATA support

Hello,

Generally looks good. Some questions and suggestions follow.

Review line 1481

Quoted 12 lines · Felix Domke

Index: linux-2.6.20/drivers/ata/libata-core.c
===================================================================
--- linux-2.6.20.orig/drivers/ata/libata-core.c 2007-03-07
19:01:12.000000000 +0100
+++ linux-2.6.20/drivers/ata/libata-core.c 2007-03-07 19:01:22.000000000
+0100

(quoted diff) +1 -1
@@ -1478,7 +1478,7 @@
 	}
 
 	tf.protocol = ATA_PROT_PIO;
-	tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
+//	tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */

Polling IDENTIFY doesn't work for you? Care to explain how it's broken?

drivers/ata/sata_xenon.c

Quoted 11 lines

Index: linux-2.6.20/drivers/ata/sata_xenon.c
===================================================================

drivers/ata/sata_xenon.c new file +7 -0
+0100
+	   Note on the DVD-ROM part:
+
+	   The drives usually require some tweaks to be usable under linux.
+
+	   You either need to hack the scsi layer, or, in case of the GDR3120L,
+	   set 'modeB' in the bootloader.

Care to explain it further? Or is it some cryptic embedded stuff?

drivers/ata/sata_xenon.c

Quoted 2 lines
drivers/ata/sata_xenon.c new file +2 -0
+extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
+						 const struct ata_port_info *port);

This is an internal function and if you do this, your driver won't build as a kernel module. Please do as other drivers do. probe_ent is in the process of being removed, so looking ugly is okay for the time being.

drivers/ata/sata_xenon.c

Quoted 9 lines
drivers/ata/sata_xenon.c new file +4 -0
+static u32 xenon_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg,

pdev->device);

drivers/ata/sata_xenon.c new file +4 -0
+	u32 val;
+
+	if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
+		return 0; /* assume no error */

Interesting, SError isn't there while other regs are?

drivers/ata/sata_xenon.c

Quoted 7 lines
drivers/ata/sata_xenon.c new file +7 -0
+static u32 xenon_scr_read (struct ata_port *ap, unsigned int sc_reg)
+{
+	if (sc_reg > SCR_CONTROL)
+		return 0xffffffffU;
+
+	return xenon_scr_cfg_read(ap, sc_reg);
+}

Just collapse xenon_scr_cfg_read() into xenon_scr_read().

drivers/ata/sata_xenon.c

Quoted 8 lines

+static void xenon_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)

drivers/ata/sata_xenon.c new file +6 -0
+{
+	if (sc_reg > SCR_CONTROL)
+		return;
+
+	xenon_scr_cfg_write(ap, sc_reg, val);
+}

Ditto for write.

Quoted 4 lines

+static int xenon_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)

drivers/ata/sata_xenon.c new file +2 -0
+{
+	static int printed_version;

drivers/ata/sata_xenon.c

Quoted 10 lines
drivers/ata/sata_xenon.c new file +10 -0
+	struct ata_probe_ent *probe_ent = NULL;
+	int rc;
+	int pci_dev_busy = 0;
+
+	if (!printed_version++)
+		dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
+	rc = pci_enable_device(pdev);
+	if (rc)
+		return rc;

New drivers are generally accepted into libata-dev#upstream branch, and it looks a bit different in the init path. If you're a gitter, please generate patch against libata-dev#upstream, if not the latest -mm should be good enough.

Thanks.

Signature · 1 line
tejun
#14 lore raw

Re: [patch 5/7] [RFC] xenon: add SATA support

In reply to Felix Domke
Quoted 7 lines · Felix Domke

This adds support for the HDD and DVD SATA controller on the xenon southbridge.

It also disables ATA_TFLAG_POLLING in libata-core, which prevented the DVD drive
from being detected. It needs to be investigated what exactly is wrong here.

It sounds like everyone agrees this needs to be investigated, so I won't belabor the point :)

Quoted 259 lines
---
 drivers/ata/Kconfig       |    8 +
 drivers/ata/Makefile      |    1
 drivers/ata/libata-core.c |    2
 drivers/ata/sata_xenon.c  |  272
++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 282 insertions(+), 1 deletion(-)

Index: linux-2.6.20/drivers/ata/Kconfig
===================================================================
--- linux-2.6.20.orig/drivers/ata/Kconfig 2007-03-07 19:01:12.000000000
+0100
+++ linux-2.6.20/drivers/ata/Kconfig 2007-03-07 19:01:22.000000000 +0100

(quoted diff) +8 -0
@@ -123,6 +123,14 @@
 
 	  If unsure, say N.
 
+config SATA_XENON
+	tristate "Xenon SATA support"
+	depends on PCI
+	help
+	  This option enables support for Xenon southbridge.
+
+	  If unsure, say N.
+
 config SATA_ULI
 	tristate "ULi Electronics SATA support"
 	depends on PCI

Index: linux-2.6.20/drivers/ata/Makefile
===================================================================
--- linux-2.6.20.orig/drivers/ata/Makefile 2007-03-07 19:01:12.000000000
+0100
+++ linux-2.6.20/drivers/ata/Makefile 2007-03-07 19:01:22.000000000 +0100

(quoted diff) +1 -0
@@ -11,6 +11,7 @@
 obj-$(CONFIG_SATA_VIA)		+= sata_via.o
 obj-$(CONFIG_SATA_VITESSE)	+= sata_vsc.o
 obj-$(CONFIG_SATA_SIS)		+= sata_sis.o
+obj-$(CONFIG_SATA_XENON)	+= sata_xenon.o
 obj-$(CONFIG_SATA_SX4)		+= sata_sx4.o
 obj-$(CONFIG_SATA_NV)		+= sata_nv.o
 obj-$(CONFIG_SATA_ULI)		+= sata_uli.o

Index: linux-2.6.20/drivers/ata/libata-core.c
===================================================================
--- linux-2.6.20.orig/drivers/ata/libata-core.c 2007-03-07
19:01:12.000000000 +0100
+++ linux-2.6.20/drivers/ata/libata-core.c 2007-03-07 19:01:22.000000000
+0100

(quoted diff) +1 -1
@@ -1478,7 +1478,7 @@
 	}
 
 	tf.protocol = ATA_PROT_PIO;
-	tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
+//	tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
 
 	err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
 				     id, sizeof(id[0]) * ATA_ID_WORDS);

Index: linux-2.6.20/drivers/ata/sata_xenon.c
===================================================================

drivers/ata/sata_xenon.c new file +73 -0
+0100
@@ -0,0 +1,272 @@
+/*
+ *  sata_xenon.c - SATA support for xenon southbridge
+ *
+ *  based on sata_sis.c, modifications by anonymous xbox360 hacker,
+ *
+ *  		    Please ALWAYS copy [email protected]
+ *		    on emails.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ *  libata documentation is available via 'make {ps|pdf}docs',
+ *  as Documentation/DocBook/libata.*
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+
+#define DRV_NAME	"sata_xenon"
+#define DRV_VERSION	"0.1"
+
+	/* small note: it's completely unknown whether the xenon southbridge sata
+	   is really based on SiS technology.
+	   Most of SATA is standardized anyway.
+
+
+	   So, we have these two pci devices, one for each port.
+
+	   They have two BARs, one for the IDE registers (0..7,
+	   altstatus/devctl is +0xA), and one for the BMDMA.
+
+	   SCR seem to be sis-like in pci config space, but that should
+	   be verified!
+
+	   Note on the DVD-ROM part:
+
+	   The drives usually require some tweaks to be usable under linux.
+
+	   You either need to hack the scsi layer, or, in case of the GDR3120L,
+	   set 'modeB' in the bootloader.
+	*/
+
+enum {
+	/* PCI configuration registers */
+	SIS_SCR_BASE		= 0xc0, /* sata0 phy SCR registers */
+};
+
+extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
+						 const struct ata_port_info *port);
+
+static int xenon_init_one (struct pci_dev *pdev, const struct

pci_device_id *ent);

drivers/ata/sata_xenon.c new file +2 -0
+static u32 xenon_scr_read (struct ata_port *ap, unsigned int sc_reg);
+static void xenon_scr_write (struct ata_port *ap, unsigned int sc_reg,

u32 val);

drivers/ata/sata_xenon.c new file +71 -0
+
+static const struct pci_device_id xenon_pci_tbl[] = {
+	{ PCI_VDEVICE(MICROSOFT, 0x5803), 0 },
+	{ PCI_VDEVICE(MICROSOFT, 0x5802), 0 },
+
+	{ }	/* terminate list */
+};
+
+static struct pci_driver xenon_pci_driver = {
+	.name			= DRV_NAME,
+	.id_table		= xenon_pci_tbl,
+	.probe			= xenon_init_one,
+	.remove			= ata_pci_remove_one,
+};
+
+static struct scsi_host_template xenon_sht = {
+	.module			= THIS_MODULE,
+	.name			= DRV_NAME,
+	.ioctl			= ata_scsi_ioctl,
+	.queuecommand		= ata_scsi_queuecmd,
+	.can_queue		= ATA_DEF_QUEUE,
+	.this_id		= ATA_SHT_THIS_ID,
+	.sg_tablesize		= ATA_MAX_PRD,
+	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
+	.emulated		= ATA_SHT_EMULATED,
+	.use_clustering		= ATA_SHT_USE_CLUSTERING,
+	.proc_name		= DRV_NAME,
+	.dma_boundary		= ATA_DMA_BOUNDARY,
+	.slave_configure	= ata_scsi_slave_config,
+	.slave_destroy		= ata_scsi_slave_destroy,
+	.bios_param		= ata_std_bios_param,
+};
+
+static const struct ata_port_operations xenon_ops = {
+	.port_disable		= ata_port_disable,
+	.tf_load		= ata_tf_load,
+	.tf_read		= ata_tf_read,
+	.check_status		= ata_check_status,
+	.exec_command		= ata_exec_command,
+	.dev_select		= ata_std_dev_select,
+	.bmdma_setup            = ata_bmdma_setup,
+	.bmdma_start            = ata_bmdma_start,
+	.bmdma_stop		= ata_bmdma_stop,
+	.bmdma_status		= ata_bmdma_status,
+	.qc_prep		= ata_qc_prep,
+	.qc_issue		= ata_qc_issue_prot,
+	.data_xfer		= ata_pio_data_xfer,
+	.freeze			= ata_bmdma_freeze,
+	.thaw			= ata_bmdma_thaw,
+	.error_handler		= ata_bmdma_error_handler,
+	.post_internal_cmd	= ata_bmdma_post_internal_cmd,
+	.irq_handler		= ata_interrupt,
+	.irq_clear		= ata_bmdma_irq_clear,
+	.scr_read		= xenon_scr_read,
+	.scr_write		= xenon_scr_write,
+	.port_start		= ata_port_start,
+	.port_stop		= ata_port_stop,
+	.host_stop		= ata_host_stop,
+};
+
+static struct ata_port_info xenon_port_info = {
+	.sht		= &xenon_sht,
+	.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+	.pio_mask	= 0x1f,
+	.mwdma_mask	= 0x7,
+	.udma_mask	= 0x7f,
+	.port_ops	= &xenon_ops,
+};
+
+
+MODULE_DESCRIPTION("low-level driver for Xenon Southbridge SATA

controller");

drivers/ata/sata_xenon.c new file +5 -0
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, xenon_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int

sc_reg, int device)

drivers/ata/sata_xenon.c new file +10 -0
+{
+	unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
+
+	return addr;
+}
+
+static u32 xenon_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg,

pdev->device);

drivers/ata/sata_xenon.c new file +11 -0
+	u32 val;
+
+	if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
+		return 0; /* assume no error */
+
+	pci_read_config_dword(pdev, cfg_addr, &val);
+
+	return val;
+}
+
+static void xenon_scr_cfg_write (struct ata_port *ap, unsigned int scr,

u32 val)

drivers/ata/sata_xenon.c new file +19 -0
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr, pdev->device);
+
+	if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
+		return;
+
+	pci_write_config_dword(pdev, cfg_addr, val);
+}
+
+static u32 xenon_scr_read (struct ata_port *ap, unsigned int sc_reg)
+{
+	if (sc_reg > SCR_CONTROL)
+		return 0xffffffffU;
+
+	return xenon_scr_cfg_read(ap, sc_reg);
+}
+
+static void xenon_scr_write (struct ata_port *ap, unsigned int sc_reg,

u32 val)

drivers/ata/sata_xenon.c

Quoted 6 lines
drivers/ata/sata_xenon.c new file +6 -0
+{
+	if (sc_reg > SCR_CONTROL)
+		return;
+
+	xenon_scr_cfg_write(ap, sc_reg, val);
+}

as noted, there is no need for two levels of scr_read/write functions. collapse each into a single read and single write function.

Quoted 10 lines

+static int xenon_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)

drivers/ata/sata_xenon.c new file +8 -0
+{
+	static int printed_version;
+	struct ata_probe_ent *probe_ent = NULL;
+	int rc;
+	int pci_dev_busy = 0;
+
+	if (!printed_version++)
+		dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");

drivers/ata/sata_xenon.c

Quoted 10 lines
drivers/ata/sata_xenon.c new file +10 -0
+
+	rc = pci_enable_device(pdev);
+	if (rc)
+		return rc;
+
+	rc = pci_request_regions(pdev, DRV_NAME);
+	if (rc) {
+		pci_dev_busy = 1;
+		goto err_out;
+	}

would be nice for you to update these against iomap, as found in 2.6.21-rc

drivers/ata/sata_xenon.c

Quoted 6 lines
drivers/ata/sata_xenon.c new file +6 -0
+	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+	if (rc)
+		goto err_out_regions;
+	rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+	if (rc)
+		goto err_out_regions;

shouldn't be needed, this is default

Quoted 14 lines
drivers/ata/sata_xenon.c new file +10 -0
+	probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), &xenon_port_info);
+	if (!probe_ent) {
+		rc = -ENOMEM;
+		goto err_out_regions;
+	}
+
+	probe_ent->irq = pdev->irq;
+	probe_ent->irq_flags = IRQF_SHARED;
+
+	probe_ent->port->cmd_addr = (long)ioremap(pci_resource_start(pdev, 0),

PAGE_SIZE);

drivers/ata/sata_xenon.c new file +3 -0
+	probe_ent->port->altstatus_addr = probe_ent->port->cmd_addr + 0xa;
+	probe_ent->port->ctl_addr = probe_ent->port->cmd_addr + 0xa;
+	probe_ent->port->bmdma_addr = (long)ioremap(pci_resource_start(pdev,
Quoted 1 line

1), PAGE_SIZE);

this needs updating for 2.6.21-rc, to get rid of the nasty casts and lack of ioremap() error handling

otherwise, seems pretty small and straightforward

#15 lore raw

PATCH 6/7 xenon: add SMC support

In reply to Felix Domke

This adds lowlevel support for the "System Management Controller" on the Xenon southbridge, which controls power, the frontpanel leds, infrared remote, tilt switch, AVIP detection, RTC and DVD tray control.

It requires a userspace daemon.

---
 drivers/char/Kconfig     |    6 +
 drivers/char/Makefile    |    1 
 drivers/char/xenon_smc.c |  280 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 287 insertions(+)
drivers/char/Kconfig +6 -0
Index: linux-2.6.20/drivers/char/Kconfig
===================================================================
@@ -350,6 +350,12 @@
 	  this case.  If you have never heard about all this, it's safe to
 	  say N.
 
+config XENON_SMC
+	bool "Xenon SMC"
+	depends on PPC_XENON
+	help
+	  SMC controller in the Xbox 360.
+
 config STALLION
 	tristate "Stallion EasyIO or EC8/32 support"
 	depends on STALDRV && BROKEN_ON_SMP
drivers/char/Makefile +1 -0
Index: linux-2.6.20/drivers/char/Makefile
===================================================================
@@ -55,6 +55,7 @@
 obj-$(CONFIG_HVCS)		+= hvcs.o
 obj-$(CONFIG_SGI_MBCS)		+= mbcs.o
 obj-$(CONFIG_BRIQ_PANEL)	+= briq_panel.o
+obj-$(CONFIG_XENON_SMC)  += xenon_smc.o
 
 obj-$(CONFIG_PRINTER)		+= lp.o
 obj-$(CONFIG_TIPAR)		+= tipar.o
drivers/char/xenon_smc.c new file +280 -0

280 lines not on this page · raw message

--

maintainer
#16 lore raw

Re: [patch 6/7] xenon: add SMC support

Quoted 1 line · On Wednesday 07 March 2007 19:01:50 Felix Domke wrote:

It requires a userspace daemon.

Is that available somewhere? You should probably list a URL for this in the driver and/or changelog

drivers/char/Kconfig line 358

Quoted 6 lines
drivers/char/Kconfig +6 -0
+config XENON_SMC
+	bool "Xenon SMC"
+	depends on PPC_XENON
+	help
+	  SMC controller in the Xbox 360.
+

Please expand the acronym here. It's not a particularly unique TLA after all.

drivers/char/xenon_smc.c line 22

Quoted 8 lines
drivers/char/xenon_smc.c new file +8 -0
+struct xenon_smc
+{
+	void __iomem *base;
+	unsigned long is_active;
+	wait_queue_head_t wait;
+};
+
+static struct xenon_smc *first_smc;

Why do you think you need the global instance variable? Normally, this should be pointed to by the pci device private data.

Quoted 14 lines
drivers/char/xenon_smc.c new file +14 -0
+#define to_smc(pdev) dev_get_drvdata(&pdev->dev)
+
+static int get_smc(struct xenon_smc *ctx, u8 *msg);
+static void send_smc(struct xenon_smc *ctx, void *msg);
+static irqreturn_t xenon_smc_irq(int irq, void *dev_id);
+static ssize_t smc_write(struct file *file, const char __user *data,
+				size_t len, loff_t *ppos);
+static int smc_ioctl(struct inode *inode, struct file *file,
+				unsigned int cmd, unsigned long arg);
+static ssize_t smc_read(struct file *file, char __user *data,
+				size_t len, loff_t *ppos);
+static int smc_open(struct inode *inode, struct file *file);
+static int smc_release(struct inode *inode, struct file *file);
+static int xenon_smc_init_one (struct pci_dev *pdev, const struct
Quoted 2 lines

pci_device_id *ent); +static void __devexit xenon_smc_remove(struct pci_dev *pdev);

Don't do forward declarations of static functions, please instead reorder them so you don't need these.

drivers/char/xenon_smc.c line 66

Quoted 5 lines
drivers/char/xenon_smc.c new file +5 -0
+static struct miscdevice smc_miscdev = {
+	.minor =  RTC_MINOR,
+	.name =   "smc",
+	.fops =	  &smc_fops,
+};

You can't grab the RTC device number if you don't support the respective interfaces. Use a dynamic minor number instead!

Quoted 15 lines
drivers/char/xenon_smc.c new file +15 -0
+static int get_smc(struct xenon_smc *ctx, u8 *msg)
+{
+	if (readl(ctx->base + 0x94) & 4)
+	{
+		u32 *message = (u32*)msg;
+		int i;
+		writel(4, ctx->base + 0x94);
+		for (i=0; i<4; ++i)
+			message[i] = __raw_readl(ctx->base + 0x90);
+		writel(0, ctx->base + 0x94);
+		return 1;
+	}
+	return 0;
+}
+

drivers/char/xenon_smc.c line 97

Quoted 10 lines
drivers/char/xenon_smc.c new file +10 -0
+static void send_smc(struct xenon_smc *ctx, void *msg)
+{
+	while (!(readl(ctx->base + 0x84) & 4));
+	writel(4, ctx->base + 0x84);
+	__raw_writel(*(u32*)(msg+0), ctx->base + 0x80);
+	__raw_writel(*(u32*)(msg+4), ctx->base + 0x80);
+	__raw_writel(*(u32*)(msg+8), ctx->base + 0x80);
+	__raw_writel(*(u32*)(msg+12), ctx->base + 0x80);
+	writel(0, ctx->base + 0x84);
+}

This needs to be cleaned up:

- don't use __raw_read/write on pci devices
- in the endless loop, use cpu_relax()
- avoid the casts if you can

Quoted 4 lines
drivers/char/xenon_smc.c new file +4 -0
+static ssize_t smc_write(struct file *file, const char __user *data,
+			     size_t len, loff_t *ppos)
+{
+	unsigned char msg[16];

drivers/char/xenon_smc.c line 126

Quoted 10 lines
drivers/char/xenon_smc.c new file +10 -0
+	if (len != 16)
+		return -EINVAL;
+
+	if (copy_from_user(msg, data, 16))
+		return -EFAULT;
+
+	send_smc(first_smc, msg);
+
+	return 16;
+}

You can get the pointer to the smc from file->f_dentry->d_inode->i_private if you put it in there

drivers/char/xenon_smc.c line 132

Quoted 5 lines
drivers/char/xenon_smc.c new file +5 -0
+static int smc_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg)
+{
+	return -ENODEV;
+}

please kill this function, it's not needed.

Quoted 26 lines
drivers/char/xenon_smc.c new file +26 -0
+static ssize_t smc_read(struct file *file, char __user *data,
+				size_t len, loff_t *ppos)
+{
+	struct xenon_smc *ctx = first_smc;
+	int ret;
+	u8 msg[0x10];
+
+	if (len != 16)
+		return -EINVAL;
+
+	if (!(readl(ctx->base + 0x94) & 4))
+	{
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+
+		ret = wait_event_interruptible(ctx->wait, readl(ctx->base + 0x94) & 4);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (get_smc(ctx, msg) == 0)
+		return -EAGAIN;
+
+	if (copy_to_user(data, msg, 0x10))
+		return -EFAULT;
+

drivers/char/xenon_smc.c line 169

Quoted 10 lines
drivers/char/xenon_smc.c new file +10 -0
+	return 0x10;
+}
+
+static int smc_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(0, &first_smc->is_active))
+		return -EBUSY;
+
+	return nonseekable_open(inode, file);
+}

This doesn't guarantee that you have only one fd to the device, you can still get multiple copies through dup or fork.

drivers/char/xenon_smc.c line 216

Quoted 4 lines
drivers/char/xenon_smc.c new file +4 -0
+
+	rc = misc_register(&smc_miscdev);
+	if (rc != 0)
+	{

You should be consistant with the indentation, opening braces here and in other places (except function bodies) go at the end of the previous line.

It's also more common to write 'if (!rc)' than comparing return values against 0 or NULL.

	Arnd <><
#17 lore raw

Re: [patch 6/7] xenon: add SMC support

In reply to Felix Domke
Quoted 3 lines · Felix Domke

This adds lowlevel support for the "System Management Controller" on the Xenon southbridge, which controls power, the frontpanel leds, infrared remote, tilt switch, AVIP detection, RTC and DVD tray control.

Unlike Arndt, I'd suggest that these three lines appear in the C file as well. I've spent too many days wondering what some some file was supposed to be doing, because the author didn't even bother to mention something as basic as this. This is particularly important when documentation is not generally available.

--linas

#18 lore raw
In reply to Felix Domke
Quoted 5 lines · Felix Domke

This series of patches add support for the Xbox 360 gaming console.

Note that these patches were written by different people, who want to remain anonymous. These drivers were written without hardware documentation being available.

Taking anonymous contributions to the kernel goes against the Developer's Certificate of Origin. Are you sure you can certify it's origin and are willing to take responsibility for the code?

Personally, I'd NAK this whole series.

josh

#19 lore raw
Quoted 12 lines · Josh Boyer
Quoted 4 lines · Felix Domke

This series of patches add support for the Xbox 360 gaming console. Note that these patches were written by different people, who want to remain anonymous. These drivers were written without hardware documentation being available.

Taking anonymous contributions to the kernel goes against the Developer's Certificate of Origin. Are you sure you can certify it's origin and are willing to take responsibility for the code?

Quoted 3 lines
Quoted 3 lines

(c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.

This is true for the patch series. I understand that as far as the original authors want to remain anonymous, this isn't worth a cent.

My guess is that the original authors either need to take resposibility for their code, or the code needs to be rewritten from scratch. I hope to be able to fix that up in the next days.

Felix

#20 lore raw
In reply to Josh Boyer
Quoted 7 lines · Josh Boyer
Quoted 5 lines · Felix Domke

This series of patches add support for the Xbox 360 gaming console.

Note that these patches were written by different people, who want to remain anonymous. These drivers were written without hardware documentation being available.

Quoted 5 lines

Taking anonymous contributions to the kernel goes against the Developer's Certificate of Origin. Are you sure you can certify it's origin and are willing to take responsibility for the code?

Personally, I'd NAK this whole series.

The whole serie can't be merged anyway, the patches aren't in good enough shape.

Regarding the legal status I think the serie can't be merged at least not by any of the maintainer for the reason you mention.

What should happen at this stage is that somebody writes a documentation of the hardware based on those patches and somebody else writes patches based on that documentation.

The fact that the initial patches were posted publically make the process a bit harder but still somewhat possible (if the final code is obviously not inherited from the original one in any way).

Ben.

#21 lore raw

PATCH 7/7 xenon: add framebuffer support (ugly)

In reply to Felix Domke

This adds support for a framebuffer on the "Xenos" graphics chip used in the Xbox 360 machine. It requires a pre-initialized framebuffer.

The major problem is that the graphics chip only supports a 'tiled' mode, thus this patch also uses some serious ugly patches to allow the framebuffer console to handle this. So this patch is given just for completeness, to have a working console output, and of course not meant for inclusion into the kernel.

This patch can probably be rewritten using the deferred io support in a much nicer way.

---
 drivers/video/Kconfig     |    9 +
 drivers/video/Makefile    |    1 
 drivers/video/cfbimgblt.c |   23 +--
 drivers/video/xenonfb.c   |  337 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fb.h        |   12 +
 5 files changed, 373 insertions(+), 9 deletions(-)
drivers/video/Kconfig +9 -0
Index: linux-2.6.20/drivers/video/Kconfig
===================================================================
@@ -568,6 +568,15 @@
 	help
 	  This is the frame buffer device driver for the Intel-based Macintosh
 
+config FB_XENON
+	bool "Xbox 360 Framebuffer Support"
+	depends on (FB = y) && PPC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Microsoft Xbox 360.
+
 config FB_HGA
 	tristate "Hercules mono graphics support"
 	depends on FB && X86
drivers/video/Makefile +1 -0
Index: linux-2.6.20/drivers/video/Makefile
===================================================================
@@ -104,6 +104,7 @@
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_VESA)             += vesafb.o
 obj-$(CONFIG_FB_IMAC)             += imacfb.o
+obj-$(CONFIG_FB_XENON)            += xenonfb.o
 obj-$(CONFIG_FB_VGA16)            += vga16fb.o vgastate.o
 obj-$(CONFIG_FB_OF)               += offb.o
 
drivers/video/cfbimgblt.c +14 -9
Index: linux-2.6.20/drivers/video/cfbimgblt.c
===================================================================
@@ -72,8 +72,13 @@
 	0x00000000, 0xffffffff
 };
 
-#define FB_WRITEL fb_writel
-#define FB_READL  fb_readl
+#if 0
+#define FB_WRITEL(p,b,addr) fb_writel(b,addr)
+#define FB_READL(p,addr)  fb_readl(addr)
+#else
+#define FB_READL(p,addr)  fb_readl(xenon_convert(p, addr))
+#define FB_WRITEL(p,b,addr) fb_writel(b, xenon_convert(p, addr))
+#endif
 
 static inline void color_imageblit(const struct fb_image *image, 
 				   struct fb_info *p, u8 __iomem *dst1, 
@@ -97,7 +102,7 @@
 		
 		if (start_index) {
 			u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0, start_index));
-			val = FB_READL(dst) & start_mask;
+			val = FB_READL(p, dst) & start_mask;
 			shift = start_index;
 		}
 		while (n--) {
@@ -109,7 +114,7 @@
 			color <<= FB_LEFT_POS(bpp);
 			val |= FB_SHIFT_HIGH(color, shift);
 			if (shift >= null_bits) {
-				FB_WRITEL(val, dst++);
+				FB_WRITEL(p, val, dst++);
 	
 				val = (shift == null_bits) ? 0 : 
 					FB_SHIFT_LOW(color, 32 - shift);
@@ -121,7 +126,7 @@
 		if (shift) {
 			u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
 
-			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
+			FB_WRITEL(p, (FB_READL(p, dst) & end_mask) | val, dst);
 		}
 		dst1 += p->fix.line_length;
 		if (pitch_index) {
@@ -162,7 +167,7 @@
 		/* write leading bits */
 		if (start_index) {
 			u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index));
-			val = FB_READL(dst) & start_mask;
+			val = FB_READL(p, dst) & start_mask;
 			shift = start_index;
 		}
 
@@ -173,7 +178,7 @@
 			
 			/* Did the bitshift spill bits to the next long? */
 			if (shift >= null_bits) {
-				FB_WRITEL(val, dst++);
+				FB_WRITEL(p, val, dst++);
 				val = (shift == null_bits) ? 0 :
 					FB_SHIFT_LOW(color,32 - shift);
 			}
@@ -186,7 +191,7 @@
  		if (shift) {
 			u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
 
-			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
+			FB_WRITEL(p, (FB_READL(p, dst) & end_mask) | val, dst);
 		}
 		
 		dst1 += pitch;
@@ -251,7 +256,7 @@
 		for (j = k; j--; ) {
 			shift -= ppw;
 			end_mask = tab[(*src >> shift) & bit_mask];
-			FB_WRITEL((end_mask & eorx)^bgx, dst++);
+			FB_WRITEL(p, (end_mask & eorx)^bgx, dst++);
 			if (!shift) { shift = 8; src++; }		
 		}
 		dst1 += p->fix.line_length;
include/linux/fb.h +12 -0
Index: linux-2.6.20/include/linux/fb.h
===================================================================
@@ -907,6 +907,18 @@
 	}
 }
 
+static inline int *xenon_convert(struct fb_info *p, int *addr)
+{
+	int index = ((char*)addr) - ((char*)p->screen_base);
+	int y = index / (p->fix.line_length);
+	int x = index % (p->fix.line_length)/4;
+	unsigned int base = ((((y & ~31)*p->var.xres) + (x & ~31)*32 ) +
+	 (((x&3) + ((y&1)<<2) + ((x&28)<<1) + ((y&30)<<5)) ^ ((y&8)<<2))) * 4;
+
+	return (int*)(((char*)p->screen_base)+base);
+}
+
+
 /* drivers/video/fbsysfs.c */
 extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
 extern void framebuffer_release(struct fb_info *info);
drivers/video/xenonfb.c new file +337 -0

337 lines not on this page · raw message

--

#22 lore raw
In reply to Felix Domke
Quoted 4 lines · On Wed, 07 Mar 2007 19:01:44 +0100 Felix Domke <[email protected]> wrote:

Note that these patches were written by different people, who want to remain anonymous. These drivers were written without hardware documentation being available.

Sorry, but given the anonymity requirement above, I do not want to even read these patches. Tracking of the pedigree of code in Linux has become an issue and deevelopers want to be anonymous really pokes a big hole in that.

--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/

#23 lore raw
Quoted 8 lines · Stephen Rothwell
Quoted 3 lines · On Wed, 07 Mar 2007 19:01:44 +0100 Felix Domke <[email protected]> wrote:

Note that these patches were written by different people, who want to remain anonymous. These drivers were written without hardware documentation being available.

Sorry, but given the anonymity requirement above, I do not want to even read these patches. Tracking of the pedigree of code in Linux has become an issue and deevelopers want to be anonymous really pokes a big hole in that.

Let me check back with the original authors. They either need to become responsible for their code, or I will remove the code. It can still be rewritten.

Felix

#24 lore raw
In reply to Stephen Rothwell
Quoted 10 lines · Stephen Rothwell
Quoted 4 lines · On Wed, 07 Mar 2007 19:01:44 +0100 Felix Domke <[email protected]> wrote:

Note that these patches were written by different people, who want to remain anonymous. These drivers were written without hardware documentation being available.

Sorry, but given the anonymity requirement above, I do not want to even read these patches. Tracking of the pedigree of code in Linux has become an issue and deevelopers want to be anonymous really pokes a big hole in that.

Then please go away from Linux mailinglist, instead of these kinds of stupid rants.

#25 lore raw
In reply to Stephen Rothwell
Quoted 5 lines · Stephen Rothwell

Sorry, but given the anonymity requirement above, I do not want to even read these patches. Tracking of the pedigree of code in Linux has become an issue and deevelopers want to be anonymous really pokes a big hole in that.

Please note that legal systems do have pretty robust notions about "reasonable people" and "reasonable behaviour". Having gone through the patches, I can affirm that these are utterly unremarkable, perfectly ordinary patches, and there is no way that any "reasonable person" will get "contaminated" reading this stuff. The code looks like any other ethernet or ide or sata code; a few register definitions are different, but that's about it.

Concepts like "pedigree" and "contamination" and "certificate of originality" and etc. apply when the code in question starts doing things that are unique, novel, "not obvious to practitioners versed in the state of the art". When some code implements something unusual, then there can be legitimate concerns about infringing on some patent, etc.

At most, one might argue that there are some "trade secrets" in that code. However, "trade secrets" are not protected by law: once they're public, the're not secret any more, and the holder of the secret is plain out-of-luck, and has no legal recourse.

Oh, did I mention I'm not a lawyer, never studied law, etc. etc.? The above is all my personal opinion, not that or my employer etc.

--linas