瀏覽代碼

Merge branch 'master' into upstream-fixes

Jeff Garzik 18 年之前
父節點
當前提交
b232923966
共有 78 個文件被更改,包括 1416 次插入1039 次删除
  1. 5 1
      arch/mips/kernel/scall32-o32.S
  2. 4 0
      arch/mips/kernel/scall64-64.S
  3. 4 0
      arch/mips/kernel/scall64-n32.S
  4. 4 0
      arch/mips/kernel/scall64-o32.S
  5. 1 1
      arch/mips/kernel/smp.c
  6. 0 3
      arch/mips/kernel/smtc-asm.S
  7. 2 2
      arch/mips/kernel/smtc.c
  8. 11 4
      arch/mips/kernel/traps.c
  9. 2 3
      arch/mips/mips-boards/atlas/atlas_int.c
  10. 2 14
      arch/mips/mips-boards/generic/time.c
  11. 1 1
      arch/mips/sgi-ip27/ip27-memory.c
  12. 24 0
      drivers/ata/ahci.c
  13. 39 23
      drivers/ata/libata-core.c
  14. 43 24
      drivers/ata/libata-scsi.c
  15. 29 8
      drivers/ata/libata-sff.c
  16. 0 1
      drivers/ata/pata_isapnp.c
  17. 5 1
      drivers/char/agp/agp.h
  18. 270 306
      drivers/char/agp/intel-agp.c
  19. 12 0
      drivers/ide/ide-disk.c
  20. 6 6
      drivers/ide/ide-probe.c
  21. 8 1
      drivers/ide/ide.c
  22. 9 3
      drivers/ide/pci/amd74xx.c
  23. 23 14
      drivers/ide/pci/generic.c
  24. 4 4
      drivers/ide/pci/hpt366.c
  25. 18 16
      drivers/ide/pci/it821x.c
  26. 32 19
      drivers/ide/pci/serverworks.c
  27. 2 2
      drivers/infiniband/core/cma.c
  28. 22 11
      drivers/infiniband/hw/mlx4/qp.c
  29. 1 1
      drivers/infiniband/hw/mthca/mthca_cmd.c
  30. 1 0
      drivers/media/common/Kconfig
  31. 5 2
      drivers/media/dvb/b2c2/Makefile
  32. 1 2
      drivers/media/dvb/cinergyT2/cinergyT2.c
  33. 16 5
      drivers/media/dvb/frontends/tda10086.c
  34. 2 2
      drivers/media/dvb/frontends/tda826x.c
  35. 1 1
      drivers/media/video/Kconfig
  36. 1 1
      drivers/media/video/ivtv/ivtv-cards.h
  37. 1 0
      drivers/media/video/ivtv/ivtv-driver.c
  38. 13 3
      drivers/media/video/ivtv/ivtv-driver.h
  39. 16 0
      drivers/media/video/ivtv/ivtv-fileops.c
  40. 38 7
      drivers/media/video/ivtv/ivtv-ioctl.c
  41. 137 67
      drivers/media/video/ivtv/ivtv-irq.c
  42. 23 8
      drivers/media/video/ivtv/ivtv-queue.c
  43. 33 6
      drivers/media/video/ivtv/ivtv-queue.h
  44. 1 1
      drivers/media/video/ivtv/ivtv-streams.c
  45. 1 1
      drivers/media/video/ivtv/ivtv-vbi.c
  46. 1 1
      drivers/media/video/ivtv/ivtv-vbi.h
  47. 19 30
      drivers/media/video/saa7111.c
  48. 53 29
      drivers/media/video/usbvision/usbvision-core.c
  49. 0 1
      drivers/media/video/usbvision/usbvision.h
  50. 21 5
      drivers/mmc/core/sd.c
  51. 2 3
      drivers/mmc/host/at91_mci.c
  52. 1 2
      drivers/mmc/host/au1xmmc.c
  53. 1 1
      drivers/net/mlx4/cq.c
  54. 3 1
      drivers/net/mlx4/eq.c
  55. 24 3
      drivers/net/mlx4/fw.c
  56. 0 3
      drivers/net/mlx4/intf.c
  57. 2 0
      drivers/net/mlx4/main.c
  58. 5 3
      drivers/net/mlx4/mr.c
  59. 129 123
      fs/cifs/cifs_debug.c
  60. 6 6
      fs/cifs/cifs_unicode.c
  61. 1 1
      fs/cifs/cifsfs.c
  62. 2 2
      fs/cifs/cifssmb.c
  63. 13 3
      fs/cifs/connect.c
  64. 94 90
      fs/cifs/dir.c
  65. 22 24
      fs/cifs/fcntl.c
  66. 3 2
      fs/cifs/inode.c
  67. 14 15
      fs/cifs/ioctl.c
  68. 1 1
      fs/cifs/rfc1002pdu.h
  69. 35 35
      fs/splice.c
  70. 19 32
      include/asm-mips/bitops.h
  71. 28 24
      include/asm-mips/stackframe.h
  72. 18 6
      include/asm-mips/unistd.h
  73. 2 1
      include/linux/ata.h
  74. 1 0
      include/linux/ide.h
  75. 1 0
      include/linux/libata.h
  76. 2 0
      include/linux/pci_ids.h
  77. 15 15
      include/linux/pipe_fs_i.h
  78. 5 2
      include/linux/videodev2.h

+ 5 - 1
arch/mips/kernel/scall32-o32.S

@@ -657,7 +657,11 @@ einval:	li	v0, -EINVAL
 	sys	sys_getcpu		3
 	sys	sys_getcpu		3
 	sys	sys_epoll_pwait		6
 	sys	sys_epoll_pwait		6
 	sys	sys_ioprio_set		3
 	sys	sys_ioprio_set		3
-	sys	sys_ioprio_get		2
+	sys	sys_ioprio_get		2	/* 4315 */
+	sys	sys_utimensat		4
+	sys	sys_signalfd		3
+	sys	sys_timerfd		4
+	sys	sys_eventfd		1
 	.endm
 	.endm
 
 
 	/* We pre-compute the number of _instruction_ bytes needed to
 	/* We pre-compute the number of _instruction_ bytes needed to

+ 4 - 0
arch/mips/kernel/scall64-64.S

@@ -473,4 +473,8 @@ sys_call_table:
 	PTR	sys_epoll_pwait
 	PTR	sys_epoll_pwait
 	PTR	sys_ioprio_set
 	PTR	sys_ioprio_set
 	PTR	sys_ioprio_get
 	PTR	sys_ioprio_get
+	PTR	sys_utimensat			/* 5275 */
+	PTR	sys_signalfd
+	PTR	sys_timerfd
+	PTR	sys_eventfd
 	.size	sys_call_table,.-sys_call_table
 	.size	sys_call_table,.-sys_call_table

+ 4 - 0
arch/mips/kernel/scall64-n32.S

@@ -399,4 +399,8 @@ EXPORT(sysn32_call_table)
 	PTR	compat_sys_epoll_pwait
 	PTR	compat_sys_epoll_pwait
 	PTR	sys_ioprio_set
 	PTR	sys_ioprio_set
 	PTR	sys_ioprio_get
 	PTR	sys_ioprio_get
+	PTR	compat_sys_utimensat
+	PTR	compat_sys_signalfd		/* 5280 */
+	PTR	compat_sys_timerfd
+	PTR	sys_eventfd
 	.size	sysn32_call_table,.-sysn32_call_table
 	.size	sysn32_call_table,.-sysn32_call_table

+ 4 - 0
arch/mips/kernel/scall64-o32.S

@@ -521,4 +521,8 @@ sys_call_table:
 	PTR	compat_sys_epoll_pwait
 	PTR	compat_sys_epoll_pwait
 	PTR	sys_ioprio_set
 	PTR	sys_ioprio_set
 	PTR	sys_ioprio_get			/* 4315 */
 	PTR	sys_ioprio_get			/* 4315 */
+	PTR	compat_sys_utimensat
+	PTR	compat_sys_signalfd
+	PTR	compat_sys_timerfd
+	PTR	sys_eventfd
 	.size	sys_call_table,.-sys_call_table
 	.size	sys_call_table,.-sys_call_table

+ 1 - 1
arch/mips/kernel/smp.c

@@ -68,7 +68,7 @@ extern ATTRIB_NORET void cpu_idle(void);
  * First C code run on the secondary CPUs after being started up by
  * First C code run on the secondary CPUs after being started up by
  * the master.
  * the master.
  */
  */
-asmlinkage void start_secondary(void)
+asmlinkage __cpuinit void start_secondary(void)
 {
 {
 	unsigned int cpu;
 	unsigned int cpu;
 
 

+ 0 - 3
arch/mips/kernel/smtc-asm.S

@@ -121,10 +121,7 @@ LEAF(self_ipi)
 	subu	t1,sp,PT_SIZE
 	subu	t1,sp,PT_SIZE
 	sw	ra,PT_EPC(t1)
 	sw	ra,PT_EPC(t1)
 	sw	a0,PT_PADSLOT4(t1)
 	sw	a0,PT_PADSLOT4(t1)
-	LONG_L	s0, TI_REGS($28)
-	LONG_S	sp, TI_REGS($28)
 	la	t2,ipi_decode
 	la	t2,ipi_decode
-	LONG_S	s0, TI_REGS($28)
 	sw	t2,PT_PADSLOT5(t1)
 	sw	t2,PT_PADSLOT5(t1)
 	/* Save pre-disable value of TCStatus */
 	/* Save pre-disable value of TCStatus */
 	sw	t0,PT_TCSTATUS(t1)
 	sw	t0,PT_TCSTATUS(t1)

+ 2 - 2
arch/mips/kernel/smtc.c

@@ -611,12 +611,12 @@ void smtc_cpus_done(void)
 int setup_irq_smtc(unsigned int irq, struct irqaction * new,
 int setup_irq_smtc(unsigned int irq, struct irqaction * new,
 			unsigned long hwmask)
 			unsigned long hwmask)
 {
 {
+#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
 	unsigned int vpe = current_cpu_data.vpe_id;
 	unsigned int vpe = current_cpu_data.vpe_id;
 
 
-	irq_hwmask[irq] = hwmask;
-#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
 	vpemask[vpe][irq - MIPSCPU_INT_BASE] = 1;
 	vpemask[vpe][irq - MIPSCPU_INT_BASE] = 1;
 #endif
 #endif
+	irq_hwmask[irq] = hwmask;
 
 
 	return setup_irq(irq, new);
 	return setup_irq(irq, new);
 }
 }

+ 11 - 4
arch/mips/kernel/traps.c

@@ -11,6 +11,7 @@
  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
  * Copyright (C) 2002, 2003, 2004, 2005  Maciej W. Rozycki
  * Copyright (C) 2002, 2003, 2004, 2005  Maciej W. Rozycki
  */
  */
+#include <linux/bug.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/module.h>
@@ -1190,8 +1191,8 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
 
 
 		memcpy (b, &except_vec_vi, handler_len);
 		memcpy (b, &except_vec_vi, handler_len);
 #ifdef CONFIG_MIPS_MT_SMTC
 #ifdef CONFIG_MIPS_MT_SMTC
-		if (n > 7)
-			printk("Vector index %d exceeds SMTC maximum\n", n);
+		BUG_ON(n > 7);	/* Vector index %d exceeds SMTC maximum. */
+
 		w = (u32 *)(b + mori_offset);
 		w = (u32 *)(b + mori_offset);
 		*w = (*w & 0xffff0000) | (0x100 << n);
 		*w = (*w & 0xffff0000) | (0x100 << n);
 #endif /* CONFIG_MIPS_MT_SMTC */
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -1383,6 +1384,13 @@ void __init per_cpu_trap_init(void)
 		cpu_cache_init();
 		cpu_cache_init();
 		tlb_init();
 		tlb_init();
 #ifdef CONFIG_MIPS_MT_SMTC
 #ifdef CONFIG_MIPS_MT_SMTC
+	} else if (!secondaryTC) {
+		/*
+		 * First TC in non-boot VPE must do subset of tlb_init()
+		 * for MMU countrol registers.
+		 */
+		write_c0_pagemask(PM_DEFAULT_MASK);
+		write_c0_wired(0);
 	}
 	}
 #endif /* CONFIG_MIPS_MT_SMTC */
 #endif /* CONFIG_MIPS_MT_SMTC */
 }
 }
@@ -1531,8 +1539,7 @@ void __init trap_init(void)
 	if (cpu_has_mipsmt)
 	if (cpu_has_mipsmt)
 		set_except_vector(25, handle_mt);
 		set_except_vector(25, handle_mt);
 
 
-	if (cpu_has_dsp)
-		set_except_vector(26, handle_dsp);
+	set_except_vector(26, handle_dsp);
 
 
 	if (cpu_has_vce)
 	if (cpu_has_vce)
 		/* Special exception: R4[04]00 uses also the divec space. */
 		/* Special exception: R4[04]00 uses also the divec space. */

+ 2 - 3
arch/mips/mips-boards/atlas/atlas_int.c

@@ -248,14 +248,13 @@ void __init arch_init_irq(void)
 	case MIPS_REVISION_CORID_CORE_24K:
 	case MIPS_REVISION_CORID_CORE_24K:
 	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
 	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
 		if (cpu_has_veic)
 		if (cpu_has_veic)
-			init_msc_irqs (MSC01E_INT_BASE,
+			init_msc_irqs (MSC01E_INT_BASE, MSC01E_INT_BASE,
 				       msc_eicirqmap, msc_nr_eicirqs);
 				       msc_eicirqmap, msc_nr_eicirqs);
 		else
 		else
-			init_msc_irqs (MSC01C_INT_BASE,
+			init_msc_irqs (MSC01E_INT_BASE, MSC01C_INT_BASE,
 				       msc_irqmap, msc_nr_irqs);
 				       msc_irqmap, msc_nr_irqs);
 	}
 	}
 
 
-
 	if (cpu_has_veic) {
 	if (cpu_has_veic) {
 		set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch);
 		set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch);
 		setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq);
 		setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq);

+ 2 - 14
arch/mips/mips-boards/generic/time.c

@@ -88,8 +88,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id)
 	 *  the general MIPS timer_interrupt routine.
 	 *  the general MIPS timer_interrupt routine.
 	 */
 	 */
 
 
-	int vpflags;
-
 	/*
 	/*
 	 * We could be here due to timer interrupt,
 	 * We could be here due to timer interrupt,
 	 * perf counter overflow, or both.
 	 * perf counter overflow, or both.
@@ -98,15 +96,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id)
 		perf_irq();
 		perf_irq();
 
 
 	if (read_c0_cause() & (1 << 30)) {
 	if (read_c0_cause() & (1 << 30)) {
-		/* If timer interrupt, make it de-assert */
-		write_c0_compare (read_c0_count() - 1);
-		/*
-		 * DVPE is necessary so long as cross-VPE interrupts
-		 * are done via read-modify-write of Cause register.
-		 */
-		vpflags = dvpe();
-		clear_c0_cause(CPUCTR_IMASKBIT);
-		evpe(vpflags);
 		/*
 		/*
 		 * There are things we only want to do once per tick
 		 * There are things we only want to do once per tick
 		 * in an "MP" system.   One TC of each VPE will take
 		 * in an "MP" system.   One TC of each VPE will take
@@ -115,14 +104,13 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id)
 		 * the tick on VPE 0 to run the full timer_interrupt().
 		 * the tick on VPE 0 to run the full timer_interrupt().
 		 */
 		 */
 		if (cpu_data[cpu].vpe_id == 0) {
 		if (cpu_data[cpu].vpe_id == 0) {
-				timer_interrupt(irq, NULL);
-				smtc_timer_broadcast(cpu_data[cpu].vpe_id);
+			timer_interrupt(irq, NULL);
 		} else {
 		} else {
 			write_c0_compare(read_c0_count() +
 			write_c0_compare(read_c0_count() +
 			                 (mips_hpt_frequency/HZ));
 			                 (mips_hpt_frequency/HZ));
 			local_timer_interrupt(irq, dev_id);
 			local_timer_interrupt(irq, dev_id);
-			smtc_timer_broadcast(cpu_data[cpu].vpe_id);
 		}
 		}
+		smtc_timer_broadcast(cpu_data[cpu].vpe_id);
 	}
 	}
 #else /* CONFIG_MIPS_MT_SMTC */
 #else /* CONFIG_MIPS_MT_SMTC */
 	int r2 = cpu_has_mips_r2;
 	int r2 = cpu_has_mips_r2;

+ 1 - 1
arch/mips/sgi-ip27/ip27-memory.c

@@ -517,7 +517,7 @@ void __init paging_init(void)
 		pfn_t start_pfn = slot_getbasepfn(node, 0);
 		pfn_t start_pfn = slot_getbasepfn(node, 0);
 		pfn_t end_pfn = node_getmaxclick(node) + 1;
 		pfn_t end_pfn = node_getmaxclick(node) + 1;
 
 
-		zones_size[ZONE_DMA] = end_pfn - start_pfn;
+		zones_size[ZONE_NORMAL] = end_pfn - start_pfn;
 		free_area_init_node(node, NODE_DATA(node),
 		free_area_init_node(node, NODE_DATA(node),
 				zones_size, start_pfn, NULL);
 				zones_size, start_pfn, NULL);
 
 

+ 24 - 0
drivers/ata/ahci.c

@@ -426,6 +426,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci },		/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci },		/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci },		/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci },		/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci },		/* MCP67 */
 	{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci },		/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad3), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad4), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad5), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad6), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad7), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad8), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci },		/* MCP77 */
+	{ PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci },		/* MCP77 */
 
 
 	/* SiS */
 	/* SiS */
 	{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
 	{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */

+ 39 - 23
drivers/ata/libata-core.c

@@ -1727,7 +1727,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
 
 
 	/* sanity check */
 	/* sanity check */
 	rc = -EINVAL;
 	rc = -EINVAL;
-	reason = "device reports illegal type";
+	reason = "device reports invalid type";
 
 
 	if (class == ATA_DEV_ATA) {
 	if (class == ATA_DEV_ATA) {
 		if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
 		if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
@@ -1900,6 +1900,13 @@ int ata_dev_configure(struct ata_device *dev)
 	if (ata_msg_probe(ap))
 	if (ata_msg_probe(ap))
 		ata_dump_id(id);
 		ata_dump_id(id);
 
 
+	/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
+	ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
+			sizeof(fwrevbuf));
+
+	ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
+			sizeof(modelbuf));
+
 	/* ATA-specific feature tests */
 	/* ATA-specific feature tests */
 	if (dev->class == ATA_DEV_ATA) {
 	if (dev->class == ATA_DEV_ATA) {
 		if (ata_id_is_cfa(id)) {
 		if (ata_id_is_cfa(id)) {
@@ -1914,13 +1921,6 @@ int ata_dev_configure(struct ata_device *dev)
 
 
 		dev->n_sectors = ata_id_n_sectors(id);
 		dev->n_sectors = ata_id_n_sectors(id);
 
 
-		/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
-		ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
-				sizeof(fwrevbuf));
-
-		ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
-				sizeof(modelbuf));
-
 		if (dev->id[59] & 0x100)
 		if (dev->id[59] & 0x100)
 			dev->multi_count = dev->id[59] & 0xff;
 			dev->multi_count = dev->id[59] & 0xff;
 
 
@@ -2009,7 +2009,9 @@ int ata_dev_configure(struct ata_device *dev)
 
 
 		/* print device info to dmesg */
 		/* print device info to dmesg */
 		if (ata_msg_drv(ap) && print_info)
 		if (ata_msg_drv(ap) && print_info)
-			ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s%s\n",
+			ata_dev_printk(dev, KERN_INFO,
+				       "ATAPI: %s, %s, max %s%s\n",
+				       modelbuf, fwrevbuf,
 				       ata_mode_string(xfer_mask),
 				       ata_mode_string(xfer_mask),
 				       cdb_intr_string);
 				       cdb_intr_string);
 	}
 	}
@@ -3059,22 +3061,28 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
 		}
 		}
 	}
 	}
 
 
-	/* if device 1 was found in ata_devchk, wait for
-	 * register access, then wait for BSY to clear
+	/* if device 1 was found in ata_devchk, wait for register
+	 * access briefly, then wait for BSY to clear.
 	 */
 	 */
-	while (dev1) {
-		u8 nsect, lbal;
+	if (dev1) {
+		int i;
 
 
 		ap->ops->dev_select(ap, 1);
 		ap->ops->dev_select(ap, 1);
-		nsect = ioread8(ioaddr->nsect_addr);
-		lbal = ioread8(ioaddr->lbal_addr);
-		if ((nsect == 1) && (lbal == 1))
-			break;
-		if (time_after(jiffies, deadline))
-			return -EBUSY;
-		msleep(50);	/* give drive a breather */
-	}
-	if (dev1) {
+
+		/* Wait for register access.  Some ATAPI devices fail
+		 * to set nsect/lbal after reset, so don't waste too
+		 * much time on it.  We're gonna wait for !BSY anyway.
+		 */
+		for (i = 0; i < 2; i++) {
+			u8 nsect, lbal;
+
+			nsect = ioread8(ioaddr->nsect_addr);
+			lbal = ioread8(ioaddr->lbal_addr);
+			if ((nsect == 1) && (lbal == 1))
+				break;
+			msleep(50);	/* give drive a breather */
+		}
+
 		rc = ata_wait_ready(ap, deadline);
 		rc = ata_wait_ready(ap, deadline);
 		if (rc) {
 		if (rc) {
 			if (rc != -ENODEV)
 			if (rc != -ENODEV)
@@ -3769,6 +3777,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 	{ "_NEC DV5800A", 	NULL,		ATA_HORKAGE_NODMA },
 	{ "_NEC DV5800A", 	NULL,		ATA_HORKAGE_NODMA },
 	{ "SAMSUNG CD-ROM SN-124","N001",	ATA_HORKAGE_NODMA },
 	{ "SAMSUNG CD-ROM SN-124","N001",	ATA_HORKAGE_NODMA },
 	{ "Seagate STT20000A", NULL,		ATA_HORKAGE_NODMA },
 	{ "Seagate STT20000A", NULL,		ATA_HORKAGE_NODMA },
+	{ "IOMEGA  ZIP 250       ATAPI", NULL,	ATA_HORKAGE_NODMA }, /* temporary fix */
 
 
 	/* Weird ATAPI devices */
 	/* Weird ATAPI devices */
 	{ "TORiSAN DVD-ROM DRD-N216", NULL,	ATA_HORKAGE_MAX_SEC_128 |
 	{ "TORiSAN DVD-ROM DRD-N216", NULL,	ATA_HORKAGE_MAX_SEC_128 |
@@ -3791,6 +3800,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 	{ "HTS541060G9SA00",    "MB3OC60D",     ATA_HORKAGE_NONCQ, },
 	{ "HTS541060G9SA00",    "MB3OC60D",     ATA_HORKAGE_NONCQ, },
 	{ "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
 	{ "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
 	{ "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
 	{ "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
+	/* Drives which do spurious command completion */
+	{ "HTS541680J9SA00",	"SB2IC7EP",	ATA_HORKAGE_NONCQ, },
 
 
 	/* Devices with NCQ limits */
 	/* Devices with NCQ limits */
 
 
@@ -6313,7 +6324,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
 		/* init sata_spd_limit to the current value */
 		/* init sata_spd_limit to the current value */
 		if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
 		if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
 			int spd = (scontrol >> 4) & 0xf;
 			int spd = (scontrol >> 4) & 0xf;
-			ap->hw_sata_spd_limit &= (1 << spd) - 1;
+			if (spd)
+				ap->hw_sata_spd_limit &= (1 << spd) - 1;
 		}
 		}
 		ap->sata_spd_limit = ap->hw_sata_spd_limit;
 		ap->sata_spd_limit = ap->hw_sata_spd_limit;
 
 
@@ -6433,6 +6445,9 @@ int ata_host_activate(struct ata_host *host, int irq,
 	if (rc)
 	if (rc)
 		devm_free_irq(host->dev, irq, host);
 		devm_free_irq(host->dev, irq, host);
 
 
+	/* Used to print device info at probe */
+	host->irq = irq;
+
 	return rc;
 	return rc;
 }
 }
 
 
@@ -6818,6 +6833,7 @@ EXPORT_SYMBOL_GPL(ata_check_status);
 EXPORT_SYMBOL_GPL(ata_altstatus);
 EXPORT_SYMBOL_GPL(ata_altstatus);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
 EXPORT_SYMBOL_GPL(ata_port_start);
+EXPORT_SYMBOL_GPL(ata_sff_port_start);
 EXPORT_SYMBOL_GPL(ata_interrupt);
 EXPORT_SYMBOL_GPL(ata_interrupt);
 EXPORT_SYMBOL_GPL(ata_do_set_mode);
 EXPORT_SYMBOL_GPL(ata_do_set_mode);
 EXPORT_SYMBOL_GPL(ata_data_xfer);
 EXPORT_SYMBOL_GPL(ata_data_xfer);

+ 43 - 24
drivers/ata/libata-scsi.c

@@ -1363,12 +1363,22 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 	 * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
 	 * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
 	 * cache
 	 * cache
 	 */
 	 */
-	if (ap->ops->error_handler &&
-	    !need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) &&
-	    ((qc->tf.feature == SETFEATURES_WC_ON) ||
-	     (qc->tf.feature == SETFEATURES_WC_OFF))) {
-		ap->eh_info.action |= ATA_EH_REVALIDATE;
-		ata_port_schedule_eh(ap);
+	if (ap->ops->error_handler && !need_sense) {
+		switch (qc->tf.command) {
+		case ATA_CMD_SET_FEATURES:
+			if ((qc->tf.feature == SETFEATURES_WC_ON) ||
+			    (qc->tf.feature == SETFEATURES_WC_OFF)) {
+				ap->eh_info.action |= ATA_EH_REVALIDATE;
+				ata_port_schedule_eh(ap);
+			}
+			break;
+
+		case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
+		case ATA_CMD_SET_MULTI: /* multi_count changed */
+			ap->eh_info.action |= ATA_EH_REVALIDATE;
+			ata_port_schedule_eh(ap);
+			break;
+		}
 	}
 	}
 
 
 	/* For ATA pass thru (SAT) commands, generate a sense block if
 	/* For ATA pass thru (SAT) commands, generate a sense block if
@@ -2506,22 +2516,21 @@ ata_scsi_map_proto(u8 byte1)
 			return ATA_PROT_NODATA;
 			return ATA_PROT_NODATA;
 
 
 		case 6:		/* DMA */
 		case 6:		/* DMA */
+		case 10:	/* UDMA Data-in */
+		case 11:	/* UDMA Data-Out */
 			return ATA_PROT_DMA;
 			return ATA_PROT_DMA;
 
 
 		case 4:		/* PIO Data-in */
 		case 4:		/* PIO Data-in */
 		case 5:		/* PIO Data-out */
 		case 5:		/* PIO Data-out */
 			return ATA_PROT_PIO;
 			return ATA_PROT_PIO;
 
 
-		case 10:	/* Device Reset */
 		case 0:		/* Hard Reset */
 		case 0:		/* Hard Reset */
 		case 1:		/* SRST */
 		case 1:		/* SRST */
-		case 2:		/* Bus Idle */
-		case 7:		/* Packet */
-		case 8:		/* DMA Queued */
-		case 9:		/* Device Diagnostic */
-		case 11:	/* UDMA Data-in */
-		case 12:	/* UDMA Data-Out */
-		case 13:	/* FPDMA */
+		case 8:		/* Device Diagnostic */
+		case 9:		/* Device Reset */
+		case 7:		/* DMA Queued */
+		case 12:	/* FPDMA */
+		case 15:	/* Return Response Info */
 		default:	/* Reserved */
 		default:	/* Reserved */
 			break;
 			break;
 	}
 	}
@@ -2552,10 +2561,6 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
 	if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
 	if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
 		goto invalid_fld;
 		goto invalid_fld;
 
 
-	if (cdb[1] & 0xe0)
-		/* PIO multi not supported yet */
-		goto invalid_fld;
-
 	/*
 	/*
 	 * 12 and 16 byte CDBs use different offsets to
 	 * 12 and 16 byte CDBs use different offsets to
 	 * provide the various register values.
 	 * provide the various register values.
@@ -2600,12 +2605,26 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
 		tf->device = cdb[8];
 		tf->device = cdb[8];
 		tf->command = cdb[9];
 		tf->command = cdb[9];
 	}
 	}
-	/*
-	 * If slave is possible, enforce correct master/slave bit
-	*/
-	if (qc->ap->flags & ATA_FLAG_SLAVE_POSS)
-		tf->device = qc->dev->devno ?
-			tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+
+	/* enforce correct master/slave bit */
+	tf->device = dev->devno ?
+		tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+
+	/* sanity check for pio multi commands */
+	if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf))
+		goto invalid_fld;
+
+	if (is_multi_taskfile(tf)) {
+		unsigned int multi_count = 1 << (cdb[1] >> 5);
+
+		/* compare the passed through multi_count
+		 * with the cached multi_count of libata
+		 */
+		if (multi_count != dev->multi_count)
+			ata_dev_printk(dev, KERN_WARNING,
+				       "invalid multi_count %u ignored\n",
+				       multi_count);
+	}	
 
 
 	/* READ/WRITE LONG use a non-standard sect_size */
 	/* READ/WRITE LONG use a non-standard sect_size */
 	qc->sect_size = ATA_SECT_SIZE;
 	qc->sect_size = ATA_SECT_SIZE;

+ 29 - 8
drivers/ata/libata-sff.c

@@ -80,25 +80,25 @@ u8 ata_dummy_irq_on (struct ata_port *ap) 	{ return 0; }
 u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
 u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
 {
 {
 	unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
 	unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
-	u8 host_stat, post_stat, status;
+	u8 host_stat = 0, post_stat = 0, status;
 
 
 	status = ata_busy_wait(ap, bits, 1000);
 	status = ata_busy_wait(ap, bits, 1000);
 	if (status & bits)
 	if (status & bits)
 		if (ata_msg_err(ap))
 		if (ata_msg_err(ap))
 			printk(KERN_ERR "abnormal status 0x%X\n", status);
 			printk(KERN_ERR "abnormal status 0x%X\n", status);
 
 
-	/* get controller status; clear intr, err bits */
-	host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-	iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
-		 ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-
-	post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+	if (ap->ioaddr.bmdma_addr) {
+		/* get controller status; clear intr, err bits */
+		host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+		iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+			 ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
 
 
+		post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+	}
 	if (ata_msg_intr(ap))
 	if (ata_msg_intr(ap))
 		printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
 		printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
 			__FUNCTION__,
 			__FUNCTION__,
 			host_stat, post_stat, status);
 			host_stat, post_stat, status);
-
 	return status;
 	return status;
 }
 }
 
 
@@ -516,6 +516,27 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
 		ata_bmdma_stop(qc);
 		ata_bmdma_stop(qc);
 }
 }
 
 
