diff options
Diffstat (limited to 'drivers')
147 files changed, 1376 insertions, 1002 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 0458811..9c07b886 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -578,6 +578,7 @@ static const struct ich_laptop ich_laptop[] = { { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */ { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ + { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ /* end marker */ { 0, } }; diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a6de57e..3ca9c61 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3022,7 +3022,7 @@ int ata_wait_ready(struct ata_port *ap, unsigned long deadline) if (!(status & ATA_BUSY)) return 0; - if (status == 0xff) + if (!ata_port_online(ap) && status == 0xff) return -ENODEV; if (time_after(now, deadline)) return -EBUSY; @@ -3368,7 +3368,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline) */ if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap)) { rc = ata_wait_ready(ap, deadline); - if (rc) { + if (rc && rc != -ENODEV) { ata_port_printk(ap, KERN_WARNING, "device not ready " "(errno=%d), forcing hardreset\n", rc); ehc->i.action |= ATA_EH_HARDRESET; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 242c43e..b3900cf 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1050,14 +1050,15 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc) static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen) { u64 lba = 0; - u32 len = 0; + u32 len; VPRINTK("six-byte command\n"); + lba |= ((u64)(cdb[1] & 0x1f)) << 16; lba |= ((u64)cdb[2]) << 8; lba |= ((u64)cdb[3]); - len |= ((u32)cdb[4]); + len = cdb[4]; *plba = lba; *plen = len; diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 7b4810c..03b6ddd 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -97,7 +97,7 @@ static int artop6260_pre_reset(struct ata_port *ap, unsigned long deadline) * artop6260_cable_detect - identify cable type * @ap: Port * - * Identify the cable type for the ARTOp interface in question + * Identify the cable type for the ARTOP interface in question */ static int artop6260_cable_detect(struct ata_port *ap) diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index a54c174..6446735 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -26,7 +26,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.5" +#define DRV_VERSION "0.6.6" struct hpt_clock { u8 xfer_speed; @@ -931,15 +931,6 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x7f, .port_ops = &hpt372_port_ops }; - /* HPT371, 372 and friends - UDMA100 at 50MHz clock */ - static const struct ata_port_info info_hpt372_50 = { - .sht = &hpt37x_sht, - .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, - .pio_mask = 0x1f, - .mwdma_mask = 0x07, - .udma_mask = 0x3f, - .port_ops = &hpt372_port_ops - }; /* HPT374 - UDMA133 */ static const struct ata_port_info info_hpt374 = { .sht = &hpt37x_sht, @@ -1098,17 +1089,21 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) * use a 50MHz DPLL by choice */ unsigned int f_low, f_high; - int adjust; + int dpll, adjust; - clock_slot = 2; + /* Compute DPLL */ + dpll = 2; if (port->udma_mask & 0xE0) - clock_slot = 3; + dpll = 3; - f_low = (MHz[clock_slot] * chip_table->base) / 192; + f_low = (MHz[clock_slot] * 48) / MHz[dpll]; f_high = f_low + 2; + if (clock_slot > 1) + f_high += 2; /* Select the DPLL clock. */ pci_write_config_byte(dev, 0x5b, 0x21); + pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); for(adjust = 0; adjust < 8; adjust++) { if (hpt37x_calibrate_dpll(dev)) @@ -1124,12 +1119,12 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); return -ENODEV; } - if (clock_slot == 3) + if (dpll == 3) private_data = (void *)hpt37x_timings_66; else private_data = (void *)hpt37x_timings_50; - printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]); + printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]); } else { private_data = (void *)chip_table->clocks[clock_slot]; /* diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index f25154a..e947433 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -521,8 +521,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* 371N if rev > 1 */ break; case PCI_DEVICE_ID_TTI_HPT372: - /* 372N if rev >= 1*/ - if (class_rev == 0) + /* 372N if rev >= 2*/ + if (class_rev < 2) return -ENODEV; break; case PCI_DEVICE_ID_TTI_HPT302: diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index ff9a6fd..b3456d7 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -1,5 +1,5 @@ /* - * ata-it821x.c - IT821x PATA for new ATA layer + * pata_it821x.c - IT821x PATA for new ATA layer * (C) 2005 Red Hat Inc * Alan Cox <alan@redhat.com> * @@ -65,7 +65,6 @@ * * TODO * - ATAPI and other speed filtering - * - Command filter in smart mode * - RAID configuration ioctls */ diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index aa138d2..61502bc 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -489,23 +489,26 @@ static unsigned int scc_devchk (struct ata_port *ap, * Note: Original code is ata_bus_post_reset(). */ -static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask) +static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask, + unsigned long deadline) { struct ata_ioports *ioaddr = &ap->ioaddr; unsigned int dev0 = devmask & (1 << 0); unsigned int dev1 = devmask & (1 << 1); - unsigned long timeout; + int rc; /* if device 0 was found in ata_devchk, wait for its * BSY bit to clear */ - if (dev0) - ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); + if (dev0) { + rc = ata_wait_ready(ap, deadline); + if (rc && rc != -ENODEV) + return rc; + } /* if device 1 was found in ata_devchk, wait for * register access, then wait for BSY to clear */ - timeout = jiffies + ATA_TMOUT_BOOT; while (dev1) { u8 nsect, lbal; @@ -514,14 +517,15 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask) lbal = in_be32(ioaddr->lbal_addr); if ((nsect == 1) && (lbal == 1)) break; - if (time_after(jiffies, timeout)) { - dev1 = 0; - break; - } + if (time_after(jiffies, deadline)) + return -EBUSY; msleep(50); /* give drive a breather */ } - if (dev1) - ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); + if (dev1) { + rc = ata_wait_ready(ap, deadline); + if (rc && rc != -ENODEV) + return rc; + } /* is all this really necessary? */ ap->ops->dev_select(ap, 0); @@ -529,6 +533,8 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask) ap->ops->dev_select(ap, 1); if (dev0) ap->ops->dev_select(ap, 0); + + return 0; } /** @@ -537,8 +543,8 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask) * Note: Original code is ata_bus_softreset(). */ -static unsigned int scc_bus_softreset (struct ata_port *ap, - unsigned int devmask) +static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask, + unsigned long deadline) { struct ata_ioports *ioaddr = &ap->ioaddr; @@ -570,7 +576,7 @@ static unsigned int scc_bus_softreset (struct ata_port *ap, if (scc_check_status(ap) == 0xFF) return 0; - scc_bus_post_reset(ap, devmask); + scc_bus_post_reset(ap, devmask, deadline); return 0; } @@ -579,11 +585,13 @@ static unsigned int scc_bus_softreset (struct ata_port *ap, * scc_std_softreset - reset host port via ATA SRST * @ap: port to reset * @classes: resulting classes of attached devices + * @deadline: deadline jiffies for the operation * * Note: Original code is ata_std_softreset(). */ -static int scc_std_softreset (struct ata_port *ap, unsigned int *classes) +static int scc_std_softreset (struct ata_port *ap, unsigned int *classes, + unsigned long deadline) { unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; unsigned int devmask = 0, err_mask; @@ -607,7 +615,7 @@ static int scc_std_softreset (struct ata_port *ap, unsigned int *classes) /* issue bus reset */ DPRINTK("about to softreset, devmask=%x\n", devmask); - err_mask = scc_bus_softreset(ap, devmask); + err_mask = scc_bus_softreset(ap, devmask, deadline); if (err_mask) { ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n", err_mask); @@ -676,10 +684,11 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc) if (reg & INTSTS_BMSINT) { unsigned int classes; + unsigned long deadline = jiffies + ATA_TMOUT_BOOT; printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); /* TBD: SW reset */ - scc_std_softreset(ap, &classes); + scc_std_softreset(ap, &classes, deadline); continue; } @@ -862,9 +871,10 @@ static void scc_bmdma_freeze (struct ata_port *ap) /** * scc_pata_prereset - prepare for reset * @ap: ATA port to be reset + * @deadline: deadline jiffies for the operation */ -static int scc_pata_prereset (struct ata_port *ap, unsigned long deadline) +static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline) { ap->cbl = ATA_CBL_PATA80; return ata_std_prereset(ap, deadline); diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index f223126..ec3ae93 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -73,14 +73,14 @@ static int sis_short_ata40(struct pci_dev *dev) } /** - * sis_port_base - return PCI configuration base for dev + * sis_old_port_base - return PCI configuration base for dev * @adev: device * * Returns the base of the PCI configuration registers for this port * number. */ -static int sis_port_base(struct ata_device *adev) +static int sis_old_port_base(struct ata_device *adev) { return 0x40 + (4 * adev->ap->port_no) + (2 * adev->devno); } @@ -211,7 +211,7 @@ static void sis_set_fifo(struct ata_port *ap, struct ata_device *adev) static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - int port = sis_port_base(adev); + int port = sis_old_port_base(adev); u8 t1, t2; int speed = adev->pio_mode - XFER_PIO_0; @@ -248,7 +248,7 @@ static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev) static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - int port = sis_port_base(adev); + int port = sis_old_port_base(adev); int speed = adev->pio_mode - XFER_PIO_0; const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 }; @@ -328,7 +328,7 @@ static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); int speed = adev->dma_mode - XFER_MW_DMA_0; - int drive_pci = sis_port_base(adev); + int drive_pci = sis_old_port_base(adev); u16 timing; const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 }; @@ -367,7 +367,7 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); int speed = adev->dma_mode - XFER_MW_DMA_0; - int drive_pci = sis_port_base(adev); + int drive_pci = sis_old_port_base(adev); u16 timing; const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 }; @@ -378,12 +378,12 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev) if (adev->dma_mode < XFER_UDMA_0) { /* bits 3-0 hold recovery timing bits 8-10 active timing and the higer bits are dependant on the device, bit 15 udma */ - timing &= ~ 0x870F; + timing &= ~0x870F; timing |= mwdma_bits[speed]; } else { /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ speed = adev->dma_mode - XFER_UDMA_0; - timing &= ~0x6000; + timing &= ~0xF000; timing |= udma_bits[speed]; } pci_write_config_word(pdev, drive_pci, timing); @@ -405,22 +405,22 @@ static void sis_100_set_dmamode (struct ata_port *ap, struct ata_device *adev) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); int speed = adev->dma_mode - XFER_MW_DMA_0; - int drive_pci = sis_port_base(adev); - u16 timing; + int drive_pci = sis_old_port_base(adev); + u8 timing; - const u16 udma_bits[] = { 0x8B00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100}; + const u8 udma_bits[] = { 0x8B, 0x87, 0x85, 0x83, 0x82, 0x81}; - pci_read_config_word(pdev, drive_pci, &timing); + pci_read_config_byte(pdev, drive_pci + 1, &timing); if (adev->dma_mode < XFER_UDMA_0) { /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ } else { - /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ + /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */ speed = adev->dma_mode - XFER_UDMA_0; - timing &= ~0x0F00; + timing &= ~0x8F; timing |= udma_bits[speed]; } - pci_write_config_word(pdev, drive_pci, timing); + pci_write_config_byte(pdev, drive_pci + 1, timing); } /** @@ -440,22 +440,22 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a { struct pci_dev *pdev = to_pci_dev(ap->host->dev); int speed = adev->dma_mode - XFER_MW_DMA_0; - int drive_pci = sis_port_base(adev); - u16 timing; - - static const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100}; + int drive_pci = sis_old_port_base(adev); + u8 timing; + /* Low 4 bits are timing */ + static const u8 udma_bits[] = { 0x8F, 0x8A, 0x87, 0x85, 0x83, 0x82, 0x81}; - pci_read_config_word(pdev, drive_pci, &timing); + pci_read_config_byte(pdev, drive_pci + 1, &timing); if (adev->dma_mode < XFER_UDMA_0) { /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ } else { - /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */ + /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */ speed = adev->dma_mode - XFER_UDMA_0; - timing &= ~0x0F00; + timing &= ~0x8F; timing |= udma_bits[speed]; } - pci_write_config_word(pdev, drive_pci, timing); + pci_write_config_byte(pdev, drive_pci + 1, timing); } /** diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index e4c71f7..a8462f1 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -60,6 +60,7 @@ #include <linux/delay.h> #include <scsi/scsi_host.h> #include <linux/libata.h> +#include <linux/dmi.h> #define DRV_NAME "pata_via" #define DRV_VERSION "0.3.1" @@ -122,6 +123,31 @@ static const struct via_isa_bridge { { NULL } }; + +/* + * Cable special cases + */ + +static struct dmi_system_id cable_dmi_table[] = { + { + .ident = "Acer Ferrari 3400", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."), + DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"), + }, + }, + { } +}; + +static int via_cable_override(struct pci_dev *pdev) +{ + /* Systems by DMI */ + if (dmi_check_system(cable_dmi_table)) + return 1; + return 0; +} + + /** * via_cable_detect - cable detection * @ap: ATA port @@ -139,6 +165,9 @@ static int via_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 ata66; + if (via_cable_override(pdev)) + return ATA_CBL_PATA40_SHORT; + /* Early chips are 40 wire */ if ((config->flags & VIA_UDMA) < VIA_UDMA_66) return ATA_CBL_PATA40; @@ -592,10 +621,11 @@ static int via_reinit_one(struct pci_dev *pdev) #endif static const struct pci_device_id via[] = { - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), }, + { PCI_VDEVICE(VIA, 0x0571), }, + { PCI_VDEVICE(VIA, 0x0581), }, + { PCI_VDEVICE(VIA, 0x1571), }, + { PCI_VDEVICE(VIA, 0x3164), }, + { PCI_VDEVICE(VIA, 0x5324), }, { }, }; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 705a020..c957e6e 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -21,6 +21,50 @@ * */ +/* + sata_mv TODO list: + + 1) Needs a full errata audit for all chipsets. I implemented most + of the errata workarounds found in the Marvell vendor driver, but + I distinctly remember a couple workarounds (one related to PCI-X) + are still needed. + + 2) Convert to LibATA new EH. Required for hotplug, NCQ, and sane + probing/error handling in general. MUST HAVE. + + 3) Add hotplug support (easy, once new-EH support appears) + + 4) Add NCQ support (easy to intermediate, once new-EH support appears) + + 5) Investigate problems with PCI Message Signalled Interrupts (MSI). + + 6) Add port multiplier support (intermediate) + + 7) Test and verify 3.0 Gbps support + + 8) Develop a low-power-consumption strategy, and implement it. + + 9) [Experiment, low priority] See if ATAPI can be supported using + "unknown FIS" or "vendor-specific FIS" support, or something creative + like that. + + 10) [Experiment, low priority] Investigate interrupt coalescing. + Quite often, especially with PCI Message Signalled Interrupts (MSI), + the overhead reduced by interrupt mitigation is quite often not + worth the latency cost. + + 11) [Experiment, Marvell value added] Is it possible to use target + mode to cross-connect two Linux boxes with Marvell cards? If so, + creating LibATA target mode support would be very interesting. + + Target mode, for those without docs, is the ability to directly + connect two SATA controllers. + + 13) Verify that 7042 is fully supported. I only have a 6042. + +*/ + + #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 3a7d9b5..2b924a6 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -297,7 +297,7 @@ static const struct ata_port_info pdc_port_info[] = { /* board_2057x_pata */ { - .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, + .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS | PDC_FLAG_GEN_II, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 51d9251b0..221099d 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -255,7 +255,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; struct ata_port_info pi = sis_port_info; - const struct ata_port_info *ppi[] = { &pi, NULL }; + const struct ata_port_info *ppi[] = { &pi, &pi }; struct ata_host *host; u32 genctl, val; u8 pmr; diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 01bba26..e8b90e7 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -85,6 +85,9 @@ static const struct pci_device_id svia_pci_tbl[] = { { PCI_VDEVICE(VIA, 0x0591), vt6420 }, { PCI_VDEVICE(VIA, 0x3149), vt6420 }, { PCI_VDEVICE(VIA, 0x3249), vt6421 }, + { PCI_VDEVICE(VIA, 0x5287), vt6420 }, + { PCI_VDEVICE(VIA, 0x5372), vt6420 }, + { PCI_VDEVICE(VIA, 0x7372), vt6420 }, { } /* terminate list */ }; diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 057efbc..3800bc0 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -47,7 +47,8 @@ static char const rcsid[] = #include <linux/bitops.h> #include <linux/wait.h> #include <linux/jiffies.h> -#include <asm/semaphore.h> +#include <linux/mutex.h> + #include <asm/io.h> #include <asm/uaccess.h> #include <asm/atomic.h> @@ -2435,7 +2436,7 @@ idt77252_open(struct atm_vcc *vcc) set_bit(ATM_VF_ADDR, &vcc->flags); - down(&card->mutex); + mutex_lock(&card->mutex); OPRINTK("%s: opening vpi.vci: %d.%d\n", card->name, vpi, vci); @@ -2446,7 +2447,7 @@ idt77252_open(struct atm_vcc *vcc) break; default: printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal); - up(&card->mutex); + mutex_unlock(&card->mutex); return -EPROTONOSUPPORT; } @@ -2455,7 +2456,7 @@ idt77252_open(struct atm_vcc *vcc) card->vcs[index] = kzalloc(sizeof(struct vc_map), GFP_KERNEL); if (!card->vcs[index]) { printk("%s: can't alloc vc in open()\n", card->name); - up(&card->mutex); + mutex_unlock(&card->mutex); return -ENOMEM; } card->vcs[index]->card = card; @@ -2484,14 +2485,14 @@ idt77252_open(struct atm_vcc *vcc) if (inuse) { printk("%s: %s vci already in use.\n", card->name, inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx"); - up(&card->mutex); + mutex_unlock(&card->mutex); return -EADDRINUSE; } if (vcc->qos.txtp.traffic_class != ATM_NONE) { error = idt77252_init_tx(card, vc, vcc, &vcc->qos); if (error) { - up(&card->mutex); + mutex_unlock(&card->mutex); return error; } } @@ -2499,14 +2500,14 @@ idt77252_open(struct atm_vcc *vcc) if (vcc->qos.rxtp.traffic_class != ATM_NONE) { error = idt77252_init_rx(card, vc, vcc, &vcc->qos); if (error) { - up(&card->mutex); + mutex_unlock(&card->mutex); return error; } } set_bit(ATM_VF_READY, &vcc->flags); - up(&card->mutex); + mutex_unlock(&card->mutex); return 0; } @@ -2520,7 +2521,7 @@ idt77252_close(struct atm_vcc *vcc) unsigned long addr; unsigned long timeout; - down(&card->mutex); + mutex_lock(&card->mutex); IPRINTK("%s: idt77252_close: vc = %d (%d.%d)\n", card->name, vc->index, vcc->vpi, vcc->vci); @@ -2591,7 +2592,7 @@ done: free_scq(card, vc->scq); } - up(&card->mutex); + mutex_unlock(&card->mutex); } static int @@ -2602,7 +2603,7 @@ idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags) struct vc_map *vc = vcc->dev_data; int error = 0; - down(&card->mutex); + mutex_lock(&card->mutex); if (qos->txtp.traffic_class != ATM_NONE) { if (!test_bit(VCF_TX, &vc->flags)) { @@ -2648,7 +2649,7 @@ idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags) set_bit(ATM_VF_HASQOS, &vcc->flags); out: - up(&card->mutex); + mutex_unlock(&card->mutex); return error; } @@ -3709,7 +3710,7 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) membase = pci_resource_start(pcidev, 1); srambase = pci_resource_start(pcidev, 2); - init_MUTEX(&card->mutex); + mutex_init(&card->mutex); spin_lock_init(&card->cmd_lock); spin_lock_init(&card->tst_lock); diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h index 544b397..6f2b4a5 100644 --- a/drivers/atm/idt77252.h +++ b/drivers/atm/idt77252.h @@ -37,7 +37,7 @@ #include <linux/ptrace.h> #include <linux/skbuff.h> #include <linux/workqueue.h> - +#include <linux/mutex.h> /*****************************************************************************/ /* */ @@ -359,7 +359,7 @@ struct idt77252_dev unsigned long srambase; /* SAR's sram base address */ void __iomem *fbq[4]; /* FBQ fill addresses */ - struct semaphore mutex; + struct mutex mutex; spinlock_t cmd_lock; /* for r/w utility/sram */ unsigned long softstat; diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 3587cb4..fe08804 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -670,7 +670,7 @@ static void __reschedule_timeout(int drive, const char *message, int marg) if (drive == current_reqD) drive = current_drive; del_timer(&fd_timeout); - if (drive < 0 || drive > N_DRIVE) { + if (drive < 0 || drive >= N_DRIVE) { fd_timeout.expires = jiffies + 20UL * HZ; drive = 0; } else diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index b0238b4..7e04dd6 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -115,11 +115,11 @@ static struct usb_device_id blacklist_ids[] = { { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 }, /* Broadcom BCM2045 */ - { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_WRONG_SCO_MTU }, + { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, /* IBM/Lenovo ThinkPad with Broadcom chip */ - { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU }, - { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_WRONG_SCO_MTU }, + { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, + { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, /* Targus ACB10US */ { USB_DEVICE(0x0a5c, 0x2100), .driver_info = HCI_RESET }, @@ -128,17 +128,17 @@ static struct usb_device_id blacklist_ids[] = { { USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET }, /* HP laptop with Broadcom chip */ - { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_WRONG_SCO_MTU }, + { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, /* Dell laptop with Broadcom chip */ - { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_WRONG_SCO_MTU }, + { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, /* Kensington Bluetooth USB adapter */ { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET }, - { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_WRONG_SCO_MTU }, + { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, /* ISSC Bluetooth Adapter v3.1 */ { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, @@ -148,8 +148,8 @@ static struct usb_device_id blacklist_ids[] = { { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC }, /* Belkin F8T012 and F8T013 devices */ - { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU }, - { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU }, + { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, + { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, /* Digianswer devices */ { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index abcafac..ef683eb 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -815,7 +815,7 @@ config SGI_IP27_RTC config GEN_RTC tristate "Generic /dev/rtc emulation" - depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390 + depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390 && !SUPERH ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index c72ee97..ca376b9 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -1061,6 +1061,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, if (data & info->ignore_status_mask) { info->icount.rx++; + spin_unlock(&cinfo->card_lock); return; } if (tty_buffer_request_room(tty, 1)) { diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c index 6d3840e..6a86958 100644 --- a/drivers/crypto/geode-aes.c +++ b/drivers/crypto/geode-aes.c @@ -102,10 +102,15 @@ geode_aes_crypt(struct geode_aes_op *op) u32 flags = 0; unsigned long iflags; - if (op->len == 0 || op->src == op->dst) + if (op->len == 0) return 0; - if (op->flags & AES_FLAGS_COHERENT) + /* If the source and destination is the same, then + * we need to turn on the coherent flags, otherwise + * we don't need to worry + */ + + if (op->src == op->dst) flags |= (AES_CTRL_DCA | AES_CTRL_SCA); if (op->dir == AES_DIR_ENCRYPT) @@ -120,7 +125,7 @@ geode_aes_crypt(struct geode_aes_op *op) _writefield(AES_WRITEIV0_REG, op->iv); } - if (op->flags & AES_FLAGS_USRKEY) { + if (!(op->flags & AES_FLAGS_HIDDENKEY)) { flags |= AES_CTRL_WRKEY; _writefield(AES_WRITEKEY0_REG, op->key); } @@ -289,6 +294,7 @@ static struct crypto_alg geode_cbc_alg = { .setkey = geode_setkey, .encrypt = geode_cbc_encrypt, .decrypt = geode_cbc_decrypt, + .ivsize = AES_IV_LENGTH, } } }; diff --git a/drivers/crypto/geode-aes.h b/drivers/crypto/geode-aes.h index 8003a36..f479686 100644 --- a/drivers/crypto/geode-aes.h +++ b/drivers/crypto/geode-aes.h @@ -20,8 +20,7 @@ #define AES_DIR_DECRYPT 0 #define AES_DIR_ENCRYPT 1 -#define AES_FLAGS_USRKEY (1 << 0) -#define AES_FLAGS_COHERENT (1 << 1) +#define AES_FLAGS_HIDDENKEY (1 << 0) struct geode_aes_op { diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 0c160675..366f4a1 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -491,6 +491,12 @@ out: /* Sysfs Files */ +static ssize_t applesmc_name_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "applesmc\n"); +} + static ssize_t applesmc_position_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -913,6 +919,8 @@ static struct led_classdev applesmc_backlight = { .brightness_set = applesmc_brightness_set, }; +static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL); + static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL); static DEVICE_ATTR(calibrate, 0644, applesmc_calibrate_show, applesmc_calibrate_store); @@ -1197,6 +1205,8 @@ static int __init applesmc_init(void) goto out_driver; } + ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr); + /* Create key enumeration sysfs files */ ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group); if (ret) diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index e68a96f..e4540fc 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -830,7 +830,8 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) i2c->irq = res; - dev_dbg(&pdev->dev, "irq resource %p (%ld)\n", res, res->start); + dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res, + (unsigned long)res->start); ret = i2c_add_adapter(&i2c->adap); if (ret < 0) { diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index 9079990..cb9abe7 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -208,7 +208,7 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface, dev->adapter.class = I2C_CLASS_HWMON; dev->adapter.algo = &usb_algorithm; dev->adapter.algo_data = dev; - snprintf(dev->adapter.name, I2C_NAME_SIZE, + snprintf(dev->adapter.name, sizeof(dev->adapter.name), "i2c-tiny-usb at bus %03d device %03d", dev->usb_dev->bus->busnum, dev->usb_dev->devnum); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 64f8e56..435925e 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -697,9 +697,10 @@ int i2c_attach_client(struct i2c_client *client) if (client->driver) client->dev.driver = &client->driver->driver; - if (client->driver && !is_newstyle_driver(client->driver)) + if (client->driver && !is_newstyle_driver(client->driver)) { client->dev.release = i2c_client_release; - else + client->dev.uevent_suppress = 1; + } else client->dev.release = i2c_client_dev_release; snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id), diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index b77b7d1..ead141e 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -119,15 +119,17 @@ static const struct drive_list_entry drive_blacklist [] = { { "HITACHI CDR-8335" , "ALL" }, { "HITACHI CDR-8435" , "ALL" }, { "Toshiba CD-ROM XM-6202B" , "ALL" }, + { "TOSHIBA CD-ROM XM-1702BC", "ALL" }, { "CD-532E-A" , "ALL" }, { "E-IDE CD-ROM CR-840", "ALL" }, { "CD-ROM Drive/F5A", "ALL" }, { "WPI CDD-820", "ALL" }, { "SAMSUNG CD-ROM SC-148C", "ALL" }, { "SAMSUNG CD-ROM SC", "ALL" }, - { "SanDisk SDP3B-64" , "ALL" }, { "ATAPI CD-ROM DRIVE 40X MAXIMUM", "ALL" }, { "_NEC DV5800A", "ALL" }, + { "SAMSUNG CD-ROM SN-124", "N001" }, + { "Seagate STT20000A", "ALL" }, { NULL , NULL } }; diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index d50bd99..ea94c9a 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -67,6 +67,8 @@ static int proc_ide_read_imodel case ide_4drives: name = "4drives"; break; case ide_pmac: name = "mac-io"; break; case ide_au1xxx: name = "au1xxx"; break; + case ide_etrax100: name = "etrax100"; break; + case ide_acorn: name = "acorn"; break; default: name = "(unknown)"; break; } len = sprintf(page, "%s\n", name); diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 0e52ad7..8ab33fa 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -317,6 +317,7 @@ static struct pci_device_id atiixp_pci_tbl[] = { { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, { 0, }, }; MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 6234f80..47bcd91 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -158,6 +158,12 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) pci_read_config_word(dev, 0x4A, &csb5_pio); pci_read_config_byte(dev, 0x54, &ultra_enable); + /* If we are in RAID mode (eg AMI MegaIDE) then we can't it + turns out trust the firmware configuration */ + + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) + goto oem_setup_failed; + /* Per Specified Design by OEM, and ASIC Architect */ if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) { @@ -173,7 +179,7 @@ dma_pio: ((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) { u8 dmaspeed = dma_timing; - dma_timing &= ~0xFF; + dma_timing &= ~0xFFU; if ((dmaspeed & 0x20) == 0x20) dmaspeed = XFER_MW_DMA_2; else if ((dmaspeed & 0x21) == 0x21) @@ -187,7 +193,7 @@ dma_pio: } else if (pio_timing) { u8 piospeed = pio_timing; - pio_timing &= ~0xFF; + pio_timing &= ~0xFFU; if ((piospeed & 0x20) == 0x20) piospeed = XFER_PIO_4; else if ((piospeed & 0x22) == 0x22) @@ -208,8 +214,8 @@ dma_pio: oem_setup_failed: - pio_timing &= ~0xFF; - dma_timing &= ~0xFF; + pio_timing &= ~0xFFU; + dma_timing &= ~0xFFU; ultra_timing &= ~(0x0F << (4*unit)); ultra_enable &= ~(0x01 << drive->dn); csb5_pio &= ~(0x0F << (4*drive->dn)); diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index 7f0beec..5766ae3 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c @@ -331,7 +331,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, 0); qp->ipz_qp_handle.handle = outs[0]; qp->real_qp_num = (u32)outs[1]; - parms->act_nr_send_sges = + parms->act_nr_send_wqes = (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]); parms->act_nr_recv_wqes = (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]); diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a824bc5..dc137de 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -270,9 +270,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, struct ib_qp_init_attr *init_attr, struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp) { - struct mlx4_wqe_ctrl_seg *ctrl; int err; - int i; mutex_init(&qp->mutex); spin_lock_init(&qp->sq.lock); @@ -319,20 +317,24 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, if (err) goto err_mtt; - err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context), - ucmd.db_addr, &qp->db); - if (err) - goto err_mtt; + if (!init_attr->srq) { + err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context), + ucmd.db_addr, &qp->db); + if (err) + goto err_mtt; + } } else { err = set_kernel_sq_size(dev, &init_attr->cap, init_attr->qp_type, qp); if (err) goto err; - err = mlx4_ib_db_alloc(dev, &qp->db, 0); - if (err) - goto err; + if (!init_attr->srq) { + err = mlx4_ib_db_alloc(dev, &qp->db, 0); + if (err) + goto err; - *qp->db.db = 0; + *qp->db.db = 0; + } if (mlx4_buf_alloc(dev->dev, qp->buf_size, PAGE_SIZE * 2, &qp->buf)) { err = -ENOMEM; @@ -348,11 +350,6 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, if (err) goto err_mtt; - for (i = 0; i < qp->sq.max; ++i) { - ctrl = get_send_wqe(qp, i); - ctrl->owner_opcode = cpu_to_be32(1 << 31); - } - qp->sq.wrid = kmalloc(qp->sq.max * sizeof (u64), GFP_KERNEL); qp->rq.wrid = kmalloc(qp->rq.max * sizeof (u64), GFP_KERNEL); @@ -386,7 +383,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, return 0; err_wrid: - if (pd->uobject) + if (pd->uobject && !init_attr->srq) mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db); else { kfree(qp->sq.wrid); @@ -403,7 +400,7 @@ err_buf: mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf); err_db: - if (!pd->uobject) + if (!pd->uobject && !init_attr->srq) mlx4_ib_db_free(dev, &qp->db); err: @@ -481,14 +478,16 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, mlx4_mtt_cleanup(dev->dev, &qp->mtt); if (is_user) { - mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context), - &qp->db); + if (!qp->ibqp.srq) + mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context), + &qp->db); ib_umem_release(qp->umem); } else { kfree(qp->sq.wrid); kfree(qp->rq.wrid); mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf); - mlx4_ib_db_free(dev, &qp->db); + if (!qp->ibqp.srq) + mlx4_ib_db_free(dev, &qp->db); } } @@ -852,7 +851,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, if (ibqp->srq) context->srqn = cpu_to_be32(1 << 24 | to_msrq(ibqp->srq)->msrq.srqn); - if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) + if (!ibqp->srq && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) context->db_rec_addr = cpu_to_be64(qp->db.dma); if (cur_state == IB_QPS_INIT && @@ -872,6 +871,21 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, else sqd_event = 0; + /* + * Before passing a kernel QP to the HW, make sure that the + * ownership bits of the send queue are set so that the + * hardware doesn't start processing stale work requests. + */ + if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) { + struct mlx4_wqe_ctrl_seg *ctrl; + int i; + + for (i = 0; i < qp->sq.max; ++i) { + ctrl = get_send_wqe(qp, i); + ctrl->owner_opcode = cpu_to_be32(1 << 31); + } + } + err = mlx4_qp_modify(dev->dev, &qp->mtt, to_mlx4_state(cur_state), to_mlx4_state(new_state), context, optpar, sqd_event, &qp->mqp); @@ -919,7 +933,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, qp->rq.tail = 0; qp->sq.head = 0; qp->sq.tail = 0; - *qp->db.db = 0; + if (!ibqp->srq) + *qp->db.db = 0; } out: diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index a0b3782..158759e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -429,6 +429,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey); void ipoib_pkey_poll(struct work_struct *work); int ipoib_pkey_dev_delay_open(struct net_device *dev); +void ipoib_drain_cq(struct net_device *dev); #ifdef CONFIG_INFINIBAND_IPOIB_CM diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index ffec794..f133b56 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -713,7 +713,7 @@ void ipoib_cm_dev_stop(struct net_device *dev) while (!list_empty(&priv->cm.rx_error_list) || !list_empty(&priv->cm.rx_flush_list) || !list_empty(&priv->cm.rx_drain_list)) { - if (!time_after(jiffies, begin + 5 * HZ)) { + if (time_after(jiffies, begin + 5 * HZ)) { ipoib_warn(priv, "RX drain timing out\n"); /* @@ -726,6 +726,7 @@ void ipoib_cm_dev_stop(struct net_device *dev) } spin_unlock_irq(&priv->lock); msleep(1); + ipoib_drain_cq(dev); spin_lock_irq(&priv->lock); } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index c1aad06..8404f05 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -550,13 +550,30 @@ static int recvs_pending(struct net_device *dev) return pending; } +void ipoib_drain_cq(struct net_device *dev) +{ + struct ipoib_dev_priv *priv = netdev_priv(dev); + int i, n; + do { + n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc); + for (i = 0; i < n; ++i) { + if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ) + ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); + else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) + ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); + else + ipoib_ib_handle_tx_wc(dev, priv->ibwc + i); + } + } while (n == IPOIB_NUM_WC); +} + int ipoib_ib_dev_stop(struct net_device *dev, int flush) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ib_qp_attr qp_attr; unsigned long begin; struct ipoib_tx_buf *tx_req; - int i, n; + int i; clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); netif_poll_disable(dev); @@ -611,17 +628,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush) goto timeout; } - do { - n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc); - for (i = 0; i < n; ++i) { - if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ) - ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); - else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) - ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); - else - ipoib_ib_handle_tx_wc(dev, priv->ibwc + i); - } - } while (n == IPOIB_NUM_WC); + ipoib_drain_cq(dev); msleep(1); } diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index fb129c4..682244b 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -370,10 +370,8 @@ int iforce_init_device(struct iforce *iforce) /* * Disable spring, enable force feedback. - * FIXME: We should use iforce_set_autocenter() et al here. */ - - iforce_send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000"); + iforce_set_autocenter(input_dev, 0); /* * Find appropriate device entry diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 21c4e13..3154ccd 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -246,6 +246,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) int iforce_get_id_packet(struct iforce *iforce, char *packet) { + int status; + switch (iforce->bus) { case IFORCE_USB: @@ -254,18 +256,22 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) iforce->cr.bRequest = packet[0]; iforce->ctrl->dev = iforce->usbdev; - if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC)) + status = usb_submit_urb(iforce->ctrl, GFP_ATOMIC); + if (status) { + err("usb_submit_urb failed %d", status); return -1; + } wait_event_interruptible_timeout(iforce->wait, iforce->ctrl->status != -EINPROGRESS, HZ); if (iforce->ctrl->status) { + dbg("iforce->ctrl->status = %d", iforce->ctrl->status); usb_unlink_urb(iforce->ctrl); return -1; } #else - err("iforce_get_id_packet: iforce->bus = USB!"); + dbg("iforce_get_id_packet: iforce->bus = USB!"); #endif break; diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 750099d..1457b73 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -65,6 +65,7 @@ void iforce_usb_xmit(struct iforce *iforce) XMIT_INC(iforce->xmit.tail, n); if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) { + clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); warn("usb_submit_urb failed %d\n", n); } @@ -163,8 +164,8 @@ static int iforce_usb_probe(struct usb_interface *intf, usb_fill_int_urb(iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress), iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval); - usb_fill_bulk_urb(iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress), - iforce + 1, 32, iforce_usb_out, iforce); + usb_fill_int_urb(iforce->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress), + iforce + 1, 32, iforce_usb_out, iforce, epout->bInterval); usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0), (void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce); diff --git a/drivers/input/misc/input-polldev.c b/drivers/input/misc/input-polldev.c index 1b2b9c9..b773d4c 100644 --- a/drivers/input/misc/input-polldev.c +++ b/drivers/input/misc/input-polldev.c @@ -12,6 +12,11 @@ #include <linux/mutex.h> #include <linux/input-polldev.h> +MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); +MODULE_DESCRIPTION("Generic implementation of a polled input device"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0.1"); + static DEFINE_MUTEX(polldev_mutex); static int polldev_users; static struct workqueue_struct *polldev_wq; diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index cf3e466..2c5f11a 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -251,11 +251,15 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); - for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++); - *version = (param[0] << 8) | (param[1] << 4) | i; + if (version) { + for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++) + /* empty */; + *version = (param[0] << 8) | (param[1] << 4) | i; + } for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) - if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature))) + if (!memcmp(param, alps_model_data[i].signature, + sizeof(alps_model_data[i].signature))) return alps_model_data + i; return NULL; @@ -380,32 +384,46 @@ static int alps_poll(struct psmouse *psmouse) return 0; } -static int alps_reconnect(struct psmouse *psmouse) +static int alps_hw_init(struct psmouse *psmouse, int *version) { struct alps_data *priv = psmouse->private; - int version; - - psmouse_reset(psmouse); - if (!(priv->i = alps_get_model(psmouse, &version))) + priv->i = alps_get_model(psmouse, version); + if (!priv->i) return -1; if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) return -1; if (alps_tap_mode(psmouse, 1)) { - printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n"); + printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); return -1; } if (alps_absolute_mode(psmouse)) { - printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n"); + printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); return -1; } if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) return -1; + /* ALPS needs stream mode, otherwise it won't report any data */ + if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { + printk(KERN_ERR "alps.c: Failed to enable stream mode\n"); + return -1; + } + + return 0; +} + +static int alps_reconnect(struct psmouse *psmouse) +{ + psmouse_reset(psmouse); + + if (alps_hw_init(psmouse, NULL)) + return -1; + return 0; } @@ -430,23 +448,9 @@ int alps_init(struct psmouse *psmouse) goto init_fail; priv->dev2 = dev2; + psmouse->private = priv; - priv->i = alps_get_model(psmouse, &version); - if (!priv->i) - goto init_fail; - - if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) - goto init_fail; - - if (alps_tap_mode(psmouse, 1)) - printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); - - if (alps_absolute_mode(psmouse)) { - printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); - goto init_fail; - } - - if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) + if (alps_hw_init(psmouse, &version)) goto init_fail; dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY); @@ -493,13 +497,13 @@ int alps_init(struct psmouse *psmouse) /* We are having trouble resyncing ALPS touchpads so disable it for now */ psmouse->resync_time = 0; - psmouse->private = priv; return 0; init_fail: psmouse_reset(psmouse); input_free_device(dev2); kfree(priv); + psmouse->private = NULL; return -1; } diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 9df74b7..0c5660d 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -221,6 +221,7 @@ static const struct ps2pp_info *get_model_info(unsigned char model) { 66, PS2PP_KIND_MX, /* MX3100 reciver */ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL }, + { 72, PS2PP_KIND_TRACKMAN, 0 }, /* T-CH11: TrackMan Marble */ { 73, 0, PS2PP_SIDE_BTN }, { 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, { 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 4f09180..e5cca9b 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -12,17 +12,17 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN config TOUCHSCREEN_ADS7846 - tristate "ADS 7846/7843 based touchscreens" + tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" depends on SPI_MASTER depends on HWMON = n || HWMON help Say Y here if you have a touchscreen interface using the - ADS7846 or ADS7843 controller, and your board-specific setup - code includes that in its table of SPI devices. + ADS7846/TSC2046 or ADS7843 controller, and your board-specific + setup code includes that in its table of SPI devices. If HWMON is selected, and the driver is told the reference voltage on your board, you will also get hwmon interfaces for the voltage - (and on ads7846, temperature) sensors of this chip. + (and on ads7846/tsc2046, temperature) sensors of this chip. If unsure, say N (but it's safe to say "Y"). diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 693e3b2..1c9069c 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -39,6 +39,7 @@ /* * This code has been heavily tested on a Nokia 770, and lightly * tested on other ads7846 devices (OSK/Mistral, Lubbock). + * TSC2046 is just newer ads7846 silicon. * Support for ads7843 tested on Atmel at91sam926x-EK. * Support for ads7845 has only been stubbed in. * @@ -847,7 +848,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) * may not. So we stick to very-portable 8 bit words, both RX and TX. */ spi->bits_per_word = 8; - spi->mode = SPI_MODE_1; + spi->mode = SPI_MODE_0; err = spi_setup(spi); if (err < 0) return err; diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index 61c1502..1a15475 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c @@ -1,7 +1,6 @@ #include <linux/input.h> #include <linux/module.h> #include <linux/init.h> - #include <linux/interrupt.h> #include <asm/io.h> #include <asm/delay.h> @@ -18,12 +17,12 @@ #define PHDR 0xa400012e #define SCPDR 0xa4000136 -static void do_softint(void *data); +static void do_softint(struct work_struct *work); static struct input_dev *hp680_ts_dev; -static DECLARE_WORK(work, do_softint); +static DECLARE_DELAYED_WORK(work, do_softint); -static void do_softint(void *data) +static void do_softint(struct work_struct *work) { int absx = 0, absy = 0; u8 scpdr; diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 6582816..f0cbcdb 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -288,9 +288,9 @@ static int ucb1400_ts_thread(void *_ucb) struct ucb1400 *ucb = _ucb; struct task_struct *tsk = current; int valid = 0; + struct sched_param param = { .sched_priority = 1 }; - tsk->policy = SCHED_FIFO; - tsk->rt_priority = 1; + sched_setscheduler(tsk, SCHED_FIFO, ¶m); while (!kthread_should_stop()) { unsigned int x, y, p; diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c index ff284ae..82edc1c 100644 --- a/drivers/isdn/hardware/eicon/capifunc.c +++ b/drivers/isdn/hardware/eicon/capifunc.c @@ -189,21 +189,21 @@ void *TransmitBufferSet(APPL * appl, dword ref) { appl->xbuffer_used[ref] = true; DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1)) - return (void *) ref; + return (void *)(long)ref; } void *TransmitBufferGet(APPL * appl, void *p) { - if (appl->xbuffer_internal[(dword) p]) - return appl->xbuffer_internal[(dword) p]; + if (appl->xbuffer_internal[(dword)(long)p]) + return appl->xbuffer_internal[(dword)(long)p]; - return appl->xbuffer_ptr[(dword) p]; + return appl->xbuffer_ptr[(dword)(long)p]; } void TransmitBufferFree(APPL * appl, void *p) { - appl->xbuffer_used[(dword) p] = false; - DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword) p) + 1)) + appl->xbuffer_used[(dword)(long)p] = false; + DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword)(long)p) + 1)) } void *ReceiveBufferGet(APPL * appl, int Num) @@ -301,7 +301,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...) /* if DATA_B3_IND, copy data too */ if (command == _DATA_B3_I) { dword data = GET_DWORD(&msg.info.data_b3_ind.Data); - memcpy(write + length, (void *) data, dlength); + memcpy(write + length, (void *)(long)data, dlength); } #ifndef DIVA_NO_DEBUGLIB @@ -318,7 +318,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...) if (myDriverDebugHandle.dbgMask & DL_BLK) { xlog("\x00\x02", &msg, 0x81, length); for (i = 0; i < dlength; i += 256) { - DBG_BLK((((char *) GET_DWORD(&msg.info.data_b3_ind.Data)) + i, + DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i, ((dlength - i) < 256) ? (dlength - i) : 256)) if (!(myDriverDebugHandle.dbgMask & DL_PRV0)) break; /* not more if not explicitely requested */ diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index 784232a..ccd35d0 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c @@ -1,4 +1,3 @@ - /* * Copyright (c) Eicon Networks, 2002. @@ -533,7 +532,7 @@ word api_put(APPL * appl, CAPI_MSG * msg) if (m->header.command == _DATA_B3_R) { - m->info.data_b3_req.Data = (dword)(TransmitBufferSet (appl, m->info.data_b3_req.Data)); + m->info.data_b3_req.Data = (dword)(long)(TransmitBufferSet (appl, m->info.data_b3_req.Data)); } @@ -1032,7 +1031,7 @@ static void plci_free_msg_in_queue (PLCI *plci) { TransmitBufferFree (plci->appl, - (byte *)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data)); + (byte *)(long)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data)); } @@ -3118,7 +3117,7 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) { - data->P = (byte *)(*((dword *)(parms[0].info))); + data->P = (byte *)(long)(*((dword *)(parms[0].info))); } else @@ -3151,7 +3150,7 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) { - TransmitBufferFree (appl, (byte *)(*((dword *)(parms[0].info)))); + TransmitBufferFree (appl, (byte *)(long)(*((dword *)(parms[0].info)))); } } @@ -4057,7 +4056,7 @@ capi_callback_suffix: { if (m->header.command == _DATA_B3_R) - TransmitBufferFree (appl, (byte *)(m->info.data_b3_req.Data)); + TransmitBufferFree (appl, (byte *)(long)(m->info.data_b3_req.Data)); dbug(1,dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command)); break; @@ -7134,7 +7133,7 @@ void nl_ind(PLCI * plci) case N_UDATA: if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f)))) { - plci->RData[0].P = plci->internal_ind_buffer + (-((int)(plci->internal_ind_buffer)) & 3); + plci->RData[0].P = plci->internal_ind_buffer + (-((int)(long)(plci->internal_ind_buffer)) & 3); plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE; plci->NL.R = plci->RData; plci->NL.RNum = 1; diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index da4196f..8d53a7f 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -1551,7 +1551,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], if (retval == 0) { // yuck cards[i].typ = 0; nrcards--; - return retval; + return -EINVAL; } cs = cards[i].cs; hisax_d_if->cs = cs; diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index 1f18f19..b1a26e0 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -485,7 +485,6 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, { int k; - spin_lock_init(&urb->lock); urb->dev = dev; urb->pipe = pipe; urb->complete = complete; @@ -578,16 +577,14 @@ stop_isoc_chain(usb_fifo * fifo) "HFC-S USB: Stopping iso chain for fifo %i.%i", fifo->fifonum, i); #endif - usb_unlink_urb(fifo->iso[i].purb); + usb_kill_urb(fifo->iso[i].purb); usb_free_urb(fifo->iso[i].purb); fifo->iso[i].purb = NULL; } } - if (fifo->urb) { - usb_unlink_urb(fifo->urb); - usb_free_urb(fifo->urb); - fifo->urb = NULL; - } + usb_kill_urb(fifo->urb); + usb_free_urb(fifo->urb); + fifo->urb = NULL; fifo->active = 0; } @@ -1305,7 +1302,11 @@ usb_init(hfcusb_data * hfc) } /* default Prot: EURO ISDN, should be a module_param */ hfc->protocol = 2; - hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol); + i = hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol); + if (i) { + printk(KERN_INFO "HFC-S USB: hisax_register -> %d\n", i); + return i; + } #ifdef CONFIG_HISAX_DEBUG hfc_debug = debug; @@ -1626,11 +1627,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) #endif /* init the chip and register the driver */ if (usb_init(context)) { - if (context->ctrl_urb) { - usb_unlink_urb(context->ctrl_urb); - usb_free_urb(context->ctrl_urb); - context->ctrl_urb = NULL; - } + usb_kill_urb(context->ctrl_urb); + usb_free_urb(context->ctrl_urb); + context->ctrl_urb = NULL; kfree(context); return (-EIO); } @@ -1682,21 +1681,15 @@ hfc_usb_disconnect(struct usb_interface i); #endif } - if (context->fifos[i].urb) { - usb_unlink_urb(context->fifos[i].urb); - usb_free_urb(context->fifos[i].urb); - context->fifos[i].urb = NULL; - } + usb_kill_urb(context->fifos[i].urb); + usb_free_urb(context->fifos[i].urb); + context->fifos[i].urb = NULL; } context->fifos[i].active = 0; } - /* wait for all URBS to terminate */ - mdelay(10); - if (context->ctrl_urb) { - usb_unlink_urb(context->ctrl_urb); - usb_free_urb(context->ctrl_urb); - context->ctrl_urb = NULL; - } + usb_kill_urb(context->ctrl_urb); + usb_free_urb(context->ctrl_urb); + context->ctrl_urb = NULL; hisax_unregister(&context->d_if); kfree(context); /* free our structure again */ } /* hfc_usb_disconnect */ diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index 9e088fc..7993e01 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -859,7 +859,11 @@ new_adapter(void) for (i = 0; i < 2; i++) b_if[i] = &adapter->bcs[i].b_if; - hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol); + if (hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", + protocol) != 0) { + kfree(adapter); + adapter = NULL; + } return adapter; } diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c index bb3a28a..1375123 100644 --- a/drivers/isdn/hisax/st5481_init.c +++ b/drivers/isdn/hisax/st5481_init.c @@ -107,12 +107,17 @@ static int probe_st5481(struct usb_interface *intf, for (i = 0; i < 2; i++) b_if[i] = &adapter->bcs[i].b_if; - hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", protocol); + if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", + protocol) != 0) + goto err_b1; + st5481_start(adapter); usb_set_intfdata(intf, adapter); return 0; + err_b1: + st5481_release_b(&adapter->bcs[1]); err_b: st5481_release_b(&adapter->bcs[0]); err_d: diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index ff15951..4ada66b 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c @@ -407,7 +407,6 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, { int k; - spin_lock_init(&urb->lock); urb->dev=dev; urb->pipe=pipe; urb->interval = 1; diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index b77ef51..b46817f 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -628,16 +628,16 @@ static void real_leds(unsigned char leds, int device) */ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct adbhid *adbhid = dev->private; + struct adbhid *adbhid = input_get_drvdata(dev); unsigned char leds; switch (type) { case EV_LED: - leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0) - | (test_bit(LED_NUML, dev->led) ? 1 : 0) - | (test_bit(LED_CAPSL, dev->led) ? 2 : 0); - real_leds(leds, adbhid->id); - return 0; + leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0) | + (test_bit(LED_NUML, dev->led) ? 1 : 0) | + (test_bit(LED_CAPSL, dev->led) ? 2 : 0); + real_leds(leds, adbhid->id); + return 0; } return -1; @@ -649,7 +649,7 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x) switch (code) { case ADB_MSG_PRE_RESET: case ADB_MSG_POWERDOWN: - /* Stop the repeat timer. Autopoll is already off at this point */ + /* Stop the repeat timer. Autopoll is already off at this point */ { int i; for (i = 1; i < 16; i++) { @@ -699,7 +699,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id, hid->current_handler_id = current_handler_id; hid->mouse_kind = mouse_kind; hid->flags = 0; - input_dev->private = hid; + input_set_drvdata(input_dev, hid); input_dev->name = hid->name; input_dev->phys = hid->phys; input_dev->id.bustype = BUS_ADB; diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 5a4a74c..9620d45 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -255,19 +255,25 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde } -static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait) +static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) { mdk_rdev_t *rdev; struct list_head *tmp; + mddev_t *mddev = bitmap->mddev; ITERATE_RDEV(mddev, rdev, tmp) if (test_bit(In_sync, &rdev->flags) - && !test_bit(Faulty, &rdev->flags)) + && !test_bit(Faulty, &rdev->flags)) { + int size = PAGE_SIZE; + if (page->index == bitmap->file_pages-1) + size = roundup(bitmap->last_page_size, + bdev_hardsect_size(rdev->bdev)); md_super_write(mddev, rdev, - (rdev->sb_offset<<1) + offset + (rdev->sb_offset<<1) + bitmap->offset + page->index * (PAGE_SIZE/512), - PAGE_SIZE, + size, page); + } if (wait) md_super_wait(mddev); @@ -282,7 +288,7 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait) struct buffer_head *bh; if (bitmap->file == NULL) - return write_sb_page(bitmap->mddev, bitmap->offset, page, wait); + return write_sb_page(bitmap, page, wait); bh = page_buffers(page); @@ -923,6 +929,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) } bitmap->filemap[bitmap->file_pages++] = page; + bitmap->last_page_size = count; } paddr = kmap_atomic(page, KM_USER0); if (bitmap->flags & BITMAP_HOSTENDIAN) diff --git a/drivers/md/linear.c b/drivers/md/linear.c index d5ecd2d..1927410 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -139,8 +139,6 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) if (!conf) return NULL; - mddev->private = conf; - cnt = 0; conf->array_size = 0; @@ -232,7 +230,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) * First calculate the device offsets. */ conf->disks[0].offset = 0; - for (i=1; i<mddev->raid_disks; i++) + for (i = 1; i < raid_disks; i++) conf->disks[i].offset = conf->disks[i-1].offset + conf->disks[i-1].size; @@ -244,7 +242,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) curr_offset < conf->array_size; curr_offset += conf->hash_spacing) { - while (i < mddev->raid_disks-1 && + while (i < raid_disks-1 && curr_offset >= conf->disks[i+1].offset) i++; @@ -299,9 +297,11 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev) */ linear_conf_t *newconf; - if (rdev->raid_disk != mddev->raid_disks) + if (rdev->saved_raid_disk != mddev->raid_disks) return -EINVAL; + rdev->raid_disk = rdev->saved_raid_disk; + newconf = linear_conf(mddev,mddev->raid_disks+1); if (!newconf) diff --git a/drivers/md/md.c b/drivers/md/md.c index c10ce91..1c54f3c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1298,8 +1298,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) ITERATE_RDEV(mddev,rdev2,tmp) if (rdev2->desc_nr+1 > max_dev) max_dev = rdev2->desc_nr+1; - - sb->max_dev = cpu_to_le32(max_dev); + + if (max_dev > le32_to_cpu(sb->max_dev)) + sb->max_dev = cpu_to_le32(max_dev); for (i=0; i<max_dev;i++) sb->dev_roles[i] = cpu_to_le16(0xfffe); @@ -1365,10 +1366,14 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) } /* make sure rdev->size exceeds mddev->size */ if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) { - if (mddev->pers) - /* Cannot change size, so fail */ - return -ENOSPC; - else + if (mddev->pers) { + /* Cannot change size, so fail + * If mddev->level <= 0, then we don't care + * about aligning sizes (e.g. linear) + */ + if (mddev->level > 0) + return -ENOSPC; + } else mddev->size = rdev->size; } @@ -2142,6 +2147,9 @@ static void analyze_sbs(mddev_t * mddev) rdev->desc_nr = i++; rdev->raid_disk = rdev->desc_nr; set_bit(In_sync, &rdev->flags); + } else if (rdev->raid_disk >= mddev->raid_disks) { + rdev->raid_disk = -1; + clear_bit(In_sync, &rdev->flags); } } diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index dfe3214..2c404f7 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -415,7 +415,7 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio) raid0_conf_t *conf = mddev_to_conf(mddev); struct strip_zone *zone; mdk_rdev_t *tmp_dev; - unsigned long chunk; + sector_t chunk; sector_t block, rsect; const int rw = bio_data_dir(bio); @@ -470,7 +470,6 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio) sector_div(x, zone->nb_dev); chunk = x; - BUG_ON(x != (sector_t)chunk); x = block >> chunksize_bits; tmp_dev = zone->dev[sector_div(x, zone->nb_dev)]; diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 0393a3d..e908e3c 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -1721,9 +1721,6 @@ static void dst_release(struct dvb_frontend *fe) symbol_put(dst_ca_attach); #endif } -#ifdef CONFIG_DVB_CORE_ATTACH - symbol_put(dst_attach); -#endif kfree(state); } diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index e23d8a0..a9fa333 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -200,7 +200,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, { struct dvb_device *dvbdev; struct file_operations *dvbdevfops; - + struct class_device *clsdev; int id; mutex_lock(&dvbdev_register_lock); @@ -242,8 +242,15 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, mutex_unlock(&dvbdev_register_lock); - class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), - adap->device, "dvb%d.%s%d", adap->num, dnames[type], id); + clsdev = class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, + nums2minor(adap->num, type, id)), + adap->device, "dvb%d.%s%d", adap->num, + dnames[type], id); + if (IS_ERR(clsdev)) { + printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n", + __FUNCTION__, adap->num, dnames[type], id, PTR_ERR(clsdev)); + return PTR_ERR(clsdev); + } dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", adap->num, dnames[type], id, nums2minor(adap->num, type, id), @@ -431,7 +438,7 @@ static void __exit exit_dvbdev(void) unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); } -module_init(init_dvbdev); +subsys_initcall(init_dvbdev); module_exit(exit_dvbdev); MODULE_DESCRIPTION("DVB Core Driver"); diff --git a/drivers/media/video/cafe_ccic-regs.h b/drivers/media/video/cafe_ccic-regs.h index b2c22a0..8e2a87c 100644 --- a/drivers/media/video/cafe_ccic-regs.h +++ b/drivers/media/video/cafe_ccic-regs.h @@ -150,6 +150,12 @@ #define REG_GL_IMASK 0x300c /* Interrupt mask register */ #define GIMSK_CCIC_EN 0x00000004 /* CCIC Interrupt enable */ +#define REG_GL_FCR 0x3038 /* GPIO functional control register */ +#define GFCR_GPIO_ON 0x08 /* Camera GPIO enabled */ +#define REG_GL_GPIOR 0x315c /* GPIO register */ +#define GGPIO_OUT 0x80000 /* GPIO output */ +#define GGPIO_VAL 0x00008 /* Output pin value */ + #define REG_LEN REG_GL_IMASK + 4 diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 96254db..c08f650 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -775,6 +775,12 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam) spin_lock_irqsave(&cam->dev_lock, flags); cafe_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN); /* + * Part one of the sensor dance: turn the global + * GPIO signal on. + */ + cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON); + cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT|GGPIO_VAL); + /* * Put the sensor into operational mode (assumes OLPC-style * wiring). Control 0 is reset - set to 1 to operate. * Control 1 is power down, set to 0 to operate. @@ -784,6 +790,7 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam) cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0); // mdelay(1); /* Enough? */ spin_unlock_irqrestore(&cam->dev_lock, flags); + msleep(5); /* Just to be sure */ } static void cafe_ctlr_power_down(struct cafe_camera *cam) @@ -792,6 +799,8 @@ static void cafe_ctlr_power_down(struct cafe_camera *cam) spin_lock_irqsave(&cam->dev_lock, flags); cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1); + cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON); + cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT); cafe_reg_set_bit(cam, REG_CTRL1, C1_PWRDWN); spin_unlock_irqrestore(&cam->dev_lock, flags); } @@ -851,6 +860,7 @@ static int cafe_cam_init(struct cafe_camera *cam) ret = 0; cam->state = S_IDLE; out: + cafe_ctlr_power_down(cam); mutex_unlock(&cam->s_mutex); return ret; } @@ -2103,10 +2113,16 @@ static int cafe_pci_probe(struct pci_dev *pdev, ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam); if (ret) goto out_iounmap; + /* + * Initialize the controller and leave it powered up. It will + * stay that way until the sensor driver shows up. + */ cafe_ctlr_init(cam); cafe_ctlr_power_up(cam); /* - * Set up I2C/SMBUS communications + * Set up I2C/SMBUS communications. We have to drop the mutex here + * because the sensor could attach in this call chain, leading to + * unsightly deadlocks. */ mutex_unlock(&cam->s_mutex); /* attach can deadlock */ ret = cafe_smbus_setup(cam); diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig index 2c450bd..5b6a403 100644 --- a/drivers/media/video/em28xx/Kconfig +++ b/drivers/media/video/em28xx/Kconfig @@ -1,7 +1,6 @@ config VIDEO_EM28XX tristate "Empia EM2800/2820/2840 USB video capture support" - depends on VIDEO_V4L1 && I2C && PCI - select VIDEO_BUF + depends on VIDEO_V4L1 && I2C select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_IR diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index 0cc98a0..1aaeaa0 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig @@ -1,6 +1,6 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" - depends on VIDEO_V4L1 && VIDEO_V4L2 && USB && I2C && EXPERIMENTAL && PCI + depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 9a412d6..552f045 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -67,14 +67,6 @@ #include <media/ivtv.h> -#ifdef CONFIG_LIRC_I2C -# error "This driver is not compatible with the LIRC I2C kernel configuration option." -#endif /* CONFIG_LIRC_I2C */ - -#ifndef CONFIG_PCI -# error "This driver requires kernel PCI support." -#endif /* CONFIG_PCI */ - #define IVTV_ENCODER_OFFSET 0x00000000 #define IVTV_ENCODER_SIZE 0x00800000 /* Last half isn't needed 0x01000000 */ diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 794a6a0..1989ec1 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -362,8 +362,6 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; - fmt->fmt.pix.left = itv->main_rect.left; - fmt->fmt.pix.top = itv->main_rect.top; fmt->fmt.pix.width = itv->main_rect.width; fmt->fmt.pix.height = itv->main_rect.height; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -402,8 +400,6 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: - fmt->fmt.pix.left = 0; - fmt->fmt.pix.top = 0; fmt->fmt.pix.width = itv->params.width; fmt->fmt.pix.height = itv->params.height; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -498,15 +494,13 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; field = fmt->fmt.pix.field; - r.top = fmt->fmt.pix.top; - r.left = fmt->fmt.pix.left; + r.top = 0; + r.left = 0; r.width = fmt->fmt.pix.width; r.height = fmt->fmt.pix.height; ivtv_get_fmt(itv, streamtype, fmt); if (itv->output_mode != OUT_UDMA_YUV) { /* TODO: would setting the rect also be valid for this mode? */ - fmt->fmt.pix.top = r.top; - fmt->fmt.pix.left = r.left; fmt->fmt.pix.width = r.width; fmt->fmt.pix.height = r.height; } @@ -1141,8 +1135,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void fb->fmt.pixelformat = itv->osd_pixelformat; fb->fmt.width = itv->osd_rect.width; fb->fmt.height = itv->osd_rect.height; - fb->fmt.left = itv->osd_rect.left; - fb->fmt.top = itv->osd_rect.top; fb->base = (void *)itv->osd_video_pbase; if (itv->osd_global_alpha_state) fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index 03bc369..3ceb8a6 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -720,12 +720,22 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt) struct ov7670_format_struct *ovfmt; struct ov7670_win_size *wsize; struct ov7670_info *info = i2c_get_clientdata(c); - unsigned char com7; + unsigned char com7, clkrc; ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize); if (ret) return ret; /* + * HACK: if we're running rgb565 we need to grab then rewrite + * CLKRC. If we're *not*, however, then rewriting clkrc hoses + * the colors. + */ + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) { + ret = ov7670_read(c, REG_CLKRC, &clkrc); + if (ret) + return ret; + } + /* * COM7 is a pain in the ass, it doesn't like to be read then * quickly written afterward. But we have everything we need * to set it absolutely here, as long as the format-specific @@ -744,7 +754,10 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt) if (wsize->regs) ret = ov7670_write_array(c, wsize->regs); info->fmt = ovfmt; - return 0; + + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0) + ret = ov7670_write(c, REG_CLKRC, clkrc); + return ret; } /* @@ -1267,7 +1280,9 @@ static int ov7670_attach(struct i2c_adapter *adapter) ret = ov7670_detect(client); if (ret) goto out_free_info; - i2c_attach_client(client); + ret = i2c_attach_client(client); + if (ret) + goto out_free_info; return 0; out_free_info: diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 1b9b074..c40b92c 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -205,9 +205,13 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) /* 0x01 -> ??? no change ??? */ /* 0x02 -> PAL BDGHI / SECAM L */ /* 0x04 -> ??? PAL others / SECAM others ??? */ - cb &= ~0x02; - if (t->std & V4L2_STD_SECAM) - cb |= 0x02; + cb &= ~0x03; + if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM + cb |= PHILIPS_MF_SET_PAL_L; + else if (t->std & V4L2_STD_SECAM_LC) + cb |= PHILIPS_MF_SET_PAL_L2; + else /* V4L2_STD_B|V4L2_STD_GH */ + cb |= PHILIPS_MF_SET_BG; break; case TUNER_TEMIC_4046FM5: diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index d25d3be..165f81d 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -436,7 +436,7 @@ typedef struct _MPT_SAS_MGMT { typedef struct _mpt_ioctl_events { u32 event; /* Specified by define above */ u32 eventContext; /* Index or counter */ - int data[2]; /* First 8 bytes of Event Data */ + u32 data[2]; /* First 8 bytes of Event Data */ } MPT_IOCTL_EVENTS; /* diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index fa0f776..3bd94f1 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -2463,11 +2463,11 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; ioc->events[idx].eventContext = ioc->eventContext; - ioc->events[idx].data[0] = (pReq->LUN[1] << 24) || - (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) || - (sc->device->channel << 8) || sc->device->id; + ioc->events[idx].data[0] = (pReq->LUN[1] << 24) | + (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) | + (sc->device->channel << 8) | sc->device->id; - ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; + ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12]; ioc->eventContext++; if (hd->ioc->pcidev->vendor == diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c index d3235f2..e0d474b 100644 --- a/drivers/message/i2o/driver.c +++ b/drivers/message/i2o/driver.c @@ -123,8 +123,12 @@ int i2o_driver_register(struct i2o_driver *drv) } rc = driver_register(&drv->driver); - if (rc) - destroy_workqueue(drv->event_queue); + if (rc) { + if (drv->event) { + destroy_workqueue(drv->event_queue); + drv->event_queue = NULL; + } + } return rc; }; @@ -256,7 +260,7 @@ void i2o_driver_notify_controller_add_all(struct i2o_controller *c) int i; struct i2o_driver *drv; - for (i = 0; i < I2O_MAX_DRIVERS; i++) { + for (i = 0; i < i2o_max_drivers; i++) { drv = i2o_drivers[i]; if (drv) @@ -276,7 +280,7 @@ void i2o_driver_notify_controller_remove_all(struct i2o_controller *c) int i; struct i2o_driver *drv; - for (i = 0; i < I2O_MAX_DRIVERS; i++) { + for (i = 0; i < i2o_max_drivers; i++) { drv = i2o_drivers[i]; if (drv) @@ -295,7 +299,7 @@ void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev) int i; struct i2o_driver *drv; - for (i = 0; i < I2O_MAX_DRIVERS; i++) { + for (i = 0; i < i2o_max_drivers; i++) { drv = i2o_drivers[i]; if (drv) @@ -314,7 +318,7 @@ void i2o_driver_notify_device_remove_all(struct i2o_device *i2o_dev) int i; struct i2o_driver *drv; - for (i = 0; i < I2O_MAX_DRIVERS; i++) { + for (i = 0; i < i2o_max_drivers; i++) { drv = i2o_drivers[i]; if (drv) @@ -335,17 +339,15 @@ int __init i2o_driver_init(void) spin_lock_init(&i2o_drivers_lock); - if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) || - ((i2o_max_drivers ^ (i2o_max_drivers - 1)) != - (2 * i2o_max_drivers - 1))) { - osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and " - "a power of 2\n", i2o_max_drivers); + if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64)) { + osm_warn("max_drivers set to %d, but must be >=2 and <= 64\n", + i2o_max_drivers); i2o_max_drivers = I2O_MAX_DRIVERS; } osm_info("max drivers = %d\n", i2o_max_drivers); i2o_drivers = - kzalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL); + kcalloc(i2o_max_drivers, sizeof(*i2o_drivers), GFP_KERNEL); if (!i2o_drivers) return -ENOMEM; diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index cb8c264..7772bd1 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c @@ -207,16 +207,7 @@ static int ucb1x00_thread(void *_ts) struct ucb1x00_ts *ts = _ts; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - int valid; - - /* - * We could run as a real-time thread. However, thus far - * this doesn't seem to be necessary. - */ -// tsk->policy = SCHED_FIFO; -// tsk->rt_priority = 1; - - valid = 0; + int valid = 0; add_wait_queue(&ts->irq_wait, &wait); while (!kthread_should_stop()) { diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 35b139b..5108b7c 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -47,6 +47,7 @@ struct phantom_device { struct cdev cdev; struct mutex open_lock; + spinlock_t ioctl_lock; }; static unsigned char phantom_devices[PHANTOM_MAX_MINORS]; @@ -59,8 +60,11 @@ static int phantom_status(struct phantom_device *dev, unsigned long newstat) atomic_set(&dev->counter, 0); iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL); iowrite32(0x43, dev->caddr + PHN_IRQCTL); - } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING)) + ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */ + } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING)) { iowrite32(0, dev->caddr + PHN_IRQCTL); + ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */ + } dev->status = newstat; @@ -71,8 +75,8 @@ static int phantom_status(struct phantom_device *dev, unsigned long newstat) * File ops */ -static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd, - u_long arg) +static long phantom_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { struct phantom_device *dev = file->private_data; struct phm_regs rs; @@ -92,24 +96,32 @@ static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd, if (r.reg > 7) return -EINVAL; + spin_lock(&dev->ioctl_lock); if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) && - phantom_status(dev, dev->status | PHB_RUNNING)) + phantom_status(dev, dev->status | PHB_RUNNING)){ + spin_unlock(&dev->ioctl_lock); return -ENODEV; + } pr_debug("phantom: writing %x to %u\n", r.value, r.reg); iowrite32(r.value, dev->iaddr + r.reg); + ioread32(dev->iaddr); /* PCI posting */ if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ)) phantom_status(dev, dev->status & ~PHB_RUNNING); + spin_unlock(&dev->ioctl_lock); break; case PHN_SET_REGS: if (copy_from_user(&rs, argp, sizeof(rs))) return -EFAULT; pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask); + spin_lock(&dev->ioctl_lock); for (i = 0; i < min(rs.count, 8U); i++) if ((1 << i) & rs.mask) iowrite32(rs.values[i], dev->oaddr + i); + ioread32(dev->iaddr); /* PCI posting */ + spin_unlock(&dev->ioctl_lock); break; case PHN_GET_REG: if (copy_from_user(&r, argp, sizeof(r))) @@ -128,9 +140,11 @@ static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd, return -EFAULT; pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask); + spin_lock(&dev->ioctl_lock); for (i = 0; i < min(rs.count, 8U); i++) if ((1 << i) & rs.mask) rs.values[i] = ioread32(dev->iaddr + i); + spin_unlock(&dev->ioctl_lock); if (copy_to_user(argp, &rs, sizeof(rs))) return -EFAULT; @@ -199,7 +213,7 @@ static unsigned int phantom_poll(struct file *file, poll_table *wait) static struct file_operations phantom_file_ops = { .open = phantom_open, .release = phantom_release, - .ioctl = phantom_ioctl, + .unlocked_ioctl = phantom_ioctl, .poll = phantom_poll, }; @@ -212,6 +226,7 @@ static irqreturn_t phantom_isr(int irq, void *data) iowrite32(0, dev->iaddr); iowrite32(0xc0, dev->iaddr); + ioread32(dev->iaddr); /* PCI posting */ atomic_inc(&dev->counter); wake_up_interruptible(&dev->wait); @@ -282,11 +297,13 @@ static int __devinit phantom_probe(struct pci_dev *pdev, } mutex_init(&pht->open_lock); + spin_lock_init(&pht->ioctl_lock); init_waitqueue_head(&pht->wait); cdev_init(&pht->cdev, &phantom_file_ops); pht->cdev.owner = THIS_MODULE; iowrite32(0, pht->caddr + PHN_IRQCTL); + ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */ retval = request_irq(pdev->irq, phantom_isr, IRQF_SHARED | IRQF_DISABLED, "phantom", pht); if (retval) { @@ -337,6 +354,7 @@ static void __devexit phantom_remove(struct pci_dev *pdev) cdev_del(&pht->cdev); iowrite32(0, pht->caddr + PHN_IRQCTL); + ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */ free_irq(pdev->irq, pht); pci_iounmap(pdev, pht->oaddr); @@ -358,6 +376,7 @@ static int phantom_suspend(struct pci_dev *pdev, pm_message_t state) struct phantom_device *dev = pci_get_drvdata(pdev); iowrite32(0, dev->caddr + PHN_IRQCTL); + ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */ return 0; } diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index a7562f7..540ff4b 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -135,23 +135,6 @@ struct mmc_blk_request { struct mmc_data data; }; -static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req) -{ - struct mmc_blk_data *md = mq->data; - int stat = BLKPREP_OK; - - /* - * If we have no device, we haven't finished initialising. - */ - if (!md || !mq->card) { - printk(KERN_ERR "%s: killing request - no device/host\n", - req->rq_disk->disk_name); - stat = BLKPREP_KILL; - } - - return stat; -} - static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) { int err; @@ -460,7 +443,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) if (ret) goto err_putdisk; - md->queue.prep_fn = mmc_blk_prep_rq; md->queue.issue_fn = mmc_blk_issue_rq; md->queue.data = md; diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 2e77963..dd97bc7 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -20,40 +20,21 @@ #define MMC_QUEUE_SUSPENDED (1 << 0) /* - * Prepare a MMC request. Essentially, this means passing the - * preparation off to the media driver. The media driver will - * create a mmc_io_request in req->special. + * Prepare a MMC request. This just filters out odd stuff. */ static int mmc_prep_request(struct request_queue *q, struct request *req) { - struct mmc_queue *mq = q->queuedata; - int ret = BLKPREP_KILL; - - if (blk_special_request(req)) { - /* - * Special commands already have the command - * blocks already setup in req->special. - */ - BUG_ON(!req->special); - - ret = BLKPREP_OK; - } else if (blk_fs_request(req) || blk_pc_request(req)) { - /* - * Block I/O requests need translating according - * to the protocol. - */ - ret = mq->prep_fn(mq, req); - } else { - /* - * Everything else is invalid. - */ + /* + * We only like normal block requests. + */ + if (!blk_fs_request(req) && !blk_pc_request(req)) { blk_dump_rq_flags(req, "MMC bad request"); + return BLKPREP_KILL; } - if (ret == BLKPREP_OK) - req->cmd_flags |= REQ_DONTPREP; + req->cmd_flags |= REQ_DONTPREP; - return ret; + return BLKPREP_OK; } static int mmc_queue_thread(void *d) diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index c9f139e..1590b3f 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h @@ -10,20 +10,12 @@ struct mmc_queue { struct semaphore thread_sem; unsigned int flags; struct request *req; - int (*prep_fn)(struct mmc_queue *, struct request *); int (*issue_fn)(struct mmc_queue *, struct request *); void *data; struct request_queue *queue; struct scatterlist *sg; }; -struct mmc_io_request { - struct request *rq; - int num; - struct mmc_command selcmd; /* mmc_queue private */ - struct mmc_command cmd[4]; /* max 4 commands */ -}; - extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *); extern void mmc_cleanup_queue(struct mmc_queue *); extern void mmc_queue_suspend(struct mmc_queue *); diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3b204ba..1798a9f 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2218,7 +2218,7 @@ config SK98LIN config VIA_VELOCITY tristate "VIA Velocity support" - depends on NET_PCI && PCI + depends on PCI select CRC32 select CRC_CCITT select MII diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig index 7284cca..4030274 100644 --- a/drivers/net/arcnet/Kconfig +++ b/drivers/net/arcnet/Kconfig @@ -2,10 +2,8 @@ # Arcnet configuration # -menu "ARCnet devices" +menuconfig ARCNET depends on NETDEVICES && (ISA || PCI) - -config ARCNET tristate "ARCnet support" ---help--- If you have a network card of this type, say Y and check out the @@ -25,9 +23,10 @@ config ARCNET <file:Documentation/networking/net-modules.txt>. The module will be called arcnet. +if ARCNET + config ARCNET_1201 tristate "Enable standard ARCNet packet format (RFC 1201)" - depends on ARCNET help This allows you to use RFC1201 with your ARCnet card via the virtual arc0 device. You need to say Y here to communicate with @@ -38,7 +37,6 @@ config ARCNET_1201 config ARCNET_1051 tristate "Enable old ARCNet packet format (RFC 1051)" - depends on ARCNET ---help--- This allows you to use RFC1051 with your ARCnet card via the virtual arc0s device. You only need arc0s if you want to talk to ARCnet @@ -53,7 +51,6 @@ config ARCNET_1051 config ARCNET_RAW tristate "Enable raw mode packet interface" - depends on ARCNET help ARCnet "raw mode" packet encapsulation, no soft headers. Unlikely to work unless talking to a copy of the same Linux arcnet driver, @@ -61,7 +58,6 @@ config ARCNET_RAW config ARCNET_CAP tristate "Enable CAP mode packet interface" - depends on ARCNET help ARCnet "cap mode" packet encapsulation. Used to get the hardware acknowledge back to userspace. After the initial protocol byte every @@ -80,7 +76,6 @@ config ARCNET_CAP config ARCNET_COM90xx tristate "ARCnet COM90xx (normal) chipset driver" - depends on ARCNET help This is the chipset driver for the standard COM90xx cards. If you have always used the old ARCnet driver without knowing what type of @@ -92,7 +87,6 @@ config ARCNET_COM90xx config ARCNET_COM90xxIO tristate "ARCnet COM90xx (IO mapped) chipset driver" - depends on ARCNET ---help--- This is the chipset driver for the COM90xx cards, using them in IO-mapped mode instead of memory-mapped mode. This is slower than @@ -105,7 +99,6 @@ config ARCNET_COM90xxIO config ARCNET_RIM_I tristate "ARCnet COM90xx (RIM I) chipset driver" - depends on ARCNET ---help--- This is yet another chipset driver for the COM90xx cards, but this time only using memory-mapped mode, and no IO ports at all. This @@ -118,7 +111,6 @@ config ARCNET_RIM_I config ARCNET_COM20020 tristate "ARCnet COM20020 chipset driver" - depends on ARCNET help This is the driver for the new COM20020 chipset. It supports such things as promiscuous mode, so packet sniffing is possible, and @@ -136,5 +128,4 @@ config ARCNET_COM20020_PCI tristate "Support for COM20020 on PCI" depends on ARCNET_COM20020 && PCI -endmenu - +endif # ARCNET diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 4aec747..9fe3a38 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -4919,7 +4919,10 @@ static int __devinit cas_init_one(struct pci_dev *pdev, pci_cmd &= ~PCI_COMMAND_SERR; pci_cmd |= PCI_COMMAND_PARITY; pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); - pci_set_mwi(pdev); + if (pci_set_mwi(pdev)) + printk(KERN_WARNING PFX "Could enable MWI for %s\n", + pci_name(pdev)); + /* * On some architectures, the default cache line size set * by pci_set_mwi reduces perforamnce. We have to increase diff --git a/drivers/net/chelsio/suni1x10gexp_regs.h b/drivers/net/chelsio/suni1x10gexp_regs.h index 269d097..d0f87d8 100644 --- a/drivers/net/chelsio/suni1x10gexp_regs.h +++ b/drivers/net/chelsio/suni1x10gexp_regs.h @@ -105,7 +105,7 @@ #define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_LOW(filterId) (0x204A + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId)) #define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_MID(filterId) (0x204B + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId)) #define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_HIGH(filterId)(0x204C + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId)) -#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_VID(filterId) (0x2062 + mSUNI1x10GEXP_MAC_VID_FILTER_OFFSET(filterId) +#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_VID(filterId) (0x2062 + mSUNI1x10GEXP_MAC_VID_FILTER_OFFSET(filterId)) #define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_LOW 0x204A #define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_MID 0x204B #define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_HIGH 0x204C diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 7a01802..4154fd0 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -195,7 +195,7 @@ enum { #define NVREG_IRQ_TX_FORCED 0x0100 #define NVREG_IRQ_RECOVER_ERROR 0x8000 #define NVREG_IRQMASK_THROUGHPUT 0x00df -#define NVREG_IRQMASK_CPU 0x0040 +#define NVREG_IRQMASK_CPU 0x0060 #define NVREG_IRQ_TX_ALL (NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED) #define NVREG_IRQ_RX_ALL (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED) #define NVREG_IRQ_OTHER (NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RECOVER_ERROR) diff --git a/drivers/net/meth.c b/drivers/net/meth.c index 0343ea1..92b403b 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -8,15 +8,16 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/module.h> -#include <linux/init.h> - -#include <linux/kernel.h> /* printk() */ #include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> #include <linux/slab.h> -#include <linux/errno.h> /* error codes */ -#include <linux/types.h> /* size_t */ -#include <linux/interrupt.h> /* mark_bh */ +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/interrupt.h> #include <linux/in.h> #include <linux/in6.h> @@ -33,7 +34,6 @@ #include <asm/io.h> #include <asm/scatterlist.h> -#include <linux/dma-mapping.h> #include "meth.h" @@ -51,8 +51,6 @@ static const char *meth_str="SGI O2 Fast Ethernet"; -MODULE_AUTHOR("Ilya Volynets <ilya@theIlya.com>"); -MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver"); #define HAVE_TX_TIMEOUT /* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */ @@ -784,15 +782,15 @@ static struct net_device_stats *meth_stats(struct net_device *dev) /* * The init function. */ -static struct net_device *meth_init(void) +static int __init meth_probe(struct platform_device *pdev) { struct net_device *dev; struct meth_private *priv; - int ret; + int err; dev = alloc_etherdev(sizeof(struct meth_private)); if (!dev) - return ERR_PTR(-ENOMEM); + return -ENOMEM; dev->open = meth_open; dev->stop = meth_release; @@ -808,11 +806,12 @@ static struct net_device *meth_init(void) priv = netdev_priv(dev); spin_lock_init(&priv->meth_lock); + SET_NETDEV_DEV(dev, &pdev->dev); - ret = register_netdev(dev); - if (ret) { + err = register_netdev(dev); + if (err) { free_netdev(dev); - return ERR_PTR(ret); + return err; } printk(KERN_INFO "%s: SGI MACE Ethernet rev. %d\n", @@ -820,21 +819,44 @@ static struct net_device *meth_init(void) return 0; } -static struct net_device *meth_dev; +static int __exit meth_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + + unregister_netdev(dev); + free_netdev(dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver meth_driver = { + .probe = meth_probe, + .remove = __devexit_p(meth_remove), + .driver = { + .name = "meth", + } +}; static int __init meth_init_module(void) { - meth_dev = meth_init(); - if (IS_ERR(meth_dev)) - return PTR_ERR(meth_dev); - return 0; + int err; + + err = platform_driver_register(&meth_driver); + if (err) + printk(KERN_ERR "Driver registration failed\n"); + + return err; } static void __exit meth_exit_module(void) { - unregister_netdev(meth_dev); - free_netdev(meth_dev); + platform_driver_unregister(&meth_driver); } module_init(meth_init_module); module_exit(meth_exit_module); + +MODULE_AUTHOR("Ilya Volynets <ilya@theIlya.com>"); +MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index 68c99b4c..bb96691 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -89,6 +89,7 @@ EXPORT_SYMBOL(fixed_mdio_set_link_update); /*----------------------------------------------------------------------------- * This is used for updating internal mii regs from the status *-----------------------------------------------------------------------------*/ +#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) static int fixed_mdio_update_regs(struct fixed_info *fixed) { u16 *regs = fixed->regs; @@ -165,6 +166,7 @@ static int fixed_mii_reset(struct mii_bus *bus) /*nothing here - no way/need to reset it*/ return 0; } +#endif static int fixed_config_aneg(struct phy_device *phydev) { @@ -194,6 +196,7 @@ static struct phy_driver fixed_mdio_driver = { * number is used to create multiple fixed PHYs, so that several devices can * utilize them simultaneously. *-----------------------------------------------------------------------------*/ +#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) static int fixed_mdio_register_device(int number, int speed, int duplex) { struct mii_bus *new_bus; @@ -301,6 +304,7 @@ device_create_fail: return err; } +#endif MODULE_DESCRIPTION("Fixed PHY device & driver for PAL"); diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index c3964c3..ef84d7c 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1014,12 +1014,12 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, */ } - /* pass skb up to stack */ - netif_receive_skb(skb); - /* update netdevice statistics */ card->netdev_stats.rx_packets++; card->netdev_stats.rx_bytes += skb->len; + + /* pass skb up to stack */ + netif_receive_skb(skb); } #ifdef DEBUG diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig index 99c4c19..e6b2e06 100644 --- a/drivers/net/tokenring/Kconfig +++ b/drivers/net/tokenring/Kconfig @@ -2,12 +2,10 @@ # Token Ring driver configuration # -menu "Token Ring devices" - depends on NETDEVICES && !UML - # So far, we only have PCI, ISA, and MCA token ring devices -config TR +menuconfig TR bool "Token Ring driver support" + depends on NETDEVICES && !UML depends on (PCI || ISA || MCA || CCW) select LLC help @@ -20,9 +18,11 @@ config TR from <http://www.tldp.org/docs.html#howto>. Most people can say N here. +if TR + config IBMTR tristate "IBM Tropic chipset based adapter support" - depends on TR && (ISA || MCA) + depends on ISA || MCA ---help--- This is support for all IBM Token Ring cards that don't use DMA. If you have such a beast, say Y and read the Token-Ring mini-HOWTO, @@ -36,7 +36,7 @@ config IBMTR config IBMOL tristate "IBM Olympic chipset PCI adapter support" - depends on TR && PCI + depends on PCI ---help--- This is support for all non-Lanstreamer IBM PCI Token Ring Cards. Specifically this is all IBM PCI, PCI Wake On Lan, PCI II, PCI II @@ -54,7 +54,7 @@ config IBMOL config IBMLS tristate "IBM Lanstreamer chipset PCI adapter support" - depends on TR && PCI && !64BIT + depends on PCI && !64BIT help This is support for IBM Lanstreamer PCI Token Ring Cards. @@ -66,7 +66,7 @@ config IBMLS config 3C359 tristate "3Com 3C359 Token Link Velocity XL adapter support" - depends on TR && PCI + depends on PCI ---help--- This is support for the 3Com PCI Velocity XL cards, specifically the 3Com 3C359, please note this is not for the 3C339 cards, you @@ -84,7 +84,7 @@ config 3C359 config TMS380TR tristate "Generic TMS380 Token Ring ISA/PCI adapter support" - depends on TR && (PCI || ISA && ISA_DMA_API || MCA) + depends on PCI || ISA && ISA_DMA_API || MCA select FW_LOADER ---help--- This driver provides generic support for token ring adapters @@ -108,7 +108,7 @@ config TMS380TR config TMSPCI tristate "Generic TMS380 PCI support" - depends on TR && TMS380TR && PCI + depends on TMS380TR && PCI ---help--- This tms380 module supports generic TMS380-based PCI cards. @@ -123,7 +123,7 @@ config TMSPCI config SKISA tristate "SysKonnect TR4/16 ISA support" - depends on TR && TMS380TR && ISA + depends on TMS380TR && ISA help This tms380 module supports SysKonnect TR4/16 ISA cards. @@ -135,7 +135,7 @@ config SKISA config PROTEON tristate "Proteon ISA support" - depends on TR && TMS380TR && ISA + depends on TMS380TR && ISA help This tms380 module supports Proteon ISA cards. @@ -148,7 +148,7 @@ config PROTEON config ABYSS tristate "Madge Smart 16/4 PCI Mk2 support" - depends on TR && TMS380TR && PCI + depends on TMS380TR && PCI help This tms380 module supports the Madge Smart 16/4 PCI Mk2 cards (51-02). @@ -158,7 +158,7 @@ config ABYSS config MADGEMC tristate "Madge Smart 16/4 Ringnode MicroChannel" - depends on TR && TMS380TR && MCA + depends on TMS380TR && MCA help This tms380 module supports the Madge Smart 16/4 MC16 and MC32 MicroChannel adapters. @@ -168,7 +168,7 @@ config MADGEMC config SMCTR tristate "SMC ISA/MCA adapter support" - depends on TR && (ISA || MCA_LEGACY) && (BROKEN || !64BIT) + depends on (ISA || MCA_LEGACY) && (BROKEN || !64BIT) ---help--- This is support for the ISA and MCA SMC Token Ring cards, specifically SMC TokenCard Elite (8115T) and SMC TokenCard Elite/A @@ -182,5 +182,4 @@ config SMCTR To compile this driver as a module, choose M here: the module will be called smctr. -endmenu - +endif # TR diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index c2ccbd0..18b731b 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -23,11 +23,8 @@ #include <linux/skbuff.h> #include <linux/spinlock.h> #include <linux/mm.h> -#include <linux/ethtool.h> -#include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/fsl_devices.h> -#include <linux/ethtool.h> #include <linux/mii.h> #include <linux/phy.h> #include <linux/workqueue.h> diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index f96966d..7bcb82f 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c @@ -260,8 +260,6 @@ static struct of_device_id uec_mdio_match[] = { {}, }; -MODULE_DEVICE_TABLE(of, uec_mdio_match); - static struct of_platform_driver uec_mdio_driver = { .name = DRV_NAME, .probe = uec_mdio_probe, diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index d5ef97b..6d95cac 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1458,6 +1458,10 @@ static const struct usb_device_id products [] = { // IO-DATA ETG-US2 USB_DEVICE (0x04bb, 0x0930), .driver_info = (unsigned long) &ax88178_info, +}, { + // Belkin F5D5055 + USB_DEVICE(0x050d, 0x5055), + .driver_info = (unsigned long) &ax88178_info, }, { }, // END }; diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 5a21f06..675ac99 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -91,6 +91,22 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) "CDC descriptors on config\n"); } + /* Maybe CDC descriptors are after the endpoint? This bug has + * been seen on some 2Wire Inc RNDIS-ish products. + */ + if (len == 0) { + struct usb_host_endpoint *hep; + + hep = intf->cur_altsetting->endpoint; + if (hep) { + buf = hep->extra; + len = hep->extralen; + } + if (len) + dev_dbg(&intf->dev, + "CDC descriptors on endpoint\n"); + } + /* this assumes that if there's a non-RNDIS vendor variant * of cdc-acm, it'll fail RNDIS requests cleanly. */ diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 980e4aa..cd991a0 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -515,6 +515,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) dev_err(&intf->dev, "dev can't take %u byte packets (max %u)\n", dev->hard_mtu, tmp); + retval = -EINVAL; goto fail_and_release; } diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index f9cd42d..5b16d9a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1252,20 +1252,23 @@ EXPORT_SYMBOL_GPL(usbnet_probe); /*-------------------------------------------------------------------------*/ -/* FIXME these suspend/resume methods assume non-CDC style - * devices, with only one interface. +/* + * suspend the whole driver as soon as the first interface is suspended + * resume only when the last interface is resumed */ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) { struct usbnet *dev = usb_get_intfdata(intf); - /* accelerate emptying of the rx and queues, to avoid - * having everything error out. - */ - netif_device_detach (dev->net); - (void) unlink_urbs (dev, &dev->rxq); - (void) unlink_urbs (dev, &dev->txq); + if (!dev->suspend_count++) { + /* accelerate emptying of the rx and queues, to avoid + * having everything error out. + */ + netif_device_detach (dev->net); + (void) unlink_urbs (dev, &dev->rxq); + (void) unlink_urbs (dev, &dev->txq); + } return 0; } EXPORT_SYMBOL_GPL(usbnet_suspend); @@ -1274,8 +1277,10 @@ int usbnet_resume (struct usb_interface *intf) { struct usbnet *dev = usb_get_intfdata(intf); - netif_device_attach (dev->net); - tasklet_schedule (&dev->bh); + if (!--dev->suspend_count) { + netif_device_attach (dev->net); + tasklet_schedule (&dev->bh); + } return 0; } EXPORT_SYMBOL_GPL(usbnet_resume); diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h index 82db5a8..a3f8b9e 100644 --- a/drivers/net/usb/usbnet.h +++ b/drivers/net/usb/usbnet.h @@ -32,6 +32,7 @@ struct usbnet { const char *driver_name; wait_queue_head_t *wait; struct mutex phy_mutex; + unsigned char suspend_count; /* i/o info: pipes etc */ unsigned in, out; diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 606bdd0..dfe2764 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -46,7 +46,7 @@ u32 libertas_index_to_data_rate(u8 index); u8 libertas_data_rate_to_index(u32 rate); void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen); -int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb); +void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb); /** The proc fs interface */ int libertas_process_rx_command(wlan_private * priv); diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c index 441123c..5c63c9b 100644 --- a/drivers/net/wireless/libertas/fw.c +++ b/drivers/net/wireless/libertas/fw.c @@ -333,18 +333,22 @@ static void command_timer_fn(unsigned long data) unsigned long flags; ptempnode = adapter->cur_cmd; + if (ptempnode == NULL) { + lbs_pr_debug(1, "PTempnode Empty\n"); + return; + } + cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr; + if (!cmd) { + lbs_pr_debug(1, "cmd is NULL\n"); + return; + } lbs_pr_info("command_timer_fn fired (%x)\n", cmd->command); if (!adapter->fw_ready) return; - if (ptempnode == NULL) { - lbs_pr_debug(1, "PTempnode Empty\n"); - return; - } - spin_lock_irqsave(&adapter->driver_lock, flags); adapter->cur_cmd = NULL; spin_unlock_irqrestore(&adapter->driver_lock, flags); diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index d17924f..96619a32 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -136,7 +136,7 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd) LEAVE(); } -int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb) +void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb) { lbs_pr_debug(1, "skb->data=%p\n", skb->data); @@ -148,8 +148,6 @@ int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb) skb->ip_summed = CHECKSUM_UNNECESSARY; netif_rx(skb); - - return 0; } /** @@ -269,15 +267,11 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) wlan_compute_rssi(priv, p_rx_pd); lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len); - if (libertas_upload_rx_packet(priv, skb)) { - lbs_pr_debug(1, "RX error: libertas_upload_rx_packet" - " returns failure\n"); - ret = -1; - goto done; - } priv->stats.rx_bytes += skb->len; priv->stats.rx_packets++; + libertas_upload_rx_packet(priv, skb); + ret = 0; done: LEAVE(); @@ -438,22 +432,14 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) wlan_compute_rssi(priv, prxpd); lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len); - - if (libertas_upload_rx_packet(priv, skb)) { - lbs_pr_debug(1, "RX error: libertas_upload_rx_packet " - "returns failure\n"); - ret = -1; - goto done; - } - priv->stats.rx_bytes += skb->len; priv->stats.rx_packets++; + libertas_upload_rx_packet(priv, skb); + ret = 0; done: LEAVE(); - skb->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */ - return (ret); } diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index ddff40c..821cde65 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -1127,6 +1127,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) int retval = 0; unsigned long flags; + zfcp_adapter_scsi_unregister(adapter); device_unregister(&adapter->generic_services); zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); dev_set_drvdata(&adapter->ccw_device->dev, NULL); diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 81680ef..1c8f71a 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -189,9 +189,7 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) * @ccw_device: pointer to belonging ccw device * * This function gets called by the common i/o layer and sets an adapter - * into state offline. Setting an fcp device offline means that it will be - * unregistered from the SCSI stack and that the adapter will be shut down - * asynchronously. + * into state offline. */ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) @@ -202,7 +200,6 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device) adapter = dev_get_drvdata(&ccw_device->dev); zfcp_erp_adapter_shutdown(adapter, 0); zfcp_erp_wait(adapter); - zfcp_adapter_scsi_unregister(adapter); zfcp_erp_thread_kill(adapter); zfcp_adapter_debug_unregister(adapter); up(&zfcp_data.config_sema); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index a8b0254..0eb31e1 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -156,44 +156,30 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req) kfree(fsf_req); } -/** - * zfcp_fsf_req_dismiss - dismiss a single fsf request - */ -static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter, - struct zfcp_fsf_req *fsf_req, - unsigned int counter) -{ - u64 dbg_tmp[2]; - - dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active); - dbg_tmp[1] = (u64) counter; - debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16); - list_del(&fsf_req->list); - fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; - zfcp_fsf_req_complete(fsf_req); -} - -/** - * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests +/* + * Never ever call this without shutting down the adapter first. + * Otherwise the adapter would continue using and corrupting s390 storage. + * Included BUG_ON() call to ensure this is done. + * ERP is supposed to be the only user of this function. */ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) { - struct zfcp_fsf_req *request, *tmp; + struct zfcp_fsf_req *fsf_req, *tmp; unsigned long flags; LIST_HEAD(remove_queue); - unsigned int i, counter; + unsigned int i; + BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)); spin_lock_irqsave(&adapter->req_list_lock, flags); atomic_set(&adapter->reqs_active, 0); - for (i=0; i<REQUEST_LIST_SIZE; i++) + for (i = 0; i < REQUEST_LIST_SIZE; i++) list_splice_init(&adapter->req_list[i], &remove_queue); - spin_unlock_irqrestore(&adapter->req_list_lock, flags); - counter = 0; - list_for_each_entry_safe(request, tmp, &remove_queue, list) { - zfcp_fsf_req_dismiss(adapter, request, counter); - counter++; + list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) { + list_del(&fsf_req->list); + fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; + zfcp_fsf_req_complete(fsf_req); } } diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 16e2d64..0acf6db 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -569,6 +569,9 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) int retval = 0; static unsigned int unique_id = 0; + if (adapter->scsi_host) + goto out; + /* register adapter as SCSI host with mid layer of SCSI stack */ adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template, sizeof (struct zfcp_adapter *)); diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 1e82c69..8dcfe4e 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -146,7 +146,7 @@ static char *aac_get_status_string(u32 status); static int nondasd = -1; static int dacmode = -1; -static int commit = -1; +int aac_commit = -1; int startup_timeout = 180; int aif_timeout = 120; @@ -154,7 +154,7 @@ module_param(nondasd, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); module_param(dacmode, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on"); -module_param(commit, int, S_IRUGO|S_IWUSR); +module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on"); module_param(startup_timeout, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS."); @@ -173,6 +173,9 @@ int expose_physicals = -1; module_param(expose_physicals, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on"); +int aac_reset_devices = 0; +module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization."); static inline int aac_valid_context(struct scsi_cmnd *scsicmd, struct fib *fibptr) { @@ -246,7 +249,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) aac_fib_complete(fibptr); /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ if (status >= 0) { - if ((commit == 1) || commit_flag) { + if ((aac_commit == 1) || commit_flag) { struct aac_commit_config * dinfo; aac_fib_init(fibptr); dinfo = (struct aac_commit_config *) fib_data(fibptr); @@ -261,7 +264,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) 1, 1, NULL, NULL); aac_fib_complete(fibptr); - } else if (commit == 0) { + } else if (aac_commit == 0) { printk(KERN_WARNING "aac_get_config_status: Foreign device configurations are being ignored\n"); } @@ -340,7 +343,7 @@ int aac_get_containers(struct aac_dev *dev) static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) { void *buf; - unsigned int transfer_len; + int transfer_len; struct scatterlist *sg = scsicmd->request_buffer; if (scsicmd->use_sg) { @@ -351,7 +354,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne transfer_len = min(scsicmd->request_bufflen, len + offset); } transfer_len -= offset; - if (buf && transfer_len) + if (buf && transfer_len > 0) memcpy(buf + offset, data, transfer_len); if (scsicmd->use_sg) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 45ca3e8..c81edf3 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1823,9 +1823,12 @@ int aac_send_shutdown(struct aac_dev *dev); int aac_probe_container(struct aac_dev *dev, int cid); int _aac_rx_init(struct aac_dev *dev); int aac_rx_select_comm(struct aac_dev *dev, int comm); +int aac_rx_deliver_producer(struct fib * fib); extern int numacb; extern int acbsize; extern char aac_driver_version[]; extern int startup_timeout; extern int aif_timeout; extern int expose_physicals; +extern int aac_reset_devices; +extern int aac_commit; diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index 291cd14..ae978a3 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c @@ -378,7 +378,7 @@ static int aac_rx_check_health(struct aac_dev *dev) * * Will send a fib, returning 0 if successful. */ -static int aac_rx_deliver_producer(struct fib * fib) +int aac_rx_deliver_producer(struct fib * fib) { struct aac_dev *dev = fib->dev; struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; @@ -488,6 +488,8 @@ static int aac_rx_restart_adapter(struct aac_dev *dev, int bled) return -EINVAL; if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) return -ENODEV; + if (startup_timeout < 300) + startup_timeout = 300; return 0; } @@ -542,7 +544,7 @@ int _aac_rx_init(struct aac_dev *dev) dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt; dev->OIMR = status = rx_readb (dev, MUnit.OIMR); - if ((((status & 0x0c) != 0x0c) || reset_devices) && + if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) && !aac_rx_restart_adapter(dev, 0)) ++restart; /* @@ -594,6 +596,8 @@ int _aac_rx_init(struct aac_dev *dev) } msleep(1); } + if (restart) + aac_commit = 1; /* * Fill in the common function dispatch table. */ diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index f4b5e97..85b91bc 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -257,6 +257,11 @@ static void aac_sa_start_adapter(struct aac_dev *dev) NULL, NULL, NULL, NULL, NULL); } +static int aac_sa_restart_adapter(struct aac_dev *dev, int bled) +{ + return -EINVAL; +} + /** * aac_sa_check_health * @dev: device to check if healthy @@ -366,7 +371,9 @@ int aac_sa_init(struct aac_dev *dev) dev->a_ops.adapter_notify = aac_sa_notify_adapter; dev->a_ops.adapter_sync_cmd = sa_sync_cmd; dev->a_ops.adapter_check_health = aac_sa_check_health; + dev->a_ops.adapter_restart = aac_sa_restart_adapter; dev->a_ops.adapter_intr = aac_sa_intr; + dev->a_ops.adapter_deliver = aac_rx_deliver_producer; dev->a_ops.adapter_ioremap = aac_sa_ioremap; /* diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y index c328596..6066998 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y @@ -106,6 +106,7 @@ static void make_expression(expression_t *immed, int value); static void add_conditional(symbol_t *symbol); static void add_version(const char *verstring); static int is_download_const(expression_t *immed); +void yyerror(const char *string); #define SRAM_SYMNAME "SRAM_BASE" #define SCB_SYMNAME "SCB_BASE" diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y index 439f760..ff46aa6 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y @@ -65,6 +65,7 @@ static symbol_t *macro_symbol; static void add_macro_arg(const char *argtext, int position); +void mmerror(const char *string); %} diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c index 9a14a6d..c0d0b7d 100644 --- a/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/drivers/scsi/aic94xx/aic94xx_tmf.c @@ -290,6 +290,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb, static inline int asd_clear_nexus(struct sas_task *task) { int res = TMF_RESP_FUNC_FAILED; + int leftover; struct asd_ascb *tascb = task->lldd_task; unsigned long flags; @@ -298,10 +299,12 @@ static inline int asd_clear_nexus(struct sas_task *task) res = asd_clear_nexus_tag(task); else res = asd_clear_nexus_index(task); - wait_for_completion_timeout(&tascb->completion, - AIC94XX_SCB_TIMEOUT); + leftover = wait_for_completion_timeout(&tascb->completion, + AIC94XX_SCB_TIMEOUT); ASD_DPRINTK("came back from clear nexus\n"); spin_lock_irqsave(&task->task_state_lock, flags); + if (leftover < 1) + res = TMF_RESP_FUNC_FAILED; if (task->task_state_flags & SAS_TASK_STATE_DONE) res = TMF_RESP_FUNC_COMPLETE; spin_unlock_irqrestore(&task->task_state_lock, flags); @@ -350,6 +353,7 @@ int asd_abort_task(struct sas_task *task) unsigned long flags; struct asd_ascb *ascb = NULL; struct scb *scb; + int leftover; spin_lock_irqsave(&task->task_state_lock, flags); if (task->task_state_flags & SAS_TASK_STATE_DONE) { @@ -455,9 +459,11 @@ int asd_abort_task(struct sas_task *task) break; case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */ res = TMF_RESP_FUNC_FAILED; - wait_for_completion_timeout(&tascb->completion, - AIC94XX_SCB_TIMEOUT); + leftover = wait_for_completion_timeout(&tascb->completion, + AIC94XX_SCB_TIMEOUT); spin_lock_irqsave(&task->task_state_lock, flags); + if (leftover < 1) + res = TMF_RESP_FUNC_FAILED; if (task->task_state_flags & SAS_TASK_STATE_DONE) res = TMF_RESP_FUNC_COMPLETE; spin_unlock_irqrestore(&task->task_state_lock, flags); diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 4baa79e..fa6ff29 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3954,6 +3954,13 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) spin_unlock_irq(scsi_cmd->device->host->host_lock); ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL); spin_lock_irq(scsi_cmd->device->host->host_lock); + + list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { + if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { + rc = -EIO; + break; + } + } } else rc = ipr_device_reset(ioa_cfg, res); res->resetting_device = 0; diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 5631c19..732446e 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -254,6 +254,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, sg_init_one(&dummy, md, id->table_desc.len); sg_dma_address(&dummy) = token; + sg_dma_len(&dummy) = id->table_desc.len; err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE, id->table_desc.len); if (err) { diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 7a81267..e2cf12e 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.03.10-rc1 + * Version : v00.00.03.10-rc5 * * Authors: * (email-id : megaraidlinux@lsi.com) @@ -886,6 +886,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) goto out_return_cmd; cmd->scmd = scmd; + scmd->SCp.ptr = (char *)cmd; /* * Issue the command to the FW @@ -919,7 +920,7 @@ static int megasas_slave_configure(struct scsi_device *sdev) * The RAID firmware may require extended timeouts. */ if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) - sdev->timeout = 90 * HZ; + sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ; return 0; } @@ -981,8 +982,8 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) instance = (struct megasas_instance *)scmd->device->host->hostdata; - scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x\n", - scmd->serial_number, scmd->cmnd[0]); + scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n", + scmd->serial_number, scmd->cmnd[0], scmd->retries); if (instance->hw_crit_error) { printk(KERN_ERR "megasas: cannot recover from previous reset " @@ -1000,6 +1001,39 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) } /** + * megasas_reset_timer - quiesce the adapter if required + * @scmd: scsi cmnd + * + * Sets the FW busy flag and reduces the host->can_queue if the + * cmd has not been completed within the timeout period. + */ +static enum +scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd) +{ + struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr; + struct megasas_instance *instance; + unsigned long flags; + + if (time_after(jiffies, scmd->jiffies_at_alloc + + (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) { + return EH_NOT_HANDLED; + } + + instance = cmd->instance; + if (!(instance->flag & MEGASAS_FW_BUSY)) { + /* FW is busy, throttle IO */ + spin_lock_irqsave(instance->host->host_lock, flags); + + instance->host->can_queue = 16; + instance->last_time = jiffies; + instance->flag |= MEGASAS_FW_BUSY; + + spin_unlock_irqrestore(instance->host->host_lock, flags); + } + return EH_RESET_TIMER; +} + +/** * megasas_reset_device - Device reset handler entry point */ static int megasas_reset_device(struct scsi_cmnd *scmd) @@ -1112,6 +1146,7 @@ static struct scsi_host_template megasas_template = { .eh_device_reset_handler = megasas_reset_device, .eh_bus_reset_handler = megasas_reset_bus_host, .eh_host_reset_handler = megasas_reset_bus_host, + .eh_timed_out = megasas_reset_timer, .bios_param = megasas_bios_param, .use_clustering = ENABLE_CLUSTERING, }; @@ -1215,9 +1250,8 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, int exception = 0; struct megasas_header *hdr = &cmd->frame->hdr; - if (cmd->scmd) { - cmd->scmd->SCp.ptr = (char *)0; - } + if (cmd->scmd) + cmd->scmd->SCp.ptr = NULL; switch (hdr->cmd) { @@ -1806,6 +1840,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr) u32 context; struct megasas_cmd *cmd; struct megasas_instance *instance = (struct megasas_instance *)instance_addr; + unsigned long flags; /* If we have already declared adapter dead, donot complete cmds */ if (instance->hw_crit_error) @@ -1828,6 +1863,22 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr) } *instance->consumer = producer; + + /* + * Check if we can restore can_queue + */ + if (instance->flag & MEGASAS_FW_BUSY + && time_after(jiffies, instance->last_time + 5 * HZ) + && atomic_read(&instance->fw_outstanding) < 17) { + + spin_lock_irqsave(instance->host->host_lock, flags); + instance->flag &= ~MEGASAS_FW_BUSY; + instance->host->can_queue = + instance->max_fw_cmds - MEGASAS_INT_CMDS; + + spin_unlock_irqrestore(instance->host->host_lock, flags); + } + } /** @@ -2398,6 +2449,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) instance->init_id = MEGASAS_DEFAULT_INIT_ID; megasas_dbg_lvl = 0; + instance->flag = 0; + instance->last_time = 0; /* * Initialize MFI Firmware diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index e862992..4dffc91 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -18,9 +18,9 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.03.10-rc1" -#define MEGASAS_RELDATE "Feb 14, 2007" -#define MEGASAS_EXT_VERSION "Wed Feb 14 10:14:25 PST 2007" +#define MEGASAS_VERSION "00.00.03.10-rc5" +#define MEGASAS_RELDATE "May 17, 2007" +#define MEGASAS_EXT_VERSION "Thu May 17 10:09:32 PDT 2007" /* * Device IDs @@ -539,6 +539,8 @@ struct megasas_ctrl_info { #define MEGASAS_DBG_LVL 1 +#define MEGASAS_FW_BUSY 1 + /* * When SCSI mid-layer calls driver's reset routine, driver waits for * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note @@ -549,8 +551,8 @@ struct megasas_ctrl_info { #define MEGASAS_RESET_WAIT_TIME 180 #define MEGASAS_INTERNAL_CMD_WAIT_TIME 180 #define MEGASAS_RESET_NOTICE_INTERVAL 5 - #define MEGASAS_IOCTL_CMD 0 +#define MEGASAS_DEFAULT_CMD_TIMEOUT 90 /* * FW reports the maximum of number of commands that it can accept (maximum @@ -1073,7 +1075,6 @@ struct megasas_instance { struct megasas_register_set __iomem *reg_set; s8 init_id; - u8 reserved[3]; u16 max_num_sge; u16 max_fw_cmds; @@ -1104,6 +1105,9 @@ struct megasas_instance { struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; + + u8 flag; + unsigned long last_time; }; #define MEGASAS_IS_LOGICAL(scp) \ diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index ce63044..18dd5cc 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -209,6 +209,7 @@ static struct { {"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"Promise", "", NULL, BLIST_SPARSELUN}, {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, {"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */ diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 00e4666..3d8c9cb 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1789,7 +1789,7 @@ static void sd_shutdown(struct device *dev) static int sd_suspend(struct device *dev, pm_message_t mesg) { struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); - int ret; + int ret = 0; if (!sdkp) return 0; /* this can happen */ @@ -1798,30 +1798,34 @@ static int sd_suspend(struct device *dev, pm_message_t mesg) sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); ret = sd_sync_cache(sdkp); if (ret) - return ret; + goto done; } if (mesg.event == PM_EVENT_SUSPEND && sdkp->device->manage_start_stop) { sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); ret = sd_start_stop_device(sdkp, 0); - if (ret) - return ret; } - return 0; +done: + scsi_disk_put(sdkp); + return ret; } static int sd_resume(struct device *dev) { struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); + int ret = 0; if (!sdkp->device->manage_start_stop) - return 0; + goto done; sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); + ret = sd_start_stop_device(sdkp, 1); - return sd_start_stop_device(sdkp, 1); +done: + scsi_disk_put(sdkp); + return ret; } /** diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 69be132..9ac83ab 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -32,11 +32,12 @@ #include <scsi/scsi_cmnd.h> #include <scsi/scsi_host.h> #include <scsi/scsi_tcq.h> +#include <scsi/scsi_dbg.h> #define DRV_NAME "stex" -#define ST_DRIVER_VERSION "3.1.0.1" +#define ST_DRIVER_VERSION "3.6.0000.1" #define ST_VER_MAJOR 3 -#define ST_VER_MINOR 1 +#define ST_VER_MINOR 6 #define ST_OEM 0 #define ST_BUILD_VER 1 @@ -113,10 +114,6 @@ enum { SG_CF_64B = 0x40, /* 64 bit item */ SG_CF_HOST = 0x20, /* sg in host memory */ - ST_MAX_ARRAY_SUPPORTED = 16, - ST_MAX_TARGET_NUM = (ST_MAX_ARRAY_SUPPORTED+1), - ST_MAX_LUN_PER_TARGET = 16, - st_shasta = 0, st_vsc = 1, st_vsc1 = 2, @@ -586,7 +583,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) u16 tag; host = cmd->device->host; id = cmd->device->id; - lun = cmd->device->channel; /* firmware lun issue work around */ + lun = cmd->device->lun; hba = (struct st_hba *) &host->hostdata[0]; switch (cmd->cmnd[0]) { @@ -605,8 +602,26 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) stex_invalid_field(cmd, done); return 0; } + case REPORT_LUNS: + /* + * The shasta firmware does not report actual luns in the + * target, so fail the command to force sequential lun scan. + * Also, the console device does not support this command. + */ + if (hba->cardtype == st_shasta || id == host->max_id - 1) { + stex_invalid_field(cmd, done); + return 0; + } + break; + case TEST_UNIT_READY: + if (id == host->max_id - 1) { + cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; + done(cmd); + return 0; + } + break; case INQUIRY: - if (id != ST_MAX_ARRAY_SUPPORTED) + if (id != host->max_id - 1) break; if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { stex_direct_copy(cmd, console_inq_page, @@ -624,7 +639,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) ver.oem = ST_OEM; ver.build = ST_BUILD_VER; ver.signature[0] = PASSTHRU_SIGNATURE; - ver.console_id = ST_MAX_ARRAY_SUPPORTED; + ver.console_id = host->max_id - 1; ver.host_no = hba->host->host_no; cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ? DID_OK << 16 | COMMAND_COMPLETE << 8 : @@ -645,13 +660,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) req = stex_alloc_req(hba); - if (hba->cardtype == st_yosemite) { - req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id; - req->target = 0; - } else { - req->lun = lun; - req->target = id; - } + req->lun = lun; + req->target = id; /* cdb */ memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); @@ -767,18 +777,6 @@ static void stex_ys_commands(struct st_hba *hba, ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; else ccb->srb_status = SRB_STATUS_SUCCESS; - } else if (ccb->cmd->cmnd[0] == REPORT_LUNS) { - u8 *report_lun_data = (u8 *)hba->copy_buffer; - - count = STEX_EXTRA_SIZE; - stex_internal_copy(ccb->cmd, report_lun_data, - &count, ccb->sg_count, ST_FROM_CMD); - if (report_lun_data[2] || report_lun_data[3]) { - report_lun_data[2] = 0x00; - report_lun_data[3] = 0x08; - stex_internal_copy(ccb->cmd, report_lun_data, - &count, ccb->sg_count, ST_TO_CMD); - } } } @@ -995,6 +993,11 @@ static int stex_abort(struct scsi_cmnd *cmd) u32 data; int result = SUCCESS; unsigned long flags; + + printk(KERN_INFO DRV_NAME + "(%s): aborting command\n", pci_name(hba->pdev)); + scsi_print_command(cmd); + base = hba->mmio_base; spin_lock_irqsave(host->host_lock, flags); if (tag < host->can_queue && hba->ccb[tag].cmd == cmd) @@ -1051,7 +1054,12 @@ static void stex_hard_reset(struct st_hba *hba) pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl); pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET; pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); - msleep(1); + + /* + * 1 ms may be enough for 8-port controllers. But 16-port controllers + * require more time to finish bus reset. Use 100 ms here for safety + */ + msleep(100); pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET; pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); @@ -1075,6 +1083,10 @@ static int stex_reset(struct scsi_cmnd *cmd) unsigned long before; hba = (struct st_hba *) &cmd->device->host->hostdata[0]; + printk(KERN_INFO DRV_NAME + "(%s): resetting host\n", pci_name(hba->pdev)); + scsi_print_command(cmd); + hba->mu_status = MU_STATE_RESETTING; if (hba->cardtype == st_shasta) @@ -1194,7 +1206,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_scsi_host_put; } - hba->mmio_base = ioremap(pci_resource_start(pdev, 0), + hba->mmio_base = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if ( !hba->mmio_base) { printk(KERN_ERR DRV_NAME "(%s): memory map failed\n", @@ -1229,12 +1241,18 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; hba->mu_status = MU_STATE_STARTING; - /* firmware uses id/lun pair for a logical drive, but lun would be - always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use - channel to map lun here */ - host->max_channel = ST_MAX_LUN_PER_TARGET - 1; - host->max_id = ST_MAX_TARGET_NUM; - host->max_lun = 1; + if (hba->cardtype == st_shasta) { + host->max_lun = 8; + host->max_id = 16 + 1; + } else if (hba->cardtype == st_yosemite) { + host->max_lun = 128; + host->max_id = 1 + 1; + } else { + /* st_vsc and st_vsc1 */ + host->max_lun = 1; + host->max_id = 128 + 1; + } + host->max_channel = 0; host->unique_id = host->host_no; host->max_cmd_len = STEX_CDB_LENGTH; diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 052359f..11f36be 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -329,8 +329,8 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) int ret = 0; #if defined(CONFIG_PPC_MERGE) - cdm = mpc52xx_find_and_map("mpc52xx-cdm"); - gpio = mpc52xx_find_and_map("mpc52xx-gpio"); + cdm = mpc52xx_find_and_map("mpc5200-cdm"); + gpio = mpc52xx_find_and_map("mpc5200-gpio"); #else cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE); gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE); @@ -445,9 +445,6 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, struct spi_master *master; int ret; - if (pdata == NULL) - return -ENODEV; - master = spi_alloc_master(dev, sizeof *mps); if (master == NULL) return -ENOMEM; @@ -594,17 +591,17 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, } regaddr64 = of_translate_address(op->node, regaddr_p); + /* get PSC id (1..6, used by port_config) */ if (op->dev.platform_data == NULL) { - struct device_node *np; - int i = 0; + const u32 *psc_nump; - for_each_node_by_type(np, "spi") { - if (of_find_device_by_node(np) == op) { - id = i; - break; - } - i++; + psc_nump = of_get_property(op->node, "cell-index", NULL); + if (!psc_nump || *psc_nump > 5) { + printk(KERN_ERR "mpc52xx_psc_spi: Device node %s has invalid " + "cell-index property\n", op->node->full_name); + return -EINVAL; } + id = *psc_nump + 1; } return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, @@ -617,7 +614,7 @@ static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op) } static struct of_device_id mpc52xx_psc_spi_of_match[] = { - { .type = "spi", .compatible = "mpc52xx-psc-spi", }, + { .type = "spi", .compatible = "mpc5200-psc-spi", }, {}, }; diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c index 96f62b2..95183e1 100644 --- a/drivers/spi/omap_uwire.c +++ b/drivers/spi/omap_uwire.c @@ -358,11 +358,11 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) switch (spi->mode & (SPI_CPOL | SPI_CPHA)) { case SPI_MODE_0: case SPI_MODE_3: - flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE; + flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE; break; case SPI_MODE_1: case SPI_MODE_2: - flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE; + flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE; break; } diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 225d6b2..d04242a 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -168,6 +168,12 @@ static int spidev_message(struct spidev_data *spidev, n--, k_tmp++, u_tmp++) { k_tmp->len = u_tmp->len; + total += k_tmp->len; + if (total > bufsiz) { + status = -EMSGSIZE; + goto done; + } + if (u_tmp->rx_buf) { k_tmp->rx_buf = buf; if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len)) @@ -179,12 +185,6 @@ static int spidev_message(struct spidev_data *spidev, u_tmp->len)) goto done; } - - total += k_tmp->len; - if (total > bufsiz) { - status = -EMSGSIZE; - goto done; - } buf += k_tmp->len; k_tmp->cs_change = !!u_tmp->cs_change; @@ -364,6 +364,7 @@ spidev_ioctl(struct inode *inode, struct file *filp, break; } if (__copy_from_user(ioc, (void __user *)arg, tmp)) { + kfree(ioc); retval = -EFAULT; break; } diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 15e740e..7b1edfe 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -1003,7 +1003,7 @@ abort: usblp->writebuf, usblp->writeurb->transfer_dma); if (usblp->readbuf) usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, - usblp->readbuf, usblp->writeurb->transfer_dma); + usblp->readbuf, usblp->readurb->transfer_dma); kfree(usblp->statusbuf); kfree(usblp->device_id_string); usb_free_urb(usblp->writeurb); diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index bfb3731..2d4fd53 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -185,10 +185,12 @@ static int usb_parse_interface(struct device *ddev, int cfgno, num_ep = USB_MAXENDPOINTS; } - len = sizeof(struct usb_host_endpoint) * num_ep; - alt->endpoint = kzalloc(len, GFP_KERNEL); - if (!alt->endpoint) - return -ENOMEM; + if (num_ep > 0) { /* Can't allocate 0 bytes */ + len = sizeof(struct usb_host_endpoint) * num_ep; + alt->endpoint = kzalloc(len, GFP_KERNEL); + if (!alt->endpoint) + return -ENOMEM; + } /* Parse all the endpoint descriptors */ n = 0; diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index b9f7f90..2619986 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -983,7 +983,10 @@ static int autosuspend_check(struct usb_device *udev) #else -#define autosuspend_check(udev) 0 +static inline int autosuspend_check(struct usb_device *udev) +{ + return 0; +} #endif /* CONFIG_USB_SUSPEND */ @@ -1041,7 +1044,6 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) if (status < 0) goto done; } - cancel_delayed_work(&udev->autosuspend); /* Suspend all the interfaces and then udev itself */ if (udev->actconfig) { @@ -1062,9 +1064,16 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) usb_resume_interface(intf); } + /* Try another autosuspend when the interfaces aren't busy */ + if (udev->auto_pm) + autosuspend_check(udev); + /* If the suspend succeeded, propagate it up the tree */ - } else if (parent) - usb_autosuspend_device(parent); + } else { + cancel_delayed_work(&udev->autosuspend); + if (parent) + usb_autosuspend_device(parent); + } done: // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); @@ -1475,6 +1484,7 @@ int usb_external_resume_device(struct usb_device *udev) usb_pm_lock(udev); udev->auto_pm = 0; status = usb_resume_both(udev); + udev->last_busy = jiffies; usb_pm_unlock(udev); /* Now that the device is awake, we can start trying to autosuspend diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 40cf882..8969e42 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1018,8 +1018,8 @@ done: atomic_dec (&urb->use_count); if (urb->reject) wake_up (&usb_kill_urb_queue); - usb_put_urb (urb); usbmon_urb_submit_error(&hcd->self, urb, status); + usb_put_urb (urb); } return status; } @@ -1175,10 +1175,6 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, struct urb *urb; hcd = bus_to_hcd(udev->bus); - - WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT && - udev->state != USB_STATE_NOTATTACHED); - local_irq_disable (); /* ep is already gone from udev->ep_{in,out}[]; no more submits */ @@ -1685,7 +1681,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) spin_unlock_irq (&hcd_root_hub_lock); #ifdef CONFIG_PM - flush_workqueue(ksuspend_usb_wq); + cancel_work_sync(&hcd->wakeup_work); #endif mutex_lock(&usb_bus_list_lock); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index f6b74a6..24f10a1 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1158,6 +1158,30 @@ static void release_address(struct usb_device *udev) } } +#ifdef CONFIG_USB_SUSPEND + +static void usb_stop_pm(struct usb_device *udev) +{ + /* Synchronize with the ksuspend thread to prevent any more + * autosuspend requests from being submitted, and decrement + * the parent's count of unsuspended children. + */ + usb_pm_lock(udev); + if (udev->parent && !udev->discon_suspended) + usb_autosuspend_device(udev->parent); + usb_pm_unlock(udev); + + /* Stop any autosuspend requests already submitted */ + cancel_rearming_delayed_work(&udev->autosuspend); +} + +#else + +static inline void usb_stop_pm(struct usb_device *udev) +{ } + +#endif + /** * usb_disconnect - disconnect a device (usbcore-internal) * @pdev: pointer to device being disconnected @@ -1224,13 +1248,7 @@ void usb_disconnect(struct usb_device **pdev) *pdev = NULL; spin_unlock_irq(&device_state_lock); - /* Decrement the parent's count of unsuspended children */ - if (udev->parent) { - usb_pm_lock(udev); - if (!udev->discon_suspended) - usb_autosuspend_device(udev->parent); - usb_pm_unlock(udev); - } + usb_stop_pm(udev); put_device(&udev->dev); } @@ -2201,14 +2219,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, continue; } - /* Use a short timeout the first time through, - * so that recalcitrant full-speed devices with - * 8- or 16-byte ep0-maxpackets won't slow things - * down tremendously by NAKing the unexpectedly - * early status stage. Also, retry on all errors; - * some devices are flakey. - * 255 is for WUSB devices, we actually need to use 512. - * WUSB1.0[4.8.1]. + /* Retry on all errors; some devices are flakey. + * 255 is for WUSB devices, we actually need to use + * 512 (WUSB1.0[4.8.1]). */ for (j = 0; j < 3; ++j) { buf->bMaxPacketSize0 = 0; @@ -2216,7 +2229,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, USB_DT_DEVICE << 8, 0, buf, GET_DESCRIPTOR_BUFSIZE, - (i ? USB_CTRL_GET_TIMEOUT : 1000)); + USB_CTRL_GET_TIMEOUT); switch (buf->bMaxPacketSize0) { case 8: case 16: case 32: case 64: case 255: if (buf->bDescriptorType == @@ -2426,10 +2439,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (portchange & USB_PORT_STAT_C_CONNECTION) { status = hub_port_debounce(hub, port1); - if (status < 0 && printk_ratelimit()) { - dev_err (hub_dev, - "connect-debounce failed, port %d disabled\n", - port1); + if (status < 0) { + if (printk_ratelimit()) + dev_err (hub_dev, "connect-debounce failed, " + "port %d disabled\n", port1); goto done; } portstatus = status; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b743478..f9fed34 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -221,15 +221,10 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) { - int interval; - - if (usb_dev->speed == USB_SPEED_HIGH) - interval = 1 << min(15, ep->desc.bInterval - 1); - else - interval = ep->desc.bInterval; pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); usb_fill_int_urb(urb, usb_dev, pipe, data, len, - usb_api_blocking_completion, NULL, interval); + usb_api_blocking_completion, NULL, + ep->desc.bInterval); } else usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, usb_api_blocking_completion, NULL); diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index e7c9823..be37c86 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -232,12 +232,15 @@ set_level(struct device *dev, struct device_attribute *attr, int len = count; char *cp; int rc = 0; + int old_autosuspend_disabled, old_autoresume_disabled; cp = memchr(buf, '\n', count); if (cp) len = cp - buf; usb_lock_device(udev); + old_autosuspend_disabled = udev->autosuspend_disabled; + old_autoresume_disabled = udev->autoresume_disabled; /* Setting the flags without calling usb_pm_lock is a subject to * races, but who cares... @@ -263,6 +266,10 @@ set_level(struct device *dev, struct device_attribute *attr, } else rc = -EINVAL; + if (rc) { + udev->autosuspend_disabled = old_autosuspend_disabled; + udev->autoresume_disabled = old_autoresume_disabled; + } usb_unlock_device(udev); return (rc < 0 ? rc : count); } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 18ddc5e..4a6299b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -184,10 +184,6 @@ static void usb_release_dev(struct device *dev) udev = to_usb_device(dev); -#ifdef CONFIG_USB_SUSPEND - cancel_delayed_work(&udev->autosuspend); - flush_workqueue(ksuspend_usb_wq); -#endif usb_destroy_configuration(udev); usb_put_hcd(bus_to_hcd(udev->bus)); kfree(udev->product); @@ -205,7 +201,11 @@ struct device_type usb_device_type = { static int ksuspend_usb_init(void) { - ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd"); + /* This workqueue is supposed to be both freezable and + * singlethreaded. Its job doesn't justify running on more + * than one CPU. + */ + ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd"); if (!ksuspend_usb_wq) return -ENOMEM; return 0; diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 157054e..3ca2b31 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -228,13 +228,15 @@ static int dr_controller_setup(struct fsl_udc *udc) /* Config PHY interface */ portctrl = fsl_readl(&dr_regs->portsc1); - portctrl &= ~PORTSCX_PHY_TYPE_SEL; + portctrl &= ~(PORTSCX_PHY_TYPE_SEL & PORTSCX_PORT_WIDTH); switch (udc->phy_mode) { case FSL_USB2_PHY_ULPI: portctrl |= PORTSCX_PTS_ULPI; break; - case FSL_USB2_PHY_UTMI: case FSL_USB2_PHY_UTMI_WIDE: + portctrl |= PORTSCX_PTW_16BIT; + /* fall through */ + case FSL_USB2_PHY_UTMI: portctrl |= PORTSCX_PTS_UTMI; break; case FSL_USB2_PHY_SERIAL: @@ -625,7 +627,7 @@ static void fsl_free_buffer(struct usb_ep *_ep, void *buf, struct fsl_ep *ep; if (!_ep) - return NULL; + return; ep = container_of(_ep, struct fsl_ep, ep); diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index a524805..c7a7c59 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -193,6 +193,19 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd) out_be32(non_ehci + FSL_SOC_USB_CTRL, 0x00000004); out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b); +#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) + /* + * Turn on cache snooping hardware, since some PowerPC platforms + * wholly rely on hardware to deal with cache coherent + */ + + /* Setup Snooping for all the 4GB space */ + /* SNOOP1 starts from 0x0, size 2G */ + out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0 | SNOOP_SIZE_2GB); + /* SNOOP2 starts from 0x80000000, size 2G */ + out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB); +#endif + if (pdata->operating_mode == FSL_USB2_DR_HOST) mpc83xx_setup_phy(ehci, pdata->phy_mode, 0); diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index f28736a..b5e59db 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h @@ -34,4 +34,5 @@ #define FSL_SOC_USB_PRICTRL 0x40c /* NOTE: big-endian */ #define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */ #define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */ +#define SNOOP_SIZE_2GB 0x1e #endif /* _EHCI_FSL_H */ diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 7970560..ca62cb5 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -137,7 +137,7 @@ static const struct pci_device_id ohci_pci_quirks[] = { /* Toshiba portege 4000 */ .vendor = PCI_VENDOR_ID_AL, .device = 0x5237, - .subvendor = PCI_VENDOR_ID_TOSHIBA_2, + .subvendor = PCI_VENDOR_ID_TOSHIBA, .subdevice = 0x0004, .driver_data = (unsigned long) broken_suspend, }, diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 2086165..c225159 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -44,6 +44,7 @@ #define EHCI_USBSTS 4 /* status register */ #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ #define EHCI_USBINTR 8 /* interrupt register */ +#define EHCI_CONFIGFLAG 0x40 /* configured flag register */ #define EHCI_USBLEGSUP 0 /* legacy support register */ #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ @@ -216,6 +217,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) u32 hcc_params, val; u8 offset, cap_length; int count = 256/4; + int tried_handoff = 0; if (!mmio_resource_enabled(pdev, 0)) return; @@ -273,6 +275,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) */ msec = 5000; while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { + tried_handoff = 1; msleep(10); msec -= 10; pci_read_config_dword(pdev, offset, &cap); @@ -292,6 +295,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) pci_write_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, 0); + + /* If the BIOS ever owned the controller then we + * can't expect any power sessions to remain intact. + */ + if (tried_handoff) + writel(0, op_reg_base + EHCI_CONFIGFLAG); break; case 0: /* illegal reserved capability */ cap = 0; diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index ff0dba0..e98df2e 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -57,6 +57,13 @@ #include <asm/system.h> #include <asm/byteorder.h> #include "../core/hcd.h" + + /* FIXME ohci.h is ONLY for internal use by the OHCI driver. + * If you're going to try stuff like this, you need to split + * out shareable stuff (register declarations?) into its own + * file, maybe name <linux/usb/ohci.h> + */ + #include "ohci.h" #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ @@ -173,11 +180,6 @@ struct u132_ring { struct u132_endp *curr_endp; struct delayed_work scheduler; }; -#define OHCI_QUIRK_AMD756 0x01 -#define OHCI_QUIRK_SUPERIO 0x02 -#define OHCI_QUIRK_INITRESET 0x04 -#define OHCI_BIG_ENDIAN 0x08 -#define OHCI_QUIRK_ZFMICRO 0x10 struct u132 { struct kref kref; struct list_head u132_list; diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 88fb56d..cac1500 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -1822,16 +1822,10 @@ static int auerchar_release (struct inode *inode, struct file *file) pauerswald_t cp; dbg("release"); - /* get the mutexes */ - if (down_interruptible (&ccp->mutex)) { - return -ERESTARTSYS; - } + down(&ccp->mutex); cp = ccp->auerdev; if (cp) { - if (down_interruptible (&cp->mutex)) { - up (&ccp->mutex); - return -ERESTARTSYS; - } + down(&cp->mutex); /* remove an open service */ auerswald_removeservice (cp, &ccp->scontext); /* detach from device */ diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index e2172e5..e0f122e 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -73,6 +73,13 @@ static struct list_head ftdi_static_list; #include "usb_u132.h" #include <asm/io.h> #include "../core/hcd.h" + + /* FIXME ohci.h is ONLY for internal use by the OHCI driver. + * If you're going to try stuff like this, you need to split + * out shareable stuff (register declarations?) into its own + * file, maybe name <linux/usb/ohci.h> + */ + #include "../host/ohci.h" /* Define these values to match your devices*/ #define USB_FTDI_ELAN_VENDOR_ID 0x0403 @@ -2300,10 +2307,7 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi) offsetof(struct ohci_regs, member), 0, data); #define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \ offsetof(struct ohci_regs, member), 0, data); -#define OHCI_QUIRK_AMD756 0x01 -#define OHCI_QUIRK_SUPERIO 0x02 -#define OHCI_QUIRK_INITRESET 0x04 -#define OHCI_BIG_ENDIAN 0x08 + #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ OHCI_INTR_WDH) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 11555bd..7bad494 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -165,6 +165,8 @@ struct ld_usb { size_t interrupt_in_endpoint_size; int interrupt_in_running; int interrupt_in_done; + int buffer_overflow; + spinlock_t rbsl; char* interrupt_out_buffer; struct usb_endpoint_descriptor* interrupt_out_endpoint; @@ -230,10 +232,12 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) } else { dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", __FUNCTION__, urb->status); + spin_lock(&dev->rbsl); goto resubmit; /* maybe we can recover */ } } + spin_lock(&dev->rbsl); if (urb->actual_length > 0) { next_ring_head = (dev->ring_head+1) % ring_buffer_size; if (next_ring_head != dev->ring_tail) { @@ -244,21 +248,25 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) dev->ring_head = next_ring_head; dbg_info(&dev->intf->dev, "%s: received %d bytes\n", __FUNCTION__, urb->actual_length); - } else + } else { dev_warn(&dev->intf->dev, "Ring buffer overflow, %d bytes dropped\n", urb->actual_length); + dev->buffer_overflow = 1; + } } resubmit: /* resubmit if we're still running */ - if (dev->interrupt_in_running && dev->intf) { + if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) { retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); - if (retval) + if (retval) { dev_err(&dev->intf->dev, "usb_submit_urb failed (%d)\n", retval); + dev->buffer_overflow = 1; + } } - + spin_unlock(&dev->rbsl); exit: dev->interrupt_in_done = 1; wake_up_interruptible(&dev->read_wait); @@ -330,6 +338,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) /* initialize in direction */ dev->ring_head = 0; dev->ring_tail = 0; + dev->buffer_overflow = 0; usb_fill_int_urb(dev->interrupt_in_urb, interface_to_usbdev(interface), usb_rcvintpipe(interface_to_usbdev(interface), @@ -439,6 +448,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, size_t *actual_buffer; size_t bytes_to_read; int retval = 0; + int rv; dev = file->private_data; @@ -460,7 +470,10 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, } /* wait for data */ + spin_lock_irq(&dev->rbsl); if (dev->ring_head == dev->ring_tail) { + dev->interrupt_in_done = 0; + spin_unlock_irq(&dev->rbsl); if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; @@ -468,6 +481,8 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done); if (retval < 0) goto unlock_exit; + } else { + spin_unlock_irq(&dev->rbsl); } /* actual_buffer contains actual_length + interrupt_in_buffer */ @@ -486,6 +501,17 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, retval = bytes_to_read; + spin_lock_irq(&dev->rbsl); + if (dev->buffer_overflow) { + dev->buffer_overflow = 0; + spin_unlock_irq(&dev->rbsl); + rv = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); + if (rv < 0) + dev->buffer_overflow = 1; + } else { + spin_unlock_irq(&dev->rbsl); + } + unlock_exit: /* unlock the device */ up(&dev->sem); @@ -635,6 +661,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * goto exit; } init_MUTEX(&dev->sem); + spin_lock_init(&dev->rbsl); dev->intf = intf; init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait); diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index ea2175b..fe43712 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -63,7 +63,8 @@ static inline void ARK3116_RCV(struct usb_serial *serial, int seq, request, requesttype, value, index, buf, 0x0000001, 1000); if (result) - dbg("%03d < %d bytes [0x%02X]", seq, result, buf[0]); + dbg("%03d < %d bytes [0x%02X]", seq, result, + ((unsigned char *)buf)[0]); else dbg("%03d < 0 bytes", seq); } diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 95a1805..2353679 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -273,12 +273,18 @@ static __u16 product; /* struct ftdi_sio_quirk is used by devices requiring special attention. */ struct ftdi_sio_quirk { + int (*probe)(struct usb_serial *); void (*setup)(struct usb_serial *); /* Special settings during startup. */ }; +static int ftdi_olimex_probe (struct usb_serial *serial); static void ftdi_USB_UIRT_setup (struct usb_serial *serial); static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); +static struct ftdi_sio_quirk ftdi_olimex_quirk = { + .probe = ftdi_olimex_probe, +}; + static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { .setup = ftdi_USB_UIRT_setup, }; @@ -319,6 +325,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, @@ -525,6 +532,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, + { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), + .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -669,7 +679,7 @@ static struct usb_serial_driver ftdi_sio_device = { /* * *************************************************************************** - * Utlity functions + * Utility functions * *************************************************************************** */ @@ -1171,9 +1181,17 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) /* Probe function to check for special devices */ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id) { + struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info; + + if (quirk && quirk->probe) { + int ret = quirk->probe(serial); + if (ret != 0) + return ret; + } + usb_set_serial_data(serial, (void *)id->driver_info); - return (0); + return 0; } static int ftdi_sio_port_probe(struct usb_serial_port *port) @@ -1268,6 +1286,24 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) priv->force_rtscts = 1; } /* ftdi_HE_TIRA1_setup */ +/* + * First port on Olimex arm-usb-ocd is reserved for JTAG interface + * and can be accessed from userspace using openocd. + */ +static int ftdi_olimex_probe(struct usb_serial *serial) +{ + struct usb_device *udev = serial->dev; + struct usb_interface *interface = serial->interface; + + dbg("%s",__FUNCTION__); + + if (interface == udev->actconfig->interface[0]) { + info("Ignoring reserved serial port on Olimex arm-usb-ocd\n"); + return -ENODEV; + } + + return 0; +} /* ftdi_shutdown is called from usbserial:usb_serial_disconnect * it is called when the usb device is disconnected diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 77ad0a0..33aee90 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -60,6 +60,9 @@ /* DMX4ALL DMX Interfaces */ #define FTDI_DMX4ALL 0xC850 +/* OpenDCC (www.opendcc.de) product id */ +#define FTDI_OPENDCC_PID 0xBFD8 + /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ /* they use the ftdi chipset for the USB interface and the vendor id is the same */ #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ @@ -518,6 +521,15 @@ #define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ #define FTDI_IBS_PROD_PID 0xff3f /* future device */ +/* + * MaxStream devices www.maxstream.net + */ +#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ + +/* Olimex */ +#define OLIMEX_VID 0x15BA +#define OLIMEX_ARM_USB_OCD_PID 0x0003 + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 2366e7b..36620c6 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -769,11 +769,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) return; } - if (!mos7840_port) { - dbg("%s", "NULL mos7840_port pointer \n"); - return; - } - if (mos7840_port_paranoia_check(mos7840_port->port, __FUNCTION__)) { dbg("%s", "Port Paranoia failed \n"); return; diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 4adfab9..00afc17 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -165,12 +165,10 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; struct usb_serial_port *wport; - struct omninet_data *od = usb_get_serial_port_data(port); int result = 0; dbg("%s - port %d", __FUNCTION__, port->number); - od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); wport = serial->port[1]; wport->tty = port->tty; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 8c3f55b..89f067d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -165,7 +165,6 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1410) }, /* Novatel U740 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1420) }, /* Novatel EU870 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel XU870 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2100) }, /* Novatel EV620 CDMA/EV-DO */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 644607d..ac1829c 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -35,6 +35,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ @@ -60,6 +61,7 @@ static struct usb_device_id id_table_3port [] = { { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 6d3dad3..d353693 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -84,7 +84,7 @@ resubmit: static int usb_onetouch_open(struct input_dev *dev) { - struct usb_onetouch *onetouch = dev->private; + struct usb_onetouch *onetouch = input_get_drvdata(dev); onetouch->is_open = 1; onetouch->irq->dev = onetouch->udev; @@ -98,7 +98,7 @@ static int usb_onetouch_open(struct input_dev *dev) static void usb_onetouch_close(struct input_dev *dev) { - struct usb_onetouch *onetouch = dev->private; + struct usb_onetouch *onetouch = input_get_drvdata(dev); usb_kill_urb(onetouch->irq); onetouch->is_open = 0; @@ -185,13 +185,14 @@ int onetouch_connect_input(struct us_data *ss) input_dev->name = onetouch->name; input_dev->phys = onetouch->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->cdev.dev = &udev->dev; + input_dev->dev.parent = &udev->dev; set_bit(EV_KEY, input_dev->evbit); set_bit(ONETOUCH_BUTTON, input_dev->keybit); clear_bit(0, input_dev->keybit); - input_dev->private = onetouch; + input_set_drvdata(input_dev, onetouch); + input_dev->open = usb_onetouch_open; input_dev->close = usb_onetouch_close; diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 8b3145ab..d230ee7 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1179,14 +1179,20 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), -/* This is a virtual windows driver CD, which the zd1211rw driver automatically - * converts into a WLAN device. */ +/* These are virtual windows driver CDs, which the zd1211rw driver automatically + * converts into a WLAN devices. */ UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, "ZyXEL", "G-220F USB-WLAN Install", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_DEVICE ), +UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101, + "SiteCom", + "WL-117 USB-WLAN Install", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE ), + #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, "ATI", diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4d7485f..6e1f1ea 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -704,6 +704,91 @@ config FB_CG6 This is the frame buffer device driver for the CGsix (GX, TurboGX) frame buffer. +config FB_FFB + bool "Creator/Creator3D/Elite3D support" + depends on FB_SBUS && SPARC64 + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Creator, Creator3D, + and Elite3D graphics boards. + +config FB_TCX + bool "TCX (SS4/SS5 only) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the TCX 24/8bit frame + buffer. + +config FB_CG14 + bool "CGfourteen (SX) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the CGfourteen frame + buffer on Desktop SPARCsystems with the SX graphics option. + +config FB_P9100 + bool "P9100 (Sparcbook 3 only) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the P9100 card + supported on Sparcbook 3 machines. + +config FB_LEO + bool "Leo (ZX) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the SBUS-based Sun ZX + (leo) frame buffer cards. + +config FB_IGA + bool "IGA 168x display support" + depends on FB && SPARC32 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for the INTERGRAPHICS 1680 and + successor frame buffer cards. + +config FB_XVR500 + bool "Sun XVR-500 3DLABS Wildcat support" + depends on FB && PCI && SPARC64 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for the Sun XVR-500 and similar + graphics cards based upon the 3DLABS Wildcat chipset. The driver + only works on sparc64 systems where the system firwmare has + mostly initialized the card already. It is treated as a + completely dumb framebuffer device. + +config FB_XVR2500 + bool "Sun XVR-2500 3DLABS Wildcat support" + depends on FB && PCI && SPARC64 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for the Sun XVR-2500 and similar + graphics cards based upon the 3DLABS Wildcat chipset. The driver + only works on sparc64 systems where the system firwmare has + mostly initialized the card already. It is treated as a + completely dumb framebuffer device. + config FB_PVR2 tristate "NEC PowerVR 2 display support" depends on FB && SH_DREAMCAST @@ -1195,7 +1280,7 @@ config FB_ATY config FB_ATY_CT bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" depends on PCI && FB_ATY - default y if SPARC64 && FB_PCI + default y if SPARC64 && PCI help Say Y here to support use of ATI's 64-bit Rage boards (or other boards based on the Mach64 CT, VT, GT, and LT chipsets) as a @@ -1484,95 +1569,6 @@ config FB_AU1200 source "drivers/video/geode/Kconfig" -config FB_FFB - bool "Creator/Creator3D/Elite3D support" - depends on FB_SBUS && SPARC64 - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Creator, Creator3D, - and Elite3D graphics boards. - -config FB_TCX - bool "TCX (SS4/SS5 only) support" - depends on FB_SBUS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the TCX 24/8bit frame - buffer. - -config FB_CG14 - bool "CGfourteen (SX) support" - depends on FB_SBUS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the CGfourteen frame - buffer on Desktop SPARCsystems with the SX graphics option. - -config FB_P9100 - bool "P9100 (Sparcbook 3 only) support" - depends on FB_SBUS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the P9100 card - supported on Sparcbook 3 machines. - -config FB_LEO - bool "Leo (ZX) support" - depends on FB_SBUS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the SBUS-based Sun ZX - (leo) frame buffer cards. - -config FB_XVR500 - bool "Sun XVR-500 3DLABS Wildcat support" - depends on (FB = y) && PCI && SPARC64 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for the Sun XVR-500 and similar - graphics cards based upon the 3DLABS Wildcat chipset. The driver - only works on sparc64 systems where the system firwmare has - mostly initialized the card already. It is treated as a - completely dumb framebuffer device. - -config FB_XVR2500 - bool "Sun XVR-2500 3DLABS Wildcat support" - depends on (FB = y) && PCI && SPARC64 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for the Sun XVR-2500 and similar - graphics cards based upon the 3DLABS Wildcat chipset. The driver - only works on sparc64 systems where the system firwmare has - mostly initialized the card already. It is treated as a - completely dumb framebuffer device. - -config FB_PCI - bool "PCI framebuffers" - depends on (FB = y) && PCI && SPARC - -config FB_IGA - bool "IGA 168x display support" - depends on SPARC32 && FB_PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for the INTERGRAPHICS 1680 and - successor frame buffer cards. - config FB_HIT tristate "HD64461 Frame Buffer support" depends on FB && HD64461 @@ -1796,9 +1792,10 @@ config FB_IBM_GXT4500 config FB_PS3 bool "PS3 GPU framebuffer driver" depends on (FB = y) && PS3_PS3AV - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS ---help--- Include support for the virtual frame buffer in the PS3 platform. diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 267c1ff..a125898 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -394,26 +394,18 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi) /* initialize GPIOs */ imx_gpio_mode(PD6_PF_LSCLK); - imx_gpio_mode(PD10_PF_SPL_SPR); imx_gpio_mode(PD11_PF_CONTRAST); imx_gpio_mode(PD14_PF_FLM_VSYNC); imx_gpio_mode(PD13_PF_LP_HSYNC); - imx_gpio_mode(PD7_PF_REV); - imx_gpio_mode(PD8_PF_CLS); - -#ifndef CONFIG_MACH_PIMX1 - /* on PiMX1 used as buffers enable signal - */ - imx_gpio_mode(PD9_PF_PS); -#endif - -#ifndef CONFIG_MACH_MX1FS2 - /* on mx1fs2 this pin is used to (de)activate the display, so we need - * it as a normal gpio - */ imx_gpio_mode(PD12_PF_ACD_OE); -#endif + /* These are only needed for Sharp HR TFT displays */ + if (fbi->pcr & PCR_SHARP) { + imx_gpio_mode(PD7_PF_REV); + imx_gpio_mode(PD8_PF_CLS); + imx_gpio_mode(PD9_PF_PS); + imx_gpio_mode(PD10_PF_SPL_SPR); + } } #ifdef CONFIG_PM @@ -476,7 +468,6 @@ static int __init imxfb_init_fbinfo(struct device *dev) info->fbops = &imxfb_ops; info->flags = FBINFO_FLAG_DEFAULT; - info->pseudo_palette = (fbi + 1); fbi->rgb[RGB_16] = &def_rgb_16; fbi->rgb[RGB_8] = &def_rgb_8; @@ -499,6 +490,7 @@ static int __init imxfb_init_fbinfo(struct device *dev) info->var.sync = inf->sync; info->var.grayscale = inf->cmap_greyscale; fbi->cmap_inverse = inf->cmap_inverse; + fbi->cmap_static = inf->cmap_static; fbi->pcr = inf->pcr; fbi->lscr1 = inf->lscr1; fbi->dmacr = inf->dmacr; diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index ab5e668..0a04483a 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c @@ -183,15 +183,17 @@ static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) index = PM2VR_RD_INDEXED_DATA; break; } - mb(); + wmb(); pm2_WR(p, index, v); + wmb(); } static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) { pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff); - mb(); + wmb(); pm2_WR(p, PM2VR_RD_INDEXED_DATA, v); + wmb(); } #ifdef CONFIG_FB_PM2_FIFO_DISCONNECT @@ -466,11 +468,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk) WAIT_FIFO(par, 8); pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8); pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0); - wmb(); pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m); pm2v_RDAC_WR(par, PM2VI_RD_MCLK_FEEDBACK, n); pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p); - wmb(); pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1); rmb(); for (i = 256; @@ -483,12 +483,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk) pm2_mnp(clk, &m, &n, &p); WAIT_FIFO(par, 10); pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6); - wmb(); pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m); pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n); - wmb(); pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p); - wmb(); pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS); rmb(); for (i = 256; @@ -509,12 +506,9 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk) pm2_mnp(clk, &m, &n, &p); WAIT_FIFO(par, 8); pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0); - wmb(); pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m); pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n); - wmb(); pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p); - wmb(); pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS); rmb(); for (i = 256; @@ -1066,10 +1060,9 @@ static void pm2fb_block_op(struct fb_info* info, int copy, if (!w || !h) return; - WAIT_FIFO(par, 6); + WAIT_FIFO(par, 5); pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE | PM2F_CONFIG_FB_READ_SOURCE_ENABLE); - pm2_WR(par, PM2R_FB_PIXEL_OFFSET, 0); if (copy) pm2_WR(par, PM2R_FB_SOURCE_DELTA, ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff)); diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index c77a1a1..616a0c0 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c @@ -52,11 +52,6 @@ static char *mode_option __devinitdata; /* - * If your driver supports multiple boards, you should make the - * below data types arrays, or allocate them dynamically (using kmalloc()). - */ - -/* * This structure defines the hardware state of the graphics card. Normally * you place this in a header file in linux/include/video. This file usually * also includes register information. That allows other driver subsystems @@ -67,7 +62,7 @@ struct pm3_par { unsigned char __iomem *v_regs;/* virtual address of p_regs */ u32 video; /* video flags before blanking */ u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */ - u32 palette[16]; + u32 palette[16]; }; /* @@ -104,36 +99,28 @@ static inline void PM3_WAIT(struct pm3_par *par, u32 n) while (PM3_READ_REG(par, PM3InFIFOSpace) < n); } -static inline void PM3_SLOW_WRITE_REG(struct pm3_par *par, s32 off, u32 v) -{ - if (par->v_regs) { - mb(); - PM3_WAIT(par, 1); - wmb(); - PM3_WRITE_REG(par, off, v); - } -} - -static inline void PM3_SET_INDEX(struct pm3_par *par, unsigned index) -{ - PM3_SLOW_WRITE_REG(par, PM3RD_IndexHigh, (index >> 8) & 0xff); - PM3_SLOW_WRITE_REG(par, PM3RD_IndexLow, index & 0xff); -} - static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v) { - PM3_SET_INDEX(par, r); + PM3_WAIT(par, 3); + PM3_WRITE_REG(par, PM3RD_IndexHigh, (r >> 8) & 0xff); + PM3_WRITE_REG(par, PM3RD_IndexLow, r & 0xff); wmb(); PM3_WRITE_REG(par, PM3RD_IndexedData, v); + wmb(); } static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno, unsigned char r, unsigned char g, unsigned char b) { - PM3_SLOW_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno); - PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, r); - PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, g); - PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, b); + PM3_WAIT(par, 4); + PM3_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno); + wmb(); + PM3_WRITE_REG(par, PM3RD_PaletteData, r); + wmb(); + PM3_WRITE_REG(par, PM3RD_PaletteData, g); + wmb(); + PM3_WRITE_REG(par, PM3RD_PaletteData, b); + wmb(); } static void pm3fb_clear_colormap(struct pm3_par *par, @@ -141,7 +128,7 @@ static void pm3fb_clear_colormap(struct pm3_par *par, { int i; - for (i = 0; i < 256 ; i++) /* fill color map with white */ + for (i = 0; i < 256 ; i++) pm3fb_set_color(par, i, r, g, b); } @@ -175,19 +162,26 @@ static void pm3fb_calculate_clock(unsigned long reqclock, } } -static inline int pm3fb_shift_bpp(unsigned long depth, int v) +static inline int pm3fb_depth(const struct fb_var_screeninfo *var) { - switch (depth) { + if ( var->bits_per_pixel == 16 ) + return var->red.length + var->green.length + + var->blue.length; + + return var->bits_per_pixel; +} + +static inline int pm3fb_shift_bpp(unsigned bpp, int v) +{ + switch (bpp) { case 8: return (v >> 4); - case 12: - case 15: case 16: return (v >> 3); case 32: return (v >> 2); } - DPRINTK("Unsupported depth %ld\n", depth); + DPRINTK("Unsupported depth %u\n", bpp); return 0; } @@ -206,56 +200,50 @@ static void pm3fb_write_mode(struct fb_info *info) const u32 vbend = vsend + info->var.upper_margin; const u32 vtotal = info->var.yres + vbend; const u32 width = (info->var.xres_virtual + 7) & ~7; - - PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff); - PM3_SLOW_WRITE_REG(par, PM3Aperture0, 0x00000000); - PM3_SLOW_WRITE_REG(par, PM3Aperture1, 0x00000000); - PM3_SLOW_WRITE_REG(par, PM3FIFODis, 0x00000007); - - PM3_SLOW_WRITE_REG(par, PM3HTotal, - pm3fb_shift_bpp(info->var.bits_per_pixel, - htotal - 1)); - PM3_SLOW_WRITE_REG(par, PM3HsEnd, - pm3fb_shift_bpp(info->var.bits_per_pixel, - hsend)); - PM3_SLOW_WRITE_REG(par, PM3HsStart, - pm3fb_shift_bpp(info->var.bits_per_pixel, - hsstart)); - PM3_SLOW_WRITE_REG(par, PM3HbEnd, - pm3fb_shift_bpp(info->var.bits_per_pixel, - hbend)); - PM3_SLOW_WRITE_REG(par, PM3HgEnd, - pm3fb_shift_bpp(info->var.bits_per_pixel, - hbend)); - PM3_SLOW_WRITE_REG(par, PM3ScreenStride, - pm3fb_shift_bpp(info->var.bits_per_pixel, - width)); - PM3_SLOW_WRITE_REG(par, PM3VTotal, vtotal - 1); - PM3_SLOW_WRITE_REG(par, PM3VsEnd, vsend - 1); - PM3_SLOW_WRITE_REG(par, PM3VsStart, vsstart - 1); - PM3_SLOW_WRITE_REG(par, PM3VbEnd, vbend); - - switch (info->var.bits_per_pixel) { + const unsigned bpp = info->var.bits_per_pixel; + + PM3_WAIT(par, 20); + PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff); + PM3_WRITE_REG(par, PM3Aperture0, 0x00000000); + PM3_WRITE_REG(par, PM3Aperture1, 0x00000000); + PM3_WRITE_REG(par, PM3FIFODis, 0x00000007); + + PM3_WRITE_REG(par, PM3HTotal, + pm3fb_shift_bpp(bpp, htotal - 1)); + PM3_WRITE_REG(par, PM3HsEnd, + pm3fb_shift_bpp(bpp, hsend)); + PM3_WRITE_REG(par, PM3HsStart, + pm3fb_shift_bpp(bpp, hsstart)); + PM3_WRITE_REG(par, PM3HbEnd, + pm3fb_shift_bpp(bpp, hbend)); + PM3_WRITE_REG(par, PM3HgEnd, + pm3fb_shift_bpp(bpp, hbend)); + PM3_WRITE_REG(par, PM3ScreenStride, + pm3fb_shift_bpp(bpp, width)); + PM3_WRITE_REG(par, PM3VTotal, vtotal - 1); + PM3_WRITE_REG(par, PM3VsEnd, vsend - 1); + PM3_WRITE_REG(par, PM3VsStart, vsstart - 1); + PM3_WRITE_REG(par, PM3VbEnd, vbend); + + switch (bpp) { case 8: - PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, + PM3_WRITE_REG(par, PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_8BIT); - PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, + PM3_WRITE_REG(par, PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_8BIT); break; - case 12: - case 15: case 16: #ifndef __BIG_ENDIAN - PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, + PM3_WRITE_REG(par, PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT); - PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, + PM3_WRITE_REG(par, PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT); #else - PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, + PM3_WRITE_REG(par, PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT | PM3ByApertureMode_BYTESWAP_BADC); - PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, + PM3_WRITE_REG(par, PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT | PM3ByApertureMode_BYTESWAP_BADC); #endif /* ! __BIG_ENDIAN */ @@ -263,23 +251,22 @@ static void pm3fb_write_mode(struct fb_info *info) case 32: #ifndef __BIG_ENDIAN - PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, + PM3_WRITE_REG(par, PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT); - PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, + PM3_WRITE_REG(par, PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT); #else - PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode, + PM3_WRITE_REG(par, PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT | PM3ByApertureMode_BYTESWAP_DCBA); - PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode, + PM3_WRITE_REG(par, PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT | PM3ByApertureMode_BYTESWAP_DCBA); #endif /* ! __BIG_ENDIAN */ break; default: - DPRINTK("Unsupported depth %d\n", - info->var.bits_per_pixel); + DPRINTK("Unsupported depth %d\n", bpp); break; } @@ -296,14 +283,15 @@ static void pm3fb_write_mode(struct fb_info *info) PM3VideoControl_VSYNC_MASK); video |= PM3VideoControl_HSYNC_ACTIVE_HIGH | PM3VideoControl_VSYNC_ACTIVE_HIGH; - PM3_SLOW_WRITE_REG(par, PM3VideoControl, video); + PM3_WRITE_REG(par, PM3VideoControl, video); } - PM3_SLOW_WRITE_REG(par, PM3VClkCtl, + PM3_WRITE_REG(par, PM3VClkCtl, (PM3_READ_REG(par, PM3VClkCtl) & 0xFFFFFFFC)); - PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base); - PM3_SLOW_WRITE_REG(par, PM3ChipConfig, + PM3_WRITE_REG(par, PM3ScreenBase, par->base); + PM3_WRITE_REG(par, PM3ChipConfig, (PM3_READ_REG(par, PM3ChipConfig) & 0xFFFFFFFD)); + wmb(); { unsigned char uninitialized_var(m); /* ClkPreScale */ unsigned char uninitialized_var(n); /* ClkFeedBackScale */ @@ -337,7 +325,7 @@ static void pm3fb_write_mode(struct fb_info *info) PM3_WRITE_DAC_REG(par, PM3RD_DACControl, 0x00); - switch (info->var.bits_per_pixel) { + switch (pm3fb_depth(&info->var)) { case 8: PM3_WRITE_DAC_REG(par, PM3RD_PixelSize, PM3RD_PixelSize_8_BIT_PIXELS); @@ -393,57 +381,44 @@ static void pm3fb_write_mode(struct fb_info *info) * hardware independent functions */ int pm3fb_init(void); -int pm3fb_setup(char*); static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { u32 lpitch; + unsigned bpp = var->red.length + var->green.length + + var->blue.length + var->transp.length; - var->transp.offset = 0; - var->transp.length = 0; - switch(var->bits_per_pixel) { - case 8: - var->red.length = var->green.length = var->blue.length = 8; - var->red.offset = var->green.offset = var->blue.offset = 0; - break; - case 12: - var->red.offset = 8; - var->red.length = 4; - var->green.offset = 4; - var->green.length = 4; - var->blue.offset = 0; - var->blue.length = 4; - var->transp.offset = 12; - var->transp.length = 4; - case 15: - var->red.offset = 10; - var->red.length = 5; - var->green.offset = 5; - var->green.length = 5; - var->blue.offset = 0; - var->blue.length = 5; - var->transp.offset = 15; - var->transp.length = 1; - break; - case 16: - var->red.offset = 11; - var->red.length = 5; - var->green.offset = 5; - var->green.length = 6; - var->blue.offset = 0; - var->blue.length = 5; - break; - case 32: - var->transp.offset = 24; - var->transp.length = 8; - var->red.offset = 16; - var->green.offset = 8; - var->blue.offset = 0; - var->red.length = var->green.length = var->blue.length = 8; - break; - default: - DPRINTK("depth not supported: %u\n", var->bits_per_pixel); - return -EINVAL; + if ( bpp != var->bits_per_pixel ) { + /* set predefined mode for bits_per_pixel settings */ + + switch(var->bits_per_pixel) { + case 8: + var->red.length = var->green.length = var->blue.length = 8; + var->red.offset = var->green.offset = var->blue.offset = 0; + var->transp.offset = 0; + var->transp.length = 0; + break; + case 16: + var->red.length = var->blue.length = 5; + var->green.length = 6; + var->transp.length = 0; + break; + case 32: + var->red.length = var->green.length = var->blue.length = 8; + var->transp.length = 8; + break; + default: + DPRINTK("depth not supported: %u\n", var->bits_per_pixel); + return -EINVAL; + } + } + /* it is assumed BGRA order */ + if (var->bits_per_pixel > 8 ) + { + var->blue.offset = 0; + var->green.offset = var->blue.length; + var->red.offset = var->green.offset + var->green.length; + var->transp.offset = var->red.offset + var->red.length; } var->height = var->width = -1; @@ -502,10 +477,9 @@ static int pm3fb_set_par(struct fb_info *info) { struct pm3_par *par = info->par; const u32 xres = (info->var.xres + 31) & ~31; - const int depth = (info->var.bits_per_pixel + 7) & ~7; + const unsigned bpp = info->var.bits_per_pixel; - par->base = pm3fb_shift_bpp(info->var.bits_per_pixel, - (info->var.yoffset * xres) + par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres) + info->var.xoffset); par->video = 0; @@ -530,12 +504,10 @@ static int pm3fb_set_par(struct fb_info *info) par->video |= PM3VideoControl_DISABLE; DPRINTK("PM3Video disabled\n"); } - switch (depth) { + switch (bpp) { case 8: par->video |= PM3VideoControl_PIXELSIZE_8BIT; break; - case 12: - case 15: case 16: par->video |= PM3VideoControl_PIXELSIZE_16BIT; break; @@ -548,9 +520,9 @@ static int pm3fb_set_par(struct fb_info *info) } info->fix.visual = - (depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; info->fix.line_length = ((info->var.xres_virtual + 7) & ~7) - * depth / 8; + * bpp / 8; /* pm3fb_clear_memory(info, 0);*/ pm3fb_clear_colormap(par, 0, 0, 0); @@ -580,8 +552,8 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green, * var->{color}.length contains length of bitfield * {hardwarespecific} contains width of DAC * pseudo_palette[X] is programmed to (X << red.offset) | - * (X << green.offset) | - * (X << blue.offset) + * (X << green.offset) | + * (X << blue.offset) * RAMDAC[X] is programmed to (red, green, blue) * color depth = SUM(var->{color}.length) * @@ -621,7 +593,6 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green, case 8: break; case 16: - case 24: case 32: ((u32*)(info->pseudo_palette))[regno] = v; break; @@ -643,7 +614,8 @@ static int pm3fb_pan_display(struct fb_var_screeninfo *var, par->base = pm3fb_shift_bpp(var->bits_per_pixel, (var->yoffset * xres) + var->xoffset); - PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base); + PM3_WAIT(par, 1); + PM3_WRITE_REG(par, PM3ScreenBase, par->base); return 0; } @@ -665,31 +637,31 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info) switch (blank_mode) { case FB_BLANK_UNBLANK: - video = video | PM3VideoControl_ENABLE; + video |= PM3VideoControl_ENABLE; break; - case FB_BLANK_NORMAL: /* FIXME */ - video = video & ~(PM3VideoControl_ENABLE); + case FB_BLANK_NORMAL: + video &= ~(PM3VideoControl_ENABLE); break; case FB_BLANK_HSYNC_SUSPEND: - video = video & ~(PM3VideoControl_HSYNC_MASK | - PM3VideoControl_BLANK_ACTIVE_LOW); + video &= ~(PM3VideoControl_HSYNC_MASK | + PM3VideoControl_BLANK_ACTIVE_LOW); break; case FB_BLANK_VSYNC_SUSPEND: - video = video & ~(PM3VideoControl_VSYNC_MASK | - PM3VideoControl_BLANK_ACTIVE_LOW); + video &= ~(PM3VideoControl_VSYNC_MASK | + PM3VideoControl_BLANK_ACTIVE_LOW); break; case FB_BLANK_POWERDOWN: - video = video & ~(PM3VideoControl_HSYNC_MASK | - PM3VideoControl_VSYNC_MASK | - PM3VideoControl_BLANK_ACTIVE_LOW); + video &= ~(PM3VideoControl_HSYNC_MASK | + PM3VideoControl_VSYNC_MASK | + PM3VideoControl_BLANK_ACTIVE_LOW); break; default: DPRINTK("Unsupported blanking %d\n", blank_mode); return 1; } - PM3_SLOW_WRITE_REG(par,PM3VideoControl, video); - + PM3_WAIT(par, 1); + PM3_WRITE_REG(par,PM3VideoControl, video); return 0; } @@ -703,9 +675,9 @@ static struct fb_ops pm3fb_ops = { .fb_set_par = pm3fb_set_par, .fb_setcolreg = pm3fb_setcolreg, .fb_pan_display = pm3fb_pan_display, - .fb_fillrect = cfb_fillrect, /* Needed !!! */ - .fb_copyarea = cfb_copyarea, /* Needed !!! */ - .fb_imageblit = cfb_imageblit, /* Needed !!! */ + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, .fb_blank = pm3fb_blank, }; @@ -722,7 +694,7 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par) unsigned long memsize = 0, tempBypass, i, temp1, temp2; unsigned char __iomem *screen_mem; - pm3fb_fix.smem_len = 64 * 1024 * 1024; /* request full aperture size */ + pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */ /* Linear frame buffer - request region and map it. */ if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len, "pm3fb smem")) { @@ -744,7 +716,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par) DPRINTK("PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass); - PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF); + PM3_WAIT(par, 1); + PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF); /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */ for (i = 0; i < 32; i++) { @@ -765,10 +738,9 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par) if (memsize + 1 == i) { for (i = 0; i < 32; i++) { /* Clear first 32MB ; 0 is 0, no need to byteswap */ - writel(0x0000000, - (screen_mem + (i * 1048576))); - mb(); + writel(0x0000000, (screen_mem + (i * 1048576))); } + wmb(); for (i = 32; i < 64; i++) { fb_writel(i * 0x00345678, @@ -787,7 +759,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par) } DPRINTK("Second detect pass got %ld MB\n", memsize + 1); - PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass); + PM3_WAIT(par, 1); + PM3_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass); iounmap(screen_mem); release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len); @@ -890,7 +863,6 @@ static int __devinit pm3fb_probe(struct pci_dev *dev, goto err_exit_both; } - /* This has to been done !!! */ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { retval = -ENOMEM; goto err_exit_both; @@ -907,7 +879,7 @@ static int __devinit pm3fb_probe(struct pci_dev *dev, } printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); - pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */ + pci_set_drvdata(dev, info); return 0; err_exit_all: @@ -949,8 +921,7 @@ static void __devexit pm3fb_remove(struct pci_dev *dev) static struct pci_device_id pm3fb_id_table[] = { { PCI_VENDOR_ID_3DLABS, 0x0a, - PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, - 0xff0000, 0 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0, } }; @@ -964,6 +935,22 @@ static struct pci_driver pm3fb_driver = { MODULE_DEVICE_TABLE(pci, pm3fb_id_table); +#ifndef MODULE + /* + * Setup + */ + +/* + * Only necessary if your driver takes special options, + * otherwise we fall back on the generic fb_setup(). + */ +static int __init pm3fb_setup(char *options) +{ + /* Parse user speficied options (`video=pm3fb:') */ + return 0; +} +#endif /* MODULE */ + int __init pm3fb_init(void) { /* @@ -985,22 +972,6 @@ static void __exit pm3fb_exit(void) pci_unregister_driver(&pm3fb_driver); } -#ifndef MODULE - /* - * Setup - */ - -/* - * Only necessary if your driver takes special options, - * otherwise we fall back on the generic fb_setup(). - */ -int __init pm3fb_setup(char *options) -{ - /* Parse user speficied options (`video=pm3fb:') */ - return 0; -} -#endif /* MODULE */ - module_init(pm3fb_init); module_exit(pm3fb_exit); diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 9756a72..9cf92ba 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -951,12 +951,14 @@ static int ps3fb_xdr_settings(u64 xdr_lpar) static struct fb_ops ps3fb_ops = { .fb_open = ps3fb_open, .fb_release = ps3fb_release, + .fb_read = fb_sys_read, + .fb_write = fb_sys_write, .fb_check_var = ps3fb_check_var, .fb_set_par = ps3fb_set_par, .fb_setcolreg = ps3fb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = sys_fillrect, + .fb_copyarea = sys_copyarea, + .fb_imageblit = sys_imageblit, .fb_mmap = ps3fb_mmap, .fb_blank = ps3fb_blank, .fb_ioctl = ps3fb_ioctl, diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index 5fc86ea..003c49a 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c @@ -660,7 +660,7 @@ int __init w100fb_probe(struct platform_device *pdev) err = -ENODEV; goto out; } - printk(" at 0x%08lx.\n", mem->start+W100_CFG_BASE); + printk(" at 0x%08lx.\n", (unsigned long) mem->start+W100_CFG_BASE); /* Remap the framebuffer */ remapped_fbuf = ioremap_nocache(mem->start+MEM_WINDOW_BASE, MEM_WINDOW_SIZE); @@ -753,10 +753,14 @@ int __init w100fb_probe(struct platform_device *pdev) goto out; } - device_create_file(&pdev->dev, &dev_attr_fastpllclk); - device_create_file(&pdev->dev, &dev_attr_reg_read); - device_create_file(&pdev->dev, &dev_attr_reg_write); - device_create_file(&pdev->dev, &dev_attr_flip); + err = device_create_file(&pdev->dev, &dev_attr_fastpllclk); + err |= device_create_file(&pdev->dev, &dev_attr_reg_read); + err |= device_create_file(&pdev->dev, &dev_attr_reg_write); + err |= device_create_file(&pdev->dev, &dev_attr_flip); + + if (err != 0) + printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n", + info->node, err); printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); return 0; |