Kaynağa Gözat

Merge branch 'master' into upstream-fixes

Jeff Garzik 18 yıl önce
ebeveyn
işleme
b232923966
78 değiştirilmiş dosya ile 1416 ekleme ve 1039 silme
  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_epoll_pwait		6
 	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
 
 	/* 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_ioprio_set
 	PTR	sys_ioprio_get
+	PTR	sys_utimensat			/* 5275 */
+	PTR	sys_signalfd
+	PTR	sys_timerfd
+	PTR	sys_eventfd
 	.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	sys_ioprio_set
 	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

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

@@ -521,4 +521,8 @@ sys_call_table:
 	PTR	compat_sys_epoll_pwait
 	PTR	sys_ioprio_set
 	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

+ 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
  * the master.
  */
-asmlinkage void start_secondary(void)
+asmlinkage __cpuinit void start_secondary(void)
 {
 	unsigned int cpu;
 

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

@@ -121,10 +121,7 @@ LEAF(self_ipi)
 	subu	t1,sp,PT_SIZE
 	sw	ra,PT_EPC(t1)
 	sw	a0,PT_PADSLOT4(t1)
-	LONG_L	s0, TI_REGS($28)
-	LONG_S	sp, TI_REGS($28)
 	la	t2,ipi_decode
-	LONG_S	s0, TI_REGS($28)
 	sw	t2,PT_PADSLOT5(t1)
 	/* Save pre-disable value of TCStatus */
 	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,
 			unsigned long hwmask)
 {
+#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
 	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;
 #endif
+	irq_hwmask[irq] = hwmask;
 
 	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) 2002, 2003, 2004, 2005  Maciej W. Rozycki
  */
+#include <linux/bug.h>
 #include <linux/init.h>
 #include <linux/mm.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);
 #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 = (*w & 0xffff0000) | (0x100 << n);
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -1383,6 +1384,13 @@ void __init per_cpu_trap_init(void)
 		cpu_cache_init();
 		tlb_init();
 #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 */
 }
@@ -1531,8 +1539,7 @@ void __init trap_init(void)
 	if (cpu_has_mipsmt)
 		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)
 		/* 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_EMUL_MSC:
 		if (cpu_has_veic)
-			init_msc_irqs (MSC01E_INT_BASE,
+			init_msc_irqs (MSC01E_INT_BASE, MSC01E_INT_BASE,
 				       msc_eicirqmap, msc_nr_eicirqs);
 		else
-			init_msc_irqs (MSC01C_INT_BASE,
+			init_msc_irqs (MSC01E_INT_BASE, MSC01C_INT_BASE,
 				       msc_irqmap, msc_nr_irqs);
 	}
 
-
 	if (cpu_has_veic) {
 		set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch);
 		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.
 	 */
 
-	int vpflags;
-
 	/*
 	 * We could be here due to timer interrupt,
 	 * perf counter overflow, or both.
@@ -98,15 +96,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id)
 		perf_irq();
 
 	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
 		 * 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().
 		 */
 		if (cpu_data[cpu].vpe_id == 0) {
-				timer_interrupt(irq, NULL);
-				smtc_timer_broadcast(cpu_data[cpu].vpe_id);
+			timer_interrupt(irq, NULL);
 		} else {
 			write_c0_compare(read_c0_count() +
 			                 (mips_hpt_frequency/HZ));
 			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 */
 	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 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),
 				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, 0x055a), 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 */
 	{ 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 */
 	rc = -EINVAL;
-	reason = "device reports illegal type";
+	reason = "device reports invalid type";
 
 	if (class == ATA_DEV_ATA) {
 		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))
 		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 */
 	if (dev->class == ATA_DEV_ATA) {
 		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);
 
-		/* 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)
 			dev->multi_count = dev->id[59] & 0xff;
 
@@ -2009,7 +2009,9 @@ int ata_dev_configure(struct ata_device *dev)
 
 		/* print device info to dmesg */
 		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),
 				       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);
-		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);
 		if (rc) {
 			if (rc != -ENODEV)
@@ -3769,6 +3777,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 	{ "_NEC DV5800A", 	NULL,		ATA_HORKAGE_NODMA },
 	{ "SAMSUNG CD-ROM SN-124","N001",	ATA_HORKAGE_NODMA },
 	{ "Seagate STT20000A", NULL,		ATA_HORKAGE_NODMA },
+	{ "IOMEGA  ZIP 250       ATAPI", NULL,	ATA_HORKAGE_NODMA }, /* temporary fix */
 
 	/* Weird ATAPI devices */
 	{ "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, },
 	{ "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
 	{ "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
+	/* Drives which do spurious command completion */
+	{ "HTS541680J9SA00",	"SB2IC7EP",	ATA_HORKAGE_NONCQ, },
 
 	/* 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 */
 		if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
 			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;
 
@@ -6433,6 +6445,9 @@ int ata_host_activate(struct ata_host *host, int irq,
 	if (rc)
 		devm_free_irq(host->dev, irq, host);
 
+	/* Used to print device info at probe */
+	host->irq = irq;
+
 	return rc;
 }
 
@@ -6818,6 +6833,7 @@ EXPORT_SYMBOL_GPL(ata_check_status);
 EXPORT_SYMBOL_GPL(ata_altstatus);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
+EXPORT_SYMBOL_GPL(ata_sff_port_start);
 EXPORT_SYMBOL_GPL(ata_interrupt);
 EXPORT_SYMBOL_GPL(ata_do_set_mode);
 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
 	 * 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
@@ -2506,22 +2516,21 @@ ata_scsi_map_proto(u8 byte1)
 			return ATA_PROT_NODATA;
 
 		case 6:		/* DMA */
+		case 10:	/* UDMA Data-in */
+		case 11:	/* UDMA Data-Out */
 			return ATA_PROT_DMA;
 
 		case 4:		/* PIO Data-in */
 		case 5:		/* PIO Data-out */
 			return ATA_PROT_PIO;
 
-		case 10:	/* Device Reset */
 		case 0:		/* Hard Reset */
 		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 */
 			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)
 		goto invalid_fld;
 
-	if (cdb[1] & 0xe0)
-		/* PIO multi not supported yet */
-		goto invalid_fld;
-
 	/*
 	 * 12 and 16 byte CDBs use different offsets to
 	 * 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->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 */
 	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)
 {
 	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);
 	if (status & bits)
 		if (ata_msg_err(ap))
 			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))
 		printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
 			__FUNCTION__,
 			host_stat, post_stat, status);
-
 	return status;
 }
 
@@ -516,6 +516,27 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *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
 
 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_port *ap;
 	void __iomem *cmd_addr, *ctl_addr;
-	int rc;
 
 	if (pnp_port_valid(idev, 0) == 0)
 		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_64M		0x1
 #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_LOCAL		0x10
 #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_256KB	(1 << 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_ROW_0		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_82965GM_HB      0x2A00
 #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 || \
                  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_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;
 
@@ -53,6 +64,8 @@ extern int agp_memory_reserved;
 #define I915_PTEADDR	0x1C
 #define I915_GMCH_GMS_STOLEN_48M	(0x6 << 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 */
 #define I965_MSAC 0x62
@@ -86,11 +99,18 @@ static struct gatt_mask intel_i810_masks[] =
 	 .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;
-} 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)
 {
@@ -127,32 +147,32 @@ static int intel_i810_configure(void)
 
 	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;
 
-		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");
 			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) {
 		/* This will need to be dynamically assigned */
 		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);
-	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) {
 		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();
@@ -161,9 +181,9 @@ static int intel_i810_configure(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)
@@ -261,9 +281,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
 			global_cache_flush();
 		for (i = pg_start; i < (pg_start + mem->page_count); i++) {
 			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;
 	case AGP_PHYS_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,
 							       mem->memory[i],
 							       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;
 	default:
 		goto out_err;
@@ -298,9 +318,9 @@ static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
 		return 0;
 
 	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);
 	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;
 
 	if (type == AGP_DCACHE_MEMORY) {
-		if (pg_count != intel_i810_private.num_dcache_entries)
+		if (pg_count != intel_private.num_dcache_entries)
 			return NULL;
 
 		new = agp_create_memory(1);
@@ -404,18 +424,6 @@ static struct aper_size_info_fixed intel_i830_sizes[] =
 	{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)
 {
 	u16 gmch_ctrl;
@@ -429,7 +437,7 @@ static void intel_i830_init_gtt_entries(void)
 
 	if (IS_I965) {
 		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,
 		 * 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 += 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 {
 		/* On previous hardware, the GTT size was just what was
 		 * required to map the aperture.
@@ -471,7 +495,7 @@ static void intel_i830_init_gtt_entries(void)
 			gtt_entries = MB(8) - KB(size);
 			break;
 		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) *
 					MB(ddt[I830_RDRAM_DDT(rdct)]);
 			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 ||
 			    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_82945GM_HB || IS_I965 )
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+			    IS_I965 || IS_G33)
 				gtt_entries = MB(48) - KB(size);
 			else
 				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 ||
 			    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_82945GM_HB || IS_I965)
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+			    IS_I965 || IS_G33)
 				gtt_entries = MB(64) - KB(size);
 			else
 				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:
 			gtt_entries = 0;
 			break;
@@ -529,7 +568,7 @@ static void intel_i830_init_gtt_entries(void)
 		       "No pre-allocated video memory detected.\n");
 	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.
@@ -547,14 +586,14 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
 	num_entries = size->num_entries;
 	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;
 
-	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;
 
-	temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+	temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
 	global_cache_flush();	/* FIXME: ?? */
 
 	/* 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);
 
-	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);
 
 	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
 	gmch_ctrl |= I830_GMCH_ENABLED;
 	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) {
-		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)
 {
-	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)
@@ -653,9 +692,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
 	temp = agp_bridge->current_size;
 	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");
 		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++) {
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
 						       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);
 
 out:
@@ -703,15 +742,15 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
 	if (mem->page_count == 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");
 		return -EINVAL;
 	}
 
 	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);
 	return 0;
@@ -734,7 +773,7 @@ static int intel_i915_configure(void)
 
 	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);
 
@@ -742,13 +781,13 @@ static int intel_i915_configure(void)
 	gmch_ctrl |= I830_GMCH_ENABLED;
 	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) {
-		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)
 {
-	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,
@@ -776,9 +815,9 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
 	temp = agp_bridge->current_size;
 	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");
 		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++) {
 		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);
 
  out:
@@ -826,15 +865,15 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
 	if (mem->page_count == 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");
 		return -EINVAL;
 	}
 
 	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);
 	return 0;
@@ -850,7 +889,7 @@ static int intel_i9xx_fetch_size(void)
 	int aper_size; /* size in megabytes */
 	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++) {
 		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;
 	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;
 
 	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;
 
-	temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+	temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
 	global_cache_flush();	/* FIXME: ? */
 
 	/* 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;
        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;
-       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;
 
 
-       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;
 
-       temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+       temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
        global_cache_flush();   /* FIXME: ? */
 
        /* 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,
 };
 
-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;
 
-	intel_i830_private.i830_dev = i830_dev;
+	intel_private.pcidev = gmch_device;
 	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,
 				     const struct pci_device_id *ent)
 {
 	struct agp_bridge_data *bridge;
-	char *name = "(unknown)";
 	u8 cap_ptr = 0;
 	struct resource *r;
+	int i;
 
 	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)
 		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)
-			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);
 		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->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
@@ -1988,12 +1959,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
 
 	pci_set_drvdata(pdev, 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)
@@ -2002,10 +1967,8 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev)
 
 	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);
 }
@@ -2021,10 +1984,8 @@ static int agp_intel_resume(struct pci_dev *pdev)
 	 * as host bridge (00:00) resumes before graphics device (02:00),
 	 * 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)
 		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_82965G_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);
 
+/*
+ * 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)
 {
 #ifdef	CONFIG_ALPHA
@@ -1071,6 +1082,7 @@ static ide_driver_t idedisk_driver = {
 	},
 	.probe			= ide_disk_probe,
 	.remove			= ide_disk_remove,
+	.resume			= ide_disk_resume,
 	.shutdown		= ide_device_shutdown,
 	.version		= IDEDISK_VERSION,
 	.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
  * 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 long flags;
@@ -820,6 +820,9 @@ static void probe_hwif(ide_hwif_t *hwif)
 		return;
 	}
 
+	if (fixup)
+		fixup(hwif);
+
 	for (unit = 0; unit < MAX_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))
 {
-	probe_hwif(hwif);
-
-	if (fixup)
-		fixup(hwif);
+	probe_hwif(hwif, fixup);
 
 	if (!hwif_init(hwif)) {
 		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)
 		if (probe[index])
-			probe_hwif(&ide_hwifs[index]);
+			probe_hwif(&ide_hwifs[index], NULL);
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[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_hwif_t *hwif = HWIF(drive);
+	ide_driver_t *drv = to_ide_driver(dev->driver);
 	struct request rq;
 	struct request_pm_state rqpm;
 	ide_task_t args;
+	int err;
 
 	/* Call ACPI _STM only once */
 	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_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,

+ 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
  * 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_MCP65_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 },
 	{ 0 }
 };
@@ -494,7 +496,9 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 	/* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"),
 	/* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"),
 	/* 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)
@@ -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_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_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, },
 };
 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)
 {
 	ide_pci_device_t *d = &generic_chipsets[id->driver_data];
-	u16 command;
 	int ret = -ENODEV;
 
 	/* Don't use the generic entry unless instructed to do so */
 	if (id->driver_data == 0 && ide_generic_all == 0)
 			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;
+		break;
 	}
 
 	if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
+		u16 command;
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		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;
 		}
 	}

+ 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>
  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
@@ -106,7 +106,8 @@
  *   switch  to calculating  PCI clock frequency based on the chip's base DPLL
  *   frequency
  * - 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(),
  *   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
@@ -365,7 +366,6 @@ static u32 sixty_six_base_hpt37x[] = {
 };
 
 #define HPT366_DEBUG_DRIVE_INFO		0
-#define HPT374_ALLOW_ATA133_6		1
 #define HPT371_ALLOW_ATA133_6		1
 #define HPT302_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 = {
 	.chip_type	= HPT374,
-	.max_mode	= HPT374_ALLOW_ATA133_6 ? 4 : 3,
+	.max_mode	= 3,
 	.dpll_clk	= 48,
 	.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) 2007		Bartlomiej Zolnierkiewicz
@@ -262,7 +262,7 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
 	}
 
 	if (itdev->smart)
-		goto set_drive_speed;
+		return 0;
 
 	/* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
 	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_program(drive, itdev->pio[unit]);
 
-set_drive_speed:
 	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:
 				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)
 					printk("(%dK stripe)", idbits[146]);
 				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 {
 			/* Non RAID volume. Fixups to stop the core code
 			   doing unsupported things */
-			id->field_valid &= 1;
+			id->field_valid &= 3;
 			id->queue_depth = 0;
 			id->command_set_1 = 0;
 			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",
 				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 Andrzej Krzysztofowicz
@@ -170,42 +170,55 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
 		if (!drive->init_speed) {
 			u8 dma_stat = inb(hwif->dma_status);
 
-dma_pio:
 			if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
 			    ((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) {
 				drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)];
 				return 0;
 			} else if ((dma_timing) &&
 				   ((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;
-				else if ((dmaspeed & 0x21) == 0x21)
+					break;
+				case 0x21:
 					dmaspeed = XFER_MW_DMA_1;
-				else if ((dmaspeed & 0x77) == 0x77)
+					break;
+				case 0x77:
 					dmaspeed = XFER_MW_DMA_0;
-				else
+					break;
+				default:
 					goto dma_pio;
+				}
+
 				drive->current_speed = drive->init_speed = dmaspeed;
 				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;
-				else if ((piospeed & 0x22) == 0x22)
+					break;
+				case 0x22:
 					piospeed = XFER_PIO_3;
-				else if ((piospeed & 0x34) == 0x34)
+					break;
+				case 0x34:
 					piospeed = XFER_PIO_2;
-				else if ((piospeed & 0x47) == 0x47)
+					break;
+				case 0x47:
 					piospeed = XFER_PIO_1;
-				else if ((piospeed & 0x5d) == 0x5d)
+					break;
+				case 0x5d:
 					piospeed = XFER_PIO_0;
-				else
+					break;
+				default:
 					goto oem_setup_failed;
+				}
+
 				drive->current_speed = drive->init_speed = piospeed;
 				return 0;
 			}