+/**
+ *	ata_sff_port_start - Set port up for dma.
+ *	@ap: Port to initialize
+ *
+ *	Called just after data structures for each port are
+ *	initialized.  Allocates space for PRD table if the device
+ *	is DMA capable SFF.
+ *
+ *	May be used as the port_start() entry in ata_port_operations.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+
+int ata_sff_port_start(struct ata_port *ap)
+{
+	if (ap->ioaddr.bmdma_addr)
+		return ata_port_start(ap);
+	return 0;
+}
+
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
 
 
 static int ata_resources_present(struct pci_dev *pdev, int port)
 static int ata_resources_present(struct pci_dev *pdev, int port)

+ 0 - 1
drivers/ata/pata_isapnp.c

@@ -77,7 +77,6 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
 	struct ata_host *host;
 	struct ata_host *host;
 	struct ata_port *ap;
 	struct ata_port *ap;
 	void __iomem *cmd_addr, *ctl_addr;
 	void __iomem *cmd_addr, *ctl_addr;
-	int rc;
 
 
 	if (pnp_port_valid(idev, 0) == 0)
 	if (pnp_port_valid(idev, 0) == 0)
 		return -ENODEV;
 		return -ENODEV;

+ 5 - 1
drivers/char/agp/agp.h

@@ -176,7 +176,7 @@ struct agp_bridge_data {
 #define I830_GMCH_MEM_MASK		0x1
 #define I830_GMCH_MEM_MASK		0x1
 #define I830_GMCH_MEM_64M		0x1
 #define I830_GMCH_MEM_64M		0x1
 #define I830_GMCH_MEM_128M		0
 #define I830_GMCH_MEM_128M		0
-#define I830_GMCH_GMS_MASK		0x70
+#define I830_GMCH_GMS_MASK		0xF0
 #define I830_GMCH_GMS_DISABLED		0x00
 #define I830_GMCH_GMS_DISABLED		0x00
 #define I830_GMCH_GMS_LOCAL		0x10
 #define I830_GMCH_GMS_LOCAL		0x10
 #define I830_GMCH_GMS_STOLEN_512	0x20
 #define I830_GMCH_GMS_STOLEN_512	0x20
@@ -231,6 +231,10 @@ struct agp_bridge_data {
 #define I965_PGETBL_SIZE_512KB	(0 << 1)
 #define I965_PGETBL_SIZE_512KB	(0 << 1)
 #define I965_PGETBL_SIZE_256KB	(1 << 1)
 #define I965_PGETBL_SIZE_256KB	(1 << 1)
 #define I965_PGETBL_SIZE_128KB	(2 << 1)
 #define I965_PGETBL_SIZE_128KB	(2 << 1)
+#define G33_PGETBL_SIZE_MASK    (3 << 8)
+#define G33_PGETBL_SIZE_1M      (1 << 8)
+#define G33_PGETBL_SIZE_2M      (2 << 8)
+
 #define I810_DRAM_CTL		0x3000
 #define I810_DRAM_CTL		0x3000
 #define I810_DRAM_ROW_0		0x00000001
 #define I810_DRAM_ROW_0		0x00000001
 #define I810_DRAM_ROW_0_SDRAM	0x00000001
 #define I810_DRAM_ROW_0_SDRAM	0x00000001

+ 270 - 306
drivers/char/agp/intel-agp.c

@@ -20,6 +20,14 @@
 #define PCI_DEVICE_ID_INTEL_82965G_IG       0x29A2
 #define PCI_DEVICE_ID_INTEL_82965G_IG       0x29A2
 #define PCI_DEVICE_ID_INTEL_82965GM_HB      0x2A00
 #define PCI_DEVICE_ID_INTEL_82965GM_HB      0x2A00
 #define PCI_DEVICE_ID_INTEL_82965GM_IG      0x2A02
 #define PCI_DEVICE_ID_INTEL_82965GM_IG      0x2A02
+#define PCI_DEVICE_ID_INTEL_82965GME_IG     0x2A12
+#define PCI_DEVICE_ID_INTEL_82945GME_IG     0x27AE
+#define PCI_DEVICE_ID_INTEL_G33_HB          0x29C0
+#define PCI_DEVICE_ID_INTEL_G33_IG          0x29C2
+#define PCI_DEVICE_ID_INTEL_Q35_HB          0x29B0
+#define PCI_DEVICE_ID_INTEL_Q35_IG          0x29B2
+#define PCI_DEVICE_ID_INTEL_Q33_HB          0x29D0
+#define PCI_DEVICE_ID_INTEL_Q33_IG          0x29D2
 
 
 #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
 #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
@@ -27,6 +35,9 @@
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
 
 
+#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB)
 
 
 extern int agp_memory_reserved;
 extern int agp_memory_reserved;
 
 
@@ -53,6 +64,8 @@ extern int agp_memory_reserved;
 #define I915_PTEADDR	0x1C
 #define I915_PTEADDR	0x1C
 #define I915_GMCH_GMS_STOLEN_48M	(0x6 << 4)
 #define I915_GMCH_GMS_STOLEN_48M	(0x6 << 4)
 #define I915_GMCH_GMS_STOLEN_64M	(0x7 << 4)
 #define I915_GMCH_GMS_STOLEN_64M	(0x7 << 4)
+#define G33_GMCH_GMS_STOLEN_128M       (0x8 << 4)
+#define G33_GMCH_GMS_STOLEN_256M       (0x9 << 4)
 
 
 /* Intel 965G registers */
 /* Intel 965G registers */
 #define I965_MSAC 0x62
 #define I965_MSAC 0x62
@@ -86,11 +99,18 @@ static struct gatt_mask intel_i810_masks[] =
 	 .type = INTEL_AGP_CACHED_MEMORY}
 	 .type = INTEL_AGP_CACHED_MEMORY}
 };
 };
 
 
-static struct _intel_i810_private {
-	struct pci_dev *i810_dev;	/* device one */
-	volatile u8 __iomem *registers;
+static struct _intel_private {
+	struct pci_dev *pcidev;	/* device one */
+	u8 __iomem *registers;
+	u32 __iomem *gtt;		/* I915G */
 	int num_dcache_entries;
 	int num_dcache_entries;
-} intel_i810_private;
+	/* gtt_entries is the number of gtt entries that are already mapped
+	 * to stolen memory.  Stolen memory is larger than the memory mapped
+	 * through gtt_entries, as it includes some reserved space for the BIOS
+	 * popup and for the GTT.
+	 */
+	int gtt_entries;			/* i830+ */
+} intel_private;
 
 
 static int intel_i810_fetch_size(void)
 static int intel_i810_fetch_size(void)
 {
 {
@@ -127,32 +147,32 @@ static int intel_i810_configure(void)
 
 
 	current_size = A_SIZE_FIX(agp_bridge->current_size);
 	current_size = A_SIZE_FIX(agp_bridge->current_size);
 
 
-	if (!intel_i810_private.registers) {
-		pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
+	if (!intel_private.registers) {
+		pci_read_config_dword(intel_private.pcidev, I810_MMADDR, &temp);
 		temp &= 0xfff80000;
 		temp &= 0xfff80000;
 
 
-		intel_i810_private.registers = ioremap(temp, 128 * 4096);
-		if (!intel_i810_private.registers) {
+		intel_private.registers = ioremap(temp, 128 * 4096);
+		if (!intel_private.registers) {
 			printk(KERN_ERR PFX "Unable to remap memory.\n");
 			printk(KERN_ERR PFX "Unable to remap memory.\n");
 			return -ENOMEM;
 			return -ENOMEM;
 		}
 		}
 	}
 	}
 
 
-	if ((readl(intel_i810_private.registers+I810_DRAM_CTL)
+	if ((readl(intel_private.registers+I810_DRAM_CTL)
 		& I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
 		& I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
 		/* This will need to be dynamically assigned */
 		/* This will need to be dynamically assigned */
 		printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
 		printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
-		intel_i810_private.num_dcache_entries = 1024;
+		intel_private.num_dcache_entries = 1024;
 	}
 	}
-	pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
+	pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp);
 	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-	writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_i810_private.registers+I810_PGETBL_CTL);
-	readl(intel_i810_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
+	writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+	readl(intel_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
 
 	if (agp_bridge->driver->needs_scratch_page) {
 	if (agp_bridge->driver->needs_scratch_page) {
 		for (i = 0; i < current_size->num_entries; i++) {
 		for (i = 0; i < current_size->num_entries; i++) {
-			writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
-			readl(intel_i810_private.registers+I810_PTE_BASE+(i*4));	/* PCI posting. */
+			writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
+			readl(intel_private.registers+I810_PTE_BASE+(i*4));	/* PCI posting. */
 		}
 		}
 	}
 	}
 	global_cache_flush();
 	global_cache_flush();
@@ -161,9 +181,9 @@ static int intel_i810_configure(void)
 
 
 static void intel_i810_cleanup(void)
 static void intel_i810_cleanup(void)
 {
 {
-	writel(0, intel_i810_private.registers+I810_PGETBL_CTL);
-	readl(intel_i810_private.registers);	/* PCI Posting. */
-	iounmap(intel_i810_private.registers);
+	writel(0, intel_private.registers+I810_PGETBL_CTL);
+	readl(intel_private.registers);	/* PCI Posting. */
+	iounmap(intel_private.registers);
 }
 }
 
 
 static void intel_i810_tlbflush(struct agp_memory *mem)
 static void intel_i810_tlbflush(struct agp_memory *mem)
@@ -261,9 +281,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
 			global_cache_flush();
 			global_cache_flush();
 		for (i = pg_start; i < (pg_start + mem->page_count); i++) {
 		for (i = pg_start; i < (pg_start + mem->page_count); i++) {
 			writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID,
 			writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID,
-			       intel_i810_private.registers+I810_PTE_BASE+(i*4));
+			       intel_private.registers+I810_PTE_BASE+(i*4));
 		}
 		}
-		readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
+		readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
 		break;
 		break;
 	case AGP_PHYS_MEMORY:
 	case AGP_PHYS_MEMORY:
 	case AGP_NORMAL_MEMORY:
 	case AGP_NORMAL_MEMORY:
@@ -273,9 +293,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
 			writel(agp_bridge->driver->mask_memory(agp_bridge,
 			writel(agp_bridge->driver->mask_memory(agp_bridge,
 							       mem->memory[i],
 							       mem->memory[i],
 							       mask_type),
 							       mask_type),
-			       intel_i810_private.registers+I810_PTE_BASE+(j*4));
+			       intel_private.registers+I810_PTE_BASE+(j*4));
 		}
 		}
-		readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4));
+		readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
 		break;
 		break;
 	default:
 	default:
 		goto out_err;
 		goto out_err;
@@ -298,9 +318,9 @@ static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
 		return 0;
 		return 0;
 
 
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
+		writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
 	}
 	}
-	readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
+	readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
 
 
 	agp_bridge->driver->tlb_flush(mem);
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
 	return 0;
@@ -354,7 +374,7 @@ static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
 	struct agp_memory *new;
 	struct agp_memory *new;
 
 
 	if (type == AGP_DCACHE_MEMORY) {
 	if (type == AGP_DCACHE_MEMORY) {
-		if (pg_count != intel_i810_private.num_dcache_entries)
+		if (pg_count != intel_private.num_dcache_entries)
 			return NULL;
 			return NULL;
 
 
 		new = agp_create_memory(1);
 		new = agp_create_memory(1);
@@ -404,18 +424,6 @@ static struct aper_size_info_fixed intel_i830_sizes[] =
 	{512, 131072, 7},
 	{512, 131072, 7},
 };
 };
 
 
-static struct _intel_i830_private {
-	struct pci_dev *i830_dev;		/* device one */
-	volatile u8 __iomem *registers;
-	volatile u32 __iomem *gtt;		/* I915G */
-	/* gtt_entries is the number of gtt entries that are already mapped
-	 * to stolen memory.  Stolen memory is larger than the memory mapped
-	 * through gtt_entries, as it includes some reserved space for the BIOS
-	 * popup and for the GTT.
-	 */
-	int gtt_entries;
-} intel_i830_private;
-
 static void intel_i830_init_gtt_entries(void)
 static void intel_i830_init_gtt_entries(void)
 {
 {
 	u16 gmch_ctrl;
 	u16 gmch_ctrl;
@@ -429,7 +437,7 @@ static void intel_i830_init_gtt_entries(void)
 
 
 	if (IS_I965) {
 	if (IS_I965) {
 		u32 pgetbl_ctl;
 		u32 pgetbl_ctl;
-		pgetbl_ctl = readl(intel_i830_private.registers+I810_PGETBL_CTL);
+		pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);
 
 
 		/* The 965 has a field telling us the size of the GTT,
 		/* The 965 has a field telling us the size of the GTT,
 		 * which may be larger than what is necessary to map the
 		 * which may be larger than what is necessary to map the
@@ -451,6 +459,22 @@ static void intel_i830_init_gtt_entries(void)
 			size = 512;
 			size = 512;
 		}
 		}
 		size += 4; /* add in BIOS popup space */
 		size += 4; /* add in BIOS popup space */
+	} else if (IS_G33) {
+	/* G33's GTT size defined in gmch_ctrl */
+		switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
+		case G33_PGETBL_SIZE_1M:
+			size = 1024;
+			break;
+		case G33_PGETBL_SIZE_2M:
+			size = 2048;
+			break;
+		default:
+			printk(KERN_INFO PFX "Unknown page table size 0x%x, "
+				"assuming 512KB\n",
+				(gmch_ctrl & G33_PGETBL_SIZE_MASK));
+			size = 512;
+		}
+		size += 4;
 	} else {
 	} else {
 		/* On previous hardware, the GTT size was just what was
 		/* On previous hardware, the GTT size was just what was
 		 * required to map the aperture.
 		 * required to map the aperture.
@@ -471,7 +495,7 @@ static void intel_i830_init_gtt_entries(void)
 			gtt_entries = MB(8) - KB(size);
 			gtt_entries = MB(8) - KB(size);
 			break;
 			break;
 		case I830_GMCH_GMS_LOCAL:
 		case I830_GMCH_GMS_LOCAL:
-			rdct = readb(intel_i830_private.registers+I830_RDRAM_CHANNEL_TYPE);
+			rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE);
 			gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
 			gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
 					MB(ddt[I830_RDRAM_DDT(rdct)]);
 					MB(ddt[I830_RDRAM_DDT(rdct)]);
 			local = 1;
 			local = 1;
@@ -502,7 +526,8 @@ static void intel_i830_init_gtt_entries(void)
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
-			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965 )
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+			    IS_I965 || IS_G33)
 				gtt_entries = MB(48) - KB(size);
 				gtt_entries = MB(48) - KB(size);
 			else
 			else
 				gtt_entries = 0;
 				gtt_entries = 0;
@@ -512,10 +537,24 @@ static void intel_i830_init_gtt_entries(void)
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
-			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965)
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+			    IS_I965 || IS_G33)
 				gtt_entries = MB(64) - KB(size);
 				gtt_entries = MB(64) - KB(size);
 			else
 			else
 				gtt_entries = 0;
 				gtt_entries = 0;
+			break;
+		case G33_GMCH_GMS_STOLEN_128M:
+			if (IS_G33)
+				gtt_entries = MB(128) - KB(size);
+			else
+				gtt_entries = 0;
+			break;
+		case G33_GMCH_GMS_STOLEN_256M:
+			if (IS_G33)
+				gtt_entries = MB(256) - KB(size);
+			else
+				gtt_entries = 0;
+			break;
 		default:
 		default:
 			gtt_entries = 0;
 			gtt_entries = 0;
 			break;
 			break;
@@ -529,7 +568,7 @@ static void intel_i830_init_gtt_entries(void)
 		       "No pre-allocated video memory detected.\n");
 		       "No pre-allocated video memory detected.\n");
 	gtt_entries /= KB(4);
 	gtt_entries /= KB(4);
 
 
-	intel_i830_private.gtt_entries = gtt_entries;
+	intel_private.gtt_entries = gtt_entries;
 }
 }
 
 
 /* The intel i830 automatically initializes the agp aperture during POST.
 /* The intel i830 automatically initializes the agp aperture during POST.
@@ -547,14 +586,14 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
 	num_entries = size->num_entries;
 	num_entries = size->num_entries;
 	agp_bridge->gatt_table_real = NULL;
 	agp_bridge->gatt_table_real = NULL;
 
 
-	pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
+	pci_read_config_dword(intel_private.pcidev,I810_MMADDR,&temp);
 	temp &= 0xfff80000;
 	temp &= 0xfff80000;
 
 
-	intel_i830_private.registers = ioremap(temp,128 * 4096);
-	if (!intel_i830_private.registers)
+	intel_private.registers = ioremap(temp,128 * 4096);
+	if (!intel_private.registers)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+	temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
 	global_cache_flush();	/* FIXME: ?? */
 	global_cache_flush();	/* FIXME: ?? */
 
 
 	/* we have to call this as early as possible after the MMIO base address is known */
 	/* we have to call this as early as possible after the MMIO base address is known */
@@ -614,20 +653,20 @@ static int intel_i830_configure(void)
 
 
 	current_size = A_SIZE_FIX(agp_bridge->current_size);
 	current_size = A_SIZE_FIX(agp_bridge->current_size);
 
 
-	pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
+	pci_read_config_dword(intel_private.pcidev,I810_GMADDR,&temp);
 	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 
 	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
 	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
 	gmch_ctrl |= I830_GMCH_ENABLED;
 	gmch_ctrl |= I830_GMCH_ENABLED;
 	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 
 
-	writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
-	readl(intel_i830_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
+	writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+	readl(intel_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
 
 	if (agp_bridge->driver->needs_scratch_page) {
 	if (agp_bridge->driver->needs_scratch_page) {
-		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
-			writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
-			readl(intel_i830_private.registers+I810_PTE_BASE+(i*4));	/* PCI Posting. */
+		for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+			writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
+			readl(intel_private.registers+I810_PTE_BASE+(i*4));	/* PCI Posting. */
 		}
 		}
 	}
 	}
 
 
@@ -637,7 +676,7 @@ static int intel_i830_configure(void)
 
 
 static void intel_i830_cleanup(void)
 static void intel_i830_cleanup(void)
 {
 {
-	iounmap(intel_i830_private.registers);
+	iounmap(intel_private.registers);
 }
 }
 
 
 static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type)
 static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type)
@@ -653,9 +692,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
 	temp = agp_bridge->current_size;
 	temp = agp_bridge->current_size;
 	num_entries = A_SIZE_FIX(temp)->num_entries;
 	num_entries = A_SIZE_FIX(temp)->num_entries;
 
 
-	if (pg_start < intel_i830_private.gtt_entries) {
-		printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
-				pg_start,intel_i830_private.gtt_entries);
+	if (pg_start < intel_private.gtt_entries) {
+		printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
+				pg_start,intel_private.gtt_entries);
 
 
 		printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
 		printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
 		goto out_err;
 		goto out_err;
@@ -683,9 +722,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
 						       mem->memory[i], mask_type),
 						       mem->memory[i], mask_type),
-		       intel_i830_private.registers+I810_PTE_BASE+(j*4));
+		       intel_private.registers+I810_PTE_BASE+(j*4));
 	}
 	}
-	readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
+	readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
 	agp_bridge->driver->tlb_flush(mem);
 	agp_bridge->driver->tlb_flush(mem);
 
 
 out:
 out:
@@ -703,15 +742,15 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
 	if (mem->page_count == 0)
 	if (mem->page_count == 0)
 		return 0;
 		return 0;
 
 
-	if (pg_start < intel_i830_private.gtt_entries) {
+	if (pg_start < intel_private.gtt_entries) {
 		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
 		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
+		writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
 	}
 	}
-	readl(intel_i830_private.registers+I810_PTE_BASE+((i-1)*4));
+	readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
 
 
 	agp_bridge->driver->tlb_flush(mem);
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
 	return 0;
@@ -734,7 +773,7 @@ static int intel_i915_configure(void)
 
 
 	current_size = A_SIZE_FIX(agp_bridge->current_size);
 	current_size = A_SIZE_FIX(agp_bridge->current_size);
 
 
-	pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp);
+	pci_read_config_dword(intel_private.pcidev, I915_GMADDR, &temp);
 
 
 	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 
@@ -742,13 +781,13 @@ static int intel_i915_configure(void)
 	gmch_ctrl |= I830_GMCH_ENABLED;
 	gmch_ctrl |= I830_GMCH_ENABLED;
 	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 
 
-	writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
-	readl(intel_i830_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
+	writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+	readl(intel_private.registers+I810_PGETBL_CTL);	/* PCI Posting. */
 
 
 	if (agp_bridge->driver->needs_scratch_page) {
 	if (agp_bridge->driver->needs_scratch_page) {
-		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
-			writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
-			readl(intel_i830_private.gtt+i);	/* PCI Posting. */
+		for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+			writel(agp_bridge->scratch_page, intel_private.gtt+i);
+			readl(intel_private.gtt+i);	/* PCI Posting. */
 		}
 		}
 	}
 	}
 
 
@@ -758,8 +797,8 @@ static int intel_i915_configure(void)
 
 
 static void intel_i915_cleanup(void)
 static void intel_i915_cleanup(void)
 {
 {
-	iounmap(intel_i830_private.gtt);
-	iounmap(intel_i830_private.registers);
+	iounmap(intel_private.gtt);
+	iounmap(intel_private.registers);
 }
 }
 
 
 static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
 static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
@@ -776,9 +815,9 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
 	temp = agp_bridge->current_size;
 	temp = agp_bridge->current_size;
 	num_entries = A_SIZE_FIX(temp)->num_entries;
 	num_entries = A_SIZE_FIX(temp)->num_entries;
 
 
-	if (pg_start < intel_i830_private.gtt_entries) {
-		printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
-				pg_start,intel_i830_private.gtt_entries);
+	if (pg_start < intel_private.gtt_entries) {
+		printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
+				pg_start,intel_private.gtt_entries);
 
 
 		printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
 		printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
 		goto out_err;
 		goto out_err;
@@ -805,10 +844,10 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
 
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
-			mem->memory[i], mask_type), intel_i830_private.gtt+j);
+			mem->memory[i], mask_type), intel_private.gtt+j);
 	}
 	}
 
 
-	readl(intel_i830_private.gtt+j-1);
+	readl(intel_private.gtt+j-1);
 	agp_bridge->driver->tlb_flush(mem);
 	agp_bridge->driver->tlb_flush(mem);
 
 
  out:
  out:
@@ -826,15 +865,15 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
 	if (mem->page_count == 0)
 	if (mem->page_count == 0)
 		return 0;
 		return 0;
 
 
-	if (pg_start < intel_i830_private.gtt_entries) {
+	if (pg_start < intel_private.gtt_entries) {
 		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
 		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
+		writel(agp_bridge->scratch_page, intel_private.gtt+i);
 	}
 	}
-	readl(intel_i830_private.gtt+i-1);
+	readl(intel_private.gtt+i-1);
 
 
 	agp_bridge->driver->tlb_flush(mem);
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
 	return 0;
@@ -850,7 +889,7 @@ static int intel_i9xx_fetch_size(void)
 	int aper_size; /* size in megabytes */
 	int aper_size; /* size in megabytes */
 	int i;
 	int i;
 
 
-	aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
+	aper_size = pci_resource_len(intel_private.pcidev, 2) / MB(1);
 
 
 	for (i = 0; i < num_sizes; i++) {
 	for (i = 0; i < num_sizes; i++) {
 		if (aper_size == intel_i830_sizes[i].size) {
 		if (aper_size == intel_i830_sizes[i].size) {
@@ -878,20 +917,20 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
 	num_entries = size->num_entries;
 	num_entries = size->num_entries;
 	agp_bridge->gatt_table_real = NULL;
 	agp_bridge->gatt_table_real = NULL;
 
 
-	pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
-	pci_read_config_dword(intel_i830_private.i830_dev, I915_PTEADDR,&temp2);
+	pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
+	pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2);
 
 
-	intel_i830_private.gtt = ioremap(temp2, 256 * 1024);
-	if (!intel_i830_private.gtt)
+	intel_private.gtt = ioremap(temp2, 256 * 1024);
+	if (!intel_private.gtt)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	temp &= 0xfff80000;
 	temp &= 0xfff80000;
 
 
-	intel_i830_private.registers = ioremap(temp,128 * 4096);
-	if (!intel_i830_private.registers)
+	intel_private.registers = ioremap(temp,128 * 4096);
+	if (!intel_private.registers)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+	temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
 	global_cache_flush();	/* FIXME: ? */
 	global_cache_flush();	/* FIXME: ? */
 
 
 	/* we have to call this as early as possible after the MMIO base address is known */
 	/* we have to call this as early as possible after the MMIO base address is known */
@@ -938,20 +977,20 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
        num_entries = size->num_entries;
        num_entries = size->num_entries;
        agp_bridge->gatt_table_real = NULL;
        agp_bridge->gatt_table_real = NULL;
 
 
-       pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
+       pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
 
 
        temp &= 0xfff00000;
        temp &= 0xfff00000;
-       intel_i830_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
+       intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
 
 
-       if (!intel_i830_private.gtt)
+       if (!intel_private.gtt)
                return -ENOMEM;
                return -ENOMEM;
 
 
 
 
-       intel_i830_private.registers = ioremap(temp,128 * 4096);
-       if (!intel_i830_private.registers)
+       intel_private.registers = ioremap(temp,128 * 4096);
+       if (!intel_private.registers)
                return -ENOMEM;
                return -ENOMEM;
 
 
-       temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+       temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
        global_cache_flush();   /* FIXME: ? */
        global_cache_flush();   /* FIXME: ? */
 
 
        /* we have to call this as early as possible after the MMIO base address is known */
        /* we have to call this as early as possible after the MMIO base address is known */
@@ -1722,41 +1761,126 @@ static const struct agp_bridge_driver intel_7505_driver = {
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 };
 
 
-static int find_i810(u16 device)
-{
-	struct pci_dev *i810_dev;
-
-	i810_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
-	if (!i810_dev)
-		return 0;
-	intel_i810_private.i810_dev = i810_dev;
-	return 1;
-}
+static const struct agp_bridge_driver intel_g33_driver = {
+	.owner                  = THIS_MODULE,
+	.aperture_sizes         = intel_i830_sizes,
+	.size_type              = FIXED_APER_SIZE,
+	.num_aperture_sizes     = 4,
+	.needs_scratch_page     = TRUE,
+	.configure              = intel_i915_configure,
+	.fetch_size             = intel_i9xx_fetch_size,
+	.cleanup                = intel_i915_cleanup,
+	.tlb_flush              = intel_i810_tlbflush,
+	.mask_memory            = intel_i965_mask_memory,
+	.masks                  = intel_i810_masks,
+	.agp_enable             = intel_i810_agp_enable,
+	.cache_flush            = global_cache_flush,
+	.create_gatt_table      = intel_i915_create_gatt_table,
+	.free_gatt_table        = intel_i830_free_gatt_table,
+	.insert_memory          = intel_i915_insert_entries,
+	.remove_memory          = intel_i915_remove_entries,
+	.alloc_by_type          = intel_i830_alloc_by_type,
+	.free_by_type           = intel_i810_free_by_type,
+	.agp_alloc_page         = agp_generic_alloc_page,
+	.agp_destroy_page       = agp_generic_destroy_page,
+	.agp_type_to_mask_type  = intel_i830_type_to_mask_type,
+};
 
 
-static int find_i830(u16 device)
+static int find_gmch(u16 device)
 {
 {
-	struct pci_dev *i830_dev;
+	struct pci_dev *gmch_device;
 
 
-	i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
-	if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
-		i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
-				device, i830_dev);
+	gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
+	if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) {
+		gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL,
+                                device, gmch_device);
 	}
 	}
 
 
-	if (!i830_dev)
+	if (!gmch_device)
 		return 0;
 		return 0;
 
 
-	intel_i830_private.i830_dev = i830_dev;
+	intel_private.pcidev = gmch_device;
 	return 1;
 	return 1;
 }
 }
 
 
+/* Table to describe Intel GMCH and AGP/PCIE GART drivers.  At least one of
+ * driver and gmch_driver must be non-null, and find_gmch will determine
+ * which one should be used if a gmch_chip_id is present.
+ */
+static const struct intel_driver_description {
+	unsigned int chip_id;
+	unsigned int gmch_chip_id;
+	char *name;
+	const struct agp_bridge_driver *driver;
+	const struct agp_bridge_driver *gmch_driver;
+} intel_agp_chipsets[] = {
+	{ PCI_DEVICE_ID_INTEL_82443LX_0, 0, "440LX", &intel_generic_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82443BX_0, 0, "440BX", &intel_generic_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82443GX_0, 0, "440GX", &intel_generic_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82810_MC1, PCI_DEVICE_ID_INTEL_82810_IG1, "i810",
+		NULL, &intel_810_driver },
+	{ PCI_DEVICE_ID_INTEL_82810_MC3, PCI_DEVICE_ID_INTEL_82810_IG3, "i810",
+		NULL, &intel_810_driver },
+	{ PCI_DEVICE_ID_INTEL_82810E_MC, PCI_DEVICE_ID_INTEL_82810E_IG, "i810",
+		NULL, &intel_810_driver },
+	{ PCI_DEVICE_ID_INTEL_82815_MC, PCI_DEVICE_ID_INTEL_82815_CGC, "i815",
+		&intel_810_driver, &intel_815_driver },
+	{ PCI_DEVICE_ID_INTEL_82820_HB, 0, "i820", &intel_820_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82820_UP_HB, 0, "i820", &intel_820_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82830_HB, PCI_DEVICE_ID_INTEL_82830_CGC, "830M",
+		&intel_830mp_driver, &intel_830_driver },
+	{ PCI_DEVICE_ID_INTEL_82840_HB, 0, "i840", &intel_840_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82845_HB, 0, "845G", &intel_845_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, "830M",
+		&intel_845_driver, &intel_830_driver },
+	{ PCI_DEVICE_ID_INTEL_82850_HB, 0, "i850", &intel_850_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82855PM_HB, 0, "855PM", &intel_845_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM",
+		&intel_845_driver, &intel_830_driver },
+	{ PCI_DEVICE_ID_INTEL_82860_HB, 0, "i860", &intel_860_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82865_HB, PCI_DEVICE_ID_INTEL_82865_IG, "865",
+		&intel_845_driver, &intel_830_driver },
+	{ PCI_DEVICE_ID_INTEL_82875_HB, 0, "i875", &intel_845_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82915G_HB, PCI_DEVICE_ID_INTEL_82915G_IG, "915G",
+		&intel_845_driver, &intel_915_driver },
+	{ PCI_DEVICE_ID_INTEL_82915GM_HB, PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM",
+		&intel_845_driver, &intel_915_driver },
+	{ PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, "945G",
+		&intel_845_driver, &intel_915_driver },
+	{ PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM",
+		&intel_845_driver, &intel_915_driver },
+	{ PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, "945GME",
+		&intel_845_driver, &intel_915_driver },
+	{ PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ",
+		&intel_845_driver, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_82965G_1_HB, PCI_DEVICE_ID_INTEL_82965G_1_IG, "965G",
+		&intel_845_driver, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_82965Q_HB, PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q",
+		&intel_845_driver, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, "965G",
+		&intel_845_driver, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM",
+		&intel_845_driver, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, "965GME/GLE",
+		&intel_845_driver, &intel_i965_driver },
+	{ PCI_DEVICE_ID_INTEL_7505_0, 0, "E7505", &intel_7505_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_7205_0, 0, "E7205", &intel_7505_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_G33_HB, PCI_DEVICE_ID_INTEL_G33_IG, "G33",
+		&intel_845_driver, &intel_g33_driver },
+	{ PCI_DEVICE_ID_INTEL_Q35_HB, PCI_DEVICE_ID_INTEL_Q35_IG, "Q35",
+		&intel_845_driver, &intel_g33_driver },
+	{ PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, "Q33",
+		&intel_845_driver, &intel_g33_driver },
+	{ 0, 0, NULL, NULL, NULL }
+};
+
 static int __devinit agp_intel_probe(struct pci_dev *pdev,
 static int __devinit agp_intel_probe(struct pci_dev *pdev,
 				     const struct pci_device_id *ent)
 				     const struct pci_device_id *ent)
 {
 {
 	struct agp_bridge_data *bridge;
 	struct agp_bridge_data *bridge;
-	char *name = "(unknown)";
 	u8 cap_ptr = 0;
 	u8 cap_ptr = 0;
 	struct resource *r;
 	struct resource *r;
+	int i;
 
 
 	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 
 
@@ -1764,195 +1888,42 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
 	if (!bridge)
 	if (!bridge)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	switch (pdev->device) {
-	case PCI_DEVICE_ID_INTEL_82443LX_0:
-		bridge->driver = &intel_generic_driver;
-		name = "440LX";
-		break;
-	case PCI_DEVICE_ID_INTEL_82443BX_0:
-		bridge->driver = &intel_generic_driver;
-		name = "440BX";
-		break;
-	case PCI_DEVICE_ID_INTEL_82443GX_0:
-		bridge->driver = &intel_generic_driver;
-		name = "440GX";
-		break;
-	case PCI_DEVICE_ID_INTEL_82810_MC1:
-		name = "i810";
-		if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG1))
-			goto fail;
-		bridge->driver = &intel_810_driver;
-		break;
-	case PCI_DEVICE_ID_INTEL_82810_MC3:
-		name = "i810 DC100";
-		if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG3))
-			goto fail;
-		bridge->driver = &intel_810_driver;
-		break;
-	case PCI_DEVICE_ID_INTEL_82810E_MC:
-		name = "i810 E";
-		if (!find_i810(PCI_DEVICE_ID_INTEL_82810E_IG))
-			goto fail;
-		bridge->driver = &intel_810_driver;
-		break;
-	 case PCI_DEVICE_ID_INTEL_82815_MC:
-		/*
-		 * The i815 can operate either as an i810 style
-		 * integrated device, or as an AGP4X motherboard.
-		 */
-		if (find_i810(PCI_DEVICE_ID_INTEL_82815_CGC))
-			bridge->driver = &intel_810_driver;
-		else
-			bridge->driver = &intel_815_driver;
-		name = "i815";
-		break;
-	case PCI_DEVICE_ID_INTEL_82820_HB:
-	case PCI_DEVICE_ID_INTEL_82820_UP_HB:
-		bridge->driver = &intel_820_driver;
-		name = "i820";
-		break;
-	case PCI_DEVICE_ID_INTEL_82830_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC))
-			bridge->driver = &intel_830_driver;
-		else
-			bridge->driver = &intel_830mp_driver;
-		name = "830M";
-		break;
-	case PCI_DEVICE_ID_INTEL_82840_HB:
-		bridge->driver = &intel_840_driver;
-		name = "i840";
-		break;
-	case PCI_DEVICE_ID_INTEL_82845_HB:
-		bridge->driver = &intel_845_driver;
-		name = "i845";
-		break;
-	case PCI_DEVICE_ID_INTEL_82845G_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG))
-			bridge->driver = &intel_830_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "845G";
-		break;
-	case PCI_DEVICE_ID_INTEL_82850_HB:
-		bridge->driver = &intel_850_driver;
-		name = "i850";
-		break;
-	case PCI_DEVICE_ID_INTEL_82855PM_HB:
-		bridge->driver = &intel_845_driver;
-		name = "855PM";
-		break;
-	case PCI_DEVICE_ID_INTEL_82855GM_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82855GM_IG)) {
-			bridge->driver = &intel_830_driver;
-			name = "855";
-		} else {
-			bridge->driver = &intel_845_driver;
-			name = "855GM";
-		}
-		break;
-	case PCI_DEVICE_ID_INTEL_82860_HB:
-		bridge->driver = &intel_860_driver;
-		name = "i860";
-		break;
-	case PCI_DEVICE_ID_INTEL_82865_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG))
-			bridge->driver = &intel_830_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "865";
-		break;
-	case PCI_DEVICE_ID_INTEL_82875_HB:
-		bridge->driver = &intel_845_driver;
-		name = "i875";
-		break;
-	case PCI_DEVICE_ID_INTEL_82915G_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82915G_IG))
-			bridge->driver = &intel_915_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "915G";
-		break;
-	case PCI_DEVICE_ID_INTEL_82915GM_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG))
-			bridge->driver = &intel_915_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "915GM";
-		break;
-	case PCI_DEVICE_ID_INTEL_82945G_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG))
-			bridge->driver = &intel_915_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "945G";
-		break;
-	case PCI_DEVICE_ID_INTEL_82945GM_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG))
-			bridge->driver = &intel_915_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "945GM";
-		break;
-	case PCI_DEVICE_ID_INTEL_82946GZ_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82946GZ_IG))
-			bridge->driver = &intel_i965_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "946GZ";
-		break;
-	case PCI_DEVICE_ID_INTEL_82965G_1_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82965G_1_IG))
-			bridge->driver = &intel_i965_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "965G";
-		break;
-	case PCI_DEVICE_ID_INTEL_82965Q_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82965Q_IG))
-			bridge->driver = &intel_i965_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "965Q";
-		break;
-	case PCI_DEVICE_ID_INTEL_82965G_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82965G_IG))
-			bridge->driver = &intel_i965_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "965G";
-		break;
-	case PCI_DEVICE_ID_INTEL_82965GM_HB:
-		if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG))
-			bridge->driver = &intel_i965_driver;
-		else
-			bridge->driver = &intel_845_driver;
-		name = "965GM";
-		break;
-	case PCI_DEVICE_ID_INTEL_7505_0:
-		bridge->driver = &intel_7505_driver;
-		name = "E7505";
-		break;
-	case PCI_DEVICE_ID_INTEL_7205_0:
-		bridge->driver = &intel_7505_driver;
-		name = "E7205";
-		break;
-	default:
+	for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
+		/* In case that multiple models of gfx chip may
+		   stand on same host bridge type, this can be
+		   sure we detect the right IGD. */
+		if ((pdev->device == intel_agp_chipsets[i].chip_id) &&
+			((intel_agp_chipsets[i].gmch_chip_id == 0) ||
+				find_gmch(intel_agp_chipsets[i].gmch_chip_id)))
+			break;
+	}
+
+	if (intel_agp_chipsets[i].name == NULL) {
 		if (cap_ptr)
 		if (cap_ptr)
-			printk(KERN_WARNING PFX "Unsupported Intel chipset (device id: %04x)\n",
-			    pdev->device);
+			printk(KERN_WARNING PFX "Unsupported Intel chipset"
+                               "(device id: %04x)\n", pdev->device);
 		agp_put_bridge(bridge);
 		agp_put_bridge(bridge);
 		return -ENODEV;
 		return -ENODEV;
-	};
+	}
+
+	if (intel_agp_chipsets[i].gmch_chip_id != 0)
+	    bridge->driver = intel_agp_chipsets[i].gmch_driver;
+	else
+	    bridge->driver = intel_agp_chipsets[i].driver;
+
+	if (bridge->driver == NULL) {
+		printk(KERN_WARNING PFX "Failed to find bridge device "
+			"(chip_id: %04x)\n", intel_agp_chipsets[i].gmch_chip_id);
+		agp_put_bridge(bridge);
+		return -ENODEV;
+        }
 
 
 	bridge->dev = pdev;
 	bridge->dev = pdev;
 	bridge->capndx = cap_ptr;
 	bridge->capndx = cap_ptr;
