mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 03:10:12 +00:00
Merge branch 'master' into upstream-fixes
This commit is contained in:
commit
b232923966
78 changed files with 1416 additions and 1039 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -611,12 +611,12 @@ void smtc_cpus_done(void)
|
|||
int setup_irq_smtc(unsigned int irq, struct irqaction * new,
|
||||
unsigned long hwmask)
|
||||
{
|
||||
#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
|
||||
unsigned int vpe = current_cpu_data.vpe_id;
|
||||
|
||||
irq_hwmask[irq] = hwmask;
|
||||
#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
|
||||
vpemask[vpe][irq - MIPSCPU_INT_BASE] = 1;
|
||||
#endif
|
||||
irq_hwmask[irq] = hwmask;
|
||||
|
||||
return setup_irq(irq, new);
|
||||
}
|
||||
|
|
|
@ -11,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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
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_gmch(u16 device)
|
||||
{
|
||||
struct pci_dev *i810_dev;
|
||||
struct pci_dev *gmch_device;
|
||||
|
||||
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 int find_i830(u16 device)
|
||||
{
|
||||
struct pci_dev *i830_dev;
|
||||
|
||||
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),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
|
|||
|
||||
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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.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 = 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.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;
|
||||
|
|
|
@ -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) |
|
||||
|
|
|
@ -4,5 +4,6 @@ config VIDEO_SAA7146
|
|||
|
||||
config VIDEO_SAA7146_VV
|
||||
tristate
|
||||
depends on VIDEO_DEV
|
||||
select VIDEO_BUF
|
||||
select VIDEO_SAA7146
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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---
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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 void ivtv_pio_work_handler(struct ivtv *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;
|
||||
|
||||
/* 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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
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;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
lookupFlag_read(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
int count, int *eof, void *data)
|
||||
{
|
||||
int len;
|
||||
|
||||
|
@ -860,15 +866,15 @@ security_flags_write(struct file *file, const char __user *buffer,
|
|||
char flags_string[12];
|
||||
char c;
|
||||
|
||||
if((count < 1) || (count > 11))
|
||||
if ((count < 1) || (count > 11))
|
||||
return -EINVAL;
|
||||
|
||||
memset(flags_string, 0, 12);
|
||||
|
||||
if(copy_from_user(flags_string, buffer, count))
|
||||
if (copy_from_user(flags_string, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
if(count < 3) {
|
||||
if (count < 3) {
|
||||
/* single char or single char followed by null */
|
||||
c = flags_string[0];
|
||||
if (c == '0' || c == 'n' || c == 'N')
|
||||
|
@ -881,15 +887,15 @@ security_flags_write(struct file *file, const char __user *buffer,
|
|||
|
||||
flags = simple_strtoul(flags_string, NULL, 0);
|
||||
|
||||
cFYI(1,("sec flags 0x%x", flags));
|
||||
cFYI(1, ("sec flags 0x%x", flags));
|
||||
|
||||
if(flags <= 0) {
|
||||
cERROR(1,("invalid security flags %s",flags_string));
|
||||
if (flags <= 0) {
|
||||
cERROR(1, ("invalid security flags %s", flags_string));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(flags & ~CIFSSEC_MASK) {
|
||||
cERROR(1,("attempt to set unsupported security flags 0x%x",
|
||||
if (flags & ~CIFSSEC_MASK) {
|
||||
cERROR(1, ("attempt to set unsupported security flags 0x%x",
|
||||
flags & ~CIFSSEC_MASK));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -6,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]);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
184
fs/cifs/dir.c
184
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 @@ build_path_from_dentry(struct dentry *direntry)
|
|||
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 @@ build_path_from_dentry(struct dentry *direntry)
|
|||
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 @@ build_path_from_dentry(struct dentry *direntry)
|
|||
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(struct inode *inode, struct dentry *direntry, int mode,
|
|||
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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -986,7 +986,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
|
|||
* 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 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
|
|||
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); */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
70
fs/splice.c
70
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 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
|
|||
* 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 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
|
|||
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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue