diff options
78 files changed, 1416 insertions, 1039 deletions
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 0c9a9ff8cd2..ae985d1fcca 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/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 diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 23f3b118f71..7bcd5a1a85f 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/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 diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 1631035ffc2..532a2f3b42f 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/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 diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 2aa99426ac1..6bbe0f4ed8b 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/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 diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index c46e479c992..67edfa7ed93 100644 --- a/arch/mips/kernel/smp.c +++ b/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; diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S index 921207c4a83..20938a4cb52 100644 --- a/arch/mips/kernel/smtc-asm.S +++ b/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) diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index b361edb83dc..21eb5993a19 100644 --- a/arch/mips/kernel/smtc.c +++ b/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); } diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 3f58b6ac135..a7a17eb9bfc 100644 --- a/arch/mips/kernel/traps.c +++ b/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. */ diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c index dfa0acbd7fc..9f49da95aac 100644 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ b/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); diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 37735bfc3af..b41db9e7ab1 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/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; diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index fe8a1066aec..e5e023f50a0 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/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); diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 7baeaffefe7..545f330e59a 100644 --- a/drivers/ata/ahci.c +++ b/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 */ diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4733f009c7c..047eabd7536 100644 --- a/drivers/ata/libata-core.c +++ b/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); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b3900cfbd88..c228df298bd 100644 --- a/drivers/ata/libata-scsi.c +++ b/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; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index e35d13466c6..ce84805ba5f 100644 --- a/drivers/ata/libata-sff.c +++ b/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) diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index 1f647b64820..5525518204e 100644 --- a/drivers/ata/pata_isapnp.c +++ b/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; diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index fdbca25a394..35ab1a9f8e8 100644 --- a/drivers/char/agp/agp.h +++ b/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 diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 9c69f2e761f..d383168b75f 100644 --- a/drivers/char/agp/intel-agp.c +++ b/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), { } }; diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 7fff773f2df..dc2175c81f5 100644 --- a/drivers/ide/ide-disk.c +++ b/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, diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 3cebed77f55..41bfa4d21ab 100644 --- a/drivers/ide/ide-probe.c +++ b/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]); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 6002713a20a..0af0d1614f7 100644 --- a/drivers/ide/ide.c +++ b/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, diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index becb1a5648b..9db1be826e8 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/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); diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index f2c5a141ca1..0d51a11e81d 100644 --- a/drivers/ide/pci/generic.c +++ b/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; } } diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index fcbc5605b38..ce8a5449a57 100644 --- a/drivers/ide/pci/hpt366.c +++ b/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 }; diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 5faaff87d58..4bd4bf02e91 100644 --- a/drivers/ide/pci/it821x.c +++ b/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; + } } } diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 47bcd91c9b5..d9c4fd1ae99 100644 --- a/drivers/ide/pci/serverworks.c +++ b/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)); diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 2eb52b7a71d..32a0e66d2a2 100644 --- a/drivers/infiniband/core/cma.c +++ b/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) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index dc137dec230..5c6d05427a0 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/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; diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 38102520ffb..f40558d7647 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/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) | diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig index c120114c241..5c63c8e24ee 100644 --- a/drivers/media/common/Kconfig +++ b/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 diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile index 1a1c3bca55f..bff00b58bf6 100644 --- a/drivers/media/dvb/b2c2/Makefile +++ b/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 diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 34d7abc900d..6aba5b39ed1 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/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); diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c index ccc429cbbad..0f2d4b41556 100644 --- a/drivers/media/dvb/frontends/tda10086.c +++ b/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; diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c index 79f971dc52b..bd3ebc28483 100644 --- a/drivers/media/dvb/frontends/tda826x.c +++ b/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 diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 5cb3f54b548..4cca55170e2 100644 --- a/drivers/media/video/Kconfig +++ b/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--- diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h index 15012f88b80..91e9e90c14a 100644 --- a/drivers/media/video/ivtv/ivtv-cards.h +++ b/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 */ diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index e29f949adf5..efc66355339 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/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; diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 552f04511ea..e6e56f175f3 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/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 */ diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 8976487a65f..555d5e6369c 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/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); } diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 1989ec1cb97..57af1762de1 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/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: diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index c3a047b381b..ba98bf054f2 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/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 diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c index ccfcef1ad91..a04f9387f63 100644 --- a/drivers/media/video/ivtv/ivtv-queue.c +++ b/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; } diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h index 903edd4b438..2ed8d548255 100644 --- a/drivers/media/video/ivtv/ivtv-queue.h +++ b/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); } diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 01a41a844a3..6af88ae9295 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/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) { diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c index 5efa5a86781..3ba46e07ea1 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.c +++ b/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; diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h index cdaea697b3e..ec211b49702 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.h +++ b/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); diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index 74839f98b7c..c1a392e4717 100644 --- a/drivers/media/video/saa7111.c +++ b/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); diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index 9118a6227ea..7df071eb0a3 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/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); } } diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h index bd6f6422ed5..c759d00d701 100644 --- a/drivers/media/video/usbvision/usbvision.h +++ b/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 */ diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index c1dfd03d559..41bfb5dfe6f 100644 --- a/drivers/mmc/core/sd.c +++ b/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) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e37943c314c..5b00c194b62 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/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 { diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index f967226d750..52b63f11ddd 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/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]; diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c index 437d78ad091..39253d0c159 100644 --- a/drivers/net/mlx4/cq.c +++ b/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; }; diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index 0f11adb8eb4..27a82cecd69 100644 --- a/drivers/net/mlx4/eq.c +++ b/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) diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index cfa5cc07233..e7ca118c8df 100644 --- a/drivers/net/mlx4/fw.c +++ b/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); diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c index 65854f9e9c7..9ae951bf6aa 100644 --- a/drivers/net/mlx4/intf.c +++ b/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); diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 20b8c0d3ced..d4172937025 100644 --- a/drivers/net/mlx4/main.c +++ b/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 diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index b33864dab17..d0808fa3ec8 100644 --- a/drivers/net/mlx4/mr.c +++ b/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)); diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 6017c465440..07838b2ac1c 100644 --- a/fs/cifs/cifs_debug.c +++ b/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; } diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 793c4b95c16..701e9a9185f 100644 --- a/fs/cifs/cifs_unicode.c +++ b/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]); } diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index d38c69b591c..7c04752b76c 100644 --- a/fs/cifs/cifsfs.c +++ b/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; } diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 14de58fa143..57419a17668 100644 --- a/fs/cifs/cifssmb.c +++ b/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; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 216fb625843..f4e92661b22 100644 --- a/fs/cifs/connect.c +++ b/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); } diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index e5210519ac4..8e86aaceb68 100644 --- a/fs/cifs/dir.c +++ b/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) diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index da12b482ebe..8e375bb4b37 100644 --- a/fs/cifs/fcntl.c +++ b/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; } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 3e87dad3367..f0ff12b3f39 100644 --- a/fs/cifs/inode.c +++ b/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); */ diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index e34c7db00f6..a414f1775ae 100644 --- a/fs/cifs/ioctl.c +++ b/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; -} +} diff --git a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h index aede606132a..8b69fcceb59 100644 --- a/fs/cifs/rfc1002pdu.h +++ b/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 */ diff --git a/fs/splice.c b/fs/splice.c index 12f28281d2b..cb211360273 100644 --- a/fs/splice.c +++ b/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 diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index d995413e11f..ffe245b4258 100644 --- a/include/asm-mips/bitops.h +++ b/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> diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 7afa1fdf70c..ed33366b85b 100644 --- a/include/asm-mips/stackframe.h +++ b/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 diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 91c306fcfb7..59d6fec8fbf 100644 --- a/include/asm-mips/unistd.h +++ b/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__ diff --git a/include/linux/ata.h b/include/linux/ata.h index edb31bfff68..703febb2df3 100644 --- a/include/linux/ata.h +++ b/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*/ diff --git a/include/linux/ide.h b/include/linux/ide.h index 07aba87d369..1e365acdd36 100644 --- a/include/linux/ide.h +++ b/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; diff --git a/include/linux/libata.h b/include/linux/libata.h index a6a3113120a..745c4f9b4ca 100644 --- a/include/linux/libata.h +++ b/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); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 6a115cffea3..9a03b47da60 100644 --- a/include/linux/pci_ids.h +++ b/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 diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 8bcbc54e1b4..c8884f97122 100644 --- a/include/linux/pipe_fs_i.h +++ b/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 diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index e7560389079..d16a2b57dc8 100644 --- a/include/linux/videodev2.h +++ b/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 { |