+	bridge->dev_private_data = &intel_private;
 
 
-	if (bridge->driver == &intel_810_driver)
-		bridge->dev_private_data = &intel_i810_private;
-	else if (bridge->driver == &intel_830_driver)
-		bridge->dev_private_data = &intel_i830_private;
-
-	printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
+	printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n",
+		intel_agp_chipsets[i].name);
 
 
 	/*
 	/*
 	* The following fixes the case where the BIOS has "forgotten" to
 	* The following fixes the case where the BIOS has "forgotten" to
@@ -1988,12 +1959,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
 
 
 	pci_set_drvdata(pdev, bridge);
 	pci_set_drvdata(pdev, bridge);
 	return agp_add_bridge(bridge);
 	return agp_add_bridge(bridge);
-
-fail:
-	printk(KERN_ERR PFX "Detected an Intel %s chipset, "
-		"but could not find the secondary device.\n", name);
-	agp_put_bridge(bridge);
-	return -ENODEV;
 }
 }
 
 
 static void __devexit agp_intel_remove(struct pci_dev *pdev)
 static void __devexit agp_intel_remove(struct pci_dev *pdev)
@@ -2002,10 +1967,8 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev)
 
 
 	agp_remove_bridge(bridge);
 	agp_remove_bridge(bridge);
 
 
-	if (intel_i810_private.i810_dev)
-		pci_dev_put(intel_i810_private.i810_dev);
-	if (intel_i830_private.i830_dev)
-		pci_dev_put(intel_i830_private.i830_dev);
+	if (intel_private.pcidev)
+		pci_dev_put(intel_private.pcidev);
 
 
 	agp_put_bridge(bridge);
 	agp_put_bridge(bridge);
 }
 }
@@ -2021,10 +1984,8 @@ static int agp_intel_resume(struct pci_dev *pdev)
 	 * as host bridge (00:00) resumes before graphics device (02:00),
 	 * as host bridge (00:00) resumes before graphics device (02:00),
 	 * then our access to its pci space can work right.
 	 * then our access to its pci space can work right.
 	 */
 	 */
-	if (intel_i810_private.i810_dev)
-		pci_restore_state(intel_i810_private.i810_dev);
-	if (intel_i830_private.i830_dev)
-		pci_restore_state(intel_i830_private.i830_dev);
+	if (intel_private.pcidev)
+		pci_restore_state(intel_private.pcidev);
 
 
 	if (bridge->driver == &intel_generic_driver)
 	if (bridge->driver == &intel_generic_driver)
 		intel_configure();
 		intel_configure();
@@ -2087,6 +2048,9 @@ static struct pci_device_id agp_intel_pci_table[] = {
 	ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
+	ID(PCI_DEVICE_ID_INTEL_G33_HB),
+	ID(PCI_DEVICE_ID_INTEL_Q35_HB),
+	ID(PCI_DEVICE_ID_INTEL_Q33_HB),
 	{ }
 	{ }
 };
 };
 
 

+ 12 - 0
drivers/ide/ide-disk.c

@@ -1037,6 +1037,17 @@ static void ide_disk_release(struct kref *kref)
 
 
 static int ide_disk_probe(ide_drive_t *drive);
 static int ide_disk_probe(ide_drive_t *drive);
 
 
+/*
+ * On HPA drives the capacity needs to be
+ * reinitilized on resume otherwise the disk
+ * can not be used and a hard reset is required
+ */
+static void ide_disk_resume(ide_drive_t *drive)
+{
+	if (idedisk_supports_hpa(drive->id))
+		init_idedisk_capacity(drive);
+}
+
 static void ide_device_shutdown(ide_drive_t *drive)
 static void ide_device_shutdown(ide_drive_t *drive)
 {
 {
 #ifdef	CONFIG_ALPHA
 #ifdef	CONFIG_ALPHA
@@ -1071,6 +1082,7 @@ static ide_driver_t idedisk_driver = {
 	},
 	},
 	.probe			= ide_disk_probe,
 	.probe			= ide_disk_probe,
 	.remove			= ide_disk_remove,
 	.remove			= ide_disk_remove,
+	.resume			= ide_disk_resume,
 	.shutdown		= ide_device_shutdown,
 	.shutdown		= ide_device_shutdown,
 	.version		= IDEDISK_VERSION,
 	.version		= IDEDISK_VERSION,
 	.media			= ide_disk,
 	.media			= ide_disk,

+ 6 - 6
drivers/ide/ide-probe.c

@@ -717,7 +717,7 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
  * This routine only knows how to look for drive units 0 and 1
  * This routine only knows how to look for drive units 0 and 1
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
  */
-static void probe_hwif(ide_hwif_t *hwif)
+static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
 {
 {
 	unsigned int unit;
 	unsigned int unit;
 	unsigned long flags;
 	unsigned long flags;
@@ -820,6 +820,9 @@ static void probe_hwif(ide_hwif_t *hwif)
 		return;
 		return;
 	}
 	}
 
 
+	if (fixup)
+		fixup(hwif);
+
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		ide_drive_t *drive = &hwif->drives[unit];
 		ide_drive_t *drive = &hwif->drives[unit];
 
 
@@ -874,10 +877,7 @@ static int hwif_init(ide_hwif_t *hwif);
 
 
 int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
 int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
 {
 {
-	probe_hwif(hwif);
-
-	if (fixup)
-		fixup(hwif);
+	probe_hwif(hwif, fixup);
 
 
 	if (!hwif_init(hwif)) {
 	if (!hwif_init(hwif)) {
 		printk(KERN_INFO "%s: failed to initialize IDE interface\n",
 		printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -1404,7 +1404,7 @@ int ideprobe_init (void)
 
 
 	for (index = 0; index < MAX_HWIFS; ++index)
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[index])
 		if (probe[index])
-			probe_hwif(&ide_hwifs[index]);
+			probe_hwif(&ide_hwifs[index], NULL);
 	for (index = 0; index < MAX_HWIFS; ++index)
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[index])
 		if (probe[index])
 			hwif_init(&ide_hwifs[index]);
 			hwif_init(&ide_hwifs[index]);

+ 8 - 1
drivers/ide/ide.c

@@ -1010,9 +1010,11 @@ static int generic_ide_resume(struct device *dev)
 {
 {
 	ide_drive_t *drive = dev->driver_data;
 	ide_drive_t *drive = dev->driver_data;
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_hwif_t *hwif = HWIF(drive);
+	ide_driver_t *drv = to_ide_driver(dev->driver);
 	struct request rq;
 	struct request rq;
 	struct request_pm_state rqpm;
 	struct request_pm_state rqpm;
 	ide_task_t args;
 	ide_task_t args;
+	int err;
 
 
 	/* Call ACPI _STM only once */
 	/* Call ACPI _STM only once */
 	if (!(drive->dn % 2))
 	if (!(drive->dn % 2))
@@ -1029,7 +1031,12 @@ static int generic_ide_resume(struct device *dev)
 	rqpm.pm_step = ide_pm_state_start_resume;
 	rqpm.pm_step = ide_pm_state_start_resume;
 	rqpm.pm_state = PM_EVENT_ON;
 	rqpm.pm_state = PM_EVENT_ON;
 
 
-	return ide_do_drive_cmd(drive, &rq, ide_head_wait);
+	err = ide_do_drive_cmd(drive, &rq, ide_head_wait);
+
+	if (err == 0 && drv && drv->resume)
+		drv->resume(drive);
+
+	return err;
 }
 }
 
 
 int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,
 int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,

+ 9 - 3
drivers/ide/pci/amd74xx.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Version 2.13
+ * Version 2.15
  *
  *
  * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
  * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
  * IDE driver for Linux.
  * IDE driver for Linux.
@@ -76,6 +76,8 @@ static struct amd_ide_chip {
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_AMD_CS5536_IDE,			0x40, AMD_UDMA_100 },
 	{ PCI_DEVICE_ID_AMD_CS5536_IDE,			0x40, AMD_UDMA_100 },
 	{ 0 }
 	{ 0 }
 };
 };
@@ -494,7 +496,9 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 	/* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"),
 	/* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"),
 	/* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"),
 	/* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"),
 	/* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"),
 	/* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"),
-	/* 20 */ DECLARE_AMD_DEV("AMD5536"),
+	/* 20 */ DECLARE_NV_DEV("NFORCE-MCP73"),
+	/* 21 */ DECLARE_NV_DEV("NFORCE-MCP77"),
+	/* 22 */ DECLARE_AMD_DEV("AMD5536"),
 };
 };
 
 
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -534,7 +538,9 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 },
-	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_CS5536_IDE,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_CS5536_IDE,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22 },
 	{ 0, },
 	{ 0, },
 };
 };
 MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
 MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);

+ 23 - 14
drivers/ide/pci/generic.c

@@ -198,32 +198,41 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
 static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
 {
 	ide_pci_device_t *d = &generic_chipsets[id->driver_data];
 	ide_pci_device_t *d = &generic_chipsets[id->driver_data];
-	u16 command;
 	int ret = -ENODEV;
 	int ret = -ENODEV;
 
 
 	/* Don't use the generic entry unless instructed to do so */
 	/* Don't use the generic entry unless instructed to do so */
 	if (id->driver_data == 0 && ide_generic_all == 0)
 	if (id->driver_data == 0 && ide_generic_all == 0)
 			goto out;
 			goto out;
 
 
-	if (dev->vendor == PCI_VENDOR_ID_UMC &&
-	    dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
-	    (!(PCI_FUNC(dev->devfn) & 1)))
-		goto out; /* UM8886A/BF pair */
-
-	if (dev->vendor == PCI_VENDOR_ID_OPTI &&
-	    dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
-	    (!(PCI_FUNC(dev->devfn) & 1)))
-		goto out;
-
-	if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
-		if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1)
+	switch (dev->vendor) {
+	case PCI_VENDOR_ID_UMC:
+		if (dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
+				!(PCI_FUNC(dev->devfn) & 1))
+			goto out; /* UM8886A/BF pair */
+		break;
+	case PCI_VENDOR_ID_OPTI:
+		if (dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
+				!(PCI_FUNC(dev->devfn) & 1))
+			goto out;
+		break;
+	case PCI_VENDOR_ID_JMICRON:
+		if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 &&
+				PCI_FUNC(dev->devfn) != 1)
+			goto out;
+		break;
+	case PCI_VENDOR_ID_NS:
+		if (dev->device == PCI_DEVICE_ID_NS_87410 &&
+				(dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
 			goto out;
 			goto out;
+		break;
 	}
 	}
 
 
 	if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
 	if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
+		u16 command;
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		if (!(command & PCI_COMMAND_IO)) {
 		if (!(command & PCI_COMMAND_IO)) {
-			printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name);
+			printk(KERN_INFO "Skipping disabled %s IDE "
+					"controller.\n", d->name);
 			goto out;
 			goto out;
 		}
 		}
 	}
 	}

+ 4 - 4
drivers/ide/pci/hpt366.c

@@ -1,5 +1,5 @@
 /*
 /*
- * linux/drivers/ide/pci/hpt366.c		Version 1.03	May 4, 2007
+ * linux/drivers/ide/pci/hpt366.c		Version 1.04	Jun 4, 2007
  *
  *
  * Copyright (C) 1999-2003		Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 1999-2003		Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
@@ -106,7 +106,8 @@
  *   switch  to calculating  PCI clock frequency based on the chip's base DPLL
  *   switch  to calculating  PCI clock frequency based on the chip's base DPLL
  *   frequency
  *   frequency
  * - switch to using the  DPLL clock and enable UltraATA/133 mode by default on
  * - switch to using the  DPLL clock and enable UltraATA/133 mode by default on
- *   anything  newer than HPT370/A
+ *   anything  newer than HPT370/A (except HPT374 that is not capable of this
+ *   mode according to the manual)
  * - fold PCI clock detection and DPLL setup code into init_chipset_hpt366(),
  * - fold PCI clock detection and DPLL setup code into init_chipset_hpt366(),
  *   also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips;
  *   also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips;
  *   unify HPT36x/37x timing setup code and the speedproc handlers by joining
  *   unify HPT36x/37x timing setup code and the speedproc handlers by joining
@@ -365,7 +366,6 @@ static u32 sixty_six_base_hpt37x[] = {
 };
 };
 
 
 #define HPT366_DEBUG_DRIVE_INFO		0
 #define HPT366_DEBUG_DRIVE_INFO		0
-#define HPT374_ALLOW_ATA133_6		1
 #define HPT371_ALLOW_ATA133_6		1
 #define HPT371_ALLOW_ATA133_6		1
 #define HPT302_ALLOW_ATA133_6		1
 #define HPT302_ALLOW_ATA133_6		1
 #define HPT372_ALLOW_ATA133_6		1
 #define HPT372_ALLOW_ATA133_6		1
@@ -450,7 +450,7 @@ static struct hpt_info hpt370a __devinitdata = {
 
 
 static struct hpt_info hpt374 __devinitdata = {
 static struct hpt_info hpt374 __devinitdata = {
 	.chip_type	= HPT374,
 	.chip_type	= HPT374,
-	.max_mode	= HPT374_ALLOW_ATA133_6 ? 4 : 3,
+	.max_mode	= 3,
 	.dpll_clk	= 48,
 	.dpll_clk	= 48,
 	.settings	= hpt37x_settings
 	.settings	= hpt37x_settings
 };
 };

+ 18 - 16
drivers/ide/pci/it821x.c

@@ -1,6 +1,6 @@
 
 
 /*
 /*
- * linux/drivers/ide/pci/it821x.c		Version 0.10	Mar 10 2007
+ * linux/drivers/ide/pci/it821x.c		Version 0.15	Jun 2 2007
  *
  *
  * Copyright (C) 2004		Red Hat <alan@redhat.com>
  * Copyright (C) 2004		Red Hat <alan@redhat.com>
  * Copyright (C) 2007		Bartlomiej Zolnierkiewicz
  * Copyright (C) 2007		Bartlomiej Zolnierkiewicz
@@ -262,7 +262,7 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
 	}
 	}
 
 
 	if (itdev->smart)
 	if (itdev->smart)
-		goto set_drive_speed;
+		return 0;
 
 
 	/* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
 	/* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
 	itdev->want[unit][1] = pio_want[set_pio];
 	itdev->want[unit][1] = pio_want[set_pio];
@@ -271,7 +271,6 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
 	it821x_clock_strategy(drive);
 	it821x_clock_strategy(drive);
 	it821x_program(drive, itdev->pio[unit]);
 	it821x_program(drive, itdev->pio[unit]);
 
 
-set_drive_speed:
 	return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
 	return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
 }
 }
 
 
@@ -455,12 +454,12 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed)
 			default:
 			default:
 				return 1;
 				return 1;
 		}
 		}
+
+		return ide_config_drive_speed(drive, speed);
 	}
 	}
-	/*
-	 *	In smart mode the clocking is done by the host controller
-	 * 	snooping the mode we picked. The rest of it is not our problem
-	 */
-	return ide_config_drive_speed(drive, speed);
+
+	/* don't touch anything in the smart mode */
+	return 0;
 }
 }
 
 
 /**
 /**
@@ -559,17 +558,10 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
 				if(idbits[129] != 1)
 				if(idbits[129] != 1)
 					printk("(%dK stripe)", idbits[146]);
 					printk("(%dK stripe)", idbits[146]);
 				printk(".\n");
 				printk(".\n");
-			/* Now the core code will have wrongly decided no DMA
-			   so we need to fix this */
-			hwif->dma_off_quietly(drive);
-#ifdef CONFIG_IDEDMA_ONLYDISK
-			if (drive->media == ide_disk)
-#endif
-				ide_set_dma(drive);
 		} else {
 		} else {
 			/* Non RAID volume. Fixups to stop the core code
 			/* Non RAID volume. Fixups to stop the core code
 			   doing unsupported things */
 			   doing unsupported things */
-			id->field_valid &= 1;
+			id->field_valid &= 3;
 			id->queue_depth = 0;
 			id->queue_depth = 0;
 			id->command_set_1 = 0;
 			id->command_set_1 = 0;
 			id->command_set_2 &= 0xC400;
 			id->command_set_2 &= 0xC400;
@@ -584,6 +576,16 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
 			printk(KERN_INFO "%s: Performing identify fixups.\n",
 			printk(KERN_INFO "%s: Performing identify fixups.\n",
 				drive->name);
 				drive->name);
 		}
 		}
+
+		/*
+		 * Set MWDMA0 mode as enabled/support - just to tell
+		 * IDE core that DMA is supported (it821x hardware
+		 * takes care of DMA mode programming).
+		 */
+		if (id->capability & 1) {
+			id->dma_mword |= 0x0101;
+			drive->current_speed = XFER_MW_DMA_0;
+		}
 	}
 	}
 
 
 }
 }

+ 32 - 19
drivers/ide/pci/serverworks.c

@@ -1,5 +1,5 @@
 /*
 /*
- * linux/drivers/ide/pci/serverworks.c		Version 0.9	Mar 4 2007
+ * linux/drivers/ide/pci/serverworks.c		Version 0.11	Jun 2 2007
  *
  *
  * Copyright (C) 1998-2000 Michel Aubry
  * Copyright (C) 1998-2000 Michel Aubry
  * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
  * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
@@ -170,42 +170,55 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
 		if (!drive->init_speed) {
 		if (!drive->init_speed) {
 			u8 dma_stat = inb(hwif->dma_status);
 			u8 dma_stat = inb(hwif->dma_status);
 
 
-dma_pio:
 			if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
 			if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
 			    ((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) {
 			    ((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) {
 				drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)];
 				drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)];
 				return 0;
 				return 0;
 			} else if ((dma_timing) &&
 			} else if ((dma_timing) &&
 				   ((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) {
 				   ((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) {
-				u8 dmaspeed = dma_timing;
+				u8 dmaspeed;
 
 
-				dma_timing &= ~0xFFU;
-				if ((dmaspeed & 0x20) == 0x20)
+				switch (dma_timing & 0x77) {
+				case 0x20:
 					dmaspeed = XFER_MW_DMA_2;
 					dmaspeed = XFER_MW_DMA_2;
-				else if ((dmaspeed & 0x21) == 0x21)
+					break;
+				case 0x21:
 					dmaspeed = XFER_MW_DMA_1;
 					dmaspeed = XFER_MW_DMA_1;
-				else if ((dmaspeed & 0x77) == 0x77)
+					break;
+				case 0x77:
 					dmaspeed = XFER_MW_DMA_0;
 					dmaspeed = XFER_MW_DMA_0;
-				else
+					break;
+				default:
 					goto dma_pio;
 					goto dma_pio;
+				}
+
 				drive->current_speed = drive->init_speed = dmaspeed;
 				drive->current_speed = drive->init_speed = dmaspeed;
 				return 0;
 				return 0;
-			} else if (pio_timing) {
-				u8 piospeed = pio_timing;
+			}
+dma_pio:
+			if (pio_timing) {
+				u8 piospeed;
 
 
-				pio_timing &= ~0xFFU;
-				if ((piospeed & 0x20) == 0x20)
+				switch (pio_timing & 0x7f) {
+				case 0x20:
 					piospeed = XFER_PIO_4;
 					piospeed = XFER_PIO_4;
-				else if ((piospeed & 0x22) == 0x22)
+					break;
+				case 0x22:
 					piospeed = XFER_PIO_3;
 					piospeed = XFER_PIO_3;
-				else if ((piospeed & 0x34) == 0x34)
+					break;
+				case 0x34:
 					piospeed = XFER_PIO_2;
 					piospeed = XFER_PIO_2;
-				else if ((piospeed & 0x47) == 0x47)
+					break;
+				case 0x47:
 					piospeed = XFER_PIO_1;
 					piospeed = XFER_PIO_1;
-				else if ((piospeed & 0x5d) == 0x5d)
+					break;
+				case 0x5d:
 					piospeed = XFER_PIO_0;
 					piospeed = XFER_PIO_0;
-				else
+					break;
+				default:
 					goto oem_setup_failed;
 					goto oem_setup_failed;
+				}
+
 				drive->current_speed = drive->init_speed = piospeed;
 				drive->current_speed = drive->init_speed = piospeed;
 				return 0;
 				return 0;
 			}
 			}
@@ -214,8 +227,8 @@ dma_pio:
 
 
 oem_setup_failed:
 oem_setup_failed:
 
 
-	pio_timing	&= ~0xFFU;
-	dma_timing	&= ~0xFFU;
+	pio_timing	= 0;
+	dma_timing	= 0;
 	ultra_timing	&= ~(0x0F << (4*unit));
 	ultra_timing	&= ~(0x0F << (4*unit));
 	ultra_enable	&= ~(0x01 << drive->dn);
 	ultra_enable	&= ~(0x01 << drive->dn);
 	csb5_pio	&= ~(0x0F << (4*drive->dn));
 	csb5_pio	&= ~(0x0F << (4*drive->dn));

+ 2 - 2
drivers/infiniband/core/cma.c

@@ -2773,8 +2773,8 @@ static int cma_init(void)
 	int ret;
 	int ret;
 
 
 	get_random_bytes(&next_port, sizeof next_port);
 	get_random_bytes(&next_port, sizeof next_port);
-	next_port = (next_port % (sysctl_local_port_range[1] -
-				  sysctl_local_port_range[0])) +
+	next_port = ((unsigned int) next_port %
+		    (sysctl_local_port_range[1] - sysctl_local_port_range[0])) +
 		    sysctl_local_port_range[0];
 		    sysctl_local_port_range[0];
 	cma_wq = create_singlethread_workqueue("rdma_cm");
 	cma_wq = create_singlethread_workqueue("rdma_cm");
 	if (!cma_wq)
 	if (!cma_wq)

+ 22 - 11
drivers/infiniband/hw/mlx4/qp.c

@@ -189,18 +189,28 @@ static int send_wqe_overhead(enum ib_qp_type type)
 }
 }
 
 
 static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
 static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
-		       struct mlx4_ib_qp *qp)
+		       int is_user, int has_srq, struct mlx4_ib_qp *qp)
 {
 {
 	/* Sanity check RQ size before proceeding */
 	/* Sanity check RQ size before proceeding */
 	if (cap->max_recv_wr  > dev->dev->caps.max_wqes  ||
 	if (cap->max_recv_wr  > dev->dev->caps.max_wqes  ||
 	    cap->max_recv_sge > dev->dev->caps.max_rq_sg)
 	    cap->max_recv_sge > dev->dev->caps.max_rq_sg)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	qp->rq.max = cap->max_recv_wr ? roundup_pow_of_two(cap->max_recv_wr) : 0;
+	if (has_srq) {
+		/* QPs attached to an SRQ should have no RQ */
+		if (cap->max_recv_wr)
+			return -EINVAL;
+
+		qp->rq.max = qp->rq.max_gs = 0;
+	} else {
+		/* HW requires >= 1 RQ entry with >= 1 gather entry */
+		if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge))
+			return -EINVAL;
 
 
-	qp->rq.wqe_shift = ilog2(roundup_pow_of_two(cap->max_recv_sge *
-						    sizeof (struct mlx4_wqe_data_seg)));
-	qp->rq.max_gs    = (1 << qp->rq.wqe_shift) / sizeof (struct mlx4_wqe_data_seg);
+		qp->rq.max	 = roundup_pow_of_two(max(1, cap->max_recv_wr));
+		qp->rq.max_gs	 = roundup_pow_of_two(max(1, cap->max_recv_sge));
+		qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
+	}
 
 
 	cap->max_recv_wr  = qp->rq.max;
 	cap->max_recv_wr  = qp->rq.max;
 	cap->max_recv_sge = qp->rq.max_gs;
 	cap->max_recv_sge = qp->rq.max_gs;
@@ -285,7 +295,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
 	qp->sq.head	    = 0;
 	qp->sq.head	    = 0;
 	qp->sq.tail	    = 0;
 	qp->sq.tail	    = 0;
 
 
-	err = set_rq_size(dev, &init_attr->cap, qp);
+	err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, !!init_attr->srq, qp);
 	if (err)
 	if (err)
 		goto err;
 		goto err;
 
 
@@ -762,11 +772,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
 		optpar |= MLX4_QP_OPTPAR_PKEY_INDEX;
 		optpar |= MLX4_QP_OPTPAR_PKEY_INDEX;
 	}
 	}
 
 
