summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2007-06-12 22:34:34 -0400
committerJeff Garzik <jeff@garzik.org>2007-06-12 22:34:34 -0400
commitb232923966f1210e1183353bbd1d52ee53b79fbf (patch)
treee90c72b2cb400af53e1f92aff0af122782d7f65c /drivers
parentbca1a5518cab2d58c766863c61ee4ef5f1cc4caa (diff)
parent99f9f3d49cbc7d944476f6fde53a77ec789ab2aa (diff)
downloadblackbird-op-linux-b232923966f1210e1183353bbd1d52ee53b79fbf.tar.gz
blackbird-op-linux-b232923966f1210e1183353bbd1d52ee53b79fbf.zip
Merge branch 'master' into upstream-fixes
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c24
-rw-r--r--drivers/ata/libata-core.c62
-rw-r--r--drivers/ata/libata-scsi.c67
-rw-r--r--drivers/ata/libata-sff.c37
-rw-r--r--drivers/ata/pata_isapnp.c1
-rw-r--r--drivers/char/agp/agp.h6
-rw-r--r--drivers/char/agp/intel-agp.c576
-rw-r--r--drivers/ide/ide-disk.c12
-rw-r--r--drivers/ide/ide-probe.c12
-rw-r--r--drivers/ide/ide.c9
-rw-r--r--drivers/ide/pci/amd74xx.c12
-rw-r--r--drivers/ide/pci/generic.c37
-rw-r--r--drivers/ide/pci/hpt366.c8
-rw-r--r--drivers/ide/pci/it821x.c34
-rw-r--r--drivers/ide/pci/serverworks.c51
-rw-r--r--drivers/infiniband/core/cma.c4
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c33
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/media/common/Kconfig1
-rw-r--r--drivers/media/dvb/b2c2/Makefile7
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c3
-rw-r--r--drivers/media/dvb/frontends/tda10086.c21
-rw-r--r--drivers/media/dvb/frontends/tda826x.c4
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h16
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c16
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c45
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c204
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.c31
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.h39
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.h2
-rw-r--r--drivers/media/video/saa7111.c49
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c82
-rw-r--r--drivers/media/video/usbvision/usbvision.h1
-rw-r--r--drivers/mmc/core/sd.c26
-rw-r--r--drivers/mmc/host/at91_mci.c5
-rw-r--r--drivers/mmc/host/au1xmmc.c3
-rw-r--r--drivers/net/mlx4/cq.c2
-rw-r--r--drivers/net/mlx4/eq.c4
-rw-r--r--drivers/net/mlx4/fw.c27
-rw-r--r--drivers/net/mlx4/intf.c3
-rw-r--r--drivers/net/mlx4/main.c2
-rw-r--r--drivers/net/mlx4/mr.c8
47 files changed, 969 insertions, 628 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 7baeaffefe7a..545f330e59a5 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -426,6 +426,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad3), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad4), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad5), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad6), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad7), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad8), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci }, /* MCP77 */
/* SiS */
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 4733f009c7c9..047eabd75363 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1727,7 +1727,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
/* sanity check */
rc = -EINVAL;
- reason = "device reports illegal type";
+ reason = "device reports invalid type";
if (class == ATA_DEV_ATA) {
if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
@@ -1900,6 +1900,13 @@ int ata_dev_configure(struct ata_device *dev)
if (ata_msg_probe(ap))
ata_dump_id(id);
+ /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
+ ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
+ sizeof(fwrevbuf));
+
+ ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
+ sizeof(modelbuf));
+
/* ATA-specific feature tests */
if (dev->class == ATA_DEV_ATA) {
if (ata_id_is_cfa(id)) {
@@ -1914,13 +1921,6 @@ int ata_dev_configure(struct ata_device *dev)
dev->n_sectors = ata_id_n_sectors(id);
- /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
- ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
- sizeof(fwrevbuf));
-
- ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
- sizeof(modelbuf));
-
if (dev->id[59] & 0x100)
dev->multi_count = dev->id[59] & 0xff;
@@ -2009,7 +2009,9 @@ int ata_dev_configure(struct ata_device *dev)
/* print device info to dmesg */
if (ata_msg_drv(ap) && print_info)
- ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s%s\n",
+ ata_dev_printk(dev, KERN_INFO,
+ "ATAPI: %s, %s, max %s%s\n",
+ modelbuf, fwrevbuf,
ata_mode_string(xfer_mask),
cdb_intr_string);
}
@@ -3059,22 +3061,28 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
}
}
- /* if device 1 was found in ata_devchk, wait for
- * register access, then wait for BSY to clear
+ /* if device 1 was found in ata_devchk, wait for register
+ * access briefly, then wait for BSY to clear.
*/
- while (dev1) {
- u8 nsect, lbal;
+ if (dev1) {
+ int i;
ap->ops->dev_select(ap, 1);
- nsect = ioread8(ioaddr->nsect_addr);
- lbal = ioread8(ioaddr->lbal_addr);
- if ((nsect == 1) && (lbal == 1))
- break;
- if (time_after(jiffies, deadline))
- return -EBUSY;
- msleep(50); /* give drive a breather */
- }
- if (dev1) {
+
+ /* Wait for register access. Some ATAPI devices fail
+ * to set nsect/lbal after reset, so don't waste too
+ * much time on it. We're gonna wait for !BSY anyway.
+ */
+ for (i = 0; i < 2; i++) {
+ u8 nsect, lbal;
+
+ nsect = ioread8(ioaddr->nsect_addr);
+ lbal = ioread8(ioaddr->lbal_addr);
+ if ((nsect == 1) && (lbal == 1))
+ break;
+ msleep(50); /* give drive a breather */
+ }
+
rc = ata_wait_ready(ap, deadline);
if (rc) {
if (rc != -ENODEV)
@@ -3769,6 +3777,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA },
{ "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
{ "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
+ { "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */
/* Weird ATAPI devices */
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 |
@@ -3791,6 +3800,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, },
{ "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, },
{ "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, },
+ /* Drives which do spurious command completion */
+ { "HTS541680J9SA00", "SB2IC7EP", ATA_HORKAGE_NONCQ, },
/* Devices with NCQ limits */
@@ -6313,7 +6324,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
/* init sata_spd_limit to the current value */
if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
int spd = (scontrol >> 4) & 0xf;
- ap->hw_sata_spd_limit &= (1 << spd) - 1;
+ if (spd)
+ ap->hw_sata_spd_limit &= (1 << spd) - 1;
}
ap->sata_spd_limit = ap->hw_sata_spd_limit;
@@ -6433,6 +6445,9 @@ int ata_host_activate(struct ata_host *host, int irq,
if (rc)
devm_free_irq(host->dev, irq, host);
+ /* Used to print device info at probe */
+ host->irq = irq;
+
return rc;
}
@@ -6818,6 +6833,7 @@ EXPORT_SYMBOL_GPL(ata_check_status);
EXPORT_SYMBOL_GPL(ata_altstatus);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
+EXPORT_SYMBOL_GPL(ata_sff_port_start);
EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_do_set_mode);
EXPORT_SYMBOL_GPL(ata_data_xfer);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index b3900cfbd880..c228df298bd8 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1363,12 +1363,22 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
* schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
* cache
*/
- if (ap->ops->error_handler &&
- !need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) &&
- ((qc->tf.feature == SETFEATURES_WC_ON) ||
- (qc->tf.feature == SETFEATURES_WC_OFF))) {
- ap->eh_info.action |= ATA_EH_REVALIDATE;
- ata_port_schedule_eh(ap);
+ if (ap->ops->error_handler && !need_sense) {
+ switch (qc->tf.command) {
+ case ATA_CMD_SET_FEATURES:
+ if ((qc->tf.feature == SETFEATURES_WC_ON) ||
+ (qc->tf.feature == SETFEATURES_WC_OFF)) {
+ ap->eh_info.action |= ATA_EH_REVALIDATE;
+ ata_port_schedule_eh(ap);
+ }
+ break;
+
+ case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
+ case ATA_CMD_SET_MULTI: /* multi_count changed */
+ ap->eh_info.action |= ATA_EH_REVALIDATE;
+ ata_port_schedule_eh(ap);
+ break;
+ }
}
/* For ATA pass thru (SAT) commands, generate a sense block if
@@ -2506,22 +2516,21 @@ ata_scsi_map_proto(u8 byte1)
return ATA_PROT_NODATA;
case 6: /* DMA */
+ case 10: /* UDMA Data-in */
+ case 11: /* UDMA Data-Out */
return ATA_PROT_DMA;
case 4: /* PIO Data-in */
case 5: /* PIO Data-out */
return ATA_PROT_PIO;
- case 10: /* Device Reset */
case 0: /* Hard Reset */
case 1: /* SRST */
- case 2: /* Bus Idle */
- case 7: /* Packet */
- case 8: /* DMA Queued */
- case 9: /* Device Diagnostic */
- case 11: /* UDMA Data-in */
- case 12: /* UDMA Data-Out */
- case 13: /* FPDMA */
+ case 8: /* Device Diagnostic */
+ case 9: /* Device Reset */
+ case 7: /* DMA Queued */
+ case 12: /* FPDMA */
+ case 15: /* Return Response Info */
default: /* Reserved */
break;
}
@@ -2552,10 +2561,6 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
goto invalid_fld;
- if (cdb[1] & 0xe0)
- /* PIO multi not supported yet */
- goto invalid_fld;
-
/*
* 12 and 16 byte CDBs use different offsets to
* provide the various register values.
@@ -2600,12 +2605,26 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->device = cdb[8];
tf->command = cdb[9];
}
- /*
- * If slave is possible, enforce correct master/slave bit
- */
- if (qc->ap->flags & ATA_FLAG_SLAVE_POSS)
- tf->device = qc->dev->devno ?
- tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+
+ /* enforce correct master/slave bit */
+ tf->device = dev->devno ?
+ tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+
+ /* sanity check for pio multi commands */
+ if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf))
+ goto invalid_fld;
+
+ if (is_multi_taskfile(tf)) {
+ unsigned int multi_count = 1 << (cdb[1] >> 5);
+
+ /* compare the passed through multi_count
+ * with the cached multi_count of libata
+ */
+ if (multi_count != dev->multi_count)
+ ata_dev_printk(dev, KERN_WARNING,
+ "invalid multi_count %u ignored\n",
+ multi_count);
+ }
/* READ/WRITE LONG use a non-standard sect_size */
qc->sect_size = ATA_SECT_SIZE;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index e35d13466c69..ce84805ba5f1 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -80,25 +80,25 @@ u8 ata_dummy_irq_on (struct ata_port *ap) { return 0; }
u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
{
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
- u8 host_stat, post_stat, status;
+ u8 host_stat = 0, post_stat = 0, status;
status = ata_busy_wait(ap, bits, 1000);
if (status & bits)
if (ata_msg_err(ap))
printk(KERN_ERR "abnormal status 0x%X\n", status);
- /* get controller status; clear intr, err bits */
- host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
- ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-
- post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ if (ap->ioaddr.bmdma_addr) {
+ /* get controller status; clear intr, err bits */
+ host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+ ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ }
if (ata_msg_intr(ap))
printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
__FUNCTION__,
host_stat, post_stat, status);
-
return status;
}
@@ -516,6 +516,27 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
ata_bmdma_stop(qc);
}
+/**
+ * ata_sff_port_start - Set port up for dma.
+ * @ap: Port to initialize
+ *
+ * Called just after data structures for each port are
+ * initialized. Allocates space for PRD table if the device
+ * is DMA capable SFF.
+ *
+ * May be used as the port_start() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+
+int ata_sff_port_start(struct ata_port *ap)
+{
+ if (ap->ioaddr.bmdma_addr)
+ return ata_port_start(ap);
+ return 0;
+}
+
#ifdef CONFIG_PCI
static int ata_resources_present(struct pci_dev *pdev, int port)
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 1f647b648204..5525518204e6 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -77,7 +77,6 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
struct ata_host *host;
struct ata_port *ap;
void __iomem *cmd_addr, *ctl_addr;
- int rc;
if (pnp_port_valid(idev, 0) == 0)
return -ENODEV;
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index fdbca25a3948..35ab1a9f8e8b 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -176,7 +176,7 @@ struct agp_bridge_data {
#define I830_GMCH_MEM_MASK 0x1
#define I830_GMCH_MEM_64M 0x1
#define I830_GMCH_MEM_128M 0
-#define I830_GMCH_GMS_MASK 0x70
+#define I830_GMCH_GMS_MASK 0xF0
#define I830_GMCH_GMS_DISABLED 0x00
#define I830_GMCH_GMS_LOCAL 0x10
#define I830_GMCH_GMS_STOLEN_512 0x20
@@ -231,6 +231,10 @@ struct agp_bridge_data {
#define I965_PGETBL_SIZE_512KB (0 << 1)
#define I965_PGETBL_SIZE_256KB (1 << 1)
#define I965_PGETBL_SIZE_128KB (2 << 1)
+#define G33_PGETBL_SIZE_MASK (3 << 8)
+#define G33_PGETBL_SIZE_1M (1 << 8)
+#define G33_PGETBL_SIZE_2M (2 << 8)
+
#define I810_DRAM_CTL 0x3000
#define I810_DRAM_ROW_0 0x00000001
#define I810_DRAM_ROW_0_SDRAM 0x00000001
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 9c69f2e761f5..d383168b75fa 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -20,6 +20,14 @@
#define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2
#define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00
#define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02
+#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
+#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
+#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
+#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
+#define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0
+#define PCI_DEVICE_ID_INTEL_Q35_IG 0x29B2
+#define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0
+#define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2
#define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
@@ -27,6 +35,9 @@
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
+#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB)
extern int agp_memory_reserved;
@@ -53,6 +64,8 @@ extern int agp_memory_reserved;
#define I915_PTEADDR 0x1C
#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4)
#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4)
+#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4)
+#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4)
/* Intel 965G registers */
#define I965_MSAC 0x62
@@ -86,11 +99,18 @@ static struct gatt_mask intel_i810_masks[] =
.type = INTEL_AGP_CACHED_MEMORY}
};
-static struct _intel_i810_private {
- struct pci_dev *i810_dev; /* device one */
- volatile u8 __iomem *registers;
+static struct _intel_private {
+ struct pci_dev *pcidev; /* device one */
+ u8 __iomem *registers;
+ u32 __iomem *gtt; /* I915G */
int num_dcache_entries;
-} intel_i810_private;
+ /* gtt_entries is the number of gtt entries that are already mapped
+ * to stolen memory. Stolen memory is larger than the memory mapped
+ * through gtt_entries, as it includes some reserved space for the BIOS
+ * popup and for the GTT.
+ */
+ int gtt_entries; /* i830+ */
+} intel_private;
static int intel_i810_fetch_size(void)
{
@@ -127,32 +147,32 @@ static int intel_i810_configure(void)
current_size = A_SIZE_FIX(agp_bridge->current_size);
- if (!intel_i810_private.registers) {
- pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
+ if (!intel_private.registers) {
+ pci_read_config_dword(intel_private.pcidev, I810_MMADDR, &temp);
temp &= 0xfff80000;
- intel_i810_private.registers = ioremap(temp, 128 * 4096);
- if (!intel_i810_private.registers) {
+ intel_private.registers = ioremap(temp, 128 * 4096);
+ if (!intel_private.registers) {
printk(KERN_ERR PFX "Unable to remap memory.\n");
return -ENOMEM;
}
}
- if ((readl(intel_i810_private.registers+I810_DRAM_CTL)
+ if ((readl(intel_private.registers+I810_DRAM_CTL)
& I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
/* This will need to be dynamically assigned */
printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
- intel_i810_private.num_dcache_entries = 1024;
+ intel_private.num_dcache_entries = 1024;
}
- pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
+ pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
- writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_i810_private.registers+I810_PGETBL_CTL);
- readl(intel_i810_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
+ writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+ readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
if (agp_bridge->driver->needs_scratch_page) {
for (i = 0; i < current_size->num_entries; i++) {
- writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
- readl(intel_i810_private.registers+I810_PTE_BASE+(i*4)); /* PCI posting. */
+ writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
+ readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI posting. */
}
}
global_cache_flush();
@@ -161,9 +181,9 @@ static int intel_i810_configure(void)
static void intel_i810_cleanup(void)
{
- writel(0, intel_i810_private.registers+I810_PGETBL_CTL);
- readl(intel_i810_private.registers); /* PCI Posting. */
- iounmap(intel_i810_private.registers);
+ writel(0, intel_private.registers+I810_PGETBL_CTL);
+ readl(intel_private.registers); /* PCI Posting. */
+ iounmap(intel_private.registers);
}
static void intel_i810_tlbflush(struct agp_memory *mem)
@@ -261,9 +281,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
global_cache_flush();
for (i = pg_start; i < (pg_start + mem->page_count); i++) {
writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID,
- intel_i810_private.registers+I810_PTE_BASE+(i*4));
+ intel_private.registers+I810_PTE_BASE+(i*4));
}
- readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
break;
case AGP_PHYS_MEMORY:
case AGP_NORMAL_MEMORY:
@@ -273,9 +293,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
writel(agp_bridge->driver->mask_memory(agp_bridge,
mem->memory[i],
mask_type),
- intel_i810_private.registers+I810_PTE_BASE+(j*4));
+ intel_private.registers+I810_PTE_BASE+(j*4));
}
- readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
break;
default:
goto out_err;
@@ -298,9 +318,9 @@ static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
return 0;
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
- writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
+ writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
}
- readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
agp_bridge->driver->tlb_flush(mem);
return 0;
@@ -354,7 +374,7 @@ static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
struct agp_memory *new;
if (type == AGP_DCACHE_MEMORY) {
- if (pg_count != intel_i810_private.num_dcache_entries)
+ if (pg_count != intel_private.num_dcache_entries)
return NULL;
new = agp_create_memory(1);
@@ -404,18 +424,6 @@ static struct aper_size_info_fixed intel_i830_sizes[] =
{512, 131072, 7},
};
-static struct _intel_i830_private {
- struct pci_dev *i830_dev; /* device one */
- volatile u8 __iomem *registers;
- volatile u32 __iomem *gtt; /* I915G */
- /* gtt_entries is the number of gtt entries that are already mapped
- * to stolen memory. Stolen memory is larger than the memory mapped
- * through gtt_entries, as it includes some reserved space for the BIOS
- * popup and for the GTT.
- */
- int gtt_entries;
-} intel_i830_private;
-
static void intel_i830_init_gtt_entries(void)
{
u16 gmch_ctrl;
@@ -429,7 +437,7 @@ static void intel_i830_init_gtt_entries(void)
if (IS_I965) {
u32 pgetbl_ctl;
- pgetbl_ctl = readl(intel_i830_private.registers+I810_PGETBL_CTL);
+ pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);
/* The 965 has a field telling us the size of the GTT,
* which may be larger than what is necessary to map the
@@ -451,6 +459,22 @@ static void intel_i830_init_gtt_entries(void)
size = 512;
}
size += 4; /* add in BIOS popup space */
+ } else if (IS_G33) {
+ /* G33's GTT size defined in gmch_ctrl */
+ switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
+ case G33_PGETBL_SIZE_1M:
+ size = 1024;
+ break;
+ case G33_PGETBL_SIZE_2M:
+ size = 2048;
+ break;
+ default:
+ printk(KERN_INFO PFX "Unknown page table size 0x%x, "
+ "assuming 512KB\n",
+ (gmch_ctrl & G33_PGETBL_SIZE_MASK));
+ size = 512;
+ }
+ size += 4;
} else {
/* On previous hardware, the GTT size was just what was
* required to map the aperture.
@@ -471,7 +495,7 @@ static void intel_i830_init_gtt_entries(void)
gtt_entries = MB(8) - KB(size);
break;
case I830_GMCH_GMS_LOCAL:
- rdct = readb(intel_i830_private.registers+I830_RDRAM_CHANNEL_TYPE);
+ rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE);
gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
MB(ddt[I830_RDRAM_DDT(rdct)]);
local = 1;
@@ -502,7 +526,8 @@ static void intel_i830_init_gtt_entries(void)
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965 )
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+ IS_I965 || IS_G33)
gtt_entries = MB(48) - KB(size);
else
gtt_entries = 0;
@@ -512,10 +537,24 @@ static void intel_i830_init_gtt_entries(void)
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+ IS_I965 || IS_G33)
gtt_entries = MB(64) - KB(size);
else
gtt_entries = 0;
+ break;
+ case G33_GMCH_GMS_STOLEN_128M:
+ if (IS_G33)
+ gtt_entries = MB(128) - KB(size);
+ else
+ gtt_entries = 0;
+ break;
+ case G33_GMCH_GMS_STOLEN_256M:
+ if (IS_G33)
+ gtt_entries = MB(256) - KB(size);
+ else
+ gtt_entries = 0;
+ break;
default:
gtt_entries = 0;
break;
@@ -529,7 +568,7 @@ static void intel_i830_init_gtt_entries(void)
"No pre-allocated video memory detected.\n");
gtt_entries /= KB(4);
- intel_i830_private.gtt_entries = gtt_entries;
+ intel_private.gtt_entries = gtt_entries;
}
/* The intel i830 automatically initializes the agp aperture during POST.
@@ -547,14 +586,14 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
num_entries = size->num_entries;
agp_bridge->gatt_table_real = NULL;
- pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
+ pci_read_config_dword(intel_private.pcidev,I810_MMADDR,&temp);
temp &= 0xfff80000;
- intel_i830_private.registers = ioremap(temp,128 * 4096);
- if (!intel_i830_private.registers)
+ intel_private.registers = ioremap(temp,128 * 4096);
+ if (!intel_private.registers)
return -ENOMEM;
- temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+ temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush(); /* FIXME: ?? */
/* we have to call this as early as possible after the MMIO base address is known */
@@ -614,20 +653,20 @@ static int intel_i830_configure(void)
current_size = A_SIZE_FIX(agp_bridge->current_size);
- pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
+ pci_read_config_dword(intel_private.pcidev,I810_GMADDR,&temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
gmch_ctrl |= I830_GMCH_ENABLED;
pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
- writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
- readl(intel_i830_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
+ writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+ readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
if (agp_bridge->driver->needs_scratch_page) {
- for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
- writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
- readl(intel_i830_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
+ for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+ writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
+ readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
}
}
@@ -637,7 +676,7 @@ static int intel_i830_configure(void)
static void intel_i830_cleanup(void)
{
- iounmap(intel_i830_private.registers);
+ iounmap(intel_private.registers);
}
static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type)
@@ -653,9 +692,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
temp = agp_bridge->current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
- if (pg_start < intel_i830_private.gtt_entries) {
- printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
- pg_start,intel_i830_private.gtt_entries);
+ if (pg_start < intel_private.gtt_entries) {
+ printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
+ pg_start,intel_private.gtt_entries);
printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
goto out_err;
@@ -683,9 +722,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
writel(agp_bridge->driver->mask_memory(agp_bridge,
mem->memory[i], mask_type),
- intel_i830_private.registers+I810_PTE_BASE+(j*4));
+ intel_private.registers+I810_PTE_BASE+(j*4));
}
- readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
agp_bridge->driver->tlb_flush(mem);
out:
@@ -703,15 +742,15 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
if (mem->page_count == 0)
return 0;
- if (pg_start < intel_i830_private.gtt_entries) {
+ if (pg_start < intel_private.gtt_entries) {
printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
return -EINVAL;
}
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
- writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
+ writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
}
- readl(intel_i830_private.registers+I810_PTE_BASE+((i-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
agp_bridge->driver->tlb_flush(mem);
return 0;
@@ -734,7 +773,7 @@ static int intel_i915_configure(void)
current_size = A_SIZE_FIX(agp_bridge->current_size);
- pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp);
+ pci_read_config_dword(intel_private.pcidev, I915_GMADDR, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
@@ -742,13 +781,13 @@ static int intel_i915_configure(void)
gmch_ctrl |= I830_GMCH_ENABLED;
pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
- writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
- readl(intel_i830_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
+ writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+ readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
if (agp_bridge->driver->needs_scratch_page) {
- for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
- writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
- readl(intel_i830_private.gtt+i); /* PCI Posting. */
+ for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+ writel(agp_bridge->scratch_page, intel_private.gtt+i);
+ readl(intel_private.gtt+i); /* PCI Posting. */
}
}
@@ -758,8 +797,8 @@ static int intel_i915_configure(void)
static void intel_i915_cleanup(void)
{
- iounmap(intel_i830_private.gtt);
- iounmap(intel_i830_private.registers);
+ iounmap(intel_private.gtt);
+ iounmap(intel_private.registers);
}
static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
@@ -776,9 +815,9 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
temp = agp_bridge->current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
- if (pg_start < intel_i830_private.gtt_entries) {
- printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
- pg_start,intel_i830_private.gtt_entries);
+ if (pg_start < intel_private.gtt_entries) {
+ printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
+ pg_start,intel_private.gtt_entries);
printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
goto out_err;
@@ -805,10 +844,10 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
writel(agp_bridge->driver->mask_memory(agp_bridge,
- mem->memory[i], mask_type), intel_i830_private.gtt+j);
+ mem->memory[i], mask_type), intel_private.gtt+j);
}
- readl(intel_i830_private.gtt+j-1);
+ readl(intel_private.gtt+j-1);
agp_bridge->driver->tlb_flush(mem);
out:
@@ -826,15 +865,15 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
if (mem->page_count == 0)
return 0;
- if (pg_start < intel_i830_private.gtt_entries) {
+ if (pg_start < intel_private.gtt_entries) {
printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
return -EINVAL;
}
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
- writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
+ writel(agp_bridge->scratch_page, intel_private.gtt+i);
}
- readl(intel_i830_private.gtt+i-1);
+ readl(intel_private.gtt+i-1);
agp_bridge->driver->tlb_flush(mem);
return 0;
@@ -850,7 +889,7 @@ static int intel_i9xx_fetch_size(void)
int aper_size; /* size in megabytes */
int i;
- aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
+ aper_size = pci_resource_len(intel_private.pcidev, 2) / MB(1);
for (i = 0; i < num_sizes; i++) {
if (aper_size == intel_i830_sizes[i].size) {
@@ -878,20 +917,20 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
num_entries = size->num_entries;
agp_bridge->gatt_table_real = NULL;
- pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
- pci_read_config_dword(intel_i830_private.i830_dev, I915_PTEADDR,&temp2);
+ pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
+ pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2);
- intel_i830_private.gtt = ioremap(temp2, 256 * 1024);
- if (!intel_i830_private.gtt)
+ intel_private.gtt = ioremap(temp2, 256 * 1024);
+ if (!intel_private.gtt)
return -ENOMEM;
temp &= 0xfff80000;
- intel_i830_private.registers = ioremap(temp,128 * 4096);
- if (!intel_i830_private.registers)
+ intel_private.registers = ioremap(temp,128 * 4096);
+ if (!intel_private.registers)
return -ENOMEM;
- temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+ temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush(); /* FIXME: ? */
/* we have to call this as early as possible after the MMIO base address is known */
@@ -938,20 +977,20 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
num_entries = size->num_entries;
agp_bridge->gatt_table_real = NULL;
- pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
+ pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
temp &= 0xfff00000;
- intel_i830_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
+ intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
- if (!intel_i830_private.gtt)
+ if (!intel_private.gtt)
return -ENOMEM;
- intel_i830_private.registers = ioremap(temp,128 * 4096);
- if (!intel_i830_private.registers)
+ intel_private.registers = ioremap(temp,128 * 4096);
+ if (!intel_private.registers)
return -ENOMEM;
- temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+ temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush(); /* FIXME: ? */
/* we have to call this as early as possible after the MMIO base address is known */
@@ -1722,41 +1761,126 @@ static const struct agp_bridge_driver intel_7505_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static int find_i810(u16 device)
-{
- struct pci_dev *i810_dev;
-
- i810_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
- if (!i810_dev)
- return 0;
- intel_i810_private.i810_dev = i810_dev;
- return 1;
-}
+static const struct agp_bridge_driver intel_g33_driver = {
+ .owner = THIS_MODULE,
+ .aperture_sizes = intel_i830_sizes,
+ .size_type = FIXED_APER_SIZE,
+ .num_aperture_sizes = 4,
+ .needs_scratch_page = TRUE,
+ .configure = intel_i915_configure,
+ .fetch_size = intel_i9xx_fetch_size,
+ .cleanup = intel_i915_cleanup,
+ .tlb_flush = intel_i810_tlbflush,
+ .mask_memory = intel_i965_mask_memory,
+ .masks = intel_i810_masks,
+ .agp_enable = intel_i810_agp_enable,
+ .cache_flush = global_cache_flush,
+ .create_gatt_table = intel_i915_create_gatt_table,
+ .free_gatt_table = intel_i830_free_gatt_table,
+ .insert_memory = intel_i915_insert_entries,
+ .remove_memory = intel_i915_remove_entries,
+ .alloc_by_type = intel_i830_alloc_by_type,
+ .free_by_type = intel_i810_free_by_type,
+ .agp_alloc_page = agp_generic_alloc_page,
+ .agp_destroy_page = agp_generic_destroy_page,
+ .agp_type_to_mask_type = intel_i830_type_to_mask_type,
+};
-static int find_i830(u16 device)
+static int find_gmch(u16 device)
{
- struct pci_dev *i830_dev;
+ struct pci_dev *gmch_device;
- i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
- if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
- i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
- device, i830_dev);
+ gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
+ if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) {
+ gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL,
+ device, gmch_device);
}
- if (!i830_dev)
+ if (!gmch_device)
return 0;
- intel_i830_private.i830_dev = i830_dev;
+ intel_private.pcidev = gmch_device;
return 1;
}
+/* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of
+ * driver and gmch_driver must be non-null, and find_gmch will determine
+ * which one should be used if a gmch_chip_id is present.
+ */
+static const struct intel_driver_description {
+ unsigned int chip_id;
+ unsigned int gmch_chip_id;
+ char *name;
+ const struct agp_bridge_driver *driver;
+ const struct agp_bridge_driver *gmch_driver;
+} intel_agp_chipsets[] = {
+ { PCI_DEVICE_ID_INTEL_82443LX_0, 0, "440LX", &intel_generic_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82443BX_0, 0, "440BX", &intel_generic_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82443GX_0, 0, "440GX", &intel_generic_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82810_MC1, PCI_DEVICE_ID_INTEL_82810_IG1, "i810",
+ NULL, &intel_810_driver },
+ { PCI_DEVICE_ID_INTEL_82810_MC3, PCI_DEVICE_ID_INTEL_82810_IG3, "i810",
+ NULL, &intel_810_driver },
+ { PCI_DEVICE_ID_INTEL_82810E_MC, PCI_DEVICE_ID_INTEL_82810E_IG, "i810",
+ NULL, &intel_810_driver },
+ { PCI_DEVICE_ID_INTEL_82815_MC, PCI_DEVICE_ID_INTEL_82815_CGC, "i815",
+ &intel_810_driver, &intel_815_driver },
+ { PCI_DEVICE_ID_INTEL_82820_HB, 0, "i820", &intel_820_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82820_UP_HB, 0, "i820", &intel_820_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82830_HB, PCI_DEVICE_ID_INTEL_82830_CGC, "830M",
+ &intel_830mp_driver, &intel_830_driver },
+ { PCI_DEVICE_ID_INTEL_82840_HB, 0, "i840", &intel_840_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82845_HB, 0, "845G", &intel_845_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, "830M",
+ &intel_845_driver, &intel_830_driver },
+ { PCI_DEVICE_ID_INTEL_82850_HB, 0, "i850", &intel_850_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82855PM_HB, 0, "855PM", &intel_845_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM",
+ &intel_845_driver, &intel_830_driver },
+ { PCI_DEVICE_ID_INTEL_82860_HB, 0, "i860", &intel_860_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82865_HB, PCI_DEVICE_ID_INTEL_82865_IG, "865",
+ &intel_845_driver, &intel_830_driver },
+ { PCI_DEVICE_ID_INTEL_82875_HB, 0, "i875", &intel_845_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82915G_HB, PCI_DEVICE_ID_INTEL_82915G_IG, "915G",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82915GM_HB, PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, "945G",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, "945GME",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965G_1_HB, PCI_DEVICE_ID_INTEL_82965G_1_IG, "965G",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965Q_HB, PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, "965G",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, "965GME/GLE",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_7505_0, 0, "E7505", &intel_7505_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_7205_0, 0, "E7205", &intel_7505_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_G33_HB, PCI_DEVICE_ID_INTEL_G33_IG, "G33",
+ &intel_845_driver, &intel_g33_driver },
+ { PCI_DEVICE_ID_INTEL_Q35_HB, PCI_DEVICE_ID_INTEL_Q35_IG, "Q35",
+ &intel_845_driver, &intel_g33_driver },
+ { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, "Q33",
+ &intel_845_driver, &intel_g33_driver },
+ { 0, 0, NULL, NULL, NULL }
+};
+
static int __devinit agp_intel_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
- char *name = "(unknown)";
u8 cap_ptr = 0;
struct resource *r;
+ int i;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
@@ -1764,195 +1888,42 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
if (!bridge)
return -ENOMEM;
- switch (pdev->device) {
- case PCI_DEVICE_ID_INTEL_82443LX_0:
- bridge->driver = &intel_generic_driver;
- name = "440LX";
- break;
- case PCI_DEVICE_ID_INTEL_82443BX_0:
- bridge->driver = &intel_generic_driver;
- name = "440BX";
- break;
- case PCI_DEVICE_ID_INTEL_82443GX_0:
- bridge->driver = &intel_generic_driver;
- name = "440GX";
- break;
- case PCI_DEVICE_ID_INTEL_82810_MC1:
- name = "i810";
- if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG1))
- goto fail;
- bridge->driver = &intel_810_driver;
- break;
- case PCI_DEVICE_ID_INTEL_82810_MC3:
- name = "i810 DC100";
- if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG3))
- goto fail;
- bridge->driver = &intel_810_driver;
- break;
- case PCI_DEVICE_ID_INTEL_82810E_MC:
- name = "i810 E";
- if (!find_i810(PCI_DEVICE_ID_INTEL_82810E_IG))
- goto fail;
- bridge->driver = &intel_810_driver;
- break;
- case PCI_DEVICE_ID_INTEL_82815_MC:
- /*
- * The i815 can operate either as an i810 style
- * integrated device, or as an AGP4X motherboard.
- */
- if (find_i810(PCI_DEVICE_ID_INTEL_82815_CGC))
- bridge->driver = &intel_810_driver;
- else
- bridge->driver = &intel_815_driver;
- name = "i815";
- break;
- case PCI_DEVICE_ID_INTEL_82820_HB:
- case PCI_DEVICE_ID_INTEL_82820_UP_HB:
- bridge->driver = &intel_820_driver;
- name = "i820";
- break;
- case PCI_DEVICE_ID_INTEL_82830_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC))
- bridge->driver = &intel_830_driver;
- else
- bridge->driver = &intel_830mp_driver;
- name = "830M";
- break;
- case PCI_DEVICE_ID_INTEL_82840_HB:
- bridge->driver = &intel_840_driver;
- name = "i840";
- break;
- case PCI_DEVICE_ID_INTEL_82845_HB:
- bridge->driver = &intel_845_driver;
- name = "i845";
- break;
- case PCI_DEVICE_ID_INTEL_82845G_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG))
- bridge->driver = &intel_830_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "845G";
- break;
- case PCI_DEVICE_ID_INTEL_82850_HB:
- bridge->driver = &intel_850_driver;
- name = "i850";
- break;
- case PCI_DEVICE_ID_INTEL_82855PM_HB:
- bridge->driver = &intel_845_driver;
- name = "855PM";
- break;
- case PCI_DEVICE_ID_INTEL_82855GM_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82855GM_IG)) {
- bridge->driver = &intel_830_driver;
- name = "855";
- } else {
- bridge->driver = &intel_845_driver;
- name = "855GM";
- }
- break;
- case PCI_DEVICE_ID_INTEL_82860_HB:
- bridge->driver = &intel_860_driver;
- name = "i860";
- break;
- case PCI_DEVICE_ID_INTEL_82865_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG))
- bridge->driver = &intel_830_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "865";
- break;
- case PCI_DEVICE_ID_INTEL_82875_HB:
- bridge->driver = &intel_845_driver;
- name = "i875";
- break;
- case PCI_DEVICE_ID_INTEL_82915G_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82915G_IG))
- bridge->driver = &intel_915_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "915G";
- break;
- case PCI_DEVICE_ID_INTEL_82915GM_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG))
- bridge->driver = &intel_915_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "915GM";
- break;
- case PCI_DEVICE_ID_INTEL_82945G_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG))
- bridge->driver = &intel_915_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "945G";
- break;
- case PCI_DEVICE_ID_INTEL_82945GM_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG))
- bridge->driver = &intel_915_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "945GM";
- break;
- case PCI_DEVICE_ID_INTEL_82946GZ_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82946GZ_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "946GZ";
- break;
- case PCI_DEVICE_ID_INTEL_82965G_1_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82965G_1_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "965G";
- break;
- case PCI_DEVICE_ID_INTEL_82965Q_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82965Q_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "965Q";
- break;
- case PCI_DEVICE_ID_INTEL_82965G_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82965G_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "965G";
- break;
- case PCI_DEVICE_ID_INTEL_82965GM_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "965GM";
- break;
- case PCI_DEVICE_ID_INTEL_7505_0:
- bridge->driver = &intel_7505_driver;
- name = "E7505";
- break;
- case PCI_DEVICE_ID_INTEL_7205_0:
- bridge->driver = &intel_7505_driver;
- name = "E7205";
- break;
- default:
+ for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
+ /* In case that multiple models of gfx chip may
+ stand on same host bridge type, this can be
+ sure we detect the right IGD. */
+ if ((pdev->device == intel_agp_chipsets[i].chip_id) &&
+ ((intel_agp_chipsets[i].gmch_chip_id == 0) ||
+ find_gmch(intel_agp_chipsets[i].gmch_chip_id)))
+ break;
+ }
+
+ if (intel_agp_chipsets[i].name == NULL) {
if (cap_ptr)
- printk(KERN_WARNING PFX "Unsupported Intel chipset (device id: %04x)\n",
- pdev->device);
+ printk(KERN_WARNING PFX "Unsupported Intel chipset"
+ "(device id: %04x)\n", pdev->device);
agp_put_bridge(bridge);
return -ENODEV;
- };
+ }
+
+ if (intel_agp_chipsets[i].gmch_chip_id != 0)
+ bridge->driver = intel_agp_chipsets[i].gmch_driver;
+ else
+ bridge->driver = intel_agp_chipsets[i].driver;
+
+ if (bridge->driver == NULL) {
+ printk(KERN_WARNING PFX "Failed to find bridge device "
+ "(chip_id: %04x)\n", intel_agp_chipsets[i].gmch_chip_id);
+ agp_put_bridge(bridge);
+ return -ENODEV;
+ }
bridge->dev = pdev;
bridge->capndx = cap_ptr;
+ bridge->dev_private_data = &intel_private;
- if (bridge->driver == &intel_810_driver)
- bridge->dev_private_data = &intel_i810_private;
- else if (bridge->driver == &intel_830_driver)
- bridge->dev_private_data = &intel_i830_private;
-
- printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
+ printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n",
+ intel_agp_chipsets[i].name);
/*
* The following fixes the case where the BIOS has "forgotten" to
@@ -1988,12 +1959,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
-
-fail:
- printk(KERN_ERR PFX "Detected an Intel %s chipset, "
- "but could not find the secondary device.\n", name);
- agp_put_bridge(bridge);
- return -ENODEV;
}
static void __devexit agp_intel_remove(struct pci_dev *pdev)
@@ -2002,10 +1967,8 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev)
agp_remove_bridge(bridge);
- if (intel_i810_private.i810_dev)
- pci_dev_put(intel_i810_private.i810_dev);
- if (intel_i830_private.i830_dev)
- pci_dev_put(intel_i830_private.i830_dev);
+ if (intel_private.pcidev)
+ pci_dev_put(intel_private.pcidev);
agp_put_bridge(bridge);
}
@@ -2021,10 +1984,8 @@ static int agp_intel_resume(struct pci_dev *pdev)
* as host bridge (00:00) resumes before graphics device (02:00),
* then our access to its pci space can work right.
*/
- if (intel_i810_private.i810_dev)
- pci_restore_state(intel_i810_private.i810_dev);
- if (intel_i830_private.i830_dev)
- pci_restore_state(intel_i830_private.i830_dev);
+ if (intel_private.pcidev)
+ pci_restore_state(intel_private.pcidev);
if (bridge->driver == &intel_generic_driver)
intel_configure();
@@ -2087,6 +2048,9 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
ID(PCI_DEVICE_ID_INTEL_82965G_HB),
ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
+ ID(PCI_DEVICE_ID_INTEL_G33_HB),
+ ID(PCI_DEVICE_ID_INTEL_Q35_HB),
+ ID(PCI_DEVICE_ID_INTEL_Q33_HB),
{ }
};
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 7fff773f2df7..dc2175c81f5e 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1037,6 +1037,17 @@ static void ide_disk_release(struct kref *kref)
static int ide_disk_probe(ide_drive_t *drive);
+/*
+ * On HPA drives the capacity needs to be
+ * reinitilized on resume otherwise the disk
+ * can not be used and a hard reset is required
+ */
+static void ide_disk_resume(ide_drive_t *drive)
+{
+ if (idedisk_supports_hpa(drive->id))
+ init_idedisk_capacity(drive);
+}
+
static void ide_device_shutdown(ide_drive_t *drive)
{
#ifdef CONFIG_ALPHA
@@ -1071,6 +1082,7 @@ static ide_driver_t idedisk_driver = {
},
.probe = ide_disk_probe,
.remove = ide_disk_remove,
+ .resume = ide_disk_resume,
.shutdown = ide_device_shutdown,
.version = IDEDISK_VERSION,
.media = ide_disk,
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3cebed77f55d..41bfa4d21ab6 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -717,7 +717,7 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
* This routine only knows how to look for drive units 0 and 1
* on an interface, so any setting of MAX_DRIVES > 2 won't work here.
*/
-static void probe_hwif(ide_hwif_t *hwif)
+static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
{
unsigned int unit;
unsigned long flags;
@@ -820,6 +820,9 @@ static void probe_hwif(ide_hwif_t *hwif)
return;
}
+ if (fixup)
+ fixup(hwif);
+
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
@@ -874,10 +877,7 @@ static int hwif_init(ide_hwif_t *hwif);
int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
{
- probe_hwif(hwif);
-
- if (fixup)
- fixup(hwif);
+ probe_hwif(hwif, fixup);
if (!hwif_init(hwif)) {
printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -1404,7 +1404,7 @@ int ideprobe_init (void)
for (index = 0; index < MAX_HWIFS; ++index)
if (probe[index])
- probe_hwif(&ide_hwifs[index]);
+ probe_hwif(&ide_hwifs[index], NULL);
for (index = 0; index < MAX_HWIFS; ++index)
if (probe[index])
hwif_init(&ide_hwifs[index]);
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 6002713a20a1..0af0d1614f75 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1010,9 +1010,11 @@ static int generic_ide_resume(struct device *dev)
{
ide_drive_t *drive = dev->driver_data;
ide_hwif_t *hwif = HWIF(drive);
+ ide_driver_t *drv = to_ide_driver(dev->driver);
struct request rq;
struct request_pm_state rqpm;
ide_task_t args;
+ int err;
/* Call ACPI _STM only once */
if (!(drive->dn % 2))
@@ -1029,7 +1031,12 @@ static int generic_ide_resume(struct device *dev)
rqpm.pm_step = ide_pm_state_start_resume;
rqpm.pm_state = PM_EVENT_ON;
- return ide_do_drive_cmd(drive, &rq, ide_head_wait);
+ err = ide_do_drive_cmd(drive, &rq, ide_head_wait);
+
+ if (err == 0 && drv && drv->resume)
+ drv->resume(drive);
+
+ return err;
}
int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index becb1a5648b0..9db1be826e80 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -1,5 +1,5 @@
/*
- * Version 2.13
+ * Version 2.15
*
* AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
* IDE driver for Linux.
@@ -76,6 +76,8 @@ static struct amd_ide_chip {
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, AMD_UDMA_133 },
+ { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, 0x50, AMD_UDMA_133 },
+ { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 },
{ 0 }
};
@@ -494,7 +496,9 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
/* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"),
/* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"),
/* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"),
- /* 20 */ DECLARE_AMD_DEV("AMD5536"),
+ /* 20 */ DECLARE_NV_DEV("NFORCE-MCP73"),
+ /* 21 */ DECLARE_NV_DEV("NFORCE-MCP77"),
+ /* 22 */ DECLARE_AMD_DEV("AMD5536"),
};
static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -534,7 +538,9 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21 },
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index f2c5a141ca10..0d51a11e81da 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -198,32 +198,41 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
ide_pci_device_t *d = &generic_chipsets[id->driver_data];
- u16 command;
int ret = -ENODEV;
/* Don't use the generic entry unless instructed to do so */
if (id->driver_data == 0 && ide_generic_all == 0)
goto out;
- if (dev->vendor == PCI_VENDOR_ID_UMC &&
- dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
- (!(PCI_FUNC(dev->devfn) & 1)))
- goto out; /* UM8886A/BF pair */
-
- if (dev->vendor == PCI_VENDOR_ID_OPTI &&
- dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
- (!(PCI_FUNC(dev->devfn) & 1)))
- goto out;
-
- if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
- if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1)
+ switch (dev->vendor) {
+ case PCI_VENDOR_ID_UMC:
+ if (dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
+ !(PCI_FUNC(dev->devfn) & 1))
+ goto out; /* UM8886A/BF pair */
+ break;
+ case PCI_VENDOR_ID_OPTI:
+ if (dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
+ !(PCI_FUNC(dev->devfn) & 1))
+ goto out;
+ break;
+ case PCI_VENDOR_ID_JMICRON:
+ if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 &&
+ PCI_FUNC(dev->devfn) != 1)
+ goto out;
+ break;
+ case PCI_VENDOR_ID_NS:
+ if (dev->device == PCI_DEVICE_ID_NS_87410 &&
+ (dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
goto out;
+ break;
}
if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
+ u16 command;
pci_read_config_word(dev, PCI_COMMAND, &command);
if (!(command & PCI_COMMAND_IO)) {
- printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name);
+ printk(KERN_INFO "Skipping disabled %s IDE "
+ "controller.\n", d->name);
goto out;
}
}
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index fcbc5605b38e..ce8a5449a574 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/hpt366.c Version 1.03 May 4, 2007
+ * linux/drivers/ide/pci/hpt366.c Version 1.04 Jun 4, 2007
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
@@ -106,7 +106,8 @@
* switch to calculating PCI clock frequency based on the chip's base DPLL
* frequency
* - switch to using the DPLL clock and enable UltraATA/133 mode by default on
- * anything newer than HPT370/A
+ * anything newer than HPT370/A (except HPT374 that is not capable of this
+ * mode according to the manual)
* - fold PCI clock detection and DPLL setup code into init_chipset_hpt366(),
* also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips;
* unify HPT36x/37x timing setup code and the speedproc handlers by joining
@@ -365,7 +366,6 @@ static u32 sixty_six_base_hpt37x[] = {
};
#define HPT366_DEBUG_DRIVE_INFO 0
-#define HPT374_ALLOW_ATA133_6 1
#define HPT371_ALLOW_ATA133_6 1
#define HPT302_ALLOW_ATA133_6 1
#define HPT372_ALLOW_ATA133_6 1
@@ -450,7 +450,7 @@ static struct hpt_info hpt370a __devinitdata = {
static struct hpt_info hpt374 __devinitdata = {
.chip_type = HPT374,
- .max_mode = HPT374_ALLOW_ATA133_6 ? 4 : 3,
+ .max_mode = 3,
.dpll_clk = 48,
.settings = hpt37x_settings
};
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 5faaff87d580..4bd4bf02e917 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -1,6 +1,6 @@
/*
- * linux/drivers/ide/pci/it821x.c Version 0.10 Mar 10 2007
+ * linux/drivers/ide/pci/it821x.c Version 0.15 Jun 2 2007
*
* Copyright (C) 2004 Red Hat <alan@redhat.com>
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
@@ -262,7 +262,7 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
}
if (itdev->smart)
- goto set_drive_speed;
+ return 0;
/* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
itdev->want[unit][1] = pio_want[set_pio];
@@ -271,7 +271,6 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
it821x_clock_strategy(drive);
it821x_program(drive, itdev->pio[unit]);
-set_drive_speed:
return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
}
@@ -455,12 +454,12 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed)
default:
return 1;
}
+
+ return ide_config_drive_speed(drive, speed);
}
- /*
- * In smart mode the clocking is done by the host controller
- * snooping the mode we picked. The rest of it is not our problem
- */
- return ide_config_drive_speed(drive, speed);
+
+ /* don't touch anything in the smart mode */
+ return 0;
}
/**
@@ -559,17 +558,10 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
if(idbits[129] != 1)
printk("(%dK stripe)", idbits[146]);
printk(".\n");
- /* Now the core code will have wrongly decided no DMA
- so we need to fix this */
- hwif->dma_off_quietly(drive);
-#ifdef CONFIG_IDEDMA_ONLYDISK
- if (drive->media == ide_disk)
-#endif
- ide_set_dma(drive);
} else {
/* Non RAID volume. Fixups to stop the core code
doing unsupported things */
- id->field_valid &= 1;
+ id->field_valid &= 3;
id->queue_depth = 0;
id->command_set_1 = 0;
id->command_set_2 &= 0xC400;
@@ -584,6 +576,16 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
printk(KERN_INFO "%s: Performing identify fixups.\n",
drive->name);
}
+
+ /*
+ * Set MWDMA0 mode as enabled/support - just to tell
+ * IDE core that DMA is supported (it821x hardware
+ * takes care of DMA mode programming).
+ */
+ if (id->capability & 1) {
+ id->dma_mword |= 0x0101;
+ drive->current_speed = XFER_MW_DMA_0;
+ }
}
}
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index 47bcd91c9b5f..d9c4fd1ae996 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/serverworks.c Version 0.9 Mar 4 2007
+ * linux/drivers/ide/pci/serverworks.c Version 0.11 Jun 2 2007
*
* Copyright (C) 1998-2000 Michel Aubry
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz
@@ -170,42 +170,55 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
if (!drive->init_speed) {
u8 dma_stat = inb(hwif->dma_status);
-dma_pio:
if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) {
drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)];
return 0;
} else if ((dma_timing) &&
((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) {
- u8 dmaspeed = dma_timing;
+ u8 dmaspeed;
- dma_timing &= ~0xFFU;
- if ((dmaspeed & 0x20) == 0x20)
+ switch (dma_timing & 0x77) {
+ case 0x20:
dmaspeed = XFER_MW_DMA_2;
- else if ((dmaspeed & 0x21) == 0x21)
+ break;
+ case 0x21:
dmaspeed = XFER_MW_DMA_1;
- else if ((dmaspeed & 0x77) == 0x77)
+ break;
+ case 0x77:
dmaspeed = XFER_MW_DMA_0;
- else
+ break;
+ default:
goto dma_pio;
+ }
+
drive->current_speed = drive->init_speed = dmaspeed;
return 0;
- } else if (pio_timing) {
- u8 piospeed = pio_timing;
+ }
+dma_pio:
+ if (pio_timing) {
+ u8 piospeed;
- pio_timing &= ~0xFFU;
- if ((piospeed & 0x20) == 0x20)
+ switch (pio_timing & 0x7f) {
+ case 0x20:
piospeed = XFER_PIO_4;
- else if ((piospeed & 0x22) == 0x22)
+ break;
+ case 0x22:
piospeed = XFER_PIO_3;
- else if ((piospeed & 0x34) == 0x34)
+ break;
+ case 0x34:
piospeed = XFER_PIO_2;
- else if ((piospeed & 0x47) == 0x47)
+ break;
+ case 0x47:
piospeed = XFER_PIO_1;
- else if ((piospeed & 0x5d) == 0x5d)
+ break;
+ case 0x5d:
piospeed = XFER_PIO_0;
- else
+ break;
+ default:
goto oem_setup_failed;
+ }
+
drive->current_speed = drive->init_speed = piospeed;
return 0;
}
@@ -214,8 +227,8 @@ dma_pio:
oem_setup_failed:
- pio_timing &= ~0xFFU;
- dma_timing &= ~0xFFU;
+ pio_timing = 0;
+ dma_timing = 0;
ultra_timing &= ~(0x0F << (4*unit));
ultra_enable &= ~(0x01 << drive->dn);
csb5_pio &= ~(0x0F << (4*drive->dn));
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 2eb52b7a71da..32a0e66d2a23 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -2773,8 +2773,8 @@ static int cma_init(void)
int ret;
get_random_bytes(&next_port, sizeof next_port);
- next_port = (next_port % (sysctl_local_port_range[1] -
- sysctl_local_port_range[0])) +
+ next_port = ((unsigned int) next_port %
+ (sysctl_local_port_range[1] - sysctl_local_port_range[0])) +
sysctl_local_port_range[0];
cma_wq = create_singlethread_workqueue("rdma_cm");
if (!cma_wq)
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index dc137dec2308..5c6d05427a0f 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -189,18 +189,28 @@ static int send_wqe_overhead(enum ib_qp_type type)
}
static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
- struct mlx4_ib_qp *qp)
+ int is_user, int has_srq, struct mlx4_ib_qp *qp)
{
/* Sanity check RQ size before proceeding */
if (cap->max_recv_wr > dev->dev->caps.max_wqes ||
cap->max_recv_sge > dev->dev->caps.max_rq_sg)
return -EINVAL;
- qp->rq.max = cap->max_recv_wr ? roundup_pow_of_two(cap->max_recv_wr) : 0;
+ if (has_srq) {
+ /* QPs attached to an SRQ should have no RQ */
+ if (cap->max_recv_wr)
+ return -EINVAL;
+
+ qp->rq.max = qp->rq.max_gs = 0;
+ } else {
+ /* HW requires >= 1 RQ entry with >= 1 gather entry */
+ if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge))
+ return -EINVAL;
- qp->rq.wqe_shift = ilog2(roundup_pow_of_two(cap->max_recv_sge *
- sizeof (struct mlx4_wqe_data_seg)));
- qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof (struct mlx4_wqe_data_seg);
+ qp->rq.max = roundup_pow_of_two(max(1, cap->max_recv_wr));
+ qp->rq.max_gs = roundup_pow_of_two(max(1, cap->max_recv_sge));
+ qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
+ }
cap->max_recv_wr = qp->rq.max;
cap->max_recv_sge = qp->rq.max_gs;
@@ -285,7 +295,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
qp->sq.head = 0;
qp->sq.tail = 0;
- err = set_rq_size(dev, &init_attr->cap, qp);
+ err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, !!init_attr->srq, qp);
if (err)
goto err;
@@ -762,11 +772,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
optpar |= MLX4_QP_OPTPAR_PKEY_INDEX;
}
- if (attr_mask & IB_QP_RNR_RETRY) {
- context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
- optpar |= MLX4_QP_OPTPAR_RNR_RETRY;
- }
-
if (attr_mask & IB_QP_AV) {
if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path,
attr_mask & IB_QP_PORT ? attr->port_num : qp->port)) {
@@ -802,6 +807,12 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pdn);
context->params1 = cpu_to_be32(MLX4_IB_ACK_REQ_FREQ << 28);
+
+ if (attr_mask & IB_QP_RNR_RETRY) {
+ context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
+ optpar |= MLX4_QP_OPTPAR_RNR_RETRY;
+ }
+
if (attr_mask & IB_QP_RETRY_CNT) {
context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
optpar |= MLX4_QP_OPTPAR_RETRY_COUNT;
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 38102520ffb3..f40558d76475 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -772,7 +772,7 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
MTHCA_GET(dev->fw_ver, outbox, QUERY_FW_VER_OFFSET);
/*
- * FW subminor version is at more signifant bits than minor
+ * FW subminor version is at more significant bits than minor
* version, so swap here.
*/
dev->fw_ver = (dev->fw_ver & 0xffff00000000ull) |
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index c120114c241b..5c63c8e24ee7 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -4,5 +4,6 @@ config VIDEO_SAA7146
config VIDEO_SAA7146_VV
tristate
+ depends on VIDEO_DEV
select VIDEO_BUF
select VIDEO_SAA7146
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index 1a1c3bca55fa..bff00b58bf65 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -1,8 +1,11 @@
b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
- flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o \
- flexcop-dma.o
+ flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
+ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
+b2c2-flexcop-objs += flexcop-dma.o
+endif
+
b2c2-flexcop-pci-objs = flexcop-pci.o
obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 34d7abc900d7..6aba5b39ed14 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -519,8 +519,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct cinergyt2 *cinergyt2 = dvbdev->priv;
- if (mutex_lock_interruptible(&cinergyt2->sem))
- return -ERESTARTSYS;
+ mutex_lock(&cinergyt2->sem);
if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
cancel_delayed_work(&cinergyt2->query_work);
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
index ccc429cbbad0..0f2d4b415560 100644
--- a/drivers/media/dvb/frontends/tda10086.c
+++ b/drivers/media/dvb/frontends/tda10086.c
@@ -41,6 +41,7 @@ struct tda10086_state {
/* private demod data */
u32 frequency;
u32 symbol_rate;
+ bool has_lock;
};
static int debug = 0;
@@ -116,7 +117,7 @@ static int tda10086_init(struct dvb_frontend* fe)
// misc setup
tda10086_write_byte(state, 0x01, 0x94);
tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP
- tda10086_write_byte(state, 0x03, 0x64);
+ tda10086_write_byte(state, 0x03, 0xe4);
tda10086_write_byte(state, 0x04, 0x43);
tda10086_write_byte(state, 0x0c, 0x0c);
tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
@@ -146,7 +147,7 @@ static int tda10086_init(struct dvb_frontend* fe)
// setup AGC
tda10086_write_byte(state, 0x05, 0x0B);
tda10086_write_byte(state, 0x37, 0x63);
- tda10086_write_byte(state, 0x3f, 0x03); // NOTE: flydvb uses 0x0a and varies it
+ tda10086_write_byte(state, 0x3f, 0x0a); // NOTE: flydvb varies it
tda10086_write_byte(state, 0x40, 0x64);
tda10086_write_byte(state, 0x41, 0x4f);
tda10086_write_byte(state, 0x42, 0x43);
@@ -398,6 +399,10 @@ static int tda10086_set_frontend(struct dvb_frontend* fe,
dprintk ("%s\n", __FUNCTION__);
+ // modify parameters for tuning
+ tda10086_write_byte(state, 0x02, 0x35);
+ state->has_lock = false;
+
// set params
if (fe->ops.tuner_ops.set_params) {
fe->ops.tuner_ops.set_params(fe, fe_params);
@@ -542,8 +547,14 @@ static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
*fe_status |= FE_HAS_VITERBI;
if (val & 0x08)
*fe_status |= FE_HAS_SYNC;
- if (val & 0x10)
+ if (val & 0x10) {
*fe_status |= FE_HAS_LOCK;
+ if (!state->has_lock) {
+ state->has_lock = true;
+ // modify parameters for stable reception
+ tda10086_write_byte(state, 0x02, 0x00);
+ }
+ }
return 0;
}
@@ -555,7 +566,7 @@ static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
dprintk ("%s\n", __FUNCTION__);
- _str = tda10086_read_byte(state, 0x43);
+ _str = 0xff - tda10086_read_byte(state, 0x43);
*signal = (_str << 8) | _str;
return 0;
@@ -568,7 +579,7 @@ static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
dprintk ("%s\n", __FUNCTION__);
- _snr = tda10086_read_byte(state, 0x1c);
+ _snr = 0xff - tda10086_read_byte(state, 0x1c);
*snr = (_snr << 8) | _snr;
return 0;
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c
index 79f971dc52b6..bd3ebc284835 100644
--- a/drivers/media/dvb/frontends/tda826x.c
+++ b/drivers/media/dvb/frontends/tda826x.c
@@ -89,8 +89,8 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
buf[3] = div >> 7;
buf[4] = div << 1;
- buf[5] = 0xff; // basedband filter to max
- buf[6] = 0xfe; // gains at max + no RF attenuation
+ buf[5] = 0x77; // baseband cut-off 19 MHz
+ buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
buf[7] = 0x83; // charge pumps at high, tests off
buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 5cb3f54b548b..4cca55170e21 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -347,7 +347,7 @@ endmenu # encoder / decoder chips
config VIDEO_VIVI
tristate "Virtual Video Driver"
- depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI
+ depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI && VIDEO_DEV
select VIDEO_BUF
default n
---help---
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 15012f88b802..91e9e90c14a5 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -86,7 +86,7 @@
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
V4L2_CAP_SLICED_VBI_CAPTURE)
#define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \
- V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_POS)
+ V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
struct ivtv_card_video_input {
u8 video_type; /* video input type */
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index e29f949adf57..efc66355339a 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -652,6 +652,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
itv->dma_timer.data = (unsigned long)itv;
itv->cur_dma_stream = -1;
+ itv->cur_pio_stream = -1;
itv->audio_stereo_mode = AUDIO_STEREO;
itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 552f04511ead..e6e56f175f3f 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -237,6 +237,7 @@ extern const u32 yuv_offset[4];
#define IVTV_IRQ_ENC_VBI_CAP (0x1 << 29)
#define IVTV_IRQ_ENC_VIM_RST (0x1 << 28)
#define IVTV_IRQ_ENC_DMA_COMPLETE (0x1 << 27)
+#define IVTV_IRQ_ENC_PIO_COMPLETE (0x1 << 25)
#define IVTV_IRQ_DEC_AUD_MODE_CHG (0x1 << 24)
#define IVTV_IRQ_DEC_DATA_REQ (0x1 << 22)
#define IVTV_IRQ_DEC_DMA_COMPLETE (0x1 << 20)
@@ -247,7 +248,8 @@ extern const u32 yuv_offset[4];
#define IVTV_IRQ_DEC_VSYNC (0x1 << 10)
/* IRQ Masks */
-#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|IVTV_IRQ_DMA_READ)
+#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
+ IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE)
#define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
#define IVTV_IRQ_MASK_DECODE (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
@@ -374,6 +376,9 @@ struct ivtv_mailbox_data {
#define IVTV_F_S_STREAMOFF 7 /* signal end of stream EOS */
#define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */
+#define IVTV_F_S_PIO_PENDING 9 /* this stream has pending PIO */
+#define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */
+
/* per-ivtv, i_flags */
#define IVTV_F_I_DMA 0 /* DMA in progress */
#define IVTV_F_I_UDMA 1 /* UDMA in progress */
@@ -390,8 +395,11 @@ struct ivtv_mailbox_data {
#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
-#define IVTV_F_I_WORK_HANDLER_VBI 15 /* there is work to be done for VBI */
-#define IVTV_F_I_WORK_HANDLER_YUV 16 /* there is work to be done for YUV */
+#define IVTV_F_I_HAVE_WORK 15 /* Used in the interrupt handler: there is work to be done */
+#define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */
+#define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */
+#define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */
+#define IVTV_F_I_PIO 19 /* PIO in progress */
/* Event notifications */
#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
@@ -484,6 +492,7 @@ struct ivtv_stream {
/* Base Dev SG Array for cx23415/6 */
struct ivtv_SG_element *SGarray;
+ struct ivtv_SG_element *PIOarray;
dma_addr_t SG_handle;
int SG_length;
@@ -706,6 +715,7 @@ struct ivtv {
atomic_t decoding; /* count number of active decoding streams */
u32 irq_rr_idx; /* Round-robin stream index */
int cur_dma_stream; /* index of stream doing DMA */
+ int cur_pio_stream; /* index of stream doing PIO */
u32 dma_data_req_offset;
u32 dma_data_req_size;
int output_mode; /* NONE, MPG, YUV, UDMA YUV, passthrough */
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 8976487a65f3..555d5e6369c3 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -32,6 +32,8 @@
#include "ivtv-yuv.h"
#include "ivtv-controls.h"
#include "ivtv-ioctl.h"
+#include "ivtv-cards.h"
+#include <media/saa7115.h>
/* This function tries to claim the stream for a specific file descriptor.
If no one else is using this stream then the stream is claimed and
@@ -786,6 +788,13 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
/* Select correct audio input (i.e. TV tuner or Line in) */
ivtv_audio_set_io(itv);
+ if (itv->hw_flags & IVTV_HW_SAA711X)
+ {
+ struct v4l2_crystal_freq crystal_freq;
+ crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
+ crystal_freq.flags = 0;
+ ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+ }
/* Done! Unmute and continue. */
ivtv_unmute(itv);
ivtv_release_stream(s);
@@ -872,6 +881,13 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
/* Select the correct audio input (i.e. radio tuner) */
ivtv_audio_set_io(itv);
+ if (itv->hw_flags & IVTV_HW_SAA711X)
+ {
+ struct v4l2_crystal_freq crystal_freq;
+ crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
+ crystal_freq.flags = SAA7115_FREQ_FL_APLL;
+ ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+ }
/* Done! Unmute and continue. */
ivtv_unmute(itv);
}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 1989ec1cb973..57af1762de1f 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -532,11 +532,6 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
itv->yuv_info.yuv_forced_update = 1;
return 0;
}
- if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
- r.width, r.height, r.left, r.top))
- itv->main_rect = r;
- else
- return -EINVAL;
}
return 0;
}
@@ -799,9 +794,39 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
return ivtv_get_fmt(itv, id->type, fmt);
}
+ case VIDIOC_CROPCAP: {
+ struct v4l2_cropcap *cropcap = arg;
+
+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ cropcap->bounds.top = cropcap->bounds.left = 0;
+ cropcap->bounds.width = 720;
+ if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ cropcap->bounds.height = itv->is_50hz ? 576 : 480;
+ cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
+ cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
+ } else {
+ cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
+ cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
+ cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+ }
+ cropcap->defrect = cropcap->bounds;
+ return 0;
+ }
+
case VIDIOC_S_CROP: {
struct v4l2_crop *crop = arg;
+ if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+ if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+ crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
+ itv->main_rect = crop->c;
+ return 0;
+ }
+ return -EINVAL;
+ }
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
@@ -810,6 +835,11 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
case VIDIOC_G_CROP: {
struct v4l2_crop *crop = arg;
+ if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+ crop->c = itv->main_rect;
+ return 0;
+ }
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
@@ -977,7 +1007,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
if (itv->hw_flags & IVTV_HW_CX25840) {
itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
}
- IVTV_DEBUG_INFO("Switching standard to %llx.\n", itv->std);
+ IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
/* Tuner */
ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
@@ -1207,7 +1237,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
(s->buffers - s->q_free.buffers) * 100 / s->buffers,
(s->buffers * s->buf_size) / 1024, s->buffers);
}
- IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", itv->mpg_data_received, itv->vbi_data_inserted);
+ IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
break;
}
@@ -1455,6 +1485,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
case VIDIOC_S_FMT:
case VIDIOC_TRY_FMT:
case VIDIOC_ENUM_FMT:
+ case VIDIOC_CROPCAP:
case VIDIOC_G_CROP:
case VIDIOC_S_CROP:
case VIDIOC_G_FREQUENCY:
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index c3a047b381b3..ba98bf054f2e 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -31,8 +31,6 @@
#define DMA_MAGIC_COOKIE 0x000001fe
-#define SLICED_VBI_PIO 1
-
static void ivtv_dma_dec_start(struct ivtv_stream *s);
static const int ivtv_stream_map[] = {
@@ -42,12 +40,40 @@ static const int ivtv_stream_map[] = {
IVTV_ENC_STREAM_TYPE_VBI,
};
-static inline int ivtv_use_pio(struct ivtv_stream *s)
+
+static void ivtv_pio_work_handler(struct ivtv *itv)
{
- struct ivtv *itv = s->itv;
+ struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
+ struct ivtv_buffer *buf;
+ struct list_head *p;
+ int i = 0;
+
+ IVTV_DEBUG_DMA("ivtv_pio_work_handler\n");
+ if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
+ s->v4l2dev == NULL || !ivtv_use_pio(s)) {
+ itv->cur_pio_stream = -1;
+ /* trigger PIO complete user interrupt */
+ write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
+ return;
+ }
+ IVTV_DEBUG_DMA("Process PIO %s\n", s->name);
+ buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list);
+ list_for_each(p, &s->q_dma.list) {
+ struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
+ u32 size = s->PIOarray[i].size & 0x3ffff;
- return s->dma == PCI_DMA_NONE ||
- (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
+ /* Copy the data from the card to the buffer */
+ if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
+ memcpy_fromio(buf->buf, itv->dec_mem + s->PIOarray[i].src - IVTV_DECODER_OFFSET, size);
+ }
+ else {
+ memcpy_fromio(buf->buf, itv->enc_mem + s->PIOarray[i].src, size);
+ }
+ if (s->PIOarray[i].size & 0x80000000)
+ break;
+ i++;
+ }
+ write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
}
void ivtv_irq_work_handler(struct work_struct *work)
@@ -56,8 +82,11 @@ void ivtv_irq_work_handler(struct work_struct *work)
DEFINE_WAIT(wait);
+ if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
+ ivtv_pio_work_handler(itv);
+
if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
- vbi_work_handler(itv);
+ ivtv_vbi_work_handler(itv);
if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
ivtv_yuv_work_handler(itv);
@@ -173,8 +202,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
}
s->buffers_stolen = rc;
- /* got the buffers, now fill in SGarray (DMA) or copy the data from the card
- to the buffers (PIO). */
+ /* got the buffers, now fill in SGarray (DMA) */
buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
memset(buf->buf, 0, 128);
list_for_each(p, &s->q_predma.list) {
@@ -182,21 +210,11 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
if (skip_bufs-- > 0)
continue;
- if (!ivtv_use_pio(s)) {
- s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
- s->SGarray[idx].src = cpu_to_le32(offset);
- s->SGarray[idx].size = cpu_to_le32(s->buf_size);
- }
+ s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
+ s->SGarray[idx].src = cpu_to_le32(offset);
+ s->SGarray[idx].size = cpu_to_le32(s->buf_size);
buf->bytesused = (size < s->buf_size) ? size : s->buf_size;
- /* If PIO, then copy the data from the card to the buffer */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- memcpy_fromio(buf->buf, itv->dec_mem + offset - IVTV_DECODER_OFFSET, buf->bytesused);
- }
- else if (ivtv_use_pio(s)) {
- memcpy_fromio(buf->buf, itv->enc_mem + offset, buf->bytesused);
- }
-
s->q_predma.bytesused += buf->bytesused;
size -= buf->bytesused;
offset += s->buf_size;
@@ -224,11 +242,6 @@ static void dma_post(struct ivtv_stream *s)
u32 *u32buf;
int x = 0;
- if (ivtv_use_pio(s)) {
- if (s->q_predma.bytesused)
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
- s->SG_length = 0;
- }
IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
s->name, s->dma_offset);
list_for_each(p, &s->q_dma.list) {
@@ -278,10 +291,14 @@ static void dma_post(struct ivtv_stream *s)
if (buf)
buf->bytesused += s->dma_last_offset;
if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- /* Parse and Groom VBI Data */
- s->q_dma.bytesused -= buf->bytesused;
- ivtv_process_vbi_data(itv, buf, 0, s->type);
- s->q_dma.bytesused += buf->bytesused;
+ list_for_each(p, &s->q_dma.list) {
+ buf = list_entry(p, struct ivtv_buffer, list);
+
+ /* Parse and Groom VBI Data */
+ s->q_dma.bytesused -= buf->bytesused;
+ ivtv_process_vbi_data(itv, buf, 0, s->type);
+ s->q_dma.bytesused += buf->bytesused;
+ }
if (s->id == -1) {
ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
return;
@@ -351,10 +368,14 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
int i;
+ IVTV_DEBUG_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name);
+
if (s->q_predma.bytesused)
ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
- IVTV_DEBUG_DMA("start DMA for %s\n", s->name);
- s->SGarray[s->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
+
+ if (ivtv_use_dma(s))
+ s->SGarray[s->SG_length - 1].size =
+ cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
/* If this is an MPEG stream, and VBI data is also pending, then append the
VBI DMA to the MPEG DMA and transfer both sets of data at once.
@@ -368,7 +389,8 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length &&
s->SG_length + s_vbi->SG_length <= s->buffers) {
ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
- s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
+ if (ivtv_use_dma(s_vbi))
+ s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
for (i = 0; i < s_vbi->SG_length; i++) {
s->SGarray[s->SG_length++] = s_vbi->SGarray[i];
}
@@ -381,14 +403,26 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
/* Mark last buffer size for Interrupt flag */
s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
- /* Sync Hardware SG List of buffers */
- ivtv_stream_sync_for_device(s);
- write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
- write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
- set_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = s->type;
- itv->dma_timer.expires = jiffies + HZ / 10;
- add_timer(&itv->dma_timer);
+ if (ivtv_use_pio(s)) {
+ for (i = 0; i < s->SG_length; i++) {
+ s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src);
+ s->PIOarray[i].size = le32_to_cpu(s->SGarray[i].size);
+ }
+ set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
+ set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
+ set_bit(IVTV_F_I_PIO, &itv->i_flags);
+ itv->cur_pio_stream = s->type;
+ }
+ else {
+ /* Sync Hardware SG List of buffers */
+ ivtv_stream_sync_for_device(s);
+ write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
+ write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
+ set_bit(IVTV_F_I_DMA, &itv->i_flags);
+ itv->cur_dma_stream = s->type;
+ itv->dma_timer.expires = jiffies + HZ / 10;
+ add_timer(&itv->dma_timer);
+ }
}
static void ivtv_dma_dec_start(struct ivtv_stream *s)
@@ -489,6 +523,40 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
wake_up(&itv->dma_waitq);
}
+static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
+{
+ struct ivtv_stream *s;
+
+ if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) {
+ itv->cur_pio_stream = -1;
+ return;
+ }
+ s = &itv->streams[itv->cur_pio_stream];
+ IVTV_DEBUG_IRQ("ENC PIO COMPLETE %s\n", s->name);
+ s->SG_length = 0;
+ clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+ clear_bit(IVTV_F_I_PIO, &itv->i_flags);
+ itv->cur_pio_stream = -1;
+ dma_post(s);
+ if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
+ ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0);
+ else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
+ ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1);
+ else if (s->type == IVTV_ENC_STREAM_TYPE_PCM)
+ ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
+ clear_bit(IVTV_F_I_PIO, &itv->i_flags);
+ if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
+ u32 tmp;
+
+ s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
+ tmp = s->dma_offset;
+ s->dma_offset = itv->vbi.dma_offset;
+ dma_post(s);
+ s->dma_offset = tmp;
+ }
+ wake_up(&itv->dma_waitq);
+}
+
static void ivtv_irq_dma_err(struct ivtv *itv)
{
u32 data[CX2341X_MBOX_MAX_DATA];
@@ -532,13 +600,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
s = &itv->streams[ivtv_stream_map[data[0]]];
if (!stream_enc_dma_append(s, data)) {
- if (ivtv_use_pio(s)) {
- dma_post(s);
- ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[0]);
- }
- else {
- set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
- }
+ set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
}
}
@@ -551,15 +613,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
IVTV_DEBUG_IRQ("ENC START VBI CAP\n");
s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- if (ivtv_use_pio(s)) {
- if (stream_enc_dma_append(s, data))
- return;
- if (s->q_predma.bytesused)
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
- s->SG_length = 0;
- dma_post(s);
- return;
- }
/* If more than two VBI buffers are pending, then
clear the old ones and start with this new one.
This can happen during transition stages when MPEG capturing is
@@ -582,11 +635,11 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
if (!stream_enc_dma_append(s, data) &&
!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
- set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
+ set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
}
}
-static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
+static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
{
u32 data[CX2341X_MBOX_MAX_DATA];
struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
@@ -594,7 +647,7 @@ static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
IVTV_DEBUG_IRQ("DEC VBI REINSERT\n");
if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
!stream_enc_dma_append(s, data)) {
- dma_post(s);
+ set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags);
}
}
@@ -657,7 +710,6 @@ static void ivtv_irq_vsync(struct ivtv *itv)
}
if (frame != (itv->lastVsyncFrame & 1)) {
struct ivtv_stream *s = ivtv_get_output_stream(itv);
- int work = 0;
itv->lastVsyncFrame += 1;
if (frame == 0) {
@@ -678,7 +730,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
/* Send VBI to saa7127 */
if (frame) {
set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
- work = 1;
+ set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
}
/* Check if we need to update the yuv registers */
@@ -691,11 +743,9 @@ static void ivtv_irq_vsync(struct ivtv *itv)
itv->yuv_info.new_frame_info[last_dma_frame].update = 0;
itv->yuv_info.yuv_forced_update = 0;
set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
- work = 1;
+ set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
}
}
- if (work)
- queue_work(itv->irq_work_queues, &itv->irq_work_queue);
}
}
@@ -755,6 +805,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
ivtv_irq_enc_dma_complete(itv);
}
+ if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
+ ivtv_irq_enc_pio_complete(itv);
+ }
+
if (combo & IVTV_IRQ_DMA_ERR) {
ivtv_irq_dma_err(itv);
}
@@ -768,7 +822,7 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
}
if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
- ivtv_irq_dev_vbi_reinsert(itv);
+ ivtv_irq_dec_vbi_reinsert(itv);
}
if (combo & IVTV_IRQ_ENC_EOS) {
@@ -813,6 +867,22 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
}
}
+ if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
+ for (i = 0; i < IVTV_MAX_STREAMS; i++) {
+ int idx = (i + itv->irq_rr_idx++) % IVTV_MAX_STREAMS;
+ struct ivtv_stream *s = &itv->streams[idx];
+
+ if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
+ continue;
+ if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG)
+ ivtv_dma_enc_start(s);
+ break;
+ }
+ }
+
+ if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags))
+ queue_work(itv->irq_work_queues, &itv->irq_work_queue);
+
spin_unlock(&itv->dma_reg_lock);
/* If we've just handled a 'forced' vsync, it's safest to say it
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
index ccfcef1ad91a..a04f9387f63d 100644
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ b/drivers/media/video/ivtv/ivtv-queue.c
@@ -195,14 +195,26 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
s->dma != PCI_DMA_NONE ? "DMA " : "",
s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
- /* Allocate DMA SG Arrays */
- if (s->dma != PCI_DMA_NONE) {
- s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
- if (s->SGarray == NULL) {
- IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
+ if (ivtv_might_use_pio(s)) {
+ s->PIOarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
+ if (s->PIOarray == NULL) {
+ IVTV_ERR("Could not allocate PIOarray for %s stream\n", s->name);
return -ENOMEM;
}
- s->SG_length = 0;
+ }
+
+ /* Allocate DMA SG Arrays */
+ s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
+ if (s->SGarray == NULL) {
+ IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
+ if (ivtv_might_use_pio(s)) {
+ kfree(s->PIOarray);
+ s->PIOarray = NULL;
+ }
+ return -ENOMEM;
+ }
+ s->SG_length = 0;
+ if (ivtv_might_use_dma(s)) {
s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma);
ivtv_stream_sync_for_cpu(s);
}
@@ -219,7 +231,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
break;
}
INIT_LIST_HEAD(&buf->list);
- if (s->dma != PCI_DMA_NONE) {
+ if (ivtv_might_use_dma(s)) {
buf->dma_handle = pci_map_single(s->itv->dev,
buf->buf, s->buf_size + 256, s->dma);
ivtv_buf_sync_for_cpu(s, buf);
@@ -242,7 +254,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
/* empty q_free */
while ((buf = ivtv_dequeue(s, &s->q_free))) {
- if (s->dma != PCI_DMA_NONE)
+ if (ivtv_might_use_dma(s))
pci_unmap_single(s->itv->dev, buf->dma_handle,
s->buf_size + 256, s->dma);
kfree(buf->buf);
@@ -256,6 +268,9 @@ void ivtv_stream_free(struct ivtv_stream *s)
sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
s->SG_handle = IVTV_DMA_UNMAPPED;
}
+ kfree(s->SGarray);
+ kfree(s->PIOarray);
+ s->PIOarray = NULL;
s->SGarray = NULL;
s->SG_length = 0;
}
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
index 903edd4b4381..2ed8d548255d 100644
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ b/drivers/media/video/ivtv/ivtv-queue.h
@@ -20,18 +20,43 @@
*/
#define IVTV_DMA_UNMAPPED ((u32) -1)
+#define SLICED_VBI_PIO 1
/* ivtv_buffer utility functions */
+
+static inline int ivtv_might_use_pio(struct ivtv_stream *s)
+{
+ return s->dma == PCI_DMA_NONE || (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI);
+}
+
+static inline int ivtv_use_pio(struct ivtv_stream *s)
+{
+ struct ivtv *itv = s->itv;
+
+ return s->dma == PCI_DMA_NONE ||
+ (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
+}
+
+static inline int ivtv_might_use_dma(struct ivtv_stream *s)
+{
+ return s->dma != PCI_DMA_NONE;
+}
+
+static inline int ivtv_use_dma(struct ivtv_stream *s)
+{
+ return !ivtv_use_pio(s);
+}
+
static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
- if (s->dma != PCI_DMA_NONE)
+ if (ivtv_use_dma(s))
pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
- if (s->dma != PCI_DMA_NONE)
+ if (ivtv_use_dma(s))
pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
@@ -53,12 +78,14 @@ void ivtv_stream_free(struct ivtv_stream *s);
static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
{
- pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
- sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+ if (ivtv_use_dma(s))
+ pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
+ sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
}
static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
{
- pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
- sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+ if (ivtv_use_dma(s))
+ pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
+ sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 01a41a844a30..6af88ae9295f 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -868,7 +868,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags))
return 0;
- IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", pts, flags);
+ IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
/* Stop Decoder */
if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) {
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 5efa5a867818..3ba46e07ea1f 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -450,7 +450,7 @@ void ivtv_disable_vbi(struct ivtv *itv)
}
-void vbi_work_handler(struct ivtv *itv)
+void ivtv_vbi_work_handler(struct ivtv *itv)
{
struct v4l2_sliced_vbi_data data;
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h
index cdaea697b3ec..ec211b49702c 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.h
+++ b/drivers/media/video/ivtv/ivtv-vbi.h
@@ -23,4 +23,4 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
int ivtv_used_line(struct ivtv *itv, int line, int field);
void ivtv_disable_vbi(struct ivtv *itv);
void ivtv_set_vbi(unsigned long arg);
-void vbi_work_handler(struct ivtv *itv);
+void ivtv_vbi_work_handler(struct ivtv *itv);
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
index 74839f98b7c4..c1a392e47170 100644
--- a/drivers/media/video/saa7111.c
+++ b/drivers/media/video/saa7111.c
@@ -75,10 +75,6 @@ struct saa7111 {
int norm;
int input;
int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
};
#define I2C_SAA7111 0x48
@@ -96,6 +92,17 @@ saa7111_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
+static inline void
+saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
+{
+ struct saa7111 *decoder = i2c_get_clientdata(client);
+
+ if (decoder->reg[reg] != value) {
+ decoder->reg[reg] = value;
+ i2c_smbus_write_byte_data(client, reg, value);
+ }
+}
+
static int
saa7111_write_block (struct i2c_client *client,
const u8 *data,
@@ -439,28 +446,14 @@ saa7111_command (struct i2c_client *client,
{
struct video_picture *pic = arg;
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- saa7111_write(client, 0x0a, decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->contrast = pic->contrast;
- saa7111_write(client, 0x0b,
- decoder->contrast >> 9);
- }
- if (decoder->sat != pic->colour) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->sat = pic->colour;
- saa7111_write(client, 0x0c, decoder->sat >> 9);
- }
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- saa7111_write(client, 0x0d,
- (decoder->hue - 32768) >> 8);
- }
+ /* We want 0 to 255 we get 0-65535 */
+ saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8);
+ /* We want 0 to 127 we get 0-65535 */
+ saa7111_write(client, 0x0b, pic->contrast >> 9);
+ /* We want 0 to 127 we get 0-65535 */
+ saa7111_write(client, 0x0c, pic->colour >> 9);
+ /* We want -128 to 127 we get 0-65535 */
+ saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
}
break;
@@ -524,10 +517,6 @@ saa7111_detect_client (struct i2c_adapter *adapter,
decoder->norm = VIDEO_MODE_NTSC;
decoder->input = 0;
decoder->enable = 1;
- decoder->bright = 32768;
- decoder->contrast = 32768;
- decoder->hue = 32768;
- decoder->sat = 32768;
i2c_set_clientdata(client, decoder);
i = i2c_attach_client(client);
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 9118a6227ea6..7df071eb0a3b 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -1414,6 +1414,11 @@ static void usbvision_isocIrq(struct urb *urb)
if (!USBVISION_IS_OPERATIONAL(usbvision))
return;
+ /* any urb with wrong status is ignored without acknowledgement */
+ if (urb->status == -ENOENT) {
+ return;
+ }
+
f = &usbvision->curFrame;
/* Manage streaming interruption */
@@ -1436,18 +1441,21 @@ static void usbvision_isocIrq(struct urb *urb)
if (usbvision->streaming == Stream_On) {
/* If we collected enough data let's parse! */
- if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH) { /* 12 == header_length */
- /*If we don't have a frame we're current working on, complain */
- if(!list_empty(&(usbvision->inqueue))) {
- if (!(*f)) {
- (*f) = list_entry(usbvision->inqueue.next,struct usbvision_frame, frame);
- }
- usbvision_parse_data(usbvision);
- }
- else {
- PDEBUG(DBG_IRQ, "received data, but no one needs it");
- scratch_reset(usbvision);
+ if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) &&
+ (!list_empty(&(usbvision->inqueue))) ) {
+ if (!(*f)) {
+ (*f) = list_entry(usbvision->inqueue.next,
+ struct usbvision_frame,
+ frame);
}
+ usbvision_parse_data(usbvision);
+ }
+ else {
+ /*If we don't have a frame
+ we're current working on, complain */
+ PDEBUG(DBG_IRQ,
+ "received data, but no one needs it");
+ scratch_reset(usbvision);
}
}
else {
@@ -1466,10 +1474,10 @@ static void usbvision_isocIrq(struct urb *urb)
urb->dev = usbvision->dev;
errCode = usb_submit_urb (urb, GFP_ATOMIC);
- /* Disable this warning. By design of the driver. */
- // if(errCode) {
- // err("%s: usb_submit_urb failed: error %d", __FUNCTION__, errCode);
- // }
+ if(errCode) {
+ err("%s: usb_submit_urb failed: error %d",
+ __FUNCTION__, errCode);
+ }
return;
}
@@ -2394,7 +2402,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
{
struct usb_device *dev = usbvision->dev;
int bufIdx, errCode, regValue;
- const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
+ int sb_size;
if (!USBVISION_IS_OPERATIONAL(usbvision))
return -EFAULT;
@@ -2408,11 +2416,14 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
usbvision->last_error = errCode;
return -EBUSY;
}
+ sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
- regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
+ regValue = (16 - usbvision_read_reg(usbvision,
+ USBVISION_ALTER_REG)) & 0x0F;
usbvision->usb_bandwidth = regValue >> 1;
- PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
+ PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
+ usbvision->usb_bandwidth);
@@ -2428,7 +2439,11 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
return -ENOMEM;
}
usbvision->sbuf[bufIdx].urb = urb;
- usbvision->sbuf[bufIdx].data = usb_buffer_alloc(usbvision->dev, sb_size, GFP_KERNEL,&urb->transfer_dma);
+ usbvision->sbuf[bufIdx].data =
+ usb_buffer_alloc(usbvision->dev,
+ sb_size,
+ GFP_KERNEL,
+ &urb->transfer_dma);
urb->dev = dev;
urb->context = usbvision;
urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
@@ -2442,21 +2457,26 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
k += usbvision->isocPacketSize) {
urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length = usbvision->isocPacketSize;
+ urb->iso_frame_desc[j].length =
+ usbvision->isocPacketSize;
}
}
/* Submit all URBs */
for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
- errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, GFP_KERNEL);
+ errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
+ GFP_KERNEL);
if (errCode) {
- err("%s: usb_submit_urb(%d) failed: error %d", __FUNCTION__, bufIdx, errCode);
+ err("%s: usb_submit_urb(%d) failed: error %d",
+ __FUNCTION__, bufIdx, errCode);
}
}
usbvision->streaming = Stream_Idle;
- PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp);
+ PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x",
+ __FUNCTION__,
+ usbvision->video_endp);
return 0;
}
@@ -2470,7 +2490,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
void usbvision_stop_isoc(struct usb_usbvision *usbvision)
{
int bufIdx, errCode, regValue;
- const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
+ int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
return;
@@ -2499,15 +2519,19 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
usbvision->ifaceAlt);
if (errCode < 0) {
- err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode);
+ err("%s: usb_set_interface() failed: error %d",
+ __FUNCTION__, errCode);
usbvision->last_error = errCode;
}
- regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
- usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1;
- PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize);
+ regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
+ usbvision->isocPacketSize =
+ (regValue == 0) ? 0 : (regValue * 64) - 1;
+ PDEBUG(DBG_ISOC, "ISO Packet Length:%d",
+ usbvision->isocPacketSize);
usbvision->usb_bandwidth = regValue >> 1;
- PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
+ PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
+ usbvision->usb_bandwidth);
}
}
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index bd6f6422ed54..c759d00d7014 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -146,7 +146,6 @@
#define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask
#define USBVISION_URB_FRAMES 32
-#define USBVISION_MAX_ISOC_PACKET_SIZE 959 // NT1003 Specs Document says 1023
#define USBVISION_NUM_HEADERMARKER 20
#define USBVISION_NUMFRAMES 3 /* Maximum number of frames an application can get */
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index c1dfd03d559a..41bfb5dfe6ff 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -15,6 +15,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
#include "core.h"
#include "sysfs.h"
@@ -192,6 +193,16 @@ static int mmc_read_switch(struct mmc_card *card)
int err;
u8 *status;
+ if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+ return MMC_ERR_NONE;
+
+ if (!(card->csd.cmdclass & CCC_SWITCH)) {
+ printk(KERN_WARNING "%s: card lacks mandatory switch "
+ "function, performance might suffer.\n",
+ mmc_hostname(card->host));
+ return MMC_ERR_NONE;
+ }
+
err = MMC_ERR_FAILED;
status = kmalloc(64, GFP_KERNEL);
@@ -204,10 +215,9 @@ static int mmc_read_switch(struct mmc_card *card)
err = mmc_sd_switch(card, 0, 0, 1, status);
if (err != MMC_ERR_NONE) {
- /*
- * Card not supporting high-speed will ignore the
- * command.
- */
+ printk(KERN_WARNING "%s: problem reading switch "
+ "capabilities, performance might suffer.\n",
+ mmc_hostname(card->host));
err = MMC_ERR_NONE;
goto out;
}
@@ -229,6 +239,12 @@ static int mmc_switch_hs(struct mmc_card *card)
int err;
u8 *status;
+ if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+ return MMC_ERR_NONE;
+
+ if (!(card->csd.cmdclass & CCC_SWITCH))
+ return MMC_ERR_NONE;
+
if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
return MMC_ERR_NONE;
@@ -402,7 +418,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
/*
* Switch to wider bus (if supported).
*/
- if ((host->caps && MMC_CAP_4_BIT_DATA) &&
+ if ((host->caps & MMC_CAP_4_BIT_DATA) &&
(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
if (err != MMC_ERR_NONE)
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index e37943c314cb..5b00c194b628 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -417,7 +417,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
blocks = 0;
}
- if (cmd->opcode == MMC_STOP_TRANSMISSION)
+ if (host->flags & FL_SENT_STOP)
cmdr |= AT91_MCI_TRCMD_STOP;
if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
@@ -563,8 +563,7 @@ static void at91mci_completed_command(struct at91mci_host *host)
if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |
AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
- if ((status & AT91_MCI_RCRCE) &&
- ((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) {
+ if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
cmd->error = MMC_ERR_NONE;
}
else {
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index f967226d7505..52b63f11ddd6 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -76,8 +76,7 @@ const struct {
#endif
};
-#define AU1XMMC_CONTROLLER_COUNT \
- (sizeof(au1xmmc_card_table) / sizeof(au1xmmc_card_table[0]))
+#define AU1XMMC_CONTROLLER_COUNT (ARRAY_SIZE(au1xmmc_card_table))
/* This array stores pointers for the hosts (used by the IRQ handler) */
struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];
diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c
index 437d78ad0912..39253d0c1590 100644
--- a/drivers/net/mlx4/cq.c
+++ b/drivers/net/mlx4/cq.c
@@ -61,7 +61,7 @@ struct mlx4_cq_context {
__be32 solicit_producer_index;
__be32 consumer_index;
__be32 producer_index;
- u8 reserved6[2];
+ u32 reserved6[2];
__be64 db_rec_addr;
};
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 0f11adb8eb4a..27a82cecd693 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -490,9 +490,11 @@ static void mlx4_free_irqs(struct mlx4_dev *dev)
if (eq_table->have_irq)
free_irq(dev->pdev->irq, dev);
- for (i = 0; i < MLX4_NUM_EQ; ++i)
+ for (i = 0; i < MLX4_EQ_CATAS; ++i)
if (eq_table->eq[i].have_irq)
free_irq(eq_table->eq[i].irq, eq_table->eq + i);
+ if (eq_table->eq[MLX4_EQ_CATAS].have_irq)
+ free_irq(eq_table->eq[MLX4_EQ_CATAS].irq, dev);
}
static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev)
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index cfa5cc072339..e7ca118c8dfd 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -37,6 +37,10 @@
#include "fw.h"
#include "icm.h"
+enum {
+ MLX4_COMMAND_INTERFACE_REV = 1
+};
+
extern void __buggy_use_of_MLX4_GET(void);
extern void __buggy_use_of_MLX4_PUT(void);
@@ -452,10 +456,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
u32 *outbox;
int err = 0;
u64 fw_ver;
+ u16 cmd_if_rev;
u8 lg;
#define QUERY_FW_OUT_SIZE 0x100
#define QUERY_FW_VER_OFFSET 0x00
+#define QUERY_FW_CMD_IF_REV_OFFSET 0x0a
#define QUERY_FW_MAX_CMD_OFFSET 0x0f
#define QUERY_FW_ERR_START_OFFSET 0x30
#define QUERY_FW_ERR_SIZE_OFFSET 0x38
@@ -477,21 +483,36 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
MLX4_GET(fw_ver, outbox, QUERY_FW_VER_OFFSET);
/*
- * FW subminor version is at more signifant bits than minor
+ * FW subminor version is at more significant bits than minor
* version, so swap here.
*/
dev->caps.fw_ver = (fw_ver & 0xffff00000000ull) |
((fw_ver & 0xffff0000ull) >> 16) |
((fw_ver & 0x0000ffffull) << 16);
+ MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET);
+ if (cmd_if_rev != MLX4_COMMAND_INTERFACE_REV) {
+ mlx4_err(dev, "Installed FW has unsupported "
+ "command interface revision %d.\n",
+ cmd_if_rev);
+ mlx4_err(dev, "(Installed FW version is %d.%d.%03d)\n",
+ (int) (dev->caps.fw_ver >> 32),
+ (int) (dev->caps.fw_ver >> 16) & 0xffff,
+ (int) dev->caps.fw_ver & 0xffff);
+ mlx4_err(dev, "This driver version supports only revision %d.\n",
+ MLX4_COMMAND_INTERFACE_REV);
+ err = -ENODEV;
+ goto out;
+ }
+
MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
cmd->max_cmds = 1 << lg;
- mlx4_dbg(dev, "FW version %d.%d.%03d, max commands %d\n",
+ mlx4_dbg(dev, "FW version %d.%d.%03d (cmd intf rev %d), max commands %d\n",
(int) (dev->caps.fw_ver >> 32),
(int) (dev->caps.fw_ver >> 16) & 0xffff,
(int) dev->caps.fw_ver & 0xffff,
- cmd->max_cmds);
+ cmd_if_rev, cmd->max_cmds);
MLX4_GET(fw->catas_offset, outbox, QUERY_FW_ERR_START_OFFSET);
MLX4_GET(fw->catas_size, outbox, QUERY_FW_ERR_SIZE_OFFSET);
diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c
index 65854f9e9c76..9ae951bf6aa6 100644
--- a/drivers/net/mlx4/intf.c
+++ b/drivers/net/mlx4/intf.c
@@ -135,9 +135,6 @@ int mlx4_register_device(struct mlx4_dev *dev)
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_interface *intf;
- INIT_LIST_HEAD(&priv->ctx_list);
- spin_lock_init(&priv->ctx_lock);
-
mutex_lock(&intf_mutex);
list_add_tail(&priv->dev_list, &dev_list);
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 20b8c0d3ced4..d4172937025b 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -787,6 +787,8 @@ static int __devinit mlx4_init_one(struct pci_dev *pdev,
dev = &priv->dev;
dev->pdev = pdev;
+ INIT_LIST_HEAD(&priv->ctx_list);
+ spin_lock_init(&priv->ctx_lock);
/*
* Now reset the HCA before we touch the PCI capabilities or
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c
index b33864dab179..d0808fa3ec82 100644
--- a/drivers/net/mlx4/mr.c
+++ b/drivers/net/mlx4/mr.c
@@ -324,15 +324,17 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
MLX4_MPT_FLAG_MIO |
MLX4_MPT_FLAG_REGION |
mr->access);
- if (mr->mtt.order < 0)
- mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL);
mpt_entry->key = cpu_to_be32(key_to_hw_index(mr->key));
mpt_entry->pd = cpu_to_be32(mr->pd);
mpt_entry->start = cpu_to_be64(mr->iova);
mpt_entry->length = cpu_to_be64(mr->size);
mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift);
- mpt_entry->mtt_seg = cpu_to_be64(mlx4_mtt_addr(dev, &mr->mtt));
+ if (mr->mtt.order < 0) {
+ mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL);
+ mpt_entry->mtt_seg = 0;
+ } else
+ mpt_entry->mtt_seg = cpu_to_be64(mlx4_mtt_addr(dev, &mr->mtt));
err = mlx4_SW2HW_MPT(dev, mailbox,
key_to_hw_index(mr->key) & (dev->caps.num_mpts - 1));
OpenPOWER on IntegriCloud