@@ -214,8 +227,8 @@ dma_pio:
 
 oem_setup_failed:
 
-	pio_timing	&= ~0xFFU;
-	dma_timing	&= ~0xFFU;
+	pio_timing	= 0;
+	dma_timing	= 0;
 	ultra_timing	&= ~(0x0F << (4*unit));
 	ultra_enable	&= ~(0x01 << 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;
 
 	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];
 	cma_wq = create_singlethread_workqueue("rdma_cm");
 	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,
-		       struct mlx4_ib_qp *qp)
+		       int is_user, int has_srq, struct mlx4_ib_qp *qp)
 {
 	/* Sanity check RQ size before proceeding */
 	if (cap->max_recv_wr  > dev->dev->caps.max_wqes  ||
 	    cap->max_recv_sge > dev->dev->caps.max_rq_sg)
 		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_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.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)
 		goto err;
 
@@ -762,11 +772,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
 		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 (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path,
 				  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->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) {
 		context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
 		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);
 	/*
-	 * FW subminor version is at more signifant bits than minor
+	 * FW subminor version is at more significant bits than minor
 	 * version, so swap here.
 	 */
 	dev->fw_ver = (dev->fw_ver & 0xffff00000000ull) |

+ 1 - 0
drivers/media/common/Kconfig

@@ -4,5 +4,6 @@ config VIDEO_SAA7146
 
 config VIDEO_SAA7146_VV
 	tristate
+	depends on VIDEO_DEV
 	select VIDEO_BUF
 	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 \
-	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
 
+ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
+b2c2-flexcop-objs += flexcop-dma.o
+endif
+
 b2c2-flexcop-pci-objs = 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 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) {
 		cancel_delayed_work(&cinergyt2->query_work);

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

@@ -41,6 +41,7 @@ struct tda10086_state {
 	/* private demod data */
 	u32 frequency;
 	u32 symbol_rate;
+	bool has_lock;
 };
 
 static int debug = 0;
@@ -116,7 +117,7 @@ static int tda10086_init(struct dvb_frontend* fe)
 	// misc setup
 	tda10086_write_byte(state, 0x01, 0x94);
 	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, 0x0c, 0x0c);
 	tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
@@ -146,7 +147,7 @@ static int tda10086_init(struct dvb_frontend* fe)
 	// setup AGC
 	tda10086_write_byte(state, 0x05, 0x0B);
 	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, 0x41, 0x4f);
 	tda10086_write_byte(state, 0x42, 0x43);
@@ -398,6 +399,10 @@ static int tda10086_set_frontend(struct dvb_frontend* fe,
 
 	dprintk ("%s\n", __FUNCTION__);
 
+	// modify parameters for tuning
+	tda10086_write_byte(state, 0x02, 0x35);
+	state->has_lock = false;
+
 	// set params
 	if (fe->ops.tuner_ops.set_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;
 	if (val & 0x08)
 		*fe_status |= FE_HAS_SYNC;
-	if (val & 0x10)
+	if (val & 0x10) {
 		*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;
 }
@@ -555,7 +566,7 @@ static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
 
 	dprintk ("%s\n", __FUNCTION__);
 
-	_str = tda10086_read_byte(state, 0x43);
+	_str = 0xff - tda10086_read_byte(state, 0x43);
 	*signal = (_str << 8) | _str;
 
 	return 0;
@@ -568,7 +579,7 @@ static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
 
 	dprintk ("%s\n", __FUNCTION__);
 
-	_snr = tda10086_read_byte(state, 0x1c);
+	_snr = 0xff - tda10086_read_byte(state, 0x1c);
 	*snr = (_snr << 8) | _snr;
 
 	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[3] = div >> 7;
 	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[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
 	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
 	tristate "Virtual Video Driver"
-	depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI
+	depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI && VIDEO_DEV
 	select VIDEO_BUF
 	default n
 	---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_SLICED_VBI_CAPTURE)
 #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 {
 	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->cur_dma_stream = -1;
+	itv->cur_pio_stream = -1;
 	itv->audio_stereo_mode = AUDIO_STEREO;
 	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_VIM_RST		(0x1 << 28)
 #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_DATA_REQ		(0x1 << 22)
 #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)
 
 /* 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_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_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 */
 #define IVTV_F_I_DMA		   0 	/* DMA 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_ENC_PAUSED	   13 	/* the encoder is paused */
 #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 */
 #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 */
 	struct ivtv_SG_element *SGarray;
+	struct ivtv_SG_element *PIOarray;
 	dma_addr_t SG_handle;
 	int SG_length;
 
@@ -706,6 +715,7 @@ struct ivtv {
 	atomic_t decoding;	/* count number of active decoding streams */
 	u32 irq_rr_idx; /* Round-robin stream index */
 	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_size;
 	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-controls.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.
    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);
 		/* Select correct audio input (i.e. TV tuner or Line in) */
 		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. */
 		ivtv_unmute(itv);
 		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);
 		/* Select the correct audio input (i.e. radio tuner) */
 		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. */
 		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;
 				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;
 	}
@@ -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);
 	}
 
+	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: {
 		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)
 			return -EINVAL;
 		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: {
 		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)
 			return -EINVAL;
 		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) {
 			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 */
 		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->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);
 		break;
 	}
@@ -1455,6 +1485,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
 	case VIDIOC_S_FMT:
 	case VIDIOC_TRY_FMT:
 	case VIDIOC_ENUM_FMT:
+	case VIDIOC_CROPCAP:
 	case VIDIOC_G_CROP:
 	case VIDIOC_S_CROP:
 	case VIDIOC_G_FREQUENCY:

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

@@ -31,8 +31,6 @@
 
 #define DMA_MAGIC_COOKIE 0x000001fe
 
-#define SLICED_VBI_PIO 1
-
 static void ivtv_dma_dec_start(struct ivtv_stream *s);
 
 static const int ivtv_stream_map[] = {
@@ -42,12 +40,40 @@ static const int ivtv_stream_map[] = {
 	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)
@@ -56,8 +82,11 @@ void ivtv_irq_work_handler(struct work_struct *work)
 
 	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))
-		vbi_work_handler(itv);
+		ivtv_vbi_work_handler(itv);
 
 	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
 		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;
 
-	/* 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);
 	memset(buf->buf, 0, 128);
 	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)
 			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;
 
-		/* 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;
 		size -= buf->bytesused;
 		offset += s->buf_size;
@@ -224,11 +242,6 @@ static void dma_post(struct ivtv_stream *s)
 	u32 *u32buf;
 	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",
 			s->name, s->dma_offset);
 	list_for_each(p, &s->q_dma.list) {
@@ -278,10 +291,14 @@ static void dma_post(struct ivtv_stream *s)
 	if (buf)
 		buf->bytesused += s->dma_last_offset;
 	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) {
 			ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
 			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];
 	int i;
 
+	IVTV_DEBUG_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name);
+
 	if (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
 	   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 &&
 			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);
-		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++) {
 			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 */
 	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)
@@ -489,6 +523,40 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
 	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)
 {
 	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);
 	s = &itv->streams[ivtv_stream_map[data[0]]];
 	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");
 	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
 	   clear the old ones and start with this new one.
 	   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) &&
 			!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_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];
 	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");
 	if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
 			!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)) {
 		struct ivtv_stream *s = ivtv_get_output_stream(itv);
-		int work = 0;
 
 		itv->lastVsyncFrame += 1;
 		if (frame == 0) {
@@ -678,7 +730,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
 		/* Send VBI to saa7127 */
 		if (frame) {
 			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 */
@@ -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.yuv_forced_update = 0;
 				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);
 	}
 
+	if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
+		ivtv_irq_enc_pio_complete(itv);
+	}
+
 	if (combo & IVTV_IRQ_DMA_ERR) {
 		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) {
-		ivtv_irq_dev_vbi_reinsert(itv);
+		ivtv_irq_dec_vbi_reinsert(itv);
 	}
 
 	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);
 
 	/* 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->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;
 		}
-		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);
 		ivtv_stream_sync_for_cpu(s);
 	}
@@ -219,7 +231,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
 			break;
 		}
 		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->buf, s->buf_size + 256, s->dma);
 			ivtv_buf_sync_for_cpu(s, buf);
@@ -242,7 +254,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
 
 	/* empty 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,
 				s->buf_size + 256, s->dma);
 		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);
 			s->SG_handle = IVTV_DMA_UNMAPPED;
 		}
+		kfree(s->SGarray);
+		kfree(s->PIOarray);
+		s->PIOarray = NULL;
 		s->SGarray = NULL;
 		s->SG_length = 0;
 	}

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

@@ -20,18 +20,43 @@
  */
 
 #define IVTV_DMA_UNMAPPED	((u32) -1)
+#define SLICED_VBI_PIO 1
 
 /* 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)
 {
-	if (s->dma != PCI_DMA_NONE)
+	if (ivtv_use_dma(s))
 		pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
 				s->buf_size + 256, s->dma);
 }
 
 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,
 				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)
 {
-	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)
 {
-	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))
 		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 */
 	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;
 

+ 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);
 void ivtv_disable_vbi(struct ivtv *itv);
 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 input;
 	int enable;
-	int bright;
-	int contrast;
-	int hue;
-	int sat;
 };
 
 #define   I2C_SAA7111        0x48
@@ -96,6 +92,17 @@ saa7111_write (struct i2c_client *client,
 	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
 saa7111_write_block (struct i2c_client *client,
 		     const u8          *data,
@@ -439,28 +446,14 @@ saa7111_command (struct i2c_client *client,
 	{
 		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;
 
@@ -524,10 +517,6 @@ saa7111_detect_client (struct i2c_adapter *adapter,
 	decoder->norm = VIDEO_MODE_NTSC;
 	decoder->input = 0;
 	decoder->enable = 1;
-	decoder->bright = 32768;
-	decoder->contrast = 32768;
-	decoder->hue = 32768;
-	decoder->sat = 32768;
 	i2c_set_clientdata(client, decoder);
 
 	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))
 		return;
 
+	/* any urb with wrong status is ignored without acknowledgement */
+	if (urb->status == -ENOENT) {
+		return;
+	}
+
 	f = &usbvision->curFrame;
 
 	/* Manage streaming interruption */
@@ -1436,18 +1441,21 @@ static void usbvision_isocIrq(struct urb *urb)
 	if (usbvision->streaming == Stream_On) {
 
 		/* 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 {
@@ -1466,10 +1474,10 @@ static void usbvision_isocIrq(struct urb *urb)
 	urb->dev = usbvision->dev;
 	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;
 }
@@ -2394,7 +2402,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 {
 	struct usb_device *dev = usbvision->dev;
 	int bufIdx, errCode, regValue;
-	const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
+	int sb_size;
 
 	if (!USBVISION_IS_OPERATIONAL(usbvision))
 		return -EFAULT;
@@ -2408,11 +2416,14 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 		usbvision->last_error = errCode;
 		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;
-	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;
 		}
 		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->context = usbvision;
 		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++,
 		     k += usbvision->isocPacketSize) {
 			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 */
 	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) {
-			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;
-	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;
 }
 
@@ -2470,7 +2490,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
 void usbvision_stop_isoc(struct usb_usbvision *usbvision)
 {
 	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))
 		return;
@@ -2499,15 +2519,19 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
 		errCode = usb_set_interface(usbvision->dev, usbvision->iface,
 					    usbvision->ifaceAlt);
 		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;
 		}
-		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;
-		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_URB_FRAMES		32
-#define USBVISION_MAX_ISOC_PACKET_SIZE 	959			// NT1003 Specs Document says 1023
 
 #define USBVISION_NUM_HEADERMARKER	20
 #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/card.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
 
 #include "core.h"
 #include "sysfs.h"
@@ -192,6 +193,16 @@ static int mmc_read_switch(struct mmc_card *card)
 	int err;
 	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;
 
 	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);
 	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;
 		goto out;
 	}
@@ -229,6 +239,12 @@ static int mmc_switch_hs(struct mmc_card *card)
 	int err;
 	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))
 		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).
 	 */
-	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)) {
 		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
 		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;
 	}
 
-	if (cmd->opcode == MMC_STOP_TRANSMISSION)
+	if (host->flags & FL_SENT_STOP)
 		cmdr |= AT91_MCI_TRCMD_STOP;
 
 	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 |
 			AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
 			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;
 		}
 		else {

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

@@ -76,8 +76,7 @@ const struct {
 #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) */
 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			consumer_index;
 	__be32			producer_index;
-	u8			reserved6[2];
+	u32			reserved6[2];
 	__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)
 		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)
 			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)

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

@@ -37,6 +37,10 @@
 #include "fw.h"
 #include "icm.h"
 
+enum {
+	MLX4_COMMAND_INTERFACE_REV	= 1
+};
+
 extern void __buggy_use_of_MLX4_GET(void);
 extern void __buggy_use_of_MLX4_PUT(void);
 
@@ -452,10 +456,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
 	u32 *outbox;
 	int err = 0;
 	u64 fw_ver;
+	u16 cmd_if_rev;
 	u8 lg;
 
 #define QUERY_FW_OUT_SIZE             0x100
 #define QUERY_FW_VER_OFFSET            0x00
+#define QUERY_FW_CMD_IF_REV_OFFSET     0x0a
 #define QUERY_FW_MAX_CMD_OFFSET        0x0f
 #define QUERY_FW_ERR_START_OFFSET      0x30
 #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);
 	/*
-	 * FW subminor version is at more signifant bits than minor
+	 * FW subminor version is at more significant bits than minor
 	 * version, so swap here.
 	 */
 	dev->caps.fw_ver = (fw_ver & 0xffff00000000ull) |
 		((fw_ver & 0xffff0000ull) >> 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);
 	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 >> 16) & 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_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_interface *intf;
 
-	INIT_LIST_HEAD(&priv->ctx_list);
-	spin_lock_init(&priv->ctx_lock);
-
 	mutex_lock(&intf_mutex);
 
 	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->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

+ 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_REGION	 |
 				       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->pd	       = cpu_to_be32(mr->pd);
 	mpt_entry->start       = cpu_to_be64(mr->iova);
 	mpt_entry->length      = cpu_to_be64(mr->size);
 	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,
 			     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
  *   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.
- * 
+ *
  *   This program is distributed in the hope that it will be useful,
  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  *   the GNU General Public License for more details.
  *
  *   You should have received a copy of the GNU General Public License
- *   along with this program;  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
  */
 #include <linux/fs.h>
@@ -39,7 +39,7 @@ cifs_dump_mem(char *label, void *data, int length)
 	char *charptr = data;
 	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);
 	for (i = 0; i < length; i += 16) {
 		line[0] = 0;
@@ -60,10 +60,10 @@ cifs_dump_mem(char *label, void *data, int length)
 #ifdef CONFIG_CIFS_DEBUG2
 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->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 mid_q_entry * mid_entry;
 
-	if(server == NULL)
+	if (server == NULL)
 		return;
 
-	cERROR(1,("Dump pending requests:"));
+	cERROR(1, ("Dump pending requests:"));
 	spin_lock(&GlobalMid_Lock);
 	list_for_each(tmp, &server->pending_mid_q) {
 		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,
 				(int)mid_entry->command,
 				mid_entry->pid,
 				mid_entry->tsk,
 				mid_entry->mid));
 #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->resp_buf,
 				mid_entry->when_received,
 				jiffies));
 #endif /* STATS2 */
-			cERROR(1,("IsMult: %d IsEnd: %d", mid_entry->multiRsp,
+			cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp,
 				  mid_entry->multiEnd));
-			if(mid_entry->resp_buf) {
+			if (mid_entry->resp_buf) {
 				cifs_dump_detail(mid_entry->resp_buf);
 				cifs_dump_mem("existing buf: ",
 					mid_entry->resp_buf,
 					62 /* fixme */);
 			}
-			
 		}
 	}
 	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"
 		    "---------------------------------------------------\n");
 	buf += length;
-	length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION);
+	length = sprintf(buf, "CIFS Version %s\n", CIFS_VERSION);
 	buf += length;
-	length = sprintf(buf,"Active VFS Requests: %d\n", GlobalTotalActiveXid);
+	length = sprintf(buf,
+		"Active VFS Requests: %d\n", GlobalTotalActiveXid);
 	buf += length;
 	length = sprintf(buf, "Servers:");
 	buf += length;