-	if (attr_mask & IB_QP_RNR_RETRY) {
-		context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
-		optpar |= MLX4_QP_OPTPAR_RNR_RETRY;
-	}
-
 	if (attr_mask & IB_QP_AV) {
 	if (attr_mask & IB_QP_AV) {
 		if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path,
 		if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path,
 				  attr_mask & IB_QP_PORT ? attr->port_num : qp->port)) {
 				  attr_mask & IB_QP_PORT ? attr->port_num : qp->port)) {
@@ -802,6 +807,12 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
 
 
 	context->pd	    = cpu_to_be32(to_mpd(ibqp->pd)->pdn);
 	context->pd	    = cpu_to_be32(to_mpd(ibqp->pd)->pdn);
 	context->params1    = cpu_to_be32(MLX4_IB_ACK_REQ_FREQ << 28);
 	context->params1    = cpu_to_be32(MLX4_IB_ACK_REQ_FREQ << 28);
+
+	if (attr_mask & IB_QP_RNR_RETRY) {
+		context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
+		optpar |= MLX4_QP_OPTPAR_RNR_RETRY;
+	}
+
 	if (attr_mask & IB_QP_RETRY_CNT) {
 	if (attr_mask & IB_QP_RETRY_CNT) {
 		context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
 		context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
 		optpar |= MLX4_QP_OPTPAR_RETRY_COUNT;
 		optpar |= MLX4_QP_OPTPAR_RETRY_COUNT;

+ 1 - 1
drivers/infiniband/hw/mthca/mthca_cmd.c

@@ -772,7 +772,7 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
 
 
 	MTHCA_GET(dev->fw_ver,   outbox, QUERY_FW_VER_OFFSET);
 	MTHCA_GET(dev->fw_ver,   outbox, QUERY_FW_VER_OFFSET);
 	/*
 	/*
-	 * FW subminor version is at more signifant bits than minor
+	 * FW subminor version is at more significant bits than minor
 	 * version, so swap here.
 	 * version, so swap here.
 	 */
 	 */
 	dev->fw_ver = (dev->fw_ver & 0xffff00000000ull) |
 	dev->fw_ver = (dev->fw_ver & 0xffff00000000ull) |

+ 1 - 0
drivers/media/common/Kconfig

@@ -4,5 +4,6 @@ config VIDEO_SAA7146
 
 
 config VIDEO_SAA7146_VV
 config VIDEO_SAA7146_VV
 	tristate
 	tristate
+	depends on VIDEO_DEV
 	select VIDEO_BUF
 	select VIDEO_BUF
 	select VIDEO_SAA7146
 	select VIDEO_SAA7146

+ 5 - 2
drivers/media/dvb/b2c2/Makefile

@@ -1,8 +1,11 @@
 b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
 b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
-	flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o \
-	flexcop-dma.o
+	flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
 
 
+ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
+b2c2-flexcop-objs += flexcop-dma.o
+endif
+
 b2c2-flexcop-pci-objs = flexcop-pci.o
 b2c2-flexcop-pci-objs = flexcop-pci.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
 
 

+ 1 - 2
drivers/media/dvb/cinergyT2/cinergyT2.c

@@ -519,8 +519,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_device *dvbdev = file->private_data;
 	struct cinergyt2 *cinergyt2 = dvbdev->priv;
 	struct cinergyt2 *cinergyt2 = dvbdev->priv;
 
 
-	if (mutex_lock_interruptible(&cinergyt2->sem))
-		return -ERESTARTSYS;
+	mutex_lock(&cinergyt2->sem);
 
 
 	if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
 	if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
 		cancel_delayed_work(&cinergyt2->query_work);
 		cancel_delayed_work(&cinergyt2->query_work);

+ 16 - 5
drivers/media/dvb/frontends/tda10086.c

@@ -41,6 +41,7 @@ struct tda10086_state {
 	/* private demod data */
 	/* private demod data */
 	u32 frequency;
 	u32 frequency;
 	u32 symbol_rate;
 	u32 symbol_rate;
+	bool has_lock;
 };
 };
 
 
 static int debug = 0;
 static int debug = 0;
@@ -116,7 +117,7 @@ static int tda10086_init(struct dvb_frontend* fe)
 	// misc setup
 	// misc setup
 	tda10086_write_byte(state, 0x01, 0x94);
 	tda10086_write_byte(state, 0x01, 0x94);
 	tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP
 	tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP
-	tda10086_write_byte(state, 0x03, 0x64);
+	tda10086_write_byte(state, 0x03, 0xe4);
 	tda10086_write_byte(state, 0x04, 0x43);
 	tda10086_write_byte(state, 0x04, 0x43);
 	tda10086_write_byte(state, 0x0c, 0x0c);
 	tda10086_write_byte(state, 0x0c, 0x0c);
 	tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
 	tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
@@ -146,7 +147,7 @@ static int tda10086_init(struct dvb_frontend* fe)
 	// setup AGC
 	// setup AGC
 	tda10086_write_byte(state, 0x05, 0x0B);
 	tda10086_write_byte(state, 0x05, 0x0B);
 	tda10086_write_byte(state, 0x37, 0x63);
 	tda10086_write_byte(state, 0x37, 0x63);
-	tda10086_write_byte(state, 0x3f, 0x03); // NOTE: flydvb uses 0x0a and varies it
+	tda10086_write_byte(state, 0x3f, 0x0a); // NOTE: flydvb varies it
 	tda10086_write_byte(state, 0x40, 0x64);
 	tda10086_write_byte(state, 0x40, 0x64);
 	tda10086_write_byte(state, 0x41, 0x4f);
 	tda10086_write_byte(state, 0x41, 0x4f);
 	tda10086_write_byte(state, 0x42, 0x43);
 	tda10086_write_byte(state, 0x42, 0x43);
@@ -398,6 +399,10 @@ static int tda10086_set_frontend(struct dvb_frontend* fe,
 
 
 	dprintk ("%s\n", __FUNCTION__);
 	dprintk ("%s\n", __FUNCTION__);
 
 
+	// modify parameters for tuning
+	tda10086_write_byte(state, 0x02, 0x35);
+	state->has_lock = false;
+
 	// set params
 	// set params
 	if (fe->ops.tuner_ops.set_params) {
 	if (fe->ops.tuner_ops.set_params) {
 		fe->ops.tuner_ops.set_params(fe, fe_params);
 		fe->ops.tuner_ops.set_params(fe, fe_params);
@@ -542,8 +547,14 @@ static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
 		*fe_status |= FE_HAS_VITERBI;
 		*fe_status |= FE_HAS_VITERBI;
 	if (val & 0x08)
 	if (val & 0x08)
 		*fe_status |= FE_HAS_SYNC;
 		*fe_status |= FE_HAS_SYNC;
-	if (val & 0x10)
+	if (val & 0x10) {
 		*fe_status |= FE_HAS_LOCK;
 		*fe_status |= FE_HAS_LOCK;
+		if (!state->has_lock) {
+			state->has_lock = true;
+			// modify parameters for stable reception
+			tda10086_write_byte(state, 0x02, 0x00);
+		}
+	}
 
 
 	return 0;
 	return 0;
 }
 }
@@ -555,7 +566,7 @@ static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
 
 
 	dprintk ("%s\n", __FUNCTION__);
 	dprintk ("%s\n", __FUNCTION__);
 
 
-	_str = tda10086_read_byte(state, 0x43);
+	_str = 0xff - tda10086_read_byte(state, 0x43);
 	*signal = (_str << 8) | _str;
 	*signal = (_str << 8) | _str;
 
 
 	return 0;
 	return 0;
@@ -568,7 +579,7 @@ static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
 
 
 	dprintk ("%s\n", __FUNCTION__);
 	dprintk ("%s\n", __FUNCTION__);
 
 
-	_snr = tda10086_read_byte(state, 0x1c);
+	_snr = 0xff - tda10086_read_byte(state, 0x1c);
 	*snr = (_snr << 8) | _snr;
 	*snr = (_snr << 8) | _snr;
 
 
 	return 0;
 	return 0;

+ 2 - 2
drivers/media/dvb/frontends/tda826x.c

@@ -89,8 +89,8 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
 	buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
 	buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
 	buf[3] = div >> 7;
 	buf[3] = div >> 7;
 	buf[4] = div << 1;
 	buf[4] = div << 1;
-	buf[5] = 0xff; // basedband filter to max
-	buf[6] = 0xfe; // gains at max + no RF attenuation
+	buf[5] = 0x77; // baseband cut-off 19 MHz
+	buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
 	buf[7] = 0x83; // charge pumps at high, tests off
 	buf[7] = 0x83; // charge pumps at high, tests off
 	buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
 	buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
 	buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
 	buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL

+ 1 - 1
drivers/media/video/Kconfig

@@ -347,7 +347,7 @@ endmenu # encoder / decoder chips
 
 
 config VIDEO_VIVI
 config VIDEO_VIVI
 	tristate "Virtual Video Driver"
 	tristate "Virtual Video Driver"
-	depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI
+	depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI && VIDEO_DEV
 	select VIDEO_BUF
 	select VIDEO_BUF
 	default n
 	default n
 	---help---
 	---help---

+ 1 - 1
drivers/media/video/ivtv/ivtv-cards.h

@@ -86,7 +86,7 @@
 			  V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
 			  V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
 			  V4L2_CAP_SLICED_VBI_CAPTURE)
 			  V4L2_CAP_SLICED_VBI_CAPTURE)
 #define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \
 #define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \
-			  V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_POS)
+			  V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
 
 
 struct ivtv_card_video_input {
 struct ivtv_card_video_input {
 	u8  video_type; 	/* video input type */
 	u8  video_type; 	/* video input type */

+ 1 - 0
drivers/media/video/ivtv/ivtv-driver.c

@@ -652,6 +652,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
 	itv->dma_timer.data = (unsigned long)itv;
 	itv->dma_timer.data = (unsigned long)itv;
 
 
 	itv->cur_dma_stream = -1;
 	itv->cur_dma_stream = -1;
+	itv->cur_pio_stream = -1;
 	itv->audio_stereo_mode = AUDIO_STEREO;
 	itv->audio_stereo_mode = AUDIO_STEREO;
 	itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
 	itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
 
 

+ 13 - 3
drivers/media/video/ivtv/ivtv-driver.h

@@ -237,6 +237,7 @@ extern const u32 yuv_offset[4];
 #define IVTV_IRQ_ENC_VBI_CAP		(0x1 << 29)
 #define IVTV_IRQ_ENC_VBI_CAP		(0x1 << 29)
 #define IVTV_IRQ_ENC_VIM_RST		(0x1 << 28)
 #define IVTV_IRQ_ENC_VIM_RST		(0x1 << 28)
 #define IVTV_IRQ_ENC_DMA_COMPLETE	(0x1 << 27)
 #define IVTV_IRQ_ENC_DMA_COMPLETE	(0x1 << 27)
+#define IVTV_IRQ_ENC_PIO_COMPLETE	(0x1 << 25)
 #define IVTV_IRQ_DEC_AUD_MODE_CHG	(0x1 << 24)
 #define IVTV_IRQ_DEC_AUD_MODE_CHG	(0x1 << 24)
 #define IVTV_IRQ_DEC_DATA_REQ		(0x1 << 22)
 #define IVTV_IRQ_DEC_DATA_REQ		(0x1 << 22)
 #define IVTV_IRQ_DEC_DMA_COMPLETE	(0x1 << 20)
 #define IVTV_IRQ_DEC_DMA_COMPLETE	(0x1 << 20)
@@ -247,7 +248,8 @@ extern const u32 yuv_offset[4];
 #define IVTV_IRQ_DEC_VSYNC		(0x1 << 10)
 #define IVTV_IRQ_DEC_VSYNC		(0x1 << 10)
 
 
 /* IRQ Masks */
 /* IRQ Masks */
-#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|IVTV_IRQ_DMA_READ)
+#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
+		IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE)
 
 
 #define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
 #define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
 #define IVTV_IRQ_MASK_DECODE  (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
 #define IVTV_IRQ_MASK_DECODE  (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
@@ -374,6 +376,9 @@ struct ivtv_mailbox_data {
 #define IVTV_F_S_STREAMOFF	7	/* signal end of stream EOS */
 #define IVTV_F_S_STREAMOFF	7	/* signal end of stream EOS */
 #define IVTV_F_S_APPL_IO        8	/* this stream is used read/written by an application */
 #define IVTV_F_S_APPL_IO        8	/* this stream is used read/written by an application */
 
 
+#define IVTV_F_S_PIO_PENDING	9	/* this stream has pending PIO */
+#define IVTV_F_S_PIO_HAS_VBI	1       /* the current PIO request also requests VBI data */
+
 /* per-ivtv, i_flags */
 /* per-ivtv, i_flags */
 #define IVTV_F_I_DMA		   0 	/* DMA in progress */
 #define IVTV_F_I_DMA		   0 	/* DMA in progress */
 #define IVTV_F_I_UDMA		   1 	/* UDMA in progress */
 #define IVTV_F_I_UDMA		   1 	/* UDMA in progress */
@@ -390,8 +395,11 @@ struct ivtv_mailbox_data {
 #define IVTV_F_I_DECODING_YUV	   12 	/* this stream is YUV frame decoding */
 #define IVTV_F_I_DECODING_YUV	   12 	/* this stream is YUV frame decoding */
 #define IVTV_F_I_ENC_PAUSED	   13 	/* the encoder is paused */
 #define IVTV_F_I_ENC_PAUSED	   13 	/* the encoder is paused */
 #define IVTV_F_I_VALID_DEC_TIMINGS 14 	/* last_dec_timing is valid */
 #define IVTV_F_I_VALID_DEC_TIMINGS 14 	/* last_dec_timing is valid */
-#define IVTV_F_I_WORK_HANDLER_VBI  15	/* there is work to be done for VBI */
-#define IVTV_F_I_WORK_HANDLER_YUV  16	/* there is work to be done for YUV */
+#define IVTV_F_I_HAVE_WORK  	   15	/* Used in the interrupt handler: there is work to be done */
+#define IVTV_F_I_WORK_HANDLER_VBI  16	/* there is work to be done for VBI */
+#define IVTV_F_I_WORK_HANDLER_YUV  17	/* there is work to be done for YUV */
+#define IVTV_F_I_WORK_HANDLER_PIO  18	/* there is work to be done for PIO */
+#define IVTV_F_I_PIO		   19	/* PIO in progress */
 
 
 /* Event notifications */
 /* Event notifications */
 #define IVTV_F_I_EV_DEC_STOPPED	   28	/* decoder stopped event */
 #define IVTV_F_I_EV_DEC_STOPPED	   28	/* decoder stopped event */
@@ -484,6 +492,7 @@ struct ivtv_stream {
 
 
 	/* Base Dev SG Array for cx23415/6 */
 	/* Base Dev SG Array for cx23415/6 */
 	struct ivtv_SG_element *SGarray;
 	struct ivtv_SG_element *SGarray;
+	struct ivtv_SG_element *PIOarray;
 	dma_addr_t SG_handle;
 	dma_addr_t SG_handle;
 	int SG_length;
 	int SG_length;
 
 
@@ -706,6 +715,7 @@ struct ivtv {
 	atomic_t decoding;	/* count number of active decoding streams */
 	atomic_t decoding;	/* count number of active decoding streams */
 	u32 irq_rr_idx; /* Round-robin stream index */
 	u32 irq_rr_idx; /* Round-robin stream index */
 	int cur_dma_stream;	/* index of stream doing DMA */
 	int cur_dma_stream;	/* index of stream doing DMA */
+	int cur_pio_stream;	/* index of stream doing PIO */
 	u32 dma_data_req_offset;
 	u32 dma_data_req_offset;
 	u32 dma_data_req_size;
 	u32 dma_data_req_size;
 	int output_mode;        /* NONE, MPG, YUV, UDMA YUV, passthrough */
 	int output_mode;        /* NONE, MPG, YUV, UDMA YUV, passthrough */

+ 16 - 0
drivers/media/video/ivtv/ivtv-fileops.c

@@ -32,6 +32,8 @@
 #include "ivtv-yuv.h"
 #include "ivtv-yuv.h"
 #include "ivtv-controls.h"
 #include "ivtv-controls.h"
 #include "ivtv-ioctl.h"
 #include "ivtv-ioctl.h"
+#include "ivtv-cards.h"
+#include <media/saa7115.h>
 
 
 /* This function tries to claim the stream for a specific file descriptor.
 /* This function tries to claim the stream for a specific file descriptor.
    If no one else is using this stream then the stream is claimed and
    If no one else is using this stream then the stream is claimed and
@@ -786,6 +788,13 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
 		ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
 		ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
 		/* Select correct audio input (i.e. TV tuner or Line in) */
 		/* Select correct audio input (i.e. TV tuner or Line in) */
 		ivtv_audio_set_io(itv);
 		ivtv_audio_set_io(itv);
+		if (itv->hw_flags & IVTV_HW_SAA711X)
+		{
+			struct v4l2_crystal_freq crystal_freq;
+			crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
+			crystal_freq.flags = 0;
+			ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+		}
 		/* Done! Unmute and continue. */
 		/* Done! Unmute and continue. */
 		ivtv_unmute(itv);
 		ivtv_unmute(itv);
 		ivtv_release_stream(s);
 		ivtv_release_stream(s);
@@ -872,6 +881,13 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
 		set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
 		set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
 		/* Select the correct audio input (i.e. radio tuner) */
 		/* Select the correct audio input (i.e. radio tuner) */
 		ivtv_audio_set_io(itv);
 		ivtv_audio_set_io(itv);
+		if (itv->hw_flags & IVTV_HW_SAA711X)
+		{
+			struct v4l2_crystal_freq crystal_freq;
+			crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
+			crystal_freq.flags = SAA7115_FREQ_FL_APLL;
+			ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+		}
 		/* Done! Unmute and continue. */
 		/* Done! Unmute and continue. */
 		ivtv_unmute(itv);
 		ivtv_unmute(itv);
 	}
 	}

+ 38 - 7
drivers/media/video/ivtv/ivtv-ioctl.c

@@ -532,11 +532,6 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
 				itv->yuv_info.yuv_forced_update = 1;
 				itv->yuv_info.yuv_forced_update = 1;
 				return 0;
 				return 0;
 			}
 			}
-			if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
-				 r.width, r.height, r.left, r.top))
-				itv->main_rect = r;
-			else
-				return -EINVAL;
 		}
 		}
 		return 0;
 		return 0;
 	}
 	}
@@ -799,9 +794,39 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
 		return ivtv_get_fmt(itv, id->type, fmt);
 		return ivtv_get_fmt(itv, id->type, fmt);
 	}
 	}
 
 
+	case VIDIOC_CROPCAP: {
+		struct v4l2_cropcap *cropcap = arg;
+
+		if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+		    cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+			return -EINVAL;
+		cropcap->bounds.top = cropcap->bounds.left = 0;
+		cropcap->bounds.width = 720;
+		if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+			cropcap->bounds.height = itv->is_50hz ? 576 : 480;
+			cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
+			cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
+		} else {
+			cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
+			cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
+			cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+		}
+		cropcap->defrect = cropcap->bounds;
+		return 0;
+	}
+
 	case VIDIOC_S_CROP: {
 	case VIDIOC_S_CROP: {
 		struct v4l2_crop *crop = arg;
 		struct v4l2_crop *crop = arg;
 
 
+		if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+		    (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+			if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+				 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
+				itv->main_rect = crop->c;
+				return 0;
+			}
+			return -EINVAL;
+		}
 		if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 			return -EINVAL;
 			return -EINVAL;
 		return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
 		return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
@@ -810,6 +835,11 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
 	case VIDIOC_G_CROP: {
 	case VIDIOC_G_CROP: {
 		struct v4l2_crop *crop = arg;
 		struct v4l2_crop *crop = arg;
 
 
+		if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+		    (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+			crop->c = itv->main_rect;
+			return 0;
+		}
 		if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 			return -EINVAL;
 			return -EINVAL;
 		return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
 		return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
@@ -977,7 +1007,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
 		if (itv->hw_flags & IVTV_HW_CX25840) {
 		if (itv->hw_flags & IVTV_HW_CX25840) {
 			itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
 			itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
 		}
 		}
-		IVTV_DEBUG_INFO("Switching standard to %llx.\n", itv->std);
+		IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
 
 
 		/* Tuner */
 		/* Tuner */
 		ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
 		ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
@@ -1207,7 +1237,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
 					(s->buffers - s->q_free.buffers) * 100 / s->buffers,
 					(s->buffers - s->q_free.buffers) * 100 / s->buffers,
 					(s->buffers * s->buf_size) / 1024, s->buffers);
 					(s->buffers * s->buf_size) / 1024, s->buffers);
 		}
 		}
-		IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", itv->mpg_data_received, itv->vbi_data_inserted);
+		IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
 		IVTV_INFO("==================  END STATUS CARD #%d  ==================\n", itv->num);
 		IVTV_INFO("==================  END STATUS CARD #%d  ==================\n", itv->num);
 		break;
 		break;
 	}
 	}
@@ -1455,6 +1485,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
 	case VIDIOC_S_FMT:
 	case VIDIOC_S_FMT:
 	case VIDIOC_TRY_FMT:
 	case VIDIOC_TRY_FMT:
 	case VIDIOC_ENUM_FMT:
 	case VIDIOC_ENUM_FMT:
+	case VIDIOC_CROPCAP:
 	case VIDIOC_G_CROP:
 	case VIDIOC_G_CROP:
 	case VIDIOC_S_CROP:
 	case VIDIOC_S_CROP:
 	case VIDIOC_G_FREQUENCY:
 	case VIDIOC_G_FREQUENCY:

+ 137 - 67
drivers/media/video/ivtv/ivtv-irq.c

@@ -31,8 +31,6 @@
 
 
 #define DMA_MAGIC_COOKIE 0x000001fe
 #define DMA_MAGIC_COOKIE 0x000001fe
 
 
-#define SLICED_VBI_PIO 1
-
 static void ivtv_dma_dec_start(struct ivtv_stream *s);
 static void ivtv_dma_dec_start(struct ivtv_stream *s);
 
 
 static const int ivtv_stream_map[] = {
 static const int ivtv_stream_map[] = {
@@ -42,12 +40,40 @@ static const int ivtv_stream_map[] = {
 	IVTV_ENC_STREAM_TYPE_VBI,
 	IVTV_ENC_STREAM_TYPE_VBI,
 };
 };
 
 
-static inline int ivtv_use_pio(struct ivtv_stream *s)
+
+static void ivtv_pio_work_handler(struct ivtv *itv)
 {
 {
-	struct ivtv *itv = s->itv;
+	struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
+	struct ivtv_buffer *buf;
+	struct list_head *p;
+	int i = 0;
+
+	IVTV_DEBUG_DMA("ivtv_pio_work_handler\n");
+	if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
+			s->v4l2dev == NULL || !ivtv_use_pio(s)) {
+		itv->cur_pio_stream = -1;
+		/* trigger PIO complete user interrupt */
+		write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
+		return;
+	}
+	IVTV_DEBUG_DMA("Process PIO %s\n", s->name);
+	buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list);
+	list_for_each(p, &s->q_dma.list) {
+		struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
+		u32 size = s->PIOarray[i].size & 0x3ffff;
 
 
-	return s->dma == PCI_DMA_NONE ||
-	    (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
+		/* Copy the data from the card to the buffer */
+		if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
+			memcpy_fromio(buf->buf, itv->dec_mem + s->PIOarray[i].src - IVTV_DECODER_OFFSET, size);
+		}
+		else {
+			memcpy_fromio(buf->buf, itv->enc_mem + s->PIOarray[i].src, size);
+		}
+		if (s->PIOarray[i].size & 0x80000000)
+			break;
+		i++;
+	}
+	write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
 }
 }
 
 
 void ivtv_irq_work_handler(struct work_struct *work)
 void ivtv_irq_work_handler(struct work_struct *work)
@@ -56,8 +82,11 @@ void ivtv_irq_work_handler(struct work_struct *work)
 
 
 	DEFINE_WAIT(wait);
 	DEFINE_WAIT(wait);
 
 
+	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
+		ivtv_pio_work_handler(itv);
+
 	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
 	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
-		vbi_work_handler(itv);
+		ivtv_vbi_work_handler(itv);
 
 
 	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
 	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
 		ivtv_yuv_work_handler(itv);
 		ivtv_yuv_work_handler(itv);
@@ -173,8 +202,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
 	}
 	}
 	s->buffers_stolen = rc;
 	s->buffers_stolen = rc;
 
 
-	/* got the buffers, now fill in SGarray (DMA) or copy the data from the card
-	   to the buffers (PIO). */
+	/* got the buffers, now fill in SGarray (DMA) */
 	buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
 	buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
 	memset(buf->buf, 0, 128);
 	memset(buf->buf, 0, 128);
 	list_for_each(p, &s->q_predma.list) {
 	list_for_each(p, &s->q_predma.list) {
@@ -182,21 +210,11 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
 
 
 		if (skip_bufs-- > 0)
 		if (skip_bufs-- > 0)
 			continue;
 			continue;
-		if (!ivtv_use_pio(s)) {
-			s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
-			s->SGarray[idx].src = cpu_to_le32(offset);
-			s->SGarray[idx].size = cpu_to_le32(s->buf_size);
-		}
+		s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
+		s->SGarray[idx].src = cpu_to_le32(offset);
+		s->SGarray[idx].size = cpu_to_le32(s->buf_size);
 		buf->bytesused = (size < s->buf_size) ? size : s->buf_size;
 		buf->bytesused = (size < s->buf_size) ? size : s->buf_size;
 
 
-		/* If PIO, then copy the data from the card to the buffer */
-		if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
-			memcpy_fromio(buf->buf, itv->dec_mem + offset - IVTV_DECODER_OFFSET, buf->bytesused);
-		}
-		else if (ivtv_use_pio(s)) {
-			memcpy_fromio(buf->buf, itv->enc_mem + offset, buf->bytesused);
-		}
-
 		s->q_predma.bytesused += buf->bytesused;
 		s->q_predma.bytesused += buf->bytesused;
 		size -= buf->bytesused;
 		size -= buf->bytesused;
 		offset += s->buf_size;
 		offset += s->buf_size;
@@ -224,11 +242,6 @@ static void dma_post(struct ivtv_stream *s)
 	u32 *u32buf;
 	u32 *u32buf;
 	int x = 0;
 	int x = 0;
 
 
-	if (ivtv_use_pio(s)) {
-		if (s->q_predma.bytesused)
-			ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
-		s->SG_length = 0;
-	}
 	IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
 	IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
 			s->name, s->dma_offset);
 			s->name, s->dma_offset);
 	list_for_each(p, &s->q_dma.list) {
 	list_for_each(p, &s->q_dma.list) {
@@ -278,10 +291,14 @@ static void dma_post(struct ivtv_stream *s)
 	if (buf)
 	if (buf)
 		buf->bytesused += s->dma_last_offset;
 		buf->bytesused += s->dma_last_offset;
 	if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
 	if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
-		/* Parse and Groom VBI Data */
-		s->q_dma.bytesused -= buf->bytesused;
-		ivtv_process_vbi_data(itv, buf, 0, s->type);
-		s->q_dma.bytesused += buf->bytesused;
+		list_for_each(p, &s->q_dma.list) {
+			buf = list_entry(p, struct ivtv_buffer, list);
+
+			/* Parse and Groom VBI Data */
+			s->q_dma.bytesused -= buf->bytesused;
+			ivtv_process_vbi_data(itv, buf, 0, s->type);
+			s->q_dma.bytesused += buf->bytesused;
+		}
 		if (s->id == -1) {
 		if (s->id == -1) {
 			ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
 			ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
 			return;
 			return;
@@ -351,10 +368,14 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
 	struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
 	struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
 	int i;
 	int i;
 
 
+	IVTV_DEBUG_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name);
+
 	if (s->q_predma.bytesused)
 	if (s->q_predma.bytesused)
 		ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
 		ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
-	IVTV_DEBUG_DMA("start DMA for %s\n", s->name);
-	s->SGarray[s->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
+
+	if (ivtv_use_dma(s))
+		s->SGarray[s->SG_length - 1].size =
+			cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
 
 
 	/* If this is an MPEG stream, and VBI data is also pending, then append the
 	/* If this is an MPEG stream, and VBI data is also pending, then append the
 	   VBI DMA to the MPEG DMA and transfer both sets of data at once.
 	   VBI DMA to the MPEG DMA and transfer both sets of data at once.
@@ -368,7 +389,8 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
 	if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length &&
 	if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length &&
 			s->SG_length + s_vbi->SG_length <= s->buffers) {
 			s->SG_length + s_vbi->SG_length <= s->buffers) {
 		ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
 		ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
-		s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
+		if (ivtv_use_dma(s_vbi))
+			s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
 		for (i = 0; i < s_vbi->SG_length; i++) {
 		for (i = 0; i < s_vbi->SG_length; i++) {
 			s->SGarray[s->SG_length++] = s_vbi->SGarray[i];
 			s->SGarray[s->SG_length++] = s_vbi->SGarray[i];
 		}
 		}
@@ -381,14 +403,26 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
 	/* Mark last buffer size for Interrupt flag */
 	/* Mark last buffer size for Interrupt flag */
 	s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
 	s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
 
 
-	/* Sync Hardware SG List of buffers */
-	ivtv_stream_sync_for_device(s);
-	write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
-	write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
-	set_bit(IVTV_F_I_DMA, &itv->i_flags);
-	itv->cur_dma_stream = s->type;
-	itv->dma_timer.expires = jiffies + HZ / 10;
-	add_timer(&itv->dma_timer);
+	if (ivtv_use_pio(s)) {
+		for (i = 0; i < s->SG_length; i++) {
+			s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src);
+			s->PIOarray[i].size = le32_to_cpu(s->SGarray[i].size);
+		}
+		set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
+		set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
+		set_bit(IVTV_F_I_PIO, &itv->i_flags);
+		itv->cur_pio_stream = s->type;
+	}
+	else {
+		/* Sync Hardware SG List of buffers */
+		ivtv_stream_sync_for_device(s);
+		write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
+		write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
+		set_bit(IVTV_F_I_DMA, &itv->i_flags);
+		itv->cur_dma_stream = s->type;
+		itv->dma_timer.expires = jiffies + HZ / 10;
+		add_timer(&itv->dma_timer);
+	}
 }
 }
 
 
 static void ivtv_dma_dec_start(struct ivtv_stream *s)
 static void ivtv_dma_dec_start(struct ivtv_stream *s)
@@ -489,6 +523,40 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
 	wake_up(&itv->dma_waitq);
 	wake_up(&itv->dma_waitq);
 }
 }
 
 
+static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
+{
+	struct ivtv_stream *s;
+
+	if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) {
+		itv->cur_pio_stream = -1;
+		return;
+	}
+	s = &itv->streams[itv->cur_pio_stream];
+	IVTV_DEBUG_IRQ("ENC PIO COMPLETE %s\n", s->name);
+	s->SG_length = 0;
+	clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+	clear_bit(IVTV_F_I_PIO, &itv->i_flags);
+	itv->cur_pio_stream = -1;
+	dma_post(s);
+	if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
+		ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0);
+	else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
+		ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1);
+	else if (s->type == IVTV_ENC_STREAM_TYPE_PCM)
+		ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
+	clear_bit(IVTV_F_I_PIO, &itv->i_flags);
+	if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
+		u32 tmp;
+
+		s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
+		tmp = s->dma_offset;
+		s->dma_offset = itv->vbi.dma_offset;
+		dma_post(s);
+		s->dma_offset = tmp;
+	}
+	wake_up(&itv->dma_waitq);
+}
+
 static void ivtv_irq_dma_err(struct ivtv *itv)
 static void ivtv_irq_dma_err(struct ivtv *itv)
 {
 {
 	u32 data[CX2341X_MBOX_MAX_DATA];
 	u32 data[CX2341X_MBOX_MAX_DATA];
@@ -532,13 +600,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
 	clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
 	clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
 	s = &itv->streams[ivtv_stream_map[data[0]]];
 	s = &itv->streams[ivtv_stream_map[data[0]]];
 	if (!stream_enc_dma_append(s, data)) {
 	if (!stream_enc_dma_append(s, data)) {
-		if (ivtv_use_pio(s)) {
-			dma_post(s);
-			ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[0]);
-		}
-		else {
-			set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
-		}
+		set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
 	}
 	}
 }
 }
 
 
@@ -551,15 +613,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
 	IVTV_DEBUG_IRQ("ENC START VBI CAP\n");
 	IVTV_DEBUG_IRQ("ENC START VBI CAP\n");
 	s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
 	s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
 
 
-	if (ivtv_use_pio(s)) {
-		if (stream_enc_dma_append(s, data))
-			return;
-		if (s->q_predma.bytesused)
-			ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
-		s->SG_length = 0;
-		dma_post(s);
-		return;
-	}
 	/* If more than two VBI buffers are pending, then
 	/* If more than two VBI buffers are pending, then
 	   clear the old ones and start with this new one.
 	   clear the old ones and start with this new one.
 	   This can happen during transition stages when MPEG capturing is
 	   This can happen during transition stages when MPEG capturing is
@@ -582,11 +635,11 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
 	if (!stream_enc_dma_append(s, data) &&
 	if (!stream_enc_dma_append(s, data) &&
 			!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
 			!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
 		set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
 		set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
-		set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
+		set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
 	}
 	}
 }
 }
 
 
-static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
+static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
 {
 {
 	u32 data[CX2341X_MBOX_MAX_DATA];
 	u32 data[CX2341X_MBOX_MAX_DATA];
 	struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
 	struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
@@ -594,7 +647,7 @@ static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
 	IVTV_DEBUG_IRQ("DEC VBI REINSERT\n");
 	IVTV_DEBUG_IRQ("DEC VBI REINSERT\n");
 	if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
 	if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
 			!stream_enc_dma_append(s, data)) {
 			!stream_enc_dma_append(s, data)) {
-		dma_post(s);
+		set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags);
 	}
 	}
 }
 }
 
 
@@ -657,7 +710,6 @@ static void ivtv_irq_vsync(struct ivtv *itv)
 	}
 	}
 	if (frame != (itv->lastVsyncFrame & 1)) {
 	if (frame != (itv->lastVsyncFrame & 1)) {
 		struct ivtv_stream *s = ivtv_get_output_stream(itv);
 		struct ivtv_stream *s = ivtv_get_output_stream(itv);
-		int work = 0;
 
 
 		itv->lastVsyncFrame += 1;
 		itv->lastVsyncFrame += 1;
 		if (frame == 0) {
 		if (frame == 0) {
@@ -678,7 +730,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
 		/* Send VBI to saa7127 */
 		/* Send VBI to saa7127 */
 		if (frame) {
 		if (frame) {
 			set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
 			set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
-			work = 1;
+			set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
 		}
 		}
 
 
 		/* Check if we need to update the yuv registers */
 		/* Check if we need to update the yuv registers */
@@ -691,11 +743,9 @@ static void ivtv_irq_vsync(struct ivtv *itv)
 				itv->yuv_info.new_frame_info[last_dma_frame].update = 0;
 				itv->yuv_info.new_frame_info[last_dma_frame].update = 0;
 				itv->yuv_info.yuv_forced_update = 0;
 				itv->yuv_info.yuv_forced_update = 0;
 				set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
 				set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
-				work = 1;
+				set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
 			}
 			}
 		}
 		}
-		if (work)
-			queue_work(itv->irq_work_queues, &itv->irq_work_queue);
 	}
 	}
 }
 }
 
 
@@ -755,6 +805,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
 		ivtv_irq_enc_dma_complete(itv);
 		ivtv_irq_enc_dma_complete(itv);
 	}
 	}
 
 
+	if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
+		ivtv_irq_enc_pio_complete(itv);
+	}
+
 	if (combo & IVTV_IRQ_DMA_ERR) {
 	if (combo & IVTV_IRQ_DMA_ERR) {
 		ivtv_irq_dma_err(itv);
 		ivtv_irq_dma_err(itv);
 	}
 	}
@@ -768,7 +822,7 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
 	}
 	}
 
 
 	if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
 	if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
-		ivtv_irq_dev_vbi_reinsert(itv);
+		ivtv_irq_dec_vbi_reinsert(itv);
 	}
 	}
 
 
 	if (combo & IVTV_IRQ_ENC_EOS) {
 	if (combo & IVTV_IRQ_ENC_EOS) {
@@ -813,6 +867,22 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
 		}
 		}
 	}
 	}
 
 
+	if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
+		for (i = 0; i < IVTV_MAX_STREAMS; i++) {
+			int idx = (i + itv->irq_rr_idx++) % IVTV_MAX_STREAMS;
+			struct ivtv_stream *s = &itv->streams[idx];
+
+			if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
+				continue;
+			if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG)
+				ivtv_dma_enc_start(s);
+			break;
+		}
+	}
+
+	if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags))
+		queue_work(itv->irq_work_queues, &itv->irq_work_queue);
+
 	spin_unlock(&itv->dma_reg_lock);
 	spin_unlock(&itv->dma_reg_lock);
 
 
 	/* If we've just handled a 'forced' vsync, it's safest to say it
 	/* If we've just handled a 'forced' vsync, it's safest to say it

+ 23 - 8
drivers/media/video/ivtv/ivtv-queue.c

@@ -195,14 +195,26 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
 		s->dma != PCI_DMA_NONE ? "DMA " : "",
 		s->dma != PCI_DMA_NONE ? "DMA " : "",
 		s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
 		s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
 
 
-	/* Allocate DMA SG Arrays */
-	if (s->dma != PCI_DMA_NONE) {
-		s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
-		if (s->SGarray == NULL) {
-			IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
+	if (ivtv_might_use_pio(s)) {
+		s->PIOarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
+		if (s->PIOarray == NULL) {
+			IVTV_ERR("Could not allocate PIOarray for %s stream\n", s->name);
 			return -ENOMEM;
 			return -ENOMEM;
 		}
 		}
-		s->SG_length = 0;
+	}
+
+	/* Allocate DMA SG Arrays */
+	s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
+	if (s->SGarray == NULL) {
+		IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
+		if (ivtv_might_use_pio(s)) {
+			kfree(s->PIOarray);
+			s->PIOarray = NULL;
+		}
+		return -ENOMEM;
+	}
+	s->SG_length = 0;
+	if (ivtv_might_use_dma(s)) {
 		s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma);
 		s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma);
 		ivtv_stream_sync_for_cpu(s);
 		ivtv_stream_sync_for_cpu(s);
 	}
 	}
@@ -219,7 +231,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
 			break;
 			break;
 		}
 		}
 		INIT_LIST_HEAD(&buf->list);
 		INIT_LIST_HEAD(&buf->list);
-		if (s->dma != PCI_DMA_NONE) {
+		if (ivtv_might_use_dma(s)) {
 			buf->dma_handle = pci_map_single(s->itv->dev,
 			buf->dma_handle = pci_map_single(s->itv->dev,
 				buf->buf, s->buf_size + 256, s->dma);
 				buf->buf, s->buf_size + 256, s->dma);
 			ivtv_buf_sync_for_cpu(s, buf);
 			ivtv_buf_sync_for_cpu(s, buf);
@@ -242,7 +254,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
 
 
 	/* empty q_free */
 	/* empty q_free */
 	while ((buf = ivtv_dequeue(s, &s->q_free))) {
 	while ((buf = ivtv_dequeue(s, &s->q_free))) {
-		if (s->dma != PCI_DMA_NONE)
+		if (ivtv_might_use_dma(s))
 			pci_unmap_single(s->itv->dev, buf->dma_handle,
 			pci_unmap_single(s->itv->dev, buf->dma_handle,
 				s->buf_size + 256, s->dma);
 				s->buf_size + 256, s->dma);
 		kfree(buf->buf);
 		kfree(buf->buf);
@@ -256,6 +268,9 @@ void ivtv_stream_free(struct ivtv_stream *s)
 				 sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
 				 sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
 			s->SG_handle = IVTV_DMA_UNMAPPED;
 			s->SG_handle = IVTV_DMA_UNMAPPED;
 		}
 		}
+		kfree(s->SGarray);
+		kfree(s->PIOarray);
+		s->PIOarray = NULL;
 		s->SGarray = NULL;
 		s->SGarray = NULL;
 		s->SG_length = 0;
 		s->SG_length = 0;
 	}
 	}

+ 33 - 6
drivers/media/video/ivtv/ivtv-queue.h

@@ -20,18 +20,43 @@
  */
  */
 
 
 #define IVTV_DMA_UNMAPPED	((u32) -1)
 #define IVTV_DMA_UNMAPPED	((u32) -1)
+#define SLICED_VBI_PIO 1
 
 
 /* ivtv_buffer utility functions */
 /* ivtv_buffer utility functions */
+
+static inline int ivtv_might_use_pio(struct ivtv_stream *s)
+{
+	return s->dma == PCI_DMA_NONE || (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI);
+}
+
+static inline int ivtv_use_pio(struct ivtv_stream *s)
+{
+	struct ivtv *itv = s->itv;
+
+	return s->dma == PCI_DMA_NONE ||
+	    (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
+}
+
+static inline int ivtv_might_use_dma(struct ivtv_stream *s)
+{
+	return s->dma != PCI_DMA_NONE;
+}
+
+static inline int ivtv_use_dma(struct ivtv_stream *s)
+{
+	return !ivtv_use_pio(s);
+}
+
 static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
 static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
 {
 {
-	if (s->dma != PCI_DMA_NONE)
+	if (ivtv_use_dma(s))
 		pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
 		pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
 				s->buf_size + 256, s->dma);
 				s->buf_size + 256, s->dma);
 }
 }
 
 
 static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
 static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
 {
 {
-	if (s->dma != PCI_DMA_NONE)
+	if (ivtv_use_dma(s))
 		pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
 		pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
 				s->buf_size + 256, s->dma);
 				s->buf_size + 256, s->dma);
 }
 }
@@ -53,12 +78,14 @@ void ivtv_stream_free(struct ivtv_stream *s);
 
 
 static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
 static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
 {
 {
-	pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
-		sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+	if (ivtv_use_dma(s))
+		pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
+			sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
 }
 }
 
 
 static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
 static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
 {
 {
-	pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
-		sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+	if (ivtv_use_dma(s))
+		pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
+			sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
 }
 }

+ 1 - 1
drivers/media/video/ivtv/ivtv-streams.c

@@ -868,7 +868,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
 	if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags))
 	if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags))
 		return 0;
 		return 0;
 
 
-	IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", pts, flags);
+	IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
 
 
 	/* Stop Decoder */
 	/* Stop Decoder */
 	if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) {
 	if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) {

+ 1 - 1
drivers/media/video/ivtv/ivtv-vbi.c

@@ -450,7 +450,7 @@ void ivtv_disable_vbi(struct ivtv *itv)
 }
 }
 
 
 
 
-void vbi_work_handler(struct ivtv *itv)
+void ivtv_vbi_work_handler(struct ivtv *itv)
 {
 {
 	struct v4l2_sliced_vbi_data data;
 	struct v4l2_sliced_vbi_data data;
 
 

+ 1 - 1
drivers/media/video/ivtv/ivtv-vbi.h

@@ -23,4 +23,4 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
 int ivtv_used_line(struct ivtv *itv, int line, int field);
 int ivtv_used_line(struct ivtv *itv, int line, int field);
 void ivtv_disable_vbi(struct ivtv *itv);
 void ivtv_disable_vbi(struct ivtv *itv);
 void ivtv_set_vbi(unsigned long arg);
 void ivtv_set_vbi(unsigned long arg);
-void vbi_work_handler(struct ivtv *itv);
+void ivtv_vbi_work_handler(struct ivtv *itv);

+ 19 - 30
drivers/media/video/saa7111.c

@@ -75,10 +75,6 @@ struct saa7111 {
 	int norm;
 	int norm;
 	int input;
 	int input;
 	int enable;
 	int enable;
-	int bright;
-	int contrast;
-	int hue;
-	int sat;
 };
 };
 
 
 #define   I2C_SAA7111        0x48
 #define   I2C_SAA7111        0x48
@@ -96,6 +92,17 @@ saa7111_write (struct i2c_client *client,
 	return i2c_smbus_write_byte_data(client, reg, value);
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 }
 
 
+static inline void
+saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
+{
+	struct saa7111 *decoder = i2c_get_clientdata(client);
+
+	if (decoder->reg[reg] != value) {
+		decoder->reg[reg] = value;
+		i2c_smbus_write_byte_data(client, reg, value);
+	}
+}
+
 static int
 static int
 saa7111_write_block (struct i2c_client *client,
 saa7111_write_block (struct i2c_client *client,
 		     const u8          *data,
 		     const u8          *data,
@@ -439,28 +446,14 @@ saa7111_command (struct i2c_client *client,
 	{
 	{
 		struct video_picture *pic = arg;
 		struct video_picture *pic = arg;
 
 
-		if (decoder->bright != pic->brightness) {
-			/* We want 0 to 255 we get 0-65535 */
-			decoder->bright = pic->brightness;
-			saa7111_write(client, 0x0a, decoder->bright >> 8);
-		}
-		if (decoder->contrast != pic->contrast) {
-			/* We want 0 to 127 we get 0-65535 */
-			decoder->contrast = pic->contrast;
-			saa7111_write(client, 0x0b,
-				      decoder->contrast >> 9);
-		}
-		if (decoder->sat != pic->colour) {
-			/* We want 0 to 127 we get 0-65535 */
-			decoder->sat = pic->colour;
-			saa7111_write(client, 0x0c, decoder->sat >> 9);
-		}
-		if (decoder->hue != pic->hue) {
-			/* We want -128 to 127 we get 0-65535 */
-			decoder->hue = pic->hue;
-			saa7111_write(client, 0x0d,
-				      (decoder->hue - 32768) >> 8);
-		}
+		/* We want 0 to 255 we get 0-65535 */
+		saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8);
+		/* We want 0 to 127 we get 0-65535 */
+		saa7111_write(client, 0x0b, pic->contrast >> 9);
+		/* We want 0 to 127 we get 0-65535 */
+		saa7111_write(client, 0x0c, pic->colour >> 9);
+		/* We want -128 to 127 we get 0-65535 */
+		saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
 	}
 	}
 		break;
 		break;
 
 
@@ -524,10 +517,6 @@ saa7111_detect_client (struct i2c_adapter *adapter,
 	decoder->norm = VIDEO_MODE_NTSC;
 	decoder->norm = VIDEO_MODE_NTSC;
 	decoder->input = 0;
 	decoder->input = 0;
 	decoder->enable = 1;
 	decoder->enable = 1;
-	decoder->bright = 32768;
-	decoder->contrast = 32768;
-	decoder->hue = 32768;
-	decoder->sat = 32768;
 	i2c_set_clientdata(client, decoder);
 	i2c_set_clientdata(client, decoder);
 
 
 	i = i2c_attach_client(client);
 	i = i2c_attach_client(client);

+ 53 - 29
drivers/media/video/usbvision/usbvision-core.c

@@ -1414,6 +1414,11 @@ static void usbvision_isocIrq(struct urb *urb)
 	if (!USBVISION_IS_OPERATIONAL(usbvision))
 	if (!USBVISION_IS_OPERATIONAL(usbvision))
 		return;
 		return;
 
 
+	/* any urb with wrong status is ignored without acknowledgement */
+	if (urb->status == -ENOENT) {
+		return;
+	}
+
 	f = &usbvision->curFrame;
 	f = &usbvision->curFrame;
 
 
 	/* Manage streaming interruption */
 	/* Manage streaming interruption */
@@ -1436,18 +1441,21 @@ static void usbvision_isocIrq(struct urb *urb)
 	if (usbvision->streaming == Stream_On) {
 	if (usbvision->streaming == Stream_On) {
 
 
 		/* If we collected enough data let's parse! */
 		/* If we collected enough data let's parse! */
-		if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH) {	/* 12 == header_length */
-			/*If we don't have a frame we're current working on, complain */
-			if(!list_empty(&(usbvision->inqueue))) {
-				if (!(*f)) {
-					(*f) = list_entry(usbvision->inqueue.next,struct usbvision_frame, frame);
-				}
-				usbvision_parse_data(usbvision);
-			}
-			else {
-				PDEBUG(DBG_IRQ, "received data, but no one needs it");
-				scratch_reset(usbvision);
+		if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) &&
+		    (!list_empty(&(usbvision->inqueue))) ) {
+			if (!(*f)) {
+				(*f) = list_entry(usbvision->inqueue.next,
+						  struct usbvision_frame,
+						  frame);
 			}
 			}
+			usbvision_parse_data(usbvision);
+		}
+		else {
+			/*If we don't have a frame
+			  we're current working on, complain */
+			PDEBUG(DBG_IRQ,
+			       "received data, but no one needs it");
+			scratch_reset(usbvision);
 		}
 		}
 	}
 	}
 	else {
 	else {
@@ -1466,10 +1474,10 @@ static void usbvision_isocIrq(struct urb *urb)
 	urb->dev = usbvision->dev;
 	urb->dev = usbvision->dev;
 	errCode = usb_submit_urb (urb, GFP_ATOMIC);
 	errCode = usb_submit_urb (urb, GFP_ATOMIC);
 
 
-	/* Disable this warning.  By design of the driver. */
-	//	if(errCode) {
-	//		err("%s: usb_submit_urb failed: error %d", __FUNCTION__, errCode);
-	//	}
+	if(errCode) {
+		err("%s: usb_submit_urb failed: error %d",
+		    __FUNCTION__, errCode);
+	}
 
 
 	return;
 	return;
 }
 }
@@ -2394,7 +2402,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 {
 {
 	struct usb_device *dev = usbvision->dev;
 	struct usb_device *dev = usbvision->dev;
 	int bufIdx, errCode, regValue;
 	int bufIdx, errCode, regValue;
-	const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
+	int sb_size;
 
 
 	if (!USBVISION_IS_OPERATIONAL(usbvision))
 	if (!USBVISION_IS_OPERATIONAL(usbvision))
 		return -EFAULT;
 		return -EFAULT;
@@ -2408,11 +2416,14 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 		usbvision->last_error = errCode;
 		usbvision->last_error = errCode;
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
+	sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
 
 
-	regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
+	regValue = (16 - usbvision_read_reg(usbvision,
+					    USBVISION_ALTER_REG)) & 0x0F;
 
 
 	usbvision->usb_bandwidth = regValue >> 1;
 	usbvision->usb_bandwidth = regValue >> 1;
-	PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
+	PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
+	       usbvision->usb_bandwidth);
 
 
 
 
 
 
@@ -2428,7 +2439,11 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 			return -ENOMEM;
 			return -ENOMEM;
 		}
 		}
 		usbvision->sbuf[bufIdx].urb = urb;
 		usbvision->sbuf[bufIdx].urb = urb;
-		usbvision->sbuf[bufIdx].data = usb_buffer_alloc(usbvision->dev, sb_size, GFP_KERNEL,&urb->transfer_dma);
+		usbvision->sbuf[bufIdx].data =
+			usb_buffer_alloc(usbvision->dev,
+					 sb_size,
+					 GFP_KERNEL,
+					 &urb->transfer_dma);
 		urb->dev = dev;
 		urb->dev = dev;
 		urb->context = usbvision;
 		urb->context = usbvision;
 		urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
 		urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
@@ -2442,21 +2457,26 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 		for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
 		for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
 		     k += usbvision->isocPacketSize) {
 		     k += usbvision->isocPacketSize) {
 			urb->iso_frame_desc[j].offset = k;
 			urb->iso_frame_desc[j].offset = k;
-			urb->iso_frame_desc[j].length = usbvision->isocPacketSize;
+			urb->iso_frame_desc[j].length =
+				usbvision->isocPacketSize;
 		}
 		}
 	}
 	}
 
 
 
 
 	/* Submit all URBs */
 	/* Submit all URBs */
 	for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
 	for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
-			errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, GFP_KERNEL);
+			errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
+						 GFP_KERNEL);
 		if (errCode) {
 		if (errCode) {
-			err("%s: usb_submit_urb(%d) failed: error %d", __FUNCTION__, bufIdx, errCode);
+			err("%s: usb_submit_urb(%d) failed: error %d",
+			    __FUNCTION__, bufIdx, errCode);
 		}
 		}
 	}
 	}
 
 
 	usbvision->streaming = Stream_Idle;
 	usbvision->streaming = Stream_Idle;
-	PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp);
+	PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x",
+	       __FUNCTION__,
+	       usbvision->video_endp);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -2470,7 +2490,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 void usbvision_stop_isoc(struct usb_usbvision *usbvision)
 void usbvision_stop_isoc(struct usb_usbvision *usbvision)
 {
 {
 	int bufIdx, errCode, regValue;
 	int bufIdx, errCode, regValue;
-	const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
+	int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
 
 
 	if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
 	if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
 		return;
 		return;
@@ -2499,15 +2519,19 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
 		errCode = usb_set_interface(usbvision->dev, usbvision->iface,
 		errCode = usb_set_interface(usbvision->dev, usbvision->iface,
 					    usbvision->ifaceAlt);
 					    usbvision->ifaceAlt);
 		if (errCode < 0) {
 		if (errCode < 0) {
-			err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode);
+			err("%s: usb_set_interface() failed: error %d",
+			    __FUNCTION__, errCode);
 			usbvision->last_error = errCode;
 			usbvision->last_error = errCode;
 		}
 		}
-		regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
-		usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1;
-		PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize);
+		regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
+		usbvision->isocPacketSize =
+			(regValue == 0) ? 0 : (regValue * 64) - 1;
+		PDEBUG(DBG_ISOC, "ISO Packet Length:%d",
+		       usbvision->isocPacketSize);
 
 
 		usbvision->usb_bandwidth = regValue >> 1;
 		usbvision->usb_bandwidth = regValue >> 1;
-		PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
+		PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
+		       usbvision->usb_bandwidth);
 	}
 	}
 }
 }
 
 

+ 0 - 1
drivers/media/video/usbvision/usbvision.h

@@ -146,7 +146,6 @@
 #define USBVISION_CLIPMASK_SIZE		(MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask
 #define USBVISION_CLIPMASK_SIZE		(MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask
 
 
 #define USBVISION_URB_FRAMES		32
 #define USBVISION_URB_FRAMES		32
-#define USBVISION_MAX_ISOC_PACKET_SIZE 	959			// NT1003 Specs Document says 1023
 
 
 #define USBVISION_NUM_HEADERMARKER	20
 #define USBVISION_NUM_HEADERMARKER	20
 #define USBVISION_NUMFRAMES		3  /* Maximum number of frames an application can get */
 #define USBVISION_NUMFRAMES		3  /* Maximum number of frames an application can get */

+ 21 - 5
drivers/mmc/core/sd.c

@@ -15,6 +15,7 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
 
 
 #include "core.h"
 #include "core.h"
 #include "sysfs.h"
 #include "sysfs.h"
@@ -192,6 +193,16 @@ static int mmc_read_switch(struct mmc_card *card)
 	int err;
 	int err;
 	u8 *status;
 	u8 *status;
 
 
+	if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+		return MMC_ERR_NONE;
+
+	if (!(card->csd.cmdclass & CCC_SWITCH)) {
+		printk(KERN_WARNING "%s: card lacks mandatory switch "
+			"function, performance might suffer.\n",
+			mmc_hostname(card->host));
+		return MMC_ERR_NONE;
+	}
+
 	err = MMC_ERR_FAILED;
 	err = MMC_ERR_FAILED;
 
 
 	status = kmalloc(64, GFP_KERNEL);
 	status = kmalloc(64, GFP_KERNEL);
@@ -204,10 +215,9 @@ static int mmc_read_switch(struct mmc_card *card)
 
 
 	err = mmc_sd_switch(card, 0, 0, 1, status);
 	err = mmc_sd_switch(card, 0, 0, 1, status);
 	if (err != MMC_ERR_NONE) {
 	if (err != MMC_ERR_NONE) {
-		/*
-		 * Card not supporting high-speed will ignore the
-		 * command.
-		 */
+		printk(KERN_WARNING "%s: problem reading switch "
+			"capabilities, performance might suffer.\n",
+			mmc_hostname(card->host));
 		err = MMC_ERR_NONE;
 		err = MMC_ERR_NONE;
 		goto out;
 		goto out;
 	}
 	}
@@ -229,6 +239,12 @@ static int mmc_switch_hs(struct mmc_card *card)
 	int err;
 	int err;
 	u8 *status;
 	u8 *status;
 
 
+	if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+		return MMC_ERR_NONE;
+
+	if (!(card->csd.cmdclass & CCC_SWITCH))
+		return MMC_ERR_NONE;
+
 	if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
 	if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
 		return MMC_ERR_NONE;
 		return MMC_ERR_NONE;
 
 
@@ -402,7 +418,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 	/*
 	/*
 	 * Switch to wider bus (if supported).
 	 * Switch to wider bus (if supported).
 	 */
 	 */
-	if ((host->caps && MMC_CAP_4_BIT_DATA) &&
+	if ((host->caps & MMC_CAP_4_BIT_DATA) &&
 		(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
 		(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
 		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
 		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
 		if (err != MMC_ERR_NONE)
 		if (err != MMC_ERR_NONE)

+ 2 - 3
drivers/mmc/host/at91_mci.c

@@ -417,7 +417,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
 		blocks = 0;
 		blocks = 0;
 	}
 	}
 
 
-	if (cmd->opcode == MMC_STOP_TRANSMISSION)
+	if (host->flags & FL_SENT_STOP)
 		cmdr |= AT91_MCI_TRCMD_STOP;
 		cmdr |= AT91_MCI_TRCMD_STOP;
 
 
 	if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
 	if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
@@ -563,8 +563,7 @@ static void at91mci_completed_command(struct at91mci_host *host)
 	if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |
 	if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |
 			AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
 			AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
 			AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
 			AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
-		if ((status & AT91_MCI_RCRCE) &&
-			((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) {
+		if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
 			cmd->error = MMC_ERR_NONE;
 			cmd->error = MMC_ERR_NONE;
 		}
 		}
 		else {
 		else {

+ 1 - 2
drivers/mmc/host/au1xmmc.c

@@ -76,8 +76,7 @@ const struct {
 #endif
 #endif
 };
 };
 
 
-#define AU1XMMC_CONTROLLER_COUNT \
-	(sizeof(au1xmmc_card_table) / sizeof(au1xmmc_card_table[0]))
+#define AU1XMMC_CONTROLLER_COUNT (ARRAY_SIZE(au1xmmc_card_table))
 
 
 /* This array stores pointers for the hosts (used by the IRQ handler) */
 /* This array stores pointers for the hosts (used by the IRQ handler) */
 struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];
 struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];

+ 1 - 1
drivers/net/mlx4/cq.c

@@ -61,7 +61,7 @@ struct mlx4_cq_context {
 	__be32			solicit_producer_index;
 	__be32			solicit_producer_index;
 	__be32			consumer_index;
 	__be32			consumer_index;
 	__be32			producer_index;
 	__be32			producer_index;
-	u8			reserved6[2];
+	u32			reserved6[2];
 	__be64			db_rec_addr;
 	__be64			db_rec_addr;
 };
 };
 
 

+ 3 - 1
drivers/net/mlx4/eq.c

@@ -490,9 +490,11 @@ static void mlx4_free_irqs(struct mlx4_dev *dev)
 
 
 	if (eq_table->have_irq)
 	if (eq_table->have_irq)
 		free_irq(dev->pdev->irq, dev);
 		free_irq(dev->pdev->irq, dev);
-	for (i = 0; i < MLX4_NUM_EQ; ++i)
+	for (i = 0; i < MLX4_EQ_CATAS; ++i)
 		if (eq_table->eq[i].have_irq)
 		if (eq_table->eq[i].have_irq)
 			free_irq(eq_table->eq[i].irq, eq_table->eq + i);
 			free_irq(eq_table->eq[i].irq, eq_table->eq + i);
+	if (eq_table->eq[MLX4_EQ_CATAS].have_irq)
+		free_irq(eq_table->eq[MLX4_EQ_CATAS].irq, dev);
 }
 }
 
 
 static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev)
 static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev)

+ 24 - 3
drivers/net/mlx4/fw.c

@@ -37,6 +37,10 @@
 #include "fw.h"
 #include "fw.h"
 #include "icm.h"
 #include "icm.h"
 
 
+enum {
+	MLX4_COMMAND_INTERFACE_REV	= 1
+};
+
 extern void __buggy_use_of_MLX4_GET(void);
 extern void __buggy_use_of_MLX4_GET(void);
 extern void __buggy_use_of_MLX4_PUT(void);
 extern void __buggy_use_of_MLX4_PUT(void);
 
 
@@ -452,10 +456,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
 	u32 *outbox;
 	u32 *outbox;
 	int err = 0;
 	int err = 0;
 	u64 fw_ver;
 	u64 fw_ver;
+	u16 cmd_if_rev;
 	u8 lg;
 	u8 lg;
 
 
 #define QUERY_FW_OUT_SIZE             0x100
 #define QUERY_FW_OUT_SIZE             0x100
 #define QUERY_FW_VER_OFFSET            0x00
 #define QUERY_FW_VER_OFFSET            0x00
+#define QUERY_FW_CMD_IF_REV_OFFSET     0x0a
 #define QUERY_FW_MAX_CMD_OFFSET        0x0f
 #define QUERY_FW_MAX_CMD_OFFSET        0x0f
 #define QUERY_FW_ERR_START_OFFSET      0x30
 #define QUERY_FW_ERR_START_OFFSET      0x30
 #define QUERY_FW_ERR_SIZE_OFFSET       0x38
 #define QUERY_FW_ERR_SIZE_OFFSET       0x38
@@ -477,21 +483,36 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
 
 
 	MLX4_GET(fw_ver, outbox, QUERY_FW_VER_OFFSET);
 	MLX4_GET(fw_ver, outbox, QUERY_FW_VER_OFFSET);
 	/*
 	/*
-	 * FW subminor version is at more signifant bits than minor
+	 * FW subminor version is at more significant bits than minor
 	 * version, so swap here.
 	 * version, so swap here.
 	 */
 	 */
 	dev->caps.fw_ver = (fw_ver & 0xffff00000000ull) |
 	dev->caps.fw_ver = (fw_ver & 0xffff00000000ull) |
 		((fw_ver & 0xffff0000ull) >> 16) |
 		((fw_ver & 0xffff0000ull) >> 16) |
 		((fw_ver & 0x0000ffffull) << 16);
 		((fw_ver & 0x0000ffffull) << 16);
 
 
+	MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET);
+	if (cmd_if_rev != MLX4_COMMAND_INTERFACE_REV) {
+		mlx4_err(dev, "Installed FW has unsupported "
+			 "command interface revision %d.\n",
+			 cmd_if_rev);
+		mlx4_err(dev, "(Installed FW version is %d.%d.%03d)\n",
+			 (int) (dev->caps.fw_ver >> 32),
+			 (int) (dev->caps.fw_ver >> 16) & 0xffff,
+			 (int) dev->caps.fw_ver & 0xffff);
+		mlx4_err(dev, "This driver version supports only revision %d.\n",
+			 MLX4_COMMAND_INTERFACE_REV);
+		err = -ENODEV;
+		goto out;
+	}
+
 	MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
 	MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
 	cmd->max_cmds = 1 << lg;
 	cmd->max_cmds = 1 << lg;
 
 
-	mlx4_dbg(dev, "FW version %d.%d.%03d, max commands %d\n",
+	mlx4_dbg(dev, "FW version %d.%d.%03d (cmd intf rev %d), max commands %d\n",
 		 (int) (dev->caps.fw_ver >> 32),
 		 (int) (dev->caps.fw_ver >> 32),
 		 (int) (dev->caps.fw_ver >> 16) & 0xffff,
 		 (int) (dev->caps.fw_ver >> 16) & 0xffff,
 		 (int) dev->caps.fw_ver & 0xffff,
 		 (int) dev->caps.fw_ver & 0xffff,
-		 cmd->max_cmds);
+		 cmd_if_rev, cmd->max_cmds);
 
 
 	MLX4_GET(fw->catas_offset, outbox, QUERY_FW_ERR_START_OFFSET);
 	MLX4_GET(fw->catas_offset, outbox, QUERY_FW_ERR_START_OFFSET);
 	MLX4_GET(fw->catas_size,   outbox, QUERY_FW_ERR_SIZE_OFFSET);
 	MLX4_GET(fw->catas_size,   outbox, QUERY_FW_ERR_SIZE_OFFSET);

+ 0 - 3
drivers/net/mlx4/intf.c

@@ -135,9 +135,6 @@ int mlx4_register_device(struct mlx4_dev *dev)
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	struct mlx4_interface *intf;
 	struct mlx4_interface *intf;
 
 
-	INIT_LIST_HEAD(&priv->ctx_list);
-	spin_lock_init(&priv->ctx_lock);
-
 	mutex_lock(&intf_mutex);
 	mutex_lock(&intf_mutex);
 
 
 	list_add_tail(&priv->dev_list, &dev_list);
 	list_add_tail(&priv->dev_list, &dev_list);

+ 2 - 0
drivers/net/mlx4/main.c

@@ -787,6 +787,8 @@ static int __devinit mlx4_init_one(struct pci_dev *pdev,
 
 
 	dev       = &priv->dev;
 	dev       = &priv->dev;
 	dev->pdev = pdev;
 	dev->pdev = pdev;
+	INIT_LIST_HEAD(&priv->ctx_list);
+	spin_lock_init(&priv->ctx_lock);
 
 
 	/*
 	/*
 	 * Now reset the HCA before we touch the PCI capabilities or
 	 * Now reset the HCA before we touch the PCI capabilities or

+ 5 - 3
drivers/net/mlx4/mr.c

@@ -324,15 +324,17 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
 				       MLX4_MPT_FLAG_MIO	 |
 				       MLX4_MPT_FLAG_MIO	 |
 				       MLX4_MPT_FLAG_REGION	 |
 				       MLX4_MPT_FLAG_REGION	 |
 				       mr->access);
 				       mr->access);
-	if (mr->mtt.order < 0)
-		mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL);
 
 
 	mpt_entry->key	       = cpu_to_be32(key_to_hw_index(mr->key));
 	mpt_entry->key	       = cpu_to_be32(key_to_hw_index(mr->key));
 	mpt_entry->pd	       = cpu_to_be32(mr->pd);
 	mpt_entry->pd	       = cpu_to_be32(mr->pd);
 	mpt_entry->start       = cpu_to_be64(mr->iova);
 	mpt_entry->start       = cpu_to_be64(mr->iova);
 	mpt_entry->length      = cpu_to_be64(mr->size);
 	mpt_entry->length      = cpu_to_be64(mr->size);
 	mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift);
 	mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift);
-	mpt_entry->mtt_seg     = cpu_to_be64(mlx4_mtt_addr(dev, &mr->mtt));
+	if (mr->mtt.order < 0) {
+		mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL);
+		mpt_entry->mtt_seg = 0;
+	} else
+		mpt_entry->mtt_seg = cpu_to_be64(mlx4_mtt_addr(dev, &mr->mtt));
 
 
 	err = mlx4_SW2HW_MPT(dev, mailbox,
 	err = mlx4_SW2HW_MPT(dev, mailbox,
 			     key_to_hw_index(mr->key) & (dev->caps.num_mpts - 1));
 			     key_to_hw_index(mr->key) & (dev->caps.num_mpts - 1));

+ 129 - 123
fs/cifs/cifs_debug.c

@@ -7,16 +7,16 @@
  *
  *
  *   This program is free software;  you can redistribute it and/or modify
  *   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
  *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or 
+ *   the Free Software Foundation; either version 2 of the License, or
  *   (at your option) any later version.
  *   (at your option) any later version.
- * 
+ *
  *   This program is distributed in the hope that it will be useful,
  *   This program is distributed in the hope that it will be useful,
  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  *   the GNU General Public License for more details.
  *   the GNU General Public License for more details.
  *
  *
  *   You should have received a copy of the GNU General Public License
  *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
  */
 #include <linux/fs.h>
 #include <linux/fs.h>
@@ -39,7 +39,7 @@ cifs_dump_mem(char *label, void *data, int length)
 	char *charptr = data;
 	char *charptr = data;
 	char buf[10], line[80];
 	char buf[10], line[80];
 
 
-	printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n", 
+	printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n",
 		label, length, data);
 		label, length, data);
 	for (i = 0; i < length; i += 16) {
 	for (i = 0; i < length; i += 16) {
 		line[0] = 0;
 		line[0] = 0;
@@ -60,10 +60,10 @@ cifs_dump_mem(char *label, void *data, int length)
 #ifdef CONFIG_CIFS_DEBUG2
 #ifdef CONFIG_CIFS_DEBUG2
 void cifs_dump_detail(struct smb_hdr * smb)
 void cifs_dump_detail(struct smb_hdr * smb)
 {
 {
-	cERROR(1,("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
+	cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
 		  smb->Command, smb->Status.CifsError,
 		  smb->Command, smb->Status.CifsError,
 		  smb->Flags, smb->Flags2, smb->Mid, smb->Pid));
 		  smb->Flags, smb->Flags2, smb->Mid, smb->Pid));
-	cERROR(1,("smb buf %p len %d", smb, smbCalcSize_LE(smb)));
+	cERROR(1, ("smb buf %p len %d", smb, smbCalcSize_LE(smb)));
 }
 }
 
 
 
 