@@ -141,7 +141,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 	list_for_each(tmp, &GlobalSMBSessionList) {
 		i++;
 		ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
-		if((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
+		if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
 		   (ses->serverNOS == NULL)) {
 			buf += sprintf(buf, "\nentry for %s not fully "
 					"displayed\n\t", ses->serverName);
@@ -149,15 +149,18 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 		} else {
 			length =
 			    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,
 				atomic_read(&ses->inUse),
 				ses->serverOS, ses->serverNOS,
-				ses->capabilities,ses->status);
+				ses->capabilities, ses->status);
 			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,
 				atomic_read(&ses->server->socketUseCount),
 				ses->server->secMode,
@@ -165,7 +168,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 
 #ifdef CONFIG_CIFS_STATS2
 			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));
 #endif
 
@@ -177,17 +180,19 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 				mid_entry = list_entry(tmp1, struct
 					mid_q_entry,
 					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;
 				}
 			}
-			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);
 		length =
 		    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,
 			    atomic_read(&tcon->useCount),
 			    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.MaxPathNameComponentLength),
 			    tcon->tidStatus);
-		buf += length;        
+		buf += length;
 		if (dev_type == FILE_DEVICE_DISK)
 			length = sprintf(buf, " type: DISK ");
 		else if (dev_type == FILE_DEVICE_CD_ROM)
@@ -224,7 +230,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 			length =
 			    sprintf(buf, " type: %d ", dev_type);
 		buf += length;
-		if(tcon->tidStatus == CifsNeedReconnect) {
+		if (tcon->tidStatus == CifsNeedReconnect) {
 			buf += sprintf(buf, "\tDISCONNECTED ");
 			length += 14;
 		}
@@ -238,9 +244,9 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 	/* Now calculate total size of returned data */
 	length = buf - original_buf;
 
-	if(offset + count >= length)
+	if (offset + count >= length)
 		*eof = 1;
-	if(length < offset) {
+	if (length < offset) {
 		*eof = 1;
 		return 0;
 	} else {
@@ -256,18 +262,18 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
 
 static int
 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 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);
 #ifdef CONFIG_CIFS_STATS2
 		atomic_set(&totBufAllocCount, 0);
@@ -297,14 +303,14 @@ cifs_stats_write(struct file *file, const char __user *buffer,
 		read_unlock(&GlobalSMBSeslock);
 	}
 
-        return count;
+	return count;
 }
 
 static int
 cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 		  int count, int *eof, void *data)
 {
-	int item_length,i,length;
+	int item_length, i, length;
 	struct list_head *tmp;
 	struct cifsTconInfo *tcon;
 
@@ -314,44 +320,44 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 			"Resources in use\nCIFS Session: %d\n",
 			sesInfoAllocCount.counter);
 	buf += length;
-	item_length = 
-		sprintf(buf,"Share (unique mount targets): %d\n",
+	item_length =
+		sprintf(buf, "Share (unique mount targets): %d\n",
 			tconInfoAllocCount.counter);
 	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,
 			cifs_min_rcv + tcpSesAllocCount.counter);
 	length += 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;
 	buf += item_length;
 #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(&totSmBufAllocCount));
+				atomic_read(&totSmBufAllocCount));
 	length += item_length;
 	buf += item_length;
 #endif /* CONFIG_CIFS_STATS2 */
 
-	item_length = 
-		sprintf(buf,"Operations (MIDs): %d\n",
+	item_length =
+		sprintf(buf, "Operations (MIDs): %d\n",
 			midCount.counter);
 	length += item_length;
 	buf += item_length;
 	item_length = sprintf(buf,
 		"\n%d session %d share reconnects\n",
-		tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
+		tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);
 	length += item_length;
 	buf += item_length;
 
 	item_length = sprintf(buf,
 		"Total vfs operations: %d maximum at one time: %d\n",
-		GlobalCurrentXid,GlobalMaxActiveXid);
+		GlobalCurrentXid, GlobalMaxActiveXid);
 	length += item_length;
 	buf += item_length;
 
@@ -360,10 +366,10 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 	list_for_each(tmp, &GlobalTreeConnectionList) {
 		i++;
 		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;
 		length += item_length;
-		if(tcon->tidStatus == CifsNeedReconnect) {
+		if (tcon->tidStatus == CifsNeedReconnect) {
 			buf += sprintf(buf, "\tDISCONNECTED ");
 			length += 14;
 		}
@@ -380,15 +386,15 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 		item_length = sprintf(buf, "\nWrites: %d Bytes: %lld",
 			atomic_read(&tcon->num_writes),
 			(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",
-                        atomic_read(&tcon->num_locks),
+			atomic_read(&tcon->num_locks),
 			atomic_read(&tcon->num_hardlinks),
 			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",
 			atomic_read(&tcon->num_opens),
@@ -415,12 +421,12 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 	}
 	read_unlock(&GlobalSMBSeslock);
 
-	buf += sprintf(buf,"\n");
+	buf += sprintf(buf, "\n");
 	length++;
 
-	if(offset + count >= length)
+	if (offset + count >= length)
 		*eof = 1;
-	if(length < offset) {
+	if (length < offset) {
 		*eof = 1;
 		return 0;
 	} else {
@@ -428,7 +434,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
 	}
 	if (length > count)
 		length = count;
-		
+
 	return length;
 }
 #endif
@@ -547,11 +553,11 @@ cifs_proc_clean(void)
 	remove_proc_entry("MultiuserMount", proc_fs_cifs);
 	remove_proc_entry("OplockEnabled", 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);
 }
 
@@ -590,7 +596,7 @@ cifsFYI_write(struct file *file, const char __user *buffer,
 		cifsFYI = 0;
 	else if (c == '1' || c == 'y' || c == 'Y')
 		cifsFYI = 1;
-	else if((c > '1') && (c <= '9'))
+	else if ((c > '1') && (c <= '9'))
 		cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
 
 	return count;
@@ -637,28 +643,28 @@ oplockEnabled_write(struct file *file, const char __user *buffer,
 
 static int
 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
 experimEnabled_write(struct file *file, const char __user *buffer,
-                    unsigned long count, void *data)
+		     unsigned long count, void *data)
 {
 	char c;
 	int rc;
@@ -678,46 +684,46 @@ experimEnabled_write(struct file *file, const char __user *buffer,
 
 static int
 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
 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
 lookupFlag_read(char *page, char **start, off_t off,
-		   int count, int *eof, void *data)
+		int count, int *eof, void *data)
 {
 	int len;
 
@@ -860,15 +866,15 @@ security_flags_write(struct file *file, const char __user *buffer,
 	char flags_string[12];
 	char c;
 
-	if((count < 1) || (count > 11))
+	if ((count < 1) || (count > 11))
 		return -EINVAL;
 
 	memset(flags_string, 0, 12);
 
-	if(copy_from_user(flags_string, buffer, count))
+	if (copy_from_user(flags_string, buffer, count))
 		return -EFAULT;
 
-	if(count < 3) {
+	if (count < 3) {
 		/* single char or single char followed by null */
 		c = flags_string[0];
 		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);
 
-	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;
 	}
 
-	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));
 		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
  *   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.
- * 
+ *
  *   This program is distributed in the hope that it will be useful,
  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  *   the GNU General Public License for more details.
  *
  *   You should have received a copy of the GNU General Public License
- *   along with this program;  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
  */
 #include <linux/fs.h>
@@ -32,7 +32,7 @@
  *
  */
 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 i;
@@ -66,7 +66,7 @@ cifs_strtoUCS(__le16 * to, const char *from, int len,
 {
 	int charlen;
 	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) {
 
@@ -79,7 +79,7 @@ cifs_strtoUCS(__le16 * to, const char *from, int len,
 			/* A question mark */
 			to[i] = cpu_to_le16(0x003f);
 			charlen = 1;
-		} else 
+		} else
 			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,
 				SLAB_HWCACHE_ALIGN, NULL, NULL);
 	if (cifs_oplock_cachep == NULL) {
-		kmem_cache_destroy(cifs_mid_cachep);
 		mempool_destroy(cifs_mid_poolp);
+		kmem_cache_destroy(cifs_mid_cachep);
 		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));
 
 	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;
 	
 	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;
 			spin_unlock(&GlobalMid_Lock);
 			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);
-				kthread_stop(srvTcp->tsk);
+				tsk = srvTcp->tsk;
+				if(tsk)
+					kthread_stop(tsk);
 			}
 		}
 		 /* 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 ((temp_rc == -ESHUTDOWN) &&
 					   (pSesInfo->server) && (pSesInfo->server->tsk)) {
+						struct task_struct *tsk;
 						send_sig(SIGKILL,pSesInfo->server->tsk,1);
-						kthread_stop(pSesInfo->server->tsk);
+						tsk = pSesInfo->server->tsk;
+						if (tsk)
+							kthread_stop(tsk);
 					}
 				} else
 					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;
 			} else if (rc == -ESHUTDOWN) {
 				cFYI(1,("Waking up socket by sending it signal"));
-				if(cifsd_task) {
+				if (cifsd_task) {
 					send_sig(SIGKILL,cifsd_task,1);
 					kthread_stop(cifsd_task);
 				}

+ 94 - 90
fs/cifs/dir.c

@@ -2,7 +2,7 @@
  *   fs/cifs/dir.c
  *
  *   vfs operations that deal with dentries
- * 
+ *
  *   Copyright (C) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
@@ -34,11 +34,12 @@
 static void
 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 {
 		direntry->d_time = jiffies;
 		direntry = direntry->d_parent;
-	} while (!IS_ROOT(direntry));	
+	} while (!IS_ROOT(direntry));
 }
 
 /* Note: caller must free return buffer */