@@ -72,36 +72,35 @@ void cifs_dump_mids(struct TCP_Server_Info * server)
 	struct list_head *tmp;
 	struct list_head *tmp;
 	struct mid_q_entry * mid_entry;
 	struct mid_q_entry * mid_entry;
 
 
-	if(server == NULL)
+	if (server == NULL)
 		return;
 		return;
 
 
-	cERROR(1,("Dump pending requests:"));
+	cERROR(1, ("Dump pending requests:"));
 	spin_lock(&GlobalMid_Lock);
 	spin_lock(&GlobalMid_Lock);
 	list_for_each(tmp, &server->pending_mid_q) {
 	list_for_each(tmp, &server->pending_mid_q) {
 		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
 		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
-		if(mid_entry) {
-			cERROR(1,("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d",
+		if (mid_entry) {
+			cERROR(1, ("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d",
 				mid_entry->midState,
 				mid_entry->midState,
 				(int)mid_entry->command,
 				(int)mid_entry->command,
 				mid_entry->pid,
 				mid_entry->pid,
 				mid_entry->tsk,
 				mid_entry->tsk,
 				mid_entry->mid));
 				mid_entry->mid));
 #ifdef CONFIG_CIFS_STATS2
 #ifdef CONFIG_CIFS_STATS2
-			cERROR(1,("IsLarge: %d buf: %p time rcv: %ld now: %ld",
+			cERROR(1, ("IsLarge: %d buf: %p time rcv: %ld now: %ld",
 				mid_entry->largeBuf,
 				mid_entry->largeBuf,
 				mid_entry->resp_buf,
 				mid_entry->resp_buf,
 				mid_entry->when_received,
 				mid_entry->when_received,
 				jiffies));
 				jiffies));
 #endif /* STATS2 */
 #endif /* STATS2 */
-			cERROR(1,("IsMult: %d IsEnd: %d", mid_entry->multiRsp,
+			cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp,
 				  mid_entry->multiEnd));
 				  mid_entry->multiEnd));
-			if(mid_entry->resp_buf) {
+			if (mid_entry->resp_buf) {
 				cifs_dump_detail(mid_entry->resp_buf);
 				cifs_dump_detail(mid_entry->resp_buf);
 				cifs_dump_mem("existing buf: ",
 				cifs_dump_mem("existing buf: ",
 					mid_entry->resp_buf,
 					mid_entry->resp_buf,
 					62 /* fixme */);
 					62 /* fixme */);
 			}
 			}
-			
 		}
 		}
 	}
 	}
 	spin_unlock(&GlobalMid_Lock);
 	spin_unlock(&GlobalMid_Lock);
@@ -129,9 +128,10 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 		    "Display Internal CIFS Data Structures for Debugging\n"
 		    "Display Internal CIFS Data Structures for Debugging\n"
 		    "---------------------------------------------------\n");
 		    "---------------------------------------------------\n");
 	buf += length;
 	buf += length;
-	length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION);
+	length = sprintf(buf, "CIFS Version %s\n", CIFS_VERSION);
 	buf += length;
 	buf += length;
-	length = sprintf(buf,"Active VFS Requests: %d\n", GlobalTotalActiveXid);
+	length = sprintf(buf,
+		"Active VFS Requests: %d\n", GlobalTotalActiveXid);
 	buf += length;
 	buf += length;
 	length = sprintf(buf, "Servers:");
 	length = sprintf(buf, "Servers:");
 	buf += length;
 	buf += length;
@@ -141,7 +141,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 	list_for_each(tmp, &GlobalSMBSessionList) {
 	list_for_each(tmp, &GlobalSMBSessionList) {
 		i++;
 		i++;
 		ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
 		ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
-		if((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
+		if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
 		   (ses->serverNOS == NULL)) {
 		   (ses->serverNOS == NULL)) {
 			buf += sprintf(buf, "\nentry for %s not fully "
 			buf += sprintf(buf, "\nentry for %s not fully "
 					"displayed\n\t", ses->serverName);
 					"displayed\n\t", ses->serverName);
@@ -149,15 +149,18 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 		} else {
 		} else {
 			length =
 			length =
 			    sprintf(buf,
 			    sprintf(buf,
-				    "\n%d) Name: %s  Domain: %s Mounts: %d OS: %s  \n\tNOS: %s\tCapability: 0x%x\n\tSMB session status: %d\t",
+				    "\n%d) Name: %s  Domain: %s Mounts: %d OS:"
+				    " %s  \n\tNOS: %s\tCapability: 0x%x\n\tSMB"
+				    " session status: %d\t",
 				i, ses->serverName, ses->serverDomain,
 				i, ses->serverName, ses->serverDomain,
 				atomic_read(&ses->inUse),
 				atomic_read(&ses->inUse),
 				ses->serverOS, ses->serverNOS,
 				ses->serverOS, ses->serverNOS,
-				ses->capabilities,ses->status);
+				ses->capabilities, ses->status);
 			buf += length;
 			buf += length;
 		}
 		}
-		if(ses->server) {
-			buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d",
+		if (ses->server) {
+			buf += sprintf(buf, "TCP status: %d\n\tLocal Users To "
+				    "Server: %d SecMode: 0x%x Req On Wire: %d",
 				ses->server->tcpStatus,
 				ses->server->tcpStatus,
 				atomic_read(&ses->server->socketUseCount),
 				atomic_read(&ses->server->socketUseCount),
 				ses->server->secMode,
 				ses->server->secMode,
@@ -165,7 +168,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 
 
 #ifdef CONFIG_CIFS_STATS2
 #ifdef CONFIG_CIFS_STATS2
 			buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d",
 			buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d",
-				atomic_read(&ses->server->inSend), 
+				atomic_read(&ses->server->inSend),
 				atomic_read(&ses->server->num_waiters));
 				atomic_read(&ses->server->num_waiters));
 #endif
 #endif
 
 
@@ -177,17 +180,19 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 				mid_entry = list_entry(tmp1, struct
 				mid_entry = list_entry(tmp1, struct
 					mid_q_entry,
 					mid_q_entry,
 					qhead);
 					qhead);
-				if(mid_entry) {
-					length = sprintf(buf,"State: %d com: %d pid: %d tsk: %p mid %d\n",
-						mid_entry->midState,
-						(int)mid_entry->command,
-						mid_entry->pid,
-						mid_entry->tsk,
-						mid_entry->mid);
+				if (mid_entry) {
+					length = sprintf(buf,
+							"State: %d com: %d pid:"
+							" %d tsk: %p mid %d\n",
+							mid_entry->midState,
+							(int)mid_entry->command,
+							mid_entry->pid,
+							mid_entry->tsk,
+							mid_entry->mid);
 					buf += length;
 					buf += length;
 				}
 				}
 			}
 			}
-			spin_unlock(&GlobalMid_Lock); 
+			spin_unlock(&GlobalMid_Lock);
 		}
 		}
 
 
 	}
 	}
@@ -207,7 +212,8 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 		dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
 		dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
 		length =
 		length =
 		    sprintf(buf,
 		    sprintf(buf,
-			    "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
+			    "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x "
+			    "Attributes: 0x%x\nPathComponentMax: %d Status: %d",
 			    i, tcon->treeName,
 			    i, tcon->treeName,
 			    atomic_read(&tcon->useCount),
 			    atomic_read(&tcon->useCount),
 			    tcon->nativeFileSystem,
 			    tcon->nativeFileSystem,
@@ -215,7 +221,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 			    le32_to_cpu(tcon->fsAttrInfo.Attributes),
 			    le32_to_cpu(tcon->fsAttrInfo.Attributes),
 			    le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
 			    le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
 			    tcon->tidStatus);
 			    tcon->tidStatus);
-		buf += length;        
+		buf += length;
 		if (dev_type == FILE_DEVICE_DISK)
 		if (dev_type == FILE_DEVICE_DISK)
 			length = sprintf(buf, " type: DISK ");
 			length = sprintf(buf, " type: DISK ");
 		else if (dev_type == FILE_DEVICE_CD_ROM)
 		else if (dev_type == FILE_DEVICE_CD_ROM)
@@ -224,7 +230,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 			length =
 			length =
 			    sprintf(buf, " type: %d ", dev_type);
 			    sprintf(buf, " type: %d ", dev_type);
 		buf += length;
 		buf += length;
-		if(tcon->tidStatus == CifsNeedReconnect) {
+		if (tcon->tidStatus == CifsNeedReconnect) {
 			buf += sprintf(buf, "\tDISCONNECTED ");
 			buf += sprintf(buf, "\tDISCONNECTED ");
 			length += 14;
 			length += 14;
 		}
 		}
@@ -238,9 +244,9 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 	/* Now calculate total size of returned data */
 	/* Now calculate total size of returned data */
 	length = buf - original_buf;
 	length = buf - original_buf;
 
 
-	if(offset + count >= length)
+	if (offset + count >= length)
 		*eof = 1;
 		*eof = 1;
-	if(length < offset) {
+	if (length < offset) {
 		*eof = 1;
 		*eof = 1;
 		return 0;
 		return 0;
 	} else {
 	} else {
@@ -256,18 +262,18 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 
 
 static int
 static int
 cifs_stats_write(struct file *file, const char __user *buffer,
 cifs_stats_write(struct file *file, const char __user *buffer,
-               unsigned long count, void *data)
+		 unsigned long count, void *data)
 {
 {
-        char c;
-        int rc;
+	char c;
+	int rc;
 	struct list_head *tmp;
 	struct list_head *tmp;
 	struct cifsTconInfo *tcon;
 	struct cifsTconInfo *tcon;
 
 
-        rc = get_user(c, buffer);
-        if (rc)
-                return rc;
+	rc = get_user(c, buffer);
+	if (rc)
+		return rc;
 
 
-        if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
+	if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
 		read_lock(&GlobalSMBSeslock);
 		read_lock(&GlobalSMBSeslock);
 #ifdef CONFIG_CIFS_STATS2
 #ifdef CONFIG_CIFS_STATS2
 		atomic_set(&totBufAllocCount, 0);
 		atomic_set(&totBufAllocCount, 0);
@@ -297,14 +303,14 @@ cifs_stats_write(struct file *file, const char __user *buffer,
 		read_unlock(&GlobalSMBSeslock);
 		read_unlock(&GlobalSMBSeslock);
 	}
 	}
 
 
-        return count;
+	return count;
 }
 }
 
 
 static int
 static int
 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 		  int count, int *eof, void *data)
 		  int count, int *eof, void *data)
 {
 {
-	int item_length,i,length;
+	int item_length, i, length;
 	struct list_head *tmp;
 	struct list_head *tmp;
 	struct cifsTconInfo *tcon;
 	struct cifsTconInfo *tcon;
 
 
@@ -314,44 +320,44 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 			"Resources in use\nCIFS Session: %d\n",
 			"Resources in use\nCIFS Session: %d\n",
 			sesInfoAllocCount.counter);
 			sesInfoAllocCount.counter);
 	buf += length;
 	buf += length;
-	item_length = 
-		sprintf(buf,"Share (unique mount targets): %d\n",
+	item_length =
+		sprintf(buf, "Share (unique mount targets): %d\n",
 			tconInfoAllocCount.counter);
 			tconInfoAllocCount.counter);
 	length += item_length;
 	length += item_length;
-	buf += item_length;      
-	item_length = 
-		sprintf(buf,"SMB Request/Response Buffer: %d Pool size: %d\n",
+	buf += item_length;
+	item_length =
+		sprintf(buf, "SMB Request/Response Buffer: %d Pool size: %d\n",
 			bufAllocCount.counter,
 			bufAllocCount.counter,
 			cifs_min_rcv + tcpSesAllocCount.counter);
 			cifs_min_rcv + tcpSesAllocCount.counter);
 	length += item_length;
 	length += item_length;
 	buf += item_length;
 	buf += item_length;
-	item_length = 
-		sprintf(buf,"SMB Small Req/Resp Buffer: %d Pool size: %d\n",
-			smBufAllocCount.counter,cifs_min_small);
+	item_length =
+		sprintf(buf, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",
+			smBufAllocCount.counter, cifs_min_small);
 	length += item_length;
 	length += item_length;
 	buf += item_length;
 	buf += item_length;
 #ifdef CONFIG_CIFS_STATS2
 #ifdef CONFIG_CIFS_STATS2
-        item_length = sprintf(buf, "Total Large %d Small %d Allocations\n",
+	item_length = sprintf(buf, "Total Large %d Small %d Allocations\n",
 				atomic_read(&totBufAllocCount),
 				atomic_read(&totBufAllocCount),
-		                atomic_read(&totSmBufAllocCount));
+				atomic_read(&totSmBufAllocCount));
 	length += item_length;
 	length += item_length;
 	buf += item_length;
 	buf += item_length;
 #endif /* CONFIG_CIFS_STATS2 */
 #endif /* CONFIG_CIFS_STATS2 */
 
 
-	item_length = 
-		sprintf(buf,"Operations (MIDs): %d\n",
+	item_length =
+		sprintf(buf, "Operations (MIDs): %d\n",
 			midCount.counter);
 			midCount.counter);
 	length += item_length;
 	length += item_length;
 	buf += item_length;
 	buf += item_length;
 	item_length = sprintf(buf,
 	item_length = sprintf(buf,
 		"\n%d session %d share reconnects\n",
 		"\n%d session %d share reconnects\n",
-		tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
+		tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);
 	length += item_length;
 	length += item_length;
 	buf += item_length;
 	buf += item_length;
 
 
 	item_length = sprintf(buf,
 	item_length = sprintf(buf,
 		"Total vfs operations: %d maximum at one time: %d\n",
 		"Total vfs operations: %d maximum at one time: %d\n",
-		GlobalCurrentXid,GlobalMaxActiveXid);
+		GlobalCurrentXid, GlobalMaxActiveXid);
 	length += item_length;
 	length += item_length;
 	buf += item_length;
 	buf += item_length;
 
 
@@ -360,10 +366,10 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 	list_for_each(tmp, &GlobalTreeConnectionList) {
 	list_for_each(tmp, &GlobalTreeConnectionList) {
 		i++;
 		i++;
 		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
 		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-		item_length = sprintf(buf,"\n%d) %s",i, tcon->treeName);
+		item_length = sprintf(buf, "\n%d) %s", i, tcon->treeName);
 		buf += item_length;
 		buf += item_length;
 		length += item_length;
 		length += item_length;
-		if(tcon->tidStatus == CifsNeedReconnect) {
+		if (tcon->tidStatus == CifsNeedReconnect) {
 			buf += sprintf(buf, "\tDISCONNECTED ");
 			buf += sprintf(buf, "\tDISCONNECTED ");
 			length += 14;
 			length += 14;
 		}
 		}
@@ -380,15 +386,15 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 		item_length = sprintf(buf, "\nWrites: %d Bytes: %lld",
 		item_length = sprintf(buf, "\nWrites: %d Bytes: %lld",
 			atomic_read(&tcon->num_writes),
 			atomic_read(&tcon->num_writes),
 			(long long)(tcon->bytes_written));
 			(long long)(tcon->bytes_written));
-                buf += item_length;
-                length += item_length;
-                item_length = sprintf(buf, 
+		buf += item_length;
+		length += item_length;
+		item_length = sprintf(buf,
 			"\nLocks: %d HardLinks: %d Symlinks: %d",
 			"\nLocks: %d HardLinks: %d Symlinks: %d",
-                        atomic_read(&tcon->num_locks),
+			atomic_read(&tcon->num_locks),
 			atomic_read(&tcon->num_hardlinks),
 			atomic_read(&tcon->num_hardlinks),
 			atomic_read(&tcon->num_symlinks));
 			atomic_read(&tcon->num_symlinks));
-                buf += item_length;
-                length += item_length;
+		buf += item_length;
+		length += item_length;
 
 
 		item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d",
 		item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d",
 			atomic_read(&tcon->num_opens),
 			atomic_read(&tcon->num_opens),
@@ -415,12 +421,12 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 	}
 	}
 	read_unlock(&GlobalSMBSeslock);
 	read_unlock(&GlobalSMBSeslock);
 
 
-	buf += sprintf(buf,"\n");
+	buf += sprintf(buf, "\n");
 	length++;
 	length++;
 
 
-	if(offset + count >= length)
+	if (offset + count >= length)
 		*eof = 1;
 		*eof = 1;
-	if(length < offset) {
+	if (length < offset) {
 		*eof = 1;
 		*eof = 1;
 		return 0;
 		return 0;
 	} else {
 	} else {
@@ -428,7 +434,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 	}
 	}
 	if (length > count)
 	if (length > count)
 		length = count;
 		length = count;
-		
+
 	return length;
 	return length;
 }
 }
 #endif
 #endif
@@ -547,11 +553,11 @@ cifs_proc_clean(void)
 	remove_proc_entry("MultiuserMount", proc_fs_cifs);
 	remove_proc_entry("MultiuserMount", proc_fs_cifs);
 	remove_proc_entry("OplockEnabled", proc_fs_cifs);
 	remove_proc_entry("OplockEnabled", proc_fs_cifs);
 /*	remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */
 /*	remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */
-	remove_proc_entry("SecurityFlags",proc_fs_cifs);
-/*	remove_proc_entry("PacketSigningEnabled",proc_fs_cifs); */
-	remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
-	remove_proc_entry("Experimental",proc_fs_cifs);
-	remove_proc_entry("LookupCacheEnabled",proc_fs_cifs);
+	remove_proc_entry("SecurityFlags", proc_fs_cifs);
+/*	remove_proc_entry("PacketSigningEnabled", proc_fs_cifs); */
+	remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
+	remove_proc_entry("Experimental", proc_fs_cifs);
+	remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
 	remove_proc_entry("cifs", proc_root_fs);
 	remove_proc_entry("cifs", proc_root_fs);
 }
 }
 
 