@@ -51,7 +52,7 @@ build_path_from_dentry(struct dentry *direntry)
 	char *full_path;
 	char dirsep;
 
-	if(direntry == NULL)
+	if (direntry == NULL)
 		return NULL;  /* not much we can do if dentry is freed and
 		we need to reopen the file after it was closed implicitly
 		when the server crashed */
@@ -59,18 +60,18 @@ build_path_from_dentry(struct dentry *direntry)
 	dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
 	pplen = CIFS_SB(direntry->d_sb)->prepathlen;
 cifs_bp_rename_retry:
-	namelen = pplen; 
+	namelen = pplen;
 	for (temp = direntry; !IS_ROOT(temp);) {
 		namelen += (1 + temp->d_name.len);
 		temp = temp->d_parent;
-		if(temp == NULL) {
-			cERROR(1,("corrupt dentry"));
+		if (temp == NULL) {
+			cERROR(1, ("corrupt dentry"));
 			return NULL;
 		}
 	}
 
 	full_path = kmalloc(namelen+1, GFP_KERNEL);
-	if(full_path == NULL)
+	if (full_path == NULL)
 		return full_path;
 	full_path[namelen] = 0;	/* trailing null */
 	for (temp = direntry; !IS_ROOT(temp);) {
@@ -84,8 +85,8 @@ cifs_bp_rename_retry:
 			cFYI(0, ("name: %s", full_path + namelen));
 		}
 		temp = temp->d_parent;
-		if(temp == NULL) {
-			cERROR(1,("corrupt dentry"));
+		if (temp == NULL) {
+			cERROR(1, ("corrupt dentry"));
 			kfree(full_path);
 			return NULL;
 		}
@@ -94,7 +95,7 @@ cifs_bp_rename_retry:
 		cERROR(1,
 		       ("did not end path lookup where expected namelen is %d",
 			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
 		above us to prevent this, but retrying should be harmless) */
 		kfree(full_path);
@@ -106,7 +107,7 @@ cifs_bp_rename_retry:
 	   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 */
 	/* 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;
 }
 
@@ -147,12 +148,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 	pTcon = cifs_sb->tcon;
 
 	full_path = build_path_from_dentry(direntry);
-	if(full_path == NULL) {
+	if (full_path == NULL) {
 		FreeXid(xid);
 		return -ENOMEM;
 	}
 
-	if(nd && (nd->flags & LOOKUP_OPEN)) {
+	if (nd && (nd->flags & LOOKUP_OPEN)) {
 		int oflags = nd->intent.open.flags;
 
 		desiredAccess = 0;
@@ -164,28 +165,29 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 				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;
-		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;
-		else if((oflags & O_CREAT) == O_CREAT)
+		else if ((oflags & O_CREAT) == O_CREAT)
 			disposition = FILE_OPEN_IF;
 		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)
 		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);
 		FreeXid(xid);
 		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,
 			 desiredAccess, CREATE_NOT_DIR,
 			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
@@ -193,27 +195,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 	else
 		rc = -EIO; /* no NT SMB support fall into legacy open below */
 
-	if(rc == -EIO) {
+	if (rc == -EIO) {
 		/* old server, retry the open legacy style */
 		rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
 			desiredAccess, CREATE_NOT_DIR,
 			&fileHandle, &oplock, buf, cifs_sb->local_nls,
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-	} 
+	}
 	if (rc) {
 		cFYI(1, ("cifs_create returned 0x%x", rc));
 	} else {
 		/* If Open reported that we actually created a file
 		then we now have to set the mode if possible */
 		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,
 					(__u64)current->fsuid,
 					(__u64)current->fsgid,
 					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);
 			} else {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
@@ -221,26 +224,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 					(__u64)-1,
 					0 /* dev */,
 					cifs_sb->local_nls,
-					cifs_sb->mnt_cifs_flags & 
+					cifs_sb->mnt_cifs_flags &
 						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*/
 		if (pTcon->ses->capabilities & CAP_UNIX)
 			rc = cifs_get_inode_info_unix(&newinode, full_path,
-						 inode->i_sb,xid);
+						 inode->i_sb, xid);
 		else {
 			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;
-				if((oplock & CIFS_CREATE_ACTION) &&
-				  (cifs_sb->mnt_cifs_flags & 
+				if ((oplock & CIFS_CREATE_ACTION) &&
+				    (cifs_sb->mnt_cifs_flags &
 				     CIFS_MOUNT_SET_UID)) {
 					newinode->i_uid = current->fsuid;
 					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;
 			d_instantiate(direntry, newinode);
 		}
-		if((nd->flags & LOOKUP_OPEN) == FALSE) {
+		if ((nd->flags & LOOKUP_OPEN) == FALSE) {
 			/* mknod case - do not leave file open */
 			CIFSSMBClose(xid, pTcon, fileHandle);
-		} else if(newinode) {
+		} else if (newinode) {
 			pCifsFile =
 			   kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
-			
-			if(pCifsFile == NULL)
+
+			if (pCifsFile == NULL)
 				goto cifs_create_out;
 			pCifsFile->netfid = fileHandle;
 			pCifsFile->pid = current->tgid;
@@ -276,33 +281,33 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 			init_MUTEX(&pCifsFile->fh_sem);
 			mutex_init(&pCifsFile->lock_mutex);
 			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; */
 			write_lock(&GlobalSMBSeslock);
-			list_add(&pCifsFile->tlist,&pTcon->openFileList);
+			list_add(&pCifsFile->tlist, &pTcon->openFileList);
 			pCifsInode = CIFS_I(newinode);
-			if(pCifsInode) {
+			if (pCifsInode) {
 				/* if readable file instance put first in list*/
 				if (write_only == TRUE) {
-                                       	list_add_tail(&pCifsFile->flist,
+					list_add_tail(&pCifsFile->flist,
 						&pCifsInode->openFileList);
 				} else {
 					list_add(&pCifsFile->flist,
 						&pCifsInode->openFileList);
 				}
-				if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
+				if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
 					pCifsInode->clientCanCacheAll = TRUE;
 					pCifsInode->clientCanCacheRead = TRUE;
-					cFYI(1,("Exclusive Oplock for inode %p",
+					cFYI(1, ("Exclusive Oplock inode %p",
 						newinode));
-				} else if((oplock & 0xF) == OPLOCK_READ)
+				} else if ((oplock & 0xF) == OPLOCK_READ)
 					pCifsInode->clientCanCacheRead = TRUE;
 			}
 			write_unlock(&GlobalSMBSeslock);
 		}
-	} 
+	}
 cifs_create_out:
 	kfree(buf);
 	kfree(full_path);
@@ -310,8 +315,8 @@ cifs_create_out:
 	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 xid;
@@ -329,43 +334,45 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 	pTcon = cifs_sb->tcon;
 
 	full_path = build_path_from_dentry(direntry);
-	if(full_path == NULL)
+	if (full_path == NULL)
 		rc = -ENOMEM;
 	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,
-				mode,(__u64)current->fsuid,(__u64)current->fsgid,
+				mode, (__u64)current->fsuid,
+				(__u64)current->fsgid,
 				device_number, cifs_sb->local_nls,
-				cifs_sb->mnt_cifs_flags & 
+				cifs_sb->mnt_cifs_flags &
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		} else {
 			rc = CIFSSMBUnixSetPerms(xid, pTcon,
 				full_path, mode, (__u64)-1, (__u64)-1,
 				device_number, cifs_sb->local_nls,
-				cifs_sb->mnt_cifs_flags & 
+				cifs_sb->mnt_cifs_flags &
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 		}
 
-		if(!rc) {
+		if (!rc) {
 			rc = cifs_get_inode_info_unix(&newinode, full_path,
-						inode->i_sb,xid);
+						inode->i_sb, xid);
 			if (pTcon->nocase)
 				direntry->d_op = &cifs_ci_dentry_ops;
 			else
 				direntry->d_op = &cifs_dentry_ops;
-			if(rc == 0)
+			if (rc == 0)
 				d_instantiate(direntry, newinode);
 		}
 	} else {
-		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
+		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
 			int oplock = 0;
 			u16 fileHandle;
 			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);
 				FreeXid(xid);
 				return -ENOMEM;
@@ -373,39 +380,38 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 
 			rc = CIFSSMBOpen(xid, pTcon, full_path,
 					 FILE_CREATE, /* fail if exists */
-					 GENERIC_WRITE /* BB would 
+					 GENERIC_WRITE /* BB would
 					  WRITE_OWNER | WRITE_DAC be better? */,
 					 /* Create a file and set the
 					    file attribute to SYSTEM */
 					 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
 					 &fileHandle, &oplock, buf,
 					 cifs_sb->local_nls,
-					 cifs_sb->mnt_cifs_flags & 
+					 cifs_sb->mnt_cifs_flags &
 					    CIFS_MOUNT_MAP_SPECIAL_CHR);
 
 			/* BB FIXME - add handling for backlevel servers
 			   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
 				   local inode yet to put timestamps in,
 				   but we can reuse it safely */
 				int bytes_written;
 				struct win_dev *pdev;
 				pdev = (struct win_dev *)buf;
-				if(S_ISCHR(mode)) {
+				if (S_ISCHR(mode)) {
 					memcpy(pdev->type, "IntxCHR", 8);
 					pdev->major =
 					      cpu_to_le64(MAJOR(device_number));
-					pdev->minor = 
+					pdev->minor =
 					      cpu_to_le64(MINOR(device_number));
 					rc = CIFSSMBWrite(xid, pTcon,
 						fileHandle,
 						sizeof(struct win_dev),
 						0, &bytes_written, (char *)pdev,
 						NULL, 0);
-				} else if(S_ISBLK(mode)) {
+				} else if (S_ISBLK(mode)) {
 					memcpy(pdev->type, "IntxBLK", 8);
 					pdev->major =
 					      cpu_to_le64(MAJOR(device_number));
@@ -432,7 +438,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 
 
 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 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_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 */
 
 	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)
 	in which we already have the sb rename sem */
 	full_path = build_path_from_dentry(direntry);
-	if(full_path == NULL) {
+	if (full_path == NULL) {
 		FreeXid(xid);
 		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)
 		rc = cifs_get_inode_info_unix(&newInode, full_path,
-					      parent_dir_inode->i_sb,xid);
+					      parent_dir_inode->i_sb, xid);
 	else
 		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 (pTcon->nocase)
@@ -499,7 +504,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
 			direntry->d_op = &cifs_dentry_ops;
 		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 */
 		renew_parental_timestamps(direntry);
 
@@ -511,13 +516,13 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
 		else
 			direntry->d_op = &cifs_dentry_ops;
 		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 {
-		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 */
 	}
 
@@ -538,11 +543,11 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 	} else {
 		cFYI(1, ("neg dentry 0x%p name = %s",
 			 direntry, direntry->d_name.name));
-		if(time_after(jiffies, direntry->d_time + HZ) || 
+		if (time_after(jiffies, direntry->d_time + HZ) ||
 			!lookupCacheEnabled) {
 			d_drop(direntry);
 			isValid = 0;
-		} 
+		}
 	}
 
 	return isValid;
@@ -559,8 +564,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 
 struct dentry_operations cifs_dentry_ops = {
 	.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)

+ 22 - 24
fs/cifs/fcntl.c

@@ -2,7 +2,7 @@
  *   fs/cifs/fcntl.c
  *
  *   vfs operations that deal with the file control API
- * 
+ *
  *   Copyright (C) International Business Machines  Corp., 2003,2004
  *   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
 	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;
 	}
-	if(fcntl_notify_flags & DN_MODIFY) {
+	if (fcntl_notify_flags & DN_MODIFY) {
 		/* What does this mean on directories? */
 		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE |
 			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;
 	}
-	if(fcntl_notify_flags & DN_DELETE) {
+	if (fcntl_notify_flags & DN_DELETE) {
 		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 */
-		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME | 
+		cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_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;
 	}
-/*	if(fcntl_notify_flags & DN_MULTISHOT) {
+/*	if (fcntl_notify_flags & DN_MULTISHOT) {
 		cifs_ntfy_flags |= ;
 	} */ /* BB fixme - not sure how to handle this with CIFS yet */
 
-
 	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;
 	__u16 netfid;
 
-
-	if(experimEnabled == 0)
+	if (experimEnabled == 0)
 		return 0;
 
 	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);
 
-	if(full_path == NULL) {
+	if (full_path == NULL) {
 		rc = -ENOMEM;
 	} 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 */,
-			&netfid, &oplock,NULL, cifs_sb->local_nls,
+			&netfid, &oplock, NULL, cifs_sb->local_nls,
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 		/* 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 {
 			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,
 					filter, file, arg & DN_MULTISHOT,
 					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
 			to do it easily when inode freed or when
 			notify info is cleared/changed */
-			cFYI(1,("notify rc %d",rc));
+			cFYI(1, ("notify rc %d", rc));
 		}
 	}
-	
+
 	FreeXid(xid);
 	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 */ 
 		if ((direntry->d_inode) && (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) {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 						    mode,
@@ -1004,7 +1005,7 @@ mkdir_get_info:
 						    cifs_sb->mnt_cifs_flags & 
 						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 			}
-		else {
+		} else {
 			/* BB to be implemented via Windows secrty descriptors
 			   eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
 						 -1, -1, local_nls); */

+ 14 - 15
fs/cifs/ioctl.c

@@ -30,7 +30,7 @@
 
 #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)
 {
 	int rc = -ENOTTY; /* strange error - but the precedent */
@@ -47,13 +47,13 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
 
 	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);
 
 #ifdef CONFIG_CIFS_POSIX
 	tcon = cifs_sb->tcon;
-	if(tcon)
+	if (tcon)
 		caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
 	else {
 		rc = -EIO;
@@ -62,24 +62,24 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
 	}
 #endif /* CONFIG_CIFS_POSIX */
 
-	switch(command) {
+	switch (command) {
 		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;
 			else {
 				rc = -EACCES;
-				cFYI(1,("uids do not match"));
+				cFYI(1, ("uids do not match"));
 			}
 			break;
 #ifdef CONFIG_CIFS_POSIX
 		case FS_IOC_GETFLAGS:
-			if(CIFS_UNIX_EXTATTR_CAP & caps) {
+			if (CIFS_UNIX_EXTATTR_CAP & caps) {
 				if (pSMBFile == NULL)
 					break;
 				rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,
 					&ExtAttrBits, &ExtAttrMask);
-				if(rc == 0)
+				if (rc == 0)
 					rc = put_user(ExtAttrBits &
 						FS_FL_USER_VISIBLE,
 						(int __user *)arg);
@@ -87,8 +87,8 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
 			break;
 
 		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;
 					break;
 				}
@@ -96,16 +96,15 @@ int cifs_ioctl (struct inode * inode, struct file * filep,
 					break;
 				/* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,
 					extAttrBits, &ExtAttrMask);*/
-				
 			}
-			cFYI(1,("set flags not implemented yet"));
+			cFYI(1, ("set flags not implemented yet"));
 			break;
 #endif /* CONFIG_CIFS_POSIX */
 		default:
-			cFYI(1,("unsupported ioctl"));
+			cFYI(1, ("unsupported ioctl"));
 			break;
 	}
 
 	FreeXid(xid);
 	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
  *   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 */

+ 35 - 35
fs/splice.c

@@ -272,7 +272,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
 	struct page *page;
 	pgoff_t index, end_index;
 	loff_t isize;
-	size_t total_len;
 	int error, page_nr;
 	struct splice_pipe_desc spd = {
 		.pages = pages,
@@ -298,7 +297,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
 	 * Now fill in the holes:
 	 */
 	error = 0;
-	total_len = 0;
 
 	/*
 	 * Lookup the (hopefully) full range of pages we need.
@@ -415,43 +413,47 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
 
 				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;
 
 			/*
-			 * 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].len = this_len;
 		len -= this_len;
-		total_len += this_len;
 		loff = 0;
 		spd.nr_pages++;
 		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.
 	 */
 	while (page_nr < nr_pages)
@@ -478,10 +480,18 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
 {
 	ssize_t spliced;
 	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;
 	spliced = 0;
-
 	while (len) {
 		ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
 
@@ -644,7 +654,6 @@ find_page:
 	 * accessed, we are now done!
 	 */
 	mark_page_accessed(page);
-	balance_dirty_pages_ratelimited(mapping);
 out:
 	page_cache_release(page);
 	unlock_page(page);
@@ -815,6 +824,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
 			if (err)
 				ret = err;
 		}
+		balance_dirty_pages_ratelimited(mapping);
 	}
 
 	return ret;
@@ -868,6 +878,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 			if (err)
 				ret = err;
 		}
+		balance_dirty_pages_ratelimited(mapping);
 	}
 
 	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,
 			 unsigned int flags)
 {
-	loff_t isize, left;
 	int ret;
 
 	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))
 		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);
 }
 
@@ -1058,8 +1060,6 @@ out_release:
 	return ret;
 }
 
-EXPORT_SYMBOL(do_splice_direct);
-
 /*
  * 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

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

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

@@ -17,6 +17,18 @@
 #include <asm/mipsregs.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
 #include <asm/mipsmtregs.h>
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -236,10 +248,10 @@
 		.set	reorder
 		.set	noat
 		mfc0	a0, CP0_STATUS
-		ori	a0, 0x1f
-		xori	a0, 0x1f
-		mtc0	a0, CP0_STATUS
 		li	v1, 0xff00
+		ori	a0, STATMASK
+		xori	a0, STATMASK
+		mtc0	a0, CP0_STATUS
 		and	a0, v1
 		LONG_L	v0, PT_STATUS(sp)
 		nor	v1, $0, v1
@@ -249,10 +261,6 @@
 		LONG_L	$31, PT_R31(sp)
 		LONG_L	$28, PT_R28(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	$6,  PT_R6(sp)
 		LONG_L	$5,  PT_R5(sp)
@@ -273,16 +281,6 @@
 		.endm
 
 #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
 		.set	push
 		.set	reorder
@@ -385,9 +383,9 @@
 		.macro	CLI
 #if !defined(CONFIG_MIPS_MT_SMTC)
 		mfc0	t0, CP0_STATUS
-		li	t1, ST0_CU0 | 0x1f
+		li	t1, ST0_CU0 | STATMASK
 		or	t0, t1
-		xori	t0, 0x1f
+		xori	t0, STATMASK
 		mtc0	t0, CP0_STATUS
 #else /* CONFIG_MIPS_MT_SMTC */
 		/*
@@ -420,9 +418,9 @@
 		.macro	STI
 #if !defined(CONFIG_MIPS_MT_SMTC)
 		mfc0	t0, CP0_STATUS
-		li	t1, ST0_CU0 | 0x1f
+		li	t1, ST0_CU0 | STATMASK
 		or	t0, t1
-		xori	t0, 0x1e
+		xori	t0, STATMASK & ~1
 		mtc0	t0, CP0_STATUS
 #else /* CONFIG_MIPS_MT_SMTC */
 		/*
@@ -451,7 +449,8 @@
 		.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
  */
 		.macro	KMODE
@@ -482,9 +481,14 @@
 		move	ra, t0
 #endif /* CONFIG_MIPS_MT_SMTC */
 		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
-		xori	t0, 0x1e
+		xori	t0, STATMASK & ~1
 		mtc0	t0, CP0_STATUS
 #ifdef CONFIG_MIPS_MT_SMTC
 		_ehb

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

@@ -336,16 +336,20 @@
 #define __NR_epoll_pwait		(__NR_Linux + 313)
 #define __NR_ioprio_set			(__NR_Linux + 314)
 #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
  */
-#define __NR_Linux_syscalls		315
+#define __NR_Linux_syscalls		319
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux			4000
-#define __NR_O32_Linux_syscalls		315
+#define __NR_O32_Linux_syscalls		319
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
@@ -628,16 +632,20 @@
 #define __NR_epoll_pwait		(__NR_Linux + 272)
 #define __NR_ioprio_set			(__NR_Linux + 273)
 #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
  */
-#define __NR_Linux_syscalls		274
+#define __NR_Linux_syscalls		278
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux			5000
-#define __NR_64_Linux_syscalls		274
+#define __NR_64_Linux_syscalls		278
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
@@ -924,16 +932,20 @@
 #define __NR_epoll_pwait		(__NR_Linux + 276)
 #define __NR_ioprio_set			(__NR_Linux + 277)
 #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
  */
-#define __NR_Linux_syscalls		278
+#define __NR_Linux_syscalls		282
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux			6000
-#define __NR_N32_Linux_syscalls		278
+#define __NR_N32_Linux_syscalls		282
 
 #ifdef __KERNEL__
 

+ 2 - 1
include/linux/ata.h

@@ -151,6 +151,7 @@ enum {
 	ATA_CMD_WRITE_MULTI_EXT	= 0x39,
 	ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE,
 	ATA_CMD_SET_FEATURES	= 0xEF,
+	ATA_CMD_SET_MULTI	= 0xC6,
 	ATA_CMD_PACKET		= 0xA0,
 	ATA_CMD_VERIFY		= 0x40,
 	ATA_CMD_VERIFY_EXT	= 0x42,
@@ -249,7 +250,7 @@ enum ata_tf_protocols {
 	/* ATA taskfile protocols */
 	ATA_PROT_UNKNOWN,	/* unknown/invalid */
 	ATA_PROT_NODATA,	/* no data */
-	ATA_PROT_PIO,		/* PIO single sector */
+	ATA_PROT_PIO,		/* PIO data xfer */
 	ATA_PROT_DMA,		/* DMA */
 	ATA_PROT_NCQ,		/* NCQ */
 	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;
 	int		(*probe)(ide_drive_t *);
 	void		(*remove)(ide_drive_t *);
+	void		(*resume)(ide_drive_t *);
 	void		(*shutdown)(ide_drive_t *);
 #ifdef CONFIG_IDE_PROC_FS
 	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 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_sff_port_start (struct ata_port *ap);
 extern irqreturn_t ata_interrupt (int irq, void *dev_instance);
 extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
 			  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_27              0x054F
 #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_DEVICE_ID_IMS_TT128		0x9128

+ 15 - 15
include/linux/pipe_fs_i.h

@@ -16,6 +16,21 @@ struct pipe_buffer {
 	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:
  *
@@ -38,21 +53,6 @@ struct pipe_buf_operations {
 	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
    memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
 #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_OUTPUT	0x00000080  /* Is a sliced VBI output device */
 #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_AUDIO			0x00020000  /* has audio support */
@@ -616,12 +615,16 @@ struct v4l2_framebuffer
 #define V4L2_FBUF_CAP_BITMAP_CLIPPING	0x0008
 #define V4L2_FBUF_CAP_LOCAL_ALPHA	0x0010
 #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. */
 #define V4L2_FBUF_FLAG_PRIMARY		0x0001
 #define V4L2_FBUF_FLAG_OVERLAY		0x0002
 #define V4L2_FBUF_FLAG_CHROMAKEY	0x0004
 #define V4L2_FBUF_FLAG_LOCAL_ALPHA	0x0008
 #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
 {