@@ -590,7 +596,7 @@ cifsFYI_write(struct file *file, const char __user *buffer,
 		cifsFYI = 0;
 		cifsFYI = 0;
 	else if (c == '1' || c == 'y' || c == 'Y')
 	else if (c == '1' || c == 'y' || c == 'Y')
 		cifsFYI = 1;
 		cifsFYI = 1;
-	else if((c > '1') && (c <= '9'))
+	else if ((c > '1') && (c <= '9'))
 		cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
 		cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
 
 
 	return count;
 	return count;
@@ -637,28 +643,28 @@ oplockEnabled_write(struct file *file, const char __user *buffer,
 
 
 static int
 static int
 experimEnabled_read(char *page, char **start, off_t off,
 experimEnabled_read(char *page, char **start, off_t off,
-                   int count, int *eof, void *data)
+		    int count, int *eof, void *data)
 {
 {
-        int len;
+	int len;
 
 
-        len = sprintf(page, "%d\n", experimEnabled);
+	len = sprintf(page, "%d\n", experimEnabled);
 
 
-        len -= off;
-        *start = page + off;
+	len -= off;
+	*start = page + off;
 
 
-        if (len > count)
-                len = count;
-        else
-                *eof = 1;
+	if (len > count)
+		len = count;
+	else
+		*eof = 1;
 
 
-        if (len < 0)
-                len = 0;
+	if (len < 0)
+		len = 0;
 
 
-        return len;
+	return len;
 }
 }
 static int
 static int
 experimEnabled_write(struct file *file, const char __user *buffer,
 experimEnabled_write(struct file *file, const char __user *buffer,
-                    unsigned long count, void *data)
+		     unsigned long count, void *data)
 {
 {
 	char c;
 	char c;
 	int rc;
 	int rc;
@@ -678,46 +684,46 @@ experimEnabled_write(struct file *file, const char __user *buffer,
 
 
 static int
 static int
 linuxExtensionsEnabled_read(char *page, char **start, off_t off,
 linuxExtensionsEnabled_read(char *page, char **start, off_t off,
-                   int count, int *eof, void *data)
+			    int count, int *eof, void *data)
 {
 {
-        int len;
+	int len;
 
 
-        len = sprintf(page, "%d\n", linuxExtEnabled);
-        len -= off;
-        *start = page + off;
+	len = sprintf(page, "%d\n", linuxExtEnabled);
+	len -= off;
+	*start = page + off;
 
 
-        if (len > count)
-                len = count;
-        else
-                *eof = 1;
+	if (len > count)
+		len = count;
+	else
+		*eof = 1;
 
 
-        if (len < 0)
-                len = 0;
+	if (len < 0)
+		len = 0;
 
 
-        return len;
+	return len;
 }
 }
 static int
 static int
 linuxExtensionsEnabled_write(struct file *file, const char __user *buffer,
 linuxExtensionsEnabled_write(struct file *file, const char __user *buffer,
-                    unsigned long count, void *data)
+			     unsigned long count, void *data)
 {
 {
-        char c;
-        int rc;
-
-        rc = get_user(c, buffer);
-        if (rc)
-                return rc;
-        if (c == '0' || c == 'n' || c == 'N')
-                linuxExtEnabled = 0;
-        else if (c == '1' || c == 'y' || c == 'Y')
-                linuxExtEnabled = 1;
-
-        return count;
+	char c;
+	int rc;
+
+	rc = get_user(c, buffer);
+	if (rc)
+		return rc;
+	if (c == '0' || c == 'n' || c == 'N')
+		linuxExtEnabled = 0;
+	else if (c == '1' || c == 'y' || c == 'Y')
+		linuxExtEnabled = 1;
+
+	return count;
 }
 }
 
 
 
 
 static int
 static int
 lookupFlag_read(char *page, char **start, off_t off,
 lookupFlag_read(char *page, char **start, off_t off,
-		   int count, int *eof, void *data)
+		int count, int *eof, void *data)
 {
 {
 	int len;
 	int len;
 
 
@@ -860,15 +866,15 @@ security_flags_write(struct file *file, const char __user *buffer,
 	char flags_string[12];
 	char flags_string[12];
 	char c;
 	char c;
 
 
-	if((count < 1) || (count > 11))
+	if ((count < 1) || (count > 11))
 		return -EINVAL;
 		return -EINVAL;
 
 
 	memset(flags_string, 0, 12);
 	memset(flags_string, 0, 12);
 
 
-	if(copy_from_user(flags_string, buffer, count))
+	if (copy_from_user(flags_string, buffer, count))
 		return -EFAULT;
 		return -EFAULT;
 
 
-	if(count < 3) {
+	if (count < 3) {
 		/* single char or single char followed by null */
 		/* single char or single char followed by null */
 		c = flags_string[0];
 		c = flags_string[0];
 		if (c == '0' || c == 'n' || c == 'N')
 		if (c == '0' || c == 'n' || c == 'N')
@@ -881,15 +887,15 @@ security_flags_write(struct file *file, const char __user *buffer,
 
 
 	flags = simple_strtoul(flags_string, NULL, 0);
 	flags = simple_strtoul(flags_string, NULL, 0);
 
 
-	cFYI(1,("sec flags 0x%x", flags));
+	cFYI(1, ("sec flags 0x%x", flags));
 
 
-	if(flags <= 0)  {
-		cERROR(1,("invalid security flags %s",flags_string));
+	if (flags <= 0)  {
+		cERROR(1, ("invalid security flags %s", flags_string));
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if(flags & ~CIFSSEC_MASK) {
-		cERROR(1,("attempt to set unsupported security flags 0x%x",
+	if (flags & ~CIFSSEC_MASK) {
+		cERROR(1, ("attempt to set unsupported security flags 0x%x",
 			flags & ~CIFSSEC_MASK));
 			flags & ~CIFSSEC_MASK));
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}

+ 6 - 6
fs/cifs/cifs_unicode.c

@@ -6,16 +6,16 @@
  *
  *
  *   This program is free software;  you can redistribute it and/or modify
  *   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
  *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or 
+ *   the Free Software Foundation; either version 2 of the License, or
  *   (at your option) any later version.
  *   (at your option) any later version.
- * 
+ *
  *   This program is distributed in the hope that it will be useful,
  *   This program is distributed in the hope that it will be useful,
  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  *   the GNU General Public License for more details.
  *   the GNU General Public License for more details.
  *
  *
  *   You should have received a copy of the GNU General Public License
  *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
  */
 #include <linux/fs.h>
 #include <linux/fs.h>
@@ -32,7 +32,7 @@
  *
  *
  */
  */
 int
 int
-cifs_strfromUCS_le(char *to, const __le16 * from,	
+cifs_strfromUCS_le(char *to, const __le16 * from,
 		   int len, const struct nls_table *codepage)
 		   int len, const struct nls_table *codepage)
 {
 {
 	int i;
 	int i;
@@ -66,7 +66,7 @@ cifs_strtoUCS(__le16 * to, const char *from, int len,
 {
 {
 	int charlen;
 	int charlen;
 	int i;
 	int i;
-	wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */  
+	wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */
 
 
 	for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
 	for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
 
 
@@ -79,7 +79,7 @@ cifs_strtoUCS(__le16 * to, const char *from, int len,
 			/* A question mark */
 			/* A question mark */
 			to[i] = cpu_to_le16(0x003f);
 			to[i] = cpu_to_le16(0x003f);
 			charlen = 1;
 			charlen = 1;
-		} else 
+		} else
 			to[i] = cpu_to_le16(wchar_to[i]);
 			to[i] = cpu_to_le16(wchar_to[i]);
 
 
 	}
 	}

+ 1 - 1
fs/cifs/cifsfs.c

@@ -825,8 +825,8 @@ cifs_init_mids(void)
 				sizeof (struct oplock_q_entry), 0,
 				sizeof (struct oplock_q_entry), 0,
 				SLAB_HWCACHE_ALIGN, NULL, NULL);
 				SLAB_HWCACHE_ALIGN, NULL, NULL);
 	if (cifs_oplock_cachep == NULL) {
 	if (cifs_oplock_cachep == NULL) {
-		kmem_cache_destroy(cifs_mid_cachep);
 		mempool_destroy(cifs_mid_poolp);
 		mempool_destroy(cifs_mid_poolp);
+		kmem_cache_destroy(cifs_mid_cachep);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 

+ 2 - 2
fs/cifs/cifssmb.c

@@ -433,8 +433,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 	cFYI(1,("secFlags 0x%x",secFlags));
 	cFYI(1,("secFlags 0x%x",secFlags));
 
 
 	pSMB->hdr.Mid = GetNextMid(server);
 	pSMB->hdr.Mid = GetNextMid(server);
-	pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
-	if((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
+	pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
+	if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
 		pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
 		pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
 	
 	
 	count = 0;
 	count = 0;

+ 13 - 3
fs/cifs/connect.c

@@ -2069,8 +2069,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 			srvTcp->tcpStatus = CifsExiting;
 			srvTcp->tcpStatus = CifsExiting;
 			spin_unlock(&GlobalMid_Lock);
 			spin_unlock(&GlobalMid_Lock);
 			if (srvTcp->tsk) {
 			if (srvTcp->tsk) {
+				struct task_struct *tsk;
+				/* If we could verify that kthread_stop would
+				   always wake up processes blocked in
+				   tcp in recv_mesg then we could remove the
+				   send_sig call */
 				send_sig(SIGKILL,srvTcp->tsk,1);
 				send_sig(SIGKILL,srvTcp->tsk,1);
-				kthread_stop(srvTcp->tsk);
+				tsk = srvTcp->tsk;
+				if(tsk)
+					kthread_stop(tsk);
 			}
 			}
 		}
 		}
 		 /* If find_unc succeeded then rc == 0 so we can not end */
 		 /* If find_unc succeeded then rc == 0 so we can not end */
@@ -2085,8 +2092,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 					/* if the socketUseCount is now zero */
 					/* if the socketUseCount is now zero */
 					if ((temp_rc == -ESHUTDOWN) &&
 					if ((temp_rc == -ESHUTDOWN) &&
 					   (pSesInfo->server) && (pSesInfo->server->tsk)) {
 					   (pSesInfo->server) && (pSesInfo->server->tsk)) {
+						struct task_struct *tsk;
 						send_sig(SIGKILL,pSesInfo->server->tsk,1);
 						send_sig(SIGKILL,pSesInfo->server->tsk,1);
-						kthread_stop(pSesInfo->server->tsk);
+						tsk = pSesInfo->server->tsk;
+						if (tsk)
+							kthread_stop(tsk);
 					}
 					}
 				} else
 				} else
 					cFYI(1, ("No session or bad tcon"));
 					cFYI(1, ("No session or bad tcon"));
@@ -3334,7 +3344,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
 				return 0;
 				return 0;
 			} else if (rc == -ESHUTDOWN) {
 			} else if (rc == -ESHUTDOWN) {
 				cFYI(1,("Waking up socket by sending it signal"));
 				cFYI(1,("Waking up socket by sending it signal"));
-				if(cifsd_task) {
+				if (cifsd_task) {
 					send_sig(SIGKILL,cifsd_task,1);
 					send_sig(SIGKILL,cifsd_task,1);
 					kthread_stop(cifsd_task);
 					kthread_stop(cifsd_task);
 				}
 				}

+ 94 - 90
fs/cifs/dir.c

@@ -2,7 +2,7 @@
  *   fs/cifs/dir.c
  *   fs/cifs/dir.c
  *
  *
  *   vfs operations that deal with dentries
  *   vfs operations that deal with dentries
- * 
+ *
  *   Copyright (C) International Business Machines  Corp., 2002,2005
  *   Copyright (C) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *
@@ -34,11 +34,12 @@
 static void
 static void
 renew_parental_timestamps(struct dentry *direntry)
 renew_parental_timestamps(struct dentry *direntry)
 {
 {
-	/* BB check if there is a way to get the kernel to do this or if we really need this */
+	/* BB check if there is a way to get the kernel to do this or if we
+	   really need this */
 	do {
 	do {
 		direntry->d_time = jiffies;
 		direntry->d_time = jiffies;
 		direntry = direntry->d_parent;
 		direntry = direntry->d_parent;
-	} while (!IS_ROOT(direntry));	
+	} while (!IS_ROOT(direntry));
 }
 }
 
 
 /* Note: caller must free return buffer */
 /* Note: caller must free return buffer */
@@ -51,7 +52,7 @@ build_path_from_dentry(struct dentry *direntry)
 	char *full_path;
 	char *full_path;
 	char dirsep;
 	char dirsep;
 
 
-	if(direntry == NULL)
+	if (direntry == NULL)
 		return NULL;  /* not much we can do if dentry is freed and
 		return NULL;  /* not much we can do if dentry is freed and
 		we need to reopen the file after it was closed implicitly
 		we need to reopen the file after it was closed implicitly
 		when the server crashed */
 		when the server crashed */
@@ -59,18 +60,18 @@ build_path_from_dentry(struct dentry *direntry)
 	dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
 	dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
 	pplen = CIFS_SB(direntry->d_sb)->prepathlen;
 	pplen = CIFS_SB(direntry->d_sb)->prepathlen;
 cifs_bp_rename_retry:
 cifs_bp_rename_retry:
-	namelen = pplen; 
+	namelen = pplen;
 	for (temp = direntry; !IS_ROOT(temp);) {
 	for (temp = direntry; !IS_ROOT(temp);) {
 		namelen += (1 + temp->d_name.len);
 		namelen += (1 + temp->d_name.len);
 		temp = temp->d_parent;
 		temp = temp->d_parent;
-		if(temp == NULL) {
-			cERROR(1,("corrupt dentry"));
+		if (temp == NULL) {
+			cERROR(1, ("corrupt dentry"));
 			return NULL;
 			return NULL;
 		}
 		}
 	}
 	}
 
 
 	full_path = kmalloc(namelen+1, GFP_KERNEL);
 	full_path = kmalloc(namelen+1, GFP_KERNEL);
-	if(full_path == NULL)
+	if (full_path == NULL)
 		return full_path;
 		return full_path;
 	full_path[namelen] = 0;	/* trailing null */
 	full_path[namelen] = 0;	/* trailing null */
 	for (temp = direntry; !IS_ROOT(temp);) {
 	for (temp = direntry; !IS_ROOT(temp);) {
@@ -84,8 +85,8 @@ cifs_bp_rename_retry:
 			cFYI(0, ("name: %s", full_path + namelen));
 			cFYI(0, ("name: %s", full_path + namelen));
 		}
 		}
 		temp = temp->d_parent;
 		temp = temp->d_parent;
-		if(temp == NULL) {
-			cERROR(1,("corrupt dentry"));
+		if (temp == NULL) {
+			cERROR(1, ("corrupt dentry"));
 			kfree(full_path);
 			kfree(full_path);
 			return NULL;
 			return NULL;
 		}
 		}
@@ -94,7 +95,7 @@ cifs_bp_rename_retry:
 		cERROR(1,
 		cERROR(1,
 		       ("did not end path lookup where expected namelen is %d",
 		       ("did not end path lookup where expected namelen is %d",
 			namelen));
 			namelen));
-		/* presumably this is only possible if racing with a rename 
+		/* presumably this is only possible if racing with a rename
 		of one of the parent directories  (we can not lock the dentries
 		of one of the parent directories  (we can not lock the dentries
 		above us to prevent this, but retrying should be harmless) */
 		above us to prevent this, but retrying should be harmless) */
 		kfree(full_path);
 		kfree(full_path);
@@ -106,7 +107,7 @@ cifs_bp_rename_retry:
 	   since the '\' is a valid posix character so we can not switch
 	   since the '\' is a valid posix character so we can not switch
 	   those safely to '/' if any are found in the middle of the prepath */
 	   those safely to '/' if any are found in the middle of the prepath */
 	/* BB test paths to Windows with '/' in the midst of prepath */
 	/* BB test paths to Windows with '/' in the midst of prepath */
-	strncpy(full_path,CIFS_SB(direntry->d_sb)->prepath,pplen);
+	strncpy(full_path, CIFS_SB(direntry->d_sb)->prepath, pplen);
 	return full_path;
 	return full_path;
 }
 }
 
 
@@ -147,12 +148,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 	pTcon = cifs_sb->tcon;
 	pTcon = cifs_sb->tcon;
 
 
 	full_path = build_path_from_dentry(direntry);
 	full_path = build_path_from_dentry(direntry);
-	if(full_path == NULL) {
+	if (full_path == NULL) {
 		FreeXid(xid);
 		FreeXid(xid);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	if(nd && (nd->flags & LOOKUP_OPEN)) {
+	if (nd && (nd->flags & LOOKUP_OPEN)) {
 		int oflags = nd->intent.open.flags;
 		int oflags = nd->intent.open.flags;
 
 
 		desiredAccess = 0;
 		desiredAccess = 0;
@@ -164,28 +165,29 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 				write_only = TRUE;
 				write_only = TRUE;
 		}
 		}
 
 
-		if((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+		if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
 			disposition = FILE_CREATE;
 			disposition = FILE_CREATE;
-		else if((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
+		else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
 			disposition = FILE_OVERWRITE_IF;
 			disposition = FILE_OVERWRITE_IF;
-		else if((oflags & O_CREAT) == O_CREAT)
+		else if ((oflags & O_CREAT) == O_CREAT)
 			disposition = FILE_OPEN_IF;
 			disposition = FILE_OPEN_IF;
 		else {
 		else {
-			cFYI(1,("Create flag not set in create function"));
+			cFYI(1, ("Create flag not set in create function"));
 		}
 		}
 	}
 	}
 
 
-	/* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */
+	/* BB add processing to set equivalent of mode - e.g. via CreateX with
+	   ACLs */
 	if (oplockEnabled)
 	if (oplockEnabled)
 		oplock = REQ_OPLOCK;
 		oplock = REQ_OPLOCK;
 
 
-	buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
-	if(buf == NULL) {
+	buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+	if (buf == NULL) {
 		kfree(full_path);
 		kfree(full_path);
 		FreeXid(xid);
 		FreeXid(xid);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
-	if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 
+	if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
 		rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
 		rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
 			 desiredAccess, CREATE_NOT_DIR,
 			 desiredAccess, CREATE_NOT_DIR,
 			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
 			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
@@ -193,27 +195,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 	else
 	else
 		rc = -EIO; /* no NT SMB support fall into legacy open below */
 		rc = -EIO; /* no NT SMB support fall into legacy open below */
 
 
-	if(rc == -EIO) {
+	if (rc == -EIO) {
 		/* old server, retry the open legacy style */
 		/* old server, retry the open legacy style */
 		rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
 		rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
 			desiredAccess, CREATE_NOT_DIR,
 			desiredAccess, CREATE_NOT_DIR,
 			&fileHandle, &oplock, buf, cifs_sb->local_nls,
 			&fileHandle, &oplock, buf, cifs_sb->local_nls,
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-	} 
+	}
 	if (rc) {
 	if (rc) {
 		cFYI(1, ("cifs_create returned 0x%x", rc));
 		cFYI(1, ("cifs_create returned 0x%x", rc));
 	} else {
 	} else {
 		/* If Open reported that we actually created a file
 		/* If Open reported that we actually created a file
 		then we now have to set the mode if possible */
 		then we now have to set the mode if possible */
 		if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
 		if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
-			(oplock & CIFS_CREATE_ACTION))
-			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+			(oplock & CIFS_CREATE_ACTION)) {
+			mode &= ~current->fs->umask;
+			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
 					(__u64)current->fsuid,
 					(__u64)current->fsuid,
 					(__u64)current->fsgid,
 					(__u64)current->fsgid,
 					0 /* dev */,
 					0 /* dev */,
-					cifs_sb->local_nls, 
-					cifs_sb->mnt_cifs_flags & 
+					cifs_sb->local_nls,
+					cifs_sb->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			} else {
 			} else {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
@@ -221,26 +224,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 					(__u64)-1,
 					(__u64)-1,
 					0 /* dev */,
 					0 /* dev */,
 					cifs_sb->local_nls,
 					cifs_sb->local_nls,
-					cifs_sb->mnt_cifs_flags & 
+					cifs_sb->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			}
 			}
-		else {
-			/* BB implement mode setting via Windows security descriptors */
-			/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
-			/* could set r/o dos attribute if mode & 0222 == 0 */
+		} else {
+			/* BB implement mode setting via Windows security
+			   descriptors e.g. */
+			/* CIFSSMBWinSetPerms(xid,pTcon,path,mode,-1,-1,nls);*/
+
+			/* Could set r/o dos attribute if mode & 0222 == 0 */
 		}
 		}
 
 
 	/* BB server might mask mode so we have to query for Unix case*/
 	/* BB server might mask mode so we have to query for Unix case*/
 		if (pTcon->ses->capabilities & CAP_UNIX)
 		if (pTcon->ses->capabilities & CAP_UNIX)
 			rc = cifs_get_inode_info_unix(&newinode, full_path,
 			rc = cifs_get_inode_info_unix(&newinode, full_path,
-						 inode->i_sb,xid);
+						 inode->i_sb, xid);
 		else {
 		else {
 			rc = cifs_get_inode_info(&newinode, full_path,
 			rc = cifs_get_inode_info(&newinode, full_path,
-						 buf, inode->i_sb,xid);
-			if(newinode) {
+						 buf, inode->i_sb, xid);
+			if (newinode) {
 				newinode->i_mode = mode;
 				newinode->i_mode = mode;
-				if((oplock & CIFS_CREATE_ACTION) &&
-				  (cifs_sb->mnt_cifs_flags & 
+				if ((oplock & CIFS_CREATE_ACTION) &&
+				    (cifs_sb->mnt_cifs_flags &
 				     CIFS_MOUNT_SET_UID)) {
 				     CIFS_MOUNT_SET_UID)) {
 					newinode->i_uid = current->fsuid;
 					newinode->i_uid = current->fsuid;
 					newinode->i_gid = current->fsgid;
 					newinode->i_gid = current->fsgid;
@@ -259,14 +264,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 				direntry->d_op = &cifs_dentry_ops;
 				direntry->d_op = &cifs_dentry_ops;
 			d_instantiate(direntry, newinode);
 			d_instantiate(direntry, newinode);
 		}
 		}
-		if((nd->flags & LOOKUP_OPEN) == FALSE) {
+		if ((nd->flags & LOOKUP_OPEN) == FALSE) {
 			/* mknod case - do not leave file open */
 			/* mknod case - do not leave file open */
 			CIFSSMBClose(xid, pTcon, fileHandle);
 			CIFSSMBClose(xid, pTcon, fileHandle);
-		} else if(newinode) {
+		} else if (newinode) {
 			pCifsFile =
 			pCifsFile =
 			   kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
 			   kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
-			
-			if(pCifsFile == NULL)
+
+			if (pCifsFile == NULL)
 				goto cifs_create_out;
 				goto cifs_create_out;
 			pCifsFile->netfid = fileHandle;
 			pCifsFile->netfid = fileHandle;
 			pCifsFile->pid = current->tgid;
 			pCifsFile->pid = current->tgid;
@@ -276,33 +281,33 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 			init_MUTEX(&pCifsFile->fh_sem);
 			init_MUTEX(&pCifsFile->fh_sem);
 			mutex_init(&pCifsFile->lock_mutex);
 			mutex_init(&pCifsFile->lock_mutex);
 			INIT_LIST_HEAD(&pCifsFile->llist);
 			INIT_LIST_HEAD(&pCifsFile->llist);
-			atomic_set(&pCifsFile->wrtPending,0);
+			atomic_set(&pCifsFile->wrtPending, 0);
 
 
-			/* set the following in open now 
+			/* set the following in open now
 				pCifsFile->pfile = file; */
 				pCifsFile->pfile = file; */
 			write_lock(&GlobalSMBSeslock);
 			write_lock(&GlobalSMBSeslock);
-			list_add(&pCifsFile->tlist,&pTcon->openFileList);
+			list_add(&pCifsFile->tlist, &pTcon->openFileList);
 			pCifsInode = CIFS_I(newinode);
 			pCifsInode = CIFS_I(newinode);
-			if(pCifsInode) {
+			if (pCifsInode) {
 				/* if readable file instance put first in list*/
 				/* if readable file instance put first in list*/
 				if (write_only == TRUE) {
 				if (write_only == TRUE) {
-                                       	list_add_tail(&pCifsFile->flist,
+					list_add_tail(&pCifsFile->flist,
 						&pCifsInode->openFileList);
 						&pCifsInode->openFileList);
 				} else {
 				} else {
 					list_add(&pCifsFile->flist,
 					list_add(&pCifsFile->flist,
 						&pCifsInode->openFileList);
 						&pCifsInode->openFileList);
 				}
 				}
-				if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
+				if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
 					pCifsInode->clientCanCacheAll = TRUE;
 					pCifsInode->clientCanCacheAll = TRUE;
 					pCifsInode->clientCanCacheRead = TRUE;
 					pCifsInode->clientCanCacheRead = TRUE;
-					cFYI(1,("Exclusive Oplock for inode %p",
+					cFYI(1, ("Exclusive Oplock inode %p",
 						newinode));
 						newinode));
-				} else if((oplock & 0xF) == OPLOCK_READ)
+				} else if ((oplock & 0xF) == OPLOCK_READ)
 					pCifsInode->clientCanCacheRead = TRUE;
 					pCifsInode->clientCanCacheRead = TRUE;
 			}
 			}
 			write_unlock(&GlobalSMBSeslock);
 			write_unlock(&GlobalSMBSeslock);
 		}
 		}
-	} 
+	}
 cifs_create_out:
 cifs_create_out:
 	kfree(buf);
 	kfree(buf);
 	kfree(full_path);
 	kfree(full_path);
@@ -310,8 +315,8 @@ cifs_create_out:
 	return rc;
 	return rc;
 }
 }
 
 
-int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, 
-		dev_t device_number) 
+int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
+		dev_t device_number)
 {
 {
 	int rc = -EPERM;
 	int rc = -EPERM;
 	int xid;
 	int xid;
@@ -329,43 +334,45 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 	pTcon = cifs_sb->tcon;
 	pTcon = cifs_sb->tcon;
 
 
 	full_path = build_path_from_dentry(direntry);
 	full_path = build_path_from_dentry(direntry);
-	if(full_path == NULL)
+	if (full_path == NULL)
 		rc = -ENOMEM;
 		rc = -ENOMEM;
 	else if (pTcon->ses->capabilities & CAP_UNIX) {
 	else if (pTcon->ses->capabilities & CAP_UNIX) {
-		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
+		mode &= ~current->fs->umask;
+		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 			rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 			rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
-				mode,(__u64)current->fsuid,(__u64)current->fsgid,
+				mode, (__u64)current->fsuid,
+				(__u64)current->fsgid,
 				device_number, cifs_sb->local_nls,
 				device_number, cifs_sb->local_nls,
-				cifs_sb->mnt_cifs_flags & 
+				cifs_sb->mnt_cifs_flags &
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		} else {
 		} else {
 			rc = CIFSSMBUnixSetPerms(xid, pTcon,
 			rc = CIFSSMBUnixSetPerms(xid, pTcon,
 				full_path, mode, (__u64)-1, (__u64)-1,
 				full_path, mode, (__u64)-1, (__u64)-1,
 				device_number, cifs_sb->local_nls,
 				device_number, cifs_sb->local_nls,
-				cifs_sb->mnt_cifs_flags & 
+				cifs_sb->mnt_cifs_flags &
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		}
 		}
 
 
-		if(!rc) {
+		if (!rc) {
 			rc = cifs_get_inode_info_unix(&newinode, full_path,
 			rc = cifs_get_inode_info_unix(&newinode, full_path,
-						inode->i_sb,xid);
+						inode->i_sb, xid);
 			if (pTcon->nocase)
 			if (pTcon->nocase)
 				direntry->d_op = &cifs_ci_dentry_ops;
 				direntry->d_op = &cifs_ci_dentry_ops;
 			else
 			else
 				direntry->d_op = &cifs_dentry_ops;
 				direntry->d_op = &cifs_dentry_ops;
-			if(rc == 0)
+			if (rc == 0)
 				d_instantiate(direntry, newinode);
 				d_instantiate(direntry, newinode);
 		}
 		}
 	} else {
 	} else {
-		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
+		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
 			int oplock = 0;
 			int oplock = 0;
 			u16 fileHandle;
 			u16 fileHandle;
 			FILE_ALL_INFO * buf;
 			FILE_ALL_INFO * buf;
 
 
-			cFYI(1,("sfu compat create special file"));
+			cFYI(1, ("sfu compat create special file"));
 
 
-			buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
-			if(buf == NULL) {
+			buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+			if (buf == NULL) {
 				kfree(full_path);
 				kfree(full_path);
 				FreeXid(xid);
 				FreeXid(xid);
 				return -ENOMEM;
 				return -ENOMEM;
@@ -373,39 +380,38 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 
 
 			rc = CIFSSMBOpen(xid, pTcon, full_path,
 			rc = CIFSSMBOpen(xid, pTcon, full_path,
 					 FILE_CREATE, /* fail if exists */
 					 FILE_CREATE, /* fail if exists */
-					 GENERIC_WRITE /* BB would 
+					 GENERIC_WRITE /* BB would
 					  WRITE_OWNER | WRITE_DAC be better? */,
 					  WRITE_OWNER | WRITE_DAC be better? */,
 					 /* Create a file and set the
 					 /* Create a file and set the
 					    file attribute to SYSTEM */
 					    file attribute to SYSTEM */
 					 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
 					 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
 					 &fileHandle, &oplock, buf,
 					 &fileHandle, &oplock, buf,
 					 cifs_sb->local_nls,
 					 cifs_sb->local_nls,
-					 cifs_sb->mnt_cifs_flags & 
+					 cifs_sb->mnt_cifs_flags &
 					    CIFS_MOUNT_MAP_SPECIAL_CHR);
 					    CIFS_MOUNT_MAP_SPECIAL_CHR);
 
 
 			/* BB FIXME - add handling for backlevel servers
 			/* BB FIXME - add handling for backlevel servers
 			   which need legacy open and check for all
 			   which need legacy open and check for all
-			   calls to SMBOpen for fallback to 
-			   SMBLeagcyOpen */
-			if(!rc) {
+			   calls to SMBOpen for fallback to SMBLeagcyOpen */
+			if (!rc) {
 				/* BB Do not bother to decode buf since no
 				/* BB Do not bother to decode buf since no
 				   local inode yet to put timestamps in,
 				   local inode yet to put timestamps in,
 				   but we can reuse it safely */
 				   but we can reuse it safely */
 				int bytes_written;
 				int bytes_written;
 				struct win_dev *pdev;
 				struct win_dev *pdev;
 				pdev = (struct win_dev *)buf;
 				pdev = (struct win_dev *)buf;
-				if(S_ISCHR(mode)) {
+				if (S_ISCHR(mode)) {
 					memcpy(pdev->type, "IntxCHR", 8);
 					memcpy(pdev->type, "IntxCHR", 8);
 					pdev->major =
 					pdev->major =
 					      cpu_to_le64(MAJOR(device_number));
 					      cpu_to_le64(MAJOR(device_number));
-					pdev->minor = 
+					pdev->minor =
 					      cpu_to_le64(MINOR(device_number));
 					      cpu_to_le64(MINOR(device_number));
 					rc = CIFSSMBWrite(xid, pTcon,
 					rc = CIFSSMBWrite(xid, pTcon,
 						fileHandle,
 						fileHandle,
 						sizeof(struct win_dev),
 						sizeof(struct win_dev),
 						0, &bytes_written, (char *)pdev,
 						0, &bytes_written, (char *)pdev,
 						NULL, 0);
 						NULL, 0);
-				} else if(S_ISBLK(mode)) {
+				} else if (S_ISBLK(mode)) {
 					memcpy(pdev->type, "IntxBLK", 8);
 					memcpy(pdev->type, "IntxBLK", 8);
 					pdev->major =
 					pdev->major =
 					      cpu_to_le64(MAJOR(device_number));
 					      cpu_to_le64(MAJOR(device_number));
@@ -432,7 +438,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 
 
 
 
 struct dentry *
 struct dentry *
-cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct nameidata *nd)
+cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
+	    struct nameidata *nd)
 {
 {
 	int xid;
 	int xid;
 	int rc = 0; /* to get around spurious gcc warning, set to zero here */
 	int rc = 0; /* to get around spurious gcc warning, set to zero here */
@@ -447,8 +454,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
 	     (" parent inode = 0x%p name is: %s and dentry = 0x%p",
 	     (" parent inode = 0x%p name is: %s and dentry = 0x%p",
 	      parent_dir_inode, direntry->d_name.name, direntry));
 	      parent_dir_inode, direntry->d_name.name, direntry));
 
 
-	/* BB Add check of incoming data - e.g. frame not longer than maximum SMB - let server check the namelen BB */
-
 	/* check whether path exists */
 	/* check whether path exists */
 
 
 	cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
 	cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
@@ -472,7 +477,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
 	deadlock in the cases (beginning of sys_rename itself)
 	deadlock in the cases (beginning of sys_rename itself)
 	in which we already have the sb rename sem */
 	in which we already have the sb rename sem */
 	full_path = build_path_from_dentry(direntry);
 	full_path = build_path_from_dentry(direntry);
-	if(full_path == NULL) {
+	if (full_path == NULL) {
 		FreeXid(xid);
 		FreeXid(xid);
 		return ERR_PTR(-ENOMEM);
 		return ERR_PTR(-ENOMEM);
 	}
 	}
@@ -487,10 +492,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
 
 
 	if (pTcon->ses->capabilities & CAP_UNIX)
 	if (pTcon->ses->capabilities & CAP_UNIX)
 		rc = cifs_get_inode_info_unix(&newInode, full_path,
 		rc = cifs_get_inode_info_unix(&newInode, full_path,
-					      parent_dir_inode->i_sb,xid);
+					      parent_dir_inode->i_sb, xid);
 	else
 	else
 		rc = cifs_get_inode_info(&newInode, full_path, NULL,
 		rc = cifs_get_inode_info(&newInode, full_path, NULL,
-					 parent_dir_inode->i_sb,xid);
+					 parent_dir_inode->i_sb, xid);
 
 
 	if ((rc == 0) && (newInode != NULL)) {
 	if ((rc == 0) && (newInode != NULL)) {
 		if (pTcon->nocase)
 		if (pTcon->nocase)
@@ -499,7 +504,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
 			direntry->d_op = &cifs_dentry_ops;
 			direntry->d_op = &cifs_dentry_ops;
 		d_add(direntry, newInode);
 		d_add(direntry, newInode);
 
 
-		/* since paths are not looked up by component - the parent 
+		/* since paths are not looked up by component - the parent
 		   directories are presumed to be good here */
 		   directories are presumed to be good here */
 		renew_parental_timestamps(direntry);
 		renew_parental_timestamps(direntry);
 
 
@@ -511,13 +516,13 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
 		else
 		else
 			direntry->d_op = &cifs_dentry_ops;
 			direntry->d_op = &cifs_dentry_ops;
 		d_add(direntry, NULL);
 		d_add(direntry, NULL);
-	/*	if it was once a directory (but how can we tell?) we could do  
-			shrink_dcache_parent(direntry); */
+	/*	if it was once a directory (but how can we tell?) we could do
+		shrink_dcache_parent(direntry); */
 	} else {
 	} else {
-		cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
-			   rc,full_path));
-		/* BB special case check for Access Denied - watch security 
-		exposure of returning dir info implicitly via different rc 
+		cERROR(1, ("Error 0x%x on cifs_get_inode_info in lookup of %s",
+			   rc, full_path));
+		/* BB special case check for Access Denied - watch security
+		exposure of returning dir info implicitly via different rc
 		if file exists or not but no access BB */
 		if file exists or not but no access BB */
 	}
 	}
 
 
@@ -538,11 +543,11 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 	} else {
 	} else {
 		cFYI(1, ("neg dentry 0x%p name = %s",
 		cFYI(1, ("neg dentry 0x%p name = %s",
 			 direntry, direntry->d_name.name));
 			 direntry, direntry->d_name.name));
-		if(time_after(jiffies, direntry->d_time + HZ) || 
+		if (time_after(jiffies, direntry->d_time + HZ) ||
 			!lookupCacheEnabled) {
 			!lookupCacheEnabled) {
 			d_drop(direntry);
 			d_drop(direntry);
 			isValid = 0;
 			isValid = 0;
-		} 
+		}
 	}
 	}
 
 
 	return isValid;
 	return isValid;
@@ -559,8 +564,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 
 
 struct dentry_operations cifs_dentry_ops = {
 struct dentry_operations cifs_dentry_ops = {
 	.d_revalidate = cifs_d_revalidate,
 	.d_revalidate = cifs_d_revalidate,
-/* d_delete:       cifs_d_delete,       *//* not needed except for debugging */
-	/* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */
+/* d_delete:       cifs_d_delete,      */ /* not needed except for debugging */
 };
 };
 
 
 static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
 static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)

+ 22 - 24
fs/cifs/fcntl.c

@@ -2,7 +2,7 @@
  *   fs/cifs/fcntl.c
  *   fs/cifs/fcntl.c
  *
  *
  *   vfs operations that deal with the file control API
  *   vfs operations that deal with the file control API
- * 
+ *
  *   Copyright (C) International Business Machines  Corp., 2003,2004
  *   Copyright (C) International Business Machines  Corp., 2003,2004
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *
@@ -35,35 +35,34 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
 
 
 	/* No way on Linux VFS to ask to monitor xattr
 	/* No way on Linux VFS to ask to monitor xattr
 	changes (and no stream support either */
 	changes (and no stream support either */
-	if(fcntl_notify_flags & DN_ACCESS) {
+	if (fcntl_notify_flags & DN_ACCESS) {
 		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
 		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
 	}
 	}
-	if(fcntl_notify_flags & DN_MODIFY) {
+	if (fcntl_notify_flags & DN_MODIFY) {
 		/* What does this mean on directories? */
 		/* What does this mean on directories? */
 		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE |
 		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE |
 			FILE_NOTIFY_CHANGE_SIZE;
 			FILE_NOTIFY_CHANGE_SIZE;
 	}
 	}
-	if(fcntl_notify_flags & DN_CREATE) {
-		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION | 
+	if (fcntl_notify_flags & DN_CREATE) {
+		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION |
 			FILE_NOTIFY_CHANGE_LAST_WRITE;
 			FILE_NOTIFY_CHANGE_LAST_WRITE;
 	}
 	}
-	if(fcntl_notify_flags & DN_DELETE) {
+	if (fcntl_notify_flags & DN_DELETE) {
 		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE;
 		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE;
 	}
 	}
-	if(fcntl_notify_flags & DN_RENAME) {
+	if (fcntl_notify_flags & DN_RENAME) {
 		/* BB review this - checking various server behaviors */
 		/* BB review this - checking various server behaviors */
-		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME | 
+		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME |
 			FILE_NOTIFY_CHANGE_FILE_NAME;
 			FILE_NOTIFY_CHANGE_FILE_NAME;
 	}
 	}
-	if(fcntl_notify_flags & DN_ATTRIB) {
-		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_SECURITY | 
+	if (fcntl_notify_flags & DN_ATTRIB) {
+		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_SECURITY |
 			FILE_NOTIFY_CHANGE_ATTRIBUTES;
 			FILE_NOTIFY_CHANGE_ATTRIBUTES;
 	}
 	}
-/*	if(fcntl_notify_flags & DN_MULTISHOT) {
+/*	if (fcntl_notify_flags & DN_MULTISHOT) {
 		cifs_ntfy_flags |= ;
 		cifs_ntfy_flags |= ;
 	} */ /* BB fixme - not sure how to handle this with CIFS yet */
 	} */ /* BB fixme - not sure how to handle this with CIFS yet */
 
 
-
 	return cifs_ntfy_flags;
 	return cifs_ntfy_flags;
 }
 }
 
 
@@ -78,8 +77,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
 	__u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
 	__u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
 	__u16 netfid;
 	__u16 netfid;
 
 
-
-	if(experimEnabled == 0)
+	if (experimEnabled == 0)
 		return 0;
 		return 0;
 
 
 	xid = GetXid();
 	xid = GetXid();
@@ -88,21 +86,21 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
 
 
 	full_path = build_path_from_dentry(file->f_path.dentry);
 	full_path = build_path_from_dentry(file->f_path.dentry);
 
 
-	if(full_path == NULL) {
+	if (full_path == NULL) {
 		rc = -ENOMEM;
 		rc = -ENOMEM;
 	} else {
 	} else {
-		cFYI(1,("dir notify on file %s Arg 0x%lx",full_path,arg));
-		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 
+		cFYI(1, ("dir notify on file %s Arg 0x%lx", full_path, arg));
+		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
 			GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
 			GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
-			&netfid, &oplock,NULL, cifs_sb->local_nls,
+			&netfid, &oplock, NULL, cifs_sb->local_nls,
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 		/* BB fixme - add this handle to a notify handle list */
 		/* BB fixme - add this handle to a notify handle list */
-		if(rc) {
-			cFYI(1,("Could not open directory for notify"));
+		if (rc) {
+			cFYI(1, ("Could not open directory for notify"));
 		} else {
 		} else {
 			filter = convert_to_cifs_notify_flags(arg);
 			filter = convert_to_cifs_notify_flags(arg);
-			if(filter != 0) {
-				rc = CIFSSMBNotify(xid, pTcon, 
+			if (filter != 0) {
+				rc = CIFSSMBNotify(xid, pTcon,
 					0 /* no subdirs */, netfid,
 					0 /* no subdirs */, netfid,
 					filter, file, arg & DN_MULTISHOT,
 					filter, file, arg & DN_MULTISHOT,
 					cifs_sb->local_nls);
 					cifs_sb->local_nls);
@@ -113,10 +111,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
 			it would close automatically but may be a way
 			it would close automatically but may be a way
 			to do it easily when inode freed or when
 			to do it easily when inode freed or when
 			notify info is cleared/changed */
 			notify info is cleared/changed */
-			cFYI(1,("notify rc %d",rc));
+			cFYI(1, ("notify rc %d", rc));
 		}
 		}
 	}
 	}
-	
+
 	FreeXid(xid);
 	FreeXid(xid);
 	return rc;
 	return rc;
 }
 }

+ 3 - 2
fs/cifs/inode.c

@@ -986,7 +986,8 @@ mkdir_get_info:
 		  * failed to get it from the server or was set bogus */ 
 		  * failed to get it from the server or was set bogus */ 
 		if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
 		if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
 				direntry->d_inode->i_nlink = 2; 
 				direntry->d_inode->i_nlink = 2; 
-		if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
+		if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) {
+			mode &= ~current->fs->umask;
 			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 						    mode,
 						    mode,
@@ -1004,7 +1005,7 @@ mkdir_get_info:
 						    cifs_sb->mnt_cifs_flags & 
 						    cifs_sb->mnt_cifs_flags & 
 						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 			}
 			}
-		else {
+		} else {
 			/* BB to be implemented via Windows secrty descriptors
 			/* BB to be implemented via Windows secrty descriptors
 			   eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
 			   eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
 						 -1, -1, local_nls); */
 						 -1, -1, local_nls); */

+ 14 - 15
fs/cifs/ioctl.c

@@ -30,7 +30,7 @@
 
 
 #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
 #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
 
 
-int cifs_ioctl (struct inode * inode, struct file * filep, 
+int cifs_ioctl (struct inode * inode, struct file * filep,
 		unsigned int command, unsigned long arg)
 		unsigned int command, unsigned long arg)
 {
 {
 	int rc = -ENOTTY; /* strange error - but the precedent */
 	int rc = -ENOTTY; /* strange error - but the precedent */
@@ -47,13 +47,13 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
 
 
 	xid = GetXid();
 	xid = GetXid();
 
 
-        cFYI(1,("ioctl file %p  cmd %u  arg %lu",filep,command,arg));
+	cFYI(1, ("ioctl file %p  cmd %u  arg %lu", filep, command, arg));
 
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 	cifs_sb = CIFS_SB(inode->i_sb);
 
 
 #ifdef CONFIG_CIFS_POSIX
 #ifdef CONFIG_CIFS_POSIX
 	tcon = cifs_sb->tcon;
 	tcon = cifs_sb->tcon;
-	if(tcon)
+	if (tcon)
 		caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
 		caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
 	else {
 	else {
 		rc = -EIO;
 		rc = -EIO;
@@ -62,24 +62,24 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
 	}
 	}
 #endif /* CONFIG_CIFS_POSIX */
 #endif /* CONFIG_CIFS_POSIX */
 
 
-	switch(command) {
+	switch (command) {
 		case CIFS_IOC_CHECKUMOUNT:
 		case CIFS_IOC_CHECKUMOUNT:
-			cFYI(1,("User unmount attempted"));
-			if(cifs_sb->mnt_uid == current->uid)
+			cFYI(1, ("User unmount attempted"));
+			if (cifs_sb->mnt_uid == current->uid)
 				rc = 0;
 				rc = 0;
 			else {
 			else {
 				rc = -EACCES;
 				rc = -EACCES;
-				cFYI(1,("uids do not match"));
+				cFYI(1, ("uids do not match"));
 			}
 			}
 			break;
 			break;
 #ifdef CONFIG_CIFS_POSIX
 #ifdef CONFIG_CIFS_POSIX
 		case FS_IOC_GETFLAGS:
 		case FS_IOC_GETFLAGS:
-			if(CIFS_UNIX_EXTATTR_CAP & caps) {
+			if (CIFS_UNIX_EXTATTR_CAP & caps) {
 				if (pSMBFile == NULL)
 				if (pSMBFile == NULL)
 					break;
 					break;
 				rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,
 				rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,
 					&ExtAttrBits, &ExtAttrMask);
 					&ExtAttrBits, &ExtAttrMask);
-				if(rc == 0)
+				if (rc == 0)
 					rc = put_user(ExtAttrBits &
 					rc = put_user(ExtAttrBits &
 						FS_FL_USER_VISIBLE,
 						FS_FL_USER_VISIBLE,
 						(int __user *)arg);
 						(int __user *)arg);
@@ -87,8 +87,8 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
 			break;
 			break;
 
 
 		case FS_IOC_SETFLAGS:
 		case FS_IOC_SETFLAGS:
-			if(CIFS_UNIX_EXTATTR_CAP & caps) {
-				if(get_user(ExtAttrBits,(int __user *)arg)) {
+			if (CIFS_UNIX_EXTATTR_CAP & caps) {
+				if (get_user(ExtAttrBits, (int __user *)arg)) {
 					rc = -EFAULT;
 					rc = -EFAULT;
 					break;
 					break;
 				}
 				}
@@ -96,16 +96,15 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
 					break;
 					break;
 				/* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,
 				/* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,
 					extAttrBits, &ExtAttrMask);*/
 					extAttrBits, &ExtAttrMask);*/
-				
 			}
 			}
-			cFYI(1,("set flags not implemented yet"));
+			cFYI(1, ("set flags not implemented yet"));
 			break;
 			break;
 #endif /* CONFIG_CIFS_POSIX */
 #endif /* CONFIG_CIFS_POSIX */
 		default:
 		default:
-			cFYI(1,("unsupported ioctl"));
+			cFYI(1, ("unsupported ioctl"));
 			break;
 			break;
 	}
 	}
 
 
 	FreeXid(xid);
 	FreeXid(xid);
 	return rc;
 	return rc;
-} 
+}

+ 1 - 1
fs/cifs/rfc1002pdu.h

@@ -18,7 +18,7 @@
  *
  *
  *   You should have received a copy of the GNU Lesser General Public License
  *   You should have received a copy of the GNU Lesser General Public License
  *   along with this library; if not, write to the Free Software
  *   along with this library; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
  */
 
 
 /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */
 /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */

+ 35 - 35
fs/splice.c

@@ -272,7 +272,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
 	struct page *page;
 	struct page *page;
 	pgoff_t index, end_index;
 	pgoff_t index, end_index;
 	loff_t isize;
 	loff_t isize;
-	size_t total_len;
 	int error, page_nr;
 	int error, page_nr;
 	struct splice_pipe_desc spd = {
 	struct splice_pipe_desc spd = {
 		.pages = pages,
 		.pages = pages,
@@ -298,7 +297,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
 	 * Now fill in the holes:
 	 * Now fill in the holes:
 	 */
 	 */
 	error = 0;
 	error = 0;
-	total_len = 0;
 
 
 	/*
 	/*
 	 * Lookup the (hopefully) full range of pages we need.
 	 * Lookup the (hopefully) full range of pages we need.
@@ -415,43 +413,47 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
 
 
 				break;
 				break;
 			}
 			}
+		}
+fill_it:
+		/*
+		 * i_size must be checked after PageUptodate.
+		 */
+		isize = i_size_read(mapping->host);
+		end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
+		if (unlikely(!isize || index > end_index))
+			break;
+
+		/*
+		 * if this is the last page, see if we need to shrink
+		 * the length and stop
+		 */
+		if (end_index == index) {
+			unsigned int plen;
 
 
 			/*
 			/*
-			 * i_size must be checked after ->readpage().
+			 * max good bytes in this page
 			 */
 			 */
-			isize = i_size_read(mapping->host);
-			end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
-			if (unlikely(!isize || index > end_index))
+			plen = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
+			if (plen <= loff)
 				break;
 				break;
 
 
 			/*
 			/*
-			 * if this is the last page, see if we need to shrink
-			 * the length and stop
+			 * force quit after adding this page
 			 */
 			 */
-			if (end_index == index) {
-				loff = PAGE_CACHE_SIZE - (isize & ~PAGE_CACHE_MASK);
-				if (total_len + loff > isize)
-					break;
-				/*
-				 * force quit after adding this page
-				 */
-				len = this_len;
-				this_len = min(this_len, loff);
-				loff = 0;
-			}
+			this_len = min(this_len, plen - loff);
+			len = this_len;
 		}
 		}
-fill_it:
+
 		partial[page_nr].offset = loff;
 		partial[page_nr].offset = loff;
 		partial[page_nr].len = this_len;
 		partial[page_nr].len = this_len;
 		len -= this_len;
 		len -= this_len;
-		total_len += this_len;
 		loff = 0;
 		loff = 0;
 		spd.nr_pages++;
 		spd.nr_pages++;
 		index++;
 		index++;
 	}
 	}
 
 
 	/*
 	/*
-	 * Release any pages at the end, if we quit early. 'i' is how far
+	 * Release any pages at the end, if we quit early. 'page_nr' is how far
 	 * we got, 'nr_pages' is how many pages are in the map.
 	 * we got, 'nr_pages' is how many pages are in the map.
 	 */
 	 */
 	while (page_nr < nr_pages)
 	while (page_nr < nr_pages)
@@ -478,10 +480,18 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
 {
 {
 	ssize_t spliced;
 	ssize_t spliced;
 	int ret;
 	int ret;
+	loff_t isize, left;
+
+	isize = i_size_read(in->f_mapping->host);
+	if (unlikely(*ppos >= isize))
+		return 0;
+
+	left = isize - *ppos;
+	if (unlikely(left < len))
+		len = left;
 
 
 	ret = 0;
 	ret = 0;
 	spliced = 0;
 	spliced = 0;
-
 	while (len) {
 	while (len) {
 		ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
 		ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
 
 
@@ -644,7 +654,6 @@ find_page:
 	 * accessed, we are now done!
 	 * accessed, we are now done!
 	 */
 	 */
 	mark_page_accessed(page);
 	mark_page_accessed(page);
-	balance_dirty_pages_ratelimited(mapping);
 out:
 out:
 	page_cache_release(page);
 	page_cache_release(page);
 	unlock_page(page);
 	unlock_page(page);
@@ -815,6 +824,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
 			if (err)
 			if (err)
 				ret = err;
 				ret = err;
 		}
 		}
+		balance_dirty_pages_ratelimited(mapping);
 	}
 	}
 
 
 	return ret;
 	return ret;
@@ -868,6 +878,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 			if (err)
 			if (err)
 				ret = err;
 				ret = err;
 		}
 		}
+		balance_dirty_pages_ratelimited(mapping);
 	}
 	}
 
 
 	return ret;
 	return ret;
@@ -922,7 +933,6 @@ static long do_splice_to(struct file *in, loff_t *ppos,
 			 struct pipe_inode_info *pipe, size_t len,
 			 struct pipe_inode_info *pipe, size_t len,
 			 unsigned int flags)
 			 unsigned int flags)
 {
 {
-	loff_t isize, left;
 	int ret;
 	int ret;
 
 
 	if (unlikely(!in->f_op || !in->f_op->splice_read))
 	if (unlikely(!in->f_op || !in->f_op->splice_read))
@@ -935,14 +945,6 @@ static long do_splice_to(struct file *in, loff_t *ppos,
 	if (unlikely(ret < 0))
 	if (unlikely(ret < 0))
 		return ret;
 		return ret;
 
 
-	isize = i_size_read(in->f_mapping->host);
-	if (unlikely(*ppos >= isize))
-		return 0;
-	
-	left = isize - *ppos;
-	if (unlikely(left < len))
-		len = left;
-
 	return in->f_op->splice_read(in, ppos, pipe, len, flags);
 	return in->f_op->splice_read(in, ppos, pipe, len, flags);
 }
 }
 
 
@@ -1058,8 +1060,6 @@ out_release:
 	return ret;
 	return ret;
 }
 }
 
 
-EXPORT_SYMBOL(do_splice_direct);
-
 /*
 /*
  * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
  * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
  * location, so checking ->i_pipe is not enough to verify that this is a
  * location, so checking ->i_pipe is not enough to verify that this is a

+ 19 - 32
include/asm-mips/bitops.h

@@ -238,10 +238,11 @@ static inline int test_and_set_bit(unsigned long nr,
 	volatile unsigned long *addr)
 	volatile unsigned long *addr)
 {
 {
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned short bit = nr & SZLONG_MASK;
+	unsigned long res;
 
 
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-		unsigned long temp, res;
+		unsigned long temp;
 
 
 		__asm__ __volatile__(
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"	.set	mips3					\n"
@@ -254,11 +255,9 @@ static inline int test_and_set_bit(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << bit), "m" (*m)
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
 		: "memory");
-
-		return res != 0;
 	} else if (cpu_has_llsc) {
 	} else if (cpu_has_llsc) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-		unsigned long temp, res;
+		unsigned long temp;
 
 
 		__asm__ __volatile__(
 		__asm__ __volatile__(
 		"	.set	push					\n"
 		"	.set	push					\n"
@@ -277,25 +276,22 @@ static inline int test_and_set_bit(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << bit), "m" (*m)
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
 		: "memory");
-
-		return res != 0;
 	} else {
 	} else {
 		volatile unsigned long *a = addr;
 		volatile unsigned long *a = addr;
 		unsigned long mask;
 		unsigned long mask;
-		int retval;
 		unsigned long flags;
 		unsigned long flags;
 
 
 		a += nr >> SZLONG_LOG;
 		a += nr >> SZLONG_LOG;
 		mask = 1UL << bit;
 		mask = 1UL << bit;
 		raw_local_irq_save(flags);
 		raw_local_irq_save(flags);
-		retval = (mask & *a) != 0;
+		res = (mask & *a);
 		*a |= mask;
 		*a |= mask;
 		raw_local_irq_restore(flags);
 		raw_local_irq_restore(flags);
-
-		return retval;
 	}
 	}
 
 
 	smp_mb();
 	smp_mb();
+
+	return res != 0;
 }
 }
 
 
 /*
 /*
@@ -310,6 +306,7 @@ static inline int test_and_clear_bit(unsigned long nr,
 	volatile unsigned long *addr)
 	volatile unsigned long *addr)
 {
 {
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned short bit = nr & SZLONG_MASK;
+	unsigned long res;
 
 
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
@@ -327,12 +324,10 @@ static inline int test_and_clear_bit(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << bit), "m" (*m)
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
 		: "memory");
-
-		return res != 0;
 #ifdef CONFIG_CPU_MIPSR2
 #ifdef CONFIG_CPU_MIPSR2
 	} else if (__builtin_constant_p(nr)) {
 	} else if (__builtin_constant_p(nr)) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-		unsigned long temp, res;
+		unsigned long temp;
 
 
 		__asm__ __volatile__(
 		__asm__ __volatile__(
 		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
 		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
@@ -346,12 +341,10 @@ static inline int test_and_clear_bit(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "ri" (bit), "m" (*m)
 		: "ri" (bit), "m" (*m)
 		: "memory");
 		: "memory");
-
-		return res;
 #endif
 #endif
 	} else if (cpu_has_llsc) {
 	} else if (cpu_has_llsc) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-		unsigned long temp, res;
+		unsigned long temp;
 
 
 		__asm__ __volatile__(
 		__asm__ __volatile__(
 		"	.set	push					\n"
 		"	.set	push					\n"
@@ -371,25 +364,22 @@ static inline int test_and_clear_bit(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << bit), "m" (*m)
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
 		: "memory");
-
-		return res != 0;
 	} else {
 	} else {
 		volatile unsigned long *a = addr;
 		volatile unsigned long *a = addr;
 		unsigned long mask;
 		unsigned long mask;
-		int retval;
 		unsigned long flags;
 		unsigned long flags;
 
 
 		a += nr >> SZLONG_LOG;
 		a += nr >> SZLONG_LOG;
 		mask = 1UL << bit;
 		mask = 1UL << bit;
 		raw_local_irq_save(flags);
 		raw_local_irq_save(flags);
-		retval = (mask & *a) != 0;
+		res = (mask & *a);
 		*a &= ~mask;
 		*a &= ~mask;
 		raw_local_irq_restore(flags);
 		raw_local_irq_restore(flags);
-
-		return retval;
 	}
 	}
 
 
 	smp_mb();
 	smp_mb();
+
+	return res != 0;
 }
 }
 
 
 /*
 /*
@@ -404,10 +394,11 @@ static inline int test_and_change_bit(unsigned long nr,
 	volatile unsigned long *addr)
 	volatile unsigned long *addr)
 {
 {
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned short bit = nr & SZLONG_MASK;
+	unsigned long res;
 
 
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-		unsigned long temp, res;
+		unsigned long temp;
 
 
 		__asm__ __volatile__(
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"	.set	mips3					\n"
@@ -420,11 +411,9 @@ static inline int test_and_change_bit(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << bit), "m" (*m)
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
 		: "memory");
-
-		return res != 0;
 	} else if (cpu_has_llsc) {
 	} else if (cpu_has_llsc) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
-		unsigned long temp, res;
+		unsigned long temp;
 
 
 		__asm__ __volatile__(
 		__asm__ __volatile__(
 		"	.set	push					\n"
 		"	.set	push					\n"
@@ -443,24 +432,22 @@ static inline int test_and_change_bit(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << bit), "m" (*m)
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
 		: "memory");
-
-		return res != 0;
 	} else {
 	} else {
 		volatile unsigned long *a = addr;
 		volatile unsigned long *a = addr;
-		unsigned long mask, retval;
+		unsigned long mask;
 		unsigned long flags;
 		unsigned long flags;
 
 
 		a += nr >> SZLONG_LOG;
 		a += nr >> SZLONG_LOG;
 		mask = 1UL << bit;
 		mask = 1UL << bit;
 		raw_local_irq_save(flags);
 		raw_local_irq_save(flags);
-		retval = (mask & *a) != 0;
+		res = (mask & *a);
 		*a ^= mask;
 		*a ^= mask;
 		raw_local_irq_restore(flags);
 		raw_local_irq_restore(flags);
-
-		return retval;
 	}
 	}
 
 
 	smp_mb();
 	smp_mb();
+
+	return res != 0;
 }
 }
 
 
 #include <asm-generic/bitops/non-atomic.h>
 #include <asm-generic/bitops/non-atomic.h>

+ 28 - 24
include/asm-mips/stackframe.h

@@ -17,6 +17,18 @@
 #include <asm/mipsregs.h>
 #include <asm/mipsregs.h>
 #include <asm/asm-offsets.h>
 #include <asm/asm-offsets.h>
 
 
+/*
+ * For SMTC kernel, global IE should be left set, and interrupts
+ * controlled exclusively via IXMT.
+ */
+#ifdef CONFIG_MIPS_MT_SMTC
+#define STATMASK 0x1e
+#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#define STATMASK 0x3f
+#else
+#define STATMASK 0x1f
+#endif
+
 #ifdef CONFIG_MIPS_MT_SMTC
 #ifdef CONFIG_MIPS_MT_SMTC
 #include <asm/mipsmtregs.h>
 #include <asm/mipsmtregs.h>
 #endif /* CONFIG_MIPS_MT_SMTC */
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -236,10 +248,10 @@
 		.set	reorder
 		.set	reorder
 		.set	noat
 		.set	noat
 		mfc0	a0, CP0_STATUS
 		mfc0	a0, CP0_STATUS
-		ori	a0, 0x1f
-		xori	a0, 0x1f
-		mtc0	a0, CP0_STATUS
 		li	v1, 0xff00
 		li	v1, 0xff00
+		ori	a0, STATMASK
+		xori	a0, STATMASK
+		mtc0	a0, CP0_STATUS
 		and	a0, v1
 		and	a0, v1
 		LONG_L	v0, PT_STATUS(sp)
 		LONG_L	v0, PT_STATUS(sp)
 		nor	v1, $0, v1
 		nor	v1, $0, v1
@@ -249,10 +261,6 @@
 		LONG_L	$31, PT_R31(sp)
 		LONG_L	$31, PT_R31(sp)
 		LONG_L	$28, PT_R28(sp)
 		LONG_L	$28, PT_R28(sp)
 		LONG_L	$25, PT_R25(sp)
 		LONG_L	$25, PT_R25(sp)
-#ifdef CONFIG_64BIT
-		LONG_L	$8, PT_R8(sp)
-		LONG_L	$9, PT_R9(sp)
-#endif
 		LONG_L	$7,  PT_R7(sp)
 		LONG_L	$7,  PT_R7(sp)
 		LONG_L	$6,  PT_R6(sp)
 		LONG_L	$6,  PT_R6(sp)
 		LONG_L	$5,  PT_R5(sp)
 		LONG_L	$5,  PT_R5(sp)
@@ -273,16 +281,6 @@
 		.endm
 		.endm
 
 
 #else
 #else
-/*
- * For SMTC kernel, global IE should be left set, and interrupts
- * controlled exclusively via IXMT.
- */
-
-#ifdef CONFIG_MIPS_MT_SMTC
-#define STATMASK 0x1e
-#else
-#define STATMASK 0x1f
-#endif
 		.macro	RESTORE_SOME
 		.macro	RESTORE_SOME
 		.set	push
 		.set	push
 		.set	reorder
 		.set	reorder
@@ -385,9 +383,9 @@
 		.macro	CLI
 		.macro	CLI
 #if !defined(CONFIG_MIPS_MT_SMTC)
 #if !defined(CONFIG_MIPS_MT_SMTC)
 		mfc0	t0, CP0_STATUS
 		mfc0	t0, CP0_STATUS
-		li	t1, ST0_CU0 | 0x1f
+		li	t1, ST0_CU0 | STATMASK
 		or	t0, t1
 		or	t0, t1
-		xori	t0, 0x1f
+		xori	t0, STATMASK
 		mtc0	t0, CP0_STATUS
 		mtc0	t0, CP0_STATUS
 #else /* CONFIG_MIPS_MT_SMTC */
 #else /* CONFIG_MIPS_MT_SMTC */
 		/*
 		/*
@@ -420,9 +418,9 @@
 		.macro	STI
 		.macro	STI
 #if !defined(CONFIG_MIPS_MT_SMTC)
 #if !defined(CONFIG_MIPS_MT_SMTC)
 		mfc0	t0, CP0_STATUS
 		mfc0	t0, CP0_STATUS
-		li	t1, ST0_CU0 | 0x1f
+		li	t1, ST0_CU0 | STATMASK
 		or	t0, t1
 		or	t0, t1
-		xori	t0, 0x1e
+		xori	t0, STATMASK & ~1
 		mtc0	t0, CP0_STATUS
 		mtc0	t0, CP0_STATUS
 #else /* CONFIG_MIPS_MT_SMTC */
 #else /* CONFIG_MIPS_MT_SMTC */
 		/*
 		/*
@@ -451,7 +449,8 @@
 		.endm
 		.endm
 
 
 /*
 /*
- * Just move to kernel mode and leave interrupts as they are.
+ * Just move to kernel mode and leave interrupts as they are.  Note
+ * for the R3000 this means copying the previous enable from IEp.
  * Set cp0 enable bit as sign that we're running on the kernel stack
  * Set cp0 enable bit as sign that we're running on the kernel stack
  */
  */
 		.macro	KMODE
 		.macro	KMODE
@@ -482,9 +481,14 @@
 		move	ra, t0
 		move	ra, t0
 #endif /* CONFIG_MIPS_MT_SMTC */
 #endif /* CONFIG_MIPS_MT_SMTC */
 		mfc0	t0, CP0_STATUS
 		mfc0	t0, CP0_STATUS
-		li	t1, ST0_CU0 | 0x1e
+		li	t1, ST0_CU0 | (STATMASK & ~1)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+		andi	t2, t0, ST0_IEP
+		srl	t2, 2
+		or	t0, t2
+#endif
 		or	t0, t1
 		or	t0, t1
-		xori	t0, 0x1e
+		xori	t0, STATMASK & ~1
 		mtc0	t0, CP0_STATUS
 		mtc0	t0, CP0_STATUS
 #ifdef CONFIG_MIPS_MT_SMTC
 #ifdef CONFIG_MIPS_MT_SMTC
 		_ehb
 		_ehb

+ 18 - 6
include/asm-mips/unistd.h

@@ -336,16 +336,20 @@
 #define __NR_epoll_pwait		(__NR_Linux + 313)
 #define __NR_epoll_pwait		(__NR_Linux + 313)
 #define __NR_ioprio_set			(__NR_Linux + 314)
 #define __NR_ioprio_set			(__NR_Linux + 314)
 #define __NR_ioprio_get			(__NR_Linux + 315)
 #define __NR_ioprio_get			(__NR_Linux + 315)
+#define __NR_utimensat			(__NR_Linux + 316)
+#define __NR_signalfd			(__NR_Linux + 317)
+#define __NR_timerfd			(__NR_Linux + 318)
+#define __NR_eventfd			(__NR_Linux + 319)
 
 
 /*
 /*
  * Offset of the last Linux o32 flavoured syscall
  * Offset of the last Linux o32 flavoured syscall
  */
  */
-#define __NR_Linux_syscalls		315
+#define __NR_Linux_syscalls		319
 
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 
 #define __NR_O32_Linux			4000
 #define __NR_O32_Linux			4000
-#define __NR_O32_Linux_syscalls		315
+#define __NR_O32_Linux_syscalls		319
 
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
 
@@ -628,16 +632,20 @@
 #define __NR_epoll_pwait		(__NR_Linux + 272)
 #define __NR_epoll_pwait		(__NR_Linux + 272)
 #define __NR_ioprio_set			(__NR_Linux + 273)
 #define __NR_ioprio_set			(__NR_Linux + 273)
 #define __NR_ioprio_get			(__NR_Linux + 274)
 #define __NR_ioprio_get			(__NR_Linux + 274)
+#define __NR_utimensat			(__NR_Linux + 275)
+#define __NR_signalfd			(__NR_Linux + 276)
+#define __NR_timerfd			(__NR_Linux + 277)
+#define __NR_eventfd			(__NR_Linux + 278)
 
 
 /*
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  * Offset of the last Linux 64-bit flavoured syscall
  */
  */
-#define __NR_Linux_syscalls		274
+#define __NR_Linux_syscalls		278
 
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 
 #define __NR_64_Linux			5000
 #define __NR_64_Linux			5000
-#define __NR_64_Linux_syscalls		274
+#define __NR_64_Linux_syscalls		278
 
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
 
@@ -924,16 +932,20 @@
 #define __NR_epoll_pwait		(__NR_Linux + 276)
 #define __NR_epoll_pwait		(__NR_Linux + 276)
 #define __NR_ioprio_set			(__NR_Linux + 277)
 #define __NR_ioprio_set			(__NR_Linux + 277)
 #define __NR_ioprio_get			(__NR_Linux + 278)
 #define __NR_ioprio_get			(__NR_Linux + 278)
+#define __NR_utimensat			(__NR_Linux + 279)
+#define __NR_signalfd			(__NR_Linux + 280)
+#define __NR_timerfd			(__NR_Linux + 281)
+#define __NR_eventfd			(__NR_Linux + 282)
 
 
 /*
 /*
  * Offset of the last N32 flavoured syscall
  * Offset of the last N32 flavoured syscall
  */
  */
-#define __NR_Linux_syscalls		278
+#define __NR_Linux_syscalls		282
 
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 
 #define __NR_N32_Linux			6000
 #define __NR_N32_Linux			6000
-#define __NR_N32_Linux_syscalls		278
+#define __NR_N32_Linux_syscalls		282
 
 
 #ifdef __KERNEL__
 #ifdef __KERNEL__
 
 

+ 2 - 1
include/linux/ata.h

@@ -151,6 +151,7 @@ enum {
 	ATA_CMD_WRITE_MULTI_EXT	= 0x39,
 	ATA_CMD_WRITE_MULTI_EXT	= 0x39,
 	ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE,
 	ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE,
 	ATA_CMD_SET_FEATURES	= 0xEF,
 	ATA_CMD_SET_FEATURES	= 0xEF,
+	ATA_CMD_SET_MULTI	= 0xC6,
 	ATA_CMD_PACKET		= 0xA0,
 	ATA_CMD_PACKET		= 0xA0,
 	ATA_CMD_VERIFY		= 0x40,
 	ATA_CMD_VERIFY		= 0x40,
 	ATA_CMD_VERIFY_EXT	= 0x42,
 	ATA_CMD_VERIFY_EXT	= 0x42,
@@ -249,7 +250,7 @@ enum ata_tf_protocols {
 	/* ATA taskfile protocols */
 	/* ATA taskfile protocols */
 	ATA_PROT_UNKNOWN,	/* unknown/invalid */
 	ATA_PROT_UNKNOWN,	/* unknown/invalid */
 	ATA_PROT_NODATA,	/* no data */
 	ATA_PROT_NODATA,	/* no data */
-	ATA_PROT_PIO,		/* PIO single sector */
+	ATA_PROT_PIO,		/* PIO data xfer */
 	ATA_PROT_DMA,		/* DMA */
 	ATA_PROT_DMA,		/* DMA */
 	ATA_PROT_NCQ,		/* NCQ */
 	ATA_PROT_NCQ,		/* NCQ */
 	ATA_PROT_ATAPI,		/* packet command, PIO data xfer*/
 	ATA_PROT_ATAPI,		/* packet command, PIO data xfer*/

+ 1 - 0
include/linux/ide.h

@@ -1001,6 +1001,7 @@ struct ide_driver_s {
 	struct device_driver	gen_driver;
 	struct device_driver	gen_driver;
 	int		(*probe)(ide_drive_t *);
 	int		(*probe)(ide_drive_t *);
 	void		(*remove)(ide_drive_t *);
 	void		(*remove)(ide_drive_t *);
+	void		(*resume)(ide_drive_t *);
 	void		(*shutdown)(ide_drive_t *);
 	void		(*shutdown)(ide_drive_t *);
 #ifdef CONFIG_IDE_PROC_FS
 #ifdef CONFIG_IDE_PROC_FS
 	ide_proc_entry_t	*proc;
 	ide_proc_entry_t	*proc;

+ 1 - 0
include/linux/libata.h

@@ -753,6 +753,7 @@ extern u8 ata_check_status(struct ata_port *ap);
 extern u8 ata_altstatus(struct ata_port *ap);
 extern u8 ata_altstatus(struct ata_port *ap);
 extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
 extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
 extern int ata_port_start (struct ata_port *ap);
 extern int ata_port_start (struct ata_port *ap);
+extern int ata_sff_port_start (struct ata_port *ap);
 extern irqreturn_t ata_interrupt (int irq, void *dev_instance);
 extern irqreturn_t ata_interrupt (int irq, void *dev_instance);
 extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
 extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
 			  unsigned int buflen, int write_data);
 			  unsigned int buflen, int write_data);

+ 2 - 0
include/linux/pci_ids.h

@@ -1233,6 +1233,8 @@
 #define PCI_DEVICE_ID_NVIDIA_NVENET_26              0x054E
 #define PCI_DEVICE_ID_NVIDIA_NVENET_26              0x054E
 #define PCI_DEVICE_ID_NVIDIA_NVENET_27              0x054F
 #define PCI_DEVICE_ID_NVIDIA_NVENET_27              0x054F
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE       0x0560
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE       0x0560
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE       0x056C
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE       0x0759
 
 
 #define PCI_VENDOR_ID_IMS		0x10e0
 #define PCI_VENDOR_ID_IMS		0x10e0
 #define PCI_DEVICE_ID_IMS_TT128		0x9128
 #define PCI_DEVICE_ID_IMS_TT128		0x9128

+ 15 - 15
include/linux/pipe_fs_i.h

@@ -16,6 +16,21 @@ struct pipe_buffer {
 	unsigned int flags;
 	unsigned int flags;
 };
 };
 
 
+struct pipe_inode_info {
+	wait_queue_head_t wait;
+	unsigned int nrbufs, curbuf;
+	struct page *tmp_page;
+	unsigned int readers;
+	unsigned int writers;
+	unsigned int waiting_writers;
+	unsigned int r_counter;
+	unsigned int w_counter;
+	struct fasync_struct *fasync_readers;
+	struct fasync_struct *fasync_writers;
+	struct inode *inode;
+	struct pipe_buffer bufs[PIPE_BUFFERS];
+};
+
 /*
 /*
  * Note on the nesting of these functions:
  * Note on the nesting of these functions:
  *
  *
@@ -38,21 +53,6 @@ struct pipe_buf_operations {
 	void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
 	void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
 };
 };
 
 
-struct pipe_inode_info {
-	wait_queue_head_t wait;
-	unsigned int nrbufs, curbuf;
-	struct page *tmp_page;
-	unsigned int readers;
-	unsigned int writers;
-	unsigned int waiting_writers;
-	unsigned int r_counter;
-	unsigned int w_counter;
-	struct fasync_struct *fasync_readers;
-	struct fasync_struct *fasync_writers;
-	struct inode *inode;
-	struct pipe_buffer bufs[PIPE_BUFFERS];
-};
-
 /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
 /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
    memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
    memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
 #define PIPE_SIZE		PAGE_SIZE
 #define PIPE_SIZE		PAGE_SIZE

+ 5 - 2
include/linux/videodev2.h

@@ -243,8 +243,7 @@ struct v4l2_capability
 #define V4L2_CAP_SLICED_VBI_CAPTURE	0x00000040  /* Is a sliced VBI capture device */
 #define V4L2_CAP_SLICED_VBI_CAPTURE	0x00000040  /* Is a sliced VBI capture device */
 #define V4L2_CAP_SLICED_VBI_OUTPUT	0x00000080  /* Is a sliced VBI output device */
 #define V4L2_CAP_SLICED_VBI_OUTPUT	0x00000080  /* Is a sliced VBI output device */
 #define V4L2_CAP_RDS_CAPTURE		0x00000100  /* RDS data capture */
 #define V4L2_CAP_RDS_CAPTURE		0x00000100  /* RDS data capture */
-#define V4L2_CAP_VIDEO_OUTPUT_POS       0x00000200  /* Video output can have x,y coords */
-#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY	0x00000400  /* Can do video output overlay */
+#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY	0x00000200  /* Can do video output overlay */
 
 
 #define V4L2_CAP_TUNER			0x00010000  /* has a tuner */
 #define V4L2_CAP_TUNER			0x00010000  /* has a tuner */
 #define V4L2_CAP_AUDIO			0x00020000  /* has audio support */
 #define V4L2_CAP_AUDIO			0x00020000  /* has audio support */
@@ -616,12 +615,16 @@ struct v4l2_framebuffer
 #define V4L2_FBUF_CAP_BITMAP_CLIPPING	0x0008
 #define V4L2_FBUF_CAP_BITMAP_CLIPPING	0x0008
 #define V4L2_FBUF_CAP_LOCAL_ALPHA	0x0010
 #define V4L2_FBUF_CAP_LOCAL_ALPHA	0x0010
 #define V4L2_FBUF_CAP_GLOBAL_ALPHA	0x0020
 #define V4L2_FBUF_CAP_GLOBAL_ALPHA	0x0020
+#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA	0x0040
+#define V4L2_FBUF_CAP_GLOBAL_INV_ALPHA	0x0080
 /*  Flags for the 'flags' field. */
 /*  Flags for the 'flags' field. */
 #define V4L2_FBUF_FLAG_PRIMARY		0x0001
 #define V4L2_FBUF_FLAG_PRIMARY		0x0001
 #define V4L2_FBUF_FLAG_OVERLAY		0x0002
 #define V4L2_FBUF_FLAG_OVERLAY		0x0002
 #define V4L2_FBUF_FLAG_CHROMAKEY	0x0004
 #define V4L2_FBUF_FLAG_CHROMAKEY	0x0004
 #define V4L2_FBUF_FLAG_LOCAL_ALPHA	0x0008
 #define V4L2_FBUF_FLAG_LOCAL_ALPHA	0x0008
 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA	0x0010
 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA	0x0010
+#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA	0x0020
+#define V4L2_FBUF_FLAG_GLOBAL_INV_ALPHA	0x0040
 
 
 struct v4l2_clip
 struct v4l2_clip
 {
 {